Merge branch 'for-john' of git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac802...
authorJohn W. Linville <linville@tuxdriver.com>
Tue, 22 Jan 2013 20:40:56 +0000 (15:40 -0500)
committerJohn W. Linville <linville@tuxdriver.com>
Tue, 22 Jan 2013 20:40:56 +0000 (15:40 -0500)
32 files changed:
drivers/net/wireless/ath/ath5k/base.c
drivers/net/wireless/ath/ath6kl/cfg80211.c
drivers/net/wireless/ath/ath9k/htc_drv_init.c
drivers/net/wireless/ath/ath9k/init.c
drivers/net/wireless/ath/carl9170/main.c
drivers/net/wireless/ath/regd.c
drivers/net/wireless/ath/regd.h
drivers/net/wireless/brcm80211/brcmsmac/channel.c
drivers/net/wireless/libertas/cfg.c
drivers/net/wireless/libertas/cfg.h
drivers/net/wireless/mwifiex/cfg80211.c
drivers/net/wireless/rtlwifi/regd.c
drivers/net/wireless/rtlwifi/regd.h
drivers/net/wireless/ti/wlcore/main.c
include/net/cfg80211.h
include/net/mac80211.h
include/uapi/linux/nl80211.h
net/mac80211/cfg.c
net/mac80211/mesh.c
net/mac80211/mesh.h
net/mac80211/mesh_plink.c
net/mac80211/mlme.c
net/mac80211/trace.h
net/mac80211/tx.c
net/mac80211/util.c
net/wireless/core.c
net/wireless/core.h
net/wireless/mesh.c
net/wireless/nl80211.c
net/wireless/reg.c
net/wireless/sme.c
net/wireless/util.c

index 30ca0a60a64c020e6b3609bff361078e03b6a89f..1d264c0f5a9b468285296e706cfef2d367678085 100644 (file)
@@ -240,13 +240,14 @@ static const struct ath_ops ath5k_common_ops = {
 * Driver Initialization *
 \***********************/
 
-static int ath5k_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request)
+static void ath5k_reg_notifier(struct wiphy *wiphy,
+                              struct regulatory_request *request)
 {
        struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
        struct ath5k_hw *ah = hw->priv;
        struct ath_regulatory *regulatory = ath5k_hw_regulatory(ah);
 
-       return ath_reg_notifier_apply(wiphy, request, regulatory);
+       ath_reg_notifier_apply(wiphy, request, regulatory);
 }
 
 /********************\
index 5516a8ccc3c6809589ff1d1fd8756859f504f7e9..4225cca0f198199a4e0b0e28ee5b4748cb85a45d 100644 (file)
@@ -3492,8 +3492,8 @@ void ath6kl_cfg80211_stop_all(struct ath6kl *ar)
                ath6kl_cfg80211_stop(vif);
 }
 
-static int ath6kl_cfg80211_reg_notify(struct wiphy *wiphy,
-                                     struct regulatory_request *request)
+static void ath6kl_cfg80211_reg_notify(struct wiphy *wiphy,
+                                      struct regulatory_request *request)
 {
        struct ath6kl *ar = wiphy_priv(wiphy);
        u32 rates[IEEE80211_NUM_BANDS];
@@ -3506,17 +3506,13 @@ static int ath6kl_cfg80211_reg_notify(struct wiphy *wiphy,
                   request->processed ? " processed" : "",
                   request->initiator, request->user_reg_hint_type);
 
-       /*
-        * As firmware is not able intersect regdoms, we can only listen to
-        * cellular hints.
-        */
        if (request->user_reg_hint_type != NL80211_USER_REG_HINT_CELL_BASE)
-               return -EOPNOTSUPP;
+               return;
 
        ret = ath6kl_wmi_set_regdomain_cmd(ar->wmi, request->alpha2);
        if (ret) {
                ath6kl_err("failed to set regdomain: %d\n", ret);
-               return ret;
+               return;
        }
 
        /*
@@ -3536,10 +3532,8 @@ static int ath6kl_cfg80211_reg_notify(struct wiphy *wiphy,
        if (ret) {
                ath6kl_err("failed to start scan for a regdomain change: %d\n",
                           ret);
-               return ret;
+               return;
        }
-
-       return 0;
 }
 
 static int ath6kl_cfg80211_vif_init(struct ath6kl_vif *vif)
index 05d5ba66cac3588f64e8f6ab0545af76fbf88cbb..e5d7958ab9485a617c60f520d2981b38b50cb7eb 100644 (file)
@@ -280,14 +280,14 @@ err:
        return ret;
 }
 
-static int ath9k_reg_notifier(struct wiphy *wiphy,
-                             struct regulatory_request *request)
+static void ath9k_reg_notifier(struct wiphy *wiphy,
+                              struct regulatory_request *request)
 {
        struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
        struct ath9k_htc_priv *priv = hw->priv;
 
-       return ath_reg_notifier_apply(wiphy, request,
-                                     ath9k_hw_regulatory(priv->ah));
+       ath_reg_notifier_apply(wiphy, request,
+                              ath9k_hw_regulatory(priv->ah));
 }
 
 static unsigned int ath9k_regread(void *hw_priv, u32 reg_offset)
index 90cfcb3983d1b683fa6cbc7e1c6e0c12c39d8863..4b1abc7da98c559fcda19845caa036c246d5b444 100644 (file)
@@ -303,16 +303,15 @@ static void setup_ht_cap(struct ath_softc *sc,
        ht_info->mcs.tx_params |= IEEE80211_HT_MCS_TX_DEFINED;
 }
 
-static int ath9k_reg_notifier(struct wiphy *wiphy,
-                             struct regulatory_request *request)
+static void ath9k_reg_notifier(struct wiphy *wiphy,
+                              struct regulatory_request *request)
 {
        struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
        struct ath_softc *sc = hw->priv;
        struct ath_hw *ah = sc->sc_ah;
        struct ath_regulatory *reg = ath9k_hw_regulatory(ah);
-       int ret;
 
-       ret = ath_reg_notifier_apply(wiphy, request, reg);
+       ath_reg_notifier_apply(wiphy, request, reg);
 
        /* Set tx power */
        if (ah->curchan) {
@@ -322,8 +321,6 @@ static int ath9k_reg_notifier(struct wiphy *wiphy,
                sc->curtxpow = ath9k_hw_regulatory(ah)->power_limit;
                ath9k_ps_restore(sc);
        }
-
-       return ret;
 }
 
 /*
index f22da264fd9352de13bd562673f36fcbb6aced13..ef82751722e0bd4ae45c50ad18e705cee755222d 100644 (file)
@@ -1981,13 +1981,13 @@ static int carl9170_parse_eeprom(struct ar9170 *ar)
        return 0;
 }
 
-static int carl9170_reg_notifier(struct wiphy *wiphy,
-                                struct regulatory_request *request)
+static void carl9170_reg_notifier(struct wiphy *wiphy,
+                                 struct regulatory_request *request)
 {
        struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
        struct ar9170 *ar = hw->priv;
 
-       return ath_reg_notifier_apply(wiphy, request, &ar->common.regulatory);
+       ath_reg_notifier_apply(wiphy, request, &ar->common.regulatory);
 }
 
 int carl9170_register(struct ar9170 *ar)
index 7a6c79e1f8199f2a6aea995b5824935689c9f704..ccc4c718f124c2a500410cc9ed16f48841e8ec29 100644 (file)
@@ -356,9 +356,9 @@ static u16 ath_regd_find_country_by_name(char *alpha2)
        return -1;
 }
 
-int ath_reg_notifier_apply(struct wiphy *wiphy,
-                          struct regulatory_request *request,
-                          struct ath_regulatory *reg)
+void ath_reg_notifier_apply(struct wiphy *wiphy,
+                           struct regulatory_request *request,
+                           struct ath_regulatory *reg)
 {
        struct ath_common *common = container_of(reg, struct ath_common,
                                                 regulatory);
@@ -373,7 +373,7 @@ int ath_reg_notifier_apply(struct wiphy *wiphy,
         * any pending requests in the queue.
         */
        if (!request)
-               return 0;
+               return;
 
        switch (request->initiator) {
        case NL80211_REGDOM_SET_BY_CORE:
@@ -409,8 +409,6 @@ int ath_reg_notifier_apply(struct wiphy *wiphy,
 
                break;
        }
-
-       return 0;
 }
 EXPORT_SYMBOL(ath_reg_notifier_apply);
 
@@ -500,8 +498,8 @@ ath_get_regpair(int regdmn)
 static int
 ath_regd_init_wiphy(struct ath_regulatory *reg,
                    struct wiphy *wiphy,
-                   int (*reg_notifier)(struct wiphy *wiphy,
-                                       struct regulatory_request *request))
+                   void (*reg_notifier)(struct wiphy *wiphy,
+                                        struct regulatory_request *request))
 {
        const struct ieee80211_regdomain *regd;
 
@@ -621,8 +619,8 @@ static int __ath_regd_init(struct ath_regulatory *reg)
 int
 ath_regd_init(struct ath_regulatory *reg,
              struct wiphy *wiphy,
-             int (*reg_notifier)(struct wiphy *wiphy,
-                                 struct regulatory_request *request))
+             void (*reg_notifier)(struct wiphy *wiphy,
+                                  struct regulatory_request *request))
 {
        struct ath_common *common = container_of(reg, struct ath_common,
                                                 regulatory);
index 03a8268ccf21a7ca9d9c8ccf9a836c7b0d402d57..37f53bd8fcb13ad1b7f850924383a4e9a297f7af 100644 (file)
@@ -252,12 +252,12 @@ enum CountryCode {
 bool ath_is_world_regd(struct ath_regulatory *reg);
 bool ath_is_49ghz_allowed(u16 redomain);
 int ath_regd_init(struct ath_regulatory *reg, struct wiphy *wiphy,
-                 int (*reg_notifier)(struct wiphy *wiphy,
-                 struct regulatory_request *request));
+                 void (*reg_notifier)(struct wiphy *wiphy,
+                                      struct regulatory_request *request));
 u32 ath_regd_get_band_ctl(struct ath_regulatory *reg,
                          enum ieee80211_band band);
-int ath_reg_notifier_apply(struct wiphy *wiphy,
-                          struct regulatory_request *request,
-                          struct ath_regulatory *reg);
+void ath_reg_notifier_apply(struct wiphy *wiphy,
+                           struct regulatory_request *request,
+                           struct ath_regulatory *reg);
 
 #endif
index 4eb3f0d5210531596657696f231b5d68783dcfd1..cdb62b8ccc79c6c6ad6ea68269d3f03008d6e3e3 100644 (file)
@@ -702,8 +702,8 @@ brcms_reg_apply_beaconing_flags(struct wiphy *wiphy,
        }
 }
 
-static int brcms_reg_notifier(struct wiphy *wiphy,
-                             struct regulatory_request *request)
+static void brcms_reg_notifier(struct wiphy *wiphy,
+                              struct regulatory_request *request)
 {
        struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
        struct brcms_info *wl = hw->priv;
@@ -744,8 +744,6 @@ static int brcms_reg_notifier(struct wiphy *wiphy,
        if (wlc->pub->_nbands > 1 || wlc->band->bandtype == BRCM_BAND_2G)
                wlc_phy_chanspec_ch14_widefilter_set(wlc->band->pi,
                                        brcms_c_japan_ccode(request->alpha2));
-
-       return 0;
 }
 
 void brcms_c_regd_init(struct brcms_c_info *wlc)
index ec6d5d6b452e7aebf8b8d782460e7b0263c121a0..230f8ebbe28921f6786e250b4f88cb421c013385 100644 (file)
@@ -2132,6 +2132,21 @@ static void lbs_cfg_set_regulatory_hint(struct lbs_private *priv)
        lbs_deb_leave(LBS_DEB_CFG80211);
 }
 
+static void lbs_reg_notifier(struct wiphy *wiphy,
+                            struct regulatory_request *request)
+{
+       struct lbs_private *priv = wiphy_priv(wiphy);
+
+       lbs_deb_enter_args(LBS_DEB_CFG80211, "cfg80211 regulatory domain "
+                       "callback for domain %c%c\n", request->alpha2[0],
+                       request->alpha2[1]);
+
+       memcpy(priv->country_code, request->alpha2, sizeof(request->alpha2));
+       if (lbs_iface_active(priv))
+               lbs_set_11d_domain_info(priv);
+
+       lbs_deb_leave(LBS_DEB_CFG80211);
+}
 
 /*
  * This function get's called after lbs_setup_firmware() determined the
@@ -2184,24 +2199,6 @@ int lbs_cfg_register(struct lbs_private *priv)
        return ret;
 }
 
-int lbs_reg_notifier(struct wiphy *wiphy,
-               struct regulatory_request *request)
-{
-       struct lbs_private *priv = wiphy_priv(wiphy);
-       int ret = 0;
-
-       lbs_deb_enter_args(LBS_DEB_CFG80211, "cfg80211 regulatory domain "
-                       "callback for domain %c%c\n", request->alpha2[0],
-                       request->alpha2[1]);
-
-       memcpy(priv->country_code, request->alpha2, sizeof(request->alpha2));
-       if (lbs_iface_active(priv))
-               ret = lbs_set_11d_domain_info(priv);
-
-       lbs_deb_leave(LBS_DEB_CFG80211);
-       return ret;
-}
-
 void lbs_scan_deinit(struct lbs_private *priv)
 {
        lbs_deb_enter(LBS_DEB_CFG80211);
index 558168ce634d519d67201d92c1992163550f4b4b..10995f59fe34a1796db45e914196fc7a03248c07 100644 (file)
@@ -10,9 +10,6 @@ struct wireless_dev *lbs_cfg_alloc(struct device *dev);
 int lbs_cfg_register(struct lbs_private *priv);
 void lbs_cfg_free(struct lbs_private *priv);
 
-int lbs_reg_notifier(struct wiphy *wiphy,
-               struct regulatory_request *request);
-
 void lbs_send_disconnect_notification(struct lbs_private *priv);
 void lbs_send_mic_failureevent(struct lbs_private *priv, u32 event);
 
index c4edb28cce083686d7f9b4aeabeb810e9d680fc0..dc0c2ddd5d4817c23a068a8147d59669f21cb3e8 100644 (file)
@@ -519,8 +519,8 @@ static int mwifiex_send_domain_info_cmd_fw(struct wiphy *wiphy)
  *      - Set by user
  *      - Set bt Country IE
  */
-static int mwifiex_reg_notifier(struct wiphy *wiphy,
-                               struct regulatory_request *request)
+static void mwifiex_reg_notifier(struct wiphy *wiphy,
+                                struct regulatory_request *request)
 {
        struct mwifiex_adapter *adapter = mwifiex_cfg80211_get_adapter(wiphy);
 
@@ -540,8 +540,6 @@ static int mwifiex_reg_notifier(struct wiphy *wiphy,
                break;
        }
        mwifiex_send_domain_info_cmd_fw(wiphy);
-
-       return 0;
 }
 
 /*
index 7e3ead774fb907c90b2f36dfc472f8e094c10c0d..d7d0d4948b01f2e804e6bcddfca93b10c7cdb312 100644 (file)
@@ -298,9 +298,9 @@ static void _rtl_reg_apply_world_flags(struct wiphy *wiphy,
        return;
 }
 
-static int _rtl_reg_notifier_apply(struct wiphy *wiphy,
-                                  struct regulatory_request *request,
-                                  struct rtl_regulatory *reg)
+static void _rtl_reg_notifier_apply(struct wiphy *wiphy,
+                                   struct regulatory_request *request,
+                                   struct rtl_regulatory *reg)
 {
        /* We always apply this */
        _rtl_reg_apply_radar_flags(wiphy);
@@ -314,8 +314,6 @@ static int _rtl_reg_notifier_apply(struct wiphy *wiphy,
                _rtl_reg_apply_world_flags(wiphy, request->initiator, reg);
                break;
        }
-
-       return 0;
 }
 
 static const struct ieee80211_regdomain *_rtl_regdomain_select(
@@ -348,9 +346,9 @@ static const struct ieee80211_regdomain *_rtl_regdomain_select(
 
 static int _rtl_regd_init_wiphy(struct rtl_regulatory *reg,
                                struct wiphy *wiphy,
-                               int (*reg_notifier) (struct wiphy *wiphy,
-                                                    struct regulatory_request *
-                                                    request))
+                               void (*reg_notifier) (struct wiphy *wiphy,
+                                                     struct regulatory_request *
+                                                     request))
 {
        const struct ieee80211_regdomain *regd;
 
@@ -379,7 +377,7 @@ static struct country_code_to_enum_rd *_rtl_regd_find_country(u16 countrycode)
 }
 
 int rtl_regd_init(struct ieee80211_hw *hw,
-                 int (*reg_notifier) (struct wiphy *wiphy,
+                 void (*reg_notifier) (struct wiphy *wiphy,
                                       struct regulatory_request *request))
 {
        struct rtl_priv *rtlpriv = rtl_priv(hw);
@@ -421,12 +419,12 @@ int rtl_regd_init(struct ieee80211_hw *hw,
        return 0;
 }
 
-int rtl_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request)
+void rtl_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request)
 {
        struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
        struct rtl_priv *rtlpriv = rtl_priv(hw);
 
        RT_TRACE(rtlpriv, COMP_REGD, DBG_LOUD, "\n");
 
-       return _rtl_reg_notifier_apply(wiphy, request, &rtlpriv->regd);
+       _rtl_reg_notifier_apply(wiphy, request, &rtlpriv->regd);
 }
index 70ef2f418a44134d1fd1d810afd5f4ace4705151..4e1f4f00e6e9633ed30c59ca2220039e733fdb39 100644 (file)
@@ -55,7 +55,7 @@ enum country_code_type_t {
 };
 
 int rtl_regd_init(struct ieee80211_hw *hw,
-                 int (*reg_notifier) (struct wiphy *wiphy,
-                                      struct regulatory_request *request));
-int rtl_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request);
+                 void (*reg_notifier) (struct wiphy *wiphy,
+                                       struct regulatory_request *request));
+void rtl_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request);
 #endif
index d7de06359ae1f71478bdbf47ba5b9140c9083eb3..ce6e62a37e1433341d3bb2c9a5ccb2c6d2cde7d4 100644 (file)
@@ -89,8 +89,8 @@ static int wl12xx_set_authorized(struct wl1271 *wl,
        return 0;
 }
 
-static int wl1271_reg_notify(struct wiphy *wiphy,
-                            struct regulatory_request *request)
+static void wl1271_reg_notify(struct wiphy *wiphy,
+                             struct regulatory_request *request)
 {
        struct ieee80211_supported_band *band;
        struct ieee80211_channel *ch;
@@ -107,8 +107,6 @@ static int wl1271_reg_notify(struct wiphy *wiphy,
                                     IEEE80211_CHAN_PASSIVE_SCAN;
 
        }
-
-       return 0;
 }
 
 static int wl1271_set_rx_streaming(struct wl1271 *wl, struct wl12xx_vif *wlvif,
index e5f085c8922116b16019eb1d03cd4d9e0ec67ba3..970da442067615ab49526397ef559c0ec5c740ea 100644 (file)
@@ -281,9 +281,13 @@ struct ieee80211_supported_band {
 /**
  * struct vif_params - describes virtual interface parameters
  * @use_4addr: use 4-address frames
+ * @macaddr: address to use for this virtual interface. This will only
+ *     be used for non-netdevice interfaces. If this parameter is set
+ *     to zero address the driver may determine the address as needed.
  */
 struct vif_params {
        int use_4addr;
+       u8 macaddr[ETH_ALEN];
 };
 
 /**
@@ -326,7 +330,7 @@ struct cfg80211_chan_def {
  * cfg80211_get_chandef_type - return old channel type from chandef
  * @chandef: the channel definition
  *
- * Returns the old channel type (NOHT, HT20, HT40+/-) from a given
+ * Return: The old channel type (NOHT, HT20, HT40+/-) from a given
  * chandef, which must have a bandwidth allowing this conversion.
  */
 static inline enum nl80211_channel_type
@@ -364,7 +368,7 @@ void cfg80211_chandef_create(struct cfg80211_chan_def *chandef,
  * @chandef1: first channel definition
  * @chandef2: second channel definition
  *
- * Returns %true if the channels defined by the channel definitions are
+ * Return: %true if the channels defined by the channel definitions are
  * identical, %false otherwise.
  */
 static inline bool
@@ -382,7 +386,7 @@ cfg80211_chandef_identical(const struct cfg80211_chan_def *chandef1,
  * @chandef1: first channel definition
  * @chandef2: second channel definition
  *
- * Returns %NULL if the given channel definitions are incompatible,
+ * Return: %NULL if the given channel definitions are incompatible,
  * chandef1 or chandef2 otherwise.
  */
 const struct cfg80211_chan_def *
@@ -392,6 +396,7 @@ cfg80211_chandef_compatible(const struct cfg80211_chan_def *chandef1,
 /**
  * cfg80211_chandef_valid - check if a channel definition is valid
  * @chandef: the channel definition to check
+ * Return: %true if the channel definition is valid. %false otherwise.
  */
 bool cfg80211_chandef_valid(const struct cfg80211_chan_def *chandef);
 
@@ -399,7 +404,8 @@ bool cfg80211_chandef_valid(const struct cfg80211_chan_def *chandef);
  * cfg80211_chandef_usable - check if secondary channels can be used
  * @wiphy: the wiphy to validate against
  * @chandef: the channel definition to check
- * @prohibited_flags: the regulatory chanenl flags that must not be set
+ * @prohibited_flags: the regulatory channel flags that must not be set
+ * Return: %true if secondary channels are usable. %false otherwise.
  */
 bool cfg80211_chandef_usable(struct wiphy *wiphy,
                             const struct cfg80211_chan_def *chandef,
@@ -608,6 +614,8 @@ enum station_parameters_apply_mask {
  * @sta_modify_mask: bitmap indicating which parameters changed
  *     (for those that don't have a natural "no change" value),
  *     see &enum station_parameters_apply_mask
+ * @local_pm: local link-specific mesh power save mode (no change when set
+ *     to unknown)
  */
 struct station_parameters {
        u8 *supported_rates;
@@ -623,6 +631,7 @@ struct station_parameters {
        struct ieee80211_vht_cap *vht_capa;
        u8 uapsd_queues;
        u8 max_sp;
+       enum nl80211_mesh_power_mode local_pm;
 };
 
 /**
@@ -653,6 +662,9 @@ struct station_parameters {
  * @STATION_INFO_STA_FLAGS: @sta_flags filled
  * @STATION_INFO_BEACON_LOSS_COUNT: @beacon_loss_count filled
  * @STATION_INFO_T_OFFSET: @t_offset filled
+ * @STATION_INFO_LOCAL_PM: @local_pm filled
+ * @STATION_INFO_PEER_PM: @peer_pm filled
+ * @STATION_INFO_NONPEER_PM: @nonpeer_pm filled
  */
 enum station_info_flags {
        STATION_INFO_INACTIVE_TIME      = 1<<0,
@@ -676,6 +688,9 @@ enum station_info_flags {
        STATION_INFO_STA_FLAGS          = 1<<18,
        STATION_INFO_BEACON_LOSS_COUNT  = 1<<19,
        STATION_INFO_T_OFFSET           = 1<<20,
+       STATION_INFO_LOCAL_PM           = 1<<21,
+       STATION_INFO_PEER_PM            = 1<<22,
+       STATION_INFO_NONPEER_PM         = 1<<23,
 };
 
 /**
@@ -789,6 +804,9 @@ struct sta_bss_parameters {
  * @sta_flags: station flags mask & values
  * @beacon_loss_count: Number of times beacon loss event has triggered.
  * @t_offset: Time offset of the station relative to this host.
+ * @local_pm: local mesh STA power save mode
+ * @peer_pm: peer mesh STA power save mode
+ * @nonpeer_pm: non-peer mesh STA power save mode
  */
 struct station_info {
        u32 filled;
@@ -818,6 +836,9 @@ struct station_info {
 
        u32 beacon_loss_count;
        s64 t_offset;
+       enum nl80211_mesh_power_mode local_pm;
+       enum nl80211_mesh_power_mode peer_pm;
+       enum nl80211_mesh_power_mode nonpeer_pm;
 
        /*
         * Note: Add a new enum station_info_flags value for each new field and
@@ -993,6 +1014,10 @@ struct bss_parameters {
  * @dot11MeshHWMPconfirmationInterval: The minimum interval of time (in TUs)
  *     during which a mesh STA can send only one Action frame containing
  *     a PREQ element for root path confirmation.
+ * @power_mode: The default mesh power save mode which will be the initial
+ *     setting for new peer links.
+ * @dot11MeshAwakeWindowDuration: The duration in TUs the STA will remain awake
+ *     after transmitting its beacon.
  */
 struct mesh_config {
        u16 dot11MeshRetryTimeout;
@@ -1020,6 +1045,8 @@ struct mesh_config {
        u32 dot11MeshHWMPactivePathToRootTimeout;
        u16 dot11MeshHWMProotInterval;
        u16 dot11MeshHWMPconfirmationInterval;
+       enum nl80211_mesh_power_mode power_mode;
+       u16 dot11MeshAwakeWindowDuration;
 };
 
 /**
@@ -1034,6 +1061,8 @@ struct mesh_config {
  * @ie_len: length of vendor information elements
  * @is_authenticated: this mesh requires authentication
  * @is_secure: this mesh uses security
+ * @dtim_period: DTIM period to use
+ * @beacon_interval: beacon interval to use
  * @mcast_rate: multicat rate for Mesh Node [6Mbps is the default for 802.11a]
  *
  * These parameters are fixed when the mesh is created.
@@ -1049,6 +1078,8 @@ struct mesh_setup {
        u8 ie_len;
        bool is_authenticated;
        bool is_secure;
+       u8 dtim_period;
+       u16 beacon_interval;
        int mcast_rate[IEEE80211_NUM_BANDS];
 };
 
@@ -1266,7 +1297,7 @@ struct cfg80211_bss {
  *
  * Note that the return value is an RCU-protected pointer, so
  * rcu_read_lock() must be held when calling this function.
- * Returns %NULL if not found.
+ * Return: %NULL if not found.
  */
 const u8 *ieee80211_bss_get_ie(struct cfg80211_bss *bss, u8 ie);
 
@@ -1434,6 +1465,7 @@ struct cfg80211_ibss_params {
  * @ie: IEs for association request
  * @ie_len: Length of assoc_ie in octets
  * @privacy: indicates whether privacy-enabled APs should be used
+ * @mfp: indicate whether management frame protection is used
  * @crypto: crypto settings
  * @key_len: length of WEP key for shared key authentication
  * @key_idx: index of WEP key for shared key authentication
@@ -1454,6 +1486,7 @@ struct cfg80211_connect_params {
        u8 *ie;
        size_t ie_len;
        bool privacy;
+       enum nl80211_mfp mfp;
        struct cfg80211_crypto_settings crypto;
        const u8 *key;
        u8 key_len, key_idx;
@@ -2092,6 +2125,7 @@ struct ieee80211_iface_limit {
  * @beacon_int_infra_match: In this combination, the beacon intervals
  *     between infrastructure and AP types must match. This is required
  *     only in special cases.
+ * @radar_detect_widths: bitmap of channel widths supported for radar detection
  *
  * These examples can be expressed as follows:
  *
@@ -2144,6 +2178,7 @@ struct ieee80211_iface_combination {
        u16 max_interfaces;
        u8 n_limits;
        bool beacon_int_infra_match;
+       u8 radar_detect_widths;
 };
 
 struct mac_address {
@@ -2364,8 +2399,8 @@ struct wiphy {
        struct ieee80211_supported_band *bands[IEEE80211_NUM_BANDS];
 
        /* Lets us get back the wiphy on the callback */
-       int (*reg_notifier)(struct wiphy *wiphy,
-                           struct regulatory_request *request);
+       void (*reg_notifier)(struct wiphy *wiphy,
+                            struct regulatory_request *request);
 
        /* fields below are read-only, assigned by cfg80211 */
 
@@ -2409,6 +2444,7 @@ static inline void wiphy_net_set(struct wiphy *wiphy, struct net *net)
  * wiphy_priv - return priv from wiphy
  *
  * @wiphy: the wiphy whose priv pointer to return
+ * Return: The priv of @wiphy.
  */
 static inline void *wiphy_priv(struct wiphy *wiphy)
 {
@@ -2420,6 +2456,7 @@ static inline void *wiphy_priv(struct wiphy *wiphy)
  * priv_to_wiphy - return the wiphy containing the priv
  *
  * @priv: a pointer previously returned by wiphy_priv
+ * Return: The wiphy of @priv.
  */
 static inline struct wiphy *priv_to_wiphy(void *priv)
 {
@@ -2442,6 +2479,7 @@ static inline void set_wiphy_dev(struct wiphy *wiphy, struct device *dev)
  * wiphy_dev - get wiphy dev pointer
  *
  * @wiphy: The wiphy whose device struct to look up
+ * Return: The dev of @wiphy.
  */
 static inline struct device *wiphy_dev(struct wiphy *wiphy)
 {
@@ -2452,6 +2490,7 @@ static inline struct device *wiphy_dev(struct wiphy *wiphy)
  * wiphy_name - get wiphy name
  *
  * @wiphy: The wiphy whose name to return
+ * Return: The name of @wiphy.
  */
 static inline const char *wiphy_name(const struct wiphy *wiphy)
 {
@@ -2467,8 +2506,8 @@ static inline const char *wiphy_name(const struct wiphy *wiphy)
  * Create a new wiphy and associate the given operations with it.
  * @sizeof_priv bytes are allocated for private use.
  *
- * The returned pointer must be assigned to each netdev's
- * ieee80211_ptr for proper operation.
+ * Return: A pointer to the new wiphy. This pointer must be
+ * assigned to each netdev's ieee80211_ptr for proper operation.
  */
 struct wiphy *wiphy_new(const struct cfg80211_ops *ops, int sizeof_priv);
 
@@ -2477,7 +2516,7 @@ struct wiphy *wiphy_new(const struct cfg80211_ops *ops, int sizeof_priv);
  *
  * @wiphy: The wiphy to register.
  *
- * Returns a non-negative wiphy index or a negative error code.
+ * Return: A non-negative wiphy index or a negative error code.
  */
 extern int wiphy_register(struct wiphy *wiphy);
 
@@ -2626,6 +2665,7 @@ static inline u8 *wdev_address(struct wireless_dev *wdev)
  * wdev_priv - return wiphy priv from wireless_dev
  *
  * @wdev: The wireless device whose wiphy's priv pointer to return
+ * Return: The wiphy priv of @wdev.
  */
 static inline void *wdev_priv(struct wireless_dev *wdev)
 {
@@ -2643,12 +2683,14 @@ static inline void *wdev_priv(struct wireless_dev *wdev)
  * ieee80211_channel_to_frequency - convert channel number to frequency
  * @chan: channel number
  * @band: band, necessary due to channel number overlap
+ * Return: The corresponding frequency (in MHz), or 0 if the conversion failed.
  */
 extern int ieee80211_channel_to_frequency(int chan, enum ieee80211_band band);
 
 /**
  * ieee80211_frequency_to_channel - convert frequency to channel number
  * @freq: center frequency
+ * Return: The corresponding channel, or 0 if the conversion failed.
  */
 extern int ieee80211_frequency_to_channel(int freq);
 
@@ -2665,6 +2707,7 @@ extern struct ieee80211_channel *__ieee80211_get_channel(struct wiphy *wiphy,
  * ieee80211_get_channel - get channel struct from wiphy for specified frequency
  * @wiphy: the struct wiphy to get the channel for
  * @freq: the center frequency of the channel
+ * Return: The channel struct from @wiphy at @freq.
  */
 static inline struct ieee80211_channel *
 ieee80211_get_channel(struct wiphy *wiphy, int freq)
@@ -2679,10 +2722,10 @@ ieee80211_get_channel(struct wiphy *wiphy, int freq)
  * @basic_rates: bitmap of basic rates
  * @bitrate: the bitrate for which to find the basic rate
  *
- * This function returns the basic rate corresponding to a given
- * bitrate, that is the next lower bitrate contained in the basic
- * rate map, which is, for this function, given as a bitmap of
- * indices of rates in the band's bitrate table.
+ * Return: The basic rate corresponding to a given bitrate, that
+ * is the next lower bitrate contained in the basic rate map,
+ * which is, for this function, given as a bitmap of indices of
+ * rates in the band's bitrate table.
  */
 struct ieee80211_rate *
 ieee80211_get_response_rate(struct ieee80211_supported_band *sband,
@@ -2775,18 +2818,21 @@ extern const unsigned char bridge_tunnel_header[6];
 /**
  * ieee80211_get_hdrlen_from_skb - get header length from data
  *
+ * @skb: the frame
+ *
  * Given an skb with a raw 802.11 header at the data pointer this function
- * returns the 802.11 header length in bytes (not including encryption
- * headers). If the data in the sk_buff is too short to contain a valid 802.11
- * header the function returns 0.
+ * returns the 802.11 header length.
  *
- * @skb: the frame
+ * Return: The 802.11 header length in bytes (not including encryption
+ * headers). Or 0 if the data in the sk_buff is too short to contain a valid
+ * 802.11 header.
  */
 unsigned int ieee80211_get_hdrlen_from_skb(const struct sk_buff *skb);
 
 /**
  * ieee80211_hdrlen - get header length in bytes from frame control
  * @fc: frame control field in little-endian format
+ * Return: The header length in bytes.
  */
 unsigned int __attribute_const__ ieee80211_hdrlen(__le16 fc);
 
@@ -2794,7 +2840,7 @@ unsigned int __attribute_const__ ieee80211_hdrlen(__le16 fc);
  * ieee80211_get_mesh_hdrlen - get mesh extension header length
  * @meshhdr: the mesh extension header, only the flags field
  *     (first byte) will be accessed
- * Returns the length of the extension header, which is always at
+ * Return: The length of the extension header, which is always at
  * least 6 bytes and at most 18 if address 5 and 6 are present.
  */
 unsigned int ieee80211_get_mesh_hdrlen(struct ieee80211s_hdr *meshhdr);
@@ -2812,6 +2858,7 @@ unsigned int ieee80211_get_mesh_hdrlen(struct ieee80211s_hdr *meshhdr);
  * @skb: the 802.11 data frame
  * @addr: the device MAC address
  * @iftype: the virtual interface type
+ * Return: 0 on success. Non-zero on error.
  */
 int ieee80211_data_to_8023(struct sk_buff *skb, const u8 *addr,
                           enum nl80211_iftype iftype);
@@ -2823,6 +2870,7 @@ int ieee80211_data_to_8023(struct sk_buff *skb, const u8 *addr,
  * @iftype: the virtual interface type
  * @bssid: the network bssid (used only for iftype STATION and ADHOC)
  * @qos: build 802.11 QoS data frame
+ * Return: 0 on success, or a negative error code.
  */
 int ieee80211_data_from_8023(struct sk_buff *skb, const u8 *addr,
                             enum nl80211_iftype iftype, u8 *bssid, bool qos);
@@ -2850,6 +2898,7 @@ void ieee80211_amsdu_to_8023s(struct sk_buff *skb, struct sk_buff_head *list,
 /**
  * cfg80211_classify8021d - determine the 802.1p/1d tag for a data frame
  * @skb: the data frame
+ * Return: The 802.1p/1d tag.
  */
 unsigned int cfg80211_classify8021d(struct sk_buff *skb);
 
@@ -2860,12 +2909,13 @@ unsigned int cfg80211_classify8021d(struct sk_buff *skb);
  * @ies: data consisting of IEs
  * @len: length of data
  *
- * This function will return %NULL if the element ID could
- * not be found or if the element is invalid (claims to be
- * longer than the given data), or a pointer to the first byte
- * of the requested element, that is the byte containing the
- * element ID. There are no checks on the element length
- * other than having to fit into the given data.
+ * Return: %NULL if the element ID could not be found or if
+ * the element is invalid (claims to be longer than the given
+ * data), or a pointer to the first byte of the requested
+ * element, that is the byte containing the element ID.
+ *
+ * Note: There are no checks on the element length other than
+ * having to fit into the given data.
  */
 const u8 *cfg80211_find_ie(u8 eid, const u8 *ies, int len);
 
@@ -2877,12 +2927,13 @@ const u8 *cfg80211_find_ie(u8 eid, const u8 *ies, int len);
  * @ies: data consisting of IEs
  * @len: length of data
  *
- * This function will return %NULL if the vendor specific element ID
- * could not be found or if the element is invalid (claims to be
- * longer than the given data), or a pointer to the first byte
- * of the requested element, that is the byte containing the
- * element ID. There are no checks on the element length
- * other than having to fit into the given data.
+ * Return: %NULL if the vendor specific element ID could not be found or if the
+ * element is invalid (claims to be longer than the given data), or a pointer to
+ * the first byte of the requested element, that is the byte containing the
+ * element ID.
+ *
+ * Note: There are no checks on the element length other than having to fit into
+ * the given data.
  */
 const u8 *cfg80211_find_vendor_ie(unsigned int oui, u8 oui_type,
                                  const u8 *ies, int len);
@@ -2915,6 +2966,8 @@ const u8 *cfg80211_find_vendor_ie(unsigned int oui, u8 oui_type,
  *
  * Drivers should check the return value, its possible you can get
  * an -ENOMEM.
+ *
+ * Return: 0 on success. -ENOMEM.
  */
 extern int regulatory_hint(struct wiphy *wiphy, const char *alpha2);
 
@@ -2944,13 +2997,13 @@ extern void wiphy_apply_custom_regulatory(
  * it wants to follow we respect that unless a country IE has been received
  * and processed already.
  *
- * When an error occurs, for example if no rule can be found, the return value
- * is encoded using ERR_PTR(). Use IS_ERR() to check and PTR_ERR() to obtain
- * the numeric return value. The numeric return value will be -ERANGE if we
- * determine the given center_freq does not even have a regulatory rule for a
- * frequency range in the center_freq's band. See freq_in_rule_band() for our
- * current definition of a band -- this is purely subjective and right now it's
- * 802.11 specific.
+ * Return: A valid pointer, or, when an error occurs, for example if no rule
+ * can be found, the return value is encoded using ERR_PTR(). Use IS_ERR() to
+ * check and PTR_ERR() to obtain the numeric return value. The numeric return
+ * value will be -ERANGE if we determine the given center_freq does not even
+ * have a regulatory rule for a frequency range in the center_freq's band.
+ * See freq_in_rule_band() for our current definition of a band -- this is
+ * purely subjective and right now it's 802.11 specific.
  */
 const struct ieee80211_reg_rule *freq_reg_info(struct wiphy *wiphy,
                                               u32 center_freq);
@@ -3000,7 +3053,8 @@ void cfg80211_sched_scan_stopped(struct wiphy *wiphy);
  * This informs cfg80211 that BSS information was found and
  * the BSS should be updated/added.
  *
- * NOTE: Returns a referenced struct, must be released with cfg80211_put_bss()!
+ * Return: A referenced struct, must be released with cfg80211_put_bss()!
+ * Or %NULL on error.
  */
 struct cfg80211_bss * __must_check
 cfg80211_inform_bss_frame(struct wiphy *wiphy,
@@ -3025,7 +3079,8 @@ cfg80211_inform_bss_frame(struct wiphy *wiphy,
  * This informs cfg80211 that BSS information was found and
  * the BSS should be updated/added.
  *
- * NOTE: Returns a referenced struct, must be released with cfg80211_put_bss()!
+ * Return: A referenced struct, must be released with cfg80211_put_bss()!
+ * Or %NULL on error.
  */
 struct cfg80211_bss * __must_check
 cfg80211_inform_bss(struct wiphy *wiphy,
@@ -3302,16 +3357,18 @@ void wiphy_rfkill_stop_polling(struct wiphy *wiphy);
  * the testmode command. Since it is intended for a reply, calling
  * it outside of the @testmode_cmd operation is invalid.
  *
- * The returned skb (or %NULL if any errors happen) is pre-filled
- * with the wiphy index and set up in a way that any data that is
- * put into the skb (with skb_put(), nla_put() or similar) will end
- * up being within the %NL80211_ATTR_TESTDATA attribute, so all that
- * needs to be done with the skb is adding data for the corresponding
- * userspace tool which can then read that data out of the testdata
- * attribute. You must not modify the skb in any other way.
+ * The returned skb is pre-filled with the wiphy index and set up in
+ * a way that any data that is put into the skb (with skb_put(),
+ * nla_put() or similar) will end up being within the
+ * %NL80211_ATTR_TESTDATA attribute, so all that needs to be done
+ * with the skb is adding data for the corresponding userspace tool
+ * which can then read that data out of the testdata attribute. You
+ * must not modify the skb in any other way.
  *
  * When done, call cfg80211_testmode_reply() with the skb and return
  * its error code as the result of the @testmode_cmd operation.
+ *
+ * Return: An allocated and pre-filled skb. %NULL if any errors happen.
  */
 struct sk_buff *cfg80211_testmode_alloc_reply_skb(struct wiphy *wiphy,
                                                  int approxlen);
@@ -3321,11 +3378,12 @@ struct sk_buff *cfg80211_testmode_alloc_reply_skb(struct wiphy *wiphy,
  * @skb: The skb, must have been allocated with
  *     cfg80211_testmode_alloc_reply_skb()
  *
- * Returns an error code or 0 on success, since calling this
- * function will usually be the last thing before returning
- * from the @testmode_cmd you should return the error code.
- * Note that this function consumes the skb regardless of the
- * return value.
+ * Since calling this function will usually be the last thing
+ * before returning from the @testmode_cmd you should return
+ * the error code.  Note that this function consumes the skb
+ * regardless of the return value.
+ *
+ * Return: An error code or 0 on success.
  */
 int cfg80211_testmode_reply(struct sk_buff *skb);
 
@@ -3339,14 +3397,16 @@ int cfg80211_testmode_reply(struct sk_buff *skb);
  * This function allocates and pre-fills an skb for an event on the
  * testmode multicast group.
  *
- * The returned skb (or %NULL if any errors happen) is set up in the
- * same way as with cfg80211_testmode_alloc_reply_skb() but prepared
- * for an event. As there, you should simply add data to it that will
- * then end up in the %NL80211_ATTR_TESTDATA attribute. Again, you must
- * not modify the skb in any other way.
+ * The returned skb is set up in the same way as with
+ * cfg80211_testmode_alloc_reply_skb() but prepared for an event. As
+ * there, you should simply add data to it that will then end up in the
+ * %NL80211_ATTR_TESTDATA attribute. Again, you must not modify the skb
+ * in any other way.
  *
  * When done filling the skb, call cfg80211_testmode_event() with the
  * skb to send the event.
+ *
+ * Return: An allocated and pre-filled skb. %NULL if any errors happen.
  */
 struct sk_buff *cfg80211_testmode_alloc_event_skb(struct wiphy *wiphy,
                                                  int approxlen, gfp_t gfp);
@@ -3527,13 +3587,13 @@ void cfg80211_conn_failed(struct net_device *dev, const u8 *mac_addr,
  * @len: length of the frame data
  * @gfp: context flags
  *
- * Returns %true if a user space application has registered for this frame.
+ * This function is called whenever an Action frame is received for a station
+ * mode interface, but is not processed in kernel.
+ *
+ * Return: %true if a user space application has registered for this frame.
  * For action frames, that makes it responsible for rejecting unrecognized
  * action frames; %false otherwise, in which case for action frames the
  * driver is responsible for rejecting the frame.
- *
- * This function is called whenever an Action frame is received for a station
- * mode interface, but is not processed in kernel.
  */
 bool cfg80211_rx_mgmt(struct wireless_dev *wdev, int freq, int sig_dbm,
                      const u8 *buf, size_t len, gfp_t gfp);
@@ -3625,7 +3685,7 @@ void cfg80211_pmksa_candidate_notify(struct net_device *dev, int index,
  * This function is used in AP mode (only!) to inform userspace that
  * a spurious class 3 frame was received, to be able to deauth the
  * sender.
- * Returns %true if the frame was passed to userspace (or this failed
+ * Return: %true if the frame was passed to userspace (or this failed
  * for a reason other than not having a subscription.)
  */
 bool cfg80211_rx_spurious_frame(struct net_device *dev,
@@ -3641,7 +3701,7 @@ bool cfg80211_rx_spurious_frame(struct net_device *dev,
  * an associated station sent a 4addr frame but that wasn't expected.
  * It is allowed and desirable to send this event only once for each
  * station to avoid event flooding.
- * Returns %true if the frame was passed to userspace (or this failed
+ * Return: %true if the frame was passed to userspace (or this failed
  * for a reason other than not having a subscription.)
  */
 bool cfg80211_rx_unexpected_4addr_frame(struct net_device *dev,
@@ -3679,8 +3739,8 @@ void cfg80211_report_obss_beacon(struct wiphy *wiphy,
  * @wiphy: the wiphy
  * @chandef: the channel definition
  *
- * This function returns true if there is no secondary channel or the secondary
- * channel(s) can be used for beaconing (i.e. is not a radar channel etc.)
+ * Return: %true if there is no secondary channel or the secondary channel(s)
+ * can be used for beaconing (i.e. is not a radar channel etc.)
  */
 bool cfg80211_reg_can_beacon(struct wiphy *wiphy,
                             struct cfg80211_chan_def *chandef);
@@ -3750,9 +3810,9 @@ void cfg80211_unregister_wdev(struct wireless_dev *wdev);
  * The function finds a given P2P attribute in the (vendor) IEs and
  * copies its contents to the given buffer.
  *
- * The return value is a negative error code (-%EILSEQ or -%ENOENT) if
- * the data is malformed or the attribute can't be found (respectively),
- * or the length of the found attribute (which can be zero).
+ * Return: A negative error code (-%EILSEQ or -%ENOENT) if the data is
+ * malformed or the attribute can't be found (respectively), or the
+ * length of the found attribute (which can be zero).
  */
 int cfg80211_get_p2p_attr(const u8 *ies, unsigned int len,
                          enum ieee80211_p2p_attr_id attr,
index 23daed3c78edc48b03be38e8f06de6735172078e..3037f49e51c89fad2f9b5ae64679a3913912ddba 100644 (file)
@@ -1522,6 +1522,8 @@ struct ieee80211_hw {
  * structure can then access it via hw->priv. Note that mac802111 drivers should
  * not use wiphy_priv() to try to get their private driver structure as this
  * is already used internally by mac80211.
+ *
+ * Return: The mac80211 driver hw struct of @wiphy.
  */
 struct ieee80211_hw *wiphy_to_ieee80211_hw(struct wiphy *wiphy);
 
@@ -2486,7 +2488,10 @@ enum ieee80211_rate_control_changed {
  *
  * @restart_complete: Called after a call to ieee80211_restart_hw(), when the
  *     reconfiguration has completed. This can help the driver implement the
- *     reconfiguration step. This callback may sleep.
+ *     reconfiguration step. Also called when reconfiguring because the
+ *     driver's resume function returned 1, as this is just like an "inline"
+ *     hardware restart. This callback may sleep.
+ *
  */
 struct ieee80211_ops {
        void (*tx)(struct ieee80211_hw *hw,
@@ -2673,6 +2678,8 @@ struct ieee80211_ops {
  *
  * @priv_data_len: length of private data
  * @ops: callbacks for this device
+ *
+ * Return: A pointer to the new hardware device, or %NULL on error.
  */
 struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
                                        const struct ieee80211_ops *ops);
@@ -2685,6 +2692,8 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
  * need to fill the contained wiphy's information.
  *
  * @hw: the device to register as returned by ieee80211_alloc_hw()
+ *
+ * Return: 0 on success. An error code otherwise.
  */
 int ieee80211_register_hw(struct ieee80211_hw *hw);
 
@@ -2731,6 +2740,8 @@ extern char *__ieee80211_create_tpt_led_trigger(
  * of the trigger so you can automatically link the LED device.
  *
  * @hw: the hardware to get the LED trigger name for
+ *
+ * Return: The name of the LED trigger. %NULL if not configured for LEDs.
  */
 static inline char *ieee80211_get_tx_led_name(struct ieee80211_hw *hw)
 {
@@ -2750,6 +2761,8 @@ static inline char *ieee80211_get_tx_led_name(struct ieee80211_hw *hw)
  * of the trigger so you can automatically link the LED device.
  *
  * @hw: the hardware to get the LED trigger name for
+ *
+ * Return: The name of the LED trigger. %NULL if not configured for LEDs.
  */
 static inline char *ieee80211_get_rx_led_name(struct ieee80211_hw *hw)
 {
@@ -2769,6 +2782,8 @@ static inline char *ieee80211_get_rx_led_name(struct ieee80211_hw *hw)
  * of the trigger so you can automatically link the LED device.
  *
  * @hw: the hardware to get the LED trigger name for
+ *
+ * Return: The name of the LED trigger. %NULL if not configured for LEDs.
  */
 static inline char *ieee80211_get_assoc_led_name(struct ieee80211_hw *hw)
 {
@@ -2788,6 +2803,8 @@ static inline char *ieee80211_get_assoc_led_name(struct ieee80211_hw *hw)
  * of the trigger so you can automatically link the LED device.
  *
  * @hw: the hardware to get the LED trigger name for
+ *
+ * Return: The name of the LED trigger. %NULL if not configured for LEDs.
  */
 static inline char *ieee80211_get_radio_led_name(struct ieee80211_hw *hw)
 {
@@ -2805,9 +2822,10 @@ static inline char *ieee80211_get_radio_led_name(struct ieee80211_hw *hw)
  * @blink_table: the blink table -- needs to be ordered by throughput
  * @blink_table_len: size of the blink table
  *
- * This function returns %NULL (in case of error, or if no LED
- * triggers are configured) or the name of the new trigger.
- * This function must be called before ieee80211_register_hw().
+ * Return: %NULL (in case of error, or if no LED triggers are
+ * configured) or the name of the new trigger.
+ *
+ * Note: This function must be called before ieee80211_register_hw().
  */
 static inline char *
 ieee80211_create_tpt_led_trigger(struct ieee80211_hw *hw, unsigned int flags,
@@ -2940,10 +2958,10 @@ static inline void ieee80211_rx_ni(struct ieee80211_hw *hw,
  * Calls to this function for a single hardware must be synchronized against
  * each other.
  *
- * The function returns -EINVAL when the requested PS mode is already set.
- *
  * @sta: currently connected sta
  * @start: start or stop PS
+ *
+ * Return: 0 on success. -EINVAL when the requested PS mode is already set.
  */
 int ieee80211_sta_ps_transition(struct ieee80211_sta *sta, bool start);
 
@@ -2957,6 +2975,8 @@ int ieee80211_sta_ps_transition(struct ieee80211_sta *sta, bool start);
  *
  * @sta: currently connected sta
  * @start: start or stop PS
+ *
+ * Return: Like ieee80211_sta_ps_transition().
  */
 static inline int ieee80211_sta_ps_transition_ni(struct ieee80211_sta *sta,
                                                  bool start)
@@ -3094,6 +3114,8 @@ void ieee80211_report_low_ack(struct ieee80211_sta *sta, u32 num_packets);
  * according to the current DTIM parameters/TIM bitmap.
  *
  * The driver is responsible for freeing the returned skb.
+ *
+ * Return: The beacon template. %NULL on error.
  */
 struct sk_buff *ieee80211_beacon_get_tim(struct ieee80211_hw *hw,
                                         struct ieee80211_vif *vif,
@@ -3105,6 +3127,8 @@ struct sk_buff *ieee80211_beacon_get_tim(struct ieee80211_hw *hw,
  * @vif: &struct ieee80211_vif pointer from the add_interface callback.
  *
  * See ieee80211_beacon_get_tim().
+ *
+ * Return: See ieee80211_beacon_get_tim().
  */
 static inline struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw,
                                                   struct ieee80211_vif *vif)
@@ -3121,6 +3145,8 @@ static inline struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw,
  * hardware. The destination address should be set by the caller.
  *
  * Can only be called in AP mode.
+ *
+ * Return: The Probe Response template. %NULL on error.
  */
 struct sk_buff *ieee80211_proberesp_get(struct ieee80211_hw *hw,
                                        struct ieee80211_vif *vif);
@@ -3136,6 +3162,8 @@ struct sk_buff *ieee80211_proberesp_get(struct ieee80211_hw *hw,
  *
  * Note: Caller (or hardware) is responsible for setting the
  * &IEEE80211_FCTL_PM bit.
+ *
+ * Return: The PS Poll template. %NULL on error.
  */
 struct sk_buff *ieee80211_pspoll_get(struct ieee80211_hw *hw,
                                     struct ieee80211_vif *vif);
@@ -3151,6 +3179,8 @@ struct sk_buff *ieee80211_pspoll_get(struct ieee80211_hw *hw,
  *
  * Note: Caller (or hardware) is responsible for setting the
  * &IEEE80211_FCTL_PM bit as well as Duration and Sequence Control fields.
+ *
+ * Return: The nullfunc template. %NULL on error.
  */
 struct sk_buff *ieee80211_nullfunc_get(struct ieee80211_hw *hw,
                                       struct ieee80211_vif *vif);
@@ -3165,6 +3195,8 @@ struct sk_buff *ieee80211_nullfunc_get(struct ieee80211_hw *hw,
  *
  * Creates a Probe Request template which can, for example, be uploaded to
  * hardware.
+ *
+ * Return: The Probe Request template. %NULL on error.
  */
 struct sk_buff *ieee80211_probereq_get(struct ieee80211_hw *hw,
                                       struct ieee80211_vif *vif,
@@ -3200,6 +3232,8 @@ void ieee80211_rts_get(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
  * If the RTS is generated in firmware, but the host system must provide
  * the duration field, the low-level driver uses this function to receive
  * the duration field value in little-endian byteorder.
+ *
+ * Return: The duration.
  */
 __le16 ieee80211_rts_duration(struct ieee80211_hw *hw,
                              struct ieee80211_vif *vif, size_t frame_len,
@@ -3235,6 +3269,8 @@ void ieee80211_ctstoself_get(struct ieee80211_hw *hw,
  * If the CTS-to-self is generated in firmware, but the host system must provide
  * the duration field, the low-level driver uses this function to receive
  * the duration field value in little-endian byteorder.
+ *
+ * Return: The duration.
  */
 __le16 ieee80211_ctstoself_duration(struct ieee80211_hw *hw,
                                    struct ieee80211_vif *vif,
@@ -3251,6 +3287,8 @@ __le16 ieee80211_ctstoself_duration(struct ieee80211_hw *hw,
  *
  * Calculate the duration field of some generic frame, given its
  * length and transmission rate (in 100kbps).
+ *
+ * Return: The duration.
  */
 __le16 ieee80211_generic_frame_duration(struct ieee80211_hw *hw,
                                        struct ieee80211_vif *vif,
@@ -3267,9 +3305,10 @@ __le16 ieee80211_generic_frame_duration(struct ieee80211_hw *hw,
  * hardware/firmware does not implement buffering of broadcast/multicast
  * frames when power saving is used, 802.11 code buffers them in the host
  * memory. The low-level driver uses this function to fetch next buffered
- * frame. In most cases, this is used when generating beacon frame. This
- * function returns a pointer to the next buffered skb or NULL if no more
- * buffered frames are available.
+ * frame. In most cases, this is used when generating beacon frame.
+ *
+ * Return: A pointer to the next buffered skb or NULL if no more buffered
+ * frames are available.
  *
  * Note: buffered frames are returned only after DTIM beacon frame was
  * generated with ieee80211_beacon_get() and the low-level driver must thus
@@ -3449,6 +3488,8 @@ void ieee80211_stop_queue(struct ieee80211_hw *hw, int queue);
  * @queue: queue number (counted from zero).
  *
  * Drivers should use this function instead of netif_stop_queue.
+ *
+ * Return: %true if the queue is stopped. %false otherwise.
  */
 
 int ieee80211_queue_stopped(struct ieee80211_hw *hw, int queue);
@@ -3646,7 +3687,9 @@ void ieee80211_stop_tx_ba_cb_irqsafe(struct ieee80211_vif *vif, const u8 *ra,
  * @vif: virtual interface to look for station on
  * @addr: station's address
  *
- * This function must be called under RCU lock and the
+ * Return: The station, if found. %NULL otherwise.
+ *
+ * Note: This function must be called under RCU lock and the
  * resulting pointer is only valid under RCU lock as well.
  */
 struct ieee80211_sta *ieee80211_find_sta(struct ieee80211_vif *vif,
@@ -3659,7 +3702,9 @@ struct ieee80211_sta *ieee80211_find_sta(struct ieee80211_vif *vif,
  * @addr: remote station's address
  * @localaddr: local address (vif->sdata->vif.addr). Use NULL for 'any'.
  *
- * This function must be called under RCU lock and the
+ * Return: The station, if found. %NULL otherwise.
+ *
+ * Note: This function must be called under RCU lock and the
  * resulting pointer is only valid under RCU lock as well.
  *
  * NOTE: You may pass NULL for localaddr, but then you will just get
@@ -3789,7 +3834,9 @@ void ieee80211_iter_chan_contexts_atomic(
  * information. This function must only be called from within the
  * .bss_info_changed callback function and only in managed mode. The function
  * is only useful when the interface is associated, otherwise it will return
- * NULL.
+ * %NULL.
+ *
+ * Return: The Probe Request template. %NULL on error.
  */
 struct sk_buff *ieee80211_ap_probereq_get(struct ieee80211_hw *hw,
                                          struct ieee80211_vif *vif);
@@ -4136,12 +4183,14 @@ void ieee80211_enable_rssi_reports(struct ieee80211_vif *vif,
 void ieee80211_disable_rssi_reports(struct ieee80211_vif *vif);
 
 /**
- * ieee80211_ave_rssi - report the average rssi for the specified interface
+ * ieee80211_ave_rssi - report the average RSSI for the specified interface
  *
  * @vif: the specified virtual interface
  *
- * This function return the average rssi value for the requested interface.
- * It assumes that the given vif is valid.
+ * Note: This function assumes that the given vif is valid.
+ *
+ * Return: The average RSSI value for the requested interface, or 0 if not
+ * applicable.
  */
 int ieee80211_ave_rssi(struct ieee80211_vif *vif);
 
index 547017100a305a3dca3ce12adcac417d8aa3270b..e6eeb4ba5dc58c83ce20c7773a1f20819e883d36 100644 (file)
  *     requests to connect to a specified network but without separating
  *     auth and assoc steps. For this, you need to specify the SSID in a
  *     %NL80211_ATTR_SSID attribute, and can optionally specify the association
- *     IEs in %NL80211_ATTR_IE, %NL80211_ATTR_AUTH_TYPE, %NL80211_ATTR_MAC,
- *     %NL80211_ATTR_WIPHY_FREQ, %NL80211_ATTR_CONTROL_PORT,
+ *     IEs in %NL80211_ATTR_IE, %NL80211_ATTR_AUTH_TYPE, %NL80211_ATTR_USE_MFP,
+ *     %NL80211_ATTR_MAC, %NL80211_ATTR_WIPHY_FREQ, %NL80211_ATTR_CONTROL_PORT,
  *     %NL80211_ATTR_CONTROL_PORT_ETHERTYPE and
  *     %NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT.
  *     Background scan period can optionally be
@@ -958,7 +958,7 @@ enum nl80211_commands {
  * @NL80211_ATTR_USE_MFP: Whether management frame protection (IEEE 802.11w) is
  *     used for the association (&enum nl80211_mfp, represented as a u32);
  *     this attribute can be used
- *     with %NL80211_CMD_ASSOCIATE request
+ *     with %NL80211_CMD_ASSOCIATE and %NL80211_CMD_CONNECT requests
  *
  * @NL80211_ATTR_STA_FLAGS2: Attribute containing a
  *     &struct nl80211_sta_flag_update.
@@ -1310,6 +1310,9 @@ enum nl80211_commands {
  *     if not given in START_AP 0 is assumed, if not given in SET_BSS
  *     no change is made.
  *
+ * @NL80211_ATTR_LOCAL_MESH_POWER_MODE: local mesh STA link-specific power mode
+ *     defined in &enum nl80211_mesh_power_mode.
+ *
  * @NL80211_ATTR_MAX: highest attribute number currently defined
  * @__NL80211_ATTR_AFTER_LAST: internal use
  */
@@ -1580,6 +1583,8 @@ enum nl80211_attrs {
        NL80211_ATTR_P2P_CTWINDOW,
        NL80211_ATTR_P2P_OPPPS,
 
+       NL80211_ATTR_LOCAL_MESH_POWER_MODE,
+
        /* add attributes here, update the policy in nl80211.c */
 
        __NL80211_ATTR_AFTER_LAST,
@@ -1838,6 +1843,10 @@ enum nl80211_sta_bss_param {
  * @NL80211_STA_INFO_STA_FLAGS: Contains a struct nl80211_sta_flag_update.
  * @NL80211_STA_INFO_BEACON_LOSS: count of times beacon loss was detected (u32)
  * @NL80211_STA_INFO_T_OFFSET: timing offset with respect to this STA (s64)
+ * @NL80211_STA_INFO_LOCAL_PM: local mesh STA link-specific power mode
+ * @NL80211_STA_INFO_PEER_PM: peer mesh STA link-specific power mode
+ * @NL80211_STA_INFO_NONPEER_PM: neighbor mesh STA power save mode towards
+ *     non-peer STA
  * @__NL80211_STA_INFO_AFTER_LAST: internal
  * @NL80211_STA_INFO_MAX: highest possible station info attribute
  */
@@ -1862,6 +1871,9 @@ enum nl80211_sta_info {
        NL80211_STA_INFO_STA_FLAGS,
        NL80211_STA_INFO_BEACON_LOSS,
        NL80211_STA_INFO_T_OFFSET,
+       NL80211_STA_INFO_LOCAL_PM,
+       NL80211_STA_INFO_PEER_PM,
+       NL80211_STA_INFO_NONPEER_PM,
 
        /* keep last */
        __NL80211_STA_INFO_AFTER_LAST,
@@ -2252,6 +2264,34 @@ enum nl80211_mntr_flags {
        NL80211_MNTR_FLAG_MAX = __NL80211_MNTR_FLAG_AFTER_LAST - 1
 };
 
+/**
+ * enum nl80211_mesh_power_mode - mesh power save modes
+ *
+ * @NL80211_MESH_POWER_UNKNOWN: The mesh power mode of the mesh STA is
+ *     not known or has not been set yet.
+ * @NL80211_MESH_POWER_ACTIVE: Active mesh power mode. The mesh STA is
+ *     in Awake state all the time.
+ * @NL80211_MESH_POWER_LIGHT_SLEEP: Light sleep mode. The mesh STA will
+ *     alternate between Active and Doze states, but will wake up for
+ *     neighbor's beacons.
+ * @NL80211_MESH_POWER_DEEP_SLEEP: Deep sleep mode. The mesh STA will
+ *     alternate between Active and Doze states, but may not wake up
+ *     for neighbor's beacons.
+ *
+ * @__NL80211_MESH_POWER_AFTER_LAST - internal use
+ * @NL80211_MESH_POWER_MAX - highest possible power save level
+ */
+
+enum nl80211_mesh_power_mode {
+       NL80211_MESH_POWER_UNKNOWN,
+       NL80211_MESH_POWER_ACTIVE,
+       NL80211_MESH_POWER_LIGHT_SLEEP,
+       NL80211_MESH_POWER_DEEP_SLEEP,
+
+       __NL80211_MESH_POWER_AFTER_LAST,
+       NL80211_MESH_POWER_MAX = __NL80211_MESH_POWER_AFTER_LAST - 1
+};
+
 /**
  * enum nl80211_meshconf_params - mesh configuration parameters
  *
@@ -2346,6 +2386,11 @@ enum nl80211_mntr_flags {
  *     (in TUs) during which a mesh STA can send only one Action frame
  *     containing a PREQ element for root path confirmation.
  *
+ * @NL80211_MESHCONF_POWER_MODE: Default mesh power mode for new peer links.
+ *     type &enum nl80211_mesh_power_mode (u32)
+ *
+ * @NL80211_MESHCONF_AWAKE_WINDOW: awake window duration (in TUs)
+ *
  * @__NL80211_MESHCONF_ATTR_AFTER_LAST: internal use
  */
 enum nl80211_meshconf_params {
@@ -2375,6 +2420,8 @@ enum nl80211_meshconf_params {
        NL80211_MESHCONF_HWMP_PATH_TO_ROOT_TIMEOUT,
        NL80211_MESHCONF_HWMP_ROOT_INTERVAL,
        NL80211_MESHCONF_HWMP_CONFIRMATION_INTERVAL,
+       NL80211_MESHCONF_POWER_MODE,
+       NL80211_MESHCONF_AWAKE_WINDOW,
 
        /* keep last */
        __NL80211_MESHCONF_ATTR_AFTER_LAST,
@@ -2937,6 +2984,8 @@ enum nl80211_iface_limit_attrs {
  *     the infrastructure network's beacon interval.
  * @NL80211_IFACE_COMB_NUM_CHANNELS: u32 attribute specifying how many
  *     different channels may be used within this group.
+ * @NL80211_IFACE_COMB_RADAR_DETECT_WIDTHS: u32 attribute containing the bitmap
+ *     of supported channel widths for radar detection.
  * @NUM_NL80211_IFACE_COMB: number of attributes
  * @MAX_NL80211_IFACE_COMB: highest attribute number
  *
@@ -2969,6 +3018,7 @@ enum nl80211_if_combination_attrs {
        NL80211_IFACE_COMB_MAXNUM,
        NL80211_IFACE_COMB_STA_AP_BI_MATCH,
        NL80211_IFACE_COMB_NUM_CHANNELS,
+       NL80211_IFACE_COMB_RADAR_DETECT_WIDTHS,
 
        /* keep last */
        NUM_NL80211_IFACE_COMB,
index 7d290bce092777561b27553bb1d4d39e697fd60d..36aa65f495fff0712bb16b87ec75fe42cbf705e5 100644 (file)
@@ -1243,18 +1243,33 @@ static int sta_apply_parameters(struct ieee80211_local *local,
 
        if (ieee80211_vif_is_mesh(&sdata->vif)) {
 #ifdef CONFIG_MAC80211_MESH
-               if (sdata->u.mesh.security & IEEE80211_MESH_SEC_SECURED)
+               if (sdata->u.mesh.security & IEEE80211_MESH_SEC_SECURED) {
+                       u32 changed = 0;
+
                        switch (params->plink_state) {
-                       case NL80211_PLINK_LISTEN:
                        case NL80211_PLINK_ESTAB:
+                               if (sta->plink_state != NL80211_PLINK_ESTAB)
+                                       changed = mesh_plink_inc_estab_count(
+                                                       sdata);
+                               sta->plink_state = params->plink_state;
+                               break;
+                       case NL80211_PLINK_LISTEN:
                        case NL80211_PLINK_BLOCKED:
+                       case NL80211_PLINK_OPN_SNT:
+                       case NL80211_PLINK_OPN_RCVD:
+                       case NL80211_PLINK_CNF_RCVD:
+                       case NL80211_PLINK_HOLDING:
+                               if (sta->plink_state == NL80211_PLINK_ESTAB)
+                                       changed = mesh_plink_dec_estab_count(
+                                                       sdata);
                                sta->plink_state = params->plink_state;
                                break;
                        default:
                                /*  nothing  */
                                break;
                        }
-               else
+                       ieee80211_bss_info_change_notify(sdata, changed);
+               } else {
                        switch (params->plink_action) {
                        case PLINK_ACTION_OPEN:
                                mesh_plink_open(sta);
@@ -1263,6 +1278,7 @@ static int sta_apply_parameters(struct ieee80211_local *local,
                                mesh_plink_block(sta);
                                break;
                        }
+               }
 #endif
        }
 
@@ -1650,6 +1666,9 @@ static int copy_mesh_setup(struct ieee80211_if_mesh *ifmsh,
        memcpy(sdata->vif.bss_conf.mcast_rate, setup->mcast_rate,
                                                sizeof(setup->mcast_rate));
 
+       sdata->vif.bss_conf.beacon_int = setup->beacon_interval;
+       sdata->vif.bss_conf.dtim_period = setup->dtim_period;
+
        return 0;
 }
 
@@ -2232,7 +2251,8 @@ static int ieee80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev,
        struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
        struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
 
-       if (sdata->vif.type != NL80211_IFTYPE_STATION)
+       if (sdata->vif.type != NL80211_IFTYPE_STATION &&
+           sdata->vif.type != NL80211_IFTYPE_MESH_POINT)
                return -EOPNOTSUPP;
 
        if (!(local->hw.flags & IEEE80211_HW_SUPPORTS_PS))
index 245885841c8dd40b9eb493f3276943296c4d6ab0..694e27376afa151941ef5628c3fa83ae32867b15 100644 (file)
@@ -625,7 +625,6 @@ void ieee80211_start_mesh(struct ieee80211_sub_if_data *sdata)
        ieee80211_queue_work(&local->hw, &sdata->work);
        sdata->vif.bss_conf.ht_operation_mode =
                                ifmsh->mshcfg.ht_opmode;
-       sdata->vif.bss_conf.beacon_int = MESH_DEFAULT_BEACON_INTERVAL;
        sdata->vif.bss_conf.enable_beacon = true;
        sdata->vif.bss_conf.basic_rates =
                ieee80211_mandatory_rates(local, band);
index 84c28c6101cdd2ef832920677d05b7f02b27ada2..aff301544c7fb30cc0fb3b8e4309a2cfead6909d 100644 (file)
@@ -191,8 +191,6 @@ struct mesh_rmc {
 #define IEEE80211_MESH_PEER_INACTIVITY_LIMIT (1800 * HZ)
 #define IEEE80211_MESH_HOUSEKEEPING_INTERVAL (60 * HZ)
 
-#define MESH_DEFAULT_BEACON_INTERVAL           1000    /* in 1024 us units */
-
 #define MESH_PATH_EXPIRE (600 * HZ)
 
 /* Default maximum number of plinks per interface */
@@ -307,6 +305,20 @@ extern int mesh_paths_generation;
 #ifdef CONFIG_MAC80211_MESH
 extern int mesh_allocated;
 
+static inline
+u32 mesh_plink_inc_estab_count(struct ieee80211_sub_if_data *sdata)
+{
+       atomic_inc(&sdata->u.mesh.estab_plinks);
+       return mesh_accept_plinks_update(sdata);
+}
+
+static inline
+u32 mesh_plink_dec_estab_count(struct ieee80211_sub_if_data *sdata)
+{
+       atomic_dec(&sdata->u.mesh.estab_plinks);
+       return mesh_accept_plinks_update(sdata);
+}
+
 static inline int mesh_plink_free_count(struct ieee80211_sub_if_data *sdata)
 {
        return sdata->u.mesh.mshcfg.dot11MeshMaxPeerLinks -
index 4b274e9c91a5f19c526c9c91d290c9fc574d4098..9e0416696a834d1481a6f47385b97bbc8b4369db 100644 (file)
@@ -41,20 +41,6 @@ static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata,
                enum ieee80211_self_protected_actioncode action,
                u8 *da, __le16 llid, __le16 plid, __le16 reason);
 
-static inline
-u32 mesh_plink_inc_estab_count(struct ieee80211_sub_if_data *sdata)
-{
-       atomic_inc(&sdata->u.mesh.estab_plinks);
-       return mesh_accept_plinks_update(sdata);
-}
-
-static inline
-u32 mesh_plink_dec_estab_count(struct ieee80211_sub_if_data *sdata)
-{
-       atomic_dec(&sdata->u.mesh.estab_plinks);
-       return mesh_accept_plinks_update(sdata);
-}
-
 /**
  * mesh_plink_fsm_restart - restart a mesh peer link finite state machine
  *
index d90c07b1795f284db3036d1b472ecceb7660ff96..e930175771ffa088dd7d58bf115c8f2cd5908b3c 100644 (file)
@@ -199,11 +199,11 @@ static u32 ieee80211_config_ht_tx(struct ieee80211_sub_if_data *sdata,
        case NL80211_CHAN_WIDTH_40:
                if (sdata->vif.bss_conf.chandef.chan->center_freq >
                                sdata->vif.bss_conf.chandef.center_freq1 &&
-                   chan->flags & IEEE80211_CHAN_NO_HT40PLUS)
+                   chan->flags & IEEE80211_CHAN_NO_HT40MINUS)
                        disable_40 = true;
                if (sdata->vif.bss_conf.chandef.chan->center_freq <
                                sdata->vif.bss_conf.chandef.center_freq1 &&
-                   chan->flags & IEEE80211_CHAN_NO_HT40MINUS)
+                   chan->flags & IEEE80211_CHAN_NO_HT40PLUS)
                        disable_40 = true;
                break;
        default:
index a8270b441a6f93249e095c74be849bdf9ce39f9b..41861b91daa3884bce04880beb4ad707ed301e4c 100644 (file)
 #define VIF_PR_FMT     " vif:%s(%d%s)"
 #define VIF_PR_ARG     __get_str(vif_name), __entry->vif_type, __entry->p2p ? "/p2p" : ""
 
-#define CHANCTX_ENTRY  __field(u32, control_freq)                              \
+#define CHANDEF_ENTRY  __field(u32, control_freq)                              \
                        __field(u32, chan_width)                                \
                        __field(u32, center_freq1)                              \
-                       __field(u32, center_freq2)                              \
+                       __field(u32, center_freq2)
+#define CHANDEF_ASSIGN(c)                                                      \
+                       __entry->control_freq = (c)->chan->center_freq;         \
+                       __entry->chan_width = (c)->width;                       \
+                       __entry->center_freq1 = (c)->center_freq1;              \
+                       __entry->center_freq1 = (c)->center_freq2;
+#define CHANDEF_PR_FMT " control:%d MHz width:%d center: %d/%d MHz"
+#define CHANDEF_PR_ARG __entry->control_freq, __entry->chan_width,             \
+                       __entry->center_freq1, __entry->center_freq2
+
+#define CHANCTX_ENTRY  CHANDEF_ENTRY                                           \
                        __field(u8, rx_chains_static)                           \
                        __field(u8, rx_chains_dynamic)
-#define CHANCTX_ASSIGN __entry->control_freq = ctx->conf.def.chan->center_freq;\
-                       __entry->chan_width = ctx->conf.def.width;              \
-                       __entry->center_freq1 = ctx->conf.def.center_freq1;     \
-                       __entry->center_freq2 = ctx->conf.def.center_freq2;     \
+#define CHANCTX_ASSIGN CHANDEF_ASSIGN(&ctx->conf.def)                          \
                        __entry->rx_chains_static = ctx->conf.rx_chains_static; \
                        __entry->rx_chains_dynamic = ctx->conf.rx_chains_dynamic
-#define CHANCTX_PR_FMT " control:%d MHz width:%d center: %d/%d MHz chains:%d/%d"
-#define CHANCTX_PR_ARG __entry->control_freq, __entry->chan_width,             \
-                       __entry->center_freq1, __entry->center_freq2,           \
+#define CHANCTX_PR_FMT CHANDEF_PR_FMT " chains:%d/%d"
+#define CHANCTX_PR_ARG CHANDEF_PR_ARG,                                         \
                        __entry->rx_chains_static, __entry->rx_chains_dynamic
 
 
index e9eadc40c09cc20bce9ad37531ef45ae767f62e8..0d7381679a5c6cf0c80560c90869be62bcec71ad 100644 (file)
@@ -2261,9 +2261,8 @@ void ieee80211_tx_pending(unsigned long data)
 
 /* functions for drivers to get certain frames */
 
-static void ieee80211_beacon_add_tim(struct ieee80211_sub_if_data *sdata,
-                                    struct ps_data *ps,
-                                    struct sk_buff *skb)
+static void __ieee80211_beacon_add_tim(struct ieee80211_sub_if_data *sdata,
+                                      struct ps_data *ps, struct sk_buff *skb)
 {
        u8 *pos, *tim;
        int aid0 = 0;
@@ -2325,6 +2324,31 @@ static void ieee80211_beacon_add_tim(struct ieee80211_sub_if_data *sdata,
        }
 }
 
+static int ieee80211_beacon_add_tim(struct ieee80211_sub_if_data *sdata,
+                                   struct ps_data *ps, struct sk_buff *skb)
+{
+       struct ieee80211_local *local = sdata->local;
+
+       /*
+        * Not very nice, but we want to allow the driver to call
+        * ieee80211_beacon_get() as a response to the set_tim()
+        * callback. That, however, is already invoked under the
+        * sta_lock to guarantee consistent and race-free update
+        * of the tim bitmap in mac80211 and the driver.
+        */
+       if (local->tim_in_locked_section) {
+               __ieee80211_beacon_add_tim(sdata, ps, skb);
+       } else {
+               unsigned long flags;
+
+               spin_lock_irqsave(&local->tim_lock, flags);
+               __ieee80211_beacon_add_tim(sdata, ps, skb);
+               spin_unlock_irqrestore(&local->tim_lock, flags);
+       }
+
+       return 0;
+}
+
 struct sk_buff *ieee80211_beacon_get_tim(struct ieee80211_hw *hw,
                                         struct ieee80211_vif *vif,
                                         u16 *tim_offset, u16 *tim_length)
@@ -2369,22 +2393,7 @@ struct sk_buff *ieee80211_beacon_get_tim(struct ieee80211_hw *hw,
                        memcpy(skb_put(skb, beacon->head_len), beacon->head,
                               beacon->head_len);
 
-                       /*
-                        * Not very nice, but we want to allow the driver to call
-                        * ieee80211_beacon_get() as a response to the set_tim()
-                        * callback. That, however, is already invoked under the
-                        * sta_lock to guarantee consistent and race-free update
-                        * of the tim bitmap in mac80211 and the driver.
-                        */
-                       if (local->tim_in_locked_section) {
-                               ieee80211_beacon_add_tim(sdata, &ap->ps, skb);
-                       } else {
-                               unsigned long flags;
-
-                               spin_lock_irqsave(&local->tim_lock, flags);
-                               ieee80211_beacon_add_tim(sdata, &ap->ps, skb);
-                               spin_unlock_irqrestore(&local->tim_lock, flags);
-                       }
+                       ieee80211_beacon_add_tim(sdata, &ap->ps, skb);
 
                        if (tim_offset)
                                *tim_offset = beacon->head_len;
index 1b9420730d8cf52628d22ff60b97d599ea87e1f2..7519018ff71af2844241f43697a1926f54122def 100644 (file)
@@ -1358,6 +1358,7 @@ int ieee80211_reconfig(struct ieee80211_local *local)
        struct ieee80211_chanctx *ctx;
        struct sta_info *sta;
        int res, i;
+       bool reconfig_due_to_wowlan = false;
 
 #ifdef CONFIG_PM
        if (local->suspended)
@@ -1377,6 +1378,7 @@ int ieee80211_reconfig(struct ieee80211_local *local)
                 * res is 1, which means the driver requested
                 * to go through a regular reset on wakeup.
                 */
+               reconfig_due_to_wowlan = true;
        }
 #endif
        /* everything else happens only if HW was up & running */
@@ -1527,7 +1529,7 @@ int ieee80211_reconfig(struct ieee80211_local *local)
                          BSS_CHANGED_TXPOWER;
 
 #ifdef CONFIG_PM
-               if (local->resuming)
+               if (local->resuming && !reconfig_due_to_wowlan)
                        sdata->vif.bss_conf = sdata->suspend_bss_conf;
 #endif
 
@@ -1654,10 +1656,11 @@ int ieee80211_reconfig(struct ieee80211_local *local)
         * If this is for hw restart things are still running.
         * We may want to change that later, however.
         */
-       if (!local->suspended) {
+       if (!local->suspended || reconfig_due_to_wowlan)
                drv_restart_complete(local);
+
+       if (!local->suspended)
                return 0;
-       }
 
 #ifdef CONFIG_PM
        /* first set suspended false, then resuming */
index 747dd9365a44ff7ce336c5db1f70d6a466cf6d0d..0e702cdc60434ef53a31884b64883405c155b2b6 100644 (file)
@@ -382,8 +382,11 @@ static int wiphy_verify_combinations(struct wiphy *wiphy)
 
                c = &wiphy->iface_combinations[i];
 
-               /* Combinations with just one interface aren't real */
-               if (WARN_ON(c->max_interfaces < 2))
+               /*
+                * Combinations with just one interface aren't real,
+                * however we make an exception for DFS.
+                */
+               if (WARN_ON((c->max_interfaces < 2) && !c->radar_detect_widths))
                        return -EINVAL;
 
                /* Need at least one channel */
@@ -398,6 +401,11 @@ static int wiphy_verify_combinations(struct wiphy *wiphy)
                                CFG80211_MAX_NUM_DIFFERENT_CHANNELS))
                        return -EINVAL;
 
+               /* DFS only works on one channel. */
+               if (WARN_ON(c->radar_detect_widths &&
+                           (c->num_different_channels > 1)))
+                       return -EINVAL;
+
                if (WARN_ON(!c->n_limits))
                        return -EINVAL;
 
index f342267e36207969b3dba3bfc071bc440082268e..8396f7671c8db682c87baf657f607ae883e4128c 100644 (file)
@@ -425,7 +425,8 @@ int cfg80211_can_use_iftype_chan(struct cfg80211_registered_device *rdev,
                                 struct wireless_dev *wdev,
                                 enum nl80211_iftype iftype,
                                 struct ieee80211_channel *chan,
-                                enum cfg80211_chan_mode chanmode);
+                                enum cfg80211_chan_mode chanmode,
+                                u8 radar_detect);
 
 static inline int
 cfg80211_can_change_interface(struct cfg80211_registered_device *rdev,
@@ -433,7 +434,7 @@ cfg80211_can_change_interface(struct cfg80211_registered_device *rdev,
                              enum nl80211_iftype iftype)
 {
        return cfg80211_can_use_iftype_chan(rdev, wdev, iftype, NULL,
-                                           CHAN_MODE_UNDEFINED);
+                                           CHAN_MODE_UNDEFINED, 0);
 }
 
 static inline int
@@ -450,7 +451,7 @@ cfg80211_can_use_chan(struct cfg80211_registered_device *rdev,
                      enum cfg80211_chan_mode chanmode)
 {
        return cfg80211_can_use_iftype_chan(rdev, wdev, wdev->iftype,
-                                           chan, chanmode);
+                                           chan, chanmode, 0);
 }
 
 void
index f9d6ce5cfabbaebfc202f2d0290d8b1f0fbbc314..55957a284f6c7e82c9b403dae01798316224ad49 100644 (file)
 
 #define MESH_SYNC_NEIGHBOR_OFFSET_MAX 50
 
+#define MESH_DEFAULT_BEACON_INTERVAL   1000    /* in 1024 us units (=TUs) */
+#define MESH_DEFAULT_DTIM_PERIOD       2
+#define MESH_DEFAULT_AWAKE_WINDOW      10      /* in 1024 us units (=TUs) */
+
 const struct mesh_config default_mesh_config = {
        .dot11MeshRetryTimeout = MESH_RET_T,
        .dot11MeshConfirmTimeout = MESH_CONF_T,
@@ -69,6 +73,8 @@ const struct mesh_config default_mesh_config = {
        .dot11MeshHWMPactivePathToRootTimeout = MESH_PATH_TO_ROOT_TIMEOUT,
        .dot11MeshHWMProotInterval = MESH_ROOT_INTERVAL,
        .dot11MeshHWMPconfirmationInterval = MESH_ROOT_CONFIRMATION_INTERVAL,
+       .power_mode = NL80211_MESH_POWER_ACTIVE,
+       .dot11MeshAwakeWindowDuration = MESH_DEFAULT_AWAKE_WINDOW,
 };
 
 const struct mesh_setup default_mesh_setup = {
@@ -79,6 +85,8 @@ const struct mesh_setup default_mesh_setup = {
        .ie = NULL,
        .ie_len = 0,
        .is_secure = false,
+       .beacon_interval = MESH_DEFAULT_BEACON_INTERVAL,
+       .dtim_period = MESH_DEFAULT_DTIM_PERIOD,
 };
 
 int __cfg80211_join_mesh(struct cfg80211_registered_device *rdev,
index 9bd8340af999c45ed59f6340a82d0957d0bb511e..33de80364c5cd183f344b8cc72f03810855141f3 100644 (file)
@@ -856,6 +856,9 @@ static int nl80211_put_iface_combinations(struct wiphy *wiphy,
                    nla_put_u32(msg, NL80211_IFACE_COMB_MAXNUM,
                                c->max_interfaces))
                        goto nla_put_failure;
+               if (nla_put_u32(msg, NL80211_IFACE_COMB_RADAR_DETECT_WIDTHS,
+                               c->radar_detect_widths))
+                       goto nla_put_failure;
 
                nla_nest_end(msg, nl_combi);
        }
@@ -2079,6 +2082,13 @@ static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info)
            !(rdev->wiphy.interface_modes & (1 << type)))
                return -EOPNOTSUPP;
 
+       if (type == NL80211_IFTYPE_P2P_DEVICE && info->attrs[NL80211_ATTR_MAC]) {
+               nla_memcpy(params.macaddr, info->attrs[NL80211_ATTR_MAC],
+                          ETH_ALEN);
+               if (!is_valid_ether_addr(params.macaddr))
+                       return -EADDRNOTAVAIL;
+       }
+
        if (info->attrs[NL80211_ATTR_4ADDR]) {
                params.use_4addr = !!nla_get_u8(info->attrs[NL80211_ATTR_4ADDR]);
                err = nl80211_valid_4addr(rdev, NULL, params.use_4addr, type);
@@ -3001,6 +3011,18 @@ static int nl80211_send_station(struct sk_buff *msg, u32 portid, u32 seq,
            nla_put_u32(msg, NL80211_STA_INFO_BEACON_LOSS,
                        sinfo->beacon_loss_count))
                goto nla_put_failure;
+       if ((sinfo->filled & STATION_INFO_LOCAL_PM) &&
+           nla_put_u32(msg, NL80211_STA_INFO_LOCAL_PM,
+                       sinfo->local_pm))
+               goto nla_put_failure;
+       if ((sinfo->filled & STATION_INFO_PEER_PM) &&
+           nla_put_u32(msg, NL80211_STA_INFO_PEER_PM,
+                       sinfo->peer_pm))
+               goto nla_put_failure;
+       if ((sinfo->filled & STATION_INFO_NONPEER_PM) &&
+           nla_put_u32(msg, NL80211_STA_INFO_NONPEER_PM,
+                       sinfo->nonpeer_pm))
+               goto nla_put_failure;
        if (sinfo->filled & STATION_INFO_BSS_PARAM) {
                bss_param = nla_nest_start(msg, NL80211_STA_INFO_BSS_PARAM);
                if (!bss_param)
@@ -3206,6 +3228,17 @@ static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info)
                params.plink_state =
                    nla_get_u8(info->attrs[NL80211_ATTR_STA_PLINK_STATE]);
 
+       if (info->attrs[NL80211_ATTR_LOCAL_MESH_POWER_MODE]) {
+               enum nl80211_mesh_power_mode pm = nla_get_u32(
+                       info->attrs[NL80211_ATTR_LOCAL_MESH_POWER_MODE]);
+
+               if (pm <= NL80211_MESH_POWER_UNKNOWN ||
+                   pm > NL80211_MESH_POWER_MAX)
+                       return -EINVAL;
+
+               params.local_pm = pm;
+       }
+
        switch (dev->ieee80211_ptr->iftype) {
        case NL80211_IFTYPE_AP:
        case NL80211_IFTYPE_AP_VLAN:
@@ -3213,6 +3246,8 @@ static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info)
                /* disallow mesh-specific things */
                if (params.plink_action)
                        return -EINVAL;
+               if (params.local_pm)
+                       return -EINVAL;
 
                /* TDLS can't be set, ... */
                if (params.sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER))
@@ -3265,6 +3300,8 @@ static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info)
                /* disallow things sta doesn't support */
                if (params.plink_action)
                        return -EINVAL;
+               if (params.local_pm)
+                       return -EINVAL;
                /* reject any changes other than AUTHORIZED */
                if (params.sta_flags_mask & ~BIT(NL80211_STA_FLAG_AUTHORIZED))
                        return -EINVAL;
@@ -3922,7 +3959,11 @@ static int nl80211_get_mesh_config(struct sk_buff *skb,
            nla_put_u16(msg, NL80211_MESHCONF_HWMP_ROOT_INTERVAL,
                        cur_params.dot11MeshHWMProotInterval) ||
            nla_put_u16(msg, NL80211_MESHCONF_HWMP_CONFIRMATION_INTERVAL,
-                       cur_params.dot11MeshHWMPconfirmationInterval))
+                       cur_params.dot11MeshHWMPconfirmationInterval) ||
+           nla_put_u32(msg, NL80211_MESHCONF_POWER_MODE,
+                       cur_params.power_mode) ||
+           nla_put_u16(msg, NL80211_MESHCONF_AWAKE_WINDOW,
+                       cur_params.dot11MeshAwakeWindowDuration))
                goto nla_put_failure;
        nla_nest_end(msg, pinfoattr);
        genlmsg_end(msg, hdr);
@@ -3961,6 +4002,8 @@ static const struct nla_policy nl80211_meshconf_params_policy[NL80211_MESHCONF_A
        [NL80211_MESHCONF_HWMP_PATH_TO_ROOT_TIMEOUT] = { .type = NLA_U32 },
        [NL80211_MESHCONF_HWMP_ROOT_INTERVAL] = { .type = NLA_U16 },
        [NL80211_MESHCONF_HWMP_CONFIRMATION_INTERVAL] = { .type = NLA_U16 },
+       [NL80211_MESHCONF_POWER_MODE] = { .type = NLA_U32 },
+       [NL80211_MESHCONF_AWAKE_WINDOW] = { .type = NLA_U16 },
 };
 
 static const struct nla_policy
@@ -3981,13 +4024,15 @@ static int nl80211_parse_mesh_config(struct genl_info *info,
        struct nlattr *tb[NL80211_MESHCONF_ATTR_MAX + 1];
        u32 mask = 0;
 
-#define FILL_IN_MESH_PARAM_IF_SET(table, cfg, param, mask, attr_num, nla_fn) \
-do {\
-       if (table[attr_num]) {\
-               cfg->param = nla_fn(table[attr_num]); \
-               mask |= (1 << (attr_num - 1)); \
-       } \
-} while (0);\
+#define FILL_IN_MESH_PARAM_IF_SET(tb, cfg, param, min, max, mask, attr, fn) \
+do {                                                                       \
+       if (tb[attr]) {                                                     \
+               if (fn(tb[attr]) < min || fn(tb[attr]) > max)               \
+                       return -EINVAL;                                     \
+               cfg->param = fn(tb[attr]);                                  \
+               mask |= (1 << (attr - 1));                                  \
+       }                                                                   \
+} while (0)
 
 
        if (!info->attrs[NL80211_ATTR_MESH_CONFIG])
@@ -4002,83 +4047,98 @@ do {\
        BUILD_BUG_ON(NL80211_MESHCONF_ATTR_MAX > 32);
 
        /* Fill in the params struct */
-       FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshRetryTimeout,
+       FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshRetryTimeout, 1, 255,
                                  mask, NL80211_MESHCONF_RETRY_TIMEOUT,
                                  nla_get_u16);
-       FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshConfirmTimeout,
+       FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshConfirmTimeout, 1, 255,
                                  mask, NL80211_MESHCONF_CONFIRM_TIMEOUT,
                                  nla_get_u16);
-       FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHoldingTimeout,
+       FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHoldingTimeout, 1, 255,
                                  mask, NL80211_MESHCONF_HOLDING_TIMEOUT,
                                  nla_get_u16);
-       FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshMaxPeerLinks,
+       FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshMaxPeerLinks, 0, 255,
                                  mask, NL80211_MESHCONF_MAX_PEER_LINKS,
                                  nla_get_u16);
-       FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshMaxRetries,
+       FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshMaxRetries, 0, 16,
                                  mask, NL80211_MESHCONF_MAX_RETRIES,
                                  nla_get_u8);
-       FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshTTL,
+       FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshTTL, 1, 255,
                                  mask, NL80211_MESHCONF_TTL, nla_get_u8);
-       FILL_IN_MESH_PARAM_IF_SET(tb, cfg, element_ttl,
+       FILL_IN_MESH_PARAM_IF_SET(tb, cfg, element_ttl, 1, 255,
                                  mask, NL80211_MESHCONF_ELEMENT_TTL,
                                  nla_get_u8);
-       FILL_IN_MESH_PARAM_IF_SET(tb, cfg, auto_open_plinks,
+       FILL_IN_MESH_PARAM_IF_SET(tb, cfg, auto_open_plinks, 0, 1,
                                  mask, NL80211_MESHCONF_AUTO_OPEN_PLINKS,
                                  nla_get_u8);
-       FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshNbrOffsetMaxNeighbor, mask,
+       FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshNbrOffsetMaxNeighbor,
+                                 1, 255, mask,
                                  NL80211_MESHCONF_SYNC_OFFSET_MAX_NEIGHBOR,
                                  nla_get_u32);
-       FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPmaxPREQretries,
+       FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPmaxPREQretries, 0, 255,
                                  mask, NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES,
                                  nla_get_u8);
-       FILL_IN_MESH_PARAM_IF_SET(tb, cfg, path_refresh_time,
+       FILL_IN_MESH_PARAM_IF_SET(tb, cfg, path_refresh_time, 1, 65535,
                                  mask, NL80211_MESHCONF_PATH_REFRESH_TIME,
                                  nla_get_u32);
-       FILL_IN_MESH_PARAM_IF_SET(tb, cfg, min_discovery_timeout,
+       FILL_IN_MESH_PARAM_IF_SET(tb, cfg, min_discovery_timeout, 1, 65535,
                                  mask, NL80211_MESHCONF_MIN_DISCOVERY_TIMEOUT,
                                  nla_get_u16);
-       FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPactivePathTimeout, mask,
+       FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPactivePathTimeout,
+                                 1, 65535, mask,
                                  NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT,
                                  nla_get_u32);
        FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPpreqMinInterval,
-                                 mask, NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL,
+                                 1, 65535, mask,
+                                 NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL,
                                  nla_get_u16);
        FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPperrMinInterval,
-                                 mask, NL80211_MESHCONF_HWMP_PERR_MIN_INTERVAL,
+                                 1, 65535, mask,
+                                 NL80211_MESHCONF_HWMP_PERR_MIN_INTERVAL,
                                  nla_get_u16);
        FILL_IN_MESH_PARAM_IF_SET(tb, cfg,
-                                 dot11MeshHWMPnetDiameterTraversalTime, mask,
+                                 dot11MeshHWMPnetDiameterTraversalTime,
+                                 1, 65535, mask,
                                  NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME,
                                  nla_get_u16);
-       FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPRootMode, mask,
-                                 NL80211_MESHCONF_HWMP_ROOTMODE, nla_get_u8);
-       FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPRannInterval, mask,
-                                 NL80211_MESHCONF_HWMP_RANN_INTERVAL,
+       FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPRootMode, 0, 4,
+                                 mask, NL80211_MESHCONF_HWMP_ROOTMODE,
+                                 nla_get_u8);
+       FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPRannInterval, 1, 65535,
+                                 mask, NL80211_MESHCONF_HWMP_RANN_INTERVAL,
                                  nla_get_u16);
        FILL_IN_MESH_PARAM_IF_SET(tb, cfg,
-                                 dot11MeshGateAnnouncementProtocol, mask,
-                                 NL80211_MESHCONF_GATE_ANNOUNCEMENTS,
+                                 dot11MeshGateAnnouncementProtocol, 0, 1,
+                                 mask, NL80211_MESHCONF_GATE_ANNOUNCEMENTS,
                                  nla_get_u8);
-       FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshForwarding,
+       FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshForwarding, 0, 1,
                                  mask, NL80211_MESHCONF_FORWARDING,
                                  nla_get_u8);
-       FILL_IN_MESH_PARAM_IF_SET(tb, cfg, rssi_threshold,
+       FILL_IN_MESH_PARAM_IF_SET(tb, cfg, rssi_threshold, 1, 255,
                                  mask, NL80211_MESHCONF_RSSI_THRESHOLD,
                                  nla_get_u32);
-       FILL_IN_MESH_PARAM_IF_SET(tb, cfg, ht_opmode,
+       FILL_IN_MESH_PARAM_IF_SET(tb, cfg, ht_opmode, 0, 16,
                                  mask, NL80211_MESHCONF_HT_OPMODE,
                                  nla_get_u16);
        FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPactivePathToRootTimeout,
-                                 mask,
+                                 1, 65535, mask,
                                  NL80211_MESHCONF_HWMP_PATH_TO_ROOT_TIMEOUT,
                                  nla_get_u32);
-       FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMProotInterval,
+       FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMProotInterval, 1, 65535,
                                  mask, NL80211_MESHCONF_HWMP_ROOT_INTERVAL,
                                  nla_get_u16);
        FILL_IN_MESH_PARAM_IF_SET(tb, cfg,
-                                 dot11MeshHWMPconfirmationInterval, mask,
+                                 dot11MeshHWMPconfirmationInterval,
+                                 1, 65535, mask,
                                  NL80211_MESHCONF_HWMP_CONFIRMATION_INTERVAL,
                                  nla_get_u16);
+       FILL_IN_MESH_PARAM_IF_SET(tb, cfg, power_mode,
+                                 NL80211_MESH_POWER_ACTIVE,
+                                 NL80211_MESH_POWER_MAX,
+                                 mask, NL80211_MESHCONF_POWER_MODE,
+                                 nla_get_u32);
+       FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshAwakeWindowDuration,
+                                 0, 65535, mask,
+                                 NL80211_MESHCONF_AWAKE_WINDOW, nla_get_u16);
        if (mask_out)
                *mask_out = mask;
 
@@ -5875,6 +5935,15 @@ static int nl80211_connect(struct sk_buff *skb, struct genl_info *info)
                connect.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
        }
 
+       if (info->attrs[NL80211_ATTR_USE_MFP]) {
+               connect.mfp = nla_get_u32(info->attrs[NL80211_ATTR_USE_MFP]);
+               if (connect.mfp != NL80211_MFP_REQUIRED &&
+                   connect.mfp != NL80211_MFP_NO)
+                       return -EINVAL;
+       } else {
+               connect.mfp = NL80211_MFP_NO;
+       }
+
        if (info->attrs[NL80211_ATTR_WIPHY_FREQ]) {
                connect.channel =
                        ieee80211_get_channel(wiphy,
@@ -6660,6 +6729,21 @@ static int nl80211_join_mesh(struct sk_buff *skb, struct genl_info *info)
                            nla_get_u32(info->attrs[NL80211_ATTR_MCAST_RATE])))
                        return -EINVAL;
 
+       if (info->attrs[NL80211_ATTR_BEACON_INTERVAL]) {
+               setup.beacon_interval =
+                       nla_get_u32(info->attrs[NL80211_ATTR_BEACON_INTERVAL]);
+               if (setup.beacon_interval < 10 ||
+                   setup.beacon_interval > 10000)
+                       return -EINVAL;
+       }
+
+       if (info->attrs[NL80211_ATTR_DTIM_PERIOD]) {
+               setup.dtim_period =
+                       nla_get_u32(info->attrs[NL80211_ATTR_DTIM_PERIOD]);
+               if (setup.dtim_period < 1 || setup.dtim_period > 100)
+                       return -EINVAL;
+       }
+
        if (info->attrs[NL80211_ATTR_MESH_SETUP]) {
                /* parse additional setup parameters if given */
                err = nl80211_parse_mesh_setup(info, &setup);
index 8c114e8a9135517e994d3ec64d650c9f8a83fcbf..6ea626b30a2ac4dbad10901a3b2c370eb002f103 100644 (file)
@@ -1123,7 +1123,9 @@ static bool is_ht40_allowed(struct ieee80211_channel *chan)
        if (chan->flags & IEEE80211_CHAN_DISABLED)
                return false;
        /* This would happen when regulatory rules disallow HT40 completely */
-       return !(chan->flags & IEEE80211_CHAN_NO_HT40);
+       if ((chan->flags & IEEE80211_CHAN_NO_HT40) == IEEE80211_CHAN_NO_HT40)
+               return false;
+       return true;
 }
 
 static void reg_process_ht_flags_channel(struct wiphy *wiphy,
index d2d26518cdd7ba64342d5388e1cd52fbdc0cc77f..a825dfe12cf74bfad50ea500b5a96f9018a11a19 100644 (file)
@@ -192,7 +192,8 @@ static int cfg80211_conn_do_work(struct wireless_dev *wdev)
                                            prev_bssid,
                                            params->ssid, params->ssid_len,
                                            params->ie, params->ie_len,
-                                           false, &params->crypto,
+                                           params->mfp != NL80211_MFP_NO,
+                                           &params->crypto,
                                            params->flags, &params->ht_capa,
                                            &params->ht_capa_mask);
                if (err)
index 16d76a807c2fac022294aa33cb0336bb89bab38b..1c2795d52db0a9d1a6cae01e836918e788be6314 100644 (file)
@@ -1184,7 +1184,8 @@ int cfg80211_can_use_iftype_chan(struct cfg80211_registered_device *rdev,
                                 struct wireless_dev *wdev,
                                 enum nl80211_iftype iftype,
                                 struct ieee80211_channel *chan,
-                                enum cfg80211_chan_mode chanmode)
+                                enum cfg80211_chan_mode chanmode,
+                                u8 radar_detect)
 {
        struct wireless_dev *wdev_iter;
        u32 used_iftypes = BIT(iftype);
@@ -1195,14 +1196,45 @@ int cfg80211_can_use_iftype_chan(struct cfg80211_registered_device *rdev,
        enum cfg80211_chan_mode chmode;
        int num_different_channels = 0;
        int total = 1;
+       bool radar_required;
        int i, j;
 
        ASSERT_RTNL();
        lockdep_assert_held(&rdev->devlist_mtx);
 
+       if (WARN_ON(hweight32(radar_detect) > 1))
+               return -EINVAL;
+
+       switch (iftype) {
+       case NL80211_IFTYPE_ADHOC:
+       case NL80211_IFTYPE_AP:
+       case NL80211_IFTYPE_AP_VLAN:
+       case NL80211_IFTYPE_MESH_POINT:
+       case NL80211_IFTYPE_P2P_GO:
+       case NL80211_IFTYPE_WDS:
+               radar_required = !!(chan->flags & IEEE80211_CHAN_RADAR);
+               break;
+       case NL80211_IFTYPE_P2P_CLIENT:
+       case NL80211_IFTYPE_STATION:
+       case NL80211_IFTYPE_MONITOR:
+               radar_required = false;
+               break;
+       case NL80211_IFTYPE_P2P_DEVICE:
+       case NUM_NL80211_IFTYPES:
+       case NL80211_IFTYPE_UNSPECIFIED:
+       default:
+               return -EINVAL;
+       }
+
+       if (radar_required && !radar_detect)
+               return -EINVAL;
+
        /* Always allow software iftypes */
-       if (rdev->wiphy.software_iftypes & BIT(iftype))
+       if (rdev->wiphy.software_iftypes & BIT(iftype)) {
+               if (radar_detect)
+                       return -EINVAL;
                return 0;
+       }
 
        memset(num, 0, sizeof(num));
        memset(used_channels, 0, sizeof(used_channels));
@@ -1275,7 +1307,7 @@ int cfg80211_can_use_iftype_chan(struct cfg80211_registered_device *rdev,
                used_iftypes |= BIT(wdev_iter->iftype);
        }
 
-       if (total == 1)
+       if (total == 1 && !radar_detect)
                return 0;
 
        for (i = 0; i < rdev->wiphy.n_iface_combinations; i++) {
@@ -1308,6 +1340,9 @@ int cfg80211_can_use_iftype_chan(struct cfg80211_registered_device *rdev,
                        }
                }
 
+               if (radar_detect && !(c->radar_detect_widths & radar_detect))
+                       goto cont;
+
                /*
                 * Finally check that all iftypes that we're currently
                 * using are actually part of this combination. If they