aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/firewire
diff options
context:
space:
mode:
authorMaxim Levitsky <maximlevitsky@gmail.com>2010-12-07 21:22:57 -0500
committerStefan Richter <stefanr@s5r6.in-berlin.de>2010-12-19 09:27:01 -0500
commit18bb36f9fab5980efeff063755c037a622f0231c (patch)
treef12d16c98aab9934306d29dc7584095479077813 /drivers/firewire
parentc4d6fd40df38eb4c187565d48807f5f902481ba8 (diff)
firewire: net: add carrier detection
To make userland, e.g. NetworkManager work with firewire, we need to detect whether cable is plugged or not. Simple and correct way of doing that is just counting number of peers. No peers - no link and vice versa. Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>
Diffstat (limited to 'drivers/firewire')
-rw-r--r--drivers/firewire/net.c17
1 files changed, 17 insertions, 0 deletions
diff --git a/drivers/firewire/net.c b/drivers/firewire/net.c
index ea31e3084d67..7fd51c9e243d 100644
--- a/drivers/firewire/net.c
+++ b/drivers/firewire/net.c
@@ -178,6 +178,7 @@ struct fwnet_device {
178 178
179 /* Number of tx datagrams that have been queued but not yet acked */ 179 /* Number of tx datagrams that have been queued but not yet acked */
180 int queued_datagrams; 180 int queued_datagrams;
181 int peer_count;
181 182
182 struct list_head peer_list; 183 struct list_head peer_list;
183 struct fw_card *card; 184 struct fw_card *card;
@@ -1405,6 +1406,10 @@ static int fwnet_change_mtu(struct net_device *net, int new_mtu)
1405 return 0; 1406 return 0;
1406} 1407}
1407 1408
1409static const struct ethtool_ops fwnet_ethtool_ops = {
1410 .get_link = ethtool_op_get_link,
1411};
1412
1408static const struct net_device_ops fwnet_netdev_ops = { 1413static const struct net_device_ops fwnet_netdev_ops = {
1409 .ndo_open = fwnet_open, 1414 .ndo_open = fwnet_open,
1410 .ndo_stop = fwnet_stop, 1415 .ndo_stop = fwnet_stop,
@@ -1423,6 +1428,8 @@ static void fwnet_init_dev(struct net_device *net)
1423 net->hard_header_len = FWNET_HLEN; 1428 net->hard_header_len = FWNET_HLEN;
1424 net->type = ARPHRD_IEEE1394; 1429 net->type = ARPHRD_IEEE1394;
1425 net->tx_queue_len = FWNET_TX_QUEUE_LEN; 1430 net->tx_queue_len = FWNET_TX_QUEUE_LEN;
1431 net->ethtool_ops = &fwnet_ethtool_ops;
1432
1426} 1433}
1427 1434
1428/* caller must hold fwnet_device_mutex */ 1435/* caller must hold fwnet_device_mutex */
@@ -1463,6 +1470,7 @@ static int fwnet_add_peer(struct fwnet_device *dev,
1463 1470
1464 spin_lock_irq(&dev->lock); 1471 spin_lock_irq(&dev->lock);
1465 list_add_tail(&peer->peer_link, &dev->peer_list); 1472 list_add_tail(&peer->peer_link, &dev->peer_list);
1473 dev->peer_count++;
1466 spin_unlock_irq(&dev->lock); 1474 spin_unlock_irq(&dev->lock);
1467 1475
1468 return 0; 1476 return 0;
@@ -1534,6 +1542,9 @@ static int fwnet_probe(struct device *_dev)
1534 unregister_netdev(net); 1542 unregister_netdev(net);
1535 list_del(&dev->dev_link); 1543 list_del(&dev->dev_link);
1536 } 1544 }
1545
1546 if (dev->peer_count > 1)
1547 netif_carrier_on(net);
1537 out: 1548 out:
1538 if (ret && allocated_netdev) 1549 if (ret && allocated_netdev)
1539 free_netdev(net); 1550 free_netdev(net);
@@ -1549,6 +1560,7 @@ static void fwnet_remove_peer(struct fwnet_peer *peer)
1549 1560
1550 spin_lock_irq(&peer->dev->lock); 1561 spin_lock_irq(&peer->dev->lock);
1551 list_del(&peer->peer_link); 1562 list_del(&peer->peer_link);
1563 peer->dev->peer_count--;
1552 spin_unlock_irq(&peer->dev->lock); 1564 spin_unlock_irq(&peer->dev->lock);
1553 1565
1554 list_for_each_entry_safe(pd, pd_next, &peer->pd_list, pd_link) 1566 list_for_each_entry_safe(pd, pd_next, &peer->pd_list, pd_link)
@@ -1568,6 +1580,11 @@ static int fwnet_remove(struct device *_dev)
1568 1580
1569 fwnet_remove_peer(peer); 1581 fwnet_remove_peer(peer);
1570 1582
1583 /* If we serve just one node, that means we lost link
1584 with outer world */
1585 if (dev->peer_count == 1)
1586 netif_carrier_off(dev->netdev);
1587
1571 if (list_empty(&dev->peer_list)) { 1588 if (list_empty(&dev->peer_list)) {
1572 net = dev->netdev; 1589 net = dev->netdev;
1573 unregister_netdev(net); 1590 unregister_netdev(net);