Commit 18bb36f9fab5980efeff063755c037a622f0231c
Committed by
Stefan Richter
1 parent
c4d6fd40df
Exists in
master
and in
4 other branches
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>
Showing 1 changed file with 17 additions and 0 deletions Side-by-side Diff
drivers/firewire/net.c
... | ... | @@ -178,6 +178,7 @@ |
178 | 178 | |
179 | 179 | /* Number of tx datagrams that have been queued but not yet acked */ |
180 | 180 | int queued_datagrams; |
181 | + int peer_count; | |
181 | 182 | |
182 | 183 | struct list_head peer_list; |
183 | 184 | struct fw_card *card; |
... | ... | @@ -1405,6 +1406,10 @@ |
1405 | 1406 | return 0; |
1406 | 1407 | } |
1407 | 1408 | |
1409 | +static const struct ethtool_ops fwnet_ethtool_ops = { | |
1410 | + .get_link = ethtool_op_get_link, | |
1411 | +}; | |
1412 | + | |
1408 | 1413 | static const struct net_device_ops fwnet_netdev_ops = { |
1409 | 1414 | .ndo_open = fwnet_open, |
1410 | 1415 | .ndo_stop = fwnet_stop, |
... | ... | @@ -1423,6 +1428,8 @@ |
1423 | 1428 | net->hard_header_len = FWNET_HLEN; |
1424 | 1429 | net->type = ARPHRD_IEEE1394; |
1425 | 1430 | net->tx_queue_len = FWNET_TX_QUEUE_LEN; |
1431 | + net->ethtool_ops = &fwnet_ethtool_ops; | |
1432 | + | |
1426 | 1433 | } |
1427 | 1434 | |
1428 | 1435 | /* caller must hold fwnet_device_mutex */ |
... | ... | @@ -1463,6 +1470,7 @@ |
1463 | 1470 | |
1464 | 1471 | spin_lock_irq(&dev->lock); |
1465 | 1472 | list_add_tail(&peer->peer_link, &dev->peer_list); |
1473 | + dev->peer_count++; | |
1466 | 1474 | spin_unlock_irq(&dev->lock); |
1467 | 1475 | |
1468 | 1476 | return 0; |
... | ... | @@ -1534,6 +1542,9 @@ |
1534 | 1542 | unregister_netdev(net); |
1535 | 1543 | list_del(&dev->dev_link); |
1536 | 1544 | } |
1545 | + | |
1546 | + if (dev->peer_count > 1) | |
1547 | + netif_carrier_on(net); | |
1537 | 1548 | out: |
1538 | 1549 | if (ret && allocated_netdev) |
1539 | 1550 | free_netdev(net); |
... | ... | @@ -1549,6 +1560,7 @@ |
1549 | 1560 | |
1550 | 1561 | spin_lock_irq(&peer->dev->lock); |
1551 | 1562 | list_del(&peer->peer_link); |
1563 | + peer->dev->peer_count--; | |
1552 | 1564 | spin_unlock_irq(&peer->dev->lock); |
1553 | 1565 | |
1554 | 1566 | list_for_each_entry_safe(pd, pd_next, &peer->pd_list, pd_link) |
... | ... | @@ -1567,6 +1579,11 @@ |
1567 | 1579 | mutex_lock(&fwnet_device_mutex); |
1568 | 1580 | |
1569 | 1581 | fwnet_remove_peer(peer); |
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); | |
1570 | 1587 | |
1571 | 1588 | if (list_empty(&dev->peer_list)) { |
1572 | 1589 | net = dev->netdev; |