From patchwork Wed Apr 13 05:53:17 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sujith Manoharan X-Patchwork-Id: 702701 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter1.kernel.org (8.14.4/8.14.3) with ESMTP id p3D5ouRp024794 for ; Wed, 13 Apr 2011 05:50:56 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752872Ab1DMFuy (ORCPT ); Wed, 13 Apr 2011 01:50:54 -0400 Received: from mail-yi0-f46.google.com ([209.85.218.46]:57682 "EHLO mail-yi0-f46.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752842Ab1DMFuy (ORCPT ); Wed, 13 Apr 2011 01:50:54 -0400 Received: by yia27 with SMTP id 27so128812yia.19 for ; Tue, 12 Apr 2011 22:50:53 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:from:mime-version:content-type :content-transfer-encoding:message-id:date:to:x-mailer:cc:subject; bh=8I6Yaxca//zJxyOM0HRdGVdeYJehg7T93Mgsg2tQMq4=; b=cYFOE4S9D0sEpe63OKMpiaB1w0nmSvpzzyd+6rxzPHLCCyh9rELDLiW9r1UawQrluy wgzYseo0QXUI9fjnzL4M578xXy9GQKWy1BG3pWCFIO2+qW5d0C0Ybcadlp5LD+K0mmKC 9SrvKvbRUt18cIbSswfHvQ6RaKgM2737vJ+hw= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=from:mime-version:content-type:content-transfer-encoding:message-id :date:to:x-mailer:cc:subject; b=WwmPOZoOiL0i5cNzO9/zS/+VXHvfYNYcYzz5olUb/No/8wV5xZF/YZxkEnVuAH0ub3 tlMO3n/1jZCdNZNdkc9w6l4a7bUJXx4ti6SJ/BEK1IJbhZaX/JyEGEIqn4XkjqBtMJwg k2WJxiTY2ek6t9HXbWmZShqsxGA+nU7YMaSdk= Received: by 10.236.183.193 with SMTP id q41mr9846237yhm.80.1302673853331; Tue, 12 Apr 2011 22:50:53 -0700 (PDT) Received: from atheros-test ([182.72.177.186]) by mx.google.com with ESMTPS id x79sm125103yhn.83.2011.04.12.22.50.50 (version=TLSv1/SSLv3 cipher=OTHER); Tue, 12 Apr 2011 22:50:52 -0700 (PDT) From: Sujith MIME-Version: 1.0 Message-ID: <19877.14925.243648.521314@gargle.gargle.HOWL> Date: Wed, 13 Apr 2011 11:23:17 +0530 To: linville@tuxdriver.com X-Mailer: VM 8.1.1 under 23.3.1 (x86_64-unknown-linux-gnu) CC: linux-wireless@vger.kernel.org, ath9k-devel@venema.h4ckr.net Subject: [PATCH 06/40] ath9k_htc: Add TSF adjust capability Sender: linux-wireless-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.6 (demeter1.kernel.org [140.211.167.41]); Wed, 13 Apr 2011 05:50:56 +0000 (UTC) From: Sujith Manoharan In multi-interface mode, beacons/probe responses that are sent out must have their timestamp field updated. Calculate the TSF adjustment value for each beaconing interface and set it in the frame properly. Signed-off-by: Sujith Manoharan --- drivers/net/wireless/ath/ath9k/htc.h | 3 ++ drivers/net/wireless/ath/ath9k/htc_drv_beacon.c | 36 +++++++++++++++++++++++ drivers/net/wireless/ath/ath9k/htc_drv_main.c | 5 ++- drivers/net/wireless/ath/ath9k/htc_drv_txrx.c | 12 +++++++- 4 files changed, 54 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h index 31c6496..87e4ca9 100644 --- a/drivers/net/wireless/ath/ath9k/htc.h +++ b/drivers/net/wireless/ath/ath9k/htc.h @@ -245,6 +245,7 @@ struct ath9k_htc_vif { u16 seq_no; bool beacon_configured; int bslot; + __le64 tsfadjust; }; struct ath9k_vif_iter_data { @@ -480,6 +481,8 @@ void ath9k_htc_assign_bslot(struct ath9k_htc_priv *priv, struct ieee80211_vif *vif); void ath9k_htc_remove_bslot(struct ath9k_htc_priv *priv, struct ieee80211_vif *vif); +void ath9k_htc_set_tsfadjust(struct ath9k_htc_priv *priv, + struct ieee80211_vif *vif); void ath9k_htc_beaconq_config(struct ath9k_htc_priv *priv); void ath9k_htc_beacon_config(struct ath9k_htc_priv *priv, struct ieee80211_vif *vif); diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c index b561f70..2fad613 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c @@ -234,6 +234,7 @@ static void ath9k_htc_send_beacon(struct ath9k_htc_priv *priv, struct tx_beacon_header beacon_hdr; struct ath9k_htc_tx_ctl tx_ctl; struct ieee80211_tx_info *info; + struct ieee80211_mgmt *mgmt; struct sk_buff *beacon; u8 *tx_fhdr; @@ -257,6 +258,13 @@ static void ath9k_htc_send_beacon(struct ath9k_htc_priv *priv, return; } + /* + * Update the TSF adjust value here, the HW will + * add this value for every beacon. + */ + mgmt = (struct ieee80211_mgmt *)beacon->data; + mgmt->u.beacon.timestamp = avp->tsfadjust; + info = IEEE80211_SKB_CB(beacon); if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) { struct ieee80211_hdr *hdr = @@ -406,6 +414,34 @@ void ath9k_htc_remove_bslot(struct ath9k_htc_priv *priv, "Removed interface at beacon slot: %d\n", avp->bslot); } +/* + * Calculate the TSF adjustment value for all slots + * other than zero. + */ +void ath9k_htc_set_tsfadjust(struct ath9k_htc_priv *priv, + struct ieee80211_vif *vif) +{ + struct ath_common *common = ath9k_hw_common(priv->ah); + struct ath9k_htc_vif *avp = (struct ath9k_htc_vif *)vif->drv_priv; + struct htc_beacon_config *cur_conf = &priv->cur_beacon_conf; + u64 tsfadjust; + + if (avp->bslot == 0) + return; + + /* + * The beacon interval cannot be different for multi-AP mode, + * and we reach here only for VIF slots greater than zero, + * so beacon_interval is guaranteed to be set in cur_conf. + */ + tsfadjust = cur_conf->beacon_interval * avp->bslot / ATH9K_HTC_MAX_BCN_VIF; + avp->tsfadjust = cpu_to_le64(TU_TO_USEC(tsfadjust)); + + ath_dbg(common, ATH_DBG_CONFIG, + "tsfadjust is: %llu for bslot: %d\n", + (unsigned long long)tsfadjust, avp->bslot); +} + static void ath9k_htc_beacon_iter(void *data, u8 *mac, struct ieee80211_vif *vif) { bool *beacon_configured = (bool *)data; diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c index 293a9b3..6926ac0 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c @@ -1291,8 +1291,10 @@ static int ath9k_htc_add_interface(struct ieee80211_hw *hw, ath9k_htc_set_opmode(priv); if ((priv->ah->opmode == NL80211_IFTYPE_AP) && - !(priv->op_flags & OP_ANI_RUNNING)) + !(priv->op_flags & OP_ANI_RUNNING)) { + ath9k_hw_set_tsfadjust(priv->ah, 1); ath9k_htc_start_ani(priv); + } ath_dbg(common, ATH_DBG_CONFIG, "Attach a VIF of type: %d at idx: %d\n", vif->type, avp->index); @@ -1652,6 +1654,7 @@ static void ath9k_htc_bss_info_changed(struct ieee80211_hw *hw, if ((changed & BSS_CHANGED_BEACON_ENABLED) && bss_conf->enable_beacon) { ath_dbg(common, ATH_DBG_CONFIG, "Beacon enabled for BSS: %pM\n", bss_conf->bssid); + ath9k_htc_set_tsfadjust(priv, vif); priv->op_flags |= OP_ENABLE_BEACON; ath9k_htc_beacon_config(priv, vif); } diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c index 4a4f27b..b3f9485 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c @@ -82,11 +82,12 @@ int ath_htc_txq_update(struct ath9k_htc_priv *priv, int qnum, int ath9k_htc_tx_start(struct ath9k_htc_priv *priv, struct sk_buff *skb) { struct ieee80211_hdr *hdr; + struct ieee80211_mgmt *mgmt; struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); struct ieee80211_sta *sta = tx_info->control.sta; struct ieee80211_vif *vif = tx_info->control.vif; struct ath9k_htc_sta *ista; - struct ath9k_htc_vif *avp; + struct ath9k_htc_vif *avp = NULL; struct ath9k_htc_tx_ctl tx_ctl; enum htc_endpoint_id epid; u16 qnum; @@ -195,6 +196,15 @@ int ath9k_htc_tx_start(struct ath9k_htc_priv *priv, struct sk_buff *skb) memset(&mgmt_hdr, 0, sizeof(struct tx_mgmt_hdr)); + /* + * Set the TSF adjust value for probe response + * frame also. + */ + if (avp && unlikely(ieee80211_is_probe_resp(fc))) { + mgmt = (struct ieee80211_mgmt *)skb->data; + mgmt->u.probe_resp.timestamp = avp->tsfadjust; + } + tx_ctl.type = ATH9K_HTC_NORMAL; mgmt_hdr.node_idx = sta_idx;