|
@@ -3517,6 +3517,101 @@ static int nl80211_set_mesh_config(void *priv,
|
|
|
#endif /* CONFIG_MESH */
|
|
|
|
|
|
|
|
|
+static int nl80211_put_beacon_rate(struct nl_msg *msg, const u64 flags,
|
|
|
+ struct wpa_driver_ap_params *params)
|
|
|
+{
|
|
|
+ struct nlattr *bands, *band;
|
|
|
+ struct nl80211_txrate_vht vht_rate;
|
|
|
+
|
|
|
+ if (!params->freq ||
|
|
|
+ (params->beacon_rate == 0 &&
|
|
|
+ params->rate_type == BEACON_RATE_LEGACY))
|
|
|
+ return 0;
|
|
|
+
|
|
|
+ bands = nla_nest_start(msg, NL80211_ATTR_TX_RATES);
|
|
|
+ if (!bands)
|
|
|
+ return -1;
|
|
|
+
|
|
|
+ switch (params->freq->mode) {
|
|
|
+ case HOSTAPD_MODE_IEEE80211B:
|
|
|
+ case HOSTAPD_MODE_IEEE80211G:
|
|
|
+ band = nla_nest_start(msg, NL80211_BAND_2GHZ);
|
|
|
+ break;
|
|
|
+ case HOSTAPD_MODE_IEEE80211A:
|
|
|
+ band = nla_nest_start(msg, NL80211_BAND_5GHZ);
|
|
|
+ break;
|
|
|
+ case HOSTAPD_MODE_IEEE80211AD:
|
|
|
+ band = nla_nest_start(msg, NL80211_BAND_60GHZ);
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!band)
|
|
|
+ return -1;
|
|
|
+
|
|
|
+ os_memset(&vht_rate, 0, sizeof(vht_rate));
|
|
|
+
|
|
|
+ switch (params->rate_type) {
|
|
|
+ case BEACON_RATE_LEGACY:
|
|
|
+ if (!(flags & WPA_DRIVER_FLAGS_BEACON_RATE_LEGACY)) {
|
|
|
+ wpa_printf(MSG_INFO,
|
|
|
+ "nl80211: Driver does not support setting Beacon frame rate (legacy)");
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (nla_put_u8(msg, NL80211_TXRATE_LEGACY,
|
|
|
+ (u8) params->beacon_rate / 5) ||
|
|
|
+ nla_put(msg, NL80211_TXRATE_HT, 0, NULL) ||
|
|
|
+ (params->freq->vht_enabled &&
|
|
|
+ nla_put(msg, NL80211_TXRATE_VHT, sizeof(vht_rate),
|
|
|
+ &vht_rate)))
|
|
|
+ return -1;
|
|
|
+
|
|
|
+ wpa_printf(MSG_DEBUG, " * beacon_rate = legacy:%u (* 100 kbps)",
|
|
|
+ params->beacon_rate);
|
|
|
+ break;
|
|
|
+ case BEACON_RATE_HT:
|
|
|
+ if (!(flags & WPA_DRIVER_FLAGS_BEACON_RATE_HT)) {
|
|
|
+ wpa_printf(MSG_INFO,
|
|
|
+ "nl80211: Driver does not support setting Beacon frame rate (HT)");
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+ if (nla_put(msg, NL80211_TXRATE_LEGACY, 0, NULL) ||
|
|
|
+ nla_put_u8(msg, NL80211_TXRATE_HT, params->beacon_rate) ||
|
|
|
+ (params->freq->vht_enabled &&
|
|
|
+ nla_put(msg, NL80211_TXRATE_VHT, sizeof(vht_rate),
|
|
|
+ &vht_rate)))
|
|
|
+ return -1;
|
|
|
+ wpa_printf(MSG_DEBUG, " * beacon_rate = HT-MCS %u",
|
|
|
+ params->beacon_rate);
|
|
|
+ break;
|
|
|
+ case BEACON_RATE_VHT:
|
|
|
+ if (!(flags & WPA_DRIVER_FLAGS_BEACON_RATE_VHT)) {
|
|
|
+ wpa_printf(MSG_INFO,
|
|
|
+ "nl80211: Driver does not support setting Beacon frame rate (VHT)");
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+ vht_rate.mcs[0] = BIT(params->beacon_rate);
|
|
|
+ if (nla_put(msg, NL80211_TXRATE_LEGACY, 0, NULL))
|
|
|
+ return -1;
|
|
|
+ if (nla_put(msg, NL80211_TXRATE_HT, 0, NULL))
|
|
|
+ return -1;
|
|
|
+ if (nla_put(msg, NL80211_TXRATE_VHT, sizeof(vht_rate),
|
|
|
+ &vht_rate))
|
|
|
+ return -1;
|
|
|
+ wpa_printf(MSG_DEBUG, " * beacon_rate = VHT-MCS %u",
|
|
|
+ params->beacon_rate);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ nla_nest_end(msg, band);
|
|
|
+ nla_nest_end(msg, bands);
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
static int wpa_driver_nl80211_set_ap(void *priv,
|
|
|
struct wpa_driver_ap_params *params)
|
|
|
{
|
|
@@ -3547,6 +3642,8 @@ static int wpa_driver_nl80211_set_ap(void *priv,
|
|
|
params->tail, params->tail_len);
|
|
|
wpa_printf(MSG_DEBUG, "nl80211: ifindex=%d", bss->ifindex);
|
|
|
wpa_printf(MSG_DEBUG, "nl80211: beacon_int=%d", params->beacon_int);
|
|
|
+ wpa_printf(MSG_DEBUG, "nl80211: beacon_rate=%u", params->beacon_rate);
|
|
|
+ wpa_printf(MSG_DEBUG, "nl80211: rate_type=%d", params->rate_type);
|
|
|
wpa_printf(MSG_DEBUG, "nl80211: dtim_period=%d", params->dtim_period);
|
|
|
wpa_hexdump_ascii(MSG_DEBUG, "nl80211: ssid",
|
|
|
params->ssid, params->ssid_len);
|
|
@@ -3556,6 +3653,7 @@ static int wpa_driver_nl80211_set_ap(void *priv,
|
|
|
nla_put(msg, NL80211_ATTR_BEACON_TAIL, params->tail_len,
|
|
|
params->tail) ||
|
|
|
nl80211_put_beacon_int(msg, params->beacon_int) ||
|
|
|
+ nl80211_put_beacon_rate(msg, drv->capa.flags, params) ||
|
|
|
nl80211_put_dtim_period(msg, params->dtim_period) ||
|
|
|
nla_put(msg, NL80211_ATTR_SSID, params->ssid_len, params->ssid))
|
|
|
goto fail;
|