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.c71
1 files changed, 54 insertions, 17 deletions
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 683b10f46505..1101563357ea 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -272,7 +272,7 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local,
272 else if (rate && rate->flags & IEEE80211_RATE_ERP_G) 272 else if (rate && rate->flags & IEEE80211_RATE_ERP_G)
273 channel_flags |= IEEE80211_CHAN_OFDM | IEEE80211_CHAN_2GHZ; 273 channel_flags |= IEEE80211_CHAN_OFDM | IEEE80211_CHAN_2GHZ;
274 else if (rate) 274 else if (rate)
275 channel_flags |= IEEE80211_CHAN_OFDM | IEEE80211_CHAN_2GHZ; 275 channel_flags |= IEEE80211_CHAN_CCK | IEEE80211_CHAN_2GHZ;
276 else 276 else
277 channel_flags |= IEEE80211_CHAN_2GHZ; 277 channel_flags |= IEEE80211_CHAN_2GHZ;
278 put_unaligned_le16(channel_flags, pos); 278 put_unaligned_le16(channel_flags, pos);
@@ -361,9 +361,6 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local,
361 u16 known = local->hw.radiotap_vht_details; 361 u16 known = local->hw.radiotap_vht_details;
362 362
363 rthdr->it_present |= cpu_to_le32(1 << IEEE80211_RADIOTAP_VHT); 363 rthdr->it_present |= cpu_to_le32(1 << IEEE80211_RADIOTAP_VHT);
364 /* known field - how to handle 80+80? */
365 if (status->vht_flag & RX_VHT_FLAG_80P80MHZ)
366 known &= ~IEEE80211_RADIOTAP_VHT_KNOWN_BANDWIDTH;
367 put_unaligned_le16(known, pos); 364 put_unaligned_le16(known, pos);
368 pos += 2; 365 pos += 2;
369 /* flags */ 366 /* flags */
@@ -378,8 +375,6 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local,
378 /* bandwidth */ 375 /* bandwidth */
379 if (status->vht_flag & RX_VHT_FLAG_80MHZ) 376 if (status->vht_flag & RX_VHT_FLAG_80MHZ)
380 *pos++ = 4; 377 *pos++ = 4;
381 else if (status->vht_flag & RX_VHT_FLAG_80P80MHZ)
382 *pos++ = 0; /* marked not known above */
383 else if (status->vht_flag & RX_VHT_FLAG_160MHZ) 378 else if (status->vht_flag & RX_VHT_FLAG_160MHZ)
384 *pos++ = 11; 379 *pos++ = 11;
385 else if (status->flag & RX_FLAG_40MHZ) 380 else if (status->flag & RX_FLAG_40MHZ)
@@ -652,6 +647,7 @@ static int ieee80211_get_mmie_keyidx(struct sk_buff *skb)
652{ 647{
653 struct ieee80211_mgmt *hdr = (struct ieee80211_mgmt *) skb->data; 648 struct ieee80211_mgmt *hdr = (struct ieee80211_mgmt *) skb->data;
654 struct ieee80211_mmie *mmie; 649 struct ieee80211_mmie *mmie;
650 struct ieee80211_mmie_16 *mmie16;
655 651
656 if (skb->len < 24 + sizeof(*mmie) || !is_multicast_ether_addr(hdr->da)) 652 if (skb->len < 24 + sizeof(*mmie) || !is_multicast_ether_addr(hdr->da))
657 return -1; 653 return -1;
@@ -661,11 +657,18 @@ static int ieee80211_get_mmie_keyidx(struct sk_buff *skb)
661 657
662 mmie = (struct ieee80211_mmie *) 658 mmie = (struct ieee80211_mmie *)
663 (skb->data + skb->len - sizeof(*mmie)); 659 (skb->data + skb->len - sizeof(*mmie));
664 if (mmie->element_id != WLAN_EID_MMIE || 660 if (mmie->element_id == WLAN_EID_MMIE &&
665 mmie->length != sizeof(*mmie) - 2) 661 mmie->length == sizeof(*mmie) - 2)
666 return -1; 662 return le16_to_cpu(mmie->key_id);
667 663
668 return le16_to_cpu(mmie->key_id); 664 mmie16 = (struct ieee80211_mmie_16 *)
665 (skb->data + skb->len - sizeof(*mmie16));
666 if (skb->len >= 24 + sizeof(*mmie16) &&
667 mmie16->element_id == WLAN_EID_MMIE &&
668 mmie16->length == sizeof(*mmie16) - 2)
669 return le16_to_cpu(mmie16->key_id);
670
671 return -1;
669} 672}
670 673
671static int iwl80211_get_cs_keyid(const struct ieee80211_cipher_scheme *cs, 674static int iwl80211_get_cs_keyid(const struct ieee80211_cipher_scheme *cs,
@@ -1655,11 +1658,27 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx)
1655 result = ieee80211_crypto_tkip_decrypt(rx); 1658 result = ieee80211_crypto_tkip_decrypt(rx);
1656 break; 1659 break;
1657 case WLAN_CIPHER_SUITE_CCMP: 1660 case WLAN_CIPHER_SUITE_CCMP:
1658 result = ieee80211_crypto_ccmp_decrypt(rx); 1661 result = ieee80211_crypto_ccmp_decrypt(
1662 rx, IEEE80211_CCMP_MIC_LEN);
1663 break;
1664 case WLAN_CIPHER_SUITE_CCMP_256:
1665 result = ieee80211_crypto_ccmp_decrypt(
1666 rx, IEEE80211_CCMP_256_MIC_LEN);
1659 break; 1667 break;
1660 case WLAN_CIPHER_SUITE_AES_CMAC: 1668 case WLAN_CIPHER_SUITE_AES_CMAC:
1661 result = ieee80211_crypto_aes_cmac_decrypt(rx); 1669 result = ieee80211_crypto_aes_cmac_decrypt(rx);
1662 break; 1670 break;
1671 case WLAN_CIPHER_SUITE_BIP_CMAC_256:
1672 result = ieee80211_crypto_aes_cmac_256_decrypt(rx);
1673 break;
1674 case WLAN_CIPHER_SUITE_BIP_GMAC_128:
1675 case WLAN_CIPHER_SUITE_BIP_GMAC_256:
1676 result = ieee80211_crypto_aes_gmac_decrypt(rx);
1677 break;
1678 case WLAN_CIPHER_SUITE_GCMP:
1679 case WLAN_CIPHER_SUITE_GCMP_256:
1680 result = ieee80211_crypto_gcmp_decrypt(rx);
1681 break;
1663 default: 1682 default:
1664 result = ieee80211_crypto_hw_decrypt(rx); 1683 result = ieee80211_crypto_hw_decrypt(rx);
1665 } 1684 }
@@ -1786,7 +1805,9 @@ ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx)
1786 /* This is the first fragment of a new frame. */ 1805 /* This is the first fragment of a new frame. */
1787 entry = ieee80211_reassemble_add(rx->sdata, frag, seq, 1806 entry = ieee80211_reassemble_add(rx->sdata, frag, seq,
1788 rx->seqno_idx, &(rx->skb)); 1807 rx->seqno_idx, &(rx->skb));
1789 if (rx->key && rx->key->conf.cipher == WLAN_CIPHER_SUITE_CCMP && 1808 if (rx->key &&
1809 (rx->key->conf.cipher == WLAN_CIPHER_SUITE_CCMP ||
1810 rx->key->conf.cipher == WLAN_CIPHER_SUITE_CCMP_256) &&
1790 ieee80211_has_protected(fc)) { 1811 ieee80211_has_protected(fc)) {
1791 int queue = rx->security_idx; 1812 int queue = rx->security_idx;
1792 /* Store CCMP PN so that we can verify that the next 1813 /* Store CCMP PN so that we can verify that the next
@@ -1815,7 +1836,9 @@ ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx)
1815 int i; 1836 int i;
1816 u8 pn[IEEE80211_CCMP_PN_LEN], *rpn; 1837 u8 pn[IEEE80211_CCMP_PN_LEN], *rpn;
1817 int queue; 1838 int queue;
1818 if (!rx->key || rx->key->conf.cipher != WLAN_CIPHER_SUITE_CCMP) 1839 if (!rx->key ||
1840 (rx->key->conf.cipher != WLAN_CIPHER_SUITE_CCMP &&
1841 rx->key->conf.cipher != WLAN_CIPHER_SUITE_CCMP_256))
1819 return RX_DROP_UNUSABLE; 1842 return RX_DROP_UNUSABLE;
1820 memcpy(pn, entry->last_pn, IEEE80211_CCMP_PN_LEN); 1843 memcpy(pn, entry->last_pn, IEEE80211_CCMP_PN_LEN);
1821 for (i = IEEE80211_CCMP_PN_LEN - 1; i >= 0; i--) { 1844 for (i = IEEE80211_CCMP_PN_LEN - 1; i >= 0; i--) {
@@ -2314,6 +2337,15 @@ ieee80211_rx_h_data(struct ieee80211_rx_data *rx)
2314 if (unlikely(!ieee80211_is_data_present(hdr->frame_control))) 2337 if (unlikely(!ieee80211_is_data_present(hdr->frame_control)))
2315 return RX_DROP_MONITOR; 2338 return RX_DROP_MONITOR;
2316 2339
2340 if (rx->sta) {
2341 /* The seqno index has the same property as needed
2342 * for the rx_msdu field, i.e. it is IEEE80211_NUM_TIDS
2343 * for non-QoS-data frames. Here we know it's a data
2344 * frame, so count MSDUs.
2345 */
2346 rx->sta->rx_msdu[rx->seqno_idx]++;
2347 }
2348
2317 /* 2349 /*
2318 * Send unexpected-4addr-frame event to hostapd. For older versions, 2350 * Send unexpected-4addr-frame event to hostapd. For older versions,
2319 * also drop the frame to cooked monitor interfaces. 2351 * also drop the frame to cooked monitor interfaces.
@@ -2598,7 +2630,7 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx)
2598 case WLAN_HT_ACTION_NOTIFY_CHANWIDTH: { 2630 case WLAN_HT_ACTION_NOTIFY_CHANWIDTH: {
2599 struct ieee80211_supported_band *sband; 2631 struct ieee80211_supported_band *sband;
2600 u8 chanwidth = mgmt->u.action.u.ht_notify_cw.chanwidth; 2632 u8 chanwidth = mgmt->u.action.u.ht_notify_cw.chanwidth;
2601 enum ieee80211_sta_rx_bandwidth new_bw; 2633 enum ieee80211_sta_rx_bandwidth max_bw, new_bw;
2602 2634
2603 /* If it doesn't support 40 MHz it can't change ... */ 2635 /* If it doesn't support 40 MHz it can't change ... */
2604 if (!(rx->sta->sta.ht_cap.cap & 2636 if (!(rx->sta->sta.ht_cap.cap &
@@ -2606,13 +2638,18 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx)
2606 goto handled; 2638 goto handled;
2607 2639
2608 if (chanwidth == IEEE80211_HT_CHANWIDTH_20MHZ) 2640 if (chanwidth == IEEE80211_HT_CHANWIDTH_20MHZ)
2609 new_bw = IEEE80211_STA_RX_BW_20; 2641 max_bw = IEEE80211_STA_RX_BW_20;
2610 else 2642 else
2611 new_bw = ieee80211_sta_cur_vht_bw(rx->sta); 2643 max_bw = ieee80211_sta_cap_rx_bw(rx->sta);
2644
2645 /* set cur_max_bandwidth and recalc sta bw */
2646 rx->sta->cur_max_bandwidth = max_bw;
2647 new_bw = ieee80211_sta_cur_vht_bw(rx->sta);
2612 2648
2613 if (rx->sta->sta.bandwidth == new_bw) 2649 if (rx->sta->sta.bandwidth == new_bw)
2614 goto handled; 2650 goto handled;
2615 2651
2652 rx->sta->sta.bandwidth = new_bw;
2616 sband = rx->local->hw.wiphy->bands[status->band]; 2653 sband = rx->local->hw.wiphy->bands[status->band];
2617 2654
2618 rate_control_rate_update(local, sband, rx->sta, 2655 rate_control_rate_update(local, sband, rx->sta,