forked from Minki/linux
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next-2.6 into for-davem
This commit is contained in:
commit
c0c33addcb
@ -13,6 +13,11 @@ config BCMA
|
||||
Bus driver for Broadcom specific Advanced Microcontroller Bus
|
||||
Architecture.
|
||||
|
||||
# Support for Block-I/O. SELECT this from the driver that needs it.
|
||||
config BCMA_BLOCKIO
|
||||
bool
|
||||
depends on BCMA
|
||||
|
||||
config BCMA_HOST_PCI_POSSIBLE
|
||||
bool
|
||||
depends on BCMA && PCI = y
|
||||
|
@ -1,4 +1,4 @@
|
||||
bcma-y += main.o scan.o core.o
|
||||
bcma-y += main.o scan.o core.o sprom.o
|
||||
bcma-y += driver_chipcommon.o driver_chipcommon_pmu.o
|
||||
bcma-y += driver_pci.o
|
||||
bcma-$(CONFIG_BCMA_HOST_PCI) += host_pci.o
|
||||
|
@ -19,6 +19,9 @@ extern void bcma_bus_unregister(struct bcma_bus *bus);
|
||||
/* scan.c */
|
||||
int bcma_bus_scan(struct bcma_bus *bus);
|
||||
|
||||
/* sprom.c */
|
||||
int bcma_sprom_get(struct bcma_bus *bus);
|
||||
|
||||
#ifdef CONFIG_BCMA_HOST_PCI
|
||||
/* host_pci.c */
|
||||
extern int __init bcma_host_pci_init(void);
|
||||
|
@ -161,3 +161,26 @@ void bcma_core_pci_init(struct bcma_drv_pci *pc)
|
||||
{
|
||||
bcma_pcicore_serdes_workaround(pc);
|
||||
}
|
||||
|
||||
int bcma_core_pci_irq_ctl(struct bcma_drv_pci *pc, struct bcma_device *core,
|
||||
bool enable)
|
||||
{
|
||||
struct pci_dev *pdev = pc->core->bus->host_pci;
|
||||
u32 coremask, tmp;
|
||||
int err;
|
||||
|
||||
err = pci_read_config_dword(pdev, BCMA_PCI_IRQMASK, &tmp);
|
||||
if (err)
|
||||
goto out;
|
||||
|
||||
coremask = BIT(core->core_index) << 8;
|
||||
if (enable)
|
||||
tmp |= coremask;
|
||||
else
|
||||
tmp &= ~coremask;
|
||||
|
||||
err = pci_write_config_dword(pdev, BCMA_PCI_IRQMASK, tmp);
|
||||
|
||||
out:
|
||||
return err;
|
||||
}
|
||||
|
@ -65,6 +65,54 @@ static void bcma_host_pci_write32(struct bcma_device *core, u16 offset,
|
||||
iowrite32(value, core->bus->mmio + offset);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_BCMA_BLOCKIO
|
||||
void bcma_host_pci_block_read(struct bcma_device *core, void *buffer,
|
||||
size_t count, u16 offset, u8 reg_width)
|
||||
{
|
||||
void __iomem *addr = core->bus->mmio + offset;
|
||||
if (core->bus->mapped_core != core)
|
||||
bcma_host_pci_switch_core(core);
|
||||
switch (reg_width) {
|
||||
case sizeof(u8):
|
||||
ioread8_rep(addr, buffer, count);
|
||||
break;
|
||||
case sizeof(u16):
|
||||
WARN_ON(count & 1);
|
||||
ioread16_rep(addr, buffer, count >> 1);
|
||||
break;
|
||||
case sizeof(u32):
|
||||
WARN_ON(count & 3);
|
||||
ioread32_rep(addr, buffer, count >> 2);
|
||||
break;
|
||||
default:
|
||||
WARN_ON(1);
|
||||
}
|
||||
}
|
||||
|
||||
void bcma_host_pci_block_write(struct bcma_device *core, const void *buffer,
|
||||
size_t count, u16 offset, u8 reg_width)
|
||||
{
|
||||
void __iomem *addr = core->bus->mmio + offset;
|
||||
if (core->bus->mapped_core != core)
|
||||
bcma_host_pci_switch_core(core);
|
||||
switch (reg_width) {
|
||||
case sizeof(u8):
|
||||
iowrite8_rep(addr, buffer, count);
|
||||
break;
|
||||
case sizeof(u16):
|
||||
WARN_ON(count & 1);
|
||||
iowrite16_rep(addr, buffer, count >> 1);
|
||||
break;
|
||||
case sizeof(u32):
|
||||
WARN_ON(count & 3);
|
||||
iowrite32_rep(addr, buffer, count >> 2);
|
||||
break;
|
||||
default:
|
||||
WARN_ON(1);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static u32 bcma_host_pci_aread32(struct bcma_device *core, u16 offset)
|
||||
{
|
||||
if (core->bus->mapped_core != core)
|
||||
@ -87,6 +135,10 @@ const struct bcma_host_ops bcma_host_pci_ops = {
|
||||
.write8 = bcma_host_pci_write8,
|
||||
.write16 = bcma_host_pci_write16,
|
||||
.write32 = bcma_host_pci_write32,
|
||||
#ifdef CONFIG_BCMA_BLOCKIO
|
||||
.block_read = bcma_host_pci_block_read,
|
||||
.block_write = bcma_host_pci_block_write,
|
||||
#endif
|
||||
.aread32 = bcma_host_pci_aread32,
|
||||
.awrite32 = bcma_host_pci_awrite32,
|
||||
};
|
||||
|
@ -89,6 +89,8 @@ static int bcma_register_cores(struct bcma_bus *bus)
|
||||
switch (bus->hosttype) {
|
||||
case BCMA_HOSTTYPE_PCI:
|
||||
core->dev.parent = &bus->host_pci->dev;
|
||||
core->dma_dev = &bus->host_pci->dev;
|
||||
core->irq = bus->host_pci->irq;
|
||||
break;
|
||||
case BCMA_HOSTTYPE_NONE:
|
||||
case BCMA_HOSTTYPE_SDIO:
|
||||
@ -144,6 +146,13 @@ int bcma_bus_register(struct bcma_bus *bus)
|
||||
bcma_core_pci_init(&bus->drv_pci);
|
||||
}
|
||||
|
||||
/* Try to get SPROM */
|
||||
err = bcma_sprom_get(bus);
|
||||
if (err) {
|
||||
pr_err("Failed to get SPROM: %d\n", err);
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
/* Register found cores */
|
||||
bcma_register_cores(bus);
|
||||
|
||||
|
162
drivers/bcma/sprom.c
Normal file
162
drivers/bcma/sprom.c
Normal file
@ -0,0 +1,162 @@
|
||||
/*
|
||||
* Broadcom specific AMBA
|
||||
* SPROM reading
|
||||
*
|
||||
* Licensed under the GNU/GPL. See COPYING for details.
|
||||
*/
|
||||
|
||||
#include "bcma_private.h"
|
||||
|
||||
#include <linux/bcma/bcma.h>
|
||||
#include <linux/bcma/bcma_regs.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#define SPOFF(offset) ((offset) / sizeof(u16))
|
||||
|
||||
/**************************************************
|
||||
* R/W ops.
|
||||
**************************************************/
|
||||
|
||||
static void bcma_sprom_read(struct bcma_bus *bus, u16 *sprom)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < SSB_SPROMSIZE_WORDS_R4; i++)
|
||||
sprom[i] = bcma_read16(bus->drv_cc.core,
|
||||
BCMA_CC_SPROM + (i * 2));
|
||||
}
|
||||
|
||||
/**************************************************
|
||||
* Validation.
|
||||
**************************************************/
|
||||
|
||||
static inline u8 bcma_crc8(u8 crc, u8 data)
|
||||
{
|
||||
/* Polynomial: x^8 + x^7 + x^6 + x^4 + x^2 + 1 */
|
||||
static const u8 t[] = {
|
||||
0x00, 0xF7, 0xB9, 0x4E, 0x25, 0xD2, 0x9C, 0x6B,
|
||||
0x4A, 0xBD, 0xF3, 0x04, 0x6F, 0x98, 0xD6, 0x21,
|
||||
0x94, 0x63, 0x2D, 0xDA, 0xB1, 0x46, 0x08, 0xFF,
|
||||
0xDE, 0x29, 0x67, 0x90, 0xFB, 0x0C, 0x42, 0xB5,
|
||||
0x7F, 0x88, 0xC6, 0x31, 0x5A, 0xAD, 0xE3, 0x14,
|
||||
0x35, 0xC2, 0x8C, 0x7B, 0x10, 0xE7, 0xA9, 0x5E,
|
||||
0xEB, 0x1C, 0x52, 0xA5, 0xCE, 0x39, 0x77, 0x80,
|
||||
0xA1, 0x56, 0x18, 0xEF, 0x84, 0x73, 0x3D, 0xCA,
|
||||
0xFE, 0x09, 0x47, 0xB0, 0xDB, 0x2C, 0x62, 0x95,
|
||||
0xB4, 0x43, 0x0D, 0xFA, 0x91, 0x66, 0x28, 0xDF,
|
||||
0x6A, 0x9D, 0xD3, 0x24, 0x4F, 0xB8, 0xF6, 0x01,
|
||||
0x20, 0xD7, 0x99, 0x6E, 0x05, 0xF2, 0xBC, 0x4B,
|
||||
0x81, 0x76, 0x38, 0xCF, 0xA4, 0x53, 0x1D, 0xEA,
|
||||
0xCB, 0x3C, 0x72, 0x85, 0xEE, 0x19, 0x57, 0xA0,
|
||||
0x15, 0xE2, 0xAC, 0x5B, 0x30, 0xC7, 0x89, 0x7E,
|
||||
0x5F, 0xA8, 0xE6, 0x11, 0x7A, 0x8D, 0xC3, 0x34,
|
||||
0xAB, 0x5C, 0x12, 0xE5, 0x8E, 0x79, 0x37, 0xC0,
|
||||
0xE1, 0x16, 0x58, 0xAF, 0xC4, 0x33, 0x7D, 0x8A,
|
||||
0x3F, 0xC8, 0x86, 0x71, 0x1A, 0xED, 0xA3, 0x54,
|
||||
0x75, 0x82, 0xCC, 0x3B, 0x50, 0xA7, 0xE9, 0x1E,
|
||||
0xD4, 0x23, 0x6D, 0x9A, 0xF1, 0x06, 0x48, 0xBF,
|
||||
0x9E, 0x69, 0x27, 0xD0, 0xBB, 0x4C, 0x02, 0xF5,
|
||||
0x40, 0xB7, 0xF9, 0x0E, 0x65, 0x92, 0xDC, 0x2B,
|
||||
0x0A, 0xFD, 0xB3, 0x44, 0x2F, 0xD8, 0x96, 0x61,
|
||||
0x55, 0xA2, 0xEC, 0x1B, 0x70, 0x87, 0xC9, 0x3E,
|
||||
0x1F, 0xE8, 0xA6, 0x51, 0x3A, 0xCD, 0x83, 0x74,
|
||||
0xC1, 0x36, 0x78, 0x8F, 0xE4, 0x13, 0x5D, 0xAA,
|
||||
0x8B, 0x7C, 0x32, 0xC5, 0xAE, 0x59, 0x17, 0xE0,
|
||||
0x2A, 0xDD, 0x93, 0x64, 0x0F, 0xF8, 0xB6, 0x41,
|
||||
0x60, 0x97, 0xD9, 0x2E, 0x45, 0xB2, 0xFC, 0x0B,
|
||||
0xBE, 0x49, 0x07, 0xF0, 0x9B, 0x6C, 0x22, 0xD5,
|
||||
0xF4, 0x03, 0x4D, 0xBA, 0xD1, 0x26, 0x68, 0x9F,
|
||||
};
|
||||
return t[crc ^ data];
|
||||
}
|
||||
|
||||
static u8 bcma_sprom_crc(const u16 *sprom)
|
||||
{
|
||||
int word;
|
||||
u8 crc = 0xFF;
|
||||
|
||||
for (word = 0; word < SSB_SPROMSIZE_WORDS_R4 - 1; word++) {
|
||||
crc = bcma_crc8(crc, sprom[word] & 0x00FF);
|
||||
crc = bcma_crc8(crc, (sprom[word] & 0xFF00) >> 8);
|
||||
}
|
||||
crc = bcma_crc8(crc, sprom[SSB_SPROMSIZE_WORDS_R4 - 1] & 0x00FF);
|
||||
crc ^= 0xFF;
|
||||
|
||||
return crc;
|
||||
}
|
||||
|
||||
static int bcma_sprom_check_crc(const u16 *sprom)
|
||||
{
|
||||
u8 crc;
|
||||
u8 expected_crc;
|
||||
u16 tmp;
|
||||
|
||||
crc = bcma_sprom_crc(sprom);
|
||||
tmp = sprom[SSB_SPROMSIZE_WORDS_R4 - 1] & SSB_SPROM_REVISION_CRC;
|
||||
expected_crc = tmp >> SSB_SPROM_REVISION_CRC_SHIFT;
|
||||
if (crc != expected_crc)
|
||||
return -EPROTO;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int bcma_sprom_valid(const u16 *sprom)
|
||||
{
|
||||
u16 revision;
|
||||
int err;
|
||||
|
||||
err = bcma_sprom_check_crc(sprom);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
revision = sprom[SSB_SPROMSIZE_WORDS_R4 - 1] & SSB_SPROM_REVISION_REV;
|
||||
if (revision != 8) {
|
||||
pr_err("Unsupported SPROM revision: %d\n", revision);
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**************************************************
|
||||
* SPROM extraction.
|
||||
**************************************************/
|
||||
|
||||
static void bcma_sprom_extract_r8(struct bcma_bus *bus, const u16 *sprom)
|
||||
{
|
||||
u16 v;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
v = sprom[SPOFF(SSB_SPROM8_IL0MAC) + i];
|
||||
*(((__be16 *)bus->sprom.il0mac) + i) = cpu_to_be16(v);
|
||||
}
|
||||
}
|
||||
|
||||
int bcma_sprom_get(struct bcma_bus *bus)
|
||||
{
|
||||
u16 *sprom;
|
||||
int err = 0;
|
||||
|
||||
if (!bus->drv_cc.core)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
sprom = kcalloc(SSB_SPROMSIZE_WORDS_R4, sizeof(u16),
|
||||
GFP_KERNEL);
|
||||
if (!sprom)
|
||||
return -ENOMEM;
|
||||
|
||||
bcma_sprom_read(bus, sprom);
|
||||
|
||||
err = bcma_sprom_valid(sprom);
|
||||
if (err)
|
||||
goto out;
|
||||
|
||||
bcma_sprom_extract_r8(bus, sprom);
|
||||
|
||||
out:
|
||||
kfree(sprom);
|
||||
return err;
|
||||
}
|
@ -161,6 +161,7 @@ struct ath_common {
|
||||
const struct ath_bus_ops *bus_ops;
|
||||
|
||||
bool btcoex_enabled;
|
||||
bool disable_ani;
|
||||
};
|
||||
|
||||
struct sk_buff *ath_rxbuf_alloc(struct ath_common *common,
|
||||
|
@ -72,6 +72,11 @@ static int modparam_all_channels;
|
||||
module_param_named(all_channels, modparam_all_channels, bool, S_IRUGO);
|
||||
MODULE_PARM_DESC(all_channels, "Expose all channels the device can use.");
|
||||
|
||||
static int modparam_fastchanswitch;
|
||||
module_param_named(fastchanswitch, modparam_fastchanswitch, bool, S_IRUGO);
|
||||
MODULE_PARM_DESC(fastchanswitch, "Enable fast channel switching for AR2413/AR5413 radios.");
|
||||
|
||||
|
||||
/* Module info */
|
||||
MODULE_AUTHOR("Jiri Slaby");
|
||||
MODULE_AUTHOR("Nick Kossifidis");
|
||||
@ -2686,6 +2691,7 @@ ath5k_reset(struct ath5k_softc *sc, struct ieee80211_channel *chan,
|
||||
struct ath5k_hw *ah = sc->ah;
|
||||
struct ath_common *common = ath5k_hw_common(ah);
|
||||
int ret, ani_mode;
|
||||
bool fast;
|
||||
|
||||
ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "resetting\n");
|
||||
|
||||
@ -2705,7 +2711,10 @@ ath5k_reset(struct ath5k_softc *sc, struct ieee80211_channel *chan,
|
||||
ath5k_drain_tx_buffs(sc);
|
||||
if (chan)
|
||||
sc->curchan = chan;
|
||||
ret = ath5k_hw_reset(ah, sc->opmode, sc->curchan, chan != NULL,
|
||||
|
||||
fast = ((chan != NULL) && modparam_fastchanswitch) ? 1 : 0;
|
||||
|
||||
ret = ath5k_hw_reset(ah, sc->opmode, sc->curchan, fast,
|
||||
skip_pcu);
|
||||
if (ret) {
|
||||
ATH5K_ERR(sc, "can't reset hardware (%d)\n", ret);
|
||||
|
@ -1124,8 +1124,11 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
|
||||
/* Non fatal, can happen eg.
|
||||
* on mode change */
|
||||
ret = 0;
|
||||
} else
|
||||
} else {
|
||||
ATH5K_DBG(ah->ah_sc, ATH5K_DEBUG_RESET,
|
||||
"fast chan change successful\n");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -28,11 +28,6 @@ static void ar9002_hw_set_desc_link(void *ds, u32 ds_link)
|
||||
((struct ath_desc*) ds)->ds_link = ds_link;
|
||||
}
|
||||
|
||||
static void ar9002_hw_get_desc_link(void *ds, u32 **ds_link)
|
||||
{
|
||||
*ds_link = &((struct ath_desc *)ds)->ds_link;
|
||||
}
|
||||
|
||||
static bool ar9002_hw_get_isr(struct ath_hw *ah, enum ath9k_int *masked)
|
||||
{
|
||||
u32 isr = 0;
|
||||
@ -437,7 +432,6 @@ void ar9002_hw_attach_mac_ops(struct ath_hw *ah)
|
||||
|
||||
ops->rx_enable = ar9002_hw_rx_enable;
|
||||
ops->set_desc_link = ar9002_hw_set_desc_link;
|
||||
ops->get_desc_link = ar9002_hw_get_desc_link;
|
||||
ops->get_isr = ar9002_hw_get_isr;
|
||||
ops->fill_txdesc = ar9002_hw_fill_txdesc;
|
||||
ops->proc_txdesc = ar9002_hw_proc_txdesc;
|
||||
|
@ -43,13 +43,6 @@ static void ar9003_hw_set_desc_link(void *ds, u32 ds_link)
|
||||
ads->ctl10 |= ar9003_calc_ptr_chksum(ads);
|
||||
}
|
||||
|
||||
static void ar9003_hw_get_desc_link(void *ds, u32 **ds_link)
|
||||
{
|
||||
struct ar9003_txc *ads = ds;
|
||||
|
||||
*ds_link = &ads->link;
|
||||
}
|
||||
|
||||
static bool ar9003_hw_get_isr(struct ath_hw *ah, enum ath9k_int *masked)
|
||||
{
|
||||
u32 isr = 0;
|
||||
@ -498,7 +491,6 @@ void ar9003_hw_attach_mac_ops(struct ath_hw *hw)
|
||||
|
||||
ops->rx_enable = ar9003_hw_rx_enable;
|
||||
ops->set_desc_link = ar9003_hw_set_desc_link;
|
||||
ops->get_desc_link = ar9003_hw_get_desc_link;
|
||||
ops->get_isr = ar9003_hw_get_isr;
|
||||
ops->fill_txdesc = ar9003_hw_fill_txdesc;
|
||||
ops->proc_txdesc = ar9003_hw_proc_txdesc;
|
||||
|
@ -46,11 +46,10 @@ EXPORT_SYMBOL(ar9003_paprd_enable);
|
||||
|
||||
static int ar9003_get_training_power_2g(struct ath_hw *ah)
|
||||
{
|
||||
struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
|
||||
struct ar9300_modal_eep_header *hdr = &eep->modalHeader2G;
|
||||
struct ath9k_channel *chan = ah->curchan;
|
||||
unsigned int power, scale, delta;
|
||||
|
||||
scale = MS(le32_to_cpu(hdr->papdRateMaskHt20), AR9300_PAPRD_SCALE_1);
|
||||
scale = ar9003_get_paprd_scale_factor(ah, chan);
|
||||
power = REG_READ_FIELD(ah, AR_PHY_POWERTX_RATE5,
|
||||
AR_PHY_POWERTX_RATE5_POWERTXHT20_0);
|
||||
|
||||
@ -67,20 +66,10 @@ static int ar9003_get_training_power_2g(struct ath_hw *ah)
|
||||
static int ar9003_get_training_power_5g(struct ath_hw *ah)
|
||||
{
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
|
||||
struct ar9300_modal_eep_header *hdr = &eep->modalHeader5G;
|
||||
struct ath9k_channel *chan = ah->curchan;
|
||||
unsigned int power, scale, delta;
|
||||
|
||||
if (chan->channel >= 5700)
|
||||
scale = MS(le32_to_cpu(hdr->papdRateMaskHt20),
|
||||
AR9300_PAPRD_SCALE_1);
|
||||
else if (chan->channel >= 5400)
|
||||
scale = MS(le32_to_cpu(hdr->papdRateMaskHt40),
|
||||
AR9300_PAPRD_SCALE_2);
|
||||
else
|
||||
scale = MS(le32_to_cpu(hdr->papdRateMaskHt40),
|
||||
AR9300_PAPRD_SCALE_1);
|
||||
scale = ar9003_get_paprd_scale_factor(ah, chan);
|
||||
|
||||
if (IS_CHAN_HT40(chan))
|
||||
power = REG_READ_FIELD(ah, AR_PHY_POWERTX_RATE8,
|
||||
@ -119,15 +108,16 @@ static int ar9003_paprd_setup_single_table(struct ath_hw *ah)
|
||||
else
|
||||
training_power = ar9003_get_training_power_5g(ah);
|
||||
|
||||
ath_dbg(common, ATH_DBG_CALIBRATE,
|
||||
"Training power: %d, Target power: %d\n",
|
||||
training_power, ah->paprd_target_power);
|
||||
|
||||
if (training_power < 0) {
|
||||
ath_dbg(common, ATH_DBG_CALIBRATE,
|
||||
"PAPRD target power delta out of range");
|
||||
return -ERANGE;
|
||||
}
|
||||
ah->paprd_training_power = training_power;
|
||||
ath_dbg(common, ATH_DBG_CALIBRATE,
|
||||
"Training power: %d, Target power: %d\n",
|
||||
ah->paprd_training_power, ah->paprd_target_power);
|
||||
|
||||
REG_RMW_FIELD(ah, AR_PHY_PAPRD_AM2AM, AR_PHY_PAPRD_AM2AM_MASK,
|
||||
ah->paprd_ratemask);
|
||||
|
@ -180,7 +180,7 @@ enum ATH_AGGR_STATUS {
|
||||
struct ath_txq {
|
||||
int mac80211_qnum; /* mac80211 queue number, -1 means not mac80211 Q */
|
||||
u32 axq_qnum; /* ath9k hardware queue number */
|
||||
u32 *axq_link;
|
||||
void *axq_link;
|
||||
struct list_head axq_q;
|
||||
spinlock_t axq_lock;
|
||||
u32 axq_depth;
|
||||
@ -189,7 +189,6 @@ struct ath_txq {
|
||||
bool axq_tx_inprogress;
|
||||
struct list_head axq_acq;
|
||||
struct list_head txq_fifo[ATH_TXFIFO_DEPTH];
|
||||
struct list_head txq_fifo_pending;
|
||||
u8 txq_headidx;
|
||||
u8 txq_tailidx;
|
||||
int pending_frames;
|
||||
@ -429,6 +428,7 @@ void ath_hw_check(struct work_struct *work);
|
||||
void ath_hw_pll_work(struct work_struct *work);
|
||||
void ath_paprd_calibrate(struct work_struct *work);
|
||||
void ath_ani_calibrate(unsigned long data);
|
||||
void ath_start_ani(struct ath_common *common);
|
||||
|
||||
/**********/
|
||||
/* BTCOEX */
|
||||
@ -670,12 +670,8 @@ int ath9k_init_device(u16 devid, struct ath_softc *sc, u16 subsysid,
|
||||
const struct ath_bus_ops *bus_ops);
|
||||
void ath9k_deinit_device(struct ath_softc *sc);
|
||||
void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw);
|
||||
int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw,
|
||||
struct ath9k_channel *hchan);
|
||||
|
||||
void ath_radio_enable(struct ath_softc *sc, struct ieee80211_hw *hw);
|
||||
void ath_radio_disable(struct ath_softc *sc, struct ieee80211_hw *hw);
|
||||
bool ath9k_setpower(struct ath_softc *sc, enum ath9k_power_mode mode);
|
||||
bool ath9k_uses_beacons(int type);
|
||||
|
||||
#ifdef CONFIG_ATH9K_PCI
|
||||
|
@ -496,7 +496,7 @@ static void ath_beacon_config_ap(struct ath_softc *sc,
|
||||
u32 nexttbtt, intval;
|
||||
|
||||
/* NB: the beacon interval is kept internally in TU's */
|
||||
intval = TU_TO_USEC(conf->beacon_interval & ATH9K_BEACON_PERIOD);
|
||||
intval = TU_TO_USEC(conf->beacon_interval);
|
||||
intval /= ATH_BCBUF; /* for staggered beacons */
|
||||
nexttbtt = intval;
|
||||
|
||||
@ -543,7 +543,7 @@ static void ath_beacon_config_sta(struct ath_softc *sc,
|
||||
}
|
||||
|
||||
memset(&bs, 0, sizeof(bs));
|
||||
intval = conf->beacon_interval & ATH9K_BEACON_PERIOD;
|
||||
intval = conf->beacon_interval;
|
||||
|
||||
/*
|
||||
* Setup dtim and cfp parameters according to
|
||||
@ -652,22 +652,13 @@ static void ath_beacon_config_adhoc(struct ath_softc *sc,
|
||||
{
|
||||
struct ath_hw *ah = sc->sc_ah;
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
u32 tsf, delta, intval, nexttbtt;
|
||||
u32 tsf, intval, nexttbtt;
|
||||
|
||||
ath9k_reset_beacon_status(sc);
|
||||
|
||||
tsf = ath9k_hw_gettsf32(ah) + TU_TO_USEC(FUDGE);
|
||||
intval = TU_TO_USEC(conf->beacon_interval & ATH9K_BEACON_PERIOD);
|
||||
|
||||
if (!sc->beacon.bc_tstamp)
|
||||
nexttbtt = tsf + intval;
|
||||
else {
|
||||
if (tsf > sc->beacon.bc_tstamp)
|
||||
delta = (tsf - sc->beacon.bc_tstamp);
|
||||
else
|
||||
delta = (tsf + 1 + (~0U - sc->beacon.bc_tstamp));
|
||||
nexttbtt = tsf + intval - (delta % intval);
|
||||
}
|
||||
intval = TU_TO_USEC(conf->beacon_interval);
|
||||
tsf = roundup(ath9k_hw_gettsf32(ah) + TU_TO_USEC(FUDGE), intval);
|
||||
nexttbtt = tsf + intval;
|
||||
|
||||
ath_dbg(common, ATH_DBG_BEACON,
|
||||
"IBSS nexttbtt %u intval %u (%u)\n",
|
||||
|
@ -176,6 +176,56 @@ static const struct file_operations fops_rx_chainmask = {
|
||||
.llseek = default_llseek,
|
||||
};
|
||||
|
||||
static ssize_t read_file_disable_ani(struct file *file, char __user *user_buf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
struct ath_softc *sc = file->private_data;
|
||||
struct ath_common *common = ath9k_hw_common(sc->sc_ah);
|
||||
char buf[32];
|
||||
unsigned int len;
|
||||
|
||||
len = sprintf(buf, "%d\n", common->disable_ani);
|
||||
return simple_read_from_buffer(user_buf, count, ppos, buf, len);
|
||||
}
|
||||
|
||||
static ssize_t write_file_disable_ani(struct file *file,
|
||||
const char __user *user_buf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
struct ath_softc *sc = file->private_data;
|
||||
struct ath_common *common = ath9k_hw_common(sc->sc_ah);
|
||||
unsigned long disable_ani;
|
||||
char buf[32];
|
||||
ssize_t len;
|
||||
|
||||
len = min(count, sizeof(buf) - 1);
|
||||
if (copy_from_user(buf, user_buf, len))
|
||||
return -EFAULT;
|
||||
|
||||
buf[len] = '\0';
|
||||
if (strict_strtoul(buf, 0, &disable_ani))
|
||||
return -EINVAL;
|
||||
|
||||
common->disable_ani = !!disable_ani;
|
||||
|
||||
if (disable_ani) {
|
||||
sc->sc_flags &= ~SC_OP_ANI_RUN;
|
||||
del_timer_sync(&common->ani.timer);
|
||||
} else {
|
||||
sc->sc_flags |= SC_OP_ANI_RUN;
|
||||
ath_start_ani(common);
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static const struct file_operations fops_disable_ani = {
|
||||
.read = read_file_disable_ani,
|
||||
.write = write_file_disable_ani,
|
||||
.open = ath9k_debugfs_open,
|
||||
.owner = THIS_MODULE,
|
||||
.llseek = default_llseek,
|
||||
};
|
||||
|
||||
static ssize_t read_file_dma(struct file *file, char __user *user_buf,
|
||||
size_t count, loff_t *ppos)
|
||||
@ -550,6 +600,7 @@ static ssize_t read_file_xmit(struct file *file, char __user *user_buf,
|
||||
|
||||
PR("MPDUs Queued: ", queued);
|
||||
PR("MPDUs Completed: ", completed);
|
||||
PR("MPDUs XRetried: ", xretries);
|
||||
PR("Aggregates: ", a_aggr);
|
||||
PR("AMPDUs Queued HW:", a_queued_hw);
|
||||
PR("AMPDUs Queued SW:", a_queued_sw);
|
||||
@ -587,7 +638,6 @@ static ssize_t read_file_xmit(struct file *file, char __user *user_buf,
|
||||
|
||||
PRQLE("axq_q empty: ", axq_q);
|
||||
PRQLE("axq_acq empty: ", axq_acq);
|
||||
PRQLE("txq_fifo_pending: ", txq_fifo_pending);
|
||||
for (i = 0; i < ATH_TXFIFO_DEPTH; i++) {
|
||||
snprintf(tmp, sizeof(tmp) - 1, "txq_fifo[%i] empty: ", i);
|
||||
PRQLE(tmp, txq_fifo[i]);
|
||||
@ -807,7 +857,10 @@ void ath_debug_stat_tx(struct ath_softc *sc, struct ath_buf *bf,
|
||||
else
|
||||
TX_STAT_INC(qnum, a_completed);
|
||||
} else {
|
||||
TX_STAT_INC(qnum, completed);
|
||||
if (bf_isxretried(bf))
|
||||
TX_STAT_INC(qnum, xretries);
|
||||
else
|
||||
TX_STAT_INC(qnum, completed);
|
||||
}
|
||||
|
||||
if (ts->ts_status & ATH9K_TXERR_FIFO)
|
||||
@ -1160,6 +1213,8 @@ int ath9k_init_debug(struct ath_hw *ah)
|
||||
sc->debug.debugfs_phy, sc, &fops_rx_chainmask);
|
||||
debugfs_create_file("tx_chainmask", S_IRUSR | S_IWUSR,
|
||||
sc->debug.debugfs_phy, sc, &fops_tx_chainmask);
|
||||
debugfs_create_file("disable_ani", S_IRUSR | S_IWUSR,
|
||||
sc->debug.debugfs_phy, sc, &fops_disable_ani);
|
||||
debugfs_create_file("regidx", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy,
|
||||
sc, &fops_regidx);
|
||||
debugfs_create_file("regval", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy,
|
||||
|
@ -116,6 +116,7 @@ struct ath_tx_stats {
|
||||
u32 tx_bytes_all;
|
||||
u32 queued;
|
||||
u32 completed;
|
||||
u32 xretries;
|
||||
u32 a_aggr;
|
||||
u32 a_queued_hw;
|
||||
u32 a_queued_sw;
|
||||
|
@ -79,7 +79,7 @@ static void ath9k_htc_beacon_config_sta(struct ath9k_htc_priv *priv,
|
||||
|
||||
memset(&bs, 0, sizeof(bs));
|
||||
|
||||
intval = bss_conf->beacon_interval & ATH9K_BEACON_PERIOD;
|
||||
intval = bss_conf->beacon_interval;
|
||||
bmiss_timeout = (ATH_DEFAULT_BMISS_LIMIT * bss_conf->beacon_interval);
|
||||
|
||||
/*
|
||||
@ -194,7 +194,7 @@ static void ath9k_htc_beacon_config_ap(struct ath9k_htc_priv *priv,
|
||||
u8 cmd_rsp;
|
||||
u64 tsf;
|
||||
|
||||
intval = bss_conf->beacon_interval & ATH9K_BEACON_PERIOD;
|
||||
intval = bss_conf->beacon_interval;
|
||||
intval /= ATH9K_HTC_MAX_BCN_VIF;
|
||||
nexttbtt = intval;
|
||||
|
||||
@ -250,7 +250,7 @@ static void ath9k_htc_beacon_config_adhoc(struct ath9k_htc_priv *priv,
|
||||
u8 cmd_rsp;
|
||||
u64 tsf;
|
||||
|
||||
intval = bss_conf->beacon_interval & ATH9K_BEACON_PERIOD;
|
||||
intval = bss_conf->beacon_interval;
|
||||
nexttbtt = intval;
|
||||
|
||||
/*
|
||||
@ -427,7 +427,7 @@ static int ath9k_htc_choose_bslot(struct ath9k_htc_priv *priv,
|
||||
u16 intval;
|
||||
int slot;
|
||||
|
||||
intval = priv->cur_beacon_conf.beacon_interval & ATH9K_BEACON_PERIOD;
|
||||
intval = priv->cur_beacon_conf.beacon_interval;
|
||||
|
||||
tsf = be64_to_cpu(swba->tsf);
|
||||
tsftu = TSF_TO_TU(tsf >> 32, tsf);
|
||||
|
@ -39,11 +39,6 @@ static inline void ath9k_hw_set_desc_link(struct ath_hw *ah, void *ds,
|
||||
ath9k_hw_ops(ah)->set_desc_link(ds, link);
|
||||
}
|
||||
|
||||
static inline void ath9k_hw_get_desc_link(struct ath_hw *ah, void *ds,
|
||||
u32 **link)
|
||||
{
|
||||
ath9k_hw_ops(ah)->get_desc_link(ds, link);
|
||||
}
|
||||
static inline bool ath9k_hw_calibrate(struct ath_hw *ah,
|
||||
struct ath9k_channel *chan,
|
||||
u8 rxchainmask,
|
||||
|
@ -1785,16 +1785,16 @@ void ath9k_hw_set_sta_beacon_timers(struct ath_hw *ah,
|
||||
REG_WRITE(ah, AR_NEXT_TBTT_TIMER, TU_TO_USEC(bs->bs_nexttbtt));
|
||||
|
||||
REG_WRITE(ah, AR_BEACON_PERIOD,
|
||||
TU_TO_USEC(bs->bs_intval & ATH9K_BEACON_PERIOD));
|
||||
TU_TO_USEC(bs->bs_intval));
|
||||
REG_WRITE(ah, AR_DMA_BEACON_PERIOD,
|
||||
TU_TO_USEC(bs->bs_intval & ATH9K_BEACON_PERIOD));
|
||||
TU_TO_USEC(bs->bs_intval));
|
||||
|
||||
REGWRITE_BUFFER_FLUSH(ah);
|
||||
|
||||
REG_RMW_FIELD(ah, AR_RSSI_THR,
|
||||
AR_RSSI_THR_BM_THR, bs->bs_bmissthreshold);
|
||||
|
||||
beaconintval = bs->bs_intval & ATH9K_BEACON_PERIOD;
|
||||
beaconintval = bs->bs_intval;
|
||||
|
||||
if (bs->bs_sleepduration > beaconintval)
|
||||
beaconintval = bs->bs_sleepduration;
|
||||
|
@ -403,7 +403,6 @@ struct ath9k_beacon_state {
|
||||
u32 bs_nexttbtt;
|
||||
u32 bs_nextdtim;
|
||||
u32 bs_intval;
|
||||
#define ATH9K_BEACON_PERIOD 0x0000ffff
|
||||
#define ATH9K_TSFOOR_THRESHOLD 0x00004240 /* 16k us */
|
||||
u32 bs_dtimperiod;
|
||||
u16 bs_cfpperiod;
|
||||
@ -603,7 +602,6 @@ struct ath_hw_ops {
|
||||
int power_off);
|
||||
void (*rx_enable)(struct ath_hw *ah);
|
||||
void (*set_desc_link)(void *ds, u32 link);
|
||||
void (*get_desc_link)(void *ds, u32 **link);
|
||||
bool (*calibrate)(struct ath_hw *ah,
|
||||
struct ath9k_channel *chan,
|
||||
u8 rxchainmask,
|
||||
|
@ -519,7 +519,6 @@ static void ath9k_init_misc(struct ath_softc *sc)
|
||||
{
|
||||
struct ath_common *common = ath9k_hw_common(sc->sc_ah);
|
||||
int i = 0;
|
||||
|
||||
setup_timer(&common->ani.timer, ath_ani_calibrate, (unsigned long)sc);
|
||||
|
||||
sc->config.txpowlimit = ATH_TXPOWER_MAX;
|
||||
@ -585,6 +584,7 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid,
|
||||
common->priv = sc;
|
||||
common->debug_mask = ath9k_debug;
|
||||
common->btcoex_enabled = ath9k_btcoex_enable == 1;
|
||||
common->disable_ani = false;
|
||||
spin_lock_init(&common->cc_lock);
|
||||
|
||||
spin_lock_init(&sc->sc_serial_rw);
|
||||
|
@ -62,14 +62,12 @@ static bool ath9k_has_pending_frames(struct ath_softc *sc, struct ath_txq *txq)
|
||||
|
||||
if (txq->axq_depth || !list_empty(&txq->axq_acq))
|
||||
pending = true;
|
||||
else if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)
|
||||
pending = !list_empty(&txq->txq_fifo_pending);
|
||||
|
||||
spin_unlock_bh(&txq->axq_lock);
|
||||
return pending;
|
||||
}
|
||||
|
||||
bool ath9k_setpower(struct ath_softc *sc, enum ath9k_power_mode mode)
|
||||
static bool ath9k_setpower(struct ath_softc *sc, enum ath9k_power_mode mode)
|
||||
{
|
||||
unsigned long flags;
|
||||
bool ret;
|
||||
@ -136,7 +134,7 @@ void ath9k_ps_restore(struct ath_softc *sc)
|
||||
spin_unlock_irqrestore(&sc->sc_pm_lock, flags);
|
||||
}
|
||||
|
||||
static void ath_start_ani(struct ath_common *common)
|
||||
void ath_start_ani(struct ath_common *common)
|
||||
{
|
||||
struct ath_hw *ah = common->ah;
|
||||
unsigned long timestamp = jiffies_to_msecs(jiffies);
|
||||
@ -219,7 +217,7 @@ static int ath_update_survey_stats(struct ath_softc *sc)
|
||||
* by reseting the chip. To accomplish this we must first cleanup any pending
|
||||
* DMA, then restart stuff.
|
||||
*/
|
||||
int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw,
|
||||
static int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw,
|
||||
struct ath9k_channel *hchan)
|
||||
{
|
||||
struct ath_hw *ah = sc->sc_ah;
|
||||
@ -302,7 +300,8 @@ int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw,
|
||||
ath_set_beacon(sc);
|
||||
ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work, 0);
|
||||
ieee80211_queue_delayed_work(sc->hw, &sc->hw_pll_work, HZ/2);
|
||||
ath_start_ani(common);
|
||||
if (!common->disable_ani)
|
||||
ath_start_ani(common);
|
||||
}
|
||||
|
||||
ps_restore:
|
||||
@ -394,12 +393,14 @@ void ath_paprd_calibrate(struct work_struct *work)
|
||||
if (!caldata)
|
||||
return;
|
||||
|
||||
ath9k_ps_wakeup(sc);
|
||||
|
||||
if (ar9003_paprd_init_table(ah) < 0)
|
||||
return;
|
||||
goto fail_paprd;
|
||||
|
||||
skb = alloc_skb(len, GFP_KERNEL);
|
||||
if (!skb)
|
||||
return;
|
||||
goto fail_paprd;
|
||||
|
||||
skb_put(skb, len);
|
||||
memset(skb->data, 0, len);
|
||||
@ -411,7 +412,6 @@ void ath_paprd_calibrate(struct work_struct *work)
|
||||
memcpy(hdr->addr2, hw->wiphy->perm_addr, ETH_ALEN);
|
||||
memcpy(hdr->addr3, hw->wiphy->perm_addr, ETH_ALEN);
|
||||
|
||||
ath9k_ps_wakeup(sc);
|
||||
for (chain = 0; chain < AR9300_MAX_CHAINS; chain++) {
|
||||
if (!(common->tx_chainmask & BIT(chain)))
|
||||
continue;
|
||||
@ -515,24 +515,19 @@ void ath_ani_calibrate(unsigned long data)
|
||||
common->ani.checkani_timer = timestamp;
|
||||
}
|
||||
|
||||
/* Skip all processing if there's nothing to do. */
|
||||
if (longcal || shortcal || aniflag) {
|
||||
/* Call ANI routine if necessary */
|
||||
if (aniflag) {
|
||||
spin_lock_irqsave(&common->cc_lock, flags);
|
||||
ath9k_hw_ani_monitor(ah, ah->curchan);
|
||||
ath_update_survey_stats(sc);
|
||||
spin_unlock_irqrestore(&common->cc_lock, flags);
|
||||
}
|
||||
/* Call ANI routine if necessary */
|
||||
if (aniflag) {
|
||||
spin_lock_irqsave(&common->cc_lock, flags);
|
||||
ath9k_hw_ani_monitor(ah, ah->curchan);
|
||||
ath_update_survey_stats(sc);
|
||||
spin_unlock_irqrestore(&common->cc_lock, flags);
|
||||
}
|
||||
|
||||
/* Perform calibration if necessary */
|
||||
if (longcal || shortcal) {
|
||||
common->ani.caldone =
|
||||
ath9k_hw_calibrate(ah,
|
||||
ah->curchan,
|
||||
common->rx_chainmask,
|
||||
longcal);
|
||||
}
|
||||
/* Perform calibration if necessary */
|
||||
if (longcal || shortcal) {
|
||||
common->ani.caldone =
|
||||
ath9k_hw_calibrate(ah, ah->curchan,
|
||||
common->rx_chainmask, longcal);
|
||||
}
|
||||
|
||||
ath9k_ps_restore(sc);
|
||||
@ -868,7 +863,7 @@ chip_reset:
|
||||
#undef SCHED_INTR
|
||||
}
|
||||
|
||||
void ath_radio_enable(struct ath_softc *sc, struct ieee80211_hw *hw)
|
||||
static void ath_radio_enable(struct ath_softc *sc, struct ieee80211_hw *hw)
|
||||
{
|
||||
struct ath_hw *ah = sc->sc_ah;
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
@ -974,6 +969,7 @@ int ath_reset(struct ath_softc *sc, bool retry_tx)
|
||||
sc->hw_busy_count = 0;
|
||||
|
||||
/* Stop ANI */
|
||||
|
||||
del_timer_sync(&common->ani.timer);
|
||||
|
||||
ath9k_ps_wakeup(sc);
|
||||
@ -1023,7 +1019,9 @@ int ath_reset(struct ath_softc *sc, bool retry_tx)
|
||||
spin_unlock_bh(&sc->sc_pcu_lock);
|
||||
|
||||
/* Start ANI */
|
||||
ath_start_ani(common);
|
||||
if (!common->disable_ani)
|
||||
ath_start_ani(common);
|
||||
|
||||
ath9k_ps_restore(sc);
|
||||
|
||||
return r;
|
||||
@ -1412,10 +1410,14 @@ static void ath9k_calculate_summary_state(struct ieee80211_hw *hw,
|
||||
ath9k_hw_set_interrupts(ah, ah->imask);
|
||||
|
||||
/* Set up ANI */
|
||||
if ((iter_data.naps + iter_data.nadhocs) > 0) {
|
||||
if (iter_data.naps > 0) {
|
||||
sc->sc_ah->stats.avgbrssi = ATH_RSSI_DUMMY_MARKER;
|
||||
sc->sc_flags |= SC_OP_ANI_RUN;
|
||||
ath_start_ani(common);
|
||||
|
||||
if (!common->disable_ani) {
|
||||
sc->sc_flags |= SC_OP_ANI_RUN;
|
||||
ath_start_ani(common);
|
||||
}
|
||||
|
||||
} else {
|
||||
sc->sc_flags &= ~SC_OP_ANI_RUN;
|
||||
del_timer_sync(&common->ani.timer);
|
||||
@ -1952,50 +1954,38 @@ static void ath9k_bss_iter(void *data, u8 *mac, struct ieee80211_vif *vif)
|
||||
struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;
|
||||
struct ath_vif *avp = (void *)vif->drv_priv;
|
||||
|
||||
switch (sc->sc_ah->opmode) {
|
||||
case NL80211_IFTYPE_ADHOC:
|
||||
/* There can be only one vif available */
|
||||
/*
|
||||
* Skip iteration if primary station vif's bss info
|
||||
* was not changed
|
||||
*/
|
||||
if (sc->sc_flags & SC_OP_PRIM_STA_VIF)
|
||||
return;
|
||||
|
||||
if (bss_conf->assoc) {
|
||||
sc->sc_flags |= SC_OP_PRIM_STA_VIF;
|
||||
avp->primary_sta_vif = true;
|
||||
memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN);
|
||||
common->curaid = bss_conf->aid;
|
||||
ath9k_hw_write_associd(sc->sc_ah);
|
||||
/* configure beacon */
|
||||
if (bss_conf->enable_beacon)
|
||||
ath_beacon_config(sc, vif);
|
||||
break;
|
||||
case NL80211_IFTYPE_STATION:
|
||||
/*
|
||||
* Skip iteration if primary station vif's bss info
|
||||
* was not changed
|
||||
*/
|
||||
if (sc->sc_flags & SC_OP_PRIM_STA_VIF)
|
||||
break;
|
||||
|
||||
if (bss_conf->assoc) {
|
||||
sc->sc_flags |= SC_OP_PRIM_STA_VIF;
|
||||
avp->primary_sta_vif = true;
|
||||
memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN);
|
||||
common->curaid = bss_conf->aid;
|
||||
ath9k_hw_write_associd(sc->sc_ah);
|
||||
ath_dbg(common, ATH_DBG_CONFIG,
|
||||
ath_dbg(common, ATH_DBG_CONFIG,
|
||||
"Bss Info ASSOC %d, bssid: %pM\n",
|
||||
bss_conf->aid, common->curbssid);
|
||||
ath_beacon_config(sc, vif);
|
||||
/*
|
||||
* Request a re-configuration of Beacon related timers
|
||||
* on the receipt of the first Beacon frame (i.e.,
|
||||
* after time sync with the AP).
|
||||
*/
|
||||
sc->ps_flags |= PS_BEACON_SYNC | PS_WAIT_FOR_BEACON;
|
||||
/* Reset rssi stats */
|
||||
sc->last_rssi = ATH_RSSI_DUMMY_MARKER;
|
||||
sc->sc_ah->stats.avgbrssi = ATH_RSSI_DUMMY_MARKER;
|
||||
ath_beacon_config(sc, vif);
|
||||
/*
|
||||
* Request a re-configuration of Beacon related timers
|
||||
* on the receipt of the first Beacon frame (i.e.,
|
||||
* after time sync with the AP).
|
||||
*/
|
||||
sc->ps_flags |= PS_BEACON_SYNC | PS_WAIT_FOR_BEACON;
|
||||
/* Reset rssi stats */
|
||||
sc->last_rssi = ATH_RSSI_DUMMY_MARKER;
|
||||
sc->sc_ah->stats.avgbrssi = ATH_RSSI_DUMMY_MARKER;
|
||||
|
||||
if (!common->disable_ani) {
|
||||
sc->sc_flags |= SC_OP_ANI_RUN;
|
||||
ath_start_ani(common);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -2005,6 +1995,9 @@ static void ath9k_config_bss(struct ath_softc *sc, struct ieee80211_vif *vif)
|
||||
struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;
|
||||
struct ath_vif *avp = (void *)vif->drv_priv;
|
||||
|
||||
if (sc->sc_ah->opmode != NL80211_IFTYPE_STATION)
|
||||
return;
|
||||
|
||||
/* Reconfigure bss info */
|
||||
if (avp->primary_sta_vif && !bss_conf->assoc) {
|
||||
ath_dbg(common, ATH_DBG_CONFIG,
|
||||
@ -2023,8 +2016,7 @@ static void ath9k_config_bss(struct ath_softc *sc, struct ieee80211_vif *vif)
|
||||
* None of station vifs are associated.
|
||||
* Clear bssid & aid
|
||||
*/
|
||||
if ((sc->sc_ah->opmode == NL80211_IFTYPE_STATION) &&
|
||||
!(sc->sc_flags & SC_OP_PRIM_STA_VIF)) {
|
||||
if (!(sc->sc_flags & SC_OP_PRIM_STA_VIF)) {
|
||||
ath9k_hw_write_associd(sc->sc_ah);
|
||||
/* Stop ANI */
|
||||
sc->sc_flags &= ~SC_OP_ANI_RUN;
|
||||
@ -2054,6 +2046,26 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw,
|
||||
common->curbssid, common->curaid);
|
||||
}
|
||||
|
||||
if (changed & BSS_CHANGED_IBSS) {
|
||||
/* There can be only one vif available */
|
||||
memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN);
|
||||
common->curaid = bss_conf->aid;
|
||||
ath9k_hw_write_associd(sc->sc_ah);
|
||||
|
||||
if (bss_conf->ibss_joined) {
|
||||
sc->sc_ah->stats.avgbrssi = ATH_RSSI_DUMMY_MARKER;
|
||||
|
||||
if (!common->disable_ani) {
|
||||
sc->sc_flags |= SC_OP_ANI_RUN;
|
||||
ath_start_ani(common);
|
||||
}
|
||||
|
||||
} else {
|
||||
sc->sc_flags &= ~SC_OP_ANI_RUN;
|
||||
del_timer_sync(&common->ani.timer);
|
||||
}
|
||||
}
|
||||
|
||||
/* Enable transmission of beacons (AP, IBSS, MESH) */
|
||||
if ((changed & BSS_CHANGED_BEACON) ||
|
||||
((changed & BSS_CHANGED_BEACON_ENABLED) && bss_conf->enable_beacon)) {
|
||||
@ -2334,7 +2346,7 @@ static bool ath9k_tx_frames_pending(struct ieee80211_hw *hw)
|
||||
return false;
|
||||
}
|
||||
|
||||
int ath9k_tx_last_beacon(struct ieee80211_hw *hw)
|
||||
static int ath9k_tx_last_beacon(struct ieee80211_hw *hw)
|
||||
{
|
||||
struct ath_softc *sc = hw->priv;
|
||||
struct ath_hw *ah = sc->sc_ah;
|
||||
|
@ -53,7 +53,7 @@ static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf,
|
||||
struct ath_txq *txq, struct list_head *bf_q,
|
||||
struct ath_tx_status *ts, int txok, int sendbar);
|
||||
static void ath_tx_txqaddbuf(struct ath_softc *sc, struct ath_txq *txq,
|
||||
struct list_head *head);
|
||||
struct list_head *head, bool internal);
|
||||
static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf, int len);
|
||||
static void ath_tx_rc_status(struct ath_softc *sc, struct ath_buf *bf,
|
||||
struct ath_tx_status *ts, int nframes, int nbad,
|
||||
@ -377,8 +377,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
|
||||
bf_next = bf->bf_next;
|
||||
|
||||
bf->bf_state.bf_type |= BUF_XRETRY;
|
||||
if ((sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) ||
|
||||
!bf->bf_stale || bf_next != NULL)
|
||||
if (!bf->bf_stale || bf_next != NULL)
|
||||
list_move_tail(&bf->list, &bf_head);
|
||||
|
||||
ath_tx_rc_status(sc, bf, ts, 1, 1, 0, false);
|
||||
@ -463,20 +462,14 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
|
||||
}
|
||||
}
|
||||
|
||||
if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) &&
|
||||
bf_next == NULL) {
|
||||
/*
|
||||
* Make sure the last desc is reclaimed if it
|
||||
* not a holding desc.
|
||||
*/
|
||||
if (!bf_last->bf_stale)
|
||||
list_move_tail(&bf->list, &bf_head);
|
||||
else
|
||||
INIT_LIST_HEAD(&bf_head);
|
||||
} else {
|
||||
BUG_ON(list_empty(bf_q));
|
||||
/*
|
||||
* Make sure the last desc is reclaimed if it
|
||||
* not a holding desc.
|
||||
*/
|
||||
if (!bf_last->bf_stale || bf_next != NULL)
|
||||
list_move_tail(&bf->list, &bf_head);
|
||||
}
|
||||
else
|
||||
INIT_LIST_HEAD(&bf_head);
|
||||
|
||||
if (!txpending || (tid->state & AGGR_CLEANUP)) {
|
||||
/*
|
||||
@ -837,7 +830,7 @@ static void ath_tx_sched_aggr(struct ath_softc *sc, struct ath_txq *txq,
|
||||
bf->bf_state.bf_type &= ~BUF_AGGR;
|
||||
ath9k_hw_clr11n_aggr(sc->sc_ah, bf->bf_desc);
|
||||
ath_buf_set_rate(sc, bf, fi->framelen);
|
||||
ath_tx_txqaddbuf(sc, txq, &bf_q);
|
||||
ath_tx_txqaddbuf(sc, txq, &bf_q, false);
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -849,7 +842,7 @@ static void ath_tx_sched_aggr(struct ath_softc *sc, struct ath_txq *txq,
|
||||
/* anchor last desc of aggregate */
|
||||
ath9k_hw_set11n_aggr_last(sc->sc_ah, bf->bf_lastbf->bf_desc);
|
||||
|
||||
ath_tx_txqaddbuf(sc, txq, &bf_q);
|
||||
ath_tx_txqaddbuf(sc, txq, &bf_q, false);
|
||||
TX_STAT_INC(txq->axq_qnum, a_aggr);
|
||||
|
||||
} while (txq->axq_ampdu_depth < ATH_AGGR_MIN_QDEPTH &&
|
||||
@ -1085,7 +1078,6 @@ struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype)
|
||||
txq->txq_headidx = txq->txq_tailidx = 0;
|
||||
for (i = 0; i < ATH_TXFIFO_DEPTH; i++)
|
||||
INIT_LIST_HEAD(&txq->txq_fifo[i]);
|
||||
INIT_LIST_HEAD(&txq->txq_fifo_pending);
|
||||
}
|
||||
return &sc->tx.txq[axq_qnum];
|
||||
}
|
||||
@ -1155,13 +1147,8 @@ static bool bf_is_ampdu_not_probing(struct ath_buf *bf)
|
||||
return bf_isampdu(bf) && !(info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE);
|
||||
}
|
||||
|
||||
/*
|
||||
* Drain a given TX queue (could be Beacon or Data)
|
||||
*
|
||||
* This assumes output has been stopped and
|
||||
* we do not need to block ath_tx_tasklet.
|
||||
*/
|
||||
void ath_draintxq(struct ath_softc *sc, struct ath_txq *txq, bool retry_tx)
|
||||
static void ath_drain_txq_list(struct ath_softc *sc, struct ath_txq *txq,
|
||||
struct list_head *list, bool retry_tx)
|
||||
{
|
||||
struct ath_buf *bf, *lastbf;
|
||||
struct list_head bf_head;
|
||||
@ -1170,93 +1157,63 @@ void ath_draintxq(struct ath_softc *sc, struct ath_txq *txq, bool retry_tx)
|
||||
memset(&ts, 0, sizeof(ts));
|
||||
INIT_LIST_HEAD(&bf_head);
|
||||
|
||||
for (;;) {
|
||||
spin_lock_bh(&txq->axq_lock);
|
||||
while (!list_empty(list)) {
|
||||
bf = list_first_entry(list, struct ath_buf, list);
|
||||
|
||||
if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) {
|
||||
if (list_empty(&txq->txq_fifo[txq->txq_tailidx])) {
|
||||
txq->txq_headidx = txq->txq_tailidx = 0;
|
||||
spin_unlock_bh(&txq->axq_lock);
|
||||
break;
|
||||
} else {
|
||||
bf = list_first_entry(&txq->txq_fifo[txq->txq_tailidx],
|
||||
struct ath_buf, list);
|
||||
}
|
||||
} else {
|
||||
if (list_empty(&txq->axq_q)) {
|
||||
txq->axq_link = NULL;
|
||||
spin_unlock_bh(&txq->axq_lock);
|
||||
break;
|
||||
}
|
||||
bf = list_first_entry(&txq->axq_q, struct ath_buf,
|
||||
list);
|
||||
if (bf->bf_stale) {
|
||||
list_del(&bf->list);
|
||||
|
||||
if (bf->bf_stale) {
|
||||
list_del(&bf->list);
|
||||
spin_unlock_bh(&txq->axq_lock);
|
||||
|
||||
ath_tx_return_buffer(sc, bf);
|
||||
continue;
|
||||
}
|
||||
ath_tx_return_buffer(sc, bf);
|
||||
continue;
|
||||
}
|
||||
|
||||
lastbf = bf->bf_lastbf;
|
||||
|
||||
if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) {
|
||||
list_cut_position(&bf_head,
|
||||
&txq->txq_fifo[txq->txq_tailidx],
|
||||
&lastbf->list);
|
||||
INCR(txq->txq_tailidx, ATH_TXFIFO_DEPTH);
|
||||
} else {
|
||||
/* remove ath_buf's of the same mpdu from txq */
|
||||
list_cut_position(&bf_head, &txq->axq_q, &lastbf->list);
|
||||
}
|
||||
list_cut_position(&bf_head, list, &lastbf->list);
|
||||
|
||||
txq->axq_depth--;
|
||||
if (bf_is_ampdu_not_probing(bf))
|
||||
txq->axq_ampdu_depth--;
|
||||
spin_unlock_bh(&txq->axq_lock);
|
||||
|
||||
spin_unlock_bh(&txq->axq_lock);
|
||||
if (bf_isampdu(bf))
|
||||
ath_tx_complete_aggr(sc, txq, bf, &bf_head, &ts, 0,
|
||||
retry_tx);
|
||||
else
|
||||
ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, 0, 0);
|
||||
}
|
||||
|
||||
spin_lock_bh(&txq->axq_lock);
|
||||
txq->axq_tx_inprogress = false;
|
||||
spin_unlock_bh(&txq->axq_lock);
|
||||
|
||||
if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) {
|
||||
spin_lock_bh(&txq->axq_lock);
|
||||
while (!list_empty(&txq->txq_fifo_pending)) {
|
||||
bf = list_first_entry(&txq->txq_fifo_pending,
|
||||
struct ath_buf, list);
|
||||
list_cut_position(&bf_head,
|
||||
&txq->txq_fifo_pending,
|
||||
&bf->bf_lastbf->list);
|
||||
spin_unlock_bh(&txq->axq_lock);
|
||||
|
||||
if (bf_isampdu(bf))
|
||||
ath_tx_complete_aggr(sc, txq, bf, &bf_head,
|
||||
&ts, 0, retry_tx);
|
||||
else
|
||||
ath_tx_complete_buf(sc, bf, txq, &bf_head,
|
||||
&ts, 0, 0);
|
||||
spin_lock_bh(&txq->axq_lock);
|
||||
}
|
||||
spin_unlock_bh(&txq->axq_lock);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Drain a given TX queue (could be Beacon or Data)
|
||||
*
|
||||
* This assumes output has been stopped and
|
||||
* we do not need to block ath_tx_tasklet.
|
||||
*/
|
||||
void ath_draintxq(struct ath_softc *sc, struct ath_txq *txq, bool retry_tx)
|
||||
{
|
||||
spin_lock_bh(&txq->axq_lock);
|
||||
if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) {
|
||||
int idx = txq->txq_tailidx;
|
||||
|
||||
while (!list_empty(&txq->txq_fifo[idx])) {
|
||||
ath_drain_txq_list(sc, txq, &txq->txq_fifo[idx],
|
||||
retry_tx);
|
||||
|
||||
INCR(idx, ATH_TXFIFO_DEPTH);
|
||||
}
|
||||
txq->txq_tailidx = idx;
|
||||
}
|
||||
|
||||
txq->axq_link = NULL;
|
||||
txq->axq_tx_inprogress = false;
|
||||
ath_drain_txq_list(sc, txq, &txq->axq_q, retry_tx);
|
||||
|
||||
/* flush any pending frames if aggregation is enabled */
|
||||
if (sc->sc_flags & SC_OP_TXAGGR) {
|
||||
if (!retry_tx) {
|
||||
spin_lock_bh(&txq->axq_lock);
|
||||
ath_txq_drain_pending_buffers(sc, txq);
|
||||
spin_unlock_bh(&txq->axq_lock);
|
||||
}
|
||||
}
|
||||
if ((sc->sc_flags & SC_OP_TXAGGR) && !retry_tx)
|
||||
ath_txq_drain_pending_buffers(sc, txq);
|
||||
|
||||
spin_unlock_bh(&txq->axq_lock);
|
||||
}
|
||||
|
||||
bool ath_drain_all_txq(struct ath_softc *sc, bool retry_tx)
|
||||
@ -1370,11 +1327,13 @@ void ath_txq_schedule(struct ath_softc *sc, struct ath_txq *txq)
|
||||
* assume the descriptors are already chained together by caller.
|
||||
*/
|
||||
static void ath_tx_txqaddbuf(struct ath_softc *sc, struct ath_txq *txq,
|
||||
struct list_head *head)
|
||||
struct list_head *head, bool internal)
|
||||
{
|
||||
struct ath_hw *ah = sc->sc_ah;
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
struct ath_buf *bf;
|
||||
struct ath_buf *bf, *bf_last;
|
||||
bool puttxbuf = false;
|
||||
bool edma;
|
||||
|
||||
/*
|
||||
* Insert the frame on the outbound list and
|
||||
@ -1384,51 +1343,49 @@ static void ath_tx_txqaddbuf(struct ath_softc *sc, struct ath_txq *txq,
|
||||
if (list_empty(head))
|
||||
return;
|
||||
|
||||
edma = !!(ah->caps.hw_caps & ATH9K_HW_CAP_EDMA);
|
||||
bf = list_first_entry(head, struct ath_buf, list);
|
||||
bf_last = list_entry(head->prev, struct ath_buf, list);
|
||||
|
||||
ath_dbg(common, ATH_DBG_QUEUE,
|
||||
"qnum: %d, txq depth: %d\n", txq->axq_qnum, txq->axq_depth);
|
||||
|
||||
if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) {
|
||||
if (txq->axq_depth >= ATH_TXFIFO_DEPTH) {
|
||||
list_splice_tail_init(head, &txq->txq_fifo_pending);
|
||||
return;
|
||||
}
|
||||
if (!list_empty(&txq->txq_fifo[txq->txq_headidx]))
|
||||
ath_dbg(common, ATH_DBG_XMIT,
|
||||
"Initializing tx fifo %d which is non-empty\n",
|
||||
txq->txq_headidx);
|
||||
INIT_LIST_HEAD(&txq->txq_fifo[txq->txq_headidx]);
|
||||
list_splice_init(head, &txq->txq_fifo[txq->txq_headidx]);
|
||||
if (edma && list_empty(&txq->txq_fifo[txq->txq_headidx])) {
|
||||
list_splice_tail_init(head, &txq->txq_fifo[txq->txq_headidx]);
|
||||
INCR(txq->txq_headidx, ATH_TXFIFO_DEPTH);
|
||||
TX_STAT_INC(txq->axq_qnum, puttxbuf);
|
||||
ath9k_hw_puttxbuf(ah, txq->axq_qnum, bf->bf_daddr);
|
||||
ath_dbg(common, ATH_DBG_XMIT, "TXDP[%u] = %llx (%p)\n",
|
||||
txq->axq_qnum, ito64(bf->bf_daddr), bf->bf_desc);
|
||||
puttxbuf = true;
|
||||
} else {
|
||||
list_splice_tail_init(head, &txq->axq_q);
|
||||
|
||||
if (txq->axq_link == NULL) {
|
||||
TX_STAT_INC(txq->axq_qnum, puttxbuf);
|
||||
ath9k_hw_puttxbuf(ah, txq->axq_qnum, bf->bf_daddr);
|
||||
ath_dbg(common, ATH_DBG_XMIT, "TXDP[%u] = %llx (%p)\n",
|
||||
txq->axq_qnum, ito64(bf->bf_daddr),
|
||||
bf->bf_desc);
|
||||
} else {
|
||||
*txq->axq_link = bf->bf_daddr;
|
||||
if (txq->axq_link) {
|
||||
ath9k_hw_set_desc_link(ah, txq->axq_link, bf->bf_daddr);
|
||||
ath_dbg(common, ATH_DBG_XMIT,
|
||||
"link[%u] (%p)=%llx (%p)\n",
|
||||
txq->axq_qnum, txq->axq_link,
|
||||
ito64(bf->bf_daddr), bf->bf_desc);
|
||||
}
|
||||
ath9k_hw_get_desc_link(ah, bf->bf_lastbf->bf_desc,
|
||||
&txq->axq_link);
|
||||
} else if (!edma)
|
||||
puttxbuf = true;
|
||||
|
||||
txq->axq_link = bf_last->bf_desc;
|
||||
}
|
||||
|
||||
if (puttxbuf) {
|
||||
TX_STAT_INC(txq->axq_qnum, puttxbuf);
|
||||
ath9k_hw_puttxbuf(ah, txq->axq_qnum, bf->bf_daddr);
|
||||
ath_dbg(common, ATH_DBG_XMIT, "TXDP[%u] = %llx (%p)\n",
|
||||
txq->axq_qnum, ito64(bf->bf_daddr), bf->bf_desc);
|
||||
}
|
||||
|
||||
if (!edma) {
|
||||
TX_STAT_INC(txq->axq_qnum, txstart);
|
||||
ath9k_hw_txstart(ah, txq->axq_qnum);
|
||||
}
|
||||
txq->axq_depth++;
|
||||
if (bf_is_ampdu_not_probing(bf))
|
||||
txq->axq_ampdu_depth++;
|
||||
|
||||
if (!internal) {
|
||||
txq->axq_depth++;
|
||||
if (bf_is_ampdu_not_probing(bf))
|
||||
txq->axq_ampdu_depth++;
|
||||
}
|
||||
}
|
||||
|
||||
static void ath_tx_send_ampdu(struct ath_softc *sc, struct ath_atx_tid *tid,
|
||||
@ -1470,7 +1427,7 @@ static void ath_tx_send_ampdu(struct ath_softc *sc, struct ath_atx_tid *tid,
|
||||
TX_STAT_INC(txctl->txq->axq_qnum, a_queued_hw);
|
||||
bf->bf_lastbf = bf;
|
||||
ath_buf_set_rate(sc, bf, fi->framelen);
|
||||
ath_tx_txqaddbuf(sc, txctl->txq, &bf_head);
|
||||
ath_tx_txqaddbuf(sc, txctl->txq, &bf_head, false);
|
||||
}
|
||||
|
||||
static void ath_tx_send_normal(struct ath_softc *sc, struct ath_txq *txq,
|
||||
@ -1490,7 +1447,7 @@ static void ath_tx_send_normal(struct ath_softc *sc, struct ath_txq *txq,
|
||||
bf->bf_lastbf = bf;
|
||||
fi = get_frame_info(bf->bf_mpdu);
|
||||
ath_buf_set_rate(sc, bf, fi->framelen);
|
||||
ath_tx_txqaddbuf(sc, txq, bf_head);
|
||||
ath_tx_txqaddbuf(sc, txq, bf_head, false);
|
||||
TX_STAT_INC(txq->axq_qnum, queued);
|
||||
}
|
||||
|
||||
@ -2077,6 +2034,38 @@ static void ath_tx_rc_status(struct ath_softc *sc, struct ath_buf *bf,
|
||||
tx_info->status.rates[tx_rateindex].count = ts->ts_longretry + 1;
|
||||
}
|
||||
|
||||
static void ath_tx_process_buffer(struct ath_softc *sc, struct ath_txq *txq,
|
||||
struct ath_tx_status *ts, struct ath_buf *bf,
|
||||
struct list_head *bf_head)
|
||||
{
|
||||
int txok;
|
||||
|
||||
txq->axq_depth--;
|
||||
txok = !(ts->ts_status & ATH9K_TXERR_MASK);
|
||||
txq->axq_tx_inprogress = false;
|
||||
if (bf_is_ampdu_not_probing(bf))
|
||||
txq->axq_ampdu_depth--;
|
||||
|
||||
spin_unlock_bh(&txq->axq_lock);
|
||||
|
||||
if (!bf_isampdu(bf)) {
|
||||
/*
|
||||
* This frame is sent out as a single frame.
|
||||
* Use hardware retry status for this frame.
|
||||
*/
|
||||
if (ts->ts_status & ATH9K_TXERR_XRETRY)
|
||||
bf->bf_state.bf_type |= BUF_XRETRY;
|
||||
ath_tx_rc_status(sc, bf, ts, 1, txok ? 0 : 1, txok, true);
|
||||
ath_tx_complete_buf(sc, bf, txq, bf_head, ts, txok, 0);
|
||||
} else
|
||||
ath_tx_complete_aggr(sc, txq, bf, bf_head, ts, txok, true);
|
||||
|
||||
spin_lock_bh(&txq->axq_lock);
|
||||
|
||||
if (sc->sc_flags & SC_OP_TXAGGR)
|
||||
ath_txq_schedule(sc, txq);
|
||||
}
|
||||
|
||||
static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq)
|
||||
{
|
||||
struct ath_hw *ah = sc->sc_ah;
|
||||
@ -2085,20 +2074,18 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq)
|
||||
struct list_head bf_head;
|
||||
struct ath_desc *ds;
|
||||
struct ath_tx_status ts;
|
||||
int txok;
|
||||
int status;
|
||||
|
||||
ath_dbg(common, ATH_DBG_QUEUE, "tx queue %d (%x), link %p\n",
|
||||
txq->axq_qnum, ath9k_hw_gettxbuf(sc->sc_ah, txq->axq_qnum),
|
||||
txq->axq_link);
|
||||
|
||||
spin_lock_bh(&txq->axq_lock);
|
||||
for (;;) {
|
||||
spin_lock_bh(&txq->axq_lock);
|
||||
if (list_empty(&txq->axq_q)) {
|
||||
txq->axq_link = NULL;
|
||||
if (sc->sc_flags & SC_OP_TXAGGR)
|
||||
ath_txq_schedule(sc, txq);
|
||||
spin_unlock_bh(&txq->axq_lock);
|
||||
break;
|
||||
}
|
||||
bf = list_first_entry(&txq->axq_q, struct ath_buf, list);
|
||||
@ -2114,13 +2101,11 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq)
|
||||
bf_held = NULL;
|
||||
if (bf->bf_stale) {
|
||||
bf_held = bf;
|
||||
if (list_is_last(&bf_held->list, &txq->axq_q)) {
|
||||
spin_unlock_bh(&txq->axq_lock);
|
||||
if (list_is_last(&bf_held->list, &txq->axq_q))
|
||||
break;
|
||||
} else {
|
||||
bf = list_entry(bf_held->list.next,
|
||||
struct ath_buf, list);
|
||||
}
|
||||
|
||||
bf = list_entry(bf_held->list.next, struct ath_buf,
|
||||
list);
|
||||
}
|
||||
|
||||
lastbf = bf->bf_lastbf;
|
||||
@ -2128,10 +2113,9 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq)
|
||||
|
||||
memset(&ts, 0, sizeof(ts));
|
||||
status = ath9k_hw_txprocdesc(ah, ds, &ts);
|
||||
if (status == -EINPROGRESS) {
|
||||
spin_unlock_bh(&txq->axq_lock);
|
||||
if (status == -EINPROGRESS)
|
||||
break;
|
||||
}
|
||||
|
||||
TX_STAT_INC(txq->axq_qnum, txprocdesc);
|
||||
|
||||
/*
|
||||
@ -2145,42 +2129,14 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq)
|
||||
list_cut_position(&bf_head,
|
||||
&txq->axq_q, lastbf->list.prev);
|
||||
|
||||
txq->axq_depth--;
|
||||
txok = !(ts.ts_status & ATH9K_TXERR_MASK);
|
||||
txq->axq_tx_inprogress = false;
|
||||
if (bf_held)
|
||||
if (bf_held) {
|
||||
list_del(&bf_held->list);
|
||||
|
||||
if (bf_is_ampdu_not_probing(bf))
|
||||
txq->axq_ampdu_depth--;
|
||||
|
||||
spin_unlock_bh(&txq->axq_lock);
|
||||
|
||||
if (bf_held)
|
||||
ath_tx_return_buffer(sc, bf_held);
|
||||
|
||||
if (!bf_isampdu(bf)) {
|
||||
/*
|
||||
* This frame is sent out as a single frame.
|
||||
* Use hardware retry status for this frame.
|
||||
*/
|
||||
if (ts.ts_status & ATH9K_TXERR_XRETRY)
|
||||
bf->bf_state.bf_type |= BUF_XRETRY;
|
||||
ath_tx_rc_status(sc, bf, &ts, 1, txok ? 0 : 1, txok, true);
|
||||
}
|
||||
|
||||
if (bf_isampdu(bf))
|
||||
ath_tx_complete_aggr(sc, txq, bf, &bf_head, &ts, txok,
|
||||
true);
|
||||
else
|
||||
ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, txok, 0);
|
||||
|
||||
spin_lock_bh(&txq->axq_lock);
|
||||
|
||||
if (sc->sc_flags & SC_OP_TXAGGR)
|
||||
ath_txq_schedule(sc, txq);
|
||||
spin_unlock_bh(&txq->axq_lock);
|
||||
ath_tx_process_buffer(sc, txq, &ts, bf, &bf_head);
|
||||
}
|
||||
spin_unlock_bh(&txq->axq_lock);
|
||||
}
|
||||
|
||||
static void ath_tx_complete_poll_work(struct work_struct *work)
|
||||
@ -2237,17 +2193,16 @@ void ath_tx_tasklet(struct ath_softc *sc)
|
||||
|
||||
void ath_tx_edma_tasklet(struct ath_softc *sc)
|
||||
{
|
||||
struct ath_tx_status txs;
|
||||
struct ath_tx_status ts;
|
||||
struct ath_common *common = ath9k_hw_common(sc->sc_ah);
|
||||
struct ath_hw *ah = sc->sc_ah;
|
||||
struct ath_txq *txq;
|
||||
struct ath_buf *bf, *lastbf;
|
||||
struct list_head bf_head;
|
||||
int status;
|
||||
int txok;
|
||||
|
||||
for (;;) {
|
||||
status = ath9k_hw_txprocdesc(ah, NULL, (void *)&txs);
|
||||
status = ath9k_hw_txprocdesc(ah, NULL, (void *)&ts);
|
||||
if (status == -EINPROGRESS)
|
||||
break;
|
||||
if (status == -EIO) {
|
||||
@ -2257,12 +2212,13 @@ void ath_tx_edma_tasklet(struct ath_softc *sc)
|
||||
}
|
||||
|
||||
/* Skip beacon completions */
|
||||
if (txs.qid == sc->beacon.beaconq)
|
||||
if (ts.qid == sc->beacon.beaconq)
|
||||
continue;
|
||||
|
||||
txq = &sc->tx.txq[txs.qid];
|
||||
txq = &sc->tx.txq[ts.qid];
|
||||
|
||||
spin_lock_bh(&txq->axq_lock);
|
||||
|
||||
if (list_empty(&txq->txq_fifo[txq->txq_tailidx])) {
|
||||
spin_unlock_bh(&txq->axq_lock);
|
||||
return;
|
||||
@ -2275,41 +2231,21 @@ void ath_tx_edma_tasklet(struct ath_softc *sc)
|
||||
INIT_LIST_HEAD(&bf_head);
|
||||
list_cut_position(&bf_head, &txq->txq_fifo[txq->txq_tailidx],
|
||||
&lastbf->list);
|
||||
INCR(txq->txq_tailidx, ATH_TXFIFO_DEPTH);
|
||||
txq->axq_depth--;
|
||||
txq->axq_tx_inprogress = false;
|
||||
if (bf_is_ampdu_not_probing(bf))
|
||||
txq->axq_ampdu_depth--;
|
||||
spin_unlock_bh(&txq->axq_lock);
|
||||
|
||||
txok = !(txs.ts_status & ATH9K_TXERR_MASK);
|
||||
if (list_empty(&txq->txq_fifo[txq->txq_tailidx])) {
|
||||
INCR(txq->txq_tailidx, ATH_TXFIFO_DEPTH);
|
||||
|
||||
if (!bf_isampdu(bf)) {
|
||||
if (txs.ts_status & ATH9K_TXERR_XRETRY)
|
||||
bf->bf_state.bf_type |= BUF_XRETRY;
|
||||
ath_tx_rc_status(sc, bf, &txs, 1, txok ? 0 : 1, txok, true);
|
||||
if (!list_empty(&txq->axq_q)) {
|
||||
struct list_head bf_q;
|
||||
|
||||
INIT_LIST_HEAD(&bf_q);
|
||||
txq->axq_link = NULL;
|
||||
list_splice_tail_init(&txq->axq_q, &bf_q);
|
||||
ath_tx_txqaddbuf(sc, txq, &bf_q, true);
|
||||
}
|
||||
}
|
||||
|
||||
if (bf_isampdu(bf))
|
||||
ath_tx_complete_aggr(sc, txq, bf, &bf_head, &txs,
|
||||
txok, true);
|
||||
else
|
||||
ath_tx_complete_buf(sc, bf, txq, &bf_head,
|
||||
&txs, txok, 0);
|
||||
|
||||
spin_lock_bh(&txq->axq_lock);
|
||||
|
||||
if (!list_empty(&txq->txq_fifo_pending)) {
|
||||
INIT_LIST_HEAD(&bf_head);
|
||||
bf = list_first_entry(&txq->txq_fifo_pending,
|
||||
struct ath_buf, list);
|
||||
list_cut_position(&bf_head,
|
||||
&txq->txq_fifo_pending,
|
||||
&bf->bf_lastbf->list);
|
||||
ath_tx_txqaddbuf(sc, txq, &bf_head);
|
||||
} else if (sc->sc_flags & SC_OP_TXAGGR)
|
||||
ath_txq_schedule(sc, txq);
|
||||
|
||||
ath_tx_process_buffer(sc, txq, &ts, bf, &bf_head);
|
||||
spin_unlock_bh(&txq->axq_lock);
|
||||
}
|
||||
}
|
||||
|
@ -26,6 +26,11 @@ config B43
|
||||
This driver can be built as a module (recommended) that will be called "b43".
|
||||
If unsure, say M.
|
||||
|
||||
config B43_BCMA
|
||||
bool "Support for BCMA bus"
|
||||
depends on B43 && BCMA && BROKEN
|
||||
default y
|
||||
|
||||
# Auto-select SSB PCI-HOST support, if possible
|
||||
config B43_PCI_AUTOSELECT
|
||||
bool
|
||||
|
@ -1,4 +1,5 @@
|
||||
b43-y += main.o
|
||||
b43-y += bus.o
|
||||
b43-y += tables.o
|
||||
b43-$(CONFIG_B43_PHY_N) += tables_nphy.o
|
||||
b43-$(CONFIG_B43_PHY_N) += radio_2055.o
|
||||
|
@ -5,12 +5,14 @@
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/hw_random.h>
|
||||
#include <linux/bcma/bcma.h>
|
||||
#include <linux/ssb/ssb.h>
|
||||
#include <net/mac80211.h>
|
||||
|
||||
#include "debugfs.h"
|
||||
#include "leds.h"
|
||||
#include "rfkill.h"
|
||||
#include "bus.h"
|
||||
#include "lo.h"
|
||||
#include "phy_common.h"
|
||||
|
||||
@ -414,6 +416,17 @@ enum {
|
||||
#define B43_MACCMD_CCA 0x00000008 /* Clear channel assessment */
|
||||
#define B43_MACCMD_BGNOISE 0x00000010 /* Background noise */
|
||||
|
||||
/* BCMA 802.11 core specific IO Control (BCMA_IOCTL) flags */
|
||||
#define B43_BCMA_IOCTL_PHY_CLKEN 0x00000004 /* PHY Clock Enable */
|
||||
#define B43_BCMA_IOCTL_PHY_RESET 0x00000008 /* PHY Reset */
|
||||
#define B43_BCMA_IOCTL_MACPHYCLKEN 0x00000010 /* MAC PHY Clock Control Enable */
|
||||
#define B43_BCMA_IOCTL_PLLREFSEL 0x00000020 /* PLL Frequency Reference Select */
|
||||
#define B43_BCMA_IOCTL_PHY_BW 0x000000C0 /* PHY band width and clock speed mask (N-PHY+ only?) */
|
||||
#define B43_BCMA_IOCTL_PHY_BW_10MHZ 0x00000000 /* 10 MHz bandwidth, 40 MHz PHY */
|
||||
#define B43_BCMA_IOCTL_PHY_BW_20MHZ 0x00000040 /* 20 MHz bandwidth, 80 MHz PHY */
|
||||
#define B43_BCMA_IOCTL_PHY_BW_40MHZ 0x00000080 /* 40 MHz bandwidth, 160 MHz PHY */
|
||||
#define B43_BCMA_IOCTL_GMODE 0x00002000 /* G Mode Enable */
|
||||
|
||||
/* 802.11 core specific TM State Low (SSB_TMSLOW) flags */
|
||||
#define B43_TMSLOW_GMODE 0x20000000 /* G Mode Enable */
|
||||
#define B43_TMSLOW_PHY_BANDWIDTH 0x00C00000 /* PHY band width and clock speed mask (N-PHY only) */
|
||||
@ -707,7 +720,8 @@ enum {
|
||||
|
||||
/* Data structure for one wireless device (802.11 core) */
|
||||
struct b43_wldev {
|
||||
struct ssb_device *sdev;
|
||||
struct ssb_device *sdev; /* TODO: remove when b43_bus_dev is ready */
|
||||
struct b43_bus_dev *dev;
|
||||
struct b43_wl *wl;
|
||||
|
||||
/* The device initialization status.
|
||||
@ -879,36 +893,59 @@ static inline enum ieee80211_band b43_current_band(struct b43_wl *wl)
|
||||
return wl->hw->conf.channel->band;
|
||||
}
|
||||
|
||||
static inline int b43_bus_may_powerdown(struct b43_wldev *wldev)
|
||||
{
|
||||
return wldev->dev->bus_may_powerdown(wldev->dev);
|
||||
}
|
||||
static inline int b43_bus_powerup(struct b43_wldev *wldev, bool dynamic_pctl)
|
||||
{
|
||||
return wldev->dev->bus_powerup(wldev->dev, dynamic_pctl);
|
||||
}
|
||||
static inline int b43_device_is_enabled(struct b43_wldev *wldev)
|
||||
{
|
||||
return wldev->dev->device_is_enabled(wldev->dev);
|
||||
}
|
||||
static inline void b43_device_enable(struct b43_wldev *wldev,
|
||||
u32 core_specific_flags)
|
||||
{
|
||||
wldev->dev->device_enable(wldev->dev, core_specific_flags);
|
||||
}
|
||||
static inline void b43_device_disable(struct b43_wldev *wldev,
|
||||
u32 core_specific_flags)
|
||||
{
|
||||
wldev->dev->device_disable(wldev->dev, core_specific_flags);
|
||||
}
|
||||
|
||||
static inline u16 b43_read16(struct b43_wldev *dev, u16 offset)
|
||||
{
|
||||
return ssb_read16(dev->sdev, offset);
|
||||
return dev->dev->read16(dev->dev, offset);
|
||||
}
|
||||
|
||||
static inline void b43_write16(struct b43_wldev *dev, u16 offset, u16 value)
|
||||
{
|
||||
ssb_write16(dev->sdev, offset, value);
|
||||
dev->dev->write16(dev->dev, offset, value);
|
||||
}
|
||||
|
||||
static inline u32 b43_read32(struct b43_wldev *dev, u16 offset)
|
||||
{
|
||||
return ssb_read32(dev->sdev, offset);
|
||||
return dev->dev->read32(dev->dev, offset);
|
||||
}
|
||||
|
||||
static inline void b43_write32(struct b43_wldev *dev, u16 offset, u32 value)
|
||||
{
|
||||
ssb_write32(dev->sdev, offset, value);
|
||||
dev->dev->write32(dev->dev, offset, value);
|
||||
}
|
||||
|
||||
static inline void b43_block_read(struct b43_wldev *dev, void *buffer,
|
||||
size_t count, u16 offset, u8 reg_width)
|
||||
{
|
||||
ssb_block_read(dev->sdev, buffer, count, offset, reg_width);
|
||||
dev->dev->block_read(dev->dev, buffer, count, offset, reg_width);
|
||||
}
|
||||
|
||||
static inline void b43_block_write(struct b43_wldev *dev, const void *buffer,
|
||||
size_t count, u16 offset, u8 reg_width)
|
||||
{
|
||||
ssb_block_write(dev->sdev, buffer, count, offset, reg_width);
|
||||
dev->dev->block_write(dev->dev, buffer, count, offset, reg_width);
|
||||
}
|
||||
|
||||
static inline bool b43_using_pio_transfers(struct b43_wldev *dev)
|
||||
|
122
drivers/net/wireless/b43/bus.c
Normal file
122
drivers/net/wireless/b43/bus.c
Normal file
@ -0,0 +1,122 @@
|
||||
/*
|
||||
|
||||
Broadcom B43 wireless driver
|
||||
Bus abstraction layer
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,
|
||||
Boston, MA 02110-1301, USA.
|
||||
|
||||
*/
|
||||
|
||||
#include "b43.h"
|
||||
#include "bus.h"
|
||||
|
||||
|
||||
/* SSB */
|
||||
|
||||
static inline int b43_bus_ssb_bus_may_powerdown(struct b43_bus_dev *dev)
|
||||
{
|
||||
return ssb_bus_may_powerdown(dev->sdev->bus);
|
||||
}
|
||||
static inline int b43_bus_ssb_bus_powerup(struct b43_bus_dev *dev,
|
||||
bool dynamic_pctl)
|
||||
{
|
||||
return ssb_bus_powerup(dev->sdev->bus, dynamic_pctl);
|
||||
}
|
||||
static inline int b43_bus_ssb_device_is_enabled(struct b43_bus_dev *dev)
|
||||
{
|
||||
return ssb_device_is_enabled(dev->sdev);
|
||||
}
|
||||
static inline void b43_bus_ssb_device_enable(struct b43_bus_dev *dev,
|
||||
u32 core_specific_flags)
|
||||
{
|
||||
ssb_device_enable(dev->sdev, core_specific_flags);
|
||||
}
|
||||
static inline void b43_bus_ssb_device_disable(struct b43_bus_dev *dev,
|
||||
u32 core_specific_flags)
|
||||
{
|
||||
ssb_device_disable(dev->sdev, core_specific_flags);
|
||||
}
|
||||
|
||||
static inline u16 b43_bus_ssb_read16(struct b43_bus_dev *dev, u16 offset)
|
||||
{
|
||||
return ssb_read16(dev->sdev, offset);
|
||||
}
|
||||
static inline u32 b43_bus_ssb_read32(struct b43_bus_dev *dev, u16 offset)
|
||||
{
|
||||
return ssb_read32(dev->sdev, offset);
|
||||
}
|
||||
static inline
|
||||
void b43_bus_ssb_write16(struct b43_bus_dev *dev, u16 offset, u16 value)
|
||||
{
|
||||
ssb_write16(dev->sdev, offset, value);
|
||||
}
|
||||
static inline
|
||||
void b43_bus_ssb_write32(struct b43_bus_dev *dev, u16 offset, u32 value)
|
||||
{
|
||||
ssb_write32(dev->sdev, offset, value);
|
||||
}
|
||||
static inline
|
||||
void b43_bus_ssb_block_read(struct b43_bus_dev *dev, void *buffer,
|
||||
size_t count, u16 offset, u8 reg_width)
|
||||
{
|
||||
ssb_block_read(dev->sdev, buffer, count, offset, reg_width);
|
||||
}
|
||||
static inline
|
||||
void b43_bus_ssb_block_write(struct b43_bus_dev *dev, const void *buffer,
|
||||
size_t count, u16 offset, u8 reg_width)
|
||||
{
|
||||
ssb_block_write(dev->sdev, buffer, count, offset, reg_width);
|
||||
}
|
||||
|
||||
struct b43_bus_dev *b43_bus_dev_ssb_init(struct ssb_device *sdev)
|
||||
{
|
||||
struct b43_bus_dev *dev = kzalloc(sizeof(*dev), GFP_KERNEL);
|
||||
|
||||
dev->bus_type = B43_BUS_SSB;
|
||||
dev->sdev = sdev;
|
||||
|
||||
dev->bus_may_powerdown = b43_bus_ssb_bus_may_powerdown;
|
||||
dev->bus_powerup = b43_bus_ssb_bus_powerup;
|
||||
dev->device_is_enabled = b43_bus_ssb_device_is_enabled;
|
||||
dev->device_enable = b43_bus_ssb_device_enable;
|
||||
dev->device_disable = b43_bus_ssb_device_disable;
|
||||
|
||||
dev->read16 = b43_bus_ssb_read16;
|
||||
dev->read32 = b43_bus_ssb_read32;
|
||||
dev->write16 = b43_bus_ssb_write16;
|
||||
dev->write32 = b43_bus_ssb_write32;
|
||||
dev->block_read = b43_bus_ssb_block_read;
|
||||
dev->block_write = b43_bus_ssb_block_write;
|
||||
|
||||
dev->dev = sdev->dev;
|
||||
dev->dma_dev = sdev->dma_dev;
|
||||
dev->irq = sdev->irq;
|
||||
|
||||
dev->board_vendor = sdev->bus->boardinfo.vendor;
|
||||
dev->board_type = sdev->bus->boardinfo.type;
|
||||
dev->board_rev = sdev->bus->boardinfo.rev;
|
||||
|
||||
dev->chip_id = sdev->bus->chip_id;
|
||||
dev->chip_rev = sdev->bus->chip_rev;
|
||||
dev->chip_pkg = sdev->bus->chip_package;
|
||||
|
||||
dev->bus_sprom = &sdev->bus->sprom;
|
||||
|
||||
dev->core_id = sdev->id.coreid;
|
||||
dev->core_rev = sdev->id.revision;
|
||||
|
||||
return dev;
|
||||
}
|
62
drivers/net/wireless/b43/bus.h
Normal file
62
drivers/net/wireless/b43/bus.h
Normal file
@ -0,0 +1,62 @@
|
||||
#ifndef B43_BUS_H_
|
||||
#define B43_BUS_H_
|
||||
|
||||
enum b43_bus_type {
|
||||
B43_BUS_SSB,
|
||||
};
|
||||
|
||||
struct b43_bus_dev {
|
||||
enum b43_bus_type bus_type;
|
||||
union {
|
||||
struct ssb_device *sdev;
|
||||
};
|
||||
|
||||
int (*bus_may_powerdown)(struct b43_bus_dev *dev);
|
||||
int (*bus_powerup)(struct b43_bus_dev *dev, bool dynamic_pctl);
|
||||
int (*device_is_enabled)(struct b43_bus_dev *dev);
|
||||
void (*device_enable)(struct b43_bus_dev *dev,
|
||||
u32 core_specific_flags);
|
||||
void (*device_disable)(struct b43_bus_dev *dev,
|
||||
u32 core_specific_flags);
|
||||
|
||||
u16 (*read16)(struct b43_bus_dev *dev, u16 offset);
|
||||
u32 (*read32)(struct b43_bus_dev *dev, u16 offset);
|
||||
void (*write16)(struct b43_bus_dev *dev, u16 offset, u16 value);
|
||||
void (*write32)(struct b43_bus_dev *dev, u16 offset, u32 value);
|
||||
void (*block_read)(struct b43_bus_dev *dev, void *buffer,
|
||||
size_t count, u16 offset, u8 reg_width);
|
||||
void (*block_write)(struct b43_bus_dev *dev, const void *buffer,
|
||||
size_t count, u16 offset, u8 reg_width);
|
||||
|
||||
struct device *dev;
|
||||
struct device *dma_dev;
|
||||
unsigned int irq;
|
||||
|
||||
u16 board_vendor;
|
||||
u16 board_type;
|
||||
u16 board_rev;
|
||||
|
||||
u16 chip_id;
|
||||
u8 chip_rev;
|
||||
u8 chip_pkg;
|
||||
|
||||
struct ssb_sprom *bus_sprom;
|
||||
|
||||
u16 core_id;
|
||||
u8 core_rev;
|
||||
};
|
||||
|
||||
static inline bool b43_bus_host_is_pcmcia(struct b43_bus_dev *dev)
|
||||
{
|
||||
return (dev->bus_type == B43_BUS_SSB &&
|
||||
dev->sdev->bus->bustype == SSB_BUSTYPE_PCMCIA);
|
||||
}
|
||||
static inline bool b43_bus_host_is_sdio(struct b43_bus_dev *dev)
|
||||
{
|
||||
return (dev->bus_type == B43_BUS_SSB &&
|
||||
dev->sdev->bus->bustype == SSB_BUSTYPE_SDIO);
|
||||
}
|
||||
|
||||
struct b43_bus_dev *b43_bus_dev_ssb_init(struct ssb_device *sdev);
|
||||
|
||||
#endif /* B43_BUS_H_ */
|
@ -333,10 +333,10 @@ static inline
|
||||
dma_addr_t dmaaddr;
|
||||
|
||||
if (tx) {
|
||||
dmaaddr = dma_map_single(ring->dev->sdev->dma_dev,
|
||||
dmaaddr = dma_map_single(ring->dev->dev->dma_dev,
|
||||
buf, len, DMA_TO_DEVICE);
|
||||
} else {
|
||||
dmaaddr = dma_map_single(ring->dev->sdev->dma_dev,
|
||||
dmaaddr = dma_map_single(ring->dev->dev->dma_dev,
|
||||
buf, len, DMA_FROM_DEVICE);
|
||||
}
|
||||
|
||||
@ -348,10 +348,10 @@ static inline
|
||||
dma_addr_t addr, size_t len, int tx)
|
||||
{
|
||||
if (tx) {
|
||||
dma_unmap_single(ring->dev->sdev->dma_dev,
|
||||
dma_unmap_single(ring->dev->dev->dma_dev,
|
||||
addr, len, DMA_TO_DEVICE);
|
||||
} else {
|
||||
dma_unmap_single(ring->dev->sdev->dma_dev,
|
||||
dma_unmap_single(ring->dev->dev->dma_dev,
|
||||
addr, len, DMA_FROM_DEVICE);
|
||||
}
|
||||
}
|
||||
@ -361,7 +361,7 @@ static inline
|
||||
dma_addr_t addr, size_t len)
|
||||
{
|
||||
B43_WARN_ON(ring->tx);
|
||||
dma_sync_single_for_cpu(ring->dev->sdev->dma_dev,
|
||||
dma_sync_single_for_cpu(ring->dev->dev->dma_dev,
|
||||
addr, len, DMA_FROM_DEVICE);
|
||||
}
|
||||
|
||||
@ -370,7 +370,7 @@ static inline
|
||||
dma_addr_t addr, size_t len)
|
||||
{
|
||||
B43_WARN_ON(ring->tx);
|
||||
dma_sync_single_for_device(ring->dev->sdev->dma_dev,
|
||||
dma_sync_single_for_device(ring->dev->dev->dma_dev,
|
||||
addr, len, DMA_FROM_DEVICE);
|
||||
}
|
||||
|
||||
@ -401,7 +401,7 @@ static int alloc_ringmemory(struct b43_dmaring *ring)
|
||||
*/
|
||||
if (ring->type == B43_DMA_64BIT)
|
||||
flags |= GFP_DMA;
|
||||
ring->descbase = dma_alloc_coherent(ring->dev->sdev->dma_dev,
|
||||
ring->descbase = dma_alloc_coherent(ring->dev->dev->dma_dev,
|
||||
B43_DMA_RINGMEMSIZE,
|
||||
&(ring->dmabase), flags);
|
||||
if (!ring->descbase) {
|
||||
@ -415,7 +415,7 @@ static int alloc_ringmemory(struct b43_dmaring *ring)
|
||||
|
||||
static void free_ringmemory(struct b43_dmaring *ring)
|
||||
{
|
||||
dma_free_coherent(ring->dev->sdev->dma_dev, B43_DMA_RINGMEMSIZE,
|
||||
dma_free_coherent(ring->dev->dev->dma_dev, B43_DMA_RINGMEMSIZE,
|
||||
ring->descbase, ring->dmabase);
|
||||
}
|
||||
|
||||
@ -523,7 +523,7 @@ static bool b43_dma_mapping_error(struct b43_dmaring *ring,
|
||||
dma_addr_t addr,
|
||||
size_t buffersize, bool dma_to_device)
|
||||
{
|
||||
if (unlikely(dma_mapping_error(ring->dev->sdev->dma_dev, addr)))
|
||||
if (unlikely(dma_mapping_error(ring->dev->dev->dma_dev, addr)))
|
||||
return 1;
|
||||
|
||||
switch (ring->type) {
|
||||
@ -757,14 +757,14 @@ static void dmacontroller_cleanup(struct b43_dmaring *ring)
|
||||
|
||||
static void free_all_descbuffers(struct b43_dmaring *ring)
|
||||
{
|
||||
struct b43_dmadesc_generic *desc;
|
||||
struct b43_dmadesc_meta *meta;
|
||||
int i;
|
||||
|
||||
if (!ring->used_slots)
|
||||
return;
|
||||
for (i = 0; i < ring->nr_slots; i++) {
|
||||
desc = ring->ops->idx2desc(ring, i, &meta);
|
||||
/* get meta - ignore returned value */
|
||||
ring->ops->idx2desc(ring, i, &meta);
|
||||
|
||||
if (!meta->skb || b43_dma_ptr_is_poisoned(meta->skb)) {
|
||||
B43_WARN_ON(!ring->tx);
|
||||
@ -869,7 +869,7 @@ struct b43_dmaring *b43_setup_dmaring(struct b43_wldev *dev,
|
||||
goto err_kfree_meta;
|
||||
|
||||
/* test for ability to dma to txhdr_cache */
|
||||
dma_test = dma_map_single(dev->sdev->dma_dev,
|
||||
dma_test = dma_map_single(dev->dev->dma_dev,
|
||||
ring->txhdr_cache,
|
||||
b43_txhdr_size(dev),
|
||||
DMA_TO_DEVICE);
|
||||
@ -884,7 +884,7 @@ struct b43_dmaring *b43_setup_dmaring(struct b43_wldev *dev,
|
||||
if (!ring->txhdr_cache)
|
||||
goto err_kfree_meta;
|
||||
|
||||
dma_test = dma_map_single(dev->sdev->dma_dev,
|
||||
dma_test = dma_map_single(dev->dev->dma_dev,
|
||||
ring->txhdr_cache,
|
||||
b43_txhdr_size(dev),
|
||||
DMA_TO_DEVICE);
|
||||
@ -898,7 +898,7 @@ struct b43_dmaring *b43_setup_dmaring(struct b43_wldev *dev,
|
||||
}
|
||||
}
|
||||
|
||||
dma_unmap_single(dev->sdev->dma_dev,
|
||||
dma_unmap_single(dev->dev->dma_dev,
|
||||
dma_test, b43_txhdr_size(dev),
|
||||
DMA_TO_DEVICE);
|
||||
}
|
||||
@ -1013,9 +1013,9 @@ static int b43_dma_set_mask(struct b43_wldev *dev, u64 mask)
|
||||
/* Try to set the DMA mask. If it fails, try falling back to a
|
||||
* lower mask, as we can always also support a lower one. */
|
||||
while (1) {
|
||||
err = dma_set_mask(dev->sdev->dma_dev, mask);
|
||||
err = dma_set_mask(dev->dev->dma_dev, mask);
|
||||
if (!err) {
|
||||
err = dma_set_coherent_mask(dev->sdev->dma_dev, mask);
|
||||
err = dma_set_coherent_mask(dev->dev->dma_dev, mask);
|
||||
if (!err)
|
||||
break;
|
||||
}
|
||||
@ -1085,7 +1085,7 @@ int b43_dma_init(struct b43_wldev *dev)
|
||||
goto err_destroy_mcast;
|
||||
|
||||
/* No support for the TX status DMA ring. */
|
||||
B43_WARN_ON(dev->sdev->id.revision < 5);
|
||||
B43_WARN_ON(dev->dev->core_rev < 5);
|
||||
|
||||
b43dbg(dev->wl, "%u-bit DMA initialized\n",
|
||||
(unsigned int)type);
|
||||
@ -1388,7 +1388,6 @@ void b43_dma_handle_txstatus(struct b43_wldev *dev,
|
||||
{
|
||||
const struct b43_dma_ops *ops;
|
||||
struct b43_dmaring *ring;
|
||||
struct b43_dmadesc_generic *desc;
|
||||
struct b43_dmadesc_meta *meta;
|
||||
int slot, firstused;
|
||||
bool frame_succeed;
|
||||
@ -1416,7 +1415,8 @@ void b43_dma_handle_txstatus(struct b43_wldev *dev,
|
||||
ops = ring->ops;
|
||||
while (1) {
|
||||
B43_WARN_ON(slot < 0 || slot >= ring->nr_slots);
|
||||
desc = ops->idx2desc(ring, slot, &meta);
|
||||
/* get meta - ignore returned value */
|
||||
ops->idx2desc(ring, slot, &meta);
|
||||
|
||||
if (b43_dma_ptr_is_poisoned(meta->skb)) {
|
||||
b43dbg(dev->wl, "Poisoned TX slot %d (first=%d) "
|
||||
|
@ -138,7 +138,7 @@ static int b43_register_led(struct b43_wldev *dev, struct b43_led *led,
|
||||
led->led_dev.default_trigger = default_trigger;
|
||||
led->led_dev.brightness_set = b43_led_brightness_set;
|
||||
|
||||
err = led_classdev_register(dev->sdev->dev, &led->led_dev);
|
||||
err = led_classdev_register(dev->dev->dev, &led->led_dev);
|
||||
if (err) {
|
||||
b43warn(dev->wl, "LEDs: Failed to register %s\n", name);
|
||||
led->wl = NULL;
|
||||
@ -215,13 +215,12 @@ static void b43_led_get_sprominfo(struct b43_wldev *dev,
|
||||
enum b43_led_behaviour *behaviour,
|
||||
bool *activelow)
|
||||
{
|
||||
struct ssb_bus *bus = dev->sdev->bus;
|
||||
u8 sprom[4];
|
||||
|
||||
sprom[0] = bus->sprom.gpio0;
|
||||
sprom[1] = bus->sprom.gpio1;
|
||||
sprom[2] = bus->sprom.gpio2;
|
||||
sprom[3] = bus->sprom.gpio3;
|
||||
sprom[0] = dev->dev->bus_sprom->gpio0;
|
||||
sprom[1] = dev->dev->bus_sprom->gpio1;
|
||||
sprom[2] = dev->dev->bus_sprom->gpio2;
|
||||
sprom[3] = dev->dev->bus_sprom->gpio3;
|
||||
|
||||
if (sprom[led_index] == 0xFF) {
|
||||
/* There is no LED information in the SPROM
|
||||
@ -231,12 +230,12 @@ static void b43_led_get_sprominfo(struct b43_wldev *dev,
|
||||
case 0:
|
||||
*behaviour = B43_LED_ACTIVITY;
|
||||
*activelow = 1;
|
||||
if (bus->boardinfo.vendor == PCI_VENDOR_ID_COMPAQ)
|
||||
if (dev->dev->board_vendor == PCI_VENDOR_ID_COMPAQ)
|
||||
*behaviour = B43_LED_RADIO_ALL;
|
||||
break;
|
||||
case 1:
|
||||
*behaviour = B43_LED_RADIO_B;
|
||||
if (bus->boardinfo.vendor == PCI_VENDOR_ID_ASUSTEK)
|
||||
if (dev->dev->board_vendor == PCI_VENDOR_ID_ASUSTEK)
|
||||
*behaviour = B43_LED_ASSOC;
|
||||
break;
|
||||
case 2:
|
||||
|
@ -98,7 +98,7 @@ static u16 lo_measure_feedthrough(struct b43_wldev *dev,
|
||||
rfover |= pga;
|
||||
rfover |= lna;
|
||||
rfover |= trsw_rx;
|
||||
if ((dev->sdev->bus->sprom.boardflags_lo & B43_BFL_EXTLNA)
|
||||
if ((dev->dev->bus_sprom->boardflags_lo & B43_BFL_EXTLNA)
|
||||
&& phy->rev > 6)
|
||||
rfover |= B43_PHY_RFOVERVAL_EXTLNA;
|
||||
|
||||
@ -301,14 +301,12 @@ static void lo_measure_gain_values(struct b43_wldev *dev,
|
||||
max_rx_gain = 0;
|
||||
|
||||
if (has_loopback_gain(phy)) {
|
||||
int trsw_rx = 0;
|
||||
int trsw_rx_gain;
|
||||
|
||||
if (use_trsw_rx) {
|
||||
trsw_rx_gain = gphy->trsw_rx_gain / 2;
|
||||
if (max_rx_gain >= trsw_rx_gain) {
|
||||
trsw_rx_gain = max_rx_gain - trsw_rx_gain;
|
||||
trsw_rx = 0x20;
|
||||
}
|
||||
} else
|
||||
trsw_rx_gain = max_rx_gain;
|
||||
@ -387,7 +385,7 @@ struct lo_g_saved_values {
|
||||
static void lo_measure_setup(struct b43_wldev *dev,
|
||||
struct lo_g_saved_values *sav)
|
||||
{
|
||||
struct ssb_sprom *sprom = &dev->sdev->bus->sprom;
|
||||
struct ssb_sprom *sprom = dev->dev->bus_sprom;
|
||||
struct b43_phy *phy = &dev->phy;
|
||||
struct b43_phy_g *gphy = phy->g;
|
||||
struct b43_txpower_lo_control *lo = gphy->lo_control;
|
||||
|
@ -113,6 +113,16 @@ static int b43_modparam_pio = B43_PIO_DEFAULT;
|
||||
module_param_named(pio, b43_modparam_pio, int, 0644);
|
||||
MODULE_PARM_DESC(pio, "Use PIO accesses by default: 0=DMA, 1=PIO");
|
||||
|
||||
#ifdef CONFIG_B43_BCMA
|
||||
static const struct bcma_device_id b43_bcma_tbl[] = {
|
||||
BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 0x17, BCMA_ANY_CLASS),
|
||||
BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 0x18, BCMA_ANY_CLASS),
|
||||
BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 0x1D, BCMA_ANY_CLASS),
|
||||
BCMA_CORETABLE_END
|
||||
};
|
||||
MODULE_DEVICE_TABLE(bcma, b43_bcma_tbl);
|
||||
#endif
|
||||
|
||||
static const struct ssb_device_id b43_ssb_tbl[] = {
|
||||
SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 5),
|
||||
SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 6),
|
||||
@ -548,7 +558,7 @@ void b43_tsf_read(struct b43_wldev *dev, u64 *tsf)
|
||||
{
|
||||
u32 low, high;
|
||||
|
||||
B43_WARN_ON(dev->sdev->id.revision < 3);
|
||||
B43_WARN_ON(dev->dev->core_rev < 3);
|
||||
|
||||
/* The hardware guarantees us an atomic read, if we
|
||||
* read the low register first. */
|
||||
@ -586,7 +596,7 @@ static void b43_tsf_write_locked(struct b43_wldev *dev, u64 tsf)
|
||||
{
|
||||
u32 low, high;
|
||||
|
||||
B43_WARN_ON(dev->sdev->id.revision < 3);
|
||||
B43_WARN_ON(dev->dev->core_rev < 3);
|
||||
|
||||
low = tsf;
|
||||
high = (tsf >> 32);
|
||||
@ -714,7 +724,7 @@ void b43_dummy_transmission(struct b43_wldev *dev, bool ofdm, bool pa_on)
|
||||
b43_ram_write(dev, i * 4, buffer[i]);
|
||||
|
||||
b43_write16(dev, 0x0568, 0x0000);
|
||||
if (dev->sdev->id.revision < 11)
|
||||
if (dev->dev->core_rev < 11)
|
||||
b43_write16(dev, 0x07C0, 0x0000);
|
||||
else
|
||||
b43_write16(dev, 0x07C0, 0x0100);
|
||||
@ -1132,7 +1142,7 @@ void b43_power_saving_ctl_bits(struct b43_wldev *dev, unsigned int ps_flags)
|
||||
b43_write32(dev, B43_MMIO_MACCTL, macctl);
|
||||
/* Commit write */
|
||||
b43_read32(dev, B43_MMIO_MACCTL);
|
||||
if (awake && dev->sdev->id.revision >= 5) {
|
||||
if (awake && dev->dev->core_rev >= 5) {
|
||||
/* Wait for the microcode to wake up. */
|
||||
for (i = 0; i < 100; i++) {
|
||||
ucstat = b43_shm_read16(dev, B43_SHM_SHARED,
|
||||
@ -1144,35 +1154,39 @@ void b43_power_saving_ctl_bits(struct b43_wldev *dev, unsigned int ps_flags)
|
||||
}
|
||||
}
|
||||
|
||||
static void b43_ssb_wireless_core_reset(struct b43_wldev *dev, u32 flags)
|
||||
static void b43_ssb_wireless_core_reset(struct b43_wldev *dev, bool gmode)
|
||||
{
|
||||
struct ssb_device *sdev = dev->dev->sdev;
|
||||
u32 tmslow;
|
||||
u32 flags = 0;
|
||||
|
||||
if (gmode)
|
||||
flags |= B43_TMSLOW_GMODE;
|
||||
flags |= B43_TMSLOW_PHYCLKEN;
|
||||
flags |= B43_TMSLOW_PHYRESET;
|
||||
if (dev->phy.type == B43_PHYTYPE_N)
|
||||
flags |= B43_TMSLOW_PHY_BANDWIDTH_20MHZ; /* Make 20 MHz def */
|
||||
ssb_device_enable(dev->sdev, flags);
|
||||
b43_device_enable(dev, flags);
|
||||
msleep(2); /* Wait for the PLL to turn on. */
|
||||
|
||||
/* Now take the PHY out of Reset again */
|
||||
tmslow = ssb_read32(dev->sdev, SSB_TMSLOW);
|
||||
tmslow = ssb_read32(sdev, SSB_TMSLOW);
|
||||
tmslow |= SSB_TMSLOW_FGC;
|
||||
tmslow &= ~B43_TMSLOW_PHYRESET;
|
||||
ssb_write32(dev->sdev, SSB_TMSLOW, tmslow);
|
||||
ssb_read32(dev->sdev, SSB_TMSLOW); /* flush */
|
||||
ssb_write32(sdev, SSB_TMSLOW, tmslow);
|
||||
ssb_read32(sdev, SSB_TMSLOW); /* flush */
|
||||
msleep(1);
|
||||
tmslow &= ~SSB_TMSLOW_FGC;
|
||||
ssb_write32(dev->sdev, SSB_TMSLOW, tmslow);
|
||||
ssb_read32(dev->sdev, SSB_TMSLOW); /* flush */
|
||||
ssb_write32(sdev, SSB_TMSLOW, tmslow);
|
||||
ssb_read32(sdev, SSB_TMSLOW); /* flush */
|
||||
msleep(1);
|
||||
}
|
||||
|
||||
void b43_wireless_core_reset(struct b43_wldev *dev, u32 flags)
|
||||
void b43_wireless_core_reset(struct b43_wldev *dev, bool gmode)
|
||||
{
|
||||
u32 macctl;
|
||||
|
||||
b43_ssb_wireless_core_reset(dev, flags);
|
||||
b43_ssb_wireless_core_reset(dev, gmode);
|
||||
|
||||
/* Turn Analog ON, but only if we already know the PHY-type.
|
||||
* This protects against very early setup where we don't know the
|
||||
@ -1183,7 +1197,7 @@ void b43_wireless_core_reset(struct b43_wldev *dev, u32 flags)
|
||||
|
||||
macctl = b43_read32(dev, B43_MMIO_MACCTL);
|
||||
macctl &= ~B43_MACCTL_GMODE;
|
||||
if (flags & B43_TMSLOW_GMODE)
|
||||
if (gmode)
|
||||
macctl |= B43_MACCTL_GMODE;
|
||||
macctl |= B43_MACCTL_IHR_ENABLED;
|
||||
b43_write32(dev, B43_MMIO_MACCTL, macctl);
|
||||
@ -1221,7 +1235,7 @@ static void drain_txstatus_queue(struct b43_wldev *dev)
|
||||
{
|
||||
u32 dummy;
|
||||
|
||||
if (dev->sdev->id.revision < 5)
|
||||
if (dev->dev->core_rev < 5)
|
||||
return;
|
||||
/* Read all entries from the microcode TXstatus FIFO
|
||||
* and throw them away.
|
||||
@ -1427,9 +1441,9 @@ u8 b43_ieee80211_antenna_sanitize(struct b43_wldev *dev,
|
||||
|
||||
/* Get the mask of available antennas. */
|
||||
if (dev->phy.gmode)
|
||||
antenna_mask = dev->sdev->bus->sprom.ant_available_bg;
|
||||
antenna_mask = dev->dev->bus_sprom->ant_available_bg;
|
||||
else
|
||||
antenna_mask = dev->sdev->bus->sprom.ant_available_a;
|
||||
antenna_mask = dev->dev->bus_sprom->ant_available_a;
|
||||
|
||||
if (!(antenna_mask & (1 << (antenna_nr - 1)))) {
|
||||
/* This antenna is not available. Fall back to default. */
|
||||
@ -1644,7 +1658,7 @@ static void b43_beacon_update_trigger_work(struct work_struct *work)
|
||||
mutex_lock(&wl->mutex);
|
||||
dev = wl->current_dev;
|
||||
if (likely(dev && (b43_status(dev) >= B43_STAT_INITIALIZED))) {
|
||||
if (dev->sdev->bus->bustype == SSB_BUSTYPE_SDIO) {
|
||||
if (b43_bus_host_is_sdio(dev->dev)) {
|
||||
/* wl->mutex is enough. */
|
||||
b43_do_beacon_update_trigger_work(dev);
|
||||
mmiowb();
|
||||
@ -1689,7 +1703,7 @@ static void b43_update_templates(struct b43_wl *wl)
|
||||
static void b43_set_beacon_int(struct b43_wldev *dev, u16 beacon_int)
|
||||
{
|
||||
b43_time_lock(dev);
|
||||
if (dev->sdev->id.revision >= 3) {
|
||||
if (dev->dev->core_rev >= 3) {
|
||||
b43_write32(dev, B43_MMIO_TSF_CFP_REP, (beacon_int << 16));
|
||||
b43_write32(dev, B43_MMIO_TSF_CFP_START, (beacon_int << 10));
|
||||
} else {
|
||||
@ -2063,7 +2077,7 @@ int b43_do_request_fw(struct b43_request_fw_context *ctx,
|
||||
B43_WARN_ON(1);
|
||||
return -ENOSYS;
|
||||
}
|
||||
err = request_firmware(&blob, ctx->fwname, ctx->dev->sdev->dev);
|
||||
err = request_firmware(&blob, ctx->fwname, ctx->dev->dev->dev);
|
||||
if (err == -ENOENT) {
|
||||
snprintf(ctx->errors[ctx->req_type],
|
||||
sizeof(ctx->errors[ctx->req_type]),
|
||||
@ -2113,7 +2127,7 @@ static int b43_try_request_fw(struct b43_request_fw_context *ctx)
|
||||
{
|
||||
struct b43_wldev *dev = ctx->dev;
|
||||
struct b43_firmware *fw = &ctx->dev->fw;
|
||||
const u8 rev = ctx->dev->sdev->id.revision;
|
||||
const u8 rev = ctx->dev->dev->core_rev;
|
||||
const char *filename;
|
||||
u32 tmshigh;
|
||||
int err;
|
||||
@ -2157,7 +2171,7 @@ static int b43_try_request_fw(struct b43_request_fw_context *ctx)
|
||||
switch (dev->phy.type) {
|
||||
case B43_PHYTYPE_A:
|
||||
if ((rev >= 5) && (rev <= 10)) {
|
||||
tmshigh = ssb_read32(dev->sdev, SSB_TMSHIGH);
|
||||
tmshigh = ssb_read32(dev->dev->sdev, SSB_TMSHIGH);
|
||||
if (tmshigh & B43_TMSHIGH_HAVE_2GHZ_PHY)
|
||||
filename = "a0g1initvals5";
|
||||
else
|
||||
@ -2202,7 +2216,7 @@ static int b43_try_request_fw(struct b43_request_fw_context *ctx)
|
||||
switch (dev->phy.type) {
|
||||
case B43_PHYTYPE_A:
|
||||
if ((rev >= 5) && (rev <= 10)) {
|
||||
tmshigh = ssb_read32(dev->sdev, SSB_TMSHIGH);
|
||||
tmshigh = ssb_read32(dev->dev->sdev, SSB_TMSHIGH);
|
||||
if (tmshigh & B43_TMSHIGH_HAVE_2GHZ_PHY)
|
||||
filename = "a0g1bsinitvals5";
|
||||
else
|
||||
@ -2448,7 +2462,7 @@ static int b43_upload_microcode(struct b43_wldev *dev)
|
||||
|
||||
snprintf(wiphy->fw_version, sizeof(wiphy->fw_version), "%u.%u",
|
||||
dev->fw.rev, dev->fw.patch);
|
||||
wiphy->hw_version = dev->sdev->id.coreid;
|
||||
wiphy->hw_version = dev->dev->core_id;
|
||||
|
||||
if (b43_is_old_txhdr_format(dev)) {
|
||||
/* We're over the deadline, but we keep support for old fw
|
||||
@ -2566,7 +2580,7 @@ out:
|
||||
*/
|
||||
static struct ssb_device *b43_ssb_gpio_dev(struct b43_wldev *dev)
|
||||
{
|
||||
struct ssb_bus *bus = dev->sdev->bus;
|
||||
struct ssb_bus *bus = dev->dev->sdev->bus;
|
||||
|
||||
#ifdef CONFIG_SSB_DRIVER_PCICORE
|
||||
return (bus->chipco.dev ? bus->chipco.dev : bus->pcicore.dev);
|
||||
@ -2588,7 +2602,7 @@ static int b43_gpio_init(struct b43_wldev *dev)
|
||||
|
||||
mask = 0x0000001F;
|
||||
set = 0x0000000F;
|
||||
if (dev->sdev->bus->chip_id == 0x4301) {
|
||||
if (dev->dev->chip_id == 0x4301) {
|
||||
mask |= 0x0060;
|
||||
set |= 0x0060;
|
||||
}
|
||||
@ -2599,14 +2613,14 @@ static int b43_gpio_init(struct b43_wldev *dev)
|
||||
mask |= 0x0180;
|
||||
set |= 0x0180;
|
||||
}
|
||||
if (dev->sdev->bus->sprom.boardflags_lo & B43_BFL_PACTRL) {
|
||||
if (dev->dev->bus_sprom->boardflags_lo & B43_BFL_PACTRL) {
|
||||
b43_write16(dev, B43_MMIO_GPIO_MASK,
|
||||
b43_read16(dev, B43_MMIO_GPIO_MASK)
|
||||
| 0x0200);
|
||||
mask |= 0x0200;
|
||||
set |= 0x0200;
|
||||
}
|
||||
if (dev->sdev->id.revision >= 2)
|
||||
if (dev->dev->core_rev >= 2)
|
||||
mask |= 0x0010; /* FIXME: This is redundant. */
|
||||
|
||||
gpiodev = b43_ssb_gpio_dev(dev);
|
||||
@ -2741,15 +2755,15 @@ static void b43_adjust_opmode(struct b43_wldev *dev)
|
||||
/* Workaround: On old hardware the HW-MAC-address-filter
|
||||
* doesn't work properly, so always run promisc in filter
|
||||
* it in software. */
|
||||
if (dev->sdev->id.revision <= 4)
|
||||
if (dev->dev->core_rev <= 4)
|
||||
ctl |= B43_MACCTL_PROMISC;
|
||||
|
||||
b43_write32(dev, B43_MMIO_MACCTL, ctl);
|
||||
|
||||
cfp_pretbtt = 2;
|
||||
if ((ctl & B43_MACCTL_INFRA) && !(ctl & B43_MACCTL_AP)) {
|
||||
if (dev->sdev->bus->chip_id == 0x4306 &&
|
||||
dev->sdev->bus->chip_rev == 3)
|
||||
if (dev->dev->chip_id == 0x4306 &&
|
||||
dev->dev->chip_rev == 3)
|
||||
cfp_pretbtt = 100;
|
||||
else
|
||||
cfp_pretbtt = 50;
|
||||
@ -2907,7 +2921,7 @@ static int b43_chip_init(struct b43_wldev *dev)
|
||||
b43_write16(dev, 0x005E, value16);
|
||||
}
|
||||
b43_write32(dev, 0x0100, 0x01000000);
|
||||
if (dev->sdev->id.revision < 5)
|
||||
if (dev->dev->core_rev < 5)
|
||||
b43_write32(dev, 0x010C, 0x01000000);
|
||||
|
||||
b43_write32(dev, B43_MMIO_MACCTL, b43_read32(dev, B43_MMIO_MACCTL)
|
||||
@ -2922,7 +2936,7 @@ static int b43_chip_init(struct b43_wldev *dev)
|
||||
/* Initially set the wireless operation mode. */
|
||||
b43_adjust_opmode(dev);
|
||||
|
||||
if (dev->sdev->id.revision < 3) {
|
||||
if (dev->dev->core_rev < 3) {
|
||||
b43_write16(dev, 0x060E, 0x0000);
|
||||
b43_write16(dev, 0x0610, 0x8000);
|
||||
b43_write16(dev, 0x0604, 0x0000);
|
||||
@ -3105,7 +3119,7 @@ static int b43_validate_chipaccess(struct b43_wldev *dev)
|
||||
b43_shm_write32(dev, B43_SHM_SHARED, 0, backup0);
|
||||
b43_shm_write32(dev, B43_SHM_SHARED, 4, backup4);
|
||||
|
||||
if ((dev->sdev->id.revision >= 3) && (dev->sdev->id.revision <= 10)) {
|
||||
if ((dev->dev->core_rev >= 3) && (dev->dev->core_rev <= 10)) {
|
||||
/* The 32bit register shadows the two 16bit registers
|
||||
* with update sideeffects. Validate this. */
|
||||
b43_write16(dev, B43_MMIO_TSF_CFP_START, 0xAAAA);
|
||||
@ -3954,7 +3968,7 @@ redo:
|
||||
|
||||
/* Disable interrupts on the device. */
|
||||
b43_set_status(dev, B43_STAT_INITIALIZED);
|
||||
if (dev->sdev->bus->bustype == SSB_BUSTYPE_SDIO) {
|
||||
if (b43_bus_host_is_sdio(dev->dev)) {
|
||||
/* wl->mutex is locked. That is enough. */
|
||||
b43_write32(dev, B43_MMIO_GEN_IRQ_MASK, 0);
|
||||
b43_read32(dev, B43_MMIO_GEN_IRQ_MASK); /* Flush */
|
||||
@ -3967,11 +3981,11 @@ redo:
|
||||
/* Synchronize and free the interrupt handlers. Unlock to avoid deadlocks. */
|
||||
orig_dev = dev;
|
||||
mutex_unlock(&wl->mutex);
|
||||
if (dev->sdev->bus->bustype == SSB_BUSTYPE_SDIO) {
|
||||
if (b43_bus_host_is_sdio(dev->dev)) {
|
||||
b43_sdio_free_irq(dev);
|
||||
} else {
|
||||
synchronize_irq(dev->sdev->irq);
|
||||
free_irq(dev->sdev->irq, dev);
|
||||
synchronize_irq(dev->dev->irq);
|
||||
free_irq(dev->dev->irq, dev);
|
||||
}
|
||||
mutex_lock(&wl->mutex);
|
||||
dev = wl->current_dev;
|
||||
@ -4004,19 +4018,19 @@ static int b43_wireless_core_start(struct b43_wldev *dev)
|
||||
B43_WARN_ON(b43_status(dev) != B43_STAT_INITIALIZED);
|
||||
|
||||
drain_txstatus_queue(dev);
|
||||
if (dev->sdev->bus->bustype == SSB_BUSTYPE_SDIO) {
|
||||
if (b43_bus_host_is_sdio(dev->dev)) {
|
||||
err = b43_sdio_request_irq(dev, b43_sdio_interrupt_handler);
|
||||
if (err) {
|
||||
b43err(dev->wl, "Cannot request SDIO IRQ\n");
|
||||
goto out;
|
||||
}
|
||||
} else {
|
||||
err = request_threaded_irq(dev->sdev->irq, b43_interrupt_handler,
|
||||
err = request_threaded_irq(dev->dev->irq, b43_interrupt_handler,
|
||||
b43_interrupt_thread_handler,
|
||||
IRQF_SHARED, KBUILD_MODNAME, dev);
|
||||
if (err) {
|
||||
b43err(dev->wl, "Cannot request IRQ-%d\n",
|
||||
dev->sdev->irq);
|
||||
dev->dev->irq);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
@ -4096,10 +4110,10 @@ static int b43_phy_versioning(struct b43_wldev *dev)
|
||||
analog_type, phy_type, phy_rev);
|
||||
|
||||
/* Get RADIO versioning */
|
||||
if (dev->sdev->bus->chip_id == 0x4317) {
|
||||
if (dev->sdev->bus->chip_rev == 0)
|
||||
if (dev->dev->chip_id == 0x4317) {
|
||||
if (dev->dev->chip_rev == 0)
|
||||
tmp = 0x3205017F;
|
||||
else if (dev->sdev->bus->chip_rev == 1)
|
||||
else if (dev->dev->chip_rev == 1)
|
||||
tmp = 0x4205017F;
|
||||
else
|
||||
tmp = 0x5205017F;
|
||||
@ -4204,7 +4218,7 @@ static void setup_struct_wldev_for_init(struct b43_wldev *dev)
|
||||
|
||||
static void b43_bluetooth_coext_enable(struct b43_wldev *dev)
|
||||
{
|
||||
struct ssb_sprom *sprom = &dev->sdev->bus->sprom;
|
||||
struct ssb_sprom *sprom = dev->dev->bus_sprom;
|
||||
u64 hf;
|
||||
|
||||
if (!modparam_btcoex)
|
||||
@ -4231,16 +4245,21 @@ static void b43_bluetooth_coext_disable(struct b43_wldev *dev)
|
||||
|
||||
static void b43_imcfglo_timeouts_workaround(struct b43_wldev *dev)
|
||||
{
|
||||
struct ssb_bus *bus = dev->sdev->bus;
|
||||
struct ssb_bus *bus;
|
||||
u32 tmp;
|
||||
|
||||
if (dev->dev->bus_type != B43_BUS_SSB)
|
||||
return;
|
||||
|
||||
bus = dev->dev->sdev->bus;
|
||||
|
||||
if ((bus->chip_id == 0x4311 && bus->chip_rev == 2) ||
|
||||
(bus->chip_id == 0x4312)) {
|
||||
tmp = ssb_read32(dev->sdev, SSB_IMCFGLO);
|
||||
tmp = ssb_read32(dev->dev->sdev, SSB_IMCFGLO);
|
||||
tmp &= ~SSB_IMCFGLO_REQTO;
|
||||
tmp &= ~SSB_IMCFGLO_SERTO;
|
||||
tmp |= 0x3;
|
||||
ssb_write32(dev->sdev, SSB_IMCFGLO, tmp);
|
||||
ssb_write32(dev->dev->sdev, SSB_IMCFGLO, tmp);
|
||||
ssb_commit_settings(bus);
|
||||
}
|
||||
}
|
||||
@ -4310,29 +4329,26 @@ static void b43_wireless_core_exit(struct b43_wldev *dev)
|
||||
dev->wl->current_beacon = NULL;
|
||||
}
|
||||
|
||||
ssb_device_disable(dev->sdev, 0);
|
||||
ssb_bus_may_powerdown(dev->sdev->bus);
|
||||
b43_device_disable(dev, 0);
|
||||
b43_bus_may_powerdown(dev);
|
||||
}
|
||||
|
||||
/* Initialize a wireless core */
|
||||
static int b43_wireless_core_init(struct b43_wldev *dev)
|
||||
{
|
||||
struct ssb_bus *bus = dev->sdev->bus;
|
||||
struct ssb_sprom *sprom = &bus->sprom;
|
||||
struct ssb_sprom *sprom = dev->dev->bus_sprom;
|
||||
struct b43_phy *phy = &dev->phy;
|
||||
int err;
|
||||
u64 hf;
|
||||
u32 tmp;
|
||||
|
||||
B43_WARN_ON(b43_status(dev) != B43_STAT_UNINIT);
|
||||
|
||||
err = ssb_bus_powerup(bus, 0);
|
||||
err = b43_bus_powerup(dev, 0);
|
||||
if (err)
|
||||
goto out;
|
||||
if (!ssb_device_is_enabled(dev->sdev)) {
|
||||
tmp = phy->gmode ? B43_TMSLOW_GMODE : 0;
|
||||
b43_wireless_core_reset(dev, tmp);
|
||||
}
|
||||
if (!b43_device_is_enabled(dev))
|
||||
b43_wireless_core_reset(dev, phy->gmode);
|
||||
|
||||
/* Reset all data structures. */
|
||||
setup_struct_wldev_for_init(dev);
|
||||
@ -4352,7 +4368,7 @@ static int b43_wireless_core_init(struct b43_wldev *dev)
|
||||
if (err)
|
||||
goto err_busdown;
|
||||
b43_shm_write16(dev, B43_SHM_SHARED,
|
||||
B43_SHM_SH_WLCOREREV, dev->sdev->id.revision);
|
||||
B43_SHM_SH_WLCOREREV, dev->dev->core_rev);
|
||||
hf = b43_hf_read(dev);
|
||||
if (phy->type == B43_PHYTYPE_G) {
|
||||
hf |= B43_HF_SYMW;
|
||||
@ -4399,8 +4415,8 @@ static int b43_wireless_core_init(struct b43_wldev *dev)
|
||||
/* Maximum Contention Window */
|
||||
b43_shm_write16(dev, B43_SHM_SCRATCH, B43_SHM_SC_MAXCONT, 0x3FF);
|
||||
|
||||
if ((dev->sdev->bus->bustype == SSB_BUSTYPE_PCMCIA) ||
|
||||
(dev->sdev->bus->bustype == SSB_BUSTYPE_SDIO) ||
|
||||
if (b43_bus_host_is_pcmcia(dev->dev) ||
|
||||
b43_bus_host_is_sdio(dev->dev) ||
|
||||
dev->use_pio) {
|
||||
dev->__using_pio_transfers = 1;
|
||||
err = b43_pio_init(dev);
|
||||
@ -4414,7 +4430,7 @@ static int b43_wireless_core_init(struct b43_wldev *dev)
|
||||
b43_set_synth_pu_delay(dev, 1);
|
||||
b43_bluetooth_coext_enable(dev);
|
||||
|
||||
ssb_bus_powerup(bus, !(sprom->boardflags_lo & B43_BFL_XTAL_NOSLOW));
|
||||
b43_bus_powerup(dev, !(sprom->boardflags_lo & B43_BFL_XTAL_NOSLOW));
|
||||
b43_upload_card_macaddress(dev);
|
||||
b43_security_init(dev);
|
||||
|
||||
@ -4431,7 +4447,7 @@ out:
|
||||
err_chip_exit:
|
||||
b43_chip_exit(dev);
|
||||
err_busdown:
|
||||
ssb_bus_may_powerdown(bus);
|
||||
b43_bus_may_powerdown(dev);
|
||||
B43_WARN_ON(b43_status(dev) != B43_STAT_UNINIT);
|
||||
return err;
|
||||
}
|
||||
@ -4741,7 +4757,6 @@ static int b43_wireless_core_attach(struct b43_wldev *dev)
|
||||
struct pci_dev *pdev = (bus->bustype == SSB_BUSTYPE_PCI) ? bus->host_pci : NULL;
|
||||
int err;
|
||||
bool have_2ghz_phy = 0, have_5ghz_phy = 0;
|
||||
u32 tmp;
|
||||
|
||||
/* Do NOT do any device initialization here.
|
||||
* Do it in wireless_core_init() instead.
|
||||
@ -4750,13 +4765,13 @@ static int b43_wireless_core_attach(struct b43_wldev *dev)
|
||||
* that in core_init(), too.
|
||||
*/
|
||||
|
||||
err = ssb_bus_powerup(bus, 0);
|
||||
err = b43_bus_powerup(dev, 0);
|
||||
if (err) {
|
||||
b43err(wl, "Bus powerup failed\n");
|
||||
goto out;
|
||||
}
|
||||
/* Get the PHY type. */
|
||||
if (dev->sdev->id.revision >= 5) {
|
||||
if (dev->dev->core_rev >= 5) {
|
||||
u32 tmshigh;
|
||||
|
||||
tmshigh = ssb_read32(dev->sdev, SSB_TMSHIGH);
|
||||
@ -4767,8 +4782,7 @@ static int b43_wireless_core_attach(struct b43_wldev *dev)
|
||||
|
||||
dev->phy.gmode = have_2ghz_phy;
|
||||
dev->phy.radio_on = 1;
|
||||
tmp = dev->phy.gmode ? B43_TMSLOW_GMODE : 0;
|
||||
b43_wireless_core_reset(dev, tmp);
|
||||
b43_wireless_core_reset(dev, dev->phy.gmode);
|
||||
|
||||
err = b43_phy_versioning(dev);
|
||||
if (err)
|
||||
@ -4816,8 +4830,7 @@ static int b43_wireless_core_attach(struct b43_wldev *dev)
|
||||
goto err_powerdown;
|
||||
|
||||
dev->phy.gmode = have_2ghz_phy;
|
||||
tmp = dev->phy.gmode ? B43_TMSLOW_GMODE : 0;
|
||||
b43_wireless_core_reset(dev, tmp);
|
||||
b43_wireless_core_reset(dev, dev->phy.gmode);
|
||||
|
||||
err = b43_validate_chipaccess(dev);
|
||||
if (err)
|
||||
@ -4832,8 +4845,8 @@ static int b43_wireless_core_attach(struct b43_wldev *dev)
|
||||
INIT_WORK(&dev->restart_work, b43_chip_reset);
|
||||
|
||||
dev->phy.ops->switch_analog(dev, 0);
|
||||
ssb_device_disable(dev->sdev, 0);
|
||||
ssb_bus_may_powerdown(bus);
|
||||
b43_device_disable(dev, 0);
|
||||
b43_bus_may_powerdown(dev);
|
||||
|
||||
out:
|
||||
return err;
|
||||
@ -4841,11 +4854,11 @@ out:
|
||||
err_phy_free:
|
||||
b43_phy_free(dev);
|
||||
err_powerdown:
|
||||
ssb_bus_may_powerdown(bus);
|
||||
b43_bus_may_powerdown(dev);
|
||||
return err;
|
||||
}
|
||||
|
||||
static void b43_one_core_detach(struct ssb_device *dev)
|
||||
static void b43_one_core_detach(struct b43_bus_dev *dev)
|
||||
{
|
||||
struct b43_wldev *wldev;
|
||||
struct b43_wl *wl;
|
||||
@ -4853,17 +4866,17 @@ static void b43_one_core_detach(struct ssb_device *dev)
|
||||
/* Do not cancel ieee80211-workqueue based work here.
|
||||
* See comment in b43_remove(). */
|
||||
|
||||
wldev = ssb_get_drvdata(dev);
|
||||
wldev = ssb_get_drvdata(dev->sdev);
|
||||
wl = wldev->wl;
|
||||
b43_debugfs_remove_device(wldev);
|
||||
b43_wireless_core_detach(wldev);
|
||||
list_del(&wldev->list);
|
||||
wl->nr_devs--;
|
||||
ssb_set_drvdata(dev, NULL);
|
||||
ssb_set_drvdata(dev->sdev, NULL);
|
||||
kfree(wldev);
|
||||
}
|
||||
|
||||
static int b43_one_core_attach(struct ssb_device *dev, struct b43_wl *wl)
|
||||
static int b43_one_core_attach(struct b43_bus_dev *dev, struct b43_wl *wl)
|
||||
{
|
||||
struct b43_wldev *wldev;
|
||||
int err = -ENOMEM;
|
||||
@ -4873,7 +4886,8 @@ static int b43_one_core_attach(struct ssb_device *dev, struct b43_wl *wl)
|
||||
goto out;
|
||||
|
||||
wldev->use_pio = b43_modparam_pio;
|
||||
wldev->sdev = dev;
|
||||
wldev->dev = dev;
|
||||
wldev->sdev = dev->sdev; /* TODO: Remove when not needed */
|
||||
wldev->wl = wl;
|
||||
b43_set_status(wldev, B43_STAT_UNINIT);
|
||||
wldev->bad_frames_preempt = modparam_bad_frames_preempt;
|
||||
@ -4885,7 +4899,7 @@ static int b43_one_core_attach(struct ssb_device *dev, struct b43_wl *wl)
|
||||
|
||||
list_add(&wldev->list, &wl->devlist);
|
||||
wl->nr_devs++;
|
||||
ssb_set_drvdata(dev, wldev);
|
||||
ssb_set_drvdata(dev->sdev, wldev);
|
||||
b43_debugfs_add_device(wldev);
|
||||
|
||||
out:
|
||||
@ -4926,11 +4940,11 @@ static void b43_sprom_fixup(struct ssb_bus *bus)
|
||||
}
|
||||
}
|
||||
|
||||
static void b43_wireless_exit(struct ssb_device *dev, struct b43_wl *wl)
|
||||
static void b43_wireless_exit(struct b43_bus_dev *dev, struct b43_wl *wl)
|
||||
{
|
||||
struct ieee80211_hw *hw = wl->hw;
|
||||
|
||||
ssb_set_devtypedata(dev, NULL);
|
||||
ssb_set_devtypedata(dev->sdev, NULL);
|
||||
ieee80211_free_hw(hw);
|
||||
}
|
||||
|
||||
@ -4982,24 +4996,48 @@ static struct b43_wl *b43_wireless_init(struct ssb_device *dev)
|
||||
return wl;
|
||||
}
|
||||
|
||||
static int b43_ssb_probe(struct ssb_device *dev, const struct ssb_device_id *id)
|
||||
#ifdef CONFIG_B43_BCMA
|
||||
static int b43_bcma_probe(struct bcma_device *core)
|
||||
{
|
||||
b43err(NULL, "BCMA is not supported yet!");
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
static void b43_bcma_remove(struct bcma_device *core)
|
||||
{
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
static struct bcma_driver b43_bcma_driver = {
|
||||
.name = KBUILD_MODNAME,
|
||||
.id_table = b43_bcma_tbl,
|
||||
.probe = b43_bcma_probe,
|
||||
.remove = b43_bcma_remove,
|
||||
};
|
||||
#endif
|
||||
|
||||
static
|
||||
int b43_ssb_probe(struct ssb_device *sdev, const struct ssb_device_id *id)
|
||||
{
|
||||
struct b43_bus_dev *dev;
|
||||
struct b43_wl *wl;
|
||||
int err;
|
||||
int first = 0;
|
||||
|
||||
wl = ssb_get_devtypedata(dev);
|
||||
dev = b43_bus_dev_ssb_init(sdev);
|
||||
|
||||
wl = ssb_get_devtypedata(sdev);
|
||||
if (!wl) {
|
||||
/* Probing the first core. Must setup common struct b43_wl */
|
||||
first = 1;
|
||||
b43_sprom_fixup(dev->bus);
|
||||
wl = b43_wireless_init(dev);
|
||||
b43_sprom_fixup(sdev->bus);
|
||||
wl = b43_wireless_init(sdev);
|
||||
if (IS_ERR(wl)) {
|
||||
err = PTR_ERR(wl);
|
||||
goto out;
|
||||
}
|
||||
ssb_set_devtypedata(dev, wl);
|
||||
B43_WARN_ON(ssb_get_devtypedata(dev) != wl);
|
||||
ssb_set_devtypedata(sdev, wl);
|
||||
B43_WARN_ON(ssb_get_devtypedata(sdev) != wl);
|
||||
}
|
||||
err = b43_one_core_attach(dev, wl);
|
||||
if (err)
|
||||
@ -5023,10 +5061,10 @@ static int b43_ssb_probe(struct ssb_device *dev, const struct ssb_device_id *id)
|
||||
return err;
|
||||
}
|
||||
|
||||
static void b43_ssb_remove(struct ssb_device *dev)
|
||||
static void b43_ssb_remove(struct ssb_device *sdev)
|
||||
{
|
||||
struct b43_wl *wl = ssb_get_devtypedata(dev);
|
||||
struct b43_wldev *wldev = ssb_get_drvdata(dev);
|
||||
struct b43_wl *wl = ssb_get_devtypedata(sdev);
|
||||
struct b43_wldev *wldev = ssb_get_drvdata(sdev);
|
||||
|
||||
/* We must cancel any work here before unregistering from ieee80211,
|
||||
* as the ieee80211 unreg will destroy the workqueue. */
|
||||
@ -5042,14 +5080,14 @@ static void b43_ssb_remove(struct ssb_device *dev)
|
||||
ieee80211_unregister_hw(wl->hw);
|
||||
}
|
||||
|
||||
b43_one_core_detach(dev);
|
||||
b43_one_core_detach(wldev->dev);
|
||||
|
||||
if (list_empty(&wl->devlist)) {
|
||||
b43_leds_unregister(wl);
|
||||
/* Last core on the chip unregistered.
|
||||
* We can destroy common struct b43_wl.
|
||||
*/
|
||||
b43_wireless_exit(dev, wl);
|
||||
b43_wireless_exit(wldev->dev, wl);
|
||||
}
|
||||
}
|
||||
|
||||
@ -5108,14 +5146,23 @@ static int __init b43_init(void)
|
||||
err = b43_sdio_init();
|
||||
if (err)
|
||||
goto err_pcmcia_exit;
|
||||
err = ssb_driver_register(&b43_ssb_driver);
|
||||
#ifdef CONFIG_B43_BCMA
|
||||
err = bcma_driver_register(&b43_bcma_driver);
|
||||
if (err)
|
||||
goto err_sdio_exit;
|
||||
#endif
|
||||
err = ssb_driver_register(&b43_ssb_driver);
|
||||
if (err)
|
||||
goto err_bcma_driver_exit;
|
||||
b43_print_driverinfo();
|
||||
|
||||
return err;
|
||||
|
||||
err_bcma_driver_exit:
|
||||
#ifdef CONFIG_B43_BCMA
|
||||
bcma_driver_unregister(&b43_bcma_driver);
|
||||
err_sdio_exit:
|
||||
#endif
|
||||
b43_sdio_exit();
|
||||
err_pcmcia_exit:
|
||||
b43_pcmcia_exit();
|
||||
@ -5127,6 +5174,9 @@ err_dfs_exit:
|
||||
static void __exit b43_exit(void)
|
||||
{
|
||||
ssb_driver_unregister(&b43_ssb_driver);
|
||||
#ifdef CONFIG_B43_BCMA
|
||||
bcma_driver_unregister(&b43_bcma_driver);
|
||||
#endif
|
||||
b43_sdio_exit();
|
||||
b43_pcmcia_exit();
|
||||
b43_debugfs_exit();
|
||||
|
@ -121,7 +121,7 @@ void b43_hf_write(struct b43_wldev *dev, u64 value);
|
||||
|
||||
void b43_dummy_transmission(struct b43_wldev *dev, bool ofdm, bool pa_on);
|
||||
|
||||
void b43_wireless_core_reset(struct b43_wldev *dev, u32 flags);
|
||||
void b43_wireless_core_reset(struct b43_wldev *dev, bool gmode);
|
||||
|
||||
void b43_controller_restart(struct b43_wldev *dev, const char *reason);
|
||||
|
||||
|
@ -265,7 +265,6 @@ static void hardware_pctl_init_aphy(struct b43_wldev *dev)
|
||||
|
||||
void b43_phy_inita(struct b43_wldev *dev)
|
||||
{
|
||||
struct ssb_bus *bus = dev->sdev->bus;
|
||||
struct b43_phy *phy = &dev->phy;
|
||||
|
||||
/* This lowlevel A-PHY init is also called from G-PHY init.
|
||||
@ -296,9 +295,9 @@ void b43_phy_inita(struct b43_wldev *dev)
|
||||
|
||||
b43_radio_init2060(dev);
|
||||
|
||||
if ((bus->boardinfo.vendor == SSB_BOARDVENDOR_BCM) &&
|
||||
((bus->boardinfo.type == SSB_BOARD_BU4306) ||
|
||||
(bus->boardinfo.type == SSB_BOARD_BU4309))) {
|
||||
if ((dev->dev->board_vendor == SSB_BOARDVENDOR_BCM) &&
|
||||
((dev->dev->board_type == SSB_BOARD_BU4306) ||
|
||||
(dev->dev->board_type == SSB_BOARD_BU4309))) {
|
||||
; //TODO: A PHY LO
|
||||
}
|
||||
|
||||
@ -311,7 +310,7 @@ void b43_phy_inita(struct b43_wldev *dev)
|
||||
}
|
||||
|
||||
if ((phy->type == B43_PHYTYPE_G) &&
|
||||
(dev->sdev->bus->sprom.boardflags_lo & B43_BFL_PACTRL)) {
|
||||
(dev->dev->bus_sprom->boardflags_lo & B43_BFL_PACTRL)) {
|
||||
b43_phy_maskset(dev, B43_PHY_OFDM(0x6E), 0xE000, 0x3CF);
|
||||
}
|
||||
}
|
||||
@ -323,17 +322,17 @@ static int b43_aphy_init_tssi2dbm_table(struct b43_wldev *dev)
|
||||
struct b43_phy_a *aphy = phy->a;
|
||||
s16 pab0, pab1, pab2;
|
||||
|
||||
pab0 = (s16) (dev->sdev->bus->sprom.pa1b0);
|
||||
pab1 = (s16) (dev->sdev->bus->sprom.pa1b1);
|
||||
pab2 = (s16) (dev->sdev->bus->sprom.pa1b2);
|
||||
pab0 = (s16) (dev->dev->bus_sprom->pa1b0);
|
||||
pab1 = (s16) (dev->dev->bus_sprom->pa1b1);
|
||||
pab2 = (s16) (dev->dev->bus_sprom->pa1b2);
|
||||
|
||||
if (pab0 != 0 && pab1 != 0 && pab2 != 0 &&
|
||||
pab0 != -1 && pab1 != -1 && pab2 != -1) {
|
||||
/* The pabX values are set in SPROM. Use them. */
|
||||
if ((s8) dev->sdev->bus->sprom.itssi_a != 0 &&
|
||||
(s8) dev->sdev->bus->sprom.itssi_a != -1)
|
||||
if ((s8) dev->dev->bus_sprom->itssi_a != 0 &&
|
||||
(s8) dev->dev->bus_sprom->itssi_a != -1)
|
||||
aphy->tgt_idle_tssi =
|
||||
(s8) (dev->sdev->bus->sprom.itssi_a);
|
||||
(s8) (dev->dev->bus_sprom->itssi_a);
|
||||
else
|
||||
aphy->tgt_idle_tssi = 62;
|
||||
aphy->tssi2dbm = b43_generate_dyn_tssi2dbm_tab(dev, pab0,
|
||||
|
@ -168,7 +168,7 @@ void b43_phy_lock(struct b43_wldev *dev)
|
||||
B43_WARN_ON(dev->phy.phy_locked);
|
||||
dev->phy.phy_locked = 1;
|
||||
#endif
|
||||
B43_WARN_ON(dev->sdev->id.revision < 3);
|
||||
B43_WARN_ON(dev->dev->core_rev < 3);
|
||||
|
||||
if (!b43_is_mode(dev->wl, NL80211_IFTYPE_AP))
|
||||
b43_power_saving_ctl_bits(dev, B43_PS_AWAKE);
|
||||
@ -180,7 +180,7 @@ void b43_phy_unlock(struct b43_wldev *dev)
|
||||
B43_WARN_ON(!dev->phy.phy_locked);
|
||||
dev->phy.phy_locked = 0;
|
||||
#endif
|
||||
B43_WARN_ON(dev->sdev->id.revision < 3);
|
||||
B43_WARN_ON(dev->dev->core_rev < 3);
|
||||
|
||||
if (!b43_is_mode(dev->wl, NL80211_IFTYPE_AP))
|
||||
b43_power_saving_ctl_bits(dev, 0);
|
||||
@ -368,8 +368,8 @@ void b43_phy_txpower_check(struct b43_wldev *dev, unsigned int flags)
|
||||
/* The next check will be needed in two seconds, or later. */
|
||||
phy->next_txpwr_check_time = round_jiffies(now + (HZ * 2));
|
||||
|
||||
if ((dev->sdev->bus->boardinfo.vendor == SSB_BOARDVENDOR_BCM) &&
|
||||
(dev->sdev->bus->boardinfo.type == SSB_BOARD_BU4306))
|
||||
if ((dev->dev->board_vendor == SSB_BOARDVENDOR_BCM) &&
|
||||
(dev->dev->board_type == SSB_BOARD_BU4306))
|
||||
return; /* No software txpower adjustment needed */
|
||||
|
||||
result = phy->ops->recalc_txpower(dev, !!(flags & B43_TXPWR_IGNORE_TSSI));
|
||||
|
@ -718,7 +718,7 @@ static void b43_calc_nrssi_threshold(struct b43_wldev *dev)
|
||||
B43_WARN_ON(phy->type != B43_PHYTYPE_G);
|
||||
|
||||
if (!phy->gmode ||
|
||||
!(dev->sdev->bus->sprom.boardflags_lo & B43_BFL_RSSI)) {
|
||||
!(dev->dev->bus_sprom->boardflags_lo & B43_BFL_RSSI)) {
|
||||
tmp16 = b43_nrssi_hw_read(dev, 0x20);
|
||||
if (tmp16 >= 0x20)
|
||||
tmp16 -= 0x40;
|
||||
@ -1114,7 +1114,7 @@ static u16 radio2050_rfover_val(struct b43_wldev *dev,
|
||||
{
|
||||
struct b43_phy *phy = &dev->phy;
|
||||
struct b43_phy_g *gphy = phy->g;
|
||||
struct ssb_sprom *sprom = &(dev->sdev->bus->sprom);
|
||||
struct ssb_sprom *sprom = dev->dev->bus_sprom;
|
||||
|
||||
if (!phy->gmode)
|
||||
return 0;
|
||||
@ -1491,7 +1491,6 @@ static u16 b43_radio_init2050(struct b43_wldev *dev)
|
||||
|
||||
static void b43_phy_initb5(struct b43_wldev *dev)
|
||||
{
|
||||
struct ssb_bus *bus = dev->sdev->bus;
|
||||
struct b43_phy *phy = &dev->phy;
|
||||
struct b43_phy_g *gphy = phy->g;
|
||||
u16 offset, value;
|
||||
@ -1500,8 +1499,8 @@ static void b43_phy_initb5(struct b43_wldev *dev)
|
||||
if (phy->analog == 1) {
|
||||
b43_radio_set(dev, 0x007A, 0x0050);
|
||||
}
|
||||
if ((bus->boardinfo.vendor != SSB_BOARDVENDOR_BCM) &&
|
||||
(bus->boardinfo.type != SSB_BOARD_BU4306)) {
|
||||
if ((dev->dev->board_vendor != SSB_BOARDVENDOR_BCM) &&
|
||||
(dev->dev->board_type != SSB_BOARD_BU4306)) {
|
||||
value = 0x2120;
|
||||
for (offset = 0x00A8; offset < 0x00C7; offset++) {
|
||||
b43_phy_write(dev, offset, value);
|
||||
@ -1620,7 +1619,7 @@ static void b43_phy_initb6(struct b43_wldev *dev)
|
||||
b43_radio_write16(dev, 0x5A, 0x88);
|
||||
b43_radio_write16(dev, 0x5B, 0x6B);
|
||||
b43_radio_write16(dev, 0x5C, 0x0F);
|
||||
if (dev->sdev->bus->sprom.boardflags_lo & B43_BFL_ALTIQ) {
|
||||
if (dev->dev->bus_sprom->boardflags_lo & B43_BFL_ALTIQ) {
|
||||
b43_radio_write16(dev, 0x5D, 0xFA);
|
||||
b43_radio_write16(dev, 0x5E, 0xD8);
|
||||
} else {
|
||||
@ -1787,7 +1786,7 @@ static void b43_calc_loopback_gain(struct b43_wldev *dev)
|
||||
b43_phy_set(dev, B43_PHY_RFOVER, 0x0100);
|
||||
b43_phy_mask(dev, B43_PHY_RFOVERVAL, 0xCFFF);
|
||||
|
||||
if (dev->sdev->bus->sprom.boardflags_lo & B43_BFL_EXTLNA) {
|
||||
if (dev->dev->bus_sprom->boardflags_lo & B43_BFL_EXTLNA) {
|
||||
if (phy->rev >= 7) {
|
||||
b43_phy_set(dev, B43_PHY_RFOVER, 0x0800);
|
||||
b43_phy_set(dev, B43_PHY_RFOVERVAL, 0x8000);
|
||||
@ -1922,7 +1921,6 @@ static void b43_hardware_pctl_init_gphy(struct b43_wldev *dev)
|
||||
/* Initialize B/G PHY power control */
|
||||
static void b43_phy_init_pctl(struct b43_wldev *dev)
|
||||
{
|
||||
struct ssb_bus *bus = dev->sdev->bus;
|
||||
struct b43_phy *phy = &dev->phy;
|
||||
struct b43_phy_g *gphy = phy->g;
|
||||
struct b43_rfatt old_rfatt;
|
||||
@ -1931,8 +1929,8 @@ static void b43_phy_init_pctl(struct b43_wldev *dev)
|
||||
|
||||
B43_WARN_ON(phy->type != B43_PHYTYPE_G);
|
||||
|
||||
if ((bus->boardinfo.vendor == SSB_BOARDVENDOR_BCM) &&
|
||||
(bus->boardinfo.type == SSB_BOARD_BU4306))
|
||||
if ((dev->dev->board_vendor == SSB_BOARDVENDOR_BCM) &&
|
||||
(dev->dev->board_type == SSB_BOARD_BU4306))
|
||||
return;
|
||||
|
||||
b43_phy_write(dev, 0x0028, 0x8018);
|
||||
@ -2053,7 +2051,7 @@ static void b43_phy_initg(struct b43_wldev *dev)
|
||||
if (phy->rev >= 6) {
|
||||
b43_phy_maskset(dev, B43_PHY_CCK(0x36), 0x0FFF, (gphy->lo_control->tx_bias << 12));
|
||||
}
|
||||
if (dev->sdev->bus->sprom.boardflags_lo & B43_BFL_PACTRL)
|
||||
if (dev->dev->bus_sprom->boardflags_lo & B43_BFL_PACTRL)
|
||||
b43_phy_write(dev, B43_PHY_CCK(0x2E), 0x8075);
|
||||
else
|
||||
b43_phy_write(dev, B43_PHY_CCK(0x2E), 0x807F);
|
||||
@ -2066,7 +2064,7 @@ static void b43_phy_initg(struct b43_wldev *dev)
|
||||
b43_phy_write(dev, B43_PHY_LO_MASK, 0x8078);
|
||||
}
|
||||
|
||||
if (!(dev->sdev->bus->sprom.boardflags_lo & B43_BFL_RSSI)) {
|
||||
if (!(dev->dev->bus_sprom->boardflags_lo & B43_BFL_RSSI)) {
|
||||
/* The specs state to update the NRSSI LT with
|
||||
* the value 0x7FFFFFFF here. I think that is some weird
|
||||
* compiler optimization in the original driver.
|
||||
@ -2088,8 +2086,8 @@ static void b43_phy_initg(struct b43_wldev *dev)
|
||||
/* FIXME: The spec says in the following if, the 0 should be replaced
|
||||
'if OFDM may not be used in the current locale'
|
||||
but OFDM is legal everywhere */
|
||||
if ((dev->sdev->bus->chip_id == 0x4306
|
||||
&& dev->sdev->bus->chip_package == 2) || 0) {
|
||||
if ((dev->dev->chip_id == 0x4306
|
||||
&& dev->dev->chip_pkg == 2) || 0) {
|
||||
b43_phy_mask(dev, B43_PHY_CRS0, 0xBFFF);
|
||||
b43_phy_mask(dev, B43_PHY_OFDM(0xC3), 0x7FFF);
|
||||
}
|
||||
@ -2105,7 +2103,7 @@ void b43_gphy_channel_switch(struct b43_wldev *dev,
|
||||
b43_write16(dev, B43_MMIO_CHANNEL, channel2freq_bg(channel));
|
||||
|
||||
if (channel == 14) {
|
||||
if (dev->sdev->bus->sprom.country_code ==
|
||||
if (dev->dev->bus_sprom->country_code ==
|
||||
SSB_SPROM1CCODE_JAPAN)
|
||||
b43_hf_write(dev,
|
||||
b43_hf_read(dev) & ~B43_HF_ACPR);
|
||||
@ -2136,17 +2134,17 @@ static void default_baseband_attenuation(struct b43_wldev *dev,
|
||||
static void default_radio_attenuation(struct b43_wldev *dev,
|
||||
struct b43_rfatt *rf)
|
||||
{
|
||||
struct ssb_bus *bus = dev->sdev->bus;
|
||||
struct b43_bus_dev *bdev = dev->dev;
|
||||
struct b43_phy *phy = &dev->phy;
|
||||
|
||||
rf->with_padmix = 0;
|
||||
|
||||
if (bus->boardinfo.vendor == SSB_BOARDVENDOR_BCM &&
|
||||
bus->boardinfo.type == SSB_BOARD_BCM4309G) {
|
||||
if (bus->boardinfo.rev < 0x43) {
|
||||
if (dev->dev->board_vendor == SSB_BOARDVENDOR_BCM &&
|
||||
dev->dev->board_type == SSB_BOARD_BCM4309G) {
|
||||
if (dev->dev->board_rev < 0x43) {
|
||||
rf->att = 2;
|
||||
return;
|
||||
} else if (bus->boardinfo.rev < 0x51) {
|
||||
} else if (dev->dev->board_rev < 0x51) {
|
||||
rf->att = 3;
|
||||
return;
|
||||
}
|
||||
@ -2172,21 +2170,21 @@ static void default_radio_attenuation(struct b43_wldev *dev,
|
||||
return;
|
||||
case 1:
|
||||
if (phy->type == B43_PHYTYPE_G) {
|
||||
if (bus->boardinfo.vendor == SSB_BOARDVENDOR_BCM
|
||||
&& bus->boardinfo.type == SSB_BOARD_BCM4309G
|
||||
&& bus->boardinfo.rev >= 30)
|
||||
if (bdev->board_vendor == SSB_BOARDVENDOR_BCM
|
||||
&& bdev->board_type == SSB_BOARD_BCM4309G
|
||||
&& bdev->board_rev >= 30)
|
||||
rf->att = 3;
|
||||
else if (bus->boardinfo.vendor ==
|
||||
else if (bdev->board_vendor ==
|
||||
SSB_BOARDVENDOR_BCM
|
||||
&& bus->boardinfo.type ==
|
||||
&& bdev->board_type ==
|
||||
SSB_BOARD_BU4306)
|
||||
rf->att = 3;
|
||||
else
|
||||
rf->att = 1;
|
||||
} else {
|
||||
if (bus->boardinfo.vendor == SSB_BOARDVENDOR_BCM
|
||||
&& bus->boardinfo.type == SSB_BOARD_BCM4309G
|
||||
&& bus->boardinfo.rev >= 30)
|
||||
if (bdev->board_vendor == SSB_BOARDVENDOR_BCM
|
||||
&& bdev->board_type == SSB_BOARD_BCM4309G
|
||||
&& bdev->board_rev >= 30)
|
||||
rf->att = 7;
|
||||
else
|
||||
rf->att = 6;
|
||||
@ -2194,16 +2192,16 @@ static void default_radio_attenuation(struct b43_wldev *dev,
|
||||
return;
|
||||
case 2:
|
||||
if (phy->type == B43_PHYTYPE_G) {
|
||||
if (bus->boardinfo.vendor == SSB_BOARDVENDOR_BCM
|
||||
&& bus->boardinfo.type == SSB_BOARD_BCM4309G
|
||||
&& bus->boardinfo.rev >= 30)
|
||||
if (bdev->board_vendor == SSB_BOARDVENDOR_BCM
|
||||
&& bdev->board_type == SSB_BOARD_BCM4309G
|
||||
&& bdev->board_rev >= 30)
|
||||
rf->att = 3;
|
||||
else if (bus->boardinfo.vendor ==
|
||||
else if (bdev->board_vendor ==
|
||||
SSB_BOARDVENDOR_BCM
|
||||
&& bus->boardinfo.type ==
|
||||
&& bdev->board_type ==
|
||||
SSB_BOARD_BU4306)
|
||||
rf->att = 5;
|
||||
else if (bus->chip_id == 0x4320)
|
||||
else if (bdev->chip_id == 0x4320)
|
||||
rf->att = 4;
|
||||
else
|
||||
rf->att = 3;
|
||||
@ -2384,11 +2382,11 @@ static int b43_gphy_init_tssi2dbm_table(struct b43_wldev *dev)
|
||||
struct b43_phy_g *gphy = phy->g;
|
||||
s16 pab0, pab1, pab2;
|
||||
|
||||
pab0 = (s16) (dev->sdev->bus->sprom.pa0b0);
|
||||
pab1 = (s16) (dev->sdev->bus->sprom.pa0b1);
|
||||
pab2 = (s16) (dev->sdev->bus->sprom.pa0b2);
|
||||
pab0 = (s16) (dev->dev->bus_sprom->pa0b0);
|
||||
pab1 = (s16) (dev->dev->bus_sprom->pa0b1);
|
||||
pab2 = (s16) (dev->dev->bus_sprom->pa0b2);
|
||||
|
||||
B43_WARN_ON((dev->sdev->bus->chip_id == 0x4301) &&
|
||||
B43_WARN_ON((dev->dev->chip_id == 0x4301) &&
|
||||
(phy->radio_ver != 0x2050)); /* Not supported anymore */
|
||||
|
||||
gphy->dyn_tssi_tbl = 0;
|
||||
@ -2396,10 +2394,10 @@ static int b43_gphy_init_tssi2dbm_table(struct b43_wldev *dev)
|
||||
if (pab0 != 0 && pab1 != 0 && pab2 != 0 &&
|
||||
pab0 != -1 && pab1 != -1 && pab2 != -1) {
|
||||
/* The pabX values are set in SPROM. Use them. */
|
||||
if ((s8) dev->sdev->bus->sprom.itssi_bg != 0 &&
|
||||
(s8) dev->sdev->bus->sprom.itssi_bg != -1) {
|
||||
if ((s8) dev->dev->bus_sprom->itssi_bg != 0 &&
|
||||
(s8) dev->dev->bus_sprom->itssi_bg != -1) {
|
||||
gphy->tgt_idle_tssi =
|
||||
(s8) (dev->sdev->bus->sprom.itssi_bg);
|
||||
(s8) (dev->dev->bus_sprom->itssi_bg);
|
||||
} else
|
||||
gphy->tgt_idle_tssi = 62;
|
||||
gphy->tssi2dbm = b43_generate_dyn_tssi2dbm_tab(dev, pab0,
|
||||
@ -2537,7 +2535,7 @@ static int b43_gphy_op_prepare_hardware(struct b43_wldev *dev)
|
||||
b43_wireless_core_reset(dev, 0);
|
||||
b43_phy_initg(dev);
|
||||
phy->gmode = 1;
|
||||
b43_wireless_core_reset(dev, B43_TMSLOW_GMODE);
|
||||
b43_wireless_core_reset(dev, 1);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -2840,7 +2838,7 @@ static void b43_gphy_op_adjust_txpower(struct b43_wldev *dev)
|
||||
B43_TXCTL_TXMIX;
|
||||
rfatt += 2;
|
||||
bbatt += 2;
|
||||
} else if (dev->sdev->bus->sprom.
|
||||
} else if (dev->dev->bus_sprom->
|
||||
boardflags_lo &
|
||||
B43_BFL_PACTRL) {
|
||||
bbatt += 4 * (rfatt - 2);
|
||||
@ -2914,14 +2912,14 @@ static enum b43_txpwr_result b43_gphy_op_recalc_txpower(struct b43_wldev *dev,
|
||||
estimated_pwr = b43_gphy_estimate_power_out(dev, average_tssi);
|
||||
|
||||
B43_WARN_ON(phy->type != B43_PHYTYPE_G);
|
||||
max_pwr = dev->sdev->bus->sprom.maxpwr_bg;
|
||||
if (dev->sdev->bus->sprom.boardflags_lo & B43_BFL_PACTRL)
|
||||
max_pwr = dev->dev->bus_sprom->maxpwr_bg;
|
||||
if (dev->dev->bus_sprom->boardflags_lo & B43_BFL_PACTRL)
|
||||
max_pwr -= 3; /* minus 0.75 */
|
||||
if (unlikely(max_pwr >= INT_TO_Q52(30/*dBm*/))) {
|
||||
b43warn(dev->wl,
|
||||
"Invalid max-TX-power value in SPROM.\n");
|
||||
max_pwr = INT_TO_Q52(20); /* fake it */
|
||||
dev->sdev->bus->sprom.maxpwr_bg = max_pwr;
|
||||
dev->dev->bus_sprom->maxpwr_bg = max_pwr;
|
||||
}
|
||||
|
||||
/* Get desired power (in Q5.2) */
|
||||
@ -3014,7 +3012,7 @@ static void b43_gphy_op_pwork_60sec(struct b43_wldev *dev)
|
||||
{
|
||||
struct b43_phy *phy = &dev->phy;
|
||||
|
||||
if (!(dev->sdev->bus->sprom.boardflags_lo & B43_BFL_RSSI))
|
||||
if (!(dev->dev->bus_sprom->boardflags_lo & B43_BFL_RSSI))
|
||||
return;
|
||||
|
||||
b43_mac_suspend(dev);
|
||||
|
@ -85,39 +85,39 @@ static void b43_lpphy_op_free(struct b43_wldev *dev)
|
||||
/* http://bcm-v4.sipsolutions.net/802.11/PHY/LP/ReadBandSrom */
|
||||
static void lpphy_read_band_sprom(struct b43_wldev *dev)
|
||||
{
|
||||
struct ssb_sprom *sprom = dev->dev->bus_sprom;
|
||||
struct b43_phy_lp *lpphy = dev->phy.lp;
|
||||
struct ssb_bus *bus = dev->sdev->bus;
|
||||
u16 cckpo, maxpwr;
|
||||
u32 ofdmpo;
|
||||
int i;
|
||||
|
||||
if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
|
||||
lpphy->tx_isolation_med_band = bus->sprom.tri2g;
|
||||
lpphy->bx_arch = bus->sprom.bxa2g;
|
||||
lpphy->rx_pwr_offset = bus->sprom.rxpo2g;
|
||||
lpphy->rssi_vf = bus->sprom.rssismf2g;
|
||||
lpphy->rssi_vc = bus->sprom.rssismc2g;
|
||||
lpphy->rssi_gs = bus->sprom.rssisav2g;
|
||||
lpphy->txpa[0] = bus->sprom.pa0b0;
|
||||
lpphy->txpa[1] = bus->sprom.pa0b1;
|
||||
lpphy->txpa[2] = bus->sprom.pa0b2;
|
||||
maxpwr = bus->sprom.maxpwr_bg;
|
||||
lpphy->tx_isolation_med_band = sprom->tri2g;
|
||||
lpphy->bx_arch = sprom->bxa2g;
|
||||
lpphy->rx_pwr_offset = sprom->rxpo2g;
|
||||
lpphy->rssi_vf = sprom->rssismf2g;
|
||||
lpphy->rssi_vc = sprom->rssismc2g;
|
||||
lpphy->rssi_gs = sprom->rssisav2g;
|
||||
lpphy->txpa[0] = sprom->pa0b0;
|
||||
lpphy->txpa[1] = sprom->pa0b1;
|
||||
lpphy->txpa[2] = sprom->pa0b2;
|
||||
maxpwr = sprom->maxpwr_bg;
|
||||
lpphy->max_tx_pwr_med_band = maxpwr;
|
||||
cckpo = bus->sprom.cck2gpo;
|
||||
cckpo = sprom->cck2gpo;
|
||||
/*
|
||||
* We don't read SPROM's opo as specs say. On rev8 SPROMs
|
||||
* opo == ofdm2gpo and we don't know any SSB with LP-PHY
|
||||
* and SPROM rev below 8.
|
||||
*/
|
||||
B43_WARN_ON(bus->sprom.revision < 8);
|
||||
ofdmpo = bus->sprom.ofdm2gpo;
|
||||
B43_WARN_ON(sprom->revision < 8);
|
||||
ofdmpo = sprom->ofdm2gpo;
|
||||
if (cckpo) {
|
||||
for (i = 0; i < 4; i++) {
|
||||
lpphy->tx_max_rate[i] =
|
||||
maxpwr - (ofdmpo & 0xF) * 2;
|
||||
ofdmpo >>= 4;
|
||||
}
|
||||
ofdmpo = bus->sprom.ofdm2gpo;
|
||||
ofdmpo = sprom->ofdm2gpo;
|
||||
for (i = 4; i < 15; i++) {
|
||||
lpphy->tx_max_rate[i] =
|
||||
maxpwr - (ofdmpo & 0xF) * 2;
|
||||
@ -131,39 +131,39 @@ static void lpphy_read_band_sprom(struct b43_wldev *dev)
|
||||
lpphy->tx_max_rate[i] = maxpwr - ofdmpo;
|
||||
}
|
||||
} else { /* 5GHz */
|
||||
lpphy->tx_isolation_low_band = bus->sprom.tri5gl;
|
||||
lpphy->tx_isolation_med_band = bus->sprom.tri5g;
|
||||
lpphy->tx_isolation_hi_band = bus->sprom.tri5gh;
|
||||
lpphy->bx_arch = bus->sprom.bxa5g;
|
||||
lpphy->rx_pwr_offset = bus->sprom.rxpo5g;
|
||||
lpphy->rssi_vf = bus->sprom.rssismf5g;
|
||||
lpphy->rssi_vc = bus->sprom.rssismc5g;
|
||||
lpphy->rssi_gs = bus->sprom.rssisav5g;
|
||||
lpphy->txpa[0] = bus->sprom.pa1b0;
|
||||
lpphy->txpa[1] = bus->sprom.pa1b1;
|
||||
lpphy->txpa[2] = bus->sprom.pa1b2;
|
||||
lpphy->txpal[0] = bus->sprom.pa1lob0;
|
||||
lpphy->txpal[1] = bus->sprom.pa1lob1;
|
||||
lpphy->txpal[2] = bus->sprom.pa1lob2;
|
||||
lpphy->txpah[0] = bus->sprom.pa1hib0;
|
||||
lpphy->txpah[1] = bus->sprom.pa1hib1;
|
||||
lpphy->txpah[2] = bus->sprom.pa1hib2;
|
||||
maxpwr = bus->sprom.maxpwr_al;
|
||||
ofdmpo = bus->sprom.ofdm5glpo;
|
||||
lpphy->tx_isolation_low_band = sprom->tri5gl;
|
||||
lpphy->tx_isolation_med_band = sprom->tri5g;
|
||||
lpphy->tx_isolation_hi_band = sprom->tri5gh;
|
||||
lpphy->bx_arch = sprom->bxa5g;
|
||||
lpphy->rx_pwr_offset = sprom->rxpo5g;
|
||||
lpphy->rssi_vf = sprom->rssismf5g;
|
||||
lpphy->rssi_vc = sprom->rssismc5g;
|
||||
lpphy->rssi_gs = sprom->rssisav5g;
|
||||
lpphy->txpa[0] = sprom->pa1b0;
|
||||
lpphy->txpa[1] = sprom->pa1b1;
|
||||
lpphy->txpa[2] = sprom->pa1b2;
|
||||
lpphy->txpal[0] = sprom->pa1lob0;
|
||||
lpphy->txpal[1] = sprom->pa1lob1;
|
||||
lpphy->txpal[2] = sprom->pa1lob2;
|
||||
lpphy->txpah[0] = sprom->pa1hib0;
|
||||
lpphy->txpah[1] = sprom->pa1hib1;
|
||||
lpphy->txpah[2] = sprom->pa1hib2;
|
||||
maxpwr = sprom->maxpwr_al;
|
||||
ofdmpo = sprom->ofdm5glpo;
|
||||
lpphy->max_tx_pwr_low_band = maxpwr;
|
||||
for (i = 4; i < 12; i++) {
|
||||
lpphy->tx_max_ratel[i] = maxpwr - (ofdmpo & 0xF) * 2;
|
||||
ofdmpo >>= 4;
|
||||
}
|
||||
maxpwr = bus->sprom.maxpwr_a;
|
||||
ofdmpo = bus->sprom.ofdm5gpo;
|
||||
maxpwr = sprom->maxpwr_a;
|
||||
ofdmpo = sprom->ofdm5gpo;
|
||||
lpphy->max_tx_pwr_med_band = maxpwr;
|
||||
for (i = 4; i < 12; i++) {
|
||||
lpphy->tx_max_rate[i] = maxpwr - (ofdmpo & 0xF) * 2;
|
||||
ofdmpo >>= 4;
|
||||
}
|
||||
maxpwr = bus->sprom.maxpwr_ah;
|
||||
ofdmpo = bus->sprom.ofdm5ghpo;
|
||||
maxpwr = sprom->maxpwr_ah;
|
||||
ofdmpo = sprom->ofdm5ghpo;
|
||||
lpphy->max_tx_pwr_hi_band = maxpwr;
|
||||
for (i = 4; i < 12; i++) {
|
||||
lpphy->tx_max_rateh[i] = maxpwr - (ofdmpo & 0xF) * 2;
|
||||
@ -214,7 +214,8 @@ static void lpphy_table_init(struct b43_wldev *dev)
|
||||
|
||||
static void lpphy_baseband_rev0_1_init(struct b43_wldev *dev)
|
||||
{
|
||||
struct ssb_bus *bus = dev->sdev->bus;
|
||||
struct ssb_bus *bus = dev->dev->sdev->bus;
|
||||
struct ssb_sprom *sprom = dev->dev->bus_sprom;
|
||||
struct b43_phy_lp *lpphy = dev->phy.lp;
|
||||
u16 tmp, tmp2;
|
||||
|
||||
@ -242,9 +243,9 @@ static void lpphy_baseband_rev0_1_init(struct b43_wldev *dev)
|
||||
b43_phy_maskset(dev, B43_LPPHY_CRS_ED_THRESH, 0x00FF, 0xAD00);
|
||||
b43_phy_maskset(dev, B43_LPPHY_INPUT_PWRDB,
|
||||
0xFF00, lpphy->rx_pwr_offset);
|
||||
if ((bus->sprom.boardflags_lo & B43_BFL_FEM) &&
|
||||
if ((sprom->boardflags_lo & B43_BFL_FEM) &&
|
||||
((b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) ||
|
||||
(bus->sprom.boardflags_hi & B43_BFH_PAREF))) {
|
||||
(sprom->boardflags_hi & B43_BFH_PAREF))) {
|
||||
ssb_pmu_set_ldo_voltage(&bus->chipco, LDO_PAREF, 0x28);
|
||||
ssb_pmu_set_ldo_paref(&bus->chipco, true);
|
||||
if (dev->phy.rev == 0) {
|
||||
@ -260,7 +261,7 @@ static void lpphy_baseband_rev0_1_init(struct b43_wldev *dev)
|
||||
}
|
||||
tmp = lpphy->rssi_vf | lpphy->rssi_vc << 4 | 0xA000;
|
||||
b43_phy_write(dev, B43_LPPHY_AFE_RSSI_CTL_0, tmp);
|
||||
if (bus->sprom.boardflags_hi & B43_BFH_RSSIINV)
|
||||
if (sprom->boardflags_hi & B43_BFH_RSSIINV)
|
||||
b43_phy_maskset(dev, B43_LPPHY_AFE_RSSI_CTL_1, 0xF000, 0x0AAA);
|
||||
else
|
||||
b43_phy_maskset(dev, B43_LPPHY_AFE_RSSI_CTL_1, 0xF000, 0x02AA);
|
||||
@ -268,7 +269,7 @@ static void lpphy_baseband_rev0_1_init(struct b43_wldev *dev)
|
||||
b43_phy_maskset(dev, B43_LPPHY_RX_RADIO_CTL,
|
||||
0xFFF9, (lpphy->bx_arch << 1));
|
||||
if (dev->phy.rev == 1 &&
|
||||
(bus->sprom.boardflags_hi & B43_BFH_FEM_BT)) {
|
||||
(sprom->boardflags_hi & B43_BFH_FEM_BT)) {
|
||||
b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_1, 0xFFC0, 0x000A);
|
||||
b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_1, 0x3F00, 0x0900);
|
||||
b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_2, 0xFFC0, 0x000A);
|
||||
@ -286,8 +287,8 @@ static void lpphy_baseband_rev0_1_init(struct b43_wldev *dev)
|
||||
b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_8, 0xFFC0, 0x000A);
|
||||
b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_8, 0xC0FF, 0x0B00);
|
||||
} else if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ ||
|
||||
(bus->boardinfo.type == 0x048A) || ((dev->phy.rev == 0) &&
|
||||
(bus->sprom.boardflags_lo & B43_BFL_FEM))) {
|
||||
(dev->dev->board_type == 0x048A) || ((dev->phy.rev == 0) &&
|
||||
(sprom->boardflags_lo & B43_BFL_FEM))) {
|
||||
b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_1, 0xFFC0, 0x0001);
|
||||
b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_1, 0xC0FF, 0x0400);
|
||||
b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_2, 0xFFC0, 0x0001);
|
||||
@ -297,7 +298,7 @@ static void lpphy_baseband_rev0_1_init(struct b43_wldev *dev)
|
||||
b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_4, 0xFFC0, 0x0002);
|
||||
b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_4, 0xC0FF, 0x0A00);
|
||||
} else if (dev->phy.rev == 1 ||
|
||||
(bus->sprom.boardflags_lo & B43_BFL_FEM)) {
|
||||
(sprom->boardflags_lo & B43_BFL_FEM)) {
|
||||
b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_1, 0xFFC0, 0x0004);
|
||||
b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_1, 0xC0FF, 0x0800);
|
||||
b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_2, 0xFFC0, 0x0004);
|
||||
@ -316,15 +317,15 @@ static void lpphy_baseband_rev0_1_init(struct b43_wldev *dev)
|
||||
b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_4, 0xFFC0, 0x0006);
|
||||
b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_4, 0xC0FF, 0x0700);
|
||||
}
|
||||
if (dev->phy.rev == 1 && (bus->sprom.boardflags_hi & B43_BFH_PAREF)) {
|
||||
if (dev->phy.rev == 1 && (sprom->boardflags_hi & B43_BFH_PAREF)) {
|
||||
b43_phy_copy(dev, B43_LPPHY_TR_LOOKUP_5, B43_LPPHY_TR_LOOKUP_1);
|
||||
b43_phy_copy(dev, B43_LPPHY_TR_LOOKUP_6, B43_LPPHY_TR_LOOKUP_2);
|
||||
b43_phy_copy(dev, B43_LPPHY_TR_LOOKUP_7, B43_LPPHY_TR_LOOKUP_3);
|
||||
b43_phy_copy(dev, B43_LPPHY_TR_LOOKUP_8, B43_LPPHY_TR_LOOKUP_4);
|
||||
}
|
||||
if ((bus->sprom.boardflags_hi & B43_BFH_FEM_BT) &&
|
||||
(bus->chip_id == 0x5354) &&
|
||||
(bus->chip_package == SSB_CHIPPACK_BCM4712S)) {
|
||||
if ((sprom->boardflags_hi & B43_BFH_FEM_BT) &&
|
||||
(dev->dev->chip_id == 0x5354) &&
|
||||
(dev->dev->chip_pkg == SSB_CHIPPACK_BCM4712S)) {
|
||||
b43_phy_set(dev, B43_LPPHY_CRSGAIN_CTL, 0x0006);
|
||||
b43_phy_write(dev, B43_LPPHY_GPIO_SELECT, 0x0005);
|
||||
b43_phy_write(dev, B43_LPPHY_GPIO_OUTEN, 0xFFFF);
|
||||
@ -412,7 +413,6 @@ static void lpphy_restore_dig_flt_state(struct b43_wldev *dev)
|
||||
|
||||
static void lpphy_baseband_rev2plus_init(struct b43_wldev *dev)
|
||||
{
|
||||
struct ssb_bus *bus = dev->sdev->bus;
|
||||
struct b43_phy_lp *lpphy = dev->phy.lp;
|
||||
|
||||
b43_phy_write(dev, B43_LPPHY_AFE_DAC_CTL, 0x50);
|
||||
@ -432,7 +432,7 @@ static void lpphy_baseband_rev2plus_init(struct b43_wldev *dev)
|
||||
b43_phy_mask(dev, B43_LPPHY_CRSGAIN_CTL, ~0x4000);
|
||||
b43_phy_mask(dev, B43_LPPHY_CRSGAIN_CTL, ~0x2000);
|
||||
b43_phy_set(dev, B43_PHY_OFDM(0x10A), 0x1);
|
||||
if (bus->boardinfo.rev >= 0x18) {
|
||||
if (dev->dev->board_rev >= 0x18) {
|
||||
b43_lptab_write(dev, B43_LPTAB32(17, 65), 0xEC);
|
||||
b43_phy_maskset(dev, B43_PHY_OFDM(0x10A), 0xFF01, 0x14);
|
||||
} else {
|
||||
@ -449,7 +449,7 @@ static void lpphy_baseband_rev2plus_init(struct b43_wldev *dev)
|
||||
b43_phy_maskset(dev, B43_LPPHY_CLIPCTRTHRESH, 0xFC1F, 0xA0);
|
||||
b43_phy_maskset(dev, B43_LPPHY_GAINDIRECTMISMATCH, 0xE0FF, 0x300);
|
||||
b43_phy_maskset(dev, B43_LPPHY_HIGAINDB, 0x00FF, 0x2A00);
|
||||
if ((bus->chip_id == 0x4325) && (bus->chip_rev == 0)) {
|
||||
if ((dev->dev->chip_id == 0x4325) && (dev->dev->chip_rev == 0)) {
|
||||
b43_phy_maskset(dev, B43_LPPHY_LOWGAINDB, 0x00FF, 0x2100);
|
||||
b43_phy_maskset(dev, B43_LPPHY_VERYLOWGAINDB, 0xFF00, 0xA);
|
||||
} else {
|
||||
@ -467,7 +467,7 @@ static void lpphy_baseband_rev2plus_init(struct b43_wldev *dev)
|
||||
b43_phy_maskset(dev, B43_LPPHY_CLIPCTRTHRESH, 0xFFE0, 0x12);
|
||||
b43_phy_maskset(dev, B43_LPPHY_GAINMISMATCH, 0x0FFF, 0x9000);
|
||||
|
||||
if ((bus->chip_id == 0x4325) && (bus->chip_rev == 0)) {
|
||||
if ((dev->dev->chip_id == 0x4325) && (dev->dev->chip_rev == 0)) {
|
||||
b43_lptab_write(dev, B43_LPTAB16(0x08, 0x14), 0);
|
||||
b43_lptab_write(dev, B43_LPTAB16(0x08, 0x12), 0x40);
|
||||
}
|
||||
@ -492,7 +492,7 @@ static void lpphy_baseband_rev2plus_init(struct b43_wldev *dev)
|
||||
0x2000 | ((u16)lpphy->rssi_gs << 10) |
|
||||
((u16)lpphy->rssi_vc << 4) | lpphy->rssi_vf);
|
||||
|
||||
if ((bus->chip_id == 0x4325) && (bus->chip_rev == 0)) {
|
||||
if ((dev->dev->chip_id == 0x4325) && (dev->dev->chip_rev == 0)) {
|
||||
b43_phy_set(dev, B43_LPPHY_AFE_ADC_CTL_0, 0x1C);
|
||||
b43_phy_maskset(dev, B43_LPPHY_AFE_CTL, 0x00FF, 0x8800);
|
||||
b43_phy_maskset(dev, B43_LPPHY_AFE_ADC_CTL_1, 0xFC3C, 0x0400);
|
||||
@ -519,7 +519,7 @@ struct b2062_freqdata {
|
||||
static void lpphy_2062_init(struct b43_wldev *dev)
|
||||
{
|
||||
struct b43_phy_lp *lpphy = dev->phy.lp;
|
||||
struct ssb_bus *bus = dev->sdev->bus;
|
||||
struct ssb_bus *bus = dev->dev->sdev->bus;
|
||||
u32 crystalfreq, tmp, ref;
|
||||
unsigned int i;
|
||||
const struct b2062_freqdata *fd = NULL;
|
||||
@ -697,7 +697,7 @@ static void lpphy_radio_init(struct b43_wldev *dev)
|
||||
lpphy_sync_stx(dev);
|
||||
b43_phy_write(dev, B43_PHY_OFDM(0xF0), 0x5F80);
|
||||
b43_phy_write(dev, B43_PHY_OFDM(0xF1), 0);
|
||||
if (dev->sdev->bus->chip_id == 0x4325) {
|
||||
if (dev->dev->chip_id == 0x4325) {
|
||||
// TODO SSB PMU recalibration
|
||||
}
|
||||
}
|
||||
@ -1289,7 +1289,7 @@ finish:
|
||||
|
||||
static void lpphy_rev2plus_rc_calib(struct b43_wldev *dev)
|
||||
{
|
||||
struct ssb_bus *bus = dev->sdev->bus;
|
||||
struct ssb_bus *bus = dev->dev->sdev->bus;
|
||||
u32 crystal_freq = bus->chipco.pmu.crystalfreq * 1000;
|
||||
u8 tmp = b43_radio_read(dev, B2063_RX_BB_SP8) & 0xFF;
|
||||
int i;
|
||||
@ -1840,7 +1840,6 @@ static void lpphy_papd_cal(struct b43_wldev *dev, struct lpphy_tx_gains gains,
|
||||
static void lpphy_papd_cal_txpwr(struct b43_wldev *dev)
|
||||
{
|
||||
struct b43_phy_lp *lpphy = dev->phy.lp;
|
||||
struct ssb_bus *bus = dev->sdev->bus;
|
||||
struct lpphy_tx_gains gains, oldgains;
|
||||
int old_txpctl, old_afe_ovr, old_rf, old_bbmult;
|
||||
|
||||
@ -1854,7 +1853,7 @@ static void lpphy_papd_cal_txpwr(struct b43_wldev *dev)
|
||||
|
||||
lpphy_set_tx_power_control(dev, B43_LPPHY_TXPCTL_OFF);
|
||||
|
||||
if (bus->chip_id == 0x4325 && bus->chip_rev == 0)
|
||||
if (dev->dev->chip_id == 0x4325 && dev->dev->chip_rev == 0)
|
||||
lpphy_papd_cal(dev, gains, 0, 1, 30);
|
||||
else
|
||||
lpphy_papd_cal(dev, gains, 0, 1, 65);
|
||||
@ -1870,7 +1869,6 @@ static int lpphy_rx_iq_cal(struct b43_wldev *dev, bool noise, bool tx,
|
||||
bool rx, bool pa, struct lpphy_tx_gains *gains)
|
||||
{
|
||||
struct b43_phy_lp *lpphy = dev->phy.lp;
|
||||
struct ssb_bus *bus = dev->sdev->bus;
|
||||
const struct lpphy_rx_iq_comp *iqcomp = NULL;
|
||||
struct lpphy_tx_gains nogains, oldgains;
|
||||
u16 tmp;
|
||||
@ -1879,7 +1877,7 @@ static int lpphy_rx_iq_cal(struct b43_wldev *dev, bool noise, bool tx,
|
||||
memset(&nogains, 0, sizeof(nogains));
|
||||
memset(&oldgains, 0, sizeof(oldgains));
|
||||
|
||||
if (bus->chip_id == 0x5354) {
|
||||
if (dev->dev->chip_id == 0x5354) {
|
||||
for (i = 0; i < ARRAY_SIZE(lpphy_5354_iq_table); i++) {
|
||||
if (lpphy_5354_iq_table[i].chan == lpphy->channel) {
|
||||
iqcomp = &lpphy_5354_iq_table[i];
|
||||
@ -2408,11 +2406,9 @@ static const struct b206x_channel b2063_chantbl[] = {
|
||||
|
||||
static void lpphy_b2062_reset_pll_bias(struct b43_wldev *dev)
|
||||
{
|
||||
struct ssb_bus *bus = dev->sdev->bus;
|
||||
|
||||
b43_radio_write(dev, B2062_S_RFPLL_CTL2, 0xFF);
|
||||
udelay(20);
|
||||
if (bus->chip_id == 0x5354) {
|
||||
if (dev->dev->chip_id == 0x5354) {
|
||||
b43_radio_write(dev, B2062_N_COMM1, 4);
|
||||
b43_radio_write(dev, B2062_S_RFPLL_CTL2, 4);
|
||||
} else {
|
||||
@ -2432,7 +2428,7 @@ static int lpphy_b2062_tune(struct b43_wldev *dev,
|
||||
unsigned int channel)
|
||||
{
|
||||
struct b43_phy_lp *lpphy = dev->phy.lp;
|
||||
struct ssb_bus *bus = dev->sdev->bus;
|
||||
struct ssb_bus *bus = dev->dev->sdev->bus;
|
||||
const struct b206x_channel *chandata = NULL;
|
||||
u32 crystal_freq = bus->chipco.pmu.crystalfreq * 1000;
|
||||
u32 tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8, tmp9;
|
||||
@ -2522,7 +2518,7 @@ static void lpphy_b2063_vco_calib(struct b43_wldev *dev)
|
||||
static int lpphy_b2063_tune(struct b43_wldev *dev,
|
||||
unsigned int channel)
|
||||
{
|
||||
struct ssb_bus *bus = dev->sdev->bus;
|
||||
struct ssb_bus *bus = dev->dev->sdev->bus;
|
||||
|
||||
static const struct b206x_channel *chandata = NULL;
|
||||
u32 crystal_freq = bus->chipco.pmu.crystalfreq * 1000;
|
||||
@ -2670,6 +2666,11 @@ static int b43_lpphy_op_init(struct b43_wldev *dev)
|
||||
{
|
||||
int err;
|
||||
|
||||
if (dev->dev->bus_type != B43_BUS_SSB) {
|
||||
b43err(dev->wl, "LP-PHY is supported only on SSB!\n");
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
lpphy_read_band_sprom(dev); //FIXME should this be in prepare_structs?
|
||||
lpphy_baseband_init(dev);
|
||||
lpphy_radio_init(dev);
|
||||
|
@ -299,7 +299,7 @@ static void b43_nphy_tx_power_ctrl(struct b43_wldev *dev, bool enable)
|
||||
static void b43_nphy_tx_power_fix(struct b43_wldev *dev)
|
||||
{
|
||||
struct b43_phy_n *nphy = dev->phy.n;
|
||||
struct ssb_sprom *sprom = &(dev->sdev->bus->sprom);
|
||||
struct ssb_sprom *sprom = dev->dev->bus_sprom;
|
||||
|
||||
u8 txpi[2], bbmult, i;
|
||||
u16 tmp, radio_gain, dac_gain;
|
||||
@ -423,16 +423,15 @@ static void b43_radio_init2055_pre(struct b43_wldev *dev)
|
||||
static void b43_radio_init2055_post(struct b43_wldev *dev)
|
||||
{
|
||||
struct b43_phy_n *nphy = dev->phy.n;
|
||||
struct ssb_sprom *sprom = &(dev->sdev->bus->sprom);
|
||||
struct ssb_boardinfo *binfo = &(dev->sdev->bus->boardinfo);
|
||||
struct ssb_sprom *sprom = dev->dev->bus_sprom;
|
||||
int i;
|
||||
u16 val;
|
||||
bool workaround = false;
|
||||
|
||||
if (sprom->revision < 4)
|
||||
workaround = (binfo->vendor != PCI_VENDOR_ID_BROADCOM &&
|
||||
binfo->type == 0x46D &&
|
||||
binfo->rev >= 0x41);
|
||||
workaround = (dev->dev->board_vendor != PCI_VENDOR_ID_BROADCOM
|
||||
&& dev->dev->board_type == 0x46D
|
||||
&& dev->dev->board_rev >= 0x41);
|
||||
else
|
||||
workaround =
|
||||
!(sprom->boardflags2_lo & B43_BFL2_RXBB_INT_REG_DIS);
|
||||
@ -983,7 +982,7 @@ static u16 b43_nphy_classifier(struct b43_wldev *dev, u16 mask, u16 val)
|
||||
{
|
||||
u16 tmp;
|
||||
|
||||
if (dev->sdev->id.revision == 16)
|
||||
if (dev->dev->core_rev == 16)
|
||||
b43_mac_suspend(dev);
|
||||
|
||||
tmp = b43_phy_read(dev, B43_NPHY_CLASSCTL);
|
||||
@ -993,7 +992,7 @@ static u16 b43_nphy_classifier(struct b43_wldev *dev, u16 mask, u16 val)
|
||||
tmp |= (val & mask);
|
||||
b43_phy_maskset(dev, B43_NPHY_CLASSCTL, 0xFFF8, tmp);
|
||||
|
||||
if (dev->sdev->id.revision == 16)
|
||||
if (dev->dev->core_rev == 16)
|
||||
b43_mac_enable(dev);
|
||||
|
||||
return tmp;
|
||||
@ -1168,7 +1167,7 @@ static void b43_nphy_adjust_lna_gain_table(struct b43_wldev *dev)
|
||||
static void b43_nphy_gain_ctrl_workarounds(struct b43_wldev *dev)
|
||||
{
|
||||
struct b43_phy_n *nphy = dev->phy.n;
|
||||
struct ssb_sprom *sprom = &(dev->sdev->bus->sprom);
|
||||
struct ssb_sprom *sprom = dev->dev->bus_sprom;
|
||||
|
||||
/* PHY rev 0, 1, 2 */
|
||||
u8 i, j;
|
||||
@ -1373,7 +1372,7 @@ static void b43_nphy_gain_ctrl_workarounds(struct b43_wldev *dev)
|
||||
/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/Workarounds */
|
||||
static void b43_nphy_workarounds(struct b43_wldev *dev)
|
||||
{
|
||||
struct ssb_bus *bus = dev->sdev->bus;
|
||||
struct ssb_sprom *sprom = dev->dev->bus_sprom;
|
||||
struct b43_phy *phy = &dev->phy;
|
||||
struct b43_phy_n *nphy = phy->n;
|
||||
|
||||
@ -1443,9 +1442,9 @@ static void b43_nphy_workarounds(struct b43_wldev *dev)
|
||||
|
||||
/* N PHY WAR TX Chain Update with hw_phytxchain as argument */
|
||||
|
||||
if ((bus->sprom.boardflags2_lo & B43_BFL2_APLL_WAR &&
|
||||
if ((sprom->boardflags2_lo & B43_BFL2_APLL_WAR &&
|
||||
b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) ||
|
||||
(bus->sprom.boardflags2_lo & B43_BFL2_GPLL_WAR &&
|
||||
(sprom->boardflags2_lo & B43_BFL2_GPLL_WAR &&
|
||||
b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ))
|
||||
tmp32 = 0x00088888;
|
||||
else
|
||||
@ -1503,8 +1502,8 @@ static void b43_nphy_workarounds(struct b43_wldev *dev)
|
||||
b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_LO2, 0x2D8);
|
||||
b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_UP2, 0x301);
|
||||
|
||||
if (bus->sprom.boardflags2_lo & 0x100 &&
|
||||
bus->boardinfo.type == 0x8B) {
|
||||
if (sprom->boardflags2_lo & 0x100 &&
|
||||
dev->dev->board_type == 0x8B) {
|
||||
delays1[0] = 0x1;
|
||||
delays1[5] = 0x14;
|
||||
}
|
||||
@ -3586,7 +3585,7 @@ static void b43_nphy_set_rx_core_state(struct b43_wldev *dev, u8 mask)
|
||||
*/
|
||||
int b43_phy_initn(struct b43_wldev *dev)
|
||||
{
|
||||
struct ssb_bus *bus = dev->sdev->bus;
|
||||
struct ssb_sprom *sprom = dev->dev->bus_sprom;
|
||||
struct b43_phy *phy = &dev->phy;
|
||||
struct b43_phy_n *nphy = phy->n;
|
||||
u8 tx_pwr_state;
|
||||
@ -3599,7 +3598,7 @@ int b43_phy_initn(struct b43_wldev *dev)
|
||||
bool do_cal = false;
|
||||
|
||||
if ((dev->phy.rev >= 3) &&
|
||||
(bus->sprom.boardflags_lo & B43_BFL_EXTLNA) &&
|
||||
(sprom->boardflags_lo & B43_BFL_EXTLNA) &&
|
||||
(b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)) {
|
||||
chipco_set32(&dev->sdev->bus->chipco, SSB_CHIPCO_CHIPCTL, 0x40);
|
||||
}
|
||||
@ -3639,9 +3638,9 @@ int b43_phy_initn(struct b43_wldev *dev)
|
||||
b43_phy_write(dev, B43_NPHY_AFESEQ_TX2RX_PUD_20M, 0x20);
|
||||
b43_phy_write(dev, B43_NPHY_AFESEQ_TX2RX_PUD_40M, 0x20);
|
||||
|
||||
if (bus->sprom.boardflags2_lo & 0x100 ||
|
||||
(bus->boardinfo.vendor == PCI_VENDOR_ID_APPLE &&
|
||||
bus->boardinfo.type == 0x8B))
|
||||
if (sprom->boardflags2_lo & 0x100 ||
|
||||
(dev->dev->board_vendor == PCI_VENDOR_ID_APPLE &&
|
||||
dev->dev->board_type == 0x8B))
|
||||
b43_phy_write(dev, B43_NPHY_TXREALFD, 0xA0);
|
||||
else
|
||||
b43_phy_write(dev, B43_NPHY_TXREALFD, 0xB8);
|
||||
|
@ -111,7 +111,7 @@ static u16 index_to_pioqueue_base(struct b43_wldev *dev,
|
||||
B43_MMIO_PIO11_BASE5,
|
||||
};
|
||||
|
||||
if (dev->sdev->id.revision >= 11) {
|
||||
if (dev->dev->core_rev >= 11) {
|
||||
B43_WARN_ON(index >= ARRAY_SIZE(bases_rev11));
|
||||
return bases_rev11[index];
|
||||
}
|
||||
@ -121,14 +121,14 @@ static u16 index_to_pioqueue_base(struct b43_wldev *dev,
|
||||
|
||||
static u16 pio_txqueue_offset(struct b43_wldev *dev)
|
||||
{
|
||||
if (dev->sdev->id.revision >= 11)
|
||||
if (dev->dev->core_rev >= 11)
|
||||
return 0x18;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static u16 pio_rxqueue_offset(struct b43_wldev *dev)
|
||||
{
|
||||
if (dev->sdev->id.revision >= 11)
|
||||
if (dev->dev->core_rev >= 11)
|
||||
return 0x38;
|
||||
return 8;
|
||||
}
|
||||
@ -144,7 +144,7 @@ static struct b43_pio_txqueue *b43_setup_pioqueue_tx(struct b43_wldev *dev,
|
||||
if (!q)
|
||||
return NULL;
|
||||
q->dev = dev;
|
||||
q->rev = dev->sdev->id.revision;
|
||||
q->rev = dev->dev->core_rev;
|
||||
q->mmio_base = index_to_pioqueue_base(dev, index) +
|
||||
pio_txqueue_offset(dev);
|
||||
q->index = index;
|
||||
@ -178,7 +178,7 @@ static struct b43_pio_rxqueue *b43_setup_pioqueue_rx(struct b43_wldev *dev,
|
||||
if (!q)
|
||||
return NULL;
|
||||
q->dev = dev;
|
||||
q->rev = dev->sdev->id.revision;
|
||||
q->rev = dev->dev->core_rev;
|
||||
q->mmio_base = index_to_pioqueue_base(dev, index) +
|
||||
pio_rxqueue_offset(dev);
|
||||
|
||||
|
@ -37,17 +37,16 @@ void b43_rfkill_poll(struct ieee80211_hw *hw)
|
||||
{
|
||||
struct b43_wl *wl = hw_to_b43_wl(hw);
|
||||
struct b43_wldev *dev = wl->current_dev;
|
||||
struct ssb_bus *bus = dev->sdev->bus;
|
||||
bool enabled;
|
||||
bool brought_up = false;
|
||||
|
||||
mutex_lock(&wl->mutex);
|
||||
if (unlikely(b43_status(dev) < B43_STAT_INITIALIZED)) {
|
||||
if (ssb_bus_powerup(bus, 0)) {
|
||||
if (b43_bus_powerup(dev, 0)) {
|
||||
mutex_unlock(&wl->mutex);
|
||||
return;
|
||||
}
|
||||
ssb_device_enable(dev->sdev, 0);
|
||||
b43_device_enable(dev, 0);
|
||||
brought_up = true;
|
||||
}
|
||||
|
||||
@ -63,8 +62,8 @@ void b43_rfkill_poll(struct ieee80211_hw *hw)
|
||||
}
|
||||
|
||||
if (brought_up) {
|
||||
ssb_device_disable(dev->sdev, 0);
|
||||
ssb_bus_may_powerdown(bus);
|
||||
b43_device_disable(dev, 0);
|
||||
b43_bus_may_powerdown(dev);
|
||||
}
|
||||
|
||||
mutex_unlock(&wl->mutex);
|
||||
|
@ -66,7 +66,7 @@ static void b43_sdio_interrupt_dispatcher(struct sdio_func *func)
|
||||
int b43_sdio_request_irq(struct b43_wldev *dev,
|
||||
void (*handler)(struct b43_wldev *dev))
|
||||
{
|
||||
struct ssb_bus *bus = dev->sdev->bus;
|
||||
struct ssb_bus *bus = dev->dev->sdev->bus;
|
||||
struct sdio_func *func = bus->host_sdio;
|
||||
struct b43_sdio *sdio = sdio_get_drvdata(func);
|
||||
int err;
|
||||
@ -82,7 +82,7 @@ int b43_sdio_request_irq(struct b43_wldev *dev,
|
||||
|
||||
void b43_sdio_free_irq(struct b43_wldev *dev)
|
||||
{
|
||||
struct ssb_bus *bus = dev->sdev->bus;
|
||||
struct ssb_bus *bus = dev->dev->sdev->bus;
|
||||
struct sdio_func *func = bus->host_sdio;
|
||||
struct b43_sdio *sdio = sdio_get_drvdata(func);
|
||||
|
||||
|
@ -140,7 +140,7 @@ static DEVICE_ATTR(interference, 0644,
|
||||
|
||||
int b43_sysfs_register(struct b43_wldev *wldev)
|
||||
{
|
||||
struct device *dev = wldev->sdev->dev;
|
||||
struct device *dev = wldev->dev->dev;
|
||||
|
||||
B43_WARN_ON(b43_status(wldev) != B43_STAT_INITIALIZED);
|
||||
|
||||
@ -149,7 +149,7 @@ int b43_sysfs_register(struct b43_wldev *wldev)
|
||||
|
||||
void b43_sysfs_unregister(struct b43_wldev *wldev)
|
||||
{
|
||||
struct device *dev = wldev->sdev->dev;
|
||||
struct device *dev = wldev->dev->dev;
|
||||
|
||||
device_remove_file(dev, &dev_attr_interference);
|
||||
}
|
||||
|
@ -2304,7 +2304,6 @@ void lpphy_rev0_1_table_init(struct b43_wldev *dev)
|
||||
|
||||
void lpphy_rev2plus_table_init(struct b43_wldev *dev)
|
||||
{
|
||||
struct ssb_bus *bus = dev->sdev->bus;
|
||||
int i;
|
||||
|
||||
B43_WARN_ON(dev->phy.rev < 2);
|
||||
@ -2341,7 +2340,7 @@ void lpphy_rev2plus_table_init(struct b43_wldev *dev)
|
||||
b43_lptab_write_bulk(dev, B43_LPTAB32(10, 0),
|
||||
ARRAY_SIZE(lpphy_papd_mult_table), lpphy_papd_mult_table);
|
||||
|
||||
if ((bus->chip_id == 0x4325) && (bus->chip_rev == 0)) {
|
||||
if ((dev->dev->chip_id == 0x4325) && (dev->dev->chip_rev == 0)) {
|
||||
b43_lptab_write_bulk(dev, B43_LPTAB32(13, 0),
|
||||
ARRAY_SIZE(lpphy_a0_gain_idx_table), lpphy_a0_gain_idx_table);
|
||||
b43_lptab_write_bulk(dev, B43_LPTAB16(14, 0),
|
||||
@ -2416,12 +2415,12 @@ void lpphy_write_gain_table_bulk(struct b43_wldev *dev, int offset, int count,
|
||||
|
||||
void lpphy_init_tx_gain_table(struct b43_wldev *dev)
|
||||
{
|
||||
struct ssb_bus *bus = dev->sdev->bus;
|
||||
struct ssb_sprom *sprom = dev->dev->bus_sprom;
|
||||
|
||||
switch (dev->phy.rev) {
|
||||
case 0:
|
||||
if ((bus->sprom.boardflags_hi & B43_BFH_NOPA) ||
|
||||
(bus->sprom.boardflags_lo & B43_BFL_HGPA))
|
||||
if ((sprom->boardflags_hi & B43_BFH_NOPA) ||
|
||||
(sprom->boardflags_lo & B43_BFL_HGPA))
|
||||
lpphy_write_gain_table_bulk(dev, 0, 128,
|
||||
lpphy_rev0_nopa_tx_gain_table);
|
||||
else if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)
|
||||
@ -2432,8 +2431,8 @@ void lpphy_init_tx_gain_table(struct b43_wldev *dev)
|
||||
lpphy_rev0_5ghz_tx_gain_table);
|
||||
break;
|
||||
case 1:
|
||||
if ((bus->sprom.boardflags_hi & B43_BFH_NOPA) ||
|
||||
(bus->sprom.boardflags_lo & B43_BFL_HGPA))
|
||||
if ((sprom->boardflags_hi & B43_BFH_NOPA) ||
|
||||
(sprom->boardflags_lo & B43_BFL_HGPA))
|
||||
lpphy_write_gain_table_bulk(dev, 0, 128,
|
||||
lpphy_rev1_nopa_tx_gain_table);
|
||||
else if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)
|
||||
@ -2444,7 +2443,7 @@ void lpphy_init_tx_gain_table(struct b43_wldev *dev)
|
||||
lpphy_rev1_5ghz_tx_gain_table);
|
||||
break;
|
||||
default:
|
||||
if (bus->sprom.boardflags_hi & B43_BFH_NOPA)
|
||||
if (sprom->boardflags_hi & B43_BFH_NOPA)
|
||||
lpphy_write_gain_table_bulk(dev, 0, 128,
|
||||
lpphy_rev2_nopa_tx_gain_table);
|
||||
else if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)
|
||||
|
@ -458,17 +458,15 @@ static void b43_wa_rssi_adc(struct b43_wldev *dev)
|
||||
|
||||
static void b43_wa_boards_a(struct b43_wldev *dev)
|
||||
{
|
||||
struct ssb_bus *bus = dev->sdev->bus;
|
||||
|
||||
if (bus->boardinfo.vendor == SSB_BOARDVENDOR_BCM &&
|
||||
bus->boardinfo.type == SSB_BOARD_BU4306 &&
|
||||
bus->boardinfo.rev < 0x30) {
|
||||
if (dev->dev->board_vendor == SSB_BOARDVENDOR_BCM &&
|
||||
dev->dev->board_type == SSB_BOARD_BU4306 &&
|
||||
dev->dev->board_rev < 0x30) {
|
||||
b43_phy_write(dev, 0x0010, 0xE000);
|
||||
b43_phy_write(dev, 0x0013, 0x0140);
|
||||
b43_phy_write(dev, 0x0014, 0x0280);
|
||||
} else {
|
||||
if (bus->boardinfo.type == SSB_BOARD_MP4318 &&
|
||||
bus->boardinfo.rev < 0x20) {
|
||||
if (dev->dev->board_type == SSB_BOARD_MP4318 &&
|
||||
dev->dev->board_rev < 0x20) {
|
||||
b43_phy_write(dev, 0x0013, 0x0210);
|
||||
b43_phy_write(dev, 0x0014, 0x0840);
|
||||
} else {
|
||||
@ -486,19 +484,19 @@ static void b43_wa_boards_a(struct b43_wldev *dev)
|
||||
|
||||
static void b43_wa_boards_g(struct b43_wldev *dev)
|
||||
{
|
||||
struct ssb_bus *bus = dev->sdev->bus;
|
||||
struct ssb_sprom *sprom = dev->dev->bus_sprom;
|
||||
struct b43_phy *phy = &dev->phy;
|
||||
|
||||
if (bus->boardinfo.vendor != SSB_BOARDVENDOR_BCM ||
|
||||
bus->boardinfo.type != SSB_BOARD_BU4306 ||
|
||||
bus->boardinfo.rev != 0x17) {
|
||||
if (dev->dev->board_vendor != SSB_BOARDVENDOR_BCM ||
|
||||
dev->dev->board_type != SSB_BOARD_BU4306 ||
|
||||
dev->dev->board_rev != 0x17) {
|
||||
if (phy->rev < 2) {
|
||||
b43_ofdmtab_write16(dev, B43_OFDMTAB_GAINX_R1, 1, 0x0002);
|
||||
b43_ofdmtab_write16(dev, B43_OFDMTAB_GAINX_R1, 2, 0x0001);
|
||||
} else {
|
||||
b43_ofdmtab_write16(dev, B43_OFDMTAB_GAINX, 1, 0x0002);
|
||||
b43_ofdmtab_write16(dev, B43_OFDMTAB_GAINX, 2, 0x0001);
|
||||
if ((bus->sprom.boardflags_lo & B43_BFL_EXTLNA) &&
|
||||
if ((sprom->boardflags_lo & B43_BFL_EXTLNA) &&
|
||||
(phy->rev >= 7)) {
|
||||
b43_phy_mask(dev, B43_PHY_EXTG(0x11), 0xF7FF);
|
||||
b43_ofdmtab_write16(dev, B43_OFDMTAB_GAINX, 0x0020, 0x0001);
|
||||
@ -510,7 +508,7 @@ static void b43_wa_boards_g(struct b43_wldev *dev)
|
||||
}
|
||||
}
|
||||
}
|
||||
if (bus->sprom.boardflags_lo & B43_BFL_FEM) {
|
||||
if (sprom->boardflags_lo & B43_BFL_FEM) {
|
||||
b43_phy_write(dev, B43_PHY_GTABCTL, 0x3120);
|
||||
b43_phy_write(dev, B43_PHY_GTABDATA, 0xC480);
|
||||
}
|
||||
|
@ -547,7 +547,7 @@ static s8 b43_rssi_postprocess(struct b43_wldev *dev,
|
||||
else
|
||||
tmp -= 3;
|
||||
} else {
|
||||
if (dev->sdev->bus->sprom.
|
||||
if (dev->dev->bus_sprom->
|
||||
boardflags_lo & B43_BFL_RSSI) {
|
||||
if (in_rssi > 63)
|
||||
in_rssi = 63;
|
||||
|
@ -817,14 +817,13 @@ static void dmacontroller_cleanup(struct b43legacy_dmaring *ring)
|
||||
|
||||
static void free_all_descbuffers(struct b43legacy_dmaring *ring)
|
||||
{
|
||||
struct b43legacy_dmadesc_generic *desc;
|
||||
struct b43legacy_dmadesc_meta *meta;
|
||||
int i;
|
||||
|
||||
if (!ring->used_slots)
|
||||
return;
|
||||
for (i = 0; i < ring->nr_slots; i++) {
|
||||
desc = ring->ops->idx2desc(ring, i, &meta);
|
||||
ring->ops->idx2desc(ring, i, &meta);
|
||||
|
||||
if (!meta->skb) {
|
||||
B43legacy_WARN_ON(!ring->tx);
|
||||
@ -1371,10 +1370,8 @@ int b43legacy_dma_tx(struct b43legacy_wldev *dev,
|
||||
struct sk_buff *skb)
|
||||
{
|
||||
struct b43legacy_dmaring *ring;
|
||||
struct ieee80211_hdr *hdr;
|
||||
int err = 0;
|
||||
unsigned long flags;
|
||||
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
|
||||
|
||||
ring = priority_to_txring(dev, skb_get_queue_mapping(skb));
|
||||
spin_lock_irqsave(&ring->lock, flags);
|
||||
@ -1401,8 +1398,6 @@ int b43legacy_dma_tx(struct b43legacy_wldev *dev,
|
||||
|
||||
/* dma_tx_fragment might reallocate the skb, so invalidate pointers pointing
|
||||
* into the skb data or cb now. */
|
||||
hdr = NULL;
|
||||
info = NULL;
|
||||
err = dma_tx_fragment(ring, &skb);
|
||||
if (unlikely(err == -ENOKEY)) {
|
||||
/* Drop this packet, as we don't have the encryption key
|
||||
@ -1435,7 +1430,6 @@ void b43legacy_dma_handle_txstatus(struct b43legacy_wldev *dev,
|
||||
{
|
||||
const struct b43legacy_dma_ops *ops;
|
||||
struct b43legacy_dmaring *ring;
|
||||
struct b43legacy_dmadesc_generic *desc;
|
||||
struct b43legacy_dmadesc_meta *meta;
|
||||
int retry_limit;
|
||||
int slot;
|
||||
@ -1450,7 +1444,7 @@ void b43legacy_dma_handle_txstatus(struct b43legacy_wldev *dev,
|
||||
ops = ring->ops;
|
||||
while (1) {
|
||||
B43legacy_WARN_ON(!(slot >= 0 && slot < ring->nr_slots));
|
||||
desc = ops->idx2desc(ring, slot, &meta);
|
||||
ops->idx2desc(ring, slot, &meta);
|
||||
|
||||
if (meta->skb)
|
||||
unmap_descbuffer(ring, meta->dmaaddr,
|
||||
|
@ -1564,10 +1564,10 @@ static int b43legacy_request_firmware(struct b43legacy_wldev *dev)
|
||||
struct b43legacy_firmware *fw = &dev->fw;
|
||||
const u8 rev = dev->dev->id.revision;
|
||||
const char *filename;
|
||||
u32 tmshigh;
|
||||
int err;
|
||||
|
||||
tmshigh = ssb_read32(dev->dev, SSB_TMSHIGH);
|
||||
/* do dummy read */
|
||||
ssb_read32(dev->dev, SSB_TMSHIGH);
|
||||
if (!fw->ucode) {
|
||||
if (rev == 2)
|
||||
filename = "ucode2";
|
||||
@ -2634,11 +2634,9 @@ static int b43legacy_op_dev_config(struct ieee80211_hw *hw,
|
||||
unsigned long flags;
|
||||
unsigned int new_phymode = 0xFFFF;
|
||||
int antenna_tx;
|
||||
int antenna_rx;
|
||||
int err = 0;
|
||||
|
||||
antenna_tx = B43legacy_ANTENNA_DEFAULT;
|
||||
antenna_rx = B43legacy_ANTENNA_DEFAULT;
|
||||
|
||||
mutex_lock(&wl->mutex);
|
||||
dev = wl->current_dev;
|
||||
@ -2775,14 +2773,12 @@ static void b43legacy_op_bss_info_changed(struct ieee80211_hw *hw,
|
||||
{
|
||||
struct b43legacy_wl *wl = hw_to_b43legacy_wl(hw);
|
||||
struct b43legacy_wldev *dev;
|
||||
struct b43legacy_phy *phy;
|
||||
unsigned long flags;
|
||||
|
||||
mutex_lock(&wl->mutex);
|
||||
B43legacy_WARN_ON(wl->vif != vif);
|
||||
|
||||
dev = wl->current_dev;
|
||||
phy = &dev->phy;
|
||||
|
||||
/* Disable IRQs while reconfiguring the device.
|
||||
* This makes it possible to drop the spinlock throughout
|
||||
|
@ -321,11 +321,9 @@ static int generate_txhdr_fw3(struct b43legacy_wldev *dev,
|
||||
struct ieee80211_hdr *hdr;
|
||||
int rts_rate;
|
||||
int rts_rate_fb;
|
||||
int rts_rate_ofdm;
|
||||
int rts_rate_fb_ofdm;
|
||||
|
||||
rts_rate = ieee80211_get_rts_cts_rate(dev->wl->hw, info)->hw_value;
|
||||
rts_rate_ofdm = b43legacy_is_ofdm_rate(rts_rate);
|
||||
rts_rate_fb = b43legacy_calc_fallback_rate(rts_rate);
|
||||
rts_rate_fb_ofdm = b43legacy_is_ofdm_rate(rts_rate_fb);
|
||||
if (rts_rate_fb_ofdm)
|
||||
|
@ -2275,6 +2275,9 @@ iwl4965_rs_get_rate(void *priv_r, struct ieee80211_sta *sta, void *priv_sta,
|
||||
if (rate_control_send_low(sta, priv_sta, txrc))
|
||||
return;
|
||||
|
||||
if (!lq_sta)
|
||||
return;
|
||||
|
||||
rate_idx = lq_sta->last_txrate_idx;
|
||||
|
||||
if (lq_sta->last_rate_n_flags & RATE_MCS_HT_MSK) {
|
||||
|
@ -496,7 +496,7 @@ static s32 iwl4965_get_tx_atten_grp(u16 channel)
|
||||
channel <= CALIB_IWL_TX_ATTEN_GR4_LCH)
|
||||
return CALIB_CH_GROUP_4;
|
||||
|
||||
return -1;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static u32 iwl4965_get_sub_band(const struct iwl_priv *priv, u32 channel)
|
||||
@ -915,7 +915,7 @@ static int iwl4965_fill_txpower_tbl(struct iwl_priv *priv, u8 band, u16 channel,
|
||||
if (txatten_grp < 0) {
|
||||
IWL_ERR(priv, "Can't find txatten group for channel %d.\n",
|
||||
channel);
|
||||
return -EINVAL;
|
||||
return txatten_grp;
|
||||
}
|
||||
|
||||
IWL_DEBUG_TXPOWER(priv, "channel %d belongs to txatten group %d\n",
|
||||
@ -1185,8 +1185,6 @@ static int iwl4965_send_rxon_assoc(struct iwl_priv *priv,
|
||||
|
||||
ret = iwl_legacy_send_cmd_pdu_async(priv, REPLY_RXON_ASSOC,
|
||||
sizeof(rxon_assoc), &rxon_assoc, NULL);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -1237,7 +1235,7 @@ static int iwl4965_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *c
|
||||
|
||||
memcpy(active_rxon, &ctx->staging, sizeof(*active_rxon));
|
||||
iwl_legacy_print_rx_config_cmd(priv, ctx);
|
||||
return 0;
|
||||
goto set_tx_power;
|
||||
}
|
||||
|
||||
/* If we are currently associated and the new config requires
|
||||
@ -1317,6 +1315,7 @@ static int iwl4965_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *c
|
||||
|
||||
iwl4965_init_sensitivity(priv);
|
||||
|
||||
set_tx_power:
|
||||
/* If we issue a new RXON command which required a tune then we must
|
||||
* send a new TXPOWER command or we won't be able to Tx any frames */
|
||||
ret = iwl_legacy_set_tx_power(priv, priv->tx_power_next, true);
|
||||
|
@ -316,7 +316,6 @@ static void iwl_legacy_init_band_reference(const struct iwl_priv *priv,
|
||||
break;
|
||||
default:
|
||||
BUG();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -174,7 +174,6 @@ static struct iwl_lib_ops iwl1000_lib = {
|
||||
.rx_handler_setup = iwlagn_rx_handler_setup,
|
||||
.setup_deferred_work = iwlagn_setup_deferred_work,
|
||||
.is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr,
|
||||
.send_tx_power = iwlagn_send_tx_power,
|
||||
.update_chain_flags = iwl_update_chain_flags,
|
||||
.apm_ops = {
|
||||
.init = iwl_apm_init,
|
||||
@ -223,6 +222,7 @@ static struct iwl_base_params iwl1000_base_params = {
|
||||
static struct iwl_ht_params iwl1000_ht_params = {
|
||||
.ht_greenfield_support = true,
|
||||
.use_rts_for_aggregation = true, /* use rts/cts protection */
|
||||
.smps_mode = IEEE80211_SMPS_STATIC,
|
||||
};
|
||||
|
||||
#define IWL_DEVICE_1000 \
|
||||
|
@ -177,88 +177,13 @@ static int iwl2000_hw_set_hw_params(struct iwl_priv *priv)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int iwl2030_hw_channel_switch(struct iwl_priv *priv,
|
||||
struct ieee80211_channel_switch *ch_switch)
|
||||
{
|
||||
/*
|
||||
* MULTI-FIXME
|
||||
* See iwl_mac_channel_switch.
|
||||
*/
|
||||
struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
|
||||
struct iwl6000_channel_switch_cmd cmd;
|
||||
const struct iwl_channel_info *ch_info;
|
||||
u32 switch_time_in_usec, ucode_switch_time;
|
||||
u16 ch;
|
||||
u32 tsf_low;
|
||||
u8 switch_count;
|
||||
u16 beacon_interval = le16_to_cpu(ctx->timing.beacon_interval);
|
||||
struct ieee80211_vif *vif = ctx->vif;
|
||||
struct iwl_host_cmd hcmd = {
|
||||
.id = REPLY_CHANNEL_SWITCH,
|
||||
.len = { sizeof(cmd), },
|
||||
.flags = CMD_SYNC,
|
||||
.data = { &cmd, },
|
||||
};
|
||||
|
||||
cmd.band = priv->band == IEEE80211_BAND_2GHZ;
|
||||
ch = ch_switch->channel->hw_value;
|
||||
IWL_DEBUG_11H(priv, "channel switch from %u to %u\n",
|
||||
ctx->active.channel, ch);
|
||||
cmd.channel = cpu_to_le16(ch);
|
||||
cmd.rxon_flags = ctx->staging.flags;
|
||||
cmd.rxon_filter_flags = ctx->staging.filter_flags;
|
||||
switch_count = ch_switch->count;
|
||||
tsf_low = ch_switch->timestamp & 0x0ffffffff;
|
||||
/*
|
||||
* calculate the ucode channel switch time
|
||||
* adding TSF as one of the factor for when to switch
|
||||
*/
|
||||
if ((priv->ucode_beacon_time > tsf_low) && beacon_interval) {
|
||||
if (switch_count > ((priv->ucode_beacon_time - tsf_low) /
|
||||
beacon_interval)) {
|
||||
switch_count -= (priv->ucode_beacon_time -
|
||||
tsf_low) / beacon_interval;
|
||||
} else
|
||||
switch_count = 0;
|
||||
}
|
||||
if (switch_count <= 1)
|
||||
cmd.switch_time = cpu_to_le32(priv->ucode_beacon_time);
|
||||
else {
|
||||
switch_time_in_usec =
|
||||
vif->bss_conf.beacon_int * switch_count * TIME_UNIT;
|
||||
ucode_switch_time = iwl_usecs_to_beacons(priv,
|
||||
switch_time_in_usec,
|
||||
beacon_interval);
|
||||
cmd.switch_time = iwl_add_beacon_time(priv,
|
||||
priv->ucode_beacon_time,
|
||||
ucode_switch_time,
|
||||
beacon_interval);
|
||||
}
|
||||
IWL_DEBUG_11H(priv, "uCode time for the switch is 0x%x\n",
|
||||
cmd.switch_time);
|
||||
ch_info = iwl_get_channel_info(priv, priv->band, ch);
|
||||
if (ch_info)
|
||||
cmd.expect_beacon = is_channel_radar(ch_info);
|
||||
else {
|
||||
IWL_ERR(priv, "invalid channel switch from %u to %u\n",
|
||||
ctx->active.channel, ch);
|
||||
return -EFAULT;
|
||||
}
|
||||
priv->switch_rxon.channel = cmd.channel;
|
||||
priv->switch_rxon.switch_in_progress = true;
|
||||
|
||||
return iwl_send_cmd_sync(priv, &hcmd);
|
||||
}
|
||||
|
||||
static struct iwl_lib_ops iwl2000_lib = {
|
||||
.set_hw_params = iwl2000_hw_set_hw_params,
|
||||
.rx_handler_setup = iwlagn_rx_handler_setup,
|
||||
.setup_deferred_work = iwlagn_bt_setup_deferred_work,
|
||||
.cancel_deferred_work = iwlagn_bt_cancel_deferred_work,
|
||||
.is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr,
|
||||
.send_tx_power = iwlagn_send_tx_power,
|
||||
.update_chain_flags = iwl_update_chain_flags,
|
||||
.set_channel_switch = iwl2030_hw_channel_switch,
|
||||
.apm_ops = {
|
||||
.init = iwl_apm_init,
|
||||
.config = iwl2000_nic_config,
|
||||
|
@ -331,8 +331,6 @@ static int iwl5000_hw_channel_switch(struct iwl_priv *priv,
|
||||
ctx->active.channel, ch);
|
||||
return -EFAULT;
|
||||
}
|
||||
priv->switch_rxon.channel = cmd.channel;
|
||||
priv->switch_rxon.switch_in_progress = true;
|
||||
|
||||
return iwl_send_cmd_sync(priv, &hcmd);
|
||||
}
|
||||
@ -342,7 +340,6 @@ static struct iwl_lib_ops iwl5000_lib = {
|
||||
.rx_handler_setup = iwlagn_rx_handler_setup,
|
||||
.setup_deferred_work = iwlagn_setup_deferred_work,
|
||||
.is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr,
|
||||
.send_tx_power = iwlagn_send_tx_power,
|
||||
.update_chain_flags = iwl_update_chain_flags,
|
||||
.set_channel_switch = iwl5000_hw_channel_switch,
|
||||
.apm_ops = {
|
||||
@ -373,7 +370,6 @@ static struct iwl_lib_ops iwl5150_lib = {
|
||||
.rx_handler_setup = iwlagn_rx_handler_setup,
|
||||
.setup_deferred_work = iwlagn_setup_deferred_work,
|
||||
.is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr,
|
||||
.send_tx_power = iwlagn_send_tx_power,
|
||||
.update_chain_flags = iwl_update_chain_flags,
|
||||
.set_channel_switch = iwl5000_hw_channel_switch,
|
||||
.apm_ops = {
|
||||
@ -425,7 +421,6 @@ static struct iwl_base_params iwl5000_base_params = {
|
||||
};
|
||||
static struct iwl_ht_params iwl5000_ht_params = {
|
||||
.ht_greenfield_support = true,
|
||||
.use_rts_for_aggregation = true, /* use rts/cts protection */
|
||||
};
|
||||
|
||||
#define IWL_DEVICE_5000 \
|
||||
|
@ -270,8 +270,6 @@ static int iwl6000_hw_channel_switch(struct iwl_priv *priv,
|
||||
ctx->active.channel, ch);
|
||||
return -EFAULT;
|
||||
}
|
||||
priv->switch_rxon.channel = cmd.channel;
|
||||
priv->switch_rxon.switch_in_progress = true;
|
||||
|
||||
return iwl_send_cmd_sync(priv, &hcmd);
|
||||
}
|
||||
@ -281,7 +279,6 @@ static struct iwl_lib_ops iwl6000_lib = {
|
||||
.rx_handler_setup = iwlagn_rx_handler_setup,
|
||||
.setup_deferred_work = iwlagn_setup_deferred_work,
|
||||
.is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr,
|
||||
.send_tx_power = iwlagn_send_tx_power,
|
||||
.update_chain_flags = iwl_update_chain_flags,
|
||||
.set_channel_switch = iwl6000_hw_channel_switch,
|
||||
.apm_ops = {
|
||||
@ -314,7 +311,6 @@ static struct iwl_lib_ops iwl6030_lib = {
|
||||
.setup_deferred_work = iwlagn_bt_setup_deferred_work,
|
||||
.cancel_deferred_work = iwlagn_bt_cancel_deferred_work,
|
||||
.is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr,
|
||||
.send_tx_power = iwlagn_send_tx_power,
|
||||
.update_chain_flags = iwl_update_chain_flags,
|
||||
.set_channel_switch = iwl6000_hw_channel_switch,
|
||||
.apm_ops = {
|
||||
|
@ -163,17 +163,9 @@ static void iwlagn_tx_cmd_protection(struct iwl_priv *priv,
|
||||
__le16 fc, __le32 *tx_flags)
|
||||
{
|
||||
if (info->control.rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS ||
|
||||
info->control.rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT) {
|
||||
info->control.rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT ||
|
||||
info->flags & IEEE80211_TX_CTL_AMPDU)
|
||||
*tx_flags |= TX_CMD_FLG_PROT_REQUIRE_MSK;
|
||||
return;
|
||||
}
|
||||
|
||||
if (priv->cfg->ht_params &&
|
||||
priv->cfg->ht_params->use_rts_for_aggregation &&
|
||||
info->flags & IEEE80211_TX_CTL_AMPDU) {
|
||||
*tx_flags |= TX_CMD_FLG_PROT_REQUIRE_MSK;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* Calc max signal level (dBm) among 3 possible receivers */
|
||||
@ -310,7 +302,6 @@ static int iwlagn_set_pan_params(struct iwl_priv *priv)
|
||||
}
|
||||
|
||||
struct iwl_hcmd_ops iwlagn_hcmd = {
|
||||
.commit_rxon = iwlagn_commit_rxon,
|
||||
.set_rxon_chain = iwlagn_set_rxon_chain,
|
||||
.set_tx_ant = iwlagn_send_tx_ant_config,
|
||||
.send_bt_config = iwl_send_bt_config,
|
||||
@ -318,7 +309,6 @@ struct iwl_hcmd_ops iwlagn_hcmd = {
|
||||
};
|
||||
|
||||
struct iwl_hcmd_ops iwlagn_bt_hcmd = {
|
||||
.commit_rxon = iwlagn_commit_rxon,
|
||||
.set_rxon_chain = iwlagn_set_rxon_chain,
|
||||
.set_tx_ant = iwlagn_send_tx_ant_config,
|
||||
.send_bt_config = iwlagn_send_advance_bt_config,
|
||||
@ -332,5 +322,4 @@ struct iwl_hcmd_utils_ops iwlagn_hcmd_utils = {
|
||||
.tx_cmd_protection = iwlagn_tx_cmd_protection,
|
||||
.calc_rssi = iwlagn_calc_rssi,
|
||||
.request_scan = iwlagn_request_scan,
|
||||
.post_scan = iwlagn_post_scan,
|
||||
};
|
||||
|
@ -408,9 +408,9 @@ static void iwlagn_rx_reply_tx(struct iwl_priv *priv,
|
||||
unsigned long flags;
|
||||
|
||||
if ((index >= txq->q.n_bd) || (iwl_queue_used(&txq->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, txq->q.n_bd, txq->q.write_ptr,
|
||||
IWL_ERR(priv, "%s: Read index for DMA queue txq_id (%d) "
|
||||
"index %d is out of range [0-%d] %d %d\n", __func__,
|
||||
txq_id, index, txq->q.n_bd, txq->q.write_ptr,
|
||||
txq->q.read_ptr);
|
||||
return;
|
||||
}
|
||||
@ -1797,6 +1797,7 @@ static void iwlagn_bt_traffic_change_work(struct work_struct *work)
|
||||
priv->cfg->ops->lib->update_chain_flags(priv);
|
||||
|
||||
if (smps_request != -1) {
|
||||
priv->current_ht_config.smps = smps_request;
|
||||
for_each_context(priv, ctx) {
|
||||
if (ctx->vif && ctx->vif->type == NL80211_IFTYPE_STATION)
|
||||
ieee80211_request_smps(ctx->vif, smps_request);
|
||||
|
@ -426,7 +426,7 @@ static int rs_tl_turn_on_agg_for_tid(struct iwl_priv *priv,
|
||||
ieee80211_stop_tx_ba_session(sta, tid);
|
||||
}
|
||||
} else {
|
||||
IWL_ERR(priv, "Aggregation not enabled for tid %d "
|
||||
IWL_DEBUG_HT(priv, "Aggregation not enabled for tid %d "
|
||||
"because load = %u\n", tid, load);
|
||||
}
|
||||
return ret;
|
||||
|
@ -81,6 +81,21 @@ static int iwlagn_disable_pan(struct iwl_priv *priv,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int iwlagn_disconn_pan(struct iwl_priv *priv,
|
||||
struct iwl_rxon_context *ctx,
|
||||
struct iwl_rxon_cmd *send)
|
||||
{
|
||||
__le32 old_filter = send->filter_flags;
|
||||
int ret;
|
||||
|
||||
send->filter_flags &= ~RXON_FILTER_ASSOC_MSK;
|
||||
ret = iwl_send_cmd_pdu(priv, ctx->rxon_cmd, sizeof(*send), send);
|
||||
|
||||
send->filter_flags = old_filter;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void iwlagn_update_qos(struct iwl_priv *priv,
|
||||
struct iwl_rxon_context *ctx)
|
||||
{
|
||||
@ -163,9 +178,6 @@ static int iwlagn_send_rxon_assoc(struct iwl_priv *priv,
|
||||
|
||||
ret = iwl_send_cmd_pdu_async(priv, ctx->rxon_assoc_cmd,
|
||||
sizeof(rxon_assoc), &rxon_assoc, NULL);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -175,10 +187,21 @@ static int iwlagn_rxon_disconn(struct iwl_priv *priv,
|
||||
int ret;
|
||||
struct iwl_rxon_cmd *active = (void *)&ctx->active;
|
||||
|
||||
if (ctx->ctxid == IWL_RXON_CTX_BSS)
|
||||
if (ctx->ctxid == IWL_RXON_CTX_BSS) {
|
||||
ret = iwlagn_disable_bss(priv, ctx, &ctx->staging);
|
||||
else
|
||||
} else {
|
||||
ret = iwlagn_disable_pan(priv, ctx, &ctx->staging);
|
||||
if (ret)
|
||||
return ret;
|
||||
if (ctx->vif) {
|
||||
ret = iwl_send_rxon_timing(priv, ctx);
|
||||
if (ret) {
|
||||
IWL_ERR(priv, "Failed to send timing (%d)!\n", ret);
|
||||
return ret;
|
||||
}
|
||||
ret = iwlagn_disconn_pan(priv, ctx, &ctx->staging);
|
||||
}
|
||||
}
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
@ -205,10 +228,12 @@ static int iwlagn_rxon_connect(struct iwl_priv *priv,
|
||||
struct iwl_rxon_cmd *active = (void *)&ctx->active;
|
||||
|
||||
/* RXON timing must be before associated RXON */
|
||||
ret = iwl_send_rxon_timing(priv, ctx);
|
||||
if (ret) {
|
||||
IWL_ERR(priv, "Failed to send timing (%d)!\n", ret);
|
||||
return ret;
|
||||
if (ctx->ctxid == IWL_RXON_CTX_BSS) {
|
||||
ret = iwl_send_rxon_timing(priv, ctx);
|
||||
if (ret) {
|
||||
IWL_ERR(priv, "Failed to send timing (%d)!\n", ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
/* QoS info may be cleared by previous un-assoc RXON */
|
||||
iwlagn_update_qos(priv, ctx);
|
||||
@ -263,6 +288,12 @@ static int iwlagn_rxon_connect(struct iwl_priv *priv,
|
||||
IWL_ERR(priv, "Error sending TX power (%d)\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if ((ctx->vif && ctx->vif->type == NL80211_IFTYPE_STATION) &&
|
||||
priv->cfg->ht_params->smps_mode)
|
||||
ieee80211_request_smps(ctx->vif,
|
||||
priv->cfg->ht_params->smps_mode);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -325,6 +356,14 @@ int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* force CTS-to-self frames protection if RTS-CTS is not preferred
|
||||
* one aggregation protection method
|
||||
*/
|
||||
if (!(priv->cfg->ht_params &&
|
||||
priv->cfg->ht_params->use_rts_for_aggregation))
|
||||
ctx->staging.flags |= RXON_FLG_SELF_CTS_EN;
|
||||
|
||||
if ((ctx->vif && ctx->vif->bss_conf.use_short_slot) ||
|
||||
!(ctx->staging.flags & RXON_FLG_BAND_24G_MSK))
|
||||
ctx->staging.flags |= RXON_FLG_SHORT_SLOT_MSK;
|
||||
@ -342,10 +381,10 @@ int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
|
||||
* receive commit_rxon request
|
||||
* abort any previous channel switch if still in process
|
||||
*/
|
||||
if (priv->switch_rxon.switch_in_progress &&
|
||||
(priv->switch_rxon.channel != ctx->staging.channel)) {
|
||||
if (test_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->status) &&
|
||||
(priv->switch_channel != ctx->staging.channel)) {
|
||||
IWL_DEBUG_11H(priv, "abort channel switch on %d\n",
|
||||
le16_to_cpu(priv->switch_rxon.channel));
|
||||
le16_to_cpu(priv->switch_channel));
|
||||
iwl_chswitch_done(priv, false);
|
||||
}
|
||||
|
||||
@ -362,13 +401,16 @@ int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
|
||||
}
|
||||
|
||||
memcpy(active, &ctx->staging, sizeof(*active));
|
||||
return 0;
|
||||
}
|
||||
/*
|
||||
* We do not commit tx power settings while channel changing,
|
||||
* do it now if after settings changed.
|
||||
*/
|
||||
iwl_set_tx_power(priv, priv->tx_power_next, false);
|
||||
|
||||
if (priv->cfg->ops->hcmd->set_pan_params) {
|
||||
ret = priv->cfg->ops->hcmd->set_pan_params(priv);
|
||||
if (ret)
|
||||
return ret;
|
||||
/* make sure we are in the right PS state */
|
||||
iwl_power_update_mode(priv, true);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
iwl_set_rxon_hwcrypto(priv, ctx, !iwlagn_mod_params.sw_crypto);
|
||||
@ -392,6 +434,12 @@ int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (priv->cfg->ops->hcmd->set_pan_params) {
|
||||
ret = priv->cfg->ops->hcmd->set_pan_params(priv);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (new_assoc)
|
||||
return iwlagn_rxon_connect(priv, ctx);
|
||||
|
||||
@ -756,6 +804,13 @@ void iwlagn_post_scan(struct iwl_priv *priv)
|
||||
{
|
||||
struct iwl_rxon_context *ctx;
|
||||
|
||||
/*
|
||||
* We do not commit power settings while scan is pending,
|
||||
* do it now if the settings changed.
|
||||
*/
|
||||
iwl_power_set_mode(priv, &priv->power_data.sleep_cmd_next, false);
|
||||
iwl_set_tx_power(priv, priv->tx_power_next, false);
|
||||
|
||||
/*
|
||||
* Since setting the RXON may have been deferred while
|
||||
* performing the scan, fire one off if needed
|
||||
|
@ -1033,8 +1033,8 @@ int iwlagn_tx_agg_start(struct iwl_priv *priv, struct ieee80211_vif *vif,
|
||||
if (unlikely(tx_fifo < 0))
|
||||
return tx_fifo;
|
||||
|
||||
IWL_WARN(priv, "%s on ra = %pM tid = %d\n",
|
||||
__func__, sta->addr, tid);
|
||||
IWL_DEBUG_HT(priv, "TX AGG request on ra = %pM tid = %d\n",
|
||||
sta->addr, tid);
|
||||
|
||||
sta_id = iwl_sta_id(sta);
|
||||
if (sta_id == IWL_INVALID_STATION) {
|
||||
@ -1236,9 +1236,9 @@ int iwlagn_tx_queue_reclaim(struct iwl_priv *priv, int txq_id, int index)
|
||||
struct ieee80211_hdr *hdr;
|
||||
|
||||
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);
|
||||
IWL_ERR(priv, "%s: Read index for DMA queue txq id (%d), "
|
||||
"index %d is out of range [0-%d] %d %d.\n", __func__,
|
||||
txq_id, index, q->n_bd, q->write_ptr, q->read_ptr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -97,7 +97,7 @@ void iwl_update_chain_flags(struct iwl_priv *priv)
|
||||
for_each_context(priv, ctx) {
|
||||
priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx);
|
||||
if (ctx->active.rx_chain != ctx->staging.rx_chain)
|
||||
iwlcore_commit_rxon(priv, ctx);
|
||||
iwlagn_commit_rxon(priv, ctx);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -274,7 +274,7 @@ static void iwl_bg_bt_full_concurrency(struct work_struct *work)
|
||||
for_each_context(priv, ctx) {
|
||||
if (priv->cfg->ops->hcmd->set_rxon_chain)
|
||||
priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx);
|
||||
iwlcore_commit_rxon(priv, ctx);
|
||||
iwlagn_commit_rxon(priv, ctx);
|
||||
}
|
||||
|
||||
priv->cfg->ops->hcmd->send_bt_config(priv);
|
||||
@ -2056,7 +2056,7 @@ int iwl_alive_start(struct iwl_priv *priv)
|
||||
set_bit(STATUS_READY, &priv->status);
|
||||
|
||||
/* Configure the adapter for unassociated operation */
|
||||
ret = iwlcore_commit_rxon(priv, ctx);
|
||||
ret = iwlagn_commit_rxon(priv, ctx);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
@ -2420,6 +2420,77 @@ unlock:
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
static const struct ieee80211_iface_limit iwlagn_sta_ap_limits[] = {
|
||||
{
|
||||
.max = 1,
|
||||
.types = BIT(NL80211_IFTYPE_STATION),
|
||||
},
|
||||
{
|
||||
.max = 1,
|
||||
.types = BIT(NL80211_IFTYPE_AP),
|
||||
},
|
||||
};
|
||||
|
||||
static const struct ieee80211_iface_limit iwlagn_2sta_limits[] = {
|
||||
{
|
||||
.max = 2,
|
||||
.types = BIT(NL80211_IFTYPE_STATION),
|
||||
},
|
||||
};
|
||||
|
||||
static const struct ieee80211_iface_limit iwlagn_p2p_sta_go_limits[] = {
|
||||
{
|
||||
.max = 1,
|
||||
.types = BIT(NL80211_IFTYPE_STATION),
|
||||
},
|
||||
{
|
||||
.max = 1,
|
||||
.types = BIT(NL80211_IFTYPE_P2P_GO) |
|
||||
BIT(NL80211_IFTYPE_AP),
|
||||
},
|
||||
};
|
||||
|
||||
static const struct ieee80211_iface_limit iwlagn_p2p_2sta_limits[] = {
|
||||
{
|
||||
.max = 2,
|
||||
.types = BIT(NL80211_IFTYPE_STATION),
|
||||
},
|
||||
{
|
||||
.max = 1,
|
||||
.types = BIT(NL80211_IFTYPE_P2P_CLIENT),
|
||||
},
|
||||
};
|
||||
|
||||
static const struct ieee80211_iface_combination
|
||||
iwlagn_iface_combinations_dualmode[] = {
|
||||
{ .num_different_channels = 1,
|
||||
.max_interfaces = 2,
|
||||
.beacon_int_infra_match = true,
|
||||
.limits = iwlagn_sta_ap_limits,
|
||||
.n_limits = ARRAY_SIZE(iwlagn_sta_ap_limits),
|
||||
},
|
||||
{ .num_different_channels = 1,
|
||||
.max_interfaces = 2,
|
||||
.limits = iwlagn_2sta_limits,
|
||||
.n_limits = ARRAY_SIZE(iwlagn_2sta_limits),
|
||||
},
|
||||
};
|
||||
|
||||
static const struct ieee80211_iface_combination
|
||||
iwlagn_iface_combinations_p2p[] = {
|
||||
{ .num_different_channels = 1,
|
||||
.max_interfaces = 2,
|
||||
.beacon_int_infra_match = true,
|
||||
.limits = iwlagn_p2p_sta_go_limits,
|
||||
.n_limits = ARRAY_SIZE(iwlagn_p2p_sta_go_limits),
|
||||
},
|
||||
{ .num_different_channels = 1,
|
||||
.max_interfaces = 2,
|
||||
.limits = iwlagn_p2p_2sta_limits,
|
||||
.n_limits = ARRAY_SIZE(iwlagn_p2p_2sta_limits),
|
||||
},
|
||||
};
|
||||
|
||||
/*
|
||||
* Not a mac80211 entry point function, but it fits in with all the
|
||||
* other mac80211 functions grouped here.
|
||||
@ -2460,6 +2531,18 @@ static int iwl_mac_setup_register(struct iwl_priv *priv,
|
||||
hw->wiphy->interface_modes |= ctx->exclusive_interface_modes;
|
||||
}
|
||||
|
||||
BUILD_BUG_ON(NUM_IWL_RXON_CTX != 2);
|
||||
|
||||
if (hw->wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_CLIENT)) {
|
||||
hw->wiphy->iface_combinations = iwlagn_iface_combinations_p2p;
|
||||
hw->wiphy->n_iface_combinations =
|
||||
ARRAY_SIZE(iwlagn_iface_combinations_p2p);
|
||||
} else if (hw->wiphy->interface_modes & BIT(NL80211_IFTYPE_AP)) {
|
||||
hw->wiphy->iface_combinations = iwlagn_iface_combinations_dualmode;
|
||||
hw->wiphy->n_iface_combinations =
|
||||
ARRAY_SIZE(iwlagn_iface_combinations_dualmode);
|
||||
}
|
||||
|
||||
hw->wiphy->max_remain_on_channel_duration = 1000;
|
||||
|
||||
hw->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY |
|
||||
@ -2711,12 +2794,9 @@ static int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw,
|
||||
ret = 0;
|
||||
if (priv->cfg->ht_params &&
|
||||
priv->cfg->ht_params->use_rts_for_aggregation) {
|
||||
struct iwl_station_priv *sta_priv =
|
||||
(void *) sta->drv_priv;
|
||||
/*
|
||||
* switch off RTS/CTS if it was previously enabled
|
||||
*/
|
||||
|
||||
sta_priv->lq_sta.lq.general_params.flags &=
|
||||
~LINK_QUAL_FLAGS_SET_STA_TLC_RTS_MSK;
|
||||
iwl_send_lq_cmd(priv, iwl_rxon_ctx_from_vif(vif),
|
||||
@ -2764,6 +2844,9 @@ static int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw,
|
||||
|
||||
iwl_send_lq_cmd(priv, iwl_rxon_ctx_from_vif(vif),
|
||||
&sta_priv->lq_sta.lq, CMD_ASYNC, false);
|
||||
|
||||
IWL_INFO(priv, "Tx aggregation enabled on ra = %pM tid = %d\n",
|
||||
sta->addr, tid);
|
||||
ret = 0;
|
||||
break;
|
||||
}
|
||||
@ -2833,7 +2916,6 @@ static void iwlagn_mac_channel_switch(struct ieee80211_hw *hw,
|
||||
*/
|
||||
struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
|
||||
u16 ch;
|
||||
unsigned long flags = 0;
|
||||
|
||||
IWL_DEBUG_MAC80211(priv, "enter\n");
|
||||
|
||||
@ -2843,73 +2925,73 @@ static void iwlagn_mac_channel_switch(struct ieee80211_hw *hw,
|
||||
goto out;
|
||||
|
||||
if (test_bit(STATUS_EXIT_PENDING, &priv->status) ||
|
||||
test_bit(STATUS_SCANNING, &priv->status))
|
||||
test_bit(STATUS_SCANNING, &priv->status) ||
|
||||
test_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->status))
|
||||
goto out;
|
||||
|
||||
if (!iwl_is_associated_ctx(ctx))
|
||||
goto out;
|
||||
|
||||
/* channel switch in progress */
|
||||
if (priv->switch_rxon.switch_in_progress == true)
|
||||
if (!priv->cfg->ops->lib->set_channel_switch)
|
||||
goto out;
|
||||
|
||||
if (priv->cfg->ops->lib->set_channel_switch) {
|
||||
ch = channel->hw_value;
|
||||
if (le16_to_cpu(ctx->active.channel) == ch)
|
||||
goto out;
|
||||
|
||||
ch = channel->hw_value;
|
||||
if (le16_to_cpu(ctx->active.channel) != ch) {
|
||||
ch_info = iwl_get_channel_info(priv,
|
||||
channel->band,
|
||||
ch);
|
||||
if (!is_channel_valid(ch_info)) {
|
||||
IWL_DEBUG_MAC80211(priv, "invalid channel\n");
|
||||
goto out;
|
||||
}
|
||||
spin_lock_irqsave(&priv->lock, flags);
|
||||
|
||||
priv->current_ht_config.smps = conf->smps_mode;
|
||||
|
||||
/* Configure HT40 channels */
|
||||
ctx->ht.enabled = conf_is_ht(conf);
|
||||
if (ctx->ht.enabled) {
|
||||
if (conf_is_ht40_minus(conf)) {
|
||||
ctx->ht.extension_chan_offset =
|
||||
IEEE80211_HT_PARAM_CHA_SEC_BELOW;
|
||||
ctx->ht.is_40mhz = true;
|
||||
} else if (conf_is_ht40_plus(conf)) {
|
||||
ctx->ht.extension_chan_offset =
|
||||
IEEE80211_HT_PARAM_CHA_SEC_ABOVE;
|
||||
ctx->ht.is_40mhz = true;
|
||||
} else {
|
||||
ctx->ht.extension_chan_offset =
|
||||
IEEE80211_HT_PARAM_CHA_SEC_NONE;
|
||||
ctx->ht.is_40mhz = false;
|
||||
}
|
||||
} else
|
||||
ctx->ht.is_40mhz = false;
|
||||
|
||||
if ((le16_to_cpu(ctx->staging.channel) != ch))
|
||||
ctx->staging.flags = 0;
|
||||
|
||||
iwl_set_rxon_channel(priv, channel, ctx);
|
||||
iwl_set_rxon_ht(priv, ht_conf);
|
||||
iwl_set_flags_for_band(priv, ctx, channel->band,
|
||||
ctx->vif);
|
||||
spin_unlock_irqrestore(&priv->lock, flags);
|
||||
|
||||
iwl_set_rate(priv);
|
||||
/*
|
||||
* at this point, staging_rxon has the
|
||||
* configuration for channel switch
|
||||
*/
|
||||
if (priv->cfg->ops->lib->set_channel_switch(priv,
|
||||
ch_switch))
|
||||
priv->switch_rxon.switch_in_progress = false;
|
||||
}
|
||||
ch_info = iwl_get_channel_info(priv, channel->band, ch);
|
||||
if (!is_channel_valid(ch_info)) {
|
||||
IWL_DEBUG_MAC80211(priv, "invalid channel\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
spin_lock_irq(&priv->lock);
|
||||
|
||||
priv->current_ht_config.smps = conf->smps_mode;
|
||||
|
||||
/* Configure HT40 channels */
|
||||
ctx->ht.enabled = conf_is_ht(conf);
|
||||
if (ctx->ht.enabled) {
|
||||
if (conf_is_ht40_minus(conf)) {
|
||||
ctx->ht.extension_chan_offset =
|
||||
IEEE80211_HT_PARAM_CHA_SEC_BELOW;
|
||||
ctx->ht.is_40mhz = true;
|
||||
} else if (conf_is_ht40_plus(conf)) {
|
||||
ctx->ht.extension_chan_offset =
|
||||
IEEE80211_HT_PARAM_CHA_SEC_ABOVE;
|
||||
ctx->ht.is_40mhz = true;
|
||||
} else {
|
||||
ctx->ht.extension_chan_offset =
|
||||
IEEE80211_HT_PARAM_CHA_SEC_NONE;
|
||||
ctx->ht.is_40mhz = false;
|
||||
}
|
||||
} else
|
||||
ctx->ht.is_40mhz = false;
|
||||
|
||||
if ((le16_to_cpu(ctx->staging.channel) != ch))
|
||||
ctx->staging.flags = 0;
|
||||
|
||||
iwl_set_rxon_channel(priv, channel, ctx);
|
||||
iwl_set_rxon_ht(priv, ht_conf);
|
||||
iwl_set_flags_for_band(priv, ctx, channel->band, ctx->vif);
|
||||
|
||||
spin_unlock_irq(&priv->lock);
|
||||
|
||||
iwl_set_rate(priv);
|
||||
/*
|
||||
* at this point, staging_rxon has the
|
||||
* configuration for channel switch
|
||||
*/
|
||||
set_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->status);
|
||||
priv->switch_channel = cpu_to_le16(ch);
|
||||
if (priv->cfg->ops->lib->set_channel_switch(priv, ch_switch)) {
|
||||
clear_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->status);
|
||||
priv->switch_channel = 0;
|
||||
ieee80211_chswitch_done(ctx->vif, false);
|
||||
}
|
||||
|
||||
out:
|
||||
mutex_unlock(&priv->mutex);
|
||||
if (!priv->switch_rxon.switch_in_progress)
|
||||
ieee80211_chswitch_done(ctx->vif, false);
|
||||
IWL_DEBUG_MAC80211(priv, "leave\n");
|
||||
}
|
||||
|
||||
@ -3018,7 +3100,7 @@ static void iwlagn_disable_roc(struct iwl_priv *priv)
|
||||
|
||||
priv->_agn.hw_roc_channel = NULL;
|
||||
|
||||
iwlcore_commit_rxon(priv, ctx);
|
||||
iwlagn_commit_rxon(priv, ctx);
|
||||
|
||||
ctx->is_active = false;
|
||||
}
|
||||
@ -3061,7 +3143,7 @@ static int iwl_mac_remain_on_channel(struct ieee80211_hw *hw,
|
||||
priv->_agn.hw_roc_channel = channel;
|
||||
priv->_agn.hw_roc_chantype = channel_type;
|
||||
priv->_agn.hw_roc_duration = DIV_ROUND_UP(duration * 1000, 1024);
|
||||
iwlcore_commit_rxon(priv, &priv->contexts[IWL_RXON_CTX_PAN]);
|
||||
iwlagn_commit_rxon(priv, &priv->contexts[IWL_RXON_CTX_PAN]);
|
||||
queue_delayed_work(priv->workqueue, &priv->_agn.hw_roc_work,
|
||||
msecs_to_jiffies(duration + 20));
|
||||
|
||||
@ -3618,8 +3700,8 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||
destroy_workqueue(priv->workqueue);
|
||||
priv->workqueue = NULL;
|
||||
free_irq(priv->pci_dev->irq, priv);
|
||||
iwl_free_isr_ict(priv);
|
||||
out_disable_msi:
|
||||
iwl_free_isr_ict(priv);
|
||||
pci_disable_msi(priv->pci_dev);
|
||||
iwl_uninit_drv(priv);
|
||||
out_free_eeprom:
|
||||
|
@ -843,12 +843,8 @@ void iwl_chswitch_done(struct iwl_priv *priv, bool is_success)
|
||||
if (test_bit(STATUS_EXIT_PENDING, &priv->status))
|
||||
return;
|
||||
|
||||
if (priv->switch_rxon.switch_in_progress) {
|
||||
if (test_and_clear_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->status))
|
||||
ieee80211_chswitch_done(ctx->vif, is_success);
|
||||
mutex_lock(&priv->mutex);
|
||||
priv->switch_rxon.switch_in_progress = false;
|
||||
mutex_unlock(&priv->mutex);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef CONFIG_IWLWIFI_DEBUG
|
||||
@ -1131,9 +1127,6 @@ int iwl_set_tx_power(struct iwl_priv *priv, s8 tx_power, bool force)
|
||||
if (priv->tx_power_user_lmt == tx_power && !force)
|
||||
return 0;
|
||||
|
||||
if (!priv->cfg->ops->lib->send_tx_power)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
if (tx_power < IWLAGN_TX_POWER_TARGET_POWER_MIN) {
|
||||
IWL_WARN(priv,
|
||||
"Requested user TXPOWER %d below lower limit %d.\n",
|
||||
@ -1167,7 +1160,7 @@ int iwl_set_tx_power(struct iwl_priv *priv, s8 tx_power, bool force)
|
||||
prev_tx_power = priv->tx_power_user_lmt;
|
||||
priv->tx_power_user_lmt = tx_power;
|
||||
|
||||
ret = priv->cfg->ops->lib->send_tx_power(priv);
|
||||
ret = iwlagn_send_tx_power(priv);
|
||||
|
||||
/* if fail to set tx_power, restore the orig. tx power */
|
||||
if (ret) {
|
||||
@ -1282,7 +1275,7 @@ static int iwl_set_mode(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
|
||||
if (priv->cfg->ops->hcmd->set_rxon_chain)
|
||||
priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx);
|
||||
|
||||
return iwlcore_commit_rxon(priv, ctx);
|
||||
return iwlagn_commit_rxon(priv, ctx);
|
||||
}
|
||||
|
||||
static int iwl_setup_interface(struct iwl_priv *priv,
|
||||
|
@ -90,7 +90,6 @@ struct iwl_cmd;
|
||||
#define IWL_CMD(x) case x: return #x
|
||||
|
||||
struct iwl_hcmd_ops {
|
||||
int (*commit_rxon)(struct iwl_priv *priv, struct iwl_rxon_context *ctx);
|
||||
void (*set_rxon_chain)(struct iwl_priv *priv,
|
||||
struct iwl_rxon_context *ctx);
|
||||
int (*set_tx_ant)(struct iwl_priv *priv, u8 valid_tx_ant);
|
||||
@ -112,7 +111,6 @@ struct iwl_hcmd_utils_ops {
|
||||
int (*calc_rssi)(struct iwl_priv *priv,
|
||||
struct iwl_rx_phy_res *rx_resp);
|
||||
int (*request_scan)(struct iwl_priv *priv, struct ieee80211_vif *vif);
|
||||
void (*post_scan)(struct iwl_priv *priv);
|
||||
};
|
||||
|
||||
struct iwl_apm_ops {
|
||||
@ -141,7 +139,6 @@ struct iwl_lib_ops {
|
||||
struct iwl_apm_ops apm_ops;
|
||||
|
||||
/* power */
|
||||
int (*send_tx_power) (struct iwl_priv *priv);
|
||||
void (*update_chain_flags)(struct iwl_priv *priv);
|
||||
|
||||
/* eeprom operations (as defined in iwl-eeprom.h) */
|
||||
@ -225,7 +222,7 @@ struct iwl_base_params {
|
||||
* @ampdu_factor: Maximum A-MPDU length factor
|
||||
* @ampdu_density: Minimum A-MPDU spacing
|
||||
* @bt_sco_disable: uCode should not response to BT in SCO/ESCO mode
|
||||
*/
|
||||
*/
|
||||
struct iwl_bt_params {
|
||||
bool advanced_bt_coexist;
|
||||
u8 bt_init_traffic_load;
|
||||
@ -238,10 +235,11 @@ struct iwl_bt_params {
|
||||
};
|
||||
/*
|
||||
* @use_rts_for_aggregation: use rts/cts protection for HT traffic
|
||||
*/
|
||||
*/
|
||||
struct iwl_ht_params {
|
||||
const bool ht_greenfield_support; /* if used set to true */
|
||||
bool use_rts_for_aggregation;
|
||||
enum ieee80211_smps_mode smps_mode;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -560,6 +558,7 @@ void iwlcore_free_geos(struct iwl_priv *priv);
|
||||
#define STATUS_POWER_PMI 16
|
||||
#define STATUS_FW_ERROR 17
|
||||
#define STATUS_DEVICE_ENABLED 18
|
||||
#define STATUS_CHANNEL_SWITCH_PENDING 19
|
||||
|
||||
|
||||
static inline int iwl_is_ready(struct iwl_priv *priv)
|
||||
@ -612,11 +611,7 @@ void iwl_apm_stop(struct iwl_priv *priv);
|
||||
int iwl_apm_init(struct iwl_priv *priv);
|
||||
|
||||
int iwl_send_rxon_timing(struct iwl_priv *priv, struct iwl_rxon_context *ctx);
|
||||
static inline int iwlcore_commit_rxon(struct iwl_priv *priv,
|
||||
struct iwl_rxon_context *ctx)
|
||||
{
|
||||
return priv->cfg->ops->hcmd->commit_rxon(priv, ctx);
|
||||
}
|
||||
|
||||
static inline const struct ieee80211_supported_band *iwl_get_hw_mode(
|
||||
struct iwl_priv *priv, enum ieee80211_band band)
|
||||
{
|
||||
|
@ -982,17 +982,6 @@ struct traffic_stats {
|
||||
#endif
|
||||
};
|
||||
|
||||
/*
|
||||
* iwl_switch_rxon: "channel switch" structure
|
||||
*
|
||||
* @ switch_in_progress: channel switch in progress
|
||||
* @ channel: new channel
|
||||
*/
|
||||
struct iwl_switch_rxon {
|
||||
bool switch_in_progress;
|
||||
__le16 channel;
|
||||
};
|
||||
|
||||
/*
|
||||
* schedule the timer to wake up every UCODE_TRACE_PERIOD milliseconds
|
||||
* to perform continuous uCode event logging operation if enabled
|
||||
@ -1288,7 +1277,7 @@ struct iwl_priv {
|
||||
|
||||
struct iwl_rxon_context contexts[NUM_IWL_RXON_CTX];
|
||||
|
||||
struct iwl_switch_rxon switch_rxon;
|
||||
__le16 switch_channel;
|
||||
|
||||
struct {
|
||||
u32 error_event_table;
|
||||
|
@ -250,19 +250,19 @@ static void iwl_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
|
||||
struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
|
||||
struct iwl_rxon_cmd *rxon = (void *)&ctx->active;
|
||||
|
||||
if (priv->switch_rxon.switch_in_progress) {
|
||||
if (!le32_to_cpu(csa->status) &&
|
||||
(csa->channel == priv->switch_rxon.channel)) {
|
||||
rxon->channel = csa->channel;
|
||||
ctx->staging.channel = csa->channel;
|
||||
IWL_DEBUG_11H(priv, "CSA notif: channel %d\n",
|
||||
if (!test_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->status))
|
||||
return;
|
||||
|
||||
if (!le32_to_cpu(csa->status) && csa->channel == priv->switch_channel) {
|
||||
rxon->channel = csa->channel;
|
||||
ctx->staging.channel = csa->channel;
|
||||
IWL_DEBUG_11H(priv, "CSA notif: channel %d\n",
|
||||
le16_to_cpu(csa->channel));
|
||||
iwl_chswitch_done(priv, true);
|
||||
} else {
|
||||
IWL_ERR(priv, "CSA notif (fail) : channel %d\n",
|
||||
le16_to_cpu(csa->channel));
|
||||
iwl_chswitch_done(priv, false);
|
||||
}
|
||||
iwl_chswitch_done(priv, true);
|
||||
} else {
|
||||
IWL_ERR(priv, "CSA notif (fail) : channel %d\n",
|
||||
le16_to_cpu(csa->channel));
|
||||
iwl_chswitch_done(priv, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -36,6 +36,7 @@
|
||||
#include "iwl-sta.h"
|
||||
#include "iwl-io.h"
|
||||
#include "iwl-helpers.h"
|
||||
#include "iwl-agn.h"
|
||||
|
||||
/* For active scan, listen ACTIVE_DWELL_TIME (msec) on each channel after
|
||||
* sending probe req. This should be set long enough to hear probe responses
|
||||
@ -600,14 +601,7 @@ out_settings:
|
||||
if (!iwl_is_ready_rf(priv))
|
||||
goto out;
|
||||
|
||||
/*
|
||||
* We do not commit power settings while scan is pending,
|
||||
* do it now if the settings changed.
|
||||
*/
|
||||
iwl_power_set_mode(priv, &priv->power_data.sleep_cmd_next, false);
|
||||
iwl_set_tx_power(priv, priv->tx_power_next, false);
|
||||
|
||||
priv->cfg->ops->utils->post_scan(priv);
|
||||
iwlagn_post_scan(priv);
|
||||
|
||||
out:
|
||||
mutex_unlock(&priv->mutex);
|
||||
|
@ -753,9 +753,9 @@ static void iwl_hcmd_queue_reclaim(struct iwl_priv *priv, int txq_id, int idx)
|
||||
int nfreed = 0;
|
||||
|
||||
if ((idx >= q->n_bd) || (iwl_queue_used(q, idx) == 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,
|
||||
idx, q->n_bd, q->write_ptr, q->read_ptr);
|
||||
IWL_ERR(priv, "%s: Read index for DMA queue txq id (%d), "
|
||||
"index %d is out of range [0-%d] %d %d.\n", __func__,
|
||||
txq_id, idx, q->n_bd, q->write_ptr, q->read_ptr);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -907,7 +907,7 @@ static void if_sdio_interrupt(struct sdio_func *func)
|
||||
card = sdio_get_drvdata(func);
|
||||
|
||||
cause = sdio_readb(card->func, IF_SDIO_H_INT_STATUS, &ret);
|
||||
if (ret)
|
||||
if (ret || !cause)
|
||||
goto out;
|
||||
|
||||
lbs_deb_sdio("interrupt: 0x%X\n", (unsigned)cause);
|
||||
@ -1008,10 +1008,6 @@ static int if_sdio_probe(struct sdio_func *func,
|
||||
if (ret)
|
||||
goto release;
|
||||
|
||||
ret = sdio_claim_irq(func, if_sdio_interrupt);
|
||||
if (ret)
|
||||
goto disable;
|
||||
|
||||
/* For 1-bit transfers to the 8686 model, we need to enable the
|
||||
* interrupt flag in the CCCR register. Set the MMC_QUIRK_LENIENT_FN0
|
||||
* bit to allow access to non-vendor registers. */
|
||||
@ -1082,6 +1078,21 @@ static int if_sdio_probe(struct sdio_func *func,
|
||||
else
|
||||
card->rx_unit = 0;
|
||||
|
||||
/*
|
||||
* Set up the interrupt handler late.
|
||||
*
|
||||
* If we set it up earlier, the (buggy) hardware generates a spurious
|
||||
* interrupt, even before the interrupt has been enabled, with
|
||||
* CCCR_INTx = 0.
|
||||
*
|
||||
* We register the interrupt handler late so that we can handle any
|
||||
* spurious interrupts, and also to avoid generation of that known
|
||||
* spurious interrupt in the first place.
|
||||
*/
|
||||
ret = sdio_claim_irq(func, if_sdio_interrupt);
|
||||
if (ret)
|
||||
goto disable;
|
||||
|
||||
/*
|
||||
* Enable interrupts now that everything is set up
|
||||
*/
|
||||
|
@ -1,6 +1,7 @@
|
||||
/*
|
||||
* mac80211_hwsim - software simulator of 802.11 radio(s) for mac80211
|
||||
* Copyright (c) 2008, Jouni Malinen <j@w1.fi>
|
||||
* Copyright (c) 2011, Javier Lopez <jlopex@gmail.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
@ -25,11 +26,17 @@
|
||||
#include <linux/rtnetlink.h>
|
||||
#include <linux/etherdevice.h>
|
||||
#include <linux/debugfs.h>
|
||||
#include <net/genetlink.h>
|
||||
#include "mac80211_hwsim.h"
|
||||
|
||||
#define WARN_QUEUE 100
|
||||
#define MAX_QUEUE 200
|
||||
|
||||
MODULE_AUTHOR("Jouni Malinen");
|
||||
MODULE_DESCRIPTION("Software simulator of 802.11 radio(s) for mac80211");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
int wmediumd_pid;
|
||||
static int radios = 2;
|
||||
module_param(radios, int, 0444);
|
||||
MODULE_PARM_DESC(radios, "Number of simulated radios");
|
||||
@ -302,6 +309,7 @@ struct mac80211_hwsim_data {
|
||||
struct dentry *debugfs;
|
||||
struct dentry *debugfs_ps;
|
||||
|
||||
struct sk_buff_head pending; /* packets pending */
|
||||
/*
|
||||
* Only radios in the same group can communicate together (the
|
||||
* channel has to match too). Each bit represents a group. A
|
||||
@ -322,6 +330,32 @@ struct hwsim_radiotap_hdr {
|
||||
__le16 rt_chbitmask;
|
||||
} __packed;
|
||||
|
||||
/* MAC80211_HWSIM netlinf family */
|
||||
static struct genl_family hwsim_genl_family = {
|
||||
.id = GENL_ID_GENERATE,
|
||||
.hdrsize = 0,
|
||||
.name = "MAC80211_HWSIM",
|
||||
.version = 1,
|
||||
.maxattr = HWSIM_ATTR_MAX,
|
||||
};
|
||||
|
||||
/* MAC80211_HWSIM netlink policy */
|
||||
|
||||
static struct nla_policy hwsim_genl_policy[HWSIM_ATTR_MAX + 1] = {
|
||||
[HWSIM_ATTR_ADDR_RECEIVER] = { .type = NLA_UNSPEC,
|
||||
.len = 6*sizeof(u8) },
|
||||
[HWSIM_ATTR_ADDR_TRANSMITTER] = { .type = NLA_UNSPEC,
|
||||
.len = 6*sizeof(u8) },
|
||||
[HWSIM_ATTR_FRAME] = { .type = NLA_BINARY,
|
||||
.len = IEEE80211_MAX_DATA_LEN },
|
||||
[HWSIM_ATTR_FLAGS] = { .type = NLA_U32 },
|
||||
[HWSIM_ATTR_RX_RATE] = { .type = NLA_U32 },
|
||||
[HWSIM_ATTR_SIGNAL] = { .type = NLA_U32 },
|
||||
[HWSIM_ATTR_TX_INFO] = { .type = NLA_UNSPEC,
|
||||
.len = IEEE80211_TX_MAX_RATES*sizeof(
|
||||
struct hwsim_tx_rate)},
|
||||
[HWSIM_ATTR_COOKIE] = { .type = NLA_U64 },
|
||||
};
|
||||
|
||||
static netdev_tx_t hwsim_mon_xmit(struct sk_buff *skb,
|
||||
struct net_device *dev)
|
||||
@ -478,9 +512,89 @@ static bool mac80211_hwsim_addr_match(struct mac80211_hwsim_data *data,
|
||||
return md.ret;
|
||||
}
|
||||
|
||||
static void mac80211_hwsim_tx_frame_nl(struct ieee80211_hw *hw,
|
||||
struct sk_buff *my_skb,
|
||||
int dst_pid)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
struct mac80211_hwsim_data *data = hw->priv;
|
||||
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) my_skb->data;
|
||||
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(my_skb);
|
||||
void *msg_head;
|
||||
unsigned int hwsim_flags = 0;
|
||||
int i;
|
||||
struct hwsim_tx_rate tx_attempts[IEEE80211_TX_MAX_RATES];
|
||||
|
||||
static bool mac80211_hwsim_tx_frame(struct ieee80211_hw *hw,
|
||||
struct sk_buff *skb)
|
||||
if (data->idle) {
|
||||
wiphy_debug(hw->wiphy, "Trying to TX when idle - reject\n");
|
||||
dev_kfree_skb(my_skb);
|
||||
return;
|
||||
}
|
||||
|
||||
if (data->ps != PS_DISABLED)
|
||||
hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_PM);
|
||||
/* If the queue contains MAX_QUEUE skb's drop some */
|
||||
if (skb_queue_len(&data->pending) >= MAX_QUEUE) {
|
||||
/* Droping until WARN_QUEUE level */
|
||||
while (skb_queue_len(&data->pending) >= WARN_QUEUE)
|
||||
skb_dequeue(&data->pending);
|
||||
}
|
||||
|
||||
skb = genlmsg_new(NLMSG_GOODSIZE, GFP_ATOMIC);
|
||||
if (skb == NULL)
|
||||
goto nla_put_failure;
|
||||
|
||||
msg_head = genlmsg_put(skb, 0, 0, &hwsim_genl_family, 0,
|
||||
HWSIM_CMD_FRAME);
|
||||
if (msg_head == NULL) {
|
||||
printk(KERN_DEBUG "mac80211_hwsim: problem with msg_head\n");
|
||||
goto nla_put_failure;
|
||||
}
|
||||
|
||||
NLA_PUT(skb, HWSIM_ATTR_ADDR_TRANSMITTER,
|
||||
sizeof(struct mac_address), data->addresses[1].addr);
|
||||
|
||||
/* We get the skb->data */
|
||||
NLA_PUT(skb, HWSIM_ATTR_FRAME, my_skb->len, my_skb->data);
|
||||
|
||||
/* We get the flags for this transmission, and we translate them to
|
||||
wmediumd flags */
|
||||
|
||||
if (info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS)
|
||||
hwsim_flags |= HWSIM_TX_CTL_REQ_TX_STATUS;
|
||||
|
||||
if (info->flags & IEEE80211_TX_CTL_NO_ACK)
|
||||
hwsim_flags |= HWSIM_TX_CTL_NO_ACK;
|
||||
|
||||
NLA_PUT_U32(skb, HWSIM_ATTR_FLAGS, hwsim_flags);
|
||||
|
||||
/* We get the tx control (rate and retries) info*/
|
||||
|
||||
for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) {
|
||||
tx_attempts[i].idx = info->status.rates[i].idx;
|
||||
tx_attempts[i].count = info->status.rates[i].count;
|
||||
}
|
||||
|
||||
NLA_PUT(skb, HWSIM_ATTR_TX_INFO,
|
||||
sizeof(struct hwsim_tx_rate)*IEEE80211_TX_MAX_RATES,
|
||||
tx_attempts);
|
||||
|
||||
/* We create a cookie to identify this skb */
|
||||
NLA_PUT_U64(skb, HWSIM_ATTR_COOKIE, (unsigned long) my_skb);
|
||||
|
||||
genlmsg_end(skb, msg_head);
|
||||
genlmsg_unicast(&init_net, skb, dst_pid);
|
||||
|
||||
/* Enqueue the packet */
|
||||
skb_queue_tail(&data->pending, my_skb);
|
||||
return;
|
||||
|
||||
nla_put_failure:
|
||||
printk(KERN_DEBUG "mac80211_hwsim: error occured in %s\n", __func__);
|
||||
}
|
||||
|
||||
static bool mac80211_hwsim_tx_frame_no_nl(struct ieee80211_hw *hw,
|
||||
struct sk_buff *skb)
|
||||
{
|
||||
struct mac80211_hwsim_data *data = hw->priv, *data2;
|
||||
bool ack = false;
|
||||
@ -540,11 +654,11 @@ static bool mac80211_hwsim_tx_frame(struct ieee80211_hw *hw,
|
||||
return ack;
|
||||
}
|
||||
|
||||
|
||||
static void mac80211_hwsim_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
|
||||
{
|
||||
bool ack;
|
||||
struct ieee80211_tx_info *txi;
|
||||
int _pid;
|
||||
|
||||
mac80211_hwsim_monitor_rx(hw, skb);
|
||||
|
||||
@ -554,7 +668,15 @@ static void mac80211_hwsim_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
|
||||
return;
|
||||
}
|
||||
|
||||
ack = mac80211_hwsim_tx_frame(hw, skb);
|
||||
/* wmediumd mode check */
|
||||
_pid = wmediumd_pid;
|
||||
|
||||
if (_pid)
|
||||
return mac80211_hwsim_tx_frame_nl(hw, skb, _pid);
|
||||
|
||||
/* NO wmediumd detected, perfect medium simulation */
|
||||
ack = mac80211_hwsim_tx_frame_no_nl(hw, skb);
|
||||
|
||||
if (ack && skb->len >= 16) {
|
||||
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
|
||||
mac80211_hwsim_monitor_ack(hw, hdr->addr2);
|
||||
@ -635,6 +757,7 @@ static void mac80211_hwsim_beacon_tx(void *arg, u8 *mac,
|
||||
struct ieee80211_hw *hw = arg;
|
||||
struct sk_buff *skb;
|
||||
struct ieee80211_tx_info *info;
|
||||
int _pid;
|
||||
|
||||
hwsim_check_magic(vif);
|
||||
|
||||
@ -649,7 +772,14 @@ static void mac80211_hwsim_beacon_tx(void *arg, u8 *mac,
|
||||
info = IEEE80211_SKB_CB(skb);
|
||||
|
||||
mac80211_hwsim_monitor_rx(hw, skb);
|
||||
mac80211_hwsim_tx_frame(hw, skb);
|
||||
|
||||
/* wmediumd mode check */
|
||||
_pid = wmediumd_pid;
|
||||
|
||||
if (_pid)
|
||||
return mac80211_hwsim_tx_frame_nl(hw, skb, _pid);
|
||||
|
||||
mac80211_hwsim_tx_frame_no_nl(hw, skb);
|
||||
dev_kfree_skb(skb);
|
||||
}
|
||||
|
||||
@ -966,12 +1096,7 @@ static int mac80211_hwsim_ampdu_action(struct ieee80211_hw *hw,
|
||||
|
||||
static void mac80211_hwsim_flush(struct ieee80211_hw *hw, bool drop)
|
||||
{
|
||||
/*
|
||||
* In this special case, there's nothing we need to
|
||||
* do because hwsim does transmission synchronously.
|
||||
* In the future, when it does transmissions via
|
||||
* userspace, we may need to do something.
|
||||
*/
|
||||
/* Not implemented, queues only on kernel side */
|
||||
}
|
||||
|
||||
struct hw_scan_done {
|
||||
@ -1119,6 +1244,7 @@ static void hwsim_send_ps_poll(void *dat, u8 *mac, struct ieee80211_vif *vif)
|
||||
struct hwsim_vif_priv *vp = (void *)vif->drv_priv;
|
||||
struct sk_buff *skb;
|
||||
struct ieee80211_pspoll *pspoll;
|
||||
int _pid;
|
||||
|
||||
if (!vp->assoc)
|
||||
return;
|
||||
@ -1137,8 +1263,15 @@ static void hwsim_send_ps_poll(void *dat, u8 *mac, struct ieee80211_vif *vif)
|
||||
pspoll->aid = cpu_to_le16(0xc000 | vp->aid);
|
||||
memcpy(pspoll->bssid, vp->bssid, ETH_ALEN);
|
||||
memcpy(pspoll->ta, mac, ETH_ALEN);
|
||||
if (!mac80211_hwsim_tx_frame(data->hw, skb))
|
||||
printk(KERN_DEBUG "%s: PS-Poll frame not ack'ed\n", __func__);
|
||||
|
||||
/* wmediumd mode check */
|
||||
_pid = wmediumd_pid;
|
||||
|
||||
if (_pid)
|
||||
return mac80211_hwsim_tx_frame_nl(data->hw, skb, _pid);
|
||||
|
||||
if (!mac80211_hwsim_tx_frame_no_nl(data->hw, skb))
|
||||
printk(KERN_DEBUG "%s: PS-poll frame not ack'ed\n", __func__);
|
||||
dev_kfree_skb(skb);
|
||||
}
|
||||
|
||||
@ -1149,6 +1282,7 @@ static void hwsim_send_nullfunc(struct mac80211_hwsim_data *data, u8 *mac,
|
||||
struct hwsim_vif_priv *vp = (void *)vif->drv_priv;
|
||||
struct sk_buff *skb;
|
||||
struct ieee80211_hdr *hdr;
|
||||
int _pid;
|
||||
|
||||
if (!vp->assoc)
|
||||
return;
|
||||
@ -1168,7 +1302,14 @@ static void hwsim_send_nullfunc(struct mac80211_hwsim_data *data, u8 *mac,
|
||||
memcpy(hdr->addr1, vp->bssid, ETH_ALEN);
|
||||
memcpy(hdr->addr2, mac, ETH_ALEN);
|
||||
memcpy(hdr->addr3, vp->bssid, ETH_ALEN);
|
||||
if (!mac80211_hwsim_tx_frame(data->hw, skb))
|
||||
|
||||
/* wmediumd mode check */
|
||||
_pid = wmediumd_pid;
|
||||
|
||||
if (_pid)
|
||||
return mac80211_hwsim_tx_frame_nl(data->hw, skb, _pid);
|
||||
|
||||
if (!mac80211_hwsim_tx_frame_no_nl(data->hw, skb))
|
||||
printk(KERN_DEBUG "%s: nullfunc frame not ack'ed\n", __func__);
|
||||
dev_kfree_skb(skb);
|
||||
}
|
||||
@ -1248,6 +1389,273 @@ DEFINE_SIMPLE_ATTRIBUTE(hwsim_fops_group,
|
||||
hwsim_fops_group_read, hwsim_fops_group_write,
|
||||
"%llx\n");
|
||||
|
||||
struct mac80211_hwsim_data *get_hwsim_data_ref_from_addr(
|
||||
struct mac_address *addr)
|
||||
{
|
||||
struct mac80211_hwsim_data *data;
|
||||
bool _found = false;
|
||||
|
||||
spin_lock_bh(&hwsim_radio_lock);
|
||||
list_for_each_entry(data, &hwsim_radios, list) {
|
||||
if (memcmp(data->addresses[1].addr, addr,
|
||||
sizeof(struct mac_address)) == 0) {
|
||||
_found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
spin_unlock_bh(&hwsim_radio_lock);
|
||||
|
||||
if (!_found)
|
||||
return NULL;
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
static int hwsim_tx_info_frame_received_nl(struct sk_buff *skb_2,
|
||||
struct genl_info *info)
|
||||
{
|
||||
|
||||
struct ieee80211_hdr *hdr;
|
||||
struct mac80211_hwsim_data *data2;
|
||||
struct ieee80211_tx_info *txi;
|
||||
struct hwsim_tx_rate *tx_attempts;
|
||||
struct sk_buff __user *ret_skb;
|
||||
struct sk_buff *skb, *tmp;
|
||||
struct mac_address *src;
|
||||
unsigned int hwsim_flags;
|
||||
|
||||
int i;
|
||||
bool found = false;
|
||||
|
||||
if (!info->attrs[HWSIM_ATTR_ADDR_TRANSMITTER] ||
|
||||
!info->attrs[HWSIM_ATTR_FLAGS] ||
|
||||
!info->attrs[HWSIM_ATTR_COOKIE] ||
|
||||
!info->attrs[HWSIM_ATTR_TX_INFO])
|
||||
goto out;
|
||||
|
||||
src = (struct mac_address *)nla_data(
|
||||
info->attrs[HWSIM_ATTR_ADDR_TRANSMITTER]);
|
||||
hwsim_flags = nla_get_u32(info->attrs[HWSIM_ATTR_FLAGS]);
|
||||
|
||||
ret_skb = (struct sk_buff __user *)
|
||||
(unsigned long) nla_get_u64(info->attrs[HWSIM_ATTR_COOKIE]);
|
||||
|
||||
data2 = get_hwsim_data_ref_from_addr(src);
|
||||
|
||||
if (data2 == NULL)
|
||||
goto out;
|
||||
|
||||
/* look for the skb matching the cookie passed back from user */
|
||||
skb_queue_walk_safe(&data2->pending, skb, tmp) {
|
||||
if (skb == ret_skb) {
|
||||
skb_unlink(skb, &data2->pending);
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* not found */
|
||||
if (!found)
|
||||
goto out;
|
||||
|
||||
/* Tx info received because the frame was broadcasted on user space,
|
||||
so we get all the necessary info: tx attempts and skb control buff */
|
||||
|
||||
tx_attempts = (struct hwsim_tx_rate *)nla_data(
|
||||
info->attrs[HWSIM_ATTR_TX_INFO]);
|
||||
|
||||
/* now send back TX status */
|
||||
txi = IEEE80211_SKB_CB(skb);
|
||||
|
||||
if (txi->control.vif)
|
||||
hwsim_check_magic(txi->control.vif);
|
||||
if (txi->control.sta)
|
||||
hwsim_check_sta_magic(txi->control.sta);
|
||||
|
||||
ieee80211_tx_info_clear_status(txi);
|
||||
|
||||
for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) {
|
||||
txi->status.rates[i].idx = tx_attempts[i].idx;
|
||||
txi->status.rates[i].count = tx_attempts[i].count;
|
||||
/*txi->status.rates[i].flags = 0;*/
|
||||
}
|
||||
|
||||
txi->status.ack_signal = nla_get_u32(info->attrs[HWSIM_ATTR_SIGNAL]);
|
||||
|
||||
if (!(hwsim_flags & HWSIM_TX_CTL_NO_ACK) &&
|
||||
(hwsim_flags & HWSIM_TX_STAT_ACK)) {
|
||||
if (skb->len >= 16) {
|
||||
hdr = (struct ieee80211_hdr *) skb->data;
|
||||
mac80211_hwsim_monitor_ack(data2->hw, hdr->addr2);
|
||||
}
|
||||
}
|
||||
ieee80211_tx_status_irqsafe(data2->hw, skb);
|
||||
return 0;
|
||||
out:
|
||||
return -EINVAL;
|
||||
|
||||
}
|
||||
|
||||
static int hwsim_cloned_frame_received_nl(struct sk_buff *skb_2,
|
||||
struct genl_info *info)
|
||||
{
|
||||
|
||||
struct mac80211_hwsim_data *data2;
|
||||
struct ieee80211_rx_status rx_status;
|
||||
struct mac_address *dst;
|
||||
int frame_data_len;
|
||||
char *frame_data;
|
||||
struct sk_buff *skb = NULL;
|
||||
|
||||
if (!info->attrs[HWSIM_ATTR_ADDR_RECEIVER] ||
|
||||
!info->attrs[HWSIM_ATTR_FRAME] ||
|
||||
!info->attrs[HWSIM_ATTR_RX_RATE] ||
|
||||
!info->attrs[HWSIM_ATTR_SIGNAL])
|
||||
goto out;
|
||||
|
||||
dst = (struct mac_address *)nla_data(
|
||||
info->attrs[HWSIM_ATTR_ADDR_RECEIVER]);
|
||||
|
||||
frame_data_len = nla_len(info->attrs[HWSIM_ATTR_FRAME]);
|
||||
frame_data = (char *)nla_data(info->attrs[HWSIM_ATTR_FRAME]);
|
||||
|
||||
/* Allocate new skb here */
|
||||
skb = alloc_skb(frame_data_len, GFP_KERNEL);
|
||||
if (skb == NULL)
|
||||
goto err;
|
||||
|
||||
if (frame_data_len <= IEEE80211_MAX_DATA_LEN) {
|
||||
/* Copy the data */
|
||||
memcpy(skb_put(skb, frame_data_len), frame_data,
|
||||
frame_data_len);
|
||||
} else
|
||||
goto err;
|
||||
|
||||
data2 = get_hwsim_data_ref_from_addr(dst);
|
||||
|
||||
if (data2 == NULL)
|
||||
goto out;
|
||||
|
||||
/* check if radio is configured properly */
|
||||
|
||||
if (data2->idle || !data2->started || !data2->channel)
|
||||
goto out;
|
||||
|
||||
/*A frame is received from user space*/
|
||||
memset(&rx_status, 0, sizeof(rx_status));
|
||||
rx_status.freq = data2->channel->center_freq;
|
||||
rx_status.band = data2->channel->band;
|
||||
rx_status.rate_idx = nla_get_u32(info->attrs[HWSIM_ATTR_RX_RATE]);
|
||||
rx_status.signal = nla_get_u32(info->attrs[HWSIM_ATTR_SIGNAL]);
|
||||
|
||||
memcpy(IEEE80211_SKB_RXCB(skb), &rx_status, sizeof(rx_status));
|
||||
ieee80211_rx_irqsafe(data2->hw, skb);
|
||||
|
||||
return 0;
|
||||
err:
|
||||
printk(KERN_DEBUG "mac80211_hwsim: error occured in %s\n", __func__);
|
||||
goto out;
|
||||
out:
|
||||
dev_kfree_skb(skb);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int hwsim_register_received_nl(struct sk_buff *skb_2,
|
||||
struct genl_info *info)
|
||||
{
|
||||
if (info == NULL)
|
||||
goto out;
|
||||
|
||||
wmediumd_pid = info->snd_pid;
|
||||
|
||||
printk(KERN_DEBUG "mac80211_hwsim: received a REGISTER, "
|
||||
"switching to wmediumd mode with pid %d\n", info->snd_pid);
|
||||
|
||||
return 0;
|
||||
out:
|
||||
printk(KERN_DEBUG "mac80211_hwsim: error occured in %s\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Generic Netlink operations array */
|
||||
static struct genl_ops hwsim_ops[] = {
|
||||
{
|
||||
.cmd = HWSIM_CMD_REGISTER,
|
||||
.policy = hwsim_genl_policy,
|
||||
.doit = hwsim_register_received_nl,
|
||||
.flags = GENL_ADMIN_PERM,
|
||||
},
|
||||
{
|
||||
.cmd = HWSIM_CMD_FRAME,
|
||||
.policy = hwsim_genl_policy,
|
||||
.doit = hwsim_cloned_frame_received_nl,
|
||||
},
|
||||
{
|
||||
.cmd = HWSIM_CMD_TX_INFO_FRAME,
|
||||
.policy = hwsim_genl_policy,
|
||||
.doit = hwsim_tx_info_frame_received_nl,
|
||||
},
|
||||
};
|
||||
|
||||
static int mac80211_hwsim_netlink_notify(struct notifier_block *nb,
|
||||
unsigned long state,
|
||||
void *_notify)
|
||||
{
|
||||
struct netlink_notify *notify = _notify;
|
||||
|
||||
if (state != NETLINK_URELEASE)
|
||||
return NOTIFY_DONE;
|
||||
|
||||
if (notify->pid == wmediumd_pid) {
|
||||
printk(KERN_INFO "mac80211_hwsim: wmediumd released netlink"
|
||||
" socket, switching to perfect channel medium\n");
|
||||
wmediumd_pid = 0;
|
||||
}
|
||||
return NOTIFY_DONE;
|
||||
|
||||
}
|
||||
|
||||
static struct notifier_block hwsim_netlink_notifier = {
|
||||
.notifier_call = mac80211_hwsim_netlink_notify,
|
||||
};
|
||||
|
||||
static int hwsim_init_netlink(void)
|
||||
{
|
||||
int rc;
|
||||
printk(KERN_INFO "mac80211_hwsim: initializing netlink\n");
|
||||
|
||||
wmediumd_pid = 0;
|
||||
|
||||
rc = genl_register_family_with_ops(&hwsim_genl_family,
|
||||
hwsim_ops, ARRAY_SIZE(hwsim_ops));
|
||||
if (rc)
|
||||
goto failure;
|
||||
|
||||
rc = netlink_register_notifier(&hwsim_netlink_notifier);
|
||||
if (rc)
|
||||
goto failure;
|
||||
|
||||
return 0;
|
||||
|
||||
failure:
|
||||
printk(KERN_DEBUG "mac80211_hwsim: error occured in %s\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static void hwsim_exit_netlink(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
printk(KERN_INFO "mac80211_hwsim: closing netlink\n");
|
||||
/* unregister the notifier */
|
||||
netlink_unregister_notifier(&hwsim_netlink_notifier);
|
||||
/* unregister the family */
|
||||
ret = genl_unregister_family(&hwsim_genl_family);
|
||||
if (ret)
|
||||
printk(KERN_DEBUG "mac80211_hwsim: "
|
||||
"unregister family %i\n", ret);
|
||||
}
|
||||
|
||||
static int __init init_mac80211_hwsim(void)
|
||||
{
|
||||
int i, err = 0;
|
||||
@ -1298,6 +1706,7 @@ static int __init init_mac80211_hwsim(void)
|
||||
goto failed_drvdata;
|
||||
}
|
||||
data->dev->driver = &mac80211_hwsim_driver;
|
||||
skb_queue_head_init(&data->pending);
|
||||
|
||||
SET_IEEE80211_DEV(hw, data->dev);
|
||||
addr[3] = i >> 8;
|
||||
@ -1379,6 +1788,10 @@ static int __init init_mac80211_hwsim(void)
|
||||
data->group = 1;
|
||||
mutex_init(&data->mutex);
|
||||
|
||||
/* Enable frame retransmissions for lossy channels */
|
||||
hw->max_rates = 4;
|
||||
hw->max_rate_tries = 11;
|
||||
|
||||
/* Work to be done prior to ieee80211_register_hw() */
|
||||
switch (regtest) {
|
||||
case HWSIM_REGTEST_DISABLED:
|
||||
@ -1515,12 +1928,29 @@ static int __init init_mac80211_hwsim(void)
|
||||
if (hwsim_mon == NULL)
|
||||
goto failed;
|
||||
|
||||
err = register_netdev(hwsim_mon);
|
||||
rtnl_lock();
|
||||
|
||||
err = dev_alloc_name(hwsim_mon, hwsim_mon->name);
|
||||
if (err < 0)
|
||||
goto failed_mon;
|
||||
|
||||
|
||||
err = register_netdevice(hwsim_mon);
|
||||
if (err < 0)
|
||||
goto failed_mon;
|
||||
|
||||
rtnl_unlock();
|
||||
|
||||
err = hwsim_init_netlink();
|
||||
if (err < 0)
|
||||
goto failed_nl;
|
||||
|
||||
return 0;
|
||||
|
||||
failed_nl:
|
||||
printk(KERN_DEBUG "mac_80211_hwsim: failed initializing netlink\n");
|
||||
return err;
|
||||
|
||||
failed_mon:
|
||||
rtnl_unlock();
|
||||
free_netdev(hwsim_mon);
|
||||
@ -1541,6 +1971,8 @@ static void __exit exit_mac80211_hwsim(void)
|
||||
{
|
||||
printk(KERN_DEBUG "mac80211_hwsim: unregister radios\n");
|
||||
|
||||
hwsim_exit_netlink();
|
||||
|
||||
mac80211_hwsim_free();
|
||||
unregister_netdev(hwsim_mon);
|
||||
}
|
||||
|
133
drivers/net/wireless/mac80211_hwsim.h
Normal file
133
drivers/net/wireless/mac80211_hwsim.h
Normal file
@ -0,0 +1,133 @@
|
||||
/*
|
||||
* mac80211_hwsim - software simulator of 802.11 radio(s) for mac80211
|
||||
* Copyright (c) 2008, Jouni Malinen <j@w1.fi>
|
||||
* Copyright (c) 2011, Javier Lopez <jlopex@gmail.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#ifndef __MAC80211_HWSIM_H
|
||||
#define __MAC80211_HWSIM_H
|
||||
|
||||
/**
|
||||
* enum hwsim_tx_control_flags - flags to describe transmission info/status
|
||||
*
|
||||
* These flags are used to give the wmediumd extra information in order to
|
||||
* modify its behavior for each frame
|
||||
*
|
||||
* @HWSIM_TX_CTL_REQ_TX_STATUS: require TX status callback for this frame.
|
||||
* @HWSIM_TX_CTL_NO_ACK: tell the wmediumd not to wait for an ack
|
||||
* @HWSIM_TX_STAT_ACK: Frame was acknowledged
|
||||
*
|
||||
*/
|
||||
enum hwsim_tx_control_flags {
|
||||
HWSIM_TX_CTL_REQ_TX_STATUS = BIT(0),
|
||||
HWSIM_TX_CTL_NO_ACK = BIT(1),
|
||||
HWSIM_TX_STAT_ACK = BIT(2),
|
||||
};
|
||||
|
||||
/**
|
||||
* DOC: Frame transmission/registration support
|
||||
*
|
||||
* Frame transmission and registration support exists to allow userspace
|
||||
* entities such as wmediumd to receive and process all broadcasted
|
||||
* frames from a mac80211_hwsim radio device.
|
||||
*
|
||||
* This allow user space applications to decide if the frame should be
|
||||
* dropped or not and implement a wireless medium simulator at user space.
|
||||
*
|
||||
* Registration is done by sending a register message to the driver and
|
||||
* will be automatically unregistered if the user application doesn't
|
||||
* responds to sent frames.
|
||||
* Once registered the user application has to take responsibility of
|
||||
* broadcasting the frames to all listening mac80211_hwsim radio
|
||||
* interfaces.
|
||||
*
|
||||
* For more technical details, see the corresponding command descriptions
|
||||
* below.
|
||||
*/
|
||||
|
||||
/**
|
||||
* enum hwsim_commands - supported hwsim commands
|
||||
*
|
||||
* @HWSIM_CMD_UNSPEC: unspecified command to catch errors
|
||||
*
|
||||
* @HWSIM_CMD_REGISTER: request to register and received all broadcasted
|
||||
* frames by any mac80211_hwsim radio device.
|
||||
* @HWSIM_CMD_FRAME: send/receive a broadcasted frame from/to kernel/user
|
||||
* space, uses:
|
||||
* %HWSIM_ATTR_ADDR_TRANSMITTER, %HWSIM_ATTR_ADDR_RECEIVER,
|
||||
* %HWSIM_ATTR_FRAME, %HWSIM_ATTR_FLAGS, %HWSIM_ATTR_RX_RATE,
|
||||
* %HWSIM_ATTR_SIGNAL, %HWSIM_ATTR_COOKIE
|
||||
* @HWSIM_CMD_TX_INFO_FRAME: Transmission info report from user space to
|
||||
* kernel, uses:
|
||||
* %HWSIM_ATTR_ADDR_TRANSMITTER, %HWSIM_ATTR_FLAGS,
|
||||
* %HWSIM_ATTR_TX_INFO, %HWSIM_ATTR_SIGNAL, %HWSIM_ATTR_COOKIE
|
||||
* @__HWSIM_CMD_MAX: enum limit
|
||||
*/
|
||||
enum {
|
||||
HWSIM_CMD_UNSPEC,
|
||||
HWSIM_CMD_REGISTER,
|
||||
HWSIM_CMD_FRAME,
|
||||
HWSIM_CMD_TX_INFO_FRAME,
|
||||
__HWSIM_CMD_MAX,
|
||||
};
|
||||
#define HWSIM_CMD_MAX (_HWSIM_CMD_MAX - 1)
|
||||
|
||||
/**
|
||||
* enum hwsim_attrs - hwsim netlink attributes
|
||||
*
|
||||
* @HWSIM_ATTR_UNSPEC: unspecified attribute to catch errors
|
||||
*
|
||||
* @HWSIM_ATTR_ADDR_RECEIVER: MAC address of the radio device that
|
||||
* the frame is broadcasted to
|
||||
* @HWSIM_ATTR_ADDR_TRANSMITTER: MAC address of the radio device that
|
||||
* the frame was broadcasted from
|
||||
* @HWSIM_ATTR_FRAME: Data array
|
||||
* @HWSIM_ATTR_FLAGS: mac80211 transmission flags, used to process
|
||||
properly the frame at user space
|
||||
* @HWSIM_ATTR_RX_RATE: estimated rx rate index for this frame at user
|
||||
space
|
||||
* @HWSIM_ATTR_SIGNAL: estimated RX signal for this frame at user
|
||||
space
|
||||
* @HWSIM_ATTR_TX_INFO: ieee80211_tx_rate array
|
||||
* @HWSIM_ATTR_COOKIE: sk_buff cookie to identify the frame
|
||||
* @__HWSIM_ATTR_MAX: enum limit
|
||||
*/
|
||||
|
||||
|
||||
enum {
|
||||
HWSIM_ATTR_UNSPEC,
|
||||
HWSIM_ATTR_ADDR_RECEIVER,
|
||||
HWSIM_ATTR_ADDR_TRANSMITTER,
|
||||
HWSIM_ATTR_FRAME,
|
||||
HWSIM_ATTR_FLAGS,
|
||||
HWSIM_ATTR_RX_RATE,
|
||||
HWSIM_ATTR_SIGNAL,
|
||||
HWSIM_ATTR_TX_INFO,
|
||||
HWSIM_ATTR_COOKIE,
|
||||
__HWSIM_ATTR_MAX,
|
||||
};
|
||||
#define HWSIM_ATTR_MAX (__HWSIM_ATTR_MAX - 1)
|
||||
|
||||
/**
|
||||
* struct hwsim_tx_rate - rate selection/status
|
||||
*
|
||||
* @idx: rate index to attempt to send with
|
||||
* @count: number of tries in this rate before going to the next rate
|
||||
*
|
||||
* A value of -1 for @idx indicates an invalid rate and, if used
|
||||
* in an array of retry rates, that no more rates should be tried.
|
||||
*
|
||||
* When used for transmit status reporting, the driver should
|
||||
* always report the rate and number of retries used.
|
||||
*
|
||||
*/
|
||||
struct hwsim_tx_rate {
|
||||
s8 idx;
|
||||
u8 count;
|
||||
} __packed;
|
||||
|
||||
#endif /* __MAC80211_HWSIM_H */
|
@ -164,12 +164,13 @@ mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv,
|
||||
struct mwifiex_tx_param tx_param;
|
||||
struct txpd *ptx_pd = NULL;
|
||||
|
||||
if (skb_queue_empty(&pra_list->skb_head)) {
|
||||
skb_src = skb_peek(&pra_list->skb_head);
|
||||
if (!skb_src) {
|
||||
spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock,
|
||||
ra_list_flags);
|
||||
return 0;
|
||||
}
|
||||
skb_src = skb_peek(&pra_list->skb_head);
|
||||
|
||||
tx_info_src = MWIFIEX_SKB_TXCB(skb_src);
|
||||
skb_aggr = dev_alloc_skb(adapter->tx_buf_size);
|
||||
if (!skb_aggr) {
|
||||
@ -184,17 +185,15 @@ mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv,
|
||||
tx_info_aggr->bss_index = tx_info_src->bss_index;
|
||||
skb_aggr->priority = skb_src->priority;
|
||||
|
||||
while (skb_src && ((skb_headroom(skb_aggr) + skb_src->len
|
||||
+ LLC_SNAP_LEN)
|
||||
<= adapter->tx_buf_size)) {
|
||||
do {
|
||||
/* Check if AMSDU can accommodate this MSDU */
|
||||
if (skb_tailroom(skb_aggr) < (skb_src->len + LLC_SNAP_LEN))
|
||||
break;
|
||||
|
||||
if (!skb_queue_empty(&pra_list->skb_head))
|
||||
skb_src = skb_dequeue(&pra_list->skb_head);
|
||||
else
|
||||
skb_src = NULL;
|
||||
skb_src = skb_dequeue(&pra_list->skb_head);
|
||||
|
||||
if (skb_src)
|
||||
pra_list->total_pkts_size -= skb_src->len;
|
||||
pra_list->total_pkts_size -= skb_src->len;
|
||||
pra_list->total_pkts--;
|
||||
|
||||
atomic_dec(&priv->wmm.tx_pkts_queued);
|
||||
|
||||
@ -212,11 +211,15 @@ mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv,
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!skb_queue_empty(&pra_list->skb_head))
|
||||
skb_src = skb_peek(&pra_list->skb_head);
|
||||
else
|
||||
skb_src = NULL;
|
||||
}
|
||||
if (skb_tailroom(skb_aggr) < pad) {
|
||||
pad = 0;
|
||||
break;
|
||||
}
|
||||
skb_put(skb_aggr, pad);
|
||||
|
||||
skb_src = skb_peek(&pra_list->skb_head);
|
||||
|
||||
} while (skb_src);
|
||||
|
||||
spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, ra_list_flags);
|
||||
|
||||
@ -230,11 +233,19 @@ mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv,
|
||||
|
||||
skb_push(skb_aggr, headroom);
|
||||
|
||||
tx_param.next_pkt_len = ((pra_list->total_pkts_size) ?
|
||||
(((pra_list->total_pkts_size) >
|
||||
adapter->tx_buf_size) ? adapter->
|
||||
tx_buf_size : pra_list->total_pkts_size +
|
||||
LLC_SNAP_LEN + sizeof(struct txpd)) : 0);
|
||||
/*
|
||||
* Padding per MSDU will affect the length of next
|
||||
* packet and hence the exact length of next packet
|
||||
* is uncertain here.
|
||||
*
|
||||
* Also, aggregation of transmission buffer, while
|
||||
* downloading the data to the card, wont gain much
|
||||
* on the AMSDU packets as the AMSDU packets utilizes
|
||||
* the transmission buffer space to the maximum
|
||||
* (adapter->tx_buf_size).
|
||||
*/
|
||||
tx_param.next_pkt_len = 0;
|
||||
|
||||
ret = adapter->if_ops.host_to_card(adapter, MWIFIEX_TYPE_DATA,
|
||||
skb_aggr->data,
|
||||
skb_aggr->len, &tx_param);
|
||||
@ -258,6 +269,7 @@ mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv,
|
||||
skb_queue_tail(&pra_list->skb_head, skb_aggr);
|
||||
|
||||
pra_list->total_pkts_size += skb_aggr->len;
|
||||
pra_list->total_pkts++;
|
||||
|
||||
atomic_inc(&priv->wmm.tx_pkts_queued);
|
||||
|
||||
|
@ -35,8 +35,6 @@ static struct mwifiex_bss_attr mwifiex_bss_sta[] = {
|
||||
|
||||
static int drv_mode = DRV_MODE_STA;
|
||||
|
||||
static char fw_name[32] = DEFAULT_FW_NAME;
|
||||
|
||||
/* Supported drv_mode table */
|
||||
static struct mwifiex_drv_mode mwifiex_drv_mode_tbl[] = {
|
||||
{
|
||||
@ -384,20 +382,8 @@ static int mwifiex_init_hw_fw(struct mwifiex_adapter *adapter)
|
||||
|
||||
memset(&fw, 0, sizeof(struct mwifiex_fw_image));
|
||||
|
||||
switch (adapter->revision_id) {
|
||||
case SD8787_W0:
|
||||
case SD8787_W1:
|
||||
strcpy(fw_name, SD8787_W1_FW_NAME);
|
||||
break;
|
||||
case SD8787_A0:
|
||||
case SD8787_A1:
|
||||
strcpy(fw_name, SD8787_AX_FW_NAME);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
err = request_firmware(&adapter->firmware, fw_name, adapter->dev);
|
||||
err = request_firmware(&adapter->firmware, adapter->fw_name,
|
||||
adapter->dev);
|
||||
if (err < 0) {
|
||||
dev_err(adapter->dev, "request_firmware() returned"
|
||||
" error code %#x\n", err);
|
||||
|
@ -48,15 +48,6 @@ enum {
|
||||
|
||||
#define DRV_MODE_STA 0x1
|
||||
|
||||
#define SD8787_W0 0x30
|
||||
#define SD8787_W1 0x31
|
||||
#define SD8787_A0 0x40
|
||||
#define SD8787_A1 0x41
|
||||
|
||||
#define DEFAULT_FW_NAME "mrvl/sd8787_uapsta.bin"
|
||||
#define SD8787_W1_FW_NAME "mrvl/sd8787_uapsta_w1.bin"
|
||||
#define SD8787_AX_FW_NAME "mrvl/sd8787_uapsta.bin"
|
||||
|
||||
struct mwifiex_drv_mode {
|
||||
u16 drv_mode;
|
||||
u16 intf_num;
|
||||
@ -190,6 +181,7 @@ struct mwifiex_ra_list_tbl {
|
||||
struct sk_buff_head skb_head;
|
||||
u8 ra[ETH_ALEN];
|
||||
u32 total_pkts_size;
|
||||
u32 total_pkts;
|
||||
u32 is_11n_enabled;
|
||||
};
|
||||
|
||||
@ -576,10 +568,10 @@ struct mwifiex_adapter {
|
||||
u8 priv_num;
|
||||
struct mwifiex_drv_mode *drv_mode;
|
||||
const struct firmware *firmware;
|
||||
char fw_name[32];
|
||||
struct device *dev;
|
||||
bool surprise_removed;
|
||||
u32 fw_release_number;
|
||||
u32 revision_id;
|
||||
u16 init_wait_q_woken;
|
||||
wait_queue_head_t init_wait_q;
|
||||
void *card;
|
||||
|
@ -1531,6 +1531,7 @@ static int mwifiex_register_dev(struct mwifiex_adapter *adapter)
|
||||
sdio_set_drvdata(func, card);
|
||||
|
||||
adapter->dev = &func->dev;
|
||||
strcpy(adapter->fw_name, SD8787_DEFAULT_FW_NAME);
|
||||
|
||||
return 0;
|
||||
|
||||
@ -1552,7 +1553,6 @@ disable_func:
|
||||
* the first interrupt got from bootloader
|
||||
* - Disable host interrupt mask register
|
||||
* - Get SDIO port
|
||||
* - Get revision ID
|
||||
* - Initialize SDIO variables in card
|
||||
* - Allocate MP registers
|
||||
* - Allocate MPA Tx and Rx buffers
|
||||
@ -1576,10 +1576,6 @@ static int mwifiex_init_sdio(struct mwifiex_adapter *adapter)
|
||||
/* Get SDIO ioport */
|
||||
mwifiex_init_sdio_ioport(adapter);
|
||||
|
||||
/* Get revision ID */
|
||||
#define REV_ID_REG 0x5c
|
||||
mwifiex_read_reg(adapter, REV_ID_REG, &adapter->revision_id);
|
||||
|
||||
/* Initialize SDIO variables in card */
|
||||
card->mp_rd_bitmap = 0;
|
||||
card->mp_wr_bitmap = 0;
|
||||
@ -1751,4 +1747,4 @@ MODULE_AUTHOR("Marvell International Ltd.");
|
||||
MODULE_DESCRIPTION("Marvell WiFi-Ex SDIO Driver version " SDIO_VERSION);
|
||||
MODULE_VERSION(SDIO_VERSION);
|
||||
MODULE_LICENSE("GPL v2");
|
||||
MODULE_FIRMWARE("sd8787.bin");
|
||||
MODULE_FIRMWARE("mrvl/sd8787_uapsta.bin");
|
||||
|
@ -28,6 +28,8 @@
|
||||
|
||||
#include "main.h"
|
||||
|
||||
#define SD8787_DEFAULT_FW_NAME "mrvl/sd8787_uapsta.bin"
|
||||
|
||||
#define BLOCK_MODE 1
|
||||
#define BYTE_MODE 0
|
||||
|
||||
|
@ -121,6 +121,7 @@ mwifiex_wmm_allocate_ralist_node(struct mwifiex_adapter *adapter, u8 *ra)
|
||||
memcpy(ra_list->ra, ra, ETH_ALEN);
|
||||
|
||||
ra_list->total_pkts_size = 0;
|
||||
ra_list->total_pkts = 0;
|
||||
|
||||
dev_dbg(adapter->dev, "info: allocated ra_list %p\n", ra_list);
|
||||
|
||||
@ -645,6 +646,7 @@ mwifiex_wmm_add_buf_txqueue(struct mwifiex_adapter *adapter,
|
||||
skb_queue_tail(&ra_list->skb_head, skb);
|
||||
|
||||
ra_list->total_pkts_size += skb->len;
|
||||
ra_list->total_pkts++;
|
||||
|
||||
atomic_inc(&priv->wmm.tx_pkts_queued);
|
||||
|
||||
@ -970,28 +972,6 @@ mwifiex_wmm_get_highest_priolist_ptr(struct mwifiex_adapter *adapter,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* This function gets the number of packets in the Tx queue of a
|
||||
* particular RA list.
|
||||
*/
|
||||
static int
|
||||
mwifiex_num_pkts_in_txq(struct mwifiex_private *priv,
|
||||
struct mwifiex_ra_list_tbl *ptr, int max_buf_size)
|
||||
{
|
||||
int count = 0, total_size = 0;
|
||||
struct sk_buff *skb, *tmp;
|
||||
|
||||
skb_queue_walk_safe(&ptr->skb_head, skb, tmp) {
|
||||
total_size += skb->len;
|
||||
if (total_size < max_buf_size)
|
||||
++count;
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
/*
|
||||
* This function sends a single packet to firmware for transmission.
|
||||
*/
|
||||
@ -1019,6 +999,7 @@ mwifiex_send_single_packet(struct mwifiex_private *priv,
|
||||
dev_dbg(adapter->dev, "data: dequeuing the packet %p %p\n", ptr, skb);
|
||||
|
||||
ptr->total_pkts_size -= skb->len;
|
||||
ptr->total_pkts--;
|
||||
|
||||
if (!skb_queue_empty(&ptr->skb_head))
|
||||
skb_next = skb_peek(&ptr->skb_head);
|
||||
@ -1044,6 +1025,7 @@ mwifiex_send_single_packet(struct mwifiex_private *priv,
|
||||
skb_queue_tail(&ptr->skb_head, skb);
|
||||
|
||||
ptr->total_pkts_size += skb->len;
|
||||
ptr->total_pkts++;
|
||||
tx_info->flags |= MWIFIEX_BUF_FLAG_REQUEUED_PKT;
|
||||
spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock,
|
||||
ra_list_flags);
|
||||
@ -1231,9 +1213,9 @@ mwifiex_dequeue_tx_packet(struct mwifiex_adapter *adapter)
|
||||
}
|
||||
/* Minimum number of AMSDU */
|
||||
#define MIN_NUM_AMSDU 2
|
||||
|
||||
if (mwifiex_is_amsdu_allowed(priv, tid) &&
|
||||
(mwifiex_num_pkts_in_txq(priv, ptr, adapter->tx_buf_size) >=
|
||||
MIN_NUM_AMSDU))
|
||||
(ptr->total_pkts >= MIN_NUM_AMSDU))
|
||||
mwifiex_11n_aggregate_pkt(priv, ptr, INTF_HEADER_LEN,
|
||||
ptr_index, flags);
|
||||
/* ra_list_spinlock has been freed in
|
||||
|
@ -83,14 +83,12 @@ config RT2800PCI_RT33XX
|
||||
config RT2800PCI_RT35XX
|
||||
bool "rt2800pci - Include support for rt35xx devices (EXPERIMENTAL)"
|
||||
depends on EXPERIMENTAL
|
||||
default n
|
||||
default y
|
||||
---help---
|
||||
This adds support for rt35xx wireless chipset family to the
|
||||
rt2800pci driver.
|
||||
Supported chips: RT3060, RT3062, RT3562, RT3592
|
||||
|
||||
Support for these devices is non-functional at the moment and is
|
||||
intended for testers and developers.
|
||||
|
||||
config RT2800PCI_RT53XX
|
||||
bool "rt2800pci - Include support for rt53xx devices (EXPERIMENTAL)"
|
||||
@ -154,15 +152,12 @@ config RT2800USB_RT33XX
|
||||
config RT2800USB_RT35XX
|
||||
bool "rt2800usb - Include support for rt35xx devices (EXPERIMENTAL)"
|
||||
depends on EXPERIMENTAL
|
||||
default n
|
||||
default y
|
||||
---help---
|
||||
This adds support for rt35xx wireless chipset family to the
|
||||
rt2800usb driver.
|
||||
Supported chips: RT3572
|
||||
|
||||
Support for these devices is non-functional at the moment and is
|
||||
intended for testers and developers.
|
||||
|
||||
config RT2800USB_RT53XX
|
||||
bool "rt2800usb - Include support for rt53xx devices (EXPERIMENTAL)"
|
||||
depends on EXPERIMENTAL
|
||||
|
@ -1740,6 +1740,7 @@ struct mac_iveiv_entry {
|
||||
/*
|
||||
* BBP 3: RX Antenna
|
||||
*/
|
||||
#define BBP3_RX_ADC FIELD8(0x03)
|
||||
#define BBP3_RX_ANTENNA FIELD8(0x18)
|
||||
#define BBP3_HT40_MINUS FIELD8(0x20)
|
||||
|
||||
@ -1783,22 +1784,34 @@ struct mac_iveiv_entry {
|
||||
#define RFCSR1_TX0_PD FIELD8(0x08)
|
||||
#define RFCSR1_RX1_PD FIELD8(0x10)
|
||||
#define RFCSR1_TX1_PD FIELD8(0x20)
|
||||
#define RFCSR1_RX2_PD FIELD8(0x40)
|
||||
#define RFCSR1_TX2_PD FIELD8(0x80)
|
||||
|
||||
/*
|
||||
* RFCSR 2:
|
||||
*/
|
||||
#define RFCSR2_RESCAL_EN FIELD8(0x80)
|
||||
|
||||
/*
|
||||
* FRCSR 5:
|
||||
*/
|
||||
#define RFCSR5_R1 FIELD8(0x0c)
|
||||
|
||||
/*
|
||||
* RFCSR 6:
|
||||
*/
|
||||
#define RFCSR6_R1 FIELD8(0x03)
|
||||
#define RFCSR6_R2 FIELD8(0x40)
|
||||
#define RFCSR6_TXDIV FIELD8(0x0c)
|
||||
|
||||
/*
|
||||
* RFCSR 7:
|
||||
*/
|
||||
#define RFCSR7_RF_TUNING FIELD8(0x01)
|
||||
#define RFCSR7_R02 FIELD8(0x07)
|
||||
#define RFCSR7_R3 FIELD8(0x08)
|
||||
#define RFCSR7_R45 FIELD8(0x30)
|
||||
#define RFCSR7_R67 FIELD8(0xc0)
|
||||
|
||||
/*
|
||||
* RFCSR 11:
|
||||
@ -1809,11 +1822,13 @@ struct mac_iveiv_entry {
|
||||
* RFCSR 12:
|
||||
*/
|
||||
#define RFCSR12_TX_POWER FIELD8(0x1f)
|
||||
#define RFCSR12_DR0 FIELD8(0xe0)
|
||||
|
||||
/*
|
||||
* RFCSR 13:
|
||||
*/
|
||||
#define RFCSR13_TX_POWER FIELD8(0x1f)
|
||||
#define RFCSR13_DR0 FIELD8(0xe0)
|
||||
|
||||
/*
|
||||
* RFCSR 15:
|
||||
@ -2256,6 +2271,7 @@ struct mac_iveiv_entry {
|
||||
#define MCU_ANT_SELECT 0X73
|
||||
#define MCU_BBP_SIGNAL 0x80
|
||||
#define MCU_POWER_SAVE 0x83
|
||||
#define MCU_BAND_SELECT 0x91
|
||||
|
||||
/*
|
||||
* MCU mailbox tokens
|
||||
|
@ -401,7 +401,8 @@ int rt2800_load_firmware(struct rt2x00_dev *rt2x00dev,
|
||||
return -EBUSY;
|
||||
|
||||
if (rt2x00_is_pci(rt2x00dev)) {
|
||||
if (rt2x00_rt(rt2x00dev, RT5390)) {
|
||||
if (rt2x00_rt(rt2x00dev, RT3572) ||
|
||||
rt2x00_rt(rt2x00dev, RT5390)) {
|
||||
rt2800_register_read(rt2x00dev, AUX_CTRL, ®);
|
||||
rt2x00_set_field32(®, AUX_CTRL_FORCE_PCIE_CLK, 1);
|
||||
rt2x00_set_field32(®, AUX_CTRL_WAKE_PCIE_EN, 1);
|
||||
@ -600,49 +601,6 @@ void rt2800_process_rxwi(struct queue_entry *entry,
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rt2800_process_rxwi);
|
||||
|
||||
static bool rt2800_txdone_entry_check(struct queue_entry *entry, u32 reg)
|
||||
{
|
||||
__le32 *txwi;
|
||||
u32 word;
|
||||
int wcid, ack, pid;
|
||||
int tx_wcid, tx_ack, tx_pid;
|
||||
|
||||
wcid = rt2x00_get_field32(reg, TX_STA_FIFO_WCID);
|
||||
ack = rt2x00_get_field32(reg, TX_STA_FIFO_TX_ACK_REQUIRED);
|
||||
pid = rt2x00_get_field32(reg, TX_STA_FIFO_PID_TYPE);
|
||||
|
||||
/*
|
||||
* This frames has returned with an IO error,
|
||||
* so the status report is not intended for this
|
||||
* frame.
|
||||
*/
|
||||
if (test_bit(ENTRY_DATA_IO_FAILED, &entry->flags)) {
|
||||
rt2x00lib_txdone_noinfo(entry, TXDONE_FAILURE);
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Validate if this TX status report is intended for
|
||||
* this entry by comparing the WCID/ACK/PID fields.
|
||||
*/
|
||||
txwi = rt2800_drv_get_txwi(entry);
|
||||
|
||||
rt2x00_desc_read(txwi, 1, &word);
|
||||
tx_wcid = rt2x00_get_field32(word, TXWI_W1_WIRELESS_CLI_ID);
|
||||
tx_ack = rt2x00_get_field32(word, TXWI_W1_ACK);
|
||||
tx_pid = rt2x00_get_field32(word, TXWI_W1_PACKETID);
|
||||
|
||||
if ((wcid != tx_wcid) || (ack != tx_ack) || (pid != tx_pid)) {
|
||||
WARNING(entry->queue->rt2x00dev,
|
||||
"TX status report missed for queue %d entry %d\n",
|
||||
entry->queue->qid, entry->entry_idx);
|
||||
rt2x00lib_txdone_noinfo(entry, TXDONE_UNKNOWN);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void rt2800_txdone_entry(struct queue_entry *entry, u32 status)
|
||||
{
|
||||
struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
|
||||
@ -725,45 +683,6 @@ void rt2800_txdone_entry(struct queue_entry *entry, u32 status)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rt2800_txdone_entry);
|
||||
|
||||
void rt2800_txdone(struct rt2x00_dev *rt2x00dev)
|
||||
{
|
||||
struct data_queue *queue;
|
||||
struct queue_entry *entry;
|
||||
u32 reg;
|
||||
u8 qid;
|
||||
|
||||
while (kfifo_get(&rt2x00dev->txstatus_fifo, ®)) {
|
||||
|
||||
/* TX_STA_FIFO_PID_QUEUE is a 2-bit field, thus
|
||||
* qid is guaranteed to be one of the TX QIDs
|
||||
*/
|
||||
qid = rt2x00_get_field32(reg, TX_STA_FIFO_PID_QUEUE);
|
||||
queue = rt2x00queue_get_tx_queue(rt2x00dev, qid);
|
||||
if (unlikely(!queue)) {
|
||||
WARNING(rt2x00dev, "Got TX status for an unavailable "
|
||||
"queue %u, dropping\n", qid);
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* Inside each queue, we process each entry in a chronological
|
||||
* order. We first check that the queue is not empty.
|
||||
*/
|
||||
entry = NULL;
|
||||
while (!rt2x00queue_empty(queue)) {
|
||||
entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE);
|
||||
if (rt2800_txdone_entry_check(entry, reg))
|
||||
break;
|
||||
}
|
||||
|
||||
if (!entry || rt2x00queue_empty(queue))
|
||||
break;
|
||||
|
||||
rt2800_txdone_entry(entry, reg);
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rt2800_txdone);
|
||||
|
||||
void rt2800_write_beacon(struct queue_entry *entry, struct txentry_desc *txdesc)
|
||||
{
|
||||
struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
|
||||
@ -1433,6 +1352,40 @@ void rt2800_config_erp(struct rt2x00_dev *rt2x00dev, struct rt2x00lib_erp *erp,
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rt2800_config_erp);
|
||||
|
||||
static void rt2800_config_3572bt_ant(struct rt2x00_dev *rt2x00dev)
|
||||
{
|
||||
u32 reg;
|
||||
u16 eeprom;
|
||||
u8 led_ctrl, led_g_mode, led_r_mode;
|
||||
|
||||
rt2800_register_read(rt2x00dev, GPIO_SWITCH, ®);
|
||||
if (rt2x00dev->curr_band == IEEE80211_BAND_5GHZ) {
|
||||
rt2x00_set_field32(®, GPIO_SWITCH_0, 1);
|
||||
rt2x00_set_field32(®, GPIO_SWITCH_1, 1);
|
||||
} else {
|
||||
rt2x00_set_field32(®, GPIO_SWITCH_0, 0);
|
||||
rt2x00_set_field32(®, GPIO_SWITCH_1, 0);
|
||||
}
|
||||
rt2800_register_write(rt2x00dev, GPIO_SWITCH, reg);
|
||||
|
||||
rt2800_register_read(rt2x00dev, LED_CFG, ®);
|
||||
led_g_mode = rt2x00_get_field32(reg, LED_CFG_LED_POLAR) ? 3 : 0;
|
||||
led_r_mode = rt2x00_get_field32(reg, LED_CFG_LED_POLAR) ? 0 : 3;
|
||||
if (led_g_mode != rt2x00_get_field32(reg, LED_CFG_G_LED_MODE) ||
|
||||
led_r_mode != rt2x00_get_field32(reg, LED_CFG_R_LED_MODE)) {
|
||||
rt2x00_eeprom_read(rt2x00dev, EEPROM_FREQ, &eeprom);
|
||||
led_ctrl = rt2x00_get_field16(eeprom, EEPROM_FREQ_LED_MODE);
|
||||
if (led_ctrl == 0 || led_ctrl > 0x40) {
|
||||
rt2x00_set_field32(®, LED_CFG_G_LED_MODE, led_g_mode);
|
||||
rt2x00_set_field32(®, LED_CFG_R_LED_MODE, led_r_mode);
|
||||
rt2800_register_write(rt2x00dev, LED_CFG, reg);
|
||||
} else {
|
||||
rt2800_mcu_request(rt2x00dev, MCU_BAND_SELECT, 0xff,
|
||||
(led_g_mode << 2) | led_r_mode, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void rt2800_set_ant_diversity(struct rt2x00_dev *rt2x00dev,
|
||||
enum antenna ant)
|
||||
{
|
||||
@ -1463,6 +1416,10 @@ void rt2800_config_ant(struct rt2x00_dev *rt2x00dev, struct antenna_setup *ant)
|
||||
rt2800_bbp_read(rt2x00dev, 1, &r1);
|
||||
rt2800_bbp_read(rt2x00dev, 3, &r3);
|
||||
|
||||
if (rt2x00_rt(rt2x00dev, RT3572) &&
|
||||
test_bit(CAPABILITY_BT_COEXIST, &rt2x00dev->cap_flags))
|
||||
rt2800_config_3572bt_ant(rt2x00dev);
|
||||
|
||||
/*
|
||||
* Configure the TX antenna.
|
||||
*/
|
||||
@ -1471,7 +1428,11 @@ void rt2800_config_ant(struct rt2x00_dev *rt2x00dev, struct antenna_setup *ant)
|
||||
rt2x00_set_field8(&r1, BBP1_TX_ANTENNA, 0);
|
||||
break;
|
||||
case 2:
|
||||
rt2x00_set_field8(&r1, BBP1_TX_ANTENNA, 2);
|
||||
if (rt2x00_rt(rt2x00dev, RT3572) &&
|
||||
test_bit(CAPABILITY_BT_COEXIST, &rt2x00dev->cap_flags))
|
||||
rt2x00_set_field8(&r1, BBP1_TX_ANTENNA, 1);
|
||||
else
|
||||
rt2x00_set_field8(&r1, BBP1_TX_ANTENNA, 2);
|
||||
break;
|
||||
case 3:
|
||||
rt2x00_set_field8(&r1, BBP1_TX_ANTENNA, 0);
|
||||
@ -1496,7 +1457,15 @@ void rt2800_config_ant(struct rt2x00_dev *rt2x00dev, struct antenna_setup *ant)
|
||||
rt2x00_set_field8(&r3, BBP3_RX_ANTENNA, 0);
|
||||
break;
|
||||
case 2:
|
||||
rt2x00_set_field8(&r3, BBP3_RX_ANTENNA, 1);
|
||||
if (rt2x00_rt(rt2x00dev, RT3572) &&
|
||||
test_bit(CAPABILITY_BT_COEXIST, &rt2x00dev->cap_flags)) {
|
||||
rt2x00_set_field8(&r3, BBP3_RX_ADC, 1);
|
||||
rt2x00_set_field8(&r3, BBP3_RX_ANTENNA,
|
||||
rt2x00dev->curr_band == IEEE80211_BAND_5GHZ);
|
||||
rt2800_set_ant_diversity(rt2x00dev, ANTENNA_B);
|
||||
} else {
|
||||
rt2x00_set_field8(&r3, BBP3_RX_ANTENNA, 1);
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
rt2x00_set_field8(&r3, BBP3_RX_ANTENNA, 2);
|
||||
@ -1630,6 +1599,161 @@ static void rt2800_config_channel_rf3xxx(struct rt2x00_dev *rt2x00dev,
|
||||
rt2800_rfcsr_write(rt2x00dev, 7, rfcsr);
|
||||
}
|
||||
|
||||
static void rt2800_config_channel_rf3052(struct rt2x00_dev *rt2x00dev,
|
||||
struct ieee80211_conf *conf,
|
||||
struct rf_channel *rf,
|
||||
struct channel_info *info)
|
||||
{
|
||||
u8 rfcsr;
|
||||
u32 reg;
|
||||
|
||||
if (rf->channel <= 14) {
|
||||
rt2800_bbp_write(rt2x00dev, 25, 0x15);
|
||||
rt2800_bbp_write(rt2x00dev, 26, 0x85);
|
||||
} else {
|
||||
rt2800_bbp_write(rt2x00dev, 25, 0x09);
|
||||
rt2800_bbp_write(rt2x00dev, 26, 0xff);
|
||||
}
|
||||
|
||||
rt2800_rfcsr_write(rt2x00dev, 2, rf->rf1);
|
||||
rt2800_rfcsr_write(rt2x00dev, 3, rf->rf3);
|
||||
|
||||
rt2800_rfcsr_read(rt2x00dev, 6, &rfcsr);
|
||||
rt2x00_set_field8(&rfcsr, RFCSR6_R1, rf->rf2);
|
||||
if (rf->channel <= 14)
|
||||
rt2x00_set_field8(&rfcsr, RFCSR6_TXDIV, 2);
|
||||
else
|
||||
rt2x00_set_field8(&rfcsr, RFCSR6_TXDIV, 1);
|
||||
rt2800_rfcsr_write(rt2x00dev, 6, rfcsr);
|
||||
|
||||
rt2800_rfcsr_read(rt2x00dev, 5, &rfcsr);
|
||||
if (rf->channel <= 14)
|
||||
rt2x00_set_field8(&rfcsr, RFCSR5_R1, 1);
|
||||
else
|
||||
rt2x00_set_field8(&rfcsr, RFCSR5_R1, 2);
|
||||
rt2800_rfcsr_write(rt2x00dev, 5, rfcsr);
|
||||
|
||||
rt2800_rfcsr_read(rt2x00dev, 12, &rfcsr);
|
||||
if (rf->channel <= 14) {
|
||||
rt2x00_set_field8(&rfcsr, RFCSR12_DR0, 3);
|
||||
rt2x00_set_field8(&rfcsr, RFCSR12_TX_POWER,
|
||||
(info->default_power1 & 0x3) |
|
||||
((info->default_power1 & 0xC) << 1));
|
||||
} else {
|
||||
rt2x00_set_field8(&rfcsr, RFCSR12_DR0, 7);
|
||||
rt2x00_set_field8(&rfcsr, RFCSR12_TX_POWER,
|
||||
(info->default_power1 & 0x3) |
|
||||
((info->default_power1 & 0xC) << 1));
|
||||
}
|
||||
rt2800_rfcsr_write(rt2x00dev, 12, rfcsr);
|
||||
|
||||
rt2800_rfcsr_read(rt2x00dev, 13, &rfcsr);
|
||||
if (rf->channel <= 14) {
|
||||
rt2x00_set_field8(&rfcsr, RFCSR13_DR0, 3);
|
||||
rt2x00_set_field8(&rfcsr, RFCSR13_TX_POWER,
|
||||
(info->default_power2 & 0x3) |
|
||||
((info->default_power2 & 0xC) << 1));
|
||||
} else {
|
||||
rt2x00_set_field8(&rfcsr, RFCSR13_DR0, 7);
|
||||
rt2x00_set_field8(&rfcsr, RFCSR13_TX_POWER,
|
||||
(info->default_power2 & 0x3) |
|
||||
((info->default_power2 & 0xC) << 1));
|
||||
}
|
||||
rt2800_rfcsr_write(rt2x00dev, 13, rfcsr);
|
||||
|
||||
rt2800_rfcsr_read(rt2x00dev, 1, &rfcsr);
|
||||
rt2x00_set_field8(&rfcsr, RFCSR1_RF_BLOCK_EN, 1);
|
||||
rt2x00_set_field8(&rfcsr, RFCSR1_RX0_PD, 0);
|
||||
rt2x00_set_field8(&rfcsr, RFCSR1_TX0_PD, 0);
|
||||
rt2x00_set_field8(&rfcsr, RFCSR1_RX1_PD, 0);
|
||||
rt2x00_set_field8(&rfcsr, RFCSR1_TX1_PD, 0);
|
||||
if (test_bit(CAPABILITY_BT_COEXIST, &rt2x00dev->cap_flags)) {
|
||||
if (rf->channel <= 14) {
|
||||
rt2x00_set_field8(&rfcsr, RFCSR1_RX0_PD, 1);
|
||||
rt2x00_set_field8(&rfcsr, RFCSR1_TX0_PD, 1);
|
||||
}
|
||||
rt2x00_set_field8(&rfcsr, RFCSR1_RX2_PD, 1);
|
||||
rt2x00_set_field8(&rfcsr, RFCSR1_TX2_PD, 1);
|
||||
} else {
|
||||
switch (rt2x00dev->default_ant.tx_chain_num) {
|
||||
case 1:
|
||||
rt2x00_set_field8(&rfcsr, RFCSR1_TX1_PD, 1);
|
||||
case 2:
|
||||
rt2x00_set_field8(&rfcsr, RFCSR1_TX2_PD, 1);
|
||||
break;
|
||||
}
|
||||
|
||||
switch (rt2x00dev->default_ant.rx_chain_num) {
|
||||
case 1:
|
||||
rt2x00_set_field8(&rfcsr, RFCSR1_RX1_PD, 1);
|
||||
case 2:
|
||||
rt2x00_set_field8(&rfcsr, RFCSR1_RX2_PD, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
rt2800_rfcsr_write(rt2x00dev, 1, rfcsr);
|
||||
|
||||
rt2800_rfcsr_read(rt2x00dev, 23, &rfcsr);
|
||||
rt2x00_set_field8(&rfcsr, RFCSR23_FREQ_OFFSET, rt2x00dev->freq_offset);
|
||||
rt2800_rfcsr_write(rt2x00dev, 23, rfcsr);
|
||||
|
||||
rt2800_rfcsr_write(rt2x00dev, 24,
|
||||
rt2x00dev->calibration[conf_is_ht40(conf)]);
|
||||
rt2800_rfcsr_write(rt2x00dev, 31,
|
||||
rt2x00dev->calibration[conf_is_ht40(conf)]);
|
||||
|
||||
if (rf->channel <= 14) {
|
||||
rt2800_rfcsr_write(rt2x00dev, 7, 0xd8);
|
||||
rt2800_rfcsr_write(rt2x00dev, 9, 0xc3);
|
||||
rt2800_rfcsr_write(rt2x00dev, 10, 0xf1);
|
||||
rt2800_rfcsr_write(rt2x00dev, 11, 0xb9);
|
||||
rt2800_rfcsr_write(rt2x00dev, 15, 0x53);
|
||||
rt2800_rfcsr_write(rt2x00dev, 16, 0x4c);
|
||||
rt2800_rfcsr_write(rt2x00dev, 17, 0x23);
|
||||
rt2800_rfcsr_write(rt2x00dev, 19, 0x93);
|
||||
rt2800_rfcsr_write(rt2x00dev, 20, 0xb3);
|
||||
rt2800_rfcsr_write(rt2x00dev, 25, 0x15);
|
||||
rt2800_rfcsr_write(rt2x00dev, 26, 0x85);
|
||||
rt2800_rfcsr_write(rt2x00dev, 27, 0x00);
|
||||
rt2800_rfcsr_write(rt2x00dev, 29, 0x9b);
|
||||
} else {
|
||||
rt2800_rfcsr_write(rt2x00dev, 7, 0x14);
|
||||
rt2800_rfcsr_write(rt2x00dev, 9, 0xc0);
|
||||
rt2800_rfcsr_write(rt2x00dev, 10, 0xf1);
|
||||
rt2800_rfcsr_write(rt2x00dev, 11, 0x00);
|
||||
rt2800_rfcsr_write(rt2x00dev, 15, 0x43);
|
||||
rt2800_rfcsr_write(rt2x00dev, 16, 0x7a);
|
||||
rt2800_rfcsr_write(rt2x00dev, 17, 0x23);
|
||||
if (rf->channel <= 64) {
|
||||
rt2800_rfcsr_write(rt2x00dev, 19, 0xb7);
|
||||
rt2800_rfcsr_write(rt2x00dev, 20, 0xf6);
|
||||
rt2800_rfcsr_write(rt2x00dev, 25, 0x3d);
|
||||
} else if (rf->channel <= 128) {
|
||||
rt2800_rfcsr_write(rt2x00dev, 19, 0x74);
|
||||
rt2800_rfcsr_write(rt2x00dev, 20, 0xf4);
|
||||
rt2800_rfcsr_write(rt2x00dev, 25, 0x01);
|
||||
} else {
|
||||
rt2800_rfcsr_write(rt2x00dev, 19, 0x72);
|
||||
rt2800_rfcsr_write(rt2x00dev, 20, 0xf3);
|
||||
rt2800_rfcsr_write(rt2x00dev, 25, 0x01);
|
||||
}
|
||||
rt2800_rfcsr_write(rt2x00dev, 26, 0x87);
|
||||
rt2800_rfcsr_write(rt2x00dev, 27, 0x01);
|
||||
rt2800_rfcsr_write(rt2x00dev, 29, 0x9f);
|
||||
}
|
||||
|
||||
rt2800_register_read(rt2x00dev, GPIO_CTRL_CFG, ®);
|
||||
rt2x00_set_field32(®, GPIO_CTRL_CFG_GPIOD_BIT7, 0);
|
||||
if (rf->channel <= 14)
|
||||
rt2x00_set_field32(®, GPIO_CTRL_CFG_BIT7, 1);
|
||||
else
|
||||
rt2x00_set_field32(®, GPIO_CTRL_CFG_BIT7, 0);
|
||||
rt2800_register_write(rt2x00dev, GPIO_CTRL_CFG, reg);
|
||||
|
||||
rt2800_rfcsr_read(rt2x00dev, 7, &rfcsr);
|
||||
rt2x00_set_field8(&rfcsr, RFCSR7_RF_TUNING, 1);
|
||||
rt2800_rfcsr_write(rt2x00dev, 7, rfcsr);
|
||||
}
|
||||
|
||||
#define RT5390_POWER_BOUND 0x27
|
||||
#define RT5390_FREQ_OFFSET_BOUND 0x5f
|
||||
@ -1748,9 +1872,10 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev,
|
||||
rt2x00_rf(rt2x00dev, RF3020) ||
|
||||
rt2x00_rf(rt2x00dev, RF3021) ||
|
||||
rt2x00_rf(rt2x00dev, RF3022) ||
|
||||
rt2x00_rf(rt2x00dev, RF3052) ||
|
||||
rt2x00_rf(rt2x00dev, RF3320))
|
||||
rt2800_config_channel_rf3xxx(rt2x00dev, conf, rf, info);
|
||||
else if (rt2x00_rf(rt2x00dev, RF3052))
|
||||
rt2800_config_channel_rf3052(rt2x00dev, conf, rf, info);
|
||||
else if (rt2x00_rf(rt2x00dev, RF5370) ||
|
||||
rt2x00_rf(rt2x00dev, RF5390))
|
||||
rt2800_config_channel_rf53xx(rt2x00dev, conf, rf, info);
|
||||
@ -1777,7 +1902,10 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev,
|
||||
}
|
||||
}
|
||||
} else {
|
||||
rt2800_bbp_write(rt2x00dev, 82, 0xf2);
|
||||
if (rt2x00_rt(rt2x00dev, RT3572))
|
||||
rt2800_bbp_write(rt2x00dev, 82, 0x94);
|
||||
else
|
||||
rt2800_bbp_write(rt2x00dev, 82, 0xf2);
|
||||
|
||||
if (test_bit(CAPABILITY_EXTERNAL_LNA_A, &rt2x00dev->cap_flags))
|
||||
rt2800_bbp_write(rt2x00dev, 75, 0x46);
|
||||
@ -1791,12 +1919,17 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev,
|
||||
rt2x00_set_field32(®, TX_BAND_CFG_BG, rf->channel <= 14);
|
||||
rt2800_register_write(rt2x00dev, TX_BAND_CFG, reg);
|
||||
|
||||
if (rt2x00_rt(rt2x00dev, RT3572))
|
||||
rt2800_rfcsr_write(rt2x00dev, 8, 0);
|
||||
|
||||
tx_pin = 0;
|
||||
|
||||
/* Turn on unused PA or LNA when not using 1T or 1R */
|
||||
if (rt2x00dev->default_ant.tx_chain_num == 2) {
|
||||
rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_A1_EN, 1);
|
||||
rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_G1_EN, 1);
|
||||
rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_A1_EN,
|
||||
rf->channel > 14);
|
||||
rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_G1_EN,
|
||||
rf->channel <= 14);
|
||||
}
|
||||
|
||||
/* Turn on unused PA or LNA when not using 1T or 1R */
|
||||
@ -1809,11 +1942,18 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev,
|
||||
rt2x00_set_field32(&tx_pin, TX_PIN_CFG_LNA_PE_G0_EN, 1);
|
||||
rt2x00_set_field32(&tx_pin, TX_PIN_CFG_RFTR_EN, 1);
|
||||
rt2x00_set_field32(&tx_pin, TX_PIN_CFG_TRSW_EN, 1);
|
||||
rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_G0_EN, rf->channel <= 14);
|
||||
if (test_bit(CAPABILITY_BT_COEXIST, &rt2x00dev->cap_flags))
|
||||
rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_G0_EN, 1);
|
||||
else
|
||||
rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_G0_EN,
|
||||
rf->channel <= 14);
|
||||
rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_A0_EN, rf->channel > 14);
|
||||
|
||||
rt2800_register_write(rt2x00dev, TX_PIN_CFG, tx_pin);
|
||||
|
||||
if (rt2x00_rt(rt2x00dev, RT3572))
|
||||
rt2800_rfcsr_write(rt2x00dev, 8, 0x80);
|
||||
|
||||
rt2800_bbp_read(rt2x00dev, 4, &bbp);
|
||||
rt2x00_set_field8(&bbp, BBP4_BANDWIDTH, 2 * conf_is_ht40(conf));
|
||||
rt2800_bbp_write(rt2x00dev, 4, bbp);
|
||||
@ -2413,6 +2553,9 @@ static int rt2800_init_registers(struct rt2x00_dev *rt2x00dev)
|
||||
rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000400);
|
||||
rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00000000);
|
||||
rt2800_register_write(rt2x00dev, TX_SW_CFG2, 0x00000030);
|
||||
} else if (rt2x00_rt(rt2x00dev, RT3572)) {
|
||||
rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000400);
|
||||
rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00080606);
|
||||
} else if (rt2x00_rt(rt2x00dev, RT5390)) {
|
||||
rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000404);
|
||||
rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00080606);
|
||||
@ -2799,6 +2942,7 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev)
|
||||
}
|
||||
|
||||
if (rt2800_is_305x_soc(rt2x00dev) ||
|
||||
rt2x00_rt(rt2x00dev, RT3572) ||
|
||||
rt2x00_rt(rt2x00dev, RT5390))
|
||||
rt2800_bbp_write(rt2x00dev, 31, 0x08);
|
||||
|
||||
@ -2828,6 +2972,7 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev)
|
||||
rt2x00_rt(rt2x00dev, RT3071) ||
|
||||
rt2x00_rt(rt2x00dev, RT3090) ||
|
||||
rt2x00_rt(rt2x00dev, RT3390) ||
|
||||
rt2x00_rt(rt2x00dev, RT3572) ||
|
||||
rt2x00_rt(rt2x00dev, RT5390)) {
|
||||
rt2800_bbp_write(rt2x00dev, 79, 0x13);
|
||||
rt2800_bbp_write(rt2x00dev, 80, 0x05);
|
||||
@ -2868,6 +3013,7 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev)
|
||||
rt2x00_rt_rev_gte(rt2x00dev, RT3071, REV_RT3071E) ||
|
||||
rt2x00_rt_rev_gte(rt2x00dev, RT3090, REV_RT3090E) ||
|
||||
rt2x00_rt_rev_gte(rt2x00dev, RT3390, REV_RT3390E) ||
|
||||
rt2x00_rt(rt2x00dev, RT3572) ||
|
||||
rt2x00_rt(rt2x00dev, RT5390) ||
|
||||
rt2800_is_305x_soc(rt2x00dev))
|
||||
rt2800_bbp_write(rt2x00dev, 103, 0xc0);
|
||||
@ -2895,6 +3041,7 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev)
|
||||
if (rt2x00_rt(rt2x00dev, RT3071) ||
|
||||
rt2x00_rt(rt2x00dev, RT3090) ||
|
||||
rt2x00_rt(rt2x00dev, RT3390) ||
|
||||
rt2x00_rt(rt2x00dev, RT3572) ||
|
||||
rt2x00_rt(rt2x00dev, RT5390)) {
|
||||
rt2800_bbp_read(rt2x00dev, 138, &value);
|
||||
|
||||
@ -3031,6 +3178,7 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
|
||||
!rt2x00_rt(rt2x00dev, RT3071) &&
|
||||
!rt2x00_rt(rt2x00dev, RT3090) &&
|
||||
!rt2x00_rt(rt2x00dev, RT3390) &&
|
||||
!rt2x00_rt(rt2x00dev, RT3572) &&
|
||||
!rt2x00_rt(rt2x00dev, RT5390) &&
|
||||
!rt2800_is_305x_soc(rt2x00dev))
|
||||
return 0;
|
||||
@ -3109,6 +3257,38 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
|
||||
rt2800_rfcsr_write(rt2x00dev, 29, 0x8f);
|
||||
rt2800_rfcsr_write(rt2x00dev, 30, 0x20);
|
||||
rt2800_rfcsr_write(rt2x00dev, 31, 0x0f);
|
||||
} else if (rt2x00_rt(rt2x00dev, RT3572)) {
|
||||
rt2800_rfcsr_write(rt2x00dev, 0, 0x70);
|
||||
rt2800_rfcsr_write(rt2x00dev, 1, 0x81);
|
||||
rt2800_rfcsr_write(rt2x00dev, 2, 0xf1);
|
||||
rt2800_rfcsr_write(rt2x00dev, 3, 0x02);
|
||||
rt2800_rfcsr_write(rt2x00dev, 4, 0x4c);
|
||||
rt2800_rfcsr_write(rt2x00dev, 5, 0x05);
|
||||
rt2800_rfcsr_write(rt2x00dev, 6, 0x4a);
|
||||
rt2800_rfcsr_write(rt2x00dev, 7, 0xd8);
|
||||
rt2800_rfcsr_write(rt2x00dev, 9, 0xc3);
|
||||
rt2800_rfcsr_write(rt2x00dev, 10, 0xf1);
|
||||
rt2800_rfcsr_write(rt2x00dev, 11, 0xb9);
|
||||
rt2800_rfcsr_write(rt2x00dev, 12, 0x70);
|
||||
rt2800_rfcsr_write(rt2x00dev, 13, 0x65);
|
||||
rt2800_rfcsr_write(rt2x00dev, 14, 0xa0);
|
||||
rt2800_rfcsr_write(rt2x00dev, 15, 0x53);
|
||||
rt2800_rfcsr_write(rt2x00dev, 16, 0x4c);
|
||||
rt2800_rfcsr_write(rt2x00dev, 17, 0x23);
|
||||
rt2800_rfcsr_write(rt2x00dev, 18, 0xac);
|
||||
rt2800_rfcsr_write(rt2x00dev, 19, 0x93);
|
||||
rt2800_rfcsr_write(rt2x00dev, 20, 0xb3);
|
||||
rt2800_rfcsr_write(rt2x00dev, 21, 0xd0);
|
||||
rt2800_rfcsr_write(rt2x00dev, 22, 0x00);
|
||||
rt2800_rfcsr_write(rt2x00dev, 23, 0x3c);
|
||||
rt2800_rfcsr_write(rt2x00dev, 24, 0x16);
|
||||
rt2800_rfcsr_write(rt2x00dev, 25, 0x15);
|
||||
rt2800_rfcsr_write(rt2x00dev, 26, 0x85);
|
||||
rt2800_rfcsr_write(rt2x00dev, 27, 0x00);
|
||||
rt2800_rfcsr_write(rt2x00dev, 28, 0x00);
|
||||
rt2800_rfcsr_write(rt2x00dev, 29, 0x9b);
|
||||
rt2800_rfcsr_write(rt2x00dev, 30, 0x09);
|
||||
rt2800_rfcsr_write(rt2x00dev, 31, 0x10);
|
||||
} else if (rt2800_is_305x_soc(rt2x00dev)) {
|
||||
rt2800_rfcsr_write(rt2x00dev, 0, 0x50);
|
||||
rt2800_rfcsr_write(rt2x00dev, 1, 0x01);
|
||||
@ -3258,6 +3438,19 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
|
||||
rt2800_register_read(rt2x00dev, GPIO_SWITCH, ®);
|
||||
rt2x00_set_field32(®, GPIO_SWITCH_5, 0);
|
||||
rt2800_register_write(rt2x00dev, GPIO_SWITCH, reg);
|
||||
} else if (rt2x00_rt(rt2x00dev, RT3572)) {
|
||||
rt2800_rfcsr_read(rt2x00dev, 6, &rfcsr);
|
||||
rt2x00_set_field8(&rfcsr, RFCSR6_R2, 1);
|
||||
rt2800_rfcsr_write(rt2x00dev, 6, rfcsr);
|
||||
|
||||
rt2800_register_read(rt2x00dev, LDO_CFG0, ®);
|
||||
rt2x00_set_field32(®, LDO_CFG0_LDO_CORE_VLEVEL, 3);
|
||||
rt2x00_set_field32(®, LDO_CFG0_BGSEL, 1);
|
||||
rt2800_register_write(rt2x00dev, LDO_CFG0, reg);
|
||||
msleep(1);
|
||||
rt2800_register_read(rt2x00dev, LDO_CFG0, ®);
|
||||
rt2x00_set_field32(®, LDO_CFG0_BGSEL, 1);
|
||||
rt2800_register_write(rt2x00dev, LDO_CFG0, reg);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -3270,7 +3463,8 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
|
||||
rt2800_init_rx_filter(rt2x00dev, true, 0x27, 0x19);
|
||||
} else if (rt2x00_rt(rt2x00dev, RT3071) ||
|
||||
rt2x00_rt(rt2x00dev, RT3090) ||
|
||||
rt2x00_rt(rt2x00dev, RT3390)) {
|
||||
rt2x00_rt(rt2x00dev, RT3390) ||
|
||||
rt2x00_rt(rt2x00dev, RT3572)) {
|
||||
rt2x00dev->calibration[0] =
|
||||
rt2800_init_rx_filter(rt2x00dev, false, 0x07, 0x13);
|
||||
rt2x00dev->calibration[1] =
|
||||
|
@ -152,7 +152,6 @@ void rt2800_write_tx_data(struct queue_entry *entry,
|
||||
struct txentry_desc *txdesc);
|
||||
void rt2800_process_rxwi(struct queue_entry *entry, struct rxdone_entry_desc *txdesc);
|
||||
|
||||
void rt2800_txdone(struct rt2x00_dev *rt2x00dev);
|
||||
void rt2800_txdone_entry(struct queue_entry *entry, u32 status);
|
||||
|
||||
void rt2800_write_beacon(struct queue_entry *entry, struct txentry_desc *txdesc);
|
||||
|
@ -501,7 +501,9 @@ static int rt2800pci_init_registers(struct rt2x00_dev *rt2x00dev)
|
||||
rt2x00pci_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000e1f);
|
||||
rt2x00pci_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000e00);
|
||||
|
||||
if (rt2x00_rt(rt2x00dev, RT5390)) {
|
||||
if (rt2x00_is_pcie(rt2x00dev) &&
|
||||
(rt2x00_rt(rt2x00dev, RT3572) ||
|
||||
rt2x00_rt(rt2x00dev, RT5390))) {
|
||||
rt2x00pci_register_read(rt2x00dev, AUX_CTRL, ®);
|
||||
rt2x00_set_field32(®, AUX_CTRL_FORCE_PCIE_CLK, 1);
|
||||
rt2x00_set_field32(®, AUX_CTRL_WAKE_PCIE_EN, 1);
|
||||
|
@ -457,6 +457,87 @@ static int rt2800usb_get_tx_data_len(struct queue_entry *entry)
|
||||
/*
|
||||
* TX control handlers
|
||||
*/
|
||||
static bool rt2800usb_txdone_entry_check(struct queue_entry *entry, u32 reg)
|
||||
{
|
||||
__le32 *txwi;
|
||||
u32 word;
|
||||
int wcid, ack, pid;
|
||||
int tx_wcid, tx_ack, tx_pid;
|
||||
|
||||
wcid = rt2x00_get_field32(reg, TX_STA_FIFO_WCID);
|
||||
ack = rt2x00_get_field32(reg, TX_STA_FIFO_TX_ACK_REQUIRED);
|
||||
pid = rt2x00_get_field32(reg, TX_STA_FIFO_PID_TYPE);
|
||||
|
||||
/*
|
||||
* This frames has returned with an IO error,
|
||||
* so the status report is not intended for this
|
||||
* frame.
|
||||
*/
|
||||
if (test_bit(ENTRY_DATA_IO_FAILED, &entry->flags)) {
|
||||
rt2x00lib_txdone_noinfo(entry, TXDONE_FAILURE);
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Validate if this TX status report is intended for
|
||||
* this entry by comparing the WCID/ACK/PID fields.
|
||||
*/
|
||||
txwi = rt2800usb_get_txwi(entry);
|
||||
|
||||
rt2x00_desc_read(txwi, 1, &word);
|
||||
tx_wcid = rt2x00_get_field32(word, TXWI_W1_WIRELESS_CLI_ID);
|
||||
tx_ack = rt2x00_get_field32(word, TXWI_W1_ACK);
|
||||
tx_pid = rt2x00_get_field32(word, TXWI_W1_PACKETID);
|
||||
|
||||
if ((wcid != tx_wcid) || (ack != tx_ack) || (pid != tx_pid)) {
|
||||
WARNING(entry->queue->rt2x00dev,
|
||||
"TX status report missed for queue %d entry %d\n",
|
||||
entry->queue->qid, entry->entry_idx);
|
||||
rt2x00lib_txdone_noinfo(entry, TXDONE_UNKNOWN);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void rt2800usb_txdone(struct rt2x00_dev *rt2x00dev)
|
||||
{
|
||||
struct data_queue *queue;
|
||||
struct queue_entry *entry;
|
||||
u32 reg;
|
||||
u8 qid;
|
||||
|
||||
while (kfifo_get(&rt2x00dev->txstatus_fifo, ®)) {
|
||||
|
||||
/* TX_STA_FIFO_PID_QUEUE is a 2-bit field, thus
|
||||
* qid is guaranteed to be one of the TX QIDs
|
||||
*/
|
||||
qid = rt2x00_get_field32(reg, TX_STA_FIFO_PID_QUEUE);
|
||||
queue = rt2x00queue_get_tx_queue(rt2x00dev, qid);
|
||||
if (unlikely(!queue)) {
|
||||
WARNING(rt2x00dev, "Got TX status for an unavailable "
|
||||
"queue %u, dropping\n", qid);
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* Inside each queue, we process each entry in a chronological
|
||||
* order. We first check that the queue is not empty.
|
||||
*/
|
||||
entry = NULL;
|
||||
while (!rt2x00queue_empty(queue)) {
|
||||
entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE);
|
||||
if (rt2800usb_txdone_entry_check(entry, reg))
|
||||
break;
|
||||
}
|
||||
|
||||
if (!entry || rt2x00queue_empty(queue))
|
||||
break;
|
||||
|
||||
rt2800_txdone_entry(entry, reg);
|
||||
}
|
||||
}
|
||||
|
||||
static void rt2800usb_work_txdone(struct work_struct *work)
|
||||
{
|
||||
struct rt2x00_dev *rt2x00dev =
|
||||
@ -464,7 +545,7 @@ static void rt2800usb_work_txdone(struct work_struct *work)
|
||||
struct data_queue *queue;
|
||||
struct queue_entry *entry;
|
||||
|
||||
rt2800_txdone(rt2x00dev);
|
||||
rt2800usb_txdone(rt2x00dev);
|
||||
|
||||
/*
|
||||
* Process any trailing TX status reports for IO failures,
|
||||
|
@ -250,7 +250,8 @@ void rt2x00lib_config(struct rt2x00_dev *rt2x00dev,
|
||||
if (ieee80211_flags & IEEE80211_CONF_CHANGE_CHANNEL)
|
||||
rt2x00link_reset_tuner(rt2x00dev, false);
|
||||
|
||||
if (test_bit(REQUIRE_PS_AUTOWAKE, &rt2x00dev->cap_flags) &&
|
||||
if (test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags) &&
|
||||
test_bit(REQUIRE_PS_AUTOWAKE, &rt2x00dev->cap_flags) &&
|
||||
(ieee80211_flags & IEEE80211_CONF_CHANGE_PS) &&
|
||||
(conf->flags & IEEE80211_CONF_PS)) {
|
||||
beacon_diff = (long)jiffies - (long)rt2x00dev->last_beacon;
|
||||
|
@ -146,6 +146,9 @@ static void rt2x00lib_autowakeup(struct work_struct *work)
|
||||
struct rt2x00_dev *rt2x00dev =
|
||||
container_of(work, struct rt2x00_dev, autowakeup_work.work);
|
||||
|
||||
if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags))
|
||||
return;
|
||||
|
||||
if (rt2x00dev->ops->lib->set_device_state(rt2x00dev, STATE_AWAKE))
|
||||
ERROR(rt2x00dev, "Device failed to wakeup.\n");
|
||||
clear_bit(CONFIG_POWERSAVING, &rt2x00dev->flags);
|
||||
@ -1160,6 +1163,7 @@ void rt2x00lib_remove_dev(struct rt2x00_dev *rt2x00dev)
|
||||
* Stop all work.
|
||||
*/
|
||||
cancel_work_sync(&rt2x00dev->intf_work);
|
||||
cancel_delayed_work_sync(&rt2x00dev->autowakeup_work);
|
||||
if (rt2x00_is_usb(rt2x00dev)) {
|
||||
del_timer_sync(&rt2x00dev->txstatus_timer);
|
||||
cancel_work_sync(&rt2x00dev->rxdone_work);
|
||||
|
@ -206,7 +206,6 @@ static void rt2x00queue_create_tx_descriptor_seq(struct queue_entry *entry,
|
||||
struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(entry->skb);
|
||||
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)entry->skb->data;
|
||||
struct rt2x00_intf *intf = vif_to_intf(tx_info->control.vif);
|
||||
unsigned long irqflags;
|
||||
|
||||
if (!(tx_info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ))
|
||||
return;
|
||||
@ -227,14 +226,14 @@ static void rt2x00queue_create_tx_descriptor_seq(struct queue_entry *entry,
|
||||
* sequence counting per-frame, since those will override the
|
||||
* sequence counter given by mac80211.
|
||||
*/
|
||||
spin_lock_irqsave(&intf->seqlock, irqflags);
|
||||
spin_lock(&intf->seqlock);
|
||||
|
||||
if (test_bit(ENTRY_TXD_FIRST_FRAGMENT, &txdesc->flags))
|
||||
intf->seqno += 0x10;
|
||||
hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG);
|
||||
hdr->seq_ctrl |= cpu_to_le16(intf->seqno);
|
||||
|
||||
spin_unlock_irqrestore(&intf->seqlock, irqflags);
|
||||
spin_unlock(&intf->seqlock);
|
||||
|
||||
}
|
||||
|
||||
|
@ -888,7 +888,6 @@ int rtl_tx_agg_stop(struct ieee80211_hw *hw,
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
|
||||
struct rtl_tid_data *tid_data;
|
||||
struct rtl_sta_info *sta_entry = NULL;
|
||||
|
||||
if (sta == NULL)
|
||||
@ -906,7 +905,6 @@ int rtl_tx_agg_stop(struct ieee80211_hw *hw,
|
||||
return -EINVAL;
|
||||
|
||||
sta_entry = (struct rtl_sta_info *)sta->drv_priv;
|
||||
tid_data = &sta_entry->tids[tid];
|
||||
sta_entry->tids[tid].agg.agg_state = RTL_AGG_STOP;
|
||||
|
||||
ieee80211_stop_tx_ba_cb_irqsafe(mac->vif, sta->addr, tid);
|
||||
@ -918,7 +916,6 @@ int rtl_tx_agg_oper(struct ieee80211_hw *hw,
|
||||
struct ieee80211_sta *sta, u16 tid)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
struct rtl_tid_data *tid_data;
|
||||
struct rtl_sta_info *sta_entry = NULL;
|
||||
|
||||
if (sta == NULL)
|
||||
@ -936,7 +933,6 @@ int rtl_tx_agg_oper(struct ieee80211_hw *hw,
|
||||
return -EINVAL;
|
||||
|
||||
sta_entry = (struct rtl_sta_info *)sta->drv_priv;
|
||||
tid_data = &sta_entry->tids[tid];
|
||||
sta_entry->tids[tid].agg.agg_state = RTL_AGG_OPERATIONAL;
|
||||
|
||||
return 0;
|
||||
|
@ -925,7 +925,7 @@ static int efuse_pg_packet_write(struct ieee80211_hw *hw,
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
struct pgpkt_struct target_pkt;
|
||||
u8 write_state = PG_STATE_HEADER;
|
||||
int continual = true, dataempty = true, result = true;
|
||||
int continual = true, result = true;
|
||||
u16 efuse_addr = 0;
|
||||
u8 efuse_data;
|
||||
u8 target_word_cnts = 0;
|
||||
@ -953,7 +953,6 @@ static int efuse_pg_packet_write(struct ieee80211_hw *hw,
|
||||
(EFUSE_MAX_SIZE - EFUSE_OOB_PROTECT_BYTES))) {
|
||||
|
||||
if (write_state == PG_STATE_HEADER) {
|
||||
dataempty = true;
|
||||
badworden = 0x0F;
|
||||
RTPRINT(rtlpriv, FEEPROM, EFUSE_PG,
|
||||
("efuse PG_STATE_HEADER\n"));
|
||||
@ -1176,13 +1175,12 @@ static u16 efuse_get_current_size(struct ieee80211_hw *hw)
|
||||
{
|
||||
int continual = true;
|
||||
u16 efuse_addr = 0;
|
||||
u8 hoffset, hworden;
|
||||
u8 hworden;
|
||||
u8 efuse_data, word_cnts;
|
||||
|
||||
while (continual && efuse_one_byte_read(hw, efuse_addr, &efuse_data)
|
||||
&& (efuse_addr < EFUSE_MAX_SIZE)) {
|
||||
if (efuse_data != 0xFF) {
|
||||
hoffset = (efuse_data >> 4) & 0x0F;
|
||||
hworden = efuse_data & 0x0F;
|
||||
word_cnts = efuse_calculate_word_cnts(hworden);
|
||||
efuse_addr = efuse_addr + (word_cnts * 2) + 1;
|
||||
|
@ -622,7 +622,7 @@ tx_status_ok:
|
||||
if (((rtlpriv->link_info.num_rx_inperiod +
|
||||
rtlpriv->link_info.num_tx_inperiod) > 8) ||
|
||||
(rtlpriv->link_info.num_rx_inperiod > 2)) {
|
||||
rtl_lps_leave(hw);
|
||||
tasklet_schedule(&rtlpriv->works.ips_leave_tasklet);
|
||||
}
|
||||
}
|
||||
|
||||
@ -644,22 +644,23 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw)
|
||||
.noise = -98,
|
||||
.rate = 0,
|
||||
};
|
||||
int index = rtlpci->rx_ring[rx_queue_idx].idx;
|
||||
|
||||
/*RX NORMAL PKT */
|
||||
while (count--) {
|
||||
/*rx descriptor */
|
||||
struct rtl_rx_desc *pdesc = &rtlpci->rx_ring[rx_queue_idx].desc[
|
||||
rtlpci->rx_ring[rx_queue_idx].idx];
|
||||
index];
|
||||
/*rx pkt */
|
||||
struct sk_buff *skb = rtlpci->rx_ring[rx_queue_idx].rx_buf[
|
||||
rtlpci->rx_ring[rx_queue_idx].idx];
|
||||
index];
|
||||
|
||||
own = (u8) rtlpriv->cfg->ops->get_desc((u8 *) pdesc,
|
||||
false, HW_DESC_OWN);
|
||||
|
||||
if (own) {
|
||||
/*wait data to be filled by hardware */
|
||||
return;
|
||||
break;
|
||||
} else {
|
||||
struct ieee80211_hdr *hdr;
|
||||
__le16 fc;
|
||||
@ -700,7 +701,7 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw)
|
||||
rtlpci->rxbuffersize,
|
||||
PCI_DMA_FROMDEVICE);
|
||||
|
||||
if (!stats.crc || !stats.hwerror) {
|
||||
if (!stats.crc && !stats.hwerror) {
|
||||
memcpy(IEEE80211_SKB_RXCB(skb), &rx_status,
|
||||
sizeof(rx_status));
|
||||
|
||||
@ -765,15 +766,12 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw)
|
||||
if (((rtlpriv->link_info.num_rx_inperiod +
|
||||
rtlpriv->link_info.num_tx_inperiod) > 8) ||
|
||||
(rtlpriv->link_info.num_rx_inperiod > 2)) {
|
||||
rtl_lps_leave(hw);
|
||||
tasklet_schedule(&rtlpriv->works.ips_leave_tasklet);
|
||||
}
|
||||
|
||||
skb = new_skb;
|
||||
|
||||
rtlpci->rx_ring[rx_queue_idx].rx_buf[rtlpci->
|
||||
rx_ring
|
||||
[rx_queue_idx].
|
||||
idx] = skb;
|
||||
rtlpci->rx_ring[rx_queue_idx].rx_buf[index] = skb;
|
||||
*((dma_addr_t *) skb->cb) =
|
||||
pci_map_single(rtlpci->pdev, skb_tail_pointer(skb),
|
||||
rtlpci->rxbuffersize,
|
||||
@ -786,23 +784,22 @@ done:
|
||||
rtlpriv->cfg->ops->set_desc((u8 *) pdesc, false,
|
||||
HW_DESC_RXBUFF_ADDR,
|
||||
(u8 *)&bufferaddress);
|
||||
rtlpriv->cfg->ops->set_desc((u8 *)pdesc, false, HW_DESC_RXOWN,
|
||||
(u8 *)&tmp_one);
|
||||
rtlpriv->cfg->ops->set_desc((u8 *)pdesc, false,
|
||||
HW_DESC_RXPKT_LEN,
|
||||
(u8 *)&rtlpci->rxbuffersize);
|
||||
|
||||
if (rtlpci->rx_ring[rx_queue_idx].idx ==
|
||||
rtlpci->rxringcount - 1)
|
||||
if (index == rtlpci->rxringcount - 1)
|
||||
rtlpriv->cfg->ops->set_desc((u8 *)pdesc, false,
|
||||
HW_DESC_RXERO,
|
||||
(u8 *)&tmp_one);
|
||||
|
||||
rtlpci->rx_ring[rx_queue_idx].idx =
|
||||
(rtlpci->rx_ring[rx_queue_idx].idx + 1) %
|
||||
rtlpci->rxringcount;
|
||||
rtlpriv->cfg->ops->set_desc((u8 *)pdesc, false, HW_DESC_RXOWN,
|
||||
(u8 *)&tmp_one);
|
||||
|
||||
index = (index + 1) % rtlpci->rxringcount;
|
||||
}
|
||||
|
||||
rtlpci->rx_ring[rx_queue_idx].idx = index;
|
||||
}
|
||||
|
||||
static irqreturn_t _rtl_pci_interrupt(int irq, void *dev_id)
|
||||
@ -940,6 +937,11 @@ static void _rtl_pci_irq_tasklet(struct ieee80211_hw *hw)
|
||||
_rtl_pci_tx_chk_waitq(hw);
|
||||
}
|
||||
|
||||
static void _rtl_pci_ips_leave_tasklet(struct ieee80211_hw *hw)
|
||||
{
|
||||
rtl_lps_leave(hw);
|
||||
}
|
||||
|
||||
static void _rtl_pci_prepare_bcn_tasklet(struct ieee80211_hw *hw)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
@ -1038,6 +1040,9 @@ static void _rtl_pci_init_struct(struct ieee80211_hw *hw,
|
||||
tasklet_init(&rtlpriv->works.irq_prepare_bcn_tasklet,
|
||||
(void (*)(unsigned long))_rtl_pci_prepare_bcn_tasklet,
|
||||
(unsigned long)hw);
|
||||
tasklet_init(&rtlpriv->works.ips_leave_tasklet,
|
||||
(void (*)(unsigned long))_rtl_pci_ips_leave_tasklet,
|
||||
(unsigned long)hw);
|
||||
}
|
||||
|
||||
static int _rtl_pci_init_tx_ring(struct ieee80211_hw *hw,
|
||||
@ -1507,6 +1512,7 @@ static void rtl_pci_deinit(struct ieee80211_hw *hw)
|
||||
|
||||
synchronize_irq(rtlpci->pdev->irq);
|
||||
tasklet_kill(&rtlpriv->works.irq_tasklet);
|
||||
tasklet_kill(&rtlpriv->works.ips_leave_tasklet);
|
||||
|
||||
flush_workqueue(rtlpriv->works.rtl_wq);
|
||||
destroy_workqueue(rtlpriv->works.rtl_wq);
|
||||
@ -1581,6 +1587,7 @@ static void rtl_pci_stop(struct ieee80211_hw *hw)
|
||||
set_hal_stop(rtlhal);
|
||||
|
||||
rtlpriv->cfg->ops->disable_interrupt(hw);
|
||||
tasklet_kill(&rtlpriv->works.ips_leave_tasklet);
|
||||
|
||||
spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flags);
|
||||
while (ppsc->rfchange_inprogress) {
|
||||
|
@ -68,6 +68,7 @@ bool rtl_ps_disable_nic(struct ieee80211_hw *hw)
|
||||
|
||||
/*<2> Disable Interrupt */
|
||||
rtlpriv->cfg->ops->disable_interrupt(hw);
|
||||
tasklet_kill(&rtlpriv->works.irq_tasklet);
|
||||
|
||||
/*<3> Disable Adapter */
|
||||
rtlpriv->cfg->ops->hw_disable(hw);
|
||||
@ -82,10 +83,8 @@ bool rtl_ps_set_rf_state(struct ieee80211_hw *hw,
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
|
||||
enum rf_pwrstate rtstate;
|
||||
bool actionallowed = false;
|
||||
u16 rfwait_cnt = 0;
|
||||
unsigned long flag;
|
||||
|
||||
/*protect_or_not = true; */
|
||||
|
||||
@ -98,10 +97,9 @@ bool rtl_ps_set_rf_state(struct ieee80211_hw *hw,
|
||||
*should wait to be executed.
|
||||
*/
|
||||
while (true) {
|
||||
spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flag);
|
||||
spin_lock(&rtlpriv->locks.rf_ps_lock);
|
||||
if (ppsc->rfchange_inprogress) {
|
||||
spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock,
|
||||
flag);
|
||||
spin_unlock(&rtlpriv->locks.rf_ps_lock);
|
||||
|
||||
RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
|
||||
("RF Change in progress!"
|
||||
@ -122,15 +120,12 @@ bool rtl_ps_set_rf_state(struct ieee80211_hw *hw,
|
||||
}
|
||||
} else {
|
||||
ppsc->rfchange_inprogress = true;
|
||||
spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock,
|
||||
flag);
|
||||
spin_unlock(&rtlpriv->locks.rf_ps_lock);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
no_protect:
|
||||
rtstate = ppsc->rfpwr_state;
|
||||
|
||||
switch (state_toset) {
|
||||
case ERFON:
|
||||
ppsc->rfoff_reason &= (~changesource);
|
||||
@ -173,9 +168,9 @@ no_protect:
|
||||
rtlpriv->cfg->ops->set_rf_power_state(hw, state_toset);
|
||||
|
||||
if (!protect_or_not) {
|
||||
spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flag);
|
||||
spin_lock(&rtlpriv->locks.rf_ps_lock);
|
||||
ppsc->rfchange_inprogress = false;
|
||||
spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag);
|
||||
spin_unlock(&rtlpriv->locks.rf_ps_lock);
|
||||
}
|
||||
|
||||
return actionallowed;
|
||||
@ -289,12 +284,11 @@ void rtl_ips_nic_on(struct ieee80211_hw *hw)
|
||||
struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
|
||||
struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
|
||||
enum rf_pwrstate rtstate;
|
||||
unsigned long flags;
|
||||
|
||||
if (mac->opmode != NL80211_IFTYPE_STATION)
|
||||
return;
|
||||
|
||||
spin_lock_irqsave(&rtlpriv->locks.ips_lock, flags);
|
||||
spin_lock(&rtlpriv->locks.ips_lock);
|
||||
|
||||
if (ppsc->inactiveps) {
|
||||
rtstate = ppsc->rfpwr_state;
|
||||
@ -310,7 +304,7 @@ void rtl_ips_nic_on(struct ieee80211_hw *hw)
|
||||
}
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(&rtlpriv->locks.ips_lock, flags);
|
||||
spin_unlock(&rtlpriv->locks.ips_lock);
|
||||
}
|
||||
|
||||
/*for FW LPS*/
|
||||
@ -428,7 +422,6 @@ void rtl_lps_enter(struct ieee80211_hw *hw)
|
||||
struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
|
||||
struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
unsigned long flag;
|
||||
|
||||
if (!ppsc->fwctrl_lps)
|
||||
return;
|
||||
@ -449,7 +442,7 @@ void rtl_lps_enter(struct ieee80211_hw *hw)
|
||||
if (mac->link_state != MAC80211_LINKED)
|
||||
return;
|
||||
|
||||
spin_lock_irqsave(&rtlpriv->locks.lps_lock, flag);
|
||||
spin_lock(&rtlpriv->locks.lps_lock);
|
||||
|
||||
/* Idle for a while if we connect to AP a while ago. */
|
||||
if (mac->cnt_after_linked >= 2) {
|
||||
@ -461,7 +454,7 @@ void rtl_lps_enter(struct ieee80211_hw *hw)
|
||||
}
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(&rtlpriv->locks.lps_lock, flag);
|
||||
spin_unlock(&rtlpriv->locks.lps_lock);
|
||||
}
|
||||
|
||||
/*Leave the leisure power save mode.*/
|
||||
@ -470,9 +463,8 @@ void rtl_lps_leave(struct ieee80211_hw *hw)
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
|
||||
struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
|
||||
unsigned long flag;
|
||||
|
||||
spin_lock_irqsave(&rtlpriv->locks.lps_lock, flag);
|
||||
spin_lock(&rtlpriv->locks.lps_lock);
|
||||
|
||||
if (ppsc->fwctrl_lps) {
|
||||
if (ppsc->dot11_psmode != EACTIVE) {
|
||||
@ -493,7 +485,7 @@ void rtl_lps_leave(struct ieee80211_hw *hw)
|
||||
rtl_lps_set_psmode(hw, EACTIVE);
|
||||
}
|
||||
}
|
||||
spin_unlock_irqrestore(&rtlpriv->locks.lps_lock, flag);
|
||||
spin_unlock(&rtlpriv->locks.lps_lock);
|
||||
}
|
||||
|
||||
/* For sw LPS*/
|
||||
@ -582,7 +574,6 @@ void rtl_swlps_rf_awake(struct ieee80211_hw *hw)
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
|
||||
struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
|
||||
unsigned long flag;
|
||||
|
||||
if (!rtlpriv->psc.swctrl_lps)
|
||||
return;
|
||||
@ -595,9 +586,9 @@ void rtl_swlps_rf_awake(struct ieee80211_hw *hw)
|
||||
RT_CLEAR_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM);
|
||||
}
|
||||
|
||||
spin_lock_irqsave(&rtlpriv->locks.lps_lock, flag);
|
||||
spin_lock(&rtlpriv->locks.lps_lock);
|
||||
rtl_ps_set_rf_state(hw, ERFON, RF_CHANGE_BY_PS, false);
|
||||
spin_unlock_irqrestore(&rtlpriv->locks.lps_lock, flag);
|
||||
spin_unlock(&rtlpriv->locks.lps_lock);
|
||||
}
|
||||
|
||||
void rtl_swlps_rfon_wq_callback(void *data)
|
||||
@ -614,7 +605,6 @@ void rtl_swlps_rf_sleep(struct ieee80211_hw *hw)
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
|
||||
struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
|
||||
unsigned long flag;
|
||||
u8 sleep_intv;
|
||||
|
||||
if (!rtlpriv->psc.sw_ps_enabled)
|
||||
@ -631,16 +621,16 @@ void rtl_swlps_rf_sleep(struct ieee80211_hw *hw)
|
||||
if (rtlpriv->link_info.busytraffic)
|
||||
return;
|
||||
|
||||
spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flag);
|
||||
spin_lock(&rtlpriv->locks.rf_ps_lock);
|
||||
if (rtlpriv->psc.rfchange_inprogress) {
|
||||
spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag);
|
||||
spin_unlock(&rtlpriv->locks.rf_ps_lock);
|
||||
return;
|
||||
}
|
||||
spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag);
|
||||
spin_unlock(&rtlpriv->locks.rf_ps_lock);
|
||||
|
||||
spin_lock_irqsave(&rtlpriv->locks.lps_lock, flag);
|
||||
spin_lock(&rtlpriv->locks.lps_lock);
|
||||
rtl_ps_set_rf_state(hw, ERFSLEEP, RF_CHANGE_BY_PS, false);
|
||||
spin_unlock_irqrestore(&rtlpriv->locks.lps_lock, flag);
|
||||
spin_unlock(&rtlpriv->locks.lps_lock);
|
||||
|
||||
if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_ASPM &&
|
||||
!RT_IN_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM)) {
|
||||
|
@ -303,22 +303,6 @@ static void _rtl_reg_apply_world_flags(struct wiphy *wiphy,
|
||||
return;
|
||||
}
|
||||
|
||||
static void _rtl_dump_channel_map(struct wiphy *wiphy)
|
||||
{
|
||||
enum ieee80211_band band;
|
||||
struct ieee80211_supported_band *sband;
|
||||
struct ieee80211_channel *ch;
|
||||
unsigned int i;
|
||||
|
||||
for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
|
||||
if (!wiphy->bands[band])
|
||||
continue;
|
||||
sband = wiphy->bands[band];
|
||||
for (i = 0; i < sband->n_channels; i++)
|
||||
ch = &sband->channels[i];
|
||||
}
|
||||
}
|
||||
|
||||
static int _rtl_reg_notifier_apply(struct wiphy *wiphy,
|
||||
struct regulatory_request *request,
|
||||
struct rtl_regulatory *reg)
|
||||
@ -336,8 +320,6 @@ static int _rtl_reg_notifier_apply(struct wiphy *wiphy,
|
||||
break;
|
||||
}
|
||||
|
||||
_rtl_dump_channel_map(wiphy);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -546,7 +546,6 @@ static bool _rtl92c_cmd_send_packet(struct ieee80211_hw *hw,
|
||||
struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
|
||||
struct rtl8192_tx_ring *ring;
|
||||
struct rtl_tx_desc *pdesc;
|
||||
u8 own;
|
||||
unsigned long flags;
|
||||
struct sk_buff *pskb = NULL;
|
||||
|
||||
@ -559,7 +558,6 @@ static bool _rtl92c_cmd_send_packet(struct ieee80211_hw *hw,
|
||||
spin_lock_irqsave(&rtlpriv->locks.irq_th_lock, flags);
|
||||
|
||||
pdesc = &ring->desc[0];
|
||||
own = (u8) rtlpriv->cfg->ops->get_desc((u8 *) pdesc, true, HW_DESC_OWN);
|
||||
|
||||
rtlpriv->cfg->ops->fill_tx_cmddesc(hw, (u8 *) pdesc, 1, 1, skb);
|
||||
|
||||
|
@ -1253,10 +1253,9 @@ static void _rtl92c_phy_iq_calibrate(struct ieee80211_hw *hw,
|
||||
|
||||
const u32 retrycount = 2;
|
||||
|
||||
u32 bbvalue;
|
||||
|
||||
if (t == 0) {
|
||||
bbvalue = rtl_get_bbreg(hw, 0x800, MASKDWORD);
|
||||
/* dummy read */
|
||||
rtl_get_bbreg(hw, 0x800, MASKDWORD);
|
||||
|
||||
_rtl92c_phy_save_adda_registers(hw, adda_reg,
|
||||
rtlphy->adda_backup, 16);
|
||||
@ -1762,8 +1761,7 @@ void rtl92c_phy_iq_calibrate(struct ieee80211_hw *hw, bool recovery)
|
||||
long result[4][8];
|
||||
u8 i, final_candidate;
|
||||
bool patha_ok, pathb_ok;
|
||||
long reg_e94, reg_e9c, reg_ea4, reg_eac, reg_eb4, reg_ebc, reg_ec4,
|
||||
reg_ecc, reg_tmp = 0;
|
||||
long reg_e94, reg_e9c, reg_ea4, reg_eb4, reg_ebc, reg_ec4, reg_tmp = 0;
|
||||
bool is12simular, is13simular, is23simular;
|
||||
bool start_conttx = false, singletone = false;
|
||||
u32 iqk_bb_reg[10] = {
|
||||
@ -1841,21 +1839,17 @@ void rtl92c_phy_iq_calibrate(struct ieee80211_hw *hw, bool recovery)
|
||||
reg_e94 = result[i][0];
|
||||
reg_e9c = result[i][1];
|
||||
reg_ea4 = result[i][2];
|
||||
reg_eac = result[i][3];
|
||||
reg_eb4 = result[i][4];
|
||||
reg_ebc = result[i][5];
|
||||
reg_ec4 = result[i][6];
|
||||
reg_ecc = result[i][7];
|
||||
}
|
||||
if (final_candidate != 0xff) {
|
||||
rtlphy->reg_e94 = reg_e94 = result[final_candidate][0];
|
||||
rtlphy->reg_e9c = reg_e9c = result[final_candidate][1];
|
||||
reg_ea4 = result[final_candidate][2];
|
||||
reg_eac = result[final_candidate][3];
|
||||
rtlphy->reg_eb4 = reg_eb4 = result[final_candidate][4];
|
||||
rtlphy->reg_ebc = reg_ebc = result[final_candidate][5];
|
||||
reg_ec4 = result[final_candidate][6];
|
||||
reg_ecc = result[final_candidate][7];
|
||||
patha_ok = pathb_ok = true;
|
||||
} else {
|
||||
rtlphy->reg_e94 = rtlphy->reg_eb4 = 0x100;
|
||||
|
@ -763,11 +763,9 @@ static void _rtl92ce_hw_configure(struct ieee80211_hw *hw)
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
|
||||
u8 reg_bw_opmode;
|
||||
u32 reg_ratr, reg_prsr;
|
||||
u32 reg_prsr;
|
||||
|
||||
reg_bw_opmode = BW_OPMODE_20MHZ;
|
||||
reg_ratr = RATE_ALL_CCK | RATE_ALL_OFDM_AG |
|
||||
RATE_ALL_OFDM_1SS | RATE_ALL_OFDM_2SS;
|
||||
reg_prsr = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
|
||||
|
||||
rtl_write_byte(rtlpriv, REG_INIRTS_RATE_SEL, 0x8);
|
||||
@ -1196,6 +1194,7 @@ void rtl92ce_disable_interrupt(struct ieee80211_hw *hw)
|
||||
rtl_write_dword(rtlpriv, REG_HIMR, IMR8190_DISABLED);
|
||||
rtl_write_dword(rtlpriv, REG_HIMRE, IMR8190_DISABLED);
|
||||
rtlpci->irq_enabled = false;
|
||||
synchronize_irq(rtlpci->pdev->irq);
|
||||
}
|
||||
|
||||
static void _rtl92ce_poweroff_adapter(struct ieee80211_hw *hw)
|
||||
@ -1969,7 +1968,7 @@ bool rtl92ce_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 *valid)
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
|
||||
struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
|
||||
enum rf_pwrstate e_rfpowerstate_toset, cur_rfstate;
|
||||
enum rf_pwrstate e_rfpowerstate_toset;
|
||||
u8 u1tmp;
|
||||
bool actuallyset = false;
|
||||
unsigned long flag;
|
||||
@ -1989,8 +1988,6 @@ bool rtl92ce_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 *valid)
|
||||
spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag);
|
||||
}
|
||||
|
||||
cur_rfstate = ppsc->rfpwr_state;
|
||||
|
||||
rtl_write_byte(rtlpriv, REG_MAC_PINMUX_CFG, rtl_read_byte(rtlpriv,
|
||||
REG_MAC_PINMUX_CFG)&~(BIT(3)));
|
||||
|
||||
|
@ -46,13 +46,12 @@ u32 rtl92c_phy_query_rf_reg(struct ieee80211_hw *hw,
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
u32 original_value, readback_value, bitshift;
|
||||
struct rtl_phy *rtlphy = &(rtlpriv->phy);
|
||||
unsigned long flags;
|
||||
|
||||
RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), "
|
||||
"rfpath(%#x), bitmask(%#x)\n",
|
||||
regaddr, rfpath, bitmask));
|
||||
|
||||
spin_lock_irqsave(&rtlpriv->locks.rf_lock, flags);
|
||||
spin_lock(&rtlpriv->locks.rf_lock);
|
||||
|
||||
if (rtlphy->rf_mode != RF_OP_BY_FW) {
|
||||
original_value = _rtl92c_phy_rf_serial_read(hw,
|
||||
@ -65,7 +64,7 @@ u32 rtl92c_phy_query_rf_reg(struct ieee80211_hw *hw,
|
||||
bitshift = _rtl92c_phy_calculate_bit_shift(bitmask);
|
||||
readback_value = (original_value & bitmask) >> bitshift;
|
||||
|
||||
spin_unlock_irqrestore(&rtlpriv->locks.rf_lock, flags);
|
||||
spin_unlock(&rtlpriv->locks.rf_lock);
|
||||
|
||||
RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
|
||||
("regaddr(%#x), rfpath(%#x), "
|
||||
@ -120,13 +119,12 @@ void rtl92ce_phy_set_rf_reg(struct ieee80211_hw *hw,
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
struct rtl_phy *rtlphy = &(rtlpriv->phy);
|
||||
u32 original_value, bitshift;
|
||||
unsigned long flags;
|
||||
|
||||
RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
|
||||
("regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n",
|
||||
regaddr, bitmask, data, rfpath));
|
||||
|
||||
spin_lock_irqsave(&rtlpriv->locks.rf_lock, flags);
|
||||
spin_lock(&rtlpriv->locks.rf_lock);
|
||||
|
||||
if (rtlphy->rf_mode != RF_OP_BY_FW) {
|
||||
if (bitmask != RFREG_OFFSET_MASK) {
|
||||
@ -153,7 +151,7 @@ void rtl92ce_phy_set_rf_reg(struct ieee80211_hw *hw,
|
||||
_rtl92c_phy_fw_rf_serial_write(hw, rfpath, regaddr, data);
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(&rtlpriv->locks.rf_lock, flags);
|
||||
spin_unlock(&rtlpriv->locks.rf_lock);
|
||||
|
||||
RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), "
|
||||
"bitmask(%#x), data(%#x), "
|
||||
@ -281,7 +279,6 @@ bool rtl92c_phy_config_rf_with_headerfile(struct ieee80211_hw *hw,
|
||||
{
|
||||
|
||||
int i;
|
||||
bool rtstatus = true;
|
||||
u32 *radioa_array_table;
|
||||
u32 *radiob_array_table;
|
||||
u16 radioa_arraylen, radiob_arraylen;
|
||||
@ -308,7 +305,6 @@ bool rtl92c_phy_config_rf_with_headerfile(struct ieee80211_hw *hw,
|
||||
("Radio_B:RTL8192CE_RADIOB_1TARRAY\n"));
|
||||
}
|
||||
RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("Radio No %x\n", rfpath));
|
||||
rtstatus = true;
|
||||
switch (rfpath) {
|
||||
case RF90_PATH_A:
|
||||
for (i = 0; i < radioa_arraylen; i = i + 2) {
|
||||
@ -521,7 +517,6 @@ static bool _rtl92ce_phy_set_rf_power_state(struct ieee80211_hw *hw,
|
||||
u8 i, queue_id;
|
||||
struct rtl8192_tx_ring *ring = NULL;
|
||||
|
||||
ppsc->set_rfpowerstate_inprogress = true;
|
||||
switch (rfpwr_state) {
|
||||
case ERFON:{
|
||||
if ((ppsc->rfpwr_state == ERFOFF) &&
|
||||
@ -617,7 +612,6 @@ static bool _rtl92ce_phy_set_rf_power_state(struct ieee80211_hw *hw,
|
||||
}
|
||||
if (bresult)
|
||||
ppsc->rfpwr_state = rfpwr_state;
|
||||
ppsc->set_rfpowerstate_inprogress = false;
|
||||
return bresult;
|
||||
}
|
||||
|
||||
|
@ -592,7 +592,6 @@ static void _rtl92ce_translate_rx_signal_stuff(struct ieee80211_hw *hw,
|
||||
struct ieee80211_hdr *hdr;
|
||||
u8 *tmp_buf;
|
||||
u8 *praddr;
|
||||
u8 *psaddr;
|
||||
__le16 fc;
|
||||
u16 type, c_fc;
|
||||
bool packet_matchbssid, packet_toself, packet_beacon;
|
||||
@ -604,7 +603,6 @@ static void _rtl92ce_translate_rx_signal_stuff(struct ieee80211_hw *hw,
|
||||
c_fc = le16_to_cpu(fc);
|
||||
type = WLAN_FC_GET_TYPE(fc);
|
||||
praddr = hdr->addr1;
|
||||
psaddr = hdr->addr2;
|
||||
|
||||
packet_matchbssid =
|
||||
((IEEE80211_FTYPE_CTL != type) &&
|
||||
@ -932,6 +930,7 @@ void rtl92ce_set_desc(u8 *pdesc, bool istx, u8 desc_name, u8 *val)
|
||||
if (istx == true) {
|
||||
switch (desc_name) {
|
||||
case HW_DESC_OWN:
|
||||
wmb();
|
||||
SET_TX_DESC_OWN(pdesc, 1);
|
||||
break;
|
||||
case HW_DESC_TX_NEXTDESC_ADDR:
|
||||
@ -945,6 +944,7 @@ void rtl92ce_set_desc(u8 *pdesc, bool istx, u8 desc_name, u8 *val)
|
||||
} else {
|
||||
switch (desc_name) {
|
||||
case HW_DESC_RXOWN:
|
||||
wmb();
|
||||
SET_RX_DESC_OWN(pdesc, 1);
|
||||
break;
|
||||
case HW_DESC_RXBUFF_ADDR:
|
||||
|
@ -1113,7 +1113,6 @@ void rtl92c_translate_rx_signal_stuff(struct ieee80211_hw *hw,
|
||||
struct ieee80211_hdr *hdr;
|
||||
u8 *tmp_buf;
|
||||
u8 *praddr;
|
||||
u8 *psaddr;
|
||||
__le16 fc;
|
||||
u16 type, cpu_fc;
|
||||
bool packet_matchbssid, packet_toself, packet_beacon;
|
||||
@ -1124,7 +1123,6 @@ void rtl92c_translate_rx_signal_stuff(struct ieee80211_hw *hw,
|
||||
cpu_fc = le16_to_cpu(fc);
|
||||
type = WLAN_FC_GET_TYPE(fc);
|
||||
praddr = hdr->addr1;
|
||||
psaddr = hdr->addr2;
|
||||
packet_matchbssid =
|
||||
((IEEE80211_FTYPE_CTL != type) &&
|
||||
(!compare_ether_addr(mac->bssid,
|
||||
|
@ -470,7 +470,6 @@ static bool _rtl92cu_phy_set_rf_power_state(struct ieee80211_hw *hw,
|
||||
u8 i, queue_id;
|
||||
struct rtl8192_tx_ring *ring = NULL;
|
||||
|
||||
ppsc->set_rfpowerstate_inprogress = true;
|
||||
switch (rfpwr_state) {
|
||||
case ERFON:
|
||||
if ((ppsc->rfpwr_state == ERFOFF) &&
|
||||
@ -590,7 +589,6 @@ static bool _rtl92cu_phy_set_rf_power_state(struct ieee80211_hw *hw,
|
||||
}
|
||||
if (bresult)
|
||||
ppsc->rfpwr_state = rfpwr_state;
|
||||
ppsc->set_rfpowerstate_inprogress = false;
|
||||
return bresult;
|
||||
}
|
||||
|
||||
|
@ -222,7 +222,6 @@ static void _rtl92s_dm_refresh_rateadaptive_mask(struct ieee80211_hw *hw)
|
||||
u32 low_rssi_thresh = 0;
|
||||
u32 middle_rssi_thresh = 0;
|
||||
u32 high_rssi_thresh = 0;
|
||||
u8 rssi_level;
|
||||
struct ieee80211_sta *sta = NULL;
|
||||
|
||||
if (is_hal_stop(rtlhal))
|
||||
@ -272,18 +271,14 @@ static void _rtl92s_dm_refresh_rateadaptive_mask(struct ieee80211_hw *hw)
|
||||
if (rtlpriv->dm.undecorated_smoothed_pwdb >
|
||||
(long)high_rssi_thresh) {
|
||||
ra->ratr_state = DM_RATR_STA_HIGH;
|
||||
rssi_level = 1;
|
||||
} else if (rtlpriv->dm.undecorated_smoothed_pwdb >
|
||||
(long)middle_rssi_thresh) {
|
||||
ra->ratr_state = DM_RATR_STA_LOW;
|
||||
rssi_level = 3;
|
||||
} else if (rtlpriv->dm.undecorated_smoothed_pwdb >
|
||||
(long)low_rssi_thresh) {
|
||||
ra->ratr_state = DM_RATR_STA_LOW;
|
||||
rssi_level = 5;
|
||||
} else {
|
||||
ra->ratr_state = DM_RATR_STA_ULTRALOW;
|
||||
rssi_level = 6;
|
||||
}
|
||||
|
||||
if (ra->pre_ratr_state != ra->ratr_state) {
|
||||
|
@ -358,7 +358,6 @@ int rtl92s_download_fw(struct ieee80211_hw *hw)
|
||||
struct fw_priv *pfw_priv = NULL;
|
||||
u8 *puc_mappedfile = NULL;
|
||||
u32 ul_filelength = 0;
|
||||
u32 file_length = 0;
|
||||
u8 fwhdr_size = RT_8192S_FIRMWARE_HDR_SIZE;
|
||||
u8 fwstatus = FW_STATUS_INIT;
|
||||
bool rtstatus = true;
|
||||
@ -370,7 +369,6 @@ int rtl92s_download_fw(struct ieee80211_hw *hw)
|
||||
firmware->fwstatus = FW_STATUS_INIT;
|
||||
|
||||
puc_mappedfile = firmware->sz_fw_tmpbuffer;
|
||||
file_length = firmware->sz_fw_tmpbufferlen;
|
||||
|
||||
/* 1. Retrieve FW header. */
|
||||
firmware->pfwheader = (struct fw_hdr *) puc_mappedfile;
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user