linux-wireless.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Luca Coelho <luca@coelho.fi>
To: johannes@sipsolutions.net, michal.kazior@tieto.com
Cc: linux-wireless@vger.kernel.org
Subject: [PATCH 2/2] mac80211: use switch_vif_chanctx to change a running chanctx
Date: Fri, 23 May 2014 14:33:13 +0300	[thread overview]
Message-ID: <1400844793-18069-2-git-send-email-luca@coelho.fi> (raw)
In-Reply-To: <1400844793-18069-1-git-send-email-luca@coelho.fi>

From: Luciano Coelho <luciano.coelho@intel.com>

Instead of hammering a new channel into the running context, make use
of the new switch_vif_chanctx to let the driver decide how to perform
the switch.

Additionally, remove the IEEE80211_HW_CHANGE_RUNNING_CHANCTX flag,
since we never change a running context directly anymore.

Signed-off-by: Luciano Coelho <luciano.coelho@intel.com>
---
 include/net/mac80211.h |  6 ----
 net/mac80211/chan.c    | 77 +++++++++++++++++++++++++++++++++++++++++++-------
 2 files changed, 67 insertions(+), 16 deletions(-)

diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 236c5c3..38c10ea 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -1601,11 +1601,6 @@ struct ieee80211_tx_control {
  *	is not enabled the default action is to disconnect when getting the
  *	CSA frame.
  *
- * @IEEE80211_HW_CHANGE_RUNNING_CHANCTX: The hardware can change a
- *	channel context on-the-fly.  This is needed for channel switch
- *	on single-channel hardware.  It can also be used as an
- *	optimization in certain channel switch cases with
- *	multi-channel.
  */
 enum ieee80211_hw_flags {
 	IEEE80211_HW_HAS_RATE_CONTROL			= 1<<0,
@@ -1637,7 +1632,6 @@ enum ieee80211_hw_flags {
 	IEEE80211_HW_TIMING_BEACON_ONLY			= 1<<26,
 	IEEE80211_HW_SUPPORTS_HT_CCK_RATES		= 1<<27,
 	IEEE80211_HW_CHANCTX_STA_CSA			= 1<<28,
-	IEEE80211_HW_CHANGE_RUNNING_CHANCTX		= 1<<29,
 };
 
 /**
diff --git a/net/mac80211/chan.c b/net/mac80211/chan.c
index 3702d64..7084c2b 100644
--- a/net/mac80211/chan.c
+++ b/net/mac80211/chan.c
@@ -928,10 +928,10 @@ int ieee80211_vif_reserve_chanctx(struct ieee80211_sub_if_data *sdata,
 	new_ctx = ieee80211_find_reservation_chanctx(local, chandef, mode);
 	if (!new_ctx) {
 		if (ieee80211_chanctx_refcount(local, curr_ctx) == 1 &&
-		    (local->hw.flags & IEEE80211_HW_CHANGE_RUNNING_CHANCTX)) {
+		    local->ops->switch_vif_chanctx) {
 			/* if we're the only users of the chanctx and
-			 * the driver supports changing a running
-			 * context, reserve our current context
+			 * the driver supports chanctx switches
+			 * reserve our current context.
 			 */
 			new_ctx = curr_ctx;
 		} else if (ieee80211_can_create_new_chanctx(local)) {
@@ -956,6 +956,64 @@ out:
 	return ret;
 }
 
+static int
+ieee80211_vif_change_reserved_context(struct ieee80211_sub_if_data *sdata,
+				      struct ieee80211_chanctx *old_ctx)
+{
+	struct ieee80211_local *local = sdata->local;
+	const struct cfg80211_chan_def *chandef = &sdata->reserved_chandef;
+	struct ieee80211_chanctx *new_ctx;
+	struct ieee80211_vif_chanctx_switch vifs[1];
+	int err, changed;
+
+	lockdep_assert_held(&local->mtx);
+	lockdep_assert_held(&local->chanctx_mtx);
+
+	new_ctx = ieee80211_alloc_chanctx(local, chandef, old_ctx->mode);
+	if (!new_ctx) {
+		err = -ENOMEM;
+		goto err;
+	}
+
+	vifs[0].vif = &sdata->vif;
+	vifs[0].old_ctx = &old_ctx->conf;
+	vifs[0].new_ctx = &new_ctx->conf;
+
+	/* turn idle off *before* setting channel -- some drivers need that */
+	changed = ieee80211_idle_off(local);
+	ieee80211_hw_config(local, changed);
+
+	err = drv_switch_vif_chanctx(local, vifs, 1,
+				     CHANCTX_SWMODE_SWAP_CONTEXTS);
+	if (err)
+		goto err_idle;
+
+	rcu_assign_pointer(sdata->vif.chanctx_conf, &new_ctx->conf);
+
+	list_del_rcu(&old_ctx->list);
+
+	if (sdata->vif.type == NL80211_IFTYPE_AP)
+		__ieee80211_vif_copy_chanctx_to_vlans(sdata, false);
+
+	list_add_rcu(&new_ctx->list, &local->chanctx_list);
+	kfree_rcu(old_ctx, rcu_head);
+
+	ieee80211_recalc_txpower(sdata);
+	ieee80211_recalc_chanctx_chantype(local, new_ctx);
+	ieee80211_recalc_smps_chanctx(local, new_ctx);
+	ieee80211_recalc_radar_chanctx(local, new_ctx);
+	ieee80211_recalc_chanctx_min_def(local, new_ctx);
+	ieee80211_recalc_idle(local);
+
+	return 0;
+
+err_idle:
+	ieee80211_recalc_idle(local);
+	kfree_rcu(new_ctx, rcu_head);
+err:
+	return err;
+}
+
 int ieee80211_vif_use_reserved_context(struct ieee80211_sub_if_data *sdata,
 				       u32 *changed)
 {
@@ -999,8 +1057,7 @@ int ieee80211_vif_use_reserved_context(struct ieee80211_sub_if_data *sdata,
 
 	if (old_ctx == ctx) {
 		/* This is our own context, just change it */
-		ret = __ieee80211_vif_change_channel(sdata, old_ctx,
-						     &tmp_changed);
+		ret = ieee80211_vif_change_reserved_context(sdata, old_ctx);
 		if (ret)
 			goto out;
 	} else {
@@ -1016,14 +1073,14 @@ int ieee80211_vif_use_reserved_context(struct ieee80211_sub_if_data *sdata,
 
 		if (sdata->vif.type == NL80211_IFTYPE_AP)
 			__ieee80211_vif_copy_chanctx_to_vlans(sdata, false);
+
+		ieee80211_recalc_chanctx_chantype(local, ctx);
+		ieee80211_recalc_smps_chanctx(local, ctx);
+		ieee80211_recalc_radar_chanctx(local, ctx);
+		ieee80211_recalc_chanctx_min_def(local, ctx);
 	}
 
 	*changed = tmp_changed;
-
-	ieee80211_recalc_chanctx_chantype(local, ctx);
-	ieee80211_recalc_smps_chanctx(local, ctx);
-	ieee80211_recalc_radar_chanctx(local, ctx);
-	ieee80211_recalc_chanctx_min_def(local, ctx);
 out:
 	mutex_unlock(&local->chanctx_mtx);
 	return ret;
-- 
2.0.0.rc0


  reply	other threads:[~2014-05-23 11:33 UTC|newest]

Thread overview: 44+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-05-22 14:07 [PATCH v6 0/6] cfg/mac80211: implement multi-vif csa Michal Kazior
2014-05-22 14:07 ` [PATCH v6 1/6] mac80211: introduce switch_vif_chanctx op Michal Kazior
2014-05-22 14:45   ` Johannes Berg
2014-05-23  2:38     ` [PATCH] mac80211: add a single-transaction driver op to switch contexts Luca Coelho
2014-05-23  2:49       ` Luca Coelho
2014-05-23  7:51         ` Michal Kazior
2014-05-23  8:01       ` Michal Kazior
2014-05-23  8:58         ` Johannes Berg
2014-05-23  9:14           ` Luca Coelho
2014-05-23  9:30             ` Johannes Berg
2014-05-23  9:52               ` Johannes Berg
2014-05-23 11:33                 ` [PATCH 1/2] " Luca Coelho
2014-05-23 11:33                   ` Luca Coelho [this message]
2014-05-23 11:35                     ` [PATCH 2/2] mac80211: use switch_vif_chanctx to change a running chanctx Luca Coelho
2014-05-23 13:28                     ` Johannes Berg
2014-05-23 13:31                       ` Luca Coelho
2014-05-23 13:24                   ` [PATCH 1/2] mac80211: add a single-transaction driver op to switch contexts Johannes Berg
2014-05-23 13:30                     ` Luca Coelho
2014-05-23  9:16           ` [PATCH] " Michal Kazior
2014-05-23  9:26             ` Johannes Berg
2014-05-23  6:09     ` [PATCH v6 1/6] mac80211: introduce switch_vif_chanctx op Michal Kazior
2014-05-23  8:51       ` Johannes Berg
2014-05-23  9:10         ` Michal Kazior
2014-05-23  9:31           ` Johannes Berg
2014-05-22 14:07 ` [PATCH v6 2/6] mac80211: implement multi-vif in-place reservations Michal Kazior
2014-05-22 14:51   ` Johannes Berg
2014-05-23  6:16     ` Michal Kazior
2014-05-23 12:23       ` Michal Kazior
2014-05-23 13:14         ` Johannes Berg
2014-05-22 14:07 ` [PATCH v6 3/6] mac80211: make check_combinations() aware of chanctx reservation Michal Kazior
2014-05-22 14:07 ` [PATCH v6 4/6] mac80211: use chanctx reservation for AP CSA Michal Kazior
2014-05-22 14:54   ` Johannes Berg
2014-05-23  6:49     ` Michal Kazior
2014-05-23  8:44       ` Johannes Berg
2014-05-23  8:58         ` Michal Kazior
2014-05-23  9:07           ` Johannes Berg
2014-05-23  9:35             ` Michal Kazior
2014-05-23  9:53               ` Johannes Berg
2014-05-22 14:07 ` [PATCH v6 5/6] mac80211: use chanctx reservation for STA CSA Michal Kazior
2014-05-22 14:07 ` [PATCH v6 6/6] cfg80211: remove channel_switch combination check Michal Kazior
2014-05-22 14:57   ` Johannes Berg
2014-05-23  7:04     ` Michal Kazior
2014-05-23  8:53       ` Johannes Berg
2014-05-23  9:11         ` Michal Kazior

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1400844793-18069-2-git-send-email-luca@coelho.fi \
    --to=luca@coelho.fi \
    --cc=johannes@sipsolutions.net \
    --cc=linux-wireless@vger.kernel.org \
    --cc=michal.kazior@tieto.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).