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: Weilun Du <wdu@google.com> Link: https://lore.kernel.org/r/20210506180530.3418576-1-wdu@google.com Signed-off-by: Johannes 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: Weilun Du <wdu@google.com> Signed-off-by: Maciej Żenczykowski <maze@google.com> Change-Id: Ia9be6c1d962b941a92f4e1be41e874dbe08024e5
This commit is contained in:

committed by
Maciej Żenczykowski

parent
5b1baee639
commit
2e289f3641
@@ -561,6 +561,7 @@ struct mac80211_hwsim_data {
|
|||||||
u32 ciphers[ARRAY_SIZE(hwsim_ciphers)];
|
u32 ciphers[ARRAY_SIZE(hwsim_ciphers)];
|
||||||
|
|
||||||
struct mac_address addresses[2];
|
struct mac_address addresses[2];
|
||||||
|
struct ieee80211_chanctx_conf *chanctx;
|
||||||
int channels, idx;
|
int channels, idx;
|
||||||
bool use_chanctx;
|
bool use_chanctx;
|
||||||
bool destroy_on_close;
|
bool destroy_on_close;
|
||||||
@@ -1191,7 +1192,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,
|
static void mac80211_hwsim_tx_frame_nl(struct ieee80211_hw *hw,
|
||||||
struct sk_buff *my_skb,
|
struct sk_buff *my_skb,
|
||||||
int dst_portid)
|
int dst_portid,
|
||||||
|
struct ieee80211_channel *channel)
|
||||||
{
|
{
|
||||||
struct sk_buff *skb;
|
struct sk_buff *skb;
|
||||||
struct mac80211_hwsim_data *data = hw->priv;
|
struct mac80211_hwsim_data *data = hw->priv;
|
||||||
@@ -1246,7 +1248,7 @@ static void mac80211_hwsim_tx_frame_nl(struct ieee80211_hw *hw,
|
|||||||
if (nla_put_u32(skb, HWSIM_ATTR_FLAGS, hwsim_flags))
|
if (nla_put_u32(skb, HWSIM_ATTR_FLAGS, hwsim_flags))
|
||||||
goto nla_put_failure;
|
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;
|
goto nla_put_failure;
|
||||||
|
|
||||||
/* We get the tx control (rate and retries) info*/
|
/* We get the tx control (rate and retries) info*/
|
||||||
@@ -1593,7 +1595,7 @@ static void mac80211_hwsim_tx(struct ieee80211_hw *hw,
|
|||||||
_portid = READ_ONCE(data->wmediumd);
|
_portid = READ_ONCE(data->wmediumd);
|
||||||
|
|
||||||
if (_portid || hwsim_virtio_enabled)
|
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 */
|
/* NO wmediumd detected, perfect medium simulation */
|
||||||
data->tx_pkts++;
|
data->tx_pkts++;
|
||||||
@@ -1704,7 +1706,7 @@ static void mac80211_hwsim_tx_frame(struct ieee80211_hw *hw,
|
|||||||
mac80211_hwsim_monitor_rx(hw, skb, chan);
|
mac80211_hwsim_monitor_rx(hw, skb, chan);
|
||||||
|
|
||||||
if (_pid || hwsim_virtio_enabled)
|
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);
|
mac80211_hwsim_tx_frame_no_nl(hw, skb, chan);
|
||||||
dev_kfree_skb(skb);
|
dev_kfree_skb(skb);
|
||||||
@@ -2443,6 +2445,11 @@ static int mac80211_hwsim_croc(struct ieee80211_hw *hw,
|
|||||||
static int mac80211_hwsim_add_chanctx(struct ieee80211_hw *hw,
|
static int mac80211_hwsim_add_chanctx(struct ieee80211_hw *hw,
|
||||||
struct ieee80211_chanctx_conf *ctx)
|
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);
|
hwsim_set_chanctx_magic(ctx);
|
||||||
wiphy_dbg(hw->wiphy,
|
wiphy_dbg(hw->wiphy,
|
||||||
"add channel context control: %d MHz/width: %d/cfreqs:%d/%d MHz\n",
|
"add channel context control: %d MHz/width: %d/cfreqs:%d/%d MHz\n",
|
||||||
@@ -2454,6 +2461,11 @@ static int mac80211_hwsim_add_chanctx(struct ieee80211_hw *hw,
|
|||||||
static void mac80211_hwsim_remove_chanctx(struct ieee80211_hw *hw,
|
static void mac80211_hwsim_remove_chanctx(struct ieee80211_hw *hw,
|
||||||
struct ieee80211_chanctx_conf *ctx)
|
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,
|
wiphy_dbg(hw->wiphy,
|
||||||
"remove channel context control: %d MHz/width: %d/cfreqs:%d/%d MHz\n",
|
"remove channel context control: %d MHz/width: %d/cfreqs:%d/%d MHz\n",
|
||||||
ctx->def.chan->center_freq, ctx->def.width,
|
ctx->def.chan->center_freq, ctx->def.width,
|
||||||
@@ -2466,6 +2478,11 @@ static void mac80211_hwsim_change_chanctx(struct ieee80211_hw *hw,
|
|||||||
struct ieee80211_chanctx_conf *ctx,
|
struct ieee80211_chanctx_conf *ctx,
|
||||||
u32 changed)
|
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);
|
hwsim_check_chanctx_magic(ctx);
|
||||||
wiphy_dbg(hw->wiphy,
|
wiphy_dbg(hw->wiphy,
|
||||||
"change channel context control: %d MHz/width: %d/cfreqs:%d/%d MHz\n",
|
"change channel context control: %d MHz/width: %d/cfreqs:%d/%d MHz\n",
|
||||||
@@ -3060,6 +3077,7 @@ static int mac80211_hwsim_new_radio(struct genl_info *info,
|
|||||||
hw->wiphy->max_remain_on_channel_duration = 1000;
|
hw->wiphy->max_remain_on_channel_duration = 1000;
|
||||||
data->if_combination.radar_detect_widths = 0;
|
data->if_combination.radar_detect_widths = 0;
|
||||||
data->if_combination.num_different_channels = data->channels;
|
data->if_combination.num_different_channels = data->channels;
|
||||||
|
data->chanctx = NULL;
|
||||||
} else {
|
} else {
|
||||||
data->if_combination.num_different_channels = 1;
|
data->if_combination.num_different_channels = 1;
|
||||||
data->if_combination.radar_detect_widths =
|
data->if_combination.radar_detect_widths =
|
||||||
@@ -3567,6 +3585,7 @@ static int hwsim_cloned_frame_received_nl(struct sk_buff *skb_2,
|
|||||||
int frame_data_len;
|
int frame_data_len;
|
||||||
void *frame_data;
|
void *frame_data;
|
||||||
struct sk_buff *skb = NULL;
|
struct sk_buff *skb = NULL;
|
||||||
|
struct ieee80211_channel *channel = NULL;
|
||||||
|
|
||||||
if (!info->attrs[HWSIM_ATTR_ADDR_RECEIVER] ||
|
if (!info->attrs[HWSIM_ATTR_ADDR_RECEIVER] ||
|
||||||
!info->attrs[HWSIM_ATTR_FRAME] ||
|
!info->attrs[HWSIM_ATTR_FRAME] ||
|
||||||
@@ -3593,6 +3612,17 @@ static int hwsim_cloned_frame_received_nl(struct sk_buff *skb_2,
|
|||||||
if (!data2)
|
if (!data2)
|
||||||
goto out;
|
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_virtio_enabled) {
|
||||||
if (hwsim_net_get_netgroup(genl_info_net(info)) !=
|
if (hwsim_net_get_netgroup(genl_info_net(info)) !=
|
||||||
data2->netgroup)
|
data2->netgroup)
|
||||||
@@ -3604,7 +3634,7 @@ static int hwsim_cloned_frame_received_nl(struct sk_buff *skb_2,
|
|||||||
|
|
||||||
/* check if radio is configured properly */
|
/* check if radio is configured properly */
|
||||||
|
|
||||||
if (data2->idle || !data2->started)
|
if ((data2->idle && !data2->tmp_chan) || !data2->started)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
/* A frame is received from user space */
|
/* A frame is received from user space */
|
||||||
@@ -3617,18 +3647,16 @@ static int hwsim_cloned_frame_received_nl(struct sk_buff *skb_2,
|
|||||||
mutex_lock(&data2->mutex);
|
mutex_lock(&data2->mutex);
|
||||||
rx_status.freq = nla_get_u32(info->attrs[HWSIM_ATTR_FREQ]);
|
rx_status.freq = nla_get_u32(info->attrs[HWSIM_ATTR_FREQ]);
|
||||||
|
|
||||||
if (rx_status.freq != data2->channel->center_freq &&
|
if (rx_status.freq != channel->center_freq) {
|
||||||
(!data2->tmp_chan ||
|
|
||||||
rx_status.freq != data2->tmp_chan->center_freq)) {
|
|
||||||
mutex_unlock(&data2->mutex);
|
mutex_unlock(&data2->mutex);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
mutex_unlock(&data2->mutex);
|
mutex_unlock(&data2->mutex);
|
||||||
} else {
|
} 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]);
|
rx_status.rate_idx = nla_get_u32(info->attrs[HWSIM_ATTR_RX_RATE]);
|
||||||
rx_status.signal = nla_get_u32(info->attrs[HWSIM_ATTR_SIGNAL]);
|
rx_status.signal = nla_get_u32(info->attrs[HWSIM_ATTR_SIGNAL]);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user