Search Linux Wireless

[RCF/WIP 3/3] mac80211: add usage of CS channel reservation for STA

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Luciano Coelho <luciano.coelho@xxxxxxxxx>

For simplicity, and as a proof of concept, only the STA case is
covered for now.  But the P2P GO and AP cases should also work with
this new concept.

Signed-off-by: Luciano Coelho <luciano.coelho@xxxxxxxxx>
---
 net/mac80211/mlme.c | 71 ++++++++++++++++++++---------------------------------
 1 file changed, 27 insertions(+), 44 deletions(-)

diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 6160483..899989c 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -927,18 +927,19 @@ static void ieee80211_chswitch_work(struct work_struct *work)
 	if (!ifmgd->associated)
 		goto out;
 
-	mutex_lock(&local->mtx);
-	ret = ieee80211_vif_change_channel(sdata, &changed);
-	mutex_unlock(&local->mtx);
-	if (ret) {
-		sdata_info(sdata,
-			   "vif channel switch failed, disconnecting\n");
-		ieee80211_queue_work(&sdata->local->hw,
-				     &ifmgd->csa_connection_drop_work);
-		goto out;
-	}
-
+	/* TODO: maybe this if block can be moved to use_reserved()? */
 	if (!local->use_chanctx) {
+		mutex_lock(&local->mtx);
+		ret = ieee80211_vif_change_channel(sdata, &changed);
+		mutex_unlock(&local->mtx);
+		if (ret) {
+			sdata_info(sdata,
+				   "vif channel switch failed, disconnecting\n");
+			ieee80211_queue_work(&sdata->local->hw,
+					     &ifmgd->csa_connection_drop_work);
+			goto out;
+		}
+
 		local->_oper_chandef = sdata->csa_chandef;
 		/* Call "hw_config" only if doing sw channel switch.
 		 * Otherwise update the channel directly
@@ -947,6 +948,17 @@ static void ieee80211_chswitch_work(struct work_struct *work)
 			ieee80211_hw_config(local, 0);
 		else
 			local->hw.conf.chandef = local->_oper_chandef;
+	} else {
+		mutex_lock(&local->mtx);
+		ret = ieee80211_vif_use_reserved_context(sdata, &changed);
+		mutex_unlock(&local->mtx);
+		if (ret) {
+			sdata_info(sdata,
+				   "using reserved context during channel switch failed, disconnecting\n");
+			ieee80211_queue_work(&sdata->local->hw,
+					     &ifmgd->csa_connection_drop_work);
+			goto out;
+		}
 	}
 
 	/* XXX: shouldn't really modify cfg80211-owned data! */
@@ -998,7 +1010,6 @@ ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata,
 	struct ieee80211_local *local = sdata->local;
 	struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
 	struct cfg80211_bss *cbss = ifmgd->associated;
-	struct ieee80211_chanctx *chanctx;
 	enum ieee80211_band current_band;
 	struct ieee80211_csa_ie csa_ie;
 	int res;
@@ -1039,44 +1050,16 @@ ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata,
 		return;
 	}
 
-	ifmgd->flags |= IEEE80211_STA_CSA_RECEIVED;
-
-	mutex_lock(&local->chanctx_mtx);
-	if (local->use_chanctx) {
-		u32 num_chanctx = 0;
-		list_for_each_entry(chanctx, &local->chanctx_list, list)
-		       num_chanctx++;
-
-		if (num_chanctx > 1 ||
-		    !(local->hw.flags & IEEE80211_HW_CHANCTX_STA_CSA)) {
-			sdata_info(sdata,
-				   "not handling chan-switch with channel contexts\n");
-			ieee80211_queue_work(&local->hw,
-					     &ifmgd->csa_connection_drop_work);
-			mutex_unlock(&local->chanctx_mtx);
-			return;
-		}
-	}
-
-	if (WARN_ON(!rcu_access_pointer(sdata->vif.chanctx_conf))) {
-		ieee80211_queue_work(&local->hw,
-				     &ifmgd->csa_connection_drop_work);
-		mutex_unlock(&local->chanctx_mtx);
-		return;
-	}
-	chanctx = container_of(rcu_access_pointer(sdata->vif.chanctx_conf),
-			       struct ieee80211_chanctx, conf);
-	if (chanctx->refcount > 1) {
+	res = ieee80211_vif_reserve_chanctx(sdata, &csa_ie.chandef);
+	if (res) {
 		sdata_info(sdata,
-			   "channel switch with multiple interfaces on the same channel, disconnecting\n");
+			   "reserving context for channel switch failed, disconnecting\n");
 		ieee80211_queue_work(&local->hw,
 				     &ifmgd->csa_connection_drop_work);
-		mutex_unlock(&local->chanctx_mtx);
 		return;
 	}
-	mutex_unlock(&local->chanctx_mtx);
 
-	sdata->csa_chandef = csa_ie.chandef;
+	ifmgd->flags |= IEEE80211_STA_CSA_RECEIVED;
 	sdata->vif.csa_active = true;
 
 	if (csa_ie.mode)
-- 
1.8.5.3

--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Linux Host AP]     [ATH6KL]     [Linux Wireless Personal Area Network]     [Linux Bluetooth]     [Linux Netdev]     [Kernel Newbies]     [Linux Kernel]     [IDE]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite Hiking]     [MIPS Linux]     [ARM Linux]     [Linux RAID]

  Powered by Linux