All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC v2] initial channel context implementation
@ 2012-06-21 12:03 Michal Kazior
  2012-06-21 12:03 ` [RFC v2 1/7] mac80211: introduce channel contexts skeleton code Michal Kazior
                   ` (7 more replies)
  0 siblings, 8 replies; 13+ messages in thread
From: Michal Kazior @ 2012-06-21 12:03 UTC (permalink / raw)
  To: johannes; +Cc: linux-wireless

Hi,

Here's my respin of channel contexts patches. Thanks for the
review on the previous version.

Changes in short:

 * renamed to chanctx (to avoid very_long_structure_names)
 * pub/priv part added (and drv_priv)
 * new mutex added
 * channel contexts are a linked list
 * tracing added

Next step would be to refactor mac80211 codepaths to take
advantage of channel contexts (if used).


-- Pozdrawiam / Best regards, Michal Kazior.


^ permalink raw reply	[flat|nested] 13+ messages in thread

* [RFC v2 1/7] mac80211: introduce channel contexts skeleton code
  2012-06-21 12:03 [RFC v2] initial channel context implementation Michal Kazior
@ 2012-06-21 12:03 ` Michal Kazior
  2012-06-21 13:24   ` Johannes Berg
  2012-06-21 12:03 ` [RFC v2 2/7] mac80211: introduce new ieee80211_ops Michal Kazior
                   ` (6 subsequent siblings)
  7 siblings, 1 reply; 13+ messages in thread
From: Michal Kazior @ 2012-06-21 12:03 UTC (permalink / raw)
  To: johannes; +Cc: linux-wireless, Kazior Michal, Michal Kazior

From: Kazior Michal <Michal.Kazior@tieto.com>

Channel context are the foundation for
multi-channel operation.

Channel contexts are immutable and are re-created
(or re-used if other interfaces are bound to a
certain channel) on channel switching.

This is a initial implementation and more features
will come in separate patches for easier review.

Signed-off-by: Michal Kazior <michal.kazior@tieto.com>
---
 include/net/mac80211.h     |   41 +++++++++++++++
 net/mac80211/chan.c        |  123 ++++++++++++++++++++++++++++++++++++++++++++
 net/mac80211/ieee80211_i.h |   23 ++++++++
 net/mac80211/main.c        |    3 +
 4 files changed, 190 insertions(+), 0 deletions(-)

diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 6914f99..0089798 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -143,6 +143,41 @@ struct ieee80211_low_level_stats {
 	unsigned int dot11RTSSuccessCount;
 };
 
+
+/**
+ * enum ieee80211_chanctx_mode - channel context configuration mode
+ *
+ * @IEEE80211_CHANCTX_SHARED: channel context may be used by
+ *	multiple interfaces
+ * @IEEE80211_CHANCTX_EXCLUSIVE: channel context can be used
+ *	only by a single interface. This can be used for example for
+ *	non-fixed channel IBSS.
+ */
+enum ieee80211_chanctx_mode {
+	IEEE80211_CHANCTX_SHARED,
+	IEEE80211_CHANCTX_EXCLUSIVE
+};
+
+/**
+ * struct ieee80211_chanctx_conf - channel context that vifs may be tuned to
+ *
+ * This is the driver-visible part. The ieee80211_chanctx
+ * that contains it is visible in mac80211 only.
+ *
+ * @channel: the channel to tune to
+ * @channel_type: the channel (HT) type
+ * @mode: the channel context mode
+ * @drv_priv: data area for driver use, will always be aligned to
+ *	sizeof(void *), size is determined in hw information.
+ */
+struct ieee80211_chanctx_conf {
+	struct ieee80211_channel *channel;
+	enum nl80211_channel_type channel_type;
+	enum ieee80211_chanctx_mode mode;
+
+	u8 drv_priv[0] __attribute__((__aligned__(sizeof(void *))));
+};
+
 /**
  * enum ieee80211_bss_change - BSS change notification flags
  *
@@ -897,6 +932,7 @@ enum ieee80211_vif_flags {
  *	at runtime, mac80211 will never touch this field
  * @hw_queue: hardware queue for each AC
  * @cab_queue: content-after-beacon (DTIM beacon really) queue, AP mode only
+ * @chanctx_conf: channel context vif is bound to, may be NULL
  * @drv_priv: data area for driver use, will always be aligned to
  *	sizeof(void *).
  */
@@ -909,6 +945,8 @@ struct ieee80211_vif {
 	u8 cab_queue;
 	u8 hw_queue[IEEE80211_NUM_ACS];
 
+	struct ieee80211_chanctx_conf *chanctx_conf;
+
 	u32 driver_flags;
 
 	/* must be last */
@@ -1268,6 +1306,8 @@ enum ieee80211_hw_flags {
  *	within &struct ieee80211_vif.
  * @sta_data_size: size (in bytes) of the drv_priv data area
  *	within &struct ieee80211_sta.
+ * @chanctx_data_size: size (in bytes) of the drv_priv data area
+ *	within &struct ieee80211_chanctx_conf.
  *
  * @max_rates: maximum number of alternate rate retry stages the hw
  *	can handle.
@@ -1312,6 +1352,7 @@ struct ieee80211_hw {
 	int channel_change_time;
 	int vif_data_size;
 	int sta_data_size;
+	int chanctx_data_size;
 	int napi_weight;
 	u16 queues;
 	u16 max_listen_interval;
diff --git a/net/mac80211/chan.c b/net/mac80211/chan.c
index f0f87e5..f5b4a77 100644
--- a/net/mac80211/chan.c
+++ b/net/mac80211/chan.c
@@ -139,3 +139,126 @@ bool ieee80211_set_channel_type(struct ieee80211_local *local,
 
 	return result;
 }
+
+static struct ieee80211_chanctx *
+ieee80211_find_chanctx(struct ieee80211_local *local,
+		       struct ieee80211_channel *channel,
+		       enum nl80211_channel_type channel_type,
+		       enum ieee80211_chanctx_mode mode)
+{
+	struct ieee80211_chanctx *ctx;
+
+	if (mode == IEEE80211_CHANCTX_EXCLUSIVE)
+		return NULL;
+	if (WARN_ON(!channel))
+		return NULL;
+
+	list_for_each_entry(ctx, &local->chanctx_list, list) {
+		if (ctx->conf.mode == IEEE80211_CHANCTX_EXCLUSIVE)
+			continue;
+		if (ctx->conf.channel != channel)
+			continue;
+		if (ctx->conf.channel_type != channel_type)
+			continue;
+
+		return ctx;
+	}
+
+	return NULL;
+}
+
+static struct ieee80211_chanctx *
+ieee80211_new_chanctx(struct ieee80211_local *local,
+		      struct ieee80211_channel *channel,
+		      enum nl80211_channel_type channel_type,
+		      enum ieee80211_chanctx_mode mode)
+{
+	struct ieee80211_chanctx *ctx;
+
+	ctx = kzalloc(sizeof(*ctx) + local->hw.chanctx_data_size, GFP_KERNEL);
+	if (!ctx)
+		return NULL;
+
+	ctx->conf.channel = channel;
+	ctx->conf.channel_type = channel_type;
+	ctx->conf.mode = mode;
+	ctx->local = local;
+
+	list_add(&ctx->list, &local->chanctx_list);
+	INIT_LIST_HEAD(&ctx->interfaces);
+
+	return ctx;
+}
+
+static void
+ieee80211_free_chanctx(struct ieee80211_chanctx *ctx)
+{
+	BUG_ON(!list_empty(&ctx->interfaces));
+
+	list_del(&ctx->list);
+	kfree(ctx);
+}
+
+static void
+ieee80211_assign_vif_chanctx(struct ieee80211_sub_if_data *sdata,
+			     struct ieee80211_chanctx *ctx)
+{
+	list_add(&sdata->chanctx_listitem, &ctx->interfaces);
+	sdata->vif.chanctx_conf = &ctx->conf;
+}
+
+static void
+ieee80211_unassign_vif_chanctx(struct ieee80211_sub_if_data *sdata,
+			       struct ieee80211_chanctx *ctx)
+{
+	sdata->vif.chanctx_conf = NULL;
+	list_del(&sdata->chanctx_listitem);
+}
+
+static void
+__ieee80211_vif_release_channel(struct ieee80211_sub_if_data *sdata)
+{
+	struct ieee80211_chanctx_conf *conf = sdata->vif.chanctx_conf;
+	struct ieee80211_chanctx *ctx =
+			container_of(conf, struct ieee80211_chanctx, conf);
+
+	if (!conf)
+		return;
+
+	ieee80211_unassign_vif_chanctx(sdata, ctx);
+	if (list_empty(&ctx->interfaces))
+		ieee80211_free_chanctx(ctx);
+}
+
+bool
+ieee80211_vif_use_channel(struct ieee80211_sub_if_data *sdata,
+			  struct ieee80211_channel *channel,
+			  enum nl80211_channel_type channel_type,
+			  enum ieee80211_chanctx_mode mode)
+{
+	struct ieee80211_local *local = sdata->local;
+	struct ieee80211_chanctx *ctx;
+
+	mutex_lock(&local->chanctx_mtx);
+	__ieee80211_vif_release_channel(sdata);
+
+	ctx = ieee80211_find_chanctx(local, channel, channel_type, mode);
+	if (!ctx)
+		ctx = ieee80211_new_chanctx(local, channel, channel_type, mode);
+	if (!ctx) {
+		mutex_unlock(&local->chanctx_mtx);
+		return false;
+	}
+
+	ieee80211_assign_vif_chanctx(sdata, ctx);
+	mutex_unlock(&local->chanctx_mtx);
+	return true;
+}
+
+void
+ieee80211_vif_release_channel(struct ieee80211_sub_if_data *sdata)
+{
+	mutex_lock(&sdata->local->chanctx_mtx);
+	__ieee80211_vif_release_channel(sdata);
+	mutex_unlock(&sdata->local->chanctx_mtx);
+}
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index e6cbf5b..eefb932 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -645,6 +645,15 @@ enum ieee80211_sdata_state_bits {
 	SDATA_STATE_OFFCHANNEL,
 };
 
+struct ieee80211_chanctx {
+	struct list_head list;
+
+	struct ieee80211_local *local;
+	struct list_head interfaces;
+
+	struct ieee80211_chanctx_conf conf;
+};
+
 struct ieee80211_sub_if_data {
 	struct list_head list;
 
@@ -693,6 +702,8 @@ struct ieee80211_sub_if_data {
 
 	bool arp_filter_state;
 
+	struct list_head chanctx_listitem;
+
 	/*
 	 * AP this belongs to: self in AP mode and
 	 * corresponding AP in VLAN mode, NULL for
@@ -969,6 +980,10 @@ struct ieee80211_local {
 	struct ieee80211_channel *tmp_channel;
 	enum nl80211_channel_type tmp_channel_type;
 
+	/* channel contexts */
+	struct list_head chanctx_list;
+	struct mutex chanctx_mtx;
+
 	/* SNMP counters */
 	/* dot11CountersTable */
 	u32 dot11TransmittedFragmentCount;
@@ -1488,6 +1503,14 @@ bool ieee80211_set_channel_type(struct ieee80211_local *local,
 enum nl80211_channel_type
 ieee80211_ht_oper_to_channel_type(struct ieee80211_ht_operation *ht_oper);
 
+bool
+ieee80211_vif_use_channel(struct ieee80211_sub_if_data *sdata,
+			  struct ieee80211_channel *channel,
+			  enum nl80211_channel_type channel_type,
+			  enum ieee80211_chanctx_mode mode);
+void
+ieee80211_vif_release_channel(struct ieee80211_sub_if_data *sdata);
+
 #ifdef CONFIG_MAC80211_NOINLINE
 #define debug_noinline noinline
 #else
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index d81c178..735edd5 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -613,6 +613,9 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
 	spin_lock_init(&local->filter_lock);
 	spin_lock_init(&local->queue_stop_reason_lock);
 
+	INIT_LIST_HEAD(&local->chanctx_list);
+	mutex_init(&local->chanctx_mtx);
+
 	/*
 	 * The rx_skb_queue is only accessed from tasklets,
 	 * but other SKB queues are used from within IRQ
-- 
1.7.0.4


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [RFC v2 2/7] mac80211: introduce new ieee80211_ops
  2012-06-21 12:03 [RFC v2] initial channel context implementation Michal Kazior
  2012-06-21 12:03 ` [RFC v2 1/7] mac80211: introduce channel contexts skeleton code Michal Kazior
@ 2012-06-21 12:03 ` Michal Kazior
  2012-06-21 12:03 ` [RFC v2 3/7] mac80211: add drv_* wrappers for channel contexts Michal Kazior
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 13+ messages in thread
From: Michal Kazior @ 2012-06-21 12:03 UTC (permalink / raw)
  To: johannes; +Cc: linux-wireless, Kazior Michal, Michal Kazior

From: Kazior Michal <Michal.Kazior@tieto.com>

Introduces channel context callbacks. Channel on a
context channel is immutable. Channel type will be
changable later though, thus change_channel_type is
adveristed.

Signed-off-by: Michal Kazior <michal.kazior@tieto.com>
---
 include/net/mac80211.h |   22 ++++++++++++++++++++++
 1 files changed, 22 insertions(+), 0 deletions(-)

diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 0089798..5040d6d 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -2295,6 +2295,15 @@ enum ieee80211_rate_control_changed {
  * @get_et_strings:  Ethtool API to get a set of strings to describe stats
  *	and perhaps other supported types of ethtool data-sets.
  *
+ * @add_chanctx: Notifies device driver about new channel context creation.
+ * @remove_chanctx: Notifies device driver about channel context destruction.
+ * @change_chantype: Notifies device driver about channel context channel_type
+ *	change which may happen when combining different vifs on a same channel
+ *	with different HTs.
+ * @assign_vif_chanctx: Notifies device driver about channel context being bound
+ *	to vif. Possible use is for hw queue remapping.
+ * @unassign_vif_chanctx: Notifies device driver about channel context being
+ *	unbound from vif.
  */
 struct ieee80211_ops {
 	void (*tx)(struct ieee80211_hw *hw, struct sk_buff *skb);
@@ -2434,6 +2443,19 @@ struct ieee80211_ops {
 	void	(*get_et_strings)(struct ieee80211_hw *hw,
 				  struct ieee80211_vif *vif,
 				  u32 sset, u8 *data);
+
+	void (*add_chanctx)(struct ieee80211_hw *hw,
+			    struct ieee80211_chanctx_conf *ctx);
+	void (*remove_chanctx)(struct ieee80211_hw *hw,
+			       struct ieee80211_chanctx_conf *ctx);
+	void (*change_chantype)(struct ieee80211_hw *hw,
+				struct ieee80211_chanctx_conf *ctx);
+	void (*assign_vif_chanctx)(struct ieee80211_hw *hw,
+				   struct ieee80211_vif *vif,
+				   struct ieee80211_chanctx_conf *ctx);
+	void (*unassign_vif_chanctx)(struct ieee80211_hw *hw,
+				     struct ieee80211_vif *vif,
+				     struct ieee80211_chanctx_conf *ctx);
 };
 
 /**
-- 
1.7.0.4


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [RFC v2 3/7] mac80211: add drv_* wrappers for channel contexts
  2012-06-21 12:03 [RFC v2] initial channel context implementation Michal Kazior
  2012-06-21 12:03 ` [RFC v2 1/7] mac80211: introduce channel contexts skeleton code Michal Kazior
  2012-06-21 12:03 ` [RFC v2 2/7] mac80211: introduce new ieee80211_ops Michal Kazior
@ 2012-06-21 12:03 ` Michal Kazior
  2012-06-21 12:03 ` [RFC v2 4/7] mac80211: add chanctx tracing Michal Kazior
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 13+ messages in thread
From: Michal Kazior @ 2012-06-21 12:03 UTC (permalink / raw)
  To: johannes; +Cc: linux-wireless, Kazior Michal, Michal Kazior

From: Kazior Michal <Michal.Kazior@tieto.com>

Signed-off-by: Michal Kazior <michal.kazior@tieto.com>
---
 net/mac80211/driver-ops.h |   51 +++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 51 insertions(+), 0 deletions(-)

diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h
index 6d33a0c..e79f06d 100644
--- a/net/mac80211/driver-ops.h
+++ b/net/mac80211/driver-ops.h
@@ -845,4 +845,55 @@ drv_allow_buffered_frames(struct ieee80211_local *local,
 						  more_data);
 	trace_drv_return_void(local);
 }
+
+static inline void
+drv_add_chanctx(struct ieee80211_local *local,
+		struct ieee80211_chanctx *ctx)
+{
+	if (local->ops->add_chanctx)
+		local->ops->add_chanctx(&local->hw, &ctx->conf);
+}
+
+static inline void
+drv_remove_chanctx(struct ieee80211_local *local,
+		   struct ieee80211_chanctx *ctx)
+{
+	if (local->ops->remove_chanctx)
+		local->ops->remove_chanctx(&local->hw, &ctx->conf);
+}
+
+static inline void
+drv_change_chantype(struct ieee80211_local *local,
+		    struct ieee80211_chanctx *ctx)
+{
+	if (local->ops->change_chantype)
+		local->ops->change_chantype(&local->hw, &ctx->conf);
+}
+
+static inline void
+drv_assign_vif_chanctx(struct ieee80211_local *local,
+		       struct ieee80211_sub_if_data *sdata,
+		       struct ieee80211_chanctx *ctx)
+{
+	check_sdata_in_driver(sdata);
+
+	if (local->ops->assign_vif_chanctx)
+		local->ops->assign_vif_chanctx(&local->hw,
+					       &sdata->vif,
+					       &ctx->conf);
+}
+
+static inline void
+drv_unassign_vif_chanctx(struct ieee80211_local *local,
+			 struct ieee80211_sub_if_data *sdata,
+			 struct ieee80211_chanctx *ctx)
+{
+	check_sdata_in_driver(sdata);
+
+	if (local->ops->unassign_vif_chanctx)
+		local->ops->unassign_vif_chanctx(&local->hw,
+						 &sdata->vif,
+						 &ctx->conf);
+}
+
 #endif /* __MAC80211_DRIVER_OPS */
-- 
1.7.0.4


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [RFC v2 4/7] mac80211: add chanctx tracing
  2012-06-21 12:03 [RFC v2] initial channel context implementation Michal Kazior
                   ` (2 preceding siblings ...)
  2012-06-21 12:03 ` [RFC v2 3/7] mac80211: add drv_* wrappers for channel contexts Michal Kazior
@ 2012-06-21 12:03 ` Michal Kazior
  2012-06-21 12:03 ` [RFC v2 5/7] mac80211: use channel context notifications Michal Kazior
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 13+ messages in thread
From: Michal Kazior @ 2012-06-21 12:03 UTC (permalink / raw)
  To: johannes; +Cc: linux-wireless, Michal Kazior

Signed-off-by: Michal Kazior <michal.kazior@tieto.com>
---
 net/mac80211/driver-ops.h   |   10 +++++
 net/mac80211/driver-trace.h |   88 +++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 98 insertions(+), 0 deletions(-)

diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h
index e79f06d..dde9f33 100644
--- a/net/mac80211/driver-ops.h
+++ b/net/mac80211/driver-ops.h
@@ -850,24 +850,30 @@ static inline void
 drv_add_chanctx(struct ieee80211_local *local,
 		struct ieee80211_chanctx *ctx)
 {
+	trace_drv_add_chanctx(local, ctx);
 	if (local->ops->add_chanctx)
 		local->ops->add_chanctx(&local->hw, &ctx->conf);
+	trace_drv_return_void(local);
 }
 
 static inline void
 drv_remove_chanctx(struct ieee80211_local *local,
 		   struct ieee80211_chanctx *ctx)
 {
+	trace_drv_remove_chanctx(local, ctx);
 	if (local->ops->remove_chanctx)
 		local->ops->remove_chanctx(&local->hw, &ctx->conf);
+	trace_drv_return_void(local);
 }
 
 static inline void
 drv_change_chantype(struct ieee80211_local *local,
 		    struct ieee80211_chanctx *ctx)
 {
+	trace_drv_change_chantype(local, ctx);
 	if (local->ops->change_chantype)
 		local->ops->change_chantype(&local->hw, &ctx->conf);
+	trace_drv_return_void(local);
 }
 
 static inline void
@@ -877,10 +883,12 @@ drv_assign_vif_chanctx(struct ieee80211_local *local,
 {
 	check_sdata_in_driver(sdata);
 
+	trace_drv_assign_vif_chanctx(local, sdata, ctx);
 	if (local->ops->assign_vif_chanctx)
 		local->ops->assign_vif_chanctx(&local->hw,
 					       &sdata->vif,
 					       &ctx->conf);
+	trace_drv_return_void(local);
 }
 
 static inline void
@@ -890,10 +898,12 @@ drv_unassign_vif_chanctx(struct ieee80211_local *local,
 {
 	check_sdata_in_driver(sdata);
 
+	trace_drv_unassign_vif_chanctx(local, sdata, ctx);
 	if (local->ops->unassign_vif_chanctx)
 		local->ops->unassign_vif_chanctx(&local->hw,
 						 &sdata->vif,
 						 &ctx->conf);
+	trace_drv_return_void(local);
 }
 
 #endif /* __MAC80211_DRIVER_OPS */
diff --git a/net/mac80211/driver-trace.h b/net/mac80211/driver-trace.h
index 6de00b2..16b0e43 100644
--- a/net/mac80211/driver-trace.h
+++ b/net/mac80211/driver-trace.h
@@ -1606,6 +1606,94 @@ TRACE_EVENT(stop_queue,
 		LOCAL_PR_ARG, __entry->queue, __entry->reason
 	)
 );
+
+DECLARE_EVENT_CLASS(local_chanctx,
+	TP_PROTO(struct ieee80211_local *local,
+		 struct ieee80211_chanctx *ctx),
+
+	TP_ARGS(local, ctx),
+
+	TP_STRUCT__entry(
+		LOCAL_ENTRY
+		__field(void *, ctx)
+		__field(int, freq)
+		__field(int, chantype)
+	),
+
+	TP_fast_assign(
+		LOCAL_ASSIGN;
+		__entry->ctx = ctx;
+		__entry->freq = ctx->conf.channel->center_freq;
+		__entry->chantype = ctx->conf.channel_type;
+	),
+
+	TP_printk(
+		LOCAL_PR_FMT " ctx:%p freq:%dMhz chantype:%d",
+		LOCAL_PR_ARG, __entry->ctx, __entry->freq, __entry->chantype
+	)
+);
+
+DEFINE_EVENT(local_chanctx, drv_add_chanctx,
+	TP_PROTO(struct ieee80211_local *local,
+		 struct ieee80211_chanctx *ctx),
+	TP_ARGS(local, ctx)
+);
+
+DEFINE_EVENT(local_chanctx, drv_remove_chanctx,
+	TP_PROTO(struct ieee80211_local *local,
+		 struct ieee80211_chanctx *ctx),
+	TP_ARGS(local, ctx)
+);
+
+DEFINE_EVENT(local_chanctx, drv_change_chantype,
+	TP_PROTO(struct ieee80211_local *local,
+		 struct ieee80211_chanctx *ctx),
+	TP_ARGS(local, ctx)
+);
+
+DECLARE_EVENT_CLASS(local_sdata_chanctx,
+	TP_PROTO(struct ieee80211_local *local,
+		 struct ieee80211_sub_if_data *sdata,
+		 struct ieee80211_chanctx *ctx),
+
+	TP_ARGS(local, sdata, ctx),
+
+	TP_STRUCT__entry(
+		LOCAL_ENTRY
+		VIF_ENTRY
+		__field(void *, ctx)
+		__field(int, freq)
+		__field(int, chantype)
+	),
+
+	TP_fast_assign(
+		LOCAL_ASSIGN;
+		VIF_ASSIGN;
+		__entry->ctx = ctx;
+		__entry->freq = ctx->conf.channel->center_freq;
+		__entry->chantype = ctx->conf.channel_type;
+	),
+
+	TP_printk(
+		LOCAL_PR_FMT VIF_PR_FMT " ctx:%p freq:%dMhz chantype:%d",
+		LOCAL_PR_ARG, VIF_PR_ARG,
+		__entry->ctx, __entry->freq, __entry->chantype
+	)
+);
+
+DEFINE_EVENT(local_sdata_chanctx, drv_assign_vif_chanctx,
+	TP_PROTO(struct ieee80211_local *local,
+		 struct ieee80211_sub_if_data *sdata,
+		 struct ieee80211_chanctx *ctx),
+	TP_ARGS(local, sdata, ctx)
+);
+
+DEFINE_EVENT(local_sdata_chanctx, drv_unassign_vif_chanctx,
+	TP_PROTO(struct ieee80211_local *local,
+		 struct ieee80211_sub_if_data *sdata,
+		 struct ieee80211_chanctx *ctx),
+	TP_ARGS(local, sdata, ctx)
+);
 #endif /* !__MAC80211_DRIVER_TRACE || TRACE_HEADER_MULTI_READ */
 
 #undef TRACE_INCLUDE_PATH
-- 
1.7.0.4


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [RFC v2 5/7] mac80211: use channel context notifications
  2012-06-21 12:03 [RFC v2] initial channel context implementation Michal Kazior
                   ` (3 preceding siblings ...)
  2012-06-21 12:03 ` [RFC v2 4/7] mac80211: add chanctx tracing Michal Kazior
@ 2012-06-21 12:03 ` Michal Kazior
  2012-06-21 12:03 ` [RFC v2 6/7] mac80211: refactor set_channel_type Michal Kazior
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 13+ messages in thread
From: Michal Kazior @ 2012-06-21 12:03 UTC (permalink / raw)
  To: johannes; +Cc: linux-wireless, Kazior Michal, Michal Kazior

From: Kazior Michal <Michal.Kazior@tieto.com>

Channel context pointer will be accessiable on
both assign and unassign events.

Signed-off-by: Michal Kazior <michal.kazior@tieto.com>
---
 net/mac80211/chan.c |    9 +++++++++
 1 files changed, 9 insertions(+), 0 deletions(-)

diff --git a/net/mac80211/chan.c b/net/mac80211/chan.c
index f5b4a77..20483a0 100644
--- a/net/mac80211/chan.c
+++ b/net/mac80211/chan.c
@@ -5,6 +5,7 @@
 #include <linux/nl80211.h>
 #include <net/cfg80211.h>
 #include "ieee80211_i.h"
+#include "driver-ops.h"
 
 static enum ieee80211_chan_mode
 __ieee80211_get_channel_mode(struct ieee80211_local *local,
@@ -187,6 +188,8 @@ ieee80211_new_chanctx(struct ieee80211_local *local,
 	list_add(&ctx->list, &local->chanctx_list);
 	INIT_LIST_HEAD(&ctx->interfaces);
 
+	drv_add_chanctx(local, ctx);
+
 	return ctx;
 }
 
@@ -195,6 +198,8 @@ ieee80211_free_chanctx(struct ieee80211_chanctx *ctx)
 {
 	BUG_ON(!list_empty(&ctx->interfaces));
 
+	drv_remove_chanctx(ctx->local, ctx);
+
 	list_del(&ctx->list);
 	kfree(ctx);
 }
@@ -205,12 +210,16 @@ ieee80211_assign_vif_chanctx(struct ieee80211_sub_if_data *sdata,
 {
 	list_add(&sdata->chanctx_listitem, &ctx->interfaces);
 	sdata->vif.chanctx_conf = &ctx->conf;
+
+	drv_assign_vif_chanctx(sdata->local, sdata, ctx);
 }
 
 static void
 ieee80211_unassign_vif_chanctx(struct ieee80211_sub_if_data *sdata,
 			       struct ieee80211_chanctx *ctx)
 {
+	drv_unassign_vif_chanctx(sdata->local, sdata, ctx);
+
 	sdata->vif.chanctx_conf = NULL;
 	list_del(&sdata->chanctx_listitem);
 }
-- 
1.7.0.4


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [RFC v2 6/7] mac80211: refactor set_channel_type
  2012-06-21 12:03 [RFC v2] initial channel context implementation Michal Kazior
                   ` (4 preceding siblings ...)
  2012-06-21 12:03 ` [RFC v2 5/7] mac80211: use channel context notifications Michal Kazior
@ 2012-06-21 12:03 ` Michal Kazior
  2012-06-21 12:03 ` [RFC v2 7/7] mac80211: reuse channels for channel context Michal Kazior
  2012-06-21 13:19 ` [RFC v2] initial channel context implementation Johannes Berg
  7 siblings, 0 replies; 13+ messages in thread
From: Michal Kazior @ 2012-06-21 12:03 UTC (permalink / raw)
  To: johannes; +Cc: linux-wireless, Kazior Michal, Michal Kazior

From: Kazior Michal <Michal.Kazior@tieto.com>

Split functionality for further reuse.

Will prevent code duplication when channel context
channel_type merging is introduced.

Signed-off-by: Michal Kazior <michal.kazior@tieto.com>
---
 net/mac80211/chan.c |   57 ++++++++++++++++++++++++++++++++++-----------------
 1 files changed, 38 insertions(+), 19 deletions(-)

diff --git a/net/mac80211/chan.c b/net/mac80211/chan.c
index 20483a0..63b7cb7 100644
--- a/net/mac80211/chan.c
+++ b/net/mac80211/chan.c
@@ -69,16 +69,14 @@ ieee80211_get_channel_mode(struct ieee80211_local *local,
 	return mode;
 }
 
-bool ieee80211_set_channel_type(struct ieee80211_local *local,
-				struct ieee80211_sub_if_data *sdata,
-				enum nl80211_channel_type chantype)
+static enum nl80211_channel_type
+ieee80211_get_superchan(struct ieee80211_local *local,
+			struct ieee80211_sub_if_data *sdata)
 {
-	struct ieee80211_sub_if_data *tmp;
 	enum nl80211_channel_type superchan = NL80211_CHAN_NO_HT;
-	bool result;
+	struct ieee80211_sub_if_data *tmp;
 
 	mutex_lock(&local->iflist_mtx);
-
 	list_for_each_entry(tmp, &local->interfaces, list) {
 		if (tmp == sdata)
 			continue;
@@ -104,41 +102,62 @@ bool ieee80211_set_channel_type(struct ieee80211_local *local,
 			break;
 		}
 	}
+	mutex_unlock(&local->iflist_mtx);
+
+	return superchan;
+}
 
-	switch (superchan) {
+static bool
+ieee80211_channel_types_are_compatible(enum nl80211_channel_type chantype1,
+				       enum nl80211_channel_type chantype2,
+				       enum nl80211_channel_type *compat)
+{
+	switch (chantype1) {
 	case NL80211_CHAN_NO_HT:
 	case NL80211_CHAN_HT20:
 		/*
 		 * allow any change that doesn't go to no-HT
 		 * (if it already is no-HT no change is needed)
 		 */
-		if (chantype == NL80211_CHAN_NO_HT)
+		if (chantype2 == NL80211_CHAN_NO_HT)
 			break;
-		superchan = chantype;
+		*compat = chantype2;
 		break;
 	case NL80211_CHAN_HT40PLUS:
 	case NL80211_CHAN_HT40MINUS:
+		*compat = chantype1;
 		/* allow smaller bandwidth and same */
-		if (chantype == NL80211_CHAN_NO_HT)
+		if (chantype2 == NL80211_CHAN_NO_HT)
 			break;
-		if (chantype == NL80211_CHAN_HT20)
+		if (chantype2 == NL80211_CHAN_HT20)
 			break;
-		if (superchan == chantype)
+		if (chantype2 == chantype1)
 			break;
-		result = false;
-		goto out;
+		return false;
 	}
 
-	local->_oper_channel_type = superchan;
+	return true;
+}
+
+bool ieee80211_set_channel_type(struct ieee80211_local *local,
+				struct ieee80211_sub_if_data *sdata,
+				enum nl80211_channel_type chantype)
+{
+	enum nl80211_channel_type superchan;
+	enum nl80211_channel_type compatchan = NL80211_CHAN_NO_HT;
+
+	superchan = ieee80211_get_superchan(local, sdata);
+	if (!ieee80211_channel_types_are_compatible(superchan, chantype,
+						    &compatchan))
+		return false;
+
+	local->_oper_channel_type = compatchan;
 
 	if (sdata)
 		sdata->vif.bss_conf.channel_type = chantype;
 
-	result = true;
- out:
-	mutex_unlock(&local->iflist_mtx);
+	return true;
 
-	return result;
 }
 
 static struct ieee80211_chanctx *
-- 
1.7.0.4


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [RFC v2 7/7] mac80211: reuse channels for channel context
  2012-06-21 12:03 [RFC v2] initial channel context implementation Michal Kazior
                   ` (5 preceding siblings ...)
  2012-06-21 12:03 ` [RFC v2 6/7] mac80211: refactor set_channel_type Michal Kazior
@ 2012-06-21 12:03 ` Michal Kazior
  2012-06-21 13:26   ` Johannes Berg
  2012-06-21 13:19 ` [RFC v2] initial channel context implementation Johannes Berg
  7 siblings, 1 reply; 13+ messages in thread
From: Michal Kazior @ 2012-06-21 12:03 UTC (permalink / raw)
  To: johannes; +Cc: linux-wireless, Kazior Michal, Michal Kazior

From: Kazior Michal <Michal.Kazior@tieto.com>

Reuse channels with compatible channel types. Some
channel types are compatible and can be used
concurrently.

Signed-off-by: Michal Kazior <michal.kazior@tieto.com>
---
 net/mac80211/chan.c |   11 +++++++++++
 1 files changed, 11 insertions(+), 0 deletions(-)

diff --git a/net/mac80211/chan.c b/net/mac80211/chan.c
index 63b7cb7..97be454 100644
--- a/net/mac80211/chan.c
+++ b/net/mac80211/chan.c
@@ -167,6 +167,7 @@ ieee80211_find_chanctx(struct ieee80211_local *local,
 		       enum ieee80211_chanctx_mode mode)
 {
 	struct ieee80211_chanctx *ctx;
+	enum nl80211_channel_type compat_type;
 
 	if (mode == IEEE80211_CHANCTX_EXCLUSIVE)
 		return NULL;
@@ -174,12 +175,22 @@ ieee80211_find_chanctx(struct ieee80211_local *local,
 		return NULL;
 
 	list_for_each_entry(ctx, &local->chanctx_list, list) {
+		compat_type = ctx->conf.channel_type;
+
 		if (ctx->conf.mode == IEEE80211_CHANCTX_EXCLUSIVE)
 			continue;
 		if (ctx->conf.channel != channel)
 			continue;
 		if (ctx->conf.channel_type != channel_type)
 			continue;
+		if (!ieee80211_channel_types_are_compatible(ctx->conf.channel_type,
+							    channel_type,
+							    &compat_type))
+			continue;
+		if (ctx->conf.channel_type != compat_type) {
+			ctx->conf.channel_type = compat_type;
+			drv_change_chantype(local, ctx);
+		}
 
 		return ctx;
 	}
-- 
1.7.0.4


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* Re: [RFC v2] initial channel context implementation
  2012-06-21 12:03 [RFC v2] initial channel context implementation Michal Kazior
                   ` (6 preceding siblings ...)
  2012-06-21 12:03 ` [RFC v2 7/7] mac80211: reuse channels for channel context Michal Kazior
@ 2012-06-21 13:19 ` Johannes Berg
  7 siblings, 0 replies; 13+ messages in thread
From: Johannes Berg @ 2012-06-21 13:19 UTC (permalink / raw)
  To: Michal Kazior; +Cc: linux-wireless

On Thu, 2012-06-21 at 14:03 +0200, Michal Kazior wrote:
> Hi,
> 
> Here's my respin of channel contexts patches. Thanks for the
> review on the previous version.

Looks pretty good to me, I'll follow up on the patches with some minor
comments.

> Changes in short:
> 
>  * renamed to chanctx (to avoid very_long_structure_names)
>  * pub/priv part added (and drv_priv)
>  * new mutex added
>  * channel contexts are a linked list
>  * tracing added
> 
> Next step would be to refactor mac80211 codepaths to take
> advantage of channel contexts (if used).

Sounds about right :)

johannes


^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [RFC v2 1/7] mac80211: introduce channel contexts skeleton code
  2012-06-21 12:03 ` [RFC v2 1/7] mac80211: introduce channel contexts skeleton code Michal Kazior
@ 2012-06-21 13:24   ` Johannes Berg
  2012-06-25  6:52     ` Michal Kazior
  0 siblings, 1 reply; 13+ messages in thread
From: Johannes Berg @ 2012-06-21 13:24 UTC (permalink / raw)
  To: Michal Kazior; +Cc: linux-wireless

On Thu, 2012-06-21 at 14:03 +0200, Michal Kazior wrote:

> +++ b/include/net/mac80211.h
> @@ -143,6 +143,41 @@ struct ieee80211_low_level_stats {
>  	unsigned int dot11RTSSuccessCount;
>  };
>  
> +
> +/**
> + * enum ieee80211_chanctx_mode - channel context configuration mode
> + *
> + * @IEEE80211_CHANCTX_SHARED: channel context may be used by
> + *	multiple interfaces
> + * @IEEE80211_CHANCTX_EXCLUSIVE: channel context can be used
> + *	only by a single interface. This can be used for example for
> + *	non-fixed channel IBSS.
> + */
> +enum ieee80211_chanctx_mode {
> +	IEEE80211_CHANCTX_SHARED,
> +	IEEE80211_CHANCTX_EXCLUSIVE
> +};

Does the driver ever care about this? It seems mostly internal to
determine what's going on?


> + * @chanctx_conf: channel context vif is bound to, may be NULL

Maybe say "will be %NULL before the interface is assigned to a channel
context" or so?

> +	INIT_LIST_HEAD(&ctx->interfaces);

Is there really a need for this list? It seems only moderately less
efficient to iterate all interfaces and filter by channel context, and
that's probably easier to maintain?

> +static void
> +__ieee80211_vif_release_channel(struct ieee80211_sub_if_data *sdata)
> +{
> +	struct ieee80211_chanctx_conf *conf = sdata->vif.chanctx_conf;
> +	struct ieee80211_chanctx *ctx =
> +			container_of(conf, struct ieee80211_chanctx, conf);
> +
> +	if (!conf)
> +		return;
> +
> +	ieee80211_unassign_vif_chanctx(sdata, ctx);
> +	if (list_empty(&ctx->interfaces))
> +		ieee80211_free_chanctx(ctx);
> +}

Ah, ok. So I guess there's a good use for the list at least here.

johannes


^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [RFC v2 7/7] mac80211: reuse channels for channel context
  2012-06-21 12:03 ` [RFC v2 7/7] mac80211: reuse channels for channel context Michal Kazior
@ 2012-06-21 13:26   ` Johannes Berg
  2012-06-25  6:54     ` Michal Kazior
  0 siblings, 1 reply; 13+ messages in thread
From: Johannes Berg @ 2012-06-21 13:26 UTC (permalink / raw)
  To: Michal Kazior; +Cc: linux-wireless

On Thu, 2012-06-21 at 14:03 +0200, Michal Kazior wrote:

> +		if (!ieee80211_channel_types_are_compatible(ctx->conf.channel_type,
> +							    channel_type,
> +							    &compat_type))
> +			continue;
> +		if (ctx->conf.channel_type != compat_type) {
> +			ctx->conf.channel_type = compat_type;
> +			drv_change_chantype(local, ctx);
> +		}

Maybe somehow there's a need to also keep track of the desired channel
type per vif so it can be recalculated when a vif is removed, not just
when one is added?

johannes


^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [RFC v2 1/7] mac80211: introduce channel contexts skeleton code
  2012-06-21 13:24   ` Johannes Berg
@ 2012-06-25  6:52     ` Michal Kazior
  0 siblings, 0 replies; 13+ messages in thread
From: Michal Kazior @ 2012-06-25  6:52 UTC (permalink / raw)
  To: Johannes Berg; +Cc: linux-wireless

Johannes Berg wrote:
> On Thu, 2012-06-21 at 14:03 +0200, Michal Kazior wrote:
>
>> +++ b/include/net/mac80211.h
>> @@ -143,6 +143,41 @@ struct ieee80211_low_level_stats {
>>   	unsigned int dot11RTSSuccessCount;
>>   };
>>
>> +
>> +/**
>> + * enum ieee80211_chanctx_mode - channel context configuration mode
>> + *
>> + * @IEEE80211_CHANCTX_SHARED: channel context may be used by
>> + *	multiple interfaces
>> + * @IEEE80211_CHANCTX_EXCLUSIVE: channel context can be used
>> + *	only by a single interface. This can be used for example for
>> + *	non-fixed channel IBSS.
>> + */
>> +enum ieee80211_chanctx_mode {
>> +	IEEE80211_CHANCTX_SHARED,
>> +	IEEE80211_CHANCTX_EXCLUSIVE
>> +};
>
> Does the driver ever care about this? It seems mostly internal to
> determine what's going on?

Why did I put it there I wonder.


>> + * @chanctx_conf: channel context vif is bound to, may be NULL
>
> Maybe say "will be %NULL before the interface is assigned to a channel
> context" or so?
>
>> +	INIT_LIST_HEAD(&ctx->interfaces);
>
> Is there really a need for this list? It seems only moderately less
> efficient to iterate all interfaces and filter by channel context, and
> that's probably easier to maintain?
>
>> +static void
>> +__ieee80211_vif_release_channel(struct ieee80211_sub_if_data *sdata)
>> +{
>> +	struct ieee80211_chanctx_conf *conf = sdata->vif.chanctx_conf;
>> +	struct ieee80211_chanctx *ctx =
>> +			container_of(conf, struct ieee80211_chanctx, conf);
>> +
>> +	if (!conf)
>> +		return;
>> +
>> +	ieee80211_unassign_vif_chanctx(sdata, ctx);
>> +	if (list_empty(&ctx->interfaces))
>> +		ieee80211_free_chanctx(ctx);
>> +}
>
> Ah, ok. So I guess there's a good use for the list at least here.

Actually you're right. I'll make it a simple refcount. No need to do 
fancy lists.


-- 
Pozdrawiam / Best regards, Michal Kazior.

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [RFC v2 7/7] mac80211: reuse channels for channel context
  2012-06-21 13:26   ` Johannes Berg
@ 2012-06-25  6:54     ` Michal Kazior
  0 siblings, 0 replies; 13+ messages in thread
From: Michal Kazior @ 2012-06-25  6:54 UTC (permalink / raw)
  To: Johannes Berg; +Cc: linux-wireless

Johannes Berg wrote:
> On Thu, 2012-06-21 at 14:03 +0200, Michal Kazior wrote:
>
>> +		if (!ieee80211_channel_types_are_compatible(ctx->conf.channel_type,
>> +							    channel_type,
>> +							&compat_type))
>> +			continue;
>> +		if (ctx->conf.channel_type != compat_type) {
>> +			ctx->conf.channel_type = compat_type;
>> +			drv_change_chantype(local, ctx);
>> +		}
>
> Maybe somehow there's a need to also keep track of the desired channel
> type per vif so it can be recalculated when a vif is removed, not just
> when one is added?

Sounds good.


-- 
Pozdrawiam / Best regards, Michal Kazior.

^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2012-06-25  6:54 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-06-21 12:03 [RFC v2] initial channel context implementation Michal Kazior
2012-06-21 12:03 ` [RFC v2 1/7] mac80211: introduce channel contexts skeleton code Michal Kazior
2012-06-21 13:24   ` Johannes Berg
2012-06-25  6:52     ` Michal Kazior
2012-06-21 12:03 ` [RFC v2 2/7] mac80211: introduce new ieee80211_ops Michal Kazior
2012-06-21 12:03 ` [RFC v2 3/7] mac80211: add drv_* wrappers for channel contexts Michal Kazior
2012-06-21 12:03 ` [RFC v2 4/7] mac80211: add chanctx tracing Michal Kazior
2012-06-21 12:03 ` [RFC v2 5/7] mac80211: use channel context notifications Michal Kazior
2012-06-21 12:03 ` [RFC v2 6/7] mac80211: refactor set_channel_type Michal Kazior
2012-06-21 12:03 ` [RFC v2 7/7] mac80211: reuse channels for channel context Michal Kazior
2012-06-21 13:26   ` Johannes Berg
2012-06-25  6:54     ` Michal Kazior
2012-06-21 13:19 ` [RFC v2] initial channel context implementation Johannes Berg

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.