aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/mwifiex/cfg80211.c
diff options
context:
space:
mode:
authorAvinash Patil <patila@marvell.com>2012-05-08 21:30:15 -0400
committerJohn W. Linville <linville@tuxdriver.com>2012-05-16 12:46:34 -0400
commitd6bffe8bb520bc1ce3333d05ce67f36dab9a61aa (patch)
treece098372b8453a433ac5b27aa7136f16d12d6915 /drivers/net/wireless/mwifiex/cfg80211.c
parent03785387e1c6b236a04d595f98b014b78e585202 (diff)
mwifiex: support for creation of AP interface
1. wiphy structure is per device; hence moved it to mwifiex_adapter mwifiex_register_cfg80211 takes mwifiex_adapter as parameter. This function only registers wiphy with cfg80211. 2. Creation of interfaces is moved to cfg80211 add_virtual_interface handler. 3. Create 2 interfaces by default: station and AP Signed-off-by: Avinash Patil <patila@marvell.com> Signed-off-by: Yogesh Ashok Powar <yogeshp@marvell.com> Signed-off-by: Amitkumar Karwar <akarwar@marvell.com> Signed-off-by: Kiran Divekar <dkiran@marvell.com> Signed-off-by: Bing Zhao <bzhao@marvell.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/mwifiex/cfg80211.c')
-rw-r--r--drivers/net/wireless/mwifiex/cfg80211.c142
1 files changed, 83 insertions, 59 deletions
diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c
index c78ea873a63a..38d51910d13c 100644
--- a/drivers/net/wireless/mwifiex/cfg80211.c
+++ b/drivers/net/wireless/mwifiex/cfg80211.c
@@ -1287,6 +1287,7 @@ struct net_device *mwifiex_add_virtual_intf(struct wiphy *wiphy,
1287 struct mwifiex_adapter *adapter; 1287 struct mwifiex_adapter *adapter;
1288 struct net_device *dev; 1288 struct net_device *dev;
1289 void *mdev_priv; 1289 void *mdev_priv;
1290 struct wireless_dev *wdev;
1290 1291
1291 if (!priv) 1292 if (!priv)
1292 return NULL; 1293 return NULL;
@@ -1299,12 +1300,21 @@ struct net_device *mwifiex_add_virtual_intf(struct wiphy *wiphy,
1299 case NL80211_IFTYPE_UNSPECIFIED: 1300 case NL80211_IFTYPE_UNSPECIFIED:
1300 case NL80211_IFTYPE_STATION: 1301 case NL80211_IFTYPE_STATION:
1301 case NL80211_IFTYPE_ADHOC: 1302 case NL80211_IFTYPE_ADHOC:
1303 priv = adapter->priv[MWIFIEX_BSS_TYPE_STA];
1302 if (priv->bss_mode) { 1304 if (priv->bss_mode) {
1303 wiphy_err(wiphy, "cannot create multiple" 1305 wiphy_err(wiphy,
1304 " station/adhoc interfaces\n"); 1306 "cannot create multiple sta/adhoc ifaces\n");
1305 return NULL; 1307 return NULL;
1306 } 1308 }
1307 1309
1310 wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL);
1311 if (!wdev)
1312 return NULL;
1313
1314 wdev->wiphy = wiphy;
1315 priv->wdev = wdev;
1316 wdev->iftype = NL80211_IFTYPE_STATION;
1317
1308 if (type == NL80211_IFTYPE_UNSPECIFIED) 1318 if (type == NL80211_IFTYPE_UNSPECIFIED)
1309 priv->bss_mode = NL80211_IFTYPE_STATION; 1319 priv->bss_mode = NL80211_IFTYPE_STATION;
1310 else 1320 else
@@ -1312,11 +1322,36 @@ struct net_device *mwifiex_add_virtual_intf(struct wiphy *wiphy,
1312 1322
1313 priv->bss_type = MWIFIEX_BSS_TYPE_STA; 1323 priv->bss_type = MWIFIEX_BSS_TYPE_STA;
1314 priv->frame_type = MWIFIEX_DATA_FRAME_TYPE_ETH_II; 1324 priv->frame_type = MWIFIEX_DATA_FRAME_TYPE_ETH_II;
1315 priv->bss_priority = 0; 1325 priv->bss_priority = MWIFIEX_BSS_ROLE_STA;
1316 priv->bss_role = MWIFIEX_BSS_ROLE_STA; 1326 priv->bss_role = MWIFIEX_BSS_ROLE_STA;
1317 priv->bss_num = 0; 1327 priv->bss_num = 0;
1318 1328
1319 break; 1329 break;
1330 case NL80211_IFTYPE_AP:
1331 priv = adapter->priv[MWIFIEX_BSS_TYPE_UAP];
1332
1333 if (priv->bss_mode) {
1334 wiphy_err(wiphy, "Can't create multiple AP interfaces");
1335 return NULL;
1336 }
1337
1338 wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL);
1339 if (!wdev)
1340 return NULL;
1341
1342 priv->wdev = wdev;
1343 wdev->wiphy = wiphy;
1344 wdev->iftype = NL80211_IFTYPE_AP;
1345
1346 priv->bss_type = MWIFIEX_BSS_TYPE_UAP;
1347 priv->frame_type = MWIFIEX_DATA_FRAME_TYPE_ETH_II;
1348 priv->bss_priority = MWIFIEX_BSS_ROLE_UAP;
1349 priv->bss_role = MWIFIEX_BSS_ROLE_UAP;
1350 priv->bss_started = 0;
1351 priv->bss_num = 0;
1352 priv->bss_mode = type;
1353
1354 break;
1320 default: 1355 default:
1321 wiphy_err(wiphy, "type not supported\n"); 1356 wiphy_err(wiphy, "type not supported\n");
1322 return NULL; 1357 return NULL;
@@ -1329,6 +1364,15 @@ struct net_device *mwifiex_add_virtual_intf(struct wiphy *wiphy,
1329 goto error; 1364 goto error;
1330 } 1365 }
1331 1366
1367 mwifiex_init_priv_params(priv, dev);
1368 priv->netdev = dev;
1369
1370 mwifiex_setup_ht_caps(&wiphy->bands[IEEE80211_BAND_2GHZ]->ht_cap, priv);
1371
1372 if (adapter->config_bands & BAND_A)
1373 mwifiex_setup_ht_caps(
1374 &wiphy->bands[IEEE80211_BAND_5GHZ]->ht_cap, priv);
1375
1332 dev_net_set(dev, wiphy_net(wiphy)); 1376 dev_net_set(dev, wiphy_net(wiphy));
1333 dev->ieee80211_ptr = priv->wdev; 1377 dev->ieee80211_ptr = priv->wdev;
1334 dev->ieee80211_ptr->iftype = priv->bss_mode; 1378 dev->ieee80211_ptr->iftype = priv->bss_mode;
@@ -1343,9 +1387,6 @@ struct net_device *mwifiex_add_virtual_intf(struct wiphy *wiphy,
1343 mdev_priv = netdev_priv(dev); 1387 mdev_priv = netdev_priv(dev);
1344 *((unsigned long *) mdev_priv) = (unsigned long) priv; 1388 *((unsigned long *) mdev_priv) = (unsigned long) priv;
1345 1389
1346 priv->netdev = dev;
1347 mwifiex_init_priv_params(priv, dev);
1348
1349 SET_NETDEV_DEV(dev, adapter->dev); 1390 SET_NETDEV_DEV(dev, adapter->dev);
1350 1391
1351 /* Register network device */ 1392 /* Register network device */
@@ -1436,82 +1477,65 @@ static struct cfg80211_ops mwifiex_cfg80211_ops = {
1436 * default parameters and handler function pointers, and finally 1477 * default parameters and handler function pointers, and finally
1437 * registers the device. 1478 * registers the device.
1438 */ 1479 */
1439int mwifiex_register_cfg80211(struct mwifiex_private *priv) 1480
1481int mwifiex_register_cfg80211(struct mwifiex_adapter *adapter)
1440{ 1482{
1441 int ret; 1483 int ret;
1442 void *wdev_priv; 1484 void *wdev_priv;
1443 struct wireless_dev *wdev; 1485 struct wiphy *wiphy;
1444 struct ieee80211_sta_ht_cap *ht_info; 1486 struct mwifiex_private *priv = adapter->priv[MWIFIEX_BSS_TYPE_STA];
1445 u8 *country_code; 1487 u8 *country_code;
1446 1488
1447 wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL); 1489 /* create a new wiphy for use with cfg80211 */
1448 if (!wdev) { 1490 wiphy = wiphy_new(&mwifiex_cfg80211_ops,
1449 dev_err(priv->adapter->dev, "%s: allocating wireless device\n", 1491 sizeof(struct mwifiex_adapter *));
1450 __func__); 1492 if (!wiphy) {
1493 dev_err(adapter->dev, "%s: creating new wiphy\n", __func__);
1451 return -ENOMEM; 1494 return -ENOMEM;
1452 } 1495 }
1453 wdev->wiphy = 1496 wiphy->max_scan_ssids = MWIFIEX_MAX_SSID_LIST_LENGTH;
1454 wiphy_new(&mwifiex_cfg80211_ops, 1497 wiphy->max_scan_ie_len = MWIFIEX_MAX_VSIE_LEN;
1455 sizeof(struct mwifiex_private *)); 1498 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
1456 if (!wdev->wiphy) { 1499 BIT(NL80211_IFTYPE_ADHOC) |
1457 kfree(wdev); 1500 BIT(NL80211_IFTYPE_AP);
1458 return -ENOMEM; 1501
1459 } 1502 wiphy->bands[IEEE80211_BAND_2GHZ] = &mwifiex_band_2ghz;
1460 wdev->iftype = NL80211_IFTYPE_STATION; 1503 if (adapter->config_bands & BAND_A)
1461 wdev->wiphy->max_scan_ssids = 10; 1504 wiphy->bands[IEEE80211_BAND_5GHZ] = &mwifiex_band_5ghz;
1462 wdev->wiphy->max_scan_ie_len = MWIFIEX_MAX_VSIE_LEN; 1505 else
1463 wdev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | 1506 wiphy->bands[IEEE80211_BAND_5GHZ] = NULL;
1464 BIT(NL80211_IFTYPE_ADHOC);
1465
1466 wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &mwifiex_band_2ghz;
1467 ht_info = &wdev->wiphy->bands[IEEE80211_BAND_2GHZ]->ht_cap;
1468 mwifiex_setup_ht_caps(ht_info, priv);
1469
1470 if (priv->adapter->config_bands & BAND_A) {
1471 wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = &mwifiex_band_5ghz;
1472 ht_info = &wdev->wiphy->bands[IEEE80211_BAND_5GHZ]->ht_cap;
1473 mwifiex_setup_ht_caps(ht_info, priv);
1474 } else {
1475 wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = NULL;
1476 }
1477 1507
1478 /* Initialize cipher suits */ 1508 /* Initialize cipher suits */
1479 wdev->wiphy->cipher_suites = mwifiex_cipher_suites; 1509 wiphy->cipher_suites = mwifiex_cipher_suites;
1480 wdev->wiphy->n_cipher_suites = ARRAY_SIZE(mwifiex_cipher_suites); 1510 wiphy->n_cipher_suites = ARRAY_SIZE(mwifiex_cipher_suites);
1481 1511
1482 memcpy(wdev->wiphy->perm_addr, priv->curr_addr, ETH_ALEN); 1512 memcpy(wiphy->perm_addr, priv->curr_addr, ETH_ALEN);
1483 wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM; 1513 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
1514 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME | WIPHY_FLAG_CUSTOM_REGULATORY;
1484 1515
1485 /* Reserve space for mwifiex specific private data for BSS */ 1516 /* Reserve space for mwifiex specific private data for BSS */
1486 wdev->wiphy->bss_priv_size = sizeof(struct mwifiex_bss_priv); 1517 wiphy->bss_priv_size = sizeof(struct mwifiex_bss_priv);
1487 1518
1488 wdev->wiphy->reg_notifier = mwifiex_reg_notifier; 1519 wiphy->reg_notifier = mwifiex_reg_notifier;
1489 1520
1490 /* Set struct mwifiex_private pointer in wiphy_priv */ 1521 /* Set struct mwifiex_private pointer in wiphy_priv */
1491 wdev_priv = wiphy_priv(wdev->wiphy); 1522 wdev_priv = wiphy_priv(wiphy);
1492 1523
1493 *(unsigned long *) wdev_priv = (unsigned long) priv; 1524 *(unsigned long *) wdev_priv = (unsigned long) priv;
1494 1525
1495 set_wiphy_dev(wdev->wiphy, (struct device *) priv->adapter->dev); 1526 set_wiphy_dev(wiphy, (struct device *)priv->adapter->dev);
1496 1527
1497 ret = wiphy_register(wdev->wiphy); 1528 ret = wiphy_register(wiphy);
1498 if (ret < 0) { 1529 if (ret < 0) {
1499 dev_err(priv->adapter->dev, "%s: registering cfg80211 device\n", 1530 dev_err(adapter->dev,
1500 __func__); 1531 "%s: wiphy_register failed: %d\n", __func__, ret);
1501 wiphy_free(wdev->wiphy); 1532 wiphy_free(wiphy);
1502 kfree(wdev);
1503 return ret; 1533 return ret;
1504 } else {
1505 dev_dbg(priv->adapter->dev,
1506 "info: successfully registered wiphy device\n");
1507 } 1534 }
1508
1509 country_code = mwifiex_11d_code_2_region(priv->adapter->region_code); 1535 country_code = mwifiex_11d_code_2_region(priv->adapter->region_code);
1510 if (country_code && regulatory_hint(wdev->wiphy, country_code)) 1536 if (country_code && regulatory_hint(wiphy, country_code))
1511 dev_err(priv->adapter->dev, 1537 dev_err(adapter->dev, "regulatory_hint() failed\n");
1512 "%s: regulatory_hint failed\n", __func__);
1513
1514 priv->wdev = wdev;
1515 1538
1539 adapter->wiphy = wiphy;
1516 return ret; 1540 return ret;
1517} 1541}