diff options
author | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2011-03-19 02:38:50 -0400 |
---|---|---|
committer | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2011-03-19 02:38:50 -0400 |
commit | 97eb3f24352ec6632c2127b35d8087d2a809a9b9 (patch) | |
tree | 722948059bbd325bbca232269490124231df80d4 /drivers/firewire/net.c | |
parent | 439581ec07fa9cf3f519dd461a2cf41cfd3adcb4 (diff) | |
parent | def179c271ac9b5020deca798470521f14d11edd (diff) |
Merge branch 'next' into for-linus
Diffstat (limited to 'drivers/firewire/net.c')
-rw-r--r-- | drivers/firewire/net.c | 216 |
1 files changed, 137 insertions, 79 deletions
diff --git a/drivers/firewire/net.c b/drivers/firewire/net.c index 18fdd9703b48..7ed08fd1214e 100644 --- a/drivers/firewire/net.c +++ b/drivers/firewire/net.c | |||
@@ -7,7 +7,9 @@ | |||
7 | */ | 7 | */ |
8 | 8 | ||
9 | #include <linux/bug.h> | 9 | #include <linux/bug.h> |
10 | #include <linux/delay.h> | ||
10 | #include <linux/device.h> | 11 | #include <linux/device.h> |
12 | #include <linux/ethtool.h> | ||
11 | #include <linux/firewire.h> | 13 | #include <linux/firewire.h> |
12 | #include <linux/firewire-constants.h> | 14 | #include <linux/firewire-constants.h> |
13 | #include <linux/highmem.h> | 15 | #include <linux/highmem.h> |
@@ -26,8 +28,14 @@ | |||
26 | #include <asm/unaligned.h> | 28 | #include <asm/unaligned.h> |
27 | #include <net/arp.h> | 29 | #include <net/arp.h> |
28 | 30 | ||
29 | #define FWNET_MAX_FRAGMENTS 25 /* arbitrary limit */ | 31 | /* rx limits */ |
30 | #define FWNET_ISO_PAGE_COUNT (PAGE_SIZE < 16 * 1024 ? 4 : 2) | 32 | #define FWNET_MAX_FRAGMENTS 30 /* arbitrary, > TX queue depth */ |
33 | #define FWNET_ISO_PAGE_COUNT (PAGE_SIZE < 16*1024 ? 4 : 2) | ||
34 | |||
35 | /* tx limits */ | ||
36 | #define FWNET_MAX_QUEUED_DATAGRAMS 20 /* < 64 = number of tlabels */ | ||
37 | #define FWNET_MIN_QUEUED_DATAGRAMS 10 /* should keep AT DMA busy enough */ | ||
38 | #define FWNET_TX_QUEUE_LEN FWNET_MAX_QUEUED_DATAGRAMS /* ? */ | ||
31 | 39 | ||
32 | #define IEEE1394_BROADCAST_CHANNEL 31 | 40 | #define IEEE1394_BROADCAST_CHANNEL 31 |
33 | #define IEEE1394_ALL_NODES (0xffc0 | 0x003f) | 41 | #define IEEE1394_ALL_NODES (0xffc0 | 0x003f) |
@@ -169,16 +177,10 @@ struct fwnet_device { | |||
169 | struct fw_address_handler handler; | 177 | struct fw_address_handler handler; |
170 | u64 local_fifo; | 178 | u64 local_fifo; |
171 | 179 | ||
172 | /* List of packets to be sent */ | 180 | /* Number of tx datagrams that have been queued but not yet acked */ |
173 | struct list_head packet_list; | 181 | int queued_datagrams; |
174 | /* | ||
175 | * List of packets that were broadcasted. When we get an ISO interrupt | ||
176 | * one of them has been sent | ||
177 | */ | ||
178 | struct list_head broadcasted_list; | ||
179 | /* List of packets that have been sent but not yet acked */ | ||
180 | struct list_head sent_list; | ||
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; |
@@ -189,13 +191,14 @@ struct fwnet_peer { | |||
189 | struct fwnet_device *dev; | 191 | struct fwnet_device *dev; |
190 | u64 guid; | 192 | u64 guid; |
191 | u64 fifo; | 193 | u64 fifo; |
194 | __be32 ip; | ||
192 | 195 | ||
193 | /* guarded by dev->lock */ | 196 | /* guarded by dev->lock */ |
194 | struct list_head pd_list; /* received partial datagrams */ | 197 | struct list_head pd_list; /* received partial datagrams */ |
195 | unsigned pdg_size; /* pd_list size */ | 198 | unsigned pdg_size; /* pd_list size */ |
196 | 199 | ||
197 | u16 datagram_label; /* outgoing datagram label */ | 200 | u16 datagram_label; /* outgoing datagram label */ |
198 | unsigned max_payload; /* includes RFC2374_FRAG_HDR_SIZE overhead */ | 201 | u16 max_payload; /* includes RFC2374_FRAG_HDR_SIZE overhead */ |
199 | int node_id; | 202 | int node_id; |
200 | int generation; | 203 | int generation; |
201 | unsigned speed; | 204 | unsigned speed; |
@@ -203,22 +206,18 @@ struct fwnet_peer { | |||
203 | 206 | ||
204 | /* This is our task struct. It's used for the packet complete callback. */ | 207 | /* This is our task struct. It's used for the packet complete callback. */ |
205 | struct fwnet_packet_task { | 208 | struct fwnet_packet_task { |
206 | /* | ||
207 | * ptask can actually be on dev->packet_list, dev->broadcasted_list, | ||
208 | * or dev->sent_list depending on its current state. | ||
209 | */ | ||
210 | struct list_head pt_link; | ||
211 | struct fw_transaction transaction; | 209 | struct fw_transaction transaction; |
212 | struct rfc2734_header hdr; | 210 | struct rfc2734_header hdr; |
213 | struct sk_buff *skb; | 211 | struct sk_buff *skb; |
214 | struct fwnet_device *dev; | 212 | struct fwnet_device *dev; |
215 | 213 | ||
216 | int outstanding_pkts; | 214 | int outstanding_pkts; |
217 | unsigned max_payload; | ||
218 | u64 fifo_addr; | 215 | u64 fifo_addr; |
219 | u16 dest_node; | 216 | u16 dest_node; |
217 | u16 max_payload; | ||
220 | u8 generation; | 218 | u8 generation; |
221 | u8 speed; | 219 | u8 speed; |
220 | u8 enqueued; | ||
222 | }; | 221 | }; |
223 | 222 | ||
224 | /* | 223 | /* |
@@ -572,6 +571,8 @@ static int fwnet_finish_incoming_packet(struct net_device *net, | |||
572 | peer->speed = sspd; | 571 | peer->speed = sspd; |
573 | if (peer->max_payload > max_payload) | 572 | if (peer->max_payload > max_payload) |
574 | peer->max_payload = max_payload; | 573 | peer->max_payload = max_payload; |
574 | |||
575 | peer->ip = arp1394->sip; | ||
575 | } | 576 | } |
576 | spin_unlock_irqrestore(&dev->lock, flags); | 577 | spin_unlock_irqrestore(&dev->lock, flags); |
577 | 578 | ||
@@ -650,8 +651,6 @@ static int fwnet_finish_incoming_packet(struct net_device *net, | |||
650 | net->stats.rx_packets++; | 651 | net->stats.rx_packets++; |
651 | net->stats.rx_bytes += skb->len; | 652 | net->stats.rx_bytes += skb->len; |
652 | } | 653 | } |
653 | if (netif_queue_stopped(net)) | ||
654 | netif_wake_queue(net); | ||
655 | 654 | ||
656 | return 0; | 655 | return 0; |
657 | 656 | ||
@@ -660,8 +659,6 @@ static int fwnet_finish_incoming_packet(struct net_device *net, | |||
660 | net->stats.rx_dropped++; | 659 | net->stats.rx_dropped++; |
661 | 660 | ||
662 | dev_kfree_skb_any(skb); | 661 | dev_kfree_skb_any(skb); |
663 | if (netif_queue_stopped(net)) | ||
664 | netif_wake_queue(net); | ||
665 | 662 | ||
666 | return -ENOENT; | 663 | return -ENOENT; |
667 | } | 664 | } |
@@ -793,15 +790,10 @@ static int fwnet_incoming_packet(struct fwnet_device *dev, __be32 *buf, int len, | |||
793 | * Datagram is not complete, we're done for the | 790 | * Datagram is not complete, we're done for the |
794 | * moment. | 791 | * moment. |
795 | */ | 792 | */ |
796 | spin_unlock_irqrestore(&dev->lock, flags); | 793 | retval = 0; |
797 | |||
798 | return 0; | ||
799 | fail: | 794 | fail: |
800 | spin_unlock_irqrestore(&dev->lock, flags); | 795 | spin_unlock_irqrestore(&dev->lock, flags); |
801 | 796 | ||
802 | if (netif_queue_stopped(net)) | ||
803 | netif_wake_queue(net); | ||
804 | |||
805 | return retval; | 797 | return retval; |
806 | } | 798 | } |
807 | 799 | ||
@@ -901,11 +893,19 @@ static void fwnet_free_ptask(struct fwnet_packet_task *ptask) | |||
901 | kmem_cache_free(fwnet_packet_task_cache, ptask); | 893 | kmem_cache_free(fwnet_packet_task_cache, ptask); |
902 | } | 894 | } |
903 | 895 | ||
896 | /* Caller must hold dev->lock. */ | ||
897 | static void dec_queued_datagrams(struct fwnet_device *dev) | ||
898 | { | ||
899 | if (--dev->queued_datagrams == FWNET_MIN_QUEUED_DATAGRAMS) | ||
900 | netif_wake_queue(dev->netdev); | ||
901 | } | ||
902 | |||
904 | static int fwnet_send_packet(struct fwnet_packet_task *ptask); | 903 | static int fwnet_send_packet(struct fwnet_packet_task *ptask); |
905 | 904 | ||
906 | static void fwnet_transmit_packet_done(struct fwnet_packet_task *ptask) | 905 | static void fwnet_transmit_packet_done(struct fwnet_packet_task *ptask) |
907 | { | 906 | { |
908 | struct fwnet_device *dev = ptask->dev; | 907 | struct fwnet_device *dev = ptask->dev; |
908 | struct sk_buff *skb = ptask->skb; | ||
909 | unsigned long flags; | 909 | unsigned long flags; |
910 | bool free; | 910 | bool free; |
911 | 911 | ||
@@ -914,10 +914,14 @@ static void fwnet_transmit_packet_done(struct fwnet_packet_task *ptask) | |||
914 | ptask->outstanding_pkts--; | 914 | ptask->outstanding_pkts--; |
915 | 915 | ||
916 | /* Check whether we or the networking TX soft-IRQ is last user. */ | 916 | /* Check whether we or the networking TX soft-IRQ is last user. */ |
917 | free = (ptask->outstanding_pkts == 0 && !list_empty(&ptask->pt_link)); | 917 | free = (ptask->outstanding_pkts == 0 && ptask->enqueued); |
918 | if (free) | ||
919 | dec_queued_datagrams(dev); | ||
918 | 920 | ||
919 | if (ptask->outstanding_pkts == 0) | 921 | if (ptask->outstanding_pkts == 0) { |
920 | list_del(&ptask->pt_link); | 922 | dev->netdev->stats.tx_packets++; |
923 | dev->netdev->stats.tx_bytes += skb->len; | ||
924 | } | ||
921 | 925 | ||
922 | spin_unlock_irqrestore(&dev->lock, flags); | 926 | spin_unlock_irqrestore(&dev->lock, flags); |
923 | 927 | ||
@@ -926,7 +930,6 @@ static void fwnet_transmit_packet_done(struct fwnet_packet_task *ptask) | |||
926 | u16 fg_off; | 930 | u16 fg_off; |
927 | u16 datagram_label; | 931 | u16 datagram_label; |
928 | u16 lf; | 932 | u16 lf; |
929 | struct sk_buff *skb; | ||
930 | 933 | ||
931 | /* Update the ptask to point to the next fragment and send it */ | 934 | /* Update the ptask to point to the next fragment and send it */ |
932 | lf = fwnet_get_hdr_lf(&ptask->hdr); | 935 | lf = fwnet_get_hdr_lf(&ptask->hdr); |
@@ -953,7 +956,7 @@ static void fwnet_transmit_packet_done(struct fwnet_packet_task *ptask) | |||
953 | datagram_label = fwnet_get_hdr_dgl(&ptask->hdr); | 956 | datagram_label = fwnet_get_hdr_dgl(&ptask->hdr); |
954 | break; | 957 | break; |
955 | } | 958 | } |
956 | skb = ptask->skb; | 959 | |
957 | skb_pull(skb, ptask->max_payload); | 960 | skb_pull(skb, ptask->max_payload); |
958 | if (ptask->outstanding_pkts > 1) { | 961 | if (ptask->outstanding_pkts > 1) { |
959 | fwnet_make_sf_hdr(&ptask->hdr, RFC2374_HDR_INTFRAG, | 962 | fwnet_make_sf_hdr(&ptask->hdr, RFC2374_HDR_INTFRAG, |
@@ -970,18 +973,52 @@ static void fwnet_transmit_packet_done(struct fwnet_packet_task *ptask) | |||
970 | fwnet_free_ptask(ptask); | 973 | fwnet_free_ptask(ptask); |
971 | } | 974 | } |
972 | 975 | ||
976 | static void fwnet_transmit_packet_failed(struct fwnet_packet_task *ptask) | ||
977 | { | ||
978 | struct fwnet_device *dev = ptask->dev; | ||
979 | unsigned long flags; | ||
980 | bool free; | ||
981 | |||
982 | spin_lock_irqsave(&dev->lock, flags); | ||
983 | |||
984 | /* One fragment failed; don't try to send remaining fragments. */ | ||
985 | ptask->outstanding_pkts = 0; | ||
986 | |||
987 | /* Check whether we or the networking TX soft-IRQ is last user. */ | ||
988 | free = ptask->enqueued; | ||
989 | if (free) | ||
990 | dec_queued_datagrams(dev); | ||
991 | |||
992 | dev->netdev->stats.tx_dropped++; | ||
993 | dev->netdev->stats.tx_errors++; | ||
994 | |||
995 | spin_unlock_irqrestore(&dev->lock, flags); | ||
996 | |||
997 | if (free) | ||
998 | fwnet_free_ptask(ptask); | ||
999 | } | ||
1000 | |||
973 | static void fwnet_write_complete(struct fw_card *card, int rcode, | 1001 | static void fwnet_write_complete(struct fw_card *card, int rcode, |
974 | void *payload, size_t length, void *data) | 1002 | void *payload, size_t length, void *data) |
975 | { | 1003 | { |
976 | struct fwnet_packet_task *ptask; | 1004 | struct fwnet_packet_task *ptask = data; |
977 | 1005 | static unsigned long j; | |
978 | ptask = data; | 1006 | static int last_rcode, errors_skipped; |
979 | 1007 | ||
980 | if (rcode == RCODE_COMPLETE) | 1008 | if (rcode == RCODE_COMPLETE) { |
981 | fwnet_transmit_packet_done(ptask); | 1009 | fwnet_transmit_packet_done(ptask); |
982 | else | 1010 | } else { |
983 | fw_error("fwnet_write_complete: failed: %x\n", rcode); | 1011 | fwnet_transmit_packet_failed(ptask); |
984 | /* ??? error recovery */ | 1012 | |
1013 | if (printk_timed_ratelimit(&j, 1000) || rcode != last_rcode) { | ||
1014 | fw_error("fwnet_write_complete: " | ||
1015 | "failed: %x (skipped %d)\n", rcode, errors_skipped); | ||
1016 | |||
1017 | errors_skipped = 0; | ||
1018 | last_rcode = rcode; | ||
1019 | } else | ||
1020 | errors_skipped++; | ||
1021 | } | ||
985 | } | 1022 | } |
986 | 1023 | ||
987 | static int fwnet_send_packet(struct fwnet_packet_task *ptask) | 1024 | static int fwnet_send_packet(struct fwnet_packet_task *ptask) |
@@ -1039,9 +1076,11 @@ static int fwnet_send_packet(struct fwnet_packet_task *ptask) | |||
1039 | spin_lock_irqsave(&dev->lock, flags); | 1076 | spin_lock_irqsave(&dev->lock, flags); |
1040 | 1077 | ||
1041 | /* If the AT tasklet already ran, we may be last user. */ | 1078 | /* If the AT tasklet already ran, we may be last user. */ |
1042 | free = (ptask->outstanding_pkts == 0 && list_empty(&ptask->pt_link)); | 1079 | free = (ptask->outstanding_pkts == 0 && !ptask->enqueued); |
1043 | if (!free) | 1080 | if (!free) |
1044 | list_add_tail(&ptask->pt_link, &dev->broadcasted_list); | 1081 | ptask->enqueued = true; |
1082 | else | ||
1083 | dec_queued_datagrams(dev); | ||
1045 | 1084 | ||
1046 | spin_unlock_irqrestore(&dev->lock, flags); | 1085 | spin_unlock_irqrestore(&dev->lock, flags); |
1047 | 1086 | ||
@@ -1056,9 +1095,11 @@ static int fwnet_send_packet(struct fwnet_packet_task *ptask) | |||
1056 | spin_lock_irqsave(&dev->lock, flags); | 1095 | spin_lock_irqsave(&dev->lock, flags); |
1057 | 1096 | ||
1058 | /* If the AT tasklet already ran, we may be last user. */ | 1097 | /* If the AT tasklet already ran, we may be last user. */ |
1059 | free = (ptask->outstanding_pkts == 0 && list_empty(&ptask->pt_link)); | 1098 | free = (ptask->outstanding_pkts == 0 && !ptask->enqueued); |
1060 | if (!free) | 1099 | if (!free) |
1061 | list_add_tail(&ptask->pt_link, &dev->sent_list); | 1100 | ptask->enqueued = true; |
1101 | else | ||
1102 | dec_queued_datagrams(dev); | ||
1062 | 1103 | ||
1063 | spin_unlock_irqrestore(&dev->lock, flags); | 1104 | spin_unlock_irqrestore(&dev->lock, flags); |
1064 | 1105 | ||
@@ -1185,6 +1226,14 @@ static int fwnet_broadcast_start(struct fwnet_device *dev) | |||
1185 | return retval; | 1226 | return retval; |
1186 | } | 1227 | } |
1187 | 1228 | ||
1229 | static void set_carrier_state(struct fwnet_device *dev) | ||
1230 | { | ||
1231 | if (dev->peer_count > 1) | ||
1232 | netif_carrier_on(dev->netdev); | ||
1233 | else | ||
1234 | netif_carrier_off(dev->netdev); | ||
1235 | } | ||
1236 | |||
1188 | /* ifup */ | 1237 | /* ifup */ |
1189 | static int fwnet_open(struct net_device *net) | 1238 | static int fwnet_open(struct net_device *net) |
1190 | { | 1239 | { |
@@ -1198,6 +1247,10 @@ static int fwnet_open(struct net_device *net) | |||
1198 | } | 1247 | } |
1199 | netif_start_queue(net); | 1248 | netif_start_queue(net); |
1200 | 1249 | ||
1250 | spin_lock_irq(&dev->lock); | ||
1251 | set_carrier_state(dev); | ||
1252 | spin_unlock_irq(&dev->lock); | ||
1253 | |||
1201 | return 0; | 1254 | return 0; |
1202 | } | 1255 | } |
1203 | 1256 | ||
@@ -1224,6 +1277,15 @@ static netdev_tx_t fwnet_tx(struct sk_buff *skb, struct net_device *net) | |||
1224 | struct fwnet_peer *peer; | 1277 | struct fwnet_peer *peer; |
1225 | unsigned long flags; | 1278 | unsigned long flags; |
1226 | 1279 | ||
1280 | spin_lock_irqsave(&dev->lock, flags); | ||
1281 | |||
1282 | /* Can this happen? */ | ||
1283 | if (netif_queue_stopped(dev->netdev)) { | ||
1284 | spin_unlock_irqrestore(&dev->lock, flags); | ||
1285 | |||
1286 | return NETDEV_TX_BUSY; | ||
1287 | } | ||
1288 | |||
1227 | ptask = kmem_cache_alloc(fwnet_packet_task_cache, GFP_ATOMIC); | 1289 | ptask = kmem_cache_alloc(fwnet_packet_task_cache, GFP_ATOMIC); |
1228 | if (ptask == NULL) | 1290 | if (ptask == NULL) |
1229 | goto fail; | 1291 | goto fail; |
@@ -1242,9 +1304,6 @@ static netdev_tx_t fwnet_tx(struct sk_buff *skb, struct net_device *net) | |||
1242 | proto = hdr_buf.h_proto; | 1304 | proto = hdr_buf.h_proto; |
1243 | dg_size = skb->len; | 1305 | dg_size = skb->len; |
1244 | 1306 | ||
1245 | /* serialize access to peer, including peer->datagram_label */ | ||
1246 | spin_lock_irqsave(&dev->lock, flags); | ||
1247 | |||
1248 | /* | 1307 | /* |
1249 | * Set the transmission type for the packet. ARP packets and IP | 1308 | * Set the transmission type for the packet. ARP packets and IP |
1250 | * broadcast packets are sent via GASP. | 1309 | * broadcast packets are sent via GASP. |
@@ -1266,7 +1325,7 @@ static netdev_tx_t fwnet_tx(struct sk_buff *skb, struct net_device *net) | |||
1266 | 1325 | ||
1267 | peer = fwnet_peer_find_by_guid(dev, be64_to_cpu(guid)); | 1326 | peer = fwnet_peer_find_by_guid(dev, be64_to_cpu(guid)); |
1268 | if (!peer || peer->fifo == FWNET_NO_FIFO_ADDR) | 1327 | if (!peer || peer->fifo == FWNET_NO_FIFO_ADDR) |
1269 | goto fail_unlock; | 1328 | goto fail; |
1270 | 1329 | ||
1271 | generation = peer->generation; | 1330 | generation = peer->generation; |
1272 | dest_node = peer->node_id; | 1331 | dest_node = peer->node_id; |
@@ -1320,18 +1379,21 @@ static netdev_tx_t fwnet_tx(struct sk_buff *skb, struct net_device *net) | |||
1320 | max_payload += RFC2374_FRAG_HDR_SIZE; | 1379 | max_payload += RFC2374_FRAG_HDR_SIZE; |
1321 | } | 1380 | } |
1322 | 1381 | ||
1382 | if (++dev->queued_datagrams == FWNET_MAX_QUEUED_DATAGRAMS) | ||
1383 | netif_stop_queue(dev->netdev); | ||
1384 | |||
1323 | spin_unlock_irqrestore(&dev->lock, flags); | 1385 | spin_unlock_irqrestore(&dev->lock, flags); |
1324 | 1386 | ||
1325 | ptask->max_payload = max_payload; | 1387 | ptask->max_payload = max_payload; |
1326 | INIT_LIST_HEAD(&ptask->pt_link); | 1388 | ptask->enqueued = 0; |
1327 | 1389 | ||
1328 | fwnet_send_packet(ptask); | 1390 | fwnet_send_packet(ptask); |
1329 | 1391 | ||
1330 | return NETDEV_TX_OK; | 1392 | return NETDEV_TX_OK; |
1331 | 1393 | ||
1332 | fail_unlock: | ||
1333 | spin_unlock_irqrestore(&dev->lock, flags); | ||
1334 | fail: | 1394 | fail: |
1395 | spin_unlock_irqrestore(&dev->lock, flags); | ||
1396 | |||
1335 | if (ptask) | 1397 | if (ptask) |
1336 | kmem_cache_free(fwnet_packet_task_cache, ptask); | 1398 | kmem_cache_free(fwnet_packet_task_cache, ptask); |
1337 | 1399 | ||
@@ -1360,6 +1422,10 @@ static int fwnet_change_mtu(struct net_device *net, int new_mtu) | |||
1360 | return 0; | 1422 | return 0; |
1361 | } | 1423 | } |
1362 | 1424 | ||
1425 | static const struct ethtool_ops fwnet_ethtool_ops = { | ||
1426 | .get_link = ethtool_op_get_link, | ||
1427 | }; | ||
1428 | |||
1363 | static const struct net_device_ops fwnet_netdev_ops = { | 1429 | static const struct net_device_ops fwnet_netdev_ops = { |
1364 | .ndo_open = fwnet_open, | 1430 | .ndo_open = fwnet_open, |
1365 | .ndo_stop = fwnet_stop, | 1431 | .ndo_stop = fwnet_stop, |
@@ -1377,7 +1443,8 @@ static void fwnet_init_dev(struct net_device *net) | |||
1377 | net->addr_len = FWNET_ALEN; | 1443 | net->addr_len = FWNET_ALEN; |
1378 | net->hard_header_len = FWNET_HLEN; | 1444 | net->hard_header_len = FWNET_HLEN; |
1379 | net->type = ARPHRD_IEEE1394; | 1445 | net->type = ARPHRD_IEEE1394; |
1380 | net->tx_queue_len = 10; | 1446 | net->tx_queue_len = FWNET_TX_QUEUE_LEN; |
1447 | net->ethtool_ops = &fwnet_ethtool_ops; | ||
1381 | } | 1448 | } |
1382 | 1449 | ||
1383 | /* caller must hold fwnet_device_mutex */ | 1450 | /* caller must hold fwnet_device_mutex */ |
@@ -1406,6 +1473,7 @@ static int fwnet_add_peer(struct fwnet_device *dev, | |||
1406 | peer->dev = dev; | 1473 | peer->dev = dev; |
1407 | peer->guid = (u64)device->config_rom[3] << 32 | device->config_rom[4]; | 1474 | peer->guid = (u64)device->config_rom[3] << 32 | device->config_rom[4]; |
1408 | peer->fifo = FWNET_NO_FIFO_ADDR; | 1475 | peer->fifo = FWNET_NO_FIFO_ADDR; |
1476 | peer->ip = 0; | ||
1409 | INIT_LIST_HEAD(&peer->pd_list); | 1477 | INIT_LIST_HEAD(&peer->pd_list); |
1410 | peer->pdg_size = 0; | 1478 | peer->pdg_size = 0; |
1411 | peer->datagram_label = 0; | 1479 | peer->datagram_label = 0; |
@@ -1418,6 +1486,8 @@ static int fwnet_add_peer(struct fwnet_device *dev, | |||
1418 | 1486 | ||
1419 | spin_lock_irq(&dev->lock); | 1487 | spin_lock_irq(&dev->lock); |
1420 | list_add_tail(&peer->peer_link, &dev->peer_list); | 1488 | list_add_tail(&peer->peer_link, &dev->peer_list); |
1489 | dev->peer_count++; | ||
1490 | set_carrier_state(dev); | ||
1421 | spin_unlock_irq(&dev->lock); | 1491 | spin_unlock_irq(&dev->lock); |
1422 | 1492 | ||
1423 | return 0; | 1493 | return 0; |
@@ -1457,14 +1527,9 @@ static int fwnet_probe(struct device *_dev) | |||
1457 | dev->broadcast_rcv_context = NULL; | 1527 | dev->broadcast_rcv_context = NULL; |
1458 | dev->broadcast_xmt_max_payload = 0; | 1528 | dev->broadcast_xmt_max_payload = 0; |
1459 | dev->broadcast_xmt_datagramlabel = 0; | 1529 | dev->broadcast_xmt_datagramlabel = 0; |
1460 | |||
1461 | dev->local_fifo = FWNET_NO_FIFO_ADDR; | 1530 | dev->local_fifo = FWNET_NO_FIFO_ADDR; |
1462 | 1531 | dev->queued_datagrams = 0; | |
1463 | INIT_LIST_HEAD(&dev->packet_list); | ||
1464 | INIT_LIST_HEAD(&dev->broadcasted_list); | ||
1465 | INIT_LIST_HEAD(&dev->sent_list); | ||
1466 | INIT_LIST_HEAD(&dev->peer_list); | 1532 | INIT_LIST_HEAD(&dev->peer_list); |
1467 | |||
1468 | dev->card = card; | 1533 | dev->card = card; |
1469 | dev->netdev = net; | 1534 | dev->netdev = net; |
1470 | 1535 | ||
@@ -1503,13 +1568,15 @@ static int fwnet_probe(struct device *_dev) | |||
1503 | return ret; | 1568 | return ret; |
1504 | } | 1569 | } |
1505 | 1570 | ||
1506 | static void fwnet_remove_peer(struct fwnet_peer *peer) | 1571 | static void fwnet_remove_peer(struct fwnet_peer *peer, struct fwnet_device *dev) |
1507 | { | 1572 | { |
1508 | struct fwnet_partial_datagram *pd, *pd_next; | 1573 | struct fwnet_partial_datagram *pd, *pd_next; |
1509 | 1574 | ||
1510 | spin_lock_irq(&peer->dev->lock); | 1575 | spin_lock_irq(&dev->lock); |
1511 | list_del(&peer->peer_link); | 1576 | list_del(&peer->peer_link); |
1512 | spin_unlock_irq(&peer->dev->lock); | 1577 | dev->peer_count--; |
1578 | set_carrier_state(dev); | ||
1579 | spin_unlock_irq(&dev->lock); | ||
1513 | 1580 | ||
1514 | list_for_each_entry_safe(pd, pd_next, &peer->pd_list, pd_link) | 1581 | list_for_each_entry_safe(pd, pd_next, &peer->pd_list, pd_link) |
1515 | fwnet_pd_delete(pd); | 1582 | fwnet_pd_delete(pd); |
@@ -1522,14 +1589,17 @@ static int fwnet_remove(struct device *_dev) | |||
1522 | struct fwnet_peer *peer = dev_get_drvdata(_dev); | 1589 | struct fwnet_peer *peer = dev_get_drvdata(_dev); |
1523 | struct fwnet_device *dev = peer->dev; | 1590 | struct fwnet_device *dev = peer->dev; |
1524 | struct net_device *net; | 1591 | struct net_device *net; |
1525 | struct fwnet_packet_task *ptask, *pt_next; | 1592 | int i; |
1526 | 1593 | ||
1527 | mutex_lock(&fwnet_device_mutex); | 1594 | mutex_lock(&fwnet_device_mutex); |
1528 | 1595 | ||
1529 | fwnet_remove_peer(peer); | 1596 | net = dev->netdev; |
1597 | if (net && peer->ip) | ||
1598 | arp_invalidate(net, peer->ip); | ||
1599 | |||
1600 | fwnet_remove_peer(peer, dev); | ||
1530 | 1601 | ||
1531 | if (list_empty(&dev->peer_list)) { | 1602 | if (list_empty(&dev->peer_list)) { |
1532 | net = dev->netdev; | ||
1533 | unregister_netdev(net); | 1603 | unregister_netdev(net); |
1534 | 1604 | ||
1535 | if (dev->local_fifo != FWNET_NO_FIFO_ADDR) | 1605 | if (dev->local_fifo != FWNET_NO_FIFO_ADDR) |
@@ -1540,21 +1610,9 @@ static int fwnet_remove(struct device *_dev) | |||
1540 | dev->card); | 1610 | dev->card); |
1541 | fw_iso_context_destroy(dev->broadcast_rcv_context); | 1611 | fw_iso_context_destroy(dev->broadcast_rcv_context); |
1542 | } | 1612 | } |
1543 | list_for_each_entry_safe(ptask, pt_next, | 1613 | for (i = 0; dev->queued_datagrams && i < 5; i++) |
1544 | &dev->packet_list, pt_link) { | 1614 | ssleep(1); |
1545 | dev_kfree_skb_any(ptask->skb); | 1615 | WARN_ON(dev->queued_datagrams); |
1546 | kmem_cache_free(fwnet_packet_task_cache, ptask); | ||
1547 | } | ||
1548 | list_for_each_entry_safe(ptask, pt_next, | ||
1549 | &dev->broadcasted_list, pt_link) { | ||
1550 | dev_kfree_skb_any(ptask->skb); | ||
1551 | kmem_cache_free(fwnet_packet_task_cache, ptask); | ||
1552 | } | ||
1553 | list_for_each_entry_safe(ptask, pt_next, | ||
1554 | &dev->sent_list, pt_link) { | ||
1555 | dev_kfree_skb_any(ptask->skb); | ||
1556 | kmem_cache_free(fwnet_packet_task_cache, ptask); | ||
1557 | } | ||
1558 | list_del(&dev->dev_link); | 1616 | list_del(&dev->dev_link); |
1559 | 1617 | ||
1560 | free_netdev(net); | 1618 | free_netdev(net); |