提交 e4d680c7 编写于 作者: J John W. Linville

Merge branch 'master' of...

Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next into for-davem
...@@ -65,7 +65,7 @@ void bcma_core_set_clockmode(struct bcma_device *core, ...@@ -65,7 +65,7 @@ void bcma_core_set_clockmode(struct bcma_device *core,
switch (clkmode) { switch (clkmode) {
case BCMA_CLKMODE_FAST: case BCMA_CLKMODE_FAST:
bcma_set32(core, BCMA_CLKCTLST, BCMA_CLKCTLST_FORCEHT); bcma_set32(core, BCMA_CLKCTLST, BCMA_CLKCTLST_FORCEHT);
udelay(64); usleep_range(64, 300);
for (i = 0; i < 1500; i++) { for (i = 0; i < 1500; i++) {
if (bcma_read32(core, BCMA_CLKCTLST) & if (bcma_read32(core, BCMA_CLKCTLST) &
BCMA_CLKCTLST_HAVEHT) { BCMA_CLKCTLST_HAVEHT) {
......
...@@ -76,7 +76,10 @@ static void bcma_pmu_resources_init(struct bcma_drv_cc *cc) ...@@ -76,7 +76,10 @@ static void bcma_pmu_resources_init(struct bcma_drv_cc *cc)
if (max_msk) if (max_msk)
bcma_cc_write32(cc, BCMA_CC_PMU_MAXRES_MSK, max_msk); bcma_cc_write32(cc, BCMA_CC_PMU_MAXRES_MSK, max_msk);
/* Add some delay; allow resources to come up and settle. */ /*
* Add some delay; allow resources to come up and settle.
* Delay is required for SoC (early init).
*/
mdelay(2); mdelay(2);
} }
......
...@@ -51,7 +51,7 @@ static void bcma_pcie_mdio_set_phy(struct bcma_drv_pci *pc, u8 phy) ...@@ -51,7 +51,7 @@ static void bcma_pcie_mdio_set_phy(struct bcma_drv_pci *pc, u8 phy)
v = pcicore_read32(pc, BCMA_CORE_PCI_MDIO_CONTROL); v = pcicore_read32(pc, BCMA_CORE_PCI_MDIO_CONTROL);
if (v & BCMA_CORE_PCI_MDIOCTL_ACCESS_DONE) if (v & BCMA_CORE_PCI_MDIOCTL_ACCESS_DONE)
break; break;
msleep(1); usleep_range(1000, 2000);
} }
} }
...@@ -92,7 +92,7 @@ static u16 bcma_pcie_mdio_read(struct bcma_drv_pci *pc, u8 device, u8 address) ...@@ -92,7 +92,7 @@ static u16 bcma_pcie_mdio_read(struct bcma_drv_pci *pc, u8 device, u8 address)
ret = pcicore_read32(pc, BCMA_CORE_PCI_MDIO_DATA); ret = pcicore_read32(pc, BCMA_CORE_PCI_MDIO_DATA);
break; break;
} }
msleep(1); usleep_range(1000, 2000);
} }
pcicore_write32(pc, BCMA_CORE_PCI_MDIO_CONTROL, 0); pcicore_write32(pc, BCMA_CORE_PCI_MDIO_CONTROL, 0);
return ret; return ret;
...@@ -132,7 +132,7 @@ static void bcma_pcie_mdio_write(struct bcma_drv_pci *pc, u8 device, ...@@ -132,7 +132,7 @@ static void bcma_pcie_mdio_write(struct bcma_drv_pci *pc, u8 device,
v = pcicore_read32(pc, BCMA_CORE_PCI_MDIO_CONTROL); v = pcicore_read32(pc, BCMA_CORE_PCI_MDIO_CONTROL);
if (v & BCMA_CORE_PCI_MDIOCTL_ACCESS_DONE) if (v & BCMA_CORE_PCI_MDIOCTL_ACCESS_DONE)
break; break;
msleep(1); usleep_range(1000, 2000);
} }
pcicore_write32(pc, BCMA_CORE_PCI_MDIO_CONTROL, 0); pcicore_write32(pc, BCMA_CORE_PCI_MDIO_CONTROL, 0);
} }
......
...@@ -425,9 +425,9 @@ void __devinit bcma_core_pci_hostmode_init(struct bcma_drv_pci *pc) ...@@ -425,9 +425,9 @@ void __devinit bcma_core_pci_hostmode_init(struct bcma_drv_pci *pc)
pc_host->io_resource.flags = IORESOURCE_IO | IORESOURCE_PCI_FIXED; pc_host->io_resource.flags = IORESOURCE_IO | IORESOURCE_PCI_FIXED;
/* Reset RC */ /* Reset RC */
udelay(3000); usleep_range(3000, 5000);
pcicore_write32(pc, BCMA_CORE_PCI_CTL, BCMA_CORE_PCI_CTL_RST_OE); pcicore_write32(pc, BCMA_CORE_PCI_CTL, BCMA_CORE_PCI_CTL_RST_OE);
udelay(1000); usleep_range(1000, 2000);
pcicore_write32(pc, BCMA_CORE_PCI_CTL, BCMA_CORE_PCI_CTL_RST | pcicore_write32(pc, BCMA_CORE_PCI_CTL, BCMA_CORE_PCI_CTL_RST |
BCMA_CORE_PCI_CTL_RST_OE); BCMA_CORE_PCI_CTL_RST_OE);
...@@ -481,7 +481,7 @@ void __devinit bcma_core_pci_hostmode_init(struct bcma_drv_pci *pc) ...@@ -481,7 +481,7 @@ void __devinit bcma_core_pci_hostmode_init(struct bcma_drv_pci *pc)
* before issuing configuration requests to PCI Express * before issuing configuration requests to PCI Express
* devices. * devices.
*/ */
udelay(100000); msleep(100);
bcma_core_pci_enable_crs(pc); bcma_core_pci_enable_crs(pc);
...@@ -501,7 +501,7 @@ void __devinit bcma_core_pci_hostmode_init(struct bcma_drv_pci *pc) ...@@ -501,7 +501,7 @@ void __devinit bcma_core_pci_hostmode_init(struct bcma_drv_pci *pc)
set_io_port_base(pc_host->pci_controller.io_map_base); set_io_port_base(pc_host->pci_controller.io_map_base);
/* Give some time to the PCI controller to configure itself with the new /* Give some time to the PCI controller to configure itself with the new
* values. Not waiting at this point causes crashes of the machine. */ * values. Not waiting at this point causes crashes of the machine. */
mdelay(10); usleep_range(10000, 15000);
register_pci_controller(&pc_host->pci_controller); register_pci_controller(&pc_host->pci_controller);
return; return;
} }
......
...@@ -182,6 +182,7 @@ static bool ar9003_hw_get_isr(struct ath_hw *ah, enum ath9k_int *masked) ...@@ -182,6 +182,7 @@ static bool ar9003_hw_get_isr(struct ath_hw *ah, enum ath9k_int *masked)
struct ath9k_hw_capabilities *pCap = &ah->caps; struct ath9k_hw_capabilities *pCap = &ah->caps;
struct ath_common *common = ath9k_hw_common(ah); struct ath_common *common = ath9k_hw_common(ah);
u32 sync_cause = 0, async_cause, async_mask = AR_INTR_MAC_IRQ; u32 sync_cause = 0, async_cause, async_mask = AR_INTR_MAC_IRQ;
bool fatal_int;
if (ath9k_hw_mci_is_enabled(ah)) if (ath9k_hw_mci_is_enabled(ah))
async_mask |= AR_INTR_ASYNC_MASK_MCI; async_mask |= AR_INTR_ASYNC_MASK_MCI;
...@@ -310,6 +311,22 @@ static bool ar9003_hw_get_isr(struct ath_hw *ah, enum ath9k_int *masked) ...@@ -310,6 +311,22 @@ static bool ar9003_hw_get_isr(struct ath_hw *ah, enum ath9k_int *masked)
if (sync_cause) { if (sync_cause) {
ath9k_debug_sync_cause(common, sync_cause); ath9k_debug_sync_cause(common, sync_cause);
fatal_int =
(sync_cause &
(AR_INTR_SYNC_HOST1_FATAL | AR_INTR_SYNC_HOST1_PERR))
? true : false;
if (fatal_int) {
if (sync_cause & AR_INTR_SYNC_HOST1_FATAL) {
ath_dbg(common, ANY,
"received PCI FATAL interrupt\n");
}
if (sync_cause & AR_INTR_SYNC_HOST1_PERR) {
ath_dbg(common, ANY,
"received PCI PERR interrupt\n");
}
*masked |= ATH9K_INT_FATAL;
}
if (sync_cause & AR_INTR_SYNC_RADM_CPL_TIMEOUT) { if (sync_cause & AR_INTR_SYNC_RADM_CPL_TIMEOUT) {
REG_WRITE(ah, AR_RC, AR_RC_HOSTIF); REG_WRITE(ah, AR_RC, AR_RC_HOSTIF);
......
...@@ -813,8 +813,8 @@ static void ar9003_mci_osla_setup(struct ath_hw *ah, bool enable) ...@@ -813,8 +813,8 @@ static void ar9003_mci_osla_setup(struct ath_hw *ah, bool enable)
AR_BTCOEX_CTRL_ONE_STEP_LOOK_AHEAD_EN, 1); AR_BTCOEX_CTRL_ONE_STEP_LOOK_AHEAD_EN, 1);
} }
void ar9003_mci_reset(struct ath_hw *ah, bool en_int, bool is_2g, int ar9003_mci_reset(struct ath_hw *ah, bool en_int, bool is_2g,
bool is_full_sleep) bool is_full_sleep)
{ {
struct ath_common *common = ath9k_hw_common(ah); struct ath_common *common = ath9k_hw_common(ah);
struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci; struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;
...@@ -824,14 +824,13 @@ void ar9003_mci_reset(struct ath_hw *ah, bool en_int, bool is_2g, ...@@ -824,14 +824,13 @@ void ar9003_mci_reset(struct ath_hw *ah, bool en_int, bool is_2g,
is_full_sleep, is_2g); is_full_sleep, is_2g);
if (!mci->gpm_addr && !mci->sched_addr) { if (!mci->gpm_addr && !mci->sched_addr) {
ath_dbg(common, MCI, ath_err(common, "MCI GPM and schedule buffers are not allocated\n");
"MCI GPM and schedule buffers are not allocated\n"); return -ENOMEM;
return;
} }
if (REG_READ(ah, AR_BTCOEX_CTRL) == 0xdeadbeef) { if (REG_READ(ah, AR_BTCOEX_CTRL) == 0xdeadbeef) {
ath_dbg(common, MCI, "BTCOEX control register is dead\n"); ath_err(common, "BTCOEX control register is dead\n");
return; return -EINVAL;
} }
/* Program MCI DMA related registers */ /* Program MCI DMA related registers */
...@@ -913,6 +912,8 @@ void ar9003_mci_reset(struct ath_hw *ah, bool en_int, bool is_2g, ...@@ -913,6 +912,8 @@ void ar9003_mci_reset(struct ath_hw *ah, bool en_int, bool is_2g,
if (en_int) if (en_int)
ar9003_mci_enable_interrupt(ah); ar9003_mci_enable_interrupt(ah);
return 0;
} }
void ar9003_mci_stop_bt(struct ath_hw *ah, bool save_fullsleep) void ar9003_mci_stop_bt(struct ath_hw *ah, bool save_fullsleep)
...@@ -1144,8 +1145,8 @@ void ar9003_mci_init_cal_done(struct ath_hw *ah) ...@@ -1144,8 +1145,8 @@ void ar9003_mci_init_cal_done(struct ath_hw *ah)
ar9003_mci_send_message(ah, MCI_GPM, 0, pld, 16, true, false); ar9003_mci_send_message(ah, MCI_GPM, 0, pld, 16, true, false);
} }
void ar9003_mci_setup(struct ath_hw *ah, u32 gpm_addr, void *gpm_buf, int ar9003_mci_setup(struct ath_hw *ah, u32 gpm_addr, void *gpm_buf,
u16 len, u32 sched_addr) u16 len, u32 sched_addr)
{ {
struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci; struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;
...@@ -1154,7 +1155,7 @@ void ar9003_mci_setup(struct ath_hw *ah, u32 gpm_addr, void *gpm_buf, ...@@ -1154,7 +1155,7 @@ void ar9003_mci_setup(struct ath_hw *ah, u32 gpm_addr, void *gpm_buf,
mci->gpm_len = len; mci->gpm_len = len;
mci->sched_addr = sched_addr; mci->sched_addr = sched_addr;
ar9003_mci_reset(ah, true, true, true); return ar9003_mci_reset(ah, true, true, true);
} }
EXPORT_SYMBOL(ar9003_mci_setup); EXPORT_SYMBOL(ar9003_mci_setup);
......
...@@ -249,8 +249,8 @@ bool ar9003_mci_send_message(struct ath_hw *ah, u8 header, u32 flag, ...@@ -249,8 +249,8 @@ bool ar9003_mci_send_message(struct ath_hw *ah, u8 header, u32 flag,
u32 *payload, u8 len, bool wait_done, u32 *payload, u8 len, bool wait_done,
bool check_bt); bool check_bt);
u32 ar9003_mci_state(struct ath_hw *ah, u32 state_type); u32 ar9003_mci_state(struct ath_hw *ah, u32 state_type);
void ar9003_mci_setup(struct ath_hw *ah, u32 gpm_addr, void *gpm_buf, int ar9003_mci_setup(struct ath_hw *ah, u32 gpm_addr, void *gpm_buf,
u16 len, u32 sched_addr); u16 len, u32 sched_addr);
void ar9003_mci_cleanup(struct ath_hw *ah); void ar9003_mci_cleanup(struct ath_hw *ah);
void ar9003_mci_get_interrupt(struct ath_hw *ah, u32 *raw_intr, void ar9003_mci_get_interrupt(struct ath_hw *ah, u32 *raw_intr,
u32 *rx_msg_intr); u32 *rx_msg_intr);
...@@ -272,8 +272,8 @@ void ar9003_mci_check_bt(struct ath_hw *ah); ...@@ -272,8 +272,8 @@ void ar9003_mci_check_bt(struct ath_hw *ah);
bool ar9003_mci_start_reset(struct ath_hw *ah, struct ath9k_channel *chan); bool ar9003_mci_start_reset(struct ath_hw *ah, struct ath9k_channel *chan);
int ar9003_mci_end_reset(struct ath_hw *ah, struct ath9k_channel *chan, int ar9003_mci_end_reset(struct ath_hw *ah, struct ath9k_channel *chan,
struct ath9k_hw_cal_data *caldata); struct ath9k_hw_cal_data *caldata);
void ar9003_mci_reset(struct ath_hw *ah, bool en_int, bool is_2g, int ar9003_mci_reset(struct ath_hw *ah, bool en_int, bool is_2g,
bool is_full_sleep); bool is_full_sleep);
void ar9003_mci_get_isr(struct ath_hw *ah, enum ath9k_int *masked); void ar9003_mci_get_isr(struct ath_hw *ah, enum ath9k_int *masked);
void ar9003_mci_bt_gain_ctrl(struct ath_hw *ah); void ar9003_mci_bt_gain_ctrl(struct ath_hw *ah);
void ar9003_mci_set_power_awake(struct ath_hw *ah); void ar9003_mci_set_power_awake(struct ath_hw *ah);
......
...@@ -1360,7 +1360,7 @@ static void ar9003_hw_antctrl_shared_chain_lnadiv(struct ath_hw *ah, ...@@ -1360,7 +1360,7 @@ static void ar9003_hw_antctrl_shared_chain_lnadiv(struct ath_hw *ah,
if (enable) { if (enable) {
REG_SET_BIT(ah, AR_PHY_MC_GAIN_CTRL, REG_SET_BIT(ah, AR_PHY_MC_GAIN_CTRL,
(1 << AR_PHY_ANT_SW_RX_PROT_S)); (1 << AR_PHY_ANT_SW_RX_PROT_S));
if (IS_CHAN_2GHZ(ah->curchan)) if (ah->curchan && IS_CHAN_2GHZ(ah->curchan))
REG_SET_BIT(ah, AR_PHY_RESTART, REG_SET_BIT(ah, AR_PHY_RESTART,
AR_PHY_RESTART_ENABLE_DIV_M2FLAG); AR_PHY_RESTART_ENABLE_DIV_M2FLAG);
REG_SET_BIT(ah, AR_BTCOEX_WL_LNADIV, REG_SET_BIT(ah, AR_BTCOEX_WL_LNADIV,
......
...@@ -173,6 +173,8 @@ void ath_descdma_cleanup(struct ath_softc *sc, struct ath_descdma *dd, ...@@ -173,6 +173,8 @@ void ath_descdma_cleanup(struct ath_softc *sc, struct ath_descdma *dd,
#define ATH_AN_2_TID(_an, _tidno) (&(_an)->tid[(_tidno)]) #define ATH_AN_2_TID(_an, _tidno) (&(_an)->tid[(_tidno)])
#define IS_CCK_RATE(rate) ((rate >= 0x18) && (rate <= 0x1e))
#define ATH_TX_COMPLETE_POLL_INT 1000 #define ATH_TX_COMPLETE_POLL_INT 1000
enum ATH_AGGR_STATUS { enum ATH_AGGR_STATUS {
......
...@@ -43,8 +43,8 @@ static const u32 ar9003_wlan_weights[ATH_BTCOEX_STOMP_MAX] ...@@ -43,8 +43,8 @@ static const u32 ar9003_wlan_weights[ATH_BTCOEX_STOMP_MAX]
{ 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, /* STOMP_NONE */ { 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, /* STOMP_NONE */
}; };
static const u32 ar9462_wlan_weights[ATH_BTCOEX_STOMP_MAX] static const u32 mci_wlan_weights[ATH_BTCOEX_STOMP_MAX]
[AR9300_NUM_WLAN_WEIGHTS] = { [AR9300_NUM_WLAN_WEIGHTS] = {
{ 0x01017d01, 0x41414101, 0x41414101, 0x41414141 }, /* STOMP_ALL */ { 0x01017d01, 0x41414101, 0x41414101, 0x41414141 }, /* STOMP_ALL */
{ 0x01017d01, 0x3b3b3b01, 0x3b3b3b01, 0x3b3b3b3b }, /* STOMP_LOW */ { 0x01017d01, 0x3b3b3b01, 0x3b3b3b01, 0x3b3b3b3b }, /* STOMP_LOW */
{ 0x01017d01, 0x01010101, 0x01010101, 0x01010101 }, /* STOMP_NONE */ { 0x01017d01, 0x01010101, 0x01010101, 0x01010101 }, /* STOMP_NONE */
...@@ -208,14 +208,37 @@ static void ath9k_hw_btcoex_enable_2wire(struct ath_hw *ah) ...@@ -208,14 +208,37 @@ static void ath9k_hw_btcoex_enable_2wire(struct ath_hw *ah)
AR_GPIO_OUTPUT_MUX_AS_TX_FRAME); AR_GPIO_OUTPUT_MUX_AS_TX_FRAME);
} }
/*
* For AR9002, bt_weight/wlan_weight are used.
* For AR9003 and above, stomp_type is used.
*/
void ath9k_hw_btcoex_set_weight(struct ath_hw *ah, void ath9k_hw_btcoex_set_weight(struct ath_hw *ah,
u32 bt_weight, u32 bt_weight,
u32 wlan_weight) u32 wlan_weight,
enum ath_stomp_type stomp_type)
{ {
struct ath_btcoex_hw *btcoex_hw = &ah->btcoex_hw; struct ath_btcoex_hw *btcoex_hw = &ah->btcoex_hw;
btcoex_hw->bt_coex_weights = SM(bt_weight, AR_BTCOEX_BT_WGHT) | if (AR_SREV_9300_20_OR_LATER(ah)) {
SM(wlan_weight, AR_BTCOEX_WL_WGHT); const u32 *weight = ar9003_wlan_weights[stomp_type];
int i;
if (AR_SREV_9462(ah) || AR_SREV_9565(ah)) {
if ((stomp_type == ATH_BTCOEX_STOMP_LOW) &&
btcoex_hw->mci.stomp_ftp)
stomp_type = ATH_BTCOEX_STOMP_LOW_FTP;
weight = mci_wlan_weights[stomp_type];
}
for (i = 0; i < AR9300_NUM_WLAN_WEIGHTS; i++) {
btcoex_hw->bt_weight[i] = AR9300_BT_WGHT;
btcoex_hw->wlan_weight[i] = weight[i];
}
} else {
btcoex_hw->bt_coex_weights =
SM(bt_weight, AR_BTCOEX_BT_WGHT) |
SM(wlan_weight, AR_BTCOEX_WL_WGHT);
}
} }
EXPORT_SYMBOL(ath9k_hw_btcoex_set_weight); EXPORT_SYMBOL(ath9k_hw_btcoex_set_weight);
...@@ -282,7 +305,7 @@ void ath9k_hw_btcoex_enable(struct ath_hw *ah) ...@@ -282,7 +305,7 @@ void ath9k_hw_btcoex_enable(struct ath_hw *ah)
ath9k_hw_btcoex_enable_2wire(ah); ath9k_hw_btcoex_enable_2wire(ah);
break; break;
case ATH_BTCOEX_CFG_3WIRE: case ATH_BTCOEX_CFG_3WIRE:
if (AR_SREV_9462(ah)) { if (AR_SREV_9462(ah) || AR_SREV_9565(ah)) {
ath9k_hw_btcoex_enable_mci(ah); ath9k_hw_btcoex_enable_mci(ah);
return; return;
} }
...@@ -304,7 +327,7 @@ void ath9k_hw_btcoex_disable(struct ath_hw *ah) ...@@ -304,7 +327,7 @@ void ath9k_hw_btcoex_disable(struct ath_hw *ah)
int i; int i;
btcoex_hw->enabled = false; btcoex_hw->enabled = false;
if (AR_SREV_9462(ah)) { if (AR_SREV_9462(ah) || AR_SREV_9565(ah)) {
ath9k_hw_btcoex_bt_stomp(ah, ATH_BTCOEX_STOMP_NONE); ath9k_hw_btcoex_bt_stomp(ah, ATH_BTCOEX_STOMP_NONE);
for (i = 0; i < AR9300_NUM_BT_WEIGHTS; i++) for (i = 0; i < AR9300_NUM_BT_WEIGHTS; i++)
REG_WRITE(ah, AR_MCI_COEX_WL_WEIGHTS(i), REG_WRITE(ah, AR_MCI_COEX_WL_WEIGHTS(i),
...@@ -332,26 +355,6 @@ void ath9k_hw_btcoex_disable(struct ath_hw *ah) ...@@ -332,26 +355,6 @@ void ath9k_hw_btcoex_disable(struct ath_hw *ah)
} }
EXPORT_SYMBOL(ath9k_hw_btcoex_disable); EXPORT_SYMBOL(ath9k_hw_btcoex_disable);
static void ar9003_btcoex_bt_stomp(struct ath_hw *ah,
enum ath_stomp_type stomp_type)
{
struct ath_btcoex_hw *btcoex = &ah->btcoex_hw;
const u32 *weight = ar9003_wlan_weights[stomp_type];
int i;
if (AR_SREV_9462(ah)) {
if ((stomp_type == ATH_BTCOEX_STOMP_LOW) &&
btcoex->mci.stomp_ftp)
stomp_type = ATH_BTCOEX_STOMP_LOW_FTP;
weight = ar9462_wlan_weights[stomp_type];
}
for (i = 0; i < AR9300_NUM_WLAN_WEIGHTS; i++) {
btcoex->bt_weight[i] = AR9300_BT_WGHT;
btcoex->wlan_weight[i] = weight[i];
}
}
/* /*
* Configures appropriate weight based on stomp type. * Configures appropriate weight based on stomp type.
*/ */
...@@ -359,22 +362,22 @@ void ath9k_hw_btcoex_bt_stomp(struct ath_hw *ah, ...@@ -359,22 +362,22 @@ void ath9k_hw_btcoex_bt_stomp(struct ath_hw *ah,
enum ath_stomp_type stomp_type) enum ath_stomp_type stomp_type)
{ {
if (AR_SREV_9300_20_OR_LATER(ah)) { if (AR_SREV_9300_20_OR_LATER(ah)) {
ar9003_btcoex_bt_stomp(ah, stomp_type); ath9k_hw_btcoex_set_weight(ah, 0, 0, stomp_type);
return; return;
} }
switch (stomp_type) { switch (stomp_type) {
case ATH_BTCOEX_STOMP_ALL: case ATH_BTCOEX_STOMP_ALL:
ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT, ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT,
AR_STOMP_ALL_WLAN_WGHT); AR_STOMP_ALL_WLAN_WGHT, 0);
break; break;
case ATH_BTCOEX_STOMP_LOW: case ATH_BTCOEX_STOMP_LOW:
ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT, ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT,
AR_STOMP_LOW_WLAN_WGHT); AR_STOMP_LOW_WLAN_WGHT, 0);
break; break;
case ATH_BTCOEX_STOMP_NONE: case ATH_BTCOEX_STOMP_NONE:
ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT, ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT,
AR_STOMP_NONE_WLAN_WGHT); AR_STOMP_NONE_WLAN_WGHT, 0);
break; break;
default: default:
ath_dbg(ath9k_hw_common(ah), BTCOEX, "Invalid Stomptype\n"); ath_dbg(ath9k_hw_common(ah), BTCOEX, "Invalid Stomptype\n");
......
...@@ -107,7 +107,8 @@ void ath9k_hw_btcoex_init_mci(struct ath_hw *ah); ...@@ -107,7 +107,8 @@ void ath9k_hw_btcoex_init_mci(struct ath_hw *ah);
void ath9k_hw_init_btcoex_hw(struct ath_hw *ah, int qnum); void ath9k_hw_init_btcoex_hw(struct ath_hw *ah, int qnum);
void ath9k_hw_btcoex_set_weight(struct ath_hw *ah, void ath9k_hw_btcoex_set_weight(struct ath_hw *ah,
u32 bt_weight, u32 bt_weight,
u32 wlan_weight); u32 wlan_weight,
enum ath_stomp_type stomp_type);
void ath9k_hw_btcoex_disable(struct ath_hw *ah); void ath9k_hw_btcoex_disable(struct ath_hw *ah);
void ath9k_hw_btcoex_bt_stomp(struct ath_hw *ah, void ath9k_hw_btcoex_bt_stomp(struct ath_hw *ah,
enum ath_stomp_type stomp_type); enum ath_stomp_type stomp_type);
......
...@@ -222,6 +222,57 @@ static const struct file_operations fops_disable_ani = { ...@@ -222,6 +222,57 @@ static const struct file_operations fops_disable_ani = {
.llseek = default_llseek, .llseek = default_llseek,
}; };
static ssize_t read_file_ant_diversity(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->antenna_diversity);
return simple_read_from_buffer(user_buf, count, ppos, buf, len);
}
static ssize_t write_file_ant_diversity(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 antenna_diversity;
char buf[32];
ssize_t len;
len = min(count, sizeof(buf) - 1);
if (copy_from_user(buf, user_buf, len))
return -EFAULT;
if (!AR_SREV_9565(sc->sc_ah))
goto exit;
buf[len] = '\0';
if (strict_strtoul(buf, 0, &antenna_diversity))
return -EINVAL;
common->antenna_diversity = !!antenna_diversity;
ath9k_ps_wakeup(sc);
ath_ant_comb_update(sc);
ath_dbg(common, CONFIG, "Antenna diversity: %d\n",
common->antenna_diversity);
ath9k_ps_restore(sc);
exit:
return count;
}
static const struct file_operations fops_ant_diversity = {
.read = read_file_ant_diversity,
.write = write_file_ant_diversity,
.open = simple_open,
.owner = THIS_MODULE,
.llseek = default_llseek,
};
static ssize_t read_file_dma(struct file *file, char __user *user_buf, static ssize_t read_file_dma(struct file *file, char __user *user_buf,
size_t count, loff_t *ppos) size_t count, loff_t *ppos)
{ {
...@@ -1601,12 +1652,12 @@ int ath9k_init_debug(struct ath_hw *ah) ...@@ -1601,12 +1652,12 @@ int ath9k_init_debug(struct ath_hw *ah)
debugfs_create_file("samples", S_IRUSR, sc->debug.debugfs_phy, sc, debugfs_create_file("samples", S_IRUSR, sc->debug.debugfs_phy, sc,
&fops_samps); &fops_samps);
#endif #endif
debugfs_create_u32("gpio_mask", S_IRUSR | S_IWUSR, debugfs_create_u32("gpio_mask", S_IRUSR | S_IWUSR,
sc->debug.debugfs_phy, &sc->sc_ah->gpio_mask); sc->debug.debugfs_phy, &sc->sc_ah->gpio_mask);
debugfs_create_u32("gpio_val", S_IRUSR | S_IWUSR, debugfs_create_u32("gpio_val", S_IRUSR | S_IWUSR,
sc->debug.debugfs_phy, &sc->sc_ah->gpio_val); sc->debug.debugfs_phy, &sc->sc_ah->gpio_val);
debugfs_create_file("diversity", S_IRUSR | S_IWUSR,
sc->debug.debugfs_phy, sc, &fops_ant_diversity);
return 0; return 0;
} }
...@@ -395,7 +395,10 @@ void ath9k_start_btcoex(struct ath_softc *sc) ...@@ -395,7 +395,10 @@ void ath9k_start_btcoex(struct ath_softc *sc)
!ah->btcoex_hw.enabled) { !ah->btcoex_hw.enabled) {
if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_MCI)) if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_MCI))
ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT, ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT,
AR_STOMP_LOW_WLAN_WGHT); AR_STOMP_LOW_WLAN_WGHT, 0);
else
ath9k_hw_btcoex_set_weight(ah, 0, 0,
ATH_BTCOEX_STOMP_NONE);
ath9k_hw_btcoex_enable(ah); ath9k_hw_btcoex_enable(ah);
if (ath9k_hw_get_btcoex_scheme(ah) == ATH_BTCOEX_CFG_3WIRE) if (ath9k_hw_get_btcoex_scheme(ah) == ATH_BTCOEX_CFG_3WIRE)
...@@ -412,7 +415,7 @@ void ath9k_stop_btcoex(struct ath_softc *sc) ...@@ -412,7 +415,7 @@ void ath9k_stop_btcoex(struct ath_softc *sc)
if (ath9k_hw_get_btcoex_scheme(ah) == ATH_BTCOEX_CFG_3WIRE) if (ath9k_hw_get_btcoex_scheme(ah) == ATH_BTCOEX_CFG_3WIRE)
ath9k_btcoex_timer_pause(sc); ath9k_btcoex_timer_pause(sc);
ath9k_hw_btcoex_disable(ah); ath9k_hw_btcoex_disable(ah);
if (AR_SREV_9462(ah)) if (AR_SREV_9462(ah) || AR_SREV_9565(ah))
ath_mci_flush_profile(&sc->btcoex.mci); ath_mci_flush_profile(&sc->btcoex.mci);
} }
} }
......
...@@ -161,7 +161,7 @@ void ath9k_htc_start_btcoex(struct ath9k_htc_priv *priv) ...@@ -161,7 +161,7 @@ void ath9k_htc_start_btcoex(struct ath9k_htc_priv *priv)
if (ath9k_hw_get_btcoex_scheme(ah) == ATH_BTCOEX_CFG_3WIRE) { if (ath9k_hw_get_btcoex_scheme(ah) == ATH_BTCOEX_CFG_3WIRE) {
ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT, ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT,
AR_STOMP_LOW_WLAN_WGHT); AR_STOMP_LOW_WLAN_WGHT, 0);
ath9k_hw_btcoex_enable(ah); ath9k_hw_btcoex_enable(ah);
ath_htc_resume_btcoex_work(priv); ath_htc_resume_btcoex_work(priv);
} }
......
...@@ -392,6 +392,7 @@ int ath_mci_setup(struct ath_softc *sc) ...@@ -392,6 +392,7 @@ int ath_mci_setup(struct ath_softc *sc)
struct ath_common *common = ath9k_hw_common(sc->sc_ah); struct ath_common *common = ath9k_hw_common(sc->sc_ah);
struct ath_mci_coex *mci = &sc->mci_coex; struct ath_mci_coex *mci = &sc->mci_coex;
struct ath_mci_buf *buf = &mci->sched_buf; struct ath_mci_buf *buf = &mci->sched_buf;
int ret;
buf->bf_addr = dma_alloc_coherent(sc->dev, buf->bf_addr = dma_alloc_coherent(sc->dev,
ATH_MCI_SCHED_BUF_SIZE + ATH_MCI_GPM_BUF_SIZE, ATH_MCI_SCHED_BUF_SIZE + ATH_MCI_GPM_BUF_SIZE,
...@@ -411,9 +412,13 @@ int ath_mci_setup(struct ath_softc *sc) ...@@ -411,9 +412,13 @@ int ath_mci_setup(struct ath_softc *sc)
mci->gpm_buf.bf_addr = (u8 *)mci->sched_buf.bf_addr + mci->sched_buf.bf_len; mci->gpm_buf.bf_addr = (u8 *)mci->sched_buf.bf_addr + mci->sched_buf.bf_len;
mci->gpm_buf.bf_paddr = mci->sched_buf.bf_paddr + mci->sched_buf.bf_len; mci->gpm_buf.bf_paddr = mci->sched_buf.bf_paddr + mci->sched_buf.bf_len;
ar9003_mci_setup(sc->sc_ah, mci->gpm_buf.bf_paddr, ret = ar9003_mci_setup(sc->sc_ah, mci->gpm_buf.bf_paddr,
mci->gpm_buf.bf_addr, (mci->gpm_buf.bf_len >> 4), mci->gpm_buf.bf_addr, (mci->gpm_buf.bf_len >> 4),
mci->sched_buf.bf_paddr); mci->sched_buf.bf_paddr);
if (ret) {
ath_err(common, "Failed to initialize MCI\n");
return ret;
}
INIT_WORK(&sc->mci_work, ath9k_mci_work); INIT_WORK(&sc->mci_work, ath9k_mci_work);
ath_dbg(common, MCI, "MCI Initialized\n"); ath_dbg(common, MCI, "MCI Initialized\n");
......
...@@ -424,8 +424,8 @@ u32 ath_calcrxfilter(struct ath_softc *sc) ...@@ -424,8 +424,8 @@ u32 ath_calcrxfilter(struct ath_softc *sc)
rfilt |= ATH9K_RX_FILTER_COMP_BAR; rfilt |= ATH9K_RX_FILTER_COMP_BAR;
if (sc->nvifs > 1 || (sc->rx.rxfilter & FIF_OTHER_BSS)) { if (sc->nvifs > 1 || (sc->rx.rxfilter & FIF_OTHER_BSS)) {
/* The following may also be needed for other older chips */ /* This is needed for older chips */
if (sc->sc_ah->hw_version.macVersion == AR_SREV_VERSION_9160) if (sc->sc_ah->hw_version.macVersion <= AR_SREV_VERSION_9160)
rfilt |= ATH9K_RX_FILTER_PROM; rfilt |= ATH9K_RX_FILTER_PROM;
rfilt |= ATH9K_RX_FILTER_MCAST_BCAST_ALL; rfilt |= ATH9K_RX_FILTER_MCAST_BCAST_ALL;
} }
......
...@@ -497,7 +497,7 @@ void ath9k_hw_wow_enable(struct ath_hw *ah, u32 pattern_enable) ...@@ -497,7 +497,7 @@ void ath9k_hw_wow_enable(struct ath_hw *ah, u32 pattern_enable)
REG_RMW(ah, AR_PCIE_PM_CTRL, set, clr); REG_RMW(ah, AR_PCIE_PM_CTRL, set, clr);
if (AR_SREV_9462(ah)) { if (AR_SREV_9462(ah) || AR_SREV_9565(ah)) {
/* /*
* this is needed to prevent the chip waking up * this is needed to prevent the chip waking up
* the host within 3-4 seconds with certain * the host within 3-4 seconds with certain
......
...@@ -1820,10 +1820,14 @@ u8 ath_txchainmask_reduction(struct ath_softc *sc, u8 chainmask, u32 rate) ...@@ -1820,10 +1820,14 @@ u8 ath_txchainmask_reduction(struct ath_softc *sc, u8 chainmask, u32 rate)
{ {
struct ath_hw *ah = sc->sc_ah; struct ath_hw *ah = sc->sc_ah;
struct ath9k_channel *curchan = ah->curchan; struct ath9k_channel *curchan = ah->curchan;
if ((ah->caps.hw_caps & ATH9K_HW_CAP_APM) && if ((ah->caps.hw_caps & ATH9K_HW_CAP_APM) &&
(curchan->channelFlags & CHANNEL_5GHZ) && (curchan->channelFlags & CHANNEL_5GHZ) &&
(chainmask == 0x7) && (rate < 0x90)) (chainmask == 0x7) && (rate < 0x90))
return 0x3; return 0x3;
else if (AR_SREV_9462(ah) && ath9k_hw_btcoex_is_enabled(ah) &&
IS_CCK_RATE(rate))
return 0x2;
else else
return chainmask; return chainmask;
} }
......
...@@ -3895,6 +3895,8 @@ static void b43legacy_remove(struct ssb_device *dev) ...@@ -3895,6 +3895,8 @@ static void b43legacy_remove(struct ssb_device *dev)
cancel_work_sync(&wl->firmware_load); cancel_work_sync(&wl->firmware_load);
B43legacy_WARN_ON(!wl); B43legacy_WARN_ON(!wl);
if (!wldev->fw.ucode)
return; /* NULL if fw never loaded */
if (wl->current_dev == wldev) if (wl->current_dev == wldev)
ieee80211_unregister_hw(wl->hw); ieee80211_unregister_hw(wl->hw);
......
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
* IO codes that are interpreted by dongle firmware * IO codes that are interpreted by dongle firmware
******************************************************************************/ ******************************************************************************/
#define BRCMF_C_UP 2 #define BRCMF_C_UP 2
#define BRCMF_C_DOWN 3
#define BRCMF_C_SET_PROMISC 10 #define BRCMF_C_SET_PROMISC 10
#define BRCMF_C_GET_RATE 12 #define BRCMF_C_GET_RATE 12
#define BRCMF_C_GET_INFRA 19 #define BRCMF_C_GET_INFRA 19
...@@ -50,7 +51,10 @@ ...@@ -50,7 +51,10 @@
#define BRCMF_C_REASSOC 53 #define BRCMF_C_REASSOC 53
#define BRCMF_C_SET_ROAM_TRIGGER 55 #define BRCMF_C_SET_ROAM_TRIGGER 55
#define BRCMF_C_SET_ROAM_DELTA 57 #define BRCMF_C_SET_ROAM_DELTA 57
#define BRCMF_C_GET_BCNPRD 75
#define BRCMF_C_SET_BCNPRD 76
#define BRCMF_C_GET_DTIMPRD 77 #define BRCMF_C_GET_DTIMPRD 77
#define BRCMF_C_SET_DTIMPRD 78
#define BRCMF_C_SET_COUNTRY 84 #define BRCMF_C_SET_COUNTRY 84
#define BRCMF_C_GET_PM 85 #define BRCMF_C_GET_PM 85
#define BRCMF_C_SET_PM 86 #define BRCMF_C_SET_PM 86
...@@ -134,6 +138,9 @@ ...@@ -134,6 +138,9 @@
#define WLC_BSS_RSSI_ON_CHANNEL 0x0002 #define WLC_BSS_RSSI_ON_CHANNEL 0x0002
#define BRCMF_MAXRATES_IN_SET 16 /* max # of rates in rateset */
#define BRCMF_STA_ASSOC 0x10 /* Associated */
struct brcmf_event_msg { struct brcmf_event_msg {
__be16 version; __be16 version;
__be16 flags; __be16 flags;
...@@ -566,6 +573,28 @@ struct brcmf_channel_info_le { ...@@ -566,6 +573,28 @@ struct brcmf_channel_info_le {
__le32 scan_channel; __le32 scan_channel;
}; };
struct brcmf_sta_info_le {
__le16 ver; /* version of this struct */
__le16 len; /* length in bytes of this structure */
__le16 cap; /* sta's advertised capabilities */
__le32 flags; /* flags defined below */
__le32 idle; /* time since data pkt rx'd from sta */
u8 ea[ETH_ALEN]; /* Station address */
__le32 count; /* # rates in this set */
u8 rates[BRCMF_MAXRATES_IN_SET]; /* rates in 500kbps units */
/* w/hi bit set if basic */
__le32 in; /* seconds elapsed since associated */
__le32 listen_interval_inms; /* Min Listen interval in ms for STA */
__le32 tx_pkts; /* # of packets transmitted */
__le32 tx_failures; /* # of packets failed */
__le32 rx_ucast_pkts; /* # of unicast packets received */
__le32 rx_mcast_pkts; /* # of multicast packets received */
__le32 tx_rate; /* Rate of last successful tx frame */
__le32 rx_rate; /* Rate of last successful rx frame */
__le32 rx_decrypt_succeeds; /* # of packet decrypted successfully */
__le32 rx_decrypt_failures; /* # of packet decrypted failed */
};
/* Bus independent dongle command */ /* Bus independent dongle command */
struct brcmf_dcmd { struct brcmf_dcmd {
uint cmd; /* common dongle cmd definition */ uint cmd; /* common dongle cmd definition */
...@@ -585,7 +614,7 @@ struct brcmf_pub { ...@@ -585,7 +614,7 @@ struct brcmf_pub {
/* Linkage ponters */ /* Linkage ponters */
struct brcmf_bus *bus_if; struct brcmf_bus *bus_if;
struct brcmf_proto *prot; struct brcmf_proto *prot;
struct brcmf_cfg80211_dev *config; struct brcmf_cfg80211_info *config;
struct device *dev; /* fullmac dongle device pointer */ struct device *dev; /* fullmac dongle device pointer */
/* Internal brcmf items */ /* Internal brcmf items */
...@@ -658,6 +687,8 @@ extern const struct bcmevent_name bcmevent_names[]; ...@@ -658,6 +687,8 @@ extern const struct bcmevent_name bcmevent_names[];
extern uint brcmf_c_mkiovar(char *name, char *data, uint datalen, extern uint brcmf_c_mkiovar(char *name, char *data, uint datalen,
char *buf, uint len); char *buf, uint len);
extern uint brcmf_c_mkiovar_bsscfg(char *name, char *data, uint datalen,
char *buf, uint buflen, s32 bssidx);
extern int brcmf_netdev_wait_pend8021x(struct net_device *ndev); extern int brcmf_netdev_wait_pend8021x(struct net_device *ndev);
......
...@@ -88,6 +88,52 @@ brcmf_c_mkiovar(char *name, char *data, uint datalen, char *buf, uint buflen) ...@@ -88,6 +88,52 @@ brcmf_c_mkiovar(char *name, char *data, uint datalen, char *buf, uint buflen)
return len; return len;
} }
uint
brcmf_c_mkiovar_bsscfg(char *name, char *data, uint datalen,
char *buf, uint buflen, s32 bssidx)
{
const s8 *prefix = "bsscfg:";
s8 *p;
u32 prefixlen;
u32 namelen;
u32 iolen;
__le32 bssidx_le;
if (bssidx == 0)
return brcmf_c_mkiovar(name, data, datalen, buf, buflen);
prefixlen = (u32) strlen(prefix); /* lengh of bsscfg prefix */
namelen = (u32) strlen(name) + 1; /* lengh of iovar name + null */
iolen = prefixlen + namelen + sizeof(bssidx_le) + datalen;
if (buflen < 0 || iolen > (u32)buflen) {
brcmf_dbg(ERROR, "buffer is too short\n");
return 0;
}
p = buf;
/* copy prefix, no null */
memcpy(p, prefix, prefixlen);
p += prefixlen;
/* copy iovar name including null */
memcpy(p, name, namelen);
p += namelen;
/* bss config index as first data */
bssidx_le = cpu_to_le32(bssidx);
memcpy(p, &bssidx_le, sizeof(bssidx_le));
p += sizeof(bssidx_le);
/* parameter buffer follows */
if (datalen)
memcpy(p, data, datalen);
return iolen;
}
bool brcmf_c_prec_enq(struct device *dev, struct pktq *q, bool brcmf_c_prec_enq(struct device *dev, struct pktq *q,
struct sk_buff *pkt, int prec) struct sk_buff *pkt, int prec)
{ {
......
...@@ -160,40 +160,17 @@ static struct brcmf_usbdev_info *brcmf_usb_get_businfo(struct device *dev) ...@@ -160,40 +160,17 @@ static struct brcmf_usbdev_info *brcmf_usb_get_businfo(struct device *dev)
return brcmf_usb_get_buspub(dev)->devinfo; return brcmf_usb_get_buspub(dev)->devinfo;
} }
static int brcmf_usb_ioctl_resp_wait(struct brcmf_usbdev_info *devinfo, static int brcmf_usb_ioctl_resp_wait(struct brcmf_usbdev_info *devinfo)
uint *condition, bool *pending)
{ {
DECLARE_WAITQUEUE(wait, current); return wait_event_timeout(devinfo->ioctl_resp_wait,
int timeout = IOCTL_RESP_TIMEOUT; devinfo->ctl_completed,
msecs_to_jiffies(IOCTL_RESP_TIMEOUT));
/* Convert timeout in millsecond to jiffies */
timeout = msecs_to_jiffies(timeout);
/* Wait until control frame is available */
add_wait_queue(&devinfo->ioctl_resp_wait, &wait);
set_current_state(TASK_INTERRUPTIBLE);
smp_mb();
while (!(*condition) && (!signal_pending(current) && timeout)) {
timeout = schedule_timeout(timeout);
/* Wait until control frame is available */
smp_mb();
}
if (signal_pending(current))
*pending = true;
set_current_state(TASK_RUNNING);
remove_wait_queue(&devinfo->ioctl_resp_wait, &wait);
return timeout;
} }
static int brcmf_usb_ioctl_resp_wake(struct brcmf_usbdev_info *devinfo) static void brcmf_usb_ioctl_resp_wake(struct brcmf_usbdev_info *devinfo)
{ {
if (waitqueue_active(&devinfo->ioctl_resp_wait)) if (waitqueue_active(&devinfo->ioctl_resp_wait))
wake_up_interruptible(&devinfo->ioctl_resp_wait); wake_up(&devinfo->ioctl_resp_wait);
return 0;
} }
static void static void
...@@ -322,7 +299,6 @@ static int brcmf_usb_tx_ctlpkt(struct device *dev, u8 *buf, u32 len) ...@@ -322,7 +299,6 @@ static int brcmf_usb_tx_ctlpkt(struct device *dev, u8 *buf, u32 len)
{ {
int err = 0; int err = 0;
int timeout = 0; int timeout = 0;
bool pending;
struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(dev); struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(dev);
if (devinfo->bus_pub.state != BCMFMAC_USB_STATE_UP) { if (devinfo->bus_pub.state != BCMFMAC_USB_STATE_UP) {
...@@ -340,9 +316,7 @@ static int brcmf_usb_tx_ctlpkt(struct device *dev, u8 *buf, u32 len) ...@@ -340,9 +316,7 @@ static int brcmf_usb_tx_ctlpkt(struct device *dev, u8 *buf, u32 len)
clear_bit(0, &devinfo->ctl_op); clear_bit(0, &devinfo->ctl_op);
return err; return err;
} }
timeout = brcmf_usb_ioctl_resp_wait(devinfo);
timeout = brcmf_usb_ioctl_resp_wait(devinfo, &devinfo->ctl_completed,
&pending);
clear_bit(0, &devinfo->ctl_op); clear_bit(0, &devinfo->ctl_op);
if (!timeout) { if (!timeout) {
brcmf_dbg(ERROR, "Txctl wait timed out\n"); brcmf_dbg(ERROR, "Txctl wait timed out\n");
...@@ -355,7 +329,6 @@ static int brcmf_usb_rx_ctlpkt(struct device *dev, u8 *buf, u32 len) ...@@ -355,7 +329,6 @@ static int brcmf_usb_rx_ctlpkt(struct device *dev, u8 *buf, u32 len)
{ {
int err = 0; int err = 0;
int timeout = 0; int timeout = 0;
bool pending;
struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(dev); struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(dev);
if (devinfo->bus_pub.state != BCMFMAC_USB_STATE_UP) { if (devinfo->bus_pub.state != BCMFMAC_USB_STATE_UP) {
...@@ -365,15 +338,14 @@ static int brcmf_usb_rx_ctlpkt(struct device *dev, u8 *buf, u32 len) ...@@ -365,15 +338,14 @@ static int brcmf_usb_rx_ctlpkt(struct device *dev, u8 *buf, u32 len)
if (test_and_set_bit(0, &devinfo->ctl_op)) if (test_and_set_bit(0, &devinfo->ctl_op))
return -EIO; return -EIO;
devinfo->ctl_completed = false;
err = brcmf_usb_recv_ctl(devinfo, buf, len); err = brcmf_usb_recv_ctl(devinfo, buf, len);
if (err) { if (err) {
brcmf_dbg(ERROR, "fail %d bytes: %d\n", err, len); brcmf_dbg(ERROR, "fail %d bytes: %d\n", err, len);
clear_bit(0, &devinfo->ctl_op); clear_bit(0, &devinfo->ctl_op);
return err; return err;
} }
devinfo->ctl_completed = false; timeout = brcmf_usb_ioctl_resp_wait(devinfo);
timeout = brcmf_usb_ioctl_resp_wait(devinfo, &devinfo->ctl_completed,
&pending);
err = devinfo->ctl_urb_status; err = devinfo->ctl_urb_status;
clear_bit(0, &devinfo->ctl_op); clear_bit(0, &devinfo->ctl_op);
if (!timeout) { if (!timeout) {
...@@ -493,6 +465,8 @@ static void brcmf_usb_tx_complete(struct urb *urb) ...@@ -493,6 +465,8 @@ static void brcmf_usb_tx_complete(struct urb *urb)
else else
devinfo->bus_pub.bus->dstats.tx_errors++; devinfo->bus_pub.bus->dstats.tx_errors++;
brcmf_txcomplete(devinfo->dev, req->skb, urb->status == 0);
brcmu_pkt_buf_free_skb(req->skb); brcmu_pkt_buf_free_skb(req->skb);
req->skb = NULL; req->skb = NULL;
brcmf_usb_enq(devinfo, &devinfo->tx_freeq, req, &devinfo->tx_freecount); brcmf_usb_enq(devinfo, &devinfo->tx_freeq, req, &devinfo->tx_freecount);
......
...@@ -17,12 +17,6 @@ ...@@ -17,12 +17,6 @@
#ifndef _wl_cfg80211_h_ #ifndef _wl_cfg80211_h_
#define _wl_cfg80211_h_ #define _wl_cfg80211_h_
struct brcmf_cfg80211_conf;
struct brcmf_cfg80211_iface;
struct brcmf_cfg80211_priv;
struct brcmf_cfg80211_security;
struct brcmf_cfg80211_ibss;
#define WL_DBG_NONE 0 #define WL_DBG_NONE 0
#define WL_DBG_CONN (1 << 5) #define WL_DBG_CONN (1 << 5)
#define WL_DBG_SCAN (1 << 4) #define WL_DBG_SCAN (1 << 4)
...@@ -130,13 +124,18 @@ do { \ ...@@ -130,13 +124,18 @@ do { \
#define WL_ESCAN_ACTION_CONTINUE 2 #define WL_ESCAN_ACTION_CONTINUE 2
#define WL_ESCAN_ACTION_ABORT 3 #define WL_ESCAN_ACTION_ABORT 3
#define WL_AUTH_SHARED_KEY 1 /* d11 shared authentication */
#define IE_MAX_LEN 512
/* dongle status */ /* dongle status */
enum wl_status { enum wl_status {
WL_STATUS_READY, WL_STATUS_READY,
WL_STATUS_SCANNING, WL_STATUS_SCANNING,
WL_STATUS_SCAN_ABORTING, WL_STATUS_SCAN_ABORTING,
WL_STATUS_CONNECTING, WL_STATUS_CONNECTING,
WL_STATUS_CONNECTED WL_STATUS_CONNECTED,
WL_STATUS_AP_CREATING,
WL_STATUS_AP_CREATED
}; };
/* wi-fi mode */ /* wi-fi mode */
...@@ -176,23 +175,17 @@ struct brcmf_cfg80211_conf { ...@@ -176,23 +175,17 @@ struct brcmf_cfg80211_conf {
struct ieee80211_channel channel; struct ieee80211_channel channel;
}; };
/* forward declaration */
struct brcmf_cfg80211_info;
/* cfg80211 main event loop */ /* cfg80211 main event loop */
struct brcmf_cfg80211_event_loop { struct brcmf_cfg80211_event_loop {
s32(*handler[BRCMF_E_LAST]) (struct brcmf_cfg80211_priv *cfg_priv, s32(*handler[BRCMF_E_LAST]) (struct brcmf_cfg80211_info *cfg,
struct net_device *ndev, struct net_device *ndev,
const struct brcmf_event_msg *e, const struct brcmf_event_msg *e,
void *data); void *data);
}; };
/* representing interface of cfg80211 plane */
struct brcmf_cfg80211_iface {
struct brcmf_cfg80211_priv *cfg_priv;
};
struct brcmf_cfg80211_dev {
void *driver_data; /* to store cfg80211 object information */
};
/* basic structure of scan request */ /* basic structure of scan request */
struct brcmf_cfg80211_scan_req { struct brcmf_cfg80211_scan_req {
struct brcmf_ssid_le ssid_le; struct brcmf_ssid_le ssid_le;
...@@ -245,7 +238,7 @@ struct brcmf_cfg80211_profile { ...@@ -245,7 +238,7 @@ struct brcmf_cfg80211_profile {
/* dongle iscan event loop */ /* dongle iscan event loop */
struct brcmf_cfg80211_iscan_eloop { struct brcmf_cfg80211_iscan_eloop {
s32 (*handler[WL_SCAN_ERSULTS_LAST]) s32 (*handler[WL_SCAN_ERSULTS_LAST])
(struct brcmf_cfg80211_priv *cfg_priv); (struct brcmf_cfg80211_info *cfg);
}; };
/* dongle iscan controller */ /* dongle iscan controller */
...@@ -295,6 +288,17 @@ struct escan_info { ...@@ -295,6 +288,17 @@ struct escan_info {
struct net_device *ndev; struct net_device *ndev;
}; };
/* Structure to hold WPS, WPA IEs for a AP */
struct ap_info {
u8 probe_res_ie[IE_MAX_LEN];
u8 beacon_ie[IE_MAX_LEN];
u32 probe_res_ie_len;
u32 beacon_ie_len;
u8 *wpa_ie;
u8 *rsn_ie;
bool security_mode;
};
/** /**
* struct brcmf_pno_param_le - PNO scan configuration parameters * struct brcmf_pno_param_le - PNO scan configuration parameters
* *
...@@ -377,7 +381,7 @@ struct brcmf_pno_scanresults_le { ...@@ -377,7 +381,7 @@ struct brcmf_pno_scanresults_le {
}; };
/** /**
* struct brcmf_cfg80211_priv - dongle private data of cfg80211 interface * struct brcmf_cfg80211_info - dongle private data of cfg80211 interface
* *
* @wdev: representing wl cfg80211 device. * @wdev: representing wl cfg80211 device.
* @conf: dongle configuration. * @conf: dongle configuration.
...@@ -417,9 +421,10 @@ struct brcmf_pno_scanresults_le { ...@@ -417,9 +421,10 @@ struct brcmf_pno_scanresults_le {
* @escan_timeout: Timer for catch scan timeout. * @escan_timeout: Timer for catch scan timeout.
* @escan_timeout_work: scan timeout worker. * @escan_timeout_work: scan timeout worker.
* @escan_ioctl_buf: dongle command buffer for escan commands. * @escan_ioctl_buf: dongle command buffer for escan commands.
* @ap_info: host ap information.
* @ci: used to link this structure to netdev private data. * @ci: used to link this structure to netdev private data.
*/ */
struct brcmf_cfg80211_priv { struct brcmf_cfg80211_info {
struct wireless_dev *wdev; struct wireless_dev *wdev;
struct brcmf_cfg80211_conf *conf; struct brcmf_cfg80211_conf *conf;
struct cfg80211_scan_request *scan_request; struct cfg80211_scan_request *scan_request;
...@@ -458,52 +463,52 @@ struct brcmf_cfg80211_priv { ...@@ -458,52 +463,52 @@ struct brcmf_cfg80211_priv {
struct timer_list escan_timeout; struct timer_list escan_timeout;
struct work_struct escan_timeout_work; struct work_struct escan_timeout_work;
u8 *escan_ioctl_buf; u8 *escan_ioctl_buf;
u8 ci[0] __aligned(NETDEV_ALIGN); struct ap_info *ap_info;
}; };
static inline struct wiphy *cfg_to_wiphy(struct brcmf_cfg80211_priv *w) static inline struct wiphy *cfg_to_wiphy(struct brcmf_cfg80211_info *w)
{ {
return w->wdev->wiphy; return w->wdev->wiphy;
} }
static inline struct brcmf_cfg80211_priv *wiphy_to_cfg(struct wiphy *w) static inline struct brcmf_cfg80211_info *wiphy_to_cfg(struct wiphy *w)
{ {
return (struct brcmf_cfg80211_priv *)(wiphy_priv(w)); return (struct brcmf_cfg80211_info *)(wiphy_priv(w));
} }
static inline struct brcmf_cfg80211_priv *wdev_to_cfg(struct wireless_dev *wd) static inline struct brcmf_cfg80211_info *wdev_to_cfg(struct wireless_dev *wd)
{ {
return (struct brcmf_cfg80211_priv *)(wdev_priv(wd)); return (struct brcmf_cfg80211_info *)(wdev_priv(wd));
} }
static inline struct net_device *cfg_to_ndev(struct brcmf_cfg80211_priv *cfg) static inline struct net_device *cfg_to_ndev(struct brcmf_cfg80211_info *cfg)
{ {
return cfg->wdev->netdev; return cfg->wdev->netdev;
} }
static inline struct brcmf_cfg80211_priv *ndev_to_cfg(struct net_device *ndev) static inline struct brcmf_cfg80211_info *ndev_to_cfg(struct net_device *ndev)
{ {
return wdev_to_cfg(ndev->ieee80211_ptr); return wdev_to_cfg(ndev->ieee80211_ptr);
} }
#define iscan_to_cfg(i) ((struct brcmf_cfg80211_priv *)(i->data)) #define iscan_to_cfg(i) ((struct brcmf_cfg80211_info *)(i->data))
#define cfg_to_iscan(w) (w->iscan) #define cfg_to_iscan(w) (w->iscan)
static inline struct static inline struct
brcmf_cfg80211_connect_info *cfg_to_conn(struct brcmf_cfg80211_priv *cfg) brcmf_cfg80211_connect_info *cfg_to_conn(struct brcmf_cfg80211_info *cfg)
{ {
return &cfg->conn_info; return &cfg->conn_info;
} }
extern struct brcmf_cfg80211_dev *brcmf_cfg80211_attach(struct net_device *ndev, struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct net_device *ndev,
struct device *busdev, struct device *busdev,
struct brcmf_pub *drvr); struct brcmf_pub *drvr);
extern void brcmf_cfg80211_detach(struct brcmf_cfg80211_dev *cfg); void brcmf_cfg80211_detach(struct brcmf_cfg80211_info *cfg);
/* event handler from dongle */ /* event handler from dongle */
extern void brcmf_cfg80211_event(struct net_device *ndev, void brcmf_cfg80211_event(struct net_device *ndev,
const struct brcmf_event_msg *e, void *data); const struct brcmf_event_msg *e, void *data);
extern s32 brcmf_cfg80211_up(struct brcmf_cfg80211_dev *cfg_dev); s32 brcmf_cfg80211_up(struct brcmf_cfg80211_info *cfg);
extern s32 brcmf_cfg80211_down(struct brcmf_cfg80211_dev *cfg_dev); s32 brcmf_cfg80211_down(struct brcmf_cfg80211_info *cfg);
#endif /* _wl_cfg80211_h_ */ #endif /* _wl_cfg80211_h_ */
...@@ -302,6 +302,7 @@ mwifiex_11n_create_rx_reorder_tbl(struct mwifiex_private *priv, u8 *ta, ...@@ -302,6 +302,7 @@ mwifiex_11n_create_rx_reorder_tbl(struct mwifiex_private *priv, u8 *ta,
new_node->start_win = last_seq + 1; new_node->start_win = last_seq + 1;
new_node->win_size = win_size; new_node->win_size = win_size;
new_node->flags = 0;
new_node->rx_reorder_ptr = kzalloc(sizeof(void *) * win_size, new_node->rx_reorder_ptr = kzalloc(sizeof(void *) * win_size,
GFP_KERNEL); GFP_KERNEL);
...@@ -457,13 +458,20 @@ int mwifiex_11n_rx_reorder_pkt(struct mwifiex_private *priv, ...@@ -457,13 +458,20 @@ int mwifiex_11n_rx_reorder_pkt(struct mwifiex_private *priv,
* If seq_num is less then starting win then ignore and drop the * If seq_num is less then starting win then ignore and drop the
* packet * packet
*/ */
if ((start_win + TWOPOW11) > (MAX_TID_VALUE - 1)) {/* Wrap */ if (tbl->flags & RXREOR_FORCE_NO_DROP) {
if (seq_num >= ((start_win + TWOPOW11) & dev_dbg(priv->adapter->dev,
(MAX_TID_VALUE - 1)) && (seq_num < start_win)) "RXREOR_FORCE_NO_DROP when HS is activated\n");
tbl->flags &= ~RXREOR_FORCE_NO_DROP;
} else {
if ((start_win + TWOPOW11) > (MAX_TID_VALUE - 1)) {
if (seq_num >= ((start_win + TWOPOW11) &
(MAX_TID_VALUE - 1)) &&
seq_num < start_win)
return -1;
} else if ((seq_num < start_win) ||
(seq_num > (start_win + TWOPOW11))) {
return -1; return -1;
} else if ((seq_num < start_win) || }
(seq_num > (start_win + TWOPOW11))) {
return -1;
} }
/* /*
...@@ -474,8 +482,7 @@ int mwifiex_11n_rx_reorder_pkt(struct mwifiex_private *priv, ...@@ -474,8 +482,7 @@ int mwifiex_11n_rx_reorder_pkt(struct mwifiex_private *priv,
seq_num = ((seq_num + win_size) - 1) & (MAX_TID_VALUE - 1); seq_num = ((seq_num + win_size) - 1) & (MAX_TID_VALUE - 1);
if (((end_win < start_win) && if (((end_win < start_win) &&
(seq_num < (TWOPOW11 - (MAX_TID_VALUE - start_win))) && (seq_num < start_win) && (seq_num > end_win)) ||
(seq_num > end_win)) ||
((end_win > start_win) && ((seq_num > end_win) || ((end_win > start_win) && ((seq_num > end_win) ||
(seq_num < start_win)))) { (seq_num < start_win)))) {
end_win = seq_num; end_win = seq_num;
...@@ -637,3 +644,29 @@ void mwifiex_11n_cleanup_reorder_tbl(struct mwifiex_private *priv) ...@@ -637,3 +644,29 @@ void mwifiex_11n_cleanup_reorder_tbl(struct mwifiex_private *priv)
INIT_LIST_HEAD(&priv->rx_reorder_tbl_ptr); INIT_LIST_HEAD(&priv->rx_reorder_tbl_ptr);
mwifiex_reset_11n_rx_seq_num(priv); mwifiex_reset_11n_rx_seq_num(priv);
} }
/*
* This function updates all rx_reorder_tbl's flags.
*/
void mwifiex_update_rxreor_flags(struct mwifiex_adapter *adapter, u8 flags)
{
struct mwifiex_private *priv;
struct mwifiex_rx_reorder_tbl *tbl;
unsigned long lock_flags;
int i;
for (i = 0; i < adapter->priv_num; i++) {
priv = adapter->priv[i];
if (!priv)
continue;
if (list_empty(&priv->rx_reorder_tbl_ptr))
continue;
spin_lock_irqsave(&priv->rx_reorder_tbl_lock, lock_flags);
list_for_each_entry(tbl, &priv->rx_reorder_tbl_ptr, list)
tbl->flags = flags;
spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock, lock_flags);
}
return;
}
...@@ -1088,6 +1088,8 @@ mwifiex_hs_activated_event(struct mwifiex_private *priv, u8 activated) ...@@ -1088,6 +1088,8 @@ mwifiex_hs_activated_event(struct mwifiex_private *priv, u8 activated)
if (activated) { if (activated) {
if (priv->adapter->is_hs_configured) { if (priv->adapter->is_hs_configured) {
priv->adapter->hs_activated = true; priv->adapter->hs_activated = true;
mwifiex_update_rxreor_flags(priv->adapter,
RXREOR_FORCE_NO_DROP);
dev_dbg(priv->adapter->dev, "event: hs_activated\n"); dev_dbg(priv->adapter->dev, "event: hs_activated\n");
priv->adapter->hs_activate_wait_q_woken = true; priv->adapter->hs_activate_wait_q_woken = true;
wake_up_interruptible( wake_up_interruptible(
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册