diff options
Diffstat (limited to 'drivers/firewire/net.c')
-rw-r--r-- | drivers/firewire/net.c | 47 |
1 files changed, 39 insertions, 8 deletions
diff --git a/drivers/firewire/net.c b/drivers/firewire/net.c index 1a467a91fb0b..c2e194c58667 100644 --- a/drivers/firewire/net.c +++ b/drivers/firewire/net.c | |||
@@ -9,6 +9,7 @@ | |||
9 | #include <linux/bug.h> | 9 | #include <linux/bug.h> |
10 | #include <linux/delay.h> | 10 | #include <linux/delay.h> |
11 | #include <linux/device.h> | 11 | #include <linux/device.h> |
12 | #include <linux/ethtool.h> | ||
12 | #include <linux/firewire.h> | 13 | #include <linux/firewire.h> |
13 | #include <linux/firewire-constants.h> | 14 | #include <linux/firewire-constants.h> |
14 | #include <linux/highmem.h> | 15 | #include <linux/highmem.h> |
@@ -179,6 +180,7 @@ struct fwnet_device { | |||
179 | /* Number of tx datagrams that have been queued but not yet acked */ | 180 | /* Number of tx datagrams that have been queued but not yet acked */ |
180 | int queued_datagrams; | 181 | int queued_datagrams; |
181 | 182 | ||
183 | int peer_count; | ||
182 | struct list_head peer_list; | 184 | struct list_head peer_list; |
183 | struct fw_card *card; | 185 | struct fw_card *card; |
184 | struct net_device *netdev; | 186 | struct net_device *netdev; |
@@ -996,15 +998,23 @@ static void fwnet_transmit_packet_failed(struct fwnet_packet_task *ptask) | |||
996 | static void fwnet_write_complete(struct fw_card *card, int rcode, | 998 | static void fwnet_write_complete(struct fw_card *card, int rcode, |
997 | void *payload, size_t length, void *data) | 999 | void *payload, size_t length, void *data) |
998 | { | 1000 | { |
999 | struct fwnet_packet_task *ptask; | 1001 | struct fwnet_packet_task *ptask = data; |
1000 | 1002 | static unsigned long j; | |
1001 | ptask = data; | 1003 | static int last_rcode, errors_skipped; |
1002 | 1004 | ||
1003 | if (rcode == RCODE_COMPLETE) { | 1005 | if (rcode == RCODE_COMPLETE) { |
1004 | fwnet_transmit_packet_done(ptask); | 1006 | fwnet_transmit_packet_done(ptask); |
1005 | } else { | 1007 | } else { |
1006 | fw_error("fwnet_write_complete: failed: %x\n", rcode); | ||
1007 | fwnet_transmit_packet_failed(ptask); | 1008 | fwnet_transmit_packet_failed(ptask); |
1009 | |||
1010 | if (printk_timed_ratelimit(&j, 1000) || rcode != last_rcode) { | ||
1011 | fw_error("fwnet_write_complete: " | ||
1012 | "failed: %x (skipped %d)\n", rcode, errors_skipped); | ||
1013 | |||
1014 | errors_skipped = 0; | ||
1015 | last_rcode = rcode; | ||
1016 | } else | ||
1017 | errors_skipped++; | ||
1008 | } | 1018 | } |
1009 | } | 1019 | } |
1010 | 1020 | ||
@@ -1213,6 +1223,14 @@ static int fwnet_broadcast_start(struct fwnet_device *dev) | |||
1213 | return retval; | 1223 | return retval; |
1214 | } | 1224 | } |
1215 | 1225 | ||
1226 | static void set_carrier_state(struct fwnet_device *dev) | ||
1227 | { | ||
1228 | if (dev->peer_count > 1) | ||
1229 | netif_carrier_on(dev->netdev); | ||
1230 | else | ||
1231 | netif_carrier_off(dev->netdev); | ||
1232 | } | ||
1233 | |||
1216 | /* ifup */ | 1234 | /* ifup */ |
1217 | static int fwnet_open(struct net_device *net) | 1235 | static int fwnet_open(struct net_device *net) |
1218 | { | 1236 | { |
@@ -1226,6 +1244,10 @@ static int fwnet_open(struct net_device *net) | |||
1226 | } | 1244 | } |
1227 | netif_start_queue(net); | 1245 | netif_start_queue(net); |
1228 | 1246 | ||
1247 | spin_lock_irq(&dev->lock); | ||
1248 | set_carrier_state(dev); | ||
1249 | spin_unlock_irq(&dev->lock); | ||
1250 | |||
1229 | return 0; | 1251 | return 0; |
1230 | } | 1252 | } |
1231 | 1253 | ||
@@ -1397,6 +1419,10 @@ static int fwnet_change_mtu(struct net_device *net, int new_mtu) | |||
1397 | return 0; | 1419 | return 0; |
1398 | } | 1420 | } |
1399 | 1421 | ||
1422 | static const struct ethtool_ops fwnet_ethtool_ops = { | ||
1423 | .get_link = ethtool_op_get_link, | ||
1424 | }; | ||
1425 | |||
1400 | static const struct net_device_ops fwnet_netdev_ops = { | 1426 | static const struct net_device_ops fwnet_netdev_ops = { |
1401 | .ndo_open = fwnet_open, | 1427 | .ndo_open = fwnet_open, |
1402 | .ndo_stop = fwnet_stop, | 1428 | .ndo_stop = fwnet_stop, |
@@ -1415,6 +1441,7 @@ static void fwnet_init_dev(struct net_device *net) | |||
1415 | net->hard_header_len = FWNET_HLEN; | 1441 | net->hard_header_len = FWNET_HLEN; |
1416 | net->type = ARPHRD_IEEE1394; | 1442 | net->type = ARPHRD_IEEE1394; |
1417 | net->tx_queue_len = FWNET_TX_QUEUE_LEN; | 1443 | net->tx_queue_len = FWNET_TX_QUEUE_LEN; |
1444 | net->ethtool_ops = &fwnet_ethtool_ops; | ||
1418 | } | 1445 | } |
1419 | 1446 | ||
1420 | /* caller must hold fwnet_device_mutex */ | 1447 | /* caller must hold fwnet_device_mutex */ |
@@ -1455,6 +1482,8 @@ static int fwnet_add_peer(struct fwnet_device *dev, | |||
1455 | 1482 | ||
1456 | spin_lock_irq(&dev->lock); | 1483 | spin_lock_irq(&dev->lock); |
1457 | list_add_tail(&peer->peer_link, &dev->peer_list); | 1484 | list_add_tail(&peer->peer_link, &dev->peer_list); |
1485 | dev->peer_count++; | ||
1486 | set_carrier_state(dev); | ||
1458 | spin_unlock_irq(&dev->lock); | 1487 | spin_unlock_irq(&dev->lock); |
1459 | 1488 | ||
1460 | return 0; | 1489 | return 0; |
@@ -1535,13 +1564,15 @@ static int fwnet_probe(struct device *_dev) | |||
1535 | return ret; | 1564 | return ret; |
1536 | } | 1565 | } |
1537 | 1566 | ||
1538 | static void fwnet_remove_peer(struct fwnet_peer *peer) | 1567 | static void fwnet_remove_peer(struct fwnet_peer *peer, struct fwnet_device *dev) |
1539 | { | 1568 | { |
1540 | struct fwnet_partial_datagram *pd, *pd_next; | 1569 | struct fwnet_partial_datagram *pd, *pd_next; |
1541 | 1570 | ||
1542 | spin_lock_irq(&peer->dev->lock); | 1571 | spin_lock_irq(&dev->lock); |
1543 | list_del(&peer->peer_link); | 1572 | list_del(&peer->peer_link); |
1544 | spin_unlock_irq(&peer->dev->lock); | 1573 | dev->peer_count--; |
1574 | set_carrier_state(dev); | ||
1575 | spin_unlock_irq(&dev->lock); | ||
1545 | 1576 | ||
1546 | list_for_each_entry_safe(pd, pd_next, &peer->pd_list, pd_link) | 1577 | list_for_each_entry_safe(pd, pd_next, &peer->pd_list, pd_link) |
1547 | fwnet_pd_delete(pd); | 1578 | fwnet_pd_delete(pd); |
@@ -1558,7 +1589,7 @@ static int fwnet_remove(struct device *_dev) | |||
1558 | 1589 | ||
1559 | mutex_lock(&fwnet_device_mutex); | 1590 | mutex_lock(&fwnet_device_mutex); |
1560 | 1591 | ||
1561 | fwnet_remove_peer(peer); | 1592 | fwnet_remove_peer(peer, dev); |
1562 | 1593 | ||
1563 | if (list_empty(&dev->peer_list)) { | 1594 | if (list_empty(&dev->peer_list)) { |
1564 | net = dev->netdev; | 1595 | net = dev->netdev; |