From d9fe60dea7779d412b34679f1177c5ca1940ea8d Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 9 Oct 2008 12:13:49 +0200 Subject: 802.11: clean up/fix HT support This patch cleans up a number of things: * the unusable definition of the HT capabilities/HT information information elements * variable names that are hard to understand * mac80211: move ieee80211_handle_ht to ht.c and remove the unused enable_ht parameter * mac80211: fix bug with MCS rate 32 in ieee80211_handle_ht * mac80211: fix bug with casting the result of ieee80211_bss_get_ie to an information element _contents_ rather than the whole element, add size checking (another out-of-bounds access bug fixed!) * mac80211: remove some unused return values in favour of BUG_ON checking * a few minor other things Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- drivers/net/wireless/ath9k/recv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net/wireless/ath9k/recv.c') diff --git a/drivers/net/wireless/ath9k/recv.c b/drivers/net/wireless/ath9k/recv.c index 4983402af559..010fcdfec3f6 100644 --- a/drivers/net/wireless/ath9k/recv.c +++ b/drivers/net/wireless/ath9k/recv.c @@ -1119,7 +1119,7 @@ int ath_rx_aggr_start(struct ath_softc *sc, sband = hw->wiphy->bands[hw->conf.channel->band]; buffersize = IEEE80211_MIN_AMPDU_BUF << - sband->ht_info.ampdu_factor; /* FIXME */ + sband->ht_cap.ampdu_factor; /* FIXME */ rxtid = &an->an_aggr.rx.tid[tid]; -- cgit v1.2.3 From ae5eb02641233a4e9d1b92d22090f1b1afa14466 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 14 Oct 2008 16:58:37 +0200 Subject: mac80211: rewrite HT handling The HT handling has the following deficiencies, which I've (partially) fixed: * it always uses the AP info even if there is no AP, hence has no chance of working as an AP * it pretends to be HW config, but really is per-BSS * channel sanity checking is left to the drivers * it generally lets the driver control too much HT enabling is still wrong with this patch if you have more than one virtual STA mode interface, but that never happens currently. Once WDS, IBSS or AP/VLAN gets HT capabilities, it will also be wrong, see the comment in ieee80211_enable_ht(). Additionally, this fixes a number of bugs: * mac80211: ieee80211_set_disassoc doesn't notify the driver any more since the refactoring * iwl-agn-rs: always uses the HT capabilities from the wrong stuff mac80211 gives it rather than the actual peer STA * ath9k: a number of bugs resulting from the broken HT API I'm not entirely happy with putting the HT capabilities into struct ieee80211_sta as restricted to our own HT TX capabilities, but I see no cleaner solution for now. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- drivers/net/wireless/ath9k/core.h | 6 +- drivers/net/wireless/ath9k/main.c | 41 ++++--- drivers/net/wireless/ath9k/rc.c | 8 +- drivers/net/wireless/ath9k/recv.c | 3 +- drivers/net/wireless/ath9k/xmit.c | 17 +-- drivers/net/wireless/iwlwifi/iwl-agn-rs.c | 23 ++-- drivers/net/wireless/iwlwifi/iwl-agn.c | 39 ++++--- drivers/net/wireless/iwlwifi/iwl-core.c | 17 +-- drivers/net/wireless/iwlwifi/iwl-dev.h | 1 - drivers/net/wireless/iwlwifi/iwl-sta.c | 33 ++++-- include/net/mac80211.h | 59 +++++----- net/mac80211/cfg.c | 6 +- net/mac80211/ht.c | 181 +++++++++++++----------------- net/mac80211/ieee80211_i.h | 12 +- net/mac80211/mlme.c | 88 ++++++++------- 15 files changed, 260 insertions(+), 274 deletions(-) (limited to 'drivers/net/wireless/ath9k/recv.c') diff --git a/drivers/net/wireless/ath9k/core.h b/drivers/net/wireless/ath9k/core.h index cb3e61e57c4d..59d835b72cd8 100644 --- a/drivers/net/wireless/ath9k/core.h +++ b/drivers/net/wireless/ath9k/core.h @@ -380,7 +380,6 @@ void ath_rx_cleanup(struct ath_softc *sc); int ath_rx_tasklet(struct ath_softc *sc, int flush); int ath_rx_input(struct ath_softc *sc, struct ath_node *node, - int is_ampdu, struct sk_buff *skb, struct ath_recv_status *rx_status, enum ATH_RX_TYPE *status); @@ -650,6 +649,9 @@ struct ath_node { u8 an_smmode; /* SM Power save mode */ u8 an_flags; u8 an_addr[ETH_ALEN]; + + u16 maxampdu; + u8 mpdudensity; }; void ath_tx_resume_tid(struct ath_softc *sc, @@ -919,8 +921,6 @@ enum RATE_TYPE { struct ath_ht_info { enum ath9k_ht_macmode tx_chan_width; - u16 maxampdu; - u8 mpdudensity; u8 ext_chan_offset; }; diff --git a/drivers/net/wireless/ath9k/main.c b/drivers/net/wireless/ath9k/main.c index 41cd114c438c..7555c3413384 100644 --- a/drivers/net/wireless/ath9k/main.c +++ b/drivers/net/wireless/ath9k/main.c @@ -330,25 +330,15 @@ static void ath9k_ht_conf(struct ath_softc *sc, { struct ath_ht_info *ht_info = &sc->sc_ht_info; - if (bss_conf->assoc_ht) { - ht_info->ext_chan_offset = - bss_conf->ht_bss_conf->bss_cap & - IEEE80211_HT_PARAM_CHA_SEC_OFFSET; - - if (!(bss_conf->ht_cap->cap & - IEEE80211_HT_CAP_40MHZ_INTOLERANT) && - (bss_conf->ht_bss_conf->bss_cap & - IEEE80211_HT_PARAM_CHAN_WIDTH_ANY)) + if (sc->hw->conf.ht.enabled) { + ht_info->ext_chan_offset = bss_conf->ht.secondary_channel_offset; + + if (bss_conf->ht.width_40_ok) ht_info->tx_chan_width = ATH9K_HT_MACMODE_2040; else ht_info->tx_chan_width = ATH9K_HT_MACMODE_20; ath9k_hw_set11nmac2040(sc->sc_ah, ht_info->tx_chan_width); - ht_info->maxampdu = 1 << (IEEE80211_HTCAP_MAXRXAMPDU_FACTOR + - bss_conf->ht_cap->ampdu_factor); - ht_info->mpdudensity = - parse_mpdudensity(bss_conf->ht_cap->ampdu_density); - } } @@ -390,7 +380,7 @@ static void ath9k_bss_assoc_info(struct ath_softc *sc, sc->sc_halstats.ns_avgtxrate = ATH_RATE_DUMMY_MARKER; /* Update chainmask */ - ath_update_chainmask(sc, bss_conf->assoc_ht); + ath_update_chainmask(sc, hw->conf.ht.enabled); DPRINTF(sc, ATH_DBG_CONFIG, "%s: bssid %pM aid 0x%x\n", @@ -408,7 +398,7 @@ static void ath9k_bss_assoc_info(struct ath_softc *sc, return; } - if (hw->conf.ht_cap.ht_supported) + if (hw->conf.ht.enabled) sc->sc_ah->ah_channels[pos].chanmode = ath_get_extchanmode(sc, curchan); else @@ -531,7 +521,6 @@ int _ath_rx_indicate(struct ath_softc *sc, if (an) { ath_rx_input(sc, an, - hw->conf.ht_cap.ht_supported, skb, status, &st); } if (!an || (st != ATH_RX_CONSUMED)) @@ -1241,6 +1230,9 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed) __func__, curchan->center_freq); + /* Update chainmask */ + ath_update_chainmask(sc, conf->ht.enabled); + pos = ath_get_channel(sc, curchan); if (pos == -1) { DPRINTF(sc, ATH_DBG_FATAL, "%s: Invalid channel\n", __func__); @@ -1251,7 +1243,7 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed) (curchan->band == IEEE80211_BAND_2GHZ) ? CHANNEL_G : CHANNEL_A; - if (sc->sc_curaid && hw->conf.ht_cap.ht_supported) + if (sc->sc_curaid && hw->conf.ht.enabled) sc->sc_ah->ah_channels[pos].chanmode = ath_get_extchanmode(sc, curchan); @@ -1434,6 +1426,14 @@ static void ath9k_sta_notify(struct ieee80211_hw *hw, } else { ath_node_get(sc, sta->addr); } + + /* XXX: Is this right? Can the capabilities change? */ + an = ath_node_find(sc, sta->addr); + an->maxampdu = 1 << (IEEE80211_HTCAP_MAXRXAMPDU_FACTOR + + sta->ht_cap.ampdu_factor); + an->mpdudensity = + parse_mpdudensity(sta->ht_cap.ampdu_density); + spin_unlock_irqrestore(&sc->node_lock, flags); break; case STA_NOTIFY_REMOVE: @@ -1552,9 +1552,8 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw, } if (changed & BSS_CHANGED_HT) { - DPRINTF(sc, ATH_DBG_CONFIG, "%s: BSS Changed HT %d\n", - __func__, - bss_conf->assoc_ht); + DPRINTF(sc, ATH_DBG_CONFIG, "%s: BSS Changed HT\n", + __func__); ath9k_ht_conf(sc, bss_conf); } diff --git a/drivers/net/wireless/ath9k/rc.c b/drivers/net/wireless/ath9k/rc.c index ee2dbce42b4d..9b2526030965 100644 --- a/drivers/net/wireless/ath9k/rc.c +++ b/drivers/net/wireless/ath9k/rc.c @@ -1838,7 +1838,7 @@ void ath_rc_node_update(struct ieee80211_hw *hw, struct ath_rate_node *rc_priv) struct ath_softc *sc = hw->priv; u32 capflag = 0; - if (hw->conf.ht_cap.ht_supported) { + if (hw->conf.ht.enabled) { capflag |= ATH_RC_HT_FLAG | ATH_RC_DS_FLAG; if (sc->sc_ht_info.tx_chan_width == ATH9K_HT_MACMODE_2040) capflag |= ATH_RC_CW40_FLAG; @@ -1979,7 +1979,7 @@ static void ath_get_rate(void *priv, struct ieee80211_supported_band *sband, /* Check if aggregation has to be enabled for this tid */ - if (hw->conf.ht_cap.ht_supported) { + if (hw->conf.ht.enabled) { if (ieee80211_is_data_qos(fc)) { qc = ieee80211_get_qos_ctl(hdr); tid = qc[0] & 0xf; @@ -2026,9 +2026,9 @@ static void ath_rate_init(void *priv, struct ieee80211_supported_band *sband, DPRINTF(sc, ATH_DBG_RATE, "%s\n", __func__); ath_setup_rates(sc, sband, sta, ath_rc_priv); - if (sc->hw->conf.flags & IEEE80211_CONF_SUPPORT_HT_MODE) { + if (sc->hw->conf.ht.enabled) { for (i = 0; i < 77; i++) { - if (sc->hw->conf.ht_cap.mcs.rx_mask[i/8] & (1<<(i%8))) + if (sta->ht_cap.mcs.rx_mask[i/8] & (1<<(i%8))) ath_rc_priv->neg_ht_rates.rs_rates[j++] = i; if (j == ATH_RATE_MAX) break; diff --git a/drivers/net/wireless/ath9k/recv.c b/drivers/net/wireless/ath9k/recv.c index 010fcdfec3f6..828322840a86 100644 --- a/drivers/net/wireless/ath9k/recv.c +++ b/drivers/net/wireless/ath9k/recv.c @@ -720,12 +720,11 @@ void ath_flushrecv(struct ath_softc *sc) int ath_rx_input(struct ath_softc *sc, struct ath_node *an, - int is_ampdu, struct sk_buff *skb, struct ath_recv_status *rx_status, enum ATH_RX_TYPE *status) { - if (is_ampdu && (sc->sc_flags & SC_OP_RXAGGR)) { + if (sc->sc_flags & SC_OP_RXAGGR) { *status = ATH_RX_CONSUMED; return ath_ampdu_input(sc, an, skb, rx_status); } else { diff --git a/drivers/net/wireless/ath9k/xmit.c b/drivers/net/wireless/ath9k/xmit.c index 3770fbe84fce..ba818cc2fb5c 100644 --- a/drivers/net/wireless/ath9k/xmit.c +++ b/drivers/net/wireless/ath9k/xmit.c @@ -300,7 +300,8 @@ static int ath_tx_prepare(struct ath_softc *sc, if (ieee80211_is_data(fc) && !txctl->use_minrate) { /* Enable HT only for DATA frames and not for EAPOL */ - txctl->ht = (hw->conf.ht_cap.ht_supported && + /* XXX why AMPDU only?? */ + txctl->ht = (hw->conf.ht.enabled && (tx_info->flags & IEEE80211_TX_CTL_AMPDU)); if (is_multicast_ether_addr(hdr->addr1)) { @@ -1450,7 +1451,8 @@ static int ath_tx_send_ampdu(struct ath_softc *sc, */ static u32 ath_lookup_rate(struct ath_softc *sc, - struct ath_buf *bf) + struct ath_buf *bf, + struct ath_atx_tid *tid) { const struct ath9k_rate_table *rt = sc->sc_currates; struct sk_buff *skb; @@ -1504,7 +1506,7 @@ static u32 ath_lookup_rate(struct ath_softc *sc, * The IE, however can hold upto 65536, which shows up here * as zero. Ignore 65536 since we are constrained by hw. */ - maxampdu = sc->sc_ht_info.maxampdu; + maxampdu = tid->an->maxampdu; if (maxampdu) aggr_limit = min(aggr_limit, maxampdu); @@ -1518,6 +1520,7 @@ static u32 ath_lookup_rate(struct ath_softc *sc, */ static int ath_compute_num_delims(struct ath_softc *sc, + struct ath_atx_tid *tid, struct ath_buf *bf, u16 frmlen) { @@ -1545,7 +1548,7 @@ static int ath_compute_num_delims(struct ath_softc *sc, * required minimum length for subframe. Take into account * whether high rate is 20 or 40Mhz and half or full GI. */ - mpdudensity = sc->sc_ht_info.mpdudensity; + mpdudensity = tid->an->mpdudensity; /* * If there is no mpdu density restriction, no further calculation @@ -1619,7 +1622,7 @@ static enum ATH_AGGR_STATUS ath_tx_form_aggr(struct ath_softc *sc, } if (!rl) { - aggr_limit = ath_lookup_rate(sc, bf); + aggr_limit = ath_lookup_rate(sc, bf, tid); rl = 1; /* * Is rate dual stream @@ -1657,7 +1660,7 @@ static enum ATH_AGGR_STATUS ath_tx_form_aggr(struct ath_softc *sc, * Get the delimiters needed to meet the MPDU * density for this node. */ - ndelim = ath_compute_num_delims(sc, bf_first, bf->bf_frmlen); + ndelim = ath_compute_num_delims(sc, tid, bf_first, bf->bf_frmlen); bpad = PADBYTES(al_delta) + (ndelim << 2); @@ -2629,7 +2632,7 @@ void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an) struct ath_atx_ac *ac; int tidno, acno; - sc->sc_ht_info.maxampdu = ATH_AMPDU_LIMIT_DEFAULT; + an->maxampdu = ATH_AMPDU_LIMIT_DEFAULT; /* * Init per tid tx state diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c index cd1bff590491..e10e0ca09ce9 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c @@ -1133,8 +1133,7 @@ static int rs_switch_to_mimo2(struct iwl_priv *priv, s32 rate; s8 is_green = lq_sta->is_green; - if (!(conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE) || - !sta->ht_cap.ht_supported) + if (!conf->ht.enabled || !sta->ht_cap.ht_supported) return -1; if (((sta->ht_cap.cap & IEEE80211_HT_CAP_SM_PS) >> 2) @@ -1201,8 +1200,7 @@ static int rs_switch_to_siso(struct iwl_priv *priv, u8 is_green = lq_sta->is_green; s32 rate; - if (!(conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE) || - !sta->ht_cap.ht_supported) + if (!conf->ht.enabled || !sta->ht_cap.ht_supported) return -1; IWL_DEBUG_RATE("LQ: try to switch to SISO\n"); @@ -2001,9 +1999,8 @@ lq_update: * stay with best antenna legacy modulation for a while * before next round of mode comparisons. */ tbl1 = &(lq_sta->lq_info[lq_sta->active_tbl]); - if (is_legacy(tbl1->lq_type) && - (!(conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE)) && - (lq_sta->action_counter >= 1)) { + if (is_legacy(tbl1->lq_type) && !conf->ht.enabled && + lq_sta->action_counter >= 1) { lq_sta->action_counter = 0; IWL_DEBUG_RATE("LQ: STAY in legacy table\n"); rs_set_stay_in_table(priv, 1, lq_sta); @@ -2238,19 +2235,19 @@ static void rs_rate_init(void *priv_r, struct ieee80211_supported_band *sband, * active_siso_rate mask includes 9 MBits (bit 5), and CCK (bits 0-3), * supp_rates[] does not; shift to convert format, force 9 MBits off. */ - lq_sta->active_siso_rate = conf->ht_cap.mcs.rx_mask[0] << 1; - lq_sta->active_siso_rate |= conf->ht_cap.mcs.rx_mask[0] & 0x1; + lq_sta->active_siso_rate = sta->ht_cap.mcs.rx_mask[0] << 1; + lq_sta->active_siso_rate |= sta->ht_cap.mcs.rx_mask[0] & 0x1; lq_sta->active_siso_rate &= ~((u16)0x2); lq_sta->active_siso_rate <<= IWL_FIRST_OFDM_RATE; /* Same here */ - lq_sta->active_mimo2_rate = conf->ht_cap.mcs.rx_mask[1] << 1; - lq_sta->active_mimo2_rate |= conf->ht_cap.mcs.rx_mask[1] & 0x1; + lq_sta->active_mimo2_rate = sta->ht_cap.mcs.rx_mask[1] << 1; + lq_sta->active_mimo2_rate |= sta->ht_cap.mcs.rx_mask[1] & 0x1; lq_sta->active_mimo2_rate &= ~((u16)0x2); lq_sta->active_mimo2_rate <<= IWL_FIRST_OFDM_RATE; - lq_sta->active_mimo3_rate = conf->ht_cap.mcs.rx_mask[2] << 1; - lq_sta->active_mimo3_rate |= conf->ht_cap.mcs.rx_mask[2] & 0x1; + lq_sta->active_mimo3_rate = sta->ht_cap.mcs.rx_mask[2] << 1; + lq_sta->active_mimo3_rate |= sta->ht_cap.mcs.rx_mask[2] & 0x1; lq_sta->active_mimo3_rate &= ~((u16)0x2); lq_sta->active_mimo3_rate <<= IWL_FIRST_OFDM_RATE; diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 79a24410dd0a..7c3eb3d8f7e7 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -552,17 +552,30 @@ static int iwl4965_send_beacon_cmd(struct iwl_priv *priv) static void iwl4965_ht_conf(struct iwl_priv *priv, struct ieee80211_bss_conf *bss_conf) { - struct ieee80211_sta_ht_cap *ht_conf = bss_conf->ht_cap; - struct ieee80211_ht_bss_info *ht_bss_conf = bss_conf->ht_bss_conf; + struct ieee80211_sta_ht_cap *ht_conf; struct iwl_ht_info *iwl_conf = &priv->current_ht_config; + struct ieee80211_sta *sta; IWL_DEBUG_MAC80211("enter: \n"); - iwl_conf->is_ht = bss_conf->assoc_ht; - if (!iwl_conf->is_ht) return; + + /* + * It is totally wrong to base global information on something + * that is valid only when associated, alas, this driver works + * that way and I don't know how to fix it. + */ + + rcu_read_lock(); + sta = ieee80211_find_sta(priv->hw, priv->bssid); + if (!sta) { + rcu_read_unlock(); + return; + } + ht_conf = &sta->ht_cap; + if (ht_conf->cap & IEEE80211_HT_CAP_SGI_20) iwl_conf->sgf |= HT_SHORT_GI_20MHZ; if (ht_conf->cap & IEEE80211_HT_CAP_SGI_40) @@ -574,8 +587,8 @@ static void iwl4965_ht_conf(struct iwl_priv *priv, iwl_conf->supported_chan_width = !!(ht_conf->cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40); - iwl_conf->extension_chan_offset = - ht_bss_conf->bss_cap & IEEE80211_HT_PARAM_CHA_SEC_OFFSET; + + iwl_conf->extension_chan_offset = bss_conf->ht.secondary_channel_offset; /* If no above or below channel supplied disable FAT channel */ if (iwl_conf->extension_chan_offset != IEEE80211_HT_PARAM_CHA_SEC_ABOVE && iwl_conf->extension_chan_offset != IEEE80211_HT_PARAM_CHA_SEC_BELOW) { @@ -587,15 +600,14 @@ static void iwl4965_ht_conf(struct iwl_priv *priv, memcpy(&iwl_conf->mcs, &ht_conf->mcs, 16); - iwl_conf->control_channel = ht_bss_conf->primary_channel; - iwl_conf->tx_chan_width = - !!(ht_bss_conf->bss_cap & IEEE80211_HT_PARAM_CHAN_WIDTH_ANY); + iwl_conf->tx_chan_width = bss_conf->ht.width_40_ok; iwl_conf->ht_protection = - ht_bss_conf->bss_op_mode & IEEE80211_HT_OP_MODE_PROTECTION; + bss_conf->ht.operation_mode & IEEE80211_HT_OP_MODE_PROTECTION; iwl_conf->non_GF_STA_present = - !!(ht_bss_conf->bss_op_mode & IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT); + !!(bss_conf->ht.operation_mode & IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT); + + rcu_read_unlock(); - IWL_DEBUG_MAC80211("control channel %d\n", iwl_conf->control_channel); IWL_DEBUG_MAC80211("leave\n"); } @@ -2746,6 +2758,8 @@ static int iwl4965_mac_config(struct ieee80211_hw *hw, u32 changed) mutex_lock(&priv->mutex); IWL_DEBUG_MAC80211("enter to channel %d\n", conf->channel->hw_value); + priv->current_ht_config.is_ht = conf->ht.enabled; + if (conf->radio_enabled && iwl_radio_kill_sw_enable_radio(priv)) { IWL_DEBUG_MAC80211("leave - RF-KILL - waiting for uCode\n"); goto out; @@ -3104,7 +3118,6 @@ static void iwl4965_bss_info_changed(struct ieee80211_hw *hw, } if (changes & BSS_CHANGED_HT) { - IWL_DEBUG_MAC80211("HT %d\n", bss_conf->assoc_ht); iwl4965_ht_conf(priv, bss_conf); iwl_set_rxon_chain(priv); } diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 4678da447ff6..10f5a0a233fe 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -637,8 +637,8 @@ u8 iwl_is_fat_tx_allowed(struct iwl_priv *priv, } return iwl_is_channel_extension(priv, priv->band, - iwl_ht_conf->control_channel, - iwl_ht_conf->extension_chan_offset); + le16_to_cpu(priv->staging_rxon.channel), + iwl_ht_conf->extension_chan_offset); } EXPORT_SYMBOL(iwl_is_fat_tx_allowed); @@ -663,13 +663,6 @@ void iwl_set_rxon_ht(struct iwl_priv *priv, struct iwl_ht_info *ht_info) rxon->flags &= ~(RXON_FLG_CHANNEL_MODE_MIXED_MSK | RXON_FLG_CHANNEL_MODE_PURE_40_MSK); - if (le16_to_cpu(rxon->channel) != ht_info->control_channel) { - IWL_DEBUG_ASSOC("control diff than current %d %d\n", - le16_to_cpu(rxon->channel), - ht_info->control_channel); - return; - } - /* Note: control channel is opposite of extension channel */ switch (ht_info->extension_chan_offset) { case IEEE80211_HT_PARAM_CHA_SEC_ABOVE: @@ -692,14 +685,12 @@ void iwl_set_rxon_ht(struct iwl_priv *priv, struct iwl_ht_info *ht_info) IWL_DEBUG_ASSOC("supported HT rate 0x%X 0x%X 0x%X " "rxon flags 0x%X operation mode :0x%X " - "extension channel offset 0x%x " - "control chan %d\n", + "extension channel offset 0x%x\n", ht_info->mcs.rx_mask[0], ht_info->mcs.rx_mask[1], ht_info->mcs.rx_mask[2], le32_to_cpu(rxon->flags), ht_info->ht_protection, - ht_info->extension_chan_offset, - ht_info->control_channel); + ht_info->extension_chan_offset); return; } EXPORT_SYMBOL(iwl_set_rxon_ht); diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 572250ee9d58..2e9514933970 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -413,7 +413,6 @@ struct iwl_ht_info { u8 mpdu_density; struct ieee80211_mcs_info mcs; /* BSS related data */ - u8 control_channel; u8 extension_chan_offset; u8 tx_chan_width; u8 ht_protection; diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c index b9b8554433a6..218483d096cc 100644 --- a/drivers/net/wireless/iwlwifi/iwl-sta.c +++ b/drivers/net/wireless/iwlwifi/iwl-sta.c @@ -890,20 +890,31 @@ static void iwl_sta_init_lq(struct iwl_priv *priv, const u8 *addr, int is_ap) */ int iwl_rxon_add_station(struct iwl_priv *priv, const u8 *addr, int is_ap) { + struct ieee80211_sta *sta; + struct ieee80211_sta_ht_cap ht_config; + struct ieee80211_sta_ht_cap *cur_ht_config = NULL; u8 sta_id; /* Add station to device's station table */ - struct ieee80211_conf *conf = &priv->hw->conf; - struct ieee80211_sta_ht_cap *cur_ht_config = &conf->ht_cap; - - if ((is_ap) && - (conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE) && - (priv->iw_mode == NL80211_IFTYPE_STATION)) - sta_id = iwl_add_station_flags(priv, addr, is_ap, - 0, cur_ht_config); - else - sta_id = iwl_add_station_flags(priv, addr, is_ap, - 0, NULL); + + /* + * XXX: This check is definitely not correct, if we're an AP + * it'll always be false which is not what we want, but + * it doesn't look like iwlagn is prepared to be an HT + * AP anyway. + */ + if (priv->current_ht_config.is_ht) { + rcu_read_lock(); + sta = ieee80211_find_sta(priv->hw, addr); + if (sta) { + memcpy(&ht_config, &sta->ht_cap, sizeof(ht_config)); + cur_ht_config = &ht_config; + } + rcu_read_unlock(); + } + + sta_id = iwl_add_station_flags(priv, addr, is_ap, + 0, cur_ht_config); /* Set up default rate scaling table in device's station table */ iwl_sta_init_lq(priv, addr, is_ap); diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 94ff3eface49..9801afb62545 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -3,7 +3,7 @@ * * Copyright 2002-2005, Devicescape Software, Inc. * Copyright 2006-2007 Jiri Benc - * Copyright 2007 Johannes Berg + * Copyright 2007-2008 Johannes Berg * * 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 @@ -81,22 +81,6 @@ enum ieee80211_notification_types { IEEE80211_NOTIFY_RE_ASSOC, }; -/** - * struct ieee80211_ht_bss_info - describing BSS's HT characteristics - * - * This structure describes most essential parameters needed - * to describe 802.11n HT characteristics in a BSS. - * - * @primary_channel: channel number of primery channel - * @bss_cap: 802.11n's general BSS capabilities (e.g. channel width) - * @bss_op_mode: 802.11n's BSS operation modes (e.g. HT protection) - */ -struct ieee80211_ht_bss_info { - u8 primary_channel; - u8 bss_cap; /* use IEEE80211_HT_IE_CHA_ */ - u8 bss_op_mode; /* use IEEE80211_HT_IE_ */ -}; - /** * enum ieee80211_max_queues - maximum number of queues * @@ -171,6 +155,19 @@ enum ieee80211_bss_change { BSS_CHANGED_BASIC_RATES = 1<<5, }; +/** + * struct ieee80211_bss_ht_conf - BSS's changing HT configuration + * @secondary_channel_offset: secondary channel offset, uses + * %IEEE80211_HT_PARAM_CHA_SEC_ values + * @width_40_ok: indicates that 40 MHz bandwidth may be used for TX + * @operation_mode: HT operation mode (like in &struct ieee80211_ht_info) + */ +struct ieee80211_bss_ht_conf { + u8 secondary_channel_offset; + bool width_40_ok; + u16 operation_mode; +}; + /** * struct ieee80211_bss_conf - holds the BSS's changing parameters * @@ -190,9 +187,7 @@ enum ieee80211_bss_change { * @timestamp: beacon timestamp * @beacon_int: beacon interval * @assoc_capability: capabilities taken from assoc resp - * @assoc_ht: association in HT mode - * @ht_cap: ht capabilities - * @ht_bss_conf: ht extended capabilities + * @ht: BSS's HT configuration * @basic_rates: bitmap of basic rates, each bit stands for an * index into the rate table configured by the driver in * the current band. @@ -210,10 +205,7 @@ struct ieee80211_bss_conf { u16 assoc_capability; u64 timestamp; u64 basic_rates; - /* ht related data */ - bool assoc_ht; - struct ieee80211_sta_ht_cap *ht_cap; - struct ieee80211_ht_bss_info *ht_bss_conf; + struct ieee80211_bss_ht_conf ht; }; /** @@ -447,13 +439,11 @@ struct ieee80211_rx_status { * Flags to define PHY configuration options * * @IEEE80211_CONF_RADIOTAP: add radiotap header at receive time (if supported) - * @IEEE80211_CONF_SUPPORT_HT_MODE: use 802.11n HT capabilities (if supported) * @IEEE80211_CONF_PS: Enable 802.11 power save mode */ enum ieee80211_conf_flags { IEEE80211_CONF_RADIOTAP = (1<<0), - IEEE80211_CONF_SUPPORT_HT_MODE = (1<<1), - IEEE80211_CONF_PS = (1<<2), + IEEE80211_CONF_PS = (1<<1), }; /* XXX: remove all this once drivers stop trying to use it */ @@ -463,6 +453,10 @@ static inline int __deprecated __IEEE80211_CONF_SHORT_SLOT_TIME(void) } #define IEEE80211_CONF_SHORT_SLOT_TIME (__IEEE80211_CONF_SHORT_SLOT_TIME()) +struct ieee80211_ht_conf { + bool enabled; +}; + /** * enum ieee80211_conf_changed - denotes which configuration changed * @@ -474,6 +468,7 @@ static inline int __deprecated __IEEE80211_CONF_SHORT_SLOT_TIME(void) * @IEEE80211_CONF_CHANGE_POWER: the TX power changed * @IEEE80211_CONF_CHANGE_CHANNEL: the channel changed * @IEEE80211_CONF_CHANGE_RETRY_LIMITS: retry limits changed + * @IEEE80211_CONF_CHANGE_HT: HT configuration changed */ enum ieee80211_conf_changed { IEEE80211_CONF_CHANGE_RADIO_ENABLED = BIT(0), @@ -484,6 +479,7 @@ enum ieee80211_conf_changed { IEEE80211_CONF_CHANGE_POWER = BIT(5), IEEE80211_CONF_CHANGE_CHANNEL = BIT(6), IEEE80211_CONF_CHANGE_RETRY_LIMITS = BIT(7), + IEEE80211_CONF_CHANGE_HT = BIT(8), }; /** @@ -496,9 +492,8 @@ enum ieee80211_conf_changed { * @listen_interval: listen interval in units of beacon interval * @flags: configuration flags defined above * @power_level: requested transmit power (in dBm) - * @ht_cap: describes current self configuration of 802.11n HT capabilities - * @ht_bss_conf: describes current BSS configuration of 802.11n HT parameters * @channel: the channel to tune to + * @ht: the HT configuration for the device * @long_frame_max_tx_count: Maximum number of transmissions for a "long" frame * (a frame not RTS protected), called "dot11LongRetryLimit" in 802.11, * but actually means the number of transmissions not the number of retries @@ -517,9 +512,7 @@ struct ieee80211_conf { u8 long_frame_max_tx_count, short_frame_max_tx_count; struct ieee80211_channel *channel; - - struct ieee80211_sta_ht_cap ht_cap; - struct ieee80211_ht_bss_info ht_bss_conf; + struct ieee80211_ht_conf ht; }; /** @@ -715,7 +708,7 @@ enum set_key_cmd { * @addr: MAC address * @aid: AID we assigned to the station if we're an AP * @supp_rates: Bitmap of supported rates (per band) - * @ht_cap: HT capabilities of this STA + * @ht_cap: HT capabilities of this STA; restricted to our own TX capabilities * @drv_priv: data area for driver use, will always be aligned to * sizeof(void *), size is determined in hw information. */ diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 28382b5c7c25..55e3a26510ed 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -582,6 +582,8 @@ static void sta_apply_parameters(struct ieee80211_local *local, struct ieee80211_supported_band *sband; struct ieee80211_sub_if_data *sdata = sta->sdata; + sband = local->hw.wiphy->bands[local->oper_channel->band]; + /* * FIXME: updating the flags is racy when this function is * called from ieee80211_change_station(), this will @@ -622,7 +624,6 @@ static void sta_apply_parameters(struct ieee80211_local *local, if (params->supported_rates) { rates = 0; - sband = local->hw.wiphy->bands[local->oper_channel->band]; for (i = 0; i < params->supported_rates_len; i++) { int rate = (params->supported_rates[i] & 0x7f) * 5; @@ -635,7 +636,8 @@ static void sta_apply_parameters(struct ieee80211_local *local, } if (params->ht_capa) - ieee80211_ht_cap_ie_to_sta_ht_cap(params->ht_capa, + ieee80211_ht_cap_ie_to_sta_ht_cap(sband, + params->ht_capa, &sta->sta.ht_cap); if (ieee80211_vif_is_mesh(&sdata->vif) && params->plink_action) { diff --git a/net/mac80211/ht.c b/net/mac80211/ht.c index e2d121bf2745..42c3e590df98 100644 --- a/net/mac80211/ht.c +++ b/net/mac80211/ht.c @@ -20,114 +20,38 @@ #include "sta_info.h" #include "wme.h" -void ieee80211_ht_cap_ie_to_sta_ht_cap(struct ieee80211_ht_cap *ht_cap_ie, +void ieee80211_ht_cap_ie_to_sta_ht_cap(struct ieee80211_supported_band *sband, + struct ieee80211_ht_cap *ht_cap_ie, struct ieee80211_sta_ht_cap *ht_cap) { + u8 ampdu_info, tx_mcs_set_cap; + int i, max_tx_streams; BUG_ON(!ht_cap); memset(ht_cap, 0, sizeof(*ht_cap)); - if (ht_cap_ie) { - u8 ampdu_info = ht_cap_ie->ampdu_params_info; - - ht_cap->ht_supported = true; - ht_cap->cap = le16_to_cpu(ht_cap_ie->cap_info); - ht_cap->ampdu_factor = - ampdu_info & IEEE80211_HT_AMPDU_PARM_FACTOR; - ht_cap->ampdu_density = - (ampdu_info & IEEE80211_HT_AMPDU_PARM_DENSITY) >> 2; - memcpy(&ht_cap->mcs, &ht_cap_ie->mcs, sizeof(ht_cap->mcs)); - } else - ht_cap->ht_supported = false; -} - -void ieee80211_ht_info_ie_to_ht_bss_info( - struct ieee80211_ht_info *ht_add_info_ie, - struct ieee80211_ht_bss_info *bss_info) -{ - BUG_ON(!bss_info); - - memset(bss_info, 0, sizeof(*bss_info)); - - if (ht_add_info_ie) { - u16 op_mode; - op_mode = le16_to_cpu(ht_add_info_ie->operation_mode); - - bss_info->primary_channel = ht_add_info_ie->control_chan; - bss_info->bss_cap = ht_add_info_ie->ht_param; - bss_info->bss_op_mode = (u8)(op_mode & 0xff); - } -} - -/* - * ieee80211_handle_ht should be called only after the operating band - * has been determined as ht configuration depends on the hw's - * HT abilities for a specific band. - */ -u32 ieee80211_handle_ht(struct ieee80211_local *local, - struct ieee80211_sta_ht_cap *req_ht_cap, - struct ieee80211_ht_bss_info *req_bss_cap) -{ - struct ieee80211_conf *conf = &local->hw.conf; - struct ieee80211_supported_band *sband; - struct ieee80211_sta_ht_cap ht_cap; - struct ieee80211_ht_bss_info ht_bss_conf; - u32 changed = 0; - int i; - u8 max_tx_streams; - u8 tx_mcs_set_cap; - bool enable_ht = true; - - sband = local->hw.wiphy->bands[conf->channel->band]; - - memset(&ht_cap, 0, sizeof(ht_cap)); - memset(&ht_bss_conf, 0, sizeof(struct ieee80211_ht_bss_info)); - - /* HT is not supported */ - if (!sband->ht_cap.ht_supported) - enable_ht = false; - - /* disable HT */ - if (!enable_ht) { - if (conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE) - changed |= BSS_CHANGED_HT; - conf->flags &= ~IEEE80211_CONF_SUPPORT_HT_MODE; - conf->ht_cap.ht_supported = false; - return changed; - } - - - if (!(conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE)) - changed |= BSS_CHANGED_HT; - - conf->flags |= IEEE80211_CONF_SUPPORT_HT_MODE; - ht_cap.ht_supported = true; + if (!ht_cap_ie) + return; - ht_cap.cap = req_ht_cap->cap & sband->ht_cap.cap; - ht_cap.cap &= ~IEEE80211_HT_CAP_SM_PS; - ht_cap.cap |= sband->ht_cap.cap & IEEE80211_HT_CAP_SM_PS; + ht_cap->ht_supported = true; - ht_bss_conf.primary_channel = req_bss_cap->primary_channel; - ht_bss_conf.bss_cap = req_bss_cap->bss_cap; - ht_bss_conf.bss_op_mode = req_bss_cap->bss_op_mode; + ht_cap->cap = ht_cap->cap & sband->ht_cap.cap; + ht_cap->cap &= ~IEEE80211_HT_CAP_SM_PS; + ht_cap->cap |= sband->ht_cap.cap & IEEE80211_HT_CAP_SM_PS; - ht_cap.ampdu_factor = req_ht_cap->ampdu_factor; - ht_cap.ampdu_density = req_ht_cap->ampdu_density; + ampdu_info = ht_cap_ie->ampdu_params_info; + ht_cap->ampdu_factor = + ampdu_info & IEEE80211_HT_AMPDU_PARM_FACTOR; + ht_cap->ampdu_density = + (ampdu_info & IEEE80211_HT_AMPDU_PARM_DENSITY) >> 2; /* own MCS TX capabilities */ tx_mcs_set_cap = sband->ht_cap.mcs.tx_params; - /* - * configure supported Tx MCS according to requested MCS - * (based in most cases on Rx capabilities of peer) and self - * Tx MCS capabilities (as defined by low level driver HW - * Tx capabilities) - */ - /* can we TX with MCS rates? */ if (!(tx_mcs_set_cap & IEEE80211_HT_MCS_TX_DEFINED)) - goto check_changed; + return; /* Counting from 0, therefore +1 */ if (tx_mcs_set_cap & IEEE80211_HT_MCS_TX_RX_DIFF) @@ -145,29 +69,73 @@ u32 ieee80211_handle_ht(struct ieee80211_local *local, * - remainder are multiple spatial streams using unequal modulation */ for (i = 0; i < max_tx_streams; i++) - ht_cap.mcs.rx_mask[i] = - sband->ht_cap.mcs.rx_mask[i] & - req_ht_cap->mcs.rx_mask[i]; + ht_cap->mcs.rx_mask[i] = + sband->ht_cap.mcs.rx_mask[i] & ht_cap_ie->mcs.rx_mask[i]; if (tx_mcs_set_cap & IEEE80211_HT_MCS_TX_UNEQUAL_MODULATION) for (i = IEEE80211_HT_MCS_UNEQUAL_MODULATION_START_BYTE; i < IEEE80211_HT_MCS_MASK_LEN; i++) - ht_cap.mcs.rx_mask[i] = + ht_cap->mcs.rx_mask[i] = sband->ht_cap.mcs.rx_mask[i] & - req_ht_cap->mcs.rx_mask[i]; + ht_cap_ie->mcs.rx_mask[i]; /* handle MCS rate 32 too */ - if (sband->ht_cap.mcs.rx_mask[32/8] & - req_ht_cap->mcs.rx_mask[32/8] & 1) - ht_cap.mcs.rx_mask[32/8] |= 1; + if (sband->ht_cap.mcs.rx_mask[32/8] & ht_cap_ie->mcs.rx_mask[32/8] & 1) + ht_cap->mcs.rx_mask[32/8] |= 1; +} + +/* + * ieee80211_enable_ht should be called only after the operating band + * has been determined as ht configuration depends on the hw's + * HT abilities for a specific band. + */ +u32 ieee80211_enable_ht(struct ieee80211_sub_if_data *sdata, + struct ieee80211_ht_info *hti, + u16 ap_ht_cap_flags) +{ + struct ieee80211_local *local = sdata->local; + struct ieee80211_supported_band *sband; + struct ieee80211_bss_ht_conf ht; + u32 changed = 0; + bool enable_ht = true, ht_changed; + + sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; + + memset(&ht, 0, sizeof(ht)); + + /* HT is not supported */ + if (!sband->ht_cap.ht_supported) + enable_ht = false; + + /* check that channel matches the right operating channel */ + if (local->hw.conf.channel->center_freq != + ieee80211_channel_to_frequency(hti->control_chan)) + enable_ht = false; + + /* + * XXX: This is totally incorrect when there are multiple virtual + * interfaces, needs to be fixed later. + */ + ht_changed = local->hw.conf.ht.enabled != enable_ht; + local->hw.conf.ht.enabled = enable_ht; + if (ht_changed) + ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_HT); + + /* disable HT */ + if (!enable_ht) + return 0; + ht.secondary_channel_offset = + hti->ht_param & IEEE80211_HT_PARAM_CHA_SEC_OFFSET; + ht.width_40_ok = + !(ap_ht_cap_flags & IEEE80211_HT_CAP_40MHZ_INTOLERANT) && + (sband->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) && + (hti->ht_param & IEEE80211_HT_PARAM_CHAN_WIDTH_ANY); + ht.operation_mode = le16_to_cpu(hti->operation_mode); - check_changed: /* if bss configuration changed store the new one */ - if (memcmp(&conf->ht_cap, &ht_cap, sizeof(ht_cap)) || - memcmp(&conf->ht_bss_conf, &ht_bss_conf, sizeof(ht_bss_conf))) { + if (memcmp(&sdata->vif.bss_conf.ht, &ht, sizeof(ht))) { changed |= BSS_CHANGED_HT; - memcpy(&conf->ht_cap, &ht_cap, sizeof(ht_cap)); - memcpy(&conf->ht_bss_conf, &ht_bss_conf, sizeof(ht_bss_conf)); + sdata->vif.bss_conf.ht = ht; } return changed; @@ -900,8 +868,9 @@ void ieee80211_process_addba_request(struct ieee80211_local *local, /* sanity check for incoming parameters: * check if configuration can support the BA policy * and if buffer size does not exceeds max value */ + /* XXX: check own ht delayed BA capability?? */ if (((ba_policy != 1) - && (!(conf->ht_cap.cap & IEEE80211_HT_CAP_DELAY_BA))) + && (!(sta->sta.ht_cap.cap & IEEE80211_HT_CAP_DELAY_BA))) || (buf_size > IEEE80211_MAX_AMPDU_BUF)) { status = WLAN_STATUS_INVALID_QOS_PARAM; #ifdef CONFIG_MAC80211_HT_DEBUG diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 859b5b001f22..6f8756d26a93 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -955,14 +955,12 @@ int ieee80211_monitor_start_xmit(struct sk_buff *skb, struct net_device *dev); int ieee80211_subif_start_xmit(struct sk_buff *skb, struct net_device *dev); /* HT */ -void ieee80211_ht_cap_ie_to_sta_ht_cap(struct ieee80211_ht_cap *ht_cap_ie, +void ieee80211_ht_cap_ie_to_sta_ht_cap(struct ieee80211_supported_band *sband, + struct ieee80211_ht_cap *ht_cap_ie, struct ieee80211_sta_ht_cap *ht_cap); -void ieee80211_ht_info_ie_to_ht_bss_info( - struct ieee80211_ht_info *ht_add_info_ie, - struct ieee80211_ht_bss_info *bss_info); -u32 ieee80211_handle_ht(struct ieee80211_local *local, - struct ieee80211_sta_ht_cap *req_ht_cap, - struct ieee80211_ht_bss_info *req_bss_cap); +u32 ieee80211_enable_ht(struct ieee80211_sub_if_data *sdata, + struct ieee80211_ht_info *hti, + u16 ap_ht_cap_flags); void ieee80211_send_bar(struct ieee80211_sub_if_data *sdata, u8 *ra, u16 tid, u16 ssn); void ieee80211_sta_stop_rx_ba_session(struct ieee80211_sub_if_data *sdata, u8 *da, diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 9c5f5c37a49e..39bc9c69893b 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -700,14 +700,15 @@ static void ieee80211_sta_send_associnfo(struct ieee80211_sub_if_data *sdata, static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata, - struct ieee80211_if_sta *ifsta) + struct ieee80211_if_sta *ifsta, + u32 bss_info_changed) { struct ieee80211_local *local = sdata->local; struct ieee80211_conf *conf = &local_to_hw(local)->conf; - u32 changed = BSS_CHANGED_ASSOC; struct ieee80211_bss *bss; + bss_info_changed |= BSS_CHANGED_ASSOC; ifsta->flags |= IEEE80211_STA_ASSOCIATED; if (sdata->vif.type != NL80211_IFTYPE_STATION) @@ -722,19 +723,12 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata, sdata->vif.bss_conf.timestamp = bss->timestamp; sdata->vif.bss_conf.dtim_period = bss->dtim_period; - changed |= ieee80211_handle_bss_capability(sdata, + bss_info_changed |= ieee80211_handle_bss_capability(sdata, bss->capability, bss->has_erp_value, bss->erp_value); ieee80211_rx_bss_put(local, bss); } - if (conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE) { - changed |= BSS_CHANGED_HT; - sdata->vif.bss_conf.assoc_ht = 1; - sdata->vif.bss_conf.ht_cap = &conf->ht_cap; - sdata->vif.bss_conf.ht_bss_conf = &conf->ht_bss_conf; - } - ifsta->flags |= IEEE80211_STA_PREV_BSSID_SET; memcpy(ifsta->prev_bssid, sdata->u.sta.bssid, ETH_ALEN); ieee80211_sta_send_associnfo(sdata, ifsta); @@ -748,8 +742,8 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata, * when we have associated, we aren't checking whether it actually * changed or not. */ - changed |= BSS_CHANGED_BASIC_RATES; - ieee80211_bss_info_change_notify(sdata, changed); + bss_info_changed |= BSS_CHANGED_BASIC_RATES; + ieee80211_bss_info_change_notify(sdata, bss_info_changed); netif_tx_start_all_queues(sdata->dev); netif_carrier_on(sdata->dev); @@ -813,7 +807,7 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata, { struct ieee80211_local *local = sdata->local; struct sta_info *sta; - u32 changed = BSS_CHANGED_ASSOC; + u32 changed = 0; rcu_read_lock(); @@ -847,15 +841,9 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata, ifsta->flags &= ~IEEE80211_STA_ASSOCIATED; changed |= ieee80211_reset_erp_info(sdata); - if (sdata->vif.bss_conf.assoc_ht) - changed |= BSS_CHANGED_HT; - - sdata->vif.bss_conf.assoc_ht = 0; - sdata->vif.bss_conf.ht_cap = NULL; - sdata->vif.bss_conf.ht_bss_conf = NULL; - ieee80211_led_assoc(local, 0); - sdata->vif.bss_conf.assoc = 0; + changed |= BSS_CHANGED_ASSOC; + sdata->vif.bss_conf.assoc = false; ieee80211_sta_send_apinfo(sdata, ifsta); @@ -867,6 +855,11 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata, rcu_read_unlock(); sta_info_destroy(sta); + + local->hw.conf.ht.enabled = false; + ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_HT); + + ieee80211_bss_info_change_notify(sdata, changed); } static int ieee80211_sta_wep_configured(struct ieee80211_sub_if_data *sdata) @@ -1184,8 +1177,10 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata, struct ieee802_11_elems elems; struct ieee80211_bss_conf *bss_conf = &sdata->vif.bss_conf; u8 *pos; + u32 changed = 0; int i, j; bool have_higher_than_11mbit = false; + u16 ap_ht_cap_flags; /* AssocResp and ReassocResp have identical structure, so process both * of them in this function. */ @@ -1333,15 +1328,11 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata, else sdata->flags &= ~IEEE80211_SDATA_OPERATING_GMODE; - if (elems.ht_cap_elem && elems.ht_info_elem && elems.wmm_param && - (ifsta->flags & IEEE80211_STA_WMM_ENABLED)) { - struct ieee80211_ht_bss_info bss_info; - ieee80211_ht_cap_ie_to_sta_ht_cap( + if (elems.ht_cap_elem) + ieee80211_ht_cap_ie_to_sta_ht_cap(sband, elems.ht_cap_elem, &sta->sta.ht_cap); - ieee80211_ht_info_ie_to_ht_bss_info( - elems.ht_info_elem, &bss_info); - ieee80211_handle_ht(local, &sta->sta.ht_cap, &bss_info); - } + + ap_ht_cap_flags = sta->sta.ht_cap.cap; rate_control_rate_init(sta); @@ -1353,11 +1344,16 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata, } else rcu_read_unlock(); + if (elems.ht_info_elem && elems.wmm_param && + (ifsta->flags & IEEE80211_STA_WMM_ENABLED)) + changed |= ieee80211_enable_ht(sdata, elems.ht_info_elem, + ap_ht_cap_flags); + /* set AID and assoc capability, * ieee80211_set_associated() will tell the driver */ bss_conf->aid = aid; bss_conf->assoc_capability = capab_info; - ieee80211_set_associated(sdata, ifsta); + ieee80211_set_associated(sdata, ifsta, changed); ieee80211_associated(sdata, ifsta); } @@ -1657,7 +1653,6 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata, size_t baselen; struct ieee802_11_elems elems; struct ieee80211_local *local = sdata->local; - struct ieee80211_conf *conf = &local->hw.conf; u32 changed = 0; bool erp_valid; u8 erp_value = 0; @@ -1693,14 +1688,31 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata, le16_to_cpu(mgmt->u.beacon.capab_info), erp_valid, erp_value); - if (elems.ht_cap_elem && elems.ht_info_elem && - elems.wmm_param && conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE) { - struct ieee80211_ht_bss_info bss_info; - ieee80211_ht_info_ie_to_ht_bss_info( - elems.ht_info_elem, &bss_info); - changed |= ieee80211_handle_ht(local, &conf->ht_cap, - &bss_info); + if (elems.ht_cap_elem && elems.ht_info_elem && elems.wmm_param) { + struct sta_info *sta; + struct ieee80211_supported_band *sband; + u16 ap_ht_cap_flags; + + rcu_read_lock(); + + sta = sta_info_get(local, ifsta->bssid); + if (!sta) { + rcu_read_unlock(); + return; + } + + sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; + + ieee80211_ht_cap_ie_to_sta_ht_cap(sband, + elems.ht_cap_elem, &sta->sta.ht_cap); + + ap_ht_cap_flags = sta->sta.ht_cap.cap; + + rcu_read_unlock(); + + changed |= ieee80211_enable_ht(sdata, elems.ht_info_elem, + ap_ht_cap_flags); } ieee80211_bss_info_change_notify(sdata, changed); -- cgit v1.2.3 From b5aa9bf9460f9e97f2c10940b029d75c6557ad7c Mon Sep 17 00:00:00 2001 From: Sujith Date: Wed, 29 Oct 2008 10:13:31 +0530 Subject: ath9k: Node cleanup Start removing the internal node list in ath9k, in preparation for using mac80211's STA list. Remove lists, locks, routines, flags, functions managing nodes in ath9k. Signed-off-by: Sujith Signed-off-by: John W. Linville --- drivers/net/wireless/ath9k/core.c | 116 +++++++++++++++----------------------- drivers/net/wireless/ath9k/core.h | 46 ++++----------- drivers/net/wireless/ath9k/main.c | 94 +++--------------------------- drivers/net/wireless/ath9k/rc.c | 15 +---- drivers/net/wireless/ath9k/recv.c | 42 ++------------ drivers/net/wireless/ath9k/xmit.c | 107 +++++++---------------------------- 6 files changed, 94 insertions(+), 326 deletions(-) (limited to 'drivers/net/wireless/ath9k/recv.c') diff --git a/drivers/net/wireless/ath9k/core.c b/drivers/net/wireless/ath9k/core.c index 0089e023c609..49fc264cfe5a 100644 --- a/drivers/net/wireless/ath9k/core.c +++ b/drivers/net/wireless/ath9k/core.c @@ -47,6 +47,41 @@ static void bus_read_cachesize(struct ath_softc *sc, int *csz) *csz = DEFAULT_CACHELINE >> 2; /* Use the default size */ } +static u8 parse_mpdudensity(u8 mpdudensity) +{ + /* + * 802.11n D2.0 defined values for "Minimum MPDU Start Spacing": + * 0 for no restriction + * 1 for 1/4 us + * 2 for 1/2 us + * 3 for 1 us + * 4 for 2 us + * 5 for 4 us + * 6 for 8 us + * 7 for 16 us + */ + switch (mpdudensity) { + case 0: + return 0; + case 1: + case 2: + case 3: + /* Our lower layer calculations limit our precision to + 1 microsecond */ + return 1; + case 4: + return 2; + case 5: + return 4; + case 6: + return 8; + case 7: + return 16; + default: + return 0; + } +} + /* * Set current operating mode * @@ -1321,7 +1356,7 @@ void ath_deinit(struct ath_softc *sc) /* Node Management */ /*******************/ -struct ath_node *ath_node_attach(struct ath_softc *sc, u8 *addr, int if_id) +void ath_node_attach(struct ath_softc *sc, struct ieee80211_sta *sta, int if_id) { struct ath_vap *avp; struct ath_node *an; @@ -1329,90 +1364,30 @@ struct ath_node *ath_node_attach(struct ath_softc *sc, u8 *addr, int if_id) avp = sc->sc_vaps[if_id]; ASSERT(avp != NULL); - /* mac80211 sta_notify callback is from an IRQ context, so no sleep */ - an = kmalloc(sizeof(struct ath_node), GFP_ATOMIC); - if (an == NULL) - return NULL; - memset(an, 0, sizeof(*an)); - - an->an_sc = sc; - memcpy(an->an_addr, addr, ETH_ALEN); - atomic_set(&an->an_refcnt, 1); + an = (struct ath_node *)sta->drv_priv; /* set up per-node tx/rx state */ ath_tx_node_init(sc, an); ath_rx_node_init(sc, an); + an->maxampdu = 1 << (IEEE80211_HTCAP_MAXRXAMPDU_FACTOR + + sta->ht_cap.ampdu_factor); + an->mpdudensity = parse_mpdudensity(sta->ht_cap.ampdu_density); + ath_chainmask_sel_init(sc, an); ath_chainmask_sel_timerstart(&an->an_chainmask_sel); - list_add(&an->list, &sc->node_list); - - return an; } -void ath_node_detach(struct ath_softc *sc, struct ath_node *an, bool bh_flag) +void ath_node_detach(struct ath_softc *sc, struct ieee80211_sta *sta) { - unsigned long flags; + struct ath_node *an = (struct ath_node *)sta->drv_priv; ath_chainmask_sel_timerstop(&an->an_chainmask_sel); - an->an_flags |= ATH_NODE_CLEAN; - ath_tx_node_cleanup(sc, an, bh_flag); - ath_rx_node_cleanup(sc, an); + + ath_tx_node_cleanup(sc, an); ath_tx_node_free(sc, an); ath_rx_node_free(sc, an); - - spin_lock_irqsave(&sc->node_lock, flags); - - list_del(&an->list); - - spin_unlock_irqrestore(&sc->node_lock, flags); - - kfree(an); -} - -/* Finds a node and increases the refcnt if found */ - -struct ath_node *ath_node_get(struct ath_softc *sc, u8 *addr) -{ - struct ath_node *an = NULL, *an_found = NULL; - - if (list_empty(&sc->node_list)) /* FIXME */ - goto out; - list_for_each_entry(an, &sc->node_list, list) { - if (!compare_ether_addr(an->an_addr, addr)) { - atomic_inc(&an->an_refcnt); - an_found = an; - break; - } - } -out: - return an_found; -} - -/* Decrements the refcnt and if it drops to zero, detach the node */ - -void ath_node_put(struct ath_softc *sc, struct ath_node *an, bool bh_flag) -{ - if (atomic_dec_and_test(&an->an_refcnt)) - ath_node_detach(sc, an, bh_flag); -} - -/* Finds a node, doesn't increment refcnt. Caller must hold sc->node_lock */ -struct ath_node *ath_node_find(struct ath_softc *sc, u8 *addr) -{ - struct ath_node *an = NULL, *an_found = NULL; - - if (list_empty(&sc->node_list)) - return NULL; - - list_for_each_entry(an, &sc->node_list, list) - if (!compare_ether_addr(an->an_addr, addr)) { - an_found = an; - break; - } - - return an_found; } /* @@ -1437,7 +1412,6 @@ void ath_newassoc(struct ath_softc *sc, ath_rx_aggr_teardown(sc, an, tidno); } } - an->an_flags = 0; } /**************/ diff --git a/drivers/net/wireless/ath9k/core.h b/drivers/net/wireless/ath9k/core.h index fbff9aa4c28f..d7228ec66c2f 100644 --- a/drivers/net/wireless/ath9k/core.h +++ b/drivers/net/wireless/ath9k/core.h @@ -373,7 +373,6 @@ void ath_flushrecv(struct ath_softc *sc); u32 ath_calcrxfilter(struct ath_softc *sc); void ath_rx_node_init(struct ath_softc *sc, struct ath_node *an); void ath_rx_node_free(struct ath_softc *sc, struct ath_node *an); -void ath_rx_node_cleanup(struct ath_softc *sc, struct ath_node *an); void ath_handle_rx_intr(struct ath_softc *sc); int ath_rx_init(struct ath_softc *sc, int nbufs); void ath_rx_cleanup(struct ath_softc *sc); @@ -546,8 +545,7 @@ void ath_draintxq(struct ath_softc *sc, bool retry_tx); void ath_tx_draintxq(struct ath_softc *sc, struct ath_txq *txq, bool retry_tx); void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an); -void ath_tx_node_cleanup(struct ath_softc *sc, - struct ath_node *an, bool bh_flag); +void ath_tx_node_cleanup(struct ath_softc *sc, struct ath_node *an); void ath_tx_node_free(struct ath_softc *sc, struct ath_node *an); void ath_txq_schedule(struct ath_softc *sc, struct ath_txq *txq); int ath_tx_init(struct ath_softc *sc, int nbufs); @@ -568,11 +566,6 @@ void ath_tx_cabq(struct ath_softc *sc, struct sk_buff *skb); /* Node / Aggregation */ /**********************/ -/* indicates the node is clened up */ -#define ATH_NODE_CLEAN 0x1 -/* indicates the node is 80211 power save */ -#define ATH_NODE_PWRSAVE 0x2 - #define ADDBA_EXCHANGE_ATTEMPTS 10 #define ATH_AGGR_DELIM_SZ 4 /* delimiter size */ #define ATH_AGGR_MINPLEN 256 /* in bytes, minimum packet length */ @@ -584,6 +577,7 @@ void ath_tx_cabq(struct ath_softc *sc, struct sk_buff *skb); #define IEEE80211_SEQ_SEQ_SHIFT 4 #define IEEE80211_SEQ_MAX 4096 #define IEEE80211_MIN_AMPDU_BUF 0x8 +#define IEEE80211_HTCAP_MAXRXAMPDU_FACTOR 13 /* return whether a bit at index _n in bitmap _bm is set * _sz is the size of the bitmap */ @@ -638,15 +632,10 @@ struct ath_node_aggr { /* driver-specific node state */ struct ath_node { - struct list_head list; struct ath_softc *an_sc; - atomic_t an_refcnt; struct ath_chainmask_sel an_chainmask_sel; struct ath_node_aggr an_aggr; u8 an_smmode; /* SM Power save mode */ - u8 an_flags; - u8 an_addr[ETH_ALEN]; - u16 maxampdu; u8 mpdudensity; }; @@ -659,28 +648,17 @@ void ath_tx_aggr_teardown(struct ath_softc *sc, struct ath_node *an, u8 tidno); void ath_rx_aggr_teardown(struct ath_softc *sc, struct ath_node *an, u8 tidno); -int ath_rx_aggr_start(struct ath_softc *sc, - const u8 *addr, - u16 tid, - u16 *ssn); -int ath_rx_aggr_stop(struct ath_softc *sc, - const u8 *addr, - u16 tid); -int ath_tx_aggr_start(struct ath_softc *sc, - const u8 *addr, - u16 tid, - u16 *ssn); -int ath_tx_aggr_stop(struct ath_softc *sc, - const u8 *addr, - u16 tid); +int ath_rx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta, + u16 tid, u16 *ssn); +int ath_rx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid); +int ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta, + u16 tid, u16 *ssn); +int ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid); void ath_newassoc(struct ath_softc *sc, struct ath_node *node, int isnew, int isuapsd); -struct ath_node *ath_node_attach(struct ath_softc *sc, - u8 addr[ETH_ALEN], int if_id); -void ath_node_detach(struct ath_softc *sc, struct ath_node *an, bool bh_flag); -struct ath_node *ath_node_get(struct ath_softc *sc, u8 addr[ETH_ALEN]); -void ath_node_put(struct ath_softc *sc, struct ath_node *an, bool bh_flag); -struct ath_node *ath_node_find(struct ath_softc *sc, u8 *addr); +void ath_node_attach(struct ath_softc *sc, struct ieee80211_sta *sta, + int if_id); +void ath_node_detach(struct ath_softc *sc, struct ieee80211_sta *sta); /*******************/ /* Beacon Handling */ @@ -975,7 +953,6 @@ struct ath_softc { u8 sc_rxotherant; /* rx's on non-default antenna */ struct ath9k_node_stats sc_halstats; /* station-mode rssi stats */ - struct list_head node_list; struct ath_ht_info sc_ht_info; enum ath9k_ht_extprotspacing sc_ht_extprotspacing; @@ -1036,7 +1013,6 @@ struct ath_softc { spinlock_t sc_rxbuflock; spinlock_t sc_txbuflock; spinlock_t sc_resetlock; - spinlock_t node_lock; /* LEDs */ struct ath_led radio_led; diff --git a/drivers/net/wireless/ath9k/main.c b/drivers/net/wireless/ath9k/main.c index b25c8f9670d1..b1b1e7f3b0b8 100644 --- a/drivers/net/wireless/ath9k/main.c +++ b/drivers/net/wireless/ath9k/main.c @@ -21,8 +21,6 @@ #define ATH_PCI_VERSION "0.1" -#define IEEE80211_HTCAP_MAXRXAMPDU_FACTOR 13 - static char *dev_info = "ath9k"; MODULE_AUTHOR("Atheros Communications"); @@ -297,41 +295,6 @@ static void ath9k_rx_prepare(struct ath_softc *sc, rx_status->flag |= RX_FLAG_TSFT; } -static u8 parse_mpdudensity(u8 mpdudensity) -{ - /* - * 802.11n D2.0 defined values for "Minimum MPDU Start Spacing": - * 0 for no restriction - * 1 for 1/4 us - * 2 for 1/2 us - * 3 for 1 us - * 4 for 2 us - * 5 for 4 us - * 6 for 8 us - * 7 for 16 us - */ - switch (mpdudensity) { - case 0: - return 0; - case 1: - case 2: - case 3: - /* Our lower layer calculations limit our precision to - 1 microsecond */ - return 1; - case 4: - return 2; - case 5: - return 4; - case 6: - return 8; - case 7: - return 16; - default: - return 0; - } -} - static void ath9k_ht_conf(struct ath_softc *sc, struct ieee80211_bss_conf *bss_conf) { @@ -479,8 +442,6 @@ void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb, tx_info->status.rates[0].count = tx_status->retries + 1; ieee80211_tx_status(hw, skb); - if (an) - ath_node_put(sc, an, ATH9K_BH_STATUS_CHANGE); } int _ath_rx_indicate(struct ath_softc *sc, @@ -518,10 +479,6 @@ int _ath_rx_indicate(struct ath_softc *sc, rx_status.flag |= RX_FLAG_DECRYPTED; } - spin_lock_bh(&sc->node_lock); - an = ath_node_find(sc, hdr->addr2); - spin_unlock_bh(&sc->node_lock); - if (an) { ath_rx_input(sc, an, skb, status, &st); @@ -913,11 +870,6 @@ static int ath_attach(u16 devid, if (error != 0) return error; - /* Init nodes */ - - INIT_LIST_HEAD(&sc->node_list); - spin_lock_init(&sc->node_lock); - /* get mac address from hardware and set in mac80211 */ SET_IEEE80211_PERM_ADDR(hw, sc->sc_myaddr); @@ -1404,50 +1356,22 @@ static void ath9k_configure_filter(struct ieee80211_hw *hw, __func__, sc->rx_filter); } +/* Only a single interface is currently supported, + so pass 0 as the interface id to ath_node_attach */ + static void ath9k_sta_notify(struct ieee80211_hw *hw, struct ieee80211_vif *vif, enum sta_notify_cmd cmd, struct ieee80211_sta *sta) { struct ath_softc *sc = hw->priv; - struct ath_node *an; - unsigned long flags; - - spin_lock_irqsave(&sc->node_lock, flags); - an = ath_node_find(sc, sta->addr); - spin_unlock_irqrestore(&sc->node_lock, flags); switch (cmd) { case STA_NOTIFY_ADD: - spin_lock_irqsave(&sc->node_lock, flags); - if (!an) { - ath_node_attach(sc, sta->addr, 0); - DPRINTF(sc, ATH_DBG_CONFIG, "%s: Attach a node: %pM\n", - __func__, sta->addr); - } else { - ath_node_get(sc, sta->addr); - } - - /* XXX: Is this right? Can the capabilities change? */ - an = ath_node_find(sc, sta->addr); - an->maxampdu = 1 << (IEEE80211_HTCAP_MAXRXAMPDU_FACTOR + - sta->ht_cap.ampdu_factor); - an->mpdudensity = - parse_mpdudensity(sta->ht_cap.ampdu_density); - - spin_unlock_irqrestore(&sc->node_lock, flags); + ath_node_attach(sc, sta, 0); break; case STA_NOTIFY_REMOVE: - if (!an) - DPRINTF(sc, ATH_DBG_FATAL, - "%s: Removal of a non-existent node\n", - __func__); - else { - ath_node_put(sc, an, ATH9K_BH_STATUS_INTACT); - DPRINTF(sc, ATH_DBG_CONFIG, "%s: Put a node: %pM\n", - __func__, - sta->addr); - } + ath_node_detach(sc, sta); break; default: break; @@ -1595,21 +1519,21 @@ static int ath9k_ampdu_action(struct ieee80211_hw *hw, switch (action) { case IEEE80211_AMPDU_RX_START: - ret = ath_rx_aggr_start(sc, sta->addr, tid, ssn); + ret = ath_rx_aggr_start(sc, sta, tid, ssn); if (ret < 0) DPRINTF(sc, ATH_DBG_FATAL, "%s: Unable to start RX aggregation\n", __func__); break; case IEEE80211_AMPDU_RX_STOP: - ret = ath_rx_aggr_stop(sc, sta->addr, tid); + ret = ath_rx_aggr_stop(sc, sta, tid); if (ret < 0) DPRINTF(sc, ATH_DBG_FATAL, "%s: Unable to stop RX aggregation\n", __func__); break; case IEEE80211_AMPDU_TX_START: - ret = ath_tx_aggr_start(sc, sta->addr, tid, ssn); + ret = ath_tx_aggr_start(sc, sta, tid, ssn); if (ret < 0) DPRINTF(sc, ATH_DBG_FATAL, "%s: Unable to start TX aggregation\n", @@ -1618,7 +1542,7 @@ static int ath9k_ampdu_action(struct ieee80211_hw *hw, ieee80211_start_tx_ba_cb_irqsafe(hw, sta->addr, tid); break; case IEEE80211_AMPDU_TX_STOP: - ret = ath_tx_aggr_stop(sc, sta->addr, tid); + ret = ath_tx_aggr_stop(sc, sta, tid); if (ret < 0) DPRINTF(sc, ATH_DBG_FATAL, "%s: Unable to stop TX aggregation\n", diff --git a/drivers/net/wireless/ath9k/rc.c b/drivers/net/wireless/ath9k/rc.c index ecffd6f45fd0..1305873b2a09 100644 --- a/drivers/net/wireless/ath9k/rc.c +++ b/drivers/net/wireless/ath9k/rc.c @@ -1867,9 +1867,7 @@ static void ath_tx_status(void *priv, struct ieee80211_supported_band *sband, /* XXX: UGLY HACK!! */ tx_info_priv = (struct ath_tx_info_priv *)tx_info->control.vif; - spin_lock_bh(&sc->node_lock); - an = ath_node_find(sc, hdr->addr1); - spin_unlock_bh(&sc->node_lock); + an = (struct ath_node *)sta->drv_priv; if (tx_info_priv == NULL) return; @@ -1984,16 +1982,7 @@ static void ath_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta, qc = ieee80211_get_qos_ctl(hdr); tid = qc[0] & 0xf; - spin_lock_bh(&sc->node_lock); - an = ath_node_find(sc, hdr->addr1); - spin_unlock_bh(&sc->node_lock); - - if (!an) { - DPRINTF(sc, ATH_DBG_AGGR, - "%s: Node not found to " - "init/chk TX aggr\n", __func__); - return; - } + an = (struct ath_node *)sta->drv_priv; chk = ath_tx_aggr_check(sc, an, tid); if (chk == AGGR_REQUIRED) { diff --git a/drivers/net/wireless/ath9k/recv.c b/drivers/net/wireless/ath9k/recv.c index 828322840a86..6b4006ed4e01 100644 --- a/drivers/net/wireless/ath9k/recv.c +++ b/drivers/net/wireless/ath9k/recv.c @@ -1095,7 +1095,7 @@ rx_next: /* Process ADDBA request in per-TID data structure */ int ath_rx_aggr_start(struct ath_softc *sc, - const u8 *addr, + struct ieee80211_sta *sta, u16 tid, u16 *ssn) { @@ -1105,17 +1105,7 @@ int ath_rx_aggr_start(struct ath_softc *sc, struct ieee80211_supported_band *sband; u16 buffersize = 0; - spin_lock_bh(&sc->node_lock); - an = ath_node_find(sc, (u8 *) addr); - spin_unlock_bh(&sc->node_lock); - - if (!an) { - DPRINTF(sc, ATH_DBG_AGGR, - "%s: Node not found to initialize RX aggregation\n", - __func__); - return -1; - } - + an = (struct ath_node *)sta->drv_priv; sband = hw->wiphy->bands[hw->conf.channel->band]; buffersize = IEEE80211_MIN_AMPDU_BUF << sband->ht_cap.ampdu_factor; /* FIXME */ @@ -1172,21 +1162,9 @@ int ath_rx_aggr_start(struct ath_softc *sc, /* Process DELBA */ -int ath_rx_aggr_stop(struct ath_softc *sc, - const u8 *addr, - u16 tid) +int ath_rx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid) { - struct ath_node *an; - - spin_lock_bh(&sc->node_lock); - an = ath_node_find(sc, (u8 *) addr); - spin_unlock_bh(&sc->node_lock); - - if (!an) { - DPRINTF(sc, ATH_DBG_AGGR, - "%s: RX aggr stop for non-existent node\n", __func__); - return -1; - } + struct ath_node *an = (struct ath_node *)sta->drv_priv; ath_rx_aggr_teardown(sc, an, tid); return 0; @@ -1194,8 +1172,7 @@ int ath_rx_aggr_stop(struct ath_softc *sc, /* Rx aggregation tear down */ -void ath_rx_aggr_teardown(struct ath_softc *sc, - struct ath_node *an, u8 tid) +void ath_rx_aggr_teardown(struct ath_softc *sc, struct ath_node *an, u8 tid) { struct ath_arx_tid *rxtid = &an->an_aggr.rx.tid[tid]; @@ -1253,7 +1230,7 @@ void ath_rx_node_init(struct ath_softc *sc, struct ath_node *an) } } -void ath_rx_node_cleanup(struct ath_softc *sc, struct ath_node *an) +void ath_rx_node_free(struct ath_softc *sc, struct ath_node *an) { if (sc->sc_flags & SC_OP_RXAGGR) { struct ath_arx_tid *rxtid; @@ -1281,10 +1258,3 @@ void ath_rx_node_cleanup(struct ath_softc *sc, struct ath_node *an) } } - -/* Cleanup per-node receive state */ - -void ath_rx_node_free(struct ath_softc *sc, struct ath_node *an) -{ - ath_rx_node_cleanup(sc, an); -} diff --git a/drivers/net/wireless/ath9k/xmit.c b/drivers/net/wireless/ath9k/xmit.c index 7cfab5a542f0..64557133b227 100644 --- a/drivers/net/wireless/ath9k/xmit.c +++ b/drivers/net/wireless/ath9k/xmit.c @@ -214,15 +214,6 @@ static int ath_tx_prepare(struct ath_softc *sc, rt = sc->sc_currates; BUG_ON(!rt); - /* Fill misc fields */ - - spin_lock_bh(&sc->node_lock); - txctl->an = ath_node_get(sc, hdr->addr1); - /* create a temp node, if the node is not there already */ - if (!txctl->an) - txctl->an = ath_node_attach(sc, hdr->addr1, 0); - spin_unlock_bh(&sc->node_lock); - if (ieee80211_is_data_qos(fc)) { qc = ieee80211_get_qos_ctl(hdr); txctl->tidno = qc[0] & 0xf; @@ -496,11 +487,9 @@ unlock: /* Compute the number of bad frames */ -static int ath_tx_num_badfrms(struct ath_softc *sc, - struct ath_buf *bf, int txok) +static int ath_tx_num_badfrms(struct ath_softc *sc, struct ath_buf *bf, + int txok) { - struct ath_node *an = bf->bf_node; - int isnodegone = (an->an_flags & ATH_NODE_CLEAN); struct ath_buf *bf_last = bf->bf_lastbf; struct ath_desc *ds = bf_last->bf_desc; u16 seq_st = 0; @@ -509,7 +498,7 @@ static int ath_tx_num_badfrms(struct ath_softc *sc, int nbad = 0; int isaggr = 0; - if (isnodegone || ds->ds_txstat.ts_flags == ATH9K_TX_SW_ABORTED) + if (ds->ds_txstat.ts_flags == ATH9K_TX_SW_ABORTED) return 0; isaggr = bf_isaggr(bf); @@ -908,7 +897,6 @@ static void ath_tx_complete_aggr_rifs(struct ath_softc *sc, u16 seq_st = 0; u32 ba[WME_BA_BMP_SIZE >> 5]; int isaggr, txfail, txpending, sendbar = 0, needreset = 0; - int isnodegone = (an->an_flags & ATH_NODE_CLEAN); isaggr = bf_isaggr(bf); if (isaggr) { @@ -954,7 +942,7 @@ static void ath_tx_complete_aggr_rifs(struct ath_softc *sc, /* transmit completion */ } else { - if (!tid->cleanup_inprogress && !isnodegone && + if (!tid->cleanup_inprogress && ds->ds_txstat.ts_flags != ATH9K_TX_SW_ABORTED) { if (bf->bf_retries < ATH_MAX_SW_RETRIES) { ath_tx_set_retry(sc, bf); @@ -1083,15 +1071,6 @@ static void ath_tx_complete_aggr_rifs(struct ath_softc *sc, bf = bf_next; } - /* - * node is already gone. no more assocication - * with the node. the node might have been freed - * any node acces can result in panic.note tid - * is part of the node. - */ - if (isnodegone) - return; - if (tid->cleanup_inprogress) { /* check to see if we're done with cleaning the h/w queue */ spin_lock_bh(&txq->axq_lock); @@ -1795,8 +1774,8 @@ static void ath_tx_sched_aggr(struct ath_softc *sc, static void ath_tid_drain(struct ath_softc *sc, struct ath_txq *txq, - struct ath_atx_tid *tid, - bool bh_flag) + struct ath_atx_tid *tid) + { struct ath_buf *bf; struct list_head bf_head; @@ -1817,18 +1796,12 @@ static void ath_tid_drain(struct ath_softc *sc, * do not indicate packets while holding txq spinlock. * unlock is intentional here */ - if (likely(bh_flag)) - spin_unlock_bh(&txq->axq_lock); - else - spin_unlock(&txq->axq_lock); + spin_unlock(&txq->axq_lock); /* complete this sub-frame */ ath_tx_complete_buf(sc, bf, &bf_head, 0, 0); - if (likely(bh_flag)) - spin_lock_bh(&txq->axq_lock); - else - spin_lock(&txq->axq_lock); + spin_lock(&txq->axq_lock); } /* @@ -1847,8 +1820,7 @@ static void ath_tid_drain(struct ath_softc *sc, */ static void ath_txq_drain_pending_buffers(struct ath_softc *sc, - struct ath_txq *txq, - bool bh_flag) + struct ath_txq *txq) { struct ath_atx_ac *ac, *ac_tmp; struct ath_atx_tid *tid, *tid_tmp; @@ -1859,7 +1831,7 @@ static void ath_txq_drain_pending_buffers(struct ath_softc *sc, list_for_each_entry_safe(tid, tid_tmp, &ac->tid_q, list) { list_del(&tid->list); tid->sched = false; - ath_tid_drain(sc, txq, tid, bh_flag); + ath_tid_drain(sc, txq, tid); } } } @@ -2294,8 +2266,6 @@ int ath_tx_start(struct ath_softc *sc, struct sk_buff *skb) * or asynchrounsly once DMA is complete. */ xmit_map_sg(sc, skb, &txctl); - else - ath_node_put(sc, txctl.an, ATH9K_BH_STATUS_CHANGE); /* failed packets will be dropped by the caller */ return error; @@ -2374,8 +2344,7 @@ void ath_tx_draintxq(struct ath_softc *sc, if (sc->sc_flags & SC_OP_TXAGGR) { if (!retry_tx) { spin_lock_bh(&txq->axq_lock); - ath_txq_drain_pending_buffers(sc, txq, - ATH9K_BH_STATUS_CHANGE); + ath_txq_drain_pending_buffers(sc, txq); spin_unlock_bh(&txq->axq_lock); } } @@ -2441,24 +2410,13 @@ enum ATH_AGGR_CHECK ath_tx_aggr_check(struct ath_softc *sc, /* Start TX aggregation */ -int ath_tx_aggr_start(struct ath_softc *sc, - const u8 *addr, - u16 tid, - u16 *ssn) +int ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta, + u16 tid, u16 *ssn) { struct ath_atx_tid *txtid; struct ath_node *an; - spin_lock_bh(&sc->node_lock); - an = ath_node_find(sc, (u8 *) addr); - spin_unlock_bh(&sc->node_lock); - - if (!an) { - DPRINTF(sc, ATH_DBG_AGGR, - "%s: Node not found to initialize " - "TX aggregation\n", __func__); - return -1; - } + an = (struct ath_node *)sta->drv_priv; if (sc->sc_flags & SC_OP_TXAGGR) { txtid = ATH_AN_2_TID(an, tid); @@ -2471,21 +2429,9 @@ int ath_tx_aggr_start(struct ath_softc *sc, /* Stop tx aggregation */ -int ath_tx_aggr_stop(struct ath_softc *sc, - const u8 *addr, - u16 tid) +int ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid) { - struct ath_node *an; - - spin_lock_bh(&sc->node_lock); - an = ath_node_find(sc, (u8 *) addr); - spin_unlock_bh(&sc->node_lock); - - if (!an) { - DPRINTF(sc, ATH_DBG_AGGR, - "%s: TX aggr stop for non-existent node\n", __func__); - return -1; - } + struct ath_node *an = (struct ath_node *)sta->drv_priv; ath_tx_aggr_teardown(sc, an, tid); return 0; @@ -2498,8 +2444,7 @@ int ath_tx_aggr_stop(struct ath_softc *sc, * - Discard all retry frames from the s/w queue. */ -void ath_tx_aggr_teardown(struct ath_softc *sc, - struct ath_node *an, u8 tid) +void ath_tx_aggr_teardown(struct ath_softc *sc, struct ath_node *an, u8 tid) { struct ath_atx_tid *txtid = ATH_AN_2_TID(an, tid); struct ath_txq *txq = &sc->sc_txq[txtid->ac->qnum]; @@ -2625,8 +2570,6 @@ void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an) struct ath_atx_ac *ac; int tidno, acno; - an->maxampdu = ATH_AMPDU_LIMIT_DEFAULT; - /* * Init per tid tx state */ @@ -2684,8 +2627,7 @@ void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an) /* Cleanupthe pending buffers for the node. */ -void ath_tx_node_cleanup(struct ath_softc *sc, - struct ath_node *an, bool bh_flag) +void ath_tx_node_cleanup(struct ath_softc *sc, struct ath_node *an) { int i; struct ath_atx_ac *ac, *ac_tmp; @@ -2695,10 +2637,7 @@ void ath_tx_node_cleanup(struct ath_softc *sc, if (ATH_TXQ_SETUP(sc, i)) { txq = &sc->sc_txq[i]; - if (likely(bh_flag)) - spin_lock_bh(&txq->axq_lock); - else - spin_lock(&txq->axq_lock); + spin_lock(&txq->axq_lock); list_for_each_entry_safe(ac, ac_tmp, &txq->axq_acq, list) { @@ -2713,17 +2652,14 @@ void ath_tx_node_cleanup(struct ath_softc *sc, tid_tmp, &ac->tid_q, list) { list_del(&tid->list); tid->sched = false; - ath_tid_drain(sc, txq, tid, bh_flag); + ath_tid_drain(sc, txq, tid); tid->addba_exchangecomplete = 0; tid->addba_exchangeattempts = 0; tid->cleanup_inprogress = false; } } - if (likely(bh_flag)) - spin_unlock_bh(&txq->axq_lock); - else - spin_unlock(&txq->axq_lock); + spin_unlock(&txq->axq_lock); } } } @@ -2794,7 +2730,6 @@ void ath_tx_cabq(struct ath_softc *sc, struct sk_buff *skb) */ xmit_map_sg(sc, skb, &txctl); } else { - ath_node_put(sc, txctl.an, ATH9K_BH_STATUS_CHANGE); DPRINTF(sc, ATH_DBG_XMIT, "%s: TX CABQ failed\n", __func__); dev_kfree_skb_any(skb); } -- cgit v1.2.3 From c51701632c8becdf0ffedb96d9cedc1149f2183a Mon Sep 17 00:00:00 2001 From: Sujith Date: Wed, 29 Oct 2008 10:13:59 +0530 Subject: ath9k: Simplify node attach/detach routines Signed-off-by: Sujith Signed-off-by: John W. Linville --- drivers/net/wireless/ath9k/core.c | 15 ++--- drivers/net/wireless/ath9k/core.h | 2 +- drivers/net/wireless/ath9k/recv.c | 81 ++++++++++++------------ drivers/net/wireless/ath9k/xmit.c | 125 ++++++++++++++++---------------------- 4 files changed, 99 insertions(+), 124 deletions(-) (limited to 'drivers/net/wireless/ath9k/recv.c') diff --git a/drivers/net/wireless/ath9k/core.c b/drivers/net/wireless/ath9k/core.c index 49fc264cfe5a..689a28037096 100644 --- a/drivers/net/wireless/ath9k/core.c +++ b/drivers/net/wireless/ath9k/core.c @@ -1366,9 +1366,10 @@ void ath_node_attach(struct ath_softc *sc, struct ieee80211_sta *sta, int if_id) an = (struct ath_node *)sta->drv_priv; - /* set up per-node tx/rx state */ - ath_tx_node_init(sc, an); - ath_rx_node_init(sc, an); + if (sc->sc_flags & SC_OP_TXAGGR) + ath_tx_node_init(sc, an); + if (sc->sc_flags & SC_OP_RXAGGR) + ath_rx_node_init(sc, an); an->maxampdu = 1 << (IEEE80211_HTCAP_MAXRXAMPDU_FACTOR + sta->ht_cap.ampdu_factor); @@ -1384,10 +1385,10 @@ void ath_node_detach(struct ath_softc *sc, struct ieee80211_sta *sta) ath_chainmask_sel_timerstop(&an->an_chainmask_sel); - ath_tx_node_cleanup(sc, an); - - ath_tx_node_free(sc, an); - ath_rx_node_free(sc, an); + if (sc->sc_flags & SC_OP_TXAGGR) + ath_tx_node_cleanup(sc, an); + if (sc->sc_flags & SC_OP_RXAGGR) + ath_rx_node_cleanup(sc, an); } /* diff --git a/drivers/net/wireless/ath9k/core.h b/drivers/net/wireless/ath9k/core.h index d7228ec66c2f..d8aafff221c8 100644 --- a/drivers/net/wireless/ath9k/core.h +++ b/drivers/net/wireless/ath9k/core.h @@ -372,7 +372,7 @@ bool ath_stoprecv(struct ath_softc *sc); void ath_flushrecv(struct ath_softc *sc); u32 ath_calcrxfilter(struct ath_softc *sc); void ath_rx_node_init(struct ath_softc *sc, struct ath_node *an); -void ath_rx_node_free(struct ath_softc *sc, struct ath_node *an); +void ath_rx_node_cleanup(struct ath_softc *sc, struct ath_node *an); void ath_handle_rx_intr(struct ath_softc *sc); int ath_rx_init(struct ath_softc *sc, int nbufs); void ath_rx_cleanup(struct ath_softc *sc); diff --git a/drivers/net/wireless/ath9k/recv.c b/drivers/net/wireless/ath9k/recv.c index 6b4006ed4e01..27d6a981a106 100644 --- a/drivers/net/wireless/ath9k/recv.c +++ b/drivers/net/wireless/ath9k/recv.c @@ -1200,61 +1200,56 @@ void ath_rx_aggr_teardown(struct ath_softc *sc, struct ath_node *an, u8 tid) void ath_rx_node_init(struct ath_softc *sc, struct ath_node *an) { - if (sc->sc_flags & SC_OP_RXAGGR) { - struct ath_arx_tid *rxtid; - int tidno; - - /* Init per tid rx state */ - for (tidno = 0, rxtid = &an->an_aggr.rx.tid[tidno]; - tidno < WME_NUM_TID; - tidno++, rxtid++) { - rxtid->an = an; - rxtid->seq_reset = 1; - rxtid->seq_next = 0; - rxtid->baw_size = WME_MAX_BA; - rxtid->baw_head = rxtid->baw_tail = 0; + struct ath_arx_tid *rxtid; + int tidno; + + /* Init per tid rx state */ + for (tidno = 0, rxtid = &an->an_aggr.rx.tid[tidno]; + tidno < WME_NUM_TID; + tidno++, rxtid++) { + rxtid->an = an; + rxtid->seq_reset = 1; + rxtid->seq_next = 0; + rxtid->baw_size = WME_MAX_BA; + rxtid->baw_head = rxtid->baw_tail = 0; - /* - * Ensure the buffer pointer is null at this point - * (needs to be allocated when addba is received) - */ + /* + * Ensure the buffer pointer is null at this point + * (needs to be allocated when addba is received) + */ - rxtid->rxbuf = NULL; - setup_timer(&rxtid->timer, ath_rx_timer, - (unsigned long)rxtid); - spin_lock_init(&rxtid->tidlock); + rxtid->rxbuf = NULL; + setup_timer(&rxtid->timer, ath_rx_timer, + (unsigned long)rxtid); + spin_lock_init(&rxtid->tidlock); - /* ADDBA state */ - rxtid->addba_exchangecomplete = 0; - } + /* ADDBA state */ + rxtid->addba_exchangecomplete = 0; } } -void ath_rx_node_free(struct ath_softc *sc, struct ath_node *an) +void ath_rx_node_cleanup(struct ath_softc *sc, struct ath_node *an) { - if (sc->sc_flags & SC_OP_RXAGGR) { - struct ath_arx_tid *rxtid; - int tidno, i; + struct ath_arx_tid *rxtid; + int tidno, i; - /* Init per tid rx state */ - for (tidno = 0, rxtid = &an->an_aggr.rx.tid[tidno]; - tidno < WME_NUM_TID; - tidno++, rxtid++) { + /* Init per tid rx state */ + for (tidno = 0, rxtid = &an->an_aggr.rx.tid[tidno]; + tidno < WME_NUM_TID; + tidno++, rxtid++) { - if (!rxtid->addba_exchangecomplete) - continue; + if (!rxtid->addba_exchangecomplete) + continue; - /* must cancel timer first */ - del_timer_sync(&rxtid->timer); + /* must cancel timer first */ + del_timer_sync(&rxtid->timer); - /* drop any pending sub-frames */ - ath_rx_flush_tid(sc, rxtid, 1); + /* drop any pending sub-frames */ + ath_rx_flush_tid(sc, rxtid, 1); - for (i = 0; i < ATH_TID_MAX_BUFS; i++) - ASSERT(rxtid->rxbuf[i].rx_wbuf == NULL); + for (i = 0; i < ATH_TID_MAX_BUFS; i++) + ASSERT(rxtid->rxbuf[i].rx_wbuf == NULL); - rxtid->addba_exchangecomplete = 0; - } + rxtid->addba_exchangecomplete = 0; } - } diff --git a/drivers/net/wireless/ath9k/xmit.c b/drivers/net/wireless/ath9k/xmit.c index 64557133b227..bd78244f1d18 100644 --- a/drivers/net/wireless/ath9k/xmit.c +++ b/drivers/net/wireless/ath9k/xmit.c @@ -2565,62 +2565,60 @@ void ath_txq_schedule(struct ath_softc *sc, struct ath_txq *txq) void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an) { - if (sc->sc_flags & SC_OP_TXAGGR) { - struct ath_atx_tid *tid; - struct ath_atx_ac *ac; - int tidno, acno; - - /* - * Init per tid tx state - */ - for (tidno = 0, tid = &an->an_aggr.tx.tid[tidno]; - tidno < WME_NUM_TID; - tidno++, tid++) { - tid->an = an; - tid->tidno = tidno; - tid->seq_start = tid->seq_next = 0; - tid->baw_size = WME_MAX_BA; - tid->baw_head = tid->baw_tail = 0; - tid->sched = false; - tid->paused = false; - tid->cleanup_inprogress = false; - INIT_LIST_HEAD(&tid->buf_q); - - acno = TID_TO_WME_AC(tidno); - tid->ac = &an->an_aggr.tx.ac[acno]; + struct ath_atx_tid *tid; + struct ath_atx_ac *ac; + int tidno, acno; - /* ADDBA state */ - tid->addba_exchangecomplete = 0; - tid->addba_exchangeinprogress = 0; - tid->addba_exchangeattempts = 0; - } + /* + * Init per tid tx state + */ + for (tidno = 0, tid = &an->an_aggr.tx.tid[tidno]; + tidno < WME_NUM_TID; + tidno++, tid++) { + tid->an = an; + tid->tidno = tidno; + tid->seq_start = tid->seq_next = 0; + tid->baw_size = WME_MAX_BA; + tid->baw_head = tid->baw_tail = 0; + tid->sched = false; + tid->paused = false; + tid->cleanup_inprogress = false; + INIT_LIST_HEAD(&tid->buf_q); + + acno = TID_TO_WME_AC(tidno); + tid->ac = &an->an_aggr.tx.ac[acno]; + + /* ADDBA state */ + tid->addba_exchangecomplete = 0; + tid->addba_exchangeinprogress = 0; + tid->addba_exchangeattempts = 0; + } - /* - * Init per ac tx state - */ - for (acno = 0, ac = &an->an_aggr.tx.ac[acno]; - acno < WME_NUM_AC; acno++, ac++) { - ac->sched = false; - INIT_LIST_HEAD(&ac->tid_q); - - switch (acno) { - case WME_AC_BE: - ac->qnum = ath_tx_get_qnum(sc, - ATH9K_TX_QUEUE_DATA, ATH9K_WME_AC_BE); - break; - case WME_AC_BK: - ac->qnum = ath_tx_get_qnum(sc, - ATH9K_TX_QUEUE_DATA, ATH9K_WME_AC_BK); - break; - case WME_AC_VI: - ac->qnum = ath_tx_get_qnum(sc, - ATH9K_TX_QUEUE_DATA, ATH9K_WME_AC_VI); - break; - case WME_AC_VO: - ac->qnum = ath_tx_get_qnum(sc, - ATH9K_TX_QUEUE_DATA, ATH9K_WME_AC_VO); - break; - } + /* + * Init per ac tx state + */ + for (acno = 0, ac = &an->an_aggr.tx.ac[acno]; + acno < WME_NUM_AC; acno++, ac++) { + ac->sched = false; + INIT_LIST_HEAD(&ac->tid_q); + + switch (acno) { + case WME_AC_BE: + ac->qnum = ath_tx_get_qnum(sc, + ATH9K_TX_QUEUE_DATA, ATH9K_WME_AC_BE); + break; + case WME_AC_BK: + ac->qnum = ath_tx_get_qnum(sc, + ATH9K_TX_QUEUE_DATA, ATH9K_WME_AC_BK); + break; + case WME_AC_VI: + ac->qnum = ath_tx_get_qnum(sc, + ATH9K_TX_QUEUE_DATA, ATH9K_WME_AC_VI); + break; + case WME_AC_VO: + ac->qnum = ath_tx_get_qnum(sc, + ATH9K_TX_QUEUE_DATA, ATH9K_WME_AC_VO); + break; } } } @@ -2664,25 +2662,6 @@ void ath_tx_node_cleanup(struct ath_softc *sc, struct ath_node *an) } } -/* Cleanup per node transmit state */ - -void ath_tx_node_free(struct ath_softc *sc, struct ath_node *an) -{ - if (sc->sc_flags & SC_OP_TXAGGR) { - struct ath_atx_tid *tid; - int tidno, i; - - /* Init per tid rx state */ - for (tidno = 0, tid = &an->an_aggr.tx.tid[tidno]; - tidno < WME_NUM_TID; - tidno++, tid++) { - - for (i = 0; i < ATH_TID_MAX_BUFS; i++) - ASSERT(tid->tx_buf[i] == NULL); - } - } -} - void ath_tx_cabq(struct ath_softc *sc, struct sk_buff *skb) { int hdrlen, padsize; -- cgit v1.2.3 From 102e0572d330e6cdb89a8f8fbd3999e3c67a1f9e Mon Sep 17 00:00:00 2001 From: Sujith Date: Wed, 29 Oct 2008 10:15:16 +0530 Subject: ath9k: Ensure ath_node is not NULL when updating tx chainmask Also, random indentation and whitespace cleanup. Signed-off-by: Sujith Signed-off-by: John W. Linville --- drivers/net/wireless/ath9k/main.c | 3 +-- drivers/net/wireless/ath9k/rc.c | 2 +- drivers/net/wireless/ath9k/recv.c | 6 ++--- drivers/net/wireless/ath9k/xmit.c | 57 ++++++++++++++++----------------------- 4 files changed, 28 insertions(+), 40 deletions(-) (limited to 'drivers/net/wireless/ath9k/recv.c') diff --git a/drivers/net/wireless/ath9k/main.c b/drivers/net/wireless/ath9k/main.c index 839db2312ca5..0a0eb7ce0f5f 100644 --- a/drivers/net/wireless/ath9k/main.c +++ b/drivers/net/wireless/ath9k/main.c @@ -489,8 +489,7 @@ int _ath_rx_indicate(struct ath_softc *sc, return 0; } -int ath_rx_subframe(struct ath_node *an, - struct sk_buff *skb, +int ath_rx_subframe(struct ath_node *an, struct sk_buff *skb, struct ath_recv_status *status) { struct ath_softc *sc = an->an_sc; diff --git a/drivers/net/wireless/ath9k/rc.c b/drivers/net/wireless/ath9k/rc.c index 1305873b2a09..02931a111f1a 100644 --- a/drivers/net/wireless/ath9k/rc.c +++ b/drivers/net/wireless/ath9k/rc.c @@ -816,7 +816,7 @@ void ath_rate_detach(struct ath_rate_softc *asc) } u8 ath_rate_findrateix(struct ath_softc *sc, - u8 dot11rate) + u8 dot11rate) { const struct ath_rate_table *ratetable; struct ath_rate_softc *rsc = sc->sc_rc; diff --git a/drivers/net/wireless/ath9k/recv.c b/drivers/net/wireless/ath9k/recv.c index 27d6a981a106..80f26b4c4e06 100644 --- a/drivers/net/wireless/ath9k/recv.c +++ b/drivers/net/wireless/ath9k/recv.c @@ -356,8 +356,8 @@ static void ath_rx_timer(unsigned long data) /* Free all pending sub-frames in the re-ordering buffer */ -static void ath_rx_flush_tid(struct ath_softc *sc, - struct ath_arx_tid *rxtid, int drop) +static void ath_rx_flush_tid(struct ath_softc *sc, struct ath_arx_tid *rxtid, + int drop) { struct ath_rxbuf *rxbuf; unsigned long flag; @@ -1218,7 +1218,7 @@ void ath_rx_node_init(struct ath_softc *sc, struct ath_node *an) * (needs to be allocated when addba is received) */ - rxtid->rxbuf = NULL; + rxtid->rxbuf = NULL; setup_timer(&rxtid->timer, ath_rx_timer, (unsigned long)rxtid); spin_lock_init(&rxtid->tidlock); diff --git a/drivers/net/wireless/ath9k/xmit.c b/drivers/net/wireless/ath9k/xmit.c index 4e7108a179fb..bd902468868f 100644 --- a/drivers/net/wireless/ath9k/xmit.c +++ b/drivers/net/wireless/ath9k/xmit.c @@ -65,11 +65,12 @@ static u32 bits_per_symbol[][2] = { * NB: must be called with txq lock held */ -static void ath_tx_txqaddbuf(struct ath_softc *sc, - struct ath_txq *txq, struct list_head *head) +static void ath_tx_txqaddbuf(struct ath_softc *sc, struct ath_txq *txq, + struct list_head *head) { struct ath_hal *ah = sc->sc_ah; struct ath_buf *bf; + /* * Insert the frame on the outbound list and * pass it on to the hardware. @@ -360,6 +361,7 @@ static void ath_tx_complete_buf(struct ath_softc *sc, if (bf_isxretried(bf)) tx_status.flags |= ATH_TX_XRETRY; } + /* Unmap this frame */ pci_unmap_single(sc->pdev, bf->bf_dmacontext, @@ -497,8 +499,8 @@ static void ath_tx_set_retry(struct ath_softc *sc, struct ath_buf *bf) /* Update block ack window */ -static void ath_tx_update_baw(struct ath_softc *sc, - struct ath_atx_tid *tid, int seqno) +static void ath_tx_update_baw(struct ath_softc *sc, struct ath_atx_tid *tid, + int seqno) { int index, cindex; @@ -522,12 +524,8 @@ static void ath_tx_update_baw(struct ath_softc *sc, * half_gi - to use 4us v/s 3.6 us for symbol time */ -static u32 ath_pkt_duration(struct ath_softc *sc, - u8 rix, - struct ath_buf *bf, - int width, - int half_gi, - bool shortPreamble) +static u32 ath_pkt_duration(struct ath_softc *sc, u8 rix, struct ath_buf *bf, + int width, int half_gi, bool shortPreamble) { const struct ath9k_rate_table *rt = sc->sc_currates; u32 nbits, nsymbits, duration, nsymbols; @@ -541,11 +539,8 @@ static u32 ath_pkt_duration(struct ath_softc *sc, * for legacy rates, use old function to compute packet duration */ if (!IS_HT_RATE(rc)) - return ath9k_hw_computetxtime(sc->sc_ah, - rt, - pktlen, - rix, - shortPreamble); + return ath9k_hw_computetxtime(sc->sc_ah, rt, pktlen, rix, + shortPreamble); /* * find number of symbols: PLCP + data */ @@ -563,6 +558,7 @@ static u32 ath_pkt_duration(struct ath_softc *sc, */ streams = HT_RC_2_STREAMS(rc); duration += L_STF + L_LTF + L_SIG + HT_SIG + HT_STF + HT_LTF(streams); + return duration; } @@ -578,7 +574,6 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf) int i, flags, rtsctsena = 0; u32 ctsduration = 0; u8 rix = 0, cix, ctsrate = 0; - u32 aggr_limit_with_rts = ah->ah_caps.rts_aggr_limit; struct ath_node *an = NULL; struct sk_buff *skb; struct ieee80211_tx_info *tx_info; @@ -646,7 +641,7 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf) /* * For AR5416 - RTS cannot be followed by a frame larger than 8K. */ - if (bf_isaggr(bf) && (bf->bf_al > aggr_limit_with_rts)) { + if (bf_isaggr(bf) && (bf->bf_al > ah->ah_caps.rts_aggr_limit)) { /* * Ensure that in the case of SM Dynamic power save * while we are bursting the second aggregate the @@ -659,8 +654,8 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf) * CTS transmit rate is derived from the transmit rate * by looking in the h/w rate table. We must also factor * in whether or not a short preamble is to be used. + * NB: cix is set above where RTS/CTS is enabled */ - /* NB: cix is set above where RTS/CTS is enabled */ BUG_ON(cix == 0xff); ctsrate = rt->info[cix].rateCode | (bf_isshpreamble(bf) ? rt->info[cix].shortPreamble : 0); @@ -689,15 +684,13 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf) ((bf->bf_rcs[i].flags & ATH_RC_SGI_FLAG) ? ATH9K_RATESERIES_HALFGI : 0); - series[i].PktDuration = ath_pkt_duration( - sc, rix, bf, - (bf->bf_rcs[i].flags & ATH_RC_CW40_FLAG) != 0, - (bf->bf_rcs[i].flags & ATH_RC_SGI_FLAG), - bf_isshpreamble(bf)); + series[i].PktDuration = ath_pkt_duration(sc, rix, bf, + (bf->bf_rcs[i].flags & ATH_RC_CW40_FLAG) != 0, + (bf->bf_rcs[i].flags & ATH_RC_SGI_FLAG), + bf_isshpreamble(bf)); - if (bf_isht(bf)) - series[i].ChSel = - ath_chainmask_sel_logic(sc, an); + if (bf_isht(bf) && an) + series[i].ChSel = ath_chainmask_sel_logic(sc, an); else series[i].ChSel = sc->sc_tx_chainmask; @@ -748,6 +741,7 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf) ctsrate, ctsduration, series, 4, flags); + if (sc->sc_config.ath_aggr_prot && flags) ath9k_hw_set11n_burstduration(ah, ds, 8192); } @@ -1238,26 +1232,21 @@ static void ath_tx_stopdma(struct ath_softc *sc, struct ath_txq *txq) static void ath_drain_txdataq(struct ath_softc *sc, bool retry_tx) { struct ath_hal *ah = sc->sc_ah; - int i; - int npend = 0; + int i, status, npend = 0; - /* XXX return value */ if (!(sc->sc_flags & SC_OP_INVALID)) { for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) { if (ATH_TXQ_SETUP(sc, i)) { ath_tx_stopdma(sc, &sc->sc_txq[i]); - /* The TxDMA may not really be stopped. * Double check the hal tx pending count */ npend += ath9k_hw_numtxpending(ah, - sc->sc_txq[i].axq_qnum); + sc->sc_txq[i].axq_qnum); } } } if (npend) { - int status; - /* TxDMA not stopped, reset the hal */ DPRINTF(sc, ATH_DBG_XMIT, "%s: Unable to stop TxDMA. Reset HAL!\n", __func__); @@ -1360,6 +1349,7 @@ static int ath_tx_send_ampdu(struct ath_softc *sc, bf->bf_lastbf = bf->bf_lastfrm; /* one single frame */ ath_buf_set_rate(sc, bf); ath_tx_txqaddbuf(sc, txctl->txq, bf_head); + return 0; } @@ -1380,7 +1370,6 @@ static u32 ath_lookup_rate(struct ath_softc *sc, u16 aggr_limit, legacy = 0, maxampdu; int i; - skb = (struct sk_buff *)bf->bf_mpdu; tx_info = IEEE80211_SKB_CB(skb); tx_info_priv = (struct ath_tx_info_priv *) -- cgit v1.2.3 From dca3edb88ef567671886a85c5e40d491ccecf934 Mon Sep 17 00:00:00 2001 From: Sujith Date: Wed, 29 Oct 2008 10:19:01 +0530 Subject: ath9k: Remove internal RX A-MPDU processing mac80211 has RX A-MPDU reordering support. Use that and remove redundant RX processing within the driver. Signed-off-by: Sujith Signed-off-by: John W. Linville --- drivers/net/wireless/ath9k/core.c | 6 - drivers/net/wireless/ath9k/core.h | 43 ---- drivers/net/wireless/ath9k/main.c | 36 +-- drivers/net/wireless/ath9k/recv.c | 501 -------------------------------------- 4 files changed, 2 insertions(+), 584 deletions(-) (limited to 'drivers/net/wireless/ath9k/recv.c') diff --git a/drivers/net/wireless/ath9k/core.c b/drivers/net/wireless/ath9k/core.c index d13844647f93..5f5184acb274 100644 --- a/drivers/net/wireless/ath9k/core.c +++ b/drivers/net/wireless/ath9k/core.c @@ -1189,8 +1189,6 @@ void ath_node_attach(struct ath_softc *sc, struct ieee80211_sta *sta) if (sc->sc_flags & SC_OP_TXAGGR) ath_tx_node_init(sc, an); - if (sc->sc_flags & SC_OP_RXAGGR) - ath_rx_node_init(sc, an); an->maxampdu = 1 << (IEEE80211_HTCAP_MAXRXAMPDU_FACTOR + sta->ht_cap.ampdu_factor); @@ -1208,8 +1206,6 @@ void ath_node_detach(struct ath_softc *sc, struct ieee80211_sta *sta) if (sc->sc_flags & SC_OP_TXAGGR) ath_tx_node_cleanup(sc, an); - if (sc->sc_flags & SC_OP_RXAGGR) - ath_rx_node_cleanup(sc, an); } /* @@ -1230,8 +1226,6 @@ void ath_newassoc(struct ath_softc *sc, for (tidno = 0; tidno < WME_NUM_TID; tidno++) { if (sc->sc_flags & SC_OP_TXAGGR) ath_tx_aggr_teardown(sc, an, tidno); - if (sc->sc_flags & SC_OP_RXAGGR) - ath_rx_aggr_teardown(sc, an, tidno); } } } diff --git a/drivers/net/wireless/ath9k/core.h b/drivers/net/wireless/ath9k/core.h index dd33cb7f2ca6..5b17e88ab9a9 100644 --- a/drivers/net/wireless/ath9k/core.h +++ b/drivers/net/wireless/ath9k/core.h @@ -304,15 +304,7 @@ void ath_descdma_cleanup(struct ath_softc *sc, #define ATH_MAX_ANTENNA 3 #define ATH_RXBUF 512 -#define ATH_RX_TIMEOUT 40 /* 40 milliseconds */ #define WME_NUM_TID 16 -#define IEEE80211_BAR_CTL_TID_M 0xF000 /* tid mask */ -#define IEEE80211_BAR_CTL_TID_S 12 /* tid shift */ - -enum ATH_RX_TYPE { - ATH_RX_NON_CONSUMED = 0, - ATH_RX_CONSUMED -}; /* per frame rx status block */ struct ath_recv_status { @@ -346,47 +338,18 @@ struct ath_rxbuf { struct ath_recv_status rx_status; /* cached rx status */ }; -/* Per-TID aggregate receiver state for a node */ -struct ath_arx_tid { - struct ath_node *an; - struct ath_rxbuf *rxbuf; /* re-ordering buffer */ - struct timer_list timer; - spinlock_t tidlock; - int baw_head; /* seq_next at head */ - int baw_tail; /* tail of block-ack window */ - int seq_reset; /* need to reset start sequence */ - int addba_exchangecomplete; - u16 seq_next; /* next expected sequence */ - u16 baw_size; /* block-ack window size */ -}; - -/* Per-node receiver aggregate state */ -struct ath_arx { - struct ath_arx_tid tid[WME_NUM_TID]; -}; - int ath_startrecv(struct ath_softc *sc); bool ath_stoprecv(struct ath_softc *sc); void ath_flushrecv(struct ath_softc *sc); u32 ath_calcrxfilter(struct ath_softc *sc); -void ath_rx_node_init(struct ath_softc *sc, struct ath_node *an); -void ath_rx_node_cleanup(struct ath_softc *sc, struct ath_node *an); void ath_handle_rx_intr(struct ath_softc *sc); int ath_rx_init(struct ath_softc *sc, int nbufs); void ath_rx_cleanup(struct ath_softc *sc); int ath_rx_tasklet(struct ath_softc *sc, int flush); -int ath_rx_input(struct ath_softc *sc, - struct ath_node *node, - struct sk_buff *skb, - struct ath_recv_status *rx_status, - enum ATH_RX_TYPE *status); int _ath_rx_indicate(struct ath_softc *sc, struct sk_buff *skb, struct ath_recv_status *status, u16 keyix); -int ath_rx_subframe(struct ath_node *an, struct sk_buff *skb, - struct ath_recv_status *status); - /******/ /* TX */ /******/ @@ -599,7 +562,6 @@ struct aggr_rifs_param { /* Per-node aggregation state */ struct ath_node_aggr { struct ath_atx tx; /* node transmit state */ - struct ath_arx rx; /* node receive state */ }; /* driver-specific node state */ @@ -616,11 +578,6 @@ void ath_tx_resume_tid(struct ath_softc *sc, bool ath_tx_aggr_check(struct ath_softc *sc, struct ath_node *an, u8 tidno); void ath_tx_aggr_teardown(struct ath_softc *sc, struct ath_node *an, u8 tidno); -void ath_rx_aggr_teardown(struct ath_softc *sc, - struct ath_node *an, u8 tidno); -int ath_rx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta, - u16 tid, u16 *ssn); -int ath_rx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid); int ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid, u16 *ssn); int ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid); diff --git a/drivers/net/wireless/ath9k/main.c b/drivers/net/wireless/ath9k/main.c index e177de47e3e0..65a532e08ecd 100644 --- a/drivers/net/wireless/ath9k/main.c +++ b/drivers/net/wireless/ath9k/main.c @@ -444,12 +444,10 @@ int _ath_rx_indicate(struct ath_softc *sc, u16 keyix) { struct ieee80211_hw *hw = sc->hw; - struct ath_node *an = NULL; struct ieee80211_rx_status rx_status; struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; int hdrlen = ieee80211_get_hdrlen_from_skb(skb); int padsize; - enum ATH_RX_TYPE st; /* see if any padding is done by the hw and remove it */ if (hdrlen & 3) { @@ -473,28 +471,6 @@ int _ath_rx_indicate(struct ath_softc *sc, rx_status.flag |= RX_FLAG_DECRYPTED; } - if (an) { - ath_rx_input(sc, an, - skb, status, &st); - } - if (!an || (st != ATH_RX_CONSUMED)) - __ieee80211_rx(hw, skb, &rx_status); - - return 0; -} - -int ath_rx_subframe(struct ath_node *an, struct sk_buff *skb, - struct ath_recv_status *status) -{ - struct ath_softc *sc = an->an_sc; - struct ieee80211_hw *hw = sc->hw; - struct ieee80211_rx_status rx_status; - - /* Prepare rx status */ - ath9k_rx_prepare(sc, skb, status, &rx_status); - if (!(status->flags & ATH_RX_DECRYPT_ERROR)) - rx_status.flag |= RX_FLAG_DECRYPTED; - __ieee80211_rx(hw, skb, &rx_status); return 0; @@ -1483,18 +1459,10 @@ static int ath9k_ampdu_action(struct ieee80211_hw *hw, switch (action) { case IEEE80211_AMPDU_RX_START: - ret = ath_rx_aggr_start(sc, sta, tid, ssn); - if (ret < 0) - DPRINTF(sc, ATH_DBG_FATAL, - "%s: Unable to start RX aggregation\n", - __func__); + if (!(sc->sc_flags & SC_OP_RXAGGR)) + ret = -ENOTSUPP; break; case IEEE80211_AMPDU_RX_STOP: - ret = ath_rx_aggr_stop(sc, sta, tid); - if (ret < 0) - DPRINTF(sc, ATH_DBG_FATAL, - "%s: Unable to stop RX aggregation\n", - __func__); break; case IEEE80211_AMPDU_TX_START: ret = ath_tx_aggr_start(sc, sta, tid, ssn); diff --git a/drivers/net/wireless/ath9k/recv.c b/drivers/net/wireless/ath9k/recv.c index 80f26b4c4e06..2ecb0a010ce2 100644 --- a/drivers/net/wireless/ath9k/recv.c +++ b/drivers/net/wireless/ath9k/recv.c @@ -64,328 +64,6 @@ static void ath_rx_buf_link(struct ath_softc *sc, struct ath_buf *bf) ath9k_hw_rxena(ah); } -/* Process received BAR frame */ - -static int ath_bar_rx(struct ath_softc *sc, - struct ath_node *an, - struct sk_buff *skb) -{ - struct ieee80211_bar *bar; - struct ath_arx_tid *rxtid; - struct sk_buff *tskb; - struct ath_recv_status *rx_status; - int tidno, index, cindex; - u16 seqno; - - /* look at BAR contents */ - - bar = (struct ieee80211_bar *)skb->data; - tidno = (le16_to_cpu(bar->control) & IEEE80211_BAR_CTL_TID_M) - >> IEEE80211_BAR_CTL_TID_S; - seqno = le16_to_cpu(bar->start_seq_num) >> IEEE80211_SEQ_SEQ_SHIFT; - - /* process BAR - indicate all pending RX frames till the BAR seqno */ - - rxtid = &an->an_aggr.rx.tid[tidno]; - - spin_lock_bh(&rxtid->tidlock); - - /* get relative index */ - - index = ATH_BA_INDEX(rxtid->seq_next, seqno); - - /* drop BAR if old sequence (index is too large) */ - - if ((index > rxtid->baw_size) && - (index > (IEEE80211_SEQ_MAX - (rxtid->baw_size << 2)))) - /* discard frame, ieee layer may not treat frame as a dup */ - goto unlock_and_free; - - /* complete receive processing for all pending frames upto BAR seqno */ - - cindex = (rxtid->baw_head + index) & (ATH_TID_MAX_BUFS - 1); - while ((rxtid->baw_head != rxtid->baw_tail) && - (rxtid->baw_head != cindex)) { - tskb = rxtid->rxbuf[rxtid->baw_head].rx_wbuf; - rx_status = &rxtid->rxbuf[rxtid->baw_head].rx_status; - rxtid->rxbuf[rxtid->baw_head].rx_wbuf = NULL; - - if (tskb != NULL) - ath_rx_subframe(an, tskb, rx_status); - - INCR(rxtid->baw_head, ATH_TID_MAX_BUFS); - INCR(rxtid->seq_next, IEEE80211_SEQ_MAX); - } - - /* ... and indicate rest of the frames in-order */ - - while (rxtid->baw_head != rxtid->baw_tail && - rxtid->rxbuf[rxtid->baw_head].rx_wbuf != NULL) { - tskb = rxtid->rxbuf[rxtid->baw_head].rx_wbuf; - rx_status = &rxtid->rxbuf[rxtid->baw_head].rx_status; - rxtid->rxbuf[rxtid->baw_head].rx_wbuf = NULL; - - ath_rx_subframe(an, tskb, rx_status); - - INCR(rxtid->baw_head, ATH_TID_MAX_BUFS); - INCR(rxtid->seq_next, IEEE80211_SEQ_MAX); - } - -unlock_and_free: - spin_unlock_bh(&rxtid->tidlock); - /* free bar itself */ - dev_kfree_skb(skb); - return IEEE80211_FTYPE_CTL; -} - -/* Function to handle a subframe of aggregation when HT is enabled */ - -static int ath_ampdu_input(struct ath_softc *sc, - struct ath_node *an, - struct sk_buff *skb, - struct ath_recv_status *rx_status) -{ - struct ieee80211_hdr *hdr; - struct ath_arx_tid *rxtid; - struct ath_rxbuf *rxbuf; - u8 type, subtype; - u16 rxseq; - int tid = 0, index, cindex, rxdiff; - __le16 fc; - u8 *qc; - - hdr = (struct ieee80211_hdr *)skb->data; - fc = hdr->frame_control; - - /* collect stats of frames with non-zero version */ - - if ((le16_to_cpu(hdr->frame_control) & IEEE80211_FCTL_VERS) != 0) { - dev_kfree_skb(skb); - return -1; - } - - type = le16_to_cpu(hdr->frame_control) & IEEE80211_FCTL_FTYPE; - subtype = le16_to_cpu(hdr->frame_control) & IEEE80211_FCTL_STYPE; - - if (ieee80211_is_back_req(fc)) - return ath_bar_rx(sc, an, skb); - - /* special aggregate processing only for qos unicast data frames */ - - if (!ieee80211_is_data(fc) || - !ieee80211_is_data_qos(fc) || - is_multicast_ether_addr(hdr->addr1)) - return ath_rx_subframe(an, skb, rx_status); - - /* lookup rx tid state */ - - if (ieee80211_is_data_qos(fc)) { - qc = ieee80211_get_qos_ctl(hdr); - tid = qc[0] & 0xf; - } - - if (sc->sc_ah->ah_opmode == ATH9K_M_STA) { - /* Drop the frame not belonging to me. */ - if (memcmp(hdr->addr1, sc->sc_myaddr, ETH_ALEN)) { - dev_kfree_skb(skb); - return -1; - } - } - - rxtid = &an->an_aggr.rx.tid[tid]; - - spin_lock(&rxtid->tidlock); - - rxdiff = (rxtid->baw_tail - rxtid->baw_head) & - (ATH_TID_MAX_BUFS - 1); - - /* - * If the ADDBA exchange has not been completed by the source, - * process via legacy path (i.e. no reordering buffer is needed) - */ - if (!rxtid->addba_exchangecomplete) { - spin_unlock(&rxtid->tidlock); - return ath_rx_subframe(an, skb, rx_status); - } - - /* extract sequence number from recvd frame */ - - rxseq = le16_to_cpu(hdr->seq_ctrl) >> IEEE80211_SEQ_SEQ_SHIFT; - - if (rxtid->seq_reset) { - rxtid->seq_reset = 0; - rxtid->seq_next = rxseq; - } - - index = ATH_BA_INDEX(rxtid->seq_next, rxseq); - - /* drop frame if old sequence (index is too large) */ - - if (index > (IEEE80211_SEQ_MAX - (rxtid->baw_size << 2))) { - /* discard frame, ieee layer may not treat frame as a dup */ - spin_unlock(&rxtid->tidlock); - dev_kfree_skb(skb); - return IEEE80211_FTYPE_DATA; - } - - /* sequence number is beyond block-ack window */ - - if (index >= rxtid->baw_size) { - - /* complete receive processing for all pending frames */ - - while (index >= rxtid->baw_size) { - - rxbuf = rxtid->rxbuf + rxtid->baw_head; - - if (rxbuf->rx_wbuf != NULL) { - ath_rx_subframe(an, rxbuf->rx_wbuf, - &rxbuf->rx_status); - rxbuf->rx_wbuf = NULL; - } - - INCR(rxtid->baw_head, ATH_TID_MAX_BUFS); - INCR(rxtid->seq_next, IEEE80211_SEQ_MAX); - - index--; - } - } - - /* add buffer to the recv ba window */ - - cindex = (rxtid->baw_head + index) & (ATH_TID_MAX_BUFS - 1); - rxbuf = rxtid->rxbuf + cindex; - - if (rxbuf->rx_wbuf != NULL) { - spin_unlock(&rxtid->tidlock); - /* duplicate frame */ - dev_kfree_skb(skb); - return IEEE80211_FTYPE_DATA; - } - - rxbuf->rx_wbuf = skb; - rxbuf->rx_time = get_timestamp(); - rxbuf->rx_status = *rx_status; - - /* advance tail if sequence received is newer - * than any received so far */ - - if (index >= rxdiff) { - rxtid->baw_tail = cindex; - INCR(rxtid->baw_tail, ATH_TID_MAX_BUFS); - } - - /* indicate all in-order received frames */ - - while (rxtid->baw_head != rxtid->baw_tail) { - rxbuf = rxtid->rxbuf + rxtid->baw_head; - if (!rxbuf->rx_wbuf) - break; - - ath_rx_subframe(an, rxbuf->rx_wbuf, &rxbuf->rx_status); - rxbuf->rx_wbuf = NULL; - - INCR(rxtid->baw_head, ATH_TID_MAX_BUFS); - INCR(rxtid->seq_next, IEEE80211_SEQ_MAX); - } - - /* - * start a timer to flush all received frames if there are pending - * receive frames - */ - if (rxtid->baw_head != rxtid->baw_tail) - mod_timer(&rxtid->timer, ATH_RX_TIMEOUT); - else - del_timer_sync(&rxtid->timer); - - spin_unlock(&rxtid->tidlock); - return IEEE80211_FTYPE_DATA; -} - -/* Timer to flush all received sub-frames */ - -static void ath_rx_timer(unsigned long data) -{ - struct ath_arx_tid *rxtid = (struct ath_arx_tid *)data; - struct ath_node *an = rxtid->an; - struct ath_rxbuf *rxbuf; - int nosched; - - spin_lock_bh(&rxtid->tidlock); - while (rxtid->baw_head != rxtid->baw_tail) { - rxbuf = rxtid->rxbuf + rxtid->baw_head; - if (!rxbuf->rx_wbuf) { - INCR(rxtid->baw_head, ATH_TID_MAX_BUFS); - INCR(rxtid->seq_next, IEEE80211_SEQ_MAX); - continue; - } - - /* - * Stop if the next one is a very recent frame. - * - * Call get_timestamp in every iteration to protect against the - * case in which a new frame is received while we are executing - * this function. Using a timestamp obtained before entering - * the loop could lead to a very large time interval - * (a negative value typecast to unsigned), breaking the - * function's logic. - */ - if ((get_timestamp() - rxbuf->rx_time) < - (ATH_RX_TIMEOUT * HZ / 1000)) - break; - - ath_rx_subframe(an, rxbuf->rx_wbuf, - &rxbuf->rx_status); - rxbuf->rx_wbuf = NULL; - - INCR(rxtid->baw_head, ATH_TID_MAX_BUFS); - INCR(rxtid->seq_next, IEEE80211_SEQ_MAX); - } - - /* - * start a timer to flush all received frames if there are pending - * receive frames - */ - if (rxtid->baw_head != rxtid->baw_tail) - nosched = 0; - else - nosched = 1; /* no need to re-arm the timer again */ - - spin_unlock_bh(&rxtid->tidlock); -} - -/* Free all pending sub-frames in the re-ordering buffer */ - -static void ath_rx_flush_tid(struct ath_softc *sc, struct ath_arx_tid *rxtid, - int drop) -{ - struct ath_rxbuf *rxbuf; - unsigned long flag; - - spin_lock_irqsave(&rxtid->tidlock, flag); - while (rxtid->baw_head != rxtid->baw_tail) { - rxbuf = rxtid->rxbuf + rxtid->baw_head; - if (!rxbuf->rx_wbuf) { - INCR(rxtid->baw_head, ATH_TID_MAX_BUFS); - INCR(rxtid->seq_next, IEEE80211_SEQ_MAX); - continue; - } - - if (drop) - dev_kfree_skb(rxbuf->rx_wbuf); - else - ath_rx_subframe(rxtid->an, - rxbuf->rx_wbuf, - &rxbuf->rx_status); - - rxbuf->rx_wbuf = NULL; - - INCR(rxtid->baw_head, ATH_TID_MAX_BUFS); - INCR(rxtid->seq_next, IEEE80211_SEQ_MAX); - } - spin_unlock_irqrestore(&rxtid->tidlock, flag); -} - static struct sk_buff *ath_rxbuf_alloc(struct ath_softc *sc, u32 len) { @@ -716,23 +394,6 @@ void ath_flushrecv(struct ath_softc *sc) spin_unlock_bh(&sc->sc_rxflushlock); } -/* Process an individual frame */ - -int ath_rx_input(struct ath_softc *sc, - struct ath_node *an, - struct sk_buff *skb, - struct ath_recv_status *rx_status, - enum ATH_RX_TYPE *status) -{ - if (sc->sc_flags & SC_OP_RXAGGR) { - *status = ATH_RX_CONSUMED; - return ath_ampdu_input(sc, an, skb, rx_status); - } else { - *status = ATH_RX_NON_CONSUMED; - return -1; - } -} - /* Process receive queue, as well as LED, etc. */ int ath_rx_tasklet(struct ath_softc *sc, int flush) @@ -1091,165 +752,3 @@ rx_next: return 0; #undef PA2DESC } - -/* Process ADDBA request in per-TID data structure */ - -int ath_rx_aggr_start(struct ath_softc *sc, - struct ieee80211_sta *sta, - u16 tid, - u16 *ssn) -{ - struct ath_arx_tid *rxtid; - struct ath_node *an; - struct ieee80211_hw *hw = sc->hw; - struct ieee80211_supported_band *sband; - u16 buffersize = 0; - - an = (struct ath_node *)sta->drv_priv; - sband = hw->wiphy->bands[hw->conf.channel->band]; - buffersize = IEEE80211_MIN_AMPDU_BUF << - sband->ht_cap.ampdu_factor; /* FIXME */ - - rxtid = &an->an_aggr.rx.tid[tid]; - - spin_lock_bh(&rxtid->tidlock); - if (sc->sc_flags & SC_OP_RXAGGR) { - /* Allow aggregation reception - * Adjust rx BA window size. Peer might indicate a - * zero buffer size for a _dont_care_ condition. - */ - if (buffersize) - rxtid->baw_size = min(buffersize, rxtid->baw_size); - - /* set rx sequence number */ - rxtid->seq_next = *ssn; - - /* Allocate the receive buffers for this TID */ - DPRINTF(sc, ATH_DBG_AGGR, - "%s: Allcating rxbuffer for TID %d\n", __func__, tid); - - if (rxtid->rxbuf == NULL) { - /* - * If the rxbuff is not NULL at this point, we *probably* - * already allocated the buffer on a previous ADDBA, - * and this is a subsequent ADDBA that got through. - * Don't allocate, but use the value in the pointer, - * we zero it out when we de-allocate. - */ - rxtid->rxbuf = kmalloc(ATH_TID_MAX_BUFS * - sizeof(struct ath_rxbuf), GFP_ATOMIC); - } - if (rxtid->rxbuf == NULL) { - DPRINTF(sc, ATH_DBG_AGGR, - "%s: Unable to allocate RX buffer, " - "refusing ADDBA\n", __func__); - } else { - /* Ensure the memory is zeroed out (all internal - * pointers are null) */ - memset(rxtid->rxbuf, 0, ATH_TID_MAX_BUFS * - sizeof(struct ath_rxbuf)); - DPRINTF(sc, ATH_DBG_AGGR, - "%s: Allocated @%p\n", __func__, rxtid->rxbuf); - - /* Allow aggregation reception */ - rxtid->addba_exchangecomplete = 1; - } - } - spin_unlock_bh(&rxtid->tidlock); - - return 0; -} - -/* Process DELBA */ - -int ath_rx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid) -{ - struct ath_node *an = (struct ath_node *)sta->drv_priv; - - ath_rx_aggr_teardown(sc, an, tid); - return 0; -} - -/* Rx aggregation tear down */ - -void ath_rx_aggr_teardown(struct ath_softc *sc, struct ath_node *an, u8 tid) -{ - struct ath_arx_tid *rxtid = &an->an_aggr.rx.tid[tid]; - - if (!rxtid->addba_exchangecomplete) - return; - - del_timer_sync(&rxtid->timer); - ath_rx_flush_tid(sc, rxtid, 0); - rxtid->addba_exchangecomplete = 0; - - /* De-allocate the receive buffer array allocated when addba started */ - - if (rxtid->rxbuf) { - DPRINTF(sc, ATH_DBG_AGGR, - "%s: Deallocating TID %d rxbuff @%p\n", - __func__, tid, rxtid->rxbuf); - kfree(rxtid->rxbuf); - - /* Set pointer to null to avoid reuse*/ - rxtid->rxbuf = NULL; - } -} - -/* Initialize per-node receive state */ - -void ath_rx_node_init(struct ath_softc *sc, struct ath_node *an) -{ - struct ath_arx_tid *rxtid; - int tidno; - - /* Init per tid rx state */ - for (tidno = 0, rxtid = &an->an_aggr.rx.tid[tidno]; - tidno < WME_NUM_TID; - tidno++, rxtid++) { - rxtid->an = an; - rxtid->seq_reset = 1; - rxtid->seq_next = 0; - rxtid->baw_size = WME_MAX_BA; - rxtid->baw_head = rxtid->baw_tail = 0; - - /* - * Ensure the buffer pointer is null at this point - * (needs to be allocated when addba is received) - */ - - rxtid->rxbuf = NULL; - setup_timer(&rxtid->timer, ath_rx_timer, - (unsigned long)rxtid); - spin_lock_init(&rxtid->tidlock); - - /* ADDBA state */ - rxtid->addba_exchangecomplete = 0; - } -} - -void ath_rx_node_cleanup(struct ath_softc *sc, struct ath_node *an) -{ - struct ath_arx_tid *rxtid; - int tidno, i; - - /* Init per tid rx state */ - for (tidno = 0, rxtid = &an->an_aggr.rx.tid[tidno]; - tidno < WME_NUM_TID; - tidno++, rxtid++) { - - if (!rxtid->addba_exchangecomplete) - continue; - - /* must cancel timer first */ - del_timer_sync(&rxtid->timer); - - /* drop any pending sub-frames */ - ath_rx_flush_tid(sc, rxtid, 1); - - for (i = 0; i < ATH_TID_MAX_BUFS; i++) - ASSERT(rxtid->rxbuf[i].rx_wbuf == NULL); - - rxtid->addba_exchangecomplete = 0; - } -} -- cgit v1.2.3 From ffb826767bffda61426d964a8fc24a216a14b0bd Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Mon, 3 Nov 2008 14:43:01 -0800 Subject: ath9k: enable RXing of beacons on STA/IBSS This enables beacons to come through on STA/IBSS. It should fix sporadic connection issues. Right now mac80211 expect beacons so give it beacons. Signed-off-by: Luis R. Rodriguez Signed-off-by: John W. Linville --- drivers/net/wireless/ath9k/recv.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers/net/wireless/ath9k/recv.c') diff --git a/drivers/net/wireless/ath9k/recv.c b/drivers/net/wireless/ath9k/recv.c index 2ecb0a010ce2..2d72ac19fada 100644 --- a/drivers/net/wireless/ath9k/recv.c +++ b/drivers/net/wireless/ath9k/recv.c @@ -296,9 +296,8 @@ u32 ath_calcrxfilter(struct ath_softc *sc) rfilt &= ~ATH9K_RX_FILTER_UCAST; } - if (((sc->sc_ah->ah_opmode == ATH9K_M_STA) && - (sc->rx_filter & FIF_BCN_PRBRESP_PROMISC)) || - (sc->sc_ah->ah_opmode == ATH9K_M_IBSS)) + if (sc->sc_ah->ah_opmode == ATH9K_M_STA || + sc->sc_ah->ah_opmode == ATH9K_M_IBSS) rfilt |= ATH9K_RX_FILTER_BEACON; /* If in HOSTAP mode, want to enable reception of PSPOLL frames -- cgit v1.2.3 From ca0c7e5101fd4f37fed8e851709f08580b92fbb3 Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Thu, 20 Nov 2008 17:15:12 -0800 Subject: ath9k: Fix SW-IOMMU bounce buffer starvation This should fix the SW-IOMMU bounce buffer starvation seen ok kernel.org bugzilla 11811: http://bugzilla.kernel.org/show_bug.cgi?id=11811 Users on MacBook Pro 3.1/MacBook v2 would see something like: DMA: Out of SW-IOMMU space for 4224 bytes at device 0000:0b:00.0 Unfortunately its only easy to trigger on MacBook Pro 3.1/MacBook v2 so far so its difficult to debug (even with swiotlb=force). We were pci_unmap_single()'ing less bytes than what we called for with pci_map_single() and as such we were starving the swiotlb from its 64MB amount of bounce buffers. We remain consistent and now always use sc->rxbufsize for RX. While at it we update the beacon DMA maps as well to only use the data portion of the skb, previous to this we were pci_map_single()'ing more data for beaconing than what we tell the hardware it can use, therefore pushing more iotlb abuse. Still not sure why this is so easily triggerable on MacBook Pro 3.1, it may be the hardware configuration tends to use more memory > 3GB mark for DMA. Signed-off-by: Maciej Zenczykowski Signed-off-by: Bennyam Malavazi Signed-off-by: Luis R. Rodriguez Signed-off-by: John W. Linville --- drivers/net/wireless/ath9k/beacon.c | 10 +++++----- drivers/net/wireless/ath9k/recv.c | 6 +++--- 2 files changed, 8 insertions(+), 8 deletions(-) (limited to 'drivers/net/wireless/ath9k/recv.c') diff --git a/drivers/net/wireless/ath9k/beacon.c b/drivers/net/wireless/ath9k/beacon.c index 9e15c30bbc06..4dd1c1bda0fb 100644 --- a/drivers/net/wireless/ath9k/beacon.c +++ b/drivers/net/wireless/ath9k/beacon.c @@ -170,7 +170,7 @@ static struct ath_buf *ath_beacon_generate(struct ath_softc *sc, int if_id) skb = (struct sk_buff *)bf->bf_mpdu; if (skb) { pci_unmap_single(sc->pdev, bf->bf_dmacontext, - skb_end_pointer(skb) - skb->head, + skb->len, PCI_DMA_TODEVICE); } @@ -193,7 +193,7 @@ static struct ath_buf *ath_beacon_generate(struct ath_softc *sc, int if_id) bf->bf_buf_addr = bf->bf_dmacontext = pci_map_single(sc->pdev, skb->data, - skb_end_pointer(skb) - skb->head, + skb->len, PCI_DMA_TODEVICE); skb = ieee80211_get_buffered_bc(sc->hw, avp->av_if_data); @@ -352,7 +352,7 @@ int ath_beacon_alloc(struct ath_softc *sc, int if_id) if (bf->bf_mpdu != NULL) { skb = (struct sk_buff *)bf->bf_mpdu; pci_unmap_single(sc->pdev, bf->bf_dmacontext, - skb_end_pointer(skb) - skb->head, + skb->len, PCI_DMA_TODEVICE); dev_kfree_skb_any(skb); bf->bf_mpdu = NULL; @@ -412,7 +412,7 @@ int ath_beacon_alloc(struct ath_softc *sc, int if_id) bf->bf_buf_addr = bf->bf_dmacontext = pci_map_single(sc->pdev, skb->data, - skb_end_pointer(skb) - skb->head, + skb->len, PCI_DMA_TODEVICE); bf->bf_mpdu = skb; @@ -439,7 +439,7 @@ void ath_beacon_return(struct ath_softc *sc, struct ath_vap *avp) if (bf->bf_mpdu != NULL) { struct sk_buff *skb = (struct sk_buff *)bf->bf_mpdu; pci_unmap_single(sc->pdev, bf->bf_dmacontext, - skb_end_pointer(skb) - skb->head, + skb->len, PCI_DMA_TODEVICE); dev_kfree_skb_any(skb); bf->bf_mpdu = NULL; diff --git a/drivers/net/wireless/ath9k/recv.c b/drivers/net/wireless/ath9k/recv.c index 4983402af559..ad5f88879dc4 100644 --- a/drivers/net/wireless/ath9k/recv.c +++ b/drivers/net/wireless/ath9k/recv.c @@ -456,7 +456,7 @@ static int ath_rx_indicate(struct ath_softc *sc, if (nskb != NULL) { bf->bf_mpdu = nskb; bf->bf_buf_addr = pci_map_single(sc->pdev, nskb->data, - skb_end_pointer(nskb) - nskb->head, + sc->sc_rxbufsize, PCI_DMA_FROMDEVICE); bf->bf_dmacontext = bf->bf_buf_addr; ATH_RX_CONTEXT(nskb)->ctx_rxbuf = bf; @@ -542,7 +542,7 @@ int ath_rx_init(struct ath_softc *sc, int nbufs) bf->bf_mpdu = skb; bf->bf_buf_addr = pci_map_single(sc->pdev, skb->data, - skb_end_pointer(skb) - skb->head, + sc->sc_rxbufsize, PCI_DMA_FROMDEVICE); bf->bf_dmacontext = bf->bf_buf_addr; ATH_RX_CONTEXT(skb)->ctx_rxbuf = bf; @@ -1007,7 +1007,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush) pci_dma_sync_single_for_cpu(sc->pdev, bf->bf_buf_addr, - skb_tailroom(skb), + sc->sc_rxbufsize, PCI_DMA_FROMDEVICE); pci_unmap_single(sc->pdev, bf->bf_buf_addr, -- cgit v1.2.3 From b4b6cda2298b0c9a0af902312184b775b8867c65 Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Thu, 20 Nov 2008 17:15:13 -0800 Subject: ath9k: correct expected max RX buffer size We should only tell the hardware its capable of DMA'ing to us only what we asked dev_alloc_skb(). Prior to this it is possible a large RX'd frame could have corrupted DMA data but for us but we were saved only because we were previously also pci_map_single()'ing the same large value. The issue prior to this though was we were unmapping a smaller amount which the prior DMA patch fixed. Signed-off-by: Bennyam Malavazi Signed-off-by: Luis R. Rodriguez Signed-off-by: John W. Linville --- drivers/net/wireless/ath9k/recv.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'drivers/net/wireless/ath9k/recv.c') diff --git a/drivers/net/wireless/ath9k/recv.c b/drivers/net/wireless/ath9k/recv.c index ad5f88879dc4..504a0444d89f 100644 --- a/drivers/net/wireless/ath9k/recv.c +++ b/drivers/net/wireless/ath9k/recv.c @@ -49,10 +49,12 @@ static void ath_rx_buf_link(struct ath_softc *sc, struct ath_buf *bf) ASSERT(skb != NULL); ds->ds_vdata = skb->data; - /* setup rx descriptors */ + /* setup rx descriptors. The sc_rxbufsize here tells the harware + * how much data it can DMA to us and that we are prepared + * to process */ ath9k_hw_setuprxdesc(ah, ds, - skb_tailroom(skb), /* buffer size */ + sc->sc_rxbufsize, 0); if (sc->sc_rxlink == NULL) @@ -398,6 +400,13 @@ static struct sk_buff *ath_rxbuf_alloc(struct ath_softc *sc, * in rx'd frames. */ + /* Note: the kernel can allocate a value greater than + * what we ask it to give us. We really only need 4 KB as that + * is this hardware supports and in fact we need at least 3849 + * as that is the MAX AMSDU size this hardware supports. + * Unfortunately this means we may get 8 KB here from the + * kernel... and that is actually what is observed on some + * systems :( */ skb = dev_alloc_skb(len + sc->sc_cachelsz - 1); if (skb != NULL) { off = ((unsigned long) skb->data) % sc->sc_cachelsz; -- cgit v1.2.3 From be0418ada3fad110977a9d5fa16d4907d4e7d726 Mon Sep 17 00:00:00 2001 From: Sujith Date: Tue, 18 Nov 2008 09:05:55 +0530 Subject: ath9k: Revamp RX handling Remove a lot of old, crufty code and make RX status reporting a bit sane and clean. Do not do anything to the RX skb before unmapping. So in ath_rx_tasklet(), move the skb_put() after PCI unmap. Signed-off-by: Sujith Signed-off-by: John W. Linville --- drivers/net/wireless/ath9k/core.h | 53 +--- drivers/net/wireless/ath9k/main.c | 100 ------- drivers/net/wireless/ath9k/recv.c | 575 ++++++++++++++------------------------ 3 files changed, 209 insertions(+), 519 deletions(-) (limited to 'drivers/net/wireless/ath9k/recv.c') diff --git a/drivers/net/wireless/ath9k/core.h b/drivers/net/wireless/ath9k/core.h index fe9dc99cc3e5..5500ef49d8bb 100644 --- a/drivers/net/wireless/ath9k/core.h +++ b/drivers/net/wireless/ath9k/core.h @@ -279,13 +279,6 @@ struct ath_descdma { dma_addr_t dd_dmacontext; }; -/* Abstraction of a received RX MPDU/MMPDU, or a RX fragment */ - -struct ath_rx_context { - struct ath_buf *ctx_rxbuf; /* associated ath_buf for rx */ -}; -#define ATH_RX_CONTEXT(skb) ((struct ath_rx_context *)skb->cb) - int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd, struct list_head *head, @@ -298,61 +291,21 @@ void ath_descdma_cleanup(struct ath_softc *sc, struct ath_descdma *dd, struct list_head *head); -/******/ -/* RX */ -/******/ +/***********/ +/* RX / TX */ +/***********/ #define ATH_MAX_ANTENNA 3 #define ATH_RXBUF 512 #define WME_NUM_TID 16 -/* per frame rx status block */ -struct ath_recv_status { - u64 tsf; /* mac tsf */ - int8_t rssi; /* RSSI (noise floor ajusted) */ - int8_t rssictl[ATH_MAX_ANTENNA]; /* RSSI (noise floor ajusted) */ - int8_t rssiextn[ATH_MAX_ANTENNA]; /* RSSI (noise floor ajusted) */ - int8_t abs_rssi; /* absolute RSSI */ - u8 rateieee; /* data rate received (IEEE rate code) */ - u8 ratecode; /* phy rate code */ - int rateKbps; /* data rate received (Kbps) */ - int antenna; /* rx antenna */ - int flags; /* status of associated skb */ -#define ATH_RX_FCS_ERROR 0x01 -#define ATH_RX_MIC_ERROR 0x02 -#define ATH_RX_DECRYPT_ERROR 0x04 -#define ATH_RX_RSSI_VALID 0x08 -/* if any of ctl,extn chainrssis are valid */ -#define ATH_RX_CHAIN_RSSI_VALID 0x10 -/* if extn chain rssis are valid */ -#define ATH_RX_RSSI_EXTN_VALID 0x20 -/* set if 40Mhz, clear if 20Mhz */ -#define ATH_RX_40MHZ 0x40 -/* set if short GI, clear if full GI */ -#define ATH_RX_SHORT_GI 0x80 -}; - -struct ath_rxbuf { - struct sk_buff *rx_wbuf; - unsigned long rx_time; /* system time when received */ - struct ath_recv_status rx_status; /* cached rx status */ -}; - int ath_startrecv(struct ath_softc *sc); bool ath_stoprecv(struct ath_softc *sc); void ath_flushrecv(struct ath_softc *sc); u32 ath_calcrxfilter(struct ath_softc *sc); -void ath_handle_rx_intr(struct ath_softc *sc); int ath_rx_init(struct ath_softc *sc, int nbufs); void ath_rx_cleanup(struct ath_softc *sc); int ath_rx_tasklet(struct ath_softc *sc, int flush); -int _ath_rx_indicate(struct ath_softc *sc, - struct sk_buff *skb, - struct ath_recv_status *status, - u16 keyix); -/******/ -/* TX */ -/******/ #define ATH_TXBUF 512 /* max number of transmit attempts (tries) */ diff --git a/drivers/net/wireless/ath9k/main.c b/drivers/net/wireless/ath9k/main.c index 60319d7ad24e..c9ac5e8acffa 100644 --- a/drivers/net/wireless/ath9k/main.c +++ b/drivers/net/wireless/ath9k/main.c @@ -236,68 +236,6 @@ static void setup_ht_cap(struct ieee80211_sta_ht_cap *ht_info) ht_info->mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED; } -static int ath_rate2idx(struct ath_softc *sc, int rate) -{ - int i = 0, cur_band, n_rates; - struct ieee80211_hw *hw = sc->hw; - - cur_band = hw->conf.channel->band; - n_rates = sc->sbands[cur_band].n_bitrates; - - for (i = 0; i < n_rates; i++) { - if (sc->sbands[cur_band].bitrates[i].bitrate == rate) - break; - } - - /* - * NB:mac80211 validates rx rate index against the supported legacy rate - * index only (should be done against ht rates also), return the highest - * legacy rate index for rx rate which does not match any one of the - * supported basic and extended rates to make mac80211 happy. - * The following hack will be cleaned up once the issue with - * the rx rate index validation in mac80211 is fixed. - */ - if (i == n_rates) - return n_rates - 1; - return i; -} - -static void ath9k_rx_prepare(struct ath_softc *sc, - struct sk_buff *skb, - struct ath_recv_status *status, - struct ieee80211_rx_status *rx_status) -{ - struct ieee80211_hw *hw = sc->hw; - struct ieee80211_channel *curchan = hw->conf.channel; - - memset(rx_status, 0, sizeof(struct ieee80211_rx_status)); - - rx_status->mactime = status->tsf; - rx_status->band = curchan->band; - rx_status->freq = curchan->center_freq; - rx_status->noise = sc->sc_ani.sc_noise_floor; - rx_status->signal = rx_status->noise + status->rssi; - rx_status->rate_idx = ath_rate2idx(sc, (status->rateKbps / 100)); - rx_status->antenna = status->antenna; - - /* at 45 you will be able to use MCS 15 reliably. A more elaborate - * scheme can be used here but it requires tables of SNR/throughput for - * each possible mode used. */ - rx_status->qual = status->rssi * 100 / 45; - - /* rssi can be more than 45 though, anything above that - * should be considered at 100% */ - if (rx_status->qual > 100) - rx_status->qual = 100; - - if (status->flags & ATH_RX_MIC_ERROR) - rx_status->flag |= RX_FLAG_MMIC_ERROR; - if (status->flags & ATH_RX_FCS_ERROR) - rx_status->flag |= RX_FLAG_FAILED_FCS_CRC; - - rx_status->flag |= RX_FLAG_TSFT; -} - static void ath9k_ht_conf(struct ath_softc *sc, struct ieee80211_bss_conf *bss_conf) { @@ -440,44 +378,6 @@ void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb, ieee80211_tx_status(hw, skb); } -int _ath_rx_indicate(struct ath_softc *sc, - struct sk_buff *skb, - struct ath_recv_status *status, - u16 keyix) -{ - struct ieee80211_hw *hw = sc->hw; - struct ieee80211_rx_status rx_status; - struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; - int hdrlen = ieee80211_get_hdrlen_from_skb(skb); - int padsize; - - /* see if any padding is done by the hw and remove it */ - if (hdrlen & 3) { - padsize = hdrlen % 4; - memmove(skb->data + padsize, skb->data, hdrlen); - skb_pull(skb, padsize); - } - - /* Prepare rx status */ - ath9k_rx_prepare(sc, skb, status, &rx_status); - - if (!(keyix == ATH9K_RXKEYIX_INVALID) && - !(status->flags & ATH_RX_DECRYPT_ERROR)) { - rx_status.flag |= RX_FLAG_DECRYPTED; - } else if ((le16_to_cpu(hdr->frame_control) & IEEE80211_FCTL_PROTECTED) - && !(status->flags & ATH_RX_DECRYPT_ERROR) - && skb->len >= hdrlen + 4) { - keyix = skb->data[hdrlen + 3] >> 6; - - if (test_bit(keyix, sc->sc_keymap)) - rx_status.flag |= RX_FLAG_DECRYPTED; - } - - __ieee80211_rx(hw, skb, &rx_status); - - return 0; -} - /********************************/ /* LED functions */ /********************************/ diff --git a/drivers/net/wireless/ath9k/recv.c b/drivers/net/wireless/ath9k/recv.c index 2d72ac19fada..000e189e104a 100644 --- a/drivers/net/wireless/ath9k/recv.c +++ b/drivers/net/wireless/ath9k/recv.c @@ -14,10 +14,6 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* - * Implementation of receive path. - */ - #include "core.h" /* @@ -27,10 +23,7 @@ * MAC acknowledges BA status as long as it copies frames to host * buffer (or rx fifo). This can incorrectly acknowledge packets * to a sender if last desc is self-linked. - * - * NOTE: Caller should hold the rxbuf lock. */ - static void ath_rx_buf_link(struct ath_softc *sc, struct ath_buf *bf) { struct ath_hal *ah = sc->sc_ah; @@ -40,19 +33,17 @@ static void ath_rx_buf_link(struct ath_softc *sc, struct ath_buf *bf) ATH_RXBUF_RESET(bf); ds = bf->bf_desc; - ds->ds_link = 0; /* link to null */ + ds->ds_link = 0; /* link to null */ ds->ds_data = bf->bf_buf_addr; - /* XXX For RADAR? - * virtual addr of the beginning of the buffer. */ + /* virtual addr of the beginning of the buffer. */ skb = bf->bf_mpdu; ASSERT(skb != NULL); ds->ds_vdata = skb->data; /* setup rx descriptors */ - ath9k_hw_setuprxdesc(ah, - ds, - skb_tailroom(skb), /* buffer size */ + ath9k_hw_setuprxdesc(ah, ds, + skb_tailroom(skb), /* buffer size */ 0); if (sc->sc_rxlink == NULL) @@ -64,8 +55,7 @@ static void ath_rx_buf_link(struct ath_softc *sc, struct ath_buf *bf) ath9k_hw_rxena(ah); } -static struct sk_buff *ath_rxbuf_alloc(struct ath_softc *sc, - u32 len) +static struct sk_buff *ath_rxbuf_alloc(struct ath_softc *sc, u32 len) { struct sk_buff *skb; u32 off; @@ -91,59 +81,154 @@ static struct sk_buff *ath_rxbuf_alloc(struct ath_softc *sc, return skb; } -static void ath_rx_requeue(struct ath_softc *sc, struct sk_buff *skb) +static void ath_rx_requeue(struct ath_softc *sc, struct ath_buf *bf) { - struct ath_buf *bf = ATH_RX_CONTEXT(skb)->ctx_rxbuf; + struct sk_buff *skb; ASSERT(bf != NULL); - spin_lock_bh(&sc->sc_rxbuflock); - if (bf->bf_status & ATH_BUFSTATUS_STALE) { - /* - * This buffer is still held for hw acess. - * Mark it as free to be re-queued it later. - */ - bf->bf_status |= ATH_BUFSTATUS_FREE; - } else { - /* XXX: we probably never enter here, remove after - * verification */ - list_add_tail(&bf->list, &sc->sc_rxbuf); - ath_rx_buf_link(sc, bf); + if (bf->bf_mpdu == NULL) { + skb = ath_rxbuf_alloc(sc, sc->sc_rxbufsize); + if (skb != NULL) { + bf->bf_mpdu = skb; + bf->bf_buf_addr = pci_map_single(sc->pdev, skb->data, + skb_end_pointer(skb) - skb->head, + PCI_DMA_FROMDEVICE); + bf->bf_dmacontext = bf->bf_buf_addr; + + } } - spin_unlock_bh(&sc->sc_rxbuflock); + + list_move_tail(&bf->list, &sc->sc_rxbuf); + ath_rx_buf_link(sc, bf); +} + + +static int ath_rate2idx(struct ath_softc *sc, int rate) +{ + int i = 0, cur_band, n_rates; + struct ieee80211_hw *hw = sc->hw; + + cur_band = hw->conf.channel->band; + n_rates = sc->sbands[cur_band].n_bitrates; + + for (i = 0; i < n_rates; i++) { + if (sc->sbands[cur_band].bitrates[i].bitrate == rate) + break; + } + + /* + * NB:mac80211 validates rx rate index against the supported legacy rate + * index only (should be done against ht rates also), return the highest + * legacy rate index for rx rate which does not match any one of the + * supported basic and extended rates to make mac80211 happy. + * The following hack will be cleaned up once the issue with + * the rx rate index validation in mac80211 is fixed. + */ + if (i == n_rates) + return n_rates - 1; + + return i; } /* - * The skb indicated to upper stack won't be returned to us. - * So we have to allocate a new one and queue it by ourselves. + * For Decrypt or Demic errors, we only mark packet status here and always push + * up the frame up to let mac80211 handle the actual error case, be it no + * decryption key or real decryption error. This let us keep statistics there. */ -static int ath_rx_indicate(struct ath_softc *sc, - struct sk_buff *skb, - struct ath_recv_status *status, - u16 keyix) +static int ath_rx_prepare(struct sk_buff *skb, struct ath_desc *ds, + struct ieee80211_rx_status *rx_status, bool *decrypt_error, + struct ath_softc *sc) { - struct ath_buf *bf = ATH_RX_CONTEXT(skb)->ctx_rxbuf; - struct sk_buff *nskb; - int type; - - /* indicate frame to the stack, which will free the old skb. */ - type = _ath_rx_indicate(sc, skb, status, keyix); - - /* allocate a new skb and queue it to for H/W processing */ - nskb = ath_rxbuf_alloc(sc, sc->sc_rxbufsize); - if (nskb != NULL) { - bf->bf_mpdu = nskb; - bf->bf_buf_addr = pci_map_single(sc->pdev, nskb->data, - skb_end_pointer(nskb) - nskb->head, - PCI_DMA_FROMDEVICE); - bf->bf_dmacontext = bf->bf_buf_addr; - ATH_RX_CONTEXT(nskb)->ctx_rxbuf = bf; + struct ieee80211_hdr *hdr; + int ratekbps; + u8 ratecode; + __le16 fc; + + hdr = (struct ieee80211_hdr *)skb->data; + fc = hdr->frame_control; + memset(rx_status, 0, sizeof(struct ieee80211_rx_status)); + + if (ds->ds_rxstat.rs_more) { + /* + * Frame spans multiple descriptors; this cannot happen yet + * as we don't support jumbograms. If not in monitor mode, + * discard the frame. Enable this if you want to see + * error frames in Monitor mode. + */ + if (sc->sc_ah->ah_opmode != ATH9K_M_MONITOR) + goto rx_next; + } else if (ds->ds_rxstat.rs_status != 0) { + if (ds->ds_rxstat.rs_status & ATH9K_RXERR_CRC) + rx_status->flag |= RX_FLAG_FAILED_FCS_CRC; + if (ds->ds_rxstat.rs_status & ATH9K_RXERR_PHY) + goto rx_next; - /* queue the new wbuf to H/W */ - ath_rx_requeue(sc, nskb); + if (ds->ds_rxstat.rs_status & ATH9K_RXERR_DECRYPT) { + *decrypt_error = true; + } else if (ds->ds_rxstat.rs_status & ATH9K_RXERR_MIC) { + if (ieee80211_is_ctl(fc)) + /* + * Sometimes, we get invalid + * MIC failures on valid control frames. + * Remove these mic errors. + */ + ds->ds_rxstat.rs_status &= ~ATH9K_RXERR_MIC; + else + rx_status->flag |= RX_FLAG_MMIC_ERROR; + } + /* + * Reject error frames with the exception of + * decryption and MIC failures. For monitor mode, + * we also ignore the CRC error. + */ + if (sc->sc_ah->ah_opmode == ATH9K_M_MONITOR) { + if (ds->ds_rxstat.rs_status & + ~(ATH9K_RXERR_DECRYPT | ATH9K_RXERR_MIC | + ATH9K_RXERR_CRC)) + goto rx_next; + } else { + if (ds->ds_rxstat.rs_status & + ~(ATH9K_RXERR_DECRYPT | ATH9K_RXERR_MIC)) { + goto rx_next; + } + } } - return type; + ratecode = ds->ds_rxstat.rs_rate; + ratekbps = sc->sc_hwmap[ratecode].rateKbps; + + /* HT rate */ + if (ratecode & 0x80) { + if (ds->ds_rxstat.rs_flags & ATH9K_RX_2040) + ratekbps = (ratekbps * 27) / 13; + if (ds->ds_rxstat.rs_flags & ATH9K_RX_GI) + ratekbps = (ratekbps * 10) / 9; + } + + rx_status->mactime = ath_extend_tsf(sc, ds->ds_rxstat.rs_tstamp); + rx_status->band = sc->hw->conf.channel->band; + rx_status->freq = sc->hw->conf.channel->center_freq; + rx_status->noise = sc->sc_ani.sc_noise_floor; + rx_status->signal = rx_status->noise + ds->ds_rxstat.rs_rssi; + rx_status->rate_idx = ath_rate2idx(sc, (ratekbps / 100)); + rx_status->antenna = ds->ds_rxstat.rs_antenna; + + /* at 45 you will be able to use MCS 15 reliably. A more elaborate + * scheme can be used here but it requires tables of SNR/throughput for + * each possible mode used. */ + rx_status->qual = ds->ds_rxstat.rs_rssi * 100 / 45; + + /* rssi can be more than 45 though, anything above that + * should be considered at 100% */ + if (rx_status->qual > 100) + rx_status->qual = 100; + + rx_status->flag |= RX_FLAG_TSFT; + + return 1; +rx_next: + return 0; } static void ath_opmode_init(struct ath_softc *sc) @@ -185,12 +270,6 @@ int ath_rx_init(struct ath_softc *sc, int nbufs) sc->sc_flags &= ~SC_OP_RXFLUSH; spin_lock_init(&sc->sc_rxbuflock); - /* - * Cisco's VPN software requires that drivers be able to - * receive encapsulated frames that are larger than the MTU. - * Since we can't be sure how large a frame we'll get, setup - * to handle the larges on possible. - */ sc->sc_rxbufsize = roundup(IEEE80211_MAX_MPDU_LEN, min(sc->sc_cachelsz, (u16)64)); @@ -209,8 +288,6 @@ int ath_rx_init(struct ath_softc *sc, int nbufs) break; } - /* Pre-allocate a wbuf for each rx buffer */ - list_for_each_entry(bf, &sc->sc_rxbuf, list) { skb = ath_rxbuf_alloc(sc, sc->sc_rxbufsize); if (skb == NULL) { @@ -223,7 +300,6 @@ int ath_rx_init(struct ath_softc *sc, int nbufs) skb_end_pointer(skb) - skb->head, PCI_DMA_FROMDEVICE); bf->bf_dmacontext = bf->bf_buf_addr; - ATH_RX_CONTEXT(skb)->ctx_rxbuf = bf; } sc->sc_rxlink = NULL; @@ -235,8 +311,6 @@ int ath_rx_init(struct ath_softc *sc, int nbufs) return error; } -/* Reclaim all rx queue resources */ - void ath_rx_cleanup(struct ath_softc *sc) { struct sk_buff *skb; @@ -248,8 +322,6 @@ void ath_rx_cleanup(struct ath_softc *sc) dev_kfree_skb(skb); } - /* cleanup rx descriptors */ - if (sc->sc_rxdma.dd_desc_len != 0) ath_descdma_cleanup(sc, &sc->sc_rxdma, &sc->sc_rxbuf); } @@ -297,20 +369,19 @@ u32 ath_calcrxfilter(struct ath_softc *sc) } if (sc->sc_ah->ah_opmode == ATH9K_M_STA || - sc->sc_ah->ah_opmode == ATH9K_M_IBSS) + sc->sc_ah->ah_opmode == ATH9K_M_IBSS) rfilt |= ATH9K_RX_FILTER_BEACON; /* If in HOSTAP mode, want to enable reception of PSPOLL frames & beacon frames */ if (sc->sc_ah->ah_opmode == ATH9K_M_HOSTAP) rfilt |= (ATH9K_RX_FILTER_BEACON | ATH9K_RX_FILTER_PSPOLL); + return rfilt; #undef RX_FILTER_PRESERVE } -/* Enable the receive h/w following a reset. */ - int ath_startrecv(struct ath_softc *sc) { struct ath_hal *ah = sc->sc_ah; @@ -322,21 +393,6 @@ int ath_startrecv(struct ath_softc *sc) sc->sc_rxlink = NULL; list_for_each_entry_safe(bf, tbf, &sc->sc_rxbuf, list) { - if (bf->bf_status & ATH_BUFSTATUS_STALE) { - /* restarting h/w, no need for holding descriptors */ - bf->bf_status &= ~ATH_BUFSTATUS_STALE; - /* - * Upper layer may not be done with the frame yet so - * we can't just re-queue it to hardware. Remove it - * from h/w queue. It'll be re-queued when upper layer - * returns the frame and ath_rx_requeue_mpdu is called. - */ - if (!(bf->bf_status & ATH_BUFSTATUS_FREE)) { - list_del(&bf->list); - continue; - } - } - /* chain descriptors */ ath_rx_buf_link(sc, bf); } @@ -346,120 +402,69 @@ int ath_startrecv(struct ath_softc *sc) bf = list_first_entry(&sc->sc_rxbuf, struct ath_buf, list); ath9k_hw_putrxbuf(ah, bf->bf_daddr); - ath9k_hw_rxena(ah); /* enable recv descriptors */ + ath9k_hw_rxena(ah); start_recv: spin_unlock_bh(&sc->sc_rxbuflock); - ath_opmode_init(sc); /* set filters, etc. */ - ath9k_hw_startpcureceive(ah); /* re-enable PCU/DMA engine */ + ath_opmode_init(sc); + ath9k_hw_startpcureceive(ah); + return 0; } -/* Disable the receive h/w in preparation for a reset. */ - bool ath_stoprecv(struct ath_softc *sc) { struct ath_hal *ah = sc->sc_ah; - u64 tsf; bool stopped; - ath9k_hw_stoppcurecv(ah); /* disable PCU */ - ath9k_hw_setrxfilter(ah, 0); /* clear recv filter */ - stopped = ath9k_hw_stopdmarecv(ah); /* disable DMA engine */ - mdelay(3); /* 3ms is long enough for 1 frame */ - tsf = ath9k_hw_gettsf64(ah); - sc->sc_rxlink = NULL; /* just in case */ + ath9k_hw_stoppcurecv(ah); + ath9k_hw_setrxfilter(ah, 0); + stopped = ath9k_hw_stopdmarecv(ah); + mdelay(3); /* 3ms is long enough for 1 frame */ + sc->sc_rxlink = NULL; + return stopped; } -/* Flush receive queue */ - void ath_flushrecv(struct ath_softc *sc) { - /* - * ath_rx_tasklet may be used to handle rx interrupt and flush receive - * queue at the same time. Use a lock to serialize the access of rx - * queue. - * ath_rx_tasklet cannot hold the spinlock while indicating packets. - * Instead, do not claim the spinlock but check for a flush in - * progress (see references to sc_rxflush) - */ spin_lock_bh(&sc->sc_rxflushlock); sc->sc_flags |= SC_OP_RXFLUSH; - ath_rx_tasklet(sc, 1); - sc->sc_flags &= ~SC_OP_RXFLUSH; spin_unlock_bh(&sc->sc_rxflushlock); } -/* Process receive queue, as well as LED, etc. */ - int ath_rx_tasklet(struct ath_softc *sc, int flush) { #define PA2DESC(_sc, _pa) \ ((struct ath_desc *)((caddr_t)(_sc)->sc_rxdma.dd_desc + \ ((_pa) - (_sc)->sc_rxdma.dd_desc_paddr))) - struct ath_buf *bf, *bf_held = NULL; + struct ath_buf *bf; struct ath_desc *ds; - struct ieee80211_hdr *hdr; struct sk_buff *skb = NULL; - struct ath_recv_status rx_status; + struct ieee80211_rx_status rx_status; struct ath_hal *ah = sc->sc_ah; - int type, rx_processed = 0; - u32 phyerr; - u8 chainreset = 0; - int retval; - __le16 fc; + struct ieee80211_hdr *hdr; + int hdrlen, padsize, retval; + bool decrypt_error = false; + u8 keyix; + + spin_lock_bh(&sc->sc_rxbuflock); do { /* If handling rx interrupt and flush is in progress => exit */ if ((sc->sc_flags & SC_OP_RXFLUSH) && (flush == 0)) break; - spin_lock_bh(&sc->sc_rxbuflock); if (list_empty(&sc->sc_rxbuf)) { sc->sc_rxlink = NULL; - spin_unlock_bh(&sc->sc_rxbuflock); break; } bf = list_first_entry(&sc->sc_rxbuf, struct ath_buf, list); - - /* - * There is a race condition that BH gets scheduled after sw - * writes RxE and before hw re-load the last descriptor to get - * the newly chained one. Software must keep the last DONE - * descriptor as a holding descriptor - software does so by - * marking it with the STALE flag. - */ - if (bf->bf_status & ATH_BUFSTATUS_STALE) { - bf_held = bf; - if (list_is_last(&bf_held->list, &sc->sc_rxbuf)) { - /* - * The holding descriptor is the last - * descriptor in queue. It's safe to - * remove the last holding descriptor - * in BH context. - */ - list_del(&bf_held->list); - bf_held->bf_status &= ~ATH_BUFSTATUS_STALE; - sc->sc_rxlink = NULL; - - if (bf_held->bf_status & ATH_BUFSTATUS_FREE) { - list_add_tail(&bf_held->list, - &sc->sc_rxbuf); - ath_rx_buf_link(sc, bf_held); - } - spin_unlock_bh(&sc->sc_rxbuflock); - break; - } - bf = list_entry(bf->list.next, struct ath_buf, list); - } - ds = bf->bf_desc; - ++rx_processed; /* * Must provide the virtual address of the current @@ -472,8 +477,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush) * on. All this is necessary because of our use of * a self-linked list to avoid rx overruns. */ - retval = ath9k_hw_rxprocdesc(ah, - ds, + retval = ath9k_hw_rxprocdesc(ah, ds, bf->bf_daddr, PA2DESC(sc, ds->ds_link), 0); @@ -482,7 +486,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush) struct ath_desc *tds; if (list_is_last(&bf->list, &sc->sc_rxbuf)) { - spin_unlock_bh(&sc->sc_rxbuflock); + sc->sc_rxlink = NULL; break; } @@ -500,215 +504,70 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush) */ tds = tbf->bf_desc; - retval = ath9k_hw_rxprocdesc(ah, - tds, tbf->bf_daddr, - PA2DESC(sc, tds->ds_link), 0); + retval = ath9k_hw_rxprocdesc(ah, tds, tbf->bf_daddr, + PA2DESC(sc, tds->ds_link), 0); if (retval == -EINPROGRESS) { - spin_unlock_bh(&sc->sc_rxbuflock); break; } } - /* XXX: we do not support frames spanning - * multiple descriptors */ - bf->bf_status |= ATH_BUFSTATUS_DONE; - skb = bf->bf_mpdu; - if (skb == NULL) { /* XXX ??? can this happen */ - spin_unlock_bh(&sc->sc_rxbuflock); + if (!skb) continue; - } - /* - * Now we know it's a completed frame, we can indicate the - * frame. Remove the previous holding descriptor and leave - * this one in the queue as the new holding descriptor. - */ - if (bf_held) { - list_del(&bf_held->list); - bf_held->bf_status &= ~ATH_BUFSTATUS_STALE; - if (bf_held->bf_status & ATH_BUFSTATUS_FREE) { - list_add_tail(&bf_held->list, &sc->sc_rxbuf); - /* try to requeue this descriptor */ - ath_rx_buf_link(sc, bf_held); - } - } - bf->bf_status |= ATH_BUFSTATUS_STALE; - bf_held = bf; /* - * Release the lock here in case ieee80211_input() return - * the frame immediately by calling ath_rx_mpdu_requeue(). + * If we're asked to flush receive queue, directly + * chain it back at the queue without processing it. */ - spin_unlock_bh(&sc->sc_rxbuflock); - - if (flush) { - /* - * If we're asked to flush receive queue, directly - * chain it back at the queue without processing it. - */ + if (flush) goto rx_next; - } - hdr = (struct ieee80211_hdr *)skb->data; - fc = hdr->frame_control; - memset(&rx_status, 0, sizeof(struct ath_recv_status)); - - if (ds->ds_rxstat.rs_more) { - /* - * Frame spans multiple descriptors; this - * cannot happen yet as we don't support - * jumbograms. If not in monitor mode, - * discard the frame. - */ -#ifndef ERROR_FRAMES - /* - * Enable this if you want to see - * error frames in Monitor mode. - */ - if (sc->sc_ah->ah_opmode != ATH9K_M_MONITOR) - goto rx_next; -#endif - /* fall thru for monitor mode handling... */ - } else if (ds->ds_rxstat.rs_status != 0) { - if (ds->ds_rxstat.rs_status & ATH9K_RXERR_CRC) - rx_status.flags |= ATH_RX_FCS_ERROR; - if (ds->ds_rxstat.rs_status & ATH9K_RXERR_PHY) { - phyerr = ds->ds_rxstat.rs_phyerr & 0x1f; - goto rx_next; - } + if (!ds->ds_rxstat.rs_datalen) + goto rx_next; - if (ds->ds_rxstat.rs_status & ATH9K_RXERR_DECRYPT) { - /* - * Decrypt error. We only mark packet status - * here and always push up the frame up to let - * mac80211 handle the actual error case, be - * it no decryption key or real decryption - * error. This let us keep statistics there. - */ - rx_status.flags |= ATH_RX_DECRYPT_ERROR; - } else if (ds->ds_rxstat.rs_status & ATH9K_RXERR_MIC) { - /* - * Demic error. We only mark frame status here - * and always push up the frame up to let - * mac80211 handle the actual error case. This - * let us keep statistics there. Hardware may - * post a false-positive MIC error. - */ - if (ieee80211_is_ctl(fc)) - /* - * Sometimes, we get invalid - * MIC failures on valid control frames. - * Remove these mic errors. - */ - ds->ds_rxstat.rs_status &= - ~ATH9K_RXERR_MIC; - else - rx_status.flags |= ATH_RX_MIC_ERROR; - } - /* - * Reject error frames with the exception of - * decryption and MIC failures. For monitor mode, - * we also ignore the CRC error. - */ - if (sc->sc_ah->ah_opmode == ATH9K_M_MONITOR) { - if (ds->ds_rxstat.rs_status & - ~(ATH9K_RXERR_DECRYPT | ATH9K_RXERR_MIC | - ATH9K_RXERR_CRC)) - goto rx_next; - } else { - if (ds->ds_rxstat.rs_status & - ~(ATH9K_RXERR_DECRYPT | ATH9K_RXERR_MIC)) { - goto rx_next; - } - } - } - /* - * The status portion of the descriptor could get corrupted. - */ + /* The status portion of the descriptor could get corrupted. */ if (sc->sc_rxbufsize < ds->ds_rxstat.rs_datalen) goto rx_next; - /* - * Sync and unmap the frame. At this point we're - * committed to passing the sk_buff somewhere so - * clear buf_skb; this means a new sk_buff must be - * allocated when the rx descriptor is setup again - * to receive another frame. - */ - skb_put(skb, ds->ds_rxstat.rs_datalen); - skb->protocol = cpu_to_be16(ETH_P_CONTROL); - rx_status.tsf = ath_extend_tsf(sc, ds->ds_rxstat.rs_tstamp); - rx_status.rateieee = - sc->sc_hwmap[ds->ds_rxstat.rs_rate].ieeerate; - rx_status.rateKbps = - sc->sc_hwmap[ds->ds_rxstat.rs_rate].rateKbps; - rx_status.ratecode = ds->ds_rxstat.rs_rate; - - /* HT rate */ - if (rx_status.ratecode & 0x80) { - /* TODO - add table to avoid division */ - if (ds->ds_rxstat.rs_flags & ATH9K_RX_2040) { - rx_status.flags |= ATH_RX_40MHZ; - rx_status.rateKbps = - (rx_status.rateKbps * 27) / 13; - } - if (ds->ds_rxstat.rs_flags & ATH9K_RX_GI) - rx_status.rateKbps = - (rx_status.rateKbps * 10) / 9; - else - rx_status.flags |= ATH_RX_SHORT_GI; - } - /* sc_noise_floor is only available when the station - attaches to an AP, so we use a default value - if we are not yet attached. */ - rx_status.abs_rssi = - ds->ds_rxstat.rs_rssi + sc->sc_ani.sc_noise_floor; + if (!ath_rx_prepare(skb, ds, &rx_status, &decrypt_error, sc)) + goto rx_next; - pci_dma_sync_single_for_cpu(sc->pdev, - bf->bf_buf_addr, + /* Sync and unmap the frame */ + pci_dma_sync_single_for_cpu(sc->pdev, bf->bf_buf_addr, skb_tailroom(skb), PCI_DMA_FROMDEVICE); - pci_unmap_single(sc->pdev, - bf->bf_buf_addr, + pci_unmap_single(sc->pdev, bf->bf_buf_addr, sc->sc_rxbufsize, PCI_DMA_FROMDEVICE); - /* XXX: Ah! make me more readable, use a helper */ - if (ah->ah_caps.hw_caps & ATH9K_HW_CAP_HT) { - if (ds->ds_rxstat.rs_moreaggr == 0) { - rx_status.rssictl[0] = - ds->ds_rxstat.rs_rssi_ctl0; - rx_status.rssictl[1] = - ds->ds_rxstat.rs_rssi_ctl1; - rx_status.rssictl[2] = - ds->ds_rxstat.rs_rssi_ctl2; - rx_status.rssi = ds->ds_rxstat.rs_rssi; - if (ds->ds_rxstat.rs_flags & ATH9K_RX_2040) { - rx_status.rssiextn[0] = - ds->ds_rxstat.rs_rssi_ext0; - rx_status.rssiextn[1] = - ds->ds_rxstat.rs_rssi_ext1; - rx_status.rssiextn[2] = - ds->ds_rxstat.rs_rssi_ext2; - rx_status.flags |= - ATH_RX_RSSI_EXTN_VALID; - } - rx_status.flags |= ATH_RX_RSSI_VALID | - ATH_RX_CHAIN_RSSI_VALID; - } - } else { - /* - * Need to insert the "combined" rssi into the - * status structure for upper layer processing - */ - rx_status.rssi = ds->ds_rxstat.rs_rssi; - rx_status.flags |= ATH_RX_RSSI_VALID; + skb_put(skb, ds->ds_rxstat.rs_datalen); + skb->protocol = cpu_to_be16(ETH_P_CONTROL); + + /* see if any padding is done by the hw and remove it */ + hdr = (struct ieee80211_hdr *)skb->data; + hdrlen = ieee80211_get_hdrlen_from_skb(skb); + + if (hdrlen & 3) { + padsize = hdrlen % 4; + memmove(skb->data + padsize, skb->data, hdrlen); + skb_pull(skb, padsize); } - /* Pass frames up to the stack. */ + keyix = ds->ds_rxstat.rs_keyix; - type = ath_rx_indicate(sc, skb, - &rx_status, ds->ds_rxstat.rs_keyix); + if (!(keyix == ATH9K_RXKEYIX_INVALID) && !decrypt_error) { + rx_status.flag |= RX_FLAG_DECRYPTED; + } else if ((le16_to_cpu(hdr->frame_control) & IEEE80211_FCTL_PROTECTED) + && !decrypt_error && skb->len >= hdrlen + 4) { + keyix = skb->data[hdrlen + 3] >> 6; + + if (test_bit(keyix, sc->sc_keymap)) + rx_status.flag |= RX_FLAG_DECRYPTED; + } + + /* Send the frame to mac80211 */ + __ieee80211_rx(sc->hw, skb, &rx_status); + bf->bf_mpdu = NULL; /* * change the default rx antenna if rx diversity chooses the @@ -716,37 +575,15 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush) */ if (sc->sc_defant != ds->ds_rxstat.rs_antenna) { if (++sc->sc_rxotherant >= 3) - ath_setdefantenna(sc, - ds->ds_rxstat.rs_antenna); + ath_setdefantenna(sc, ds->ds_rxstat.rs_antenna); } else { sc->sc_rxotherant = 0; } - -#ifdef CONFIG_SLOW_ANT_DIV - if ((rx_status.flags & ATH_RX_RSSI_VALID) && - ieee80211_is_beacon(fc)) { - ath_slow_ant_div(&sc->sc_antdiv, hdr, &ds->ds_rxstat); - } -#endif - /* - * For frames successfully indicated, the buffer will be - * returned to us by upper layers by calling - * ath_rx_mpdu_requeue, either synchronusly or asynchronously. - * So we don't want to do it here in this loop. - */ - continue; - rx_next: - bf->bf_status |= ATH_BUFSTATUS_FREE; - } while (TRUE); - - if (chainreset) { - DPRINTF(sc, ATH_DBG_CONFIG, - "%s: Reset rx chain mask. " - "Do internal reset\n", __func__); - ASSERT(flush == 0); - ath_reset(sc, false); - } + ath_rx_requeue(sc, bf); + } while (1); + + spin_unlock_bh(&sc->sc_rxbuflock); return 0; #undef PA2DESC -- cgit v1.2.3 From e63835b0f4d8545942fd41b3ca32bbf71bd73e4b Mon Sep 17 00:00:00 2001 From: Sujith Date: Tue, 18 Nov 2008 09:07:53 +0530 Subject: ath9k: Remove ath9k_rate_table Maintaining two sets of rate tables is redundant, remove one and use struct ath_rate_table exclusively. Signed-off-by: Sujith Signed-off-by: John W. Linville --- drivers/net/wireless/ath9k/ath9k.h | 26 +---- drivers/net/wireless/ath9k/beacon.c | 8 +- drivers/net/wireless/ath9k/core.c | 52 ++-------- drivers/net/wireless/ath9k/core.h | 5 - drivers/net/wireless/ath9k/hw.c | 190 +----------------------------------- drivers/net/wireless/ath9k/main.c | 2 + drivers/net/wireless/ath9k/rc.c | 51 ++++++++-- drivers/net/wireless/ath9k/rc.h | 3 + drivers/net/wireless/ath9k/recv.c | 6 +- drivers/net/wireless/ath9k/xmit.c | 163 +++++++++++-------------------- 10 files changed, 132 insertions(+), 374 deletions(-) (limited to 'drivers/net/wireless/ath9k/recv.c') diff --git a/drivers/net/wireless/ath9k/ath9k.h b/drivers/net/wireless/ath9k/ath9k.h index 6be2b947307c..c4012c88d82b 100644 --- a/drivers/net/wireless/ath9k/ath9k.h +++ b/drivers/net/wireless/ath9k/ath9k.h @@ -401,22 +401,6 @@ enum ath9k_int { ATH9K_INT_NOCARD = 0xffffffff }; -struct ath9k_rate_table { - int rateCount; - u8 rateCodeToIndex[256]; - struct { - u8 valid; - u8 phy; - u32 rateKbps; - u8 rateCode; - u8 shortPreamble; - u8 dot11Rate; - u8 controlRate; - u16 lpAckDuration; - u16 spAckDuration; - } info[32]; -}; - #define ATH9K_RATESERIES_RTS_CTS 0x0001 #define ATH9K_RATESERIES_2040 0x0002 #define ATH9K_RATESERIES_HALFGI 0x0004 @@ -828,6 +812,8 @@ struct chan_centers { u16 ext_center; }; +struct ath_rate_table; + /* Helpers */ enum wireless_mode ath9k_hw_chan2wmode(struct ath_hal *ah, @@ -838,7 +824,7 @@ bool ath9k_get_channel_edges(struct ath_hal *ah, u16 flags, u16 *low, u16 *high); u16 ath9k_hw_computetxtime(struct ath_hal *ah, - const struct ath9k_rate_table *rates, + struct ath_rate_table *rates, u32 frameLen, u16 rateix, bool shortPreamble); u32 ath9k_hw_mhz2ieee(struct ath_hal *ah, u32 freq, u32 flags); @@ -883,12 +869,6 @@ void ath9k_hw_configpcipowersave(struct ath_hal *ah, int restore); void ath9k_hw_beaconinit(struct ath_hal *ah, u32 next_beacon, u32 beacon_period); void ath9k_hw_set_sta_beacon_timers(struct ath_hal *ah, const struct ath9k_beacon_state *bs); - -/* Rate table */ - -const struct ath9k_rate_table *ath9k_hw_getratetable(struct ath_hal *ah, - u32 mode); - /* HW Capabilities */ bool ath9k_hw_fill_cap_info(struct ath_hal *ah); diff --git a/drivers/net/wireless/ath9k/beacon.c b/drivers/net/wireless/ath9k/beacon.c index d186cd41c235..dcf23834194c 100644 --- a/drivers/net/wireless/ath9k/beacon.c +++ b/drivers/net/wireless/ath9k/beacon.c @@ -68,7 +68,7 @@ static void ath_beacon_setup(struct ath_softc *sc, struct ath_hal *ah = sc->sc_ah; struct ath_desc *ds; struct ath9k_11n_rate_series series[4]; - const struct ath9k_rate_table *rt; + struct ath_rate_table *rt; int flags, antenna; u8 rix, rate; int ctsrate = 0; @@ -106,10 +106,10 @@ static void ath_beacon_setup(struct ath_softc *sc, * XXX everything at min xmit rate */ rix = 0; - rt = sc->sc_currates; - rate = rt->info[rix].rateCode; + rt = sc->hw_rate_table[sc->sc_curmode]; + rate = rt->info[rix].ratecode; if (sc->sc_flags & SC_OP_PREAMBLE_SHORT) - rate |= rt->info[rix].shortPreamble; + rate |= rt->info[rix].short_preamble; ath9k_hw_set11n_txdesc(ah, ds, skb->len + FCS_LEN, /* frame length */ diff --git a/drivers/net/wireless/ath9k/core.c b/drivers/net/wireless/ath9k/core.c index 6c872e704b93..fb6a013f3f31 100644 --- a/drivers/net/wireless/ath9k/core.c +++ b/drivers/net/wireless/ath9k/core.c @@ -80,38 +80,9 @@ static u8 parse_mpdudensity(u8 mpdudensity) /* * Set current operating mode - * - * This function initializes and fills the rate table in the ATH object based - * on the operating mode. */ static void ath_setcurmode(struct ath_softc *sc, enum wireless_mode mode) { - const struct ath9k_rate_table *rt; - int i; - - rt = ath9k_hw_getratetable(sc->sc_ah, mode); - BUG_ON(!rt); - - memset(sc->sc_hwmap, 0, sizeof(sc->sc_hwmap)); - for (i = 0; i < 256; i++) { - u8 ix = rt->rateCodeToIndex[i]; - - if (ix == 0xff) - continue; - - sc->sc_hwmap[i].ieeerate = - rt->info[ix].dot11Rate & IEEE80211_RATE_VAL; - sc->sc_hwmap[i].rateKbps = rt->info[ix].rateKbps; - - if (rt->info[ix].shortPreamble || - rt->info[ix].phy == PHY_OFDM) { - /* XXX: Handle this */ - } - - /* NB: this uses the last entry if the rate isn't found */ - /* XXX beware of overlow */ - } - sc->sc_currates = rt; sc->sc_curmode = mode; /* * All protection frames are transmited at 2Mb/s for @@ -126,37 +97,36 @@ static void ath_setcurmode(struct ath_softc *sc, enum wireless_mode mode) */ static void ath_setup_rates(struct ath_softc *sc, enum ieee80211_band band) { - struct ath_hal *ah = sc->sc_ah; - const struct ath9k_rate_table *rt = NULL; + struct ath_rate_table *rate_table = NULL; struct ieee80211_supported_band *sband; struct ieee80211_rate *rate; int i, maxrates; switch (band) { case IEEE80211_BAND_2GHZ: - rt = ath9k_hw_getratetable(ah, ATH9K_MODE_11G); + rate_table = sc->hw_rate_table[ATH9K_MODE_11G]; break; case IEEE80211_BAND_5GHZ: - rt = ath9k_hw_getratetable(ah, ATH9K_MODE_11A); + rate_table = sc->hw_rate_table[ATH9K_MODE_11A]; break; default: break; } - if (rt == NULL) + if (rate_table == NULL) return; sband = &sc->sbands[band]; rate = sc->rates[band]; - if (rt->rateCount > ATH_RATE_MAX) + if (rate_table->rate_cnt > ATH_RATE_MAX) maxrates = ATH_RATE_MAX; else - maxrates = rt->rateCount; + maxrates = rate_table->rate_cnt; for (i = 0; i < maxrates; i++) { - rate[i].bitrate = rt->info[i].rateKbps / 100; - rate[i].hw_value = rt->info[i].rateCode; + rate[i].bitrate = rate_table->info[i].ratekbps / 100; + rate[i].hw_value = rate_table->info[i].ratecode; sband->n_bitrates++; DPRINTF(sc, ATH_DBG_CONFIG, "%s: Rate: %2dMbps, ratecode: %2d\n", @@ -1000,12 +970,10 @@ int ath_init(u16 devid, struct ath_softc *sc) /* Setup rate tables */ + ath_rate_attach(sc); ath_setup_rates(sc, IEEE80211_BAND_2GHZ); ath_setup_rates(sc, IEEE80211_BAND_5GHZ); - /* NB: setup here so ath_rate_update is happy */ - ath_setcurmode(sc, ATH9K_MODE_11A); - /* * Allocate hardware transmit queues: one queue for * beacon frames and one data queue for each QoS @@ -1071,8 +1039,6 @@ int ath_init(u16 devid, struct ath_softc *sc) sc->sc_ani.sc_noise_floor = ATH_DEFAULT_NOISE_FLOOR; setup_timer(&sc->sc_ani.timer, ath_ani_calibrate, (unsigned long)sc); - ath_rate_attach(sc); - if (ath9k_hw_getcapability(ah, ATH9K_CAP_CIPHER, ATH9K_CIPHER_TKIP, NULL)) { /* diff --git a/drivers/net/wireless/ath9k/core.h b/drivers/net/wireless/ath9k/core.h index 255f860b2719..0c348209f39c 100644 --- a/drivers/net/wireless/ath9k/core.h +++ b/drivers/net/wireless/ath9k/core.h @@ -858,12 +858,7 @@ struct ath_softc { /* Rate */ struct ieee80211_rate rates[IEEE80211_NUM_BANDS][ATH_RATE_MAX]; struct ath_rate_table *hw_rate_table[ATH9K_MODE_MAX]; - const struct ath9k_rate_table *sc_currates; u8 sc_protrix; /* protection rate index */ - struct { - u32 rateKbps; /* transfer rate in kbs */ - u8 ieeerate; /* IEEE rate */ - } sc_hwmap[256]; /* h/w rate ix mappings */ /* Channel, Band */ struct ieee80211_channel channels[IEEE80211_NUM_BANDS][ATH_CHAN_MAX]; diff --git a/drivers/net/wireless/ath9k/hw.c b/drivers/net/wireless/ath9k/hw.c index 82c2a4259ce4..a26867c56a82 100644 --- a/drivers/net/wireless/ath9k/hw.c +++ b/drivers/net/wireless/ath9k/hw.c @@ -142,14 +142,14 @@ bool ath9k_get_channel_edges(struct ath_hal *ah, } u16 ath9k_hw_computetxtime(struct ath_hal *ah, - const struct ath9k_rate_table *rates, + struct ath_rate_table *rates, u32 frameLen, u16 rateix, bool shortPreamble) { u32 bitsPerSymbol, numBits, numSymbols, phyTime, txTime; u32 kbps; - kbps = rates->info[rateix].rateKbps; + kbps = rates->info[rateix].ratekbps; if (kbps == 0) return 0; @@ -157,7 +157,7 @@ u16 ath9k_hw_computetxtime(struct ath_hal *ah, switch (rates->info[rateix].phy) { case PHY_CCK: phyTime = CCK_PREAMBLE_BITS + CCK_PLCP_BITS; - if (shortPreamble && rates->info[rateix].shortPreamble) + if (shortPreamble && rates->info[rateix].short_preamble) phyTime >>= 1; numBits = frameLen << 3; txTime = CCK_SIFS_TIME + phyTime + ((numBits * 1000) / kbps); @@ -3190,190 +3190,6 @@ void ath9k_hw_set_sta_beacon_timers(struct ath_hal *ah, } -/***************/ -/* Rate tables */ -/***************/ - -static struct ath9k_rate_table ar5416_11a_table = { - 8, - {0}, - { - {true, PHY_OFDM, 6000, 0x0b, 0x00, (0x80 | 12), 0}, - {true, PHY_OFDM, 9000, 0x0f, 0x00, 18, 0}, - {true, PHY_OFDM, 12000, 0x0a, 0x00, (0x80 | 24), 2}, - {true, PHY_OFDM, 18000, 0x0e, 0x00, 36, 2}, - {true, PHY_OFDM, 24000, 0x09, 0x00, (0x80 | 48), 4}, - {true, PHY_OFDM, 36000, 0x0d, 0x00, 72, 4}, - {true, PHY_OFDM, 48000, 0x08, 0x00, 96, 4}, - {true, PHY_OFDM, 54000, 0x0c, 0x00, 108, 4} - }, -}; - -static struct ath9k_rate_table ar5416_11b_table = { - 4, - {0}, - { - {true, PHY_CCK, 1000, 0x1b, 0x00, (0x80 | 2), 0}, - {true, PHY_CCK, 2000, 0x1a, 0x04, (0x80 | 4), 1}, - {true, PHY_CCK, 5500, 0x19, 0x04, (0x80 | 11), 1}, - {true, PHY_CCK, 11000, 0x18, 0x04, (0x80 | 22), 1} - }, -}; - -static struct ath9k_rate_table ar5416_11g_table = { - 12, - {0}, - { - {true, PHY_CCK, 1000, 0x1b, 0x00, (0x80 | 2), 0}, - {true, PHY_CCK, 2000, 0x1a, 0x04, (0x80 | 4), 1}, - {true, PHY_CCK, 5500, 0x19, 0x04, (0x80 | 11), 2}, - {true, PHY_CCK, 11000, 0x18, 0x04, (0x80 | 22), 3}, - - {false, PHY_OFDM, 6000, 0x0b, 0x00, 12, 4}, - {false, PHY_OFDM, 9000, 0x0f, 0x00, 18, 4}, - {true, PHY_OFDM, 12000, 0x0a, 0x00, 24, 6}, - {true, PHY_OFDM, 18000, 0x0e, 0x00, 36, 6}, - {true, PHY_OFDM, 24000, 0x09, 0x00, 48, 8}, - {true, PHY_OFDM, 36000, 0x0d, 0x00, 72, 8}, - {true, PHY_OFDM, 48000, 0x08, 0x00, 96, 8}, - {true, PHY_OFDM, 54000, 0x0c, 0x00, 108, 8} - }, -}; - -static struct ath9k_rate_table ar5416_11ng_table = { - 28, - {0}, - { - {true, PHY_CCK, 1000, 0x1b, 0x00, (0x80 | 2), 0}, - {true, PHY_CCK, 2000, 0x1a, 0x04, (0x80 | 4), 1}, - {true, PHY_CCK, 5500, 0x19, 0x04, (0x80 | 11), 2}, - {true, PHY_CCK, 11000, 0x18, 0x04, (0x80 | 22), 3}, - - {false, PHY_OFDM, 6000, 0x0b, 0x00, 12, 4}, - {false, PHY_OFDM, 9000, 0x0f, 0x00, 18, 4}, - {true, PHY_OFDM, 12000, 0x0a, 0x00, 24, 6}, - {true, PHY_OFDM, 18000, 0x0e, 0x00, 36, 6}, - {true, PHY_OFDM, 24000, 0x09, 0x00, 48, 8}, - {true, PHY_OFDM, 36000, 0x0d, 0x00, 72, 8}, - {true, PHY_OFDM, 48000, 0x08, 0x00, 96, 8}, - {true, PHY_OFDM, 54000, 0x0c, 0x00, 108, 8}, - {true, PHY_HT, 6500, 0x80, 0x00, 0, 4}, - {true, PHY_HT, 13000, 0x81, 0x00, 1, 6}, - {true, PHY_HT, 19500, 0x82, 0x00, 2, 6}, - {true, PHY_HT, 26000, 0x83, 0x00, 3, 8}, - {true, PHY_HT, 39000, 0x84, 0x00, 4, 8}, - {true, PHY_HT, 52000, 0x85, 0x00, 5, 8}, - {true, PHY_HT, 58500, 0x86, 0x00, 6, 8}, - {true, PHY_HT, 65000, 0x87, 0x00, 7, 8}, - {true, PHY_HT, 13000, 0x88, 0x00, 8, 4}, - {true, PHY_HT, 26000, 0x89, 0x00, 9, 6}, - {true, PHY_HT, 39000, 0x8a, 0x00, 10, 6}, - {true, PHY_HT, 52000, 0x8b, 0x00, 11, 8}, - {true, PHY_HT, 78000, 0x8c, 0x00, 12, 8}, - {true, PHY_HT, 104000, 0x8d, 0x00, 13, 8}, - {true, PHY_HT, 117000, 0x8e, 0x00, 14, 8}, - {true, PHY_HT, 130000, 0x8f, 0x00, 15, 8}, - }, -}; - -static struct ath9k_rate_table ar5416_11na_table = { - 24, - {0}, - { - {true, PHY_OFDM, 6000, 0x0b, 0x00, (0x80 | 12), 0}, - {true, PHY_OFDM, 9000, 0x0f, 0x00, 18, 0}, - {true, PHY_OFDM, 12000, 0x0a, 0x00, (0x80 | 24), 2}, - {true, PHY_OFDM, 18000, 0x0e, 0x00, 36, 2}, - {true, PHY_OFDM, 24000, 0x09, 0x00, (0x80 | 48), 4}, - {true, PHY_OFDM, 36000, 0x0d, 0x00, 72, 4}, - {true, PHY_OFDM, 48000, 0x08, 0x00, 96, 4}, - {true, PHY_OFDM, 54000, 0x0c, 0x00, 108, 4}, - {true, PHY_HT, 6500, 0x80, 0x00, 0, 0}, - {true, PHY_HT, 13000, 0x81, 0x00, 1, 2}, - {true, PHY_HT, 19500, 0x82, 0x00, 2, 2}, - {true, PHY_HT, 26000, 0x83, 0x00, 3, 4}, - {true, PHY_HT, 39000, 0x84, 0x00, 4, 4}, - {true, PHY_HT, 52000, 0x85, 0x00, 5, 4}, - {true, PHY_HT, 58500, 0x86, 0x00, 6, 4}, - {true, PHY_HT, 65000, 0x87, 0x00, 7, 4}, - {true, PHY_HT, 13000, 0x88, 0x00, 8, 0}, - {true, PHY_HT, 26000, 0x89, 0x00, 9, 2}, - {true, PHY_HT, 39000, 0x8a, 0x00, 10, 2}, - {true, PHY_HT, 52000, 0x8b, 0x00, 11, 4}, - {true, PHY_HT, 78000, 0x8c, 0x00, 12, 4}, - {true, PHY_HT, 104000, 0x8d, 0x00, 13, 4}, - {true, PHY_HT, 117000, 0x8e, 0x00, 14, 4}, - {true, PHY_HT, 130000, 0x8f, 0x00, 15, 4}, - }, -}; - -static void ath9k_hw_setup_rate_table(struct ath_hal *ah, - struct ath9k_rate_table *rt) -{ - int i; - - if (rt->rateCodeToIndex[0] != 0) - return; - - for (i = 0; i < 256; i++) - rt->rateCodeToIndex[i] = (u8) -1; - - for (i = 0; i < rt->rateCount; i++) { - u8 code = rt->info[i].rateCode; - u8 cix = rt->info[i].controlRate; - - rt->rateCodeToIndex[code] = i; - rt->rateCodeToIndex[code | rt->info[i].shortPreamble] = i; - - rt->info[i].lpAckDuration = - ath9k_hw_computetxtime(ah, rt, - WLAN_CTRL_FRAME_SIZE, - cix, - false); - rt->info[i].spAckDuration = - ath9k_hw_computetxtime(ah, rt, - WLAN_CTRL_FRAME_SIZE, - cix, - true); - } -} - -const struct ath9k_rate_table *ath9k_hw_getratetable(struct ath_hal *ah, - u32 mode) -{ - struct ath9k_rate_table *rt; - - switch (mode) { - case ATH9K_MODE_11A: - rt = &ar5416_11a_table; - break; - case ATH9K_MODE_11B: - rt = &ar5416_11b_table; - break; - case ATH9K_MODE_11G: - rt = &ar5416_11g_table; - break; - case ATH9K_MODE_11NG_HT20: - case ATH9K_MODE_11NG_HT40PLUS: - case ATH9K_MODE_11NG_HT40MINUS: - rt = &ar5416_11ng_table; - break; - case ATH9K_MODE_11NA_HT20: - case ATH9K_MODE_11NA_HT40PLUS: - case ATH9K_MODE_11NA_HT40MINUS: - rt = &ar5416_11na_table; - break; - default: - DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL, "%s: invalid mode 0x%x\n", - __func__, mode); - return NULL; - } - - ath9k_hw_setup_rate_table(ah, rt); - - return rt; -} - /*******************/ /* HW Capabilities */ /*******************/ diff --git a/drivers/net/wireless/ath9k/main.c b/drivers/net/wireless/ath9k/main.c index 11d7bee2fda0..e86bcd284148 100644 --- a/drivers/net/wireless/ath9k/main.c +++ b/drivers/net/wireless/ath9k/main.c @@ -780,6 +780,8 @@ static int ath_attach(u16 devid, struct ath_softc *sc) BIT(NL80211_IFTYPE_ADHOC); hw->queues = 4; + hw->max_rates = 4; + hw->max_rate_tries = ATH_11N_TXMAXTRY; hw->sta_data_size = sizeof(struct ath_node); hw->vif_data_size = sizeof(struct ath_vap); diff --git a/drivers/net/wireless/ath9k/rc.c b/drivers/net/wireless/ath9k/rc.c index 156b245ab9e4..bf637aa7ddab 100644 --- a/drivers/net/wireless/ath9k/rc.c +++ b/drivers/net/wireless/ath9k/rc.c @@ -25,6 +25,7 @@ static struct ath_rate_table ar5416_11na_ratetable = { 42, + {0}, { { TRUE, TRUE, WLAN_PHY_OFDM, 6000, /* 6 Mb */ 5400, 0x0b, 0x00, 12, @@ -168,6 +169,7 @@ static struct ath_rate_table ar5416_11na_ratetable = { static struct ath_rate_table ar5416_11ng_ratetable = { 46, + {0}, { { TRUE_ALL, TRUE_ALL, WLAN_PHY_CCK, 1000, /* 1 Mb */ 900, 0x1b, 0x00, 2, @@ -315,6 +317,7 @@ static struct ath_rate_table ar5416_11ng_ratetable = { static struct ath_rate_table ar5416_11a_ratetable = { 8, + {0}, { { TRUE, TRUE, WLAN_PHY_OFDM, 6000, /* 6 Mb */ 5400, 0x0b, 0x00, (0x80|12), @@ -348,6 +351,7 @@ static struct ath_rate_table ar5416_11a_ratetable = { static struct ath_rate_table ar5416_11g_ratetable = { 12, + {0}, { { TRUE, TRUE, WLAN_PHY_CCK, 1000, /* 1 Mb */ 900, 0x1b, 0x00, 2, @@ -393,6 +397,7 @@ static struct ath_rate_table ar5416_11g_ratetable = { static struct ath_rate_table ar5416_11b_ratetable = { 4, + {0}, { { TRUE, TRUE, WLAN_PHY_CCK, 1000, /* 1 Mb */ 900, 0x1b, 0x00, (0x80|2), @@ -1302,14 +1307,14 @@ static void ath_rc_update(struct ath_softc *sc, if (final_ts_idx != 0) { /* Process intermediate rates that failed.*/ for (series = 0; series < final_ts_idx ; series++) { - if (rates[series].count != 0) { + if (rates[series].count != 0 && (rates[series].idx >= 0)) { flags = rates[series].flags; /* If HT40 and we have switched mode from * 40 to 20 => don't update */ if ((flags & IEEE80211_TX_RC_40_MHZ_WIDTH) && - (ath_rc_priv->rc_phy_mode != - (flags & IEEE80211_TX_RC_40_MHZ_WIDTH))) + (ath_rc_priv->rc_phy_mode != WLAN_RC_40_FLAG)) return; + if ((flags & IEEE80211_TX_RC_40_MHZ_WIDTH) && (flags & IEEE80211_TX_RC_SHORT_GI)) rix = rate_table->info[ @@ -1343,8 +1348,9 @@ static void ath_rc_update(struct ath_softc *sc, flags = rates[series].flags; /* If HT40 and we have switched mode from 40 to 20 => don't update */ if ((flags & IEEE80211_TX_RC_40_MHZ_WIDTH) && - (ath_rc_priv->rc_phy_mode != (flags & IEEE80211_TX_RC_40_MHZ_WIDTH))) + (ath_rc_priv->rc_phy_mode != WLAN_RC_40_FLAG)) { return; + } if ((flags & IEEE80211_TX_RC_40_MHZ_WIDTH) && (flags & IEEE80211_TX_RC_SHORT_GI)) rix = rate_table->info[rates[series].idx].ht_index; @@ -1628,7 +1634,6 @@ static void ath_rate_free_sta(void *priv, struct ieee80211_sta *sta, void *priv_sta) { struct ath_rate_node *rate_priv = priv_sta; - kfree(rate_priv); } @@ -1644,6 +1649,35 @@ static struct rate_control_ops ath_rate_ops = { .free_sta = ath_rate_free_sta, }; +static void ath_setup_rate_table(struct ath_softc *sc, + struct ath_rate_table *rate_table) +{ + int i; + + for (i = 0; i < 256; i++) + rate_table->rateCodeToIndex[i] = (u8)-1; + + for (i = 0; i < rate_table->rate_cnt; i++) { + u8 code = rate_table->info[i].ratecode; + u8 cix = rate_table->info[i].ctrl_rate; + u8 sh = rate_table->info[i].short_preamble; + + rate_table->rateCodeToIndex[code] = i; + rate_table->rateCodeToIndex[code | sh] = i; + + rate_table->info[i].lpAckDuration = + ath9k_hw_computetxtime(sc->sc_ah, rate_table, + WLAN_CTRL_FRAME_SIZE, + cix, + false); + rate_table->info[i].spAckDuration = + ath9k_hw_computetxtime(sc->sc_ah, rate_table, + WLAN_CTRL_FRAME_SIZE, + cix, + true); + } +} + void ath_rate_attach(struct ath_softc *sc) { sc->hw_rate_table[ATH9K_MODE_11B] = @@ -1664,6 +1698,12 @@ void ath_rate_attach(struct ath_softc *sc) &ar5416_11ng_ratetable; sc->hw_rate_table[ATH9K_MODE_11NG_HT40MINUS] = &ar5416_11ng_ratetable; + + ath_setup_rate_table(sc, &ar5416_11b_ratetable); + ath_setup_rate_table(sc, &ar5416_11a_ratetable); + ath_setup_rate_table(sc, &ar5416_11g_ratetable); + ath_setup_rate_table(sc, &ar5416_11na_ratetable); + ath_setup_rate_table(sc, &ar5416_11ng_ratetable); } int ath_rate_control_register(void) @@ -1675,4 +1715,3 @@ void ath_rate_control_unregister(void) { ieee80211_rate_control_unregister(&ath_rate_ops); } - diff --git a/drivers/net/wireless/ath9k/rc.h b/drivers/net/wireless/ath9k/rc.h index 3324bed3f0ac..c1e370c7c681 100644 --- a/drivers/net/wireless/ath9k/rc.h +++ b/drivers/net/wireless/ath9k/rc.h @@ -143,6 +143,7 @@ enum { */ struct ath_rate_table { int rate_cnt; + u8 rateCodeToIndex[256]; struct { int valid; int valid_single_stream; @@ -160,6 +161,8 @@ struct ath_rate_table { u8 sgi_index; u8 ht_index; u32 max_4ms_framelen; + u16 lpAckDuration; + u16 spAckDuration; } info[RATE_TABLE_SIZE]; u32 probe_interval; u32 rssi_reduce_interval; diff --git a/drivers/net/wireless/ath9k/recv.c b/drivers/net/wireless/ath9k/recv.c index 000e189e104a..20f83779278a 100644 --- a/drivers/net/wireless/ath9k/recv.c +++ b/drivers/net/wireless/ath9k/recv.c @@ -140,8 +140,9 @@ static int ath_rx_prepare(struct sk_buff *skb, struct ath_desc *ds, struct ieee80211_rx_status *rx_status, bool *decrypt_error, struct ath_softc *sc) { + struct ath_rate_table *rate_table = sc->hw_rate_table[sc->sc_curmode]; struct ieee80211_hdr *hdr; - int ratekbps; + int ratekbps, rix; u8 ratecode; __le16 fc; @@ -196,7 +197,8 @@ static int ath_rx_prepare(struct sk_buff *skb, struct ath_desc *ds, } ratecode = ds->ds_rxstat.rs_rate; - ratekbps = sc->sc_hwmap[ratecode].rateKbps; + rix = rate_table->rateCodeToIndex[ratecode]; + ratekbps = rate_table->info[rix].ratekbps; /* HT rate */ if (ratecode & 0x80) { diff --git a/drivers/net/wireless/ath9k/xmit.c b/drivers/net/wireless/ath9k/xmit.c index baf5cb9d967e..b2d0cca6f4a6 100644 --- a/drivers/net/wireless/ath9k/xmit.c +++ b/drivers/net/wireless/ath9k/xmit.c @@ -176,25 +176,6 @@ static int get_hw_crypto_keytype(struct sk_buff *skb) return ATH9K_KEY_TYPE_CLEAR; } -static void setup_rate_retries(struct ath_softc *sc, struct sk_buff *skb) -{ - struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); - struct ieee80211_tx_rate *rates = tx_info->control.rates; - struct ieee80211_hdr *hdr; - __le16 fc; - - hdr = (struct ieee80211_hdr *)skb->data; - fc = hdr->frame_control; - - if (ieee80211_has_morefrags(fc) || - (le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG)) { - rates[1].count = rates[2].count = rates[3].count = 0; - rates[1].idx = rates[2].idx = rates[3].idx = 0; - /* reset tries but keep rate index */ - rates[0].count = ATH_TXMAXTRY; - } -} - /* Called only when tx aggregation is enabled and HT is supported */ static void assign_aggr_tid_seqno(struct sk_buff *skb, @@ -468,27 +449,23 @@ static void ath_tx_update_baw(struct ath_softc *sc, struct ath_atx_tid *tid, * width - 0 for 20 MHz, 1 for 40 MHz * half_gi - to use 4us v/s 3.6 us for symbol time */ - static u32 ath_pkt_duration(struct ath_softc *sc, u8 rix, struct ath_buf *bf, int width, int half_gi, bool shortPreamble) { - const struct ath9k_rate_table *rt = sc->sc_currates; + struct ath_rate_table *rate_table = sc->hw_rate_table[sc->sc_curmode]; u32 nbits, nsymbits, duration, nsymbols; u8 rc; int streams, pktlen; pktlen = bf_isaggr(bf) ? bf->bf_al : bf->bf_frmlen; - rc = rt->info[rix].rateCode; + rc = rate_table->info[rix].ratecode; - /* - * for legacy rates, use old function to compute packet duration - */ + /* for legacy rates, use old function to compute packet duration */ if (!IS_HT_RATE(rc)) - return ath9k_hw_computetxtime(sc->sc_ah, rt, pktlen, rix, - shortPreamble); - /* - * find number of symbols: PLCP + data - */ + return ath9k_hw_computetxtime(sc->sc_ah, rate_table, pktlen, + rix, shortPreamble); + + /* find number of symbols: PLCP + data */ nbits = (pktlen << 3) + OFDM_PLCP_BITS; nsymbits = bits_per_symbol[HT_RC_2_MCS(rc)][width]; nsymbols = (nbits + nsymbits - 1) / nsymbits; @@ -498,9 +475,7 @@ static u32 ath_pkt_duration(struct ath_softc *sc, u8 rix, struct ath_buf *bf, else duration = SYMBOL_TIME_HALFGI(nsymbols); - /* - * addup duration for legacy/ht training and signal fields - */ + /* addup duration for legacy/ht training and signal fields */ streams = HT_RC_2_STREAMS(rc); duration += L_STF + L_LTF + L_SIG + HT_SIG + HT_STF + HT_LTF(streams); @@ -512,114 +487,104 @@ static u32 ath_pkt_duration(struct ath_softc *sc, u8 rix, struct ath_buf *bf, static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf) { struct ath_hal *ah = sc->sc_ah; - const struct ath9k_rate_table *rt; + struct ath_rate_table *rt; struct ath_desc *ds = bf->bf_desc; struct ath_desc *lastds = bf->bf_lastbf->bf_desc; struct ath9k_11n_rate_series series[4]; - int i, flags, rtsctsena = 0; - u32 ctsduration = 0; - u8 rix = 0, cix, ctsrate = 0; struct ath_node *an = NULL; struct sk_buff *skb; struct ieee80211_tx_info *tx_info; struct ieee80211_tx_rate *rates; + struct ieee80211_hdr *hdr; + int i, flags, rtsctsena = 0; + u32 ctsduration = 0; + u8 rix = 0, cix, ctsrate = 0; + __le16 fc; + + memset(series, 0, sizeof(struct ath9k_11n_rate_series) * 4); skb = (struct sk_buff *)bf->bf_mpdu; + hdr = (struct ieee80211_hdr *)skb->data; + fc = hdr->frame_control; tx_info = IEEE80211_SKB_CB(skb); - rates = tx_info->rate_driver_data[0]; + rates = tx_info->control.rates; if (tx_info->control.sta) an = (struct ath_node *)tx_info->control.sta->drv_priv; - /* - * get the cix for the lowest valid rix. - */ - rt = sc->sc_currates; + if (ieee80211_has_morefrags(fc) || + (le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG)) { + rates[1].count = rates[2].count = rates[3].count = 0; + rates[1].idx = rates[2].idx = rates[3].idx = 0; + rates[0].count = ATH_TXMAXTRY; + } + + /* get the cix for the lowest valid rix */ + rt = sc->hw_rate_table[sc->sc_curmode]; for (i = 3; i >= 0; i--) { - if (rates[i].count) { + if (rates[i].count && (rates[i].idx >= 0)) { rix = rates[i].idx; break; } } + flags = (bf->bf_flags & (ATH9K_TXDESC_RTSENA | ATH9K_TXDESC_CTSENA)); - cix = rt->info[rix].controlRate; + cix = rt->info[rix].ctrl_rate; /* - * If 802.11g protection is enabled, determine whether - * to use RTS/CTS or just CTS. Note that this is only - * done for OFDM/HT unicast frames. + * If 802.11g protection is enabled, determine whether to use RTS/CTS or + * just CTS. Note that this is only done for OFDM/HT unicast frames. */ - if (sc->sc_protmode != PROT_M_NONE && - (rt->info[rix].phy == PHY_OFDM || - rt->info[rix].phy == PHY_HT) && - (bf->bf_flags & ATH9K_TXDESC_NOACK) == 0) { + if (sc->sc_protmode != PROT_M_NONE && !(bf->bf_flags & ATH9K_TXDESC_NOACK) + && (rt->info[rix].phy == WLAN_PHY_OFDM || + WLAN_RC_PHY_HT(rt->info[rix].phy))) { if (sc->sc_protmode == PROT_M_RTSCTS) flags = ATH9K_TXDESC_RTSENA; else if (sc->sc_protmode == PROT_M_CTSONLY) flags = ATH9K_TXDESC_CTSENA; - cix = rt->info[sc->sc_protrix].controlRate; + cix = rt->info[sc->sc_protrix].ctrl_rate; rtsctsena = 1; } - /* For 11n, the default behavior is to enable RTS for - * hw retried frames. We enable the global flag here and - * let rate series flags determine which rates will actually - * use RTS. + /* For 11n, the default behavior is to enable RTS for hw retried frames. + * We enable the global flag here and let rate series flags determine + * which rates will actually use RTS. */ if ((ah->ah_caps.hw_caps & ATH9K_HW_CAP_HT) && bf_isdata(bf)) { - /* - * 802.11g protection not needed, use our default behavior - */ + /* 802.11g protection not needed, use our default behavior */ if (!rtsctsena) flags = ATH9K_TXDESC_RTSENA; } - /* - * Set protection if aggregate protection on - */ + /* Set protection if aggregate protection on */ if (sc->sc_config.ath_aggr_prot && (!bf_isaggr(bf) || (bf_isaggr(bf) && bf->bf_al < 8192))) { flags = ATH9K_TXDESC_RTSENA; - cix = rt->info[sc->sc_protrix].controlRate; + cix = rt->info[sc->sc_protrix].ctrl_rate; rtsctsena = 1; } - /* - * For AR5416 - RTS cannot be followed by a frame larger than 8K. - */ - if (bf_isaggr(bf) && (bf->bf_al > ah->ah_caps.rts_aggr_limit)) { - /* - * Ensure that in the case of SM Dynamic power save - * while we are bursting the second aggregate the - * RTS is cleared. - */ + /* For AR5416 - RTS cannot be followed by a frame larger than 8K */ + if (bf_isaggr(bf) && (bf->bf_al > ah->ah_caps.rts_aggr_limit)) flags &= ~(ATH9K_TXDESC_RTSENA); - } - - /* - * CTS transmit rate is derived from the transmit rate - * by looking in the h/w rate table. We must also factor - * in whether or not a short preamble is to be used. - * NB: cix is set above where RTS/CTS is enabled - */ - BUG_ON(cix == 0xff); - ctsrate = rt->info[cix].rateCode | - (bf_isshpreamble(bf) ? rt->info[cix].shortPreamble : 0); /* - * Setup HAL rate series + * CTS transmit rate is derived from the transmit rate by looking in the + * h/w rate table. We must also factor in whether or not a short + * preamble is to be used. NB: cix is set above where RTS/CTS is enabled */ - memset(series, 0, sizeof(struct ath9k_11n_rate_series) * 4); + ctsrate = rt->info[cix].ratecode | + (bf_isshpreamble(bf) ? rt->info[cix].short_preamble : 0); for (i = 0; i < 4; i++) { - if (!rates[i].count) + if (!rates[i].count || (rates[i].idx < 0)) continue; rix = rates[i].idx; - series[i].Rate = rt->info[rix].rateCode | - (bf_isshpreamble(bf) ? rt->info[rix].shortPreamble : 0); + series[i].Rate = rt->info[rix].ratecode | + (bf_isshpreamble(bf) ? rt->info[rix].short_preamble : 0); series[i].Tries = rates[i].count; @@ -645,13 +610,9 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf) series[i].RateFlags |= ATH9K_RATESERIES_RTS_CTS; } - /* - * set dur_update_en for l-sig computation except for PS-Poll frames - */ - ath9k_hw_set11n_ratescenario(ah, ds, lastds, - !bf_ispspoll(bf), - ctsrate, - ctsduration, + /* set dur_update_en for l-sig computation except for PS-Poll frames */ + ath9k_hw_set11n_ratescenario(ah, ds, lastds, !bf_ispspoll(bf), + ctsrate, ctsduration, series, 4, flags); if (sc->sc_config.ath_aggr_prot && flags) @@ -662,7 +623,6 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf) * Function to send a normal HT (non-AMPDU) frame * NB: must be called with txq lock held */ - static int ath_tx_send_normal(struct ath_softc *sc, struct ath_txq *txq, struct ath_atx_tid *tid, @@ -1256,7 +1216,6 @@ static u32 ath_lookup_rate(struct ath_softc *sc, struct ath_atx_tid *tid) { struct ath_rate_table *rate_table = sc->hw_rate_table[sc->sc_curmode]; - const struct ath9k_rate_table *rt = sc->sc_currates; struct sk_buff *skb; struct ieee80211_tx_info *tx_info; struct ieee80211_tx_rate *rates; @@ -1280,7 +1239,7 @@ static u32 ath_lookup_rate(struct ath_softc *sc, for (i = 0; i < 4; i++) { if (rates[i].count) { - if (rt->info[rates[i].idx].phy != PHY_HT) { + if (!WLAN_RC_PHY_HT(rate_table->info[rates[i].idx].phy)) { legacy = 1; break; } @@ -1325,7 +1284,7 @@ static int ath_compute_num_delims(struct ath_softc *sc, struct ath_buf *bf, u16 frmlen) { - const struct ath9k_rate_table *rt = sc->sc_currates; + struct ath_rate_table *rt = sc->hw_rate_table[sc->sc_curmode]; struct sk_buff *skb = bf->bf_mpdu; struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); u32 nsymbits, nsymbols, mpdudensity; @@ -1362,7 +1321,7 @@ static int ath_compute_num_delims(struct ath_softc *sc, rix = tx_info->control.rates[0].idx; flags = tx_info->control.rates[0].flags; - rc = rt->info[rix].rateCode; + rc = rt->info[rix].ratecode; width = (flags & IEEE80211_TX_RC_40_MHZ_WIDTH) ? 1 : 0; half_gi = (flags & IEEE80211_TX_RC_SHORT_GI) ? 1 : 0; @@ -1713,10 +1672,6 @@ static void ath_tx_setup_buffer(struct ath_softc *sc, struct ath_buf *bf, bf->bf_keyix = ATH9K_TXKEYIX_INVALID; } - /* Rate series */ - - setup_rate_retries(sc, skb); - /* Assign seqno, tidno */ if (bf_isht(bf) && (sc->sc_flags & SC_OP_TXAGGR)) -- cgit v1.2.3 From cb71d9bafb37adab50ddce53bb119a84b4966c06 Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Fri, 21 Nov 2008 17:41:33 -0800 Subject: ath9k: Handle -ENOMEM on RX gracefully We would get an oops on RX on -ENOMEM by passing NULL to the hardware on ath_rx_buf_link(). The oops would look something like this: ath_rx_tasklet+0x515/0x53b ath9k_tasklet+0x48 tasklet_action __do_softirq irq_exit do_IRQ RIP: ath_rx_buf_link+0x3a We correct this by handling the requeue directly on the ath_rx_tasklet() and trying to allocate an skb *prior* to sending up the last hardware processed skb. If we run out of memory this gauranteees we have skbs to work with while it simply drops new received frames. Signed-off-by: Luis R. Rodriguez Signed-off-by: John W. Linville --- drivers/net/wireless/ath9k/recv.c | 57 ++++++++++++++++++--------------------- 1 file changed, 26 insertions(+), 31 deletions(-) (limited to 'drivers/net/wireless/ath9k/recv.c') diff --git a/drivers/net/wireless/ath9k/recv.c b/drivers/net/wireless/ath9k/recv.c index 20f83779278a..6eae2542392a 100644 --- a/drivers/net/wireless/ath9k/recv.c +++ b/drivers/net/wireless/ath9k/recv.c @@ -81,29 +81,6 @@ static struct sk_buff *ath_rxbuf_alloc(struct ath_softc *sc, u32 len) return skb; } -static void ath_rx_requeue(struct ath_softc *sc, struct ath_buf *bf) -{ - struct sk_buff *skb; - - ASSERT(bf != NULL); - - if (bf->bf_mpdu == NULL) { - skb = ath_rxbuf_alloc(sc, sc->sc_rxbufsize); - if (skb != NULL) { - bf->bf_mpdu = skb; - bf->bf_buf_addr = pci_map_single(sc->pdev, skb->data, - skb_end_pointer(skb) - skb->head, - PCI_DMA_FROMDEVICE); - bf->bf_dmacontext = bf->bf_buf_addr; - - } - } - - list_move_tail(&bf->list, &sc->sc_rxbuf); - ath_rx_buf_link(sc, bf); -} - - static int ath_rate2idx(struct ath_softc *sc, int rate) { int i = 0, cur_band, n_rates; @@ -445,7 +422,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush) struct ath_buf *bf; struct ath_desc *ds; - struct sk_buff *skb = NULL; + struct sk_buff *skb = NULL, *requeue_skb; struct ieee80211_rx_status rx_status; struct ath_hal *ah = sc->sc_ah; struct ieee80211_hdr *hdr; @@ -522,17 +499,28 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush) * chain it back at the queue without processing it. */ if (flush) - goto rx_next; + goto requeue; if (!ds->ds_rxstat.rs_datalen) - goto rx_next; + goto requeue; /* The status portion of the descriptor could get corrupted. */ if (sc->sc_rxbufsize < ds->ds_rxstat.rs_datalen) - goto rx_next; + goto requeue; if (!ath_rx_prepare(skb, ds, &rx_status, &decrypt_error, sc)) - goto rx_next; + goto requeue; + + /* Ensure we always have an skb to requeue once we are done + * processing the current buffer's skb */ + requeue_skb = ath_rxbuf_alloc(sc, sc->sc_rxbufsize); + + /* If there is no memory we ignore the current RX'd frame, + * tell hardware it can give us a new frame using the old + * skb and put it at the tail of the sc->sc_rxbuf list for + * processing. */ + if (!requeue_skb) + goto requeue; /* Sync and unmap the frame */ pci_dma_sync_single_for_cpu(sc->pdev, bf->bf_buf_addr, @@ -569,7 +557,13 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush) /* Send the frame to mac80211 */ __ieee80211_rx(sc->hw, skb, &rx_status); - bf->bf_mpdu = NULL; + + /* We will now give hardware our shiny new allocated skb */ + bf->bf_mpdu = requeue_skb; + bf->bf_buf_addr = pci_map_single(sc->pdev, requeue_skb->data, + sc->sc_rxbufsize, + PCI_DMA_FROMDEVICE); + bf->bf_dmacontext = bf->bf_buf_addr; /* * change the default rx antenna if rx diversity chooses the @@ -581,8 +575,9 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush) } else { sc->sc_rxotherant = 0; } -rx_next: - ath_rx_requeue(sc, bf); +requeue: + list_move_tail(&bf->list, &sc->sc_rxbuf); + ath_rx_buf_link(sc, bf); } while (1); spin_unlock_bh(&sc->sc_rxbuflock); -- cgit v1.2.3 From ff37e337beb838d4c2540fa93b2c4c632ee17750 Mon Sep 17 00:00:00 2001 From: Sujith Date: Mon, 24 Nov 2008 12:07:55 +0530 Subject: ath9k: Code scrub Merge core.c and base.c Remove Antenna Diversity (unused now). Remove unused chainmask handling code. Comment, indentation scrub. Signed-off-by: Sujith Signed-off-by: John W. Linville --- drivers/net/wireless/ath9k/Makefile | 3 +- drivers/net/wireless/ath9k/beacon.c | 80 +- drivers/net/wireless/ath9k/core.c | 1610 ----------------------------------- drivers/net/wireless/ath9k/core.h | 155 +--- drivers/net/wireless/ath9k/main.c | 1195 +++++++++++++++++++++++++- drivers/net/wireless/ath9k/rc.c | 9 +- drivers/net/wireless/ath9k/recv.c | 22 + drivers/net/wireless/ath9k/xmit.c | 22 +- 8 files changed, 1231 insertions(+), 1865 deletions(-) delete mode 100644 drivers/net/wireless/ath9k/core.c (limited to 'drivers/net/wireless/ath9k/recv.c') diff --git a/drivers/net/wireless/ath9k/Makefile b/drivers/net/wireless/ath9k/Makefile index c58cfdeb49c9..c741e8d34748 100644 --- a/drivers/net/wireless/ath9k/Makefile +++ b/drivers/net/wireless/ath9k/Makefile @@ -9,7 +9,6 @@ ath9k-y += hw.o \ main.o \ recv.o \ xmit.o \ - rc.o \ - core.o + rc.o obj-$(CONFIG_ATH9K) += ath9k.o diff --git a/drivers/net/wireless/ath9k/beacon.c b/drivers/net/wireless/ath9k/beacon.c index dcf23834194c..377d2df05316 100644 --- a/drivers/net/wireless/ath9k/beacon.c +++ b/drivers/net/wireless/ath9k/beacon.c @@ -14,13 +14,9 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ - /* Implementation of beacon processing. */ - #include "core.h" /* - * Configure parameters for the beacon queue - * * This function will modify certain transmit queue properties depending on * the operating mode of the station (AP or AdHoc). Parameters are AIFS * settings and channel width min/max @@ -54,9 +50,15 @@ static int ath_beaconq_config(struct ath_softc *sc) } } +static void ath_bstuck_process(struct ath_softc *sc) +{ + DPRINTF(sc, ATH_DBG_BEACON, + "%s: stuck beacon; resetting (bmiss count %u)\n", + __func__, sc->sc_bmisscount); + ath_reset(sc, false); +} + /* - * Setup the beacon frame for transmit. - * * Associates the beacon frame buffer with a transmit descriptor. Will set * up all required antenna switch parameters, rate codes, and channel flags. * Beacons are always sent out at the lowest rate, and are not retried. @@ -138,14 +140,7 @@ static void ath_beacon_setup(struct ath_softc *sc, ctsrate, ctsduration, series, 4, 0); } -/* - * Generate beacon frame and queue cab data for a vap. - * - * Updates the contents of the beacon frame. It is assumed that the buffer for - * the beacon frame has been allocated in the ATH object, and simply needs to - * be filled for this cycle. Also, any CAB (crap after beacon?) traffic will - * be added to the beacon frame at this point. -*/ +/* Generate beacon frame and queue cab data for a vap */ static struct ath_buf *ath_beacon_generate(struct ath_softc *sc, int if_id) { struct ath_buf *bf; @@ -275,14 +270,6 @@ static void ath_beacon_start_adhoc(struct ath_softc *sc, int if_id) sc->sc_bhalq, ito64(bf->bf_daddr), bf->bf_desc); } -/* - * Setup a h/w transmit queue for beacons. - * - * This function allocates an information structure (struct ath9k_txq_info) - * on the stack, sets some specific parameters (zero out channel width - * min/max, and enable aifs). The info structure does not need to be - * persistant. -*/ int ath_beaconq_setup(struct ath_hal *ah) { struct ath9k_tx_queue_info qi; @@ -295,14 +282,6 @@ int ath_beaconq_setup(struct ath_hal *ah) return ath9k_hw_setuptxqueue(ah, ATH9K_TX_QUEUE_BEACON, &qi); } - -/* - * Allocate and setup an initial beacon frame. - * - * Allocate a beacon state variable for a specific VAP instance created on - * the ATH interface. This routine also calculates the beacon "slot" for - * staggared beacons in the mBSSID case. -*/ int ath_beacon_alloc(struct ath_softc *sc, int if_id) { struct ieee80211_vif *vif; @@ -321,7 +300,6 @@ int ath_beacon_alloc(struct ath_softc *sc, int if_id) if (!avp->av_bcbuf) { /* Allocate beacon state for hostap/ibss. We know * a buffer is available. */ - avp->av_bcbuf = list_first_entry(&sc->sc_bbuf, struct ath_buf, list); list_del(&avp->av_bcbuf->list); @@ -427,12 +405,6 @@ int ath_beacon_alloc(struct ath_softc *sc, int if_id) return 0; } -/* - * Reclaim beacon resources and return buffer to the pool. - * - * Checks the VAP to put the beacon frame buffer back to the ATH object - * queue, and de-allocates any skbs that were sent as CAB traffic. -*/ void ath_beacon_return(struct ath_softc *sc, struct ath_vap *avp) { if (avp->av_bcbuf != NULL) { @@ -458,13 +430,6 @@ void ath_beacon_return(struct ath_softc *sc, struct ath_vap *avp) } } -/* - * Tasklet for Sending Beacons - * - * Transmit one or more beacon frames at SWBA. Dynamic updates to the frame - * contents are done as needed and the slot time is also adjusted based on - * current state. -*/ void ath9k_beacon_tasklet(unsigned long data) { struct ath_softc *sc = (struct ath_softc *)data; @@ -481,9 +446,7 @@ void ath9k_beacon_tasklet(unsigned long data) if (sc->sc_flags & SC_OP_NO_RESET) { show_cycles = ath9k_hw_GetMibCycleCountsPct(ah, - &rx_clear, - &rx_frame, - &tx_frame); + &rx_clear, &rx_frame, &tx_frame); } /* @@ -605,9 +568,10 @@ void ath9k_beacon_tasklet(unsigned long data) if (sc->sc_updateslot == UPDATE) { sc->sc_updateslot = COMMIT; /* commit next beacon */ sc->sc_slotupdate = slot; - } else if (sc->sc_updateslot == COMMIT && sc->sc_slotupdate == slot) - ath_setslottime(sc); /* commit change to hardware */ - + } else if (sc->sc_updateslot == COMMIT && sc->sc_slotupdate == slot) { + ath9k_hw_setslottime(sc->sc_ah, sc->sc_slottime); + sc->sc_updateslot = OK; + } if (bfaddr != 0) { /* * Stop any current dma and put the new frame(s) on the queue. @@ -629,20 +593,6 @@ void ath9k_beacon_tasklet(unsigned long data) } } -/* - * Tasklet for Beacon Stuck processing - * - * Processing for Beacon Stuck. - * Basically resets the chip. -*/ -void ath_bstuck_process(struct ath_softc *sc) -{ - DPRINTF(sc, ATH_DBG_BEACON, - "%s: stuck beacon; resetting (bmiss count %u)\n", - __func__, sc->sc_bmisscount); - ath_reset(sc, false); -} - /* * Configure the beacon and sleep timers. * @@ -886,8 +836,6 @@ void ath_beacon_config(struct ath_softc *sc, int if_id) } } -/* Function to collect beacon rssi data and resync beacon if necessary */ - void ath_beacon_sync(struct ath_softc *sc, int if_id) { /* diff --git a/drivers/net/wireless/ath9k/core.c b/drivers/net/wireless/ath9k/core.c deleted file mode 100644 index fb6a013f3f31..000000000000 --- a/drivers/net/wireless/ath9k/core.c +++ /dev/null @@ -1,1610 +0,0 @@ -/* - * Copyright (c) 2008, Atheros Communications Inc. - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include "core.h" -#include "regd.h" - -static u32 ath_chainmask_sel_up_rssi_thres = - ATH_CHAINMASK_SEL_UP_RSSI_THRES; -static u32 ath_chainmask_sel_down_rssi_thres = - ATH_CHAINMASK_SEL_DOWN_RSSI_THRES; -static u32 ath_chainmask_sel_period = - ATH_CHAINMASK_SEL_TIMEOUT; - -/* return bus cachesize in 4B word units */ - -static void bus_read_cachesize(struct ath_softc *sc, int *csz) -{ - u8 u8tmp; - - pci_read_config_byte(sc->pdev, PCI_CACHE_LINE_SIZE, (u8 *)&u8tmp); - *csz = (int)u8tmp; - - /* - * This check was put in to avoid "unplesant" consequences if - * the bootrom has not fully initialized all PCI devices. - * Sometimes the cache line size register is not set - */ - - if (*csz == 0) - *csz = DEFAULT_CACHELINE >> 2; /* Use the default size */ -} - -static u8 parse_mpdudensity(u8 mpdudensity) -{ - /* - * 802.11n D2.0 defined values for "Minimum MPDU Start Spacing": - * 0 for no restriction - * 1 for 1/4 us - * 2 for 1/2 us - * 3 for 1 us - * 4 for 2 us - * 5 for 4 us - * 6 for 8 us - * 7 for 16 us - */ - switch (mpdudensity) { - case 0: - return 0; - case 1: - case 2: - case 3: - /* Our lower layer calculations limit our precision to - 1 microsecond */ - return 1; - case 4: - return 2; - case 5: - return 4; - case 6: - return 8; - case 7: - return 16; - default: - return 0; - } -} - -/* - * Set current operating mode -*/ -static void ath_setcurmode(struct ath_softc *sc, enum wireless_mode mode) -{ - sc->sc_curmode = mode; - /* - * All protection frames are transmited at 2Mb/s for - * 11g, otherwise at 1Mb/s. - * XXX select protection rate index from rate table. - */ - sc->sc_protrix = (mode == ATH9K_MODE_11G ? 1 : 0); -} - -/* - * Set up rate table (legacy rates) - */ -static void ath_setup_rates(struct ath_softc *sc, enum ieee80211_band band) -{ - struct ath_rate_table *rate_table = NULL; - struct ieee80211_supported_band *sband; - struct ieee80211_rate *rate; - int i, maxrates; - - switch (band) { - case IEEE80211_BAND_2GHZ: - rate_table = sc->hw_rate_table[ATH9K_MODE_11G]; - break; - case IEEE80211_BAND_5GHZ: - rate_table = sc->hw_rate_table[ATH9K_MODE_11A]; - break; - default: - break; - } - - if (rate_table == NULL) - return; - - sband = &sc->sbands[band]; - rate = sc->rates[band]; - - if (rate_table->rate_cnt > ATH_RATE_MAX) - maxrates = ATH_RATE_MAX; - else - maxrates = rate_table->rate_cnt; - - for (i = 0; i < maxrates; i++) { - rate[i].bitrate = rate_table->info[i].ratekbps / 100; - rate[i].hw_value = rate_table->info[i].ratecode; - sband->n_bitrates++; - DPRINTF(sc, ATH_DBG_CONFIG, - "%s: Rate: %2dMbps, ratecode: %2d\n", - __func__, - rate[i].bitrate / 10, - rate[i].hw_value); - } -} - -/* - * Set up channel list - */ -static int ath_setup_channels(struct ath_softc *sc) -{ - struct ath_hal *ah = sc->sc_ah; - int nchan, i, a = 0, b = 0; - u8 regclassids[ATH_REGCLASSIDS_MAX]; - u32 nregclass = 0; - struct ieee80211_supported_band *band_2ghz; - struct ieee80211_supported_band *band_5ghz; - struct ieee80211_channel *chan_2ghz; - struct ieee80211_channel *chan_5ghz; - struct ath9k_channel *c; - - /* Fill in ah->ah_channels */ - if (!ath9k_regd_init_channels(ah, ATH_CHAN_MAX, (u32 *)&nchan, - regclassids, ATH_REGCLASSIDS_MAX, - &nregclass, CTRY_DEFAULT, false, 1)) { - u32 rd = ah->ah_currentRD; - DPRINTF(sc, ATH_DBG_FATAL, - "%s: unable to collect channel list; " - "regdomain likely %u country code %u\n", - __func__, rd, CTRY_DEFAULT); - return -EINVAL; - } - - band_2ghz = &sc->sbands[IEEE80211_BAND_2GHZ]; - band_5ghz = &sc->sbands[IEEE80211_BAND_5GHZ]; - chan_2ghz = sc->channels[IEEE80211_BAND_2GHZ]; - chan_5ghz = sc->channels[IEEE80211_BAND_5GHZ]; - - for (i = 0; i < nchan; i++) { - c = &ah->ah_channels[i]; - if (IS_CHAN_2GHZ(c)) { - chan_2ghz[a].band = IEEE80211_BAND_2GHZ; - chan_2ghz[a].center_freq = c->channel; - chan_2ghz[a].max_power = c->maxTxPower; - - if (c->privFlags & CHANNEL_DISALLOW_ADHOC) - chan_2ghz[a].flags |= IEEE80211_CHAN_NO_IBSS; - if (c->channelFlags & CHANNEL_PASSIVE) - chan_2ghz[a].flags |= IEEE80211_CHAN_PASSIVE_SCAN; - - band_2ghz->n_channels = ++a; - - DPRINTF(sc, ATH_DBG_CONFIG, - "%s: 2MHz channel: %d, " - "channelFlags: 0x%x\n", - __func__, c->channel, c->channelFlags); - } else if (IS_CHAN_5GHZ(c)) { - chan_5ghz[b].band = IEEE80211_BAND_5GHZ; - chan_5ghz[b].center_freq = c->channel; - chan_5ghz[b].max_power = c->maxTxPower; - - if (c->privFlags & CHANNEL_DISALLOW_ADHOC) - chan_5ghz[b].flags |= IEEE80211_CHAN_NO_IBSS; - if (c->channelFlags & CHANNEL_PASSIVE) - chan_5ghz[b].flags |= IEEE80211_CHAN_PASSIVE_SCAN; - - band_5ghz->n_channels = ++b; - - DPRINTF(sc, ATH_DBG_CONFIG, - "%s: 5MHz channel: %d, " - "channelFlags: 0x%x\n", - __func__, c->channel, c->channelFlags); - } - } - - return 0; -} - -/* - * Determine mode from channel flags - * - * This routine will provide the enumerated WIRELESSS_MODE value based - * on the settings of the channel flags. If no valid set of flags - * exist, the lowest mode (11b) is selected. -*/ - -static enum wireless_mode ath_chan2mode(struct ath9k_channel *chan) -{ - if (chan->chanmode == CHANNEL_A) - return ATH9K_MODE_11A; - else if (chan->chanmode == CHANNEL_G) - return ATH9K_MODE_11G; - else if (chan->chanmode == CHANNEL_B) - return ATH9K_MODE_11B; - else if (chan->chanmode == CHANNEL_A_HT20) - return ATH9K_MODE_11NA_HT20; - else if (chan->chanmode == CHANNEL_G_HT20) - return ATH9K_MODE_11NG_HT20; - else if (chan->chanmode == CHANNEL_A_HT40PLUS) - return ATH9K_MODE_11NA_HT40PLUS; - else if (chan->chanmode == CHANNEL_A_HT40MINUS) - return ATH9K_MODE_11NA_HT40MINUS; - else if (chan->chanmode == CHANNEL_G_HT40PLUS) - return ATH9K_MODE_11NG_HT40PLUS; - else if (chan->chanmode == CHANNEL_G_HT40MINUS) - return ATH9K_MODE_11NG_HT40MINUS; - - WARN_ON(1); /* should not get here */ - - return ATH9K_MODE_11B; -} - -/* - * Set the current channel - * - * Set/change channels. If the channel is really being changed, it's done - * by reseting the chip. To accomplish this we must first cleanup any pending - * DMA, then restart stuff after a la ath_init. -*/ -int ath_set_channel(struct ath_softc *sc, struct ath9k_channel *hchan) -{ - struct ath_hal *ah = sc->sc_ah; - bool fastcc = true, stopped; - - if (sc->sc_flags & SC_OP_INVALID) /* the device is invalid or removed */ - return -EIO; - - DPRINTF(sc, ATH_DBG_CONFIG, - "%s: %u (%u MHz) -> %u (%u MHz), cflags:%x\n", - __func__, - ath9k_hw_mhz2ieee(ah, sc->sc_ah->ah_curchan->channel, - sc->sc_ah->ah_curchan->channelFlags), - sc->sc_ah->ah_curchan->channel, - ath9k_hw_mhz2ieee(ah, hchan->channel, hchan->channelFlags), - hchan->channel, hchan->channelFlags); - - if (hchan->channel != sc->sc_ah->ah_curchan->channel || - hchan->channelFlags != sc->sc_ah->ah_curchan->channelFlags || - (sc->sc_flags & SC_OP_CHAINMASK_UPDATE) || - (sc->sc_flags & SC_OP_FULL_RESET)) { - int status; - /* - * This is only performed if the channel settings have - * actually changed. - * - * To switch channels clear any pending DMA operations; - * wait long enough for the RX fifo to drain, reset the - * hardware at the new frequency, and then re-enable - * the relevant bits of the h/w. - */ - ath9k_hw_set_interrupts(ah, 0); /* disable interrupts */ - ath_draintxq(sc, false); /* clear pending tx frames */ - stopped = ath_stoprecv(sc); /* turn off frame recv */ - - /* XXX: do not flush receive queue here. We don't want - * to flush data frames already in queue because of - * changing channel. */ - - if (!stopped || (sc->sc_flags & SC_OP_FULL_RESET)) - fastcc = false; - - spin_lock_bh(&sc->sc_resetlock); - if (!ath9k_hw_reset(ah, hchan, - sc->sc_ht_info.tx_chan_width, - sc->sc_tx_chainmask, - sc->sc_rx_chainmask, - sc->sc_ht_extprotspacing, - fastcc, &status)) { - DPRINTF(sc, ATH_DBG_FATAL, - "%s: unable to reset channel %u (%uMhz) " - "flags 0x%x hal status %u\n", __func__, - ath9k_hw_mhz2ieee(ah, hchan->channel, - hchan->channelFlags), - hchan->channel, hchan->channelFlags, status); - spin_unlock_bh(&sc->sc_resetlock); - return -EIO; - } - spin_unlock_bh(&sc->sc_resetlock); - - sc->sc_flags &= ~SC_OP_CHAINMASK_UPDATE; - sc->sc_flags &= ~SC_OP_FULL_RESET; - - /* Re-enable rx framework */ - if (ath_startrecv(sc) != 0) { - DPRINTF(sc, ATH_DBG_FATAL, - "%s: unable to restart recv logic\n", __func__); - return -EIO; - } - /* - * Change channels and update the h/w rate map - * if we're switching; e.g. 11a to 11b/g. - */ - ath_setcurmode(sc, ath_chan2mode(hchan)); - - ath_update_txpow(sc); /* update tx power state */ - /* - * Re-enable interrupts. - */ - ath9k_hw_set_interrupts(ah, sc->sc_imask); - } - return 0; -} - -/**********************/ -/* Chainmask Handling */ -/**********************/ - -static void ath_chainmask_sel_timertimeout(unsigned long data) -{ - struct ath_chainmask_sel *cm = (struct ath_chainmask_sel *)data; - cm->switch_allowed = 1; -} - -/* Start chainmask select timer */ -static void ath_chainmask_sel_timerstart(struct ath_chainmask_sel *cm) -{ - cm->switch_allowed = 0; - mod_timer(&cm->timer, ath_chainmask_sel_period); -} - -/* Stop chainmask select timer */ -static void ath_chainmask_sel_timerstop(struct ath_chainmask_sel *cm) -{ - cm->switch_allowed = 0; - del_timer_sync(&cm->timer); -} - -static void ath_chainmask_sel_init(struct ath_softc *sc, struct ath_node *an) -{ - struct ath_chainmask_sel *cm = &an->an_chainmask_sel; - - memset(cm, 0, sizeof(struct ath_chainmask_sel)); - - cm->cur_tx_mask = sc->sc_tx_chainmask; - cm->cur_rx_mask = sc->sc_rx_chainmask; - cm->tx_avgrssi = ATH_RSSI_DUMMY_MARKER; - setup_timer(&cm->timer, - ath_chainmask_sel_timertimeout, (unsigned long) cm); -} - -int ath_chainmask_sel_logic(struct ath_softc *sc, struct ath_node *an) -{ - struct ath_chainmask_sel *cm = &an->an_chainmask_sel; - - /* - * Disable auto-swtiching in one of the following if conditions. - * sc_chainmask_auto_sel is used for internal global auto-switching - * enabled/disabled setting - */ - if (sc->sc_ah->ah_caps.tx_chainmask != ATH_CHAINMASK_SEL_3X3) { - cm->cur_tx_mask = sc->sc_tx_chainmask; - return cm->cur_tx_mask; - } - - if (cm->tx_avgrssi == ATH_RSSI_DUMMY_MARKER) - return cm->cur_tx_mask; - - if (cm->switch_allowed) { - /* Switch down from tx 3 to tx 2. */ - if (cm->cur_tx_mask == ATH_CHAINMASK_SEL_3X3 && - ATH_RSSI_OUT(cm->tx_avgrssi) >= - ath_chainmask_sel_down_rssi_thres) { - cm->cur_tx_mask = sc->sc_tx_chainmask; - - /* Don't let another switch happen until - * this timer expires */ - ath_chainmask_sel_timerstart(cm); - } - /* Switch up from tx 2 to 3. */ - else if (cm->cur_tx_mask == sc->sc_tx_chainmask && - ATH_RSSI_OUT(cm->tx_avgrssi) <= - ath_chainmask_sel_up_rssi_thres) { - cm->cur_tx_mask = ATH_CHAINMASK_SEL_3X3; - - /* Don't let another switch happen - * until this timer expires */ - ath_chainmask_sel_timerstart(cm); - } - } - - return cm->cur_tx_mask; -} - -/* - * Update tx/rx chainmask. For legacy association, - * hard code chainmask to 1x1, for 11n association, use - * the chainmask configuration. - */ - -void ath_update_chainmask(struct ath_softc *sc, int is_ht) -{ - sc->sc_flags |= SC_OP_CHAINMASK_UPDATE; - if (is_ht) { - sc->sc_tx_chainmask = sc->sc_ah->ah_caps.tx_chainmask; - sc->sc_rx_chainmask = sc->sc_ah->ah_caps.rx_chainmask; - } else { - sc->sc_tx_chainmask = 1; - sc->sc_rx_chainmask = 1; - } - - DPRINTF(sc, ATH_DBG_CONFIG, "%s: tx chmask: %d, rx chmask: %d\n", - __func__, sc->sc_tx_chainmask, sc->sc_rx_chainmask); -} - -/*******/ -/* ANI */ -/*******/ - -/* - * This routine performs the periodic noise floor calibration function - * that is used to adjust and optimize the chip performance. This - * takes environmental changes (location, temperature) into account. - * When the task is complete, it reschedules itself depending on the - * appropriate interval that was calculated. - */ - -static void ath_ani_calibrate(unsigned long data) -{ - struct ath_softc *sc; - struct ath_hal *ah; - bool longcal = false; - bool shortcal = false; - bool aniflag = false; - unsigned int timestamp = jiffies_to_msecs(jiffies); - u32 cal_interval; - - sc = (struct ath_softc *)data; - ah = sc->sc_ah; - - /* - * don't calibrate when we're scanning. - * we are most likely not on our home channel. - */ - if (sc->rx_filter & FIF_BCN_PRBRESP_PROMISC) - return; - - /* Long calibration runs independently of short calibration. */ - if ((timestamp - sc->sc_ani.sc_longcal_timer) >= ATH_LONG_CALINTERVAL) { - longcal = true; - DPRINTF(sc, ATH_DBG_ANI, "%s: longcal @%lu\n", - __func__, jiffies); - sc->sc_ani.sc_longcal_timer = timestamp; - } - - /* Short calibration applies only while sc_caldone is false */ - if (!sc->sc_ani.sc_caldone) { - if ((timestamp - sc->sc_ani.sc_shortcal_timer) >= - ATH_SHORT_CALINTERVAL) { - shortcal = true; - DPRINTF(sc, ATH_DBG_ANI, "%s: shortcal @%lu\n", - __func__, jiffies); - sc->sc_ani.sc_shortcal_timer = timestamp; - sc->sc_ani.sc_resetcal_timer = timestamp; - } - } else { - if ((timestamp - sc->sc_ani.sc_resetcal_timer) >= - ATH_RESTART_CALINTERVAL) { - ath9k_hw_reset_calvalid(ah, ah->ah_curchan, - &sc->sc_ani.sc_caldone); - if (sc->sc_ani.sc_caldone) - sc->sc_ani.sc_resetcal_timer = timestamp; - } - } - - /* Verify whether we must check ANI */ - if ((timestamp - sc->sc_ani.sc_checkani_timer) >= - ATH_ANI_POLLINTERVAL) { - aniflag = true; - sc->sc_ani.sc_checkani_timer = timestamp; - } - - /* Skip all processing if there's nothing to do. */ - if (longcal || shortcal || aniflag) { - /* Call ANI routine if necessary */ - if (aniflag) - ath9k_hw_ani_monitor(ah, &sc->sc_halstats, - ah->ah_curchan); - - /* Perform calibration if necessary */ - if (longcal || shortcal) { - bool iscaldone = false; - - if (ath9k_hw_calibrate(ah, ah->ah_curchan, - sc->sc_rx_chainmask, longcal, - &iscaldone)) { - if (longcal) - sc->sc_ani.sc_noise_floor = - ath9k_hw_getchan_noise(ah, - ah->ah_curchan); - - DPRINTF(sc, ATH_DBG_ANI, - "%s: calibrate chan %u/%x nf: %d\n", - __func__, - ah->ah_curchan->channel, - ah->ah_curchan->channelFlags, - sc->sc_ani.sc_noise_floor); - } else { - DPRINTF(sc, ATH_DBG_ANY, - "%s: calibrate chan %u/%x failed\n", - __func__, - ah->ah_curchan->channel, - ah->ah_curchan->channelFlags); - } - sc->sc_ani.sc_caldone = iscaldone; - } - } - - /* - * Set timer interval based on previous results. - * The interval must be the shortest necessary to satisfy ANI, - * short calibration and long calibration. - */ - - cal_interval = ATH_ANI_POLLINTERVAL; - if (!sc->sc_ani.sc_caldone) - cal_interval = min(cal_interval, (u32)ATH_SHORT_CALINTERVAL); - - mod_timer(&sc->sc_ani.timer, jiffies + msecs_to_jiffies(cal_interval)); -} - -/********/ -/* Core */ -/********/ - -int ath_open(struct ath_softc *sc, struct ath9k_channel *initial_chan) -{ - struct ath_hal *ah = sc->sc_ah; - int status; - int error = 0; - - DPRINTF(sc, ATH_DBG_CONFIG, "%s: mode %d\n", - __func__, sc->sc_ah->ah_opmode); - - /* Reset SERDES registers */ - ath9k_hw_configpcipowersave(ah, 0); - - /* - * The basic interface to setting the hardware in a good - * state is ``reset''. On return the hardware is known to - * be powered up and with interrupts disabled. This must - * be followed by initialization of the appropriate bits - * and then setup of the interrupt mask. - */ - - spin_lock_bh(&sc->sc_resetlock); - if (!ath9k_hw_reset(ah, initial_chan, - sc->sc_ht_info.tx_chan_width, - sc->sc_tx_chainmask, sc->sc_rx_chainmask, - sc->sc_ht_extprotspacing, false, &status)) { - DPRINTF(sc, ATH_DBG_FATAL, - "%s: unable to reset hardware; hal status %u " - "(freq %u flags 0x%x)\n", __func__, status, - initial_chan->channel, initial_chan->channelFlags); - error = -EIO; - spin_unlock_bh(&sc->sc_resetlock); - goto done; - } - spin_unlock_bh(&sc->sc_resetlock); - - /* - * This is needed only to setup initial state - * but it's best done after a reset. - */ - ath_update_txpow(sc); - - /* - * Setup the hardware after reset: - * The receive engine is set going. - * Frame transmit is handled entirely - * in the frame output path; there's nothing to do - * here except setup the interrupt mask. - */ - if (ath_startrecv(sc) != 0) { - DPRINTF(sc, ATH_DBG_FATAL, - "%s: unable to start recv logic\n", __func__); - error = -EIO; - goto done; - } - - /* Setup our intr mask. */ - sc->sc_imask = ATH9K_INT_RX | ATH9K_INT_TX - | ATH9K_INT_RXEOL | ATH9K_INT_RXORN - | ATH9K_INT_FATAL | ATH9K_INT_GLOBAL; - - if (ah->ah_caps.hw_caps & ATH9K_HW_CAP_GTT) - sc->sc_imask |= ATH9K_INT_GTT; - - if (ah->ah_caps.hw_caps & ATH9K_HW_CAP_HT) - sc->sc_imask |= ATH9K_INT_CST; - - /* - * Enable MIB interrupts when there are hardware phy counters. - * Note we only do this (at the moment) for station mode. - */ - if (ath9k_hw_phycounters(ah) && - ((sc->sc_ah->ah_opmode == ATH9K_M_STA) || - (sc->sc_ah->ah_opmode == ATH9K_M_IBSS))) - sc->sc_imask |= ATH9K_INT_MIB; - /* - * Some hardware processes the TIM IE and fires an - * interrupt when the TIM bit is set. For hardware - * that does, if not overridden by configuration, - * enable the TIM interrupt when operating as station. - */ - if ((ah->ah_caps.hw_caps & ATH9K_HW_CAP_ENHANCEDPM) && - (sc->sc_ah->ah_opmode == ATH9K_M_STA) && - !sc->sc_config.swBeaconProcess) - sc->sc_imask |= ATH9K_INT_TIM; - - ath_setcurmode(sc, ath_chan2mode(initial_chan)); - - sc->sc_flags &= ~SC_OP_INVALID; - - /* Disable BMISS interrupt when we're not associated */ - sc->sc_imask &= ~(ATH9K_INT_SWBA | ATH9K_INT_BMISS); - ath9k_hw_set_interrupts(sc->sc_ah,sc->sc_imask); - - ieee80211_wake_queues(sc->hw); -done: - return error; -} - -void ath_stop(struct ath_softc *sc) -{ - struct ath_hal *ah = sc->sc_ah; - - DPRINTF(sc, ATH_DBG_CONFIG, "%s: Cleaning up\n", __func__); - - ieee80211_stop_queues(sc->hw); - - /* make sure h/w will not generate any interrupt - * before setting the invalid flag. */ - ath9k_hw_set_interrupts(ah, 0); - - if (!(sc->sc_flags & SC_OP_INVALID)) { - ath_draintxq(sc, false); - ath_stoprecv(sc); - ath9k_hw_phy_disable(ah); - } else - sc->sc_rxlink = NULL; - -#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE) - if (sc->sc_ah->ah_caps.hw_caps & ATH9K_HW_CAP_RFSILENT) - cancel_delayed_work_sync(&sc->rf_kill.rfkill_poll); -#endif - /* disable HAL and put h/w to sleep */ - ath9k_hw_disable(sc->sc_ah); - ath9k_hw_configpcipowersave(sc->sc_ah, 1); - - sc->sc_flags |= SC_OP_INVALID; -} - -int ath_reset(struct ath_softc *sc, bool retry_tx) -{ - struct ath_hal *ah = sc->sc_ah; - int status; - int error = 0; - - ath9k_hw_set_interrupts(ah, 0); - ath_draintxq(sc, retry_tx); - ath_stoprecv(sc); - ath_flushrecv(sc); - - /* Reset chip */ - spin_lock_bh(&sc->sc_resetlock); - if (!ath9k_hw_reset(ah, sc->sc_ah->ah_curchan, - sc->sc_ht_info.tx_chan_width, - sc->sc_tx_chainmask, sc->sc_rx_chainmask, - sc->sc_ht_extprotspacing, false, &status)) { - DPRINTF(sc, ATH_DBG_FATAL, - "%s: unable to reset hardware; hal status %u\n", - __func__, status); - error = -EIO; - } - spin_unlock_bh(&sc->sc_resetlock); - - if (ath_startrecv(sc) != 0) - DPRINTF(sc, ATH_DBG_FATAL, - "%s: unable to start recv logic\n", __func__); - - /* - * We may be doing a reset in response to a request - * that changes the channel so update any state that - * might change as a result. - */ - ath_setcurmode(sc, ath_chan2mode(sc->sc_ah->ah_curchan)); - - ath_update_txpow(sc); - - if (sc->sc_flags & SC_OP_BEACONS) - ath_beacon_config(sc, ATH_IF_ID_ANY); /* restart beacons */ - - ath9k_hw_set_interrupts(ah, sc->sc_imask); - - /* Restart the txq */ - if (retry_tx) { - int i; - for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) { - if (ATH_TXQ_SETUP(sc, i)) { - spin_lock_bh(&sc->sc_txq[i].axq_lock); - ath_txq_schedule(sc, &sc->sc_txq[i]); - spin_unlock_bh(&sc->sc_txq[i].axq_lock); - } - } - } - - return error; -} - -/* Interrupt handler. Most of the actual processing is deferred. - * It's the caller's responsibility to ensure the chip is awake. */ - -irqreturn_t ath_isr(int irq, void *dev) -{ - struct ath_softc *sc = dev; - struct ath_hal *ah = sc->sc_ah; - enum ath9k_int status; - bool sched = false; - - do { - if (sc->sc_flags & SC_OP_INVALID) { - /* - * The hardware is not ready/present, don't - * touch anything. Note this can happen early - * on if the IRQ is shared. - */ - return IRQ_NONE; - } - if (!ath9k_hw_intrpend(ah)) { /* shared irq, not for us */ - return IRQ_NONE; - } - - /* - * Figure out the reason(s) for the interrupt. Note - * that the hal returns a pseudo-ISR that may include - * bits we haven't explicitly enabled so we mask the - * value to insure we only process bits we requested. - */ - ath9k_hw_getisr(ah, &status); /* NB: clears ISR too */ - - status &= sc->sc_imask; /* discard unasked-for bits */ - - /* - * If there are no status bits set, then this interrupt was not - * for me (should have been caught above). - */ - - if (!status) - return IRQ_NONE; - - sc->sc_intrstatus = status; - - if (status & ATH9K_INT_FATAL) { - /* need a chip reset */ - sched = true; - } else if (status & ATH9K_INT_RXORN) { - /* need a chip reset */ - sched = true; - } else { - if (status & ATH9K_INT_SWBA) { - /* schedule a tasklet for beacon handling */ - tasklet_schedule(&sc->bcon_tasklet); - } - if (status & ATH9K_INT_RXEOL) { - /* - * NB: the hardware should re-read the link when - * RXE bit is written, but it doesn't work - * at least on older hardware revs. - */ - sched = true; - } - - if (status & ATH9K_INT_TXURN) - /* bump tx trigger level */ - ath9k_hw_updatetxtriglevel(ah, true); - /* XXX: optimize this */ - if (status & ATH9K_INT_RX) - sched = true; - if (status & ATH9K_INT_TX) - sched = true; - if (status & ATH9K_INT_BMISS) - sched = true; - /* carrier sense timeout */ - if (status & ATH9K_INT_CST) - sched = true; - if (status & ATH9K_INT_MIB) { - /* - * Disable interrupts until we service the MIB - * interrupt; otherwise it will continue to - * fire. - */ - ath9k_hw_set_interrupts(ah, 0); - /* - * Let the hal handle the event. We assume - * it will clear whatever condition caused - * the interrupt. - */ - ath9k_hw_procmibevent(ah, &sc->sc_halstats); - ath9k_hw_set_interrupts(ah, sc->sc_imask); - } - if (status & ATH9K_INT_TIM_TIMER) { - if (!(ah->ah_caps.hw_caps & - ATH9K_HW_CAP_AUTOSLEEP)) { - /* Clear RxAbort bit so that we can - * receive frames */ - ath9k_hw_setrxabort(ah, 0); - sched = true; - } - } - } - } while (0); - - if (sched) { - /* turn off every interrupt except SWBA */ - ath9k_hw_set_interrupts(ah, (sc->sc_imask & ATH9K_INT_SWBA)); - tasklet_schedule(&sc->intr_tq); - } - - return IRQ_HANDLED; -} - -/* Deferred interrupt processing */ - -static void ath9k_tasklet(unsigned long data) -{ - struct ath_softc *sc = (struct ath_softc *)data; - u32 status = sc->sc_intrstatus; - - if (status & ATH9K_INT_FATAL) { - /* need a chip reset */ - ath_reset(sc, false); - return; - } else { - - if (status & - (ATH9K_INT_RX | ATH9K_INT_RXEOL | ATH9K_INT_RXORN)) { - /* XXX: fill me in */ - /* - if (status & ATH9K_INT_RXORN) { - } - if (status & ATH9K_INT_RXEOL) { - } - */ - spin_lock_bh(&sc->sc_rxflushlock); - ath_rx_tasklet(sc, 0); - spin_unlock_bh(&sc->sc_rxflushlock); - } - /* XXX: optimize this */ - if (status & ATH9K_INT_TX) - ath_tx_tasklet(sc); - /* XXX: fill me in */ - /* - if (status & ATH9K_INT_BMISS) { - } - if (status & (ATH9K_INT_TIM | ATH9K_INT_DTIMSYNC)) { - if (status & ATH9K_INT_TIM) { - } - if (status & ATH9K_INT_DTIMSYNC) { - } - } - */ - } - - /* re-enable hardware interrupt */ - ath9k_hw_set_interrupts(sc->sc_ah, sc->sc_imask); -} - -int ath_init(u16 devid, struct ath_softc *sc) -{ - struct ath_hal *ah = NULL; - int status; - int error = 0, i; - int csz = 0; - - /* XXX: hardware will not be ready until ath_open() being called */ - sc->sc_flags |= SC_OP_INVALID; - sc->sc_debug = DBG_DEFAULT; - - spin_lock_init(&sc->sc_resetlock); - tasklet_init(&sc->intr_tq, ath9k_tasklet, (unsigned long)sc); - tasklet_init(&sc->bcon_tasklet, ath9k_beacon_tasklet, - (unsigned long)sc); - - /* - * Cache line size is used to size and align various - * structures used to communicate with the hardware. - */ - bus_read_cachesize(sc, &csz); - /* XXX assert csz is non-zero */ - sc->sc_cachelsz = csz << 2; /* convert to bytes */ - - ah = ath9k_hw_attach(devid, sc, sc->mem, &status); - if (ah == NULL) { - DPRINTF(sc, ATH_DBG_FATAL, - "%s: unable to attach hardware; HAL status %u\n", - __func__, status); - error = -ENXIO; - goto bad; - } - sc->sc_ah = ah; - - /* Get the hardware key cache size. */ - sc->sc_keymax = ah->ah_caps.keycache_size; - if (sc->sc_keymax > ATH_KEYMAX) { - DPRINTF(sc, ATH_DBG_KEYCACHE, - "%s: Warning, using only %u entries in %u key cache\n", - __func__, ATH_KEYMAX, sc->sc_keymax); - sc->sc_keymax = ATH_KEYMAX; - } - - /* - * Reset the key cache since some parts do not - * reset the contents on initial power up. - */ - for (i = 0; i < sc->sc_keymax; i++) - ath9k_hw_keyreset(ah, (u16) i); - /* - * Mark key cache slots associated with global keys - * as in use. If we knew TKIP was not to be used we - * could leave the +32, +64, and +32+64 slots free. - * XXX only for splitmic. - */ - for (i = 0; i < IEEE80211_WEP_NKID; i++) { - set_bit(i, sc->sc_keymap); - set_bit(i + 32, sc->sc_keymap); - set_bit(i + 64, sc->sc_keymap); - set_bit(i + 32 + 64, sc->sc_keymap); - } - - /* Collect the channel list using the default country code */ - - error = ath_setup_channels(sc); - if (error) - goto bad; - - /* default to MONITOR mode */ - sc->sc_ah->ah_opmode = ATH9K_M_MONITOR; - - /* Setup rate tables */ - - ath_rate_attach(sc); - ath_setup_rates(sc, IEEE80211_BAND_2GHZ); - ath_setup_rates(sc, IEEE80211_BAND_5GHZ); - - /* - * Allocate hardware transmit queues: one queue for - * beacon frames and one data queue for each QoS - * priority. Note that the hal handles reseting - * these queues at the needed time. - */ - sc->sc_bhalq = ath_beaconq_setup(ah); - if (sc->sc_bhalq == -1) { - DPRINTF(sc, ATH_DBG_FATAL, - "%s: unable to setup a beacon xmit queue\n", __func__); - error = -EIO; - goto bad2; - } - sc->sc_cabq = ath_txq_setup(sc, ATH9K_TX_QUEUE_CAB, 0); - if (sc->sc_cabq == NULL) { - DPRINTF(sc, ATH_DBG_FATAL, - "%s: unable to setup CAB xmit queue\n", __func__); - error = -EIO; - goto bad2; - } - - sc->sc_config.cabqReadytime = ATH_CABQ_READY_TIME; - ath_cabq_update(sc); - - for (i = 0; i < ARRAY_SIZE(sc->sc_haltype2q); i++) - sc->sc_haltype2q[i] = -1; - - /* Setup data queues */ - /* NB: ensure BK queue is the lowest priority h/w queue */ - if (!ath_tx_setup(sc, ATH9K_WME_AC_BK)) { - DPRINTF(sc, ATH_DBG_FATAL, - "%s: unable to setup xmit queue for BK traffic\n", - __func__); - error = -EIO; - goto bad2; - } - - if (!ath_tx_setup(sc, ATH9K_WME_AC_BE)) { - DPRINTF(sc, ATH_DBG_FATAL, - "%s: unable to setup xmit queue for BE traffic\n", - __func__); - error = -EIO; - goto bad2; - } - if (!ath_tx_setup(sc, ATH9K_WME_AC_VI)) { - DPRINTF(sc, ATH_DBG_FATAL, - "%s: unable to setup xmit queue for VI traffic\n", - __func__); - error = -EIO; - goto bad2; - } - if (!ath_tx_setup(sc, ATH9K_WME_AC_VO)) { - DPRINTF(sc, ATH_DBG_FATAL, - "%s: unable to setup xmit queue for VO traffic\n", - __func__); - error = -EIO; - goto bad2; - } - - /* Initializes the noise floor to a reasonable default value. - * Later on this will be updated during ANI processing. */ - - sc->sc_ani.sc_noise_floor = ATH_DEFAULT_NOISE_FLOOR; - setup_timer(&sc->sc_ani.timer, ath_ani_calibrate, (unsigned long)sc); - - if (ath9k_hw_getcapability(ah, ATH9K_CAP_CIPHER, - ATH9K_CIPHER_TKIP, NULL)) { - /* - * Whether we should enable h/w TKIP MIC. - * XXX: if we don't support WME TKIP MIC, then we wouldn't - * report WMM capable, so it's always safe to turn on - * TKIP MIC in this case. - */ - ath9k_hw_setcapability(sc->sc_ah, ATH9K_CAP_TKIP_MIC, - 0, 1, NULL); - } - - /* - * Check whether the separate key cache entries - * are required to handle both tx+rx MIC keys. - * With split mic keys the number of stations is limited - * to 27 otherwise 59. - */ - if (ath9k_hw_getcapability(ah, ATH9K_CAP_CIPHER, - ATH9K_CIPHER_TKIP, NULL) - && ath9k_hw_getcapability(ah, ATH9K_CAP_CIPHER, - ATH9K_CIPHER_MIC, NULL) - && ath9k_hw_getcapability(ah, ATH9K_CAP_TKIP_SPLIT, - 0, NULL)) - sc->sc_splitmic = 1; - - /* turn on mcast key search if possible */ - if (!ath9k_hw_getcapability(ah, ATH9K_CAP_MCAST_KEYSRCH, 0, NULL)) - (void)ath9k_hw_setcapability(ah, ATH9K_CAP_MCAST_KEYSRCH, 1, - 1, NULL); - - sc->sc_config.txpowlimit = ATH_TXPOWER_MAX; - sc->sc_config.txpowlimit_override = 0; - - /* 11n Capabilities */ - if (ah->ah_caps.hw_caps & ATH9K_HW_CAP_HT) { - sc->sc_flags |= SC_OP_TXAGGR; - sc->sc_flags |= SC_OP_RXAGGR; - } - - sc->sc_tx_chainmask = ah->ah_caps.tx_chainmask; - sc->sc_rx_chainmask = ah->ah_caps.rx_chainmask; - - ath9k_hw_setcapability(ah, ATH9K_CAP_DIVERSITY, 1, true, NULL); - sc->sc_defant = ath9k_hw_getdefantenna(ah); - - ath9k_hw_getmac(ah, sc->sc_myaddr); - if (ah->ah_caps.hw_caps & ATH9K_HW_CAP_BSSIDMASK) { - ath9k_hw_getbssidmask(ah, sc->sc_bssidmask); - ATH_SET_VAP_BSSID_MASK(sc->sc_bssidmask); - ath9k_hw_setbssidmask(ah, sc->sc_bssidmask); - } - - sc->sc_slottime = ATH9K_SLOT_TIME_9; /* default to short slot time */ - - /* initialize beacon slots */ - for (i = 0; i < ARRAY_SIZE(sc->sc_bslot); i++) - sc->sc_bslot[i] = ATH_IF_ID_ANY; - - /* save MISC configurations */ - sc->sc_config.swBeaconProcess = 1; - -#ifdef CONFIG_SLOW_ANT_DIV - /* range is 40 - 255, we use something in the middle */ - ath_slow_ant_div_init(&sc->sc_antdiv, sc, 0x127); -#endif - - /* setup channels and rates */ - - sc->sbands[IEEE80211_BAND_2GHZ].channels = - sc->channels[IEEE80211_BAND_2GHZ]; - sc->sbands[IEEE80211_BAND_2GHZ].bitrates = - sc->rates[IEEE80211_BAND_2GHZ]; - sc->sbands[IEEE80211_BAND_2GHZ].band = IEEE80211_BAND_2GHZ; - - if (test_bit(ATH9K_MODE_11A, sc->sc_ah->ah_caps.wireless_modes)) { - sc->sbands[IEEE80211_BAND_5GHZ].channels = - sc->channels[IEEE80211_BAND_5GHZ]; - sc->sbands[IEEE80211_BAND_5GHZ].bitrates = - sc->rates[IEEE80211_BAND_5GHZ]; - sc->sbands[IEEE80211_BAND_5GHZ].band = IEEE80211_BAND_5GHZ; - } - - return 0; -bad2: - /* cleanup tx queues */ - for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) - if (ATH_TXQ_SETUP(sc, i)) - ath_tx_cleanupq(sc, &sc->sc_txq[i]); -bad: - if (ah) - ath9k_hw_detach(ah); - - return error; -} - -/*******************/ -/* Node Management */ -/*******************/ - -void ath_node_attach(struct ath_softc *sc, struct ieee80211_sta *sta) -{ - struct ath_node *an; - - an = (struct ath_node *)sta->drv_priv; - - if (sc->sc_flags & SC_OP_TXAGGR) - ath_tx_node_init(sc, an); - - an->maxampdu = 1 << (IEEE80211_HTCAP_MAXRXAMPDU_FACTOR + - sta->ht_cap.ampdu_factor); - an->mpdudensity = parse_mpdudensity(sta->ht_cap.ampdu_density); - - ath_chainmask_sel_init(sc, an); - ath_chainmask_sel_timerstart(&an->an_chainmask_sel); -} - -void ath_node_detach(struct ath_softc *sc, struct ieee80211_sta *sta) -{ - struct ath_node *an = (struct ath_node *)sta->drv_priv; - - ath_chainmask_sel_timerstop(&an->an_chainmask_sel); - - if (sc->sc_flags & SC_OP_TXAGGR) - ath_tx_node_cleanup(sc, an); -} - -/* - * Set up New Node - * - * Setup driver-specific state for a newly associated node. This routine - * really only applies if compression or XR are enabled, there is no code - * covering any other cases. -*/ - -void ath_newassoc(struct ath_softc *sc, - struct ath_node *an, int isnew, int isuapsd) -{ - int tidno; - - /* if station reassociates, tear down the aggregation state. */ - if (!isnew) { - for (tidno = 0; tidno < WME_NUM_TID; tidno++) { - if (sc->sc_flags & SC_OP_TXAGGR) - ath_tx_aggr_teardown(sc, an, tidno); - } - } -} - -/**************/ -/* Encryption */ -/**************/ - -void ath_key_reset(struct ath_softc *sc, u16 keyix, int freeslot) -{ - ath9k_hw_keyreset(sc->sc_ah, keyix); - if (freeslot) - clear_bit(keyix, sc->sc_keymap); -} - -int ath_keyset(struct ath_softc *sc, - u16 keyix, - struct ath9k_keyval *hk, - const u8 mac[ETH_ALEN]) -{ - bool status; - - status = ath9k_hw_set_keycache_entry(sc->sc_ah, - keyix, hk, mac, false); - - return status != false; -} - -/***********************/ -/* TX Power/Regulatory */ -/***********************/ - -/* - * Set Transmit power in HAL - * - * This routine makes the actual HAL calls to set the new transmit power - * limit. -*/ - -void ath_update_txpow(struct ath_softc *sc) -{ - struct ath_hal *ah = sc->sc_ah; - u32 txpow; - - if (sc->sc_curtxpow != sc->sc_config.txpowlimit) { - ath9k_hw_set_txpowerlimit(ah, sc->sc_config.txpowlimit); - /* read back in case value is clamped */ - ath9k_hw_getcapability(ah, ATH9K_CAP_TXPOW, 1, &txpow); - sc->sc_curtxpow = txpow; - } -} - -/**************************/ -/* Slow Antenna Diversity */ -/**************************/ - -void ath_slow_ant_div_init(struct ath_antdiv *antdiv, - struct ath_softc *sc, - int32_t rssitrig) -{ - int trig; - - /* antdivf_rssitrig can range from 40 - 0xff */ - trig = (rssitrig > 0xff) ? 0xff : rssitrig; - trig = (rssitrig < 40) ? 40 : rssitrig; - - antdiv->antdiv_sc = sc; - antdiv->antdivf_rssitrig = trig; -} - -void ath_slow_ant_div_start(struct ath_antdiv *antdiv, - u8 num_antcfg, - const u8 *bssid) -{ - antdiv->antdiv_num_antcfg = - num_antcfg < ATH_ANT_DIV_MAX_CFG ? - num_antcfg : ATH_ANT_DIV_MAX_CFG; - antdiv->antdiv_state = ATH_ANT_DIV_IDLE; - antdiv->antdiv_curcfg = 0; - antdiv->antdiv_bestcfg = 0; - antdiv->antdiv_laststatetsf = 0; - - memcpy(antdiv->antdiv_bssid, bssid, sizeof(antdiv->antdiv_bssid)); - - antdiv->antdiv_start = 1; -} - -void ath_slow_ant_div_stop(struct ath_antdiv *antdiv) -{ - antdiv->antdiv_start = 0; -} - -static int32_t ath_find_max_val(int32_t *val, - u8 num_val, u8 *max_index) -{ - u32 MaxVal = *val++; - u32 cur_index = 0; - - *max_index = 0; - while (++cur_index < num_val) { - if (*val > MaxVal) { - MaxVal = *val; - *max_index = cur_index; - } - - val++; - } - - return MaxVal; -} - -void ath_slow_ant_div(struct ath_antdiv *antdiv, - struct ieee80211_hdr *hdr, - struct ath_rx_status *rx_stats) -{ - struct ath_softc *sc = antdiv->antdiv_sc; - struct ath_hal *ah = sc->sc_ah; - u64 curtsf = 0; - u8 bestcfg, curcfg = antdiv->antdiv_curcfg; - __le16 fc = hdr->frame_control; - - if (antdiv->antdiv_start && ieee80211_is_beacon(fc) - && !compare_ether_addr(hdr->addr3, antdiv->antdiv_bssid)) { - antdiv->antdiv_lastbrssi[curcfg] = rx_stats->rs_rssi; - antdiv->antdiv_lastbtsf[curcfg] = ath9k_hw_gettsf64(sc->sc_ah); - curtsf = antdiv->antdiv_lastbtsf[curcfg]; - } else { - return; - } - - switch (antdiv->antdiv_state) { - case ATH_ANT_DIV_IDLE: - if ((antdiv->antdiv_lastbrssi[curcfg] < - antdiv->antdivf_rssitrig) - && ((curtsf - antdiv->antdiv_laststatetsf) > - ATH_ANT_DIV_MIN_IDLE_US)) { - - curcfg++; - if (curcfg == antdiv->antdiv_num_antcfg) - curcfg = 0; - - if (!ath9k_hw_select_antconfig(ah, curcfg)) { - antdiv->antdiv_bestcfg = antdiv->antdiv_curcfg; - antdiv->antdiv_curcfg = curcfg; - antdiv->antdiv_laststatetsf = curtsf; - antdiv->antdiv_state = ATH_ANT_DIV_SCAN; - } - } - break; - - case ATH_ANT_DIV_SCAN: - if ((curtsf - antdiv->antdiv_laststatetsf) < - ATH_ANT_DIV_MIN_SCAN_US) - break; - - curcfg++; - if (curcfg == antdiv->antdiv_num_antcfg) - curcfg = 0; - - if (curcfg == antdiv->antdiv_bestcfg) { - ath_find_max_val(antdiv->antdiv_lastbrssi, - antdiv->antdiv_num_antcfg, &bestcfg); - if (!ath9k_hw_select_antconfig(ah, bestcfg)) { - antdiv->antdiv_bestcfg = bestcfg; - antdiv->antdiv_curcfg = bestcfg; - antdiv->antdiv_laststatetsf = curtsf; - antdiv->antdiv_state = ATH_ANT_DIV_IDLE; - } - } else { - if (!ath9k_hw_select_antconfig(ah, curcfg)) { - antdiv->antdiv_curcfg = curcfg; - antdiv->antdiv_laststatetsf = curtsf; - antdiv->antdiv_state = ATH_ANT_DIV_SCAN; - } - } - - break; - } -} - -/***********************/ -/* Descriptor Handling */ -/***********************/ - -/* - * Set up DMA descriptors - * - * This function will allocate both the DMA descriptor structure, and the - * buffers it contains. These are used to contain the descriptors used - * by the system. -*/ - -int ath_descdma_setup(struct ath_softc *sc, - struct ath_descdma *dd, - struct list_head *head, - const char *name, - int nbuf, - int ndesc) -{ -#define DS2PHYS(_dd, _ds) \ - ((_dd)->dd_desc_paddr + ((caddr_t)(_ds) - (caddr_t)(_dd)->dd_desc)) -#define ATH_DESC_4KB_BOUND_CHECK(_daddr) ((((_daddr) & 0xFFF) > 0xF7F) ? 1 : 0) -#define ATH_DESC_4KB_BOUND_NUM_SKIPPED(_len) ((_len) / 4096) - - struct ath_desc *ds; - struct ath_buf *bf; - int i, bsize, error; - - DPRINTF(sc, ATH_DBG_CONFIG, "%s: %s DMA: %u buffers %u desc/buf\n", - __func__, name, nbuf, ndesc); - - /* ath_desc must be a multiple of DWORDs */ - if ((sizeof(struct ath_desc) % 4) != 0) { - DPRINTF(sc, ATH_DBG_FATAL, "%s: ath_desc not DWORD aligned\n", - __func__); - ASSERT((sizeof(struct ath_desc) % 4) == 0); - error = -ENOMEM; - goto fail; - } - - dd->dd_name = name; - dd->dd_desc_len = sizeof(struct ath_desc) * nbuf * ndesc; - - /* - * Need additional DMA memory because we can't use - * descriptors that cross the 4K page boundary. Assume - * one skipped descriptor per 4K page. - */ - if (!(sc->sc_ah->ah_caps.hw_caps & ATH9K_HW_CAP_4KB_SPLITTRANS)) { - u32 ndesc_skipped = - ATH_DESC_4KB_BOUND_NUM_SKIPPED(dd->dd_desc_len); - u32 dma_len; - - while (ndesc_skipped) { - dma_len = ndesc_skipped * sizeof(struct ath_desc); - dd->dd_desc_len += dma_len; - - ndesc_skipped = ATH_DESC_4KB_BOUND_NUM_SKIPPED(dma_len); - }; - } - - /* allocate descriptors */ - dd->dd_desc = pci_alloc_consistent(sc->pdev, - dd->dd_desc_len, - &dd->dd_desc_paddr); - if (dd->dd_desc == NULL) { - error = -ENOMEM; - goto fail; - } - ds = dd->dd_desc; - DPRINTF(sc, ATH_DBG_CONFIG, "%s: %s DMA map: %p (%u) -> %llx (%u)\n", - __func__, dd->dd_name, ds, (u32) dd->dd_desc_len, - ito64(dd->dd_desc_paddr), /*XXX*/(u32) dd->dd_desc_len); - - /* allocate buffers */ - bsize = sizeof(struct ath_buf) * nbuf; - bf = kmalloc(bsize, GFP_KERNEL); - if (bf == NULL) { - error = -ENOMEM; - goto fail2; - } - memset(bf, 0, bsize); - dd->dd_bufptr = bf; - - INIT_LIST_HEAD(head); - for (i = 0; i < nbuf; i++, bf++, ds += ndesc) { - bf->bf_desc = ds; - bf->bf_daddr = DS2PHYS(dd, ds); - - if (!(sc->sc_ah->ah_caps.hw_caps & - ATH9K_HW_CAP_4KB_SPLITTRANS)) { - /* - * Skip descriptor addresses which can cause 4KB - * boundary crossing (addr + length) with a 32 dword - * descriptor fetch. - */ - while (ATH_DESC_4KB_BOUND_CHECK(bf->bf_daddr)) { - ASSERT((caddr_t) bf->bf_desc < - ((caddr_t) dd->dd_desc + - dd->dd_desc_len)); - - ds += ndesc; - bf->bf_desc = ds; - bf->bf_daddr = DS2PHYS(dd, ds); - } - } - list_add_tail(&bf->list, head); - } - return 0; -fail2: - pci_free_consistent(sc->pdev, - dd->dd_desc_len, dd->dd_desc, dd->dd_desc_paddr); -fail: - memset(dd, 0, sizeof(*dd)); - return error; -#undef ATH_DESC_4KB_BOUND_CHECK -#undef ATH_DESC_4KB_BOUND_NUM_SKIPPED -#undef DS2PHYS -} - -/* - * Cleanup DMA descriptors - * - * This function will free the DMA block that was allocated for the descriptor - * pool. Since this was allocated as one "chunk", it is freed in the same - * manner. -*/ - -void ath_descdma_cleanup(struct ath_softc *sc, - struct ath_descdma *dd, - struct list_head *head) -{ - /* Free memory associated with descriptors */ - pci_free_consistent(sc->pdev, - dd->dd_desc_len, dd->dd_desc, dd->dd_desc_paddr); - - INIT_LIST_HEAD(head); - kfree(dd->dd_bufptr); - memset(dd, 0, sizeof(*dd)); -} - -/*************/ -/* Utilities */ -/*************/ - -int ath_get_hal_qnum(u16 queue, struct ath_softc *sc) -{ - int qnum; - - switch (queue) { - case 0: - qnum = sc->sc_haltype2q[ATH9K_WME_AC_VO]; - break; - case 1: - qnum = sc->sc_haltype2q[ATH9K_WME_AC_VI]; - break; - case 2: - qnum = sc->sc_haltype2q[ATH9K_WME_AC_BE]; - break; - case 3: - qnum = sc->sc_haltype2q[ATH9K_WME_AC_BK]; - break; - default: - qnum = sc->sc_haltype2q[ATH9K_WME_AC_BE]; - break; - } - - return qnum; -} - -int ath_get_mac80211_qnum(u32 queue, struct ath_softc *sc) -{ - int qnum; - - switch (queue) { - case ATH9K_WME_AC_VO: - qnum = 0; - break; - case ATH9K_WME_AC_VI: - qnum = 1; - break; - case ATH9K_WME_AC_BE: - qnum = 2; - break; - case ATH9K_WME_AC_BK: - qnum = 3; - break; - default: - qnum = -1; - break; - } - - return qnum; -} - - -/* - * Expand time stamp to TSF - * - * Extend 15-bit time stamp from rx descriptor to - * a full 64-bit TSF using the current h/w TSF. -*/ - -u64 ath_extend_tsf(struct ath_softc *sc, u32 rstamp) -{ - u64 tsf; - - tsf = ath9k_hw_gettsf64(sc->sc_ah); - if ((tsf & 0x7fff) < rstamp) - tsf -= 0x8000; - return (tsf & ~0x7fff) | rstamp; -} - -/* - * Set Default Antenna - * - * Call into the HAL to set the default antenna to use. Not really valid for - * MIMO technology. -*/ - -void ath_setdefantenna(void *context, u32 antenna) -{ - struct ath_softc *sc = (struct ath_softc *)context; - struct ath_hal *ah = sc->sc_ah; - - /* XXX block beacon interrupts */ - ath9k_hw_setantenna(ah, antenna); - sc->sc_defant = antenna; - sc->sc_rxotherant = 0; -} - -/* - * Set Slot Time - * - * This will wake up the chip if required, and set the slot time for the - * frame (maximum transmit time). Slot time is assumed to be already set - * in the ATH object member sc_slottime -*/ - -void ath_setslottime(struct ath_softc *sc) -{ - ath9k_hw_setslottime(sc->sc_ah, sc->sc_slottime); - sc->sc_updateslot = OK; -} diff --git a/drivers/net/wireless/ath9k/core.h b/drivers/net/wireless/ath9k/core.h index e6725567109d..21ee0c240528 100644 --- a/drivers/net/wireless/ath9k/core.h +++ b/drivers/net/wireless/ath9k/core.h @@ -47,10 +47,6 @@ struct ath_node; -/******************/ -/* Utility macros */ -/******************/ - /* Macro to expand scalars to 64-bit objects */ #define ito64(x) (sizeof(x) == 8) ? \ @@ -86,11 +82,6 @@ struct ath_node; #define ATH_TXQ_SETUP(sc, i) ((sc)->sc_txqsetup & (1<= ((mul)/2)) ? ((x) + ((mul) - 1)) / (mul) : (x)/(mul)) -#define ATH_RSSI_OUT(x) \ - (((x) != ATH_RSSI_DUMMY_MARKER) ? \ - (ATH_EP_RND((x), ATH_RSSI_EP_MULTIPLIER)) : ATH_RSSI_DUMMY_MARKER) -#define ATH_RSSI_IN(x) \ - (ATH_EP_MUL((x), ATH_RSSI_EP_MULTIPLIER)) -#define ATH_LPF_RSSI(x, y, len) \ - ((x != ATH_RSSI_DUMMY_MARKER) ? \ - (((x) * ((len) - 1) + (y)) / (len)) : (y)) -#define ATH_RSSI_LPF(x, y) do { \ - if ((y) >= RSSI_LPF_THRESHOLD) \ - x = ATH_LPF_RSSI((x), \ - ATH_RSSI_IN((y)), ATH_RSSI_LPF_LEN); \ - } while (0) - +#define ATH_RSSI_DUMMY_MARKER 0x127 +#define ATH_RATE_DUMMY_MARKER 0 enum PROT_MODE { PROT_M_NONE = 0, @@ -748,12 +633,6 @@ enum PROT_MODE { PROT_M_CTSONLY }; -enum RATE_TYPE { - NORMAL_RATE = 0, - HALF_RATE, - QUARTER_RATE -}; - struct ath_ht_info { enum ath9k_ht_macmode tx_chan_width; u8 ext_chan_offset; @@ -881,27 +760,9 @@ struct ath_softc { struct ath_ani sc_ani; }; -int ath_init(u16 devid, struct ath_softc *sc); -int ath_open(struct ath_softc *sc, struct ath9k_channel *initial_chan); -void ath_stop(struct ath_softc *sc); -irqreturn_t ath_isr(int irq, void *dev); int ath_reset(struct ath_softc *sc, bool retry_tx); -int ath_set_channel(struct ath_softc *sc, struct ath9k_channel *hchan); - -/*********************/ -/* Utility Functions */ -/*********************/ - -void ath_key_reset(struct ath_softc *sc, u16 keyix, int freeslot); -int ath_keyset(struct ath_softc *sc, - u16 keyix, - struct ath9k_keyval *hk, - const u8 mac[ETH_ALEN]); int ath_get_hal_qnum(u16 queue, struct ath_softc *sc); int ath_get_mac80211_qnum(u32 queue, struct ath_softc *sc); -void ath_setslottime(struct ath_softc *sc); -void ath_update_txpow(struct ath_softc *sc); int ath_cabq_update(struct ath_softc *); -u64 ath_extend_tsf(struct ath_softc *sc, u32 rstamp); #endif /* CORE_H */ diff --git a/drivers/net/wireless/ath9k/main.c b/drivers/net/wireless/ath9k/main.c index 54d89abce478..f226a4daef75 100644 --- a/drivers/net/wireless/ath9k/main.c +++ b/drivers/net/wireless/ath9k/main.c @@ -14,8 +14,6 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* mac80211 and PCI callbacks */ - #include #include "core.h" #include "reg.h" @@ -40,6 +38,580 @@ static struct pci_device_id ath_pci_id_table[] __devinitdata = { static void ath_detach(struct ath_softc *sc); +/* return bus cachesize in 4B word units */ + +static void bus_read_cachesize(struct ath_softc *sc, int *csz) +{ + u8 u8tmp; + + pci_read_config_byte(sc->pdev, PCI_CACHE_LINE_SIZE, (u8 *)&u8tmp); + *csz = (int)u8tmp; + + /* + * This check was put in to avoid "unplesant" consequences if + * the bootrom has not fully initialized all PCI devices. + * Sometimes the cache line size register is not set + */ + + if (*csz == 0) + *csz = DEFAULT_CACHELINE >> 2; /* Use the default size */ +} + +static void ath_setcurmode(struct ath_softc *sc, enum wireless_mode mode) +{ + sc->sc_curmode = mode; + /* + * All protection frames are transmited at 2Mb/s for + * 11g, otherwise at 1Mb/s. + * XXX select protection rate index from rate table. + */ + sc->sc_protrix = (mode == ATH9K_MODE_11G ? 1 : 0); +} + +static enum wireless_mode ath_chan2mode(struct ath9k_channel *chan) +{ + if (chan->chanmode == CHANNEL_A) + return ATH9K_MODE_11A; + else if (chan->chanmode == CHANNEL_G) + return ATH9K_MODE_11G; + else if (chan->chanmode == CHANNEL_B) + return ATH9K_MODE_11B; + else if (chan->chanmode == CHANNEL_A_HT20) + return ATH9K_MODE_11NA_HT20; + else if (chan->chanmode == CHANNEL_G_HT20) + return ATH9K_MODE_11NG_HT20; + else if (chan->chanmode == CHANNEL_A_HT40PLUS) + return ATH9K_MODE_11NA_HT40PLUS; + else if (chan->chanmode == CHANNEL_A_HT40MINUS) + return ATH9K_MODE_11NA_HT40MINUS; + else if (chan->chanmode == CHANNEL_G_HT40PLUS) + return ATH9K_MODE_11NG_HT40PLUS; + else if (chan->chanmode == CHANNEL_G_HT40MINUS) + return ATH9K_MODE_11NG_HT40MINUS; + + WARN_ON(1); /* should not get here */ + + return ATH9K_MODE_11B; +} + +static void ath_update_txpow(struct ath_softc *sc) +{ + struct ath_hal *ah = sc->sc_ah; + u32 txpow; + + if (sc->sc_curtxpow != sc->sc_config.txpowlimit) { + ath9k_hw_set_txpowerlimit(ah, sc->sc_config.txpowlimit); + /* read back in case value is clamped */ + ath9k_hw_getcapability(ah, ATH9K_CAP_TXPOW, 1, &txpow); + sc->sc_curtxpow = txpow; + } +} + +static u8 parse_mpdudensity(u8 mpdudensity) +{ + /* + * 802.11n D2.0 defined values for "Minimum MPDU Start Spacing": + * 0 for no restriction + * 1 for 1/4 us + * 2 for 1/2 us + * 3 for 1 us + * 4 for 2 us + * 5 for 4 us + * 6 for 8 us + * 7 for 16 us + */ + switch (mpdudensity) { + case 0: + return 0; + case 1: + case 2: + case 3: + /* Our lower layer calculations limit our precision to + 1 microsecond */ + return 1; + case 4: + return 2; + case 5: + return 4; + case 6: + return 8; + case 7: + return 16; + default: + return 0; + } +} + +static void ath_setup_rates(struct ath_softc *sc, enum ieee80211_band band) +{ + struct ath_rate_table *rate_table = NULL; + struct ieee80211_supported_band *sband; + struct ieee80211_rate *rate; + int i, maxrates; + + switch (band) { + case IEEE80211_BAND_2GHZ: + rate_table = sc->hw_rate_table[ATH9K_MODE_11G]; + break; + case IEEE80211_BAND_5GHZ: + rate_table = sc->hw_rate_table[ATH9K_MODE_11A]; + break; + default: + break; + } + + if (rate_table == NULL) + return; + + sband = &sc->sbands[band]; + rate = sc->rates[band]; + + if (rate_table->rate_cnt > ATH_RATE_MAX) + maxrates = ATH_RATE_MAX; + else + maxrates = rate_table->rate_cnt; + + for (i = 0; i < maxrates; i++) { + rate[i].bitrate = rate_table->info[i].ratekbps / 100; + rate[i].hw_value = rate_table->info[i].ratecode; + sband->n_bitrates++; + DPRINTF(sc, ATH_DBG_CONFIG, "%s: Rate: %2dMbps, ratecode: %2d\n", + __func__, rate[i].bitrate / 10, rate[i].hw_value); + } +} + +static int ath_setup_channels(struct ath_softc *sc) +{ + struct ath_hal *ah = sc->sc_ah; + int nchan, i, a = 0, b = 0; + u8 regclassids[ATH_REGCLASSIDS_MAX]; + u32 nregclass = 0; + struct ieee80211_supported_band *band_2ghz; + struct ieee80211_supported_band *band_5ghz; + struct ieee80211_channel *chan_2ghz; + struct ieee80211_channel *chan_5ghz; + struct ath9k_channel *c; + + /* Fill in ah->ah_channels */ + if (!ath9k_regd_init_channels(ah, ATH_CHAN_MAX, (u32 *)&nchan, + regclassids, ATH_REGCLASSIDS_MAX, + &nregclass, CTRY_DEFAULT, false, 1)) { + u32 rd = ah->ah_currentRD; + DPRINTF(sc, ATH_DBG_FATAL, + "%s: unable to collect channel list; " + "regdomain likely %u country code %u\n", + __func__, rd, CTRY_DEFAULT); + return -EINVAL; + } + + band_2ghz = &sc->sbands[IEEE80211_BAND_2GHZ]; + band_5ghz = &sc->sbands[IEEE80211_BAND_5GHZ]; + chan_2ghz = sc->channels[IEEE80211_BAND_2GHZ]; + chan_5ghz = sc->channels[IEEE80211_BAND_5GHZ]; + + for (i = 0; i < nchan; i++) { + c = &ah->ah_channels[i]; + if (IS_CHAN_2GHZ(c)) { + chan_2ghz[a].band = IEEE80211_BAND_2GHZ; + chan_2ghz[a].center_freq = c->channel; + chan_2ghz[a].max_power = c->maxTxPower; + + if (c->privFlags & CHANNEL_DISALLOW_ADHOC) + chan_2ghz[a].flags |= IEEE80211_CHAN_NO_IBSS; + if (c->channelFlags & CHANNEL_PASSIVE) + chan_2ghz[a].flags |= IEEE80211_CHAN_PASSIVE_SCAN; + + band_2ghz->n_channels = ++a; + + DPRINTF(sc, ATH_DBG_CONFIG, "%s: 2MHz channel: %d, " + "channelFlags: 0x%x\n", + __func__, c->channel, c->channelFlags); + } else if (IS_CHAN_5GHZ(c)) { + chan_5ghz[b].band = IEEE80211_BAND_5GHZ; + chan_5ghz[b].center_freq = c->channel; + chan_5ghz[b].max_power = c->maxTxPower; + + if (c->privFlags & CHANNEL_DISALLOW_ADHOC) + chan_5ghz[b].flags |= IEEE80211_CHAN_NO_IBSS; + if (c->channelFlags & CHANNEL_PASSIVE) + chan_5ghz[b].flags |= IEEE80211_CHAN_PASSIVE_SCAN; + + band_5ghz->n_channels = ++b; + + DPRINTF(sc, ATH_DBG_CONFIG, "%s: 5MHz channel: %d, " + "channelFlags: 0x%x\n", + __func__, c->channel, c->channelFlags); + } + } + + return 0; +} + +/* + * Set/change channels. If the channel is really being changed, it's done + * by reseting the chip. To accomplish this we must first cleanup any pending + * DMA, then restart stuff. +*/ +static int ath_set_channel(struct ath_softc *sc, struct ath9k_channel *hchan) +{ + struct ath_hal *ah = sc->sc_ah; + bool fastcc = true, stopped; + + if (sc->sc_flags & SC_OP_INVALID) + return -EIO; + + DPRINTF(sc, ATH_DBG_CONFIG, + "%s: %u (%u MHz) -> %u (%u MHz), cflags:%x\n", + __func__, + ath9k_hw_mhz2ieee(ah, sc->sc_ah->ah_curchan->channel, + sc->sc_ah->ah_curchan->channelFlags), + sc->sc_ah->ah_curchan->channel, + ath9k_hw_mhz2ieee(ah, hchan->channel, hchan->channelFlags), + hchan->channel, hchan->channelFlags); + + if (hchan->channel != sc->sc_ah->ah_curchan->channel || + hchan->channelFlags != sc->sc_ah->ah_curchan->channelFlags || + (sc->sc_flags & SC_OP_CHAINMASK_UPDATE) || + (sc->sc_flags & SC_OP_FULL_RESET)) { + int status; + /* + * This is only performed if the channel settings have + * actually changed. + * + * To switch channels clear any pending DMA operations; + * wait long enough for the RX fifo to drain, reset the + * hardware at the new frequency, and then re-enable + * the relevant bits of the h/w. + */ + ath9k_hw_set_interrupts(ah, 0); /* disable interrupts */ + ath_draintxq(sc, false); /* clear pending tx frames */ + stopped = ath_stoprecv(sc); /* turn off frame recv */ + + /* XXX: do not flush receive queue here. We don't want + * to flush data frames already in queue because of + * changing channel. */ + + if (!stopped || (sc->sc_flags & SC_OP_FULL_RESET)) + fastcc = false; + + spin_lock_bh(&sc->sc_resetlock); + if (!ath9k_hw_reset(ah, hchan, sc->sc_ht_info.tx_chan_width, + sc->sc_tx_chainmask, sc->sc_rx_chainmask, + sc->sc_ht_extprotspacing, fastcc, &status)) { + DPRINTF(sc, ATH_DBG_FATAL, + "%s: unable to reset channel %u (%uMhz) " + "flags 0x%x hal status %u\n", __func__, + ath9k_hw_mhz2ieee(ah, hchan->channel, + hchan->channelFlags), + hchan->channel, hchan->channelFlags, status); + spin_unlock_bh(&sc->sc_resetlock); + return -EIO; + } + spin_unlock_bh(&sc->sc_resetlock); + + sc->sc_flags &= ~SC_OP_CHAINMASK_UPDATE; + sc->sc_flags &= ~SC_OP_FULL_RESET; + + if (ath_startrecv(sc) != 0) { + DPRINTF(sc, ATH_DBG_FATAL, + "%s: unable to restart recv logic\n", __func__); + return -EIO; + } + + ath_setcurmode(sc, ath_chan2mode(hchan)); + ath_update_txpow(sc); + ath9k_hw_set_interrupts(ah, sc->sc_imask); + } + return 0; +} + +/* + * This routine performs the periodic noise floor calibration function + * that is used to adjust and optimize the chip performance. This + * takes environmental changes (location, temperature) into account. + * When the task is complete, it reschedules itself depending on the + * appropriate interval that was calculated. + */ +static void ath_ani_calibrate(unsigned long data) +{ + struct ath_softc *sc; + struct ath_hal *ah; + bool longcal = false; + bool shortcal = false; + bool aniflag = false; + unsigned int timestamp = jiffies_to_msecs(jiffies); + u32 cal_interval; + + sc = (struct ath_softc *)data; + ah = sc->sc_ah; + + /* + * don't calibrate when we're scanning. + * we are most likely not on our home channel. + */ + if (sc->rx_filter & FIF_BCN_PRBRESP_PROMISC) + return; + + /* Long calibration runs independently of short calibration. */ + if ((timestamp - sc->sc_ani.sc_longcal_timer) >= ATH_LONG_CALINTERVAL) { + longcal = true; + DPRINTF(sc, ATH_DBG_ANI, "%s: longcal @%lu\n", + __func__, jiffies); + sc->sc_ani.sc_longcal_timer = timestamp; + } + + /* Short calibration applies only while sc_caldone is false */ + if (!sc->sc_ani.sc_caldone) { + if ((timestamp - sc->sc_ani.sc_shortcal_timer) >= + ATH_SHORT_CALINTERVAL) { + shortcal = true; + DPRINTF(sc, ATH_DBG_ANI, "%s: shortcal @%lu\n", + __func__, jiffies); + sc->sc_ani.sc_shortcal_timer = timestamp; + sc->sc_ani.sc_resetcal_timer = timestamp; + } + } else { + if ((timestamp - sc->sc_ani.sc_resetcal_timer) >= + ATH_RESTART_CALINTERVAL) { + ath9k_hw_reset_calvalid(ah, ah->ah_curchan, + &sc->sc_ani.sc_caldone); + if (sc->sc_ani.sc_caldone) + sc->sc_ani.sc_resetcal_timer = timestamp; + } + } + + /* Verify whether we must check ANI */ + if ((timestamp - sc->sc_ani.sc_checkani_timer) >= + ATH_ANI_POLLINTERVAL) { + aniflag = true; + sc->sc_ani.sc_checkani_timer = timestamp; + } + + /* Skip all processing if there's nothing to do. */ + if (longcal || shortcal || aniflag) { + /* Call ANI routine if necessary */ + if (aniflag) + ath9k_hw_ani_monitor(ah, &sc->sc_halstats, + ah->ah_curchan); + + /* Perform calibration if necessary */ + if (longcal || shortcal) { + bool iscaldone = false; + + if (ath9k_hw_calibrate(ah, ah->ah_curchan, + sc->sc_rx_chainmask, longcal, + &iscaldone)) { + if (longcal) + sc->sc_ani.sc_noise_floor = + ath9k_hw_getchan_noise(ah, + ah->ah_curchan); + + DPRINTF(sc, ATH_DBG_ANI, + "%s: calibrate chan %u/%x nf: %d\n", + __func__, + ah->ah_curchan->channel, + ah->ah_curchan->channelFlags, + sc->sc_ani.sc_noise_floor); + } else { + DPRINTF(sc, ATH_DBG_ANY, + "%s: calibrate chan %u/%x failed\n", + __func__, + ah->ah_curchan->channel, + ah->ah_curchan->channelFlags); + } + sc->sc_ani.sc_caldone = iscaldone; + } + } + + /* + * Set timer interval based on previous results. + * The interval must be the shortest necessary to satisfy ANI, + * short calibration and long calibration. + */ + + cal_interval = ATH_ANI_POLLINTERVAL; + if (!sc->sc_ani.sc_caldone) + cal_interval = min(cal_interval, (u32)ATH_SHORT_CALINTERVAL); + + mod_timer(&sc->sc_ani.timer, jiffies + msecs_to_jiffies(cal_interval)); +} + +/* + * Update tx/rx chainmask. For legacy association, + * hard code chainmask to 1x1, for 11n association, use + * the chainmask configuration. + */ +static void ath_update_chainmask(struct ath_softc *sc, int is_ht) +{ + sc->sc_flags |= SC_OP_CHAINMASK_UPDATE; + if (is_ht) { + sc->sc_tx_chainmask = sc->sc_ah->ah_caps.tx_chainmask; + sc->sc_rx_chainmask = sc->sc_ah->ah_caps.rx_chainmask; + } else { + sc->sc_tx_chainmask = 1; + sc->sc_rx_chainmask = 1; + } + + DPRINTF(sc, ATH_DBG_CONFIG, "%s: tx chmask: %d, rx chmask: %d\n", + __func__, sc->sc_tx_chainmask, sc->sc_rx_chainmask); +} + +static void ath_node_attach(struct ath_softc *sc, struct ieee80211_sta *sta) +{ + struct ath_node *an; + + an = (struct ath_node *)sta->drv_priv; + + if (sc->sc_flags & SC_OP_TXAGGR) + ath_tx_node_init(sc, an); + + an->maxampdu = 1 << (IEEE80211_HTCAP_MAXRXAMPDU_FACTOR + + sta->ht_cap.ampdu_factor); + an->mpdudensity = parse_mpdudensity(sta->ht_cap.ampdu_density); +} + +static void ath_node_detach(struct ath_softc *sc, struct ieee80211_sta *sta) +{ + struct ath_node *an = (struct ath_node *)sta->drv_priv; + + if (sc->sc_flags & SC_OP_TXAGGR) + ath_tx_node_cleanup(sc, an); +} + +static void ath9k_tasklet(unsigned long data) +{ + struct ath_softc *sc = (struct ath_softc *)data; + u32 status = sc->sc_intrstatus; + + if (status & ATH9K_INT_FATAL) { + /* need a chip reset */ + ath_reset(sc, false); + return; + } else { + + if (status & + (ATH9K_INT_RX | ATH9K_INT_RXEOL | ATH9K_INT_RXORN)) { + spin_lock_bh(&sc->sc_rxflushlock); + ath_rx_tasklet(sc, 0); + spin_unlock_bh(&sc->sc_rxflushlock); + } + /* XXX: optimize this */ + if (status & ATH9K_INT_TX) + ath_tx_tasklet(sc); + } + + /* re-enable hardware interrupt */ + ath9k_hw_set_interrupts(sc->sc_ah, sc->sc_imask); +} + +static irqreturn_t ath_isr(int irq, void *dev) +{ + struct ath_softc *sc = dev; + struct ath_hal *ah = sc->sc_ah; + enum ath9k_int status; + bool sched = false; + + do { + if (sc->sc_flags & SC_OP_INVALID) { + /* + * The hardware is not ready/present, don't + * touch anything. Note this can happen early + * on if the IRQ is shared. + */ + return IRQ_NONE; + } + if (!ath9k_hw_intrpend(ah)) { /* shared irq, not for us */ + return IRQ_NONE; + } + + /* + * Figure out the reason(s) for the interrupt. Note + * that the hal returns a pseudo-ISR that may include + * bits we haven't explicitly enabled so we mask the + * value to insure we only process bits we requested. + */ + ath9k_hw_getisr(ah, &status); /* NB: clears ISR too */ + + status &= sc->sc_imask; /* discard unasked-for bits */ + + /* + * If there are no status bits set, then this interrupt was not + * for me (should have been caught above). + */ + if (!status) + return IRQ_NONE; + + sc->sc_intrstatus = status; + + if (status & ATH9K_INT_FATAL) { + /* need a chip reset */ + sched = true; + } else if (status & ATH9K_INT_RXORN) { + /* need a chip reset */ + sched = true; + } else { + if (status & ATH9K_INT_SWBA) { + /* schedule a tasklet for beacon handling */ + tasklet_schedule(&sc->bcon_tasklet); + } + if (status & ATH9K_INT_RXEOL) { + /* + * NB: the hardware should re-read the link when + * RXE bit is written, but it doesn't work + * at least on older hardware revs. + */ + sched = true; + } + + if (status & ATH9K_INT_TXURN) + /* bump tx trigger level */ + ath9k_hw_updatetxtriglevel(ah, true); + /* XXX: optimize this */ + if (status & ATH9K_INT_RX) + sched = true; + if (status & ATH9K_INT_TX) + sched = true; + if (status & ATH9K_INT_BMISS) + sched = true; + /* carrier sense timeout */ + if (status & ATH9K_INT_CST) + sched = true; + if (status & ATH9K_INT_MIB) { + /* + * Disable interrupts until we service the MIB + * interrupt; otherwise it will continue to + * fire. + */ + ath9k_hw_set_interrupts(ah, 0); + /* + * Let the hal handle the event. We assume + * it will clear whatever condition caused + * the interrupt. + */ + ath9k_hw_procmibevent(ah, &sc->sc_halstats); + ath9k_hw_set_interrupts(ah, sc->sc_imask); + } + if (status & ATH9K_INT_TIM_TIMER) { + if (!(ah->ah_caps.hw_caps & + ATH9K_HW_CAP_AUTOSLEEP)) { + /* Clear RxAbort bit so that we can + * receive frames */ + ath9k_hw_setrxabort(ah, 0); + sched = true; + } + } + } + } while (0); + + if (sched) { + /* turn off every interrupt except SWBA */ + ath9k_hw_set_interrupts(ah, (sc->sc_imask & ATH9K_INT_SWBA)); + tasklet_schedule(&sc->intr_tq); + } + + return IRQ_HANDLED; +} + static int ath_get_channel(struct ath_softc *sc, struct ieee80211_channel *chan) { @@ -90,6 +662,23 @@ static u32 ath_get_extchanmode(struct ath_softc *sc, return chanmode; } +static void ath_key_reset(struct ath_softc *sc, u16 keyix, int freeslot) +{ + ath9k_hw_keyreset(sc->sc_ah, keyix); + if (freeslot) + clear_bit(keyix, sc->sc_keymap); +} + +static int ath_keyset(struct ath_softc *sc, u16 keyix, + struct ath9k_keyval *hk, const u8 mac[ETH_ALEN]) +{ + bool status; + + status = ath9k_hw_set_keycache_entry(sc->sc_ah, + keyix, hk, mac, false); + + return status != false; +} static int ath_setkey_tkip(struct ath_softc *sc, struct ieee80211_key_conf *key, @@ -327,20 +916,6 @@ static void ath9k_bss_assoc_info(struct ath_softc *sc, } } -void ath_get_beaconconfig(struct ath_softc *sc, - int if_id, - struct ath_beacon_config *conf) -{ - struct ieee80211_hw *hw = sc->hw; - - /* fill in beacon config data */ - - conf->beacon_interval = hw->conf.beacon_int; - conf->listen_interval = 100; - conf->dtim_count = 1; - conf->bmiss_timeout = ATH_DEFAULT_BMISS_LIMIT * conf->listen_interval; -} - /********************************/ /* LED functions */ /********************************/ @@ -722,6 +1297,244 @@ static void ath_detach(struct ath_softc *sc) ath9k_hw_detach(sc->sc_ah); } +static int ath_init(u16 devid, struct ath_softc *sc) +{ + struct ath_hal *ah = NULL; + int status; + int error = 0, i; + int csz = 0; + + /* XXX: hardware will not be ready until ath_open() being called */ + sc->sc_flags |= SC_OP_INVALID; + sc->sc_debug = DBG_DEFAULT; + + spin_lock_init(&sc->sc_resetlock); + tasklet_init(&sc->intr_tq, ath9k_tasklet, (unsigned long)sc); + tasklet_init(&sc->bcon_tasklet, ath9k_beacon_tasklet, + (unsigned long)sc); + + /* + * Cache line size is used to size and align various + * structures used to communicate with the hardware. + */ + bus_read_cachesize(sc, &csz); + /* XXX assert csz is non-zero */ + sc->sc_cachelsz = csz << 2; /* convert to bytes */ + + ah = ath9k_hw_attach(devid, sc, sc->mem, &status); + if (ah == NULL) { + DPRINTF(sc, ATH_DBG_FATAL, + "%s: unable to attach hardware; HAL status %u\n", + __func__, status); + error = -ENXIO; + goto bad; + } + sc->sc_ah = ah; + + /* Get the hardware key cache size. */ + sc->sc_keymax = ah->ah_caps.keycache_size; + if (sc->sc_keymax > ATH_KEYMAX) { + DPRINTF(sc, ATH_DBG_KEYCACHE, + "%s: Warning, using only %u entries in %u key cache\n", + __func__, ATH_KEYMAX, sc->sc_keymax); + sc->sc_keymax = ATH_KEYMAX; + } + + /* + * Reset the key cache since some parts do not + * reset the contents on initial power up. + */ + for (i = 0; i < sc->sc_keymax; i++) + ath9k_hw_keyreset(ah, (u16) i); + /* + * Mark key cache slots associated with global keys + * as in use. If we knew TKIP was not to be used we + * could leave the +32, +64, and +32+64 slots free. + * XXX only for splitmic. + */ + for (i = 0; i < IEEE80211_WEP_NKID; i++) { + set_bit(i, sc->sc_keymap); + set_bit(i + 32, sc->sc_keymap); + set_bit(i + 64, sc->sc_keymap); + set_bit(i + 32 + 64, sc->sc_keymap); + } + + /* Collect the channel list using the default country code */ + + error = ath_setup_channels(sc); + if (error) + goto bad; + + /* default to MONITOR mode */ + sc->sc_ah->ah_opmode = ATH9K_M_MONITOR; + + /* Setup rate tables */ + + ath_rate_attach(sc); + ath_setup_rates(sc, IEEE80211_BAND_2GHZ); + ath_setup_rates(sc, IEEE80211_BAND_5GHZ); + + /* + * Allocate hardware transmit queues: one queue for + * beacon frames and one data queue for each QoS + * priority. Note that the hal handles reseting + * these queues at the needed time. + */ + sc->sc_bhalq = ath_beaconq_setup(ah); + if (sc->sc_bhalq == -1) { + DPRINTF(sc, ATH_DBG_FATAL, + "%s: unable to setup a beacon xmit queue\n", __func__); + error = -EIO; + goto bad2; + } + sc->sc_cabq = ath_txq_setup(sc, ATH9K_TX_QUEUE_CAB, 0); + if (sc->sc_cabq == NULL) { + DPRINTF(sc, ATH_DBG_FATAL, + "%s: unable to setup CAB xmit queue\n", __func__); + error = -EIO; + goto bad2; + } + + sc->sc_config.cabqReadytime = ATH_CABQ_READY_TIME; + ath_cabq_update(sc); + + for (i = 0; i < ARRAY_SIZE(sc->sc_haltype2q); i++) + sc->sc_haltype2q[i] = -1; + + /* Setup data queues */ + /* NB: ensure BK queue is the lowest priority h/w queue */ + if (!ath_tx_setup(sc, ATH9K_WME_AC_BK)) { + DPRINTF(sc, ATH_DBG_FATAL, + "%s: unable to setup xmit queue for BK traffic\n", + __func__); + error = -EIO; + goto bad2; + } + + if (!ath_tx_setup(sc, ATH9K_WME_AC_BE)) { + DPRINTF(sc, ATH_DBG_FATAL, + "%s: unable to setup xmit queue for BE traffic\n", + __func__); + error = -EIO; + goto bad2; + } + if (!ath_tx_setup(sc, ATH9K_WME_AC_VI)) { + DPRINTF(sc, ATH_DBG_FATAL, + "%s: unable to setup xmit queue for VI traffic\n", + __func__); + error = -EIO; + goto bad2; + } + if (!ath_tx_setup(sc, ATH9K_WME_AC_VO)) { + DPRINTF(sc, ATH_DBG_FATAL, + "%s: unable to setup xmit queue for VO traffic\n", + __func__); + error = -EIO; + goto bad2; + } + + /* Initializes the noise floor to a reasonable default value. + * Later on this will be updated during ANI processing. */ + + sc->sc_ani.sc_noise_floor = ATH_DEFAULT_NOISE_FLOOR; + setup_timer(&sc->sc_ani.timer, ath_ani_calibrate, (unsigned long)sc); + + if (ath9k_hw_getcapability(ah, ATH9K_CAP_CIPHER, + ATH9K_CIPHER_TKIP, NULL)) { + /* + * Whether we should enable h/w TKIP MIC. + * XXX: if we don't support WME TKIP MIC, then we wouldn't + * report WMM capable, so it's always safe to turn on + * TKIP MIC in this case. + */ + ath9k_hw_setcapability(sc->sc_ah, ATH9K_CAP_TKIP_MIC, + 0, 1, NULL); + } + + /* + * Check whether the separate key cache entries + * are required to handle both tx+rx MIC keys. + * With split mic keys the number of stations is limited + * to 27 otherwise 59. + */ + if (ath9k_hw_getcapability(ah, ATH9K_CAP_CIPHER, + ATH9K_CIPHER_TKIP, NULL) + && ath9k_hw_getcapability(ah, ATH9K_CAP_CIPHER, + ATH9K_CIPHER_MIC, NULL) + && ath9k_hw_getcapability(ah, ATH9K_CAP_TKIP_SPLIT, + 0, NULL)) + sc->sc_splitmic = 1; + + /* turn on mcast key search if possible */ + if (!ath9k_hw_getcapability(ah, ATH9K_CAP_MCAST_KEYSRCH, 0, NULL)) + (void)ath9k_hw_setcapability(ah, ATH9K_CAP_MCAST_KEYSRCH, 1, + 1, NULL); + + sc->sc_config.txpowlimit = ATH_TXPOWER_MAX; + sc->sc_config.txpowlimit_override = 0; + + /* 11n Capabilities */ + if (ah->ah_caps.hw_caps & ATH9K_HW_CAP_HT) { + sc->sc_flags |= SC_OP_TXAGGR; + sc->sc_flags |= SC_OP_RXAGGR; + } + + sc->sc_tx_chainmask = ah->ah_caps.tx_chainmask; + sc->sc_rx_chainmask = ah->ah_caps.rx_chainmask; + + ath9k_hw_setcapability(ah, ATH9K_CAP_DIVERSITY, 1, true, NULL); + sc->sc_defant = ath9k_hw_getdefantenna(ah); + + ath9k_hw_getmac(ah, sc->sc_myaddr); + if (ah->ah_caps.hw_caps & ATH9K_HW_CAP_BSSIDMASK) { + ath9k_hw_getbssidmask(ah, sc->sc_bssidmask); + ATH_SET_VAP_BSSID_MASK(sc->sc_bssidmask); + ath9k_hw_setbssidmask(ah, sc->sc_bssidmask); + } + + sc->sc_slottime = ATH9K_SLOT_TIME_9; /* default to short slot time */ + + /* initialize beacon slots */ + for (i = 0; i < ARRAY_SIZE(sc->sc_bslot); i++) + sc->sc_bslot[i] = ATH_IF_ID_ANY; + + /* save MISC configurations */ + sc->sc_config.swBeaconProcess = 1; + +#ifdef CONFIG_SLOW_ANT_DIV + /* range is 40 - 255, we use something in the middle */ + ath_slow_ant_div_init(&sc->sc_antdiv, sc, 0x127); +#endif + + /* setup channels and rates */ + + sc->sbands[IEEE80211_BAND_2GHZ].channels = + sc->channels[IEEE80211_BAND_2GHZ]; + sc->sbands[IEEE80211_BAND_2GHZ].bitrates = + sc->rates[IEEE80211_BAND_2GHZ]; + sc->sbands[IEEE80211_BAND_2GHZ].band = IEEE80211_BAND_2GHZ; + + if (test_bit(ATH9K_MODE_11A, sc->sc_ah->ah_caps.wireless_modes)) { + sc->sbands[IEEE80211_BAND_5GHZ].channels = + sc->channels[IEEE80211_BAND_5GHZ]; + sc->sbands[IEEE80211_BAND_5GHZ].bitrates = + sc->rates[IEEE80211_BAND_5GHZ]; + sc->sbands[IEEE80211_BAND_5GHZ].band = IEEE80211_BAND_5GHZ; + } + + return 0; +bad2: + /* cleanup tx queues */ + for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) + if (ATH_TXQ_SETUP(sc, i)) + ath_tx_cleanupq(sc, &sc->sc_txq[i]); +bad: + if (ah) + ath9k_hw_detach(ah); + + return error; +} + static int ath_attach(u16 devid, struct ath_softc *sc) { struct ieee80211_hw *hw = sc->hw; @@ -810,11 +1623,243 @@ bad: return error; } +int ath_reset(struct ath_softc *sc, bool retry_tx) +{ + struct ath_hal *ah = sc->sc_ah; + int status; + int error = 0; + + ath9k_hw_set_interrupts(ah, 0); + ath_draintxq(sc, retry_tx); + ath_stoprecv(sc); + ath_flushrecv(sc); + + spin_lock_bh(&sc->sc_resetlock); + if (!ath9k_hw_reset(ah, sc->sc_ah->ah_curchan, + sc->sc_ht_info.tx_chan_width, + sc->sc_tx_chainmask, sc->sc_rx_chainmask, + sc->sc_ht_extprotspacing, false, &status)) { + DPRINTF(sc, ATH_DBG_FATAL, + "%s: unable to reset hardware; hal status %u\n", + __func__, status); + error = -EIO; + } + spin_unlock_bh(&sc->sc_resetlock); + + if (ath_startrecv(sc) != 0) + DPRINTF(sc, ATH_DBG_FATAL, + "%s: unable to start recv logic\n", __func__); + + /* + * We may be doing a reset in response to a request + * that changes the channel so update any state that + * might change as a result. + */ + ath_setcurmode(sc, ath_chan2mode(sc->sc_ah->ah_curchan)); + + ath_update_txpow(sc); + + if (sc->sc_flags & SC_OP_BEACONS) + ath_beacon_config(sc, ATH_IF_ID_ANY); /* restart beacons */ + + ath9k_hw_set_interrupts(ah, sc->sc_imask); + + if (retry_tx) { + int i; + for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) { + if (ATH_TXQ_SETUP(sc, i)) { + spin_lock_bh(&sc->sc_txq[i].axq_lock); + ath_txq_schedule(sc, &sc->sc_txq[i]); + spin_unlock_bh(&sc->sc_txq[i].axq_lock); + } + } + } + + return error; +} + +/* + * This function will allocate both the DMA descriptor structure, and the + * buffers it contains. These are used to contain the descriptors used + * by the system. +*/ +int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd, + struct list_head *head, const char *name, + int nbuf, int ndesc) +{ +#define DS2PHYS(_dd, _ds) \ + ((_dd)->dd_desc_paddr + ((caddr_t)(_ds) - (caddr_t)(_dd)->dd_desc)) +#define ATH_DESC_4KB_BOUND_CHECK(_daddr) ((((_daddr) & 0xFFF) > 0xF7F) ? 1 : 0) +#define ATH_DESC_4KB_BOUND_NUM_SKIPPED(_len) ((_len) / 4096) + + struct ath_desc *ds; + struct ath_buf *bf; + int i, bsize, error; + + DPRINTF(sc, ATH_DBG_CONFIG, "%s: %s DMA: %u buffers %u desc/buf\n", + __func__, name, nbuf, ndesc); + + /* ath_desc must be a multiple of DWORDs */ + if ((sizeof(struct ath_desc) % 4) != 0) { + DPRINTF(sc, ATH_DBG_FATAL, "%s: ath_desc not DWORD aligned\n", + __func__); + ASSERT((sizeof(struct ath_desc) % 4) == 0); + error = -ENOMEM; + goto fail; + } + + dd->dd_name = name; + dd->dd_desc_len = sizeof(struct ath_desc) * nbuf * ndesc; + + /* + * Need additional DMA memory because we can't use + * descriptors that cross the 4K page boundary. Assume + * one skipped descriptor per 4K page. + */ + if (!(sc->sc_ah->ah_caps.hw_caps & ATH9K_HW_CAP_4KB_SPLITTRANS)) { + u32 ndesc_skipped = + ATH_DESC_4KB_BOUND_NUM_SKIPPED(dd->dd_desc_len); + u32 dma_len; + + while (ndesc_skipped) { + dma_len = ndesc_skipped * sizeof(struct ath_desc); + dd->dd_desc_len += dma_len; + + ndesc_skipped = ATH_DESC_4KB_BOUND_NUM_SKIPPED(dma_len); + }; + } + + /* allocate descriptors */ + dd->dd_desc = pci_alloc_consistent(sc->pdev, + dd->dd_desc_len, + &dd->dd_desc_paddr); + if (dd->dd_desc == NULL) { + error = -ENOMEM; + goto fail; + } + ds = dd->dd_desc; + DPRINTF(sc, ATH_DBG_CONFIG, "%s: %s DMA map: %p (%u) -> %llx (%u)\n", + __func__, dd->dd_name, ds, (u32) dd->dd_desc_len, + ito64(dd->dd_desc_paddr), /*XXX*/(u32) dd->dd_desc_len); + + /* allocate buffers */ + bsize = sizeof(struct ath_buf) * nbuf; + bf = kmalloc(bsize, GFP_KERNEL); + if (bf == NULL) { + error = -ENOMEM; + goto fail2; + } + memset(bf, 0, bsize); + dd->dd_bufptr = bf; + + INIT_LIST_HEAD(head); + for (i = 0; i < nbuf; i++, bf++, ds += ndesc) { + bf->bf_desc = ds; + bf->bf_daddr = DS2PHYS(dd, ds); + + if (!(sc->sc_ah->ah_caps.hw_caps & + ATH9K_HW_CAP_4KB_SPLITTRANS)) { + /* + * Skip descriptor addresses which can cause 4KB + * boundary crossing (addr + length) with a 32 dword + * descriptor fetch. + */ + while (ATH_DESC_4KB_BOUND_CHECK(bf->bf_daddr)) { + ASSERT((caddr_t) bf->bf_desc < + ((caddr_t) dd->dd_desc + + dd->dd_desc_len)); + + ds += ndesc; + bf->bf_desc = ds; + bf->bf_daddr = DS2PHYS(dd, ds); + } + } + list_add_tail(&bf->list, head); + } + return 0; +fail2: + pci_free_consistent(sc->pdev, + dd->dd_desc_len, dd->dd_desc, dd->dd_desc_paddr); +fail: + memset(dd, 0, sizeof(*dd)); + return error; +#undef ATH_DESC_4KB_BOUND_CHECK +#undef ATH_DESC_4KB_BOUND_NUM_SKIPPED +#undef DS2PHYS +} + +void ath_descdma_cleanup(struct ath_softc *sc, + struct ath_descdma *dd, + struct list_head *head) +{ + pci_free_consistent(sc->pdev, + dd->dd_desc_len, dd->dd_desc, dd->dd_desc_paddr); + + INIT_LIST_HEAD(head); + kfree(dd->dd_bufptr); + memset(dd, 0, sizeof(*dd)); +} + +int ath_get_hal_qnum(u16 queue, struct ath_softc *sc) +{ + int qnum; + + switch (queue) { + case 0: + qnum = sc->sc_haltype2q[ATH9K_WME_AC_VO]; + break; + case 1: + qnum = sc->sc_haltype2q[ATH9K_WME_AC_VI]; + break; + case 2: + qnum = sc->sc_haltype2q[ATH9K_WME_AC_BE]; + break; + case 3: + qnum = sc->sc_haltype2q[ATH9K_WME_AC_BK]; + break; + default: + qnum = sc->sc_haltype2q[ATH9K_WME_AC_BE]; + break; + } + + return qnum; +} + +int ath_get_mac80211_qnum(u32 queue, struct ath_softc *sc) +{ + int qnum; + + switch (queue) { + case ATH9K_WME_AC_VO: + qnum = 0; + break; + case ATH9K_WME_AC_VI: + qnum = 1; + break; + case ATH9K_WME_AC_BE: + qnum = 2; + break; + case ATH9K_WME_AC_BK: + qnum = 3; + break; + default: + qnum = -1; + break; + } + + return qnum; +} + +/**********************/ +/* mac80211 callbacks */ +/**********************/ + static int ath9k_start(struct ieee80211_hw *hw) { struct ath_softc *sc = hw->priv; struct ieee80211_channel *curchan = hw->conf.channel; - int error = 0, pos; + struct ath9k_channel *init_channel; + int error = 0, pos, status; DPRINTF(sc, ATH_DBG_CONFIG, "%s: Starting driver with " "initial channel: %d MHz\n", __func__, curchan->center_freq); @@ -827,24 +1872,103 @@ static int ath9k_start(struct ieee80211_hw *hw) if (pos == -1) { DPRINTF(sc, ATH_DBG_FATAL, "%s: Invalid channel\n", __func__); error = -EINVAL; - goto exit; + goto error; } sc->sc_ah->ah_channels[pos].chanmode = (curchan->band == IEEE80211_BAND_2GHZ) ? CHANNEL_G : CHANNEL_A; + init_channel = &sc->sc_ah->ah_channels[pos]; - error = ath_open(sc, &sc->sc_ah->ah_channels[pos]); - if (error) { + /* Reset SERDES registers */ + ath9k_hw_configpcipowersave(sc->sc_ah, 0); + + /* + * The basic interface to setting the hardware in a good + * state is ``reset''. On return the hardware is known to + * be powered up and with interrupts disabled. This must + * be followed by initialization of the appropriate bits + * and then setup of the interrupt mask. + */ + spin_lock_bh(&sc->sc_resetlock); + if (!ath9k_hw_reset(sc->sc_ah, init_channel, + sc->sc_ht_info.tx_chan_width, + sc->sc_tx_chainmask, sc->sc_rx_chainmask, + sc->sc_ht_extprotspacing, false, &status)) { DPRINTF(sc, ATH_DBG_FATAL, - "%s: Unable to complete ath_open\n", __func__); - goto exit; + "%s: unable to reset hardware; hal status %u " + "(freq %u flags 0x%x)\n", __func__, status, + init_channel->channel, init_channel->channelFlags); + error = -EIO; + spin_unlock_bh(&sc->sc_resetlock); + goto error; } + spin_unlock_bh(&sc->sc_resetlock); + + /* + * This is needed only to setup initial state + * but it's best done after a reset. + */ + ath_update_txpow(sc); + + /* + * Setup the hardware after reset: + * The receive engine is set going. + * Frame transmit is handled entirely + * in the frame output path; there's nothing to do + * here except setup the interrupt mask. + */ + if (ath_startrecv(sc) != 0) { + DPRINTF(sc, ATH_DBG_FATAL, + "%s: unable to start recv logic\n", __func__); + error = -EIO; + goto error; + } + + /* Setup our intr mask. */ + sc->sc_imask = ATH9K_INT_RX | ATH9K_INT_TX + | ATH9K_INT_RXEOL | ATH9K_INT_RXORN + | ATH9K_INT_FATAL | ATH9K_INT_GLOBAL; + + if (sc->sc_ah->ah_caps.hw_caps & ATH9K_HW_CAP_GTT) + sc->sc_imask |= ATH9K_INT_GTT; + + if (sc->sc_ah->ah_caps.hw_caps & ATH9K_HW_CAP_HT) + sc->sc_imask |= ATH9K_INT_CST; + + /* + * Enable MIB interrupts when there are hardware phy counters. + * Note we only do this (at the moment) for station mode. + */ + if (ath9k_hw_phycounters(sc->sc_ah) && + ((sc->sc_ah->ah_opmode == ATH9K_M_STA) || + (sc->sc_ah->ah_opmode == ATH9K_M_IBSS))) + sc->sc_imask |= ATH9K_INT_MIB; + /* + * Some hardware processes the TIM IE and fires an + * interrupt when the TIM bit is set. For hardware + * that does, if not overridden by configuration, + * enable the TIM interrupt when operating as station. + */ + if ((sc->sc_ah->ah_caps.hw_caps & ATH9K_HW_CAP_ENHANCEDPM) && + (sc->sc_ah->ah_opmode == ATH9K_M_STA) && + !sc->sc_config.swBeaconProcess) + sc->sc_imask |= ATH9K_INT_TIM; + + ath_setcurmode(sc, ath_chan2mode(init_channel)); + + sc->sc_flags &= ~SC_OP_INVALID; + + /* Disable BMISS interrupt when we're not associated */ + sc->sc_imask &= ~(ATH9K_INT_SWBA | ATH9K_INT_BMISS); + ath9k_hw_set_interrupts(sc->sc_ah, sc->sc_imask); + + ieee80211_wake_queues(sc->hw); #if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE) error = ath_start_rfkill_poll(sc); #endif -exit: +error: return error; } @@ -911,7 +2035,30 @@ static void ath9k_stop(struct ieee80211_hw *hw) return; } - ath_stop(sc); + DPRINTF(sc, ATH_DBG_CONFIG, "%s: Cleaning up\n", __func__); + + ieee80211_stop_queues(sc->hw); + + /* make sure h/w will not generate any interrupt + * before setting the invalid flag. */ + ath9k_hw_set_interrupts(sc->sc_ah, 0); + + if (!(sc->sc_flags & SC_OP_INVALID)) { + ath_draintxq(sc, false); + ath_stoprecv(sc); + ath9k_hw_phy_disable(sc->sc_ah); + } else + sc->sc_rxlink = NULL; + +#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE) + if (sc->sc_ah->ah_caps.hw_caps & ATH9K_HW_CAP_RFSILENT) + cancel_delayed_work_sync(&sc->rf_kill.rfkill_poll); +#endif + /* disable HAL and put h/w to sleep */ + ath9k_hw_disable(sc->sc_ah); + ath9k_hw_configpcipowersave(sc->sc_ah, 1); + + sc->sc_flags |= SC_OP_INVALID; DPRINTF(sc, ATH_DBG_CONFIG, "%s: Driver halt\n", __func__); } diff --git a/drivers/net/wireless/ath9k/rc.c b/drivers/net/wireless/ath9k/rc.c index 7d1913d48d31..93dfea897ff2 100644 --- a/drivers/net/wireless/ath9k/rc.c +++ b/drivers/net/wireless/ath9k/rc.c @@ -1401,7 +1401,6 @@ static void ath_tx_status(void *priv, struct ieee80211_supported_band *sband, struct ath_softc *sc = priv; struct ath_rate_priv *ath_rc_priv = priv_sta; struct ath_tx_info_priv *tx_info_priv = NULL; - struct ath_node *an; struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); struct ieee80211_hdr *hdr; int final_ts_idx, tx_status = 0, is_underrun = 0; @@ -1410,21 +1409,15 @@ static void ath_tx_status(void *priv, struct ieee80211_supported_band *sband, hdr = (struct ieee80211_hdr *)skb->data; fc = hdr->frame_control; tx_info_priv = ATH_TX_INFO_PRIV(tx_info); - an = (struct ath_node *)sta->drv_priv; final_ts_idx = tx_info_priv->tx.ts_rateindex; - if (!an || !priv_sta || !ieee80211_is_data(fc) || + if (!priv_sta || !ieee80211_is_data(fc) || !tx_info_priv->update_rc) goto exit; if (tx_info_priv->tx.ts_status & ATH9K_TXERR_FILT) goto exit; - if (tx_info_priv->tx.ts_rssi > 0) { - ATH_RSSI_LPF(an->an_chainmask_sel.tx_avgrssi, - tx_info_priv->tx.ts_rssi); - } - /* * If underrun error is seen assume it as an excessive retry only * if prefetch trigger level have reached the max (0x3f for 5416) diff --git a/drivers/net/wireless/ath9k/recv.c b/drivers/net/wireless/ath9k/recv.c index 6eae2542392a..743ad228b833 100644 --- a/drivers/net/wireless/ath9k/recv.c +++ b/drivers/net/wireless/ath9k/recv.c @@ -55,6 +55,28 @@ static void ath_rx_buf_link(struct ath_softc *sc, struct ath_buf *bf) ath9k_hw_rxena(ah); } +static void ath_setdefantenna(struct ath_softc *sc, u32 antenna) +{ + /* XXX block beacon interrupts */ + ath9k_hw_setantenna(sc->sc_ah, antenna); + sc->sc_defant = antenna; + sc->sc_rxotherant = 0; +} + +/* + * Extend 15-bit time stamp from rx descriptor to + * a full 64-bit TSF using the current h/w TSF. +*/ +static u64 ath_extend_tsf(struct ath_softc *sc, u32 rstamp) +{ + u64 tsf; + + tsf = ath9k_hw_gettsf64(sc->sc_ah); + if ((tsf & 0x7fff) < rstamp) + tsf -= 0x8000; + return (tsf & ~0x7fff) | rstamp; +} + static struct sk_buff *ath_rxbuf_alloc(struct ath_softc *sc, u32 len) { struct sk_buff *skb; diff --git a/drivers/net/wireless/ath9k/xmit.c b/drivers/net/wireless/ath9k/xmit.c index dad81a9df152..3de60c51e5f2 100644 --- a/drivers/net/wireless/ath9k/xmit.c +++ b/drivers/net/wireless/ath9k/xmit.c @@ -147,6 +147,19 @@ static int ath_aggr_query(struct ath_softc *sc, struct ath_node *an, u8 tidno) return 0; } +static void ath_get_beaconconfig(struct ath_softc *sc, int if_id, + struct ath_beacon_config *conf) +{ + struct ieee80211_hw *hw = sc->hw; + + /* fill in beacon config data */ + + conf->beacon_interval = hw->conf.beacon_int; + conf->listen_interval = 100; + conf->dtim_count = 1; + conf->bmiss_timeout = ATH_DEFAULT_BMISS_LIMIT * conf->listen_interval; +} + /* Calculate Atheros packet type from IEEE80211 packet header */ static enum ath9k_pkt_type get_hw_packet_type(struct sk_buff *skb) @@ -522,7 +535,6 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf) struct ath_desc *ds = bf->bf_desc; struct ath_desc *lastds = bf->bf_lastbf->bf_desc; struct ath9k_11n_rate_series series[4]; - struct ath_node *an = NULL; struct sk_buff *skb; struct ieee80211_tx_info *tx_info; struct ieee80211_tx_rate *rates; @@ -540,9 +552,6 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf) tx_info = IEEE80211_SKB_CB(skb); rates = tx_info->control.rates; - if (tx_info->control.sta) - an = (struct ath_node *)tx_info->control.sta->drv_priv; - if (ieee80211_has_morefrags(fc) || (le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG)) { rates[1].count = rates[2].count = rates[3].count = 0; @@ -632,10 +641,7 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf) (rates[i].flags & IEEE80211_TX_RC_SHORT_GI), bf_isshpreamble(bf)); - if (bf_isht(bf) && an) - series[i].ChSel = ath_chainmask_sel_logic(sc, an); - else - series[i].ChSel = sc->sc_tx_chainmask; + series[i].ChSel = sc->sc_tx_chainmask; if (rtsctsena) series[i].RateFlags |= ATH9K_RATESERIES_RTS_CTS; -- cgit v1.2.3 From 04bd4638097c767278fdf12d50fecc8b60194d39 Mon Sep 17 00:00:00 2001 From: Sujith Date: Fri, 28 Nov 2008 22:18:05 +0530 Subject: ath9k: Use cleaner debug masks Remove all the useless __func__ prefixes in debug messages, and replace the DPRINTF macro with a function. Signed-off-by: Sujith Signed-off-by: John W. Linville --- drivers/net/wireless/ath9k/ani.c | 34 +++--- drivers/net/wireless/ath9k/beacon.c | 77 ++++++------ drivers/net/wireless/ath9k/calib.c | 69 +++++------ drivers/net/wireless/ath9k/core.h | 157 +++++++++--------------- drivers/net/wireless/ath9k/eeprom.c | 16 ++- drivers/net/wireless/ath9k/hw.c | 189 ++++++++++++---------------- drivers/net/wireless/ath9k/mac.c | 66 ++++------ drivers/net/wireless/ath9k/main.c | 237 ++++++++++++++++-------------------- drivers/net/wireless/ath9k/phy.c | 14 +-- drivers/net/wireless/ath9k/rc.c | 7 +- drivers/net/wireless/ath9k/recv.c | 14 +-- drivers/net/wireless/ath9k/regd.c | 81 ++++++------ drivers/net/wireless/ath9k/xmit.c | 77 +++++------- 13 files changed, 429 insertions(+), 609 deletions(-) (limited to 'drivers/net/wireless/ath9k/recv.c') diff --git a/drivers/net/wireless/ath9k/ani.c b/drivers/net/wireless/ath9k/ani.c index ada12e9aa7f9..c25b72be1139 100644 --- a/drivers/net/wireless/ath9k/ani.c +++ b/drivers/net/wireless/ath9k/ani.c @@ -53,8 +53,8 @@ static bool ath9k_hw_ani_control(struct ath_hal *ah, if (level >= ARRAY_SIZE(ahp->ah_totalSizeDesired)) { DPRINTF(ah->ah_sc, ATH_DBG_ANI, - "%s: level out of range (%u > %u)\n", - __func__, level, + "level out of range (%u > %u)\n", + level, (unsigned)ARRAY_SIZE(ahp->ah_totalSizeDesired)); return false; } @@ -158,8 +158,8 @@ static bool ath9k_hw_ani_control(struct ath_hal *ah, if (level >= ARRAY_SIZE(firstep)) { DPRINTF(ah->ah_sc, ATH_DBG_ANI, - "%s: level out of range (%u > %u)\n", - __func__, level, + "level out of range (%u > %u)\n", + level, (unsigned) ARRAY_SIZE(firstep)); return false; } @@ -180,8 +180,8 @@ static bool ath9k_hw_ani_control(struct ath_hal *ah, if (level >= ARRAY_SIZE(cycpwrThr1)) { DPRINTF(ah->ah_sc, ATH_DBG_ANI, - "%s: level out of range (%u > %u)\n", - __func__, level, + "level out of range (%u > %u)\n", + level, (unsigned) ARRAY_SIZE(cycpwrThr1)); return false; @@ -200,11 +200,11 @@ static bool ath9k_hw_ani_control(struct ath_hal *ah, break; default: DPRINTF(ah->ah_sc, ATH_DBG_ANI, - "%s: invalid cmd %u\n", __func__, cmd); + "invalid cmd %u\n", cmd); return false; } - DPRINTF(ah->ah_sc, ATH_DBG_ANI, "%s: ANI parameters:\n", __func__); + DPRINTF(ah->ah_sc, ATH_DBG_ANI, "ANI parameters:\n"); DPRINTF(ah->ah_sc, ATH_DBG_ANI, "noiseImmunityLevel=%d, spurImmunityLevel=%d, " "ofdmWeakSigDetectOff=%d\n", @@ -262,8 +262,8 @@ static void ath9k_ani_restart(struct ath_hal *ah) AR_PHY_COUNTMAX - aniState->cckTrigHigh; } DPRINTF(ah->ah_sc, ATH_DBG_ANI, - "%s: Writing ofdmbase=%u cckbase=%u\n", - __func__, aniState->ofdmPhyErrBase, + "Writing ofdmbase=%u cckbase=%u\n", + aniState->ofdmPhyErrBase, aniState->cckPhyErrBase); REG_WRITE(ah, AR_PHY_ERR_1, aniState->ofdmPhyErrBase); REG_WRITE(ah, AR_PHY_ERR_2, aniState->cckPhyErrBase); @@ -490,8 +490,7 @@ void ath9k_ani_reset(struct ath_hal *ah) if (DO_ANI(ah) && ah->ah_opmode != ATH9K_M_STA && ah->ah_opmode != ATH9K_M_IBSS) { DPRINTF(ah->ah_sc, ATH_DBG_ANI, - "%s: Reset ANI state opmode %u\n", __func__, - ah->ah_opmode); + "Reset ANI state opmode %u\n", ah->ah_opmode); ahp->ah_stats.ast_ani_reset++; ath9k_hw_ani_control(ah, ATH9K_ANI_NOISE_IMMUNITY_LEVEL, 0); @@ -581,9 +580,9 @@ void ath9k_hw_ani_monitor(struct ath_hal *ah, phyCnt2 < aniState->cckPhyErrBase) { if (phyCnt1 < aniState->ofdmPhyErrBase) { DPRINTF(ah->ah_sc, ATH_DBG_ANI, - "%s: phyCnt1 0x%x, resetting " + "phyCnt1 0x%x, resetting " "counter value to 0x%x\n", - __func__, phyCnt1, + phyCnt1, aniState->ofdmPhyErrBase); REG_WRITE(ah, AR_PHY_ERR_1, aniState->ofdmPhyErrBase); @@ -592,9 +591,9 @@ void ath9k_hw_ani_monitor(struct ath_hal *ah, } if (phyCnt2 < aniState->cckPhyErrBase) { DPRINTF(ah->ah_sc, ATH_DBG_ANI, - "%s: phyCnt2 0x%x, resetting " + "phyCnt2 0x%x, resetting " "counter value to 0x%x\n", - __func__, phyCnt2, + phyCnt2, aniState->cckPhyErrBase); REG_WRITE(ah, AR_PHY_ERR_2, aniState->cckPhyErrBase); @@ -692,8 +691,7 @@ u32 ath9k_hw_GetMibCycleCountsPct(struct ath_hal *ah, if (cycles == 0 || cycles > cc) { DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL, - "%s: cycle counter wrap. ExtBusy = 0\n", - __func__); + "cycle counter wrap. ExtBusy = 0\n"); good = 0; } else { u32 cc_d = cc - cycles; diff --git a/drivers/net/wireless/ath9k/beacon.c b/drivers/net/wireless/ath9k/beacon.c index e80d9b9b61a0..88fbfe5bb7b5 100644 --- a/drivers/net/wireless/ath9k/beacon.c +++ b/drivers/net/wireless/ath9k/beacon.c @@ -41,8 +41,7 @@ static int ath_beaconq_config(struct ath_softc *sc) if (!ath9k_hw_set_txq_props(ah, sc->sc_bhalq, &qi)) { DPRINTF(sc, ATH_DBG_FATAL, - "%s: unable to update h/w beacon queue parameters\n", - __func__); + "unable to update h/w beacon queue parameters\n"); return 0; } else { ath9k_hw_resettxqueue(ah, sc->sc_bhalq); /* push to h/w */ @@ -53,8 +52,8 @@ static int ath_beaconq_config(struct ath_softc *sc) static void ath_bstuck_process(struct ath_softc *sc) { DPRINTF(sc, ATH_DBG_BEACON, - "%s: stuck beacon; resetting (bmiss count %u)\n", - __func__, sc->sc_bmisscount); + "stuck beacon; resetting (bmiss count %u)\n", + sc->sc_bmisscount); ath_reset(sc, false); } @@ -76,8 +75,7 @@ static void ath_beacon_setup(struct ath_softc *sc, int ctsrate = 0; int ctsduration = 0; - DPRINTF(sc, ATH_DBG_BEACON, "%s: m %p len %u\n", - __func__, skb, skb->len); + DPRINTF(sc, ATH_DBG_BEACON, "m %p len %u\n", skb, skb->len); /* setup descriptors */ ds = bf->bf_desc; @@ -158,8 +156,8 @@ static struct ath_buf *ath_beacon_generate(struct ath_softc *sc, int if_id) cabq = sc->sc_cabq; if (avp->av_bcbuf == NULL) { - DPRINTF(sc, ATH_DBG_BEACON, "%s: avp=%p av_bcbuf=%p\n", - __func__, avp, avp->av_bcbuf); + DPRINTF(sc, ATH_DBG_BEACON, "avp=%p av_bcbuf=%p\n", + avp, avp->av_bcbuf); return NULL; } @@ -216,7 +214,7 @@ static struct ath_buf *ath_beacon_generate(struct ath_softc *sc, int if_id) if (sc->sc_nvaps > 1) { ath_tx_draintxq(sc, cabq, false); DPRINTF(sc, ATH_DBG_BEACON, - "%s: flush previous cabq traffic\n", __func__); + "flush previous cabq traffic\n"); } } @@ -253,8 +251,8 @@ static void ath_beacon_start_adhoc(struct ath_softc *sc, int if_id) avp = (void *)vif->drv_priv; if (avp->av_bcbuf == NULL) { - DPRINTF(sc, ATH_DBG_BEACON, "%s: avp=%p av_bcbuf=%p\n", - __func__, avp, avp != NULL ? avp->av_bcbuf : NULL); + DPRINTF(sc, ATH_DBG_BEACON, "avp=%p av_bcbuf=%p\n", + avp, avp != NULL ? avp->av_bcbuf : NULL); return; } bf = avp->av_bcbuf; @@ -266,7 +264,7 @@ static void ath_beacon_start_adhoc(struct ath_softc *sc, int if_id) /* NB: caller is known to have already stopped tx dma */ ath9k_hw_puttxbuf(ah, sc->sc_bhalq, bf->bf_daddr); ath9k_hw_txstart(ah, sc->sc_bhalq); - DPRINTF(sc, ATH_DBG_BEACON, "%s: TXDP%u = %llx (%p)\n", __func__, + DPRINTF(sc, ATH_DBG_BEACON, "TXDP%u = %llx (%p)\n", sc->sc_bhalq, ito64(bf->bf_daddr), bf->bf_desc); } @@ -351,8 +349,7 @@ int ath_beacon_alloc(struct ath_softc *sc, int if_id) */ skb = ieee80211_beacon_get(sc->hw, vif); if (skb == NULL) { - DPRINTF(sc, ATH_DBG_BEACON, "%s: cannot get skb\n", - __func__); + DPRINTF(sc, ATH_DBG_BEACON, "cannot get skb\n"); return -ENOMEM; } @@ -388,8 +385,7 @@ int ath_beacon_alloc(struct ath_softc *sc, int if_id) val = cpu_to_le64(tsfadjust << 10); /* TU->TSF */ DPRINTF(sc, ATH_DBG_BEACON, - "%s: %s beacons, bslot %d intval %u tsfadjust %llu\n", - __func__, "stagger", + "stagger beacons, bslot %d intval %u tsfadjust %llu\n", avp->av_bslot, intval, (unsigned long long)tsfadjust); hdr = (struct ieee80211_hdr *)skb->data; @@ -468,40 +464,39 @@ void ath9k_beacon_tasklet(unsigned long data) if (sc->sc_bmisscount < BSTUCK_THRESH) { if (sc->sc_flags & SC_OP_NO_RESET) { DPRINTF(sc, ATH_DBG_BEACON, - "%s: missed %u consecutive beacons\n", - __func__, sc->sc_bmisscount); + "missed %u consecutive beacons\n", + sc->sc_bmisscount); if (show_cycles) { /* * Display cycle counter stats from HW * to aide in debug of stickiness. */ DPRINTF(sc, ATH_DBG_BEACON, - "%s: busy times: rx_clear=%d, " + "busy times: rx_clear=%d, " "rx_frame=%d, tx_frame=%d\n", - __func__, rx_clear, rx_frame, + rx_clear, rx_frame, tx_frame); } else { DPRINTF(sc, ATH_DBG_BEACON, - "%s: unable to obtain " - "busy times\n", __func__); + "unable to obtain " + "busy times\n"); } } else { DPRINTF(sc, ATH_DBG_BEACON, - "%s: missed %u consecutive beacons\n", - __func__, sc->sc_bmisscount); + "missed %u consecutive beacons\n", + sc->sc_bmisscount); } } else if (sc->sc_bmisscount >= BSTUCK_THRESH) { if (sc->sc_flags & SC_OP_NO_RESET) { if (sc->sc_bmisscount == BSTUCK_THRESH) { DPRINTF(sc, ATH_DBG_BEACON, - "%s: beacon is officially " - "stuck\n", __func__); + "beacon is officially " + "stuck\n"); ath9k_hw_dmaRegDump(ah); } } else { DPRINTF(sc, ATH_DBG_BEACON, - "%s: beacon is officially stuck\n", - __func__); + "beacon is officially stuck\n"); ath_bstuck_process(sc); } } @@ -511,12 +506,12 @@ void ath9k_beacon_tasklet(unsigned long data) if (sc->sc_bmisscount != 0) { if (sc->sc_flags & SC_OP_NO_RESET) { DPRINTF(sc, ATH_DBG_BEACON, - "%s: resume beacon xmit after %u misses\n", - __func__, sc->sc_bmisscount); + "resume beacon xmit after %u misses\n", + sc->sc_bmisscount); } else { DPRINTF(sc, ATH_DBG_BEACON, - "%s: resume beacon xmit after %u misses\n", - __func__, sc->sc_bmisscount); + "resume beacon xmit after %u misses\n", + sc->sc_bmisscount); } sc->sc_bmisscount = 0; } @@ -536,8 +531,8 @@ void ath9k_beacon_tasklet(unsigned long data) if_id = sc->sc_bslot[(slot + 1) % ATH_BCBUF]; DPRINTF(sc, ATH_DBG_BEACON, - "%s: slot %d [tsf %llu tsftu %u intval %u] if_id %d\n", - __func__, slot, (unsigned long long)tsf, tsftu, + "slot %d [tsf %llu tsftu %u intval %u] if_id %d\n", + slot, (unsigned long long)tsf, tsftu, intval, if_id); bfaddr = 0; @@ -580,8 +575,7 @@ void ath9k_beacon_tasklet(unsigned long data) */ if (!ath9k_hw_stoptxdma(ah, sc->sc_bhalq)) { DPRINTF(sc, ATH_DBG_FATAL, - "%s: beacon queue %u did not stop?\n", - __func__, sc->sc_bhalq); + "beacon queue %u did not stop?\n", sc->sc_bhalq); /* NB: the HAL still stops DMA, so proceed */ } @@ -658,8 +652,8 @@ void ath_beacon_config(struct ath_softc *sc, int if_id) else if (intval) /* NB: can be 0 for monitor mode */ nexttbtt = roundup(nexttbtt, intval); - DPRINTF(sc, ATH_DBG_BEACON, "%s: nexttbtt %u intval %u (%u)\n", - __func__, nexttbtt, intval, conf.beacon_interval); + DPRINTF(sc, ATH_DBG_BEACON, "nexttbtt %u intval %u (%u)\n", + nexttbtt, intval, conf.beacon_interval); /* Check for ATH9K_M_HOSTAP and sc_nostabeacons for WDS client */ if (sc->sc_ah->ah_opmode == ATH9K_M_STA) { @@ -746,7 +740,7 @@ void ath_beacon_config(struct ath_softc *sc, int if_id) bs.bs_sleepduration = bs.bs_dtimperiod; DPRINTF(sc, ATH_DBG_BEACON, - "%s: tsf %llu " + "tsf %llu " "tsf:tu %u " "intval %u " "nexttbtt %u " @@ -758,7 +752,6 @@ void ath_beacon_config(struct ath_softc *sc, int if_id) "maxdur %u " "next %u " "timoffset %u\n", - __func__, (unsigned long long)tsf, tsftu, bs.bs_intval, bs.bs_nexttbtt, @@ -798,8 +791,8 @@ void ath_beacon_config(struct ath_softc *sc, int if_id) } #undef FUDGE DPRINTF(sc, ATH_DBG_BEACON, - "%s: IBSS nexttbtt %u intval %u (%u)\n", - __func__, nexttbtt, + "IBSS nexttbtt %u intval %u (%u)\n", + nexttbtt, intval & ~ATH9K_BEACON_RESET_TSF, conf.beacon_interval); diff --git a/drivers/net/wireless/ath9k/calib.c b/drivers/net/wireless/ath9k/calib.c index 0e214f746a96..51c8a3ce4e60 100644 --- a/drivers/net/wireless/ath9k/calib.c +++ b/drivers/net/wireless/ath9k/calib.c @@ -31,11 +31,11 @@ static const int16_t NOISE_FLOOR[] = { -96, -93, -98, -96, -93, -96 }; static bool ath9k_hw_nf_in_range(struct ath_hal *ah, s16 nf) { if (nf > ATH9K_NF_TOO_LOW) { - DPRINTF(ah->ah_sc, ATH_DBG_NF_CAL, - "%s: noise floor value detected (%d) is " + DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, + "noise floor value detected (%d) is " "lower than what we think is a " "reasonable value (%d)\n", - __func__, nf, ATH9K_NF_TOO_LOW); + nf, ATH9K_NF_TOO_LOW); return false; } return true; @@ -116,7 +116,7 @@ static void ath9k_hw_do_getnf(struct ath_hal *ah, if (nf & 0x100) nf = 0 - ((nf ^ 0x1ff) + 1); - DPRINTF(ah->ah_sc, ATH_DBG_NF_CAL, + DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, "NF calibrated [ctl] [chain 1] is %d\n", nf); nfarray[1] = nf; @@ -125,7 +125,7 @@ static void ath9k_hw_do_getnf(struct ath_hal *ah, AR_PHY_CH2_MINCCA_PWR); if (nf & 0x100) nf = 0 - ((nf ^ 0x1ff) + 1); - DPRINTF(ah->ah_sc, ATH_DBG_NF_CAL, + DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, "NF calibrated [ctl] [chain 2] is %d\n", nf); nfarray[2] = nf; } @@ -139,7 +139,7 @@ static void ath9k_hw_do_getnf(struct ath_hal *ah, if (nf & 0x100) nf = 0 - ((nf ^ 0x1ff) + 1); - DPRINTF(ah->ah_sc, ATH_DBG_NF_CAL, + DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, "NF calibrated [ext] [chain 0] is %d\n", nf); nfarray[3] = nf; @@ -161,7 +161,7 @@ static void ath9k_hw_do_getnf(struct ath_hal *ah, AR_PHY_CH2_EXT_MINCCA_PWR); if (nf & 0x100) nf = 0 - ((nf ^ 0x1ff) + 1); - DPRINTF(ah->ah_sc, ATH_DBG_NF_CAL, + DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, "NF calibrated [ext] [chain 2] is %d\n", nf); nfarray[5] = nf; } @@ -187,8 +187,7 @@ static bool getNoiseFloorThresh(struct ath_hal *ah, break; default: DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL, - "%s: invalid channel flags 0x%x\n", __func__, - chan->channelFlags); + "invalid channel flags 0x%x\n", chan->channelFlags); return false; } @@ -206,24 +205,22 @@ static void ath9k_hw_setup_calibration(struct ath_hal *ah, case IQ_MISMATCH_CAL: REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_IQ); DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, - "%s: starting IQ Mismatch Calibration\n", - __func__); + "starting IQ Mismatch Calibration\n"); break; case ADC_GAIN_CAL: REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_ADC_GAIN); DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, - "%s: starting ADC Gain Calibration\n", __func__); + "starting ADC Gain Calibration\n"); break; case ADC_DC_CAL: REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_ADC_DC_PER); DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, - "%s: starting ADC DC Calibration\n", __func__); + "starting ADC DC Calibration\n"); break; case ADC_DC_INIT_CAL: REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_ADC_DC_INIT); DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, - "%s: starting Init ADC DC Calibration\n", - __func__); + "starting Init ADC DC Calibration\n"); break; } @@ -594,16 +591,16 @@ void ath9k_hw_reset_calvalid(struct ath_hal *ah, struct ath9k_channel *chan, if (ichan == NULL) { DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, - "%s: invalid channel %u/0x%x; no mapping\n", - __func__, chan->channel, chan->channelFlags); + "invalid channel %u/0x%x; no mapping\n", + chan->channel, chan->channelFlags); return; } if (currCal->calState != CAL_DONE) { DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, - "%s: Calibration state incorrect, %d\n", - __func__, currCal->calState); + "Calibration state incorrect, %d\n", + currCal->calState); return; } @@ -612,8 +609,8 @@ void ath9k_hw_reset_calvalid(struct ath_hal *ah, struct ath9k_channel *chan, return; DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, - "%s: Resetting Cal %d state for channel %u/0x%x\n", - __func__, currCal->calData->calType, chan->channel, + "Resetting Cal %d state for channel %u/0x%x\n", + currCal->calData->calType, chan->channel, chan->channelFlags); ichan->CalValid &= ~currCal->calData->calType; @@ -705,8 +702,7 @@ int16_t ath9k_hw_getnf(struct ath_hal *ah, chan->channelFlags &= (~CHANNEL_CW_INT); if (REG_READ(ah, AR_PHY_AGC_CONTROL) & AR_PHY_AGC_CONTROL_NF) { DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, - "%s: NF did not complete in calibration window\n", - __func__); + "NF did not complete in calibration window\n"); nf = 0; chan->rawNoiseFloor = nf; return chan->rawNoiseFloor; @@ -716,8 +712,8 @@ int16_t ath9k_hw_getnf(struct ath_hal *ah, if (getNoiseFloorThresh(ah, chan, &nfThresh) && nf > nfThresh) { DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, - "%s: noise floor failed detected; " - "detected %d, threshold %d\n", __func__, + "noise floor failed detected; " + "detected %d, threshold %d\n", nf, nfThresh); chan->channelFlags |= CHANNEL_CW_INT; } @@ -759,9 +755,9 @@ s16 ath9k_hw_getchan_noise(struct ath_hal *ah, struct ath9k_channel *chan) ichan = ath9k_regd_check_channel(ah, chan); if (ichan == NULL) { - DPRINTF(ah->ah_sc, ATH_DBG_NF_CAL, - "%s: invalid channel %u/0x%x; no mapping\n", - __func__, chan->channel, chan->channelFlags); + DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, + "invalid channel %u/0x%x; no mapping\n", + chan->channel, chan->channelFlags); return ATH_DEFAULT_NOISE_FLOOR; } if (ichan->rawNoiseFloor == 0) { @@ -788,8 +784,8 @@ bool ath9k_hw_calibrate(struct ath_hal *ah, struct ath9k_channel *chan, if (ichan == NULL) { DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL, - "%s: invalid channel %u/0x%x; no mapping\n", - __func__, chan->channel, chan->channelFlags); + "invalid channel %u/0x%x; no mapping\n", + chan->channel, chan->channelFlags); return false; } @@ -834,8 +830,8 @@ bool ath9k_hw_init_cal(struct ath_hal *ah, if (!ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL, 0)) { DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, - "%s: offset calibration failed to complete in 1ms; " - "noisy environment?\n", __func__); + "offset calibration failed to complete in 1ms; " + "noisy environment?\n"); return false; } @@ -850,22 +846,19 @@ bool ath9k_hw_init_cal(struct ath_hal *ah, INIT_CAL(&ahp->ah_adcGainCalData); INSERT_CAL(ahp, &ahp->ah_adcGainCalData); DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, - "%s: enabling ADC Gain Calibration.\n", - __func__); + "enabling ADC Gain Calibration.\n"); } if (ath9k_hw_iscal_supported(ah, chan, ADC_DC_CAL)) { INIT_CAL(&ahp->ah_adcDcCalData); INSERT_CAL(ahp, &ahp->ah_adcDcCalData); DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, - "%s: enabling ADC DC Calibration.\n", - __func__); + "enabling ADC DC Calibration.\n"); } if (ath9k_hw_iscal_supported(ah, chan, IQ_MISMATCH_CAL)) { INIT_CAL(&ahp->ah_iqCalData); INSERT_CAL(ahp, &ahp->ah_iqCalData); DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, - "%s: enabling IQ Calibration.\n", - __func__); + "enabling IQ Calibration.\n"); } ahp->ah_cal_list_curr = ahp->ah_cal_list; diff --git a/drivers/net/wireless/ath9k/core.h b/drivers/net/wireless/ath9k/core.h index f0c54377dfe6..ae32b2c4ef16 100644 --- a/drivers/net/wireless/ath9k/core.h +++ b/drivers/net/wireless/ath9k/core.h @@ -84,52 +84,33 @@ struct ath_node; static const u8 ath_bcast_mac[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; -/*************/ -/* Debugging */ -/*************/ - enum ATH_DEBUG { ATH_DBG_RESET = 0x00000001, - ATH_DBG_PHY_IO = 0x00000002, - ATH_DBG_REG_IO = 0x00000004, - ATH_DBG_QUEUE = 0x00000008, - ATH_DBG_EEPROM = 0x00000010, - ATH_DBG_NF_CAL = 0x00000020, - ATH_DBG_CALIBRATE = 0x00000040, - ATH_DBG_CHANNEL = 0x00000080, - ATH_DBG_INTERRUPT = 0x00000100, - ATH_DBG_REGULATORY = 0x00000200, - ATH_DBG_ANI = 0x00000400, - ATH_DBG_POWER_MGMT = 0x00000800, - ATH_DBG_XMIT = 0x00001000, - ATH_DBG_BEACON = 0x00002000, - ATH_DBG_RATE = 0x00004000, - ATH_DBG_CONFIG = 0x00008000, - ATH_DBG_KEYCACHE = 0x00010000, - ATH_DBG_AGGR = 0x00020000, - ATH_DBG_FATAL = 0x00040000, + ATH_DBG_REG_IO = 0x00000002, + ATH_DBG_QUEUE = 0x00000004, + ATH_DBG_EEPROM = 0x00000008, + ATH_DBG_CALIBRATE = 0x00000010, + ATH_DBG_CHANNEL = 0x00000020, + ATH_DBG_INTERRUPT = 0x00000040, + ATH_DBG_REGULATORY = 0x00000080, + ATH_DBG_ANI = 0x00000100, + ATH_DBG_POWER_MGMT = 0x00000200, + ATH_DBG_XMIT = 0x00000400, + ATH_DBG_BEACON = 0x00001000, + ATH_DBG_CONFIG = 0x00002000, + ATH_DBG_KEYCACHE = 0x00004000, + ATH_DBG_FATAL = 0x00008000, ATH_DBG_ANY = 0xffffffff }; #define DBG_DEFAULT (ATH_DBG_FATAL) -#define DPRINTF(sc, _m, _fmt, ...) do { \ - if (sc->sc_debug & (_m)) \ - printk(_fmt , ##__VA_ARGS__); \ - } while (0) - -/***************************/ -/* Load-time Configuration */ -/***************************/ - -/* Per-instance load-time (note: NOT run-time) configurations - * for Atheros Device */ struct ath_config { u32 ath_aggr_prot; u16 txpowlimit; u16 txpowlimit_override; - u8 cabqReadytime; /* Cabq Readytime % */ - u8 swBeaconProcess; /* Process received beacons in SW (vs HW) */ + u8 cabqReadytime; + u8 swBeaconProcess; }; /*************************/ @@ -160,14 +141,13 @@ enum buffer_type { }; struct ath_buf_state { - int bfs_nframes; /* # frames in aggregate */ - u16 bfs_al; /* length of aggregate */ - u16 bfs_frmlen; /* length of frame */ - int bfs_seqno; /* sequence number */ - int bfs_tidno; /* tid of this frame */ - int bfs_retries; /* current retries */ - u32 bf_type; /* BUF_* (enum buffer_type) */ - /* key type use to encrypt this frame */ + int bfs_nframes; /* # frames in aggregate */ + u16 bfs_al; /* length of aggregate */ + u16 bfs_frmlen; /* length of frame */ + int bfs_seqno; /* sequence number */ + int bfs_tidno; /* tid of this frame */ + int bfs_retries; /* current retries */ + u32 bf_type; /* BUF_* (enum buffer_type) */ u32 bfs_keyix; enum ath9k_key_type bfs_keytype; }; @@ -213,13 +193,6 @@ struct ath_buf { dma_addr_t bf_dmacontext; }; -/* - * reset the rx buffer. - * any new fields added to the athbuf and require - * reset need to be added to this macro. - * currently bf_status is the only one requires that - * requires reset. - */ #define ATH_RXBUF_RESET(_bf) ((_bf)->bf_status = 0) /* hw processing complete, desc processed by hal */ @@ -263,11 +236,8 @@ void ath_rx_cleanup(struct ath_softc *sc); int ath_rx_tasklet(struct ath_softc *sc, int flush); #define ATH_TXBUF 512 -/* max number of transmit attempts (tries) */ #define ATH_TXMAXTRY 13 -/* max number of 11n transmit attempts (tries) */ #define ATH_11N_TXMAXTRY 10 -/* max number of tries for management and control frames */ #define ATH_MGT_TXMAXTRY 4 #define WME_BA_BMP_SIZE 64 #define WME_MAX_BA WME_BA_BMP_SIZE @@ -279,22 +249,12 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush); WME_AC_VO) -/* Wireless Multimedia Extension Defines */ -#define WME_AC_BE 0 /* best effort */ -#define WME_AC_BK 1 /* background */ -#define WME_AC_VI 2 /* video */ -#define WME_AC_VO 3 /* voice */ -#define WME_NUM_AC 4 +#define WME_AC_BE 0 +#define WME_AC_BK 1 +#define WME_AC_VI 2 +#define WME_AC_VO 3 +#define WME_NUM_AC 4 -/* - * Data transmit queue state. One of these exists for each - * hardware transmit queue. Packets sent to us from above - * are assigned to queues based on their priority. Not all - * devices support a complete set of hardware transmit queues. - * For those devices the array sc_ac2q will map multiple - * priorities to fewer hardware queues (typically all to one - * hardware queue). - */ struct ath_txq { u32 axq_qnum; /* hardware q number */ u32 *axq_link; /* link ptr in last TX desc */ @@ -372,14 +332,15 @@ struct ath_xmit_status { #define ATH_TX_BAR 0x04 }; +/* All RSSI values are noise floor adjusted */ struct ath_tx_stat { - int rssi; /* RSSI (noise floor ajusted) */ - int rssictl[ATH_MAX_ANTENNA]; /* RSSI (noise floor ajusted) */ - int rssiextn[ATH_MAX_ANTENNA]; /* RSSI (noise floor ajusted) */ - int rateieee; /* data rate xmitted (IEEE rate code) */ - int rateKbps; /* data rate xmitted (Kbps) */ - int ratecode; /* phy rate code */ - int flags; /* validity flags */ + int rssi; + int rssictl[ATH_MAX_ANTENNA]; + int rssiextn[ATH_MAX_ANTENNA]; + int rateieee; + int rateKbps; + int ratecode; + int flags; /* if any of ctl,extn chain rssis are valid */ #define ATH_TX_CHAIN_RSSI_VALID 0x01 /* if extn chain rssis are valid */ @@ -415,7 +376,7 @@ void ath_tx_cabq(struct ath_softc *sc, struct sk_buff *skb); /**********************/ #define ADDBA_EXCHANGE_ATTEMPTS 10 -#define ATH_AGGR_DELIM_SZ 4 /* delimiter size */ +#define ATH_AGGR_DELIM_SZ 4 #define ATH_AGGR_MINPLEN 256 /* in bytes, minimum packet length */ /* number of delimiters for encryption padding */ #define ATH_AGGR_ENCRYPTDELIM 10 @@ -466,10 +427,9 @@ struct aggr_rifs_param { /* Per-node aggregation state */ struct ath_node_aggr { - struct ath_atx tx; /* node transmit state */ + struct ath_atx tx; }; -/* driver-specific node state */ struct ath_node { struct ath_softc *an_sc; struct ath_node_aggr an_aggr; @@ -500,12 +460,11 @@ void ath_tx_aggr_resume(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid #define ATH_SET_VAP_BSSID_MASK(bssid_mask) \ ((bssid_mask)[0] &= ~(((ATH_BCBUF-1)<<2)|0x02)) -/* driver-specific vap state */ struct ath_vap { - int av_bslot; /* beacon slot index */ - enum ath9k_opmode av_opmode; /* VAP operational mode */ - struct ath_buf *av_bcbuf; /* beacon buffer */ - struct ath_tx_control av_btxctl; /* txctl information for beacon */ + int av_bslot; + enum ath9k_opmode av_opmode; + struct ath_buf *av_bcbuf; + struct ath_tx_control av_btxctl; }; /*******************/ @@ -518,12 +477,11 @@ struct ath_vap { * number of beacon intervals, the game's up. */ #define BSTUCK_THRESH (9 * ATH_BCBUF) -#define ATH_BCBUF 4 /* number of beacon buffers */ -#define ATH_DEFAULT_BINTVAL 100 /* default beacon interval in TU */ +#define ATH_BCBUF 4 +#define ATH_DEFAULT_BINTVAL 100 /* TU */ #define ATH_DEFAULT_BMISS_LIMIT 10 #define IEEE80211_MS_TO_TU(x) (((x) * 1000) / 1024) -/* beacon configuration */ struct ath_beacon_config { u16 beacon_interval; u16 listen_interval; @@ -674,18 +632,18 @@ struct ath_softc { u8 sc_tx_chainmask; u8 sc_rx_chainmask; enum ath9k_int sc_imask; - enum wireless_mode sc_curmode; /* current phy mode */ + enum wireless_mode sc_curmode; enum PROT_MODE sc_protmode; - u8 sc_nbcnvaps; /* # of vaps sending beacons */ - u16 sc_nvaps; /* # of active virtual ap's */ + u8 sc_nbcnvaps; + u16 sc_nvaps; struct ieee80211_vif *sc_vaps[ATH_BCBUF]; u8 sc_mcastantenna; - u8 sc_defant; /* current default antenna */ - u8 sc_rxotherant; /* rx's on non-default antenna */ + u8 sc_defant; + u8 sc_rxotherant; - struct ath9k_node_stats sc_halstats; /* station-mode rssi stats */ + struct ath9k_node_stats sc_halstats; enum ath9k_ht_extprotspacing sc_ht_extprotspacing; enum ath9k_ht_macmode tx_chan_width; @@ -699,22 +657,22 @@ struct ath_softc { } sc_updateslot; /* slot time update fsm */ /* Crypto */ - u32 sc_keymax; /* size of key cache */ - DECLARE_BITMAP(sc_keymap, ATH_KEYMAX); /* key use bit map */ + u32 sc_keymax; + DECLARE_BITMAP(sc_keymap, ATH_KEYMAX); u8 sc_splitmic; /* split TKIP MIC keys */ /* RX */ struct list_head sc_rxbuf; struct ath_descdma sc_rxdma; - int sc_rxbufsize; /* rx size based on mtu */ - u32 *sc_rxlink; /* link ptr in last RX desc */ + int sc_rxbufsize; + u32 *sc_rxlink; /* TX */ struct list_head sc_txbuf; struct ath_txq sc_txq[ATH9K_NUM_TX_QUEUES]; struct ath_descdma sc_txdma; u32 sc_txqsetup; - int sc_haltype2q[ATH9K_WME_AC_VO+1]; /* HAL WME AC -> h/w qnum */ + int sc_haltype2q[ATH9K_WME_AC_VO+1]; u16 seq_no; /* TX sequence number */ /* Beacon */ @@ -724,13 +682,13 @@ struct ath_softc { struct list_head sc_bbuf; u32 sc_bhalq; u32 sc_bmisscount; - u32 ast_be_xmit; /* beacons transmitted */ + u32 ast_be_xmit; u64 bc_tstamp; /* Rate */ struct ieee80211_rate rates[IEEE80211_NUM_BANDS][ATH_RATE_MAX]; struct ath_rate_table *hw_rate_table[ATH9K_MODE_MAX]; - u8 sc_protrix; /* protection rate index */ + u8 sc_protrix; /* Channel, Band */ struct ieee80211_channel channels[IEEE80211_NUM_BANDS][ATH_CHAN_MAX]; @@ -755,6 +713,7 @@ struct ath_softc { struct ath_ani sc_ani; }; +void DPRINTF(struct ath_softc *sc, int dbg_mask, const char *fmt, ...); int ath_reset(struct ath_softc *sc, bool retry_tx); int ath_get_hal_qnum(u16 queue, struct ath_softc *sc); int ath_get_mac80211_qnum(u32 queue, struct ath_softc *sc); diff --git a/drivers/net/wireless/ath9k/eeprom.c b/drivers/net/wireless/ath9k/eeprom.c index 466dbce2c5f7..e180c9043df6 100644 --- a/drivers/net/wireless/ath9k/eeprom.c +++ b/drivers/net/wireless/ath9k/eeprom.c @@ -116,7 +116,7 @@ static int ath9k_hw_flash_map(struct ath_hal *ah) if (!ahp->ah_cal_mem) { DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, - "%s: cannot remap eeprom region \n", __func__); + "cannot remap eeprom region \n"); return -EIO; } @@ -149,7 +149,7 @@ static bool ath9k_hw_fill_eeprom(struct ath_hal *ah) if (!ath9k_hw_use_flash(ah)) { DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, - "%s: Reading from EEPROM, not flash\n", __func__); + "Reading from EEPROM, not flash\n"); ar5416_eep_start_loc = 256; } @@ -162,8 +162,7 @@ static bool ath9k_hw_fill_eeprom(struct ath_hal *ah) if (!ath9k_hw_nvram_read(ah, addr + ar5416_eep_start_loc, eep_data)) { DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, - "%s: Unable to read eeprom region \n", - __func__); + "Unable to read eeprom region \n"); return false; } eep_data++; @@ -185,12 +184,11 @@ static int ath9k_hw_check_eeprom(struct ath_hal *ah) if (!ath9k_hw_nvram_read(ah, AR5416_EEPROM_MAGIC_OFFSET, &magic)) { DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, - "%s: Reading Magic # failed\n", __func__); + "Reading Magic # failed\n"); return false; } - DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, "%s: Read Magic = 0x%04X\n", - __func__, magic); + DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, "Read Magic = 0x%04X\n", magic); if (magic != AR5416_EEPROM_MAGIC) { magic2 = swab16(magic); @@ -1205,11 +1203,11 @@ bool ath9k_hw_set_power_cal_table(struct ath_hal *ah, ((pdadcValues[4 * j + 3] & 0xFF) << 24); REG_WRITE(ah, regOffset, reg32); - DPRINTF(ah->ah_sc, ATH_DBG_PHY_IO, + DPRINTF(ah->ah_sc, ATH_DBG_REG_IO, "PDADC (%d,%4x): %4.4x %8.8x\n", i, regChainOffset, regOffset, reg32); - DPRINTF(ah->ah_sc, ATH_DBG_PHY_IO, + DPRINTF(ah->ah_sc, ATH_DBG_REG_IO, "PDADC: Chain %d | PDADC %3d Value %3d | " "PDADC %3d Value %3d | PDADC %3d Value %3d | " "PDADC %3d Value %3d |\n", diff --git a/drivers/net/wireless/ath9k/hw.c b/drivers/net/wireless/ath9k/hw.c index 6eef10477896..b3f2899026d6 100644 --- a/drivers/net/wireless/ath9k/hw.c +++ b/drivers/net/wireless/ath9k/hw.c @@ -104,9 +104,10 @@ bool ath9k_hw_wait(struct ath_hal *ah, u32 reg, u32 mask, u32 val) udelay(AH_TIME_QUANTUM); } - DPRINTF(ah->ah_sc, ATH_DBG_PHY_IO, - "%s: timeout on reg 0x%x: 0x%08x & 0x%08x != 0x%08x\n", - __func__, reg, REG_READ(ah, reg), mask, val); + + DPRINTF(ah->ah_sc, ATH_DBG_REG_IO, + "timeout on reg 0x%x: 0x%08x & 0x%08x != 0x%08x\n", + reg, REG_READ(ah, reg), mask, val); return false; } @@ -188,8 +189,8 @@ u16 ath9k_hw_computetxtime(struct ath_hal *ah, } break; default: - DPRINTF(ah->ah_sc, ATH_DBG_PHY_IO, - "%s: unknown phy %u (rate ix %u)\n", __func__, + DPRINTF(ah->ah_sc, ATH_DBG_REG_IO, + "Unknown phy %u (rate ix %u)\n", rates->info[rateix].phy, rateix); txTime = 0; break; @@ -355,9 +356,9 @@ static bool ath9k_hw_chip_test(struct ath_hal *ah) rdData = REG_READ(ah, addr); if (rdData != wrData) { DPRINTF(ah->ah_sc, ATH_DBG_REG_IO, - "%s: address test failed " + "address test failed " "addr: 0x%08x - wr:0x%08x != rd:0x%08x\n", - __func__, addr, wrData, rdData); + addr, wrData, rdData); return false; } } @@ -367,9 +368,9 @@ static bool ath9k_hw_chip_test(struct ath_hal *ah) rdData = REG_READ(ah, addr); if (wrData != rdData) { DPRINTF(ah->ah_sc, ATH_DBG_REG_IO, - "%s: address test failed " + "address test failed " "addr: 0x%08x - wr:0x%08x != rd:0x%08x\n", - __func__, addr, wrData, rdData); + addr, wrData, rdData); return false; } } @@ -449,8 +450,7 @@ static struct ath_hal_5416 *ath9k_hw_newstate(u16 devid, ahp = kzalloc(sizeof(struct ath_hal_5416), GFP_KERNEL); if (ahp == NULL) { DPRINTF(sc, ATH_DBG_FATAL, - "%s: cannot allocate memory for state block\n", - __func__); + "Cannot allocate memory for state block\n"); *status = -ENOMEM; return NULL; } @@ -497,8 +497,7 @@ static int ath9k_hw_rfattach(struct ath_hal *ah) rfStatus = ath9k_hw_init_rf(ah, &ecode); if (!rfStatus) { DPRINTF(ah->ah_sc, ATH_DBG_RESET, - "%s: RF setup failed, status %u\n", __func__, - ecode); + "RF setup failed, status %u\n", ecode); return ecode; } @@ -523,9 +522,9 @@ static int ath9k_hw_rf_claim(struct ath_hal *ah) break; default: DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL, - "%s: 5G Radio Chip Rev 0x%02X is not " + "5G Radio Chip Rev 0x%02X is not " "supported by this driver\n", - __func__, ah->ah_analog5GhzRev); + ah->ah_analog5GhzRev); return -EOPNOTSUPP; } @@ -550,7 +549,7 @@ static int ath9k_hw_init_macaddr(struct ath_hal *ah) } if (sum == 0 || sum == 0xffff * 3) { DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, - "%s: mac address read failed: %pM\n", __func__, + "mac address read failed: %pM\n", ahp->ah_macaddr); return -EADDRNOTAVAIL; } @@ -612,7 +611,7 @@ static int ath9k_hw_post_attach(struct ath_hal *ah) if (!ath9k_hw_chip_test(ah)) { DPRINTF(ah->ah_sc, ATH_DBG_REG_IO, - "%s: hardware self-test failed\n", __func__); + "hardware self-test failed\n"); return -ENODEV; } @@ -658,15 +657,13 @@ static struct ath_hal *ath9k_hw_do_attach(u16 devid, struct ath_softc *sc, ahp->ah_intrMitigation = true; if (!ath9k_hw_set_reset_reg(ah, ATH9K_RESET_POWER_ON)) { - DPRINTF(ah->ah_sc, ATH_DBG_RESET, "%s: couldn't reset chip\n", - __func__); + DPRINTF(ah->ah_sc, ATH_DBG_RESET, "Couldn't reset chip\n"); ecode = -EIO; goto bad; } if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE)) { - DPRINTF(ah->ah_sc, ATH_DBG_RESET, "%s: couldn't wakeup chip\n", - __func__); + DPRINTF(ah->ah_sc, ATH_DBG_RESET, "Couldn't wakeup chip\n"); ecode = -EIO; goto bad; } @@ -682,17 +679,16 @@ static struct ath_hal *ath9k_hw_do_attach(u16 devid, struct ath_softc *sc, } DPRINTF(ah->ah_sc, ATH_DBG_RESET, - "%s: serialize_regmode is %d\n", - __func__, ah->ah_config.serialize_regmode); + "serialize_regmode is %d\n", + ah->ah_config.serialize_regmode); if ((ah->ah_macVersion != AR_SREV_VERSION_5416_PCI) && (ah->ah_macVersion != AR_SREV_VERSION_5416_PCIE) && (ah->ah_macVersion != AR_SREV_VERSION_9160) && (!AR_SREV_9100(ah)) && (!AR_SREV_9280(ah))) { DPRINTF(ah->ah_sc, ATH_DBG_RESET, - "%s: Mac Chip Rev 0x%02x.%x is not supported by " - "this driver\n", __func__, - ah->ah_macVersion, ah->ah_macRev); + "Mac Chip Rev 0x%02x.%x is not supported by " + "this driver\n", ah->ah_macVersion, ah->ah_macRev); ecode = -EOPNOTSUPP; goto bad; } @@ -737,7 +733,7 @@ static struct ath_hal *ath9k_hw_do_attach(u16 devid, struct ath_softc *sc, } DPRINTF(ah->ah_sc, ATH_DBG_RESET, - "%s: This Mac Chip Rev 0x%02x.%x is \n", __func__, + "This Mac Chip Rev 0x%02x.%x is \n", ah->ah_macVersion, ah->ah_macRev); if (AR_SREV_9280_20_OR_LATER(ah)) { @@ -874,7 +870,7 @@ static struct ath_hal *ath9k_hw_do_attach(u16 devid, struct ath_softc *sc, #endif if (!ath9k_hw_fill_cap_info(ah)) { DPRINTF(ah->ah_sc, ATH_DBG_RESET, - "%s:failed ath9k_hw_fill_cap_info\n", __func__); + "failed ath9k_hw_fill_cap_info\n"); ecode = -EINVAL; goto bad; } @@ -882,8 +878,7 @@ static struct ath_hal *ath9k_hw_do_attach(u16 devid, struct ath_softc *sc, ecode = ath9k_hw_init_macaddr(ah); if (ecode != 0) { DPRINTF(ah->ah_sc, ATH_DBG_RESET, - "%s: failed initializing mac address\n", - __func__); + "failed initializing mac address\n"); goto bad; } @@ -1080,8 +1075,7 @@ static bool ath9k_hw_set_ack_timeout(struct ath_hal *ah, u32 us) struct ath_hal_5416 *ahp = AH5416(ah); if (us > ath9k_hw_mac_to_usec(ah, MS(0xffffffff, AR_TIME_OUT_ACK))) { - DPRINTF(ah->ah_sc, ATH_DBG_RESET, "%s: bad ack timeout %u\n", - __func__, us); + DPRINTF(ah->ah_sc, ATH_DBG_RESET, "bad ack timeout %u\n", us); ahp->ah_acktimeout = (u32) -1; return false; } else { @@ -1097,8 +1091,7 @@ static bool ath9k_hw_set_cts_timeout(struct ath_hal *ah, u32 us) struct ath_hal_5416 *ahp = AH5416(ah); if (us > ath9k_hw_mac_to_usec(ah, MS(0xffffffff, AR_TIME_OUT_CTS))) { - DPRINTF(ah->ah_sc, ATH_DBG_RESET, "%s: bad cts timeout %u\n", - __func__, us); + DPRINTF(ah->ah_sc, ATH_DBG_RESET, "bad cts timeout %u\n", us); ahp->ah_ctstimeout = (u32) -1; return false; } else { @@ -1115,7 +1108,7 @@ static bool ath9k_hw_set_global_txtimeout(struct ath_hal *ah, u32 tu) if (tu > 0xFFFF) { DPRINTF(ah->ah_sc, ATH_DBG_XMIT, - "%s: bad global tx timeout %u\n", __func__, tu); + "bad global tx timeout %u\n", tu); ahp->ah_globaltxtimeout = (u32) -1; return false; } else { @@ -1129,8 +1122,8 @@ static void ath9k_hw_init_user_settings(struct ath_hal *ah) { struct ath_hal_5416 *ahp = AH5416(ah); - DPRINTF(ah->ah_sc, ATH_DBG_RESET, "--AP %s ahp->ah_miscMode 0x%x\n", - __func__, ahp->ah_miscMode); + DPRINTF(ah->ah_sc, ATH_DBG_RESET, "ahp->ah_miscMode 0x%x\n", + ahp->ah_miscMode); if (ahp->ah_miscMode != 0) REG_WRITE(ah, AR_PCU_MISC, @@ -1176,7 +1169,7 @@ struct ath_hal *ath9k_hw_attach(u16 devid, struct ath_softc *sc, break; default: DPRINTF(ah->ah_sc, ATH_DBG_ANY, - "devid=0x%x not supported.\n", devid); + "devid=0x%x not supported.\n", devid); ah = NULL; *error = -ENXIO; break; @@ -1355,13 +1348,13 @@ static int ath9k_hw_process_ini(struct ath_hal *ah, (u32) ah->ah_powerLimit)); if (status != 0) { DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT, - "%s: error init'ing transmit power\n", __func__); + "error init'ing transmit power\n"); return -EIO; } if (!ath9k_hw_set_rf_regs(ah, chan, freqIndex)) { DPRINTF(ah->ah_sc, ATH_DBG_REG_IO, - "%s: ar5416SetRfRegs failed\n", __func__); + "ar5416SetRfRegs failed\n"); return -EIO; } @@ -1533,8 +1526,7 @@ static bool ath9k_hw_set_reset(struct ath_hal *ah, int type) REG_WRITE(ah, (u16) (AR_RTC_RC), 0); if (!ath9k_hw_wait(ah, (u16) (AR_RTC_RC), AR_RTC_RC_M, 0)) { DPRINTF(ah->ah_sc, ATH_DBG_RESET, - "%s: RTC stuck in MAC reset\n", - __func__); + "RTC stuck in MAC reset\n"); return false; } @@ -1561,8 +1553,7 @@ static bool ath9k_hw_set_reset_power_on(struct ath_hal *ah) AR_RTC_STATUS, AR_RTC_STATUS_M, AR_RTC_STATUS_ON)) { - DPRINTF(ah->ah_sc, ATH_DBG_RESET, "%s: RTC not waking up\n", - __func__); + DPRINTF(ah->ah_sc, ATH_DBG_RESET, "RTC not waking up\n"); return false; } @@ -1641,9 +1632,8 @@ static struct ath9k_channel *ath9k_hw_check_chan(struct ath_hal *ah, { if (!(IS_CHAN_2GHZ(chan) ^ IS_CHAN_5GHZ(chan))) { DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL, - "%s: invalid channel %u/0x%x; not marked as " - "2GHz or 5GHz\n", __func__, chan->channel, - chan->channelFlags); + "invalid channel %u/0x%x; not marked as " + "2GHz or 5GHz\n", chan->channel, chan->channelFlags); return NULL; } @@ -1652,9 +1642,9 @@ static struct ath9k_channel *ath9k_hw_check_chan(struct ath_hal *ah, !IS_CHAN_HT20(chan) && !IS_CHAN_HT40(chan)) { DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL, - "%s: invalid channel %u/0x%x; not marked as " + "invalid channel %u/0x%x; not marked as " "OFDM or CCK or HT20 or HT40PLUS or HT40MINUS\n", - __func__, chan->channel, chan->channelFlags); + chan->channel, chan->channelFlags); return NULL; } @@ -1670,8 +1660,7 @@ static bool ath9k_hw_channel_change(struct ath_hal *ah, for (qnum = 0; qnum < AR_NUM_QCU; qnum++) { if (ath9k_hw_numtxpending(ah, qnum)) { DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, - "%s: Transmit frames pending on queue %d\n", - __func__, qnum); + "Transmit frames pending on queue %d\n", qnum); return false; } } @@ -1679,8 +1668,8 @@ static bool ath9k_hw_channel_change(struct ath_hal *ah, REG_WRITE(ah, AR_PHY_RFBUS_REQ, AR_PHY_RFBUS_REQ_EN); if (!ath9k_hw_wait(ah, AR_PHY_RFBUS_GRANT, AR_PHY_RFBUS_GRANT_EN, AR_PHY_RFBUS_GRANT_EN)) { - DPRINTF(ah->ah_sc, ATH_DBG_PHY_IO, - "%s: Could not kill baseband RX\n", __func__); + DPRINTF(ah->ah_sc, ATH_DBG_REG_IO, + "Could not kill baseband RX\n"); return false; } @@ -1689,13 +1678,13 @@ static bool ath9k_hw_channel_change(struct ath_hal *ah, if (AR_SREV_9280_10_OR_LATER(ah)) { if (!(ath9k_hw_ar9280_set_channel(ah, chan))) { DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL, - "%s: failed to set channel\n", __func__); + "failed to set channel\n"); return false; } } else { if (!(ath9k_hw_set_channel(ah, chan))) { DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL, - "%s: failed to set channel\n", __func__); + "failed to set channel\n"); return false; } } @@ -1707,7 +1696,7 @@ static bool ath9k_hw_channel_change(struct ath_hal *ah, min((u32) MAX_RATE_POWER, (u32) ah->ah_powerLimit)) != 0) { DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, - "%s: error init'ing transmit power\n", __func__); + "error init'ing transmit power\n"); return false; } @@ -2211,8 +2200,8 @@ bool ath9k_hw_reset(struct ath_hal *ah, struct ath9k_channel *chan, if (ath9k_hw_check_chan(ah, chan) == NULL) { DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL, - "%s: invalid channel %u/0x%x; no mapping\n", - __func__, chan->channel, chan->channelFlags); + "invalid channel %u/0x%x; no mapping\n", + chan->channel, chan->channelFlags); ecode = -EINVAL; goto bad; } @@ -2254,8 +2243,7 @@ bool ath9k_hw_reset(struct ath_hal *ah, struct ath9k_channel *chan, ath9k_hw_mark_phy_inactive(ah); if (!ath9k_hw_chip_reset(ah, chan)) { - DPRINTF(ah->ah_sc, ATH_DBG_RESET, "%s: chip reset failed\n", - __func__); + DPRINTF(ah->ah_sc, ATH_DBG_RESET, "chip reset failed\n"); ecode = -EINVAL; goto bad; } @@ -2289,7 +2277,7 @@ bool ath9k_hw_reset(struct ath_hal *ah, struct ath9k_channel *chan, if (!ath9k_hw_eeprom_set_board_values(ah, chan)) { DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, - "%s: error setting board options\n", __func__); + "error setting board options\n"); ecode = -EIO; goto bad; } @@ -2379,15 +2367,13 @@ bool ath9k_hw_reset(struct ath_hal *ah, struct ath9k_channel *chan, mask = REG_READ(ah, AR_CFG); if (mask & (AR_CFG_SWRB | AR_CFG_SWTB | AR_CFG_SWRG)) { DPRINTF(ah->ah_sc, ATH_DBG_RESET, - "%s CFG Byte Swap Set 0x%x\n", __func__, - mask); + "CFG Byte Swap Set 0x%x\n", mask); } else { mask = INIT_CONFIG_STATUS | AR_CFG_SWRB | AR_CFG_SWTB; REG_WRITE(ah, AR_CFG, mask); DPRINTF(ah->ah_sc, ATH_DBG_RESET, - "%s Setting CFG 0x%x\n", __func__, - REG_READ(ah, AR_CFG)); + "Setting CFG 0x%x\n", REG_READ(ah, AR_CFG)); } } else { #ifdef __BIG_ENDIAN @@ -2412,7 +2398,7 @@ bool ath9k_hw_keyreset(struct ath_hal *ah, u16 entry) if (entry >= ah->ah_caps.keycache_size) { DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE, - "%s: entry %u out of range\n", __func__, entry); + "entry %u out of range\n", entry); return false; } @@ -2449,7 +2435,7 @@ bool ath9k_hw_keysetmac(struct ath_hal *ah, u16 entry, const u8 *mac) if (entry >= ah->ah_caps.keycache_size) { DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE, - "%s: entry %u out of range\n", __func__, entry); + "entry %u out of range\n", entry); return false; } @@ -2485,7 +2471,7 @@ bool ath9k_hw_set_keycache_entry(struct ath_hal *ah, u16 entry, if (entry >= pCap->keycache_size) { DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE, - "%s: entry %u out of range\n", __func__, entry); + "entry %u out of range\n", entry); return false; } @@ -2496,8 +2482,7 @@ bool ath9k_hw_set_keycache_entry(struct ath_hal *ah, u16 entry, case ATH9K_CIPHER_AES_CCM: if (!(pCap->hw_caps & ATH9K_HW_CAP_CIPHER_AESCCM)) { DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE, - "%s: AES-CCM not supported by " - "mac rev 0x%x\n", __func__, + "AES-CCM not supported by mac rev 0x%x\n", ah->ah_macRev); return false; } @@ -2508,16 +2493,14 @@ bool ath9k_hw_set_keycache_entry(struct ath_hal *ah, u16 entry, if (ATH9K_IS_MIC_ENABLED(ah) && entry + 64 >= pCap->keycache_size) { DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE, - "%s: entry %u inappropriate for TKIP\n", - __func__, entry); + "entry %u inappropriate for TKIP\n", entry); return false; } break; case ATH9K_CIPHER_WEP: if (k->kv_len < LEN_WEP40) { DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE, - "%s: WEP key length %u too small\n", - __func__, k->kv_len); + "WEP key length %u too small\n", k->kv_len); return false; } if (k->kv_len <= LEN_WEP40) @@ -2532,8 +2515,7 @@ bool ath9k_hw_set_keycache_entry(struct ath_hal *ah, u16 entry, break; default: DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE, - "%s: cipher %u not supported\n", __func__, - k->kv_type); + "cipher %u not supported\n", k->kv_type); return false; } @@ -2682,8 +2664,7 @@ static bool ath9k_hw_set_power_awake(struct ath_hal *ah, } if (i == 0) { DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT, - "%s: Failed to wakeup in %uus\n", - __func__, POWER_UP_TIME / 20); + "Failed to wakeup in %uus\n", POWER_UP_TIME / 20); return false; } } @@ -2705,7 +2686,7 @@ bool ath9k_hw_setpower(struct ath_hal *ah, }; int status = true, setChip = true; - DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT, "%s: %s -> %s (%s)\n", __func__, + DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT, "%s -> %s (%s)\n", modes[ahp->ah_powerMode], modes[mode], setChip ? "set chip " : ""); @@ -2722,7 +2703,7 @@ bool ath9k_hw_setpower(struct ath_hal *ah, break; default: DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT, - "%s: unknown power mode %u\n", __func__, mode); + "Unknown power mode %u\n", mode); return false; } ahp->ah_powerMode = mode; @@ -2899,8 +2880,7 @@ bool ath9k_hw_getisr(struct ath_hal *ah, enum ath9k_int *masked) if (isr & AR_ISR_RXORN) { DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT, - "%s: receive FIFO overrun interrupt\n", - __func__); + "receive FIFO overrun interrupt\n"); } if (!AR_SREV_9100(ah)) { @@ -2926,27 +2906,23 @@ bool ath9k_hw_getisr(struct ath_hal *ah, enum ath9k_int *masked) if (fatal_int) { if (sync_cause & AR_INTR_SYNC_HOST1_FATAL) { DPRINTF(ah->ah_sc, ATH_DBG_ANY, - "%s: received PCI FATAL interrupt\n", - __func__); + "received PCI FATAL interrupt\n"); } if (sync_cause & AR_INTR_SYNC_HOST1_PERR) { DPRINTF(ah->ah_sc, ATH_DBG_ANY, - "%s: received PCI PERR interrupt\n", - __func__); + "received PCI PERR interrupt\n"); } } if (sync_cause & AR_INTR_SYNC_RADM_CPL_TIMEOUT) { DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT, - "%s: AR_INTR_SYNC_RADM_CPL_TIMEOUT\n", - __func__); + "AR_INTR_SYNC_RADM_CPL_TIMEOUT\n"); REG_WRITE(ah, AR_RC, AR_RC_HOSTIF); REG_WRITE(ah, AR_RC, 0); *masked |= ATH9K_INT_FATAL; } if (sync_cause & AR_INTR_SYNC_LOCAL_TIMEOUT) { DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT, - "%s: AR_INTR_SYNC_LOCAL_TIMEOUT\n", - __func__); + "AR_INTR_SYNC_LOCAL_TIMEOUT\n"); } REG_WRITE(ah, AR_INTR_SYNC_CAUSE_CLR, sync_cause); @@ -2968,12 +2944,10 @@ enum ath9k_int ath9k_hw_set_interrupts(struct ath_hal *ah, enum ath9k_int ints) u32 mask, mask2; struct ath9k_hw_capabilities *pCap = &ah->ah_caps; - DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT, "%s: 0x%x => 0x%x\n", __func__, - omask, ints); + DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT, "0x%x => 0x%x\n", omask, ints); if (omask & ATH9K_INT_GLOBAL) { - DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT, "%s: disable IER\n", - __func__); + DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT, "disable IER\n"); REG_WRITE(ah, AR_IER, AR_IER_DISABLE); (void) REG_READ(ah, AR_IER); if (!AR_SREV_9100(ah)) { @@ -3028,8 +3002,7 @@ enum ath9k_int ath9k_hw_set_interrupts(struct ath_hal *ah, enum ath9k_int ints) mask2 |= AR_IMR_S2_CST; } - DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT, "%s: new IMR 0x%x\n", __func__, - mask); + DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT, "new IMR 0x%x\n", mask); REG_WRITE(ah, AR_IMR, mask); mask = REG_READ(ah, AR_IMR_S2) & ~(AR_IMR_S2_TIM | AR_IMR_S2_DTIM | @@ -3049,8 +3022,7 @@ enum ath9k_int ath9k_hw_set_interrupts(struct ath_hal *ah, enum ath9k_int ints) } if (ints & ATH9K_INT_GLOBAL) { - DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT, "%s: enable IER\n", - __func__); + DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT, "enable IER\n"); REG_WRITE(ah, AR_IER, AR_IER_ENABLE); if (!AR_SREV_9100(ah)) { REG_WRITE(ah, AR_INTR_ASYNC_ENABLE, @@ -3156,14 +3128,10 @@ void ath9k_hw_set_sta_beacon_timers(struct ath_hal *ah, else nextTbtt = bs->bs_nexttbtt; - DPRINTF(ah->ah_sc, ATH_DBG_BEACON, "%s: next DTIM %d\n", __func__, - bs->bs_nextdtim); - DPRINTF(ah->ah_sc, ATH_DBG_BEACON, "%s: next beacon %d\n", __func__, - nextTbtt); - DPRINTF(ah->ah_sc, ATH_DBG_BEACON, "%s: beacon period %d\n", __func__, - beaconintval); - DPRINTF(ah->ah_sc, ATH_DBG_BEACON, "%s: DTIM period %d\n", __func__, - dtimperiod); + DPRINTF(ah->ah_sc, ATH_DBG_BEACON, "next DTIM %d\n", bs->bs_nextdtim); + DPRINTF(ah->ah_sc, ATH_DBG_BEACON, "next beacon %d\n", nextTbtt); + DPRINTF(ah->ah_sc, ATH_DBG_BEACON, "beacon period %d\n", beaconintval); + DPRINTF(ah->ah_sc, ATH_DBG_BEACON, "DTIM period %d\n", dtimperiod); REG_WRITE(ah, AR_NEXT_DTIM, TU_TO_USEC(bs->bs_nextdtim - SLEEP_SLOP)); @@ -3216,8 +3184,7 @@ bool ath9k_hw_fill_cap_info(struct ath_hal *ah) else if (ah->ah_currentRD == 0x41) ah->ah_currentRD = 0x43; DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, - "%s: regdomain mapped to 0x%x\n", __func__, - ah->ah_currentRD); + "regdomain mapped to 0x%x\n", ah->ah_currentRD); } eeval = ath9k_hw_get_eeprom(ah, EEP_OP_MODE); @@ -3823,8 +3790,7 @@ void ath9k_hw_reset_tsf(struct ath_hal *ah) count++; if (count > 10) { DPRINTF(ah->ah_sc, ATH_DBG_RESET, - "%s: AR_SLP32_TSF_WRITE_STATUS limit exceeded\n", - __func__); + "AR_SLP32_TSF_WRITE_STATUS limit exceeded\n"); break; } udelay(10); @@ -3849,8 +3815,7 @@ bool ath9k_hw_setslottime(struct ath_hal *ah, u32 us) struct ath_hal_5416 *ahp = AH5416(ah); if (us < ATH9K_SLOT_TIME_9 || us > ath9k_hw_mac_to_usec(ah, 0xffff)) { - DPRINTF(ah->ah_sc, ATH_DBG_RESET, "%s: bad slot time %u\n", - __func__, us); + DPRINTF(ah->ah_sc, ATH_DBG_RESET, "bad slot time %u\n", us); ahp->ah_slottime = (u32) -1; return false; } else { diff --git a/drivers/net/wireless/ath9k/mac.c b/drivers/net/wireless/ath9k/mac.c index 36955e0b1849..8d2b139818ee 100644 --- a/drivers/net/wireless/ath9k/mac.c +++ b/drivers/net/wireless/ath9k/mac.c @@ -25,10 +25,10 @@ static void ath9k_hw_set_txq_interrupts(struct ath_hal *ah, struct ath_hal_5416 *ahp = AH5416(ah); DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT, - "%s: tx ok 0x%x err 0x%x desc 0x%x eol 0x%x urn 0x%x\n", - __func__, ahp->ah_txOkInterruptMask, - ahp->ah_txErrInterruptMask, ahp->ah_txDescInterruptMask, - ahp->ah_txEolInterruptMask, ahp->ah_txUrnInterruptMask); + "tx ok 0x%x err 0x%x desc 0x%x eol 0x%x urn 0x%x\n", + ahp->ah_txOkInterruptMask, ahp->ah_txErrInterruptMask, + ahp->ah_txDescInterruptMask, ahp->ah_txEolInterruptMask, + ahp->ah_txUrnInterruptMask); REG_WRITE(ah, AR_IMR_S0, SM(ahp->ah_txOkInterruptMask, AR_IMR_S0_QCU_TXOK) @@ -126,7 +126,7 @@ bool ath9k_hw_puttxbuf(struct ath_hal *ah, u32 q, u32 txdp) bool ath9k_hw_txstart(struct ath_hal *ah, u32 q) { - DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: queue %u\n", __func__, q); + DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "queue %u\n", q); REG_WRITE(ah, AR_Q_TXE, 1 << q); @@ -207,9 +207,8 @@ bool ath9k_hw_stoptxdma(struct ath_hal *ah, u32 q) break; DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, - "%s: TSF have moved while trying to set " - "quiet time TSF: 0x%08x\n", - __func__, tsfLow); + "TSF have moved while trying to set " + "quiet time TSF: 0x%08x\n", tsfLow); } REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_FORCE_CH_IDLE_HIGH); @@ -222,9 +221,8 @@ bool ath9k_hw_stoptxdma(struct ath_hal *ah, u32 q) while (ath9k_hw_numtxpending(ah, q)) { if ((--wait) == 0) { DPRINTF(ah->ah_sc, ATH_DBG_XMIT, - "%s: Failed to stop Tx DMA in 100 " - "msec after killing last frame\n", - __func__); + "Failed to stop Tx DMA in 100 " + "msec after killing last frame\n"); break; } udelay(100); @@ -523,19 +521,17 @@ bool ath9k_hw_set_txq_props(struct ath_hal *ah, int q, struct ath9k_tx_queue_info *qi; if (q >= pCap->total_queues) { - DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: invalid queue num %u\n", - __func__, q); + DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "invalid queue num %u\n", q); return false; } qi = &ahp->ah_txq[q]; if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) { - DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: inactive queue\n", - __func__); + DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "inactive queue\n"); return false; } - DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: queue %p\n", __func__, qi); + DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "queue %p\n", qi); qi->tqi_ver = qinfo->tqi_ver; qi->tqi_subtype = qinfo->tqi_subtype; @@ -593,15 +589,13 @@ bool ath9k_hw_get_txq_props(struct ath_hal *ah, int q, struct ath9k_tx_queue_info *qi; if (q >= pCap->total_queues) { - DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: invalid queue num %u\n", - __func__, q); + DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "invalid queue num %u\n", q); return false; } qi = &ahp->ah_txq[q]; if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) { - DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: inactive queue\n", - __func__); + DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "inactive queue\n"); return false; } @@ -651,22 +645,21 @@ int ath9k_hw_setuptxqueue(struct ath_hal *ah, enum ath9k_tx_queue type, break; if (q == pCap->total_queues) { DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, - "%s: no available tx queue\n", __func__); + "no available tx queue\n"); return -1; } break; default: - DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: bad tx queue type %u\n", - __func__, type); + DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "bad tx queue type %u\n", type); return -1; } - DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: queue %u\n", __func__, q); + DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "queue %u\n", q); qi = &ahp->ah_txq[q]; if (qi->tqi_type != ATH9K_TX_QUEUE_INACTIVE) { DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, - "%s: tx queue %u already active\n", __func__, q); + "tx queue %u already active\n", q); return -1; } memset(qi, 0, sizeof(struct ath9k_tx_queue_info)); @@ -697,19 +690,16 @@ bool ath9k_hw_releasetxqueue(struct ath_hal *ah, u32 q) struct ath9k_tx_queue_info *qi; if (q >= pCap->total_queues) { - DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: invalid queue num %u\n", - __func__, q); + DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "invalid queue num %u\n", q); return false; } qi = &ahp->ah_txq[q]; if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) { - DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: inactive queue %u\n", - __func__, q); + DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "inactive queue %u\n", q); return false; } - DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: release queue %u\n", - __func__, q); + DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "release queue %u\n", q); qi->tqi_type = ATH9K_TX_QUEUE_INACTIVE; ahp->ah_txOkInterruptMask &= ~(1 << q); @@ -731,19 +721,17 @@ bool ath9k_hw_resettxqueue(struct ath_hal *ah, u32 q) u32 cwMin, chanCwMin, value; if (q >= pCap->total_queues) { - DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: invalid queue num %u\n", - __func__, q); + DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "invalid queue num %u\n", q); return false; } qi = &ahp->ah_txq[q]; if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) { - DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: inactive queue %u\n", - __func__, q); + DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "inactive queue %u\n", q); return true; } - DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: reset queue %u\n", __func__, q); + DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "reset queue %u\n", q); if (qi->tqi_cwmin == ATH9K_TXQ_USEDEFAULT) { if (chan && IS_CHAN_B(chan)) @@ -976,8 +964,7 @@ bool ath9k_hw_setrxabort(struct ath_hal *ah, bool set) reg = REG_READ(ah, AR_OBS_BUS_1); DPRINTF(ah->ah_sc, ATH_DBG_FATAL, - "%s: rx failed to go idle in 10 ms RXSM=0x%x\n", - __func__, reg); + "rx failed to go idle in 10 ms RXSM=0x%x\n", reg); return false; } @@ -1022,9 +1009,8 @@ bool ath9k_hw_stopdmarecv(struct ath_hal *ah) if (!ath9k_hw_wait(ah, AR_CR, AR_CR_RXE, 0)) { DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, - "%s: dma failed to stop in 10ms\n" + "dma failed to stop in 10ms\n" "AR_CR=0x%08x\nAR_DIAG_SW=0x%08x\n", - __func__, REG_READ(ah, AR_CR), REG_READ(ah, AR_DIAG_SW)); return false; } else { diff --git a/drivers/net/wireless/ath9k/main.c b/drivers/net/wireless/ath9k/main.c index e05eb1f07894..de059c38467d 100644 --- a/drivers/net/wireless/ath9k/main.c +++ b/drivers/net/wireless/ath9k/main.c @@ -38,6 +38,21 @@ static struct pci_device_id ath_pci_id_table[] __devinitdata = { static void ath_detach(struct ath_softc *sc); +void DPRINTF(struct ath_softc *sc, int dbg_mask, const char *fmt, ...) +{ + if (!sc) + return; + + if (sc->sc_debug & dbg_mask) { + va_list args; + + va_start(args, fmt); + printk(KERN_DEBUG "ath9k: "); + vprintk(fmt, args); + va_end(args); + } +} + /* return bus cachesize in 4B word units */ static void bus_read_cachesize(struct ath_softc *sc, int *csz) @@ -175,8 +190,8 @@ static void ath_setup_rates(struct ath_softc *sc, enum ieee80211_band band) rate[i].bitrate = rate_table->info[i].ratekbps / 100; rate[i].hw_value = rate_table->info[i].ratecode; sband->n_bitrates++; - DPRINTF(sc, ATH_DBG_CONFIG, "%s: Rate: %2dMbps, ratecode: %2d\n", - __func__, rate[i].bitrate / 10, rate[i].hw_value); + DPRINTF(sc, ATH_DBG_CONFIG, "Rate: %2dMbps, ratecode: %2d\n", + rate[i].bitrate / 10, rate[i].hw_value); } } @@ -198,9 +213,9 @@ static int ath_setup_channels(struct ath_softc *sc) &nregclass, CTRY_DEFAULT, false, 1)) { u32 rd = ah->ah_currentRD; DPRINTF(sc, ATH_DBG_FATAL, - "%s: unable to collect channel list; " + "Unable to collect channel list; " "regdomain likely %u country code %u\n", - __func__, rd, CTRY_DEFAULT); + rd, CTRY_DEFAULT); return -EINVAL; } @@ -223,9 +238,9 @@ static int ath_setup_channels(struct ath_softc *sc) band_2ghz->n_channels = ++a; - DPRINTF(sc, ATH_DBG_CONFIG, "%s: 2MHz channel: %d, " + DPRINTF(sc, ATH_DBG_CONFIG, "2MHz channel: %d, " "channelFlags: 0x%x\n", - __func__, c->channel, c->channelFlags); + c->channel, c->channelFlags); } else if (IS_CHAN_5GHZ(c)) { chan_5ghz[b].band = IEEE80211_BAND_5GHZ; chan_5ghz[b].center_freq = c->channel; @@ -238,9 +253,9 @@ static int ath_setup_channels(struct ath_softc *sc) band_5ghz->n_channels = ++b; - DPRINTF(sc, ATH_DBG_CONFIG, "%s: 5MHz channel: %d, " + DPRINTF(sc, ATH_DBG_CONFIG, "5MHz channel: %d, " "channelFlags: 0x%x\n", - __func__, c->channel, c->channelFlags); + c->channel, c->channelFlags); } } @@ -274,9 +289,9 @@ static int ath_set_channel(struct ath_softc *sc, struct ath9k_channel *hchan) * hardware at the new frequency, and then re-enable * the relevant bits of the h/w. */ - ath9k_hw_set_interrupts(ah, 0); /* disable interrupts */ - ath_draintxq(sc, false); /* clear pending tx frames */ - stopped = ath_stoprecv(sc); /* turn off frame recv */ + ath9k_hw_set_interrupts(ah, 0); + ath_draintxq(sc, false); + stopped = ath_stoprecv(sc); /* XXX: do not flush receive queue here. We don't want * to flush data frames already in queue because of @@ -286,8 +301,7 @@ static int ath_set_channel(struct ath_softc *sc, struct ath9k_channel *hchan) fastcc = false; DPRINTF(sc, ATH_DBG_CONFIG, - "%s: (%u MHz) -> (%u MHz), cflags:%x, chanwidth: %d\n", - __func__, + "(%u MHz) -> (%u MHz), cflags:%x, chanwidth: %d\n", sc->sc_ah->ah_curchan->channel, hchan->channel, hchan->channelFlags, sc->tx_chan_width); @@ -296,8 +310,8 @@ static int ath_set_channel(struct ath_softc *sc, struct ath9k_channel *hchan) sc->sc_tx_chainmask, sc->sc_rx_chainmask, sc->sc_ht_extprotspacing, fastcc, &status)) { DPRINTF(sc, ATH_DBG_FATAL, - "%s: unable to reset channel %u (%uMhz) " - "flags 0x%x hal status %u\n", __func__, + "Unable to reset channel %u (%uMhz) " + "flags 0x%x hal status %u\n", ath9k_hw_mhz2ieee(ah, hchan->channel, hchan->channelFlags), hchan->channel, hchan->channelFlags, status); @@ -311,7 +325,7 @@ static int ath_set_channel(struct ath_softc *sc, struct ath9k_channel *hchan) if (ath_startrecv(sc) != 0) { DPRINTF(sc, ATH_DBG_FATAL, - "%s: unable to restart recv logic\n", __func__); + "Unable to restart recv logic\n"); return -EIO; } @@ -352,8 +366,7 @@ static void ath_ani_calibrate(unsigned long data) /* Long calibration runs independently of short calibration. */ if ((timestamp - sc->sc_ani.sc_longcal_timer) >= ATH_LONG_CALINTERVAL) { longcal = true; - DPRINTF(sc, ATH_DBG_ANI, "%s: longcal @%lu\n", - __func__, jiffies); + DPRINTF(sc, ATH_DBG_ANI, "longcal @%lu\n", jiffies); sc->sc_ani.sc_longcal_timer = timestamp; } @@ -362,8 +375,7 @@ static void ath_ani_calibrate(unsigned long data) if ((timestamp - sc->sc_ani.sc_shortcal_timer) >= ATH_SHORT_CALINTERVAL) { shortcal = true; - DPRINTF(sc, ATH_DBG_ANI, "%s: shortcal @%lu\n", - __func__, jiffies); + DPRINTF(sc, ATH_DBG_ANI, "shortcal @%lu\n", jiffies); sc->sc_ani.sc_shortcal_timer = timestamp; sc->sc_ani.sc_resetcal_timer = timestamp; } @@ -404,15 +416,13 @@ static void ath_ani_calibrate(unsigned long data) ah->ah_curchan); DPRINTF(sc, ATH_DBG_ANI, - "%s: calibrate chan %u/%x nf: %d\n", - __func__, + "calibrate chan %u/%x nf: %d\n", ah->ah_curchan->channel, ah->ah_curchan->channelFlags, sc->sc_ani.sc_noise_floor); } else { DPRINTF(sc, ATH_DBG_ANY, - "%s: calibrate chan %u/%x failed\n", - __func__, + "calibrate chan %u/%x failed\n", ah->ah_curchan->channel, ah->ah_curchan->channelFlags); } @@ -449,8 +459,8 @@ static void ath_update_chainmask(struct ath_softc *sc, int is_ht) sc->sc_rx_chainmask = 1; } - DPRINTF(sc, ATH_DBG_CONFIG, "%s: tx chmask: %d, rx chmask: %d\n", - __func__, sc->sc_tx_chainmask, sc->sc_rx_chainmask); + DPRINTF(sc, ATH_DBG_CONFIG, "tx chmask: %d, rx chmask: %d\n", + sc->sc_tx_chainmask, sc->sc_rx_chainmask); } static void ath_node_attach(struct ath_softc *sc, struct ieee80211_sta *sta) @@ -712,7 +722,7 @@ static int ath_setkey_tkip(struct ath_softc *sc, if (!ath_keyset(sc, key->keyidx, hk, NULL)) { /* Txmic entry failed. No need to proceed further */ DPRINTF(sc, ATH_DBG_KEYCACHE, - "%s Setting TX MIC Key Failed\n", __func__); + "Setting TX MIC Key Failed\n"); return 0; } @@ -836,8 +846,7 @@ static void ath9k_ht_conf(struct ath_softc *sc, ath9k_hw_set11nmac2040(sc->sc_ah, sc->tx_chan_width); DPRINTF(sc, ATH_DBG_CONFIG, - "%s: BSS Changed HT, chanwidth: %d\n", - __func__, sc->tx_chan_width); + "BSS Changed HT, chanwidth: %d\n", sc->tx_chan_width); } } @@ -863,9 +872,7 @@ static void ath9k_bss_assoc_info(struct ath_softc *sc, int pos; if (bss_conf->assoc) { - DPRINTF(sc, ATH_DBG_CONFIG, "%s: Bss Info ASSOC %d\n", - __func__, - bss_conf->aid); + DPRINTF(sc, ATH_DBG_CONFIG, "Bss Info ASSOC %d\n", bss_conf->aid); /* New association, store aid */ if (avp->av_opmode == ATH9K_M_STA) { @@ -888,18 +895,13 @@ static void ath9k_bss_assoc_info(struct ath_softc *sc, ath_update_chainmask(sc, hw->conf.ht.enabled); DPRINTF(sc, ATH_DBG_CONFIG, - "%s: bssid %pM aid 0x%x\n", - __func__, + "bssid %pM aid 0x%x\n", sc->sc_curbssid, sc->sc_curaid); - DPRINTF(sc, ATH_DBG_CONFIG, "%s: Set channel: %d MHz\n", - __func__, - curchan->center_freq); - pos = ath_get_channel(sc, curchan); if (pos == -1) { DPRINTF(sc, ATH_DBG_FATAL, - "%s: Invalid channel\n", __func__); + "Invalid channel: %d\n", curchan->center_freq); return; } @@ -920,14 +922,15 @@ static void ath9k_bss_assoc_info(struct ath_softc *sc, /* set h/w channel */ if (ath_set_channel(sc, &sc->sc_ah->ah_channels[pos]) < 0) - DPRINTF(sc, ATH_DBG_FATAL, - "%s: Unable to set channel\n", __func__); + DPRINTF(sc, ATH_DBG_FATAL, "Unable to set channel: %d\n", + curchan->center_freq); + /* Start ANI */ mod_timer(&sc->sc_ani.timer, jiffies + msecs_to_jiffies(ATH_ANI_POLLINTERVAL)); } else { - DPRINTF(sc, ATH_DBG_CONFIG, "%s: Bss Info DISSOC\n", __func__); + DPRINTF(sc, ATH_DBG_CONFIG, "Bss Info DISSOC\n"); sc->sc_curaid = 0; } } @@ -1066,8 +1069,8 @@ static void ath_radio_enable(struct ath_softc *sc) sc->sc_ht_extprotspacing, false, &status)) { DPRINTF(sc, ATH_DBG_FATAL, - "%s: unable to reset channel %u (%uMhz) " - "flags 0x%x hal status %u\n", __func__, + "Unable to reset channel %u (%uMhz) " + "flags 0x%x hal status %u\n", ath9k_hw_mhz2ieee(ah, ah->ah_curchan->channel, ah->ah_curchan->channelFlags), @@ -1079,7 +1082,7 @@ static void ath_radio_enable(struct ath_softc *sc) ath_update_txpow(sc); if (ath_startrecv(sc) != 0) { DPRINTF(sc, ATH_DBG_FATAL, - "%s: unable to restart recv logic\n", __func__); + "Unable to restart recv logic\n"); return; } @@ -1124,8 +1127,8 @@ static void ath_radio_disable(struct ath_softc *sc) sc->sc_ht_extprotspacing, false, &status)) { DPRINTF(sc, ATH_DBG_FATAL, - "%s: unable to reset channel %u (%uMhz) " - "flags 0x%x hal status %u\n", __func__, + "Unable to reset channel %u (%uMhz) " + "flags 0x%x hal status %u\n", ath9k_hw_mhz2ieee(ah, ah->ah_curchan->channel, ah->ah_curchan->channelFlags), @@ -1205,7 +1208,7 @@ static int ath_sw_toggle_radio(void *data, enum rfkill_state state) sc->sc_flags &= ~SC_OP_RFKILL_SW_BLOCKED; if (sc->sc_flags & SC_OP_RFKILL_HW_BLOCKED) { DPRINTF(sc, ATH_DBG_FATAL, "Can't turn on the" - "radio as it is disabled by h/w \n"); + "radio as it is disabled by h/w\n"); return -EPERM; } ath_radio_enable(sc); @@ -1285,7 +1288,7 @@ static void ath_detach(struct ath_softc *sc) struct ieee80211_hw *hw = sc->hw; int i = 0; - DPRINTF(sc, ATH_DBG_CONFIG, "%s: Detach ATH hw\n", __func__); + DPRINTF(sc, ATH_DBG_CONFIG, "Detach ATH hw\n"); #if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE) ath_deinit_rfkill(sc); @@ -1340,8 +1343,7 @@ static int ath_init(u16 devid, struct ath_softc *sc) ah = ath9k_hw_attach(devid, sc, sc->mem, &status); if (ah == NULL) { DPRINTF(sc, ATH_DBG_FATAL, - "%s: unable to attach hardware; HAL status %u\n", - __func__, status); + "Unable to attach hardware; HAL status %u\n", status); error = -ENXIO; goto bad; } @@ -1351,8 +1353,8 @@ static int ath_init(u16 devid, struct ath_softc *sc) sc->sc_keymax = ah->ah_caps.keycache_size; if (sc->sc_keymax > ATH_KEYMAX) { DPRINTF(sc, ATH_DBG_KEYCACHE, - "%s: Warning, using only %u entries in %u key cache\n", - __func__, ATH_KEYMAX, sc->sc_keymax); + "Warning, using only %u entries in %u key cache\n", + ATH_KEYMAX, sc->sc_keymax); sc->sc_keymax = ATH_KEYMAX; } @@ -1399,14 +1401,14 @@ static int ath_init(u16 devid, struct ath_softc *sc) sc->sc_bhalq = ath_beaconq_setup(ah); if (sc->sc_bhalq == -1) { DPRINTF(sc, ATH_DBG_FATAL, - "%s: unable to setup a beacon xmit queue\n", __func__); + "Unable to setup a beacon xmit queue\n"); error = -EIO; goto bad2; } sc->sc_cabq = ath_txq_setup(sc, ATH9K_TX_QUEUE_CAB, 0); if (sc->sc_cabq == NULL) { DPRINTF(sc, ATH_DBG_FATAL, - "%s: unable to setup CAB xmit queue\n", __func__); + "Unable to setup CAB xmit queue\n"); error = -EIO; goto bad2; } @@ -1421,30 +1423,26 @@ static int ath_init(u16 devid, struct ath_softc *sc) /* NB: ensure BK queue is the lowest priority h/w queue */ if (!ath_tx_setup(sc, ATH9K_WME_AC_BK)) { DPRINTF(sc, ATH_DBG_FATAL, - "%s: unable to setup xmit queue for BK traffic\n", - __func__); + "Unable to setup xmit queue for BK traffic\n"); error = -EIO; goto bad2; } if (!ath_tx_setup(sc, ATH9K_WME_AC_BE)) { DPRINTF(sc, ATH_DBG_FATAL, - "%s: unable to setup xmit queue for BE traffic\n", - __func__); + "Unable to setup xmit queue for BE traffic\n"); error = -EIO; goto bad2; } if (!ath_tx_setup(sc, ATH9K_WME_AC_VI)) { DPRINTF(sc, ATH_DBG_FATAL, - "%s: unable to setup xmit queue for VI traffic\n", - __func__); + "Unable to setup xmit queue for VI traffic\n"); error = -EIO; goto bad2; } if (!ath_tx_setup(sc, ATH9K_WME_AC_VO)) { DPRINTF(sc, ATH_DBG_FATAL, - "%s: unable to setup xmit queue for VO traffic\n", - __func__); + "Unable to setup xmit queue for VO traffic\n"); error = -EIO; goto bad2; } @@ -1556,7 +1554,7 @@ static int ath_attach(u16 devid, struct ath_softc *sc) struct ieee80211_hw *hw = sc->hw; int error = 0; - DPRINTF(sc, ATH_DBG_CONFIG, "%s: Attach ATH hw\n", __func__); + DPRINTF(sc, ATH_DBG_CONFIG, "Attach ATH hw\n"); error = ath_init(devid, sc); if (error != 0) @@ -1587,8 +1585,7 @@ static int ath_attach(u16 devid, struct ath_softc *sc) error = ath_rate_control_register(); if (error != 0) { DPRINTF(sc, ATH_DBG_FATAL, - "%s: Unable to register rate control " - "algorithm:%d\n", __func__, error); + "Unable to register rate control algorithm: %d\n", error); ath_rate_control_unregister(); goto bad; } @@ -1656,15 +1653,13 @@ int ath_reset(struct ath_softc *sc, bool retry_tx) sc->sc_tx_chainmask, sc->sc_rx_chainmask, sc->sc_ht_extprotspacing, false, &status)) { DPRINTF(sc, ATH_DBG_FATAL, - "%s: unable to reset hardware; hal status %u\n", - __func__, status); + "Unable to reset hardware; hal status %u\n", status); error = -EIO; } spin_unlock_bh(&sc->sc_resetlock); if (ath_startrecv(sc) != 0) - DPRINTF(sc, ATH_DBG_FATAL, - "%s: unable to start recv logic\n", __func__); + DPRINTF(sc, ATH_DBG_FATAL, "Unable to start recv logic\n"); /* * We may be doing a reset in response to a request @@ -1712,13 +1707,12 @@ int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd, struct ath_buf *bf; int i, bsize, error; - DPRINTF(sc, ATH_DBG_CONFIG, "%s: %s DMA: %u buffers %u desc/buf\n", - __func__, name, nbuf, ndesc); + DPRINTF(sc, ATH_DBG_CONFIG, "%s DMA: %u buffers %u desc/buf\n", + name, nbuf, ndesc); /* ath_desc must be a multiple of DWORDs */ if ((sizeof(struct ath_desc) % 4) != 0) { - DPRINTF(sc, ATH_DBG_FATAL, "%s: ath_desc not DWORD aligned\n", - __func__); + DPRINTF(sc, ATH_DBG_FATAL, "ath_desc not DWORD aligned\n"); ASSERT((sizeof(struct ath_desc) % 4) == 0); error = -ENOMEM; goto fail; @@ -1754,8 +1748,8 @@ int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd, goto fail; } ds = dd->dd_desc; - DPRINTF(sc, ATH_DBG_CONFIG, "%s: %s DMA map: %p (%u) -> %llx (%u)\n", - __func__, dd->dd_name, ds, (u32) dd->dd_desc_len, + DPRINTF(sc, ATH_DBG_CONFIG, "%s DMA map: %p (%u) -> %llx (%u)\n", + dd->dd_name, ds, (u32) dd->dd_desc_len, ito64(dd->dd_desc_paddr), /*XXX*/(u32) dd->dd_desc_len); /* allocate buffers */ @@ -1877,14 +1871,14 @@ static int ath9k_start(struct ieee80211_hw *hw) struct ath9k_channel *init_channel; int error = 0, pos, status; - DPRINTF(sc, ATH_DBG_CONFIG, "%s: Starting driver with " - "initial channel: %d MHz\n", __func__, curchan->center_freq); + DPRINTF(sc, ATH_DBG_CONFIG, "Starting driver with " + "initial channel: %d MHz\n", curchan->center_freq); /* setup initial channel */ pos = ath_get_channel(sc, curchan); if (pos == -1) { - DPRINTF(sc, ATH_DBG_FATAL, "%s: Invalid channel\n", __func__); + DPRINTF(sc, ATH_DBG_FATAL, "Invalid channel: %d\n", curchan->center_freq); error = -EINVAL; goto error; } @@ -1910,8 +1904,8 @@ static int ath9k_start(struct ieee80211_hw *hw) sc->sc_tx_chainmask, sc->sc_rx_chainmask, sc->sc_ht_extprotspacing, false, &status)) { DPRINTF(sc, ATH_DBG_FATAL, - "%s: unable to reset hardware; hal status %u " - "(freq %u flags 0x%x)\n", __func__, status, + "Unable to reset hardware; hal status %u " + "(freq %u flags 0x%x)\n", status, init_channel->channel, init_channel->channelFlags); error = -EIO; spin_unlock_bh(&sc->sc_resetlock); @@ -1934,7 +1928,7 @@ static int ath9k_start(struct ieee80211_hw *hw) */ if (ath_startrecv(sc) != 0) { DPRINTF(sc, ATH_DBG_FATAL, - "%s: unable to start recv logic\n", __func__); + "Unable to start recv logic\n"); error = -EIO; goto error; } @@ -2026,12 +2020,10 @@ static int ath9k_tx(struct ieee80211_hw *hw, if (!txctl.txq) goto exit; - DPRINTF(sc, ATH_DBG_XMIT, "%s: transmitting packet, skb: %p\n", - __func__, - skb); + DPRINTF(sc, ATH_DBG_XMIT, "transmitting packet, skb: %p\n", skb); if (ath_tx_start(sc, skb, &txctl) != 0) { - DPRINTF(sc, ATH_DBG_XMIT, "%s: TX failed\n", __func__); + DPRINTF(sc, ATH_DBG_XMIT, "TX failed\n"); goto exit; } @@ -2046,11 +2038,11 @@ static void ath9k_stop(struct ieee80211_hw *hw) struct ath_softc *sc = hw->priv; if (sc->sc_flags & SC_OP_INVALID) { - DPRINTF(sc, ATH_DBG_ANY, "%s: Device not present\n", __func__); + DPRINTF(sc, ATH_DBG_ANY, "Device not present\n"); return; } - DPRINTF(sc, ATH_DBG_CONFIG, "%s: Cleaning up\n", __func__); + DPRINTF(sc, ATH_DBG_CONFIG, "Cleaning up\n"); ieee80211_stop_queues(sc->hw); @@ -2075,7 +2067,7 @@ static void ath9k_stop(struct ieee80211_hw *hw) sc->sc_flags |= SC_OP_INVALID; - DPRINTF(sc, ATH_DBG_CONFIG, "%s: Driver halt\n", __func__); + DPRINTF(sc, ATH_DBG_CONFIG, "Driver halt\n"); } static int ath9k_add_interface(struct ieee80211_hw *hw, @@ -2102,14 +2094,11 @@ static int ath9k_add_interface(struct ieee80211_hw *hw, break; default: DPRINTF(sc, ATH_DBG_FATAL, - "%s: Interface type %d not yet supported\n", - __func__, conf->type); + "Interface type %d not yet supported\n", conf->type); return -EOPNOTSUPP; } - DPRINTF(sc, ATH_DBG_CONFIG, "%s: Attach a VAP of type: %d\n", - __func__, - ic_opmode); + DPRINTF(sc, ATH_DBG_CONFIG, "Attach a VAP of type: %d\n", ic_opmode); /* Set the VAP opmode */ avp->av_opmode = ic_opmode; @@ -2140,7 +2129,7 @@ static void ath9k_remove_interface(struct ieee80211_hw *hw, struct ath_softc *sc = hw->priv; struct ath_vap *avp = (void *)conf->vif->drv_priv; - DPRINTF(sc, ATH_DBG_CONFIG, "%s: Detach VAP\n", __func__); + DPRINTF(sc, ATH_DBG_CONFIG, "Detach Interface\n"); #ifdef CONFIG_SLOW_ANT_DIV ath_slow_ant_div_stop(&sc->sc_antdiv); @@ -2170,12 +2159,13 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed) struct ieee80211_channel *curchan = hw->conf.channel; int pos; - DPRINTF(sc, ATH_DBG_CONFIG, "%s: Set channel: %d MHz\n", - __func__, curchan->center_freq); + DPRINTF(sc, ATH_DBG_CONFIG, "Set channel: %d MHz\n", + curchan->center_freq); pos = ath_get_channel(sc, curchan); if (pos == -1) { - DPRINTF(sc, ATH_DBG_FATAL, "%s: Invalid channel\n", __func__); + DPRINTF(sc, ATH_DBG_FATAL, "Invalid channel: %d\n", + curchan->center_freq); return -EINVAL; } @@ -2196,8 +2186,7 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed) } if (ath_set_channel(sc, &sc->sc_ah->ah_channels[pos]) < 0) { - DPRINTF(sc, ATH_DBG_FATAL, - "%s: Unable to set channel\n", __func__); + DPRINTF(sc, ATH_DBG_FATAL, "Unable to set channel\n"); return -EINVAL; } } @@ -2247,9 +2236,8 @@ static int ath9k_config_interface(struct ieee80211_hw *hw, sc->sc_config.ath_aggr_prot = 0; DPRINTF(sc, ATH_DBG_CONFIG, - "%s: RX filter 0x%x bssid %pM aid 0x%x\n", - __func__, rfilt, - sc->sc_curbssid, sc->sc_curaid); + "RX filter 0x%x bssid %pM aid 0x%x\n", + rfilt, sc->sc_curbssid, sc->sc_curaid); /* need to reconfigure the beacon */ sc->sc_flags &= ~SC_OP_BEACONS ; @@ -2326,8 +2314,7 @@ static void ath9k_configure_filter(struct ieee80211_hw *hw, ath9k_hw_write_associd(sc->sc_ah, ath_bcast_mac, 0); } - DPRINTF(sc, ATH_DBG_CONFIG, "%s: Set HW RX filter: 0x%x\n", - __func__, sc->rx_filter); + DPRINTF(sc, ATH_DBG_CONFIG, "Set HW RX filter: 0x%x\n", sc->rx_filter); } static void ath9k_sta_notify(struct ieee80211_hw *hw, @@ -2367,20 +2354,14 @@ static int ath9k_conf_tx(struct ieee80211_hw *hw, qnum = ath_get_hal_qnum(queue, sc); DPRINTF(sc, ATH_DBG_CONFIG, - "%s: Configure tx [queue/halq] [%d/%d], " + "Configure tx [queue/halq] [%d/%d], " "aifs: %d, cw_min: %d, cw_max: %d, txop: %d\n", - __func__, - queue, - qnum, - params->aifs, - params->cw_min, - params->cw_max, - params->txop); + queue, qnum, params->aifs, params->cw_min, + params->cw_max, params->txop); ret = ath_txq_update(sc, qnum, &qi); if (ret) - DPRINTF(sc, ATH_DBG_FATAL, - "%s: TXQ Update failed\n", __func__); + DPRINTF(sc, ATH_DBG_FATAL, "TXQ Update failed\n"); return ret; } @@ -2394,7 +2375,7 @@ static int ath9k_set_key(struct ieee80211_hw *hw, struct ath_softc *sc = hw->priv; int ret = 0; - DPRINTF(sc, ATH_DBG_KEYCACHE, " %s: Set HW Key\n", __func__); + DPRINTF(sc, ATH_DBG_KEYCACHE, "Set HW Key\n"); switch (cmd) { case SET_KEY: @@ -2427,8 +2408,7 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw, struct ath_softc *sc = hw->priv; if (changed & BSS_CHANGED_ERP_PREAMBLE) { - DPRINTF(sc, ATH_DBG_CONFIG, "%s: BSS Changed PREAMBLE %d\n", - __func__, + DPRINTF(sc, ATH_DBG_CONFIG, "BSS Changed PREAMBLE %d\n", bss_conf->use_short_preamble); if (bss_conf->use_short_preamble) sc->sc_flags |= SC_OP_PREAMBLE_SHORT; @@ -2437,8 +2417,7 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw, } if (changed & BSS_CHANGED_ERP_CTS_PROT) { - DPRINTF(sc, ATH_DBG_CONFIG, "%s: BSS Changed CTS PROT %d\n", - __func__, + DPRINTF(sc, ATH_DBG_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) @@ -2451,8 +2430,7 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw, ath9k_ht_conf(sc, bss_conf); if (changed & BSS_CHANGED_ASSOC) { - DPRINTF(sc, ATH_DBG_CONFIG, "%s: BSS Changed ASSOC %d\n", - __func__, + DPRINTF(sc, ATH_DBG_CONFIG, "BSS Changed ASSOC %d\n", bss_conf->assoc); ath9k_bss_assoc_info(sc, vif, bss_conf); } @@ -2496,8 +2474,7 @@ static int ath9k_ampdu_action(struct ieee80211_hw *hw, ret = ath_tx_aggr_start(sc, sta, tid, ssn); if (ret < 0) DPRINTF(sc, ATH_DBG_FATAL, - "%s: Unable to start TX aggregation\n", - __func__); + "Unable to start TX aggregation\n"); else ieee80211_start_tx_ba_cb_irqsafe(hw, sta->addr, tid); break; @@ -2505,8 +2482,7 @@ static int ath9k_ampdu_action(struct ieee80211_hw *hw, ret = ath_tx_aggr_stop(sc, sta, tid); if (ret < 0) DPRINTF(sc, ATH_DBG_FATAL, - "%s: Unable to stop TX aggregation\n", - __func__); + "Unable to stop TX aggregation\n"); ieee80211_stop_tx_ba_cb_irqsafe(hw, sta->addr, tid); break; @@ -2514,8 +2490,7 @@ static int ath9k_ampdu_action(struct ieee80211_hw *hw, ath_tx_aggr_resume(sc, sta, tid); break; default: - DPRINTF(sc, ATH_DBG_FATAL, - "%s: Unknown AMPDU action\n", __func__); + DPRINTF(sc, ATH_DBG_FATAL, "Unknown AMPDU action\n"); } return ret; @@ -2571,7 +2546,6 @@ static struct { /* * Return the MAC/BB name. "????" is returned if the MAC/BB is unknown. */ - static const char * ath_mac_bb_name(u32 mac_bb_version) { @@ -2589,7 +2563,6 @@ ath_mac_bb_name(u32 mac_bb_version) /* * Return the RF name. "????" is returned if the RF is unknown. */ - static const char * ath_rf_name(u16 rf_version) { @@ -2628,7 +2601,7 @@ static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) if (ret) { printk(KERN_ERR "ath9k: 32-bit DMA consistent " - "DMA enable faled\n"); + "DMA enable failed\n"); goto bad; } @@ -2838,6 +2811,6 @@ module_init(init_ath_pci); static void __exit exit_ath_pci(void) { pci_unregister_driver(&ath_pci_driver); - printk(KERN_INFO "%s: driver unloaded\n", dev_info); + printk(KERN_INFO "%s: Driver unloaded\n", dev_info); } module_exit(exit_ath_pci); diff --git a/drivers/net/wireless/ath9k/phy.c b/drivers/net/wireless/ath9k/phy.c index 4f1c8bf8342b..766982a8196e 100644 --- a/drivers/net/wireless/ath9k/phy.c +++ b/drivers/net/wireless/ath9k/phy.c @@ -52,8 +52,7 @@ ath9k_hw_set_channel(struct ath_hal *ah, struct ath9k_channel *chan) bModeSynth = 1; } else { DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL, - "%s: invalid channel %u MHz\n", __func__, - freq); + "Invalid channel %u MHz\n", freq); return false; } @@ -86,7 +85,7 @@ ath9k_hw_set_channel(struct ath_hal *ah, struct ath9k_channel *chan) aModeRefSel = ath9k_hw_reverse_bits(1, 2); } else { DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL, - "%s: invalid channel %u MHz\n", __func__, freq); + "Invalid channel %u MHz\n", freq); return false; } @@ -348,8 +347,7 @@ bool ath9k_hw_init_rf(struct ath_hal *ah, int *status) || ahp->ah_analogBank6TPCData == NULL || ahp->ah_analogBank7Data == NULL) { DPRINTF(ah->ah_sc, ATH_DBG_FATAL, - "%s: cannot allocate RF banks\n", - __func__); + "Cannot allocate RF banks\n"); *status = -ENOMEM; return false; } @@ -360,8 +358,7 @@ bool ath9k_hw_init_rf(struct ath_hal *ah, int *status) ahp->ah_iniAddac.ia_columns), GFP_KERNEL); if (ahp->ah_addac5416_21 == NULL) { DPRINTF(ah->ah_sc, ATH_DBG_FATAL, - "%s: cannot allocate ah_addac5416_21\n", - __func__); + "Cannot allocate ah_addac5416_21\n"); *status = -ENOMEM; return false; } @@ -371,8 +368,7 @@ bool ath9k_hw_init_rf(struct ath_hal *ah, int *status) ahp->ah_iniBank6.ia_rows), GFP_KERNEL); if (ahp->ah_bank6Temp == NULL) { DPRINTF(ah->ah_sc, ATH_DBG_FATAL, - "%s: cannot allocate ah_bank6Temp\n", - __func__); + "Cannot allocate ah_bank6Temp\n"); *status = -ENOMEM; return false; } diff --git a/drivers/net/wireless/ath9k/rc.c b/drivers/net/wireless/ath9k/rc.c index 7c08583a7943..7d5affda3b8b 100644 --- a/drivers/net/wireless/ath9k/rc.c +++ b/drivers/net/wireless/ath9k/rc.c @@ -1326,13 +1326,13 @@ static struct ath_rate_table *ath_choose_rate_table(struct ath_softc *sc, mode = ATH9K_MODE_11NA_HT40PLUS; break; default: - DPRINTF(sc, ATH_DBG_RATE, "Invalid band\n"); + DPRINTF(sc, ATH_DBG_CONFIG, "Invalid band\n"); return NULL; } BUG_ON(mode >= ATH9K_MODE_MAX); - DPRINTF(sc, ATH_DBG_RATE, "Choosing rate table for mode: %d\n", mode); + DPRINTF(sc, ATH_DBG_CONFIG, "Choosing rate table for mode: %d\n", mode); return sc->hw_rate_table[mode]; } @@ -1572,8 +1572,7 @@ static void *ath_rate_alloc_sta(void *priv, struct ieee80211_sta *sta, gfp_t gfp rate_priv = kzalloc(sizeof(struct ath_rate_priv), gfp); if (!rate_priv) { DPRINTF(sc, ATH_DBG_FATAL, - "%s: Unable to allocate private rc structure\n", - __func__); + "Unable to allocate private rc structure\n"); return NULL; } diff --git a/drivers/net/wireless/ath9k/recv.c b/drivers/net/wireless/ath9k/recv.c index e49e32356e92..0b9a3d9c5824 100644 --- a/drivers/net/wireless/ath9k/recv.c +++ b/drivers/net/wireless/ath9k/recv.c @@ -105,8 +105,7 @@ static struct sk_buff *ath_rxbuf_alloc(struct ath_softc *sc, u32 len) skb_reserve(skb, sc->sc_cachelsz - off); } else { DPRINTF(sc, ATH_DBG_FATAL, - "%s: skbuff alloc of size %u failed\n", - __func__, len); + "skbuff alloc of size %u failed\n", len); return NULL; } @@ -263,11 +262,7 @@ static void ath_opmode_init(struct ath_softc *sc) /* calculate and install multicast filter */ mfilt[0] = mfilt[1] = ~0; - ath9k_hw_setmcastfilter(ah, mfilt[0], mfilt[1]); - DPRINTF(sc, ATH_DBG_CONFIG , - "%s: RX filter 0x%x, MC filter %08x:%08x\n", - __func__, rfilt, mfilt[0], mfilt[1]); } int ath_rx_init(struct ath_softc *sc, int nbufs) @@ -285,8 +280,8 @@ int ath_rx_init(struct ath_softc *sc, int nbufs) min(sc->sc_cachelsz, (u16)64)); - DPRINTF(sc, ATH_DBG_CONFIG, "%s: cachelsz %u rxbufsize %u\n", - __func__, sc->sc_cachelsz, sc->sc_rxbufsize); + DPRINTF(sc, ATH_DBG_CONFIG, "cachelsz %u rxbufsize %u\n", + sc->sc_cachelsz, sc->sc_rxbufsize); /* Initialize rx descriptors */ @@ -294,8 +289,7 @@ int ath_rx_init(struct ath_softc *sc, int nbufs) "rx", nbufs, 1); if (error != 0) { DPRINTF(sc, ATH_DBG_FATAL, - "%s: failed to allocate rx descriptors: %d\n", - __func__, error); + "failed to allocate rx descriptors: %d\n", error); break; } diff --git a/drivers/net/wireless/ath9k/regd.c b/drivers/net/wireless/ath9k/regd.c index 62e28887ccd3..e3dd91f7b7b7 100644 --- a/drivers/net/wireless/ath9k/regd.c +++ b/drivers/net/wireless/ath9k/regd.c @@ -78,8 +78,7 @@ static bool ath9k_regd_is_eeprom_valid(struct ath_hal *ah) return true; } DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, - "%s: invalid regulatory domain/country code 0x%x\n", - __func__, rd); + "invalid regulatory domain/country code 0x%x\n", rd); return false; } @@ -107,13 +106,12 @@ static bool ath9k_regd_is_ccode_valid(struct ath_hal *ah, return true; rd = ath9k_regd_get_eepromRD(ah); - DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, "%s: EEPROM regdomain 0x%x\n", - __func__, rd); + DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, "EEPROM regdomain 0x%x\n", rd); if (rd & COUNTRY_ERD_FLAG) { DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, - "%s: EEPROM setting is country code %u\n", - __func__, rd & ~COUNTRY_ERD_FLAG); + "EEPROM setting is country code %u\n", + rd & ~COUNTRY_ERD_FLAG); return cc == (rd & ~COUNTRY_ERD_FLAG); } @@ -290,8 +288,7 @@ ath9k_regd_get_wmode_regdomain(struct ath_hal *ah, int regDmn, } if (!found) { DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, - "%s: Failed to find reg domain pair %u\n", - __func__, regDmn); + "Failed to find reg domain pair %u\n", regDmn); return false; } if (!(channelFlag & CHANNEL_2GHZ)) { @@ -307,8 +304,7 @@ ath9k_regd_get_wmode_regdomain(struct ath_hal *ah, int regDmn, found = ath9k_regd_is_valid_reg_domain(regDmn, rd); if (!found) { DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, - "%s: Failed to find unitary reg domain %u\n", - __func__, regDmn); + "Failed to find unitary reg domain %u\n", regDmn); return false; } else { rd->pscan &= regPair->pscanMask; @@ -430,30 +426,27 @@ ath9k_regd_add_channel(struct ath_hal *ah, if (!(c_lo <= c && c <= c_hi)) { DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, - "%s: c %u out of range [%u..%u]\n", - __func__, c, c_lo, c_hi); + "c %u out of range [%u..%u]\n", + c, c_lo, c_hi); return false; } if ((fband->channelBW == CHANNEL_HALF_BW) && !(ah->ah_caps.hw_caps & ATH9K_HW_CAP_CHAN_HALFRATE)) { DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, - "%s: Skipping %u half rate channel\n", - __func__, c); + "Skipping %u half rate channel\n", c); return false; } if ((fband->channelBW == CHANNEL_QUARTER_BW) && !(ah->ah_caps.hw_caps & ATH9K_HW_CAP_CHAN_QUARTERRATE)) { DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, - "%s: Skipping %u quarter rate channel\n", - __func__, c); + "Skipping %u quarter rate channel\n", c); return false; } if (((c + fband->channelSep) / 2) > (maxChan + HALF_MAXCHANBW)) { DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, - "%s: c %u > maxChan %u\n", - __func__, c, maxChan); + "c %u > maxChan %u\n", c, maxChan); return false; } @@ -606,8 +599,7 @@ static bool ath9k_regd_japan_check(struct ath_hal *ah, } DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, - "%s: Skipping %d freq band\n", - __func__, j_bandcheck[i].freqbandbit); + "Skipping %d freq band\n", j_bandcheck[i].freqbandbit); return skipband; } @@ -632,20 +624,19 @@ ath9k_regd_init_channels(struct ath_hal *ah, unsigned long *modes_avail; DECLARE_BITMAP(modes_allowed, ATH9K_MODE_MAX); - DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, "%s: cc %u %s %s\n", - __func__, cc, + DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, "cc %u %s %s\n", cc, enableOutdoor ? "Enable outdoor" : "", enableExtendedChannels ? "Enable ecm" : ""); if (!ath9k_regd_is_ccode_valid(ah, cc)) { DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, - "%s: invalid country code %d\n", __func__, cc); + "Invalid country code %d\n", cc); return false; } if (!ath9k_regd_is_eeprom_valid(ah)) { DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, - "%s: invalid EEPROM contents\n", __func__); + "Invalid EEPROM contents\n"); return false; } @@ -693,9 +684,9 @@ ath9k_regd_init_channels(struct ath_hal *ah, ~CHANNEL_2GHZ, &rd5GHz)) { DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, - "%s: couldn't find unitary " + "Couldn't find unitary " "5GHz reg domain for country %u\n", - __func__, ah->ah_countryCode); + ah->ah_countryCode); return false; } if (!ath9k_regd_get_wmode_regdomain(ah, @@ -703,9 +694,9 @@ ath9k_regd_init_channels(struct ath_hal *ah, CHANNEL_2GHZ, &rd2GHz)) { DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, - "%s: couldn't find unitary 2GHz " + "Couldn't find unitary 2GHz " "reg domain for country %u\n", - __func__, ah->ah_countryCode); + ah->ah_countryCode); return false; } @@ -717,9 +708,9 @@ ath9k_regd_init_channels(struct ath_hal *ah, ~CHANNEL_2GHZ, &rd5GHz)) { DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, - "%s: couldn't find unitary 5GHz " + "Couldn't find unitary 5GHz " "reg domain for country %u\n", - __func__, ah->ah_countryCode); + ah->ah_countryCode); return false; } } @@ -749,15 +740,14 @@ ath9k_regd_init_channels(struct ath_hal *ah, if (!test_bit(cm->mode, modes_avail)) { DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, - "%s: !avail mode %d flags 0x%x\n", - __func__, cm->mode, cm->flags); + "!avail mode %d flags 0x%x\n", + cm->mode, cm->flags); continue; } if (!ath9k_get_channel_edges(ah, cm->flags, &c_lo, &c_hi)) { DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, - "%s: channels 0x%x not supported " - "by hardware\n", - __func__, cm->flags); + "channels 0x%x not supported " + "by hardware\n", cm->flags); continue; } @@ -788,8 +778,7 @@ ath9k_regd_init_channels(struct ath_hal *ah, break; default: DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, - "%s: Unknown HAL mode 0x%x\n", __func__, - cm->mode); + "Unknown HAL mode 0x%x\n", cm->mode); continue; } @@ -841,9 +830,8 @@ ath9k_regd_init_channels(struct ath_hal *ah, if (next >= maxchans) { DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, - "%s: too many channels " - "for channel table\n", - __func__); + "too many channels " + "for channel table\n"); goto done; } if (ath9k_regd_add_channel(ah, @@ -869,9 +857,8 @@ done: if (next > ARRAY_SIZE(ah->ah_channels)) { DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, - "%s: too many channels %u; truncating to %u\n", - __func__, next, - (int) ARRAY_SIZE(ah->ah_channels)); + "too many channels %u; truncating to %u\n", + next, (int) ARRAY_SIZE(ah->ah_channels)); next = ARRAY_SIZE(ah->ah_channels); } #ifdef ATH_NF_PER_CHAN @@ -919,7 +906,7 @@ ath9k_regd_check_channel(struct ath_hal *ah, int n, lim; DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, - "%s: channel %u/0x%x (0x%x) requested\n", __func__, + "channel %u/0x%x (0x%x) requested\n", c->channel, c->channelFlags, flags); cc = ah->ah_curchan; @@ -950,15 +937,15 @@ ath9k_regd_check_channel(struct ath_hal *ah, d = flags - (cc->channelFlags & CHAN_FLAGS); } DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, - "%s: channel %u/0x%x d %d\n", __func__, + "channel %u/0x%x d %d\n", cc->channel, cc->channelFlags, d); if (d > 0) { base = cc + 1; lim--; } } - DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, "%s: no match for %u/0x%x\n", - __func__, c->channel, c->channelFlags); + DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, "no match for %u/0x%x\n", + c->channel, c->channelFlags); return NULL; } diff --git a/drivers/net/wireless/ath9k/xmit.c b/drivers/net/wireless/ath9k/xmit.c index 413fbdd38ab6..fc52f61ef3ed 100644 --- a/drivers/net/wireless/ath9k/xmit.c +++ b/drivers/net/wireless/ath9k/xmit.c @@ -83,18 +83,16 @@ static void ath_tx_txqaddbuf(struct ath_softc *sc, struct ath_txq *txq, txq->axq_linkbuf = list_entry(txq->axq_q.prev, struct ath_buf, list); DPRINTF(sc, ATH_DBG_QUEUE, - "%s: txq depth = %d\n", __func__, txq->axq_depth); + "qnum: %d, txq depth: %d\n", txq->axq_qnum, txq->axq_depth); if (txq->axq_link == NULL) { ath9k_hw_puttxbuf(ah, txq->axq_qnum, bf->bf_daddr); DPRINTF(sc, ATH_DBG_XMIT, - "%s: TXDP[%u] = %llx (%p)\n", - __func__, txq->axq_qnum, - ito64(bf->bf_daddr), bf->bf_desc); + "TXDP[%u] = %llx (%p)\n", + txq->axq_qnum, ito64(bf->bf_daddr), bf->bf_desc); } else { *txq->axq_link = bf->bf_daddr; - DPRINTF(sc, ATH_DBG_XMIT, "%s: link[%u] (%p)=%llx (%p)\n", - __func__, + DPRINTF(sc, ATH_DBG_XMIT, "link[%u] (%p)=%llx (%p)\n", txq->axq_qnum, txq->axq_link, ito64(bf->bf_daddr), bf->bf_desc); } @@ -109,8 +107,7 @@ static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb, struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); struct ath_tx_info_priv *tx_info_priv = ATH_TX_INFO_PRIV(tx_info); - DPRINTF(sc, ATH_DBG_XMIT, - "%s: TX complete: skb: %p\n", __func__, skb); + DPRINTF(sc, ATH_DBG_XMIT, "TX complete: skb: %p\n", skb); if (tx_info->flags & IEEE80211_TX_CTL_NO_ACK || tx_info->flags & IEEE80211_TX_STAT_TX_FILTERED) { @@ -983,8 +980,7 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq) int txok, nbad = 0; int status; - DPRINTF(sc, ATH_DBG_QUEUE, - "%s: tx queue %d (%x), link %p\n", __func__, + DPRINTF(sc, 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); @@ -1116,9 +1112,9 @@ static void ath_tx_stopdma(struct ath_softc *sc, struct ath_txq *txq) struct ath_hal *ah = sc->sc_ah; (void) ath9k_hw_stoptxdma(ah, txq->axq_qnum); - DPRINTF(sc, ATH_DBG_XMIT, "%s: tx queue [%u] %x, link %p\n", - __func__, txq->axq_qnum, - ath9k_hw_gettxbuf(ah, txq->axq_qnum), txq->axq_link); + DPRINTF(sc, ATH_DBG_XMIT, "tx queue [%u] %x, link %p\n", + txq->axq_qnum, ath9k_hw_gettxbuf(ah, txq->axq_qnum), + txq->axq_link); } /* Drain only the data queues */ @@ -1142,8 +1138,7 @@ static void ath_drain_txdataq(struct ath_softc *sc, bool retry_tx) if (npend) { /* TxDMA not stopped, reset the hal */ - DPRINTF(sc, ATH_DBG_XMIT, - "%s: Unable to stop TxDMA. Reset HAL!\n", __func__); + DPRINTF(sc, ATH_DBG_XMIT, "Unable to stop TxDMA. Reset HAL!\n"); spin_lock_bh(&sc->sc_resetlock); if (!ath9k_hw_reset(ah, @@ -1153,8 +1148,7 @@ static void ath_drain_txdataq(struct ath_softc *sc, bool retry_tx) sc->sc_ht_extprotspacing, true, &status)) { DPRINTF(sc, ATH_DBG_FATAL, - "%s: unable to reset hardware; hal status %u\n", - __func__, + "Unable to reset hardware; hal status %u\n", status); } spin_unlock_bh(&sc->sc_resetlock); @@ -1194,7 +1188,6 @@ static void ath_tx_addto_baw(struct ath_softc *sc, * Function to send an A-MPDU * NB: must be called with txq lock held */ - static int ath_tx_send_ampdu(struct ath_softc *sc, struct ath_atx_tid *tid, struct list_head *bf_head, @@ -1242,7 +1235,6 @@ static int ath_tx_send_ampdu(struct ath_softc *sc, * looks up the rate * returns aggr limit based on lowest of the rates */ - static u32 ath_lookup_rate(struct ath_softc *sc, struct ath_buf *bf, struct ath_atx_tid *tid) @@ -1310,7 +1302,6 @@ static u32 ath_lookup_rate(struct ath_softc *sc, * meet the minimum required mpdudensity. * caller should make sure that the rate is HT rate . */ - static int ath_compute_num_delims(struct ath_softc *sc, struct ath_atx_tid *tid, struct ath_buf *bf, @@ -1382,7 +1373,6 @@ static int ath_compute_num_delims(struct ath_softc *sc, * For aggregation from software buffer queue. * NB: must be called with txq lock held */ - static enum ATH_AGGR_STATUS ath_tx_form_aggr(struct ath_softc *sc, struct ath_atx_tid *tid, struct list_head *bf_q, @@ -1505,7 +1495,6 @@ static enum ATH_AGGR_STATUS ath_tx_form_aggr(struct ath_softc *sc, * process pending frames possibly doing a-mpdu aggregation * NB: must be called with txq lock held */ - static void ath_tx_sched_aggr(struct ath_softc *sc, struct ath_txq *txq, struct ath_atx_tid *tid) { @@ -1635,7 +1624,6 @@ static void ath_tid_drain(struct ath_softc *sc, * Drain all pending buffers * NB: must be called with txq lock held */ - static void ath_txq_drain_pending_buffers(struct ath_softc *sc, struct ath_txq *txq) { @@ -1795,8 +1783,7 @@ int ath_tx_start(struct ath_softc *sc, struct sk_buff *skb, bf = ath_tx_get_buffer(sc); if (!bf) { - DPRINTF(sc, ATH_DBG_XMIT, "%s: TX buffers are full\n", - __func__); + DPRINTF(sc, ATH_DBG_XMIT, "TX buffers are full\n"); return -1; } @@ -1820,8 +1807,8 @@ int ath_tx_init(struct ath_softc *sc, int nbufs) "tx", nbufs, 1); if (error != 0) { DPRINTF(sc, ATH_DBG_FATAL, - "%s: failed to allocate tx descriptors: %d\n", - __func__, error); + "Failed to allocate tx descriptors: %d\n", + error); break; } @@ -1830,9 +1817,8 @@ int ath_tx_init(struct ath_softc *sc, int nbufs) "beacon", ATH_BCBUF, 1); if (error != 0) { DPRINTF(sc, ATH_DBG_FATAL, - "%s: failed to allocate " - "beacon descripotrs: %d\n", - __func__, error); + "Failed to allocate beacon descriptors: %d\n", + error); break; } @@ -1904,8 +1890,8 @@ struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype) } if (qnum >= ARRAY_SIZE(sc->sc_txq)) { DPRINTF(sc, ATH_DBG_FATAL, - "%s: hal qnum %u out of range, max %u!\n", - __func__, qnum, (unsigned int)ARRAY_SIZE(sc->sc_txq)); + "qnum %u out of range, max %u!\n", + qnum, (unsigned int)ARRAY_SIZE(sc->sc_txq)); ath9k_hw_releasetxqueue(ah, qnum); return NULL; } @@ -1950,8 +1936,8 @@ int ath_tx_setup(struct ath_softc *sc, int haltype) if (haltype >= ARRAY_SIZE(sc->sc_haltype2q)) { DPRINTF(sc, ATH_DBG_FATAL, - "%s: HAL AC %u out of range, max %zu!\n", - __func__, haltype, ARRAY_SIZE(sc->sc_haltype2q)); + "HAL AC %u out of range, max %zu!\n", + haltype, ARRAY_SIZE(sc->sc_haltype2q)); return 0; } txq = ath_txq_setup(sc, ATH9K_TX_QUEUE_DATA, haltype); @@ -1970,8 +1956,7 @@ int ath_tx_get_qnum(struct ath_softc *sc, int qtype, int haltype) case ATH9K_TX_QUEUE_DATA: if (haltype >= ARRAY_SIZE(sc->sc_haltype2q)) { DPRINTF(sc, ATH_DBG_FATAL, - "%s: HAL AC %u out of range, max %zu!\n", - __func__, + "HAL AC %u out of range, max %zu!\n", haltype, ARRAY_SIZE(sc->sc_haltype2q)); return -1; } @@ -2004,8 +1989,8 @@ struct ath_txq *ath_test_get_txq(struct ath_softc *sc, struct sk_buff *skb) /* Try to avoid running out of descriptors */ if (txq->axq_depth >= (ATH_TXBUF - 20)) { DPRINTF(sc, ATH_DBG_FATAL, - "%s: TX queue: %d is full, depth: %d\n", - __func__, qnum, txq->axq_depth); + "TX queue: %d is full, depth: %d\n", + qnum, txq->axq_depth); ieee80211_stop_queue(sc->hw, skb_get_queue_mapping(skb)); txq->stopped = 1; spin_unlock_bh(&txq->axq_lock); @@ -2047,8 +2032,7 @@ int ath_txq_update(struct ath_softc *sc, int qnum, if (!ath9k_hw_set_txq_props(ah, qnum, &qi)) { DPRINTF(sc, ATH_DBG_FATAL, - "%s: unable to update hardware queue %u!\n", - __func__, qnum); + "Unable to update hardware queue %u!\n", qnum); error = -EIO; } else { ath9k_hw_resettxqueue(ah, qnum); /* push to h/w */ @@ -2167,7 +2151,7 @@ void ath_draintxq(struct ath_softc *sc, bool retry_tx) * we go to INIT state */ if (!(sc->sc_flags & SC_OP_INVALID)) { (void) ath9k_hw_stoptxdma(sc->sc_ah, sc->sc_bhalq); - DPRINTF(sc, ATH_DBG_XMIT, "%s: beacon queue %x\n", __func__, + DPRINTF(sc, ATH_DBG_XMIT, "beacon queue %x\n", ath9k_hw_gettxbuf(sc->sc_ah, sc->sc_bhalq)); } @@ -2267,8 +2251,6 @@ void ath_tx_aggr_teardown(struct ath_softc *sc, struct ath_node *an, u8 tid) struct list_head bf_head; INIT_LIST_HEAD(&bf_head); - DPRINTF(sc, ATH_DBG_AGGR, "%s: teardown TX aggregation\n", __func__); - if (txtid->state & AGGR_CLEANUP) /* cleanup is in progress */ return; @@ -2501,8 +2483,7 @@ void ath_tx_cabq(struct ath_softc *sc, struct sk_buff *skb) if (hdrlen & 3) { padsize = hdrlen % 4; if (skb_headroom(skb) < padsize) { - DPRINTF(sc, ATH_DBG_XMIT, "%s: TX CABQ padding " - "failed\n", __func__); + DPRINTF(sc, ATH_DBG_XMIT, "TX CABQ padding failed\n"); dev_kfree_skb_any(skb); return; } @@ -2512,12 +2493,10 @@ void ath_tx_cabq(struct ath_softc *sc, struct sk_buff *skb) txctl.txq = sc->sc_cabq; - DPRINTF(sc, ATH_DBG_XMIT, "%s: transmitting CABQ packet, skb: %p\n", - __func__, - skb); + DPRINTF(sc, ATH_DBG_XMIT, "transmitting CABQ packet, skb: %p\n", skb); if (ath_tx_start(sc, skb, &txctl) != 0) { - DPRINTF(sc, ATH_DBG_XMIT, "%s: TX failed\n", __func__); + DPRINTF(sc, ATH_DBG_XMIT, "CABQ TX failed\n"); goto exit; } -- cgit v1.2.3 From d97809dbbf1b8a6df79c82be75fa0cababec783b Mon Sep 17 00:00:00 2001 From: Colin McCabe Date: Mon, 1 Dec 2008 13:38:55 -0800 Subject: ath9k: Replace ath9k_opmode with nl80211_iftype This patch kills ath9k's ath9k_opmode enum by replacing it with nl80211_iftype. Signed-off-by: Colin McCabe Signed-off-by: Andrey Yurovsky Signed-off-by: John W. Linville --- drivers/net/wireless/ath9k/ani.c | 12 ++++----- drivers/net/wireless/ath9k/ath9k.h | 10 ++------ drivers/net/wireless/ath9k/beacon.c | 24 ++++++++--------- drivers/net/wireless/ath9k/core.h | 2 +- drivers/net/wireless/ath9k/hw.c | 29 +++++++++++++-------- drivers/net/wireless/ath9k/main.c | 51 ++++++++++++++++++++----------------- drivers/net/wireless/ath9k/rc.c | 6 ++--- drivers/net/wireless/ath9k/recv.c | 16 ++++++------ drivers/net/wireless/ath9k/regd.c | 2 +- drivers/net/wireless/ath9k/xmit.c | 3 ++- 10 files changed, 81 insertions(+), 74 deletions(-) (limited to 'drivers/net/wireless/ath9k/recv.c') diff --git a/drivers/net/wireless/ath9k/ani.c b/drivers/net/wireless/ath9k/ani.c index c25b72be1139..251e2d9a7a4a 100644 --- a/drivers/net/wireless/ath9k/ani.c +++ b/drivers/net/wireless/ath9k/ani.c @@ -303,7 +303,7 @@ static void ath9k_hw_ani_ofdm_err_trigger(struct ath_hal *ah) } } - if (ah->ah_opmode == ATH9K_M_HOSTAP) { + if (ah->ah_opmode == NL80211_IFTYPE_AP) { if (aniState->firstepLevel < HAL_FIRST_STEP_MAX) { ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL, aniState->firstepLevel + 1); @@ -368,7 +368,7 @@ static void ath9k_hw_ani_cck_err_trigger(struct ath_hal *ah) return; } } - if (ah->ah_opmode == ATH9K_M_HOSTAP) { + if (ah->ah_opmode == NL80211_IFTYPE_AP) { if (aniState->firstepLevel < HAL_FIRST_STEP_MAX) { ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL, aniState->firstepLevel + 1); @@ -398,7 +398,7 @@ static void ath9k_hw_ani_lower_immunity(struct ath_hal *ah) aniState = ahp->ah_curani; - if (ah->ah_opmode == ATH9K_M_HOSTAP) { + if (ah->ah_opmode == NL80211_IFTYPE_AP) { if (aniState->firstepLevel > 0) { if (ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL, aniState->firstepLevel - 1)) @@ -487,8 +487,8 @@ void ath9k_ani_reset(struct ath_hal *ah) aniState = &ahp->ah_ani[index]; ahp->ah_curani = aniState; - if (DO_ANI(ah) && ah->ah_opmode != ATH9K_M_STA - && ah->ah_opmode != ATH9K_M_IBSS) { + if (DO_ANI(ah) && ah->ah_opmode != NL80211_IFTYPE_STATION + && ah->ah_opmode != NL80211_IFTYPE_ADHOC) { DPRINTF(ah->ah_sc, ATH_DBG_ANI, "Reset ANI state opmode %u\n", ah->ah_opmode); ahp->ah_stats.ast_ani_reset++; @@ -504,7 +504,7 @@ void ath9k_ani_reset(struct ath_hal *ah) ath9k_hw_setrxfilter(ah, ath9k_hw_getrxfilter(ah) | ATH9K_RX_FILTER_PHYERR); - if (ah->ah_opmode == ATH9K_M_HOSTAP) { + if (ah->ah_opmode == NL80211_IFTYPE_AP) { ahp->ah_curani->ofdmTrigHigh = ah->ah_config.ofdm_trig_high; ahp->ah_curani->ofdmTrigLow = diff --git a/drivers/net/wireless/ath9k/ath9k.h b/drivers/net/wireless/ath9k/ath9k.h index 9eaa3fce631c..9520aa0898e3 100644 --- a/drivers/net/wireless/ath9k/ath9k.h +++ b/drivers/net/wireless/ath9k/ath9k.h @@ -647,13 +647,6 @@ enum ath9k_ant_setting { ATH9K_ANT_FIXED_B }; -enum ath9k_opmode { - ATH9K_M_STA = 1, - ATH9K_M_IBSS = 0, - ATH9K_M_HOSTAP = 6, - ATH9K_M_MONITOR = 8 -}; - #define ATH9K_SLOT_TIME_6 6 #define ATH9K_SLOT_TIME_9 9 #define ATH9K_SLOT_TIME_20 20 @@ -780,7 +773,8 @@ struct ath_hal { void __iomem *ah_sh; struct ath_softc *ah_sc; - enum ath9k_opmode ah_opmode; + + enum nl80211_iftype ah_opmode; struct ath9k_ops_config ah_config; struct ath9k_hw_capabilities ah_caps; diff --git a/drivers/net/wireless/ath9k/beacon.c b/drivers/net/wireless/ath9k/beacon.c index ca5782fa7627..fe6929dc2937 100644 --- a/drivers/net/wireless/ath9k/beacon.c +++ b/drivers/net/wireless/ath9k/beacon.c @@ -27,7 +27,7 @@ static int ath_beaconq_config(struct ath_softc *sc) struct ath9k_tx_queue_info qi; ath9k_hw_get_txq_props(ah, sc->sc_bhalq, &qi); - if (sc->sc_ah->ah_opmode == ATH9K_M_HOSTAP) { + if (sc->sc_ah->ah_opmode == NL80211_IFTYPE_AP) { /* Always burst out beacon and CAB traffic. */ qi.tqi_aifs = 1; qi.tqi_cwmin = 0; @@ -82,7 +82,7 @@ static void ath_beacon_setup(struct ath_softc *sc, flags = ATH9K_TXDESC_NOACK; - if (sc->sc_ah->ah_opmode == ATH9K_M_IBSS && + if (sc->sc_ah->ah_opmode == NL80211_IFTYPE_ADHOC && (ah->ah_caps.hw_caps & ATH9K_HW_CAP_VEOL)) { ds->ds_link = bf->bf_daddr; /* self-linked */ flags |= ATH9K_TXDESC_VEOL; @@ -302,7 +302,7 @@ int ath_beacon_alloc(struct ath_softc *sc, int if_id) struct ath_buf, list); list_del(&avp->av_bcbuf->list); - if (sc->sc_ah->ah_opmode == ATH9K_M_HOSTAP || + if (sc->sc_ah->ah_opmode == NL80211_IFTYPE_AP || !(sc->sc_ah->ah_caps.hw_caps & ATH9K_HW_CAP_VEOL)) { int slot; /* @@ -607,16 +607,16 @@ void ath_beacon_config(struct ath_softc *sc, int if_id) struct ath_hal *ah = sc->sc_ah; struct ath_beacon_config conf; struct ath_vap *avp; - enum ath9k_opmode av_opmode; + enum nl80211_iftype opmode; u32 nexttbtt, intval; if (if_id != ATH_IF_ID_ANY) { vif = sc->sc_vaps[if_id]; ASSERT(vif); avp = (void *)vif->drv_priv; - av_opmode = avp->av_opmode; + opmode = avp->av_opmode; } else { - av_opmode = sc->sc_ah->ah_opmode; + opmode = sc->sc_ah->ah_opmode; } memset(&conf, 0, sizeof(struct ath_beacon_config)); @@ -632,7 +632,7 @@ void ath_beacon_config(struct ath_softc *sc, int if_id) nexttbtt = TSF_TO_TU(sc->bc_tstamp >> 32, sc->bc_tstamp); /* XXX conditionalize multi-bss support? */ - if (sc->sc_ah->ah_opmode == ATH9K_M_HOSTAP) { + if (sc->sc_ah->ah_opmode == NL80211_IFTYPE_AP) { /* * For multi-bss ap support beacons are either staggered * evenly over N slots or burst together. For the former @@ -654,8 +654,8 @@ void ath_beacon_config(struct ath_softc *sc, int if_id) DPRINTF(sc, ATH_DBG_BEACON, "nexttbtt %u intval %u (%u)\n", nexttbtt, intval, conf.beacon_interval); - /* Check for ATH9K_M_HOSTAP and sc_nostabeacons for WDS client */ - if (sc->sc_ah->ah_opmode == ATH9K_M_STA) { + /* Check for NL80211_IFTYPE_AP and sc_nostabeacons for WDS client */ + if (sc->sc_ah->ah_opmode == NL80211_IFTYPE_STATION) { struct ath9k_beacon_state bs; u64 tsf; u32 tsftu; @@ -774,7 +774,7 @@ void ath_beacon_config(struct ath_softc *sc, int if_id) ath9k_hw_set_interrupts(ah, 0); if (nexttbtt == intval) intval |= ATH9K_BEACON_RESET_TSF; - if (sc->sc_ah->ah_opmode == ATH9K_M_IBSS) { + if (sc->sc_ah->ah_opmode == NL80211_IFTYPE_ADHOC) { /* * Pull nexttbtt forward to reflect the current * TSF @@ -806,7 +806,7 @@ void ath_beacon_config(struct ath_softc *sc, int if_id) if (!(ah->ah_caps.hw_caps & ATH9K_HW_CAP_VEOL)) sc->sc_imask |= ATH9K_INT_SWBA; ath_beaconq_config(sc); - } else if (sc->sc_ah->ah_opmode == ATH9K_M_HOSTAP) { + } else if (sc->sc_ah->ah_opmode == NL80211_IFTYPE_AP) { /* * In AP mode we enable the beacon timers and * SWBA interrupts to prepare beacon frames. @@ -822,7 +822,7 @@ void ath_beacon_config(struct ath_softc *sc, int if_id) * When using a self-linked beacon descriptor in * ibss mode load it once here. */ - if (sc->sc_ah->ah_opmode == ATH9K_M_IBSS && + if (sc->sc_ah->ah_opmode == NL80211_IFTYPE_ADHOC && (ah->ah_caps.hw_caps & ATH9K_HW_CAP_VEOL)) ath_beacon_start_adhoc(sc, 0); } diff --git a/drivers/net/wireless/ath9k/core.h b/drivers/net/wireless/ath9k/core.h index 8c11c0f5c644..a500d1770534 100644 --- a/drivers/net/wireless/ath9k/core.h +++ b/drivers/net/wireless/ath9k/core.h @@ -474,7 +474,7 @@ void ath_tx_aggr_resume(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid struct ath_vap { int av_bslot; - enum ath9k_opmode av_opmode; + enum nl80211_iftype av_opmode; struct ath_buf *av_bcbuf; struct ath_tx_control av_btxctl; }; diff --git a/drivers/net/wireless/ath9k/hw.c b/drivers/net/wireless/ath9k/hw.c index b3f2899026d6..668865dce533 100644 --- a/drivers/net/wireless/ath9k/hw.c +++ b/drivers/net/wireless/ath9k/hw.c @@ -1040,7 +1040,8 @@ static void ath9k_hw_init_chain_masks(struct ath_hal *ah) REG_READ(ah, AR_PHY_ANALOG_SWAP) | 0x00000001); } -static void ath9k_hw_init_interrupt_masks(struct ath_hal *ah, enum ath9k_opmode opmode) +static void ath9k_hw_init_interrupt_masks(struct ath_hal *ah, + enum nl80211_iftype opmode) { struct ath_hal_5416 *ahp = AH5416(ah); @@ -1057,7 +1058,7 @@ static void ath9k_hw_init_interrupt_masks(struct ath_hal *ah, enum ath9k_opmode ahp->ah_maskReg |= AR_IMR_TXOK; - if (opmode == ATH9K_M_HOSTAP) + if (opmode == NL80211_IFTYPE_AP) ahp->ah_maskReg |= AR_IMR_MIB; REG_WRITE(ah, AR_IMR, ahp->ah_maskReg); @@ -1423,18 +1424,18 @@ static void ath9k_hw_set_operating_mode(struct ath_hal *ah, int opmode) val = REG_READ(ah, AR_STA_ID1); val &= ~(AR_STA_ID1_STA_AP | AR_STA_ID1_ADHOC); switch (opmode) { - case ATH9K_M_HOSTAP: + case NL80211_IFTYPE_AP: REG_WRITE(ah, AR_STA_ID1, val | AR_STA_ID1_STA_AP | AR_STA_ID1_KSRCH_MODE); REG_CLR_BIT(ah, AR_CFG, AR_CFG_AP_ADHOC_INDICATION); break; - case ATH9K_M_IBSS: + case NL80211_IFTYPE_ADHOC: REG_WRITE(ah, AR_STA_ID1, val | AR_STA_ID1_ADHOC | AR_STA_ID1_KSRCH_MODE); REG_SET_BIT(ah, AR_CFG, AR_CFG_AP_ADHOC_INDICATION); break; - case ATH9K_M_STA: - case ATH9K_M_MONITOR: + case NL80211_IFTYPE_STATION: + case NL80211_IFTYPE_MONITOR: REG_WRITE(ah, AR_STA_ID1, val | AR_STA_ID1_KSRCH_MODE); break; } @@ -3054,14 +3055,14 @@ void ath9k_hw_beaconinit(struct ath_hal *ah, u32 next_beacon, u32 beacon_period) ahp->ah_beaconInterval = beacon_period; switch (ah->ah_opmode) { - case ATH9K_M_STA: - case ATH9K_M_MONITOR: + case NL80211_IFTYPE_STATION: + case NL80211_IFTYPE_MONITOR: REG_WRITE(ah, AR_NEXT_TBTT_TIMER, TU_TO_USEC(next_beacon)); REG_WRITE(ah, AR_NEXT_DMA_BEACON_ALERT, 0xffff); REG_WRITE(ah, AR_NEXT_SWBA, 0x7ffff); flags |= AR_TBTT_TIMER_EN; break; - case ATH9K_M_IBSS: + case NL80211_IFTYPE_ADHOC: REG_SET_BIT(ah, AR_TXCFG, AR_TXCFG_ADHOC_BEACON_ATIM_TX_POLICY); REG_WRITE(ah, AR_NEXT_NDP_TIMER, @@ -3069,7 +3070,7 @@ void ath9k_hw_beaconinit(struct ath_hal *ah, u32 next_beacon, u32 beacon_period) (ahp->ah_atimWindow ? ahp-> ah_atimWindow : 1))); flags |= AR_NDP_TIMER_EN; - case ATH9K_M_HOSTAP: + case NL80211_IFTYPE_AP: REG_WRITE(ah, AR_NEXT_TBTT_TIMER, TU_TO_USEC(next_beacon)); REG_WRITE(ah, AR_NEXT_DMA_BEACON_ALERT, TU_TO_USEC(next_beacon - @@ -3082,6 +3083,12 @@ void ath9k_hw_beaconinit(struct ath_hal *ah, u32 next_beacon, u32 beacon_period) flags |= AR_TBTT_TIMER_EN | AR_DBA_TIMER_EN | AR_SWBA_TIMER_EN; break; + default: + DPRINTF(ah->ah_sc, ATH_DBG_BEACON, + "%s: unsupported opmode: %d\n", + __func__, ah->ah_opmode); + return; + break; } REG_WRITE(ah, AR_BEACON_PERIOD, TU_TO_USEC(beacon_period)); @@ -3177,7 +3184,7 @@ bool ath9k_hw_fill_cap_info(struct ath_hal *ah) capField = ath9k_hw_get_eeprom(ah, EEP_OP_CAP); - if (ah->ah_opmode != ATH9K_M_HOSTAP && + if (ah->ah_opmode != NL80211_IFTYPE_AP && ah->ah_subvendorid == AR_SUBVENDOR_ID_NEW_A) { if (ah->ah_currentRD == 0x64 || ah->ah_currentRD == 0x65) ah->ah_currentRD += 5; diff --git a/drivers/net/wireless/ath9k/main.c b/drivers/net/wireless/ath9k/main.c index ac37605d65af..3d7111e9b8d8 100644 --- a/drivers/net/wireless/ath9k/main.c +++ b/drivers/net/wireless/ath9k/main.c @@ -754,13 +754,17 @@ static int ath_key_config(struct ath_softc *sc, /* * Strategy: - * For _M_STA mc tx, we will not setup a key at all since we never - * tx mc. - * _M_STA mc rx, we will use the keyID. - * for _M_IBSS mc tx, we will use the keyID, and no macaddr. - * for _M_IBSS mc rx, we will alloc a slot and plumb the mac of the - * peer node. BUT we will plumb a cleartext key so that we can do - * perSta default key table lookup in software. + * For STA mc tx, we will not setup a key at + * all since we never tx mc. + * + * For STA mc rx, we will use the keyID. + * + * For ADHOC mc tx, we will use the keyID, and no macaddr. + * + * For ADHOC mc rx, we will alloc a slot and plumb the mac of + * the peer node. + * BUT we will plumb a cleartext key so that we can do + * per-Sta default key table lookup in software. */ if (is_broadcast_ether_addr(addr)) { switch (opmode) { @@ -861,7 +865,7 @@ static void ath9k_bss_assoc_info(struct ath_softc *sc, DPRINTF(sc, ATH_DBG_CONFIG, "Bss Info ASSOC %d\n", bss_conf->aid); /* New association, store aid */ - if (avp->av_opmode == ATH9K_M_STA) { + if (avp->av_opmode == NL80211_IFTYPE_STATION) { sc->sc_curaid = bss_conf->aid; ath9k_hw_write_associd(sc->sc_ah, sc->sc_curbssid, sc->sc_curaid); @@ -1373,7 +1377,8 @@ static int ath_init(u16 devid, struct ath_softc *sc) goto bad; /* default to MONITOR mode */ - sc->sc_ah->ah_opmode = ATH9K_M_MONITOR; + sc->sc_ah->ah_opmode = NL80211_IFTYPE_MONITOR; + /* Setup rate tables */ @@ -1938,8 +1943,8 @@ static int ath9k_start(struct ieee80211_hw *hw) * Note we only do this (at the moment) for station mode. */ if (ath9k_hw_phycounters(sc->sc_ah) && - ((sc->sc_ah->ah_opmode == ATH9K_M_STA) || - (sc->sc_ah->ah_opmode == ATH9K_M_IBSS))) + ((sc->sc_ah->ah_opmode == NL80211_IFTYPE_STATION) || + (sc->sc_ah->ah_opmode == NL80211_IFTYPE_ADHOC))) sc->sc_imask |= ATH9K_INT_MIB; /* * Some hardware processes the TIM IE and fires an @@ -1948,7 +1953,7 @@ static int ath9k_start(struct ieee80211_hw *hw) * enable the TIM interrupt when operating as station. */ if ((sc->sc_ah->ah_caps.hw_caps & ATH9K_HW_CAP_ENHANCEDPM) && - (sc->sc_ah->ah_opmode == ATH9K_M_STA) && + (sc->sc_ah->ah_opmode == NL80211_IFTYPE_STATION) && !sc->sc_config.swBeaconProcess) sc->sc_imask |= ATH9K_INT_TIM; @@ -2064,7 +2069,7 @@ static int ath9k_add_interface(struct ieee80211_hw *hw, { struct ath_softc *sc = hw->priv; struct ath_vap *avp = (void *)conf->vif->drv_priv; - int ic_opmode = 0; + enum nl80211_iftype ic_opmode = NL80211_IFTYPE_UNSPECIFIED; /* Support only vap for now */ @@ -2073,13 +2078,13 @@ static int ath9k_add_interface(struct ieee80211_hw *hw, switch (conf->type) { case NL80211_IFTYPE_STATION: - ic_opmode = ATH9K_M_STA; + ic_opmode = NL80211_IFTYPE_STATION; break; case NL80211_IFTYPE_ADHOC: - ic_opmode = ATH9K_M_IBSS; + ic_opmode = NL80211_IFTYPE_ADHOC; break; case NL80211_IFTYPE_AP: - ic_opmode = ATH9K_M_HOSTAP; + ic_opmode = NL80211_IFTYPE_AP; break; default: DPRINTF(sc, ATH_DBG_FATAL, @@ -2093,7 +2098,7 @@ static int ath9k_add_interface(struct ieee80211_hw *hw, avp->av_opmode = ic_opmode; avp->av_bslot = -1; - if (ic_opmode == ATH9K_M_HOSTAP) + if (ic_opmode == NL80211_IFTYPE_AP) ath9k_hw_set_tsfadjust(sc->sc_ah, 1); sc->sc_vaps[0] = conf->vif; @@ -2127,8 +2132,8 @@ static void ath9k_remove_interface(struct ieee80211_hw *hw, del_timer_sync(&sc->sc_ani.timer); /* Reclaim beacon resources */ - if (sc->sc_ah->ah_opmode == ATH9K_M_HOSTAP || - sc->sc_ah->ah_opmode == ATH9K_M_IBSS) { + if (sc->sc_ah->ah_opmode == NL80211_IFTYPE_AP || + sc->sc_ah->ah_opmode == NL80211_IFTYPE_ADHOC) { ath9k_hw_stoptxdma(sc->sc_ah, sc->sc_bhalq); ath_beacon_return(sc, avp); } @@ -2163,7 +2168,7 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed) (curchan->band == IEEE80211_BAND_2GHZ) ? CHANNEL_G : CHANNEL_A; - if ((sc->sc_ah->ah_opmode == ATH9K_M_HOSTAP) && + if ((sc->sc_ah->ah_opmode == NL80211_IFTYPE_AP) && (conf->ht.enabled)) { sc->tx_chan_width = (!!conf->ht.sec_chan_offset) ? ATH9K_HT_MACMODE_2040 : ATH9K_HT_MACMODE_20; @@ -2202,8 +2207,8 @@ static int ath9k_config_interface(struct ieee80211_hw *hw, /* TODO: Need to decide which hw opmode to use for multi-interface * cases */ if (vif->type == NL80211_IFTYPE_AP && - ah->ah_opmode != ATH9K_M_HOSTAP) { - ah->ah_opmode = ATH9K_M_HOSTAP; + ah->ah_opmode != NL80211_IFTYPE_AP) { + ah->ah_opmode = NL80211_IFTYPE_STATION; ath9k_hw_setopmode(ah); ath9k_hw_write_associd(ah, sc->sc_myaddr, 0); /* Request full reset to get hw opmode changed properly */ @@ -2258,7 +2263,7 @@ static int ath9k_config_interface(struct ieee80211_hw *hw, } /* Check for WLAN_CAPABILITY_PRIVACY ? */ - if ((avp->av_opmode != ATH9K_M_STA)) { + if ((avp->av_opmode != NL80211_IFTYPE_STATION)) { for (i = 0; i < IEEE80211_WEP_NKID; i++) if (ath9k_hw_keyisvalid(sc->sc_ah, (u16)i)) ath9k_hw_keysetmac(sc->sc_ah, diff --git a/drivers/net/wireless/ath9k/rc.c b/drivers/net/wireless/ath9k/rc.c index 7d5affda3b8b..76acd2b75fcd 100644 --- a/drivers/net/wireless/ath9k/rc.c +++ b/drivers/net/wireless/ath9k/rc.c @@ -1347,13 +1347,13 @@ static void ath_rc_init(struct ath_softc *sc, u8 i, j, k, hi = 0, hthi = 0; /* FIXME: Adhoc */ - if ((sc->sc_ah->ah_opmode == ATH9K_M_STA) || - (sc->sc_ah->ah_opmode == ATH9K_M_IBSS)) { + if ((sc->sc_ah->ah_opmode == NL80211_IFTYPE_STATION) || + (sc->sc_ah->ah_opmode == NL80211_IFTYPE_ADHOC)) { bool is_cw_40 = sta->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40; rate_table = ath_choose_rate_table(sc, sband->band, sta->ht_cap.ht_supported, is_cw_40); - } else if (sc->sc_ah->ah_opmode == ATH9K_M_HOSTAP) { + } else if (sc->sc_ah->ah_opmode == NL80211_IFTYPE_AP) { /* sc_curmode would be set on init through config() */ rate_table = sc->hw_rate_table[sc->sc_curmode]; } diff --git a/drivers/net/wireless/ath9k/recv.c b/drivers/net/wireless/ath9k/recv.c index 0b9a3d9c5824..51e058710d17 100644 --- a/drivers/net/wireless/ath9k/recv.c +++ b/drivers/net/wireless/ath9k/recv.c @@ -165,7 +165,7 @@ static int ath_rx_prepare(struct sk_buff *skb, struct ath_desc *ds, * discard the frame. Enable this if you want to see * error frames in Monitor mode. */ - if (sc->sc_ah->ah_opmode != ATH9K_M_MONITOR) + if (sc->sc_ah->ah_opmode != NL80211_IFTYPE_MONITOR) goto rx_next; } else if (ds->ds_rxstat.rs_status != 0) { if (ds->ds_rxstat.rs_status & ATH9K_RXERR_CRC) @@ -191,7 +191,7 @@ static int ath_rx_prepare(struct sk_buff *skb, struct ath_desc *ds, * decryption and MIC failures. For monitor mode, * we also ignore the CRC error. */ - if (sc->sc_ah->ah_opmode == ATH9K_M_MONITOR) { + if (sc->sc_ah->ah_opmode == NL80211_IFTYPE_MONITOR) { if (ds->ds_rxstat.rs_status & ~(ATH9K_RXERR_DECRYPT | ATH9K_RXERR_MIC | ATH9K_RXERR_CRC)) @@ -361,25 +361,25 @@ u32 ath_calcrxfilter(struct ath_softc *sc) | ATH9K_RX_FILTER_MCAST; /* If not a STA, enable processing of Probe Requests */ - if (sc->sc_ah->ah_opmode != ATH9K_M_STA) + if (sc->sc_ah->ah_opmode != NL80211_IFTYPE_STATION) rfilt |= ATH9K_RX_FILTER_PROBEREQ; /* Can't set HOSTAP into promiscous mode */ - if (((sc->sc_ah->ah_opmode != ATH9K_M_HOSTAP) && + if (((sc->sc_ah->ah_opmode != NL80211_IFTYPE_AP) && (sc->rx_filter & FIF_PROMISC_IN_BSS)) || - (sc->sc_ah->ah_opmode == ATH9K_M_MONITOR)) { + (sc->sc_ah->ah_opmode == NL80211_IFTYPE_MONITOR)) { rfilt |= ATH9K_RX_FILTER_PROM; /* ??? To prevent from sending ACK */ rfilt &= ~ATH9K_RX_FILTER_UCAST; } - if (sc->sc_ah->ah_opmode == ATH9K_M_STA || - sc->sc_ah->ah_opmode == ATH9K_M_IBSS) + if (sc->sc_ah->ah_opmode == NL80211_IFTYPE_STATION || + sc->sc_ah->ah_opmode == NL80211_IFTYPE_ADHOC) rfilt |= ATH9K_RX_FILTER_BEACON; /* If in HOSTAP mode, want to enable reception of PSPOLL frames & beacon frames */ - if (sc->sc_ah->ah_opmode == ATH9K_M_HOSTAP) + if (sc->sc_ah->ah_opmode == NL80211_IFTYPE_AP) rfilt |= (ATH9K_RX_FILTER_BEACON | ATH9K_RX_FILTER_PSPOLL); return rfilt; diff --git a/drivers/net/wireless/ath9k/regd.c b/drivers/net/wireless/ath9k/regd.c index e3dd91f7b7b7..42ce1d9abad0 100644 --- a/drivers/net/wireless/ath9k/regd.c +++ b/drivers/net/wireless/ath9k/regd.c @@ -456,7 +456,7 @@ ath9k_regd_add_channel(struct ath_hal *ah, return false; } - if ((rd->flags & NO_HOSTAP) && (ah->ah_opmode == ATH9K_M_HOSTAP)) { + if ((rd->flags & NO_HOSTAP) && (ah->ah_opmode == NL80211_IFTYPE_AP)) { DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, "Skipping HOSTAP channel\n"); return false; diff --git a/drivers/net/wireless/ath9k/xmit.c b/drivers/net/wireless/ath9k/xmit.c index fc52f61ef3ed..5cf83111e1a7 100644 --- a/drivers/net/wireless/ath9k/xmit.c +++ b/drivers/net/wireless/ath9k/xmit.c @@ -760,7 +760,8 @@ static void ath_tx_complete_aggr_rifs(struct ath_softc *sc, * when perform internal reset in this routine. * Only enable reset in STA mode for now. */ - if (sc->sc_ah->ah_opmode == ATH9K_M_STA) + if (sc->sc_ah->ah_opmode == + NL80211_IFTYPE_STATION) needreset = 1; } } else { -- cgit v1.2.3 From f8316df10c4e3bec5b4c3a5a8e026c577640c3a6 Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Wed, 3 Dec 2008 03:35:29 -0800 Subject: ath9k: Check for pci_map_single() errors pci_map_single() can fail so detect those errors with pci_dma_mapping_error() and deal with them accordingly. Signed-off-by: Luis R. Rodriguez Signed-off-by: John W. Linville --- drivers/net/wireless/ath9k/beacon.c | 16 +++++++++++++++- drivers/net/wireless/ath9k/recv.c | 17 +++++++++++++++++ drivers/net/wireless/ath9k/xmit.c | 23 +++++++++++++++++++++-- 3 files changed, 53 insertions(+), 3 deletions(-) (limited to 'drivers/net/wireless/ath9k/recv.c') diff --git a/drivers/net/wireless/ath9k/beacon.c b/drivers/net/wireless/ath9k/beacon.c index fe6929dc2937..507299bf0136 100644 --- a/drivers/net/wireless/ath9k/beacon.c +++ b/drivers/net/wireless/ath9k/beacon.c @@ -190,6 +190,13 @@ static struct ath_buf *ath_beacon_generate(struct ath_softc *sc, int if_id) pci_map_single(sc->pdev, skb->data, skb->len, PCI_DMA_TODEVICE); + if (unlikely(pci_dma_mapping_error(sc->pdev, bf->bf_buf_addr))) { + dev_kfree_skb_any(skb); + bf->bf_mpdu = NULL; + DPRINTF(sc, ATH_DBG_CONFIG, + "pci_dma_mapping_error() on beaconing\n"); + return NULL; + } skb = ieee80211_get_buffered_bc(sc->hw, vif); @@ -392,11 +399,18 @@ int ath_beacon_alloc(struct ath_softc *sc, int if_id) memcpy(&hdr[1], &val, sizeof(val)); } + bf->bf_mpdu = skb; bf->bf_buf_addr = bf->bf_dmacontext = pci_map_single(sc->pdev, skb->data, skb->len, PCI_DMA_TODEVICE); - bf->bf_mpdu = skb; + if (unlikely(pci_dma_mapping_error(sc->pdev, bf->bf_buf_addr))) { + dev_kfree_skb_any(skb); + bf->bf_mpdu = NULL; + DPRINTF(sc, ATH_DBG_CONFIG, + "pci_dma_mapping_error() on beacon alloc\n"); + return -ENOMEM; + } return 0; } diff --git a/drivers/net/wireless/ath9k/recv.c b/drivers/net/wireless/ath9k/recv.c index 51e058710d17..7a455468823b 100644 --- a/drivers/net/wireless/ath9k/recv.c +++ b/drivers/net/wireless/ath9k/recv.c @@ -304,6 +304,15 @@ int ath_rx_init(struct ath_softc *sc, int nbufs) bf->bf_buf_addr = pci_map_single(sc->pdev, skb->data, sc->sc_rxbufsize, PCI_DMA_FROMDEVICE); + if (unlikely(pci_dma_mapping_error(sc->pdev, + bf->bf_buf_addr))) { + dev_kfree_skb_any(skb); + bf->bf_mpdu = NULL; + DPRINTF(sc, ATH_DBG_CONFIG, + "pci_dma_mapping_error() on RX init\n"); + error = -ENOMEM; + break; + } bf->bf_dmacontext = bf->bf_buf_addr; } sc->sc_rxlink = NULL; @@ -589,6 +598,14 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush) bf->bf_buf_addr = pci_map_single(sc->pdev, requeue_skb->data, sc->sc_rxbufsize, PCI_DMA_FROMDEVICE); + if (unlikely(pci_dma_mapping_error(sc->pdev, + bf->bf_buf_addr))) { + dev_kfree_skb_any(requeue_skb); + bf->bf_mpdu = NULL; + DPRINTF(sc, ATH_DBG_CONFIG, + "pci_dma_mapping_error() on RX\n"); + break; + } bf->bf_dmacontext = bf->bf_buf_addr; /* diff --git a/drivers/net/wireless/ath9k/xmit.c b/drivers/net/wireless/ath9k/xmit.c index 5cf83111e1a7..17fd05e2f247 100644 --- a/drivers/net/wireless/ath9k/xmit.c +++ b/drivers/net/wireless/ath9k/xmit.c @@ -1642,7 +1642,7 @@ static void ath_txq_drain_pending_buffers(struct ath_softc *sc, } } -static void ath_tx_setup_buffer(struct ath_softc *sc, struct ath_buf *bf, +static int ath_tx_setup_buffer(struct ath_softc *sc, struct ath_buf *bf, struct sk_buff *skb, struct ath_tx_control *txctl) { @@ -1701,9 +1701,18 @@ static void ath_tx_setup_buffer(struct ath_softc *sc, struct ath_buf *bf, /* DMA setup */ bf->bf_mpdu = skb; + bf->bf_dmacontext = pci_map_single(sc->pdev, skb->data, skb->len, PCI_DMA_TODEVICE); + if (unlikely(pci_dma_mapping_error(sc->pdev, bf->bf_dmacontext))) { + bf->bf_mpdu = NULL; + DPRINTF(sc, ATH_DBG_CONFIG, + "pci_dma_mapping_error() on TX\n"); + return -ENOMEM; + } + bf->bf_buf_addr = bf->bf_dmacontext; + return 0; } /* FIXME: tx power */ @@ -1775,10 +1784,12 @@ static void ath_tx_start_dma(struct ath_softc *sc, struct ath_buf *bf, spin_unlock_bh(&txctl->txq->axq_lock); } +/* Upon failure caller should free skb */ int ath_tx_start(struct ath_softc *sc, struct sk_buff *skb, struct ath_tx_control *txctl) { struct ath_buf *bf; + int r; /* Check if a tx buffer is available */ @@ -1788,7 +1799,15 @@ int ath_tx_start(struct ath_softc *sc, struct sk_buff *skb, return -1; } - ath_tx_setup_buffer(sc, bf, skb, txctl); + r = ath_tx_setup_buffer(sc, bf, skb, txctl); + if (unlikely(r)) { + spin_lock_bh(&sc->sc_txbuflock); + DPRINTF(sc, ATH_DBG_FATAL, "TX mem alloc failure\n"); + list_add_tail(&bf->list, &sc->sc_txbuf); + spin_unlock_bh(&sc->sc_txbuflock); + return r; + } + ath_tx_start_dma(sc, bf, txctl); return 0; -- cgit v1.2.3 From 3706de6f58962ba74c18eb4cb1ebe034ff723037 Mon Sep 17 00:00:00 2001 From: Sujith Date: Sun, 7 Dec 2008 21:42:10 +0530 Subject: ath9k: Maintain rate table choice after association A scan run after association would change sc_curmode which is used to get the current rate table. This patch fixes it by removing sc_curmode and setting the rate table in usage in cur_rate_table on association. Signed-off-by: Sujith Signed-off-by: John W. Linville --- drivers/net/wireless/ath9k/beacon.c | 2 +- drivers/net/wireless/ath9k/core.h | 1 - drivers/net/wireless/ath9k/main.c | 3 ++- drivers/net/wireless/ath9k/rc.c | 9 ++++----- drivers/net/wireless/ath9k/recv.c | 2 +- drivers/net/wireless/ath9k/xmit.c | 8 ++++---- 6 files changed, 12 insertions(+), 13 deletions(-) (limited to 'drivers/net/wireless/ath9k/recv.c') diff --git a/drivers/net/wireless/ath9k/beacon.c b/drivers/net/wireless/ath9k/beacon.c index d8742230e624..9e5c0c0446b6 100644 --- a/drivers/net/wireless/ath9k/beacon.c +++ b/drivers/net/wireless/ath9k/beacon.c @@ -106,7 +106,7 @@ static void ath_beacon_setup(struct ath_softc *sc, * XXX everything at min xmit rate */ rix = 0; - rt = sc->hw_rate_table[sc->sc_curmode]; + rt = sc->cur_rate_table; rate = rt->info[rix].ratecode; if (sc->sc_flags & SC_OP_PREAMBLE_SHORT) rate |= rt->info[rix].short_preamble; diff --git a/drivers/net/wireless/ath9k/core.h b/drivers/net/wireless/ath9k/core.h index 726d0a38d240..23844e02eff1 100644 --- a/drivers/net/wireless/ath9k/core.h +++ b/drivers/net/wireless/ath9k/core.h @@ -646,7 +646,6 @@ struct ath_softc { u8 sc_tx_chainmask; u8 sc_rx_chainmask; enum ath9k_int sc_imask; - enum wireless_mode sc_curmode; enum PROT_MODE sc_protmode; u8 sc_nbcnvaps; diff --git a/drivers/net/wireless/ath9k/main.c b/drivers/net/wireless/ath9k/main.c index 26c47577e183..ade92d518d52 100644 --- a/drivers/net/wireless/ath9k/main.c +++ b/drivers/net/wireless/ath9k/main.c @@ -60,7 +60,8 @@ static void bus_read_cachesize(struct ath_softc *sc, int *csz) static void ath_setcurmode(struct ath_softc *sc, enum wireless_mode mode) { - sc->sc_curmode = mode; + if (!sc->sc_curaid) + sc->cur_rate_table = sc->hw_rate_table[mode]; /* * All protection frames are transmited at 2Mb/s for * 11g, otherwise at 1Mb/s. diff --git a/drivers/net/wireless/ath9k/rc.c b/drivers/net/wireless/ath9k/rc.c index 8eec66756c75..0ae5988e0b65 100644 --- a/drivers/net/wireless/ath9k/rc.c +++ b/drivers/net/wireless/ath9k/rc.c @@ -874,9 +874,8 @@ static void ath_rc_ratefind(struct ath_softc *sc, * So, set fourth rate in series to be same as third one for * above conditions. */ - if ((sc->sc_curmode == ATH9K_MODE_11NG_HT20) || - (sc->sc_curmode == ATH9K_MODE_11NG_HT40PLUS) || - (sc->sc_curmode == ATH9K_MODE_11NG_HT40MINUS)) { + if ((sc->hw->conf.channel->band == IEEE80211_BAND_2GHZ) && + (sc->hw->conf.ht.enabled)) { u8 dot11rate = rate_table->info[rix].dot11rate; u8 phy = rate_table->info[rix].phy; if (i == 4 && @@ -1354,8 +1353,8 @@ static void ath_rc_init(struct ath_softc *sc, sta->ht_cap.ht_supported, is_cw_40); } else if (sc->sc_ah->ah_opmode == NL80211_IFTYPE_AP) { - /* sc_curmode would be set on init through config() */ - rate_table = sc->hw_rate_table[sc->sc_curmode]; + /* cur_rate_table would be set on init through config() */ + rate_table = sc->cur_rate_table; } if (!rate_table) { diff --git a/drivers/net/wireless/ath9k/recv.c b/drivers/net/wireless/ath9k/recv.c index 7a455468823b..b182ef570f88 100644 --- a/drivers/net/wireless/ath9k/recv.c +++ b/drivers/net/wireless/ath9k/recv.c @@ -148,7 +148,7 @@ static int ath_rx_prepare(struct sk_buff *skb, struct ath_desc *ds, struct ieee80211_rx_status *rx_status, bool *decrypt_error, struct ath_softc *sc) { - struct ath_rate_table *rate_table = sc->hw_rate_table[sc->sc_curmode]; + struct ath_rate_table *rate_table = sc->cur_rate_table; struct ieee80211_hdr *hdr; int ratekbps, rix; u8 ratecode; diff --git a/drivers/net/wireless/ath9k/xmit.c b/drivers/net/wireless/ath9k/xmit.c index 9de27c681b86..353b7ed1c8a4 100644 --- a/drivers/net/wireless/ath9k/xmit.c +++ b/drivers/net/wireless/ath9k/xmit.c @@ -493,7 +493,7 @@ static void ath_tx_update_baw(struct ath_softc *sc, struct ath_atx_tid *tid, static u32 ath_pkt_duration(struct ath_softc *sc, u8 rix, struct ath_buf *bf, int width, int half_gi, bool shortPreamble) { - struct ath_rate_table *rate_table = sc->hw_rate_table[sc->sc_curmode]; + struct ath_rate_table *rate_table = sc->cur_rate_table; u32 nbits, nsymbits, duration, nsymbols; u8 rc; int streams, pktlen; @@ -557,7 +557,7 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf) } /* get the cix for the lowest valid rix */ - rt = sc->hw_rate_table[sc->sc_curmode]; + rt = sc->cur_rate_table; for (i = 3; i >= 0; i--) { if (rates[i].count && (rates[i].idx >= 0)) { rix = rates[i].idx; @@ -1240,7 +1240,7 @@ static u32 ath_lookup_rate(struct ath_softc *sc, struct ath_buf *bf, struct ath_atx_tid *tid) { - struct ath_rate_table *rate_table = sc->hw_rate_table[sc->sc_curmode]; + struct ath_rate_table *rate_table = sc->cur_rate_table; struct sk_buff *skb; struct ieee80211_tx_info *tx_info; struct ieee80211_tx_rate *rates; @@ -1308,7 +1308,7 @@ static int ath_compute_num_delims(struct ath_softc *sc, struct ath_buf *bf, u16 frmlen) { - struct ath_rate_table *rt = sc->hw_rate_table[sc->sc_curmode]; + struct ath_rate_table *rt = sc->cur_rate_table; struct sk_buff *skb = bf->bf_mpdu; struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); u32 nsymbits, nsymbols, mpdudensity; -- cgit v1.2.3 From b77f483fcf0579de28873828897f53371a33a0ea Mon Sep 17 00:00:00 2001 From: Sujith Date: Sun, 7 Dec 2008 21:44:03 +0530 Subject: ath9k: Refactor struct ath_softc Split ath_softc into smaller structures for rx, tx and beacon handling. Signed-off-by: Sujith Signed-off-by: John W. Linville --- drivers/net/wireless/ath9k/beacon.c | 94 ++++++++++++------------- drivers/net/wireless/ath9k/core.h | 134 ++++++++++++++++-------------------- drivers/net/wireless/ath9k/main.c | 60 ++++++++-------- drivers/net/wireless/ath9k/recv.c | 107 ++++++++++++++-------------- drivers/net/wireless/ath9k/xmit.c | 126 ++++++++++++++++----------------- 5 files changed, 254 insertions(+), 267 deletions(-) (limited to 'drivers/net/wireless/ath9k/recv.c') diff --git a/drivers/net/wireless/ath9k/beacon.c b/drivers/net/wireless/ath9k/beacon.c index 9e5c0c0446b6..3ab0b43aaf93 100644 --- a/drivers/net/wireless/ath9k/beacon.c +++ b/drivers/net/wireless/ath9k/beacon.c @@ -26,7 +26,7 @@ static int ath_beaconq_config(struct ath_softc *sc) struct ath_hal *ah = sc->sc_ah; struct ath9k_tx_queue_info qi; - ath9k_hw_get_txq_props(ah, sc->sc_bhalq, &qi); + ath9k_hw_get_txq_props(ah, sc->beacon.beaconq, &qi); if (sc->sc_ah->ah_opmode == NL80211_IFTYPE_AP) { /* Always burst out beacon and CAB traffic. */ qi.tqi_aifs = 1; @@ -34,17 +34,17 @@ static int ath_beaconq_config(struct ath_softc *sc) qi.tqi_cwmax = 0; } else { /* Adhoc mode; important thing is to use 2x cwmin. */ - qi.tqi_aifs = sc->sc_beacon_qi.tqi_aifs; - qi.tqi_cwmin = 2*sc->sc_beacon_qi.tqi_cwmin; - qi.tqi_cwmax = sc->sc_beacon_qi.tqi_cwmax; + qi.tqi_aifs = sc->beacon.beacon_qi.tqi_aifs; + qi.tqi_cwmin = 2*sc->beacon.beacon_qi.tqi_cwmin; + qi.tqi_cwmax = sc->beacon.beacon_qi.tqi_cwmax; } - if (!ath9k_hw_set_txq_props(ah, sc->sc_bhalq, &qi)) { + if (!ath9k_hw_set_txq_props(ah, sc->beacon.beaconq, &qi)) { DPRINTF(sc, ATH_DBG_FATAL, "unable to update h/w beacon queue parameters\n"); return 0; } else { - ath9k_hw_resettxqueue(ah, sc->sc_bhalq); /* push to h/w */ + ath9k_hw_resettxqueue(ah, sc->beacon.beaconq); /* push to h/w */ return 1; } } @@ -53,7 +53,7 @@ static void ath_bstuck_process(struct ath_softc *sc) { DPRINTF(sc, ATH_DBG_BEACON, "stuck beacon; resetting (bmiss count %u)\n", - sc->sc_bmisscount); + sc->beacon.bmisscnt); ath_reset(sc, false); } @@ -96,7 +96,7 @@ static void ath_beacon_setup(struct ath_softc *sc, * SWBA's * XXX assumes two antenna */ - antenna = ((sc->ast_be_xmit / sc->sc_nbcnvaps) & 1 ? 2 : 1); + antenna = ((sc->beacon.ast_be_xmit / sc->sc_nbcnvaps) & 1 ? 2 : 1); } ds->ds_data = bf->bf_buf_addr; @@ -153,7 +153,7 @@ static struct ath_buf *ath_beacon_generate(struct ath_softc *sc, int if_id) ASSERT(vif); avp = (void *)vif->drv_priv; - cabq = sc->sc_cabq; + cabq = sc->beacon.cabq; if (avp->av_bcbuf == NULL) { DPRINTF(sc, ATH_DBG_BEACON, "avp=%p av_bcbuf=%p\n", @@ -182,9 +182,9 @@ static struct ath_buf *ath_beacon_generate(struct ath_softc *sc, int if_id) * TX frames) */ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; - sc->seq_no += 0x10; + sc->tx.seq_no += 0x10; hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG); - hdr->seq_ctrl |= cpu_to_le16(sc->seq_no); + hdr->seq_ctrl |= cpu_to_le16(sc->tx.seq_no); } bf->bf_buf_addr = bf->bf_dmacontext = @@ -270,10 +270,10 @@ static void ath_beacon_start_adhoc(struct ath_softc *sc, int if_id) ath_beacon_setup(sc, avp, bf); /* NB: caller is known to have already stopped tx dma */ - ath9k_hw_puttxbuf(ah, sc->sc_bhalq, bf->bf_daddr); - ath9k_hw_txstart(ah, sc->sc_bhalq); + ath9k_hw_puttxbuf(ah, sc->beacon.beaconq, bf->bf_daddr); + ath9k_hw_txstart(ah, sc->beacon.beaconq); DPRINTF(sc, ATH_DBG_BEACON, "TXDP%u = %llx (%p)\n", - sc->sc_bhalq, ito64(bf->bf_daddr), bf->bf_desc); + sc->beacon.beaconq, ito64(bf->bf_daddr), bf->bf_desc); } int ath_beaconq_setup(struct ath_hal *ah) @@ -306,7 +306,7 @@ int ath_beacon_alloc(struct ath_softc *sc, int if_id) if (!avp->av_bcbuf) { /* Allocate beacon state for hostap/ibss. We know * a buffer is available. */ - avp->av_bcbuf = list_first_entry(&sc->sc_bbuf, + avp->av_bcbuf = list_first_entry(&sc->beacon.bbuf, struct ath_buf, list); list_del(&avp->av_bcbuf->list); @@ -319,13 +319,13 @@ int ath_beacon_alloc(struct ath_softc *sc, int if_id) */ avp->av_bslot = 0; for (slot = 0; slot < ATH_BCBUF; slot++) - if (sc->sc_bslot[slot] == ATH_IF_ID_ANY) { + if (sc->beacon.bslot[slot] == ATH_IF_ID_ANY) { /* * XXX hack, space out slots to better * deal with misses */ if (slot+1 < ATH_BCBUF && - sc->sc_bslot[slot+1] == + sc->beacon.bslot[slot+1] == ATH_IF_ID_ANY) { avp->av_bslot = slot+1; break; @@ -333,8 +333,8 @@ int ath_beacon_alloc(struct ath_softc *sc, int if_id) avp->av_bslot = slot; /* NB: keep looking for a double slot */ } - BUG_ON(sc->sc_bslot[avp->av_bslot] != ATH_IF_ID_ANY); - sc->sc_bslot[avp->av_bslot] = if_id; + BUG_ON(sc->beacon.bslot[avp->av_bslot] != ATH_IF_ID_ANY); + sc->beacon.bslot[avp->av_bslot] = if_id; sc->sc_nbcnvaps++; } } @@ -362,7 +362,7 @@ int ath_beacon_alloc(struct ath_softc *sc, int if_id) } tstamp = ((struct ieee80211_mgmt *)skb->data)->u.beacon.timestamp; - sc->bc_tstamp = le64_to_cpu(tstamp); + sc->beacon.bc_tstamp = le64_to_cpu(tstamp); /* * Calculate a TSF adjustment factor required for @@ -422,7 +422,7 @@ void ath_beacon_return(struct ath_softc *sc, struct ath_vap *avp) struct ath_buf *bf; if (avp->av_bslot != -1) { - sc->sc_bslot[avp->av_bslot] = ATH_IF_ID_ANY; + sc->beacon.bslot[avp->av_bslot] = ATH_IF_ID_ANY; sc->sc_nbcnvaps--; } @@ -435,7 +435,7 @@ void ath_beacon_return(struct ath_softc *sc, struct ath_vap *avp) dev_kfree_skb_any(skb); bf->bf_mpdu = NULL; } - list_add_tail(&bf->list, &sc->sc_bbuf); + list_add_tail(&bf->list, &sc->beacon.bbuf); avp->av_bcbuf = NULL; } @@ -469,18 +469,18 @@ void ath9k_beacon_tasklet(unsigned long data) * * FIXME: Clean up this mess !! */ - if (ath9k_hw_numtxpending(ah, sc->sc_bhalq) != 0) { - sc->sc_bmisscount++; + if (ath9k_hw_numtxpending(ah, sc->beacon.beaconq) != 0) { + sc->beacon.bmisscnt++; /* XXX: doth needs the chanchange IE countdown decremented. * We should consider adding a mac80211 call to indicate * a beacon miss so appropriate action could be taken * (in that layer). */ - if (sc->sc_bmisscount < BSTUCK_THRESH) { + if (sc->beacon.bmisscnt < BSTUCK_THRESH) { if (sc->sc_flags & SC_OP_NO_RESET) { DPRINTF(sc, ATH_DBG_BEACON, "missed %u consecutive beacons\n", - sc->sc_bmisscount); + sc->beacon.bmisscnt); if (show_cycles) { /* * Display cycle counter stats from HW @@ -499,11 +499,11 @@ void ath9k_beacon_tasklet(unsigned long data) } else { DPRINTF(sc, ATH_DBG_BEACON, "missed %u consecutive beacons\n", - sc->sc_bmisscount); + sc->beacon.bmisscnt); } - } else if (sc->sc_bmisscount >= BSTUCK_THRESH) { + } else if (sc->beacon.bmisscnt >= BSTUCK_THRESH) { if (sc->sc_flags & SC_OP_NO_RESET) { - if (sc->sc_bmisscount == BSTUCK_THRESH) { + if (sc->beacon.bmisscnt == BSTUCK_THRESH) { DPRINTF(sc, ATH_DBG_BEACON, "beacon is officially " "stuck\n"); @@ -517,17 +517,17 @@ void ath9k_beacon_tasklet(unsigned long data) return; } - if (sc->sc_bmisscount != 0) { + if (sc->beacon.bmisscnt != 0) { if (sc->sc_flags & SC_OP_NO_RESET) { DPRINTF(sc, ATH_DBG_BEACON, "resume beacon xmit after %u misses\n", - sc->sc_bmisscount); + sc->beacon.bmisscnt); } else { DPRINTF(sc, ATH_DBG_BEACON, "resume beacon xmit after %u misses\n", - sc->sc_bmisscount); + sc->beacon.bmisscnt); } - sc->sc_bmisscount = 0; + sc->beacon.bmisscnt = 0; } /* @@ -542,7 +542,7 @@ void ath9k_beacon_tasklet(unsigned long data) tsf = ath9k_hw_gettsf64(ah); tsftu = TSF_TO_TU(tsf>>32, tsf); slot = ((tsftu % intval) * ATH_BCBUF) / intval; - if_id = sc->sc_bslot[(slot + 1) % ATH_BCBUF]; + if_id = sc->beacon.bslot[(slot + 1) % ATH_BCBUF]; DPRINTF(sc, ATH_DBG_BEACON, "slot %d [tsf %llu tsftu %u intval %u] if_id %d\n", @@ -574,12 +574,12 @@ void ath9k_beacon_tasklet(unsigned long data) * set to ATH_BCBUF so this check is a noop. */ /* XXX locking */ - if (sc->sc_updateslot == UPDATE) { - sc->sc_updateslot = COMMIT; /* commit next beacon */ - sc->sc_slotupdate = slot; - } else if (sc->sc_updateslot == COMMIT && sc->sc_slotupdate == slot) { - ath9k_hw_setslottime(sc->sc_ah, sc->sc_slottime); - sc->sc_updateslot = OK; + if (sc->beacon.updateslot == UPDATE) { + sc->beacon.updateslot = COMMIT; /* commit next beacon */ + sc->beacon.slotupdate = slot; + } else if (sc->beacon.updateslot == COMMIT && sc->beacon.slotupdate == slot) { + ath9k_hw_setslottime(sc->sc_ah, sc->beacon.slottime); + sc->beacon.updateslot = OK; } if (bfaddr != 0) { /* @@ -587,17 +587,17 @@ void ath9k_beacon_tasklet(unsigned long data) * This should never fail since we check above that no frames * are still pending on the queue. */ - if (!ath9k_hw_stoptxdma(ah, sc->sc_bhalq)) { + if (!ath9k_hw_stoptxdma(ah, sc->beacon.beaconq)) { DPRINTF(sc, ATH_DBG_FATAL, - "beacon queue %u did not stop?\n", sc->sc_bhalq); + "beacon queue %u did not stop?\n", sc->beacon.beaconq); /* NB: the HAL still stops DMA, so proceed */ } /* NB: cabq traffic should already be queued and primed */ - ath9k_hw_puttxbuf(ah, sc->sc_bhalq, bfaddr); - ath9k_hw_txstart(ah, sc->sc_bhalq); + ath9k_hw_puttxbuf(ah, sc->beacon.beaconq, bfaddr); + ath9k_hw_txstart(ah, sc->beacon.beaconq); - sc->ast_be_xmit += bc; /* XXX per-vap? */ + sc->beacon.ast_be_xmit += bc; /* XXX per-vap? */ } } @@ -644,7 +644,7 @@ void ath_beacon_config(struct ath_softc *sc, int if_id) conf.bmiss_timeout = ATH_DEFAULT_BMISS_LIMIT * conf.beacon_interval; /* extract tstamp from last beacon and convert to TU */ - nexttbtt = TSF_TO_TU(sc->bc_tstamp >> 32, sc->bc_tstamp); + nexttbtt = TSF_TO_TU(sc->beacon.bc_tstamp >> 32, sc->beacon.bc_tstamp); /* XXX conditionalize multi-bss support? */ if (sc->sc_ah->ah_opmode == NL80211_IFTYPE_AP) { @@ -831,7 +831,7 @@ void ath_beacon_config(struct ath_softc *sc, int if_id) ath_beaconq_config(sc); } ath9k_hw_beaconinit(ah, nexttbtt, intval); - sc->sc_bmisscount = 0; + sc->beacon.bmisscnt = 0; ath9k_hw_set_interrupts(ah, sc->sc_imask); /* * When using a self-linked beacon descriptor in diff --git a/drivers/net/wireless/ath9k/core.h b/drivers/net/wireless/ath9k/core.h index 41a87b99deaa..e38f0331cfd5 100644 --- a/drivers/net/wireless/ath9k/core.h +++ b/drivers/net/wireless/ath9k/core.h @@ -61,7 +61,7 @@ struct ath_node; #define TSF_TO_TU(_h,_l) \ ((((u32)(_h)) << 22) | (((u32)(_l)) >> 10)) -#define ATH_TXQ_SETUP(sc, i) ((sc)->sc_txqsetup & (1<tx.txqsetup & (1<rx_filter & FIF_BCN_PRBRESP_PROMISC) + if (sc->rx.rxfilter & FIF_BCN_PRBRESP_PROMISC) return; /* Long calibration runs independently of short calibration. */ @@ -487,9 +487,9 @@ static void ath9k_tasklet(unsigned long data) if (status & (ATH9K_INT_RX | ATH9K_INT_RXEOL | ATH9K_INT_RXORN)) { - spin_lock_bh(&sc->sc_rxflushlock); + spin_lock_bh(&sc->rx.rxflushlock); ath_rx_tasklet(sc, 0); - spin_unlock_bh(&sc->sc_rxflushlock); + spin_unlock_bh(&sc->rx.rxflushlock); } /* XXX: optimize this */ if (status & ATH9K_INT_TX) @@ -1306,7 +1306,7 @@ static void ath_detach(struct ath_softc *sc) /* cleanup tx queues */ for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) if (ATH_TXQ_SETUP(sc, i)) - ath_tx_cleanupq(sc, &sc->sc_txq[i]); + ath_tx_cleanupq(sc, &sc->tx.txq[i]); ath9k_hw_detach(sc->sc_ah); ath9k_exit_debug(sc); @@ -1397,15 +1397,15 @@ static int ath_init(u16 devid, struct ath_softc *sc) * priority. Note that the hal handles reseting * these queues at the needed time. */ - sc->sc_bhalq = ath_beaconq_setup(ah); - if (sc->sc_bhalq == -1) { + sc->beacon.beaconq = ath_beaconq_setup(ah); + if (sc->beacon.beaconq == -1) { DPRINTF(sc, ATH_DBG_FATAL, "Unable to setup a beacon xmit queue\n"); error = -EIO; goto bad2; } - sc->sc_cabq = ath_txq_setup(sc, ATH9K_TX_QUEUE_CAB, 0); - if (sc->sc_cabq == NULL) { + sc->beacon.cabq = ath_txq_setup(sc, ATH9K_TX_QUEUE_CAB, 0); + if (sc->beacon.cabq == NULL) { DPRINTF(sc, ATH_DBG_FATAL, "Unable to setup CAB xmit queue\n"); error = -EIO; @@ -1415,8 +1415,8 @@ static int ath_init(u16 devid, struct ath_softc *sc) sc->sc_config.cabqReadytime = ATH_CABQ_READY_TIME; ath_cabq_update(sc); - for (i = 0; i < ARRAY_SIZE(sc->sc_haltype2q); i++) - sc->sc_haltype2q[i] = -1; + for (i = 0; i < ARRAY_SIZE(sc->tx.hwq_map); i++) + sc->tx.hwq_map[i] = -1; /* Setup data queues */ /* NB: ensure BK queue is the lowest priority h/w queue */ @@ -1496,7 +1496,7 @@ static int ath_init(u16 devid, struct ath_softc *sc) sc->sc_rx_chainmask = ah->ah_caps.rx_chainmask; ath9k_hw_setcapability(ah, ATH9K_CAP_DIVERSITY, 1, true, NULL); - sc->sc_defant = ath9k_hw_getdefantenna(ah); + sc->rx.defant = ath9k_hw_getdefantenna(ah); ath9k_hw_getmac(ah, sc->sc_myaddr); if (ah->ah_caps.hw_caps & ATH9K_HW_CAP_BSSIDMASK) { @@ -1505,11 +1505,11 @@ static int ath_init(u16 devid, struct ath_softc *sc) ath9k_hw_setbssidmask(ah, sc->sc_bssidmask); } - sc->sc_slottime = ATH9K_SLOT_TIME_9; /* default to short slot time */ + sc->beacon.slottime = ATH9K_SLOT_TIME_9; /* default to short slot time */ /* initialize beacon slots */ - for (i = 0; i < ARRAY_SIZE(sc->sc_bslot); i++) - sc->sc_bslot[i] = ATH_IF_ID_ANY; + for (i = 0; i < ARRAY_SIZE(sc->beacon.bslot); i++) + sc->beacon.bslot[i] = ATH_IF_ID_ANY; /* save MISC configurations */ sc->sc_config.swBeaconProcess = 1; @@ -1535,7 +1535,7 @@ bad2: /* cleanup tx queues */ for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) if (ATH_TXQ_SETUP(sc, i)) - ath_tx_cleanupq(sc, &sc->sc_txq[i]); + ath_tx_cleanupq(sc, &sc->tx.txq[i]); bad: if (ah) ath9k_hw_detach(ah); @@ -1673,9 +1673,9 @@ int ath_reset(struct ath_softc *sc, bool retry_tx) int i; for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) { if (ATH_TXQ_SETUP(sc, i)) { - spin_lock_bh(&sc->sc_txq[i].axq_lock); - ath_txq_schedule(sc, &sc->sc_txq[i]); - spin_unlock_bh(&sc->sc_txq[i].axq_lock); + spin_lock_bh(&sc->tx.txq[i].axq_lock); + ath_txq_schedule(sc, &sc->tx.txq[i]); + spin_unlock_bh(&sc->tx.txq[i].axq_lock); } } } @@ -1810,19 +1810,19 @@ int ath_get_hal_qnum(u16 queue, struct ath_softc *sc) switch (queue) { case 0: - qnum = sc->sc_haltype2q[ATH9K_WME_AC_VO]; + qnum = sc->tx.hwq_map[ATH9K_WME_AC_VO]; break; case 1: - qnum = sc->sc_haltype2q[ATH9K_WME_AC_VI]; + qnum = sc->tx.hwq_map[ATH9K_WME_AC_VI]; break; case 2: - qnum = sc->sc_haltype2q[ATH9K_WME_AC_BE]; + qnum = sc->tx.hwq_map[ATH9K_WME_AC_BE]; break; case 3: - qnum = sc->sc_haltype2q[ATH9K_WME_AC_BK]; + qnum = sc->tx.hwq_map[ATH9K_WME_AC_BK]; break; default: - qnum = sc->sc_haltype2q[ATH9K_WME_AC_BE]; + qnum = sc->tx.hwq_map[ATH9K_WME_AC_BE]; break; } @@ -1993,9 +1993,9 @@ static int ath9k_tx(struct ieee80211_hw *hw, if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) { struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; if (info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT) - sc->seq_no += 0x10; + sc->tx.seq_no += 0x10; hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG); - hdr->seq_ctrl |= cpu_to_le16(sc->seq_no); + hdr->seq_ctrl |= cpu_to_le16(sc->tx.seq_no); } /* Add the padding after the header if this is not already done */ @@ -2049,7 +2049,7 @@ static void ath9k_stop(struct ieee80211_hw *hw) ath_stoprecv(sc); ath9k_hw_phy_disable(sc->sc_ah); } else - sc->sc_rxlink = NULL; + sc->rx.rxlink = NULL; #if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE) if (sc->sc_ah->ah_caps.hw_caps & ATH9K_HW_CAP_RFSILENT) @@ -2131,7 +2131,7 @@ static void ath9k_remove_interface(struct ieee80211_hw *hw, /* Reclaim beacon resources */ if (sc->sc_ah->ah_opmode == NL80211_IFTYPE_AP || sc->sc_ah->ah_opmode == NL80211_IFTYPE_ADHOC) { - ath9k_hw_stoptxdma(sc->sc_ah, sc->sc_bhalq); + ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq); ath_beacon_return(sc, avp); } @@ -2250,7 +2250,7 @@ static int ath9k_config_interface(struct ieee80211_hw *hw, * causes reconfiguration; we may be called * with beacon transmission active. */ - ath9k_hw_stoptxdma(sc->sc_ah, sc->sc_bhalq); + ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq); error = ath_beacon_alloc(sc, 0); if (error != 0) @@ -2296,7 +2296,7 @@ static void ath9k_configure_filter(struct ieee80211_hw *hw, changed_flags &= SUPPORTED_FILTERS; *total_flags &= SUPPORTED_FILTERS; - sc->rx_filter = *total_flags; + sc->rx.rxfilter = *total_flags; rfilt = ath_calcrxfilter(sc); ath9k_hw_setrxfilter(sc->sc_ah, rfilt); @@ -2305,7 +2305,7 @@ static void ath9k_configure_filter(struct ieee80211_hw *hw, ath9k_hw_write_associd(sc->sc_ah, ath_bcast_mac, 0); } - DPRINTF(sc, ATH_DBG_CONFIG, "Set HW RX filter: 0x%x\n", sc->rx_filter); + DPRINTF(sc, ATH_DBG_CONFIG, "Set HW RX filter: 0x%x\n", sc->rx.rxfilter); } static void ath9k_sta_notify(struct ieee80211_hw *hw, diff --git a/drivers/net/wireless/ath9k/recv.c b/drivers/net/wireless/ath9k/recv.c index b182ef570f88..cb449f0b4171 100644 --- a/drivers/net/wireless/ath9k/recv.c +++ b/drivers/net/wireless/ath9k/recv.c @@ -41,20 +41,19 @@ static void ath_rx_buf_link(struct ath_softc *sc, struct ath_buf *bf) ASSERT(skb != NULL); ds->ds_vdata = skb->data; - /* setup rx descriptors. The sc_rxbufsize here tells the harware + /* setup rx descriptors. The rx.bufsize here tells the harware * how much data it can DMA to us and that we are prepared * to process */ - ath9k_hw_setuprxdesc(ah, - ds, - sc->sc_rxbufsize, + ath9k_hw_setuprxdesc(ah, ds, + sc->rx.bufsize, 0); - if (sc->sc_rxlink == NULL) + if (sc->rx.rxlink == NULL) ath9k_hw_putrxbuf(ah, bf->bf_daddr); else - *sc->sc_rxlink = bf->bf_daddr; + *sc->rx.rxlink = bf->bf_daddr; - sc->sc_rxlink = &ds->ds_link; + sc->rx.rxlink = &ds->ds_link; ath9k_hw_rxena(ah); } @@ -62,8 +61,8 @@ static void ath_setdefantenna(struct ath_softc *sc, u32 antenna) { /* XXX block beacon interrupts */ ath9k_hw_setantenna(sc->sc_ah, antenna); - sc->sc_defant = antenna; - sc->sc_rxotherant = 0; + sc->rx.defant = antenna; + sc->rx.rxotherant = 0; } /* @@ -272,20 +271,20 @@ int ath_rx_init(struct ath_softc *sc, int nbufs) int error = 0; do { - spin_lock_init(&sc->sc_rxflushlock); + spin_lock_init(&sc->rx.rxflushlock); sc->sc_flags &= ~SC_OP_RXFLUSH; - spin_lock_init(&sc->sc_rxbuflock); + spin_lock_init(&sc->rx.rxbuflock); - sc->sc_rxbufsize = roundup(IEEE80211_MAX_MPDU_LEN, + sc->rx.bufsize = roundup(IEEE80211_MAX_MPDU_LEN, min(sc->sc_cachelsz, (u16)64)); DPRINTF(sc, ATH_DBG_CONFIG, "cachelsz %u rxbufsize %u\n", - sc->sc_cachelsz, sc->sc_rxbufsize); + sc->sc_cachelsz, sc->rx.bufsize); /* Initialize rx descriptors */ - error = ath_descdma_setup(sc, &sc->sc_rxdma, &sc->sc_rxbuf, + error = ath_descdma_setup(sc, &sc->rx.rxdma, &sc->rx.rxbuf, "rx", nbufs, 1); if (error != 0) { DPRINTF(sc, ATH_DBG_FATAL, @@ -293,8 +292,8 @@ int ath_rx_init(struct ath_softc *sc, int nbufs) break; } - list_for_each_entry(bf, &sc->sc_rxbuf, list) { - skb = ath_rxbuf_alloc(sc, sc->sc_rxbufsize); + list_for_each_entry(bf, &sc->rx.rxbuf, list) { + skb = ath_rxbuf_alloc(sc, sc->rx.bufsize); if (skb == NULL) { error = -ENOMEM; break; @@ -302,8 +301,8 @@ int ath_rx_init(struct ath_softc *sc, int nbufs) bf->bf_mpdu = skb; bf->bf_buf_addr = pci_map_single(sc->pdev, skb->data, - sc->sc_rxbufsize, - PCI_DMA_FROMDEVICE); + sc->rx.bufsize, + PCI_DMA_FROMDEVICE); if (unlikely(pci_dma_mapping_error(sc->pdev, bf->bf_buf_addr))) { dev_kfree_skb_any(skb); @@ -315,7 +314,7 @@ int ath_rx_init(struct ath_softc *sc, int nbufs) } bf->bf_dmacontext = bf->bf_buf_addr; } - sc->sc_rxlink = NULL; + sc->rx.rxlink = NULL; } while (0); @@ -330,14 +329,14 @@ void ath_rx_cleanup(struct ath_softc *sc) struct sk_buff *skb; struct ath_buf *bf; - list_for_each_entry(bf, &sc->sc_rxbuf, list) { + list_for_each_entry(bf, &sc->rx.rxbuf, list) { skb = bf->bf_mpdu; if (skb) dev_kfree_skb(skb); } - if (sc->sc_rxdma.dd_desc_len != 0) - ath_descdma_cleanup(sc, &sc->sc_rxdma, &sc->sc_rxbuf); + if (sc->rx.rxdma.dd_desc_len != 0) + ath_descdma_cleanup(sc, &sc->rx.rxdma, &sc->rx.rxbuf); } /* @@ -375,7 +374,7 @@ u32 ath_calcrxfilter(struct ath_softc *sc) /* Can't set HOSTAP into promiscous mode */ if (((sc->sc_ah->ah_opmode != NL80211_IFTYPE_AP) && - (sc->rx_filter & FIF_PROMISC_IN_BSS)) || + (sc->rx.rxfilter & FIF_PROMISC_IN_BSS)) || (sc->sc_ah->ah_opmode == NL80211_IFTYPE_MONITOR)) { rfilt |= ATH9K_RX_FILTER_PROM; /* ??? To prevent from sending ACK */ @@ -401,25 +400,25 @@ int ath_startrecv(struct ath_softc *sc) struct ath_hal *ah = sc->sc_ah; struct ath_buf *bf, *tbf; - spin_lock_bh(&sc->sc_rxbuflock); - if (list_empty(&sc->sc_rxbuf)) + spin_lock_bh(&sc->rx.rxbuflock); + if (list_empty(&sc->rx.rxbuf)) goto start_recv; - sc->sc_rxlink = NULL; - list_for_each_entry_safe(bf, tbf, &sc->sc_rxbuf, list) { + sc->rx.rxlink = NULL; + list_for_each_entry_safe(bf, tbf, &sc->rx.rxbuf, list) { ath_rx_buf_link(sc, bf); } /* We could have deleted elements so the list may be empty now */ - if (list_empty(&sc->sc_rxbuf)) + if (list_empty(&sc->rx.rxbuf)) goto start_recv; - bf = list_first_entry(&sc->sc_rxbuf, struct ath_buf, list); + bf = list_first_entry(&sc->rx.rxbuf, struct ath_buf, list); ath9k_hw_putrxbuf(ah, bf->bf_daddr); ath9k_hw_rxena(ah); start_recv: - spin_unlock_bh(&sc->sc_rxbuflock); + spin_unlock_bh(&sc->rx.rxbuflock); ath_opmode_init(sc); ath9k_hw_startpcureceive(ah); @@ -435,25 +434,25 @@ bool ath_stoprecv(struct ath_softc *sc) ath9k_hw_setrxfilter(ah, 0); stopped = ath9k_hw_stopdmarecv(ah); mdelay(3); /* 3ms is long enough for 1 frame */ - sc->sc_rxlink = NULL; + sc->rx.rxlink = NULL; return stopped; } void ath_flushrecv(struct ath_softc *sc) { - spin_lock_bh(&sc->sc_rxflushlock); + spin_lock_bh(&sc->rx.rxflushlock); sc->sc_flags |= SC_OP_RXFLUSH; ath_rx_tasklet(sc, 1); sc->sc_flags &= ~SC_OP_RXFLUSH; - spin_unlock_bh(&sc->sc_rxflushlock); + spin_unlock_bh(&sc->rx.rxflushlock); } int ath_rx_tasklet(struct ath_softc *sc, int flush) { #define PA2DESC(_sc, _pa) \ - ((struct ath_desc *)((caddr_t)(_sc)->sc_rxdma.dd_desc + \ - ((_pa) - (_sc)->sc_rxdma.dd_desc_paddr))) + ((struct ath_desc *)((caddr_t)(_sc)->rx.rxdma.dd_desc + \ + ((_pa) - (_sc)->rx.rxdma.dd_desc_paddr))) struct ath_buf *bf; struct ath_desc *ds; @@ -465,19 +464,19 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush) bool decrypt_error = false; u8 keyix; - spin_lock_bh(&sc->sc_rxbuflock); + spin_lock_bh(&sc->rx.rxbuflock); do { /* If handling rx interrupt and flush is in progress => exit */ if ((sc->sc_flags & SC_OP_RXFLUSH) && (flush == 0)) break; - if (list_empty(&sc->sc_rxbuf)) { - sc->sc_rxlink = NULL; + if (list_empty(&sc->rx.rxbuf)) { + sc->rx.rxlink = NULL; break; } - bf = list_first_entry(&sc->sc_rxbuf, struct ath_buf, list); + bf = list_first_entry(&sc->rx.rxbuf, struct ath_buf, list); ds = bf->bf_desc; /* @@ -499,8 +498,8 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush) struct ath_buf *tbf; struct ath_desc *tds; - if (list_is_last(&bf->list, &sc->sc_rxbuf)) { - sc->sc_rxlink = NULL; + if (list_is_last(&bf->list, &sc->rx.rxbuf)) { + sc->rx.rxlink = NULL; break; } @@ -540,7 +539,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush) goto requeue; /* The status portion of the descriptor could get corrupted. */ - if (sc->sc_rxbufsize < ds->ds_rxstat.rs_datalen) + if (sc->rx.bufsize < ds->ds_rxstat.rs_datalen) goto requeue; if (!ath_rx_prepare(skb, ds, &rx_status, &decrypt_error, sc)) @@ -548,21 +547,21 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush) /* Ensure we always have an skb to requeue once we are done * processing the current buffer's skb */ - requeue_skb = ath_rxbuf_alloc(sc, sc->sc_rxbufsize); + requeue_skb = ath_rxbuf_alloc(sc, sc->rx.bufsize); /* If there is no memory we ignore the current RX'd frame, * tell hardware it can give us a new frame using the old - * skb and put it at the tail of the sc->sc_rxbuf list for + * skb and put it at the tail of the sc->rx.rxbuf list for * processing. */ if (!requeue_skb) goto requeue; - pci_dma_sync_single_for_cpu(sc->pdev, - bf->bf_buf_addr, - sc->sc_rxbufsize, + /* Sync and unmap the frame */ + pci_dma_sync_single_for_cpu(sc->pdev, bf->bf_buf_addr, + sc->rx.bufsize, PCI_DMA_FROMDEVICE); pci_unmap_single(sc->pdev, bf->bf_buf_addr, - sc->sc_rxbufsize, + sc->rx.bufsize, PCI_DMA_FROMDEVICE); skb_put(skb, ds->ds_rxstat.rs_datalen); @@ -596,7 +595,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush) /* We will now give hardware our shiny new allocated skb */ bf->bf_mpdu = requeue_skb; bf->bf_buf_addr = pci_map_single(sc->pdev, requeue_skb->data, - sc->sc_rxbufsize, + sc->rx.bufsize, PCI_DMA_FROMDEVICE); if (unlikely(pci_dma_mapping_error(sc->pdev, bf->bf_buf_addr))) { @@ -612,18 +611,18 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush) * change the default rx antenna if rx diversity chooses the * other antenna 3 times in a row. */ - if (sc->sc_defant != ds->ds_rxstat.rs_antenna) { - if (++sc->sc_rxotherant >= 3) + if (sc->rx.defant != ds->ds_rxstat.rs_antenna) { + if (++sc->rx.rxotherant >= 3) ath_setdefantenna(sc, ds->ds_rxstat.rs_antenna); } else { - sc->sc_rxotherant = 0; + sc->rx.rxotherant = 0; } requeue: - list_move_tail(&bf->list, &sc->sc_rxbuf); + list_move_tail(&bf->list, &sc->rx.rxbuf); ath_rx_buf_link(sc, bf); } while (1); - spin_unlock_bh(&sc->sc_rxbuflock); + spin_unlock_bh(&sc->rx.rxbuflock); return 0; #undef PA2DESC diff --git a/drivers/net/wireless/ath9k/xmit.c b/drivers/net/wireless/ath9k/xmit.c index e2e847db0891..f9c309ed3a2d 100644 --- a/drivers/net/wireless/ath9k/xmit.c +++ b/drivers/net/wireless/ath9k/xmit.c @@ -286,17 +286,17 @@ static struct ath_buf *ath_tx_get_buffer(struct ath_softc *sc) { struct ath_buf *bf = NULL; - spin_lock_bh(&sc->sc_txbuflock); + spin_lock_bh(&sc->tx.txbuflock); - if (unlikely(list_empty(&sc->sc_txbuf))) { - spin_unlock_bh(&sc->sc_txbuflock); + if (unlikely(list_empty(&sc->tx.txbuf))) { + spin_unlock_bh(&sc->tx.txbuflock); return NULL; } - bf = list_first_entry(&sc->sc_txbuf, struct ath_buf, list); + bf = list_first_entry(&sc->tx.txbuf, struct ath_buf, list); list_del(&bf->list); - spin_unlock_bh(&sc->sc_txbuflock); + spin_unlock_bh(&sc->tx.txbuflock); return bf; } @@ -341,9 +341,9 @@ static void ath_tx_complete_buf(struct ath_softc *sc, /* * Return the list of ath_buf of this mpdu to free queue */ - spin_lock_irqsave(&sc->sc_txbuflock, flags); - list_splice_tail_init(bf_q, &sc->sc_txbuf); - spin_unlock_irqrestore(&sc->sc_txbuflock, flags); + spin_lock_irqsave(&sc->tx.txbuflock, flags); + list_splice_tail_init(bf_q, &sc->tx.txbuf); + spin_unlock_irqrestore(&sc->tx.txbuflock, flags); } /* @@ -384,7 +384,7 @@ static void ath_tx_queue_tid(struct ath_txq *txq, struct ath_atx_tid *tid) static void ath_tx_pause_tid(struct ath_softc *sc, struct ath_atx_tid *tid) { - struct ath_txq *txq = &sc->sc_txq[tid->ac->qnum]; + struct ath_txq *txq = &sc->tx.txq[tid->ac->qnum]; spin_lock_bh(&txq->axq_lock); @@ -397,7 +397,7 @@ static void ath_tx_pause_tid(struct ath_softc *sc, struct ath_atx_tid *tid) void ath_tx_resume_tid(struct ath_softc *sc, struct ath_atx_tid *tid) { - struct ath_txq *txq = &sc->sc_txq[tid->ac->qnum]; + struct ath_txq *txq = &sc->tx.txq[tid->ac->qnum]; ASSERT(tid->paused > 0); spin_lock_bh(&txq->axq_lock); @@ -686,7 +686,7 @@ static int ath_tx_send_normal(struct ath_softc *sc, static void ath_tx_flush_tid(struct ath_softc *sc, struct ath_atx_tid *tid) { - struct ath_txq *txq = &sc->sc_txq[tid->ac->qnum]; + struct ath_txq *txq = &sc->tx.txq[tid->ac->qnum]; struct ath_buf *bf; struct list_head bf_head; INIT_LIST_HEAD(&bf_head); @@ -861,12 +861,12 @@ static void ath_tx_complete_aggr_rifs(struct ath_softc *sc, struct ath_buf *tbf; /* allocate new descriptor */ - spin_lock_bh(&sc->sc_txbuflock); - ASSERT(!list_empty((&sc->sc_txbuf))); - tbf = list_first_entry(&sc->sc_txbuf, + spin_lock_bh(&sc->tx.txbuflock); + ASSERT(!list_empty((&sc->tx.txbuf))); + tbf = list_first_entry(&sc->tx.txbuf, struct ath_buf, list); list_del(&tbf->list); - spin_unlock_bh(&sc->sc_txbuflock); + spin_unlock_bh(&sc->tx.txbuflock); ATH_TXBUF_RESET(tbf); @@ -1058,9 +1058,9 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq) if (bf_held) { list_del(&bf_held->list); - spin_lock_bh(&sc->sc_txbuflock); - list_add_tail(&bf_held->list, &sc->sc_txbuf); - spin_unlock_bh(&sc->sc_txbuflock); + spin_lock_bh(&sc->tx.txbuflock); + list_add_tail(&bf_held->list, &sc->tx.txbuf); + spin_unlock_bh(&sc->tx.txbuflock); } if (!bf_isampdu(bf)) { @@ -1129,11 +1129,11 @@ static void ath_drain_txdataq(struct ath_softc *sc, bool retry_tx) if (!(sc->sc_flags & SC_OP_INVALID)) { for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) { if (ATH_TXQ_SETUP(sc, i)) { - ath_tx_stopdma(sc, &sc->sc_txq[i]); + ath_tx_stopdma(sc, &sc->tx.txq[i]); /* The TxDMA may not really be stopped. * Double check the hal tx pending count */ npend += ath9k_hw_numtxpending(ah, - sc->sc_txq[i].axq_qnum); + sc->tx.txq[i].axq_qnum); } } } @@ -1158,7 +1158,7 @@ static void ath_drain_txdataq(struct ath_softc *sc, bool retry_tx) for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) { if (ATH_TXQ_SETUP(sc, i)) - ath_tx_draintxq(sc, &sc->sc_txq[i], retry_tx); + ath_tx_draintxq(sc, &sc->tx.txq[i], retry_tx); } } @@ -1820,9 +1820,9 @@ int ath_tx_start(struct ath_softc *sc, struct sk_buff *skb, } spin_unlock_bh(&txq->axq_lock); - spin_lock_bh(&sc->sc_txbuflock); - list_add_tail(&bf->list, &sc->sc_txbuf); - spin_unlock_bh(&sc->sc_txbuflock); + spin_lock_bh(&sc->tx.txbuflock); + list_add_tail(&bf->list, &sc->tx.txbuf); + spin_unlock_bh(&sc->tx.txbuflock); return r; } @@ -1839,10 +1839,10 @@ int ath_tx_init(struct ath_softc *sc, int nbufs) int error = 0; do { - spin_lock_init(&sc->sc_txbuflock); + spin_lock_init(&sc->tx.txbuflock); /* Setup tx descriptors */ - error = ath_descdma_setup(sc, &sc->sc_txdma, &sc->sc_txbuf, + error = ath_descdma_setup(sc, &sc->tx.txdma, &sc->tx.txbuf, "tx", nbufs, 1); if (error != 0) { DPRINTF(sc, ATH_DBG_FATAL, @@ -1852,7 +1852,7 @@ int ath_tx_init(struct ath_softc *sc, int nbufs) } /* XXX allocate beacon state together with vap */ - error = ath_descdma_setup(sc, &sc->sc_bdma, &sc->sc_bbuf, + error = ath_descdma_setup(sc, &sc->beacon.bdma, &sc->beacon.bbuf, "beacon", ATH_BCBUF, 1); if (error != 0) { DPRINTF(sc, ATH_DBG_FATAL, @@ -1874,12 +1874,12 @@ int ath_tx_init(struct ath_softc *sc, int nbufs) int ath_tx_cleanup(struct ath_softc *sc) { /* cleanup beacon descriptors */ - if (sc->sc_bdma.dd_desc_len != 0) - ath_descdma_cleanup(sc, &sc->sc_bdma, &sc->sc_bbuf); + if (sc->beacon.bdma.dd_desc_len != 0) + ath_descdma_cleanup(sc, &sc->beacon.bdma, &sc->beacon.bbuf); /* cleanup tx descriptors */ - if (sc->sc_txdma.dd_desc_len != 0) - ath_descdma_cleanup(sc, &sc->sc_txdma, &sc->sc_txbuf); + if (sc->tx.txdma.dd_desc_len != 0) + ath_descdma_cleanup(sc, &sc->tx.txdma, &sc->tx.txbuf); return 0; } @@ -1927,15 +1927,15 @@ struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype) */ return NULL; } - if (qnum >= ARRAY_SIZE(sc->sc_txq)) { + if (qnum >= ARRAY_SIZE(sc->tx.txq)) { DPRINTF(sc, ATH_DBG_FATAL, "qnum %u out of range, max %u!\n", - qnum, (unsigned int)ARRAY_SIZE(sc->sc_txq)); + qnum, (unsigned int)ARRAY_SIZE(sc->tx.txq)); ath9k_hw_releasetxqueue(ah, qnum); return NULL; } if (!ATH_TXQ_SETUP(sc, qnum)) { - struct ath_txq *txq = &sc->sc_txq[qnum]; + struct ath_txq *txq = &sc->tx.txq[qnum]; txq->axq_qnum = qnum; txq->axq_link = NULL; @@ -1946,9 +1946,9 @@ struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype) txq->axq_aggr_depth = 0; txq->axq_totalqueued = 0; txq->axq_linkbuf = NULL; - sc->sc_txqsetup |= 1<tx.txqsetup |= 1<sc_txq[qnum]; + return &sc->tx.txq[qnum]; } /* Reclaim resources for a setup queue */ @@ -1956,7 +1956,7 @@ struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype) void ath_tx_cleanupq(struct ath_softc *sc, struct ath_txq *txq) { ath9k_hw_releasetxqueue(sc->sc_ah, txq->axq_qnum); - sc->sc_txqsetup &= ~(1<axq_qnum); + sc->tx.txqsetup &= ~(1<axq_qnum); } /* @@ -1973,15 +1973,15 @@ int ath_tx_setup(struct ath_softc *sc, int haltype) { struct ath_txq *txq; - if (haltype >= ARRAY_SIZE(sc->sc_haltype2q)) { + if (haltype >= ARRAY_SIZE(sc->tx.hwq_map)) { DPRINTF(sc, ATH_DBG_FATAL, "HAL AC %u out of range, max %zu!\n", - haltype, ARRAY_SIZE(sc->sc_haltype2q)); + haltype, ARRAY_SIZE(sc->tx.hwq_map)); return 0; } txq = ath_txq_setup(sc, ATH9K_TX_QUEUE_DATA, haltype); if (txq != NULL) { - sc->sc_haltype2q[haltype] = txq->axq_qnum; + sc->tx.hwq_map[haltype] = txq->axq_qnum; return 1; } else return 0; @@ -1993,19 +1993,19 @@ int ath_tx_get_qnum(struct ath_softc *sc, int qtype, int haltype) switch (qtype) { case ATH9K_TX_QUEUE_DATA: - if (haltype >= ARRAY_SIZE(sc->sc_haltype2q)) { + if (haltype >= ARRAY_SIZE(sc->tx.hwq_map)) { DPRINTF(sc, ATH_DBG_FATAL, "HAL AC %u out of range, max %zu!\n", - haltype, ARRAY_SIZE(sc->sc_haltype2q)); + haltype, ARRAY_SIZE(sc->tx.hwq_map)); return -1; } - qnum = sc->sc_haltype2q[haltype]; + qnum = sc->tx.hwq_map[haltype]; break; case ATH9K_TX_QUEUE_BEACON: - qnum = sc->sc_bhalq; + qnum = sc->beacon.beaconq; break; case ATH9K_TX_QUEUE_CAB: - qnum = sc->sc_cabq->axq_qnum; + qnum = sc->beacon.cabq->axq_qnum; break; default: qnum = -1; @@ -2021,7 +2021,7 @@ struct ath_txq *ath_test_get_txq(struct ath_softc *sc, struct sk_buff *skb) int qnum; qnum = ath_get_hal_qnum(skb_get_queue_mapping(skb), sc); - txq = &sc->sc_txq[qnum]; + txq = &sc->tx.txq[qnum]; spin_lock_bh(&txq->axq_lock); @@ -2050,17 +2050,17 @@ int ath_txq_update(struct ath_softc *sc, int qnum, int error = 0; struct ath9k_tx_queue_info qi; - if (qnum == sc->sc_bhalq) { + if (qnum == sc->beacon.beaconq) { /* * XXX: for beacon queue, we just save the parameter. * It will be picked up by ath_beaconq_config when * it's necessary. */ - sc->sc_beacon_qi = *qinfo; + sc->beacon.beacon_qi = *qinfo; return 0; } - ASSERT(sc->sc_txq[qnum].axq_qnum == qnum); + ASSERT(sc->tx.txq[qnum].axq_qnum == qnum); ath9k_hw_get_txq_props(ah, qnum, &qi); qi.tqi_aifs = qinfo->tqi_aifs; @@ -2083,7 +2083,7 @@ int ath_txq_update(struct ath_softc *sc, int qnum, int ath_cabq_update(struct ath_softc *sc) { struct ath9k_tx_queue_info qi; - int qnum = sc->sc_cabq->axq_qnum; + int qnum = sc->beacon.cabq->axq_qnum; struct ath_beacon_config conf; ath9k_hw_get_txq_props(sc->sc_ah, qnum, &qi); @@ -2117,7 +2117,7 @@ void ath_tx_tasklet(struct ath_softc *sc) */ for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) { if (ATH_TXQ_SETUP(sc, i) && (qcumask & (1 << i))) - ath_tx_processq(sc, &sc->sc_txq[i]); + ath_tx_processq(sc, &sc->tx.txq[i]); } } @@ -2149,9 +2149,9 @@ void ath_tx_draintxq(struct ath_softc *sc, list_del(&bf->list); spin_unlock_bh(&txq->axq_lock); - spin_lock_bh(&sc->sc_txbuflock); - list_add_tail(&bf->list, &sc->sc_txbuf); - spin_unlock_bh(&sc->sc_txbuflock); + spin_lock_bh(&sc->tx.txbuflock); + list_add_tail(&bf->list, &sc->tx.txbuf); + spin_unlock_bh(&sc->tx.txbuflock); continue; } @@ -2189,9 +2189,9 @@ void ath_draintxq(struct ath_softc *sc, bool retry_tx) /* stop beacon queue. The beacon will be freed when * we go to INIT state */ if (!(sc->sc_flags & SC_OP_INVALID)) { - (void) ath9k_hw_stoptxdma(sc->sc_ah, sc->sc_bhalq); + (void) ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq); DPRINTF(sc, ATH_DBG_XMIT, "beacon queue %x\n", - ath9k_hw_gettxbuf(sc->sc_ah, sc->sc_bhalq)); + ath9k_hw_gettxbuf(sc->sc_ah, sc->beacon.beaconq)); } ath_drain_txdataq(sc, retry_tx); @@ -2199,12 +2199,12 @@ void ath_draintxq(struct ath_softc *sc, bool retry_tx) u32 ath_txq_depth(struct ath_softc *sc, int qnum) { - return sc->sc_txq[qnum].axq_depth; + return sc->tx.txq[qnum].axq_depth; } u32 ath_txq_aggr_depth(struct ath_softc *sc, int qnum) { - return sc->sc_txq[qnum].axq_aggr_depth; + return sc->tx.txq[qnum].axq_aggr_depth; } bool ath_tx_aggr_check(struct ath_softc *sc, struct ath_node *an, u8 tidno) @@ -2285,7 +2285,7 @@ void ath_tx_aggr_resume(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid void ath_tx_aggr_teardown(struct ath_softc *sc, struct ath_node *an, u8 tid) { struct ath_atx_tid *txtid = ATH_AN_2_TID(an, tid); - struct ath_txq *txq = &sc->sc_txq[txtid->ac->qnum]; + struct ath_txq *txq = &sc->tx.txq[txtid->ac->qnum]; struct ath_buf *bf; struct list_head bf_head; INIT_LIST_HEAD(&bf_head); @@ -2467,7 +2467,7 @@ void ath_tx_node_cleanup(struct ath_softc *sc, struct ath_node *an) struct ath_txq *txq; for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) { if (ATH_TXQ_SETUP(sc, i)) { - txq = &sc->sc_txq[i]; + txq = &sc->tx.txq[i]; spin_lock(&txq->axq_lock); @@ -2512,9 +2512,9 @@ void ath_tx_cabq(struct ath_softc *sc, struct sk_buff *skb) if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) { struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; if (info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT) - sc->seq_no += 0x10; + sc->tx.seq_no += 0x10; hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG); - hdr->seq_ctrl |= cpu_to_le16(sc->seq_no); + hdr->seq_ctrl |= cpu_to_le16(sc->tx.seq_no); } /* Add the padding after the header if this is not already done */ @@ -2530,7 +2530,7 @@ void ath_tx_cabq(struct ath_softc *sc, struct sk_buff *skb) memmove(skb->data, skb->data + padsize, hdrlen); } - txctl.txq = sc->sc_cabq; + txctl.txq = sc->beacon.cabq; DPRINTF(sc, ATH_DBG_XMIT, "transmitting CABQ packet, skb: %p\n", skb); -- cgit v1.2.3 From 9c5f89b3f6580cca21dca4ede940900c5b3c3a81 Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Thu, 11 Dec 2008 18:22:13 +0200 Subject: ath9k: Do not remove header padding on RX from short frames The 802.11 header is only padded to 32-bit boundary when the frame has a non-zero length payload. In other words, control frames (e.g., ACK) do not have a padding and we should not try to remove it. This fixes monitor mode for short control frames. In addition, the hdrlen&3 use is described in more detail to make it easier to understand how the padding length is calculated. Signed-off-by: Jouni Malinen Signed-off-by: John W. Linville --- drivers/net/wireless/ath9k/recv.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'drivers/net/wireless/ath9k/recv.c') diff --git a/drivers/net/wireless/ath9k/recv.c b/drivers/net/wireless/ath9k/recv.c index cb449f0b4171..f2327d8e9c28 100644 --- a/drivers/net/wireless/ath9k/recv.c +++ b/drivers/net/wireless/ath9k/recv.c @@ -571,8 +571,16 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush) hdr = (struct ieee80211_hdr *)skb->data; hdrlen = ieee80211_get_hdrlen_from_skb(skb); - if (hdrlen & 3) { - padsize = hdrlen % 4; + /* The MAC header is padded to have 32-bit boundary if the + * packet payload is non-zero. The general calculation for + * padsize would take into account odd header lengths: + * padsize = (4 - hdrlen % 4) % 4; However, since only + * even-length headers are used, padding can only be 0 or 2 + * bytes and we can optimize this a bit. In addition, we must + * not try to remove padding from short control frames that do + * not have payload. */ + padsize = hdrlen & 3; + if (padsize && hdrlen >= 24) { memmove(skb->data + padsize, skb->data, hdrlen); skb_pull(skb, padsize); } -- cgit v1.2.3 From baad1d921b1565b6f08f60c035531d13ad8afa82 Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Fri, 12 Dec 2008 14:38:34 +0200 Subject: ath9k: Report HT rates in RX status Fix and clean up the RX status reporting by getting rid of code that used internal rate tables and ratekbps calculation. The correct value is now reported with MCS index instead of the old mechanism that defaulted to using the highest legacy rate. Signed-off-by: Jouni Malinen Signed-off-by: John W. Linville --- drivers/net/wireless/ath9k/recv.c | 61 +++++++++++++++++---------------------- 1 file changed, 26 insertions(+), 35 deletions(-) (limited to 'drivers/net/wireless/ath9k/recv.c') diff --git a/drivers/net/wireless/ath9k/recv.c b/drivers/net/wireless/ath9k/recv.c index f2327d8e9c28..cc160fe9f817 100644 --- a/drivers/net/wireless/ath9k/recv.c +++ b/drivers/net/wireless/ath9k/recv.c @@ -111,33 +111,6 @@ static struct sk_buff *ath_rxbuf_alloc(struct ath_softc *sc, u32 len) return skb; } -static int ath_rate2idx(struct ath_softc *sc, int rate) -{ - int i = 0, cur_band, n_rates; - struct ieee80211_hw *hw = sc->hw; - - cur_band = hw->conf.channel->band; - n_rates = sc->sbands[cur_band].n_bitrates; - - for (i = 0; i < n_rates; i++) { - if (sc->sbands[cur_band].bitrates[i].bitrate == rate) - break; - } - - /* - * NB:mac80211 validates rx rate index against the supported legacy rate - * index only (should be done against ht rates also), return the highest - * legacy rate index for rx rate which does not match any one of the - * supported basic and extended rates to make mac80211 happy. - * The following hack will be cleaned up once the issue with - * the rx rate index validation in mac80211 is fixed. - */ - if (i == n_rates) - return n_rates - 1; - - return i; -} - /* * For Decrypt or Demic errors, we only mark packet status here and always push * up the frame up to let mac80211 handle the actual error case, be it no @@ -147,9 +120,7 @@ static int ath_rx_prepare(struct sk_buff *skb, struct ath_desc *ds, struct ieee80211_rx_status *rx_status, bool *decrypt_error, struct ath_softc *sc) { - struct ath_rate_table *rate_table = sc->cur_rate_table; struct ieee80211_hdr *hdr; - int ratekbps, rix; u8 ratecode; __le16 fc; @@ -204,15 +175,36 @@ static int ath_rx_prepare(struct sk_buff *skb, struct ath_desc *ds, } ratecode = ds->ds_rxstat.rs_rate; - rix = rate_table->rateCodeToIndex[ratecode]; - ratekbps = rate_table->info[rix].ratekbps; - /* HT rate */ if (ratecode & 0x80) { + /* HT rate */ + rx_status->flag |= RX_FLAG_HT; if (ds->ds_rxstat.rs_flags & ATH9K_RX_2040) - ratekbps = (ratekbps * 27) / 13; + rx_status->flag |= RX_FLAG_40MHZ; if (ds->ds_rxstat.rs_flags & ATH9K_RX_GI) - ratekbps = (ratekbps * 10) / 9; + rx_status->flag |= RX_FLAG_SHORT_GI; + rx_status->rate_idx = ratecode & 0x7f; + } else { + int i = 0, cur_band, n_rates; + struct ieee80211_hw *hw = sc->hw; + + cur_band = hw->conf.channel->band; + n_rates = sc->sbands[cur_band].n_bitrates; + + for (i = 0; i < n_rates; i++) { + if (sc->sbands[cur_band].bitrates[i].hw_value == + ratecode) { + rx_status->rate_idx = i; + break; + } + + if (sc->sbands[cur_band].bitrates[i].hw_value_short == + ratecode) { + rx_status->rate_idx = i; + rx_status->flag |= RX_FLAG_SHORTPRE; + break; + } + } } rx_status->mactime = ath_extend_tsf(sc, ds->ds_rxstat.rs_tstamp); @@ -220,7 +212,6 @@ static int ath_rx_prepare(struct sk_buff *skb, struct ath_desc *ds, rx_status->freq = sc->hw->conf.channel->center_freq; rx_status->noise = sc->sc_ani.sc_noise_floor; rx_status->signal = rx_status->noise + ds->ds_rxstat.rs_rssi; - rx_status->rate_idx = ath_rate2idx(sc, (ratekbps / 100)); rx_status->antenna = ds->ds_rxstat.rs_antenna; /* at 45 you will be able to use MCS 15 reliably. A more elaborate -- cgit v1.2.3 From 9bf9fca8dea70116016d32c2bf3f83170c8fba76 Mon Sep 17 00:00:00 2001 From: Vasanthakumar Thiagarajan Date: Mon, 15 Dec 2008 20:40:46 +0530 Subject: ath9k: Synchronize DMA transfer with CPU at right place This patch does pci_dma_sync_single_for_cpu() before accessing the header of the frame and queueing the same buffer into h/w. Signed-off-by: Vasanthakumar Thiagarajan Signed-off-by: John W. Linville --- drivers/net/wireless/ath9k/recv.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) (limited to 'drivers/net/wireless/ath9k/recv.c') diff --git a/drivers/net/wireless/ath9k/recv.c b/drivers/net/wireless/ath9k/recv.c index cc160fe9f817..462e08c3d09d 100644 --- a/drivers/net/wireless/ath9k/recv.c +++ b/drivers/net/wireless/ath9k/recv.c @@ -519,6 +519,15 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush) if (!skb) continue; + /* + * Synchronize the DMA transfer with CPU before + * 1. accessing the frame + * 2. requeueing the same buffer to h/w + */ + pci_dma_sync_single_for_cpu(sc->pdev, bf->bf_buf_addr, + sc->rx.bufsize, + PCI_DMA_FROMDEVICE); + /* * If we're asked to flush receive queue, directly * chain it back at the queue without processing it. @@ -547,10 +556,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush) if (!requeue_skb) goto requeue; - /* Sync and unmap the frame */ - pci_dma_sync_single_for_cpu(sc->pdev, bf->bf_buf_addr, - sc->rx.bufsize, - PCI_DMA_FROMDEVICE); + /* Unmap the frame */ pci_unmap_single(sc->pdev, bf->bf_buf_addr, sc->rx.bufsize, PCI_DMA_FROMDEVICE); -- cgit v1.2.3