mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-01-10 07:10:27 +00:00
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
|
||||
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
|
||||
|
||||
@ -65,3 +61,8 @@ hostapd hostapd.conf
|
||||
|
||||
# Run wpa_supplicant (station) for wlan1
|
||||
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/
|
||||
S: Maintained
|
||||
|
||||
RTL818X WIRELESS DRIVER
|
||||
P: Michael Wu
|
||||
M: flamingice@sourmilk.net
|
||||
P: Andrea Merello
|
||||
M: andreamrl@tiscali.it
|
||||
RTL8180 WIRELESS DRIVER
|
||||
P: John W. Linville
|
||||
M: linville@tuxdriver.com
|
||||
L: linux-wireless@vger.kernel.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
|
||||
|
||||
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
|
||||
P: Antonino Daplas
|
||||
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
|
||||
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
|
||||
tristate "Marvell 8xxx Libertas WLAN driver support"
|
||||
depends on WLAN_80211
|
||||
@ -712,6 +568,7 @@ config MAC80211_HWSIM
|
||||
source "drivers/net/wireless/p54/Kconfig"
|
||||
source "drivers/net/wireless/ath5k/Kconfig"
|
||||
source "drivers/net/wireless/ath9k/Kconfig"
|
||||
source "drivers/net/wireless/ipw2x00/Kconfig"
|
||||
source "drivers/net/wireless/iwlwifi/Kconfig"
|
||||
source "drivers/net/wireless/hostap/Kconfig"
|
||||
source "drivers/net/wireless/b43/Kconfig"
|
||||
|
@ -2,9 +2,8 @@
|
||||
# Makefile for the Linux Wireless network device drivers.
|
||||
#
|
||||
|
||||
obj-$(CONFIG_IPW2100) += ipw2100.o
|
||||
|
||||
obj-$(CONFIG_IPW2200) += ipw2200.o
|
||||
obj-$(CONFIG_IPW2100) += ipw2x00/
|
||||
obj-$(CONFIG_IPW2200) += ipw2x00/
|
||||
|
||||
obj-$(CONFIG_STRIP) += strip.o
|
||||
obj-$(CONFIG_ARLAN) += arlan.o
|
||||
@ -31,6 +30,8 @@ obj-$(CONFIG_HOSTAP) += hostap/
|
||||
obj-$(CONFIG_B43) += b43/
|
||||
obj-$(CONFIG_B43LEGACY) += b43legacy/
|
||||
obj-$(CONFIG_ZD1211RW) += zd1211rw/
|
||||
obj-$(CONFIG_RTL8180) += rtl818x/
|
||||
obj-$(CONFIG_RTL8187) += rtl818x/
|
||||
|
||||
# 16-bit wireless PCMCIA client drivers
|
||||
obj-$(CONFIG_PCMCIA_RAYCS) += ray_cs.o
|
||||
@ -43,12 +44,6 @@ obj-$(CONFIG_LIBERTAS) += libertas/
|
||||
|
||||
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_IWLWIFI) += iwlwifi/
|
||||
|
@ -2219,9 +2219,9 @@ ath5k_init(struct ath5k_softc *sc, bool is_resume)
|
||||
*/
|
||||
sc->curchan = sc->hw->conf.channel;
|
||||
sc->curband = &sc->sbands[sc->curchan->band];
|
||||
sc->imask = AR5K_INT_RXOK | AR5K_INT_TXOK | AR5K_INT_RXEOL |
|
||||
AR5K_INT_RXORN | AR5K_INT_FATAL | AR5K_INT_GLOBAL |
|
||||
AR5K_INT_MIB;
|
||||
sc->imask = AR5K_INT_RXOK | AR5K_INT_RXERR | AR5K_INT_RXEOL |
|
||||
AR5K_INT_RXORN | AR5K_INT_TXDESC | AR5K_INT_TXEOL |
|
||||
AR5K_INT_FATAL | AR5K_INT_GLOBAL | AR5K_INT_MIB;
|
||||
ret = ath5k_reset(sc, false, false);
|
||||
if (ret)
|
||||
goto done;
|
||||
@ -2953,9 +2953,9 @@ static void ath5k_configure_filter(struct ieee80211_hw *hw,
|
||||
test_bit(ATH_STAT_PROMISC, sc->status))
|
||||
rfilt |= AR5K_RX_FILTER_PROM;
|
||||
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;
|
||||
}
|
||||
if (sc->opmode == NL80211_IFTYPE_MESH_POINT)
|
||||
rfilt |= AR5K_RX_FILTER_CONTROL | AR5K_RX_FILTER_BEACON |
|
||||
AR5K_RX_FILTER_PROBEREQ | AR5K_RX_FILTER_PROM;
|
||||
|
@ -2196,9 +2196,7 @@ static int ath5k_hw_rf5110_calibrate(struct ath5k_hw *ah,
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = ath5k_hw_noise_floor_calibration(ah, channel->center_freq);
|
||||
if (ret)
|
||||
return ret;
|
||||
ath5k_hw_noise_floor_calibration(ah, channel->center_freq);
|
||||
|
||||
/*
|
||||
* 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...
|
||||
*/
|
||||
ret = ath5k_hw_noise_floor_calibration(ah, channel->center_freq);
|
||||
if (ret)
|
||||
return ret;
|
||||
ath5k_hw_noise_floor_calibration(ah, channel->center_freq);
|
||||
|
||||
/*
|
||||
* 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) {
|
||||
case AR5416_DEVID_PCI:
|
||||
case AR5416_DEVID_PCIE:
|
||||
return "Atheros 5416";
|
||||
case AR5416_DEVID_PCIE:
|
||||
return "Atheros 5418";
|
||||
case AR9160_DEVID_PCI:
|
||||
return "Atheros 9160";
|
||||
case AR9280_DEVID_PCI:
|
||||
|
@ -18,6 +18,7 @@
|
||||
|
||||
#include <linux/nl80211.h>
|
||||
#include "core.h"
|
||||
#include "reg.h"
|
||||
|
||||
#define ATH_PCI_VERSION "0.1"
|
||||
|
||||
@ -1519,15 +1520,74 @@ static struct ieee80211_ops ath9k_ops = {
|
||||
.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)
|
||||
{
|
||||
void __iomem *mem;
|
||||
struct ath_softc *sc;
|
||||
struct ieee80211_hw *hw;
|
||||
const char *athname;
|
||||
u8 csz;
|
||||
u32 val;
|
||||
int ret = 0;
|
||||
struct ath_hal *ah;
|
||||
|
||||
if (pci_enable_device(pdev))
|
||||
return -EIO;
|
||||
@ -1614,11 +1674,15 @@ static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
|
||||
goto bad4;
|
||||
}
|
||||
|
||||
athname = ath9k_hw_probe(id->vendor, id->device);
|
||||
|
||||
printk(KERN_INFO "%s: %s: mem=0x%lx, irq=%d\n",
|
||||
ah = sc->sc_ah;
|
||||
printk(KERN_INFO
|
||||
"%s: Atheros AR%s MAC/BB Rev:%x "
|
||||
"AR%s RF Rev:%x: mem=0x%lx, irq=%d\n",
|
||||
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);
|
||||
|
||||
return 0;
|
||||
|
@ -1272,8 +1272,7 @@ static void ath_rc_update_ht(struct ath_softc *sc,
|
||||
rate_ctrl->state[tx_rate].per = 100;
|
||||
} else {
|
||||
/* xretries == 2 */
|
||||
count = sizeof(nretry_to_per_lookup) /
|
||||
sizeof(nretry_to_per_lookup[0]);
|
||||
count = ARRAY_SIZE(nretry_to_per_lookup);
|
||||
if (retries >= count)
|
||||
retries = count - 1;
|
||||
/* 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 */
|
||||
/* Update the PER. */
|
||||
/* Make sure it doesn't index out of array's bounds. */
|
||||
count = sizeof(nretry_to_per_lookup) /
|
||||
sizeof(nretry_to_per_lookup[0]);
|
||||
count = ARRAY_SIZE(nretry_to_per_lookup);
|
||||
if (retries >= count)
|
||||
retries = count - 1;
|
||||
if (info_priv->n_bad_frames) {
|
||||
|
@ -296,9 +296,8 @@ u32 ath_calcrxfilter(struct ath_softc *sc)
|
||||
rfilt &= ~ATH9K_RX_FILTER_UCAST;
|
||||
}
|
||||
|
||||
if (((sc->sc_ah->ah_opmode == ATH9K_M_STA) &&
|
||||
(sc->rx_filter & FIF_BCN_PRBRESP_PROMISC)) ||
|
||||
(sc->sc_ah->ah_opmode == ATH9K_M_IBSS))
|
||||
if (sc->sc_ah->ah_opmode == ATH9K_M_STA ||
|
||||
sc->sc_ah->ah_opmode == ATH9K_M_IBSS)
|
||||
rfilt |= ATH9K_RX_FILTER_BEACON;
|
||||
|
||||
/* 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:
|
||||
return 3;
|
||||
}
|
||||
B43_WARN_ON(1);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -73,7 +72,6 @@ static u8 b43_plcp_get_bitrate_idx_ofdm(struct b43_plcp_hdr6 *plcp, bool aphy)
|
||||
case 0xC:
|
||||
return base + 7;
|
||||
}
|
||||
B43_WARN_ON(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);
|
||||
else
|
||||
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);
|
||||
|
||||
/*
|
||||
|
@ -145,6 +145,10 @@
|
||||
#define B43legacy_SHM_SH_PRMAXTIME 0x0074 /* Probe Response max time */
|
||||
#define B43legacy_SHM_SH_PRPHYCTL 0x0188 /* Probe Resp PHY TX control */
|
||||
/* 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 */
|
||||
#define B43legacy_SHM_SH_UCODEREV 0x0000 /* Microcode revision */
|
||||
#define B43legacy_SHM_SH_UCODEPATCH 0x0002 /* Microcode patchlevel */
|
||||
@ -663,7 +667,6 @@ struct b43legacy_wldev {
|
||||
bool bad_frames_preempt;/* Use "Bad Frames Preemption". */
|
||||
bool dfq_valid; /* Directed frame queue valid (IBSS PS mode, ATIM). */
|
||||
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. */
|
||||
|
||||
/* 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)
|
||||
{
|
||||
b43legacy_set_slot_time(dev, 9);
|
||||
dev->short_slot = 1;
|
||||
}
|
||||
|
||||
static void b43legacy_short_slot_timing_disable(struct b43legacy_wldev *dev)
|
||||
{
|
||||
b43legacy_set_slot_time(dev, 20);
|
||||
dev->short_slot = 0;
|
||||
}
|
||||
|
||||
/* 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)
|
||||
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);
|
||||
|
||||
/* Adjust the desired TX power level. */
|
||||
@ -2662,6 +2650,104 @@ out_unlock_mutex:
|
||||
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,
|
||||
unsigned int changed,
|
||||
unsigned int *fflags,
|
||||
@ -3370,6 +3456,7 @@ static const struct ieee80211_ops b43legacy_hw_ops = {
|
||||
.add_interface = b43legacy_op_add_interface,
|
||||
.remove_interface = b43legacy_op_remove_interface,
|
||||
.config = b43legacy_op_dev_config,
|
||||
.bss_info_changed = b43legacy_op_bss_info_changed,
|
||||
.config_interface = b43legacy_op_config_interface,
|
||||
.configure_filter = b43legacy_op_configure_filter,
|
||||
.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)"
|
||||
depends on WLAN_80211
|
||||
select WIRELESS_EXT
|
||||
select IEEE80211
|
||||
select IEEE80211_CRYPT_WEP
|
||||
select LIB80211
|
||||
select LIB80211_CRYPT_WEP
|
||||
select LIB80211_CRYPT_TKIP
|
||||
select LIB80211_CRYPT_CCMP
|
||||
---help---
|
||||
Shared driver code for IEEE 802.11b wireless cards based on
|
||||
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);
|
||||
void ap_control_kickall(struct ap_data *ap);
|
||||
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[],
|
||||
struct iw_quality qual[], int buf_size,
|
||||
int aplist);
|
||||
|
@ -2,7 +2,7 @@
|
||||
#define HOSTAP_80211_H
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <net/ieee80211_crypt.h>
|
||||
#include <net/ieee80211.h>
|
||||
|
||||
struct hostap_ieee80211_mgmt {
|
||||
__le16 frame_control;
|
||||
|
@ -1,5 +1,5 @@
|
||||
#include <linux/etherdevice.h>
|
||||
#include <net/ieee80211_crypt.h>
|
||||
#include <net/lib80211.h>
|
||||
|
||||
#include "hostap_80211.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) */
|
||||
static int
|
||||
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;
|
||||
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) */
|
||||
static int
|
||||
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;
|
||||
int res, hdrlen;
|
||||
@ -733,7 +733,7 @@ void hostap_80211_rx(struct net_device *dev, struct sk_buff *skb,
|
||||
int from_assoc_ap = 0;
|
||||
u8 dst[ETH_ALEN];
|
||||
u8 src[ETH_ALEN];
|
||||
struct ieee80211_crypt_data *crypt = NULL;
|
||||
struct lib80211_crypt_data *crypt = NULL;
|
||||
void *sta = NULL;
|
||||
int keyidx = 0;
|
||||
|
||||
@ -785,7 +785,7 @@ void hostap_80211_rx(struct net_device *dev, struct sk_buff *skb,
|
||||
int idx = 0;
|
||||
if (skb->len >= hdrlen + 3)
|
||||
idx = skb->data[hdrlen + 3] >> 6;
|
||||
crypt = local->crypt[idx];
|
||||
crypt = local->crypt_info.crypt[idx];
|
||||
sta = NULL;
|
||||
|
||||
/* 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 */
|
||||
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;
|
||||
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) {
|
||||
/* Set crypt to default algorithm and key; will be replaced in
|
||||
* 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;
|
||||
} else {
|
||||
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))
|
||||
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
|
||||
*/
|
||||
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)
|
||||
{
|
||||
ap->crypt = ieee80211_get_crypto_ops("WEP");
|
||||
ap->crypt = lib80211_get_crypto_ops("WEP");
|
||||
|
||||
if (ap->crypt) {
|
||||
if (ap->crypt->init) {
|
||||
@ -1224,7 +1224,7 @@ static void ap_crypt_init(struct ap_data *ap)
|
||||
|
||||
if (ap->crypt == NULL) {
|
||||
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;
|
||||
u16 resp = WLAN_STATUS_SUCCESS, fc;
|
||||
struct sta_info *sta = NULL;
|
||||
struct ieee80211_crypt_data *crypt;
|
||||
struct lib80211_crypt_data *crypt;
|
||||
char *txt = "";
|
||||
|
||||
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;
|
||||
if (skb->len >= hdrlen + 3)
|
||||
idx = skb->data[hdrlen + 3] >> 6;
|
||||
crypt = local->crypt[idx];
|
||||
crypt = local->crypt_info.crypt[idx];
|
||||
}
|
||||
|
||||
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) */
|
||||
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)
|
||||
{
|
||||
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,
|
||||
struct ieee80211_crypt_data ***crypt)
|
||||
struct lib80211_crypt_data ***crypt)
|
||||
{
|
||||
struct sta_info *sta;
|
||||
|
||||
|
@ -74,7 +74,7 @@ struct sta_info {
|
||||
u32 tx_since_last_failure;
|
||||
u32 tx_consecutive_exc;
|
||||
|
||||
struct ieee80211_crypt_data *crypt;
|
||||
struct lib80211_crypt_data *crypt;
|
||||
|
||||
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
|
||||
* authentication */
|
||||
struct ieee80211_crypto_ops *crypt;
|
||||
struct lib80211_crypto_ops *crypt;
|
||||
void *crypt_priv;
|
||||
#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
|
||||
};
|
||||
@ -229,7 +229,7 @@ typedef enum {
|
||||
struct hostap_tx_data {
|
||||
struct sk_buff *skb;
|
||||
int host_encrypt;
|
||||
struct ieee80211_crypt_data *crypt;
|
||||
struct lib80211_crypt_data *crypt;
|
||||
void *sta_ptr;
|
||||
};
|
||||
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,
|
||||
int wds);
|
||||
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);
|
||||
int hostap_is_sta_assoc(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 <net/iw_handler.h>
|
||||
#include <net/ieee80211.h>
|
||||
#include <net/ieee80211_crypt.h>
|
||||
#include <net/lib80211.h>
|
||||
#include <asm/irq.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)
|
||||
{
|
||||
local_info_t *local = (local_info_t *) data;
|
||||
@ -3250,10 +3211,8 @@ while (0)
|
||||
|
||||
INIT_LIST_HEAD(&local->cmd_queue);
|
||||
init_waitqueue_head(&local->hostscan_wq);
|
||||
INIT_LIST_HEAD(&local->crypt_deinit_list);
|
||||
init_timer(&local->crypt_deinit_timer);
|
||||
local->crypt_deinit_timer.data = (unsigned long) local;
|
||||
local->crypt_deinit_timer.function = prism2_crypt_deinit_handler;
|
||||
|
||||
lib80211_crypt_info_init(&local->crypt_info, dev->name, &local->lock);
|
||||
|
||||
init_timer(&local->passive_scan_timer);
|
||||
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();
|
||||
|
||||
if (timer_pending(&local->crypt_deinit_timer))
|
||||
del_timer(&local->crypt_deinit_timer);
|
||||
prism2_crypt_deinit_entries(local, 1);
|
||||
lib80211_crypt_info_free(&local->crypt_info);
|
||||
|
||||
if (timer_pending(&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)
|
||||
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)
|
||||
hostap_free_data(local->ap);
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/ethtool.h>
|
||||
#include <net/ieee80211_crypt.h>
|
||||
#include <net/lib80211.h>
|
||||
|
||||
#include "hostap_wlan.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,
|
||||
struct iw_request_info *info,
|
||||
struct iw_point *erq, char *keybuf)
|
||||
@ -149,47 +123,47 @@ static int prism2_ioctl_siwencode(struct net_device *dev,
|
||||
struct hostap_interface *iface;
|
||||
local_info_t *local;
|
||||
int i;
|
||||
struct ieee80211_crypt_data **crypt;
|
||||
struct lib80211_crypt_data **crypt;
|
||||
|
||||
iface = netdev_priv(dev);
|
||||
local = iface->local;
|
||||
|
||||
i = erq->flags & IW_ENCODE_INDEX;
|
||||
if (i < 1 || i > 4)
|
||||
i = local->tx_keyidx;
|
||||
i = local->crypt_info.tx_keyidx;
|
||||
else
|
||||
i--;
|
||||
if (i < 0 || i >= WEP_KEYS)
|
||||
return -EINVAL;
|
||||
|
||||
crypt = &local->crypt[i];
|
||||
crypt = &local->crypt_info.crypt[i];
|
||||
|
||||
if (erq->flags & IW_ENCODE_DISABLED) {
|
||||
if (*crypt)
|
||||
prism2_crypt_delayed_deinit(local, crypt);
|
||||
lib80211_crypt_delayed_deinit(&local->crypt_info, crypt);
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (*crypt != NULL && (*crypt)->ops != NULL &&
|
||||
strcmp((*crypt)->ops->name, "WEP") != 0) {
|
||||
/* 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) {
|
||||
struct ieee80211_crypt_data *new_crypt;
|
||||
struct lib80211_crypt_data *new_crypt;
|
||||
|
||||
/* take WEP into use */
|
||||
new_crypt = kzalloc(sizeof(struct ieee80211_crypt_data),
|
||||
new_crypt = kzalloc(sizeof(struct lib80211_crypt_data),
|
||||
GFP_KERNEL);
|
||||
if (new_crypt == NULL)
|
||||
return -ENOMEM;
|
||||
new_crypt->ops = ieee80211_get_crypto_ops("WEP");
|
||||
new_crypt->ops = lib80211_get_crypto_ops("WEP");
|
||||
if (!new_crypt->ops) {
|
||||
request_module("ieee80211_crypt_wep");
|
||||
new_crypt->ops = ieee80211_get_crypto_ops("WEP");
|
||||
request_module("lib80211_crypt_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);
|
||||
if (!new_crypt->ops || !new_crypt->priv) {
|
||||
kfree(new_crypt);
|
||||
@ -210,16 +184,16 @@ static int prism2_ioctl_siwencode(struct net_device *dev,
|
||||
memset(keybuf + erq->length, 0, len - erq->length);
|
||||
(*crypt)->ops->set_key(keybuf, len, NULL, (*crypt)->priv);
|
||||
for (j = 0; j < WEP_KEYS; j++) {
|
||||
if (j != i && local->crypt[j]) {
|
||||
if (j != i && local->crypt_info.crypt[j]) {
|
||||
first = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (first)
|
||||
local->tx_keyidx = i;
|
||||
local->crypt_info.tx_keyidx = i;
|
||||
} else {
|
||||
/* No key data - just set the default TX key index */
|
||||
local->tx_keyidx = i;
|
||||
local->crypt_info.tx_keyidx = i;
|
||||
}
|
||||
|
||||
done:
|
||||
@ -252,20 +226,20 @@ static int prism2_ioctl_giwencode(struct net_device *dev,
|
||||
local_info_t *local;
|
||||
int i, len;
|
||||
u16 val;
|
||||
struct ieee80211_crypt_data *crypt;
|
||||
struct lib80211_crypt_data *crypt;
|
||||
|
||||
iface = netdev_priv(dev);
|
||||
local = iface->local;
|
||||
|
||||
i = erq->flags & IW_ENCODE_INDEX;
|
||||
if (i < 1 || i > 4)
|
||||
i = local->tx_keyidx;
|
||||
i = local->crypt_info.tx_keyidx;
|
||||
else
|
||||
i--;
|
||||
if (i < 0 || i >= WEP_KEYS)
|
||||
return -EINVAL;
|
||||
|
||||
crypt = local->crypt[i];
|
||||
crypt = local->crypt_info.crypt[i];
|
||||
erq->flags = i + 1;
|
||||
|
||||
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;
|
||||
struct iw_encode_ext *ext = (struct iw_encode_ext *) extra;
|
||||
int i, ret = 0;
|
||||
struct ieee80211_crypto_ops *ops;
|
||||
struct ieee80211_crypt_data **crypt;
|
||||
struct lib80211_crypto_ops *ops;
|
||||
struct lib80211_crypt_data **crypt;
|
||||
void *sta_ptr;
|
||||
u8 *addr;
|
||||
const char *alg, *module;
|
||||
@ -3237,7 +3211,7 @@ static int prism2_ioctl_siwencodeext(struct net_device *dev,
|
||||
if (i > WEP_KEYS)
|
||||
return -EINVAL;
|
||||
if (i < 1 || i > WEP_KEYS)
|
||||
i = local->tx_keyidx;
|
||||
i = local->crypt_info.tx_keyidx;
|
||||
else
|
||||
i--;
|
||||
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 &&
|
||||
addr[3] == 0xff && addr[4] == 0xff && addr[5] == 0xff) {
|
||||
sta_ptr = NULL;
|
||||
crypt = &local->crypt[i];
|
||||
crypt = &local->crypt_info.crypt[i];
|
||||
} else {
|
||||
if (i != 0)
|
||||
return -EINVAL;
|
||||
@ -3260,7 +3234,7 @@ static int prism2_ioctl_siwencodeext(struct net_device *dev,
|
||||
* is emulated by using default key idx 0.
|
||||
*/
|
||||
i = 0;
|
||||
crypt = &local->crypt[i];
|
||||
crypt = &local->crypt_info.crypt[i];
|
||||
} else
|
||||
return -EINVAL;
|
||||
}
|
||||
@ -3269,22 +3243,22 @@ static int prism2_ioctl_siwencodeext(struct net_device *dev,
|
||||
if ((erq->flags & IW_ENCODE_DISABLED) ||
|
||||
ext->alg == IW_ENCODE_ALG_NONE) {
|
||||
if (*crypt)
|
||||
prism2_crypt_delayed_deinit(local, crypt);
|
||||
lib80211_crypt_delayed_deinit(&local->crypt_info, crypt);
|
||||
goto done;
|
||||
}
|
||||
|
||||
switch (ext->alg) {
|
||||
case IW_ENCODE_ALG_WEP:
|
||||
alg = "WEP";
|
||||
module = "ieee80211_crypt_wep";
|
||||
module = "lib80211_crypt_wep";
|
||||
break;
|
||||
case IW_ENCODE_ALG_TKIP:
|
||||
alg = "TKIP";
|
||||
module = "ieee80211_crypt_tkip";
|
||||
module = "lib80211_crypt_tkip";
|
||||
break;
|
||||
case IW_ENCODE_ALG_CCMP:
|
||||
alg = "CCMP";
|
||||
module = "ieee80211_crypt_ccmp";
|
||||
module = "lib80211_crypt_ccmp";
|
||||
break;
|
||||
default:
|
||||
printk(KERN_DEBUG "%s: unsupported algorithm %d\n",
|
||||
@ -3293,10 +3267,10 @@ static int prism2_ioctl_siwencodeext(struct net_device *dev,
|
||||
goto done;
|
||||
}
|
||||
|
||||
ops = ieee80211_get_crypto_ops(alg);
|
||||
ops = lib80211_get_crypto_ops(alg);
|
||||
if (ops == NULL) {
|
||||
request_module(module);
|
||||
ops = ieee80211_get_crypto_ops(alg);
|
||||
ops = lib80211_get_crypto_ops(alg);
|
||||
}
|
||||
if (ops == NULL) {
|
||||
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) {
|
||||
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);
|
||||
if (new_crypt == NULL) {
|
||||
ret = -ENOMEM;
|
||||
goto done;
|
||||
}
|
||||
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) {
|
||||
kfree(new_crypt);
|
||||
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 (!sta_ptr)
|
||||
local->tx_keyidx = i;
|
||||
local->crypt_info.tx_keyidx = i;
|
||||
}
|
||||
|
||||
|
||||
if (sta_ptr == NULL && ext->key_len > 0) {
|
||||
int first = 1, j;
|
||||
for (j = 0; j < WEP_KEYS; j++) {
|
||||
if (j != i && local->crypt[j]) {
|
||||
if (j != i && local->crypt_info.crypt[j]) {
|
||||
first = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (first)
|
||||
local->tx_keyidx = i;
|
||||
local->crypt_info.tx_keyidx = i;
|
||||
}
|
||||
|
||||
done:
|
||||
@ -3399,7 +3374,7 @@ static int prism2_ioctl_giwencodeext(struct net_device *dev,
|
||||
{
|
||||
struct hostap_interface *iface = netdev_priv(dev);
|
||||
local_info_t *local = iface->local;
|
||||
struct ieee80211_crypt_data **crypt;
|
||||
struct lib80211_crypt_data **crypt;
|
||||
void *sta_ptr;
|
||||
int max_key_len, i;
|
||||
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;
|
||||
if (i < 1 || i > WEP_KEYS)
|
||||
i = local->tx_keyidx;
|
||||
i = local->crypt_info.tx_keyidx;
|
||||
else
|
||||
i--;
|
||||
|
||||
@ -3419,7 +3394,7 @@ static int prism2_ioctl_giwencodeext(struct net_device *dev,
|
||||
if (addr[0] == 0xff && addr[1] == 0xff && addr[2] == 0xff &&
|
||||
addr[3] == 0xff && addr[4] == 0xff && addr[5] == 0xff) {
|
||||
sta_ptr = NULL;
|
||||
crypt = &local->crypt[i];
|
||||
crypt = &local->crypt_info.crypt[i];
|
||||
} else {
|
||||
i = 0;
|
||||
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 ret = 0;
|
||||
struct ieee80211_crypto_ops *ops;
|
||||
struct ieee80211_crypt_data **crypt;
|
||||
struct lib80211_crypto_ops *ops;
|
||||
struct lib80211_crypt_data **crypt;
|
||||
void *sta_ptr;
|
||||
|
||||
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)
|
||||
return -EINVAL;
|
||||
sta_ptr = NULL;
|
||||
crypt = &local->crypt[param->u.crypt.idx];
|
||||
crypt = &local->crypt_info.crypt[param->u.crypt.idx];
|
||||
} else {
|
||||
if (param->u.crypt.idx)
|
||||
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 (crypt)
|
||||
prism2_crypt_delayed_deinit(local, crypt);
|
||||
lib80211_crypt_delayed_deinit(&local->crypt_info, crypt);
|
||||
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) {
|
||||
request_module("ieee80211_crypt_wep");
|
||||
ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
|
||||
request_module("lib80211_crypt_wep");
|
||||
ops = lib80211_get_crypto_ops(param->u.crypt.alg);
|
||||
} else if (ops == NULL && strcmp(param->u.crypt.alg, "TKIP") == 0) {
|
||||
request_module("ieee80211_crypt_tkip");
|
||||
ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
|
||||
request_module("lib80211_crypt_tkip");
|
||||
ops = lib80211_get_crypto_ops(param->u.crypt.alg);
|
||||
} else if (ops == NULL && strcmp(param->u.crypt.alg, "CCMP") == 0) {
|
||||
request_module("ieee80211_crypt_ccmp");
|
||||
ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
|
||||
request_module("lib80211_crypt_ccmp");
|
||||
ops = lib80211_get_crypto_ops(param->u.crypt.alg);
|
||||
}
|
||||
if (ops == NULL) {
|
||||
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;
|
||||
|
||||
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);
|
||||
if (new_crypt == NULL) {
|
||||
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 (!sta_ptr)
|
||||
local->tx_keyidx = param->u.crypt.idx;
|
||||
local->crypt_info.tx_keyidx = param->u.crypt.idx;
|
||||
else if (param->u.crypt.idx) {
|
||||
printk(KERN_DEBUG "%s: TX key idx setting failed\n",
|
||||
local->dev->name);
|
||||
@ -3604,7 +3579,7 @@ static int prism2_ioctl_get_encryption(local_info_t *local,
|
||||
struct prism2_hostapd_param *param,
|
||||
int param_len)
|
||||
{
|
||||
struct ieee80211_crypt_data **crypt;
|
||||
struct lib80211_crypt_data **crypt;
|
||||
void *sta_ptr;
|
||||
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) {
|
||||
sta_ptr = NULL;
|
||||
if (param->u.crypt.idx >= WEP_KEYS)
|
||||
param->u.crypt.idx = local->tx_keyidx;
|
||||
crypt = &local->crypt[param->u.crypt.idx];
|
||||
param->u.crypt.idx = local->crypt_info.tx_keyidx;
|
||||
crypt = &local->crypt_info.crypt[param->u.crypt.idx];
|
||||
} else {
|
||||
param->u.crypt.idx = 0;
|
||||
sta_ptr = ap_crypt_get_ptrs(local->ap, param->sta_addr, 0,
|
||||
|
@ -27,7 +27,7 @@
|
||||
#include <net/net_namespace.h>
|
||||
#include <net/iw_handler.h>
|
||||
#include <net/ieee80211.h>
|
||||
#include <net/ieee80211_crypt.h>
|
||||
#include <net/lib80211.h>
|
||||
#include <asm/uaccess.h>
|
||||
|
||||
#include "hostap_wlan.h"
|
||||
@ -343,10 +343,11 @@ int hostap_set_encryption(local_info_t *local)
|
||||
char keybuf[WEP_KEY_LEN + 1];
|
||||
enum { NONE, WEP, OTHER } encrypt_type;
|
||||
|
||||
idx = local->tx_keyidx;
|
||||
if (local->crypt[idx] == NULL || local->crypt[idx]->ops == NULL)
|
||||
idx = local->crypt_info.tx_keyidx;
|
||||
if (local->crypt_info.crypt[idx] == NULL ||
|
||||
local->crypt_info.crypt[idx]->ops == NULL)
|
||||
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;
|
||||
else
|
||||
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
|
||||
* same keylen */
|
||||
keylen = 6; /* first 5 octets */
|
||||
len = local->crypt[idx]->ops->get_key(keybuf, sizeof(keybuf),
|
||||
NULL, local->crypt[idx]->priv);
|
||||
len = local->crypt_info.crypt[idx]->ops->get_key(keybuf, sizeof(keybuf), NULL,
|
||||
local->crypt_info.crypt[idx]->priv);
|
||||
if (idx >= 0 && idx < WEP_KEYS && len > 5)
|
||||
keylen = WEP_KEY_LEN + 1; /* first 13 octets */
|
||||
|
||||
for (i = 0; i < WEP_KEYS; i++) {
|
||||
memset(keybuf, 0, sizeof(keybuf));
|
||||
if (local->crypt[i]) {
|
||||
(void) local->crypt[i]->ops->get_key(
|
||||
if (local->crypt_info.crypt[i]) {
|
||||
(void) local->crypt_info.crypt[i]->ops->get_key(
|
||||
keybuf, sizeof(keybuf),
|
||||
NULL, local->crypt[i]->priv);
|
||||
NULL, local->crypt_info.crypt[i]->priv);
|
||||
}
|
||||
if (local->func->set_rid(local->dev,
|
||||
HFA384X_RID_CNFDEFAULTKEY0 + i,
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/proc_fs.h>
|
||||
#include <net/ieee80211_crypt.h>
|
||||
#include <net/lib80211.h>
|
||||
|
||||
#include "hostap_wlan.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, "sw_tick_stuck=%d\n", local->sw_tick_stuck);
|
||||
for (i = 0; i < WEP_KEYS; i++) {
|
||||
if (local->crypt[i] && local->crypt[i]->ops) {
|
||||
p += sprintf(p, "crypt[%d]=%s\n",
|
||||
i, local->crypt[i]->ops->name);
|
||||
if (local->crypt_info.crypt[i] &&
|
||||
local->crypt_info.crypt[i]->ops) {
|
||||
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);
|
||||
@ -206,12 +207,13 @@ static int prism2_crypt_proc_read(char *page, char **start, off_t off,
|
||||
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++) {
|
||||
if (local->crypt[i] && local->crypt[i]->ops &&
|
||||
local->crypt[i]->ops->print_stats) {
|
||||
p = local->crypt[i]->ops->print_stats(
|
||||
p, local->crypt[i]->priv);
|
||||
if (local->crypt_info.crypt[i] &&
|
||||
local->crypt_info.crypt[i]->ops &&
|
||||
local->crypt_info.crypt[i]->ops->print_stats) {
|
||||
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 <net/iw_handler.h>
|
||||
#include <net/ieee80211_radiotap.h>
|
||||
#include <net/lib80211.h>
|
||||
|
||||
#include "hostap_config.h"
|
||||
#include "hostap_common.h"
|
||||
@ -763,10 +764,7 @@ struct local_info {
|
||||
|
||||
#define WEP_KEYS 4
|
||||
#define WEP_KEY_LEN 13
|
||||
struct ieee80211_crypt_data *crypt[WEP_KEYS];
|
||||
int tx_keyidx; /* default TX key index (crypt[tx_keyidx]) */
|
||||
struct timer_list crypt_deinit_timer;
|
||||
struct list_head crypt_deinit_list;
|
||||
struct lib80211_crypt_info crypt_info;
|
||||
|
||||
int open_wep; /* allow unencrypted frames */
|
||||
int host_encrypt;
|
||||
|
191
drivers/net/wireless/ipw2x00/Kconfig
Normal file
191
drivers/net/wireless/ipw2x00/Kconfig
Normal file
@ -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.
|
14
drivers/net/wireless/ipw2x00/Makefile
Normal file
14
drivers/net/wireless/ipw2x00/Makefile
Normal file
@ -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
|
||||
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(config, "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
|
||||
@ -7620,7 +7620,7 @@ static int ipw2100_wx_set_auth(struct net_device *dev,
|
||||
struct ipw2100_priv *priv = ieee80211_priv(dev);
|
||||
struct ieee80211_device *ieee = priv->ieee;
|
||||
struct iw_param *param = &wrqu->param;
|
||||
struct ieee80211_crypt_data *crypt;
|
||||
struct lib80211_crypt_data *crypt;
|
||||
unsigned long flags;
|
||||
int ret = 0;
|
||||
|
||||
@ -7635,7 +7635,7 @@ static int ipw2100_wx_set_auth(struct net_device *dev,
|
||||
break;
|
||||
|
||||
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)
|
||||
break;
|
||||
|
||||
@ -7712,7 +7712,7 @@ static int ipw2100_wx_get_auth(struct net_device *dev,
|
||||
{
|
||||
struct ipw2100_priv *priv = ieee80211_priv(dev);
|
||||
struct ieee80211_device *ieee = priv->ieee;
|
||||
struct ieee80211_crypt_data *crypt;
|
||||
struct lib80211_crypt_data *crypt;
|
||||
struct iw_param *param = &wrqu->param;
|
||||
int ret = 0;
|
||||
|
||||
@ -7728,7 +7728,7 @@ static int ipw2100_wx_get_auth(struct net_device *dev,
|
||||
break;
|
||||
|
||||
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) {
|
||||
IPW_DEBUG_WARNING("Can't get TKIP countermeasures: "
|
||||
"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 ieee80211_device *ieee = priv->ieee;
|
||||
struct iw_param *param = &wrqu->param;
|
||||
struct ieee80211_crypt_data *crypt;
|
||||
struct lib80211_crypt_data *crypt;
|
||||
unsigned long flags;
|
||||
int ret = 0;
|
||||
|
||||
@ -6622,7 +6622,7 @@ static int ipw_wx_set_auth(struct net_device *dev,
|
||||
break;
|
||||
|
||||
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)
|
||||
break;
|
||||
|
||||
@ -6699,7 +6699,7 @@ static int ipw_wx_get_auth(struct net_device *dev,
|
||||
{
|
||||
struct ipw_priv *priv = ieee80211_priv(dev);
|
||||
struct ieee80211_device *ieee = priv->ieee;
|
||||
struct ieee80211_crypt_data *crypt;
|
||||
struct lib80211_crypt_data *crypt;
|
||||
struct iw_param *param = &wrqu->param;
|
||||
int ret = 0;
|
||||
|
||||
@ -6715,7 +6715,7 @@ static int ipw_wx_get_auth(struct net_device *dev,
|
||||
break;
|
||||
|
||||
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)
|
||||
break;
|
||||
|
||||
@ -7575,8 +7575,7 @@ static int ipw_associate(void *data)
|
||||
}
|
||||
|
||||
if (!(priv->config & CFG_ASSOCIATE) &&
|
||||
!(priv->config & (CFG_STATIC_ESSID |
|
||||
CFG_STATIC_CHANNEL | CFG_STATIC_BSSID))) {
|
||||
!(priv->config & (CFG_STATIC_ESSID | CFG_STATIC_BSSID))) {
|
||||
IPW_DEBUG_ASSOC("Not attempting association (associate=0)\n");
|
||||
return 0;
|
||||
}
|
||||
@ -10252,8 +10251,8 @@ static int ipw_tx_skb(struct ipw_priv *priv, struct ieee80211_txb *txb,
|
||||
case SEC_LEVEL_1:
|
||||
tfd->u.data.tfd.tfd_24.mchdr.frame_ctl |=
|
||||
cpu_to_le16(IEEE80211_FCTL_PROTECTED);
|
||||
tfd->u.data.key_index = priv->ieee->tx_keyidx;
|
||||
if (priv->ieee->sec.key_sizes[priv->ieee->tx_keyidx] <=
|
||||
tfd->u.data.key_index = priv->ieee->crypt_info.tx_keyidx;
|
||||
if (priv->ieee->sec.key_sizes[priv->ieee->crypt_info.tx_keyidx] <=
|
||||
40)
|
||||
tfd->u.data.key_index |= DCT_WEP_KEY_64Bit;
|
||||
else
|
@ -180,13 +180,10 @@ struct net_device *alloc_ieee80211(int sizeof_priv)
|
||||
ieee->host_open_frag = 1;
|
||||
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);
|
||||
|
||||
lib80211_crypt_info_init(&ieee->crypt_info, dev->name, &ieee->lock);
|
||||
|
||||
ieee->wpa_enabled = 0;
|
||||
ieee->drop_unencrypted = 0;
|
||||
ieee->privacy_invoked = 0;
|
||||
@ -203,23 +200,7 @@ void free_ieee80211(struct net_device *dev)
|
||||
{
|
||||
struct ieee80211_device *ieee = netdev_priv(dev);
|
||||
|
||||
int i;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
lib80211_crypt_info_free(&ieee->crypt_info);
|
||||
|
||||
ieee80211_networks_free(ieee);
|
||||
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 */
|
||||
static int
|
||||
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;
|
||||
int res, hdrlen;
|
||||
@ -300,7 +300,7 @@ ieee80211_rx_frame_decrypt(struct ieee80211_device *ieee, struct sk_buff *skb,
|
||||
static int
|
||||
ieee80211_rx_frame_decrypt_msdu(struct ieee80211_device *ieee,
|
||||
struct sk_buff *skb, int keyidx,
|
||||
struct ieee80211_crypt_data *crypt)
|
||||
struct lib80211_crypt_data *crypt)
|
||||
{
|
||||
struct ieee80211_hdr_3addr *hdr;
|
||||
int res, hdrlen;
|
||||
@ -348,7 +348,7 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
|
||||
#endif
|
||||
u8 dst[ETH_ALEN];
|
||||
u8 src[ETH_ALEN];
|
||||
struct ieee80211_crypt_data *crypt = NULL;
|
||||
struct lib80211_crypt_data *crypt = NULL;
|
||||
int keyidx = 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
|
||||
* be provided via above code that would result in keyidx
|
||||
* being out of range */
|
||||
crypt = ieee->crypt[keyidx];
|
||||
crypt = ieee->crypt_info.crypt[keyidx];
|
||||
|
||||
#ifdef NOT_YET
|
||||
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,
|
||||
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;
|
||||
|
||||
if (crypt == NULL)
|
||||
@ -270,7 +271,7 @@ int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev)
|
||||
.qos_ctl = 0
|
||||
};
|
||||
u8 dest[ETH_ALEN], src[ETH_ALEN];
|
||||
struct ieee80211_crypt_data *crypt;
|
||||
struct lib80211_crypt_data *crypt;
|
||||
int priority = skb->priority;
|
||||
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;
|
||||
|
||||
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) &&
|
||||
ieee->sec.encrypt;
|
@ -307,7 +307,7 @@ int ieee80211_wx_set_encode(struct ieee80211_device *ieee,
|
||||
.flags = 0
|
||||
};
|
||||
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;
|
||||
DECLARE_SSID_BUF(ssid);
|
||||
|
||||
@ -321,30 +321,30 @@ int ieee80211_wx_set_encode(struct ieee80211_device *ieee,
|
||||
key_provided = 1;
|
||||
} else {
|
||||
key_provided = 0;
|
||||
key = ieee->tx_keyidx;
|
||||
key = ieee->crypt_info.tx_keyidx;
|
||||
}
|
||||
|
||||
IEEE80211_DEBUG_WX("Key: %d [%s]\n", key, key_provided ?
|
||||
"provided" : "default");
|
||||
|
||||
crypt = &ieee->crypt[key];
|
||||
crypt = &ieee->crypt_info.crypt[key];
|
||||
|
||||
if (erq->flags & IW_ENCODE_DISABLED) {
|
||||
if (key_provided && *crypt) {
|
||||
IEEE80211_DEBUG_WX("Disabling encryption on key %d.\n",
|
||||
key);
|
||||
ieee80211_crypt_delayed_deinit(ieee, crypt);
|
||||
lib80211_crypt_delayed_deinit(&ieee->crypt_info, crypt);
|
||||
} else
|
||||
IEEE80211_DEBUG_WX("Disabling encryption.\n");
|
||||
|
||||
/* Check all the keys to see if any are still configured,
|
||||
* and if no key index was provided, de-init them all */
|
||||
for (i = 0; i < WEP_KEYS; i++) {
|
||||
if (ieee->crypt[i] != NULL) {
|
||||
if (ieee->crypt_info.crypt[i] != NULL) {
|
||||
if (key_provided)
|
||||
break;
|
||||
ieee80211_crypt_delayed_deinit(ieee,
|
||||
&ieee->crypt[i]);
|
||||
lib80211_crypt_delayed_deinit(&ieee->crypt_info,
|
||||
&ieee->crypt_info.crypt[i]);
|
||||
}
|
||||
}
|
||||
|
||||
@ -366,21 +366,21 @@ int ieee80211_wx_set_encode(struct ieee80211_device *ieee,
|
||||
strcmp((*crypt)->ops->name, "WEP") != 0) {
|
||||
/* changing to use WEP; deinit previously used algorithm
|
||||
* on this key */
|
||||
ieee80211_crypt_delayed_deinit(ieee, crypt);
|
||||
lib80211_crypt_delayed_deinit(&ieee->crypt_info, crypt);
|
||||
}
|
||||
|
||||
if (*crypt == NULL && host_crypto) {
|
||||
struct ieee80211_crypt_data *new_crypt;
|
||||
struct lib80211_crypt_data *new_crypt;
|
||||
|
||||
/* take WEP into use */
|
||||
new_crypt = kzalloc(sizeof(struct ieee80211_crypt_data),
|
||||
new_crypt = kzalloc(sizeof(struct lib80211_crypt_data),
|
||||
GFP_KERNEL);
|
||||
if (new_crypt == NULL)
|
||||
return -ENOMEM;
|
||||
new_crypt->ops = ieee80211_get_crypto_ops("WEP");
|
||||
new_crypt->ops = lib80211_get_crypto_ops("WEP");
|
||||
if (!new_crypt->ops) {
|
||||
request_module("ieee80211_crypt_wep");
|
||||
new_crypt->ops = ieee80211_get_crypto_ops("WEP");
|
||||
request_module("lib80211_crypt_wep");
|
||||
new_crypt->ops = lib80211_get_crypto_ops("WEP");
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
}
|
||||
*crypt = new_crypt;
|
||||
@ -440,7 +440,7 @@ int ieee80211_wx_set_encode(struct ieee80211_device *ieee,
|
||||
if (key_provided) {
|
||||
IEEE80211_DEBUG_WX("Setting key %d to default Tx "
|
||||
"key.\n", key);
|
||||
ieee->tx_keyidx = key;
|
||||
ieee->crypt_info.tx_keyidx = key;
|
||||
sec.active_key = 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);
|
||||
int len, key;
|
||||
struct ieee80211_crypt_data *crypt;
|
||||
struct lib80211_crypt_data *crypt;
|
||||
struct ieee80211_security *sec = &ieee->sec;
|
||||
|
||||
IEEE80211_DEBUG_WX("GET_ENCODE\n");
|
||||
@ -496,9 +496,9 @@ int ieee80211_wx_get_encode(struct ieee80211_device *ieee,
|
||||
return -EINVAL;
|
||||
key--;
|
||||
} 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;
|
||||
|
||||
if (!sec->enabled) {
|
||||
@ -531,8 +531,8 @@ int ieee80211_wx_set_encodeext(struct ieee80211_device *ieee,
|
||||
int i, idx, ret = 0;
|
||||
int group_key = 0;
|
||||
const char *alg, *module;
|
||||
struct ieee80211_crypto_ops *ops;
|
||||
struct ieee80211_crypt_data **crypt;
|
||||
struct lib80211_crypto_ops *ops;
|
||||
struct lib80211_crypt_data **crypt;
|
||||
|
||||
struct ieee80211_security sec = {
|
||||
.flags = 0,
|
||||
@ -544,17 +544,17 @@ int ieee80211_wx_set_encodeext(struct ieee80211_device *ieee,
|
||||
return -EINVAL;
|
||||
idx--;
|
||||
} else
|
||||
idx = ieee->tx_keyidx;
|
||||
idx = ieee->crypt_info.tx_keyidx;
|
||||
|
||||
if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) {
|
||||
crypt = &ieee->crypt[idx];
|
||||
crypt = &ieee->crypt_info.crypt[idx];
|
||||
group_key = 1;
|
||||
} else {
|
||||
/* some Cisco APs use idx>0 for unicast in dynamic WEP */
|
||||
if (idx != 0 && ext->alg != IW_ENCODE_ALG_WEP)
|
||||
return -EINVAL;
|
||||
if (ieee->iw_mode == IW_MODE_INFRA)
|
||||
crypt = &ieee->crypt[idx];
|
||||
crypt = &ieee->crypt_info.crypt[idx];
|
||||
else
|
||||
return -EINVAL;
|
||||
}
|
||||
@ -563,10 +563,10 @@ int ieee80211_wx_set_encodeext(struct ieee80211_device *ieee,
|
||||
if ((encoding->flags & IW_ENCODE_DISABLED) ||
|
||||
ext->alg == IW_ENCODE_ALG_NONE) {
|
||||
if (*crypt)
|
||||
ieee80211_crypt_delayed_deinit(ieee, crypt);
|
||||
lib80211_crypt_delayed_deinit(&ieee->crypt_info, crypt);
|
||||
|
||||
for (i = 0; i < WEP_KEYS; i++)
|
||||
if (ieee->crypt[i] != NULL)
|
||||
if (ieee->crypt_info.crypt[i] != NULL)
|
||||
break;
|
||||
|
||||
if (i == WEP_KEYS) {
|
||||
@ -589,15 +589,15 @@ int ieee80211_wx_set_encodeext(struct ieee80211_device *ieee,
|
||||
switch (ext->alg) {
|
||||
case IW_ENCODE_ALG_WEP:
|
||||
alg = "WEP";
|
||||
module = "ieee80211_crypt_wep";
|
||||
module = "lib80211_crypt_wep";
|
||||
break;
|
||||
case IW_ENCODE_ALG_TKIP:
|
||||
alg = "TKIP";
|
||||
module = "ieee80211_crypt_tkip";
|
||||
module = "lib80211_crypt_tkip";
|
||||
break;
|
||||
case IW_ENCODE_ALG_CCMP:
|
||||
alg = "CCMP";
|
||||
module = "ieee80211_crypt_ccmp";
|
||||
module = "lib80211_crypt_ccmp";
|
||||
break;
|
||||
default:
|
||||
IEEE80211_DEBUG_WX("%s: unknown crypto alg %d\n",
|
||||
@ -606,10 +606,10 @@ int ieee80211_wx_set_encodeext(struct ieee80211_device *ieee,
|
||||
goto done;
|
||||
}
|
||||
|
||||
ops = ieee80211_get_crypto_ops(alg);
|
||||
ops = lib80211_get_crypto_ops(alg);
|
||||
if (ops == NULL) {
|
||||
request_module(module);
|
||||
ops = ieee80211_get_crypto_ops(alg);
|
||||
ops = lib80211_get_crypto_ops(alg);
|
||||
}
|
||||
if (ops == NULL) {
|
||||
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) {
|
||||
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);
|
||||
if (new_crypt == NULL) {
|
||||
@ -649,7 +649,7 @@ int ieee80211_wx_set_encodeext(struct ieee80211_device *ieee,
|
||||
|
||||
skip_host_crypt:
|
||||
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.flags |= SEC_ACTIVE_KEY;
|
||||
}
|
||||
@ -715,7 +715,7 @@ int ieee80211_wx_get_encodeext(struct ieee80211_device *ieee,
|
||||
return -EINVAL;
|
||||
idx--;
|
||||
} else
|
||||
idx = ieee->tx_keyidx;
|
||||
idx = ieee->crypt_info.tx_keyidx;
|
||||
|
||||
if (!(ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) &&
|
||||
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_LEDS) += iwl-led.o
|
||||
iwlcore-$(CONFIG_IWLWIFI_RFKILL) += iwl-rfkill.o
|
||||
iwlcore-$(CONFIG_IWLAGN_SPECTRUM_MEASUREMENT) += iwl-spectrum.o
|
||||
|
||||
obj-$(CONFIG_IWLAGN) += iwlagn.o
|
||||
iwlagn-objs := iwl-agn.o iwl-agn-rs.o
|
||||
|
@ -819,64 +819,6 @@ enum {
|
||||
#define IWL49_NUM_QUEUES 16
|
||||
#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
|
||||
@ -896,64 +838,9 @@ struct iwl_tfd {
|
||||
* padding puts each byte count table on a 1024-byte boundary;
|
||||
* 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];
|
||||
u8 pad[1024 - (TFD_QUEUE_BC_SIZE) * sizeof(__le16)];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
|
||||
/**
|
||||
* 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__ */
|
||||
#endif /* !__iwl_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 */
|
||||
iwl_write_prph(priv, IWL49_SCD_DRAM_BASE_ADDR,
|
||||
(priv->shared_phys +
|
||||
offsetof(struct iwl4965_shared, queues_bc_tbls)) >> 10);
|
||||
priv->scd_bc_tbls.dma >> 10);
|
||||
|
||||
/* Disable chain mode for all queues */
|
||||
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.scd_bc_tbls_size =
|
||||
IWL49_NUM_QUEUES * sizeof(struct iwl4965_scd_bc_tbl);
|
||||
priv->hw_params.max_stations = IWL4965_STATION_COUNT;
|
||||
priv->hw_params.bcast_sta_id = IWL4965_BROADCAST_ID;
|
||||
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
|
||||
|
||||
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
|
||||
*/
|
||||
@ -1668,7 +1639,7 @@ static void iwl4965_txq_update_byte_cnt_tbl(struct iwl_priv *priv,
|
||||
struct iwl_tx_queue *txq,
|
||||
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 write_ptr = txq->q.write_ptr;
|
||||
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);
|
||||
/* 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 (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;
|
||||
}
|
||||
|
||||
@ -2304,9 +2275,6 @@ static struct iwl_hcmd_utils_ops iwl4965_hcmd_utils = {
|
||||
|
||||
static struct iwl_lib_ops iwl4965_lib = {
|
||||
.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_set_sched = iwl4965_txq_set_sched,
|
||||
.txq_agg_enable = iwl4965_txq_agg_enable,
|
||||
|
@ -90,45 +90,10 @@
|
||||
* @tfd_offset 0-12 - tx command byte count
|
||||
* 12-16 - station index
|
||||
*/
|
||||
struct iwl5000_schedq_bc_tbl {
|
||||
struct iwl5000_scd_bc_tbl {
|
||||
__le16 tfd_offset[TFD_QUEUE_BC_SIZE];
|
||||
} __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__ */
|
||||
|
||||
|
@ -721,11 +721,9 @@ static int iwl5000_alive_notify(struct iwl_priv *priv)
|
||||
iwl_write_targ_mem(priv, a, 0);
|
||||
|
||||
iwl_write_prph(priv, IWL50_SCD_DRAM_BASE_ADDR,
|
||||
(priv->shared_phys +
|
||||
offsetof(struct iwl5000_shared, queues_bc_tbls)) >> 10);
|
||||
priv->scd_bc_tbls.dma >> 10);
|
||||
iwl_write_prph(priv, IWL50_SCD_QUEUECHAIN_SEL,
|
||||
IWL50_SCD_QUEUECHAIN_SEL_ALL(
|
||||
priv->hw_params.max_txq_num));
|
||||
IWL50_SCD_QUEUECHAIN_SEL_ALL(priv->hw_params.max_txq_num));
|
||||
iwl_write_prph(priv, IWL50_SCD_AGGR_SEL, 0);
|
||||
|
||||
/* 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.scd_bc_tbls_size =
|
||||
IWL50_NUM_QUEUES * sizeof(struct iwl5000_scd_bc_tbl);
|
||||
priv->hw_params.max_stations = IWL5000_STATION_COUNT;
|
||||
priv->hw_params.bcast_sta_id = IWL5000_BROADCAST_ID;
|
||||
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;
|
||||
}
|
||||
|
||||
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
|
||||
*/
|
||||
@ -890,7 +860,7 @@ static void iwl5000_txq_update_byte_cnt_tbl(struct iwl_priv *priv,
|
||||
struct iwl_tx_queue *txq,
|
||||
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 txq_id = txq->q.id;
|
||||
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));
|
||||
|
||||
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)
|
||||
shared_data->queues_bc_tbls[txq_id].
|
||||
scd_bc_tbl[txq_id].
|
||||
tfd_offset[TFD_QUEUE_SIZE_MAX + write_ptr] = bc_ent;
|
||||
}
|
||||
|
||||
static void iwl5000_txq_inval_byte_cnt_tbl(struct iwl_priv *priv,
|
||||
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 read_ptr = txq->q.read_ptr;
|
||||
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;
|
||||
|
||||
bc_ent = cpu_to_le16(1 | (sta_id << 12));
|
||||
shared_data->queues_bc_tbls[txq_id].
|
||||
tfd_offset[read_ptr] = bc_ent;
|
||||
scd_bc_tbl[txq_id].tfd_offset[read_ptr] = bc_ent;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@ -1458,9 +1427,6 @@ static struct iwl_hcmd_utils_ops iwl5000_hcmd_utils = {
|
||||
|
||||
static struct iwl_lib_ops iwl5000_lib = {
|
||||
.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_inval_byte_cnt_tbl = iwl5000_txq_inval_byte_cnt_tbl,
|
||||
.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;
|
||||
}
|
||||
|
||||
#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;
|
||||
}
|
||||
|
||||
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,
|
||||
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_ERROR] = iwl_rx_reply_error;
|
||||
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_DEBUG_STATISTIC_NOTIFIC] =
|
||||
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[STATISTICS_NOTIFICATION] = iwl_rx_statistics;
|
||||
|
||||
iwl_setup_spectrum_handlers(priv);
|
||||
iwl_setup_rx_scan_handlers(priv);
|
||||
|
||||
/* 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
|
||||
* 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;
|
||||
|
||||
/* Rx interrupt, but nothing sent from uCode */
|
||||
@ -2002,6 +1851,10 @@ static int iwl_read_ucode(struct iwl_priv *priv)
|
||||
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
|
||||
* 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);
|
||||
|
||||
/* 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))
|
||||
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);
|
||||
else
|
||||
priv->cfg->ops->lib->apm_ops.reset(priv);
|
||||
priv->cfg->ops->lib->free_shared_mem(priv);
|
||||
|
||||
exit:
|
||||
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);
|
||||
|
||||
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);
|
||||
if (ret) {
|
||||
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... */
|
||||
}
|
||||
|
||||
/* 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,
|
||||
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);
|
||||
if (!beacon)
|
||||
return -ENOMEM;
|
||||
mutex_lock(&priv->mutex);
|
||||
rc = iwl_mac_beacon_update(hw, beacon);
|
||||
mutex_unlock(&priv->mutex);
|
||||
if (rc)
|
||||
return rc;
|
||||
}
|
||||
@ -3529,18 +3383,15 @@ static int iwl_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb)
|
||||
unsigned long flags;
|
||||
__le64 timestamp;
|
||||
|
||||
mutex_lock(&priv->mutex);
|
||||
IWL_DEBUG_MAC80211("enter\n");
|
||||
|
||||
if (!iwl_is_ready_rf(priv)) {
|
||||
IWL_DEBUG_MAC80211("leave - RF not ready\n");
|
||||
mutex_unlock(&priv->mutex);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
if (priv->iw_mode != NL80211_IFTYPE_ADHOC) {
|
||||
IWL_DEBUG_MAC80211("leave - not IBSS\n");
|
||||
mutex_unlock(&priv->mutex);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
@ -3562,7 +3413,6 @@ static int iwl_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb)
|
||||
|
||||
iwl_post_associate(priv);
|
||||
|
||||
mutex_unlock(&priv->mutex);
|
||||
|
||||
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,
|
||||
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,
|
||||
struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
@ -4091,9 +3868,6 @@ static struct attribute *iwl_sysfs_entries[] = {
|
||||
&dev_attr_channels.attr,
|
||||
&dev_attr_flags.attr,
|
||||
&dev_attr_filter_flags.attr,
|
||||
#ifdef CONFIG_IWLAGN_SPECTRUM_MEASUREMENT
|
||||
&dev_attr_measurement.attr,
|
||||
#endif
|
||||
&dev_attr_power_level.attr,
|
||||
&dev_attr_retry_rate.attr,
|
||||
&dev_attr_statistics.attr,
|
||||
|
@ -213,10 +213,11 @@ struct iwl_cmd_header {
|
||||
} __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_MPDU (response only)
|
||||
* REPLY_TX (both command and response)
|
||||
* REPLY_TX_LINK_QUALITY_CMD
|
||||
*
|
||||
@ -230,8 +231,9 @@ struct iwl_cmd_header {
|
||||
* 6) 54 Mbps
|
||||
* 7) 60 Mbps
|
||||
*
|
||||
* 3: 0) Single stream (SISO)
|
||||
* 4-3: 0) Single stream (SISO)
|
||||
* 1) Dual stream (MIMO)
|
||||
* 2) Triple stream (MIMO)
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
#define RATE_MCS_CODE_MSK 0x7
|
||||
#define RATE_MCS_MIMO_POS 3
|
||||
#define RATE_MCS_MIMO_MSK 0x8
|
||||
#define RATE_MCS_SPATIAL_POS 3
|
||||
#define RATE_MCS_SPATIAL_MSK 0x18
|
||||
#define RATE_MCS_HT_DUP_POS 5
|
||||
#define RATE_MCS_HT_DUP_MSK 0x20
|
||||
|
||||
|
@ -30,10 +30,9 @@
|
||||
#include <linux/module.h>
|
||||
#include <net/mac80211.h>
|
||||
|
||||
struct iwl_priv; /* FIXME: remove */
|
||||
#include "iwl-debug.h"
|
||||
#include "iwl-eeprom.h"
|
||||
#include "iwl-dev.h" /* FIXME: remove */
|
||||
#include "iwl-debug.h"
|
||||
#include "iwl-core.h"
|
||||
#include "iwl-io.h"
|
||||
#include "iwl-rfkill.h"
|
||||
@ -190,52 +189,6 @@ void iwl_hw_detect(struct iwl_priv *priv)
|
||||
}
|
||||
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)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
@ -102,10 +102,6 @@ struct iwl_hcmd_utils_ops {
|
||||
struct iwl_lib_ops {
|
||||
/* set hw dependent parameters */
|
||||
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 */
|
||||
void (*txq_update_byte_cnt_tbl)(struct iwl_priv *priv,
|
||||
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_init_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
|
||||
@ -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);
|
||||
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 *
|
||||
*****************************************************/
|
||||
|
@ -40,6 +40,13 @@ do { if ((priv->debug_level & (level)) && net_ratelimit()) \
|
||||
dev_printk(KERN_ERR, &(priv->hw->wiphy->dev), "%c %s " fmt, \
|
||||
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
|
||||
struct iwl_debugfs {
|
||||
const char *name;
|
||||
@ -70,6 +77,9 @@ void iwl_dbgfs_unregister(struct iwl_priv *priv);
|
||||
#else
|
||||
#define IWL_DEBUG(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 */
|
||||
|
||||
|
||||
|
@ -301,7 +301,6 @@ struct iwl_host_cmd {
|
||||
|
||||
/**
|
||||
* struct iwl_rx_queue - Rx queue
|
||||
* @processed: Internal index to last handled Rx packet
|
||||
* @read: Shared index to newest available Rx buffer
|
||||
* @write: Shared index to oldest written Rx packet
|
||||
* @free_count: Number of pre-allocated buffers in rx_free
|
||||
@ -316,13 +315,14 @@ struct iwl_rx_queue {
|
||||
dma_addr_t dma_addr;
|
||||
struct iwl_rx_mem_buffer pool[RX_QUEUE_SIZE + RX_FREE_BUFFERS];
|
||||
struct iwl_rx_mem_buffer *queue[RX_QUEUE_SIZE];
|
||||
u32 processed;
|
||||
u32 read;
|
||||
u32 write;
|
||||
u32 free_count;
|
||||
struct list_head rx_free;
|
||||
struct list_head rx_used;
|
||||
int need_update;
|
||||
struct iwl_rb_status *rb_stts;
|
||||
dma_addr_t rb_stts_dma;
|
||||
spinlock_t lock;
|
||||
};
|
||||
|
||||
@ -507,6 +507,7 @@ struct iwl_sensitivity_ranges {
|
||||
/**
|
||||
* struct iwl_hw_params
|
||||
* @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
|
||||
* @valid_tx/rx_ant: usable antennas
|
||||
* @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 {
|
||||
u16 max_txq_num;
|
||||
u16 scd_bc_tbls_size;
|
||||
u8 tx_chains_num;
|
||||
u8 rx_chains_num;
|
||||
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;
|
||||
|
||||
|
||||
/* Structures, enum, and defines specific to the 4965 */
|
||||
|
||||
#define IWL_KW_SIZE 0x1000 /*4k */
|
||||
|
||||
struct iwl_kw {
|
||||
dma_addr_t dma_addr;
|
||||
void *v_addr;
|
||||
struct iwl_dma_ptr {
|
||||
dma_addr_t dma;
|
||||
void *addr;
|
||||
size_t size;
|
||||
};
|
||||
|
||||
@ -907,7 +905,9 @@ struct iwl_priv {
|
||||
struct iwl_rx_queue rxq;
|
||||
struct iwl_tx_queue txq[IWL_MAX_NUM_QUEUES];
|
||||
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 */
|
||||
|
||||
unsigned long status;
|
||||
@ -967,11 +967,7 @@ struct iwl_priv {
|
||||
struct ieee80211_vif *vif;
|
||||
|
||||
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
|
||||
* 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;
|
||||
}
|
||||
|
||||
#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(
|
||||
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_INT_HOST_VAL (0x00001000)
|
||||
|
||||
#define FH_RCSR_CHNL0_RX_CONFIG_SINGLE_FRAME (0x00008000)
|
||||
|
||||
|
||||
/**
|
||||
* Rx Shared Status Registers (RSSR)
|
||||
@ -403,5 +405,86 @@
|
||||
#define TFD_QUEUE_SIZE_BC_DUP (64)
|
||||
#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__ */
|
||||
|
@ -257,15 +257,11 @@ int iwl_power_update_mode(struct iwl_priv *priv, bool force)
|
||||
struct iwl_power_mgr *setting = &(priv->power_data);
|
||||
int ret = 0;
|
||||
u16 uninitialized_var(final_mode);
|
||||
bool update_chains;
|
||||
|
||||
/* Don't update the RX chain when chain noise calibration is running */
|
||||
if (priv->chain_noise_data.state != IWL_CHAIN_NOISE_DONE &&
|
||||
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;
|
||||
}
|
||||
update_chains = priv->chain_noise_data.state == IWL_CHAIN_NOISE_DONE ||
|
||||
priv->chain_noise_data.state == IWL_CHAIN_NOISE_ALIVE;
|
||||
|
||||
/* If on battery, set to 3,
|
||||
* 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
|
||||
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);
|
||||
|
||||
else
|
||||
IWL_DEBUG_POWER("Cannot update the power, chain noise "
|
||||
"calibration running: %d\n",
|
||||
priv->chain_noise_data.state);
|
||||
if (!ret)
|
||||
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.
|
||||
* Increment device's write pointer in multiples of 8. */
|
||||
if ((write != (rxq->write & ~0x7))
|
||||
|| (abs(rxq->write - rxq->read) > 7)) {
|
||||
if (write != (rxq->write & ~0x7)) {
|
||||
spin_lock_irqsave(&rxq->lock, flags);
|
||||
rxq->need_update = 1;
|
||||
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,
|
||||
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->rb_stts = NULL;
|
||||
}
|
||||
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) */
|
||||
rxq->bd = pci_alloc_consistent(dev, 4 * RX_QUEUE_SIZE, &rxq->dma_addr);
|
||||
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 */
|
||||
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->need_update = 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);
|
||||
|
||||
@ -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 */
|
||||
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
|
||||
* 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_CHNL0_RX_IGNORE_RXF_EMPTY |
|
||||
FH_RCSR_CHNL0_RX_CONFIG_IRQ_DEST_INT_HOST_VAL |
|
||||
FH_RCSR_CHNL0_RX_CONFIG_SINGLE_FRAME |
|
||||
rb_size|
|
||||
(rb_timeout << FH_RCSR_RX_CONFIG_REG_IRQ_RBTH_POS)|
|
||||
(rfdnlog << FH_RCSR_RX_CONFIG_RBDCB_SIZE_POS));
|
||||
|
198
drivers/net/wireless/iwlwifi/iwl-spectrum.c
Normal file
198
drivers/net/wireless/iwlwifi/iwl-spectrum.c
Normal file
@ -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];
|
||||
} u;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
#endif
|
||||
|
@ -56,6 +56,26 @@ static const u16 default_tid_to_tx_fifo[] = {
|
||||
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)
|
||||
{
|
||||
struct iwl_tfd_tb *tb = &tfd->tbs[idx];
|
||||
@ -517,8 +537,9 @@ void iwl_hw_txq_ctx_free(struct iwl_priv *priv)
|
||||
else
|
||||
iwl_tx_queue_free(priv, txq_id);
|
||||
|
||||
/* Keep-warm buffer */
|
||||
iwl_kw_free(priv);
|
||||
iwl_free_dma_ptr(priv, &priv->kw);
|
||||
|
||||
iwl_free_dma_ptr(priv, &priv->scd_bc_tbls);
|
||||
}
|
||||
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;
|
||||
unsigned long flags;
|
||||
|
||||
iwl_kw_free(priv);
|
||||
|
||||
/* Free all tx/cmd queues and keep-warm buffer */
|
||||
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 */
|
||||
ret = iwl_kw_alloc(priv);
|
||||
ret = iwl_alloc_dma_ptr(priv, &priv->kw, IWL_KW_SIZE);
|
||||
if (ret) {
|
||||
IWL_ERROR("Keep Warm allocation failed\n");
|
||||
goto error_kw;
|
||||
@ -556,16 +581,13 @@ int iwl_txq_ctx_reset(struct iwl_priv *priv)
|
||||
/* Turn off all Tx DMA fifos */
|
||||
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);
|
||||
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) */
|
||||
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:
|
||||
iwl_hw_txq_ctx_free(priv);
|
||||
error_reset:
|
||||
iwl_kw_free(priv);
|
||||
iwl_free_dma_ptr(priv, &priv->kw);
|
||||
error_kw:
|
||||
iwl_free_dma_ptr(priv, &priv->scd_bc_tbls);
|
||||
error_bc_tbls:
|
||||
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
|
||||
* in the queue management code. */
|
||||
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;
|
||||
}
|
||||
|
||||
cmd_index = get_cmd_index(&priv->txq[IWL_CMD_QUEUE_NUM].q, index, huge);
|
||||
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;
|
||||
}
|
||||
|
||||
static u8 iwl3945_rate_get_lowest_plcp(int rate_mask)
|
||||
static u8 iwl3945_rate_get_lowest_plcp(struct iwl3945_priv *priv)
|
||||
{
|
||||
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;
|
||||
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 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)
|
||||
@ -1446,16 +1457,7 @@ static int iwl3945_send_beacon_cmd(struct iwl3945_priv *priv)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
if (!(priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK)) {
|
||||
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;
|
||||
}
|
||||
rate = iwl3945_rate_get_lowest_plcp(priv);
|
||||
|
||||
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_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,
|
||||
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
|
||||
* from protocol/runtime uCode (initialization uCode's
|
||||
@ -5704,6 +5710,14 @@ static void iwl3945_alive_start(struct iwl3945_priv *priv)
|
||||
if (priv->error_recovering)
|
||||
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;
|
||||
|
||||
restart:
|
||||
@ -6710,9 +6724,6 @@ static void iwl3945_config_ap(struct iwl3945_priv *priv)
|
||||
* 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,
|
||||
struct ieee80211_vif *vif,
|
||||
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);
|
||||
if (!beacon)
|
||||
return -ENOMEM;
|
||||
mutex_lock(&priv->mutex);
|
||||
rc = iwl3945_mac_beacon_update(hw, beacon);
|
||||
mutex_unlock(&priv->mutex);
|
||||
if (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;
|
||||
unsigned long flags;
|
||||
|
||||
mutex_lock(&priv->mutex);
|
||||
IWL_DEBUG_MAC80211("enter\n");
|
||||
|
||||
if (!iwl3945_is_ready_rf(priv)) {
|
||||
IWL_DEBUG_MAC80211("leave - RF not ready\n");
|
||||
mutex_unlock(&priv->mutex);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
if (priv->iw_mode != NL80211_IFTYPE_ADHOC) {
|
||||
IWL_DEBUG_MAC80211("leave - not IBSS\n");
|
||||
mutex_unlock(&priv->mutex);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
@ -7219,7 +7229,6 @@ static int iwl3945_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *sk
|
||||
|
||||
iwl3945_post_associate(priv);
|
||||
|
||||
mutex_unlock(&priv->mutex);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -159,7 +159,8 @@ out:
|
||||
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;
|
||||
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.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);
|
||||
if (!ret) {
|
||||
lbs_deb_cmd("Set WOL criteria to %x\n", criteria);
|
||||
priv->wol_criteria = criteria;
|
||||
if (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 {
|
||||
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);
|
||||
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);
|
||||
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_MULTICAST_DATA 0x0008
|
||||
#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 */
|
||||
/* 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_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 = {
|
||||
|
@ -220,6 +220,14 @@ enum cmd_fwt_access_opts {
|
||||
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 */
|
||||
enum cmd_mesh_access_opts {
|
||||
CMD_ACT_MESH_GET_TTL = 1,
|
||||
|
@ -580,13 +580,37 @@ struct MrvlIEtype_keyParamSet {
|
||||
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_header hdr;
|
||||
__le32 criteria;
|
||||
uint8_t gpio;
|
||||
uint8_t gap;
|
||||
uint16_t gap;
|
||||
struct wol_config wol_conf;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
|
||||
|
||||
struct cmd_ds_802_11_key_material {
|
||||
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_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.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);
|
||||
|
||||
if (vif->type != NL80211_IFTYPE_AP)
|
||||
if (vif->type != NL80211_IFTYPE_AP &&
|
||||
vif->type != NL80211_IFTYPE_MESH_POINT)
|
||||
return;
|
||||
|
||||
skb = ieee80211_beacon_get(hw, vif);
|
||||
@ -774,7 +775,8 @@ static int __init init_mac80211_hwsim(void)
|
||||
hw->queues = 4;
|
||||
hw->wiphy->interface_modes =
|
||||
BIT(NL80211_IFTYPE_STATION) |
|
||||
BIT(NL80211_IFTYPE_AP);
|
||||
BIT(NL80211_IFTYPE_AP) |
|
||||
BIT(NL80211_IFTYPE_MESH_POINT);
|
||||
hw->ampdu_queues = 1;
|
||||
|
||||
/* 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 *end_buf,
|
||||
union hermes_scan_info *bss,
|
||||
unsigned int last_scanned)
|
||||
unsigned long last_scanned)
|
||||
{
|
||||
struct orinoco_private *priv = netdev_priv(dev);
|
||||
u16 capabilities;
|
||||
@ -5591,7 +5591,7 @@ static inline char *orinoco_translate_ext_scan(struct net_device *dev,
|
||||
char *current_ev,
|
||||
char *end_buf,
|
||||
struct agere_ext_scan_info *bss,
|
||||
unsigned int last_scanned)
|
||||
unsigned long last_scanned)
|
||||
{
|
||||
u16 capabilities;
|
||||
u16 channel;
|
||||
|
@ -69,14 +69,14 @@ static void rt2400pci_bbp_write(struct rt2x00_dev *rt2x00dev,
|
||||
{
|
||||
u32 reg;
|
||||
|
||||
mutex_lock(&rt2x00dev->csr_mutex);
|
||||
|
||||
/*
|
||||
* Wait until the BBP becomes ready.
|
||||
*/
|
||||
reg = rt2400pci_bbp_check(rt2x00dev);
|
||||
if (rt2x00_get_field32(reg, BBPCSR_BUSY)) {
|
||||
ERROR(rt2x00dev, "BBPCSR register busy. Write failed.\n");
|
||||
return;
|
||||
}
|
||||
if (rt2x00_get_field32(reg, BBPCSR_BUSY))
|
||||
goto exit_fail;
|
||||
|
||||
/*
|
||||
* 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);
|
||||
|
||||
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,
|
||||
@ -95,14 +104,14 @@ static void rt2400pci_bbp_read(struct rt2x00_dev *rt2x00dev,
|
||||
{
|
||||
u32 reg;
|
||||
|
||||
mutex_lock(&rt2x00dev->csr_mutex);
|
||||
|
||||
/*
|
||||
* Wait until the BBP becomes ready.
|
||||
*/
|
||||
reg = rt2400pci_bbp_check(rt2x00dev);
|
||||
if (rt2x00_get_field32(reg, BBPCSR_BUSY)) {
|
||||
ERROR(rt2x00dev, "BBPCSR register busy. Read failed.\n");
|
||||
return;
|
||||
}
|
||||
if (rt2x00_get_field32(reg, BBPCSR_BUSY))
|
||||
goto exit_fail;
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
reg = rt2400pci_bbp_check(rt2x00dev);
|
||||
if (rt2x00_get_field32(reg, BBPCSR_BUSY)) {
|
||||
ERROR(rt2x00dev, "BBPCSR register busy. Read failed.\n");
|
||||
*value = 0xff;
|
||||
return;
|
||||
}
|
||||
if (rt2x00_get_field32(reg, BBPCSR_BUSY))
|
||||
goto exit_fail;
|
||||
|
||||
*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,
|
||||
@ -136,6 +152,8 @@ static void rt2400pci_rf_write(struct rt2x00_dev *rt2x00dev,
|
||||
if (!word)
|
||||
return;
|
||||
|
||||
mutex_lock(&rt2x00dev->csr_mutex);
|
||||
|
||||
for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
|
||||
rt2x00pci_register_read(rt2x00dev, RFCSR, ®);
|
||||
if (!rt2x00_get_field32(reg, RFCSR_BUSY))
|
||||
@ -143,6 +161,7 @@ static void rt2400pci_rf_write(struct rt2x00_dev *rt2x00dev,
|
||||
udelay(REGISTER_BUSY_DELAY);
|
||||
}
|
||||
|
||||
mutex_unlock(&rt2x00dev->csr_mutex);
|
||||
ERROR(rt2x00dev, "RFCSR register busy. Write failed.\n");
|
||||
return;
|
||||
|
||||
@ -155,6 +174,8 @@ rf_write:
|
||||
|
||||
rt2x00pci_register_write(rt2x00dev, RFCSR, reg);
|
||||
rt2x00_rf_write(rt2x00dev, word, value);
|
||||
|
||||
mutex_unlock(&rt2x00dev->csr_mutex);
|
||||
}
|
||||
|
||||
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
|
||||
*/
|
||||
bcn_preload = PREAMBLE + get_duration(IEEE80211_HEADER, 20);
|
||||
bcn_preload = PREAMBLE + GET_DURATION(IEEE80211_HEADER, 20);
|
||||
rt2x00pci_register_read(rt2x00dev, BCNCSR1, ®);
|
||||
rt2x00_set_field32(®, BCNCSR1_PRELOAD, bcn_preload);
|
||||
rt2x00pci_register_write(rt2x00dev, BCNCSR1, reg);
|
||||
@ -367,25 +388,25 @@ static void rt2400pci_config_erp(struct rt2x00_dev *rt2x00dev,
|
||||
rt2x00pci_register_read(rt2x00dev, ARCSR2, ®);
|
||||
rt2x00_set_field32(®, ARCSR2_SIGNAL, 0x00);
|
||||
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_read(rt2x00dev, ARCSR3, ®);
|
||||
rt2x00_set_field32(®, ARCSR3_SIGNAL, 0x01 | preamble_mask);
|
||||
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_read(rt2x00dev, ARCSR4, ®);
|
||||
rt2x00_set_field32(®, ARCSR4_SIGNAL, 0x02 | preamble_mask);
|
||||
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_read(rt2x00dev, ARCSR5, ®);
|
||||
rt2x00_set_field32(®, ARCSR5_SIGNAL, 0x03 | preamble_mask);
|
||||
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, ARCSR1, erp->basic_rates);
|
||||
@ -626,36 +647,47 @@ static void rt2400pci_link_tuner(struct rt2x00_dev *rt2x00dev)
|
||||
/*
|
||||
* Initialization functions.
|
||||
*/
|
||||
static void rt2400pci_init_rxentry(struct rt2x00_dev *rt2x00dev,
|
||||
struct queue_entry *entry)
|
||||
static bool rt2400pci_get_entry_state(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 skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
|
||||
u32 word;
|
||||
|
||||
rt2x00_desc_read(entry_priv->desc, 2, &word);
|
||||
rt2x00_set_field32(&word, RXD_W2_BUFFER_LENGTH, entry->skb->len);
|
||||
rt2x00_desc_write(entry_priv->desc, 2, word);
|
||||
if (entry->queue->qid == QID_RX) {
|
||||
rt2x00_desc_read(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_set_field32(&word, RXD_W1_BUFFER_ADDRESS, skbdesc->skb_dma);
|
||||
rt2x00_desc_write(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_desc_write(entry_priv->desc, 1, word);
|
||||
|
||||
rt2x00_desc_read(entry_priv->desc, 0, &word);
|
||||
rt2x00_set_field32(&word, RXD_W0_OWNER_NIC, 1);
|
||||
rt2x00_desc_write(entry_priv->desc, 0, word);
|
||||
}
|
||||
|
||||
static void rt2400pci_init_txentry(struct rt2x00_dev *rt2x00dev,
|
||||
struct queue_entry *entry)
|
||||
{
|
||||
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);
|
||||
rt2x00_desc_read(entry_priv->desc, 0, &word);
|
||||
rt2x00_set_field32(&word, RXD_W0_OWNER_NIC, 1);
|
||||
rt2x00_desc_write(entry_priv->desc, 0, word);
|
||||
} else {
|
||||
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)
|
||||
@ -1570,8 +1602,8 @@ static const struct rt2x00lib_ops rt2400pci_rt2x00_ops = {
|
||||
.probe_hw = rt2400pci_probe_hw,
|
||||
.initialize = rt2x00pci_initialize,
|
||||
.uninitialize = rt2x00pci_uninitialize,
|
||||
.init_rxentry = rt2400pci_init_rxentry,
|
||||
.init_txentry = rt2400pci_init_txentry,
|
||||
.get_entry_state = rt2400pci_get_entry_state,
|
||||
.clear_entry = rt2400pci_clear_entry,
|
||||
.set_device_state = rt2400pci_set_device_state,
|
||||
.rfkill_poll = rt2400pci_rfkill_poll,
|
||||
.link_stats = rt2400pci_link_stats,
|
||||
|
@ -69,14 +69,14 @@ static void rt2500pci_bbp_write(struct rt2x00_dev *rt2x00dev,
|
||||
{
|
||||
u32 reg;
|
||||
|
||||
mutex_lock(&rt2x00dev->csr_mutex);
|
||||
|
||||
/*
|
||||
* Wait until the BBP becomes ready.
|
||||
*/
|
||||
reg = rt2500pci_bbp_check(rt2x00dev);
|
||||
if (rt2x00_get_field32(reg, BBPCSR_BUSY)) {
|
||||
ERROR(rt2x00dev, "BBPCSR register busy. Write failed.\n");
|
||||
return;
|
||||
}
|
||||
if (rt2x00_get_field32(reg, BBPCSR_BUSY))
|
||||
goto exit_fail;
|
||||
|
||||
/*
|
||||
* 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);
|
||||
|
||||
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,
|
||||
@ -95,14 +104,14 @@ static void rt2500pci_bbp_read(struct rt2x00_dev *rt2x00dev,
|
||||
{
|
||||
u32 reg;
|
||||
|
||||
mutex_lock(&rt2x00dev->csr_mutex);
|
||||
|
||||
/*
|
||||
* Wait until the BBP becomes ready.
|
||||
*/
|
||||
reg = rt2500pci_bbp_check(rt2x00dev);
|
||||
if (rt2x00_get_field32(reg, BBPCSR_BUSY)) {
|
||||
ERROR(rt2x00dev, "BBPCSR register busy. Read failed.\n");
|
||||
return;
|
||||
}
|
||||
if (rt2x00_get_field32(reg, BBPCSR_BUSY))
|
||||
goto exit_fail;
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
reg = rt2500pci_bbp_check(rt2x00dev);
|
||||
if (rt2x00_get_field32(reg, BBPCSR_BUSY)) {
|
||||
ERROR(rt2x00dev, "BBPCSR register busy. Read failed.\n");
|
||||
*value = 0xff;
|
||||
return;
|
||||
}
|
||||
if (rt2x00_get_field32(reg, BBPCSR_BUSY))
|
||||
goto exit_fail;
|
||||
|
||||
*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,
|
||||
@ -136,6 +152,8 @@ static void rt2500pci_rf_write(struct rt2x00_dev *rt2x00dev,
|
||||
if (!word)
|
||||
return;
|
||||
|
||||
mutex_lock(&rt2x00dev->csr_mutex);
|
||||
|
||||
for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
|
||||
rt2x00pci_register_read(rt2x00dev, RFCSR, ®);
|
||||
if (!rt2x00_get_field32(reg, RFCSR_BUSY))
|
||||
@ -143,6 +161,7 @@ static void rt2500pci_rf_write(struct rt2x00_dev *rt2x00dev,
|
||||
udelay(REGISTER_BUSY_DELAY);
|
||||
}
|
||||
|
||||
mutex_unlock(&rt2x00dev->csr_mutex);
|
||||
ERROR(rt2x00dev, "RFCSR register busy. Write failed.\n");
|
||||
return;
|
||||
|
||||
@ -155,6 +174,8 @@ rf_write:
|
||||
|
||||
rt2x00pci_register_write(rt2x00dev, RFCSR, reg);
|
||||
rt2x00_rf_write(rt2x00dev, word, value);
|
||||
|
||||
mutex_unlock(&rt2x00dev->csr_mutex);
|
||||
}
|
||||
|
||||
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
|
||||
*/
|
||||
bcn_preload = PREAMBLE + get_duration(IEEE80211_HEADER, 20);
|
||||
bcn_preload = PREAMBLE + GET_DURATION(IEEE80211_HEADER, 20);
|
||||
rt2x00pci_register_read(rt2x00dev, BCNCSR1, ®);
|
||||
rt2x00_set_field32(®, BCNCSR1_PRELOAD, bcn_preload);
|
||||
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, ®);
|
||||
rt2x00_set_field32(®, ARCSR2_SIGNAL, 0x00);
|
||||
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_read(rt2x00dev, ARCSR3, ®);
|
||||
rt2x00_set_field32(®, ARCSR3_SIGNAL, 0x01 | preamble_mask);
|
||||
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_read(rt2x00dev, ARCSR4, ®);
|
||||
rt2x00_set_field32(®, ARCSR4_SIGNAL, 0x02 | preamble_mask);
|
||||
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_read(rt2x00dev, ARCSR5, ®);
|
||||
rt2x00_set_field32(®, ARCSR5_SIGNAL, 0x03 | preamble_mask);
|
||||
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, ARCSR1, erp->basic_rates);
|
||||
@ -722,32 +743,43 @@ dynamic_cca_tune:
|
||||
/*
|
||||
* Initialization functions.
|
||||
*/
|
||||
static void rt2500pci_init_rxentry(struct rt2x00_dev *rt2x00dev,
|
||||
struct queue_entry *entry)
|
||||
static bool rt2500pci_get_entry_state(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 skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
|
||||
u32 word;
|
||||
|
||||
rt2x00_desc_read(entry_priv->desc, 1, &word);
|
||||
rt2x00_set_field32(&word, RXD_W1_BUFFER_ADDRESS, skbdesc->skb_dma);
|
||||
rt2x00_desc_write(entry_priv->desc, 1, word);
|
||||
if (entry->queue->qid == QID_RX) {
|
||||
rt2x00_desc_read(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_set_field32(&word, RXD_W0_OWNER_NIC, 1);
|
||||
rt2x00_desc_write(entry_priv->desc, 0, word);
|
||||
}
|
||||
|
||||
static void rt2500pci_init_txentry(struct rt2x00_dev *rt2x00dev,
|
||||
struct queue_entry *entry)
|
||||
{
|
||||
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);
|
||||
rt2x00_desc_read(entry_priv->desc, 0, &word);
|
||||
rt2x00_set_field32(&word, RXD_W0_OWNER_NIC, 1);
|
||||
rt2x00_desc_write(entry_priv->desc, 0, word);
|
||||
} else {
|
||||
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)
|
||||
@ -1871,8 +1903,8 @@ static const struct rt2x00lib_ops rt2500pci_rt2x00_ops = {
|
||||
.probe_hw = rt2500pci_probe_hw,
|
||||
.initialize = rt2x00pci_initialize,
|
||||
.uninitialize = rt2x00pci_uninitialize,
|
||||
.init_rxentry = rt2500pci_init_rxentry,
|
||||
.init_txentry = rt2500pci_init_txentry,
|
||||
.get_entry_state = rt2500pci_get_entry_state,
|
||||
.clear_entry = rt2500pci_clear_entry,
|
||||
.set_device_state = rt2500pci_set_device_state,
|
||||
.rfkill_poll = rt2500pci_rfkill_poll,
|
||||
.link_stats = rt2500pci_link_stats,
|
||||
|
@ -47,7 +47,7 @@
|
||||
* between each attampt. When the busy bit is still set at that time,
|
||||
* the access attempt is considered to have failed,
|
||||
* 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.
|
||||
*/
|
||||
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;
|
||||
|
||||
mutex_lock(&rt2x00dev->usb_cache_mutex);
|
||||
mutex_lock(&rt2x00dev->csr_mutex);
|
||||
|
||||
/*
|
||||
* 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);
|
||||
|
||||
mutex_unlock(&rt2x00dev->usb_cache_mutex);
|
||||
mutex_unlock(&rt2x00dev->csr_mutex);
|
||||
|
||||
return;
|
||||
|
||||
exit_fail:
|
||||
mutex_unlock(&rt2x00dev->usb_cache_mutex);
|
||||
mutex_unlock(&rt2x00dev->csr_mutex);
|
||||
|
||||
ERROR(rt2x00dev, "PHY_CSR8 register busy. Write failed.\n");
|
||||
}
|
||||
@ -166,7 +166,7 @@ static void rt2500usb_bbp_read(struct rt2x00_dev *rt2x00dev,
|
||||
{
|
||||
u16 reg;
|
||||
|
||||
mutex_lock(&rt2x00dev->usb_cache_mutex);
|
||||
mutex_lock(&rt2x00dev->csr_mutex);
|
||||
|
||||
/*
|
||||
* 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, ®);
|
||||
*value = rt2x00_get_field16(reg, PHY_CSR7_DATA);
|
||||
|
||||
mutex_unlock(&rt2x00dev->usb_cache_mutex);
|
||||
mutex_unlock(&rt2x00dev->csr_mutex);
|
||||
|
||||
return;
|
||||
|
||||
exit_fail:
|
||||
mutex_unlock(&rt2x00dev->usb_cache_mutex);
|
||||
mutex_unlock(&rt2x00dev->csr_mutex);
|
||||
|
||||
ERROR(rt2x00dev, "PHY_CSR8 register busy. Read failed.\n");
|
||||
*value = 0xff;
|
||||
@ -214,7 +214,7 @@ static void rt2500usb_rf_write(struct rt2x00_dev *rt2x00dev,
|
||||
if (!word)
|
||||
return;
|
||||
|
||||
mutex_lock(&rt2x00dev->usb_cache_mutex);
|
||||
mutex_lock(&rt2x00dev->csr_mutex);
|
||||
|
||||
for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
|
||||
rt2500usb_register_read_lock(rt2x00dev, PHY_CSR10, ®);
|
||||
@ -223,7 +223,7 @@ static void rt2500usb_rf_write(struct rt2x00_dev *rt2x00dev,
|
||||
udelay(REGISTER_BUSY_DELAY);
|
||||
}
|
||||
|
||||
mutex_unlock(&rt2x00dev->usb_cache_mutex);
|
||||
mutex_unlock(&rt2x00dev->csr_mutex);
|
||||
ERROR(rt2x00dev, "PHY_CSR10 register busy. Write failed.\n");
|
||||
return;
|
||||
|
||||
@ -241,7 +241,7 @@ rf_write:
|
||||
rt2500usb_register_write_lock(rt2x00dev, PHY_CSR10, reg);
|
||||
rt2x00_rf_write(rt2x00dev, word, value);
|
||||
|
||||
mutex_unlock(&rt2x00dev->usb_cache_mutex);
|
||||
mutex_unlock(&rt2x00dev->csr_mutex);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_RT2X00_LIB_DEBUGFS
|
||||
@ -385,7 +385,7 @@ static void rt2500usb_config_intf(struct rt2x00_dev *rt2x00dev,
|
||||
/*
|
||||
* 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, ®);
|
||||
rt2x00_set_field16(®, TXRX_CSR20_OFFSET, bcn_preload >> 6);
|
||||
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,
|
||||
.initialize = rt2x00usb_initialize,
|
||||
.uninitialize = rt2x00usb_uninitialize,
|
||||
.init_rxentry = rt2x00usb_init_rxentry,
|
||||
.init_txentry = rt2x00usb_init_txentry,
|
||||
.clear_entry = rt2x00usb_clear_entry,
|
||||
.set_device_state = rt2500usb_set_device_state,
|
||||
.link_stats = rt2500usb_link_stats,
|
||||
.reset_tuner = rt2500usb_reset_tuner,
|
||||
|
@ -91,6 +91,16 @@
|
||||
#define EEPROM(__dev, __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.
|
||||
* These values should follow the ieee80211 specifications.
|
||||
@ -109,9 +119,9 @@
|
||||
#define DIFS ( PIFS + SLOT_TIME )
|
||||
#define SHORT_DIFS ( SHORT_PIFS + SHORT_SLOT_TIME )
|
||||
#define EIFS ( SIFS + DIFS + \
|
||||
(8 * (IEEE80211_HEADER + ACK_SIZE)) )
|
||||
GET_DURATION(IEEE80211_HEADER + ACK_SIZE, 10) )
|
||||
#define SHORT_EIFS ( SIFS + SHORT_DIFS + \
|
||||
(8 * (IEEE80211_HEADER + ACK_SIZE)) )
|
||||
GET_DURATION(IEEE80211_HEADER + ACK_SIZE, 10) )
|
||||
|
||||
/*
|
||||
* Chipset identification
|
||||
@ -523,10 +533,8 @@ struct rt2x00lib_ops {
|
||||
/*
|
||||
* queue initialization handlers
|
||||
*/
|
||||
void (*init_rxentry) (struct rt2x00_dev *rt2x00dev,
|
||||
struct queue_entry *entry);
|
||||
void (*init_txentry) (struct rt2x00_dev *rt2x00dev,
|
||||
struct queue_entry *entry);
|
||||
bool (*get_entry_state) (struct queue_entry *entry);
|
||||
void (*clear_entry) (struct queue_entry *entry);
|
||||
|
||||
/*
|
||||
* Radio control handlers.
|
||||
@ -723,8 +731,7 @@ struct rt2x00_dev {
|
||||
|
||||
/*
|
||||
* This is the default TX/RX antenna setup as indicated
|
||||
* by the device's EEPROM. When mac80211 sets its
|
||||
* antenna value to 0 we should be using these values.
|
||||
* by the device's EEPROM.
|
||||
*/
|
||||
struct antenna_setup default_ant;
|
||||
|
||||
@ -739,16 +746,15 @@ struct rt2x00_dev {
|
||||
} csr;
|
||||
|
||||
/*
|
||||
* Mutex to protect register accesses on USB devices.
|
||||
* There are 2 reasons this is needed, one is to ensure
|
||||
* use of the csr_cache (for USB devices) by one thread
|
||||
* isn't corrupted by another thread trying to access it.
|
||||
* The other is that access to BBP and RF registers
|
||||
* require multiple BUS transactions and if another thread
|
||||
* attempted to access one of those registers at the same
|
||||
* time one of the writes could silently fail.
|
||||
* Mutex to protect register accesses.
|
||||
* For PCI and USB devices it protects against concurrent indirect
|
||||
* register access (BBP, RF, MCU) since accessing those
|
||||
* registers require multiple calls to the CSR registers.
|
||||
* For USB devices it also protects the csr_cache since that
|
||||
* field is used for normal CSR access and it cannot support
|
||||
* multiple callers simultaneously.
|
||||
*/
|
||||
struct mutex usb_cache_mutex;
|
||||
struct mutex csr_mutex;
|
||||
|
||||
/*
|
||||
* 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));
|
||||
}
|
||||
|
||||
/*
|
||||
* 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.
|
||||
* @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.eifs = bss_conf->use_short_slot ? SHORT_EIFS : EIFS;
|
||||
|
||||
erp.ack_timeout = PLCP + erp.difs + get_duration(ACK_SIZE, 10);
|
||||
erp.ack_consume_time = SIFS + PLCP + 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);
|
||||
|
||||
if (bss_conf->use_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,
|
||||
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;
|
||||
|
||||
if (rx == rt2x00dev->link.ant.active.rx &&
|
||||
tx == rt2x00dev->link.ant.active.tx)
|
||||
/*
|
||||
* Only reconfigure when something has changed.
|
||||
*/
|
||||
if (ant->rx == rt2x00dev->link.ant.active.rx &&
|
||||
ant->tx == rt2x00dev->link.ant.active.tx)
|
||||
return;
|
||||
|
||||
/*
|
||||
@ -132,12 +149,12 @@ void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev,
|
||||
* The latter is required since we need to recalibrate the
|
||||
* 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);
|
||||
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))
|
||||
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.
|
||||
*/
|
||||
rt2x00queue_init_rx(rt2x00dev);
|
||||
rt2x00queue_init_tx(rt2x00dev);
|
||||
rt2x00queue_init_queues(rt2x00dev);
|
||||
|
||||
/*
|
||||
* 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)
|
||||
{
|
||||
enum antenna rx = rt2x00dev->link.ant.active.rx;
|
||||
enum antenna tx = rt2x00dev->link.ant.active.tx;
|
||||
struct antenna_setup ant;
|
||||
int sample_a =
|
||||
rt2x00_get_link_ant_rssi_history(&rt2x00dev->link, ANTENNA_A);
|
||||
int sample_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.
|
||||
*/
|
||||
@ -200,21 +200,22 @@ static void rt2x00lib_evaluate_antenna_sample(struct rt2x00_dev *rt2x00dev)
|
||||
return;
|
||||
|
||||
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)
|
||||
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)
|
||||
{
|
||||
enum antenna rx = rt2x00dev->link.ant.active.rx;
|
||||
enum antenna tx = rt2x00dev->link.ant.active.tx;
|
||||
struct antenna_setup ant;
|
||||
int rssi_curr = rt2x00_get_link_ant_rssi(&rt2x00dev->link);
|
||||
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
|
||||
* 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;
|
||||
|
||||
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)
|
||||
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)
|
||||
@ -574,7 +575,7 @@ void rt2x00lib_txdone(struct queue_entry *entry,
|
||||
entry->skb = NULL;
|
||||
entry->flags = 0;
|
||||
|
||||
rt2x00dev->ops->lib->init_txentry(rt2x00dev, entry);
|
||||
rt2x00dev->ops->lib->clear_entry(entry);
|
||||
|
||||
clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags);
|
||||
rt2x00queue_index_inc(entry->queue, Q_INDEX_DONE);
|
||||
@ -706,7 +707,7 @@ void rt2x00lib_rxdone(struct rt2x00_dev *rt2x00dev,
|
||||
entry->skb = skb;
|
||||
entry->flags = 0;
|
||||
|
||||
rt2x00dev->ops->lib->init_rxentry(rt2x00dev, entry);
|
||||
rt2x00dev->ops->lib->clear_entry(entry);
|
||||
|
||||
rt2x00queue_index_inc(entry->queue, Q_INDEX);
|
||||
}
|
||||
@ -717,31 +718,31 @@ EXPORT_SYMBOL_GPL(rt2x00lib_rxdone);
|
||||
*/
|
||||
const struct rt2x00_rate rt2x00_supported_rates[12] = {
|
||||
{
|
||||
.flags = DEV_RATE_CCK | DEV_RATE_BASIC,
|
||||
.flags = DEV_RATE_CCK,
|
||||
.bitrate = 10,
|
||||
.ratemask = BIT(0),
|
||||
.plcp = 0x00,
|
||||
},
|
||||
{
|
||||
.flags = DEV_RATE_CCK | DEV_RATE_SHORT_PREAMBLE | DEV_RATE_BASIC,
|
||||
.flags = DEV_RATE_CCK | DEV_RATE_SHORT_PREAMBLE,
|
||||
.bitrate = 20,
|
||||
.ratemask = BIT(1),
|
||||
.plcp = 0x01,
|
||||
},
|
||||
{
|
||||
.flags = DEV_RATE_CCK | DEV_RATE_SHORT_PREAMBLE | DEV_RATE_BASIC,
|
||||
.flags = DEV_RATE_CCK | DEV_RATE_SHORT_PREAMBLE,
|
||||
.bitrate = 55,
|
||||
.ratemask = BIT(2),
|
||||
.plcp = 0x02,
|
||||
},
|
||||
{
|
||||
.flags = DEV_RATE_CCK | DEV_RATE_SHORT_PREAMBLE | DEV_RATE_BASIC,
|
||||
.flags = DEV_RATE_CCK | DEV_RATE_SHORT_PREAMBLE,
|
||||
.bitrate = 110,
|
||||
.ratemask = BIT(3),
|
||||
.plcp = 0x03,
|
||||
},
|
||||
{
|
||||
.flags = DEV_RATE_OFDM | DEV_RATE_BASIC,
|
||||
.flags = DEV_RATE_OFDM,
|
||||
.bitrate = 60,
|
||||
.ratemask = BIT(4),
|
||||
.plcp = 0x0b,
|
||||
@ -753,7 +754,7 @@ const struct rt2x00_rate rt2x00_supported_rates[12] = {
|
||||
.plcp = 0x0f,
|
||||
},
|
||||
{
|
||||
.flags = DEV_RATE_OFDM | DEV_RATE_BASIC,
|
||||
.flags = DEV_RATE_OFDM,
|
||||
.bitrate = 120,
|
||||
.ratemask = BIT(6),
|
||||
.plcp = 0x0a,
|
||||
@ -765,7 +766,7 @@ const struct rt2x00_rate rt2x00_supported_rates[12] = {
|
||||
.plcp = 0x0e,
|
||||
},
|
||||
{
|
||||
.flags = DEV_RATE_OFDM | DEV_RATE_BASIC,
|
||||
.flags = DEV_RATE_OFDM,
|
||||
.bitrate = 240,
|
||||
.ratemask = BIT(8),
|
||||
.plcp = 0x09,
|
||||
@ -1050,6 +1051,8 @@ int rt2x00lib_probe_dev(struct rt2x00_dev *rt2x00dev)
|
||||
{
|
||||
int retval = -ENOMEM;
|
||||
|
||||
mutex_init(&rt2x00dev->csr_mutex);
|
||||
|
||||
/*
|
||||
* Make room for rt2x00_intf inside the per-interface
|
||||
* 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;
|
||||
unsigned int brightness = enabled ? LED_FULL : LED_OFF;
|
||||
|
||||
if ((led->type != LED_TYPE_ACTIVITY) || !(led->flags & LED_REGISTERED))
|
||||
if (!(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;
|
||||
}
|
||||
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)
|
||||
{
|
||||
struct rt2x00_led *led = &rt2x00dev->led_assoc;
|
||||
unsigned int brightness;
|
||||
|
||||
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;
|
||||
}
|
||||
if (rt2x00dev->led_assoc.type == LED_TYPE_ASSOC)
|
||||
rt2x00led_led_simple(&rt2x00dev->led_assoc, enabled);
|
||||
}
|
||||
|
||||
void rt2x00leds_led_radio(struct rt2x00_dev *rt2x00dev, bool enabled)
|
||||
{
|
||||
struct rt2x00_led *led = &rt2x00dev->led_radio;
|
||||
unsigned int brightness;
|
||||
|
||||
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;
|
||||
}
|
||||
if (rt2x00dev->led_radio.type == LED_TYPE_ASSOC)
|
||||
rt2x00led_led_simple(&rt2x00dev->led_radio, enabled);
|
||||
}
|
||||
|
||||
static int rt2x00leds_register_led(struct rt2x00_dev *rt2x00dev,
|
||||
@ -125,6 +109,13 @@ static int rt2x00leds_register_led(struct rt2x00_dev *rt2x00dev,
|
||||
int retval;
|
||||
|
||||
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);
|
||||
if (retval) {
|
||||
@ -199,7 +190,16 @@ exit_fail:
|
||||
static void rt2x00leds_unregister_led(struct rt2x00_led *led)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
@ -213,22 +213,40 @@ void rt2x00leds_unregister(struct rt2x00_dev *rt2x00dev)
|
||||
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)
|
||||
{
|
||||
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)
|
||||
led_classdev_suspend(&rt2x00dev->led_assoc.led_dev);
|
||||
rt2x00leds_suspend_led(&rt2x00dev->led_assoc);
|
||||
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)
|
||||
{
|
||||
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)
|
||||
led_classdev_resume(&rt2x00dev->led_assoc.led_dev);
|
||||
rt2x00leds_resume_led(&rt2x00dev->led_assoc);
|
||||
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_OFDM 0x0002
|
||||
#define DEV_RATE_SHORT_PREAMBLE 0x0004
|
||||
#define DEV_RATE_BASIC 0x0008
|
||||
|
||||
unsigned short bitrate; /* In 100kbit/s */
|
||||
unsigned short ratemask;
|
||||
@ -94,7 +93,7 @@ void rt2x00lib_config_erp(struct rt2x00_dev *rt2x00dev,
|
||||
struct rt2x00_intf *intf,
|
||||
struct ieee80211_bss_conf *conf);
|
||||
void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev,
|
||||
enum antenna rx, enum antenna tx);
|
||||
struct antenna_setup *ant);
|
||||
void rt2x00lib_config(struct rt2x00_dev *rt2x00dev,
|
||||
struct ieee80211_conf *conf,
|
||||
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_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);
|
||||
void rt2x00queue_uninitialize(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 ieee80211_conf *conf = &hw->conf;
|
||||
int radio_on;
|
||||
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
|
||||
* only be set when the radio is enabled.
|
||||
*/
|
||||
radio_on = test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags);
|
||||
if (conf->radio_enabled) {
|
||||
/* For programming the values, we have to turn 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);
|
||||
|
||||
/*
|
||||
* 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 */
|
||||
rt2x00lib_toggle_rx(rt2x00dev, STATE_RADIO_RX_ON);
|
||||
} else {
|
||||
@ -486,7 +495,9 @@ int rt2x00mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
|
||||
struct ieee80211_key_conf *key);
|
||||
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;
|
||||
else if (key->keylen > 32)
|
||||
return -ENOSPC;
|
||||
|
@ -36,20 +36,17 @@
|
||||
*/
|
||||
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 skb_frame_desc *skbdesc;
|
||||
u32 word;
|
||||
|
||||
rt2x00_desc_read(entry_priv->desc, 0, &word);
|
||||
|
||||
/*
|
||||
* This should not happen, we already checked the entry
|
||||
* was ours. When the hardware disagrees there has been
|
||||
* a queue corruption!
|
||||
*/
|
||||
if (unlikely(rt2x00_get_field32(word, TXD_ENTRY_OWNER_NIC) ||
|
||||
rt2x00_get_field32(word, TXD_ENTRY_VALID))) {
|
||||
ERROR(entry->queue->rt2x00dev,
|
||||
if (unlikely(rt2x00dev->ops->lib->get_entry_state(entry))) {
|
||||
ERROR(rt2x00dev,
|
||||
"Corrupt queue %d, accessing entry which is not ours.\n"
|
||||
"Please file bug report to %s.\n",
|
||||
entry->queue->qid, DRV_PROJECT);
|
||||
@ -76,14 +73,12 @@ void rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev)
|
||||
struct queue_entry *entry;
|
||||
struct queue_entry_priv_pci *entry_priv;
|
||||
struct skb_frame_desc *skbdesc;
|
||||
u32 word;
|
||||
|
||||
while (1) {
|
||||
entry = rt2x00queue_get_entry(queue, Q_INDEX);
|
||||
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;
|
||||
|
||||
/*
|
||||
|
@ -43,17 +43,6 @@
|
||||
#define REGISTER_BUSY_COUNT 5
|
||||
#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.
|
||||
*/
|
||||
|
@ -319,8 +319,8 @@ static void rt2x00queue_create_tx_descriptor(struct queue_entry *entry,
|
||||
/*
|
||||
* Convert length to microseconds.
|
||||
*/
|
||||
residual = get_duration_res(data_length, hwrate->bitrate);
|
||||
duration = get_duration(data_length, hwrate->bitrate);
|
||||
residual = GET_DURATION_RES(data_length, hwrate->bitrate);
|
||||
duration = GET_DURATION(data_length, hwrate->bitrate);
|
||||
|
||||
if (residual != 0) {
|
||||
duration++;
|
||||
@ -589,40 +589,18 @@ static void rt2x00queue_reset(struct data_queue *queue)
|
||||
spin_unlock_irqrestore(&queue->lock, irqflags);
|
||||
}
|
||||
|
||||
void rt2x00queue_init_rx(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)
|
||||
void rt2x00queue_init_queues(struct rt2x00_dev *rt2x00dev)
|
||||
{
|
||||
struct data_queue *queue;
|
||||
unsigned int i;
|
||||
|
||||
txall_queue_for_each(rt2x00dev, queue) {
|
||||
queue_for_each(rt2x00dev, queue) {
|
||||
rt2x00queue_reset(queue);
|
||||
|
||||
if (!rt2x00dev->ops->lib->init_txentry)
|
||||
continue;
|
||||
|
||||
for (i = 0; i < queue->limit; i++) {
|
||||
queue->entries[i].flags = 0;
|
||||
|
||||
rt2x00dev->ops->lib->init_txentry(rt2x00dev,
|
||||
&queue->entries[i]);
|
||||
rt2x00dev->ops->lib->clear_entry(&queue->entries[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -79,7 +79,7 @@ int rt2x00usb_vendor_req_buff_lock(struct rt2x00_dev *rt2x00dev,
|
||||
{
|
||||
int status;
|
||||
|
||||
BUG_ON(!mutex_is_locked(&rt2x00dev->usb_cache_mutex));
|
||||
BUG_ON(!mutex_is_locked(&rt2x00dev->csr_mutex));
|
||||
|
||||
/*
|
||||
* Check for Cache availability.
|
||||
@ -110,13 +110,13 @@ int rt2x00usb_vendor_request_buff(struct rt2x00_dev *rt2x00dev,
|
||||
{
|
||||
int status;
|
||||
|
||||
mutex_lock(&rt2x00dev->usb_cache_mutex);
|
||||
mutex_lock(&rt2x00dev->csr_mutex);
|
||||
|
||||
status = rt2x00usb_vendor_req_buff_lock(rt2x00dev, request,
|
||||
requesttype, offset, buffer,
|
||||
buffer_length, timeout);
|
||||
|
||||
mutex_unlock(&rt2x00dev->usb_cache_mutex);
|
||||
mutex_unlock(&rt2x00dev->csr_mutex);
|
||||
|
||||
return status;
|
||||
}
|
||||
@ -132,7 +132,7 @@ int rt2x00usb_vendor_request_large_buff(struct rt2x00_dev *rt2x00dev,
|
||||
unsigned char *tb;
|
||||
u16 off, len, bsize;
|
||||
|
||||
mutex_lock(&rt2x00dev->usb_cache_mutex);
|
||||
mutex_lock(&rt2x00dev->csr_mutex);
|
||||
|
||||
tb = (char *)buffer;
|
||||
off = offset;
|
||||
@ -148,7 +148,7 @@ int rt2x00usb_vendor_request_large_buff(struct rt2x00_dev *rt2x00dev,
|
||||
off += bsize;
|
||||
}
|
||||
|
||||
mutex_unlock(&rt2x00dev->usb_cache_mutex);
|
||||
mutex_unlock(&rt2x00dev->csr_mutex);
|
||||
|
||||
return status;
|
||||
}
|
||||
@ -351,28 +351,25 @@ EXPORT_SYMBOL_GPL(rt2x00usb_disable_radio);
|
||||
/*
|
||||
* Device initialization handlers.
|
||||
*/
|
||||
void rt2x00usb_init_rxentry(struct rt2x00_dev *rt2x00dev,
|
||||
struct queue_entry *entry)
|
||||
void rt2x00usb_clear_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;
|
||||
|
||||
usb_fill_bulk_urb(entry_priv->urb, usb_dev,
|
||||
usb_rcvbulkpipe(usb_dev, 1),
|
||||
entry->skb->data, entry->skb->len,
|
||||
rt2x00usb_interrupt_rxdone, entry);
|
||||
if (entry->queue->qid == QID_RX) {
|
||||
usb_fill_bulk_urb(entry_priv->urb, usb_dev,
|
||||
usb_rcvbulkpipe(usb_dev, 1),
|
||||
entry->skb->data, entry->skb->len,
|
||||
rt2x00usb_interrupt_rxdone, entry);
|
||||
|
||||
set_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags);
|
||||
usb_submit_urb(entry_priv->urb, GFP_ATOMIC);
|
||||
set_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags);
|
||||
usb_submit_urb(entry_priv->urb, GFP_ATOMIC);
|
||||
} else {
|
||||
entry->flags = 0;
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rt2x00usb_init_rxentry);
|
||||
|
||||
void rt2x00usb_init_txentry(struct rt2x00_dev *rt2x00dev,
|
||||
struct queue_entry *entry)
|
||||
{
|
||||
entry->flags = 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rt2x00usb_init_txentry);
|
||||
EXPORT_SYMBOL_GPL(rt2x00usb_clear_entry);
|
||||
|
||||
static int rt2x00usb_alloc_urb(struct rt2x00_dev *rt2x00dev,
|
||||
struct data_queue *queue)
|
||||
@ -534,7 +531,6 @@ int rt2x00usb_probe(struct usb_interface *usb_intf,
|
||||
rt2x00dev->dev = &usb_intf->dev;
|
||||
rt2x00dev->ops = ops;
|
||||
rt2x00dev->hw = hw;
|
||||
mutex_init(&rt2x00dev->usb_cache_mutex);
|
||||
|
||||
rt2x00dev->usb_maxpacket =
|
||||
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.
|
||||
*/
|
||||
void rt2x00usb_init_rxentry(struct rt2x00_dev *rt2x00dev,
|
||||
struct queue_entry *entry);
|
||||
void rt2x00usb_init_txentry(struct rt2x00_dev *rt2x00dev,
|
||||
struct queue_entry *entry);
|
||||
void rt2x00usb_clear_entry(struct queue_entry *entry);
|
||||
int rt2x00usb_initialize(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;
|
||||
|
||||
mutex_lock(&rt2x00dev->csr_mutex);
|
||||
|
||||
/*
|
||||
* Wait until the BBP becomes ready.
|
||||
*/
|
||||
reg = rt61pci_bbp_check(rt2x00dev);
|
||||
if (rt2x00_get_field32(reg, PHY_CSR3_BUSY)) {
|
||||
ERROR(rt2x00dev, "PHY_CSR3 register busy. Write failed.\n");
|
||||
return;
|
||||
}
|
||||
if (rt2x00_get_field32(reg, PHY_CSR3_BUSY))
|
||||
goto exit_fail;
|
||||
|
||||
/*
|
||||
* 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);
|
||||
|
||||
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,
|
||||
@ -101,14 +109,14 @@ static void rt61pci_bbp_read(struct rt2x00_dev *rt2x00dev,
|
||||
{
|
||||
u32 reg;
|
||||
|
||||
mutex_lock(&rt2x00dev->csr_mutex);
|
||||
|
||||
/*
|
||||
* Wait until the BBP becomes ready.
|
||||
*/
|
||||
reg = rt61pci_bbp_check(rt2x00dev);
|
||||
if (rt2x00_get_field32(reg, PHY_CSR3_BUSY)) {
|
||||
ERROR(rt2x00dev, "PHY_CSR3 register busy. Read failed.\n");
|
||||
return;
|
||||
}
|
||||
if (rt2x00_get_field32(reg, PHY_CSR3_BUSY))
|
||||
goto exit_fail;
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
reg = rt61pci_bbp_check(rt2x00dev);
|
||||
if (rt2x00_get_field32(reg, PHY_CSR3_BUSY)) {
|
||||
ERROR(rt2x00dev, "PHY_CSR3 register busy. Read failed.\n");
|
||||
*value = 0xff;
|
||||
return;
|
||||
}
|
||||
if (rt2x00_get_field32(reg, PHY_CSR3_BUSY))
|
||||
goto exit_fail;
|
||||
|
||||
*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,
|
||||
@ -142,6 +156,8 @@ static void rt61pci_rf_write(struct rt2x00_dev *rt2x00dev,
|
||||
if (!word)
|
||||
return;
|
||||
|
||||
mutex_lock(&rt2x00dev->csr_mutex);
|
||||
|
||||
for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
|
||||
rt2x00pci_register_read(rt2x00dev, PHY_CSR4, ®);
|
||||
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);
|
||||
}
|
||||
|
||||
mutex_unlock(&rt2x00dev->csr_mutex);
|
||||
ERROR(rt2x00dev, "PHY_CSR4 register busy. Write failed.\n");
|
||||
return;
|
||||
|
||||
@ -161,6 +178,8 @@ rf_write:
|
||||
|
||||
rt2x00pci_register_write(rt2x00dev, PHY_CSR4, reg);
|
||||
rt2x00_rf_write(rt2x00dev, word, value);
|
||||
|
||||
mutex_unlock(&rt2x00dev->csr_mutex);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_RT2X00_LIB_LEDS
|
||||
@ -175,14 +194,12 @@ static void rt61pci_mcu_request(struct rt2x00_dev *rt2x00dev,
|
||||
{
|
||||
u32 reg;
|
||||
|
||||
mutex_lock(&rt2x00dev->csr_mutex);
|
||||
|
||||
rt2x00pci_register_read(rt2x00dev, H2M_MAILBOX_CSR, ®);
|
||||
|
||||
if (rt2x00_get_field32(reg, H2M_MAILBOX_CSR_OWNER)) {
|
||||
ERROR(rt2x00dev, "mcu request error. "
|
||||
"Request 0x%02x failed for token 0x%02x.\n",
|
||||
command, token);
|
||||
return;
|
||||
}
|
||||
if (rt2x00_get_field32(reg, H2M_MAILBOX_CSR_OWNER))
|
||||
goto exit_fail;
|
||||
|
||||
rt2x00_set_field32(®, H2M_MAILBOX_CSR_OWNER, 1);
|
||||
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_INTERRUPT_MCU, 1);
|
||||
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 */
|
||||
|
||||
@ -1261,33 +1289,44 @@ static int rt61pci_load_firmware(struct rt2x00_dev *rt2x00dev, const void *data,
|
||||
/*
|
||||
* Initialization functions.
|
||||
*/
|
||||
static void rt61pci_init_rxentry(struct rt2x00_dev *rt2x00dev,
|
||||
struct queue_entry *entry)
|
||||
static bool rt61pci_get_entry_state(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 skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
|
||||
u32 word;
|
||||
|
||||
rt2x00_desc_read(entry_priv->desc, 5, &word);
|
||||
rt2x00_set_field32(&word, RXD_W5_BUFFER_PHYSICAL_ADDRESS,
|
||||
skbdesc->skb_dma);
|
||||
rt2x00_desc_write(entry_priv->desc, 5, word);
|
||||
if (entry->queue->qid == QID_RX) {
|
||||
rt2x00_desc_read(entry_priv->desc, 5, &word);
|
||||
rt2x00_set_field32(&word, RXD_W5_BUFFER_PHYSICAL_ADDRESS,
|
||||
skbdesc->skb_dma);
|
||||
rt2x00_desc_write(entry_priv->desc, 5, word);
|
||||
|
||||
rt2x00_desc_read(entry_priv->desc, 0, &word);
|
||||
rt2x00_set_field32(&word, RXD_W0_OWNER_NIC, 1);
|
||||
rt2x00_desc_write(entry_priv->desc, 0, word);
|
||||
}
|
||||
|
||||
static void rt61pci_init_txentry(struct rt2x00_dev *rt2x00dev,
|
||||
struct queue_entry *entry)
|
||||
{
|
||||
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);
|
||||
rt2x00_desc_read(entry_priv->desc, 0, &word);
|
||||
rt2x00_set_field32(&word, RXD_W0_OWNER_NIC, 1);
|
||||
rt2x00_desc_write(entry_priv->desc, 0, word);
|
||||
} else {
|
||||
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)
|
||||
@ -2722,8 +2761,8 @@ static const struct rt2x00lib_ops rt61pci_rt2x00_ops = {
|
||||
.load_firmware = rt61pci_load_firmware,
|
||||
.initialize = rt2x00pci_initialize,
|
||||
.uninitialize = rt2x00pci_uninitialize,
|
||||
.init_rxentry = rt61pci_init_rxentry,
|
||||
.init_txentry = rt61pci_init_txentry,
|
||||
.get_entry_state = rt61pci_get_entry_state,
|
||||
.clear_entry = rt61pci_clear_entry,
|
||||
.set_device_state = rt61pci_set_device_state,
|
||||
.rfkill_poll = rt61pci_rfkill_poll,
|
||||
.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,
|
||||
* the access attempt is considered to have failed,
|
||||
* 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,
|
||||
const unsigned int offset, u32 *value)
|
||||
@ -135,7 +135,7 @@ static void rt73usb_bbp_write(struct rt2x00_dev *rt2x00dev,
|
||||
{
|
||||
u32 reg;
|
||||
|
||||
mutex_lock(&rt2x00dev->usb_cache_mutex);
|
||||
mutex_lock(&rt2x00dev->csr_mutex);
|
||||
|
||||
/*
|
||||
* 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);
|
||||
|
||||
rt73usb_register_write_lock(rt2x00dev, PHY_CSR3, reg);
|
||||
mutex_unlock(&rt2x00dev->usb_cache_mutex);
|
||||
mutex_unlock(&rt2x00dev->csr_mutex);
|
||||
|
||||
return;
|
||||
|
||||
exit_fail:
|
||||
mutex_unlock(&rt2x00dev->usb_cache_mutex);
|
||||
mutex_unlock(&rt2x00dev->csr_mutex);
|
||||
|
||||
ERROR(rt2x00dev, "PHY_CSR3 register busy. Write failed.\n");
|
||||
}
|
||||
@ -169,7 +169,7 @@ static void rt73usb_bbp_read(struct rt2x00_dev *rt2x00dev,
|
||||
{
|
||||
u32 reg;
|
||||
|
||||
mutex_lock(&rt2x00dev->usb_cache_mutex);
|
||||
mutex_lock(&rt2x00dev->csr_mutex);
|
||||
|
||||
/*
|
||||
* Wait until the BBP becomes ready.
|
||||
@ -196,12 +196,12 @@ static void rt73usb_bbp_read(struct rt2x00_dev *rt2x00dev,
|
||||
goto exit_fail;
|
||||
|
||||
*value = rt2x00_get_field32(reg, PHY_CSR3_VALUE);
|
||||
mutex_unlock(&rt2x00dev->usb_cache_mutex);
|
||||
mutex_unlock(&rt2x00dev->csr_mutex);
|
||||
|
||||
return;
|
||||
|
||||
exit_fail:
|
||||
mutex_unlock(&rt2x00dev->usb_cache_mutex);
|
||||
mutex_unlock(&rt2x00dev->csr_mutex);
|
||||
|
||||
ERROR(rt2x00dev, "PHY_CSR3 register busy. Read failed.\n");
|
||||
*value = 0xff;
|
||||
@ -216,7 +216,7 @@ static void rt73usb_rf_write(struct rt2x00_dev *rt2x00dev,
|
||||
if (!word)
|
||||
return;
|
||||
|
||||
mutex_lock(&rt2x00dev->usb_cache_mutex);
|
||||
mutex_lock(&rt2x00dev->csr_mutex);
|
||||
|
||||
for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
|
||||
rt73usb_register_read_lock(rt2x00dev, PHY_CSR4, ®);
|
||||
@ -225,7 +225,7 @@ static void rt73usb_rf_write(struct rt2x00_dev *rt2x00dev,
|
||||
udelay(REGISTER_BUSY_DELAY);
|
||||
}
|
||||
|
||||
mutex_unlock(&rt2x00dev->usb_cache_mutex);
|
||||
mutex_unlock(&rt2x00dev->csr_mutex);
|
||||
ERROR(rt2x00dev, "PHY_CSR4 register busy. Write failed.\n");
|
||||
return;
|
||||
|
||||
@ -245,7 +245,8 @@ rf_write:
|
||||
|
||||
rt73usb_register_write_lock(rt2x00dev, PHY_CSR4, reg);
|
||||
rt2x00_rf_write(rt2x00dev, word, value);
|
||||
mutex_unlock(&rt2x00dev->usb_cache_mutex);
|
||||
|
||||
mutex_unlock(&rt2x00dev->csr_mutex);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_RT2X00_LIB_DEBUGFS
|
||||
@ -2313,8 +2314,7 @@ static const struct rt2x00lib_ops rt73usb_rt2x00_ops = {
|
||||
.load_firmware = rt73usb_load_firmware,
|
||||
.initialize = rt2x00usb_initialize,
|
||||
.uninitialize = rt2x00usb_uninitialize,
|
||||
.init_rxentry = rt2x00usb_init_rxentry,
|
||||
.init_txentry = rt2x00usb_init_txentry,
|
||||
.clear_entry = rt2x00usb_clear_entry,
|
||||
.set_device_state = rt73usb_set_device_state,
|
||||
.link_stats = rt73usb_link_stats,
|
||||
.reset_tuner = rt73usb_reset_tuner,
|
||||
|
7
drivers/net/wireless/rtl818x/Makefile
Normal file
7
drivers/net/wireless/rtl818x/Makefile
Normal file
@ -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;
|
||||
}
|
||||
|
||||
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,
|
||||
unsigned int changed_flags,
|
||||
unsigned int *total_flags,
|
||||
@ -760,6 +771,7 @@ static const struct ieee80211_ops rtl8180_ops = {
|
||||
.remove_interface = rtl8180_remove_interface,
|
||||
.config = rtl8180_config,
|
||||
.config_interface = rtl8180_config_interface,
|
||||
.bss_info_changed = rtl8180_bss_info_changed,
|
||||
.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]);
|
||||
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->SIFS, 0x22);
|
||||
rtl818x_iowrite8(priv, &priv->map->DIFS, 0x14);
|
||||
@ -745,14 +751,16 @@ static const struct rtl818x_rf_ops rtl8225_ops = {
|
||||
.name = "rtl8225",
|
||||
.init = rtl8225_rf_init,
|
||||
.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 = {
|
||||
.name = "rtl8225z2",
|
||||
.init = rtl8225z2_rf_init,
|
||||
.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)
|
@ -7,6 +7,11 @@
|
||||
* Based on the r8187 driver, which is:
|
||||
* 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
|
||||
* r8187 driver sources. Thanks to Realtek for their support!
|
||||
*
|
||||
@ -27,6 +32,9 @@
|
||||
|
||||
MODULE_AUTHOR("Michael Wu <flamingice@sourmilk.net>");
|
||||
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_LICENSE("GPL");
|
||||
|
@ -191,6 +191,7 @@ struct rtl818x_rf_ops {
|
||||
void (*init)(struct ieee80211_hw *);
|
||||
void (*stop)(struct ieee80211_hw *);
|
||||
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 */
|
@ -743,7 +743,7 @@ static int zd1201_join(struct zd1201 *zd, char *essid, int essidlen)
|
||||
|
||||
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 */
|
||||
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)
|
||||
{
|
||||
struct zd1201 *zd = (struct zd1201 *)dev->priv;
|
||||
struct zd1201 *zd = netdev_priv(dev);
|
||||
unsigned char *txbuf = zd->txdata;
|
||||
int txbuflen, pad = 0, err;
|
||||
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)
|
||||
{
|
||||
struct zd1201 *zd = (struct zd1201 *)dev->priv;
|
||||
struct zd1201 *zd = netdev_priv(dev);
|
||||
|
||||
if (!zd)
|
||||
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)
|
||||
{
|
||||
struct sockaddr *addr = p;
|
||||
struct zd1201 *zd = (struct zd1201 *)dev->priv;
|
||||
struct zd1201 *zd = netdev_priv(dev);
|
||||
int err;
|
||||
|
||||
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)
|
||||
{
|
||||
struct zd1201 *zd = (struct zd1201 *)dev->priv;
|
||||
struct zd1201 *zd = netdev_priv(dev);
|
||||
|
||||
return &zd->stats;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
unsigned char reqbuf[ETH_ALEN*ZD1201_MAXMULTI];
|
||||
int i;
|
||||
@ -897,7 +897,7 @@ static void zd1201_set_multicast(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 zd1201 *zd = (struct zd1201 *)dev->priv;
|
||||
struct zd1201 *zd = netdev_priv(dev);
|
||||
|
||||
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,
|
||||
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;
|
||||
int err;
|
||||
|
||||
@ -937,7 +937,7 @@ static int zd1201_set_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 zd1201 *zd = (struct zd1201 *)dev->priv;
|
||||
struct zd1201 *zd = netdev_priv(dev);
|
||||
short channel;
|
||||
int err;
|
||||
|
||||
@ -953,7 +953,7 @@ static int zd1201_get_freq(struct net_device *dev,
|
||||
static int zd1201_set_mode(struct net_device *dev,
|
||||
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;
|
||||
unsigned char buffer[IW_ESSID_MAX_SIZE+2];
|
||||
int err;
|
||||
@ -1015,7 +1015,7 @@ static int zd1201_set_mode(struct net_device *dev,
|
||||
static int zd1201_get_mode(struct net_device *dev,
|
||||
struct iw_request_info *info, __u32 *mode, char *extra)
|
||||
{
|
||||
struct zd1201 *zd = (struct zd1201 *)dev->priv;
|
||||
struct zd1201 *zd = netdev_priv(dev);
|
||||
short porttype;
|
||||
int err;
|
||||
|
||||
@ -1091,7 +1091,7 @@ static int zd1201_get_range(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 zd1201 *zd = (struct zd1201 *)dev->priv;
|
||||
struct zd1201 *zd = netdev_priv(dev);
|
||||
unsigned char 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,
|
||||
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;
|
||||
struct iw_event iwe;
|
||||
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,
|
||||
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)
|
||||
return -EINVAL;
|
||||
@ -1226,7 +1226,7 @@ static int zd1201_set_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 zd1201 *zd = (struct zd1201 *)dev->priv;
|
||||
struct zd1201 *zd = netdev_priv(dev);
|
||||
|
||||
memcpy(essid, zd->essid, zd->essidlen);
|
||||
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,
|
||||
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;
|
||||
int err;
|
||||
|
||||
@ -1280,7 +1280,7 @@ static int zd1201_set_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 zd1201 *zd = (struct zd1201 *)dev->priv;
|
||||
struct zd1201 *zd = netdev_priv(dev);
|
||||
short rate;
|
||||
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,
|
||||
struct iw_param *rts, char *extra)
|
||||
{
|
||||
struct zd1201 *zd = (struct zd1201 *)dev->priv;
|
||||
struct zd1201 *zd = netdev_priv(dev);
|
||||
int err;
|
||||
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,
|
||||
struct iw_param *rts, char *extra)
|
||||
{
|
||||
struct zd1201 *zd = (struct zd1201 *)dev->priv;
|
||||
struct zd1201 *zd = netdev_priv(dev);
|
||||
short rtst;
|
||||
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,
|
||||
struct iw_param *frag, char *extra)
|
||||
{
|
||||
struct zd1201 *zd = (struct zd1201 *)dev->priv;
|
||||
struct zd1201 *zd = netdev_priv(dev);
|
||||
int err;
|
||||
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,
|
||||
struct iw_param *frag, char *extra)
|
||||
{
|
||||
struct zd1201 *zd = (struct zd1201 *)dev->priv;
|
||||
struct zd1201 *zd = netdev_priv(dev);
|
||||
short fragt;
|
||||
int err;
|
||||
|
||||
@ -1400,7 +1400,7 @@ static int zd1201_get_retry(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 zd1201 *zd = (struct zd1201 *)dev->priv;
|
||||
struct zd1201 *zd = netdev_priv(dev);
|
||||
short i;
|
||||
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,
|
||||
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;
|
||||
int err;
|
||||
|
||||
@ -1490,7 +1490,7 @@ static int zd1201_get_encode(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 zd1201 *zd = (struct zd1201 *)dev->priv;
|
||||
struct zd1201 *zd = netdev_priv(dev);
|
||||
short enabled, duration, level;
|
||||
int err;
|
||||
|
||||
@ -1529,7 +1529,7 @@ out:
|
||||
static int zd1201_get_power(struct net_device *dev,
|
||||
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;
|
||||
int err;
|
||||
|
||||
@ -1616,7 +1616,7 @@ static const iw_handler zd1201_iw_handler[] =
|
||||
static int zd1201_set_hostauth(struct net_device *dev,
|
||||
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)
|
||||
return -EOPNOTSUPP;
|
||||
@ -1627,7 +1627,7 @@ static int zd1201_set_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 zd1201 *zd = (struct zd1201 *)dev->priv;
|
||||
struct zd1201 *zd = netdev_priv(dev);
|
||||
short hostauth;
|
||||
int err;
|
||||
|
||||
@ -1646,7 +1646,7 @@ static int zd1201_get_hostauth(struct net_device *dev,
|
||||
static int zd1201_auth_sta(struct net_device *dev,
|
||||
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];
|
||||
|
||||
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,
|
||||
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;
|
||||
|
||||
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,
|
||||
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;
|
||||
int err;
|
||||
|
||||
@ -1729,6 +1729,7 @@ static int zd1201_probe(struct usb_interface *interface,
|
||||
const struct usb_device_id *id)
|
||||
{
|
||||
struct zd1201 *zd;
|
||||
struct net_device *dev;
|
||||
struct usb_device *usb;
|
||||
int err;
|
||||
short porttype;
|
||||
@ -1736,9 +1737,12 @@ static int zd1201_probe(struct usb_interface *interface,
|
||||
|
||||
usb = interface_to_usbdev(interface);
|
||||
|
||||
zd = kzalloc(sizeof(struct zd1201), GFP_KERNEL);
|
||||
if (!zd)
|
||||
dev = alloc_etherdev(sizeof(*zd));
|
||||
if (!dev)
|
||||
return -ENOMEM;
|
||||
zd = netdev_priv(dev);
|
||||
zd->dev = dev;
|
||||
|
||||
zd->ap = ap;
|
||||
zd->usb = usb;
|
||||
zd->removed = 0;
|
||||
@ -1773,34 +1777,29 @@ static int zd1201_probe(struct usb_interface *interface,
|
||||
if (err)
|
||||
goto err_start;
|
||||
|
||||
zd->dev = alloc_etherdev(0);
|
||||
if (!zd->dev)
|
||||
goto err_start;
|
||||
|
||||
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 =
|
||||
dev->open = zd1201_net_open;
|
||||
dev->stop = zd1201_net_stop;
|
||||
dev->get_stats = zd1201_get_stats;
|
||||
dev->wireless_handlers =
|
||||
(struct iw_handler_def *)&zd1201_iw_handlers;
|
||||
zd->dev->hard_start_xmit = zd1201_hard_start_xmit;
|
||||
zd->dev->watchdog_timeo = ZD1201_TX_TIMEOUT;
|
||||
zd->dev->tx_timeout = zd1201_tx_timeout;
|
||||
zd->dev->set_multicast_list = zd1201_set_multicast;
|
||||
zd->dev->set_mac_address = zd1201_set_mac_address;
|
||||
strcpy(zd->dev->name, "wlan%d");
|
||||
dev->hard_start_xmit = zd1201_hard_start_xmit;
|
||||
dev->watchdog_timeo = ZD1201_TX_TIMEOUT;
|
||||
dev->tx_timeout = zd1201_tx_timeout;
|
||||
dev->set_multicast_list = zd1201_set_multicast;
|
||||
dev->set_mac_address = zd1201_set_mac_address;
|
||||
strcpy(dev->name, "wlan%d");
|
||||
|
||||
err = zd1201_getconfig(zd, ZD1201_RID_CNFOWNMACADDR,
|
||||
zd->dev->dev_addr, zd->dev->addr_len);
|
||||
dev->dev_addr, dev->addr_len);
|
||||
if (err)
|
||||
goto err_net;
|
||||
goto err_start;
|
||||
|
||||
/* Set wildcard essid to match zd->essid */
|
||||
*(__le16 *)buf = cpu_to_le16(0);
|
||||
err = zd1201_setconfig(zd, ZD1201_RID_CNFDESIREDSSID, buf,
|
||||
IW_ESSID_MAX_SIZE+2, 1);
|
||||
if (err)
|
||||
goto err_net;
|
||||
goto err_start;
|
||||
|
||||
if (zd->ap)
|
||||
porttype = ZD1201_PORTTYPE_AP;
|
||||
@ -1808,30 +1807,28 @@ static int zd1201_probe(struct usb_interface *interface,
|
||||
porttype = ZD1201_PORTTYPE_BSS;
|
||||
err = zd1201_setconfig16(zd, ZD1201_RID_CNFPORTTYPE, porttype);
|
||||
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)
|
||||
goto err_net;
|
||||
goto err_start;
|
||||
dev_info(&usb->dev, "%s: ZD1201 USB Wireless interface\n",
|
||||
zd->dev->name);
|
||||
dev->name);
|
||||
|
||||
usb_set_intfdata(interface, zd);
|
||||
zd1201_enable(zd); /* zd1201 likes to startup enabled, */
|
||||
zd1201_disable(zd); /* interfering with all the wifis in range */
|
||||
return 0;
|
||||
|
||||
err_net:
|
||||
free_netdev(zd->dev);
|
||||
err_start:
|
||||
/* Leave the device in reset state */
|
||||
zd1201_docmd(zd, ZD1201_CMDCODE_INIT, 0, 0, 0);
|
||||
err_zd:
|
||||
usb_free_urb(zd->tx_urb);
|
||||
usb_free_urb(zd->rx_urb);
|
||||
kfree(zd);
|
||||
free_netdev(dev);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
@ -226,7 +226,7 @@ int ssb_devices_freeze(struct ssb_bus *bus)
|
||||
err = drv->suspend(dev, state);
|
||||
if (err) {
|
||||
ssb_printk(KERN_ERR PFX "Failed to freeze device %s\n",
|
||||
dev->dev->bus_id);
|
||||
dev_name(dev->dev));
|
||||
goto err_unwind;
|
||||
}
|
||||
}
|
||||
@ -269,7 +269,7 @@ int ssb_devices_thaw(struct ssb_bus *bus)
|
||||
err = drv->resume(dev);
|
||||
if (err) {
|
||||
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->bus = &ssb_bustype;
|
||||
snprintf(dev->bus_id, sizeof(dev->bus_id),
|
||||
"ssb%u:%d", bus->busnumber, dev_idx);
|
||||
dev_set_name(dev, "ssb%u:%d", bus->busnumber, dev_idx);
|
||||
|
||||
switch (bus->bustype) {
|
||||
case SSB_BUSTYPE_PCI:
|
||||
@ -480,7 +479,7 @@ static int ssb_devices_register(struct ssb_bus *bus)
|
||||
if (err) {
|
||||
ssb_printk(KERN_ERR PFX
|
||||
"Could not register %s\n",
|
||||
dev->bus_id);
|
||||
dev_name(dev));
|
||||
/* Set dev to NULL to not unregister
|
||||
* dev on error unwinding. */
|
||||
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);
|
||||
if (!err) {
|
||||
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;
|
||||
|
@ -65,7 +65,7 @@ static int ssb_pcihost_probe(struct pci_dev *dev,
|
||||
err = pci_enable_device(dev);
|
||||
if (err)
|
||||
goto err_kfree_ssb;
|
||||
name = dev->dev.bus_id;
|
||||
name = dev_name(&dev->dev);
|
||||
if (dev->driver && dev->driver->name)
|
||||
name = dev->driver->name;
|
||||
err = pci_request_regions(dev, name);
|
||||
|
@ -30,6 +30,8 @@
|
||||
#include <linux/wireless.h>
|
||||
#include <linux/ieee80211.h>
|
||||
|
||||
#include <net/lib80211.h>
|
||||
|
||||
#define IEEE80211_VERSION "git-1.1.13"
|
||||
|
||||
#define IEEE80211_DATA_LEN 2304
|
||||
@ -355,8 +357,6 @@ struct ieee80211_stats {
|
||||
|
||||
struct ieee80211_device;
|
||||
|
||||
#include "ieee80211_crypt.h"
|
||||
|
||||
#define SEC_KEY_1 (1<<0)
|
||||
#define SEC_KEY_2 (1<<1)
|
||||
#define SEC_KEY_3 (1<<2)
|
||||
@ -937,11 +937,7 @@ struct ieee80211_device {
|
||||
size_t wpa_ie_len;
|
||||
u8 *wpa_ie;
|
||||
|
||||
struct list_head crypt_deinit_list;
|
||||
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;
|
||||
struct lib80211_crypt_info crypt_info;
|
||||
|
||||
int bcrx_sta_key; /* use individual keys to override default keys even
|
||||
* with RX of broad/multicast frames */
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user