diff options
-rw-r--r-- | MAINTAINERS | 6 | ||||
-rw-r--r-- | drivers/ieee1394/ieee1394_core.c | 2 | ||||
-rw-r--r-- | drivers/ieee1394/ohci1394.c | 4 | ||||
-rw-r--r-- | drivers/net/bnx2.c | 7 | ||||
-rw-r--r-- | drivers/net/myri10ge/myri10ge.c | 3 | ||||
-rw-r--r-- | drivers/net/phy/phy.c | 1 | ||||
-rw-r--r-- | drivers/net/pppoe.c | 3 | ||||
-rw-r--r-- | drivers/net/pppol2tp.c | 118 | ||||
-rw-r--r-- | drivers/net/sky2.c | 368 | ||||
-rw-r--r-- | drivers/net/sky2.h | 41 | ||||
-rw-r--r-- | fs/exec.c | 3 | ||||
-rw-r--r-- | fs/signalfd.c | 190 | ||||
-rw-r--r-- | include/linux/init_task.h | 2 | ||||
-rw-r--r-- | include/linux/sched.h | 2 | ||||
-rw-r--r-- | include/linux/signalfd.h | 40 | ||||
-rw-r--r-- | kernel/exit.c | 9 | ||||
-rw-r--r-- | kernel/fork.c | 2 | ||||
-rw-r--r-- | kernel/signal.c | 8 | ||||
-rw-r--r-- | net/netfilter/nfnetlink_log.c | 13 | ||||
-rw-r--r-- | net/sched/sch_sfq.c | 10 | ||||
-rw-r--r-- | net/sunrpc/svcsock.c | 3 |
21 files changed, 408 insertions, 427 deletions
diff --git a/MAINTAINERS b/MAINTAINERS index 9c54a5ef0ba7..9a91d9e3f1f2 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -2622,8 +2622,8 @@ P: Harald Welte | |||
2622 | P: Jozsef Kadlecsik | 2622 | P: Jozsef Kadlecsik |
2623 | P: Patrick McHardy | 2623 | P: Patrick McHardy |
2624 | M: kaber@trash.net | 2624 | M: kaber@trash.net |
2625 | L: netfilter-devel@lists.netfilter.org | 2625 | L: netfilter-devel@vger.kernel.org |
2626 | L: netfilter@lists.netfilter.org (subscribers-only) | 2626 | L: netfilter@vger.kernel.org |
2627 | L: coreteam@netfilter.org | 2627 | L: coreteam@netfilter.org |
2628 | W: http://www.netfilter.org/ | 2628 | W: http://www.netfilter.org/ |
2629 | W: http://www.iptables.org/ | 2629 | W: http://www.iptables.org/ |
@@ -2676,7 +2676,7 @@ M: jmorris@namei.org | |||
2676 | P: Hideaki YOSHIFUJI | 2676 | P: Hideaki YOSHIFUJI |
2677 | M: yoshfuji@linux-ipv6.org | 2677 | M: yoshfuji@linux-ipv6.org |
2678 | P: Patrick McHardy | 2678 | P: Patrick McHardy |
2679 | M: kaber@coreworks.de | 2679 | M: kaber@trash.net |
2680 | L: netdev@vger.kernel.org | 2680 | L: netdev@vger.kernel.org |
2681 | T: git kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6.git | 2681 | T: git kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6.git |
2682 | S: Maintained | 2682 | S: Maintained |
diff --git a/drivers/ieee1394/ieee1394_core.c b/drivers/ieee1394/ieee1394_core.c index ee45259573c8..98fd985a32ff 100644 --- a/drivers/ieee1394/ieee1394_core.c +++ b/drivers/ieee1394/ieee1394_core.c | |||
@@ -1273,7 +1273,7 @@ static void __exit ieee1394_cleanup(void) | |||
1273 | unregister_chrdev_region(IEEE1394_CORE_DEV, 256); | 1273 | unregister_chrdev_region(IEEE1394_CORE_DEV, 256); |
1274 | } | 1274 | } |
1275 | 1275 | ||
1276 | fs_initcall(ieee1394_init); /* same as ohci1394 */ | 1276 | module_init(ieee1394_init); |
1277 | module_exit(ieee1394_cleanup); | 1277 | module_exit(ieee1394_cleanup); |
1278 | 1278 | ||
1279 | /* Exported symbols */ | 1279 | /* Exported symbols */ |
diff --git a/drivers/ieee1394/ohci1394.c b/drivers/ieee1394/ohci1394.c index 5667c8102efc..372c5c16eb31 100644 --- a/drivers/ieee1394/ohci1394.c +++ b/drivers/ieee1394/ohci1394.c | |||
@@ -3537,7 +3537,5 @@ static int __init ohci1394_init(void) | |||
3537 | return pci_register_driver(&ohci1394_pci_driver); | 3537 | return pci_register_driver(&ohci1394_pci_driver); |
3538 | } | 3538 | } |
3539 | 3539 | ||
3540 | /* Register before most other device drivers. | 3540 | module_init(ohci1394_init); |
3541 | * Useful for remote debugging via physical DMA, e.g. using firescope. */ | ||
3542 | fs_initcall(ohci1394_init); | ||
3543 | module_exit(ohci1394_cleanup); | 3541 | module_exit(ohci1394_cleanup); |
diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c index 854d80c330ec..66eed22cbd21 100644 --- a/drivers/net/bnx2.c +++ b/drivers/net/bnx2.c | |||
@@ -54,8 +54,8 @@ | |||
54 | 54 | ||
55 | #define DRV_MODULE_NAME "bnx2" | 55 | #define DRV_MODULE_NAME "bnx2" |
56 | #define PFX DRV_MODULE_NAME ": " | 56 | #define PFX DRV_MODULE_NAME ": " |
57 | #define DRV_MODULE_VERSION "1.6.4" | 57 | #define DRV_MODULE_VERSION "1.6.5" |
58 | #define DRV_MODULE_RELDATE "August 3, 2007" | 58 | #define DRV_MODULE_RELDATE "September 20, 2007" |
59 | 59 | ||
60 | #define RUN_AT(x) (jiffies + (x)) | 60 | #define RUN_AT(x) (jiffies + (x)) |
61 | 61 | ||
@@ -6727,7 +6727,8 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev) | |||
6727 | } else if (CHIP_NUM(bp) == CHIP_NUM_5706 || | 6727 | } else if (CHIP_NUM(bp) == CHIP_NUM_5706 || |
6728 | CHIP_NUM(bp) == CHIP_NUM_5708) | 6728 | CHIP_NUM(bp) == CHIP_NUM_5708) |
6729 | bp->phy_flags |= PHY_CRC_FIX_FLAG; | 6729 | bp->phy_flags |= PHY_CRC_FIX_FLAG; |
6730 | else if (CHIP_ID(bp) == CHIP_ID_5709_A0) | 6730 | else if (CHIP_ID(bp) == CHIP_ID_5709_A0 || |
6731 | CHIP_ID(bp) == CHIP_ID_5709_A1) | ||
6731 | bp->phy_flags |= PHY_DIS_EARLY_DAC_FLAG; | 6732 | bp->phy_flags |= PHY_DIS_EARLY_DAC_FLAG; |
6732 | 6733 | ||
6733 | if ((CHIP_ID(bp) == CHIP_ID_5708_A0) || | 6734 | if ((CHIP_ID(bp) == CHIP_ID_5708_A0) || |
diff --git a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c index 1c42266bf889..556962f9612d 100644 --- a/drivers/net/myri10ge/myri10ge.c +++ b/drivers/net/myri10ge/myri10ge.c | |||
@@ -3094,9 +3094,12 @@ static void myri10ge_remove(struct pci_dev *pdev) | |||
3094 | } | 3094 | } |
3095 | 3095 | ||
3096 | #define PCI_DEVICE_ID_MYRICOM_MYRI10GE_Z8E 0x0008 | 3096 | #define PCI_DEVICE_ID_MYRICOM_MYRI10GE_Z8E 0x0008 |
3097 | #define PCI_DEVICE_ID_MYRICOM_MYRI10GE_Z8E_9 0x0009 | ||
3097 | 3098 | ||
3098 | static struct pci_device_id myri10ge_pci_tbl[] = { | 3099 | static struct pci_device_id myri10ge_pci_tbl[] = { |
3099 | {PCI_DEVICE(PCI_VENDOR_ID_MYRICOM, PCI_DEVICE_ID_MYRICOM_MYRI10GE_Z8E)}, | 3100 | {PCI_DEVICE(PCI_VENDOR_ID_MYRICOM, PCI_DEVICE_ID_MYRICOM_MYRI10GE_Z8E)}, |
3101 | {PCI_DEVICE | ||
3102 | (PCI_VENDOR_ID_MYRICOM, PCI_DEVICE_ID_MYRICOM_MYRI10GE_Z8E_9)}, | ||
3100 | {0}, | 3103 | {0}, |
3101 | }; | 3104 | }; |
3102 | 3105 | ||
diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c index 0cc4369cacba..cb230f44d6fc 100644 --- a/drivers/net/phy/phy.c +++ b/drivers/net/phy/phy.c | |||
@@ -409,6 +409,7 @@ int phy_mii_ioctl(struct phy_device *phydev, | |||
409 | 409 | ||
410 | return 0; | 410 | return 0; |
411 | } | 411 | } |
412 | EXPORT_SYMBOL(phy_mii_ioctl); | ||
412 | 413 | ||
413 | /** | 414 | /** |
414 | * phy_start_aneg - start auto-negotiation for this PHY device | 415 | * phy_start_aneg - start auto-negotiation for this PHY device |
diff --git a/drivers/net/pppoe.c b/drivers/net/pppoe.c index 0d7f570b9a54..9b30cd600a64 100644 --- a/drivers/net/pppoe.c +++ b/drivers/net/pppoe.c | |||
@@ -879,8 +879,7 @@ static int __pppoe_xmit(struct sock *sk, struct sk_buff *skb) | |||
879 | dev->hard_header(skb, dev, ETH_P_PPP_SES, | 879 | dev->hard_header(skb, dev, ETH_P_PPP_SES, |
880 | po->pppoe_pa.remote, NULL, data_len); | 880 | po->pppoe_pa.remote, NULL, data_len); |
881 | 881 | ||
882 | if (dev_queue_xmit(skb) < 0) | 882 | dev_queue_xmit(skb); |
883 | goto abort; | ||
884 | 883 | ||
885 | return 1; | 884 | return 1; |
886 | 885 | ||
diff --git a/drivers/net/pppol2tp.c b/drivers/net/pppol2tp.c index 266e8b38fe10..abe91cb595f4 100644 --- a/drivers/net/pppol2tp.c +++ b/drivers/net/pppol2tp.c | |||
@@ -491,44 +491,46 @@ static int pppol2tp_recv_core(struct sock *sock, struct sk_buff *skb) | |||
491 | u16 hdrflags; | 491 | u16 hdrflags; |
492 | u16 tunnel_id, session_id; | 492 | u16 tunnel_id, session_id; |
493 | int length; | 493 | int length; |
494 | struct udphdr *uh; | 494 | int offset; |
495 | 495 | ||
496 | tunnel = pppol2tp_sock_to_tunnel(sock); | 496 | tunnel = pppol2tp_sock_to_tunnel(sock); |
497 | if (tunnel == NULL) | 497 | if (tunnel == NULL) |
498 | goto error; | 498 | goto error; |
499 | 499 | ||
500 | /* UDP always verifies the packet length. */ | ||
501 | __skb_pull(skb, sizeof(struct udphdr)); | ||
502 | |||
500 | /* Short packet? */ | 503 | /* Short packet? */ |
501 | if (skb->len < sizeof(struct udphdr)) { | 504 | if (!pskb_may_pull(skb, 12)) { |
502 | PRINTK(tunnel->debug, PPPOL2TP_MSG_DATA, KERN_INFO, | 505 | PRINTK(tunnel->debug, PPPOL2TP_MSG_DATA, KERN_INFO, |
503 | "%s: recv short packet (len=%d)\n", tunnel->name, skb->len); | 506 | "%s: recv short packet (len=%d)\n", tunnel->name, skb->len); |
504 | goto error; | 507 | goto error; |
505 | } | 508 | } |
506 | 509 | ||
507 | /* Point to L2TP header */ | 510 | /* Point to L2TP header */ |
508 | ptr = skb->data + sizeof(struct udphdr); | 511 | ptr = skb->data; |
509 | 512 | ||
510 | /* Get L2TP header flags */ | 513 | /* Get L2TP header flags */ |
511 | hdrflags = ntohs(*(__be16*)ptr); | 514 | hdrflags = ntohs(*(__be16*)ptr); |
512 | 515 | ||
513 | /* Trace packet contents, if enabled */ | 516 | /* Trace packet contents, if enabled */ |
514 | if (tunnel->debug & PPPOL2TP_MSG_DATA) { | 517 | if (tunnel->debug & PPPOL2TP_MSG_DATA) { |
518 | length = min(16u, skb->len); | ||
519 | if (!pskb_may_pull(skb, length)) | ||
520 | goto error; | ||
521 | |||
515 | printk(KERN_DEBUG "%s: recv: ", tunnel->name); | 522 | printk(KERN_DEBUG "%s: recv: ", tunnel->name); |
516 | 523 | ||
517 | for (length = 0; length < 16; length++) | 524 | offset = 0; |
518 | printk(" %02X", ptr[length]); | 525 | do { |
526 | printk(" %02X", ptr[offset]); | ||
527 | } while (++offset < length); | ||
528 | |||
519 | printk("\n"); | 529 | printk("\n"); |
520 | } | 530 | } |
521 | 531 | ||
522 | /* Get length of L2TP packet */ | 532 | /* Get length of L2TP packet */ |
523 | uh = (struct udphdr *) skb_transport_header(skb); | 533 | length = skb->len; |
524 | length = ntohs(uh->len) - sizeof(struct udphdr); | ||
525 | |||
526 | /* Too short? */ | ||
527 | if (length < 12) { | ||
528 | PRINTK(tunnel->debug, PPPOL2TP_MSG_DATA, KERN_INFO, | ||
529 | "%s: recv short L2TP packet (len=%d)\n", tunnel->name, length); | ||
530 | goto error; | ||
531 | } | ||
532 | 534 | ||
533 | /* If type is control packet, it is handled by userspace. */ | 535 | /* If type is control packet, it is handled by userspace. */ |
534 | if (hdrflags & L2TP_HDRFLAG_T) { | 536 | if (hdrflags & L2TP_HDRFLAG_T) { |
@@ -606,7 +608,6 @@ static int pppol2tp_recv_core(struct sock *sock, struct sk_buff *skb) | |||
606 | "%s: recv data has no seq numbers when required. " | 608 | "%s: recv data has no seq numbers when required. " |
607 | "Discarding\n", session->name); | 609 | "Discarding\n", session->name); |
608 | session->stats.rx_seq_discards++; | 610 | session->stats.rx_seq_discards++; |
609 | session->stats.rx_errors++; | ||
610 | goto discard; | 611 | goto discard; |
611 | } | 612 | } |
612 | 613 | ||
@@ -625,7 +626,6 @@ static int pppol2tp_recv_core(struct sock *sock, struct sk_buff *skb) | |||
625 | "%s: recv data has no seq numbers when required. " | 626 | "%s: recv data has no seq numbers when required. " |
626 | "Discarding\n", session->name); | 627 | "Discarding\n", session->name); |
627 | session->stats.rx_seq_discards++; | 628 | session->stats.rx_seq_discards++; |
628 | session->stats.rx_errors++; | ||
629 | goto discard; | 629 | goto discard; |
630 | } | 630 | } |
631 | 631 | ||
@@ -634,10 +634,14 @@ static int pppol2tp_recv_core(struct sock *sock, struct sk_buff *skb) | |||
634 | } | 634 | } |
635 | 635 | ||
636 | /* If offset bit set, skip it. */ | 636 | /* If offset bit set, skip it. */ |
637 | if (hdrflags & L2TP_HDRFLAG_O) | 637 | if (hdrflags & L2TP_HDRFLAG_O) { |
638 | ptr += 2 + ntohs(*(__be16 *) ptr); | 638 | offset = ntohs(*(__be16 *)ptr); |
639 | skb->transport_header += 2 + offset; | ||
640 | if (!pskb_may_pull(skb, skb_transport_offset(skb) + 2)) | ||
641 | goto discard; | ||
642 | } | ||
639 | 643 | ||
640 | skb_pull(skb, ptr - skb->data); | 644 | __skb_pull(skb, skb_transport_offset(skb)); |
641 | 645 | ||
642 | /* Skip PPP header, if present. In testing, Microsoft L2TP clients | 646 | /* Skip PPP header, if present. In testing, Microsoft L2TP clients |
643 | * don't send the PPP header (PPP header compression enabled), but | 647 | * don't send the PPP header (PPP header compression enabled), but |
@@ -673,7 +677,6 @@ static int pppol2tp_recv_core(struct sock *sock, struct sk_buff *skb) | |||
673 | */ | 677 | */ |
674 | if (PPPOL2TP_SKB_CB(skb)->ns != session->nr) { | 678 | if (PPPOL2TP_SKB_CB(skb)->ns != session->nr) { |
675 | session->stats.rx_seq_discards++; | 679 | session->stats.rx_seq_discards++; |
676 | session->stats.rx_errors++; | ||
677 | PRINTK(session->debug, PPPOL2TP_MSG_SEQ, KERN_DEBUG, | 680 | PRINTK(session->debug, PPPOL2TP_MSG_SEQ, KERN_DEBUG, |
678 | "%s: oos pkt %hu len %d discarded, " | 681 | "%s: oos pkt %hu len %d discarded, " |
679 | "waiting for %hu, reorder_q_len=%d\n", | 682 | "waiting for %hu, reorder_q_len=%d\n", |
@@ -698,6 +701,7 @@ static int pppol2tp_recv_core(struct sock *sock, struct sk_buff *skb) | |||
698 | return 0; | 701 | return 0; |
699 | 702 | ||
700 | discard: | 703 | discard: |
704 | session->stats.rx_errors++; | ||
701 | kfree_skb(skb); | 705 | kfree_skb(skb); |
702 | sock_put(session->sock); | 706 | sock_put(session->sock); |
703 | 707 | ||
@@ -958,7 +962,6 @@ static int pppol2tp_xmit(struct ppp_channel *chan, struct sk_buff *skb) | |||
958 | int data_len = skb->len; | 962 | int data_len = skb->len; |
959 | struct inet_sock *inet; | 963 | struct inet_sock *inet; |
960 | __wsum csum = 0; | 964 | __wsum csum = 0; |
961 | struct sk_buff *skb2 = NULL; | ||
962 | struct udphdr *uh; | 965 | struct udphdr *uh; |
963 | unsigned int len; | 966 | unsigned int len; |
964 | 967 | ||
@@ -989,41 +992,30 @@ static int pppol2tp_xmit(struct ppp_channel *chan, struct sk_buff *skb) | |||
989 | */ | 992 | */ |
990 | headroom = NET_SKB_PAD + sizeof(struct iphdr) + | 993 | headroom = NET_SKB_PAD + sizeof(struct iphdr) + |
991 | sizeof(struct udphdr) + hdr_len + sizeof(ppph); | 994 | sizeof(struct udphdr) + hdr_len + sizeof(ppph); |
992 | if (skb_headroom(skb) < headroom) { | 995 | if (skb_cow_head(skb, headroom)) |
993 | skb2 = skb_realloc_headroom(skb, headroom); | 996 | goto abort; |
994 | if (skb2 == NULL) | ||
995 | goto abort; | ||
996 | } else | ||
997 | skb2 = skb; | ||
998 | |||
999 | /* Check that the socket has room */ | ||
1000 | if (atomic_read(&sk_tun->sk_wmem_alloc) < sk_tun->sk_sndbuf) | ||
1001 | skb_set_owner_w(skb2, sk_tun); | ||
1002 | else | ||
1003 | goto discard; | ||
1004 | 997 | ||
1005 | /* Setup PPP header */ | 998 | /* Setup PPP header */ |
1006 | skb_push(skb2, sizeof(ppph)); | 999 | __skb_push(skb, sizeof(ppph)); |
1007 | skb2->data[0] = ppph[0]; | 1000 | skb->data[0] = ppph[0]; |
1008 | skb2->data[1] = ppph[1]; | 1001 | skb->data[1] = ppph[1]; |
1009 | 1002 | ||
1010 | /* Setup L2TP header */ | 1003 | /* Setup L2TP header */ |
1011 | skb_push(skb2, hdr_len); | 1004 | pppol2tp_build_l2tp_header(session, __skb_push(skb, hdr_len)); |
1012 | pppol2tp_build_l2tp_header(session, skb2->data); | ||
1013 | 1005 | ||
1014 | /* Setup UDP header */ | 1006 | /* Setup UDP header */ |
1015 | inet = inet_sk(sk_tun); | 1007 | inet = inet_sk(sk_tun); |
1016 | skb_push(skb2, sizeof(struct udphdr)); | 1008 | __skb_push(skb, sizeof(*uh)); |
1017 | skb_reset_transport_header(skb2); | 1009 | skb_reset_transport_header(skb); |
1018 | uh = (struct udphdr *) skb2->data; | 1010 | uh = udp_hdr(skb); |
1019 | uh->source = inet->sport; | 1011 | uh->source = inet->sport; |
1020 | uh->dest = inet->dport; | 1012 | uh->dest = inet->dport; |
1021 | uh->len = htons(sizeof(struct udphdr) + hdr_len + sizeof(ppph) + data_len); | 1013 | uh->len = htons(sizeof(struct udphdr) + hdr_len + sizeof(ppph) + data_len); |
1022 | uh->check = 0; | 1014 | uh->check = 0; |
1023 | 1015 | ||
1024 | /* Calculate UDP checksum if configured to do so */ | 1016 | /* *BROKEN* Calculate UDP checksum if configured to do so */ |
1025 | if (sk_tun->sk_no_check != UDP_CSUM_NOXMIT) | 1017 | if (sk_tun->sk_no_check != UDP_CSUM_NOXMIT) |
1026 | csum = udp_csum_outgoing(sk_tun, skb2); | 1018 | csum = udp_csum_outgoing(sk_tun, skb); |
1027 | 1019 | ||
1028 | /* Debug */ | 1020 | /* Debug */ |
1029 | if (session->send_seq) | 1021 | if (session->send_seq) |
@@ -1036,7 +1028,7 @@ static int pppol2tp_xmit(struct ppp_channel *chan, struct sk_buff *skb) | |||
1036 | 1028 | ||
1037 | if (session->debug & PPPOL2TP_MSG_DATA) { | 1029 | if (session->debug & PPPOL2TP_MSG_DATA) { |
1038 | int i; | 1030 | int i; |
1039 | unsigned char *datap = skb2->data; | 1031 | unsigned char *datap = skb->data; |
1040 | 1032 | ||
1041 | printk(KERN_DEBUG "%s: xmit:", session->name); | 1033 | printk(KERN_DEBUG "%s: xmit:", session->name); |
1042 | for (i = 0; i < data_len; i++) { | 1034 | for (i = 0; i < data_len; i++) { |
@@ -1049,18 +1041,18 @@ static int pppol2tp_xmit(struct ppp_channel *chan, struct sk_buff *skb) | |||
1049 | printk("\n"); | 1041 | printk("\n"); |
1050 | } | 1042 | } |
1051 | 1043 | ||
1052 | memset(&(IPCB(skb2)->opt), 0, sizeof(IPCB(skb2)->opt)); | 1044 | memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt)); |
1053 | IPCB(skb2)->flags &= ~(IPSKB_XFRM_TUNNEL_SIZE | IPSKB_XFRM_TRANSFORMED | | 1045 | IPCB(skb)->flags &= ~(IPSKB_XFRM_TUNNEL_SIZE | IPSKB_XFRM_TRANSFORMED | |
1054 | IPSKB_REROUTED); | 1046 | IPSKB_REROUTED); |
1055 | nf_reset(skb2); | 1047 | nf_reset(skb); |
1056 | 1048 | ||
1057 | /* Get routing info from the tunnel socket */ | 1049 | /* Get routing info from the tunnel socket */ |
1058 | dst_release(skb2->dst); | 1050 | dst_release(skb->dst); |
1059 | skb2->dst = sk_dst_get(sk_tun); | 1051 | skb->dst = sk_dst_get(sk_tun); |
1060 | 1052 | ||
1061 | /* Queue the packet to IP for output */ | 1053 | /* Queue the packet to IP for output */ |
1062 | len = skb2->len; | 1054 | len = skb->len; |
1063 | rc = ip_queue_xmit(skb2, 1); | 1055 | rc = ip_queue_xmit(skb, 1); |
1064 | 1056 | ||
1065 | /* Update stats */ | 1057 | /* Update stats */ |
1066 | if (rc >= 0) { | 1058 | if (rc >= 0) { |
@@ -1073,17 +1065,12 @@ static int pppol2tp_xmit(struct ppp_channel *chan, struct sk_buff *skb) | |||
1073 | session->stats.tx_errors++; | 1065 | session->stats.tx_errors++; |
1074 | } | 1066 | } |
1075 | 1067 | ||
1076 | /* Free the original skb */ | ||
1077 | kfree_skb(skb); | ||
1078 | |||
1079 | return 1; | 1068 | return 1; |
1080 | 1069 | ||
1081 | discard: | ||
1082 | /* Free the new skb. Caller will free original skb. */ | ||
1083 | if (skb2 != skb) | ||
1084 | kfree_skb(skb2); | ||
1085 | abort: | 1070 | abort: |
1086 | return 0; | 1071 | /* Free the original skb */ |
1072 | kfree_skb(skb); | ||
1073 | return 1; | ||
1087 | } | 1074 | } |
1088 | 1075 | ||
1089 | /***************************************************************************** | 1076 | /***************************************************************************** |
@@ -1326,12 +1313,14 @@ static struct sock *pppol2tp_prepare_tunnel_socket(int fd, u16 tunnel_id, | |||
1326 | goto err; | 1313 | goto err; |
1327 | } | 1314 | } |
1328 | 1315 | ||
1316 | sk = sock->sk; | ||
1317 | |||
1329 | /* Quick sanity checks */ | 1318 | /* Quick sanity checks */ |
1330 | err = -ESOCKTNOSUPPORT; | 1319 | err = -EPROTONOSUPPORT; |
1331 | if (sock->type != SOCK_DGRAM) { | 1320 | if (sk->sk_protocol != IPPROTO_UDP) { |
1332 | PRINTK(-1, PPPOL2TP_MSG_CONTROL, KERN_ERR, | 1321 | PRINTK(-1, PPPOL2TP_MSG_CONTROL, KERN_ERR, |
1333 | "tunl %hu: fd %d wrong type, got %d, expected %d\n", | 1322 | "tunl %hu: fd %d wrong protocol, got %d, expected %d\n", |
1334 | tunnel_id, fd, sock->type, SOCK_DGRAM); | 1323 | tunnel_id, fd, sk->sk_protocol, IPPROTO_UDP); |
1335 | goto err; | 1324 | goto err; |
1336 | } | 1325 | } |
1337 | err = -EAFNOSUPPORT; | 1326 | err = -EAFNOSUPPORT; |
@@ -1343,7 +1332,6 @@ static struct sock *pppol2tp_prepare_tunnel_socket(int fd, u16 tunnel_id, | |||
1343 | } | 1332 | } |
1344 | 1333 | ||
1345 | err = -ENOTCONN; | 1334 | err = -ENOTCONN; |
1346 | sk = sock->sk; | ||
1347 | 1335 | ||
1348 | /* Check if this socket has already been prepped */ | 1336 | /* Check if this socket has already been prepped */ |
1349 | tunnel = (struct pppol2tp_tunnel *)sk->sk_user_data; | 1337 | tunnel = (struct pppol2tp_tunnel *)sk->sk_user_data; |
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index 5d812de65d90..eaffe551d1d8 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c | |||
@@ -51,7 +51,7 @@ | |||
51 | #include "sky2.h" | 51 | #include "sky2.h" |
52 | 52 | ||
53 | #define DRV_NAME "sky2" | 53 | #define DRV_NAME "sky2" |
54 | #define DRV_VERSION "1.17" | 54 | #define DRV_VERSION "1.18" |
55 | #define PFX DRV_NAME " " | 55 | #define PFX DRV_NAME " " |
56 | 56 | ||
57 | /* | 57 | /* |
@@ -118,12 +118,15 @@ static const struct pci_device_id sky2_id_table[] = { | |||
118 | { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4351) }, /* 88E8036 */ | 118 | { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4351) }, /* 88E8036 */ |
119 | { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4352) }, /* 88E8038 */ | 119 | { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4352) }, /* 88E8038 */ |
120 | { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4353) }, /* 88E8039 */ | 120 | { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4353) }, /* 88E8039 */ |
121 | { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4354) }, /* 88E8040 */ | ||
121 | { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4356) }, /* 88EC033 */ | 122 | { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4356) }, /* 88EC033 */ |
123 | { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x435A) }, /* 88E8048 */ | ||
122 | { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4360) }, /* 88E8052 */ | 124 | { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4360) }, /* 88E8052 */ |
123 | { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4361) }, /* 88E8050 */ | 125 | { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4361) }, /* 88E8050 */ |
124 | { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4362) }, /* 88E8053 */ | 126 | { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4362) }, /* 88E8053 */ |
125 | { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4363) }, /* 88E8055 */ | 127 | { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4363) }, /* 88E8055 */ |
126 | { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4364) }, /* 88E8056 */ | 128 | { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4364) }, /* 88E8056 */ |
129 | { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4365) }, /* 88E8070 */ | ||
127 | { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4366) }, /* 88EC036 */ | 130 | { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4366) }, /* 88EC036 */ |
128 | { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4367) }, /* 88EC032 */ | 131 | { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4367) }, /* 88EC032 */ |
129 | { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4368) }, /* 88EC034 */ | 132 | { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4368) }, /* 88EC034 */ |
@@ -147,6 +150,7 @@ static const char *yukon2_name[] = { | |||
147 | "Extreme", /* 0xb5 */ | 150 | "Extreme", /* 0xb5 */ |
148 | "EC", /* 0xb6 */ | 151 | "EC", /* 0xb6 */ |
149 | "FE", /* 0xb7 */ | 152 | "FE", /* 0xb7 */ |
153 | "FE+", /* 0xb8 */ | ||
150 | }; | 154 | }; |
151 | 155 | ||
152 | static void sky2_set_multicast(struct net_device *dev); | 156 | static void sky2_set_multicast(struct net_device *dev); |
@@ -217,8 +221,7 @@ static void sky2_power_on(struct sky2_hw *hw) | |||
217 | else | 221 | else |
218 | sky2_write8(hw, B2_Y2_CLK_GATE, 0); | 222 | sky2_write8(hw, B2_Y2_CLK_GATE, 0); |
219 | 223 | ||
220 | if (hw->chip_id == CHIP_ID_YUKON_EC_U || | 224 | if (hw->flags & SKY2_HW_ADV_POWER_CTL) { |
221 | hw->chip_id == CHIP_ID_YUKON_EX) { | ||
222 | u32 reg; | 225 | u32 reg; |
223 | 226 | ||
224 | sky2_pci_write32(hw, PCI_DEV_REG3, 0); | 227 | sky2_pci_write32(hw, PCI_DEV_REG3, 0); |
@@ -311,10 +314,8 @@ static void sky2_phy_init(struct sky2_hw *hw, unsigned port) | |||
311 | struct sky2_port *sky2 = netdev_priv(hw->dev[port]); | 314 | struct sky2_port *sky2 = netdev_priv(hw->dev[port]); |
312 | u16 ctrl, ct1000, adv, pg, ledctrl, ledover, reg; | 315 | u16 ctrl, ct1000, adv, pg, ledctrl, ledover, reg; |
313 | 316 | ||
314 | if (sky2->autoneg == AUTONEG_ENABLE | 317 | if (sky2->autoneg == AUTONEG_ENABLE && |
315 | && !(hw->chip_id == CHIP_ID_YUKON_XL | 318 | !(hw->flags & SKY2_HW_NEWER_PHY)) { |
316 | || hw->chip_id == CHIP_ID_YUKON_EC_U | ||
317 | || hw->chip_id == CHIP_ID_YUKON_EX)) { | ||
318 | u16 ectrl = gm_phy_read(hw, port, PHY_MARV_EXT_CTRL); | 319 | u16 ectrl = gm_phy_read(hw, port, PHY_MARV_EXT_CTRL); |
319 | 320 | ||
320 | ectrl &= ~(PHY_M_EC_M_DSC_MSK | PHY_M_EC_S_DSC_MSK | | 321 | ectrl &= ~(PHY_M_EC_M_DSC_MSK | PHY_M_EC_S_DSC_MSK | |
@@ -334,7 +335,7 @@ static void sky2_phy_init(struct sky2_hw *hw, unsigned port) | |||
334 | 335 | ||
335 | ctrl = gm_phy_read(hw, port, PHY_MARV_PHY_CTRL); | 336 | ctrl = gm_phy_read(hw, port, PHY_MARV_PHY_CTRL); |
336 | if (sky2_is_copper(hw)) { | 337 | if (sky2_is_copper(hw)) { |
337 | if (hw->chip_id == CHIP_ID_YUKON_FE) { | 338 | if (!(hw->flags & SKY2_HW_GIGABIT)) { |
338 | /* enable automatic crossover */ | 339 | /* enable automatic crossover */ |
339 | ctrl |= PHY_M_PC_MDI_XMODE(PHY_M_PC_ENA_AUTO) >> 1; | 340 | ctrl |= PHY_M_PC_MDI_XMODE(PHY_M_PC_ENA_AUTO) >> 1; |
340 | } else { | 341 | } else { |
@@ -346,9 +347,7 @@ static void sky2_phy_init(struct sky2_hw *hw, unsigned port) | |||
346 | 347 | ||
347 | /* downshift on PHY 88E1112 and 88E1149 is changed */ | 348 | /* downshift on PHY 88E1112 and 88E1149 is changed */ |
348 | if (sky2->autoneg == AUTONEG_ENABLE | 349 | if (sky2->autoneg == AUTONEG_ENABLE |
349 | && (hw->chip_id == CHIP_ID_YUKON_XL | 350 | && (hw->flags & SKY2_HW_NEWER_PHY)) { |
350 | || hw->chip_id == CHIP_ID_YUKON_EC_U | ||
351 | || hw->chip_id == CHIP_ID_YUKON_EX)) { | ||
352 | /* set downshift counter to 3x and enable downshift */ | 351 | /* set downshift counter to 3x and enable downshift */ |
353 | ctrl &= ~PHY_M_PC_DSC_MSK; | 352 | ctrl &= ~PHY_M_PC_DSC_MSK; |
354 | ctrl |= PHY_M_PC_DSC(2) | PHY_M_PC_DOWN_S_ENA; | 353 | ctrl |= PHY_M_PC_DSC(2) | PHY_M_PC_DOWN_S_ENA; |
@@ -364,7 +363,7 @@ static void sky2_phy_init(struct sky2_hw *hw, unsigned port) | |||
364 | gm_phy_write(hw, port, PHY_MARV_PHY_CTRL, ctrl); | 363 | gm_phy_write(hw, port, PHY_MARV_PHY_CTRL, ctrl); |
365 | 364 | ||
366 | /* special setup for PHY 88E1112 Fiber */ | 365 | /* special setup for PHY 88E1112 Fiber */ |
367 | if (hw->chip_id == CHIP_ID_YUKON_XL && !sky2_is_copper(hw)) { | 366 | if (hw->chip_id == CHIP_ID_YUKON_XL && (hw->flags & SKY2_HW_FIBRE_PHY)) { |
368 | pg = gm_phy_read(hw, port, PHY_MARV_EXT_ADR); | 367 | pg = gm_phy_read(hw, port, PHY_MARV_EXT_ADR); |
369 | 368 | ||
370 | /* Fiber: select 1000BASE-X only mode MAC Specific Ctrl Reg. */ | 369 | /* Fiber: select 1000BASE-X only mode MAC Specific Ctrl Reg. */ |
@@ -455,7 +454,7 @@ static void sky2_phy_init(struct sky2_hw *hw, unsigned port) | |||
455 | 454 | ||
456 | gma_write16(hw, port, GM_GP_CTRL, reg); | 455 | gma_write16(hw, port, GM_GP_CTRL, reg); |
457 | 456 | ||
458 | if (hw->chip_id != CHIP_ID_YUKON_FE) | 457 | if (hw->flags & SKY2_HW_GIGABIT) |
459 | gm_phy_write(hw, port, PHY_MARV_1000T_CTRL, ct1000); | 458 | gm_phy_write(hw, port, PHY_MARV_1000T_CTRL, ct1000); |
460 | 459 | ||
461 | gm_phy_write(hw, port, PHY_MARV_AUNE_ADV, adv); | 460 | gm_phy_write(hw, port, PHY_MARV_AUNE_ADV, adv); |
@@ -479,6 +478,23 @@ static void sky2_phy_init(struct sky2_hw *hw, unsigned port) | |||
479 | gm_phy_write(hw, port, PHY_MARV_FE_LED_PAR, ctrl); | 478 | gm_phy_write(hw, port, PHY_MARV_FE_LED_PAR, ctrl); |
480 | break; | 479 | break; |
481 | 480 | ||
481 | case CHIP_ID_YUKON_FE_P: | ||
482 | /* Enable Link Partner Next Page */ | ||
483 | ctrl = gm_phy_read(hw, port, PHY_MARV_PHY_CTRL); | ||
484 | ctrl |= PHY_M_PC_ENA_LIP_NP; | ||
485 | |||
486 | /* disable Energy Detect and enable scrambler */ | ||
487 | ctrl &= ~(PHY_M_PC_ENA_ENE_DT | PHY_M_PC_DIS_SCRAMB); | ||
488 | gm_phy_write(hw, port, PHY_MARV_PHY_CTRL, ctrl); | ||
489 | |||
490 | /* set LED2 -> ACT, LED1 -> LINK, LED0 -> SPEED */ | ||
491 | ctrl = PHY_M_FELP_LED2_CTRL(LED_PAR_CTRL_ACT_BL) | | ||
492 | PHY_M_FELP_LED1_CTRL(LED_PAR_CTRL_LINK) | | ||
493 | PHY_M_FELP_LED0_CTRL(LED_PAR_CTRL_SPEED); | ||
494 | |||
495 | gm_phy_write(hw, port, PHY_MARV_FE_LED_PAR, ctrl); | ||
496 | break; | ||
497 | |||
482 | case CHIP_ID_YUKON_XL: | 498 | case CHIP_ID_YUKON_XL: |
483 | pg = gm_phy_read(hw, port, PHY_MARV_EXT_ADR); | 499 | pg = gm_phy_read(hw, port, PHY_MARV_EXT_ADR); |
484 | 500 | ||
@@ -548,7 +564,13 @@ static void sky2_phy_init(struct sky2_hw *hw, unsigned port) | |||
548 | 564 | ||
549 | /* set page register to 0 */ | 565 | /* set page register to 0 */ |
550 | gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 0); | 566 | gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 0); |
567 | } else if (hw->chip_id == CHIP_ID_YUKON_FE_P && | ||
568 | hw->chip_rev == CHIP_REV_YU_FE2_A0) { | ||
569 | /* apply workaround for integrated resistors calibration */ | ||
570 | gm_phy_write(hw, port, PHY_MARV_PAGE_ADDR, 17); | ||
571 | gm_phy_write(hw, port, PHY_MARV_PAGE_DATA, 0x3f60); | ||
551 | } else if (hw->chip_id != CHIP_ID_YUKON_EX) { | 572 | } else if (hw->chip_id != CHIP_ID_YUKON_EX) { |
573 | /* no effect on Yukon-XL */ | ||
552 | gm_phy_write(hw, port, PHY_MARV_LED_CTRL, ledctrl); | 574 | gm_phy_write(hw, port, PHY_MARV_LED_CTRL, ledctrl); |
553 | 575 | ||
554 | if (sky2->autoneg == AUTONEG_DISABLE || sky2->speed == SPEED_100) { | 576 | if (sky2->autoneg == AUTONEG_DISABLE || sky2->speed == SPEED_100) { |
@@ -669,25 +691,25 @@ static void sky2_wol_init(struct sky2_port *sky2) | |||
669 | 691 | ||
670 | static void sky2_set_tx_stfwd(struct sky2_hw *hw, unsigned port) | 692 | static void sky2_set_tx_stfwd(struct sky2_hw *hw, unsigned port) |
671 | { | 693 | { |
672 | if (hw->chip_id == CHIP_ID_YUKON_EX && hw->chip_rev != CHIP_REV_YU_EX_A0) { | 694 | struct net_device *dev = hw->dev[port]; |
695 | |||
696 | if (dev->mtu <= ETH_DATA_LEN) | ||
673 | sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T), | 697 | sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T), |
674 | TX_STFW_ENA | | 698 | TX_JUMBO_DIS | TX_STFW_ENA); |
675 | (hw->dev[port]->mtu > ETH_DATA_LEN) ? TX_JUMBO_ENA : TX_JUMBO_DIS); | ||
676 | } else { | ||
677 | if (hw->dev[port]->mtu > ETH_DATA_LEN) { | ||
678 | /* set Tx GMAC FIFO Almost Empty Threshold */ | ||
679 | sky2_write32(hw, SK_REG(port, TX_GMF_AE_THR), | ||
680 | (ECU_JUMBO_WM << 16) | ECU_AE_THR); | ||
681 | 699 | ||
682 | sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T), | 700 | else if (hw->chip_id != CHIP_ID_YUKON_EC_U) |
683 | TX_JUMBO_ENA | TX_STFW_DIS); | 701 | sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T), |
702 | TX_STFW_ENA | TX_JUMBO_ENA); | ||
703 | else { | ||
704 | /* set Tx GMAC FIFO Almost Empty Threshold */ | ||
705 | sky2_write32(hw, SK_REG(port, TX_GMF_AE_THR), | ||
706 | (ECU_JUMBO_WM << 16) | ECU_AE_THR); | ||
684 | 707 | ||
685 | /* Can't do offload because of lack of store/forward */ | 708 | sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T), |
686 | hw->dev[port]->features &= ~(NETIF_F_TSO | NETIF_F_SG | 709 | TX_JUMBO_ENA | TX_STFW_DIS); |
687 | | NETIF_F_ALL_CSUM); | 710 | |
688 | } else | 711 | /* Can't do offload because of lack of store/forward */ |
689 | sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T), | 712 | dev->features &= ~(NETIF_F_TSO | NETIF_F_SG | NETIF_F_ALL_CSUM); |
690 | TX_JUMBO_DIS | TX_STFW_ENA); | ||
691 | } | 713 | } |
692 | } | 714 | } |
693 | 715 | ||
@@ -773,7 +795,8 @@ static void sky2_mac_init(struct sky2_hw *hw, unsigned port) | |||
773 | /* Configure Rx MAC FIFO */ | 795 | /* Configure Rx MAC FIFO */ |
774 | sky2_write8(hw, SK_REG(port, RX_GMF_CTRL_T), GMF_RST_CLR); | 796 | sky2_write8(hw, SK_REG(port, RX_GMF_CTRL_T), GMF_RST_CLR); |
775 | rx_reg = GMF_OPER_ON | GMF_RX_F_FL_ON; | 797 | rx_reg = GMF_OPER_ON | GMF_RX_F_FL_ON; |
776 | if (hw->chip_id == CHIP_ID_YUKON_EX) | 798 | if (hw->chip_id == CHIP_ID_YUKON_EX || |
799 | hw->chip_id == CHIP_ID_YUKON_FE_P) | ||
777 | rx_reg |= GMF_RX_OVER_ON; | 800 | rx_reg |= GMF_RX_OVER_ON; |
778 | 801 | ||
779 | sky2_write32(hw, SK_REG(port, RX_GMF_CTRL_T), rx_reg); | 802 | sky2_write32(hw, SK_REG(port, RX_GMF_CTRL_T), rx_reg); |
@@ -782,13 +805,18 @@ static void sky2_mac_init(struct sky2_hw *hw, unsigned port) | |||
782 | sky2_write16(hw, SK_REG(port, RX_GMF_FL_MSK), GMR_FS_ANY_ERR); | 805 | sky2_write16(hw, SK_REG(port, RX_GMF_FL_MSK), GMR_FS_ANY_ERR); |
783 | 806 | ||
784 | /* Set threshold to 0xa (64 bytes) + 1 to workaround pause bug */ | 807 | /* Set threshold to 0xa (64 bytes) + 1 to workaround pause bug */ |
785 | sky2_write16(hw, SK_REG(port, RX_GMF_FL_THR), RX_GMF_FL_THR_DEF+1); | 808 | reg = RX_GMF_FL_THR_DEF + 1; |
809 | /* Another magic mystery workaround from sk98lin */ | ||
810 | if (hw->chip_id == CHIP_ID_YUKON_FE_P && | ||
811 | hw->chip_rev == CHIP_REV_YU_FE2_A0) | ||
812 | reg = 0x178; | ||
813 | sky2_write16(hw, SK_REG(port, RX_GMF_FL_THR), reg); | ||
786 | 814 | ||
787 | /* Configure Tx MAC FIFO */ | 815 | /* Configure Tx MAC FIFO */ |
788 | sky2_write8(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_RST_CLR); | 816 | sky2_write8(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_RST_CLR); |
789 | sky2_write16(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_OPER_ON); | 817 | sky2_write16(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_OPER_ON); |
790 | 818 | ||
791 | if (hw->chip_id == CHIP_ID_YUKON_EC_U || hw->chip_id == CHIP_ID_YUKON_EX) { | 819 | if (!(hw->flags & SKY2_HW_RAMBUFFER)) { |
792 | sky2_write8(hw, SK_REG(port, RX_GMF_LP_THR), 768/8); | 820 | sky2_write8(hw, SK_REG(port, RX_GMF_LP_THR), 768/8); |
793 | sky2_write8(hw, SK_REG(port, RX_GMF_UP_THR), 1024/8); | 821 | sky2_write8(hw, SK_REG(port, RX_GMF_UP_THR), 1024/8); |
794 | 822 | ||
@@ -967,19 +995,15 @@ static void sky2_rx_unmap_skb(struct pci_dev *pdev, struct rx_ring_info *re) | |||
967 | */ | 995 | */ |
968 | static void rx_set_checksum(struct sky2_port *sky2) | 996 | static void rx_set_checksum(struct sky2_port *sky2) |
969 | { | 997 | { |
970 | struct sky2_rx_le *le; | 998 | struct sky2_rx_le *le = sky2_next_rx(sky2); |
971 | 999 | ||
972 | if (sky2->hw->chip_id != CHIP_ID_YUKON_EX) { | 1000 | le->addr = cpu_to_le32((ETH_HLEN << 16) | ETH_HLEN); |
973 | le = sky2_next_rx(sky2); | 1001 | le->ctrl = 0; |
974 | le->addr = cpu_to_le32((ETH_HLEN << 16) | ETH_HLEN); | 1002 | le->opcode = OP_TCPSTART | HW_OWNER; |
975 | le->ctrl = 0; | ||
976 | le->opcode = OP_TCPSTART | HW_OWNER; | ||
977 | |||
978 | sky2_write32(sky2->hw, | ||
979 | Q_ADDR(rxqaddr[sky2->port], Q_CSR), | ||
980 | sky2->rx_csum ? BMU_ENA_RX_CHKSUM : BMU_DIS_RX_CHKSUM); | ||
981 | } | ||
982 | 1003 | ||
1004 | sky2_write32(sky2->hw, | ||
1005 | Q_ADDR(rxqaddr[sky2->port], Q_CSR), | ||
1006 | sky2->rx_csum ? BMU_ENA_RX_CHKSUM : BMU_DIS_RX_CHKSUM); | ||
983 | } | 1007 | } |
984 | 1008 | ||
985 | /* | 1009 | /* |
@@ -1175,7 +1199,8 @@ static int sky2_rx_start(struct sky2_port *sky2) | |||
1175 | 1199 | ||
1176 | sky2_prefetch_init(hw, rxq, sky2->rx_le_map, RX_LE_SIZE - 1); | 1200 | sky2_prefetch_init(hw, rxq, sky2->rx_le_map, RX_LE_SIZE - 1); |
1177 | 1201 | ||
1178 | rx_set_checksum(sky2); | 1202 | if (!(hw->flags & SKY2_HW_NEW_LE)) |
1203 | rx_set_checksum(sky2); | ||
1179 | 1204 | ||
1180 | /* Space needed for frame data + headers rounded up */ | 1205 | /* Space needed for frame data + headers rounded up */ |
1181 | size = roundup(sky2->netdev->mtu + ETH_HLEN + VLAN_HLEN, 8); | 1206 | size = roundup(sky2->netdev->mtu + ETH_HLEN + VLAN_HLEN, 8); |
@@ -1246,7 +1271,7 @@ static int sky2_up(struct net_device *dev) | |||
1246 | struct sky2_port *sky2 = netdev_priv(dev); | 1271 | struct sky2_port *sky2 = netdev_priv(dev); |
1247 | struct sky2_hw *hw = sky2->hw; | 1272 | struct sky2_hw *hw = sky2->hw; |
1248 | unsigned port = sky2->port; | 1273 | unsigned port = sky2->port; |
1249 | u32 ramsize, imask; | 1274 | u32 imask; |
1250 | int cap, err = -ENOMEM; | 1275 | int cap, err = -ENOMEM; |
1251 | struct net_device *otherdev = hw->dev[sky2->port^1]; | 1276 | struct net_device *otherdev = hw->dev[sky2->port^1]; |
1252 | 1277 | ||
@@ -1301,13 +1326,13 @@ static int sky2_up(struct net_device *dev) | |||
1301 | 1326 | ||
1302 | sky2_mac_init(hw, port); | 1327 | sky2_mac_init(hw, port); |
1303 | 1328 | ||
1304 | /* Register is number of 4K blocks on internal RAM buffer. */ | 1329 | if (hw->flags & SKY2_HW_RAMBUFFER) { |
1305 | ramsize = sky2_read8(hw, B2_E_0) * 4; | 1330 | /* Register is number of 4K blocks on internal RAM buffer. */ |
1306 | printk(KERN_INFO PFX "%s: ram buffer %dK\n", dev->name, ramsize); | 1331 | u32 ramsize = sky2_read8(hw, B2_E_0) * 4; |
1307 | |||
1308 | if (ramsize > 0) { | ||
1309 | u32 rxspace; | 1332 | u32 rxspace; |
1310 | 1333 | ||
1334 | printk(KERN_DEBUG PFX "%s: ram buffer %dK\n", dev->name, ramsize); | ||
1335 | |||
1311 | if (ramsize < 16) | 1336 | if (ramsize < 16) |
1312 | rxspace = ramsize / 2; | 1337 | rxspace = ramsize / 2; |
1313 | else | 1338 | else |
@@ -1436,13 +1461,15 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev) | |||
1436 | /* Check for TCP Segmentation Offload */ | 1461 | /* Check for TCP Segmentation Offload */ |
1437 | mss = skb_shinfo(skb)->gso_size; | 1462 | mss = skb_shinfo(skb)->gso_size; |
1438 | if (mss != 0) { | 1463 | if (mss != 0) { |
1439 | if (hw->chip_id != CHIP_ID_YUKON_EX) | 1464 | |
1465 | if (!(hw->flags & SKY2_HW_NEW_LE)) | ||
1440 | mss += ETH_HLEN + ip_hdrlen(skb) + tcp_hdrlen(skb); | 1466 | mss += ETH_HLEN + ip_hdrlen(skb) + tcp_hdrlen(skb); |
1441 | 1467 | ||
1442 | if (mss != sky2->tx_last_mss) { | 1468 | if (mss != sky2->tx_last_mss) { |
1443 | le = get_tx_le(sky2); | 1469 | le = get_tx_le(sky2); |
1444 | le->addr = cpu_to_le32(mss); | 1470 | le->addr = cpu_to_le32(mss); |
1445 | if (hw->chip_id == CHIP_ID_YUKON_EX) | 1471 | |
1472 | if (hw->flags & SKY2_HW_NEW_LE) | ||
1446 | le->opcode = OP_MSS | HW_OWNER; | 1473 | le->opcode = OP_MSS | HW_OWNER; |
1447 | else | 1474 | else |
1448 | le->opcode = OP_LRGLEN | HW_OWNER; | 1475 | le->opcode = OP_LRGLEN | HW_OWNER; |
@@ -1468,8 +1495,7 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev) | |||
1468 | /* Handle TCP checksum offload */ | 1495 | /* Handle TCP checksum offload */ |
1469 | if (skb->ip_summed == CHECKSUM_PARTIAL) { | 1496 | if (skb->ip_summed == CHECKSUM_PARTIAL) { |
1470 | /* On Yukon EX (some versions) encoding change. */ | 1497 | /* On Yukon EX (some versions) encoding change. */ |
1471 | if (hw->chip_id == CHIP_ID_YUKON_EX | 1498 | if (hw->flags & SKY2_HW_AUTO_TX_SUM) |
1472 | && hw->chip_rev != CHIP_REV_YU_EX_B0) | ||
1473 | ctrl |= CALSUM; /* auto checksum */ | 1499 | ctrl |= CALSUM; /* auto checksum */ |
1474 | else { | 1500 | else { |
1475 | const unsigned offset = skb_transport_offset(skb); | 1501 | const unsigned offset = skb_transport_offset(skb); |
@@ -1622,9 +1648,6 @@ static int sky2_down(struct net_device *dev) | |||
1622 | if (netif_msg_ifdown(sky2)) | 1648 | if (netif_msg_ifdown(sky2)) |
1623 | printk(KERN_INFO PFX "%s: disabling interface\n", dev->name); | 1649 | printk(KERN_INFO PFX "%s: disabling interface\n", dev->name); |
1624 | 1650 | ||
1625 | if (netif_carrier_ok(dev) && --hw->active == 0) | ||
1626 | del_timer(&hw->watchdog_timer); | ||
1627 | |||
1628 | /* Stop more packets from being queued */ | 1651 | /* Stop more packets from being queued */ |
1629 | netif_stop_queue(dev); | 1652 | netif_stop_queue(dev); |
1630 | 1653 | ||
@@ -1708,11 +1731,15 @@ static int sky2_down(struct net_device *dev) | |||
1708 | 1731 | ||
1709 | static u16 sky2_phy_speed(const struct sky2_hw *hw, u16 aux) | 1732 | static u16 sky2_phy_speed(const struct sky2_hw *hw, u16 aux) |
1710 | { | 1733 | { |
1711 | if (!sky2_is_copper(hw)) | 1734 | if (hw->flags & SKY2_HW_FIBRE_PHY) |
1712 | return SPEED_1000; | 1735 | return SPEED_1000; |
1713 | 1736 | ||
1714 | if (hw->chip_id == CHIP_ID_YUKON_FE) | 1737 | if (!(hw->flags & SKY2_HW_GIGABIT)) { |
1715 | return (aux & PHY_M_PS_SPEED_100) ? SPEED_100 : SPEED_10; | 1738 | if (aux & PHY_M_PS_SPEED_100) |
1739 | return SPEED_100; | ||
1740 | else | ||
1741 | return SPEED_10; | ||
1742 | } | ||
1716 | 1743 | ||
1717 | switch (aux & PHY_M_PS_SPEED_MSK) { | 1744 | switch (aux & PHY_M_PS_SPEED_MSK) { |
1718 | case PHY_M_PS_SPEED_1000: | 1745 | case PHY_M_PS_SPEED_1000: |
@@ -1745,17 +1772,13 @@ static void sky2_link_up(struct sky2_port *sky2) | |||
1745 | 1772 | ||
1746 | netif_carrier_on(sky2->netdev); | 1773 | netif_carrier_on(sky2->netdev); |
1747 | 1774 | ||
1748 | if (hw->active++ == 0) | 1775 | mod_timer(&hw->watchdog_timer, jiffies + 1); |
1749 | mod_timer(&hw->watchdog_timer, jiffies + 1); | ||
1750 | |||
1751 | 1776 | ||
1752 | /* Turn on link LED */ | 1777 | /* Turn on link LED */ |
1753 | sky2_write8(hw, SK_REG(port, LNK_LED_REG), | 1778 | sky2_write8(hw, SK_REG(port, LNK_LED_REG), |
1754 | LINKLED_ON | LINKLED_BLINK_OFF | LINKLED_LINKSYNC_OFF); | 1779 | LINKLED_ON | LINKLED_BLINK_OFF | LINKLED_LINKSYNC_OFF); |
1755 | 1780 | ||
1756 | if (hw->chip_id == CHIP_ID_YUKON_XL | 1781 | if (hw->flags & SKY2_HW_NEWER_PHY) { |
1757 | || hw->chip_id == CHIP_ID_YUKON_EC_U | ||
1758 | || hw->chip_id == CHIP_ID_YUKON_EX) { | ||
1759 | u16 pg = gm_phy_read(hw, port, PHY_MARV_EXT_ADR); | 1782 | u16 pg = gm_phy_read(hw, port, PHY_MARV_EXT_ADR); |
1760 | u16 led = PHY_M_LEDC_LOS_CTRL(1); /* link active */ | 1783 | u16 led = PHY_M_LEDC_LOS_CTRL(1); /* link active */ |
1761 | 1784 | ||
@@ -1800,11 +1823,6 @@ static void sky2_link_down(struct sky2_port *sky2) | |||
1800 | 1823 | ||
1801 | netif_carrier_off(sky2->netdev); | 1824 | netif_carrier_off(sky2->netdev); |
1802 | 1825 | ||
1803 | /* Stop watchdog if both ports are not active */ | ||
1804 | if (--hw->active == 0) | ||
1805 | del_timer(&hw->watchdog_timer); | ||
1806 | |||
1807 | |||
1808 | /* Turn on link LED */ | 1826 | /* Turn on link LED */ |
1809 | sky2_write8(hw, SK_REG(port, LNK_LED_REG), LINKLED_OFF); | 1827 | sky2_write8(hw, SK_REG(port, LNK_LED_REG), LINKLED_OFF); |
1810 | 1828 | ||
@@ -1847,7 +1865,7 @@ static int sky2_autoneg_done(struct sky2_port *sky2, u16 aux) | |||
1847 | /* Since the pause result bits seem to in different positions on | 1865 | /* Since the pause result bits seem to in different positions on |
1848 | * different chips. look at registers. | 1866 | * different chips. look at registers. |
1849 | */ | 1867 | */ |
1850 | if (!sky2_is_copper(hw)) { | 1868 | if (hw->flags & SKY2_HW_FIBRE_PHY) { |
1851 | /* Shift for bits in fiber PHY */ | 1869 | /* Shift for bits in fiber PHY */ |
1852 | advert &= ~(ADVERTISE_PAUSE_CAP|ADVERTISE_PAUSE_ASYM); | 1870 | advert &= ~(ADVERTISE_PAUSE_CAP|ADVERTISE_PAUSE_ASYM); |
1853 | lpa &= ~(LPA_PAUSE_CAP|LPA_PAUSE_ASYM); | 1871 | lpa &= ~(LPA_PAUSE_CAP|LPA_PAUSE_ASYM); |
@@ -1958,7 +1976,9 @@ static int sky2_change_mtu(struct net_device *dev, int new_mtu) | |||
1958 | if (new_mtu < ETH_ZLEN || new_mtu > ETH_JUMBO_MTU) | 1976 | if (new_mtu < ETH_ZLEN || new_mtu > ETH_JUMBO_MTU) |
1959 | return -EINVAL; | 1977 | return -EINVAL; |
1960 | 1978 | ||
1961 | if (new_mtu > ETH_DATA_LEN && hw->chip_id == CHIP_ID_YUKON_FE) | 1979 | if (new_mtu > ETH_DATA_LEN && |
1980 | (hw->chip_id == CHIP_ID_YUKON_FE || | ||
1981 | hw->chip_id == CHIP_ID_YUKON_FE_P)) | ||
1962 | return -EINVAL; | 1982 | return -EINVAL; |
1963 | 1983 | ||
1964 | if (!netif_running(dev)) { | 1984 | if (!netif_running(dev)) { |
@@ -1975,7 +1995,7 @@ static int sky2_change_mtu(struct net_device *dev, int new_mtu) | |||
1975 | 1995 | ||
1976 | synchronize_irq(hw->pdev->irq); | 1996 | synchronize_irq(hw->pdev->irq); |
1977 | 1997 | ||
1978 | if (hw->chip_id == CHIP_ID_YUKON_EC_U || hw->chip_id == CHIP_ID_YUKON_EX) | 1998 | if (!(hw->flags & SKY2_HW_RAMBUFFER)) |
1979 | sky2_set_tx_stfwd(hw, port); | 1999 | sky2_set_tx_stfwd(hw, port); |
1980 | 2000 | ||
1981 | ctl = gma_read16(hw, port, GM_GP_CTRL); | 2001 | ctl = gma_read16(hw, port, GM_GP_CTRL); |
@@ -2103,6 +2123,13 @@ static struct sk_buff *sky2_receive(struct net_device *dev, | |||
2103 | struct sky2_port *sky2 = netdev_priv(dev); | 2123 | struct sky2_port *sky2 = netdev_priv(dev); |
2104 | struct rx_ring_info *re = sky2->rx_ring + sky2->rx_next; | 2124 | struct rx_ring_info *re = sky2->rx_ring + sky2->rx_next; |
2105 | struct sk_buff *skb = NULL; | 2125 | struct sk_buff *skb = NULL; |
2126 | u16 count = (status & GMR_FS_LEN) >> 16; | ||
2127 | |||
2128 | #ifdef SKY2_VLAN_TAG_USED | ||
2129 | /* Account for vlan tag */ | ||
2130 | if (sky2->vlgrp && (status & GMR_FS_VLAN)) | ||
2131 | count -= VLAN_HLEN; | ||
2132 | #endif | ||
2106 | 2133 | ||
2107 | if (unlikely(netif_msg_rx_status(sky2))) | 2134 | if (unlikely(netif_msg_rx_status(sky2))) |
2108 | printk(KERN_DEBUG PFX "%s: rx slot %u status 0x%x len %d\n", | 2135 | printk(KERN_DEBUG PFX "%s: rx slot %u status 0x%x len %d\n", |
@@ -2117,7 +2144,8 @@ static struct sk_buff *sky2_receive(struct net_device *dev, | |||
2117 | if (!(status & GMR_FS_RX_OK)) | 2144 | if (!(status & GMR_FS_RX_OK)) |
2118 | goto resubmit; | 2145 | goto resubmit; |
2119 | 2146 | ||
2120 | if (status >> 16 != length) | 2147 | /* if length reported by DMA does not match PHY, packet was truncated */ |
2148 | if (length != count) | ||
2121 | goto len_mismatch; | 2149 | goto len_mismatch; |
2122 | 2150 | ||
2123 | if (length < copybreak) | 2151 | if (length < copybreak) |
@@ -2133,6 +2161,10 @@ len_mismatch: | |||
2133 | /* Truncation of overlength packets | 2161 | /* Truncation of overlength packets |
2134 | causes PHY length to not match MAC length */ | 2162 | causes PHY length to not match MAC length */ |
2135 | ++sky2->net_stats.rx_length_errors; | 2163 | ++sky2->net_stats.rx_length_errors; |
2164 | if (netif_msg_rx_err(sky2) && net_ratelimit()) | ||
2165 | pr_info(PFX "%s: rx length mismatch: length %d status %#x\n", | ||
2166 | dev->name, length, status); | ||
2167 | goto resubmit; | ||
2136 | 2168 | ||
2137 | error: | 2169 | error: |
2138 | ++sky2->net_stats.rx_errors; | 2170 | ++sky2->net_stats.rx_errors; |
@@ -2202,7 +2234,7 @@ static int sky2_status_intr(struct sky2_hw *hw, int to_do) | |||
2202 | } | 2234 | } |
2203 | 2235 | ||
2204 | /* This chip reports checksum status differently */ | 2236 | /* This chip reports checksum status differently */ |
2205 | if (hw->chip_id == CHIP_ID_YUKON_EX) { | 2237 | if (hw->flags & SKY2_HW_NEW_LE) { |
2206 | if (sky2->rx_csum && | 2238 | if (sky2->rx_csum && |
2207 | (le->css & (CSS_ISIPV4 | CSS_ISIPV6)) && | 2239 | (le->css & (CSS_ISIPV4 | CSS_ISIPV6)) && |
2208 | (le->css & CSS_TCPUDPCSOK)) | 2240 | (le->css & CSS_TCPUDPCSOK)) |
@@ -2243,8 +2275,14 @@ static int sky2_status_intr(struct sky2_hw *hw, int to_do) | |||
2243 | if (!sky2->rx_csum) | 2275 | if (!sky2->rx_csum) |
2244 | break; | 2276 | break; |
2245 | 2277 | ||
2246 | if (hw->chip_id == CHIP_ID_YUKON_EX) | 2278 | /* If this happens then driver assuming wrong format */ |
2279 | if (unlikely(hw->flags & SKY2_HW_NEW_LE)) { | ||
2280 | if (net_ratelimit()) | ||
2281 | printk(KERN_NOTICE "%s: unexpected" | ||
2282 | " checksum status\n", | ||
2283 | dev->name); | ||
2247 | break; | 2284 | break; |
2285 | } | ||
2248 | 2286 | ||
2249 | /* Both checksum counters are programmed to start at | 2287 | /* Both checksum counters are programmed to start at |
2250 | * the same offset, so unless there is a problem they | 2288 | * the same offset, so unless there is a problem they |
@@ -2436,20 +2474,72 @@ static void sky2_le_error(struct sky2_hw *hw, unsigned port, | |||
2436 | sky2_write32(hw, Q_ADDR(q, Q_CSR), BMU_CLR_IRQ_CHK); | 2474 | sky2_write32(hw, Q_ADDR(q, Q_CSR), BMU_CLR_IRQ_CHK); |
2437 | } | 2475 | } |
2438 | 2476 | ||
2439 | /* Check for lost IRQ once a second */ | 2477 | static int sky2_rx_hung(struct net_device *dev) |
2478 | { | ||
2479 | struct sky2_port *sky2 = netdev_priv(dev); | ||
2480 | struct sky2_hw *hw = sky2->hw; | ||
2481 | unsigned port = sky2->port; | ||
2482 | unsigned rxq = rxqaddr[port]; | ||
2483 | u32 mac_rp = sky2_read32(hw, SK_REG(port, RX_GMF_RP)); | ||
2484 | u8 mac_lev = sky2_read8(hw, SK_REG(port, RX_GMF_RLEV)); | ||
2485 | u8 fifo_rp = sky2_read8(hw, Q_ADDR(rxq, Q_RP)); | ||
2486 | u8 fifo_lev = sky2_read8(hw, Q_ADDR(rxq, Q_RL)); | ||
2487 | |||
2488 | /* If idle and MAC or PCI is stuck */ | ||
2489 | if (sky2->check.last == dev->last_rx && | ||
2490 | ((mac_rp == sky2->check.mac_rp && | ||
2491 | mac_lev != 0 && mac_lev >= sky2->check.mac_lev) || | ||
2492 | /* Check if the PCI RX hang */ | ||
2493 | (fifo_rp == sky2->check.fifo_rp && | ||
2494 | fifo_lev != 0 && fifo_lev >= sky2->check.fifo_lev))) { | ||
2495 | printk(KERN_DEBUG PFX "%s: hung mac %d:%d fifo %d (%d:%d)\n", | ||
2496 | dev->name, mac_lev, mac_rp, fifo_lev, fifo_rp, | ||
2497 | sky2_read8(hw, Q_ADDR(rxq, Q_WP))); | ||
2498 | return 1; | ||
2499 | } else { | ||
2500 | sky2->check.last = dev->last_rx; | ||
2501 | sky2->check.mac_rp = mac_rp; | ||
2502 | sky2->check.mac_lev = mac_lev; | ||
2503 | sky2->check.fifo_rp = fifo_rp; | ||
2504 | sky2->check.fifo_lev = fifo_lev; | ||
2505 | return 0; | ||
2506 | } | ||
2507 | } | ||
2508 | |||
2440 | static void sky2_watchdog(unsigned long arg) | 2509 | static void sky2_watchdog(unsigned long arg) |
2441 | { | 2510 | { |
2442 | struct sky2_hw *hw = (struct sky2_hw *) arg; | 2511 | struct sky2_hw *hw = (struct sky2_hw *) arg; |
2512 | struct net_device *dev; | ||
2443 | 2513 | ||
2514 | /* Check for lost IRQ once a second */ | ||
2444 | if (sky2_read32(hw, B0_ISRC)) { | 2515 | if (sky2_read32(hw, B0_ISRC)) { |
2445 | struct net_device *dev = hw->dev[0]; | 2516 | dev = hw->dev[0]; |
2446 | |||
2447 | if (__netif_rx_schedule_prep(dev)) | 2517 | if (__netif_rx_schedule_prep(dev)) |
2448 | __netif_rx_schedule(dev); | 2518 | __netif_rx_schedule(dev); |
2519 | } else { | ||
2520 | int i, active = 0; | ||
2521 | |||
2522 | for (i = 0; i < hw->ports; i++) { | ||
2523 | dev = hw->dev[i]; | ||
2524 | if (!netif_running(dev)) | ||
2525 | continue; | ||
2526 | ++active; | ||
2527 | |||
2528 | /* For chips with Rx FIFO, check if stuck */ | ||
2529 | if ((hw->flags & SKY2_HW_RAMBUFFER) && | ||
2530 | sky2_rx_hung(dev)) { | ||
2531 | pr_info(PFX "%s: receiver hang detected\n", | ||
2532 | dev->name); | ||
2533 | schedule_work(&hw->restart_work); | ||
2534 | return; | ||
2535 | } | ||
2536 | } | ||
2537 | |||
2538 | if (active == 0) | ||
2539 | return; | ||
2449 | } | 2540 | } |
2450 | 2541 | ||
2451 | if (hw->active > 0) | 2542 | mod_timer(&hw->watchdog_timer, round_jiffies(jiffies + HZ)); |
2452 | mod_timer(&hw->watchdog_timer, round_jiffies(jiffies + HZ)); | ||
2453 | } | 2543 | } |
2454 | 2544 | ||
2455 | /* Hardware/software error handling */ | 2545 | /* Hardware/software error handling */ |
@@ -2546,17 +2636,25 @@ static void sky2_netpoll(struct net_device *dev) | |||
2546 | #endif | 2636 | #endif |
2547 | 2637 | ||
2548 | /* Chip internal frequency for clock calculations */ | 2638 | /* Chip internal frequency for clock calculations */ |
2549 | static inline u32 sky2_mhz(const struct sky2_hw *hw) | 2639 | static u32 sky2_mhz(const struct sky2_hw *hw) |
2550 | { | 2640 | { |
2551 | switch (hw->chip_id) { | 2641 | switch (hw->chip_id) { |
2552 | case CHIP_ID_YUKON_EC: | 2642 | case CHIP_ID_YUKON_EC: |
2553 | case CHIP_ID_YUKON_EC_U: | 2643 | case CHIP_ID_YUKON_EC_U: |
2554 | case CHIP_ID_YUKON_EX: | 2644 | case CHIP_ID_YUKON_EX: |
2555 | return 125; /* 125 Mhz */ | 2645 | return 125; |
2646 | |||
2556 | case CHIP_ID_YUKON_FE: | 2647 | case CHIP_ID_YUKON_FE: |
2557 | return 100; /* 100 Mhz */ | 2648 | return 100; |
2558 | default: /* YUKON_XL */ | 2649 | |
2559 | return 156; /* 156 Mhz */ | 2650 | case CHIP_ID_YUKON_FE_P: |
2651 | return 50; | ||
2652 | |||
2653 | case CHIP_ID_YUKON_XL: | ||
2654 | return 156; | ||
2655 | |||
2656 | default: | ||
2657 | BUG(); | ||
2560 | } | 2658 | } |
2561 | } | 2659 | } |
2562 | 2660 | ||
@@ -2581,23 +2679,62 @@ static int __devinit sky2_init(struct sky2_hw *hw) | |||
2581 | sky2_write8(hw, B0_CTST, CS_RST_CLR); | 2679 | sky2_write8(hw, B0_CTST, CS_RST_CLR); |
2582 | 2680 | ||
2583 | hw->chip_id = sky2_read8(hw, B2_CHIP_ID); | 2681 | hw->chip_id = sky2_read8(hw, B2_CHIP_ID); |
2584 | if (hw->chip_id < CHIP_ID_YUKON_XL || hw->chip_id > CHIP_ID_YUKON_FE) { | 2682 | hw->chip_rev = (sky2_read8(hw, B2_MAC_CFG) & CFG_CHIP_R_MSK) >> 4; |
2683 | |||
2684 | switch(hw->chip_id) { | ||
2685 | case CHIP_ID_YUKON_XL: | ||
2686 | hw->flags = SKY2_HW_GIGABIT | ||
2687 | | SKY2_HW_NEWER_PHY | ||
2688 | | SKY2_HW_RAMBUFFER; | ||
2689 | break; | ||
2690 | |||
2691 | case CHIP_ID_YUKON_EC_U: | ||
2692 | hw->flags = SKY2_HW_GIGABIT | ||
2693 | | SKY2_HW_NEWER_PHY | ||
2694 | | SKY2_HW_ADV_POWER_CTL; | ||
2695 | break; | ||
2696 | |||
2697 | case CHIP_ID_YUKON_EX: | ||
2698 | hw->flags = SKY2_HW_GIGABIT | ||
2699 | | SKY2_HW_NEWER_PHY | ||
2700 | | SKY2_HW_NEW_LE | ||
2701 | | SKY2_HW_ADV_POWER_CTL; | ||
2702 | |||
2703 | /* New transmit checksum */ | ||
2704 | if (hw->chip_rev != CHIP_REV_YU_EX_B0) | ||
2705 | hw->flags |= SKY2_HW_AUTO_TX_SUM; | ||
2706 | break; | ||
2707 | |||
2708 | case CHIP_ID_YUKON_EC: | ||
2709 | /* This rev is really old, and requires untested workarounds */ | ||
2710 | if (hw->chip_rev == CHIP_REV_YU_EC_A1) { | ||
2711 | dev_err(&hw->pdev->dev, "unsupported revision Yukon-EC rev A1\n"); | ||
2712 | return -EOPNOTSUPP; | ||
2713 | } | ||
2714 | hw->flags = SKY2_HW_GIGABIT | SKY2_HW_RAMBUFFER; | ||
2715 | break; | ||
2716 | |||
2717 | case CHIP_ID_YUKON_FE: | ||
2718 | hw->flags = SKY2_HW_RAMBUFFER; | ||
2719 | break; | ||
2720 | |||
2721 | case CHIP_ID_YUKON_FE_P: | ||
2722 | hw->flags = SKY2_HW_NEWER_PHY | ||
2723 | | SKY2_HW_NEW_LE | ||
2724 | | SKY2_HW_AUTO_TX_SUM | ||
2725 | | SKY2_HW_ADV_POWER_CTL; | ||
2726 | break; | ||
2727 | default: | ||
2585 | dev_err(&hw->pdev->dev, "unsupported chip type 0x%x\n", | 2728 | dev_err(&hw->pdev->dev, "unsupported chip type 0x%x\n", |
2586 | hw->chip_id); | 2729 | hw->chip_id); |
2587 | return -EOPNOTSUPP; | 2730 | return -EOPNOTSUPP; |
2588 | } | 2731 | } |
2589 | 2732 | ||
2590 | hw->chip_rev = (sky2_read8(hw, B2_MAC_CFG) & CFG_CHIP_R_MSK) >> 4; | 2733 | hw->pmd_type = sky2_read8(hw, B2_PMD_TYP); |
2734 | if (hw->pmd_type == 'L' || hw->pmd_type == 'S' || hw->pmd_type == 'P') | ||
2735 | hw->flags |= SKY2_HW_FIBRE_PHY; | ||
2591 | 2736 | ||
2592 | /* This rev is really old, and requires untested workarounds */ | ||
2593 | if (hw->chip_id == CHIP_ID_YUKON_EC && hw->chip_rev == CHIP_REV_YU_EC_A1) { | ||
2594 | dev_err(&hw->pdev->dev, "unsupported revision Yukon-%s (0x%x) rev %d\n", | ||
2595 | yukon2_name[hw->chip_id - CHIP_ID_YUKON_XL], | ||
2596 | hw->chip_id, hw->chip_rev); | ||
2597 | return -EOPNOTSUPP; | ||
2598 | } | ||
2599 | 2737 | ||
2600 | hw->pmd_type = sky2_read8(hw, B2_PMD_TYP); | ||
2601 | hw->ports = 1; | 2738 | hw->ports = 1; |
2602 | t8 = sky2_read8(hw, B2_Y2_HW_RES); | 2739 | t8 = sky2_read8(hw, B2_Y2_HW_RES); |
2603 | if ((t8 & CFG_DUAL_MAC_MSK) == CFG_DUAL_MAC_MSK) { | 2740 | if ((t8 & CFG_DUAL_MAC_MSK) == CFG_DUAL_MAC_MSK) { |
@@ -2791,7 +2928,9 @@ static int sky2_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol) | |||
2791 | 2928 | ||
2792 | sky2->wol = wol->wolopts; | 2929 | sky2->wol = wol->wolopts; |
2793 | 2930 | ||
2794 | if (hw->chip_id == CHIP_ID_YUKON_EC_U || hw->chip_id == CHIP_ID_YUKON_EX) | 2931 | if (hw->chip_id == CHIP_ID_YUKON_EC_U || |
2932 | hw->chip_id == CHIP_ID_YUKON_EX || | ||
2933 | hw->chip_id == CHIP_ID_YUKON_FE_P) | ||
2795 | sky2_write32(hw, B0_CTST, sky2->wol | 2934 | sky2_write32(hw, B0_CTST, sky2->wol |
2796 | ? Y2_HW_WOL_ON : Y2_HW_WOL_OFF); | 2935 | ? Y2_HW_WOL_ON : Y2_HW_WOL_OFF); |
2797 | 2936 | ||
@@ -2809,7 +2948,7 @@ static u32 sky2_supported_modes(const struct sky2_hw *hw) | |||
2809 | | SUPPORTED_100baseT_Full | 2948 | | SUPPORTED_100baseT_Full |
2810 | | SUPPORTED_Autoneg | SUPPORTED_TP; | 2949 | | SUPPORTED_Autoneg | SUPPORTED_TP; |
2811 | 2950 | ||
2812 | if (hw->chip_id != CHIP_ID_YUKON_FE) | 2951 | if (hw->flags & SKY2_HW_GIGABIT) |
2813 | modes |= SUPPORTED_1000baseT_Half | 2952 | modes |= SUPPORTED_1000baseT_Half |
2814 | | SUPPORTED_1000baseT_Full; | 2953 | | SUPPORTED_1000baseT_Full; |
2815 | return modes; | 2954 | return modes; |
@@ -2829,13 +2968,6 @@ static int sky2_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd) | |||
2829 | ecmd->supported = sky2_supported_modes(hw); | 2968 | ecmd->supported = sky2_supported_modes(hw); |
2830 | ecmd->phy_address = PHY_ADDR_MARV; | 2969 | ecmd->phy_address = PHY_ADDR_MARV; |
2831 | if (sky2_is_copper(hw)) { | 2970 | if (sky2_is_copper(hw)) { |
2832 | ecmd->supported = SUPPORTED_10baseT_Half | ||
2833 | | SUPPORTED_10baseT_Full | ||
2834 | | SUPPORTED_100baseT_Half | ||
2835 | | SUPPORTED_100baseT_Full | ||
2836 | | SUPPORTED_1000baseT_Half | ||
2837 | | SUPPORTED_1000baseT_Full | ||
2838 | | SUPPORTED_Autoneg | SUPPORTED_TP; | ||
2839 | ecmd->port = PORT_TP; | 2971 | ecmd->port = PORT_TP; |
2840 | ecmd->speed = sky2->speed; | 2972 | ecmd->speed = sky2->speed; |
2841 | } else { | 2973 | } else { |
@@ -3791,6 +3923,13 @@ static __devinit struct net_device *sky2_init_netdev(struct sky2_hw *hw, | |||
3791 | sky2->hw = hw; | 3923 | sky2->hw = hw; |
3792 | sky2->msg_enable = netif_msg_init(debug, default_msg); | 3924 | sky2->msg_enable = netif_msg_init(debug, default_msg); |
3793 | 3925 | ||
3926 | /* This chip has hardware problems that generates | ||
3927 | * bogus PHY receive status so by default shut up the message. | ||
3928 | */ | ||
3929 | if (hw->chip_id == CHIP_ID_YUKON_FE_P && | ||
3930 | hw->chip_rev == CHIP_REV_YU_FE2_A0) | ||
3931 | sky2->msg_enable &= ~NETIF_MSG_RX_ERR; | ||
3932 | |||
3794 | /* Auto speed and flow control */ | 3933 | /* Auto speed and flow control */ |
3795 | sky2->autoneg = AUTONEG_ENABLE; | 3934 | sky2->autoneg = AUTONEG_ENABLE; |
3796 | sky2->flow_mode = FC_BOTH; | 3935 | sky2->flow_mode = FC_BOTH; |
@@ -3846,7 +3985,7 @@ static irqreturn_t __devinit sky2_test_intr(int irq, void *dev_id) | |||
3846 | return IRQ_NONE; | 3985 | return IRQ_NONE; |
3847 | 3986 | ||
3848 | if (status & Y2_IS_IRQ_SW) { | 3987 | if (status & Y2_IS_IRQ_SW) { |
3849 | hw->msi = 1; | 3988 | hw->flags |= SKY2_HW_USE_MSI; |
3850 | wake_up(&hw->msi_wait); | 3989 | wake_up(&hw->msi_wait); |
3851 | sky2_write8(hw, B0_CTST, CS_CL_SW_IRQ); | 3990 | sky2_write8(hw, B0_CTST, CS_CL_SW_IRQ); |
3852 | } | 3991 | } |
@@ -3874,9 +4013,9 @@ static int __devinit sky2_test_msi(struct sky2_hw *hw) | |||
3874 | sky2_write8(hw, B0_CTST, CS_ST_SW_IRQ); | 4013 | sky2_write8(hw, B0_CTST, CS_ST_SW_IRQ); |
3875 | sky2_read8(hw, B0_CTST); | 4014 | sky2_read8(hw, B0_CTST); |
3876 | 4015 | ||
3877 | wait_event_timeout(hw->msi_wait, hw->msi, HZ/10); | 4016 | wait_event_timeout(hw->msi_wait, (hw->flags & SKY2_HW_USE_MSI), HZ/10); |
3878 | 4017 | ||
3879 | if (!hw->msi) { | 4018 | if (!(hw->flags & SKY2_HW_USE_MSI)) { |
3880 | /* MSI test failed, go back to INTx mode */ | 4019 | /* MSI test failed, go back to INTx mode */ |
3881 | dev_info(&pdev->dev, "No interrupt generated using MSI, " | 4020 | dev_info(&pdev->dev, "No interrupt generated using MSI, " |
3882 | "switching to INTx mode.\n"); | 4021 | "switching to INTx mode.\n"); |
@@ -4009,7 +4148,8 @@ static int __devinit sky2_probe(struct pci_dev *pdev, | |||
4009 | goto err_out_free_netdev; | 4148 | goto err_out_free_netdev; |
4010 | } | 4149 | } |
4011 | 4150 | ||
4012 | err = request_irq(pdev->irq, sky2_intr, hw->msi ? 0 : IRQF_SHARED, | 4151 | err = request_irq(pdev->irq, sky2_intr, |
4152 | (hw->flags & SKY2_HW_USE_MSI) ? 0 : IRQF_SHARED, | ||
4013 | dev->name, hw); | 4153 | dev->name, hw); |
4014 | if (err) { | 4154 | if (err) { |
4015 | dev_err(&pdev->dev, "cannot assign irq %d\n", pdev->irq); | 4155 | dev_err(&pdev->dev, "cannot assign irq %d\n", pdev->irq); |
@@ -4042,7 +4182,7 @@ static int __devinit sky2_probe(struct pci_dev *pdev, | |||
4042 | return 0; | 4182 | return 0; |
4043 | 4183 | ||
4044 | err_out_unregister: | 4184 | err_out_unregister: |
4045 | if (hw->msi) | 4185 | if (hw->flags & SKY2_HW_USE_MSI) |
4046 | pci_disable_msi(pdev); | 4186 | pci_disable_msi(pdev); |
4047 | unregister_netdev(dev); | 4187 | unregister_netdev(dev); |
4048 | err_out_free_netdev: | 4188 | err_out_free_netdev: |
@@ -4091,7 +4231,7 @@ static void __devexit sky2_remove(struct pci_dev *pdev) | |||
4091 | sky2_read8(hw, B0_CTST); | 4231 | sky2_read8(hw, B0_CTST); |
4092 | 4232 | ||
4093 | free_irq(pdev->irq, hw); | 4233 | free_irq(pdev->irq, hw); |
4094 | if (hw->msi) | 4234 | if (hw->flags & SKY2_HW_USE_MSI) |
4095 | pci_disable_msi(pdev); | 4235 | pci_disable_msi(pdev); |
4096 | pci_free_consistent(pdev, STATUS_LE_BYTES, hw->st_le, hw->st_dma); | 4236 | pci_free_consistent(pdev, STATUS_LE_BYTES, hw->st_le, hw->st_dma); |
4097 | pci_release_regions(pdev); | 4237 | pci_release_regions(pdev); |
@@ -4159,7 +4299,9 @@ static int sky2_resume(struct pci_dev *pdev) | |||
4159 | pci_enable_wake(pdev, PCI_D0, 0); | 4299 | pci_enable_wake(pdev, PCI_D0, 0); |
4160 | 4300 | ||
4161 | /* Re-enable all clocks */ | 4301 | /* Re-enable all clocks */ |
4162 | if (hw->chip_id == CHIP_ID_YUKON_EX || hw->chip_id == CHIP_ID_YUKON_EC_U) | 4302 | if (hw->chip_id == CHIP_ID_YUKON_EX || |
4303 | hw->chip_id == CHIP_ID_YUKON_EC_U || | ||
4304 | hw->chip_id == CHIP_ID_YUKON_FE_P) | ||
4163 | sky2_pci_write32(hw, PCI_DEV_REG3, 0); | 4305 | sky2_pci_write32(hw, PCI_DEV_REG3, 0); |
4164 | 4306 | ||
4165 | sky2_reset(hw); | 4307 | sky2_reset(hw); |
diff --git a/drivers/net/sky2.h b/drivers/net/sky2.h index 72e12b7cfa40..69cd98400fe6 100644 --- a/drivers/net/sky2.h +++ b/drivers/net/sky2.h | |||
@@ -470,18 +470,24 @@ enum { | |||
470 | CHIP_ID_YUKON_EX = 0xb5, /* Chip ID for YUKON-2 Extreme */ | 470 | CHIP_ID_YUKON_EX = 0xb5, /* Chip ID for YUKON-2 Extreme */ |
471 | CHIP_ID_YUKON_EC = 0xb6, /* Chip ID for YUKON-2 EC */ | 471 | CHIP_ID_YUKON_EC = 0xb6, /* Chip ID for YUKON-2 EC */ |
472 | CHIP_ID_YUKON_FE = 0xb7, /* Chip ID for YUKON-2 FE */ | 472 | CHIP_ID_YUKON_FE = 0xb7, /* Chip ID for YUKON-2 FE */ |
473 | 473 | CHIP_ID_YUKON_FE_P = 0xb8, /* Chip ID for YUKON-2 FE+ */ | |
474 | }; | ||
475 | enum yukon_ec_rev { | ||
474 | CHIP_REV_YU_EC_A1 = 0, /* Chip Rev. for Yukon-EC A1/A0 */ | 476 | CHIP_REV_YU_EC_A1 = 0, /* Chip Rev. for Yukon-EC A1/A0 */ |
475 | CHIP_REV_YU_EC_A2 = 1, /* Chip Rev. for Yukon-EC A2 */ | 477 | CHIP_REV_YU_EC_A2 = 1, /* Chip Rev. for Yukon-EC A2 */ |
476 | CHIP_REV_YU_EC_A3 = 2, /* Chip Rev. for Yukon-EC A3 */ | 478 | CHIP_REV_YU_EC_A3 = 2, /* Chip Rev. for Yukon-EC A3 */ |
477 | 479 | }; | |
480 | enum yukon_ec_u_rev { | ||
478 | CHIP_REV_YU_EC_U_A0 = 1, | 481 | CHIP_REV_YU_EC_U_A0 = 1, |
479 | CHIP_REV_YU_EC_U_A1 = 2, | 482 | CHIP_REV_YU_EC_U_A1 = 2, |
480 | CHIP_REV_YU_EC_U_B0 = 3, | 483 | CHIP_REV_YU_EC_U_B0 = 3, |
481 | 484 | }; | |
485 | enum yukon_fe_rev { | ||
482 | CHIP_REV_YU_FE_A1 = 1, | 486 | CHIP_REV_YU_FE_A1 = 1, |
483 | CHIP_REV_YU_FE_A2 = 2, | 487 | CHIP_REV_YU_FE_A2 = 2, |
484 | 488 | }; | |
489 | enum yukon_fe_p_rev { | ||
490 | CHIP_REV_YU_FE2_A0 = 0, | ||
485 | }; | 491 | }; |
486 | enum yukon_ex_rev { | 492 | enum yukon_ex_rev { |
487 | CHIP_REV_YU_EX_A0 = 1, | 493 | CHIP_REV_YU_EX_A0 = 1, |
@@ -1668,7 +1674,7 @@ enum { | |||
1668 | 1674 | ||
1669 | /* Receive Frame Status Encoding */ | 1675 | /* Receive Frame Status Encoding */ |
1670 | enum { | 1676 | enum { |
1671 | GMR_FS_LEN = 0xffff<<16, /* Bit 31..16: Rx Frame Length */ | 1677 | GMR_FS_LEN = 0x7fff<<16, /* Bit 30..16: Rx Frame Length */ |
1672 | GMR_FS_VLAN = 1<<13, /* VLAN Packet */ | 1678 | GMR_FS_VLAN = 1<<13, /* VLAN Packet */ |
1673 | GMR_FS_JABBER = 1<<12, /* Jabber Packet */ | 1679 | GMR_FS_JABBER = 1<<12, /* Jabber Packet */ |
1674 | GMR_FS_UN_SIZE = 1<<11, /* Undersize Packet */ | 1680 | GMR_FS_UN_SIZE = 1<<11, /* Undersize Packet */ |
@@ -1729,6 +1735,10 @@ enum { | |||
1729 | GMF_RX_CTRL_DEF = GMF_OPER_ON | GMF_RX_F_FL_ON, | 1735 | GMF_RX_CTRL_DEF = GMF_OPER_ON | GMF_RX_F_FL_ON, |
1730 | }; | 1736 | }; |
1731 | 1737 | ||
1738 | /* TX_GMF_EA 32 bit Tx GMAC FIFO End Address */ | ||
1739 | enum { | ||
1740 | TX_DYN_WM_ENA = 3, /* Yukon-FE+ specific */ | ||
1741 | }; | ||
1732 | 1742 | ||
1733 | /* TX_GMF_CTRL_T 32 bit Tx GMAC FIFO Control/Test */ | 1743 | /* TX_GMF_CTRL_T 32 bit Tx GMAC FIFO Control/Test */ |
1734 | enum { | 1744 | enum { |
@@ -2017,6 +2027,14 @@ struct sky2_port { | |||
2017 | u16 rx_tag; | 2027 | u16 rx_tag; |
2018 | struct vlan_group *vlgrp; | 2028 | struct vlan_group *vlgrp; |
2019 | #endif | 2029 | #endif |
2030 | struct { | ||
2031 | unsigned long last; | ||
2032 | u32 mac_rp; | ||
2033 | u8 mac_lev; | ||
2034 | u8 fifo_rp; | ||
2035 | u8 fifo_lev; | ||
2036 | } check; | ||
2037 | |||
2020 | 2038 | ||
2021 | dma_addr_t rx_le_map; | 2039 | dma_addr_t rx_le_map; |
2022 | dma_addr_t tx_le_map; | 2040 | dma_addr_t tx_le_map; |
@@ -2040,12 +2058,20 @@ struct sky2_hw { | |||
2040 | void __iomem *regs; | 2058 | void __iomem *regs; |
2041 | struct pci_dev *pdev; | 2059 | struct pci_dev *pdev; |
2042 | struct net_device *dev[2]; | 2060 | struct net_device *dev[2]; |
2061 | unsigned long flags; | ||
2062 | #define SKY2_HW_USE_MSI 0x00000001 | ||
2063 | #define SKY2_HW_FIBRE_PHY 0x00000002 | ||
2064 | #define SKY2_HW_GIGABIT 0x00000004 | ||
2065 | #define SKY2_HW_NEWER_PHY 0x00000008 | ||
2066 | #define SKY2_HW_RAMBUFFER 0x00000010 /* chip has RAM FIFO */ | ||
2067 | #define SKY2_HW_NEW_LE 0x00000020 /* new LSOv2 format */ | ||
2068 | #define SKY2_HW_AUTO_TX_SUM 0x00000040 /* new IP decode for Tx */ | ||
2069 | #define SKY2_HW_ADV_POWER_CTL 0x00000080 /* additional PHY power regs */ | ||
2043 | 2070 | ||
2044 | u8 chip_id; | 2071 | u8 chip_id; |
2045 | u8 chip_rev; | 2072 | u8 chip_rev; |
2046 | u8 pmd_type; | 2073 | u8 pmd_type; |
2047 | u8 ports; | 2074 | u8 ports; |
2048 | u8 active; | ||
2049 | 2075 | ||
2050 | struct sky2_status_le *st_le; | 2076 | struct sky2_status_le *st_le; |
2051 | u32 st_idx; | 2077 | u32 st_idx; |
@@ -2053,13 +2079,12 @@ struct sky2_hw { | |||
2053 | 2079 | ||
2054 | struct timer_list watchdog_timer; | 2080 | struct timer_list watchdog_timer; |
2055 | struct work_struct restart_work; | 2081 | struct work_struct restart_work; |
2056 | int msi; | ||
2057 | wait_queue_head_t msi_wait; | 2082 | wait_queue_head_t msi_wait; |
2058 | }; | 2083 | }; |
2059 | 2084 | ||
2060 | static inline int sky2_is_copper(const struct sky2_hw *hw) | 2085 | static inline int sky2_is_copper(const struct sky2_hw *hw) |
2061 | { | 2086 | { |
2062 | return !(hw->pmd_type == 'L' || hw->pmd_type == 'S' || hw->pmd_type == 'P'); | 2087 | return !(hw->flags & SKY2_HW_FIBRE_PHY); |
2063 | } | 2088 | } |
2064 | 2089 | ||
2065 | /* Register accessor for memory mapped device */ | 2090 | /* Register accessor for memory mapped device */ |
@@ -50,7 +50,6 @@ | |||
50 | #include <linux/tsacct_kern.h> | 50 | #include <linux/tsacct_kern.h> |
51 | #include <linux/cn_proc.h> | 51 | #include <linux/cn_proc.h> |
52 | #include <linux/audit.h> | 52 | #include <linux/audit.h> |
53 | #include <linux/signalfd.h> | ||
54 | 53 | ||
55 | #include <asm/uaccess.h> | 54 | #include <asm/uaccess.h> |
56 | #include <asm/mmu_context.h> | 55 | #include <asm/mmu_context.h> |
@@ -784,7 +783,6 @@ static int de_thread(struct task_struct *tsk) | |||
784 | * and we can just re-use it all. | 783 | * and we can just re-use it all. |
785 | */ | 784 | */ |
786 | if (atomic_read(&oldsighand->count) <= 1) { | 785 | if (atomic_read(&oldsighand->count) <= 1) { |
787 | signalfd_detach(tsk); | ||
788 | exit_itimers(sig); | 786 | exit_itimers(sig); |
789 | return 0; | 787 | return 0; |
790 | } | 788 | } |
@@ -923,7 +921,6 @@ static int de_thread(struct task_struct *tsk) | |||
923 | sig->flags = 0; | 921 | sig->flags = 0; |
924 | 922 | ||
925 | no_thread_group: | 923 | no_thread_group: |
926 | signalfd_detach(tsk); | ||
927 | exit_itimers(sig); | 924 | exit_itimers(sig); |
928 | if (leader) | 925 | if (leader) |
929 | release_task(leader); | 926 | release_task(leader); |
diff --git a/fs/signalfd.c b/fs/signalfd.c index a8e293d30034..aefb0be07942 100644 --- a/fs/signalfd.c +++ b/fs/signalfd.c | |||
@@ -11,8 +11,10 @@ | |||
11 | * Now using anonymous inode source. | 11 | * Now using anonymous inode source. |
12 | * Thanks to Oleg Nesterov for useful code review and suggestions. | 12 | * Thanks to Oleg Nesterov for useful code review and suggestions. |
13 | * More comments and suggestions from Arnd Bergmann. | 13 | * More comments and suggestions from Arnd Bergmann. |
14 | * Sat May 19, 2007: Davi E. M. Arnaut <davi@haxent.com.br> | 14 | * Sat May 19, 2007: Davi E. M. Arnaut <davi@haxent.com.br> |
15 | * Retrieve multiple signals with one read() call | 15 | * Retrieve multiple signals with one read() call |
16 | * Sun Jul 15, 2007: Davide Libenzi <davidel@xmailserver.org> | ||
17 | * Attach to the sighand only during read() and poll(). | ||
16 | */ | 18 | */ |
17 | 19 | ||
18 | #include <linux/file.h> | 20 | #include <linux/file.h> |
@@ -27,102 +29,12 @@ | |||
27 | #include <linux/signalfd.h> | 29 | #include <linux/signalfd.h> |
28 | 30 | ||
29 | struct signalfd_ctx { | 31 | struct signalfd_ctx { |
30 | struct list_head lnk; | ||
31 | wait_queue_head_t wqh; | ||
32 | sigset_t sigmask; | 32 | sigset_t sigmask; |
33 | struct task_struct *tsk; | ||
34 | }; | 33 | }; |
35 | 34 | ||
36 | struct signalfd_lockctx { | ||
37 | struct task_struct *tsk; | ||
38 | unsigned long flags; | ||
39 | }; | ||
40 | |||
41 | /* | ||
42 | * Tries to acquire the sighand lock. We do not increment the sighand | ||
43 | * use count, and we do not even pin the task struct, so we need to | ||
44 | * do it inside an RCU read lock, and we must be prepared for the | ||
45 | * ctx->tsk going to NULL (in signalfd_deliver()), and for the sighand | ||
46 | * being detached. We return 0 if the sighand has been detached, or | ||
47 | * 1 if we were able to pin the sighand lock. | ||
48 | */ | ||
49 | static int signalfd_lock(struct signalfd_ctx *ctx, struct signalfd_lockctx *lk) | ||
50 | { | ||
51 | struct sighand_struct *sighand = NULL; | ||
52 | |||
53 | rcu_read_lock(); | ||
54 | lk->tsk = rcu_dereference(ctx->tsk); | ||
55 | if (likely(lk->tsk != NULL)) | ||
56 | sighand = lock_task_sighand(lk->tsk, &lk->flags); | ||
57 | rcu_read_unlock(); | ||
58 | |||
59 | if (!sighand) | ||
60 | return 0; | ||
61 | |||
62 | if (!ctx->tsk) { | ||
63 | unlock_task_sighand(lk->tsk, &lk->flags); | ||
64 | return 0; | ||
65 | } | ||
66 | |||
67 | if (lk->tsk->tgid == current->tgid) | ||
68 | lk->tsk = current; | ||
69 | |||
70 | return 1; | ||
71 | } | ||
72 | |||
73 | static void signalfd_unlock(struct signalfd_lockctx *lk) | ||
74 | { | ||
75 | unlock_task_sighand(lk->tsk, &lk->flags); | ||
76 | } | ||
77 | |||
78 | /* | ||
79 | * This must be called with the sighand lock held. | ||
80 | */ | ||
81 | void signalfd_deliver(struct task_struct *tsk, int sig) | ||
82 | { | ||
83 | struct sighand_struct *sighand = tsk->sighand; | ||
84 | struct signalfd_ctx *ctx, *tmp; | ||
85 | |||
86 | BUG_ON(!sig); | ||
87 | list_for_each_entry_safe(ctx, tmp, &sighand->signalfd_list, lnk) { | ||
88 | /* | ||
89 | * We use a negative signal value as a way to broadcast that the | ||
90 | * sighand has been orphaned, so that we can notify all the | ||
91 | * listeners about this. Remember the ctx->sigmask is inverted, | ||
92 | * so if the user is interested in a signal, that corresponding | ||
93 | * bit will be zero. | ||
94 | */ | ||
95 | if (sig < 0) { | ||
96 | if (ctx->tsk == tsk) { | ||
97 | ctx->tsk = NULL; | ||
98 | list_del_init(&ctx->lnk); | ||
99 | wake_up(&ctx->wqh); | ||
100 | } | ||
101 | } else { | ||
102 | if (!sigismember(&ctx->sigmask, sig)) | ||
103 | wake_up(&ctx->wqh); | ||
104 | } | ||
105 | } | ||
106 | } | ||
107 | |||
108 | static void signalfd_cleanup(struct signalfd_ctx *ctx) | ||
109 | { | ||
110 | struct signalfd_lockctx lk; | ||
111 | |||
112 | /* | ||
113 | * This is tricky. If the sighand is gone, we do not need to remove | ||
114 | * context from the list, the list itself won't be there anymore. | ||
115 | */ | ||
116 | if (signalfd_lock(ctx, &lk)) { | ||
117 | list_del(&ctx->lnk); | ||
118 | signalfd_unlock(&lk); | ||
119 | } | ||
120 | kfree(ctx); | ||
121 | } | ||
122 | |||
123 | static int signalfd_release(struct inode *inode, struct file *file) | 35 | static int signalfd_release(struct inode *inode, struct file *file) |
124 | { | 36 | { |
125 | signalfd_cleanup(file->private_data); | 37 | kfree(file->private_data); |
126 | return 0; | 38 | return 0; |
127 | } | 39 | } |
128 | 40 | ||
@@ -130,23 +42,15 @@ static unsigned int signalfd_poll(struct file *file, poll_table *wait) | |||
130 | { | 42 | { |
131 | struct signalfd_ctx *ctx = file->private_data; | 43 | struct signalfd_ctx *ctx = file->private_data; |
132 | unsigned int events = 0; | 44 | unsigned int events = 0; |
133 | struct signalfd_lockctx lk; | ||
134 | 45 | ||
135 | poll_wait(file, &ctx->wqh, wait); | 46 | poll_wait(file, ¤t->sighand->signalfd_wqh, wait); |
136 | 47 | ||
137 | /* | 48 | spin_lock_irq(¤t->sighand->siglock); |
138 | * Let the caller get a POLLIN in this case, ala socket recv() when | 49 | if (next_signal(¤t->pending, &ctx->sigmask) || |
139 | * the peer disconnects. | 50 | next_signal(¤t->signal->shared_pending, |
140 | */ | 51 | &ctx->sigmask)) |
141 | if (signalfd_lock(ctx, &lk)) { | ||
142 | if ((lk.tsk == current && | ||
143 | next_signal(&lk.tsk->pending, &ctx->sigmask) > 0) || | ||
144 | next_signal(&lk.tsk->signal->shared_pending, | ||
145 | &ctx->sigmask) > 0) | ||
146 | events |= POLLIN; | ||
147 | signalfd_unlock(&lk); | ||
148 | } else | ||
149 | events |= POLLIN; | 52 | events |= POLLIN; |
53 | spin_unlock_irq(¤t->sighand->siglock); | ||
150 | 54 | ||
151 | return events; | 55 | return events; |
152 | } | 56 | } |
@@ -219,59 +123,46 @@ static ssize_t signalfd_dequeue(struct signalfd_ctx *ctx, siginfo_t *info, | |||
219 | int nonblock) | 123 | int nonblock) |
220 | { | 124 | { |
221 | ssize_t ret; | 125 | ssize_t ret; |
222 | struct signalfd_lockctx lk; | ||
223 | DECLARE_WAITQUEUE(wait, current); | 126 | DECLARE_WAITQUEUE(wait, current); |
224 | 127 | ||
225 | if (!signalfd_lock(ctx, &lk)) | 128 | spin_lock_irq(¤t->sighand->siglock); |
226 | return 0; | 129 | ret = dequeue_signal(current, &ctx->sigmask, info); |
227 | |||
228 | ret = dequeue_signal(lk.tsk, &ctx->sigmask, info); | ||
229 | switch (ret) { | 130 | switch (ret) { |
230 | case 0: | 131 | case 0: |
231 | if (!nonblock) | 132 | if (!nonblock) |
232 | break; | 133 | break; |
233 | ret = -EAGAIN; | 134 | ret = -EAGAIN; |
234 | default: | 135 | default: |
235 | signalfd_unlock(&lk); | 136 | spin_unlock_irq(¤t->sighand->siglock); |
236 | return ret; | 137 | return ret; |
237 | } | 138 | } |
238 | 139 | ||
239 | add_wait_queue(&ctx->wqh, &wait); | 140 | add_wait_queue(¤t->sighand->signalfd_wqh, &wait); |
240 | for (;;) { | 141 | for (;;) { |
241 | set_current_state(TASK_INTERRUPTIBLE); | 142 | set_current_state(TASK_INTERRUPTIBLE); |
242 | ret = dequeue_signal(lk.tsk, &ctx->sigmask, info); | 143 | ret = dequeue_signal(current, &ctx->sigmask, info); |
243 | signalfd_unlock(&lk); | ||
244 | if (ret != 0) | 144 | if (ret != 0) |
245 | break; | 145 | break; |
246 | if (signal_pending(current)) { | 146 | if (signal_pending(current)) { |
247 | ret = -ERESTARTSYS; | 147 | ret = -ERESTARTSYS; |
248 | break; | 148 | break; |
249 | } | 149 | } |
150 | spin_unlock_irq(¤t->sighand->siglock); | ||
250 | schedule(); | 151 | schedule(); |
251 | ret = signalfd_lock(ctx, &lk); | 152 | spin_lock_irq(¤t->sighand->siglock); |
252 | if (unlikely(!ret)) { | ||
253 | /* | ||
254 | * Let the caller read zero byte, ala socket | ||
255 | * recv() when the peer disconnect. This test | ||
256 | * must be done before doing a dequeue_signal(), | ||
257 | * because if the sighand has been orphaned, | ||
258 | * the dequeue_signal() call is going to crash | ||
259 | * because ->sighand will be long gone. | ||
260 | */ | ||
261 | break; | ||
262 | } | ||
263 | } | 153 | } |
154 | spin_unlock_irq(¤t->sighand->siglock); | ||
264 | 155 | ||
265 | remove_wait_queue(&ctx->wqh, &wait); | 156 | remove_wait_queue(¤t->sighand->signalfd_wqh, &wait); |
266 | __set_current_state(TASK_RUNNING); | 157 | __set_current_state(TASK_RUNNING); |
267 | 158 | ||
268 | return ret; | 159 | return ret; |
269 | } | 160 | } |
270 | 161 | ||
271 | /* | 162 | /* |
272 | * Returns either the size of a "struct signalfd_siginfo", or zero if the | 163 | * Returns a multiple of the size of a "struct signalfd_siginfo", or a negative |
273 | * sighand we are attached to, has been orphaned. The "count" parameter | 164 | * error code. The "count" parameter must be at least the size of a |
274 | * must be at least the size of a "struct signalfd_siginfo". | 165 | * "struct signalfd_siginfo". |
275 | */ | 166 | */ |
276 | static ssize_t signalfd_read(struct file *file, char __user *buf, size_t count, | 167 | static ssize_t signalfd_read(struct file *file, char __user *buf, size_t count, |
277 | loff_t *ppos) | 168 | loff_t *ppos) |
@@ -287,7 +178,6 @@ static ssize_t signalfd_read(struct file *file, char __user *buf, size_t count, | |||
287 | return -EINVAL; | 178 | return -EINVAL; |
288 | 179 | ||
289 | siginfo = (struct signalfd_siginfo __user *) buf; | 180 | siginfo = (struct signalfd_siginfo __user *) buf; |
290 | |||
291 | do { | 181 | do { |
292 | ret = signalfd_dequeue(ctx, &info, nonblock); | 182 | ret = signalfd_dequeue(ctx, &info, nonblock); |
293 | if (unlikely(ret <= 0)) | 183 | if (unlikely(ret <= 0)) |
@@ -300,7 +190,7 @@ static ssize_t signalfd_read(struct file *file, char __user *buf, size_t count, | |||
300 | nonblock = 1; | 190 | nonblock = 1; |
301 | } while (--count); | 191 | } while (--count); |
302 | 192 | ||
303 | return total ? total : ret; | 193 | return total ? total: ret; |
304 | } | 194 | } |
305 | 195 | ||
306 | static const struct file_operations signalfd_fops = { | 196 | static const struct file_operations signalfd_fops = { |
@@ -309,20 +199,13 @@ static const struct file_operations signalfd_fops = { | |||
309 | .read = signalfd_read, | 199 | .read = signalfd_read, |
310 | }; | 200 | }; |
311 | 201 | ||
312 | /* | ||
313 | * Create a file descriptor that is associated with our signal | ||
314 | * state. We can pass it around to others if we want to, but | ||
315 | * it will always be _our_ signal state. | ||
316 | */ | ||
317 | asmlinkage long sys_signalfd(int ufd, sigset_t __user *user_mask, size_t sizemask) | 202 | asmlinkage long sys_signalfd(int ufd, sigset_t __user *user_mask, size_t sizemask) |
318 | { | 203 | { |
319 | int error; | 204 | int error; |
320 | sigset_t sigmask; | 205 | sigset_t sigmask; |
321 | struct signalfd_ctx *ctx; | 206 | struct signalfd_ctx *ctx; |
322 | struct sighand_struct *sighand; | ||
323 | struct file *file; | 207 | struct file *file; |
324 | struct inode *inode; | 208 | struct inode *inode; |
325 | struct signalfd_lockctx lk; | ||
326 | 209 | ||
327 | if (sizemask != sizeof(sigset_t) || | 210 | if (sizemask != sizeof(sigset_t) || |
328 | copy_from_user(&sigmask, user_mask, sizeof(sigmask))) | 211 | copy_from_user(&sigmask, user_mask, sizeof(sigmask))) |
@@ -335,17 +218,7 @@ asmlinkage long sys_signalfd(int ufd, sigset_t __user *user_mask, size_t sizemas | |||
335 | if (!ctx) | 218 | if (!ctx) |
336 | return -ENOMEM; | 219 | return -ENOMEM; |
337 | 220 | ||
338 | init_waitqueue_head(&ctx->wqh); | ||
339 | ctx->sigmask = sigmask; | 221 | ctx->sigmask = sigmask; |
340 | ctx->tsk = current->group_leader; | ||
341 | |||
342 | sighand = current->sighand; | ||
343 | /* | ||
344 | * Add this fd to the list of signal listeners. | ||
345 | */ | ||
346 | spin_lock_irq(&sighand->siglock); | ||
347 | list_add_tail(&ctx->lnk, &sighand->signalfd_list); | ||
348 | spin_unlock_irq(&sighand->siglock); | ||
349 | 222 | ||
350 | /* | 223 | /* |
351 | * When we call this, the initialization must be complete, since | 224 | * When we call this, the initialization must be complete, since |
@@ -364,23 +237,18 @@ asmlinkage long sys_signalfd(int ufd, sigset_t __user *user_mask, size_t sizemas | |||
364 | fput(file); | 237 | fput(file); |
365 | return -EINVAL; | 238 | return -EINVAL; |
366 | } | 239 | } |
367 | /* | 240 | spin_lock_irq(¤t->sighand->siglock); |
368 | * We need to be prepared of the fact that the sighand this fd | 241 | ctx->sigmask = sigmask; |
369 | * is attached to, has been detched. In that case signalfd_lock() | 242 | spin_unlock_irq(¤t->sighand->siglock); |
370 | * will return 0, and we'll just skip setting the new mask. | 243 | |
371 | */ | 244 | wake_up(¤t->sighand->signalfd_wqh); |
372 | if (signalfd_lock(ctx, &lk)) { | ||
373 | ctx->sigmask = sigmask; | ||
374 | signalfd_unlock(&lk); | ||
375 | } | ||
376 | wake_up(&ctx->wqh); | ||
377 | fput(file); | 245 | fput(file); |
378 | } | 246 | } |
379 | 247 | ||
380 | return ufd; | 248 | return ufd; |
381 | 249 | ||
382 | err_fdalloc: | 250 | err_fdalloc: |
383 | signalfd_cleanup(ctx); | 251 | kfree(ctx); |
384 | return error; | 252 | return error; |
385 | } | 253 | } |
386 | 254 | ||
diff --git a/include/linux/init_task.h b/include/linux/init_task.h index cab741c2d603..f8abfa349ef9 100644 --- a/include/linux/init_task.h +++ b/include/linux/init_task.h | |||
@@ -86,7 +86,7 @@ extern struct nsproxy init_nsproxy; | |||
86 | .count = ATOMIC_INIT(1), \ | 86 | .count = ATOMIC_INIT(1), \ |
87 | .action = { { { .sa_handler = NULL, } }, }, \ | 87 | .action = { { { .sa_handler = NULL, } }, }, \ |
88 | .siglock = __SPIN_LOCK_UNLOCKED(sighand.siglock), \ | 88 | .siglock = __SPIN_LOCK_UNLOCKED(sighand.siglock), \ |
89 | .signalfd_list = LIST_HEAD_INIT(sighand.signalfd_list), \ | 89 | .signalfd_wqh = __WAIT_QUEUE_HEAD_INITIALIZER(sighand.signalfd_wqh), \ |
90 | } | 90 | } |
91 | 91 | ||
92 | extern struct group_info init_groups; | 92 | extern struct group_info init_groups; |
diff --git a/include/linux/sched.h b/include/linux/sched.h index 3de79016f2a6..a01ac6dd5f5e 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h | |||
@@ -438,7 +438,7 @@ struct sighand_struct { | |||
438 | atomic_t count; | 438 | atomic_t count; |
439 | struct k_sigaction action[_NSIG]; | 439 | struct k_sigaction action[_NSIG]; |
440 | spinlock_t siglock; | 440 | spinlock_t siglock; |
441 | struct list_head signalfd_list; | 441 | wait_queue_head_t signalfd_wqh; |
442 | }; | 442 | }; |
443 | 443 | ||
444 | struct pacct_struct { | 444 | struct pacct_struct { |
diff --git a/include/linux/signalfd.h b/include/linux/signalfd.h index 510429495690..4c9ff0910ae0 100644 --- a/include/linux/signalfd.h +++ b/include/linux/signalfd.h | |||
@@ -45,49 +45,17 @@ struct signalfd_siginfo { | |||
45 | #ifdef CONFIG_SIGNALFD | 45 | #ifdef CONFIG_SIGNALFD |
46 | 46 | ||
47 | /* | 47 | /* |
48 | * Deliver the signal to listening signalfd. This must be called | 48 | * Deliver the signal to listening signalfd. |
49 | * with the sighand lock held. Same are the following that end up | ||
50 | * calling signalfd_deliver(). | ||
51 | */ | ||
52 | void signalfd_deliver(struct task_struct *tsk, int sig); | ||
53 | |||
54 | /* | ||
55 | * No need to fall inside signalfd_deliver() if no signal listeners | ||
56 | * are available. | ||
57 | */ | 49 | */ |
58 | static inline void signalfd_notify(struct task_struct *tsk, int sig) | 50 | static inline void signalfd_notify(struct task_struct *tsk, int sig) |
59 | { | 51 | { |
60 | if (unlikely(!list_empty(&tsk->sighand->signalfd_list))) | 52 | if (unlikely(waitqueue_active(&tsk->sighand->signalfd_wqh))) |
61 | signalfd_deliver(tsk, sig); | 53 | wake_up(&tsk->sighand->signalfd_wqh); |
62 | } | ||
63 | |||
64 | /* | ||
65 | * The signal -1 is used to notify the signalfd that the sighand | ||
66 | * is on its way to be detached. | ||
67 | */ | ||
68 | static inline void signalfd_detach_locked(struct task_struct *tsk) | ||
69 | { | ||
70 | if (unlikely(!list_empty(&tsk->sighand->signalfd_list))) | ||
71 | signalfd_deliver(tsk, -1); | ||
72 | } | ||
73 | |||
74 | static inline void signalfd_detach(struct task_struct *tsk) | ||
75 | { | ||
76 | struct sighand_struct *sighand = tsk->sighand; | ||
77 | |||
78 | if (unlikely(!list_empty(&sighand->signalfd_list))) { | ||
79 | spin_lock_irq(&sighand->siglock); | ||
80 | signalfd_deliver(tsk, -1); | ||
81 | spin_unlock_irq(&sighand->siglock); | ||
82 | } | ||
83 | } | 54 | } |
84 | 55 | ||
85 | #else /* CONFIG_SIGNALFD */ | 56 | #else /* CONFIG_SIGNALFD */ |
86 | 57 | ||
87 | #define signalfd_deliver(t, s) do { } while (0) | 58 | static inline void signalfd_notify(struct task_struct *tsk, int sig) { } |
88 | #define signalfd_notify(t, s) do { } while (0) | ||
89 | #define signalfd_detach_locked(t) do { } while (0) | ||
90 | #define signalfd_detach(t) do { } while (0) | ||
91 | 59 | ||
92 | #endif /* CONFIG_SIGNALFD */ | 60 | #endif /* CONFIG_SIGNALFD */ |
93 | 61 | ||
diff --git a/kernel/exit.c b/kernel/exit.c index 06b24b3aa370..993369ee94d1 100644 --- a/kernel/exit.c +++ b/kernel/exit.c | |||
@@ -24,7 +24,6 @@ | |||
24 | #include <linux/pid_namespace.h> | 24 | #include <linux/pid_namespace.h> |
25 | #include <linux/ptrace.h> | 25 | #include <linux/ptrace.h> |
26 | #include <linux/profile.h> | 26 | #include <linux/profile.h> |
27 | #include <linux/signalfd.h> | ||
28 | #include <linux/mount.h> | 27 | #include <linux/mount.h> |
29 | #include <linux/proc_fs.h> | 28 | #include <linux/proc_fs.h> |
30 | #include <linux/kthread.h> | 29 | #include <linux/kthread.h> |
@@ -86,14 +85,6 @@ static void __exit_signal(struct task_struct *tsk) | |||
86 | sighand = rcu_dereference(tsk->sighand); | 85 | sighand = rcu_dereference(tsk->sighand); |
87 | spin_lock(&sighand->siglock); | 86 | spin_lock(&sighand->siglock); |
88 | 87 | ||
89 | /* | ||
90 | * Notify that this sighand has been detached. This must | ||
91 | * be called with the tsk->sighand lock held. Also, this | ||
92 | * access tsk->sighand internally, so it must be called | ||
93 | * before tsk->sighand is reset. | ||
94 | */ | ||
95 | signalfd_detach_locked(tsk); | ||
96 | |||
97 | posix_cpu_timers_exit(tsk); | 88 | posix_cpu_timers_exit(tsk); |
98 | if (atomic_dec_and_test(&sig->count)) | 89 | if (atomic_dec_and_test(&sig->count)) |
99 | posix_cpu_timers_exit_group(tsk); | 90 | posix_cpu_timers_exit_group(tsk); |
diff --git a/kernel/fork.c b/kernel/fork.c index 7332e236d367..33f12f48684a 100644 --- a/kernel/fork.c +++ b/kernel/fork.c | |||
@@ -1438,7 +1438,7 @@ static void sighand_ctor(void *data, struct kmem_cache *cachep, | |||
1438 | struct sighand_struct *sighand = data; | 1438 | struct sighand_struct *sighand = data; |
1439 | 1439 | ||
1440 | spin_lock_init(&sighand->siglock); | 1440 | spin_lock_init(&sighand->siglock); |
1441 | INIT_LIST_HEAD(&sighand->signalfd_list); | 1441 | init_waitqueue_head(&sighand->signalfd_wqh); |
1442 | } | 1442 | } |
1443 | 1443 | ||
1444 | void __init proc_caches_init(void) | 1444 | void __init proc_caches_init(void) |
diff --git a/kernel/signal.c b/kernel/signal.c index 3169bed0b4d0..9fb91a32edda 100644 --- a/kernel/signal.c +++ b/kernel/signal.c | |||
@@ -378,8 +378,7 @@ int dequeue_signal(struct task_struct *tsk, sigset_t *mask, siginfo_t *info) | |||
378 | /* We only dequeue private signals from ourselves, we don't let | 378 | /* We only dequeue private signals from ourselves, we don't let |
379 | * signalfd steal them | 379 | * signalfd steal them |
380 | */ | 380 | */ |
381 | if (likely(tsk == current)) | 381 | signr = __dequeue_signal(&tsk->pending, mask, info); |
382 | signr = __dequeue_signal(&tsk->pending, mask, info); | ||
383 | if (!signr) { | 382 | if (!signr) { |
384 | signr = __dequeue_signal(&tsk->signal->shared_pending, | 383 | signr = __dequeue_signal(&tsk->signal->shared_pending, |
385 | mask, info); | 384 | mask, info); |
@@ -407,8 +406,7 @@ int dequeue_signal(struct task_struct *tsk, sigset_t *mask, siginfo_t *info) | |||
407 | } | 406 | } |
408 | } | 407 | } |
409 | } | 408 | } |
410 | if (likely(tsk == current)) | 409 | recalc_sigpending(); |
411 | recalc_sigpending(); | ||
412 | if (signr && unlikely(sig_kernel_stop(signr))) { | 410 | if (signr && unlikely(sig_kernel_stop(signr))) { |
413 | /* | 411 | /* |
414 | * Set a marker that we have dequeued a stop signal. Our | 412 | * Set a marker that we have dequeued a stop signal. Our |
@@ -425,7 +423,7 @@ int dequeue_signal(struct task_struct *tsk, sigset_t *mask, siginfo_t *info) | |||
425 | if (!(tsk->signal->flags & SIGNAL_GROUP_EXIT)) | 423 | if (!(tsk->signal->flags & SIGNAL_GROUP_EXIT)) |
426 | tsk->signal->flags |= SIGNAL_STOP_DEQUEUED; | 424 | tsk->signal->flags |= SIGNAL_STOP_DEQUEUED; |
427 | } | 425 | } |
428 | if (signr && likely(tsk == current) && | 426 | if (signr && |
429 | ((info->si_code & __SI_MASK) == __SI_TIMER) && | 427 | ((info->si_code & __SI_MASK) == __SI_TIMER) && |
430 | info->si_sys_private){ | 428 | info->si_sys_private){ |
431 | /* | 429 | /* |
diff --git a/net/netfilter/nfnetlink_log.c b/net/netfilter/nfnetlink_log.c index e185a5b55913..2351533a8507 100644 --- a/net/netfilter/nfnetlink_log.c +++ b/net/netfilter/nfnetlink_log.c | |||
@@ -58,7 +58,6 @@ struct nfulnl_instance { | |||
58 | 58 | ||
59 | unsigned int qlen; /* number of nlmsgs in skb */ | 59 | unsigned int qlen; /* number of nlmsgs in skb */ |
60 | struct sk_buff *skb; /* pre-allocatd skb */ | 60 | struct sk_buff *skb; /* pre-allocatd skb */ |
61 | struct nlmsghdr *lastnlh; /* netlink header of last msg in skb */ | ||
62 | struct timer_list timer; | 61 | struct timer_list timer; |
63 | int peer_pid; /* PID of the peer process */ | 62 | int peer_pid; /* PID of the peer process */ |
64 | 63 | ||
@@ -345,10 +344,12 @@ static struct sk_buff *nfulnl_alloc_skb(unsigned int inst_size, | |||
345 | static int | 344 | static int |
346 | __nfulnl_send(struct nfulnl_instance *inst) | 345 | __nfulnl_send(struct nfulnl_instance *inst) |
347 | { | 346 | { |
348 | int status; | 347 | int status = -1; |
349 | 348 | ||
350 | if (inst->qlen > 1) | 349 | if (inst->qlen > 1) |
351 | inst->lastnlh->nlmsg_type = NLMSG_DONE; | 350 | NLMSG_PUT(inst->skb, 0, 0, |
351 | NLMSG_DONE, | ||
352 | sizeof(struct nfgenmsg)); | ||
352 | 353 | ||
353 | status = nfnetlink_unicast(inst->skb, inst->peer_pid, MSG_DONTWAIT); | 354 | status = nfnetlink_unicast(inst->skb, inst->peer_pid, MSG_DONTWAIT); |
354 | if (status < 0) { | 355 | if (status < 0) { |
@@ -358,8 +359,8 @@ __nfulnl_send(struct nfulnl_instance *inst) | |||
358 | 359 | ||
359 | inst->qlen = 0; | 360 | inst->qlen = 0; |
360 | inst->skb = NULL; | 361 | inst->skb = NULL; |
361 | inst->lastnlh = NULL; | ||
362 | 362 | ||
363 | nlmsg_failure: | ||
363 | return status; | 364 | return status; |
364 | } | 365 | } |
365 | 366 | ||
@@ -538,7 +539,6 @@ __build_packet_message(struct nfulnl_instance *inst, | |||
538 | } | 539 | } |
539 | 540 | ||
540 | nlh->nlmsg_len = inst->skb->tail - old_tail; | 541 | nlh->nlmsg_len = inst->skb->tail - old_tail; |
541 | inst->lastnlh = nlh; | ||
542 | return 0; | 542 | return 0; |
543 | 543 | ||
544 | nlmsg_failure: | 544 | nlmsg_failure: |
@@ -644,7 +644,8 @@ nfulnl_log_packet(unsigned int pf, | |||
644 | } | 644 | } |
645 | 645 | ||
646 | if (inst->qlen >= qthreshold || | 646 | if (inst->qlen >= qthreshold || |
647 | (inst->skb && size > skb_tailroom(inst->skb))) { | 647 | (inst->skb && size > |
648 | skb_tailroom(inst->skb) - sizeof(struct nfgenmsg))) { | ||
648 | /* either the queue len is too high or we don't have | 649 | /* either the queue len is too high or we don't have |
649 | * enough room in the skb left. flush to userspace. */ | 650 | * enough room in the skb left. flush to userspace. */ |
650 | UDEBUG("flushing old skb\n"); | 651 | UDEBUG("flushing old skb\n"); |
diff --git a/net/sched/sch_sfq.c b/net/sched/sch_sfq.c index 957957309859..3a23e30bc79e 100644 --- a/net/sched/sch_sfq.c +++ b/net/sched/sch_sfq.c | |||
@@ -270,7 +270,7 @@ sfq_enqueue(struct sk_buff *skb, struct Qdisc* sch) | |||
270 | q->tail = x; | 270 | q->tail = x; |
271 | } | 271 | } |
272 | } | 272 | } |
273 | if (++sch->q.qlen < q->limit-1) { | 273 | if (++sch->q.qlen <= q->limit) { |
274 | sch->bstats.bytes += skb->len; | 274 | sch->bstats.bytes += skb->len; |
275 | sch->bstats.packets++; | 275 | sch->bstats.packets++; |
276 | return 0; | 276 | return 0; |
@@ -306,7 +306,7 @@ sfq_requeue(struct sk_buff *skb, struct Qdisc* sch) | |||
306 | q->tail = x; | 306 | q->tail = x; |
307 | } | 307 | } |
308 | } | 308 | } |
309 | if (++sch->q.qlen < q->limit - 1) { | 309 | if (++sch->q.qlen <= q->limit) { |
310 | sch->qstats.requeues++; | 310 | sch->qstats.requeues++; |
311 | return 0; | 311 | return 0; |
312 | } | 312 | } |
@@ -391,10 +391,10 @@ static int sfq_change(struct Qdisc *sch, struct rtattr *opt) | |||
391 | q->quantum = ctl->quantum ? : psched_mtu(sch->dev); | 391 | q->quantum = ctl->quantum ? : psched_mtu(sch->dev); |
392 | q->perturb_period = ctl->perturb_period*HZ; | 392 | q->perturb_period = ctl->perturb_period*HZ; |
393 | if (ctl->limit) | 393 | if (ctl->limit) |
394 | q->limit = min_t(u32, ctl->limit, SFQ_DEPTH); | 394 | q->limit = min_t(u32, ctl->limit, SFQ_DEPTH - 2); |
395 | 395 | ||
396 | qlen = sch->q.qlen; | 396 | qlen = sch->q.qlen; |
397 | while (sch->q.qlen >= q->limit-1) | 397 | while (sch->q.qlen > q->limit) |
398 | sfq_drop(sch); | 398 | sfq_drop(sch); |
399 | qdisc_tree_decrease_qlen(sch, qlen - sch->q.qlen); | 399 | qdisc_tree_decrease_qlen(sch, qlen - sch->q.qlen); |
400 | 400 | ||
@@ -423,7 +423,7 @@ static int sfq_init(struct Qdisc *sch, struct rtattr *opt) | |||
423 | q->dep[i+SFQ_DEPTH].next = i+SFQ_DEPTH; | 423 | q->dep[i+SFQ_DEPTH].next = i+SFQ_DEPTH; |
424 | q->dep[i+SFQ_DEPTH].prev = i+SFQ_DEPTH; | 424 | q->dep[i+SFQ_DEPTH].prev = i+SFQ_DEPTH; |
425 | } | 425 | } |
426 | q->limit = SFQ_DEPTH; | 426 | q->limit = SFQ_DEPTH - 2; |
427 | q->max_depth = 0; | 427 | q->max_depth = 0; |
428 | q->tail = SFQ_DEPTH; | 428 | q->tail = SFQ_DEPTH; |
429 | if (opt == NULL) { | 429 | if (opt == NULL) { |
diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c index 1a899924023f..036ab520df21 100644 --- a/net/sunrpc/svcsock.c +++ b/net/sunrpc/svcsock.c | |||
@@ -1110,7 +1110,8 @@ svc_tcp_accept(struct svc_sock *svsk) | |||
1110 | serv->sv_name); | 1110 | serv->sv_name); |
1111 | printk(KERN_NOTICE | 1111 | printk(KERN_NOTICE |
1112 | "%s: last TCP connect from %s\n", | 1112 | "%s: last TCP connect from %s\n", |
1113 | serv->sv_name, buf); | 1113 | serv->sv_name, __svc_print_addr(sin, |
1114 | buf, sizeof(buf))); | ||
1114 | } | 1115 | } |
1115 | /* | 1116 | /* |
1116 | * Always select the oldest socket. It's not fair, | 1117 | * Always select the oldest socket. It's not fair, |