From patchwork Fri Aug 2 15:38:05 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Wunderlich X-Patchwork-Id: 2838014 Return-Path: X-Original-To: patchwork-linux-wireless@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 014A89F496 for ; Fri, 2 Aug 2013 15:38:44 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 02EB8203D9 for ; Fri, 2 Aug 2013 15:38:43 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id DA70B203B5 for ; Fri, 2 Aug 2013 15:38:41 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753828Ab3HBPie (ORCPT ); Fri, 2 Aug 2013 11:38:34 -0400 Received: from cora.hrz.tu-chemnitz.de ([134.109.228.40]:43906 "EHLO cora.hrz.tu-chemnitz.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754080Ab3HBPiT (ORCPT ); Fri, 2 Aug 2013 11:38:19 -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=AWeC34Oi3227mRXPeoT42hsg6VsxYpqMzBzsZsIHrns=; b=0SfaLx2OWBxvAcIC85CBHBhkx9nyTWcm2E1bwRCWLDwV8YHr2D9lh3KGIDA4Wv7Nw93Jhs2PxOErrdX8JtFy3EOQ06K7NDYx2Z0TRw6Z4RmW3KJdfAL/bWzaugKpJrG42On6UVOXtrj6M4GMU9VqwZqfrmyYMRaJ3M30x19fFQo=; Received: from p579e7cd2.dip0.t-ipconnect.de ([87.158.124.210] helo=pandem0nium) by cora.hrz.tu-chemnitz.de with esmtpsa (TLSv1:DHE-RSA-AES128-SHA:128) (Exim 4.80.1) (envelope-from ) id 1V5HQn-0008If-TR; Fri, 02 Aug 2013 17:38:18 +0200 Received: from dotslash by pandem0nium with local (Exim 4.80) (envelope-from ) id 1V5HQm-0001uG-4a; Fri, 02 Aug 2013 17:38:16 +0200 From: Simon Wunderlich To: linux-wireless@vger.kernel.org Cc: Johannes Berg , Mathias Kretschmer , Simon Wunderlich Subject: [PATCH 6/7] mac80211: send a CSA action frame when changing channel Date: Fri, 2 Aug 2013 17:38:05 +0200 Message-Id: <1375457886-7275-7-git-send-email-siwu@hrz.tu-chemnitz.de> X-Mailer: git-send-email 1.7.10.4 In-Reply-To: <1375457886-7275-1-git-send-email-siwu@hrz.tu-chemnitz.de> References: <1375457886-7275-1-git-send-email-siwu@hrz.tu-chemnitz.de> X-purgate: clean X-purgate-type: clean X-purgate-ID: 154106::1375457897-0000051A-54AC9D94/0-0/0-0 X-Scan-AV: cora.hrz.tu-chemnitz.de; 2013-08-02 17:38:17; 5fc0f1c1d8a8c0f8f9c4fe67b799b0b3 X-Scan-SA: cora.hrz.tu-chemnitz.de; 2013-08-02 17:38:18; 402d7b310dbbfd6999e8b3c09f30b35c 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=-8.2 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 | 61 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c index 4a10e00..2bd86a2 100644 --- a/net/mac80211/ibss.c +++ b/net/mac80211/ibss.c @@ -405,6 +405,61 @@ 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; +} + + /* must hold sdata lock */ int ieee80211_ibss_csa_beacon(struct ieee80211_sub_if_data *sdata, struct cfg80211_csa_settings *csa_settings) @@ -458,6 +513,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;