aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/libertas/main.c
diff options
context:
space:
mode:
authorDavid Woodhouse <dwmw2@infradead.org>2007-12-10 16:38:18 -0500
committerDavid S. Miller <davem@davemloft.net>2008-01-28 18:06:38 -0500
commit8552855f9860b222673e86a88de2543f53f83dc2 (patch)
tree8f3880dac86342343c5070f80149c90490fe63dd /drivers/net/wireless/libertas/main.c
parent852e1f2a2627274102a3c2dc70a6547aeab99cb6 (diff)
libertas: make rtap and normal modes mutually exclusive, clean up open/stop
Signed-off-by: David Woodhouse <dwmw2@infradead.org> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/libertas/main.c')
-rw-r--r--drivers/net/wireless/libertas/main.c133
1 files changed, 50 insertions, 83 deletions
diff --git a/drivers/net/wireless/libertas/main.c b/drivers/net/wireless/libertas/main.c
index 3d9de7a1bfc6..88664024bf80 100644
--- a/drivers/net/wireless/libertas/main.c
+++ b/drivers/net/wireless/libertas/main.c
@@ -274,6 +274,8 @@ static ssize_t lbs_rtap_set(struct device *dev,
274 if(priv->monitormode == monitor_mode) 274 if(priv->monitormode == monitor_mode)
275 return strlen(buf); 275 return strlen(buf);
276 if (priv->monitormode == LBS_MONITOR_OFF) { 276 if (priv->monitormode == LBS_MONITOR_OFF) {
277 if (priv->infra_open || priv->mesh_open)
278 return -EBUSY;
277 if (priv->mode == IW_MODE_INFRA) 279 if (priv->mode == IW_MODE_INFRA)
278 lbs_send_deauthentication(priv); 280 lbs_send_deauthentication(priv);
279 else if (priv->mode == IW_MODE_ADHOC) 281 else if (priv->mode == IW_MODE_ADHOC)
@@ -367,84 +369,42 @@ static struct attribute_group lbs_mesh_attr_group = {
367}; 369};
368 370
369/** 371/**
370 * @brief This function opens the device 372 * @brief This function opens the ethX or mshX interface
371 * 373 *
372 * @param dev A pointer to net_device structure 374 * @param dev A pointer to net_device structure
373 * @return 0 375 * @return 0 or -EBUSY if monitor mode active
374 */ 376 */
375static int lbs_dev_open(struct net_device *dev) 377static int lbs_dev_open(struct net_device *dev)
376{ 378{
377 struct lbs_private *priv = (struct lbs_private *) dev->priv; 379 struct lbs_private *priv = (struct lbs_private *) dev->priv ;
378 380 int ret = 0;
379 lbs_deb_enter(LBS_DEB_NET);
380 381
381 priv->open = 1; 382 spin_lock_irq(&priv->driver_lock);
382 383
383 if (priv->connect_status == LBS_CONNECTED) 384 if (priv->monitormode != LBS_MONITOR_OFF) {
384 netif_carrier_on(priv->dev); 385 ret = -EBUSY;
385 else 386 goto out;
386 netif_carrier_off(priv->dev); 387 }
387 388
388 if (priv->mesh_dev) { 389 if (dev == priv->mesh_dev) {
389 if (priv->mesh_connect_status == LBS_CONNECTED) 390 priv->mesh_open = 1;
390 netif_carrier_on(priv->mesh_dev); 391 priv->mesh_connect_status = LBS_CONNECTED;
392 netif_carrier_on(dev);
393 } else {
394 priv->infra_open = 1;
395
396 if (priv->connect_status == LBS_CONNECTED)
397 netif_carrier_on(dev);
391 else 398 else
392 netif_carrier_off(priv->mesh_dev); 399 netif_carrier_off(dev);
393 } 400 }
394 401
395 lbs_deb_leave(LBS_DEB_NET); 402 if (!priv->tx_pending_len)
396 return 0; 403 netif_wake_queue(dev);
397} 404 out:
398/**
399 * @brief This function opens the mshX interface
400 *
401 * @param dev A pointer to net_device structure
402 * @return 0
403 */
404static int lbs_mesh_open(struct net_device *dev)
405{
406 struct lbs_private *priv = (struct lbs_private *) dev->priv ;
407
408 priv->mesh_open = 1 ;
409 netif_wake_queue(priv->mesh_dev);
410
411 priv->mesh_connect_status = LBS_CONNECTED;
412
413 netif_carrier_on(priv->mesh_dev);
414 netif_wake_queue(priv->mesh_dev);
415 if (priv->infra_open == 0)
416 return lbs_dev_open(priv->dev) ;
417 return 0;
418}
419
420/**
421 * @brief This function opens the ethX interface
422 *
423 * @param dev A pointer to net_device structure
424 * @return 0
425 */
426static int lbs_open(struct net_device *dev)
427{
428 struct lbs_private *priv = (struct lbs_private *) dev->priv ;
429
430 priv->infra_open = 1 ;
431 netif_wake_queue(priv->dev);
432 if (priv->open == 0)
433 return lbs_dev_open(priv->dev) ;
434 return 0;
435}
436 405
437static int lbs_dev_close(struct net_device *dev) 406 spin_unlock_irq(&priv->driver_lock);
438{ 407 return ret;
439 struct lbs_private *priv = dev->priv;
440
441 lbs_deb_enter(LBS_DEB_NET);
442
443 netif_carrier_off(priv->dev);
444 priv->open = 0;
445
446 lbs_deb_leave(LBS_DEB_NET);
447 return 0;
448} 408}
449 409
450/** 410/**
@@ -453,16 +413,20 @@ static int lbs_dev_close(struct net_device *dev)
453 * @param dev A pointer to net_device structure 413 * @param dev A pointer to net_device structure
454 * @return 0 414 * @return 0
455 */ 415 */
456static int lbs_mesh_close(struct net_device *dev) 416static int lbs_mesh_stop(struct net_device *dev)
457{ 417{
458 struct lbs_private *priv = (struct lbs_private *) (dev->priv); 418 struct lbs_private *priv = (struct lbs_private *) (dev->priv);
459 419
420 spin_lock_irq(&priv->driver_lock);
421
460 priv->mesh_open = 0; 422 priv->mesh_open = 0;
461 netif_stop_queue(priv->mesh_dev); 423 priv->mesh_connect_status = LBS_DISCONNECTED;
462 if (priv->infra_open == 0) 424
463 return lbs_dev_close(dev); 425 netif_stop_queue(dev);
464 else 426 netif_carrier_off(dev);
465 return 0; 427
428 spin_unlock_irq(&priv->driver_lock);
429 return 0;
466} 430}
467 431
468/** 432/**
@@ -471,16 +435,18 @@ static int lbs_mesh_close(struct net_device *dev)
471 * @param dev A pointer to net_device structure 435 * @param dev A pointer to net_device structure
472 * @return 0 436 * @return 0
473 */ 437 */
474static int lbs_close(struct net_device *dev) 438static int lbs_eth_stop(struct net_device *dev)
475{ 439{
476 struct lbs_private *priv = (struct lbs_private *) dev->priv; 440 struct lbs_private *priv = (struct lbs_private *) dev->priv;
477 441
478 netif_stop_queue(dev); 442 spin_lock_irq(&priv->driver_lock);
443
479 priv->infra_open = 0; 444 priv->infra_open = 0;
480 if (priv->mesh_open == 0) 445
481 return lbs_dev_close(dev); 446 netif_stop_queue(dev);
482 else 447
483 return 0; 448 spin_unlock_irq(&priv->driver_lock);
449 return 0;
484} 450}
485 451
486static void lbs_tx_timeout(struct net_device *dev) 452static void lbs_tx_timeout(struct net_device *dev)
@@ -1065,9 +1031,9 @@ struct lbs_private *lbs_add_card(void *card, struct device *dmdev)
1065 priv->infra_open = 0; 1031 priv->infra_open = 0;
1066 1032
1067 /* Setup the OS Interface to our functions */ 1033 /* Setup the OS Interface to our functions */
1068 dev->open = lbs_open; 1034 dev->open = lbs_dev_open;
1069 dev->hard_start_xmit = lbs_hard_start_xmit; 1035 dev->hard_start_xmit = lbs_hard_start_xmit;
1070 dev->stop = lbs_close; 1036 dev->stop = lbs_eth_stop;
1071 dev->set_mac_address = lbs_set_mac_address; 1037 dev->set_mac_address = lbs_set_mac_address;
1072 dev->tx_timeout = lbs_tx_timeout; 1038 dev->tx_timeout = lbs_tx_timeout;
1073 dev->get_stats = lbs_get_stats; 1039 dev->get_stats = lbs_get_stats;
@@ -1237,9 +1203,9 @@ int lbs_add_mesh(struct lbs_private *priv, struct device *dev)
1237 mesh_dev->priv = priv; 1203 mesh_dev->priv = priv;
1238 priv->mesh_dev = mesh_dev; 1204 priv->mesh_dev = mesh_dev;
1239 1205
1240 mesh_dev->open = lbs_mesh_open; 1206 mesh_dev->open = lbs_dev_open;
1241 mesh_dev->hard_start_xmit = lbs_hard_start_xmit; 1207 mesh_dev->hard_start_xmit = lbs_hard_start_xmit;
1242 mesh_dev->stop = lbs_mesh_close; 1208 mesh_dev->stop = lbs_mesh_stop;
1243 mesh_dev->get_stats = lbs_get_stats; 1209 mesh_dev->get_stats = lbs_get_stats;
1244 mesh_dev->set_mac_address = lbs_set_mac_address; 1210 mesh_dev->set_mac_address = lbs_set_mac_address;
1245 mesh_dev->ethtool_ops = &lbs_ethtool_ops; 1211 mesh_dev->ethtool_ops = &lbs_ethtool_ops;
@@ -1436,6 +1402,7 @@ static void __exit lbs_exit_module(void)
1436 1402
1437static int lbs_rtap_open(struct net_device *dev) 1403static int lbs_rtap_open(struct net_device *dev)
1438{ 1404{
1405 /* Yes, _stop_ the queue. Because we don't support injection */
1439 netif_carrier_off(dev); 1406 netif_carrier_off(dev);
1440 netif_stop_queue(dev); 1407 netif_stop_queue(dev);
1441 return 0; 1408 return 0;
@@ -1449,7 +1416,7 @@ static int lbs_rtap_stop(struct net_device *dev)
1449static int lbs_rtap_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) 1416static int lbs_rtap_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
1450{ 1417{
1451 netif_stop_queue(dev); 1418 netif_stop_queue(dev);
1452 return -EOPNOTSUPP; 1419 return NETDEV_TX_BUSY;
1453} 1420}
1454 1421
1455static struct net_device_stats *lbs_rtap_get_stats(struct net_device *dev) 1422static struct net_device_stats *lbs_rtap_get_stats(struct net_device *dev)