Commit 066433a6 authored by John W. Linville's avatar John W. Linville
parents aa3c90b8 5a32aff3
...@@ -240,13 +240,14 @@ static const struct ath_ops ath5k_common_ops = { ...@@ -240,13 +240,14 @@ static const struct ath_ops ath5k_common_ops = {
* Driver Initialization * * 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 ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
struct ath5k_hw *ah = hw->priv; struct ath5k_hw *ah = hw->priv;
struct ath_regulatory *regulatory = ath5k_hw_regulatory(ah); struct ath_regulatory *regulatory = ath5k_hw_regulatory(ah);
return ath_reg_notifier_apply(wiphy, request, regulatory); ath_reg_notifier_apply(wiphy, request, regulatory);
} }
/********************\ /********************\
......
...@@ -3492,7 +3492,7 @@ void ath6kl_cfg80211_stop_all(struct ath6kl *ar) ...@@ -3492,7 +3492,7 @@ void ath6kl_cfg80211_stop_all(struct ath6kl *ar)
ath6kl_cfg80211_stop(vif); ath6kl_cfg80211_stop(vif);
} }
static int ath6kl_cfg80211_reg_notify(struct wiphy *wiphy, static void ath6kl_cfg80211_reg_notify(struct wiphy *wiphy,
struct regulatory_request *request) struct regulatory_request *request)
{ {
struct ath6kl *ar = wiphy_priv(wiphy); struct ath6kl *ar = wiphy_priv(wiphy);
...@@ -3506,17 +3506,13 @@ static int ath6kl_cfg80211_reg_notify(struct wiphy *wiphy, ...@@ -3506,17 +3506,13 @@ static int ath6kl_cfg80211_reg_notify(struct wiphy *wiphy,
request->processed ? " processed" : "", request->processed ? " processed" : "",
request->initiator, request->user_reg_hint_type); 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) 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); ret = ath6kl_wmi_set_regdomain_cmd(ar->wmi, request->alpha2);
if (ret) { if (ret) {
ath6kl_err("failed to set regdomain: %d\n", 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, ...@@ -3536,10 +3532,8 @@ static int ath6kl_cfg80211_reg_notify(struct wiphy *wiphy,
if (ret) { if (ret) {
ath6kl_err("failed to start scan for a regdomain change: %d\n", ath6kl_err("failed to start scan for a regdomain change: %d\n",
ret); ret);
return ret; return;
} }
return 0;
} }
static int ath6kl_cfg80211_vif_init(struct ath6kl_vif *vif) static int ath6kl_cfg80211_vif_init(struct ath6kl_vif *vif)
......
...@@ -280,13 +280,13 @@ static int ath9k_init_htc_services(struct ath9k_htc_priv *priv, u16 devid, ...@@ -280,13 +280,13 @@ static int ath9k_init_htc_services(struct ath9k_htc_priv *priv, u16 devid,
return ret; return ret;
} }
static int ath9k_reg_notifier(struct wiphy *wiphy, static void ath9k_reg_notifier(struct wiphy *wiphy,
struct regulatory_request *request) struct regulatory_request *request)
{ {
struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy); struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
struct ath9k_htc_priv *priv = hw->priv; struct ath9k_htc_priv *priv = hw->priv;
return ath_reg_notifier_apply(wiphy, request, ath_reg_notifier_apply(wiphy, request,
ath9k_hw_regulatory(priv->ah)); ath9k_hw_regulatory(priv->ah));
} }
......
...@@ -303,16 +303,15 @@ static void setup_ht_cap(struct ath_softc *sc, ...@@ -303,16 +303,15 @@ static void setup_ht_cap(struct ath_softc *sc,
ht_info->mcs.tx_params |= IEEE80211_HT_MCS_TX_DEFINED; ht_info->mcs.tx_params |= IEEE80211_HT_MCS_TX_DEFINED;
} }
static int ath9k_reg_notifier(struct wiphy *wiphy, static void ath9k_reg_notifier(struct wiphy *wiphy,
struct regulatory_request *request) struct regulatory_request *request)
{ {
struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy); struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
struct ath_softc *sc = hw->priv; struct ath_softc *sc = hw->priv;
struct ath_hw *ah = sc->sc_ah; struct ath_hw *ah = sc->sc_ah;
struct ath_regulatory *reg = ath9k_hw_regulatory(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 */ /* Set tx power */
if (ah->curchan) { if (ah->curchan) {
...@@ -322,8 +321,6 @@ static int ath9k_reg_notifier(struct wiphy *wiphy, ...@@ -322,8 +321,6 @@ static int ath9k_reg_notifier(struct wiphy *wiphy,
sc->curtxpow = ath9k_hw_regulatory(ah)->power_limit; sc->curtxpow = ath9k_hw_regulatory(ah)->power_limit;
ath9k_ps_restore(sc); ath9k_ps_restore(sc);
} }
return ret;
} }
/* /*
......
...@@ -1981,13 +1981,13 @@ static int carl9170_parse_eeprom(struct ar9170 *ar) ...@@ -1981,13 +1981,13 @@ static int carl9170_parse_eeprom(struct ar9170 *ar)
return 0; return 0;
} }
static int carl9170_reg_notifier(struct wiphy *wiphy, static void carl9170_reg_notifier(struct wiphy *wiphy,
struct regulatory_request *request) struct regulatory_request *request)
{ {
struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy); struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
struct ar9170 *ar = hw->priv; 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) int carl9170_register(struct ar9170 *ar)
......
...@@ -356,7 +356,7 @@ static u16 ath_regd_find_country_by_name(char *alpha2) ...@@ -356,7 +356,7 @@ static u16 ath_regd_find_country_by_name(char *alpha2)
return -1; return -1;
} }
int ath_reg_notifier_apply(struct wiphy *wiphy, void ath_reg_notifier_apply(struct wiphy *wiphy,
struct regulatory_request *request, struct regulatory_request *request,
struct ath_regulatory *reg) struct ath_regulatory *reg)
{ {
...@@ -373,7 +373,7 @@ int ath_reg_notifier_apply(struct wiphy *wiphy, ...@@ -373,7 +373,7 @@ int ath_reg_notifier_apply(struct wiphy *wiphy,
* any pending requests in the queue. * any pending requests in the queue.
*/ */
if (!request) if (!request)
return 0; return;
switch (request->initiator) { switch (request->initiator) {
case NL80211_REGDOM_SET_BY_CORE: case NL80211_REGDOM_SET_BY_CORE:
...@@ -409,8 +409,6 @@ int ath_reg_notifier_apply(struct wiphy *wiphy, ...@@ -409,8 +409,6 @@ int ath_reg_notifier_apply(struct wiphy *wiphy,
break; break;
} }
return 0;
} }
EXPORT_SYMBOL(ath_reg_notifier_apply); EXPORT_SYMBOL(ath_reg_notifier_apply);
...@@ -500,7 +498,7 @@ ath_get_regpair(int regdmn) ...@@ -500,7 +498,7 @@ ath_get_regpair(int regdmn)
static int static int
ath_regd_init_wiphy(struct ath_regulatory *reg, ath_regd_init_wiphy(struct ath_regulatory *reg,
struct wiphy *wiphy, struct wiphy *wiphy,
int (*reg_notifier)(struct wiphy *wiphy, void (*reg_notifier)(struct wiphy *wiphy,
struct regulatory_request *request)) struct regulatory_request *request))
{ {
const struct ieee80211_regdomain *regd; const struct ieee80211_regdomain *regd;
...@@ -621,7 +619,7 @@ static int __ath_regd_init(struct ath_regulatory *reg) ...@@ -621,7 +619,7 @@ static int __ath_regd_init(struct ath_regulatory *reg)
int int
ath_regd_init(struct ath_regulatory *reg, ath_regd_init(struct ath_regulatory *reg,
struct wiphy *wiphy, struct wiphy *wiphy,
int (*reg_notifier)(struct wiphy *wiphy, void (*reg_notifier)(struct wiphy *wiphy,
struct regulatory_request *request)) struct regulatory_request *request))
{ {
struct ath_common *common = container_of(reg, struct ath_common, struct ath_common *common = container_of(reg, struct ath_common,
......
...@@ -252,11 +252,11 @@ enum CountryCode { ...@@ -252,11 +252,11 @@ enum CountryCode {
bool ath_is_world_regd(struct ath_regulatory *reg); bool ath_is_world_regd(struct ath_regulatory *reg);
bool ath_is_49ghz_allowed(u16 redomain); bool ath_is_49ghz_allowed(u16 redomain);
int ath_regd_init(struct ath_regulatory *reg, struct wiphy *wiphy, int ath_regd_init(struct ath_regulatory *reg, struct wiphy *wiphy,
int (*reg_notifier)(struct wiphy *wiphy, void (*reg_notifier)(struct wiphy *wiphy,
struct regulatory_request *request)); struct regulatory_request *request));
u32 ath_regd_get_band_ctl(struct ath_regulatory *reg, u32 ath_regd_get_band_ctl(struct ath_regulatory *reg,
enum ieee80211_band band); enum ieee80211_band band);
int ath_reg_notifier_apply(struct wiphy *wiphy, void ath_reg_notifier_apply(struct wiphy *wiphy,
struct regulatory_request *request, struct regulatory_request *request,
struct ath_regulatory *reg); struct ath_regulatory *reg);
......
...@@ -702,7 +702,7 @@ brcms_reg_apply_beaconing_flags(struct wiphy *wiphy, ...@@ -702,7 +702,7 @@ brcms_reg_apply_beaconing_flags(struct wiphy *wiphy,
} }
} }
static int brcms_reg_notifier(struct wiphy *wiphy, static void brcms_reg_notifier(struct wiphy *wiphy,
struct regulatory_request *request) struct regulatory_request *request)
{ {
struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy); struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
...@@ -744,8 +744,6 @@ static int brcms_reg_notifier(struct wiphy *wiphy, ...@@ -744,8 +744,6 @@ static int brcms_reg_notifier(struct wiphy *wiphy,
if (wlc->pub->_nbands > 1 || wlc->band->bandtype == BRCM_BAND_2G) if (wlc->pub->_nbands > 1 || wlc->band->bandtype == BRCM_BAND_2G)
wlc_phy_chanspec_ch14_widefilter_set(wlc->band->pi, wlc_phy_chanspec_ch14_widefilter_set(wlc->band->pi,
brcms_c_japan_ccode(request->alpha2)); brcms_c_japan_ccode(request->alpha2));
return 0;
} }
void brcms_c_regd_init(struct brcms_c_info *wlc) void brcms_c_regd_init(struct brcms_c_info *wlc)
......
...@@ -2132,6 +2132,21 @@ static void lbs_cfg_set_regulatory_hint(struct lbs_private *priv) ...@@ -2132,6 +2132,21 @@ static void lbs_cfg_set_regulatory_hint(struct lbs_private *priv)
lbs_deb_leave(LBS_DEB_CFG80211); 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 * This function get's called after lbs_setup_firmware() determined the
...@@ -2184,24 +2199,6 @@ int lbs_cfg_register(struct lbs_private *priv) ...@@ -2184,24 +2199,6 @@ int lbs_cfg_register(struct lbs_private *priv)
return ret; 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) void lbs_scan_deinit(struct lbs_private *priv)
{ {
lbs_deb_enter(LBS_DEB_CFG80211); lbs_deb_enter(LBS_DEB_CFG80211);
......
...@@ -10,9 +10,6 @@ struct wireless_dev *lbs_cfg_alloc(struct device *dev); ...@@ -10,9 +10,6 @@ struct wireless_dev *lbs_cfg_alloc(struct device *dev);
int lbs_cfg_register(struct lbs_private *priv); int lbs_cfg_register(struct lbs_private *priv);
void lbs_cfg_free(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_disconnect_notification(struct lbs_private *priv);
void lbs_send_mic_failureevent(struct lbs_private *priv, u32 event); void lbs_send_mic_failureevent(struct lbs_private *priv, u32 event);
......
...@@ -519,7 +519,7 @@ static int mwifiex_send_domain_info_cmd_fw(struct wiphy *wiphy) ...@@ -519,7 +519,7 @@ static int mwifiex_send_domain_info_cmd_fw(struct wiphy *wiphy)
* - Set by user * - Set by user
* - Set bt Country IE * - Set bt Country IE
*/ */
static int mwifiex_reg_notifier(struct wiphy *wiphy, static void mwifiex_reg_notifier(struct wiphy *wiphy,
struct regulatory_request *request) struct regulatory_request *request)
{ {
struct mwifiex_adapter *adapter = mwifiex_cfg80211_get_adapter(wiphy); struct mwifiex_adapter *adapter = mwifiex_cfg80211_get_adapter(wiphy);
...@@ -540,8 +540,6 @@ static int mwifiex_reg_notifier(struct wiphy *wiphy, ...@@ -540,8 +540,6 @@ static int mwifiex_reg_notifier(struct wiphy *wiphy,
break; break;
} }
mwifiex_send_domain_info_cmd_fw(wiphy); mwifiex_send_domain_info_cmd_fw(wiphy);
return 0;
} }
/* /*
......
...@@ -298,7 +298,7 @@ static void _rtl_reg_apply_world_flags(struct wiphy *wiphy, ...@@ -298,7 +298,7 @@ static void _rtl_reg_apply_world_flags(struct wiphy *wiphy,
return; return;
} }
static int _rtl_reg_notifier_apply(struct wiphy *wiphy, static void _rtl_reg_notifier_apply(struct wiphy *wiphy,
struct regulatory_request *request, struct regulatory_request *request,
struct rtl_regulatory *reg) struct rtl_regulatory *reg)
{ {
...@@ -314,8 +314,6 @@ static int _rtl_reg_notifier_apply(struct wiphy *wiphy, ...@@ -314,8 +314,6 @@ static int _rtl_reg_notifier_apply(struct wiphy *wiphy,
_rtl_reg_apply_world_flags(wiphy, request->initiator, reg); _rtl_reg_apply_world_flags(wiphy, request->initiator, reg);
break; break;
} }
return 0;
} }
static const struct ieee80211_regdomain *_rtl_regdomain_select( static const struct ieee80211_regdomain *_rtl_regdomain_select(
...@@ -348,7 +346,7 @@ static const struct ieee80211_regdomain *_rtl_regdomain_select( ...@@ -348,7 +346,7 @@ static const struct ieee80211_regdomain *_rtl_regdomain_select(
static int _rtl_regd_init_wiphy(struct rtl_regulatory *reg, static int _rtl_regd_init_wiphy(struct rtl_regulatory *reg,
struct wiphy *wiphy, struct wiphy *wiphy,
int (*reg_notifier) (struct wiphy *wiphy, void (*reg_notifier) (struct wiphy *wiphy,
struct regulatory_request * struct regulatory_request *
request)) request))
{ {
...@@ -379,7 +377,7 @@ static struct country_code_to_enum_rd *_rtl_regd_find_country(u16 countrycode) ...@@ -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 rtl_regd_init(struct ieee80211_hw *hw,
int (*reg_notifier) (struct wiphy *wiphy, void (*reg_notifier) (struct wiphy *wiphy,
struct regulatory_request *request)) struct regulatory_request *request))
{ {
struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_priv *rtlpriv = rtl_priv(hw);
...@@ -421,12 +419,12 @@ int rtl_regd_init(struct ieee80211_hw *hw, ...@@ -421,12 +419,12 @@ int rtl_regd_init(struct ieee80211_hw *hw,
return 0; 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 ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_priv *rtlpriv = rtl_priv(hw);
RT_TRACE(rtlpriv, COMP_REGD, DBG_LOUD, "\n"); 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);
} }
...@@ -55,7 +55,7 @@ enum country_code_type_t { ...@@ -55,7 +55,7 @@ enum country_code_type_t {
}; };
int rtl_regd_init(struct ieee80211_hw *hw, 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 regulatory_request *request));
int rtl_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request); void rtl_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request);
#endif #endif
...@@ -89,7 +89,7 @@ static int wl12xx_set_authorized(struct wl1271 *wl, ...@@ -89,7 +89,7 @@ static int wl12xx_set_authorized(struct wl1271 *wl,
return 0; return 0;
} }
static int wl1271_reg_notify(struct wiphy *wiphy, static void wl1271_reg_notify(struct wiphy *wiphy,
struct regulatory_request *request) struct regulatory_request *request)
{ {
struct ieee80211_supported_band *band; struct ieee80211_supported_band *band;
...@@ -107,8 +107,6 @@ static int wl1271_reg_notify(struct wiphy *wiphy, ...@@ -107,8 +107,6 @@ static int wl1271_reg_notify(struct wiphy *wiphy,
IEEE80211_CHAN_PASSIVE_SCAN; IEEE80211_CHAN_PASSIVE_SCAN;
} }
return 0;
} }
static int wl1271_set_rx_streaming(struct wl1271 *wl, struct wl12xx_vif *wlvif, static int wl1271_set_rx_streaming(struct wl1271 *wl, struct wl12xx_vif *wlvif,
......
This diff is collapsed.
This diff is collapsed.
...@@ -374,8 +374,8 @@ ...@@ -374,8 +374,8 @@
* requests to connect to a specified network but without separating * requests to connect to a specified network but without separating
* auth and assoc steps. For this, you need to specify the SSID in a * auth and assoc steps. For this, you need to specify the SSID in a
* %NL80211_ATTR_SSID attribute, and can optionally specify the association * %NL80211_ATTR_SSID attribute, and can optionally specify the association
* IEs in %NL80211_ATTR_IE, %NL80211_ATTR_AUTH_TYPE, %NL80211_ATTR_MAC, * IEs in %NL80211_ATTR_IE, %NL80211_ATTR_AUTH_TYPE, %NL80211_ATTR_USE_MFP,
* %NL80211_ATTR_WIPHY_FREQ, %NL80211_ATTR_CONTROL_PORT, * %NL80211_ATTR_MAC, %NL80211_ATTR_WIPHY_FREQ, %NL80211_ATTR_CONTROL_PORT,
* %NL80211_ATTR_CONTROL_PORT_ETHERTYPE and * %NL80211_ATTR_CONTROL_PORT_ETHERTYPE and
* %NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT. * %NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT.
* Background scan period can optionally be * Background scan period can optionally be
...@@ -958,7 +958,7 @@ enum nl80211_commands { ...@@ -958,7 +958,7 @@ enum nl80211_commands {
* @NL80211_ATTR_USE_MFP: Whether management frame protection (IEEE 802.11w) is * @NL80211_ATTR_USE_MFP: Whether management frame protection (IEEE 802.11w) is
* used for the association (&enum nl80211_mfp, represented as a u32); * used for the association (&enum nl80211_mfp, represented as a u32);
* this attribute can be used * 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 * @NL80211_ATTR_STA_FLAGS2: Attribute containing a
* &struct nl80211_sta_flag_update. * &struct nl80211_sta_flag_update.
...@@ -1310,6 +1310,9 @@ enum nl80211_commands { ...@@ -1310,6 +1310,9 @@ enum nl80211_commands {
* if not given in START_AP 0 is assumed, if not given in SET_BSS * if not given in START_AP 0 is assumed, if not given in SET_BSS
* no change is made. * 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_MAX: highest attribute number currently defined
* @__NL80211_ATTR_AFTER_LAST: internal use * @__NL80211_ATTR_AFTER_LAST: internal use
*/ */
...@@ -1580,6 +1583,8 @@ enum nl80211_attrs { ...@@ -1580,6 +1583,8 @@ enum nl80211_attrs {
NL80211_ATTR_P2P_CTWINDOW, NL80211_ATTR_P2P_CTWINDOW,
NL80211_ATTR_P2P_OPPPS, NL80211_ATTR_P2P_OPPPS,
NL80211_ATTR_LOCAL_MESH_POWER_MODE,
/* add attributes here, update the policy in nl80211.c */ /* add attributes here, update the policy in nl80211.c */
__NL80211_ATTR_AFTER_LAST, __NL80211_ATTR_AFTER_LAST,
...@@ -1838,6 +1843,10 @@ enum nl80211_sta_bss_param { ...@@ -1838,6 +1843,10 @@ enum nl80211_sta_bss_param {
* @NL80211_STA_INFO_STA_FLAGS: Contains a struct nl80211_sta_flag_update. * @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_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_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_AFTER_LAST: internal
* @NL80211_STA_INFO_MAX: highest possible station info attribute * @NL80211_STA_INFO_MAX: highest possible station info attribute
*/ */
...@@ -1862,6 +1871,9 @@ enum nl80211_sta_info { ...@@ -1862,6 +1871,9 @@ enum nl80211_sta_info {
NL80211_STA_INFO_STA_FLAGS, NL80211_STA_INFO_STA_FLAGS,
NL80211_STA_INFO_BEACON_LOSS, NL80211_STA_INFO_BEACON_LOSS,
NL80211_STA_INFO_T_OFFSET, NL80211_STA_INFO_T_OFFSET,
NL80211_STA_INFO_LOCAL_PM,
NL80211_STA_INFO_PEER_PM,
NL80211_STA_INFO_NONPEER_PM,
/* keep last */ /* keep last */
__NL80211_STA_INFO_AFTER_LAST, __NL80211_STA_INFO_AFTER_LAST,
...@@ -2252,6 +2264,34 @@ enum nl80211_mntr_flags { ...@@ -2252,6 +2264,34 @@ enum nl80211_mntr_flags {
NL80211_MNTR_FLAG_MAX = __NL80211_MNTR_FLAG_AFTER_LAST - 1 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 * enum nl80211_meshconf_params - mesh configuration parameters
* *
...@@ -2346,6 +2386,11 @@ enum nl80211_mntr_flags { ...@@ -2346,6 +2386,11 @@ enum nl80211_mntr_flags {
* (in TUs) during which a mesh STA can send only one Action frame * (in TUs) during which a mesh STA can send only one Action frame
* containing a PREQ element for root path confirmation. * 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 * @__NL80211_MESHCONF_ATTR_AFTER_LAST: internal use
*/ */
enum nl80211_meshconf_params { enum nl80211_meshconf_params {
...@@ -2375,6 +2420,8 @@ enum nl80211_meshconf_params { ...@@ -2375,6 +2420,8 @@ enum nl80211_meshconf_params {
NL80211_MESHCONF_HWMP_PATH_TO_ROOT_TIMEOUT, NL80211_MESHCONF_HWMP_PATH_TO_ROOT_TIMEOUT,
NL80211_MESHCONF_HWMP_ROOT_INTERVAL, NL80211_MESHCONF_HWMP_ROOT_INTERVAL,
NL80211_MESHCONF_HWMP_CONFIRMATION_INTERVAL, NL80211_MESHCONF_HWMP_CONFIRMATION_INTERVAL,
NL80211_MESHCONF_POWER_MODE,
NL80211_MESHCONF_AWAKE_WINDOW,
/* keep last */ /* keep last */
__NL80211_MESHCONF_ATTR_AFTER_LAST, __NL80211_MESHCONF_ATTR_AFTER_LAST,
...@@ -2937,6 +2984,8 @@ enum nl80211_iface_limit_attrs { ...@@ -2937,6 +2984,8 @@ enum nl80211_iface_limit_attrs {
* the infrastructure network's beacon interval. * the infrastructure network's beacon interval.
* @NL80211_IFACE_COMB_NUM_CHANNELS: u32 attribute specifying how many * @NL80211_IFACE_COMB_NUM_CHANNELS: u32 attribute specifying how many
* different channels may be used within this group. * 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 * @NUM_NL80211_IFACE_COMB: number of attributes
* @MAX_NL80211_IFACE_COMB: highest attribute number * @MAX_NL80211_IFACE_COMB: highest attribute number
* *
...@@ -2969,6 +3018,7 @@ enum nl80211_if_combination_attrs { ...@@ -2969,6 +3018,7 @@ enum nl80211_if_combination_attrs {
NL80211_IFACE_COMB_MAXNUM, NL80211_IFACE_COMB_MAXNUM,
NL80211_IFACE_COMB_STA_AP_BI_MATCH, NL80211_IFACE_COMB_STA_AP_BI_MATCH,
NL80211_IFACE_COMB_NUM_CHANNELS, NL80211_IFACE_COMB_NUM_CHANNELS,
NL80211_IFACE_COMB_RADAR_DETECT_WIDTHS,
/* keep last */ /* keep last */
NUM_NL80211_IFACE_COMB, NUM_NL80211_IFACE_COMB,
......
...@@ -1243,18 +1243,33 @@ static int sta_apply_parameters(struct ieee80211_local *local, ...@@ -1243,18 +1243,33 @@ static int sta_apply_parameters(struct ieee80211_local *local,
if (ieee80211_vif_is_mesh(&sdata->vif)) { if (ieee80211_vif_is_mesh(&sdata->vif)) {
#ifdef CONFIG_MAC80211_MESH #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) { switch (params->plink_state) {
case NL80211_PLINK_LISTEN:
case NL80211_PLINK_ESTAB: 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_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; sta->plink_state = params->plink_state;
break; break;
default: default:
/* nothing */ /* nothing */
break; break;
} }
else ieee80211_bss_info_change_notify(sdata, changed);
} else {
switch (params->plink_action) { switch (params->plink_action) {
case PLINK_ACTION_OPEN: case PLINK_ACTION_OPEN:
mesh_plink_open(sta); mesh_plink_open(sta);
...@@ -1263,6 +1278,7 @@ static int sta_apply_parameters(struct ieee80211_local *local, ...@@ -1263,6 +1278,7 @@ static int sta_apply_parameters(struct ieee80211_local *local,
mesh_plink_block(sta); mesh_plink_block(sta);
break; break;
} }
}
#endif #endif
} }
...@@ -1650,6 +1666,9 @@ static int copy_mesh_setup(struct ieee80211_if_mesh *ifmsh, ...@@ -1650,6 +1666,9 @@ static int copy_mesh_setup(struct ieee80211_if_mesh *ifmsh,
memcpy(sdata->vif.bss_conf.mcast_rate, setup->mcast_rate, memcpy(sdata->vif.bss_conf.mcast_rate, setup->mcast_rate,
sizeof(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; return 0;
} }
...@@ -2232,7 +2251,8 @@ static int ieee80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev, ...@@ -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_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 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; return -EOPNOTSUPP;
if (!(local->hw.flags & IEEE80211_HW_SUPPORTS_PS)) if (!(local->hw.flags & IEEE80211_HW_SUPPORTS_PS))
......
...@@ -625,7 +625,6 @@ void ieee80211_start_mesh(struct ieee80211_sub_if_data *sdata) ...@@ -625,7 +625,6 @@ void ieee80211_start_mesh(struct ieee80211_sub_if_data *sdata)
ieee80211_queue_work(&local->hw, &sdata->work); ieee80211_queue_work(&local->hw, &sdata->work);
sdata->vif.bss_conf.ht_operation_mode = sdata->vif.bss_conf.ht_operation_mode =
ifmsh->mshcfg.ht_opmode; 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.enable_beacon = true;
sdata->vif.bss_conf.basic_rates = sdata->vif.bss_conf.basic_rates =
ieee80211_mandatory_rates(local, band); ieee80211_mandatory_rates(local, band);
......
...@@ -191,8 +191,6 @@ struct mesh_rmc { ...@@ -191,8 +191,6 @@ struct mesh_rmc {
#define IEEE80211_MESH_PEER_INACTIVITY_LIMIT (1800 * HZ) #define IEEE80211_MESH_PEER_INACTIVITY_LIMIT (1800 * HZ)
#define IEEE80211_MESH_HOUSEKEEPING_INTERVAL (60 * HZ) #define IEEE80211_MESH_HOUSEKEEPING_INTERVAL (60 * HZ)
#define MESH_DEFAULT_BEACON_INTERVAL 1000 /* in 1024 us units */
#define MESH_PATH_EXPIRE (600 * HZ) #define MESH_PATH_EXPIRE (600 * HZ)
/* Default maximum number of plinks per interface */ /* Default maximum number of plinks per interface */
...@@ -307,6 +305,20 @@ extern int mesh_paths_generation; ...@@ -307,6 +305,20 @@ extern int mesh_paths_generation;
#ifdef CONFIG_MAC80211_MESH #ifdef CONFIG_MAC80211_MESH
extern int mesh_allocated; 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) static inline int mesh_plink_free_count(struct ieee80211_sub_if_data *sdata)
{ {
return sdata->u.mesh.mshcfg.dot11MeshMaxPeerLinks - return sdata->u.mesh.mshcfg.dot11MeshMaxPeerLinks -
......
...@@ -41,20 +41,6 @@ static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata, ...@@ -41,20 +41,6 @@ static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata,
enum ieee80211_self_protected_actioncode action, enum ieee80211_self_protected_actioncode action,
u8 *da, __le16 llid, __le16 plid, __le16 reason); 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 * mesh_plink_fsm_restart - restart a mesh peer link finite state machine
* *
......
...@@ -199,11 +199,11 @@ static u32 ieee80211_config_ht_tx(struct ieee80211_sub_if_data *sdata, ...@@ -199,11 +199,11 @@ static u32 ieee80211_config_ht_tx(struct ieee80211_sub_if_data *sdata,
case NL80211_CHAN_WIDTH_40: case NL80211_CHAN_WIDTH_40:
if (sdata->vif.bss_conf.chandef.chan->center_freq > if (sdata->vif.bss_conf.chandef.chan->center_freq >
sdata->vif.bss_conf.chandef.center_freq1 && sdata->vif.bss_conf.chandef.center_freq1 &&
chan->flags & IEEE80211_CHAN_NO_HT40PLUS) chan->flags & IEEE80211_CHAN_NO_HT40MINUS)
disable_40 = true; disable_40 = true;
if (sdata->vif.bss_conf.chandef.chan->center_freq < if (sdata->vif.bss_conf.chandef.chan->center_freq <
sdata->vif.bss_conf.chandef.center_freq1 && sdata->vif.bss_conf.chandef.center_freq1 &&
chan->flags & IEEE80211_CHAN_NO_HT40MINUS) chan->flags & IEEE80211_CHAN_NO_HT40PLUS)
disable_40 = true; disable_40 = true;
break; break;
default: default:
......
...@@ -28,21 +28,27 @@ ...@@ -28,21 +28,27 @@
#define VIF_PR_FMT " vif:%s(%d%s)" #define VIF_PR_FMT " vif:%s(%d%s)"
#define VIF_PR_ARG __get_str(vif_name), __entry->vif_type, __entry->p2p ? "/p2p" : "" #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, chan_width) \
__field(u32, center_freq1) \ __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_static) \
__field(u8, rx_chains_dynamic) __field(u8, rx_chains_dynamic)
#define CHANCTX_ASSIGN __entry->control_freq = ctx->conf.def.chan->center_freq;\ #define CHANCTX_ASSIGN CHANDEF_ASSIGN(&ctx->conf.def) \
__entry->chan_width = ctx->conf.def.width; \
__entry->center_freq1 = ctx->conf.def.center_freq1; \
__entry->center_freq2 = ctx->conf.def.center_freq2; \
__entry->rx_chains_static = ctx->conf.rx_chains_static; \ __entry->rx_chains_static = ctx->conf.rx_chains_static; \
__entry->rx_chains_dynamic = ctx->conf.rx_chains_dynamic __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_FMT CHANDEF_PR_FMT " chains:%d/%d"
#define CHANCTX_PR_ARG __entry->control_freq, __entry->chan_width, \ #define CHANCTX_PR_ARG CHANDEF_PR_ARG, \
__entry->center_freq1, __entry->center_freq2, \
__entry->rx_chains_static, __entry->rx_chains_dynamic __entry->rx_chains_static, __entry->rx_chains_dynamic
......
...@@ -2261,9 +2261,8 @@ void ieee80211_tx_pending(unsigned long data) ...@@ -2261,9 +2261,8 @@ void ieee80211_tx_pending(unsigned long data)
/* functions for drivers to get certain frames */ /* functions for drivers to get certain frames */
static void ieee80211_beacon_add_tim(struct ieee80211_sub_if_data *sdata, static void __ieee80211_beacon_add_tim(struct ieee80211_sub_if_data *sdata,
struct ps_data *ps, struct ps_data *ps, struct sk_buff *skb)
struct sk_buff *skb)
{ {
u8 *pos, *tim; u8 *pos, *tim;
int aid0 = 0; int aid0 = 0;
...@@ -2325,6 +2324,31 @@ static void ieee80211_beacon_add_tim(struct ieee80211_sub_if_data *sdata, ...@@ -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 sk_buff *ieee80211_beacon_get_tim(struct ieee80211_hw *hw,
struct ieee80211_vif *vif, struct ieee80211_vif *vif,
u16 *tim_offset, u16 *tim_length) u16 *tim_offset, u16 *tim_length)
...@@ -2369,22 +2393,7 @@ struct sk_buff *ieee80211_beacon_get_tim(struct ieee80211_hw *hw, ...@@ -2369,22 +2393,7 @@ struct sk_buff *ieee80211_beacon_get_tim(struct ieee80211_hw *hw,
memcpy(skb_put(skb, beacon->head_len), beacon->head, memcpy(skb_put(skb, beacon->head_len), beacon->head,
beacon->head_len); 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); ieee80211_beacon_add_tim(sdata, &ap->ps, skb);
spin_unlock_irqrestore(&local->tim_lock, flags);
}
if (tim_offset) if (tim_offset)
*tim_offset = beacon->head_len; *tim_offset = beacon->head_len;
......
...@@ -1358,6 +1358,7 @@ int ieee80211_reconfig(struct ieee80211_local *local) ...@@ -1358,6 +1358,7 @@ int ieee80211_reconfig(struct ieee80211_local *local)
struct ieee80211_chanctx *ctx; struct ieee80211_chanctx *ctx;
struct sta_info *sta; struct sta_info *sta;
int res, i; int res, i;
bool reconfig_due_to_wowlan = false;
#ifdef CONFIG_PM #ifdef CONFIG_PM
if (local->suspended) if (local->suspended)
...@@ -1377,6 +1378,7 @@ int ieee80211_reconfig(struct ieee80211_local *local) ...@@ -1377,6 +1378,7 @@ int ieee80211_reconfig(struct ieee80211_local *local)
* res is 1, which means the driver requested * res is 1, which means the driver requested
* to go through a regular reset on wakeup. * to go through a regular reset on wakeup.
*/ */
reconfig_due_to_wowlan = true;
} }
#endif #endif
/* everything else happens only if HW was up & running */ /* everything else happens only if HW was up & running */
...@@ -1527,7 +1529,7 @@ int ieee80211_reconfig(struct ieee80211_local *local) ...@@ -1527,7 +1529,7 @@ int ieee80211_reconfig(struct ieee80211_local *local)
BSS_CHANGED_TXPOWER; BSS_CHANGED_TXPOWER;
#ifdef CONFIG_PM #ifdef CONFIG_PM
if (local->resuming) if (local->resuming && !reconfig_due_to_wowlan)
sdata->vif.bss_conf = sdata->suspend_bss_conf; sdata->vif.bss_conf = sdata->suspend_bss_conf;
#endif #endif
...@@ -1654,10 +1656,11 @@ int ieee80211_reconfig(struct ieee80211_local *local) ...@@ -1654,10 +1656,11 @@ int ieee80211_reconfig(struct ieee80211_local *local)
* If this is for hw restart things are still running. * If this is for hw restart things are still running.
* We may want to change that later, however. * We may want to change that later, however.
*/ */
if (!local->suspended) { if (!local->suspended || reconfig_due_to_wowlan)
drv_restart_complete(local); drv_restart_complete(local);
if (!local->suspended)
return 0; return 0;
}
#ifdef CONFIG_PM #ifdef CONFIG_PM
/* first set suspended false, then resuming */ /* first set suspended false, then resuming */
......
...@@ -382,8 +382,11 @@ static int wiphy_verify_combinations(struct wiphy *wiphy) ...@@ -382,8 +382,11 @@ static int wiphy_verify_combinations(struct wiphy *wiphy)
c = &wiphy->iface_combinations[i]; 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; return -EINVAL;
/* Need at least one channel */ /* Need at least one channel */
...@@ -398,6 +401,11 @@ static int wiphy_verify_combinations(struct wiphy *wiphy) ...@@ -398,6 +401,11 @@ static int wiphy_verify_combinations(struct wiphy *wiphy)
CFG80211_MAX_NUM_DIFFERENT_CHANNELS)) CFG80211_MAX_NUM_DIFFERENT_CHANNELS))
return -EINVAL; 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)) if (WARN_ON(!c->n_limits))
return -EINVAL; return -EINVAL;
......
...@@ -425,7 +425,8 @@ int cfg80211_can_use_iftype_chan(struct cfg80211_registered_device *rdev, ...@@ -425,7 +425,8 @@ int cfg80211_can_use_iftype_chan(struct cfg80211_registered_device *rdev,
struct wireless_dev *wdev, struct wireless_dev *wdev,
enum nl80211_iftype iftype, enum nl80211_iftype iftype,
struct ieee80211_channel *chan, struct ieee80211_channel *chan,
enum cfg80211_chan_mode chanmode); enum cfg80211_chan_mode chanmode,
u8 radar_detect);
static inline int static inline int
cfg80211_can_change_interface(struct cfg80211_registered_device *rdev, cfg80211_can_change_interface(struct cfg80211_registered_device *rdev,
...@@ -433,7 +434,7 @@ 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) enum nl80211_iftype iftype)
{ {
return cfg80211_can_use_iftype_chan(rdev, wdev, iftype, NULL, return cfg80211_can_use_iftype_chan(rdev, wdev, iftype, NULL,
CHAN_MODE_UNDEFINED); CHAN_MODE_UNDEFINED, 0);
} }
static inline int static inline int
...@@ -450,7 +451,7 @@ cfg80211_can_use_chan(struct cfg80211_registered_device *rdev, ...@@ -450,7 +451,7 @@ cfg80211_can_use_chan(struct cfg80211_registered_device *rdev,
enum cfg80211_chan_mode chanmode) enum cfg80211_chan_mode chanmode)
{ {
return cfg80211_can_use_iftype_chan(rdev, wdev, wdev->iftype, return cfg80211_can_use_iftype_chan(rdev, wdev, wdev->iftype,
chan, chanmode); chan, chanmode, 0);
} }
void void
......
...@@ -44,6 +44,10 @@ ...@@ -44,6 +44,10 @@
#define MESH_SYNC_NEIGHBOR_OFFSET_MAX 50 #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 = { const struct mesh_config default_mesh_config = {
.dot11MeshRetryTimeout = MESH_RET_T, .dot11MeshRetryTimeout = MESH_RET_T,
.dot11MeshConfirmTimeout = MESH_CONF_T, .dot11MeshConfirmTimeout = MESH_CONF_T,
...@@ -69,6 +73,8 @@ const struct mesh_config default_mesh_config = { ...@@ -69,6 +73,8 @@ const struct mesh_config default_mesh_config = {
.dot11MeshHWMPactivePathToRootTimeout = MESH_PATH_TO_ROOT_TIMEOUT, .dot11MeshHWMPactivePathToRootTimeout = MESH_PATH_TO_ROOT_TIMEOUT,
.dot11MeshHWMProotInterval = MESH_ROOT_INTERVAL, .dot11MeshHWMProotInterval = MESH_ROOT_INTERVAL,
.dot11MeshHWMPconfirmationInterval = MESH_ROOT_CONFIRMATION_INTERVAL, .dot11MeshHWMPconfirmationInterval = MESH_ROOT_CONFIRMATION_INTERVAL,
.power_mode = NL80211_MESH_POWER_ACTIVE,
.dot11MeshAwakeWindowDuration = MESH_DEFAULT_AWAKE_WINDOW,
}; };
const struct mesh_setup default_mesh_setup = { const struct mesh_setup default_mesh_setup = {
...@@ -79,6 +85,8 @@ const struct mesh_setup default_mesh_setup = { ...@@ -79,6 +85,8 @@ const struct mesh_setup default_mesh_setup = {
.ie = NULL, .ie = NULL,
.ie_len = 0, .ie_len = 0,
.is_secure = false, .is_secure = false,
.beacon_interval = MESH_DEFAULT_BEACON_INTERVAL,
.dtim_period = MESH_DEFAULT_DTIM_PERIOD,
}; };
int __cfg80211_join_mesh(struct cfg80211_registered_device *rdev, int __cfg80211_join_mesh(struct cfg80211_registered_device *rdev,
......
This diff is collapsed.
...@@ -1123,7 +1123,9 @@ static bool is_ht40_allowed(struct ieee80211_channel *chan) ...@@ -1123,7 +1123,9 @@ static bool is_ht40_allowed(struct ieee80211_channel *chan)
if (chan->flags & IEEE80211_CHAN_DISABLED) if (chan->flags & IEEE80211_CHAN_DISABLED)
return false; return false;
/* This would happen when regulatory rules disallow HT40 completely */ /* 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, static void reg_process_ht_flags_channel(struct wiphy *wiphy,
......
...@@ -192,7 +192,8 @@ static int cfg80211_conn_do_work(struct wireless_dev *wdev) ...@@ -192,7 +192,8 @@ static int cfg80211_conn_do_work(struct wireless_dev *wdev)
prev_bssid, prev_bssid,
params->ssid, params->ssid_len, params->ssid, params->ssid_len,
params->ie, params->ie_len, params->ie, params->ie_len,
false, &params->crypto, params->mfp != NL80211_MFP_NO,
&params->crypto,
params->flags, &params->ht_capa, params->flags, &params->ht_capa,
&params->ht_capa_mask); &params->ht_capa_mask);
if (err) if (err)
......
...@@ -1184,7 +1184,8 @@ int cfg80211_can_use_iftype_chan(struct cfg80211_registered_device *rdev, ...@@ -1184,7 +1184,8 @@ int cfg80211_can_use_iftype_chan(struct cfg80211_registered_device *rdev,
struct wireless_dev *wdev, struct wireless_dev *wdev,
enum nl80211_iftype iftype, enum nl80211_iftype iftype,
struct ieee80211_channel *chan, struct ieee80211_channel *chan,
enum cfg80211_chan_mode chanmode) enum cfg80211_chan_mode chanmode,
u8 radar_detect)
{ {
struct wireless_dev *wdev_iter; struct wireless_dev *wdev_iter;
u32 used_iftypes = BIT(iftype); u32 used_iftypes = BIT(iftype);
...@@ -1195,14 +1196,45 @@ int cfg80211_can_use_iftype_chan(struct cfg80211_registered_device *rdev, ...@@ -1195,14 +1196,45 @@ int cfg80211_can_use_iftype_chan(struct cfg80211_registered_device *rdev,
enum cfg80211_chan_mode chmode; enum cfg80211_chan_mode chmode;
int num_different_channels = 0; int num_different_channels = 0;
int total = 1; int total = 1;
bool radar_required;
int i, j; int i, j;
ASSERT_RTNL(); ASSERT_RTNL();
lockdep_assert_held(&rdev->devlist_mtx); 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 */ /* 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; return 0;
}
memset(num, 0, sizeof(num)); memset(num, 0, sizeof(num));
memset(used_channels, 0, sizeof(used_channels)); memset(used_channels, 0, sizeof(used_channels));
...@@ -1275,7 +1307,7 @@ int cfg80211_can_use_iftype_chan(struct cfg80211_registered_device *rdev, ...@@ -1275,7 +1307,7 @@ int cfg80211_can_use_iftype_chan(struct cfg80211_registered_device *rdev,
used_iftypes |= BIT(wdev_iter->iftype); used_iftypes |= BIT(wdev_iter->iftype);
} }
if (total == 1) if (total == 1 && !radar_detect)
return 0; return 0;
for (i = 0; i < rdev->wiphy.n_iface_combinations; i++) { 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, ...@@ -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 * Finally check that all iftypes that we're currently
* using are actually part of this combination. If they * using are actually part of this combination. If they
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment