Skip to content

Commit

Permalink
firewire: net: add carrier detection
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Maxim Levitsky authored and Stefan Richter committed Dec 19, 2010
1 parent c4d6fd4 commit 18bb36f
Showing 1 changed file with 17 additions and 0 deletions.
17 changes: 17 additions & 0 deletions drivers/firewire/net.c
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,7 @@ struct fwnet_device {

/* Number of tx datagrams that have been queued but not yet acked */
int queued_datagrams;
int peer_count;

struct list_head peer_list;
struct fw_card *card;
Expand Down Expand Up @@ -1405,6 +1406,10 @@ static int fwnet_change_mtu(struct net_device *net, int new_mtu)
return 0;
}

static const struct ethtool_ops fwnet_ethtool_ops = {
.get_link = ethtool_op_get_link,
};

static const struct net_device_ops fwnet_netdev_ops = {
.ndo_open = fwnet_open,
.ndo_stop = fwnet_stop,
Expand All @@ -1423,6 +1428,8 @@ static void fwnet_init_dev(struct net_device *net)
net->hard_header_len = FWNET_HLEN;
net->type = ARPHRD_IEEE1394;
net->tx_queue_len = FWNET_TX_QUEUE_LEN;
net->ethtool_ops = &fwnet_ethtool_ops;

}

/* caller must hold fwnet_device_mutex */
Expand Down Expand Up @@ -1463,6 +1470,7 @@ static int fwnet_add_peer(struct fwnet_device *dev,

spin_lock_irq(&dev->lock);
list_add_tail(&peer->peer_link, &dev->peer_list);
dev->peer_count++;
spin_unlock_irq(&dev->lock);

return 0;
Expand Down Expand Up @@ -1534,6 +1542,9 @@ static int fwnet_probe(struct device *_dev)
unregister_netdev(net);
list_del(&dev->dev_link);
}

if (dev->peer_count > 1)
netif_carrier_on(net);
out:
if (ret && allocated_netdev)
free_netdev(net);
Expand All @@ -1549,6 +1560,7 @@ static void fwnet_remove_peer(struct fwnet_peer *peer)

spin_lock_irq(&peer->dev->lock);
list_del(&peer->peer_link);
peer->dev->peer_count--;
spin_unlock_irq(&peer->dev->lock);

list_for_each_entry_safe(pd, pd_next, &peer->pd_list, pd_link)
Expand All @@ -1568,6 +1580,11 @@ static int fwnet_remove(struct device *_dev)

fwnet_remove_peer(peer);

/* If we serve just one node, that means we lost link
with outer world */
if (dev->peer_count == 1)
netif_carrier_off(dev->netdev);

if (list_empty(&dev->peer_list)) {
net = dev->netdev;
unregister_netdev(net);
Expand Down

0 comments on commit 18bb36f

Please sign in to comment.