diff options
author | Simon Wunderlich <simon.wunderlich@s2003.tu-chemnitz.de> | 2013-07-08 10:55:51 -0400 |
---|---|---|
committer | Johannes Berg <johannes.berg@intel.com> | 2013-07-16 02:58:04 -0400 |
commit | 438b61b77082e70d2a408cc77b8c5faac312e940 (patch) | |
tree | 2a4575f29605a16fc051a6b81c71d0f3b31d7d77 /net/mac80211 | |
parent | 3de805cf965d69c8d3d7d69368d5fd2c925a2d5a (diff) |
mac80211: fix timing for 5 MHz and 10 MHz channels
according to IEEE 802.11-2012 section 18, various timings change
when using 5 MHz and 10 MHz. Reflect this by using a "shift" when
calculating durations.
Signed-off-by: Simon Wunderlich <siwu@hrz.tu-chemnitz.de>
Signed-off-by: Mathias Kretschmer <mathias.kretschmer@fokus.fraunhofer.de>
Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
Diffstat (limited to 'net/mac80211')
-rw-r--r-- | net/mac80211/ieee80211_i.h | 31 | ||||
-rw-r--r-- | net/mac80211/rc80211_minstrel.c | 30 | ||||
-rw-r--r-- | net/mac80211/rc80211_minstrel_ht.c | 5 | ||||
-rw-r--r-- | net/mac80211/tx.c | 10 | ||||
-rw-r--r-- | net/mac80211/util.c | 39 |
5 files changed, 90 insertions, 25 deletions
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 683751a1eceb..338e7ca21ea5 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h | |||
@@ -812,6 +812,34 @@ ieee80211_get_sdata_band(struct ieee80211_sub_if_data *sdata) | |||
812 | return band; | 812 | return band; |
813 | } | 813 | } |
814 | 814 | ||
815 | static inline int | ||
816 | ieee80211_chandef_get_shift(struct cfg80211_chan_def *chandef) | ||
817 | { | ||
818 | switch (chandef->width) { | ||
819 | case NL80211_CHAN_WIDTH_5: | ||
820 | return 2; | ||
821 | case NL80211_CHAN_WIDTH_10: | ||
822 | return 1; | ||
823 | default: | ||
824 | return 0; | ||
825 | } | ||
826 | } | ||
827 | |||
828 | static inline int | ||
829 | ieee80211_vif_get_shift(struct ieee80211_vif *vif) | ||
830 | { | ||
831 | struct ieee80211_chanctx_conf *chanctx_conf; | ||
832 | int shift = 0; | ||
833 | |||
834 | rcu_read_lock(); | ||
835 | chanctx_conf = rcu_dereference(vif->chanctx_conf); | ||
836 | if (chanctx_conf) | ||
837 | shift = ieee80211_chandef_get_shift(&chanctx_conf->def); | ||
838 | rcu_read_unlock(); | ||
839 | |||
840 | return shift; | ||
841 | } | ||
842 | |||
815 | enum sdata_queue_type { | 843 | enum sdata_queue_type { |
816 | IEEE80211_SDATA_QUEUE_TYPE_FRAME = 0, | 844 | IEEE80211_SDATA_QUEUE_TYPE_FRAME = 0, |
817 | IEEE80211_SDATA_QUEUE_AGG_START = 1, | 845 | IEEE80211_SDATA_QUEUE_AGG_START = 1, |
@@ -1468,7 +1496,8 @@ extern void *mac80211_wiphy_privid; /* for wiphy privid */ | |||
1468 | u8 *ieee80211_get_bssid(struct ieee80211_hdr *hdr, size_t len, | 1496 | u8 *ieee80211_get_bssid(struct ieee80211_hdr *hdr, size_t len, |
1469 | enum nl80211_iftype type); | 1497 | enum nl80211_iftype type); |
1470 | int ieee80211_frame_duration(enum ieee80211_band band, size_t len, | 1498 | int ieee80211_frame_duration(enum ieee80211_band band, size_t len, |
1471 | int rate, int erp, int short_preamble); | 1499 | int rate, int erp, int short_preamble, |
1500 | int shift); | ||
1472 | void mac80211_ev_michael_mic_failure(struct ieee80211_sub_if_data *sdata, int keyidx, | 1501 | void mac80211_ev_michael_mic_failure(struct ieee80211_sub_if_data *sdata, int keyidx, |
1473 | struct ieee80211_hdr *hdr, const u8 *tsc, | 1502 | struct ieee80211_hdr *hdr, const u8 *tsc, |
1474 | gfp_t gfp); | 1503 | gfp_t gfp); |
diff --git a/net/mac80211/rc80211_minstrel.c b/net/mac80211/rc80211_minstrel.c index 5b25966add10..a507376d5316 100644 --- a/net/mac80211/rc80211_minstrel.c +++ b/net/mac80211/rc80211_minstrel.c | |||
@@ -382,14 +382,18 @@ minstrel_get_rate(void *priv, struct ieee80211_sta *sta, | |||
382 | static void | 382 | static void |
383 | calc_rate_durations(enum ieee80211_band band, | 383 | calc_rate_durations(enum ieee80211_band band, |
384 | struct minstrel_rate *d, | 384 | struct minstrel_rate *d, |
385 | struct ieee80211_rate *rate) | 385 | struct ieee80211_rate *rate, |
386 | struct cfg80211_chan_def *chandef) | ||
386 | { | 387 | { |
387 | int erp = !!(rate->flags & IEEE80211_RATE_ERP_G); | 388 | int erp = !!(rate->flags & IEEE80211_RATE_ERP_G); |
389 | int shift = ieee80211_chandef_get_shift(chandef); | ||
388 | 390 | ||
389 | d->perfect_tx_time = ieee80211_frame_duration(band, 1200, | 391 | d->perfect_tx_time = ieee80211_frame_duration(band, 1200, |
390 | rate->bitrate, erp, 1); | 392 | DIV_ROUND_UP(rate->bitrate, 1 << shift), erp, 1, |
393 | shift); | ||
391 | d->ack_time = ieee80211_frame_duration(band, 10, | 394 | d->ack_time = ieee80211_frame_duration(band, 10, |
392 | rate->bitrate, erp, 1); | 395 | DIV_ROUND_UP(rate->bitrate, 1 << shift), erp, 1, |
396 | shift); | ||
393 | } | 397 | } |
394 | 398 | ||
395 | static void | 399 | static void |
@@ -425,14 +429,17 @@ minstrel_rate_init(void *priv, struct ieee80211_supported_band *sband, | |||
425 | struct ieee80211_rate *ctl_rate; | 429 | struct ieee80211_rate *ctl_rate; |
426 | unsigned int i, n = 0; | 430 | unsigned int i, n = 0; |
427 | unsigned int t_slot = 9; /* FIXME: get real slot time */ | 431 | unsigned int t_slot = 9; /* FIXME: get real slot time */ |
432 | u32 rate_flags; | ||
428 | 433 | ||
429 | mi->sta = sta; | 434 | mi->sta = sta; |
430 | mi->lowest_rix = rate_lowest_index(sband, sta); | 435 | mi->lowest_rix = rate_lowest_index(sband, sta); |
431 | ctl_rate = &sband->bitrates[mi->lowest_rix]; | 436 | ctl_rate = &sband->bitrates[mi->lowest_rix]; |
432 | mi->sp_ack_dur = ieee80211_frame_duration(sband->band, 10, | 437 | mi->sp_ack_dur = ieee80211_frame_duration(sband->band, 10, |
433 | ctl_rate->bitrate, | 438 | ctl_rate->bitrate, |
434 | !!(ctl_rate->flags & IEEE80211_RATE_ERP_G), 1); | 439 | !!(ctl_rate->flags & IEEE80211_RATE_ERP_G), 1, |
440 | ieee80211_chandef_get_shift(chandef)); | ||
435 | 441 | ||
442 | rate_flags = ieee80211_chandef_rate_flags(&mp->hw->conf.chandef); | ||
436 | memset(mi->max_tp_rate, 0, sizeof(mi->max_tp_rate)); | 443 | memset(mi->max_tp_rate, 0, sizeof(mi->max_tp_rate)); |
437 | mi->max_prob_rate = 0; | 444 | mi->max_prob_rate = 0; |
438 | 445 | ||
@@ -441,15 +448,22 @@ minstrel_rate_init(void *priv, struct ieee80211_supported_band *sband, | |||
441 | unsigned int tx_time = 0, tx_time_cts = 0, tx_time_rtscts = 0; | 448 | unsigned int tx_time = 0, tx_time_cts = 0, tx_time_rtscts = 0; |
442 | unsigned int tx_time_single; | 449 | unsigned int tx_time_single; |
443 | unsigned int cw = mp->cw_min; | 450 | unsigned int cw = mp->cw_min; |
451 | int shift; | ||
444 | 452 | ||
445 | if (!rate_supported(sta, sband->band, i)) | 453 | if (!rate_supported(sta, sband->band, i)) |
446 | continue; | 454 | continue; |
455 | if ((rate_flags & sband->bitrates[i].flags) != rate_flags) | ||
456 | continue; | ||
457 | |||
447 | n++; | 458 | n++; |
448 | memset(mr, 0, sizeof(*mr)); | 459 | memset(mr, 0, sizeof(*mr)); |
449 | 460 | ||
450 | mr->rix = i; | 461 | mr->rix = i; |
451 | mr->bitrate = sband->bitrates[i].bitrate / 5; | 462 | shift = ieee80211_chandef_get_shift(chandef); |
452 | calc_rate_durations(sband->band, mr, &sband->bitrates[i]); | 463 | mr->bitrate = DIV_ROUND_UP(sband->bitrates[i].bitrate, |
464 | (1 << shift) * 5); | ||
465 | calc_rate_durations(sband->band, mr, &sband->bitrates[i], | ||
466 | chandef); | ||
453 | 467 | ||
454 | /* calculate maximum number of retransmissions before | 468 | /* calculate maximum number of retransmissions before |
455 | * fallback (based on maximum segment size) */ | 469 | * fallback (based on maximum segment size) */ |
@@ -547,6 +561,7 @@ minstrel_init_cck_rates(struct minstrel_priv *mp) | |||
547 | { | 561 | { |
548 | static const int bitrates[4] = { 10, 20, 55, 110 }; | 562 | static const int bitrates[4] = { 10, 20, 55, 110 }; |
549 | struct ieee80211_supported_band *sband; | 563 | struct ieee80211_supported_band *sband; |
564 | u32 rate_flags = ieee80211_chandef_rate_flags(&mp->hw->conf.chandef); | ||
550 | int i, j; | 565 | int i, j; |
551 | 566 | ||
552 | sband = mp->hw->wiphy->bands[IEEE80211_BAND_2GHZ]; | 567 | sband = mp->hw->wiphy->bands[IEEE80211_BAND_2GHZ]; |
@@ -559,6 +574,9 @@ minstrel_init_cck_rates(struct minstrel_priv *mp) | |||
559 | if (rate->flags & IEEE80211_RATE_ERP_G) | 574 | if (rate->flags & IEEE80211_RATE_ERP_G) |
560 | continue; | 575 | continue; |
561 | 576 | ||
577 | if ((rate_flags & sband->bitrates[i].flags) != rate_flags) | ||
578 | continue; | ||
579 | |||
562 | for (j = 0; j < ARRAY_SIZE(bitrates); j++) { | 580 | for (j = 0; j < ARRAY_SIZE(bitrates); j++) { |
563 | if (rate->bitrate != bitrates[j]) | 581 | if (rate->bitrate != bitrates[j]) |
564 | continue; | 582 | continue; |
diff --git a/net/mac80211/rc80211_minstrel_ht.c b/net/mac80211/rc80211_minstrel_ht.c index 52562973fbd1..7475a7a33797 100644 --- a/net/mac80211/rc80211_minstrel_ht.c +++ b/net/mac80211/rc80211_minstrel_ht.c | |||
@@ -862,8 +862,9 @@ minstrel_ht_update_caps(void *priv, struct ieee80211_supported_band *sband, | |||
862 | mi->sta = sta; | 862 | mi->sta = sta; |
863 | mi->stats_update = jiffies; | 863 | mi->stats_update = jiffies; |
864 | 864 | ||
865 | ack_dur = ieee80211_frame_duration(sband->band, 10, 60, 1, 1); | 865 | ack_dur = ieee80211_frame_duration(sband->band, 10, 60, 1, 1, 0); |
866 | mi->overhead = ieee80211_frame_duration(sband->band, 0, 60, 1, 1) + ack_dur; | 866 | mi->overhead = ieee80211_frame_duration(sband->band, 0, 60, 1, 1, 0); |
867 | mi->overhead += ack_dur; | ||
867 | mi->overhead_rtscts = mi->overhead + 2 * ack_dur; | 868 | mi->overhead_rtscts = mi->overhead + 2 * ack_dur; |
868 | 869 | ||
869 | mi->avg_ampdu_len = MINSTREL_FRAC(1, 1); | 870 | mi->avg_ampdu_len = MINSTREL_FRAC(1, 1); |
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 4105d0ca963e..3523daa0b15c 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c | |||
@@ -40,7 +40,7 @@ static __le16 ieee80211_duration(struct ieee80211_tx_data *tx, | |||
40 | struct sk_buff *skb, int group_addr, | 40 | struct sk_buff *skb, int group_addr, |
41 | int next_frag_len) | 41 | int next_frag_len) |
42 | { | 42 | { |
43 | int rate, mrate, erp, dur, i; | 43 | int rate, mrate, erp, dur, i, shift; |
44 | struct ieee80211_rate *txrate; | 44 | struct ieee80211_rate *txrate; |
45 | struct ieee80211_local *local = tx->local; | 45 | struct ieee80211_local *local = tx->local; |
46 | struct ieee80211_supported_band *sband; | 46 | struct ieee80211_supported_band *sband; |
@@ -153,6 +153,8 @@ static __le16 ieee80211_duration(struct ieee80211_tx_data *tx, | |||
153 | rate = mrate; | 153 | rate = mrate; |
154 | } | 154 | } |
155 | 155 | ||
156 | shift = ieee80211_vif_get_shift(&tx->sdata->vif); | ||
157 | |||
156 | /* Don't calculate ACKs for QoS Frames with NoAck Policy set */ | 158 | /* Don't calculate ACKs for QoS Frames with NoAck Policy set */ |
157 | if (ieee80211_is_data_qos(hdr->frame_control) && | 159 | if (ieee80211_is_data_qos(hdr->frame_control) && |
158 | *(ieee80211_get_qos_ctl(hdr)) & IEEE80211_QOS_CTL_ACK_POLICY_NOACK) | 160 | *(ieee80211_get_qos_ctl(hdr)) & IEEE80211_QOS_CTL_ACK_POLICY_NOACK) |
@@ -162,7 +164,8 @@ static __le16 ieee80211_duration(struct ieee80211_tx_data *tx, | |||
162 | * (10 bytes + 4-byte FCS = 112 bits) plus SIFS; rounded up | 164 | * (10 bytes + 4-byte FCS = 112 bits) plus SIFS; rounded up |
163 | * to closest integer */ | 165 | * to closest integer */ |
164 | dur = ieee80211_frame_duration(sband->band, 10, rate, erp, | 166 | dur = ieee80211_frame_duration(sband->band, 10, rate, erp, |
165 | tx->sdata->vif.bss_conf.use_short_preamble); | 167 | tx->sdata->vif.bss_conf.use_short_preamble, |
168 | shift); | ||
166 | 169 | ||
167 | if (next_frag_len) { | 170 | if (next_frag_len) { |
168 | /* Frame is fragmented: duration increases with time needed to | 171 | /* Frame is fragmented: duration increases with time needed to |
@@ -171,7 +174,8 @@ static __le16 ieee80211_duration(struct ieee80211_tx_data *tx, | |||
171 | /* next fragment */ | 174 | /* next fragment */ |
172 | dur += ieee80211_frame_duration(sband->band, next_frag_len, | 175 | dur += ieee80211_frame_duration(sband->band, next_frag_len, |
173 | txrate->bitrate, erp, | 176 | txrate->bitrate, erp, |
174 | tx->sdata->vif.bss_conf.use_short_preamble); | 177 | tx->sdata->vif.bss_conf.use_short_preamble, |
178 | shift); | ||
175 | } | 179 | } |
176 | 180 | ||
177 | return cpu_to_le16(dur); | 181 | return cpu_to_le16(dur); |
diff --git a/net/mac80211/util.c b/net/mac80211/util.c index 22654452a561..61856e17a1e4 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c | |||
@@ -107,7 +107,8 @@ void ieee80211_tx_set_protected(struct ieee80211_tx_data *tx) | |||
107 | } | 107 | } |
108 | 108 | ||
109 | int ieee80211_frame_duration(enum ieee80211_band band, size_t len, | 109 | int ieee80211_frame_duration(enum ieee80211_band band, size_t len, |
110 | int rate, int erp, int short_preamble) | 110 | int rate, int erp, int short_preamble, |
111 | int shift) | ||
111 | { | 112 | { |
112 | int dur; | 113 | int dur; |
113 | 114 | ||
@@ -118,6 +119,9 @@ int ieee80211_frame_duration(enum ieee80211_band band, size_t len, | |||
118 | * | 119 | * |
119 | * rate is in 100 kbps, so divident is multiplied by 10 in the | 120 | * rate is in 100 kbps, so divident is multiplied by 10 in the |
120 | * DIV_ROUND_UP() operations. | 121 | * DIV_ROUND_UP() operations. |
122 | * | ||
123 | * shift may be 2 for 5 MHz channels or 1 for 10 MHz channels, and | ||
124 | * is assumed to be 0 otherwise. | ||
121 | */ | 125 | */ |
122 | 126 | ||
123 | if (band == IEEE80211_BAND_5GHZ || erp) { | 127 | if (band == IEEE80211_BAND_5GHZ || erp) { |
@@ -130,15 +134,21 @@ int ieee80211_frame_duration(enum ieee80211_band band, size_t len, | |||
130 | * TXTIME = T_PREAMBLE + T_SIGNAL + T_SYM x N_SYM + Signal Ext | 134 | * TXTIME = T_PREAMBLE + T_SIGNAL + T_SYM x N_SYM + Signal Ext |
131 | * | 135 | * |
132 | * T_SYM = 4 usec | 136 | * T_SYM = 4 usec |
133 | * 802.11a - 17.5.2: aSIFSTime = 16 usec | 137 | * 802.11a - 18.5.2: aSIFSTime = 16 usec |
134 | * 802.11g - 19.8.4: aSIFSTime = 10 usec + | 138 | * 802.11g - 19.8.4: aSIFSTime = 10 usec + |
135 | * signal ext = 6 usec | 139 | * signal ext = 6 usec |
136 | */ | 140 | */ |
137 | dur = 16; /* SIFS + signal ext */ | 141 | dur = 16; /* SIFS + signal ext */ |
138 | dur += 16; /* 17.3.2.3: T_PREAMBLE = 16 usec */ | 142 | dur += 16; /* IEEE 802.11-2012 18.3.2.4: T_PREAMBLE = 16 usec */ |
139 | dur += 4; /* 17.3.2.3: T_SIGNAL = 4 usec */ | 143 | dur += 4; /* IEEE 802.11-2012 18.3.2.4: T_SIGNAL = 4 usec */ |
140 | dur += 4 * DIV_ROUND_UP((16 + 8 * (len + 4) + 6) * 10, | 144 | dur += 4 * DIV_ROUND_UP((16 + 8 * (len + 4) + 6) * 10, |
141 | 4 * rate); /* T_SYM x N_SYM */ | 145 | 4 * rate); /* T_SYM x N_SYM */ |
146 | |||
147 | /* IEEE 802.11-2012 18.3.2.4: all values above are: | ||
148 | * * times 4 for 5 MHz | ||
149 | * * times 2 for 10 MHz | ||
150 | */ | ||
151 | dur *= 1 << shift; | ||
142 | } else { | 152 | } else { |
143 | /* | 153 | /* |
144 | * 802.11b or 802.11g with 802.11b compatibility: | 154 | * 802.11b or 802.11g with 802.11b compatibility: |
@@ -168,7 +178,7 @@ __le16 ieee80211_generic_frame_duration(struct ieee80211_hw *hw, | |||
168 | { | 178 | { |
169 | struct ieee80211_sub_if_data *sdata; | 179 | struct ieee80211_sub_if_data *sdata; |
170 | u16 dur; | 180 | u16 dur; |
171 | int erp; | 181 | int erp, shift = 0; |
172 | bool short_preamble = false; | 182 | bool short_preamble = false; |
173 | 183 | ||
174 | erp = 0; | 184 | erp = 0; |
@@ -177,10 +187,11 @@ __le16 ieee80211_generic_frame_duration(struct ieee80211_hw *hw, | |||
177 | short_preamble = sdata->vif.bss_conf.use_short_preamble; | 187 | short_preamble = sdata->vif.bss_conf.use_short_preamble; |
178 | if (sdata->flags & IEEE80211_SDATA_OPERATING_GMODE) | 188 | if (sdata->flags & IEEE80211_SDATA_OPERATING_GMODE) |
179 | erp = rate->flags & IEEE80211_RATE_ERP_G; | 189 | erp = rate->flags & IEEE80211_RATE_ERP_G; |
190 | shift = ieee80211_vif_get_shift(vif); | ||
180 | } | 191 | } |
181 | 192 | ||
182 | dur = ieee80211_frame_duration(band, frame_len, rate->bitrate, erp, | 193 | dur = ieee80211_frame_duration(band, frame_len, rate->bitrate, erp, |
183 | short_preamble); | 194 | short_preamble, shift); |
184 | 195 | ||
185 | return cpu_to_le16(dur); | 196 | return cpu_to_le16(dur); |
186 | } | 197 | } |
@@ -194,7 +205,7 @@ __le16 ieee80211_rts_duration(struct ieee80211_hw *hw, | |||
194 | struct ieee80211_rate *rate; | 205 | struct ieee80211_rate *rate; |
195 | struct ieee80211_sub_if_data *sdata; | 206 | struct ieee80211_sub_if_data *sdata; |
196 | bool short_preamble; | 207 | bool short_preamble; |
197 | int erp; | 208 | int erp, shift = 0; |
198 | u16 dur; | 209 | u16 dur; |
199 | struct ieee80211_supported_band *sband; | 210 | struct ieee80211_supported_band *sband; |
200 | 211 | ||
@@ -210,17 +221,18 @@ __le16 ieee80211_rts_duration(struct ieee80211_hw *hw, | |||
210 | short_preamble = sdata->vif.bss_conf.use_short_preamble; | 221 | short_preamble = sdata->vif.bss_conf.use_short_preamble; |
211 | if (sdata->flags & IEEE80211_SDATA_OPERATING_GMODE) | 222 | if (sdata->flags & IEEE80211_SDATA_OPERATING_GMODE) |
212 | erp = rate->flags & IEEE80211_RATE_ERP_G; | 223 | erp = rate->flags & IEEE80211_RATE_ERP_G; |
224 | shift = ieee80211_vif_get_shift(vif); | ||
213 | } | 225 | } |
214 | 226 | ||
215 | /* CTS duration */ | 227 | /* CTS duration */ |
216 | dur = ieee80211_frame_duration(sband->band, 10, rate->bitrate, | 228 | dur = ieee80211_frame_duration(sband->band, 10, rate->bitrate, |
217 | erp, short_preamble); | 229 | erp, short_preamble, shift); |
218 | /* Data frame duration */ | 230 | /* Data frame duration */ |
219 | dur += ieee80211_frame_duration(sband->band, frame_len, rate->bitrate, | 231 | dur += ieee80211_frame_duration(sband->band, frame_len, rate->bitrate, |
220 | erp, short_preamble); | 232 | erp, short_preamble, shift); |
221 | /* ACK duration */ | 233 | /* ACK duration */ |
222 | dur += ieee80211_frame_duration(sband->band, 10, rate->bitrate, | 234 | dur += ieee80211_frame_duration(sband->band, 10, rate->bitrate, |
223 | erp, short_preamble); | 235 | erp, short_preamble, shift); |
224 | 236 | ||
225 | return cpu_to_le16(dur); | 237 | return cpu_to_le16(dur); |
226 | } | 238 | } |
@@ -235,7 +247,7 @@ __le16 ieee80211_ctstoself_duration(struct ieee80211_hw *hw, | |||
235 | struct ieee80211_rate *rate; | 247 | struct ieee80211_rate *rate; |
236 | struct ieee80211_sub_if_data *sdata; | 248 | struct ieee80211_sub_if_data *sdata; |
237 | bool short_preamble; | 249 | bool short_preamble; |
238 | int erp; | 250 | int erp, shift = 0; |
239 | u16 dur; | 251 | u16 dur; |
240 | struct ieee80211_supported_band *sband; | 252 | struct ieee80211_supported_band *sband; |
241 | 253 | ||
@@ -250,15 +262,16 @@ __le16 ieee80211_ctstoself_duration(struct ieee80211_hw *hw, | |||
250 | short_preamble = sdata->vif.bss_conf.use_short_preamble; | 262 | short_preamble = sdata->vif.bss_conf.use_short_preamble; |
251 | if (sdata->flags & IEEE80211_SDATA_OPERATING_GMODE) | 263 | if (sdata->flags & IEEE80211_SDATA_OPERATING_GMODE) |
252 | erp = rate->flags & IEEE80211_RATE_ERP_G; | 264 | erp = rate->flags & IEEE80211_RATE_ERP_G; |
265 | shift = ieee80211_vif_get_shift(vif); | ||
253 | } | 266 | } |
254 | 267 | ||
255 | /* Data frame duration */ | 268 | /* Data frame duration */ |
256 | dur = ieee80211_frame_duration(sband->band, frame_len, rate->bitrate, | 269 | dur = ieee80211_frame_duration(sband->band, frame_len, rate->bitrate, |
257 | erp, short_preamble); | 270 | erp, short_preamble, shift); |
258 | if (!(frame_txctl->flags & IEEE80211_TX_CTL_NO_ACK)) { | 271 | if (!(frame_txctl->flags & IEEE80211_TX_CTL_NO_ACK)) { |
259 | /* ACK duration */ | 272 | /* ACK duration */ |
260 | dur += ieee80211_frame_duration(sband->band, 10, rate->bitrate, | 273 | dur += ieee80211_frame_duration(sband->band, 10, rate->bitrate, |
261 | erp, short_preamble); | 274 | erp, short_preamble, shift); |
262 | } | 275 | } |
263 | 276 | ||
264 | return cpu_to_le16(dur); | 277 | return cpu_to_le16(dur); |