aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorIgor Perminov <igor.perminov@inbox.ru>2009-08-04 08:48:51 -0400
committerJohn W. Linville <linville@tuxdriver.com>2009-08-04 16:44:35 -0400
commite3b90ca28412fb9dcc8c5ca38e179e78fec07eee (patch)
treefa17113d9d7c96edc076b3f46558e8c3fb78d673 /net
parente48e3a2f17f189deb086ff221e489e7fd8ec4302 (diff)
mac80211: FIF_PSPOLL filter flag
When an interface is configured in the AP mode, the mac80211 implementation doesn't inform the driver to receive PS Poll frames. It leads to inability to communicate with power-saving stations reliably. The FIF_CONTROL flag isn't passed by mac80211 to ieee80211_ops.configure_filter when an interface is in the AP mode. And it's ok, because we don't want to receive ACK frames and other control ones, but only PS Poll ones. This patch introduces the FIF_PSPOLL filter flag in addition to FIF_CONTROL, which means for the driver "pass PS Poll frames". This flag is passed to the driver: A) When an interface is configured in the AP mode. B) In all cases, when the FIF_CONTROL flag was passed earlier (in addition to it). Signed-off-by: Igor Perminov <igor.perminov@inbox.ru> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net')
-rw-r--r--net/mac80211/ieee80211_i.h2
-rw-r--r--net/mac80211/iface.c18
-rw-r--r--net/mac80211/main.c3
3 files changed, 20 insertions, 3 deletions
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 8d790e40f3e9..630a438180fd 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -628,7 +628,7 @@ struct ieee80211_local {
628 int open_count; 628 int open_count;
629 int monitors, cooked_mntrs; 629 int monitors, cooked_mntrs;
630 /* number of interfaces with corresponding FIF_ flags */ 630 /* number of interfaces with corresponding FIF_ flags */
631 int fif_fcsfail, fif_plcpfail, fif_control, fif_other_bss; 631 int fif_fcsfail, fif_plcpfail, fif_control, fif_other_bss, fif_pspoll;
632 unsigned int filter_flags; /* FIF_* */ 632 unsigned int filter_flags; /* FIF_* */
633 struct iw_statistics wstats; 633 struct iw_statistics wstats;
634 634
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index 8c1284d45e69..e8fb03b91a44 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -220,8 +220,10 @@ static int ieee80211_open(struct net_device *dev)
220 local->fif_fcsfail++; 220 local->fif_fcsfail++;
221 if (sdata->u.mntr_flags & MONITOR_FLAG_PLCPFAIL) 221 if (sdata->u.mntr_flags & MONITOR_FLAG_PLCPFAIL)
222 local->fif_plcpfail++; 222 local->fif_plcpfail++;
223 if (sdata->u.mntr_flags & MONITOR_FLAG_CONTROL) 223 if (sdata->u.mntr_flags & MONITOR_FLAG_CONTROL) {
224 local->fif_control++; 224 local->fif_control++;
225 local->fif_pspoll++;
226 }
225 if (sdata->u.mntr_flags & MONITOR_FLAG_OTHER_BSS) 227 if (sdata->u.mntr_flags & MONITOR_FLAG_OTHER_BSS)
226 local->fif_other_bss++; 228 local->fif_other_bss++;
227 229
@@ -244,7 +246,14 @@ static int ieee80211_open(struct net_device *dev)
244 spin_unlock_bh(&local->filter_lock); 246 spin_unlock_bh(&local->filter_lock);
245 247
246 ieee80211_start_mesh(sdata); 248 ieee80211_start_mesh(sdata);
249 } else if (sdata->vif.type == NL80211_IFTYPE_AP) {
250 local->fif_pspoll++;
251
252 spin_lock_bh(&local->filter_lock);
253 ieee80211_configure_filter(local);
254 spin_unlock_bh(&local->filter_lock);
247 } 255 }
256
248 changed |= ieee80211_reset_erp_info(sdata); 257 changed |= ieee80211_reset_erp_info(sdata);
249 ieee80211_bss_info_change_notify(sdata, changed); 258 ieee80211_bss_info_change_notify(sdata, changed);
250 ieee80211_enable_keys(sdata); 259 ieee80211_enable_keys(sdata);
@@ -388,6 +397,9 @@ static int ieee80211_stop(struct net_device *dev)
388 if (sdata->flags & IEEE80211_SDATA_PROMISC) 397 if (sdata->flags & IEEE80211_SDATA_PROMISC)
389 atomic_dec(&local->iff_promiscs); 398 atomic_dec(&local->iff_promiscs);
390 399
400 if (sdata->vif.type == NL80211_IFTYPE_AP)
401 local->fif_pspoll--;
402
391 netif_addr_lock_bh(dev); 403 netif_addr_lock_bh(dev);
392 spin_lock_bh(&local->filter_lock); 404 spin_lock_bh(&local->filter_lock);
393 __dev_addr_unsync(&local->mc_list, &local->mc_count, 405 __dev_addr_unsync(&local->mc_list, &local->mc_count,
@@ -439,8 +451,10 @@ static int ieee80211_stop(struct net_device *dev)
439 local->fif_fcsfail--; 451 local->fif_fcsfail--;
440 if (sdata->u.mntr_flags & MONITOR_FLAG_PLCPFAIL) 452 if (sdata->u.mntr_flags & MONITOR_FLAG_PLCPFAIL)
441 local->fif_plcpfail--; 453 local->fif_plcpfail--;
442 if (sdata->u.mntr_flags & MONITOR_FLAG_CONTROL) 454 if (sdata->u.mntr_flags & MONITOR_FLAG_CONTROL) {
455 local->fif_pspoll--;
443 local->fif_control--; 456 local->fif_control--;
457 }
444 if (sdata->u.mntr_flags & MONITOR_FLAG_OTHER_BSS) 458 if (sdata->u.mntr_flags & MONITOR_FLAG_OTHER_BSS)
445 local->fif_other_bss--; 459 local->fif_other_bss--;
446 460
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index 22e07385ff60..0c4f8e122ed6 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -77,6 +77,9 @@ void ieee80211_configure_filter(struct ieee80211_local *local)
77 if (local->fif_other_bss) 77 if (local->fif_other_bss)
78 new_flags |= FIF_OTHER_BSS; 78 new_flags |= FIF_OTHER_BSS;
79 79
80 if (local->fif_pspoll)
81 new_flags |= FIF_PSPOLL;
82
80 changed_flags = local->filter_flags ^ new_flags; 83 changed_flags = local->filter_flags ^ new_flags;
81 84
82 /* be a bit nasty */ 85 /* be a bit nasty */