aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/mlme.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/mac80211/mlme.c')
-rw-r--r--net/mac80211/mlme.c54
1 files changed, 51 insertions, 3 deletions
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 05c8d13d39b6..169f10c51042 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -511,6 +511,39 @@ static void ieee80211_send_deauth_disassoc(struct ieee80211_sub_if_data *sdata,
511 ieee80211_tx_skb(sdata, skb, ifsta->flags & IEEE80211_STA_MFP_ENABLED); 511 ieee80211_tx_skb(sdata, skb, ifsta->flags & IEEE80211_STA_MFP_ENABLED);
512} 512}
513 513
514void ieee80211_send_pspoll(struct ieee80211_local *local,
515 struct ieee80211_sub_if_data *sdata)
516{
517 struct ieee80211_if_sta *ifsta = &sdata->u.sta;
518 struct ieee80211_pspoll *pspoll;
519 struct sk_buff *skb;
520 u16 fc;
521
522 skb = dev_alloc_skb(local->hw.extra_tx_headroom + sizeof(*pspoll));
523 if (!skb) {
524 printk(KERN_DEBUG "%s: failed to allocate buffer for "
525 "pspoll frame\n", sdata->dev->name);
526 return;
527 }
528 skb_reserve(skb, local->hw.extra_tx_headroom);
529
530 pspoll = (struct ieee80211_pspoll *) skb_put(skb, sizeof(*pspoll));
531 memset(pspoll, 0, sizeof(*pspoll));
532 fc = IEEE80211_FTYPE_CTL | IEEE80211_STYPE_PSPOLL | IEEE80211_FCTL_PM;
533 pspoll->frame_control = cpu_to_le16(fc);
534 pspoll->aid = cpu_to_le16(ifsta->aid);
535
536 /* aid in PS-Poll has its two MSBs each set to 1 */
537 pspoll->aid |= cpu_to_le16(1 << 15 | 1 << 14);
538
539 memcpy(pspoll->bssid, ifsta->bssid, ETH_ALEN);
540 memcpy(pspoll->ta, sdata->dev->dev_addr, ETH_ALEN);
541
542 ieee80211_tx_skb(sdata, skb, 0);
543
544 return;
545}
546
514/* MLME */ 547/* MLME */
515static void ieee80211_sta_def_wmm_params(struct ieee80211_sub_if_data *sdata, 548static void ieee80211_sta_def_wmm_params(struct ieee80211_sub_if_data *sdata,
516 struct ieee80211_bss *bss) 549 struct ieee80211_bss *bss)
@@ -1868,9 +1901,24 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
1868 directed_tim = ieee80211_check_tim(&elems, ifsta->aid); 1901 directed_tim = ieee80211_check_tim(&elems, ifsta->aid);
1869 1902
1870 if (directed_tim) { 1903 if (directed_tim) {
1871 local->hw.conf.flags &= ~IEEE80211_CONF_PS; 1904 if (local->hw.conf.dynamic_ps_timeout > 0) {
1872 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS); 1905 local->hw.conf.flags &= ~IEEE80211_CONF_PS;
1873 ieee80211_send_nullfunc(local, sdata, 0); 1906 ieee80211_hw_config(local,
1907 IEEE80211_CONF_CHANGE_PS);
1908 ieee80211_send_nullfunc(local, sdata, 0);
1909 } else {
1910 local->pspolling = true;
1911
1912 /*
1913 * Here is assumed that the driver will be
1914 * able to send ps-poll frame and receive a
1915 * response even though power save mode is
1916 * enabled, but some drivers might require
1917 * to disable power save here. This needs
1918 * to be investigated.
1919 */
1920 ieee80211_send_pspoll(local, sdata);
1921 }
1874 } 1922 }
1875 } 1923 }
1876 1924