mac80211_hwsim: refactor radio registration
In order to support dynamic radio registration in the future, refactor the actual registration into a new function with only minor cleanups. Since it had to change anyway, also clean up the init error paths. Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
parent
3a8cc5e73f
commit
f39c2bfa9a
1 changed files with 225 additions and 230 deletions
|
@ -2122,70 +2122,27 @@ static const struct ieee80211_iface_combination hwsim_if_comb[] = {
|
|||
}
|
||||
};
|
||||
|
||||
static int __init init_mac80211_hwsim(void)
|
||||
static int __init mac80211_hwsim_create_radio(int idx)
|
||||
{
|
||||
int i, err = 0;
|
||||
int err;
|
||||
u8 addr[ETH_ALEN];
|
||||
struct mac80211_hwsim_data *data;
|
||||
struct ieee80211_hw *hw;
|
||||
enum ieee80211_band band;
|
||||
const struct ieee80211_ops *ops;
|
||||
const struct ieee80211_ops *ops = &mac80211_hwsim_ops;
|
||||
|
||||
if (radios < 1 || radios > 100)
|
||||
return -EINVAL;
|
||||
|
||||
if (channels < 1)
|
||||
return -EINVAL;
|
||||
|
||||
mac80211_hwsim_mchan_ops = mac80211_hwsim_ops;
|
||||
mac80211_hwsim_mchan_ops.hw_scan = mac80211_hwsim_hw_scan;
|
||||
mac80211_hwsim_mchan_ops.cancel_hw_scan = mac80211_hwsim_cancel_hw_scan;
|
||||
mac80211_hwsim_mchan_ops.sw_scan_start = NULL;
|
||||
mac80211_hwsim_mchan_ops.sw_scan_complete = NULL;
|
||||
mac80211_hwsim_mchan_ops.remain_on_channel = mac80211_hwsim_roc;
|
||||
mac80211_hwsim_mchan_ops.cancel_remain_on_channel = mac80211_hwsim_croc;
|
||||
mac80211_hwsim_mchan_ops.add_chanctx = mac80211_hwsim_add_chanctx;
|
||||
mac80211_hwsim_mchan_ops.remove_chanctx = mac80211_hwsim_remove_chanctx;
|
||||
mac80211_hwsim_mchan_ops.change_chanctx = mac80211_hwsim_change_chanctx;
|
||||
mac80211_hwsim_mchan_ops.assign_vif_chanctx =
|
||||
mac80211_hwsim_assign_vif_chanctx;
|
||||
mac80211_hwsim_mchan_ops.unassign_vif_chanctx =
|
||||
mac80211_hwsim_unassign_vif_chanctx;
|
||||
|
||||
spin_lock_init(&hwsim_radio_lock);
|
||||
INIT_LIST_HEAD(&hwsim_radios);
|
||||
|
||||
err = platform_driver_register(&mac80211_hwsim_driver);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
hwsim_class = class_create(THIS_MODULE, "mac80211_hwsim");
|
||||
if (IS_ERR(hwsim_class)) {
|
||||
err = PTR_ERR(hwsim_class);
|
||||
goto failed_unregister_driver;
|
||||
}
|
||||
|
||||
memset(addr, 0, ETH_ALEN);
|
||||
addr[0] = 0x02;
|
||||
|
||||
for (i = 0; i < radios; i++) {
|
||||
printk(KERN_DEBUG "mac80211_hwsim: Initializing radio %d\n",
|
||||
i);
|
||||
ops = &mac80211_hwsim_ops;
|
||||
if (channels > 1)
|
||||
ops = &mac80211_hwsim_mchan_ops;
|
||||
hw = ieee80211_alloc_hw(sizeof(*data), ops);
|
||||
if (!hw) {
|
||||
printk(KERN_DEBUG "mac80211_hwsim: ieee80211_alloc_hw "
|
||||
"failed\n");
|
||||
printk(KERN_DEBUG "mac80211_hwsim: ieee80211_alloc_hw failed\n");
|
||||
err = -ENOMEM;
|
||||
goto failed;
|
||||
}
|
||||
data = hw->priv;
|
||||
data->hw = hw;
|
||||
|
||||
data->dev = device_create(hwsim_class, NULL, 0, hw,
|
||||
"hwsim%d", i);
|
||||
data->dev = device_create(hwsim_class, NULL, 0, hw, "hwsim%d", idx);
|
||||
if (IS_ERR(data->dev)) {
|
||||
printk(KERN_DEBUG
|
||||
"mac80211_hwsim: device_create failed (%ld)\n",
|
||||
|
@ -2196,8 +2153,7 @@ static int __init init_mac80211_hwsim(void)
|
|||
data->dev->driver = &mac80211_hwsim_driver.driver;
|
||||
err = device_bind_driver(data->dev);
|
||||
if (err != 0) {
|
||||
printk(KERN_DEBUG
|
||||
"mac80211_hwsim: device_bind_driver failed (%d)\n",
|
||||
printk(KERN_DEBUG "mac80211_hwsim: device_bind_driver failed (%d)\n",
|
||||
err);
|
||||
goto failed_hw;
|
||||
}
|
||||
|
@ -2205,8 +2161,10 @@ static int __init init_mac80211_hwsim(void)
|
|||
skb_queue_head_init(&data->pending);
|
||||
|
||||
SET_IEEE80211_DEV(hw, data->dev);
|
||||
addr[3] = i >> 8;
|
||||
addr[4] = i;
|
||||
memset(addr, 0, ETH_ALEN);
|
||||
addr[0] = 0x02;
|
||||
addr[3] = idx >> 8;
|
||||
addr[4] = idx;
|
||||
memcpy(data->addresses[0].addr, addr, ETH_ALEN);
|
||||
memcpy(data->addresses[1].addr, addr, ETH_ALEN);
|
||||
data->addresses[1].addr[0] |= 0x40;
|
||||
|
@ -2223,12 +2181,10 @@ static int __init init_mac80211_hwsim(void)
|
|||
hw->wiphy->n_iface_combinations = 1;
|
||||
hw->wiphy->iface_combinations = &data->if_combination;
|
||||
data->if_combination = hwsim_if_comb[0];
|
||||
data->if_combination.num_different_channels =
|
||||
data->channels;
|
||||
data->if_combination.num_different_channels = data->channels;
|
||||
} else {
|
||||
hw->wiphy->iface_combinations = hwsim_if_comb;
|
||||
hw->wiphy->n_iface_combinations =
|
||||
ARRAY_SIZE(hwsim_if_comb);
|
||||
hw->wiphy->n_iface_combinations = ARRAY_SIZE(hwsim_if_comb);
|
||||
}
|
||||
|
||||
INIT_DELAYED_WORK(&data->roc_done, hw_roc_done);
|
||||
|
@ -2236,8 +2192,7 @@ static int __init init_mac80211_hwsim(void)
|
|||
|
||||
hw->queues = 5;
|
||||
hw->offchannel_tx_hw_queue = 4;
|
||||
hw->wiphy->interface_modes =
|
||||
BIT(NL80211_IFTYPE_STATION) |
|
||||
hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
|
||||
BIT(NL80211_IFTYPE_AP) |
|
||||
BIT(NL80211_IFTYPE_P2P_CLIENT) |
|
||||
BIT(NL80211_IFTYPE_P2P_GO) |
|
||||
|
@ -2277,15 +2232,13 @@ static int __init init_mac80211_hwsim(void)
|
|||
switch (band) {
|
||||
case IEEE80211_BAND_2GHZ:
|
||||
sband->channels = data->channels_2ghz;
|
||||
sband->n_channels =
|
||||
ARRAY_SIZE(hwsim_channels_2ghz);
|
||||
sband->n_channels = ARRAY_SIZE(hwsim_channels_2ghz);
|
||||
sband->bitrates = data->rates;
|
||||
sband->n_bitrates = ARRAY_SIZE(hwsim_rates);
|
||||
break;
|
||||
case IEEE80211_BAND_5GHZ:
|
||||
sband->channels = data->channels_5ghz;
|
||||
sband->n_channels =
|
||||
ARRAY_SIZE(hwsim_channels_5ghz);
|
||||
sband->n_channels = ARRAY_SIZE(hwsim_channels_5ghz);
|
||||
sband->bitrates = data->rates + 4;
|
||||
sband->n_bitrates = ARRAY_SIZE(hwsim_rates) - 4;
|
||||
break;
|
||||
|
@ -2334,7 +2287,8 @@ static int __init init_mac80211_hwsim(void)
|
|||
sband->vht_cap.vht_mcs.tx_mcs_map =
|
||||
sband->vht_cap.vht_mcs.rx_mcs_map;
|
||||
}
|
||||
/* By default all radios are belonging to the first group */
|
||||
|
||||
/* By default all radios belong to the first group */
|
||||
data->group = 1;
|
||||
mutex_init(&data->mutex);
|
||||
|
||||
|
@ -2344,21 +2298,18 @@ static int __init init_mac80211_hwsim(void)
|
|||
|
||||
err = ieee80211_register_hw(hw);
|
||||
if (err < 0) {
|
||||
printk(KERN_DEBUG "mac80211_hwsim: "
|
||||
"ieee80211_register_hw failed (%d)\n", err);
|
||||
printk(KERN_DEBUG "mac80211_hwsim: ieee80211_register_hw failed (%d)\n",
|
||||
err);
|
||||
goto failed_hw;
|
||||
}
|
||||
|
||||
wiphy_debug(hw->wiphy, "hwaddr %pm registered\n",
|
||||
hw->wiphy->perm_addr);
|
||||
wiphy_debug(hw->wiphy, "hwaddr %pM registered\n", hw->wiphy->perm_addr);
|
||||
|
||||
data->debugfs = debugfs_create_dir("hwsim",
|
||||
hw->wiphy->debugfsdir);
|
||||
debugfs_create_file("ps", 0666, data->debugfs, data,
|
||||
&hwsim_fops_ps);
|
||||
data->debugfs = debugfs_create_dir("hwsim", hw->wiphy->debugfsdir);
|
||||
debugfs_create_file("ps", 0666, data->debugfs, data, &hwsim_fops_ps);
|
||||
debugfs_create_file("group", 0666, data->debugfs, data,
|
||||
&hwsim_fops_group);
|
||||
if (channels == 1)
|
||||
if (data->channels == 1)
|
||||
debugfs_create_file("dfs_simulate_radar", 0222,
|
||||
data->debugfs,
|
||||
data, &hwsim_simulate_radar);
|
||||
|
@ -2367,51 +2318,95 @@ static int __init init_mac80211_hwsim(void)
|
|||
mac80211_hwsim_beacon,
|
||||
CLOCK_MONOTONIC_RAW, HRTIMER_MODE_ABS);
|
||||
|
||||
spin_lock_bh(&hwsim_radio_lock);
|
||||
list_add_tail(&data->list, &hwsim_radios);
|
||||
}
|
||||
|
||||
hwsim_mon = alloc_netdev(0, "hwsim%d", hwsim_mon_setup);
|
||||
if (hwsim_mon == NULL) {
|
||||
err = -ENOMEM;
|
||||
goto failed;
|
||||
}
|
||||
|
||||
rtnl_lock();
|
||||
|
||||
err = dev_alloc_name(hwsim_mon, hwsim_mon->name);
|
||||
if (err < 0)
|
||||
goto failed_mon;
|
||||
|
||||
|
||||
err = register_netdevice(hwsim_mon);
|
||||
if (err < 0)
|
||||
goto failed_mon;
|
||||
|
||||
rtnl_unlock();
|
||||
|
||||
err = hwsim_init_netlink();
|
||||
if (err < 0)
|
||||
goto failed_nl;
|
||||
spin_unlock_bh(&hwsim_radio_lock);
|
||||
|
||||
return 0;
|
||||
|
||||
failed_nl:
|
||||
printk(KERN_DEBUG "mac80211_hwsim: failed initializing netlink\n");
|
||||
return err;
|
||||
|
||||
failed_mon:
|
||||
rtnl_unlock();
|
||||
free_netdev(hwsim_mon);
|
||||
mac80211_hwsim_free();
|
||||
return err;
|
||||
|
||||
failed_hw:
|
||||
device_unregister(data->dev);
|
||||
failed_drvdata:
|
||||
ieee80211_free_hw(hw);
|
||||
failed:
|
||||
return err;
|
||||
}
|
||||
|
||||
static int __init init_mac80211_hwsim(void)
|
||||
{
|
||||
int i, err;
|
||||
|
||||
if (radios < 1 || radios > 100)
|
||||
return -EINVAL;
|
||||
|
||||
if (channels < 1)
|
||||
return -EINVAL;
|
||||
|
||||
mac80211_hwsim_mchan_ops = mac80211_hwsim_ops;
|
||||
mac80211_hwsim_mchan_ops.hw_scan = mac80211_hwsim_hw_scan;
|
||||
mac80211_hwsim_mchan_ops.cancel_hw_scan = mac80211_hwsim_cancel_hw_scan;
|
||||
mac80211_hwsim_mchan_ops.sw_scan_start = NULL;
|
||||
mac80211_hwsim_mchan_ops.sw_scan_complete = NULL;
|
||||
mac80211_hwsim_mchan_ops.remain_on_channel = mac80211_hwsim_roc;
|
||||
mac80211_hwsim_mchan_ops.cancel_remain_on_channel = mac80211_hwsim_croc;
|
||||
mac80211_hwsim_mchan_ops.add_chanctx = mac80211_hwsim_add_chanctx;
|
||||
mac80211_hwsim_mchan_ops.remove_chanctx = mac80211_hwsim_remove_chanctx;
|
||||
mac80211_hwsim_mchan_ops.change_chanctx = mac80211_hwsim_change_chanctx;
|
||||
mac80211_hwsim_mchan_ops.assign_vif_chanctx =
|
||||
mac80211_hwsim_assign_vif_chanctx;
|
||||
mac80211_hwsim_mchan_ops.unassign_vif_chanctx =
|
||||
mac80211_hwsim_unassign_vif_chanctx;
|
||||
|
||||
spin_lock_init(&hwsim_radio_lock);
|
||||
INIT_LIST_HEAD(&hwsim_radios);
|
||||
|
||||
err = platform_driver_register(&mac80211_hwsim_driver);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
hwsim_class = class_create(THIS_MODULE, "mac80211_hwsim");
|
||||
if (IS_ERR(hwsim_class)) {
|
||||
err = PTR_ERR(hwsim_class);
|
||||
goto out_unregister_driver;
|
||||
}
|
||||
|
||||
for (i = 0; i < radios; i++) {
|
||||
err = mac80211_hwsim_create_radio(i);
|
||||
if (err)
|
||||
goto out_free_radios;
|
||||
}
|
||||
|
||||
hwsim_mon = alloc_netdev(0, "hwsim%d", hwsim_mon_setup);
|
||||
if (hwsim_mon == NULL) {
|
||||
err = -ENOMEM;
|
||||
goto out_free_radios;
|
||||
}
|
||||
|
||||
rtnl_lock();
|
||||
err = dev_alloc_name(hwsim_mon, hwsim_mon->name);
|
||||
if (err < 0) {
|
||||
rtnl_unlock();
|
||||
goto out_free_radios;
|
||||
}
|
||||
|
||||
err = register_netdevice(hwsim_mon);
|
||||
if (err < 0) {
|
||||
rtnl_unlock();
|
||||
goto out_free_mon;
|
||||
}
|
||||
rtnl_unlock();
|
||||
|
||||
err = hwsim_init_netlink();
|
||||
if (err < 0)
|
||||
goto out_free_mon;
|
||||
|
||||
return 0;
|
||||
|
||||
out_free_mon:
|
||||
free_netdev(hwsim_mon);
|
||||
out_free_radios:
|
||||
mac80211_hwsim_free();
|
||||
failed_unregister_driver:
|
||||
out_unregister_driver:
|
||||
platform_driver_unregister(&mac80211_hwsim_driver);
|
||||
return err;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue