Signed-off-by: Felix Fietkau <nbd@openwrt.org> SVN-Revision: 41022master
parent
22fcfab353
commit
5758b210e3
@ -1,202 +0,0 @@ |
|||||||
--- a/hostapd/config_file.c
|
|
||||||
+++ b/hostapd/config_file.c
|
|
||||||
@@ -2648,6 +2648,10 @@ static int hostapd_config_fill(struct ho
|
|
||||||
line);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
+ } else if (os_strcmp(buf, "dynamic_ht40") == 0) {
|
|
||||||
+ conf->dynamic_ht40 = atoi(pos);
|
|
||||||
+ if (conf->dynamic_ht40 == 1)
|
|
||||||
+ conf->dynamic_ht40 = 1500;
|
|
||||||
} else if (os_strcmp(buf, "require_ht") == 0) {
|
|
||||||
conf->require_ht = atoi(pos);
|
|
||||||
} else if (os_strcmp(buf, "obss_interval") == 0) {
|
|
||||||
--- a/src/ap/ap_config.h
|
|
||||||
+++ b/src/ap/ap_config.h
|
|
||||||
@@ -580,6 +580,7 @@ struct hostapd_config {
|
|
||||||
int ieee80211n;
|
|
||||||
int secondary_channel;
|
|
||||||
int require_ht;
|
|
||||||
+ int dynamic_ht40;
|
|
||||||
int obss_interval;
|
|
||||||
u32 vht_capab;
|
|
||||||
int ieee80211ac;
|
|
||||||
--- a/src/ap/hostapd.c
|
|
||||||
+++ b/src/ap/hostapd.c
|
|
||||||
@@ -22,6 +22,7 @@
|
|
||||||
#include "beacon.h"
|
|
||||||
#include "iapp.h"
|
|
||||||
#include "ieee802_1x.h"
|
|
||||||
+#include "ieee802_11.h"
|
|
||||||
#include "ieee802_11_auth.h"
|
|
||||||
#include "vlan_init.h"
|
|
||||||
#include "wpa_auth.h"
|
|
||||||
@@ -328,6 +329,7 @@ static void hostapd_cleanup(struct hosta
|
|
||||||
static void hostapd_cleanup_iface_partial(struct hostapd_iface *iface)
|
|
||||||
{
|
|
||||||
wpa_printf(MSG_DEBUG, "%s(%p)", __func__, iface);
|
|
||||||
+ hostapd_deinit_ht(iface);
|
|
||||||
hostapd_free_hw_features(iface->hw_features, iface->num_hw_features);
|
|
||||||
iface->hw_features = NULL;
|
|
||||||
os_free(iface->current_rates);
|
|
||||||
--- a/src/ap/hostapd.h
|
|
||||||
+++ b/src/ap/hostapd.h
|
|
||||||
@@ -330,6 +330,9 @@ struct hostapd_iface {
|
|
||||||
/* Overlapping BSS information */
|
|
||||||
int olbc_ht;
|
|
||||||
|
|
||||||
+ int force_20mhz;
|
|
||||||
+ struct os_time last_20mhz_trigger;
|
|
||||||
+
|
|
||||||
u16 ht_op_mode;
|
|
||||||
|
|
||||||
/* surveying helpers */
|
|
||||||
--- a/src/ap/ieee802_11.c
|
|
||||||
+++ b/src/ap/ieee802_11.c
|
|
||||||
@@ -1556,6 +1556,9 @@ static void handle_beacon(struct hostapd
|
|
||||||
sizeof(mgmt->u.beacon)), &elems,
|
|
||||||
0);
|
|
||||||
|
|
||||||
+ if (!elems.ht_capabilities)
|
|
||||||
+ hostapd_trigger_20mhz(hapd->iface);
|
|
||||||
+
|
|
||||||
ap_list_process_beacon(hapd->iface, mgmt, &elems, fi);
|
|
||||||
}
|
|
||||||
|
|
||||||
--- a/src/ap/ieee802_11.h
|
|
||||||
+++ b/src/ap/ieee802_11.h
|
|
||||||
@@ -83,4 +83,17 @@ int hostapd_update_time_adv(struct hosta
|
|
||||||
void hostapd_client_poll_ok(struct hostapd_data *hapd, const u8 *addr);
|
|
||||||
u8 * hostapd_eid_bss_max_idle_period(struct hostapd_data *hapd, u8 *eid);
|
|
||||||
|
|
||||||
+#ifdef CONFIG_IEEE80211N
|
|
||||||
+void hostapd_trigger_20mhz(struct hostapd_iface *iface);
|
|
||||||
+void hostapd_deinit_ht(struct hostapd_iface *iface);
|
|
||||||
+
|
|
||||||
+#else
|
|
||||||
+static inline void hostapd_deinit_ht(struct hostapd_iface *iface)
|
|
||||||
+{
|
|
||||||
+}
|
|
||||||
+static inline void hostapd_trigger_20mhz(struct hostapd_iface *iface)
|
|
||||||
+{
|
|
||||||
+}
|
|
||||||
+#endif /* CONFIG_IEEE80211N */
|
|
||||||
+
|
|
||||||
#endif /* IEEE802_11_H */
|
|
||||||
--- a/src/ap/ieee802_11_ht.c
|
|
||||||
+++ b/src/ap/ieee802_11_ht.c
|
|
||||||
@@ -13,9 +13,11 @@
|
|
||||||
#include "common/ieee802_11_defs.h"
|
|
||||||
#include "hostapd.h"
|
|
||||||
#include "ap_config.h"
|
|
||||||
+#include "ap_drv_ops.h"
|
|
||||||
#include "sta_info.h"
|
|
||||||
#include "beacon.h"
|
|
||||||
#include "ieee802_11.h"
|
|
||||||
+#include "utils/eloop.h"
|
|
||||||
|
|
||||||
|
|
||||||
u8 * hostapd_eid_ht_capabilities(struct hostapd_data *hapd, u8 *eid)
|
|
||||||
@@ -92,6 +94,9 @@ u8 * hostapd_eid_ht_operation(struct hos
|
|
||||||
|
|
||||||
oper->primary_chan = hapd->iconf->channel;
|
|
||||||
oper->operation_mode = host_to_le16(hapd->iface->ht_op_mode);
|
|
||||||
+ if (hapd->iface->force_20mhz)
|
|
||||||
+ goto skip;
|
|
||||||
+
|
|
||||||
if (hapd->iconf->secondary_channel == 1)
|
|
||||||
oper->ht_param |= HT_INFO_HT_PARAM_SECONDARY_CHNL_ABOVE |
|
|
||||||
HT_INFO_HT_PARAM_STA_CHNL_WIDTH;
|
|
||||||
@@ -99,6 +104,7 @@ u8 * hostapd_eid_ht_operation(struct hos
|
|
||||||
oper->ht_param |= HT_INFO_HT_PARAM_SECONDARY_CHNL_BELOW |
|
|
||||||
HT_INFO_HT_PARAM_STA_CHNL_WIDTH;
|
|
||||||
|
|
||||||
+skip:
|
|
||||||
pos += sizeof(*oper);
|
|
||||||
|
|
||||||
return pos;
|
|
||||||
@@ -288,3 +294,84 @@ void hostapd_get_ht_capab(struct hostapd
|
|
||||||
|
|
||||||
neg_ht_cap->ht_capabilities_info = host_to_le16(cap);
|
|
||||||
}
|
|
||||||
+
|
|
||||||
+static void hostapd_set_force_20mhz(struct hostapd_iface *iface);
|
|
||||||
+
|
|
||||||
+static void hostapd_restore_40mhz(void *eloop_data, void *user_ctx)
|
|
||||||
+{
|
|
||||||
+ struct hostapd_iface *iface = eloop_data;
|
|
||||||
+ struct os_time time;
|
|
||||||
+ int timeout;
|
|
||||||
+
|
|
||||||
+ if (!iface->last_20mhz_trigger.sec)
|
|
||||||
+ return;
|
|
||||||
+
|
|
||||||
+ os_get_time(&time);
|
|
||||||
+ timeout = iface->last_20mhz_trigger.sec + iface->conf->dynamic_ht40 -
|
|
||||||
+ time.sec;
|
|
||||||
+
|
|
||||||
+ if (timeout > 0) {
|
|
||||||
+ eloop_register_timeout(timeout, 0, hostapd_restore_40mhz,
|
|
||||||
+ iface, NULL);
|
|
||||||
+ return;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ iface->last_20mhz_trigger.sec = 0;
|
|
||||||
+ iface->last_20mhz_trigger.usec = 0;
|
|
||||||
+
|
|
||||||
+ iface->force_20mhz = 0;
|
|
||||||
+ hostapd_set_force_20mhz(iface);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static void hostapd_set_force_20mhz(struct hostapd_iface *iface)
|
|
||||||
+{
|
|
||||||
+ int secondary_channel;
|
|
||||||
+ int i;
|
|
||||||
+
|
|
||||||
+ ieee802_11_set_beacons(iface);
|
|
||||||
+
|
|
||||||
+ for (i = 0; i < iface->num_bss; i++) {
|
|
||||||
+ struct hostapd_data *hapd = iface->bss[i];
|
|
||||||
+
|
|
||||||
+ if (iface->force_20mhz)
|
|
||||||
+ secondary_channel = 0;
|
|
||||||
+ else
|
|
||||||
+ secondary_channel = hapd->iconf->secondary_channel;
|
|
||||||
+
|
|
||||||
+ if (hostapd_set_freq(hapd, hapd->iconf->hw_mode, iface->freq,
|
|
||||||
+ hapd->iconf->channel,
|
|
||||||
+ hapd->iconf->ieee80211n,
|
|
||||||
+ hapd->iconf->ieee80211ac,
|
|
||||||
+ secondary_channel,
|
|
||||||
+ hapd->iconf->vht_oper_chwidth,
|
|
||||||
+ hapd->iconf->vht_oper_centr_freq_seg0_idx,
|
|
||||||
+ hapd->iconf->vht_oper_centr_freq_seg1_idx)) {
|
|
||||||
+ wpa_printf(MSG_ERROR, "Could not set channel for "
|
|
||||||
+ "kernel driver");
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+void hostapd_deinit_ht(struct hostapd_iface *iface)
|
|
||||||
+{
|
|
||||||
+ eloop_cancel_timeout(hostapd_restore_40mhz, iface, NULL);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+void hostapd_trigger_20mhz(struct hostapd_iface *iface)
|
|
||||||
+{
|
|
||||||
+ if (!iface->conf->dynamic_ht40)
|
|
||||||
+ return;
|
|
||||||
+
|
|
||||||
+ if (!iface->force_20mhz) {
|
|
||||||
+ iface->force_20mhz = 1;
|
|
||||||
+ hostapd_set_force_20mhz(iface);
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ if (!iface->last_20mhz_trigger.sec) {
|
|
||||||
+ eloop_cancel_timeout(hostapd_restore_40mhz, iface, NULL);
|
|
||||||
+ eloop_register_timeout(iface->conf->dynamic_ht40, 0,
|
|
||||||
+ hostapd_restore_40mhz, iface, NULL);
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ os_get_time(&iface->last_20mhz_trigger);
|
|
||||||
+}
|
|
Loading…
Reference in new issue