hostapd: Allow configuring driver to VHT
Signed-hostap: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
parent
7ab5441262
commit
fa4763369a
5 changed files with 85 additions and 7 deletions
|
@ -454,19 +454,76 @@ int hostapd_flush(struct hostapd_data *hapd)
|
||||||
|
|
||||||
|
|
||||||
int hostapd_set_freq(struct hostapd_data *hapd, int mode, int freq,
|
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;
|
struct hostapd_freq_params data;
|
||||||
if (hapd->driver == NULL)
|
int tmp;
|
||||||
return 0;
|
|
||||||
if (hapd->driver->set_freq == NULL)
|
|
||||||
return 0;
|
|
||||||
os_memset(&data, 0, sizeof(data));
|
os_memset(&data, 0, sizeof(data));
|
||||||
data.mode = mode;
|
data.mode = mode;
|
||||||
data.freq = freq;
|
data.freq = freq;
|
||||||
data.channel = channel;
|
data.channel = channel;
|
||||||
data.ht_enabled = ht_enabled;
|
data.ht_enabled = ht_enabled;
|
||||||
|
data.vht_enabled = vht_enabled;
|
||||||
data.sec_channel_offset = sec_channel_offset;
|
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;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This validation code is probably misplaced, maybe it should be
|
||||||
|
* in src/ap/hw_features.c and check the hardware support as well.
|
||||||
|
*/
|
||||||
|
if (data.vht_enabled) switch (vht_oper_chwidth) {
|
||||||
|
case VHT_CHANWIDTH_USE_HT:
|
||||||
|
if (center_segment1)
|
||||||
|
return -1;
|
||||||
|
if (5000 + center_segment0 * 5 != data.center_freq1)
|
||||||
|
return -1;
|
||||||
|
break;
|
||||||
|
case VHT_CHANWIDTH_80P80MHZ:
|
||||||
|
if (center_segment1 == center_segment0 + 4 ||
|
||||||
|
center_segment1 == center_segment0 - 4)
|
||||||
|
return -1;
|
||||||
|
data.center_freq2 = 5000 + center_segment1 * 5;
|
||||||
|
/* fall through */
|
||||||
|
case VHT_CHANWIDTH_80MHZ:
|
||||||
|
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 VHT_CHANWIDTH_160MHZ:
|
||||||
|
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);
|
return hapd->driver->set_freq(hapd->drv_priv, &data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -55,7 +55,9 @@ int hostapd_get_seqnum(const char *ifname, struct hostapd_data *hapd,
|
||||||
const u8 *addr, int idx, u8 *seq);
|
const u8 *addr, int idx, u8 *seq);
|
||||||
int hostapd_flush(struct hostapd_data *hapd);
|
int hostapd_flush(struct hostapd_data *hapd);
|
||||||
int hostapd_set_freq(struct hostapd_data *hapd, int mode, int freq,
|
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_rts(struct hostapd_data *hapd, int rts);
|
||||||
int hostapd_set_frag(struct hostapd_data *hapd, int frag);
|
int hostapd_set_frag(struct hostapd_data *hapd, int frag);
|
||||||
int hostapd_sta_set_flags(struct hostapd_data *hapd, u8 *addr,
|
int hostapd_sta_set_flags(struct hostapd_data *hapd, u8 *addr,
|
||||||
|
|
|
@ -894,7 +894,11 @@ int hostapd_setup_interface_complete(struct hostapd_iface *iface, int err)
|
||||||
if (hostapd_set_freq(hapd, hapd->iconf->hw_mode, iface->freq,
|
if (hostapd_set_freq(hapd, hapd->iconf->hw_mode, iface->freq,
|
||||||
hapd->iconf->channel,
|
hapd->iconf->channel,
|
||||||
hapd->iconf->ieee80211n,
|
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 "
|
wpa_printf(MSG_ERROR, "Could not set channel for "
|
||||||
"kernel driver");
|
"kernel driver");
|
||||||
return -1;
|
return -1;
|
||||||
|
|
|
@ -712,6 +712,12 @@ struct ieee80211_vht_operation {
|
||||||
#define VHT_CAP_RX_ANTENNA_PATTERN ((u32) BIT(28))
|
#define VHT_CAP_RX_ANTENNA_PATTERN ((u32) BIT(28))
|
||||||
#define VHT_CAP_TX_ANTENNA_PATTERN ((u32) BIT(29))
|
#define VHT_CAP_TX_ANTENNA_PATTERN ((u32) BIT(29))
|
||||||
|
|
||||||
|
/* VHT channel widths */
|
||||||
|
#define VHT_CHANWIDTH_USE_HT 0
|
||||||
|
#define VHT_CHANWIDTH_80MHZ 1
|
||||||
|
#define VHT_CHANWIDTH_160MHZ 2
|
||||||
|
#define VHT_CHANWIDTH_80P80MHZ 3
|
||||||
|
|
||||||
#define OUI_MICROSOFT 0x0050f2 /* Microsoft (also used in Wi-Fi specs)
|
#define OUI_MICROSOFT 0x0050f2 /* Microsoft (also used in Wi-Fi specs)
|
||||||
* 00:50:F2 */
|
* 00:50:F2 */
|
||||||
#define WPA_IE_VENDOR_TYPE 0x0050f201
|
#define WPA_IE_VENDOR_TYPE 0x0050f201
|
||||||
|
|
|
@ -907,10 +907,19 @@ struct hostapd_freq_params {
|
||||||
int mode;
|
int mode;
|
||||||
int freq;
|
int freq;
|
||||||
int channel;
|
int channel;
|
||||||
|
/* for HT */
|
||||||
int ht_enabled;
|
int ht_enabled;
|
||||||
int sec_channel_offset; /* 0 = HT40 disabled, -1 = HT40 enabled,
|
int sec_channel_offset; /* 0 = HT40 disabled, -1 = HT40 enabled,
|
||||||
* secondary channel below primary, 1 = HT40
|
* secondary channel below primary, 1 = HT40
|
||||||
* enabled, secondary channel above primary */
|
* 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 {
|
enum wpa_driver_if_type {
|
||||||
|
|
Loading…
Reference in a new issue