diff options
Diffstat (limited to 'net/mac80211/rx.c')
-rw-r--r-- | net/mac80211/rx.c | 59 |
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 | ||
653 | static void ap_sta_ps_start(struct net_device *dev, struct sta_info *sta) | 653 | static 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 | ||
668 | static int ap_sta_ps_end(struct net_device *dev, struct sta_info *sta) | 666 | static 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 | |||
715 | ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx) | 711 | ieee80211_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: |