From patchwork Tue Jul 9 18:27:04 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Wunderlich X-Patchwork-Id: 2825421 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 935B8C0AB2 for ; Tue, 9 Jul 2013 18:27:26 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 6F1762010F for ; Tue, 9 Jul 2013 18:27:25 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 5C3792017D for ; Tue, 9 Jul 2013 18:27:24 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752156Ab3GIS1W (ORCPT ); Tue, 9 Jul 2013 14:27:22 -0400 Received: from cora.hrz.tu-chemnitz.de ([134.109.228.40]:33163 "EHLO cora.hrz.tu-chemnitz.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751749Ab3GIS1R (ORCPT ); Tue, 9 Jul 2013 14:27:17 -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=tWpO9pmNYW1VqC7FwSYG96Xq74ATc2pM6PALLsGnBRY=; b=cav68+4lm7XdM7DWriDy4ohDjnp5zGhLzeASNs85F7VSHHuV5hHS625RZbNyNHrG/lOdYvMGQfVgv2LBD/jxInvztfLdsH0uC6tNCTM6l3XJcoUzpUvpDNi47HFhFWrQxkeMspFaT3l8nXsDJRmfCBmpdW1V1ITqIXo8kEZbxBs=; Received: from p579e7a48.dip0.t-ipconnect.de ([87.158.122.72] helo=pandem0nium) by cora.hrz.tu-chemnitz.de with esmtpsa (TLSv1:DHE-RSA-AES128-SHA:128) (Exim 4.80.1) (envelope-from ) id 1Uwcd9-0005fI-L1; Tue, 09 Jul 2013 20:27:16 +0200 Received: from dotslash by pandem0nium with local (Exim 4.80) (envelope-from ) id 1Uwcd7-00064f-07; Tue, 09 Jul 2013 20:27:13 +0200 From: Simon Wunderlich To: Johannes Berg Cc: linux-wireless@vger.kernel.org, Mathias Kretschmer , Simon Wunderlich Subject: [PATCHv4 5/5] ath9k: enable CSA functionality in ath9k Date: Tue, 9 Jul 2013 20:27:04 +0200 Message-Id: <1373394424-23298-6-git-send-email-siwu@hrz.tu-chemnitz.de> X-Mailer: git-send-email 1.7.10.4 In-Reply-To: <1373394424-23298-1-git-send-email-siwu@hrz.tu-chemnitz.de> References: <1373394424-23298-1-git-send-email-siwu@hrz.tu-chemnitz.de> X-purgate: clean X-purgate-type: clean X-purgate-ID: 154106::1373394435-0000051A-1659B071/0-0/0-0 X-Scan-AV: cora.hrz.tu-chemnitz.de; 2013-07-09 20:27:15; 54b59e1ea12ff37d6ef0bf32681d360f X-Scan-SA: cora.hrz.tu-chemnitz.de; 2013-07-09 20:27:16; dd3a7b9de5c5203d3b1f3e2b060aaf09 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.1 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 CSA is only enabled for one interface, but the same limitation applies for mac80211 too. It checks whether the beacon has been sent (different approaches for non-EDMA-enabled and EDMA-enabled devices), and completes the channel switch after that. Signed-off-by: Simon Wunderlich Signed-off-by: Mathias Kretschmer --- Changes to PATCHv2: * announce support for channel switch Changes to PATCHv1: * complete channel switch after the last beacon has been sent --- drivers/net/wireless/ath/ath9k/ath9k.h | 2 ++ drivers/net/wireless/ath/ath9k/beacon.c | 21 +++++++++++++++++++++ drivers/net/wireless/ath/ath9k/init.c | 1 + drivers/net/wireless/ath/ath9k/main.c | 17 +++++++++++++++++ drivers/net/wireless/ath/ath9k/xmit.c | 2 ++ 5 files changed, 43 insertions(+) diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index 579ed9c..3745487 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -424,6 +424,7 @@ void ath9k_beacon_assign_slot(struct ath_softc *sc, struct ieee80211_vif *vif); void ath9k_beacon_remove_slot(struct ath_softc *sc, struct ieee80211_vif *vif); void ath9k_set_tsfadjust(struct ath_softc *sc, struct ieee80211_vif *vif); void ath9k_set_beacon(struct ath_softc *sc); +bool ath9k_csa_is_finished(struct ath_softc *sc); /*******************/ /* Link Monitoring */ @@ -751,6 +752,7 @@ struct ath_softc { #endif struct ath_descdma txsdma; + struct ieee80211_vif *csa_vif; struct ath_ant_comb ant_comb; u8 ant_tx, ant_rx; diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c index fd1eeba..e400151 100644 --- a/drivers/net/wireless/ath/ath9k/beacon.c +++ b/drivers/net/wireless/ath/ath9k/beacon.c @@ -310,6 +310,23 @@ void ath9k_set_tsfadjust(struct ath_softc *sc, struct ieee80211_vif *vif) (unsigned long long)tsfadjust, avp->av_bslot); } +bool ath9k_csa_is_finished(struct ath_softc *sc) +{ + struct ieee80211_vif *vif; + + vif = sc->csa_vif; + if (!vif || !vif->csa_active) + return false; + + if (!ieee80211_csa_is_complete(vif)) + return false; + + ieee80211_csa_finish(vif); + vif->csa_active = 0; + sc->csa_vif = NULL; + return true; +} + void ath9k_beacon_tasklet(unsigned long data) { struct ath_softc *sc = (struct ath_softc *)data; @@ -355,6 +372,10 @@ void ath9k_beacon_tasklet(unsigned long data) return; } + /* EDMA devices check that in the tx completion function. */ + if (!edma && ath9k_csa_is_finished(sc)) + return; + slot = ath9k_beacon_choose_slot(sc); vif = sc->beacon.bslot[slot]; diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c index f359b0d..3ce83c4 100644 --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c @@ -807,6 +807,7 @@ void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw) hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN; hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS; hw->wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL; + hw->wiphy->flags |= WIPHY_FLAG_HAS_CHANNEL_SWITCH; #ifdef CONFIG_PM_SLEEP if ((ah->caps.hw_caps & ATH9K_HW_WOW_DEVICE_CAPABLE) && diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index d1ce3da..6844968 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -1026,6 +1026,9 @@ static void ath9k_remove_interface(struct ieee80211_hw *hw, if (ath9k_uses_beacons(vif->type)) ath9k_beacon_remove_slot(sc, vif); + if (sc->csa_vif == vif) + sc->csa_vif = NULL; + ath9k_ps_wakeup(sc); ath9k_calculate_summary_state(hw, NULL); ath9k_ps_restore(sc); @@ -2319,6 +2322,19 @@ static void ath9k_sw_scan_complete(struct ieee80211_hw *hw) clear_bit(SC_OP_SCANNING, &sc->sc_flags); } +static void ath9k_channel_switch_beacon(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct cfg80211_chan_def *chandef) +{ + struct ath_softc *sc = hw->priv; + + /* mac80211 does not support CSA in multi-if cases (yet) */ + if (WARN_ON(sc->csa_vif)) + return; + + sc->csa_vif = vif; +} + struct ieee80211_ops ath9k_ops = { .tx = ath9k_tx, .start = ath9k_start, @@ -2366,4 +2382,5 @@ struct ieee80211_ops ath9k_ops = { #endif .sw_scan_start = ath9k_sw_scan_start, .sw_scan_complete = ath9k_sw_scan_complete, + .channel_switch_beacon = ath9k_channel_switch_beacon, }; diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index eab0fcb..cec670d 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c @@ -2282,6 +2282,8 @@ void ath_tx_edma_tasklet(struct ath_softc *sc) if (ts.qid == sc->beacon.beaconq) { sc->beacon.tx_processed = true; sc->beacon.tx_last = !(ts.ts_status & ATH9K_TXERR_MASK); + + ath9k_csa_is_finished(sc); continue; }