提交 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,
switch (clkmode) {
case BCMA_CLKMODE_FAST:
bcma_set32(core, BCMA_CLKCTLST, BCMA_CLKCTLST_FORCEHT);
udelay(64);
usleep_range(64, 300);
for (i = 0; i < 1500; i++) {
if (bcma_read32(core, BCMA_CLKCTLST) &
BCMA_CLKCTLST_HAVEHT) {
......
......@@ -76,7 +76,10 @@ static void bcma_pmu_resources_init(struct bcma_drv_cc *cc)
if (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);
}
......
......@@ -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);
if (v & BCMA_CORE_PCI_MDIOCTL_ACCESS_DONE)
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)
ret = pcicore_read32(pc, BCMA_CORE_PCI_MDIO_DATA);
break;
}
msleep(1);
usleep_range(1000, 2000);
}
pcicore_write32(pc, BCMA_CORE_PCI_MDIO_CONTROL, 0);
return ret;
......@@ -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);
if (v & BCMA_CORE_PCI_MDIOCTL_ACCESS_DONE)
break;
msleep(1);
usleep_range(1000, 2000);
}
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)
pc_host->io_resource.flags = IORESOURCE_IO | IORESOURCE_PCI_FIXED;
/* Reset RC */
udelay(3000);
usleep_range(3000, 5000);
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 |
BCMA_CORE_PCI_CTL_RST_OE);
......@@ -481,7 +481,7 @@ void __devinit bcma_core_pci_hostmode_init(struct bcma_drv_pci *pc)
* before issuing configuration requests to PCI Express
* devices.
*/
udelay(100000);
msleep(100);
bcma_core_pci_enable_crs(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);
/* Give some time to the PCI controller to configure itself with the new
* values. Not waiting at this point causes crashes of the machine. */
mdelay(10);
usleep_range(10000, 15000);
register_pci_controller(&pc_host->pci_controller);
return;
}
......
......@@ -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 ath_common *common = ath9k_hw_common(ah);
u32 sync_cause = 0, async_cause, async_mask = AR_INTR_MAC_IRQ;
bool fatal_int;
if (ath9k_hw_mci_is_enabled(ah))
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)
if (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) {
REG_WRITE(ah, AR_RC, AR_RC_HOSTIF);
......
......@@ -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);
}
void ar9003_mci_reset(struct ath_hw *ah, bool en_int, bool is_2g,
bool is_full_sleep)
int ar9003_mci_reset(struct ath_hw *ah, bool en_int, bool is_2g,
bool is_full_sleep)
{
struct ath_common *common = ath9k_hw_common(ah);
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,
is_full_sleep, is_2g);
if (!mci->gpm_addr && !mci->sched_addr) {
ath_dbg(common, MCI,
"MCI GPM and schedule buffers are not allocated\n");
return;
ath_err(common, "MCI GPM and schedule buffers are not allocated\n");
return -ENOMEM;
}
if (REG_READ(ah, AR_BTCOEX_CTRL) == 0xdeadbeef) {
ath_dbg(common, MCI, "BTCOEX control register is dead\n");
return;
ath_err(common, "BTCOEX control register is dead\n");
return -EINVAL;
}
/* Program MCI DMA related registers */
......@@ -913,6 +912,8 @@ void ar9003_mci_reset(struct ath_hw *ah, bool en_int, bool is_2g,
if (en_int)
ar9003_mci_enable_interrupt(ah);
return 0;
}
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)
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,
u16 len, u32 sched_addr)
int ar9003_mci_setup(struct ath_hw *ah, u32 gpm_addr, void *gpm_buf,
u16 len, u32 sched_addr)
{
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,
mci->gpm_len = len;
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);
......
......@@ -249,8 +249,8 @@ bool ar9003_mci_send_message(struct ath_hw *ah, u8 header, u32 flag,
u32 *payload, u8 len, bool wait_done,
bool check_bt);
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,
u16 len, u32 sched_addr);
int ar9003_mci_setup(struct ath_hw *ah, u32 gpm_addr, void *gpm_buf,
u16 len, u32 sched_addr);
void ar9003_mci_cleanup(struct ath_hw *ah);
void ar9003_mci_get_interrupt(struct ath_hw *ah, u32 *raw_intr,
u32 *rx_msg_intr);
......@@ -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);
int ar9003_mci_end_reset(struct ath_hw *ah, struct ath9k_channel *chan,
struct ath9k_hw_cal_data *caldata);
void ar9003_mci_reset(struct ath_hw *ah, bool en_int, bool is_2g,
bool is_full_sleep);
int ar9003_mci_reset(struct ath_hw *ah, bool en_int, bool is_2g,
bool is_full_sleep);
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_set_power_awake(struct ath_hw *ah);
......
......@@ -1360,7 +1360,7 @@ static void ar9003_hw_antctrl_shared_chain_lnadiv(struct ath_hw *ah,
if (enable) {
REG_SET_BIT(ah, AR_PHY_MC_GAIN_CTRL,
(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,
AR_PHY_RESTART_ENABLE_DIV_M2FLAG);
REG_SET_BIT(ah, AR_BTCOEX_WL_LNADIV,
......
......@@ -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 IS_CCK_RATE(rate) ((rate >= 0x18) && (rate <= 0x1e))
#define ATH_TX_COMPLETE_POLL_INT 1000
enum ATH_AGGR_STATUS {
......
......@@ -43,8 +43,8 @@ static const u32 ar9003_wlan_weights[ATH_BTCOEX_STOMP_MAX]
{ 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, /* STOMP_NONE */
};
static const u32 ar9462_wlan_weights[ATH_BTCOEX_STOMP_MAX]
[AR9300_NUM_WLAN_WEIGHTS] = {
static const u32 mci_wlan_weights[ATH_BTCOEX_STOMP_MAX]
[AR9300_NUM_WLAN_WEIGHTS] = {
{ 0x01017d01, 0x41414101, 0x41414101, 0x41414141 }, /* STOMP_ALL */
{ 0x01017d01, 0x3b3b3b01, 0x3b3b3b01, 0x3b3b3b3b }, /* STOMP_LOW */
{ 0x01017d01, 0x01010101, 0x01010101, 0x01010101 }, /* STOMP_NONE */
......@@ -208,14 +208,37 @@ static void ath9k_hw_btcoex_enable_2wire(struct ath_hw *ah)
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,
u32 bt_weight,
u32 wlan_weight)
u32 wlan_weight,
enum ath_stomp_type stomp_type)
{
struct ath_btcoex_hw *btcoex_hw = &ah->btcoex_hw;
btcoex_hw->bt_coex_weights = SM(bt_weight, AR_BTCOEX_BT_WGHT) |
SM(wlan_weight, AR_BTCOEX_WL_WGHT);
if (AR_SREV_9300_20_OR_LATER(ah)) {
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);
......@@ -282,7 +305,7 @@ void ath9k_hw_btcoex_enable(struct ath_hw *ah)
ath9k_hw_btcoex_enable_2wire(ah);
break;
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);
return;
}
......@@ -304,7 +327,7 @@ void ath9k_hw_btcoex_disable(struct ath_hw *ah)
int i;
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);
for (i = 0; i < AR9300_NUM_BT_WEIGHTS; i++)
REG_WRITE(ah, AR_MCI_COEX_WL_WEIGHTS(i),
......@@ -332,26 +355,6 @@ void ath9k_hw_btcoex_disable(struct ath_hw *ah)
}
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.
*/
......@@ -359,22 +362,22 @@ void ath9k_hw_btcoex_bt_stomp(struct ath_hw *ah,
enum ath_stomp_type stomp_type)
{
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;
}
switch (stomp_type) {
case ATH_BTCOEX_STOMP_ALL:
ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT,
AR_STOMP_ALL_WLAN_WGHT);
AR_STOMP_ALL_WLAN_WGHT, 0);
break;
case ATH_BTCOEX_STOMP_LOW:
ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT,
AR_STOMP_LOW_WLAN_WGHT);
AR_STOMP_LOW_WLAN_WGHT, 0);
break;
case ATH_BTCOEX_STOMP_NONE:
ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT,
AR_STOMP_NONE_WLAN_WGHT);
AR_STOMP_NONE_WLAN_WGHT, 0);
break;
default:
ath_dbg(ath9k_hw_common(ah), BTCOEX, "Invalid Stomptype\n");
......
......@@ -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_btcoex_set_weight(struct ath_hw *ah,
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_bt_stomp(struct ath_hw *ah,
enum ath_stomp_type stomp_type);
......
......@@ -222,6 +222,57 @@ static const struct file_operations fops_disable_ani = {
.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,
size_t count, loff_t *ppos)
{
......@@ -1601,12 +1652,12 @@ int ath9k_init_debug(struct ath_hw *ah)
debugfs_create_file("samples", S_IRUSR, sc->debug.debugfs_phy, sc,
&fops_samps);
#endif
debugfs_create_u32("gpio_mask", S_IRUSR | S_IWUSR,
sc->debug.debugfs_phy, &sc->sc_ah->gpio_mask);
debugfs_create_u32("gpio_val", S_IRUSR | S_IWUSR,
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;
}
......@@ -395,7 +395,10 @@ void ath9k_start_btcoex(struct ath_softc *sc)
!ah->btcoex_hw.enabled) {
if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_MCI))
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);
if (ath9k_hw_get_btcoex_scheme(ah) == ATH_BTCOEX_CFG_3WIRE)
......@@ -412,7 +415,7 @@ void ath9k_stop_btcoex(struct ath_softc *sc)
if (ath9k_hw_get_btcoex_scheme(ah) == ATH_BTCOEX_CFG_3WIRE)
ath9k_btcoex_timer_pause(sc);
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);
}
}
......
......@@ -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) {
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);
ath_htc_resume_btcoex_work(priv);
}
......
......@@ -392,6 +392,7 @@ int ath_mci_setup(struct ath_softc *sc)
struct ath_common *common = ath9k_hw_common(sc->sc_ah);
struct ath_mci_coex *mci = &sc->mci_coex;
struct ath_mci_buf *buf = &mci->sched_buf;
int ret;
buf->bf_addr = dma_alloc_coherent(sc->dev,
ATH_MCI_SCHED_BUF_SIZE + ATH_MCI_GPM_BUF_SIZE,
......@@ -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_paddr = mci->sched_buf.bf_paddr + mci->sched_buf.bf_len;
ar9003_mci_setup(sc->sc_ah, mci->gpm_buf.bf_paddr,
mci->gpm_buf.bf_addr, (mci->gpm_buf.bf_len >> 4),
mci->sched_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->sched_buf.bf_paddr);
if (ret) {
ath_err(common, "Failed to initialize MCI\n");
return ret;
}
INIT_WORK(&sc->mci_work, ath9k_mci_work);
ath_dbg(common, MCI, "MCI Initialized\n");
......
......@@ -424,8 +424,8 @@ u32 ath_calcrxfilter(struct ath_softc *sc)
rfilt |= ATH9K_RX_FILTER_COMP_BAR;
if (sc->nvifs > 1 || (sc->rx.rxfilter & FIF_OTHER_BSS)) {
/* The following may also be needed for other older chips */
if (sc->sc_ah->hw_version.macVersion == AR_SREV_VERSION_9160)
/* This is needed for older chips */
if (sc->sc_ah->hw_version.macVersion <= AR_SREV_VERSION_9160)
rfilt |= ATH9K_RX_FILTER_PROM;
rfilt |= ATH9K_RX_FILTER_MCAST_BCAST_ALL;
}
......
......@@ -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);
if (AR_SREV_9462(ah)) {
if (AR_SREV_9462(ah) || AR_SREV_9565(ah)) {
/*
* this is needed to prevent the chip waking up
* the host within 3-4 seconds with certain
......
......@@ -1820,10 +1820,14 @@ u8 ath_txchainmask_reduction(struct ath_softc *sc, u8 chainmask, u32 rate)
{
struct ath_hw *ah = sc->sc_ah;
struct ath9k_channel *curchan = ah->curchan;
if ((ah->caps.hw_caps & ATH9K_HW_CAP_APM) &&
(curchan->channelFlags & CHANNEL_5GHZ) &&
(chainmask == 0x7) && (rate < 0x90))
return 0x3;
else if (AR_SREV_9462(ah) && ath9k_hw_btcoex_is_enabled(ah) &&
IS_CCK_RATE(rate))
return 0x2;
else
return chainmask;
}
......
......@@ -3895,6 +3895,8 @@ static void b43legacy_remove(struct ssb_device *dev)
cancel_work_sync(&wl->firmware_load);
B43legacy_WARN_ON(!wl);
if (!wldev->fw.ucode)
return; /* NULL if fw never loaded */
if (wl->current_dev == wldev)
ieee80211_unregister_hw(wl->hw);
......
......@@ -27,6 +27,7 @@
* IO codes that are interpreted by dongle firmware
******************************************************************************/
#define BRCMF_C_UP 2
#define BRCMF_C_DOWN 3
#define BRCMF_C_SET_PROMISC 10
#define BRCMF_C_GET_RATE 12
#define BRCMF_C_GET_INFRA 19
......@@ -50,7 +51,10 @@
#define BRCMF_C_REASSOC 53
#define BRCMF_C_SET_ROAM_TRIGGER 55
#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_SET_DTIMPRD 78
#define BRCMF_C_SET_COUNTRY 84
#define BRCMF_C_GET_PM 85
#define BRCMF_C_SET_PM 86
......@@ -134,6 +138,9 @@
#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 {
__be16 version;
__be16 flags;
......@@ -566,6 +573,28 @@ struct brcmf_channel_info_le {
__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 */
struct brcmf_dcmd {
uint cmd; /* common dongle cmd definition */
......@@ -585,7 +614,7 @@ struct brcmf_pub {
/* Linkage ponters */
struct brcmf_bus *bus_if;
struct brcmf_proto *prot;
struct brcmf_cfg80211_dev *config;
struct brcmf_cfg80211_info *config;
struct device *dev; /* fullmac dongle device pointer */
/* Internal brcmf items */
......@@ -658,6 +687,8 @@ extern const struct bcmevent_name bcmevent_names[];
extern uint brcmf_c_mkiovar(char *name, char *data, uint datalen,
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);
......
......@@ -88,6 +88,52 @@ brcmf_c_mkiovar(char *name, char *data, uint datalen, char *buf, uint buflen)
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,
struct sk_buff *pkt, int prec)
{
......
......@@ -160,40 +160,17 @@ static struct brcmf_usbdev_info *brcmf_usb_get_businfo(struct device *dev)
return brcmf_usb_get_buspub(dev)->devinfo;
}
static int brcmf_usb_ioctl_resp_wait(struct brcmf_usbdev_info *devinfo,
uint *condition, bool *pending)
static int brcmf_usb_ioctl_resp_wait(struct brcmf_usbdev_info *devinfo)
{
DECLARE_WAITQUEUE(wait, current);
int timeout = 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;
return wait_event_timeout(devinfo->ioctl_resp_wait,
devinfo->ctl_completed,
msecs_to_jiffies(IOCTL_RESP_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))
wake_up_interruptible(&devinfo->ioctl_resp_wait);
return 0;
wake_up(&devinfo->ioctl_resp_wait);
}
static void
......@@ -322,7 +299,6 @@ static int brcmf_usb_tx_ctlpkt(struct device *dev, u8 *buf, u32 len)
{
int err = 0;
int timeout = 0;
bool pending;
struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(dev);
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)
clear_bit(0, &devinfo->ctl_op);
return err;
}
timeout = brcmf_usb_ioctl_resp_wait(devinfo, &devinfo->ctl_completed,
&pending);
timeout = brcmf_usb_ioctl_resp_wait(devinfo);
clear_bit(0, &devinfo->ctl_op);
if (!timeout) {
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)
{
int err = 0;
int timeout = 0;
bool pending;
struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(dev);
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)
if (test_and_set_bit(0, &devinfo->ctl_op))
return -EIO;
devinfo->ctl_completed = false;
err = brcmf_usb_recv_ctl(devinfo, buf, len);
if (err) {
brcmf_dbg(ERROR, "fail %d bytes: %d\n", err, len);
clear_bit(0, &devinfo->ctl_op);
return err;
}
devinfo->ctl_completed = false;
timeout = brcmf_usb_ioctl_resp_wait(devinfo, &devinfo->ctl_completed,
&pending);
timeout = brcmf_usb_ioctl_resp_wait(devinfo);
err = devinfo->ctl_urb_status;
clear_bit(0, &devinfo->ctl_op);
if (!timeout) {
......@@ -493,6 +465,8 @@ static void brcmf_usb_tx_complete(struct urb *urb)
else
devinfo->bus_pub.bus->dstats.tx_errors++;
brcmf_txcomplete(devinfo->dev, req->skb, urb->status == 0);
brcmu_pkt_buf_free_skb(req->skb);
req->skb = NULL;
brcmf_usb_enq(devinfo, &devinfo->tx_freeq, req, &devinfo->tx_freecount);
......
......@@ -17,12 +17,6 @@
#ifndef _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_CONN (1 << 5)
#define WL_DBG_SCAN (1 << 4)
......@@ -130,13 +124,18 @@ do { \
#define WL_ESCAN_ACTION_CONTINUE 2
#define WL_ESCAN_ACTION_ABORT 3
#define WL_AUTH_SHARED_KEY 1 /* d11 shared authentication */
#define IE_MAX_LEN 512
/* dongle status */
enum wl_status {
WL_STATUS_READY,
WL_STATUS_SCANNING,
WL_STATUS_SCAN_ABORTING,
WL_STATUS_CONNECTING,
WL_STATUS_CONNECTED
WL_STATUS_CONNECTED,
WL_STATUS_AP_CREATING,
WL_STATUS_AP_CREATED
};
/* wi-fi mode */
......@@ -176,23 +175,17 @@ struct brcmf_cfg80211_conf {
struct ieee80211_channel channel;
};
/* forward declaration */
struct brcmf_cfg80211_info;
/* cfg80211 main 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,
const struct brcmf_event_msg *e,
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 */
struct brcmf_cfg80211_scan_req {
struct brcmf_ssid_le ssid_le;
......@@ -245,7 +238,7 @@ struct brcmf_cfg80211_profile {
/* dongle iscan event loop */
struct brcmf_cfg80211_iscan_eloop {
s32 (*handler[WL_SCAN_ERSULTS_LAST])
(struct brcmf_cfg80211_priv *cfg_priv);
(struct brcmf_cfg80211_info *cfg);
};
/* dongle iscan controller */
......@@ -295,6 +288,17 @@ struct escan_info {
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
*
......@@ -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.
* @conf: dongle configuration.
......@@ -417,9 +421,10 @@ struct brcmf_pno_scanresults_le {
* @escan_timeout: Timer for catch scan timeout.
* @escan_timeout_work: scan timeout worker.
* @escan_ioctl_buf: dongle command buffer for escan commands.
* @ap_info: host ap information.
* @ci: used to link this structure to netdev private data.
*/
struct brcmf_cfg80211_priv {
struct brcmf_cfg80211_info {
struct wireless_dev *wdev;
struct brcmf_cfg80211_conf *conf;
struct cfg80211_scan_request *scan_request;
......@@ -458,52 +463,52 @@ struct brcmf_cfg80211_priv {
struct timer_list escan_timeout;
struct work_struct escan_timeout_work;
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;
}
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;
}
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);
}
#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)
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;
}
extern struct brcmf_cfg80211_dev *brcmf_cfg80211_attach(struct net_device *ndev,
struct device *busdev,
struct brcmf_pub *drvr);
extern void brcmf_cfg80211_detach(struct brcmf_cfg80211_dev *cfg);
struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct net_device *ndev,
struct device *busdev,
struct brcmf_pub *drvr);
void brcmf_cfg80211_detach(struct brcmf_cfg80211_info *cfg);
/* event handler from dongle */
extern void brcmf_cfg80211_event(struct net_device *ndev,
const struct brcmf_event_msg *e, void *data);
extern s32 brcmf_cfg80211_up(struct brcmf_cfg80211_dev *cfg_dev);
extern s32 brcmf_cfg80211_down(struct brcmf_cfg80211_dev *cfg_dev);
void brcmf_cfg80211_event(struct net_device *ndev,
const struct brcmf_event_msg *e, void *data);
s32 brcmf_cfg80211_up(struct brcmf_cfg80211_info *cfg);
s32 brcmf_cfg80211_down(struct brcmf_cfg80211_info *cfg);
#endif /* _wl_cfg80211_h_ */
......@@ -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->win_size = win_size;
new_node->flags = 0;
new_node->rx_reorder_ptr = kzalloc(sizeof(void *) * win_size,
GFP_KERNEL);
......@@ -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
* packet
*/
if ((start_win + TWOPOW11) > (MAX_TID_VALUE - 1)) {/* Wrap */
if (seq_num >= ((start_win + TWOPOW11) &
(MAX_TID_VALUE - 1)) && (seq_num < start_win))
if (tbl->flags & RXREOR_FORCE_NO_DROP) {
dev_dbg(priv->adapter->dev,
"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;
} 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,
seq_num = ((seq_num + win_size) - 1) & (MAX_TID_VALUE - 1);
if (((end_win < start_win) &&
(seq_num < (TWOPOW11 - (MAX_TID_VALUE - start_win))) &&
(seq_num > end_win)) ||
(seq_num < start_win) && (seq_num > end_win)) ||
((end_win > start_win) && ((seq_num > end_win) ||
(seq_num < start_win)))) {
end_win = seq_num;
......@@ -637,3 +644,29 @@ void mwifiex_11n_cleanup_reorder_tbl(struct mwifiex_private *priv)
INIT_LIST_HEAD(&priv->rx_reorder_tbl_ptr);
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)
if (activated) {
if (priv->adapter->is_hs_configured) {
priv->adapter->hs_activated = true;
mwifiex_update_rxreor_flags(priv->adapter,
RXREOR_FORCE_NO_DROP);
dev_dbg(priv->adapter->dev, "event: hs_activated\n");
priv->adapter->hs_activate_wait_q_woken = true;
wake_up_interruptible(
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册