aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2016-09-19 03:44:44 -0400
committerJohannes Berg <johannes.berg@intel.com>2016-09-26 04:23:48 -0400
commit8564e38206de2ff005a27c8d7c2ce3869a44f0dd (patch)
tree2c6a9ae667d5bf80a6789d1201dfb9a492ea99d1
parenta7c7fbff6a408d00431c705bbe3dfc5f51e3f1c4 (diff)
cfg80211: add checks for beacon rate, extend to mesh
The previous commit added support for specifying the beacon rate for AP mode. Add features checks to this, and extend it to also support the rate configuration for mesh networks. For IBSS it's not as simple due to joining etc., so that's not yet supported. Signed-off-by: Johannes Berg <johannes.berg@intel.com>
-rw-r--r--include/net/cfg80211.h4
-rw-r--r--include/uapi/linux/nl80211.h17
-rw-r--r--net/wireless/nl80211.c46
3 files changed, 54 insertions, 13 deletions
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index e0949c8bc2d1..ed37304fa09d 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -712,7 +712,7 @@ struct cfg80211_bitrate_mask {
712 * MAC address based access control 712 * MAC address based access control
713 * @pbss: If set, start as a PCP instead of AP. Relevant for DMG 713 * @pbss: If set, start as a PCP instead of AP. Relevant for DMG
714 * networks. 714 * networks.
715 * @beacon_rate: masks for setting user configured beacon tx rate. 715 * @beacon_rate: bitrate to be used for beacons
716 */ 716 */
717struct cfg80211_ap_settings { 717struct cfg80211_ap_settings {
718 struct cfg80211_chan_def chandef; 718 struct cfg80211_chan_def chandef;
@@ -1365,6 +1365,7 @@ struct mesh_config {
1365 * @beacon_interval: beacon interval to use 1365 * @beacon_interval: beacon interval to use
1366 * @mcast_rate: multicat rate for Mesh Node [6Mbps is the default for 802.11a] 1366 * @mcast_rate: multicat rate for Mesh Node [6Mbps is the default for 802.11a]
1367 * @basic_rates: basic rates to use when creating the mesh 1367 * @basic_rates: basic rates to use when creating the mesh
1368 * @beacon_rate: bitrate to be used for beacons
1368 * 1369 *
1369 * These parameters are fixed when the mesh is created. 1370 * These parameters are fixed when the mesh is created.
1370 */ 1371 */
@@ -1385,6 +1386,7 @@ struct mesh_setup {
1385 u16 beacon_interval; 1386 u16 beacon_interval;
1386 int mcast_rate[NUM_NL80211_BANDS]; 1387 int mcast_rate[NUM_NL80211_BANDS];
1387 u32 basic_rates; 1388 u32 basic_rates;
1389 struct cfg80211_bitrate_mask beacon_rate;
1388}; 1390};
1389 1391
1390/** 1392/**
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index 220694151434..ec10d1b2838f 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -1343,7 +1343,13 @@ enum nl80211_commands {
1343 * enum nl80211_band value is used as the index (nla_type() of the nested 1343 * enum nl80211_band value is used as the index (nla_type() of the nested
1344 * data. If a band is not included, it will be configured to allow all 1344 * data. If a band is not included, it will be configured to allow all
1345 * rates based on negotiated supported rates information. This attribute 1345 * rates based on negotiated supported rates information. This attribute
1346 * is used with %NL80211_CMD_SET_TX_BITRATE_MASK. 1346 * is used with %NL80211_CMD_SET_TX_BITRATE_MASK and with starting AP,
1347 * and joining mesh networks (not IBSS yet). In the later case, it must
1348 * specify just a single bitrate, which is to be used for the beacon.
1349 * The driver must also specify support for this with the extended
1350 * features NL80211_EXT_FEATURE_BEACON_RATE_LEGACY,
1351 * NL80211_EXT_FEATURE_BEACON_RATE_HT and
1352 * NL80211_EXT_FEATURE_BEACON_RATE_VHT.
1347 * 1353 *
1348 * @NL80211_ATTR_FRAME_MATCH: A binary attribute which typically must contain 1354 * @NL80211_ATTR_FRAME_MATCH: A binary attribute which typically must contain
1349 * at least one byte, currently used with @NL80211_CMD_REGISTER_FRAME. 1355 * at least one byte, currently used with @NL80211_CMD_REGISTER_FRAME.
@@ -4551,6 +4557,12 @@ enum nl80211_feature_flags {
4551 * (if available). 4557 * (if available).
4552 * @NL80211_EXT_FEATURE_SET_SCAN_DWELL: This driver supports configuration of 4558 * @NL80211_EXT_FEATURE_SET_SCAN_DWELL: This driver supports configuration of
4553 * channel dwell time. 4559 * channel dwell time.
4560 * @NL80211_EXT_FEATURE_BEACON_RATE_LEGACY: Driver supports beacon rate
4561 * configuration (AP/mesh), supporting a legacy (non HT/VHT) rate.
4562 * @NL80211_EXT_FEATURE_BEACON_RATE_HT: Driver supports beacon rate
4563 * configuration (AP/mesh) with HT rates.
4564 * @NL80211_EXT_FEATURE_BEACON_RATE_VHT: Driver supports beacon rate
4565 * configuration (AP/mesh) with VHT rates.
4554 * 4566 *
4555 * @NUM_NL80211_EXT_FEATURES: number of extended features. 4567 * @NUM_NL80211_EXT_FEATURES: number of extended features.
4556 * @MAX_NL80211_EXT_FEATURES: highest extended feature index. 4568 * @MAX_NL80211_EXT_FEATURES: highest extended feature index.
@@ -4562,6 +4574,9 @@ enum nl80211_ext_feature_index {
4562 NL80211_EXT_FEATURE_SCAN_START_TIME, 4574 NL80211_EXT_FEATURE_SCAN_START_TIME,
4563 NL80211_EXT_FEATURE_BSS_PARENT_TSF, 4575 NL80211_EXT_FEATURE_BSS_PARENT_TSF,
4564 NL80211_EXT_FEATURE_SET_SCAN_DWELL, 4576 NL80211_EXT_FEATURE_SET_SCAN_DWELL,
4577 NL80211_EXT_FEATURE_BEACON_RATE_LEGACY,
4578 NL80211_EXT_FEATURE_BEACON_RATE_HT,
4579 NL80211_EXT_FEATURE_BEACON_RATE_VHT,
4565 4580
4566 /* add new features before the definition below */ 4581 /* add new features before the definition below */
4567 NUM_NL80211_EXT_FEATURES, 4582 NUM_NL80211_EXT_FEATURES,
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index a10484da60c0..b8441e60b0f6 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -3569,13 +3569,12 @@ out:
3569 return 0; 3569 return 0;
3570} 3570}
3571 3571
3572static int validate_beacon_tx_rate(struct cfg80211_ap_settings *params) 3572static int validate_beacon_tx_rate(struct cfg80211_registered_device *rdev,
3573 enum nl80211_band band,
3574 struct cfg80211_bitrate_mask *beacon_rate)
3573{ 3575{
3574 u32 rate, count_ht, count_vht, i; 3576 u32 count_ht, count_vht, i;
3575 enum nl80211_band band; 3577 u32 rate = beacon_rate->control[band].legacy;
3576
3577 band = params->chandef.chan->band;
3578 rate = params->beacon_rate.control[band].legacy;
3579 3578
3580 /* Allow only one rate */ 3579 /* Allow only one rate */
3581 if (hweight32(rate) > 1) 3580 if (hweight32(rate) > 1)
@@ -3583,9 +3582,9 @@ static int validate_beacon_tx_rate(struct cfg80211_ap_settings *params)
3583 3582
3584 count_ht = 0; 3583 count_ht = 0;
3585 for (i = 0; i < IEEE80211_HT_MCS_MASK_LEN; i++) { 3584 for (i = 0; i < IEEE80211_HT_MCS_MASK_LEN; i++) {
3586 if (hweight8(params->beacon_rate.control[band].ht_mcs[i]) > 1) { 3585 if (hweight8(beacon_rate->control[band].ht_mcs[i]) > 1) {
3587 return -EINVAL; 3586 return -EINVAL;
3588 } else if (params->beacon_rate.control[band].ht_mcs[i]) { 3587 } else if (beacon_rate->control[band].ht_mcs[i]) {
3589 count_ht++; 3588 count_ht++;
3590 if (count_ht > 1) 3589 if (count_ht > 1)
3591 return -EINVAL; 3590 return -EINVAL;
@@ -3596,9 +3595,9 @@ static int validate_beacon_tx_rate(struct cfg80211_ap_settings *params)
3596 3595
3597 count_vht = 0; 3596 count_vht = 0;
3598 for (i = 0; i < NL80211_VHT_NSS_MAX; i++) { 3597 for (i = 0; i < NL80211_VHT_NSS_MAX; i++) {
3599 if (hweight16(params->beacon_rate.control[band].vht_mcs[i]) > 1) { 3598 if (hweight16(beacon_rate->control[band].vht_mcs[i]) > 1) {
3600 return -EINVAL; 3599 return -EINVAL;
3601 } else if (params->beacon_rate.control[band].vht_mcs[i]) { 3600 } else if (beacon_rate->control[band].vht_mcs[i]) {
3602 count_vht++; 3601 count_vht++;
3603 if (count_vht > 1) 3602 if (count_vht > 1)
3604 return -EINVAL; 3603 return -EINVAL;
@@ -3610,6 +3609,19 @@ static int validate_beacon_tx_rate(struct cfg80211_ap_settings *params)
3610 if ((count_ht && count_vht) || (!rate && !count_ht && !count_vht)) 3609 if ((count_ht && count_vht) || (!rate && !count_ht && !count_vht))
3611 return -EINVAL; 3610 return -EINVAL;
3612 3611
3612 if (rate &&
3613 !wiphy_ext_feature_isset(&rdev->wiphy,
3614 NL80211_EXT_FEATURE_BEACON_RATE_LEGACY))
3615 return -EINVAL;
3616 if (count_ht &&
3617 !wiphy_ext_feature_isset(&rdev->wiphy,
3618 NL80211_EXT_FEATURE_BEACON_RATE_HT))
3619 return -EINVAL;
3620 if (count_vht &&
3621 !wiphy_ext_feature_isset(&rdev->wiphy,
3622 NL80211_EXT_FEATURE_BEACON_RATE_VHT))
3623 return -EINVAL;
3624
3613 return 0; 3625 return 0;
3614} 3626}
3615 3627
@@ -3847,7 +3859,8 @@ static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info)
3847 if (err) 3859 if (err)
3848 return err; 3860 return err;
3849 3861
3850 err = validate_beacon_tx_rate(&params); 3862 err = validate_beacon_tx_rate(rdev, params.chandef.chan->band,
3863 &params.beacon_rate);
3851 if (err) 3864 if (err)
3852 return err; 3865 return err;
3853 } 3866 }
@@ -9406,6 +9419,17 @@ static int nl80211_join_mesh(struct sk_buff *skb, struct genl_info *info)
9406 return err; 9419 return err;
9407 } 9420 }
9408 9421
9422 if (info->attrs[NL80211_ATTR_TX_RATES]) {
9423 err = nl80211_parse_tx_bitrate_mask(info, &setup.beacon_rate);
9424 if (err)
9425 return err;
9426
9427 err = validate_beacon_tx_rate(rdev, setup.chandef.chan->band,
9428 &setup.beacon_rate);
9429 if (err)
9430 return err;
9431 }
9432
9409 return cfg80211_join_mesh(rdev, dev, &setup, &cfg); 9433 return cfg80211_join_mesh(rdev, dev, &setup, &cfg);
9410} 9434}
9411 9435