aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/rx.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/mac80211/rx.c')
-rw-r--r--net/mac80211/rx.c59
1 files changed, 39 insertions, 20 deletions
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 92d898b901e9..c489865761bc 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -650,32 +650,28 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx)
650 return result; 650 return result;
651} 651}
652 652
653static void ap_sta_ps_start(struct net_device *dev, struct sta_info *sta) 653static void ap_sta_ps_start(struct sta_info *sta)
654{ 654{
655 struct ieee80211_sub_if_data *sdata; 655 struct ieee80211_sub_if_data *sdata = sta->sdata;
656 DECLARE_MAC_BUF(mac); 656 DECLARE_MAC_BUF(mac);
657 657
658 sdata = sta->sdata;
659
660 atomic_inc(&sdata->bss->num_sta_ps); 658 atomic_inc(&sdata->bss->num_sta_ps);
661 set_and_clear_sta_flags(sta, WLAN_STA_PS, WLAN_STA_PSPOLL); 659 set_and_clear_sta_flags(sta, WLAN_STA_PS, WLAN_STA_PSPOLL);
662#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG 660#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG
663 printk(KERN_DEBUG "%s: STA %s aid %d enters power save mode\n", 661 printk(KERN_DEBUG "%s: STA %s aid %d enters power save mode\n",
664 dev->name, print_mac(mac, sta->sta.addr), sta->sta.aid); 662 sdata->dev->name, print_mac(mac, sta->sta.addr), sta->sta.aid);
665#endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ 663#endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */
666} 664}
667 665
668static int ap_sta_ps_end(struct net_device *dev, struct sta_info *sta) 666static int ap_sta_ps_end(struct sta_info *sta)
669{ 667{
670 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 668 struct ieee80211_sub_if_data *sdata = sta->sdata;
669 struct ieee80211_local *local = sdata->local;
671 struct sk_buff *skb; 670 struct sk_buff *skb;
672 int sent = 0; 671 int sent = 0;
673 struct ieee80211_sub_if_data *sdata;
674 struct ieee80211_tx_info *info; 672 struct ieee80211_tx_info *info;
675 DECLARE_MAC_BUF(mac); 673 DECLARE_MAC_BUF(mac);
676 674
677 sdata = sta->sdata;
678
679 atomic_dec(&sdata->bss->num_sta_ps); 675 atomic_dec(&sdata->bss->num_sta_ps);
680 676
681 clear_sta_flags(sta, WLAN_STA_PS | WLAN_STA_PSPOLL); 677 clear_sta_flags(sta, WLAN_STA_PS | WLAN_STA_PSPOLL);
@@ -685,7 +681,7 @@ static int ap_sta_ps_end(struct net_device *dev, struct sta_info *sta)
685 681
686#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG 682#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG
687 printk(KERN_DEBUG "%s: STA %s aid %d exits power save mode\n", 683 printk(KERN_DEBUG "%s: STA %s aid %d exits power save mode\n",
688 dev->name, print_mac(mac, sta->sta.addr), sta->sta.aid); 684 sdata->dev->name, print_mac(mac, sta->sta.addr), sta->sta.aid);
689#endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ 685#endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */
690 686
691 /* Send all buffered frames to the station */ 687 /* Send all buffered frames to the station */
@@ -701,7 +697,7 @@ static int ap_sta_ps_end(struct net_device *dev, struct sta_info *sta)
701 sent++; 697 sent++;
702#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG 698#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG
703 printk(KERN_DEBUG "%s: STA %s aid %d send PS frame " 699 printk(KERN_DEBUG "%s: STA %s aid %d send PS frame "
704 "since STA not sleeping anymore\n", dev->name, 700 "since STA not sleeping anymore\n", sdata->dev->name,
705 print_mac(mac, sta->sta.addr), sta->sta.aid); 701 print_mac(mac, sta->sta.addr), sta->sta.aid);
706#endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ 702#endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */
707 info->flags |= IEEE80211_TX_CTL_REQUEUE; 703 info->flags |= IEEE80211_TX_CTL_REQUEUE;
@@ -715,7 +711,6 @@ static ieee80211_rx_result debug_noinline
715ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx) 711ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx)
716{ 712{
717 struct sta_info *sta = rx->sta; 713 struct sta_info *sta = rx->sta;
718 struct net_device *dev = rx->dev;
719 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data; 714 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data;
720 715
721 if (!sta) 716 if (!sta)
@@ -757,10 +752,10 @@ ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx)
757 * exchange sequence */ 752 * exchange sequence */
758 if (test_sta_flags(sta, WLAN_STA_PS) && 753 if (test_sta_flags(sta, WLAN_STA_PS) &&
759 !ieee80211_has_pm(hdr->frame_control)) 754 !ieee80211_has_pm(hdr->frame_control))
760 rx->sent_ps_buffered += ap_sta_ps_end(dev, sta); 755 rx->sent_ps_buffered += ap_sta_ps_end(sta);
761 else if (!test_sta_flags(sta, WLAN_STA_PS) && 756 else if (!test_sta_flags(sta, WLAN_STA_PS) &&
762 ieee80211_has_pm(hdr->frame_control)) 757 ieee80211_has_pm(hdr->frame_control))
763 ap_sta_ps_start(dev, sta); 758 ap_sta_ps_start(sta);
764 } 759 }
765 760
766 /* Drop data::nullfunc frames silently, since they are used only to 761 /* Drop data::nullfunc frames silently, since they are used only to
@@ -1112,10 +1107,6 @@ ieee80211_data_to_8023(struct ieee80211_rx_data *rx)
1112 1107
1113 hdrlen = ieee80211_hdrlen(hdr->frame_control); 1108 hdrlen = ieee80211_hdrlen(hdr->frame_control);
1114 1109
1115 if (ieee80211_vif_is_mesh(&sdata->vif))
1116 hdrlen += ieee80211_get_mesh_hdrlen(
1117 (struct ieee80211s_hdr *) (skb->data + hdrlen));
1118
1119 /* convert IEEE 802.11 header + possible LLC headers into Ethernet 1110 /* convert IEEE 802.11 header + possible LLC headers into Ethernet
1120 * header 1111 * header
1121 * IEEE 802.11 address fields: 1112 * IEEE 802.11 address fields:
@@ -1139,6 +1130,15 @@ ieee80211_data_to_8023(struct ieee80211_rx_data *rx)
1139 if (unlikely(sdata->vif.type != NL80211_IFTYPE_WDS && 1130 if (unlikely(sdata->vif.type != NL80211_IFTYPE_WDS &&
1140 sdata->vif.type != NL80211_IFTYPE_MESH_POINT)) 1131 sdata->vif.type != NL80211_IFTYPE_MESH_POINT))
1141 return -1; 1132 return -1;
1133 if (ieee80211_vif_is_mesh(&sdata->vif)) {
1134 struct ieee80211s_hdr *meshdr = (struct ieee80211s_hdr *)
1135 (skb->data + hdrlen);
1136 hdrlen += ieee80211_get_mesh_hdrlen(meshdr);
1137 if (meshdr->flags & MESH_FLAGS_AE_A5_A6) {
1138 memcpy(dst, meshdr->eaddr1, ETH_ALEN);
1139 memcpy(src, meshdr->eaddr2, ETH_ALEN);
1140 }
1141 }
1142 break; 1142 break;
1143 case __constant_cpu_to_le16(IEEE80211_FCTL_FROMDS): 1143 case __constant_cpu_to_le16(IEEE80211_FCTL_FROMDS):
1144 if (sdata->vif.type != NL80211_IFTYPE_STATION || 1144 if (sdata->vif.type != NL80211_IFTYPE_STATION ||
@@ -1398,6 +1398,25 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx)
1398 /* illegal frame */ 1398 /* illegal frame */
1399 return RX_DROP_MONITOR; 1399 return RX_DROP_MONITOR;
1400 1400
1401 if (mesh_hdr->flags & MESH_FLAGS_AE_A5_A6){
1402 struct ieee80211_sub_if_data *sdata;
1403 struct mesh_path *mppath;
1404
1405 sdata = IEEE80211_DEV_TO_SUB_IF(rx->dev);
1406 rcu_read_lock();
1407 mppath = mpp_path_lookup(mesh_hdr->eaddr2, sdata);
1408 if (!mppath) {
1409 mpp_path_add(mesh_hdr->eaddr2, hdr->addr4, sdata);
1410 } else {
1411 spin_lock_bh(&mppath->state_lock);
1412 mppath->exp_time = jiffies;
1413 if (compare_ether_addr(mppath->mpp, hdr->addr4) != 0)
1414 memcpy(mppath->mpp, hdr->addr4, ETH_ALEN);
1415 spin_unlock_bh(&mppath->state_lock);
1416 }
1417 rcu_read_unlock();
1418 }
1419
1401 if (compare_ether_addr(rx->dev->dev_addr, hdr->addr3) == 0) 1420 if (compare_ether_addr(rx->dev->dev_addr, hdr->addr3) == 0)
1402 return RX_CONTINUE; 1421 return RX_CONTINUE;
1403 1422
@@ -1538,7 +1557,7 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx)
1538 */ 1557 */
1539 if (sdata->vif.type != NL80211_IFTYPE_STATION && 1558 if (sdata->vif.type != NL80211_IFTYPE_STATION &&
1540 sdata->vif.type != NL80211_IFTYPE_ADHOC) 1559 sdata->vif.type != NL80211_IFTYPE_ADHOC)
1541 return RX_DROP_MONITOR; 1560 return RX_CONTINUE;
1542 1561
1543 switch (mgmt->u.action.category) { 1562 switch (mgmt->u.action.category) {
1544 case WLAN_CATEGORY_BACK: 1563 case WLAN_CATEGORY_BACK: