mirror of
https://github.com/torvalds/linux.git
synced 2024-11-28 23:21:31 +00:00
Merge branch 'for-john' of git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next
This commit is contained in:
commit
066433a6fa
@ -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);
|
||||
}
|
||||
|
||||
/********************\
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* @skb: the frame
|
||||
*
|
||||
* Given an skb with a raw 802.11 header at the data pointer this function
|
||||
* returns the 802.11 header length.
|
||||
*
|
||||
* 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,
|
||||
|
@ -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);
|
||||
|
||||
|
@ -374,8 +374,8 @@
|
||||
* 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,
|
||||
|
@ -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))
|
||||
|
@ -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);
|
||||
|
@ -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 -
|
||||
|
@ -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
|
||||
*
|
||||
|
@ -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:
|
||||
|
@ -28,21 +28,27 @@
|
||||
#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
|
||||
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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
|
||||
|
@ -44,6 +44,10 @@
|
||||
|
||||
#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,
|
||||
|
@ -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);
|
||||
|
@ -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,
|
||||
|
@ -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, ¶ms->crypto,
|
||||
params->mfp != NL80211_MFP_NO,
|
||||
¶ms->crypto,
|
||||
params->flags, ¶ms->ht_capa,
|
||||
¶ms->ht_capa_mask);
|
||||
if (err)
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user