From patchwork Tue Oct 15 10:29:24 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marco Porsch X-Patchwork-Id: 3044271 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 C1C699F2B6 for ; Tue, 15 Oct 2013 10:29:57 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 0D8F920265 for ; Tue, 15 Oct 2013 10:29:53 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 6120920263 for ; Tue, 15 Oct 2013 10:29:51 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1758716Ab3JOK3t (ORCPT ); Tue, 15 Oct 2013 06:29:49 -0400 Received: from mail-bk0-f49.google.com ([209.85.214.49]:38192 "EHLO mail-bk0-f49.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1758265Ab3JOK3s (ORCPT ); Tue, 15 Oct 2013 06:29:48 -0400 Received: by mail-bk0-f49.google.com with SMTP id w14so63991bkz.36 for ; Tue, 15 Oct 2013 03:29:47 -0700 (PDT) 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=4ye79kiNJjCe3XdQRbSzisZb5Ew3hScI1BHag7itIBY=; b=LDocBEWK4ar0dgDYOwm+974SxutCszu2cL18SrRB11a/dccpkAkz8aLRa1W1OoO2/F rLxTQ5nmpng4qSrTlF5w0RYqjon065mRYvb01SQ8Hom6qkbmLeyHiM2wxjLSCyH2sarQ p+raGvZnnTNWqf4t1MFMxwM0awhgEu5fs/TaL5yB4uvYCEdE2m5OkdrYR08geaOpc24l rCx/MpeGtdxKUOSmuWXYZOl4J2x4hlhnJ0KB3H7s2fO5Cr8Z7ZuHjpKUgRBq5Gd+SCg1 ALNYOsceCb34Ik79sZyDrwawif5atqQ5j83nZcYJ2bUVJ7OwY/EuxmICkd5b/bqICx3O Zt5w== X-Gm-Message-State: ALoCoQnC/Hod3TRzDkFQ5Z+3WHUcG8l91aBH6GdSgKJWtTBGT4tWDD6XVTFPAmkuXC+LjdynDeCR X-Received: by 10.204.123.199 with SMTP id q7mr35352372bkr.10.1381832987303; Tue, 15 Oct 2013 03:29:47 -0700 (PDT) Received: from X220-marco.infotech.tu-chemnitz.de (perseus.infotech.tu-chemnitz.de. [134.109.4.8]) by mx.google.com with ESMTPSA id b6sm43116097bko.16.1969.12.31.16.00.00 (version=TLSv1.1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Tue, 15 Oct 2013 03:29:46 -0700 (PDT) From: Marco Porsch To: johannes@sipsolutions.net Cc: linux-wireless@vger.kernel.org, devel@lists.open80211s.org, Marco Porsch Subject: [PATCH] mac80211: fixes for mesh powersave logic Date: Tue, 15 Oct 2013 12:29:24 +0200 Message-Id: <1381832964-3684-1-git-send-email-marco@cozybit.com> X-Mailer: git-send-email 1.8.1.2 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.4 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=ham 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 This patch fixes errors in the mesh powersave logic which cause that remote peers do not get peer power mode change notifications and mesh peer service periods (MPSPs) got stuck. When closing a peer link, set the (now invalid) peer-specific power mode to 'unknown'. Avoid overhead when local power mode is unchanged. Reliably clear MPSP flags on peering status update. Avoid MPSP flags getting stuck by not requesting a further MPSP ownership if we already are an MPSP owner. Signed-off-by: Marco Porsch --- net/mac80211/cfg.c | 4 ++-- net/mac80211/mesh_plink.c | 3 ++- net/mac80211/mesh_ps.c | 33 ++++++++++++++++++--------------- 3 files changed, 22 insertions(+), 18 deletions(-) diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index b0a651c..f1e1944 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -1342,8 +1342,8 @@ static int sta_apply_parameters(struct ieee80211_local *local, sta->plink_state = params->plink_state; ieee80211_mps_sta_status_update(sta); - changed |= - ieee80211_mps_local_status_update(sdata); + changed |= ieee80211_mps_set_sta_local_pm(sta, + NL80211_MESH_POWER_UNKNOWN); break; default: /* nothing */ diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c index 6b65d50..4301aa5 100644 --- a/net/mac80211/mesh_plink.c +++ b/net/mac80211/mesh_plink.c @@ -222,7 +222,8 @@ static u32 __mesh_plink_deactivate(struct sta_info *sta) mesh_path_flush_by_nexthop(sta); ieee80211_mps_sta_status_update(sta); - changed |= ieee80211_mps_local_status_update(sdata); + changed |= ieee80211_mps_set_sta_local_pm(sta, + NL80211_MESH_POWER_UNKNOWN); return changed; } diff --git a/net/mac80211/mesh_ps.c b/net/mac80211/mesh_ps.c index 22290a9..0f79b78 100644 --- a/net/mac80211/mesh_ps.c +++ b/net/mac80211/mesh_ps.c @@ -152,6 +152,9 @@ u32 ieee80211_mps_set_sta_local_pm(struct sta_info *sta, { struct ieee80211_sub_if_data *sdata = sta->sdata; + if (sta->local_pm == pm) + return 0; + mps_dbg(sdata, "local STA operates in mode %d with %pM\n", pm, sta->sta.addr); @@ -245,6 +248,14 @@ void ieee80211_mps_sta_status_update(struct sta_info *sta) do_buffer = (pm != NL80211_MESH_POWER_ACTIVE); + /* clear the MPSP flags for non-peers or active STA */ + if (sta->plink_state != NL80211_PLINK_ESTAB) { + clear_sta_flag(sta, WLAN_STA_MPSP_OWNER); + clear_sta_flag(sta, WLAN_STA_MPSP_RECIPIENT); + } else if (!do_buffer) { + clear_sta_flag(sta, WLAN_STA_MPSP_OWNER); + } + /* Don't let the same PS state be set twice */ if (test_sta_flag(sta, WLAN_STA_PS_STA) == do_buffer) return; @@ -257,14 +268,6 @@ void ieee80211_mps_sta_status_update(struct sta_info *sta) } else { ieee80211_sta_ps_deliver_wakeup(sta); } - - /* clear the MPSP flags for non-peers or active STA */ - if (sta->plink_state != NL80211_PLINK_ESTAB) { - clear_sta_flag(sta, WLAN_STA_MPSP_OWNER); - clear_sta_flag(sta, WLAN_STA_MPSP_RECIPIENT); - } else if (!do_buffer) { - clear_sta_flag(sta, WLAN_STA_MPSP_OWNER); - } } static void mps_set_sta_peer_pm(struct sta_info *sta, @@ -444,8 +447,7 @@ static void mpsp_qos_null_append(struct sta_info *sta, */ static void mps_frame_deliver(struct sta_info *sta, int n_frames) { - struct ieee80211_sub_if_data *sdata = sta->sdata; - struct ieee80211_local *local = sdata->local; + struct ieee80211_local *local = sta->sdata->local; int ac; struct sk_buff_head frames; struct sk_buff *skb; @@ -558,10 +560,10 @@ void ieee80211_mpsp_trigger_process(u8 *qc, struct sta_info *sta, } /** - * ieee80211_mps_frame_release - release buffered frames in response to beacon + * ieee80211_mps_frame_release - release frames buffered due to mesh power save * * @sta: mesh STA - * @elems: beacon IEs + * @elems: IEs of beacon or probe response * * For peers if we have individually-addressed frames buffered or the peer * indicates buffered frames, send a corresponding MPSP trigger frame. Since @@ -588,9 +590,10 @@ void ieee80211_mps_frame_release(struct sta_info *sta, (!elems->awake_window || !le16_to_cpu(*elems->awake_window))) return; - for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) - buffer_local += skb_queue_len(&sta->ps_tx_buf[ac]) + - skb_queue_len(&sta->tx_filtered[ac]); + if (!test_sta_flag(sta, WLAN_STA_MPSP_OWNER)) + for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) + buffer_local += skb_queue_len(&sta->ps_tx_buf[ac]) + + skb_queue_len(&sta->tx_filtered[ac]); if (!has_buffered && !buffer_local) return;