All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC PATCH 0/3] mac80211: nullfunc connection monitor
@ 2010-02-17 21:04 Kalle Valo
  2010-02-17 21:04 ` [RFC PATCH 1/3] mac80211: refactor nullfunc status handling to a separate function Kalle Valo
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Kalle Valo @ 2010-02-17 21:04 UTC (permalink / raw)
  To: linux-wireless

I have been thinking about using nullfunc frames in connection monitor
with hw which have IEEE80211_HW_REPORTS_TX_ACK_STATUS. Here are my
current patches based on the idea. They have received minimal testing
and there's still some work to do.

But I would like to get comments what people think about this. Might
this create some kind of IOP problems, for example?

I also added a new hw flag to be able to offload connection monitoring
to the hardware.

TODO:

o send qos nullfunc when using wmm

---

Kalle Valo (3):
      mac80211: refactor nullfunc status handling to a separate function
      mac80211: use nullfunc in connection monitor
      mac80211: add support connection monitor in hardware


 include/net/mac80211.h     |    1 +
 net/mac80211/ieee80211_i.h |    1 +
 net/mac80211/mlme.c        |   40 +++++++++++++++++----
 net/mac80211/status.c      |   84 +++++++++++++++++++++++++++++++++++++-------
 4 files changed, 106 insertions(+), 20 deletions(-)


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

* [RFC PATCH 1/3] mac80211: refactor nullfunc status handling to a separate function
  2010-02-17 21:04 [RFC PATCH 0/3] mac80211: nullfunc connection monitor Kalle Valo
@ 2010-02-17 21:04 ` Kalle Valo
  2010-02-17 21:04 ` [RFC PATCH 2/3] mac80211: use nullfunc in connection monitor Kalle Valo
  2010-02-17 21:04 ` [RFC PATCH 3/3] mac80211: add support connection monitor in hardware Kalle Valo
  2 siblings, 0 replies; 4+ messages in thread
From: Kalle Valo @ 2010-02-17 21:04 UTC (permalink / raw)
  To: linux-wireless

From: Kalle Valo <kalle.valo@nokia.com>

Create a new function for handling nullfunc status and make it easier
to add new functionality.

No functional changes.

Signed-off-by: Kalle Valo <kalle.valo@nokia.com>
---
 net/mac80211/status.c |   38 +++++++++++++++++++++++++-------------
 1 files changed, 25 insertions(+), 13 deletions(-)

diff --git a/net/mac80211/status.c b/net/mac80211/status.c
index 56d5b9a..8a17454 100644
--- a/net/mac80211/status.c
+++ b/net/mac80211/status.c
@@ -157,6 +157,29 @@ static void ieee80211_frame_acked(struct sta_info *sta, struct sk_buff *skb)
 	}
 }
 
+static void ieee80211_nullfunc_status(struct ieee80211_local *local,
+				      struct sk_buff *skb)
+{
+	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
+	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+	__le16 fc = hdr->frame_control;
+
+	if (ieee80211_has_pm(fc) &&
+	    (local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS) &&
+	    !(info->flags & IEEE80211_TX_CTL_INJECTED) &&
+	    local->ps_sdata && !(local->scanning)) {
+		if (info->flags & IEEE80211_TX_STAT_ACK) {
+			local->ps_sdata->u.mgd.flags |=
+				IEEE80211_STA_NULLFUNC_ACKED;
+			ieee80211_queue_work(&local->hw,
+					     &local->dynamic_ps_enable_work);
+		} else
+			mod_timer(&local->dynamic_ps_timer, jiffies +
+				  msecs_to_jiffies(10));
+	}
+}
+
+
 void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
 {
 	struct sk_buff *skb2;
@@ -274,19 +297,8 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
 			local->dot11FailedCount++;
 	}
 
-	if (ieee80211_is_nullfunc(fc) && ieee80211_has_pm(fc) &&
-	    (local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS) &&
-	    !(info->flags & IEEE80211_TX_CTL_INJECTED) &&
-	    local->ps_sdata && !(local->scanning)) {
-		if (info->flags & IEEE80211_TX_STAT_ACK) {
-			local->ps_sdata->u.mgd.flags |=
-					IEEE80211_STA_NULLFUNC_ACKED;
-			ieee80211_queue_work(&local->hw,
-					&local->dynamic_ps_enable_work);
-		} else
-			mod_timer(&local->dynamic_ps_timer, jiffies +
-					msecs_to_jiffies(10));
-	}
+	if (ieee80211_is_nullfunc(fc))
+		ieee80211_nullfunc_status(local, skb);
 
 	if (info->flags & IEEE80211_TX_INTFL_NL80211_FRAME_TX)
 		cfg80211_action_tx_status(


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

* [RFC PATCH 2/3] mac80211: use nullfunc in connection monitor
  2010-02-17 21:04 [RFC PATCH 0/3] mac80211: nullfunc connection monitor Kalle Valo
  2010-02-17 21:04 ` [RFC PATCH 1/3] mac80211: refactor nullfunc status handling to a separate function Kalle Valo
@ 2010-02-17 21:04 ` Kalle Valo
  2010-02-17 21:04 ` [RFC PATCH 3/3] mac80211: add support connection monitor in hardware Kalle Valo
  2 siblings, 0 replies; 4+ messages in thread
From: Kalle Valo @ 2010-02-17 21:04 UTC (permalink / raw)
  To: linux-wireless

From: Kalle Valo <kalle.valo@nokia.com>

Currently mac80211 is periodically sending probe request to the AP
during idle periods to make sure that the connection to the AP works. But
on hardware which have IEEE80211_HW_REPORTS_TX_ACK_STATUS we can use
nullfunc frames. This is because  we can check from the tx status if an
acknowledgement frame was received from the AP or not.

Major benefit from this is that we don't need to wakeup from power save
just for this and can save power. Another benefit is that we can faster notice
if the AP is lost and hopefully reduce the roaming time in that case.
(NB: these are not implemented yet)

In the first phase we just use nullfunc frames instead of the probe requsts
and do not change the mlme drastically, just to be on the safe side. Later
on the logic can be improved and we can get the benefits mentioned above.

Signed-off-by: Kalle Valo <kalle.valo@nokia.com>
---
 net/mac80211/ieee80211_i.h |    1 +
 net/mac80211/mlme.c        |   37 ++++++++++++++++++++++++------
 net/mac80211/status.c      |   54 +++++++++++++++++++++++++++++++++++++++++---
 3 files changed, 81 insertions(+), 11 deletions(-)

diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 241533e..79e065b 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -317,6 +317,7 @@ enum ieee80211_sta_flags {
 	IEEE80211_STA_MFP_ENABLED	= BIT(6),
 	IEEE80211_STA_UAPSD_ENABLED	= BIT(7),
 	IEEE80211_STA_NULLFUNC_ACKED	= BIT(8),
+	IEEE80211_STA_CON_POLL_ACKED	= BIT(9),
 };
 
 struct ieee80211_if_managed {
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 41812a1..4b9596f 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -857,11 +857,16 @@ void ieee80211_sta_rx_notify(struct ieee80211_sub_if_data *sdata,
 static void ieee80211_mgd_probe_ap_send(struct ieee80211_sub_if_data *sdata)
 {
 	struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
+	struct ieee80211_local *local = sdata->local;
 	const u8 *ssid;
 
-	ssid = ieee80211_bss_get_ie(ifmgd->associated, WLAN_EID_SSID);
-	ieee80211_send_probe_req(sdata, ifmgd->associated->bssid,
-				 ssid + 2, ssid[1], NULL, 0);
+	if (local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS) {
+		ieee80211_send_nullfunc(local, sdata, 0);
+	} else {
+		ssid = ieee80211_bss_get_ie(ifmgd->associated, WLAN_EID_SSID);
+		ieee80211_send_probe_req(sdata, ifmgd->associated->bssid,
+					 ssid + 2, ssid[1], NULL, 0);
+	}
 
 	ifmgd->probe_send_count++;
 	ifmgd->probe_timeout = jiffies + IEEE80211_PROBE_WAIT;
@@ -1579,9 +1584,27 @@ static void ieee80211_sta_work(struct work_struct *work)
 	/* then process the rest of the work */
 	mutex_lock(&ifmgd->mtx);
 
-	if (ifmgd->flags & (IEEE80211_STA_BEACON_POLL |
+	if ((local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS) &&
+	    (ifmgd->flags & IEEE80211_STA_CON_POLL_ACKED)) {
+		/* FIXME: refactor with rx_mgmg_probe_resp() */
+		ifmgd->flags &= ~(IEEE80211_STA_CONNECTION_POLL |
+				  IEEE80211_STA_BEACON_POLL |
+				  IEEE80211_STA_CON_POLL_ACKED);
+		mutex_lock(&sdata->local->iflist_mtx);
+		ieee80211_recalc_ps(sdata->local, -1);
+		mutex_unlock(&sdata->local->iflist_mtx);
+		/*
+		 * We've received a probe response, but are not sure whether
+		 * we have or will be receiving any beacons or data, so let's
+		 * schedule the timers again, just in case.
+		 */
+		mod_beacon_timer(sdata);
+		mod_timer(&ifmgd->conn_mon_timer,
+			  round_jiffies_up(jiffies +
+					   IEEE80211_CONNECTION_IDLE_TIME));
+	} else if (ifmgd->flags & (IEEE80211_STA_BEACON_POLL |
 			    IEEE80211_STA_CONNECTION_POLL) &&
-	    ifmgd->associated) {
+		   ifmgd->associated) {
 		u8 bssid[ETH_ALEN];
 
 		memcpy(bssid, ifmgd->associated->bssid, ETH_ALEN);
@@ -1590,7 +1613,7 @@ static void ieee80211_sta_work(struct work_struct *work)
 
 		else if (ifmgd->probe_send_count < IEEE80211_MAX_PROBE_TRIES) {
 #ifdef CONFIG_MAC80211_VERBOSE_DEBUG
-			printk(KERN_DEBUG "No probe response from AP %pM"
+			printk(KERN_DEBUG "No response from AP %pM"
 				" after %dms, try %d\n", bssid,
 				(1000 * IEEE80211_PROBE_WAIT)/HZ,
 				ifmgd->probe_send_count);
@@ -1603,7 +1626,7 @@ static void ieee80211_sta_work(struct work_struct *work)
 			 */
 			ifmgd->flags &= ~(IEEE80211_STA_CONNECTION_POLL |
 					  IEEE80211_STA_BEACON_POLL);
-			printk(KERN_DEBUG "No probe response from AP %pM"
+			printk(KERN_DEBUG "No response from AP %pM"
 				" after %dms, disconnecting.\n",
 				bssid, (1000 * IEEE80211_PROBE_WAIT)/HZ);
 			ieee80211_set_disassoc(sdata);
diff --git a/net/mac80211/status.c b/net/mac80211/status.c
index 8a17454..5311977 100644
--- a/net/mac80211/status.c
+++ b/net/mac80211/status.c
@@ -162,12 +162,58 @@ static void ieee80211_nullfunc_status(struct ieee80211_local *local,
 {
 	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
 	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+	struct ieee80211_sub_if_data *sdata;
+	struct ieee80211_if_managed *ifmgd;
 	__le16 fc = hdr->frame_control;
 
-	if (ieee80211_has_pm(fc) &&
-	    (local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS) &&
-	    !(info->flags & IEEE80211_TX_CTL_INJECTED) &&
-	    local->ps_sdata && !(local->scanning)) {
+	if (!(local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS))
+		return;
+
+	if (info->flags & IEEE80211_TX_CTL_INJECTED)
+		return;
+
+	if (local->scanning)
+		return;
+
+	/* FIXME: check association? */
+
+	/*
+	 * only executed when either 1) power save is enabled or 2) idle
+	 * connection monitor is enabled, so this is definitely not in fast
+	 * path and can be slow
+	 */
+
+	/* connection tracking */
+	rcu_read_lock();
+	list_for_each_entry_rcu(sdata, &local->interfaces, list) {
+		if (sdata->vif.type != NL80211_IFTYPE_STATION)
+			continue;
+
+		ifmgd = &sdata->u.mgd;
+
+		if (ifmgd->flags & (IEEE80211_STA_BEACON_POLL |
+				    IEEE80211_STA_CONNECTION_POLL)) {
+			printk(KERN_DEBUG "nullfunc %s\n",
+			       (info->flags & IEEE80211_TX_STAT_ACK) ?
+			       "acked" : "nacked");
+
+			if (info->flags & IEEE80211_TX_STAT_ACK)
+				ifmgd->flags |= IEEE80211_STA_CON_POLL_ACKED;
+
+			/*
+			 * FIXME: report negative failure somehow, that way
+			 * there's no need to wait for the timer to
+			 * trigger
+			 */
+			ieee80211_queue_work(&local->hw, &ifmgd->work);
+		}
+
+	}
+	rcu_read_unlock();
+
+	/* trying to go into power save */
+	/* FIXME: add check for IEEE80211_HW_PS_NULLFUNC_STACK */
+	if (local->ps_sdata && ieee80211_has_pm(fc)) {
 		if (info->flags & IEEE80211_TX_STAT_ACK) {
 			local->ps_sdata->u.mgd.flags |=
 				IEEE80211_STA_NULLFUNC_ACKED;


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

* [RFC PATCH 3/3] mac80211: add support connection monitor in hardware
  2010-02-17 21:04 [RFC PATCH 0/3] mac80211: nullfunc connection monitor Kalle Valo
  2010-02-17 21:04 ` [RFC PATCH 1/3] mac80211: refactor nullfunc status handling to a separate function Kalle Valo
  2010-02-17 21:04 ` [RFC PATCH 2/3] mac80211: use nullfunc in connection monitor Kalle Valo
@ 2010-02-17 21:04 ` Kalle Valo
  2 siblings, 0 replies; 4+ messages in thread
From: Kalle Valo @ 2010-02-17 21:04 UTC (permalink / raw)
  To: linux-wireless

From: Kalle Valo <kalle.valo@nokia.com>

wl1271 has a feature so that it handles the connection monitor logic
in hardware, basically sending periodically nullfunc frames and reporting
to the host if AP is lost.

Add support to mac80211 by adding a new flag IEEE80211_HW_CONNECTION_MONITOR
which prevents conn_mon_timer from triggering during idle periods.

Signed-off-by: Kalle Valo <kalle.valo@nokia.com>
---
 include/net/mac80211.h |    1 +
 net/mac80211/mlme.c    |    3 +++
 2 files changed, 4 insertions(+), 0 deletions(-)

diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 80eb7cc..1d28fcc 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -975,6 +975,7 @@ enum ieee80211_hw_flags {
 	IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS		= 1<<16,
 	IEEE80211_HW_SUPPORTS_UAPSD			= 1<<17,
 	IEEE80211_HW_REPORTS_TX_ACK_STATUS		= 1<<18,
+	IEEE80211_HW_CONNECTION_MONITOR			= 1<<19,
 };
 
 /**
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 4b9596f..3fa8e6a 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -850,6 +850,9 @@ void ieee80211_sta_rx_notify(struct ieee80211_sub_if_data *sdata,
 	if (is_multicast_ether_addr(hdr->addr1))
 		return;
 
+	if (sdata->local->hw.flags & IEEE80211_HW_CONNECTION_MONITOR)
+		return;
+
 	mod_timer(&sdata->u.mgd.conn_mon_timer,
 		  round_jiffies_up(jiffies + IEEE80211_CONNECTION_IDLE_TIME));
 }


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

end of thread, other threads:[~2010-02-17 21:04 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-02-17 21:04 [RFC PATCH 0/3] mac80211: nullfunc connection monitor Kalle Valo
2010-02-17 21:04 ` [RFC PATCH 1/3] mac80211: refactor nullfunc status handling to a separate function Kalle Valo
2010-02-17 21:04 ` [RFC PATCH 2/3] mac80211: use nullfunc in connection monitor Kalle Valo
2010-02-17 21:04 ` [RFC PATCH 3/3] mac80211: add support connection monitor in hardware Kalle Valo

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.