From patchwork Mon Oct 7 16:41:06 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Wunderlich X-Patchwork-Id: 2997991 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 0E75F9F243 for ; Mon, 7 Oct 2013 16:41:32 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id D17542012B for ; Mon, 7 Oct 2013 16:41:30 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 5BFC52013A for ; Mon, 7 Oct 2013 16:41:29 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1756182Ab3JGQlZ (ORCPT ); Mon, 7 Oct 2013 12:41:25 -0400 Received: from cora.hrz.tu-chemnitz.de ([134.109.228.40]:48942 "EHLO cora.hrz.tu-chemnitz.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755519Ab3JGQlT (ORCPT ); Mon, 7 Oct 2013 12:41: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=kMAtuqa3RfV8g38xQTg/TRgFjv+qxL/oa6MkPw9S9Zk=; b=N3kEC3HyVGAZrv27idfur1w0BTRcyZTa4RF94qw9VODsI+ZVolAJC6oE7WBEp9NLwzfwPqSd2tHxjfuaflD7XC/icxUGfD95f4O0t9hBZgmw9yaFQtQSWYYhT2ChcaCJ1SS3tots7/wy8EgE8u2NvFLnCDpHVkcnmmQULMdll6g=; Received: from p549bda47.dip0.t-ipconnect.de ([84.155.218.71] helo=pandem0nium) by cora.hrz.tu-chemnitz.de with esmtpsa (TLSv1:DHE-RSA-AES128-SHA:128) (Exim 4.80.1) (envelope-from ) id 1VTDry-0000bp-39; Mon, 07 Oct 2013 18:41:18 +0200 Received: from dotslash by pandem0nium with local (Exim 4.80) (envelope-from ) id 1VTDrx-0001GX-3X; Mon, 07 Oct 2013 18:41:17 +0200 From: Simon Wunderlich To: linux-wireless@vger.kernel.org Cc: Johannes Berg , Mathias Kretschmer , Simon Wunderlich Subject: [PATCHv2 2/3] mac80211: enable DFS for IBSS mode Date: Mon, 7 Oct 2013 18:41:06 +0200 Message-Id: <1381164067-4830-3-git-send-email-siwu@hrz.tu-chemnitz.de> X-Mailer: git-send-email 1.7.10.4 In-Reply-To: <1381164067-4830-1-git-send-email-siwu@hrz.tu-chemnitz.de> References: <1381164067-4830-1-git-send-email-siwu@hrz.tu-chemnitz.de> X-purgate: clean X-purgate-type: clean X-purgate-ID: 154106::1381164078-00007495-9CFEDAFA/0-0/0-0 X-Scan-AV: cora.hrz.tu-chemnitz.de; 2013-10-07 18:41:18; d511dc729293424b0fa55dafe5b398b3 X-Scan-SA: cora.hrz.tu-chemnitz.de; 2013-10-07 18:41:18; 87a2d1bfde35e0e78d73c8b011be8913 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=-7.0 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 Allow changing to DFS channels if the channel is available for beaconing and userspace controls DFS operation. Channel switch announcement from other stations on DFS channels will be interpreted as radar event. These channels will then be marked as unvailable. Signed-off-by: Simon Wunderlich Signed-off-by: Mathias Kretschmer --- Changes to PATCHv1: * rename control_port_dfs to userspace_handles_dfs --- net/mac80211/ibss.c | 49 +++++++++++++++++++++++++++++++++++++++----- net/mac80211/ieee80211_i.h | 1 + 2 files changed, 45 insertions(+), 5 deletions(-) diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c index 21a0b88..275bbb2 100644 --- a/net/mac80211/ibss.c +++ b/net/mac80211/ibss.c @@ -229,6 +229,7 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, struct beacon_data *presp; enum nl80211_bss_scan_width scan_width; bool have_higher_than_11mbit; + bool radar_required = false; int err; sdata_assert_lock(sdata); @@ -273,6 +274,23 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, } chandef.width = NL80211_CHAN_WIDTH_20; chandef.center_freq1 = chan->center_freq; + /* check again for downgraded chandef */ + if (!cfg80211_reg_can_beacon(local->hw.wiphy, &chandef)) { + sdata_info(sdata, + "Failed to join IBSS, beacons forbidden\n"); + return; + } + } + + err = cfg80211_chandef_dfs_required(sdata->local->hw.wiphy, + &chandef); + if (err > 0) { + if (!ifibss->userspace_handles_dfs) { + sdata_info(sdata, + "Failed to join IBSS, DFS channel without control program\n"); + return; + } + radar_required = true; } ieee80211_vif_release_channel(sdata); @@ -297,6 +315,7 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, rcu_assign_pointer(ifibss->presp, presp); mgmt = (void *)presp->head; + sdata->radar_required = radar_required; sdata->vif.bss_conf.enable_beacon = true; sdata->vif.bss_conf.beacon_int = beacon_int; sdata->vif.bss_conf.basic_rates = basic_rates; @@ -796,6 +815,21 @@ static void ieee80211_csa_connection_drop_work(struct work_struct *work) ieee80211_queue_work(&sdata->local->hw, &sdata->work); } +static void ieee80211_ibss_csa_mark_radar(struct ieee80211_sub_if_data *sdata) +{ + struct ieee80211_if_ibss *ifibss = &sdata->u.ibss; + int err; + + /* if the current channel is a DFS channel, mark the channel as + * unavailable. + */ + err = cfg80211_chandef_dfs_required(sdata->local->hw.wiphy, + &ifibss->chandef); + if (err > 0) + cfg80211_radar_event(sdata->local->hw.wiphy, &ifibss->chandef, + GFP_ATOMIC); +} + static bool ieee80211_ibss_process_chanswitch(struct ieee80211_sub_if_data *sdata, struct ieee802_11_elems *elems, @@ -880,8 +914,7 @@ ieee80211_ibss_process_chanswitch(struct ieee80211_sub_if_data *sdata, goto disconnect; } - if (!cfg80211_chandef_usable(sdata->local->hw.wiphy, ¶ms.chandef, - IEEE80211_CHAN_DISABLED)) { + if (!cfg80211_reg_can_beacon(sdata->local->hw.wiphy, ¶ms.chandef)) { sdata_info(sdata, "IBSS %pM switches to unsupported channel (%d MHz, width:%d, CF1/2: %d/%d MHz), disconnecting\n", ifibss->bssid, @@ -897,10 +930,11 @@ ieee80211_ibss_process_chanswitch(struct ieee80211_sub_if_data *sdata, if (err < 0) goto disconnect; if (err) { + /* IBSS-DFS only allowed with a control program */ + if (!ifibss->userspace_handles_dfs) + goto disconnect; + params.radar_required = true; - - /* TODO: IBSS-DFS not (yet) supported, disconnect. */ - goto disconnect; } rcu_read_lock(); @@ -947,12 +981,16 @@ ieee80211_ibss_process_chanswitch(struct ieee80211_sub_if_data *sdata, ieee80211_bss_info_change_notify(sdata, err); drv_channel_switch_beacon(sdata, ¶ms.chandef); + ieee80211_ibss_csa_mark_radar(sdata); + return true; disconnect: ibss_dbg(sdata, "Can't handle channel switch, disconnect\n"); ieee80211_queue_work(&sdata->local->hw, &ifibss->csa_connection_drop_work); + ieee80211_ibss_csa_mark_radar(sdata); + return true; } @@ -1688,6 +1726,7 @@ int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata, sdata->u.ibss.privacy = params->privacy; sdata->u.ibss.control_port = params->control_port; + sdata->u.ibss.userspace_handles_dfs = params->userspace_handles_dfs; sdata->u.ibss.basic_rates = params->basic_rates; /* fix basic_rates if channel does not support these rates */ diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 3a87c89..9752567 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -497,6 +497,7 @@ struct ieee80211_if_ibss { bool privacy; bool control_port; + bool userspace_handles_dfs; u8 bssid[ETH_ALEN] __aligned(2); u8 ssid[IEEE80211_MAX_SSID_LEN];