Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'mac80211-next-for-davem-2017-01-13' of git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next

Johannes Berg says:

====================
For 4.11, we seem to have more than in the past few releases:
* socket owner support for connections, so when the wifi
manager (e.g. wpa_supplicant) is killed, connections are
torn down - wpa_supplicant is critical to managing certain
operations, and can opt in to this where applicable
* minstrel & minstrel_ht updates to be more efficient (time and space)
* set wifi_acked/wifi_acked_valid for skb->destructor use in the
kernel, which was already available to userspace
* don't indicate new mesh peers that might be used if there's no
room to add them
* multicast-to-unicast support in mac80211, for better medium usage
(since unicast frames can use *much* higher rates, by ~3 orders of
magnitude)
* add API to read channel (frequency) limitations from DT
* add infrastructure to allow randomizing public action frames for
MAC address privacy (still requires driver support)
* many cleanups and small improvements/fixes across the board
====================

Signed-off-by: David S. Miller <davem@davemloft.net>

+1015 -426
+24
Documentation/devicetree/bindings/net/wireless/ieee80211.txt
··· 1 + Common IEEE 802.11 properties 2 + 3 + This provides documentation of common properties that are valid for all wireless 4 + devices. 5 + 6 + Optional properties: 7 + - ieee80211-freq-limit : list of supported frequency ranges in KHz. This can be 8 + used for devices that in a given config support less channels than 9 + normally. It may happen chipset supports a wide wireless band but it is 10 + limited to some part of it due to used antennas or power amplifier. 11 + An example case for this can be tri-band wireless router with two 12 + identical chipsets used for two different 5 GHz subbands. Using them 13 + incorrectly could not work or decrease performance noticeably. 14 + 15 + Example: 16 + 17 + pcie@0,0 { 18 + reg = <0x0000 0 0 0 0>; 19 + wifi@0,0 { 20 + reg = <0x0000 0 0 0 0>; 21 + ieee80211-freq-limit = <2402000 2482000>, 22 + <5170000 5250000>; 23 + }; 24 + };
+3
Documentation/driver-api/80211/cfg80211.rst
··· 45 45 :functions: wiphy_new 46 46 47 47 .. kernel-doc:: include/net/cfg80211.h 48 + :functions: wiphy_read_of_freq_limits 49 + 50 + .. kernel-doc:: include/net/cfg80211.h 48 51 :functions: wiphy_register 49 52 50 53 .. kernel-doc:: include/net/cfg80211.h
+4 -4
Documentation/networking/regulatory.txt
··· 156 156 //.alpha2 = "99", /* If I have no alpha2 to map it to */ 157 157 .reg_rules = { 158 158 /* IEEE 802.11b/g, channels 1..14 */ 159 - REG_RULE(2412-20, 2484+20, 40, 6, 20, 0), 159 + REG_RULE(2412-10, 2484+10, 40, 6, 20, 0), 160 160 /* IEEE 802.11a, channels 34..48 */ 161 - REG_RULE(5170-20, 5240+20, 40, 6, 20, 161 + REG_RULE(5170-10, 5240+10, 40, 6, 20, 162 162 NL80211_RRF_NO_IR), 163 163 /* IEEE 802.11a, channels 52..64 */ 164 - REG_RULE(5260-20, 5320+20, 40, 6, 20, 164 + REG_RULE(5260-10, 5320+10, 40, 6, 20, 165 165 NL80211_RRF_NO_IR| 166 166 NL80211_RRF_DFS), 167 167 } ··· 205 205 The file net/wireless/db.txt should be kept up-to-date with the db.txt 206 206 file available in the git repository here: 207 207 208 - git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-regdb.git 208 + git://git.kernel.org/pub/scm/linux/kernel/git/sforshee/wireless-regdb.git 209 209 210 210 Again, most users in most situations should be using the CRDA package 211 211 provided with their distribution, and in most other situations users
+1 -2
drivers/net/wireless/ath/ath10k/htt_rx.c
··· 2451 2451 u32 phymode = __le32_to_cpu(resp->chan_change.phymode); 2452 2452 u32 freq = __le32_to_cpu(resp->chan_change.freq); 2453 2453 2454 - ar->tgt_oper_chan = 2455 - __ieee80211_get_channel(ar->hw->wiphy, freq); 2454 + ar->tgt_oper_chan = ieee80211_get_channel(ar->hw->wiphy, freq); 2456 2455 ath10k_dbg(ar, ATH10K_DBG_HTT, 2457 2456 "htt chan change freq %u phymode %s\n", 2458 2457 freq, ath10k_wmi_phymode_str(phymode));
+1 -1
drivers/net/wireless/marvell/mwifiex/cfg80211.c
··· 2078 2078 ie_len = ie_buf[1] + sizeof(struct ieee_types_header); 2079 2079 2080 2080 band = mwifiex_band_to_radio_type(priv->curr_bss_params.band); 2081 - chan = __ieee80211_get_channel(priv->wdev.wiphy, 2081 + chan = ieee80211_get_channel(priv->wdev.wiphy, 2082 2082 ieee80211_channel_to_frequency(bss_info.bss_chan, 2083 2083 band)); 2084 2084
+2
include/linux/ieee80211.h
··· 185 185 186 186 /* number of user priorities 802.11 uses */ 187 187 #define IEEE80211_NUM_UPS 8 188 + /* number of ACs */ 189 + #define IEEE80211_NUM_ACS 4 188 190 189 191 #define IEEE80211_QOS_CTL_LEN 2 190 192 /* 1d tag mask */
+94 -39
include/net/cfg80211.h
··· 311 311 struct ieee80211_sta_vht_cap vht_cap; 312 312 }; 313 313 314 + /** 315 + * wiphy_read_of_freq_limits - read frequency limits from device tree 316 + * 317 + * @wiphy: the wireless device to get extra limits for 318 + * 319 + * Some devices may have extra limitations specified in DT. This may be useful 320 + * for chipsets that normally support more bands but are limited due to board 321 + * design (e.g. by antennas or external power amplifier). 322 + * 323 + * This function reads info from DT and uses it to *modify* channels (disable 324 + * unavailable ones). It's usually a *bad* idea to use it in drivers with 325 + * shared channel data as DT limitations are device specific. You should make 326 + * sure to call it only if channels in wiphy are copied and can be modified 327 + * without affecting other devices. 328 + * 329 + * As this function access device node it has to be called after set_wiphy_dev. 330 + * It also modifies channels so they have to be set first. 331 + * If using this helper, call it before wiphy_register(). 332 + */ 333 + #ifdef CONFIG_OF 334 + void wiphy_read_of_freq_limits(struct wiphy *wiphy); 335 + #else /* CONFIG_OF */ 336 + static inline void wiphy_read_of_freq_limits(struct wiphy *wiphy) 337 + { 338 + } 339 + #endif /* !CONFIG_OF */ 340 + 341 + 314 342 /* 315 343 * Wireless hardware/device configuration structures and methods 316 344 */ ··· 1620 1592 }; 1621 1593 1622 1594 /** 1595 + * struct cfg80211_bss_select_adjust - BSS selection with RSSI adjustment. 1596 + * 1597 + * @band: band of BSS which should match for RSSI level adjustment. 1598 + * @delta: value of RSSI level adjustment. 1599 + */ 1600 + struct cfg80211_bss_select_adjust { 1601 + enum nl80211_band band; 1602 + s8 delta; 1603 + }; 1604 + 1605 + /** 1623 1606 * struct cfg80211_sched_scan_request - scheduled scan request description 1624 1607 * 1625 1608 * @ssids: SSIDs to scan for (passed in the probe_reqs in active scans) ··· 1665 1626 * cycle. The driver may ignore this parameter and start 1666 1627 * immediately (or at any other time), if this feature is not 1667 1628 * supported. 1629 + * @relative_rssi_set: Indicates whether @relative_rssi is set or not. 1630 + * @relative_rssi: Relative RSSI threshold in dB to restrict scan result 1631 + * reporting in connected state to cases where a matching BSS is determined 1632 + * to have better or slightly worse RSSI than the current connected BSS. 1633 + * The relative RSSI threshold values are ignored in disconnected state. 1634 + * @rssi_adjust: delta dB of RSSI preference to be given to the BSSs that belong 1635 + * to the specified band while deciding whether a better BSS is reported 1636 + * using @relative_rssi. If delta is a negative number, the BSSs that 1637 + * belong to the specified band will be penalized by delta dB in relative 1638 + * comparisions. 1668 1639 */ 1669 1640 struct cfg80211_sched_scan_request { 1670 1641 struct cfg80211_ssid *ssids; ··· 1693 1644 1694 1645 u8 mac_addr[ETH_ALEN] __aligned(2); 1695 1646 u8 mac_addr_mask[ETH_ALEN] __aligned(2); 1647 + 1648 + bool relative_rssi_set; 1649 + s8 relative_rssi; 1650 + struct cfg80211_bss_select_adjust rssi_adjust; 1696 1651 1697 1652 /* internal */ 1698 1653 struct wiphy *wiphy; ··· 2003 1950 int mcast_rate[NUM_NL80211_BANDS]; 2004 1951 struct ieee80211_ht_cap ht_capa; 2005 1952 struct ieee80211_ht_cap ht_capa_mask; 2006 - }; 2007 - 2008 - /** 2009 - * struct cfg80211_bss_select_adjust - BSS selection with RSSI adjustment. 2010 - * 2011 - * @band: band of BSS which should match for RSSI level adjustment. 2012 - * @delta: value of RSSI level adjustment. 2013 - */ 2014 - struct cfg80211_bss_select_adjust { 2015 - enum nl80211_band band; 2016 - s8 delta; 2017 1953 }; 2018 1954 2019 1955 /** ··· 3879 3837 * @conn: (private) cfg80211 software SME connection state machine data 3880 3838 * @connect_keys: (private) keys to set after connection is established 3881 3839 * @conn_bss_type: connecting/connected BSS type 3840 + * @conn_owner_nlportid: (private) connection owner socket port ID 3841 + * @disconnect_wk: (private) auto-disconnect work 3842 + * @disconnect_bssid: (private) the BSSID to use for auto-disconnect 3882 3843 * @ibss_fixed: (private) IBSS is using fixed BSSID 3883 3844 * @ibss_dfs_possible: (private) IBSS may change to a DFS channel 3884 3845 * @event_list: (private) list for internal event processing ··· 3913 3868 struct cfg80211_conn *conn; 3914 3869 struct cfg80211_cached_keys *connect_keys; 3915 3870 enum ieee80211_bss_type conn_bss_type; 3871 + u32 conn_owner_nlportid; 3872 + 3873 + struct work_struct disconnect_wk; 3874 + u8 disconnect_bssid[ETH_ALEN]; 3916 3875 3917 3876 struct list_head event_list; 3918 3877 spinlock_t event_lock; ··· 4004 3955 */ 4005 3956 int ieee80211_frequency_to_channel(int freq); 4006 3957 4007 - /* 4008 - * Name indirection necessary because the ieee80211 code also has 4009 - * a function named "ieee80211_get_channel", so if you include 4010 - * cfg80211's header file you get cfg80211's version, if you try 4011 - * to include both header files you'll (rightfully!) get a symbol 4012 - * clash. 4013 - */ 4014 - struct ieee80211_channel *__ieee80211_get_channel(struct wiphy *wiphy, 4015 - int freq); 4016 3958 /** 4017 3959 * ieee80211_get_channel - get channel struct from wiphy for specified frequency 3960 + * 4018 3961 * @wiphy: the struct wiphy to get the channel for 4019 3962 * @freq: the center frequency of the channel 3963 + * 4020 3964 * Return: The channel struct from @wiphy at @freq. 4021 3965 */ 4022 - static inline struct ieee80211_channel * 4023 - ieee80211_get_channel(struct wiphy *wiphy, int freq) 4024 - { 4025 - return __ieee80211_get_channel(wiphy, freq); 4026 - } 3966 + struct ieee80211_channel *ieee80211_get_channel(struct wiphy *wiphy, int freq); 4027 3967 4028 3968 /** 4029 3969 * ieee80211_get_response_rate - get basic rate for a given rate ··· 5086 5048 * @req_ie_len: association request IEs length 5087 5049 * @resp_ie: association response IEs (may be %NULL) 5088 5050 * @resp_ie_len: assoc response IEs length 5089 - * @status: status code, 0 for successful connection, use 5090 - * %WLAN_STATUS_UNSPECIFIED_FAILURE if your device cannot give you 5091 - * the real status code for failures. 5051 + * @status: status code, %WLAN_STATUS_SUCCESS for successful connection, use 5052 + * %WLAN_STATUS_UNSPECIFIED_FAILURE if your device cannot give you 5053 + * the real status code for failures. If this call is used to report a 5054 + * failure due to a timeout (e.g., not receiving an Authentication frame 5055 + * from the AP) instead of an explicit rejection by the AP, -1 is used to 5056 + * indicate that this is a failure, but without a status code. 5057 + * @timeout_reason is used to report the reason for the timeout in that 5058 + * case. 5092 5059 * @gfp: allocation flags 5060 + * @timeout_reason: reason for connection timeout. This is used when the 5061 + * connection fails due to a timeout instead of an explicit rejection from 5062 + * the AP. %NL80211_TIMEOUT_UNSPECIFIED is used when the timeout reason is 5063 + * not known. This value is used only if @status < 0 to indicate that the 5064 + * failure is due to a timeout and not due to explicit rejection by the AP. 5065 + * This value is ignored in other cases (@status >= 0). 5093 5066 * 5094 - * It should be called by the underlying driver whenever connect() has 5095 - * succeeded. This is similar to cfg80211_connect_result(), but with the 5096 - * option of identifying the exact bss entry for the connection. Only one of 5097 - * these functions should be called. 5067 + * It should be called by the underlying driver once execution of the connection 5068 + * request from connect() has been completed. This is similar to 5069 + * cfg80211_connect_result(), but with the option of identifying the exact bss 5070 + * entry for the connection. Only one of these functions should be called. 5098 5071 */ 5099 5072 void cfg80211_connect_bss(struct net_device *dev, const u8 *bssid, 5100 5073 struct cfg80211_bss *bss, const u8 *req_ie, 5101 5074 size_t req_ie_len, const u8 *resp_ie, 5102 - size_t resp_ie_len, int status, gfp_t gfp); 5075 + size_t resp_ie_len, int status, gfp_t gfp, 5076 + enum nl80211_timeout_reason timeout_reason); 5103 5077 5104 5078 /** 5105 5079 * cfg80211_connect_result - notify cfg80211 of connection result ··· 5122 5072 * @req_ie_len: association request IEs length 5123 5073 * @resp_ie: association response IEs (may be %NULL) 5124 5074 * @resp_ie_len: assoc response IEs length 5125 - * @status: status code, 0 for successful connection, use 5075 + * @status: status code, %WLAN_STATUS_SUCCESS for successful connection, use 5126 5076 * %WLAN_STATUS_UNSPECIFIED_FAILURE if your device cannot give you 5127 5077 * the real status code for failures. 5128 5078 * @gfp: allocation flags 5129 5079 * 5130 - * It should be called by the underlying driver whenever connect() has 5131 - * succeeded. 5080 + * It should be called by the underlying driver once execution of the connection 5081 + * request from connect() has been completed. This is similar to 5082 + * cfg80211_connect_bss() which allows the exact bss entry to be specified. Only 5083 + * one of these functions should be called. 5132 5084 */ 5133 5085 static inline void 5134 5086 cfg80211_connect_result(struct net_device *dev, const u8 *bssid, ··· 5139 5087 u16 status, gfp_t gfp) 5140 5088 { 5141 5089 cfg80211_connect_bss(dev, bssid, NULL, req_ie, req_ie_len, resp_ie, 5142 - resp_ie_len, status, gfp); 5090 + resp_ie_len, status, gfp, 5091 + NL80211_TIMEOUT_UNSPECIFIED); 5143 5092 } 5144 5093 5145 5094 /** ··· 5151 5098 * @req_ie: association request IEs (maybe be %NULL) 5152 5099 * @req_ie_len: association request IEs length 5153 5100 * @gfp: allocation flags 5101 + * @timeout_reason: reason for connection timeout. 5154 5102 * 5155 5103 * It should be called by the underlying driver whenever connect() has failed 5156 5104 * in a sequence where no explicit authentication/association rejection was ··· 5161 5107 */ 5162 5108 static inline void 5163 5109 cfg80211_connect_timeout(struct net_device *dev, const u8 *bssid, 5164 - const u8 *req_ie, size_t req_ie_len, gfp_t gfp) 5110 + const u8 *req_ie, size_t req_ie_len, gfp_t gfp, 5111 + enum nl80211_timeout_reason timeout_reason) 5165 5112 { 5166 5113 cfg80211_connect_bss(dev, bssid, NULL, req_ie, req_ie_len, NULL, 0, -1, 5167 - gfp); 5114 + gfp, timeout_reason); 5168 5115 } 5169 5116 5170 5117 /**
+7 -59
include/net/iw_handler.h
··· 505 505 /* 506 506 * Wrapper to add an Wireless Event to a stream of events. 507 507 */ 508 - static inline char * 509 - iwe_stream_add_event(struct iw_request_info *info, char *stream, char *ends, 510 - struct iw_event *iwe, int event_len) 511 - { 512 - int lcp_len = iwe_stream_lcp_len(info); 513 - 514 - event_len = iwe_stream_event_len_adjust(info, event_len); 515 - 516 - /* Check if it's possible */ 517 - if(likely((stream + event_len) < ends)) { 518 - iwe->len = event_len; 519 - /* Beware of alignement issues on 64 bits */ 520 - memcpy(stream, (char *) iwe, IW_EV_LCP_PK_LEN); 521 - memcpy(stream + lcp_len, &iwe->u, 522 - event_len - lcp_len); 523 - stream += event_len; 524 - } 525 - return stream; 526 - } 508 + char *iwe_stream_add_event(struct iw_request_info *info, char *stream, 509 + char *ends, struct iw_event *iwe, int event_len); 527 510 528 511 static inline char * 529 512 iwe_stream_add_event_check(struct iw_request_info *info, char *stream, ··· 524 541 * Wrapper to add an short Wireless Event containing a pointer to a 525 542 * stream of events. 526 543 */ 527 - static inline char * 528 - iwe_stream_add_point(struct iw_request_info *info, char *stream, char *ends, 529 - struct iw_event *iwe, char *extra) 530 - { 531 - int event_len = iwe_stream_point_len(info) + iwe->u.data.length; 532 - int point_len = iwe_stream_point_len(info); 533 - int lcp_len = iwe_stream_lcp_len(info); 534 - 535 - /* Check if it's possible */ 536 - if(likely((stream + event_len) < ends)) { 537 - iwe->len = event_len; 538 - memcpy(stream, (char *) iwe, IW_EV_LCP_PK_LEN); 539 - memcpy(stream + lcp_len, 540 - ((char *) &iwe->u) + IW_EV_POINT_OFF, 541 - IW_EV_POINT_PK_LEN - IW_EV_LCP_PK_LEN); 542 - memcpy(stream + point_len, extra, iwe->u.data.length); 543 - stream += event_len; 544 - } 545 - return stream; 546 - } 544 + char *iwe_stream_add_point(struct iw_request_info *info, char *stream, 545 + char *ends, struct iw_event *iwe, char *extra); 547 546 548 547 static inline char * 549 548 iwe_stream_add_point_check(struct iw_request_info *info, char *stream, ··· 544 579 * Be careful, this one is tricky to use properly : 545 580 * At the first run, you need to have (value = event + IW_EV_LCP_LEN). 546 581 */ 547 - static inline char * 548 - iwe_stream_add_value(struct iw_request_info *info, char *event, char *value, 549 - char *ends, struct iw_event *iwe, int event_len) 550 - { 551 - int lcp_len = iwe_stream_lcp_len(info); 552 - 553 - /* Don't duplicate LCP */ 554 - event_len -= IW_EV_LCP_LEN; 555 - 556 - /* Check if it's possible */ 557 - if(likely((value + event_len) < ends)) { 558 - /* Add new value */ 559 - memcpy(value, &iwe->u, event_len); 560 - value += event_len; 561 - /* Patch LCP */ 562 - iwe->len = value - event; 563 - memcpy(event, (char *) iwe, lcp_len); 564 - } 565 - return value; 566 - } 582 + char *iwe_stream_add_value(struct iw_request_info *info, char *event, 583 + char *value, char *ends, struct iw_event *iwe, 584 + int event_len); 567 585 568 586 #endif /* _IW_HANDLER_H */
+4 -2
include/net/mac80211.h
··· 147 147 IEEE80211_AC_BE = 2, 148 148 IEEE80211_AC_BK = 3, 149 149 }; 150 - #define IEEE80211_NUM_ACS 4 151 150 152 151 /** 153 152 * struct ieee80211_tx_queue_params - transmit queue configuration ··· 1017 1018 * @RX_FLAG_DECRYPTED: This frame was decrypted in hardware. 1018 1019 * @RX_FLAG_MMIC_STRIPPED: the Michael MIC is stripped off this frame, 1019 1020 * verification has been done by the hardware. 1020 - * @RX_FLAG_IV_STRIPPED: The IV/ICV are stripped from this frame. 1021 + * @RX_FLAG_IV_STRIPPED: The IV and ICV are stripped from this frame. 1021 1022 * If this flag is set, the stack cannot do any replay detection 1022 1023 * hence the driver or hardware will have to do that. 1023 1024 * @RX_FLAG_PN_VALIDATED: Currently only valid for CCMP/GCMP frames, this ··· 1088 1089 * @RX_FLAG_ALLOW_SAME_PN: Allow the same PN as same packet before. 1089 1090 * This is used for AMSDU subframes which can have the same PN as 1090 1091 * the first subframe. 1092 + * @RX_FLAG_ICV_STRIPPED: The ICV is stripped from this frame. CRC checking must 1093 + * be done in the hardware. 1091 1094 */ 1092 1095 enum mac80211_rx_flags { 1093 1096 RX_FLAG_MMIC_ERROR = BIT(0), ··· 1125 1124 RX_FLAG_RADIOTAP_VENDOR_DATA = BIT(31), 1126 1125 RX_FLAG_MIC_STRIPPED = BIT_ULL(32), 1127 1126 RX_FLAG_ALLOW_SAME_PN = BIT_ULL(33), 1127 + RX_FLAG_ICV_STRIPPED = BIT_ULL(34), 1128 1128 }; 1129 1129 1130 1130 #define RX_FLAG_STBC_SHIFT 26
+62 -2
include/uapi/linux/nl80211.h
··· 1820 1820 * and remove functions. NAN notifications will be sent in unicast to that 1821 1821 * socket. Without this attribute, any socket can add functions and the 1822 1822 * notifications will be sent to the %NL80211_MCGRP_NAN multicast group. 1823 + * If set during %NL80211_CMD_ASSOCIATE or %NL80211_CMD_CONNECT the 1824 + * station will deauthenticate when the socket is closed. 1823 1825 * 1824 1826 * @NL80211_ATTR_TDLS_INITIATOR: flag attribute indicating the current end is 1825 1827 * the TDLS link initiator. ··· 1981 1979 * 1982 1980 * @NL80211_ATTR_BSSID: The BSSID of the AP. Note that %NL80211_ATTR_MAC is also 1983 1981 * used in various commands/events for specifying the BSSID. 1982 + * 1983 + * @NL80211_ATTR_SCHED_SCAN_RELATIVE_RSSI: Relative RSSI threshold by which 1984 + * other BSSs has to be better or slightly worse than the current 1985 + * connected BSS so that they get reported to user space. 1986 + * This will give an opportunity to userspace to consider connecting to 1987 + * other matching BSSs which have better or slightly worse RSSI than 1988 + * the current connected BSS by using an offloaded operation to avoid 1989 + * unnecessary wakeups. 1990 + * 1991 + * @NL80211_ATTR_SCHED_SCAN_RSSI_ADJUST: When present the RSSI level for BSSs in 1992 + * the specified band is to be adjusted before doing 1993 + * %NL80211_ATTR_SCHED_SCAN_RELATIVE_RSSI based comparision to figure out 1994 + * better BSSs. The attribute value is a packed structure 1995 + * value as specified by &struct nl80211_bss_select_rssi_adjust. 1996 + * 1997 + * @NL80211_ATTR_TIMEOUT_REASON: The reason for which an operation timed out. 1998 + * u32 attribute with an &enum nl80211_timeout_reason value. This is used, 1999 + * e.g., with %NL80211_CMD_CONNECT event. 1984 2000 * 1985 2001 * @NUM_NL80211_ATTR: total number of nl80211_attrs available 1986 2002 * @NL80211_ATTR_MAX: highest attribute number currently defined ··· 2405 2385 NL80211_ATTR_MULTICAST_TO_UNICAST_ENABLED, 2406 2386 2407 2387 NL80211_ATTR_BSSID, 2388 + 2389 + NL80211_ATTR_SCHED_SCAN_RELATIVE_RSSI, 2390 + NL80211_ATTR_SCHED_SCAN_RSSI_ADJUST, 2391 + 2392 + NL80211_ATTR_TIMEOUT_REASON, 2408 2393 2409 2394 /* add attributes here, update the policy in nl80211.c */ 2410 2395 ··· 3103 3078 * how this API was implemented in the past. Also, due to the same problem, 3104 3079 * the only way to create a matchset with only an RSSI filter (with this 3105 3080 * attribute) is if there's only a single matchset with the RSSI attribute. 3081 + * @NL80211_SCHED_SCAN_MATCH_ATTR_RELATIVE_RSSI: Flag indicating whether 3082 + * %NL80211_SCHED_SCAN_MATCH_ATTR_RSSI to be used as absolute RSSI or 3083 + * relative to current bss's RSSI. 3084 + * @NL80211_SCHED_SCAN_MATCH_ATTR_RSSI_ADJUST: When present the RSSI level for 3085 + * BSS-es in the specified band is to be adjusted before doing 3086 + * RSSI-based BSS selection. The attribute value is a packed structure 3087 + * value as specified by &struct nl80211_bss_select_rssi_adjust. 3106 3088 * @NL80211_SCHED_SCAN_MATCH_ATTR_MAX: highest scheduled scan filter 3107 3089 * attribute number currently defined 3108 3090 * @__NL80211_SCHED_SCAN_MATCH_ATTR_AFTER_LAST: internal use ··· 3119 3087 3120 3088 NL80211_SCHED_SCAN_MATCH_ATTR_SSID, 3121 3089 NL80211_SCHED_SCAN_MATCH_ATTR_RSSI, 3090 + NL80211_SCHED_SCAN_MATCH_ATTR_RELATIVE_RSSI, 3091 + NL80211_SCHED_SCAN_MATCH_ATTR_RSSI_ADJUST, 3122 3092 3123 3093 /* keep last */ 3124 3094 __NL80211_SCHED_SCAN_MATCH_ATTR_AFTER_LAST, ··· 4731 4697 * configuration (AP/mesh) with VHT rates. 4732 4698 * @NL80211_EXT_FEATURE_FILS_STA: This driver supports Fast Initial Link Setup 4733 4699 * with user space SME (NL80211_CMD_AUTHENTICATE) in station mode. 4700 + * @NL80211_EXT_FEATURE_MGMT_TX_RANDOM_TA: This driver supports randomized TA 4701 + * in @NL80211_CMD_FRAME while not associated. 4702 + * @NL80211_EXT_FEATURE_MGMT_TX_RANDOM_TA_CONNECTED: This driver supports 4703 + * randomized TA in @NL80211_CMD_FRAME while associated. 4704 + * @NL80211_EXT_FEATURE_SCHED_SCAN_RELATIVE_RSSI: The driver supports sched_scan 4705 + * for reporting BSSs with better RSSI than the current connected BSS 4706 + * (%NL80211_ATTR_SCHED_SCAN_RELATIVE_RSSI). 4734 4707 * 4735 4708 * @NUM_NL80211_EXT_FEATURES: number of extended features. 4736 4709 * @MAX_NL80211_EXT_FEATURES: highest extended feature index. ··· 4753 4712 NL80211_EXT_FEATURE_BEACON_RATE_HT, 4754 4713 NL80211_EXT_FEATURE_BEACON_RATE_VHT, 4755 4714 NL80211_EXT_FEATURE_FILS_STA, 4715 + NL80211_EXT_FEATURE_MGMT_TX_RANDOM_TA, 4716 + NL80211_EXT_FEATURE_MGMT_TX_RANDOM_TA_CONNECTED, 4717 + NL80211_EXT_FEATURE_SCHED_SCAN_RELATIVE_RSSI, 4756 4718 4757 4719 /* add new features before the definition below */ 4758 4720 NUM_NL80211_EXT_FEATURES, ··· 4792 4748 enum nl80211_connect_failed_reason { 4793 4749 NL80211_CONN_FAIL_MAX_CLIENTS, 4794 4750 NL80211_CONN_FAIL_BLOCKED_CLIENT, 4751 + }; 4752 + 4753 + /** 4754 + * enum nl80211_timeout_reason - timeout reasons 4755 + * 4756 + * @NL80211_TIMEOUT_UNSPECIFIED: Timeout reason unspecified. 4757 + * @NL80211_TIMEOUT_SCAN: Scan (AP discovery) timed out. 4758 + * @NL80211_TIMEOUT_AUTH: Authentication timed out. 4759 + * @NL80211_TIMEOUT_ASSOC: Association timed out. 4760 + */ 4761 + enum nl80211_timeout_reason { 4762 + NL80211_TIMEOUT_UNSPECIFIED, 4763 + NL80211_TIMEOUT_SCAN, 4764 + NL80211_TIMEOUT_AUTH, 4765 + NL80211_TIMEOUT_ASSOC, 4795 4766 }; 4796 4767 4797 4768 /** ··· 5023 4964 /** 5024 4965 * struct nl80211_bss_select_rssi_adjust - RSSI adjustment parameters. 5025 4966 * 5026 - * @band: band of BSS that must match for RSSI value adjustment. 5027 - * @delta: value used to adjust the RSSI value of matching BSS. 4967 + * @band: band of BSS that must match for RSSI value adjustment. The value 4968 + * of this field is according to &enum nl80211_band. 4969 + * @delta: value used to adjust the RSSI value of matching BSS in dB. 5028 4970 */ 5029 4971 struct nl80211_bss_select_rssi_adjust { 5030 4972 __u8 band;
+12
net/mac80211/cfg.c
··· 3563 3563 } 3564 3564 EXPORT_SYMBOL(ieee80211_nan_func_match); 3565 3565 3566 + static int ieee80211_set_multicast_to_unicast(struct wiphy *wiphy, 3567 + struct net_device *dev, 3568 + const bool enabled) 3569 + { 3570 + struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 3571 + 3572 + sdata->u.ap.multicast_to_unicast = enabled; 3573 + 3574 + return 0; 3575 + } 3576 + 3566 3577 const struct cfg80211_ops mac80211_config_ops = { 3567 3578 .add_virtual_intf = ieee80211_add_iface, 3568 3579 .del_virtual_intf = ieee80211_del_iface, ··· 3664 3653 .nan_change_conf = ieee80211_nan_change_conf, 3665 3654 .add_nan_func = ieee80211_add_nan_func, 3666 3655 .del_nan_func = ieee80211_del_nan_func, 3656 + .set_multicast_to_unicast = ieee80211_set_multicast_to_unicast, 3667 3657 };
+1 -3
net/mac80211/chan.c
··· 1270 1270 struct ieee80211_sub_if_data *sdata, *sdata_tmp; 1271 1271 struct ieee80211_chanctx *ctx, *ctx_tmp, *old_ctx; 1272 1272 struct ieee80211_chanctx *new_ctx = NULL; 1273 - int i, err, n_assigned, n_reserved, n_ready; 1273 + int err, n_assigned, n_reserved, n_ready; 1274 1274 int n_ctx = 0, n_vifs_switch = 0, n_vifs_assign = 0, n_vifs_ctxless = 0; 1275 1275 1276 1276 lockdep_assert_held(&local->mtx); ··· 1391 1391 * Update all structures, values and pointers to point to new channel 1392 1392 * context(s). 1393 1393 */ 1394 - 1395 - i = 0; 1396 1394 list_for_each_entry(ctx, &local->chanctx_list, list) { 1397 1395 if (ctx->replace_state != IEEE80211_CHANCTX_REPLACES_OTHER) 1398 1396 continue;
+27
net/mac80211/debugfs.c
··· 243 243 return rv; 244 244 } 245 245 246 + static ssize_t misc_read(struct file *file, char __user *user_buf, 247 + size_t count, loff_t *ppos) 248 + { 249 + struct ieee80211_local *local = file->private_data; 250 + /* Max len of each line is 16 characters, plus 9 for 'pending:\n' */ 251 + size_t bufsz = IEEE80211_MAX_QUEUES * 16 + 9; 252 + char *buf = kzalloc(bufsz, GFP_KERNEL); 253 + char *pos = buf, *end = buf + bufsz - 1; 254 + ssize_t rv; 255 + int i; 256 + int ln; 257 + 258 + pos += scnprintf(pos, end - pos, "pending:\n"); 259 + 260 + for (i = 0; i < IEEE80211_MAX_QUEUES; i++) { 261 + ln = skb_queue_len(&local->pending[i]); 262 + pos += scnprintf(pos, end - pos, "[%i] %d\n", 263 + i, ln); 264 + } 265 + 266 + rv = simple_read_from_buffer(user_buf, count, ppos, buf, strlen(buf)); 267 + kfree(buf); 268 + return rv; 269 + } 270 + 246 271 static ssize_t queues_read(struct file *file, char __user *user_buf, 247 272 size_t count, loff_t *ppos) 248 273 { ··· 288 263 289 264 DEBUGFS_READONLY_FILE_OPS(hwflags); 290 265 DEBUGFS_READONLY_FILE_OPS(queues); 266 + DEBUGFS_READONLY_FILE_OPS(misc); 291 267 292 268 /* statistics stuff */ 293 269 ··· 357 331 DEBUGFS_ADD(total_ps_buffered); 358 332 DEBUGFS_ADD(wep_iv); 359 333 DEBUGFS_ADD(queues); 334 + DEBUGFS_ADD(misc); 360 335 #ifdef CONFIG_PM 361 336 DEBUGFS_ADD_MODE(reset, 0200); 362 337 #endif
+3
net/mac80211/debugfs_netdev.c
··· 519 519 } 520 520 IEEE80211_IF_FILE_R(aqm); 521 521 522 + IEEE80211_IF_FILE(multicast_to_unicast, u.ap.multicast_to_unicast, HEX); 523 + 522 524 /* IBSS attributes */ 523 525 static ssize_t ieee80211_if_fmt_tsf( 524 526 const struct ieee80211_sub_if_data *sdata, char *buf, int buflen) ··· 685 683 DEBUGFS_ADD(dtim_count); 686 684 DEBUGFS_ADD(num_buffered_multicast); 687 685 DEBUGFS_ADD_MODE(tkip_mic_test, 0200); 686 + DEBUGFS_ADD_MODE(multicast_to_unicast, 0600); 688 687 } 689 688 690 689 static void add_vlan_files(struct ieee80211_sub_if_data *sdata)
+3 -3
net/mac80211/ieee80211_i.h
··· 297 297 driver_smps_mode; /* smps mode request */ 298 298 299 299 struct work_struct request_smps_work; 300 + bool multicast_to_unicast; 300 301 }; 301 302 302 303 struct ieee80211_if_wds { ··· 625 624 struct ieee80211_rx_status *rx_status); 626 625 627 626 /* should be called with beacon_data under RCU read lock */ 628 - void (*adjust_tbtt)(struct ieee80211_sub_if_data *sdata, 629 - struct beacon_data *beacon); 627 + void (*adjust_tsf)(struct ieee80211_sub_if_data *sdata, 628 + struct beacon_data *beacon); 630 629 /* add other framework functions here */ 631 630 }; 632 631 ··· 689 688 const struct ieee80211_mesh_sync_ops *sync_ops; 690 689 s64 sync_offset_clockdrift_max; 691 690 spinlock_t sync_offset_lock; 692 - bool adjusting_tbtt; 693 691 /* mesh power save */ 694 692 enum nl80211_mesh_power_mode nonpeer_pm; 695 693 int ps_peers_light_sleep;
+1 -6
net/mac80211/mesh.c
··· 279 279 /* Mesh PS mode. See IEEE802.11-2012 8.4.2.100.8 */ 280 280 *pos |= ifmsh->ps_peers_deep_sleep ? 281 281 IEEE80211_MESHCONF_CAPAB_POWER_SAVE_LEVEL : 0x00; 282 - *pos++ |= ifmsh->adjusting_tbtt ? 283 - IEEE80211_MESHCONF_CAPAB_TBTT_ADJUSTING : 0x00; 284 - *pos++ = 0x00; 285 - 286 282 return 0; 287 283 } 288 284 ··· 846 850 ifmsh->mesh_cc_id = 0; /* Disabled */ 847 851 /* register sync ops from extensible synchronization framework */ 848 852 ifmsh->sync_ops = ieee80211_mesh_sync_ops_get(ifmsh->mesh_sp_id); 849 - ifmsh->adjusting_tbtt = false; 850 853 ifmsh->sync_offset_clockdrift_max = 0; 851 854 set_bit(MESH_WORK_HOUSEKEEPING, &ifmsh->wrkq_flags); 852 855 ieee80211_mesh_root_setup(ifmsh); ··· 1344 1349 ieee80211_mesh_rootpath(sdata); 1345 1350 1346 1351 if (test_and_clear_bit(MESH_WORK_DRIFT_ADJUST, &ifmsh->wrkq_flags)) 1347 - mesh_sync_adjust_tbtt(sdata); 1352 + mesh_sync_adjust_tsf(sdata); 1348 1353 1349 1354 if (test_and_clear_bit(MESH_WORK_MBSS_CHANGED, &ifmsh->wrkq_flags)) 1350 1355 mesh_bss_info_changed(sdata);
+1 -1
net/mac80211/mesh.h
··· 341 341 } 342 342 343 343 void mesh_path_flush_by_iface(struct ieee80211_sub_if_data *sdata); 344 - void mesh_sync_adjust_tbtt(struct ieee80211_sub_if_data *sdata); 344 + void mesh_sync_adjust_tsf(struct ieee80211_sub_if_data *sdata); 345 345 void ieee80211s_stop(void); 346 346 #else 347 347 static inline bool mesh_path_sel_is_hwmp(struct ieee80211_sub_if_data *sdata)
+8 -6
net/mac80211/mesh_plink.c
··· 505 505 506 506 /* Userspace handles station allocation */ 507 507 if (sdata->u.mesh.user_mpm || 508 - sdata->u.mesh.security & IEEE80211_MESH_SEC_AUTHED) 509 - cfg80211_notify_new_peer_candidate(sdata->dev, addr, 510 - elems->ie_start, 511 - elems->total_len, 512 - GFP_KERNEL); 513 - else 508 + sdata->u.mesh.security & IEEE80211_MESH_SEC_AUTHED) { 509 + if (mesh_peer_accepts_plinks(elems) && 510 + mesh_plink_availables(sdata)) 511 + cfg80211_notify_new_peer_candidate(sdata->dev, addr, 512 + elems->ie_start, 513 + elems->total_len, 514 + GFP_KERNEL); 515 + } else 514 516 sta = __mesh_sta_info_alloc(sdata, addr); 515 517 516 518 return sta;
+8 -19
net/mac80211/mesh_sync.c
··· 12 12 #include "mesh.h" 13 13 #include "driver-ops.h" 14 14 15 - /* This is not in the standard. It represents a tolerable tbtt drift below 15 + /* This is not in the standard. It represents a tolerable tsf drift below 16 16 * which we do no TSF adjustment. 17 17 */ 18 18 #define TOFFSET_MINIMUM_ADJUSTMENT 10 ··· 46 46 IEEE80211_MESHCONF_CAPAB_TBTT_ADJUSTING) != 0; 47 47 } 48 48 49 - void mesh_sync_adjust_tbtt(struct ieee80211_sub_if_data *sdata) 49 + void mesh_sync_adjust_tsf(struct ieee80211_sub_if_data *sdata) 50 50 { 51 51 struct ieee80211_local *local = sdata->local; 52 52 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; ··· 57 57 58 58 spin_lock_bh(&ifmsh->sync_offset_lock); 59 59 if (ifmsh->sync_offset_clockdrift_max < beacon_int_fraction) { 60 - msync_dbg(sdata, "TBTT : max clockdrift=%lld; adjusting\n", 60 + msync_dbg(sdata, "TSF : max clockdrift=%lld; adjusting\n", 61 61 (long long) ifmsh->sync_offset_clockdrift_max); 62 62 tsfdelta = -ifmsh->sync_offset_clockdrift_max; 63 63 ifmsh->sync_offset_clockdrift_max = 0; 64 64 } else { 65 - msync_dbg(sdata, "TBTT : max clockdrift=%lld; adjusting by %llu\n", 65 + msync_dbg(sdata, "TSF : max clockdrift=%lld; adjusting by %llu\n", 66 66 (long long) ifmsh->sync_offset_clockdrift_max, 67 67 (unsigned long long) beacon_int_fraction); 68 68 tsfdelta = -beacon_int_fraction; ··· 123 123 */ 124 124 125 125 if (elems->mesh_config && mesh_peer_tbtt_adjusting(elems)) { 126 - clear_sta_flag(sta, WLAN_STA_TOFFSET_KNOWN); 127 126 msync_dbg(sdata, "STA %pM : is adjusting TBTT\n", 128 127 sta->sta.addr); 129 128 goto no_sync; ··· 167 168 rcu_read_unlock(); 168 169 } 169 170 170 - static void mesh_sync_offset_adjust_tbtt(struct ieee80211_sub_if_data *sdata, 171 + static void mesh_sync_offset_adjust_tsf(struct ieee80211_sub_if_data *sdata, 171 172 struct beacon_data *beacon) 172 173 { 173 174 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; 174 - u8 cap; 175 175 176 176 WARN_ON(ifmsh->mesh_sp_id != IEEE80211_SYNC_METHOD_NEIGHBOR_OFFSET); 177 177 WARN_ON(!rcu_read_lock_held()); 178 - cap = beacon->meshconf->meshconf_cap; 179 178 180 179 spin_lock_bh(&ifmsh->sync_offset_lock); 181 180 ··· 184 187 * the tsf adjustment to the mesh tasklet 185 188 */ 186 189 msync_dbg(sdata, 187 - "TBTT : kicking off TBTT adjustment with clockdrift_max=%lld\n", 190 + "TSF : kicking off TSF adjustment with clockdrift_max=%lld\n", 188 191 ifmsh->sync_offset_clockdrift_max); 189 192 set_bit(MESH_WORK_DRIFT_ADJUST, &ifmsh->wrkq_flags); 190 - 191 - ifmsh->adjusting_tbtt = true; 192 193 } else { 193 194 msync_dbg(sdata, 194 - "TBTT : max clockdrift=%lld; too small to adjust\n", 195 + "TSF : max clockdrift=%lld; too small to adjust\n", 195 196 (long long)ifmsh->sync_offset_clockdrift_max); 196 197 ifmsh->sync_offset_clockdrift_max = 0; 197 - 198 - ifmsh->adjusting_tbtt = false; 199 198 } 200 199 spin_unlock_bh(&ifmsh->sync_offset_lock); 201 - 202 - beacon->meshconf->meshconf_cap = ifmsh->adjusting_tbtt ? 203 - IEEE80211_MESHCONF_CAPAB_TBTT_ADJUSTING | cap : 204 - ~IEEE80211_MESHCONF_CAPAB_TBTT_ADJUSTING & cap; 205 200 } 206 201 207 202 static const struct sync_method sync_methods[] = { ··· 201 212 .method = IEEE80211_SYNC_METHOD_NEIGHBOR_OFFSET, 202 213 .ops = { 203 214 .rx_bcn_presp = &mesh_sync_offset_rx_bcn_presp, 204 - .adjust_tbtt = &mesh_sync_offset_adjust_tbtt, 215 + .adjust_tsf = &mesh_sync_offset_adjust_tsf, 205 216 } 206 217 }, 207 218 };
-4
net/mac80211/mlme.c
··· 1486 1486 1487 1487 if (count == 1 && ieee80211_powersave_allowed(found)) { 1488 1488 u8 dtimper = found->u.mgd.dtim_period; 1489 - s32 beaconint_us; 1490 - 1491 - beaconint_us = ieee80211_tu_to_usec( 1492 - found->vif.bss_conf.beacon_int); 1493 1489 1494 1490 timeout = local->dynamic_ps_forced_timeout; 1495 1491 if (timeout < 0)
+14 -7
net/mac80211/rc80211_minstrel.c
··· 159 159 void 160 160 minstrel_calc_rate_stats(struct minstrel_rate_stats *mrs) 161 161 { 162 + unsigned int cur_prob; 163 + 162 164 if (unlikely(mrs->attempts > 0)) { 163 165 mrs->sample_skipped = 0; 164 - mrs->cur_prob = MINSTREL_FRAC(mrs->success, mrs->attempts); 166 + cur_prob = MINSTREL_FRAC(mrs->success, mrs->attempts); 165 167 if (unlikely(!mrs->att_hist)) { 166 - mrs->prob_ewma = mrs->cur_prob; 168 + mrs->prob_ewma = cur_prob; 167 169 } else { 168 170 /* update exponential weighted moving variance */ 169 - mrs->prob_ewmsd = minstrel_ewmsd(mrs->prob_ewmsd, 170 - mrs->cur_prob, 171 - mrs->prob_ewma, 172 - EWMA_LEVEL); 171 + mrs->prob_ewmv = minstrel_ewmv(mrs->prob_ewmv, 172 + cur_prob, 173 + mrs->prob_ewma, 174 + EWMA_LEVEL); 173 175 174 176 /*update exponential weighted moving avarage */ 175 177 mrs->prob_ewma = minstrel_ewma(mrs->prob_ewma, 176 - mrs->cur_prob, 178 + cur_prob, 177 179 EWMA_LEVEL); 178 180 } 179 181 mrs->att_hist += mrs->attempts; ··· 366 364 if (mp->fixed_rate_idx != -1) 367 365 return; 368 366 #endif 367 + 368 + /* Don't use EAPOL frames for sampling on non-mrr hw */ 369 + if (mp->hw->max_rates == 1 && 370 + (info->control.flags & IEEE80211_TX_CTRL_PORT_CTRL_PROTO)) 371 + return; 369 372 370 373 delta = (mi->total_packets * sampling_ratio / 100) - 371 374 (mi->sample_packets + mi->sample_deferred / 2);
+17 -16
net/mac80211/rc80211_minstrel.h
··· 14 14 #define SAMPLE_COLUMNS 10 /* number of columns in sample table */ 15 15 16 16 /* scaled fraction values */ 17 - #define MINSTREL_SCALE 16 17 + #define MINSTREL_SCALE 12 18 18 #define MINSTREL_FRAC(val, div) (((val) << MINSTREL_SCALE) / div) 19 19 #define MINSTREL_TRUNC(val) ((val) >> MINSTREL_SCALE) 20 20 ··· 36 36 } 37 37 38 38 /* 39 - * Perform EWMSD (Exponentially Weighted Moving Standard Deviation) calculation 39 + * Perform EWMV (Exponentially Weighted Moving Variance) calculation 40 40 */ 41 41 static inline int 42 - minstrel_ewmsd(int old_ewmsd, int cur_prob, int prob_ewma, int weight) 42 + minstrel_ewmv(int old_ewmv, int cur_prob, int prob_ewma, int weight) 43 43 { 44 - int diff, incr, tmp_var; 44 + int diff, incr; 45 45 46 - /* calculate exponential weighted moving variance */ 47 - diff = MINSTREL_TRUNC((cur_prob - prob_ewma) * 1000000); 46 + diff = cur_prob - prob_ewma; 48 47 incr = (EWMA_DIV - weight) * diff / EWMA_DIV; 49 - tmp_var = old_ewmsd * old_ewmsd; 50 - tmp_var = weight * (tmp_var + diff * incr / 1000000) / EWMA_DIV; 51 - 52 - /* return standard deviation */ 53 - return (u16) int_sqrt(tmp_var); 48 + return weight * (old_ewmv + MINSTREL_TRUNC(diff * incr)) / EWMA_DIV; 54 49 } 55 50 56 51 struct minstrel_rate_stats { ··· 54 59 u16 success, last_success; 55 60 56 61 /* total attempts/success counters */ 57 - u64 att_hist, succ_hist; 62 + u32 att_hist, succ_hist; 58 63 59 64 /* statistis of packet delivery probability 60 - * cur_prob - current prob within last update intervall 61 65 * prob_ewma - exponential weighted moving average of prob 62 66 * prob_ewmsd - exp. weighted moving standard deviation of prob */ 63 - unsigned int cur_prob; 64 - unsigned int prob_ewma; 65 - u16 prob_ewmsd; 67 + u16 prob_ewma; 68 + u16 prob_ewmv; 66 69 67 70 /* maximum retry counts */ 68 71 u8 retry_count; ··· 145 152 size_t len; 146 153 char buf[]; 147 154 }; 155 + 156 + /* Get EWMSD (Exponentially Weighted Moving Standard Deviation) * 10 */ 157 + static inline int 158 + minstrel_get_ewmsd10(struct minstrel_rate_stats *mrs) 159 + { 160 + unsigned int ewmv = mrs->prob_ewmv; 161 + return int_sqrt(MINSTREL_TRUNC(ewmv * 1000 * 1000)); 162 + } 148 163 149 164 extern const struct rate_control_ops mac80211_minstrel; 150 165 void minstrel_add_sta_debugfs(void *priv, void *priv_sta, struct dentry *dir);
+12 -12
net/mac80211/rc80211_minstrel_debugfs.c
··· 75 75 { 76 76 struct minstrel_sta_info *mi = inode->i_private; 77 77 struct minstrel_debugfs_info *ms; 78 - unsigned int i, tp_max, tp_avg, prob, eprob; 78 + unsigned int i, tp_max, tp_avg, eprob; 79 79 char *p; 80 80 81 81 ms = kmalloc(2048, GFP_KERNEL); ··· 86 86 p = ms->buf; 87 87 p += sprintf(p, "\n"); 88 88 p += sprintf(p, 89 - "best __________rate_________ ________statistics________ ________last_______ ______sum-of________\n"); 89 + "best __________rate_________ ________statistics________ ____last_____ ______sum-of________\n"); 90 90 p += sprintf(p, 91 - "rate [name idx airtime max_tp] [avg(tp) avg(prob) sd(prob)] [prob.|retry|suc|att] [#success | #attempts]\n"); 91 + "rate [name idx airtime max_tp] [avg(tp) avg(prob) sd(prob)] [retry|suc|att] [#success | #attempts]\n"); 92 92 93 93 for (i = 0; i < mi->n_rates; i++) { 94 94 struct minstrel_rate *mr = &mi->r[i]; 95 95 struct minstrel_rate_stats *mrs = &mi->r[i].stats; 96 + unsigned int prob_ewmsd; 96 97 97 98 *(p++) = (i == mi->max_tp_rate[0]) ? 'A' : ' '; 98 99 *(p++) = (i == mi->max_tp_rate[1]) ? 'B' : ' '; ··· 108 107 109 108 tp_max = minstrel_get_tp_avg(mr, MINSTREL_FRAC(100,100)); 110 109 tp_avg = minstrel_get_tp_avg(mr, mrs->prob_ewma); 111 - prob = MINSTREL_TRUNC(mrs->cur_prob * 1000); 112 110 eprob = MINSTREL_TRUNC(mrs->prob_ewma * 1000); 111 + prob_ewmsd = minstrel_get_ewmsd10(mrs); 113 112 114 113 p += sprintf(p, "%4u.%1u %4u.%1u %3u.%1u %3u.%1u" 115 - " %3u.%1u %3u %3u %-3u " 114 + " %3u %3u %-3u " 116 115 "%9llu %-9llu\n", 117 116 tp_max / 10, tp_max % 10, 118 117 tp_avg / 10, tp_avg % 10, 119 118 eprob / 10, eprob % 10, 120 - mrs->prob_ewmsd / 10, mrs->prob_ewmsd % 10, 121 - prob / 10, prob % 10, 119 + prob_ewmsd / 10, prob_ewmsd % 10, 122 120 mrs->retry_count, 123 121 mrs->last_success, 124 122 mrs->last_attempts, ··· 148 148 { 149 149 struct minstrel_sta_info *mi = inode->i_private; 150 150 struct minstrel_debugfs_info *ms; 151 - unsigned int i, tp_max, tp_avg, prob, eprob; 151 + unsigned int i, tp_max, tp_avg, eprob; 152 152 char *p; 153 153 154 154 ms = kmalloc(2048, GFP_KERNEL); ··· 161 161 for (i = 0; i < mi->n_rates; i++) { 162 162 struct minstrel_rate *mr = &mi->r[i]; 163 163 struct minstrel_rate_stats *mrs = &mi->r[i].stats; 164 + unsigned int prob_ewmsd; 164 165 165 166 p += sprintf(p, "%s" ,((i == mi->max_tp_rate[0]) ? "A" : "")); 166 167 p += sprintf(p, "%s" ,((i == mi->max_tp_rate[1]) ? "B" : "")); ··· 176 175 177 176 tp_max = minstrel_get_tp_avg(mr, MINSTREL_FRAC(100,100)); 178 177 tp_avg = minstrel_get_tp_avg(mr, mrs->prob_ewma); 179 - prob = MINSTREL_TRUNC(mrs->cur_prob * 1000); 180 178 eprob = MINSTREL_TRUNC(mrs->prob_ewma * 1000); 179 + prob_ewmsd = minstrel_get_ewmsd10(mrs); 181 180 182 - p += sprintf(p, "%u.%u,%u.%u,%u.%u,%u.%u,%u.%u,%u,%u,%u," 181 + p += sprintf(p, "%u.%u,%u.%u,%u.%u,%u.%u,%u,%u,%u," 183 182 "%llu,%llu,%d,%d\n", 184 183 tp_max / 10, tp_max % 10, 185 184 tp_avg / 10, tp_avg % 10, 186 185 eprob / 10, eprob % 10, 187 - mrs->prob_ewmsd / 10, mrs->prob_ewmsd % 10, 188 - prob / 10, prob % 10, 186 + prob_ewmsd / 10, prob_ewmsd % 10, 189 187 mrs->retry_count, 190 188 mrs->last_success, 191 189 mrs->last_attempts,
+18 -50
net/mac80211/rc80211_minstrel_ht.c
··· 14 14 #include <linux/ieee80211.h> 15 15 #include <net/mac80211.h> 16 16 #include "rate.h" 17 + #include "sta_info.h" 17 18 #include "rc80211_minstrel.h" 18 19 #include "rc80211_minstrel_ht.h" 19 20 ··· 155 154 const struct mcs_group minstrel_mcs_groups[] = { 156 155 MCS_GROUP(1, 0, BW_20), 157 156 MCS_GROUP(2, 0, BW_20), 158 - #if MINSTREL_MAX_STREAMS >= 3 159 157 MCS_GROUP(3, 0, BW_20), 160 - #endif 161 158 162 159 MCS_GROUP(1, 1, BW_20), 163 160 MCS_GROUP(2, 1, BW_20), 164 - #if MINSTREL_MAX_STREAMS >= 3 165 161 MCS_GROUP(3, 1, BW_20), 166 - #endif 167 162 168 163 MCS_GROUP(1, 0, BW_40), 169 164 MCS_GROUP(2, 0, BW_40), 170 - #if MINSTREL_MAX_STREAMS >= 3 171 165 MCS_GROUP(3, 0, BW_40), 172 - #endif 173 166 174 167 MCS_GROUP(1, 1, BW_40), 175 168 MCS_GROUP(2, 1, BW_40), 176 - #if MINSTREL_MAX_STREAMS >= 3 177 169 MCS_GROUP(3, 1, BW_40), 178 - #endif 179 170 180 171 CCK_GROUP, 181 172 182 173 #ifdef CONFIG_MAC80211_RC_MINSTREL_VHT 183 174 VHT_GROUP(1, 0, BW_20), 184 175 VHT_GROUP(2, 0, BW_20), 185 - #if MINSTREL_MAX_STREAMS >= 3 186 176 VHT_GROUP(3, 0, BW_20), 187 - #endif 188 177 189 178 VHT_GROUP(1, 1, BW_20), 190 179 VHT_GROUP(2, 1, BW_20), 191 - #if MINSTREL_MAX_STREAMS >= 3 192 180 VHT_GROUP(3, 1, BW_20), 193 - #endif 194 181 195 182 VHT_GROUP(1, 0, BW_40), 196 183 VHT_GROUP(2, 0, BW_40), 197 - #if MINSTREL_MAX_STREAMS >= 3 198 184 VHT_GROUP(3, 0, BW_40), 199 - #endif 200 185 201 186 VHT_GROUP(1, 1, BW_40), 202 187 VHT_GROUP(2, 1, BW_40), 203 - #if MINSTREL_MAX_STREAMS >= 3 204 188 VHT_GROUP(3, 1, BW_40), 205 - #endif 206 189 207 190 VHT_GROUP(1, 0, BW_80), 208 191 VHT_GROUP(2, 0, BW_80), 209 - #if MINSTREL_MAX_STREAMS >= 3 210 192 VHT_GROUP(3, 0, BW_80), 211 - #endif 212 193 213 194 VHT_GROUP(1, 1, BW_80), 214 195 VHT_GROUP(2, 1, BW_80), 215 - #if MINSTREL_MAX_STREAMS >= 3 216 196 VHT_GROUP(3, 1, BW_80), 217 - #endif 218 197 #endif 219 198 }; 220 199 ··· 282 301 break; 283 302 284 303 /* short preamble */ 285 - if (!(mi->groups[group].supported & BIT(idx))) 304 + if (!(mi->supported[group] & BIT(idx))) 286 305 idx += 4; 287 306 } 288 307 return &mi->groups[group].rates[idx]; ··· 467 486 MCS_GROUP_RATES].streams; 468 487 for (group = 0; group < ARRAY_SIZE(minstrel_mcs_groups); group++) { 469 488 mg = &mi->groups[group]; 470 - if (!mg->supported || group == MINSTREL_CCK_GROUP) 489 + if (!mi->supported[group] || group == MINSTREL_CCK_GROUP) 471 490 continue; 472 491 473 492 tmp_idx = mg->max_group_prob_rate % MCS_GROUP_RATES; ··· 521 540 for (group = 0; group < ARRAY_SIZE(minstrel_mcs_groups); group++) { 522 541 523 542 mg = &mi->groups[group]; 524 - if (!mg->supported) 543 + if (!mi->supported[group]) 525 544 continue; 526 545 527 546 mi->sample_count++; ··· 531 550 tmp_group_tp_rate[j] = group; 532 551 533 552 for (i = 0; i < MCS_GROUP_RATES; i++) { 534 - if (!(mg->supported & BIT(i))) 553 + if (!(mi->supported[group] & BIT(i))) 535 554 continue; 536 555 537 556 index = MCS_GROUP_RATES * group + i; ··· 617 636 mi->sample_group %= ARRAY_SIZE(minstrel_mcs_groups); 618 637 mg = &mi->groups[mi->sample_group]; 619 638 620 - if (!mg->supported) 639 + if (!mi->supported[mi->sample_group]) 621 640 continue; 622 641 623 642 if (++mg->index >= MCS_GROUP_RATES) { ··· 638 657 while (group > 0) { 639 658 group--; 640 659 641 - if (!mi->groups[group].supported) 660 + if (!mi->supported[group]) 642 661 continue; 643 662 644 663 if (minstrel_mcs_groups[group].streams > ··· 975 994 sample_idx = sample_table[mg->column][mg->index]; 976 995 minstrel_set_next_sample_idx(mi); 977 996 978 - if (!(mg->supported & BIT(sample_idx))) 997 + if (!(mi->supported[sample_group] & BIT(sample_idx))) 979 998 return -1; 980 999 981 1000 mrs = &mg->rates[sample_idx]; ··· 1030 1049 } 1031 1050 1032 1051 static void 1033 - minstrel_ht_check_cck_shortpreamble(struct minstrel_priv *mp, 1034 - struct minstrel_ht_sta *mi, bool val) 1035 - { 1036 - u8 supported = mi->groups[MINSTREL_CCK_GROUP].supported; 1037 - 1038 - if (!supported || !mi->cck_supported_short) 1039 - return; 1040 - 1041 - if (supported & (mi->cck_supported_short << (val * 4))) 1042 - return; 1043 - 1044 - supported ^= mi->cck_supported_short | (mi->cck_supported_short << 4); 1045 - mi->groups[MINSTREL_CCK_GROUP].supported = supported; 1046 - } 1047 - 1048 - static void 1049 1052 minstrel_ht_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta, 1050 1053 struct ieee80211_tx_rate_control *txrc) 1051 1054 { ··· 1052 1087 minstrel_aggr_check(sta, txrc->skb); 1053 1088 1054 1089 info->flags |= mi->tx_flags; 1055 - minstrel_ht_check_cck_shortpreamble(mp, mi, txrc->short_preamble); 1056 1090 1057 1091 #ifdef CONFIG_MAC80211_DEBUGFS 1058 1092 if (mp->fixed_rate_idx != -1) ··· 1118 1154 mi->cck_supported_short |= BIT(i); 1119 1155 } 1120 1156 1121 - mi->groups[MINSTREL_CCK_GROUP].supported = mi->cck_supported; 1157 + mi->supported[MINSTREL_CCK_GROUP] = mi->cck_supported; 1122 1158 } 1123 1159 1124 1160 static void ··· 1132 1168 struct ieee80211_mcs_info *mcs = &sta->ht_cap.mcs; 1133 1169 u16 sta_cap = sta->ht_cap.cap; 1134 1170 struct ieee80211_sta_vht_cap *vht_cap = &sta->vht_cap; 1171 + struct sta_info *sinfo = container_of(sta, struct sta_info, sta); 1135 1172 int use_vht; 1136 1173 int n_supported = 0; 1137 1174 int ack_dur; ··· 1189 1224 u32 gflags = minstrel_mcs_groups[i].flags; 1190 1225 int bw, nss; 1191 1226 1192 - mi->groups[i].supported = 0; 1227 + mi->supported[i] = 0; 1193 1228 if (i == MINSTREL_CCK_GROUP) { 1194 1229 minstrel_ht_update_cck(mp, mi, sband, sta); 1195 1230 continue; ··· 1221 1256 if (use_vht && minstrel_vht_only) 1222 1257 continue; 1223 1258 #endif 1224 - mi->groups[i].supported = mcs->rx_mask[nss - 1]; 1225 - if (mi->groups[i].supported) 1259 + mi->supported[i] = mcs->rx_mask[nss - 1]; 1260 + if (mi->supported[i]) 1226 1261 n_supported++; 1227 1262 continue; 1228 1263 } ··· 1248 1283 else 1249 1284 bw = BW_20; 1250 1285 1251 - mi->groups[i].supported = minstrel_get_valid_vht_rates(bw, nss, 1286 + mi->supported[i] = minstrel_get_valid_vht_rates(bw, nss, 1252 1287 vht_cap->vht_mcs.tx_mcs_map); 1253 1288 1254 - if (mi->groups[i].supported) 1289 + if (mi->supported[i]) 1255 1290 n_supported++; 1256 1291 } 1257 1292 1258 1293 if (!n_supported) 1259 1294 goto use_legacy; 1295 + 1296 + if (test_sta_flag(sinfo, WLAN_STA_SHORT_PREAMBLE)) 1297 + mi->cck_supported_short |= mi->cck_supported_short << 4; 1260 1298 1261 1299 /* create an initial rate table with the lowest supported rates */ 1262 1300 minstrel_ht_update_stats(mp, mi);
+3 -3
net/mac80211/rc80211_minstrel_ht.h
··· 52 52 u8 index; 53 53 u8 column; 54 54 55 - /* bitfield of supported MCS rates of this group */ 56 - u16 supported; 57 - 58 55 /* sorted rate set within a MCS group*/ 59 56 u16 max_group_tp_rate[MAX_THR_RATES]; 60 57 u16 max_group_prob_rate; ··· 97 100 98 101 u8 cck_supported; 99 102 u8 cck_supported_short; 103 + 104 + /* Bitfield of supported MCS rates of all groups */ 105 + u16 supported[MINSTREL_GROUPS_NB]; 100 106 101 107 /* MCS rate group info and statistics */ 102 108 struct minstrel_mcs_group_data groups[MINSTREL_GROUPS_NB];
+16 -16
net/mac80211/rc80211_minstrel_ht_debugfs.c
··· 19 19 minstrel_ht_stats_dump(struct minstrel_ht_sta *mi, int i, char *p) 20 20 { 21 21 const struct mcs_group *mg; 22 - unsigned int j, tp_max, tp_avg, prob, eprob, tx_time; 22 + unsigned int j, tp_max, tp_avg, eprob, tx_time; 23 23 char htmode = '2'; 24 24 char gimode = 'L'; 25 25 u32 gflags; 26 26 27 - if (!mi->groups[i].supported) 27 + if (!mi->supported[i]) 28 28 return p; 29 29 30 30 mg = &minstrel_mcs_groups[i]; ··· 41 41 struct minstrel_rate_stats *mrs = &mi->groups[i].rates[j]; 42 42 static const int bitrates[4] = { 10, 20, 55, 110 }; 43 43 int idx = i * MCS_GROUP_RATES + j; 44 + unsigned int prob_ewmsd; 44 45 45 - if (!(mi->groups[i].supported & BIT(j))) 46 + if (!(mi->supported[i] & BIT(j))) 46 47 continue; 47 48 48 49 if (gflags & IEEE80211_TX_RC_MCS) { ··· 84 83 85 84 tp_max = minstrel_ht_get_tp_avg(mi, i, j, MINSTREL_FRAC(100, 100)); 86 85 tp_avg = minstrel_ht_get_tp_avg(mi, i, j, mrs->prob_ewma); 87 - prob = MINSTREL_TRUNC(mrs->cur_prob * 1000); 88 86 eprob = MINSTREL_TRUNC(mrs->prob_ewma * 1000); 87 + prob_ewmsd = minstrel_get_ewmsd10(mrs); 89 88 90 89 p += sprintf(p, "%4u.%1u %4u.%1u %3u.%1u %3u.%1u" 91 - " %3u.%1u %3u %3u %-3u " 90 + " %3u %3u %-3u " 92 91 "%9llu %-9llu\n", 93 92 tp_max / 10, tp_max % 10, 94 93 tp_avg / 10, tp_avg % 10, 95 94 eprob / 10, eprob % 10, 96 - mrs->prob_ewmsd / 10, mrs->prob_ewmsd % 10, 97 - prob / 10, prob % 10, 95 + prob_ewmsd / 10, prob_ewmsd % 10, 98 96 mrs->retry_count, 99 97 mrs->last_success, 100 98 mrs->last_attempts, ··· 130 130 131 131 p += sprintf(p, "\n"); 132 132 p += sprintf(p, 133 - " best ____________rate__________ ________statistics________ ________last_______ ______sum-of________\n"); 133 + " best ____________rate__________ ________statistics________ _____last____ ______sum-of________\n"); 134 134 p += sprintf(p, 135 - "mode guard # rate [name idx airtime max_tp] [avg(tp) avg(prob) sd(prob)] [prob.|retry|suc|att] [#success | #attempts]\n"); 135 + "mode guard # rate [name idx airtime max_tp] [avg(tp) avg(prob) sd(prob)] [retry|suc|att] [#success | #attempts]\n"); 136 136 137 137 p = minstrel_ht_stats_dump(mi, MINSTREL_CCK_GROUP, p); 138 138 for (i = 0; i < MINSTREL_CCK_GROUP; i++) ··· 165 165 minstrel_ht_stats_csv_dump(struct minstrel_ht_sta *mi, int i, char *p) 166 166 { 167 167 const struct mcs_group *mg; 168 - unsigned int j, tp_max, tp_avg, prob, eprob, tx_time; 168 + unsigned int j, tp_max, tp_avg, eprob, tx_time; 169 169 char htmode = '2'; 170 170 char gimode = 'L'; 171 171 u32 gflags; 172 172 173 - if (!mi->groups[i].supported) 173 + if (!mi->supported[i]) 174 174 return p; 175 175 176 176 mg = &minstrel_mcs_groups[i]; ··· 187 187 struct minstrel_rate_stats *mrs = &mi->groups[i].rates[j]; 188 188 static const int bitrates[4] = { 10, 20, 55, 110 }; 189 189 int idx = i * MCS_GROUP_RATES + j; 190 + unsigned int prob_ewmsd; 190 191 191 - if (!(mi->groups[i].supported & BIT(j))) 192 + if (!(mi->supported[i] & BIT(j))) 192 193 continue; 193 194 194 195 if (gflags & IEEE80211_TX_RC_MCS) { ··· 227 226 228 227 tp_max = minstrel_ht_get_tp_avg(mi, i, j, MINSTREL_FRAC(100, 100)); 229 228 tp_avg = minstrel_ht_get_tp_avg(mi, i, j, mrs->prob_ewma); 230 - prob = MINSTREL_TRUNC(mrs->cur_prob * 1000); 231 229 eprob = MINSTREL_TRUNC(mrs->prob_ewma * 1000); 230 + prob_ewmsd = minstrel_get_ewmsd10(mrs); 232 231 233 - p += sprintf(p, "%u.%u,%u.%u,%u.%u,%u.%u,%u.%u,%u,%u," 232 + p += sprintf(p, "%u.%u,%u.%u,%u.%u,%u.%u,%u,%u," 234 233 "%u,%llu,%llu,", 235 234 tp_max / 10, tp_max % 10, 236 235 tp_avg / 10, tp_avg % 10, 237 236 eprob / 10, eprob % 10, 238 - mrs->prob_ewmsd / 10, mrs->prob_ewmsd % 10, 239 - prob / 10, prob % 10, 237 + prob_ewmsd / 10, prob_ewmsd % 10, 240 238 mrs->retry_count, 241 239 mrs->last_success, 242 240 mrs->last_attempts,
-4
net/mac80211/rx.c
··· 1908 1908 unsigned int frag, seq; 1909 1909 struct ieee80211_fragment_entry *entry; 1910 1910 struct sk_buff *skb; 1911 - struct ieee80211_rx_status *status; 1912 1911 1913 1912 hdr = (struct ieee80211_hdr *)rx->skb->data; 1914 1913 fc = hdr->frame_control; ··· 2032 2033 memcpy(skb_put(rx->skb, skb->len), skb->data, skb->len); 2033 2034 dev_kfree_skb(skb); 2034 2035 } 2035 - 2036 - /* Complete frame has been reassembled - process it now */ 2037 - status = IEEE80211_SKB_RXCB(rx->skb); 2038 2036 2039 2037 out: 2040 2038 ieee80211_led_rx(rx->local);
+3 -5
net/mac80211/scan.c
··· 1120 1120 u32 rate_masks[NUM_NL80211_BANDS] = {}; 1121 1121 u8 bands_used = 0; 1122 1122 u8 *ie; 1123 - size_t len; 1124 1123 1125 1124 iebufsz = local->scan_ies_len + req->ie_len; 1126 1125 ··· 1144 1145 1145 1146 ieee80211_prepare_scan_chandef(&chandef, req->scan_width); 1146 1147 1147 - len = ieee80211_build_preq_ies(local, ie, num_bands * iebufsz, 1148 - &sched_scan_ies, req->ie, 1149 - req->ie_len, bands_used, 1150 - rate_masks, &chandef); 1148 + ieee80211_build_preq_ies(local, ie, num_bands * iebufsz, 1149 + &sched_scan_ies, req->ie, 1150 + req->ie_len, bands_used, rate_masks, &chandef); 1151 1151 1152 1152 ret = drv_sched_scan_start(local, sdata, req, &sched_scan_ies); 1153 1153 if (ret == 0) {
+7 -11
net/mac80211/sta_info.c
··· 513 513 { 514 514 struct ieee80211_local *local = sta->local; 515 515 struct ieee80211_sub_if_data *sdata = sta->sdata; 516 - struct station_info *sinfo; 516 + struct station_info *sinfo = NULL; 517 517 int err = 0; 518 518 519 519 lockdep_assert_held(&local->sta_mtx); 520 520 521 - sinfo = kzalloc(sizeof(struct station_info), GFP_KERNEL); 522 - if (!sinfo) { 523 - err = -ENOMEM; 524 - goto out_err; 525 - } 526 - 527 521 /* check if STA exists already */ 528 522 if (sta_info_get_bss(sdata, sta->sta.addr)) { 529 523 err = -EEXIST; 524 + goto out_err; 525 + } 526 + 527 + sinfo = kzalloc(sizeof(struct station_info), GFP_KERNEL); 528 + if (!sinfo) { 529 + err = -ENOMEM; 530 530 goto out_err; 531 531 } 532 532 ··· 2051 2051 { 2052 2052 struct ieee80211_sub_if_data *sdata = sta->sdata; 2053 2053 struct ieee80211_local *local = sdata->local; 2054 - struct rate_control_ref *ref = NULL; 2055 2054 u32 thr = 0; 2056 2055 int i, ac, cpu; 2057 2056 struct ieee80211_sta_rx_stats *last_rxstats; 2058 2057 2059 2058 last_rxstats = sta_get_last_rx_stats(sta); 2060 - 2061 - if (test_sta_flag(sta, WLAN_STA_RATE_CONTROL)) 2062 - ref = local->rate_ctrl; 2063 2059 2064 2060 sinfo->generation = sdata->local->sta_generation; 2065 2061
+6 -2
net/mac80211/status.c
··· 541 541 } else if (info->ack_frame_id) { 542 542 ieee80211_report_ack_skb(local, info, acked, dropped); 543 543 } 544 + 545 + if (!dropped && skb->destructor) { 546 + skb->wifi_acked_valid = 1; 547 + skb->wifi_acked = acked; 548 + } 544 549 } 545 550 546 551 /* ··· 638 633 struct ieee80211_local *local = hw_to_local(hw); 639 634 struct ieee80211_supported_band *sband; 640 635 int retry_count; 641 - int rates_idx; 642 636 bool acked, noack_success; 643 637 644 - rates_idx = ieee80211_tx_get_rates(hw, info, &retry_count); 638 + ieee80211_tx_get_rates(hw, info, &retry_count); 645 639 646 640 sband = hw->wiphy->bands[info->band]; 647 641
+126 -6
net/mac80211/tx.c
··· 16 16 #include <linux/kernel.h> 17 17 #include <linux/slab.h> 18 18 #include <linux/skbuff.h> 19 + #include <linux/if_vlan.h> 19 20 #include <linux/etherdevice.h> 20 21 #include <linux/bitmap.h> 21 22 #include <linux/rcupdate.h> ··· 64 63 struct ieee80211_chanctx_conf *chanctx_conf; 65 64 u32 rate_flags = 0; 66 65 66 + /* assume HW handles this */ 67 + if (tx->rate.flags & (IEEE80211_TX_RC_MCS | IEEE80211_TX_RC_VHT_MCS)) 68 + return 0; 69 + 67 70 rcu_read_lock(); 68 71 chanctx_conf = rcu_dereference(tx->sdata->vif.chanctx_conf); 69 72 if (chanctx_conf) { ··· 75 70 rate_flags = ieee80211_chandef_rate_flags(&chanctx_conf->def); 76 71 } 77 72 rcu_read_unlock(); 78 - 79 - /* assume HW handles this */ 80 - if (tx->rate.flags & (IEEE80211_TX_RC_MCS | IEEE80211_TX_RC_VHT_MCS)) 81 - return 0; 82 73 83 74 /* uh huh? */ 84 75 if (WARN_ON_ONCE(tx->rate.idx < 0)) ··· 3575 3574 rcu_read_unlock(); 3576 3575 } 3577 3576 3577 + static int ieee80211_change_da(struct sk_buff *skb, struct sta_info *sta) 3578 + { 3579 + struct ethhdr *eth; 3580 + int err; 3581 + 3582 + err = skb_ensure_writable(skb, ETH_HLEN); 3583 + if (unlikely(err)) 3584 + return err; 3585 + 3586 + eth = (void *)skb->data; 3587 + ether_addr_copy(eth->h_dest, sta->sta.addr); 3588 + 3589 + return 0; 3590 + } 3591 + 3592 + static bool ieee80211_multicast_to_unicast(struct sk_buff *skb, 3593 + struct net_device *dev) 3594 + { 3595 + struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 3596 + const struct ethhdr *eth = (void *)skb->data; 3597 + const struct vlan_ethhdr *ethvlan = (void *)skb->data; 3598 + __be16 ethertype; 3599 + 3600 + if (likely(!is_multicast_ether_addr(eth->h_dest))) 3601 + return false; 3602 + 3603 + switch (sdata->vif.type) { 3604 + case NL80211_IFTYPE_AP_VLAN: 3605 + if (sdata->u.vlan.sta) 3606 + return false; 3607 + if (sdata->wdev.use_4addr) 3608 + return false; 3609 + /* fall through */ 3610 + case NL80211_IFTYPE_AP: 3611 + /* check runtime toggle for this bss */ 3612 + if (!sdata->bss->multicast_to_unicast) 3613 + return false; 3614 + break; 3615 + default: 3616 + return false; 3617 + } 3618 + 3619 + /* multicast to unicast conversion only for some payload */ 3620 + ethertype = eth->h_proto; 3621 + if (ethertype == htons(ETH_P_8021Q) && skb->len >= VLAN_ETH_HLEN) 3622 + ethertype = ethvlan->h_vlan_encapsulated_proto; 3623 + switch (ethertype) { 3624 + case htons(ETH_P_ARP): 3625 + case htons(ETH_P_IP): 3626 + case htons(ETH_P_IPV6): 3627 + break; 3628 + default: 3629 + return false; 3630 + } 3631 + 3632 + return true; 3633 + } 3634 + 3635 + static void 3636 + ieee80211_convert_to_unicast(struct sk_buff *skb, struct net_device *dev, 3637 + struct sk_buff_head *queue) 3638 + { 3639 + struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 3640 + struct ieee80211_local *local = sdata->local; 3641 + const struct ethhdr *eth = (struct ethhdr *)skb->data; 3642 + struct sta_info *sta, *first = NULL; 3643 + struct sk_buff *cloned_skb; 3644 + 3645 + rcu_read_lock(); 3646 + 3647 + list_for_each_entry_rcu(sta, &local->sta_list, list) { 3648 + if (sdata != sta->sdata) 3649 + /* AP-VLAN mismatch */ 3650 + continue; 3651 + if (unlikely(ether_addr_equal(eth->h_source, sta->sta.addr))) 3652 + /* do not send back to source */ 3653 + continue; 3654 + if (!first) { 3655 + first = sta; 3656 + continue; 3657 + } 3658 + cloned_skb = skb_clone(skb, GFP_ATOMIC); 3659 + if (!cloned_skb) 3660 + goto multicast; 3661 + if (unlikely(ieee80211_change_da(cloned_skb, sta))) { 3662 + dev_kfree_skb(cloned_skb); 3663 + goto multicast; 3664 + } 3665 + __skb_queue_tail(queue, cloned_skb); 3666 + } 3667 + 3668 + if (likely(first)) { 3669 + if (unlikely(ieee80211_change_da(skb, first))) 3670 + goto multicast; 3671 + __skb_queue_tail(queue, skb); 3672 + } else { 3673 + /* no STA connected, drop */ 3674 + kfree_skb(skb); 3675 + skb = NULL; 3676 + } 3677 + 3678 + goto out; 3679 + multicast: 3680 + __skb_queue_purge(queue); 3681 + __skb_queue_tail(queue, skb); 3682 + out: 3683 + rcu_read_unlock(); 3684 + } 3685 + 3578 3686 /** 3579 3687 * ieee80211_subif_start_xmit - netif start_xmit function for 802.3 vifs 3580 3688 * @skb: packet to be sent ··· 3694 3584 netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, 3695 3585 struct net_device *dev) 3696 3586 { 3697 - __ieee80211_subif_start_xmit(skb, dev, 0); 3587 + if (unlikely(ieee80211_multicast_to_unicast(skb, dev))) { 3588 + struct sk_buff_head queue; 3589 + 3590 + __skb_queue_head_init(&queue); 3591 + ieee80211_convert_to_unicast(skb, dev, &queue); 3592 + while ((skb = __skb_dequeue(&queue))) 3593 + __ieee80211_subif_start_xmit(skb, dev, 0); 3594 + } else { 3595 + __ieee80211_subif_start_xmit(skb, dev, 0); 3596 + } 3597 + 3698 3598 return NETDEV_TX_OK; 3699 3599 } 3700 3600 ··· 4197 4077 } 4198 4078 4199 4079 if (ifmsh->sync_ops) 4200 - ifmsh->sync_ops->adjust_tbtt(sdata, beacon); 4080 + ifmsh->sync_ops->adjust_tsf(sdata, beacon); 4201 4081 4202 4082 skb = dev_alloc_skb(local->tx_headroom + 4203 4083 beacon->head_len +
-4
net/mac80211/vht.c
··· 436 436 struct sta_info *sta, u8 opmode, 437 437 enum nl80211_band band) 438 438 { 439 - struct ieee80211_local *local = sdata->local; 440 - struct ieee80211_supported_band *sband; 441 439 enum ieee80211_sta_rx_bandwidth new_bw; 442 440 u32 changed = 0; 443 441 u8 nss; 444 - 445 - sband = local->hw.wiphy->bands[band]; 446 442 447 443 /* ignore - no support for BF yet */ 448 444 if (opmode & IEEE80211_OPMODE_NOTIF_RX_NSS_TYPE_BF)
+2 -1
net/mac80211/wep.c
··· 293 293 return RX_DROP_UNUSABLE; 294 294 ieee80211_wep_remove_iv(rx->local, rx->skb, rx->key); 295 295 /* remove ICV */ 296 - if (pskb_trim(rx->skb, rx->skb->len - IEEE80211_WEP_ICV_LEN)) 296 + if (!(status->flag & RX_FLAG_ICV_STRIPPED) && 297 + pskb_trim(rx->skb, rx->skb->len - IEEE80211_WEP_ICV_LEN)) 297 298 return RX_DROP_UNUSABLE; 298 299 } 299 300
+2 -1
net/mac80211/wpa.c
··· 294 294 return RX_DROP_UNUSABLE; 295 295 296 296 /* Trim ICV */ 297 - skb_trim(skb, skb->len - IEEE80211_TKIP_ICV_LEN); 297 + if (!(status->flag & RX_FLAG_ICV_STRIPPED)) 298 + skb_trim(skb, skb->len - IEEE80211_TKIP_ICV_LEN); 298 299 299 300 /* Remove IV */ 300 301 memmove(skb->data + IEEE80211_TKIP_IV_LEN, skb->data, hdrlen);
+85 -15
net/rfkill/core.c
··· 176 176 { 177 177 led_trigger_unregister(&rfkill->led_trigger); 178 178 } 179 + 180 + static struct led_trigger rfkill_any_led_trigger; 181 + static struct work_struct rfkill_any_work; 182 + 183 + static void rfkill_any_led_trigger_worker(struct work_struct *work) 184 + { 185 + enum led_brightness brightness = LED_OFF; 186 + struct rfkill *rfkill; 187 + 188 + mutex_lock(&rfkill_global_mutex); 189 + list_for_each_entry(rfkill, &rfkill_list, node) { 190 + if (!(rfkill->state & RFKILL_BLOCK_ANY)) { 191 + brightness = LED_FULL; 192 + break; 193 + } 194 + } 195 + mutex_unlock(&rfkill_global_mutex); 196 + 197 + led_trigger_event(&rfkill_any_led_trigger, brightness); 198 + } 199 + 200 + static void rfkill_any_led_trigger_event(void) 201 + { 202 + schedule_work(&rfkill_any_work); 203 + } 204 + 205 + static void rfkill_any_led_trigger_activate(struct led_classdev *led_cdev) 206 + { 207 + rfkill_any_led_trigger_event(); 208 + } 209 + 210 + static int rfkill_any_led_trigger_register(void) 211 + { 212 + INIT_WORK(&rfkill_any_work, rfkill_any_led_trigger_worker); 213 + rfkill_any_led_trigger.name = "rfkill-any"; 214 + rfkill_any_led_trigger.activate = rfkill_any_led_trigger_activate; 215 + return led_trigger_register(&rfkill_any_led_trigger); 216 + } 217 + 218 + static void rfkill_any_led_trigger_unregister(void) 219 + { 220 + led_trigger_unregister(&rfkill_any_led_trigger); 221 + cancel_work_sync(&rfkill_any_work); 222 + } 179 223 #else 180 224 static void rfkill_led_trigger_event(struct rfkill *rfkill) 181 225 { ··· 231 187 } 232 188 233 189 static inline void rfkill_led_trigger_unregister(struct rfkill *rfkill) 190 + { 191 + } 192 + 193 + static void rfkill_any_led_trigger_event(void) 194 + { 195 + } 196 + 197 + static int rfkill_any_led_trigger_register(void) 198 + { 199 + return 0; 200 + } 201 + 202 + static void rfkill_any_led_trigger_unregister(void) 234 203 { 235 204 } 236 205 #endif /* CONFIG_RFKILL_LEDS */ ··· 354 297 spin_unlock_irqrestore(&rfkill->lock, flags); 355 298 356 299 rfkill_led_trigger_event(rfkill); 300 + rfkill_any_led_trigger_event(); 357 301 358 302 if (prev != curr) 359 303 rfkill_event(rfkill); ··· 535 477 spin_unlock_irqrestore(&rfkill->lock, flags); 536 478 537 479 rfkill_led_trigger_event(rfkill); 480 + rfkill_any_led_trigger_event(); 538 481 539 - if (!rfkill->registered) 540 - return ret; 541 - 542 - if (prev != blocked) 482 + if (rfkill->registered && prev != blocked) 543 483 schedule_work(&rfkill->uevent_work); 544 484 545 485 return ret; ··· 579 523 schedule_work(&rfkill->uevent_work); 580 524 581 525 rfkill_led_trigger_event(rfkill); 526 + rfkill_any_led_trigger_event(); 582 527 583 528 return blocked; 584 529 } ··· 629 572 schedule_work(&rfkill->uevent_work); 630 573 631 574 rfkill_led_trigger_event(rfkill); 575 + rfkill_any_led_trigger_event(); 632 576 } 633 577 } 634 578 EXPORT_SYMBOL(rfkill_set_states); ··· 1046 988 #endif 1047 989 } 1048 990 991 + rfkill_any_led_trigger_event(); 1049 992 rfkill_send_events(rfkill, RFKILL_OP_ADD); 1050 993 1051 994 mutex_unlock(&rfkill_global_mutex); ··· 1079 1020 mutex_lock(&rfkill_global_mutex); 1080 1021 rfkill_send_events(rfkill, RFKILL_OP_DEL); 1081 1022 list_del_init(&rfkill->node); 1023 + rfkill_any_led_trigger_event(); 1082 1024 mutex_unlock(&rfkill_global_mutex); 1083 1025 1084 1026 rfkill_led_trigger_unregister(rfkill); ··· 1326 1266 1327 1267 error = class_register(&rfkill_class); 1328 1268 if (error) 1329 - goto out; 1269 + goto error_class; 1330 1270 1331 1271 error = misc_register(&rfkill_miscdev); 1332 - if (error) { 1333 - class_unregister(&rfkill_class); 1334 - goto out; 1335 - } 1272 + if (error) 1273 + goto error_misc; 1274 + 1275 + error = rfkill_any_led_trigger_register(); 1276 + if (error) 1277 + goto error_led_trigger; 1336 1278 1337 1279 #ifdef CONFIG_RFKILL_INPUT 1338 1280 error = rfkill_handler_init(); 1339 - if (error) { 1340 - misc_deregister(&rfkill_miscdev); 1341 - class_unregister(&rfkill_class); 1342 - goto out; 1343 - } 1281 + if (error) 1282 + goto error_input; 1344 1283 #endif 1345 1284 1346 - out: 1285 + return 0; 1286 + 1287 + #ifdef CONFIG_RFKILL_INPUT 1288 + error_input: 1289 + rfkill_any_led_trigger_unregister(); 1290 + #endif 1291 + error_led_trigger: 1292 + misc_deregister(&rfkill_miscdev); 1293 + error_misc: 1294 + class_unregister(&rfkill_class); 1295 + error_class: 1347 1296 return error; 1348 1297 } 1349 1298 subsys_initcall(rfkill_init); ··· 1362 1293 #ifdef CONFIG_RFKILL_INPUT 1363 1294 rfkill_handler_exit(); 1364 1295 #endif 1296 + rfkill_any_led_trigger_unregister(); 1365 1297 misc_deregister(&rfkill_miscdev); 1366 1298 class_unregister(&rfkill_class); 1367 1299 }
+1
net/wireless/Makefile
··· 11 11 12 12 cfg80211-y += core.o sysfs.o radiotap.o util.o reg.o scan.o nl80211.o 13 13 cfg80211-y += mlme.o ibss.o sme.o chan.o ethtool.o mesh.o ap.o trace.o ocb.o 14 + cfg80211-$(CONFIG_OF) += of.o 14 15 cfg80211-$(CONFIG_CFG80211_DEBUGFS) += debugfs.o 15 16 cfg80211-$(CONFIG_CFG80211_WEXT) += wext-compat.o wext-sme.o 16 17 cfg80211-$(CONFIG_CFG80211_INTERNAL_REGDB) += regdb.o
+3
net/wireless/core.c
··· 1142 1142 wdev->iftype == NL80211_IFTYPE_ADHOC) && !wdev->use_4addr) 1143 1143 dev->priv_flags |= IFF_DONT_BRIDGE; 1144 1144 1145 + INIT_WORK(&wdev->disconnect_wk, cfg80211_autodisconnect_wk); 1146 + 1145 1147 nl80211_notify_iface(rdev, wdev, NL80211_CMD_NEW_INTERFACE); 1146 1148 break; 1147 1149 case NETDEV_GOING_DOWN: ··· 1232 1230 #ifdef CONFIG_CFG80211_WEXT 1233 1231 kzfree(wdev->wext.keys); 1234 1232 #endif 1233 + flush_work(&wdev->disconnect_wk); 1235 1234 } 1236 1235 /* 1237 1236 * synchronise (so that we won't find this netdev
+7 -1
net/wireless/core.h
··· 228 228 size_t resp_ie_len; 229 229 struct cfg80211_bss *bss; 230 230 int status; /* -1 = failed; 0..65535 = status code */ 231 + enum nl80211_timeout_reason timeout_reason; 231 232 } cr; 232 233 struct { 233 234 const u8 *req_ie; ··· 389 388 const u8 *req_ie, size_t req_ie_len, 390 389 const u8 *resp_ie, size_t resp_ie_len, 391 390 int status, bool wextev, 392 - struct cfg80211_bss *bss); 391 + struct cfg80211_bss *bss, 392 + enum nl80211_timeout_reason timeout_reason); 393 393 void __cfg80211_disconnected(struct net_device *dev, const u8 *ie, 394 394 size_t ie_len, u16 reason, bool from_ap); 395 395 int cfg80211_disconnect(struct cfg80211_registered_device *rdev, ··· 402 400 const u8 *resp_ie, size_t resp_ie_len); 403 401 int cfg80211_mgd_wext_connect(struct cfg80211_registered_device *rdev, 404 402 struct wireless_dev *wdev); 403 + void cfg80211_autodisconnect_wk(struct work_struct *work); 405 404 406 405 /* SME implementation */ 407 406 void cfg80211_conn_work(struct work_struct *work); ··· 432 429 u32 *flags, struct vif_params *params); 433 430 void cfg80211_process_rdev_events(struct cfg80211_registered_device *rdev); 434 431 void cfg80211_process_wdev_events(struct wireless_dev *wdev); 432 + 433 + bool cfg80211_does_bw_fit_range(const struct ieee80211_freq_range *freq_range, 434 + u32 center_freq_khz, u32 bw_khz); 435 435 436 436 /** 437 437 * cfg80211_chandef_dfs_usable - checks if chandef is DFS usable
+26 -3
net/wireless/mlme.c
··· 48 48 /* update current_bss etc., consumes the bss reference */ 49 49 __cfg80211_connect_result(dev, mgmt->bssid, NULL, 0, ie, len - ieoffs, 50 50 status_code, 51 - status_code == WLAN_STATUS_SUCCESS, bss); 51 + status_code == WLAN_STATUS_SUCCESS, bss, 52 + NL80211_TIMEOUT_UNSPECIFIED); 52 53 } 53 54 EXPORT_SYMBOL(cfg80211_rx_assoc_resp); 54 55 ··· 345 344 (!wdev->current_bss || 346 345 !ether_addr_equal(wdev->current_bss->pub.bssid, bssid))) 347 346 return 0; 347 + 348 + if (ether_addr_equal(wdev->disconnect_bssid, bssid) || 349 + (wdev->current_bss && 350 + ether_addr_equal(wdev->current_bss->pub.bssid, bssid))) 351 + wdev->conn_owner_nlportid = 0; 348 352 349 353 return rdev_deauth(rdev, dev, &req); 350 354 } ··· 663 657 return err; 664 658 } 665 659 666 - if (!ether_addr_equal(mgmt->sa, wdev_address(wdev))) 667 - return -EINVAL; 660 + if (!ether_addr_equal(mgmt->sa, wdev_address(wdev))) { 661 + /* Allow random TA to be used with Public Action frames if the 662 + * driver has indicated support for this. Otherwise, only allow 663 + * the local address to be used. 664 + */ 665 + if (!ieee80211_is_action(mgmt->frame_control) || 666 + mgmt->u.action.category != WLAN_CATEGORY_PUBLIC) 667 + return -EINVAL; 668 + if (!wdev->current_bss && 669 + !wiphy_ext_feature_isset( 670 + &rdev->wiphy, 671 + NL80211_EXT_FEATURE_MGMT_TX_RANDOM_TA)) 672 + return -EINVAL; 673 + if (wdev->current_bss && 674 + !wiphy_ext_feature_isset( 675 + &rdev->wiphy, 676 + NL80211_EXT_FEATURE_MGMT_TX_RANDOM_TA_CONNECTED)) 677 + return -EINVAL; 678 + } 668 679 669 680 /* Transmit the Action frame as requested by user space */ 670 681 return rdev_mgmt_tx(rdev, wdev, params, cookie);
+93 -44
net/wireless/nl80211.c
··· 405 405 [NL80211_ATTR_FILS_NONCES] = { .len = 2 * FILS_NONCE_LEN }, 406 406 [NL80211_ATTR_MULTICAST_TO_UNICAST_ENABLED] = { .type = NLA_FLAG, }, 407 407 [NL80211_ATTR_BSSID] = { .len = ETH_ALEN }, 408 + [NL80211_ATTR_SCHED_SCAN_RELATIVE_RSSI] = { .type = NLA_S8 }, 409 + [NL80211_ATTR_SCHED_SCAN_RSSI_ADJUST] = { 410 + .len = sizeof(struct nl80211_bss_select_rssi_adjust) 411 + }, 412 + [NL80211_ATTR_TIMEOUT_REASON] = { .type = NLA_U32 }, 408 413 }; 409 414 410 415 /* policy for the key attributes */ ··· 6780 6775 6781 6776 /* 6782 6777 * If scan plans are not specified, 6783 - * %NL80211_ATTR_SCHED_SCAN_INTERVAL must be specified. In this 6778 + * %NL80211_ATTR_SCHED_SCAN_INTERVAL will be specified. In this 6784 6779 * case one scan plan will be set with the specified scan 6785 6780 * interval and infinite number of iterations. 6786 6781 */ 6787 - if (!attrs[NL80211_ATTR_SCHED_SCAN_INTERVAL]) 6788 - return -EINVAL; 6789 - 6790 6782 interval = nla_get_u32(attrs[NL80211_ATTR_SCHED_SCAN_INTERVAL]); 6791 6783 if (!interval) 6792 6784 return -EINVAL; ··· 6953 6951 } 6954 6952 6955 6953 if (!n_plans || n_plans > wiphy->max_sched_scan_plans) 6954 + return ERR_PTR(-EINVAL); 6955 + 6956 + if (!wiphy_ext_feature_isset( 6957 + wiphy, NL80211_EXT_FEATURE_SCHED_SCAN_RELATIVE_RSSI) && 6958 + (attrs[NL80211_ATTR_SCHED_SCAN_RELATIVE_RSSI] || 6959 + attrs[NL80211_ATTR_SCHED_SCAN_RSSI_ADJUST])) 6956 6960 return ERR_PTR(-EINVAL); 6957 6961 6958 6962 request = kzalloc(sizeof(*request) ··· 7166 7158 if (attrs[NL80211_ATTR_SCHED_SCAN_DELAY]) 7167 7159 request->delay = 7168 7160 nla_get_u32(attrs[NL80211_ATTR_SCHED_SCAN_DELAY]); 7161 + 7162 + if (attrs[NL80211_ATTR_SCHED_SCAN_RELATIVE_RSSI]) { 7163 + request->relative_rssi = nla_get_s8( 7164 + attrs[NL80211_ATTR_SCHED_SCAN_RELATIVE_RSSI]); 7165 + request->relative_rssi_set = true; 7166 + } 7167 + 7168 + if (request->relative_rssi_set && 7169 + attrs[NL80211_ATTR_SCHED_SCAN_RSSI_ADJUST]) { 7170 + struct nl80211_bss_select_rssi_adjust *rssi_adjust; 7171 + 7172 + rssi_adjust = nla_data( 7173 + attrs[NL80211_ATTR_SCHED_SCAN_RSSI_ADJUST]); 7174 + request->rssi_adjust.band = rssi_adjust->band; 7175 + request->rssi_adjust.delta = rssi_adjust->delta; 7176 + if (!is_band_valid(wiphy, request->rssi_adjust.band)) { 7177 + err = -EINVAL; 7178 + goto out_free; 7179 + } 7180 + } 7169 7181 7170 7182 err = nl80211_parse_sched_scan_plans(wiphy, n_plans, request, attrs); 7171 7183 if (err) ··· 8081 8053 err = nl80211_crypto_settings(rdev, info, &req.crypto, 1); 8082 8054 if (!err) { 8083 8055 wdev_lock(dev->ieee80211_ptr); 8056 + 8084 8057 err = cfg80211_mlme_assoc(rdev, dev, chan, bssid, 8085 8058 ssid, ssid_len, &req); 8059 + 8060 + if (!err && info->attrs[NL80211_ATTR_SOCKET_OWNER]) { 8061 + dev->ieee80211_ptr->conn_owner_nlportid = 8062 + info->snd_portid; 8063 + memcpy(dev->ieee80211_ptr->disconnect_bssid, 8064 + bssid, ETH_ALEN); 8065 + } 8066 + 8086 8067 wdev_unlock(dev->ieee80211_ptr); 8087 8068 } 8088 8069 ··· 8810 8773 } 8811 8774 8812 8775 wdev_lock(dev->ieee80211_ptr); 8776 + 8813 8777 err = cfg80211_connect(rdev, dev, &connect, connkeys, 8814 8778 connect.prev_bssid); 8815 - wdev_unlock(dev->ieee80211_ptr); 8816 8779 if (err) 8817 8780 kzfree(connkeys); 8781 + 8782 + if (!err && info->attrs[NL80211_ATTR_SOCKET_OWNER]) { 8783 + dev->ieee80211_ptr->conn_owner_nlportid = info->snd_portid; 8784 + if (connect.bssid) 8785 + memcpy(dev->ieee80211_ptr->disconnect_bssid, 8786 + connect.bssid, ETH_ALEN); 8787 + else 8788 + memset(dev->ieee80211_ptr->disconnect_bssid, 8789 + 0, ETH_ALEN); 8790 + } 8791 + 8792 + wdev_unlock(dev->ieee80211_ptr); 8793 + 8818 8794 return err; 8819 8795 } 8820 8796 ··· 9722 9672 9723 9673 if (nla_put_u32(msg, NL80211_ATTR_SCHED_SCAN_DELAY, req->delay)) 9724 9674 return -ENOBUFS; 9675 + 9676 + if (req->relative_rssi_set) { 9677 + struct nl80211_bss_select_rssi_adjust rssi_adjust; 9678 + 9679 + if (nla_put_s8(msg, NL80211_ATTR_SCHED_SCAN_RELATIVE_RSSI, 9680 + req->relative_rssi)) 9681 + return -ENOBUFS; 9682 + 9683 + rssi_adjust.band = req->rssi_adjust.band; 9684 + rssi_adjust.delta = req->rssi_adjust.delta; 9685 + if (nla_put(msg, NL80211_ATTR_SCHED_SCAN_RSSI_ADJUST, 9686 + sizeof(rssi_adjust), &rssi_adjust)) 9687 + return -ENOBUFS; 9688 + } 9725 9689 9726 9690 freqs = nla_nest_start(msg, NL80211_ATTR_SCAN_FREQUENCIES); 9727 9691 if (!freqs) ··· 11871 11807 const struct nlattr *nla; 11872 11808 bool enabled; 11873 11809 11874 - if (netif_running(dev)) 11875 - return -EBUSY; 11876 - 11877 11810 if (!rdev->ops->set_multicast_to_unicast) 11878 11811 return -EOPNOTSUPP; 11879 11812 ··· 12871 12810 return -ENOBUFS; 12872 12811 } 12873 12812 12874 - static int nl80211_send_scan_msg(struct sk_buff *msg, 12813 + static int nl80211_prep_scan_msg(struct sk_buff *msg, 12875 12814 struct cfg80211_registered_device *rdev, 12876 12815 struct wireless_dev *wdev, 12877 12816 u32 portid, u32 seq, int flags, ··· 12902 12841 } 12903 12842 12904 12843 static int 12905 - nl80211_send_sched_scan_msg(struct sk_buff *msg, 12844 + nl80211_prep_sched_scan_msg(struct sk_buff *msg, 12906 12845 struct cfg80211_registered_device *rdev, 12907 12846 struct net_device *netdev, 12908 12847 u32 portid, u32 seq, int flags, u32 cmd) ··· 12934 12873 if (!msg) 12935 12874 return; 12936 12875 12937 - if (nl80211_send_scan_msg(msg, rdev, wdev, 0, 0, 0, 12876 + if (nl80211_prep_scan_msg(msg, rdev, wdev, 0, 0, 0, 12938 12877 NL80211_CMD_TRIGGER_SCAN) < 0) { 12939 12878 nlmsg_free(msg); 12940 12879 return; ··· 12953 12892 if (!msg) 12954 12893 return NULL; 12955 12894 12956 - if (nl80211_send_scan_msg(msg, rdev, wdev, 0, 0, 0, 12895 + if (nl80211_prep_scan_msg(msg, rdev, wdev, 0, 0, 0, 12957 12896 aborted ? NL80211_CMD_SCAN_ABORTED : 12958 12897 NL80211_CMD_NEW_SCAN_RESULTS) < 0) { 12959 12898 nlmsg_free(msg); ··· 12963 12902 return msg; 12964 12903 } 12965 12904 12966 - void nl80211_send_scan_result(struct cfg80211_registered_device *rdev, 12967 - struct sk_buff *msg) 12905 + /* send message created by nl80211_build_scan_msg() */ 12906 + void nl80211_send_scan_msg(struct cfg80211_registered_device *rdev, 12907 + struct sk_buff *msg) 12968 12908 { 12969 12909 if (!msg) 12970 12910 return; 12971 - 12972 - genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0, 12973 - NL80211_MCGRP_SCAN, GFP_KERNEL); 12974 - } 12975 - 12976 - void nl80211_send_sched_scan_results(struct cfg80211_registered_device *rdev, 12977 - struct net_device *netdev) 12978 - { 12979 - struct sk_buff *msg; 12980 - 12981 - msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 12982 - if (!msg) 12983 - return; 12984 - 12985 - if (nl80211_send_sched_scan_msg(msg, rdev, netdev, 0, 0, 0, 12986 - NL80211_CMD_SCHED_SCAN_RESULTS) < 0) { 12987 - nlmsg_free(msg); 12988 - return; 12989 - } 12990 12911 12991 12912 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0, 12992 12913 NL80211_MCGRP_SCAN, GFP_KERNEL); ··· 12983 12940 if (!msg) 12984 12941 return; 12985 12942 12986 - if (nl80211_send_sched_scan_msg(msg, rdev, netdev, 0, 0, 0, cmd) < 0) { 12943 + if (nl80211_prep_sched_scan_msg(msg, rdev, netdev, 0, 0, 0, cmd) < 0) { 12987 12944 nlmsg_free(msg); 12988 12945 return; 12989 12946 } ··· 13085 13042 struct sk_buff *msg; 13086 13043 void *hdr; 13087 13044 13088 - msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp); 13045 + msg = nlmsg_new(100 + len, gfp); 13089 13046 if (!msg) 13090 13047 return; 13091 13048 ··· 13232 13189 struct net_device *netdev, const u8 *bssid, 13233 13190 const u8 *req_ie, size_t req_ie_len, 13234 13191 const u8 *resp_ie, size_t resp_ie_len, 13235 - int status, gfp_t gfp) 13192 + int status, 13193 + enum nl80211_timeout_reason timeout_reason, 13194 + gfp_t gfp) 13236 13195 { 13237 13196 struct sk_buff *msg; 13238 13197 void *hdr; 13239 13198 13240 - msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp); 13199 + msg = nlmsg_new(100 + req_ie_len + resp_ie_len, gfp); 13241 13200 if (!msg) 13242 13201 return; 13243 13202 ··· 13255 13210 nla_put_u16(msg, NL80211_ATTR_STATUS_CODE, 13256 13211 status < 0 ? WLAN_STATUS_UNSPECIFIED_FAILURE : 13257 13212 status) || 13258 - (status < 0 && nla_put_flag(msg, NL80211_ATTR_TIMED_OUT)) || 13213 + (status < 0 && 13214 + (nla_put_flag(msg, NL80211_ATTR_TIMED_OUT) || 13215 + nla_put_u32(msg, NL80211_ATTR_TIMEOUT_REASON, timeout_reason))) || 13259 13216 (req_ie && 13260 13217 nla_put(msg, NL80211_ATTR_REQ_IE, req_ie_len, req_ie)) || 13261 13218 (resp_ie && ··· 13283 13236 struct sk_buff *msg; 13284 13237 void *hdr; 13285 13238 13286 - msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp); 13239 + msg = nlmsg_new(100 + req_ie_len + resp_ie_len, gfp); 13287 13240 if (!msg) 13288 13241 return; 13289 13242 ··· 13320 13273 struct sk_buff *msg; 13321 13274 void *hdr; 13322 13275 13323 - msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 13276 + msg = nlmsg_new(100 + ie_len, GFP_KERNEL); 13324 13277 if (!msg) 13325 13278 return; 13326 13279 ··· 13396 13349 13397 13350 trace_cfg80211_notify_new_peer_candidate(dev, addr); 13398 13351 13399 - msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp); 13352 + msg = nlmsg_new(100 + ie_len, gfp); 13400 13353 if (!msg) 13401 13354 return; 13402 13355 ··· 13767 13720 struct sk_buff *msg; 13768 13721 void *hdr; 13769 13722 13770 - msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp); 13723 + msg = nlmsg_new(100 + len, gfp); 13771 13724 if (!msg) 13772 13725 return -ENOMEM; 13773 13726 ··· 13811 13764 13812 13765 trace_cfg80211_mgmt_tx_status(wdev, cookie, ack); 13813 13766 13814 - msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp); 13767 + msg = nlmsg_new(100 + len, gfp); 13815 13768 if (!msg) 13816 13769 return; 13817 13770 ··· 14566 14519 14567 14520 if (wdev->owner_nlportid == notify->portid) 14568 14521 schedule_destroy_work = true; 14522 + else if (wdev->conn_owner_nlportid == notify->portid) 14523 + schedule_work(&wdev->disconnect_wk); 14569 14524 } 14570 14525 14571 14526 spin_lock_bh(&rdev->beacon_registrations_lock); ··· 14622 14573 if (!ft_event->target_ap) 14623 14574 return; 14624 14575 14625 - msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 14576 + msg = nlmsg_new(100 + ft_event->ric_ies_len, GFP_KERNEL); 14626 14577 if (!msg) 14627 14578 return; 14628 14579
+5 -5
net/wireless/nl80211.h
··· 14 14 struct wireless_dev *wdev); 15 15 struct sk_buff *nl80211_build_scan_msg(struct cfg80211_registered_device *rdev, 16 16 struct wireless_dev *wdev, bool aborted); 17 - void nl80211_send_scan_result(struct cfg80211_registered_device *rdev, 18 - struct sk_buff *msg); 17 + void nl80211_send_scan_msg(struct cfg80211_registered_device *rdev, 18 + struct sk_buff *msg); 19 19 void nl80211_send_sched_scan(struct cfg80211_registered_device *rdev, 20 20 struct net_device *netdev, u32 cmd); 21 - void nl80211_send_sched_scan_results(struct cfg80211_registered_device *rdev, 22 - struct net_device *netdev); 23 21 void nl80211_common_reg_change_event(enum nl80211_commands cmd_id, 24 22 struct regulatory_request *request); 25 23 ··· 56 58 struct net_device *netdev, const u8 *bssid, 57 59 const u8 *req_ie, size_t req_ie_len, 58 60 const u8 *resp_ie, size_t resp_ie_len, 59 - int status, gfp_t gfp); 61 + int status, 62 + enum nl80211_timeout_reason timeout_reason, 63 + gfp_t gfp); 60 64 void nl80211_send_roamed(struct cfg80211_registered_device *rdev, 61 65 struct net_device *netdev, const u8 *bssid, 62 66 const u8 *req_ie, size_t req_ie_len,
+138
net/wireless/of.c
··· 1 + /* 2 + * Copyright (C) 2017 Rafał Miłecki <rafal@milecki.pl> 3 + * 4 + * Permission to use, copy, modify, and/or distribute this software for any 5 + * purpose with or without fee is hereby granted, provided that the above 6 + * copyright notice and this permission notice appear in all copies. 7 + * 8 + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 + */ 16 + 17 + #include <linux/of.h> 18 + #include <net/cfg80211.h> 19 + #include "core.h" 20 + 21 + static bool wiphy_freq_limits_valid_chan(struct wiphy *wiphy, 22 + struct ieee80211_freq_range *freq_limits, 23 + unsigned int n_freq_limits, 24 + struct ieee80211_channel *chan) 25 + { 26 + u32 bw = MHZ_TO_KHZ(20); 27 + int i; 28 + 29 + for (i = 0; i < n_freq_limits; i++) { 30 + struct ieee80211_freq_range *limit = &freq_limits[i]; 31 + 32 + if (cfg80211_does_bw_fit_range(limit, 33 + MHZ_TO_KHZ(chan->center_freq), 34 + bw)) 35 + return true; 36 + } 37 + 38 + return false; 39 + } 40 + 41 + static void wiphy_freq_limits_apply(struct wiphy *wiphy, 42 + struct ieee80211_freq_range *freq_limits, 43 + unsigned int n_freq_limits) 44 + { 45 + enum nl80211_band band; 46 + int i; 47 + 48 + if (WARN_ON(!n_freq_limits)) 49 + return; 50 + 51 + for (band = 0; band < NUM_NL80211_BANDS; band++) { 52 + struct ieee80211_supported_band *sband = wiphy->bands[band]; 53 + 54 + if (!sband) 55 + continue; 56 + 57 + for (i = 0; i < sband->n_channels; i++) { 58 + struct ieee80211_channel *chan = &sband->channels[i]; 59 + 60 + if (chan->flags & IEEE80211_CHAN_DISABLED) 61 + continue; 62 + 63 + if (!wiphy_freq_limits_valid_chan(wiphy, freq_limits, 64 + n_freq_limits, 65 + chan)) { 66 + pr_debug("Disabling freq %d MHz as it's out of OF limits\n", 67 + chan->center_freq); 68 + chan->flags |= IEEE80211_CHAN_DISABLED; 69 + } 70 + } 71 + } 72 + } 73 + 74 + void wiphy_read_of_freq_limits(struct wiphy *wiphy) 75 + { 76 + struct device *dev = wiphy_dev(wiphy); 77 + struct device_node *np; 78 + struct property *prop; 79 + struct ieee80211_freq_range *freq_limits; 80 + unsigned int n_freq_limits; 81 + const __be32 *p; 82 + int len, i; 83 + int err = 0; 84 + 85 + if (!dev) 86 + return; 87 + np = dev_of_node(dev); 88 + if (!np) 89 + return; 90 + 91 + prop = of_find_property(np, "ieee80211-freq-limit", &len); 92 + if (!prop) 93 + return; 94 + 95 + if (!len || len % sizeof(u32) || len / sizeof(u32) % 2) { 96 + dev_err(dev, "ieee80211-freq-limit wrong format"); 97 + return; 98 + } 99 + n_freq_limits = len / sizeof(u32) / 2; 100 + 101 + freq_limits = kcalloc(n_freq_limits, sizeof(*freq_limits), GFP_KERNEL); 102 + if (!freq_limits) { 103 + err = -ENOMEM; 104 + goto out_kfree; 105 + } 106 + 107 + p = NULL; 108 + for (i = 0; i < n_freq_limits; i++) { 109 + struct ieee80211_freq_range *limit = &freq_limits[i]; 110 + 111 + p = of_prop_next_u32(prop, p, &limit->start_freq_khz); 112 + if (!p) { 113 + err = -EINVAL; 114 + goto out_kfree; 115 + } 116 + 117 + p = of_prop_next_u32(prop, p, &limit->end_freq_khz); 118 + if (!p) { 119 + err = -EINVAL; 120 + goto out_kfree; 121 + } 122 + 123 + if (!limit->start_freq_khz || 124 + !limit->end_freq_khz || 125 + limit->start_freq_khz >= limit->end_freq_khz) { 126 + err = -EINVAL; 127 + goto out_kfree; 128 + } 129 + } 130 + 131 + wiphy_freq_limits_apply(wiphy, freq_limits, n_freq_limits); 132 + 133 + out_kfree: 134 + kfree(freq_limits); 135 + if (err) 136 + dev_err(dev, "Failed to get limits: %d\n", err); 137 + } 138 + EXPORT_SYMBOL(wiphy_read_of_freq_limits);
+7 -20
net/wireless/reg.c
··· 748 748 return true; 749 749 } 750 750 751 - static bool reg_does_bw_fit(const struct ieee80211_freq_range *freq_range, 752 - u32 center_freq_khz, u32 bw_khz) 753 - { 754 - u32 start_freq_khz, end_freq_khz; 755 - 756 - start_freq_khz = center_freq_khz - (bw_khz/2); 757 - end_freq_khz = center_freq_khz + (bw_khz/2); 758 - 759 - if (start_freq_khz >= freq_range->start_freq_khz && 760 - end_freq_khz <= freq_range->end_freq_khz) 761 - return true; 762 - 763 - return false; 764 - } 765 - 766 751 /** 767 752 * freq_in_rule_band - tells us if a frequency is in a frequency band 768 753 * @freq_range: frequency rule we want to query ··· 1055 1070 if (!band_rule_found) 1056 1071 band_rule_found = freq_in_rule_band(fr, center_freq); 1057 1072 1058 - bw_fits = reg_does_bw_fit(fr, center_freq, bw); 1073 + bw_fits = cfg80211_does_bw_fit_range(fr, center_freq, bw); 1059 1074 1060 1075 if (band_rule_found && bw_fits) 1061 1076 return rr; ··· 1123 1138 max_bandwidth_khz = reg_get_max_bandwidth(regd, reg_rule); 1124 1139 1125 1140 /* If we get a reg_rule we can assume that at least 5Mhz fit */ 1126 - if (!reg_does_bw_fit(freq_range, MHZ_TO_KHZ(chan->center_freq), 1127 - MHZ_TO_KHZ(10))) 1141 + if (!cfg80211_does_bw_fit_range(freq_range, 1142 + MHZ_TO_KHZ(chan->center_freq), 1143 + MHZ_TO_KHZ(10))) 1128 1144 bw_flags |= IEEE80211_CHAN_NO_10MHZ; 1129 - if (!reg_does_bw_fit(freq_range, MHZ_TO_KHZ(chan->center_freq), 1130 - MHZ_TO_KHZ(20))) 1145 + if (!cfg80211_does_bw_fit_range(freq_range, 1146 + MHZ_TO_KHZ(chan->center_freq), 1147 + MHZ_TO_KHZ(20))) 1131 1148 bw_flags |= IEEE80211_CHAN_NO_20MHZ; 1132 1149 1133 1150 if (max_bandwidth_khz < MHZ_TO_KHZ(10))
+5 -4
net/wireless/scan.c
··· 227 227 ASSERT_RTNL(); 228 228 229 229 if (rdev->scan_msg) { 230 - nl80211_send_scan_result(rdev, rdev->scan_msg); 230 + nl80211_send_scan_msg(rdev, rdev->scan_msg); 231 231 rdev->scan_msg = NULL; 232 232 return; 233 233 } ··· 273 273 if (!send_message) 274 274 rdev->scan_msg = msg; 275 275 else 276 - nl80211_send_scan_result(rdev, msg); 276 + nl80211_send_scan_msg(rdev, msg); 277 277 } 278 278 279 279 void __cfg80211_scan_done(struct work_struct *wk) ··· 321 321 spin_unlock_bh(&rdev->bss_lock); 322 322 request->scan_start = jiffies; 323 323 } 324 - nl80211_send_sched_scan_results(rdev, request->dev); 324 + nl80211_send_sched_scan(rdev, request->dev, 325 + NL80211_CMD_SCHED_SCAN_RESULTS); 325 326 } 326 327 327 328 rtnl_unlock(); ··· 1148 1147 else 1149 1148 rcu_assign_pointer(tmp.pub.beacon_ies, ies); 1150 1149 rcu_assign_pointer(tmp.pub.ies, ies); 1151 - 1150 + 1152 1151 memcpy(tmp.pub.bssid, mgmt->bssid, ETH_ALEN); 1153 1152 tmp.pub.channel = channel; 1154 1153 tmp.pub.scan_width = data->scan_width;
+60 -12
net/wireless/sme.c
··· 34 34 CFG80211_CONN_SCAN_AGAIN, 35 35 CFG80211_CONN_AUTHENTICATE_NEXT, 36 36 CFG80211_CONN_AUTHENTICATING, 37 - CFG80211_CONN_AUTH_FAILED, 37 + CFG80211_CONN_AUTH_FAILED_TIMEOUT, 38 38 CFG80211_CONN_ASSOCIATE_NEXT, 39 39 CFG80211_CONN_ASSOCIATING, 40 40 CFG80211_CONN_ASSOC_FAILED, 41 + CFG80211_CONN_ASSOC_FAILED_TIMEOUT, 41 42 CFG80211_CONN_DEAUTH, 42 43 CFG80211_CONN_ABANDON, 43 44 CFG80211_CONN_CONNECTED, ··· 141 140 return err; 142 141 } 143 142 144 - static int cfg80211_conn_do_work(struct wireless_dev *wdev) 143 + static int cfg80211_conn_do_work(struct wireless_dev *wdev, 144 + enum nl80211_timeout_reason *treason) 145 145 { 146 146 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy); 147 147 struct cfg80211_connect_params *params; ··· 173 171 NULL, 0, 174 172 params->key, params->key_len, 175 173 params->key_idx, NULL, 0); 176 - case CFG80211_CONN_AUTH_FAILED: 174 + case CFG80211_CONN_AUTH_FAILED_TIMEOUT: 175 + *treason = NL80211_TIMEOUT_AUTH; 177 176 return -ENOTCONN; 178 177 case CFG80211_CONN_ASSOCIATE_NEXT: 179 178 if (WARN_ON(!rdev->ops->assoc)) ··· 201 198 WLAN_REASON_DEAUTH_LEAVING, 202 199 false); 203 200 return err; 201 + case CFG80211_CONN_ASSOC_FAILED_TIMEOUT: 202 + *treason = NL80211_TIMEOUT_ASSOC; 203 + /* fall through */ 204 204 case CFG80211_CONN_ASSOC_FAILED: 205 205 cfg80211_mlme_deauth(rdev, wdev->netdev, params->bssid, 206 206 NULL, 0, ··· 229 223 container_of(work, struct cfg80211_registered_device, conn_work); 230 224 struct wireless_dev *wdev; 231 225 u8 bssid_buf[ETH_ALEN], *bssid = NULL; 226 + enum nl80211_timeout_reason treason; 232 227 233 228 rtnl_lock(); 234 229 ··· 251 244 memcpy(bssid_buf, wdev->conn->params.bssid, ETH_ALEN); 252 245 bssid = bssid_buf; 253 246 } 254 - if (cfg80211_conn_do_work(wdev)) { 247 + treason = NL80211_TIMEOUT_UNSPECIFIED; 248 + if (cfg80211_conn_do_work(wdev, &treason)) { 255 249 __cfg80211_connect_result( 256 250 wdev->netdev, bssid, 257 - NULL, 0, NULL, 0, -1, false, NULL); 251 + NULL, 0, NULL, 0, -1, false, NULL, 252 + treason); 258 253 } 259 254 wdev_unlock(wdev); 260 255 } ··· 361 352 } else if (status_code != WLAN_STATUS_SUCCESS) { 362 353 __cfg80211_connect_result(wdev->netdev, mgmt->bssid, 363 354 NULL, 0, NULL, 0, 364 - status_code, false, NULL); 355 + status_code, false, NULL, 356 + NL80211_TIMEOUT_UNSPECIFIED); 365 357 } else if (wdev->conn->state == CFG80211_CONN_AUTHENTICATING) { 366 358 wdev->conn->state = CFG80211_CONN_ASSOCIATE_NEXT; 367 359 schedule_work(&rdev->conn_work); ··· 410 400 if (!wdev->conn) 411 401 return; 412 402 413 - wdev->conn->state = CFG80211_CONN_AUTH_FAILED; 403 + wdev->conn->state = CFG80211_CONN_AUTH_FAILED_TIMEOUT; 414 404 schedule_work(&rdev->conn_work); 415 405 } 416 406 ··· 432 422 if (!wdev->conn) 433 423 return; 434 424 435 - wdev->conn->state = CFG80211_CONN_ASSOC_FAILED; 425 + wdev->conn->state = CFG80211_CONN_ASSOC_FAILED_TIMEOUT; 436 426 schedule_work(&rdev->conn_work); 437 427 } 438 428 ··· 574 564 575 565 /* we're good if we have a matching bss struct */ 576 566 if (bss) { 577 - err = cfg80211_conn_do_work(wdev); 567 + enum nl80211_timeout_reason treason; 568 + 569 + err = cfg80211_conn_do_work(wdev, &treason); 578 570 cfg80211_put_bss(wdev->wiphy, bss); 579 571 } else { 580 572 /* otherwise we'll need to scan for the AP first */ ··· 673 661 const u8 *req_ie, size_t req_ie_len, 674 662 const u8 *resp_ie, size_t resp_ie_len, 675 663 int status, bool wextev, 676 - struct cfg80211_bss *bss) 664 + struct cfg80211_bss *bss, 665 + enum nl80211_timeout_reason timeout_reason) 677 666 { 678 667 struct wireless_dev *wdev = dev->ieee80211_ptr; 679 668 const u8 *country_ie; ··· 693 680 nl80211_send_connect_result(wiphy_to_rdev(wdev->wiphy), dev, 694 681 bssid, req_ie, req_ie_len, 695 682 resp_ie, resp_ie_len, 696 - status, GFP_KERNEL); 683 + status, timeout_reason, GFP_KERNEL); 697 684 698 685 #ifdef CONFIG_CFG80211_WEXT 699 686 if (wextev) { ··· 740 727 kzfree(wdev->connect_keys); 741 728 wdev->connect_keys = NULL; 742 729 wdev->ssid_len = 0; 730 + wdev->conn_owner_nlportid = 0; 743 731 if (bss) { 744 732 cfg80211_unhold_bss(bss_from_pub(bss)); 745 733 cfg80211_put_bss(wdev->wiphy, bss); ··· 784 770 void cfg80211_connect_bss(struct net_device *dev, const u8 *bssid, 785 771 struct cfg80211_bss *bss, const u8 *req_ie, 786 772 size_t req_ie_len, const u8 *resp_ie, 787 - size_t resp_ie_len, int status, gfp_t gfp) 773 + size_t resp_ie_len, int status, gfp_t gfp, 774 + enum nl80211_timeout_reason timeout_reason) 788 775 { 789 776 struct wireless_dev *wdev = dev->ieee80211_ptr; 790 777 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy); ··· 825 810 cfg80211_hold_bss(bss_from_pub(bss)); 826 811 ev->cr.bss = bss; 827 812 ev->cr.status = status; 813 + ev->cr.timeout_reason = timeout_reason; 828 814 829 815 spin_lock_irqsave(&wdev->event_lock, flags); 830 816 list_add_tail(&ev->list, &wdev->event_list); ··· 971 955 972 956 wdev->current_bss = NULL; 973 957 wdev->ssid_len = 0; 958 + wdev->conn_owner_nlportid = 0; 974 959 975 960 nl80211_send_disconnected(rdev, dev, reason, ie, ie_len, from_ap); 976 961 ··· 1115 1098 kzfree(wdev->connect_keys); 1116 1099 wdev->connect_keys = NULL; 1117 1100 1101 + wdev->conn_owner_nlportid = 0; 1102 + 1118 1103 if (wdev->conn) 1119 1104 err = cfg80211_sme_disconnect(wdev, reason); 1120 1105 else if (!rdev->ops->disconnect) ··· 1125 1106 err = rdev_disconnect(rdev, dev, reason); 1126 1107 1127 1108 return err; 1109 + } 1110 + 1111 + /* 1112 + * Used to clean up after the connection / connection attempt owner socket 1113 + * disconnects 1114 + */ 1115 + void cfg80211_autodisconnect_wk(struct work_struct *work) 1116 + { 1117 + struct wireless_dev *wdev = 1118 + container_of(work, struct wireless_dev, disconnect_wk); 1119 + struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy); 1120 + 1121 + wdev_lock(wdev); 1122 + 1123 + if (wdev->conn_owner_nlportid) { 1124 + /* 1125 + * Use disconnect_bssid if still connecting and ops->disconnect 1126 + * not implemented. Otherwise we can use cfg80211_disconnect. 1127 + */ 1128 + if (rdev->ops->disconnect || wdev->current_bss) 1129 + cfg80211_disconnect(rdev, wdev->netdev, 1130 + WLAN_REASON_DEAUTH_LEAVING, true); 1131 + else 1132 + cfg80211_mlme_deauth(rdev, wdev->netdev, 1133 + wdev->disconnect_bssid, NULL, 0, 1134 + WLAN_REASON_DEAUTH_LEAVING, false); 1135 + } 1136 + 1137 + wdev_unlock(wdev); 1128 1138 }
+4 -2
net/wireless/sysfs.c
··· 39 39 40 40 static ssize_t name_show(struct device *dev, 41 41 struct device_attribute *attr, 42 - char *buf) { 42 + char *buf) 43 + { 43 44 struct wiphy *wiphy = &dev_to_rdev(dev)->wiphy; 44 - return sprintf(buf, "%s\n", dev_name(&wiphy->dev)); 45 + 46 + return sprintf(buf, "%s\n", wiphy_name(wiphy)); 45 47 } 46 48 static DEVICE_ATTR_RO(name); 47 49
+22 -8
net/wireless/util.c
··· 114 114 } 115 115 EXPORT_SYMBOL(ieee80211_frequency_to_channel); 116 116 117 - struct ieee80211_channel *__ieee80211_get_channel(struct wiphy *wiphy, 118 - int freq) 117 + struct ieee80211_channel *ieee80211_get_channel(struct wiphy *wiphy, int freq) 119 118 { 120 119 enum nl80211_band band; 121 120 struct ieee80211_supported_band *sband; ··· 134 135 135 136 return NULL; 136 137 } 137 - EXPORT_SYMBOL(__ieee80211_get_channel); 138 + EXPORT_SYMBOL(ieee80211_get_channel); 138 139 139 - static void set_mandatory_flags_band(struct ieee80211_supported_band *sband, 140 - enum nl80211_band band) 140 + static void set_mandatory_flags_band(struct ieee80211_supported_band *sband) 141 141 { 142 142 int i, want; 143 143 144 - switch (band) { 144 + switch (sband->band) { 145 145 case NL80211_BAND_5GHZ: 146 146 want = 3; 147 147 for (i = 0; i < sband->n_bitrates; i++) { ··· 190 192 WARN_ON((sband->ht_cap.mcs.rx_mask[0] & 0x1e) != 0x1e); 191 193 break; 192 194 case NUM_NL80211_BANDS: 195 + default: 193 196 WARN_ON(1); 194 197 break; 195 198 } ··· 202 203 203 204 for (band = 0; band < NUM_NL80211_BANDS; band++) 204 205 if (wiphy->bands[band]) 205 - set_mandatory_flags_band(wiphy->bands[band], band); 206 + set_mandatory_flags_band(wiphy->bands[band]); 206 207 } 207 208 208 209 bool cfg80211_supported_cipher_suite(struct wiphy *wiphy, u32 cipher) ··· 951 952 ev->cr.resp_ie, ev->cr.resp_ie_len, 952 953 ev->cr.status, 953 954 ev->cr.status == WLAN_STATUS_SUCCESS, 954 - ev->cr.bss); 955 + ev->cr.bss, ev->cr.timeout_reason); 955 956 break; 956 957 case EVENT_ROAMED: 957 958 __cfg80211_roamed(wdev, ev->rm.bss, ev->rm.req_ie, ··· 1846 1847 kfree(f); 1847 1848 } 1848 1849 EXPORT_SYMBOL(cfg80211_free_nan_func); 1850 + 1851 + bool cfg80211_does_bw_fit_range(const struct ieee80211_freq_range *freq_range, 1852 + u32 center_freq_khz, u32 bw_khz) 1853 + { 1854 + u32 start_freq_khz, end_freq_khz; 1855 + 1856 + start_freq_khz = center_freq_khz - (bw_khz / 2); 1857 + end_freq_khz = center_freq_khz + (bw_khz / 2); 1858 + 1859 + if (start_freq_khz >= freq_range->start_freq_khz && 1860 + end_freq_khz <= freq_range->end_freq_khz) 1861 + return true; 1862 + 1863 + return false; 1864 + } 1849 1865 1850 1866 /* See IEEE 802.1H for LLC/SNAP encapsulation/decapsulation */ 1851 1867 /* Ethernet-II snap header (RFC1042 for most EtherTypes) */
+67
net/wireless/wext-core.c
··· 1119 1119 return ret; 1120 1120 } 1121 1121 #endif 1122 + 1123 + char *iwe_stream_add_event(struct iw_request_info *info, char *stream, 1124 + char *ends, struct iw_event *iwe, int event_len) 1125 + { 1126 + int lcp_len = iwe_stream_lcp_len(info); 1127 + 1128 + event_len = iwe_stream_event_len_adjust(info, event_len); 1129 + 1130 + /* Check if it's possible */ 1131 + if (likely((stream + event_len) < ends)) { 1132 + iwe->len = event_len; 1133 + /* Beware of alignement issues on 64 bits */ 1134 + memcpy(stream, (char *) iwe, IW_EV_LCP_PK_LEN); 1135 + memcpy(stream + lcp_len, &iwe->u, 1136 + event_len - lcp_len); 1137 + stream += event_len; 1138 + } 1139 + 1140 + return stream; 1141 + } 1142 + EXPORT_SYMBOL(iwe_stream_add_event); 1143 + 1144 + char *iwe_stream_add_point(struct iw_request_info *info, char *stream, 1145 + char *ends, struct iw_event *iwe, char *extra) 1146 + { 1147 + int event_len = iwe_stream_point_len(info) + iwe->u.data.length; 1148 + int point_len = iwe_stream_point_len(info); 1149 + int lcp_len = iwe_stream_lcp_len(info); 1150 + 1151 + /* Check if it's possible */ 1152 + if (likely((stream + event_len) < ends)) { 1153 + iwe->len = event_len; 1154 + memcpy(stream, (char *) iwe, IW_EV_LCP_PK_LEN); 1155 + memcpy(stream + lcp_len, 1156 + ((char *) &iwe->u) + IW_EV_POINT_OFF, 1157 + IW_EV_POINT_PK_LEN - IW_EV_LCP_PK_LEN); 1158 + if (iwe->u.data.length && extra) 1159 + memcpy(stream + point_len, extra, iwe->u.data.length); 1160 + stream += event_len; 1161 + } 1162 + 1163 + return stream; 1164 + } 1165 + EXPORT_SYMBOL(iwe_stream_add_point); 1166 + 1167 + char *iwe_stream_add_value(struct iw_request_info *info, char *event, 1168 + char *value, char *ends, struct iw_event *iwe, 1169 + int event_len) 1170 + { 1171 + int lcp_len = iwe_stream_lcp_len(info); 1172 + 1173 + /* Don't duplicate LCP */ 1174 + event_len -= IW_EV_LCP_LEN; 1175 + 1176 + /* Check if it's possible */ 1177 + if (likely((value + event_len) < ends)) { 1178 + /* Add new value */ 1179 + memcpy(value, &iwe->u, event_len); 1180 + value += event_len; 1181 + /* Patch LCP */ 1182 + iwe->len = value - event; 1183 + memcpy(event, (char *) iwe, lcp_len); 1184 + } 1185 + 1186 + return value; 1187 + } 1188 + EXPORT_SYMBOL(iwe_stream_add_value);
-23
net/wireless/wext-sme.c
··· 105 105 goto out; 106 106 } 107 107 108 - 109 108 wdev->wext.connect.channel = chan; 110 - 111 - /* 112 - * SSID is not set, we just want to switch monitor channel, 113 - * this is really just backward compatibility, if the SSID 114 - * is set then we use the channel to select the BSS to use 115 - * to connect to instead. If we were connected on another 116 - * channel we disconnected above and reconnect below. 117 - */ 118 - if (chan && !wdev->wext.connect.ssid_len) { 119 - struct cfg80211_chan_def chandef = { 120 - .width = NL80211_CHAN_WIDTH_20_NOHT, 121 - .center_freq1 = freq, 122 - }; 123 - 124 - chandef.chan = ieee80211_get_channel(&rdev->wiphy, freq); 125 - if (chandef.chan) 126 - err = cfg80211_set_monitor_channel(rdev, &chandef); 127 - else 128 - err = -EINVAL; 129 - goto out; 130 - } 131 - 132 109 err = cfg80211_mgd_wext_connect(rdev, wdev); 133 110 out: 134 111 wdev_unlock(wdev);