[RFC] hostapd: allow configuring driver to VHT
Johannes Berg
johannes
Tue Nov 20 13:07:50 PST 2012
From: Johannes Berg <johannes.berg at intel.com>
Signed-hostap: Johannes Berg <johannes.berg at intel.com>
---
src/ap/ap_drv_ops.c | 60 +++++++++++++++++++++++++++++++++++++++++++++++-----
src/ap/ap_drv_ops.h | 4 +++-
src/ap/hostapd.c | 6 +++++-
src/drivers/driver.h | 9 ++++++++
4 files changed, 72 insertions(+), 7 deletions(-)
diff --git a/src/ap/ap_drv_ops.c b/src/ap/ap_drv_ops.c
index 02da25b..7b927cf 100644
--- a/src/ap/ap_drv_ops.c
+++ b/src/ap/ap_drv_ops.c
@@ -454,19 +454,69 @@ int hostapd_flush(struct hostapd_data *hapd)
int hostapd_set_freq(struct hostapd_data *hapd, int mode, int freq,
- int channel, int ht_enabled, int sec_channel_offset)
+ int channel, int ht_enabled, int vht_enabled,
+ int sec_channel_offset, int vht_oper_chwidth,
+ int center_segment0, int center_segment1)
{
struct hostapd_freq_params data;
- if (hapd->driver == NULL)
- return 0;
- if (hapd->driver->set_freq == NULL)
- return 0;
+ int tmp;
+
os_memset(&data, 0, sizeof(data));
data.mode = mode;
data.freq = freq;
data.channel = channel;
data.ht_enabled = ht_enabled;
+ data.vht_enabled = vht_enabled;
data.sec_channel_offset = sec_channel_offset;
+ data.center_freq1 = freq + sec_channel_offset * 10;
+ data.center_freq2 = 0;
+ data.bandwidth = sec_channel_offset ? 40 : 20;
+
+ if (data.vht_enabled) switch (vht_oper_chwidth) {
+ case 0:
+ if (center_segment1)
+ return -1;
+ if (5000 + center_segment0 * 5 != data.center_freq1)
+ return -1;
+ break;
+ case 3:
+ data.center_freq2 = 5000 + center_segment1 * 5;
+ /* fall through */
+ case 1:
+ data.bandwidth = 80;
+ if (vht_oper_chwidth == 1 && center_segment1)
+ return -1;
+ if (vht_oper_chwidth == 3 && !center_segment1)
+ return -1;
+ if (!sec_channel_offset)
+ return -1;
+ /* primary 40 part must match the HT configuration */
+ tmp = (30 + freq - 5000 - center_segment0 * 5)/20;
+ tmp /= 2;
+ if (data.center_freq1 != 5000 +
+ center_segment0 * 5 - 20 + 40 * tmp)
+ return -1;
+ data.center_freq1 = 5000 + center_segment0 * 5;
+ break;
+ case 2:
+ data.bandwidth = 160;
+ if (center_segment1)
+ return -1;
+ if (!sec_channel_offset)
+ return -1;
+ /* primary 40 part must match the HT configuration */
+ tmp = (70 + freq - 5000 - center_segment0 * 5)/20;
+ tmp /= 2;
+ if (data.center_freq1 != 5000 +
+ center_segment0 * 5 - 60 + 40 * tmp)
+ return -1;
+ data.center_freq1 = 5000 + center_segment0 * 5;
+ break;
+ }
+ if (hapd->driver == NULL)
+ return 0;
+ if (hapd->driver->set_freq == NULL)
+ return 0;
return hapd->driver->set_freq(hapd->drv_priv, &data);
}
diff --git a/src/ap/ap_drv_ops.h b/src/ap/ap_drv_ops.h
index 9c53b99..768a0ba 100644
--- a/src/ap/ap_drv_ops.h
+++ b/src/ap/ap_drv_ops.h
@@ -55,7 +55,9 @@ int hostapd_get_seqnum(const char *ifname, struct hostapd_data *hapd,
const u8 *addr, int idx, u8 *seq);
int hostapd_flush(struct hostapd_data *hapd);
int hostapd_set_freq(struct hostapd_data *hapd, int mode, int freq,
- int channel, int ht_enabled, int sec_channel_offset);
+ int channel, int ht_enabled, int vht_enabled,
+ int sec_channel_offset, int vht_oper_chwidth,
+ int center_segment0, int center_segment1);
int hostapd_set_rts(struct hostapd_data *hapd, int rts);
int hostapd_set_frag(struct hostapd_data *hapd, int frag);
int hostapd_sta_set_flags(struct hostapd_data *hapd, u8 *addr,
diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c
index 1c968a7..15fb861 100644
--- a/src/ap/hostapd.c
+++ b/src/ap/hostapd.c
@@ -889,7 +889,11 @@ int hostapd_setup_interface_complete(struct hostapd_iface *iface, int err)
if (hostapd_set_freq(hapd, hapd->iconf->hw_mode, iface->freq,
hapd->iconf->channel,
hapd->iconf->ieee80211n,
- hapd->iconf->secondary_channel)) {
+ hapd->iconf->ieee80211ac,
+ hapd->iconf->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");
return -1;
diff --git a/src/drivers/driver.h b/src/drivers/driver.h
index ccc5a0e..10d639e 100644
--- a/src/drivers/driver.h
+++ b/src/drivers/driver.h
@@ -905,10 +905,19 @@ struct hostapd_freq_params {
int mode;
int freq;
int channel;
+ /* for HT */
int ht_enabled;
int sec_channel_offset; /* 0 = HT40 disabled, -1 = HT40 enabled,
* secondary channel below primary, 1 = HT40
* enabled, secondary channel above primary */
+
+ /* for VHT */
+ int vht_enabled;
+
+ /* valid for both HT and VHT, center_freq2 is non-zero
+ * only for bandwidth 80 and an 80+80 channel */
+ int center_freq1, center_freq2;
+ int bandwidth;
};
enum wpa_driver_if_type {
--
1.8.0
More information about the Hostap
mailing list