summaryrefslogtreecommitdiff
path: root/drivers/net/wireless/mac80211_hwsim.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/mac80211_hwsim.c')
-rw-r--r--drivers/net/wireless/mac80211_hwsim.c51
1 files changed, 37 insertions, 14 deletions
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c
index fb787df01666..643f968b05ee 100644
--- a/drivers/net/wireless/mac80211_hwsim.c
+++ b/drivers/net/wireless/mac80211_hwsim.c
@@ -292,7 +292,7 @@ struct mac80211_hwsim_data {
struct list_head list;
struct ieee80211_hw *hw;
struct device *dev;
- struct ieee80211_supported_band bands[2];
+ struct ieee80211_supported_band bands[IEEE80211_NUM_BANDS];
struct ieee80211_channel channels_2ghz[ARRAY_SIZE(hwsim_channels_2ghz)];
struct ieee80211_channel channels_5ghz[ARRAY_SIZE(hwsim_channels_5ghz)];
struct ieee80211_rate rates[ARRAY_SIZE(hwsim_rates)];
@@ -571,7 +571,7 @@ static void mac80211_hwsim_tx_frame_nl(struct ieee80211_hw *hw,
skb_dequeue(&data->pending);
}
- skb = genlmsg_new(NLMSG_GOODSIZE, GFP_ATOMIC);
+ skb = genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_ATOMIC);
if (skb == NULL)
goto nla_put_failure;
@@ -678,8 +678,7 @@ static bool mac80211_hwsim_tx_frame_no_nl(struct ieee80211_hw *hw,
continue;
if (data2->idle || !data2->started ||
- !hwsim_ps_rx_ok(data2, skb) ||
- !data->channel || !data2->channel ||
+ !hwsim_ps_rx_ok(data2, skb) || !data2->channel ||
data->channel->center_freq != data2->channel->center_freq ||
!(data->group & data2->group))
continue;
@@ -1083,6 +1082,8 @@ enum hwsim_testmode_attr {
enum hwsim_testmode_cmd {
HWSIM_TM_CMD_SET_PS = 0,
HWSIM_TM_CMD_GET_PS = 1,
+ HWSIM_TM_CMD_STOP_QUEUES = 2,
+ HWSIM_TM_CMD_WAKE_QUEUES = 3,
};
static const struct nla_policy hwsim_testmode_policy[HWSIM_TM_ATTR_MAX + 1] = {
@@ -1122,6 +1123,12 @@ static int mac80211_hwsim_testmode_cmd(struct ieee80211_hw *hw,
if (nla_put_u32(skb, HWSIM_TM_ATTR_PS, hwsim->ps))
goto nla_put_failure;
return cfg80211_testmode_reply(skb);
+ case HWSIM_TM_CMD_STOP_QUEUES:
+ ieee80211_stop_queues(hw);
+ return 0;
+ case HWSIM_TM_CMD_WAKE_QUEUES:
+ ieee80211_wake_queues(hw);
+ return 0;
default:
return -EOPNOTSUPP;
}
@@ -1486,7 +1493,7 @@ static int hwsim_tx_info_frame_received_nl(struct sk_buff *skb_2,
struct mac80211_hwsim_data *data2;
struct ieee80211_tx_info *txi;
struct hwsim_tx_rate *tx_attempts;
- struct sk_buff __user *ret_skb;
+ unsigned long ret_skb_ptr;
struct sk_buff *skb, *tmp;
struct mac_address *src;
unsigned int hwsim_flags;
@@ -1504,8 +1511,7 @@ static int hwsim_tx_info_frame_received_nl(struct sk_buff *skb_2,
info->attrs[HWSIM_ATTR_ADDR_TRANSMITTER]);
hwsim_flags = nla_get_u32(info->attrs[HWSIM_ATTR_FLAGS]);
- ret_skb = (struct sk_buff __user *)
- (unsigned long) nla_get_u64(info->attrs[HWSIM_ATTR_COOKIE]);
+ ret_skb_ptr = nla_get_u64(info->attrs[HWSIM_ATTR_COOKIE]);
data2 = get_hwsim_data_ref_from_addr(src);
@@ -1514,7 +1520,7 @@ static int hwsim_tx_info_frame_received_nl(struct sk_buff *skb_2,
/* look for the skb matching the cookie passed back from user */
skb_queue_walk_safe(&data2->pending, skb, tmp) {
- if (skb == ret_skb) {
+ if ((unsigned long)skb == ret_skb_ptr) {
skb_unlink(skb, &data2->pending);
found = true;
break;
@@ -1534,11 +1540,6 @@ static int hwsim_tx_info_frame_received_nl(struct sk_buff *skb_2,
/* now send back TX status */
txi = IEEE80211_SKB_CB(skb);
- if (txi->control.vif)
- hwsim_check_magic(txi->control.vif);
- if (txi->control.sta)
- hwsim_check_sta_magic(txi->control.sta);
-
ieee80211_tx_info_clear_status(txi);
for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) {
@@ -1555,6 +1556,7 @@ static int hwsim_tx_info_frame_received_nl(struct sk_buff *skb_2,
hdr = (struct ieee80211_hdr *) skb->data;
mac80211_hwsim_monitor_ack(data2->hw, hdr->addr2);
}
+ txi->flags |= IEEE80211_TX_STAT_ACK;
}
ieee80211_tx_status_irqsafe(data2->hw, skb);
return 0;
@@ -1721,6 +1723,24 @@ static void hwsim_exit_netlink(void)
"unregister family %i\n", ret);
}
+static const struct ieee80211_iface_limit hwsim_if_limits[] = {
+ { .max = 1, .types = BIT(NL80211_IFTYPE_ADHOC) },
+ { .max = 2048, .types = BIT(NL80211_IFTYPE_STATION) |
+ BIT(NL80211_IFTYPE_P2P_CLIENT) |
+#ifdef CONFIG_MAC80211_MESH
+ BIT(NL80211_IFTYPE_MESH_POINT) |
+#endif
+ BIT(NL80211_IFTYPE_AP) |
+ BIT(NL80211_IFTYPE_P2P_GO) },
+};
+
+static const struct ieee80211_iface_combination hwsim_if_comb = {
+ .limits = hwsim_if_limits,
+ .n_limits = ARRAY_SIZE(hwsim_if_limits),
+ .max_interfaces = 2048,
+ .num_different_channels = 1,
+};
+
static int __init init_mac80211_hwsim(void)
{
int i, err = 0;
@@ -1782,6 +1802,9 @@ static int __init init_mac80211_hwsim(void)
hw->wiphy->n_addresses = 2;
hw->wiphy->addresses = data->addresses;
+ hw->wiphy->iface_combinations = &hwsim_if_comb;
+ hw->wiphy->n_iface_combinations = 1;
+
if (fake_hw_scan) {
hw->wiphy->max_scan_ssids = 255;
hw->wiphy->max_scan_ie_len = IEEE80211_MAX_DATA_LEN;
@@ -1835,7 +1858,7 @@ static int __init init_mac80211_hwsim(void)
sband->n_bitrates = ARRAY_SIZE(hwsim_rates) - 4;
break;
default:
- break;
+ continue;
}
sband->ht_cap.ht_supported = true;