Commit bfd8403a authored by Johannes Berg's avatar Johannes Berg
Browse files

wifi: mac80211: reorg some iface data structs for MLD



Start reorganizing interface related data structures toward
MLD. The most complex part here is for the keys, since we
have to split the various kinds of GTKs off to the link but
still need to use (for WEP) the other keys as a fallback
even for multicast frames.

Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
parent f276e20b
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -9,7 +9,7 @@
 * Copyright 2007, Michael Wu <flamingice@sourmilk.net>
 * Copyright 2007-2010, Intel Corporation
 * Copyright(c) 2015-2017 Intel Deutschland GmbH
 * Copyright (C) 2018-2021 Intel Corporation
 * Copyright (C) 2018-2022 Intel Corporation
 */

/**
@@ -242,7 +242,7 @@ static void ieee80211_send_addba_resp(struct sta_info *sta, u8 *da, u16 tid,
	    sdata->vif.type == NL80211_IFTYPE_MESH_POINT)
		memcpy(mgmt->bssid, sdata->vif.addr, ETH_ALEN);
	else if (sdata->vif.type == NL80211_IFTYPE_STATION)
		memcpy(mgmt->bssid, sdata->u.mgd.bssid, ETH_ALEN);
		memcpy(mgmt->bssid, sdata->deflink.u.mgd.bssid, ETH_ALEN);
	else if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
		memcpy(mgmt->bssid, sdata->u.ibss.bssid, ETH_ALEN);

+1 −1
Original line number Diff line number Diff line
@@ -82,7 +82,7 @@ static void ieee80211_send_addba_request(struct ieee80211_sub_if_data *sdata,
	    sdata->vif.type == NL80211_IFTYPE_MESH_POINT)
		memcpy(mgmt->bssid, sdata->vif.addr, ETH_ALEN);
	else if (sdata->vif.type == NL80211_IFTYPE_STATION)
		memcpy(mgmt->bssid, sdata->u.mgd.bssid, ETH_ALEN);
		memcpy(mgmt->bssid, sdata->deflink.u.mgd.bssid, ETH_ALEN);
	else if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
		memcpy(mgmt->bssid, sdata->u.ibss.bssid, ETH_ALEN);

+88 −77
Original line number Diff line number Diff line
@@ -205,7 +205,7 @@ static int ieee80211_change_iface(struct wiphy *wiphy,
			return 0;

		mutex_lock(&local->sta_mtx);
		sta = sta_info_get(sdata, ifmgd->bssid);
		sta = sta_info_get(sdata, sdata->deflink.u.mgd.bssid);
		if (sta)
			drv_sta_set_4addr(local, sdata, &sta->sta,
					  params->use_4addr);
@@ -538,6 +538,7 @@ ieee80211_lookup_key(struct ieee80211_sub_if_data *sdata,
		     u8 key_idx, bool pairwise, const u8 *mac_addr)
{
	struct ieee80211_local *local = sdata->local;
	struct ieee80211_key *key;
	struct sta_info *sta;

	if (mac_addr) {
@@ -559,12 +560,14 @@ ieee80211_lookup_key(struct ieee80211_sub_if_data *sdata,
		return NULL;
	}

	if (key_idx < NUM_DEFAULT_KEYS +
		      NUM_DEFAULT_MGMT_KEYS +
		      NUM_DEFAULT_BEACON_KEYS)
	if (pairwise && key_idx < NUM_DEFAULT_KEYS)
		return rcu_dereference_check_key_mtx(local,
						     sdata->keys[key_idx]);

	key = rcu_dereference_check_key_mtx(local, sdata->deflink.gtk[key_idx]);
	if (key)
		return key;

	return NULL;
}

@@ -863,7 +866,7 @@ ieee80211_set_probe_resp(struct ieee80211_sub_if_data *sdata,
	if (!resp || !resp_len)
		return 1;

	old = sdata_dereference(sdata->u.ap.probe_resp, sdata);
	old = sdata_dereference(sdata->deflink.u.ap.probe_resp, sdata);

	new = kzalloc(sizeof(struct probe_resp) + resp_len, GFP_KERNEL);
	if (!new)
@@ -879,7 +882,7 @@ ieee80211_set_probe_resp(struct ieee80211_sub_if_data *sdata,
	else if (cca)
		new->cntdwn_counter_offsets[0] = cca->counter_offset_presp;

	rcu_assign_pointer(sdata->u.ap.probe_resp, new);
	rcu_assign_pointer(sdata->deflink.u.ap.probe_resp, new);
	if (old)
		kfree_rcu(old, rcu_head);

@@ -899,13 +902,13 @@ static int ieee80211_set_fils_discovery(struct ieee80211_sub_if_data *sdata,
	fd->min_interval = params->min_interval;
	fd->max_interval = params->max_interval;

	old = sdata_dereference(sdata->u.ap.fils_discovery, sdata);
	old = sdata_dereference(sdata->deflink.u.ap.fils_discovery, sdata);
	new = kzalloc(sizeof(*new) + params->tmpl_len, GFP_KERNEL);
	if (!new)
		return -ENOMEM;
	new->len = params->tmpl_len;
	memcpy(new->data, params->tmpl, params->tmpl_len);
	rcu_assign_pointer(sdata->u.ap.fils_discovery, new);
	rcu_assign_pointer(sdata->deflink.u.ap.fils_discovery, new);

	if (old)
		kfree_rcu(old, rcu_head);
@@ -922,13 +925,14 @@ ieee80211_set_unsol_bcast_probe_resp(struct ieee80211_sub_if_data *sdata,
	if (!params->tmpl || !params->tmpl_len)
		return -EINVAL;

	old = sdata_dereference(sdata->u.ap.unsol_bcast_probe_resp, sdata);
	old = sdata_dereference(sdata->deflink.u.ap.unsol_bcast_probe_resp,
				sdata);
	new = kzalloc(sizeof(*new) + params->tmpl_len, GFP_KERNEL);
	if (!new)
		return -ENOMEM;
	new->len = params->tmpl_len;
	memcpy(new->data, params->tmpl, params->tmpl_len);
	rcu_assign_pointer(sdata->u.ap.unsol_bcast_probe_resp, new);
	rcu_assign_pointer(sdata->deflink.u.ap.unsol_bcast_probe_resp, new);

	if (old)
		kfree_rcu(old, rcu_head);
@@ -1009,8 +1013,7 @@ static int ieee80211_assign_beacon(struct ieee80211_sub_if_data *sdata,
	int size, err;
	u32 changed = BSS_CHANGED_BEACON;

	old = sdata_dereference(sdata->u.ap.beacon, sdata);

	old = sdata_dereference(sdata->deflink.u.ap.beacon, sdata);

	/* Need to have a beacon head if we don't have one yet */
	if (!params->head && !old)
@@ -1116,7 +1119,8 @@ static int ieee80211_assign_beacon(struct ieee80211_sub_if_data *sdata,
		changed |= BSS_CHANGED_FTM_RESPONDER;
	}

	rcu_assign_pointer(sdata->u.ap.beacon, new);
	rcu_assign_pointer(sdata->deflink.u.ap.beacon, new);
	sdata->u.ap.active = true;

	if (old)
		kfree_rcu(old, rcu_head);
@@ -1141,16 +1145,16 @@ static int ieee80211_start_ap(struct wiphy *wiphy, struct net_device *dev,
	int i, err;
	int prev_beacon_int;

	old = sdata_dereference(sdata->u.ap.beacon, sdata);
	old = sdata_dereference(sdata->deflink.u.ap.beacon, sdata);
	if (old)
		return -EALREADY;

	if (params->smps_mode != NL80211_SMPS_OFF)
		return -ENOTSUPP;

	sdata->smps_mode = IEEE80211_SMPS_OFF;
	sdata->deflink.smps_mode = IEEE80211_SMPS_OFF;

	sdata->needed_rx_chains = sdata->local->rx_chains;
	sdata->deflink.needed_rx_chains = sdata->local->rx_chains;

	prev_beacon_int = sdata->vif.bss_conf.beacon_int;
	sdata->vif.bss_conf.beacon_int = params->beacon_interval;
@@ -1271,11 +1275,12 @@ static int ieee80211_start_ap(struct wiphy *wiphy, struct net_device *dev,

	err = drv_start_ap(sdata->local, sdata);
	if (err) {
		old = sdata_dereference(sdata->u.ap.beacon, sdata);
		old = sdata_dereference(sdata->deflink.u.ap.beacon, sdata);

		if (old)
			kfree_rcu(old, rcu_head);
		RCU_INIT_POINTER(sdata->u.ap.beacon, NULL);
		RCU_INIT_POINTER(sdata->deflink.u.ap.beacon, NULL);
		sdata->u.ap.active = false;
		goto error;
	}

@@ -1313,7 +1318,7 @@ static int ieee80211_change_beacon(struct wiphy *wiphy, struct net_device *dev,
	if (sdata->vif.bss_conf.csa_active || sdata->vif.bss_conf.color_change_active)
		return -EBUSY;

	old = sdata_dereference(sdata->u.ap.beacon, sdata);
	old = sdata_dereference(sdata->deflink.u.ap.beacon, sdata);
	if (!old)
		return -ENOENT;

@@ -1334,12 +1339,12 @@ static int ieee80211_change_beacon(struct wiphy *wiphy, struct net_device *dev,

static void ieee80211_free_next_beacon(struct ieee80211_sub_if_data *sdata)
{
	if (!sdata->u.ap.next_beacon)
	if (!sdata->deflink.u.ap.next_beacon)
		return;

	kfree(sdata->u.ap.next_beacon->mbssid_ies);
	kfree(sdata->u.ap.next_beacon);
	sdata->u.ap.next_beacon = NULL;
	kfree(sdata->deflink.u.ap.next_beacon->mbssid_ies);
	kfree(sdata->deflink.u.ap.next_beacon);
	sdata->deflink.u.ap.next_beacon = NULL;
}

static int ieee80211_stop_ap(struct wiphy *wiphy, struct net_device *dev,
@@ -1356,23 +1361,24 @@ static int ieee80211_stop_ap(struct wiphy *wiphy, struct net_device *dev,

	sdata_assert_lock(sdata);

	old_beacon = sdata_dereference(sdata->u.ap.beacon, sdata);
	old_beacon = sdata_dereference(sdata->deflink.u.ap.beacon, sdata);
	if (!old_beacon)
		return -ENOENT;
	old_probe_resp = sdata_dereference(sdata->u.ap.probe_resp, sdata);
	old_fils_discovery = sdata_dereference(sdata->u.ap.fils_discovery,
	old_probe_resp = sdata_dereference(sdata->deflink.u.ap.probe_resp,
					   sdata);
	old_fils_discovery = sdata_dereference(sdata->deflink.u.ap.fils_discovery,
					       sdata);
	old_unsol_bcast_probe_resp =
		sdata_dereference(sdata->u.ap.unsol_bcast_probe_resp,
		sdata_dereference(sdata->deflink.u.ap.unsol_bcast_probe_resp,
				  sdata);

	/* abort any running channel switch */
	mutex_lock(&local->mtx);
	sdata->vif.bss_conf.csa_active = false;
	if (sdata->csa_block_tx) {
	if (sdata->deflink.csa_block_tx) {
		ieee80211_wake_vif_queues(local, sdata,
					  IEEE80211_QUEUE_STOP_REASON_CSA);
		sdata->csa_block_tx = false;
		sdata->deflink.csa_block_tx = false;
	}

	mutex_unlock(&local->mtx);
@@ -1385,10 +1391,11 @@ static int ieee80211_stop_ap(struct wiphy *wiphy, struct net_device *dev,
	netif_carrier_off(dev);

	/* remove beacon and probe response */
	RCU_INIT_POINTER(sdata->u.ap.beacon, NULL);
	RCU_INIT_POINTER(sdata->u.ap.probe_resp, NULL);
	RCU_INIT_POINTER(sdata->u.ap.fils_discovery, NULL);
	RCU_INIT_POINTER(sdata->u.ap.unsol_bcast_probe_resp, NULL);
	sdata->u.ap.active = false;
	RCU_INIT_POINTER(sdata->deflink.u.ap.beacon, NULL);
	RCU_INIT_POINTER(sdata->deflink.u.ap.probe_resp, NULL);
	RCU_INIT_POINTER(sdata->deflink.u.ap.fils_discovery, NULL);
	RCU_INIT_POINTER(sdata->deflink.u.ap.unsol_bcast_probe_resp, NULL);
	kfree_rcu(old_beacon, rcu_head);
	if (old_probe_resp)
		kfree_rcu(old_probe_resp, rcu_head);
@@ -1411,7 +1418,7 @@ static int ieee80211_stop_ap(struct wiphy *wiphy, struct net_device *dev,

	if (sdata->wdev.cac_started) {
		chandef = sdata->vif.bss_conf.chandef;
		cancel_delayed_work_sync(&sdata->dfs_cac_timer_work);
		cancel_delayed_work_sync(&sdata->deflink.dfs_cac_timer_work);
		cfg80211_cac_event(sdata->dev, &chandef,
				   NL80211_RADAR_CAC_ABORTED,
				   GFP_KERNEL);
@@ -2388,8 +2395,8 @@ static int ieee80211_join_mesh(struct wiphy *wiphy, struct net_device *dev,
	sdata->control_port_over_nl80211 = setup->control_port_over_nl80211;

	/* can mesh use other SMPS modes? */
	sdata->smps_mode = IEEE80211_SMPS_OFF;
	sdata->needed_rx_chains = sdata->local->rx_chains;
	sdata->deflink.smps_mode = IEEE80211_SMPS_OFF;
	sdata->deflink.needed_rx_chains = sdata->local->rx_chains;

	mutex_lock(&sdata->local->mtx);
	err = ieee80211_vif_use_channel(sdata, &setup->chandef,
@@ -2423,7 +2430,7 @@ static int ieee80211_change_bss(struct wiphy *wiphy,
	struct ieee80211_supported_band *sband;
	u32 changed = 0;

	if (!sdata_dereference(sdata->u.ap.beacon, sdata))
	if (!sdata_dereference(sdata->deflink.u.ap.beacon, sdata))
		return -ENOENT;

	sband = ieee80211_get_sband(sdata);
@@ -2588,7 +2595,7 @@ static int ieee80211_scan(struct wiphy *wiphy,
		 * the  frames sent while scanning on other channel will be
		 * lost)
		 */
		if (sdata->u.ap.beacon &&
		if (sdata->deflink.u.ap.beacon &&
		    (!(wiphy->features & NL80211_FEATURE_AP_SCAN) ||
		     !(req->flags & NL80211_SCAN_FLAG_AP)))
			return -EOPNOTSUPP;
@@ -2769,14 +2776,15 @@ static int ieee80211_set_tx_power(struct wiphy *wiphy,

		switch (type) {
		case NL80211_TX_POWER_AUTOMATIC:
			sdata->user_power_level = IEEE80211_UNSET_POWER_LEVEL;
			sdata->deflink.user_power_level =
				IEEE80211_UNSET_POWER_LEVEL;
			txp_type = NL80211_TX_POWER_LIMITED;
			break;
		case NL80211_TX_POWER_LIMITED:
		case NL80211_TX_POWER_FIXED:
			if (mbm < 0 || (mbm % 100))
				return -EOPNOTSUPP;
			sdata->user_power_level = MBM_TO_DBM(mbm);
			sdata->deflink.user_power_level = MBM_TO_DBM(mbm);
			break;
		}

@@ -2809,7 +2817,7 @@ static int ieee80211_set_tx_power(struct wiphy *wiphy,
			has_monitor = true;
			continue;
		}
		sdata->user_power_level = local->user_power_level;
		sdata->deflink.user_power_level = local->user_power_level;
		if (txp_type != sdata->vif.bss_conf.txpower_type)
			update_txp_type = true;
		sdata->vif.bss_conf.txpower_type = txp_type;
@@ -2825,7 +2833,7 @@ static int ieee80211_set_tx_power(struct wiphy *wiphy,
		sdata = wiphy_dereference(local->hw.wiphy,
					  local->monitor_sdata);
		if (sdata) {
			sdata->user_power_level = local->user_power_level;
			sdata->deflink.user_power_level = local->user_power_level;
			if (txp_type != sdata->vif.bss_conf.txpower_type)
				update_txp_type = true;
			sdata->vif.bss_conf.txpower_type = txp_type;
@@ -2912,8 +2920,8 @@ int __ieee80211_request_smps_mgd(struct ieee80211_sub_if_data *sdata,
	if (WARN_ON_ONCE(sdata->vif.type != NL80211_IFTYPE_STATION))
		return -EINVAL;

	old_req = sdata->u.mgd.req_smps;
	sdata->u.mgd.req_smps = smps_mode;
	old_req = sdata->deflink.u.mgd.req_smps;
	sdata->deflink.u.mgd.req_smps = smps_mode;

	if (old_req == smps_mode &&
	    smps_mode != IEEE80211_SMPS_AUTOMATIC)
@@ -2928,7 +2936,7 @@ int __ieee80211_request_smps_mgd(struct ieee80211_sub_if_data *sdata,
	    sdata->vif.bss_conf.chandef.width == NL80211_CHAN_WIDTH_20_NOHT)
		return 0;

	ap = sdata->u.mgd.bssid;
	ap = sdata->deflink.u.mgd.bssid;

	rcu_read_lock();
	list_for_each_entry_rcu(sta, &sdata->local->sta_list, list) {
@@ -2952,7 +2960,7 @@ int __ieee80211_request_smps_mgd(struct ieee80211_sub_if_data *sdata,
	err = ieee80211_send_smps_action(sdata, smps_mode,
					 ap, ap);
	if (err)
		sdata->u.mgd.req_smps = old_req;
		sdata->deflink.u.mgd.req_smps = old_req;
	else if (smps_mode != IEEE80211_SMPS_OFF && tdls_peer_found)
		ieee80211_teardown_tdls_peers(sdata);

@@ -2980,7 +2988,7 @@ static int ieee80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev,

	/* no change, but if automatic follow powersave */
	sdata_lock(sdata);
	__ieee80211_request_smps_mgd(sdata, sdata->u.mgd.req_smps);
	__ieee80211_request_smps_mgd(sdata, sdata->deflink.u.mgd.req_smps);
	sdata_unlock(sdata);

	if (ieee80211_hw_check(&local->hw, SUPPORTS_DYNAMIC_PS))
@@ -3013,7 +3021,7 @@ static int ieee80211_set_cqm_rssi_config(struct wiphy *wiphy,
	bss_conf->cqm_rssi_hyst = rssi_hyst;
	bss_conf->cqm_rssi_low = 0;
	bss_conf->cqm_rssi_high = 0;
	sdata->u.mgd.last_cqm_event_signal = 0;
	sdata->deflink.u.mgd.last_cqm_event_signal = 0;

	/* tell the driver upon association, unless already associated */
	if (sdata->u.mgd.associated &&
@@ -3038,7 +3046,7 @@ static int ieee80211_set_cqm_rssi_range_config(struct wiphy *wiphy,
	bss_conf->cqm_rssi_high = rssi_high;
	bss_conf->cqm_rssi_thold = 0;
	bss_conf->cqm_rssi_hyst = 0;
	sdata->u.mgd.last_cqm_event_signal = 0;
	sdata->deflink.u.mgd.last_cqm_event_signal = 0;

	/* tell the driver upon association, unless already associated */
	if (sdata->u.mgd.associated &&
@@ -3132,8 +3140,8 @@ static int ieee80211_start_radar_detection(struct wiphy *wiphy,
	}

	/* whatever, but channel contexts should not complain about that one */
	sdata->smps_mode = IEEE80211_SMPS_OFF;
	sdata->needed_rx_chains = local->rx_chains;
	sdata->deflink.smps_mode = IEEE80211_SMPS_OFF;
	sdata->deflink.needed_rx_chains = local->rx_chains;

	err = ieee80211_vif_use_channel(sdata, chandef,
					IEEE80211_CHANCTX_SHARED);
@@ -3141,7 +3149,7 @@ static int ieee80211_start_radar_detection(struct wiphy *wiphy,
		goto out_unlock;

	ieee80211_queue_delayed_work(&sdata->local->hw,
				     &sdata->dfs_cac_timer_work,
				     &sdata->deflink.dfs_cac_timer_work,
				     msecs_to_jiffies(cac_time_ms));

 out_unlock:
@@ -3161,7 +3169,7 @@ static void ieee80211_end_cac(struct wiphy *wiphy,
		 * by the time it gets it, sdata->wdev.cac_started
		 * will no longer be true
		 */
		cancel_delayed_work(&sdata->dfs_cac_timer_work);
		cancel_delayed_work(&sdata->deflink.dfs_cac_timer_work);

		if (sdata->wdev.cac_started) {
			ieee80211_vif_release_channel(sdata);
@@ -3280,10 +3288,10 @@ void ieee80211_csa_finish(struct ieee80211_vif *vif)
				continue;

			ieee80211_queue_work(&iter->local->hw,
					     &iter->csa_finalize_work);
					     &iter->deflink.csa_finalize_work);
		}
	}
	ieee80211_queue_work(&local->hw, &sdata->csa_finalize_work);
	ieee80211_queue_work(&local->hw, &sdata->deflink.csa_finalize_work);

	rcu_read_unlock();
}
@@ -3295,7 +3303,7 @@ void ieee80211_channel_switch_disconnect(struct ieee80211_vif *vif, bool block_t
	struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
	struct ieee80211_local *local = sdata->local;

	sdata->csa_block_tx = block_tx;
	sdata->deflink.csa_block_tx = block_tx;
	sdata_info(sdata, "channel switch failed, disconnecting\n");
	ieee80211_queue_work(&local->hw, &ifmgd->csa_connection_drop_work);
}
@@ -3308,10 +3316,11 @@ static int ieee80211_set_after_csa_beacon(struct ieee80211_sub_if_data *sdata,

	switch (sdata->vif.type) {
	case NL80211_IFTYPE_AP:
		if (!sdata->u.ap.next_beacon)
		if (!sdata->deflink.u.ap.next_beacon)
			return -EINVAL;

		err = ieee80211_assign_beacon(sdata, sdata->u.ap.next_beacon,
		err = ieee80211_assign_beacon(sdata,
					      sdata->deflink.u.ap.next_beacon,
					      NULL, NULL);
		ieee80211_free_next_beacon(sdata);

@@ -3358,20 +3367,20 @@ static int __ieee80211_csa_finalize(struct ieee80211_sub_if_data *sdata)
	 * completed successfully
	 */

	if (sdata->reserved_chanctx) {
	if (sdata->deflink.reserved_chanctx) {
		/*
		 * with multi-vif csa driver may call ieee80211_csa_finish()
		 * many times while waiting for other interfaces to use their
		 * reservations
		 */
		if (sdata->reserved_ready)
		if (sdata->deflink.reserved_ready)
			return 0;

		return ieee80211_vif_use_reserved_context(sdata);
	}

	if (!cfg80211_chandef_identical(&sdata->vif.bss_conf.chandef,
					&sdata->csa_chandef))
					&sdata->deflink.csa_chandef))
		return -EINVAL;

	sdata->vif.bss_conf.csa_active = false;
@@ -3382,17 +3391,17 @@ static int __ieee80211_csa_finalize(struct ieee80211_sub_if_data *sdata)

	ieee80211_bss_info_change_notify(sdata, changed);

	if (sdata->csa_block_tx) {
	if (sdata->deflink.csa_block_tx) {
		ieee80211_wake_vif_queues(local, sdata,
					  IEEE80211_QUEUE_STOP_REASON_CSA);
		sdata->csa_block_tx = false;
		sdata->deflink.csa_block_tx = false;
	}

	err = drv_post_channel_switch(sdata);
	if (err)
		return err;

	cfg80211_ch_switch_notify(sdata->dev, &sdata->csa_chandef, 0);
	cfg80211_ch_switch_notify(sdata->dev, &sdata->deflink.csa_chandef, 0);

	return 0;
}
@@ -3410,7 +3419,7 @@ void ieee80211_csa_finalize_work(struct work_struct *work)
{
	struct ieee80211_sub_if_data *sdata =
		container_of(work, struct ieee80211_sub_if_data,
			     csa_finalize_work);
			     deflink.csa_finalize_work);
	struct ieee80211_local *local = sdata->local;

	sdata_lock(sdata);
@@ -3441,9 +3450,9 @@ static int ieee80211_set_csa_beacon(struct ieee80211_sub_if_data *sdata,

	switch (sdata->vif.type) {
	case NL80211_IFTYPE_AP:
		sdata->u.ap.next_beacon =
		sdata->deflink.u.ap.next_beacon =
			cfg80211_beacon_dup(&params->beacon_after);
		if (!sdata->u.ap.next_beacon)
		if (!sdata->deflink.u.ap.next_beacon)
			return -ENOMEM;

		/*
@@ -3655,15 +3664,16 @@ __ieee80211_channel_switch(struct wiphy *wiphy, struct net_device *dev,
		goto out;
	}

	sdata->csa_chandef = params->chandef;
	sdata->csa_block_tx = params->block_tx;
	sdata->deflink.csa_chandef = params->chandef;
	sdata->deflink.csa_block_tx = params->block_tx;
	sdata->vif.bss_conf.csa_active = true;

	if (sdata->csa_block_tx)
	if (sdata->deflink.csa_block_tx)
		ieee80211_stop_vif_queues(local, sdata,
					  IEEE80211_QUEUE_STOP_REASON_CSA);

	cfg80211_ch_switch_started_notify(sdata->dev, &sdata->csa_chandef,
	cfg80211_ch_switch_started_notify(sdata->dev,
					  &sdata->deflink.csa_chandef,
					  params->count, params->block_tx);

	if (changed) {
@@ -4310,10 +4320,11 @@ ieee80211_set_after_color_change_beacon(struct ieee80211_sub_if_data *sdata,
	case NL80211_IFTYPE_AP: {
		int ret;

		if (!sdata->u.ap.next_beacon)
		if (!sdata->deflink.u.ap.next_beacon)
			return -EINVAL;

		ret = ieee80211_assign_beacon(sdata, sdata->u.ap.next_beacon,
		ret = ieee80211_assign_beacon(sdata,
					      sdata->deflink.u.ap.next_beacon,
					      NULL, NULL);
		ieee80211_free_next_beacon(sdata);

@@ -4341,9 +4352,9 @@ ieee80211_set_color_change_beacon(struct ieee80211_sub_if_data *sdata,

	switch (sdata->vif.type) {
	case NL80211_IFTYPE_AP:
		sdata->u.ap.next_beacon =
		sdata->deflink.u.ap.next_beacon =
			cfg80211_beacon_dup(&params->beacon_next);
		if (!sdata->u.ap.next_beacon)
		if (!sdata->deflink.u.ap.next_beacon)
			return -ENOMEM;

		if (params->count <= 1)
@@ -4425,7 +4436,7 @@ void ieee80211_color_change_finalize_work(struct work_struct *work)
{
	struct ieee80211_sub_if_data *sdata =
		container_of(work, struct ieee80211_sub_if_data,
			     color_change_finalize_work);
			     deflink.color_change_finalize_work);
	struct ieee80211_local *local = sdata->local;

	sdata_lock(sdata);
@@ -4450,7 +4461,7 @@ void ieee80211_color_change_finish(struct ieee80211_vif *vif)
	struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);

	ieee80211_queue_work(&sdata->local->hw,
			     &sdata->color_change_finalize_work);
			     &sdata->deflink.color_change_finalize_work);
}
EXPORT_SYMBOL_GPL(ieee80211_color_change_finish);

+48 −47
Original line number Diff line number Diff line
@@ -92,9 +92,9 @@ ieee80211_chanctx_reserved_chandef(struct ieee80211_local *local,
	list_for_each_entry(sdata, &ctx->reserved_vifs,
			    reserved_chanctx_list) {
		if (!compat)
			compat = &sdata->reserved_chandef;
			compat = &sdata->deflink.reserved_chandef;

		compat = cfg80211_chandef_compatible(&sdata->reserved_chandef,
		compat = cfg80211_chandef_compatible(&sdata->deflink.reserved_chandef,
						     compat);
		if (!compat)
			break;
@@ -114,7 +114,7 @@ ieee80211_chanctx_non_reserved_chandef(struct ieee80211_local *local,

	list_for_each_entry(sdata, &ctx->assigned_vifs,
			    assigned_chanctx_list) {
		if (sdata->reserved_chanctx != NULL)
		if (sdata->deflink.reserved_chanctx != NULL)
			continue;

		if (!compat)
@@ -508,7 +508,7 @@ bool ieee80211_is_radar_required(struct ieee80211_local *local)

	rcu_read_lock();
	list_for_each_entry_rcu(sdata, &local->interfaces, list) {
		if (sdata->radar_required) {
		if (sdata->deflink.radar_required) {
			rcu_read_unlock();
			return true;
		}
@@ -535,7 +535,7 @@ ieee80211_chanctx_radar_required(struct ieee80211_local *local,
			continue;
		if (rcu_access_pointer(sdata->vif.bss_conf.chanctx_conf) != conf)
			continue;
		if (!sdata->radar_required)
		if (!sdata->deflink.radar_required)
			continue;

		required = true;
@@ -848,18 +848,18 @@ void ieee80211_recalc_smps_chanctx(struct ieee80211_local *local,
			WARN_ON_ONCE(1);
		}

		switch (sdata->smps_mode) {
		switch (sdata->deflink.smps_mode) {
		default:
			WARN_ONCE(1, "Invalid SMPS mode %d\n",
				  sdata->smps_mode);
				  sdata->deflink.smps_mode);
			fallthrough;
		case IEEE80211_SMPS_OFF:
			needed_static = sdata->needed_rx_chains;
			needed_dynamic = sdata->needed_rx_chains;
			needed_static = sdata->deflink.needed_rx_chains;
			needed_dynamic = sdata->deflink.needed_rx_chains;
			break;
		case IEEE80211_SMPS_DYNAMIC:
			needed_static = 1;
			needed_dynamic = sdata->needed_rx_chains;
			needed_dynamic = sdata->deflink.needed_rx_chains;
			break;
		case IEEE80211_SMPS_STATIC:
			needed_static = 1;
@@ -942,7 +942,7 @@ void ieee80211_vif_copy_chanctx_to_vlans(struct ieee80211_sub_if_data *sdata,

int ieee80211_vif_unreserve_chanctx(struct ieee80211_sub_if_data *sdata)
{
	struct ieee80211_chanctx *ctx = sdata->reserved_chanctx;
	struct ieee80211_chanctx *ctx = sdata->deflink.reserved_chanctx;

	lockdep_assert_held(&sdata->local->chanctx_mtx);

@@ -950,7 +950,7 @@ int ieee80211_vif_unreserve_chanctx(struct ieee80211_sub_if_data *sdata)
		return -EINVAL;

	list_del(&sdata->reserved_chanctx_list);
	sdata->reserved_chanctx = NULL;
	sdata->deflink.reserved_chanctx = NULL;

	if (ieee80211_chanctx_refcount(sdata->local, ctx) == 0) {
		if (ctx->replace_state == IEEE80211_CHANCTX_REPLACES_OTHER) {
@@ -1063,10 +1063,10 @@ int ieee80211_vif_reserve_chanctx(struct ieee80211_sub_if_data *sdata,
	}

	list_add(&sdata->reserved_chanctx_list, &new_ctx->reserved_vifs);
	sdata->reserved_chanctx = new_ctx;
	sdata->reserved_chandef = *chandef;
	sdata->reserved_radar_required = radar_required;
	sdata->reserved_ready = false;
	sdata->deflink.reserved_chanctx = new_ctx;
	sdata->deflink.reserved_chandef = *chandef;
	sdata->deflink.reserved_radar_required = radar_required;
	sdata->deflink.reserved_ready = false;

	return 0;
}
@@ -1080,7 +1080,7 @@ ieee80211_vif_chanctx_reservation_complete(struct ieee80211_sub_if_data *sdata)
	case NL80211_IFTYPE_MESH_POINT:
	case NL80211_IFTYPE_OCB:
		ieee80211_queue_work(&sdata->local->hw,
				     &sdata->csa_finalize_work);
				     &sdata->deflink.csa_finalize_work);
		break;
	case NL80211_IFTYPE_STATION:
		ieee80211_queue_work(&sdata->local->hw,
@@ -1128,10 +1128,10 @@ ieee80211_vif_use_reserved_reassign(struct ieee80211_sub_if_data *sdata)
	lockdep_assert_held(&local->mtx);
	lockdep_assert_held(&local->chanctx_mtx);

	new_ctx = sdata->reserved_chanctx;
	new_ctx = sdata->deflink.reserved_chanctx;
	old_ctx = ieee80211_vif_get_chanctx(sdata);

	if (WARN_ON(!sdata->reserved_ready))
	if (WARN_ON(!sdata->deflink.reserved_ready))
		return -EBUSY;

	if (WARN_ON(!new_ctx))
@@ -1145,14 +1145,14 @@ ieee80211_vif_use_reserved_reassign(struct ieee80211_sub_if_data *sdata)
		return -EINVAL;

	chandef = ieee80211_chanctx_non_reserved_chandef(local, new_ctx,
				&sdata->reserved_chandef);
				&sdata->deflink.reserved_chandef);
	if (WARN_ON(!chandef))
		return -EINVAL;

	if (sdata->vif.bss_conf.chandef.width != sdata->reserved_chandef.width)
	if (sdata->vif.bss_conf.chandef.width != sdata->deflink.reserved_chandef.width)
		changed = BSS_CHANGED_BANDWIDTH;

	ieee80211_vif_update_chandef(sdata, &sdata->reserved_chandef);
	ieee80211_vif_update_chandef(sdata, &sdata->deflink.reserved_chandef);

	ieee80211_change_chanctx(local, new_ctx, old_ctx, chandef);

@@ -1161,7 +1161,7 @@ ieee80211_vif_use_reserved_reassign(struct ieee80211_sub_if_data *sdata)
	vif_chsw[0].new_ctx = &new_ctx->conf;

	list_del(&sdata->reserved_chanctx_list);
	sdata->reserved_chanctx = NULL;
	sdata->deflink.reserved_chanctx = NULL;

	err = drv_switch_vif_chanctx(local, vif_chsw, 1,
				     CHANCTX_SWMODE_REASSIGN_VIF);
@@ -1204,9 +1204,9 @@ ieee80211_vif_use_reserved_assign(struct ieee80211_sub_if_data *sdata)
	int err;

	old_ctx = ieee80211_vif_get_chanctx(sdata);
	new_ctx = sdata->reserved_chanctx;
	new_ctx = sdata->deflink.reserved_chanctx;

	if (WARN_ON(!sdata->reserved_ready))
	if (WARN_ON(!sdata->deflink.reserved_ready))
		return -EINVAL;

	if (WARN_ON(old_ctx))
@@ -1220,14 +1220,14 @@ ieee80211_vif_use_reserved_assign(struct ieee80211_sub_if_data *sdata)
		return -EINVAL;

	chandef = ieee80211_chanctx_non_reserved_chandef(local, new_ctx,
				&sdata->reserved_chandef);
				&sdata->deflink.reserved_chandef);
	if (WARN_ON(!chandef))
		return -EINVAL;

	ieee80211_change_chanctx(local, new_ctx, new_ctx, chandef);

	list_del(&sdata->reserved_chanctx_list);
	sdata->reserved_chanctx = NULL;
	sdata->deflink.reserved_chanctx = NULL;

	err = ieee80211_assign_vif_chanctx(sdata, new_ctx);
	if (err) {
@@ -1249,7 +1249,7 @@ ieee80211_vif_has_in_place_reservation(struct ieee80211_sub_if_data *sdata)

	lockdep_assert_held(&sdata->local->chanctx_mtx);

	new_ctx = sdata->reserved_chanctx;
	new_ctx = sdata->deflink.reserved_chanctx;
	old_ctx = ieee80211_vif_get_chanctx(sdata);

	if (!old_ctx)
@@ -1421,9 +1421,9 @@ static int ieee80211_vif_use_reserved_switch(struct ieee80211_local *local)
		list_for_each_entry(sdata, &ctx->replace_ctx->assigned_vifs,
				    assigned_chanctx_list) {
			n_assigned++;
			if (sdata->reserved_chanctx) {
			if (sdata->deflink.reserved_chanctx) {
				n_reserved++;
				if (sdata->reserved_ready)
				if (sdata->deflink.reserved_ready)
					n_ready++;
			}
		}
@@ -1443,7 +1443,7 @@ static int ieee80211_vif_use_reserved_switch(struct ieee80211_local *local)
		list_for_each_entry(sdata, &ctx->reserved_vifs,
				    reserved_chanctx_list) {
			if (ieee80211_vif_has_in_place_reservation(sdata) &&
			    !sdata->reserved_ready)
			    !sdata->deflink.reserved_ready)
				return -EAGAIN;

			old_ctx = ieee80211_vif_get_chanctx(sdata);
@@ -1457,7 +1457,7 @@ static int ieee80211_vif_use_reserved_switch(struct ieee80211_local *local)
				n_vifs_ctxless++;
			}

			if (sdata->reserved_radar_required)
			if (sdata->deflink.reserved_radar_required)
				ctx->conf.radar_enabled = true;
		}
	}
@@ -1524,13 +1524,14 @@ static int ieee80211_vif_use_reserved_switch(struct ieee80211_local *local)

			ieee80211_check_fast_xmit_iface(sdata);

			sdata->radar_required = sdata->reserved_radar_required;
			sdata->deflink.radar_required = sdata->deflink.reserved_radar_required;

			if (sdata->vif.bss_conf.chandef.width !=
			    sdata->reserved_chandef.width)
			    sdata->deflink.reserved_chandef.width)
				changed = BSS_CHANGED_BANDWIDTH;

			ieee80211_vif_update_chandef(sdata, &sdata->reserved_chandef);
			ieee80211_vif_update_chandef(sdata,
						     &sdata->deflink.reserved_chandef);
			if (changed)
				ieee80211_bss_info_change_notify(sdata,
								 changed);
@@ -1551,7 +1552,7 @@ static int ieee80211_vif_use_reserved_switch(struct ieee80211_local *local)
			list_del(&sdata->reserved_chanctx_list);
			list_move(&sdata->assigned_chanctx_list,
				  &ctx->assigned_vifs);
			sdata->reserved_chanctx = NULL;
			sdata->deflink.reserved_chanctx = NULL;

			ieee80211_vif_chanctx_reservation_complete(sdata);
		}
@@ -1569,10 +1570,10 @@ static int ieee80211_vif_use_reserved_switch(struct ieee80211_local *local)
					sdata)))
				continue;

			if (WARN_ON(sdata->reserved_chanctx != ctx))
			if (WARN_ON(sdata->deflink.reserved_chanctx != ctx))
				continue;

			if (!sdata->reserved_ready)
			if (!sdata->deflink.reserved_ready)
				continue;

			if (ieee80211_vif_get_chanctx(sdata))
@@ -1642,11 +1643,11 @@ static void __ieee80211_vif_release_channel(struct ieee80211_sub_if_data *sdata)

	ctx = container_of(conf, struct ieee80211_chanctx, conf);

	if (sdata->reserved_chanctx) {
		if (sdata->reserved_chanctx->replace_state ==
	if (sdata->deflink.reserved_chanctx) {
		if (sdata->deflink.reserved_chanctx->replace_state ==
		    IEEE80211_CHANCTX_REPLACES_OTHER &&
		    ieee80211_chanctx_num_reserved(local,
						   sdata->reserved_chanctx) > 1)
						   sdata->deflink.reserved_chanctx) > 1)
			use_reserved_switch = true;

		ieee80211_vif_unreserve_chanctx(sdata);
@@ -1656,7 +1657,7 @@ static void __ieee80211_vif_release_channel(struct ieee80211_sub_if_data *sdata)
	if (ieee80211_chanctx_refcount(local, ctx) == 0)
		ieee80211_free_chanctx(local, ctx);

	sdata->radar_required = false;
	sdata->deflink.radar_required = false;

	/* Unreserving may ready an in-place reservation. */
	if (use_reserved_switch)
@@ -1686,7 +1687,7 @@ int ieee80211_vif_use_channel(struct ieee80211_sub_if_data *sdata,
	if (ret > 0)
		radar_detect_width = BIT(chandef->width);

	sdata->radar_required = ret;
	sdata->deflink.radar_required = ret;

	ret = ieee80211_check_combinations(sdata, chandef, mode,
					   radar_detect_width);
@@ -1717,7 +1718,7 @@ int ieee80211_vif_use_channel(struct ieee80211_sub_if_data *sdata,
	ieee80211_recalc_radar_chanctx(local, ctx);
 out:
	if (ret)
		sdata->radar_required = false;
		sdata->deflink.radar_required = false;

	mutex_unlock(&local->chanctx_mtx);
	return ret;
@@ -1733,7 +1734,7 @@ int ieee80211_vif_use_reserved_context(struct ieee80211_sub_if_data *sdata)
	lockdep_assert_held(&local->mtx);
	lockdep_assert_held(&local->chanctx_mtx);

	new_ctx = sdata->reserved_chanctx;
	new_ctx = sdata->deflink.reserved_chanctx;
	old_ctx = ieee80211_vif_get_chanctx(sdata);

	if (WARN_ON(!new_ctx))
@@ -1743,10 +1744,10 @@ int ieee80211_vif_use_reserved_context(struct ieee80211_sub_if_data *sdata)
		    IEEE80211_CHANCTX_WILL_BE_REPLACED))
		return -EINVAL;

	if (WARN_ON(sdata->reserved_ready))
	if (WARN_ON(sdata->deflink.reserved_ready))
		return -EINVAL;

	sdata->reserved_ready = true;
	sdata->deflink.reserved_ready = true;

	if (new_ctx->replace_state == IEEE80211_CHANCTX_REPLACE_NONE) {
		if (old_ctx)
+5 −5

File changed.

Preview size limit exceeded, changes collapsed.

Loading