diff options
author | Johannes Berg <johannes.berg@intel.com> | 2010-06-10 04:21:34 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2010-06-14 15:39:26 -0400 |
commit | 77a121c3a88eb00a4b5e753d083dbb7d49fefb0a (patch) | |
tree | d1c802c9133a149094b484cd4796faeb9d7201fb /net/mac80211/rx.c | |
parent | 36b3a628a4e85d002ee8813ebd2a5caef6d3c1a7 (diff) |
mac80211: pull mgmt frame rx into rx handler
Some code is duplicated between ibss, mesh and
managed mode regarding the queueing of management
frames. Since all modes now use a common skb
queue and a common work function, we can pull
the queueing code into the rx handler directly
and remove the duplicated length checks etc.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211/rx.c')
-rw-r--r-- | net/mac80211/rx.c | 61 |
1 files changed, 48 insertions, 13 deletions
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 3adcda502b7d..40fe2798cbf5 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c | |||
@@ -1950,8 +1950,11 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx) | |||
1950 | if (len < IEEE80211_MIN_ACTION_SIZE + 1) | 1950 | if (len < IEEE80211_MIN_ACTION_SIZE + 1) |
1951 | break; | 1951 | break; |
1952 | 1952 | ||
1953 | if (sdata->vif.type == NL80211_IFTYPE_STATION) | 1953 | if (sdata->vif.type == NL80211_IFTYPE_STATION) { |
1954 | return ieee80211_sta_rx_mgmt(sdata, rx->skb); | 1954 | skb_queue_tail(&sdata->skb_queue, rx->skb); |
1955 | ieee80211_queue_work(&local->hw, &sdata->work); | ||
1956 | return RX_QUEUED; | ||
1957 | } | ||
1955 | 1958 | ||
1956 | switch (mgmt->u.action.u.addba_req.action_code) { | 1959 | switch (mgmt->u.action.u.addba_req.action_code) { |
1957 | case WLAN_ACTION_ADDBA_REQ: | 1960 | case WLAN_ACTION_ADDBA_REQ: |
@@ -2003,7 +2006,9 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx) | |||
2003 | if (memcmp(mgmt->bssid, sdata->u.mgd.bssid, ETH_ALEN)) | 2006 | if (memcmp(mgmt->bssid, sdata->u.mgd.bssid, ETH_ALEN)) |
2004 | break; | 2007 | break; |
2005 | 2008 | ||
2006 | return ieee80211_sta_rx_mgmt(sdata, rx->skb); | 2009 | skb_queue_tail(&sdata->skb_queue, rx->skb); |
2010 | ieee80211_queue_work(&local->hw, &sdata->work); | ||
2011 | return RX_QUEUED; | ||
2007 | } | 2012 | } |
2008 | break; | 2013 | break; |
2009 | case WLAN_CATEGORY_SA_QUERY: | 2014 | case WLAN_CATEGORY_SA_QUERY: |
@@ -2021,9 +2026,11 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx) | |||
2021 | break; | 2026 | break; |
2022 | case WLAN_CATEGORY_MESH_PLINK: | 2027 | case WLAN_CATEGORY_MESH_PLINK: |
2023 | case WLAN_CATEGORY_MESH_PATH_SEL: | 2028 | case WLAN_CATEGORY_MESH_PATH_SEL: |
2024 | if (ieee80211_vif_is_mesh(&sdata->vif)) | 2029 | if (!ieee80211_vif_is_mesh(&sdata->vif)) |
2025 | return ieee80211_mesh_rx_mgmt(sdata, rx->skb); | 2030 | break; |
2026 | break; | 2031 | skb_queue_tail(&sdata->skb_queue, rx->skb); |
2032 | ieee80211_queue_work(&local->hw, &sdata->work); | ||
2033 | return RX_QUEUED; | ||
2027 | } | 2034 | } |
2028 | 2035 | ||
2029 | /* | 2036 | /* |
@@ -2080,10 +2087,15 @@ ieee80211_rx_h_mgmt(struct ieee80211_rx_data *rx) | |||
2080 | { | 2087 | { |
2081 | struct ieee80211_sub_if_data *sdata = rx->sdata; | 2088 | struct ieee80211_sub_if_data *sdata = rx->sdata; |
2082 | ieee80211_rx_result rxs; | 2089 | ieee80211_rx_result rxs; |
2090 | struct ieee80211_mgmt *mgmt = (void *)rx->skb->data; | ||
2091 | __le16 stype; | ||
2083 | 2092 | ||
2084 | if (!(rx->flags & IEEE80211_RX_RA_MATCH)) | 2093 | if (!(rx->flags & IEEE80211_RX_RA_MATCH)) |
2085 | return RX_DROP_MONITOR; | 2094 | return RX_DROP_MONITOR; |
2086 | 2095 | ||
2096 | if (rx->skb->len < 24) | ||
2097 | return RX_DROP_MONITOR; | ||
2098 | |||
2087 | if (ieee80211_drop_unencrypted_mgmt(rx)) | 2099 | if (ieee80211_drop_unencrypted_mgmt(rx)) |
2088 | return RX_DROP_UNUSABLE; | 2100 | return RX_DROP_UNUSABLE; |
2089 | 2101 | ||
@@ -2091,16 +2103,39 @@ ieee80211_rx_h_mgmt(struct ieee80211_rx_data *rx) | |||
2091 | if (rxs != RX_CONTINUE) | 2103 | if (rxs != RX_CONTINUE) |
2092 | return rxs; | 2104 | return rxs; |
2093 | 2105 | ||
2094 | if (ieee80211_vif_is_mesh(&sdata->vif)) | 2106 | stype = mgmt->frame_control & cpu_to_le16(IEEE80211_FCTL_STYPE); |
2095 | return ieee80211_mesh_rx_mgmt(sdata, rx->skb); | ||
2096 | 2107 | ||
2097 | if (sdata->vif.type == NL80211_IFTYPE_ADHOC) | 2108 | if (!ieee80211_vif_is_mesh(&sdata->vif) && |
2098 | return ieee80211_ibss_rx_mgmt(sdata, rx->skb); | 2109 | sdata->vif.type != NL80211_IFTYPE_ADHOC && |
2110 | sdata->vif.type != NL80211_IFTYPE_STATION) | ||
2111 | return RX_DROP_MONITOR; | ||
2099 | 2112 | ||
2100 | if (sdata->vif.type == NL80211_IFTYPE_STATION) | 2113 | switch (stype) { |
2101 | return ieee80211_sta_rx_mgmt(sdata, rx->skb); | 2114 | case cpu_to_le16(IEEE80211_STYPE_BEACON): |
2115 | case cpu_to_le16(IEEE80211_STYPE_PROBE_RESP): | ||
2116 | /* process for all: mesh, mlme, ibss */ | ||
2117 | break; | ||
2118 | case cpu_to_le16(IEEE80211_STYPE_DEAUTH): | ||
2119 | case cpu_to_le16(IEEE80211_STYPE_DISASSOC): | ||
2120 | /* process only for station */ | ||
2121 | if (sdata->vif.type != NL80211_IFTYPE_STATION) | ||
2122 | return RX_DROP_MONITOR; | ||
2123 | break; | ||
2124 | case cpu_to_le16(IEEE80211_STYPE_PROBE_REQ): | ||
2125 | case cpu_to_le16(IEEE80211_STYPE_AUTH): | ||
2126 | /* process only for ibss */ | ||
2127 | if (sdata->vif.type != NL80211_IFTYPE_ADHOC) | ||
2128 | return RX_DROP_MONITOR; | ||
2129 | break; | ||
2130 | default: | ||
2131 | return RX_DROP_MONITOR; | ||
2132 | } | ||
2102 | 2133 | ||
2103 | return RX_DROP_MONITOR; | 2134 | /* queue up frame and kick off work to process it */ |
2135 | skb_queue_tail(&sdata->skb_queue, rx->skb); | ||
2136 | ieee80211_queue_work(&rx->local->hw, &sdata->work); | ||
2137 | |||
2138 | return RX_QUEUED; | ||
2104 | } | 2139 | } |
2105 | 2140 | ||
2106 | static void ieee80211_rx_michael_mic_report(struct ieee80211_hdr *hdr, | 2141 | static void ieee80211_rx_michael_mic_report(struct ieee80211_hdr *hdr, |