From patchwork Thu Dec 27 21:43:54 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thomas Pedersen X-Patchwork-Id: 1913701 Return-Path: X-Original-To: patchwork-linux-wireless@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork2.kernel.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by patchwork2.kernel.org (Postfix) with ESMTP id 1D19FDF2A2 for ; Thu, 27 Dec 2012 21:44:34 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751815Ab2L0Voc (ORCPT ); Thu, 27 Dec 2012 16:44:32 -0500 Received: from mail-pa0-f53.google.com ([209.85.220.53]:34368 "EHLO mail-pa0-f53.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751492Ab2L0Vob (ORCPT ); Thu, 27 Dec 2012 16:44:31 -0500 Received: by mail-pa0-f53.google.com with SMTP id hz1so5662804pad.26 for ; Thu, 27 Dec 2012 13:44:31 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=x-received:from:to:cc:subject:date:message-id:x-mailer:in-reply-to :references:x-gm-message-state; bh=EScGZcNPPLoTbR1CwmpZ/3zg8hElGOwK+swxmUmur78=; b=pD7RQB/kw7pUFwb4ZEyiTlU8WBZgPikoQKpgp3fpuHsrbbUaxC7+5D4Acm4Xtv7vh7 +Y550PCSyOxeyi03b86CtW7I7twWZ584/0VTFy8GhXkYHEin8iE15va60/LuWwT7p5ka 774xtjFSgsvHuBgRVW5zM+FA7Pp7cOGNsaN6bu7OIjkQO7qq/z6l6vcuo2Fr+kPqc0uX nphkKqvOvYucaoXDefcKxs6hiRHa38jIWpVgzF8TrcEJKlqg1c9sdIEAyFMOPurfNpdd Hfbp7WPkkYC9JPtediIVzwvdW58JhB9Wn3WbjFNIcdoXfmFnr5AGFJM8rovG/m80TKSX qbZw== X-Received: by 10.68.234.201 with SMTP id ug9mr98360891pbc.63.1356644671156; Thu, 27 Dec 2012 13:44:31 -0800 (PST) Received: from cable.lan (70-35-43-50.static.wiline.com. [70.35.43.50]) by mx.google.com with ESMTPS id kl3sm18416026pbc.15.2012.12.27.13.44.28 (version=TLSv1/SSLv3 cipher=OTHER); Thu, 27 Dec 2012 13:44:29 -0800 (PST) From: Thomas Pedersen To: linville@tuxdriver.org Cc: j@w1.fi, linux-wireless@vger.kernel.org, johannes@sipsolutions.net, Thomas Pedersen Subject: [PATCH 2/4] mac80211_hwsim: hrtimer beacon Date: Thu, 27 Dec 2012 13:43:54 -0800 Message-Id: <1356644636-5309-2-git-send-email-thomas@cozybit.com> X-Mailer: git-send-email 1.7.10.4 In-Reply-To: <1356644636-5309-1-git-send-email-thomas@cozybit.com> References: <1356644636-5309-1-git-send-email-thomas@cozybit.com> X-Gm-Message-State: ALoCoQkpkCTCPOyEHa7d52c0FZroJwfw0c+3nVpS0ax3rA+lqrjB1fL97x47UqWJKElpD/e8LmvH Sender: linux-wireless-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org For testing various timing-sensitive protocols (power save, MBCA, etc.), a beacon accuracy of jiffies is not sufficient. A tasklet_hrtimer is used for the beacon since it runs the callback in soft-IRQ context with hrtimer resolution. Also handle BSS_CHANGED_BEACON_ENABLED for hwsim. Signed-off-by: Thomas Pedersen --- drivers/net/wireless/mac80211_hwsim.c | 69 ++++++++++++++++++++++----------- 1 file changed, 47 insertions(+), 22 deletions(-) diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c index 59761fb..f353d5e 100644 --- a/drivers/net/wireless/mac80211_hwsim.c +++ b/drivers/net/wireless/mac80211_hwsim.c @@ -333,11 +333,11 @@ struct mac80211_hwsim_data { int scan_chan_idx; struct ieee80211_channel *channel; - unsigned long beacon_int; /* in jiffies unit */ + u64 beacon_int /* beacon interval in us */; unsigned int rx_filter; bool started, idle, scanning; struct mutex mutex; - struct timer_list beacon_timer; + struct tasklet_hrtimer beacon_timer; enum ps_mode { PS_DISABLED, PS_ENABLED, PS_AUTO_POLL, PS_MANUAL_POLL } ps; @@ -897,7 +897,7 @@ static void mac80211_hwsim_stop(struct ieee80211_hw *hw) { struct mac80211_hwsim_data *data = hw->priv; data->started = false; - del_timer(&data->beacon_timer); + tasklet_hrtimer_cancel(&data->beacon_timer); wiphy_debug(hw->wiphy, "%s\n", __func__); } @@ -981,21 +981,32 @@ static void mac80211_hwsim_beacon_tx(void *arg, u8 *mac, rcu_dereference(vif->chanctx_conf)->def.chan); } - -static void mac80211_hwsim_beacon(unsigned long arg) +static enum hrtimer_restart +mac80211_hwsim_beacon(struct hrtimer *timer) { - struct ieee80211_hw *hw = (struct ieee80211_hw *) arg; - struct mac80211_hwsim_data *data = hw->priv; + struct tasklet_hrtimer *ttimer = container_of(timer, + struct tasklet_hrtimer, + timer); + struct mac80211_hwsim_data *data = container_of(ttimer, + struct mac80211_hwsim_data, + beacon_timer); + struct ieee80211_hw *hw = data->hw; + u64 bcn_int = data->beacon_int; + ktime_t next_bcn; if (!data->started) - return; + goto out; ieee80211_iterate_active_interfaces_atomic( hw, IEEE80211_IFACE_ITER_NORMAL, - mac80211_hwsim_beacon_tx, hw); + mac80211_hwsim_beacon_tx, data); + - data->beacon_timer.expires = jiffies + data->beacon_int; - add_timer(&data->beacon_timer); + next_bcn = ktime_add(hrtimer_get_expires(timer), + ns_to_ktime(bcn_int * 1000)); + tasklet_hrtimer_start(ttimer, next_bcn, HRTIMER_MODE_ABS); +out: + return HRTIMER_NORESTART; } static const char *hwsim_chantypes[] = { @@ -1033,9 +1044,12 @@ static int mac80211_hwsim_config(struct ieee80211_hw *hw, u32 changed) data->power_level = conf->power_level; if (!data->started || !data->beacon_int) - del_timer(&data->beacon_timer); - else - mod_timer(&data->beacon_timer, jiffies + data->beacon_int); + tasklet_hrtimer_cancel(&data->beacon_timer); + else if (!hrtimer_is_queued(&data->beacon_timer.timer)) { + tasklet_hrtimer_start(&data->beacon_timer, + ns_to_ktime(data->beacon_int * 1000), + HRTIMER_MODE_REL); + } return 0; } @@ -1085,12 +1099,22 @@ static void mac80211_hwsim_bss_info_changed(struct ieee80211_hw *hw, if (changed & BSS_CHANGED_BEACON_INT) { wiphy_debug(hw->wiphy, " BCNINT: %d\n", info->beacon_int); - data->beacon_int = 1024 * info->beacon_int / 1000 * HZ / 1000; - if (WARN_ON(!data->beacon_int)) - data->beacon_int = 1; - if (data->started) - mod_timer(&data->beacon_timer, - jiffies + data->beacon_int); + data->beacon_int = info->beacon_int * 1024; + } + + if (changed & BSS_CHANGED_BEACON_ENABLED) { + wiphy_debug(hw->wiphy, " BCN EN: %d\n", info->enable_beacon); + if (data->started && + !hrtimer_is_queued(&data->beacon_timer.timer) && + info->enable_beacon) { + if (WARN_ON(!data->beacon_int)) + data->beacon_int = 1000 * 1024; + tasklet_hrtimer_start(&data->beacon_timer, + ns_to_ktime(data->beacon_int * + 1000), + HRTIMER_MODE_REL); + } else if (!info->enable_beacon) + tasklet_hrtimer_cancel(&data->beacon_timer); } if (changed & BSS_CHANGED_ERP_CTS_PROT) { @@ -2371,8 +2395,9 @@ static int __init init_mac80211_hwsim(void) data->debugfs, data, &hwsim_fops_group); - setup_timer(&data->beacon_timer, mac80211_hwsim_beacon, - (unsigned long) hw); + tasklet_hrtimer_init(&data->beacon_timer, + mac80211_hwsim_beacon, + CLOCK_REALTIME, HRTIMER_MODE_ABS); list_add_tail(&data->list, &hwsim_radios); }