diff options
author | David Woodhouse <dwmw2@infradead.org> | 2007-12-10 16:38:18 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-01-28 18:06:38 -0500 |
commit | 8552855f9860b222673e86a88de2543f53f83dc2 (patch) | |
tree | 8f3880dac86342343c5070f80149c90490fe63dd /drivers/net/wireless/libertas/main.c | |
parent | 852e1f2a2627274102a3c2dc70a6547aeab99cb6 (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.c | 133 |
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 | */ |
375 | static int lbs_dev_open(struct net_device *dev) | 377 | static 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 | */ | ||
404 | static 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 | */ | ||
426 | static 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 | ||
437 | static 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 | */ |
456 | static int lbs_mesh_close(struct net_device *dev) | 416 | static 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 | */ |
474 | static int lbs_close(struct net_device *dev) | 438 | static 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 | ||
486 | static void lbs_tx_timeout(struct net_device *dev) | 452 | static 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 | ||
1437 | static int lbs_rtap_open(struct net_device *dev) | 1403 | static 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) | |||
1449 | static int lbs_rtap_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) | 1416 | static 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 | ||
1455 | static struct net_device_stats *lbs_rtap_get_stats(struct net_device *dev) | 1422 | static struct net_device_stats *lbs_rtap_get_stats(struct net_device *dev) |