From patchwork Mon Aug 19 15:12:19 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Wunderlich X-Patchwork-Id: 2846554 Return-Path: X-Original-To: patchwork-linux-wireless@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 20CBDBF546 for ; Mon, 19 Aug 2013 15:12:48 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id E6E4A20292 for ; Mon, 19 Aug 2013 15:12:46 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id A1F6D201CD for ; Mon, 19 Aug 2013 15:12:45 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751030Ab3HSPMh (ORCPT ); Mon, 19 Aug 2013 11:12:37 -0400 Received: from nick.hrz.tu-chemnitz.de ([134.109.228.11]:55770 "EHLO nick.hrz.tu-chemnitz.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750874Ab3HSPM2 (ORCPT ); Mon, 19 Aug 2013 11:12:28 -0400 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=tu-chemnitz.de; s=dkim2010; h=References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From; bh=SlU4ZFo9rDXG7IMqZiVd+byzYLJQVsNm8W16Zs0XGzc=; b=KwGItF9rZ+u2g4YlB+SsjbLdMZq37SNEqC1nZTevckWstouE7POinoIUVENNrFYTnRbLX9iGXkR1AF4YY2DQU1jQKI3dtM6buPC+XO0/FCRkh1N1Sl6w8RCsg3ZBfsMF+YxDrL1R9itgZsW0Wt5I5BTM8pn2iu3tx+vH9Jt+nSU=; Received: from p4ffe4b02.dip0.t-ipconnect.de ([79.254.75.2] helo=pandem0nium) by nick.hrz.tu-chemnitz.de with esmtpsa (TLSv1:DHE-RSA-AES128-SHA:128) (Exim 4.80.1) (envelope-from ) id 1VBR87-00010u-54; Mon, 19 Aug 2013 17:12:27 +0200 Received: from dotslash by pandem0nium with local (Exim 4.80) (envelope-from ) id 1VBR85-00040W-VM; Mon, 19 Aug 2013 17:12:26 +0200 From: Simon Wunderlich To: linux-wireless@vger.kernel.org Cc: Johannes Berg , Mathias Kretschmer , Simon Wunderlich Subject: [PATCHv3 5/6] mac80211: send a CSA action frame when changing channel Date: Mon, 19 Aug 2013 17:12:19 +0200 Message-Id: <1376925141-15353-6-git-send-email-siwu@hrz.tu-chemnitz.de> X-Mailer: git-send-email 1.7.10.4 In-Reply-To: <1376925141-15353-1-git-send-email-siwu@hrz.tu-chemnitz.de> References: <1376925141-15353-1-git-send-email-siwu@hrz.tu-chemnitz.de> X-purgate: clean X-purgate-type: clean X-purgate-ID: 154106::1376925147-000004FE-31ED0171/0-0/0-0 X-Scan-AV: nick.hrz.tu-chemnitz.de; 2013-08-19 17:12:27; c244ac16affa3de6e6d8e9696a36f99a X-Scan-SA: nick.hrz.tu-chemnitz.de; 2013-08-19 17:12:27; e1cc34bcbe3f3ff9df2c08e955c7a3eb X-Spam-Score: -1.0 (-) Sender: linux-wireless-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org X-Spam-Status: No, score=-9.6 required=5.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_HI,RP_MATCHES_RCVD,T_DKIM_INVALID,UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP IBSS members may not immediately be able to send out their beacon when performing CSA, therefore also send a CSA action frame. Signed-off-by: Simon Wunderlich Signed-off-by: Mathias Kretschmer --- net/mac80211/ibss.c | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c index e4b880e..92d4922 100644 --- a/net/mac80211/ibss.c +++ b/net/mac80211/ibss.c @@ -405,6 +405,60 @@ static void ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, tsf, false); } +static int ieee80211_send_action_csa(struct ieee80211_sub_if_data *sdata, + struct cfg80211_csa_settings *csa_settings) +{ + struct sk_buff *skb; + struct ieee80211_mgmt *mgmt; + struct ieee80211_if_ibss *ifibss = &sdata->u.ibss; + struct ieee80211_local *local = sdata->local; + int freq; + int hdr_len = offsetof(struct ieee80211_mgmt, u.action.u.chan_switch) + + sizeof(mgmt->u.action.u.chan_switch); + u8 *pos; + + skb = dev_alloc_skb(local->tx_headroom + hdr_len + + 5 + /* channel switch announcement element */ + 3); /* secondary channel offset element */ + if (!skb) + return -1; + + skb_reserve(skb, local->tx_headroom); + mgmt = (struct ieee80211_mgmt *)skb_put(skb, hdr_len); + memset(mgmt, 0, hdr_len); + mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | + IEEE80211_STYPE_ACTION); + + eth_broadcast_addr(mgmt->da); + memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN); + memcpy(mgmt->bssid, ifibss->bssid, ETH_ALEN); + mgmt->u.action.category = WLAN_CATEGORY_SPECTRUM_MGMT; + mgmt->u.action.u.chan_switch.action_code = WLAN_ACTION_SPCT_CHL_SWITCH; + pos = skb_put(skb, 5); + *pos++ = WLAN_EID_CHANNEL_SWITCH; /* EID */ + *pos++ = 3; /* IE length */ + *pos++ = csa_settings->block_tx ? 1 : 0; /* CSA mode */ + freq = csa_settings->chandef.chan->center_freq; + *pos++ = ieee80211_frequency_to_channel(freq); /* channel */ + *pos++ = csa_settings->count; /* count */ + + if (csa_settings->chandef.width == NL80211_CHAN_WIDTH_40) { + enum nl80211_channel_type ch_type; + + skb_put(skb, 3); + *pos++ = WLAN_EID_SECONDARY_CHANNEL_OFFSET; /* EID */ + *pos++ = 1; /* IE length */ + ch_type = cfg80211_get_chandef_type(&csa_settings->chandef); + if (ch_type == NL80211_CHAN_HT40PLUS) + *pos++ = IEEE80211_HT_PARAM_CHA_SEC_ABOVE; + else + *pos++ = IEEE80211_HT_PARAM_CHA_SEC_BELOW; + } + + ieee80211_tx_skb(sdata, skb); + return 0; +} + int ieee80211_ibss_csa_beacon(struct ieee80211_sub_if_data *sdata, struct cfg80211_csa_settings *csa_settings) { @@ -457,6 +511,12 @@ int ieee80211_ibss_csa_beacon(struct ieee80211_sub_if_data *sdata, if (old_presp) kfree_rcu(old_presp, rcu_head); + /* it might not send the beacon for a while. send an action frame + * immediately to announce the channel switch. + */ + if (csa_settings) + ieee80211_send_action_csa(sdata, csa_settings); + ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON); out: return ret;