Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next-2.6
This commit is contained in:
Коммит
af4330631c
|
@ -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"
|
||||
|
|
|
@ -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/
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 *
|
||||
\********************/
|
||||
|
|
|
@ -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) ? ®s[*pos] : NULL;
|
||||
return *pos < ARRAY_SIZE(regs) ? (void *)®s[*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) ? ®s[*pos] : NULL;
|
||||
return *pos < ARRAY_SIZE(regs) ? (void *)®s[*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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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 };
|
||||
|
||||
/**
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -261,7 +261,7 @@ struct base_eep_header_4k {
|
|||
u16 deviceCap;
|
||||
u32 binBuildNumber;
|
||||
u8 deviceType;
|
||||
u8 futureBase[1];
|
||||
u8 txGainType;
|
||||
} __packed;
|
||||
|
||||
|
||||
|
|
|
@ -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++) {
|
||||
|
|
|
@ -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 },
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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) || \
|
||||
|
|
|
@ -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, ®_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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
||||
|
||||
|
|
|
@ -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,
|
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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++) {
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -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
|
||||
|
|
|
@ -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_ */
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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)
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 *
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -417,9 +417,6 @@ static void ieee80211_sta_wmm_params(struct ieee80211_local *local,
|
|||
|
||||
memset(¶ms, 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, ¶ms)) {
|
||||
if (local->ops->conf_tx &&
|
||||
local->ops->conf_tx(local_to_hw(local), queue, ¶ms)) {
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 = ®_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;
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче