History

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

Johannes Berg says: ==================== My last pull request has been a while, we now have: * connection quality monitoring with multiple thresholds * support for FILS shared key authentication offload * pre-CAC regulatory compliance - only ETSI allows this * sanity check for some rate confusion that hit ChromeOS (but nobody else uses it, evidently) * some documentation updates * lots of cleanups ====================

David S. Miller committed 9 years ago

Commit 028f43b2 parents 0ef9059 bbf67e484 files · +1802 −540Browse files

Unified · Split

84 files
  1. Documentation/driver-api/80211/cfg80211.rst +9 −0
  2. drivers/net/wireless/admtek/adm8211.c +2 −0
  3. drivers/net/wireless/ath/ar5523/ar5523.c +2 −0
  4. drivers/net/wireless/ath/ath10k/mac.c +2 −0
  5. drivers/net/wireless/ath/ath5k/base.c +2 −0
  6. drivers/net/wireless/ath/ath6kl/cfg80211.c +1 −2
  7. drivers/net/wireless/ath/ath9k/htc_drv_init.c +2 −0
  8. drivers/net/wireless/ath/ath9k/init.c +2 −0
  9. drivers/net/wireless/ath/carl9170/main.c +2 −0
  10. drivers/net/wireless/ath/wcn36xx/main.c +3 −0
  11. drivers/net/wireless/ath/wil6210/cfg80211.c +5 −9
  12. drivers/net/wireless/atmel/at76c50x-usb.c +2 −0
  13. drivers/net/wireless/broadcom/b43/main.c +2 −0
  14. drivers/net/wireless/broadcom/b43legacy/main.c +2 −0
  15. drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +5 −7
  16. drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c +1 −2
  17. drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.h +1 −1
  18. drivers/net/wireless/broadcom/brcm80211/brcmsmac/mac80211_if.c +2 −0
  19. drivers/net/wireless/intel/iwlegacy/3945-mac.c +2 −0
  20. drivers/net/wireless/intel/iwlegacy/3945-rs.c +1 −1
  21. drivers/net/wireless/intel/iwlegacy/4965-mac.c +2 −0
  22. drivers/net/wireless/intel/iwlegacy/4965-rs.c +1 −1
  23. drivers/net/wireless/intel/iwlwifi/dvm/mac80211.c +2 −0
  24. drivers/net/wireless/intel/iwlwifi/dvm/rs.c +1 −1
  25. drivers/net/wireless/intersil/orinoco/cfg.c +1 −1
  26. drivers/net/wireless/mac80211_hwsim.c +69 −21
  27. drivers/net/wireless/mac80211_hwsim.h +2 −2
  28. drivers/net/wireless/marvell/libertas/cfg.c +1 −1
  29. drivers/net/wireless/marvell/libertas_tf/main.c +2 −0
  30. drivers/net/wireless/marvell/mwifiex/cfg80211.c +12 −15
  31. drivers/net/wireless/marvell/mwifiex/main.c +3 −4
  32. drivers/net/wireless/marvell/mwifiex/main.h +0 −1
  33. drivers/net/wireless/marvell/mwifiex/tdls.c +1 −1
  34. drivers/net/wireless/marvell/mwl8k.c +2 −0
  35. drivers/net/wireless/mediatek/mt7601u/init.c +2 −0
  36. drivers/net/wireless/ralink/rt2x00/rt2x00dev.c +3 −0
  37. drivers/net/wireless/realtek/rtl818x/rtl8180/dev.c +2 −0
  38. drivers/net/wireless/realtek/rtl818x/rtl8187/dev.c +2 −0
  39. drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c +2 −0
  40. drivers/net/wireless/rndis_wlan.c +2 −2
  41. drivers/net/wireless/rsi/rsi_91x_mac80211.c +2 −0
  42. drivers/net/wireless/zydas/zd1211rw/zd_mac.c +2 −0
  43. drivers/staging/wilc1000/wilc_wfi_cfgoperations.c +1 −2
  44. drivers/staging/wlan-ng/cfg80211.c +1 −1
  45. include/linux/ieee80211.h +18 −2
  46. include/net/cfg80211.h +176 −16
  47. include/net/mac80211.h +6 −4
  48. include/uapi/linux/nl80211.h +96 −4
  49. net/mac80211/agg-rx.c +6 −6
  50. net/mac80211/agg-tx.c +6 −6
  51. net/mac80211/cfg.c +145 −58
  52. net/mac80211/ibss.c +2 −2
  53. net/mac80211/ieee80211_i.h +3 −0
  54. net/mac80211/iface.c +17 −2
  55. net/mac80211/main.c +1 −0
  56. net/mac80211/mesh.c +8 −2
  57. net/mac80211/mesh_hwmp.c +17 −6
  58. net/mac80211/mesh_pathtbl.c +5 −3
  59. net/mac80211/mlme.c +34 −7
  60. net/mac80211/rate.c +36 −7
  61. net/mac80211/rate.h +2 −1
  62. net/mac80211/rx.c +19 −31
  63. net/mac80211/spectmgmt.c +2 −2
  64. net/mac80211/sta_info.c +8 −3
  65. net/mac80211/sta_info.h +11 −7
  66. net/mac80211/tx.c +0 −8
  67. net/mac80211/util.c +11 −11
  68. net/wireless/ap.c +5 −0
  69. net/wireless/chan.c +117 −0
  70. net/wireless/core.c +61 −7
  71. net/wireless/core.h +30 −17
  72. net/wireless/ibss.c +1 −0
  73. net/wireless/mesh.c +1 −0
  74. net/wireless/mlme.c +53 −17
  75. net/wireless/nl80211.c +361 −104
  76. net/wireless/nl80211.h +3 −7
  77. net/wireless/rdev-ops.h +16 −5
  78. net/wireless/reg.c +148 −0
  79. net/wireless/reg.h +36 −0
  80. net/wireless/scan.c +2 −3
  81. net/wireless/sme.c +103 −69
  82. net/wireless/trace.h +22 −0
  83. net/wireless/util.c +45 −47
  84. net/wireless/wext-compat.c +1 −1
Documentation/driver-api/80211/cfg80211.rst+9−0
@@ -2,6 +2,9 @@ · 1 unmodified line
2cfg80211 subsystem2cfg80211 subsystem
3==================3==================
4 4
5.. kernel-doc:: include/net/cfg80211.h
6 :doc: Introduction
7
5Device registration8Device registration
6===================9===================
7 10
@@ -179,6 +182,12 @@ Actions and configuration · 171 unmodified lines
179.. kernel-doc:: include/net/cfg80211.h182.. kernel-doc:: include/net/cfg80211.h
180 :functions: cfg80211_ibss_joined183 :functions: cfg80211_ibss_joined
181 184
185.. kernel-doc:: include/net/cfg80211.h
186 :functions: cfg80211_connect_resp_params
187
188.. kernel-doc:: include/net/cfg80211.h
189 :functions: cfg80211_connect_done
190
182.. kernel-doc:: include/net/cfg80211.h191.. kernel-doc:: include/net/cfg80211.h
183 :functions: cfg80211_connect_result192 :functions: cfg80211_connect_result
184 193
drivers/net/wireless/admtek/adm8211.c+2−0
@@ -1917,6 +1917,8 @@ static int adm8211_probe(struct pci_dev *pdev, · 1916 unmodified lines
1917 1917
1918 dev->wiphy->bands[NL80211_BAND_2GHZ] = &priv->band;1918 dev->wiphy->bands[NL80211_BAND_2GHZ] = &priv->band;
1919 1919
1920 wiphy_ext_feature_set(dev->wiphy, NL80211_EXT_FEATURE_CQM_RSSI_LIST);
1921
1920 err = ieee80211_register_hw(dev);1922 err = ieee80211_register_hw(dev);
1921 if (err) {1923 if (err) {
1922 printk(KERN_ERR "%s (adm8211): Cannot register device\n",1924 printk(KERN_ERR "%s (adm8211): Cannot register device\n",
drivers/net/wireless/ath/ar5523/ar5523.c+2−0
@@ -1689,6 +1689,8 @@ static int ar5523_probe(struct usb_interface *intf, · 1688 unmodified lines
1689 if (error)1689 if (error)
1690 goto out_cancel_rx_cmd;1690 goto out_cancel_rx_cmd;
1691 1691
1692 wiphy_ext_feature_set(hw->wiphy, NL80211_EXT_FEATURE_CQM_RSSI_LIST);
1693
1692 usb_set_intfdata(intf, hw);1694 usb_set_intfdata(intf, hw);
1693 1695
1694 error = ieee80211_register_hw(hw);1696 error = ieee80211_register_hw(hw);
drivers/net/wireless/ath/ath10k/mac.c+2−0
@@ -8267,6 +8267,8 @@ int ath10k_mac_register(struct ath10k *ar) · 8266 unmodified lines
8267 ar->hw->wiphy->cipher_suites = cipher_suites;8267 ar->hw->wiphy->cipher_suites = cipher_suites;
8268 ar->hw->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);8268 ar->hw->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
8269 8269
8270 wiphy_ext_feature_set(ar->hw->wiphy, NL80211_EXT_FEATURE_CQM_RSSI_LIST);
8271
8270 ret = ieee80211_register_hw(ar->hw);8272 ret = ieee80211_register_hw(ar->hw);
8271 if (ret) {8273 if (ret) {
8272 ath10k_err(ar, "failed to register ieee80211: %d\n", ret);8274 ath10k_err(ar, "failed to register ieee80211: %d\n", ret);
drivers/net/wireless/ath/ath5k/base.c+2−0
@@ -2564,6 +2564,8 @@ ath5k_init_ah(struct ath5k_hw *ah, const struct ath_bus_ops *bus_ops) · 2563 unmodified lines
2564 2564
2565 hw->extra_tx_headroom = 2;2565 hw->extra_tx_headroom = 2;
2566 2566
2567 wiphy_ext_feature_set(hw->wiphy, NL80211_EXT_FEATURE_CQM_RSSI_LIST);
2568
2567 /*2569 /*
2568 * Mark the device as detached to avoid processing2570 * Mark the device as detached to avoid processing
2569 * interrupts until setup is complete.2571 * interrupts until setup is complete.
drivers/net/wireless/ath/ath6kl/cfg80211.c+1−2
@@ -1503,7 +1503,6 @@ static struct wireless_dev *ath6kl_cfg80211_add_iface(struct wiphy *wiphy, · 1502 unmodified lines
1503 const char *name,1503 const char *name,
1504 unsigned char name_assign_type,1504 unsigned char name_assign_type,
1505 enum nl80211_iftype type,1505 enum nl80211_iftype type,
1506 u32 *flags,
1507 struct vif_params *params)1506 struct vif_params *params)
1508{1507{
1509 struct ath6kl *ar = wiphy_priv(wiphy);1508 struct ath6kl *ar = wiphy_priv(wiphy);
@@ -1550,7 +1549,7 @@ static int ath6kl_cfg80211_del_iface(struct wiphy *wiphy, · 40 unmodified lines
1550 1549
1551static int ath6kl_cfg80211_change_iface(struct wiphy *wiphy,1550static int ath6kl_cfg80211_change_iface(struct wiphy *wiphy,
1552 struct net_device *ndev,1551 struct net_device *ndev,
1553 enum nl80211_iftype type, u32 *flags,1552 enum nl80211_iftype type,
1554 struct vif_params *params)1553 struct vif_params *params)
1555{1554{
1556 struct ath6kl_vif *vif = netdev_priv(ndev);1555 struct ath6kl_vif *vif = netdev_priv(ndev);
drivers/net/wireless/ath/ath9k/htc_drv_init.c+2−0
@@ -780,6 +780,8 @@ static void ath9k_set_hw_capab(struct ath9k_htc_priv *priv, · 779 unmodified lines
780 }780 }
781 781
782 SET_IEEE80211_PERM_ADDR(hw, common->macaddr);782 SET_IEEE80211_PERM_ADDR(hw, common->macaddr);
783
784 wiphy_ext_feature_set(hw->wiphy, NL80211_EXT_FEATURE_CQM_RSSI_LIST);
783}785}
784 786
785static int ath9k_init_firmware_version(struct ath9k_htc_priv *priv)787static int ath9k_init_firmware_version(struct ath9k_htc_priv *priv)
drivers/net/wireless/ath/ath9k/init.c+2−0
@@ -955,6 +955,8 @@ static void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw) · 954 unmodified lines
955 ath9k_cmn_reload_chainmask(ah);955 ath9k_cmn_reload_chainmask(ah);
956 956
957 SET_IEEE80211_PERM_ADDR(hw, common->macaddr);957 SET_IEEE80211_PERM_ADDR(hw, common->macaddr);
958
959 wiphy_ext_feature_set(hw->wiphy, NL80211_EXT_FEATURE_CQM_RSSI_LIST);
958}960}
959 961
960int ath9k_init_device(u16 devid, struct ath_softc *sc,962int ath9k_init_device(u16 devid, struct ath_softc *sc,
drivers/net/wireless/ath/carl9170/main.c+2−0
@@ -1874,6 +1874,8 @@ void *carl9170_alloc(size_t priv_size) · 1873 unmodified lines
1874 for (i = 0; i < ARRAY_SIZE(ar->noise); i++)1874 for (i = 0; i < ARRAY_SIZE(ar->noise); i++)
1875 ar->noise[i] = -95; /* ATH_DEFAULT_NOISE_FLOOR */1875 ar->noise[i] = -95; /* ATH_DEFAULT_NOISE_FLOOR */
1876 1876
1877 wiphy_ext_feature_set(hw->wiphy, NL80211_EXT_FEATURE_CQM_RSSI_LIST);
1878
1877 return ar;1879 return ar;
1878 1880
1879err_nomem:1881err_nomem:
drivers/net/wireless/ath/wcn36xx/main.c+3−0
@@ -1112,6 +1112,9 @@ static int wcn36xx_init_ieee80211(struct wcn36xx *wcn) · 1111 unmodified lines
1112 wcn->hw->sta_data_size = sizeof(struct wcn36xx_sta);1112 wcn->hw->sta_data_size = sizeof(struct wcn36xx_sta);
1113 wcn->hw->vif_data_size = sizeof(struct wcn36xx_vif);1113 wcn->hw->vif_data_size = sizeof(struct wcn36xx_vif);
1114 1114
1115 wiphy_ext_feature_set(wcn->hw->wiphy,
1116 NL80211_EXT_FEATURE_CQM_RSSI_LIST);
1117
1115 return ret;1118 return ret;
1116}1119}
1117 1120
drivers/net/wireless/ath/wil6210/cfg80211.c+5−9
@@ -178,9 +178,8 @@ int wil_cid_fill_sinfo(struct wil6210_priv *wil, int cid, · 177 unmodified lines
178 BIT(NL80211_STA_INFO_RX_DROP_MISC) |178 BIT(NL80211_STA_INFO_RX_DROP_MISC) |
179 BIT(NL80211_STA_INFO_TX_FAILED);179 BIT(NL80211_STA_INFO_TX_FAILED);
180 180
181 sinfo->txrate.flags = RATE_INFO_FLAGS_MCS | RATE_INFO_FLAGS_60G;181 sinfo->txrate.flags = RATE_INFO_FLAGS_60G;
182 sinfo->txrate.mcs = le16_to_cpu(reply.evt.bf_mcs);182 sinfo->txrate.mcs = le16_to_cpu(reply.evt.bf_mcs);
183 sinfo->rxrate.flags = RATE_INFO_FLAGS_MCS | RATE_INFO_FLAGS_60G;
184 sinfo->rxrate.mcs = stats->last_mcs_rx;183 sinfo->rxrate.mcs = stats->last_mcs_rx;
185 sinfo->rx_bytes = stats->rx_bytes;184 sinfo->rx_bytes = stats->rx_bytes;
186 sinfo->rx_packets = stats->rx_packets;185 sinfo->rx_packets = stats->rx_packets;
@@ -256,7 +255,7 @@ static struct wireless_dev * · 69 unmodified lines
256wil_cfg80211_add_iface(struct wiphy *wiphy, const char *name,255wil_cfg80211_add_iface(struct wiphy *wiphy, const char *name,
257 unsigned char name_assign_type,256 unsigned char name_assign_type,
258 enum nl80211_iftype type,257 enum nl80211_iftype type,
259 u32 *flags, struct vif_params *params)258 struct vif_params *params)
260{259{
261 struct wil6210_priv *wil = wiphy_to_wil(wiphy);260 struct wil6210_priv *wil = wiphy_to_wil(wiphy);
262 struct net_device *ndev = wil_to_ndev(wil);261 struct net_device *ndev = wil_to_ndev(wil);
@@ -307,7 +306,7 @@ static int wil_cfg80211_del_iface(struct wiphy *wiphy, · 44 unmodified lines
307 306
308static int wil_cfg80211_change_iface(struct wiphy *wiphy,307static int wil_cfg80211_change_iface(struct wiphy *wiphy,
309 struct net_device *ndev,308 struct net_device *ndev,
310 enum nl80211_iftype type, u32 *flags,309 enum nl80211_iftype type,
311 struct vif_params *params)310 struct vif_params *params)
312{311{
313 struct wil6210_priv *wil = wiphy_to_wil(wiphy);312 struct wil6210_priv *wil = wiphy_to_wil(wiphy);
@@ -334,11 +333,8 @@ static int wil_cfg80211_change_iface(struct wiphy *wiphy, · 20 unmodified lines
334 case NL80211_IFTYPE_P2P_GO:333 case NL80211_IFTYPE_P2P_GO:
335 break;334 break;
336 case NL80211_IFTYPE_MONITOR:335 case NL80211_IFTYPE_MONITOR:
337 if (flags)336 if (params->flags)
338 wil->monitor_flags = *flags;337 wil->monitor_flags = params->flags;
339 else
340 wil->monitor_flags = 0;
341
342 break;338 break;
343 default:339 default:
344 return -EOPNOTSUPP;340 return -EOPNOTSUPP;
drivers/net/wireless/atmel/at76c50x-usb.c+2−0
@@ -2377,6 +2377,8 @@ static int at76_init_new_device(struct at76_priv *priv, · 2376 unmodified lines
2377 2377
2378 wiphy->hw_version = priv->board_type;2378 wiphy->hw_version = priv->board_type;
2379 2379
2380 wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_CQM_RSSI_LIST);
2381
2380 ret = ieee80211_register_hw(priv->hw);2382 ret = ieee80211_register_hw(priv->hw);
2381 if (ret) {2383 if (ret) {
2382 printk(KERN_ERR "cannot register mac80211 hw (status %d)!\n",2384 printk(KERN_ERR "cannot register mac80211 hw (status %d)!\n",
drivers/net/wireless/broadcom/b43/main.c+2−0
@@ -5598,6 +5598,8 @@ static struct b43_wl *b43_wireless_init(struct b43_bus_dev *dev) · 5597 unmodified lines
5598 5598
5599 hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN;5599 hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN;
5600 5600
5601 wiphy_ext_feature_set(hw->wiphy, NL80211_EXT_FEATURE_CQM_RSSI_LIST);
5602
5601 wl->hw_registred = false;5603 wl->hw_registred = false;
5602 hw->max_rates = 2;5604 hw->max_rates = 2;
5603 SET_IEEE80211_DEV(hw, dev->dev);5605 SET_IEEE80211_DEV(hw, dev->dev);
drivers/net/wireless/broadcom/b43legacy/main.c+2−0
@@ -3850,6 +3850,8 @@ static int b43legacy_wireless_init(struct ssb_device *dev) · 3849 unmodified lines
3850 else3850 else
3851 SET_IEEE80211_PERM_ADDR(hw, sprom->il0mac);3851 SET_IEEE80211_PERM_ADDR(hw, sprom->il0mac);
3852 3852
3853 wiphy_ext_feature_set(hw->wiphy, NL80211_EXT_FEATURE_CQM_RSSI_LIST);
3854
3853 /* Get and initialize struct b43legacy_wl */3855 /* Get and initialize struct b43legacy_wl */
3854 wl = hw_to_b43legacy_wl(hw);3856 wl = hw_to_b43legacy_wl(hw);
3855 memset(wl, 0, sizeof(*wl));3857 memset(wl, 0, sizeof(*wl));
drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c+5−7
@@ -575,12 +575,11 @@ static int brcmf_cfg80211_request_ap_if(struct brcmf_if *ifp) · 574 unmodified lines
575 *575 *
576 * @wiphy: wiphy device of new interface.576 * @wiphy: wiphy device of new interface.
577 * @name: name of the new interface.577 * @name: name of the new interface.
578 * @flags: not used.
579 * @params: contains mac address for AP device.578 * @params: contains mac address for AP device.
580 */579 */
581static580static
582struct wireless_dev *brcmf_ap_add_vif(struct wiphy *wiphy, const char *name,581struct wireless_dev *brcmf_ap_add_vif(struct wiphy *wiphy, const char *name,
583 u32 *flags, struct vif_params *params)582 struct vif_params *params)
584{583{
585 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);584 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
586 struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));585 struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
@@ -653,7 +652,6 @@ static struct wireless_dev *brcmf_cfg80211_add_iface(struct wiphy *wiphy, · 66 unmodified lines
653 const char *name,652 const char *name,
654 unsigned char name_assign_type,653 unsigned char name_assign_type,
655 enum nl80211_iftype type,654 enum nl80211_iftype type,
656 u32 *flags,
657 struct vif_params *params)655 struct vif_params *params)
658{656{
659 struct wireless_dev *wdev;657 struct wireless_dev *wdev;
@@ -674,12 +672,12 @@ static struct wireless_dev *brcmf_cfg80211_add_iface(struct wiphy *wiphy, · 14 unmodified lines
674 case NL80211_IFTYPE_MESH_POINT:672 case NL80211_IFTYPE_MESH_POINT:
675 return ERR_PTR(-EOPNOTSUPP);673 return ERR_PTR(-EOPNOTSUPP);
676 case NL80211_IFTYPE_AP:674 case NL80211_IFTYPE_AP:
677 wdev = brcmf_ap_add_vif(wiphy, name, flags, params);675 wdev = brcmf_ap_add_vif(wiphy, name, params);
678 break;676 break;
679 case NL80211_IFTYPE_P2P_CLIENT:677 case NL80211_IFTYPE_P2P_CLIENT:
680 case NL80211_IFTYPE_P2P_GO:678 case NL80211_IFTYPE_P2P_GO:
681 case NL80211_IFTYPE_P2P_DEVICE:679 case NL80211_IFTYPE_P2P_DEVICE:
682 wdev = brcmf_p2p_add_vif(wiphy, name, name_assign_type, type, flags, params);680 wdev = brcmf_p2p_add_vif(wiphy, name, name_assign_type, type, params);
683 break;681 break;
684 case NL80211_IFTYPE_UNSPECIFIED:682 case NL80211_IFTYPE_UNSPECIFIED:
685 default:683 default:
@@ -858,7 +856,7 @@ int brcmf_cfg80211_del_iface(struct wiphy *wiphy, struct wireless_dev *wdev) · 172 unmodified lines
858 856
859static s32857static s32
860brcmf_cfg80211_change_iface(struct wiphy *wiphy, struct net_device *ndev,858brcmf_cfg80211_change_iface(struct wiphy *wiphy, struct net_device *ndev,
861 enum nl80211_iftype type, u32 *flags,859 enum nl80211_iftype type,
862 struct vif_params *params)860 struct vif_params *params)
863{861{
864 struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy);862 struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy);
@@ -6553,7 +6551,7 @@ static s32 brcmf_config_dongle(struct brcmf_cfg80211_info *cfg) · 5688 unmodified lines
6553 if (err)6551 if (err)
6554 goto default_conf_out;6552 goto default_conf_out;
6555 err = brcmf_cfg80211_change_iface(wdev->wiphy, ndev, wdev->iftype,6553 err = brcmf_cfg80211_change_iface(wdev->wiphy, ndev, wdev->iftype,
6556 NULL, NULL);6554 NULL);
6557 if (err)6555 if (err)
6558 goto default_conf_out;6556 goto default_conf_out;
6559 6557
drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c+1−2
@@ -2141,12 +2141,11 @@ fail: · 2140 unmodified lines
2141 * @name: name of the new interface.2141 * @name: name of the new interface.
2142 * @name_assign_type: origin of the interface name2142 * @name_assign_type: origin of the interface name
2143 * @type: nl80211 interface type.2143 * @type: nl80211 interface type.
2144 * @flags: not used.
2145 * @params: contains mac address for P2P device.2144 * @params: contains mac address for P2P device.
2146 */2145 */
2147struct wireless_dev *brcmf_p2p_add_vif(struct wiphy *wiphy, const char *name,2146struct wireless_dev *brcmf_p2p_add_vif(struct wiphy *wiphy, const char *name,
2148 unsigned char name_assign_type,2147 unsigned char name_assign_type,
2149 enum nl80211_iftype type, u32 *flags,2148 enum nl80211_iftype type,
2150 struct vif_params *params)2149 struct vif_params *params)
2151{2150{
2152 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);2151 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.h+1−1
@@ -150,7 +150,7 @@ s32 brcmf_p2p_attach(struct brcmf_cfg80211_info *cfg, bool p2pdev_forced); · 149 unmodified lines
150void brcmf_p2p_detach(struct brcmf_p2p_info *p2p);150void brcmf_p2p_detach(struct brcmf_p2p_info *p2p);
151struct wireless_dev *brcmf_p2p_add_vif(struct wiphy *wiphy, const char *name,151struct wireless_dev *brcmf_p2p_add_vif(struct wiphy *wiphy, const char *name,
152 unsigned char name_assign_type,152 unsigned char name_assign_type,
153 enum nl80211_iftype type, u32 *flags,153 enum nl80211_iftype type,
154 struct vif_params *params);154 struct vif_params *params);
155int brcmf_p2p_del_vif(struct wiphy *wiphy, struct wireless_dev *wdev);155int brcmf_p2p_del_vif(struct wiphy *wiphy, struct wireless_dev *wdev);
156int brcmf_p2p_ifchange(struct brcmf_cfg80211_info *cfg,156int brcmf_p2p_ifchange(struct brcmf_cfg80211_info *cfg,
drivers/net/wireless/broadcom/brcm80211/brcmsmac/mac80211_if.c+2−0
@@ -1082,6 +1082,8 @@ static int ieee_hw_init(struct ieee80211_hw *hw) · 1081 unmodified lines
1082 * hw->wiphy->flags |= WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD;1082 * hw->wiphy->flags |= WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD;
1083 */1083 */
1084 1084
1085 wiphy_ext_feature_set(hw->wiphy, NL80211_EXT_FEATURE_CQM_RSSI_LIST);
1086
1085 hw->rate_control_algorithm = "minstrel_ht";1087 hw->rate_control_algorithm = "minstrel_ht";
1086 1088
1087 hw->sta_data_size = 0;1089 hw->sta_data_size = 0;
drivers/net/wireless/intel/iwlegacy/3945-mac.c+2−0
@@ -3592,6 +3592,8 @@ il3945_setup_mac(struct il_priv *il) · 3591 unmodified lines
3592 3592
3593 il_leds_init(il);3593 il_leds_init(il);
3594 3594
3595 wiphy_ext_feature_set(il->hw->wiphy, NL80211_EXT_FEATURE_CQM_RSSI_LIST);
3596
3595 ret = ieee80211_register_hw(il->hw);3597 ret = ieee80211_register_hw(il->hw);
3596 if (ret) {3598 if (ret) {
3597 IL_ERR("Failed to register hw (error %d)\n", ret);3599 IL_ERR("Failed to register hw (error %d)\n", ret);
drivers/net/wireless/intel/iwlegacy/3945-rs.c+1−1
@@ -656,7 +656,7 @@ il3945_rs_get_rate(void *il_r, struct ieee80211_sta *sta, void *il_sta, · 655 unmodified lines
656 rate_mask = sta->supp_rates[sband->band];656 rate_mask = sta->supp_rates[sband->band];
657 657
658 /* get user max rate if set */658 /* get user max rate if set */
659 max_rate_idx = txrc->max_rate_idx;659 max_rate_idx = fls(txrc->rate_idx_mask) - 1;
660 if (sband->band == NL80211_BAND_5GHZ && max_rate_idx != -1)660 if (sband->band == NL80211_BAND_5GHZ && max_rate_idx != -1)
661 max_rate_idx += IL_FIRST_OFDM_RATE;661 max_rate_idx += IL_FIRST_OFDM_RATE;
662 if (max_rate_idx < 0 || max_rate_idx >= RATE_COUNT)662 if (max_rate_idx < 0 || max_rate_idx >= RATE_COUNT)
drivers/net/wireless/intel/iwlegacy/4965-mac.c+2−0
@@ -5799,6 +5799,8 @@ il4965_mac_setup_register(struct il_priv *il, u32 max_probe_length) · 5798 unmodified lines
5799 5799
5800 il_leds_init(il);5800 il_leds_init(il);
5801 5801
5802 wiphy_ext_feature_set(il->hw->wiphy, NL80211_EXT_FEATURE_CQM_RSSI_LIST);
5803
5802 ret = ieee80211_register_hw(il->hw);5804 ret = ieee80211_register_hw(il->hw);
5803 if (ret) {5805 if (ret) {
5804 IL_ERR("Failed to register hw (error %d)\n", ret);5806 IL_ERR("Failed to register hw (error %d)\n", ret);
drivers/net/wireless/intel/iwlegacy/4965-rs.c+1−1
@@ -2211,7 +2211,7 @@ il4965_rs_get_rate(void *il_r, struct ieee80211_sta *sta, void *il_sta, · 2210 unmodified lines
2211 2211
2212 /* Get max rate if user set max rate */2212 /* Get max rate if user set max rate */
2213 if (lq_sta) {2213 if (lq_sta) {
2214 lq_sta->max_rate_idx = txrc->max_rate_idx;2214 lq_sta->max_rate_idx = fls(txrc->rate_idx_mask) - 1;
2215 if (sband->band == NL80211_BAND_5GHZ &&2215 if (sband->band == NL80211_BAND_5GHZ &&
2216 lq_sta->max_rate_idx != -1)2216 lq_sta->max_rate_idx != -1)
2217 lq_sta->max_rate_idx += IL_FIRST_OFDM_RATE;2217 lq_sta->max_rate_idx += IL_FIRST_OFDM_RATE;
drivers/net/wireless/intel/iwlwifi/dvm/mac80211.c+2−0
@@ -213,6 +213,8 @@ int iwlagn_mac_setup_register(struct iwl_priv *priv, · 212 unmodified lines
213 213
214 iwl_leds_init(priv);214 iwl_leds_init(priv);
215 215
216 wiphy_ext_feature_set(hw->wiphy, NL80211_EXT_FEATURE_CQM_RSSI_LIST);
217
216 ret = ieee80211_register_hw(priv->hw);218 ret = ieee80211_register_hw(priv->hw);
217 if (ret) {219 if (ret) {
218 IWL_ERR(priv, "Failed to register hw (error %d)\n", ret);220 IWL_ERR(priv, "Failed to register hw (error %d)\n", ret);
drivers/net/wireless/intel/iwlwifi/dvm/rs.c+1−1
@@ -2720,7 +2720,7 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta, void *priv_sta, · 2719 unmodified lines
2720 2720
2721 /* Get max rate if user set max rate */2721 /* Get max rate if user set max rate */
2722 if (lq_sta) {2722 if (lq_sta) {
2723 lq_sta->max_rate_idx = txrc->max_rate_idx;2723 lq_sta->max_rate_idx = fls(txrc->rate_idx_mask) - 1;
2724 if ((sband->band == NL80211_BAND_5GHZ) &&2724 if ((sband->band == NL80211_BAND_5GHZ) &&
2725 (lq_sta->max_rate_idx != -1))2725 (lq_sta->max_rate_idx != -1))
2726 lq_sta->max_rate_idx += IWL_FIRST_OFDM_RATE;2726 lq_sta->max_rate_idx += IWL_FIRST_OFDM_RATE;
drivers/net/wireless/intersil/orinoco/cfg.c+1−1
@@ -97,7 +97,7 @@ int orinoco_wiphy_register(struct wiphy *wiphy) · 96 unmodified lines
97}97}
98 98
99static int orinoco_change_vif(struct wiphy *wiphy, struct net_device *dev,99static int orinoco_change_vif(struct wiphy *wiphy, struct net_device *dev,
100 enum nl80211_iftype type, u32 *flags,100 enum nl80211_iftype type,
101 struct vif_params *params)101 struct vif_params *params)
102{102{
103 struct orinoco_private *priv = wiphy_priv(wiphy);103 struct orinoco_private *priv = wiphy_priv(wiphy);
drivers/net/wireless/mac80211_hwsim.c+69−21
@@ -350,6 +350,7 @@ static const struct ieee80211_channel hwsim_channels_5ghz[] = { · 349 unmodified lines
350 CHAN5G(5785), /* Channel 157 */350 CHAN5G(5785), /* Channel 157 */
351 CHAN5G(5805), /* Channel 161 */351 CHAN5G(5805), /* Channel 161 */
352 CHAN5G(5825), /* Channel 165 */352 CHAN5G(5825), /* Channel 165 */
353 CHAN5G(5845), /* Channel 169 */
353};354};
354 355
355static const struct ieee80211_rate hwsim_rates[] = {356static const struct ieee80211_rate hwsim_rates[] = {
@@ -525,6 +526,11 @@ struct mac80211_hwsim_data { · 169 unmodified lines
525 struct ieee80211_vif *hw_scan_vif;526 struct ieee80211_vif *hw_scan_vif;
526 int scan_chan_idx;527 int scan_chan_idx;
527 u8 scan_addr[ETH_ALEN];528 u8 scan_addr[ETH_ALEN];
529 struct {
530 struct ieee80211_channel *channel;
531 unsigned long next_start, start, end;
532 } survey_data[ARRAY_SIZE(hwsim_channels_2ghz) +
533 ARRAY_SIZE(hwsim_channels_5ghz)];
528 534
529 struct ieee80211_channel *channel;535 struct ieee80211_channel *channel;
530 u64 beacon_int /* beacon interval in us */;536 u64 beacon_int /* beacon interval in us */;
@@ -552,8 +558,6 @@ struct mac80211_hwsim_data { · 21 unmodified lines
552 /* wmediumd portid responsible for netgroup of this radio */558 /* wmediumd portid responsible for netgroup of this radio */
553 u32 wmediumd;559 u32 wmediumd;
554 560
555 int power_level;
556
557 /* difference between this hw's clock and the real clock, in usecs */561 /* difference between this hw's clock and the real clock, in usecs */
558 s64 tsf_offset;562 s64 tsf_offset;
559 s64 bcn_delta;563 s64 bcn_delta;
@@ -1201,7 +1205,9 @@ static bool mac80211_hwsim_tx_frame_no_nl(struct ieee80211_hw *hw, · 641 unmodified lines
1201 if (info->control.rates[0].flags & IEEE80211_TX_RC_SHORT_GI)1205 if (info->control.rates[0].flags & IEEE80211_TX_RC_SHORT_GI)
1202 rx_status.flag |= RX_FLAG_SHORT_GI;1206 rx_status.flag |= RX_FLAG_SHORT_GI;
1203 /* TODO: simulate real signal strength (and optional packet loss) */1207 /* TODO: simulate real signal strength (and optional packet loss) */
1204 rx_status.signal = data->power_level - 50;1208 rx_status.signal = -50;
1209 if (info->control.vif)
1210 rx_status.signal += info->control.vif->bss_conf.txpower;
1205 1211
1206 if (data->ps != PS_DISABLED)1212 if (data->ps != PS_DISABLED)
1207 hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_PM);1213 hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_PM);
@@ -1576,6 +1582,7 @@ static int mac80211_hwsim_config(struct ieee80211_hw *hw, u32 changed) · 368 unmodified lines
1576 [IEEE80211_SMPS_STATIC] = "static",1582 [IEEE80211_SMPS_STATIC] = "static",
1577 [IEEE80211_SMPS_DYNAMIC] = "dynamic",1583 [IEEE80211_SMPS_DYNAMIC] = "dynamic",
1578 };1584 };
1585 int idx;
1579 1586
1580 if (conf->chandef.chan)1587 if (conf->chandef.chan)
1581 wiphy_debug(hw->wiphy,1588 wiphy_debug(hw->wiphy,
@@ -1598,11 +1605,34 @@ static int mac80211_hwsim_config(struct ieee80211_hw *hw, u32 changed) · 16 unmodified lines
1598 1605
1599 data->idle = !!(conf->flags & IEEE80211_CONF_IDLE);1606 data->idle = !!(conf->flags & IEEE80211_CONF_IDLE);
1600 1607
1601 data->channel = conf->chandef.chan;1608 WARN_ON(conf->chandef.chan && data->use_chanctx);
1609
1610 mutex_lock(&data->mutex);
1611 if (data->scanning && conf->chandef.chan) {
1612 for (idx = 0; idx < ARRAY_SIZE(data->survey_data); idx++) {
1613 if (data->survey_data[idx].channel == data->channel) {
1614 data->survey_data[idx].start =
1615 data->survey_data[idx].next_start;
1616 data->survey_data[idx].end = jiffies;
1617 break;
1618 }
1619 }
1602 1620
1603 WARN_ON(data->channel && data->use_chanctx);1621 data->channel = conf->chandef.chan;
1622
1623 for (idx = 0; idx < ARRAY_SIZE(data->survey_data); idx++) {
1624 if (data->survey_data[idx].channel &&
1625 data->survey_data[idx].channel != data->channel)
1626 continue;
1627 data->survey_data[idx].channel = data->channel;
1628 data->survey_data[idx].next_start = jiffies;
1629 break;
1630 }
1631 } else {
1632 data->channel = conf->chandef.chan;
1633 }
1634 mutex_unlock(&data->mutex);
1604 1635
1605 data->power_level = conf->power_level;
1606 if (!data->started || !data->beacon_int)1636 if (!data->started || !data->beacon_int)
1607 tasklet_hrtimer_cancel(&data->beacon_timer);1637 tasklet_hrtimer_cancel(&data->beacon_timer);
1608 else if (!hrtimer_is_queued(&data->beacon_timer.timer)) {1638 else if (!hrtimer_is_queued(&data->beacon_timer.timer)) {
@@ -1787,28 +1817,37 @@ static int mac80211_hwsim_conf_tx( · 178 unmodified lines
1787 return 0;1817 return 0;
1788}1818}
1789 1819
1790static int mac80211_hwsim_get_survey(1820static int mac80211_hwsim_get_survey(struct ieee80211_hw *hw, int idx,
1791 struct ieee80211_hw *hw, int idx,1821 struct survey_info *survey)
1792 struct survey_info *survey)
1793{1822{
1794 struct ieee80211_conf *conf = &hw->conf;1823 struct mac80211_hwsim_data *hwsim = hw->priv;
1795
1796 wiphy_debug(hw->wiphy, "%s (idx=%d)\n", __func__, idx);
1797 1824
1798 if (idx != 0)1825 if (idx < 0 || idx >= ARRAY_SIZE(hwsim->survey_data))
1799 return -ENOENT;1826 return -ENOENT;
1800 1827
1801 /* Current channel */1828 mutex_lock(&hwsim->mutex);
1802 survey->channel = conf->chandef.chan;1829 survey->channel = hwsim->survey_data[idx].channel;
1830 if (!survey->channel) {
1831 mutex_unlock(&hwsim->mutex);
1832 return -ENOENT;
1833 }
1803 1834
1804 /*1835 /*
1805 * Magically conjured noise level --- this is only ok for simulated hardware.1836 * Magically conjured dummy values --- this is only ok for simulated hardware.
1806 *1837 *
1807 * A real driver which cannot determine the real channel noise MUST NOT1838 * A real driver which cannot determine real values noise MUST NOT
1808 * report any noise, especially not a magically conjured one :-)1839 * report any, especially not a magically conjured ones :-)
1809 */1840 */
1810 survey->filled = SURVEY_INFO_NOISE_DBM;1841 survey->filled = SURVEY_INFO_NOISE_DBM |
1842 SURVEY_INFO_TIME |
1843 SURVEY_INFO_TIME_BUSY;
1811 survey->noise = -92;1844 survey->noise = -92;
1845 survey->time =
1846 jiffies_to_msecs(hwsim->survey_data[idx].end -
1847 hwsim->survey_data[idx].start);
1848 /* report 12.5% of channel time is used */
1849 survey->time_busy = survey->time/8;
1850 mutex_unlock(&hwsim->mutex);
1812 1851
1813 return 0;1852 return 0;
1814}1853}
@@ -1986,6 +2025,10 @@ static void hw_scan_work(struct work_struct *work) · 171 unmodified lines
1986 }2025 }
1987 ieee80211_queue_delayed_work(hwsim->hw, &hwsim->hw_scan,2026 ieee80211_queue_delayed_work(hwsim->hw, &hwsim->hw_scan,
1988 msecs_to_jiffies(dwell));2027 msecs_to_jiffies(dwell));
2028 hwsim->survey_data[hwsim->scan_chan_idx].channel = hwsim->tmp_chan;
2029 hwsim->survey_data[hwsim->scan_chan_idx].start = jiffies;
2030 hwsim->survey_data[hwsim->scan_chan_idx].end =
2031 jiffies + msecs_to_jiffies(dwell);
1989 hwsim->scan_chan_idx++;2032 hwsim->scan_chan_idx++;
1990 mutex_unlock(&hwsim->mutex);2033 mutex_unlock(&hwsim->mutex);
1991}2034}
@@ -2011,6 +2054,7 @@ static int mac80211_hwsim_hw_scan(struct ieee80211_hw *hw, · 19 unmodified lines
2011 hw_req->req.mac_addr_mask);2054 hw_req->req.mac_addr_mask);
2012 else2055 else
2013 memcpy(hwsim->scan_addr, vif->addr, ETH_ALEN);2056 memcpy(hwsim->scan_addr, vif->addr, ETH_ALEN);
2057 memset(hwsim->survey_data, 0, sizeof(hwsim->survey_data));
2014 mutex_unlock(&hwsim->mutex);2058 mutex_unlock(&hwsim->mutex);
2015 2059
2016 wiphy_debug(hw->wiphy, "hwsim hw_scan request\n");2060 wiphy_debug(hw->wiphy, "hwsim hw_scan request\n");
@@ -2057,6 +2101,7 @@ static void mac80211_hwsim_sw_scan(struct ieee80211_hw *hw, · 40 unmodified lines
2057 2101
2058 memcpy(hwsim->scan_addr, mac_addr, ETH_ALEN);2102 memcpy(hwsim->scan_addr, mac_addr, ETH_ALEN);
2059 hwsim->scanning = true;2103 hwsim->scanning = true;
2104 memset(hwsim->survey_data, 0, sizeof(hwsim->survey_data));
2060 2105
2061out:2106out:
2062 mutex_unlock(&hwsim->mutex);2107 mutex_unlock(&hwsim->mutex);
@@ -2207,7 +2252,6 @@ static const char mac80211_hwsim_gstrings_stats[][ETH_GSTRING_LEN] = { · 144 unmodified lines
2207 "d_tx_failed",2252 "d_tx_failed",
2208 "d_ps_mode",2253 "d_ps_mode",
2209 "d_group",2254 "d_group",
2210 "d_tx_power",
2211};2255};
2212 2256
2213#define MAC80211_HWSIM_SSTATS_LEN ARRAY_SIZE(mac80211_hwsim_gstrings_stats)2257#define MAC80211_HWSIM_SSTATS_LEN ARRAY_SIZE(mac80211_hwsim_gstrings_stats)
@@ -2244,7 +2288,6 @@ static void mac80211_hwsim_get_et_stats(struct ieee80211_hw *hw, · 30 unmodified lines
2244 data[i++] = ar->tx_failed;2288 data[i++] = ar->tx_failed;
2245 data[i++] = ar->ps;2289 data[i++] = ar->ps;
2246 data[i++] = ar->group;2290 data[i++] = ar->group;
2247 data[i++] = ar->power_level;
2248 2291
2249 WARN_ON(i != MAC80211_HWSIM_SSTATS_LEN);2292 WARN_ON(i != MAC80211_HWSIM_SSTATS_LEN);
2250}2293}
@@ -2438,6 +2481,9 @@ static int mac80211_hwsim_new_radio(struct genl_info *info, · 187 unmodified lines
2438 goto failed;2481 goto failed;
2439 }2482 }
2440 2483
2484 /* ieee80211_alloc_hw_nm may have used a default name */
2485 param->hwname = wiphy_name(hw->wiphy);
2486
2441 if (info)2487 if (info)
2442 net = genl_info_net(info);2488 net = genl_info_net(info);
2443 else2489 else
@@ -2645,6 +2691,8 @@ static int mac80211_hwsim_new_radio(struct genl_info *info, · 201 unmodified lines
2645 if (param->no_vif)2691 if (param->no_vif)
2646 ieee80211_hw_set(hw, NO_AUTO_VIF);2692 ieee80211_hw_set(hw, NO_AUTO_VIF);
2647 2693
2694 wiphy_ext_feature_set(hw->wiphy, NL80211_EXT_FEATURE_CQM_RSSI_LIST);
2695
2648 err = ieee80211_register_hw(hw);2696 err = ieee80211_register_hw(hw);
2649 if (err < 0) {2697 if (err < 0) {
2650 printk(KERN_DEBUG "mac80211_hwsim: ieee80211_register_hw failed (%d)\n",2698 printk(KERN_DEBUG "mac80211_hwsim: ieee80211_register_hw failed (%d)\n",
drivers/net/wireless/mac80211_hwsim.h+2−2
@@ -57,12 +57,12 @@ enum hwsim_tx_control_flags { · 56 unmodified lines
57 * @HWSIM_CMD_REGISTER: request to register and received all broadcasted57 * @HWSIM_CMD_REGISTER: request to register and received all broadcasted
58 * frames by any mac80211_hwsim radio device.58 * frames by any mac80211_hwsim radio device.
59 * @HWSIM_CMD_FRAME: send/receive a broadcasted frame from/to kernel/user59 * @HWSIM_CMD_FRAME: send/receive a broadcasted frame from/to kernel/user
60 * space, uses:60 * space, uses:
61 * %HWSIM_ATTR_ADDR_TRANSMITTER, %HWSIM_ATTR_ADDR_RECEIVER,61 * %HWSIM_ATTR_ADDR_TRANSMITTER, %HWSIM_ATTR_ADDR_RECEIVER,
62 * %HWSIM_ATTR_FRAME, %HWSIM_ATTR_FLAGS, %HWSIM_ATTR_RX_RATE,62 * %HWSIM_ATTR_FRAME, %HWSIM_ATTR_FLAGS, %HWSIM_ATTR_RX_RATE,
63 * %HWSIM_ATTR_SIGNAL, %HWSIM_ATTR_COOKIE, %HWSIM_ATTR_FREQ (optional)63 * %HWSIM_ATTR_SIGNAL, %HWSIM_ATTR_COOKIE, %HWSIM_ATTR_FREQ (optional)
64 * @HWSIM_CMD_TX_INFO_FRAME: Transmission info report from user space to64 * @HWSIM_CMD_TX_INFO_FRAME: Transmission info report from user space to
65 * kernel, uses:65 * kernel, uses:
66 * %HWSIM_ATTR_ADDR_TRANSMITTER, %HWSIM_ATTR_FLAGS,66 * %HWSIM_ATTR_ADDR_TRANSMITTER, %HWSIM_ATTR_FLAGS,
67 * %HWSIM_ATTR_TX_INFO, %HWSIM_ATTR_SIGNAL, %HWSIM_ATTR_COOKIE67 * %HWSIM_ATTR_TX_INFO, %HWSIM_ATTR_SIGNAL, %HWSIM_ATTR_COOKIE
68 * @HWSIM_CMD_NEW_RADIO: create a new radio with the given parameters,68 * @HWSIM_CMD_NEW_RADIO: create a new radio with the given parameters,
drivers/net/wireless/marvell/libertas/cfg.c+1−1
@@ -1657,7 +1657,7 @@ static int lbs_cfg_get_station(struct wiphy *wiphy, struct net_device *dev, · 1656 unmodified lines
1657 */1657 */
1658 1658
1659static int lbs_change_intf(struct wiphy *wiphy, struct net_device *dev,1659static int lbs_change_intf(struct wiphy *wiphy, struct net_device *dev,
1660 enum nl80211_iftype type, u32 *flags,1660 enum nl80211_iftype type,
1661 struct vif_params *params)1661 struct vif_params *params)
1662{1662{
1663 struct lbs_private *priv = wiphy_priv(wiphy);1663 struct lbs_private *priv = wiphy_priv(wiphy);
drivers/net/wireless/marvell/libertas_tf/main.c+2−0
@@ -641,6 +641,8 @@ struct lbtf_private *lbtf_add_card(void *card, struct device *dmdev) · 640 unmodified lines
641 BIT(NL80211_IFTYPE_ADHOC);641 BIT(NL80211_IFTYPE_ADHOC);
642 skb_queue_head_init(&priv->bc_ps_buf);642 skb_queue_head_init(&priv->bc_ps_buf);
643 643
644 wiphy_ext_feature_set(hw->wiphy, NL80211_EXT_FEATURE_CQM_RSSI_LIST);
645
644 SET_IEEE80211_DEV(hw, dmdev);646 SET_IEEE80211_DEV(hw, dmdev);
645 647
646 INIT_WORK(&priv->cmd_work, lbtf_cmd_work);648 INIT_WORK(&priv->cmd_work, lbtf_cmd_work);
drivers/net/wireless/marvell/mwifiex/cfg80211.c+12−15
@@ -935,7 +935,7 @@ mwifiex_init_new_priv_params(struct mwifiex_private *priv, · 934 unmodified lines
935static int935static int
936mwifiex_change_vif_to_p2p(struct net_device *dev,936mwifiex_change_vif_to_p2p(struct net_device *dev,
937 enum nl80211_iftype curr_iftype,937 enum nl80211_iftype curr_iftype,
938 enum nl80211_iftype type, u32 *flags,938 enum nl80211_iftype type,
939 struct vif_params *params)939 struct vif_params *params)
940{940{
941 struct mwifiex_private *priv;941 struct mwifiex_private *priv;
@@ -1007,7 +1007,7 @@ mwifiex_change_vif_to_p2p(struct net_device *dev, · 65 unmodified lines
1007static int1007static int
1008mwifiex_change_vif_to_sta_adhoc(struct net_device *dev,1008mwifiex_change_vif_to_sta_adhoc(struct net_device *dev,
1009 enum nl80211_iftype curr_iftype,1009 enum nl80211_iftype curr_iftype,
1010 enum nl80211_iftype type, u32 *flags,1010 enum nl80211_iftype type,
1011 struct vif_params *params)1011 struct vif_params *params)
1012{1012{
1013 struct mwifiex_private *priv;1013 struct mwifiex_private *priv;
@@ -1066,7 +1066,7 @@ mwifiex_change_vif_to_sta_adhoc(struct net_device *dev, · 52 unmodified lines
1066static int1066static int
1067mwifiex_change_vif_to_ap(struct net_device *dev,1067mwifiex_change_vif_to_ap(struct net_device *dev,
1068 enum nl80211_iftype curr_iftype,1068 enum nl80211_iftype curr_iftype,
1069 enum nl80211_iftype type, u32 *flags,1069 enum nl80211_iftype type,
1070 struct vif_params *params)1070 struct vif_params *params)
1071{1071{
1072 struct mwifiex_private *priv;1072 struct mwifiex_private *priv;
@@ -1122,7 +1122,7 @@ mwifiex_change_vif_to_ap(struct net_device *dev, · 49 unmodified lines
1122static int1122static int
1123mwifiex_cfg80211_change_virtual_intf(struct wiphy *wiphy,1123mwifiex_cfg80211_change_virtual_intf(struct wiphy *wiphy,
1124 struct net_device *dev,1124 struct net_device *dev,
1125 enum nl80211_iftype type, u32 *flags,1125 enum nl80211_iftype type,
1126 struct vif_params *params)1126 struct vif_params *params)
1127{1127{
1128 struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);1128 struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
@@ -1143,10 +1143,10 @@ mwifiex_cfg80211_change_virtual_intf(struct wiphy *wiphy, · 14 unmodified lines
1143 case NL80211_IFTYPE_P2P_CLIENT:1143 case NL80211_IFTYPE_P2P_CLIENT:
1144 case NL80211_IFTYPE_P2P_GO:1144 case NL80211_IFTYPE_P2P_GO:
1145 return mwifiex_change_vif_to_p2p(dev, curr_iftype,1145 return mwifiex_change_vif_to_p2p(dev, curr_iftype,
1146 type, flags, params);1146 type, params);
1147 case NL80211_IFTYPE_AP:1147 case NL80211_IFTYPE_AP:
1148 return mwifiex_change_vif_to_ap(dev, curr_iftype, type,1148 return mwifiex_change_vif_to_ap(dev, curr_iftype, type,
1149 flags, params);1149 params);
1150 case NL80211_IFTYPE_UNSPECIFIED:1150 case NL80211_IFTYPE_UNSPECIFIED:
1151 mwifiex_dbg(priv->adapter, INFO,1151 mwifiex_dbg(priv->adapter, INFO,
1152 "%s: kept type as IBSS\n", dev->name);1152 "%s: kept type as IBSS\n", dev->name);
@@ -1173,10 +1173,10 @@ mwifiex_cfg80211_change_virtual_intf(struct wiphy *wiphy, · 20 unmodified lines
1173 case NL80211_IFTYPE_P2P_CLIENT:1173 case NL80211_IFTYPE_P2P_CLIENT:
1174 case NL80211_IFTYPE_P2P_GO:1174 case NL80211_IFTYPE_P2P_GO:
1175 return mwifiex_change_vif_to_p2p(dev, curr_iftype,1175 return mwifiex_change_vif_to_p2p(dev, curr_iftype,
1176 type, flags, params);1176 type, params);
1177 case NL80211_IFTYPE_AP:1177 case NL80211_IFTYPE_AP:
1178 return mwifiex_change_vif_to_ap(dev, curr_iftype, type,1178 return mwifiex_change_vif_to_ap(dev, curr_iftype, type,
1179 flags, params);1179 params);
1180 case NL80211_IFTYPE_UNSPECIFIED:1180 case NL80211_IFTYPE_UNSPECIFIED:
1181 mwifiex_dbg(priv->adapter, INFO,1181 mwifiex_dbg(priv->adapter, INFO,
1182 "%s: kept type as STA\n", dev->name);1182 "%s: kept type as STA\n", dev->name);
@@ -1194,13 +1194,12 @@ mwifiex_cfg80211_change_virtual_intf(struct wiphy *wiphy, · 11 unmodified lines
1194 case NL80211_IFTYPE_ADHOC:1194 case NL80211_IFTYPE_ADHOC:
1195 case NL80211_IFTYPE_STATION:1195 case NL80211_IFTYPE_STATION:
1196 return mwifiex_change_vif_to_sta_adhoc(dev, curr_iftype,1196 return mwifiex_change_vif_to_sta_adhoc(dev, curr_iftype,
1197 type, flags,1197 type, params);
1198 params);
1199 break;1198 break;
1200 case NL80211_IFTYPE_P2P_CLIENT:1199 case NL80211_IFTYPE_P2P_CLIENT:
1201 case NL80211_IFTYPE_P2P_GO:1200 case NL80211_IFTYPE_P2P_GO:
1202 return mwifiex_change_vif_to_p2p(dev, curr_iftype,1201 return mwifiex_change_vif_to_p2p(dev, curr_iftype,
1203 type, flags, params);1202 type, params);
1204 case NL80211_IFTYPE_UNSPECIFIED:1203 case NL80211_IFTYPE_UNSPECIFIED:
1205 mwifiex_dbg(priv->adapter, INFO,1204 mwifiex_dbg(priv->adapter, INFO,
1206 "%s: kept type as AP\n", dev->name);1205 "%s: kept type as AP\n", dev->name);
@@ -1233,14 +1232,13 @@ mwifiex_cfg80211_change_virtual_intf(struct wiphy *wiphy, · 26 unmodified lines
1233 if (mwifiex_cfg80211_deinit_p2p(priv))1232 if (mwifiex_cfg80211_deinit_p2p(priv))
1234 return -EFAULT;1233 return -EFAULT;
1235 return mwifiex_change_vif_to_sta_adhoc(dev, curr_iftype,1234 return mwifiex_change_vif_to_sta_adhoc(dev, curr_iftype,
1236 type, flags,1235 type, params);
1237 params);
1238 break;1236 break;
1239 case NL80211_IFTYPE_AP:1237 case NL80211_IFTYPE_AP:
1240 if (mwifiex_cfg80211_deinit_p2p(priv))1238 if (mwifiex_cfg80211_deinit_p2p(priv))
1241 return -EFAULT;1239 return -EFAULT;
1242 return mwifiex_change_vif_to_ap(dev, curr_iftype, type,1240 return mwifiex_change_vif_to_ap(dev, curr_iftype, type,
1243 flags, params);1241 params);
1244 case NL80211_IFTYPE_UNSPECIFIED:1242 case NL80211_IFTYPE_UNSPECIFIED:
1245 mwifiex_dbg(priv->adapter, INFO,1243 mwifiex_dbg(priv->adapter, INFO,
1246 "%s: kept type as P2P\n", dev->name);1244 "%s: kept type as P2P\n", dev->name);
@@ -2841,7 +2839,6 @@ struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy, · 1594 unmodified lines
2841 const char *name,2839 const char *name,
2842 unsigned char name_assign_type,2840 unsigned char name_assign_type,
2843 enum nl80211_iftype type,2841 enum nl80211_iftype type,
2844 u32 *flags,
2845 struct vif_params *params)2842 struct vif_params *params)
2846{2843{
2847 struct mwifiex_adapter *adapter = mwifiex_cfg80211_get_adapter(wiphy);2844 struct mwifiex_adapter *adapter = mwifiex_cfg80211_get_adapter(wiphy);
drivers/net/wireless/marvell/mwifiex/main.c+3−4
@@ -596,7 +596,7 @@ static int _mwifiex_fw_dpc(const struct firmware *firmware, void *context) · 595 unmodified lines
596 rtnl_lock();596 rtnl_lock();
597 /* Create station interface by default */597 /* Create station interface by default */
598 wdev = mwifiex_add_virtual_intf(adapter->wiphy, "mlan%d", NET_NAME_ENUM,598 wdev = mwifiex_add_virtual_intf(adapter->wiphy, "mlan%d", NET_NAME_ENUM,
599 NL80211_IFTYPE_STATION, NULL, NULL);599 NL80211_IFTYPE_STATION, NULL);
600 if (IS_ERR(wdev)) {600 if (IS_ERR(wdev)) {
601 mwifiex_dbg(adapter, ERROR,601 mwifiex_dbg(adapter, ERROR,
602 "cannot create default STA interface\n");602 "cannot create default STA interface\n");
@@ -606,7 +606,7 @@ static int _mwifiex_fw_dpc(const struct firmware *firmware, void *context) · 3 unmodified lines
606 606
607 if (driver_mode & MWIFIEX_DRIVER_MODE_UAP) {607 if (driver_mode & MWIFIEX_DRIVER_MODE_UAP) {
608 wdev = mwifiex_add_virtual_intf(adapter->wiphy, "uap%d", NET_NAME_ENUM,608 wdev = mwifiex_add_virtual_intf(adapter->wiphy, "uap%d", NET_NAME_ENUM,
609 NL80211_IFTYPE_AP, NULL, NULL);609 NL80211_IFTYPE_AP, NULL);
610 if (IS_ERR(wdev)) {610 if (IS_ERR(wdev)) {
611 mwifiex_dbg(adapter, ERROR,611 mwifiex_dbg(adapter, ERROR,
612 "cannot create AP interface\n");612 "cannot create AP interface\n");
@@ -617,8 +617,7 @@ static int _mwifiex_fw_dpc(const struct firmware *firmware, void *context) · 4 unmodified lines
617 617
618 if (driver_mode & MWIFIEX_DRIVER_MODE_P2P) {618 if (driver_mode & MWIFIEX_DRIVER_MODE_P2P) {
619 wdev = mwifiex_add_virtual_intf(adapter->wiphy, "p2p%d", NET_NAME_ENUM,619 wdev = mwifiex_add_virtual_intf(adapter->wiphy, "p2p%d", NET_NAME_ENUM,
620 NL80211_IFTYPE_P2P_CLIENT, NULL,620 NL80211_IFTYPE_P2P_CLIENT, NULL);
621 NULL);
622 if (IS_ERR(wdev)) {621 if (IS_ERR(wdev)) {
623 mwifiex_dbg(adapter, ERROR,622 mwifiex_dbg(adapter, ERROR,
624 "cannot create p2p client interface\n");623 "cannot create p2p client interface\n");
drivers/net/wireless/marvell/mwifiex/main.h+0−1
@@ -1529,7 +1529,6 @@ struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy, · 1528 unmodified lines
1529 const char *name,1529 const char *name,
1530 unsigned char name_assign_type,1530 unsigned char name_assign_type,
1531 enum nl80211_iftype type,1531 enum nl80211_iftype type,
1532 u32 *flags,
1533 struct vif_params *params);1532 struct vif_params *params);
1534int mwifiex_del_virtual_intf(struct wiphy *wiphy, struct wireless_dev *wdev);1533int mwifiex_del_virtual_intf(struct wiphy *wiphy, struct wireless_dev *wdev);
1535 1534
drivers/net/wireless/marvell/mwifiex/tdls.c+1−1
@@ -349,7 +349,7 @@ static int mwifiex_tdls_add_vht_oper(struct mwifiex_private *priv, · 348 unmodified lines
349 chan_bw = IEEE80211_VHT_CHANWIDTH_USE_HT;349 chan_bw = IEEE80211_VHT_CHANWIDTH_USE_HT;
350 break;350 break;
351 }351 }
352 vht_oper->center_freq_seg1_idx =352 vht_oper->center_freq_seg0_idx =
353 mwifiex_get_center_freq_index(priv, BAND_AAC,353 mwifiex_get_center_freq_index(priv, BAND_AAC,
354 bss_desc->channel,354 bss_desc->channel,
355 chan_bw);355 chan_bw);
drivers/net/wireless/marvell/mwl8k.c+2−0
@@ -6144,6 +6144,8 @@ static int mwl8k_firmware_load_success(struct mwl8k_priv *priv) · 6143 unmodified lines
6144 if (priv->sta_macids_supported || priv->device_info->fw_image_sta)6144 if (priv->sta_macids_supported || priv->device_info->fw_image_sta)
6145 hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_STATION);6145 hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_STATION);
6146 6146
6147 wiphy_ext_feature_set(hw->wiphy, NL80211_EXT_FEATURE_CQM_RSSI_LIST);
6148
6147 rc = ieee80211_register_hw(hw);6149 rc = ieee80211_register_hw(hw);
6148 if (rc) {6150 if (rc) {
6149 wiphy_err(hw->wiphy, "Cannot register device\n");6151 wiphy_err(hw->wiphy, "Cannot register device\n");
drivers/net/wireless/mediatek/mt7601u/init.c+2−0
@@ -615,6 +615,8 @@ int mt7601u_register_device(struct mt7601u_dev *dev) · 614 unmodified lines
615 wiphy->features |= NL80211_FEATURE_ACTIVE_MONITOR;615 wiphy->features |= NL80211_FEATURE_ACTIVE_MONITOR;
616 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION);616 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION);
617 617
618 wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_CQM_RSSI_LIST);
619
618 ret = mt76_init_sband_2g(dev);620 ret = mt76_init_sband_2g(dev);
619 if (ret)621 if (ret)
620 return ret;622 return ret;
drivers/net/wireless/ralink/rt2x00/rt2x00dev.c+3−0
@@ -1456,6 +1456,9 @@ int rt2x00lib_probe_dev(struct rt2x00_dev *rt2x00dev) · 1455 unmodified lines
1456 1456
1457 rt2x00dev->hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN;1457 rt2x00dev->hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN;
1458 1458
1459 wiphy_ext_feature_set(rt2x00dev->hw->wiphy,
1460 NL80211_EXT_FEATURE_CQM_RSSI_LIST);
1461
1459 /*1462 /*
1460 * Initialize ieee80211 structure.1463 * Initialize ieee80211 structure.
1461 */1464 */
drivers/net/wireless/realtek/rtl818x/rtl8180/dev.c+2−0
@@ -1877,6 +1877,8 @@ static int rtl8180_probe(struct pci_dev *pdev, · 1876 unmodified lines
1877 else1877 else
1878 ieee80211_hw_set(dev, SIGNAL_UNSPEC);1878 ieee80211_hw_set(dev, SIGNAL_UNSPEC);
1879 1879
1880 wiphy_ext_feature_set(dev->wiphy, NL80211_EXT_FEATURE_CQM_RSSI_LIST);
1881
1880 rtl8180_eeprom_read(priv);1882 rtl8180_eeprom_read(priv);
1881 1883
1882 switch (priv->rf_type) {1884 switch (priv->rf_type) {
drivers/net/wireless/realtek/rtl818x/rtl8187/dev.c+2−0
@@ -1607,6 +1607,8 @@ static int rtl8187_probe(struct usb_interface *intf, · 1606 unmodified lines
1607 dev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |1607 dev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
1608 BIT(NL80211_IFTYPE_ADHOC) ;1608 BIT(NL80211_IFTYPE_ADHOC) ;
1609 1609
1610 wiphy_ext_feature_set(dev->wiphy, NL80211_EXT_FEATURE_CQM_RSSI_LIST);
1611
1610 if ((id->driver_info == DEVICE_RTL8187) && priv->is_rtl8187b)1612 if ((id->driver_info == DEVICE_RTL8187) && priv->is_rtl8187b)
1611 printk(KERN_INFO "rtl8187: inconsistency between id with OEM"1613 printk(KERN_INFO "rtl8187: inconsistency between id with OEM"
1612 " info!\n");1614 " info!\n");
drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c+2−0
@@ -6135,6 +6135,8 @@ static int rtl8xxxu_probe(struct usb_interface *interface, · 6134 unmodified lines
6135 ieee80211_hw_set(hw, HAS_RATE_CONTROL);6135 ieee80211_hw_set(hw, HAS_RATE_CONTROL);
6136 ieee80211_hw_set(hw, AMPDU_AGGREGATION);6136 ieee80211_hw_set(hw, AMPDU_AGGREGATION);
6137 6137
6138 wiphy_ext_feature_set(hw->wiphy, NL80211_EXT_FEATURE_CQM_RSSI_LIST);
6139
6138 ret = ieee80211_register_hw(priv->hw);6140 ret = ieee80211_register_hw(priv->hw);
6139 if (ret) {6141 if (ret) {
6140 dev_err(&udev->dev, "%s: Failed to register: %i\n",6142 dev_err(&udev->dev, "%s: Failed to register: %i\n",
drivers/net/wireless/rndis_wlan.c+2−2
@@ -479,7 +479,7 @@ struct rndis_wlan_private { · 478 unmodified lines
479 */479 */
480static int rndis_change_virtual_intf(struct wiphy *wiphy,480static int rndis_change_virtual_intf(struct wiphy *wiphy,
481 struct net_device *dev,481 struct net_device *dev,
482 enum nl80211_iftype type, u32 *flags,482 enum nl80211_iftype type,
483 struct vif_params *params);483 struct vif_params *params);
484 484
485static int rndis_scan(struct wiphy *wiphy,485static int rndis_scan(struct wiphy *wiphy,
@@ -1857,7 +1857,7 @@ error: · 1371 unmodified lines
1857 */1857 */
1858static int rndis_change_virtual_intf(struct wiphy *wiphy,1858static int rndis_change_virtual_intf(struct wiphy *wiphy,
1859 struct net_device *dev,1859 struct net_device *dev,
1860 enum nl80211_iftype type, u32 *flags,1860 enum nl80211_iftype type,
1861 struct vif_params *params)1861 struct vif_params *params)
1862{1862{
1863 struct rndis_wlan_private *priv = wiphy_priv(wiphy);1863 struct rndis_wlan_private *priv = wiphy_priv(wiphy);
drivers/net/wireless/rsi/rsi_91x_mac80211.c+2−0
@@ -1261,6 +1261,8 @@ int rsi_mac80211_attach(struct rsi_common *common) · 1260 unmodified lines
1261 1261
1262 wiphy->reg_notifier = rsi_reg_notify;1262 wiphy->reg_notifier = rsi_reg_notify;
1263 1263
1264 wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_CQM_RSSI_LIST);
1265
1264 status = ieee80211_register_hw(hw);1266 status = ieee80211_register_hw(hw);
1265 if (status)1267 if (status)
1266 return status;1268 return status;
drivers/net/wireless/zydas/zd1211rw/zd_mac.c+2−0
@@ -1408,6 +1408,8 @@ struct ieee80211_hw *zd_mac_alloc_hw(struct usb_interface *intf) · 1407 unmodified lines
1408 BIT(NL80211_IFTYPE_ADHOC) |1408 BIT(NL80211_IFTYPE_ADHOC) |
1409 BIT(NL80211_IFTYPE_AP);1409 BIT(NL80211_IFTYPE_AP);
1410 1410
1411 wiphy_ext_feature_set(hw->wiphy, NL80211_EXT_FEATURE_CQM_RSSI_LIST);
1412
1411 hw->max_signal = 100;1413 hw->max_signal = 100;
1412 hw->queues = 1;1414 hw->queues = 1;
1413 hw->extra_tx_headroom = sizeof(struct zd_ctrlset);1415 hw->extra_tx_headroom = sizeof(struct zd_ctrlset);
drivers/staging/wilc1000/wilc_wfi_cfgoperations.c+1−2
@@ -1837,7 +1837,7 @@ static int set_power_mgmt(struct wiphy *wiphy, struct net_device *dev, · 1836 unmodified lines
1837}1837}
1838 1838
1839static int change_virtual_intf(struct wiphy *wiphy, struct net_device *dev,1839static int change_virtual_intf(struct wiphy *wiphy, struct net_device *dev,
1840 enum nl80211_iftype type, u32 *flags, struct vif_params *params)1840 enum nl80211_iftype type, struct vif_params *params)
1841{1841{
1842 struct wilc_priv *priv;1842 struct wilc_priv *priv;
1843 struct wilc_vif *vif;1843 struct wilc_vif *vif;
@@ -2099,7 +2099,6 @@ static struct wireless_dev *add_virtual_intf(struct wiphy *wiphy, · 255 unmodified lines
2099 const char *name,2099 const char *name,
2100 unsigned char name_assign_type,2100 unsigned char name_assign_type,
2101 enum nl80211_iftype type,2101 enum nl80211_iftype type,
2102 u32 *flags,
2103 struct vif_params *params)2102 struct vif_params *params)
2104{2103{
2105 struct wilc_vif *vif;2104 struct wilc_vif *vif;
drivers/staging/wlan-ng/cfg80211.c+1−1
@@ -100,7 +100,7 @@ static int prism2_domibset_pstr32(struct wlandevice *wlandev, · 99 unmodified lines
100/* The interface functions, called by the cfg80211 layer */100/* The interface functions, called by the cfg80211 layer */
101static int prism2_change_virtual_intf(struct wiphy *wiphy,101static int prism2_change_virtual_intf(struct wiphy *wiphy,
102 struct net_device *dev,102 struct net_device *dev,
103 enum nl80211_iftype type, u32 *flags,103 enum nl80211_iftype type,
104 struct vif_params *params)104 struct vif_params *params)
105{105{
106 struct wlandevice *wlandev = dev->ml_priv;106 struct wlandevice *wlandev = dev->ml_priv;
include/linux/ieee80211.h+18−2
@@ -1411,6 +1411,8 @@ struct ieee80211_ht_operation { · 1410 unmodified lines
1411#define IEEE80211_HT_OP_MODE_PROTECTION_NONHT_MIXED 31411#define IEEE80211_HT_OP_MODE_PROTECTION_NONHT_MIXED 3
1412#define IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT 0x00041412#define IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT 0x0004
1413#define IEEE80211_HT_OP_MODE_NON_HT_STA_PRSNT 0x00101413#define IEEE80211_HT_OP_MODE_NON_HT_STA_PRSNT 0x0010
1414#define IEEE80211_HT_OP_MODE_CCFS2_SHIFT 5
1415#define IEEE80211_HT_OP_MODE_CCFS2_MASK 0x1fe0
1414 1416
1415/* for stbc_param */1417/* for stbc_param */
1416#define IEEE80211_HT_STBC_PARAM_DUAL_BEACON 0x00401418#define IEEE80211_HT_STBC_PARAM_DUAL_BEACON 0x0040
@@ -1525,14 +1527,14 @@ enum ieee80211_vht_chanwidth { · 108 unmodified lines
1525 * This structure is the "VHT operation element" as1527 * This structure is the "VHT operation element" as
1526 * described in 802.11ac D3.0 8.4.2.1611528 * described in 802.11ac D3.0 8.4.2.161
1527 * @chan_width: Operating channel width1529 * @chan_width: Operating channel width
1530 * @center_freq_seg0_idx: center freq segment 0 index
1528 * @center_freq_seg1_idx: center freq segment 1 index1531 * @center_freq_seg1_idx: center freq segment 1 index
1529 * @center_freq_seg2_idx: center freq segment 2 index
1530 * @basic_mcs_set: VHT Basic MCS rate set1532 * @basic_mcs_set: VHT Basic MCS rate set
1531 */1533 */
1532struct ieee80211_vht_operation {1534struct ieee80211_vht_operation {
1533 u8 chan_width;1535 u8 chan_width;
1536 u8 center_freq_seg0_idx;
1534 u8 center_freq_seg1_idx;1537 u8 center_freq_seg1_idx;
1535 u8 center_freq_seg2_idx;
1536 __le16 basic_mcs_set;1538 __le16 basic_mcs_set;
1537} __packed;1539} __packed;
1538 1540
@@ -1721,6 +1723,9 @@ enum ieee80211_statuscode { · 182 unmodified lines
1721 WLAN_STATUS_REJECT_DSE_BAND = 96,1723 WLAN_STATUS_REJECT_DSE_BAND = 96,
1722 WLAN_STATUS_DENIED_WITH_SUGGESTED_BAND_AND_CHANNEL = 99,1724 WLAN_STATUS_DENIED_WITH_SUGGESTED_BAND_AND_CHANNEL = 99,
1723 WLAN_STATUS_DENIED_DUE_TO_SPECTRUM_MANAGEMENT = 103,1725 WLAN_STATUS_DENIED_DUE_TO_SPECTRUM_MANAGEMENT = 103,
1726 /* 802.11ai */
1727 WLAN_STATUS_FILS_AUTHENTICATION_FAILURE = 108,
1728 WLAN_STATUS_UNKNOWN_AUTHENTICATION_SERVER = 109,
1724};1729};
1725 1730
1726 1731
@@ -2102,6 +2107,12 @@ enum ieee80211_key_len { · 375 unmodified lines
2102#define FILS_NONCE_LEN 162107#define FILS_NONCE_LEN 16
2103#define FILS_MAX_KEK_LEN 642108#define FILS_MAX_KEK_LEN 64
2104 2109
2110#define FILS_ERP_MAX_USERNAME_LEN 16
2111#define FILS_ERP_MAX_REALM_LEN 253
2112#define FILS_ERP_MAX_RRK_LEN 64
2113
2114#define PMK_MAX_LEN 48
2115
2105/* Public action codes */2116/* Public action codes */
2106enum ieee80211_pub_actioncode {2117enum ieee80211_pub_actioncode {
2107 WLAN_PUB_ACTION_EXT_CHANSW_ANN = 4,2118 WLAN_PUB_ACTION_EXT_CHANSW_ANN = 4,
@@ -2347,11 +2358,16 @@ enum ieee80211_sa_query_action { · 239 unmodified lines
2347/* AKM suite selectors */2358/* AKM suite selectors */
2348#define WLAN_AKM_SUITE_8021X SUITE(0x000FAC, 1)2359#define WLAN_AKM_SUITE_8021X SUITE(0x000FAC, 1)
2349#define WLAN_AKM_SUITE_PSK SUITE(0x000FAC, 2)2360#define WLAN_AKM_SUITE_PSK SUITE(0x000FAC, 2)
2361#define WLAN_AKM_SUITE_FT_PSK SUITE(0x000FAC, 4)
2350#define WLAN_AKM_SUITE_8021X_SHA256 SUITE(0x000FAC, 5)2362#define WLAN_AKM_SUITE_8021X_SHA256 SUITE(0x000FAC, 5)
2351#define WLAN_AKM_SUITE_PSK_SHA256 SUITE(0x000FAC, 6)2363#define WLAN_AKM_SUITE_PSK_SHA256 SUITE(0x000FAC, 6)
2352#define WLAN_AKM_SUITE_TDLS SUITE(0x000FAC, 7)2364#define WLAN_AKM_SUITE_TDLS SUITE(0x000FAC, 7)
2353#define WLAN_AKM_SUITE_SAE SUITE(0x000FAC, 8)2365#define WLAN_AKM_SUITE_SAE SUITE(0x000FAC, 8)
2354#define WLAN_AKM_SUITE_FT_OVER_SAE SUITE(0x000FAC, 9)2366#define WLAN_AKM_SUITE_FT_OVER_SAE SUITE(0x000FAC, 9)
2367#define WLAN_AKM_SUITE_FILS_SHA256 SUITE(0x000FAC, 14)
2368#define WLAN_AKM_SUITE_FILS_SHA384 SUITE(0x000FAC, 15)
2369#define WLAN_AKM_SUITE_FT_FILS_SHA256 SUITE(0x000FAC, 16)
2370#define WLAN_AKM_SUITE_FT_FILS_SHA384 SUITE(0x000FAC, 17)
2355 2371
2356#define WLAN_MAX_KEY_LEN 322372#define WLAN_MAX_KEY_LEN 32
2357 2373
include/net/cfg80211.h+176−16
@@ -363,6 +363,8 @@ static inline void wiphy_read_of_freq_limits(struct wiphy *wiphy) · 362 unmodified lines
363 363
364/**364/**
365 * struct vif_params - describes virtual interface parameters365 * struct vif_params - describes virtual interface parameters
366 * @flags: monitor interface flags, unchanged if 0, otherwise
367 * %MONITOR_FLAG_CHANGED will be set
366 * @use_4addr: use 4-address frames368 * @use_4addr: use 4-address frames
367 * @macaddr: address to use for this virtual interface.369 * @macaddr: address to use for this virtual interface.
368 * If this parameter is set to zero address the driver may370 * If this parameter is set to zero address the driver may
@@ -370,13 +372,17 @@ static inline void wiphy_read_of_freq_limits(struct wiphy *wiphy) · 1 unmodified line
370 * This feature is only fully supported by drivers that enable the372 * This feature is only fully supported by drivers that enable the
371 * %NL80211_FEATURE_MAC_ON_CREATE flag. Others may support creating373 * %NL80211_FEATURE_MAC_ON_CREATE flag. Others may support creating
372 ** only p2p devices with specified MAC.374 ** only p2p devices with specified MAC.
373 * @vht_mumimo_groups: MU-MIMO groupID. used for monitoring only375 * @vht_mumimo_groups: MU-MIMO groupID, used for monitoring MU-MIMO packets
374 * packets belonging to that MU-MIMO groupID.376 * belonging to that MU-MIMO groupID; %NULL if not changed
377 * @vht_mumimo_follow_addr: MU-MIMO follow address, used for monitoring
378 * MU-MIMO packets going to the specified station; %NULL if not changed
375 */379 */
376struct vif_params {380struct vif_params {
381 u32 flags;
377 int use_4addr;382 int use_4addr;
378 u8 macaddr[ETH_ALEN];383 u8 macaddr[ETH_ALEN];
379 u8 vht_mumimo_groups[VHT_MUMIMO_GROUPS_DATA_LEN];384 const u8 *vht_mumimo_groups;
385 const u8 *vht_mumimo_follow_addr;
380};386};
381 387
382/**388/**
@@ -1211,6 +1217,7 @@ static inline int cfg80211_get_station(struct net_device *dev, · 828 unmodified lines
1211 * Monitor interface configuration flags. Note that these must be the bits1217 * Monitor interface configuration flags. Note that these must be the bits
1212 * according to the nl80211 flags.1218 * according to the nl80211 flags.
1213 *1219 *
1220 * @MONITOR_FLAG_CHANGED: set if the flags were changed
1214 * @MONITOR_FLAG_FCSFAIL: pass frames with bad FCS1221 * @MONITOR_FLAG_FCSFAIL: pass frames with bad FCS
1215 * @MONITOR_FLAG_PLCPFAIL: pass frames with bad PLCP1222 * @MONITOR_FLAG_PLCPFAIL: pass frames with bad PLCP
1216 * @MONITOR_FLAG_CONTROL: pass control frames1223 * @MONITOR_FLAG_CONTROL: pass control frames
@@ -1219,6 +1226,7 @@ static inline int cfg80211_get_station(struct net_device *dev, · 2 unmodified lines
1219 * @MONITOR_FLAG_ACTIVE: active monitor, ACKs frames on its MAC address1226 * @MONITOR_FLAG_ACTIVE: active monitor, ACKs frames on its MAC address
1220 */1227 */
1221enum monitor_flags {1228enum monitor_flags {
1229 MONITOR_FLAG_CHANGED = 1<<__NL80211_MNTR_FLAG_INVALID,
1222 MONITOR_FLAG_FCSFAIL = 1<<NL80211_MNTR_FLAG_FCSFAIL,1230 MONITOR_FLAG_FCSFAIL = 1<<NL80211_MNTR_FLAG_FCSFAIL,
1223 MONITOR_FLAG_PLCPFAIL = 1<<NL80211_MNTR_FLAG_PLCPFAIL,1231 MONITOR_FLAG_PLCPFAIL = 1<<NL80211_MNTR_FLAG_PLCPFAIL,
1224 MONITOR_FLAG_CONTROL = 1<<NL80211_MNTR_FLAG_CONTROL,1232 MONITOR_FLAG_CONTROL = 1<<NL80211_MNTR_FLAG_CONTROL,
@@ -1641,6 +1649,7 @@ struct cfg80211_bss_select_adjust { · 416 unmodified lines
1641/**1649/**
1642 * struct cfg80211_sched_scan_request - scheduled scan request description1650 * struct cfg80211_sched_scan_request - scheduled scan request description
1643 *1651 *
1652 * @reqid: identifies this request.
1644 * @ssids: SSIDs to scan for (passed in the probe_reqs in active scans)1653 * @ssids: SSIDs to scan for (passed in the probe_reqs in active scans)
1645 * @n_ssids: number of SSIDs1654 * @n_ssids: number of SSIDs
1646 * @n_channels: total number of channels to scan1655 * @n_channels: total number of channels to scan
@@ -1685,6 +1694,7 @@ struct cfg80211_bss_select_adjust { · 38 unmodified lines
1685 * comparisions.1694 * comparisions.
1686 */1695 */
1687struct cfg80211_sched_scan_request {1696struct cfg80211_sched_scan_request {
1697 u64 reqid;
1688 struct cfg80211_ssid *ssids;1698 struct cfg80211_ssid *ssids;
1689 int n_ssids;1699 int n_ssids;
1690 u32 n_channels;1700 u32 n_channels;
@@ -2073,6 +2083,19 @@ struct cfg80211_bss_selection { · 382 unmodified lines
2073 * the BSSID of the current association, i.e., to the value that is2083 * the BSSID of the current association, i.e., to the value that is
2074 * included in the Current AP address field of the Reassociation Request2084 * included in the Current AP address field of the Reassociation Request
2075 * frame.2085 * frame.
2086 * @fils_erp_username: EAP re-authentication protocol (ERP) username part of the
2087 * NAI or %NULL if not specified. This is used to construct FILS wrapped
2088 * data IE.
2089 * @fils_erp_username_len: Length of @fils_erp_username in octets.
2090 * @fils_erp_realm: EAP re-authentication protocol (ERP) realm part of NAI or
2091 * %NULL if not specified. This specifies the domain name of ER server and
2092 * is used to construct FILS wrapped data IE.
2093 * @fils_erp_realm_len: Length of @fils_erp_realm in octets.
2094 * @fils_erp_next_seq_num: The next sequence number to use in the FILS ERP
2095 * messages. This is also used to construct FILS wrapped data IE.
2096 * @fils_erp_rrk: ERP re-authentication Root Key (rRK) used to derive additional
2097 * keys in FILS or %NULL if not specified.
2098 * @fils_erp_rrk_len: Length of @fils_erp_rrk in octets.
2076 */2099 */
2077struct cfg80211_connect_params {2100struct cfg80211_connect_params {
2078 struct ieee80211_channel *channel;2101 struct ieee80211_channel *channel;
@@ -2098,6 +2121,13 @@ struct cfg80211_connect_params { · 19 unmodified lines
2098 bool pbss;2121 bool pbss;
2099 struct cfg80211_bss_selection bss_select;2122 struct cfg80211_bss_selection bss_select;
2100 const u8 *prev_bssid;2123 const u8 *prev_bssid;
2124 const u8 *fils_erp_username;
2125 size_t fils_erp_username_len;
2126 const u8 *fils_erp_realm;
2127 size_t fils_erp_realm_len;
2128 u16 fils_erp_next_seq_num;
2129 const u8 *fils_erp_rrk;
2130 size_t fils_erp_rrk_len;
2101};2131};
2102 2132
2103/**2133/**
@@ -2136,12 +2166,27 @@ enum wiphy_params_flags { · 32 unmodified lines
2136 * This structure is passed to the set/del_pmksa() method for PMKSA2166 * This structure is passed to the set/del_pmksa() method for PMKSA
2137 * caching.2167 * caching.
2138 *2168 *
2139 * @bssid: The AP's BSSID.2169 * @bssid: The AP's BSSID (may be %NULL).
2140 * @pmkid: The PMK material itself.2170 * @pmkid: The identifier to refer a PMKSA.
2171 * @pmk: The PMK for the PMKSA identified by @pmkid. This is used for key
2172 * derivation by a FILS STA. Otherwise, %NULL.
2173 * @pmk_len: Length of the @pmk. The length of @pmk can differ depending on
2174 * the hash algorithm used to generate this.
2175 * @ssid: SSID to specify the ESS within which a PMKSA is valid when using FILS
2176 * cache identifier (may be %NULL).
2177 * @ssid_len: Length of the @ssid in octets.
2178 * @cache_id: 2-octet cache identifier advertized by a FILS AP identifying the
2179 * scope of PMKSA. This is valid only if @ssid_len is non-zero (may be
2180 * %NULL).
2141 */2181 */
2142struct cfg80211_pmksa {2182struct cfg80211_pmksa {
2143 const u8 *bssid;2183 const u8 *bssid;
2144 const u8 *pmkid;2184 const u8 *pmkid;
2185 const u8 *pmk;
2186 size_t pmk_len;
2187 const u8 *ssid;
2188 size_t ssid_len;
2189 const u8 *cache_id;
2145};2190};
2146 2191
2147/**2192/**
@@ -2712,6 +2757,11 @@ struct cfg80211_nan_func { · 564 unmodified lines
2712 * the current level is above/below the configured threshold; this may2757 * the current level is above/below the configured threshold; this may
2713 * need some care when the configuration is changed (without first being2758 * need some care when the configuration is changed (without first being
2714 * disabled.)2759 * disabled.)
2760 * @set_cqm_rssi_range_config: Configure two RSSI thresholds in the
2761 * connection quality monitor. An event is to be sent only when the
2762 * signal level is found to be outside the two values. The driver should
2763 * set %NL80211_EXT_FEATURE_CQM_RSSI_LIST if this method is implemented.
2764 * If it is provided then there's no point providing @set_cqm_rssi_config.
2715 * @set_cqm_txe_config: Configure connection quality monitor TX error2765 * @set_cqm_txe_config: Configure connection quality monitor TX error
2716 * thresholds.2766 * thresholds.
2717 * @sched_scan_start: Tell the driver to start a scheduled scan.2767 * @sched_scan_start: Tell the driver to start a scheduled scan.
@@ -2826,13 +2876,12 @@ struct cfg80211_ops { · 108 unmodified lines
2826 const char *name,2876 const char *name,
2827 unsigned char name_assign_type,2877 unsigned char name_assign_type,
2828 enum nl80211_iftype type,2878 enum nl80211_iftype type,
2829 u32 *flags,
2830 struct vif_params *params);2879 struct vif_params *params);
2831 int (*del_virtual_intf)(struct wiphy *wiphy,2880 int (*del_virtual_intf)(struct wiphy *wiphy,
2832 struct wireless_dev *wdev);2881 struct wireless_dev *wdev);
2833 int (*change_virtual_intf)(struct wiphy *wiphy,2882 int (*change_virtual_intf)(struct wiphy *wiphy,
2834 struct net_device *dev,2883 struct net_device *dev,
2835 enum nl80211_iftype type, u32 *flags,2884 enum nl80211_iftype type,
2836 struct vif_params *params);2885 struct vif_params *params);
2837 2886
2838 int (*add_key)(struct wiphy *wiphy, struct net_device *netdev,2887 int (*add_key)(struct wiphy *wiphy, struct net_device *netdev,
@@ -3001,6 +3050,10 @@ struct cfg80211_ops { · 162 unmodified lines
3001 struct net_device *dev,3050 struct net_device *dev,
3002 s32 rssi_thold, u32 rssi_hyst);3051 s32 rssi_thold, u32 rssi_hyst);
3003 3052
3053 int (*set_cqm_rssi_range_config)(struct wiphy *wiphy,
3054 struct net_device *dev,
3055 s32 rssi_low, s32 rssi_high);
3056
3004 int (*set_cqm_txe_config)(struct wiphy *wiphy,3057 int (*set_cqm_txe_config)(struct wiphy *wiphy,
3005 struct net_device *dev,3058 struct net_device *dev,
3006 u32 rate, u32 pkts, u32 intvl);3059 u32 rate, u32 pkts, u32 intvl);
@@ -3871,6 +3924,7 @@ void wiphy_free(struct wiphy *wiphy); · 864 unmodified lines
3871struct cfg80211_conn;3924struct cfg80211_conn;
3872struct cfg80211_internal_bss;3925struct cfg80211_internal_bss;
3873struct cfg80211_cached_keys;3926struct cfg80211_cached_keys;
3927struct cfg80211_cqm_config;
3874 3928
3875/**3929/**
3876 * struct wireless_dev - wireless device state3930 * struct wireless_dev - wireless device state
@@ -3934,6 +3988,7 @@ struct cfg80211_cached_keys; · 57 unmodified lines
3934 * @event_list: (private) list for internal event processing3988 * @event_list: (private) list for internal event processing
3935 * @event_lock: (private) lock for event list3989 * @event_lock: (private) lock for event list
3936 * @owner_nlportid: (private) owner socket port ID3990 * @owner_nlportid: (private) owner socket port ID
3991 * @cqm_config: (private) nl80211 RSSI monitor state
3937 */3992 */
3938struct wireless_dev {3993struct wireless_dev {
3939 struct wiphy *wiphy;3994 struct wiphy *wiphy;
@@ -4002,6 +4057,8 @@ struct wireless_dev { · 62 unmodified lines
4002 bool prev_bssid_valid;4057 bool prev_bssid_valid;
4003 } wext;4058 } wext;
4004#endif4059#endif
4060
4061 struct cfg80211_cqm_config *cqm_config;
4005};4062};
4006 4063
4007static inline u8 *wdev_address(struct wireless_dev *wdev)4064static inline u8 *wdev_address(struct wireless_dev *wdev)
@@ -4651,12 +4708,22 @@ cfg80211_inform_bss(struct wiphy *wiphy, · 643 unmodified lines
4651 gfp);4708 gfp);
4652}4709}
4653 4710
4711/**
4712 * cfg80211_get_bss - get a BSS reference
4713 * @wiphy: the wiphy this BSS struct belongs to
4714 * @channel: the channel to search on (or %NULL)
4715 * @bssid: the desired BSSID (or %NULL)
4716 * @ssid: the desired SSID (or %NULL)
4717 * @ssid_len: length of the SSID (or 0)
4718 * @bss_type: type of BSS, see &enum ieee80211_bss_type
4719 * @privacy: privacy filter, see &enum ieee80211_privacy
4720 */
4654struct cfg80211_bss *cfg80211_get_bss(struct wiphy *wiphy,4721struct cfg80211_bss *cfg80211_get_bss(struct wiphy *wiphy,
4655 struct ieee80211_channel *channel,4722 struct ieee80211_channel *channel,
4656 const u8 *bssid,4723 const u8 *bssid,
4657 const u8 *ssid, size_t ssid_len,4724 const u8 *ssid, size_t ssid_len,
4658 enum ieee80211_bss_type bss_type,4725 enum ieee80211_bss_type bss_type,
4659 enum ieee80211_privacy);4726 enum ieee80211_privacy privacy);
4660static inline struct cfg80211_bss *4727static inline struct cfg80211_bss *
4661cfg80211_get_ibss(struct wiphy *wiphy,4728cfg80211_get_ibss(struct wiphy *wiphy,
4662 struct ieee80211_channel *channel,4729 struct ieee80211_channel *channel,
@@ -5122,6 +5189,78 @@ static inline void cfg80211_testmode_event(struct sk_buff *skb, gfp_t gfp) · 459 unmodified lines
5122#define CFG80211_TESTMODE_DUMP(cmd)5189#define CFG80211_TESTMODE_DUMP(cmd)
5123#endif5190#endif
5124 5191
5192/**
5193 * struct cfg80211_connect_resp_params - Connection response params
5194 * @status: Status code, %WLAN_STATUS_SUCCESS for successful connection, use
5195 * %WLAN_STATUS_UNSPECIFIED_FAILURE if your device cannot give you
5196 * the real status code for failures. If this call is used to report a
5197 * failure due to a timeout (e.g., not receiving an Authentication frame
5198 * from the AP) instead of an explicit rejection by the AP, -1 is used to
5199 * indicate that this is a failure, but without a status code.
5200 * @timeout_reason is used to report the reason for the timeout in that
5201 * case.
5202 * @bssid: The BSSID of the AP (may be %NULL)
5203 * @bss: Entry of bss to which STA got connected to, can be obtained through
5204 * cfg80211_get_bss() (may be %NULL). Only one parameter among @bssid and
5205 * @bss needs to be specified.
5206 * @req_ie: Association request IEs (may be %NULL)
5207 * @req_ie_len: Association request IEs length
5208 * @resp_ie: Association response IEs (may be %NULL)
5209 * @resp_ie_len: Association response IEs length
5210 * @fils_kek: KEK derived from a successful FILS connection (may be %NULL)
5211 * @fils_kek_len: Length of @fils_kek in octets
5212 * @update_erp_next_seq_num: Boolean value to specify whether the value in
5213 * @fils_erp_next_seq_num is valid.
5214 * @fils_erp_next_seq_num: The next sequence number to use in ERP message in
5215 * FILS Authentication. This value should be specified irrespective of the
5216 * status for a FILS connection.
5217 * @pmk: A new PMK if derived from a successful FILS connection (may be %NULL).
5218 * @pmk_len: Length of @pmk in octets
5219 * @pmkid: A new PMKID if derived from a successful FILS connection or the PMKID
5220 * used for this FILS connection (may be %NULL).
5221 * @timeout_reason: Reason for connection timeout. This is used when the
5222 * connection fails due to a timeout instead of an explicit rejection from
5223 * the AP. %NL80211_TIMEOUT_UNSPECIFIED is used when the timeout reason is
5224 * not known. This value is used only if @status < 0 to indicate that the
5225 * failure is due to a timeout and not due to explicit rejection by the AP.
5226 * This value is ignored in other cases (@status >= 0).
5227 */
5228struct cfg80211_connect_resp_params {
5229 int status;
5230 const u8 *bssid;
5231 struct cfg80211_bss *bss;
5232 const u8 *req_ie;
5233 size_t req_ie_len;
5234 const u8 *resp_ie;
5235 size_t resp_ie_len;
5236 const u8 *fils_kek;
5237 size_t fils_kek_len;
5238 bool update_erp_next_seq_num;
5239 u16 fils_erp_next_seq_num;
5240 const u8 *pmk;
5241 size_t pmk_len;
5242 const u8 *pmkid;
5243 enum nl80211_timeout_reason timeout_reason;
5244};
5245
5246/**
5247 * cfg80211_connect_done - notify cfg80211 of connection result
5248 *
5249 * @dev: network device
5250 * @params: connection response parameters
5251 * @gfp: allocation flags
5252 *
5253 * It should be called by the underlying driver once execution of the connection
5254 * request from connect() has been completed. This is similar to
5255 * cfg80211_connect_bss(), but takes a structure pointer for connection response
5256 * parameters. Only one of the functions among cfg80211_connect_bss(),
5257 * cfg80211_connect_result(), cfg80211_connect_timeout(),
5258 * and cfg80211_connect_done() should be called.
5259 */
5260void cfg80211_connect_done(struct net_device *dev,
5261 struct cfg80211_connect_resp_params *params,
5262 gfp_t gfp);
5263
5125/**5264/**
5126 * cfg80211_connect_bss - notify cfg80211 of connection result5265 * cfg80211_connect_bss - notify cfg80211 of connection result
5127 *5266 *
@@ -5152,13 +5291,31 @@ static inline void cfg80211_testmode_event(struct sk_buff *skb, gfp_t gfp) · 24 unmodified lines
5152 * It should be called by the underlying driver once execution of the connection5291 * It should be called by the underlying driver once execution of the connection
5153 * request from connect() has been completed. This is similar to5292 * request from connect() has been completed. This is similar to
5154 * cfg80211_connect_result(), but with the option of identifying the exact bss5293 * cfg80211_connect_result(), but with the option of identifying the exact bss
5155 * entry for the connection. Only one of these functions should be called.5294 * entry for the connection. Only one of the functions among
5295 * cfg80211_connect_bss(), cfg80211_connect_result(),
5296 * cfg80211_connect_timeout(), and cfg80211_connect_done() should be called.
5156 */5297 */
5157void cfg80211_connect_bss(struct net_device *dev, const u8 *bssid,5298static inline void
5158 struct cfg80211_bss *bss, const u8 *req_ie,5299cfg80211_connect_bss(struct net_device *dev, const u8 *bssid,
5159 size_t req_ie_len, const u8 *resp_ie,5300 struct cfg80211_bss *bss, const u8 *req_ie,
5160 size_t resp_ie_len, int status, gfp_t gfp,5301 size_t req_ie_len, const u8 *resp_ie,
5161 enum nl80211_timeout_reason timeout_reason);5302 size_t resp_ie_len, int status, gfp_t gfp,
5303 enum nl80211_timeout_reason timeout_reason)
5304{
5305 struct cfg80211_connect_resp_params params;
5306
5307 memset(&params, 0, sizeof(params));
5308 params.status = status;
5309 params.bssid = bssid;
5310 params.bss = bss;
5311 params.req_ie = req_ie;
5312 params.req_ie_len = req_ie_len;
5313 params.resp_ie = resp_ie;
5314 params.resp_ie_len = resp_ie_len;
5315 params.timeout_reason = timeout_reason;
5316
5317 cfg80211_connect_done(dev, &params, gfp);
5318}
5162 5319
5163/**5320/**
5164 * cfg80211_connect_result - notify cfg80211 of connection result5321 * cfg80211_connect_result - notify cfg80211 of connection result
@@ -5177,7 +5334,8 @@ void cfg80211_connect_bss(struct net_device *dev, const u8 *bssid, · 12 unmodified lines
5177 * It should be called by the underlying driver once execution of the connection5334 * It should be called by the underlying driver once execution of the connection
5178 * request from connect() has been completed. This is similar to5335 * request from connect() has been completed. This is similar to
5179 * cfg80211_connect_bss() which allows the exact bss entry to be specified. Only5336 * cfg80211_connect_bss() which allows the exact bss entry to be specified. Only
5180 * one of these functions should be called.5337 * one of the functions among cfg80211_connect_bss(), cfg80211_connect_result(),
5338 * cfg80211_connect_timeout(), and cfg80211_connect_done() should be called.
5181 */5339 */
5182static inline void5340static inline void
5183cfg80211_connect_result(struct net_device *dev, const u8 *bssid,5341cfg80211_connect_result(struct net_device *dev, const u8 *bssid,
@@ -5204,7 +5362,9 @@ cfg80211_connect_result(struct net_device *dev, const u8 *bssid, · 20 unmodified lines
5204 * in a sequence where no explicit authentication/association rejection was5362 * in a sequence where no explicit authentication/association rejection was
5205 * received from the AP. This could happen, e.g., due to not being able to send5363 * received from the AP. This could happen, e.g., due to not being able to send
5206 * out the Authentication or Association Request frame or timing out while5364 * out the Authentication or Association Request frame or timing out while
5207 * waiting for the response.5365 * waiting for the response. Only one of the functions among
5366 * cfg80211_connect_bss(), cfg80211_connect_result(),
5367 * cfg80211_connect_timeout(), and cfg80211_connect_done() should be called.
5208 */5368 */
5209static inline void5369static inline void
5210cfg80211_connect_timeout(struct net_device *dev, const u8 *bssid,5370cfg80211_connect_timeout(struct net_device *dev, const u8 *bssid,
include/net/mac80211.h+6−4
@@ -501,6 +501,10 @@ struct ieee80211_mu_group_data { · 500 unmodified lines
501 * implies disabled. As with the cfg80211 callback, a change here should501 * implies disabled. As with the cfg80211 callback, a change here should
502 * cause an event to be sent indicating where the current value is in502 * cause an event to be sent indicating where the current value is in
503 * relation to the newly configured threshold.503 * relation to the newly configured threshold.
504 * @cqm_rssi_low: Connection quality monitor RSSI lower threshold, a zero value
505 * implies disabled. This is an alternative mechanism to the single
506 * threshold event and can't be enabled simultaneously with it.
507 * @cqm_rssi_high: Connection quality monitor RSSI upper threshold.
504 * @cqm_rssi_hyst: Connection quality monitor RSSI hysteresis508 * @cqm_rssi_hyst: Connection quality monitor RSSI hysteresis
505 * @arp_addr_list: List of IPv4 addresses for hardware ARP filtering. The509 * @arp_addr_list: List of IPv4 addresses for hardware ARP filtering. The
506 * may filter ARP queries targeted for other addresses than listed here.510 * may filter ARP queries targeted for other addresses than listed here.
@@ -553,6 +557,8 @@ struct ieee80211_bss_conf { · 46 unmodified lines
553 u16 ht_operation_mode;557 u16 ht_operation_mode;
554 s32 cqm_rssi_thold;558 s32 cqm_rssi_thold;
555 u32 cqm_rssi_hyst;559 u32 cqm_rssi_hyst;
560 s32 cqm_rssi_low;
561 s32 cqm_rssi_high;
556 struct cfg80211_chan_def chandef;562 struct cfg80211_chan_def chandef;
557 struct ieee80211_mu_group_data mu_group;563 struct ieee80211_mu_group_data mu_group;
558 __be32 arp_addr_list[IEEE80211_BSS_ARP_ADDR_LIST_LEN];564 __be32 arp_addr_list[IEEE80211_BSS_ARP_ADDR_LIST_LEN];
@@ -5438,9 +5444,6 @@ void ieee80211_stop_rx_ba_session_offl(struct ieee80211_vif *vif, · 4879 unmodified lines
5438 * RTS threshold5444 * RTS threshold
5439 * @short_preamble: whether mac80211 will request short-preamble transmission5445 * @short_preamble: whether mac80211 will request short-preamble transmission
5440 * if the selected rate supports it5446 * if the selected rate supports it
5441 * @max_rate_idx: user-requested maximum (legacy) rate
5442 * (deprecated; this will be removed once drivers get updated to use
5443 * rate_idx_mask)
5444 * @rate_idx_mask: user-requested (legacy) rate mask5447 * @rate_idx_mask: user-requested (legacy) rate mask
5445 * @rate_idx_mcs_mask: user-requested MCS rate mask (NULL if not in use)5448 * @rate_idx_mcs_mask: user-requested MCS rate mask (NULL if not in use)
5446 * @bss: whether this frame is sent out in AP or IBSS mode5449 * @bss: whether this frame is sent out in AP or IBSS mode
@@ -5452,7 +5455,6 @@ struct ieee80211_tx_rate_control { · 5 unmodified lines
5452 struct sk_buff *skb;5455 struct sk_buff *skb;
5453 struct ieee80211_tx_rate reported_rate;5456 struct ieee80211_tx_rate reported_rate;
5454 bool rts, short_preamble;5457 bool rts, short_preamble;
5455 u8 max_rate_idx;
5456 u32 rate_idx_mask;5458 u32 rate_idx_mask;
5457 u8 *rate_idx_mcs_mask;5459 u8 *rate_idx_mcs_mask;
5458 bool bss;5460 bool bss;
include/uapi/linux/nl80211.h+96−4
@@ -172,6 +172,42 @@ · 171 unmodified lines
172 * Multiple such rules can be created.172 * Multiple such rules can be created.
173 */173 */
174 174
175/**
176 * DOC: FILS shared key authentication offload
177 *
178 * FILS shared key authentication offload can be advertized by drivers by
179 * setting @NL80211_EXT_FEATURE_FILS_SK_OFFLOAD flag. The drivers that support
180 * FILS shared key authentication offload should be able to construct the
181 * authentication and association frames for FILS shared key authentication and
182 * eventually do a key derivation as per IEEE 802.11ai. The below additional
183 * parameters should be given to driver in %NL80211_CMD_CONNECT.
184 * %NL80211_ATTR_FILS_ERP_USERNAME - used to construct keyname_nai
185 * %NL80211_ATTR_FILS_ERP_REALM - used to construct keyname_nai
186 * %NL80211_ATTR_FILS_ERP_NEXT_SEQ_NUM - used to construct erp message
187 * %NL80211_ATTR_FILS_ERP_RRK - used to generate the rIK and rMSK
188 * rIK should be used to generate an authentication tag on the ERP message and
189 * rMSK should be used to derive a PMKSA.
190 * rIK, rMSK should be generated and keyname_nai, sequence number should be used
191 * as specified in IETF RFC 6696.
192 *
193 * When FILS shared key authentication is completed, driver needs to provide the
194 * below additional parameters to userspace.
195 * %NL80211_ATTR_FILS_KEK - used for key renewal
196 * %NL80211_ATTR_FILS_ERP_NEXT_SEQ_NUM - used in further EAP-RP exchanges
197 * %NL80211_ATTR_PMKID - used to identify the PMKSA used/generated
198 * %Nl80211_ATTR_PMK - used to update PMKSA cache in userspace
199 * The PMKSA can be maintained in userspace persistently so that it can be used
200 * later after reboots or wifi turn off/on also.
201 *
202 * %NL80211_ATTR_FILS_CACHE_ID is the cache identifier advertized by a FILS
203 * capable AP supporting PMK caching. It specifies the scope within which the
204 * PMKSAs are cached in an ESS. %NL80211_CMD_SET_PMKSA and
205 * %NL80211_CMD_DEL_PMKSA are enhanced to allow support for PMKSA caching based
206 * on FILS cache identifier. Additionally %NL80211_ATTR_PMK is used with
207 * %NL80211_SET_PMKSA to specify the PMK corresponding to a PMKSA for driver to
208 * use in a FILS shared key connection with PMKSA caching.
209 */
210
175/**211/**
176 * enum nl80211_commands - supported nl80211 commands212 * enum nl80211_commands - supported nl80211 commands
177 *213 *
@@ -370,10 +406,18 @@ · 192 unmodified lines
370 * @NL80211_CMD_NEW_SURVEY_RESULTS: survey data notification (as a reply to406 * @NL80211_CMD_NEW_SURVEY_RESULTS: survey data notification (as a reply to
371 * NL80211_CMD_GET_SURVEY and on the "scan" multicast group)407 * NL80211_CMD_GET_SURVEY and on the "scan" multicast group)
372 *408 *
373 * @NL80211_CMD_SET_PMKSA: Add a PMKSA cache entry, using %NL80211_ATTR_MAC409 * @NL80211_CMD_SET_PMKSA: Add a PMKSA cache entry using %NL80211_ATTR_MAC
374 * (for the BSSID) and %NL80211_ATTR_PMKID.410 * (for the BSSID), %NL80211_ATTR_PMKID, and optionally %NL80211_ATTR_PMK
411 * (PMK is used for PTKSA derivation in case of FILS shared key offload) or
412 * using %NL80211_ATTR_SSID, %NL80211_ATTR_FILS_CACHE_ID,
413 * %NL80211_ATTR_PMKID, and %NL80211_ATTR_PMK in case of FILS
414 * authentication where %NL80211_ATTR_FILS_CACHE_ID is the identifier
415 * advertized by a FILS capable AP identifying the scope of PMKSA in an
416 * ESS.
375 * @NL80211_CMD_DEL_PMKSA: Delete a PMKSA cache entry, using %NL80211_ATTR_MAC417 * @NL80211_CMD_DEL_PMKSA: Delete a PMKSA cache entry, using %NL80211_ATTR_MAC
376 * (for the BSSID) and %NL80211_ATTR_PMKID.418 * (for the BSSID) and %NL80211_ATTR_PMKID or using %NL80211_ATTR_SSID,
419 * %NL80211_ATTR_FILS_CACHE_ID, and %NL80211_ATTR_PMKID in case of FILS
420 * authentication.
377 * @NL80211_CMD_FLUSH_PMKSA: Flush all PMKSA cache entries.421 * @NL80211_CMD_FLUSH_PMKSA: Flush all PMKSA cache entries.
378 *422 *
379 * @NL80211_CMD_REG_CHANGE: indicates to userspace the regulatory domain423 * @NL80211_CMD_REG_CHANGE: indicates to userspace the regulatory domain
@@ -2012,6 +2056,31 @@ enum nl80211_commands { · 1632 unmodified lines
2012 * u32 attribute with an &enum nl80211_timeout_reason value. This is used,2056 * u32 attribute with an &enum nl80211_timeout_reason value. This is used,
2013 * e.g., with %NL80211_CMD_CONNECT event.2057 * e.g., with %NL80211_CMD_CONNECT event.
2014 *2058 *
2059 * @NL80211_ATTR_FILS_ERP_USERNAME: EAP Re-authentication Protocol (ERP)
2060 * username part of NAI used to refer keys rRK and rIK. This is used with
2061 * %NL80211_CMD_CONNECT.
2062 *
2063 * @NL80211_ATTR_FILS_ERP_REALM: EAP Re-authentication Protocol (ERP) realm part
2064 * of NAI specifying the domain name of the ER server. This is used with
2065 * %NL80211_CMD_CONNECT.
2066 *
2067 * @NL80211_ATTR_FILS_ERP_NEXT_SEQ_NUM: Unsigned 16-bit ERP next sequence number
2068 * to use in ERP messages. This is used in generating the FILS wrapped data
2069 * for FILS authentication and is used with %NL80211_CMD_CONNECT.
2070 *
2071 * @NL80211_ATTR_FILS_ERP_RRK: ERP re-authentication Root Key (rRK) for the
2072 * NAI specified by %NL80211_ATTR_FILS_ERP_USERNAME and
2073 * %NL80211_ATTR_FILS_ERP_REALM. This is used for generating rIK and rMSK
2074 * from successful FILS authentication and is used with
2075 * %NL80211_CMD_CONNECT.
2076 *
2077 * @NL80211_ATTR_FILS_CACHE_ID: A 2-octet identifier advertized by a FILS AP
2078 * identifying the scope of PMKSAs. This is used with
2079 * @NL80211_CMD_SET_PMKSA and @NL80211_CMD_DEL_PMKSA.
2080 *
2081 * @NL80211_ATTR_PMK: PMK for the PMKSA identified by %NL80211_ATTR_PMKID.
2082 * This is used with @NL80211_CMD_SET_PMKSA.
2083 *
2015 * @NUM_NL80211_ATTR: total number of nl80211_attrs available2084 * @NUM_NL80211_ATTR: total number of nl80211_attrs available
2016 * @NL80211_ATTR_MAX: highest attribute number currently defined2085 * @NL80211_ATTR_MAX: highest attribute number currently defined
2017 * @__NL80211_ATTR_AFTER_LAST: internal use2086 * @__NL80211_ATTR_AFTER_LAST: internal use
@@ -2423,6 +2492,14 @@ enum nl80211_attrs { · 405 unmodified lines
2423 2492
2424 NL80211_ATTR_TIMEOUT_REASON,2493 NL80211_ATTR_TIMEOUT_REASON,
2425 2494
2495 NL80211_ATTR_FILS_ERP_USERNAME,
2496 NL80211_ATTR_FILS_ERP_REALM,
2497 NL80211_ATTR_FILS_ERP_NEXT_SEQ_NUM,
2498 NL80211_ATTR_FILS_ERP_RRK,
2499 NL80211_ATTR_FILS_CACHE_ID,
2500
2501 NL80211_ATTR_PMK,
2502
2426 /* add attributes here, update the policy in nl80211.c */2503 /* add attributes here, update the policy in nl80211.c */
2427 2504
2428 __NL80211_ATTR_AFTER_LAST,2505 __NL80211_ATTR_AFTER_LAST,
@@ -3942,7 +4019,10 @@ enum nl80211_ps_state { · 1513 unmodified lines
3942 * @__NL80211_ATTR_CQM_INVALID: invalid4019 * @__NL80211_ATTR_CQM_INVALID: invalid
3943 * @NL80211_ATTR_CQM_RSSI_THOLD: RSSI threshold in dBm. This value specifies4020 * @NL80211_ATTR_CQM_RSSI_THOLD: RSSI threshold in dBm. This value specifies
3944 * the threshold for the RSSI level at which an event will be sent. Zero4021 * the threshold for the RSSI level at which an event will be sent. Zero
3945 * to disable.4022 * to disable. Alternatively, if %NL80211_EXT_FEATURE_CQM_RSSI_LIST is
4023 * set, multiple values can be supplied as a low-to-high sorted array of
4024 * threshold values in dBm. Events will be sent when the RSSI value
4025 * crosses any of the thresholds.
3946 * @NL80211_ATTR_CQM_RSSI_HYST: RSSI hysteresis in dBm. This value specifies4026 * @NL80211_ATTR_CQM_RSSI_HYST: RSSI hysteresis in dBm. This value specifies
3947 * the minimum amount the RSSI level must change after an event before a4027 * the minimum amount the RSSI level must change after an event before a
3948 * new event may be issued (to reduce effects of RSSI oscillation).4028 * new event may be issued (to reduce effects of RSSI oscillation).
@@ -4753,6 +4833,11 @@ enum nl80211_feature_flags { · 804 unmodified lines
4753 * @NL80211_EXT_FEATURE_SCHED_SCAN_RELATIVE_RSSI: The driver supports sched_scan4833 * @NL80211_EXT_FEATURE_SCHED_SCAN_RELATIVE_RSSI: The driver supports sched_scan
4754 * for reporting BSSs with better RSSI than the current connected BSS4834 * for reporting BSSs with better RSSI than the current connected BSS
4755 * (%NL80211_ATTR_SCHED_SCAN_RELATIVE_RSSI).4835 * (%NL80211_ATTR_SCHED_SCAN_RELATIVE_RSSI).
4836 * @NL80211_EXT_FEATURE_CQM_RSSI_LIST: With this driver the
4837 * %NL80211_ATTR_CQM_RSSI_THOLD attribute accepts a list of zero or more
4838 * RSSI threshold values to monitor rather than exactly one threshold.
4839 * @NL80211_EXT_FEATURE_FILS_SK_OFFLOAD: Driver SME supports FILS shared key
4840 * authentication with %NL80211_CMD_CONNECT.
4756 *4841 *
4757 * @NUM_NL80211_EXT_FEATURES: number of extended features.4842 * @NUM_NL80211_EXT_FEATURES: number of extended features.
4758 * @MAX_NL80211_EXT_FEATURES: highest extended feature index.4843 * @MAX_NL80211_EXT_FEATURES: highest extended feature index.
@@ -4771,6 +4856,8 @@ enum nl80211_ext_feature_index { · 12 unmodified lines
4771 NL80211_EXT_FEATURE_MGMT_TX_RANDOM_TA,4856 NL80211_EXT_FEATURE_MGMT_TX_RANDOM_TA,
4772 NL80211_EXT_FEATURE_MGMT_TX_RANDOM_TA_CONNECTED,4857 NL80211_EXT_FEATURE_MGMT_TX_RANDOM_TA_CONNECTED,
4773 NL80211_EXT_FEATURE_SCHED_SCAN_RELATIVE_RSSI,4858 NL80211_EXT_FEATURE_SCHED_SCAN_RELATIVE_RSSI,
4859 NL80211_EXT_FEATURE_CQM_RSSI_LIST,
4860 NL80211_EXT_FEATURE_FILS_SK_OFFLOAD,
4774 4861
4775 /* add new features before the definition below */4862 /* add new features before the definition below */
4776 NUM_NL80211_EXT_FEATURES,4863 NUM_NL80211_EXT_FEATURES,
@@ -4906,12 +4993,17 @@ enum nl80211_smps_mode { · 129 unmodified lines
4906 * change to the channel status.4993 * change to the channel status.
4907 * @NL80211_RADAR_NOP_FINISHED: The Non-Occupancy Period for this channel is4994 * @NL80211_RADAR_NOP_FINISHED: The Non-Occupancy Period for this channel is
4908 * over, channel becomes usable.4995 * over, channel becomes usable.
4996 * @NL80211_RADAR_PRE_CAC_EXPIRED: Channel Availability Check done on this
4997 * non-operating channel is expired and no longer valid. New CAC must
4998 * be done on this channel before starting the operation. This is not
4999 * applicable for ETSI dfs domain where pre-CAC is valid for ever.
4909 */5000 */
4910enum nl80211_radar_event {5001enum nl80211_radar_event {
4911 NL80211_RADAR_DETECTED,5002 NL80211_RADAR_DETECTED,
4912 NL80211_RADAR_CAC_FINISHED,5003 NL80211_RADAR_CAC_FINISHED,
4913 NL80211_RADAR_CAC_ABORTED,5004 NL80211_RADAR_CAC_ABORTED,
4914 NL80211_RADAR_NOP_FINISHED,5005 NL80211_RADAR_NOP_FINISHED,
5006 NL80211_RADAR_PRE_CAC_EXPIRED,
4915};5007};
4916 5008
4917/**5009/**
net/mac80211/agg-rx.c+6−6
@@ -357,14 +357,14 @@ void __ieee80211_start_rx_ba_session(struct sta_info *sta, · 356 unmodified lines
357 spin_lock_init(&tid_agg_rx->reorder_lock);357 spin_lock_init(&tid_agg_rx->reorder_lock);
358 358
359 /* rx timer */359 /* rx timer */
360 tid_agg_rx->session_timer.function = sta_rx_agg_session_timer_expired;360 setup_deferrable_timer(&tid_agg_rx->session_timer,
361 tid_agg_rx->session_timer.data = (unsigned long)&sta->timer_to_tid[tid];361 sta_rx_agg_session_timer_expired,
362 init_timer_deferrable(&tid_agg_rx->session_timer);362 (unsigned long)&sta->timer_to_tid[tid]);
363 363
364 /* rx reorder timer */364 /* rx reorder timer */
365 tid_agg_rx->reorder_timer.function = sta_rx_agg_reorder_timer_expired;365 setup_timer(&tid_agg_rx->reorder_timer,
366 tid_agg_rx->reorder_timer.data = (unsigned long)&sta->timer_to_tid[tid];366 sta_rx_agg_reorder_timer_expired,
367 init_timer(&tid_agg_rx->reorder_timer);367 (unsigned long)&sta->timer_to_tid[tid]);
368 368
369 /* prepare reordering buffer */369 /* prepare reordering buffer */
370 tid_agg_rx->reorder_buf =370 tid_agg_rx->reorder_buf =
net/mac80211/agg-tx.c+6−6
@@ -670,14 +670,14 @@ int ieee80211_start_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid, · 669 unmodified lines
670 tid_tx->timeout = timeout;670 tid_tx->timeout = timeout;
671 671
672 /* response timer */672 /* response timer */
673 tid_tx->addba_resp_timer.function = sta_addba_resp_timer_expired;673 setup_timer(&tid_tx->addba_resp_timer,
674 tid_tx->addba_resp_timer.data = (unsigned long)&sta->timer_to_tid[tid];674 sta_addba_resp_timer_expired,
675 init_timer(&tid_tx->addba_resp_timer);675 (unsigned long)&sta->timer_to_tid[tid]);
676 676
677 /* tx timer */677 /* tx timer */
678 tid_tx->session_timer.function = sta_tx_agg_session_timer_expired;678 setup_deferrable_timer(&tid_tx->session_timer,
679 tid_tx->session_timer.data = (unsigned long)&sta->timer_to_tid[tid];679 sta_tx_agg_session_timer_expired,
680 init_timer_deferrable(&tid_tx->session_timer);680 (unsigned long)&sta->timer_to_tid[tid]);
681 681
682 /* assign a dialog token */682 /* assign a dialog token */
683 sta->ampdu_mlme.dialog_token_allocator++;683 sta->ampdu_mlme.dialog_token_allocator++;
net/mac80211/cfg.c+145−58
@@ -3,7 +3,7 @@ · 2 unmodified lines
3 *3 *
4 * Copyright 2006-2010 Johannes Berg <johannes@sipsolutions.net>4 * Copyright 2006-2010 Johannes Berg <johannes@sipsolutions.net>
5 * Copyright 2013-2015 Intel Mobile Communications GmbH5 * Copyright 2013-2015 Intel Mobile Communications GmbH
6 * Copyright (C) 2015-2016 Intel Deutschland GmbH6 * Copyright (C) 2015-2017 Intel Deutschland GmbH
7 *7 *
8 * This file is GPLv2 as found in COPYING.8 * This file is GPLv2 as found in COPYING.
9 */9 */
@@ -22,11 +22,98 @@ · 12 unmodified lines
22#include "mesh.h"22#include "mesh.h"
23#include "wme.h"23#include "wme.h"
24 24
25static void ieee80211_set_mu_mimo_follow(struct ieee80211_sub_if_data *sdata,
26 struct vif_params *params)
27{
28 bool mu_mimo_groups = false;
29 bool mu_mimo_follow = false;
30
31 if (params->vht_mumimo_groups) {
32 u64 membership;
33
34 BUILD_BUG_ON(sizeof(membership) != WLAN_MEMBERSHIP_LEN);
35
36 memcpy(sdata->vif.bss_conf.mu_group.membership,
37 params->vht_mumimo_groups, WLAN_MEMBERSHIP_LEN);
38 memcpy(sdata->vif.bss_conf.mu_group.position,
39 params->vht_mumimo_groups + WLAN_MEMBERSHIP_LEN,
40 WLAN_USER_POSITION_LEN);
41 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_MU_GROUPS);
42 /* don't care about endianness - just check for 0 */
43 memcpy(&membership, params->vht_mumimo_groups,
44 WLAN_MEMBERSHIP_LEN);
45 mu_mimo_groups = membership != 0;
46 }
47
48 if (params->vht_mumimo_follow_addr) {
49 mu_mimo_follow =
50 is_valid_ether_addr(params->vht_mumimo_follow_addr);
51 ether_addr_copy(sdata->u.mntr.mu_follow_addr,
52 params->vht_mumimo_follow_addr);
53 }
54
55 sdata->vif.mu_mimo_owner = mu_mimo_groups || mu_mimo_follow;
56}
57
58static int ieee80211_set_mon_options(struct ieee80211_sub_if_data *sdata,
59 struct vif_params *params)
60{
61 struct ieee80211_local *local = sdata->local;
62 struct ieee80211_sub_if_data *monitor_sdata;
63
64 /* check flags first */
65 if (params->flags && ieee80211_sdata_running(sdata)) {
66 u32 mask = MONITOR_FLAG_COOK_FRAMES | MONITOR_FLAG_ACTIVE;
67
68 /*
69 * Prohibit MONITOR_FLAG_COOK_FRAMES and
70 * MONITOR_FLAG_ACTIVE to be changed while the
71 * interface is up.
72 * Else we would need to add a lot of cruft
73 * to update everything:
74 * cooked_mntrs, monitor and all fif_* counters
75 * reconfigure hardware
76 */
77 if ((params->flags & mask) != (sdata->u.mntr.flags & mask))
78 return -EBUSY;
79 }
80
81 /* also validate MU-MIMO change */
82 monitor_sdata = rtnl_dereference(local->monitor_sdata);
83
84 if (!monitor_sdata &&
85 (params->vht_mumimo_groups || params->vht_mumimo_follow_addr))
86 return -EOPNOTSUPP;
87
88 /* apply all changes now - no failures allowed */
89
90 if (monitor_sdata)
91 ieee80211_set_mu_mimo_follow(monitor_sdata, params);
92
93 if (params->flags) {
94 if (ieee80211_sdata_running(sdata)) {
95 ieee80211_adjust_monitor_flags(sdata, -1);
96 sdata->u.mntr.flags = params->flags;
97 ieee80211_adjust_monitor_flags(sdata, 1);
98
99 ieee80211_configure_filter(local);
100 } else {
101 /*
102 * Because the interface is down, ieee80211_do_stop
103 * and ieee80211_do_open take care of "everything"
104 * mentioned in the comment above.
105 */
106 sdata->u.mntr.flags = params->flags;
107 }
108 }
109
110 return 0;
111}
112
25static struct wireless_dev *ieee80211_add_iface(struct wiphy *wiphy,113static struct wireless_dev *ieee80211_add_iface(struct wiphy *wiphy,
26 const char *name,114 const char *name,
27 unsigned char name_assign_type,115 unsigned char name_assign_type,
28 enum nl80211_iftype type,116 enum nl80211_iftype type,
29 u32 *flags,
30 struct vif_params *params)117 struct vif_params *params)
31{118{
32 struct ieee80211_local *local = wiphy_priv(wiphy);119 struct ieee80211_local *local = wiphy_priv(wiphy);
@@ -38,9 +125,14 @@ static struct wireless_dev *ieee80211_add_iface(struct wiphy *wiphy, · 5 unmodified lines
38 if (err)125 if (err)
39 return ERR_PTR(err);126 return ERR_PTR(err);
40 127
41 if (type == NL80211_IFTYPE_MONITOR && flags) {128 sdata = IEEE80211_WDEV_TO_SUB_IF(wdev);
42 sdata = IEEE80211_WDEV_TO_SUB_IF(wdev);129
43 sdata->u.mntr.flags = *flags;130 if (type == NL80211_IFTYPE_MONITOR) {
131 err = ieee80211_set_mon_options(sdata, params);
132 if (err) {
133 ieee80211_if_remove(sdata);
134 return NULL;
135 }
44 }136 }
45 137
46 return wdev;138 return wdev;
@@ -55,7 +147,7 @@ static int ieee80211_del_iface(struct wiphy *wiphy, struct wireless_dev *wdev) · 8 unmodified lines
55 147
56static int ieee80211_change_iface(struct wiphy *wiphy,148static int ieee80211_change_iface(struct wiphy *wiphy,
57 struct net_device *dev,149 struct net_device *dev,
58 enum nl80211_iftype type, u32 *flags,150 enum nl80211_iftype type,
59 struct vif_params *params)151 struct vif_params *params)
60{152{
61 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);153 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
@@ -75,58 +167,9 @@ static int ieee80211_change_iface(struct wiphy *wiphy, · 13 unmodified lines
75 }167 }
76 168
77 if (sdata->vif.type == NL80211_IFTYPE_MONITOR) {169 if (sdata->vif.type == NL80211_IFTYPE_MONITOR) {
78 struct ieee80211_local *local = sdata->local;170 ret = ieee80211_set_mon_options(sdata, params);
79 struct ieee80211_sub_if_data *monitor_sdata;171 if (ret)
80 u32 mu_mntr_cap_flag = NL80211_EXT_FEATURE_MU_MIMO_AIR_SNIFFER;172 return ret;
81
82 monitor_sdata = rtnl_dereference(local->monitor_sdata);
83 if (monitor_sdata &&
84 wiphy_ext_feature_isset(wiphy, mu_mntr_cap_flag)) {
85 memcpy(monitor_sdata->vif.bss_conf.mu_group.membership,
86 params->vht_mumimo_groups, WLAN_MEMBERSHIP_LEN);
87 memcpy(monitor_sdata->vif.bss_conf.mu_group.position,
88 params->vht_mumimo_groups + WLAN_MEMBERSHIP_LEN,
89 WLAN_USER_POSITION_LEN);
90 monitor_sdata->vif.mu_mimo_owner = true;
91 ieee80211_bss_info_change_notify(monitor_sdata,
92 BSS_CHANGED_MU_GROUPS);
93
94 ether_addr_copy(monitor_sdata->u.mntr.mu_follow_addr,
95 params->macaddr);
96 }
97
98 if (!flags)
99 return 0;
100
101 if (ieee80211_sdata_running(sdata)) {
102 u32 mask = MONITOR_FLAG_COOK_FRAMES |
103 MONITOR_FLAG_ACTIVE;
104
105 /*
106 * Prohibit MONITOR_FLAG_COOK_FRAMES and
107 * MONITOR_FLAG_ACTIVE to be changed while the
108 * interface is up.
109 * Else we would need to add a lot of cruft
110 * to update everything:
111 * cooked_mntrs, monitor and all fif_* counters
112 * reconfigure hardware
113 */
114 if ((*flags & mask) != (sdata->u.mntr.flags & mask))
115 return -EBUSY;
116
117 ieee80211_adjust_monitor_flags(sdata, -1);
118 sdata->u.mntr.flags = *flags;
119 ieee80211_adjust_monitor_flags(sdata, 1);
120
121 ieee80211_configure_filter(local);
122 } else {
123 /*
124 * Because the interface is down, ieee80211_do_stop
125 * and ieee80211_do_open take care of "everything"
126 * mentioned in the comment above.
127 */
128 sdata->u.mntr.flags = *flags;
129 }
130 }173 }
131 174
132 return 0;175 return 0;
@@ -2042,6 +2085,7 @@ static int ieee80211_change_bss(struct wiphy *wiphy, · 1909 unmodified lines
2042 params->basic_rates_len,2085 params->basic_rates_len,
2043 &sdata->vif.bss_conf.basic_rates);2086 &sdata->vif.bss_conf.basic_rates);
2044 changed |= BSS_CHANGED_BASIC_RATES;2087 changed |= BSS_CHANGED_BASIC_RATES;
2088 ieee80211_check_rate_mask(sdata);
2045 }2089 }
2046 2090
2047 if (params->ap_isolate >= 0) {2091 if (params->ap_isolate >= 0) {
@@ -2630,6 +2674,33 @@ static int ieee80211_set_cqm_rssi_config(struct wiphy *wiphy, · 582 unmodified lines
2630 2674
2631 bss_conf->cqm_rssi_thold = rssi_thold;2675 bss_conf->cqm_rssi_thold = rssi_thold;
2632 bss_conf->cqm_rssi_hyst = rssi_hyst;2676 bss_conf->cqm_rssi_hyst = rssi_hyst;
2677 bss_conf->cqm_rssi_low = 0;
2678 bss_conf->cqm_rssi_high = 0;
2679 sdata->u.mgd.last_cqm_event_signal = 0;
2680
2681 /* tell the driver upon association, unless already associated */
2682 if (sdata->u.mgd.associated &&
2683 sdata->vif.driver_flags & IEEE80211_VIF_SUPPORTS_CQM_RSSI)
2684 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_CQM);
2685
2686 return 0;
2687}
2688
2689static int ieee80211_set_cqm_rssi_range_config(struct wiphy *wiphy,
2690 struct net_device *dev,
2691 s32 rssi_low, s32 rssi_high)
2692{
2693 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
2694 struct ieee80211_vif *vif = &sdata->vif;
2695 struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;
2696
2697 if (sdata->vif.driver_flags & IEEE80211_VIF_BEACON_FILTER)
2698 return -EOPNOTSUPP;
2699
2700 bss_conf->cqm_rssi_low = rssi_low;
2701 bss_conf->cqm_rssi_high = rssi_high;
2702 bss_conf->cqm_rssi_thold = 0;
2703 bss_conf->cqm_rssi_hyst = 0;
2633 sdata->u.mgd.last_cqm_event_signal = 0;2704 sdata->u.mgd.last_cqm_event_signal = 0;
2634 2705
2635 /* tell the driver upon association, unless already associated */2706 /* tell the driver upon association, unless already associated */
@@ -2658,6 +2729,21 @@ static int ieee80211_set_bitrate_mask(struct wiphy *wiphy, · 22 unmodified lines
2658 return ret;2729 return ret;
2659 }2730 }
2660 2731
2732 /*
2733 * If active validate the setting and reject it if it doesn't leave
2734 * at least one basic rate usable, since we really have to be able
2735 * to send something, and if we're an AP we have to be able to do
2736 * so at a basic rate so that all clients can receive it.
2737 */
2738 if (rcu_access_pointer(sdata->vif.chanctx_conf) &&
2739 sdata->vif.bss_conf.chandef.chan) {
2740 u32 basic_rates = sdata->vif.bss_conf.basic_rates;
2741 enum nl80211_band band = sdata->vif.bss_conf.chandef.chan->band;
2742
2743 if (!(mask->control[band].legacy & basic_rates))
2744 return -EINVAL;
2745 }
2746
2661 for (i = 0; i < NUM_NL80211_BANDS; i++) {2747 for (i = 0; i < NUM_NL80211_BANDS; i++) {
2662 struct ieee80211_supported_band *sband = wiphy->bands[i];2748 struct ieee80211_supported_band *sband = wiphy->bands[i];
2663 int j;2749 int j;
@@ -3639,6 +3725,7 @@ const struct cfg80211_ops mac80211_config_ops = { · 975 unmodified lines
3639 .mgmt_tx = ieee80211_mgmt_tx,3725 .mgmt_tx = ieee80211_mgmt_tx,
3640 .mgmt_tx_cancel_wait = ieee80211_mgmt_tx_cancel_wait,3726 .mgmt_tx_cancel_wait = ieee80211_mgmt_tx_cancel_wait,
3641 .set_cqm_rssi_config = ieee80211_set_cqm_rssi_config,3727 .set_cqm_rssi_config = ieee80211_set_cqm_rssi_config,
3728 .set_cqm_rssi_range_config = ieee80211_set_cqm_rssi_range_config,
3642 .mgmt_frame_register = ieee80211_mgmt_frame_register,3729 .mgmt_frame_register = ieee80211_mgmt_frame_register,
3643 .set_antenna = ieee80211_set_antenna,3730 .set_antenna = ieee80211_set_antenna,
3644 .get_antenna = ieee80211_get_antenna,3731 .get_antenna = ieee80211_get_antenna,
net/mac80211/ibss.c+2−2
@@ -425,7 +425,7 @@ static void ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, · 424 unmodified lines
425 case NL80211_CHAN_WIDTH_5:425 case NL80211_CHAN_WIDTH_5:
426 case NL80211_CHAN_WIDTH_10:426 case NL80211_CHAN_WIDTH_10:
427 cfg80211_chandef_create(&chandef, cbss->channel,427 cfg80211_chandef_create(&chandef, cbss->channel,
428 NL80211_CHAN_WIDTH_20_NOHT);428 NL80211_CHAN_NO_HT);
429 chandef.width = sdata->u.ibss.chandef.width;429 chandef.width = sdata->u.ibss.chandef.width;
430 break;430 break;
431 case NL80211_CHAN_WIDTH_80:431 case NL80211_CHAN_WIDTH_80:
@@ -437,7 +437,7 @@ static void ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, · 5 unmodified lines
437 default:437 default:
438 /* fall back to 20 MHz for unsupported modes */438 /* fall back to 20 MHz for unsupported modes */
439 cfg80211_chandef_create(&chandef, cbss->channel,439 cfg80211_chandef_create(&chandef, cbss->channel,
440 NL80211_CHAN_WIDTH_20_NOHT);440 NL80211_CHAN_NO_HT);
441 break;441 break;
442 }442 }
443 443
net/mac80211/ieee80211_i.h+3−0
@@ -839,6 +839,8 @@ struct txq_info { · 838 unmodified lines
839struct ieee80211_if_mntr {839struct ieee80211_if_mntr {
840 u32 flags;840 u32 flags;
841 u8 mu_follow_addr[ETH_ALEN] __aligned(2);841 u8 mu_follow_addr[ETH_ALEN] __aligned(2);
842
843 struct list_head list;
842};844};
843 845
844/**846/**
@@ -1259,6 +1261,7 @@ struct ieee80211_local { · 414 unmodified lines
1259 1261
1260 /* see iface.c */1262 /* see iface.c */
1261 struct list_head interfaces;1263 struct list_head interfaces;
1264 struct list_head mon_list; /* only that are IFF_UP && !cooked */
1262 struct mutex iflist_mtx;1265 struct mutex iflist_mtx;
1263 1266
1264 /*1267 /*
net/mac80211/iface.c+17−2
@@ -676,7 +676,8 @@ int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up) · 675 unmodified lines
676 676
677 set_bit(SDATA_STATE_RUNNING, &sdata->state);677 set_bit(SDATA_STATE_RUNNING, &sdata->state);
678 678
679 if (sdata->vif.type == NL80211_IFTYPE_WDS) {679 switch (sdata->vif.type) {
680 case NL80211_IFTYPE_WDS:
680 /* Create STA entry for the WDS peer */681 /* Create STA entry for the WDS peer */
681 sta = sta_info_alloc(sdata, sdata->u.wds.remote_addr,682 sta = sta_info_alloc(sdata, sdata->u.wds.remote_addr,
682 GFP_KERNEL);683 GFP_KERNEL);
@@ -697,8 +698,17 @@ int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up) · 14 unmodified lines
697 698
698 rate_control_rate_init(sta);699 rate_control_rate_init(sta);
699 netif_carrier_on(dev);700 netif_carrier_on(dev);
700 } else if (sdata->vif.type == NL80211_IFTYPE_P2P_DEVICE) {701 break;
702 case NL80211_IFTYPE_P2P_DEVICE:
701 rcu_assign_pointer(local->p2p_sdata, sdata);703 rcu_assign_pointer(local->p2p_sdata, sdata);
704 break;
705 case NL80211_IFTYPE_MONITOR:
706 if (sdata->u.mntr.flags & MONITOR_FLAG_COOK_FRAMES)
707 break;
708 list_add_tail_rcu(&sdata->u.mntr.list, &local->mon_list);
709 break;
710 default:
711 break;
702 }712 }
703 713
704 /*714 /*
@@ -817,6 +827,11 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, · 112 unmodified lines
817 case NL80211_IFTYPE_AP:827 case NL80211_IFTYPE_AP:
818 cancel_work_sync(&sdata->u.ap.request_smps_work);828 cancel_work_sync(&sdata->u.ap.request_smps_work);
819 break;829 break;
830 case NL80211_IFTYPE_MONITOR:
831 if (sdata->u.mntr.flags & MONITOR_FLAG_COOK_FRAMES)
832 break;
833 list_del_rcu(&sdata->u.mntr.list);
834 break;
820 default:835 default:
821 break;836 break;
822 }837 }
net/mac80211/main.c+1−0
@@ -603,6 +603,7 @@ struct ieee80211_hw *ieee80211_alloc_hw_nm(size_t priv_data_len, · 602 unmodified lines
603 ARRAY_SIZE(local->ext_capa);603 ARRAY_SIZE(local->ext_capa);
604 604
605 INIT_LIST_HEAD(&local->interfaces);605 INIT_LIST_HEAD(&local->interfaces);
606 INIT_LIST_HEAD(&local->mon_list);
606 607
607 __hw_addr_init(&local->mc_list);608 __hw_addr_init(&local->mc_list);
608 609
net/mac80211/mesh.c+8−2
@@ -1100,8 +1100,14 @@ static void ieee80211_mesh_rx_bcn_presp(struct ieee80211_sub_if_data *sdata, · 1099 unmodified lines
1100 if (!channel || channel->flags & IEEE80211_CHAN_DISABLED)1100 if (!channel || channel->flags & IEEE80211_CHAN_DISABLED)
1101 return;1101 return;
1102 1102
1103 if (mesh_matches_local(sdata, &elems))1103 if (mesh_matches_local(sdata, &elems)) {
1104 mesh_neighbour_update(sdata, mgmt->sa, &elems);1104 mpl_dbg(sdata, "rssi_threshold=%d,rx_status->signal=%d\n",
1105 sdata->u.mesh.mshcfg.rssi_threshold, rx_status->signal);
1106 if (!sdata->u.mesh.user_mpm ||
1107 sdata->u.mesh.mshcfg.rssi_threshold == 0 ||
1108 sdata->u.mesh.mshcfg.rssi_threshold < rx_status->signal)
1109 mesh_neighbour_update(sdata, mgmt->sa, &elems);
1110 }
1105 1111
1106 if (ifmsh->sync_ops)1112 if (ifmsh->sync_ops)
1107 ifmsh->sync_ops->rx_bcn_presp(sdata,1113 ifmsh->sync_ops->rx_bcn_presp(sdata,
net/mac80211/mesh_hwmp.c+17−6
@@ -16,6 +16,7 @@ · 15 unmodified lines
16#define TEST_FRAME_LEN 819216#define TEST_FRAME_LEN 8192
17#define MAX_METRIC 0xffffffff17#define MAX_METRIC 0xffffffff
18#define ARITH_SHIFT 818#define ARITH_SHIFT 8
19#define LINK_FAIL_THRESH 95
19 20
20#define MAX_PREQ_QUEUE_LEN 6421#define MAX_PREQ_QUEUE_LEN 64
21 22
@@ -307,10 +308,12 @@ void ieee80211s_update_metric(struct ieee80211_local *local, · 285 unmodified lines
307 308
308 failed = !(txinfo->flags & IEEE80211_TX_STAT_ACK);309 failed = !(txinfo->flags & IEEE80211_TX_STAT_ACK);
309 310
310 /* moving average, scaled to 100 */311 /* moving average, scaled to 100.
311 sta->mesh->fail_avg =312 * feed failure as 100 and success as 0
312 ((80 * sta->mesh->fail_avg + 5) / 100 + 20 * failed);313 */
313 if (sta->mesh->fail_avg > 95)314 ewma_mesh_fail_avg_add(&sta->mesh->fail_avg, failed * 100);
315 if (ewma_mesh_fail_avg_read(&sta->mesh->fail_avg) >
316 LINK_FAIL_THRESH)
314 mesh_plink_broken(sta);317 mesh_plink_broken(sta);
315}318}
316 319
@@ -325,6 +328,8 @@ static u32 airtime_link_metric_get(struct ieee80211_local *local, · 8 unmodified lines
325 int rate, err;328 int rate, err;
326 u32 tx_time, estimated_retx;329 u32 tx_time, estimated_retx;
327 u64 result;330 u64 result;
331 unsigned long fail_avg =
332 ewma_mesh_fail_avg_read(&sta->mesh->fail_avg);
328 333
329 /* Try to get rate based on HW/SW RC algorithm.334 /* Try to get rate based on HW/SW RC algorithm.
330 * Rate is returned in units of Kbps, correct this335 * Rate is returned in units of Kbps, correct this
@@ -336,7 +341,7 @@ static u32 airtime_link_metric_get(struct ieee80211_local *local, · 5 unmodified lines
336 if (rate) {341 if (rate) {
337 err = 0;342 err = 0;
338 } else {343 } else {
339 if (sta->mesh->fail_avg >= 100)344 if (fail_avg > LINK_FAIL_THRESH)
340 return MAX_METRIC;345 return MAX_METRIC;
341 346
342 sta_set_rate_info_tx(sta, &sta->tx_stats.last_rate, &rinfo);347 sta_set_rate_info_tx(sta, &sta->tx_stats.last_rate, &rinfo);
@@ -344,7 +349,7 @@ static u32 airtime_link_metric_get(struct ieee80211_local *local, · 1 unmodified line
344 if (WARN_ON(!rate))349 if (WARN_ON(!rate))
345 return MAX_METRIC;350 return MAX_METRIC;
346 351
347 err = (sta->mesh->fail_avg << ARITH_SHIFT) / 100;352 err = (fail_avg << ARITH_SHIFT) / 100;
348 }353 }
349 354
350 /* bitrate is in units of 100 Kbps, while we need rate in units of355 /* bitrate is in units of 100 Kbps, while we need rate in units of
@@ -484,6 +489,9 @@ static u32 hwmp_route_info_get(struct ieee80211_sub_if_data *sdata, · 133 unmodified lines
484 ? mpath->exp_time : exp_time;489 ? mpath->exp_time : exp_time;
485 mesh_path_activate(mpath);490 mesh_path_activate(mpath);
486 spin_unlock_bh(&mpath->state_lock);491 spin_unlock_bh(&mpath->state_lock);
492 ewma_mesh_fail_avg_init(&sta->mesh->fail_avg);
493 /* init it at a low value - 0 start is tricky */
494 ewma_mesh_fail_avg_add(&sta->mesh->fail_avg, 1);
487 mesh_path_tx_pending(mpath);495 mesh_path_tx_pending(mpath);
488 /* draft says preq_id should be saved to, but there does496 /* draft says preq_id should be saved to, but there does
489 * not seem to be any use for it, skipping by now497 * not seem to be any use for it, skipping by now
@@ -522,6 +530,9 @@ static u32 hwmp_route_info_get(struct ieee80211_sub_if_data *sdata, · 32 unmodified lines
522 ? mpath->exp_time : exp_time;530 ? mpath->exp_time : exp_time;
523 mesh_path_activate(mpath);531 mesh_path_activate(mpath);
524 spin_unlock_bh(&mpath->state_lock);532 spin_unlock_bh(&mpath->state_lock);
533 ewma_mesh_fail_avg_init(&sta->mesh->fail_avg);
534 /* init it at a low value - 0 start is tricky */
535 ewma_mesh_fail_avg_add(&sta->mesh->fail_avg, 1);
525 mesh_path_tx_pending(mpath);536 mesh_path_tx_pending(mpath);
526 } else537 } else
527 spin_unlock_bh(&mpath->state_lock);538 spin_unlock_bh(&mpath->state_lock);
net/mac80211/mesh_pathtbl.c+5−3
@@ -397,11 +397,10 @@ struct mesh_path *mesh_path_new(struct ieee80211_sub_if_data *sdata, · 396 unmodified lines
397 new_mpath->sdata = sdata;397 new_mpath->sdata = sdata;
398 new_mpath->flags = 0;398 new_mpath->flags = 0;
399 skb_queue_head_init(&new_mpath->frame_queue);399 skb_queue_head_init(&new_mpath->frame_queue);
400 new_mpath->timer.data = (unsigned long) new_mpath;
401 new_mpath->timer.function = mesh_path_timer;
402 new_mpath->exp_time = jiffies;400 new_mpath->exp_time = jiffies;
403 spin_lock_init(&new_mpath->state_lock);401 spin_lock_init(&new_mpath->state_lock);
404 init_timer(&new_mpath->timer);402 setup_timer(&new_mpath->timer, mesh_path_timer,
403 (unsigned long) new_mpath);
405 404
406 return new_mpath;405 return new_mpath;
407}406}
@@ -829,6 +828,9 @@ void mesh_path_fix_nexthop(struct mesh_path *mpath, struct sta_info *next_hop) · 421 unmodified lines
829 mpath->flags = MESH_PATH_FIXED | MESH_PATH_SN_VALID;828 mpath->flags = MESH_PATH_FIXED | MESH_PATH_SN_VALID;
830 mesh_path_activate(mpath);829 mesh_path_activate(mpath);
831 spin_unlock_bh(&mpath->state_lock);830 spin_unlock_bh(&mpath->state_lock);
831 ewma_mesh_fail_avg_init(&next_hop->mesh->fail_avg);
832 /* init it at a low value - 0 start is tricky */
833 ewma_mesh_fail_avg_add(&next_hop->mesh->fail_avg, 1);
832 mesh_path_tx_pending(mpath);834 mesh_path_tx_pending(mpath);
833}835}
834 836
net/mac80211/mlme.c+34−7
@@ -1908,6 +1908,8 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata, · 1907 unmodified lines
1908 sdata->u.mgd.associated = cbss;1908 sdata->u.mgd.associated = cbss;
1909 memcpy(sdata->u.mgd.bssid, cbss->bssid, ETH_ALEN);1909 memcpy(sdata->u.mgd.bssid, cbss->bssid, ETH_ALEN);
1910 1910
1911 ieee80211_check_rate_mask(sdata);
1912
1911 sdata->u.mgd.flags |= IEEE80211_STA_RESET_SIGNAL_AVE;1913 sdata->u.mgd.flags |= IEEE80211_STA_RESET_SIGNAL_AVE;
1912 1914
1913 if (sdata->vif.p2p ||1915 if (sdata->vif.p2p ||
@@ -2797,8 +2799,9 @@ static void ieee80211_rx_mgmt_disassoc(struct ieee80211_sub_if_data *sdata, · 883 unmodified lines
2797 2799
2798 reason_code = le16_to_cpu(mgmt->u.disassoc.reason_code);2800 reason_code = le16_to_cpu(mgmt->u.disassoc.reason_code);
2799 2801
2800 sdata_info(sdata, "disassociated from %pM (Reason: %u)\n",2802 sdata_info(sdata, "disassociated from %pM (Reason: %u=%s)\n",
2801 mgmt->sa, reason_code);2803 mgmt->sa, reason_code,
2804 ieee80211_get_reason_code_string(reason_code));
2802 2805
2803 ieee80211_set_disassoc(sdata, 0, 0, false, NULL);2806 ieee80211_set_disassoc(sdata, 0, 0, false, NULL);
2804 2807
@@ -2822,15 +2825,15 @@ static void ieee80211_get_rates(struct ieee80211_supported_band *sband, · 17 unmodified lines
2822 *have_higher_than_11mbit = true;2825 *have_higher_than_11mbit = true;
2823 2826
2824 /*2827 /*
2825 * BSS_MEMBERSHIP_SELECTOR_HT_PHY is defined in 802.11n-20092828 * Skip HT and VHT BSS membership selectors since they're not
2826 * 7.3.2.2 as a magic value instead of a rate. Hence, skip it.2829 * rates.
2827 *2830 *
2828 * Note: Even through the membership selector and the basic2831 * Note: Even though the membership selector and the basic
2829 * rate flag share the same bit, they are not exactly2832 * rate flag share the same bit, they are not exactly
2830 * the same.2833 * the same.
2831 */2834 */
2832 if (!!(supp_rates[i] & 0x80) &&2835 if (supp_rates[i] == (0x80 | BSS_MEMBERSHIP_SELECTOR_HT_PHY) ||
2833 (supp_rates[i] & 0x7f) == BSS_MEMBERSHIP_SELECTOR_HT_PHY)2836 supp_rates[i] == (0x80 | BSS_MEMBERSHIP_SELECTOR_VHT_PHY))
2834 continue;2837 continue;
2835 2838
2836 for (j = 0; j < sband->n_bitrates; j++) {2839 for (j = 0; j < sband->n_bitrates; j++) {
@@ -3430,6 +3433,30 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata, · 593 unmodified lines
3430 }3433 }
3431 }3434 }
3432 3435
3436 if (bss_conf->cqm_rssi_low &&
3437 ifmgd->count_beacon_signal >= IEEE80211_SIGNAL_AVE_MIN_COUNT) {
3438 int sig = -ewma_beacon_signal_read(&ifmgd->ave_beacon_signal);
3439 int last_event = ifmgd->last_cqm_event_signal;
3440 int low = bss_conf->cqm_rssi_low;
3441 int high = bss_conf->cqm_rssi_high;
3442
3443 if (sig < low &&
3444 (last_event == 0 || last_event >= low)) {
3445 ifmgd->last_cqm_event_signal = sig;
3446 ieee80211_cqm_rssi_notify(
3447 &sdata->vif,
3448 NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW,
3449 sig, GFP_KERNEL);
3450 } else if (sig > high &&
3451 (last_event == 0 || last_event <= high)) {
3452 ifmgd->last_cqm_event_signal = sig;
3453 ieee80211_cqm_rssi_notify(
3454 &sdata->vif,
3455 NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH,
3456 sig, GFP_KERNEL);
3457 }
3458 }
3459
3433 if (ifmgd->flags & IEEE80211_STA_CONNECTION_POLL) {3460 if (ifmgd->flags & IEEE80211_STA_CONNECTION_POLL) {
3434 mlme_dbg_ratelimited(sdata,3461 mlme_dbg_ratelimited(sdata,
3435 "cancelling AP probe due to a received beacon\n");3462 "cancelling AP probe due to a received beacon\n");
net/mac80211/rate.c+36−7
@@ -2,6 +2,7 @@ · 1 unmodified line
2 * Copyright 2002-2005, Instant802 Networks, Inc.2 * Copyright 2002-2005, Instant802 Networks, Inc.
3 * Copyright 2005-2006, Devicescape Software, Inc.3 * Copyright 2005-2006, Devicescape Software, Inc.
4 * Copyright (c) 2006 Jiri Benc <jbenc@suse.cz>4 * Copyright (c) 2006 Jiri Benc <jbenc@suse.cz>
5 * Copyright 2017 Intel Deutschland GmbH
5 *6 *
6 * This program is free software; you can redistribute it and/or modify7 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as8 * it under the terms of the GNU General Public License version 2 as
@@ -173,9 +174,11 @@ ieee80211_rate_control_ops_get(const char *name) · 165 unmodified lines
173 /* try default if specific alg requested but not found */174 /* try default if specific alg requested but not found */
174 ops = ieee80211_try_rate_control_ops_get(ieee80211_default_rc_algo);175 ops = ieee80211_try_rate_control_ops_get(ieee80211_default_rc_algo);
175 176
176 /* try built-in one if specific alg requested but not found */177 /* Note: check for > 0 is intentional to avoid clang warning */
177 if (!ops && strlen(CONFIG_MAC80211_RC_DEFAULT))178 if (!ops && (strlen(CONFIG_MAC80211_RC_DEFAULT) > 0))
179 /* try built-in one if specific alg requested but not found */
178 ops = ieee80211_try_rate_control_ops_get(CONFIG_MAC80211_RC_DEFAULT);180 ops = ieee80211_try_rate_control_ops_get(CONFIG_MAC80211_RC_DEFAULT);
181
179 kernel_param_unlock(THIS_MODULE);182 kernel_param_unlock(THIS_MODULE);
180 183
181 return ops;184 return ops;
@@ -208,7 +211,6 @@ static struct rate_control_ref *rate_control_alloc(const char *name, · 26 unmodified lines
208 ref = kmalloc(sizeof(struct rate_control_ref), GFP_KERNEL);211 ref = kmalloc(sizeof(struct rate_control_ref), GFP_KERNEL);
209 if (!ref)212 if (!ref)
210 return NULL;213 return NULL;
211 ref->local = local;
212 ref->ops = ieee80211_rate_control_ops_get(name);214 ref->ops = ieee80211_rate_control_ops_get(name);
213 if (!ref->ops)215 if (!ref->ops)
214 goto free;216 goto free;
@@ -229,18 +231,45 @@ free: · 14 unmodified lines
229 return NULL;231 return NULL;
230}232}
231 233
232static void rate_control_free(struct rate_control_ref *ctrl_ref)234static void rate_control_free(struct ieee80211_local *local,
235 struct rate_control_ref *ctrl_ref)
233{236{
234 ctrl_ref->ops->free(ctrl_ref->priv);237 ctrl_ref->ops->free(ctrl_ref->priv);
235 238
236#ifdef CONFIG_MAC80211_DEBUGFS239#ifdef CONFIG_MAC80211_DEBUGFS
237 debugfs_remove_recursive(ctrl_ref->local->debugfs.rcdir);240 debugfs_remove_recursive(local->debugfs.rcdir);
238 ctrl_ref->local->debugfs.rcdir = NULL;241 local->debugfs.rcdir = NULL;
239#endif242#endif
240 243
241 kfree(ctrl_ref);244 kfree(ctrl_ref);
242}245}
243 246
247void ieee80211_check_rate_mask(struct ieee80211_sub_if_data *sdata)
248{
249 struct ieee80211_local *local = sdata->local;
250 struct ieee80211_supported_band *sband;
251 u32 user_mask, basic_rates = sdata->vif.bss_conf.basic_rates;
252 enum nl80211_band band;
253
254 if (WARN_ON(!sdata->vif.bss_conf.chandef.chan))
255 return;
256
257 if (WARN_ON_ONCE(!basic_rates))
258 return;
259
260 band = sdata->vif.bss_conf.chandef.chan->band;
261 user_mask = sdata->rc_rateidx_mask[band];
262 sband = local->hw.wiphy->bands[band];
263
264 if (user_mask & basic_rates)
265 return;
266
267 sdata_dbg(sdata,
268 "no overlap between basic rates (0x%x) and user mask (0x%x on band %d) - clearing the latter",
269 basic_rates, user_mask, band);
270 sdata->rc_rateidx_mask[band] = (1 << sband->n_bitrates) - 1;
271}
272
244static bool rc_no_data_or_no_ack_use_min(struct ieee80211_tx_rate_control *txrc)273static bool rc_no_data_or_no_ack_use_min(struct ieee80211_tx_rate_control *txrc)
245{274{
246 struct sk_buff *skb = txrc->skb;275 struct sk_buff *skb = txrc->skb;
@@ -936,6 +965,6 @@ void rate_control_deinitialize(struct ieee80211_local *local) · 689 unmodified lines
936 return;965 return;
937 966
938 local->rate_ctrl = NULL;967 local->rate_ctrl = NULL;
939 rate_control_free(ref);968 rate_control_free(local, ref);
940}969}
941 970
net/mac80211/rate.h+2−1
@@ -20,7 +20,6 @@ · 19 unmodified lines
20#include "driver-ops.h"20#include "driver-ops.h"
21 21
22struct rate_control_ref {22struct rate_control_ref {
23 struct ieee80211_local *local;
24 const struct rate_control_ops *ops;23 const struct rate_control_ops *ops;
25 void *priv;24 void *priv;
26};25};
@@ -111,6 +110,8 @@ static inline void rate_control_remove_sta_debugfs(struct sta_info *sta) · 84 unmodified lines
111#endif110#endif
112}111}
113 112
113void ieee80211_check_rate_mask(struct ieee80211_sub_if_data *sdata);
114
114/* Get a reference to the rate control algorithm. If `name' is NULL, get the115/* Get a reference to the rate control algorithm. If `name' is NULL, get the
115 * first available algorithm. */116 * first available algorithm. */
116int ieee80211_init_rate_ctrl_alg(struct ieee80211_local *local,117int ieee80211_init_rate_ctrl_alg(struct ieee80211_local *local,
net/mac80211/rx.c+19−31
@@ -95,24 +95,13 @@ static u8 *ieee80211_get_bssid(struct ieee80211_hdr *hdr, size_t len, · 94 unmodified lines
95 * This function cleans up the SKB, i.e. it removes all the stuff95 * This function cleans up the SKB, i.e. it removes all the stuff
96 * only useful for monitoring.96 * only useful for monitoring.
97 */97 */
98static struct sk_buff *remove_monitor_info(struct ieee80211_local *local,98static void remove_monitor_info(struct sk_buff *skb,
99 struct sk_buff *skb,99 unsigned int present_fcs_len,
100 unsigned int rtap_vendor_space)100 unsigned int rtap_vendor_space)
101{101{
102 if (ieee80211_hw_check(&local->hw, RX_INCLUDES_FCS)) {102 if (present_fcs_len)
103 if (likely(skb->len > FCS_LEN))103 __pskb_trim(skb, skb->len - present_fcs_len);
104 __pskb_trim(skb, skb->len - FCS_LEN);
105 else {
106 /* driver bug */
107 WARN_ON(1);
108 dev_kfree_skb(skb);
109 return NULL;
110 }
111 }
112
113 __pskb_pull(skb, rtap_vendor_space);104 __pskb_pull(skb, rtap_vendor_space);
114
115 return skb;
116}105}
117 106
118static inline bool should_drop_frame(struct sk_buff *skb, int present_fcs_len,107static inline bool should_drop_frame(struct sk_buff *skb, int present_fcs_len,
@@ -534,8 +523,15 @@ ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb, · 415 unmodified lines
534 * the SKB because it has a bad FCS/PLCP checksum.523 * the SKB because it has a bad FCS/PLCP checksum.
535 */524 */
536 525
537 if (ieee80211_hw_check(&local->hw, RX_INCLUDES_FCS))526 if (ieee80211_hw_check(&local->hw, RX_INCLUDES_FCS)) {
527 if (unlikely(origskb->len <= FCS_LEN)) {
528 /* driver bug */
529 WARN_ON(1);
530 dev_kfree_skb(origskb);
531 return NULL;
532 }
538 present_fcs_len = FCS_LEN;533 present_fcs_len = FCS_LEN;
534 }
539 535
540 /* ensure hdr->frame_control and vendor radiotap data are in skb head */536 /* ensure hdr->frame_control and vendor radiotap data are in skb head */
541 if (!pskb_may_pull(origskb, 2 + rtap_vendor_space)) {537 if (!pskb_may_pull(origskb, 2 + rtap_vendor_space)) {
@@ -550,7 +546,9 @@ ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb, · 8 unmodified lines
550 return NULL;546 return NULL;
551 }547 }
552 548
553 return remove_monitor_info(local, origskb, rtap_vendor_space);549 remove_monitor_info(origskb, present_fcs_len,
550 rtap_vendor_space);
551 return origskb;
554 }552 }
555 553
556 /* room for the radiotap header based on driver features */554 /* room for the radiotap header based on driver features */
@@ -580,9 +578,8 @@ ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb, · 23 unmodified lines
580 * and FCS from the original.578 * and FCS from the original.
581 */579 */
582 skb = skb_copy_expand(origskb, needed_headroom, 0, GFP_ATOMIC);580 skb = skb_copy_expand(origskb, needed_headroom, 0, GFP_ATOMIC);
583 581 remove_monitor_info(origskb, present_fcs_len,
584 origskb = remove_monitor_info(local, origskb,582 rtap_vendor_space);
585 rtap_vendor_space);
586 583
587 if (!skb)584 if (!skb)
588 return origskb;585 return origskb;
@@ -596,16 +593,7 @@ ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb, · 7 unmodified lines
596 skb->pkt_type = PACKET_OTHERHOST;593 skb->pkt_type = PACKET_OTHERHOST;
597 skb->protocol = htons(ETH_P_802_2);594 skb->protocol = htons(ETH_P_802_2);
598 595
599 list_for_each_entry_rcu(sdata, &local->interfaces, list) {596 list_for_each_entry_rcu(sdata, &local->mon_list, u.mntr.list) {
600 if (sdata->vif.type != NL80211_IFTYPE_MONITOR)
601 continue;
602
603 if (sdata->u.mntr.flags & MONITOR_FLAG_COOK_FRAMES)
604 continue;
605
606 if (!ieee80211_sdata_running(sdata))
607 continue;
608
609 if (prev_dev) {597 if (prev_dev) {
610 skb2 = skb_clone(skb, GFP_ATOMIC);598 skb2 = skb_clone(skb, GFP_ATOMIC);
611 if (skb2) {599 if (skb2) {
net/mac80211/spectmgmt.c+2−2
@@ -132,9 +132,9 @@ int ieee80211_parse_ch_switch_ie(struct ieee80211_sub_if_data *sdata, · 131 unmodified lines
132 struct ieee80211_vht_operation vht_oper = {132 struct ieee80211_vht_operation vht_oper = {
133 .chan_width =133 .chan_width =
134 wide_bw_chansw_ie->new_channel_width,134 wide_bw_chansw_ie->new_channel_width,
135 .center_freq_seg1_idx =135 .center_freq_seg0_idx =
136 wide_bw_chansw_ie->new_center_freq_seg0,136 wide_bw_chansw_ie->new_center_freq_seg0,
137 .center_freq_seg2_idx =137 .center_freq_seg1_idx =
138 wide_bw_chansw_ie->new_center_freq_seg1,138 wide_bw_chansw_ie->new_center_freq_seg1,
139 /* .basic_mcs_set doesn't matter */139 /* .basic_mcs_set doesn't matter */
140 };140 };
net/mac80211/sta_info.c+8−3
@@ -1960,14 +1960,17 @@ static void sta_stats_decode_rate(struct ieee80211_local *local, u16 rate, · 1959 unmodified lines
1960 rinfo->bw = (rate & STA_STATS_RATE_BW_MASK) >>1960 rinfo->bw = (rate & STA_STATS_RATE_BW_MASK) >>
1961 STA_STATS_RATE_BW_SHIFT;1961 STA_STATS_RATE_BW_SHIFT;
1962 1962
1963 if (rate & STA_STATS_RATE_VHT) {1963 switch (rate & STA_STATS_RATE_TYPE_MASK) {
1964 case STA_STATS_RATE_TYPE_VHT:
1964 rinfo->flags = RATE_INFO_FLAGS_VHT_MCS;1965 rinfo->flags = RATE_INFO_FLAGS_VHT_MCS;
1965 rinfo->mcs = rate & 0xf;1966 rinfo->mcs = rate & 0xf;
1966 rinfo->nss = (rate & 0xf0) >> 4;1967 rinfo->nss = (rate & 0xf0) >> 4;
1967 } else if (rate & STA_STATS_RATE_HT) {1968 break;
1969 case STA_STATS_RATE_TYPE_HT:
1968 rinfo->flags = RATE_INFO_FLAGS_MCS;1970 rinfo->flags = RATE_INFO_FLAGS_MCS;
1969 rinfo->mcs = rate & 0xff;1971 rinfo->mcs = rate & 0xff;
1970 } else if (rate & STA_STATS_RATE_LEGACY) {1972 break;
1973 case STA_STATS_RATE_TYPE_LEGACY: {
1971 struct ieee80211_supported_band *sband;1974 struct ieee80211_supported_band *sband;
1972 u16 brate;1975 u16 brate;
1973 unsigned int shift;1976 unsigned int shift;
@@ -1982,6 +1985,8 @@ static void sta_stats_decode_rate(struct ieee80211_local *local, u16 rate, · 8 unmodified lines
1982 else1985 else
1983 shift = 0;1986 shift = 0;
1984 rinfo->legacy = DIV_ROUND_UP(brate, 1 << shift);1987 rinfo->legacy = DIV_ROUND_UP(brate, 1 << shift);
1988 break;
1989 }
1985 }1990 }
1986 1991
1987 if (rate & STA_STATS_RATE_SGI)1992 if (rate & STA_STATS_RATE_SGI)
net/mac80211/sta_info.h+11−7
@@ -324,6 +324,9 @@ struct ieee80211_fast_rx { · 323 unmodified lines
324 struct rcu_head rcu_head;324 struct rcu_head rcu_head;
325};325};
326 326
327/* we use only values in the range 0-100, so pick a large precision */
328DECLARE_EWMA(mesh_fail_avg, 20, 8)
329
327/**330/**
328 * struct mesh_sta - mesh STA information331 * struct mesh_sta - mesh STA information
329 * @plink_lock: serialize access to plink fields332 * @plink_lock: serialize access to plink fields
@@ -369,7 +372,7 @@ struct mesh_sta { · 39 unmodified lines
369 enum nl80211_mesh_power_mode nonpeer_pm;372 enum nl80211_mesh_power_mode nonpeer_pm;
370 373
371 /* moving percentage of failed MSDUs */374 /* moving percentage of failed MSDUs */
372 unsigned int fail_avg;375 struct ewma_mesh_fail_avg fail_avg;
373};376};
374 377
375DECLARE_EWMA(signal, 10, 8)378DECLARE_EWMA(signal, 10, 8)
@@ -725,9 +728,10 @@ void ieee80211_sta_ps_deliver_uapsd(struct sta_info *sta); · 349 unmodified lines
725unsigned long ieee80211_sta_last_active(struct sta_info *sta);728unsigned long ieee80211_sta_last_active(struct sta_info *sta);
726 729
727#define STA_STATS_RATE_INVALID 0730#define STA_STATS_RATE_INVALID 0
728#define STA_STATS_RATE_VHT 0x8000731#define STA_STATS_RATE_TYPE_MASK 0xC000
729#define STA_STATS_RATE_HT 0x4000732#define STA_STATS_RATE_TYPE_LEGACY 0x4000
730#define STA_STATS_RATE_LEGACY 0x2000733#define STA_STATS_RATE_TYPE_HT 0x8000
734#define STA_STATS_RATE_TYPE_VHT 0xC000
731#define STA_STATS_RATE_SGI 0x1000735#define STA_STATS_RATE_SGI 0x1000
732#define STA_STATS_RATE_BW_SHIFT 9736#define STA_STATS_RATE_BW_SHIFT 9
733#define STA_STATS_RATE_BW_MASK (0x7 << STA_STATS_RATE_BW_SHIFT)737#define STA_STATS_RATE_BW_MASK (0x7 << STA_STATS_RATE_BW_SHIFT)
@@ -753,11 +757,11 @@ static inline u16 sta_stats_encode_rate(struct ieee80211_rx_status *s) · 19 unmodified lines
753 r |= STA_STATS_RATE_SGI;757 r |= STA_STATS_RATE_SGI;
754 758
755 if (s->flag & RX_FLAG_VHT)759 if (s->flag & RX_FLAG_VHT)
756 r |= STA_STATS_RATE_VHT | (s->vht_nss << 4);760 r |= STA_STATS_RATE_TYPE_VHT | (s->vht_nss << 4);
757 else if (s->flag & RX_FLAG_HT)761 else if (s->flag & RX_FLAG_HT)
758 r |= STA_STATS_RATE_HT;762 r |= STA_STATS_RATE_TYPE_HT;
759 else763 else
760 r |= STA_STATS_RATE_LEGACY | (s->band << 4);764 r |= STA_STATS_RATE_TYPE_LEGACY | (s->band << 4);
761 765
762 return r;766 return r;
763}767}
net/mac80211/tx.c+0−8
@@ -682,10 +682,6 @@ ieee80211_tx_h_rate_ctrl(struct ieee80211_tx_data *tx) · 681 unmodified lines
682 txrc.skb = tx->skb;682 txrc.skb = tx->skb;
683 txrc.reported_rate.idx = -1;683 txrc.reported_rate.idx = -1;
684 txrc.rate_idx_mask = tx->sdata->rc_rateidx_mask[info->band];684 txrc.rate_idx_mask = tx->sdata->rc_rateidx_mask[info->band];
685 if (txrc.rate_idx_mask == (1 << sband->n_bitrates) - 1)
686 txrc.max_rate_idx = -1;
687 else
688 txrc.max_rate_idx = fls(txrc.rate_idx_mask) - 1;
689 685
690 if (tx->sdata->rc_has_mcs_mask[info->band])686 if (tx->sdata->rc_has_mcs_mask[info->band])
691 txrc.rate_idx_mcs_mask =687 txrc.rate_idx_mcs_mask =
@@ -4249,10 +4245,6 @@ __ieee80211_beacon_get(struct ieee80211_hw *hw, · 3557 unmodified lines
4249 txrc.skb = skb;4245 txrc.skb = skb;
4250 txrc.reported_rate.idx = -1;4246 txrc.reported_rate.idx = -1;
4251 txrc.rate_idx_mask = sdata->rc_rateidx_mask[band];4247 txrc.rate_idx_mask = sdata->rc_rateidx_mask[band];
4252 if (txrc.rate_idx_mask == (1 << txrc.sband->n_bitrates) - 1)
4253 txrc.max_rate_idx = -1;
4254 else
4255 txrc.max_rate_idx = fls(txrc.rate_idx_mask) - 1;
4256 txrc.bss = true;4248 txrc.bss = true;
4257 rate_control_get_rate(sdata, NULL, &txrc);4249 rate_control_get_rate(sdata, NULL, &txrc);
4258 4250
net/mac80211/util.c+11−11
@@ -2413,13 +2413,13 @@ u8 *ieee80211_ie_build_vht_oper(u8 *pos, struct ieee80211_sta_vht_cap *vht_cap, · 2412 unmodified lines
2413 *pos++ = WLAN_EID_VHT_OPERATION;2413 *pos++ = WLAN_EID_VHT_OPERATION;
2414 *pos++ = sizeof(struct ieee80211_vht_operation);2414 *pos++ = sizeof(struct ieee80211_vht_operation);
2415 vht_oper = (struct ieee80211_vht_operation *)pos;2415 vht_oper = (struct ieee80211_vht_operation *)pos;
2416 vht_oper->center_freq_seg1_idx = ieee80211_frequency_to_channel(2416 vht_oper->center_freq_seg0_idx = ieee80211_frequency_to_channel(
2417 chandef->center_freq1);2417 chandef->center_freq1);
2418 if (chandef->center_freq2)2418 if (chandef->center_freq2)
2419 vht_oper->center_freq_seg2_idx =2419 vht_oper->center_freq_seg1_idx =
2420 ieee80211_frequency_to_channel(chandef->center_freq2);2420 ieee80211_frequency_to_channel(chandef->center_freq2);
2421 else2421 else
2422 vht_oper->center_freq_seg2_idx = 0x00;2422 vht_oper->center_freq_seg1_idx = 0x00;
2423 2423
2424 switch (chandef->width) {2424 switch (chandef->width) {
2425 case NL80211_CHAN_WIDTH_160:2425 case NL80211_CHAN_WIDTH_160:
@@ -2428,11 +2428,11 @@ u8 *ieee80211_ie_build_vht_oper(u8 *pos, struct ieee80211_sta_vht_cap *vht_cap, · 2 unmodified lines
2428 * workaround.2428 * workaround.
2429 */2429 */
2430 vht_oper->chan_width = IEEE80211_VHT_CHANWIDTH_80MHZ;2430 vht_oper->chan_width = IEEE80211_VHT_CHANWIDTH_80MHZ;
2431 vht_oper->center_freq_seg2_idx = vht_oper->center_freq_seg1_idx;2431 vht_oper->center_freq_seg1_idx = vht_oper->center_freq_seg0_idx;
2432 if (chandef->chan->center_freq < chandef->center_freq1)2432 if (chandef->chan->center_freq < chandef->center_freq1)
2433 vht_oper->center_freq_seg1_idx -= 8;2433 vht_oper->center_freq_seg0_idx -= 8;
2434 else2434 else
2435 vht_oper->center_freq_seg1_idx += 8;2435 vht_oper->center_freq_seg0_idx += 8;
2436 break;2436 break;
2437 case NL80211_CHAN_WIDTH_80P80:2437 case NL80211_CHAN_WIDTH_80P80:
2438 /*2438 /*
@@ -2491,9 +2491,9 @@ bool ieee80211_chandef_vht_oper(const struct ieee80211_vht_operation *oper, · 52 unmodified lines
2491 if (!oper)2491 if (!oper)
2492 return false;2492 return false;
2493 2493
2494 cf1 = ieee80211_channel_to_frequency(oper->center_freq_seg1_idx,2494 cf1 = ieee80211_channel_to_frequency(oper->center_freq_seg0_idx,
2495 chandef->chan->band);2495 chandef->chan->band);
2496 cf2 = ieee80211_channel_to_frequency(oper->center_freq_seg2_idx,2496 cf2 = ieee80211_channel_to_frequency(oper->center_freq_seg1_idx,
2497 chandef->chan->band);2497 chandef->chan->band);
2498 2498
2499 switch (oper->chan_width) {2499 switch (oper->chan_width) {
@@ -2503,11 +2503,11 @@ bool ieee80211_chandef_vht_oper(const struct ieee80211_vht_operation *oper, · 3 unmodified lines
2503 new.width = NL80211_CHAN_WIDTH_80;2503 new.width = NL80211_CHAN_WIDTH_80;
2504 new.center_freq1 = cf1;2504 new.center_freq1 = cf1;
2505 /* If needed, adjust based on the newer interop workaround. */2505 /* If needed, adjust based on the newer interop workaround. */
2506 if (oper->center_freq_seg2_idx) {2506 if (oper->center_freq_seg1_idx) {
2507 unsigned int diff;2507 unsigned int diff;
2508 2508
2509 diff = abs(oper->center_freq_seg2_idx -2509 diff = abs(oper->center_freq_seg1_idx -
2510 oper->center_freq_seg1_idx);2510 oper->center_freq_seg0_idx);
2511 if (diff == 8) {2511 if (diff == 8) {
2512 new.width = NL80211_CHAN_WIDTH_160;2512 new.width = NL80211_CHAN_WIDTH_160;
2513 new.center_freq1 = cf2;2513 new.center_freq1 = cf2;
net/wireless/ap.c+5−0
@@ -32,6 +32,11 @@ int __cfg80211_stop_ap(struct cfg80211_registered_device *rdev, · 31 unmodified lines
32 rdev_set_qos_map(rdev, dev, NULL);32 rdev_set_qos_map(rdev, dev, NULL);
33 if (notify)33 if (notify)
34 nl80211_send_ap_stopped(wdev);34 nl80211_send_ap_stopped(wdev);
35
36 /* Should we apply the grace period during beaconing interface
37 * shutdown also?
38 */
39 cfg80211_sched_dfs_chan_update(rdev);
35 }40 }
36 41
37 return err;42 return err;
net/wireless/chan.c+117−0
@@ -456,6 +456,123 @@ bool cfg80211_chandef_dfs_usable(struct wiphy *wiphy, · 455 unmodified lines
456 return (r1 + r2 > 0);456 return (r1 + r2 > 0);
457}457}
458 458
459/*
460 * Checks if center frequency of chan falls with in the bandwidth
461 * range of chandef.
462 */
463bool cfg80211_is_sub_chan(struct cfg80211_chan_def *chandef,
464 struct ieee80211_channel *chan)
465{
466 int width;
467 u32 cf_offset, freq;
468
469 if (chandef->chan->center_freq == chan->center_freq)
470 return true;
471
472 width = cfg80211_chandef_get_width(chandef);
473 if (width <= 20)
474 return false;
475
476 cf_offset = width / 2 - 10;
477
478 for (freq = chandef->center_freq1 - width / 2 + 10;
479 freq <= chandef->center_freq1 + width / 2 - 10; freq += 20) {
480 if (chan->center_freq == freq)
481 return true;
482 }
483
484 if (!chandef->center_freq2)
485 return false;
486
487 for (freq = chandef->center_freq2 - width / 2 + 10;
488 freq <= chandef->center_freq2 + width / 2 - 10; freq += 20) {
489 if (chan->center_freq == freq)
490 return true;
491 }
492
493 return false;
494}
495
496bool cfg80211_beaconing_iface_active(struct wireless_dev *wdev)
497{
498 bool active = false;
499
500 ASSERT_WDEV_LOCK(wdev);
501
502 if (!wdev->chandef.chan)
503 return false;
504
505 switch (wdev->iftype) {
506 case NL80211_IFTYPE_AP:
507 case NL80211_IFTYPE_P2P_GO:
508 active = wdev->beacon_interval != 0;
509 break;
510 case NL80211_IFTYPE_ADHOC:
511 active = wdev->ssid_len != 0;
512 break;
513 case NL80211_IFTYPE_MESH_POINT:
514 active = wdev->mesh_id_len != 0;
515 break;
516 case NL80211_IFTYPE_STATION:
517 case NL80211_IFTYPE_OCB:
518 case NL80211_IFTYPE_P2P_CLIENT:
519 case NL80211_IFTYPE_MONITOR:
520 case NL80211_IFTYPE_AP_VLAN:
521 case NL80211_IFTYPE_WDS:
522 case NL80211_IFTYPE_P2P_DEVICE:
523 /* Can NAN type be considered as beaconing interface? */
524 case NL80211_IFTYPE_NAN:
525 break;
526 case NL80211_IFTYPE_UNSPECIFIED:
527 case NUM_NL80211_IFTYPES:
528 WARN_ON(1);
529 }
530
531 return active;
532}
533
534static bool cfg80211_is_wiphy_oper_chan(struct wiphy *wiphy,
535 struct ieee80211_channel *chan)
536{
537 struct wireless_dev *wdev;
538
539 list_for_each_entry(wdev, &wiphy->wdev_list, list) {
540 wdev_lock(wdev);
541 if (!cfg80211_beaconing_iface_active(wdev)) {
542 wdev_unlock(wdev);
543 continue;
544 }
545
546 if (cfg80211_is_sub_chan(&wdev->chandef, chan)) {
547 wdev_unlock(wdev);
548 return true;
549 }
550 wdev_unlock(wdev);
551 }
552
553 return false;
554}
555
556bool cfg80211_any_wiphy_oper_chan(struct wiphy *wiphy,
557 struct ieee80211_channel *chan)
558{
559 struct cfg80211_registered_device *rdev;
560
561 ASSERT_RTNL();
562
563 if (!(chan->flags & IEEE80211_CHAN_RADAR))
564 return false;
565
566 list_for_each_entry(rdev, &cfg80211_rdev_list, list) {
567 if (!reg_dfs_domain_same(wiphy, &rdev->wiphy))
568 continue;
569
570 if (cfg80211_is_wiphy_oper_chan(&rdev->wiphy, chan))
571 return true;
572 }
573
574 return false;
575}
459 576
460static bool cfg80211_get_chans_dfs_available(struct wiphy *wiphy,577static bool cfg80211_get_chans_dfs_available(struct wiphy *wiphy,
461 u32 center_freq,578 u32 center_freq,
net/wireless/core.c+61−7
@@ -357,6 +357,38 @@ static void cfg80211_sched_scan_stop_wk(struct work_struct *work) · 356 unmodified lines
357 rtnl_unlock();357 rtnl_unlock();
358}358}
359 359
360static void cfg80211_propagate_radar_detect_wk(struct work_struct *work)
361{
362 struct cfg80211_registered_device *rdev;
363
364 rdev = container_of(work, struct cfg80211_registered_device,
365 propagate_radar_detect_wk);
366
367 rtnl_lock();
368
369 regulatory_propagate_dfs_state(&rdev->wiphy, &rdev->radar_chandef,
370 NL80211_DFS_UNAVAILABLE,
371 NL80211_RADAR_DETECTED);
372
373 rtnl_unlock();
374}
375
376static void cfg80211_propagate_cac_done_wk(struct work_struct *work)
377{
378 struct cfg80211_registered_device *rdev;
379
380 rdev = container_of(work, struct cfg80211_registered_device,
381 propagate_cac_done_wk);
382
383 rtnl_lock();
384
385 regulatory_propagate_dfs_state(&rdev->wiphy, &rdev->cac_done_chandef,
386 NL80211_DFS_AVAILABLE,
387 NL80211_RADAR_CAC_FINISHED);
388
389 rtnl_unlock();
390}
391
360/* exported functions */392/* exported functions */
361 393
362struct wiphy *wiphy_new_nm(const struct cfg80211_ops *ops, int sizeof_priv,394struct wiphy *wiphy_new_nm(const struct cfg80211_ops *ops, int sizeof_priv,
@@ -456,6 +488,9 @@ use_default_name: · 93 unmodified lines
456 spin_lock_init(&rdev->destroy_list_lock);488 spin_lock_init(&rdev->destroy_list_lock);
457 INIT_WORK(&rdev->destroy_work, cfg80211_destroy_iface_wk);489 INIT_WORK(&rdev->destroy_work, cfg80211_destroy_iface_wk);
458 INIT_WORK(&rdev->sched_scan_stop_wk, cfg80211_sched_scan_stop_wk);490 INIT_WORK(&rdev->sched_scan_stop_wk, cfg80211_sched_scan_stop_wk);
491 INIT_WORK(&rdev->propagate_radar_detect_wk,
492 cfg80211_propagate_radar_detect_wk);
493 INIT_WORK(&rdev->propagate_cac_done_wk, cfg80211_propagate_cac_done_wk);
459 494
460#ifdef CONFIG_CFG80211_DEFAULT_PS495#ifdef CONFIG_CFG80211_DEFAULT_PS
461 rdev->wiphy.flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT;496 rdev->wiphy.flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT;
@@ -915,6 +950,8 @@ void wiphy_unregister(struct wiphy *wiphy) · 453 unmodified lines
915 flush_work(&rdev->destroy_work);950 flush_work(&rdev->destroy_work);
916 flush_work(&rdev->sched_scan_stop_wk);951 flush_work(&rdev->sched_scan_stop_wk);
917 flush_work(&rdev->mlme_unreg_wk);952 flush_work(&rdev->mlme_unreg_wk);
953 flush_work(&rdev->propagate_radar_detect_wk);
954 flush_work(&rdev->propagate_cac_done_wk);
918 955
919#ifdef CONFIG_PM956#ifdef CONFIG_PM
920 if (rdev->wiphy.wowlan_config && rdev->ops->set_wakeup)957 if (rdev->wiphy.wowlan_config && rdev->ops->set_wakeup)
@@ -954,6 +991,12 @@ void wiphy_rfkill_set_hw_state(struct wiphy *wiphy, bool blocked) · 33 unmodified lines
954}991}
955EXPORT_SYMBOL(wiphy_rfkill_set_hw_state);992EXPORT_SYMBOL(wiphy_rfkill_set_hw_state);
956 993
994void cfg80211_cqm_config_free(struct wireless_dev *wdev)
995{
996 kfree(wdev->cqm_config);
997 wdev->cqm_config = NULL;
998}
999
957void cfg80211_unregister_wdev(struct wireless_dev *wdev)1000void cfg80211_unregister_wdev(struct wireless_dev *wdev)
958{1001{
959 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);1002 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
@@ -980,6 +1023,8 @@ void cfg80211_unregister_wdev(struct wireless_dev *wdev) · 20 unmodified lines
980 WARN_ON_ONCE(1);1023 WARN_ON_ONCE(1);
981 break;1024 break;
982 }1025 }
1026
1027 cfg80211_cqm_config_free(wdev);
983}1028}
984EXPORT_SYMBOL(cfg80211_unregister_wdev);1029EXPORT_SYMBOL(cfg80211_unregister_wdev);
985 1030
@@ -1114,7 +1159,15 @@ static int cfg80211_netdev_notifier_call(struct notifier_block *nb, · 128 unmodified lines
1114 INIT_LIST_HEAD(&wdev->mgmt_registrations);1159 INIT_LIST_HEAD(&wdev->mgmt_registrations);
1115 spin_lock_init(&wdev->mgmt_registrations_lock);1160 spin_lock_init(&wdev->mgmt_registrations_lock);
1116 1161
1117 wdev->identifier = ++rdev->wdev_id;1162 /*
1163 * We get here also when the interface changes network namespaces,
1164 * as it's registered into the new one, but we don't want it to
1165 * change ID in that case. Checking if the ID is already assigned
1166 * works, because 0 isn't considered a valid ID and the memory is
1167 * 0-initialized.
1168 */
1169 if (!wdev->identifier)
1170 wdev->identifier = ++rdev->wdev_id;
1118 list_add_rcu(&wdev->list, &rdev->wiphy.wdev_list);1171 list_add_rcu(&wdev->list, &rdev->wiphy.wdev_list);
1119 rdev->devlist_generation++;1172 rdev->devlist_generation++;
1120 /* can only change netns with wiphy */1173 /* can only change netns with wiphy */
@@ -1208,12 +1261,12 @@ static int cfg80211_netdev_notifier_call(struct notifier_block *nb, · 87 unmodified lines
1208 */1261 */
1209 if ((wdev->iftype == NL80211_IFTYPE_STATION ||1262 if ((wdev->iftype == NL80211_IFTYPE_STATION ||
1210 wdev->iftype == NL80211_IFTYPE_P2P_CLIENT) &&1263 wdev->iftype == NL80211_IFTYPE_P2P_CLIENT) &&
1211 rdev->ops->set_power_mgmt)1264 rdev->ops->set_power_mgmt &&
1212 if (rdev_set_power_mgmt(rdev, dev, wdev->ps,1265 rdev_set_power_mgmt(rdev, dev, wdev->ps,
1213 wdev->ps_timeout)) {1266 wdev->ps_timeout)) {
1214 /* assume this means it's off */1267 /* assume this means it's off */
1215 wdev->ps = false;1268 wdev->ps = false;
1216 }1269 }
1217 break;1270 break;
1218 case NETDEV_UNREGISTER:1271 case NETDEV_UNREGISTER:
1219 /*1272 /*
@@ -1234,6 +1287,7 @@ static int cfg80211_netdev_notifier_call(struct notifier_block *nb, · 14 unmodified lines
1234 kzfree(wdev->wext.keys);1287 kzfree(wdev->wext.keys);
1235#endif1288#endif
1236 flush_work(&wdev->disconnect_wk);1289 flush_work(&wdev->disconnect_wk);
1290 cfg80211_cqm_config_free(wdev);
1237 }1291 }
1238 /*1292 /*
1239 * synchronise (so that we won't find this netdev1293 * synchronise (so that we won't find this netdev
net/wireless/core.h+30−17
@@ -97,6 +97,12 @@ struct cfg80211_registered_device { · 96 unmodified lines
97 97
98 struct work_struct sched_scan_stop_wk;98 struct work_struct sched_scan_stop_wk;
99 99
100 struct cfg80211_chan_def radar_chandef;
101 struct work_struct propagate_radar_detect_wk;
102
103 struct cfg80211_chan_def cac_done_chandef;
104 struct work_struct propagate_cac_done_wk;
105
100 /* must be last because of the way we do wiphy_priv(),106 /* must be last because of the way we do wiphy_priv(),
101 * and it should at least be aligned to NETDEV_ALIGN */107 * and it should at least be aligned to NETDEV_ALIGN */
102 struct wiphy wiphy __aligned(NETDEV_ALIGN);108 struct wiphy wiphy __aligned(NETDEV_ALIGN);
@@ -220,16 +226,7 @@ struct cfg80211_event { · 117 unmodified lines
220 enum cfg80211_event_type type;226 enum cfg80211_event_type type;
221 227
222 union {228 union {
223 struct {229 struct cfg80211_connect_resp_params cr;
224 u8 bssid[ETH_ALEN];
225 const u8 *req_ie;
226 const u8 *resp_ie;
227 size_t req_ie_len;
228 size_t resp_ie_len;
229 struct cfg80211_bss *bss;
230 int status; /* -1 = failed; 0..65535 = status code */
231 enum nl80211_timeout_reason timeout_reason;
232 } cr;
233 struct {230 struct {
234 const u8 *req_ie;231 const u8 *req_ie;
235 const u8 *resp_ie;232 const u8 *resp_ie;
@@ -272,6 +269,13 @@ struct cfg80211_iface_destroy { · 36 unmodified lines
272 u32 nlportid;269 u32 nlportid;
273};270};
274 271
272struct cfg80211_cqm_config {
273 u32 rssi_hyst;
274 s32 last_rssi_event_value;
275 int n_rssi_thresholds;
276 s32 rssi_thresholds[0];
277};
278
275void cfg80211_destroy_ifaces(struct cfg80211_registered_device *rdev);279void cfg80211_destroy_ifaces(struct cfg80211_registered_device *rdev);
276 280
277/* free object */281/* free object */
@@ -385,12 +389,9 @@ int cfg80211_connect(struct cfg80211_registered_device *rdev, · 107 unmodified lines
385 struct cfg80211_connect_params *connect,389 struct cfg80211_connect_params *connect,
386 struct cfg80211_cached_keys *connkeys,390 struct cfg80211_cached_keys *connkeys,
387 const u8 *prev_bssid);391 const u8 *prev_bssid);
388void __cfg80211_connect_result(struct net_device *dev, const u8 *bssid,392void __cfg80211_connect_result(struct net_device *dev,
389 const u8 *req_ie, size_t req_ie_len,393 struct cfg80211_connect_resp_params *params,
390 const u8 *resp_ie, size_t resp_ie_len,394 bool wextev);
391 int status, bool wextev,
392 struct cfg80211_bss *bss,
393 enum nl80211_timeout_reason timeout_reason);
394void __cfg80211_disconnected(struct net_device *dev, const u8 *ie,395void __cfg80211_disconnected(struct net_device *dev, const u8 *ie,
395 size_t ie_len, u16 reason, bool from_ap);396 size_t ie_len, u16 reason, bool from_ap);
396int cfg80211_disconnect(struct cfg80211_registered_device *rdev,397int cfg80211_disconnect(struct cfg80211_registered_device *rdev,
@@ -429,7 +430,7 @@ int __cfg80211_stop_sched_scan(struct cfg80211_registered_device *rdev, · 32 unmodified lines
429void cfg80211_upload_connect_keys(struct wireless_dev *wdev);430void cfg80211_upload_connect_keys(struct wireless_dev *wdev);
430int cfg80211_change_iface(struct cfg80211_registered_device *rdev,431int cfg80211_change_iface(struct cfg80211_registered_device *rdev,
431 struct net_device *dev, enum nl80211_iftype ntype,432 struct net_device *dev, enum nl80211_iftype ntype,
432 u32 *flags, struct vif_params *params);433 struct vif_params *params);
433void cfg80211_process_rdev_events(struct cfg80211_registered_device *rdev);434void cfg80211_process_rdev_events(struct cfg80211_registered_device *rdev);
434void cfg80211_process_wdev_events(struct wireless_dev *wdev);435void cfg80211_process_wdev_events(struct wireless_dev *wdev);
435 436
@@ -459,6 +460,16 @@ unsigned int · 23 unmodified lines
459cfg80211_chandef_dfs_cac_time(struct wiphy *wiphy,460cfg80211_chandef_dfs_cac_time(struct wiphy *wiphy,
460 const struct cfg80211_chan_def *chandef);461 const struct cfg80211_chan_def *chandef);
461 462
463void cfg80211_sched_dfs_chan_update(struct cfg80211_registered_device *rdev);
464
465bool cfg80211_any_wiphy_oper_chan(struct wiphy *wiphy,
466 struct ieee80211_channel *chan);
467
468bool cfg80211_beaconing_iface_active(struct wireless_dev *wdev);
469
470bool cfg80211_is_sub_chan(struct cfg80211_chan_def *chandef,
471 struct ieee80211_channel *chan);
472
462static inline unsigned int elapsed_jiffies_msecs(unsigned long start)473static inline unsigned int elapsed_jiffies_msecs(unsigned long start)
463{474{
464 unsigned long end = jiffies;475 unsigned long end = jiffies;
@@ -512,4 +523,6 @@ void cfg80211_stop_nan(struct cfg80211_registered_device *rdev, · 47 unmodified lines
512#define CFG80211_DEV_WARN_ON(cond) ({bool __r = (cond); __r; })523#define CFG80211_DEV_WARN_ON(cond) ({bool __r = (cond); __r; })
513#endif524#endif
514 525
526void cfg80211_cqm_config_free(struct wireless_dev *wdev);
527
515#endif /* __NET_WIRELESS_CORE_H */528#endif /* __NET_WIRELESS_CORE_H */
net/wireless/ibss.c+1−0
@@ -190,6 +190,7 @@ static void __cfg80211_clear_ibss(struct net_device *dev, bool nowext) · 189 unmodified lines
190 if (!nowext)190 if (!nowext)
191 wdev->wext.ibss.ssid_len = 0;191 wdev->wext.ibss.ssid_len = 0;
192#endif192#endif
193 cfg80211_sched_dfs_chan_update(rdev);
193}194}
194 195
195void cfg80211_clear_ibss(struct net_device *dev, bool nowext)196void cfg80211_clear_ibss(struct net_device *dev, bool nowext)
net/wireless/mesh.c+1−0
@@ -262,6 +262,7 @@ int __cfg80211_leave_mesh(struct cfg80211_registered_device *rdev, · 261 unmodified lines
262 wdev->beacon_interval = 0;262 wdev->beacon_interval = 0;
263 memset(&wdev->chandef, 0, sizeof(wdev->chandef));263 memset(&wdev->chandef, 0, sizeof(wdev->chandef));
264 rdev_set_qos_map(rdev, dev, NULL);264 rdev_set_qos_map(rdev, dev, NULL);
265 cfg80211_sched_dfs_chan_update(rdev);
265 }266 }
266 267
267 return err;268 return err;
net/wireless/mlme.c+53−17
@@ -26,9 +26,16 @@ void cfg80211_rx_assoc_resp(struct net_device *dev, struct cfg80211_bss *bss, · 25 unmodified lines
26 struct wiphy *wiphy = wdev->wiphy;26 struct wiphy *wiphy = wdev->wiphy;
27 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);27 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
28 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)buf;28 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)buf;
29 u8 *ie = mgmt->u.assoc_resp.variable;29 struct cfg80211_connect_resp_params cr;
30 int ieoffs = offsetof(struct ieee80211_mgmt, u.assoc_resp.variable);30
31 u16 status_code = le16_to_cpu(mgmt->u.assoc_resp.status_code);31 memset(&cr, 0, sizeof(cr));
32 cr.status = (int)le16_to_cpu(mgmt->u.assoc_resp.status_code);
33 cr.bssid = mgmt->bssid;
34 cr.bss = bss;
35 cr.resp_ie = mgmt->u.assoc_resp.variable;
36 cr.resp_ie_len =
37 len - offsetof(struct ieee80211_mgmt, u.assoc_resp.variable);
38 cr.timeout_reason = NL80211_TIMEOUT_UNSPECIFIED;
32 39
33 trace_cfg80211_send_rx_assoc(dev, bss);40 trace_cfg80211_send_rx_assoc(dev, bss);
34 41
@@ -38,7 +45,7 @@ void cfg80211_rx_assoc_resp(struct net_device *dev, struct cfg80211_bss *bss, · 3 unmodified lines
38 * and got a reject -- we only try again with an assoc45 * and got a reject -- we only try again with an assoc
39 * frame instead of reassoc.46 * frame instead of reassoc.
40 */47 */
41 if (cfg80211_sme_rx_assoc_resp(wdev, status_code)) {48 if (cfg80211_sme_rx_assoc_resp(wdev, cr.status)) {
42 cfg80211_unhold_bss(bss_from_pub(bss));49 cfg80211_unhold_bss(bss_from_pub(bss));
43 cfg80211_put_bss(wiphy, bss);50 cfg80211_put_bss(wiphy, bss);
44 return;51 return;
@@ -46,10 +53,7 @@ void cfg80211_rx_assoc_resp(struct net_device *dev, struct cfg80211_bss *bss, · 1 unmodified line
46 53
47 nl80211_send_rx_assoc(rdev, dev, buf, len, GFP_KERNEL, uapsd_queues);54 nl80211_send_rx_assoc(rdev, dev, buf, len, GFP_KERNEL, uapsd_queues);
48 /* update current_bss etc., consumes the bss reference */55 /* update current_bss etc., consumes the bss reference */
49 __cfg80211_connect_result(dev, mgmt->bssid, NULL, 0, ie, len - ieoffs,56 __cfg80211_connect_result(dev, &cr, cr.status == WLAN_STATUS_SUCCESS);
50 status_code,
51 status_code == WLAN_STATUS_SUCCESS, bss,
52 NL80211_TIMEOUT_UNSPECIFIED);
53}57}
54EXPORT_SYMBOL(cfg80211_rx_assoc_resp);58EXPORT_SYMBOL(cfg80211_rx_assoc_resp);
55 59
@@ -745,6 +749,12 @@ bool cfg80211_rx_mgmt(struct wireless_dev *wdev, int freq, int sig_mbm, · 689 unmodified lines
745}749}
746EXPORT_SYMBOL(cfg80211_rx_mgmt);750EXPORT_SYMBOL(cfg80211_rx_mgmt);
747 751
752void cfg80211_sched_dfs_chan_update(struct cfg80211_registered_device *rdev)
753{
754 cancel_delayed_work(&rdev->dfs_update_channels_wk);
755 queue_delayed_work(cfg80211_wq, &rdev->dfs_update_channels_wk, 0);
756}
757
748void cfg80211_dfs_channels_update_work(struct work_struct *work)758void cfg80211_dfs_channels_update_work(struct work_struct *work)
749{759{
750 struct delayed_work *delayed_work = to_delayed_work(work);760 struct delayed_work *delayed_work = to_delayed_work(work);
@@ -755,6 +765,8 @@ void cfg80211_dfs_channels_update_work(struct work_struct *work) · 4 unmodified lines
755 struct wiphy *wiphy;765 struct wiphy *wiphy;
756 bool check_again = false;766 bool check_again = false;
757 unsigned long timeout, next_time = 0;767 unsigned long timeout, next_time = 0;
768 unsigned long time_dfs_update;
769 enum nl80211_radar_event radar_event;
758 int bandid, i;770 int bandid, i;
759 771
760 rdev = container_of(delayed_work, struct cfg80211_registered_device,772 rdev = container_of(delayed_work, struct cfg80211_registered_device,
@@ -770,11 +782,27 @@ void cfg80211_dfs_channels_update_work(struct work_struct *work) · 9 unmodified lines
770 for (i = 0; i < sband->n_channels; i++) {782 for (i = 0; i < sband->n_channels; i++) {
771 c = &sband->channels[i];783 c = &sband->channels[i];
772 784
773 if (c->dfs_state != NL80211_DFS_UNAVAILABLE)785 if (!(c->flags & IEEE80211_CHAN_RADAR))
786 continue;
787
788 if (c->dfs_state != NL80211_DFS_UNAVAILABLE &&
789 c->dfs_state != NL80211_DFS_AVAILABLE)
774 continue;790 continue;
775 791
776 timeout = c->dfs_state_entered + msecs_to_jiffies(792 if (c->dfs_state == NL80211_DFS_UNAVAILABLE) {
777 IEEE80211_DFS_MIN_NOP_TIME_MS);793 time_dfs_update = IEEE80211_DFS_MIN_NOP_TIME_MS;
794 radar_event = NL80211_RADAR_NOP_FINISHED;
795 } else {
796 if (regulatory_pre_cac_allowed(wiphy) ||
797 cfg80211_any_wiphy_oper_chan(wiphy, c))
798 continue;
799
800 time_dfs_update = REG_PRE_CAC_EXPIRY_GRACE_MS;
801 radar_event = NL80211_RADAR_PRE_CAC_EXPIRED;
802 }
803
804 timeout = c->dfs_state_entered +
805 msecs_to_jiffies(time_dfs_update);
778 806
779 if (time_after_eq(jiffies, timeout)) {807 if (time_after_eq(jiffies, timeout)) {
780 c->dfs_state = NL80211_DFS_USABLE;808 c->dfs_state = NL80211_DFS_USABLE;
@@ -784,8 +812,12 @@ void cfg80211_dfs_channels_update_work(struct work_struct *work) · 3 unmodified lines
784 NL80211_CHAN_NO_HT);812 NL80211_CHAN_NO_HT);
785 813
786 nl80211_radar_notify(rdev, &chandef,814 nl80211_radar_notify(rdev, &chandef,
787 NL80211_RADAR_NOP_FINISHED,815 radar_event, NULL,
788 NULL, GFP_ATOMIC);816 GFP_ATOMIC);
817
818 regulatory_propagate_dfs_state(wiphy, &chandef,
819 c->dfs_state,
820 radar_event);
789 continue;821 continue;
790 }822 }
791 823
@@ -810,7 +842,6 @@ void cfg80211_radar_event(struct wiphy *wiphy, · 18 unmodified lines
810 gfp_t gfp)842 gfp_t gfp)
811{843{
812 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);844 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
813 unsigned long timeout;
814 845
815 trace_cfg80211_radar_event(wiphy, chandef);846 trace_cfg80211_radar_event(wiphy, chandef);
816 847
@@ -820,11 +851,12 @@ void cfg80211_radar_event(struct wiphy *wiphy, · 3 unmodified lines
820 */851 */
821 cfg80211_set_dfs_state(wiphy, chandef, NL80211_DFS_UNAVAILABLE);852 cfg80211_set_dfs_state(wiphy, chandef, NL80211_DFS_UNAVAILABLE);
822 853
823 timeout = msecs_to_jiffies(IEEE80211_DFS_MIN_NOP_TIME_MS);854 cfg80211_sched_dfs_chan_update(rdev);
824 queue_delayed_work(cfg80211_wq, &rdev->dfs_update_channels_wk,
825 timeout);
826 855
827 nl80211_radar_notify(rdev, chandef, NL80211_RADAR_DETECTED, NULL, gfp);856 nl80211_radar_notify(rdev, chandef, NL80211_RADAR_DETECTED, NULL, gfp);
857
858 memcpy(&rdev->radar_chandef, chandef, sizeof(struct cfg80211_chan_def));
859 queue_work(cfg80211_wq, &rdev->propagate_radar_detect_wk);
828}860}
829EXPORT_SYMBOL(cfg80211_radar_event);861EXPORT_SYMBOL(cfg80211_radar_event);
830 862
@@ -851,6 +883,10 @@ void cfg80211_cac_event(struct net_device *netdev, · 20 unmodified lines
851 msecs_to_jiffies(wdev->cac_time_ms);883 msecs_to_jiffies(wdev->cac_time_ms);
852 WARN_ON(!time_after_eq(jiffies, timeout));884 WARN_ON(!time_after_eq(jiffies, timeout));
853 cfg80211_set_dfs_state(wiphy, chandef, NL80211_DFS_AVAILABLE);885 cfg80211_set_dfs_state(wiphy, chandef, NL80211_DFS_AVAILABLE);
886 memcpy(&rdev->cac_done_chandef, chandef,
887 sizeof(struct cfg80211_chan_def));
888 queue_work(cfg80211_wq, &rdev->propagate_cac_done_wk);
889 cfg80211_sched_dfs_chan_update(rdev);
854 break;890 break;
855 case NL80211_RADAR_CAC_ABORTED:891 case NL80211_RADAR_CAC_ABORTED:
856 break;892 break;
net/wireless/nl80211.c+361−104
@@ -410,6 +410,15 @@ static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = { · 409 unmodified lines
410 .len = sizeof(struct nl80211_bss_select_rssi_adjust)410 .len = sizeof(struct nl80211_bss_select_rssi_adjust)
411 },411 },
412 [NL80211_ATTR_TIMEOUT_REASON] = { .type = NLA_U32 },412 [NL80211_ATTR_TIMEOUT_REASON] = { .type = NLA_U32 },
413 [NL80211_ATTR_FILS_ERP_USERNAME] = { .type = NLA_BINARY,
414 .len = FILS_ERP_MAX_USERNAME_LEN },
415 [NL80211_ATTR_FILS_ERP_REALM] = { .type = NLA_BINARY,
416 .len = FILS_ERP_MAX_REALM_LEN },
417 [NL80211_ATTR_FILS_ERP_NEXT_SEQ_NUM] = { .type = NLA_U16 },
418 [NL80211_ATTR_FILS_ERP_RRK] = { .type = NLA_BINARY,
419 .len = FILS_ERP_MAX_RRK_LEN },
420 [NL80211_ATTR_FILS_CACHE_ID] = { .len = 2 },
421 [NL80211_ATTR_PMK] = { .type = NLA_BINARY, .len = PMK_MAX_LEN },
413};422};
414 423
415/* policy for the key attributes */424/* policy for the key attributes */
@@ -2705,9 +2714,74 @@ static int parse_monitor_flags(struct nlattr *nla, u32 *mntrflags) · 2289 unmodified lines
2705 if (flags[flag])2714 if (flags[flag])
2706 *mntrflags |= (1<<flag);2715 *mntrflags |= (1<<flag);
2707 2716
2717 *mntrflags |= MONITOR_FLAG_CHANGED;
2718
2708 return 0;2719 return 0;
2709}2720}
2710 2721
2722static int nl80211_parse_mon_options(struct cfg80211_registered_device *rdev,
2723 enum nl80211_iftype type,
2724 struct genl_info *info,
2725 struct vif_params *params)
2726{
2727 bool change = false;
2728 int err;
2729
2730 if (info->attrs[NL80211_ATTR_MNTR_FLAGS]) {
2731 if (type != NL80211_IFTYPE_MONITOR)
2732 return -EINVAL;
2733
2734 err = parse_monitor_flags(info->attrs[NL80211_ATTR_MNTR_FLAGS],
2735 &params->flags);
2736 if (err)
2737 return err;
2738
2739 change = true;
2740 }
2741
2742 if (params->flags & MONITOR_FLAG_ACTIVE &&
2743 !(rdev->wiphy.features & NL80211_FEATURE_ACTIVE_MONITOR))
2744 return -EOPNOTSUPP;
2745
2746 if (info->attrs[NL80211_ATTR_MU_MIMO_GROUP_DATA]) {
2747 const u8 *mumimo_groups;
2748 u32 cap_flag = NL80211_EXT_FEATURE_MU_MIMO_AIR_SNIFFER;
2749
2750 if (type != NL80211_IFTYPE_MONITOR)
2751 return -EINVAL;
2752
2753 if (!wiphy_ext_feature_isset(&rdev->wiphy, cap_flag))
2754 return -EOPNOTSUPP;
2755
2756 mumimo_groups =
2757 nla_data(info->attrs[NL80211_ATTR_MU_MIMO_GROUP_DATA]);
2758
2759 /* bits 0 and 63 are reserved and must be zero */
2760 if ((mumimo_groups[0] & BIT(7)) ||
2761 (mumimo_groups[VHT_MUMIMO_GROUPS_DATA_LEN - 1] & BIT(0)))
2762 return -EINVAL;
2763
2764 params->vht_mumimo_groups = mumimo_groups;
2765 change = true;
2766 }
2767
2768 if (info->attrs[NL80211_ATTR_MU_MIMO_FOLLOW_MAC_ADDR]) {
2769 u32 cap_flag = NL80211_EXT_FEATURE_MU_MIMO_AIR_SNIFFER;
2770
2771 if (type != NL80211_IFTYPE_MONITOR)
2772 return -EINVAL;
2773
2774 if (!wiphy_ext_feature_isset(&rdev->wiphy, cap_flag))
2775 return -EOPNOTSUPP;
2776
2777 params->vht_mumimo_follow_addr =
2778 nla_data(info->attrs[NL80211_ATTR_MU_MIMO_FOLLOW_MAC_ADDR]);
2779 change = true;
2780 }
2781
2782 return change ? 1 : 0;
2783}
2784
2711static int nl80211_valid_4addr(struct cfg80211_registered_device *rdev,2785static int nl80211_valid_4addr(struct cfg80211_registered_device *rdev,
2712 struct net_device *netdev, u8 use_4addr,2786 struct net_device *netdev, u8 use_4addr,
2713 enum nl80211_iftype iftype)2787 enum nl80211_iftype iftype)
@@ -2741,7 +2815,6 @@ static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info) · 27 unmodified lines
2741 int err;2815 int err;
2742 enum nl80211_iftype otype, ntype;2816 enum nl80211_iftype otype, ntype;
2743 struct net_device *dev = info->user_ptr[1];2817 struct net_device *dev = info->user_ptr[1];
2744 u32 _flags, *flags = NULL;
2745 bool change = false;2818 bool change = false;
2746 2819
2747 memset(&params, 0, sizeof(params));2820 memset(&params, 0, sizeof(params));
@@ -2784,56 +2857,14 @@ static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info) · 36 unmodified lines
2784 params.use_4addr = -1;2857 params.use_4addr = -1;
2785 }2858 }
2786 2859
2787 if (info->attrs[NL80211_ATTR_MNTR_FLAGS]) {2860 err = nl80211_parse_mon_options(rdev, ntype, info, &params);
2788 if (ntype != NL80211_IFTYPE_MONITOR)2861 if (err < 0)
2789 return -EINVAL;2862 return err;
2790 err = parse_monitor_flags(info->attrs[NL80211_ATTR_MNTR_FLAGS],2863 if (err > 0)
2791 &_flags);
2792 if (err)
2793 return err;
2794
2795 flags = &_flags;
2796 change = true;
2797 }
2798
2799 if (info->attrs[NL80211_ATTR_MU_MIMO_GROUP_DATA]) {
2800 const u8 *mumimo_groups;
2801 u32 cap_flag = NL80211_EXT_FEATURE_MU_MIMO_AIR_SNIFFER;
2802
2803 if (!wiphy_ext_feature_isset(&rdev->wiphy, cap_flag))
2804 return -EOPNOTSUPP;
2805
2806 mumimo_groups =
2807 nla_data(info->attrs[NL80211_ATTR_MU_MIMO_GROUP_DATA]);
2808
2809 /* bits 0 and 63 are reserved and must be zero */
2810 if ((mumimo_groups[0] & BIT(7)) ||
2811 (mumimo_groups[VHT_MUMIMO_GROUPS_DATA_LEN - 1] & BIT(0)))
2812 return -EINVAL;
2813
2814 memcpy(params.vht_mumimo_groups, mumimo_groups,
2815 VHT_MUMIMO_GROUPS_DATA_LEN);
2816 change = true;
2817 }
2818
2819 if (info->attrs[NL80211_ATTR_MU_MIMO_FOLLOW_MAC_ADDR]) {
2820 u32 cap_flag = NL80211_EXT_FEATURE_MU_MIMO_AIR_SNIFFER;
2821
2822 if (!wiphy_ext_feature_isset(&rdev->wiphy, cap_flag))
2823 return -EOPNOTSUPP;
2824
2825 nla_memcpy(params.macaddr,
2826 info->attrs[NL80211_ATTR_MU_MIMO_FOLLOW_MAC_ADDR],
2827 ETH_ALEN);
2828 change = true;2864 change = true;
2829 }
2830
2831 if (flags && (*flags & MONITOR_FLAG_ACTIVE) &&
2832 !(rdev->wiphy.features & NL80211_FEATURE_ACTIVE_MONITOR))
2833 return -EOPNOTSUPP;
2834 2865
2835 if (change)2866 if (change)
2836 err = cfg80211_change_iface(rdev, dev, ntype, flags, &params);2867 err = cfg80211_change_iface(rdev, dev, ntype, &params);
2837 else2868 else
2838 err = 0;2869 err = 0;
2839 2870
@@ -2851,7 +2882,6 @@ static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info) · 11 unmodified lines
2851 struct sk_buff *msg;2882 struct sk_buff *msg;
2852 int err;2883 int err;
2853 enum nl80211_iftype type = NL80211_IFTYPE_UNSPECIFIED;2884 enum nl80211_iftype type = NL80211_IFTYPE_UNSPECIFIED;
2854 u32 flags;
2855 2885
2856 /* to avoid failing a new interface creation due to pending removal */2886 /* to avoid failing a new interface creation due to pending removal */
2857 cfg80211_destroy_ifaces(rdev);2887 cfg80211_destroy_ifaces(rdev);
@@ -2887,13 +2917,9 @@ static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info) · 29 unmodified lines
2887 return err;2917 return err;
2888 }2918 }
2889 2919
2890 err = parse_monitor_flags(type == NL80211_IFTYPE_MONITOR ?2920 err = nl80211_parse_mon_options(rdev, type, info, &params);
2891 info->attrs[NL80211_ATTR_MNTR_FLAGS] : NULL,2921 if (err < 0)
2892 &flags);2922 return err;
2893
2894 if (!err && (flags & MONITOR_FLAG_ACTIVE) &&
2895 !(rdev->wiphy.features & NL80211_FEATURE_ACTIVE_MONITOR))
2896 return -EOPNOTSUPP;
2897 2923
2898 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);2924 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
2899 if (!msg)2925 if (!msg)
@@ -2901,8 +2927,7 @@ static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info) · 1 unmodified line
2901 2927
2902 wdev = rdev_add_virtual_intf(rdev,2928 wdev = rdev_add_virtual_intf(rdev,
2903 nla_data(info->attrs[NL80211_ATTR_IFNAME]),2929 nla_data(info->attrs[NL80211_ATTR_IFNAME]),
2904 NET_NAME_USER, type, err ? NULL : &flags,2930 NET_NAME_USER, type, &params);
2905 &params);
2906 if (WARN_ON(!wdev)) {2931 if (WARN_ON(!wdev)) {
2907 nlmsg_free(msg);2932 nlmsg_free(msg);
2908 return -EPROTO;2933 return -EPROTO;
@@ -3820,6 +3845,19 @@ static bool nl80211_valid_auth_type(struct cfg80211_registered_device *rdev, · 911 unmodified lines
3820 return false;3845 return false;
3821 return true;3846 return true;
3822 case NL80211_CMD_CONNECT:3847 case NL80211_CMD_CONNECT:
3848 /* SAE not supported yet */
3849 if (auth_type == NL80211_AUTHTYPE_SAE)
3850 return false;
3851 /* FILS with SK PFS or PK not supported yet */
3852 if (auth_type == NL80211_AUTHTYPE_FILS_SK_PFS ||
3853 auth_type == NL80211_AUTHTYPE_FILS_PK)
3854 return false;
3855 if (!wiphy_ext_feature_isset(
3856 &rdev->wiphy,
3857 NL80211_EXT_FEATURE_FILS_SK_OFFLOAD) &&
3858 auth_type == NL80211_AUTHTYPE_FILS_SK)
3859 return false;
3860 return true;
3823 case NL80211_CMD_START_AP:3861 case NL80211_CMD_START_AP:
3824 /* SAE not supported yet */3862 /* SAE not supported yet */
3825 if (auth_type == NL80211_AUTHTYPE_SAE)3863 if (auth_type == NL80211_AUTHTYPE_SAE)
@@ -4153,7 +4191,7 @@ static bool nl80211_put_sta_rate(struct sk_buff *msg, struct rate_info *info, · 327 unmodified lines
4153 struct nlattr *rate;4191 struct nlattr *rate;
4154 u32 bitrate;4192 u32 bitrate;
4155 u16 bitrate_compat;4193 u16 bitrate_compat;
4156 enum nl80211_attrs rate_flg;4194 enum nl80211_rate_info rate_flg;
4157 4195
4158 rate = nla_nest_start(msg, attr);4196 rate = nla_nest_start(msg, attr);
4159 if (!rate)4197 if (!rate)
@@ -5705,7 +5743,7 @@ static int nl80211_get_mesh_config(struct sk_buff *skb, · 1545 unmodified lines
5705 cur_params.dot11MeshGateAnnouncementProtocol) ||5743 cur_params.dot11MeshGateAnnouncementProtocol) ||
5706 nla_put_u8(msg, NL80211_MESHCONF_FORWARDING,5744 nla_put_u8(msg, NL80211_MESHCONF_FORWARDING,
5707 cur_params.dot11MeshForwarding) ||5745 cur_params.dot11MeshForwarding) ||
5708 nla_put_u32(msg, NL80211_MESHCONF_RSSI_THRESHOLD,5746 nla_put_s32(msg, NL80211_MESHCONF_RSSI_THRESHOLD,
5709 cur_params.rssi_threshold) ||5747 cur_params.rssi_threshold) ||
5710 nla_put_u32(msg, NL80211_MESHCONF_HT_OPMODE,5748 nla_put_u32(msg, NL80211_MESHCONF_HT_OPMODE,
5711 cur_params.ht_opmode) ||5749 cur_params.ht_opmode) ||
@@ -6548,6 +6586,19 @@ static int nl80211_parse_random_mac(struct nlattr **attrs, · 836 unmodified lines
6548 return 0;6586 return 0;
6549}6587}
6550 6588
6589static bool cfg80211_off_channel_oper_allowed(struct wireless_dev *wdev)
6590{
6591 ASSERT_WDEV_LOCK(wdev);
6592
6593 if (!cfg80211_beaconing_iface_active(wdev))
6594 return true;
6595
6596 if (!(wdev->chandef.chan->flags & IEEE80211_CHAN_RADAR))
6597 return true;
6598
6599 return regulatory_pre_cac_allowed(wdev->wiphy);
6600}
6601
6551static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)6602static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
6552{6603{
6553 struct cfg80211_registered_device *rdev = info->user_ptr[0];6604 struct cfg80211_registered_device *rdev = info->user_ptr[0];
@@ -6673,6 +6724,25 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info) · 119 unmodified lines
6673 6724
6674 request->n_channels = i;6725 request->n_channels = i;
6675 6726
6727 wdev_lock(wdev);
6728 if (!cfg80211_off_channel_oper_allowed(wdev)) {
6729 struct ieee80211_channel *chan;
6730
6731 if (request->n_channels != 1) {
6732 wdev_unlock(wdev);
6733 err = -EBUSY;
6734 goto out_free;
6735 }
6736
6737 chan = request->channels[0];
6738 if (chan->center_freq != wdev->chandef.chan->center_freq) {
6739 wdev_unlock(wdev);
6740 err = -EBUSY;
6741 goto out_free;
6742 }
6743 }
6744 wdev_unlock(wdev);
6745
6676 i = 0;6746 i = 0;
6677 if (n_ssids) {6747 if (n_ssids) {
6678 nla_for_each_nested(attr, info->attrs[NL80211_ATTR_SCAN_SSIDS], tmp) {6748 nla_for_each_nested(attr, info->attrs[NL80211_ATTR_SCAN_SSIDS], tmp) {
@@ -7295,8 +7365,7 @@ static int nl80211_start_sched_scan(struct sk_buff *skb, · 616 unmodified lines
7295 7365
7296 rcu_assign_pointer(rdev->sched_scan_req, sched_scan_req);7366 rcu_assign_pointer(rdev->sched_scan_req, sched_scan_req);
7297 7367
7298 nl80211_send_sched_scan(rdev, dev,7368 nl80211_send_sched_scan(sched_scan_req, NL80211_CMD_START_SCHED_SCAN);
7299 NL80211_CMD_START_SCHED_SCAN);
7300 return 0;7369 return 0;
7301 7370
7302out_free:7371out_free:
@@ -8873,6 +8942,35 @@ static int nl80211_connect(struct sk_buff *skb, struct genl_info *info) · 1570 unmodified lines
8873 }8942 }
8874 }8943 }
8875 8944
8945 if (wiphy_ext_feature_isset(&rdev->wiphy,
8946 NL80211_EXT_FEATURE_FILS_SK_OFFLOAD) &&
8947 info->attrs[NL80211_ATTR_FILS_ERP_USERNAME] &&
8948 info->attrs[NL80211_ATTR_FILS_ERP_REALM] &&
8949 info->attrs[NL80211_ATTR_FILS_ERP_NEXT_SEQ_NUM] &&
8950 info->attrs[NL80211_ATTR_FILS_ERP_RRK]) {
8951 connect.fils_erp_username =
8952 nla_data(info->attrs[NL80211_ATTR_FILS_ERP_USERNAME]);
8953 connect.fils_erp_username_len =
8954 nla_len(info->attrs[NL80211_ATTR_FILS_ERP_USERNAME]);
8955 connect.fils_erp_realm =
8956 nla_data(info->attrs[NL80211_ATTR_FILS_ERP_REALM]);
8957 connect.fils_erp_realm_len =
8958 nla_len(info->attrs[NL80211_ATTR_FILS_ERP_REALM]);
8959 connect.fils_erp_next_seq_num =
8960 nla_get_u16(
8961 info->attrs[NL80211_ATTR_FILS_ERP_NEXT_SEQ_NUM]);
8962 connect.fils_erp_rrk =
8963 nla_data(info->attrs[NL80211_ATTR_FILS_ERP_RRK]);
8964 connect.fils_erp_rrk_len =
8965 nla_len(info->attrs[NL80211_ATTR_FILS_ERP_RRK]);
8966 } else if (info->attrs[NL80211_ATTR_FILS_ERP_USERNAME] ||
8967 info->attrs[NL80211_ATTR_FILS_ERP_REALM] ||
8968 info->attrs[NL80211_ATTR_FILS_ERP_NEXT_SEQ_NUM] ||
8969 info->attrs[NL80211_ATTR_FILS_ERP_RRK]) {
8970 kzfree(connkeys);
8971 return -EINVAL;
8972 }
8973
8876 wdev_lock(dev->ieee80211_ptr);8974 wdev_lock(dev->ieee80211_ptr);
8877 8975
8878 err = cfg80211_connect(rdev, dev, &connect, connkeys,8976 err = cfg80211_connect(rdev, dev, &connect, connkeys,
@@ -8992,14 +9090,28 @@ static int nl80211_setdel_pmksa(struct sk_buff *skb, struct genl_info *info) · 113 unmodified lines
8992 9090
8993 memset(&pmksa, 0, sizeof(struct cfg80211_pmksa));9091 memset(&pmksa, 0, sizeof(struct cfg80211_pmksa));
8994 9092
8995 if (!info->attrs[NL80211_ATTR_MAC])
8996 return -EINVAL;
8997
8998 if (!info->attrs[NL80211_ATTR_PMKID])9093 if (!info->attrs[NL80211_ATTR_PMKID])
8999 return -EINVAL;9094 return -EINVAL;
9000 9095
9001 pmksa.pmkid = nla_data(info->attrs[NL80211_ATTR_PMKID]);9096 pmksa.pmkid = nla_data(info->attrs[NL80211_ATTR_PMKID]);
9002 pmksa.bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);9097
9098 if (info->attrs[NL80211_ATTR_MAC]) {
9099 pmksa.bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
9100 } else if (info->attrs[NL80211_ATTR_SSID] &&
9101 info->attrs[NL80211_ATTR_FILS_CACHE_ID] &&
9102 (info->genlhdr->cmd == NL80211_CMD_DEL_PMKSA ||
9103 info->attrs[NL80211_ATTR_PMK])) {
9104 pmksa.ssid = nla_data(info->attrs[NL80211_ATTR_SSID]);
9105 pmksa.ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]);
9106 pmksa.cache_id =
9107 nla_data(info->attrs[NL80211_ATTR_FILS_CACHE_ID]);
9108 } else {
9109 return -EINVAL;
9110 }
9111 if (info->attrs[NL80211_ATTR_PMK]) {
9112 pmksa.pmk = nla_data(info->attrs[NL80211_ATTR_PMK]);
9113 pmksa.pmk_len = nla_len(info->attrs[NL80211_ATTR_PMK]);
9114 }
9003 9115
9004 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&9116 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
9005 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT)9117 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT)
@@ -9102,6 +9214,7 @@ static int nl80211_remain_on_channel(struct sk_buff *skb, · 96 unmodified lines
9102 struct cfg80211_registered_device *rdev = info->user_ptr[0];9214 struct cfg80211_registered_device *rdev = info->user_ptr[0];
9103 struct wireless_dev *wdev = info->user_ptr[1];9215 struct wireless_dev *wdev = info->user_ptr[1];
9104 struct cfg80211_chan_def chandef;9216 struct cfg80211_chan_def chandef;
9217 const struct cfg80211_chan_def *compat_chandef;
9105 struct sk_buff *msg;9218 struct sk_buff *msg;
9106 void *hdr;9219 void *hdr;
9107 u64 cookie;9220 u64 cookie;
@@ -9130,6 +9243,18 @@ static int nl80211_remain_on_channel(struct sk_buff *skb, · 22 unmodified lines
9130 if (err)9243 if (err)
9131 return err;9244 return err;
9132 9245
9246 wdev_lock(wdev);
9247 if (!cfg80211_off_channel_oper_allowed(wdev) &&
9248 !cfg80211_chandef_identical(&wdev->chandef, &chandef)) {
9249 compat_chandef = cfg80211_chandef_compatible(&wdev->chandef,
9250 &chandef);
9251 if (compat_chandef != &chandef) {
9252 wdev_unlock(wdev);
9253 return -EBUSY;
9254 }
9255 }
9256 wdev_unlock(wdev);
9257
9133 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);9258 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
9134 if (!msg)9259 if (!msg)
9135 return -ENOMEM;9260 return -ENOMEM;
@@ -9305,6 +9430,13 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info) · 169 unmodified lines
9305 if (!chandef.chan && params.offchan)9430 if (!chandef.chan && params.offchan)
9306 return -EINVAL;9431 return -EINVAL;
9307 9432
9433 wdev_lock(wdev);
9434 if (params.offchan && !cfg80211_off_channel_oper_allowed(wdev)) {
9435 wdev_unlock(wdev);
9436 return -EBUSY;
9437 }
9438 wdev_unlock(wdev);
9439
9308 params.buf = nla_data(info->attrs[NL80211_ATTR_FRAME]);9440 params.buf = nla_data(info->attrs[NL80211_ATTR_FRAME]);
9309 params.len = nla_len(info->attrs[NL80211_ATTR_FRAME]);9441 params.len = nla_len(info->attrs[NL80211_ATTR_FRAME]);
9310 9442
@@ -9472,7 +9604,7 @@ static int nl80211_get_power_save(struct sk_buff *skb, struct genl_info *info) · 161 unmodified lines
9472 9604
9473static const struct nla_policy9605static const struct nla_policy
9474nl80211_attr_cqm_policy[NL80211_ATTR_CQM_MAX + 1] = {9606nl80211_attr_cqm_policy[NL80211_ATTR_CQM_MAX + 1] = {
9475 [NL80211_ATTR_CQM_RSSI_THOLD] = { .type = NLA_U32 },9607 [NL80211_ATTR_CQM_RSSI_THOLD] = { .type = NLA_BINARY },
9476 [NL80211_ATTR_CQM_RSSI_HYST] = { .type = NLA_U32 },9608 [NL80211_ATTR_CQM_RSSI_HYST] = { .type = NLA_U32 },
9477 [NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT] = { .type = NLA_U32 },9609 [NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT] = { .type = NLA_U32 },
9478 [NL80211_ATTR_CQM_TXE_RATE] = { .type = NLA_U32 },9610 [NL80211_ATTR_CQM_TXE_RATE] = { .type = NLA_U32 },
@@ -9501,28 +9633,123 @@ static int nl80211_set_cqm_txe(struct genl_info *info, · 22 unmodified lines
9501 return rdev_set_cqm_txe_config(rdev, dev, rate, pkts, intvl);9633 return rdev_set_cqm_txe_config(rdev, dev, rate, pkts, intvl);
9502}9634}
9503 9635
9636static int cfg80211_cqm_rssi_update(struct cfg80211_registered_device *rdev,
9637 struct net_device *dev)
9638{
9639 struct wireless_dev *wdev = dev->ieee80211_ptr;
9640 s32 last, low, high;
9641 u32 hyst;
9642 int i, n;
9643 int err;
9644
9645 /* RSSI reporting disabled? */
9646 if (!wdev->cqm_config)
9647 return rdev_set_cqm_rssi_range_config(rdev, dev, 0, 0);
9648
9649 /*
9650 * Obtain current RSSI value if possible, if not and no RSSI threshold
9651 * event has been received yet, we should receive an event after a
9652 * connection is established and enough beacons received to calculate
9653 * the average.
9654 */
9655 if (!wdev->cqm_config->last_rssi_event_value && wdev->current_bss &&
9656 rdev->ops->get_station) {
9657 struct station_info sinfo;
9658 u8 *mac_addr;
9659
9660 mac_addr = wdev->current_bss->pub.bssid;
9661
9662 err = rdev_get_station(rdev, dev, mac_addr, &sinfo);
9663 if (err)
9664 return err;
9665
9666 if (sinfo.filled & BIT(NL80211_STA_INFO_BEACON_SIGNAL_AVG))
9667 wdev->cqm_config->last_rssi_event_value =
9668 (s8) sinfo.rx_beacon_signal_avg;
9669 }
9670
9671 last = wdev->cqm_config->last_rssi_event_value;
9672 hyst = wdev->cqm_config->rssi_hyst;
9673 n = wdev->cqm_config->n_rssi_thresholds;
9674
9675 for (i = 0; i < n; i++)
9676 if (last < wdev->cqm_config->rssi_thresholds[i])
9677 break;
9678
9679 low = i > 0 ?
9680 (wdev->cqm_config->rssi_thresholds[i - 1] - hyst) : S32_MIN;
9681 high = i < n ?
9682 (wdev->cqm_config->rssi_thresholds[i] + hyst - 1) : S32_MAX;
9683
9684 return rdev_set_cqm_rssi_range_config(rdev, dev, low, high);
9685}
9686
9504static int nl80211_set_cqm_rssi(struct genl_info *info,9687static int nl80211_set_cqm_rssi(struct genl_info *info,
9505 s32 threshold, u32 hysteresis)9688 const s32 *thresholds, int n_thresholds,
9689 u32 hysteresis)
9506{9690{
9507 struct cfg80211_registered_device *rdev = info->user_ptr[0];9691 struct cfg80211_registered_device *rdev = info->user_ptr[0];
9508 struct net_device *dev = info->user_ptr[1];9692 struct net_device *dev = info->user_ptr[1];
9509 struct wireless_dev *wdev = dev->ieee80211_ptr;9693 struct wireless_dev *wdev = dev->ieee80211_ptr;
9694 int i, err;
9695 s32 prev = S32_MIN;
9510 9696
9511 if (threshold > 0)9697 /* Check all values negative and sorted */
9512 return -EINVAL;9698 for (i = 0; i < n_thresholds; i++) {
9513 9699 if (thresholds[i] > 0 || thresholds[i] <= prev)
9514 /* disabling - hysteresis should also be zero then */9700 return -EINVAL;
9515 if (threshold == 0)
9516 hysteresis = 0;
9517 9701
9518 if (!rdev->ops->set_cqm_rssi_config)9702 prev = thresholds[i];
9519 return -EOPNOTSUPP;9703 }
9520 9704
9521 if (wdev->iftype != NL80211_IFTYPE_STATION &&9705 if (wdev->iftype != NL80211_IFTYPE_STATION &&
9522 wdev->iftype != NL80211_IFTYPE_P2P_CLIENT)9706 wdev->iftype != NL80211_IFTYPE_P2P_CLIENT)
9523 return -EOPNOTSUPP;9707 return -EOPNOTSUPP;
9524 9708
9525 return rdev_set_cqm_rssi_config(rdev, dev, threshold, hysteresis);9709 wdev_lock(wdev);
9710 cfg80211_cqm_config_free(wdev);
9711 wdev_unlock(wdev);
9712
9713 if (n_thresholds <= 1 && rdev->ops->set_cqm_rssi_config) {
9714 if (n_thresholds == 0 || thresholds[0] == 0) /* Disabling */
9715 return rdev_set_cqm_rssi_config(rdev, dev, 0, 0);
9716
9717 return rdev_set_cqm_rssi_config(rdev, dev,
9718 thresholds[0], hysteresis);
9719 }
9720
9721 if (!wiphy_ext_feature_isset(&rdev->wiphy,
9722 NL80211_EXT_FEATURE_CQM_RSSI_LIST))
9723 return -EOPNOTSUPP;
9724
9725 if (n_thresholds == 1 && thresholds[0] == 0) /* Disabling */
9726 n_thresholds = 0;
9727
9728 wdev_lock(wdev);
9729 if (n_thresholds) {
9730 struct cfg80211_cqm_config *cqm_config;
9731
9732 cqm_config = kzalloc(sizeof(struct cfg80211_cqm_config) +
9733 n_thresholds * sizeof(s32), GFP_KERNEL);
9734 if (!cqm_config) {
9735 err = -ENOMEM;
9736 goto unlock;
9737 }
9738
9739 cqm_config->rssi_hyst = hysteresis;
9740 cqm_config->n_rssi_thresholds = n_thresholds;
9741 memcpy(cqm_config->rssi_thresholds, thresholds,
9742 n_thresholds * sizeof(s32));
9743
9744 wdev->cqm_config = cqm_config;
9745 }
9746
9747 err = cfg80211_cqm_rssi_update(rdev, dev);
9748
9749unlock:
9750 wdev_unlock(wdev);
9751
9752 return err;
9526}9753}
9527 9754
9528static int nl80211_set_cqm(struct sk_buff *skb, struct genl_info *info)9755static int nl80211_set_cqm(struct sk_buff *skb, struct genl_info *info)
@@ -9542,10 +9769,16 @@ static int nl80211_set_cqm(struct sk_buff *skb, struct genl_info *info) · 13 unmodified lines
9542 9769
9543 if (attrs[NL80211_ATTR_CQM_RSSI_THOLD] &&9770 if (attrs[NL80211_ATTR_CQM_RSSI_THOLD] &&
9544 attrs[NL80211_ATTR_CQM_RSSI_HYST]) {9771 attrs[NL80211_ATTR_CQM_RSSI_HYST]) {
9545 s32 threshold = nla_get_s32(attrs[NL80211_ATTR_CQM_RSSI_THOLD]);9772 const s32 *thresholds =
9773 nla_data(attrs[NL80211_ATTR_CQM_RSSI_THOLD]);
9774 int len = nla_len(attrs[NL80211_ATTR_CQM_RSSI_THOLD]);
9546 u32 hysteresis = nla_get_u32(attrs[NL80211_ATTR_CQM_RSSI_HYST]);9775 u32 hysteresis = nla_get_u32(attrs[NL80211_ATTR_CQM_RSSI_HYST]);
9547 9776
9548 return nl80211_set_cqm_rssi(info, threshold, hysteresis);9777 if (len % 4)
9778 return -EINVAL;
9779
9780 return nl80211_set_cqm_rssi(info, thresholds, len / 4,
9781 hysteresis);
9549 }9782 }
9550 9783
9551 if (attrs[NL80211_ATTR_CQM_TXE_RATE] &&9784 if (attrs[NL80211_ATTR_CQM_TXE_RATE] &&
@@ -12977,18 +13210,19 @@ static int nl80211_prep_scan_msg(struct sk_buff *msg, · 3425 unmodified lines
12977 13210
12978static int13211static int
12979nl80211_prep_sched_scan_msg(struct sk_buff *msg,13212nl80211_prep_sched_scan_msg(struct sk_buff *msg,
12980 struct cfg80211_registered_device *rdev,13213 struct cfg80211_sched_scan_request *req, u32 cmd)
12981 struct net_device *netdev,
12982 u32 portid, u32 seq, int flags, u32 cmd)
12983{13214{
12984 void *hdr;13215 void *hdr;
12985 13216
12986 hdr = nl80211hdr_put(msg, portid, seq, flags, cmd);13217 hdr = nl80211hdr_put(msg, 0, 0, 0, cmd);
12987 if (!hdr)13218 if (!hdr)
12988 return -1;13219 return -1;
12989 13220
12990 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||13221 if (nla_put_u32(msg, NL80211_ATTR_WIPHY,
12991 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex))13222 wiphy_to_rdev(req->wiphy)->wiphy_idx) ||
13223 nla_put_u32(msg, NL80211_ATTR_IFINDEX, req->dev->ifindex) ||
13224 nla_put_u64_64bit(msg, NL80211_ATTR_COOKIE, req->reqid,
13225 NL80211_ATTR_PAD))
12992 goto nla_put_failure;13226 goto nla_put_failure;
12993 13227
12994 genlmsg_end(msg, hdr);13228 genlmsg_end(msg, hdr);
@@ -13048,8 +13282,7 @@ void nl80211_send_scan_msg(struct cfg80211_registered_device *rdev, · 53 unmodified lines
13048 NL80211_MCGRP_SCAN, GFP_KERNEL);13282 NL80211_MCGRP_SCAN, GFP_KERNEL);
13049}13283}
13050 13284
13051void nl80211_send_sched_scan(struct cfg80211_registered_device *rdev,13285void nl80211_send_sched_scan(struct cfg80211_sched_scan_request *req, u32 cmd)
13052 struct net_device *netdev, u32 cmd)
13053{13286{
13054 struct sk_buff *msg;13287 struct sk_buff *msg;
13055 13288
@@ -13057,12 +13290,12 @@ void nl80211_send_sched_scan(struct cfg80211_registered_device *rdev, · 1 unmodified line
13057 if (!msg)13290 if (!msg)
13058 return;13291 return;
13059 13292
13060 if (nl80211_prep_sched_scan_msg(msg, rdev, netdev, 0, 0, 0, cmd) < 0) {13293 if (nl80211_prep_sched_scan_msg(msg, req, cmd) < 0) {
13061 nlmsg_free(msg);13294 nlmsg_free(msg);
13062 return;13295 return;
13063 }13296 }
13064 13297
13065 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,13298 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(req->wiphy), msg, 0,
13066 NL80211_MCGRP_SCAN, GFP_KERNEL);13299 NL80211_MCGRP_SCAN, GFP_KERNEL);
13067}13300}
13068 13301
@@ -13303,17 +13536,16 @@ void nl80211_send_assoc_timeout(struct cfg80211_registered_device *rdev, · 234 unmodified lines
13303}13536}
13304 13537
13305void nl80211_send_connect_result(struct cfg80211_registered_device *rdev,13538void nl80211_send_connect_result(struct cfg80211_registered_device *rdev,
13306 struct net_device *netdev, const u8 *bssid,13539 struct net_device *netdev,
13307 const u8 *req_ie, size_t req_ie_len,13540 struct cfg80211_connect_resp_params *cr,
13308 const u8 *resp_ie, size_t resp_ie_len,
13309 int status,
13310 enum nl80211_timeout_reason timeout_reason,
13311 gfp_t gfp)13541 gfp_t gfp)
13312{13542{
13313 struct sk_buff *msg;13543 struct sk_buff *msg;
13314 void *hdr;13544 void *hdr;
13315 13545
13316 msg = nlmsg_new(100 + req_ie_len + resp_ie_len, gfp);13546 msg = nlmsg_new(100 + cr->req_ie_len + cr->resp_ie_len +
13547 cr->fils_kek_len + cr->pmk_len +
13548 (cr->pmkid ? WLAN_PMKID_LEN : 0), gfp);
13317 if (!msg)13549 if (!msg)
13318 return;13550 return;
13319 13551
@@ -13325,17 +13557,31 @@ void nl80211_send_connect_result(struct cfg80211_registered_device *rdev, · 5 unmodified lines
13325 13557
13326 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||13558 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
13327 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||13559 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
13328 (bssid && nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, bssid)) ||13560 (cr->bssid &&
13561 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, cr->bssid)) ||
13329 nla_put_u16(msg, NL80211_ATTR_STATUS_CODE,13562 nla_put_u16(msg, NL80211_ATTR_STATUS_CODE,
13330 status < 0 ? WLAN_STATUS_UNSPECIFIED_FAILURE :13563 cr->status < 0 ? WLAN_STATUS_UNSPECIFIED_FAILURE :
13331 status) ||13564 cr->status) ||
13332 (status < 0 &&13565 (cr->status < 0 &&
13333 (nla_put_flag(msg, NL80211_ATTR_TIMED_OUT) ||13566 (nla_put_flag(msg, NL80211_ATTR_TIMED_OUT) ||
13334 nla_put_u32(msg, NL80211_ATTR_TIMEOUT_REASON, timeout_reason))) ||13567 nla_put_u32(msg, NL80211_ATTR_TIMEOUT_REASON,
13335 (req_ie &&13568 cr->timeout_reason))) ||
13336 nla_put(msg, NL80211_ATTR_REQ_IE, req_ie_len, req_ie)) ||13569 (cr->req_ie &&
13337 (resp_ie &&13570 nla_put(msg, NL80211_ATTR_REQ_IE, cr->req_ie_len, cr->req_ie)) ||
13338 nla_put(msg, NL80211_ATTR_RESP_IE, resp_ie_len, resp_ie)))13571 (cr->resp_ie &&
13572 nla_put(msg, NL80211_ATTR_RESP_IE, cr->resp_ie_len,
13573 cr->resp_ie)) ||
13574 (cr->update_erp_next_seq_num &&
13575 nla_put_u16(msg, NL80211_ATTR_FILS_ERP_NEXT_SEQ_NUM,
13576 cr->fils_erp_next_seq_num)) ||
13577 (cr->status == WLAN_STATUS_SUCCESS &&
13578 ((cr->fils_kek &&
13579 nla_put(msg, NL80211_ATTR_FILS_KEK, cr->fils_kek_len,
13580 cr->fils_kek)) ||
13581 (cr->pmk &&
13582 nla_put(msg, NL80211_ATTR_PMK, cr->pmk_len, cr->pmk)) ||
13583 (cr->pmkid &&
13584 nla_put(msg, NL80211_ATTR_PMKID, WLAN_PMKID_LEN, cr->pmkid)))))
13339 goto nla_put_failure;13585 goto nla_put_failure;
13340 13586
13341 genlmsg_end(msg, hdr);13587 genlmsg_end(msg, hdr);
@@ -13975,6 +14221,8 @@ void cfg80211_cqm_rssi_notify(struct net_device *dev, · 633 unmodified lines
13975 s32 rssi_level, gfp_t gfp)14221 s32 rssi_level, gfp_t gfp)
13976{14222{
13977 struct sk_buff *msg;14223 struct sk_buff *msg;
14224 struct wireless_dev *wdev = dev->ieee80211_ptr;
14225 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
13978 14226
13979 trace_cfg80211_cqm_rssi_notify(dev, rssi_event, rssi_level);14227 trace_cfg80211_cqm_rssi_notify(dev, rssi_event, rssi_level);
13980 14228
@@ -13982,6 +14230,15 @@ void cfg80211_cqm_rssi_notify(struct net_device *dev, · 1 unmodified line
13982 rssi_event != NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH))14230 rssi_event != NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH))
13983 return;14231 return;
13984 14232
14233 if (wdev->cqm_config) {
14234 wdev->cqm_config->last_rssi_event_value = rssi_level;
14235
14236 cfg80211_cqm_rssi_update(rdev, dev);
14237
14238 if (rssi_level == 0)
14239 rssi_level = wdev->cqm_config->last_rssi_event_value;
14240 }
14241
13985 msg = cfg80211_prepare_cqm(dev, NULL, gfp);14242 msg = cfg80211_prepare_cqm(dev, NULL, gfp);
13986 if (!msg)14243 if (!msg)
13987 return;14244 return;
net/wireless/nl80211.h+3−7
@@ -16,8 +16,7 @@ struct sk_buff *nl80211_build_scan_msg(struct cfg80211_registered_device *rdev, · 15 unmodified lines
16 struct wireless_dev *wdev, bool aborted);16 struct wireless_dev *wdev, bool aborted);
17void nl80211_send_scan_msg(struct cfg80211_registered_device *rdev,17void nl80211_send_scan_msg(struct cfg80211_registered_device *rdev,
18 struct sk_buff *msg);18 struct sk_buff *msg);
19void nl80211_send_sched_scan(struct cfg80211_registered_device *rdev,19void nl80211_send_sched_scan(struct cfg80211_sched_scan_request *req, u32 cmd);
20 struct net_device *netdev, u32 cmd);
21void nl80211_common_reg_change_event(enum nl80211_commands cmd_id,20void nl80211_common_reg_change_event(enum nl80211_commands cmd_id,
22 struct regulatory_request *request);21 struct regulatory_request *request);
23 22
@@ -53,11 +52,8 @@ void nl80211_send_assoc_timeout(struct cfg80211_registered_device *rdev, · 29 unmodified lines
53 struct net_device *netdev,52 struct net_device *netdev,
54 const u8 *addr, gfp_t gfp);53 const u8 *addr, gfp_t gfp);
55void nl80211_send_connect_result(struct cfg80211_registered_device *rdev,54void nl80211_send_connect_result(struct cfg80211_registered_device *rdev,
56 struct net_device *netdev, const u8 *bssid,55 struct net_device *netdev,
57 const u8 *req_ie, size_t req_ie_len,56 struct cfg80211_connect_resp_params *params,
58 const u8 *resp_ie, size_t resp_ie_len,
59 int status,
60 enum nl80211_timeout_reason timeout_reason,
61 gfp_t gfp);57 gfp_t gfp);
62void nl80211_send_roamed(struct cfg80211_registered_device *rdev,58void nl80211_send_roamed(struct cfg80211_registered_device *rdev,
63 struct net_device *netdev, const u8 *bssid,59 struct net_device *netdev, const u8 *bssid,
net/wireless/rdev-ops.h+16−5
@@ -36,13 +36,13 @@ static inline void rdev_set_wakeup(struct cfg80211_registered_device *rdev, · 35 unmodified lines
36static inline struct wireless_dev36static inline struct wireless_dev
37*rdev_add_virtual_intf(struct cfg80211_registered_device *rdev, char *name,37*rdev_add_virtual_intf(struct cfg80211_registered_device *rdev, char *name,
38 unsigned char name_assign_type,38 unsigned char name_assign_type,
39 enum nl80211_iftype type, u32 *flags,39 enum nl80211_iftype type,
40 struct vif_params *params)40 struct vif_params *params)
41{41{
42 struct wireless_dev *ret;42 struct wireless_dev *ret;
43 trace_rdev_add_virtual_intf(&rdev->wiphy, name, type);43 trace_rdev_add_virtual_intf(&rdev->wiphy, name, type);
44 ret = rdev->ops->add_virtual_intf(&rdev->wiphy, name, name_assign_type,44 ret = rdev->ops->add_virtual_intf(&rdev->wiphy, name, name_assign_type,
45 type, flags, params);45 type, params);
46 trace_rdev_return_wdev(&rdev->wiphy, ret);46 trace_rdev_return_wdev(&rdev->wiphy, ret);
47 return ret;47 return ret;
48}48}
@@ -61,12 +61,11 @@ rdev_del_virtual_intf(struct cfg80211_registered_device *rdev, · 12 unmodified lines
61static inline int61static inline int
62rdev_change_virtual_intf(struct cfg80211_registered_device *rdev,62rdev_change_virtual_intf(struct cfg80211_registered_device *rdev,
63 struct net_device *dev, enum nl80211_iftype type,63 struct net_device *dev, enum nl80211_iftype type,
64 u32 *flags, struct vif_params *params)64 struct vif_params *params)
65{65{
66 int ret;66 int ret;
67 trace_rdev_change_virtual_intf(&rdev->wiphy, dev, type);67 trace_rdev_change_virtual_intf(&rdev->wiphy, dev, type);
68 ret = rdev->ops->change_virtual_intf(&rdev->wiphy, dev, type, flags,68 ret = rdev->ops->change_virtual_intf(&rdev->wiphy, dev, type, params);
69 params);
70 trace_rdev_return_int(&rdev->wiphy, ret);69 trace_rdev_return_int(&rdev->wiphy, ret);
71 return ret;70 return ret;
72}71}
@@ -749,6 +748,18 @@ rdev_set_cqm_rssi_config(struct cfg80211_registered_device *rdev, · 676 unmodified lines
749 return ret;748 return ret;
750}749}
751 750
751static inline int
752rdev_set_cqm_rssi_range_config(struct cfg80211_registered_device *rdev,
753 struct net_device *dev, s32 low, s32 high)
754{
755 int ret;
756 trace_rdev_set_cqm_rssi_range_config(&rdev->wiphy, dev, low, high);
757 ret = rdev->ops->set_cqm_rssi_range_config(&rdev->wiphy, dev,
758 low, high);
759 trace_rdev_return_int(&rdev->wiphy, ret);
760 return ret;
761}
762
752static inline int763static inline int
753rdev_set_cqm_txe_config(struct cfg80211_registered_device *rdev,764rdev_set_cqm_txe_config(struct cfg80211_registered_device *rdev,
754 struct net_device *dev, u32 rate, u32 pkts, u32 intvl)765 struct net_device *dev, u32 rate, u32 pkts, u32 intvl)
net/wireless/reg.c+148−0
@@ -2067,6 +2067,88 @@ reg_process_hint_country_ie(struct wiphy *wiphy, · 2066 unmodified lines
2067 return REG_REQ_IGNORE;2067 return REG_REQ_IGNORE;
2068}2068}
2069 2069
2070bool reg_dfs_domain_same(struct wiphy *wiphy1, struct wiphy *wiphy2)
2071{
2072 const struct ieee80211_regdomain *wiphy1_regd = NULL;
2073 const struct ieee80211_regdomain *wiphy2_regd = NULL;
2074 const struct ieee80211_regdomain *cfg80211_regd = NULL;
2075 bool dfs_domain_same;
2076
2077 rcu_read_lock();
2078
2079 cfg80211_regd = rcu_dereference(cfg80211_regdomain);
2080 wiphy1_regd = rcu_dereference(wiphy1->regd);
2081 if (!wiphy1_regd)
2082 wiphy1_regd = cfg80211_regd;
2083
2084 wiphy2_regd = rcu_dereference(wiphy2->regd);
2085 if (!wiphy2_regd)
2086 wiphy2_regd = cfg80211_regd;
2087
2088 dfs_domain_same = wiphy1_regd->dfs_region == wiphy2_regd->dfs_region;
2089
2090 rcu_read_unlock();
2091
2092 return dfs_domain_same;
2093}
2094
2095static void reg_copy_dfs_chan_state(struct ieee80211_channel *dst_chan,
2096 struct ieee80211_channel *src_chan)
2097{
2098 if (!(dst_chan->flags & IEEE80211_CHAN_RADAR) ||
2099 !(src_chan->flags & IEEE80211_CHAN_RADAR))
2100 return;
2101
2102 if (dst_chan->flags & IEEE80211_CHAN_DISABLED ||
2103 src_chan->flags & IEEE80211_CHAN_DISABLED)
2104 return;
2105
2106 if (src_chan->center_freq == dst_chan->center_freq &&
2107 dst_chan->dfs_state == NL80211_DFS_USABLE) {
2108 dst_chan->dfs_state = src_chan->dfs_state;
2109 dst_chan->dfs_state_entered = src_chan->dfs_state_entered;
2110 }
2111}
2112
2113static void wiphy_share_dfs_chan_state(struct wiphy *dst_wiphy,
2114 struct wiphy *src_wiphy)
2115{
2116 struct ieee80211_supported_band *src_sband, *dst_sband;
2117 struct ieee80211_channel *src_chan, *dst_chan;
2118 int i, j, band;
2119
2120 if (!reg_dfs_domain_same(dst_wiphy, src_wiphy))
2121 return;
2122
2123 for (band = 0; band < NUM_NL80211_BANDS; band++) {
2124 dst_sband = dst_wiphy->bands[band];
2125 src_sband = src_wiphy->bands[band];
2126 if (!dst_sband || !src_sband)
2127 continue;
2128
2129 for (i = 0; i < dst_sband->n_channels; i++) {
2130 dst_chan = &dst_sband->channels[i];
2131 for (j = 0; j < src_sband->n_channels; j++) {
2132 src_chan = &src_sband->channels[j];
2133 reg_copy_dfs_chan_state(dst_chan, src_chan);
2134 }
2135 }
2136 }
2137}
2138
2139static void wiphy_all_share_dfs_chan_state(struct wiphy *wiphy)
2140{
2141 struct cfg80211_registered_device *rdev;
2142
2143 ASSERT_RTNL();
2144
2145 list_for_each_entry(rdev, &cfg80211_rdev_list, list) {
2146 if (wiphy == &rdev->wiphy)
2147 continue;
2148 wiphy_share_dfs_chan_state(wiphy, &rdev->wiphy);
2149 }
2150}
2151
2070/* This processes *all* regulatory hints */2152/* This processes *all* regulatory hints */
2071static void reg_process_hint(struct regulatory_request *reg_request)2153static void reg_process_hint(struct regulatory_request *reg_request)
2072{2154{
@@ -2110,6 +2192,7 @@ static void reg_process_hint(struct regulatory_request *reg_request) · 37 unmodified lines
2110 if (treatment == REG_REQ_ALREADY_SET && wiphy &&2192 if (treatment == REG_REQ_ALREADY_SET && wiphy &&
2111 wiphy->regulatory_flags & REGULATORY_STRICT_REG) {2193 wiphy->regulatory_flags & REGULATORY_STRICT_REG) {
2112 wiphy_update_regulatory(wiphy, reg_request->initiator);2194 wiphy_update_regulatory(wiphy, reg_request->initiator);
2195 wiphy_all_share_dfs_chan_state(wiphy);
2113 reg_check_channels();2196 reg_check_channels();
2114 }2197 }
2115 2198
@@ -3061,6 +3144,7 @@ void wiphy_regulatory_register(struct wiphy *wiphy) · 945 unmodified lines
3061 3144
3062 lr = get_last_request();3145 lr = get_last_request();
3063 wiphy_update_regulatory(wiphy, lr->initiator);3146 wiphy_update_regulatory(wiphy, lr->initiator);
3147 wiphy_all_share_dfs_chan_state(wiphy);
3064}3148}
3065 3149
3066void wiphy_regulatory_deregister(struct wiphy *wiphy)3150void wiphy_regulatory_deregister(struct wiphy *wiphy)
@@ -3120,6 +3204,70 @@ bool regulatory_indoor_allowed(void) · 53 unmodified lines
3120 return reg_is_indoor;3204 return reg_is_indoor;
3121}3205}
3122 3206
3207bool regulatory_pre_cac_allowed(struct wiphy *wiphy)
3208{
3209 const struct ieee80211_regdomain *regd = NULL;
3210 const struct ieee80211_regdomain *wiphy_regd = NULL;
3211 bool pre_cac_allowed = false;
3212
3213 rcu_read_lock();
3214
3215 regd = rcu_dereference(cfg80211_regdomain);
3216 wiphy_regd = rcu_dereference(wiphy->regd);
3217 if (!wiphy_regd) {
3218 if (regd->dfs_region == NL80211_DFS_ETSI)
3219 pre_cac_allowed = true;
3220
3221 rcu_read_unlock();
3222
3223 return pre_cac_allowed;
3224 }
3225
3226 if (regd->dfs_region == wiphy_regd->dfs_region &&
3227 wiphy_regd->dfs_region == NL80211_DFS_ETSI)
3228 pre_cac_allowed = true;
3229
3230 rcu_read_unlock();
3231
3232 return pre_cac_allowed;
3233}
3234
3235void regulatory_propagate_dfs_state(struct wiphy *wiphy,
3236 struct cfg80211_chan_def *chandef,
3237 enum nl80211_dfs_state dfs_state,
3238 enum nl80211_radar_event event)
3239{
3240 struct cfg80211_registered_device *rdev;
3241
3242 ASSERT_RTNL();
3243
3244 if (WARN_ON(!cfg80211_chandef_valid(chandef)))
3245 return;
3246
3247 if (WARN_ON(!(chandef->chan->flags & IEEE80211_CHAN_RADAR)))
3248 return;
3249
3250 list_for_each_entry(rdev, &cfg80211_rdev_list, list) {
3251 if (wiphy == &rdev->wiphy)
3252 continue;
3253
3254 if (!reg_dfs_domain_same(wiphy, &rdev->wiphy))
3255 continue;
3256
3257 if (!ieee80211_get_channel(&rdev->wiphy,
3258 chandef->chan->center_freq))
3259 continue;
3260
3261 cfg80211_set_dfs_state(&rdev->wiphy, chandef, dfs_state);
3262
3263 if (event == NL80211_RADAR_DETECTED ||
3264 event == NL80211_RADAR_CAC_FINISHED)
3265 cfg80211_sched_dfs_chan_update(rdev);
3266
3267 nl80211_radar_notify(rdev, chandef, event, NULL, GFP_KERNEL);
3268 }
3269}
3270
3123int __init regulatory_init(void)3271int __init regulatory_init(void)
3124{3272{
3125 int err = 0;3273 int err = 0;
net/wireless/reg.h+36−0
@@ -143,4 +143,40 @@ int cfg80211_get_unii(int freq); · 142 unmodified lines
143 */143 */
144bool regulatory_indoor_allowed(void);144bool regulatory_indoor_allowed(void);
145 145
146/*
147 * Grace period to timeout pre-CAC results on the dfs channels. This timeout
148 * value is used for Non-ETSI domain.
149 * TODO: May be make this timeout available through regdb?
150 */
151#define REG_PRE_CAC_EXPIRY_GRACE_MS 2000
152
153/**
154 * regulatory_pre_cac_allowed - if pre-CAC allowed in the current dfs domain
155 * @wiphy: wiphy for which pre-CAC capability is checked.
156
157 * Pre-CAC is allowed only in ETSI domain.
158 */
159bool regulatory_pre_cac_allowed(struct wiphy *wiphy);
160
161/**
162 * regulatory_propagate_dfs_state - Propagate DFS channel state to other wiphys
163 * @wiphy - wiphy on which radar is detected and the event will be propagated
164 * to other available wiphys having the same DFS domain
165 * @chandef - Channel definition of radar detected channel
166 * @dfs_state - DFS channel state to be set
167 * @event - Type of radar event which triggered this DFS state change
168 *
169 * This function should be called with rtnl lock held.
170 */
171void regulatory_propagate_dfs_state(struct wiphy *wiphy,
172 struct cfg80211_chan_def *chandef,
173 enum nl80211_dfs_state dfs_state,
174 enum nl80211_radar_event event);
175
176/**
177 * reg_dfs_domain_same - Checks if both wiphy have same DFS domain configured
178 * @wiphy1 - wiphy it's dfs_region to be checked against that of wiphy2
179 * @wiphy2 - wiphy it's dfs_region to be checked against that of wiphy1
180 */
181bool reg_dfs_domain_same(struct wiphy *wiphy1, struct wiphy *wiphy2);
146#endif /* __NET_WIRELESS_REG_H */182#endif /* __NET_WIRELESS_REG_H */
net/wireless/scan.c+2−3
@@ -321,8 +321,7 @@ void __cfg80211_sched_scan_results(struct work_struct *wk) · 320 unmodified lines
321 spin_unlock_bh(&rdev->bss_lock);321 spin_unlock_bh(&rdev->bss_lock);
322 request->scan_start = jiffies;322 request->scan_start = jiffies;
323 }323 }
324 nl80211_send_sched_scan(rdev, request->dev,324 nl80211_send_sched_scan(request, NL80211_CMD_SCHED_SCAN_RESULTS);
325 NL80211_CMD_SCHED_SCAN_RESULTS);
326 }325 }
327 326
328 rtnl_unlock();327 rtnl_unlock();
@@ -379,7 +378,7 @@ int __cfg80211_stop_sched_scan(struct cfg80211_registered_device *rdev, · 50 unmodified lines
379 return err;378 return err;
380 }379 }
381 380
382 nl80211_send_sched_scan(rdev, dev, NL80211_CMD_SCHED_SCAN_STOPPED);381 nl80211_send_sched_scan(sched_scan_req, NL80211_CMD_SCHED_SCAN_STOPPED);
383 382
384 RCU_INIT_POINTER(rdev->sched_scan_req, NULL);383 RCU_INIT_POINTER(rdev->sched_scan_req, NULL);
385 kfree_rcu(sched_scan_req, rcu_head);384 kfree_rcu(sched_scan_req, rcu_head);
net/wireless/sme.c+103−69
@@ -253,10 +253,13 @@ void cfg80211_conn_work(struct work_struct *work) · 252 unmodified lines
253 }253 }
254 treason = NL80211_TIMEOUT_UNSPECIFIED;254 treason = NL80211_TIMEOUT_UNSPECIFIED;
255 if (cfg80211_conn_do_work(wdev, &treason)) {255 if (cfg80211_conn_do_work(wdev, &treason)) {
256 __cfg80211_connect_result(256 struct cfg80211_connect_resp_params cr;
257 wdev->netdev, bssid,257
258 NULL, 0, NULL, 0, -1, false, NULL,258 memset(&cr, 0, sizeof(cr));
259 treason);259 cr.status = -1;
260 cr.bssid = bssid;
261 cr.timeout_reason = treason;
262 __cfg80211_connect_result(wdev->netdev, &cr, false);
260 }263 }
261 wdev_unlock(wdev);264 wdev_unlock(wdev);
262 }265 }
@@ -359,10 +362,13 @@ void cfg80211_sme_rx_auth(struct wireless_dev *wdev, const u8 *buf, size_t len) · 96 unmodified lines
359 wdev->conn->state = CFG80211_CONN_AUTHENTICATE_NEXT;362 wdev->conn->state = CFG80211_CONN_AUTHENTICATE_NEXT;
360 schedule_work(&rdev->conn_work);363 schedule_work(&rdev->conn_work);
361 } else if (status_code != WLAN_STATUS_SUCCESS) {364 } else if (status_code != WLAN_STATUS_SUCCESS) {
362 __cfg80211_connect_result(wdev->netdev, mgmt->bssid,365 struct cfg80211_connect_resp_params cr;
363 NULL, 0, NULL, 0,366
364 status_code, false, NULL,367 memset(&cr, 0, sizeof(cr));
365 NL80211_TIMEOUT_UNSPECIFIED);368 cr.status = status_code;
369 cr.bssid = mgmt->bssid;
370 cr.timeout_reason = NL80211_TIMEOUT_UNSPECIFIED;
371 __cfg80211_connect_result(wdev->netdev, &cr, false);
366 } else if (wdev->conn->state == CFG80211_CONN_AUTHENTICATING) {372 } else if (wdev->conn->state == CFG80211_CONN_AUTHENTICATING) {
367 wdev->conn->state = CFG80211_CONN_ASSOCIATE_NEXT;373 wdev->conn->state = CFG80211_CONN_ASSOCIATE_NEXT;
368 schedule_work(&rdev->conn_work);374 schedule_work(&rdev->conn_work);
@@ -669,12 +675,9 @@ static DECLARE_WORK(cfg80211_disconnect_work, disconnect_work); · 300 unmodified lines
669 */675 */
670 676
671/* This method must consume bss one way or another */677/* This method must consume bss one way or another */
672void __cfg80211_connect_result(struct net_device *dev, const u8 *bssid,678void __cfg80211_connect_result(struct net_device *dev,
673 const u8 *req_ie, size_t req_ie_len,679 struct cfg80211_connect_resp_params *cr,
674 const u8 *resp_ie, size_t resp_ie_len,680 bool wextev)
675 int status, bool wextev,
676 struct cfg80211_bss *bss,
677 enum nl80211_timeout_reason timeout_reason)
678{681{
679 struct wireless_dev *wdev = dev->ieee80211_ptr;682 struct wireless_dev *wdev = dev->ieee80211_ptr;
680 const u8 *country_ie;683 const u8 *country_ie;
@@ -686,48 +689,48 @@ void __cfg80211_connect_result(struct net_device *dev, const u8 *bssid, · 5 unmodified lines
686 689
687 if (WARN_ON(wdev->iftype != NL80211_IFTYPE_STATION &&690 if (WARN_ON(wdev->iftype != NL80211_IFTYPE_STATION &&
688 wdev->iftype != NL80211_IFTYPE_P2P_CLIENT)) {691 wdev->iftype != NL80211_IFTYPE_P2P_CLIENT)) {
689 cfg80211_put_bss(wdev->wiphy, bss);692 cfg80211_put_bss(wdev->wiphy, cr->bss);
690 return;693 return;
691 }694 }
692 695
693 nl80211_send_connect_result(wiphy_to_rdev(wdev->wiphy), dev,696 nl80211_send_connect_result(wiphy_to_rdev(wdev->wiphy), dev, cr,
694 bssid, req_ie, req_ie_len,697 GFP_KERNEL);
695 resp_ie, resp_ie_len,
696 status, timeout_reason, GFP_KERNEL);
697 698
698#ifdef CONFIG_CFG80211_WEXT699#ifdef CONFIG_CFG80211_WEXT
699 if (wextev) {700 if (wextev) {
700 if (req_ie && status == WLAN_STATUS_SUCCESS) {701 if (cr->req_ie && cr->status == WLAN_STATUS_SUCCESS) {
701 memset(&wrqu, 0, sizeof(wrqu));702 memset(&wrqu, 0, sizeof(wrqu));
702 wrqu.data.length = req_ie_len;703 wrqu.data.length = cr->req_ie_len;
703 wireless_send_event(dev, IWEVASSOCREQIE, &wrqu, req_ie);704 wireless_send_event(dev, IWEVASSOCREQIE, &wrqu,
705 cr->req_ie);
704 }706 }
705 707
706 if (resp_ie && status == WLAN_STATUS_SUCCESS) {708 if (cr->resp_ie && cr->status == WLAN_STATUS_SUCCESS) {
707 memset(&wrqu, 0, sizeof(wrqu));709 memset(&wrqu, 0, sizeof(wrqu));
708 wrqu.data.length = resp_ie_len;710 wrqu.data.length = cr->resp_ie_len;
709 wireless_send_event(dev, IWEVASSOCRESPIE, &wrqu, resp_ie);711 wireless_send_event(dev, IWEVASSOCRESPIE, &wrqu,
712 cr->resp_ie);
710 }713 }
711 714
712 memset(&wrqu, 0, sizeof(wrqu));715 memset(&wrqu, 0, sizeof(wrqu));
713 wrqu.ap_addr.sa_family = ARPHRD_ETHER;716 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
714 if (bssid && status == WLAN_STATUS_SUCCESS) {717 if (cr->bssid && cr->status == WLAN_STATUS_SUCCESS) {
715 memcpy(wrqu.ap_addr.sa_data, bssid, ETH_ALEN);718 memcpy(wrqu.ap_addr.sa_data, cr->bssid, ETH_ALEN);
716 memcpy(wdev->wext.prev_bssid, bssid, ETH_ALEN);719 memcpy(wdev->wext.prev_bssid, cr->bssid, ETH_ALEN);
717 wdev->wext.prev_bssid_valid = true;720 wdev->wext.prev_bssid_valid = true;
718 }721 }
719 wireless_send_event(dev, SIOCGIWAP, &wrqu, NULL);722 wireless_send_event(dev, SIOCGIWAP, &wrqu, NULL);
720 }723 }
721#endif724#endif
722 725
723 if (!bss && (status == WLAN_STATUS_SUCCESS)) {726 if (!cr->bss && (cr->status == WLAN_STATUS_SUCCESS)) {
724 WARN_ON_ONCE(!wiphy_to_rdev(wdev->wiphy)->ops->connect);727 WARN_ON_ONCE(!wiphy_to_rdev(wdev->wiphy)->ops->connect);
725 bss = cfg80211_get_bss(wdev->wiphy, NULL, bssid,728 cr->bss = cfg80211_get_bss(wdev->wiphy, NULL, cr->bssid,
726 wdev->ssid, wdev->ssid_len,729 wdev->ssid, wdev->ssid_len,
727 wdev->conn_bss_type,730 wdev->conn_bss_type,
728 IEEE80211_PRIVACY_ANY);731 IEEE80211_PRIVACY_ANY);
729 if (bss)732 if (cr->bss)
730 cfg80211_hold_bss(bss_from_pub(bss));733 cfg80211_hold_bss(bss_from_pub(cr->bss));
731 }734 }
732 735
733 if (wdev->current_bss) {736 if (wdev->current_bss) {
@@ -736,29 +739,29 @@ void __cfg80211_connect_result(struct net_device *dev, const u8 *bssid, · 2 unmodified lines
736 wdev->current_bss = NULL;739 wdev->current_bss = NULL;
737 }740 }
738 741
739 if (status != WLAN_STATUS_SUCCESS) {742 if (cr->status != WLAN_STATUS_SUCCESS) {
740 kzfree(wdev->connect_keys);743 kzfree(wdev->connect_keys);
741 wdev->connect_keys = NULL;744 wdev->connect_keys = NULL;
742 wdev->ssid_len = 0;745 wdev->ssid_len = 0;
743 wdev->conn_owner_nlportid = 0;746 wdev->conn_owner_nlportid = 0;
744 if (bss) {747 if (cr->bss) {
745 cfg80211_unhold_bss(bss_from_pub(bss));748 cfg80211_unhold_bss(bss_from_pub(cr->bss));
746 cfg80211_put_bss(wdev->wiphy, bss);749 cfg80211_put_bss(wdev->wiphy, cr->bss);
747 }750 }
748 cfg80211_sme_free(wdev);751 cfg80211_sme_free(wdev);
749 return;752 return;
750 }753 }
751 754
752 if (WARN_ON(!bss))755 if (WARN_ON(!cr->bss))
753 return;756 return;
754 757
755 wdev->current_bss = bss_from_pub(bss);758 wdev->current_bss = bss_from_pub(cr->bss);
756 759
757 if (!(wdev->wiphy->flags & WIPHY_FLAG_HAS_STATIC_WEP))760 if (!(wdev->wiphy->flags & WIPHY_FLAG_HAS_STATIC_WEP))
758 cfg80211_upload_connect_keys(wdev);761 cfg80211_upload_connect_keys(wdev);
759 762
760 rcu_read_lock();763 rcu_read_lock();
761 country_ie = ieee80211_bss_get_ie(bss, WLAN_EID_COUNTRY);764 country_ie = ieee80211_bss_get_ie(cr->bss, WLAN_EID_COUNTRY);
762 if (!country_ie) {765 if (!country_ie) {
763 rcu_read_unlock();766 rcu_read_unlock();
764 return;767 return;
@@ -775,64 +778,95 @@ void __cfg80211_connect_result(struct net_device *dev, const u8 *bssid, · 10 unmodified lines
775 * - country_ie + 2, the start of the country ie data, and778 * - country_ie + 2, the start of the country ie data, and
776 * - and country_ie[1] which is the IE length779 * - and country_ie[1] which is the IE length
777 */780 */
778 regulatory_hint_country_ie(wdev->wiphy, bss->channel->band,781 regulatory_hint_country_ie(wdev->wiphy, cr->bss->channel->band,
779 country_ie + 2, country_ie[1]);782 country_ie + 2, country_ie[1]);
780 kfree(country_ie);783 kfree(country_ie);
781}784}
782 785
783/* Consumes bss object one way or another */786/* Consumes bss object one way or another */
784void cfg80211_connect_bss(struct net_device *dev, const u8 *bssid,787void cfg80211_connect_done(struct net_device *dev,
785 struct cfg80211_bss *bss, const u8 *req_ie,788 struct cfg80211_connect_resp_params *params,
786 size_t req_ie_len, const u8 *resp_ie,789 gfp_t gfp)
787 size_t resp_ie_len, int status, gfp_t gfp,
788 enum nl80211_timeout_reason timeout_reason)
789{790{
790 struct wireless_dev *wdev = dev->ieee80211_ptr;791 struct wireless_dev *wdev = dev->ieee80211_ptr;
791 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);792 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
792 struct cfg80211_event *ev;793 struct cfg80211_event *ev;
793 unsigned long flags;794 unsigned long flags;
795 u8 *next;
794 796
795 if (bss) {797 if (params->bss) {
796 /* Make sure the bss entry provided by the driver is valid. */798 /* Make sure the bss entry provided by the driver is valid. */
797 struct cfg80211_internal_bss *ibss = bss_from_pub(bss);799 struct cfg80211_internal_bss *ibss = bss_from_pub(params->bss);
798 800
799 if (WARN_ON(list_empty(&ibss->list))) {801 if (WARN_ON(list_empty(&ibss->list))) {
800 cfg80211_put_bss(wdev->wiphy, bss);802 cfg80211_put_bss(wdev->wiphy, params->bss);
801 return;803 return;
802 }804 }
803 }805 }
804 806
805 ev = kzalloc(sizeof(*ev) + req_ie_len + resp_ie_len, gfp);807 ev = kzalloc(sizeof(*ev) + (params->bssid ? ETH_ALEN : 0) +
808 params->req_ie_len + params->resp_ie_len +
809 params->fils_kek_len + params->pmk_len +
810 (params->pmkid ? WLAN_PMKID_LEN : 0), gfp);
806 if (!ev) {811 if (!ev) {
807 cfg80211_put_bss(wdev->wiphy, bss);812 cfg80211_put_bss(wdev->wiphy, params->bss);
808 return;813 return;
809 }814 }
810 815
811 ev->type = EVENT_CONNECT_RESULT;816 ev->type = EVENT_CONNECT_RESULT;
812 if (bssid)817 next = ((u8 *)ev) + sizeof(*ev);
813 memcpy(ev->cr.bssid, bssid, ETH_ALEN);818 if (params->bssid) {
814 if (req_ie_len) {819 ev->cr.bssid = next;
815 ev->cr.req_ie = ((u8 *)ev) + sizeof(*ev);820 memcpy((void *)ev->cr.bssid, params->bssid, ETH_ALEN);
816 ev->cr.req_ie_len = req_ie_len;821 next += ETH_ALEN;
817 memcpy((void *)ev->cr.req_ie, req_ie, req_ie_len);
818 }822 }
819 if (resp_ie_len) {823 if (params->req_ie_len) {
820 ev->cr.resp_ie = ((u8 *)ev) + sizeof(*ev) + req_ie_len;824 ev->cr.req_ie = next;
821 ev->cr.resp_ie_len = resp_ie_len;825 ev->cr.req_ie_len = params->req_ie_len;
822 memcpy((void *)ev->cr.resp_ie, resp_ie, resp_ie_len);826 memcpy((void *)ev->cr.req_ie, params->req_ie,
827 params->req_ie_len);
828 next += params->req_ie_len;
823 }829 }
824 if (bss)830 if (params->resp_ie_len) {
825 cfg80211_hold_bss(bss_from_pub(bss));831 ev->cr.resp_ie = next;
826 ev->cr.bss = bss;832 ev->cr.resp_ie_len = params->resp_ie_len;
827 ev->cr.status = status;833 memcpy((void *)ev->cr.resp_ie, params->resp_ie,
828 ev->cr.timeout_reason = timeout_reason;834 params->resp_ie_len);
835 next += params->resp_ie_len;
836 }
837 if (params->fils_kek_len) {
838 ev->cr.fils_kek = next;
839 ev->cr.fils_kek_len = params->fils_kek_len;
840 memcpy((void *)ev->cr.fils_kek, params->fils_kek,
841 params->fils_kek_len);
842 next += params->fils_kek_len;
843 }
844 if (params->pmk_len) {
845 ev->cr.pmk = next;
846 ev->cr.pmk_len = params->pmk_len;
847 memcpy((void *)ev->cr.pmk, params->pmk, params->pmk_len);
848 next += params->pmk_len;
849 }
850 if (params->pmkid) {
851 ev->cr.pmkid = next;
852 memcpy((void *)ev->cr.pmkid, params->pmkid, WLAN_PMKID_LEN);
853 next += WLAN_PMKID_LEN;
854 }
855 ev->cr.update_erp_next_seq_num = params->update_erp_next_seq_num;
856 if (params->update_erp_next_seq_num)
857 ev->cr.fils_erp_next_seq_num = params->fils_erp_next_seq_num;
858 if (params->bss)
859 cfg80211_hold_bss(bss_from_pub(params->bss));
860 ev->cr.bss = params->bss;
861 ev->cr.status = params->status;
862 ev->cr.timeout_reason = params->timeout_reason;
829 863
830 spin_lock_irqsave(&wdev->event_lock, flags);864 spin_lock_irqsave(&wdev->event_lock, flags);
831 list_add_tail(&ev->list, &wdev->event_list);865 list_add_tail(&ev->list, &wdev->event_list);
832 spin_unlock_irqrestore(&wdev->event_lock, flags);866 spin_unlock_irqrestore(&wdev->event_lock, flags);
833 queue_work(cfg80211_wq, &rdev->event_work);867 queue_work(cfg80211_wq, &rdev->event_work);
834}868}
835EXPORT_SYMBOL(cfg80211_connect_bss);869EXPORT_SYMBOL(cfg80211_connect_done);
836 870
837/* Consumes bss object one way or another */871/* Consumes bss object one way or another */
838void __cfg80211_roamed(struct wireless_dev *wdev,872void __cfg80211_roamed(struct wireless_dev *wdev,
net/wireless/trace.h+22−0
@@ -1322,6 +1322,28 @@ TRACE_EVENT(rdev_set_cqm_rssi_config, · 1321 unmodified lines
1322 __entry->rssi_thold, __entry->rssi_hyst)1322 __entry->rssi_thold, __entry->rssi_hyst)
1323);1323);
1324 1324
1325TRACE_EVENT(rdev_set_cqm_rssi_range_config,
1326 TP_PROTO(struct wiphy *wiphy,
1327 struct net_device *netdev, s32 low, s32 high),
1328 TP_ARGS(wiphy, netdev, low, high),
1329 TP_STRUCT__entry(
1330 WIPHY_ENTRY
1331 NETDEV_ENTRY
1332 __field(s32, rssi_low)
1333 __field(s32, rssi_high)
1334 ),
1335 TP_fast_assign(
1336 WIPHY_ASSIGN;
1337 NETDEV_ASSIGN;
1338 __entry->rssi_low = low;
1339 __entry->rssi_high = high;
1340 ),
1341 TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT
1342 ", range: %d - %d ",
1343 WIPHY_PR_ARG, NETDEV_PR_ARG,
1344 __entry->rssi_low, __entry->rssi_high)
1345);
1346
1325TRACE_EVENT(rdev_set_cqm_txe_config,1347TRACE_EVENT(rdev_set_cqm_txe_config,
1326 TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, u32 rate,1348 TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, u32 rate,
1327 u32 pkts, u32 intvl),1349 u32 pkts, u32 intvl),
net/wireless/util.c+45−47
@@ -659,7 +659,7 @@ __ieee80211_amsdu_copy_frag(struct sk_buff *skb, struct sk_buff *frame, · 658 unmodified lines
659 int offset, int len)659 int offset, int len)
660{660{
661 struct skb_shared_info *sh = skb_shinfo(skb);661 struct skb_shared_info *sh = skb_shinfo(skb);
662 const skb_frag_t *frag = &sh->frags[-1];662 const skb_frag_t *frag = &sh->frags[0];
663 struct page *frag_page;663 struct page *frag_page;
664 void *frag_ptr;664 void *frag_ptr;
665 int frag_len, frag_size;665 int frag_len, frag_size;
@@ -672,10 +672,10 @@ __ieee80211_amsdu_copy_frag(struct sk_buff *skb, struct sk_buff *frame, · 6 unmodified lines
672 672
673 while (offset >= frag_size) {673 while (offset >= frag_size) {
674 offset -= frag_size;674 offset -= frag_size;
675 frag++;
676 frag_page = skb_frag_page(frag);675 frag_page = skb_frag_page(frag);
677 frag_ptr = skb_frag_address(frag);676 frag_ptr = skb_frag_address(frag);
678 frag_size = skb_frag_size(frag);677 frag_size = skb_frag_size(frag);
678 frag++;
679 }679 }
680 680
681 frag_ptr += offset;681 frag_ptr += offset;
@@ -687,12 +687,12 @@ __ieee80211_amsdu_copy_frag(struct sk_buff *skb, struct sk_buff *frame, · 5 unmodified lines
687 len -= cur_len;687 len -= cur_len;
688 688
689 while (len > 0) {689 while (len > 0) {
690 frag++;
691 frag_len = skb_frag_size(frag);690 frag_len = skb_frag_size(frag);
692 cur_len = min(len, frag_len);691 cur_len = min(len, frag_len);
693 __frame_add_frag(frame, skb_frag_page(frag),692 __frame_add_frag(frame, skb_frag_page(frag),
694 skb_frag_address(frag), cur_len, frag_len);693 skb_frag_address(frag), cur_len, frag_len);
695 len -= cur_len;694 len -= cur_len;
695 frag++;
696 }696 }
697}697}
698 698
@@ -914,11 +914,11 @@ void cfg80211_upload_connect_keys(struct wireless_dev *wdev) · 215 unmodified lines
914 netdev_err(dev, "failed to set key %d\n", i);914 netdev_err(dev, "failed to set key %d\n", i);
915 continue;915 continue;
916 }916 }
917 if (wdev->connect_keys->def == i)917 if (wdev->connect_keys->def == i &&
918 if (rdev_set_default_key(rdev, dev, i, true, true)) {918 rdev_set_default_key(rdev, dev, i, true, true)) {
919 netdev_err(dev, "failed to set defkey %d\n", i);919 netdev_err(dev, "failed to set defkey %d\n", i);
920 continue;920 continue;
921 }921 }
922 }922 }
923 923
924 kzfree(wdev->connect_keys);924 kzfree(wdev->connect_keys);
@@ -929,7 +929,6 @@ void cfg80211_process_wdev_events(struct wireless_dev *wdev) · 4 unmodified lines
929{929{
930 struct cfg80211_event *ev;930 struct cfg80211_event *ev;
931 unsigned long flags;931 unsigned long flags;
932 const u8 *bssid = NULL;
933 932
934 spin_lock_irqsave(&wdev->event_lock, flags);933 spin_lock_irqsave(&wdev->event_lock, flags);
935 while (!list_empty(&wdev->event_list)) {934 while (!list_empty(&wdev->event_list)) {
@@ -941,15 +940,10 @@ void cfg80211_process_wdev_events(struct wireless_dev *wdev) · 5 unmodified lines
941 wdev_lock(wdev);940 wdev_lock(wdev);
942 switch (ev->type) {941 switch (ev->type) {
943 case EVENT_CONNECT_RESULT:942 case EVENT_CONNECT_RESULT:
944 if (!is_zero_ether_addr(ev->cr.bssid))
945 bssid = ev->cr.bssid;
946 __cfg80211_connect_result(943 __cfg80211_connect_result(
947 wdev->netdev, bssid,944 wdev->netdev,
948 ev->cr.req_ie, ev->cr.req_ie_len,945 &ev->cr,
949 ev->cr.resp_ie, ev->cr.resp_ie_len,946 ev->cr.status == WLAN_STATUS_SUCCESS);
950 ev->cr.status,
951 ev->cr.status == WLAN_STATUS_SUCCESS,
952 ev->cr.bss, ev->cr.timeout_reason);
953 break;947 break;
954 case EVENT_ROAMED:948 case EVENT_ROAMED:
955 __cfg80211_roamed(wdev, ev->rm.bss, ev->rm.req_ie,949 __cfg80211_roamed(wdev, ev->rm.bss, ev->rm.req_ie,
@@ -991,7 +985,7 @@ void cfg80211_process_rdev_events(struct cfg80211_registered_device *rdev) · 35 unmodified lines
991 985
992int cfg80211_change_iface(struct cfg80211_registered_device *rdev,986int cfg80211_change_iface(struct cfg80211_registered_device *rdev,
993 struct net_device *dev, enum nl80211_iftype ntype,987 struct net_device *dev, enum nl80211_iftype ntype,
994 u32 *flags, struct vif_params *params)988 struct vif_params *params)
995{989{
996 int err;990 int err;
997 enum nl80211_iftype otype = dev->ieee80211_ptr->iftype;991 enum nl80211_iftype otype = dev->ieee80211_ptr->iftype;
@@ -1049,7 +1043,7 @@ int cfg80211_change_iface(struct cfg80211_registered_device *rdev, · 51 unmodified lines
1049 cfg80211_process_rdev_events(rdev);1043 cfg80211_process_rdev_events(rdev);
1050 }1044 }
1051 1045
1052 err = rdev_change_virtual_intf(rdev, dev, ntype, flags, params);1046 err = rdev_change_virtual_intf(rdev, dev, ntype, params);
1053 1047
1054 WARN_ON(!err && dev->ieee80211_ptr->iftype != ntype);1048 WARN_ON(!err && dev->ieee80211_ptr->iftype != ntype);
1055 1049
@@ -1097,6 +1091,35 @@ int cfg80211_change_iface(struct cfg80211_registered_device *rdev, · 41 unmodified lines
1097 return err;1091 return err;
1098}1092}
1099 1093
1094static u32 cfg80211_calculate_bitrate_ht(struct rate_info *rate)
1095{
1096 int modulation, streams, bitrate;
1097
1098 /* the formula below does only work for MCS values smaller than 32 */
1099 if (WARN_ON_ONCE(rate->mcs >= 32))
1100 return 0;
1101
1102 modulation = rate->mcs & 7;
1103 streams = (rate->mcs >> 3) + 1;
1104
1105 bitrate = (rate->bw == RATE_INFO_BW_40) ? 13500000 : 6500000;
1106
1107 if (modulation < 4)
1108 bitrate *= (modulation + 1);
1109 else if (modulation == 4)
1110 bitrate *= (modulation + 2);
1111 else
1112 bitrate *= (modulation + 3);
1113
1114 bitrate *= streams;
1115
1116 if (rate->flags & RATE_INFO_FLAGS_SHORT_GI)
1117 bitrate = (bitrate / 9) * 10;
1118
1119 /* do NOT round down here */
1120 return (bitrate + 50000) / 100000;
1121}
1122
1100static u32 cfg80211_calculate_bitrate_60g(struct rate_info *rate)1123static u32 cfg80211_calculate_bitrate_60g(struct rate_info *rate)
1101{1124{
1102 static const u32 __mcs2bitrate[] = {1125 static const u32 __mcs2bitrate[] = {
@@ -1230,39 +1253,14 @@ static u32 cfg80211_calculate_bitrate_vht(struct rate_info *rate) · 127 unmodified lines
1230 1253
1231u32 cfg80211_calculate_bitrate(struct rate_info *rate)1254u32 cfg80211_calculate_bitrate(struct rate_info *rate)
1232{1255{
1233 int modulation, streams, bitrate;1256 if (rate->flags & RATE_INFO_FLAGS_MCS)
1234 1257 return cfg80211_calculate_bitrate_ht(rate);
1235 if (!(rate->flags & RATE_INFO_FLAGS_MCS) &&
1236 !(rate->flags & RATE_INFO_FLAGS_VHT_MCS))
1237 return rate->legacy;
1238 if (rate->flags & RATE_INFO_FLAGS_60G)1258 if (rate->flags & RATE_INFO_FLAGS_60G)
1239 return cfg80211_calculate_bitrate_60g(rate);1259 return cfg80211_calculate_bitrate_60g(rate);
1240 if (rate->flags & RATE_INFO_FLAGS_VHT_MCS)1260 if (rate->flags & RATE_INFO_FLAGS_VHT_MCS)
1241 return cfg80211_calculate_bitrate_vht(rate);1261 return cfg80211_calculate_bitrate_vht(rate);
1242 1262
1243 /* the formula below does only work for MCS values smaller than 32 */1263 return rate->legacy;
1244 if (WARN_ON_ONCE(rate->mcs >= 32))
1245 return 0;
1246
1247 modulation = rate->mcs & 7;
1248 streams = (rate->mcs >> 3) + 1;
1249
1250 bitrate = (rate->bw == RATE_INFO_BW_40) ? 13500000 : 6500000;
1251
1252 if (modulation < 4)
1253 bitrate *= (modulation + 1);
1254 else if (modulation == 4)
1255 bitrate *= (modulation + 2);
1256 else
1257 bitrate *= (modulation + 3);
1258
1259 bitrate *= streams;
1260
1261 if (rate->flags & RATE_INFO_FLAGS_SHORT_GI)
1262 bitrate = (bitrate / 9) * 10;
1263
1264 /* do NOT round down here */
1265 return (bitrate + 50000) / 100000;
1266}1264}
1267EXPORT_SYMBOL(cfg80211_calculate_bitrate);1265EXPORT_SYMBOL(cfg80211_calculate_bitrate);
1268 1266
net/wireless/wext-compat.c+1−1
@@ -62,7 +62,7 @@ int cfg80211_wext_siwmode(struct net_device *dev, struct iw_request_info *info, · 61 unmodified lines
62 62
63 memset(&vifparams, 0, sizeof(vifparams));63 memset(&vifparams, 0, sizeof(vifparams));
64 64
65 return cfg80211_change_iface(rdev, dev, type, NULL, &vifparams);65 return cfg80211_change_iface(rdev, dev, type, &vifparams);
66}66}
67EXPORT_WEXT_HANDLER(cfg80211_wext_siwmode);67EXPORT_WEXT_HANDLER(cfg80211_wext_siwmode);
68 68