From patchwork Thu Feb 12 13:53:18 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michal Kazior X-Patchwork-Id: 5819741 Return-Path: X-Original-To: patchwork-ath10k@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id C08ACBF440 for ; Thu, 12 Feb 2015 13:55:04 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id B6C9520220 for ; Thu, 12 Feb 2015 13:55:03 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.9]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 9AE932021B for ; Thu, 12 Feb 2015 13:55:02 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1YLuEE-0008Ur-Qs; Thu, 12 Feb 2015 13:54:50 +0000 Received: from mail-la0-f45.google.com ([209.85.215.45]) by bombadil.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1YLuEB-0008Ej-EJ for ath10k@lists.infradead.org; Thu, 12 Feb 2015 13:54:48 +0000 Received: by labms9 with SMTP id ms9so4260416lab.10 for ; Thu, 12 Feb 2015 05:54:23 -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; bh=tPNCGaYt8gUSQnx9us7n87tT7LBan2wpnudOmVGRdpo=; b=alLkjUtlT3QLFV0ef85tB4D8cXS795TYyLodG2r6Ff591I0Eol5D50VoMysgTuJhfr fkBZmINczN/xL3RIqiGr4mIx1uF3MULtfW7ewQHhFi1FUqJCd1Qqux71uOut2VGNtpvB 1Zv/y/0wC5PYYnClM2pgo8oO9mm+hn7L/4rWI= 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; bh=tPNCGaYt8gUSQnx9us7n87tT7LBan2wpnudOmVGRdpo=; b=UXFJfAms0S1rT9/uPeEv6zUCp9FRLWKDStfEn2CZOELjsN8/0NclPGPeVuuJ/1zeGU /W3gnehGuNqRLq+arLasQHMia26QXfMxsw0wYgukFILprBbGNjJdn5NCusB/QuSuQYiB X4Be87/Ll3IjzoEbLEDm3MxgixNvrJGWAWHO26G3GxtVHYLUO4HCeeUN900LzHLAmgi1 CKaaM8GqFFTJiqwKJdCOEhwWOCKhso8FFd1KcwzENjD+fR7xzc2F+z7eO05A7rCr0E+J SwsiiUGQxKT9WTRYJvlu0YTfjVDetItGndRYatm1xLOib25pqlxYN3VR9IFkZxEfcCG/ c/rg== X-Gm-Message-State: ALoCoQkBMtOlyNj44qvcviMgIV5MJWZoP7IeRCLcLuTWImYB3LXoV43TL3MeS4GY2YPheKTLuKKlXY0+cJRNlKRscuCIcxC+Vbf3xtEiOYwy03M2bQPXff1yh5r7fBDg9RQ3+rQWwwzdnqhPnTJe8ZsKYteJ/E4ZKW/CSFwSOvNDskgWFoMLSRo= X-Received: by 10.152.242.132 with SMTP id wq4mr3337533lac.79.1423749263511; Thu, 12 Feb 2015 05:54:23 -0800 (PST) Received: from bob.homerouter.cpe (apn-31-1-134-151.dynamic.gprs.plus.pl. [31.1.134.151]) by mx.google.com with ESMTPSA id k1sm782490laf.19.2015.02.12.05.54.22 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 12 Feb 2015 05:54:22 -0800 (PST) From: Michal Kazior To: ath10k@lists.infradead.org Subject: [PATCH] ath10k: fix AP/IBSS CSA with template based fw Date: Thu, 12 Feb 2015 14:53:18 +0100 Message-Id: <1423749198-11346-1-git-send-email-michal.kazior@tieto.com> X-Mailer: git-send-email 1.8.5.3 X-DomainID: tieto.com X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20150212_055447_682838_5CC7ACDD X-CRM114-Status: GOOD ( 14.84 ) X-Spam-Score: -0.8 (/) Cc: linux-wireless@vger.kernel.org, Michal Kazior X-BeenThere: ath10k@lists.infradead.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: "ath10k" Errors-To: ath10k-bounces+patchwork-ath10k=patchwork.kernel.org@lists.infradead.org X-Spam-Status: No, score=-4.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_MED, T_DKIM_INVALID, T_RP_MATCHES_RCVD, 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 qca6174 with wmi-tlv firmware uses offloaded beaconing scheme (i.e. templates). This requires a little different approach when implementing CSA. Add missing code to update CS count and report CSA completion to mac80211. Without it channel switch was never finished. To avoid races during interface teardown data_lock has been used to protect is_up and is_started so they can be compared against before scheduling count down work. Signed-off-by: Michal Kazior --- @Kalle: I'm deferring the chanctx patchset v4 until this gets applied. I'd like to avoid posting patches without a valid parent id and leaving you with some weird conflicts and implicit depndencies in the code to deal with. drivers/net/wireless/ath/ath10k/core.h | 1 + drivers/net/wireless/ath/ath10k/mac.c | 70 ++++++++++++++++++++++++++++++- drivers/net/wireless/ath/ath10k/wmi-tlv.c | 8 ++++ 3 files changed, 77 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h index d60e46f..43fa2ec 100644 --- a/drivers/net/wireless/ath/ath10k/core.h +++ b/drivers/net/wireless/ath/ath10k/core.h @@ -320,6 +320,7 @@ struct ath10k_vif { int num_legacy_stations; int txpower; struct wmi_wmm_params_all_arg wmm_params; + struct work_struct ap_csa_work; }; struct ath10k_vif_iter { diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c index d6d2f0f..631e73b 100644 --- a/drivers/net/wireless/ath/ath10k/mac.c +++ b/drivers/net/wireless/ath/ath10k/mac.c @@ -1055,6 +1055,10 @@ static int ath10k_mac_setup_bcn_tmpl(struct ath10k_vif *arvif) if (!test_bit(WMI_SERVICE_BEACON_OFFLOAD, ar->wmi.svc_map)) return 0; + if (arvif->vdev_type != WMI_VDEV_TYPE_AP && + arvif->vdev_type != WMI_VDEV_TYPE_IBSS) + return 0; + bcn = ieee80211_beacon_get_template(hw, vif, &offs); if (!bcn) { ath10k_warn(ar, "failed to get beacon template from mac80211\n"); @@ -1100,6 +1104,9 @@ static int ath10k_mac_setup_prb_tmpl(struct ath10k_vif *arvif) if (!test_bit(WMI_SERVICE_BEACON_OFFLOAD, ar->wmi.svc_map)) return 0; + if (arvif->vdev_type != WMI_VDEV_TYPE_AP) + return 0; + prb = ieee80211_proberesp_get(hw, vif); if (!prb) { ath10k_warn(ar, "failed to get probe resp template from mac80211\n"); @@ -1129,10 +1136,9 @@ static void ath10k_control_beaconing(struct ath10k_vif *arvif, if (!info->enable_beacon) { ath10k_vdev_stop(arvif); + spin_lock_bh(&arvif->ar->data_lock); arvif->is_started = false; arvif->is_up = false; - - spin_lock_bh(&arvif->ar->data_lock); ath10k_mac_vif_beacon_free(arvif); spin_unlock_bh(&arvif->ar->data_lock); @@ -1335,6 +1341,49 @@ static int ath10k_mac_vif_disable_keepalive(struct ath10k_vif *arvif) return 0; } +static void ath10k_mac_vif_ap_csa_count_down(struct ath10k_vif *arvif) +{ + struct ath10k *ar = arvif->ar; + struct ieee80211_vif *vif = arvif->vif; + int ret; + + if (arvif->vdev_type != WMI_VDEV_TYPE_AP) + return; + + if (!vif->csa_active) + return; + + if (!arvif->is_up) + return; + + if (!ieee80211_csa_is_complete(vif)) { + ieee80211_csa_update_counter(vif); + + ret = ath10k_mac_setup_bcn_tmpl(arvif); + if (ret) + ath10k_warn(ar, "failed to update bcn tmpl during csa: %d\n", + ret); + + ret = ath10k_mac_setup_prb_tmpl(arvif); + if (ret) + ath10k_warn(ar, "failed to update prb tmpl during csa: %d\n", + ret); + } else { + ieee80211_csa_finish(vif); + } +} + +static void ath10k_mac_vif_ap_csa_work(struct work_struct *work) +{ + struct ath10k_vif *arvif = container_of(work, struct ath10k_vif, + ap_csa_work); + struct ath10k *ar = arvif->ar; + + mutex_lock(&ar->conf_mutex); + ath10k_mac_vif_ap_csa_count_down(arvif); + mutex_unlock(&ar->conf_mutex); +} + /**********************/ /* Station management */ /**********************/ @@ -1852,7 +1901,9 @@ static void ath10k_bss_assoc(struct ieee80211_hw *hw, return; } + spin_lock_bh(&arvif->ar->data_lock); arvif->is_up = true; + spin_unlock_bh(&arvif->ar->data_lock); } static void ath10k_bss_disassoc(struct ieee80211_hw *hw, @@ -1874,7 +1925,9 @@ static void ath10k_bss_disassoc(struct ieee80211_hw *hw, arvif->def_wep_key_idx = -1; + spin_lock_bh(&arvif->ar->data_lock); arvif->is_up = false; + spin_unlock_bh(&arvif->ar->data_lock); } static int ath10k_station_assoc(struct ath10k *ar, @@ -2931,6 +2984,16 @@ static void ath10k_config_chan(struct ath10k *ar) if (arvif->vdev_type == WMI_VDEV_TYPE_MONITOR) continue; + ret = ath10k_mac_setup_bcn_tmpl(arvif); + if (ret) + ath10k_warn(ar, "failed to update bcn tmpl during csa: %d\n", + ret); + + ret = ath10k_mac_setup_prb_tmpl(arvif); + if (ret) + ath10k_warn(ar, "failed to update prb tmpl during csa: %d\n", + ret); + ret = ath10k_vdev_restart(arvif); if (ret) { ath10k_warn(ar, "failed to restart vdev %d: %d\n", @@ -3091,6 +3154,7 @@ static int ath10k_add_interface(struct ieee80211_hw *hw, arvif->vif = vif; INIT_LIST_HEAD(&arvif->list); + INIT_WORK(&arvif->ap_csa_work, ath10k_mac_vif_ap_csa_work); if (ar->free_vdev_map == 0) { ath10k_warn(ar, "Free vdev map is empty, no more interfaces allowed.\n"); @@ -3308,6 +3372,8 @@ static void ath10k_remove_interface(struct ieee80211_hw *hw, struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif); int ret; + cancel_work_sync(&arvif->ap_csa_work); + mutex_lock(&ar->conf_mutex); spin_lock_bh(&ar->data_lock); diff --git a/drivers/net/wireless/ath/ath10k/wmi-tlv.c b/drivers/net/wireless/ath/ath10k/wmi-tlv.c index 71614ba..538a643 100644 --- a/drivers/net/wireless/ath/ath10k/wmi-tlv.c +++ b/drivers/net/wireless/ath/ath10k/wmi-tlv.c @@ -17,6 +17,7 @@ #include "core.h" #include "debug.h" #include "hw.h" +#include "mac.h" #include "wmi.h" #include "wmi-ops.h" #include "wmi-tlv.h" @@ -168,6 +169,7 @@ static int ath10k_wmi_tlv_event_bcn_tx_status(struct ath10k *ar, { const void **tb; const struct wmi_tlv_bcn_tx_status_ev *ev; + struct ath10k_vif *arvif; u32 vdev_id, tx_status; int ret; @@ -201,6 +203,12 @@ static int ath10k_wmi_tlv_event_bcn_tx_status(struct ath10k *ar, break; } + spin_lock_bh(&ar->data_lock); + arvif = ath10k_get_arvif(ar, vdev_id); + if (arvif && arvif->is_up) + ieee80211_queue_work(ar->hw, &arvif->ap_csa_work); + spin_unlock_bh(&ar->data_lock); + kfree(tb); return 0; }