Commit 08fad438 authored by Jouni Malinen's avatar Jouni Malinen Committed by Johannes Berg
Browse files

mac80211: TX legacy rate control for Beacon frames



Use the Beacon frame specific legacy rate configuration, if specified
for AP or mesh, instead of the generic rate mask when selecting the TX
rate for Beacon frames.

Signed-off-by: default avatarJouni Malinen <jouni@codeaurora.org>
Link: https://lore.kernel.org/r/20200425155713.25687-4-jouni@codeaurora.org


Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
parent bedd7904
Loading
Loading
Loading
Loading
+25 −1
Original line number Diff line number Diff line
@@ -994,7 +994,7 @@ static int ieee80211_start_ap(struct wiphy *wiphy, struct net_device *dev,
		      BSS_CHANGED_TWT |
		      BSS_CHANGED_HE_OBSS_PD |
		      BSS_CHANGED_HE_BSS_COLOR;
	int err;
	int i, err;
	int prev_beacon_int;

	old = sdata_dereference(sdata->u.ap.beacon, sdata);
@@ -1085,6 +1085,17 @@ static int ieee80211_start_ap(struct wiphy *wiphy, struct net_device *dev,
		sdata->vif.bss_conf.p2p_noa_attr.oppps_ctwindow |=
					IEEE80211_P2P_OPPPS_ENABLE_BIT;

	sdata->beacon_rate_set = false;
	if (wiphy_ext_feature_isset(local->hw.wiphy,
				    NL80211_EXT_FEATURE_BEACON_RATE_LEGACY)) {
		for (i = 0; i < NUM_NL80211_BANDS; i++) {
			sdata->beacon_rateidx_mask[i] =
				params->beacon_rate.control[i].legacy;
			if (sdata->beacon_rateidx_mask[i])
				sdata->beacon_rate_set = true;
		}
	}

	err = ieee80211_assign_beacon(sdata, &params->beacon, NULL);
	if (err < 0) {
		ieee80211_vif_release_channel(sdata);
@@ -1189,6 +1200,7 @@ static int ieee80211_stop_ap(struct wiphy *wiphy, struct net_device *dev)
	ieee80211_free_keys(sdata, true);

	sdata->vif.bss_conf.enable_beacon = false;
	sdata->beacon_rate_set = false;
	sdata->vif.bss_conf.ssid_len = 0;
	clear_bit(SDATA_STATE_OFFCHANNEL_BEACON_STOPPED, &sdata->state);
	ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON_ENABLED);
@@ -1949,6 +1961,7 @@ static int copy_mesh_setup(struct ieee80211_if_mesh *ifmsh,
	const u8 *old_ie;
	struct ieee80211_sub_if_data *sdata = container_of(ifmsh,
					struct ieee80211_sub_if_data, u.mesh);
	int i;

	/* allocate information elements */
	new_ie = NULL;
@@ -1987,6 +2000,17 @@ static int copy_mesh_setup(struct ieee80211_if_mesh *ifmsh,
	sdata->vif.bss_conf.beacon_int = setup->beacon_interval;
	sdata->vif.bss_conf.dtim_period = setup->dtim_period;

	sdata->beacon_rate_set = false;
	if (wiphy_ext_feature_isset(sdata->local->hw.wiphy,
				    NL80211_EXT_FEATURE_BEACON_RATE_LEGACY)) {
		for (i = 0; i < NUM_NL80211_BANDS; i++) {
			sdata->beacon_rateidx_mask[i] =
				setup->beacon_rate.control[i].legacy;
			if (sdata->beacon_rateidx_mask[i])
				sdata->beacon_rate_set = true;
		}
	}

	return 0;
}

+4 −0
Original line number Diff line number Diff line
@@ -962,6 +962,10 @@ struct ieee80211_sub_if_data {
	bool rc_has_vht_mcs_mask[NUM_NL80211_BANDS];
	u16 rc_rateidx_vht_mcs_mask[NUM_NL80211_BANDS][NL80211_VHT_NSS_MAX];

	/* Beacon frame (non-MCS) rate (as a bitmap) */
	u32 beacon_rateidx_mask[NUM_NL80211_BANDS];
	bool beacon_rate_set;

	union {
		struct ieee80211_if_ap ap;
		struct ieee80211_if_wds wds;
+1 −0
Original line number Diff line number Diff line
@@ -994,6 +994,7 @@ void ieee80211_stop_mesh(struct ieee80211_sub_if_data *sdata)
	/* stop the beacon */
	ifmsh->mesh_id_len = 0;
	sdata->vif.bss_conf.enable_beacon = false;
	sdata->beacon_rate_set = false;
	clear_bit(SDATA_STATE_OFFCHANNEL_BEACON_STOPPED, &sdata->state);
	ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON_ENABLED);

+4 −1
Original line number Diff line number Diff line
@@ -4883,6 +4883,9 @@ __ieee80211_beacon_get(struct ieee80211_hw *hw,
	txrc.bss_conf = &sdata->vif.bss_conf;
	txrc.skb = skb;
	txrc.reported_rate.idx = -1;
	if (sdata->beacon_rate_set && sdata->beacon_rateidx_mask[band])
		txrc.rate_idx_mask = sdata->beacon_rateidx_mask[band];
	else
		txrc.rate_idx_mask = sdata->rc_rateidx_mask[band];
	txrc.bss = true;
	rate_control_get_rate(sdata, NULL, &txrc);