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.c118
1 files changed, 83 insertions, 35 deletions
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index db46601e50bf..b867bd55de7a 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -841,7 +841,7 @@ ieee80211_rx_h_check(struct ieee80211_rx_data *rx)
841 ieee80211_is_pspoll(hdr->frame_control)) && 841 ieee80211_is_pspoll(hdr->frame_control)) &&
842 rx->sdata->vif.type != NL80211_IFTYPE_ADHOC && 842 rx->sdata->vif.type != NL80211_IFTYPE_ADHOC &&
843 rx->sdata->vif.type != NL80211_IFTYPE_WDS && 843 rx->sdata->vif.type != NL80211_IFTYPE_WDS &&
844 (!rx->sta || !test_sta_flags(rx->sta, WLAN_STA_ASSOC)))) { 844 (!rx->sta || !test_sta_flag(rx->sta, WLAN_STA_ASSOC)))) {
845 if (rx->sta && rx->sta->dummy && 845 if (rx->sta && rx->sta->dummy &&
846 ieee80211_is_data_present(hdr->frame_control)) { 846 ieee80211_is_data_present(hdr->frame_control)) {
847 u16 ethertype; 847 u16 ethertype;
@@ -1110,7 +1110,7 @@ static void ap_sta_ps_start(struct sta_info *sta)
1110 struct ieee80211_local *local = sdata->local; 1110 struct ieee80211_local *local = sdata->local;
1111 1111
1112 atomic_inc(&sdata->bss->num_sta_ps); 1112 atomic_inc(&sdata->bss->num_sta_ps);
1113 set_sta_flags(sta, WLAN_STA_PS_STA); 1113 set_sta_flag(sta, WLAN_STA_PS_STA);
1114 if (!(local->hw.flags & IEEE80211_HW_AP_LINK_PS)) 1114 if (!(local->hw.flags & IEEE80211_HW_AP_LINK_PS))
1115 drv_sta_notify(local, sdata, STA_NOTIFY_SLEEP, &sta->sta); 1115 drv_sta_notify(local, sdata, STA_NOTIFY_SLEEP, &sta->sta);
1116#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG 1116#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG
@@ -1130,7 +1130,7 @@ static void ap_sta_ps_end(struct sta_info *sta)
1130 sdata->name, sta->sta.addr, sta->sta.aid); 1130 sdata->name, sta->sta.addr, sta->sta.aid);
1131#endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ 1131#endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */
1132 1132
1133 if (test_sta_flags(sta, WLAN_STA_PS_DRIVER)) { 1133 if (test_sta_flag(sta, WLAN_STA_PS_DRIVER)) {
1134#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG 1134#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG
1135 printk(KERN_DEBUG "%s: STA %pM aid %d driver-ps-blocked\n", 1135 printk(KERN_DEBUG "%s: STA %pM aid %d driver-ps-blocked\n",
1136 sdata->name, sta->sta.addr, sta->sta.aid); 1136 sdata->name, sta->sta.addr, sta->sta.aid);
@@ -1149,7 +1149,7 @@ int ieee80211_sta_ps_transition(struct ieee80211_sta *sta, bool start)
1149 WARN_ON(!(sta_inf->local->hw.flags & IEEE80211_HW_AP_LINK_PS)); 1149 WARN_ON(!(sta_inf->local->hw.flags & IEEE80211_HW_AP_LINK_PS));
1150 1150
1151 /* Don't let the same PS state be set twice */ 1151 /* Don't let the same PS state be set twice */
1152 in_ps = test_sta_flags(sta_inf, WLAN_STA_PS_STA); 1152 in_ps = test_sta_flag(sta_inf, WLAN_STA_PS_STA);
1153 if ((start && in_ps) || (!start && !in_ps)) 1153 if ((start && in_ps) || (!start && !in_ps))
1154 return -EINVAL; 1154 return -EINVAL;
1155 1155
@@ -1163,6 +1163,81 @@ int ieee80211_sta_ps_transition(struct ieee80211_sta *sta, bool start)
1163EXPORT_SYMBOL(ieee80211_sta_ps_transition); 1163EXPORT_SYMBOL(ieee80211_sta_ps_transition);
1164 1164
1165static ieee80211_rx_result debug_noinline 1165static ieee80211_rx_result debug_noinline
1166ieee80211_rx_h_uapsd_and_pspoll(struct ieee80211_rx_data *rx)
1167{
1168 struct ieee80211_sub_if_data *sdata = rx->sdata;
1169 struct ieee80211_hdr *hdr = (void *)rx->skb->data;
1170 struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb);
1171 int tid, ac;
1172
1173 if (!rx->sta || !(status->rx_flags & IEEE80211_RX_RA_MATCH))
1174 return RX_CONTINUE;
1175
1176 if (sdata->vif.type != NL80211_IFTYPE_AP &&
1177 sdata->vif.type != NL80211_IFTYPE_AP_VLAN)
1178 return RX_CONTINUE;
1179
1180 /*
1181 * The device handles station powersave, so don't do anything about
1182 * uAPSD and PS-Poll frames (the latter shouldn't even come up from
1183 * it to mac80211 since they're handled.)
1184 */
1185 if (sdata->local->hw.flags & IEEE80211_HW_AP_LINK_PS)
1186 return RX_CONTINUE;
1187
1188 /*
1189 * Don't do anything if the station isn't already asleep. In
1190 * the uAPSD case, the station will probably be marked asleep,
1191 * in the PS-Poll case the station must be confused ...
1192 */
1193 if (!test_sta_flag(rx->sta, WLAN_STA_PS_STA))
1194 return RX_CONTINUE;
1195
1196 if (unlikely(ieee80211_is_pspoll(hdr->frame_control))) {
1197 if (!test_sta_flag(rx->sta, WLAN_STA_SP)) {
1198 if (!test_sta_flag(rx->sta, WLAN_STA_PS_DRIVER))
1199 ieee80211_sta_ps_deliver_poll_response(rx->sta);
1200 else
1201 set_sta_flag(rx->sta, WLAN_STA_PSPOLL);
1202 }
1203
1204 /* Free PS Poll skb here instead of returning RX_DROP that would
1205 * count as an dropped frame. */
1206 dev_kfree_skb(rx->skb);
1207
1208 return RX_QUEUED;
1209 } else if (!ieee80211_has_morefrags(hdr->frame_control) &&
1210 !(status->rx_flags & IEEE80211_RX_DEFERRED_RELEASE) &&
1211 ieee80211_has_pm(hdr->frame_control) &&
1212 (ieee80211_is_data_qos(hdr->frame_control) ||
1213 ieee80211_is_qos_nullfunc(hdr->frame_control))) {
1214 tid = *ieee80211_get_qos_ctl(hdr) & IEEE80211_QOS_CTL_TID_MASK;
1215 ac = ieee802_1d_to_ac[tid & 7];
1216
1217 /*
1218 * If this AC is not trigger-enabled do nothing.
1219 *
1220 * NB: This could/should check a separate bitmap of trigger-
1221 * enabled queues, but for now we only implement uAPSD w/o
1222 * TSPEC changes to the ACs, so they're always the same.
1223 */
1224 if (!(rx->sta->sta.uapsd_queues & BIT(ac)))
1225 return RX_CONTINUE;
1226
1227 /* if we are in a service period, do nothing */
1228 if (test_sta_flag(rx->sta, WLAN_STA_SP))
1229 return RX_CONTINUE;
1230
1231 if (!test_sta_flag(rx->sta, WLAN_STA_PS_DRIVER))
1232 ieee80211_sta_ps_deliver_uapsd(rx->sta);
1233 else
1234 set_sta_flag(rx->sta, WLAN_STA_UAPSD);
1235 }
1236
1237 return RX_CONTINUE;
1238}
1239
1240static ieee80211_rx_result debug_noinline
1166ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx) 1241ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx)
1167{ 1242{
1168 struct sta_info *sta = rx->sta; 1243 struct sta_info *sta = rx->sta;
@@ -1220,7 +1295,7 @@ ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx)
1220 !(status->rx_flags & IEEE80211_RX_DEFERRED_RELEASE) && 1295 !(status->rx_flags & IEEE80211_RX_DEFERRED_RELEASE) &&
1221 (rx->sdata->vif.type == NL80211_IFTYPE_AP || 1296 (rx->sdata->vif.type == NL80211_IFTYPE_AP ||
1222 rx->sdata->vif.type == NL80211_IFTYPE_AP_VLAN)) { 1297 rx->sdata->vif.type == NL80211_IFTYPE_AP_VLAN)) {
1223 if (test_sta_flags(sta, WLAN_STA_PS_STA)) { 1298 if (test_sta_flag(sta, WLAN_STA_PS_STA)) {
1224 /* 1299 /*
1225 * Ignore doze->wake transitions that are 1300 * Ignore doze->wake transitions that are
1226 * indicated by non-data frames, the standard 1301 * indicated by non-data frames, the standard
@@ -1473,33 +1548,6 @@ ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx)
1473} 1548}
1474 1549
1475static ieee80211_rx_result debug_noinline 1550static ieee80211_rx_result debug_noinline
1476ieee80211_rx_h_ps_poll(struct ieee80211_rx_data *rx)
1477{
1478 struct ieee80211_sub_if_data *sdata = rx->sdata;
1479 __le16 fc = ((struct ieee80211_hdr *)rx->skb->data)->frame_control;
1480 struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb);
1481
1482 if (likely(!rx->sta || !ieee80211_is_pspoll(fc) ||
1483 !(status->rx_flags & IEEE80211_RX_RA_MATCH)))
1484 return RX_CONTINUE;
1485
1486 if ((sdata->vif.type != NL80211_IFTYPE_AP) &&
1487 (sdata->vif.type != NL80211_IFTYPE_AP_VLAN))
1488 return RX_DROP_UNUSABLE;
1489
1490 if (!test_sta_flags(rx->sta, WLAN_STA_PS_DRIVER))
1491 ieee80211_sta_ps_deliver_poll_response(rx->sta);
1492 else
1493 set_sta_flags(rx->sta, WLAN_STA_PSPOLL);
1494
1495 /* Free PS Poll skb here instead of returning RX_DROP that would
1496 * count as an dropped frame. */
1497 dev_kfree_skb(rx->skb);
1498
1499 return RX_QUEUED;
1500}
1501
1502static ieee80211_rx_result debug_noinline
1503ieee80211_rx_h_remove_qos_control(struct ieee80211_rx_data *rx) 1551ieee80211_rx_h_remove_qos_control(struct ieee80211_rx_data *rx)
1504{ 1552{
1505 u8 *data = rx->skb->data; 1553 u8 *data = rx->skb->data;
@@ -1522,7 +1570,7 @@ static int
1522ieee80211_802_1x_port_control(struct ieee80211_rx_data *rx) 1570ieee80211_802_1x_port_control(struct ieee80211_rx_data *rx)
1523{ 1571{
1524 if (unlikely(!rx->sta || 1572 if (unlikely(!rx->sta ||
1525 !test_sta_flags(rx->sta, WLAN_STA_AUTHORIZED))) 1573 !test_sta_flag(rx->sta, WLAN_STA_AUTHORIZED)))
1526 return -EACCES; 1574 return -EACCES;
1527 1575
1528 return 0; 1576 return 0;
@@ -1565,7 +1613,7 @@ ieee80211_drop_unencrypted_mgmt(struct ieee80211_rx_data *rx)
1565 if (status->flag & RX_FLAG_DECRYPTED) 1613 if (status->flag & RX_FLAG_DECRYPTED)
1566 return 0; 1614 return 0;
1567 1615
1568 if (rx->sta && test_sta_flags(rx->sta, WLAN_STA_MFP)) { 1616 if (rx->sta && test_sta_flag(rx->sta, WLAN_STA_MFP)) {
1569 if (unlikely(!ieee80211_has_protected(fc) && 1617 if (unlikely(!ieee80211_has_protected(fc) &&
1570 ieee80211_is_unicast_robust_mgmt_frame(rx->skb) && 1618 ieee80211_is_unicast_robust_mgmt_frame(rx->skb) &&
1571 rx->key)) { 1619 rx->key)) {
@@ -2567,9 +2615,9 @@ static void ieee80211_rx_handlers(struct ieee80211_rx_data *rx)
2567 2615
2568 CALL_RXH(ieee80211_rx_h_decrypt) 2616 CALL_RXH(ieee80211_rx_h_decrypt)
2569 CALL_RXH(ieee80211_rx_h_check_more_data) 2617 CALL_RXH(ieee80211_rx_h_check_more_data)
2618 CALL_RXH(ieee80211_rx_h_uapsd_and_pspoll)
2570 CALL_RXH(ieee80211_rx_h_sta_process) 2619 CALL_RXH(ieee80211_rx_h_sta_process)
2571 CALL_RXH(ieee80211_rx_h_defragment) 2620 CALL_RXH(ieee80211_rx_h_defragment)
2572 CALL_RXH(ieee80211_rx_h_ps_poll)
2573 CALL_RXH(ieee80211_rx_h_michael_mic_verify) 2621 CALL_RXH(ieee80211_rx_h_michael_mic_verify)
2574 /* must be after MMIC verify so header is counted in MPDU mic */ 2622 /* must be after MMIC verify so header is counted in MPDU mic */
2575#ifdef CONFIG_MAC80211_MESH 2623#ifdef CONFIG_MAC80211_MESH