Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next-2.6

This commit is contained in:
David S. Miller 2008-11-21 17:05:11 -08:00
commit 6c0bce37ff
119 changed files with 2207 additions and 2085 deletions

View File

@ -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)

View File

@ -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

View File

@ -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"

View File

@ -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/

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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:

View File

@ -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;

View File

@ -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) {

View File

@ -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

View File

@ -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);
/*

View File

@ -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. */

View File

@ -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,

View File

@ -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

View File

@ -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);

View File

@ -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;

View File

@ -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

View File

@ -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;

View File

@ -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;

View File

@ -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);

View File

@ -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);

View File

@ -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,

View File

@ -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,

View File

@ -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);
}
}

View File

@ -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;

View 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.

View 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

View File

@ -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");

View File

@ -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

View File

@ -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);

View File

@ -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;

View File

@ -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;

View File

@ -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)

View File

@ -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

View File

@ -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__ */

View File

@ -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,

View File

@ -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__ */

View File

@ -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,

View File

@ -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, &params, 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,

View File

@ -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

View File

@ -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;

View File

@ -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 *
*****************************************************/

View File

@ -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 */

View File

@ -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);

View File

@ -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__ */

View File

@ -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;
}

View File

@ -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));

View 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);

View File

@ -88,4 +88,5 @@ struct ieee80211_measurement_report {
struct ieee80211_basic_report basic[0];
} u;
} __attribute__ ((packed));
#endif

View File

@ -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];

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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);

View File

@ -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 */

View File

@ -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 = {

View File

@ -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,

View File

@ -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;

View File

@ -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);

View File

@ -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 */

View File

@ -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;

View File

@ -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(&reg, 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, &reg);
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, &reg);
rt2x00_set_field32(&reg, 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, &reg);
rt2x00_set_field32(&reg, ARCSR2_SIGNAL, 0x00);
rt2x00_set_field32(&reg, ARCSR2_SERVICE, 0x04);
rt2x00_set_field32(&reg, ARCSR2_LENGTH, get_duration(ACK_SIZE, 10));
rt2x00_set_field32(&reg, ARCSR2_LENGTH, GET_DURATION(ACK_SIZE, 10));
rt2x00pci_register_write(rt2x00dev, ARCSR2, reg);
rt2x00pci_register_read(rt2x00dev, ARCSR3, &reg);
rt2x00_set_field32(&reg, ARCSR3_SIGNAL, 0x01 | preamble_mask);
rt2x00_set_field32(&reg, ARCSR3_SERVICE, 0x04);
rt2x00_set_field32(&reg, ARCSR2_LENGTH, get_duration(ACK_SIZE, 20));
rt2x00_set_field32(&reg, ARCSR2_LENGTH, GET_DURATION(ACK_SIZE, 20));
rt2x00pci_register_write(rt2x00dev, ARCSR3, reg);
rt2x00pci_register_read(rt2x00dev, ARCSR4, &reg);
rt2x00_set_field32(&reg, ARCSR4_SIGNAL, 0x02 | preamble_mask);
rt2x00_set_field32(&reg, ARCSR4_SERVICE, 0x04);
rt2x00_set_field32(&reg, ARCSR2_LENGTH, get_duration(ACK_SIZE, 55));
rt2x00_set_field32(&reg, ARCSR2_LENGTH, GET_DURATION(ACK_SIZE, 55));
rt2x00pci_register_write(rt2x00dev, ARCSR4, reg);
rt2x00pci_register_read(rt2x00dev, ARCSR5, &reg);
rt2x00_set_field32(&reg, ARCSR5_SIGNAL, 0x03 | preamble_mask);
rt2x00_set_field32(&reg, ARCSR5_SERVICE, 0x84);
rt2x00_set_field32(&reg, ARCSR2_LENGTH, get_duration(ACK_SIZE, 110));
rt2x00_set_field32(&reg, 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,

View File

@ -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(&reg, 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, &reg);
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, &reg);
rt2x00_set_field32(&reg, BCNCSR1_PRELOAD, bcn_preload);
rt2x00_set_field32(&reg, BCNCSR1_BEACON_CWMIN, queue->cw_min);
@ -373,25 +394,25 @@ static void rt2500pci_config_erp(struct rt2x00_dev *rt2x00dev,
rt2x00pci_register_read(rt2x00dev, ARCSR2, &reg);
rt2x00_set_field32(&reg, ARCSR2_SIGNAL, 0x00);
rt2x00_set_field32(&reg, ARCSR2_SERVICE, 0x04);
rt2x00_set_field32(&reg, ARCSR2_LENGTH, get_duration(ACK_SIZE, 10));
rt2x00_set_field32(&reg, ARCSR2_LENGTH, GET_DURATION(ACK_SIZE, 10));
rt2x00pci_register_write(rt2x00dev, ARCSR2, reg);
rt2x00pci_register_read(rt2x00dev, ARCSR3, &reg);
rt2x00_set_field32(&reg, ARCSR3_SIGNAL, 0x01 | preamble_mask);
rt2x00_set_field32(&reg, ARCSR3_SERVICE, 0x04);
rt2x00_set_field32(&reg, ARCSR2_LENGTH, get_duration(ACK_SIZE, 20));
rt2x00_set_field32(&reg, ARCSR2_LENGTH, GET_DURATION(ACK_SIZE, 20));
rt2x00pci_register_write(rt2x00dev, ARCSR3, reg);
rt2x00pci_register_read(rt2x00dev, ARCSR4, &reg);
rt2x00_set_field32(&reg, ARCSR4_SIGNAL, 0x02 | preamble_mask);
rt2x00_set_field32(&reg, ARCSR4_SERVICE, 0x04);
rt2x00_set_field32(&reg, ARCSR2_LENGTH, get_duration(ACK_SIZE, 55));
rt2x00_set_field32(&reg, ARCSR2_LENGTH, GET_DURATION(ACK_SIZE, 55));
rt2x00pci_register_write(rt2x00dev, ARCSR4, reg);
rt2x00pci_register_read(rt2x00dev, ARCSR5, &reg);
rt2x00_set_field32(&reg, ARCSR5_SIGNAL, 0x03 | preamble_mask);
rt2x00_set_field32(&reg, ARCSR5_SERVICE, 0x84);
rt2x00_set_field32(&reg, ARCSR2_LENGTH, get_duration(ACK_SIZE, 110));
rt2x00_set_field32(&reg, 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,

View File

@ -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, &reg);
*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, &reg);
@ -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, &reg);
rt2x00_set_field16(&reg, TXRX_CSR20_OFFSET, bcn_preload >> 6);
rt2x00_set_field16(&reg, 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,

View File

@ -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.

View File

@ -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);

View File

@ -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.

View File

@ -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);
}

View File

@ -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);

View File

@ -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;

View File

@ -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;
/*

View File

@ -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.
*/

View File

@ -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]);
}
}
}

View File

@ -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);

View File

@ -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);

View File

@ -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(&reg, 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, &reg);
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, &reg);
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(&reg, H2M_MAILBOX_CSR_OWNER, 1);
rt2x00_set_field32(&reg, H2M_MAILBOX_CSR_CMD_TOKEN, token);
@ -194,6 +211,17 @@ static void rt61pci_mcu_request(struct rt2x00_dev *rt2x00dev,
rt2x00_set_field32(&reg, HOST_CMD_CSR_HOST_COMMAND, command);
rt2x00_set_field32(&reg, 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,

View File

@ -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(&reg, 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, &reg);
@ -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,

View 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

View File

@ -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,
};

View File

@ -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)

View File

@ -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");

View File

@ -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 */

View File

@ -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;
}

View File

@ -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;

View File

@ -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);

View File

@ -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