I enabled power save for an rt2860 AP using the following diff:
Index: sys/dev/ic/rt2860.c
===================================================================
RCS file: /cvs/src/sys/dev/ic/rt2860.c,v
retrieving revision 1.65
diff -u -p -r1.65 sys/dev/ic/rt2860.c
--- sys/dev/ic/rt2860.c 23 Oct 2010 14:24:54 -0000 1.65
+++ sys/dev/ic/rt2860.c 17 Sep 2012 12:15:41 -0000
@@ -303,9 +303,7 @@ rt2860_attachhook(void *xsc)
#ifndef IEEE80211_STA_ONLY
IEEE80211_C_IBSS | /* IBSS mode supported */
IEEE80211_C_HOSTAP | /* HostAP mode supported */
-#ifdef notyet
IEEE80211_C_APPMGT | /* HostAP power management */
-#endif
#endif
IEEE80211_C_SHPREAMBLE | /* short preamble supported */
IEEE80211_C_SHSLOT | /* short slot time supported */
I found that some devices (android phones) would eventually fail to
associate. An ifconfig scan on the AP shows that the node would end up
in IEEE80211_STA_COLLECT status with power save enabled. Attempts by
the station to authenticate would then fail because the AP buffered
the authentication responses. The AP refuses to change the power save
status of a node that is not associated, which in turn prevents the
station from associating.
The first part of the solution is to clear the power save mode and
savedq in ieee80211_node_leave:
Index: ieee80211_node.c
===================================================================
RCS file: /cvs/src/sys/net80211/ieee80211_node.c,v
retrieving revision 1.74
diff -u -p -r1.74 ieee80211_node.c
--- ieee80211_node.c 20 Sep 2012 17:21:13 -0000 1.74
+++ ieee80211_node.c 28 Sep 2012 13:35:52 -0000
@@ -1604,8 +1604,18 @@ ieee80211_node_leave(struct ieee80211com
return;
}
- if (ni->ni_pwrsave == IEEE80211_PS_DOZE)
+ if (ni->ni_pwrsave == IEEE80211_PS_DOZE) {
ic->ic_pssta--;
+ ni->ni_pwrsave = IEEE80211_PS_AWAKE;
+ }
+
+#ifndef IEEE80211_STA_ONLY
+ if (!IF_IS_EMPTY(&ni->ni_savedq)) {
+ IF_PURGE(&ni->ni_savedq);
+ if (ic->ic_set_tim != NULL)
+ (*ic->ic_set_tim)(ic, ni->ni_associd, 0);
+ }
+#endif
if (ic->ic_flags & IEEE80211_F_RSNON)
ieee80211_node_leave_rsn(ic, ni);
This solves the problem providing the node leaves (either by
disassociating or by timeout) before trying to reauthenticate. However
if an associated station crashes while power save is enabled and then
attempts to reauthenticate with the power save flag set the power save
mode would become latched for that node. Normally this situation would
be avoided because a station would not set the power save flag during
authentication, but it can be avoided without relying on the behaviour
of the station by preventing nodes from transitioning directly from
IEEE80211_STA_ASSOC to IEEE80211_STA_AUTH. This has the additional
benefit of preventing a rogue station from forcing an already
associated node back to authenticated state, resulting in a DoS of an
associated station.
Index: ieee80211_proto.c
===================================================================
RCS file: /cvs/src/sys/net80211/ieee80211_proto.c,v
retrieving revision 1.46
diff -u -p -r1.46 ieee80211_proto.c
--- ieee80211_proto.c 18 Jan 2012 14:35:56 -0000 1.46
+++ ieee80211_proto.c 28 Sep 2012 13:35:53 -0000
@@ -721,7 +721,8 @@ ieee80211_auth_open(struct ieee80211com
ether_sprintf((u_int8_t *)ni->ni_macaddr),
ni->ni_state != IEEE80211_STA_CACHE ?
"newly" : "already");
- ieee80211_node_newstate(ni, IEEE80211_STA_AUTH);
+ if (ni->ni_state != IEEE80211_STA_ASSOC)
+ ieee80211_node_newstate(ni, IEEE80211_STA_AUTH);
break;
#endif /* IEEE80211_STA_ONLY */
Nathanael