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 2009-03-17 15:04:31 -07:00
commit af4330631c
72 changed files with 7616 additions and 2951 deletions

View file

@ -473,6 +473,15 @@ config MAC80211_HWSIM
To compile this driver as a module, choose M here: the module will be
called mac80211_hwsim. If unsure, say N.
config MWL8K
tristate "Marvell 88W8xxx PCI/PCIe Wireless support"
depends on MAC80211 && PCI && WLAN_80211 && EXPERIMENTAL
---help---
This driver supports Marvell TOPDOG 802.11 wireless cards.
To compile this driver as a module, choose M here: the module
will be called mwl8k. If unsure, say N.
source "drivers/net/wireless/p54/Kconfig"
source "drivers/net/wireless/ath5k/Kconfig"
source "drivers/net/wireless/ath9k/Kconfig"

View file

@ -48,6 +48,8 @@ obj-$(CONFIG_LIBERTAS_THINFIRM) += libertas_tf/
obj-$(CONFIG_ADM8211) += adm8211.o
obj-$(CONFIG_MWL8K) += mwl8k.o
obj-$(CONFIG_IWLWIFI) += iwlwifi/
obj-$(CONFIG_RT2X00) += rt2x00/

View file

@ -16,8 +16,8 @@
In addition this module was derived from dummy_cs.
The initial developer of dummy_cs is David A. Hinds
<dahinds@users.sourceforge.net>. Portions created by David A. Hinds
are Copyright (C) 1999 David A. Hinds. All Rights Reserved.
are Copyright (C) 1999 David A. Hinds. All Rights Reserved.
======================================================================*/
#ifdef __IN_PCMCIA_PACKAGE__
@ -38,7 +38,7 @@
#include <pcmcia/cisreg.h>
#include <pcmcia/ds.h>
#include <asm/io.h>
#include <linux/io.h>
#include <asm/system.h>
#include "airo.h"
@ -54,7 +54,7 @@
static int pc_debug = PCMCIA_DEBUG;
module_param(pc_debug, int, 0);
static char *version = "$Revision: 1.2 $";
#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args);
#define DEBUG(n, args...) if (pc_debug > (n)) printk(KERN_DEBUG args);
#else
#define DEBUG(n, args...)
#endif
@ -62,9 +62,9 @@ static char *version = "$Revision: 1.2 $";
/*====================================================================*/
MODULE_AUTHOR("Benjamin Reed");
MODULE_DESCRIPTION("Support for Cisco/Aironet 802.11 wireless ethernet \
cards. This is the module that links the PCMCIA card \
with the airo module.");
MODULE_DESCRIPTION("Support for Cisco/Aironet 802.11 wireless ethernet "
"cards. This is the module that links the PCMCIA card "
"with the airo module.");
MODULE_LICENSE("Dual BSD/GPL");
MODULE_SUPPORTED_DEVICE("Aironet 4500, 4800 and Cisco 340 PCMCIA cards");
@ -76,7 +76,7 @@ MODULE_SUPPORTED_DEVICE("Aironet 4500, 4800 and Cisco 340 PCMCIA cards");
event is received. The config() and release() entry points are
used to configure or release a socket, in response to card
insertion and ejection events. They are invoked from the airo_cs
event handler.
event handler.
*/
static int airo_config(struct pcmcia_device *link);
@ -103,8 +103,9 @@ static void airo_detach(struct pcmcia_device *p_dev);
by one struct pcmcia_device structure (defined in ds.h).
You may not want to use a linked list for this -- for example, the
memory card driver uses an array of struct pcmcia_device pointers, where minor
device numbers are used to derive the corresponding array index.
memory card driver uses an array of struct pcmcia_device pointers,
where minor device numbers are used to derive the corresponding
array index.
*/
/*
@ -122,22 +123,22 @@ static void airo_detach(struct pcmcia_device *p_dev);
device IO routines can use a flag like this to throttle IO to a
card that is not ready to accept it.
*/
typedef struct local_info_t {
dev_node_t node;
struct net_device *eth_dev;
} local_info_t;
/*======================================================================
airo_attach() creates an "instance" of the driver, allocating
local data structures for one device. The device is registered
with Card Services.
The dev_link structure is initialized, but we don't actually
configure the card at this point -- we wait until we receive a
card insertion event.
======================================================================*/
static int airo_probe(struct pcmcia_device *p_dev)
@ -150,7 +151,7 @@ static int airo_probe(struct pcmcia_device *p_dev)
p_dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
p_dev->irq.IRQInfo1 = IRQ_LEVEL_ID;
p_dev->irq.Handler = NULL;
/*
General socket configuration defaults can go here. In this
client, we assume very little, and rely on the CIS for almost
@ -160,7 +161,7 @@ static int airo_probe(struct pcmcia_device *p_dev)
*/
p_dev->conf.Attributes = 0;
p_dev->conf.IntType = INT_MEMORY_AND_IO;
/* Allocate space for private device-specific data */
local = kzalloc(sizeof(local_info_t), GFP_KERNEL);
if (!local) {
@ -173,12 +174,12 @@ static int airo_probe(struct pcmcia_device *p_dev)
} /* airo_attach */
/*======================================================================
This deletes a driver "instance". The device is de-registered
with Card Services. If it has been released, all local data
structures are freed. Otherwise, the structures will be freed
when the device is released.
======================================================================*/
static void airo_detach(struct pcmcia_device *link)
@ -187,20 +188,20 @@ static void airo_detach(struct pcmcia_device *link)
airo_release(link);
if ( ((local_info_t*)link->priv)->eth_dev ) {
stop_airo_card( ((local_info_t*)link->priv)->eth_dev, 0 );
if (((local_info_t *)link->priv)->eth_dev) {
stop_airo_card(((local_info_t *)link->priv)->eth_dev, 0);
}
((local_info_t*)link->priv)->eth_dev = NULL;
((local_info_t *)link->priv)->eth_dev = NULL;
kfree(link->priv);
} /* airo_detach */
/*======================================================================
airo_config() is scheduled to run after a CARD_INSERTION event
is received, to configure the PCMCIA socket, and to make the
device available to the system.
======================================================================*/
#define CS_CHECK(fn, ret) \
@ -325,26 +326,28 @@ static int airo_config(struct pcmcia_device *link)
*/
if (link->conf.Attributes & CONF_ENABLE_IRQ)
CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
/*
This actually configures the PCMCIA socket -- setting up
the I/O windows and the interrupt mapping, and putting the
card and host interface into "Memory and IO" mode.
*/
CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
((local_info_t*)link->priv)->eth_dev =
init_airo_card( link->irq.AssignedIRQ,
link->io.BasePort1, 1, &handle_to_dev(link) );
if (!((local_info_t*)link->priv)->eth_dev) goto cs_failed;
CS_CHECK(RequestConfiguration,
pcmcia_request_configuration(link, &link->conf));
((local_info_t *)link->priv)->eth_dev =
init_airo_card(link->irq.AssignedIRQ,
link->io.BasePort1, 1, &handle_to_dev(link));
if (!((local_info_t *)link->priv)->eth_dev)
goto cs_failed;
/*
At this point, the dev_node_t structure(s) need to be
initialized and arranged in a linked list at link->dev_node.
*/
strcpy(dev->node.dev_name, ((local_info_t*)link->priv)->eth_dev->name );
strcpy(dev->node.dev_name, ((local_info_t *)link->priv)->eth_dev->name);
dev->node.major = dev->node.minor = 0;
link->dev_node = &dev->node;
/* Finally, report what we've done */
printk(KERN_INFO "%s: index 0x%02x: ",
dev->node.dev_name, link->conf.ConfigIndex);
@ -374,11 +377,11 @@ static int airo_config(struct pcmcia_device *link)
} /* airo_config */
/*======================================================================
After a card is removed, airo_release() will unregister the
device, and release the PCMCIA configuration. If the device is
still open, this will be postponed until it is closed.
======================================================================*/
static void airo_release(struct pcmcia_device *link)
@ -475,7 +478,7 @@ static void airo_cs_cleanup(void)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
POSSIBILITY OF SUCH DAMAGE.
*/
module_init(airo_cs_init);

View file

@ -10,5 +10,6 @@ ath5k-y += phy.o
ath5k-y += reset.o
ath5k-y += attach.o
ath5k-y += base.o
ath5k-y += led.o
ath5k-$(CONFIG_ATH5K_DEBUG) += debug.o
obj-$(CONFIG_ATH5K) += ath5k.o

View file

@ -1129,6 +1129,12 @@ struct ath5k_hw {
extern struct ath5k_hw *ath5k_hw_attach(struct ath5k_softc *sc, u8 mac_version);
extern void ath5k_hw_detach(struct ath5k_hw *ah);
/* LED functions */
extern int ath5k_init_leds(struct ath5k_softc *sc);
extern void ath5k_led_enable(struct ath5k_softc *sc);
extern void ath5k_led_off(struct ath5k_softc *sc);
extern void ath5k_unregister_leds(struct ath5k_softc *sc);
/* Reset Functions */
extern int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial);
extern int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode, struct ieee80211_channel *channel, bool change_channel);

View file

@ -34,14 +34,14 @@
static int ath5k_hw_post(struct ath5k_hw *ah)
{
int i, c;
u16 cur_reg;
u16 regs[2] = {AR5K_STA_ID0, AR5K_PHY(8)};
u32 var_pattern;
u32 static_pattern[4] = {
static const u32 static_pattern[4] = {
0x55555555, 0xaaaaaaaa,
0x66666666, 0x99999999
};
static const u16 regs[2] = { AR5K_STA_ID0, AR5K_PHY(8) };
int i, c;
u16 cur_reg;
u32 var_pattern;
u32 init_val;
u32 cur_val;
@ -106,7 +106,6 @@ struct ath5k_hw *ath5k_hw_attach(struct ath5k_softc *sc, u8 mac_version)
{
struct ath5k_hw *ah;
struct pci_dev *pdev = sc->pdev;
u8 mac[ETH_ALEN] = {};
int ret;
u32 srev;
@ -312,7 +311,7 @@ struct ath5k_hw *ath5k_hw_attach(struct ath5k_softc *sc, u8 mac_version)
}
/* MAC address is cleared until add_interface */
ath5k_hw_set_lladdr(ah, mac);
ath5k_hw_set_lladdr(ah, (u8[ETH_ALEN]){});
/* Set BSSID to bcast address: ff:ff:ff:ff:ff:ff for now */
memset(ah->ah_bssid, 0xff, ETH_ALEN);

View file

@ -79,7 +79,7 @@ MODULE_VERSION("0.6.0 (EXPERIMENTAL)");
/* Known PCI ids */
static struct pci_device_id ath5k_pci_id_table[] __devinitdata = {
static const struct pci_device_id ath5k_pci_id_table[] = {
{ PCI_VDEVICE(ATHEROS, 0x0207), .driver_data = AR5K_AR5210 }, /* 5210 early */
{ PCI_VDEVICE(ATHEROS, 0x0007), .driver_data = AR5K_AR5210 }, /* 5210 */
{ PCI_VDEVICE(ATHEROS, 0x0011), .driver_data = AR5K_AR5211 }, /* 5311 - this is on AHB bus !*/
@ -103,7 +103,7 @@ static struct pci_device_id ath5k_pci_id_table[] __devinitdata = {
MODULE_DEVICE_TABLE(pci, ath5k_pci_id_table);
/* Known SREVs */
static struct ath5k_srev_name srev_names[] = {
static const struct ath5k_srev_name srev_names[] = {
{ "5210", AR5K_VERSION_MAC, AR5K_SREV_AR5210 },
{ "5311", AR5K_VERSION_MAC, AR5K_SREV_AR5311 },
{ "5311A", AR5K_VERSION_MAC, AR5K_SREV_AR5311A },
@ -142,7 +142,7 @@ static struct ath5k_srev_name srev_names[] = {
{ "xxxxx", AR5K_VERSION_RAD, AR5K_SREV_UNKNOWN },
};
static struct ieee80211_rate ath5k_rates[] = {
static const struct ieee80211_rate ath5k_rates[] = {
{ .bitrate = 10,
.hw_value = ATH5K_RATE_CODE_1M, },
{ .bitrate = 20,
@ -248,7 +248,7 @@ static void ath5k_bss_info_changed(struct ieee80211_hw *hw,
struct ieee80211_bss_conf *bss_conf,
u32 changes);
static struct ieee80211_ops ath5k_hw_ops = {
static const struct ieee80211_ops ath5k_hw_ops = {
.tx = ath5k_tx,
.start = ath5k_start,
.stop = ath5k_stop,
@ -370,11 +370,6 @@ static irqreturn_t ath5k_intr(int irq, void *dev_id);
static void ath5k_tasklet_reset(unsigned long data);
static void ath5k_calibrate(unsigned long data);
/* LED functions */
static int ath5k_init_leds(struct ath5k_softc *sc);
static void ath5k_led_enable(struct ath5k_softc *sc);
static void ath5k_led_off(struct ath5k_softc *sc);
static void ath5k_unregister_leds(struct ath5k_softc *sc);
/*
* Module init/exit functions
@ -2530,141 +2525,6 @@ ath5k_calibrate(unsigned long data)
}
/***************\
* LED functions *
\***************/
static void
ath5k_led_enable(struct ath5k_softc *sc)
{
if (test_bit(ATH_STAT_LEDSOFT, sc->status)) {
ath5k_hw_set_gpio_output(sc->ah, sc->led_pin);
ath5k_led_off(sc);
}
}
static void
ath5k_led_on(struct ath5k_softc *sc)
{
if (!test_bit(ATH_STAT_LEDSOFT, sc->status))
return;
ath5k_hw_set_gpio(sc->ah, sc->led_pin, sc->led_on);
}
static void
ath5k_led_off(struct ath5k_softc *sc)
{
if (!test_bit(ATH_STAT_LEDSOFT, sc->status))
return;
ath5k_hw_set_gpio(sc->ah, sc->led_pin, !sc->led_on);
}
static void
ath5k_led_brightness_set(struct led_classdev *led_dev,
enum led_brightness brightness)
{
struct ath5k_led *led = container_of(led_dev, struct ath5k_led,
led_dev);
if (brightness == LED_OFF)
ath5k_led_off(led->sc);
else
ath5k_led_on(led->sc);
}
static int
ath5k_register_led(struct ath5k_softc *sc, struct ath5k_led *led,
const char *name, char *trigger)
{
int err;
led->sc = sc;
strncpy(led->name, name, sizeof(led->name));
led->led_dev.name = led->name;
led->led_dev.default_trigger = trigger;
led->led_dev.brightness_set = ath5k_led_brightness_set;
err = led_classdev_register(&sc->pdev->dev, &led->led_dev);
if (err) {
ATH5K_WARN(sc, "could not register LED %s\n", name);
led->sc = NULL;
}
return err;
}
static void
ath5k_unregister_led(struct ath5k_led *led)
{
if (!led->sc)
return;
led_classdev_unregister(&led->led_dev);
ath5k_led_off(led->sc);
led->sc = NULL;
}
static void
ath5k_unregister_leds(struct ath5k_softc *sc)
{
ath5k_unregister_led(&sc->rx_led);
ath5k_unregister_led(&sc->tx_led);
}
static int
ath5k_init_leds(struct ath5k_softc *sc)
{
int ret = 0;
struct ieee80211_hw *hw = sc->hw;
struct pci_dev *pdev = sc->pdev;
char name[ATH5K_LED_MAX_NAME_LEN + 1];
/*
* Auto-enable soft led processing for IBM cards and for
* 5211 minipci cards.
*/
if (pdev->device == PCI_DEVICE_ID_ATHEROS_AR5212_IBM ||
pdev->device == PCI_DEVICE_ID_ATHEROS_AR5211) {
__set_bit(ATH_STAT_LEDSOFT, sc->status);
sc->led_pin = 0;
sc->led_on = 0; /* active low */
}
/* Enable softled on PIN1 on HP Compaq nc6xx, nc4000 & nx5000 laptops */
if (pdev->subsystem_vendor == PCI_VENDOR_ID_COMPAQ) {
__set_bit(ATH_STAT_LEDSOFT, sc->status);
sc->led_pin = 1;
sc->led_on = 1; /* active high */
}
/*
* Pin 3 on Foxconn chips used in Acer Aspire One (0x105b:e008) and
* in emachines notebooks with AMBIT subsystem.
*/
if (pdev->subsystem_vendor == PCI_VENDOR_ID_FOXCONN ||
pdev->subsystem_vendor == PCI_VENDOR_ID_AMBIT) {
__set_bit(ATH_STAT_LEDSOFT, sc->status);
sc->led_pin = 3;
sc->led_on = 0; /* active low */
}
if (!test_bit(ATH_STAT_LEDSOFT, sc->status))
goto out;
ath5k_led_enable(sc);
snprintf(name, sizeof(name), "ath5k-%s::rx", wiphy_name(hw->wiphy));
ret = ath5k_register_led(sc, &sc->rx_led, name,
ieee80211_get_rx_led_name(hw));
if (ret)
goto out;
snprintf(name, sizeof(name), "ath5k-%s::tx", wiphy_name(hw->wiphy));
ret = ath5k_register_led(sc, &sc->tx_led, name,
ieee80211_get_tx_led_name(hw));
out:
return ret;
}
/********************\
* Mac80211 functions *
\********************/

View file

@ -82,14 +82,14 @@ static int ath5k_debugfs_open(struct inode *inode, struct file *file)
/* debugfs: registers */
struct reg {
char *name;
const char *name;
int addr;
};
#define REG_STRUCT_INIT(r) { #r, r }
/* just a few random registers, might want to add more */
static struct reg regs[] = {
static const struct reg regs[] = {
REG_STRUCT_INIT(AR5K_CR),
REG_STRUCT_INIT(AR5K_RXDP),
REG_STRUCT_INIT(AR5K_CFG),
@ -142,7 +142,7 @@ static struct reg regs[] = {
static void *reg_start(struct seq_file *seq, loff_t *pos)
{
return *pos < ARRAY_SIZE(regs) ? &regs[*pos] : NULL;
return *pos < ARRAY_SIZE(regs) ? (void *)&regs[*pos] : NULL;
}
static void reg_stop(struct seq_file *seq, void *p)
@ -153,7 +153,7 @@ static void reg_stop(struct seq_file *seq, void *p)
static void *reg_next(struct seq_file *seq, void *p, loff_t *pos)
{
++*pos;
return *pos < ARRAY_SIZE(regs) ? &regs[*pos] : NULL;
return *pos < ARRAY_SIZE(regs) ? (void *)&regs[*pos] : NULL;
}
static int reg_show(struct seq_file *seq, void *p)
@ -290,7 +290,7 @@ static const struct file_operations fops_reset = {
/* debugfs: debug level */
static struct {
static const struct {
enum ath5k_debug_level level;
const char *name;
const char *desc;

View file

@ -1418,14 +1418,11 @@ ath5k_eeprom_init(struct ath5k_hw *ah)
*/
int ath5k_eeprom_read_mac(struct ath5k_hw *ah, u8 *mac)
{
u8 mac_d[ETH_ALEN];
u8 mac_d[ETH_ALEN] = {};
u32 total, offset;
u16 data;
int octet, ret;
memset(mac, 0, ETH_ALEN);
memset(mac_d, 0, ETH_ALEN);
ret = ath5k_hw_eeprom_read(ah, 0x20, &data);
if (ret)
return ret;
@ -1441,11 +1438,11 @@ int ath5k_eeprom_read_mac(struct ath5k_hw *ah, u8 *mac)
octet += 2;
}
memcpy(mac, mac_d, ETH_ALEN);
if (!total || total == 3 * 0xffff)
return -EINVAL;
memcpy(mac, mac_d, ETH_ALEN);
return 0;
}

View file

@ -0,0 +1,174 @@
/*
* Copyright (c) 2002-2005 Sam Leffler, Errno Consulting
* Copyright (c) 2004-2005 Atheros Communications, Inc.
* Copyright (c) 2007 Jiri Slaby <jirislaby@gmail.com>
* Copyright (c) 2009 Bob Copeland <me@bobcopeland.com>
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer,
* without modification.
* 2. Redistributions in binary form must reproduce at minimum a disclaimer
* similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
* redistribution must be conditioned upon including a substantially
* similar Disclaimer requirement for further binary redistribution.
* 3. Neither the names of the above-listed copyright holders nor the names
* of any contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* Alternatively, this software may be distributed under the terms of the
* GNU General Public License ("GPL") version 2 as published by the Free
* Software Foundation.
*
* NO WARRANTY
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGES.
*
*/
#include <linux/pci.h>
#include "ath5k.h"
#include "base.h"
#define ATH_SDEVICE(subv,subd) \
.vendor = PCI_ANY_ID, .device = PCI_ANY_ID, \
.subvendor = (subv), .subdevice = (subd)
#define ATH_LED(pin,polarity) .driver_data = (((pin) << 8) | (polarity))
#define ATH_PIN(data) ((data) >> 8)
#define ATH_POLARITY(data) ((data) & 0xff)
/* Devices we match on for LED config info (typically laptops) */
static const struct pci_device_id ath5k_led_devices[] = {
/* IBM-specific AR5212 */
{ PCI_VDEVICE(ATHEROS, PCI_DEVICE_ID_ATHEROS_AR5212_IBM), ATH_LED(0, 0) },
/* AR5211 */
{ PCI_VDEVICE(ATHEROS, PCI_DEVICE_ID_ATHEROS_AR5211), ATH_LED(0, 0) },
/* HP Compaq nc6xx, nc4000, nx6000 */
{ ATH_SDEVICE(PCI_VENDOR_ID_COMPAQ, PCI_ANY_ID), ATH_LED(1, 1) },
/* Acer Aspire One A150 (maximlevitsky@gmail.com) */
{ ATH_SDEVICE(PCI_VENDOR_ID_FOXCONN, 0xe008), ATH_LED(3, 0) },
/* Acer Ferrari 5000 (russ.dill@gmail.com) */
{ ATH_SDEVICE(PCI_VENDOR_ID_AMBIT, 0x0422), ATH_LED(1, 1) },
/* E-machines E510 (tuliom@gmail.com) */
{ ATH_SDEVICE(PCI_VENDOR_ID_AMBIT, 0x0428), ATH_LED(3, 0) },
{ }
};
void ath5k_led_enable(struct ath5k_softc *sc)
{
if (test_bit(ATH_STAT_LEDSOFT, sc->status)) {
ath5k_hw_set_gpio_output(sc->ah, sc->led_pin);
ath5k_led_off(sc);
}
}
void ath5k_led_on(struct ath5k_softc *sc)
{
if (!test_bit(ATH_STAT_LEDSOFT, sc->status))
return;
ath5k_hw_set_gpio(sc->ah, sc->led_pin, sc->led_on);
}
void ath5k_led_off(struct ath5k_softc *sc)
{
if (!test_bit(ATH_STAT_LEDSOFT, sc->status))
return;
ath5k_hw_set_gpio(sc->ah, sc->led_pin, !sc->led_on);
}
static void
ath5k_led_brightness_set(struct led_classdev *led_dev,
enum led_brightness brightness)
{
struct ath5k_led *led = container_of(led_dev, struct ath5k_led,
led_dev);
if (brightness == LED_OFF)
ath5k_led_off(led->sc);
else
ath5k_led_on(led->sc);
}
static int
ath5k_register_led(struct ath5k_softc *sc, struct ath5k_led *led,
const char *name, char *trigger)
{
int err;
led->sc = sc;
strncpy(led->name, name, sizeof(led->name));
led->led_dev.name = led->name;
led->led_dev.default_trigger = trigger;
led->led_dev.brightness_set = ath5k_led_brightness_set;
err = led_classdev_register(&sc->pdev->dev, &led->led_dev);
if (err) {
ATH5K_WARN(sc, "could not register LED %s\n", name);
led->sc = NULL;
}
return err;
}
static void
ath5k_unregister_led(struct ath5k_led *led)
{
if (!led->sc)
return;
led_classdev_unregister(&led->led_dev);
ath5k_led_off(led->sc);
led->sc = NULL;
}
void ath5k_unregister_leds(struct ath5k_softc *sc)
{
ath5k_unregister_led(&sc->rx_led);
ath5k_unregister_led(&sc->tx_led);
}
int ath5k_init_leds(struct ath5k_softc *sc)
{
int ret = 0;
struct ieee80211_hw *hw = sc->hw;
struct pci_dev *pdev = sc->pdev;
char name[ATH5K_LED_MAX_NAME_LEN + 1];
const struct pci_device_id *match;
match = pci_match_id(&ath5k_led_devices[0], pdev);
if (match) {
__set_bit(ATH_STAT_LEDSOFT, sc->status);
sc->led_pin = ATH_PIN(match->driver_data);
sc->led_on = ATH_POLARITY(match->driver_data);
}
if (!test_bit(ATH_STAT_LEDSOFT, sc->status))
goto out;
ath5k_led_enable(sc);
snprintf(name, sizeof(name), "ath5k-%s::rx", wiphy_name(hw->wiphy));
ret = ath5k_register_led(sc, &sc->rx_led, name,
ieee80211_get_rx_led_name(hw));
if (ret)
goto out;
snprintf(name, sizeof(name), "ath5k-%s::tx", wiphy_name(hw->wiphy));
ret = ath5k_register_led(sc, &sc->tx_led, name,
ieee80211_get_tx_led_name(hw));
out:
return ret;
}

View file

@ -102,7 +102,7 @@ static inline int ath5k_hw_write_ofdm_timings(struct ath5k_hw *ah,
* index into rates for control rates, we can set it up like this because
* this is only used for AR5212 and we know it supports G mode
*/
static int control_rates[] =
static const unsigned int control_rates[] =
{ 0, 1, 1, 1, 4, 4, 6, 6, 8, 8, 8, 8 };
/**

View file

@ -60,6 +60,7 @@ static struct ath_bus_ops ath_ahb_bus_ops = {
static int ath_ahb_probe(struct platform_device *pdev)
{
void __iomem *mem;
struct ath_wiphy *aphy;
struct ath_softc *sc;
struct ieee80211_hw *hw;
struct resource *res;

View file

@ -745,43 +745,6 @@ static void ath9k_olc_temp_compensation(struct ath_hw *ah)
}
}
bool ath9k_hw_calibrate(struct ath_hw *ah, struct ath9k_channel *chan,
u8 rxchainmask, bool longcal,
bool *isCalDone)
{
struct hal_cal_list *currCal = ah->cal_list_curr;
*isCalDone = true;
if (currCal &&
(currCal->calState == CAL_RUNNING ||
currCal->calState == CAL_WAITING)) {
ath9k_hw_per_calibration(ah, chan, rxchainmask, currCal,
isCalDone);
if (*isCalDone) {
ah->cal_list_curr = currCal = currCal->calNext;
if (currCal->calState == CAL_WAITING) {
*isCalDone = false;
ath9k_hw_reset_calibration(ah, currCal);
}
}
}
if (longcal) {
if (OLC_FOR_AR9280_20_LATER)
ath9k_olc_temp_compensation(ah);
ath9k_hw_getnf(ah, chan);
ath9k_hw_loadnf(ah, ah->curchan);
ath9k_hw_start_nfcal(ah);
if (chan->channelFlags & CHANNEL_CW_INT)
chan->channelFlags &= ~CHANNEL_CW_INT;
}
return true;
}
static inline void ath9k_hw_9285_pa_cal(struct ath_hw *ah)
{
@ -877,22 +840,104 @@ static inline void ath9k_hw_9285_pa_cal(struct ath_hw *ah)
}
bool ath9k_hw_calibrate(struct ath_hw *ah, struct ath9k_channel *chan,
u8 rxchainmask, bool longcal,
bool *isCalDone)
{
struct hal_cal_list *currCal = ah->cal_list_curr;
*isCalDone = true;
if (currCal &&
(currCal->calState == CAL_RUNNING ||
currCal->calState == CAL_WAITING)) {
ath9k_hw_per_calibration(ah, chan, rxchainmask, currCal,
isCalDone);
if (*isCalDone) {
ah->cal_list_curr = currCal = currCal->calNext;
if (currCal->calState == CAL_WAITING) {
*isCalDone = false;
ath9k_hw_reset_calibration(ah, currCal);
}
}
}
if (longcal) {
if (AR_SREV_9285(ah) && AR_SREV_9285_11_OR_LATER(ah))
ath9k_hw_9285_pa_cal(ah);
if (OLC_FOR_AR9280_20_LATER)
ath9k_olc_temp_compensation(ah);
ath9k_hw_getnf(ah, chan);
ath9k_hw_loadnf(ah, ah->curchan);
ath9k_hw_start_nfcal(ah);
if (chan->channelFlags & CHANNEL_CW_INT)
chan->channelFlags &= ~CHANNEL_CW_INT;
}
return true;
}
static bool ar9285_clc(struct ath_hw *ah, struct ath9k_channel *chan)
{
REG_SET_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_CL_CAL_ENABLE);
if (chan->channelFlags & CHANNEL_HT20) {
REG_SET_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_PARALLEL_CAL_ENABLE);
REG_SET_BIT(ah, AR_PHY_TURBO, AR_PHY_FC_DYN2040_EN);
REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL,
AR_PHY_AGC_CONTROL_FLTR_CAL);
REG_CLR_BIT(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_CAL_ENABLE);
REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL);
if (!ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL,
AR_PHY_AGC_CONTROL_CAL, 0, AH_WAIT_TIMEOUT)) {
DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, "offset "
"calibration failed to complete in "
"1ms; noisy ??\n");
return false;
}
REG_CLR_BIT(ah, AR_PHY_TURBO, AR_PHY_FC_DYN2040_EN);
REG_CLR_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_PARALLEL_CAL_ENABLE);
REG_CLR_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_CL_CAL_ENABLE);
}
REG_CLR_BIT(ah, AR_PHY_ADC_CTL, AR_PHY_ADC_CTL_OFF_PWDADC);
REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_FLTR_CAL);
REG_SET_BIT(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_CAL_ENABLE);
REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL);
if (!ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL,
0, AH_WAIT_TIMEOUT)) {
DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, "offset calibration "
"failed to complete in 1ms; noisy ??\n");
return false;
}
REG_SET_BIT(ah, AR_PHY_ADC_CTL, AR_PHY_ADC_CTL_OFF_PWDADC);
REG_CLR_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_CL_CAL_ENABLE);
REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_FLTR_CAL);
return true;
}
bool ath9k_hw_init_cal(struct ath_hw *ah,
struct ath9k_channel *chan)
{
if (AR_SREV_9280_10_OR_LATER(ah)) {
if (AR_SREV_9285(ah) && AR_SREV_9285_12_OR_LATER(ah)) {
if (!ar9285_clc(ah, chan))
return false;
} else if (AR_SREV_9280_10_OR_LATER(ah)) {
REG_CLR_BIT(ah, AR_PHY_ADC_CTL, AR_PHY_ADC_CTL_OFF_PWDADC);
REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_FLTR_CAL);
REG_CLR_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_CL_CAL_ENABLE);
/* Kick off the cal */
REG_WRITE(ah, AR_PHY_AGC_CONTROL,
REG_READ(ah, AR_PHY_AGC_CONTROL) |
AR_PHY_AGC_CONTROL_CAL);
REG_READ(ah, AR_PHY_AGC_CONTROL) |
AR_PHY_AGC_CONTROL_CAL);
if (!ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL,
AR_PHY_AGC_CONTROL_CAL, 0,
AH_WAIT_TIMEOUT)) {
AR_PHY_AGC_CONTROL_CAL, 0,
AH_WAIT_TIMEOUT)) {
DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
"offset calibration failed to complete in 1ms; "
"noisy environment?\n");
@ -906,11 +951,11 @@ bool ath9k_hw_init_cal(struct ath_hw *ah,
/* Calibrate the AGC */
REG_WRITE(ah, AR_PHY_AGC_CONTROL,
REG_READ(ah, AR_PHY_AGC_CONTROL) |
AR_PHY_AGC_CONTROL_CAL);
REG_READ(ah, AR_PHY_AGC_CONTROL) |
AR_PHY_AGC_CONTROL_CAL);
if (!ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL,
0, AH_WAIT_TIMEOUT)) {
0, AH_WAIT_TIMEOUT)) {
DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
"offset calibration failed to complete in 1ms; "
"noisy environment?\n");
@ -928,8 +973,8 @@ bool ath9k_hw_init_cal(struct ath_hw *ah,
/* Do NF Calibration */
REG_WRITE(ah, AR_PHY_AGC_CONTROL,
REG_READ(ah, AR_PHY_AGC_CONTROL) |
AR_PHY_AGC_CONTROL_NF);
REG_READ(ah, AR_PHY_AGC_CONTROL) |
AR_PHY_AGC_CONTROL_NF);
ah->cal_list = ah->cal_list_last = ah->cal_list_curr = NULL;
@ -938,19 +983,19 @@ bool ath9k_hw_init_cal(struct ath_hw *ah,
INIT_CAL(&ah->adcgain_caldata);
INSERT_CAL(ah, &ah->adcgain_caldata);
DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
"enabling ADC Gain Calibration.\n");
"enabling ADC Gain Calibration.\n");
}
if (ath9k_hw_iscal_supported(ah, ADC_DC_CAL)) {
INIT_CAL(&ah->adcdc_caldata);
INSERT_CAL(ah, &ah->adcdc_caldata);
DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
"enabling ADC DC Calibration.\n");
"enabling ADC DC Calibration.\n");
}
if (ath9k_hw_iscal_supported(ah, IQ_MISMATCH_CAL)) {
INIT_CAL(&ah->iq_caldata);
INSERT_CAL(ah, &ah->iq_caldata);
DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
"enabling IQ Calibration.\n");
"enabling IQ Calibration.\n");
}
ah->cal_list_curr = ah->cal_list;

View file

@ -14,11 +14,15 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <asm/unaligned.h>
#include "ath9k.h"
static unsigned int ath9k_debug = DBG_DEFAULT;
module_param_named(debug, ath9k_debug, uint, 0);
static struct dentry *ath9k_debugfs_root;
void DPRINTF(struct ath_softc *sc, int dbg_mask, const char *fmt, ...)
{
if (!sc)
@ -318,6 +322,9 @@ static ssize_t read_file_rcstat(struct file *file, char __user *user_buf,
{
struct ath_softc *sc = file->private_data;
if (sc->cur_rate_table == NULL)
return 0;
if (conf_is_ht(&sc->hw->conf))
return ath_read_file_stat_11n_rc(file, user_buf, count, ppos);
else
@ -491,12 +498,8 @@ int ath9k_init_debug(struct ath_softc *sc)
{
sc->debug.debug_mask = ath9k_debug;
sc->debug.debugfs_root = debugfs_create_dir(KBUILD_MODNAME, NULL);
if (!sc->debug.debugfs_root)
goto err;
sc->debug.debugfs_phy = debugfs_create_dir(wiphy_name(sc->hw->wiphy),
sc->debug.debugfs_root);
ath9k_debugfs_root);
if (!sc->debug.debugfs_phy)
goto err;
@ -538,5 +541,19 @@ void ath9k_exit_debug(struct ath_softc *sc)
debugfs_remove(sc->debug.debugfs_interrupt);
debugfs_remove(sc->debug.debugfs_dma);
debugfs_remove(sc->debug.debugfs_phy);
debugfs_remove(sc->debug.debugfs_root);
}
int ath9k_debug_create_root(void)
{
ath9k_debugfs_root = debugfs_create_dir(KBUILD_MODNAME, NULL);
if (!ath9k_debugfs_root)
return -ENOENT;
return 0;
}
void ath9k_debug_remove_root(void)
{
debugfs_remove(ath9k_debugfs_root);
ath9k_debugfs_root = NULL;
}

View file

@ -102,7 +102,6 @@ struct ath_stats {
struct ath9k_debug {
int debug_mask;
struct dentry *debugfs_root;
struct dentry *debugfs_phy;
struct dentry *debugfs_dma;
struct dentry *debugfs_interrupt;
@ -114,6 +113,8 @@ struct ath9k_debug {
void DPRINTF(struct ath_softc *sc, int dbg_mask, const char *fmt, ...);
int ath9k_init_debug(struct ath_softc *sc);
void ath9k_exit_debug(struct ath_softc *sc);
int ath9k_debug_create_root(void);
void ath9k_debug_remove_root(void);
void ath_debug_stat_interrupt(struct ath_softc *sc, enum ath9k_int status);
void ath_debug_stat_rc(struct ath_softc *sc, struct sk_buff *skb);
void ath_debug_stat_retries(struct ath_softc *sc, int rix,
@ -135,6 +136,15 @@ static inline void ath9k_exit_debug(struct ath_softc *sc)
{
}
static inline int ath9k_debug_create_root(void)
{
return 0;
}
static inline void ath9k_debug_remove_root(void)
{
}
static inline void ath_debug_stat_interrupt(struct ath_softc *sc,
enum ath9k_int status)
{

View file

@ -640,7 +640,7 @@ static void ath9k_hw_get_4k_gain_boundaries_pdadcs(struct ath_hw *ah,
pPdGainBoundaries[i] =
min((u16)AR5416_MAX_RATE_POWER, pPdGainBoundaries[i]);
if ((i == 0) && !AR_SREV_5416_V20_OR_LATER(ah)) {
if ((i == 0) && !AR_SREV_5416_20_OR_LATER(ah)) {
minDelta = pPdGainBoundaries[0] - 23;
pPdGainBoundaries[0] = 23;
} else {
@ -679,7 +679,7 @@ static void ath9k_hw_get_4k_gain_boundaries_pdadcs(struct ath_hw *ah,
vpdTableI[i][sizeCurrVpdTable - 2]);
vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep);
if (tgtIndex > maxIndex) {
if (tgtIndex >= maxIndex) {
while ((ss <= tgtIndex) &&
(k < (AR5416_NUM_PDADC_VALUES - 1))) {
tmpVal = (int16_t) TMP_VAL_VPD_TABLE;
@ -713,11 +713,11 @@ static bool ath9k_hw_set_4k_power_cal_table(struct ath_hw *ah,
u8 *pCalBChans = NULL;
u16 pdGainOverlap_t2;
static u8 pdadcValues[AR5416_NUM_PDADC_VALUES];
u16 gainBoundaries[AR5416_PD_GAINS_IN_MASK];
u16 gainBoundaries[AR5416_EEP4K_PD_GAINS_IN_MASK];
u16 numPiers, i, j;
int16_t tMinCalPower;
u16 numXpdGain, xpdMask;
u16 xpdGainValues[AR5416_NUM_PD_GAINS] = { 0, 0, 0, 0 };
u16 xpdGainValues[AR5416_EEP4K_NUM_PD_GAINS] = { 0, 0 };
u32 reg32, regOffset, regChainOffset;
xpdMask = pEepData->modalHeader.xpdGain;
@ -732,16 +732,16 @@ static bool ath9k_hw_set_4k_power_cal_table(struct ath_hw *ah,
}
pCalBChans = pEepData->calFreqPier2G;
numPiers = AR5416_NUM_2G_CAL_PIERS;
numPiers = AR5416_EEP4K_NUM_2G_CAL_PIERS;
numXpdGain = 0;
for (i = 1; i <= AR5416_PD_GAINS_IN_MASK; i++) {
if ((xpdMask >> (AR5416_PD_GAINS_IN_MASK - i)) & 1) {
if (numXpdGain >= AR5416_NUM_PD_GAINS)
for (i = 1; i <= AR5416_EEP4K_PD_GAINS_IN_MASK; i++) {
if ((xpdMask >> (AR5416_EEP4K_PD_GAINS_IN_MASK - i)) & 1) {
if (numXpdGain >= AR5416_EEP4K_NUM_PD_GAINS)
break;
xpdGainValues[numXpdGain] =
(u16)(AR5416_PD_GAINS_IN_MASK - i);
(u16)(AR5416_EEP4K_PD_GAINS_IN_MASK - i);
numXpdGain++;
}
}
@ -754,8 +754,8 @@ static bool ath9k_hw_set_4k_power_cal_table(struct ath_hw *ah,
xpdGainValues[1]);
REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_3, 0);
for (i = 0; i < AR5416_MAX_CHAINS; i++) {
if (AR_SREV_5416_V20_OR_LATER(ah) &&
for (i = 0; i < AR5416_EEP4K_MAX_CHAINS; i++) {
if (AR_SREV_5416_20_OR_LATER(ah) &&
(ah->rxchainmask == 5 || ah->txchainmask == 5) &&
(i != 0)) {
regChainOffset = (i == 1) ? 0x2000 : 0x1000;
@ -771,7 +771,7 @@ static bool ath9k_hw_set_4k_power_cal_table(struct ath_hw *ah,
&tMinCalPower, gainBoundaries,
pdadcValues, numXpdGain);
if ((i == 0) || AR_SREV_5416_V20_OR_LATER(ah)) {
if ((i == 0) || AR_SREV_5416_20_OR_LATER(ah)) {
REG_WRITE(ah, AR_PHY_TPCRG5 + regChainOffset,
SM(pdGainOverlap_t2,
AR_PHY_TPCRG5_PD_GAIN_OVERLAP)
@ -1707,7 +1707,7 @@ static bool ath9k_hw_def_set_board_values(struct ath_hw *ah,
break;
}
if (AR_SREV_5416_V20_OR_LATER(ah) &&
if (AR_SREV_5416_20_OR_LATER(ah) &&
(ah->rxchainmask == 5 || ah->txchainmask == 5)
&& (i != 0))
regChainOffset = (i == 1) ? 0x2000 : 0x1000;
@ -1728,7 +1728,7 @@ static bool ath9k_hw_def_set_board_values(struct ath_hw *ah,
SM(pModal->iqCalQCh[i],
AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF));
if ((i == 0) || AR_SREV_5416_V20_OR_LATER(ah)) {
if ((i == 0) || AR_SREV_5416_20_OR_LATER(ah)) {
if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_3) {
txRxAttenLocal = pModal->txRxAttenCh[i];
if (AR_SREV_9280_10_OR_LATER(ah)) {
@ -2094,7 +2094,7 @@ static void ath9k_hw_get_def_gain_boundaries_pdadcs(struct ath_hw *ah,
pPdGainBoundaries[i] =
min((u16)AR5416_MAX_RATE_POWER, pPdGainBoundaries[i]);
if ((i == 0) && !AR_SREV_5416_V20_OR_LATER(ah)) {
if ((i == 0) && !AR_SREV_5416_20_OR_LATER(ah)) {
minDelta = pPdGainBoundaries[0] - 23;
pPdGainBoundaries[0] = 23;
} else {
@ -2228,7 +2228,7 @@ static bool ath9k_hw_set_def_power_cal_table(struct ath_hw *ah,
xpdGainValues[2]);
for (i = 0; i < AR5416_MAX_CHAINS; i++) {
if (AR_SREV_5416_V20_OR_LATER(ah) &&
if (AR_SREV_5416_20_OR_LATER(ah) &&
(ah->rxchainmask == 5 || ah->txchainmask == 5) &&
(i != 0)) {
regChainOffset = (i == 1) ? 0x2000 : 0x1000;
@ -2262,7 +2262,7 @@ static bool ath9k_hw_set_def_power_cal_table(struct ath_hw *ah,
numXpdGain);
}
if ((i == 0) || AR_SREV_5416_V20_OR_LATER(ah)) {
if ((i == 0) || AR_SREV_5416_20_OR_LATER(ah)) {
if (OLC_FOR_AR9280_20_LATER) {
REG_WRITE(ah,
AR_PHY_TPCRG5 + regChainOffset,

View file

@ -261,7 +261,7 @@ struct base_eep_header_4k {
u16 deviceCap;
u32 binBuildNumber;
u8 deviceType;
u8 futureBase[1];
u8 txGainType;
} __packed;

View file

@ -682,22 +682,16 @@ static struct ath_hw *ath9k_hw_do_attach(u16 devid, struct ath_softc *sc,
ah->supp_cals = ADC_GAIN_CAL | ADC_DC_CAL | IQ_MISMATCH_CAL;
}
if (AR_SREV_9160(ah)) {
ah->config.enable_ani = 1;
ah->ani_function = (ATH9K_ANI_SPUR_IMMUNITY_LEVEL |
ATH9K_ANI_FIRSTEP_LEVEL);
} else {
ah->ani_function = ATH9K_ANI_ALL;
if (AR_SREV_9280_10_OR_LATER(ah)) {
ah->ani_function &= ~ATH9K_ANI_NOISE_IMMUNITY_LEVEL;
}
}
ah->ani_function = ATH9K_ANI_ALL;
if (AR_SREV_9280_10_OR_LATER(ah))
ah->ani_function &= ~ATH9K_ANI_NOISE_IMMUNITY_LEVEL;
DPRINTF(sc, ATH_DBG_RESET,
"This Mac Chip Rev 0x%02x.%x is \n",
ah->hw_version.macVersion, ah->hw_version.macRev);
if (AR_SREV_9285_12_OR_LATER(ah)) {
INIT_INI_ARRAY(&ah->iniModes, ar9285Modes_9285_1_2,
ARRAY_SIZE(ar9285Modes_9285_1_2), 6);
INIT_INI_ARRAY(&ah->iniCommon, ar9285Common_9285_1_2,
@ -837,6 +831,22 @@ static struct ath_hw *ath9k_hw_do_attach(u16 devid, struct ath_softc *sc,
if (ecode != 0)
goto bad;
if (AR_SREV_9285_12_OR_LATER(ah)) {
u32 txgain_type = ah->eep_ops->get_eeprom(ah, EEP_TXGAIN_TYPE);
/* txgain table */
if (txgain_type == AR5416_EEP_TXGAIN_HIGH_POWER) {
INIT_INI_ARRAY(&ah->iniModesTxGain,
ar9285Modes_high_power_tx_gain_9285_1_2,
ARRAY_SIZE(ar9285Modes_high_power_tx_gain_9285_1_2), 6);
} else {
INIT_INI_ARRAY(&ah->iniModesTxGain,
ar9285Modes_original_tx_gain_9285_1_2,
ARRAY_SIZE(ar9285Modes_original_tx_gain_9285_1_2), 6);
}
}
/* rxgain table */
if (AR_SREV_9280_20(ah))
ath9k_hw_init_rxgain_ini(ah);
@ -1173,7 +1183,7 @@ static void ath9k_hw_override_ini(struct ath_hw *ah,
REG_SET_BIT(ah, AR_DIAG_SW, (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT));
if (!AR_SREV_5416_V20_OR_LATER(ah) ||
if (!AR_SREV_5416_20_OR_LATER(ah) ||
AR_SREV_9280_10_OR_LATER(ah))
return;
@ -1275,7 +1285,7 @@ static int ath9k_hw_process_ini(struct ath_hw *ah,
REG_WRITE(ah, AR_PHY_ADC_SERIAL_CTL, AR_PHY_SEL_EXTERNAL_RADIO);
ah->eep_ops->set_addac(ah, chan);
if (AR_SREV_5416_V22_OR_LATER(ah)) {
if (AR_SREV_5416_22_OR_LATER(ah)) {
REG_WRITE_ARRAY(&ah->iniAddac, 1, regWrites);
} else {
struct ar5416IniArray temp;
@ -1313,7 +1323,8 @@ static int ath9k_hw_process_ini(struct ath_hw *ah,
if (AR_SREV_9280(ah))
REG_WRITE_ARRAY(&ah->iniModesRxGain, modesIndex, regWrites);
if (AR_SREV_9280(ah))
if (AR_SREV_9280(ah) || (AR_SREV_9285(ah) &&
AR_SREV_9285_12_OR_LATER(ah)))
REG_WRITE_ARRAY(&ah->iniModesTxGain, modesIndex, regWrites);
for (i = 0; i < ah->iniCommon.ia_rows; i++) {

View file

@ -14,7 +14,7 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
static const u32 ar5416Modes_9100[][6] = {
static const u32 ar5416Modes[][6] = {
{ 0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160, 0x000001e0 },
{ 0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c, 0x000001e0 },
{ 0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38, 0x00001180 },
@ -78,7 +78,7 @@ static const u32 ar5416Modes_9100[][6] = {
{ 0x0000a334, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
};
static const u32 ar5416Common_9100[][2] = {
static const u32 ar5416Common[][2] = {
{ 0x0000000c, 0x00000000 },
{ 0x00000030, 0x00020015 },
{ 0x00000034, 0x00000005 },
@ -456,12 +456,12 @@ static const u32 ar5416Common_9100[][2] = {
{ 0x0000a3e0, 0x000001ce },
};
static const u32 ar5416Bank0_9100[][2] = {
static const u32 ar5416Bank0[][2] = {
{ 0x000098b0, 0x1e5795e5 },
{ 0x000098e0, 0x02008020 },
};
static const u32 ar5416BB_RfGain_9100[][3] = {
static const u32 ar5416BB_RfGain[][3] = {
{ 0x00009a00, 0x00000000, 0x00000000 },
{ 0x00009a04, 0x00000040, 0x00000040 },
{ 0x00009a08, 0x00000080, 0x00000080 },
@ -528,21 +528,21 @@ static const u32 ar5416BB_RfGain_9100[][3] = {
{ 0x00009afc, 0x000000f9, 0x000000f9 },
};
static const u32 ar5416Bank1_9100[][2] = {
static const u32 ar5416Bank1[][2] = {
{ 0x000098b0, 0x02108421 },
{ 0x000098ec, 0x00000008 },
};
static const u32 ar5416Bank2_9100[][2] = {
static const u32 ar5416Bank2[][2] = {
{ 0x000098b0, 0x0e73ff17 },
{ 0x000098e0, 0x00000420 },
};
static const u32 ar5416Bank3_9100[][3] = {
static const u32 ar5416Bank3[][3] = {
{ 0x000098f0, 0x01400018, 0x01c00018 },
};
static const u32 ar5416Bank6_9100[][3] = {
static const u32 ar5416Bank6[][3] = {
{ 0x0000989c, 0x00000000, 0x00000000 },
{ 0x0000989c, 0x00000000, 0x00000000 },
@ -579,7 +579,7 @@ static const u32 ar5416Bank6_9100[][3] = {
{ 0x000098d0, 0x0000000f, 0x0010000f },
};
static const u32 ar5416Bank6TPC_9100[][3] = {
static const u32 ar5416Bank6TPC[][3] = {
{ 0x0000989c, 0x00000000, 0x00000000 },
{ 0x0000989c, 0x00000000, 0x00000000 },
{ 0x0000989c, 0x00000000, 0x00000000 },
@ -615,13 +615,13 @@ static const u32 ar5416Bank6TPC_9100[][3] = {
{ 0x000098d0, 0x0000000f, 0x0010000f },
};
static const u32 ar5416Bank7_9100[][2] = {
static const u32 ar5416Bank7[][2] = {
{ 0x0000989c, 0x00000500 },
{ 0x0000989c, 0x00000800 },
{ 0x000098cc, 0x0000000e },
};
static const u32 ar5416Addac_9100[][2] = {
static const u32 ar5416Addac[][2] = {
{0x0000989c, 0x00000000 },
{0x0000989c, 0x00000003 },
{0x0000989c, 0x00000000 },
@ -661,7 +661,7 @@ static const u32 ar5416Addac_9100[][2] = {
{0x000098cc, 0x00000000 },
};
static const u32 ar5416Modes[][6] = {
static const u32 ar5416Modes_9100[][6] = {
{ 0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160, 0x000001e0 },
{ 0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c, 0x000001e0 },
{ 0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38, 0x00001180 },
@ -735,7 +735,7 @@ static const u32 ar5416Modes[][6] = {
{ 0x0000a334, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
};
static const u32 ar5416Common[][2] = {
static const u32 ar5416Common_9100[][2] = {
{ 0x0000000c, 0x00000000 },
{ 0x00000030, 0x00020015 },
{ 0x00000034, 0x00000005 },
@ -1109,12 +1109,12 @@ static const u32 ar5416Common[][2] = {
{ 0x0000a3e0, 0x000001ce },
};
static const u32 ar5416Bank0[][2] = {
static const u32 ar5416Bank0_9100[][2] = {
{ 0x000098b0, 0x1e5795e5 },
{ 0x000098e0, 0x02008020 },
};
static const u32 ar5416BB_RfGain[][3] = {
static const u32 ar5416BB_RfGain_9100[][3] = {
{ 0x00009a00, 0x00000000, 0x00000000 },
{ 0x00009a04, 0x00000040, 0x00000040 },
{ 0x00009a08, 0x00000080, 0x00000080 },
@ -1181,21 +1181,21 @@ static const u32 ar5416BB_RfGain[][3] = {
{ 0x00009afc, 0x000000f9, 0x000000f9 },
};
static const u32 ar5416Bank1[][2] = {
static const u32 ar5416Bank1_9100[][2] = {
{ 0x000098b0, 0x02108421},
{ 0x000098ec, 0x00000008},
};
static const u32 ar5416Bank2[][2] = {
static const u32 ar5416Bank2_9100[][2] = {
{ 0x000098b0, 0x0e73ff17},
{ 0x000098e0, 0x00000420},
};
static const u32 ar5416Bank3[][3] = {
static const u32 ar5416Bank3_9100[][3] = {
{ 0x000098f0, 0x01400018, 0x01c00018 },
};
static const u32 ar5416Bank6[][3] = {
static const u32 ar5416Bank6_9100[][3] = {
{ 0x0000989c, 0x00000000, 0x00000000 },
{ 0x0000989c, 0x00000000, 0x00000000 },
@ -1233,7 +1233,7 @@ static const u32 ar5416Bank6[][3] = {
};
static const u32 ar5416Bank6TPC[][3] = {
static const u32 ar5416Bank6TPC_9100[][3] = {
{ 0x0000989c, 0x00000000, 0x00000000 },
{ 0x0000989c, 0x00000000, 0x00000000 },
@ -1270,13 +1270,13 @@ static const u32 ar5416Bank6TPC[][3] = {
{ 0x000098d0, 0x0000000f, 0x0010000f },
};
static const u32 ar5416Bank7[][2] = {
static const u32 ar5416Bank7_9100[][2] = {
{ 0x0000989c, 0x00000500 },
{ 0x0000989c, 0x00000800 },
{ 0x000098cc, 0x0000000e },
};
static const u32 ar5416Addac[][2] = {
static const u32 ar5416Addac_9100[][2] = {
{0x0000989c, 0x00000000 },
{0x0000989c, 0x00000000 },
{0x0000989c, 0x00000000 },
@ -4121,6 +4121,7 @@ static const u_int32_t ar9285PciePhy_clkreq_off_L1_9285[][2] = {
{0x00004044, 0x00000000 },
};
/* AR9285 v1_2 PCI Register Writes. Created: 03/04/09 */
static const u_int32_t ar9285Modes_9285_1_2[][6] = {
{ 0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160, 0x000001e0 },
{ 0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c, 0x000001e0 },
@ -4155,7 +4156,7 @@ static const u_int32_t ar9285Modes_9285_1_2[][6] = {
{ 0x000099bc, 0x00000600, 0x00000600, 0x00000c00, 0x00000c00, 0x00000c00 },
{ 0x000099c0, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4 },
{ 0x000099c4, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77 },
{ 0x000099c8, 0x60f65329, 0x60f65329, 0x60f65329, 0x60f65329, 0x60f65329 },
{ 0x000099c8, 0x6af65329, 0x6af65329, 0x6af65329, 0x6af65329, 0x6af65329 },
{ 0x000099cc, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8 },
{ 0x000099d0, 0x00046384, 0x00046384, 0x00046384, 0x00046384, 0x00046384 },
{ 0x000099d4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
@ -4421,25 +4422,6 @@ static const u_int32_t ar9285Modes_9285_1_2[][6] = {
{ 0x0000a21c, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a },
{ 0x0000a230, 0x00000000, 0x00000000, 0x00000210, 0x00000108, 0x00000000 },
{ 0x0000a250, 0x0004f000, 0x0004f000, 0x0004a000, 0x0004a000, 0x0004a000 },
{ 0x0000a274, 0x0a81c652, 0x0a81c652, 0x0a820652, 0x0a820652, 0x0a82a652 },
{ 0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
{ 0x0000a304, 0x00000000, 0x00000000, 0x00007201, 0x00007201, 0x00000000 },
{ 0x0000a308, 0x00000000, 0x00000000, 0x00010408, 0x00010408, 0x00000000 },
{ 0x0000a30c, 0x00000000, 0x00000000, 0x0001860a, 0x0001860a, 0x00000000 },
{ 0x0000a310, 0x00000000, 0x00000000, 0x00020818, 0x00020818, 0x00000000 },
{ 0x0000a314, 0x00000000, 0x00000000, 0x00024858, 0x00024858, 0x00000000 },
{ 0x0000a318, 0x00000000, 0x00000000, 0x00026859, 0x00026859, 0x00000000 },
{ 0x0000a31c, 0x00000000, 0x00000000, 0x0002985b, 0x0002985b, 0x00000000 },
{ 0x0000a320, 0x00000000, 0x00000000, 0x0002b89a, 0x0002b89a, 0x00000000 },
{ 0x0000a324, 0x00000000, 0x00000000, 0x0002d89b, 0x0002d89b, 0x00000000 },
{ 0x0000a328, 0x00000000, 0x00000000, 0x0002f89c, 0x0002f89c, 0x00000000 },
{ 0x0000a32c, 0x00000000, 0x00000000, 0x0003189d, 0x0003189d, 0x00000000 },
{ 0x0000a330, 0x00000000, 0x00000000, 0x0003389e, 0x0003389e, 0x00000000 },
{ 0x0000a334, 0x00000000, 0x00000000, 0x000368de, 0x000368de, 0x00000000 },
{ 0x0000a338, 0x00000000, 0x00000000, 0x0003891e, 0x0003891e, 0x00000000 },
{ 0x0000a33c, 0x00000000, 0x00000000, 0x0003a95e, 0x0003a95e, 0x00000000 },
{ 0x0000a340, 0x00000000, 0x00000000, 0x0003e9df, 0x0003e9df, 0x00000000 },
{ 0x0000a344, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
{ 0x0000a358, 0x7999aa02, 0x7999aa02, 0x7999aa0e, 0x7999aa0e, 0x7999aa0e },
};
@ -4569,7 +4551,7 @@ static const u_int32_t ar9285Common_9285_1_2[][2] = {
{ 0x00008110, 0x00000168 },
{ 0x00008118, 0x000100aa },
{ 0x0000811c, 0x00003210 },
{ 0x00008120, 0x08f04800 },
{ 0x00008120, 0x08f04810 },
{ 0x00008124, 0x00000000 },
{ 0x00008128, 0x00000000 },
{ 0x0000812c, 0x00000000 },
@ -4585,7 +4567,7 @@ static const u_int32_t ar9285Common_9285_1_2[][2] = {
{ 0x00008178, 0x00000100 },
{ 0x0000817c, 0x00000000 },
{ 0x000081c0, 0x00000000 },
{ 0x000081d0, 0x00003210 },
{ 0x000081d0, 0x0000320a },
{ 0x000081ec, 0x00000000 },
{ 0x000081f0, 0x00000000 },
{ 0x000081f4, 0x00000000 },
@ -4709,8 +4691,6 @@ static const u_int32_t ar9285Common_9285_1_2[][2] = {
{ 0x0000a268, 0x00000000 },
{ 0x0000a26c, 0x0ebae9e6 },
{ 0x0000d270, 0x0d820820 },
{ 0x0000a278, 0x318c6318 },
{ 0x0000a27c, 0x050c0318 },
{ 0x0000d35c, 0x07ffffef },
{ 0x0000d360, 0x0fffffe7 },
{ 0x0000d364, 0x17ffffe5 },
@ -4725,8 +4705,6 @@ static const u_int32_t ar9285Common_9285_1_2[][2] = {
{ 0x0000a388, 0x0c000000 },
{ 0x0000a38c, 0x20202020 },
{ 0x0000a390, 0x20202020 },
{ 0x0000a394, 0x318c6318 },
{ 0x0000a398, 0x00000318 },
{ 0x0000a39c, 0x00000001 },
{ 0x0000a3a0, 0x00000000 },
{ 0x0000a3a4, 0x00000000 },
@ -4741,8 +4719,6 @@ static const u_int32_t ar9285Common_9285_1_2[][2] = {
{ 0x0000a3cc, 0x20202020 },
{ 0x0000a3d0, 0x20202020 },
{ 0x0000a3d4, 0x20202020 },
{ 0x0000a3dc, 0x318c6318 },
{ 0x0000a3e0, 0x00000318 },
{ 0x0000a3e4, 0x00000000 },
{ 0x0000a3e8, 0x18c43433 },
{ 0x0000a3ec, 0x00f70081 },
@ -4753,13 +4729,11 @@ static const u_int32_t ar9285Common_9285_1_2[][2] = {
{ 0x00007810, 0x71c0d388 },
{ 0x00007814, 0x924934a8 },
{ 0x0000781c, 0x00000000 },
{ 0x00007820, 0x00000c04 },
{ 0x00007824, 0x00d86fff },
{ 0x00007828, 0x26d2491b },
{ 0x0000782c, 0x6e36d97b },
{ 0x00007830, 0xedb6d96e },
{ 0x00007834, 0x71400087 },
{ 0x00007838, 0xfac68801 },
{ 0x0000783c, 0x0001fffe },
{ 0x00007840, 0xffeb1a20 },
{ 0x00007844, 0x000c0db6 },
@ -4772,10 +4746,81 @@ static const u_int32_t ar9285Common_9285_1_2[][2] = {
{ 0x00007860, 0x21084210 },
{ 0x00007864, 0xf7d7ffde },
{ 0x00007868, 0xc2034080 },
{ 0x0000786c, 0x48609eb4 },
{ 0x00007870, 0x10142c00 },
};
static const u_int32_t ar9285Modes_high_power_tx_gain_9285_1_2[][6] = {
/* Address 5G-HT20 5G-HT40 2G-HT40 2G-HT20 Turbo */
{ 0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
{ 0x0000a304, 0x00000000, 0x00000000, 0x00005200, 0x00005200, 0x00000000 },
{ 0x0000a308, 0x00000000, 0x00000000, 0x00007201, 0x00007201, 0x00000000 },
{ 0x0000a30c, 0x00000000, 0x00000000, 0x0000b240, 0x0000b240, 0x00000000 },
{ 0x0000a310, 0x00000000, 0x00000000, 0x0000d241, 0x0000d241, 0x00000000 },
{ 0x0000a314, 0x00000000, 0x00000000, 0x0000f440, 0x0000f440, 0x00000000 },
{ 0x0000a318, 0x00000000, 0x00000000, 0x00014640, 0x00014640, 0x00000000 },
{ 0x0000a31c, 0x00000000, 0x00000000, 0x00018680, 0x00018680, 0x00000000 },
{ 0x0000a320, 0x00000000, 0x00000000, 0x00019841, 0x00019841, 0x00000000 },
{ 0x0000a324, 0x00000000, 0x00000000, 0x0001ca40, 0x0001ca40, 0x00000000 },
{ 0x0000a328, 0x00000000, 0x00000000, 0x0001fa80, 0x0001fa80, 0x00000000 },
{ 0x0000a32c, 0x00000000, 0x00000000, 0x00023ac0, 0x00023ac0, 0x00000000 },
{ 0x0000a330, 0x00000000, 0x00000000, 0x0002ab40, 0x0002ab40, 0x00000000 },
{ 0x0000a334, 0x00000000, 0x00000000, 0x00033d82, 0x00033d82, 0x00000000 },
{ 0x0000a338, 0x0003891e, 0x0003891e, 0x0003891e, 0x0003891e, 0x00000000 },
{ 0x0000a33c, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x00000000 },
{ 0x0000a340, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
{ 0x0000a344, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
{ 0x0000a348, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
{ 0x0000a34c, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
{ 0x0000a350, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
{ 0x0000a354, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
{ 0x00007838, 0xfac68803, 0xfac68803, 0xfac68803, 0xfac68803, 0xfac68803 },
{ 0x0000786c, 0x08609ebe, 0x08609ebe, 0x08609ebe, 0x08609ebe, 0x08609ebe },
{ 0x00007820, 0x00000c00, 0x00000c00, 0x00000c00, 0x00000c00, 0x00000c00 },
{ 0x0000a274, 0x0a22a652, 0x0a22a652, 0x0a21a652, 0x0a21a652, 0x0a22a652 },
{ 0x0000a278, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce },
{ 0x0000a27c, 0x050701ce, 0x050701ce, 0x050701ce, 0x050701ce, 0x050701ce },
{ 0x0000a394, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce },
{ 0x0000a398, 0x000001ce, 0x000001ce, 0x000001ce, 0x000001ce, 0x000001ce },
{ 0x0000a3dc, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce },
{ 0x0000a3e0, 0x000001ce, 0x000001ce, 0x000001ce, 0x000001ce, 0x000001ce },
};
static const u_int32_t ar9285Modes_original_tx_gain_9285_1_2[][6] = {
/* Address 5G-HT20 5G-HT40 2G-HT40 2G-HT20 Turbo */
{ 0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
{ 0x0000a304, 0x00000000, 0x00000000, 0x00009200, 0x00009200, 0x00000000 },
{ 0x0000a308, 0x00000000, 0x00000000, 0x00010208, 0x00010208, 0x00000000 },
{ 0x0000a30c, 0x00000000, 0x00000000, 0x00019608, 0x00019608, 0x00000000 },
{ 0x0000a310, 0x00000000, 0x00000000, 0x00022618, 0x00022618, 0x00000000 },
{ 0x0000a314, 0x00000000, 0x00000000, 0x0002a6c9, 0x0002a6c9, 0x00000000 },
{ 0x0000a318, 0x00000000, 0x00000000, 0x00031710, 0x00031710, 0x00000000 },
{ 0x0000a31c, 0x00000000, 0x00000000, 0x00035718, 0x00035718, 0x00000000 },
{ 0x0000a320, 0x00000000, 0x00000000, 0x00038758, 0x00038758, 0x00000000 },
{ 0x0000a324, 0x00000000, 0x00000000, 0x0003c75a, 0x0003c75a, 0x00000000 },
{ 0x0000a328, 0x00000000, 0x00000000, 0x0004075c, 0x0004075c, 0x00000000 },
{ 0x0000a32c, 0x00000000, 0x00000000, 0x0004475e, 0x0004475e, 0x00000000 },
{ 0x0000a330, 0x00000000, 0x00000000, 0x0004679f, 0x0004679f, 0x00000000 },
{ 0x0000a334, 0x00000000, 0x00000000, 0x000487df, 0x000487df, 0x00000000 },
{ 0x0000a338, 0x0003891e, 0x0003891e, 0x0003891e, 0x0003891e, 0x00000000 },
{ 0x0000a33c, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x00000000 },
{ 0x0000a340, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
{ 0x0000a344, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
{ 0x0000a348, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
{ 0x0000a34c, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
{ 0x0000a350, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
{ 0x0000a354, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
{ 0x00007838, 0xfac68801, 0xfac68801, 0xfac68801, 0xfac68801, 0xfac68801 },
{ 0x0000786c, 0x48609eb4, 0x48609eb4, 0x48609eb4, 0x48609eb4, 0x48609eb4 },
{ 0x00007820, 0x00000c04, 0x00000c04, 0x00000c04, 0x00000c04, 0x00000c04 },
{ 0x0000a274, 0x0a21c652, 0x0a21c652, 0x0a21a652, 0x0a21a652, 0x0a22a652 },
{ 0x0000a278, 0x39ce739c, 0x39ce739c, 0x39ce739c, 0x39ce739c, 0x39ce739c },
{ 0x0000a27c, 0x050e039c, 0x050e039c, 0x050e039c, 0x050e039c, 0x050e039c },
{ 0x0000a394, 0x39ce739c, 0x39ce739c, 0x39ce739c, 0x39ce739c, 0x39ce739c },
{ 0x0000a398, 0x0000039c, 0x0000039c, 0x0000039c, 0x0000039c, 0x0000039c },
{ 0x0000a3dc, 0x39ce739c, 0x39ce739c, 0x39ce739c, 0x39ce739c, 0x39ce739c },
{ 0x0000a3e0, 0x0000039c, 0x0000039c, 0x0000039c, 0x0000039c, 0x0000039c },
};
static const u_int32_t ar9285PciePhy_clkreq_always_on_L1_9285_1_2[][2] = {
{0x00004040, 0x9248fd00 },
{0x00004040, 0x24924924 },

View file

@ -17,7 +17,7 @@
#ifndef MAC_H
#define MAC_H
#define RXSTATUS_RATE(ah, ads) (AR_SREV_5416_V20_OR_LATER(ah) ? \
#define RXSTATUS_RATE(ah, ads) (AR_SREV_5416_20_OR_LATER(ah) ? \
MS(ads->ds_rxstatus0, AR_RxRate) : \
(ads->ds_rxstatus3 >> 2) & 0xFF)

View file

@ -1084,12 +1084,6 @@ fail:
ath_deinit_leds(sc);
}
#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE)
/*******************/
/* Rfkill */
/*******************/
void ath_radio_enable(struct ath_softc *sc)
{
struct ath_hw *ah = sc->sc_ah;
@ -1166,6 +1160,12 @@ void ath_radio_disable(struct ath_softc *sc)
ath9k_ps_restore(sc);
}
#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE)
/*******************/
/* Rfkill */
/*******************/
static bool ath_is_rfkill_set(struct ath_softc *sc)
{
struct ath_hw *ah = sc->sc_ah;
@ -1583,7 +1583,8 @@ void ath_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)
IEEE80211_HW_SIGNAL_DBM |
IEEE80211_HW_AMPDU_AGGREGATION |
IEEE80211_HW_SUPPORTS_PS |
IEEE80211_HW_PS_NULLFUNC_STACK;
IEEE80211_HW_PS_NULLFUNC_STACK |
IEEE80211_HW_SPECTRUM_MGMT;
if (AR_SREV_9160_10_OR_LATER(sc->sc_ah) || modparam_nohwcrypt)
hw->flags |= IEEE80211_HW_MFP_CAPABLE;
@ -1671,7 +1672,7 @@ int ath_attach(u16 devid, struct ath_softc *sc)
}
wiphy_apply_custom_regulatory(hw->wiphy, regd);
ath9k_reg_apply_radar_flags(hw->wiphy);
ath9k_reg_apply_world_flags(hw->wiphy, REGDOM_SET_BY_INIT);
ath9k_reg_apply_world_flags(hw->wiphy, NL80211_REGDOM_SET_BY_DRIVER);
INIT_WORK(&sc->chan_work, ath9k_wiphy_chan_work);
INIT_DELAYED_WORK(&sc->wiphy_work, ath9k_wiphy_work);
@ -1774,6 +1775,7 @@ int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd,
DPRINTF(sc, ATH_DBG_CONFIG, "%s DMA: %u buffers %u desc/buf\n",
name, nbuf, ndesc);
INIT_LIST_HEAD(head);
/* ath_desc must be a multiple of DWORDs */
if ((sizeof(struct ath_desc) % 4) != 0) {
DPRINTF(sc, ATH_DBG_FATAL, "ath_desc not DWORD aligned\n");
@ -1805,7 +1807,7 @@ int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd,
/* allocate descriptors */
dd->dd_desc = dma_alloc_coherent(sc->dev, dd->dd_desc_len,
&dd->dd_desc_paddr, GFP_ATOMIC);
&dd->dd_desc_paddr, GFP_KERNEL);
if (dd->dd_desc == NULL) {
error = -ENOMEM;
goto fail;
@ -1817,15 +1819,13 @@ int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd,
/* allocate buffers */
bsize = sizeof(struct ath_buf) * nbuf;
bf = kmalloc(bsize, GFP_KERNEL);
bf = kzalloc(bsize, GFP_KERNEL);
if (bf == NULL) {
error = -ENOMEM;
goto fail2;
}
memset(bf, 0, bsize);
dd->dd_bufptr = bf;
INIT_LIST_HEAD(head);
for (i = 0; i < nbuf; i++, bf++, ds += ndesc) {
bf->bf_desc = ds;
bf->bf_daddr = DS2PHYS(dd, ds);
@ -2859,12 +2859,20 @@ static int __init ath9k_init(void)
goto err_out;
}
error = ath9k_debug_create_root();
if (error) {
printk(KERN_ERR
"ath9k: Unable to create debugfs root: %d\n",
error);
goto err_rate_unregister;
}
error = ath_pci_init();
if (error < 0) {
printk(KERN_ERR
"ath9k: No PCI devices found, driver not installed.\n");
error = -ENODEV;
goto err_rate_unregister;
goto err_remove_root;
}
error = ath_ahb_init();
@ -2878,6 +2886,8 @@ static int __init ath9k_init(void)
err_pci_exit:
ath_pci_exit();
err_remove_root:
ath9k_debug_remove_root();
err_rate_unregister:
ath_rate_control_unregister();
err_out:
@ -2889,6 +2899,7 @@ static void __exit ath9k_exit(void)
{
ath_ahb_exit();
ath_pci_exit();
ath9k_debug_remove_root();
ath_rate_control_unregister();
printk(KERN_INFO "%s: Driver unloaded\n", dev_info);
}

View file

@ -446,6 +446,9 @@ bool ath9k_hw_init_rf(struct ath_hw *ah,
#define AR_PHY_TPCRG1_PD_GAIN_3 0x00300000
#define AR_PHY_TPCRG1_PD_GAIN_3_S 20
#define AR_PHY_TPCRG1_PD_CAL_ENABLE 0x00400000
#define AR_PHY_TPCRG1_PD_CAL_ENABLE_S 22
#define AR_PHY_TX_PWRCTRL4 0xa264
#define AR_PHY_TX_PWRCTRL_PD_AVG_VALID 0x00000001
#define AR_PHY_TX_PWRCTRL_PD_AVG_VALID_S 0
@ -513,6 +516,7 @@ bool ath9k_hw_init_rf(struct ath_hw *ah,
/* Carrier leak calibration control, do it after AGC calibration */
#define AR_PHY_CL_CAL_CTL 0xA358
#define AR_PHY_CL_CAL_ENABLE 0x00000002
#define AR_PHY_PARALLEL_CAL_ENABLE 0x00000001
#define AR_PHY_POWER_TX_RATE5 0xA38C
#define AR_PHY_POWER_TX_RATE6 0xA390

View file

@ -100,7 +100,7 @@ static u64 ath_extend_tsf(struct ath_softc *sc, u32 rstamp)
return (tsf & ~0x7fff) | rstamp;
}
static struct sk_buff *ath_rxbuf_alloc(struct ath_softc *sc, u32 len)
static struct sk_buff *ath_rxbuf_alloc(struct ath_softc *sc, u32 len, gfp_t gfp_mask)
{
struct sk_buff *skb;
u32 off;
@ -118,7 +118,7 @@ static struct sk_buff *ath_rxbuf_alloc(struct ath_softc *sc, u32 len)
* Unfortunately this means we may get 8 KB here from the
* kernel... and that is actually what is observed on some
* systems :( */
skb = dev_alloc_skb(len + sc->cachelsz - 1);
skb = __dev_alloc_skb(len + sc->cachelsz - 1, gfp_mask);
if (skb != NULL) {
off = ((unsigned long) skb->data) % sc->cachelsz;
if (off != 0)
@ -306,7 +306,7 @@ int ath_rx_init(struct ath_softc *sc, int nbufs)
}
list_for_each_entry(bf, &sc->rx.rxbuf, list) {
skb = ath_rxbuf_alloc(sc, sc->rx.bufsize);
skb = ath_rxbuf_alloc(sc, sc->rx.bufsize, GFP_KERNEL);
if (skb == NULL) {
error = -ENOMEM;
break;
@ -385,14 +385,15 @@ u32 ath_calcrxfilter(struct ath_softc *sc)
if (sc->sc_ah->opmode != NL80211_IFTYPE_STATION)
rfilt |= ATH9K_RX_FILTER_PROBEREQ;
/* Can't set HOSTAP into promiscous mode */
/*
* Set promiscuous mode when FIF_PROMISC_IN_BSS is enabled for station
* mode interface or when in monitor mode. AP mode does not need this
* since it receives all in-BSS frames anyway.
*/
if (((sc->sc_ah->opmode != NL80211_IFTYPE_AP) &&
(sc->rx.rxfilter & FIF_PROMISC_IN_BSS)) ||
(sc->sc_ah->opmode == NL80211_IFTYPE_MONITOR)) {
(sc->sc_ah->opmode == NL80211_IFTYPE_MONITOR))
rfilt |= ATH9K_RX_FILTER_PROM;
/* ??? To prevent from sending ACK */
rfilt &= ~ATH9K_RX_FILTER_UCAST;
}
if (sc->rx.rxfilter & FIF_CONTROL)
rfilt |= ATH9K_RX_FILTER_CONTROL;
@ -580,7 +581,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush)
/* Ensure we always have an skb to requeue once we are done
* processing the current buffer's skb */
requeue_skb = ath_rxbuf_alloc(sc, sc->rx.bufsize);
requeue_skb = ath_rxbuf_alloc(sc, sc->rx.bufsize, GFP_ATOMIC);
/* If there is no memory we ignore the current RX'd frame,
* tell hardware it can give us a new frame using the old

View file

@ -158,14 +158,6 @@
#define AR_CST_TIMEOUT_LIMIT 0xFFFF0000
#define AR_CST_TIMEOUT_LIMIT_S 16
#define AR_SREV_VERSION_9100 0x014
#define AR_SREV_9100(ah) ((ah->hw_version.macVersion) == AR_SREV_VERSION_9100)
#define AR_SREV_5416_V20_OR_LATER(_ah) \
(AR_SREV_9100((_ah)) || AR_SREV_5416_20_OR_LATER(_ah))
#define AR_SREV_5416_V22_OR_LATER(_ah) \
(AR_SREV_9100((_ah)) || AR_SREV_5416_22_OR_LATER(_ah))
#define AR_ISR 0x0080
#define AR_ISR_RXOK 0x00000001
#define AR_ISR_RXDESC 0x00000002
@ -734,6 +726,7 @@
#define AR_SREV_REVISION_5416_10 0
#define AR_SREV_REVISION_5416_20 1
#define AR_SREV_REVISION_5416_22 2
#define AR_SREV_VERSION_9100 0x14
#define AR_SREV_VERSION_9160 0x40
#define AR_SREV_REVISION_9160_10 0
#define AR_SREV_REVISION_9160_11 1
@ -746,14 +739,23 @@
#define AR_SREV_REVISION_9285_11 1
#define AR_SREV_REVISION_9285_12 2
#define AR_SREV_9100_OR_LATER(_ah) \
(((_ah)->hw_version.macVersion >= AR_SREV_VERSION_5416_PCIE))
#define AR_SREV_5416(_ah) \
(((_ah)->hw_version.macVersion == AR_SREV_VERSION_5416_PCI) || \
((_ah)->hw_version.macVersion == AR_SREV_VERSION_5416_PCIE))
#define AR_SREV_5416_20_OR_LATER(_ah) \
(((_ah)->hw_version.macVersion >= AR_SREV_VERSION_9160) || \
((_ah)->hw_version.macRev >= AR_SREV_REVISION_5416_20))
(((AR_SREV_5416(_ah)) && \
((_ah)->hw_version.macRev >= AR_SREV_REVISION_5416_20)) || \
((_ah)->hw_version.macVersion >= AR_SREV_VERSION_9100))
#define AR_SREV_5416_22_OR_LATER(_ah) \
(((_ah)->hw_version.macVersion >= AR_SREV_VERSION_9160) || \
((_ah)->hw_version.macRev >= AR_SREV_REVISION_5416_22))
(((AR_SREV_5416(_ah)) && \
((_ah)->hw_version.macRev >= AR_SREV_REVISION_5416_22)) || \
((_ah)->hw_version.macVersion >= AR_SREV_VERSION_9100))
#define AR_SREV_9100(ah) \
((ah->hw_version.macVersion) == AR_SREV_VERSION_9100)
#define AR_SREV_9100_OR_LATER(_ah) \
(((_ah)->hw_version.macVersion >= AR_SREV_VERSION_9100))
#define AR_SREV_9160(_ah) \
(((_ah)->hw_version.macVersion == AR_SREV_VERSION_9160))
#define AR_SREV_9160_10_OR_LATER(_ah) \
@ -778,14 +780,14 @@
#define AR_SREV_9285_10_OR_LATER(_ah) \
(((_ah)->hw_version.macVersion >= AR_SREV_VERSION_9285))
#define AR_SREV_9285_11(_ah) \
(AR_SREV_9280(ah) && \
(AR_SREV_9285(ah) && \
((_ah)->hw_version.macRev == AR_SREV_REVISION_9285_11))
#define AR_SREV_9285_11_OR_LATER(_ah) \
(((_ah)->hw_version.macVersion > AR_SREV_VERSION_9285) || \
(AR_SREV_9285(ah) && ((_ah)->hw_version.macRev >= \
AR_SREV_REVISION_9285_11)))
#define AR_SREV_9285_12(_ah) \
(AR_SREV_9280(ah) && \
(AR_SREV_9285(ah) && \
((_ah)->hw_version.macRev == AR_SREV_REVISION_9285_12))
#define AR_SREV_9285_12_OR_LATER(_ah) \
(((_ah)->hw_version.macVersion > AR_SREV_VERSION_9285) || \

View file

@ -168,8 +168,9 @@ static bool ath9k_is_radar_freq(u16 center_freq)
* received a beacon on a channel we can enable active scan and
* adhoc (or beaconing).
*/
static void ath9k_reg_apply_beaconing_flags(struct wiphy *wiphy,
enum reg_set_by setby)
static void ath9k_reg_apply_beaconing_flags(
struct wiphy *wiphy,
enum nl80211_reg_initiator initiator)
{
enum ieee80211_band band;
struct ieee80211_supported_band *sband;
@ -194,7 +195,7 @@ static void ath9k_reg_apply_beaconing_flags(struct wiphy *wiphy,
(ch->flags & IEEE80211_CHAN_RADAR))
continue;
if (setby == REGDOM_SET_BY_COUNTRY_IE) {
if (initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE) {
r = freq_reg_info(wiphy, ch->center_freq,
&bandwidth, &reg_rule);
if (r)
@ -226,8 +227,9 @@ static void ath9k_reg_apply_beaconing_flags(struct wiphy *wiphy,
}
/* Allows active scan scan on Ch 12 and 13 */
static void ath9k_reg_apply_active_scan_flags(struct wiphy *wiphy,
enum reg_set_by setby)
static void ath9k_reg_apply_active_scan_flags(
struct wiphy *wiphy,
enum nl80211_reg_initiator initiator)
{
struct ieee80211_supported_band *sband;
struct ieee80211_channel *ch;
@ -241,7 +243,7 @@ static void ath9k_reg_apply_active_scan_flags(struct wiphy *wiphy,
* If no country IE has been received always enable active scan
* on these channels. This is only done for specific regulatory SKUs
*/
if (setby != REGDOM_SET_BY_COUNTRY_IE) {
if (initiator != NL80211_REGDOM_SET_BY_COUNTRY_IE) {
ch = &sband->channels[11]; /* CH 12 */
if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN)
ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN;
@ -308,7 +310,8 @@ void ath9k_reg_apply_radar_flags(struct wiphy *wiphy)
}
}
void ath9k_reg_apply_world_flags(struct wiphy *wiphy, enum reg_set_by setby)
void ath9k_reg_apply_world_flags(struct wiphy *wiphy,
enum nl80211_reg_initiator initiator)
{
struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
struct ath_wiphy *aphy = hw->priv;
@ -320,11 +323,11 @@ void ath9k_reg_apply_world_flags(struct wiphy *wiphy, enum reg_set_by setby)
case 0x63:
case 0x66:
case 0x67:
ath9k_reg_apply_beaconing_flags(wiphy, setby);
ath9k_reg_apply_beaconing_flags(wiphy, initiator);
break;
case 0x68:
ath9k_reg_apply_beaconing_flags(wiphy, setby);
ath9k_reg_apply_active_scan_flags(wiphy, setby);
ath9k_reg_apply_beaconing_flags(wiphy, initiator);
ath9k_reg_apply_active_scan_flags(wiphy, initiator);
break;
}
return;
@ -340,12 +343,11 @@ int ath9k_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request)
ath9k_reg_apply_radar_flags(wiphy);
switch (request->initiator) {
case REGDOM_SET_BY_DRIVER:
case REGDOM_SET_BY_INIT:
case REGDOM_SET_BY_CORE:
case REGDOM_SET_BY_USER:
case NL80211_REGDOM_SET_BY_DRIVER:
case NL80211_REGDOM_SET_BY_CORE:
case NL80211_REGDOM_SET_BY_USER:
break;
case REGDOM_SET_BY_COUNTRY_IE:
case NL80211_REGDOM_SET_BY_COUNTRY_IE:
if (ath9k_is_world_regd(sc->sc_ah))
ath9k_reg_apply_world_flags(wiphy, request->initiator);
break;

View file

@ -236,7 +236,8 @@ enum CountryCode {
bool ath9k_is_world_regd(struct ath_hw *ah);
const struct ieee80211_regdomain *ath9k_world_regdomain(struct ath_hw *ah);
const struct ieee80211_regdomain *ath9k_default_world_regdomain(void);
void ath9k_reg_apply_world_flags(struct wiphy *wiphy, enum reg_set_by setby);
void ath9k_reg_apply_world_flags(struct wiphy *wiphy,
enum nl80211_reg_initiator initiator);
void ath9k_reg_apply_radar_flags(struct wiphy *wiphy);
int ath9k_regd_init(struct ath_hw *ah);
bool ath9k_regd_is_eeprom_valid(struct ath_hw *ah);

View file

@ -55,9 +55,9 @@ static u32 bits_per_symbol[][2] = {
#define IS_HT_RATE(_rate) ((_rate) & 0x80)
static void ath_tx_send_normal(struct ath_softc *sc, struct ath_txq *txq,
struct ath_atx_tid *tid,
struct list_head *bf_head);
static void ath_tx_send_ht_normal(struct ath_softc *sc, struct ath_txq *txq,
struct ath_atx_tid *tid,
struct list_head *bf_head);
static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf,
struct list_head *bf_q,
int txok, int sendbar);
@ -152,7 +152,7 @@ static void ath_tx_flush_tid(struct ath_softc *sc, struct ath_atx_tid *tid)
bf = list_first_entry(&tid->buf_q, struct ath_buf, list);
ASSERT(!bf_isretried(bf));
list_move_tail(&bf->list, &bf_head);
ath_tx_send_normal(sc, txq, tid, &bf_head);
ath_tx_send_ht_normal(sc, txq, tid, &bf_head);
}
spin_unlock_bh(&txq->axq_lock);
@ -891,7 +891,7 @@ struct ath_txq *ath_test_get_txq(struct ath_softc *sc, struct sk_buff *skb)
spin_lock_bh(&txq->axq_lock);
if (txq->axq_depth >= (ATH_TXBUF - 20)) {
DPRINTF(sc, ATH_DBG_FATAL,
DPRINTF(sc, ATH_DBG_XMIT,
"TX queue: %d is full, depth: %d\n",
qnum, txq->axq_depth);
ieee80211_stop_queue(sc->hw, skb_get_queue_mapping(skb));
@ -1238,9 +1238,9 @@ static void ath_tx_send_ampdu(struct ath_softc *sc, struct ath_atx_tid *tid,
ath_tx_txqaddbuf(sc, txctl->txq, bf_head);
}
static void ath_tx_send_normal(struct ath_softc *sc, struct ath_txq *txq,
struct ath_atx_tid *tid,
struct list_head *bf_head)
static void ath_tx_send_ht_normal(struct ath_softc *sc, struct ath_txq *txq,
struct ath_atx_tid *tid,
struct list_head *bf_head)
{
struct ath_buf *bf;
@ -1256,6 +1256,19 @@ static void ath_tx_send_normal(struct ath_softc *sc, struct ath_txq *txq,
ath_tx_txqaddbuf(sc, txq, bf_head);
}
static void ath_tx_send_normal(struct ath_softc *sc, struct ath_txq *txq,
struct list_head *bf_head)
{
struct ath_buf *bf;
bf = list_first_entry(bf_head, struct ath_buf, list);
bf->bf_lastbf = bf;
bf->bf_nframes = 1;
ath_buf_set_rate(sc, bf);
ath_tx_txqaddbuf(sc, txq, bf_head);
}
static enum ath9k_pkt_type get_hw_packet_type(struct sk_buff *skb)
{
struct ieee80211_hdr *hdr;
@ -1522,8 +1535,7 @@ static int ath_tx_setup_buffer(struct ieee80211_hw *hw, struct ath_buf *bf,
bf->bf_frmlen = skb->len + FCS_LEN - (hdrlen & 3);
if ((conf_is_ht(&sc->hw->conf) && !is_pae(skb) &&
(tx_info->flags & IEEE80211_TX_CTL_AMPDU)))
if (conf_is_ht(&sc->hw->conf) && !is_pae(skb))
bf->bf_state.bf_type |= BUF_HT;
bf->bf_flags = setup_tx_flags(sc, skb, txctl->txq);
@ -1560,14 +1572,17 @@ static void ath_tx_start_dma(struct ath_softc *sc, struct ath_buf *bf,
{
struct sk_buff *skb = (struct sk_buff *)bf->bf_mpdu;
struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
struct ath_node *an = NULL;
struct list_head bf_head;
struct ath_desc *ds;
struct ath_atx_tid *tid;
struct ath_hw *ah = sc->sc_ah;
int frm_type;
__le16 fc;
frm_type = get_hw_packet_type(skb);
fc = hdr->frame_control;
INIT_LIST_HEAD(&bf_head);
list_add_tail(&bf->list, &bf_head);
@ -1592,6 +1607,11 @@ static void ath_tx_start_dma(struct ath_softc *sc, struct ath_buf *bf,
an = (struct ath_node *)tx_info->control.sta->drv_priv;
tid = ATH_AN_2_TID(an, bf->bf_tidno);
if (!ieee80211_is_data_qos(fc)) {
ath_tx_send_normal(sc, txctl->txq, &bf_head);
goto tx_done;
}
if (ath_aggr_query(sc, an, bf->bf_tidno)) {
/*
* Try aggregation if it's a unicast data frame
@ -1603,17 +1623,14 @@ static void ath_tx_start_dma(struct ath_softc *sc, struct ath_buf *bf,
* Send this frame as regular when ADDBA
* exchange is neither complete nor pending.
*/
ath_tx_send_normal(sc, txctl->txq,
tid, &bf_head);
ath_tx_send_ht_normal(sc, txctl->txq,
tid, &bf_head);
}
} else {
bf->bf_lastbf = bf;
bf->bf_nframes = 1;
ath_buf_set_rate(sc, bf);
ath_tx_txqaddbuf(sc, txctl->txq, &bf_head);
ath_tx_send_normal(sc, txctl->txq, &bf_head);
}
tx_done:
spin_unlock_bh(&txctl->txq->axq_lock);
}

View file

@ -2,8 +2,8 @@
Driver for Atmel at76c502 at76c504 and at76c506 wireless cards.
Copyright 2000-2001 ATMEL Corporation.
Copyright 2003-2004 Simon Kelley.
Copyright 2000-2001 ATMEL Corporation.
Copyright 2003-2004 Simon Kelley.
This code was developed from version 2.1.1 of the Atmel drivers,
released by Atmel corp. under the GPL in December 2002. It also
@ -89,15 +89,15 @@ static struct {
const char *fw_file;
const char *fw_file_ext;
} fw_table[] = {
{ ATMEL_FW_TYPE_502, "atmel_at76c502", "bin" },
{ ATMEL_FW_TYPE_502D, "atmel_at76c502d", "bin" },
{ ATMEL_FW_TYPE_502E, "atmel_at76c502e", "bin" },
{ ATMEL_FW_TYPE_502_3COM, "atmel_at76c502_3com", "bin" },
{ ATMEL_FW_TYPE_504, "atmel_at76c504", "bin" },
{ ATMEL_FW_TYPE_504_2958, "atmel_at76c504_2958", "bin" },
{ ATMEL_FW_TYPE_504A_2958,"atmel_at76c504a_2958","bin" },
{ ATMEL_FW_TYPE_506, "atmel_at76c506", "bin" },
{ ATMEL_FW_TYPE_NONE, NULL, NULL }
{ ATMEL_FW_TYPE_502, "atmel_at76c502", "bin" },
{ ATMEL_FW_TYPE_502D, "atmel_at76c502d", "bin" },
{ ATMEL_FW_TYPE_502E, "atmel_at76c502e", "bin" },
{ ATMEL_FW_TYPE_502_3COM, "atmel_at76c502_3com", "bin" },
{ ATMEL_FW_TYPE_504, "atmel_at76c504", "bin" },
{ ATMEL_FW_TYPE_504_2958, "atmel_at76c504_2958", "bin" },
{ ATMEL_FW_TYPE_504A_2958, "atmel_at76c504a_2958", "bin" },
{ ATMEL_FW_TYPE_506, "atmel_at76c506", "bin" },
{ ATMEL_FW_TYPE_NONE, NULL, NULL }
};
#define MAX_SSID_LENGTH 32
@ -106,60 +106,60 @@ static struct {
#define MAX_BSS_ENTRIES 64
/* registers */
#define GCR 0x00 // (SIR0) General Configuration Register
#define BSR 0x02 // (SIR1) Bank Switching Select Register
#define GCR 0x00 /* (SIR0) General Configuration Register */
#define BSR 0x02 /* (SIR1) Bank Switching Select Register */
#define AR 0x04
#define DR 0x08
#define MR1 0x12 // Mirror Register 1
#define MR2 0x14 // Mirror Register 2
#define MR3 0x16 // Mirror Register 3
#define MR4 0x18 // Mirror Register 4
#define MR1 0x12 /* Mirror Register 1 */
#define MR2 0x14 /* Mirror Register 2 */
#define MR3 0x16 /* Mirror Register 3 */
#define MR4 0x18 /* Mirror Register 4 */
#define GPR1 0x0c
#define GPR2 0x0e
#define GPR3 0x10
//
// Constants for the GCR register.
//
#define GCR_REMAP 0x0400 // Remap internal SRAM to 0
#define GCR_SWRES 0x0080 // BIU reset (ARM and PAI are NOT reset)
#define GCR_CORES 0x0060 // Core Reset (ARM and PAI are reset)
#define GCR_ENINT 0x0002 // Enable Interrupts
#define GCR_ACKINT 0x0008 // Acknowledge Interrupts
/*
* Constants for the GCR register.
*/
#define GCR_REMAP 0x0400 /* Remap internal SRAM to 0 */
#define GCR_SWRES 0x0080 /* BIU reset (ARM and PAI are NOT reset) */
#define GCR_CORES 0x0060 /* Core Reset (ARM and PAI are reset) */
#define GCR_ENINT 0x0002 /* Enable Interrupts */
#define GCR_ACKINT 0x0008 /* Acknowledge Interrupts */
#define BSS_SRAM 0x0200 // AMBA module selection --> SRAM
#define BSS_IRAM 0x0100 // AMBA module selection --> IRAM
//
// Constants for the MR registers.
//
#define MAC_INIT_COMPLETE 0x0001 // MAC init has been completed
#define MAC_BOOT_COMPLETE 0x0010 // MAC boot has been completed
#define MAC_INIT_OK 0x0002 // MAC boot has been completed
#define BSS_SRAM 0x0200 /* AMBA module selection --> SRAM */
#define BSS_IRAM 0x0100 /* AMBA module selection --> IRAM */
/*
*Constants for the MR registers.
*/
#define MAC_INIT_COMPLETE 0x0001 /* MAC init has been completed */
#define MAC_BOOT_COMPLETE 0x0010 /* MAC boot has been completed */
#define MAC_INIT_OK 0x0002 /* MAC boot has been completed */
#define MIB_MAX_DATA_BYTES 212
#define MIB_HEADER_SIZE 4 /* first four fields */
struct get_set_mib {
u8 type;
u8 size;
u8 index;
u8 reserved;
u8 data[MIB_MAX_DATA_BYTES];
u8 type;
u8 size;
u8 index;
u8 reserved;
u8 data[MIB_MAX_DATA_BYTES];
};
struct rx_desc {
u32 Next;
u16 MsduPos;
u16 MsduSize;
u32 Next;
u16 MsduPos;
u16 MsduSize;
u8 State;
u8 Status;
u8 Rate;
u8 Rssi;
u8 LinkQuality;
u8 PreambleType;
u16 Duration;
u32 RxTime;
u8 State;
u8 Status;
u8 Rate;
u8 Rssi;
u8 LinkQuality;
u8 PreambleType;
u16 Duration;
u32 RxTime;
};
#define RX_DESC_FLAG_VALID 0x80
@ -192,7 +192,7 @@ struct tx_desc {
u8 KeyIndex;
u8 ChiperType;
u8 ChipreLength;
u8 Reserved1;
u8 Reserved1;
u8 Reserved;
u8 PacketType;
@ -212,9 +212,9 @@ struct tx_desc {
#define TX_DESC_PACKET_TYPE_OFFSET 17
#define TX_DESC_HOST_LENGTH_OFFSET 18
///////////////////////////////////////////////////////
// Host-MAC interface
///////////////////////////////////////////////////////
/*
* Host-MAC interface
*/
#define TX_STATUS_SUCCESS 0x00
@ -226,14 +226,14 @@ struct tx_desc {
#define TX_PACKET_TYPE_DATA 0x01
#define TX_PACKET_TYPE_MGMT 0x02
#define ISR_EMPTY 0x00 // no bits set in ISR
#define ISR_TxCOMPLETE 0x01 // packet transmitted
#define ISR_RxCOMPLETE 0x02 // packet received
#define ISR_RxFRAMELOST 0x04 // Rx Frame lost
#define ISR_FATAL_ERROR 0x08 // Fatal error
#define ISR_COMMAND_COMPLETE 0x10 // command completed
#define ISR_OUT_OF_RANGE 0x20 // command completed
#define ISR_IBSS_MERGE 0x40 // (4.1.2.30): IBSS merge
#define ISR_EMPTY 0x00 /* no bits set in ISR */
#define ISR_TxCOMPLETE 0x01 /* packet transmitted */
#define ISR_RxCOMPLETE 0x02 /* packet received */
#define ISR_RxFRAMELOST 0x04 /* Rx Frame lost */
#define ISR_FATAL_ERROR 0x08 /* Fatal error */
#define ISR_COMMAND_COMPLETE 0x10 /* command completed */
#define ISR_OUT_OF_RANGE 0x20 /* command completed */
#define ISR_IBSS_MERGE 0x40 /* (4.1.2.30): IBSS merge */
#define ISR_GENERIC_IRQ 0x80
#define Local_Mib_Type 0x01
@ -311,22 +311,22 @@ struct tx_desc {
#define MAX_ENCRYPTION_KEYS 4
#define MAX_ENCRYPTION_KEY_SIZE 40
///////////////////////////////////////////////////////////////////////////
// 802.11 related definitions
///////////////////////////////////////////////////////////////////////////
/*
* 802.11 related definitions
*/
//
// Regulatory Domains
//
/*
* Regulatory Domains
*/
#define REG_DOMAIN_FCC 0x10 //Channels 1-11 USA
#define REG_DOMAIN_DOC 0x20 //Channel 1-11 Canada
#define REG_DOMAIN_ETSI 0x30 //Channel 1-13 Europe (ex Spain/France)
#define REG_DOMAIN_SPAIN 0x31 //Channel 10-11 Spain
#define REG_DOMAIN_FRANCE 0x32 //Channel 10-13 France
#define REG_DOMAIN_MKK 0x40 //Channel 14 Japan
#define REG_DOMAIN_MKK1 0x41 //Channel 1-14 Japan(MKK1)
#define REG_DOMAIN_ISRAEL 0x50 //Channel 3-9 ISRAEL
#define REG_DOMAIN_FCC 0x10 /* Channels 1-11 USA */
#define REG_DOMAIN_DOC 0x20 /* Channel 1-11 Canada */
#define REG_DOMAIN_ETSI 0x30 /* Channel 1-13 Europe (ex Spain/France) */
#define REG_DOMAIN_SPAIN 0x31 /* Channel 10-11 Spain */
#define REG_DOMAIN_FRANCE 0x32 /* Channel 10-13 France */
#define REG_DOMAIN_MKK 0x40 /* Channel 14 Japan */
#define REG_DOMAIN_MKK1 0x41 /* Channel 1-14 Japan(MKK1) */
#define REG_DOMAIN_ISRAEL 0x50 /* Channel 3-9 ISRAEL */
#define BSS_TYPE_AD_HOC 1
#define BSS_TYPE_INFRASTRUCTURE 2
@ -364,13 +364,13 @@ struct tx_desc {
#define CIPHER_SUITE_CCX 4
#define CIPHER_SUITE_WEP_128 5
//
// IFACE MACROS & definitions
//
//
/*
* IFACE MACROS & definitions
*/
// FuncCtrl field:
//
/*
* FuncCtrl field:
*/
#define FUNC_CTRL_TxENABLE 0x10
#define FUNC_CTRL_RxENABLE 0x20
#define FUNC_CTRL_INIT_COMPLETE 0x01
@ -378,48 +378,48 @@ struct tx_desc {
/* A stub firmware image which reads the MAC address from NVRAM on the card.
For copyright information and source see the end of this file. */
static u8 mac_reader[] = {
0x06,0x00,0x00,0xea,0x04,0x00,0x00,0xea,0x03,0x00,0x00,0xea,0x02,0x00,0x00,0xea,
0x01,0x00,0x00,0xea,0x00,0x00,0x00,0xea,0xff,0xff,0xff,0xea,0xfe,0xff,0xff,0xea,
0xd3,0x00,0xa0,0xe3,0x00,0xf0,0x21,0xe1,0x0e,0x04,0xa0,0xe3,0x00,0x10,0xa0,0xe3,
0x81,0x11,0xa0,0xe1,0x00,0x10,0x81,0xe3,0x00,0x10,0x80,0xe5,0x1c,0x10,0x90,0xe5,
0x10,0x10,0xc1,0xe3,0x1c,0x10,0x80,0xe5,0x01,0x10,0xa0,0xe3,0x08,0x10,0x80,0xe5,
0x02,0x03,0xa0,0xe3,0x00,0x10,0xa0,0xe3,0xb0,0x10,0xc0,0xe1,0xb4,0x10,0xc0,0xe1,
0xb8,0x10,0xc0,0xe1,0xbc,0x10,0xc0,0xe1,0x56,0xdc,0xa0,0xe3,0x21,0x00,0x00,0xeb,
0x0a,0x00,0xa0,0xe3,0x1a,0x00,0x00,0xeb,0x10,0x00,0x00,0xeb,0x07,0x00,0x00,0xeb,
0x02,0x03,0xa0,0xe3,0x02,0x14,0xa0,0xe3,0xb4,0x10,0xc0,0xe1,0x4c,0x10,0x9f,0xe5,
0xbc,0x10,0xc0,0xe1,0x10,0x10,0xa0,0xe3,0xb8,0x10,0xc0,0xe1,0xfe,0xff,0xff,0xea,
0x00,0x40,0x2d,0xe9,0x00,0x20,0xa0,0xe3,0x02,0x3c,0xa0,0xe3,0x00,0x10,0xa0,0xe3,
0x28,0x00,0x9f,0xe5,0x37,0x00,0x00,0xeb,0x00,0x40,0xbd,0xe8,0x1e,0xff,0x2f,0xe1,
0x00,0x40,0x2d,0xe9,0x12,0x2e,0xa0,0xe3,0x06,0x30,0xa0,0xe3,0x00,0x10,0xa0,0xe3,
0x02,0x04,0xa0,0xe3,0x2f,0x00,0x00,0xeb,0x00,0x40,0xbd,0xe8,0x1e,0xff,0x2f,0xe1,
0x00,0x02,0x00,0x02,0x80,0x01,0x90,0xe0,0x01,0x00,0x00,0x0a,0x01,0x00,0x50,0xe2,
0xfc,0xff,0xff,0xea,0x1e,0xff,0x2f,0xe1,0x80,0x10,0xa0,0xe3,0xf3,0x06,0xa0,0xe3,
0x00,0x10,0x80,0xe5,0x00,0x10,0xa0,0xe3,0x00,0x10,0x80,0xe5,0x01,0x10,0xa0,0xe3,
0x04,0x10,0x80,0xe5,0x00,0x10,0x80,0xe5,0x0e,0x34,0xa0,0xe3,0x1c,0x10,0x93,0xe5,
0x02,0x1a,0x81,0xe3,0x1c,0x10,0x83,0xe5,0x58,0x11,0x9f,0xe5,0x30,0x10,0x80,0xe5,
0x54,0x11,0x9f,0xe5,0x34,0x10,0x80,0xe5,0x38,0x10,0x80,0xe5,0x3c,0x10,0x80,0xe5,
0x10,0x10,0x90,0xe5,0x08,0x00,0x90,0xe5,0x1e,0xff,0x2f,0xe1,0xf3,0x16,0xa0,0xe3,
0x08,0x00,0x91,0xe5,0x05,0x00,0xa0,0xe3,0x0c,0x00,0x81,0xe5,0x10,0x00,0x91,0xe5,
0x02,0x00,0x10,0xe3,0xfc,0xff,0xff,0x0a,0xff,0x00,0xa0,0xe3,0x0c,0x00,0x81,0xe5,
0x10,0x00,0x91,0xe5,0x02,0x00,0x10,0xe3,0xfc,0xff,0xff,0x0a,0x08,0x00,0x91,0xe5,
0x10,0x00,0x91,0xe5,0x01,0x00,0x10,0xe3,0xfc,0xff,0xff,0x0a,0x08,0x00,0x91,0xe5,
0xff,0x00,0x00,0xe2,0x1e,0xff,0x2f,0xe1,0x30,0x40,0x2d,0xe9,0x00,0x50,0xa0,0xe1,
0x03,0x40,0xa0,0xe1,0xa2,0x02,0xa0,0xe1,0x08,0x00,0x00,0xe2,0x03,0x00,0x80,0xe2,
0xd8,0x10,0x9f,0xe5,0x00,0x00,0xc1,0xe5,0x01,0x20,0xc1,0xe5,0xe2,0xff,0xff,0xeb,
0x01,0x00,0x10,0xe3,0xfc,0xff,0xff,0x1a,0x14,0x00,0xa0,0xe3,0xc4,0xff,0xff,0xeb,
0x04,0x20,0xa0,0xe1,0x05,0x10,0xa0,0xe1,0x02,0x00,0xa0,0xe3,0x01,0x00,0x00,0xeb,
0x30,0x40,0xbd,0xe8,0x1e,0xff,0x2f,0xe1,0x70,0x40,0x2d,0xe9,0xf3,0x46,0xa0,0xe3,
0x00,0x30,0xa0,0xe3,0x00,0x00,0x50,0xe3,0x08,0x00,0x00,0x9a,0x8c,0x50,0x9f,0xe5,
0x03,0x60,0xd5,0xe7,0x0c,0x60,0x84,0xe5,0x10,0x60,0x94,0xe5,0x02,0x00,0x16,0xe3,
0xfc,0xff,0xff,0x0a,0x01,0x30,0x83,0xe2,0x00,0x00,0x53,0xe1,0xf7,0xff,0xff,0x3a,
0xff,0x30,0xa0,0xe3,0x0c,0x30,0x84,0xe5,0x08,0x00,0x94,0xe5,0x10,0x00,0x94,0xe5,
0x01,0x00,0x10,0xe3,0xfc,0xff,0xff,0x0a,0x08,0x00,0x94,0xe5,0x00,0x00,0xa0,0xe3,
0x00,0x00,0x52,0xe3,0x0b,0x00,0x00,0x9a,0x10,0x50,0x94,0xe5,0x02,0x00,0x15,0xe3,
0xfc,0xff,0xff,0x0a,0x0c,0x30,0x84,0xe5,0x10,0x50,0x94,0xe5,0x01,0x00,0x15,0xe3,
0xfc,0xff,0xff,0x0a,0x08,0x50,0x94,0xe5,0x01,0x50,0xc1,0xe4,0x01,0x00,0x80,0xe2,
0x02,0x00,0x50,0xe1,0xf3,0xff,0xff,0x3a,0xc8,0x00,0xa0,0xe3,0x98,0xff,0xff,0xeb,
0x70,0x40,0xbd,0xe8,0x1e,0xff,0x2f,0xe1,0x01,0x0c,0x00,0x02,0x01,0x02,0x00,0x02,
0x00,0x01,0x00,0x02
0x06, 0x00, 0x00, 0xea, 0x04, 0x00, 0x00, 0xea, 0x03, 0x00, 0x00, 0xea, 0x02, 0x00, 0x00, 0xea,
0x01, 0x00, 0x00, 0xea, 0x00, 0x00, 0x00, 0xea, 0xff, 0xff, 0xff, 0xea, 0xfe, 0xff, 0xff, 0xea,
0xd3, 0x00, 0xa0, 0xe3, 0x00, 0xf0, 0x21, 0xe1, 0x0e, 0x04, 0xa0, 0xe3, 0x00, 0x10, 0xa0, 0xe3,
0x81, 0x11, 0xa0, 0xe1, 0x00, 0x10, 0x81, 0xe3, 0x00, 0x10, 0x80, 0xe5, 0x1c, 0x10, 0x90, 0xe5,
0x10, 0x10, 0xc1, 0xe3, 0x1c, 0x10, 0x80, 0xe5, 0x01, 0x10, 0xa0, 0xe3, 0x08, 0x10, 0x80, 0xe5,
0x02, 0x03, 0xa0, 0xe3, 0x00, 0x10, 0xa0, 0xe3, 0xb0, 0x10, 0xc0, 0xe1, 0xb4, 0x10, 0xc0, 0xe1,
0xb8, 0x10, 0xc0, 0xe1, 0xbc, 0x10, 0xc0, 0xe1, 0x56, 0xdc, 0xa0, 0xe3, 0x21, 0x00, 0x00, 0xeb,
0x0a, 0x00, 0xa0, 0xe3, 0x1a, 0x00, 0x00, 0xeb, 0x10, 0x00, 0x00, 0xeb, 0x07, 0x00, 0x00, 0xeb,
0x02, 0x03, 0xa0, 0xe3, 0x02, 0x14, 0xa0, 0xe3, 0xb4, 0x10, 0xc0, 0xe1, 0x4c, 0x10, 0x9f, 0xe5,
0xbc, 0x10, 0xc0, 0xe1, 0x10, 0x10, 0xa0, 0xe3, 0xb8, 0x10, 0xc0, 0xe1, 0xfe, 0xff, 0xff, 0xea,
0x00, 0x40, 0x2d, 0xe9, 0x00, 0x20, 0xa0, 0xe3, 0x02, 0x3c, 0xa0, 0xe3, 0x00, 0x10, 0xa0, 0xe3,
0x28, 0x00, 0x9f, 0xe5, 0x37, 0x00, 0x00, 0xeb, 0x00, 0x40, 0xbd, 0xe8, 0x1e, 0xff, 0x2f, 0xe1,
0x00, 0x40, 0x2d, 0xe9, 0x12, 0x2e, 0xa0, 0xe3, 0x06, 0x30, 0xa0, 0xe3, 0x00, 0x10, 0xa0, 0xe3,
0x02, 0x04, 0xa0, 0xe3, 0x2f, 0x00, 0x00, 0xeb, 0x00, 0x40, 0xbd, 0xe8, 0x1e, 0xff, 0x2f, 0xe1,
0x00, 0x02, 0x00, 0x02, 0x80, 0x01, 0x90, 0xe0, 0x01, 0x00, 0x00, 0x0a, 0x01, 0x00, 0x50, 0xe2,
0xfc, 0xff, 0xff, 0xea, 0x1e, 0xff, 0x2f, 0xe1, 0x80, 0x10, 0xa0, 0xe3, 0xf3, 0x06, 0xa0, 0xe3,
0x00, 0x10, 0x80, 0xe5, 0x00, 0x10, 0xa0, 0xe3, 0x00, 0x10, 0x80, 0xe5, 0x01, 0x10, 0xa0, 0xe3,
0x04, 0x10, 0x80, 0xe5, 0x00, 0x10, 0x80, 0xe5, 0x0e, 0x34, 0xa0, 0xe3, 0x1c, 0x10, 0x93, 0xe5,
0x02, 0x1a, 0x81, 0xe3, 0x1c, 0x10, 0x83, 0xe5, 0x58, 0x11, 0x9f, 0xe5, 0x30, 0x10, 0x80, 0xe5,
0x54, 0x11, 0x9f, 0xe5, 0x34, 0x10, 0x80, 0xe5, 0x38, 0x10, 0x80, 0xe5, 0x3c, 0x10, 0x80, 0xe5,
0x10, 0x10, 0x90, 0xe5, 0x08, 0x00, 0x90, 0xe5, 0x1e, 0xff, 0x2f, 0xe1, 0xf3, 0x16, 0xa0, 0xe3,
0x08, 0x00, 0x91, 0xe5, 0x05, 0x00, 0xa0, 0xe3, 0x0c, 0x00, 0x81, 0xe5, 0x10, 0x00, 0x91, 0xe5,
0x02, 0x00, 0x10, 0xe3, 0xfc, 0xff, 0xff, 0x0a, 0xff, 0x00, 0xa0, 0xe3, 0x0c, 0x00, 0x81, 0xe5,
0x10, 0x00, 0x91, 0xe5, 0x02, 0x00, 0x10, 0xe3, 0xfc, 0xff, 0xff, 0x0a, 0x08, 0x00, 0x91, 0xe5,
0x10, 0x00, 0x91, 0xe5, 0x01, 0x00, 0x10, 0xe3, 0xfc, 0xff, 0xff, 0x0a, 0x08, 0x00, 0x91, 0xe5,
0xff, 0x00, 0x00, 0xe2, 0x1e, 0xff, 0x2f, 0xe1, 0x30, 0x40, 0x2d, 0xe9, 0x00, 0x50, 0xa0, 0xe1,
0x03, 0x40, 0xa0, 0xe1, 0xa2, 0x02, 0xa0, 0xe1, 0x08, 0x00, 0x00, 0xe2, 0x03, 0x00, 0x80, 0xe2,
0xd8, 0x10, 0x9f, 0xe5, 0x00, 0x00, 0xc1, 0xe5, 0x01, 0x20, 0xc1, 0xe5, 0xe2, 0xff, 0xff, 0xeb,
0x01, 0x00, 0x10, 0xe3, 0xfc, 0xff, 0xff, 0x1a, 0x14, 0x00, 0xa0, 0xe3, 0xc4, 0xff, 0xff, 0xeb,
0x04, 0x20, 0xa0, 0xe1, 0x05, 0x10, 0xa0, 0xe1, 0x02, 0x00, 0xa0, 0xe3, 0x01, 0x00, 0x00, 0xeb,
0x30, 0x40, 0xbd, 0xe8, 0x1e, 0xff, 0x2f, 0xe1, 0x70, 0x40, 0x2d, 0xe9, 0xf3, 0x46, 0xa0, 0xe3,
0x00, 0x30, 0xa0, 0xe3, 0x00, 0x00, 0x50, 0xe3, 0x08, 0x00, 0x00, 0x9a, 0x8c, 0x50, 0x9f, 0xe5,
0x03, 0x60, 0xd5, 0xe7, 0x0c, 0x60, 0x84, 0xe5, 0x10, 0x60, 0x94, 0xe5, 0x02, 0x00, 0x16, 0xe3,
0xfc, 0xff, 0xff, 0x0a, 0x01, 0x30, 0x83, 0xe2, 0x00, 0x00, 0x53, 0xe1, 0xf7, 0xff, 0xff, 0x3a,
0xff, 0x30, 0xa0, 0xe3, 0x0c, 0x30, 0x84, 0xe5, 0x08, 0x00, 0x94, 0xe5, 0x10, 0x00, 0x94, 0xe5,
0x01, 0x00, 0x10, 0xe3, 0xfc, 0xff, 0xff, 0x0a, 0x08, 0x00, 0x94, 0xe5, 0x00, 0x00, 0xa0, 0xe3,
0x00, 0x00, 0x52, 0xe3, 0x0b, 0x00, 0x00, 0x9a, 0x10, 0x50, 0x94, 0xe5, 0x02, 0x00, 0x15, 0xe3,
0xfc, 0xff, 0xff, 0x0a, 0x0c, 0x30, 0x84, 0xe5, 0x10, 0x50, 0x94, 0xe5, 0x01, 0x00, 0x15, 0xe3,
0xfc, 0xff, 0xff, 0x0a, 0x08, 0x50, 0x94, 0xe5, 0x01, 0x50, 0xc1, 0xe4, 0x01, 0x00, 0x80, 0xe2,
0x02, 0x00, 0x50, 0xe1, 0xf3, 0xff, 0xff, 0x3a, 0xc8, 0x00, 0xa0, 0xe3, 0x98, 0xff, 0xff, 0xeb,
0x70, 0x40, 0xbd, 0xe8, 0x1e, 0xff, 0x2f, 0xe1, 0x01, 0x0c, 0x00, 0x02, 0x01, 0x02, 0x00, 0x02,
0x00, 0x01, 0x00, 0x02
};
struct atmel_private {
@ -433,7 +433,7 @@ struct atmel_private {
struct net_device *dev;
struct device *sys_dev;
struct iw_statistics wstats;
spinlock_t irqlock, timerlock; // spinlocks
spinlock_t irqlock, timerlock; /* spinlocks */
enum { BUS_TYPE_PCCARD, BUS_TYPE_PCI } bus_type;
enum {
CARD_TYPE_PARALLEL_FLASH,
@ -541,7 +541,7 @@ struct atmel_private {
u8 rx_buf[MAX_WIRELESS_BODY];
};
static u8 atmel_basic_rates[4] = {0x82,0x84,0x0b,0x16};
static u8 atmel_basic_rates[4] = {0x82, 0x84, 0x0b, 0x16};
static const struct {
int reg_domain;
@ -1283,17 +1283,17 @@ static struct iw_statistics *atmel_get_wireless_stats(struct net_device *dev)
static int atmel_change_mtu(struct net_device *dev, int new_mtu)
{
if ((new_mtu < 68) || (new_mtu > 2312))
return -EINVAL;
dev->mtu = new_mtu;
return 0;
if ((new_mtu < 68) || (new_mtu > 2312))
return -EINVAL;
dev->mtu = new_mtu;
return 0;
}
static int atmel_set_mac_address(struct net_device *dev, void *p)
{
struct sockaddr *addr = p;
memcpy (dev->dev_addr, addr->sa_data, dev->addr_len);
memcpy (dev->dev_addr, addr->sa_data, dev->addr_len);
return atmel_open(dev);
}
@ -1420,10 +1420,17 @@ static int atmel_proc_output (char *buf, struct atmel_private *priv)
priv->firmware_id);
switch (priv->card_type) {
case CARD_TYPE_PARALLEL_FLASH: c = "Parallel flash"; break;
case CARD_TYPE_SPI_FLASH: c = "SPI flash\n"; break;
case CARD_TYPE_EEPROM: c = "EEPROM"; break;
default: c = "<unknown>";
case CARD_TYPE_PARALLEL_FLASH:
c = "Parallel flash";
break;
case CARD_TYPE_SPI_FLASH:
c = "SPI flash\n";
break;
case CARD_TYPE_EEPROM:
c = "EEPROM";
break;
default:
c = "<unknown>";
}
r = "<unknown>";
@ -1439,16 +1446,33 @@ static int atmel_proc_output (char *buf, struct atmel_private *priv)
priv->use_wpa ? "Yes" : "No");
}
switch(priv->station_state) {
case STATION_STATE_SCANNING: s = "Scanning"; break;
case STATION_STATE_JOINNING: s = "Joining"; break;
case STATION_STATE_AUTHENTICATING: s = "Authenticating"; break;
case STATION_STATE_ASSOCIATING: s = "Associating"; break;
case STATION_STATE_READY: s = "Ready"; break;
case STATION_STATE_REASSOCIATING: s = "Reassociating"; break;
case STATION_STATE_MGMT_ERROR: s = "Management error"; break;
case STATION_STATE_DOWN: s = "Down"; break;
default: s = "<unknown>";
switch (priv->station_state) {
case STATION_STATE_SCANNING:
s = "Scanning";
break;
case STATION_STATE_JOINNING:
s = "Joining";
break;
case STATION_STATE_AUTHENTICATING:
s = "Authenticating";
break;
case STATION_STATE_ASSOCIATING:
s = "Associating";
break;
case STATION_STATE_READY:
s = "Ready";
break;
case STATION_STATE_REASSOCIATING:
s = "Reassociating";
break;
case STATION_STATE_MGMT_ERROR:
s = "Management error";
break;
case STATION_STATE_DOWN:
s = "Down";
break;
default:
s = "<unknown>";
}
p += sprintf(p, "Current state:\t\t%s\n", s);
@ -1458,14 +1482,17 @@ static int atmel_proc_output (char *buf, struct atmel_private *priv)
static int atmel_read_proc(char *page, char **start, off_t off,
int count, int *eof, void *data)
{
struct atmel_private *priv = data;
struct atmel_private *priv = data;
int len = atmel_proc_output (page, priv);
if (len <= off+count) *eof = 1;
*start = page + off;
len -= off;
if (len>count) len = count;
if (len<0) len = 0;
return len;
if (len <= off+count)
*eof = 1;
*start = page + off;
len -= off;
if (len > count)
len = count;
if (len < 0)
len = 0;
return len;
}
struct net_device *init_atmel_card(unsigned short irq, unsigned long port,
@ -1479,11 +1506,11 @@ struct net_device *init_atmel_card(unsigned short irq, unsigned long port,
int rc;
/* Create the network device object. */
dev = alloc_etherdev(sizeof(*priv));
if (!dev) {
dev = alloc_etherdev(sizeof(*priv));
if (!dev) {
printk(KERN_ERR "atmel: Couldn't alloc_etherdev\n");
return NULL;
}
}
if (dev_alloc_name(dev, dev->name) < 0) {
printk(KERN_ERR "atmel: Couldn't get name!\n");
goto err_out_free;
@ -1577,7 +1604,7 @@ struct net_device *init_atmel_card(unsigned short irq, unsigned long port,
if (register_netdev(dev))
goto err_out_res;
if (!probe_atmel_card(dev)){
if (!probe_atmel_card(dev)) {
unregister_netdev(dev);
goto err_out_res;
}
@ -1594,7 +1621,7 @@ struct net_device *init_atmel_card(unsigned short irq, unsigned long port,
return dev;
err_out_res:
release_region( dev->base_addr, 32);
release_region(dev->base_addr, 32);
err_out_irq:
free_irq(dev->irq, dev);
err_out_free:
@ -1632,7 +1659,7 @@ static int atmel_set_essid(struct net_device *dev,
struct atmel_private *priv = netdev_priv(dev);
/* Check if we asked for `any' */
if(dwrq->flags == 0) {
if (dwrq->flags == 0) {
priv->connect_to_any_BSS = 1;
} else {
int index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
@ -1768,7 +1795,7 @@ static int atmel_set_encode(struct net_device *dev,
}
if (dwrq->flags & IW_ENCODE_RESTRICTED)
priv->exclude_unencrypted = 1;
if(dwrq->flags & IW_ENCODE_OPEN)
if (dwrq->flags & IW_ENCODE_OPEN)
priv->exclude_unencrypted = 0;
return -EINPROGRESS; /* Call commit handler */
@ -1797,7 +1824,7 @@ static int atmel_get_encode(struct net_device *dev,
/* Copy the key to the user buffer */
dwrq->length = priv->wep_key_len[index];
if (dwrq->length > 16) {
dwrq->length=0;
dwrq->length = 0;
} else {
memset(extra, 0, 16);
memcpy(extra, priv->wep_keys[index], dwrq->length);
@ -2013,11 +2040,20 @@ static int atmel_set_rate(struct net_device *dev,
} else {
/* Setting by frequency value */
switch (vwrq->value) {
case 1000000: priv->tx_rate = 0; break;
case 2000000: priv->tx_rate = 1; break;
case 5500000: priv->tx_rate = 2; break;
case 11000000: priv->tx_rate = 3; break;
default: return -EINVAL;
case 1000000:
priv->tx_rate = 0;
break;
case 2000000:
priv->tx_rate = 1;
break;
case 5500000:
priv->tx_rate = 2;
break;
case 11000000:
priv->tx_rate = 3;
break;
default:
return -EINVAL;
}
}
}
@ -2062,11 +2098,19 @@ static int atmel_get_rate(struct net_device *dev,
vwrq->value = 11000000;
} else {
vwrq->fixed = 1;
switch(priv->tx_rate) {
case 0: vwrq->value = 1000000; break;
case 1: vwrq->value = 2000000; break;
case 2: vwrq->value = 5500000; break;
case 3: vwrq->value = 11000000; break;
switch (priv->tx_rate) {
case 0:
vwrq->value = 1000000;
break;
case 1:
vwrq->value = 2000000;
break;
case 2:
vwrq->value = 5500000;
break;
case 3:
vwrq->value = 11000000;
break;
}
}
return 0;
@ -2576,8 +2620,7 @@ static const struct iw_priv_args atmel_private_args[] = {
},
};
static const struct iw_handler_def atmel_handler_def =
{
static const struct iw_handler_def atmel_handler_def = {
.num_standard = ARRAY_SIZE(atmel_handler),
.num_private = ARRAY_SIZE(atmel_private_handler),
.num_private_args = ARRAY_SIZE(atmel_private_args),
@ -2834,7 +2877,7 @@ static void send_authentication_request(struct atmel_private *priv, u16 system,
if (priv->wep_is_on && priv->CurrentAuthentTransactionSeqNum != 1)
/* no WEP for authentication frames with TrSeqNo 1 */
header.frame_control |= cpu_to_le16(IEEE80211_FCTL_PROTECTED);
header.frame_control |= cpu_to_le16(IEEE80211_FCTL_PROTECTED);
auth.alg = cpu_to_le16(system);
@ -2969,7 +3012,7 @@ static void store_bss_info(struct atmel_private *priv,
if (memcmp(bss, priv->BSSinfo[i].BSSID, 6) == 0)
index = i;
/* If we process a probe and an entry from this BSS exists
/* If we process a probe and an entry from this BSS exists
we will update the BSS entry with the info from this BSS.
If we process a beacon we will only update RSSI */
@ -2995,7 +3038,7 @@ static void store_bss_info(struct atmel_private *priv,
if (capability & WLAN_CAPABILITY_IBSS)
priv->BSSinfo[index].BSStype = IW_MODE_ADHOC;
else if (capability & WLAN_CAPABILITY_ESS)
priv->BSSinfo[index].BSStype =IW_MODE_INFRA;
priv->BSSinfo[index].BSStype = IW_MODE_INFRA;
priv->BSSinfo[index].preamble = capability & WLAN_CAPABILITY_SHORT_PREAMBLE ?
SHORT_PREAMBLE : LONG_PREAMBLE;
@ -3042,7 +3085,7 @@ static void authenticate(struct atmel_private *priv, u16 frame_len)
}
if (should_associate) {
if(priv->station_was_associated) {
if (priv->station_was_associated) {
atmel_enter_state(priv, STATION_STATE_REASSOCIATING);
send_association_request(priv, 1);
return;
@ -3063,8 +3106,8 @@ static void authenticate(struct atmel_private *priv, u16 frame_len)
priv->exclude_unencrypted = 1;
send_authentication_request(priv, WLAN_AUTH_SHARED_KEY, NULL, 0);
return;
} else if ( system == WLAN_AUTH_SHARED_KEY
&& priv->wep_is_on) {
} else if (system == WLAN_AUTH_SHARED_KEY
&& priv->wep_is_on) {
priv->CurrentAuthentTransactionSeqNum = 0x001;
priv->exclude_unencrypted = 0;
send_authentication_request(priv, WLAN_AUTH_OPEN, NULL, 0);
@ -3252,11 +3295,11 @@ static void smooth_rssi(struct atmel_private *priv, u8 rssi)
u8 max_rssi = 42; /* 502-rmfd-revd max by experiment, default for now */
switch (priv->firmware_type) {
case ATMEL_FW_TYPE_502E:
max_rssi = 63; /* 502-rmfd-reve max by experiment */
break;
default:
break;
case ATMEL_FW_TYPE_502E:
max_rssi = 63; /* 502-rmfd-reve max by experiment */
break;
default:
break;
}
rssi = rssi * 100 / max_rssi;
@ -3473,8 +3516,7 @@ static void atmel_command_irq(struct atmel_private *priv)
status == CMD_STATUS_IN_PROGRESS)
return;
switch (command){
switch (command) {
case CMD_Start:
if (status == CMD_STATUS_COMPLETE) {
priv->station_was_associated = priv->station_is_associated;
@ -3709,7 +3751,7 @@ static int probe_atmel_card(struct net_device *dev)
if (rc) {
if (dev->dev_addr[0] == 0xFF) {
u8 default_mac[] = {0x00,0x04, 0x25, 0x00, 0x00, 0x00};
u8 default_mac[] = {0x00, 0x04, 0x25, 0x00, 0x00, 0x00};
printk(KERN_ALERT "%s: *** Invalid MAC address. UPGRADE Firmware ****\n", dev->name);
memcpy(dev->dev_addr, default_mac, 6);
}
@ -3803,7 +3845,7 @@ static void build_wpa_mib(struct atmel_private *priv)
} else {
mib.group_key = i;
priv->group_cipher_suite = priv->pairwise_cipher_suite;
mib.cipher_default_key_value[i][MAX_ENCRYPTION_KEY_SIZE-1] = 1;
mib.cipher_default_key_value[i][MAX_ENCRYPTION_KEY_SIZE-1] = 1;
mib.cipher_default_key_value[i][MAX_ENCRYPTION_KEY_SIZE-2] = priv->group_cipher_suite;
}
}
@ -3913,7 +3955,7 @@ static int reset_atmel_card(struct net_device *dev)
len = fw_entry->size;
}
if (len <= 0x6000) {
if (len <= 0x6000) {
atmel_write16(priv->dev, BSR, BSS_IRAM);
atmel_copy_to_card(priv->dev, 0, fw, len);
atmel_set_gcr(priv->dev, GCR_REMAP);
@ -3942,7 +3984,7 @@ static int reset_atmel_card(struct net_device *dev)
priv->use_wpa = (priv->host_info.major_version == 4);
priv->radio_on_broken = (priv->host_info.major_version == 5);
/* unmask all irq sources */
/* unmask all irq sources */
atmel_wmem8(priv, atmel_hi(priv, IFACE_INT_MASK_OFFSET), 0xff);
/* int Tx system and enable Tx */
@ -3975,7 +4017,7 @@ static int reset_atmel_card(struct net_device *dev)
CMD_STATUS_REJECTED_RADIO_OFF) {
printk(KERN_INFO "%s: cannot turn the radio on.\n",
dev->name);
return -EIO;
return -EIO;
}
}
@ -3999,8 +4041,7 @@ static int reset_atmel_card(struct net_device *dev)
else
build_wep_mib(priv);
if (old_state == STATION_STATE_READY)
{
if (old_state == STATION_STATE_READY) {
union iwreq_data wrqu;
wrqu.data.length = 0;
@ -4277,24 +4318,24 @@ static void atmel_wmem32(struct atmel_private *priv, u16 pos, u32 data)
.set NVRAM_LENGTH, 0x0200
.set MAC_ADDRESS_MIB, SRAM_BASE
.set MAC_ADDRESS_LENGTH, 6
.set MAC_BOOT_FLAG, 0x10
.set MAC_BOOT_FLAG, 0x10
.set MR1, 0
.set MR2, 4
.set MR3, 8
.set MR4, 0xC
RESET_VECTOR:
b RESET_HANDLER
b RESET_HANDLER
UNDEF_VECTOR:
b HALT1
b HALT1
SWI_VECTOR:
b HALT1
b HALT1
IABORT_VECTOR:
b HALT1
b HALT1
DABORT_VECTOR:
RESERVED_VECTOR:
b HALT1
b HALT1
IRQ_VECTOR:
b HALT1
b HALT1
FIQ_VECTOR:
b HALT1
HALT1: b HALT1
@ -4306,7 +4347,7 @@ RESET_HANDLER:
ldr r0, =SPI_CGEN_BASE
mov r1, #0
mov r1, r1, lsl #3
orr r1,r1, #0
orr r1, r1, #0
str r1, [r0]
ldr r1, [r0, #28]
bic r1, r1, #16

View file

@ -54,65 +54,12 @@
#define MIN_FRAG_THRESHOLD 256U
#define MAX_FRAG_THRESHOLD 2346U
/* Frame control field constants */
#define IEEE80211_FCTL_VERS 0x0003
#define IEEE80211_FCTL_FTYPE 0x000c
#define IEEE80211_FCTL_STYPE 0x00f0
#define IEEE80211_FCTL_TODS 0x0100
#define IEEE80211_FCTL_FROMDS 0x0200
#define IEEE80211_FCTL_MOREFRAGS 0x0400
#define IEEE80211_FCTL_RETRY 0x0800
#define IEEE80211_FCTL_PM 0x1000
#define IEEE80211_FCTL_MOREDATA 0x2000
#define IEEE80211_FCTL_PROTECTED 0x4000
#define IEEE80211_FCTL_ORDER 0x8000
#define IEEE80211_FTYPE_MGMT 0x0000
#define IEEE80211_FTYPE_CTL 0x0004
#define IEEE80211_FTYPE_DATA 0x0008
/* management */
#define IEEE80211_STYPE_ASSOC_REQ 0x0000
#define IEEE80211_STYPE_ASSOC_RESP 0x0010
#define IEEE80211_STYPE_REASSOC_REQ 0x0020
#define IEEE80211_STYPE_REASSOC_RESP 0x0030
#define IEEE80211_STYPE_PROBE_REQ 0x0040
#define IEEE80211_STYPE_PROBE_RESP 0x0050
#define IEEE80211_STYPE_BEACON 0x0080
#define IEEE80211_STYPE_ATIM 0x0090
#define IEEE80211_STYPE_DISASSOC 0x00A0
#define IEEE80211_STYPE_AUTH 0x00B0
#define IEEE80211_STYPE_DEAUTH 0x00C0
#define IEEE80211_STYPE_ACTION 0x00D0
/* control */
#define IEEE80211_STYPE_PSPOLL 0x00A0
#define IEEE80211_STYPE_RTS 0x00B0
#define IEEE80211_STYPE_CTS 0x00C0
#define IEEE80211_STYPE_ACK 0x00D0
#define IEEE80211_STYPE_CFEND 0x00E0
#define IEEE80211_STYPE_CFENDACK 0x00F0
/* data */
#define IEEE80211_STYPE_DATA 0x0000
#define IEEE80211_STYPE_DATA_CFACK 0x0010
#define IEEE80211_STYPE_DATA_CFPOLL 0x0020
#define IEEE80211_STYPE_DATA_CFACKPOLL 0x0030
#define IEEE80211_STYPE_NULLFUNC 0x0040
#define IEEE80211_STYPE_CFACK 0x0050
#define IEEE80211_STYPE_CFPOLL 0x0060
#define IEEE80211_STYPE_CFACKPOLL 0x0070
#define IEEE80211_STYPE_QOS_DATA 0x0080
#define IEEE80211_SCTL_FRAG 0x000F
#define IEEE80211_SCTL_SEQ 0xFFF0
/* QOS control */
#define IEEE80211_QCTL_TID 0x000F
/* debug macros */
#ifdef CONFIG_IEEE80211_DEBUG
#ifdef CONFIG_LIBIPW_DEBUG
extern u32 ieee80211_debug_level;
#define IEEE80211_DEBUG(level, fmt, args...) \
do { if (ieee80211_debug_level & (level)) \
@ -128,7 +75,7 @@ static inline bool ieee80211_ratelimit_debug(u32 level)
{
return false;
}
#endif /* CONFIG_IEEE80211_DEBUG */
#endif /* CONFIG_LIBIPW_DEBUG */
/*
* To use the debug system:
@ -152,7 +99,7 @@ static inline bool ieee80211_ratelimit_debug(u32 level)
* you simply need to add your entry to the ieee80211_debug_level array.
*
* If you do not see debug_level in /proc/net/ieee80211 then you do not have
* CONFIG_IEEE80211_DEBUG defined in your kernel configuration
* CONFIG_LIBIPW_DEBUG defined in your kernel configuration
*
*/
@ -217,23 +164,6 @@ struct ieee80211_snap_hdr {
#define WLAN_GET_SEQ_FRAG(seq) ((seq) & IEEE80211_SCTL_FRAG)
#define WLAN_GET_SEQ_SEQ(seq) (((seq) & IEEE80211_SCTL_SEQ) >> 4)
/* Action categories - 802.11h */
enum ieee80211_actioncategories {
WLAN_ACTION_SPECTRUM_MGMT = 0,
/* Reserved 1-127 */
/* Error 128-255 */
};
/* Action details - 802.11h */
enum ieee80211_actiondetails {
WLAN_ACTION_CATEGORY_MEASURE_REQUEST = 0,
WLAN_ACTION_CATEGORY_MEASURE_REPORT = 1,
WLAN_ACTION_CATEGORY_TPC_REQUEST = 2,
WLAN_ACTION_CATEGORY_TPC_REPORT = 3,
WLAN_ACTION_CATEGORY_CHANNEL_SWITCH = 4,
/* 5 - 255 Reserved */
};
#define IEEE80211_STATMASK_SIGNAL (1<<0)
#define IEEE80211_STATMASK_RSSI (1<<1)
#define IEEE80211_STATMASK_NOISE (1<<2)
@ -411,37 +341,6 @@ Total: 28-2340 bytes
#define BEACON_PROBE_SSID_ID_POSITION 12
/* Management Frame Information Element Types */
enum ieee80211_mfie {
MFIE_TYPE_SSID = 0,
MFIE_TYPE_RATES = 1,
MFIE_TYPE_FH_SET = 2,
MFIE_TYPE_DS_SET = 3,
MFIE_TYPE_CF_SET = 4,
MFIE_TYPE_TIM = 5,
MFIE_TYPE_IBSS_SET = 6,
MFIE_TYPE_COUNTRY = 7,
MFIE_TYPE_HOP_PARAMS = 8,
MFIE_TYPE_HOP_TABLE = 9,
MFIE_TYPE_REQUEST = 10,
MFIE_TYPE_CHALLENGE = 16,
MFIE_TYPE_POWER_CONSTRAINT = 32,
MFIE_TYPE_POWER_CAPABILITY = 33,
MFIE_TYPE_TPC_REQUEST = 34,
MFIE_TYPE_TPC_REPORT = 35,
MFIE_TYPE_SUPP_CHANNELS = 36,
MFIE_TYPE_CSA = 37,
MFIE_TYPE_MEASURE_REQUEST = 38,
MFIE_TYPE_MEASURE_REPORT = 39,
MFIE_TYPE_QUIET = 40,
MFIE_TYPE_IBSS_DFS = 41,
MFIE_TYPE_ERP_INFO = 42,
MFIE_TYPE_RSN = 48,
MFIE_TYPE_RATES_EX = 50,
MFIE_TYPE_GENERIC = 221,
MFIE_TYPE_QOS_PARAMETER = 222,
};
struct ieee80211_hdr_1addr {
__le16 frame_ctl;
__le16 duration_id;

View file

@ -221,7 +221,7 @@ void free_ieee80211(struct net_device *dev)
free_netdev(dev);
}
#ifdef CONFIG_IEEE80211_DEBUG
#ifdef CONFIG_LIBIPW_DEBUG
static int debug = 0;
u32 ieee80211_debug_level = 0;
@ -252,11 +252,11 @@ static int store_debug_level(struct file *file, const char __user * buffer,
return strnlen(buf, len);
}
#endif /* CONFIG_IEEE80211_DEBUG */
#endif /* CONFIG_LIBIPW_DEBUG */
static int __init ieee80211_init(void)
{
#ifdef CONFIG_IEEE80211_DEBUG
#ifdef CONFIG_LIBIPW_DEBUG
struct proc_dir_entry *e;
ieee80211_debug_level = debug;
@ -276,7 +276,7 @@ static int __init ieee80211_init(void)
e->read_proc = show_debug_level;
e->write_proc = store_debug_level;
e->data = NULL;
#endif /* CONFIG_IEEE80211_DEBUG */
#endif /* CONFIG_LIBIPW_DEBUG */
printk(KERN_INFO DRV_NAME ": " DRV_DESCRIPTION ", " DRV_VERSION "\n");
printk(KERN_INFO DRV_NAME ": " DRV_COPYRIGHT "\n");
@ -286,20 +286,20 @@ static int __init ieee80211_init(void)
static void __exit ieee80211_exit(void)
{
#ifdef CONFIG_IEEE80211_DEBUG
#ifdef CONFIG_LIBIPW_DEBUG
if (ieee80211_proc) {
remove_proc_entry("debug_level", ieee80211_proc);
remove_proc_entry(DRV_NAME, init_net.proc_net);
ieee80211_proc = NULL;
}
#endif /* CONFIG_IEEE80211_DEBUG */
#endif /* CONFIG_LIBIPW_DEBUG */
}
#ifdef CONFIG_IEEE80211_DEBUG
#ifdef CONFIG_LIBIPW_DEBUG
#include <linux/moduleparam.h>
module_param(debug, int, 0444);
MODULE_PARM_DESC(debug, "debug output mask");
#endif /* CONFIG_IEEE80211_DEBUG */
#endif /* CONFIG_LIBIPW_DEBUG */
module_exit(ieee80211_exit);
module_init(ieee80211_init);

View file

@ -1080,37 +1080,37 @@ static int ieee80211_parse_qos_info_param_IE(struct ieee80211_info_element
return rc;
}
#ifdef CONFIG_IEEE80211_DEBUG
#define MFIE_STRING(x) case MFIE_TYPE_ ##x: return #x
#ifdef CONFIG_LIBIPW_DEBUG
#define MFIE_STRING(x) case WLAN_EID_ ##x: return #x
static const char *get_info_element_string(u16 id)
{
switch (id) {
MFIE_STRING(SSID);
MFIE_STRING(RATES);
MFIE_STRING(FH_SET);
MFIE_STRING(DS_SET);
MFIE_STRING(CF_SET);
MFIE_STRING(SUPP_RATES);
MFIE_STRING(FH_PARAMS);
MFIE_STRING(DS_PARAMS);
MFIE_STRING(CF_PARAMS);
MFIE_STRING(TIM);
MFIE_STRING(IBSS_SET);
MFIE_STRING(IBSS_PARAMS);
MFIE_STRING(COUNTRY);
MFIE_STRING(HOP_PARAMS);
MFIE_STRING(HOP_TABLE);
MFIE_STRING(HP_PARAMS);
MFIE_STRING(HP_TABLE);
MFIE_STRING(REQUEST);
MFIE_STRING(CHALLENGE);
MFIE_STRING(POWER_CONSTRAINT);
MFIE_STRING(POWER_CAPABILITY);
MFIE_STRING(PWR_CONSTRAINT);
MFIE_STRING(PWR_CAPABILITY);
MFIE_STRING(TPC_REQUEST);
MFIE_STRING(TPC_REPORT);
MFIE_STRING(SUPP_CHANNELS);
MFIE_STRING(CSA);
MFIE_STRING(SUPPORTED_CHANNELS);
MFIE_STRING(CHANNEL_SWITCH);
MFIE_STRING(MEASURE_REQUEST);
MFIE_STRING(MEASURE_REPORT);
MFIE_STRING(QUIET);
MFIE_STRING(IBSS_DFS);
MFIE_STRING(ERP_INFO);
MFIE_STRING(RSN);
MFIE_STRING(RATES_EX);
MFIE_STRING(EXT_SUPP_RATES);
MFIE_STRING(GENERIC);
MFIE_STRING(QOS_PARAMETER);
default:
@ -1125,7 +1125,7 @@ static int ieee80211_parse_info_param(struct ieee80211_info_element
{
DECLARE_SSID_BUF(ssid);
u8 i;
#ifdef CONFIG_IEEE80211_DEBUG
#ifdef CONFIG_LIBIPW_DEBUG
char rates_str[64];
char *p;
#endif
@ -1145,7 +1145,7 @@ static int ieee80211_parse_info_param(struct ieee80211_info_element
}
switch (info_element->id) {
case MFIE_TYPE_SSID:
case WLAN_EID_SSID:
network->ssid_len = min(info_element->len,
(u8) IW_ESSID_MAX_SIZE);
memcpy(network->ssid, info_element->data,
@ -1154,21 +1154,21 @@ static int ieee80211_parse_info_param(struct ieee80211_info_element
memset(network->ssid + network->ssid_len, 0,
IW_ESSID_MAX_SIZE - network->ssid_len);
IEEE80211_DEBUG_MGMT("MFIE_TYPE_SSID: '%s' len=%d.\n",
IEEE80211_DEBUG_MGMT("WLAN_EID_SSID: '%s' len=%d.\n",
print_ssid(ssid, network->ssid,
network->ssid_len),
network->ssid_len);
break;
case MFIE_TYPE_RATES:
#ifdef CONFIG_IEEE80211_DEBUG
case WLAN_EID_SUPP_RATES:
#ifdef CONFIG_LIBIPW_DEBUG
p = rates_str;
#endif
network->rates_len = min(info_element->len,
MAX_RATES_LENGTH);
for (i = 0; i < network->rates_len; i++) {
network->rates[i] = info_element->data[i];
#ifdef CONFIG_IEEE80211_DEBUG
#ifdef CONFIG_LIBIPW_DEBUG
p += snprintf(p, sizeof(rates_str) -
(p - rates_str), "%02X ",
network->rates[i]);
@ -1183,19 +1183,19 @@ static int ieee80211_parse_info_param(struct ieee80211_info_element
}
}
IEEE80211_DEBUG_MGMT("MFIE_TYPE_RATES: '%s' (%d)\n",
IEEE80211_DEBUG_MGMT("WLAN_EID_SUPP_RATES: '%s' (%d)\n",
rates_str, network->rates_len);
break;
case MFIE_TYPE_RATES_EX:
#ifdef CONFIG_IEEE80211_DEBUG
case WLAN_EID_EXT_SUPP_RATES:
#ifdef CONFIG_LIBIPW_DEBUG
p = rates_str;
#endif
network->rates_ex_len = min(info_element->len,
MAX_RATES_EX_LENGTH);
for (i = 0; i < network->rates_ex_len; i++) {
network->rates_ex[i] = info_element->data[i];
#ifdef CONFIG_IEEE80211_DEBUG
#ifdef CONFIG_LIBIPW_DEBUG
p += snprintf(p, sizeof(rates_str) -
(p - rates_str), "%02X ",
network->rates[i]);
@ -1210,49 +1210,49 @@ static int ieee80211_parse_info_param(struct ieee80211_info_element
}
}
IEEE80211_DEBUG_MGMT("MFIE_TYPE_RATES_EX: '%s' (%d)\n",
IEEE80211_DEBUG_MGMT("WLAN_EID_EXT_SUPP_RATES: '%s' (%d)\n",
rates_str, network->rates_ex_len);
break;
case MFIE_TYPE_DS_SET:
IEEE80211_DEBUG_MGMT("MFIE_TYPE_DS_SET: %d\n",
case WLAN_EID_DS_PARAMS:
IEEE80211_DEBUG_MGMT("WLAN_EID_DS_PARAMS: %d\n",
info_element->data[0]);
network->channel = info_element->data[0];
break;
case MFIE_TYPE_FH_SET:
IEEE80211_DEBUG_MGMT("MFIE_TYPE_FH_SET: ignored\n");
case WLAN_EID_FH_PARAMS:
IEEE80211_DEBUG_MGMT("WLAN_EID_FH_PARAMS: ignored\n");
break;
case MFIE_TYPE_CF_SET:
IEEE80211_DEBUG_MGMT("MFIE_TYPE_CF_SET: ignored\n");
case WLAN_EID_CF_PARAMS:
IEEE80211_DEBUG_MGMT("WLAN_EID_CF_PARAMS: ignored\n");
break;
case MFIE_TYPE_TIM:
case WLAN_EID_TIM:
network->tim.tim_count = info_element->data[0];
network->tim.tim_period = info_element->data[1];
IEEE80211_DEBUG_MGMT("MFIE_TYPE_TIM: partially ignored\n");
IEEE80211_DEBUG_MGMT("WLAN_EID_TIM: partially ignored\n");
break;
case MFIE_TYPE_ERP_INFO:
case WLAN_EID_ERP_INFO:
network->erp_value = info_element->data[0];
network->flags |= NETWORK_HAS_ERP_VALUE;
IEEE80211_DEBUG_MGMT("MFIE_TYPE_ERP_SET: %d\n",
network->erp_value);
break;
case MFIE_TYPE_IBSS_SET:
case WLAN_EID_IBSS_PARAMS:
network->atim_window = info_element->data[0];
IEEE80211_DEBUG_MGMT("MFIE_TYPE_IBSS_SET: %d\n",
IEEE80211_DEBUG_MGMT("WLAN_EID_IBSS_PARAMS: %d\n",
network->atim_window);
break;
case MFIE_TYPE_CHALLENGE:
IEEE80211_DEBUG_MGMT("MFIE_TYPE_CHALLENGE: ignored\n");
case WLAN_EID_CHALLENGE:
IEEE80211_DEBUG_MGMT("WLAN_EID_CHALLENGE: ignored\n");
break;
case MFIE_TYPE_GENERIC:
IEEE80211_DEBUG_MGMT("MFIE_TYPE_GENERIC: %d bytes\n",
case WLAN_EID_GENERIC:
IEEE80211_DEBUG_MGMT("WLAN_EID_GENERIC: %d bytes\n",
info_element->len);
if (!ieee80211_parse_qos_info_param_IE(info_element,
network))
@ -1270,8 +1270,8 @@ static int ieee80211_parse_info_param(struct ieee80211_info_element
}
break;
case MFIE_TYPE_RSN:
IEEE80211_DEBUG_MGMT("MFIE_TYPE_RSN: %d bytes\n",
case WLAN_EID_RSN:
IEEE80211_DEBUG_MGMT("WLAN_EID_RSN: %d bytes\n",
info_element->len);
network->rsn_ie_len = min(info_element->len + 2,
MAX_WPA_IE_LEN);
@ -1279,22 +1279,22 @@ static int ieee80211_parse_info_param(struct ieee80211_info_element
network->rsn_ie_len);
break;
case MFIE_TYPE_QOS_PARAMETER:
case WLAN_EID_QOS_PARAMETER:
printk(KERN_ERR
"QoS Error need to parse QOS_PARAMETER IE\n");
break;
/* 802.11h */
case MFIE_TYPE_POWER_CONSTRAINT:
case WLAN_EID_PWR_CONSTRAINT:
network->power_constraint = info_element->data[0];
network->flags |= NETWORK_HAS_POWER_CONSTRAINT;
break;
case MFIE_TYPE_CSA:
case WLAN_EID_CHANNEL_SWITCH:
network->power_constraint = info_element->data[0];
network->flags |= NETWORK_HAS_CSA;
break;
case MFIE_TYPE_QUIET:
case WLAN_EID_QUIET:
network->quiet.count = info_element->data[0];
network->quiet.period = info_element->data[1];
network->quiet.duration = info_element->data[2];
@ -1302,7 +1302,7 @@ static int ieee80211_parse_info_param(struct ieee80211_info_element
network->flags |= NETWORK_HAS_QUIET;
break;
case MFIE_TYPE_IBSS_DFS:
case WLAN_EID_IBSS_DFS:
if (network->ibss_dfs)
break;
network->ibss_dfs = kmemdup(info_element->data,
@ -1313,7 +1313,7 @@ static int ieee80211_parse_info_param(struct ieee80211_info_element
network->flags |= NETWORK_HAS_IBSS_DFS;
break;
case MFIE_TYPE_TPC_REPORT:
case WLAN_EID_TPC_REPORT:
network->tpc_report.transmit_power =
info_element->data[0];
network->tpc_report.link_margin = info_element->data[1];
@ -1562,7 +1562,7 @@ static void ieee80211_process_probe_response(struct ieee80211_device
};
struct ieee80211_network *target;
struct ieee80211_network *oldest = NULL;
#ifdef CONFIG_IEEE80211_DEBUG
#ifdef CONFIG_LIBIPW_DEBUG
struct ieee80211_info_element *info_element = beacon->info_element;
#endif
unsigned long flags;
@ -1640,7 +1640,7 @@ static void ieee80211_process_probe_response(struct ieee80211_device
list_del(ieee->network_free_list.next);
}
#ifdef CONFIG_IEEE80211_DEBUG
#ifdef CONFIG_LIBIPW_DEBUG
IEEE80211_DEBUG_SCAN("Adding '%s' (%pM) via %s.\n",
print_ssid(ssid, network.ssid,
network.ssid_len),

View file

@ -6,11 +6,9 @@ config IWLWIFI
select MAC80211_LEDS if IWLWIFI_LEDS
select LEDS_CLASS if IWLWIFI_LEDS
select RFKILL if IWLWIFI_RFKILL
select MAC80211_LEDS if IWL3945_LEDS
select LEDS_CLASS if IWL3945_LEDS
config IWLWIFI_LEDS
bool "Enable LED support in iwlagn driver"
bool "Enable LED support in iwlagn and iwl3945 drivers"
depends on IWLWIFI
config IWLWIFI_RFKILL
@ -87,7 +85,7 @@ config IWL4965
This option enables support for Intel Wireless WiFi Link 4965AGN
config IWL5000
bool "Intel Wireless WiFi 5000AGN; Intel WiFi Link 100, 6000, and 6050 Series"
bool "Intel Wireless WiFi 5000AGN; Intel WiFi Link 1000, 6000, and 6050 Series"
depends on IWLAGN
---help---
This option enables support for Intel Wireless WiFi Link 5000AGN Family
@ -122,9 +120,3 @@ config IWL3945_SPECTRUM_MEASUREMENT
depends on IWL3945
---help---
This option will enable spectrum measurement for the iwl3945 driver.
config IWL3945_LEDS
bool "Enable LEDS features in iwl3945 driver"
depends on IWL3945
---help---
This option enables LEDS for the iwl3945 driver.

View file

@ -13,10 +13,9 @@ iwlagn-objs := iwl-agn.o iwl-agn-rs.o
iwlagn-$(CONFIG_IWL4965) += iwl-4965.o
iwlagn-$(CONFIG_IWL5000) += iwl-5000.o
iwlagn-$(CONFIG_IWL5000) += iwl-6000.o
iwlagn-$(CONFIG_IWL5000) += iwl-100.o
iwlagn-$(CONFIG_IWL5000) += iwl-1000.o
obj-$(CONFIG_IWL3945) += iwl3945.o
iwl3945-objs := iwl3945-base.o iwl-3945.o iwl-3945-rs.o
iwl3945-$(CONFIG_IWL3945_LEDS) += iwl-3945-led.o
iwl3945-objs := iwl3945-base.o iwl-3945.o iwl-3945-rs.o iwl-3945-led.o

View file

@ -46,20 +46,20 @@
#include "iwl-5000-hw.h"
/* Highest firmware API version supported */
#define IWL100_UCODE_API_MAX 2
#define IWL1000_UCODE_API_MAX 2
/* Lowest firmware API version supported */
#define IWL100_UCODE_API_MIN 1
#define IWL1000_UCODE_API_MIN 1
#define IWL100_FW_PRE "iwlwifi-100-"
#define _IWL100_MODULE_FIRMWARE(api) IWL100_FW_PRE #api ".ucode"
#define IWL100_MODULE_FIRMWARE(api) _IWL100_MODULE_FIRMWARE(api)
#define IWL1000_FW_PRE "iwlwifi-1000-"
#define _IWL1000_MODULE_FIRMWARE(api) IWL1000_FW_PRE #api ".ucode"
#define IWL1000_MODULE_FIRMWARE(api) _IWL1000_MODULE_FIRMWARE(api)
struct iwl_cfg iwl100_bgn_cfg = {
.name = "100 Series BGN",
.fw_name_pre = IWL100_FW_PRE,
.ucode_api_max = IWL100_UCODE_API_MAX,
.ucode_api_min = IWL100_UCODE_API_MIN,
struct iwl_cfg iwl1000_bgn_cfg = {
.name = "1000 Series BGN",
.fw_name_pre = IWL1000_FW_PRE,
.ucode_api_max = IWL1000_UCODE_API_MAX,
.ucode_api_min = IWL1000_UCODE_API_MIN,
.sku = IWL_SKU_G|IWL_SKU_N,
.ops = &iwl5000_ops,
.eeprom_size = IWL_5000_EEPROM_IMG_SIZE,

View file

@ -24,6 +24,7 @@
*
*****************************************************************************/
#ifdef CONFIG_IWLWIFI_LEDS
#include <linux/kernel.h>
#include <linux/module.h>
@ -163,8 +164,8 @@ static int iwl3945_led_associated(struct iwl_priv *priv, int led_id)
static void iwl3945_led_brightness_set(struct led_classdev *led_cdev,
enum led_brightness brightness)
{
struct iwl3945_led *led = container_of(led_cdev,
struct iwl3945_led, led_dev);
struct iwl_led *led = container_of(led_cdev,
struct iwl_led, led_dev);
struct iwl_priv *priv = led->priv;
if (test_bit(STATUS_EXIT_PENDING, &priv->status))
@ -202,7 +203,7 @@ static void iwl3945_led_brightness_set(struct led_classdev *led_cdev,
* Register led class with the system
*/
static int iwl3945_led_register_led(struct iwl_priv *priv,
struct iwl3945_led *led,
struct iwl_led *led,
enum led_type type, u8 set_led,
char *trigger)
{
@ -315,66 +316,66 @@ int iwl3945_led_register(struct iwl_priv *priv)
priv->allow_blinking = 0;
trigger = ieee80211_get_radio_led_name(priv->hw);
snprintf(priv->led39[IWL_LED_TRG_RADIO].name,
sizeof(priv->led39[IWL_LED_TRG_RADIO].name), "iwl-%s::radio",
snprintf(priv->led[IWL_LED_TRG_RADIO].name,
sizeof(priv->led[IWL_LED_TRG_RADIO].name), "iwl-%s::radio",
wiphy_name(priv->hw->wiphy));
priv->led39[IWL_LED_TRG_RADIO].led_on = iwl3945_led_on;
priv->led39[IWL_LED_TRG_RADIO].led_off = iwl3945_led_off;
priv->led39[IWL_LED_TRG_RADIO].led_pattern = NULL;
priv->led[IWL_LED_TRG_RADIO].led_on = iwl3945_led_on;
priv->led[IWL_LED_TRG_RADIO].led_off = iwl3945_led_off;
priv->led[IWL_LED_TRG_RADIO].led_pattern = NULL;
ret = iwl3945_led_register_led(priv,
&priv->led39[IWL_LED_TRG_RADIO],
&priv->led[IWL_LED_TRG_RADIO],
IWL_LED_TRG_RADIO, 1, trigger);
if (ret)
goto exit_fail;
trigger = ieee80211_get_assoc_led_name(priv->hw);
snprintf(priv->led39[IWL_LED_TRG_ASSOC].name,
sizeof(priv->led39[IWL_LED_TRG_ASSOC].name), "iwl-%s::assoc",
snprintf(priv->led[IWL_LED_TRG_ASSOC].name,
sizeof(priv->led[IWL_LED_TRG_ASSOC].name), "iwl-%s::assoc",
wiphy_name(priv->hw->wiphy));
ret = iwl3945_led_register_led(priv,
&priv->led39[IWL_LED_TRG_ASSOC],
&priv->led[IWL_LED_TRG_ASSOC],
IWL_LED_TRG_ASSOC, 0, trigger);
/* for assoc always turn led on */
priv->led39[IWL_LED_TRG_ASSOC].led_on = iwl3945_led_on;
priv->led39[IWL_LED_TRG_ASSOC].led_off = iwl3945_led_on;
priv->led39[IWL_LED_TRG_ASSOC].led_pattern = NULL;
priv->led[IWL_LED_TRG_ASSOC].led_on = iwl3945_led_on;
priv->led[IWL_LED_TRG_ASSOC].led_off = iwl3945_led_on;
priv->led[IWL_LED_TRG_ASSOC].led_pattern = NULL;
if (ret)
goto exit_fail;
trigger = ieee80211_get_rx_led_name(priv->hw);
snprintf(priv->led39[IWL_LED_TRG_RX].name,
sizeof(priv->led39[IWL_LED_TRG_RX].name), "iwl-%s::RX",
snprintf(priv->led[IWL_LED_TRG_RX].name,
sizeof(priv->led[IWL_LED_TRG_RX].name), "iwl-%s::RX",
wiphy_name(priv->hw->wiphy));
ret = iwl3945_led_register_led(priv,
&priv->led39[IWL_LED_TRG_RX],
&priv->led[IWL_LED_TRG_RX],
IWL_LED_TRG_RX, 0, trigger);
priv->led39[IWL_LED_TRG_RX].led_on = iwl3945_led_associated;
priv->led39[IWL_LED_TRG_RX].led_off = iwl3945_led_associated;
priv->led39[IWL_LED_TRG_RX].led_pattern = iwl3945_led_pattern;
priv->led[IWL_LED_TRG_RX].led_on = iwl3945_led_associated;
priv->led[IWL_LED_TRG_RX].led_off = iwl3945_led_associated;
priv->led[IWL_LED_TRG_RX].led_pattern = iwl3945_led_pattern;
if (ret)
goto exit_fail;
trigger = ieee80211_get_tx_led_name(priv->hw);
snprintf(priv->led39[IWL_LED_TRG_TX].name,
sizeof(priv->led39[IWL_LED_TRG_TX].name), "iwl-%s::TX",
snprintf(priv->led[IWL_LED_TRG_TX].name,
sizeof(priv->led[IWL_LED_TRG_TX].name), "iwl-%s::TX",
wiphy_name(priv->hw->wiphy));
ret = iwl3945_led_register_led(priv,
&priv->led39[IWL_LED_TRG_TX],
&priv->led[IWL_LED_TRG_TX],
IWL_LED_TRG_TX, 0, trigger);
priv->led39[IWL_LED_TRG_TX].led_on = iwl3945_led_associated;
priv->led39[IWL_LED_TRG_TX].led_off = iwl3945_led_associated;
priv->led39[IWL_LED_TRG_TX].led_pattern = iwl3945_led_pattern;
priv->led[IWL_LED_TRG_TX].led_on = iwl3945_led_associated;
priv->led[IWL_LED_TRG_TX].led_off = iwl3945_led_associated;
priv->led[IWL_LED_TRG_TX].led_pattern = iwl3945_led_pattern;
if (ret)
goto exit_fail;
@ -388,7 +389,7 @@ exit_fail:
/* unregister led class */
static void iwl3945_led_unregister_led(struct iwl3945_led *led, u8 set_led)
static void iwl3945_led_unregister_led(struct iwl_led *led, u8 set_led)
{
if (!led->registered)
return;
@ -403,9 +404,10 @@ static void iwl3945_led_unregister_led(struct iwl3945_led *led, u8 set_led)
/* Unregister all led handlers */
void iwl3945_led_unregister(struct iwl_priv *priv)
{
iwl3945_led_unregister_led(&priv->led39[IWL_LED_TRG_ASSOC], 0);
iwl3945_led_unregister_led(&priv->led39[IWL_LED_TRG_RX], 0);
iwl3945_led_unregister_led(&priv->led39[IWL_LED_TRG_TX], 0);
iwl3945_led_unregister_led(&priv->led39[IWL_LED_TRG_RADIO], 1);
iwl3945_led_unregister_led(&priv->led[IWL_LED_TRG_ASSOC], 0);
iwl3945_led_unregister_led(&priv->led[IWL_LED_TRG_RX], 0);
iwl3945_led_unregister_led(&priv->led[IWL_LED_TRG_TX], 0);
iwl3945_led_unregister_led(&priv->led[IWL_LED_TRG_RADIO], 1);
}
#endif

View file

@ -29,24 +29,10 @@
struct iwl_priv;
#ifdef CONFIG_IWL3945_LEDS
#ifdef CONFIG_IWLWIFI_LEDS
#include "iwl-led.h"
struct iwl3945_led {
struct iwl_priv *priv;
struct led_classdev led_dev;
char name[32];
int (*led_on) (struct iwl_priv *priv, int led_id);
int (*led_off) (struct iwl_priv *priv, int led_id);
int (*led_pattern) (struct iwl_priv *priv, int led_id,
unsigned int idx);
enum led_type type;
unsigned int registered;
};
extern int iwl3945_led_register(struct iwl_priv *priv);
extern void iwl3945_led_unregister(struct iwl_priv *priv);
extern void iwl3945_led_background(struct iwl_priv *priv);
@ -55,6 +41,6 @@ extern void iwl3945_led_background(struct iwl_priv *priv);
static inline int iwl3945_led_register(struct iwl_priv *priv) { return 0; }
static inline void iwl3945_led_unregister(struct iwl_priv *priv) {}
static inline void iwl3945_led_background(struct iwl_priv *priv) {}
#endif /* CONFIG_IWL3945_LEDS */
#endif /* IWLWIFI_LEDS*/
#endif /* IWL3945_LEDS_H */

View file

@ -127,6 +127,7 @@ static struct iwl3945_tpt_entry iwl3945_tpt_table_g[] = {
#define IWL_RATE_MIN_FAILURE_TH 8
#define IWL_RATE_MIN_SUCCESS_TH 8
#define IWL_RATE_DECREASE_TH 1920
#define IWL_RATE_RETRY_TH 15
static u8 iwl3945_get_rate_index_by_rssi(s32 rssi, enum ieee80211_band band)
{
@ -298,37 +299,53 @@ static void iwl3945_collect_tx_data(struct iwl3945_rs_sta *rs_sta,
}
spin_lock_irqsave(&rs_sta->lock, flags);
while (retries--) {
/* If we have filled up the window then subtract one from the
* success counter if the high-bit is counting toward
* success */
if (window->counter == IWL_RATE_MAX_WINDOW) {
if (window->data & (1ULL << (IWL_RATE_MAX_WINDOW - 1)))
/*
* Keep track of only the latest 62 tx frame attempts in this rate's
* history window; anything older isn't really relevant any more.
* If we have filled up the sliding window, drop the oldest attempt;
* if the oldest attempt (highest bit in bitmap) shows "success",
* subtract "1" from the success counter (this is the main reason
* we keep these bitmaps!).
* */
while (retries > 0) {
if (window->counter >= IWL_RATE_MAX_WINDOW) {
/* remove earliest */
window->counter = IWL_RATE_MAX_WINDOW - 1;
if (window->data & (1ULL << (IWL_RATE_MAX_WINDOW - 1))) {
window->data &= ~(1ULL << (IWL_RATE_MAX_WINDOW - 1));
window->success_counter--;
} else
window->counter++;
/* Slide the window to the left one bit */
window->data = (window->data << 1);
/* If this packet was a success then set the low bit high */
if (success) {
window->success_counter++;
window->data |= 1;
}
}
/* window->counter can't be 0 -- it is either >0 or
* IWL_RATE_MAX_WINDOW */
window->success_ratio = 12800 * window->success_counter /
window->counter;
/* Increment frames-attempted counter */
window->counter++;
/* Tag this window as having been updated */
window->stamp = jiffies;
/* Shift bitmap by one frame (throw away oldest history),
* OR in "1", and increment "success" if this
* frame was successful. */
window->data <<= 1;
if (success > 0) {
window->success_counter++;
window->data |= 0x1;
success--;
}
retries--;
}
/* Calculate current success ratio, avoid divide-by-0! */
if (window->counter > 0)
window->success_ratio = 128 * (100 * window->success_counter)
/ window->counter;
else
window->success_ratio = IWL_INVALID_VALUE;
fail_count = window->counter - window->success_counter;
/* Calculate average throughput, if we have enough history. */
if ((fail_count >= IWL_RATE_MIN_FAILURE_TH) ||
(window->success_counter >= IWL_RATE_MIN_SUCCESS_TH))
window->average_tpt = ((window->success_ratio *
@ -336,6 +353,9 @@ static void iwl3945_collect_tx_data(struct iwl3945_rs_sta *rs_sta,
else
window->average_tpt = IWL_INVALID_VALUE;
/* Tag this window as having been updated */
window->stamp = jiffies;
spin_unlock_irqrestore(&rs_sta->lock, flags);
}
@ -468,7 +488,10 @@ static void rs_tx_status(void *priv_rate, struct ieee80211_supported_band *sband
IWL_DEBUG_RATE(priv, "enter\n");
retries = info->status.rates[0].count;
retries = info->status.rates[0].count - 1;
/* Sanity Check for retries */
if (retries > IWL_RATE_RETRY_TH)
retries = IWL_RATE_RETRY_TH;
first_index = sband->bitrates[info->status.rates[0].idx].hw_value;
if ((first_index < 0) || (first_index >= IWL_RATE_COUNT_3945)) {
@ -724,7 +747,7 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta,
fail_count = window->counter - window->success_counter;
if (((fail_count <= IWL_RATE_MIN_FAILURE_TH) &&
if (((fail_count < IWL_RATE_MIN_FAILURE_TH) &&
(window->success_counter < IWL_RATE_MIN_SUCCESS_TH))) {
spin_unlock_irqrestore(&rs_sta->lock, flags);
@ -735,6 +758,9 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta,
window->counter,
window->success_counter,
rs_sta->expected_tpt ? "not " : "");
/* Can't calculate this yet; not enough history */
window->average_tpt = IWL_INVALID_VALUE;
goto out;
}
@ -750,6 +776,7 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta,
if ((max_rate_idx != -1) && (max_rate_idx < high))
high = IWL_RATE_INVALID;
/* Collect Measured throughputs of adjacent rates */
if (low != IWL_RATE_INVALID)
low_tpt = rs_sta->win[low].average_tpt;
@ -758,24 +785,43 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta,
spin_unlock_irqrestore(&rs_sta->lock, flags);
scale_action = 1;
scale_action = 0;
/* Low success ratio , need to drop the rate */
if ((window->success_ratio < IWL_RATE_DECREASE_TH) || !current_tpt) {
IWL_DEBUG_RATE(priv, "decrease rate because of low success_ratio\n");
scale_action = -1;
/* No throughput measured yet for adjacent rates,
* try increase */
} else if ((low_tpt == IWL_INVALID_VALUE) &&
(high_tpt == IWL_INVALID_VALUE))
scale_action = 1;
else if ((low_tpt != IWL_INVALID_VALUE) &&
(high_tpt == IWL_INVALID_VALUE)) {
if (high != IWL_RATE_INVALID && window->success_counter >= IWL_RATE_INCREASE_TH)
scale_action = 1;
else if (low != IWL_RATE_INVALID)
scale_action = -1;
/* Both adjacent throughputs are measured, but neither one has
* better throughput; we're using the best rate, don't change
* it! */
} else if ((low_tpt != IWL_INVALID_VALUE) &&
(high_tpt != IWL_INVALID_VALUE) &&
(low_tpt < current_tpt) && (high_tpt < current_tpt)) {
IWL_DEBUG_RATE(priv, "No action -- low [%d] & high [%d] < "
"current_tpt [%d]\n",
low_tpt, high_tpt, current_tpt);
scale_action = 0;
/* At least one of the rates has better throughput */
} else {
if (high_tpt != IWL_INVALID_VALUE) {
if (high_tpt > current_tpt)
/* High rate has better throughput, Increase
* rate */
if (high_tpt > current_tpt &&
window->success_ratio >= IWL_RATE_INCREASE_TH)
scale_action = 1;
else {
IWL_DEBUG_RATE(priv,
@ -787,29 +833,31 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta,
IWL_DEBUG_RATE(priv,
"decrease rate because of low tpt\n");
scale_action = -1;
} else
} else if (window->success_counter >= IWL_RATE_INCREASE_TH) {
/* Lower rate has better
* throughput,decrease rate */
scale_action = 1;
}
}
}
if (scale_action == -1) {
if (window->success_ratio > IWL_SUCCESS_DOWN_TH)
scale_action = 0;
} else if (scale_action == 1) {
if (window->success_ratio < IWL_SUCCESS_UP_TH) {
IWL_DEBUG_RATE(priv, "No action -- success_ratio [%d] < "
"SUCCESS UP\n", window->success_ratio);
scale_action = 0;
}
}
/* Sanity check; asked for decrease, but success rate or throughput
* has been good at old rate. Don't change it. */
if ((scale_action == -1) && (low != IWL_RATE_INVALID) &&
((window->success_ratio > IWL_RATE_HIGH_TH) ||
(current_tpt > (100 * rs_sta->expected_tpt[low]))))
scale_action = 0;
switch (scale_action) {
case -1:
/* Decrese rate */
if (low != IWL_RATE_INVALID)
index = low;
break;
case 1:
/* Increase rate */
if (high != IWL_RATE_INVALID)
index = high;
@ -817,6 +865,7 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta,
case 0:
default:
/* No change */
break;
}

View file

@ -554,7 +554,7 @@ static void iwl3945_pass_packet_to_mac80211(struct iwl_priv *priv,
struct ieee80211_rx_status *stats)
{
struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
#ifdef CONFIG_IWL3945_LEDS
#ifdef CONFIG_IWLWIFI_LEDS
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)IWL_RX_DATA(pkt);
#endif
struct iwl3945_rx_frame_hdr *rx_hdr = IWL_RX_HDR(pkt);
@ -583,7 +583,7 @@ static void iwl3945_pass_packet_to_mac80211(struct iwl_priv *priv,
(struct ieee80211_hdr *)rxb->skb->data,
le32_to_cpu(rx_end->status), stats);
#ifdef CONFIG_IWL3945_LEDS
#ifdef CONFIG_IWLWIFI_LEDS
if (ieee80211_is_data(hdr->frame_control))
priv->rxtxpackets += len;
#endif
@ -741,7 +741,8 @@ int iwl3945_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv,
void iwl3945_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq)
{
struct iwl3945_tfd *tfd_tmp = (struct iwl3945_tfd *)txq->tfds;
struct iwl3945_tfd *tfd = &tfd_tmp[txq->q.read_ptr];
int index = txq->q.read_ptr;
struct iwl3945_tfd *tfd = &tfd_tmp[index];
struct pci_dev *dev = priv->pci_dev;
int i;
int counter;
@ -759,6 +760,13 @@ void iwl3945_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq)
return;
}
/* Unmap tx_cmd */
if (counter)
pci_unmap_single(dev,
pci_unmap_addr(&txq->cmd[index]->meta, mapping),
pci_unmap_len(&txq->cmd[index]->meta, len),
PCI_DMA_TODEVICE);
/* unmap chunks if any */
for (i = 1; i < counter; i++) {

View file

@ -801,7 +801,10 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband,
!(info->flags & IEEE80211_TX_STAT_AMPDU))
return;
retries = info->status.rates[0].count - 1;
if (info->flags & IEEE80211_TX_STAT_AMPDU)
retries = 0;
else
retries = info->status.rates[0].count - 1;
if (retries > 15)
retries = 15;
@ -913,7 +916,7 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband,
tpt = search_tbl->expected_tpt[rs_index];
else
tpt = 0;
if (info->flags & IEEE80211_TX_CTL_AMPDU)
if (info->flags & IEEE80211_TX_STAT_AMPDU)
rs_collect_tx_data(search_win, rs_index, tpt,
info->status.ampdu_ack_len,
info->status.ampdu_ack_map);
@ -929,7 +932,7 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband,
tpt = curr_tbl->expected_tpt[rs_index];
else
tpt = 0;
if (info->flags & IEEE80211_TX_CTL_AMPDU)
if (info->flags & IEEE80211_TX_STAT_AMPDU)
rs_collect_tx_data(window, rs_index, tpt,
info->status.ampdu_ack_len,
info->status.ampdu_ack_map);
@ -941,7 +944,7 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband,
/* If not searching for new mode, increment success/failed counter
* ... these help determine when to start searching again */
if (lq_sta->stay_in_tbl) {
if (info->flags & IEEE80211_TX_CTL_AMPDU) {
if (info->flags & IEEE80211_TX_STAT_AMPDU) {
lq_sta->total_success += info->status.ampdu_ack_map;
lq_sta->total_failed +=
(info->status.ampdu_ack_len - info->status.ampdu_ack_map);
@ -1700,6 +1703,7 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
u16 high_low;
s32 sr;
u8 tid = MAX_TID_COUNT;
struct iwl_tid_data *tid_data;
IWL_DEBUG_RATE(priv, "rate scale calculate new rate for skb\n");
@ -1896,7 +1900,7 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
if (high != IWL_RATE_INVALID && sr >= IWL_RATE_INCREASE_TH)
scale_action = 1;
else if (low != IWL_RATE_INVALID)
scale_action = -1;
scale_action = 0;
}
/* Both adjacent throughputs are measured, but neither one has better
@ -1917,9 +1921,7 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
sr >= IWL_RATE_INCREASE_TH) {
scale_action = 1;
} else {
IWL_DEBUG_RATE(priv,
"decrease rate because of high tpt\n");
scale_action = -1;
scale_action = 0;
}
/* Lower adjacent rate's throughput is measured */
@ -2035,8 +2037,15 @@ lq_update:
if ((lq_sta->last_tpt > IWL_AGG_TPT_THREHOLD) &&
(lq_sta->tx_agg_tid_en & (1 << tid)) &&
(tid != MAX_TID_COUNT)) {
IWL_DEBUG_RATE(priv, "try to aggregate tid %d\n", tid);
rs_tl_turn_on_agg(priv, tid, lq_sta, sta);
tid_data =
&priv->stations[lq_sta->lq.sta_id].tid[tid];
if (tid_data->agg.state == IWL_AGG_OFF) {
IWL_DEBUG_RATE(priv,
"try to aggregate tid %d\n",
tid);
rs_tl_turn_on_agg(priv, tid,
lq_sta, sta);
}
}
lq_sta->action_counter = 0;
rs_set_stay_in_table(priv, 0, lq_sta);
@ -2464,18 +2473,25 @@ static void rs_dbgfs_set_mcs(struct iwl_lq_sta *lq_sta,
u32 *rate_n_flags, int index)
{
struct iwl_priv *priv;
u8 valid_tx_ant;
u8 ant_sel_tx;
priv = lq_sta->drv;
valid_tx_ant = priv->hw_params.valid_tx_ant;
if (lq_sta->dbg_fixed_rate) {
if (index < 12) {
ant_sel_tx =
((lq_sta->dbg_fixed_rate & RATE_MCS_ANT_ABC_MSK)
>> RATE_MCS_ANT_POS);
if ((valid_tx_ant & ant_sel_tx) == ant_sel_tx) {
*rate_n_flags = lq_sta->dbg_fixed_rate;
IWL_DEBUG_RATE(priv, "Fixed rate ON\n");
} else {
if (lq_sta->band == IEEE80211_BAND_5GHZ)
*rate_n_flags = 0x800D;
else
*rate_n_flags = 0x820A;
lq_sta->dbg_fixed_rate = 0;
IWL_ERR(priv,
"Invalid antenna selection 0x%X, Valid is 0x%X\n",
ant_sel_tx, valid_tx_ant);
IWL_DEBUG_RATE(priv, "Fixed rate OFF\n");
}
IWL_DEBUG_RATE(priv, "Fixed rate ON\n");
} else {
IWL_DEBUG_RATE(priv, "Fixed rate OFF\n");
}
@ -2526,7 +2542,10 @@ static ssize_t rs_sta_dbgfs_scale_table_read(struct file *file,
ssize_t ret;
struct iwl_lq_sta *lq_sta = file->private_data;
struct iwl_priv *priv;
struct iwl_scale_tbl_info *tbl = &(lq_sta->lq_info[lq_sta->active_tbl]);
priv = lq_sta->drv;
buff = kmalloc(1024, GFP_KERNEL);
if (!buff)
return -ENOMEM;
@ -2537,6 +2556,20 @@ static ssize_t rs_sta_dbgfs_scale_table_read(struct file *file,
lq_sta->active_legacy_rate);
desc += sprintf(buff+desc, "fixed rate 0x%X\n",
lq_sta->dbg_fixed_rate);
desc += sprintf(buff+desc, "valid_tx_ant %s%s%s\n",
(priv->hw_params.valid_tx_ant & ANT_A) ? "ANT_A," : "",
(priv->hw_params.valid_tx_ant & ANT_B) ? "ANT_B," : "",
(priv->hw_params.valid_tx_ant & ANT_C) ? "ANT_C" : "");
desc += sprintf(buff+desc, "lq type %s\n",
(is_legacy(tbl->lq_type)) ? "legacy" : "HT");
if (is_Ht(tbl->lq_type)) {
desc += sprintf(buff+desc, " %s",
(is_siso(tbl->lq_type)) ? "SISO" :
((is_mimo2(tbl->lq_type)) ? "MIMO2" : "MIMO3"));
desc += sprintf(buff+desc, " %s",
(tbl->is_fat) ? "40MHz" : "20MHz");
desc += sprintf(buff+desc, " %s\n", (tbl->is_SGI) ? "SGI" : "");
}
desc += sprintf(buff+desc, "general:"
"flags=0x%X mimo-d=%d s-ant0x%x d-ant=0x%x\n",
lq_sta->lq.general_params.flags,

View file

@ -231,7 +231,7 @@ enum {
#define IWL_RS_GOOD_RATIO 12800 /* 100% */
#define IWL_RATE_SCALE_SWITCH 10880 /* 85% */
#define IWL_RATE_HIGH_TH 10880 /* 85% */
#define IWL_RATE_INCREASE_TH 8960 /* 70% */
#define IWL_RATE_INCREASE_TH 6400 /* 50% */
#define IWL_RATE_DECREASE_TH 1920 /* 15% */
/* possible actions when in legacy mode */

View file

@ -3359,7 +3359,7 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
/* amp init */
err = priv->cfg->ops->lib->apm_ops.init(priv);
if (err < 0) {
IWL_DEBUG_INFO(priv, "Failed to init APMG\n");
IWL_ERR(priv, "Failed to init APMG\n");
goto out_iounmap;
}
/*****************
@ -3643,9 +3643,9 @@ static struct pci_device_id iwl_hw_card_ids[] = {
{IWL_PCI_DEVICE(0x0087, PCI_ANY_ID, iwl6050_2agn_cfg)},
{IWL_PCI_DEVICE(0x0088, PCI_ANY_ID, iwl6050_3agn_cfg)},
{IWL_PCI_DEVICE(0x0089, PCI_ANY_ID, iwl6050_2agn_cfg)},
/* 100 Series WiFi */
{IWL_PCI_DEVICE(0x0083, PCI_ANY_ID, iwl100_bgn_cfg)},
{IWL_PCI_DEVICE(0x0084, PCI_ANY_ID, iwl100_bgn_cfg)},
/* 1000 Series WiFi */
{IWL_PCI_DEVICE(0x0083, PCI_ANY_ID, iwl1000_bgn_cfg)},
{IWL_PCI_DEVICE(0x0084, PCI_ANY_ID, iwl1000_bgn_cfg)},
#endif /* CONFIG_IWL5000 */
{0}

View file

@ -211,7 +211,7 @@
#define CSR_HW_REV_TYPE_5350 (0x0000030)
#define CSR_HW_REV_TYPE_5100 (0x0000050)
#define CSR_HW_REV_TYPE_5150 (0x0000040)
#define CSR_HW_REV_TYPE_100 (0x0000060)
#define CSR_HW_REV_TYPE_1000 (0x0000060)
#define CSR_HW_REV_TYPE_6x00 (0x0000070)
#define CSR_HW_REV_TYPE_6x50 (0x0000080)
#define CSR_HW_REV_TYPE_NONE (0x00000F0)

View file

@ -62,7 +62,7 @@ extern struct iwl_cfg iwl6000_2agn_cfg;
extern struct iwl_cfg iwl6000_3agn_cfg;
extern struct iwl_cfg iwl6050_2agn_cfg;
extern struct iwl_cfg iwl6050_3agn_cfg;
extern struct iwl_cfg iwl100_bgn_cfg;
extern struct iwl_cfg iwl1000_bgn_cfg;
/* shared structures from iwl-5000.c */
extern struct iwl_mod_params iwl50_mod_params;
@ -926,19 +926,12 @@ struct iwl_priv {
struct rfkill *rfkill;
#endif
#if defined(CONFIG_IWLWIFI_LEDS) || defined(CONFIG_IWL3945_LEDS)
#ifdef CONFIG_IWLWIFI_LEDS
unsigned long last_blink_time;
u8 last_blink_rate;
u8 allow_blinking;
u64 led_tpt;
#endif
#ifdef CONFIG_IWLWIFI_LEDS
struct iwl_led led[IWL_LED_TRG_MAX];
#endif
#ifdef CONFIG_IWL3945_LEDS
struct iwl3945_led led39[IWL_LED_TRG_MAX];
unsigned int rxtxpackets;
#endif
u16 active_rate;

View file

@ -156,6 +156,7 @@ static inline void __iwl_clear_bit(const char *f, u32 l,
static inline int _iwl_grab_nic_access(struct iwl_priv *priv)
{
int ret;
u32 val;
#ifdef CONFIG_IWLWIFI_DEBUG
if (atomic_read(&priv->restrict_refcnt))
return 0;
@ -167,7 +168,8 @@ static inline int _iwl_grab_nic_access(struct iwl_priv *priv)
(CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY |
CSR_GP_CNTRL_REG_FLAG_GOING_TO_SLEEP), 15000);
if (ret < 0) {
IWL_ERR(priv, "MAC is in deep sleep!\n");
val = _iwl_read32(priv, CSR_GP_CNTRL);
IWL_ERR(priv, "MAC is in deep sleep!. CSR_GP_CNTRL = 0x%08X\n", val);
return -EIO;
}

View file

@ -30,7 +30,7 @@
struct iwl_priv;
#if defined(CONFIG_IWLWIFI_LEDS) || defined(CONFIG_IWL3945_LEDS)
#ifdef CONFIG_IWLWIFI_LEDS
#include <linux/leds.h>
#define IWL_LED_SOLID 11

View file

@ -472,6 +472,7 @@ EXPORT_SYMBOL(iwl_remove_station);
void iwl_clear_stations_table(struct iwl_priv *priv)
{
unsigned long flags;
int i;
spin_lock_irqsave(&priv->sta_lock, flags);
@ -486,6 +487,12 @@ void iwl_clear_stations_table(struct iwl_priv *priv)
/* clean ucode key table bit map */
priv->ucode_key_table = 0;
/* keep track of static keys */
for (i = 0; i < WEP_KEYS_MAX ; i++) {
if (priv->wep_keys[i].key_size)
test_and_set_bit(i, &priv->ucode_key_table);
}
spin_unlock_irqrestore(&priv->sta_lock, flags);
}
EXPORT_SYMBOL(iwl_clear_stations_table);

View file

@ -328,6 +328,8 @@ static int iwl3945_commit_rxon(struct iwl_priv *priv)
struct iwl3945_rxon_cmd *active_rxon = (void *)&priv->active_rxon;
struct iwl3945_rxon_cmd *staging_rxon = (void *)&priv->staging_rxon;
int rc = 0;
bool new_assoc =
!!(priv->staging_rxon.filter_flags & RXON_FILTER_ASSOC_MSK);
if (!iwl_is_alive(priv))
return -1;
@ -366,8 +368,7 @@ static int iwl3945_commit_rxon(struct iwl_priv *priv)
* an RXON_ASSOC and the new config wants the associated mask enabled,
* we must clear the associated from the active configuration
* before we apply the new config */
if (iwl_is_associated(priv) &&
(staging_rxon->filter_flags & RXON_FILTER_ASSOC_MSK)) {
if (iwl_is_associated(priv) && new_assoc) {
IWL_DEBUG_INFO(priv, "Toggling associated bit on current RXON\n");
active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK;
@ -395,8 +396,7 @@ static int iwl3945_commit_rxon(struct iwl_priv *priv)
"* with%s RXON_FILTER_ASSOC_MSK\n"
"* channel = %d\n"
"* bssid = %pM\n",
((priv->staging_rxon.filter_flags &
RXON_FILTER_ASSOC_MSK) ? "" : "out"),
(new_assoc ? "" : "out"),
le16_to_cpu(staging_rxon->channel),
staging_rxon->bssid_addr);
@ -542,7 +542,7 @@ static int iwl3945_clear_sta_key_info(struct iwl_priv *priv, u8 sta_id)
return 0;
}
int iwl3945_set_dynamic_key(struct iwl_priv *priv,
static int iwl3945_set_dynamic_key(struct iwl_priv *priv,
struct ieee80211_key_conf *keyconf, u8 sta_id)
{
int ret = 0;
@ -890,7 +890,7 @@ static void iwl3945_build_tx_cmd_basic(struct iwl_priv *priv,
tx->timeout.pm_frame_timeout = cpu_to_le16(2);
} else {
tx->timeout.pm_frame_timeout = 0;
#ifdef CONFIG_IWL3945_LEDS
#ifdef CONFIG_IWLWIFI_LEDS
priv->rxtxpackets += le16_to_cpu(cmd->cmd.tx.len);
#endif
}
@ -1479,85 +1479,6 @@ static void iwl3945_setup_rx_handlers(struct iwl_priv *priv)
iwl3945_hw_rx_handler_setup(priv);
}
/**
* iwl3945_cmd_queue_reclaim - Reclaim CMD queue entries
* When FW advances 'R' index, all entries between old and new 'R' index
* need to be reclaimed.
*/
static void iwl3945_cmd_queue_reclaim(struct iwl_priv *priv,
int txq_id, int index)
{
struct iwl_tx_queue *txq = &priv->txq[txq_id];
struct iwl_queue *q = &txq->q;
int nfreed = 0;
if ((index >= q->n_bd) || (iwl_queue_used(q, index) == 0)) {
IWL_ERR(priv, "Read index for DMA queue txq id (%d), index %d, "
"is out of range [0-%d] %d %d.\n", txq_id,
index, q->n_bd, q->write_ptr, q->read_ptr);
return;
}
for (index = iwl_queue_inc_wrap(index, q->n_bd); q->read_ptr != index;
q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd)) {
if (nfreed > 1) {
IWL_ERR(priv, "HCMD skipped: index (%d) %d %d\n", index,
q->write_ptr, q->read_ptr);
queue_work(priv->workqueue, &priv->restart);
break;
}
nfreed++;
}
}
/**
* iwl3945_tx_cmd_complete - Pull unused buffers off the queue and reclaim them
* @rxb: Rx buffer to reclaim
*
* If an Rx buffer has an async callback associated with it the callback
* will be executed. The attached skb (if present) will only be freed
* if the callback returns 1
*/
static void iwl3945_tx_cmd_complete(struct iwl_priv *priv,
struct iwl_rx_mem_buffer *rxb)
{
struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
u16 sequence = le16_to_cpu(pkt->hdr.sequence);
int txq_id = SEQ_TO_QUEUE(sequence);
int index = SEQ_TO_INDEX(sequence);
int huge = !!(pkt->hdr.sequence & SEQ_HUGE_FRAME);
int cmd_index;
struct iwl_cmd *cmd;
if (WARN(txq_id != IWL_CMD_QUEUE_NUM,
"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];
/* Input error checking is done when commands are added to queue. */
if (cmd->meta.flags & CMD_WANT_SKB) {
cmd->meta.source->u.skb = rxb->skb;
rxb->skb = NULL;
} else if (cmd->meta.u.callback &&
!cmd->meta.u.callback(priv, cmd, rxb->skb))
rxb->skb = NULL;
iwl3945_cmd_queue_reclaim(priv, txq_id, index);
if (!(cmd->meta.flags & CMD_ASYNC)) {
clear_bit(STATUS_HCMD_ACTIVE, &priv->status);
wake_up_interruptible(&priv->wait_command_queue);
}
}
/************************** RX-FUNCTIONS ****************************/
/*
* Rx theory of operation
@ -1917,7 +1838,7 @@ static void iwl3945_rx_handle(struct iwl_priv *priv)
* fire off the (possibly) blocking iwl_send_cmd()
* as we reclaim the driver command queue */
if (rxb && rxb->skb)
iwl3945_tx_cmd_complete(priv, rxb);
iwl_tx_cmd_complete(priv, rxb);
else
IWL_WARN(priv, "Claim null rxb?\n");
}

View file

@ -10,7 +10,6 @@
/*
* TODO:
* - IBSS mode simulation (Beacon transmission with competition for "air time")
* - IEEE 802.11a and 802.11n modes
* - RX filtering based on filter configuration (data->rx_filter)
*/
@ -31,6 +30,112 @@ static int radios = 2;
module_param(radios, int, 0444);
MODULE_PARM_DESC(radios, "Number of simulated radios");
/**
* enum hwsim_regtest - the type of regulatory tests we offer
*
* These are the different values you can use for the regtest
* module parameter. This is useful to help test world roaming
* and the driver regulatory_hint() call and combinations of these.
* If you want to do specific alpha2 regulatory domain tests simply
* use the userspace regulatory request as that will be respected as
* well without the need of this module parameter. This is designed
* only for testing the driver regulatory request, world roaming
* and all possible combinations.
*
* @HWSIM_REGTEST_DISABLED: No regulatory tests are performed,
* this is the default value.
* @HWSIM_REGTEST_DRIVER_REG_FOLLOW: Used for testing the driver regulatory
* hint, only one driver regulatory hint will be sent as such the
* secondary radios are expected to follow.
* @HWSIM_REGTEST_DRIVER_REG_ALL: Used for testing the driver regulatory
* request with all radios reporting the same regulatory domain.
* @HWSIM_REGTEST_DIFF_COUNTRY: Used for testing the drivers calling
* different regulatory domains requests. Expected behaviour is for
* an intersection to occur but each device will still use their
* respective regulatory requested domains. Subsequent radios will
* use the resulting intersection.
* @HWSIM_REGTEST_WORLD_ROAM: Used for testing the world roaming. We acomplish
* this by using a custom beacon-capable regulatory domain for the first
* radio. All other device world roam.
* @HWSIM_REGTEST_CUSTOM_WORLD: Used for testing the custom world regulatory
* domain requests. All radios will adhere to this custom world regulatory
* domain.
* @HWSIM_REGTEST_CUSTOM_WORLD_2: Used for testing 2 custom world regulatory
* domain requests. The first radio will adhere to the first custom world
* regulatory domain, the second one to the second custom world regulatory
* domain. All other devices will world roam.
* @HWSIM_REGTEST_STRICT_FOLLOW_: Used for testing strict regulatory domain
* settings, only the first radio will send a regulatory domain request
* and use strict settings. The rest of the radios are expected to follow.
* @HWSIM_REGTEST_STRICT_ALL: Used for testing strict regulatory domain
* settings. All radios will adhere to this.
* @HWSIM_REGTEST_STRICT_AND_DRIVER_REG: Used for testing strict regulatory
* domain settings, combined with secondary driver regulatory domain
* settings. The first radio will get a strict regulatory domain setting
* using the first driver regulatory request and the second radio will use
* non-strict settings using the second driver regulatory request. All
* other devices should follow the intersection created between the
* first two.
* @HWSIM_REGTEST_ALL: Used for testing every possible mix. You will need
* at least 6 radios for a complete test. We will test in this order:
* 1 - driver custom world regulatory domain
* 2 - second custom world regulatory domain
* 3 - first driver regulatory domain request
* 4 - second driver regulatory domain request
* 5 - strict regulatory domain settings using the third driver regulatory
* domain request
* 6 and on - should follow the intersection of the 3rd, 4rth and 5th radio
* regulatory requests.
*/
enum hwsim_regtest {
HWSIM_REGTEST_DISABLED = 0,
HWSIM_REGTEST_DRIVER_REG_FOLLOW = 1,
HWSIM_REGTEST_DRIVER_REG_ALL = 2,
HWSIM_REGTEST_DIFF_COUNTRY = 3,
HWSIM_REGTEST_WORLD_ROAM = 4,
HWSIM_REGTEST_CUSTOM_WORLD = 5,
HWSIM_REGTEST_CUSTOM_WORLD_2 = 6,
HWSIM_REGTEST_STRICT_FOLLOW = 7,
HWSIM_REGTEST_STRICT_ALL = 8,
HWSIM_REGTEST_STRICT_AND_DRIVER_REG = 9,
HWSIM_REGTEST_ALL = 10,
};
/* Set to one of the HWSIM_REGTEST_* values above */
static int regtest = HWSIM_REGTEST_DISABLED;
module_param(regtest, int, 0444);
MODULE_PARM_DESC(regtest, "The type of regulatory test we want to run");
static const char *hwsim_alpha2s[] = {
"FI",
"AL",
"US",
"DE",
"JP",
"AL",
};
static const struct ieee80211_regdomain hwsim_world_regdom_custom_01 = {
.n_reg_rules = 4,
.alpha2 = "99",
.reg_rules = {
REG_RULE(2412-10, 2462+10, 40, 0, 20, 0),
REG_RULE(2484-10, 2484+10, 40, 0, 20, 0),
REG_RULE(5150-10, 5240+10, 40, 0, 30, 0),
REG_RULE(5745-10, 5825+10, 40, 0, 30, 0),
}
};
static const struct ieee80211_regdomain hwsim_world_regdom_custom_02 = {
.n_reg_rules = 2,
.alpha2 = "99",
.reg_rules = {
REG_RULE(2412-10, 2462+10, 40, 0, 20, 0),
REG_RULE(5725-10, 5850+10, 40, 0, 30,
NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS),
}
};
struct hwsim_vif_priv {
u32 magic;
u8 bssid[ETH_ALEN];
@ -86,22 +191,65 @@ static struct class *hwsim_class;
static struct net_device *hwsim_mon; /* global monitor netdev */
#define CHAN2G(_freq) { \
.band = IEEE80211_BAND_2GHZ, \
.center_freq = (_freq), \
.hw_value = (_freq), \
.max_power = 20, \
}
static const struct ieee80211_channel hwsim_channels[] = {
{ .center_freq = 2412 },
{ .center_freq = 2417 },
{ .center_freq = 2422 },
{ .center_freq = 2427 },
{ .center_freq = 2432 },
{ .center_freq = 2437 },
{ .center_freq = 2442 },
{ .center_freq = 2447 },
{ .center_freq = 2452 },
{ .center_freq = 2457 },
{ .center_freq = 2462 },
{ .center_freq = 2467 },
{ .center_freq = 2472 },
{ .center_freq = 2484 },
#define CHAN5G(_freq) { \
.band = IEEE80211_BAND_5GHZ, \
.center_freq = (_freq), \
.hw_value = (_freq), \
.max_power = 20, \
}
static const struct ieee80211_channel hwsim_channels_2ghz[] = {
CHAN2G(2412), /* Channel 1 */
CHAN2G(2417), /* Channel 2 */
CHAN2G(2422), /* Channel 3 */
CHAN2G(2427), /* Channel 4 */
CHAN2G(2432), /* Channel 5 */
CHAN2G(2437), /* Channel 6 */
CHAN2G(2442), /* Channel 7 */
CHAN2G(2447), /* Channel 8 */
CHAN2G(2452), /* Channel 9 */
CHAN2G(2457), /* Channel 10 */
CHAN2G(2462), /* Channel 11 */
CHAN2G(2467), /* Channel 12 */
CHAN2G(2472), /* Channel 13 */
CHAN2G(2484), /* Channel 14 */
};
static const struct ieee80211_channel hwsim_channels_5ghz[] = {
CHAN5G(5180), /* Channel 36 */
CHAN5G(5200), /* Channel 40 */
CHAN5G(5220), /* Channel 44 */
CHAN5G(5240), /* Channel 48 */
CHAN5G(5260), /* Channel 52 */
CHAN5G(5280), /* Channel 56 */
CHAN5G(5300), /* Channel 60 */
CHAN5G(5320), /* Channel 64 */
CHAN5G(5500), /* Channel 100 */
CHAN5G(5520), /* Channel 104 */
CHAN5G(5540), /* Channel 108 */
CHAN5G(5560), /* Channel 112 */
CHAN5G(5580), /* Channel 116 */
CHAN5G(5600), /* Channel 120 */
CHAN5G(5620), /* Channel 124 */
CHAN5G(5640), /* Channel 128 */
CHAN5G(5660), /* Channel 132 */
CHAN5G(5680), /* Channel 136 */
CHAN5G(5700), /* Channel 140 */
CHAN5G(5745), /* Channel 149 */
CHAN5G(5765), /* Channel 153 */
CHAN5G(5785), /* Channel 157 */
CHAN5G(5805), /* Channel 161 */
CHAN5G(5825), /* Channel 165 */
};
static const struct ieee80211_rate hwsim_rates[] = {
@ -126,8 +274,9 @@ struct mac80211_hwsim_data {
struct list_head list;
struct ieee80211_hw *hw;
struct device *dev;
struct ieee80211_supported_band band;
struct ieee80211_channel channels[ARRAY_SIZE(hwsim_channels)];
struct ieee80211_supported_band bands[2];
struct ieee80211_channel channels_2ghz[ARRAY_SIZE(hwsim_channels_2ghz)];
struct ieee80211_channel channels_5ghz[ARRAY_SIZE(hwsim_channels_5ghz)];
struct ieee80211_rate rates[ARRAY_SIZE(hwsim_rates)];
struct ieee80211_channel *channel;
@ -728,6 +877,7 @@ static int __init init_mac80211_hwsim(void)
u8 addr[ETH_ALEN];
struct mac80211_hwsim_data *data;
struct ieee80211_hw *hw;
enum ieee80211_band band;
if (radios < 1 || radios > 100)
return -EINVAL;
@ -785,25 +935,105 @@ static int __init init_mac80211_hwsim(void)
hw->vif_data_size = sizeof(struct hwsim_vif_priv);
hw->sta_data_size = sizeof(struct hwsim_sta_priv);
memcpy(data->channels, hwsim_channels, sizeof(hwsim_channels));
memcpy(data->channels_2ghz, hwsim_channels_2ghz,
sizeof(hwsim_channels_2ghz));
memcpy(data->channels_5ghz, hwsim_channels_5ghz,
sizeof(hwsim_channels_5ghz));
memcpy(data->rates, hwsim_rates, sizeof(hwsim_rates));
data->band.channels = data->channels;
data->band.n_channels = ARRAY_SIZE(hwsim_channels);
data->band.bitrates = data->rates;
data->band.n_bitrates = ARRAY_SIZE(hwsim_rates);
data->band.ht_cap.ht_supported = true;
data->band.ht_cap.cap = IEEE80211_HT_CAP_SUP_WIDTH_20_40 |
IEEE80211_HT_CAP_GRN_FLD |
IEEE80211_HT_CAP_SGI_40 |
IEEE80211_HT_CAP_DSSSCCK40;
data->band.ht_cap.ampdu_factor = 0x3;
data->band.ht_cap.ampdu_density = 0x6;
memset(&data->band.ht_cap.mcs, 0,
sizeof(data->band.ht_cap.mcs));
data->band.ht_cap.mcs.rx_mask[0] = 0xff;
data->band.ht_cap.mcs.rx_mask[1] = 0xff;
data->band.ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED;
hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &data->band;
for (band = IEEE80211_BAND_2GHZ; band < IEEE80211_NUM_BANDS; band++) {
struct ieee80211_supported_band *sband = &data->bands[band];
switch (band) {
case IEEE80211_BAND_2GHZ:
sband->channels = data->channels_2ghz;
sband->n_channels =
ARRAY_SIZE(hwsim_channels_2ghz);
break;
case IEEE80211_BAND_5GHZ:
sband->channels = data->channels_5ghz;
sband->n_channels =
ARRAY_SIZE(hwsim_channels_5ghz);
break;
default:
break;
}
sband->bitrates = data->rates;
sband->n_bitrates = ARRAY_SIZE(hwsim_rates);
sband->ht_cap.ht_supported = true;
sband->ht_cap.cap = IEEE80211_HT_CAP_SUP_WIDTH_20_40 |
IEEE80211_HT_CAP_GRN_FLD |
IEEE80211_HT_CAP_SGI_40 |
IEEE80211_HT_CAP_DSSSCCK40;
sband->ht_cap.ampdu_factor = 0x3;
sband->ht_cap.ampdu_density = 0x6;
memset(&sband->ht_cap.mcs, 0,
sizeof(sband->ht_cap.mcs));
sband->ht_cap.mcs.rx_mask[0] = 0xff;
sband->ht_cap.mcs.rx_mask[1] = 0xff;
sband->ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED;
hw->wiphy->bands[band] = sband;
}
/* Work to be done prior to ieee80211_register_hw() */
switch (regtest) {
case HWSIM_REGTEST_DISABLED:
case HWSIM_REGTEST_DRIVER_REG_FOLLOW:
case HWSIM_REGTEST_DRIVER_REG_ALL:
case HWSIM_REGTEST_DIFF_COUNTRY:
/*
* Nothing to be done for driver regulatory domain
* hints prior to ieee80211_register_hw()
*/
break;
case HWSIM_REGTEST_WORLD_ROAM:
if (i == 0) {
hw->wiphy->custom_regulatory = true;
wiphy_apply_custom_regulatory(hw->wiphy,
&hwsim_world_regdom_custom_01);
}
break;
case HWSIM_REGTEST_CUSTOM_WORLD:
hw->wiphy->custom_regulatory = true;
wiphy_apply_custom_regulatory(hw->wiphy,
&hwsim_world_regdom_custom_01);
break;
case HWSIM_REGTEST_CUSTOM_WORLD_2:
if (i == 0) {
hw->wiphy->custom_regulatory = true;
wiphy_apply_custom_regulatory(hw->wiphy,
&hwsim_world_regdom_custom_01);
} else if (i == 1) {
hw->wiphy->custom_regulatory = true;
wiphy_apply_custom_regulatory(hw->wiphy,
&hwsim_world_regdom_custom_02);
}
break;
case HWSIM_REGTEST_STRICT_ALL:
hw->wiphy->strict_regulatory = true;
break;
case HWSIM_REGTEST_STRICT_FOLLOW:
case HWSIM_REGTEST_STRICT_AND_DRIVER_REG:
if (i == 0)
hw->wiphy->strict_regulatory = true;
break;
case HWSIM_REGTEST_ALL:
if (i == 0) {
hw->wiphy->custom_regulatory = true;
wiphy_apply_custom_regulatory(hw->wiphy,
&hwsim_world_regdom_custom_01);
} else if (i == 1) {
hw->wiphy->custom_regulatory = true;
wiphy_apply_custom_regulatory(hw->wiphy,
&hwsim_world_regdom_custom_02);
} else if (i == 4)
hw->wiphy->strict_regulatory = true;
break;
default:
break;
}
err = ieee80211_register_hw(hw);
if (err < 0) {
@ -812,6 +1042,52 @@ static int __init init_mac80211_hwsim(void)
goto failed_hw;
}
/* Work to be done after to ieee80211_register_hw() */
switch (regtest) {
case HWSIM_REGTEST_WORLD_ROAM:
case HWSIM_REGTEST_DISABLED:
break;
case HWSIM_REGTEST_DRIVER_REG_FOLLOW:
if (!i)
regulatory_hint(hw->wiphy, hwsim_alpha2s[0]);
break;
case HWSIM_REGTEST_DRIVER_REG_ALL:
case HWSIM_REGTEST_STRICT_ALL:
regulatory_hint(hw->wiphy, hwsim_alpha2s[0]);
break;
case HWSIM_REGTEST_DIFF_COUNTRY:
if (i < ARRAY_SIZE(hwsim_alpha2s))
regulatory_hint(hw->wiphy, hwsim_alpha2s[i]);
break;
case HWSIM_REGTEST_CUSTOM_WORLD:
case HWSIM_REGTEST_CUSTOM_WORLD_2:
/*
* Nothing to be done for custom world regulatory
* domains after to ieee80211_register_hw
*/
break;
case HWSIM_REGTEST_STRICT_FOLLOW:
if (i == 0)
regulatory_hint(hw->wiphy, hwsim_alpha2s[0]);
break;
case HWSIM_REGTEST_STRICT_AND_DRIVER_REG:
if (i == 0)
regulatory_hint(hw->wiphy, hwsim_alpha2s[0]);
else if (i == 1)
regulatory_hint(hw->wiphy, hwsim_alpha2s[1]);
break;
case HWSIM_REGTEST_ALL:
if (i == 2)
regulatory_hint(hw->wiphy, hwsim_alpha2s[0]);
else if (i == 3)
regulatory_hint(hw->wiphy, hwsim_alpha2s[1]);
else if (i == 4)
regulatory_hint(hw->wiphy, hwsim_alpha2s[2]);
break;
default:
break;
}
printk(KERN_DEBUG "%s: hwaddr %pM registered\n",
wiphy_name(hw->wiphy),
hw->wiphy->perm_addr);

3789
drivers/net/wireless/mwl8k.c Normal file

File diff suppressed because it is too large Load diff

View file

@ -70,6 +70,19 @@ static const char *validate_fw(const struct orinoco_fw_header *hdr, size_t len)
return NULL;
}
#if defined(CONFIG_HERMES_CACHE_FW_ON_INIT) || defined(CONFIG_PM_SLEEP)
static inline const struct firmware *
orinoco_cached_fw_get(struct orinoco_private *priv, bool primary)
{
if (primary)
return priv->cached_pri_fw;
else
return priv->cached_fw;
}
#else
#define orinoco_cached_fw_get(priv, primary) (NULL)
#endif
/* Download either STA or AP firmware into the card. */
static int
orinoco_dl_firmware(struct orinoco_private *priv,
@ -107,7 +120,7 @@ orinoco_dl_firmware(struct orinoco_private *priv,
if (err)
goto free;
if (!priv->cached_fw) {
if (!orinoco_cached_fw_get(priv, false)) {
err = request_firmware(&fw_entry, firmware, priv->dev);
if (err) {
@ -117,7 +130,7 @@ orinoco_dl_firmware(struct orinoco_private *priv,
goto free;
}
} else
fw_entry = priv->cached_fw;
fw_entry = orinoco_cached_fw_get(priv, false);
hdr = (const struct orinoco_fw_header *) fw_entry->data;
@ -170,7 +183,7 @@ orinoco_dl_firmware(struct orinoco_private *priv,
abort:
/* If we requested the firmware, release it. */
if (!priv->cached_fw)
if (!orinoco_cached_fw_get(priv, false))
release_firmware(fw_entry);
free:
@ -273,20 +286,20 @@ symbol_dl_firmware(struct orinoco_private *priv,
int ret;
const struct firmware *fw_entry;
if (!priv->cached_pri_fw) {
if (!orinoco_cached_fw_get(priv, true)) {
if (request_firmware(&fw_entry, fw->pri_fw, priv->dev) != 0) {
printk(KERN_ERR "%s: Cannot find firmware: %s\n",
dev->name, fw->pri_fw);
return -ENOENT;
}
} else
fw_entry = priv->cached_pri_fw;
fw_entry = orinoco_cached_fw_get(priv, true);
/* Load primary firmware */
ret = symbol_dl_image(priv, fw, fw_entry->data,
fw_entry->data + fw_entry->size, 0);
if (!priv->cached_pri_fw)
if (!orinoco_cached_fw_get(priv, true))
release_firmware(fw_entry);
if (ret) {
printk(KERN_ERR "%s: Primary firmware download failed\n",
@ -294,19 +307,19 @@ symbol_dl_firmware(struct orinoco_private *priv,
return ret;
}
if (!priv->cached_fw) {
if (!orinoco_cached_fw_get(priv, false)) {
if (request_firmware(&fw_entry, fw->sta_fw, priv->dev) != 0) {
printk(KERN_ERR "%s: Cannot find firmware: %s\n",
dev->name, fw->sta_fw);
return -ENOENT;
}
} else
fw_entry = priv->cached_fw;
fw_entry = orinoco_cached_fw_get(priv, false);
/* Load secondary firmware */
ret = symbol_dl_image(priv, fw, fw_entry->data,
fw_entry->data + fw_entry->size, 1);
if (!priv->cached_fw)
if (!orinoco_cached_fw_get(priv, false))
release_firmware(fw_entry);
if (ret) {
printk(KERN_ERR "%s: Secondary firmware download failed\n",
@ -340,9 +353,9 @@ int orinoco_download(struct orinoco_private *priv)
return err;
}
#if defined(CONFIG_HERMES_CACHE_FW_ON_INIT) || defined(CONFIG_PM_SLEEP)
void orinoco_cache_fw(struct orinoco_private *priv, int ap)
{
#if defined(CONFIG_HERMES_CACHE_FW_ON_INIT) || defined(CONFIG_PM_SLEEP)
const struct firmware *fw_entry = NULL;
const char *pri_fw;
const char *fw;
@ -362,12 +375,10 @@ void orinoco_cache_fw(struct orinoco_private *priv, int ap)
if (request_firmware(&fw_entry, fw, priv->dev) == 0)
priv->cached_fw = fw_entry;
}
#endif
}
void orinoco_uncache_fw(struct orinoco_private *priv)
{
#if defined(CONFIG_HERMES_CACHE_FW_ON_INIT) || defined(CONFIG_PM_SLEEP)
if (priv->cached_pri_fw)
release_firmware(priv->cached_pri_fw);
if (priv->cached_fw)
@ -375,5 +386,5 @@ void orinoco_uncache_fw(struct orinoco_private *priv)
priv->cached_pri_fw = NULL;
priv->cached_fw = NULL;
#endif
}
#endif

View file

@ -10,7 +10,12 @@ struct orinoco_private;
int orinoco_download(struct orinoco_private *priv);
#if defined(CONFIG_HERMES_CACHE_FW_ON_INIT) || defined(CONFIG_PM_SLEEP)
void orinoco_cache_fw(struct orinoco_private *priv, int ap);
void orinoco_uncache_fw(struct orinoco_private *priv);
#else
#define orinoco_cache_fw(priv, ap) do { } while(0)
#define orinoco_uncache_fw(priv) do { } while (0)
#endif
#endif /* _ORINOCO_FW_H_ */

View file

@ -2580,8 +2580,10 @@ struct net_device
netif_carrier_off(dev);
priv->last_linkstatus = 0xffff;
#if defined(CONFIG_HERMES_CACHE_FW_ON_INIT) || defined(CONFIG_PM_SLEEP)
priv->cached_pri_fw = NULL;
priv->cached_fw = NULL;
#endif
/* Register PM notifiers */
orinoco_register_pm_notifier(priv);

View file

@ -159,9 +159,11 @@ struct orinoco_private {
unsigned int tkip_cm_active:1;
unsigned int key_mgmt:3;
#if defined(CONFIG_HERMES_CACHE_FW_ON_INIT) || defined(CONFIG_PM_SLEEP)
/* Cached in memory firmware to use during ->resume. */
const struct firmware *cached_pri_fw;
const struct firmware *cached_fw;
#endif
struct notifier_block pm_notifier;
};

View file

@ -14,6 +14,10 @@
* published by the Free Software Foundation.
*/
#ifdef CONFIG_MAC80211_LEDS
#include <linux/leds.h>
#endif /* CONFIG_MAC80211_LEDS */
enum p54_control_frame_types {
P54_CONTROL_TYPE_SETUP = 0,
P54_CONTROL_TYPE_SCAN,
@ -112,6 +116,21 @@ enum fw_state {
FW_STATE_RESETTING,
};
#ifdef CONFIG_MAC80211_LEDS
#define P54_LED_MAX_NAME_LEN 31
struct p54_led_dev {
struct ieee80211_hw *hw_dev;
struct led_classdev led_dev;
char name[P54_LED_MAX_NAME_LEN + 1];
unsigned int index;
unsigned int registered;
};
#endif /* CONFIG_MAC80211_LEDS */
struct p54_common {
struct ieee80211_hw *hw;
u32 rx_start;
@ -157,6 +176,12 @@ struct p54_common {
struct completion eeprom_comp;
u8 privacy_caps;
u8 rx_keycache_size;
/* LED management */
#ifdef CONFIG_MAC80211_LEDS
struct p54_led_dev assoc_led;
struct p54_led_dev tx_led;
#endif /* CONFIG_MAC80211_LEDS */
u16 softled_state; /* bit field of glowing LEDs */
};
int p54_rx(struct ieee80211_hw *dev, struct sk_buff *skb);
@ -165,6 +190,7 @@ int p54_parse_firmware(struct ieee80211_hw *dev, const struct firmware *fw);
int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len);
int p54_read_eeprom(struct ieee80211_hw *dev);
struct ieee80211_hw *p54_init_common(size_t priv_data_len);
int p54_register_common(struct ieee80211_hw *dev, struct device *pdev);
void p54_free_common(struct ieee80211_hw *dev);
#endif /* P54_H */

View file

@ -21,6 +21,9 @@
#include <linux/etherdevice.h>
#include <net/mac80211.h>
#ifdef CONFIG_MAC80211_LEDS
#include <linux/leds.h>
#endif /* CONFIG_MAC80211_LEDS */
#include "p54.h"
#include "p54common.h"
@ -735,10 +738,7 @@ static int p54_rx_data(struct ieee80211_hw *dev, struct sk_buff *skb)
return 0;
if (!(hdr->flags & cpu_to_le16(P54_HDR_FLAG_DATA_IN_FCS_GOOD))) {
if (priv->filter_flags & FIF_FCSFAIL)
rx_status.flag |= RX_FLAG_FAILED_FCS_CRC;
else
return 0;
return 0;
}
if (hdr->decrypt_status == P54_DECRYPT_OK)
@ -1680,7 +1680,7 @@ static int p54_setup_mac(struct ieee80211_hw *dev)
mode = P54_FILTER_TYPE_PROMISCUOUS;
break;
default:
mode = P54_FILTER_TYPE_NONE;
mode = P54_FILTER_TYPE_HIBERNATE;
break;
}
@ -1693,7 +1693,7 @@ static int p54_setup_mac(struct ieee80211_hw *dev)
(mode != P54_FILTER_TYPE_PROMISCUOUS))
mode |= P54_FILTER_TYPE_TRANSPARENT;
} else
mode = P54_FILTER_TYPE_RX_DISABLED;
mode = P54_FILTER_TYPE_HIBERNATE;
setup->mac_mode = cpu_to_le16(mode);
memcpy(setup->mac_addr, priv->mac_addr, ETH_ALEN);
@ -1871,7 +1871,7 @@ static int p54_scan(struct ieee80211_hw *dev, u16 mode, u16 dwell)
return -EINVAL;
}
static int p54_set_leds(struct ieee80211_hw *dev, int mode, int link, int act)
static int p54_set_leds(struct ieee80211_hw *dev)
{
struct p54_common *priv = dev->priv;
struct sk_buff *skb;
@ -1882,11 +1882,11 @@ static int p54_set_leds(struct ieee80211_hw *dev, int mode, int link, int act)
if (!skb)
return -ENOMEM;
led = (struct p54_led *)skb_put(skb, sizeof(*led));
led->mode = cpu_to_le16(mode);
led->led_permanent = cpu_to_le16(link);
led->led_temporary = cpu_to_le16(act);
led->duration = cpu_to_le16(1000);
led = (struct p54_led *) skb_put(skb, sizeof(*led));
led->flags = cpu_to_le16(0x0003);
led->mask[0] = led->mask[1] = cpu_to_le16(priv->softled_state);
led->delay[0] = cpu_to_le16(1);
led->delay[1] = cpu_to_le16(0);
priv->tx(dev, skb);
return 0;
}
@ -2070,6 +2070,9 @@ static int p54_start(struct ieee80211_hw *dev)
queue_delayed_work(dev->workqueue, &priv->work, 0);
priv->softled_state = 0;
err = p54_set_leds(dev);
out:
mutex_unlock(&priv->conf_mutex);
return err;
@ -2082,6 +2085,9 @@ static void p54_stop(struct ieee80211_hw *dev)
mutex_lock(&priv->conf_mutex);
priv->mode = NL80211_IFTYPE_UNSPECIFIED;
priv->softled_state = 0;
p54_set_leds(dev);
cancel_delayed_work_sync(&priv->work);
if (priv->cached_beacon)
p54_tx_cancel(dev, priv->cached_beacon);
@ -2119,7 +2125,6 @@ static int p54_add_interface(struct ieee80211_hw *dev,
memcpy(priv->mac_addr, conf->mac_addr, ETH_ALEN);
p54_setup_mac(dev);
p54_set_leds(dev, 1, 0, 0);
mutex_unlock(&priv->conf_mutex);
return 0;
}
@ -2199,8 +2204,6 @@ static int p54_config_interface(struct ieee80211_hw *dev,
goto out;
}
ret = p54_set_leds(dev, 1, !is_multicast_ether_addr(priv->bssid), 0);
out:
mutex_unlock(&priv->conf_mutex);
return ret;
@ -2214,9 +2217,7 @@ static void p54_configure_filter(struct ieee80211_hw *dev,
struct p54_common *priv = dev->priv;
*total_flags &= FIF_PROMISC_IN_BSS |
FIF_OTHER_BSS |
(*total_flags & FIF_PROMISC_IN_BSS ?
FIF_FCSFAIL : 0);
FIF_OTHER_BSS;
priv->filter_flags = *total_flags;
@ -2419,6 +2420,96 @@ static int p54_set_key(struct ieee80211_hw *dev, enum set_key_cmd cmd,
return 0;
}
#ifdef CONFIG_MAC80211_LEDS
static void p54_led_brightness_set(struct led_classdev *led_dev,
enum led_brightness brightness)
{
struct p54_led_dev *led = container_of(led_dev, struct p54_led_dev,
led_dev);
struct ieee80211_hw *dev = led->hw_dev;
struct p54_common *priv = dev->priv;
int err;
/* Don't toggle the LED, when the device is down. */
if (priv->mode == NL80211_IFTYPE_UNSPECIFIED)
return ;
if (brightness != LED_OFF)
priv->softled_state |= BIT(led->index);
else
priv->softled_state &= ~BIT(led->index);
err = p54_set_leds(dev);
if (err && net_ratelimit())
printk(KERN_ERR "%s: failed to update %s LED.\n",
wiphy_name(dev->wiphy), led_dev->name);
}
static int p54_register_led(struct ieee80211_hw *dev,
struct p54_led_dev *led,
unsigned int led_index,
char *name, char *trigger)
{
int err;
if (led->registered)
return -EEXIST;
snprintf(led->name, sizeof(led->name), "p54-%s::%s",
wiphy_name(dev->wiphy), name);
led->hw_dev = dev;
led->index = led_index;
led->led_dev.name = led->name;
led->led_dev.default_trigger = trigger;
led->led_dev.brightness_set = p54_led_brightness_set;
err = led_classdev_register(wiphy_dev(dev->wiphy), &led->led_dev);
if (err)
printk(KERN_ERR "%s: Failed to register %s LED.\n",
wiphy_name(dev->wiphy), name);
else
led->registered = 1;
return err;
}
static int p54_init_leds(struct ieee80211_hw *dev)
{
struct p54_common *priv = dev->priv;
int err;
/*
* TODO:
* Figure out if the EEPROM contains some hints about the number
* of available/programmable LEDs of the device.
* But for now, we can assume that we have two programmable LEDs.
*/
err = p54_register_led(dev, &priv->assoc_led, 0, "assoc",
ieee80211_get_assoc_led_name(dev));
if (err)
return err;
err = p54_register_led(dev, &priv->tx_led, 1, "tx",
ieee80211_get_tx_led_name(dev));
if (err)
return err;
err = p54_set_leds(dev);
return err;
}
static void p54_unregister_leds(struct ieee80211_hw *dev)
{
struct p54_common *priv = dev->priv;
if (priv->tx_led.registered)
led_classdev_unregister(&priv->tx_led.led_dev);
if (priv->assoc_led.registered)
led_classdev_unregister(&priv->assoc_led.led_dev);
}
#endif /* CONFIG_MAC80211_LEDS */
static const struct ieee80211_ops p54_ops = {
.tx = p54_tx,
.start = p54_start,
@ -2452,6 +2543,8 @@ struct ieee80211_hw *p54_init_common(size_t priv_data_len)
priv->basic_rate_mask = 0x15f;
skb_queue_head_init(&priv->tx_queue);
dev->flags = IEEE80211_HW_RX_INCLUDES_FCS |
IEEE80211_HW_SUPPORTS_PS |
IEEE80211_HW_PS_NULLFUNC_STACK |
IEEE80211_HW_SIGNAL_DBM |
IEEE80211_HW_NOISE_DBM;
@ -2489,12 +2582,37 @@ struct ieee80211_hw *p54_init_common(size_t priv_data_len)
}
EXPORT_SYMBOL_GPL(p54_init_common);
int p54_register_common(struct ieee80211_hw *dev, struct device *pdev)
{
int err;
err = ieee80211_register_hw(dev);
if (err) {
dev_err(pdev, "Cannot register device (%d).\n", err);
return err;
}
#ifdef CONFIG_MAC80211_LEDS
err = p54_init_leds(dev);
if (err)
return err;
#endif /* CONFIG_MAC80211_LEDS */
dev_info(pdev, "is registered as '%s'\n", wiphy_name(dev->wiphy));
return 0;
}
EXPORT_SYMBOL_GPL(p54_register_common);
void p54_free_common(struct ieee80211_hw *dev)
{
struct p54_common *priv = dev->priv;
kfree(priv->iq_autocal);
kfree(priv->output_limit);
kfree(priv->curve_data);
#ifdef CONFIG_MAC80211_LEDS
p54_unregister_leds(dev);
#endif /* CONFIG_MAC80211_LEDS */
}
EXPORT_SYMBOL_GPL(p54_free_common);

View file

@ -515,10 +515,9 @@ struct p54_scan_tail_rate {
} __attribute__ ((packed));
struct p54_led {
__le16 mode;
__le16 led_temporary;
__le16 led_permanent;
__le16 duration;
__le16 flags;
__le16 mask[2];
__le16 delay[2];
} __attribute__ ((packed));
struct p54_edcf {

View file

@ -413,8 +413,7 @@ static int p54p_open(struct ieee80211_hw *dev)
err = request_irq(priv->pdev->irq, &p54p_interrupt,
IRQF_SHARED, "p54pci", dev);
if (err) {
printk(KERN_ERR "%s: failed to register IRQ handler\n",
wiphy_name(dev->wiphy));
dev_err(&priv->pdev->dev, "failed to register IRQ handler\n");
return err;
}
@ -476,30 +475,26 @@ static int __devinit p54p_probe(struct pci_dev *pdev,
err = pci_enable_device(pdev);
if (err) {
printk(KERN_ERR "%s (p54pci): Cannot enable new PCI device\n",
pci_name(pdev));
dev_err(&pdev->dev, "Cannot enable new PCI device\n");
return err;
}
mem_addr = pci_resource_start(pdev, 0);
mem_len = pci_resource_len(pdev, 0);
if (mem_len < sizeof(struct p54p_csr)) {
printk(KERN_ERR "%s (p54pci): Too short PCI resources\n",
pci_name(pdev));
dev_err(&pdev->dev, "Too short PCI resources\n");
goto err_disable_dev;
}
err = pci_request_regions(pdev, "p54pci");
if (err) {
printk(KERN_ERR "%s (p54pci): Cannot obtain PCI resources\n",
pci_name(pdev));
dev_err(&pdev->dev, "Cannot obtain PCI resources\n");
goto err_disable_dev;
}
if (pci_set_dma_mask(pdev, DMA_32BIT_MASK) ||
pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK)) {
printk(KERN_ERR "%s (p54pci): No suitable DMA available\n",
pci_name(pdev));
dev_err(&pdev->dev, "No suitable DMA available\n");
goto err_free_reg;
}
@ -511,8 +506,7 @@ static int __devinit p54p_probe(struct pci_dev *pdev,
dev = p54_init_common(sizeof(*priv));
if (!dev) {
printk(KERN_ERR "%s (p54pci): ieee80211 alloc failed\n",
pci_name(pdev));
dev_err(&pdev->dev, "ieee80211 alloc failed\n");
err = -ENOMEM;
goto err_free_reg;
}
@ -525,17 +519,15 @@ static int __devinit p54p_probe(struct pci_dev *pdev,
priv->map = ioremap(mem_addr, mem_len);
if (!priv->map) {
printk(KERN_ERR "%s (p54pci): Cannot map device memory\n",
pci_name(pdev));
err = -EINVAL; // TODO: use a better error code?
dev_err(&pdev->dev, "Cannot map device memory\n");
err = -ENOMEM;
goto err_free_dev;
}
priv->ring_control = pci_alloc_consistent(pdev, sizeof(*priv->ring_control),
&priv->ring_control_dma);
if (!priv->ring_control) {
printk(KERN_ERR "%s (p54pci): Cannot allocate rings\n",
pci_name(pdev));
dev_err(&pdev->dev, "Cannot allocate rings\n");
err = -ENOMEM;
goto err_iounmap;
}
@ -549,8 +541,7 @@ static int __devinit p54p_probe(struct pci_dev *pdev,
err = request_firmware(&priv->firmware, "isl3886pci",
&priv->pdev->dev);
if (err) {
printk(KERN_ERR "%s (p54pci): cannot find firmware "
"(isl3886pci)\n", pci_name(priv->pdev));
dev_err(&pdev->dev, "Cannot find firmware (isl3886pci)\n");
err = request_firmware(&priv->firmware, "isl3886",
&priv->pdev->dev);
if (err)
@ -565,12 +556,9 @@ static int __devinit p54p_probe(struct pci_dev *pdev,
if (err)
goto err_free_common;
err = ieee80211_register_hw(dev);
if (err) {
printk(KERN_ERR "%s (p54pci): Cannot register netdevice\n",
pci_name(pdev));
err = p54_register_common(dev, &pdev->dev);
if (err)
goto err_free_common;
}
return 0;

View file

@ -694,15 +694,10 @@ static int __devinit p54spi_probe(struct spi_device *spi)
if (ret)
goto err_free_common;
ret = ieee80211_register_hw(hw);
if (ret) {
dev_err(&priv->spi->dev, "unable to register "
"mac80211 hw: %d", ret);
ret = p54_register_common(hw, &priv->spi->dev);
if (ret)
goto err_free_common;
}
dev_info(&priv->spi->dev, "device is bound to %s\n",
wiphy_name(hw->wiphy));
return 0;
err_free_common:

View file

@ -976,11 +976,9 @@ static int __devinit p54u_probe(struct usb_interface *intf,
if (err)
goto err_free_dev;
err = ieee80211_register_hw(dev);
if (err) {
dev_err(&udev->dev, "(p54usb) Cannot register netdevice\n");
err = p54_register_common(dev, &udev->dev);
if (err)
goto err_free_dev;
}
return 0;
@ -1024,6 +1022,7 @@ static struct usb_driver p54u_driver = {
.disconnect = p54u_disconnect,
.pre_reset = p54u_pre_reset,
.post_reset = p54u_post_reset,
.soft_unbind = 1,
};
static int __init p54u_init(void)

File diff suppressed because it is too large Load diff

View file

@ -150,6 +150,17 @@
* @NL80211_CMD_SCAN_ABORTED: scan was aborted, for unspecified reasons,
* partial scan results may be available
*
* @NL80211_CMD_REG_CHANGE: indicates to userspace the regulatory domain
* has been changed and provides details of the request information
* that caused the change such as who initiated the regulatory request
* (%NL80211_ATTR_REG_INITIATOR), the wiphy_idx
* (%NL80211_ATTR_REG_ALPHA2) on which the request was made from if
* the initiator was %NL80211_REGDOM_SET_BY_COUNTRY_IE or
* %NL80211_REGDOM_SET_BY_DRIVER, the type of regulatory domain
* set (%NL80211_ATTR_REG_TYPE), if the type of regulatory domain is
* %NL80211_REG_TYPE_COUNTRY the alpha2 to which we have moved on
* to (%NL80211_ATTR_REG_ALPHA2).
*
* @NL80211_CMD_MAX: highest used command number
* @__NL80211_CMD_AFTER_LAST: internal use
*/
@ -204,6 +215,8 @@ enum nl80211_commands {
NL80211_CMD_NEW_SCAN_RESULTS,
NL80211_CMD_SCAN_ABORTED,
NL80211_CMD_REG_CHANGE,
/* add new commands above here */
/* used to define NL80211_CMD_MAX below */
@ -218,6 +231,8 @@ enum nl80211_commands {
#define NL80211_CMD_SET_BSS NL80211_CMD_SET_BSS
#define NL80211_CMD_SET_MGMT_EXTRA_IE NL80211_CMD_SET_MGMT_EXTRA_IE
#define NL80211_CMD_REG_CHANGE NL80211_CMD_REG_CHANGE
/**
* enum nl80211_attrs - nl80211 netlink attributes
*
@ -329,6 +344,11 @@ enum nl80211_commands {
* messages carried the same generation number)
* @NL80211_ATTR_BSS: scan result BSS
*
* @NL80211_ATTR_REG_INITIATOR: indicates who requested the regulatory domain
* currently in effect. This could be any of the %NL80211_REGDOM_SET_BY_*
* @NL80211_ATTR_REG_TYPE: indicates the type of the regulatory domain currently
* set. This can be one of the nl80211_reg_type (%NL80211_REGDOM_TYPE_*)
*
* @NL80211_ATTR_MAX: highest attribute number currently defined
* @__NL80211_ATTR_AFTER_LAST: internal use
*/
@ -403,6 +423,9 @@ enum nl80211_attrs {
NL80211_ATTR_SCAN_GENERATION,
NL80211_ATTR_BSS,
NL80211_ATTR_REG_INITIATOR,
NL80211_ATTR_REG_TYPE,
/* add attributes here, update the policy in nl80211.c */
__NL80211_ATTR_AFTER_LAST,
@ -420,6 +443,8 @@ enum nl80211_attrs {
#define NL80211_ATTR_WIPHY_CHANNEL_TYPE NL80211_ATTR_WIPHY_CHANNEL_TYPE
#define NL80211_ATTR_MGMT_SUBTYPE NL80211_ATTR_MGMT_SUBTYPE
#define NL80211_ATTR_IE NL80211_ATTR_IE
#define NL80211_ATTR_REG_INITIATOR NL80211_ATTR_REG_INITIATOR
#define NL80211_ATTR_REG_TYPE NL80211_ATTR_REG_TYPE
#define NL80211_MAX_SUPP_RATES 32
#define NL80211_MAX_SUPP_REG_RULES 32
@ -672,6 +697,48 @@ enum nl80211_bitrate_attr {
NL80211_BITRATE_ATTR_MAX = __NL80211_BITRATE_ATTR_AFTER_LAST - 1
};
/**
* enum nl80211_initiator - Indicates the initiator of a reg domain request
* @NL80211_REGDOM_SET_BY_CORE: Core queried CRDA for a dynamic world
* regulatory domain.
* @NL80211_REGDOM_SET_BY_USER: User asked the wireless core to set the
* regulatory domain.
* @NL80211_REGDOM_SET_BY_DRIVER: a wireless drivers has hinted to the
* wireless core it thinks its knows the regulatory domain we should be in.
* @NL80211_REGDOM_SET_BY_COUNTRY_IE: the wireless core has received an
* 802.11 country information element with regulatory information it
* thinks we should consider.
*/
enum nl80211_reg_initiator {
NL80211_REGDOM_SET_BY_CORE,
NL80211_REGDOM_SET_BY_USER,
NL80211_REGDOM_SET_BY_DRIVER,
NL80211_REGDOM_SET_BY_COUNTRY_IE,
};
/**
* enum nl80211_reg_type - specifies the type of regulatory domain
* @NL80211_REGDOM_TYPE_COUNTRY: the regulatory domain set is one that pertains
* to a specific country. When this is set you can count on the
* ISO / IEC 3166 alpha2 country code being valid.
* @NL80211_REGDOM_TYPE_WORLD: the regulatory set domain is the world regulatory
* domain.
* @NL80211_REGDOM_TYPE_CUSTOM_WORLD: the regulatory domain set is a custom
* driver specific world regulatory domain. These do not apply system-wide
* and are only applicable to the individual devices which have requested
* them to be applied.
* @NL80211_REGDOM_TYPE_INTERSECTION: the regulatory domain set is the product
* of an intersection between two regulatory domains -- the previously
* set regulatory domain on the system and the last accepted regulatory
* domain request to be processed.
*/
enum nl80211_reg_type {
NL80211_REGDOM_TYPE_COUNTRY,
NL80211_REGDOM_TYPE_WORLD,
NL80211_REGDOM_TYPE_CUSTOM_WORLD,
NL80211_REGDOM_TYPE_INTERSECTION,
};
/**
* enum nl80211_reg_rule_attr - regulatory rule attributes
* @NL80211_ATTR_REG_RULE_FLAGS: a set of flags which specify additional

View file

@ -348,31 +348,10 @@ struct bss_parameters {
u8 basic_rates_len;
};
/**
* enum reg_set_by - Indicates who is trying to set the regulatory domain
* @REGDOM_SET_BY_INIT: regulatory domain was set by initialization. We will be
* using a static world regulatory domain by default.
* @REGDOM_SET_BY_CORE: Core queried CRDA for a dynamic world regulatory domain.
* @REGDOM_SET_BY_USER: User asked the wireless core to set the
* regulatory domain.
* @REGDOM_SET_BY_DRIVER: a wireless drivers has hinted to the wireless core
* it thinks its knows the regulatory domain we should be in.
* @REGDOM_SET_BY_COUNTRY_IE: the wireless core has received an 802.11 country
* information element with regulatory information it thinks we
* should consider.
*/
enum reg_set_by {
REGDOM_SET_BY_INIT,
REGDOM_SET_BY_CORE,
REGDOM_SET_BY_USER,
REGDOM_SET_BY_DRIVER,
REGDOM_SET_BY_COUNTRY_IE,
};
/**
* enum environment_cap - Environment parsed from country IE
* @ENVIRON_ANY: indicates country IE applies to both indoor and
* outdoor operation.
* outdoor operation.
* @ENVIRON_INDOOR: indicates country IE applies only to indoor operation
* @ENVIRON_OUTDOOR: indicates country IE applies only to outdoor operation
*/
@ -391,7 +370,7 @@ enum environment_cap {
* and potentially inform users of which devices specifically
* cased the conflicts.
* @initiator: indicates who sent this request, could be any of
* of those set in reg_set_by, %REGDOM_SET_BY_*
* of those set in nl80211_reg_initiator (%NL80211_REGDOM_SET_BY_*)
* @alpha2: the ISO / IEC 3166 alpha2 country code of the requested
* regulatory domain. We have a few special codes:
* 00 - World regulatory domain
@ -408,7 +387,7 @@ enum environment_cap {
*/
struct regulatory_request {
int wiphy_idx;
enum reg_set_by initiator;
enum nl80211_reg_initiator initiator;
char alpha2[2];
bool intersect;
u32 country_ie_checksum;

View file

@ -972,6 +972,7 @@ int ieee80211_sta_set_extra_ie(struct ieee80211_sub_if_data *sdata,
char *ie, size_t len);
void ieee80211_mlme_notify_scan_completed(struct ieee80211_local *local);
void ieee80211_scan_failed(struct ieee80211_local *local);
int ieee80211_start_scan(struct ieee80211_sub_if_data *scan_sdata,
struct cfg80211_scan_request *req);
struct ieee80211_bss *

View file

@ -369,6 +369,18 @@ static int ieee80211_stop(struct net_device *dev)
rcu_read_unlock();
/*
* Announce that we are leaving the network, in case we are a
* station interface type. This must be done before removing
* all stations associated with sta_info_flush, otherwise STA
* information will be gone and no announce being done.
*/
if (sdata->vif.type == NL80211_IFTYPE_STATION) {
if (sdata->u.mgd.state != IEEE80211_STA_MLME_DISABLED)
ieee80211_sta_deauthenticate(sdata,
WLAN_REASON_DEAUTH_LEAVING);
}
/*
* Remove all stations associated with this interface.
*
@ -454,10 +466,6 @@ static int ieee80211_stop(struct net_device *dev)
netif_addr_unlock_bh(local->mdev);
break;
case NL80211_IFTYPE_STATION:
/* Announce that we are leaving the network. */
if (sdata->u.mgd.state != IEEE80211_STA_MLME_DISABLED)
ieee80211_sta_deauthenticate(sdata,
WLAN_REASON_DEAUTH_LEAVING);
memset(sdata->u.mgd.bssid, 0, ETH_ALEN);
del_timer_sync(&sdata->u.mgd.chswitch_timer);
del_timer_sync(&sdata->u.mgd.timer);

View file

@ -417,9 +417,6 @@ static void ieee80211_sta_wmm_params(struct ieee80211_local *local,
memset(&params, 0, sizeof(params));
if (!local->ops->conf_tx)
return;
local->wmm_acm = 0;
for (; left >= 4; left -= 4, pos += 4) {
int aci = (pos[0] >> 5) & 0x03;
@ -427,26 +424,26 @@ static void ieee80211_sta_wmm_params(struct ieee80211_local *local,
int queue;
switch (aci) {
case 1:
case 1: /* AC_BK */
queue = 3;
if (acm)
local->wmm_acm |= BIT(0) | BIT(3);
local->wmm_acm |= BIT(1) | BIT(2); /* BK/- */
break;
case 2:
case 2: /* AC_VI */
queue = 1;
if (acm)
local->wmm_acm |= BIT(4) | BIT(5);
local->wmm_acm |= BIT(4) | BIT(5); /* CL/VI */
break;
case 3:
case 3: /* AC_VO */
queue = 0;
if (acm)
local->wmm_acm |= BIT(6) | BIT(7);
local->wmm_acm |= BIT(6) | BIT(7); /* VO/NC */
break;
case 0:
case 0: /* AC_BE */
default:
queue = 2;
if (acm)
local->wmm_acm |= BIT(1) | BIT(2);
local->wmm_acm |= BIT(0) | BIT(3); /* BE/EE */
break;
}
@ -460,9 +457,8 @@ static void ieee80211_sta_wmm_params(struct ieee80211_local *local,
local->mdev->name, queue, aci, acm, params.aifs, params.cw_min,
params.cw_max, params.txop);
#endif
/* TODO: handle ACM (block TX, fallback to next lowest allowed
* AC for now) */
if (local->ops->conf_tx(local_to_hw(local), queue, &params)) {
if (local->ops->conf_tx &&
local->ops->conf_tx(local_to_hw(local), queue, &params)) {
printk(KERN_DEBUG "%s: failed to set TX queue "
"parameters for queue %d\n", local->mdev->name, queue);
}
@ -1724,7 +1720,10 @@ static int ieee80211_sta_config_auth(struct ieee80211_sub_if_data *sdata)
local->int_scan_req.ssids[0].ssid_len = 0;
else
local->int_scan_req.ssids[0].ssid_len = ifmgd->ssid_len;
ieee80211_start_scan(sdata, &local->int_scan_req);
if (ieee80211_start_scan(sdata, &local->int_scan_req))
ieee80211_scan_failed(local);
ifmgd->state = IEEE80211_STA_MLME_AUTHENTICATE;
set_bit(IEEE80211_STA_REQ_AUTH, &ifmgd->request);
} else {
@ -1761,7 +1760,14 @@ static void ieee80211_sta_work(struct work_struct *work)
ifmgd->state != IEEE80211_STA_MLME_AUTHENTICATE &&
ifmgd->state != IEEE80211_STA_MLME_ASSOCIATE &&
test_and_clear_bit(IEEE80211_STA_REQ_SCAN, &ifmgd->request)) {
ieee80211_start_scan(sdata, local->scan_req);
/*
* The call to ieee80211_start_scan can fail but ieee80211_request_scan
* (which queued ieee80211_sta_work) did not return an error. Thus, call
* ieee80211_scan_failed here if ieee80211_start_scan fails in order to
* notify the scan requester.
*/
if (ieee80211_start_scan(sdata, local->scan_req))
ieee80211_scan_failed(local);
return;
}

View file

@ -202,6 +202,18 @@ ieee80211_scan_rx(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb,
return RX_QUEUED;
}
void ieee80211_scan_failed(struct ieee80211_local *local)
{
if (WARN_ON(!local->scan_req))
return;
/* notify cfg80211 about the failed scan */
if (local->scan_req != &local->int_scan_req)
cfg80211_scan_done(local->scan_req, true);
local->scan_req = NULL;
}
void ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted)
{
struct ieee80211_local *local = hw_to_local(hw);

View file

@ -99,10 +99,13 @@ static u16 classify80211(struct ieee80211_local *local, struct sk_buff *skb)
/* in case we are a client verify acm is not set for this ac */
while (unlikely(local->wmm_acm & BIT(skb->priority))) {
if (wme_downgrade_ac(skb)) {
/* The old code would drop the packet in this
* case.
/*
* This should not really happen. The AP has marked all
* lower ACs to require admission control which is not
* a reasonable configuration. Allow the frame to be
* transmitted using AC_BK as a workaround.
*/
return 0;
break;
}
}

View file

@ -350,7 +350,7 @@ int wiphy_register(struct wiphy *wiphy)
mutex_lock(&cfg80211_mutex);
/* set up regulatory info */
wiphy_update_regulatory(wiphy, REGDOM_SET_BY_CORE);
wiphy_update_regulatory(wiphy, NL80211_REGDOM_SET_BY_CORE);
res = device_add(&drv->wiphy.dev);
if (res)
@ -365,6 +365,17 @@ int wiphy_register(struct wiphy *wiphy)
if (IS_ERR(drv->wiphy.debugfsdir))
drv->wiphy.debugfsdir = NULL;
if (wiphy->custom_regulatory) {
struct regulatory_request request;
request.wiphy_idx = get_wiphy_idx(wiphy);
request.initiator = NL80211_REGDOM_SET_BY_DRIVER;
request.alpha2[0] = '9';
request.alpha2[1] = '9';
nl80211_send_reg_change_event(&request);
}
res = 0;
out_unlock:
mutex_unlock(&cfg80211_mutex);

View file

@ -136,7 +136,8 @@ extern int cfg80211_dev_rename(struct cfg80211_registered_device *drv,
char *newname);
void ieee80211_set_bitrate_flags(struct wiphy *wiphy);
void wiphy_update_regulatory(struct wiphy *wiphy, enum reg_set_by setby);
void wiphy_update_regulatory(struct wiphy *wiphy,
enum nl80211_reg_initiator setby);
void cfg80211_bss_expire(struct cfg80211_registered_device *dev);
void cfg80211_bss_age(struct cfg80211_registered_device *dev,

View file

@ -2739,6 +2739,9 @@ static struct genl_multicast_group nl80211_config_mcgrp = {
static struct genl_multicast_group nl80211_scan_mcgrp = {
.name = "scan",
};
static struct genl_multicast_group nl80211_regulatory_mcgrp = {
.name = "regulatory",
};
/* notification functions */
@ -2818,6 +2821,61 @@ void nl80211_send_scan_aborted(struct cfg80211_registered_device *rdev,
genlmsg_multicast(msg, 0, nl80211_scan_mcgrp.id, GFP_KERNEL);
}
/*
* This can happen on global regulatory changes or device specific settings
* based on custom world regulatory domains.
*/
void nl80211_send_reg_change_event(struct regulatory_request *request)
{
struct sk_buff *msg;
void *hdr;
msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
if (!msg)
return;
hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_REG_CHANGE);
if (!hdr) {
nlmsg_free(msg);
return;
}
/* Userspace can always count this one always being set */
NLA_PUT_U8(msg, NL80211_ATTR_REG_INITIATOR, request->initiator);
if (request->alpha2[0] == '0' && request->alpha2[1] == '0')
NLA_PUT_U8(msg, NL80211_ATTR_REG_TYPE,
NL80211_REGDOM_TYPE_WORLD);
else if (request->alpha2[0] == '9' && request->alpha2[1] == '9')
NLA_PUT_U8(msg, NL80211_ATTR_REG_TYPE,
NL80211_REGDOM_TYPE_CUSTOM_WORLD);
else if ((request->alpha2[0] == '9' && request->alpha2[1] == '8') ||
request->intersect)
NLA_PUT_U8(msg, NL80211_ATTR_REG_TYPE,
NL80211_REGDOM_TYPE_INTERSECTION);
else {
NLA_PUT_U8(msg, NL80211_ATTR_REG_TYPE,
NL80211_REGDOM_TYPE_COUNTRY);
NLA_PUT_STRING(msg, NL80211_ATTR_REG_ALPHA2, request->alpha2);
}
if (wiphy_idx_valid(request->wiphy_idx))
NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, request->wiphy_idx);
if (genlmsg_end(msg, hdr) < 0) {
nlmsg_free(msg);
return;
}
genlmsg_multicast(msg, 0, nl80211_regulatory_mcgrp.id, GFP_KERNEL);
return;
nla_put_failure:
genlmsg_cancel(msg, hdr);
nlmsg_free(msg);
}
/* initialisation/exit functions */
int nl80211_init(void)
@ -2842,6 +2900,10 @@ int nl80211_init(void)
if (err)
goto err_out;
err = genl_register_mc_group(&nl80211_fam, &nl80211_regulatory_mcgrp);
if (err)
goto err_out;
return 0;
err_out:
genl_unregister_family(&nl80211_fam);

View file

@ -11,6 +11,7 @@ extern void nl80211_send_scan_done(struct cfg80211_registered_device *rdev,
struct net_device *netdev);
extern void nl80211_send_scan_aborted(struct cfg80211_registered_device *rdev,
struct net_device *netdev);
extern void nl80211_send_reg_change_event(struct regulatory_request *request);
#else
static inline int nl80211_init(void)
{
@ -31,6 +32,10 @@ static inline void nl80211_send_scan_aborted(
struct cfg80211_registered_device *rdev,
struct net_device *netdev)
{}
static inline void
nl80211_send_reg_change_event(struct regulatory_request *request)
{
}
#endif /* CONFIG_NL80211 */
#endif /* __NET_WIRELESS_NL80211_H */

View file

@ -41,6 +41,7 @@
#include <net/cfg80211.h>
#include "core.h"
#include "reg.h"
#include "nl80211.h"
/* Receipt of information from last regulatory request */
static struct regulatory_request *last_request;
@ -86,20 +87,31 @@ struct reg_beacon {
/* We keep a static world regulatory domain in case of the absence of CRDA */
static const struct ieee80211_regdomain world_regdom = {
.n_reg_rules = 3,
.n_reg_rules = 5,
.alpha2 = "00",
.reg_rules = {
/* IEEE 802.11b/g, channels 1..11 */
REG_RULE(2412-10, 2462+10, 40, 6, 20, 0),
/* IEEE 802.11a, channel 36..48 */
REG_RULE(5180-10, 5240+10, 40, 6, 23,
/* IEEE 802.11b/g, channels 12..13. No HT40
* channel fits here. */
REG_RULE(2467-10, 2472+10, 20, 6, 20,
NL80211_RRF_PASSIVE_SCAN |
NL80211_RRF_NO_IBSS),
/* IEEE 802.11 channel 14 - Only JP enables
* this and for 802.11b only */
REG_RULE(2484-10, 2484+10, 20, 6, 20,
NL80211_RRF_PASSIVE_SCAN |
NL80211_RRF_NO_IBSS |
NL80211_RRF_NO_OFDM),
/* IEEE 802.11a, channel 36..48 */
REG_RULE(5180-10, 5240+10, 40, 6, 20,
NL80211_RRF_PASSIVE_SCAN |
NL80211_RRF_NO_IBSS),
/* NB: 5260 MHz - 5700 MHz requies DFS */
/* IEEE 802.11a, channel 149..165 */
REG_RULE(5745-10, 5825+10, 40, 6, 23,
REG_RULE(5745-10, 5825+10, 40, 6, 20,
NL80211_RRF_PASSIVE_SCAN |
NL80211_RRF_NO_IBSS),
}
@ -846,8 +858,8 @@ static int freq_reg_info_regd(struct wiphy *wiphy,
* Follow the driver's regulatory domain, if present, unless a country
* IE has been processed or a user wants to help complaince further
*/
if (last_request->initiator != REGDOM_SET_BY_COUNTRY_IE &&
last_request->initiator != REGDOM_SET_BY_USER &&
if (last_request->initiator != NL80211_REGDOM_SET_BY_COUNTRY_IE &&
last_request->initiator != NL80211_REGDOM_SET_BY_USER &&
wiphy->regd)
regd = wiphy->regd;
@ -932,7 +944,8 @@ static void handle_channel(struct wiphy *wiphy, enum ieee80211_band band,
* http://tinyurl.com/11d-clarification
*/
if (r == -ERANGE &&
last_request->initiator == REGDOM_SET_BY_COUNTRY_IE) {
last_request->initiator ==
NL80211_REGDOM_SET_BY_COUNTRY_IE) {
#ifdef CONFIG_CFG80211_REG_DEBUG
printk(KERN_DEBUG "cfg80211: Leaving channel %d MHz "
"intact on %s - no rule found in band on "
@ -945,7 +958,8 @@ static void handle_channel(struct wiphy *wiphy, enum ieee80211_band band,
* for the band so we respect its band definitions
*/
#ifdef CONFIG_CFG80211_REG_DEBUG
if (last_request->initiator == REGDOM_SET_BY_COUNTRY_IE)
if (last_request->initiator ==
NL80211_REGDOM_SET_BY_COUNTRY_IE)
printk(KERN_DEBUG "cfg80211: Disabling "
"channel %d MHz on %s due to "
"Country IE\n",
@ -959,7 +973,7 @@ static void handle_channel(struct wiphy *wiphy, enum ieee80211_band band,
power_rule = &reg_rule->power_rule;
if (last_request->initiator == REGDOM_SET_BY_DRIVER &&
if (last_request->initiator == NL80211_REGDOM_SET_BY_DRIVER &&
request_wiphy && request_wiphy == wiphy &&
request_wiphy->strict_regulatory) {
/*
@ -1000,11 +1014,12 @@ static void handle_band(struct wiphy *wiphy, enum ieee80211_band band)
handle_channel(wiphy, band, i);
}
static bool ignore_reg_update(struct wiphy *wiphy, enum reg_set_by setby)
static bool ignore_reg_update(struct wiphy *wiphy,
enum nl80211_reg_initiator initiator)
{
if (!last_request)
return true;
if (setby == REGDOM_SET_BY_CORE &&
if (initiator == NL80211_REGDOM_SET_BY_CORE &&
wiphy->custom_regulatory)
return true;
/*
@ -1017,12 +1032,12 @@ static bool ignore_reg_update(struct wiphy *wiphy, enum reg_set_by setby)
return false;
}
static void update_all_wiphy_regulatory(enum reg_set_by setby)
static void update_all_wiphy_regulatory(enum nl80211_reg_initiator initiator)
{
struct cfg80211_registered_device *drv;
list_for_each_entry(drv, &cfg80211_drv_list, list)
wiphy_update_regulatory(&drv->wiphy, setby);
wiphy_update_regulatory(&drv->wiphy, initiator);
}
static void handle_reg_beacon(struct wiphy *wiphy,
@ -1113,7 +1128,7 @@ static bool reg_is_world_roaming(struct wiphy *wiphy)
if (is_world_regdom(cfg80211_regdomain->alpha2) ||
(wiphy->regd && is_world_regdom(wiphy->regd->alpha2)))
return true;
if (last_request->initiator != REGDOM_SET_BY_COUNTRY_IE &&
if (last_request->initiator != NL80211_REGDOM_SET_BY_COUNTRY_IE &&
wiphy->custom_regulatory)
return true;
return false;
@ -1127,11 +1142,12 @@ static void reg_process_beacons(struct wiphy *wiphy)
wiphy_update_beacon_reg(wiphy);
}
void wiphy_update_regulatory(struct wiphy *wiphy, enum reg_set_by setby)
void wiphy_update_regulatory(struct wiphy *wiphy,
enum nl80211_reg_initiator initiator)
{
enum ieee80211_band band;
if (ignore_reg_update(wiphy, setby))
if (ignore_reg_update(wiphy, initiator))
goto out;
for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
if (wiphy->bands[band])
@ -1244,17 +1260,16 @@ static int ignore_request(struct wiphy *wiphy,
return 0;
switch (pending_request->initiator) {
case REGDOM_SET_BY_INIT:
case NL80211_REGDOM_SET_BY_CORE:
return -EINVAL;
case REGDOM_SET_BY_CORE:
return -EINVAL;
case REGDOM_SET_BY_COUNTRY_IE:
case NL80211_REGDOM_SET_BY_COUNTRY_IE:
last_wiphy = wiphy_idx_to_wiphy(last_request->wiphy_idx);
if (unlikely(!is_an_alpha2(pending_request->alpha2)))
return -EINVAL;
if (last_request->initiator == REGDOM_SET_BY_COUNTRY_IE) {
if (last_request->initiator ==
NL80211_REGDOM_SET_BY_COUNTRY_IE) {
if (last_wiphy != wiphy) {
/*
* Two cards with two APs claiming different
@ -1275,8 +1290,8 @@ static int ignore_request(struct wiphy *wiphy,
return -EALREADY;
}
return REG_INTERSECT;
case REGDOM_SET_BY_DRIVER:
if (last_request->initiator == REGDOM_SET_BY_CORE) {
case NL80211_REGDOM_SET_BY_DRIVER:
if (last_request->initiator == NL80211_REGDOM_SET_BY_CORE) {
if (is_old_static_regdom(cfg80211_regdomain))
return 0;
if (regdom_changes(pending_request->alpha2))
@ -1289,28 +1304,28 @@ static int ignore_request(struct wiphy *wiphy,
* back in or if you add a new device for which the previously
* loaded card also agrees on the regulatory domain.
*/
if (last_request->initiator == REGDOM_SET_BY_DRIVER &&
if (last_request->initiator == NL80211_REGDOM_SET_BY_DRIVER &&
!regdom_changes(pending_request->alpha2))
return -EALREADY;
return REG_INTERSECT;
case REGDOM_SET_BY_USER:
if (last_request->initiator == REGDOM_SET_BY_COUNTRY_IE)
case NL80211_REGDOM_SET_BY_USER:
if (last_request->initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE)
return REG_INTERSECT;
/*
* If the user knows better the user should set the regdom
* to their country before the IE is picked up
*/
if (last_request->initiator == REGDOM_SET_BY_USER &&
if (last_request->initiator == NL80211_REGDOM_SET_BY_USER &&
last_request->intersect)
return -EOPNOTSUPP;
/*
* Process user requests only after previous user/driver/core
* requests have been processed
*/
if (last_request->initiator == REGDOM_SET_BY_CORE ||
last_request->initiator == REGDOM_SET_BY_DRIVER ||
last_request->initiator == REGDOM_SET_BY_USER) {
if (last_request->initiator == NL80211_REGDOM_SET_BY_CORE ||
last_request->initiator == NL80211_REGDOM_SET_BY_DRIVER ||
last_request->initiator == NL80211_REGDOM_SET_BY_USER) {
if (regdom_changes(last_request->alpha2))
return -EAGAIN;
}
@ -1350,7 +1365,8 @@ static int __regulatory_hint(struct wiphy *wiphy,
r = ignore_request(wiphy, pending_request);
if (r == REG_INTERSECT) {
if (pending_request->initiator == REGDOM_SET_BY_DRIVER) {
if (pending_request->initiator ==
NL80211_REGDOM_SET_BY_DRIVER) {
r = reg_copy_regd(&wiphy->regd, cfg80211_regdomain);
if (r) {
kfree(pending_request);
@ -1365,7 +1381,8 @@ static int __regulatory_hint(struct wiphy *wiphy,
* wiphy
*/
if (r == -EALREADY &&
pending_request->initiator == REGDOM_SET_BY_DRIVER) {
pending_request->initiator ==
NL80211_REGDOM_SET_BY_DRIVER) {
r = reg_copy_regd(&wiphy->regd, cfg80211_regdomain);
if (r) {
kfree(pending_request);
@ -1387,8 +1404,16 @@ new_request:
pending_request = NULL;
/* When r == REG_INTERSECT we do need to call CRDA */
if (r < 0)
if (r < 0) {
/*
* Since CRDA will not be called in this case as we already
* have applied the requested regulatory domain before we just
* inform userspace we have processed the request
*/
if (r == -EALREADY)
nl80211_send_reg_change_event(last_request);
return r;
}
/*
* Note: When CONFIG_WIRELESS_OLD_REGULATORY is enabled
@ -1416,7 +1441,7 @@ static void reg_process_hint(struct regulatory_request *reg_request)
if (wiphy_idx_valid(reg_request->wiphy_idx))
wiphy = wiphy_idx_to_wiphy(reg_request->wiphy_idx);
if (reg_request->initiator == REGDOM_SET_BY_DRIVER &&
if (reg_request->initiator == NL80211_REGDOM_SET_BY_DRIVER &&
!wiphy) {
kfree(reg_request);
goto out;
@ -1430,7 +1455,7 @@ out:
mutex_unlock(&cfg80211_mutex);
}
/* Processes regulatory hints, this is all the REGDOM_SET_BY_* */
/* Processes regulatory hints, this is all the NL80211_REGDOM_SET_BY_* */
static void reg_process_pending_hints(void)
{
struct regulatory_request *reg_request;
@ -1514,7 +1539,7 @@ static int regulatory_hint_core(const char *alpha2)
request->alpha2[0] = alpha2[0];
request->alpha2[1] = alpha2[1];
request->initiator = REGDOM_SET_BY_CORE;
request->initiator = NL80211_REGDOM_SET_BY_CORE;
queue_regulatory_request(request);
@ -1535,7 +1560,7 @@ int regulatory_hint_user(const char *alpha2)
request->wiphy_idx = WIPHY_IDX_STALE;
request->alpha2[0] = alpha2[0];
request->alpha2[1] = alpha2[1];
request->initiator = REGDOM_SET_BY_USER,
request->initiator = NL80211_REGDOM_SET_BY_USER,
queue_regulatory_request(request);
@ -1561,7 +1586,7 @@ int regulatory_hint(struct wiphy *wiphy, const char *alpha2)
request->alpha2[0] = alpha2[0];
request->alpha2[1] = alpha2[1];
request->initiator = REGDOM_SET_BY_DRIVER;
request->initiator = NL80211_REGDOM_SET_BY_DRIVER;
queue_regulatory_request(request);
@ -1710,7 +1735,7 @@ void regulatory_hint_11d(struct wiphy *wiphy,
request->wiphy_idx = get_wiphy_idx(wiphy);
request->alpha2[0] = rd->alpha2[0];
request->alpha2[1] = rd->alpha2[1];
request->initiator = REGDOM_SET_BY_COUNTRY_IE;
request->initiator = NL80211_REGDOM_SET_BY_COUNTRY_IE;
request->country_ie_checksum = checksum;
request->country_ie_env = env;
@ -1818,7 +1843,8 @@ static void print_regdomain(const struct ieee80211_regdomain *rd)
if (is_intersected_alpha2(rd->alpha2)) {
if (last_request->initiator == REGDOM_SET_BY_COUNTRY_IE) {
if (last_request->initiator ==
NL80211_REGDOM_SET_BY_COUNTRY_IE) {
struct cfg80211_registered_device *drv;
drv = cfg80211_drv_by_wiphy_idx(
last_request->wiphy_idx);
@ -1910,7 +1936,7 @@ static int __set_regdom(const struct ieee80211_regdomain *rd)
* rd is non static (it means CRDA was present and was used last)
* and the pending request came in from a country IE
*/
if (last_request->initiator != REGDOM_SET_BY_COUNTRY_IE) {
if (last_request->initiator != NL80211_REGDOM_SET_BY_COUNTRY_IE) {
/*
* If someone else asked us to change the rd lets only bother
* checking if the alpha2 changes if CRDA was already called
@ -1942,7 +1968,7 @@ static int __set_regdom(const struct ieee80211_regdomain *rd)
if (!last_request->intersect) {
int r;
if (last_request->initiator != REGDOM_SET_BY_DRIVER) {
if (last_request->initiator != NL80211_REGDOM_SET_BY_DRIVER) {
reset_regdomains();
cfg80211_regdomain = rd;
return 0;
@ -1966,7 +1992,7 @@ static int __set_regdom(const struct ieee80211_regdomain *rd)
/* Intersection requires a bit more work */
if (last_request->initiator != REGDOM_SET_BY_COUNTRY_IE) {
if (last_request->initiator != NL80211_REGDOM_SET_BY_COUNTRY_IE) {
intersected_rd = regdom_intersect(rd, cfg80211_regdomain);
if (!intersected_rd)
@ -1977,7 +2003,7 @@ static int __set_regdom(const struct ieee80211_regdomain *rd)
* However if a driver requested this specific regulatory
* domain we keep it for its private use
*/
if (last_request->initiator == REGDOM_SET_BY_DRIVER)
if (last_request->initiator == NL80211_REGDOM_SET_BY_DRIVER)
request_wiphy->regd = rd;
else
kfree(rd);
@ -2067,6 +2093,8 @@ int set_regdom(const struct ieee80211_regdomain *rd)
print_regdomain(cfg80211_regdomain);
nl80211_send_reg_change_event(last_request);
return r;
}