aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKalle Valo <kalle.valo@nokia.com>2009-02-10 10:09:24 -0500
committerJohn W. Linville <linville@tuxdriver.com>2009-02-13 13:45:15 -0500
commit1fb3606bc5864c64c78ce4e1751e5382a9a5aa84 (patch)
tree466cf1d2f488cfc9172ce24d83c11a0323fd6192
parentf733ded107ff15022e3f0f8204f11ab2e83a2aa4 (diff)
mac80211: remove multicast check from check_tim()
Currently mac80211 checks for the multicast tim bit from beacons, disables power save and sends a null frame if the bit is set. This was added to support ath9k. But this is a bit controversial because the AP will send multicast frames immediately after the beacon and the time constraints are really high. Relying mac80211 to be fast enough here might not be reliable in all situations. And there's no need to send a null frame, AP will send the frames immediately after the dtim beacon no matter what. Also if dynamic power save is disabled (iwconfig wlan0 power timeout 0) currently mac80211 disables power save whenever the multicast bit is set but it's never enabled again after receiving the first multicast/broadcast frame. The current implementation is not usable on p54/stlc45xx and the easiest way to fix this is to remove the multicast tim bit check altogether. Handling multicast tim bit in host is rare, most of the designs do this in firmware/hardware, so it's better not to have it in mac80211. It's a lot better to do this in firmware/hardware, or if that's not possible it could be done in the driver. Also renamed the function to ieee80211_check_tim() to follow the style of the file. Signed-off-by: Kalle Valo <kalle.valo@nokia.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r--net/mac80211/mlme.c11
1 files changed, 4 insertions, 7 deletions
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 91c9a5a5746d..05c8d13d39b6 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -611,7 +611,7 @@ static void ieee80211_sta_wmm_params(struct ieee80211_local *local,
611 } 611 }
612} 612}
613 613
614static bool check_tim(struct ieee802_11_elems *elems, u16 aid, bool *is_mc) 614static bool ieee80211_check_tim(struct ieee802_11_elems *elems, u16 aid)
615{ 615{
616 u8 mask; 616 u8 mask;
617 u8 index, indexn1, indexn2; 617 u8 index, indexn1, indexn2;
@@ -621,9 +621,6 @@ static bool check_tim(struct ieee802_11_elems *elems, u16 aid, bool *is_mc)
621 index = aid / 8; 621 index = aid / 8;
622 mask = 1 << (aid & 7); 622 mask = 1 << (aid & 7);
623 623
624 if (tim->bitmap_ctrl & 0x01)
625 *is_mc = true;
626
627 indexn1 = tim->bitmap_ctrl & 0xfe; 624 indexn1 = tim->bitmap_ctrl & 0xfe;
628 indexn2 = elems->tim_len + indexn1 - 4; 625 indexn2 = elems->tim_len + indexn1 - 4;
629 626
@@ -1840,7 +1837,7 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
1840 struct ieee802_11_elems elems; 1837 struct ieee802_11_elems elems;
1841 struct ieee80211_local *local = sdata->local; 1838 struct ieee80211_local *local = sdata->local;
1842 u32 changed = 0; 1839 u32 changed = 0;
1843 bool erp_valid, directed_tim, is_mc = false; 1840 bool erp_valid, directed_tim;
1844 u8 erp_value = 0; 1841 u8 erp_value = 0;
1845 1842
1846 /* Process beacon from the current BSS */ 1843 /* Process beacon from the current BSS */
@@ -1868,9 +1865,9 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
1868 1865
1869 if (local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK && 1866 if (local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK &&
1870 local->hw.conf.flags & IEEE80211_CONF_PS) { 1867 local->hw.conf.flags & IEEE80211_CONF_PS) {
1871 directed_tim = check_tim(&elems, ifsta->aid, &is_mc); 1868 directed_tim = ieee80211_check_tim(&elems, ifsta->aid);
1872 1869
1873 if (directed_tim || is_mc) { 1870 if (directed_tim) {
1874 local->hw.conf.flags &= ~IEEE80211_CONF_PS; 1871 local->hw.conf.flags &= ~IEEE80211_CONF_PS;
1875 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS); 1872 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS);
1876 ieee80211_send_nullfunc(local, sdata, 0); 1873 ieee80211_send_nullfunc(local, sdata, 0);