diff options
| -rw-r--r-- | include/net/cfg80211.h | 4 | ||||
| -rw-r--r-- | include/uapi/linux/nl80211.h | 17 | ||||
| -rw-r--r-- | net/wireless/nl80211.c | 46 |
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 | */ |
| 717 | struct cfg80211_ap_settings { | 717 | struct 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 | ||
| 3572 | static int validate_beacon_tx_rate(struct cfg80211_ap_settings *params) | 3572 | static 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(¶ms); | 3862 | err = validate_beacon_tx_rate(rdev, params.chandef.chan->band, |
| 3863 | ¶ms.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 | ||
