Loading include/linux/ieee80211.h +2 −2 Original line number Diff line number Diff line Loading @@ -1391,8 +1391,8 @@ struct ieee80211_vht_operation { #define IEEE80211_VHT_CAP_RXSTBC_MASK 0x00000700 #define IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE 0x00000800 #define IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE 0x00001000 #define IEEE80211_VHT_CAP_BEAMFORMER_ANTENNAS_MAX 0x00006000 #define IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_MAX 0x00030000 #define IEEE80211_VHT_CAP_BEAMFORMEE_STS_MAX 0x0000e000 #define IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_MAX 0x00070000 #define IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE 0x00080000 #define IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE 0x00100000 #define IEEE80211_VHT_CAP_VHT_TXOP_PS 0x00200000 Loading include/net/cfg80211.h +9 −0 Original line number Diff line number Diff line Loading @@ -436,6 +436,15 @@ bool cfg80211_chandef_usable(struct wiphy *wiphy, const struct cfg80211_chan_def *chandef, u32 prohibited_flags); /** * cfg80211_chandef_dfs_required - checks if radar detection is required * @wiphy: the wiphy to validate against * @chandef: the channel definition to check * Return: 1 if radar detection is required, 0 if it is not, < 0 on error */ int cfg80211_chandef_dfs_required(struct wiphy *wiphy, const struct cfg80211_chan_def *chandef); /** * ieee80211_chandef_rate_flags - returns rate flags for a channel * Loading include/net/mac80211.h +42 −0 Original line number Diff line number Diff line Loading @@ -829,6 +829,15 @@ ieee80211_tx_info_clear_status(struct ieee80211_tx_info *info) * @RX_FLAG_STBC_MASK: STBC 2 bit bitmask. 1 - Nss=1, 2 - Nss=2, 3 - Nss=3 * @RX_FLAG_10MHZ: 10 MHz (half channel) was used * @RX_FLAG_5MHZ: 5 MHz (quarter channel) was used * @RX_FLAG_AMSDU_MORE: Some drivers may prefer to report separate A-MSDU * subframes instead of a one huge frame for performance reasons. * All, but the last MSDU from an A-MSDU should have this flag set. E.g. * if an A-MSDU has 3 frames, the first 2 must have the flag set, while * the 3rd (last) one must not have this flag set. The flag is used to * deal with retransmission/duplication recovery properly since A-MSDU * subframes share the same sequence number. Reported subframes can be * either regular MSDU or singly A-MSDUs. Subframes must not be * interleaved with other frames. */ enum mac80211_rx_flags { RX_FLAG_MMIC_ERROR = BIT(0), Loading Loading @@ -859,6 +868,7 @@ enum mac80211_rx_flags { RX_FLAG_STBC_MASK = BIT(26) | BIT(27), RX_FLAG_10MHZ = BIT(28), RX_FLAG_5MHZ = BIT(29), RX_FLAG_AMSDU_MORE = BIT(30), }; #define RX_FLAG_STBC_SHIFT 26 Loading Loading @@ -1492,6 +1502,11 @@ struct ieee80211_tx_control { * * @IEEE80211_HW_TIMING_BEACON_ONLY: Use sync timing from beacon frames * only, to allow getting TBTT of a DTIM beacon. * * @IEEE80211_HW_CHANCTX_STA_CSA: Support 802.11h based channel-switch (CSA) * for a single active channel while using channel contexts. When support * is not enabled the default action is to disconnect when getting the * CSA frame. */ enum ieee80211_hw_flags { IEEE80211_HW_HAS_RATE_CONTROL = 1<<0, Loading Loading @@ -1522,6 +1537,7 @@ enum ieee80211_hw_flags { IEEE80211_HW_P2P_DEV_ADDR_FOR_INTF = 1<<25, IEEE80211_HW_TIMING_BEACON_ONLY = 1<<26, IEEE80211_HW_SUPPORTS_HT_CCK_RATES = 1<<27, IEEE80211_HW_CHANCTX_STA_CSA = 1<<28, }; /** Loading Loading @@ -2666,6 +2682,10 @@ enum ieee80211_roc_type { * zero using ieee80211_csa_is_complete() after the beacon has been * transmitted and then call ieee80211_csa_finish(). * * @join_ibss: Join an IBSS (on an IBSS interface); this is called after all * information in bss_conf is set up and the beacon can be retrieved. A * channel context is bound before this is called. * @leave_ibss: Leave the IBSS again. */ struct ieee80211_ops { void (*tx)(struct ieee80211_hw *hw, Loading Loading @@ -2857,6 +2877,9 @@ struct ieee80211_ops { void (*channel_switch_beacon)(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct cfg80211_chan_def *chandef); int (*join_ibss)(struct ieee80211_hw *hw, struct ieee80211_vif *vif); void (*leave_ibss)(struct ieee80211_hw *hw, struct ieee80211_vif *vif); }; /** Loading Loading @@ -3919,6 +3942,25 @@ void ieee80211_iterate_active_interfaces_atomic(struct ieee80211_hw *hw, struct ieee80211_vif *vif), void *data); /** * ieee80211_iterate_active_interfaces_rtnl - iterate active interfaces * * This function iterates over the interfaces associated with a given * hardware that are currently active and calls the callback for them. * This version can only be used while holding the RTNL. * * @hw: the hardware struct of which the interfaces should be iterated over * @iter_flags: iteration flags, see &enum ieee80211_interface_iteration_flags * @iterator: the iterator function to call, cannot sleep * @data: first argument of the iterator function */ void ieee80211_iterate_active_interfaces_rtnl(struct ieee80211_hw *hw, u32 iter_flags, void (*iterator)(void *data, u8 *mac, struct ieee80211_vif *vif), void *data); /** * ieee80211_queue_work - add work onto the mac80211 workqueue * Loading net/mac80211/cfg.c +69 −23 Original line number Diff line number Diff line Loading @@ -2865,30 +2865,43 @@ void ieee80211_csa_finalize_work(struct work_struct *work) if (!ieee80211_sdata_running(sdata)) return; if (WARN_ON(sdata->vif.type != NL80211_IFTYPE_AP)) return; sdata->radar_required = sdata->csa_radar_required; err = ieee80211_vif_change_channel(sdata, &local->csa_chandef, &changed); if (WARN_ON(err < 0)) return; if (!local->use_chanctx) { local->_oper_chandef = local->csa_chandef; ieee80211_hw_config(local, 0); } ieee80211_bss_info_change_notify(sdata, changed); switch (sdata->vif.type) { case NL80211_IFTYPE_AP: err = ieee80211_assign_beacon(sdata, sdata->u.ap.next_beacon); if (err < 0) return; changed |= err; kfree(sdata->u.ap.next_beacon); sdata->u.ap.next_beacon = NULL; ieee80211_bss_info_change_notify(sdata, err); break; case NL80211_IFTYPE_ADHOC: ieee80211_ibss_finish_csa(sdata); break; default: WARN_ON(1); return; } sdata->vif.csa_active = false; ieee80211_wake_queues_by_reason(&sdata->local->hw, IEEE80211_MAX_QUEUE_MAP, IEEE80211_QUEUE_STOP_REASON_CSA); ieee80211_bss_info_change_notify(sdata, changed); cfg80211_ch_switch_notify(sdata->dev, &local->csa_chandef); } Loading Loading @@ -2936,20 +2949,56 @@ static int ieee80211_channel_switch(struct wiphy *wiphy, struct net_device *dev, if (sdata->vif.csa_active) return -EBUSY; /* only handle AP for now. */ switch (sdata->vif.type) { case NL80211_IFTYPE_AP: sdata->csa_counter_offset_beacon = params->counter_offset_beacon; sdata->csa_counter_offset_presp = params->counter_offset_presp; sdata->u.ap.next_beacon = cfg80211_beacon_dup(¶ms->beacon_after); if (!sdata->u.ap.next_beacon) return -ENOMEM; err = ieee80211_assign_beacon(sdata, ¶ms->beacon_csa); if (err < 0) { kfree(sdata->u.ap.next_beacon); return err; } break; case NL80211_IFTYPE_ADHOC: if (!sdata->vif.bss_conf.ibss_joined) return -EINVAL; if (params->chandef.width != sdata->u.ibss.chandef.width) return -EINVAL; switch (params->chandef.width) { case NL80211_CHAN_WIDTH_40: if (cfg80211_get_chandef_type(¶ms->chandef) != cfg80211_get_chandef_type(&sdata->u.ibss.chandef)) return -EINVAL; case NL80211_CHAN_WIDTH_5: case NL80211_CHAN_WIDTH_10: case NL80211_CHAN_WIDTH_20_NOHT: case NL80211_CHAN_WIDTH_20: break; default: return -EOPNOTSUPP; return -EINVAL; } sdata->u.ap.next_beacon = cfg80211_beacon_dup(¶ms->beacon_after); if (!sdata->u.ap.next_beacon) return -ENOMEM; /* changes into another band are not supported */ if (sdata->u.ibss.chandef.chan->band != params->chandef.chan->band) return -EINVAL; err = ieee80211_ibss_csa_beacon(sdata, params); if (err < 0) return err; break; default: return -EOPNOTSUPP; } sdata->csa_counter_offset_beacon = params->counter_offset_beacon; sdata->csa_counter_offset_presp = params->counter_offset_presp; sdata->csa_radar_required = params->radar_required; if (params->block_tx) Loading @@ -2957,10 +3006,6 @@ static int ieee80211_channel_switch(struct wiphy *wiphy, struct net_device *dev, IEEE80211_MAX_QUEUE_MAP, IEEE80211_QUEUE_STOP_REASON_CSA); err = ieee80211_assign_beacon(sdata, ¶ms->beacon_csa); if (err < 0) return err; local->csa_chandef = params->chandef; sdata->vif.csa_active = true; Loading Loading @@ -3014,7 +3059,8 @@ static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev, need_offchan = true; if (!ieee80211_is_action(mgmt->frame_control) || mgmt->u.action.category == WLAN_CATEGORY_PUBLIC || mgmt->u.action.category == WLAN_CATEGORY_SELF_PROTECTED) mgmt->u.action.category == WLAN_CATEGORY_SELF_PROTECTED || mgmt->u.action.category == WLAN_CATEGORY_SPECTRUM_MGMT) break; rcu_read_lock(); sta = sta_info_get(sdata, mgmt->da); Loading net/mac80211/chan.c +0 −5 Original line number Diff line number Diff line Loading @@ -453,11 +453,6 @@ int ieee80211_vif_change_channel(struct ieee80211_sub_if_data *sdata, chanctx_changed |= IEEE80211_CHANCTX_CHANGE_CHANNEL; drv_change_chanctx(local, ctx, chanctx_changed); if (!local->use_chanctx) { local->_oper_chandef = *chandef; ieee80211_hw_config(local, 0); } ieee80211_recalc_chanctx_chantype(local, ctx); ieee80211_recalc_smps_chanctx(local, ctx); ieee80211_recalc_radar_chanctx(local, ctx); Loading Loading
include/linux/ieee80211.h +2 −2 Original line number Diff line number Diff line Loading @@ -1391,8 +1391,8 @@ struct ieee80211_vht_operation { #define IEEE80211_VHT_CAP_RXSTBC_MASK 0x00000700 #define IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE 0x00000800 #define IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE 0x00001000 #define IEEE80211_VHT_CAP_BEAMFORMER_ANTENNAS_MAX 0x00006000 #define IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_MAX 0x00030000 #define IEEE80211_VHT_CAP_BEAMFORMEE_STS_MAX 0x0000e000 #define IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_MAX 0x00070000 #define IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE 0x00080000 #define IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE 0x00100000 #define IEEE80211_VHT_CAP_VHT_TXOP_PS 0x00200000 Loading
include/net/cfg80211.h +9 −0 Original line number Diff line number Diff line Loading @@ -436,6 +436,15 @@ bool cfg80211_chandef_usable(struct wiphy *wiphy, const struct cfg80211_chan_def *chandef, u32 prohibited_flags); /** * cfg80211_chandef_dfs_required - checks if radar detection is required * @wiphy: the wiphy to validate against * @chandef: the channel definition to check * Return: 1 if radar detection is required, 0 if it is not, < 0 on error */ int cfg80211_chandef_dfs_required(struct wiphy *wiphy, const struct cfg80211_chan_def *chandef); /** * ieee80211_chandef_rate_flags - returns rate flags for a channel * Loading
include/net/mac80211.h +42 −0 Original line number Diff line number Diff line Loading @@ -829,6 +829,15 @@ ieee80211_tx_info_clear_status(struct ieee80211_tx_info *info) * @RX_FLAG_STBC_MASK: STBC 2 bit bitmask. 1 - Nss=1, 2 - Nss=2, 3 - Nss=3 * @RX_FLAG_10MHZ: 10 MHz (half channel) was used * @RX_FLAG_5MHZ: 5 MHz (quarter channel) was used * @RX_FLAG_AMSDU_MORE: Some drivers may prefer to report separate A-MSDU * subframes instead of a one huge frame for performance reasons. * All, but the last MSDU from an A-MSDU should have this flag set. E.g. * if an A-MSDU has 3 frames, the first 2 must have the flag set, while * the 3rd (last) one must not have this flag set. The flag is used to * deal with retransmission/duplication recovery properly since A-MSDU * subframes share the same sequence number. Reported subframes can be * either regular MSDU or singly A-MSDUs. Subframes must not be * interleaved with other frames. */ enum mac80211_rx_flags { RX_FLAG_MMIC_ERROR = BIT(0), Loading Loading @@ -859,6 +868,7 @@ enum mac80211_rx_flags { RX_FLAG_STBC_MASK = BIT(26) | BIT(27), RX_FLAG_10MHZ = BIT(28), RX_FLAG_5MHZ = BIT(29), RX_FLAG_AMSDU_MORE = BIT(30), }; #define RX_FLAG_STBC_SHIFT 26 Loading Loading @@ -1492,6 +1502,11 @@ struct ieee80211_tx_control { * * @IEEE80211_HW_TIMING_BEACON_ONLY: Use sync timing from beacon frames * only, to allow getting TBTT of a DTIM beacon. * * @IEEE80211_HW_CHANCTX_STA_CSA: Support 802.11h based channel-switch (CSA) * for a single active channel while using channel contexts. When support * is not enabled the default action is to disconnect when getting the * CSA frame. */ enum ieee80211_hw_flags { IEEE80211_HW_HAS_RATE_CONTROL = 1<<0, Loading Loading @@ -1522,6 +1537,7 @@ enum ieee80211_hw_flags { IEEE80211_HW_P2P_DEV_ADDR_FOR_INTF = 1<<25, IEEE80211_HW_TIMING_BEACON_ONLY = 1<<26, IEEE80211_HW_SUPPORTS_HT_CCK_RATES = 1<<27, IEEE80211_HW_CHANCTX_STA_CSA = 1<<28, }; /** Loading Loading @@ -2666,6 +2682,10 @@ enum ieee80211_roc_type { * zero using ieee80211_csa_is_complete() after the beacon has been * transmitted and then call ieee80211_csa_finish(). * * @join_ibss: Join an IBSS (on an IBSS interface); this is called after all * information in bss_conf is set up and the beacon can be retrieved. A * channel context is bound before this is called. * @leave_ibss: Leave the IBSS again. */ struct ieee80211_ops { void (*tx)(struct ieee80211_hw *hw, Loading Loading @@ -2857,6 +2877,9 @@ struct ieee80211_ops { void (*channel_switch_beacon)(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct cfg80211_chan_def *chandef); int (*join_ibss)(struct ieee80211_hw *hw, struct ieee80211_vif *vif); void (*leave_ibss)(struct ieee80211_hw *hw, struct ieee80211_vif *vif); }; /** Loading Loading @@ -3919,6 +3942,25 @@ void ieee80211_iterate_active_interfaces_atomic(struct ieee80211_hw *hw, struct ieee80211_vif *vif), void *data); /** * ieee80211_iterate_active_interfaces_rtnl - iterate active interfaces * * This function iterates over the interfaces associated with a given * hardware that are currently active and calls the callback for them. * This version can only be used while holding the RTNL. * * @hw: the hardware struct of which the interfaces should be iterated over * @iter_flags: iteration flags, see &enum ieee80211_interface_iteration_flags * @iterator: the iterator function to call, cannot sleep * @data: first argument of the iterator function */ void ieee80211_iterate_active_interfaces_rtnl(struct ieee80211_hw *hw, u32 iter_flags, void (*iterator)(void *data, u8 *mac, struct ieee80211_vif *vif), void *data); /** * ieee80211_queue_work - add work onto the mac80211 workqueue * Loading
net/mac80211/cfg.c +69 −23 Original line number Diff line number Diff line Loading @@ -2865,30 +2865,43 @@ void ieee80211_csa_finalize_work(struct work_struct *work) if (!ieee80211_sdata_running(sdata)) return; if (WARN_ON(sdata->vif.type != NL80211_IFTYPE_AP)) return; sdata->radar_required = sdata->csa_radar_required; err = ieee80211_vif_change_channel(sdata, &local->csa_chandef, &changed); if (WARN_ON(err < 0)) return; if (!local->use_chanctx) { local->_oper_chandef = local->csa_chandef; ieee80211_hw_config(local, 0); } ieee80211_bss_info_change_notify(sdata, changed); switch (sdata->vif.type) { case NL80211_IFTYPE_AP: err = ieee80211_assign_beacon(sdata, sdata->u.ap.next_beacon); if (err < 0) return; changed |= err; kfree(sdata->u.ap.next_beacon); sdata->u.ap.next_beacon = NULL; ieee80211_bss_info_change_notify(sdata, err); break; case NL80211_IFTYPE_ADHOC: ieee80211_ibss_finish_csa(sdata); break; default: WARN_ON(1); return; } sdata->vif.csa_active = false; ieee80211_wake_queues_by_reason(&sdata->local->hw, IEEE80211_MAX_QUEUE_MAP, IEEE80211_QUEUE_STOP_REASON_CSA); ieee80211_bss_info_change_notify(sdata, changed); cfg80211_ch_switch_notify(sdata->dev, &local->csa_chandef); } Loading Loading @@ -2936,20 +2949,56 @@ static int ieee80211_channel_switch(struct wiphy *wiphy, struct net_device *dev, if (sdata->vif.csa_active) return -EBUSY; /* only handle AP for now. */ switch (sdata->vif.type) { case NL80211_IFTYPE_AP: sdata->csa_counter_offset_beacon = params->counter_offset_beacon; sdata->csa_counter_offset_presp = params->counter_offset_presp; sdata->u.ap.next_beacon = cfg80211_beacon_dup(¶ms->beacon_after); if (!sdata->u.ap.next_beacon) return -ENOMEM; err = ieee80211_assign_beacon(sdata, ¶ms->beacon_csa); if (err < 0) { kfree(sdata->u.ap.next_beacon); return err; } break; case NL80211_IFTYPE_ADHOC: if (!sdata->vif.bss_conf.ibss_joined) return -EINVAL; if (params->chandef.width != sdata->u.ibss.chandef.width) return -EINVAL; switch (params->chandef.width) { case NL80211_CHAN_WIDTH_40: if (cfg80211_get_chandef_type(¶ms->chandef) != cfg80211_get_chandef_type(&sdata->u.ibss.chandef)) return -EINVAL; case NL80211_CHAN_WIDTH_5: case NL80211_CHAN_WIDTH_10: case NL80211_CHAN_WIDTH_20_NOHT: case NL80211_CHAN_WIDTH_20: break; default: return -EOPNOTSUPP; return -EINVAL; } sdata->u.ap.next_beacon = cfg80211_beacon_dup(¶ms->beacon_after); if (!sdata->u.ap.next_beacon) return -ENOMEM; /* changes into another band are not supported */ if (sdata->u.ibss.chandef.chan->band != params->chandef.chan->band) return -EINVAL; err = ieee80211_ibss_csa_beacon(sdata, params); if (err < 0) return err; break; default: return -EOPNOTSUPP; } sdata->csa_counter_offset_beacon = params->counter_offset_beacon; sdata->csa_counter_offset_presp = params->counter_offset_presp; sdata->csa_radar_required = params->radar_required; if (params->block_tx) Loading @@ -2957,10 +3006,6 @@ static int ieee80211_channel_switch(struct wiphy *wiphy, struct net_device *dev, IEEE80211_MAX_QUEUE_MAP, IEEE80211_QUEUE_STOP_REASON_CSA); err = ieee80211_assign_beacon(sdata, ¶ms->beacon_csa); if (err < 0) return err; local->csa_chandef = params->chandef; sdata->vif.csa_active = true; Loading Loading @@ -3014,7 +3059,8 @@ static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev, need_offchan = true; if (!ieee80211_is_action(mgmt->frame_control) || mgmt->u.action.category == WLAN_CATEGORY_PUBLIC || mgmt->u.action.category == WLAN_CATEGORY_SELF_PROTECTED) mgmt->u.action.category == WLAN_CATEGORY_SELF_PROTECTED || mgmt->u.action.category == WLAN_CATEGORY_SPECTRUM_MGMT) break; rcu_read_lock(); sta = sta_info_get(sdata, mgmt->da); Loading
net/mac80211/chan.c +0 −5 Original line number Diff line number Diff line Loading @@ -453,11 +453,6 @@ int ieee80211_vif_change_channel(struct ieee80211_sub_if_data *sdata, chanctx_changed |= IEEE80211_CHANCTX_CHANGE_CHANNEL; drv_change_chanctx(local, ctx, chanctx_changed); if (!local->use_chanctx) { local->_oper_chandef = *chandef; ieee80211_hw_config(local, 0); } ieee80211_recalc_chanctx_chantype(local, ctx); ieee80211_recalc_smps_chanctx(local, ctx); ieee80211_recalc_radar_chanctx(local, ctx); Loading