From patchwork Fri Jan 31 16:57:00 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bartosz.Markowski@tieto.com X-Patchwork-Id: 315762 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]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 1CD1E2C009A for ; Sat, 1 Feb 2014 03:58:22 +1100 (EST) Received: from localhost (localhost [127.0.0.1]) by maxx.maxx.shmoo.com (Postfix) with ESMTP id 8B74B9C1B4; Fri, 31 Jan 2014 11:58:03 -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 gYvy+zyj-XQh; Fri, 31 Jan 2014 11:58:03 -0500 (EST) Received: from maxx.shmoo.com (localhost [127.0.0.1]) by maxx.maxx.shmoo.com (Postfix) with ESMTP id 40BD19C1B6; Fri, 31 Jan 2014 11:57:27 -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 C3D2C9C198 for ; Fri, 31 Jan 2014 11:57:24 -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 gD8SODTt90yR for ; Fri, 31 Jan 2014 11:57:19 -0500 (EST) Received: from mail-ee0-f54.google.com (mail-ee0-f54.google.com [74.125.83.54]) (using TLSv1 with cipher RC4-SHA (128/128 bits)) (Client CN "smtp.gmail.com", Issuer "Google Internet Authority G2" (not verified)) by maxx.maxx.shmoo.com (Postfix) with ESMTPS id 4634C9C199 for ; Fri, 31 Jan 2014 11:57:15 -0500 (EST) Received: by mail-ee0-f54.google.com with SMTP id e53so2421474eek.13 for ; Fri, 31 Jan 2014 08:57:14 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=tieto.com; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=m1Qs40u7YsOm6aZFJi+7SprJrUzFi/MmX3VTU1qCN6I=; b=RGx95vjlswL6JQ+d0WkD6hs3BvWo8QKd6eSPBrxsXbQ0Weiwm/GskGqUtz4lR1lhDr 2E1pnV9OEv8osCwfD0gNRbvtqswYE/w3TH1VRBqG3F0AMTFMKHV9iFjG+vFbyjg33TOc YFxKvB/3AL40gb/qh5rllYzi4tObgKt3eJybE= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=m1Qs40u7YsOm6aZFJi+7SprJrUzFi/MmX3VTU1qCN6I=; b=kDEvJ4IjZE92TqWn9l8Pf+msFoHr8eIjJE9Va75IFV14LlWQfU2jtvDV1jD/dEdFtL LdCDTo9+E6tLvfF2sZjWTlBH9SOsHR24Uqj6PVfxeRwAmqWMuU7F7pRPId5c4dMXd5c2 Mex4dD6v1bnSg+Lr2kX34cZ+V1V9ioVs4/Ep9kgv1qZBNrDreXByfViAB9g5ao+ZTn0C vHAQdpu5/hkwmqGEeUJsYQw6GxIh+vcWQTOY16vhTW+vLWUPZvQbg72zaRfg91aUQwE+ zwO/jTWSPkSy2hqQzezxS2gJr2GGludwUjHK0aLk8V2x3DiaCYpej+JoNuzzU23yefrd nnsg== X-Gm-Message-State: ALoCoQkhtnr9EglOGTMZMzOdh7rJMmA9csu5RZnJy97Y4ViHF2+4akI1EP3vsBz0auoE9m3WSCdlfcaLNJFaWm3iTGMLlpKzModqJumSG/NsUsnG/RHIPlk= X-Received: by 10.14.176.195 with SMTP id b43mr25881032eem.39.1391187432948; Fri, 31 Jan 2014 08:57:12 -0800 (PST) Received: from E4300.vivaldiego.wroclaw.pl (v22-98-181.vivaldiego.wroclaw.pl. [195.22.98.181]) by mx.google.com with ESMTPSA id 4sm38839220eed.14.2014.01.31.08.57.12 for (version=TLSv1.1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Fri, 31 Jan 2014 08:57:12 -0800 (PST) From: Bartosz Markowski To: hostap@lists.shmoo.com Subject: [RFC v2 2/6] hostapd: extend CSA driver API Date: Fri, 31 Jan 2014 17:57:00 +0100 Message-Id: <1391187424-5653-3-git-send-email-bartosz.markowski@tieto.com> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <1391187424-5653-1-git-send-email-bartosz.markowski@tieto.com> References: <1391187424-5653-1-git-send-email-bartosz.markowski@tieto.com> X-DomainID: tieto.com X-BeenThere: hostap@lists.shmoo.com X-Mailman-Version: 2.1.11 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: Michal Kazior This prepares CSA driver API to support multi-BSS. Signed-hostap: Michal Kazior --- hostapd/ctrl_iface.c | 5 ++++- src/ap/ap_drv_ops.h | 14 +++++++++++--- src/ap/dfs.c | 4 +++- src/ap/hostapd.c | 35 ++++++++++++++++++++++------------- src/ap/hostapd.h | 3 +-- src/drivers/driver.h | 11 +++++++++-- src/drivers/driver_nl80211.c | 7 ++++++- wpa_supplicant/ap.c | 5 ++++- wpa_supplicant/driver_i.h | 2 +- 9 files changed, 61 insertions(+), 25 deletions(-) diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c index 4a9da5f..df5c513 100644 --- a/hostapd/ctrl_iface.c +++ b/hostapd/ctrl_iface.c @@ -1138,7 +1138,10 @@ static int hostapd_ctrl_iface_chan_switch(struct hostapd_data *hapd, char *pos) if (ret) return ret; - return hostapd_switch_channel(hapd, &settings); + settings.hapd = hapd; + settings.priv = hapd->drv_priv; + + return hostapd_switch_channel(&settings, 1); #else /* NEED_AP_MLME */ return -1; #endif /* NEED_AP_MLME */ diff --git a/src/ap/ap_drv_ops.h b/src/ap/ap_drv_ops.h index 15a4b26..a729d7c 100644 --- a/src/ap/ap_drv_ops.h +++ b/src/ap/ap_drv_ops.h @@ -263,13 +263,21 @@ static inline const char * hostapd_drv_get_radio_name(struct hostapd_data *hapd) return hapd->driver->get_radio_name(hapd->drv_priv); } -static inline int hostapd_drv_switch_channel(struct hostapd_data *hapd, - struct csa_settings *settings) +static inline int hostapd_drv_switch_channel(struct csa_settings *settings, + int num_settings) { + struct hostapd_data *hapd; + + if (num_settings < 1) + return -EINVAL; + + hapd = settings[0].hapd; + if (hapd->driver == NULL || hapd->driver->switch_channel == NULL) return -ENOTSUP; - return hapd->driver->switch_channel(hapd->drv_priv, settings); + return hapd->driver->switch_channel(hapd->drv_priv, settings, + num_settings); } static inline int hostapd_drv_status(struct hostapd_data *hapd, char *buf, diff --git a/src/ap/dfs.c b/src/ap/dfs.c index fe69333..9e86925 100644 --- a/src/ap/dfs.c +++ b/src/ap/dfs.c @@ -724,6 +724,8 @@ static int hostapd_dfs_start_channel_switch(struct hostapd_iface *iface) /* Setup CSA request */ os_memset(&csa_settings, 0, sizeof(csa_settings)); + csa_settings.hapd = hapd; + csa_settings.priv = hapd->drv_priv; csa_settings.cs_count = 5; csa_settings.block_tx = 1; err = hostapd_set_freq_params(&csa_settings.freq_params, @@ -744,7 +746,7 @@ static int hostapd_dfs_start_channel_switch(struct hostapd_iface *iface) return err; } - err = hostapd_switch_channel(hapd, &csa_settings); + err = hostapd_switch_channel(&csa_settings, 1); if (err) { wpa_printf(MSG_WARNING, "DFS failed to schedule CSA (%d) - trying fallback", err); diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c index 3526049..b1817a8 100644 --- a/src/ap/hostapd.c +++ b/src/ap/hostapd.c @@ -2174,9 +2174,9 @@ static int hostapd_change_config_freq(struct hostapd_data *hapd, } -static int hostapd_fill_csa_settings(struct hostapd_data *hapd, - struct csa_settings *settings) +static int hostapd_fill_csa_settings(struct csa_settings *settings) { + struct hostapd_data *hapd = settings->hapd; struct hostapd_iface *iface = hapd->iface; struct hostapd_freq_params old_freq; int ret; @@ -2230,25 +2230,34 @@ void hostapd_cleanup_cs_params(struct hostapd_data *hapd) } -int hostapd_switch_channel(struct hostapd_data *hapd, - struct csa_settings *settings) +int hostapd_switch_channel(struct csa_settings *settings, + int num_settings) { - int ret; - ret = hostapd_fill_csa_settings(hapd, settings); - if (ret) - return ret; + int i, ret; + + for (i = 0; i < num_settings; i++) { + ret = hostapd_fill_csa_settings(&settings[i]); + if (ret) + return ret; + } - ret = hostapd_drv_switch_channel(hapd, settings); - free_beacon_data(&settings->beacon_csa); - free_beacon_data(&settings->beacon_after); + ret = hostapd_drv_switch_channel(settings, num_settings); + + for (i = 0; i < num_settings; i++) { + free_beacon_data(&settings[i].beacon_csa); + free_beacon_data(&settings[i].beacon_after); + } if (ret) { /* if we failed, clean cs parameters */ - hostapd_cleanup_cs_params(hapd); + for (i = 0; i < num_settings; i++) + hostapd_cleanup_cs_params(settings[i].hapd); return ret; } - hapd->csa_in_progress = 1; + for (i = 0; i < num_settings; i++) + settings[i].hapd->csa_in_progress = 1; + return 0; } diff --git a/src/ap/hostapd.h b/src/ap/hostapd.h index 993def0..3510911 100644 --- a/src/ap/hostapd.h +++ b/src/ap/hostapd.h @@ -391,8 +391,7 @@ int hostapd_remove_iface(struct hapd_interfaces *ifaces, char *buf); void hostapd_channel_list_updated(struct hostapd_iface *iface, int initiator); void hostapd_set_state(struct hostapd_iface *iface, enum hostapd_iface_state s); const char * hostapd_state_text(enum hostapd_iface_state s); -int hostapd_switch_channel(struct hostapd_data *hapd, - struct csa_settings *settings); +int hostapd_switch_channel(struct csa_settings *settings, int num_settings); void hostapd_cleanup_cs_params(struct hostapd_data *hapd); /* utils.c */ diff --git a/src/drivers/driver.h b/src/drivers/driver.h index 2f4536e..57bff4a 100644 --- a/src/drivers/driver.h +++ b/src/drivers/driver.h @@ -1213,6 +1213,8 @@ struct beacon_data { /** * struct csa_settings - Settings for channel switch command + * @hapd: Pointer to hostapd context + * @priv: Pointer to driver-specific context. * @cs_count: Count in Beacon frames (TBTT) to perform the switch * @block_tx: 1 - block transmission for CSA period * @freq_params: Next channel frequency parameter @@ -1222,6 +1224,9 @@ struct beacon_data { * @counter_offset_presp: Offset to the count field in probe resp. */ struct csa_settings { + struct hostapd_data *hapd; + void *priv; + u8 cs_count; u8 block_tx; @@ -2622,13 +2627,15 @@ struct wpa_driver_ops { * switch_channel - Announce channel switch and migrate the GO to the * given frequency * @priv: Private driver interface data - * @settings: Settings for CSA period and new channel + * @settings: Settings for CSA period and new channel for multiple BSSes + * @num_settings: Number of CSA settings for different BSSes * Returns: 0 on success, -1 on failure * * This function is used to move the GO to the legacy STA channel to * avoid frequency conflict in single channel concurrency. */ - int (*switch_channel)(void *priv, struct csa_settings *settings); + int (*switch_channel)(void *priv, struct csa_settings *settings, + int num_settings); /** * start_dfs_cac - Listen for radar interference on the channel diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c index 5162ecd..f10bd1f 100644 --- a/src/drivers/driver_nl80211.c +++ b/src/drivers/driver_nl80211.c @@ -11558,7 +11558,8 @@ nla_put_failure: } -static int nl80211_switch_channel(void *priv, struct csa_settings *settings) +static int nl80211_switch_channel(void *priv, struct csa_settings *settings, + int num_settings) { struct nl_msg *msg; struct i802_bss *bss = priv; @@ -11566,6 +11567,10 @@ static int nl80211_switch_channel(void *priv, struct csa_settings *settings) struct nlattr *beacon_csa; int ret = -ENOBUFS; + /* multi-BSS not implemented yet */ + if (num_settings != 1) + return -EOPNOTSUPP; + wpa_printf(MSG_DEBUG, "nl80211: Channel switch request (cs_count=%u block_tx=%u freq=%d width=%d cf1=%d cf2=%d)", settings->cs_count, settings->block_tx, settings->freq_params.freq, settings->freq_params.bandwidth, diff --git a/wpa_supplicant/ap.c b/wpa_supplicant/ap.c index ce3efcb..ba21f18 100644 --- a/wpa_supplicant/ap.c +++ b/wpa_supplicant/ap.c @@ -1094,7 +1094,10 @@ int ap_switch_channel(struct wpa_supplicant *wpa_s, if (!wpa_s->ap_iface || !wpa_s->ap_iface->bss[0]) return -1; - return hostapd_switch_channel(wpa_s->ap_iface->bss[0], settings); + settings->hapd = wpa_s->ap_iface->bss[0]; + settings->priv = wpa_s->ap_iface->bss[0]->drv_priv; + + return hostapd_switch_channel(settings, 1); #else /* NEED_AP_MLME */ return -1; #endif /* NEED_AP_MLME */ diff --git a/wpa_supplicant/driver_i.h b/wpa_supplicant/driver_i.h index 0691b6c..c2a16fd 100644 --- a/wpa_supplicant/driver_i.h +++ b/wpa_supplicant/driver_i.h @@ -574,7 +574,7 @@ static inline int wpa_drv_switch_channel(struct wpa_supplicant *wpa_s, { if (!wpa_s->driver->switch_channel) return -1; - return wpa_s->driver->switch_channel(wpa_s->drv_priv, settings); + return wpa_s->driver->switch_channel(wpa_s->drv_priv, settings, 1); } static inline int wpa_drv_wnm_oper(struct wpa_supplicant *wpa_s,