aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/ieee80211.c
diff options
context:
space:
mode:
authorJohannes Berg <johannes@sipsolutions.net>2008-02-08 03:48:13 -0500
committerJohn W. Linville <linville@tuxdriver.com>2008-02-29 15:37:06 -0500
commit96d510566e4908f77f03ff1436c78ae7162a17d0 (patch)
tree76b9abb66bcaf870a3ec4ee71e00f20d668e712b /net/mac80211/ieee80211.c
parent4688be308f35f1e0099140a179d95c5e63b2319d (diff)
mac80211: defer master netdev allocation to ieee80211_register_hw
When we want to go multiqueue, we will need to know the number of queues the hardware has for registering the master netdev. This number is only available in ieee80211_register_hw() rather than ieee80211_alloc_hw(), so defer allocation of the master device to ieee80211_register_hw(). Signed-off-by: Johannes Berg <johannes@sipsolutions.net> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211/ieee80211.c')
-rw-r--r--net/mac80211/ieee80211.c72
1 files changed, 38 insertions, 34 deletions
diff --git a/net/mac80211/ieee80211.c b/net/mac80211/ieee80211.c
index 91f06c3f4a7c..7df14799e38b 100644
--- a/net/mac80211/ieee80211.c
+++ b/net/mac80211/ieee80211.c
@@ -1375,9 +1375,7 @@ EXPORT_SYMBOL(ieee80211_tx_status);
1375struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len, 1375struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
1376 const struct ieee80211_ops *ops) 1376 const struct ieee80211_ops *ops)
1377{ 1377{
1378 struct net_device *mdev;
1379 struct ieee80211_local *local; 1378 struct ieee80211_local *local;
1380 struct ieee80211_sub_if_data *sdata;
1381 int priv_size; 1379 int priv_size;
1382 struct wiphy *wiphy; 1380 struct wiphy *wiphy;
1383 1381
@@ -1423,22 +1421,8 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
1423 BUG_ON(!ops->configure_filter); 1421 BUG_ON(!ops->configure_filter);
1424 local->ops = ops; 1422 local->ops = ops;
1425 1423
1426 /* for now, mdev needs sub_if_data :/ */
1427 mdev = alloc_netdev(sizeof(struct ieee80211_sub_if_data),
1428 "wmaster%d", ether_setup);
1429 if (!mdev) {
1430 wiphy_free(wiphy);
1431 return NULL;
1432 }
1433
1434 sdata = IEEE80211_DEV_TO_SUB_IF(mdev);
1435 mdev->ieee80211_ptr = &sdata->wdev;
1436 sdata->wdev.wiphy = wiphy;
1437
1438 local->hw.queues = 1; /* default */ 1424 local->hw.queues = 1; /* default */
1439 1425
1440 local->mdev = mdev;
1441
1442 local->bridge_packets = 1; 1426 local->bridge_packets = 1;
1443 1427
1444 local->rts_threshold = IEEE80211_MAX_RTS_THRESHOLD; 1428 local->rts_threshold = IEEE80211_MAX_RTS_THRESHOLD;
@@ -1450,26 +1434,9 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
1450 INIT_LIST_HEAD(&local->interfaces); 1434 INIT_LIST_HEAD(&local->interfaces);
1451 1435
1452 INIT_DELAYED_WORK(&local->scan_work, ieee80211_sta_scan_work); 1436 INIT_DELAYED_WORK(&local->scan_work, ieee80211_sta_scan_work);
1453 ieee80211_rx_bss_list_init(mdev);
1454 1437
1455 sta_info_init(local); 1438 sta_info_init(local);
1456 1439
1457 mdev->hard_start_xmit = ieee80211_master_start_xmit;
1458 mdev->open = ieee80211_master_open;
1459 mdev->stop = ieee80211_master_stop;
1460 mdev->type = ARPHRD_IEEE80211;
1461 mdev->header_ops = &ieee80211_header_ops;
1462 mdev->set_multicast_list = ieee80211_master_set_multicast_list;
1463
1464 sdata->vif.type = IEEE80211_IF_TYPE_AP;
1465 sdata->dev = mdev;
1466 sdata->local = local;
1467 sdata->u.ap.force_unicast_rateidx = -1;
1468 sdata->u.ap.max_ratectrl_rateidx = -1;
1469 ieee80211_if_sdata_init(sdata);
1470 /* no RCU needed since we're still during init phase */
1471 list_add_tail(&sdata->list, &local->interfaces);
1472
1473 tasklet_init(&local->tx_pending_tasklet, ieee80211_tx_pending, 1440 tasklet_init(&local->tx_pending_tasklet, ieee80211_tx_pending,
1474 (unsigned long)local); 1441 (unsigned long)local);
1475 tasklet_disable(&local->tx_pending_tasklet); 1442 tasklet_disable(&local->tx_pending_tasklet);
@@ -1492,6 +1459,8 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
1492 const char *name; 1459 const char *name;
1493 int result; 1460 int result;
1494 enum ieee80211_band band; 1461 enum ieee80211_band band;
1462 struct net_device *mdev;
1463 struct ieee80211_sub_if_data *sdata;
1495 1464
1496 /* 1465 /*
1497 * generic code guarantees at least one band, 1466 * generic code guarantees at least one band,
@@ -1515,6 +1484,37 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
1515 if (result < 0) 1484 if (result < 0)
1516 return result; 1485 return result;
1517 1486
1487 /* for now, mdev needs sub_if_data :/ */
1488 mdev = alloc_netdev(sizeof(struct ieee80211_sub_if_data),
1489 "wmaster%d", ether_setup);
1490 if (!mdev)
1491 goto fail_mdev_alloc;
1492
1493 sdata = IEEE80211_DEV_TO_SUB_IF(mdev);
1494 mdev->ieee80211_ptr = &sdata->wdev;
1495 sdata->wdev.wiphy = local->hw.wiphy;
1496
1497 local->mdev = mdev;
1498
1499 ieee80211_rx_bss_list_init(mdev);
1500
1501 mdev->hard_start_xmit = ieee80211_master_start_xmit;
1502 mdev->open = ieee80211_master_open;
1503 mdev->stop = ieee80211_master_stop;
1504 mdev->type = ARPHRD_IEEE80211;
1505 mdev->header_ops = &ieee80211_header_ops;
1506 mdev->set_multicast_list = ieee80211_master_set_multicast_list;
1507
1508 sdata->vif.type = IEEE80211_IF_TYPE_AP;
1509 sdata->dev = mdev;
1510 sdata->local = local;
1511 sdata->u.ap.force_unicast_rateidx = -1;
1512 sdata->u.ap.max_ratectrl_rateidx = -1;
1513 ieee80211_if_sdata_init(sdata);
1514
1515 /* no RCU needed since we're still during init phase */
1516 list_add_tail(&sdata->list, &local->interfaces);
1517
1518 name = wiphy_dev(local->hw.wiphy)->driver->name; 1518 name = wiphy_dev(local->hw.wiphy)->driver->name;
1519 local->hw.workqueue = create_singlethread_workqueue(name); 1519 local->hw.workqueue = create_singlethread_workqueue(name);
1520 if (!local->hw.workqueue) { 1520 if (!local->hw.workqueue) {
@@ -1606,6 +1606,9 @@ fail_sta_info:
1606 debugfs_hw_del(local); 1606 debugfs_hw_del(local);
1607 destroy_workqueue(local->hw.workqueue); 1607 destroy_workqueue(local->hw.workqueue);
1608fail_workqueue: 1608fail_workqueue:
1609 ieee80211_if_free(local->mdev);
1610 local->mdev = NULL;
1611fail_mdev_alloc:
1609 wiphy_unregister(local->hw.wiphy); 1612 wiphy_unregister(local->hw.wiphy);
1610 return result; 1613 return result;
1611} 1614}
@@ -1666,6 +1669,8 @@ void ieee80211_unregister_hw(struct ieee80211_hw *hw)
1666 wiphy_unregister(local->hw.wiphy); 1669 wiphy_unregister(local->hw.wiphy);
1667 ieee80211_wep_free(local); 1670 ieee80211_wep_free(local);
1668 ieee80211_led_exit(local); 1671 ieee80211_led_exit(local);
1672 ieee80211_if_free(local->mdev);
1673 local->mdev = NULL;
1669} 1674}
1670EXPORT_SYMBOL(ieee80211_unregister_hw); 1675EXPORT_SYMBOL(ieee80211_unregister_hw);
1671 1676
@@ -1673,7 +1678,6 @@ void ieee80211_free_hw(struct ieee80211_hw *hw)
1673{ 1678{
1674 struct ieee80211_local *local = hw_to_local(hw); 1679 struct ieee80211_local *local = hw_to_local(hw);
1675 1680
1676 ieee80211_if_free(local->mdev);
1677 wiphy_free(local->hw.wiphy); 1681 wiphy_free(local->hw.wiphy);
1678} 1682}
1679EXPORT_SYMBOL(ieee80211_free_hw); 1683EXPORT_SYMBOL(ieee80211_free_hw);