diff options
| author | Johannes Berg <johannes.berg@intel.com> | 2015-01-15 10:14:02 -0500 |
|---|---|---|
| committer | Johannes Berg <johannes.berg@intel.com> | 2015-01-15 16:41:32 -0500 |
| commit | b51f3beecfbbfc946749a91fb444cb8917cf444f (patch) | |
| tree | 68ecd024ca26b392b48599dc3725e4416d053d1f /net | |
| parent | 97d910d0aaa619ca530d08e2b1125b8014ccb030 (diff) | |
cfg80211: change bandwidth reporting to explicit field
For some reason, we made the bandwidth separate flags, which
is rather confusing - a single rate cannot have different
bandwidths at the same time.
Change this to no longer be flags but use a separate field
for the bandwidth ('bw') instead.
While at it, add support for 5 and 10 MHz rates - these are
reported as regular legacy rates with their real bitrate,
but tagged as 5/10 now to make it easier to distinguish them.
In the nl80211 API, the flags are preserved, but the code
now can also clearly only set a single one of the flags.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net')
| -rw-r--r-- | net/mac80211/cfg.c | 31 | ||||
| -rw-r--r-- | net/mac80211/util.c | 25 | ||||
| -rw-r--r-- | net/wireless/nl80211.c | 40 | ||||
| -rw-r--r-- | net/wireless/util.c | 24 |
4 files changed, 84 insertions, 36 deletions
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 6d5076fbf87a..ff090ef1ea2c 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c | |||
| @@ -428,11 +428,13 @@ void sta_set_rate_info_tx(struct sta_info *sta, | |||
| 428 | rinfo->legacy = DIV_ROUND_UP(brate, 1 << shift); | 428 | rinfo->legacy = DIV_ROUND_UP(brate, 1 << shift); |
| 429 | } | 429 | } |
| 430 | if (rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH) | 430 | if (rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH) |
| 431 | rinfo->flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH; | 431 | rinfo->bw = RATE_INFO_BW_40; |
| 432 | if (rate->flags & IEEE80211_TX_RC_80_MHZ_WIDTH) | 432 | else if (rate->flags & IEEE80211_TX_RC_80_MHZ_WIDTH) |
| 433 | rinfo->flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH; | 433 | rinfo->bw = RATE_INFO_BW_80; |
| 434 | if (rate->flags & IEEE80211_TX_RC_160_MHZ_WIDTH) | 434 | else if (rate->flags & IEEE80211_TX_RC_160_MHZ_WIDTH) |
| 435 | rinfo->flags |= RATE_INFO_FLAGS_160_MHZ_WIDTH; | 435 | rinfo->bw = RATE_INFO_BW_160; |
| 436 | else | ||
| 437 | rinfo->bw = RATE_INFO_BW_20; | ||
| 436 | if (rate->flags & IEEE80211_TX_RC_SHORT_GI) | 438 | if (rate->flags & IEEE80211_TX_RC_SHORT_GI) |
| 437 | rinfo->flags |= RATE_INFO_FLAGS_SHORT_GI; | 439 | rinfo->flags |= RATE_INFO_FLAGS_SHORT_GI; |
| 438 | } | 440 | } |
| @@ -459,14 +461,21 @@ void sta_set_rate_info_rx(struct sta_info *sta, struct rate_info *rinfo) | |||
| 459 | rinfo->legacy = DIV_ROUND_UP(brate, 1 << shift); | 461 | rinfo->legacy = DIV_ROUND_UP(brate, 1 << shift); |
| 460 | } | 462 | } |
| 461 | 463 | ||
| 462 | if (sta->last_rx_rate_flag & RX_FLAG_40MHZ) | ||
| 463 | rinfo->flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH; | ||
| 464 | if (sta->last_rx_rate_flag & RX_FLAG_SHORT_GI) | 464 | if (sta->last_rx_rate_flag & RX_FLAG_SHORT_GI) |
| 465 | rinfo->flags |= RATE_INFO_FLAGS_SHORT_GI; | 465 | rinfo->flags |= RATE_INFO_FLAGS_SHORT_GI; |
| 466 | if (sta->last_rx_rate_vht_flag & RX_VHT_FLAG_80MHZ) | 466 | |
| 467 | rinfo->flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH; | 467 | if (sta->last_rx_rate_flag & RX_FLAG_5MHZ) |
| 468 | if (sta->last_rx_rate_vht_flag & RX_VHT_FLAG_160MHZ) | 468 | rinfo->bw = RATE_INFO_BW_5; |
| 469 | rinfo->flags |= RATE_INFO_FLAGS_160_MHZ_WIDTH; | 469 | else if (sta->last_rx_rate_flag & RX_FLAG_10MHZ) |
| 470 | rinfo->bw = RATE_INFO_BW_10; | ||
| 471 | else if (sta->last_rx_rate_flag & RX_FLAG_40MHZ) | ||
| 472 | rinfo->bw = RATE_INFO_BW_40; | ||
| 473 | else if (sta->last_rx_rate_vht_flag & RX_VHT_FLAG_80MHZ) | ||
| 474 | rinfo->bw = RATE_INFO_BW_80; | ||
| 475 | else if (sta->last_rx_rate_vht_flag & RX_VHT_FLAG_160MHZ) | ||
| 476 | rinfo->bw = RATE_INFO_BW_160; | ||
| 477 | else | ||
| 478 | rinfo->bw = RATE_INFO_BW_20; | ||
| 470 | } | 479 | } |
| 471 | 480 | ||
| 472 | static int ieee80211_dump_station(struct wiphy *wiphy, struct net_device *dev, | 481 | static int ieee80211_dump_station(struct wiphy *wiphy, struct net_device *dev, |
diff --git a/net/mac80211/util.c b/net/mac80211/util.c index db7216124736..fbd37d43dfce 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c | |||
| @@ -2541,7 +2541,9 @@ u64 ieee80211_calculate_rx_timestamp(struct ieee80211_local *local, | |||
| 2541 | ri.mcs = status->rate_idx; | 2541 | ri.mcs = status->rate_idx; |
| 2542 | ri.flags |= RATE_INFO_FLAGS_MCS; | 2542 | ri.flags |= RATE_INFO_FLAGS_MCS; |
| 2543 | if (status->flag & RX_FLAG_40MHZ) | 2543 | if (status->flag & RX_FLAG_40MHZ) |
| 2544 | ri.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH; | 2544 | ri.bw = RATE_INFO_BW_40; |
| 2545 | else | ||
| 2546 | ri.bw = RATE_INFO_BW_20; | ||
| 2545 | if (status->flag & RX_FLAG_SHORT_GI) | 2547 | if (status->flag & RX_FLAG_SHORT_GI) |
| 2546 | ri.flags |= RATE_INFO_FLAGS_SHORT_GI; | 2548 | ri.flags |= RATE_INFO_FLAGS_SHORT_GI; |
| 2547 | } else if (status->flag & RX_FLAG_VHT) { | 2549 | } else if (status->flag & RX_FLAG_VHT) { |
| @@ -2549,11 +2551,13 @@ u64 ieee80211_calculate_rx_timestamp(struct ieee80211_local *local, | |||
| 2549 | ri.mcs = status->rate_idx; | 2551 | ri.mcs = status->rate_idx; |
| 2550 | ri.nss = status->vht_nss; | 2552 | ri.nss = status->vht_nss; |
| 2551 | if (status->flag & RX_FLAG_40MHZ) | 2553 | if (status->flag & RX_FLAG_40MHZ) |
| 2552 | ri.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH; | 2554 | ri.bw = RATE_INFO_BW_40; |
| 2553 | if (status->vht_flag & RX_VHT_FLAG_80MHZ) | 2555 | else if (status->vht_flag & RX_VHT_FLAG_80MHZ) |
| 2554 | ri.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH; | 2556 | ri.bw = RATE_INFO_BW_80; |
| 2555 | if (status->vht_flag & RX_VHT_FLAG_160MHZ) | 2557 | else if (status->vht_flag & RX_VHT_FLAG_160MHZ) |
| 2556 | ri.flags |= RATE_INFO_FLAGS_160_MHZ_WIDTH; | 2558 | ri.bw = RATE_INFO_BW_160; |
| 2559 | else | ||
| 2560 | ri.bw = RATE_INFO_BW_20; | ||
| 2557 | if (status->flag & RX_FLAG_SHORT_GI) | 2561 | if (status->flag & RX_FLAG_SHORT_GI) |
| 2558 | ri.flags |= RATE_INFO_FLAGS_SHORT_GI; | 2562 | ri.flags |= RATE_INFO_FLAGS_SHORT_GI; |
| 2559 | } else { | 2563 | } else { |
| @@ -2561,10 +2565,15 @@ u64 ieee80211_calculate_rx_timestamp(struct ieee80211_local *local, | |||
| 2561 | int shift = 0; | 2565 | int shift = 0; |
| 2562 | int bitrate; | 2566 | int bitrate; |
| 2563 | 2567 | ||
| 2564 | if (status->flag & RX_FLAG_10MHZ) | 2568 | if (status->flag & RX_FLAG_10MHZ) { |
| 2565 | shift = 1; | 2569 | shift = 1; |
| 2566 | if (status->flag & RX_FLAG_5MHZ) | 2570 | ri.bw = RATE_INFO_BW_10; |
| 2571 | } else if (status->flag & RX_FLAG_5MHZ) { | ||
| 2567 | shift = 2; | 2572 | shift = 2; |
| 2573 | ri.bw = RATE_INFO_BW_5; | ||
| 2574 | } else { | ||
| 2575 | ri.bw = RATE_INFO_BW_20; | ||
| 2576 | } | ||
| 2568 | 2577 | ||
| 2569 | sband = local->hw.wiphy->bands[status->band]; | 2578 | sband = local->hw.wiphy->bands[status->band]; |
| 2570 | bitrate = sband->bitrates[status->rate_idx].bitrate; | 2579 | bitrate = sband->bitrates[status->rate_idx].bitrate; |
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 8998484ea970..8e56eeb583aa 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c | |||
| @@ -3578,6 +3578,7 @@ static bool nl80211_put_sta_rate(struct sk_buff *msg, struct rate_info *info, | |||
| 3578 | struct nlattr *rate; | 3578 | struct nlattr *rate; |
| 3579 | u32 bitrate; | 3579 | u32 bitrate; |
| 3580 | u16 bitrate_compat; | 3580 | u16 bitrate_compat; |
| 3581 | enum nl80211_attrs rate_flg; | ||
| 3581 | 3582 | ||
| 3582 | rate = nla_nest_start(msg, attr); | 3583 | rate = nla_nest_start(msg, attr); |
| 3583 | if (!rate) | 3584 | if (!rate) |
| @@ -3594,12 +3595,36 @@ static bool nl80211_put_sta_rate(struct sk_buff *msg, struct rate_info *info, | |||
| 3594 | nla_put_u16(msg, NL80211_RATE_INFO_BITRATE, bitrate_compat)) | 3595 | nla_put_u16(msg, NL80211_RATE_INFO_BITRATE, bitrate_compat)) |
| 3595 | return false; | 3596 | return false; |
| 3596 | 3597 | ||
| 3598 | switch (info->bw) { | ||
| 3599 | case RATE_INFO_BW_5: | ||
| 3600 | rate_flg = NL80211_RATE_INFO_5_MHZ_WIDTH; | ||
| 3601 | break; | ||
| 3602 | case RATE_INFO_BW_10: | ||
| 3603 | rate_flg = NL80211_RATE_INFO_10_MHZ_WIDTH; | ||
| 3604 | break; | ||
| 3605 | default: | ||
| 3606 | WARN_ON(1); | ||
| 3607 | /* fall through */ | ||
| 3608 | case RATE_INFO_BW_20: | ||
| 3609 | rate_flg = 0; | ||
| 3610 | break; | ||
| 3611 | case RATE_INFO_BW_40: | ||
| 3612 | rate_flg = NL80211_RATE_INFO_40_MHZ_WIDTH; | ||
| 3613 | break; | ||
| 3614 | case RATE_INFO_BW_80: | ||
| 3615 | rate_flg = NL80211_RATE_INFO_80_MHZ_WIDTH; | ||
| 3616 | break; | ||
| 3617 | case RATE_INFO_BW_160: | ||
| 3618 | rate_flg = NL80211_RATE_INFO_160_MHZ_WIDTH; | ||
| 3619 | break; | ||
| 3620 | } | ||
| 3621 | |||
| 3622 | if (rate_flg && nla_put_flag(msg, rate_flg)) | ||
| 3623 | return false; | ||
| 3624 | |||
| 3597 | if (info->flags & RATE_INFO_FLAGS_MCS) { | 3625 | if (info->flags & RATE_INFO_FLAGS_MCS) { |
| 3598 | if (nla_put_u8(msg, NL80211_RATE_INFO_MCS, info->mcs)) | 3626 | if (nla_put_u8(msg, NL80211_RATE_INFO_MCS, info->mcs)) |
| 3599 | return false; | 3627 | return false; |
| 3600 | if (info->flags & RATE_INFO_FLAGS_40_MHZ_WIDTH && | ||
| 3601 | nla_put_flag(msg, NL80211_RATE_INFO_40_MHZ_WIDTH)) | ||
| 3602 | return false; | ||
| 3603 | if (info->flags & RATE_INFO_FLAGS_SHORT_GI && | 3628 | if (info->flags & RATE_INFO_FLAGS_SHORT_GI && |
| 3604 | nla_put_flag(msg, NL80211_RATE_INFO_SHORT_GI)) | 3629 | nla_put_flag(msg, NL80211_RATE_INFO_SHORT_GI)) |
| 3605 | return false; | 3630 | return false; |
| @@ -3608,15 +3633,6 @@ static bool nl80211_put_sta_rate(struct sk_buff *msg, struct rate_info *info, | |||
| 3608 | return false; | 3633 | return false; |
| 3609 | if (nla_put_u8(msg, NL80211_RATE_INFO_VHT_NSS, info->nss)) | 3634 | if (nla_put_u8(msg, NL80211_RATE_INFO_VHT_NSS, info->nss)) |
| 3610 | return false; | 3635 | return false; |
| 3611 | if (info->flags & RATE_INFO_FLAGS_40_MHZ_WIDTH && | ||
| 3612 | nla_put_flag(msg, NL80211_RATE_INFO_40_MHZ_WIDTH)) | ||
| 3613 | return false; | ||
| 3614 | if (info->flags & RATE_INFO_FLAGS_80_MHZ_WIDTH && | ||
| 3615 | nla_put_flag(msg, NL80211_RATE_INFO_80_MHZ_WIDTH)) | ||
| 3616 | return false; | ||
| 3617 | if (info->flags & RATE_INFO_FLAGS_160_MHZ_WIDTH && | ||
| 3618 | nla_put_flag(msg, NL80211_RATE_INFO_160_MHZ_WIDTH)) | ||
| 3619 | return false; | ||
| 3620 | if (info->flags & RATE_INFO_FLAGS_SHORT_GI && | 3636 | if (info->flags & RATE_INFO_FLAGS_SHORT_GI && |
| 3621 | nla_put_flag(msg, NL80211_RATE_INFO_SHORT_GI)) | 3637 | nla_put_flag(msg, NL80211_RATE_INFO_SHORT_GI)) |
| 3622 | return false; | 3638 | return false; |
diff --git a/net/wireless/util.c b/net/wireless/util.c index 6942d48f1ac5..3535e8ade48f 100644 --- a/net/wireless/util.c +++ b/net/wireless/util.c | |||
| @@ -1073,9 +1073,24 @@ static u32 cfg80211_calculate_bitrate_vht(struct rate_info *rate) | |||
| 1073 | if (WARN_ON_ONCE(rate->mcs > 9)) | 1073 | if (WARN_ON_ONCE(rate->mcs > 9)) |
| 1074 | return 0; | 1074 | return 0; |
| 1075 | 1075 | ||
| 1076 | idx = rate->flags & RATE_INFO_FLAGS_160_MHZ_WIDTH ? 3 : | 1076 | switch (rate->bw) { |
| 1077 | rate->flags & RATE_INFO_FLAGS_80_MHZ_WIDTH ? 2 : | 1077 | case RATE_INFO_BW_160: |
| 1078 | rate->flags & RATE_INFO_FLAGS_40_MHZ_WIDTH ? 1 : 0; | 1078 | idx = 3; |
| 1079 | break; | ||
| 1080 | case RATE_INFO_BW_80: | ||
| 1081 | idx = 2; | ||
| 1082 | break; | ||
| 1083 | case RATE_INFO_BW_40: | ||
| 1084 | idx = 1; | ||
| 1085 | break; | ||
| 1086 | case RATE_INFO_BW_5: | ||
| 1087 | case RATE_INFO_BW_10: | ||
| 1088 | default: | ||
| 1089 | WARN_ON(1); | ||
| 1090 | /* fall through */ | ||
| 1091 | case RATE_INFO_BW_20: | ||
| 1092 | idx = 0; | ||
| 1093 | } | ||
| 1079 | 1094 | ||
| 1080 | bitrate = base[idx][rate->mcs]; | 1095 | bitrate = base[idx][rate->mcs]; |
| 1081 | bitrate *= rate->nss; | 1096 | bitrate *= rate->nss; |
| @@ -1106,8 +1121,7 @@ u32 cfg80211_calculate_bitrate(struct rate_info *rate) | |||
| 1106 | modulation = rate->mcs & 7; | 1121 | modulation = rate->mcs & 7; |
| 1107 | streams = (rate->mcs >> 3) + 1; | 1122 | streams = (rate->mcs >> 3) + 1; |
| 1108 | 1123 | ||
| 1109 | bitrate = (rate->flags & RATE_INFO_FLAGS_40_MHZ_WIDTH) ? | 1124 | bitrate = (rate->bw == RATE_INFO_BW_40) ? 13500000 : 6500000; |
| 1110 | 13500000 : 6500000; | ||
| 1111 | 1125 | ||
| 1112 | if (modulation < 4) | 1126 | if (modulation < 4) |
| 1113 | bitrate *= (modulation + 1); | 1127 | bitrate *= (modulation + 1); |
