From patchwork Wed Nov 21 16:32:12 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Johannes Berg X-Patchwork-Id: 200807 Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from maxx.maxx.shmoo.com (maxx.shmoo.com [205.134.188.171]) by ozlabs.org (Postfix) with ESMTP id 863EB2C00D8 for ; Thu, 22 Nov 2012 03:33:00 +1100 (EST) Received: from localhost (localhost [127.0.0.1]) by maxx.maxx.shmoo.com (Postfix) with ESMTP id B92939D211; Wed, 21 Nov 2012 11:32:41 -0500 (EST) X-Virus-Scanned: amavisd-new at maxx.shmoo.com Received: from maxx.maxx.shmoo.com ([127.0.0.1]) by localhost (maxx.shmoo.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id eCJIkrY+OG7I; Wed, 21 Nov 2012 11:32:41 -0500 (EST) Received: from maxx.shmoo.com (localhost [127.0.0.1]) by maxx.maxx.shmoo.com (Postfix) with ESMTP id EAD1717C00A; Wed, 21 Nov 2012 11:31:58 -0500 (EST) X-Original-To: mailman-post+hostap@maxx.shmoo.com Delivered-To: mailman-post+hostap@maxx.shmoo.com Received: from localhost (localhost [127.0.0.1]) by maxx.maxx.shmoo.com (Postfix) with ESMTP id 65E139D0D3 for ; Wed, 21 Nov 2012 11:31:57 -0500 (EST) X-Virus-Scanned: amavisd-new at maxx.shmoo.com Received: from maxx.maxx.shmoo.com ([127.0.0.1]) by localhost (maxx.shmoo.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id jfErPa9XRNMs for ; Wed, 21 Nov 2012 11:31:52 -0500 (EST) Received: from sipsolutions.net (he.sipsolutions.net [78.46.109.217]) (using TLSv1 with cipher DHE-RSA-AES128-SHA (128/128 bits)) (Client did not present a certificate) by maxx.maxx.shmoo.com (Postfix) with ESMTPS id B34379D0D5 for ; Wed, 21 Nov 2012 11:31:48 -0500 (EST) Received: by sipsolutions.net with esmtpsa (TLS1.2:DHE_RSA_AES_256_CBC_SHA256:256) (Exim 4.80) (envelope-from ) id 1TbDDH-0004Eq-BB; Wed, 21 Nov 2012 17:31:47 +0100 From: Johannes Berg To: hostap@lists.shmoo.com Subject: [RFC 3/7] hostapd: allow configuring driver to VHT Date: Wed, 21 Nov 2012 17:32:12 +0100 Message-Id: <1353515536-30235-4-git-send-email-johannes@sipsolutions.net> X-Mailer: git-send-email 1.8.0 In-Reply-To: <1353515536-30235-1-git-send-email-johannes@sipsolutions.net> References: <1353515536-30235-1-git-send-email-johannes@sipsolutions.net> Cc: Johannes Berg X-BeenThere: hostap@lists.shmoo.com X-Mailman-Version: 2.1.9 Precedence: list List-Id: HostAP Project List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: hostap-bounces@lists.shmoo.com Errors-To: hostap-bounces@lists.shmoo.com From: Johannes Berg Signed-hostap: Johannes Berg --- src/ap/ap_drv_ops.c | 68 ++++++++++++++++++++++++++++++++++++++++++++++++---- src/ap/ap_drv_ops.h | 4 +++- src/ap/hostapd.c | 6 ++++- src/drivers/driver.h | 9 +++++++ 4 files changed, 80 insertions(+), 7 deletions(-) diff --git a/src/ap/ap_drv_ops.c b/src/ap/ap_drv_ops.c index 02da25b..cca52f3 100644 --- a/src/ap/ap_drv_ops.c +++ b/src/ap/ap_drv_ops.c @@ -454,19 +454,77 @@ 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; + + /* + * 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 0: + if (center_segment1) + return -1; + /* + * TODO: use a constant for 5000 throughout this code, + * or even support different regulatory classes? + */ + 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 cef9daf..92fda56 100644 --- a/src/ap/hostapd.c +++ b/src/ap/hostapd.c @@ -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, 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 {