diff options
Diffstat (limited to 'drivers/net/wireless/ath/ath9k/htc_drv_txrx.c')
-rw-r--r-- | drivers/net/wireless/ath/ath9k/htc_drv_txrx.c | 84 |
1 files changed, 50 insertions, 34 deletions
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c index 7a5ffca2195..4a4f27ba96a 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c | |||
@@ -84,7 +84,9 @@ int ath9k_htc_tx_start(struct ath9k_htc_priv *priv, struct sk_buff *skb) | |||
84 | struct ieee80211_hdr *hdr; | 84 | struct ieee80211_hdr *hdr; |
85 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); | 85 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); |
86 | struct ieee80211_sta *sta = tx_info->control.sta; | 86 | struct ieee80211_sta *sta = tx_info->control.sta; |
87 | struct ieee80211_vif *vif = tx_info->control.vif; | ||
87 | struct ath9k_htc_sta *ista; | 88 | struct ath9k_htc_sta *ista; |
89 | struct ath9k_htc_vif *avp; | ||
88 | struct ath9k_htc_tx_ctl tx_ctl; | 90 | struct ath9k_htc_tx_ctl tx_ctl; |
89 | enum htc_endpoint_id epid; | 91 | enum htc_endpoint_id epid; |
90 | u16 qnum; | 92 | u16 qnum; |
@@ -95,18 +97,31 @@ int ath9k_htc_tx_start(struct ath9k_htc_priv *priv, struct sk_buff *skb) | |||
95 | hdr = (struct ieee80211_hdr *) skb->data; | 97 | hdr = (struct ieee80211_hdr *) skb->data; |
96 | fc = hdr->frame_control; | 98 | fc = hdr->frame_control; |
97 | 99 | ||
98 | if (tx_info->control.vif && | 100 | /* |
99 | (struct ath9k_htc_vif *) tx_info->control.vif->drv_priv) | 101 | * Find out on which interface this packet has to be |
100 | vif_idx = ((struct ath9k_htc_vif *) | 102 | * sent out. |
101 | tx_info->control.vif->drv_priv)->index; | 103 | */ |
102 | else | 104 | if (vif) { |
103 | vif_idx = priv->nvifs; | 105 | avp = (struct ath9k_htc_vif *) vif->drv_priv; |
106 | vif_idx = avp->index; | ||
107 | } else { | ||
108 | if (!priv->ah->is_monitoring) { | ||
109 | ath_dbg(ath9k_hw_common(priv->ah), ATH_DBG_XMIT, | ||
110 | "VIF is null, but no monitor interface !\n"); | ||
111 | return -EINVAL; | ||
112 | } | ||
104 | 113 | ||
114 | vif_idx = priv->mon_vif_idx; | ||
115 | } | ||
116 | |||
117 | /* | ||
118 | * Find out which station this packet is destined for. | ||
119 | */ | ||
105 | if (sta) { | 120 | if (sta) { |
106 | ista = (struct ath9k_htc_sta *) sta->drv_priv; | 121 | ista = (struct ath9k_htc_sta *) sta->drv_priv; |
107 | sta_idx = ista->index; | 122 | sta_idx = ista->index; |
108 | } else { | 123 | } else { |
109 | sta_idx = 0; | 124 | sta_idx = priv->vif_sta_pos[vif_idx]; |
110 | } | 125 | } |
111 | 126 | ||
112 | memset(&tx_ctl, 0, sizeof(struct ath9k_htc_tx_ctl)); | 127 | memset(&tx_ctl, 0, sizeof(struct ath9k_htc_tx_ctl)); |
@@ -141,7 +156,7 @@ int ath9k_htc_tx_start(struct ath9k_htc_priv *priv, struct sk_buff *skb) | |||
141 | 156 | ||
142 | /* CTS-to-self */ | 157 | /* CTS-to-self */ |
143 | if (!(flags & ATH9K_HTC_TX_RTSCTS) && | 158 | if (!(flags & ATH9K_HTC_TX_RTSCTS) && |
144 | (priv->op_flags & OP_PROTECT_ENABLE)) | 159 | (vif && vif->bss_conf.use_cts_prot)) |
145 | flags |= ATH9K_HTC_TX_CTSONLY; | 160 | flags |= ATH9K_HTC_TX_CTSONLY; |
146 | 161 | ||
147 | tx_hdr.flags = cpu_to_be32(flags); | 162 | tx_hdr.flags = cpu_to_be32(flags); |
@@ -217,6 +232,7 @@ static bool ath9k_htc_check_tx_aggr(struct ath9k_htc_priv *priv, | |||
217 | void ath9k_tx_tasklet(unsigned long data) | 232 | void ath9k_tx_tasklet(unsigned long data) |
218 | { | 233 | { |
219 | struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *)data; | 234 | struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *)data; |
235 | struct ieee80211_vif *vif; | ||
220 | struct ieee80211_sta *sta; | 236 | struct ieee80211_sta *sta; |
221 | struct ieee80211_hdr *hdr; | 237 | struct ieee80211_hdr *hdr; |
222 | struct ieee80211_tx_info *tx_info; | 238 | struct ieee80211_tx_info *tx_info; |
@@ -228,12 +244,16 @@ void ath9k_tx_tasklet(unsigned long data) | |||
228 | hdr = (struct ieee80211_hdr *) skb->data; | 244 | hdr = (struct ieee80211_hdr *) skb->data; |
229 | fc = hdr->frame_control; | 245 | fc = hdr->frame_control; |
230 | tx_info = IEEE80211_SKB_CB(skb); | 246 | tx_info = IEEE80211_SKB_CB(skb); |
247 | vif = tx_info->control.vif; | ||
231 | 248 | ||
232 | memset(&tx_info->status, 0, sizeof(tx_info->status)); | 249 | memset(&tx_info->status, 0, sizeof(tx_info->status)); |
233 | 250 | ||
251 | if (!vif) | ||
252 | goto send_mac80211; | ||
253 | |||
234 | rcu_read_lock(); | 254 | rcu_read_lock(); |
235 | 255 | ||
236 | sta = ieee80211_find_sta(priv->vif, hdr->addr1); | 256 | sta = ieee80211_find_sta(vif, hdr->addr1); |
237 | if (!sta) { | 257 | if (!sta) { |
238 | rcu_read_unlock(); | 258 | rcu_read_unlock(); |
239 | ieee80211_tx_status(priv->hw, skb); | 259 | ieee80211_tx_status(priv->hw, skb); |
@@ -263,6 +283,7 @@ void ath9k_tx_tasklet(unsigned long data) | |||
263 | 283 | ||
264 | rcu_read_unlock(); | 284 | rcu_read_unlock(); |
265 | 285 | ||
286 | send_mac80211: | ||
266 | /* Send status to mac80211 */ | 287 | /* Send status to mac80211 */ |
267 | ieee80211_tx_status(priv->hw, skb); | 288 | ieee80211_tx_status(priv->hw, skb); |
268 | } | 289 | } |
@@ -386,7 +407,7 @@ u32 ath9k_htc_calcrxfilter(struct ath9k_htc_priv *priv) | |||
386 | */ | 407 | */ |
387 | if (((ah->opmode != NL80211_IFTYPE_AP) && | 408 | if (((ah->opmode != NL80211_IFTYPE_AP) && |
388 | (priv->rxfilter & FIF_PROMISC_IN_BSS)) || | 409 | (priv->rxfilter & FIF_PROMISC_IN_BSS)) || |
389 | (ah->opmode == NL80211_IFTYPE_MONITOR)) | 410 | ah->is_monitoring) |
390 | rfilt |= ATH9K_RX_FILTER_PROM; | 411 | rfilt |= ATH9K_RX_FILTER_PROM; |
391 | 412 | ||
392 | if (priv->rxfilter & FIF_CONTROL) | 413 | if (priv->rxfilter & FIF_CONTROL) |
@@ -398,8 +419,13 @@ u32 ath9k_htc_calcrxfilter(struct ath9k_htc_priv *priv) | |||
398 | else | 419 | else |
399 | rfilt |= ATH9K_RX_FILTER_BEACON; | 420 | rfilt |= ATH9K_RX_FILTER_BEACON; |
400 | 421 | ||
401 | if (conf_is_ht(&priv->hw->conf)) | 422 | if (conf_is_ht(&priv->hw->conf)) { |
402 | rfilt |= ATH9K_RX_FILTER_COMP_BAR; | 423 | rfilt |= ATH9K_RX_FILTER_COMP_BAR; |
424 | rfilt |= ATH9K_RX_FILTER_UNCOMP_BA_BAR; | ||
425 | } | ||
426 | |||
427 | if (priv->rxfilter & FIF_PSPOLL) | ||
428 | rfilt |= ATH9K_RX_FILTER_PSPOLL; | ||
403 | 429 | ||
404 | return rfilt; | 430 | return rfilt; |
405 | 431 | ||
@@ -412,20 +438,12 @@ u32 ath9k_htc_calcrxfilter(struct ath9k_htc_priv *priv) | |||
412 | static void ath9k_htc_opmode_init(struct ath9k_htc_priv *priv) | 438 | static void ath9k_htc_opmode_init(struct ath9k_htc_priv *priv) |
413 | { | 439 | { |
414 | struct ath_hw *ah = priv->ah; | 440 | struct ath_hw *ah = priv->ah; |
415 | struct ath_common *common = ath9k_hw_common(ah); | ||
416 | |||
417 | u32 rfilt, mfilt[2]; | 441 | u32 rfilt, mfilt[2]; |
418 | 442 | ||
419 | /* configure rx filter */ | 443 | /* configure rx filter */ |
420 | rfilt = ath9k_htc_calcrxfilter(priv); | 444 | rfilt = ath9k_htc_calcrxfilter(priv); |
421 | ath9k_hw_setrxfilter(ah, rfilt); | 445 | ath9k_hw_setrxfilter(ah, rfilt); |
422 | 446 | ||
423 | /* configure bssid mask */ | ||
424 | ath_hw_setbssidmask(common); | ||
425 | |||
426 | /* configure operational mode */ | ||
427 | ath9k_hw_setopmode(ah); | ||
428 | |||
429 | /* calculate and install multicast filter */ | 447 | /* calculate and install multicast filter */ |
430 | mfilt[0] = mfilt[1] = ~0; | 448 | mfilt[0] = mfilt[1] = ~0; |
431 | ath9k_hw_setmcastfilter(ah, mfilt[0], mfilt[1]); | 449 | ath9k_hw_setmcastfilter(ah, mfilt[0], mfilt[1]); |
@@ -576,31 +594,29 @@ static bool ath9k_rx_prepare(struct ath9k_htc_priv *priv, | |||
576 | ath9k_process_rate(hw, rx_status, rxbuf->rxstatus.rs_rate, | 594 | ath9k_process_rate(hw, rx_status, rxbuf->rxstatus.rs_rate, |
577 | rxbuf->rxstatus.rs_flags); | 595 | rxbuf->rxstatus.rs_flags); |
578 | 596 | ||
579 | if (priv->op_flags & OP_ASSOCIATED) { | 597 | if (rxbuf->rxstatus.rs_rssi != ATH9K_RSSI_BAD && |
580 | if (rxbuf->rxstatus.rs_rssi != ATH9K_RSSI_BAD && | 598 | !rxbuf->rxstatus.rs_moreaggr) |
581 | !rxbuf->rxstatus.rs_moreaggr) | 599 | ATH_RSSI_LPF(priv->rx.last_rssi, |
582 | ATH_RSSI_LPF(priv->rx.last_rssi, | 600 | rxbuf->rxstatus.rs_rssi); |
583 | rxbuf->rxstatus.rs_rssi); | ||
584 | 601 | ||
585 | last_rssi = priv->rx.last_rssi; | 602 | last_rssi = priv->rx.last_rssi; |
586 | 603 | ||
587 | if (likely(last_rssi != ATH_RSSI_DUMMY_MARKER)) | 604 | if (likely(last_rssi != ATH_RSSI_DUMMY_MARKER)) |
588 | rxbuf->rxstatus.rs_rssi = ATH_EP_RND(last_rssi, | 605 | rxbuf->rxstatus.rs_rssi = ATH_EP_RND(last_rssi, |
589 | ATH_RSSI_EP_MULTIPLIER); | 606 | ATH_RSSI_EP_MULTIPLIER); |
590 | 607 | ||
591 | if (rxbuf->rxstatus.rs_rssi < 0) | 608 | if (rxbuf->rxstatus.rs_rssi < 0) |
592 | rxbuf->rxstatus.rs_rssi = 0; | 609 | rxbuf->rxstatus.rs_rssi = 0; |
593 | 610 | ||
594 | if (ieee80211_is_beacon(fc)) | 611 | if (ieee80211_is_beacon(fc)) |
595 | priv->ah->stats.avgbrssi = rxbuf->rxstatus.rs_rssi; | 612 | priv->ah->stats.avgbrssi = rxbuf->rxstatus.rs_rssi; |
596 | } | ||
597 | 613 | ||
598 | rx_status->mactime = be64_to_cpu(rxbuf->rxstatus.rs_tstamp); | 614 | rx_status->mactime = be64_to_cpu(rxbuf->rxstatus.rs_tstamp); |
599 | rx_status->band = hw->conf.channel->band; | 615 | rx_status->band = hw->conf.channel->band; |
600 | rx_status->freq = hw->conf.channel->center_freq; | 616 | rx_status->freq = hw->conf.channel->center_freq; |
601 | rx_status->signal = rxbuf->rxstatus.rs_rssi + ATH_DEFAULT_NOISE_FLOOR; | 617 | rx_status->signal = rxbuf->rxstatus.rs_rssi + ATH_DEFAULT_NOISE_FLOOR; |
602 | rx_status->antenna = rxbuf->rxstatus.rs_antenna; | 618 | rx_status->antenna = rxbuf->rxstatus.rs_antenna; |
603 | rx_status->flag |= RX_FLAG_TSFT; | 619 | rx_status->flag |= RX_FLAG_MACTIME_MPDU; |
604 | 620 | ||
605 | return true; | 621 | return true; |
606 | 622 | ||