aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/rx.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-08-06 12:38:14 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2014-08-06 12:38:14 -0400
commitae045e2455429c418a418a3376301a9e5753a0a8 (patch)
treeb445bdeecd3f38aa0d0a29c9585cee49e4ccb0f1 /net/mac80211/rx.c
parentf4f142ed4ef835709c7e6d12eaca10d190bcebed (diff)
parentd247b6ab3ce6dd43665780865ec5fa145d9ab6bd (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next
Pull networking updates from David Miller: "Highlights: 1) Steady transitioning of the BPF instructure to a generic spot so all kernel subsystems can make use of it, from Alexei Starovoitov. 2) SFC driver supports busy polling, from Alexandre Rames. 3) Take advantage of hash table in UDP multicast delivery, from David Held. 4) Lighten locking, in particular by getting rid of the LRU lists, in inet frag handling. From Florian Westphal. 5) Add support for various RFC6458 control messages in SCTP, from Geir Ola Vaagland. 6) Allow to filter bridge forwarding database dumps by device, from Jamal Hadi Salim. 7) virtio-net also now supports busy polling, from Jason Wang. 8) Some low level optimization tweaks in pktgen from Jesper Dangaard Brouer. 9) Add support for ipv6 address generation modes, so that userland can have some input into the process. From Jiri Pirko. 10) Consolidate common TCP connection request code in ipv4 and ipv6, from Octavian Purdila. 11) New ARP packet logger in netfilter, from Pablo Neira Ayuso. 12) Generic resizable RCU hash table, with intial users in netlink and nftables. From Thomas Graf. 13) Maintain a name assignment type so that userspace can see where a network device name came from (enumerated by kernel, assigned explicitly by userspace, etc.) From Tom Gundersen. 14) Automatic flow label generation on transmit in ipv6, from Tom Herbert. 15) New packet timestamping facilities from Willem de Bruijn, meant to assist in measuring latencies going into/out-of the packet scheduler, latency from TCP data transmission to ACK, etc" * git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next: (1536 commits) cxgb4 : Disable recursive mailbox commands when enabling vi net: reduce USB network driver config options. tg3: Modify tg3_tso_bug() to handle multiple TX rings amd-xgbe: Perform phy connect/disconnect at dev open/stop amd-xgbe: Use dma_set_mask_and_coherent to set DMA mask net: sun4i-emac: fix memory leak on bad packet sctp: fix possible seqlock seadlock in sctp_packet_transmit() Revert "net: phy: Set the driver when registering an MDIO bus device" cxgb4vf: Turn off SGE RX/TX Callback Timers and interrupts in PCI shutdown routine team: Simplify return path of team_newlink bridge: Update outdated comment on promiscuous mode net-timestamp: ACK timestamp for bytestreams net-timestamp: TCP timestamping net-timestamp: SCHED timestamp on entering packet scheduler net-timestamp: add key to disambiguate concurrent datagrams net-timestamp: move timestamp flags out of sk_flags net-timestamp: extend SCM_TIMESTAMPING ancillary data struct cxgb4i : Move stray CPL definitions to cxgb4 driver tcp: reduce spurious retransmits due to transient SACK reneging qlcnic: Initialize dcbnl_ops before register_netdev ...
Diffstat (limited to 'net/mac80211/rx.c')
-rw-r--r--net/mac80211/rx.c67
1 files changed, 48 insertions, 19 deletions
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 394e201cde6d..bd2c9b22c945 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -688,20 +688,27 @@ static void ieee80211_release_reorder_frame(struct ieee80211_sub_if_data *sdata,
688 int index, 688 int index,
689 struct sk_buff_head *frames) 689 struct sk_buff_head *frames)
690{ 690{
691 struct sk_buff *skb = tid_agg_rx->reorder_buf[index]; 691 struct sk_buff_head *skb_list = &tid_agg_rx->reorder_buf[index];
692 struct sk_buff *skb;
692 struct ieee80211_rx_status *status; 693 struct ieee80211_rx_status *status;
693 694
694 lockdep_assert_held(&tid_agg_rx->reorder_lock); 695 lockdep_assert_held(&tid_agg_rx->reorder_lock);
695 696
696 if (!skb) 697 if (skb_queue_empty(skb_list))
698 goto no_frame;
699
700 if (!ieee80211_rx_reorder_ready(skb_list)) {
701 __skb_queue_purge(skb_list);
697 goto no_frame; 702 goto no_frame;
703 }
698 704
699 /* release the frame from the reorder ring buffer */ 705 /* release frames from the reorder ring buffer */
700 tid_agg_rx->stored_mpdu_num--; 706 tid_agg_rx->stored_mpdu_num--;
701 tid_agg_rx->reorder_buf[index] = NULL; 707 while ((skb = __skb_dequeue(skb_list))) {
702 status = IEEE80211_SKB_RXCB(skb); 708 status = IEEE80211_SKB_RXCB(skb);
703 status->rx_flags |= IEEE80211_RX_DEFERRED_RELEASE; 709 status->rx_flags |= IEEE80211_RX_DEFERRED_RELEASE;
704 __skb_queue_tail(frames, skb); 710 __skb_queue_tail(frames, skb);
711 }
705 712
706no_frame: 713no_frame:
707 tid_agg_rx->head_seq_num = ieee80211_sn_inc(tid_agg_rx->head_seq_num); 714 tid_agg_rx->head_seq_num = ieee80211_sn_inc(tid_agg_rx->head_seq_num);
@@ -738,13 +745,13 @@ static void ieee80211_sta_reorder_release(struct ieee80211_sub_if_data *sdata,
738 struct tid_ampdu_rx *tid_agg_rx, 745 struct tid_ampdu_rx *tid_agg_rx,
739 struct sk_buff_head *frames) 746 struct sk_buff_head *frames)
740{ 747{
741 int index, j; 748 int index, i, j;
742 749
743 lockdep_assert_held(&tid_agg_rx->reorder_lock); 750 lockdep_assert_held(&tid_agg_rx->reorder_lock);
744 751
745 /* release the buffer until next missing frame */ 752 /* release the buffer until next missing frame */
746 index = tid_agg_rx->head_seq_num % tid_agg_rx->buf_size; 753 index = tid_agg_rx->head_seq_num % tid_agg_rx->buf_size;
747 if (!tid_agg_rx->reorder_buf[index] && 754 if (!ieee80211_rx_reorder_ready(&tid_agg_rx->reorder_buf[index]) &&
748 tid_agg_rx->stored_mpdu_num) { 755 tid_agg_rx->stored_mpdu_num) {
749 /* 756 /*
750 * No buffers ready to be released, but check whether any 757 * No buffers ready to be released, but check whether any
@@ -753,7 +760,8 @@ static void ieee80211_sta_reorder_release(struct ieee80211_sub_if_data *sdata,
753 int skipped = 1; 760 int skipped = 1;
754 for (j = (index + 1) % tid_agg_rx->buf_size; j != index; 761 for (j = (index + 1) % tid_agg_rx->buf_size; j != index;
755 j = (j + 1) % tid_agg_rx->buf_size) { 762 j = (j + 1) % tid_agg_rx->buf_size) {
756 if (!tid_agg_rx->reorder_buf[j]) { 763 if (!ieee80211_rx_reorder_ready(
764 &tid_agg_rx->reorder_buf[j])) {
757 skipped++; 765 skipped++;
758 continue; 766 continue;
759 } 767 }
@@ -762,6 +770,11 @@ static void ieee80211_sta_reorder_release(struct ieee80211_sub_if_data *sdata,
762 HT_RX_REORDER_BUF_TIMEOUT)) 770 HT_RX_REORDER_BUF_TIMEOUT))
763 goto set_release_timer; 771 goto set_release_timer;
764 772
773 /* don't leave incomplete A-MSDUs around */
774 for (i = (index + 1) % tid_agg_rx->buf_size; i != j;
775 i = (i + 1) % tid_agg_rx->buf_size)
776 __skb_queue_purge(&tid_agg_rx->reorder_buf[i]);
777
765 ht_dbg_ratelimited(sdata, 778 ht_dbg_ratelimited(sdata,
766 "release an RX reorder frame due to timeout on earlier frames\n"); 779 "release an RX reorder frame due to timeout on earlier frames\n");
767 ieee80211_release_reorder_frame(sdata, tid_agg_rx, j, 780 ieee80211_release_reorder_frame(sdata, tid_agg_rx, j,
@@ -775,7 +788,8 @@ static void ieee80211_sta_reorder_release(struct ieee80211_sub_if_data *sdata,
775 skipped) & IEEE80211_SN_MASK; 788 skipped) & IEEE80211_SN_MASK;
776 skipped = 0; 789 skipped = 0;
777 } 790 }
778 } else while (tid_agg_rx->reorder_buf[index]) { 791 } else while (ieee80211_rx_reorder_ready(
792 &tid_agg_rx->reorder_buf[index])) {
779 ieee80211_release_reorder_frame(sdata, tid_agg_rx, index, 793 ieee80211_release_reorder_frame(sdata, tid_agg_rx, index,
780 frames); 794 frames);
781 index = tid_agg_rx->head_seq_num % tid_agg_rx->buf_size; 795 index = tid_agg_rx->head_seq_num % tid_agg_rx->buf_size;
@@ -786,7 +800,8 @@ static void ieee80211_sta_reorder_release(struct ieee80211_sub_if_data *sdata,
786 800
787 for (; j != (index - 1) % tid_agg_rx->buf_size; 801 for (; j != (index - 1) % tid_agg_rx->buf_size;
788 j = (j + 1) % tid_agg_rx->buf_size) { 802 j = (j + 1) % tid_agg_rx->buf_size) {
789 if (tid_agg_rx->reorder_buf[j]) 803 if (ieee80211_rx_reorder_ready(
804 &tid_agg_rx->reorder_buf[j]))
790 break; 805 break;
791 } 806 }
792 807
@@ -811,6 +826,7 @@ static bool ieee80211_sta_manage_reorder_buf(struct ieee80211_sub_if_data *sdata
811 struct sk_buff_head *frames) 826 struct sk_buff_head *frames)
812{ 827{
813 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; 828 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
829 struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
814 u16 sc = le16_to_cpu(hdr->seq_ctrl); 830 u16 sc = le16_to_cpu(hdr->seq_ctrl);
815 u16 mpdu_seq_num = (sc & IEEE80211_SCTL_SEQ) >> 4; 831 u16 mpdu_seq_num = (sc & IEEE80211_SCTL_SEQ) >> 4;
816 u16 head_seq_num, buf_size; 832 u16 head_seq_num, buf_size;
@@ -845,7 +861,7 @@ static bool ieee80211_sta_manage_reorder_buf(struct ieee80211_sub_if_data *sdata
845 index = mpdu_seq_num % tid_agg_rx->buf_size; 861 index = mpdu_seq_num % tid_agg_rx->buf_size;
846 862
847 /* check if we already stored this frame */ 863 /* check if we already stored this frame */
848 if (tid_agg_rx->reorder_buf[index]) { 864 if (ieee80211_rx_reorder_ready(&tid_agg_rx->reorder_buf[index])) {
849 dev_kfree_skb(skb); 865 dev_kfree_skb(skb);
850 goto out; 866 goto out;
851 } 867 }
@@ -858,17 +874,20 @@ static bool ieee80211_sta_manage_reorder_buf(struct ieee80211_sub_if_data *sdata
858 */ 874 */
859 if (mpdu_seq_num == tid_agg_rx->head_seq_num && 875 if (mpdu_seq_num == tid_agg_rx->head_seq_num &&
860 tid_agg_rx->stored_mpdu_num == 0) { 876 tid_agg_rx->stored_mpdu_num == 0) {
861 tid_agg_rx->head_seq_num = 877 if (!(status->flag & RX_FLAG_AMSDU_MORE))
862 ieee80211_sn_inc(tid_agg_rx->head_seq_num); 878 tid_agg_rx->head_seq_num =
879 ieee80211_sn_inc(tid_agg_rx->head_seq_num);
863 ret = false; 880 ret = false;
864 goto out; 881 goto out;
865 } 882 }
866 883
867 /* put the frame in the reordering buffer */ 884 /* put the frame in the reordering buffer */
868 tid_agg_rx->reorder_buf[index] = skb; 885 __skb_queue_tail(&tid_agg_rx->reorder_buf[index], skb);
869 tid_agg_rx->reorder_time[index] = jiffies; 886 if (!(status->flag & RX_FLAG_AMSDU_MORE)) {
870 tid_agg_rx->stored_mpdu_num++; 887 tid_agg_rx->reorder_time[index] = jiffies;
871 ieee80211_sta_reorder_release(sdata, tid_agg_rx, frames); 888 tid_agg_rx->stored_mpdu_num++;
889 ieee80211_sta_reorder_release(sdata, tid_agg_rx, frames);
890 }
872 891
873 out: 892 out:
874 spin_unlock(&tid_agg_rx->reorder_lock); 893 spin_unlock(&tid_agg_rx->reorder_lock);
@@ -1107,6 +1126,8 @@ static void sta_ps_end(struct sta_info *sta)
1107 return; 1126 return;
1108 } 1127 }
1109 1128
1129 set_sta_flag(sta, WLAN_STA_PS_DELIVER);
1130 clear_sta_flag(sta, WLAN_STA_PS_STA);
1110 ieee80211_sta_ps_deliver_wakeup(sta); 1131 ieee80211_sta_ps_deliver_wakeup(sta);
1111} 1132}
1112 1133
@@ -3127,6 +3148,14 @@ static bool prepare_for_handlers(struct ieee80211_rx_data *rx,
3127 if (!ieee80211_is_beacon(hdr->frame_control)) 3148 if (!ieee80211_is_beacon(hdr->frame_control))
3128 return false; 3149 return false;
3129 status->rx_flags &= ~IEEE80211_RX_RA_MATCH; 3150 status->rx_flags &= ~IEEE80211_RX_RA_MATCH;
3151 } else if (!ieee80211_has_tods(hdr->frame_control)) {
3152 /* ignore data frames to TDLS-peers */
3153 if (ieee80211_is_data(hdr->frame_control))
3154 return false;
3155 /* ignore action frames to TDLS-peers */
3156 if (ieee80211_is_action(hdr->frame_control) &&
3157 !ether_addr_equal(bssid, hdr->addr1))
3158 return false;
3130 } 3159 }
3131 break; 3160 break;
3132 case NL80211_IFTYPE_WDS: 3161 case NL80211_IFTYPE_WDS: