diff options
Diffstat (limited to 'net/mac80211/rc80211_minstrel.c')
-rw-r--r-- | net/mac80211/rc80211_minstrel.c | 33 |
1 files changed, 26 insertions, 7 deletions
diff --git a/net/mac80211/rc80211_minstrel.c b/net/mac80211/rc80211_minstrel.c index e6512e2ffd20..8b5f7ef7c0c9 100644 --- a/net/mac80211/rc80211_minstrel.c +++ b/net/mac80211/rc80211_minstrel.c | |||
@@ -383,14 +383,18 @@ minstrel_get_rate(void *priv, struct ieee80211_sta *sta, | |||
383 | static void | 383 | static void |
384 | calc_rate_durations(enum ieee80211_band band, | 384 | calc_rate_durations(enum ieee80211_band band, |
385 | struct minstrel_rate *d, | 385 | struct minstrel_rate *d, |
386 | struct ieee80211_rate *rate) | 386 | struct ieee80211_rate *rate, |
387 | struct cfg80211_chan_def *chandef) | ||
387 | { | 388 | { |
388 | int erp = !!(rate->flags & IEEE80211_RATE_ERP_G); | 389 | int erp = !!(rate->flags & IEEE80211_RATE_ERP_G); |
390 | int shift = ieee80211_chandef_get_shift(chandef); | ||
389 | 391 | ||
390 | d->perfect_tx_time = ieee80211_frame_duration(band, 1200, | 392 | d->perfect_tx_time = ieee80211_frame_duration(band, 1200, |
391 | rate->bitrate, erp, 1); | 393 | DIV_ROUND_UP(rate->bitrate, 1 << shift), erp, 1, |
394 | shift); | ||
392 | d->ack_time = ieee80211_frame_duration(band, 10, | 395 | d->ack_time = ieee80211_frame_duration(band, 10, |
393 | rate->bitrate, erp, 1); | 396 | DIV_ROUND_UP(rate->bitrate, 1 << shift), erp, 1, |
397 | shift); | ||
394 | } | 398 | } |
395 | 399 | ||
396 | static void | 400 | static void |
@@ -418,21 +422,25 @@ init_sample_table(struct minstrel_sta_info *mi) | |||
418 | 422 | ||
419 | static void | 423 | static void |
420 | minstrel_rate_init(void *priv, struct ieee80211_supported_band *sband, | 424 | minstrel_rate_init(void *priv, struct ieee80211_supported_band *sband, |
421 | struct ieee80211_sta *sta, void *priv_sta) | 425 | struct cfg80211_chan_def *chandef, |
426 | struct ieee80211_sta *sta, void *priv_sta) | ||
422 | { | 427 | { |
423 | struct minstrel_sta_info *mi = priv_sta; | 428 | struct minstrel_sta_info *mi = priv_sta; |
424 | struct minstrel_priv *mp = priv; | 429 | struct minstrel_priv *mp = priv; |
425 | struct ieee80211_rate *ctl_rate; | 430 | struct ieee80211_rate *ctl_rate; |
426 | unsigned int i, n = 0; | 431 | unsigned int i, n = 0; |
427 | unsigned int t_slot = 9; /* FIXME: get real slot time */ | 432 | unsigned int t_slot = 9; /* FIXME: get real slot time */ |
433 | u32 rate_flags; | ||
428 | 434 | ||
429 | mi->sta = sta; | 435 | mi->sta = sta; |
430 | mi->lowest_rix = rate_lowest_index(sband, sta); | 436 | mi->lowest_rix = rate_lowest_index(sband, sta); |
431 | ctl_rate = &sband->bitrates[mi->lowest_rix]; | 437 | ctl_rate = &sband->bitrates[mi->lowest_rix]; |
432 | mi->sp_ack_dur = ieee80211_frame_duration(sband->band, 10, | 438 | mi->sp_ack_dur = ieee80211_frame_duration(sband->band, 10, |
433 | ctl_rate->bitrate, | 439 | ctl_rate->bitrate, |
434 | !!(ctl_rate->flags & IEEE80211_RATE_ERP_G), 1); | 440 | !!(ctl_rate->flags & IEEE80211_RATE_ERP_G), 1, |
441 | ieee80211_chandef_get_shift(chandef)); | ||
435 | 442 | ||
443 | rate_flags = ieee80211_chandef_rate_flags(&mp->hw->conf.chandef); | ||
436 | memset(mi->max_tp_rate, 0, sizeof(mi->max_tp_rate)); | 444 | memset(mi->max_tp_rate, 0, sizeof(mi->max_tp_rate)); |
437 | mi->max_prob_rate = 0; | 445 | mi->max_prob_rate = 0; |
438 | 446 | ||
@@ -441,15 +449,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; | 449 | unsigned int tx_time = 0, tx_time_cts = 0, tx_time_rtscts = 0; |
442 | unsigned int tx_time_single; | 450 | unsigned int tx_time_single; |
443 | unsigned int cw = mp->cw_min; | 451 | unsigned int cw = mp->cw_min; |
452 | int shift; | ||
444 | 453 | ||
445 | if (!rate_supported(sta, sband->band, i)) | 454 | if (!rate_supported(sta, sband->band, i)) |
446 | continue; | 455 | continue; |
456 | if ((rate_flags & sband->bitrates[i].flags) != rate_flags) | ||
457 | continue; | ||
458 | |||
447 | n++; | 459 | n++; |
448 | memset(mr, 0, sizeof(*mr)); | 460 | memset(mr, 0, sizeof(*mr)); |
449 | 461 | ||
450 | mr->rix = i; | 462 | mr->rix = i; |
451 | mr->bitrate = sband->bitrates[i].bitrate / 5; | 463 | shift = ieee80211_chandef_get_shift(chandef); |
452 | calc_rate_durations(sband->band, mr, &sband->bitrates[i]); | 464 | mr->bitrate = DIV_ROUND_UP(sband->bitrates[i].bitrate, |
465 | (1 << shift) * 5); | ||
466 | calc_rate_durations(sband->band, mr, &sband->bitrates[i], | ||
467 | chandef); | ||
453 | 468 | ||
454 | /* calculate maximum number of retransmissions before | 469 | /* calculate maximum number of retransmissions before |
455 | * fallback (based on maximum segment size) */ | 470 | * fallback (based on maximum segment size) */ |
@@ -547,6 +562,7 @@ minstrel_init_cck_rates(struct minstrel_priv *mp) | |||
547 | { | 562 | { |
548 | static const int bitrates[4] = { 10, 20, 55, 110 }; | 563 | static const int bitrates[4] = { 10, 20, 55, 110 }; |
549 | struct ieee80211_supported_band *sband; | 564 | struct ieee80211_supported_band *sband; |
565 | u32 rate_flags = ieee80211_chandef_rate_flags(&mp->hw->conf.chandef); | ||
550 | int i, j; | 566 | int i, j; |
551 | 567 | ||
552 | sband = mp->hw->wiphy->bands[IEEE80211_BAND_2GHZ]; | 568 | sband = mp->hw->wiphy->bands[IEEE80211_BAND_2GHZ]; |
@@ -559,6 +575,9 @@ minstrel_init_cck_rates(struct minstrel_priv *mp) | |||
559 | if (rate->flags & IEEE80211_RATE_ERP_G) | 575 | if (rate->flags & IEEE80211_RATE_ERP_G) |
560 | continue; | 576 | continue; |
561 | 577 | ||
578 | if ((rate_flags & sband->bitrates[i].flags) != rate_flags) | ||
579 | continue; | ||
580 | |||
562 | for (j = 0; j < ARRAY_SIZE(bitrates); j++) { | 581 | for (j = 0; j < ARRAY_SIZE(bitrates); j++) { |
563 | if (rate->bitrate != bitrates[j]) | 582 | if (rate->bitrate != bitrates[j]) |
564 | continue; | 583 | continue; |