diff options
Diffstat (limited to 'drivers/net/wireless/ath/ath9k')
-rw-r--r-- | drivers/net/wireless/ath/ath9k/ath9k.h | 10 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/common.c | 19 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/common.h | 1 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/debug.c | 11 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/hw.c | 55 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/hw.h | 23 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/main.c | 121 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/phy.c | 90 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/phy.h | 3 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/rc.c | 73 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/rc.h | 18 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/virtual.c | 9 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/xmit.c | 83 |
13 files changed, 141 insertions, 375 deletions
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index d9bcc3abb425..2a40fa2cd914 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h | |||
@@ -198,18 +198,8 @@ struct ath_txq { | |||
198 | struct list_head axq_q; | 198 | struct list_head axq_q; |
199 | spinlock_t axq_lock; | 199 | spinlock_t axq_lock; |
200 | u32 axq_depth; | 200 | u32 axq_depth; |
201 | u8 axq_aggr_depth; | ||
202 | bool stopped; | 201 | bool stopped; |
203 | bool axq_tx_inprogress; | 202 | bool axq_tx_inprogress; |
204 | struct ath_buf *axq_linkbuf; | ||
205 | |||
206 | /* first desc of the last descriptor that contains CTS */ | ||
207 | struct ath_desc *axq_lastdsWithCTS; | ||
208 | |||
209 | /* final desc of the gating desc that determines whether | ||
210 | lastdsWithCTS has been DMA'ed or not */ | ||
211 | struct ath_desc *axq_gatingds; | ||
212 | |||
213 | struct list_head axq_acq; | 203 | struct list_head axq_acq; |
214 | }; | 204 | }; |
215 | 205 | ||
diff --git a/drivers/net/wireless/ath/ath9k/common.c b/drivers/net/wireless/ath/ath9k/common.c index 2f1e1612e2ad..4a13632e3e4d 100644 --- a/drivers/net/wireless/ath/ath9k/common.c +++ b/drivers/net/wireless/ath/ath9k/common.c | |||
@@ -231,26 +231,35 @@ void ath9k_cmn_rx_skb_postprocess(struct ath_common *common, | |||
231 | { | 231 | { |
232 | struct ath_hw *ah = common->ah; | 232 | struct ath_hw *ah = common->ah; |
233 | struct ieee80211_hdr *hdr; | 233 | struct ieee80211_hdr *hdr; |
234 | int hdrlen, padsize; | 234 | int hdrlen, padpos, padsize; |
235 | u8 keyix; | 235 | u8 keyix; |
236 | __le16 fc; | 236 | __le16 fc; |
237 | 237 | ||
238 | /* see if any padding is done by the hw and remove it */ | 238 | /* see if any padding is done by the hw and remove it */ |
239 | hdr = (struct ieee80211_hdr *) skb->data; | 239 | hdr = (struct ieee80211_hdr *) skb->data; |
240 | hdrlen = ieee80211_get_hdrlen_from_skb(skb); | 240 | hdrlen = ieee80211_get_hdrlen_from_skb(skb); |
241 | padpos = 24; | ||
241 | fc = hdr->frame_control; | 242 | fc = hdr->frame_control; |
243 | if ((fc & cpu_to_le16(IEEE80211_FCTL_FROMDS|IEEE80211_FCTL_TODS)) == | ||
244 | cpu_to_le16(IEEE80211_FCTL_FROMDS|IEEE80211_FCTL_TODS)) { | ||
245 | padpos += 6; /* ETH_ALEN */ | ||
246 | } | ||
247 | if ((fc & cpu_to_le16(IEEE80211_STYPE_QOS_DATA|IEEE80211_FCTL_FTYPE)) == | ||
248 | cpu_to_le16(IEEE80211_STYPE_QOS_DATA|IEEE80211_FTYPE_DATA)) { | ||
249 | padpos += 2; | ||
250 | } | ||
242 | 251 | ||
243 | /* The MAC header is padded to have 32-bit boundary if the | 252 | /* The MAC header is padded to have 32-bit boundary if the |
244 | * packet payload is non-zero. The general calculation for | 253 | * packet payload is non-zero. The general calculation for |
245 | * padsize would take into account odd header lengths: | 254 | * padsize would take into account odd header lengths: |
246 | * padsize = (4 - hdrlen % 4) % 4; However, since only | 255 | * padsize = (4 - padpos % 4) % 4; However, since only |
247 | * even-length headers are used, padding can only be 0 or 2 | 256 | * even-length headers are used, padding can only be 0 or 2 |
248 | * bytes and we can optimize this a bit. In addition, we must | 257 | * bytes and we can optimize this a bit. In addition, we must |
249 | * not try to remove padding from short control frames that do | 258 | * not try to remove padding from short control frames that do |
250 | * not have payload. */ | 259 | * not have payload. */ |
251 | padsize = hdrlen & 3; | 260 | padsize = padpos & 3; |
252 | if (padsize && hdrlen >= 24) { | 261 | if (padsize && skb->len>=padpos+padsize+FCS_LEN) { |
253 | memmove(skb->data + padsize, skb->data, hdrlen); | 262 | memmove(skb->data + padsize, skb->data, padpos); |
254 | skb_pull(skb, padsize); | 263 | skb_pull(skb, padsize); |
255 | } | 264 | } |
256 | 265 | ||
diff --git a/drivers/net/wireless/ath/ath9k/common.h b/drivers/net/wireless/ath/ath9k/common.h index 292e3d860c0e..4e1176029356 100644 --- a/drivers/net/wireless/ath/ath9k/common.h +++ b/drivers/net/wireless/ath/ath9k/common.h | |||
@@ -81,6 +81,7 @@ struct ath_buf { | |||
81 | u16 bf_flags; | 81 | u16 bf_flags; |
82 | struct ath_buf_state bf_state; | 82 | struct ath_buf_state bf_state; |
83 | dma_addr_t bf_dmacontext; | 83 | dma_addr_t bf_dmacontext; |
84 | struct ath_wiphy *aphy; | ||
84 | }; | 85 | }; |
85 | 86 | ||
86 | struct ath_atx_tid { | 87 | struct ath_atx_tid { |
diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c index 84f44269de47..06f1fcfb03e9 100644 --- a/drivers/net/wireless/ath/ath9k/debug.c +++ b/drivers/net/wireless/ath/ath9k/debug.c | |||
@@ -257,14 +257,17 @@ static const struct file_operations fops_interrupt = { | |||
257 | 257 | ||
258 | void ath_debug_stat_rc(struct ath_softc *sc, struct sk_buff *skb) | 258 | void ath_debug_stat_rc(struct ath_softc *sc, struct sk_buff *skb) |
259 | { | 259 | { |
260 | struct ath_tx_info_priv *tx_info_priv = NULL; | ||
261 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); | 260 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); |
262 | struct ieee80211_tx_rate *rates = tx_info->status.rates; | 261 | struct ieee80211_tx_rate *rates = tx_info->status.rates; |
263 | int final_ts_idx, idx; | 262 | int final_ts_idx = 0, idx, i; |
264 | struct ath_rc_stats *stats; | 263 | struct ath_rc_stats *stats; |
265 | 264 | ||
266 | tx_info_priv = ATH_TX_INFO_PRIV(tx_info); | 265 | for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) { |
267 | final_ts_idx = tx_info_priv->tx.ts_rateindex; | 266 | if (!rates[i].count) |
267 | break; | ||
268 | |||
269 | final_ts_idx = i; | ||
270 | } | ||
268 | idx = rates[final_ts_idx].idx; | 271 | idx = rates[final_ts_idx].idx; |
269 | stats = &sc->debug.stats.rcstats[idx]; | 272 | stats = &sc->debug.stats.rcstats[idx]; |
270 | stats->success++; | 273 | stats->success++; |
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index b25eedf67e0b..53a7b980d8f6 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c | |||
@@ -390,8 +390,6 @@ static void ath9k_hw_init_config(struct ath_hw *ah) | |||
390 | ah->config.cck_trig_high = 200; | 390 | ah->config.cck_trig_high = 200; |
391 | ah->config.cck_trig_low = 100; | 391 | ah->config.cck_trig_low = 100; |
392 | ah->config.enable_ani = 1; | 392 | ah->config.enable_ani = 1; |
393 | ah->config.diversity_control = ATH9K_ANT_VARIABLE; | ||
394 | ah->config.antenna_switch_swap = 0; | ||
395 | 393 | ||
396 | for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) { | 394 | for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) { |
397 | ah->config.spurchans[i][0] = AR_NO_SPUR; | 395 | ah->config.spurchans[i][0] = AR_NO_SPUR; |
@@ -446,9 +444,6 @@ static void ath9k_hw_init_defaults(struct ath_hw *ah) | |||
446 | ah->acktimeout = (u32) -1; | 444 | ah->acktimeout = (u32) -1; |
447 | ah->ctstimeout = (u32) -1; | 445 | ah->ctstimeout = (u32) -1; |
448 | ah->globaltxtimeout = (u32) -1; | 446 | ah->globaltxtimeout = (u32) -1; |
449 | |||
450 | ah->gbeacon_rate = 0; | ||
451 | |||
452 | ah->power_mode = ATH9K_PM_UNDEFINED; | 447 | ah->power_mode = ATH9K_PM_UNDEFINED; |
453 | } | 448 | } |
454 | 449 | ||
@@ -1151,7 +1146,7 @@ static void ath9k_hw_init_chain_masks(struct ath_hw *ah) | |||
1151 | REG_SET_BIT(ah, AR_PHY_ANALOG_SWAP, | 1146 | REG_SET_BIT(ah, AR_PHY_ANALOG_SWAP, |
1152 | AR_PHY_SWAP_ALT_CHAIN); | 1147 | AR_PHY_SWAP_ALT_CHAIN); |
1153 | case 0x3: | 1148 | case 0x3: |
1154 | if (((ah)->hw_version.macVersion <= AR_SREV_VERSION_9160)) { | 1149 | if (ah->hw_version.macVersion == AR_SREV_REVISION_5416_10) { |
1155 | REG_WRITE(ah, AR_PHY_RX_CHAINMASK, 0x7); | 1150 | REG_WRITE(ah, AR_PHY_RX_CHAINMASK, 0x7); |
1156 | REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, 0x7); | 1151 | REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, 0x7); |
1157 | break; | 1152 | break; |
@@ -2056,9 +2051,6 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, | |||
2056 | ah->ath9k_hw_spur_mitigate_freq(ah, chan); | 2051 | ah->ath9k_hw_spur_mitigate_freq(ah, chan); |
2057 | ah->eep_ops->set_board_values(ah, chan); | 2052 | ah->eep_ops->set_board_values(ah, chan); |
2058 | 2053 | ||
2059 | if (AR_SREV_5416(ah)) | ||
2060 | ath9k_hw_decrease_chain_power(ah, chan); | ||
2061 | |||
2062 | REG_WRITE(ah, AR_STA_ID0, get_unaligned_le32(common->macaddr)); | 2054 | REG_WRITE(ah, AR_STA_ID0, get_unaligned_le32(common->macaddr)); |
2063 | REG_WRITE(ah, AR_STA_ID1, get_unaligned_le16(common->macaddr + 4) | 2055 | REG_WRITE(ah, AR_STA_ID1, get_unaligned_le16(common->macaddr + 4) |
2064 | | macStaId1 | 2056 | | macStaId1 |
@@ -3518,51 +3510,6 @@ void ath9k_hw_setantenna(struct ath_hw *ah, u32 antenna) | |||
3518 | } | 3510 | } |
3519 | EXPORT_SYMBOL(ath9k_hw_setantenna); | 3511 | EXPORT_SYMBOL(ath9k_hw_setantenna); |
3520 | 3512 | ||
3521 | bool ath9k_hw_setantennaswitch(struct ath_hw *ah, | ||
3522 | enum ath9k_ant_setting settings, | ||
3523 | struct ath9k_channel *chan, | ||
3524 | u8 *tx_chainmask, | ||
3525 | u8 *rx_chainmask, | ||
3526 | u8 *antenna_cfgd) | ||
3527 | { | ||
3528 | static u8 tx_chainmask_cfg, rx_chainmask_cfg; | ||
3529 | |||
3530 | if (AR_SREV_9280(ah)) { | ||
3531 | if (!tx_chainmask_cfg) { | ||
3532 | |||
3533 | tx_chainmask_cfg = *tx_chainmask; | ||
3534 | rx_chainmask_cfg = *rx_chainmask; | ||
3535 | } | ||
3536 | |||
3537 | switch (settings) { | ||
3538 | case ATH9K_ANT_FIXED_A: | ||
3539 | *tx_chainmask = ATH9K_ANTENNA0_CHAINMASK; | ||
3540 | *rx_chainmask = ATH9K_ANTENNA0_CHAINMASK; | ||
3541 | *antenna_cfgd = true; | ||
3542 | break; | ||
3543 | case ATH9K_ANT_FIXED_B: | ||
3544 | if (ah->caps.tx_chainmask > | ||
3545 | ATH9K_ANTENNA1_CHAINMASK) { | ||
3546 | *tx_chainmask = ATH9K_ANTENNA1_CHAINMASK; | ||
3547 | } | ||
3548 | *rx_chainmask = ATH9K_ANTENNA1_CHAINMASK; | ||
3549 | *antenna_cfgd = true; | ||
3550 | break; | ||
3551 | case ATH9K_ANT_VARIABLE: | ||
3552 | *tx_chainmask = tx_chainmask_cfg; | ||
3553 | *rx_chainmask = rx_chainmask_cfg; | ||
3554 | *antenna_cfgd = true; | ||
3555 | break; | ||
3556 | default: | ||
3557 | break; | ||
3558 | } | ||
3559 | } else { | ||
3560 | ah->config.diversity_control = settings; | ||
3561 | } | ||
3562 | |||
3563 | return true; | ||
3564 | } | ||
3565 | |||
3566 | /*********************/ | 3513 | /*********************/ |
3567 | /* General Operation */ | 3514 | /* General Operation */ |
3568 | /*********************/ | 3515 | /*********************/ |
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index abaa2f09a3bc..f8f5e997162c 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h | |||
@@ -148,21 +148,6 @@ enum wireless_mode { | |||
148 | ATH9K_MODE_MAX, | 148 | ATH9K_MODE_MAX, |
149 | }; | 149 | }; |
150 | 150 | ||
151 | /** | ||
152 | * ath9k_ant_setting - transmit antenna settings | ||
153 | * | ||
154 | * Configures the antenna setting to use for transmit. | ||
155 | * | ||
156 | * @ATH9K_ANT_VARIABLE: this means transmit on all active antennas | ||
157 | * @ATH9K_ANT_FIXED_A: this means transmit on the first antenna only | ||
158 | * @ATH9K_ANT_FIXED_B: this means transmit on the second antenna only | ||
159 | */ | ||
160 | enum ath9k_ant_setting { | ||
161 | ATH9K_ANT_VARIABLE = 0, | ||
162 | ATH9K_ANT_FIXED_A, | ||
163 | ATH9K_ANT_FIXED_B | ||
164 | }; | ||
165 | |||
166 | enum ath9k_hw_caps { | 151 | enum ath9k_hw_caps { |
167 | ATH9K_HW_CAP_MIC_AESCCM = BIT(0), | 152 | ATH9K_HW_CAP_MIC_AESCCM = BIT(0), |
168 | ATH9K_HW_CAP_MIC_CKIP = BIT(1), | 153 | ATH9K_HW_CAP_MIC_CKIP = BIT(1), |
@@ -226,8 +211,6 @@ struct ath9k_ops_config { | |||
226 | u32 cck_trig_high; | 211 | u32 cck_trig_high; |
227 | u32 cck_trig_low; | 212 | u32 cck_trig_low; |
228 | u32 enable_ani; | 213 | u32 enable_ani; |
229 | enum ath9k_ant_setting diversity_control; | ||
230 | u16 antenna_switch_swap; | ||
231 | int serialize_regmode; | 214 | int serialize_regmode; |
232 | bool intr_mitigation; | 215 | bool intr_mitigation; |
233 | #define SPUR_DISABLE 0 | 216 | #define SPUR_DISABLE 0 |
@@ -572,7 +555,6 @@ struct ath_hw { | |||
572 | u32 acktimeout; | 555 | u32 acktimeout; |
573 | u32 ctstimeout; | 556 | u32 ctstimeout; |
574 | u32 globaltxtimeout; | 557 | u32 globaltxtimeout; |
575 | u8 gbeacon_rate; | ||
576 | 558 | ||
577 | /* ANI */ | 559 | /* ANI */ |
578 | u32 proc_phyerr; | 560 | u32 proc_phyerr; |
@@ -659,11 +641,6 @@ void ath9k_hw_cfg_output(struct ath_hw *ah, u32 gpio, | |||
659 | void ath9k_hw_set_gpio(struct ath_hw *ah, u32 gpio, u32 val); | 641 | void ath9k_hw_set_gpio(struct ath_hw *ah, u32 gpio, u32 val); |
660 | u32 ath9k_hw_getdefantenna(struct ath_hw *ah); | 642 | u32 ath9k_hw_getdefantenna(struct ath_hw *ah); |
661 | void ath9k_hw_setantenna(struct ath_hw *ah, u32 antenna); | 643 | void ath9k_hw_setantenna(struct ath_hw *ah, u32 antenna); |
662 | bool ath9k_hw_setantennaswitch(struct ath_hw *ah, | ||
663 | enum ath9k_ant_setting settings, | ||
664 | struct ath9k_channel *chan, | ||
665 | u8 *tx_chainmask, u8 *rx_chainmask, | ||
666 | u8 *antenna_cfgd); | ||
667 | 644 | ||
668 | /* General Operation */ | 645 | /* General Operation */ |
669 | bool ath9k_hw_wait(struct ath_hw *ah, u32 reg, u32 mask, u32 val, u32 timeout); | 646 | bool ath9k_hw_wait(struct ath_hw *ah, u32 reg, u32 mask, u32 val, u32 timeout); |
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 3c02b977a613..cbf5d2a1bb26 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c | |||
@@ -1893,6 +1893,8 @@ void ath_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw) | |||
1893 | BIT(NL80211_IFTYPE_ADHOC) | | 1893 | BIT(NL80211_IFTYPE_ADHOC) | |
1894 | BIT(NL80211_IFTYPE_MESH_POINT); | 1894 | BIT(NL80211_IFTYPE_MESH_POINT); |
1895 | 1895 | ||
1896 | hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; | ||
1897 | |||
1896 | hw->queues = 4; | 1898 | hw->queues = 4; |
1897 | hw->max_rates = 4; | 1899 | hw->max_rates = 4; |
1898 | hw->channel_change_time = 5000; | 1900 | hw->channel_change_time = 5000; |
@@ -2956,90 +2958,62 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw, | |||
2956 | struct ath_hw *ah = sc->sc_ah; | 2958 | struct ath_hw *ah = sc->sc_ah; |
2957 | struct ath_common *common = ath9k_hw_common(ah); | 2959 | struct ath_common *common = ath9k_hw_common(ah); |
2958 | struct ath_vif *avp = (void *)vif->drv_priv; | 2960 | struct ath_vif *avp = (void *)vif->drv_priv; |
2959 | u32 rfilt = 0; | 2961 | int error; |
2960 | int error, i; | ||
2961 | 2962 | ||
2962 | mutex_lock(&sc->mutex); | 2963 | mutex_lock(&sc->mutex); |
2963 | 2964 | ||
2964 | /* | 2965 | if (changed & BSS_CHANGED_BSSID) { |
2965 | * TODO: Need to decide which hw opmode to use for | 2966 | /* Set BSSID */ |
2966 | * multi-interface cases | 2967 | memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN); |
2967 | * XXX: This belongs into add_interface! | 2968 | memcpy(avp->bssid, bss_conf->bssid, ETH_ALEN); |
2968 | */ | ||
2969 | if (vif->type == NL80211_IFTYPE_AP && | ||
2970 | ah->opmode != NL80211_IFTYPE_AP) { | ||
2971 | ah->opmode = NL80211_IFTYPE_STATION; | ||
2972 | ath9k_hw_setopmode(ah); | ||
2973 | memcpy(common->curbssid, common->macaddr, ETH_ALEN); | ||
2974 | common->curaid = 0; | 2969 | common->curaid = 0; |
2975 | ath9k_hw_write_associd(ah); | 2970 | ath9k_hw_write_associd(ah); |
2976 | /* Request full reset to get hw opmode changed properly */ | ||
2977 | sc->sc_flags |= SC_OP_FULL_RESET; | ||
2978 | } | ||
2979 | 2971 | ||
2980 | if ((changed & BSS_CHANGED_BSSID) && | 2972 | /* Set aggregation protection mode parameters */ |
2981 | !is_zero_ether_addr(bss_conf->bssid)) { | 2973 | sc->config.ath_aggr_prot = 0; |
2982 | switch (vif->type) { | ||
2983 | case NL80211_IFTYPE_STATION: | ||
2984 | case NL80211_IFTYPE_ADHOC: | ||
2985 | case NL80211_IFTYPE_MESH_POINT: | ||
2986 | /* Set BSSID */ | ||
2987 | memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN); | ||
2988 | memcpy(avp->bssid, bss_conf->bssid, ETH_ALEN); | ||
2989 | common->curaid = 0; | ||
2990 | ath9k_hw_write_associd(ah); | ||
2991 | 2974 | ||
2992 | /* Set aggregation protection mode parameters */ | 2975 | /* Only legacy IBSS for now */ |
2993 | sc->config.ath_aggr_prot = 0; | 2976 | if (vif->type == NL80211_IFTYPE_ADHOC) |
2977 | ath_update_chainmask(sc, 0); | ||
2994 | 2978 | ||
2995 | ath_print(common, ATH_DBG_CONFIG, | 2979 | ath_print(common, ATH_DBG_CONFIG, |
2996 | "RX filter 0x%x bssid %pM aid 0x%x\n", | 2980 | "BSSID: %pM aid: 0x%x\n", |
2997 | rfilt, common->curbssid, common->curaid); | 2981 | common->curbssid, common->curaid); |
2998 | 2982 | ||
2999 | /* need to reconfigure the beacon */ | 2983 | /* need to reconfigure the beacon */ |
3000 | sc->sc_flags &= ~SC_OP_BEACONS ; | 2984 | sc->sc_flags &= ~SC_OP_BEACONS ; |
2985 | } | ||
3001 | 2986 | ||
3002 | break; | 2987 | /* Enable transmission of beacons (AP, IBSS, MESH) */ |
3003 | default: | 2988 | if ((changed & BSS_CHANGED_BEACON) || |
3004 | break; | 2989 | ((changed & BSS_CHANGED_BEACON_ENABLED) && bss_conf->enable_beacon)) { |
3005 | } | 2990 | ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq); |
2991 | error = ath_beacon_alloc(aphy, vif); | ||
2992 | if (!error) | ||
2993 | ath_beacon_config(sc, vif); | ||
3006 | } | 2994 | } |
3007 | 2995 | ||
3008 | if ((vif->type == NL80211_IFTYPE_ADHOC) || | 2996 | /* Disable transmission of beacons */ |
3009 | (vif->type == NL80211_IFTYPE_AP) || | 2997 | if ((changed & BSS_CHANGED_BEACON_ENABLED) && !bss_conf->enable_beacon) |
3010 | (vif->type == NL80211_IFTYPE_MESH_POINT)) { | 2998 | ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq); |
3011 | if ((changed & BSS_CHANGED_BEACON) || | ||
3012 | (changed & BSS_CHANGED_BEACON_ENABLED && | ||
3013 | bss_conf->enable_beacon)) { | ||
3014 | /* | ||
3015 | * Allocate and setup the beacon frame. | ||
3016 | * | ||
3017 | * Stop any previous beacon DMA. This may be | ||
3018 | * necessary, for example, when an ibss merge | ||
3019 | * causes reconfiguration; we may be called | ||
3020 | * with beacon transmission active. | ||
3021 | */ | ||
3022 | ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq); | ||
3023 | 2999 | ||
3000 | if (changed & BSS_CHANGED_BEACON_INT) { | ||
3001 | sc->beacon_interval = bss_conf->beacon_int; | ||
3002 | /* | ||
3003 | * In case of AP mode, the HW TSF has to be reset | ||
3004 | * when the beacon interval changes. | ||
3005 | */ | ||
3006 | if (vif->type == NL80211_IFTYPE_AP) { | ||
3007 | sc->sc_flags |= SC_OP_TSF_RESET; | ||
3008 | ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq); | ||
3024 | error = ath_beacon_alloc(aphy, vif); | 3009 | error = ath_beacon_alloc(aphy, vif); |
3025 | if (!error) | 3010 | if (!error) |
3026 | ath_beacon_config(sc, vif); | 3011 | ath_beacon_config(sc, vif); |
3012 | } else { | ||
3013 | ath_beacon_config(sc, vif); | ||
3027 | } | 3014 | } |
3028 | } | 3015 | } |
3029 | 3016 | ||
3030 | /* Check for WLAN_CAPABILITY_PRIVACY ? */ | ||
3031 | if ((avp->av_opmode != NL80211_IFTYPE_STATION)) { | ||
3032 | for (i = 0; i < IEEE80211_WEP_NKID; i++) | ||
3033 | if (ath9k_hw_keyisvalid(sc->sc_ah, (u16)i)) | ||
3034 | ath9k_hw_keysetmac(sc->sc_ah, | ||
3035 | (u16)i, | ||
3036 | common->curbssid); | ||
3037 | } | ||
3038 | |||
3039 | /* Only legacy IBSS for now */ | ||
3040 | if (vif->type == NL80211_IFTYPE_ADHOC) | ||
3041 | ath_update_chainmask(sc, 0); | ||
3042 | |||
3043 | if (changed & BSS_CHANGED_ERP_PREAMBLE) { | 3017 | if (changed & BSS_CHANGED_ERP_PREAMBLE) { |
3044 | ath_print(common, ATH_DBG_CONFIG, "BSS Changed PREAMBLE %d\n", | 3018 | ath_print(common, ATH_DBG_CONFIG, "BSS Changed PREAMBLE %d\n", |
3045 | bss_conf->use_short_preamble); | 3019 | bss_conf->use_short_preamble); |
@@ -3065,18 +3039,6 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw, | |||
3065 | ath9k_bss_assoc_info(sc, vif, bss_conf); | 3039 | ath9k_bss_assoc_info(sc, vif, bss_conf); |
3066 | } | 3040 | } |
3067 | 3041 | ||
3068 | /* | ||
3069 | * The HW TSF has to be reset when the beacon interval changes. | ||
3070 | * We set the flag here, and ath_beacon_config_ap() would take this | ||
3071 | * into account when it gets called through the subsequent | ||
3072 | * config_interface() call - with IFCC_BEACON in the changed field. | ||
3073 | */ | ||
3074 | |||
3075 | if (changed & BSS_CHANGED_BEACON_INT) { | ||
3076 | sc->sc_flags |= SC_OP_TSF_RESET; | ||
3077 | sc->beacon_interval = bss_conf->beacon_int; | ||
3078 | } | ||
3079 | |||
3080 | mutex_unlock(&sc->mutex); | 3042 | mutex_unlock(&sc->mutex); |
3081 | } | 3043 | } |
3082 | 3044 | ||
@@ -3118,6 +3080,7 @@ static void ath9k_reset_tsf(struct ieee80211_hw *hw) | |||
3118 | } | 3080 | } |
3119 | 3081 | ||
3120 | static int ath9k_ampdu_action(struct ieee80211_hw *hw, | 3082 | static int ath9k_ampdu_action(struct ieee80211_hw *hw, |
3083 | struct ieee80211_vif *vif, | ||
3121 | enum ieee80211_ampdu_mlme_action action, | 3084 | enum ieee80211_ampdu_mlme_action action, |
3122 | struct ieee80211_sta *sta, | 3085 | struct ieee80211_sta *sta, |
3123 | u16 tid, u16 *ssn) | 3086 | u16 tid, u16 *ssn) |
@@ -3135,11 +3098,11 @@ static int ath9k_ampdu_action(struct ieee80211_hw *hw, | |||
3135 | break; | 3098 | break; |
3136 | case IEEE80211_AMPDU_TX_START: | 3099 | case IEEE80211_AMPDU_TX_START: |
3137 | ath_tx_aggr_start(sc, sta, tid, ssn); | 3100 | ath_tx_aggr_start(sc, sta, tid, ssn); |
3138 | ieee80211_start_tx_ba_cb_irqsafe(hw, sta->addr, tid); | 3101 | ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid); |
3139 | break; | 3102 | break; |
3140 | case IEEE80211_AMPDU_TX_STOP: | 3103 | case IEEE80211_AMPDU_TX_STOP: |
3141 | ath_tx_aggr_stop(sc, sta, tid); | 3104 | ath_tx_aggr_stop(sc, sta, tid); |
3142 | ieee80211_stop_tx_ba_cb_irqsafe(hw, sta->addr, tid); | 3105 | ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid); |
3143 | break; | 3106 | break; |
3144 | case IEEE80211_AMPDU_TX_OPERATIONAL: | 3107 | case IEEE80211_AMPDU_TX_OPERATIONAL: |
3145 | ath_tx_aggr_resume(sc, sta, tid); | 3108 | ath_tx_aggr_resume(sc, sta, tid); |
diff --git a/drivers/net/wireless/ath/ath9k/phy.c b/drivers/net/wireless/ath/ath9k/phy.c index 13ab4d7eb7aa..c3b59390fe38 100644 --- a/drivers/net/wireless/ath/ath9k/phy.c +++ b/drivers/net/wireless/ath/ath9k/phy.c | |||
@@ -528,95 +528,6 @@ static void ath9k_hw_force_bias(struct ath_hw *ah, u16 synth_freq) | |||
528 | } | 528 | } |
529 | 529 | ||
530 | /** | 530 | /** |
531 | * ath9k_hw_decrease_chain_power() | ||
532 | * | ||
533 | * @ah: atheros hardware structure | ||
534 | * @chan: | ||
535 | * | ||
536 | * Only used on the AR5416 and AR5418 with the external AR2133/AR5133 radios. | ||
537 | * | ||
538 | * Sets a chain internal RF path to the lowest output power. Any | ||
539 | * further writes to bank6 after this setting will override these | ||
540 | * changes. Thus this function must be the last function in the | ||
541 | * sequence to modify bank 6. | ||
542 | * | ||
543 | * This function must be called after ar5416SetRfRegs() which is | ||
544 | * called from ath9k_hw_process_ini() due to swizzling of bank 6. | ||
545 | * Depends on ah->analogBank6Data being initialized by | ||
546 | * ath9k_hw_set_rf_regs() | ||
547 | * | ||
548 | * Additional additive reduction in power - | ||
549 | * change chain's switch table so chain's tx state is actually the rx | ||
550 | * state value. May produce different results in 2GHz/5GHz as well as | ||
551 | * board to board but in general should be a reduction. | ||
552 | * | ||
553 | * Activated by #ifdef ALTER_SWITCH. Not tried yet. If so, must be | ||
554 | * called after ah->eep_ops->set_board_values() due to RMW of | ||
555 | * PHY_SWITCH_CHAIN_0. | ||
556 | */ | ||
557 | void ath9k_hw_decrease_chain_power(struct ath_hw *ah, | ||
558 | struct ath9k_channel *chan) | ||
559 | { | ||
560 | int i, regWrites = 0; | ||
561 | u32 bank6SelMask; | ||
562 | u32 *bank6Temp = ah->bank6Temp; | ||
563 | |||
564 | BUG_ON(AR_SREV_9280_10_OR_LATER(ah)); | ||
565 | |||
566 | switch (ah->config.diversity_control) { | ||
567 | case ATH9K_ANT_FIXED_A: | ||
568 | bank6SelMask = | ||
569 | (ah->config.antenna_switch_swap & ANTSWAP_AB) ? | ||
570 | REDUCE_CHAIN_0 : /* swapped, reduce chain 0 */ | ||
571 | REDUCE_CHAIN_1; /* normal, select chain 1/2 to reduce */ | ||
572 | break; | ||
573 | case ATH9K_ANT_FIXED_B: | ||
574 | bank6SelMask = | ||
575 | (ah->config.antenna_switch_swap & ANTSWAP_AB) ? | ||
576 | REDUCE_CHAIN_1 : /* swapped, reduce chain 1/2 */ | ||
577 | REDUCE_CHAIN_0; /* normal, select chain 0 to reduce */ | ||
578 | break; | ||
579 | case ATH9K_ANT_VARIABLE: | ||
580 | return; /* do not change anything */ | ||
581 | break; | ||
582 | default: | ||
583 | return; /* do not change anything */ | ||
584 | break; | ||
585 | } | ||
586 | |||
587 | for (i = 0; i < ah->iniBank6.ia_rows; i++) | ||
588 | bank6Temp[i] = ah->analogBank6Data[i]; | ||
589 | |||
590 | /* Write Bank 5 to switch Bank 6 write to selected chain only */ | ||
591 | REG_WRITE(ah, AR_PHY_BASE + 0xD8, bank6SelMask); | ||
592 | |||
593 | /* | ||
594 | * Modify Bank6 selected chain to use lowest amplification. | ||
595 | * Modifies the parameters to a value of 1. | ||
596 | * Depends on existing bank 6 values to be cached in | ||
597 | * ah->analogBank6Data | ||
598 | */ | ||
599 | ath9k_phy_modify_rx_buffer(bank6Temp, 1, 1, 189, 0); | ||
600 | ath9k_phy_modify_rx_buffer(bank6Temp, 1, 1, 190, 0); | ||
601 | ath9k_phy_modify_rx_buffer(bank6Temp, 1, 1, 191, 0); | ||
602 | ath9k_phy_modify_rx_buffer(bank6Temp, 1, 1, 192, 0); | ||
603 | ath9k_phy_modify_rx_buffer(bank6Temp, 1, 1, 193, 0); | ||
604 | ath9k_phy_modify_rx_buffer(bank6Temp, 1, 1, 222, 0); | ||
605 | ath9k_phy_modify_rx_buffer(bank6Temp, 1, 1, 245, 0); | ||
606 | ath9k_phy_modify_rx_buffer(bank6Temp, 1, 1, 246, 0); | ||
607 | ath9k_phy_modify_rx_buffer(bank6Temp, 1, 1, 247, 0); | ||
608 | |||
609 | REG_WRITE_RF_ARRAY(&ah->iniBank6, bank6Temp, regWrites); | ||
610 | |||
611 | REG_WRITE(ah, AR_PHY_BASE + 0xD8, 0x00000053); | ||
612 | #ifdef ALTER_SWITCH | ||
613 | REG_WRITE(ah, PHY_SWITCH_CHAIN_0, | ||
614 | (REG_READ(ah, PHY_SWITCH_CHAIN_0) & ~0x38) | ||
615 | | ((REG_READ(ah, PHY_SWITCH_CHAIN_0) >> 3) & 0x38)); | ||
616 | #endif | ||
617 | } | ||
618 | |||
619 | /** | ||
620 | * ath9k_hw_set_channel - tune to a channel on the external AR2133/AR5133 radios | 531 | * ath9k_hw_set_channel - tune to a channel on the external AR2133/AR5133 radios |
621 | * @ah: atheros hardware stucture | 532 | * @ah: atheros hardware stucture |
622 | * @chan: | 533 | * @chan: |
@@ -687,7 +598,6 @@ int ath9k_hw_set_channel(struct ath_hw *ah, struct ath9k_channel *chan) | |||
687 | } | 598 | } |
688 | 599 | ||
689 | ath9k_hw_force_bias(ah, freq); | 600 | ath9k_hw_force_bias(ah, freq); |
690 | ath9k_hw_decrease_chain_power(ah, chan); | ||
691 | 601 | ||
692 | reg32 = | 602 | reg32 = |
693 | (channelSel << 8) | (aModeRefSel << 2) | (bModeSynth << 1) | | 603 | (channelSel << 8) | (aModeRefSel << 2) | (bModeSynth << 1) | |
diff --git a/drivers/net/wireless/ath/ath9k/phy.h b/drivers/net/wireless/ath/ath9k/phy.h index dc145a135dc7..31de27dc0c4a 100644 --- a/drivers/net/wireless/ath/ath9k/phy.h +++ b/drivers/net/wireless/ath/ath9k/phy.h | |||
@@ -35,9 +35,6 @@ bool ath9k_hw_set_rf_regs(struct ath_hw *ah, | |||
35 | struct ath9k_channel *chan, | 35 | struct ath9k_channel *chan, |
36 | u16 modesIndex); | 36 | u16 modesIndex); |
37 | 37 | ||
38 | void ath9k_hw_decrease_chain_power(struct ath_hw *ah, | ||
39 | struct ath9k_channel *chan); | ||
40 | |||
41 | #define AR_PHY_BASE 0x9800 | 38 | #define AR_PHY_BASE 0x9800 |
42 | #define AR_PHY(_n) (AR_PHY_BASE + ((_n)<<2)) | 39 | #define AR_PHY(_n) (AR_PHY_BASE + ((_n)<<2)) |
43 | 40 | ||
diff --git a/drivers/net/wireless/ath/ath9k/rc.c b/drivers/net/wireless/ath/ath9k/rc.c index bb72b46567f9..1d96777b4cd2 100644 --- a/drivers/net/wireless/ath/ath9k/rc.c +++ b/drivers/net/wireless/ath/ath9k/rc.c | |||
@@ -859,12 +859,12 @@ static void ath_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta, | |||
859 | static bool ath_rc_update_per(struct ath_softc *sc, | 859 | static bool ath_rc_update_per(struct ath_softc *sc, |
860 | const struct ath_rate_table *rate_table, | 860 | const struct ath_rate_table *rate_table, |
861 | struct ath_rate_priv *ath_rc_priv, | 861 | struct ath_rate_priv *ath_rc_priv, |
862 | struct ath_tx_info_priv *tx_info_priv, | 862 | struct ieee80211_tx_info *tx_info, |
863 | int tx_rate, int xretries, int retries, | 863 | int tx_rate, int xretries, int retries, |
864 | u32 now_msec) | 864 | u32 now_msec) |
865 | { | 865 | { |
866 | bool state_change = false; | 866 | bool state_change = false; |
867 | int count; | 867 | int count, n_bad_frames; |
868 | u8 last_per; | 868 | u8 last_per; |
869 | static u32 nretry_to_per_lookup[10] = { | 869 | static u32 nretry_to_per_lookup[10] = { |
870 | 100 * 0 / 1, | 870 | 100 * 0 / 1, |
@@ -880,6 +880,7 @@ static bool ath_rc_update_per(struct ath_softc *sc, | |||
880 | }; | 880 | }; |
881 | 881 | ||
882 | last_per = ath_rc_priv->per[tx_rate]; | 882 | last_per = ath_rc_priv->per[tx_rate]; |
883 | n_bad_frames = tx_info->status.ampdu_len - tx_info->status.ampdu_ack_len; | ||
883 | 884 | ||
884 | if (xretries) { | 885 | if (xretries) { |
885 | if (xretries == 1) { | 886 | if (xretries == 1) { |
@@ -907,7 +908,7 @@ static bool ath_rc_update_per(struct ath_softc *sc, | |||
907 | if (retries >= count) | 908 | if (retries >= count) |
908 | retries = count - 1; | 909 | retries = count - 1; |
909 | 910 | ||
910 | if (tx_info_priv->n_bad_frames) { | 911 | if (n_bad_frames) { |
911 | /* new_PER = 7/8*old_PER + 1/8*(currentPER) | 912 | /* new_PER = 7/8*old_PER + 1/8*(currentPER) |
912 | * Assuming that n_frames is not 0. The current PER | 913 | * Assuming that n_frames is not 0. The current PER |
913 | * from the retries is 100 * retries / (retries+1), | 914 | * from the retries is 100 * retries / (retries+1), |
@@ -920,14 +921,14 @@ static bool ath_rc_update_per(struct ath_softc *sc, | |||
920 | * the above PER. The expression below is a | 921 | * the above PER. The expression below is a |
921 | * simplified version of the sum of these two terms. | 922 | * simplified version of the sum of these two terms. |
922 | */ | 923 | */ |
923 | if (tx_info_priv->n_frames > 0) { | 924 | if (tx_info->status.ampdu_len > 0) { |
924 | int n_frames, n_bad_frames; | 925 | int n_frames, n_bad_tries; |
925 | u8 cur_per, new_per; | 926 | u8 cur_per, new_per; |
926 | 927 | ||
927 | n_bad_frames = retries * tx_info_priv->n_frames + | 928 | n_bad_tries = retries * tx_info->status.ampdu_len + |
928 | tx_info_priv->n_bad_frames; | 929 | n_bad_frames; |
929 | n_frames = tx_info_priv->n_frames * (retries + 1); | 930 | n_frames = tx_info->status.ampdu_len * (retries + 1); |
930 | cur_per = (100 * n_bad_frames / n_frames) >> 3; | 931 | cur_per = (100 * n_bad_tries / n_frames) >> 3; |
931 | new_per = (u8)(last_per - (last_per >> 3) + cur_per); | 932 | new_per = (u8)(last_per - (last_per >> 3) + cur_per); |
932 | ath_rc_priv->per[tx_rate] = new_per; | 933 | ath_rc_priv->per[tx_rate] = new_per; |
933 | } | 934 | } |
@@ -943,8 +944,7 @@ static bool ath_rc_update_per(struct ath_softc *sc, | |||
943 | * this was a probe. Otherwise, ignore the probe. | 944 | * this was a probe. Otherwise, ignore the probe. |
944 | */ | 945 | */ |
945 | if (ath_rc_priv->probe_rate && ath_rc_priv->probe_rate == tx_rate) { | 946 | if (ath_rc_priv->probe_rate && ath_rc_priv->probe_rate == tx_rate) { |
946 | if (retries > 0 || 2 * tx_info_priv->n_bad_frames > | 947 | if (retries > 0 || 2 * n_bad_frames > tx_info->status.ampdu_len) { |
947 | tx_info_priv->n_frames) { | ||
948 | /* | 948 | /* |
949 | * Since we probed with just a single attempt, | 949 | * Since we probed with just a single attempt, |
950 | * any retries means the probe failed. Also, | 950 | * any retries means the probe failed. Also, |
@@ -1003,7 +1003,7 @@ static bool ath_rc_update_per(struct ath_softc *sc, | |||
1003 | 1003 | ||
1004 | static void ath_rc_update_ht(struct ath_softc *sc, | 1004 | static void ath_rc_update_ht(struct ath_softc *sc, |
1005 | struct ath_rate_priv *ath_rc_priv, | 1005 | struct ath_rate_priv *ath_rc_priv, |
1006 | struct ath_tx_info_priv *tx_info_priv, | 1006 | struct ieee80211_tx_info *tx_info, |
1007 | int tx_rate, int xretries, int retries) | 1007 | int tx_rate, int xretries, int retries) |
1008 | { | 1008 | { |
1009 | u32 now_msec = jiffies_to_msecs(jiffies); | 1009 | u32 now_msec = jiffies_to_msecs(jiffies); |
@@ -1020,7 +1020,7 @@ static void ath_rc_update_ht(struct ath_softc *sc, | |||
1020 | 1020 | ||
1021 | /* Update PER first */ | 1021 | /* Update PER first */ |
1022 | state_change = ath_rc_update_per(sc, rate_table, ath_rc_priv, | 1022 | state_change = ath_rc_update_per(sc, rate_table, ath_rc_priv, |
1023 | tx_info_priv, tx_rate, xretries, | 1023 | tx_info, tx_rate, xretries, |
1024 | retries, now_msec); | 1024 | retries, now_msec); |
1025 | 1025 | ||
1026 | /* | 1026 | /* |
@@ -1098,7 +1098,6 @@ static void ath_rc_tx_status(struct ath_softc *sc, | |||
1098 | struct ieee80211_tx_info *tx_info, | 1098 | struct ieee80211_tx_info *tx_info, |
1099 | int final_ts_idx, int xretries, int long_retry) | 1099 | int final_ts_idx, int xretries, int long_retry) |
1100 | { | 1100 | { |
1101 | struct ath_tx_info_priv *tx_info_priv = ATH_TX_INFO_PRIV(tx_info); | ||
1102 | const struct ath_rate_table *rate_table; | 1101 | const struct ath_rate_table *rate_table; |
1103 | struct ieee80211_tx_rate *rates = tx_info->status.rates; | 1102 | struct ieee80211_tx_rate *rates = tx_info->status.rates; |
1104 | u8 flags; | 1103 | u8 flags; |
@@ -1124,9 +1123,8 @@ static void ath_rc_tx_status(struct ath_softc *sc, | |||
1124 | return; | 1123 | return; |
1125 | 1124 | ||
1126 | rix = ath_rc_get_rateindex(rate_table, &rates[i]); | 1125 | rix = ath_rc_get_rateindex(rate_table, &rates[i]); |
1127 | ath_rc_update_ht(sc, ath_rc_priv, | 1126 | ath_rc_update_ht(sc, ath_rc_priv, tx_info, |
1128 | tx_info_priv, rix, | 1127 | rix, xretries ? 1 : 2, |
1129 | xretries ? 1 : 2, | ||
1130 | rates[i].count); | 1128 | rates[i].count); |
1131 | } | 1129 | } |
1132 | } | 1130 | } |
@@ -1149,8 +1147,7 @@ static void ath_rc_tx_status(struct ath_softc *sc, | |||
1149 | return; | 1147 | return; |
1150 | 1148 | ||
1151 | rix = ath_rc_get_rateindex(rate_table, &rates[i]); | 1149 | rix = ath_rc_get_rateindex(rate_table, &rates[i]); |
1152 | ath_rc_update_ht(sc, ath_rc_priv, tx_info_priv, rix, | 1150 | ath_rc_update_ht(sc, ath_rc_priv, tx_info, rix, xretries, long_retry); |
1153 | xretries, long_retry); | ||
1154 | } | 1151 | } |
1155 | 1152 | ||
1156 | static const | 1153 | static const |
@@ -1301,23 +1298,30 @@ static void ath_tx_status(void *priv, struct ieee80211_supported_band *sband, | |||
1301 | { | 1298 | { |
1302 | struct ath_softc *sc = priv; | 1299 | struct ath_softc *sc = priv; |
1303 | struct ath_rate_priv *ath_rc_priv = priv_sta; | 1300 | struct ath_rate_priv *ath_rc_priv = priv_sta; |
1304 | struct ath_tx_info_priv *tx_info_priv = NULL; | ||
1305 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); | 1301 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); |
1306 | struct ieee80211_hdr *hdr; | 1302 | struct ieee80211_hdr *hdr; |
1307 | int final_ts_idx, tx_status = 0, is_underrun = 0; | 1303 | int final_ts_idx = 0, tx_status = 0, is_underrun = 0; |
1304 | int long_retry = 0; | ||
1308 | __le16 fc; | 1305 | __le16 fc; |
1306 | int i; | ||
1309 | 1307 | ||
1310 | hdr = (struct ieee80211_hdr *)skb->data; | 1308 | hdr = (struct ieee80211_hdr *)skb->data; |
1311 | fc = hdr->frame_control; | 1309 | fc = hdr->frame_control; |
1312 | tx_info_priv = ATH_TX_INFO_PRIV(tx_info); | 1310 | for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) { |
1313 | final_ts_idx = tx_info_priv->tx.ts_rateindex; | 1311 | struct ieee80211_tx_rate *rate = &tx_info->status.rates[i]; |
1312 | if (!rate->count) | ||
1313 | break; | ||
1314 | |||
1315 | final_ts_idx = i; | ||
1316 | long_retry = rate->count - 1; | ||
1317 | } | ||
1314 | 1318 | ||
1315 | if (!priv_sta || !ieee80211_is_data(fc) || | 1319 | if (!priv_sta || !ieee80211_is_data(fc) || |
1316 | !tx_info_priv->update_rc) | 1320 | !(tx_info->pad[0] & ATH_TX_INFO_UPDATE_RC)) |
1317 | goto exit; | 1321 | return; |
1318 | 1322 | ||
1319 | if (tx_info_priv->tx.ts_status & ATH9K_TXERR_FILT) | 1323 | if (tx_info->flags & IEEE80211_TX_STAT_TX_FILTERED) |
1320 | goto exit; | 1324 | return; |
1321 | 1325 | ||
1322 | /* | 1326 | /* |
1323 | * If underrun error is seen assume it as an excessive retry only | 1327 | * If underrun error is seen assume it as an excessive retry only |
@@ -1325,20 +1329,17 @@ static void ath_tx_status(void *priv, struct ieee80211_supported_band *sband, | |||
1325 | * Adjust the long retry as if the frame was tried hw->max_rate_tries | 1329 | * Adjust the long retry as if the frame was tried hw->max_rate_tries |
1326 | * times. This affects how ratectrl updates PER for the failed rate. | 1330 | * times. This affects how ratectrl updates PER for the failed rate. |
1327 | */ | 1331 | */ |
1328 | if (tx_info_priv->tx.ts_flags & | 1332 | if ((tx_info->pad[0] & ATH_TX_INFO_UNDERRUN) && |
1329 | (ATH9K_TX_DATA_UNDERRUN | ATH9K_TX_DELIM_UNDERRUN) && | 1333 | (sc->sc_ah->tx_trig_level >= ath_rc_priv->tx_triglevel_max)) { |
1330 | ((sc->sc_ah->tx_trig_level) >= ath_rc_priv->tx_triglevel_max)) { | ||
1331 | tx_status = 1; | 1334 | tx_status = 1; |
1332 | is_underrun = 1; | 1335 | is_underrun = 1; |
1333 | } | 1336 | } |
1334 | 1337 | ||
1335 | if ((tx_info_priv->tx.ts_status & ATH9K_TXERR_XRETRY) || | 1338 | if (tx_info->pad[0] & ATH_TX_INFO_XRETRY) |
1336 | (tx_info_priv->tx.ts_status & ATH9K_TXERR_FIFO)) | ||
1337 | tx_status = 1; | 1339 | tx_status = 1; |
1338 | 1340 | ||
1339 | ath_rc_tx_status(sc, ath_rc_priv, tx_info, final_ts_idx, tx_status, | 1341 | ath_rc_tx_status(sc, ath_rc_priv, tx_info, final_ts_idx, tx_status, |
1340 | (is_underrun) ? sc->hw->max_rate_tries : | 1342 | (is_underrun) ? sc->hw->max_rate_tries : long_retry); |
1341 | tx_info_priv->tx.ts_longretry); | ||
1342 | 1343 | ||
1343 | /* Check if aggregation has to be enabled for this tid */ | 1344 | /* Check if aggregation has to be enabled for this tid */ |
1344 | if (conf_is_ht(&sc->hw->conf) && | 1345 | if (conf_is_ht(&sc->hw->conf) && |
@@ -1352,13 +1353,11 @@ static void ath_tx_status(void *priv, struct ieee80211_supported_band *sband, | |||
1352 | an = (struct ath_node *)sta->drv_priv; | 1353 | an = (struct ath_node *)sta->drv_priv; |
1353 | 1354 | ||
1354 | if(ath_tx_aggr_check(sc, an, tid)) | 1355 | if(ath_tx_aggr_check(sc, an, tid)) |
1355 | ieee80211_start_tx_ba_session(sc->hw, hdr->addr1, tid); | 1356 | ieee80211_start_tx_ba_session(sta, tid); |
1356 | } | 1357 | } |
1357 | } | 1358 | } |
1358 | 1359 | ||
1359 | ath_debug_stat_rc(sc, skb); | 1360 | ath_debug_stat_rc(sc, skb); |
1360 | exit: | ||
1361 | kfree(tx_info_priv); | ||
1362 | } | 1361 | } |
1363 | 1362 | ||
1364 | static void ath_rate_init(void *priv, struct ieee80211_supported_band *sband, | 1363 | static void ath_rate_init(void *priv, struct ieee80211_supported_band *sband, |
diff --git a/drivers/net/wireless/ath/ath9k/rc.h b/drivers/net/wireless/ath/ath9k/rc.h index 94cb9f8d2446..51f85ecbe88d 100644 --- a/drivers/net/wireless/ath/ath9k/rc.h +++ b/drivers/net/wireless/ath/ath9k/rc.h | |||
@@ -167,24 +167,18 @@ struct ath_rate_priv { | |||
167 | struct ath_rate_softc *asc; | 167 | struct ath_rate_softc *asc; |
168 | }; | 168 | }; |
169 | 169 | ||
170 | #define ATH_TX_INFO_FRAME_TYPE_INTERNAL (1 << 0) | ||
171 | #define ATH_TX_INFO_FRAME_TYPE_PAUSE (1 << 1) | ||
172 | #define ATH_TX_INFO_UPDATE_RC (1 << 2) | ||
173 | #define ATH_TX_INFO_XRETRY (1 << 3) | ||
174 | #define ATH_TX_INFO_UNDERRUN (1 << 4) | ||
175 | |||
170 | enum ath9k_internal_frame_type { | 176 | enum ath9k_internal_frame_type { |
171 | ATH9K_NOT_INTERNAL, | 177 | ATH9K_NOT_INTERNAL, |
172 | ATH9K_INT_PAUSE, | 178 | ATH9K_INT_PAUSE, |
173 | ATH9K_INT_UNPAUSE | 179 | ATH9K_INT_UNPAUSE |
174 | }; | 180 | }; |
175 | 181 | ||
176 | struct ath_tx_info_priv { | ||
177 | struct ath_wiphy *aphy; | ||
178 | struct ath_tx_status tx; | ||
179 | int n_frames; | ||
180 | int n_bad_frames; | ||
181 | bool update_rc; | ||
182 | enum ath9k_internal_frame_type frame_type; | ||
183 | }; | ||
184 | |||
185 | #define ATH_TX_INFO_PRIV(tx_info) \ | ||
186 | ((struct ath_tx_info_priv *)((tx_info)->rate_driver_data[0])) | ||
187 | |||
188 | void ath_rate_attach(struct ath_softc *sc); | 182 | void ath_rate_attach(struct ath_softc *sc); |
189 | u8 ath_rate_findrateix(struct ath_softc *sc, u8 dot11_rate); | 183 | u8 ath_rate_findrateix(struct ath_softc *sc, u8 dot11_rate); |
190 | int ath_rate_control_register(void); | 184 | int ath_rate_control_register(void); |
diff --git a/drivers/net/wireless/ath/ath9k/virtual.c b/drivers/net/wireless/ath/ath9k/virtual.c index 0a36b572294c..cd26caaf44e7 100644 --- a/drivers/net/wireless/ath/ath9k/virtual.c +++ b/drivers/net/wireless/ath/ath9k/virtual.c | |||
@@ -338,13 +338,11 @@ void ath9k_wiphy_chan_work(struct work_struct *work) | |||
338 | void ath9k_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb) | 338 | void ath9k_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb) |
339 | { | 339 | { |
340 | struct ath_wiphy *aphy = hw->priv; | 340 | struct ath_wiphy *aphy = hw->priv; |
341 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | ||
342 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); | 341 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); |
343 | struct ath_tx_info_priv *tx_info_priv = ATH_TX_INFO_PRIV(tx_info); | ||
344 | 342 | ||
345 | if (tx_info_priv && tx_info_priv->frame_type == ATH9K_INT_PAUSE && | 343 | if ((tx_info->pad[0] & ATH_TX_INFO_FRAME_TYPE_PAUSE) && |
346 | aphy->state == ATH_WIPHY_PAUSING) { | 344 | aphy->state == ATH_WIPHY_PAUSING) { |
347 | if (!(info->flags & IEEE80211_TX_STAT_ACK)) { | 345 | if (!(tx_info->flags & IEEE80211_TX_STAT_ACK)) { |
348 | printk(KERN_DEBUG "ath9k: %s: no ACK for pause " | 346 | printk(KERN_DEBUG "ath9k: %s: no ACK for pause " |
349 | "frame\n", wiphy_name(hw->wiphy)); | 347 | "frame\n", wiphy_name(hw->wiphy)); |
350 | /* | 348 | /* |
@@ -363,9 +361,6 @@ void ath9k_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
363 | } | 361 | } |
364 | } | 362 | } |
365 | 363 | ||
366 | kfree(tx_info_priv); | ||
367 | tx_info->rate_driver_data[0] = NULL; | ||
368 | |||
369 | dev_kfree_skb(skb); | 364 | dev_kfree_skb(skb); |
370 | } | 365 | } |
371 | 366 | ||
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index 86b54ddd01cb..745d91995d78 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c | |||
@@ -251,6 +251,7 @@ static struct ath_buf* ath_clone_txbuf(struct ath_softc *sc, struct ath_buf *bf) | |||
251 | 251 | ||
252 | ATH_TXBUF_RESET(tbf); | 252 | ATH_TXBUF_RESET(tbf); |
253 | 253 | ||
254 | tbf->aphy = bf->aphy; | ||
254 | tbf->bf_mpdu = bf->bf_mpdu; | 255 | tbf->bf_mpdu = bf->bf_mpdu; |
255 | tbf->bf_buf_addr = bf->bf_buf_addr; | 256 | tbf->bf_buf_addr = bf->bf_buf_addr; |
256 | *(tbf->bf_desc) = *(bf->bf_desc); | 257 | *(tbf->bf_desc) = *(bf->bf_desc); |
@@ -270,7 +271,6 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, | |||
270 | struct ieee80211_hw *hw; | 271 | struct ieee80211_hw *hw; |
271 | struct ieee80211_hdr *hdr; | 272 | struct ieee80211_hdr *hdr; |
272 | struct ieee80211_tx_info *tx_info; | 273 | struct ieee80211_tx_info *tx_info; |
273 | struct ath_tx_info_priv *tx_info_priv; | ||
274 | struct ath_atx_tid *tid = NULL; | 274 | struct ath_atx_tid *tid = NULL; |
275 | struct ath_buf *bf_next, *bf_last = bf->bf_lastbf; | 275 | struct ath_buf *bf_next, *bf_last = bf->bf_lastbf; |
276 | struct ath_desc *ds = bf_last->bf_desc; | 276 | struct ath_desc *ds = bf_last->bf_desc; |
@@ -284,8 +284,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, | |||
284 | hdr = (struct ieee80211_hdr *)skb->data; | 284 | hdr = (struct ieee80211_hdr *)skb->data; |
285 | 285 | ||
286 | tx_info = IEEE80211_SKB_CB(skb); | 286 | tx_info = IEEE80211_SKB_CB(skb); |
287 | tx_info_priv = (struct ath_tx_info_priv *) tx_info->rate_driver_data[0]; | 287 | hw = bf->aphy->hw; |
288 | hw = tx_info_priv->aphy->hw; | ||
289 | 288 | ||
290 | rcu_read_lock(); | 289 | rcu_read_lock(); |
291 | 290 | ||
@@ -464,7 +463,6 @@ static u32 ath_lookup_rate(struct ath_softc *sc, struct ath_buf *bf, | |||
464 | struct sk_buff *skb; | 463 | struct sk_buff *skb; |
465 | struct ieee80211_tx_info *tx_info; | 464 | struct ieee80211_tx_info *tx_info; |
466 | struct ieee80211_tx_rate *rates; | 465 | struct ieee80211_tx_rate *rates; |
467 | struct ath_tx_info_priv *tx_info_priv; | ||
468 | u32 max_4ms_framelen, frmlen; | 466 | u32 max_4ms_framelen, frmlen; |
469 | u16 aggr_limit, legacy = 0; | 467 | u16 aggr_limit, legacy = 0; |
470 | int i; | 468 | int i; |
@@ -472,7 +470,6 @@ static u32 ath_lookup_rate(struct ath_softc *sc, struct ath_buf *bf, | |||
472 | skb = bf->bf_mpdu; | 470 | skb = bf->bf_mpdu; |
473 | tx_info = IEEE80211_SKB_CB(skb); | 471 | tx_info = IEEE80211_SKB_CB(skb); |
474 | rates = tx_info->control.rates; | 472 | rates = tx_info->control.rates; |
475 | tx_info_priv = (struct ath_tx_info_priv *)tx_info->rate_driver_data[0]; | ||
476 | 473 | ||
477 | /* | 474 | /* |
478 | * Find the lowest frame length among the rate series that will have a | 475 | * Find the lowest frame length among the rate series that will have a |
@@ -702,7 +699,6 @@ static void ath_tx_sched_aggr(struct ath_softc *sc, struct ath_txq *txq, | |||
702 | /* anchor last desc of aggregate */ | 699 | /* anchor last desc of aggregate */ |
703 | ath9k_hw_set11n_aggr_last(sc->sc_ah, bf->bf_lastbf->bf_desc); | 700 | ath9k_hw_set11n_aggr_last(sc->sc_ah, bf->bf_lastbf->bf_desc); |
704 | 701 | ||
705 | txq->axq_aggr_depth++; | ||
706 | ath_tx_txqaddbuf(sc, txq, &bf_q); | 702 | ath_tx_txqaddbuf(sc, txq, &bf_q); |
707 | TX_STAT_INC(txq->axq_qnum, a_aggr); | 703 | TX_STAT_INC(txq->axq_qnum, a_aggr); |
708 | 704 | ||
@@ -878,8 +874,6 @@ struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype) | |||
878 | INIT_LIST_HEAD(&txq->axq_acq); | 874 | INIT_LIST_HEAD(&txq->axq_acq); |
879 | spin_lock_init(&txq->axq_lock); | 875 | spin_lock_init(&txq->axq_lock); |
880 | txq->axq_depth = 0; | 876 | txq->axq_depth = 0; |
881 | txq->axq_aggr_depth = 0; | ||
882 | txq->axq_linkbuf = NULL; | ||
883 | txq->axq_tx_inprogress = false; | 877 | txq->axq_tx_inprogress = false; |
884 | sc->tx.txqsetup |= 1<<qnum; | 878 | sc->tx.txqsetup |= 1<<qnum; |
885 | } | 879 | } |
@@ -1014,7 +1008,6 @@ void ath_draintxq(struct ath_softc *sc, struct ath_txq *txq, bool retry_tx) | |||
1014 | 1008 | ||
1015 | if (list_empty(&txq->axq_q)) { | 1009 | if (list_empty(&txq->axq_q)) { |
1016 | txq->axq_link = NULL; | 1010 | txq->axq_link = NULL; |
1017 | txq->axq_linkbuf = NULL; | ||
1018 | spin_unlock_bh(&txq->axq_lock); | 1011 | spin_unlock_bh(&txq->axq_lock); |
1019 | break; | 1012 | break; |
1020 | } | 1013 | } |
@@ -1199,7 +1192,6 @@ static void ath_tx_txqaddbuf(struct ath_softc *sc, struct ath_txq *txq, | |||
1199 | 1192 | ||
1200 | list_splice_tail_init(head, &txq->axq_q); | 1193 | list_splice_tail_init(head, &txq->axq_q); |
1201 | txq->axq_depth++; | 1194 | txq->axq_depth++; |
1202 | txq->axq_linkbuf = list_entry(txq->axq_q.prev, struct ath_buf, list); | ||
1203 | 1195 | ||
1204 | ath_print(common, ATH_DBG_QUEUE, | 1196 | ath_print(common, ATH_DBG_QUEUE, |
1205 | "qnum: %d, txq depth: %d\n", txq->axq_qnum, txq->axq_depth); | 1197 | "qnum: %d, txq depth: %d\n", txq->axq_qnum, txq->axq_depth); |
@@ -1560,21 +1552,26 @@ static int ath_tx_setup_buffer(struct ieee80211_hw *hw, struct ath_buf *bf, | |||
1560 | struct ath_softc *sc = aphy->sc; | 1552 | struct ath_softc *sc = aphy->sc; |
1561 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); | 1553 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); |
1562 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; | 1554 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; |
1563 | struct ath_tx_info_priv *tx_info_priv; | ||
1564 | int hdrlen; | 1555 | int hdrlen; |
1565 | __le16 fc; | 1556 | __le16 fc; |
1566 | 1557 | ||
1567 | tx_info_priv = kzalloc(sizeof(*tx_info_priv), GFP_ATOMIC); | 1558 | tx_info->pad[0] = 0; |
1568 | if (unlikely(!tx_info_priv)) | 1559 | switch (txctl->frame_type) { |
1569 | return -ENOMEM; | 1560 | case ATH9K_NOT_INTERNAL: |
1570 | tx_info->rate_driver_data[0] = tx_info_priv; | 1561 | break; |
1571 | tx_info_priv->aphy = aphy; | 1562 | case ATH9K_INT_PAUSE: |
1572 | tx_info_priv->frame_type = txctl->frame_type; | 1563 | tx_info->pad[0] |= ATH_TX_INFO_FRAME_TYPE_PAUSE; |
1564 | /* fall through */ | ||
1565 | case ATH9K_INT_UNPAUSE: | ||
1566 | tx_info->pad[0] |= ATH_TX_INFO_FRAME_TYPE_INTERNAL; | ||
1567 | break; | ||
1568 | } | ||
1573 | hdrlen = ieee80211_get_hdrlen_from_skb(skb); | 1569 | hdrlen = ieee80211_get_hdrlen_from_skb(skb); |
1574 | fc = hdr->frame_control; | 1570 | fc = hdr->frame_control; |
1575 | 1571 | ||
1576 | ATH_TXBUF_RESET(bf); | 1572 | ATH_TXBUF_RESET(bf); |
1577 | 1573 | ||
1574 | bf->aphy = aphy; | ||
1578 | bf->bf_frmlen = skb->len + FCS_LEN - (hdrlen & 3); | 1575 | bf->bf_frmlen = skb->len + FCS_LEN - (hdrlen & 3); |
1579 | 1576 | ||
1580 | if (conf_is_ht(&hw->conf) && !is_pae(skb)) | 1577 | if (conf_is_ht(&hw->conf) && !is_pae(skb)) |
@@ -1599,8 +1596,6 @@ static int ath_tx_setup_buffer(struct ieee80211_hw *hw, struct ath_buf *bf, | |||
1599 | skb->len, DMA_TO_DEVICE); | 1596 | skb->len, DMA_TO_DEVICE); |
1600 | if (unlikely(dma_mapping_error(sc->dev, bf->bf_dmacontext))) { | 1597 | if (unlikely(dma_mapping_error(sc->dev, bf->bf_dmacontext))) { |
1601 | bf->bf_mpdu = NULL; | 1598 | bf->bf_mpdu = NULL; |
1602 | kfree(tx_info_priv); | ||
1603 | tx_info->rate_driver_data[0] = NULL; | ||
1604 | ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_FATAL, | 1599 | ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_FATAL, |
1605 | "dma_mapping_error() on TX\n"); | 1600 | "dma_mapping_error() on TX\n"); |
1606 | return -ENOMEM; | 1601 | return -ENOMEM; |
@@ -1781,27 +1776,17 @@ exit: | |||
1781 | /*****************/ | 1776 | /*****************/ |
1782 | 1777 | ||
1783 | static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb, | 1778 | static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb, |
1784 | int tx_flags) | 1779 | struct ath_wiphy *aphy, int tx_flags) |
1785 | { | 1780 | { |
1786 | struct ieee80211_hw *hw = sc->hw; | 1781 | struct ieee80211_hw *hw = sc->hw; |
1787 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); | 1782 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); |
1788 | struct ath_tx_info_priv *tx_info_priv = ATH_TX_INFO_PRIV(tx_info); | ||
1789 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | 1783 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); |
1790 | int hdrlen, padsize; | 1784 | int hdrlen, padsize; |
1791 | int frame_type = ATH9K_NOT_INTERNAL; | ||
1792 | 1785 | ||
1793 | ath_print(common, ATH_DBG_XMIT, "TX complete: skb: %p\n", skb); | 1786 | ath_print(common, ATH_DBG_XMIT, "TX complete: skb: %p\n", skb); |
1794 | 1787 | ||
1795 | if (tx_info_priv) { | 1788 | if (aphy) |
1796 | hw = tx_info_priv->aphy->hw; | 1789 | hw = aphy->hw; |
1797 | frame_type = tx_info_priv->frame_type; | ||
1798 | } | ||
1799 | |||
1800 | if (tx_info->flags & IEEE80211_TX_CTL_NO_ACK || | ||
1801 | tx_info->flags & IEEE80211_TX_STAT_TX_FILTERED) { | ||
1802 | kfree(tx_info_priv); | ||
1803 | tx_info->rate_driver_data[0] = NULL; | ||
1804 | } | ||
1805 | 1790 | ||
1806 | if (tx_flags & ATH_TX_BAR) | 1791 | if (tx_flags & ATH_TX_BAR) |
1807 | tx_info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK; | 1792 | tx_info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK; |
@@ -1833,10 +1818,10 @@ static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb, | |||
1833 | SC_OP_WAIT_FOR_TX_ACK)); | 1818 | SC_OP_WAIT_FOR_TX_ACK)); |
1834 | } | 1819 | } |
1835 | 1820 | ||
1836 | if (frame_type == ATH9K_NOT_INTERNAL) | 1821 | if (unlikely(tx_info->pad[0] & ATH_TX_INFO_FRAME_TYPE_INTERNAL)) |
1837 | ieee80211_tx_status(hw, skb); | ||
1838 | else | ||
1839 | ath9k_tx_status(hw, skb); | 1822 | ath9k_tx_status(hw, skb); |
1823 | else | ||
1824 | ieee80211_tx_status(hw, skb); | ||
1840 | } | 1825 | } |
1841 | 1826 | ||
1842 | static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf, | 1827 | static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf, |
@@ -1859,7 +1844,7 @@ static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf, | |||
1859 | } | 1844 | } |
1860 | 1845 | ||
1861 | dma_unmap_single(sc->dev, bf->bf_dmacontext, skb->len, DMA_TO_DEVICE); | 1846 | dma_unmap_single(sc->dev, bf->bf_dmacontext, skb->len, DMA_TO_DEVICE); |
1862 | ath_tx_complete(sc, skb, tx_flags); | 1847 | ath_tx_complete(sc, skb, bf->aphy, tx_flags); |
1863 | ath_debug_stat_tx(sc, txq, bf); | 1848 | ath_debug_stat_tx(sc, txq, bf); |
1864 | 1849 | ||
1865 | /* | 1850 | /* |
@@ -1907,8 +1892,7 @@ static void ath_tx_rc_status(struct ath_buf *bf, struct ath_desc *ds, | |||
1907 | struct sk_buff *skb = bf->bf_mpdu; | 1892 | struct sk_buff *skb = bf->bf_mpdu; |
1908 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; | 1893 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; |
1909 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); | 1894 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); |
1910 | struct ath_tx_info_priv *tx_info_priv = ATH_TX_INFO_PRIV(tx_info); | 1895 | struct ieee80211_hw *hw = bf->aphy->hw; |
1911 | struct ieee80211_hw *hw = tx_info_priv->aphy->hw; | ||
1912 | u8 i, tx_rateindex; | 1896 | u8 i, tx_rateindex; |
1913 | 1897 | ||
1914 | if (txok) | 1898 | if (txok) |
@@ -1917,17 +1901,22 @@ static void ath_tx_rc_status(struct ath_buf *bf, struct ath_desc *ds, | |||
1917 | tx_rateindex = ds->ds_txstat.ts_rateindex; | 1901 | tx_rateindex = ds->ds_txstat.ts_rateindex; |
1918 | WARN_ON(tx_rateindex >= hw->max_rates); | 1902 | WARN_ON(tx_rateindex >= hw->max_rates); |
1919 | 1903 | ||
1920 | tx_info_priv->update_rc = update_rc; | 1904 | if (update_rc) |
1905 | tx_info->pad[0] |= ATH_TX_INFO_UPDATE_RC; | ||
1921 | if (ds->ds_txstat.ts_status & ATH9K_TXERR_FILT) | 1906 | if (ds->ds_txstat.ts_status & ATH9K_TXERR_FILT) |
1922 | tx_info->flags |= IEEE80211_TX_STAT_TX_FILTERED; | 1907 | tx_info->flags |= IEEE80211_TX_STAT_TX_FILTERED; |
1923 | 1908 | ||
1924 | if ((ds->ds_txstat.ts_status & ATH9K_TXERR_FILT) == 0 && | 1909 | if ((ds->ds_txstat.ts_status & ATH9K_TXERR_FILT) == 0 && |
1925 | (bf->bf_flags & ATH9K_TXDESC_NOACK) == 0 && update_rc) { | 1910 | (bf->bf_flags & ATH9K_TXDESC_NOACK) == 0 && update_rc) { |
1926 | if (ieee80211_is_data(hdr->frame_control)) { | 1911 | if (ieee80211_is_data(hdr->frame_control)) { |
1927 | memcpy(&tx_info_priv->tx, &ds->ds_txstat, | 1912 | if (ds->ds_txstat.ts_flags & |
1928 | sizeof(tx_info_priv->tx)); | 1913 | (ATH9K_TX_DATA_UNDERRUN | ATH9K_TX_DELIM_UNDERRUN)) |
1929 | tx_info_priv->n_frames = bf->bf_nframes; | 1914 | tx_info->pad[0] |= ATH_TX_INFO_UNDERRUN; |
1930 | tx_info_priv->n_bad_frames = nbad; | 1915 | if ((ds->ds_txstat.ts_status & ATH9K_TXERR_XRETRY) || |
1916 | (ds->ds_txstat.ts_status & ATH9K_TXERR_FIFO)) | ||
1917 | tx_info->pad[0] |= ATH_TX_INFO_XRETRY; | ||
1918 | tx_info->status.ampdu_len = bf->bf_nframes; | ||
1919 | tx_info->status.ampdu_ack_len = bf->bf_nframes - nbad; | ||
1931 | } | 1920 | } |
1932 | } | 1921 | } |
1933 | 1922 | ||
@@ -1971,7 +1960,6 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq) | |||
1971 | spin_lock_bh(&txq->axq_lock); | 1960 | spin_lock_bh(&txq->axq_lock); |
1972 | if (list_empty(&txq->axq_q)) { | 1961 | if (list_empty(&txq->axq_q)) { |
1973 | txq->axq_link = NULL; | 1962 | txq->axq_link = NULL; |
1974 | txq->axq_linkbuf = NULL; | ||
1975 | spin_unlock_bh(&txq->axq_lock); | 1963 | spin_unlock_bh(&txq->axq_lock); |
1976 | break; | 1964 | break; |
1977 | } | 1965 | } |
@@ -2005,10 +1993,6 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq) | |||
2005 | spin_unlock_bh(&txq->axq_lock); | 1993 | spin_unlock_bh(&txq->axq_lock); |
2006 | break; | 1994 | break; |
2007 | } | 1995 | } |
2008 | if (bf->bf_desc == txq->axq_lastdsWithCTS) | ||
2009 | txq->axq_lastdsWithCTS = NULL; | ||
2010 | if (ds == txq->axq_gatingds) | ||
2011 | txq->axq_gatingds = NULL; | ||
2012 | 1996 | ||
2013 | /* | 1997 | /* |
2014 | * Remove ath_buf's of the same transmit unit from txq, | 1998 | * Remove ath_buf's of the same transmit unit from txq, |
@@ -2022,9 +2006,6 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq) | |||
2022 | &txq->axq_q, lastbf->list.prev); | 2006 | &txq->axq_q, lastbf->list.prev); |
2023 | 2007 | ||
2024 | txq->axq_depth--; | 2008 | txq->axq_depth--; |
2025 | if (bf_isaggr(bf)) | ||
2026 | txq->axq_aggr_depth--; | ||
2027 | |||
2028 | txok = (ds->ds_txstat.ts_status == 0); | 2009 | txok = (ds->ds_txstat.ts_status == 0); |
2029 | txq->axq_tx_inprogress = false; | 2010 | txq->axq_tx_inprogress = false; |
2030 | spin_unlock_bh(&txq->axq_lock); | 2011 | spin_unlock_bh(&txq->axq_lock); |