aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/util.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/mac80211/util.c')
-rw-r--r--net/mac80211/util.c51
1 files changed, 47 insertions, 4 deletions
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index 471fb0516c99..22ca35054dd0 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -792,8 +792,11 @@ u32 ieee802_11_parse_elems_crc(u8 *start, size_t len,
792 elems->country_elem_len = elen; 792 elems->country_elem_len = elen;
793 break; 793 break;
794 case WLAN_EID_PWR_CONSTRAINT: 794 case WLAN_EID_PWR_CONSTRAINT:
795 if (elen != 1) {
796 elem_parse_failed = true;
797 break;
798 }
795 elems->pwr_constr_elem = pos; 799 elems->pwr_constr_elem = pos;
796 elems->pwr_constr_elem_len = elen;
797 break; 800 break;
798 case WLAN_EID_TIMEOUT_INTERVAL: 801 case WLAN_EID_TIMEOUT_INTERVAL:
799 elems->timeout_int = pos; 802 elems->timeout_int = pos;
@@ -1004,6 +1007,45 @@ void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata,
1004 ieee80211_tx_skb(sdata, skb); 1007 ieee80211_tx_skb(sdata, skb);
1005} 1008}
1006 1009
1010void ieee80211_send_deauth_disassoc(struct ieee80211_sub_if_data *sdata,
1011 const u8 *bssid, u16 stype, u16 reason,
1012 bool send_frame, u8 *frame_buf)
1013{
1014 struct ieee80211_local *local = sdata->local;
1015 struct sk_buff *skb;
1016 struct ieee80211_mgmt *mgmt = (void *)frame_buf;
1017
1018 /* build frame */
1019 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | stype);
1020 mgmt->duration = 0; /* initialize only */
1021 mgmt->seq_ctrl = 0; /* initialize only */
1022 memcpy(mgmt->da, bssid, ETH_ALEN);
1023 memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN);
1024 memcpy(mgmt->bssid, bssid, ETH_ALEN);
1025 /* u.deauth.reason_code == u.disassoc.reason_code */
1026 mgmt->u.deauth.reason_code = cpu_to_le16(reason);
1027
1028 if (send_frame) {
1029 skb = dev_alloc_skb(local->hw.extra_tx_headroom +
1030 IEEE80211_DEAUTH_FRAME_LEN);
1031 if (!skb)
1032 return;
1033
1034 skb_reserve(skb, local->hw.extra_tx_headroom);
1035
1036 /* copy in frame */
1037 memcpy(skb_put(skb, IEEE80211_DEAUTH_FRAME_LEN),
1038 mgmt, IEEE80211_DEAUTH_FRAME_LEN);
1039
1040 if (sdata->vif.type != NL80211_IFTYPE_STATION ||
1041 !(sdata->u.mgd.flags & IEEE80211_STA_MFP_ENABLED))
1042 IEEE80211_SKB_CB(skb)->flags |=
1043 IEEE80211_TX_INTFL_DONT_ENCRYPT;
1044
1045 ieee80211_tx_skb(sdata, skb);
1046 }
1047}
1048
1007int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer, 1049int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer,
1008 const u8 *ie, size_t ie_len, 1050 const u8 *ie, size_t ie_len,
1009 enum ieee80211_band band, u32 rate_mask, 1051 enum ieee80211_band band, u32 rate_mask,
@@ -1564,14 +1606,13 @@ static int check_mgd_smps(struct ieee80211_if_managed *ifmgd,
1564 return 0; 1606 return 0;
1565} 1607}
1566 1608
1567/* must hold iflist_mtx */
1568void ieee80211_recalc_smps(struct ieee80211_local *local) 1609void ieee80211_recalc_smps(struct ieee80211_local *local)
1569{ 1610{
1570 struct ieee80211_sub_if_data *sdata; 1611 struct ieee80211_sub_if_data *sdata;
1571 enum ieee80211_smps_mode smps_mode = IEEE80211_SMPS_OFF; 1612 enum ieee80211_smps_mode smps_mode = IEEE80211_SMPS_OFF;
1572 int count = 0; 1613 int count = 0;
1573 1614
1574 lockdep_assert_held(&local->iflist_mtx); 1615 mutex_lock(&local->iflist_mtx);
1575 1616
1576 /* 1617 /*
1577 * This function could be improved to handle multiple 1618 * This function could be improved to handle multiple
@@ -1600,12 +1641,14 @@ void ieee80211_recalc_smps(struct ieee80211_local *local)
1600 } 1641 }
1601 1642
1602 if (smps_mode == local->smps_mode) 1643 if (smps_mode == local->smps_mode)
1603 return; 1644 goto unlock;
1604 1645
1605 set: 1646 set:
1606 local->smps_mode = smps_mode; 1647 local->smps_mode = smps_mode;
1607 /* changed flag is auto-detected for this */ 1648 /* changed flag is auto-detected for this */
1608 ieee80211_hw_config(local, 0); 1649 ieee80211_hw_config(local, 0);
1650 unlock:
1651 mutex_unlock(&local->iflist_mtx);
1609} 1652}
1610 1653
1611static bool ieee80211_id_in_list(const u8 *ids, int n_ids, u8 id) 1654static bool ieee80211_id_in_list(const u8 *ids, int n_ids, u8 id)