diff options
Diffstat (limited to 'net/mac80211')
-rw-r--r-- | net/mac80211/ieee80211_i.h | 8 | ||||
-rw-r--r-- | net/mac80211/main.c | 54 | ||||
-rw-r--r-- | net/mac80211/mesh_hwmp.c | 6 | ||||
-rw-r--r-- | net/mac80211/rate.c | 52 | ||||
-rw-r--r-- | net/mac80211/rate.h | 5 | ||||
-rw-r--r-- | net/mac80211/rc80211_minstrel.c | 72 | ||||
-rw-r--r-- | net/mac80211/rc80211_pid.h | 1 | ||||
-rw-r--r-- | net/mac80211/rc80211_pid_algo.c | 27 | ||||
-rw-r--r-- | net/mac80211/rc80211_pid_debugfs.c | 5 | ||||
-rw-r--r-- | net/mac80211/sta_info.h | 4 | ||||
-rw-r--r-- | net/mac80211/tx.c | 378 | ||||
-rw-r--r-- | net/mac80211/wext.c | 4 |
12 files changed, 306 insertions, 310 deletions
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 6f8756d26a93..fe4efdd4253d 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h | |||
@@ -142,7 +142,6 @@ typedef unsigned __bitwise__ ieee80211_tx_result; | |||
142 | #define IEEE80211_TX_FRAGMENTED BIT(0) | 142 | #define IEEE80211_TX_FRAGMENTED BIT(0) |
143 | #define IEEE80211_TX_UNICAST BIT(1) | 143 | #define IEEE80211_TX_UNICAST BIT(1) |
144 | #define IEEE80211_TX_PS_BUFFERED BIT(2) | 144 | #define IEEE80211_TX_PS_BUFFERED BIT(2) |
145 | #define IEEE80211_TX_PROBE_LAST_FRAG BIT(3) | ||
146 | 145 | ||
147 | struct ieee80211_tx_data { | 146 | struct ieee80211_tx_data { |
148 | struct sk_buff *skb; | 147 | struct sk_buff *skb; |
@@ -153,11 +152,6 @@ struct ieee80211_tx_data { | |||
153 | struct ieee80211_key *key; | 152 | struct ieee80211_key *key; |
154 | 153 | ||
155 | struct ieee80211_channel *channel; | 154 | struct ieee80211_channel *channel; |
156 | s8 rate_idx; | ||
157 | /* use this rate (if set) for last fragment; rate can | ||
158 | * be set to lower rate for the first fragments, e.g., | ||
159 | * when using CTS protection with IEEE 802.11g. */ | ||
160 | s8 last_frag_rate_idx; | ||
161 | 155 | ||
162 | /* Extra fragments (in addition to the first fragment | 156 | /* Extra fragments (in addition to the first fragment |
163 | * in skb) */ | 157 | * in skb) */ |
@@ -203,9 +197,7 @@ struct ieee80211_rx_data { | |||
203 | struct ieee80211_tx_stored_packet { | 197 | struct ieee80211_tx_stored_packet { |
204 | struct sk_buff *skb; | 198 | struct sk_buff *skb; |
205 | struct sk_buff **extra_frag; | 199 | struct sk_buff **extra_frag; |
206 | s8 last_frag_rate_idx; | ||
207 | int num_extra_frag; | 200 | int num_extra_frag; |
208 | bool last_frag_rate_ctrl_probe; | ||
209 | }; | 201 | }; |
210 | 202 | ||
211 | struct beacon_data { | 203 | struct beacon_data { |
diff --git a/net/mac80211/main.c b/net/mac80211/main.c index ffff54944f9d..88c1975a97a5 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c | |||
@@ -41,6 +41,8 @@ | |||
41 | */ | 41 | */ |
42 | struct ieee80211_tx_status_rtap_hdr { | 42 | struct ieee80211_tx_status_rtap_hdr { |
43 | struct ieee80211_radiotap_header hdr; | 43 | struct ieee80211_radiotap_header hdr; |
44 | u8 rate; | ||
45 | u8 padding_for_rate; | ||
44 | __le16 tx_flags; | 46 | __le16 tx_flags; |
45 | u8 data_retries; | 47 | u8 data_retries; |
46 | } __attribute__ ((packed)); | 48 | } __attribute__ ((packed)); |
@@ -465,13 +467,28 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
465 | struct ieee80211_sub_if_data *sdata; | 467 | struct ieee80211_sub_if_data *sdata; |
466 | struct net_device *prev_dev = NULL; | 468 | struct net_device *prev_dev = NULL; |
467 | struct sta_info *sta; | 469 | struct sta_info *sta; |
470 | int retry_count = -1, i; | ||
471 | |||
472 | for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) { | ||
473 | /* the HW cannot have attempted that rate */ | ||
474 | if (i >= hw->max_rates) { | ||
475 | info->status.rates[i].idx = -1; | ||
476 | info->status.rates[i].count = 0; | ||
477 | } | ||
478 | |||
479 | retry_count += info->status.rates[i].count; | ||
480 | } | ||
481 | if (retry_count < 0) | ||
482 | retry_count = 0; | ||
468 | 483 | ||
469 | rcu_read_lock(); | 484 | rcu_read_lock(); |
470 | 485 | ||
486 | sband = local->hw.wiphy->bands[info->band]; | ||
487 | |||
471 | sta = sta_info_get(local, hdr->addr1); | 488 | sta = sta_info_get(local, hdr->addr1); |
472 | 489 | ||
473 | if (sta) { | 490 | if (sta) { |
474 | if (info->status.excessive_retries && | 491 | if (!(info->flags & IEEE80211_TX_STAT_ACK) && |
475 | test_sta_flags(sta, WLAN_STA_PS)) { | 492 | test_sta_flags(sta, WLAN_STA_PS)) { |
476 | /* | 493 | /* |
477 | * The STA is in power save mode, so assume | 494 | * The STA is in power save mode, so assume |
@@ -502,12 +519,11 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
502 | rcu_read_unlock(); | 519 | rcu_read_unlock(); |
503 | return; | 520 | return; |
504 | } else { | 521 | } else { |
505 | if (info->status.excessive_retries) | 522 | if (!(info->flags & IEEE80211_TX_STAT_ACK)) |
506 | sta->tx_retry_failed++; | 523 | sta->tx_retry_failed++; |
507 | sta->tx_retry_count += info->status.retry_count; | 524 | sta->tx_retry_count += retry_count; |
508 | } | 525 | } |
509 | 526 | ||
510 | sband = local->hw.wiphy->bands[info->band]; | ||
511 | rate_control_tx_status(local, sband, sta, skb); | 527 | rate_control_tx_status(local, sband, sta, skb); |
512 | } | 528 | } |
513 | 529 | ||
@@ -528,9 +544,9 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
528 | local->dot11TransmittedFrameCount++; | 544 | local->dot11TransmittedFrameCount++; |
529 | if (is_multicast_ether_addr(hdr->addr1)) | 545 | if (is_multicast_ether_addr(hdr->addr1)) |
530 | local->dot11MulticastTransmittedFrameCount++; | 546 | local->dot11MulticastTransmittedFrameCount++; |
531 | if (info->status.retry_count > 0) | 547 | if (retry_count > 0) |
532 | local->dot11RetryCount++; | 548 | local->dot11RetryCount++; |
533 | if (info->status.retry_count > 1) | 549 | if (retry_count > 1) |
534 | local->dot11MultipleRetryCount++; | 550 | local->dot11MultipleRetryCount++; |
535 | } | 551 | } |
536 | 552 | ||
@@ -574,19 +590,30 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
574 | rthdr->hdr.it_len = cpu_to_le16(sizeof(*rthdr)); | 590 | rthdr->hdr.it_len = cpu_to_le16(sizeof(*rthdr)); |
575 | rthdr->hdr.it_present = | 591 | rthdr->hdr.it_present = |
576 | cpu_to_le32((1 << IEEE80211_RADIOTAP_TX_FLAGS) | | 592 | cpu_to_le32((1 << IEEE80211_RADIOTAP_TX_FLAGS) | |
577 | (1 << IEEE80211_RADIOTAP_DATA_RETRIES)); | 593 | (1 << IEEE80211_RADIOTAP_DATA_RETRIES) | |
594 | (1 << IEEE80211_RADIOTAP_RATE)); | ||
578 | 595 | ||
579 | if (!(info->flags & IEEE80211_TX_STAT_ACK) && | 596 | if (!(info->flags & IEEE80211_TX_STAT_ACK) && |
580 | !is_multicast_ether_addr(hdr->addr1)) | 597 | !is_multicast_ether_addr(hdr->addr1)) |
581 | rthdr->tx_flags |= cpu_to_le16(IEEE80211_RADIOTAP_F_TX_FAIL); | 598 | rthdr->tx_flags |= cpu_to_le16(IEEE80211_RADIOTAP_F_TX_FAIL); |
582 | 599 | ||
583 | if ((info->flags & IEEE80211_TX_CTL_USE_RTS_CTS) && | 600 | /* |
584 | (info->flags & IEEE80211_TX_CTL_USE_CTS_PROTECT)) | 601 | * XXX: Once radiotap gets the bitmap reset thing the vendor |
602 | * extensions proposal contains, we can actually report | ||
603 | * the whole set of tries we did. | ||
604 | */ | ||
605 | if ((info->status.rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS) || | ||
606 | (info->status.rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT)) | ||
585 | rthdr->tx_flags |= cpu_to_le16(IEEE80211_RADIOTAP_F_TX_CTS); | 607 | rthdr->tx_flags |= cpu_to_le16(IEEE80211_RADIOTAP_F_TX_CTS); |
586 | else if (info->flags & IEEE80211_TX_CTL_USE_RTS_CTS) | 608 | else if (info->status.rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS) |
587 | rthdr->tx_flags |= cpu_to_le16(IEEE80211_RADIOTAP_F_TX_RTS); | 609 | rthdr->tx_flags |= cpu_to_le16(IEEE80211_RADIOTAP_F_TX_RTS); |
610 | if (info->status.rates[0].idx >= 0 && | ||
611 | !(info->status.rates[0].flags & IEEE80211_TX_RC_MCS)) | ||
612 | rthdr->rate = sband->bitrates[ | ||
613 | info->status.rates[0].idx].bitrate / 5; | ||
588 | 614 | ||
589 | rthdr->data_retries = info->status.retry_count; | 615 | /* for now report the total retry_count */ |
616 | rthdr->data_retries = retry_count; | ||
590 | 617 | ||
591 | /* XXX: is this sufficient for BPF? */ | 618 | /* XXX: is this sufficient for BPF? */ |
592 | skb_set_mac_header(skb, 0); | 619 | skb_set_mac_header(skb, 0); |
@@ -671,8 +698,9 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len, | |||
671 | BUG_ON(!ops->configure_filter); | 698 | BUG_ON(!ops->configure_filter); |
672 | local->ops = ops; | 699 | local->ops = ops; |
673 | 700 | ||
674 | local->hw.queues = 1; /* default */ | 701 | /* set up some defaults */ |
675 | 702 | local->hw.queues = 1; | |
703 | local->hw.max_rates = 1; | ||
676 | local->rts_threshold = IEEE80211_MAX_RTS_THRESHOLD; | 704 | local->rts_threshold = IEEE80211_MAX_RTS_THRESHOLD; |
677 | local->fragmentation_threshold = IEEE80211_MAX_FRAG_THRESHOLD; | 705 | local->fragmentation_threshold = IEEE80211_MAX_FRAG_THRESHOLD; |
678 | local->hw.conf.long_frame_max_tx_count = 4; | 706 | local->hw.conf.long_frame_max_tx_count = 4; |
diff --git a/net/mac80211/mesh_hwmp.c b/net/mac80211/mesh_hwmp.c index 501c7831adb4..e8d573d592e7 100644 --- a/net/mac80211/mesh_hwmp.c +++ b/net/mac80211/mesh_hwmp.c | |||
@@ -218,12 +218,16 @@ static u32 airtime_link_metric_get(struct ieee80211_local *local, | |||
218 | 218 | ||
219 | if (sta->fail_avg >= 100) | 219 | if (sta->fail_avg >= 100) |
220 | return MAX_METRIC; | 220 | return MAX_METRIC; |
221 | |||
222 | if (sta->last_tx_rate.flags & IEEE80211_TX_RC_MCS) | ||
223 | return MAX_METRIC; | ||
224 | |||
221 | err = (sta->fail_avg << ARITH_SHIFT) / 100; | 225 | err = (sta->fail_avg << ARITH_SHIFT) / 100; |
222 | 226 | ||
223 | /* bitrate is in units of 100 Kbps, while we need rate in units of | 227 | /* bitrate is in units of 100 Kbps, while we need rate in units of |
224 | * 1Mbps. This will be corrected on tx_time computation. | 228 | * 1Mbps. This will be corrected on tx_time computation. |
225 | */ | 229 | */ |
226 | rate = sband->bitrates[sta->last_txrate_idx].bitrate; | 230 | rate = sband->bitrates[sta->last_tx_rate.idx].bitrate; |
227 | tx_time = (device_constant + 10 * test_frame_len / rate); | 231 | tx_time = (device_constant + 10 * test_frame_len / rate); |
228 | estimated_retx = ((1 << (2 * ARITH_SHIFT)) / (s_unit - err)); | 232 | estimated_retx = ((1 << (2 * ARITH_SHIFT)) / (s_unit - err)); |
229 | result = (tx_time * estimated_retx) >> (2 * ARITH_SHIFT) ; | 233 | result = (tx_time * estimated_retx) >> (2 * ARITH_SHIFT) ; |
diff --git a/net/mac80211/rate.c b/net/mac80211/rate.c index 5d786720d935..3fa7ab285066 100644 --- a/net/mac80211/rate.c +++ b/net/mac80211/rate.c | |||
@@ -199,48 +199,44 @@ static void rate_control_release(struct kref *kref) | |||
199 | } | 199 | } |
200 | 200 | ||
201 | void rate_control_get_rate(struct ieee80211_sub_if_data *sdata, | 201 | void rate_control_get_rate(struct ieee80211_sub_if_data *sdata, |
202 | struct ieee80211_supported_band *sband, | 202 | struct sta_info *sta, |
203 | struct sta_info *sta, struct sk_buff *skb, | 203 | struct ieee80211_tx_rate_control *txrc) |
204 | struct rate_selection *sel) | ||
205 | { | 204 | { |
206 | struct rate_control_ref *ref = sdata->local->rate_ctrl; | 205 | struct rate_control_ref *ref = sdata->local->rate_ctrl; |
207 | void *priv_sta = NULL; | 206 | void *priv_sta = NULL; |
208 | struct ieee80211_sta *ista = NULL; | 207 | struct ieee80211_sta *ista = NULL; |
208 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(txrc->skb); | ||
209 | int i; | 209 | int i; |
210 | 210 | ||
211 | sel->rate_idx = -1; | ||
212 | sel->nonerp_idx = -1; | ||
213 | sel->probe_idx = -1; | ||
214 | sel->max_rate_idx = sdata->max_ratectrl_rateidx; | ||
215 | |||
216 | if (sta) { | 211 | if (sta) { |
217 | ista = &sta->sta; | 212 | ista = &sta->sta; |
218 | priv_sta = sta->rate_ctrl_priv; | 213 | priv_sta = sta->rate_ctrl_priv; |
219 | } | 214 | } |
220 | 215 | ||
216 | for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) { | ||
217 | info->control.rates[i].idx = -1; | ||
218 | info->control.rates[i].flags = 0; | ||
219 | info->control.rates[i].count = 1; | ||
220 | } | ||
221 | |||
221 | if (sta && sdata->force_unicast_rateidx > -1) | 222 | if (sta && sdata->force_unicast_rateidx > -1) |
222 | sel->rate_idx = sdata->force_unicast_rateidx; | 223 | info->control.rates[0].idx = sdata->force_unicast_rateidx; |
223 | else | 224 | else |
224 | ref->ops->get_rate(ref->priv, sband, ista, priv_sta, skb, sel); | 225 | ref->ops->get_rate(ref->priv, ista, priv_sta, txrc); |
225 | 226 | ||
226 | if (sdata->max_ratectrl_rateidx > -1 && | 227 | /* |
227 | sel->rate_idx > sdata->max_ratectrl_rateidx) | 228 | * try to enforce the maximum rate the user wanted |
228 | sel->rate_idx = sdata->max_ratectrl_rateidx; | 229 | */ |
229 | 230 | if (sdata->max_ratectrl_rateidx > -1) | |
230 | BUG_ON(sel->rate_idx < 0); | 231 | for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) { |
231 | 232 | if (info->control.rates[i].flags & IEEE80211_TX_RC_MCS) | |
232 | /* Select a non-ERP backup rate. */ | 233 | continue; |
233 | if (sel->nonerp_idx < 0) { | 234 | info->control.rates[i].idx = |
234 | for (i = 0; i < sband->n_bitrates; i++) { | 235 | min_t(s8, info->control.rates[i].idx, |
235 | struct ieee80211_rate *rate = &sband->bitrates[i]; | 236 | sdata->max_ratectrl_rateidx); |
236 | if (sband->bitrates[sel->rate_idx].bitrate < rate->bitrate) | ||
237 | break; | ||
238 | |||
239 | if (rate_supported(ista, sband->band, i) && | ||
240 | !(rate->flags & IEEE80211_RATE_ERP_G)) | ||
241 | sel->nonerp_idx = i; | ||
242 | } | ||
243 | } | 237 | } |
238 | |||
239 | BUG_ON(info->control.rates[0].idx < 0); | ||
244 | } | 240 | } |
245 | 241 | ||
246 | struct rate_control_ref *rate_control_get(struct rate_control_ref *ref) | 242 | struct rate_control_ref *rate_control_get(struct rate_control_ref *ref) |
diff --git a/net/mac80211/rate.h b/net/mac80211/rate.h index d0092f847f82..7c25edf9ac55 100644 --- a/net/mac80211/rate.h +++ b/net/mac80211/rate.h | |||
@@ -31,9 +31,8 @@ struct rate_control_ref { | |||
31 | struct rate_control_ref *rate_control_alloc(const char *name, | 31 | struct rate_control_ref *rate_control_alloc(const char *name, |
32 | struct ieee80211_local *local); | 32 | struct ieee80211_local *local); |
33 | void rate_control_get_rate(struct ieee80211_sub_if_data *sdata, | 33 | void rate_control_get_rate(struct ieee80211_sub_if_data *sdata, |
34 | struct ieee80211_supported_band *sband, | 34 | struct sta_info *sta, |
35 | struct sta_info *sta, struct sk_buff *skb, | 35 | struct ieee80211_tx_rate_control *txrc); |
36 | struct rate_selection *sel); | ||
37 | struct rate_control_ref *rate_control_get(struct rate_control_ref *ref); | 36 | struct rate_control_ref *rate_control_get(struct rate_control_ref *ref); |
38 | void rate_control_put(struct rate_control_ref *ref); | 37 | void rate_control_put(struct rate_control_ref *ref); |
39 | 38 | ||
diff --git a/net/mac80211/rc80211_minstrel.c b/net/mac80211/rc80211_minstrel.c index f6d69dab07a3..759ddd8bf0f4 100644 --- a/net/mac80211/rc80211_minstrel.c +++ b/net/mac80211/rc80211_minstrel.c | |||
@@ -169,30 +169,20 @@ minstrel_tx_status(void *priv, struct ieee80211_supported_band *sband, | |||
169 | { | 169 | { |
170 | struct minstrel_sta_info *mi = priv_sta; | 170 | struct minstrel_sta_info *mi = priv_sta; |
171 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | 171 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
172 | struct ieee80211_tx_altrate *ar = info->status.retries; | 172 | struct ieee80211_tx_rate *ar = info->status.rates; |
173 | struct minstrel_priv *mp = priv; | 173 | int i, ndx; |
174 | int i, ndx, tries; | 174 | int success; |
175 | int success = 0; | ||
176 | 175 | ||
177 | if (!info->status.excessive_retries) | 176 | success = !!(info->flags & IEEE80211_TX_STAT_ACK); |
178 | success = 1; | ||
179 | 177 | ||
180 | if (!mp->has_mrr || (ar[0].rate_idx < 0)) { | 178 | for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) { |
181 | ndx = rix_to_ndx(mi, info->tx_rate_idx); | 179 | if (ar[i].idx < 0) |
182 | tries = info->status.retry_count + 1; | ||
183 | mi->r[ndx].success += success; | ||
184 | mi->r[ndx].attempts += tries; | ||
185 | return; | ||
186 | } | ||
187 | |||
188 | for (i = 0; i < 4; i++) { | ||
189 | if (ar[i].rate_idx < 0) | ||
190 | break; | 180 | break; |
191 | 181 | ||
192 | ndx = rix_to_ndx(mi, ar[i].rate_idx); | 182 | ndx = rix_to_ndx(mi, ar[i].idx); |
193 | mi->r[ndx].attempts += ar[i].limit + 1; | 183 | mi->r[ndx].attempts += ar[i].count; |
194 | 184 | ||
195 | if ((i != 3) && (ar[i + 1].rate_idx < 0)) | 185 | if ((i != IEEE80211_TX_MAX_RATES - 1) && (ar[i + 1].idx < 0)) |
196 | mi->r[ndx].success += success; | 186 | mi->r[ndx].success += success; |
197 | } | 187 | } |
198 | 188 | ||
@@ -210,9 +200,9 @@ minstrel_get_retry_count(struct minstrel_rate *mr, | |||
210 | { | 200 | { |
211 | unsigned int retry = mr->adjusted_retry_count; | 201 | unsigned int retry = mr->adjusted_retry_count; |
212 | 202 | ||
213 | if (info->flags & IEEE80211_TX_CTL_USE_RTS_CTS) | 203 | if (info->control.rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS) |
214 | retry = max(2U, min(mr->retry_count_rtscts, retry)); | 204 | retry = max(2U, min(mr->retry_count_rtscts, retry)); |
215 | else if (info->flags & IEEE80211_TX_CTL_USE_CTS_PROTECT) | 205 | else if (info->control.rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT) |
216 | retry = max(2U, min(mr->retry_count_cts, retry)); | 206 | retry = max(2U, min(mr->retry_count_cts, retry)); |
217 | return retry; | 207 | return retry; |
218 | } | 208 | } |
@@ -234,14 +224,15 @@ minstrel_get_next_sample(struct minstrel_sta_info *mi) | |||
234 | } | 224 | } |
235 | 225 | ||
236 | void | 226 | void |
237 | minstrel_get_rate(void *priv, struct ieee80211_supported_band *sband, | 227 | minstrel_get_rate(void *priv, struct ieee80211_sta *sta, |
238 | struct ieee80211_sta *sta, void *priv_sta, | 228 | void *priv_sta, struct ieee80211_tx_rate_control *txrc) |
239 | struct sk_buff *skb, struct rate_selection *sel) | ||
240 | { | 229 | { |
230 | struct sk_buff *skb = txrc->skb; | ||
231 | struct ieee80211_supported_band *sband = txrc->sband; | ||
241 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | 232 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
242 | struct minstrel_sta_info *mi = priv_sta; | 233 | struct minstrel_sta_info *mi = priv_sta; |
243 | struct minstrel_priv *mp = priv; | 234 | struct minstrel_priv *mp = priv; |
244 | struct ieee80211_tx_altrate *ar = info->control.retries; | 235 | struct ieee80211_tx_rate *ar = info->control.rates; |
245 | unsigned int ndx, sample_ndx = 0; | 236 | unsigned int ndx, sample_ndx = 0; |
246 | bool mrr; | 237 | bool mrr; |
247 | bool sample_slower = false; | 238 | bool sample_slower = false; |
@@ -251,16 +242,12 @@ minstrel_get_rate(void *priv, struct ieee80211_supported_band *sband, | |||
251 | int sample_rate; | 242 | int sample_rate; |
252 | 243 | ||
253 | if (!sta || !mi || use_low_rate(skb)) { | 244 | if (!sta || !mi || use_low_rate(skb)) { |
254 | sel->rate_idx = rate_lowest_index(sband, sta); | 245 | ar[0].idx = rate_lowest_index(sband, sta); |
246 | ar[0].count = mp->max_retry; | ||
255 | return; | 247 | return; |
256 | } | 248 | } |
257 | 249 | ||
258 | mrr = mp->has_mrr; | 250 | mrr = mp->has_mrr && !txrc->rts && !txrc->bss_conf->use_cts_prot; |
259 | |||
260 | /* mac80211 does not allow mrr for RTS/CTS */ | ||
261 | if ((info->flags & IEEE80211_TX_CTL_USE_RTS_CTS) || | ||
262 | (info->flags & IEEE80211_TX_CTL_USE_CTS_PROTECT)) | ||
263 | mrr = false; | ||
264 | 251 | ||
265 | if (time_after(jiffies, mi->stats_update + (mp->update_interval * | 252 | if (time_after(jiffies, mi->stats_update + (mp->update_interval * |
266 | HZ) / 1000)) | 253 | HZ) / 1000)) |
@@ -315,13 +302,12 @@ minstrel_get_rate(void *priv, struct ieee80211_supported_band *sband, | |||
315 | mi->sample_deferred++; | 302 | mi->sample_deferred++; |
316 | } | 303 | } |
317 | } | 304 | } |
318 | sel->rate_idx = mi->r[ndx].rix; | 305 | ar[0].idx = mi->r[ndx].rix; |
319 | info->control.retry_limit = minstrel_get_retry_count(&mi->r[ndx], info); | 306 | ar[0].count = minstrel_get_retry_count(&mi->r[ndx], info); |
320 | 307 | ||
321 | if (!mrr) { | 308 | if (!mrr) { |
322 | ar[0].rate_idx = mi->lowest_rix; | 309 | ar[1].idx = mi->lowest_rix; |
323 | ar[0].limit = mp->max_retry; | 310 | ar[1].count = mp->max_retry; |
324 | ar[1].rate_idx = -1; | ||
325 | return; | 311 | return; |
326 | } | 312 | } |
327 | 313 | ||
@@ -336,9 +322,9 @@ minstrel_get_rate(void *priv, struct ieee80211_supported_band *sband, | |||
336 | } | 322 | } |
337 | mrr_ndx[1] = mi->max_prob_rate; | 323 | mrr_ndx[1] = mi->max_prob_rate; |
338 | mrr_ndx[2] = 0; | 324 | mrr_ndx[2] = 0; |
339 | for (i = 0; i < 3; i++) { | 325 | for (i = 1; i < 4; i++) { |
340 | ar[i].rate_idx = mi->r[mrr_ndx[i]].rix; | 326 | ar[i].idx = mi->r[mrr_ndx[i - 1]].rix; |
341 | ar[i].limit = mi->r[mrr_ndx[i]].adjusted_retry_count; | 327 | ar[i].count = mi->r[mrr_ndx[i - 1]].adjusted_retry_count; |
342 | } | 328 | } |
343 | } | 329 | } |
344 | 330 | ||
@@ -532,13 +518,13 @@ minstrel_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir) | |||
532 | /* maximum time that the hw is allowed to stay in one MRR segment */ | 518 | /* maximum time that the hw is allowed to stay in one MRR segment */ |
533 | mp->segment_size = 6000; | 519 | mp->segment_size = 6000; |
534 | 520 | ||
535 | if (hw->max_altrate_tries > 0) | 521 | if (hw->max_rate_tries > 0) |
536 | mp->max_retry = hw->max_altrate_tries; | 522 | mp->max_retry = hw->max_rate_tries; |
537 | else | 523 | else |
538 | /* safe default, does not necessarily have to match hw properties */ | 524 | /* safe default, does not necessarily have to match hw properties */ |
539 | mp->max_retry = 7; | 525 | mp->max_retry = 7; |
540 | 526 | ||
541 | if (hw->max_altrates >= 3) | 527 | if (hw->max_rates >= 4) |
542 | mp->has_mrr = true; | 528 | mp->has_mrr = true; |
543 | 529 | ||
544 | mp->hw = hw; | 530 | mp->hw = hw; |
diff --git a/net/mac80211/rc80211_pid.h b/net/mac80211/rc80211_pid.h index ce099ea1d5d3..1a873f00691a 100644 --- a/net/mac80211/rc80211_pid.h +++ b/net/mac80211/rc80211_pid.h | |||
@@ -61,6 +61,7 @@ enum rc_pid_event_type { | |||
61 | union rc_pid_event_data { | 61 | union rc_pid_event_data { |
62 | /* RC_PID_EVENT_TX_STATUS */ | 62 | /* RC_PID_EVENT_TX_STATUS */ |
63 | struct { | 63 | struct { |
64 | u32 flags; | ||
64 | struct ieee80211_tx_info tx_status; | 65 | struct ieee80211_tx_info tx_status; |
65 | }; | 66 | }; |
66 | /* RC_PID_EVENT_TYPE_RATE_CHANGE */ | 67 | /* RC_PID_EVENT_TYPE_RATE_CHANGE */ |
diff --git a/net/mac80211/rc80211_pid_algo.c b/net/mac80211/rc80211_pid_algo.c index 86eb374e3b87..92caecfcee78 100644 --- a/net/mac80211/rc80211_pid_algo.c +++ b/net/mac80211/rc80211_pid_algo.c | |||
@@ -241,7 +241,7 @@ static void rate_control_pid_tx_status(void *priv, struct ieee80211_supported_ba | |||
241 | 241 | ||
242 | /* Ignore all frames that were sent with a different rate than the rate | 242 | /* Ignore all frames that were sent with a different rate than the rate |
243 | * we currently advise mac80211 to use. */ | 243 | * we currently advise mac80211 to use. */ |
244 | if (info->tx_rate_idx != spinfo->txrate_idx) | 244 | if (info->status.rates[0].idx != spinfo->txrate_idx) |
245 | return; | 245 | return; |
246 | 246 | ||
247 | spinfo->tx_num_xmit++; | 247 | spinfo->tx_num_xmit++; |
@@ -253,10 +253,10 @@ static void rate_control_pid_tx_status(void *priv, struct ieee80211_supported_ba | |||
253 | /* We count frames that totally failed to be transmitted as two bad | 253 | /* We count frames that totally failed to be transmitted as two bad |
254 | * frames, those that made it out but had some retries as one good and | 254 | * frames, those that made it out but had some retries as one good and |
255 | * one bad frame. */ | 255 | * one bad frame. */ |
256 | if (info->status.excessive_retries) { | 256 | if (!(info->flags & IEEE80211_TX_STAT_ACK)) { |
257 | spinfo->tx_num_failed += 2; | 257 | spinfo->tx_num_failed += 2; |
258 | spinfo->tx_num_xmit++; | 258 | spinfo->tx_num_xmit++; |
259 | } else if (info->status.retry_count) { | 259 | } else if (info->status.rates[0].count) { |
260 | spinfo->tx_num_failed++; | 260 | spinfo->tx_num_failed++; |
261 | spinfo->tx_num_xmit++; | 261 | spinfo->tx_num_xmit++; |
262 | } | 262 | } |
@@ -270,23 +270,32 @@ static void rate_control_pid_tx_status(void *priv, struct ieee80211_supported_ba | |||
270 | } | 270 | } |
271 | 271 | ||
272 | static void | 272 | static void |
273 | rate_control_pid_get_rate(void *priv, struct ieee80211_supported_band *sband, | 273 | rate_control_pid_get_rate(void *priv, struct ieee80211_sta *sta, |
274 | struct ieee80211_sta *sta, void *priv_sta, | 274 | void *priv_sta, |
275 | struct sk_buff *skb, | 275 | struct ieee80211_tx_rate_control *txrc) |
276 | struct rate_selection *sel) | ||
277 | { | 276 | { |
277 | struct sk_buff *skb = txrc->skb; | ||
278 | struct ieee80211_supported_band *sband = txrc->sband; | ||
278 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; | 279 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; |
280 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | ||
279 | struct rc_pid_sta_info *spinfo = priv_sta; | 281 | struct rc_pid_sta_info *spinfo = priv_sta; |
280 | int rateidx; | 282 | int rateidx; |
281 | u16 fc; | 283 | u16 fc; |
282 | 284 | ||
285 | if (txrc->rts) | ||
286 | info->control.rates[0].count = | ||
287 | txrc->hw->conf.long_frame_max_tx_count; | ||
288 | else | ||
289 | info->control.rates[0].count = | ||
290 | txrc->hw->conf.short_frame_max_tx_count; | ||
291 | |||
283 | /* Send management frames and broadcast/multicast data using lowest | 292 | /* Send management frames and broadcast/multicast data using lowest |
284 | * rate. */ | 293 | * rate. */ |
285 | fc = le16_to_cpu(hdr->frame_control); | 294 | fc = le16_to_cpu(hdr->frame_control); |
286 | if (!sta || !spinfo || | 295 | if (!sta || !spinfo || |
287 | (fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA || | 296 | (fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA || |
288 | is_multicast_ether_addr(hdr->addr1)) { | 297 | is_multicast_ether_addr(hdr->addr1)) { |
289 | sel->rate_idx = rate_lowest_index(sband, sta); | 298 | info->control.rates[0].idx = rate_lowest_index(sband, sta); |
290 | return; | 299 | return; |
291 | } | 300 | } |
292 | 301 | ||
@@ -295,7 +304,7 @@ rate_control_pid_get_rate(void *priv, struct ieee80211_supported_band *sband, | |||
295 | if (rateidx >= sband->n_bitrates) | 304 | if (rateidx >= sband->n_bitrates) |
296 | rateidx = sband->n_bitrates - 1; | 305 | rateidx = sband->n_bitrates - 1; |
297 | 306 | ||
298 | sel->rate_idx = rateidx; | 307 | info->control.rates[0].idx = rateidx; |
299 | 308 | ||
300 | #ifdef CONFIG_MAC80211_DEBUGFS | 309 | #ifdef CONFIG_MAC80211_DEBUGFS |
301 | rate_control_pid_event_tx_rate(&spinfo->events, | 310 | rate_control_pid_event_tx_rate(&spinfo->events, |
diff --git a/net/mac80211/rc80211_pid_debugfs.c b/net/mac80211/rc80211_pid_debugfs.c index 8121d3bc6835..a08a9b530347 100644 --- a/net/mac80211/rc80211_pid_debugfs.c +++ b/net/mac80211/rc80211_pid_debugfs.c | |||
@@ -43,6 +43,7 @@ void rate_control_pid_event_tx_status(struct rc_pid_event_buffer *buf, | |||
43 | { | 43 | { |
44 | union rc_pid_event_data evd; | 44 | union rc_pid_event_data evd; |
45 | 45 | ||
46 | evd.flags = stat->flags; | ||
46 | memcpy(&evd.tx_status, stat, sizeof(struct ieee80211_tx_info)); | 47 | memcpy(&evd.tx_status, stat, sizeof(struct ieee80211_tx_info)); |
47 | rate_control_pid_event(buf, RC_PID_EVENT_TYPE_TX_STATUS, &evd); | 48 | rate_control_pid_event(buf, RC_PID_EVENT_TYPE_TX_STATUS, &evd); |
48 | } | 49 | } |
@@ -167,8 +168,8 @@ static ssize_t rate_control_pid_events_read(struct file *file, char __user *buf, | |||
167 | switch (ev->type) { | 168 | switch (ev->type) { |
168 | case RC_PID_EVENT_TYPE_TX_STATUS: | 169 | case RC_PID_EVENT_TYPE_TX_STATUS: |
169 | p += snprintf(pb + p, length - p, "tx_status %u %u", | 170 | p += snprintf(pb + p, length - p, "tx_status %u %u", |
170 | ev->data.tx_status.status.excessive_retries, | 171 | !(ev->data.flags & IEEE80211_TX_STAT_ACK), |
171 | ev->data.tx_status.status.retry_count); | 172 | ev->data.tx_status.status.rates[0].idx); |
172 | break; | 173 | break; |
173 | case RC_PID_EVENT_TYPE_RATE_CHANGE: | 174 | case RC_PID_EVENT_TYPE_RATE_CHANGE: |
174 | p += snprintf(pb + p, length - p, "rate_change %d %d", | 175 | p += snprintf(pb + p, length - p, "rate_change %d %d", |
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h index 168a39a298bd..4ac372aa75ce 100644 --- a/net/mac80211/sta_info.h +++ b/net/mac80211/sta_info.h | |||
@@ -196,7 +196,7 @@ struct sta_ampdu_mlme { | |||
196 | * @tx_packets: number of RX/TX MSDUs | 196 | * @tx_packets: number of RX/TX MSDUs |
197 | * @tx_bytes: TBD | 197 | * @tx_bytes: TBD |
198 | * @tx_fragments: number of transmitted MPDUs | 198 | * @tx_fragments: number of transmitted MPDUs |
199 | * @last_txrate_idx: Index of the last used transmit rate | 199 | * @last_txrate: description of the last used transmit rate |
200 | * @tid_seq: TBD | 200 | * @tid_seq: TBD |
201 | * @ampdu_mlme: TBD | 201 | * @ampdu_mlme: TBD |
202 | * @timer_to_tid: identity mapping to ID timers | 202 | * @timer_to_tid: identity mapping to ID timers |
@@ -267,7 +267,7 @@ struct sta_info { | |||
267 | unsigned long tx_packets; | 267 | unsigned long tx_packets; |
268 | unsigned long tx_bytes; | 268 | unsigned long tx_bytes; |
269 | unsigned long tx_fragments; | 269 | unsigned long tx_fragments; |
270 | unsigned int last_txrate_idx; | 270 | struct ieee80211_tx_rate last_tx_rate; |
271 | u16 tid_seq[IEEE80211_QOS_CTL_TID_MASK + 1]; | 271 | u16 tid_seq[IEEE80211_QOS_CTL_TID_MASK + 1]; |
272 | 272 | ||
273 | /* | 273 | /* |
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 6f3e4be97631..21951bac1ef7 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c | |||
@@ -46,13 +46,20 @@ static __le16 ieee80211_duration(struct ieee80211_tx_data *tx, int group_addr, | |||
46 | struct ieee80211_local *local = tx->local; | 46 | struct ieee80211_local *local = tx->local; |
47 | struct ieee80211_supported_band *sband; | 47 | struct ieee80211_supported_band *sband; |
48 | struct ieee80211_hdr *hdr; | 48 | struct ieee80211_hdr *hdr; |
49 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb); | ||
50 | |||
51 | /* assume HW handles this */ | ||
52 | if (info->control.rates[0].flags & IEEE80211_TX_RC_MCS) | ||
53 | return 0; | ||
54 | |||
55 | /* uh huh? */ | ||
56 | if (WARN_ON_ONCE(info->control.rates[0].idx < 0)) | ||
57 | return 0; | ||
49 | 58 | ||
50 | sband = local->hw.wiphy->bands[tx->channel->band]; | 59 | sband = local->hw.wiphy->bands[tx->channel->band]; |
51 | txrate = &sband->bitrates[tx->rate_idx]; | 60 | txrate = &sband->bitrates[info->control.rates[0].idx]; |
52 | 61 | ||
53 | erp = 0; | 62 | erp = txrate->flags & IEEE80211_RATE_ERP_G; |
54 | if (tx->sdata->flags & IEEE80211_SDATA_OPERATING_GMODE) | ||
55 | erp = txrate->flags & IEEE80211_RATE_ERP_G; | ||
56 | 63 | ||
57 | /* | 64 | /* |
58 | * data and mgmt (except PS Poll): | 65 | * data and mgmt (except PS Poll): |
@@ -437,140 +444,154 @@ ieee80211_tx_h_select_key(struct ieee80211_tx_data *tx) | |||
437 | static ieee80211_tx_result debug_noinline | 444 | static ieee80211_tx_result debug_noinline |
438 | ieee80211_tx_h_rate_ctrl(struct ieee80211_tx_data *tx) | 445 | ieee80211_tx_h_rate_ctrl(struct ieee80211_tx_data *tx) |
439 | { | 446 | { |
440 | struct rate_selection rsel; | ||
441 | struct ieee80211_supported_band *sband; | ||
442 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb); | 447 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb); |
448 | struct ieee80211_hdr *hdr = (void *)tx->skb->data; | ||
449 | struct ieee80211_supported_band *sband; | ||
450 | struct ieee80211_rate *rate; | ||
451 | int i, len; | ||
452 | bool inval = false, rts = false, short_preamble = false; | ||
453 | struct ieee80211_tx_rate_control txrc; | ||
443 | 454 | ||
444 | sband = tx->local->hw.wiphy->bands[tx->channel->band]; | 455 | memset(&txrc, 0, sizeof(txrc)); |
445 | 456 | ||
446 | if (likely(tx->rate_idx < 0)) { | 457 | sband = tx->local->hw.wiphy->bands[tx->channel->band]; |
447 | rate_control_get_rate(tx->sdata, sband, tx->sta, | ||
448 | tx->skb, &rsel); | ||
449 | if (tx->sta) | ||
450 | tx->sta->last_txrate_idx = rsel.rate_idx; | ||
451 | tx->rate_idx = rsel.rate_idx; | ||
452 | if (unlikely(rsel.probe_idx >= 0)) { | ||
453 | info->flags |= IEEE80211_TX_CTL_RATE_CTRL_PROBE; | ||
454 | tx->flags |= IEEE80211_TX_PROBE_LAST_FRAG; | ||
455 | info->control.retries[0].rate_idx = tx->rate_idx; | ||
456 | info->control.retries[0].limit = tx->local->hw.max_altrate_tries; | ||
457 | tx->rate_idx = rsel.probe_idx; | ||
458 | } else if (info->control.retries[0].limit == 0) | ||
459 | info->control.retries[0].rate_idx = -1; | ||
460 | |||
461 | if (unlikely(tx->rate_idx < 0)) | ||
462 | return TX_DROP; | ||
463 | } else | ||
464 | info->control.retries[0].rate_idx = -1; | ||
465 | 458 | ||
466 | if (tx->sdata->vif.bss_conf.use_cts_prot && | 459 | len = min_t(int, tx->skb->len + FCS_LEN, |
467 | (tx->flags & IEEE80211_TX_FRAGMENTED) && (rsel.nonerp_idx >= 0)) { | 460 | tx->local->fragmentation_threshold); |
468 | tx->last_frag_rate_idx = tx->rate_idx; | 461 | |
469 | if (rsel.probe_idx >= 0) | 462 | /* set up the tx rate control struct we give the RC algo */ |
470 | tx->flags &= ~IEEE80211_TX_PROBE_LAST_FRAG; | 463 | txrc.hw = local_to_hw(tx->local); |
471 | else | 464 | txrc.sband = sband; |
472 | tx->flags |= IEEE80211_TX_PROBE_LAST_FRAG; | 465 | txrc.bss_conf = &tx->sdata->vif.bss_conf; |
473 | tx->rate_idx = rsel.nonerp_idx; | 466 | txrc.skb = tx->skb; |
474 | info->tx_rate_idx = rsel.nonerp_idx; | 467 | txrc.reported_rate.idx = -1; |
475 | info->flags &= ~IEEE80211_TX_CTL_RATE_CTRL_PROBE; | 468 | txrc.max_rate_idx = tx->sdata->max_ratectrl_rateidx; |
476 | } else { | 469 | |
477 | tx->last_frag_rate_idx = tx->rate_idx; | 470 | /* set up RTS protection if desired */ |
478 | info->tx_rate_idx = tx->rate_idx; | 471 | if (tx->local->rts_threshold < IEEE80211_MAX_RTS_THRESHOLD && |
472 | len > tx->local->rts_threshold) { | ||
473 | txrc.rts = rts = true; | ||
479 | } | 474 | } |
480 | info->tx_rate_idx = tx->rate_idx; | ||
481 | 475 | ||
482 | return TX_CONTINUE; | 476 | /* |
483 | } | 477 | * Use short preamble if the BSS can handle it, but not for |
478 | * management frames unless we know the receiver can handle | ||
479 | * that -- the management frame might be to a station that | ||
480 | * just wants a probe response. | ||
481 | */ | ||
482 | if (tx->sdata->vif.bss_conf.use_short_preamble && | ||
483 | (ieee80211_is_data(hdr->frame_control) || | ||
484 | (tx->sta && test_sta_flags(tx->sta, WLAN_STA_SHORT_PREAMBLE)))) | ||
485 | txrc.short_preamble = short_preamble = true; | ||
484 | 486 | ||
485 | static ieee80211_tx_result debug_noinline | ||
486 | ieee80211_tx_h_misc(struct ieee80211_tx_data *tx) | ||
487 | { | ||
488 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data; | ||
489 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb); | ||
490 | struct ieee80211_supported_band *sband; | ||
491 | 487 | ||
492 | sband = tx->local->hw.wiphy->bands[tx->channel->band]; | 488 | rate_control_get_rate(tx->sdata, tx->sta, &txrc); |
489 | |||
490 | if (unlikely(info->control.rates[0].idx < 0)) | ||
491 | return TX_DROP; | ||
492 | |||
493 | if (txrc.reported_rate.idx < 0) | ||
494 | txrc.reported_rate = info->control.rates[0]; | ||
493 | 495 | ||
494 | if (tx->sta) | 496 | if (tx->sta) |
495 | info->control.sta = &tx->sta->sta; | 497 | tx->sta->last_tx_rate = txrc.reported_rate; |
496 | 498 | ||
497 | if (!info->control.retry_limit) { | 499 | if (unlikely(!info->control.rates[0].count)) |
498 | if (!is_multicast_ether_addr(hdr->addr1)) { | 500 | info->control.rates[0].count = 1; |
499 | int len = min_t(int, tx->skb->len + FCS_LEN, | ||
500 | tx->local->fragmentation_threshold); | ||
501 | if (len > tx->local->rts_threshold | ||
502 | && tx->local->rts_threshold < | ||
503 | IEEE80211_MAX_RTS_THRESHOLD) { | ||
504 | info->flags |= IEEE80211_TX_CTL_USE_RTS_CTS; | ||
505 | info->flags |= | ||
506 | IEEE80211_TX_CTL_LONG_RETRY_LIMIT; | ||
507 | info->control.retry_limit = | ||
508 | tx->local->hw.conf.long_frame_max_tx_count - 1; | ||
509 | } else { | ||
510 | info->control.retry_limit = | ||
511 | tx->local->hw.conf.short_frame_max_tx_count - 1; | ||
512 | } | ||
513 | } else { | ||
514 | info->control.retry_limit = 1; | ||
515 | } | ||
516 | } | ||
517 | 501 | ||
518 | if (tx->flags & IEEE80211_TX_FRAGMENTED) { | 502 | if (is_multicast_ether_addr(hdr->addr1)) { |
519 | /* Do not use multiple retry rates when sending fragmented | 503 | /* |
520 | * frames. | 504 | * XXX: verify the rate is in the basic rateset |
521 | * TODO: The last fragment could still use multiple retry | 505 | */ |
522 | * rates. */ | 506 | return TX_CONTINUE; |
523 | info->control.retries[0].rate_idx = -1; | ||
524 | } | 507 | } |
525 | 508 | ||
526 | /* Use CTS protection for unicast frames sent using extended rates if | 509 | /* |
527 | * there are associated non-ERP stations and RTS/CTS is not configured | 510 | * set up the RTS/CTS rate as the fastest basic rate |
528 | * for the frame. */ | 511 | * that is not faster than the data rate |
529 | if ((tx->sdata->flags & IEEE80211_SDATA_OPERATING_GMODE) && | 512 | * |
530 | (sband->bitrates[tx->rate_idx].flags & IEEE80211_RATE_ERP_G) && | 513 | * XXX: Should this check all retry rates? |
531 | (tx->flags & IEEE80211_TX_UNICAST) && | 514 | */ |
532 | tx->sdata->vif.bss_conf.use_cts_prot && | 515 | if (!(info->control.rates[0].flags & IEEE80211_TX_RC_MCS)) { |
533 | !(info->flags & IEEE80211_TX_CTL_USE_RTS_CTS)) | 516 | s8 baserate = 0; |
534 | info->flags |= IEEE80211_TX_CTL_USE_CTS_PROTECT; | 517 | |
535 | 518 | rate = &sband->bitrates[info->control.rates[0].idx]; | |
536 | /* Transmit data frames using short preambles if the driver supports | 519 | |
537 | * short preambles at the selected rate and short preambles are | 520 | for (i = 0; i < sband->n_bitrates; i++) { |
538 | * available on the network at the current point in time. */ | 521 | /* must be a basic rate */ |
539 | if (ieee80211_is_data(hdr->frame_control) && | 522 | if (!(tx->sdata->vif.bss_conf.basic_rates & BIT(i))) |
540 | (sband->bitrates[tx->rate_idx].flags & IEEE80211_RATE_SHORT_PREAMBLE) && | 523 | continue; |
541 | tx->sdata->vif.bss_conf.use_short_preamble && | 524 | /* must not be faster than the data rate */ |
542 | (!tx->sta || test_sta_flags(tx->sta, WLAN_STA_SHORT_PREAMBLE))) { | 525 | if (sband->bitrates[i].bitrate > rate->bitrate) |
543 | info->flags |= IEEE80211_TX_CTL_SHORT_PREAMBLE; | 526 | continue; |
527 | /* maximum */ | ||
528 | if (sband->bitrates[baserate].bitrate < | ||
529 | sband->bitrates[i].bitrate) | ||
530 | baserate = i; | ||
531 | } | ||
532 | |||
533 | info->control.rts_cts_rate_idx = baserate; | ||
544 | } | 534 | } |
545 | 535 | ||
546 | if ((info->flags & IEEE80211_TX_CTL_USE_RTS_CTS) || | 536 | for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) { |
547 | (info->flags & IEEE80211_TX_CTL_USE_CTS_PROTECT)) { | 537 | /* |
548 | struct ieee80211_rate *rate; | 538 | * make sure there's no valid rate following |
549 | s8 baserate = -1; | 539 | * an invalid one, just in case drivers don't |
550 | int idx; | 540 | * take the API seriously to stop at -1. |
541 | */ | ||
542 | if (inval) { | ||
543 | info->control.rates[i].idx = -1; | ||
544 | continue; | ||
545 | } | ||
546 | if (info->control.rates[i].idx < 0) { | ||
547 | inval = true; | ||
548 | continue; | ||
549 | } | ||
551 | 550 | ||
552 | /* Do not use multiple retry rates when using RTS/CTS */ | 551 | /* |
553 | info->control.retries[0].rate_idx = -1; | 552 | * For now assume MCS is already set up correctly, this |
553 | * needs to be fixed. | ||
554 | */ | ||
555 | if (info->control.rates[i].flags & IEEE80211_TX_RC_MCS) { | ||
556 | WARN_ON(info->control.rates[i].idx > 76); | ||
557 | continue; | ||
558 | } | ||
554 | 559 | ||
555 | /* Use min(data rate, max base rate) as CTS/RTS rate */ | 560 | /* set up RTS protection if desired */ |
556 | rate = &sband->bitrates[tx->rate_idx]; | 561 | if (rts) |
562 | info->control.rates[i].flags |= | ||
563 | IEEE80211_TX_RC_USE_RTS_CTS; | ||
557 | 564 | ||
558 | for (idx = 0; idx < sband->n_bitrates; idx++) { | 565 | /* RC is busted */ |
559 | if (sband->bitrates[idx].bitrate > rate->bitrate) | 566 | if (WARN_ON(info->control.rates[i].idx >= |
560 | continue; | 567 | sband->n_bitrates)) { |
561 | if (tx->sdata->vif.bss_conf.basic_rates & BIT(idx) && | 568 | info->control.rates[i].idx = -1; |
562 | (baserate < 0 || | 569 | continue; |
563 | (sband->bitrates[baserate].bitrate | ||
564 | < sband->bitrates[idx].bitrate))) | ||
565 | baserate = idx; | ||
566 | } | 570 | } |
567 | 571 | ||
568 | if (baserate >= 0) | 572 | rate = &sband->bitrates[info->control.rates[i].idx]; |
569 | info->control.rts_cts_rate_idx = baserate; | 573 | |
570 | else | 574 | /* set up short preamble */ |
571 | info->control.rts_cts_rate_idx = 0; | 575 | if (short_preamble && |
576 | rate->flags & IEEE80211_RATE_SHORT_PREAMBLE) | ||
577 | info->control.rates[i].flags |= | ||
578 | IEEE80211_TX_RC_USE_SHORT_PREAMBLE; | ||
579 | |||
580 | /* set up G protection */ | ||
581 | if (!rts && tx->sdata->vif.bss_conf.use_cts_prot && | ||
582 | rate->flags & IEEE80211_RATE_ERP_G) | ||
583 | info->control.rates[i].flags |= | ||
584 | IEEE80211_TX_RC_USE_CTS_PROTECT; | ||
572 | } | 585 | } |
573 | 586 | ||
587 | return TX_CONTINUE; | ||
588 | } | ||
589 | |||
590 | static ieee80211_tx_result debug_noinline | ||
591 | ieee80211_tx_h_misc(struct ieee80211_tx_data *tx) | ||
592 | { | ||
593 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb); | ||
594 | |||
574 | if (tx->sta) | 595 | if (tx->sta) |
575 | info->control.sta = &tx->sta->sta; | 596 | info->control.sta = &tx->sta->sta; |
576 | 597 | ||
@@ -678,6 +699,7 @@ ieee80211_tx_h_fragment(struct ieee80211_tx_data *tx) | |||
678 | left = payload_len - per_fragm; | 699 | left = payload_len - per_fragm; |
679 | for (i = 0; i < num_fragm - 1; i++) { | 700 | for (i = 0; i < num_fragm - 1; i++) { |
680 | struct ieee80211_hdr *fhdr; | 701 | struct ieee80211_hdr *fhdr; |
702 | struct ieee80211_tx_info *info; | ||
681 | size_t copylen; | 703 | size_t copylen; |
682 | 704 | ||
683 | if (left <= 0) | 705 | if (left <= 0) |
@@ -692,20 +714,45 @@ ieee80211_tx_h_fragment(struct ieee80211_tx_data *tx) | |||
692 | IEEE80211_ENCRYPT_TAILROOM); | 714 | IEEE80211_ENCRYPT_TAILROOM); |
693 | if (!frag) | 715 | if (!frag) |
694 | goto fail; | 716 | goto fail; |
717 | |||
695 | /* Make sure that all fragments use the same priority so | 718 | /* Make sure that all fragments use the same priority so |
696 | * that they end up using the same TX queue */ | 719 | * that they end up using the same TX queue */ |
697 | frag->priority = first->priority; | 720 | frag->priority = first->priority; |
721 | |||
698 | skb_reserve(frag, tx->local->tx_headroom + | 722 | skb_reserve(frag, tx->local->tx_headroom + |
699 | IEEE80211_ENCRYPT_HEADROOM); | 723 | IEEE80211_ENCRYPT_HEADROOM); |
724 | |||
725 | /* copy TX information */ | ||
726 | info = IEEE80211_SKB_CB(frag); | ||
727 | memcpy(info, first->cb, sizeof(frag->cb)); | ||
728 | |||
729 | /* copy/fill in 802.11 header */ | ||
700 | fhdr = (struct ieee80211_hdr *) skb_put(frag, hdrlen); | 730 | fhdr = (struct ieee80211_hdr *) skb_put(frag, hdrlen); |
701 | memcpy(fhdr, first->data, hdrlen); | 731 | memcpy(fhdr, first->data, hdrlen); |
702 | if (i == num_fragm - 2) | ||
703 | fhdr->frame_control &= cpu_to_le16(~IEEE80211_FCTL_MOREFRAGS); | ||
704 | fhdr->seq_ctrl = cpu_to_le16(seq | ((i + 1) & IEEE80211_SCTL_FRAG)); | 732 | fhdr->seq_ctrl = cpu_to_le16(seq | ((i + 1) & IEEE80211_SCTL_FRAG)); |
733 | |||
734 | if (i == num_fragm - 2) { | ||
735 | /* clear MOREFRAGS bit for the last fragment */ | ||
736 | fhdr->frame_control &= cpu_to_le16(~IEEE80211_FCTL_MOREFRAGS); | ||
737 | } else { | ||
738 | /* | ||
739 | * No multi-rate retries for fragmented frames, that | ||
740 | * would completely throw off the NAV at other STAs. | ||
741 | */ | ||
742 | info->control.rates[1].idx = -1; | ||
743 | info->control.rates[2].idx = -1; | ||
744 | info->control.rates[3].idx = -1; | ||
745 | info->control.rates[4].idx = -1; | ||
746 | BUILD_BUG_ON(IEEE80211_TX_MAX_RATES != 5); | ||
747 | info->flags &= ~IEEE80211_TX_CTL_RATE_CTRL_PROBE; | ||
748 | } | ||
749 | |||
750 | /* copy data */ | ||
705 | copylen = left > per_fragm ? per_fragm : left; | 751 | copylen = left > per_fragm ? per_fragm : left; |
706 | memcpy(skb_put(frag, copylen), pos, copylen); | 752 | memcpy(skb_put(frag, copylen), pos, copylen); |
707 | memcpy(frag->cb, first->cb, sizeof(frag->cb)); | 753 | |
708 | skb_copy_queue_mapping(frag, first); | 754 | skb_copy_queue_mapping(frag, first); |
755 | |||
709 | frag->do_not_encrypt = first->do_not_encrypt; | 756 | frag->do_not_encrypt = first->do_not_encrypt; |
710 | 757 | ||
711 | pos += copylen; | 758 | pos += copylen; |
@@ -765,12 +812,10 @@ ieee80211_tx_h_calculate_duration(struct ieee80211_tx_data *tx) | |||
765 | tx->extra_frag[0]->len); | 812 | tx->extra_frag[0]->len); |
766 | 813 | ||
767 | for (i = 0; i < tx->num_extra_frag; i++) { | 814 | for (i = 0; i < tx->num_extra_frag; i++) { |
768 | if (i + 1 < tx->num_extra_frag) { | 815 | if (i + 1 < tx->num_extra_frag) |
769 | next_len = tx->extra_frag[i + 1]->len; | 816 | next_len = tx->extra_frag[i + 1]->len; |
770 | } else { | 817 | else |
771 | next_len = 0; | 818 | next_len = 0; |
772 | tx->rate_idx = tx->last_frag_rate_idx; | ||
773 | } | ||
774 | 819 | ||
775 | hdr = (struct ieee80211_hdr *)tx->extra_frag[i]->data; | 820 | hdr = (struct ieee80211_hdr *)tx->extra_frag[i]->data; |
776 | hdr->duration_id = ieee80211_duration(tx, 0, next_len); | 821 | hdr->duration_id = ieee80211_duration(tx, 0, next_len); |
@@ -823,7 +868,6 @@ __ieee80211_parse_tx_radiotap(struct ieee80211_tx_data *tx, | |||
823 | (struct ieee80211_radiotap_header *) skb->data; | 868 | (struct ieee80211_radiotap_header *) skb->data; |
824 | struct ieee80211_supported_band *sband; | 869 | struct ieee80211_supported_band *sband; |
825 | int ret = ieee80211_radiotap_iterator_init(&iterator, rthdr, skb->len); | 870 | int ret = ieee80211_radiotap_iterator_init(&iterator, rthdr, skb->len); |
826 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | ||
827 | 871 | ||
828 | sband = tx->local->hw.wiphy->bands[tx->channel->band]; | 872 | sband = tx->local->hw.wiphy->bands[tx->channel->band]; |
829 | 873 | ||
@@ -837,8 +881,6 @@ __ieee80211_parse_tx_radiotap(struct ieee80211_tx_data *tx, | |||
837 | */ | 881 | */ |
838 | 882 | ||
839 | while (!ret) { | 883 | while (!ret) { |
840 | int i, target_rate; | ||
841 | |||
842 | ret = ieee80211_radiotap_iterator_next(&iterator); | 884 | ret = ieee80211_radiotap_iterator_next(&iterator); |
843 | 885 | ||
844 | if (ret) | 886 | if (ret) |
@@ -852,38 +894,6 @@ __ieee80211_parse_tx_radiotap(struct ieee80211_tx_data *tx, | |||
852 | * get_unaligned((type *)iterator.this_arg) to dereference | 894 | * get_unaligned((type *)iterator.this_arg) to dereference |
853 | * iterator.this_arg for type "type" safely on all arches. | 895 | * iterator.this_arg for type "type" safely on all arches. |
854 | */ | 896 | */ |
855 | case IEEE80211_RADIOTAP_RATE: | ||
856 | /* | ||
857 | * radiotap rate u8 is in 500kbps units eg, 0x02=1Mbps | ||
858 | * ieee80211 rate int is in 100kbps units eg, 0x0a=1Mbps | ||
859 | */ | ||
860 | target_rate = (*iterator.this_arg) * 5; | ||
861 | for (i = 0; i < sband->n_bitrates; i++) { | ||
862 | struct ieee80211_rate *r; | ||
863 | |||
864 | r = &sband->bitrates[i]; | ||
865 | |||
866 | if (r->bitrate == target_rate) { | ||
867 | tx->rate_idx = i; | ||
868 | break; | ||
869 | } | ||
870 | } | ||
871 | break; | ||
872 | |||
873 | case IEEE80211_RADIOTAP_ANTENNA: | ||
874 | /* | ||
875 | * radiotap uses 0 for 1st ant, mac80211 is 1 for | ||
876 | * 1st ant | ||
877 | */ | ||
878 | info->antenna_sel_tx = (*iterator.this_arg) + 1; | ||
879 | break; | ||
880 | |||
881 | #if 0 | ||
882 | case IEEE80211_RADIOTAP_DBM_TX_POWER: | ||
883 | control->power_level = *iterator.this_arg; | ||
884 | break; | ||
885 | #endif | ||
886 | |||
887 | case IEEE80211_RADIOTAP_FLAGS: | 897 | case IEEE80211_RADIOTAP_FLAGS: |
888 | if (*iterator.this_arg & IEEE80211_RADIOTAP_F_FCS) { | 898 | if (*iterator.this_arg & IEEE80211_RADIOTAP_F_FCS) { |
889 | /* | 899 | /* |
@@ -949,8 +959,6 @@ __ieee80211_tx_prepare(struct ieee80211_tx_data *tx, | |||
949 | tx->local = local; | 959 | tx->local = local; |
950 | tx->sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 960 | tx->sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
951 | tx->channel = local->hw.conf.channel; | 961 | tx->channel = local->hw.conf.channel; |
952 | tx->rate_idx = -1; | ||
953 | tx->last_frag_rate_idx = -1; | ||
954 | /* | 962 | /* |
955 | * Set this flag (used below to indicate "automatic fragmentation"), | 963 | * Set this flag (used below to indicate "automatic fragmentation"), |
956 | * it will be cleared/left by radiotap as desired. | 964 | * it will be cleared/left by radiotap as desired. |
@@ -1051,23 +1059,11 @@ static int __ieee80211_tx(struct ieee80211_local *local, struct sk_buff *skb, | |||
1051 | if (!tx->extra_frag[i]) | 1059 | if (!tx->extra_frag[i]) |
1052 | continue; | 1060 | continue; |
1053 | info = IEEE80211_SKB_CB(tx->extra_frag[i]); | 1061 | info = IEEE80211_SKB_CB(tx->extra_frag[i]); |
1054 | info->flags &= ~(IEEE80211_TX_CTL_USE_RTS_CTS | | 1062 | info->flags &= ~(IEEE80211_TX_CTL_CLEAR_PS_FILT | |
1055 | IEEE80211_TX_CTL_USE_CTS_PROTECT | | ||
1056 | IEEE80211_TX_CTL_CLEAR_PS_FILT | | ||
1057 | IEEE80211_TX_CTL_FIRST_FRAGMENT); | 1063 | IEEE80211_TX_CTL_FIRST_FRAGMENT); |
1058 | if (netif_subqueue_stopped(local->mdev, | 1064 | if (netif_subqueue_stopped(local->mdev, |
1059 | tx->extra_frag[i])) | 1065 | tx->extra_frag[i])) |
1060 | return IEEE80211_TX_FRAG_AGAIN; | 1066 | return IEEE80211_TX_FRAG_AGAIN; |
1061 | if (i == tx->num_extra_frag) { | ||
1062 | info->tx_rate_idx = tx->last_frag_rate_idx; | ||
1063 | |||
1064 | if (tx->flags & IEEE80211_TX_PROBE_LAST_FRAG) | ||
1065 | info->flags |= | ||
1066 | IEEE80211_TX_CTL_RATE_CTRL_PROBE; | ||
1067 | else | ||
1068 | info->flags &= | ||
1069 | ~IEEE80211_TX_CTL_RATE_CTRL_PROBE; | ||
1070 | } | ||
1071 | 1067 | ||
1072 | ret = local->ops->tx(local_to_hw(local), | 1068 | ret = local->ops->tx(local_to_hw(local), |
1073 | tx->extra_frag[i]); | 1069 | tx->extra_frag[i]); |
@@ -1204,9 +1200,6 @@ retry: | |||
1204 | store->skb = skb; | 1200 | store->skb = skb; |
1205 | store->extra_frag = tx.extra_frag; | 1201 | store->extra_frag = tx.extra_frag; |
1206 | store->num_extra_frag = tx.num_extra_frag; | 1202 | store->num_extra_frag = tx.num_extra_frag; |
1207 | store->last_frag_rate_idx = tx.last_frag_rate_idx; | ||
1208 | store->last_frag_rate_ctrl_probe = | ||
1209 | !!(tx.flags & IEEE80211_TX_PROBE_LAST_FRAG); | ||
1210 | } | 1203 | } |
1211 | out: | 1204 | out: |
1212 | rcu_read_unlock(); | 1205 | rcu_read_unlock(); |
@@ -1763,10 +1756,7 @@ void ieee80211_tx_pending(unsigned long data) | |||
1763 | store = &local->pending_packet[i]; | 1756 | store = &local->pending_packet[i]; |
1764 | tx.extra_frag = store->extra_frag; | 1757 | tx.extra_frag = store->extra_frag; |
1765 | tx.num_extra_frag = store->num_extra_frag; | 1758 | tx.num_extra_frag = store->num_extra_frag; |
1766 | tx.last_frag_rate_idx = store->last_frag_rate_idx; | ||
1767 | tx.flags = 0; | 1759 | tx.flags = 0; |
1768 | if (store->last_frag_rate_ctrl_probe) | ||
1769 | tx.flags |= IEEE80211_TX_PROBE_LAST_FRAG; | ||
1770 | ret = __ieee80211_tx(local, store->skb, &tx); | 1760 | ret = __ieee80211_tx(local, store->skb, &tx); |
1771 | if (ret) { | 1761 | if (ret) { |
1772 | if (ret == IEEE80211_TX_FRAG_AGAIN) | 1762 | if (ret == IEEE80211_TX_FRAG_AGAIN) |
@@ -1854,7 +1844,6 @@ struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw, | |||
1854 | struct ieee80211_sub_if_data *sdata = NULL; | 1844 | struct ieee80211_sub_if_data *sdata = NULL; |
1855 | struct ieee80211_if_ap *ap = NULL; | 1845 | struct ieee80211_if_ap *ap = NULL; |
1856 | struct ieee80211_if_sta *ifsta = NULL; | 1846 | struct ieee80211_if_sta *ifsta = NULL; |
1857 | struct rate_selection rsel; | ||
1858 | struct beacon_data *beacon; | 1847 | struct beacon_data *beacon; |
1859 | struct ieee80211_supported_band *sband; | 1848 | struct ieee80211_supported_band *sband; |
1860 | enum ieee80211_band band = local->hw.conf.channel->band; | 1849 | enum ieee80211_band band = local->hw.conf.channel->band; |
@@ -1958,32 +1947,23 @@ struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw, | |||
1958 | skb->do_not_encrypt = 1; | 1947 | skb->do_not_encrypt = 1; |
1959 | 1948 | ||
1960 | info->band = band; | 1949 | info->band = band; |
1961 | rate_control_get_rate(sdata, sband, NULL, skb, &rsel); | 1950 | /* |
1962 | 1951 | * XXX: For now, always use the lowest rate | |
1963 | if (unlikely(rsel.rate_idx < 0)) { | 1952 | */ |
1964 | if (net_ratelimit()) { | 1953 | info->control.rates[0].idx = 0; |
1965 | printk(KERN_DEBUG "%s: ieee80211_beacon_get: " | 1954 | info->control.rates[0].count = 1; |
1966 | "no rate found\n", | 1955 | info->control.rates[1].idx = -1; |
1967 | wiphy_name(local->hw.wiphy)); | 1956 | info->control.rates[2].idx = -1; |
1968 | } | 1957 | info->control.rates[3].idx = -1; |
1969 | dev_kfree_skb_any(skb); | 1958 | info->control.rates[4].idx = -1; |
1970 | skb = NULL; | 1959 | BUILD_BUG_ON(IEEE80211_TX_MAX_RATES != 5); |
1971 | goto out; | ||
1972 | } | ||
1973 | 1960 | ||
1974 | info->control.vif = vif; | 1961 | info->control.vif = vif; |
1975 | info->tx_rate_idx = rsel.rate_idx; | ||
1976 | 1962 | ||
1977 | info->flags |= IEEE80211_TX_CTL_NO_ACK; | 1963 | info->flags |= IEEE80211_TX_CTL_NO_ACK; |
1978 | info->flags |= IEEE80211_TX_CTL_CLEAR_PS_FILT; | 1964 | info->flags |= IEEE80211_TX_CTL_CLEAR_PS_FILT; |
1979 | info->flags |= IEEE80211_TX_CTL_ASSIGN_SEQ; | 1965 | info->flags |= IEEE80211_TX_CTL_ASSIGN_SEQ; |
1980 | if (sdata->vif.bss_conf.use_short_preamble && | 1966 | out: |
1981 | sband->bitrates[rsel.rate_idx].flags & IEEE80211_RATE_SHORT_PREAMBLE) | ||
1982 | info->flags |= IEEE80211_TX_CTL_SHORT_PREAMBLE; | ||
1983 | |||
1984 | info->control.retry_limit = 1; | ||
1985 | |||
1986 | out: | ||
1987 | rcu_read_unlock(); | 1967 | rcu_read_unlock(); |
1988 | return skb; | 1968 | return skb; |
1989 | } | 1969 | } |
diff --git a/net/mac80211/wext.c b/net/mac80211/wext.c index f7e442f80a17..31d2e74a1bc0 100644 --- a/net/mac80211/wext.c +++ b/net/mac80211/wext.c | |||
@@ -636,8 +636,8 @@ static int ieee80211_ioctl_giwrate(struct net_device *dev, | |||
636 | 636 | ||
637 | sta = sta_info_get(local, sdata->u.sta.bssid); | 637 | sta = sta_info_get(local, sdata->u.sta.bssid); |
638 | 638 | ||
639 | if (sta && sta->last_txrate_idx < sband->n_bitrates) | 639 | if (sta && !(sta->last_tx_rate.flags & IEEE80211_TX_RC_MCS)) |
640 | rate->value = sband->bitrates[sta->last_txrate_idx].bitrate; | 640 | rate->value = sband->bitrates[sta->last_tx_rate.idx].bitrate; |
641 | else | 641 | else |
642 | rate->value = 0; | 642 | rate->value = 0; |
643 | 643 | ||