aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/mac80211_hwsim.c
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2014-01-06 16:39:27 -0500
committerJohannes Berg <johannes.berg@intel.com>2014-01-10 14:12:57 -0500
commitf39c2bfa9a1e2bae726cce65d2d328652e81f0c2 (patch)
treee7ec076b7842d20371f217b833c93859b4a76187 /drivers/net/wireless/mac80211_hwsim.c
parent3a8cc5e73f7105faf32fb8df57ba3e7b967e1982 (diff)
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>
Diffstat (limited to 'drivers/net/wireless/mac80211_hwsim.c')
-rw-r--r--drivers/net/wireless/mac80211_hwsim.c455
1 files changed, 225 insertions, 230 deletions
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c
index 55cdfd6a40e8..23fa6ee8eefe 100644
--- a/drivers/net/wireless/mac80211_hwsim.c
+++ b/drivers/net/wireless/mac80211_hwsim.c
@@ -2122,14 +2122,219 @@ static const struct ieee80211_iface_combination hwsim_if_comb[] = {
2122 } 2122 }
2123}; 2123};
2124 2124
2125static int __init init_mac80211_hwsim(void) 2125static int __init mac80211_hwsim_create_radio(int idx)
2126{ 2126{
2127 int i, err = 0; 2127 int err;
2128 u8 addr[ETH_ALEN]; 2128 u8 addr[ETH_ALEN];
2129 struct mac80211_hwsim_data *data; 2129 struct mac80211_hwsim_data *data;
2130 struct ieee80211_hw *hw; 2130 struct ieee80211_hw *hw;
2131 enum ieee80211_band band; 2131 enum ieee80211_band band;
2132 const struct ieee80211_ops *ops; 2132 const struct ieee80211_ops *ops = &mac80211_hwsim_ops;
2133
2134 if (channels > 1)
2135 ops = &mac80211_hwsim_mchan_ops;
2136 hw = ieee80211_alloc_hw(sizeof(*data), ops);
2137 if (!hw) {
2138 printk(KERN_DEBUG "mac80211_hwsim: ieee80211_alloc_hw failed\n");
2139 err = -ENOMEM;
2140 goto failed;
2141 }
2142 data = hw->priv;
2143 data->hw = hw;
2144
2145 data->dev = device_create(hwsim_class, NULL, 0, hw, "hwsim%d", idx);
2146 if (IS_ERR(data->dev)) {
2147 printk(KERN_DEBUG
2148 "mac80211_hwsim: device_create failed (%ld)\n",
2149 PTR_ERR(data->dev));
2150 err = -ENOMEM;
2151 goto failed_drvdata;
2152 }
2153 data->dev->driver = &mac80211_hwsim_driver.driver;
2154 err = device_bind_driver(data->dev);
2155 if (err != 0) {
2156 printk(KERN_DEBUG "mac80211_hwsim: device_bind_driver failed (%d)\n",
2157 err);
2158 goto failed_hw;
2159 }
2160
2161 skb_queue_head_init(&data->pending);
2162
2163 SET_IEEE80211_DEV(hw, data->dev);
2164 memset(addr, 0, ETH_ALEN);
2165 addr[0] = 0x02;
2166 addr[3] = idx >> 8;
2167 addr[4] = idx;
2168 memcpy(data->addresses[0].addr, addr, ETH_ALEN);
2169 memcpy(data->addresses[1].addr, addr, ETH_ALEN);
2170 data->addresses[1].addr[0] |= 0x40;
2171 hw->wiphy->n_addresses = 2;
2172 hw->wiphy->addresses = data->addresses;
2173
2174 data->channels = channels;
2175
2176 if (data->channels > 1) {
2177 hw->wiphy->max_scan_ssids = 255;
2178 hw->wiphy->max_scan_ie_len = IEEE80211_MAX_DATA_LEN;
2179 hw->wiphy->max_remain_on_channel_duration = 1000;
2180 /* For channels > 1 DFS is not allowed */
2181 hw->wiphy->n_iface_combinations = 1;
2182 hw->wiphy->iface_combinations = &data->if_combination;
2183 data->if_combination = hwsim_if_comb[0];
2184 data->if_combination.num_different_channels = data->channels;
2185 } else {
2186 hw->wiphy->iface_combinations = hwsim_if_comb;
2187 hw->wiphy->n_iface_combinations = ARRAY_SIZE(hwsim_if_comb);
2188 }
2189
2190 INIT_DELAYED_WORK(&data->roc_done, hw_roc_done);
2191 INIT_DELAYED_WORK(&data->hw_scan, hw_scan_work);
2192
2193 hw->queues = 5;
2194 hw->offchannel_tx_hw_queue = 4;
2195 hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
2196 BIT(NL80211_IFTYPE_AP) |
2197 BIT(NL80211_IFTYPE_P2P_CLIENT) |
2198 BIT(NL80211_IFTYPE_P2P_GO) |
2199 BIT(NL80211_IFTYPE_ADHOC) |
2200 BIT(NL80211_IFTYPE_MESH_POINT) |
2201 BIT(NL80211_IFTYPE_P2P_DEVICE);
2202
2203 hw->flags = IEEE80211_HW_MFP_CAPABLE |
2204 IEEE80211_HW_SIGNAL_DBM |
2205 IEEE80211_HW_SUPPORTS_STATIC_SMPS |
2206 IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS |
2207 IEEE80211_HW_AMPDU_AGGREGATION |
2208 IEEE80211_HW_WANT_MONITOR_VIF |
2209 IEEE80211_HW_QUEUE_CONTROL |
2210 IEEE80211_HW_SUPPORTS_HT_CCK_RATES;
2211 if (rctbl)
2212 hw->flags |= IEEE80211_HW_SUPPORTS_RC_TABLE;
2213
2214 hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS |
2215 WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL |
2216 WIPHY_FLAG_AP_UAPSD;
2217 hw->wiphy->features |= NL80211_FEATURE_ACTIVE_MONITOR;
2218
2219 /* ask mac80211 to reserve space for magic */
2220 hw->vif_data_size = sizeof(struct hwsim_vif_priv);
2221 hw->sta_data_size = sizeof(struct hwsim_sta_priv);
2222 hw->chanctx_data_size = sizeof(struct hwsim_chanctx_priv);
2223
2224 memcpy(data->channels_2ghz, hwsim_channels_2ghz,
2225 sizeof(hwsim_channels_2ghz));
2226 memcpy(data->channels_5ghz, hwsim_channels_5ghz,
2227 sizeof(hwsim_channels_5ghz));
2228 memcpy(data->rates, hwsim_rates, sizeof(hwsim_rates));
2229
2230 for (band = IEEE80211_BAND_2GHZ; band < IEEE80211_NUM_BANDS; band++) {
2231 struct ieee80211_supported_band *sband = &data->bands[band];
2232 switch (band) {
2233 case IEEE80211_BAND_2GHZ:
2234 sband->channels = data->channels_2ghz;
2235 sband->n_channels = ARRAY_SIZE(hwsim_channels_2ghz);
2236 sband->bitrates = data->rates;
2237 sband->n_bitrates = ARRAY_SIZE(hwsim_rates);
2238 break;
2239 case IEEE80211_BAND_5GHZ:
2240 sband->channels = data->channels_5ghz;
2241 sband->n_channels = ARRAY_SIZE(hwsim_channels_5ghz);
2242 sband->bitrates = data->rates + 4;
2243 sband->n_bitrates = ARRAY_SIZE(hwsim_rates) - 4;
2244 break;
2245 default:
2246 continue;
2247 }
2248
2249 sband->ht_cap.ht_supported = true;
2250 sband->ht_cap.cap = IEEE80211_HT_CAP_SUP_WIDTH_20_40 |
2251 IEEE80211_HT_CAP_GRN_FLD |
2252 IEEE80211_HT_CAP_SGI_40 |
2253 IEEE80211_HT_CAP_DSSSCCK40;
2254 sband->ht_cap.ampdu_factor = 0x3;
2255 sband->ht_cap.ampdu_density = 0x6;
2256 memset(&sband->ht_cap.mcs, 0,
2257 sizeof(sband->ht_cap.mcs));
2258 sband->ht_cap.mcs.rx_mask[0] = 0xff;
2259 sband->ht_cap.mcs.rx_mask[1] = 0xff;
2260 sband->ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED;
2261
2262 hw->wiphy->bands[band] = sband;
2263
2264 sband->vht_cap.vht_supported = true;
2265 sband->vht_cap.cap =
2266 IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454 |
2267 IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ |
2268 IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ |
2269 IEEE80211_VHT_CAP_RXLDPC |
2270 IEEE80211_VHT_CAP_SHORT_GI_80 |
2271 IEEE80211_VHT_CAP_SHORT_GI_160 |
2272 IEEE80211_VHT_CAP_TXSTBC |
2273 IEEE80211_VHT_CAP_RXSTBC_1 |
2274 IEEE80211_VHT_CAP_RXSTBC_2 |
2275 IEEE80211_VHT_CAP_RXSTBC_3 |
2276 IEEE80211_VHT_CAP_RXSTBC_4 |
2277 IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK;
2278 sband->vht_cap.vht_mcs.rx_mcs_map =
2279 cpu_to_le16(IEEE80211_VHT_MCS_SUPPORT_0_8 << 0 |
2280 IEEE80211_VHT_MCS_SUPPORT_0_8 << 2 |
2281 IEEE80211_VHT_MCS_SUPPORT_0_9 << 4 |
2282 IEEE80211_VHT_MCS_SUPPORT_0_8 << 6 |
2283 IEEE80211_VHT_MCS_SUPPORT_0_8 << 8 |
2284 IEEE80211_VHT_MCS_SUPPORT_0_9 << 10 |
2285 IEEE80211_VHT_MCS_SUPPORT_0_9 << 12 |
2286 IEEE80211_VHT_MCS_SUPPORT_0_8 << 14);
2287 sband->vht_cap.vht_mcs.tx_mcs_map =
2288 sband->vht_cap.vht_mcs.rx_mcs_map;
2289 }
2290
2291 /* By default all radios belong to the first group */
2292 data->group = 1;
2293 mutex_init(&data->mutex);
2294
2295 /* Enable frame retransmissions for lossy channels */
2296 hw->max_rates = 4;
2297 hw->max_rate_tries = 11;
2298
2299 err = ieee80211_register_hw(hw);
2300 if (err < 0) {
2301 printk(KERN_DEBUG "mac80211_hwsim: ieee80211_register_hw failed (%d)\n",
2302 err);
2303 goto failed_hw;
2304 }
2305
2306 wiphy_debug(hw->wiphy, "hwaddr %pM registered\n", hw->wiphy->perm_addr);
2307
2308 data->debugfs = debugfs_create_dir("hwsim", hw->wiphy->debugfsdir);
2309 debugfs_create_file("ps", 0666, data->debugfs, data, &hwsim_fops_ps);
2310 debugfs_create_file("group", 0666, data->debugfs, data,
2311 &hwsim_fops_group);
2312 if (data->channels == 1)
2313 debugfs_create_file("dfs_simulate_radar", 0222,
2314 data->debugfs,
2315 data, &hwsim_simulate_radar);
2316
2317 tasklet_hrtimer_init(&data->beacon_timer,
2318 mac80211_hwsim_beacon,
2319 CLOCK_MONOTONIC_RAW, HRTIMER_MODE_ABS);
2320
2321 spin_lock_bh(&hwsim_radio_lock);
2322 list_add_tail(&data->list, &hwsim_radios);
2323 spin_unlock_bh(&hwsim_radio_lock);
2324
2325 return 0;
2326
2327failed_hw:
2328 device_unregister(data->dev);
2329failed_drvdata:
2330 ieee80211_free_hw(hw);
2331failed:
2332 return err;
2333}
2334
2335static int __init init_mac80211_hwsim(void)
2336{
2337 int i, err;
2133 2338
2134 if (radios < 1 || radios > 100) 2339 if (radios < 1 || radios > 100)
2135 return -EINVAL; 2340 return -EINVAL;
@@ -2162,256 +2367,46 @@ static int __init init_mac80211_hwsim(void)
2162 hwsim_class = class_create(THIS_MODULE, "mac80211_hwsim"); 2367 hwsim_class = class_create(THIS_MODULE, "mac80211_hwsim");
2163 if (IS_ERR(hwsim_class)) { 2368 if (IS_ERR(hwsim_class)) {
2164 err = PTR_ERR(hwsim_class); 2369 err = PTR_ERR(hwsim_class);
2165 goto failed_unregister_driver; 2370 goto out_unregister_driver;
2166 } 2371 }
2167 2372
2168 memset(addr, 0, ETH_ALEN);
2169 addr[0] = 0x02;
2170
2171 for (i = 0; i < radios; i++) { 2373 for (i = 0; i < radios; i++) {
2172 printk(KERN_DEBUG "mac80211_hwsim: Initializing radio %d\n", 2374 err = mac80211_hwsim_create_radio(i);
2173 i); 2375 if (err)
2174 ops = &mac80211_hwsim_ops; 2376 goto out_free_radios;
2175 if (channels > 1)
2176 ops = &mac80211_hwsim_mchan_ops;
2177 hw = ieee80211_alloc_hw(sizeof(*data), ops);
2178 if (!hw) {
2179 printk(KERN_DEBUG "mac80211_hwsim: ieee80211_alloc_hw "
2180 "failed\n");
2181 err = -ENOMEM;
2182 goto failed;
2183 }
2184 data = hw->priv;
2185 data->hw = hw;
2186
2187 data->dev = device_create(hwsim_class, NULL, 0, hw,
2188 "hwsim%d", i);
2189 if (IS_ERR(data->dev)) {
2190 printk(KERN_DEBUG
2191 "mac80211_hwsim: device_create failed (%ld)\n",
2192 PTR_ERR(data->dev));
2193 err = -ENOMEM;
2194 goto failed_drvdata;
2195 }
2196 data->dev->driver = &mac80211_hwsim_driver.driver;
2197 err = device_bind_driver(data->dev);
2198 if (err != 0) {
2199 printk(KERN_DEBUG
2200 "mac80211_hwsim: device_bind_driver failed (%d)\n",
2201 err);
2202 goto failed_hw;
2203 }
2204
2205 skb_queue_head_init(&data->pending);
2206
2207 SET_IEEE80211_DEV(hw, data->dev);
2208 addr[3] = i >> 8;
2209 addr[4] = i;
2210 memcpy(data->addresses[0].addr, addr, ETH_ALEN);
2211 memcpy(data->addresses[1].addr, addr, ETH_ALEN);
2212 data->addresses[1].addr[0] |= 0x40;
2213 hw->wiphy->n_addresses = 2;
2214 hw->wiphy->addresses = data->addresses;
2215
2216 data->channels = channels;
2217
2218 if (data->channels > 1) {
2219 hw->wiphy->max_scan_ssids = 255;
2220 hw->wiphy->max_scan_ie_len = IEEE80211_MAX_DATA_LEN;
2221 hw->wiphy->max_remain_on_channel_duration = 1000;
2222 /* For channels > 1 DFS is not allowed */
2223 hw->wiphy->n_iface_combinations = 1;
2224 hw->wiphy->iface_combinations = &data->if_combination;
2225 data->if_combination = hwsim_if_comb[0];
2226 data->if_combination.num_different_channels =
2227 data->channels;
2228 } else {
2229 hw->wiphy->iface_combinations = hwsim_if_comb;
2230 hw->wiphy->n_iface_combinations =
2231 ARRAY_SIZE(hwsim_if_comb);
2232 }
2233
2234 INIT_DELAYED_WORK(&data->roc_done, hw_roc_done);
2235 INIT_DELAYED_WORK(&data->hw_scan, hw_scan_work);
2236
2237 hw->queues = 5;
2238 hw->offchannel_tx_hw_queue = 4;
2239 hw->wiphy->interface_modes =
2240 BIT(NL80211_IFTYPE_STATION) |
2241 BIT(NL80211_IFTYPE_AP) |
2242 BIT(NL80211_IFTYPE_P2P_CLIENT) |
2243 BIT(NL80211_IFTYPE_P2P_GO) |
2244 BIT(NL80211_IFTYPE_ADHOC) |
2245 BIT(NL80211_IFTYPE_MESH_POINT) |
2246 BIT(NL80211_IFTYPE_P2P_DEVICE);
2247
2248 hw->flags = IEEE80211_HW_MFP_CAPABLE |
2249 IEEE80211_HW_SIGNAL_DBM |
2250 IEEE80211_HW_SUPPORTS_STATIC_SMPS |
2251 IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS |
2252 IEEE80211_HW_AMPDU_AGGREGATION |
2253 IEEE80211_HW_WANT_MONITOR_VIF |
2254 IEEE80211_HW_QUEUE_CONTROL |
2255 IEEE80211_HW_SUPPORTS_HT_CCK_RATES;
2256 if (rctbl)
2257 hw->flags |= IEEE80211_HW_SUPPORTS_RC_TABLE;
2258
2259 hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS |
2260 WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL |
2261 WIPHY_FLAG_AP_UAPSD;
2262 hw->wiphy->features |= NL80211_FEATURE_ACTIVE_MONITOR;
2263
2264 /* ask mac80211 to reserve space for magic */
2265 hw->vif_data_size = sizeof(struct hwsim_vif_priv);
2266 hw->sta_data_size = sizeof(struct hwsim_sta_priv);
2267 hw->chanctx_data_size = sizeof(struct hwsim_chanctx_priv);
2268
2269 memcpy(data->channels_2ghz, hwsim_channels_2ghz,
2270 sizeof(hwsim_channels_2ghz));
2271 memcpy(data->channels_5ghz, hwsim_channels_5ghz,
2272 sizeof(hwsim_channels_5ghz));
2273 memcpy(data->rates, hwsim_rates, sizeof(hwsim_rates));
2274
2275 for (band = IEEE80211_BAND_2GHZ; band < IEEE80211_NUM_BANDS; band++) {
2276 struct ieee80211_supported_band *sband = &data->bands[band];
2277 switch (band) {
2278 case IEEE80211_BAND_2GHZ:
2279 sband->channels = data->channels_2ghz;
2280 sband->n_channels =
2281 ARRAY_SIZE(hwsim_channels_2ghz);
2282 sband->bitrates = data->rates;
2283 sband->n_bitrates = ARRAY_SIZE(hwsim_rates);
2284 break;
2285 case IEEE80211_BAND_5GHZ:
2286 sband->channels = data->channels_5ghz;
2287 sband->n_channels =
2288 ARRAY_SIZE(hwsim_channels_5ghz);
2289 sband->bitrates = data->rates + 4;
2290 sband->n_bitrates = ARRAY_SIZE(hwsim_rates) - 4;
2291 break;
2292 default:
2293 continue;
2294 }
2295
2296 sband->ht_cap.ht_supported = true;
2297 sband->ht_cap.cap = IEEE80211_HT_CAP_SUP_WIDTH_20_40 |
2298 IEEE80211_HT_CAP_GRN_FLD |
2299 IEEE80211_HT_CAP_SGI_40 |
2300 IEEE80211_HT_CAP_DSSSCCK40;
2301 sband->ht_cap.ampdu_factor = 0x3;
2302 sband->ht_cap.ampdu_density = 0x6;
2303 memset(&sband->ht_cap.mcs, 0,
2304 sizeof(sband->ht_cap.mcs));
2305 sband->ht_cap.mcs.rx_mask[0] = 0xff;
2306 sband->ht_cap.mcs.rx_mask[1] = 0xff;
2307 sband->ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED;
2308
2309 hw->wiphy->bands[band] = sband;
2310
2311 sband->vht_cap.vht_supported = true;
2312 sband->vht_cap.cap =
2313 IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454 |
2314 IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ |
2315 IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ |
2316 IEEE80211_VHT_CAP_RXLDPC |
2317 IEEE80211_VHT_CAP_SHORT_GI_80 |
2318 IEEE80211_VHT_CAP_SHORT_GI_160 |
2319 IEEE80211_VHT_CAP_TXSTBC |
2320 IEEE80211_VHT_CAP_RXSTBC_1 |
2321 IEEE80211_VHT_CAP_RXSTBC_2 |
2322 IEEE80211_VHT_CAP_RXSTBC_3 |
2323 IEEE80211_VHT_CAP_RXSTBC_4 |
2324 IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK;
2325 sband->vht_cap.vht_mcs.rx_mcs_map =
2326 cpu_to_le16(IEEE80211_VHT_MCS_SUPPORT_0_8 << 0 |
2327 IEEE80211_VHT_MCS_SUPPORT_0_8 << 2 |
2328 IEEE80211_VHT_MCS_SUPPORT_0_9 << 4 |
2329 IEEE80211_VHT_MCS_SUPPORT_0_8 << 6 |
2330 IEEE80211_VHT_MCS_SUPPORT_0_8 << 8 |
2331 IEEE80211_VHT_MCS_SUPPORT_0_9 << 10 |
2332 IEEE80211_VHT_MCS_SUPPORT_0_9 << 12 |
2333 IEEE80211_VHT_MCS_SUPPORT_0_8 << 14);
2334 sband->vht_cap.vht_mcs.tx_mcs_map =
2335 sband->vht_cap.vht_mcs.rx_mcs_map;
2336 }
2337 /* By default all radios are belonging to the first group */
2338 data->group = 1;
2339 mutex_init(&data->mutex);
2340
2341 /* Enable frame retransmissions for lossy channels */
2342 hw->max_rates = 4;
2343 hw->max_rate_tries = 11;
2344
2345 err = ieee80211_register_hw(hw);
2346 if (err < 0) {
2347 printk(KERN_DEBUG "mac80211_hwsim: "
2348 "ieee80211_register_hw failed (%d)\n", err);
2349 goto failed_hw;
2350 }
2351
2352 wiphy_debug(hw->wiphy, "hwaddr %pm registered\n",
2353 hw->wiphy->perm_addr);
2354
2355 data->debugfs = debugfs_create_dir("hwsim",
2356 hw->wiphy->debugfsdir);
2357 debugfs_create_file("ps", 0666, data->debugfs, data,
2358 &hwsim_fops_ps);
2359 debugfs_create_file("group", 0666, data->debugfs, data,
2360 &hwsim_fops_group);
2361 if (channels == 1)
2362 debugfs_create_file("dfs_simulate_radar", 0222,
2363 data->debugfs,
2364 data, &hwsim_simulate_radar);
2365
2366 tasklet_hrtimer_init(&data->beacon_timer,
2367 mac80211_hwsim_beacon,
2368 CLOCK_MONOTONIC_RAW, HRTIMER_MODE_ABS);
2369
2370 list_add_tail(&data->list, &hwsim_radios);
2371 } 2377 }
2372 2378
2373 hwsim_mon = alloc_netdev(0, "hwsim%d", hwsim_mon_setup); 2379 hwsim_mon = alloc_netdev(0, "hwsim%d", hwsim_mon_setup);
2374 if (hwsim_mon == NULL) { 2380 if (hwsim_mon == NULL) {
2375 err = -ENOMEM; 2381 err = -ENOMEM;
2376 goto failed; 2382 goto out_free_radios;
2377 } 2383 }
2378 2384
2379 rtnl_lock(); 2385 rtnl_lock();
2380
2381 err = dev_alloc_name(hwsim_mon, hwsim_mon->name); 2386 err = dev_alloc_name(hwsim_mon, hwsim_mon->name);
2382 if (err < 0) 2387 if (err < 0) {
2383 goto failed_mon; 2388 rtnl_unlock();
2384 2389 goto out_free_radios;
2390 }
2385 2391
2386 err = register_netdevice(hwsim_mon); 2392 err = register_netdevice(hwsim_mon);
2387 if (err < 0) 2393 if (err < 0) {
2388 goto failed_mon; 2394 rtnl_unlock();
2389 2395 goto out_free_mon;
2396 }
2390 rtnl_unlock(); 2397 rtnl_unlock();
2391 2398
2392 err = hwsim_init_netlink(); 2399 err = hwsim_init_netlink();
2393 if (err < 0) 2400 if (err < 0)
2394 goto failed_nl; 2401 goto out_free_mon;
2395 2402
2396 return 0; 2403 return 0;
2397 2404
2398failed_nl: 2405out_free_mon:
2399 printk(KERN_DEBUG "mac80211_hwsim: failed initializing netlink\n");
2400 return err;
2401
2402failed_mon:
2403 rtnl_unlock();
2404 free_netdev(hwsim_mon); 2406 free_netdev(hwsim_mon);
2407out_free_radios:
2405 mac80211_hwsim_free(); 2408 mac80211_hwsim_free();
2406 return err; 2409out_unregister_driver:
2407
2408failed_hw:
2409 device_unregister(data->dev);
2410failed_drvdata:
2411 ieee80211_free_hw(hw);
2412failed:
2413 mac80211_hwsim_free();
2414failed_unregister_driver:
2415 platform_driver_unregister(&mac80211_hwsim_driver); 2410 platform_driver_unregister(&mac80211_hwsim_driver);
2416 return err; 2411 return err;
2417} 2412}