From patchwork Tue Feb 3 07:14:30 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Emmanuel Grumbach X-Patchwork-Id: 5766671 X-Patchwork-Delegate: johannes@sipsolutions.net 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.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 6CC6F9F380 for ; Tue, 3 Feb 2015 07:15:19 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 7E89C20A6A for ; Tue, 3 Feb 2015 07:15:17 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 6439520A6B for ; Tue, 3 Feb 2015 07:15:16 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S965365AbbBCHPI (ORCPT ); Tue, 3 Feb 2015 02:15:08 -0500 Received: from mga02.intel.com ([134.134.136.20]:1142 "EHLO mga02.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S965287AbbBCHPE (ORCPT ); Tue, 3 Feb 2015 02:15:04 -0500 Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by orsmga101.jf.intel.com with ESMTP; 02 Feb 2015 23:15:02 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.09,511,1418112000"; d="scan'208";a="671889900" Received: from egrumbacbox.jer.intel.com ([10.13.6.46]) by fmsmga002.fm.intel.com with ESMTP; 02 Feb 2015 23:15:00 -0800 From: Emmanuel Grumbach To: linux-wireless@vger.kernel.org Cc: Arik Nemtsov , Arik Nemtsov , Emmanuel Grumbach Subject: [PATCH 11/19] iwlwifi: mvm: ignore stale TDLS ch-switch responses Date: Tue, 3 Feb 2015 09:14:30 +0200 Message-Id: <1422947678-16917-11-git-send-email-emmanuel.grumbach@intel.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1422947482.30742.8.camel@egrumbacBox> References: <1422947482.30742.8.camel@egrumbacBox> Sender: linux-wireless-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, 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 From: Arik Nemtsov During out-of-channel activities (e.g. scan) TDLS ch-switch responses from a peer are kept in FW. These packets arrive only after the out-of-channel activity is complete, which can be in the order of several seconds. Since TDLS ch-sw has no dialog-token-like mechanism for distinguishing sessions, use the GP2 time of the incoming ch-switch response to discern validity. For this purpose record the GP2 time of an outgoing TDLS ch-sw request and compare to the Rx time of the ch-sw response. The methods works in practice since the GP2 time of FW-deferred Rx is accurate and contains the real Rx timestamp. Signed-off-by: Arik Nemtsov Reviewed-by: Johannes Berg Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/iwlwifi/mvm/mvm.h | 3 +++ drivers/net/wireless/iwlwifi/mvm/tdls.c | 15 +++++++++++++-- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/mvm/mvm.h b/drivers/net/wireless/iwlwifi/mvm/mvm.h index fc80b7b..ed09726 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/iwlwifi/mvm/mvm.h @@ -798,6 +798,9 @@ struct iwl_mvm { struct cfg80211_chan_def chandef; struct sk_buff *skb; /* ch sw template */ u32 ch_sw_tm_ie; + + /* timestamp of last ch-sw request sent (GP2 time) */ + u32 sent_timestamp; } peer; } tdls_cs; diff --git a/drivers/net/wireless/iwlwifi/mvm/tdls.c b/drivers/net/wireless/iwlwifi/mvm/tdls.c index ea1831c..a87b506 100644 --- a/drivers/net/wireless/iwlwifi/mvm/tdls.c +++ b/drivers/net/wireless/iwlwifi/mvm/tdls.c @@ -64,6 +64,8 @@ #include #include "mvm.h" #include "time-event.h" +#include "iwl-io.h" +#include "iwl-prph.h" #define TU_TO_US(x) (x * 1024) #define TU_TO_MS(x) (TU_TO_US(x) / 1000) @@ -250,6 +252,11 @@ static void iwl_mvm_tdls_update_cs_state(struct iwl_mvm *mvm, iwl_mvm_tdls_cs_state_str(state)); mvm->tdls_cs.state = state; + /* we only send requests to our switching peer - update sent time */ + if (state == IWL_MVM_TDLS_SW_REQ_SENT) + mvm->tdls_cs.peer.sent_timestamp = + iwl_read_prph(mvm->trans, DEVICE_SYSTEM_TIME_REG); + if (state == IWL_MVM_TDLS_SW_IDLE) mvm->tdls_cs.cur_sta_id = IWL_MVM_STATION_COUNT; } @@ -302,7 +309,7 @@ out: static int iwl_mvm_tdls_check_action(struct iwl_mvm *mvm, enum iwl_tdls_channel_switch_type type, - const u8 *peer, bool peer_initiator) + const u8 *peer, bool peer_initiator, u32 timestamp) { bool same_peer = false; int ret = 0; @@ -341,6 +348,9 @@ iwl_mvm_tdls_check_action(struct iwl_mvm *mvm, else if (type == TDLS_SEND_CHAN_SW_REQ) /* wait for idle before sending another request */ ret = -EBUSY; + else if (timestamp <= mvm->tdls_cs.peer.sent_timestamp) + /* we got a stale response - ignore it */ + ret = -EINVAL; break; case IWL_MVM_TDLS_SW_RESP_RCVD: /* @@ -399,7 +409,8 @@ iwl_mvm_tdls_config_channel_switch(struct iwl_mvm *mvm, lockdep_assert_held(&mvm->mutex); - ret = iwl_mvm_tdls_check_action(mvm, type, peer, peer_initiator); + ret = iwl_mvm_tdls_check_action(mvm, type, peer, peer_initiator, + timestamp); if (ret) return ret;