Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b6a441d6 authored by Weilun Du's avatar Weilun Du Committed by Jeongik Cha
Browse files

FROMGIT: mac80211_hwsim: add concurrent channels scanning support over virtio



This fixed the crash when setting channels to 2 or more when
communicating over virtio.

Signed-off-by: default avatarWeilun Du <wdu@google.com>
Link: https://lore.kernel.org/r/20210506180530.3418576-1-wdu@google.com


Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>

(cherry picked from commit 626c30f9e77354301ff9162c3bdddaf92d9b5cf3 https://git.kernel.org/pub/scm/linux/kernel/git/netdev/net-next.git/commit/?id=626c30f9e77354301ff9162c3bdddaf92d9b5cf3

)
Bug: 182576217
Signed-off-by: default avatarWeilun Du <wdu@google.com>
Signed-off-by: default avatarMaciej Żenczykowski <maze@google.com>
Change-Id: Ia9be6c1d962b941a92f4e1be41e874dbe08024e5
(cherry picked from commit 2e289f3641a9c37ad054f9e84398533ccd930c8f)
(cherry picked from commit 085ebe864e396d3df82d06761bb1ddb97d8ce4d9)
parent 1866ee1a
Loading
Loading
Loading
Loading
+38 −10
Original line number Diff line number Diff line
@@ -499,6 +499,7 @@ struct mac80211_hwsim_data {
	u32 ciphers[ARRAY_SIZE(hwsim_ciphers)];

	struct mac_address addresses[2];
	struct ieee80211_chanctx_conf *chanctx;
	int channels, idx;
	bool use_chanctx;
	bool destroy_on_close;
@@ -1091,7 +1092,8 @@ static inline u16 trans_tx_rate_flags_ieee2hwsim(struct ieee80211_tx_rate *rate)

static void mac80211_hwsim_tx_frame_nl(struct ieee80211_hw *hw,
				       struct sk_buff *my_skb,
				       int dst_portid)
				       int dst_portid,
				       struct ieee80211_channel *channel)
{
	struct sk_buff *skb;
	struct mac80211_hwsim_data *data = hw->priv;
@@ -1146,7 +1148,7 @@ static void mac80211_hwsim_tx_frame_nl(struct ieee80211_hw *hw,
	if (nla_put_u32(skb, HWSIM_ATTR_FLAGS, hwsim_flags))
		goto nla_put_failure;

	if (nla_put_u32(skb, HWSIM_ATTR_FREQ, data->channel->center_freq))
	if (nla_put_u32(skb, HWSIM_ATTR_FREQ, channel->center_freq))
		goto nla_put_failure;

	/* We get the tx control (rate and retries) info*/
@@ -1487,7 +1489,7 @@ static void mac80211_hwsim_tx(struct ieee80211_hw *hw,
	_portid = READ_ONCE(data->wmediumd);

	if (_portid || hwsim_virtio_enabled)
		return mac80211_hwsim_tx_frame_nl(hw, skb, _portid);
		return mac80211_hwsim_tx_frame_nl(hw, skb, _portid, channel);

	/* NO wmediumd detected, perfect medium simulation */
	data->tx_pkts++;
@@ -1598,7 +1600,7 @@ static void mac80211_hwsim_tx_frame(struct ieee80211_hw *hw,
	mac80211_hwsim_monitor_rx(hw, skb, chan);

	if (_pid || hwsim_virtio_enabled)
		return mac80211_hwsim_tx_frame_nl(hw, skb, _pid);
		return mac80211_hwsim_tx_frame_nl(hw, skb, _pid, chan);

	mac80211_hwsim_tx_frame_no_nl(hw, skb, chan);
	dev_kfree_skb(skb);
@@ -2316,6 +2318,11 @@ static int mac80211_hwsim_croc(struct ieee80211_hw *hw,
static int mac80211_hwsim_add_chanctx(struct ieee80211_hw *hw,
				      struct ieee80211_chanctx_conf *ctx)
{
	struct mac80211_hwsim_data *hwsim = hw->priv;

	mutex_lock(&hwsim->mutex);
	hwsim->chanctx = ctx;
	mutex_unlock(&hwsim->mutex);
	hwsim_set_chanctx_magic(ctx);
	wiphy_dbg(hw->wiphy,
		  "add channel context control: %d MHz/width: %d/cfreqs:%d/%d MHz\n",
@@ -2327,6 +2334,11 @@ static int mac80211_hwsim_add_chanctx(struct ieee80211_hw *hw,
static void mac80211_hwsim_remove_chanctx(struct ieee80211_hw *hw,
					  struct ieee80211_chanctx_conf *ctx)
{
	struct mac80211_hwsim_data *hwsim = hw->priv;

	mutex_lock(&hwsim->mutex);
	hwsim->chanctx = NULL;
	mutex_unlock(&hwsim->mutex);
	wiphy_dbg(hw->wiphy,
		  "remove channel context control: %d MHz/width: %d/cfreqs:%d/%d MHz\n",
		  ctx->def.chan->center_freq, ctx->def.width,
@@ -2339,6 +2351,11 @@ static void mac80211_hwsim_change_chanctx(struct ieee80211_hw *hw,
					  struct ieee80211_chanctx_conf *ctx,
					  u32 changed)
{
	struct mac80211_hwsim_data *hwsim = hw->priv;

	mutex_lock(&hwsim->mutex);
	hwsim->chanctx = ctx;
	mutex_unlock(&hwsim->mutex);
	hwsim_check_chanctx_magic(ctx);
	wiphy_dbg(hw->wiphy,
		  "change channel context control: %d MHz/width: %d/cfreqs:%d/%d MHz\n",
@@ -2926,6 +2943,7 @@ static int mac80211_hwsim_new_radio(struct genl_info *info,
		hw->wiphy->max_remain_on_channel_duration = 1000;
		data->if_combination.radar_detect_widths = 0;
		data->if_combination.num_different_channels = data->channels;
		data->chanctx = NULL;
	} else {
		data->if_combination.num_different_channels = 1;
		data->if_combination.radar_detect_widths =
@@ -3420,6 +3438,7 @@ static int hwsim_cloned_frame_received_nl(struct sk_buff *skb_2,
	int frame_data_len;
	void *frame_data;
	struct sk_buff *skb = NULL;
	struct ieee80211_channel *channel = NULL;

	if (!info->attrs[HWSIM_ATTR_ADDR_RECEIVER] ||
	    !info->attrs[HWSIM_ATTR_FRAME] ||
@@ -3446,6 +3465,17 @@ static int hwsim_cloned_frame_received_nl(struct sk_buff *skb_2,
	if (!data2)
		goto out;

	if (data2->use_chanctx) {
		if (data2->tmp_chan)
			channel = data2->tmp_chan;
		else if (data2->chanctx)
			channel = data2->chanctx->def.chan;
	} else {
		channel = data2->channel;
	}
	if (!channel)
		goto out;

	if (!hwsim_virtio_enabled) {
		if (hwsim_net_get_netgroup(genl_info_net(info)) !=
		    data2->netgroup)
@@ -3457,7 +3487,7 @@ static int hwsim_cloned_frame_received_nl(struct sk_buff *skb_2,

	/* check if radio is configured properly */

	if (data2->idle || !data2->started)
	if ((data2->idle && !data2->tmp_chan) || !data2->started)
		goto out;

	/* A frame is received from user space */
@@ -3470,18 +3500,16 @@ static int hwsim_cloned_frame_received_nl(struct sk_buff *skb_2,
		mutex_lock(&data2->mutex);
		rx_status.freq = nla_get_u32(info->attrs[HWSIM_ATTR_FREQ]);

		if (rx_status.freq != data2->channel->center_freq &&
		    (!data2->tmp_chan ||
		     rx_status.freq != data2->tmp_chan->center_freq)) {
		if (rx_status.freq != channel->center_freq) {
			mutex_unlock(&data2->mutex);
			goto out;
		}
		mutex_unlock(&data2->mutex);
	} else {
		rx_status.freq = data2->channel->center_freq;
		rx_status.freq = channel->center_freq;
	}

	rx_status.band = data2->channel->band;
	rx_status.band = channel->band;
	rx_status.rate_idx = nla_get_u32(info->attrs[HWSIM_ATTR_RX_RATE]);
	if (rx_status.rate_idx >= data2->hw->wiphy->bands[rx_status.band]->n_bitrates)
		goto out;