sc->hw_busy_count = 0;
del_timer_sync(&common->ani.timer);
+ del_timer_sync(&sc->rx_poll_timer);
ath9k_debug_samp_bb_mac(sc);
ath9k_hw_disable_interrupts(ah);
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_rx_poll(sc, 3);
if (!common->disable_ani)
ath_start_ani(common);
}
hchan = ah->curchan;
}
- if (fastcc && (ah->chip_fullsleep ||
- !ath9k_hw_check_alive(ah)))
- fastcc = false;
-
if (!ath_prepare_reset(sc, retry_tx, flush))
fastcc = false;
ath_dbg(common, CONFIG, "Reset to %u MHz, HT40: %d fastcc: %d\n",
- hchan->channel, !!(hchan->channelFlags & (CHANNEL_HT40MINUS |
- CHANNEL_HT40PLUS)),
- fastcc);
+ hchan->channel, IS_CHAN_HT40(hchan), fastcc);
r = ath9k_hw_reset(ah, hchan, caldata, fastcc);
if (r) {
if (sc->sc_flags & SC_OP_INVALID)
return -EIO;
- ath9k_ps_wakeup(sc);
-
r = ath_reset_internal(sc, hchan, false);
- ath9k_ps_restore(sc);
-
return r;
}
#endif
an->sta = sta;
an->vif = vif;
- if (sc->sc_flags & SC_OP_TXAGGR) {
+
+ if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT) {
ath_tx_node_init(sc, an);
an->maxampdu = 1 << (IEEE80211_HT_MAX_AMPDU_FACTOR +
sta->ht_cap.ampdu_factor);
an->sta = NULL;
#endif
- if (sc->sc_flags & SC_OP_TXAGGR)
+ if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT)
ath_tx_node_cleanup(sc, an);
}
ath_tx_tasklet(sc);
}
- if (ath9k_hw_get_btcoex_scheme(ah) == ATH_BTCOEX_CFG_3WIRE)
- if (status & ATH9K_INT_GENTIMER)
- ath_gen_timer_isr(sc->sc_ah);
-
- if ((status & ATH9K_INT_MCI) && ATH9K_HW_CAP_MCI)
- ath_mci_intr(sc);
+ ath9k_btcoex_handle_interrupt(sc, status);
out:
/* re-enable hardware interrupt */
struct ath_common *common = ath9k_hw_common(sc->sc_ah);
unsigned long flags;
int busy;
+ u8 is_alive, nbeacon = 1;
ath9k_ps_wakeup(sc);
- if (ath9k_hw_check_alive(sc->sc_ah))
+ is_alive = ath9k_hw_check_alive(sc->sc_ah);
+
+ if (is_alive && !AR_SREV_9300(sc->sc_ah))
goto out;
+ else if (!is_alive && AR_SREV_9300(sc->sc_ah)) {
+ ath_dbg(common, RESET,
+ "DCU stuck is detected. Schedule chip reset\n");
+ RESET_STAT_INC(sc, RESET_TYPE_MAC_HANG);
+ goto sched_reset;
+ }
spin_lock_irqsave(&common->cc_lock, flags);
busy = ath_update_survey_stats(sc);
if (busy >= 99) {
if (++sc->hw_busy_count >= 3) {
RESET_STAT_INC(sc, RESET_TYPE_BB_HANG);
- ieee80211_queue_work(sc->hw, &sc->hw_reset_work);
+ goto sched_reset;
}
-
- } else if (busy >= 0)
+ } else if (busy >= 0) {
sc->hw_busy_count = 0;
+ nbeacon = 3;
+ }
+
+ ath_start_rx_poll(sc, nbeacon);
+ goto out;
+sched_reset:
+ ieee80211_queue_work(sc->hw, &sc->hw_reset_work);
out:
ath9k_ps_restore(sc);
}
curchan->center_freq);
ath9k_ps_wakeup(sc);
-
mutex_lock(&sc->mutex);
- /* setup initial channel */
- sc->chan_idx = curchan->hw_value;
-
init_channel = ath9k_cmn_get_curchannel(hw, ah);
/* Reset SERDES registers */
sc->sc_flags &= ~SC_OP_INVALID;
sc->sc_ah->is_monitoring = false;
- /* Disable BMISS interrupt when we're not associated */
- ah->imask &= ~(ATH9K_INT_SWBA | ATH9K_INT_BMISS);
-
if (!ath_complete_reset(sc, false)) {
r = -EIO;
spin_unlock_bh(&sc->sc_pcu_lock);
spin_unlock_bh(&sc->sc_pcu_lock);
- if ((ath9k_hw_get_btcoex_scheme(ah) != ATH_BTCOEX_CFG_NONE) &&
- !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);
- ath9k_hw_btcoex_enable(ah);
-
- if (ath9k_hw_get_btcoex_scheme(ah) == ATH_BTCOEX_CFG_3WIRE)
- ath9k_btcoex_timer_resume(sc);
- }
+ ath9k_start_btcoex(sc);
if (ah->caps.pcie_lcr_extsync_en && common->bus_ops->extn_synch_en)
common->bus_ops->extn_synch_en(common);
if (ath_tx_start(hw, skb, &txctl) != 0) {
ath_dbg(common, XMIT, "TX failed\n");
+ TX_STAT_INC(txctl.txq->axq_qnum, txfailed);
goto exit;
}
mutex_lock(&sc->mutex);
ath_cancel_work(sc);
+ del_timer_sync(&sc->rx_poll_timer);
if (sc->sc_flags & SC_OP_INVALID) {
ath_dbg(common, ANY, "Device not present\n");
/* Ensure HW is awake when we try to shut it down. */
ath9k_ps_wakeup(sc);
- if (ah->btcoex_hw.enabled &&
- ath9k_hw_get_btcoex_scheme(ah) != ATH_BTCOEX_CFG_NONE) {
- ath9k_hw_btcoex_disable(ah);
- if (ath9k_hw_get_btcoex_scheme(ah) == ATH_BTCOEX_CFG_3WIRE)
- ath9k_btcoex_timer_pause(sc);
- ath_mci_flush_profile(&sc->btcoex.mci);
- }
+ ath9k_stop_btcoex(sc);
spin_lock_bh(&sc->sc_pcu_lock);
iter_data->nwds++;
break;
default:
- iter_data->nothers++;
break;
}
}
}
}
+void ath_start_rx_poll(struct ath_softc *sc, u8 nbeacon)
+{
+ if (!AR_SREV_9300(sc->sc_ah))
+ return;
+
+ if (!(sc->sc_flags & SC_OP_PRIM_STA_VIF))
+ return;
+
+ mod_timer(&sc->rx_poll_timer, jiffies + msecs_to_jiffies
+ (nbeacon * sc->cur_beacon_conf.beacon_interval));
+}
+
+void ath_rx_poll(unsigned long data)
+{
+ struct ath_softc *sc = (struct ath_softc *)data;
+
+ ieee80211_queue_work(sc->hw, &sc->hw_check_work);
+}
static int ath9k_add_interface(struct ieee80211_hw *hw,
struct ieee80211_vif *vif)
ath9k_ps_wakeup(sc);
mutex_lock(&sc->mutex);
- /*
- * Leave this as the first check because we need to turn on the
- * radio if it was disabled before prior to processing the rest
- * of the changes. Likewise we must only disable the radio towards
- * the end.
- */
if (changed & IEEE80211_CONF_CHANGE_IDLE) {
sc->ps_idle = !!(conf->flags & IEEE80211_CONF_IDLE);
if (sc->ps_idle)
struct ath_softc *sc = hw->priv;
struct ath_node *an = (struct ath_node *) sta->drv_priv;
- if (!(sc->sc_flags & SC_OP_TXAGGR))
+ if (!sta->ht_cap.ht_supported)
return;
switch (cmd) {
sc->last_rssi = ATH_RSSI_DUMMY_MARKER;
sc->sc_ah->stats.avgbrssi = ATH_RSSI_DUMMY_MARKER;
+ ath_start_rx_poll(sc, 3);
+
if (!common->disable_ani) {
sc->sc_flags |= SC_OP_ANI_RUN;
ath_start_ani(common);
/* Stop ANI */
sc->sc_flags &= ~SC_OP_ANI_RUN;
del_timer_sync(&common->ani.timer);
+ del_timer_sync(&sc->rx_poll_timer);
memset(&sc->caldata, 0, sizeof(sc->caldata));
}
}
ath9k_ps_wakeup(sc);
mutex_lock(&sc->mutex);
- if (changed & BSS_CHANGED_BSSID) {
+ if (changed & BSS_CHANGED_ASSOC) {
ath9k_config_bss(sc, vif);
ath_dbg(common, CONFIG, "BSSID: %pM aid: 0x%x\n",
} else {
sc->sc_flags &= ~SC_OP_ANI_RUN;
del_timer_sync(&common->ani.timer);
+ del_timer_sync(&sc->rx_poll_timer);
}
}
ath_beacon_config(sc, vif);
}
- if (changed & BSS_CHANGED_ERP_PREAMBLE) {
- ath_dbg(common, CONFIG, "BSS Changed PREAMBLE %d\n",
- bss_conf->use_short_preamble);
- if (bss_conf->use_short_preamble)
- sc->sc_flags |= SC_OP_PREAMBLE_SHORT;
- else
- sc->sc_flags &= ~SC_OP_PREAMBLE_SHORT;
- }
-
- if (changed & BSS_CHANGED_ERP_CTS_PROT) {
- ath_dbg(common, CONFIG, "BSS Changed CTS PROT %d\n",
- bss_conf->use_cts_prot);
- if (bss_conf->use_cts_prot &&
- hw->conf.channel->band != IEEE80211_BAND_5GHZ)
- sc->sc_flags |= SC_OP_PROTECT_ENABLE;
- else
- sc->sc_flags &= ~SC_OP_PROTECT_ENABLE;
- }
-
mutex_unlock(&sc->mutex);
ath9k_ps_restore(sc);
}
switch (action) {
case IEEE80211_AMPDU_RX_START:
- if (!(sc->sc_flags & SC_OP_RXAGGR))
- ret = -ENOTSUPP;
break;
case IEEE80211_AMPDU_RX_STOP:
break;
case IEEE80211_AMPDU_TX_START:
- if (!(sc->sc_flags & SC_OP_TXAGGR))
- return -EOPNOTSUPP;
-
ath9k_ps_wakeup(sc);
ret = ath_tx_aggr_start(sc, sta, tid, ssn);
if (!ret)
struct ath_vif *avp;
struct ath_buf *bf;
struct ath_tx_status ts;
+ bool edma = !!(ah->caps.hw_caps & ATH9K_HW_CAP_EDMA);
int status;
vif = sc->beacon.bslot[0];
if (!avp->is_bslot_active)
return 0;
- if (!sc->beacon.tx_processed) {
+ if (!sc->beacon.tx_processed && !edma) {
tasklet_disable(&sc->bcon_tasklet);
bf = avp->av_bcbuf;