Prechádzať zdrojové kódy

cfg80211: introduce cfg80211_get_chan_state

Helper function for finding out which channel is
used by a given interface.

An exclusive channel can be used only by a single
interface. This is mainly for non-fixed channel
IBSS handling.

Signed-off-by: Michal Kazior <michal.kazior@tieto.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Michal Kazior 13 rokov pred
rodič
commit
26ab9a0c58
2 zmenil súbory, kde vykonal 63 pridanie a 0 odobranie
  1. 51 0
      net/wireless/chan.c
  2. 12 0
      net/wireless/core.h

+ 51 - 0
net/wireless/chan.c

@@ -92,3 +92,54 @@ int cfg80211_set_monitor_channel(struct cfg80211_registered_device *rdev,
 
 
 	return rdev->ops->set_monitor_channel(&rdev->wiphy, chan, chantype);
 	return rdev->ops->set_monitor_channel(&rdev->wiphy, chan, chantype);
 }
 }
+
+void
+cfg80211_get_chan_state(struct cfg80211_registered_device *rdev,
+		        struct wireless_dev *wdev,
+		        struct ieee80211_channel **chan,
+		        enum cfg80211_chan_mode *chanmode)
+{
+	*chan = NULL;
+	*chanmode = CHAN_MODE_UNDEFINED;
+
+	ASSERT_RDEV_LOCK(rdev);
+	ASSERT_WDEV_LOCK(wdev);
+
+	if (!netif_running(wdev->netdev))
+		return;
+
+	switch (wdev->iftype) {
+	case NL80211_IFTYPE_ADHOC:
+		if (wdev->current_bss) {
+			*chan = wdev->current_bss->pub.channel;
+			*chanmode = wdev->ibss_fixed
+				  ? CHAN_MODE_SHARED
+				  : CHAN_MODE_EXCLUSIVE;
+			return;
+		}
+	case NL80211_IFTYPE_STATION:
+	case NL80211_IFTYPE_P2P_CLIENT:
+		if (wdev->current_bss) {
+			*chan = wdev->current_bss->pub.channel;
+			*chanmode = CHAN_MODE_SHARED;
+			return;
+		}
+		break;
+	case NL80211_IFTYPE_AP:
+	case NL80211_IFTYPE_P2P_GO:
+	case NL80211_IFTYPE_MESH_POINT:
+		*chan = wdev->channel;
+		*chanmode = CHAN_MODE_SHARED;
+		return;
+	case NL80211_IFTYPE_MONITOR:
+	case NL80211_IFTYPE_AP_VLAN:
+	case NL80211_IFTYPE_WDS:
+		/* these interface types don't really have a channel */
+		return;
+	case NL80211_IFTYPE_UNSPECIFIED:
+	case NUM_NL80211_IFTYPES:
+		WARN_ON(1);
+	}
+
+	return;
+}

+ 12 - 0
net/wireless/core.h

@@ -241,6 +241,12 @@ struct cfg80211_cached_keys {
 	int def, defmgmt;
 	int def, defmgmt;
 };
 };
 
 
+enum cfg80211_chan_mode {
+	CHAN_MODE_UNDEFINED,
+	CHAN_MODE_SHARED,
+	CHAN_MODE_EXCLUSIVE,
+};
+
 
 
 /* free object */
 /* free object */
 extern void cfg80211_dev_free(struct cfg80211_registered_device *rdev);
 extern void cfg80211_dev_free(struct cfg80211_registered_device *rdev);
@@ -419,6 +425,12 @@ cfg80211_can_add_interface(struct cfg80211_registered_device *rdev,
 	return cfg80211_can_change_interface(rdev, NULL, iftype);
 	return cfg80211_can_change_interface(rdev, NULL, iftype);
 }
 }
 
 
+void
+cfg80211_get_chan_state(struct cfg80211_registered_device *rdev,
+		        struct wireless_dev *wdev,
+		        struct ieee80211_channel **chan,
+		        enum cfg80211_chan_mode *chanmode);
+
 struct ieee80211_channel *
 struct ieee80211_channel *
 rdev_freq_to_chan(struct cfg80211_registered_device *rdev,
 rdev_freq_to_chan(struct cfg80211_registered_device *rdev,
 		  int freq, enum nl80211_channel_type channel_type);
 		  int freq, enum nl80211_channel_type channel_type);