diff mbox

[RFC,4/4] mac80211: OCB mode interface configuration

Message ID 1401468984-24575-5-git-send-email-rostislav.lisovy@fel.cvut.cz (mailing list archive)
State Not Applicable, archived
Headers show

Commit Message

Rostislav Lisovy May 30, 2014, 4:56 p.m. UTC
Add functions necessary for OCB mode interface configuration
used in interface bring-up and when 'joining' the network.

Signed-off-by: Rostislav Lisovy <rostislav.lisovy@fel.cvut.cz>
---
 net/mac80211/Makefile      |  3 ++-
 net/mac80211/cfg.c         | 22 ++++++++++++++++++++++
 net/mac80211/chan.c        |  1 +
 net/mac80211/driver-ops.h  |  3 ++-
 net/mac80211/ieee80211_i.h |  3 +++
 net/mac80211/iface.c       | 22 ++++++++++++++++++++++
 net/mac80211/ocb.c         | 22 ++++++++++++++++++++++
 net/mac80211/util.c        |  5 +++++
 8 files changed, 79 insertions(+), 2 deletions(-)
 create mode 100644 net/mac80211/ocb.c

Comments

Johannes Berg June 3, 2014, 8:13 p.m. UTC | #1
On Fri, 2014-05-30 at 18:56 +0200, Rostislav Lisovy wrote:
> +	static u8 bssid_wildcard[ETH_ALEN] = { 0xff, 0xff, 0xff,
> +					       0xff, 0xff, 0xff };

const

that doesn't actually exist anywhere already? Maybe not I guess.

> +int ieee80211_start_ocb(struct ieee80211_sub_if_data *sdata)
> +{
> +	u32 changed = BSS_CHANGED_BEACON_ENABLED;
> +
> +	sdata->vif.bss_conf.enable_beacon = false;
> +	ieee80211_bss_info_change_notify(sdata, changed);

Why would beacon_enabled be changing?

> +	/* MORE TO BE DONE ... */

From a brief look it seems that you should at least be setting the QoS
parameters, but what, if anything, else is there?

Certainly there should also be some indication to the low-level driver
that it should now consider being part of the OCB network though.

> +	netif_carrier_on(sdata->dev);
> +	return 0;
> +}
> diff --git a/net/mac80211/util.c b/net/mac80211/util.c
> index 7e0dd4b..bf4fd61 100644
> --- a/net/mac80211/util.c
> +++ b/net/mac80211/util.c
> @@ -1689,6 +1689,11 @@ int ieee80211_reconfig(struct ieee80211_local *local)
>  			ieee80211_bss_info_change_notify(sdata, changed);
>  			sdata_unlock(sdata);
>  			break;
> +		case NL80211_IFTYPE_OCB:
> +			changed |= BSS_CHANGED_IBSS |
> +				   BSS_CHANGED_BEACON_ENABLED;

CHANGED_IBSS?

I guess you need a new CHANGED_OCB flag and ocb_active bool value.

johannes

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

Patch

diff --git a/net/mac80211/Makefile b/net/mac80211/Makefile
index 1e46ffa..1b9d37f 100644
--- a/net/mac80211/Makefile
+++ b/net/mac80211/Makefile
@@ -26,7 +26,8 @@  mac80211-y := \
 	event.o \
 	chan.o \
 	trace.o mlme.o \
-	tdls.o
+	tdls.o \
+	ocb.o
 
 mac80211-$(CONFIG_MAC80211_LEDS) += led.o
 mac80211-$(CONFIG_MAC80211_DEBUGFS) += \
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 7c56445..ac15b59 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -228,6 +228,7 @@  static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev,
 	case NUM_NL80211_IFTYPES:
 	case NL80211_IFTYPE_P2P_CLIENT:
 	case NL80211_IFTYPE_P2P_GO:
+	case NL80211_IFTYPE_OCB:
 		/* shouldn't happen */
 		WARN_ON_ONCE(1);
 		break;
@@ -2032,6 +2033,26 @@  static int ieee80211_leave_mesh(struct wiphy *wiphy, struct net_device *dev)
 }
 #endif
 
+static int ieee80211_join_ocb(struct wiphy *wiphy, struct net_device *dev,
+			      struct ocb_setup *setup)
+{
+	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+	int err;
+
+	sdata->flags |= IEEE80211_SDATA_OPERATING_GMODE;
+	sdata->smps_mode = IEEE80211_SMPS_OFF;
+	sdata->needed_rx_chains = sdata->local->rx_chains;
+
+	mutex_lock(&sdata->local->mtx);
+	err = ieee80211_vif_use_channel(sdata, &setup->chandef,
+					IEEE80211_CHANCTX_EXCLUSIVE);
+	mutex_unlock(&sdata->local->mtx);
+	if (err)
+		return err;
+
+	return ieee80211_start_ocb(sdata);
+}
+
 static int ieee80211_change_bss(struct wiphy *wiphy,
 				struct net_device *dev,
 				struct bss_parameters *params)
@@ -3768,6 +3789,7 @@  const struct cfg80211_ops mac80211_config_ops = {
 	.join_mesh = ieee80211_join_mesh,
 	.leave_mesh = ieee80211_leave_mesh,
 #endif
+	.join_ocb = ieee80211_join_ocb,
 	.change_bss = ieee80211_change_bss,
 	.set_txq_params = ieee80211_set_txq_params,
 	.set_monitor_channel = ieee80211_set_monitor_channel,
diff --git a/net/mac80211/chan.c b/net/mac80211/chan.c
index 3702d64..62002de 100644
--- a/net/mac80211/chan.c
+++ b/net/mac80211/chan.c
@@ -675,6 +675,7 @@  void ieee80211_recalc_smps_chanctx(struct ieee80211_local *local,
 		case NL80211_IFTYPE_ADHOC:
 		case NL80211_IFTYPE_WDS:
 		case NL80211_IFTYPE_MESH_POINT:
+		case NL80211_IFTYPE_OCB:
 			break;
 		default:
 			WARN_ON_ONCE(1);
diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h
index df1d502..ccf770d 100644
--- a/net/mac80211/driver-ops.h
+++ b/net/mac80211/driver-ops.h
@@ -214,7 +214,8 @@  static inline void drv_bss_info_changed(struct ieee80211_local *local,
 				    BSS_CHANGED_BEACON_ENABLED) &&
 			 sdata->vif.type != NL80211_IFTYPE_AP &&
 			 sdata->vif.type != NL80211_IFTYPE_ADHOC &&
-			 sdata->vif.type != NL80211_IFTYPE_MESH_POINT))
+			 sdata->vif.type != NL80211_IFTYPE_MESH_POINT &&
+			 sdata->vif.type != NL80211_IFTYPE_OCB))
 		return;
 
 	if (WARN_ON_ONCE(sdata->vif.type == NL80211_IFTYPE_P2P_DEVICE ||
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 4668ce9..002fd8f 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -1421,6 +1421,9 @@  int ieee80211_ibss_csa_beacon(struct ieee80211_sub_if_data *sdata,
 int ieee80211_ibss_finish_csa(struct ieee80211_sub_if_data *sdata);
 void ieee80211_ibss_stop(struct ieee80211_sub_if_data *sdata);
 
+/* OCB code */
+int ieee80211_start_ocb(struct ieee80211_sub_if_data *sdata);
+
 /* mesh code */
 void ieee80211_mesh_work(struct ieee80211_sub_if_data *sdata);
 void ieee80211_mesh_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index 79fc988..23e573e 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -258,6 +258,15 @@  static int ieee80211_check_concurrent_iface(struct ieee80211_sub_if_data *sdata,
 	list_for_each_entry(nsdata, &local->interfaces, list) {
 		if (nsdata != sdata && ieee80211_sdata_running(nsdata)) {
 			/*
+			 * Only OCB and monitor mode may coexist
+			 */
+			if ((sdata->vif.type == NL80211_IFTYPE_OCB &&
+			     nsdata->vif.type != NL80211_IFTYPE_MONITOR) ||
+			    (sdata->vif.type != NL80211_IFTYPE_MONITOR &&
+			     nsdata->vif.type == NL80211_IFTYPE_OCB))
+				return -EBUSY;
+
+			/*
 			 * Allow only a single IBSS interface to be up at any
 			 * time. This is restricted because beacon distribution
 			 * cannot work properly if both are in the same IBSS.
@@ -519,6 +528,7 @@  int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up)
 	case NL80211_IFTYPE_MONITOR:
 	case NL80211_IFTYPE_ADHOC:
 	case NL80211_IFTYPE_P2P_DEVICE:
+	case NL80211_IFTYPE_OCB:
 		/* no special treatment */
 		break;
 	case NL80211_IFTYPE_UNSPECIFIED:
@@ -618,6 +628,9 @@  int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up)
 			ieee80211_configure_filter(local);
 		} else if (sdata->vif.type == NL80211_IFTYPE_ADHOC) {
 			local->fif_probe_req++;
+		} else if (sdata->vif.type == NL80211_IFTYPE_OCB) {
+			local->fif_other_bss++;
+			ieee80211_configure_filter(local);
 		}
 
 		if (sdata->vif.type != NL80211_IFTYPE_P2P_DEVICE)
@@ -629,6 +642,7 @@  int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up)
 		case NL80211_IFTYPE_ADHOC:
 		case NL80211_IFTYPE_AP:
 		case NL80211_IFTYPE_MESH_POINT:
+		case NL80211_IFTYPE_OCB:
 			netif_carrier_off(dev);
 			break;
 		case NL80211_IFTYPE_WDS:
@@ -1274,6 +1288,9 @@  static void ieee80211_recalc_smps_work(struct work_struct *work)
 static void ieee80211_setup_sdata(struct ieee80211_sub_if_data *sdata,
 				  enum nl80211_iftype type)
 {
+	static u8 bssid_wildcard[ETH_ALEN] = { 0xff, 0xff, 0xff,
+					       0xff, 0xff, 0xff };
+
 	/* clear type-dependent union */
 	memset(&sdata->u, 0, sizeof(sdata->u));
 
@@ -1324,6 +1341,9 @@  static void ieee80211_setup_sdata(struct ieee80211_sub_if_data *sdata,
 		sdata->vif.bss_conf.bssid = sdata->u.mgd.bssid;
 		ieee80211_sta_setup_sdata(sdata);
 		break;
+	case NL80211_IFTYPE_OCB:
+		sdata->vif.bss_conf.bssid = bssid_wildcard;
+		break;
 	case NL80211_IFTYPE_ADHOC:
 		sdata->vif.bss_conf.bssid = sdata->u.ibss.bssid;
 		ieee80211_ibss_setup_sdata(sdata);
@@ -1371,6 +1391,7 @@  static int ieee80211_runtime_change_iftype(struct ieee80211_sub_if_data *sdata,
 	case NL80211_IFTYPE_AP:
 	case NL80211_IFTYPE_STATION:
 	case NL80211_IFTYPE_ADHOC:
+	case NL80211_IFTYPE_OCB:
 		/*
 		 * Could maybe also all others here?
 		 * Just not sure how that interacts
@@ -1386,6 +1407,7 @@  static int ieee80211_runtime_change_iftype(struct ieee80211_sub_if_data *sdata,
 	case NL80211_IFTYPE_AP:
 	case NL80211_IFTYPE_STATION:
 	case NL80211_IFTYPE_ADHOC:
+	case NL80211_IFTYPE_OCB:
 		/*
 		 * Could probably support everything
 		 * but WDS here (WDS do_open can fail
diff --git a/net/mac80211/ocb.c b/net/mac80211/ocb.c
new file mode 100644
index 0000000..2dd9723
--- /dev/null
+++ b/net/mac80211/ocb.c
@@ -0,0 +1,22 @@ 
+ /* OCB mode implementation
+ * Copyright 2014, Czech Technical University in Prague, Rostislav Lisovy
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include "ieee80211_i.h"
+
+int ieee80211_start_ocb(struct ieee80211_sub_if_data *sdata)
+{
+	u32 changed = BSS_CHANGED_BEACON_ENABLED;
+
+	sdata->vif.bss_conf.enable_beacon = false;
+	ieee80211_bss_info_change_notify(sdata, changed);
+
+	/* MORE TO BE DONE ... */
+
+	netif_carrier_on(sdata->dev);
+	return 0;
+}
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index 7e0dd4b..bf4fd61 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -1689,6 +1689,11 @@  int ieee80211_reconfig(struct ieee80211_local *local)
 			ieee80211_bss_info_change_notify(sdata, changed);
 			sdata_unlock(sdata);
 			break;
+		case NL80211_IFTYPE_OCB:
+			changed |= BSS_CHANGED_IBSS |
+				   BSS_CHANGED_BEACON_ENABLED;
+			ieee80211_bss_info_change_notify(sdata, changed);
+			break;
 		case NL80211_IFTYPE_ADHOC:
 			changed |= BSS_CHANGED_IBSS;
 			/* fall through */