2012-03-20 14:40:15

by Michal Kazior

[permalink] [raw]
Subject: [RFC 11/12] mac80211: split offchannel functions to per-vif

In preparation for multi-channel operation.

Signed-off-by: Michal Kazior <[email protected]>
---
net/mac80211/ieee80211_i.h | 4 ++
net/mac80211/offchannel.c | 122 ++++++++++++++++++++++++--------------------
2 files changed, 70 insertions(+), 56 deletions(-)

diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 4ceedff..58ee794 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -1280,8 +1280,12 @@ int ieee80211_request_sched_scan_stop(struct ieee80211_sub_if_data *sdata);
void ieee80211_sched_scan_stopped_work(struct work_struct *work);

/* off-channel helpers */
+void ieee80211_offchannel_stop_vif(struct ieee80211_sub_if_data *sdata,
+ bool offchannel_ps_enable);
void ieee80211_offchannel_stop_vifs(struct ieee80211_local *local,
bool offchannel_ps_enable);
+void ieee80211_offchannel_return_vif(struct ieee80211_sub_if_data *sdata,
+ bool offchannel_ps_disable);
void ieee80211_offchannel_return_vifs(struct ieee80211_local *local,
bool offchannel_ps_disable);
void ieee80211_hw_roc_setup(struct ieee80211_local *local);
diff --git a/net/mac80211/offchannel.c b/net/mac80211/offchannel.c
index 06a809d..a5a5f1d 100644
--- a/net/mac80211/offchannel.c
+++ b/net/mac80211/offchannel.c
@@ -103,6 +103,31 @@ static void ieee80211_offchannel_ps_disable(struct ieee80211_sub_if_data *sdata)
ieee80211_sta_reset_conn_monitor(sdata);
}

+void ieee80211_offchannel_stop_vif(struct ieee80211_sub_if_data *sdata,
+ bool offchannel_ps_enable)
+{
+ if (!ieee80211_sdata_running(sdata))
+ return;
+
+ if (sdata->vif.type != NL80211_IFTYPE_MONITOR)
+ set_bit(SDATA_STATE_OFFCHANNEL, &sdata->state);
+
+ /* Check to see if we should disable beaconing. */
+ if (sdata->vif.type == NL80211_IFTYPE_AP ||
+ sdata->vif.type == NL80211_IFTYPE_ADHOC ||
+ sdata->vif.type == NL80211_IFTYPE_MESH_POINT)
+ ieee80211_bss_info_change_notify(
+ sdata, BSS_CHANGED_BEACON_ENABLED);
+
+ if (sdata->vif.type != NL80211_IFTYPE_MONITOR) {
+ netif_tx_stop_all_queues(sdata->dev);
+ if (offchannel_ps_enable &&
+ (sdata->vif.type == NL80211_IFTYPE_STATION) &&
+ sdata->u.mgd.associated)
+ ieee80211_offchannel_ps_enable(sdata, true);
+ }
+}
+
void ieee80211_offchannel_stop_vifs(struct ieee80211_local *local,
bool offchannel_ps_enable)
{
@@ -113,71 +138,56 @@ void ieee80211_offchannel_stop_vifs(struct ieee80211_local *local,
* STA interfaces.
*/
mutex_lock(&local->iflist_mtx);
- list_for_each_entry(sdata, &local->interfaces, list) {
- if (!ieee80211_sdata_running(sdata))
- continue;
-
- if (sdata->vif.type != NL80211_IFTYPE_MONITOR)
- set_bit(SDATA_STATE_OFFCHANNEL, &sdata->state);
-
- /* Check to see if we should disable beaconing. */
- if (sdata->vif.type == NL80211_IFTYPE_AP ||
- sdata->vif.type == NL80211_IFTYPE_ADHOC ||
- sdata->vif.type == NL80211_IFTYPE_MESH_POINT)
- ieee80211_bss_info_change_notify(
- sdata, BSS_CHANGED_BEACON_ENABLED);
-
- if (sdata->vif.type != NL80211_IFTYPE_MONITOR) {
- netif_tx_stop_all_queues(sdata->dev);
- if (offchannel_ps_enable &&
- (sdata->vif.type == NL80211_IFTYPE_STATION) &&
- sdata->u.mgd.associated)
- ieee80211_offchannel_ps_enable(sdata, true);
- }
- }
+ list_for_each_entry(sdata, &local->interfaces, list)
+ ieee80211_offchannel_stop_vif(sdata, offchannel_ps_enable);
mutex_unlock(&local->iflist_mtx);
}

+void ieee80211_offchannel_return_vif(struct ieee80211_sub_if_data *sdata,
+ bool offchannel_ps_disable)
+{
+ if (sdata->vif.type != NL80211_IFTYPE_MONITOR)
+ clear_bit(SDATA_STATE_OFFCHANNEL, &sdata->state);
+
+ if (!ieee80211_sdata_running(sdata))
+ return;
+
+ /* Tell AP we're back */
+ if (offchannel_ps_disable &&
+ sdata->vif.type == NL80211_IFTYPE_STATION) {
+ if (sdata->u.mgd.associated)
+ ieee80211_offchannel_ps_disable(sdata);
+ }
+
+ if (sdata->vif.type != NL80211_IFTYPE_MONITOR) {
+ /*
+ * This may wake up queues even though the driver
+ * currently has them stopped. This is not very
+ * likely, since the driver won't have gotten any
+ * (or hardly any) new packets while we weren't
+ * on the right channel, and even if it happens
+ * it will at most lead to queueing up one more
+ * packet per queue in mac80211 rather than on
+ * the interface qdisc.
+ */
+ netif_tx_wake_all_queues(sdata->dev);
+ }
+
+ if (sdata->vif.type == NL80211_IFTYPE_AP ||
+ sdata->vif.type == NL80211_IFTYPE_ADHOC ||
+ sdata->vif.type == NL80211_IFTYPE_MESH_POINT)
+ ieee80211_bss_info_change_notify(
+ sdata, BSS_CHANGED_BEACON_ENABLED);
+}
+
void ieee80211_offchannel_return_vifs(struct ieee80211_local *local,
bool offchannel_ps_disable)
{
struct ieee80211_sub_if_data *sdata;

mutex_lock(&local->iflist_mtx);
- list_for_each_entry(sdata, &local->interfaces, list) {
- if (sdata->vif.type != NL80211_IFTYPE_MONITOR)
- clear_bit(SDATA_STATE_OFFCHANNEL, &sdata->state);
-
- if (!ieee80211_sdata_running(sdata))
- continue;
-
- /* Tell AP we're back */
- if (offchannel_ps_disable &&
- sdata->vif.type == NL80211_IFTYPE_STATION) {
- if (sdata->u.mgd.associated)
- ieee80211_offchannel_ps_disable(sdata);
- }
-
- if (sdata->vif.type != NL80211_IFTYPE_MONITOR) {
- /*
- * This may wake up queues even though the driver
- * currently has them stopped. This is not very
- * likely, since the driver won't have gotten any
- * (or hardly any) new packets while we weren't
- * on the right channel, and even if it happens
- * it will at most lead to queueing up one more
- * packet per queue in mac80211 rather than on
- * the interface qdisc.
- */
- netif_tx_wake_all_queues(sdata->dev);
- }
-
- if (sdata->vif.type == NL80211_IFTYPE_AP ||
- sdata->vif.type == NL80211_IFTYPE_ADHOC ||
- sdata->vif.type == NL80211_IFTYPE_MESH_POINT)
- ieee80211_bss_info_change_notify(
- sdata, BSS_CHANGED_BEACON_ENABLED);
- }
+ list_for_each_entry(sdata, &local->interfaces, list)
+ ieee80211_offchannel_return_vif(sdata, offchannel_ps_disable);
mutex_unlock(&local->iflist_mtx);
}

--
1.7.0.4



2012-03-23 09:15:33

by Michal Kazior

[permalink] [raw]
Subject: Re: [RFC 11/12] mac80211: split offchannel functions to per-vif

Johannes Berg wrote:
> This seems very odd. Why would one vif be off-channel, and the other be
> on-channel? That makes no sense, off-channel is a global state.

Should mac80211 care if the device does channel-hopping? What if it's
possible for off-channel to be done simultaneously because the device
has two radios?

Maybe off-channel should also be reworked more to support multiple
scenarios?


> My thinking here right now is that mac80211-based off-channel and
> scanning will only be supported for devices that don't implement
> multi-channel, since all others really need to do the channel scheduling
> themselves.

Software off-channel isn't used only for scanning, or is it?


-- Pozdrawiam / Best Regards, Michal Kazior.

2012-03-23 09:20:18

by Johannes Berg

[permalink] [raw]
Subject: Re: [RFC 11/12] mac80211: split offchannel functions to per-vif

On Fri, 2012-03-23 at 10:15 +0100, MichaƂ Kazior wrote:
> Johannes Berg wrote:
> > This seems very odd. Why would one vif be off-channel, and the other be
> > on-channel? That makes no sense, off-channel is a global state.
>
> Should mac80211 care if the device does channel-hopping? What if it's
> possible for off-channel to be done simultaneously because the device
> has two radios?

What do you mean by channel hopping? IBSS-like behaviour?

The two radios case is interesting, but is it really relevant right now?
I suspect the first case of it we'll see will be 11ad and then it's two
different bands.

> Maybe off-channel should also be reworked more to support multiple
> scenarios?

What scenarios do you have in mind?

> > My thinking here right now is that mac80211-based off-channel and
> > scanning will only be supported for devices that don't implement
> > multi-channel, since all others really need to do the channel scheduling
> > themselves.
>
> Software off-channel isn't used only for scanning, or is it?

It's only used for scanning & P2P-device activities right now, I could
see it being used for FT-OTA (with resource reservation) too in the
future, if needed, but that's about it.

johannes


2012-03-23 08:53:26

by Johannes Berg

[permalink] [raw]
Subject: Re: [RFC 11/12] mac80211: split offchannel functions to per-vif

This seems very odd. Why would one vif be off-channel, and the other be
on-channel? That makes no sense, off-channel is a global state.

My thinking here right now is that mac80211-based off-channel and
scanning will only be supported for devices that don't implement
multi-channel, since all others really need to do the channel scheduling
themselves.

johannes