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>
This commit is contained in:
Simon Wunderlich
2013-07-08 16:55:51 +02:00
committed by Johannes Berg
parent 3de805cf96
commit 438b61b770
5 changed files with 90 additions and 25 deletions

View File

@@ -382,14 +382,18 @@ minstrel_get_rate(void *priv, struct ieee80211_sta *sta,
static void
calc_rate_durations(enum ieee80211_band band,
struct minstrel_rate *d,
struct ieee80211_rate *rate)
struct ieee80211_rate *rate,
struct cfg80211_chan_def *chandef)
{
int erp = !!(rate->flags & IEEE80211_RATE_ERP_G);
int shift = ieee80211_chandef_get_shift(chandef);
d->perfect_tx_time = ieee80211_frame_duration(band, 1200,
rate->bitrate, erp, 1);
DIV_ROUND_UP(rate->bitrate, 1 << shift), erp, 1,
shift);
d->ack_time = ieee80211_frame_duration(band, 10,
rate->bitrate, erp, 1);
DIV_ROUND_UP(rate->bitrate, 1 << shift), erp, 1,
shift);
}
static void
@@ -425,14 +429,17 @@ minstrel_rate_init(void *priv, struct ieee80211_supported_band *sband,
struct ieee80211_rate *ctl_rate;
unsigned int i, n = 0;
unsigned int t_slot = 9; /* FIXME: get real slot time */
u32 rate_flags;
mi->sta = sta;
mi->lowest_rix = rate_lowest_index(sband, sta);
ctl_rate = &sband->bitrates[mi->lowest_rix];
mi->sp_ack_dur = ieee80211_frame_duration(sband->band, 10,
ctl_rate->bitrate,
!!(ctl_rate->flags & IEEE80211_RATE_ERP_G), 1);
!!(ctl_rate->flags & IEEE80211_RATE_ERP_G), 1,
ieee80211_chandef_get_shift(chandef));
rate_flags = ieee80211_chandef_rate_flags(&mp->hw->conf.chandef);
memset(mi->max_tp_rate, 0, sizeof(mi->max_tp_rate));
mi->max_prob_rate = 0;
@@ -441,15 +448,22 @@ minstrel_rate_init(void *priv, struct ieee80211_supported_band *sband,
unsigned int tx_time = 0, tx_time_cts = 0, tx_time_rtscts = 0;
unsigned int tx_time_single;
unsigned int cw = mp->cw_min;
int shift;
if (!rate_supported(sta, sband->band, i))
continue;
if ((rate_flags & sband->bitrates[i].flags) != rate_flags)
continue;
n++;
memset(mr, 0, sizeof(*mr));
mr->rix = i;
mr->bitrate = sband->bitrates[i].bitrate / 5;
calc_rate_durations(sband->band, mr, &sband->bitrates[i]);
shift = ieee80211_chandef_get_shift(chandef);
mr->bitrate = DIV_ROUND_UP(sband->bitrates[i].bitrate,
(1 << shift) * 5);
calc_rate_durations(sband->band, mr, &sband->bitrates[i],
chandef);
/* calculate maximum number of retransmissions before
* fallback (based on maximum segment size) */
@@ -547,6 +561,7 @@ minstrel_init_cck_rates(struct minstrel_priv *mp)
{
static const int bitrates[4] = { 10, 20, 55, 110 };
struct ieee80211_supported_band *sband;
u32 rate_flags = ieee80211_chandef_rate_flags(&mp->hw->conf.chandef);
int i, j;
sband = mp->hw->wiphy->bands[IEEE80211_BAND_2GHZ];
@@ -559,6 +574,9 @@ minstrel_init_cck_rates(struct minstrel_priv *mp)
if (rate->flags & IEEE80211_RATE_ERP_G)
continue;
if ((rate_flags & sband->bitrates[i].flags) != rate_flags)
continue;
for (j = 0; j < ARRAY_SIZE(bitrates); j++) {
if (rate->bitrate != bitrates[j])
continue;