diff options
Diffstat (limited to 'drivers/net')
229 files changed, 7119 insertions, 2839 deletions
diff --git a/drivers/net/3c509.c b/drivers/net/3c509.c index e6c545fe5f58..b9d097c9f6bb 100644 --- a/drivers/net/3c509.c +++ b/drivers/net/3c509.c | |||
@@ -413,7 +413,7 @@ static int __devinit el3_pnp_probe(struct pnp_dev *pdev, | |||
413 | { | 413 | { |
414 | short i; | 414 | short i; |
415 | int ioaddr, irq, if_port; | 415 | int ioaddr, irq, if_port; |
416 | u16 phys_addr[3]; | 416 | __be16 phys_addr[3]; |
417 | struct net_device *dev = NULL; | 417 | struct net_device *dev = NULL; |
418 | int err; | 418 | int err; |
419 | 419 | ||
@@ -605,7 +605,7 @@ static int __init el3_mca_probe(struct device *device) | |||
605 | 605 | ||
606 | short i; | 606 | short i; |
607 | int ioaddr, irq, if_port; | 607 | int ioaddr, irq, if_port; |
608 | u16 phys_addr[3]; | 608 | __be16 phys_addr[3]; |
609 | struct net_device *dev = NULL; | 609 | struct net_device *dev = NULL; |
610 | u_char pos4, pos5; | 610 | u_char pos4, pos5; |
611 | struct mca_device *mdev = to_mca_device(device); | 611 | struct mca_device *mdev = to_mca_device(device); |
@@ -635,14 +635,13 @@ static int __init el3_mca_probe(struct device *device) | |||
635 | printk(KERN_DEBUG "3c529: irq %d ioaddr 0x%x ifport %d\n", irq, ioaddr, if_port); | 635 | printk(KERN_DEBUG "3c529: irq %d ioaddr 0x%x ifport %d\n", irq, ioaddr, if_port); |
636 | } | 636 | } |
637 | EL3WINDOW(0); | 637 | EL3WINDOW(0); |
638 | for (i = 0; i < 3; i++) { | 638 | for (i = 0; i < 3; i++) |
639 | phys_addr[i] = htons(read_eeprom(ioaddr, i)); | 639 | phys_addr[i] = htons(read_eeprom(ioaddr, i)); |
640 | } | ||
641 | 640 | ||
642 | dev = alloc_etherdev(sizeof (struct el3_private)); | 641 | dev = alloc_etherdev(sizeof (struct el3_private)); |
643 | if (dev == NULL) { | 642 | if (dev == NULL) { |
644 | release_region(ioaddr, EL3_IO_EXTENT); | 643 | release_region(ioaddr, EL3_IO_EXTENT); |
645 | return -ENOMEM; | 644 | return -ENOMEM; |
646 | } | 645 | } |
647 | 646 | ||
648 | netdev_boot_setup_check(dev); | 647 | netdev_boot_setup_check(dev); |
@@ -668,7 +667,7 @@ static int __init el3_eisa_probe (struct device *device) | |||
668 | { | 667 | { |
669 | short i; | 668 | short i; |
670 | int ioaddr, irq, if_port; | 669 | int ioaddr, irq, if_port; |
671 | u16 phys_addr[3]; | 670 | __be16 phys_addr[3]; |
672 | struct net_device *dev = NULL; | 671 | struct net_device *dev = NULL; |
673 | struct eisa_device *edev; | 672 | struct eisa_device *edev; |
674 | int err; | 673 | int err; |
@@ -1063,7 +1062,6 @@ el3_rx(struct net_device *dev) | |||
1063 | struct sk_buff *skb; | 1062 | struct sk_buff *skb; |
1064 | 1063 | ||
1065 | skb = dev_alloc_skb(pkt_len+5); | 1064 | skb = dev_alloc_skb(pkt_len+5); |
1066 | dev->stats.rx_bytes += pkt_len; | ||
1067 | if (el3_debug > 4) | 1065 | if (el3_debug > 4) |
1068 | printk("Receiving packet size %d status %4.4x.\n", | 1066 | printk("Receiving packet size %d status %4.4x.\n", |
1069 | pkt_len, rx_status); | 1067 | pkt_len, rx_status); |
@@ -1078,6 +1076,7 @@ el3_rx(struct net_device *dev) | |||
1078 | skb->protocol = eth_type_trans(skb,dev); | 1076 | skb->protocol = eth_type_trans(skb,dev); |
1079 | netif_rx(skb); | 1077 | netif_rx(skb); |
1080 | dev->last_rx = jiffies; | 1078 | dev->last_rx = jiffies; |
1079 | dev->stats.rx_bytes += pkt_len; | ||
1081 | dev->stats.rx_packets++; | 1080 | dev->stats.rx_packets++; |
1082 | continue; | 1081 | continue; |
1083 | } | 1082 | } |
diff --git a/drivers/net/3c59x.c b/drivers/net/3c59x.c index 6f8e7d4cf74d..aabad8ce7458 100644 --- a/drivers/net/3c59x.c +++ b/drivers/net/3c59x.c | |||
@@ -319,7 +319,7 @@ static struct vortex_chip_info { | |||
319 | {"3c920B-EMB-WNM (ATI Radeon 9100 IGP)", | 319 | {"3c920B-EMB-WNM (ATI Radeon 9100 IGP)", |
320 | PCI_USES_MASTER, IS_TORNADO|HAS_MII|HAS_HWCKSM, 128, }, | 320 | PCI_USES_MASTER, IS_TORNADO|HAS_MII|HAS_HWCKSM, 128, }, |
321 | {"3c980 Cyclone", | 321 | {"3c980 Cyclone", |
322 | PCI_USES_MASTER, IS_CYCLONE|HAS_HWCKSM, 128, }, | 322 | PCI_USES_MASTER, IS_CYCLONE|HAS_HWCKSM|EXTRA_PREAMBLE, 128, }, |
323 | 323 | ||
324 | {"3c980C Python-T", | 324 | {"3c980C Python-T", |
325 | PCI_USES_MASTER, IS_CYCLONE|HAS_NWAY|HAS_HWCKSM, 128, }, | 325 | PCI_USES_MASTER, IS_CYCLONE|HAS_NWAY|HAS_HWCKSM, 128, }, |
@@ -600,7 +600,6 @@ struct vortex_private { | |||
600 | struct sk_buff* tx_skbuff[TX_RING_SIZE]; | 600 | struct sk_buff* tx_skbuff[TX_RING_SIZE]; |
601 | unsigned int cur_rx, cur_tx; /* The next free ring entry */ | 601 | unsigned int cur_rx, cur_tx; /* The next free ring entry */ |
602 | unsigned int dirty_rx, dirty_tx; /* The ring entries to be free()ed. */ | 602 | unsigned int dirty_rx, dirty_tx; /* The ring entries to be free()ed. */ |
603 | struct net_device_stats stats; /* Generic stats */ | ||
604 | struct vortex_extra_stats xstats; /* NIC-specific extra stats */ | 603 | struct vortex_extra_stats xstats; /* NIC-specific extra stats */ |
605 | struct sk_buff *tx_skb; /* Packet being eaten by bus master ctrl. */ | 604 | struct sk_buff *tx_skb; /* Packet being eaten by bus master ctrl. */ |
606 | dma_addr_t tx_skb_dma; /* Allocated DMA address for bus master ctrl DMA. */ | 605 | dma_addr_t tx_skb_dma; /* Allocated DMA address for bus master ctrl DMA. */ |
@@ -1769,9 +1768,10 @@ vortex_timer(unsigned long data) | |||
1769 | case XCVR_MII: case XCVR_NWAY: | 1768 | case XCVR_MII: case XCVR_NWAY: |
1770 | { | 1769 | { |
1771 | ok = 1; | 1770 | ok = 1; |
1772 | spin_lock_bh(&vp->lock); | 1771 | /* Interrupts are already disabled */ |
1772 | spin_lock(&vp->lock); | ||
1773 | vortex_check_media(dev, 0); | 1773 | vortex_check_media(dev, 0); |
1774 | spin_unlock_bh(&vp->lock); | 1774 | spin_unlock(&vp->lock); |
1775 | } | 1775 | } |
1776 | break; | 1776 | break; |
1777 | default: /* Other media types handled by Tx timeouts. */ | 1777 | default: /* Other media types handled by Tx timeouts. */ |
@@ -1875,7 +1875,7 @@ static void vortex_tx_timeout(struct net_device *dev) | |||
1875 | 1875 | ||
1876 | issue_and_wait(dev, TxReset); | 1876 | issue_and_wait(dev, TxReset); |
1877 | 1877 | ||
1878 | vp->stats.tx_errors++; | 1878 | dev->stats.tx_errors++; |
1879 | if (vp->full_bus_master_tx) { | 1879 | if (vp->full_bus_master_tx) { |
1880 | printk(KERN_DEBUG "%s: Resetting the Tx ring pointer.\n", dev->name); | 1880 | printk(KERN_DEBUG "%s: Resetting the Tx ring pointer.\n", dev->name); |
1881 | if (vp->cur_tx - vp->dirty_tx > 0 && ioread32(ioaddr + DownListPtr) == 0) | 1881 | if (vp->cur_tx - vp->dirty_tx > 0 && ioread32(ioaddr + DownListPtr) == 0) |
@@ -1887,7 +1887,7 @@ static void vortex_tx_timeout(struct net_device *dev) | |||
1887 | iowrite8(PKT_BUF_SZ>>8, ioaddr + TxFreeThreshold); | 1887 | iowrite8(PKT_BUF_SZ>>8, ioaddr + TxFreeThreshold); |
1888 | iowrite16(DownUnstall, ioaddr + EL3_CMD); | 1888 | iowrite16(DownUnstall, ioaddr + EL3_CMD); |
1889 | } else { | 1889 | } else { |
1890 | vp->stats.tx_dropped++; | 1890 | dev->stats.tx_dropped++; |
1891 | netif_wake_queue(dev); | 1891 | netif_wake_queue(dev); |
1892 | } | 1892 | } |
1893 | 1893 | ||
@@ -1928,8 +1928,8 @@ vortex_error(struct net_device *dev, int status) | |||
1928 | } | 1928 | } |
1929 | dump_tx_ring(dev); | 1929 | dump_tx_ring(dev); |
1930 | } | 1930 | } |
1931 | if (tx_status & 0x14) vp->stats.tx_fifo_errors++; | 1931 | if (tx_status & 0x14) dev->stats.tx_fifo_errors++; |
1932 | if (tx_status & 0x38) vp->stats.tx_aborted_errors++; | 1932 | if (tx_status & 0x38) dev->stats.tx_aborted_errors++; |
1933 | if (tx_status & 0x08) vp->xstats.tx_max_collisions++; | 1933 | if (tx_status & 0x08) vp->xstats.tx_max_collisions++; |
1934 | iowrite8(0, ioaddr + TxStatus); | 1934 | iowrite8(0, ioaddr + TxStatus); |
1935 | if (tx_status & 0x30) { /* txJabber or txUnderrun */ | 1935 | if (tx_status & 0x30) { /* txJabber or txUnderrun */ |
@@ -2051,8 +2051,8 @@ vortex_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
2051 | if (vortex_debug > 2) | 2051 | if (vortex_debug > 2) |
2052 | printk(KERN_DEBUG "%s: Tx error, status %2.2x.\n", | 2052 | printk(KERN_DEBUG "%s: Tx error, status %2.2x.\n", |
2053 | dev->name, tx_status); | 2053 | dev->name, tx_status); |
2054 | if (tx_status & 0x04) vp->stats.tx_fifo_errors++; | 2054 | if (tx_status & 0x04) dev->stats.tx_fifo_errors++; |
2055 | if (tx_status & 0x38) vp->stats.tx_aborted_errors++; | 2055 | if (tx_status & 0x38) dev->stats.tx_aborted_errors++; |
2056 | if (tx_status & 0x30) { | 2056 | if (tx_status & 0x30) { |
2057 | issue_and_wait(dev, TxReset); | 2057 | issue_and_wait(dev, TxReset); |
2058 | } | 2058 | } |
@@ -2350,7 +2350,7 @@ boomerang_interrupt(int irq, void *dev_id) | |||
2350 | } else { | 2350 | } else { |
2351 | printk(KERN_DEBUG "boomerang_interrupt: no skb!\n"); | 2351 | printk(KERN_DEBUG "boomerang_interrupt: no skb!\n"); |
2352 | } | 2352 | } |
2353 | /* vp->stats.tx_packets++; Counted below. */ | 2353 | /* dev->stats.tx_packets++; Counted below. */ |
2354 | dirty_tx++; | 2354 | dirty_tx++; |
2355 | } | 2355 | } |
2356 | vp->dirty_tx = dirty_tx; | 2356 | vp->dirty_tx = dirty_tx; |
@@ -2409,12 +2409,12 @@ static int vortex_rx(struct net_device *dev) | |||
2409 | unsigned char rx_error = ioread8(ioaddr + RxErrors); | 2409 | unsigned char rx_error = ioread8(ioaddr + RxErrors); |
2410 | if (vortex_debug > 2) | 2410 | if (vortex_debug > 2) |
2411 | printk(KERN_DEBUG " Rx error: status %2.2x.\n", rx_error); | 2411 | printk(KERN_DEBUG " Rx error: status %2.2x.\n", rx_error); |
2412 | vp->stats.rx_errors++; | 2412 | dev->stats.rx_errors++; |
2413 | if (rx_error & 0x01) vp->stats.rx_over_errors++; | 2413 | if (rx_error & 0x01) dev->stats.rx_over_errors++; |
2414 | if (rx_error & 0x02) vp->stats.rx_length_errors++; | 2414 | if (rx_error & 0x02) dev->stats.rx_length_errors++; |
2415 | if (rx_error & 0x04) vp->stats.rx_frame_errors++; | 2415 | if (rx_error & 0x04) dev->stats.rx_frame_errors++; |
2416 | if (rx_error & 0x08) vp->stats.rx_crc_errors++; | 2416 | if (rx_error & 0x08) dev->stats.rx_crc_errors++; |
2417 | if (rx_error & 0x10) vp->stats.rx_length_errors++; | 2417 | if (rx_error & 0x10) dev->stats.rx_length_errors++; |
2418 | } else { | 2418 | } else { |
2419 | /* The packet length: up to 4.5K!. */ | 2419 | /* The packet length: up to 4.5K!. */ |
2420 | int pkt_len = rx_status & 0x1fff; | 2420 | int pkt_len = rx_status & 0x1fff; |
@@ -2446,7 +2446,7 @@ static int vortex_rx(struct net_device *dev) | |||
2446 | skb->protocol = eth_type_trans(skb, dev); | 2446 | skb->protocol = eth_type_trans(skb, dev); |
2447 | netif_rx(skb); | 2447 | netif_rx(skb); |
2448 | dev->last_rx = jiffies; | 2448 | dev->last_rx = jiffies; |
2449 | vp->stats.rx_packets++; | 2449 | dev->stats.rx_packets++; |
2450 | /* Wait a limited time to go to next packet. */ | 2450 | /* Wait a limited time to go to next packet. */ |
2451 | for (i = 200; i >= 0; i--) | 2451 | for (i = 200; i >= 0; i--) |
2452 | if ( ! (ioread16(ioaddr + EL3_STATUS) & CmdInProgress)) | 2452 | if ( ! (ioread16(ioaddr + EL3_STATUS) & CmdInProgress)) |
@@ -2455,7 +2455,7 @@ static int vortex_rx(struct net_device *dev) | |||
2455 | } else if (vortex_debug > 0) | 2455 | } else if (vortex_debug > 0) |
2456 | printk(KERN_NOTICE "%s: No memory to allocate a sk_buff of " | 2456 | printk(KERN_NOTICE "%s: No memory to allocate a sk_buff of " |
2457 | "size %d.\n", dev->name, pkt_len); | 2457 | "size %d.\n", dev->name, pkt_len); |
2458 | vp->stats.rx_dropped++; | 2458 | dev->stats.rx_dropped++; |
2459 | } | 2459 | } |
2460 | issue_and_wait(dev, RxDiscard); | 2460 | issue_and_wait(dev, RxDiscard); |
2461 | } | 2461 | } |
@@ -2482,12 +2482,12 @@ boomerang_rx(struct net_device *dev) | |||
2482 | unsigned char rx_error = rx_status >> 16; | 2482 | unsigned char rx_error = rx_status >> 16; |
2483 | if (vortex_debug > 2) | 2483 | if (vortex_debug > 2) |
2484 | printk(KERN_DEBUG " Rx error: status %2.2x.\n", rx_error); | 2484 | printk(KERN_DEBUG " Rx error: status %2.2x.\n", rx_error); |
2485 | vp->stats.rx_errors++; | 2485 | dev->stats.rx_errors++; |
2486 | if (rx_error & 0x01) vp->stats.rx_over_errors++; | 2486 | if (rx_error & 0x01) dev->stats.rx_over_errors++; |
2487 | if (rx_error & 0x02) vp->stats.rx_length_errors++; | 2487 | if (rx_error & 0x02) dev->stats.rx_length_errors++; |
2488 | if (rx_error & 0x04) vp->stats.rx_frame_errors++; | 2488 | if (rx_error & 0x04) dev->stats.rx_frame_errors++; |
2489 | if (rx_error & 0x08) vp->stats.rx_crc_errors++; | 2489 | if (rx_error & 0x08) dev->stats.rx_crc_errors++; |
2490 | if (rx_error & 0x10) vp->stats.rx_length_errors++; | 2490 | if (rx_error & 0x10) dev->stats.rx_length_errors++; |
2491 | } else { | 2491 | } else { |
2492 | /* The packet length: up to 4.5K!. */ | 2492 | /* The packet length: up to 4.5K!. */ |
2493 | int pkt_len = rx_status & 0x1fff; | 2493 | int pkt_len = rx_status & 0x1fff; |
@@ -2529,7 +2529,7 @@ boomerang_rx(struct net_device *dev) | |||
2529 | } | 2529 | } |
2530 | netif_rx(skb); | 2530 | netif_rx(skb); |
2531 | dev->last_rx = jiffies; | 2531 | dev->last_rx = jiffies; |
2532 | vp->stats.rx_packets++; | 2532 | dev->stats.rx_packets++; |
2533 | } | 2533 | } |
2534 | entry = (++vp->cur_rx) % RX_RING_SIZE; | 2534 | entry = (++vp->cur_rx) % RX_RING_SIZE; |
2535 | } | 2535 | } |
@@ -2591,7 +2591,7 @@ vortex_down(struct net_device *dev, int final_down) | |||
2591 | del_timer_sync(&vp->rx_oom_timer); | 2591 | del_timer_sync(&vp->rx_oom_timer); |
2592 | del_timer_sync(&vp->timer); | 2592 | del_timer_sync(&vp->timer); |
2593 | 2593 | ||
2594 | /* Turn off statistics ASAP. We update vp->stats below. */ | 2594 | /* Turn off statistics ASAP. We update dev->stats below. */ |
2595 | iowrite16(StatsDisable, ioaddr + EL3_CMD); | 2595 | iowrite16(StatsDisable, ioaddr + EL3_CMD); |
2596 | 2596 | ||
2597 | /* Disable the receiver and transmitter. */ | 2597 | /* Disable the receiver and transmitter. */ |
@@ -2728,7 +2728,7 @@ static struct net_device_stats *vortex_get_stats(struct net_device *dev) | |||
2728 | update_stats(ioaddr, dev); | 2728 | update_stats(ioaddr, dev); |
2729 | spin_unlock_irqrestore (&vp->lock, flags); | 2729 | spin_unlock_irqrestore (&vp->lock, flags); |
2730 | } | 2730 | } |
2731 | return &vp->stats; | 2731 | return &dev->stats; |
2732 | } | 2732 | } |
2733 | 2733 | ||
2734 | /* Update statistics. | 2734 | /* Update statistics. |
@@ -2748,18 +2748,18 @@ static void update_stats(void __iomem *ioaddr, struct net_device *dev) | |||
2748 | /* Unlike the 3c5x9 we need not turn off stats updates while reading. */ | 2748 | /* Unlike the 3c5x9 we need not turn off stats updates while reading. */ |
2749 | /* Switch to the stats window, and read everything. */ | 2749 | /* Switch to the stats window, and read everything. */ |
2750 | EL3WINDOW(6); | 2750 | EL3WINDOW(6); |
2751 | vp->stats.tx_carrier_errors += ioread8(ioaddr + 0); | 2751 | dev->stats.tx_carrier_errors += ioread8(ioaddr + 0); |
2752 | vp->stats.tx_heartbeat_errors += ioread8(ioaddr + 1); | 2752 | dev->stats.tx_heartbeat_errors += ioread8(ioaddr + 1); |
2753 | vp->stats.tx_window_errors += ioread8(ioaddr + 4); | 2753 | dev->stats.tx_window_errors += ioread8(ioaddr + 4); |
2754 | vp->stats.rx_fifo_errors += ioread8(ioaddr + 5); | 2754 | dev->stats.rx_fifo_errors += ioread8(ioaddr + 5); |
2755 | vp->stats.tx_packets += ioread8(ioaddr + 6); | 2755 | dev->stats.tx_packets += ioread8(ioaddr + 6); |
2756 | vp->stats.tx_packets += (ioread8(ioaddr + 9)&0x30) << 4; | 2756 | dev->stats.tx_packets += (ioread8(ioaddr + 9)&0x30) << 4; |
2757 | /* Rx packets */ ioread8(ioaddr + 7); /* Must read to clear */ | 2757 | /* Rx packets */ ioread8(ioaddr + 7); /* Must read to clear */ |
2758 | /* Don't bother with register 9, an extension of registers 6&7. | 2758 | /* Don't bother with register 9, an extension of registers 6&7. |
2759 | If we do use the 6&7 values the atomic update assumption above | 2759 | If we do use the 6&7 values the atomic update assumption above |
2760 | is invalid. */ | 2760 | is invalid. */ |
2761 | vp->stats.rx_bytes += ioread16(ioaddr + 10); | 2761 | dev->stats.rx_bytes += ioread16(ioaddr + 10); |
2762 | vp->stats.tx_bytes += ioread16(ioaddr + 12); | 2762 | dev->stats.tx_bytes += ioread16(ioaddr + 12); |
2763 | /* Extra stats for get_ethtool_stats() */ | 2763 | /* Extra stats for get_ethtool_stats() */ |
2764 | vp->xstats.tx_multiple_collisions += ioread8(ioaddr + 2); | 2764 | vp->xstats.tx_multiple_collisions += ioread8(ioaddr + 2); |
2765 | vp->xstats.tx_single_collisions += ioread8(ioaddr + 3); | 2765 | vp->xstats.tx_single_collisions += ioread8(ioaddr + 3); |
@@ -2767,14 +2767,14 @@ static void update_stats(void __iomem *ioaddr, struct net_device *dev) | |||
2767 | EL3WINDOW(4); | 2767 | EL3WINDOW(4); |
2768 | vp->xstats.rx_bad_ssd += ioread8(ioaddr + 12); | 2768 | vp->xstats.rx_bad_ssd += ioread8(ioaddr + 12); |
2769 | 2769 | ||
2770 | vp->stats.collisions = vp->xstats.tx_multiple_collisions | 2770 | dev->stats.collisions = vp->xstats.tx_multiple_collisions |
2771 | + vp->xstats.tx_single_collisions | 2771 | + vp->xstats.tx_single_collisions |
2772 | + vp->xstats.tx_max_collisions; | 2772 | + vp->xstats.tx_max_collisions; |
2773 | 2773 | ||
2774 | { | 2774 | { |
2775 | u8 up = ioread8(ioaddr + 13); | 2775 | u8 up = ioread8(ioaddr + 13); |
2776 | vp->stats.rx_bytes += (up & 0x0f) << 16; | 2776 | dev->stats.rx_bytes += (up & 0x0f) << 16; |
2777 | vp->stats.tx_bytes += (up & 0xf0) << 12; | 2777 | dev->stats.tx_bytes += (up & 0xf0) << 12; |
2778 | } | 2778 | } |
2779 | 2779 | ||
2780 | EL3WINDOW(old_window >> 13); | 2780 | EL3WINDOW(old_window >> 13); |
diff --git a/drivers/net/7990.c b/drivers/net/7990.c index 750a46f4bc58..ad6b8a5b6574 100644 --- a/drivers/net/7990.c +++ b/drivers/net/7990.c | |||
@@ -506,6 +506,7 @@ int lance_open (struct net_device *dev) | |||
506 | 506 | ||
507 | return res; | 507 | return res; |
508 | } | 508 | } |
509 | EXPORT_SYMBOL_GPL(lance_open); | ||
509 | 510 | ||
510 | int lance_close (struct net_device *dev) | 511 | int lance_close (struct net_device *dev) |
511 | { | 512 | { |
@@ -521,6 +522,7 @@ int lance_close (struct net_device *dev) | |||
521 | 522 | ||
522 | return 0; | 523 | return 0; |
523 | } | 524 | } |
525 | EXPORT_SYMBOL_GPL(lance_close); | ||
524 | 526 | ||
525 | void lance_tx_timeout(struct net_device *dev) | 527 | void lance_tx_timeout(struct net_device *dev) |
526 | { | 528 | { |
@@ -529,7 +531,7 @@ void lance_tx_timeout(struct net_device *dev) | |||
529 | dev->trans_start = jiffies; | 531 | dev->trans_start = jiffies; |
530 | netif_wake_queue (dev); | 532 | netif_wake_queue (dev); |
531 | } | 533 | } |
532 | 534 | EXPORT_SYMBOL_GPL(lance_tx_timeout); | |
533 | 535 | ||
534 | int lance_start_xmit (struct sk_buff *skb, struct net_device *dev) | 536 | int lance_start_xmit (struct sk_buff *skb, struct net_device *dev) |
535 | { | 537 | { |
@@ -586,6 +588,7 @@ int lance_start_xmit (struct sk_buff *skb, struct net_device *dev) | |||
586 | 588 | ||
587 | return 0; | 589 | return 0; |
588 | } | 590 | } |
591 | EXPORT_SYMBOL_GPL(lance_start_xmit); | ||
589 | 592 | ||
590 | /* taken from the depca driver via a2065.c */ | 593 | /* taken from the depca driver via a2065.c */ |
591 | static void lance_load_multicast (struct net_device *dev) | 594 | static void lance_load_multicast (struct net_device *dev) |
@@ -654,6 +657,7 @@ void lance_set_multicast (struct net_device *dev) | |||
654 | if (!stopped) | 657 | if (!stopped) |
655 | netif_start_queue (dev); | 658 | netif_start_queue (dev); |
656 | } | 659 | } |
660 | EXPORT_SYMBOL_GPL(lance_set_multicast); | ||
657 | 661 | ||
658 | #ifdef CONFIG_NET_POLL_CONTROLLER | 662 | #ifdef CONFIG_NET_POLL_CONTROLLER |
659 | void lance_poll(struct net_device *dev) | 663 | void lance_poll(struct net_device *dev) |
diff --git a/drivers/net/82596.c b/drivers/net/82596.c index 2797da7eeee6..da292e647eb1 100644 --- a/drivers/net/82596.c +++ b/drivers/net/82596.c | |||
@@ -1162,6 +1162,7 @@ struct net_device * __init i82596_probe(int unit) | |||
1162 | memcpy(eth_addr, (void *) 0xfffc1f2c, 6); /* YUCK! Get addr from NOVRAM */ | 1162 | memcpy(eth_addr, (void *) 0xfffc1f2c, 6); /* YUCK! Get addr from NOVRAM */ |
1163 | dev->base_addr = MVME_I596_BASE; | 1163 | dev->base_addr = MVME_I596_BASE; |
1164 | dev->irq = (unsigned) MVME16x_IRQ_I596; | 1164 | dev->irq = (unsigned) MVME16x_IRQ_I596; |
1165 | goto found; | ||
1165 | } | 1166 | } |
1166 | #endif | 1167 | #endif |
1167 | #ifdef ENABLE_BVME6000_NET | 1168 | #ifdef ENABLE_BVME6000_NET |
@@ -1176,6 +1177,7 @@ struct net_device * __init i82596_probe(int unit) | |||
1176 | rtc[3] = msr; | 1177 | rtc[3] = msr; |
1177 | dev->base_addr = BVME_I596_BASE; | 1178 | dev->base_addr = BVME_I596_BASE; |
1178 | dev->irq = (unsigned) BVME_IRQ_I596; | 1179 | dev->irq = (unsigned) BVME_IRQ_I596; |
1180 | goto found; | ||
1179 | } | 1181 | } |
1180 | #endif | 1182 | #endif |
1181 | #ifdef ENABLE_APRICOT | 1183 | #ifdef ENABLE_APRICOT |
@@ -1212,8 +1214,13 @@ struct net_device * __init i82596_probe(int unit) | |||
1212 | } | 1214 | } |
1213 | 1215 | ||
1214 | dev->irq = 10; | 1216 | dev->irq = 10; |
1217 | goto found; | ||
1215 | } | 1218 | } |
1216 | #endif | 1219 | #endif |
1220 | err = -ENODEV; | ||
1221 | goto out; | ||
1222 | |||
1223 | found: | ||
1217 | dev->mem_start = (int)__get_free_pages(GFP_ATOMIC, 0); | 1224 | dev->mem_start = (int)__get_free_pages(GFP_ATOMIC, 0); |
1218 | if (!dev->mem_start) { | 1225 | if (!dev->mem_start) { |
1219 | err = -ENOMEM; | 1226 | err = -ENOMEM; |
diff --git a/drivers/net/8390.c b/drivers/net/8390.c index a499e867f0f4..dc5d2584bd0c 100644 --- a/drivers/net/8390.c +++ b/drivers/net/8390.c | |||
@@ -34,7 +34,7 @@ struct net_device *__alloc_ei_netdev(int size) | |||
34 | 34 | ||
35 | void NS8390_init(struct net_device *dev, int startp) | 35 | void NS8390_init(struct net_device *dev, int startp) |
36 | { | 36 | { |
37 | return __NS8390_init(dev, startp); | 37 | __NS8390_init(dev, startp); |
38 | } | 38 | } |
39 | 39 | ||
40 | EXPORT_SYMBOL(ei_open); | 40 | EXPORT_SYMBOL(ei_open); |
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index af46341827f2..f4182cfffe9d 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig | |||
@@ -1273,20 +1273,6 @@ config PCNET32 | |||
1273 | To compile this driver as a module, choose M here. The module | 1273 | To compile this driver as a module, choose M here. The module |
1274 | will be called pcnet32. | 1274 | will be called pcnet32. |
1275 | 1275 | ||
1276 | config PCNET32_NAPI | ||
1277 | bool "Use RX polling (NAPI)" | ||
1278 | depends on PCNET32 | ||
1279 | help | ||
1280 | NAPI is a new driver API designed to reduce CPU and interrupt load | ||
1281 | when the driver is receiving lots of packets from the card. It is | ||
1282 | still somewhat experimental and thus not yet enabled by default. | ||
1283 | |||
1284 | If your estimated Rx load is 10kpps or more, or if the card will be | ||
1285 | deployed on potentially unfriendly networks (e.g. in a firewall), | ||
1286 | then say Y here. | ||
1287 | |||
1288 | If in doubt, say N. | ||
1289 | |||
1290 | config AMD8111_ETH | 1276 | config AMD8111_ETH |
1291 | tristate "AMD 8111 (new PCI lance) support" | 1277 | tristate "AMD 8111 (new PCI lance) support" |
1292 | depends on NET_PCI && PCI | 1278 | depends on NET_PCI && PCI |
@@ -1367,7 +1353,7 @@ config APRICOT | |||
1367 | 1353 | ||
1368 | config B44 | 1354 | config B44 |
1369 | tristate "Broadcom 440x/47xx ethernet support" | 1355 | tristate "Broadcom 440x/47xx ethernet support" |
1370 | depends on SSB_POSSIBLE | 1356 | depends on SSB_POSSIBLE && HAS_DMA |
1371 | select SSB | 1357 | select SSB |
1372 | select MII | 1358 | select MII |
1373 | help | 1359 | help |
diff --git a/drivers/net/apne.c b/drivers/net/apne.c index 47a8275d3962..867f6fff543c 100644 --- a/drivers/net/apne.c +++ b/drivers/net/apne.c | |||
@@ -127,6 +127,9 @@ struct net_device * __init apne_probe(int unit) | |||
127 | #endif | 127 | #endif |
128 | int err; | 128 | int err; |
129 | 129 | ||
130 | if (!MACH_IS_AMIGA) | ||
131 | return ERR_PTR(-ENODEV); | ||
132 | |||
130 | if (apne_owned) | 133 | if (apne_owned) |
131 | return ERR_PTR(-ENODEV); | 134 | return ERR_PTR(-ENODEV); |
132 | 135 | ||
diff --git a/drivers/net/appletalk/cops.c b/drivers/net/appletalk/cops.c index 82e9a5bd0dd2..a0b4c8516073 100644 --- a/drivers/net/appletalk/cops.c +++ b/drivers/net/appletalk/cops.c | |||
@@ -499,19 +499,13 @@ static void cops_reset(struct net_device *dev, int sleep) | |||
499 | { | 499 | { |
500 | outb(0, ioaddr+DAYNA_RESET); /* Assert the reset port */ | 500 | outb(0, ioaddr+DAYNA_RESET); /* Assert the reset port */ |
501 | inb(ioaddr+DAYNA_RESET); /* Clear the reset */ | 501 | inb(ioaddr+DAYNA_RESET); /* Clear the reset */ |
502 | if(sleep) | 502 | if (sleep) |
503 | { | 503 | msleep(333); |
504 | long snap=jiffies; | 504 | else |
505 | 505 | mdelay(333); | |
506 | /* Let card finish initializing, about 1/3 second */ | ||
507 | while (time_before(jiffies, snap + HZ/3)) | ||
508 | schedule(); | ||
509 | } | ||
510 | else | ||
511 | mdelay(333); | ||
512 | } | 506 | } |
507 | |||
513 | netif_wake_queue(dev); | 508 | netif_wake_queue(dev); |
514 | return; | ||
515 | } | 509 | } |
516 | 510 | ||
517 | static void cops_load (struct net_device *dev) | 511 | static void cops_load (struct net_device *dev) |
diff --git a/drivers/net/atlx/atl1.c b/drivers/net/atlx/atl1.c index 0afe522b8f7b..3c798ae5c343 100644 --- a/drivers/net/atlx/atl1.c +++ b/drivers/net/atlx/atl1.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright(c) 2005 - 2006 Attansic Corporation. All rights reserved. | 2 | * Copyright(c) 2005 - 2006 Attansic Corporation. All rights reserved. |
3 | * Copyright(c) 2006 - 2007 Chris Snook <csnook@redhat.com> | 3 | * Copyright(c) 2006 - 2007 Chris Snook <csnook@redhat.com> |
4 | * Copyright(c) 2006 Jay Cliburn <jcliburn@gmail.com> | 4 | * Copyright(c) 2006 - 2008 Jay Cliburn <jcliburn@gmail.com> |
5 | * | 5 | * |
6 | * Derived from Intel e1000 driver | 6 | * Derived from Intel e1000 driver |
7 | * Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved. | 7 | * Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved. |
@@ -36,7 +36,6 @@ | |||
36 | * A very incomplete list of things that need to be dealt with: | 36 | * A very incomplete list of things that need to be dealt with: |
37 | * | 37 | * |
38 | * TODO: | 38 | * TODO: |
39 | * Wake on LAN. | ||
40 | * Add more ethtool functions. | 39 | * Add more ethtool functions. |
41 | * Fix abstruse irq enable/disable condition described here: | 40 | * Fix abstruse irq enable/disable condition described here: |
42 | * http://marc.theaimsgroup.com/?l=linux-netdev&m=116398508500553&w=2 | 41 | * http://marc.theaimsgroup.com/?l=linux-netdev&m=116398508500553&w=2 |
@@ -472,7 +471,6 @@ static int atl1_get_permanent_address(struct atl1_hw *hw) | |||
472 | memcpy(hw->perm_mac_addr, eth_addr, ETH_ALEN); | 471 | memcpy(hw->perm_mac_addr, eth_addr, ETH_ALEN); |
473 | return 0; | 472 | return 0; |
474 | } | 473 | } |
475 | return 1; | ||
476 | } | 474 | } |
477 | 475 | ||
478 | /* see if SPI FLAGS exist ? */ | 476 | /* see if SPI FLAGS exist ? */ |
@@ -638,25 +636,6 @@ static s32 atl1_phy_leave_power_saving(struct atl1_hw *hw) | |||
638 | } | 636 | } |
639 | 637 | ||
640 | /* | 638 | /* |
641 | *TODO: do something or get rid of this | ||
642 | */ | ||
643 | #ifdef CONFIG_PM | ||
644 | static s32 atl1_phy_enter_power_saving(struct atl1_hw *hw) | ||
645 | { | ||
646 | /* s32 ret_val; | ||
647 | * u16 phy_data; | ||
648 | */ | ||
649 | |||
650 | /* | ||
651 | ret_val = atl1_write_phy_reg(hw, ...); | ||
652 | ret_val = atl1_write_phy_reg(hw, ...); | ||
653 | .... | ||
654 | */ | ||
655 | return 0; | ||
656 | } | ||
657 | #endif | ||
658 | |||
659 | /* | ||
660 | * Resets the PHY and make all config validate | 639 | * Resets the PHY and make all config validate |
661 | * hw - Struct containing variables accessed by shared code | 640 | * hw - Struct containing variables accessed by shared code |
662 | * | 641 | * |
@@ -2027,6 +2006,7 @@ rrd_ok: | |||
2027 | /* Good Receive */ | 2006 | /* Good Receive */ |
2028 | pci_unmap_page(adapter->pdev, buffer_info->dma, | 2007 | pci_unmap_page(adapter->pdev, buffer_info->dma, |
2029 | buffer_info->length, PCI_DMA_FROMDEVICE); | 2008 | buffer_info->length, PCI_DMA_FROMDEVICE); |
2009 | buffer_info->dma = 0; | ||
2030 | skb = buffer_info->skb; | 2010 | skb = buffer_info->skb; |
2031 | length = le16_to_cpu(rrd->xsz.xsum_sz.pkt_size); | 2011 | length = le16_to_cpu(rrd->xsz.xsum_sz.pkt_size); |
2032 | 2012 | ||
@@ -2139,7 +2119,7 @@ static int atl1_tso(struct atl1_adapter *adapter, struct sk_buff *skb, | |||
2139 | return -1; | 2119 | return -1; |
2140 | } | 2120 | } |
2141 | 2121 | ||
2142 | if (skb->protocol == ntohs(ETH_P_IP)) { | 2122 | if (skb->protocol == htons(ETH_P_IP)) { |
2143 | struct iphdr *iph = ip_hdr(skb); | 2123 | struct iphdr *iph = ip_hdr(skb); |
2144 | 2124 | ||
2145 | real_len = (((unsigned char *)iph - skb->data) + | 2125 | real_len = (((unsigned char *)iph - skb->data) + |
@@ -2784,64 +2764,92 @@ static int atl1_suspend(struct pci_dev *pdev, pm_message_t state) | |||
2784 | struct atl1_hw *hw = &adapter->hw; | 2764 | struct atl1_hw *hw = &adapter->hw; |
2785 | u32 ctrl = 0; | 2765 | u32 ctrl = 0; |
2786 | u32 wufc = adapter->wol; | 2766 | u32 wufc = adapter->wol; |
2767 | u32 val; | ||
2768 | int retval; | ||
2769 | u16 speed; | ||
2770 | u16 duplex; | ||
2787 | 2771 | ||
2788 | netif_device_detach(netdev); | 2772 | netif_device_detach(netdev); |
2789 | if (netif_running(netdev)) | 2773 | if (netif_running(netdev)) |
2790 | atl1_down(adapter); | 2774 | atl1_down(adapter); |
2791 | 2775 | ||
2776 | retval = pci_save_state(pdev); | ||
2777 | if (retval) | ||
2778 | return retval; | ||
2779 | |||
2792 | atl1_read_phy_reg(hw, MII_BMSR, (u16 *) & ctrl); | 2780 | atl1_read_phy_reg(hw, MII_BMSR, (u16 *) & ctrl); |
2793 | atl1_read_phy_reg(hw, MII_BMSR, (u16 *) & ctrl); | 2781 | atl1_read_phy_reg(hw, MII_BMSR, (u16 *) & ctrl); |
2794 | if (ctrl & BMSR_LSTATUS) | 2782 | val = ctrl & BMSR_LSTATUS; |
2783 | if (val) | ||
2795 | wufc &= ~ATLX_WUFC_LNKC; | 2784 | wufc &= ~ATLX_WUFC_LNKC; |
2796 | 2785 | ||
2797 | /* reduce speed to 10/100M */ | 2786 | if (val && wufc) { |
2798 | if (wufc) { | 2787 | val = atl1_get_speed_and_duplex(hw, &speed, &duplex); |
2799 | atl1_phy_enter_power_saving(hw); | 2788 | if (val) { |
2800 | /* if resume, let driver to re- setup link */ | 2789 | if (netif_msg_ifdown(adapter)) |
2801 | hw->phy_configured = false; | 2790 | dev_printk(KERN_DEBUG, &pdev->dev, |
2802 | atl1_set_mac_addr(hw); | 2791 | "error getting speed/duplex\n"); |
2803 | atlx_set_multi(netdev); | 2792 | goto disable_wol; |
2793 | } | ||
2804 | 2794 | ||
2805 | ctrl = 0; | 2795 | ctrl = 0; |
2806 | /* turn on magic packet wol */ | ||
2807 | if (wufc & ATLX_WUFC_MAG) | ||
2808 | ctrl = WOL_MAGIC_EN | WOL_MAGIC_PME_EN; | ||
2809 | 2796 | ||
2810 | /* turn on Link change WOL */ | 2797 | /* enable magic packet WOL */ |
2811 | if (wufc & ATLX_WUFC_LNKC) | 2798 | if (wufc & ATLX_WUFC_MAG) |
2812 | ctrl |= (WOL_LINK_CHG_EN | WOL_LINK_CHG_PME_EN); | 2799 | ctrl |= (WOL_MAGIC_EN | WOL_MAGIC_PME_EN); |
2813 | iowrite32(ctrl, hw->hw_addr + REG_WOL_CTRL); | 2800 | iowrite32(ctrl, hw->hw_addr + REG_WOL_CTRL); |
2801 | ioread32(hw->hw_addr + REG_WOL_CTRL); | ||
2802 | |||
2803 | /* configure the mac */ | ||
2804 | ctrl = MAC_CTRL_RX_EN; | ||
2805 | ctrl |= ((u32)((speed == SPEED_1000) ? MAC_CTRL_SPEED_1000 : | ||
2806 | MAC_CTRL_SPEED_10_100) << MAC_CTRL_SPEED_SHIFT); | ||
2807 | if (duplex == FULL_DUPLEX) | ||
2808 | ctrl |= MAC_CTRL_DUPLX; | ||
2809 | ctrl |= (((u32)adapter->hw.preamble_len & | ||
2810 | MAC_CTRL_PRMLEN_MASK) << MAC_CTRL_PRMLEN_SHIFT); | ||
2811 | if (adapter->vlgrp) | ||
2812 | ctrl |= MAC_CTRL_RMV_VLAN; | ||
2813 | if (wufc & ATLX_WUFC_MAG) | ||
2814 | ctrl |= MAC_CTRL_BC_EN; | ||
2815 | iowrite32(ctrl, hw->hw_addr + REG_MAC_CTRL); | ||
2816 | ioread32(hw->hw_addr + REG_MAC_CTRL); | ||
2814 | 2817 | ||
2815 | /* turn on all-multi mode if wake on multicast is enabled */ | 2818 | /* poke the PHY */ |
2816 | ctrl = ioread32(hw->hw_addr + REG_MAC_CTRL); | 2819 | ctrl = ioread32(hw->hw_addr + REG_PCIE_PHYMISC); |
2817 | ctrl &= ~MAC_CTRL_DBG; | 2820 | ctrl |= PCIE_PHYMISC_FORCE_RCV_DET; |
2818 | ctrl &= ~MAC_CTRL_PROMIS_EN; | 2821 | iowrite32(ctrl, hw->hw_addr + REG_PCIE_PHYMISC); |
2819 | if (wufc & ATLX_WUFC_MC) | 2822 | ioread32(hw->hw_addr + REG_PCIE_PHYMISC); |
2820 | ctrl |= MAC_CTRL_MC_ALL_EN; | ||
2821 | else | ||
2822 | ctrl &= ~MAC_CTRL_MC_ALL_EN; | ||
2823 | 2823 | ||
2824 | /* turn on broadcast mode if wake on-BC is enabled */ | 2824 | pci_enable_wake(pdev, pci_choose_state(pdev, state), 1); |
2825 | if (wufc & ATLX_WUFC_BC) | 2825 | goto exit; |
2826 | ctrl |= MAC_CTRL_BC_EN; | 2826 | } |
2827 | else | ||
2828 | ctrl &= ~MAC_CTRL_BC_EN; | ||
2829 | 2827 | ||
2830 | /* enable RX */ | 2828 | if (!val && wufc) { |
2831 | ctrl |= MAC_CTRL_RX_EN; | 2829 | ctrl |= (WOL_LINK_CHG_EN | WOL_LINK_CHG_PME_EN); |
2832 | iowrite32(ctrl, hw->hw_addr + REG_MAC_CTRL); | 2830 | iowrite32(ctrl, hw->hw_addr + REG_WOL_CTRL); |
2833 | pci_enable_wake(pdev, PCI_D3hot, 1); | 2831 | ioread32(hw->hw_addr + REG_WOL_CTRL); |
2834 | pci_enable_wake(pdev, PCI_D3cold, 1); | 2832 | iowrite32(0, hw->hw_addr + REG_MAC_CTRL); |
2835 | } else { | 2833 | ioread32(hw->hw_addr + REG_MAC_CTRL); |
2836 | iowrite32(0, hw->hw_addr + REG_WOL_CTRL); | 2834 | hw->phy_configured = false; |
2837 | pci_enable_wake(pdev, PCI_D3hot, 0); | 2835 | pci_enable_wake(pdev, pci_choose_state(pdev, state), 1); |
2838 | pci_enable_wake(pdev, PCI_D3cold, 0); | 2836 | goto exit; |
2839 | } | 2837 | } |
2840 | 2838 | ||
2841 | pci_save_state(pdev); | 2839 | disable_wol: |
2840 | iowrite32(0, hw->hw_addr + REG_WOL_CTRL); | ||
2841 | ioread32(hw->hw_addr + REG_WOL_CTRL); | ||
2842 | ctrl = ioread32(hw->hw_addr + REG_PCIE_PHYMISC); | ||
2843 | ctrl |= PCIE_PHYMISC_FORCE_RCV_DET; | ||
2844 | iowrite32(ctrl, hw->hw_addr + REG_PCIE_PHYMISC); | ||
2845 | ioread32(hw->hw_addr + REG_PCIE_PHYMISC); | ||
2846 | hw->phy_configured = false; | ||
2847 | pci_enable_wake(pdev, pci_choose_state(pdev, state), 0); | ||
2848 | exit: | ||
2849 | if (netif_running(netdev)) | ||
2850 | pci_disable_msi(adapter->pdev); | ||
2842 | pci_disable_device(pdev); | 2851 | pci_disable_device(pdev); |
2843 | 2852 | pci_set_power_state(pdev, pci_choose_state(pdev, state)); | |
2844 | pci_set_power_state(pdev, PCI_D3hot); | ||
2845 | 2853 | ||
2846 | return 0; | 2854 | return 0; |
2847 | } | 2855 | } |
@@ -2855,20 +2863,26 @@ static int atl1_resume(struct pci_dev *pdev) | |||
2855 | pci_set_power_state(pdev, PCI_D0); | 2863 | pci_set_power_state(pdev, PCI_D0); |
2856 | pci_restore_state(pdev); | 2864 | pci_restore_state(pdev); |
2857 | 2865 | ||
2858 | /* FIXME: check and handle */ | ||
2859 | err = pci_enable_device(pdev); | 2866 | err = pci_enable_device(pdev); |
2867 | if (err) { | ||
2868 | if (netif_msg_ifup(adapter)) | ||
2869 | dev_printk(KERN_DEBUG, &pdev->dev, | ||
2870 | "error enabling pci device\n"); | ||
2871 | return err; | ||
2872 | } | ||
2873 | |||
2874 | pci_set_master(pdev); | ||
2875 | iowrite32(0, adapter->hw.hw_addr + REG_WOL_CTRL); | ||
2860 | pci_enable_wake(pdev, PCI_D3hot, 0); | 2876 | pci_enable_wake(pdev, PCI_D3hot, 0); |
2861 | pci_enable_wake(pdev, PCI_D3cold, 0); | 2877 | pci_enable_wake(pdev, PCI_D3cold, 0); |
2862 | 2878 | ||
2863 | iowrite32(0, adapter->hw.hw_addr + REG_WOL_CTRL); | 2879 | atl1_reset_hw(&adapter->hw); |
2864 | atl1_reset(adapter); | 2880 | adapter->cmb.cmb->int_stats = 0; |
2865 | 2881 | ||
2866 | if (netif_running(netdev)) | 2882 | if (netif_running(netdev)) |
2867 | atl1_up(adapter); | 2883 | atl1_up(adapter); |
2868 | netif_device_attach(netdev); | 2884 | netif_device_attach(netdev); |
2869 | 2885 | ||
2870 | atl1_via_workaround(adapter); | ||
2871 | |||
2872 | return 0; | 2886 | return 0; |
2873 | } | 2887 | } |
2874 | #else | 2888 | #else |
@@ -2876,6 +2890,13 @@ static int atl1_resume(struct pci_dev *pdev) | |||
2876 | #define atl1_resume NULL | 2890 | #define atl1_resume NULL |
2877 | #endif | 2891 | #endif |
2878 | 2892 | ||
2893 | static void atl1_shutdown(struct pci_dev *pdev) | ||
2894 | { | ||
2895 | #ifdef CONFIG_PM | ||
2896 | atl1_suspend(pdev, PMSG_SUSPEND); | ||
2897 | #endif | ||
2898 | } | ||
2899 | |||
2879 | #ifdef CONFIG_NET_POLL_CONTROLLER | 2900 | #ifdef CONFIG_NET_POLL_CONTROLLER |
2880 | static void atl1_poll_controller(struct net_device *netdev) | 2901 | static void atl1_poll_controller(struct net_device *netdev) |
2881 | { | 2902 | { |
@@ -3122,7 +3143,8 @@ static struct pci_driver atl1_driver = { | |||
3122 | .probe = atl1_probe, | 3143 | .probe = atl1_probe, |
3123 | .remove = __devexit_p(atl1_remove), | 3144 | .remove = __devexit_p(atl1_remove), |
3124 | .suspend = atl1_suspend, | 3145 | .suspend = atl1_suspend, |
3125 | .resume = atl1_resume | 3146 | .resume = atl1_resume, |
3147 | .shutdown = atl1_shutdown | ||
3126 | }; | 3148 | }; |
3127 | 3149 | ||
3128 | /* | 3150 | /* |
diff --git a/drivers/net/atlx/atl1.h b/drivers/net/atlx/atl1.h index 51893d66eae1..a5015b14a429 100644 --- a/drivers/net/atlx/atl1.h +++ b/drivers/net/atlx/atl1.h | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright(c) 2005 - 2006 Attansic Corporation. All rights reserved. | 2 | * Copyright(c) 2005 - 2006 Attansic Corporation. All rights reserved. |
3 | * Copyright(c) 2006 - 2007 Chris Snook <csnook@redhat.com> | 3 | * Copyright(c) 2006 - 2007 Chris Snook <csnook@redhat.com> |
4 | * Copyright(c) 2006 Jay Cliburn <jcliburn@gmail.com> | 4 | * Copyright(c) 2006 - 2008 Jay Cliburn <jcliburn@gmail.com> |
5 | * | 5 | * |
6 | * Derived from Intel e1000 driver | 6 | * Derived from Intel e1000 driver |
7 | * Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved. | 7 | * Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved. |
diff --git a/drivers/net/atlx/atlx.c b/drivers/net/atlx/atlx.c index f06b854e2501..b3e7fcf0f6e7 100644 --- a/drivers/net/atlx/atlx.c +++ b/drivers/net/atlx/atlx.c | |||
@@ -2,7 +2,7 @@ | |||
2 | * | 2 | * |
3 | * Copyright(c) 2005 - 2006 Attansic Corporation. All rights reserved. | 3 | * Copyright(c) 2005 - 2006 Attansic Corporation. All rights reserved. |
4 | * Copyright(c) 2006 - 2007 Chris Snook <csnook@redhat.com> | 4 | * Copyright(c) 2006 - 2007 Chris Snook <csnook@redhat.com> |
5 | * Copyright(c) 2006 Jay Cliburn <jcliburn@gmail.com> | 5 | * Copyright(c) 2006 - 2008 Jay Cliburn <jcliburn@gmail.com> |
6 | * Copyright(c) 2007 Atheros Corporation. All rights reserved. | 6 | * Copyright(c) 2007 Atheros Corporation. All rights reserved. |
7 | * | 7 | * |
8 | * Derived from Intel e1000 driver | 8 | * Derived from Intel e1000 driver |
diff --git a/drivers/net/atlx/atlx.h b/drivers/net/atlx/atlx.h index 3be7c09734d4..297a03da6b7f 100644 --- a/drivers/net/atlx/atlx.h +++ b/drivers/net/atlx/atlx.h | |||
@@ -2,7 +2,7 @@ | |||
2 | * | 2 | * |
3 | * Copyright(c) 2005 - 2006 Attansic Corporation. All rights reserved. | 3 | * Copyright(c) 2005 - 2006 Attansic Corporation. All rights reserved. |
4 | * Copyright(c) 2006 - 2007 Chris Snook <csnook@redhat.com> | 4 | * Copyright(c) 2006 - 2007 Chris Snook <csnook@redhat.com> |
5 | * Copyright(c) 2006 Jay Cliburn <jcliburn@gmail.com> | 5 | * Copyright(c) 2006 - 2008 Jay Cliburn <jcliburn@gmail.com> |
6 | * Copyright(c) 2007 Atheros Corporation. All rights reserved. | 6 | * Copyright(c) 2007 Atheros Corporation. All rights reserved. |
7 | * | 7 | * |
8 | * Derived from Intel e1000 driver | 8 | * Derived from Intel e1000 driver |
@@ -29,7 +29,7 @@ | |||
29 | #include <linux/module.h> | 29 | #include <linux/module.h> |
30 | #include <linux/types.h> | 30 | #include <linux/types.h> |
31 | 31 | ||
32 | #define ATLX_DRIVER_VERSION "2.1.1" | 32 | #define ATLX_DRIVER_VERSION "2.1.3" |
33 | MODULE_AUTHOR("Xiong Huang <xiong.huang@atheros.com>, \ | 33 | MODULE_AUTHOR("Xiong Huang <xiong.huang@atheros.com>, \ |
34 | Chris Snook <csnook@redhat.com>, Jay Cliburn <jcliburn@gmail.com>"); | 34 | Chris Snook <csnook@redhat.com>, Jay Cliburn <jcliburn@gmail.com>"); |
35 | MODULE_LICENSE("GPL"); | 35 | MODULE_LICENSE("GPL"); |
@@ -460,6 +460,9 @@ MODULE_VERSION(ATLX_DRIVER_VERSION); | |||
460 | #define MII_ATLX_PSSR_100MBS 0x4000 /* 01=100Mbs */ | 460 | #define MII_ATLX_PSSR_100MBS 0x4000 /* 01=100Mbs */ |
461 | #define MII_ATLX_PSSR_1000MBS 0x8000 /* 10=1000Mbs */ | 461 | #define MII_ATLX_PSSR_1000MBS 0x8000 /* 10=1000Mbs */ |
462 | 462 | ||
463 | #define MII_DBG_ADDR 0x1D | ||
464 | #define MII_DBG_DATA 0x1E | ||
465 | |||
463 | /* PCI Command Register Bit Definitions */ | 466 | /* PCI Command Register Bit Definitions */ |
464 | #define PCI_REG_COMMAND 0x04 /* PCI Command Register */ | 467 | #define PCI_REG_COMMAND 0x04 /* PCI Command Register */ |
465 | #define CMD_IO_SPACE 0x0001 | 468 | #define CMD_IO_SPACE 0x0001 |
diff --git a/drivers/net/au1000_eth.c b/drivers/net/au1000_eth.c index 3634b5fd7919..7023d77bf380 100644 --- a/drivers/net/au1000_eth.c +++ b/drivers/net/au1000_eth.c | |||
@@ -1239,12 +1239,7 @@ static int au1000_rx(struct net_device *dev) | |||
1239 | */ | 1239 | */ |
1240 | static irqreturn_t au1000_interrupt(int irq, void *dev_id) | 1240 | static irqreturn_t au1000_interrupt(int irq, void *dev_id) |
1241 | { | 1241 | { |
1242 | struct net_device *dev = (struct net_device *) dev_id; | 1242 | struct net_device *dev = dev_id; |
1243 | |||
1244 | if (dev == NULL) { | ||
1245 | printk(KERN_ERR "%s: isr: null dev ptr\n", dev->name); | ||
1246 | return IRQ_RETVAL(1); | ||
1247 | } | ||
1248 | 1243 | ||
1249 | /* Handle RX interrupts first to minimize chance of overrun */ | 1244 | /* Handle RX interrupts first to minimize chance of overrun */ |
1250 | 1245 | ||
diff --git a/drivers/net/bfin_mac.c b/drivers/net/bfin_mac.c index 89c0018132ec..41443435ab1c 100644 --- a/drivers/net/bfin_mac.c +++ b/drivers/net/bfin_mac.c | |||
@@ -22,7 +22,6 @@ | |||
22 | #include <linux/crc32.h> | 22 | #include <linux/crc32.h> |
23 | #include <linux/device.h> | 23 | #include <linux/device.h> |
24 | #include <linux/spinlock.h> | 24 | #include <linux/spinlock.h> |
25 | #include <linux/ethtool.h> | ||
26 | #include <linux/mii.h> | 25 | #include <linux/mii.h> |
27 | #include <linux/phy.h> | 26 | #include <linux/phy.h> |
28 | #include <linux/netdevice.h> | 27 | #include <linux/netdevice.h> |
diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c index 15853be4680a..367b6d462708 100644 --- a/drivers/net/bnx2.c +++ b/drivers/net/bnx2.c | |||
@@ -56,8 +56,8 @@ | |||
56 | 56 | ||
57 | #define DRV_MODULE_NAME "bnx2" | 57 | #define DRV_MODULE_NAME "bnx2" |
58 | #define PFX DRV_MODULE_NAME ": " | 58 | #define PFX DRV_MODULE_NAME ": " |
59 | #define DRV_MODULE_VERSION "1.7.4" | 59 | #define DRV_MODULE_VERSION "1.7.5" |
60 | #define DRV_MODULE_RELDATE "February 18, 2008" | 60 | #define DRV_MODULE_RELDATE "April 29, 2008" |
61 | 61 | ||
62 | #define RUN_AT(x) (jiffies + (x)) | 62 | #define RUN_AT(x) (jiffies + (x)) |
63 | 63 | ||
@@ -1631,8 +1631,10 @@ bnx2_set_default_remote_link(struct bnx2 *bp) | |||
1631 | static void | 1631 | static void |
1632 | bnx2_set_default_link(struct bnx2 *bp) | 1632 | bnx2_set_default_link(struct bnx2 *bp) |
1633 | { | 1633 | { |
1634 | if (bp->phy_flags & BNX2_PHY_FLAG_REMOTE_PHY_CAP) | 1634 | if (bp->phy_flags & BNX2_PHY_FLAG_REMOTE_PHY_CAP) { |
1635 | return bnx2_set_default_remote_link(bp); | 1635 | bnx2_set_default_remote_link(bp); |
1636 | return; | ||
1637 | } | ||
1636 | 1638 | ||
1637 | bp->autoneg = AUTONEG_SPEED | AUTONEG_FLOW_CTRL; | 1639 | bp->autoneg = AUTONEG_SPEED | AUTONEG_FLOW_CTRL; |
1638 | bp->req_line_speed = 0; | 1640 | bp->req_line_speed = 0; |
@@ -1715,7 +1717,6 @@ bnx2_remote_phy_event(struct bnx2 *bp) | |||
1715 | break; | 1717 | break; |
1716 | } | 1718 | } |
1717 | 1719 | ||
1718 | spin_lock(&bp->phy_lock); | ||
1719 | bp->flow_ctrl = 0; | 1720 | bp->flow_ctrl = 0; |
1720 | if ((bp->autoneg & (AUTONEG_SPEED | AUTONEG_FLOW_CTRL)) != | 1721 | if ((bp->autoneg & (AUTONEG_SPEED | AUTONEG_FLOW_CTRL)) != |
1721 | (AUTONEG_SPEED | AUTONEG_FLOW_CTRL)) { | 1722 | (AUTONEG_SPEED | AUTONEG_FLOW_CTRL)) { |
@@ -1737,7 +1738,6 @@ bnx2_remote_phy_event(struct bnx2 *bp) | |||
1737 | if (old_port != bp->phy_port) | 1738 | if (old_port != bp->phy_port) |
1738 | bnx2_set_default_link(bp); | 1739 | bnx2_set_default_link(bp); |
1739 | 1740 | ||
1740 | spin_unlock(&bp->phy_lock); | ||
1741 | } | 1741 | } |
1742 | if (bp->link_up != link_up) | 1742 | if (bp->link_up != link_up) |
1743 | bnx2_report_link(bp); | 1743 | bnx2_report_link(bp); |
@@ -2222,6 +2222,11 @@ bnx2_init_5709_context(struct bnx2 *bp) | |||
2222 | for (i = 0; i < bp->ctx_pages; i++) { | 2222 | for (i = 0; i < bp->ctx_pages; i++) { |
2223 | int j; | 2223 | int j; |
2224 | 2224 | ||
2225 | if (bp->ctx_blk[i]) | ||
2226 | memset(bp->ctx_blk[i], 0, BCM_PAGE_SIZE); | ||
2227 | else | ||
2228 | return -ENOMEM; | ||
2229 | |||
2225 | REG_WR(bp, BNX2_CTX_HOST_PAGE_TBL_DATA0, | 2230 | REG_WR(bp, BNX2_CTX_HOST_PAGE_TBL_DATA0, |
2226 | (bp->ctx_blk_mapping[i] & 0xffffffff) | | 2231 | (bp->ctx_blk_mapping[i] & 0xffffffff) | |
2227 | BNX2_CTX_HOST_PAGE_TBL_DATA0_VALID); | 2232 | BNX2_CTX_HOST_PAGE_TBL_DATA0_VALID); |
@@ -2445,14 +2450,15 @@ bnx2_phy_event_is_set(struct bnx2 *bp, struct bnx2_napi *bnapi, u32 event) | |||
2445 | static void | 2450 | static void |
2446 | bnx2_phy_int(struct bnx2 *bp, struct bnx2_napi *bnapi) | 2451 | bnx2_phy_int(struct bnx2 *bp, struct bnx2_napi *bnapi) |
2447 | { | 2452 | { |
2448 | if (bnx2_phy_event_is_set(bp, bnapi, STATUS_ATTN_BITS_LINK_STATE)) { | 2453 | spin_lock(&bp->phy_lock); |
2449 | spin_lock(&bp->phy_lock); | 2454 | |
2455 | if (bnx2_phy_event_is_set(bp, bnapi, STATUS_ATTN_BITS_LINK_STATE)) | ||
2450 | bnx2_set_link(bp); | 2456 | bnx2_set_link(bp); |
2451 | spin_unlock(&bp->phy_lock); | ||
2452 | } | ||
2453 | if (bnx2_phy_event_is_set(bp, bnapi, STATUS_ATTN_BITS_TIMER_ABORT)) | 2457 | if (bnx2_phy_event_is_set(bp, bnapi, STATUS_ATTN_BITS_TIMER_ABORT)) |
2454 | bnx2_set_remote_link(bp); | 2458 | bnx2_set_remote_link(bp); |
2455 | 2459 | ||
2460 | spin_unlock(&bp->phy_lock); | ||
2461 | |||
2456 | } | 2462 | } |
2457 | 2463 | ||
2458 | static inline u16 | 2464 | static inline u16 |
@@ -3174,6 +3180,12 @@ load_rv2p_fw(struct bnx2 *bp, __le32 *rv2p_code, u32 rv2p_code_len, | |||
3174 | int i; | 3180 | int i; |
3175 | u32 val; | 3181 | u32 val; |
3176 | 3182 | ||
3183 | if (rv2p_proc == RV2P_PROC2 && CHIP_NUM(bp) == CHIP_NUM_5709) { | ||
3184 | val = le32_to_cpu(rv2p_code[XI_RV2P_PROC2_MAX_BD_PAGE_LOC]); | ||
3185 | val &= ~XI_RV2P_PROC2_BD_PAGE_SIZE_MSK; | ||
3186 | val |= XI_RV2P_PROC2_BD_PAGE_SIZE; | ||
3187 | rv2p_code[XI_RV2P_PROC2_MAX_BD_PAGE_LOC] = cpu_to_le32(val); | ||
3188 | } | ||
3177 | 3189 | ||
3178 | for (i = 0; i < rv2p_code_len; i += 8) { | 3190 | for (i = 0; i < rv2p_code_len; i += 8) { |
3179 | REG_WR(bp, BNX2_RV2P_INSTR_HIGH, le32_to_cpu(*rv2p_code)); | 3191 | REG_WR(bp, BNX2_RV2P_INSTR_HIGH, le32_to_cpu(*rv2p_code)); |
@@ -4215,13 +4227,6 @@ bnx2_init_remote_phy(struct bnx2 *bp) | |||
4215 | if (netif_running(bp->dev)) { | 4227 | if (netif_running(bp->dev)) { |
4216 | u32 sig; | 4228 | u32 sig; |
4217 | 4229 | ||
4218 | if (val & BNX2_LINK_STATUS_LINK_UP) { | ||
4219 | bp->link_up = 1; | ||
4220 | netif_carrier_on(bp->dev); | ||
4221 | } else { | ||
4222 | bp->link_up = 0; | ||
4223 | netif_carrier_off(bp->dev); | ||
4224 | } | ||
4225 | sig = BNX2_DRV_ACK_CAP_SIGNATURE | | 4230 | sig = BNX2_DRV_ACK_CAP_SIGNATURE | |
4226 | BNX2_FW_CAP_REMOTE_PHY_CAPABLE; | 4231 | BNX2_FW_CAP_REMOTE_PHY_CAPABLE; |
4227 | bnx2_shmem_wr(bp, BNX2_DRV_ACK_CAP_MB, sig); | 4232 | bnx2_shmem_wr(bp, BNX2_DRV_ACK_CAP_MB, sig); |
@@ -4878,6 +4883,8 @@ bnx2_init_nic(struct bnx2 *bp) | |||
4878 | spin_lock_bh(&bp->phy_lock); | 4883 | spin_lock_bh(&bp->phy_lock); |
4879 | bnx2_init_phy(bp); | 4884 | bnx2_init_phy(bp); |
4880 | bnx2_set_link(bp); | 4885 | bnx2_set_link(bp); |
4886 | if (bp->phy_flags & BNX2_PHY_FLAG_REMOTE_PHY_CAP) | ||
4887 | bnx2_remote_phy_event(bp); | ||
4881 | spin_unlock_bh(&bp->phy_lock); | 4888 | spin_unlock_bh(&bp->phy_lock); |
4882 | return 0; | 4889 | return 0; |
4883 | } | 4890 | } |
@@ -4920,7 +4927,7 @@ bnx2_test_registers(struct bnx2 *bp) | |||
4920 | { 0x0c08, BNX2_FL_NOT_5709, 0x0f0ff073, 0x00000000 }, | 4927 | { 0x0c08, BNX2_FL_NOT_5709, 0x0f0ff073, 0x00000000 }, |
4921 | 4928 | ||
4922 | { 0x1000, 0, 0x00000000, 0x00000001 }, | 4929 | { 0x1000, 0, 0x00000000, 0x00000001 }, |
4923 | { 0x1004, 0, 0x00000000, 0x000f0001 }, | 4930 | { 0x1004, BNX2_FL_NOT_5709, 0x00000000, 0x000f0001 }, |
4924 | 4931 | ||
4925 | { 0x1408, 0, 0x01c00800, 0x00000000 }, | 4932 | { 0x1408, 0, 0x01c00800, 0x00000000 }, |
4926 | { 0x149c, 0, 0x8000ffff, 0x00000000 }, | 4933 | { 0x149c, 0, 0x8000ffff, 0x00000000 }, |
@@ -5717,14 +5724,12 @@ bnx2_reset_task(struct work_struct *work) | |||
5717 | if (!netif_running(bp->dev)) | 5724 | if (!netif_running(bp->dev)) |
5718 | return; | 5725 | return; |
5719 | 5726 | ||
5720 | bp->in_reset_task = 1; | ||
5721 | bnx2_netif_stop(bp); | 5727 | bnx2_netif_stop(bp); |
5722 | 5728 | ||
5723 | bnx2_init_nic(bp); | 5729 | bnx2_init_nic(bp); |
5724 | 5730 | ||
5725 | atomic_set(&bp->intr_sem, 1); | 5731 | atomic_set(&bp->intr_sem, 1); |
5726 | bnx2_netif_start(bp); | 5732 | bnx2_netif_start(bp); |
5727 | bp->in_reset_task = 0; | ||
5728 | } | 5733 | } |
5729 | 5734 | ||
5730 | static void | 5735 | static void |
@@ -5900,12 +5905,7 @@ bnx2_close(struct net_device *dev) | |||
5900 | struct bnx2 *bp = netdev_priv(dev); | 5905 | struct bnx2 *bp = netdev_priv(dev); |
5901 | u32 reset_code; | 5906 | u32 reset_code; |
5902 | 5907 | ||
5903 | /* Calling flush_scheduled_work() may deadlock because | 5908 | cancel_work_sync(&bp->reset_task); |
5904 | * linkwatch_event() may be on the workqueue and it will try to get | ||
5905 | * the rtnl_lock which we are holding. | ||
5906 | */ | ||
5907 | while (bp->in_reset_task) | ||
5908 | msleep(1); | ||
5909 | 5909 | ||
5910 | bnx2_disable_int_sync(bp); | 5910 | bnx2_disable_int_sync(bp); |
5911 | bnx2_napi_disable(bp); | 5911 | bnx2_napi_disable(bp); |
diff --git a/drivers/net/bnx2.h b/drivers/net/bnx2.h index 1eaf5bb3d9c2..2377cc13bf61 100644 --- a/drivers/net/bnx2.h +++ b/drivers/net/bnx2.h | |||
@@ -6656,7 +6656,6 @@ struct bnx2 { | |||
6656 | int current_interval; | 6656 | int current_interval; |
6657 | struct timer_list timer; | 6657 | struct timer_list timer; |
6658 | struct work_struct reset_task; | 6658 | struct work_struct reset_task; |
6659 | int in_reset_task; | ||
6660 | 6659 | ||
6661 | /* Used to synchronize phy accesses. */ | 6660 | /* Used to synchronize phy accesses. */ |
6662 | spinlock_t phy_lock; | 6661 | spinlock_t phy_lock; |
diff --git a/drivers/net/bnx2_fw2.h b/drivers/net/bnx2_fw2.h index e6ffa2769f3d..ed0514cba0ee 100644 --- a/drivers/net/bnx2_fw2.h +++ b/drivers/net/bnx2_fw2.h | |||
@@ -3173,251 +3173,267 @@ static struct fw_info bnx2_rxp_fw_09 = { | |||
3173 | }; | 3173 | }; |
3174 | 3174 | ||
3175 | static u8 bnx2_xi_rv2p_proc1[] = { | 3175 | static u8 bnx2_xi_rv2p_proc1[] = { |
3176 | /* Date: 01/14/2008 15:44 */ | 3176 | /* Date: 04/25/2008 22:02 */ |
3177 | 0xc5, 0x56, 0xcd, 0x6b, 0x13, 0x51, 0x10, 0x9f, 0xdd, 0x7c, 0x6c, 0x9a, | 3177 | 0xbd, 0x56, 0x4f, 0x68, 0x1c, 0x55, 0x18, 0xff, 0x76, 0x76, 0x77, 0x66, |
3178 | 0x6c, 0xb2, 0xa1, 0x6a, 0x09, 0x35, 0xd2, 0x58, 0x7a, 0x30, 0x6d, 0xc4, | 3178 | 0x33, 0x3b, 0xbb, 0xb3, 0xd8, 0x34, 0x4c, 0xb7, 0x2b, 0x59, 0x83, 0x97, |
3179 | 0x56, 0x3d, 0x78, 0x28, 0x54, 0x7a, 0x11, 0xac, 0xa7, 0x1e, 0x44, 0xc4, | 3179 | 0xdd, 0x6c, 0x69, 0xa2, 0x15, 0x04, 0x53, 0x5a, 0x72, 0x09, 0xd8, 0x9e, |
3180 | 0xcf, 0x20, 0x05, 0xf5, 0x8f, 0x70, 0x51, 0xab, 0x20, 0x78, 0x28, 0x68, | 3180 | 0x02, 0xb5, 0x52, 0x84, 0xb6, 0x8b, 0xf4, 0x52, 0x5a, 0x28, 0x78, 0x11, |
3181 | 0xb4, 0x7e, 0xa0, 0x27, 0x15, 0xf1, 0x90, 0x1c, 0x04, 0x05, 0x45, 0x50, | 3181 | 0x84, 0x0e, 0x6d, 0x93, 0x82, 0xe8, 0x61, 0xc1, 0x06, 0x12, 0x44, 0xa3, |
3182 | 0xf0, 0xa4, 0x37, 0x41, 0xbd, 0x54, 0xc5, 0x0f, 0xf0, 0xe2, 0x45, 0x8f, | 3182 | 0x07, 0x95, 0x60, 0x61, 0x07, 0x3c, 0x78, 0x10, 0x14, 0x15, 0x11, 0x6c, |
3183 | 0xda, 0xf8, 0xde, 0xcc, 0xef, 0xd9, 0xdd, 0x4d, 0xd2, 0x14, 0x0f, 0x1a, | 3183 | 0x0f, 0x85, 0x88, 0xf6, 0xd2, 0x54, 0x4b, 0x0b, 0x1e, 0x5b, 0x3c, 0xd6, |
3184 | 0x68, 0x7f, 0xec, 0xdb, 0xdf, 0x9b, 0x37, 0xf3, 0x9b, 0x79, 0x33, 0x9b, | 3184 | 0x8c, 0xef, 0xfb, 0xf3, 0x92, 0x99, 0x97, 0x9d, 0x24, 0xa7, 0x2e, 0xb4, |
3185 | 0x27, 0x22, 0x9b, 0xfc, 0xc6, 0x80, 0x42, 0x72, 0xad, 0x58, 0x4a, 0x81, | 3185 | 0x3f, 0xbe, 0x37, 0xdf, 0xbf, 0xf7, 0xfd, 0xf9, 0xbd, 0xd4, 0x00, 0xc0, |
3186 | 0x45, 0x74, 0xcf, 0x65, 0xf4, 0x37, 0x91, 0xfc, 0x46, 0x04, 0xfc, 0x91, | 3186 | 0x82, 0x30, 0x1a, 0x55, 0x08, 0x65, 0x2b, 0x5f, 0x52, 0x90, 0x03, 0xf8, |
3187 | 0xbc, 0xfa, 0xff, 0x9d, 0x26, 0x4a, 0x1a, 0x63, 0x34, 0xb1, 0x5e, 0xe3, | 3187 | 0x1a, 0xf8, 0x57, 0xf4, 0x48, 0x0e, 0x0f, 0x8a, 0x3c, 0xce, 0x10, 0x8e, |
3188 | 0x24, 0x3d, 0x29, 0x15, 0x14, 0xfe, 0x6a, 0x92, 0xaf, 0x9f, 0x87, 0xea, | 3188 | 0xd7, 0xd4, 0xff, 0x17, 0xe0, 0x48, 0x13, 0x31, 0x0f, 0x47, 0x5e, 0x40, |
3189 | 0x0f, 0x1a, 0x19, 0xb6, 0xfb, 0x0e, 0xfb, 0xdf, 0xc4, 0x04, 0xb7, 0x55, | 3189 | 0x3c, 0x0c, 0xdf, 0x37, 0x03, 0x85, 0xff, 0xc5, 0x10, 0xa2, 0x3c, 0xdc, |
3190 | 0x52, 0x62, 0x07, 0x48, 0x1b, 0xf3, 0x0c, 0xaf, 0xe6, 0xf4, 0x73, 0xd1, | 3190 | 0xff, 0x36, 0x2a, 0x93, 0xff, 0x35, 0xb1, 0xff, 0x33, 0xcf, 0xf8, 0x6a, |
3191 | 0xf2, 0x37, 0xe2, 0x7c, 0x5b, 0xd6, 0x17, 0xe6, 0x3c, 0xbd, 0x4e, 0xef, | 3191 | 0xa7, 0xc4, 0x7e, 0x04, 0xe1, 0x40, 0x8d, 0x60, 0xb5, 0x87, 0xf2, 0x89, |
3192 | 0x27, 0xf5, 0xb3, 0x97, 0x3e, 0xdd, 0x48, 0xb1, 0x5d, 0x79, 0xdf, 0x9b, | 3192 | 0x13, 0x60, 0xa3, 0x9f, 0x4f, 0x94, 0x02, 0xca, 0x8d, 0x5c, 0x78, 0x40, |
3193 | 0x3e, 0xcd, 0xfb, 0x5c, 0x4b, 0xec, 0xa9, 0x3f, 0xde, 0xbf, 0x55, 0xd9, | 3193 | 0xf2, 0xb2, 0x58, 0xef, 0x5e, 0xcf, 0xc7, 0x73, 0xb8, 0x3f, 0x8d, 0xf2, |
3194 | 0x81, 0xdf, 0x24, 0x76, 0x0e, 0x96, 0xf4, 0xfa, 0x76, 0xf0, 0xc6, 0xc1, | 3194 | 0x3e, 0xf7, 0x5a, 0x0f, 0x31, 0x80, 0x73, 0x25, 0x8f, 0xef, 0x33, 0xca, |
3195 | 0x2b, 0xb6, 0xf0, 0x16, 0xe6, 0x34, 0x3a, 0x54, 0xad, 0xe8, 0x78, 0x06, | 3195 | 0x6e, 0xd7, 0xda, 0x68, 0xa7, 0x74, 0xdb, 0xe2, 0xb7, 0x88, 0x7e, 0xff, |
3196 | 0x49, 0xe2, 0x49, 0xd0, 0x4c, 0xca, 0x15, 0x9d, 0x06, 0x84, 0xfd, 0x6e, | 3196 | 0x89, 0xd9, 0x2f, 0xfa, 0x4b, 0xfa, 0x69, 0x28, 0x3f, 0x78, 0x6e, 0x4b, |
3197 | 0x58, 0xef, 0x57, 0xbe, 0x0d, 0x6b, 0xde, 0x82, 0x8a, 0xdb, 0xc4, 0x1b, | 3197 | 0x5e, 0xb6, 0x91, 0x97, 0xad, 0xf2, 0x90, 0x3a, 0x80, 0xce, 0x03, 0x71, |
3198 | 0xe6, 0x39, 0x15, 0x63, 0x57, 0xf3, 0xde, 0x2a, 0x9e, 0x89, 0x2f, 0x18, | 3198 | 0xaf, 0x8a, 0x8b, 0x7e, 0x1f, 0xcb, 0xbd, 0x01, 0x4e, 0x37, 0xc5, 0x7f, |
3199 | 0x57, 0x26, 0x10, 0x57, 0x24, 0xde, 0x96, 0xf8, 0x82, 0x7a, 0xa5, 0xda, | 3199 | 0x84, 0xe8, 0xe5, 0xd8, 0x9f, 0xfa, 0x27, 0xf7, 0xd8, 0xea, 0x47, 0xd7, |
3200 | 0xf8, 0xaf, 0xcf, 0x51, 0xbe, 0xf0, 0x39, 0x49, 0xe8, 0x9c, 0x8c, 0xec, | 3200 | 0x29, 0x9d, 0xbf, 0xd3, 0xd1, 0xdf, 0x75, 0x3f, 0x30, 0xce, 0x1d, 0x15, |
3201 | 0x4b, 0x76, 0x88, 0xfb, 0x93, 0x35, 0xb3, 0x21, 0xec, 0x3f, 0x91, 0xb6, | 3201 | 0x27, 0xa9, 0x0f, 0x3b, 0xe8, 0xff, 0xa6, 0xf4, 0xd3, 0x7e, 0xf9, 0xfc, |
3202 | 0xf7, 0x54, 0xf9, 0x8d, 0xf5, 0x72, 0x3b, 0x1d, 0x12, 0xd0, 0xe1, 0x31, | 3202 | 0xd7, 0xcd, 0xf3, 0xd6, 0xa0, 0xba, 0x15, 0x8d, 0xba, 0xfd, 0x28, 0x75, |
3203 | 0xe2, 0x9b, 0xa2, 0x21, 0xbb, 0xc0, 0xef, 0xe3, 0xbc, 0x7f, 0xad, 0xf2, | 3203 | 0x9b, 0x81, 0x17, 0xad, 0x80, 0xf4, 0x0a, 0x80, 0xb8, 0x5f, 0x25, 0x80, |
3204 | 0x47, 0xe3, 0x3a, 0xe0, 0x7a, 0xe0, 0x01, 0xe0, 0x7e, 0xe0, 0x1a, 0xe0, | 3204 | 0xf8, 0xbc, 0xe0, 0x45, 0xc1, 0xcf, 0x04, 0x97, 0x05, 0xf7, 0x0a, 0x0e, |
3205 | 0x6a, 0xe0, 0x2a, 0x60, 0x2f, 0xf0, 0x32, 0x30, 0x0f, 0xf4, 0x80, 0x39, | 3205 | 0x0b, 0xee, 0x11, 0x7c, 0x4e, 0xf0, 0x6f, 0xc1, 0x9a, 0xa0, 0x2f, 0x58, |
3206 | 0xe0, 0x05, 0xa0, 0x0b, 0xcc, 0x00, 0x6b, 0xc0, 0xab, 0xc0, 0x14, 0xf0, | 3206 | 0x15, 0xbc, 0x27, 0xe8, 0x09, 0x96, 0x0d, 0x7f, 0x75, 0xc1, 0x92, 0x60, |
3207 | 0x28, 0xf0, 0x21, 0xf0, 0x31, 0xf0, 0x0b, 0xf0, 0x1c, 0xd0, 0xb1, 0x60, | 3207 | 0x24, 0xf8, 0x9a, 0x61, 0xef, 0xe6, 0x18, 0x57, 0x45, 0x3e, 0x28, 0xf2, |
3208 | 0x0f, 0xa8, 0x7e, 0x3e, 0xee, 0x47, 0x48, 0xa7, 0xeb, 0xa8, 0x7f, 0xad, | 3208 | 0x49, 0x91, 0xb1, 0xa0, 0x32, 0xf7, 0xa9, 0x7a, 0x7d, 0xbe, 0xd1, 0xdf, |
3209 | 0x33, 0xde, 0x97, 0x0d, 0x0f, 0xf9, 0x65, 0x9d, 0x2e, 0x83, 0xd7, 0x5b, | 3209 | 0xd5, 0x9e, 0x7c, 0x6f, 0x69, 0xbd, 0x12, 0xd5, 0x0f, 0xda, 0x49, 0xfd, |
3210 | 0xbf, 0x19, 0xb9, 0x27, 0xa5, 0xae, 0xf7, 0x23, 0x9a, 0x37, 0x8f, 0xe3, | 3210 | 0x8f, 0xb7, 0xd1, 0x67, 0xb5, 0xe9, 0xd6, 0x20, 0xbb, 0x1b, 0x31, 0xe7, |
3211 | 0x39, 0xb4, 0xc3, 0xe3, 0x73, 0x72, 0x49, 0x59, 0x37, 0x6e, 0xed, 0xf1, | 3211 | 0xf1, 0x91, 0xd8, 0x07, 0xfd, 0xef, 0x32, 0xf6, 0x68, 0xaa, 0x63, 0xce, |
3212 | 0x04, 0x8f, 0xa4, 0x05, 0x3f, 0xa7, 0x7b, 0xd4, 0xff, 0x66, 0x73, 0x26, | 3212 | 0xd7, 0xa0, 0x3d, 0x7a, 0x45, 0xf6, 0xe8, 0xd0, 0x96, 0xf9, 0xe5, 0x39, |
3213 | 0x23, 0xcf, 0x87, 0xb3, 0x46, 0x67, 0x63, 0xc7, 0xf8, 0xd3, 0xcd, 0x8f, | 3213 | 0x3d, 0x2a, 0xf6, 0x53, 0x32, 0x9f, 0x8d, 0x0c, 0xbd, 0x30, 0xb1, 0xaf, |
3214 | 0x4e, 0xe7, 0x19, 0xbf, 0xba, 0x9d, 0x2b, 0x58, 0xb5, 0xc3, 0xf1, 0x5f, | 3214 | 0x14, 0x2f, 0x63, 0x1f, 0x6e, 0xe6, 0xba, 0x1d, 0x8c, 0x5b, 0x94, 0xb8, |
3215 | 0x19, 0x15, 0x8c, 0x8f, 0x31, 0x54, 0xdc, 0x64, 0x5c, 0xe3, 0x56, 0xf7, | 3215 | 0x59, 0xf9, 0xa1, 0xbd, 0xcc, 0x6f, 0x4b, 0xcf, 0x71, 0x7a, 0x7e, 0x79, |
3216 | 0xb9, 0x39, 0x47, 0xa3, 0x5b, 0xa8, 0xf1, 0x7d, 0x89, 0x53, 0x2d, 0xa9, | 3216 | 0x0e, 0x6d, 0x63, 0x0e, 0x2f, 0xed, 0xd0, 0x87, 0xb2, 0x51, 0xcf, 0xf3, |
3217 | 0xed, 0xfe, 0x6c, 0x9e, 0x17, 0x5e, 0xff, 0xe1, 0x97, 0x8c, 0x85, 0x2b, | 3217 | 0x4a, 0x9f, 0x45, 0xcb, 0x62, 0x5c, 0x62, 0xec, 0x78, 0x76, 0x01, 0xf1, |
3218 | 0x2f, 0x84, 0xff, 0xba, 0xe4, 0x32, 0xee, 0x1e, 0xa1, 0xc8, 0xcf, 0xbc, | 3218 | 0x90, 0xf7, 0x0b, 0xfb, 0x1b, 0xa5, 0x7b, 0x78, 0xc1, 0x02, 0xed, 0x6d, |
3219 | 0x97, 0xfb, 0xe8, 0xb3, 0xdf, 0x3f, 0x2c, 0xbf, 0x61, 0xce, 0xc1, 0xbe, | 3219 | 0x01, 0x16, 0xec, 0x21, 0x85, 0x4f, 0xe3, 0x0f, 0x59, 0xaf, 0x5e, 0xbc, |
3220 | 0xe3, 0x26, 0x8f, 0x79, 0xf6, 0x73, 0x90, 0xe4, 0x79, 0xba, 0x2c, 0xef, | 3220 | 0x4d, 0x18, 0x2c, 0xdd, 0x62, 0xfd, 0x3f, 0x9a, 0x9c, 0xf7, 0x1b, 0xe3, |
3221 | 0xa7, 0xcb, 0xb8, 0xcf, 0x83, 0xe1, 0x7a, 0x90, 0x7b, 0x11, 0x43, 0xbe, | 3221 | 0x60, 0xfc, 0xf4, 0x77, 0xd9, 0x77, 0x1f, 0xe5, 0x7f, 0x73, 0x61, 0xa4, |
3222 | 0xf7, 0xe2, 0x5e, 0x44, 0xef, 0x71, 0xaa, 0x7e, 0x73, 0x2e, 0x58, 0x2f, | 3222 | 0xe3, 0x88, 0xdd, 0x79, 0xbd, 0x47, 0xfc, 0xbb, 0x62, 0xd7, 0xa8, 0x6e, |
3223 | 0x05, 0xaa, 0x8e, 0xc1, 0x9f, 0x96, 0x3c, 0x9b, 0xbe, 0x6c, 0xea, 0x9d, | 3223 | 0xef, 0x47, 0x24, 0x0e, 0x7b, 0xf3, 0xcc, 0xaf, 0x1f, 0x44, 0xfa, 0x3e, |
3224 | 0x97, 0xeb, 0x7e, 0x2c, 0xa4, 0xdf, 0x76, 0xaa, 0x04, 0xf3, 0x64, 0xb5, | 3224 | 0xc2, 0x2b, 0x6d, 0xb6, 0xab, 0x50, 0x9c, 0x3d, 0xfd, 0x65, 0x63, 0x3e, |
3225 | 0xa9, 0x97, 0x6e, 0xe7, 0x84, 0xec, 0xe5, 0x54, 0x06, 0xa8, 0xb5, 0x8e, | 3225 | 0x9a, 0xbb, 0xe2, 0xd7, 0x27, 0xf1, 0x26, 0xbf, 0x26, 0xef, 0xaf, 0xf9, |
3226 | 0x1d, 0xc4, 0x35, 0x81, 0x3a, 0x5e, 0xdb, 0x52, 0xc7, 0xa6, 0xdf, 0x4b, | 3226 | 0xb5, 0x04, 0x67, 0x66, 0x7c, 0x8a, 0x57, 0xb5, 0xd9, 0xcd, 0x9b, 0x3e, |
3227 | 0x3d, 0x77, 0xea, 0x5f, 0x7f, 0xdf, 0xa7, 0x85, 0xe7, 0x07, 0xea, 0xd3, | 3227 | 0xe3, 0xdb, 0x2e, 0xe3, 0x43, 0x17, 0xeb, 0x13, 0xc7, 0xe7, 0xca, 0x2c, |
3228 | 0xf4, 0x43, 0xe8, 0xe4, 0x30, 0xaf, 0xb8, 0x70, 0x5f, 0xf2, 0x26, 0xfd, | 3228 | 0x9f, 0xad, 0xe8, 0xbd, 0xd6, 0xf6, 0x3a, 0xaf, 0xed, 0xf2, 0xc1, 0xf8, |
3229 | 0x5c, 0x15, 0xa3, 0x1f, 0xf6, 0xd3, 0x31, 0xf1, 0x0d, 0x04, 0xfb, 0xe7, | 3229 | 0x3a, 0x8e, 0xce, 0x43, 0xc7, 0x4b, 0xcf, 0x43, 0x76, 0x5c, 0xc6, 0xae, |
3230 | 0x50, 0x87, 0x7c, 0x05, 0xfb, 0x6e, 0x54, 0x97, 0x70, 0xdd, 0x4b, 0xfe, | 3230 | 0x95, 0xae, 0xc3, 0xd2, 0x04, 0x63, 0x61, 0x12, 0xf3, 0xfa, 0x21, 0xde, |
3231 | 0xd3, 0xd0, 0xa9, 0xbf, 0x4b, 0x5f, 0xe8, 0x01, 0x6f, 0xcd, 0x32, 0x3c, | 3231 | 0xd8, 0xeb, 0x56, 0x8d, 0xf4, 0xc6, 0x80, 0xe5, 0x59, 0x99, 0xbf, 0x59, |
3232 | 0xb1, 0x3b, 0x59, 0x0e, 0xf6, 0x11, 0xaf, 0x89, 0xfe, 0x87, 0x7d, 0x7d, | 3232 | 0xda, 0x47, 0xc5, 0x37, 0x16, 0x62, 0x1d, 0x42, 0x7a, 0x6f, 0x2c, 0xf7, |
3233 | 0xf5, 0x47, 0x1d, 0xf2, 0x30, 0xfe, 0x7f, 0xf3, 0x80, 0xf9, 0x52, 0xb4, | 3233 | 0x67, 0x9a, 0x87, 0xbc, 0x9c, 0xab, 0xfa, 0x8f, 0xa5, 0xf7, 0x78, 0x8d, |
3234 | 0x24, 0x0f, 0x09, 0x5a, 0x99, 0xbe, 0x84, 0xf8, 0xa9, 0x83, 0xbe, 0x49, | 3234 | 0xe7, 0xad, 0x94, 0x9e, 0xd3, 0x46, 0x3c, 0x78, 0xfe, 0xdd, 0xfe, 0x72, |
3235 | 0xe8, 0xf0, 0x6d, 0x71, 0x79, 0x7d, 0x33, 0xe0, 0x7d, 0x0d, 0xf0, 0xb8, | 3235 | 0x6f, 0x50, 0x3f, 0x74, 0x7e, 0x01, 0x74, 0x27, 0xb3, 0xde, 0x09, 0xfd, |
3236 | 0x2e, 0xc6, 0xe5, 0xfe, 0x39, 0xd5, 0x2f, 0x11, 0xdd, 0xc6, 0x2a, 0xba, | 3236 | 0x3e, 0x6b, 0x9e, 0xa4, 0xe3, 0x7e, 0x98, 0x4f, 0xdd, 0xfb, 0x28, 0x74, |
3237 | 0xaf, 0x9c, 0xa0, 0x06, 0xe2, 0x7a, 0x1b, 0x8a, 0x2f, 0xab, 0xfc, 0x93, | 3237 | 0x06, 0xf9, 0xff, 0x46, 0xbf, 0x7b, 0x03, 0xf6, 0x76, 0xa7, 0xb8, 0x29, |
3238 | 0xef, 0x84, 0x3b, 0x0d, 0xa3, 0x83, 0xbc, 0x2e, 0x55, 0x04, 0x6f, 0x33, | 3238 | 0xff, 0x55, 0xb5, 0x39, 0xb0, 0x75, 0xef, 0x1c, 0x63, 0x4f, 0x9f, 0xae, |
3239 | 0x3f, 0x1f, 0xd0, 0x23, 0xac, 0x9b, 0xe8, 0x91, 0xa7, 0x5b, 0x7f, 0xfa, | 3239 | 0xf3, 0x9e, 0x36, 0xb6, 0xcc, 0xa7, 0xe6, 0xaf, 0xe6, 0xb6, 0xfc, 0xf5, |
3240 | 0x8d, 0xc7, 0xf6, 0x46, 0xd1, 0xaf, 0x0f, 0xa1, 0x6f, 0x7e, 0x48, 0x4b, | 3240 | 0xac, 0xf8, 0xca, 0x02, 0xe6, 0x2b, 0x7c, 0x4f, 0xd2, 0x79, 0x3a, 0xfa, |
3241 | 0x5f, 0xae, 0x4e, 0x71, 0xff, 0xa4, 0x3e, 0xf4, 0xcf, 0x6a, 0x56, 0x9e, | 3241 | 0x9e, 0x06, 0x2f, 0xf1, 0xfd, 0xee, 0xaf, 0xef, 0x8e, 0xdf, 0x92, 0x75, |
3242 | 0xfb, 0xb3, 0xf2, 0x1d, 0x36, 0xea, 0xb8, 0xcc, 0xeb, 0xcf, 0x0a, 0xf6, | 3242 | 0x1a, 0xc4, 0x6f, 0xae, 0xc1, 0x57, 0xbf, 0xaf, 0x6f, 0xf2, 0x1b, 0x7e, |
3243 | 0x65, 0xf4, 0xbe, 0x02, 0x7d, 0xdc, 0xc5, 0xf4, 0xca, 0xbc, 0x2b, 0x7d, | 3243 | 0x5f, 0x59, 0xe1, 0xfe, 0xbd, 0x97, 0x98, 0xdf, 0x64, 0xdd, 0x87, 0xa4, |
3244 | 0x74, 0xfe, 0x05, 0xfa, 0xba, 0x67, 0x74, 0x42, 0xbc, 0x5b, 0xf4, 0x7a, | 3244 | 0xee, 0x4a, 0x8f, 0xec, 0x6f, 0x1b, 0xf6, 0xba, 0xff, 0xef, 0x08, 0x6f, |
3245 | 0x1f, 0x7f, 0xf2, 0x2c, 0xe9, 0xab, 0x38, 0xc3, 0xe2, 0xdf, 0x0d, 0x78, | 3245 | 0x5a, 0x53, 0x3c, 0x7f, 0x4e, 0xf7, 0x91, 0xd1, 0x97, 0xc9, 0x0e, 0xee, |
3246 | 0x5f, 0x32, 0xfb, 0x06, 0xb4, 0x9e, 0x4f, 0x16, 0xcd, 0xdc, 0x18, 0xdc, | 3246 | 0xd5, 0x65, 0x88, 0xa4, 0x6e, 0x77, 0x53, 0xf5, 0xab, 0x08, 0x4f, 0x38, |
3247 | 0xa1, 0xfd, 0xf1, 0x28, 0xe7, 0x48, 0x3e, 0x05, 0x15, 0xcf, 0x76, 0xf4, | 3247 | 0xf0, 0x55, 0xa4, 0xeb, 0xac, 0xfb, 0xc8, 0xf8, 0x25, 0xe9, 0xd7, 0x76, |
3248 | 0xb6, 0xe2, 0xac, 0x2d, 0xcf, 0xb3, 0x27, 0xd9, 0xcc, 0xae, 0x59, 0xb3, | 3248 | 0xa8, 0x77, 0x0d, 0xbe, 0xd8, 0xe0, 0x41, 0x9f, 0xfc, 0x4d, 0x08, 0xaf, |
3249 | 0x3e, 0xc9, 0x05, 0x3a, 0x7d, 0xf7, 0x19, 0xaf, 0xe7, 0x1a, 0x31, 0x59, | 3249 | 0x9c, 0x91, 0xfd, 0xfe, 0xcb, 0x65, 0xfe, 0xe8, 0x1e, 0xa3, 0x3d, 0x87, |
3250 | 0x77, 0xa6, 0x8c, 0x1e, 0x1e, 0xc7, 0x57, 0x13, 0x3d, 0xf6, 0x5d, 0x14, | 3250 | 0x11, 0xd9, 0xf3, 0x6e, 0x85, 0xe5, 0x7a, 0x85, 0x79, 0x71, 0xc2, 0xf1, |
3251 | 0xdc, 0x4b, 0x3b, 0x19, 0xd3, 0x35, 0x57, 0xe6, 0xca, 0xbc, 0x9b, 0x62, | 3251 | 0x48, 0xaf, 0x5e, 0x61, 0x1c, 0x29, 0xa3, 0x5d, 0x00, 0x0f, 0x8e, 0x93, |
3252 | 0x24, 0xd6, 0xc3, 0xde, 0x2c, 0xf3, 0x21, 0x81, 0xbe, 0xde, 0x13, 0xc8, | 3252 | 0x7a, 0x67, 0xd1, 0x63, 0x7e, 0x5f, 0xbc, 0x25, 0xfc, 0xe3, 0xeb, 0xfa, |
3253 | 0x53, 0x74, 0xde, 0xae, 0x34, 0x5f, 0xc1, 0x39, 0x60, 0xe6, 0x43, 0xb4, | 3253 | 0xc9, 0x7d, 0x5f, 0xc6, 0xf3, 0x11, 0xb5, 0xcf, 0xc9, 0x7e, 0x28, 0x9d, |
3254 | 0xdf, 0x67, 0x51, 0x67, 0xd7, 0xba, 0xd4, 0xa3, 0xe9, 0x9f, 0x97, 0x16, | 3254 | 0x36, 0xe7, 0xf7, 0xa9, 0x64, 0xdf, 0xf4, 0x93, 0xf5, 0xd6, 0xf3, 0xbd, |
3255 | 0xe5, 0x1e, 0xb4, 0x9b, 0xb3, 0x1a, 0x73, 0x1d, 0xbe, 0x0f, 0x8a, 0xa8, | 3255 | 0x9c, 0xd1, 0xa7, 0x99, 0x58, 0xf3, 0xdf, 0xd8, 0x0c, 0xe6, 0xeb, 0x43, |
3256 | 0x3f, 0x33, 0x0f, 0xdb, 0x7d, 0x07, 0x08, 0x7f, 0x65, 0xf3, 0x3f, 0xdf, | 3256 | 0xd5, 0xe1, 0xf9, 0x60, 0x54, 0x7e, 0x2c, 0x07, 0xcd, 0x1a, 0x73, 0xc2, |
3257 | 0x61, 0xfe, 0xff, 0xb3, 0x39, 0x5f, 0x58, 0xca, 0xa3, 0xa9, 0xd3, 0x60, | 3257 | 0x27, 0x73, 0x57, 0xc8, 0xcd, 0xf1, 0x39, 0x7d, 0x3e, 0x4d, 0x0b, 0x32, |
3258 | 0x1e, 0x83, 0xf5, 0x1a, 0x9d, 0xc3, 0xcb, 0xcd, 0xdf, 0x1c, 0x74, 0x3e, | 3258 | 0xbb, 0xf2, 0x13, 0x9d, 0x57, 0xa3, 0x3c, 0x9f, 0x3b, 0xc7, 0x74, 0xbd, |
3259 | 0x06, 0x9d, 0xe3, 0x94, 0x88, 0xb1, 0x30, 0x6e, 0xfc, 0x14, 0xdb, 0xb5, | 3259 | 0x7c, 0xba, 0xff, 0x02, 0xd7, 0xeb, 0xad, 0x1b, 0x8c, 0xa7, 0xe0, 0x75, |
3260 | 0x67, 0x6d, 0xa6, 0xbb, 0x89, 0x33, 0x96, 0xc6, 0x9c, 0x7b, 0x46, 0x78, | 3260 | 0x42, 0x77, 0xc1, 0x63, 0x7e, 0x5c, 0xf4, 0x4a, 0x84, 0x40, 0xf5, 0xb2, |
3261 | 0x71, 0x59, 0x2f, 0x18, 0x3c, 0x7b, 0x4a, 0xbe, 0xfb, 0x6c, 0xfa, 0x0d, | 3261 | 0x5e, 0xe2, 0x77, 0xad, 0x28, 0xef, 0xd1, 0x50, 0xa2, 0x8f, 0xe6, 0xfb, |
3262 | 0x6d, 0x29, 0x98, 0xe1, 0x30, 0x0d, 0x00, 0x00, 0x00 }; | 3262 | 0xb1, 0xdb, 0x7e, 0x26, 0xf9, 0x54, 0xbf, 0x6b, 0x39, 0xe3, 0xef, 0xc8, |
3263 | 0x8a, 0x31, 0x9f, 0xef, 0x66, 0xcc, 0x67, 0x33, 0x63, 0xbe, 0x4d, 0x5e, | ||
3264 | 0xb9, 0x24, 0x7b, 0x57, 0x80, 0x62, 0x9e, 0x1e, 0x26, 0xaf, 0x70, 0x95, | ||
3265 | 0xfa, 0x6b, 0xcd, 0xf1, 0xbb, 0xee, 0x15, 0xe7, 0x73, 0x54, 0x37, 0x6f, | ||
3266 | 0x9e, 0xf5, 0x0a, 0x7c, 0x1e, 0x68, 0xbc, 0x7e, 0x95, 0xdf, 0x4f, 0x0b, | ||
3267 | 0xfe, 0x07, 0x89, 0x6e, 0x1e, 0x13, 0x00, 0x0d, 0x00, 0x00, 0x00 }; | ||
3263 | 3268 | ||
3264 | static u8 bnx2_xi_rv2p_proc2[] = { | 3269 | static u8 bnx2_xi_rv2p_proc2[] = { |
3265 | /* Date: 01/14/2008 15:44 */ | 3270 | /* Date: 04/25/2008 22:02 */ |
3266 | 0xad, 0x58, 0x5d, 0x6c, 0xd3, 0x55, 0x14, 0xbf, 0xfd, 0x58, 0xdb, 0x75, | 3271 | #define XI_RV2P_PROC2_MAX_BD_PAGE_LOC 5 |
3267 | 0xff, 0xb6, 0x63, 0x9b, 0xdd, 0xa7, 0x6e, 0x6e, 0x61, 0x6c, 0xd8, 0xcd, | 3272 | #define XI_RV2P_PROC2_BD_PAGE_SIZE_MSK 0xffff |
3268 | 0xd1, 0x8d, 0x4f, 0x4d, 0x5c, 0x86, 0x19, 0x20, 0x26, 0x8c, 0x61, 0xd4, | 3273 | #define XI_RV2P_PROC2_BD_PAGE_SIZE ((PAGE_SIZE / 16) - 1) |
3269 | 0x37, 0xd8, 0x90, 0xb2, 0xb2, 0x8d, 0x2c, 0x8c, 0xf0, 0xc0, 0x8b, 0x0d, | 3274 | 0xad, 0x58, 0x5b, 0x6c, 0x54, 0x55, 0x14, 0x3d, 0xf3, 0xe8, 0xcc, 0xed, |
3270 | 0xd3, 0xf1, 0xd2, 0x07, 0x47, 0xb2, 0x0d, 0x8d, 0xc1, 0x45, 0x7d, 0x40, | 3275 | 0xcc, 0x9d, 0x99, 0xd2, 0xd6, 0xe9, 0x8b, 0x48, 0x69, 0xa5, 0x74, 0x70, |
3271 | 0x9f, 0xec, 0x83, 0x52, 0x30, 0xc6, 0xc4, 0xe8, 0x42, 0xf0, 0x01, 0x48, | 3276 | 0x0a, 0x65, 0x5a, 0x1e, 0x3e, 0x12, 0x49, 0xd1, 0x02, 0x3e, 0x42, 0xa9, |
3272 | 0x30, 0xc6, 0x68, 0x48, 0x08, 0xea, 0x32, 0x10, 0x75, 0x0c, 0xfb, 0x64, | 3277 | 0x86, 0x98, 0x18, 0x03, 0x9d, 0x4a, 0xe9, 0x40, 0x4b, 0x2a, 0x25, 0x7c, |
3273 | 0x98, 0xf7, 0x9e, 0xdf, 0xb9, 0xff, 0xfe, 0xff, 0x5d, 0x27, 0x18, 0xec, | 3278 | 0xf0, 0xe3, 0x84, 0x62, 0xf9, 0x99, 0x44, 0x4b, 0x80, 0x16, 0x63, 0x48, |
3274 | 0x43, 0x4f, 0xef, 0xbd, 0xe7, 0x9e, 0x7b, 0x3e, 0x7e, 0xe7, 0x9c, 0x7b, | 3279 | 0x23, 0x3f, 0xc4, 0xbf, 0x26, 0x28, 0x45, 0x3f, 0x4c, 0x88, 0x36, 0x04, |
3275 | 0x5b, 0x2c, 0x84, 0x70, 0x8a, 0x44, 0xaa, 0x56, 0x52, 0x61, 0x38, 0x5c, | 3280 | 0x3e, 0xc0, 0x44, 0x63, 0xfc, 0x21, 0x12, 0xc4, 0x5a, 0xa0, 0xc1, 0x82, |
3276 | 0x02, 0x9f, 0xb5, 0xc5, 0x44, 0xae, 0xa5, 0x7c, 0xf2, 0xbb, 0x40, 0xbc, | 3281 | 0x36, 0xc6, 0x48, 0xeb, 0x3d, 0x7b, 0xed, 0x73, 0xe7, 0xde, 0xe9, 0x2d, |
3277 | 0xe4, 0xac, 0xa0, 0xb1, 0x5b, 0x28, 0x1a, 0x12, 0x22, 0x61, 0xa5, 0xa5, | 3282 | 0x8f, 0x48, 0x3f, 0x58, 0x9c, 0x73, 0xf7, 0x39, 0x67, 0xef, 0xb5, 0x1f, |
3278 | 0x4c, 0xaf, 0x32, 0xfd, 0x9d, 0xe9, 0xe3, 0x0e, 0xd0, 0x2b, 0x3c, 0xde, | 3283 | 0x67, 0x9f, 0x29, 0x10, 0x42, 0x78, 0x45, 0x7a, 0x64, 0x91, 0x81, 0x22, |
3279 | 0xc2, 0xe3, 0x6b, 0x3c, 0xfe, 0x91, 0xe9, 0x46, 0x9e, 0xdf, 0xcc, 0x34, | 3284 | 0xe8, 0xf6, 0x68, 0x06, 0xcc, 0x0a, 0x91, 0x57, 0x2a, 0xc7, 0xc2, 0x2d, |
3280 | 0xc9, 0x74, 0x3b, 0xaf, 0xa7, 0x99, 0xca, 0x4f, 0xc2, 0x90, 0x5f, 0x72, | 3285 | 0xf8, 0x6f, 0x59, 0x01, 0xc1, 0x0f, 0x23, 0xf2, 0xbb, 0x5f, 0xbc, 0xe5, |
3281 | 0xb9, 0x59, 0xeb, 0x69, 0x60, 0xba, 0x19, 0xfa, 0xee, 0xa9, 0x53, 0x7c, | 3286 | 0xc6, 0x77, 0xaf, 0x90, 0x18, 0x11, 0x22, 0x2d, 0xb1, 0x80, 0x31, 0xc6, |
3282 | 0xf3, 0x4b, 0x59, 0x3e, 0xcc, 0x5f, 0x9f, 0x00, 0xad, 0xc5, 0xae, 0x8f, | 3287 | 0xe8, 0x72, 0x01, 0x4b, 0x18, 0x5f, 0x61, 0x14, 0x8c, 0xba, 0x1b, 0xe8, |
3283 | 0x13, 0x4f, 0xeb, 0xfd, 0x20, 0x7d, 0x01, 0xd0, 0x7e, 0xb6, 0xbf, 0x33, | 3288 | 0x66, 0xf4, 0xaa, 0x79, 0x5e, 0xaf, 0xf1, 0x7c, 0x3b, 0xe3, 0x76, 0x9e, |
3284 | 0x42, 0x24, 0xb9, 0xdf, 0x89, 0x71, 0x77, 0xa3, 0xf2, 0x43, 0x89, 0x70, | 3289 | 0xff, 0xdd, 0x40, 0xa5, 0x97, 0x1c, 0x4f, 0xce, 0x8a, 0xb4, 0x8e, 0x6d, |
3285 | 0x3b, 0x95, 0x9c, 0x56, 0x9f, 0xe7, 0x3c, 0xe6, 0x5f, 0x0d, 0x81, 0xbe, | 3290 | 0x63, 0x6a, 0x5e, 0x27, 0x48, 0xc7, 0xa0, 0xf7, 0x9b, 0x95, 0xb4, 0xce, |
3286 | 0xe6, 0x07, 0xfd, 0xc5, 0x5f, 0x28, 0xbf, 0x97, 0x96, 0x62, 0x45, 0x2c, | 3291 | 0x41, 0x4e, 0xce, 0xdf, 0x98, 0x55, 0xfb, 0x1d, 0xf4, 0xc8, 0xf1, 0x2f, |
3287 | 0xdf, 0x60, 0xb5, 0x8b, 0xb0, 0x7f, 0xd6, 0x80, 0x1e, 0x2f, 0xd7, 0x41, | 3292 | 0xc6, 0xd8, 0x25, 0x87, 0xc5, 0x51, 0x6c, 0x53, 0x5c, 0x9a, 0x91, 0xfb, |
3288 | 0xbf, 0xef, 0x9f, 0x52, 0xf3, 0x2e, 0x91, 0x60, 0x39, 0x42, 0x68, 0x3d, | 3293 | 0x78, 0xc4, 0xd0, 0x80, 0x46, 0xac, 0x1c, 0xd7, 0x31, 0x4e, 0x13, 0x1f, |
3289 | 0x79, 0x7d, 0x10, 0xfb, 0x56, 0xad, 0xc1, 0xea, 0x5b, 0x31, 0x8c, 0xab, | 3294 | 0x2e, 0x63, 0xcc, 0xfb, 0x31, 0x96, 0x85, 0x70, 0xee, 0xd6, 0x4a, 0x9c, |
3290 | 0x3f, 0x28, 0xa6, 0xb8, 0x9c, 0x4e, 0x69, 0xfe, 0x7c, 0x72, 0xdd, 0x52, | 3295 | 0xf7, 0xd3, 0xb3, 0x90, 0x4b, 0x47, 0x14, 0xa1, 0xf8, 0xbe, 0x48, 0xf0, |
3291 | 0x2e, 0xe4, 0x8b, 0x7a, 0x1f, 0x29, 0x93, 0x88, 0x80, 0x8a, 0x96, 0xdc, | 3296 | 0xf7, 0xdd, 0x72, 0x3c, 0xe5, 0x2a, 0x72, 0x81, 0x57, 0xbf, 0x50, 0x7a, |
3292 | 0x73, 0x20, 0x7f, 0x6a, 0xb5, 0x9a, 0x77, 0x8a, 0x5e, 0x97, 0x9a, 0xf7, | 3297 | 0x42, 0xee, 0xea, 0x40, 0xae, 0x3c, 0x0d, 0x3f, 0x4f, 0xaf, 0x50, 0x76, |
3293 | 0x88, 0xde, 0xb8, 0xf6, 0x2f, 0xd6, 0x63, 0x1e, 0x22, 0x15, 0x7d, 0xe3, | 3298 | 0x00, 0xda, 0x42, 0xc0, 0xa4, 0x07, 0xb8, 0x2e, 0x4e, 0x90, 0x69, 0x67, |
3294 | 0xca, 0xce, 0x90, 0xd8, 0xe7, 0x0c, 0x11, 0x3f, 0xfc, 0xe2, 0xf2, 0x19, | 3299 | 0x47, 0x36, 0xd7, 0x48, 0x3d, 0x0a, 0x85, 0xd7, 0x2d, 0xf7, 0x5b, 0xa1, |
3295 | 0x9f, 0x81, 0xff, 0xcb, 0x5a, 0x83, 0x6c, 0x89, 0xb5, 0x63, 0x5f, 0x59, | 3300 | 0xf9, 0xce, 0x61, 0xfe, 0x6d, 0xd6, 0xeb, 0xbd, 0x00, 0xf0, 0x46, 0x20, |
3296 | 0x14, 0x74, 0x32, 0x5a, 0xa0, 0x48, 0x24, 0x36, 0x4a, 0xc3, 0xd6, 0x9b, | 3301 | 0xdf, 0xf8, 0x77, 0x76, 0xb6, 0x23, 0x68, 0xb7, 0x2b, 0x1d, 0xc4, 0xfa, |
3297 | 0xeb, 0x7c, 0xc4, 0x97, 0x68, 0xd1, 0xf1, 0xd3, 0xf1, 0x52, 0x71, 0xfc, | 3302 | 0x31, 0xdd, 0xc9, 0x3e, 0xcf, 0x03, 0xec, 0xc3, 0xba, 0x05, 0x4b, 0xf1, |
3298 | 0x44, 0xc6, 0x91, 0xdd, 0xd2, 0x00, 0xbf, 0xfe, 0xba, 0x5a, 0xf1, 0x4b, | 3303 | 0xf5, 0xe3, 0x0e, 0x8c, 0x2b, 0x4e, 0x49, 0x39, 0x9f, 0x18, 0x1a, 0x71, |
3299 | 0xe7, 0xd6, 0xe3, 0x9c, 0xac, 0x7e, 0xd6, 0xf8, 0x7f, 0xf4, 0x1f, 0xe2, | 3304 | 0xe2, 0x23, 0x77, 0x7f, 0x23, 0x4e, 0x23, 0x38, 0x47, 0x54, 0x69, 0xa4, |
3300 | 0xaf, 0xe4, 0x75, 0xb2, 0x5f, 0xea, 0xa4, 0x5f, 0x14, 0xad, 0x71, 0x24, | 3305 | 0x54, 0x3a, 0x0e, 0x14, 0x75, 0x8e, 0xfc, 0x88, 0xe3, 0x4b, 0xe4, 0xbc, |
3301 | 0x5a, 0xec, 0xf1, 0xb8, 0x3e, 0x11, 0xa2, 0xdf, 0xb7, 0xba, 0x8a, 0xc9, | 3306 | 0x5b, 0xb4, 0x7a, 0x74, 0x3a, 0xa7, 0x35, 0xa5, 0xe2, 0x02, 0xdf, 0x3b, |
3302 | 0xaf, 0xbb, 0x30, 0x7f, 0xaa, 0xfb, 0x1c, 0xe2, 0xb1, 0x83, 0xec, 0x17, | 3307 | 0x7c, 0x04, 0xa5, 0x6d, 0xfd, 0xd2, 0xde, 0x88, 0xd8, 0xee, 0x8e, 0x90, |
3303 | 0xfe, 0x37, 0x3e, 0xc5, 0xae, 0xbe, 0x80, 0x1a, 0xbf, 0xd2, 0x11, 0xbb, | 3308 | 0x3c, 0xf8, 0xf1, 0x68, 0xfa, 0x97, 0x90, 0xff, 0x66, 0x91, 0x4e, 0x36, |
3304 | 0x80, 0xf5, 0x82, 0x31, 0xf8, 0x75, 0x17, 0x4b, 0xdd, 0xe1, 0x72, 0x28, | 3309 | 0x75, 0x34, 0x60, 0x5d, 0x71, 0x02, 0x78, 0x2c, 0x91, 0x27, 0x21, 0xde, |
3305 | 0x92, 0xf4, 0x8c, 0xd1, 0xd0, 0x98, 0xa5, 0x75, 0x43, 0x9c, 0x4c, 0x61, | 3310 | 0xd1, 0x4b, 0xc3, 0xe5, 0xd7, 0x57, 0x6a, 0x24, 0x97, 0xae, 0x53, 0x71, |
3306 | 0xfd, 0x70, 0x91, 0x1a, 0xef, 0x8a, 0xcc, 0x63, 0x1c, 0x89, 0x8f, 0xf3, | 3311 | 0xa7, 0xfc, 0x27, 0xfd, 0x3a, 0x64, 0xc6, 0x99, 0xa8, 0x06, 0xbf, 0xbf, |
3307 | 0x46, 0x27, 0xfc, 0x70, 0xcb, 0x09, 0x79, 0x0c, 0x2f, 0xbf, 0x9b, 0xe2, | 3312 | 0x2d, 0x91, 0xf2, 0x06, 0xc9, 0x55, 0x38, 0x27, 0xab, 0x9f, 0x35, 0x6e, |
3308 | 0xe0, 0x10, 0x46, 0x37, 0xe8, 0x9b, 0xb4, 0xfe, 0xb7, 0x23, 0x49, 0x76, | 3313 | 0x07, 0x2c, 0x71, 0xfb, 0x78, 0xf1, 0xb0, 0x8e, 0xf8, 0x59, 0xc7, 0x3c, |
3309 | 0x77, 0x07, 0xdd, 0xe7, 0xc0, 0xc8, 0xb8, 0x36, 0x71, 0xab, 0x71, 0xff, | 3314 | 0x55, 0x1a, 0x3c, 0x49, 0x5c, 0xe8, 0x4a, 0xd7, 0xd9, 0xfd, 0x74, 0x75, |
3310 | 0xb0, 0xf8, 0x1d, 0x37, 0x34, 0x5e, 0xd9, 0xff, 0xec, 0xdf, 0xf7, 0x44, | 3315 | 0x20, 0x42, 0xff, 0xbf, 0xd9, 0x54, 0x40, 0x3c, 0x6f, 0xc6, 0xfc, 0x91, |
3311 | 0x2e, 0x4e, 0x41, 0xbb, 0x1b, 0x41, 0x3d, 0x0d, 0xb9, 0x78, 0xd5, 0xf8, | 3316 | 0xe6, 0xb3, 0xf0, 0xd3, 0x26, 0xe2, 0x43, 0x04, 0x0e, 0x7d, 0x81, 0x55, |
3312 | 0xb4, 0xfb, 0x99, 0xe3, 0x63, 0xc1, 0x0b, 0x11, 0x89, 0x13, 0x1b, 0x6e, | 3317 | 0x6d, 0x14, 0xdf, 0xdd, 0x8d, 0x1d, 0x5f, 0x61, 0x9c, 0xf4, 0xc8, 0xf1, |
3313 | 0x18, 0xa7, 0x95, 0xd2, 0x5f, 0x3a, 0xfe, 0x4a, 0x90, 0x57, 0x0c, 0xb2, | 3318 | 0x6e, 0xbd, 0x7d, 0x14, 0xf2, 0x79, 0x7d, 0xe0, 0x7d, 0x33, 0x9f, 0xb2, |
3314 | 0xbc, 0x38, 0xdb, 0x35, 0xc4, 0x76, 0xdd, 0xf1, 0x6b, 0xbf, 0x6a, 0x7b, | 3319 | 0xc9, 0x43, 0xf9, 0x94, 0xf1, 0xf5, 0xd1, 0x50, 0x1f, 0xa3, 0xef, 0x05, |
3315 | 0x40, 0x4f, 0xda, 0xec, 0x71, 0x48, 0x3c, 0xd9, 0x71, 0xc8, 0xfa, 0x24, | 3320 | 0xe2, 0xf0, 0x08, 0xbe, 0xef, 0x09, 0x4a, 0x3b, 0xdf, 0x37, 0xf3, 0x2e, |
3316 | 0xbf, 0xa9, 0xc7, 0x8f, 0xea, 0x06, 0x50, 0xd3, 0xce, 0x46, 0xc5, 0xe7, | 3321 | 0xe5, 0xc3, 0xfa, 0xcc, 0x00, 0xf2, 0x66, 0xe2, 0x8c, 0x1c, 0x6f, 0x8b, |
3317 | 0x89, 0x4e, 0xa7, 0xec, 0x38, 0xd4, 0xf9, 0xb8, 0xa7, 0x4e, 0xcb, 0x57, | 3322 | 0x4f, 0x40, 0x3e, 0x9e, 0xea, 0xe7, 0x8d, 0xdd, 0xe0, 0xf1, 0xa6, 0x1b, |
3318 | 0xb8, 0xcc, 0x48, 0x5c, 0x22, 0x6e, 0xa7, 0x53, 0xd6, 0xfc, 0xac, 0xca, | 3323 | 0xf2, 0x1c, 0xa6, 0x01, 0x2f, 0xf9, 0xd1, 0x25, 0xf4, 0x66, 0xe0, 0x87, |
3319 | 0x93, 0x9f, 0xf6, 0xbc, 0xd0, 0x7e, 0x39, 0x1c, 0xa0, 0x02, 0xd5, 0x71, | 3324 | 0xf4, 0xfd, 0x5f, 0x57, 0x86, 0x78, 0xdb, 0x1a, 0xf6, 0x9e, 0x55, 0xfc, |
3320 | 0x79, 0xce, 0x7e, 0x1e, 0xf0, 0xed, 0x35, 0xf1, 0x53, 0xb6, 0x81, 0xfd, | 3325 | 0x30, 0x46, 0x94, 0x5d, 0xc0, 0x47, 0xcd, 0x83, 0xfe, 0x79, 0xf3, 0x80, |
3321 | 0xc7, 0x34, 0xbc, 0x51, 0xc9, 0xeb, 0x61, 0xf9, 0x6d, 0x2c, 0xdf, 0xb0, | 3326 | 0xfd, 0x19, 0x7b, 0x58, 0x1e, 0x00, 0x9b, 0x6b, 0x80, 0xbe, 0x6a, 0x29, |
3322 | 0xe4, 0x9d, 0xd2, 0xaf, 0xcb, 0xcc, 0x37, 0x1d, 0xb7, 0x6c, 0xde, 0x69, | 3327 | 0x9f, 0xff, 0x18, 0xf9, 0xc0, 0x7a, 0xcd, 0xc9, 0x37, 0xcc, 0x66, 0xe3, |
3323 | 0xff, 0xd1, 0xf9, 0x91, 0xcb, 0x73, 0x6a, 0x7f, 0xf5, 0x03, 0xf2, 0x70, | 3328 | 0x94, 0xc0, 0x88, 0x4f, 0x5b, 0xbc, 0x72, 0x7e, 0x2c, 0x36, 0xfc, 0xa0, |
3324 | 0x93, 0x29, 0xef, 0x3b, 0x33, 0xdf, 0xd4, 0x7a, 0x91, 0x78, 0x8e, 0x87, | 3329 | 0xe2, 0x4e, 0x6e, 0xe8, 0x17, 0xbb, 0x79, 0xdf, 0x14, 0xf3, 0xd1, 0xc5, |
3325 | 0xf6, 0x7a, 0xf2, 0xa7, 0xac, 0x27, 0x64, 0x87, 0xcf, 0x38, 0xc7, 0xf5, | 3330 | 0x7c, 0x4c, 0x32, 0xee, 0x09, 0x2a, 0x1e, 0x80, 0x87, 0x75, 0x9c, 0xdb, |
3326 | 0x63, 0x54, 0x9d, 0x53, 0xc1, 0x7a, 0x57, 0xb0, 0xde, 0xb2, 0x5f, 0xb5, | 3331 | 0x9a, 0x92, 0x7e, 0x5c, 0xeb, 0x50, 0x3f, 0x55, 0x9d, 0x84, 0x9f, 0x86, |
3327 | 0x70, 0x9d, 0xd9, 0x6b, 0xad, 0x17, 0x6b, 0x2d, 0x79, 0xaf, 0xc6, 0x4d, | 3332 | 0xd8, 0xaf, 0x27, 0xcc, 0x7a, 0xa9, 0xf8, 0x9d, 0xaf, 0x6e, 0xda, 0xf3, |
3328 | 0x4b, 0xcb, 0xfb, 0x85, 0xcd, 0x9f, 0x09, 0x41, 0xfe, 0xf7, 0x72, 0x7c, | 3333 | 0x29, 0xc7, 0xce, 0xcc, 0x77, 0x55, 0x58, 0x5e, 0x58, 0x0d, 0x34, 0xf9, |
3329 | 0x3c, 0x79, 0xfa, 0x8b, 0xe6, 0x07, 0xbe, 0xb6, 0x11, 0xbf, 0xcf, 0xc4, | 3334 | 0xad, 0xa1, 0x3c, 0x0e, 0x97, 0x8c, 0x2a, 0xfb, 0xa4, 0x7e, 0xb7, 0x55, |
3330 | 0xbf, 0xdd, 0xde, 0xaa, 0x3c, 0x75, 0x27, 0xd7, 0x7e, 0xf8, 0xb3, 0xcf, | 3335 | 0x1e, 0x86, 0x07, 0x0f, 0x12, 0x06, 0x0a, 0x4f, 0xc9, 0x73, 0xca, 0x1d, |
3331 | 0x19, 0x20, 0xbe, 0x1b, 0x23, 0x6a, 0xdf, 0x49, 0x87, 0xf6, 0x53, 0x27, | 3336 | 0xea, 0x8a, 0x3d, 0x9f, 0x73, 0xf9, 0xdd, 0x13, 0xa2, 0x42, 0xdb, 0x78, |
3332 | 0xea, 0x90, 0x03, 0xf6, 0xd6, 0xb0, 0xbd, 0x72, 0xb9, 0x85, 0xf0, 0xef, | 3337 | 0x79, 0xdc, 0x9e, 0xb7, 0xc8, 0x4f, 0xbf, 0x19, 0xdf, 0xc5, 0xab, 0xd9, |
3333 | 0xbb, 0x31, 0x62, 0xb5, 0xd7, 0xf8, 0x97, 0xf3, 0xec, 0xb8, 0x19, 0xe1, | 3338 | 0x0f, 0x8c, 0xd1, 0x35, 0x72, 0xdf, 0x16, 0x3e, 0xa7, 0x9e, 0xcf, 0xd1, |
3334 | 0x3e, 0xd6, 0x8f, 0xbc, 0xf0, 0xed, 0xff, 0x5c, 0xeb, 0xc3, 0xe7, 0x86, | 3339 | 0x2d, 0x75, 0x43, 0xea, 0x59, 0x68, 0xd6, 0x0b, 0x15, 0x1f, 0xd9, 0xba, |
3335 | 0xf4, 0xf9, 0x4a, 0x5e, 0xb5, 0x98, 0x1b, 0x55, 0xfb, 0x1f, 0x13, 0x0c, | 3340 | 0xa1, 0xfc, 0x40, 0xe7, 0xc7, 0x2f, 0x8f, 0xcb, 0xf5, 0x15, 0x0f, 0xa9, |
3336 | 0x33, 0x31, 0xdc, 0x84, 0xfa, 0x77, 0xe7, 0x00, 0xf4, 0x1f, 0x6e, 0xd4, | 3341 | 0x23, 0x9a, 0xb9, 0xdf, 0x8f, 0x66, 0x9d, 0x90, 0xdf, 0x83, 0xe2, 0x25, |
3337 | 0x7d, 0x1c, 0x38, 0x16, 0x5c, 0xff, 0xbf, 0x9e, 0xc8, 0xe7, 0x97, 0x41, | 3342 | 0x1e, 0xda, 0xeb, 0xe1, 0x1f, 0x46, 0x3d, 0x24, 0x3b, 0x34, 0xfd, 0x2c, |
3338 | 0x07, 0xf8, 0xca, 0xd8, 0xae, 0x62, 0xb6, 0x2b, 0x22, 0x72, 0xeb, 0xec, | 3343 | 0xd7, 0xbf, 0x5e, 0x79, 0x4e, 0x29, 0xeb, 0x5d, 0xca, 0x7a, 0x1b, 0xd7, |
3339 | 0x5e, 0xca, 0x97, 0x4e, 0xe6, 0x7b, 0x56, 0xd7, 0xe3, 0x65, 0x7c, 0xb0, | 3344 | 0x73, 0x1d, 0xd7, 0xc9, 0x6d, 0xd6, 0x7a, 0xf7, 0xcf, 0x4c, 0xb6, 0x6e, |
3340 | 0xbf, 0x80, 0xcf, 0xcf, 0xe7, 0xaf, 0x7c, 0x72, 0xd3, 0x8c, 0xa3, 0x01, | 3345 | 0xc9, 0xf1, 0xdf, 0x33, 0x73, 0xef, 0x5f, 0x47, 0x5e, 0xd3, 0x22, 0x82, |
3341 | 0xe6, 0x73, 0xe7, 0xa9, 0xf3, 0x18, 0x65, 0xd6, 0x50, 0x9d, 0x3f, 0x73, | 3346 | 0x3e, 0x23, 0x1d, 0x51, 0x7d, 0x41, 0x6e, 0xfd, 0xcb, 0xb5, 0x03, 0xbc, |
3342 | 0x3c, 0xad, 0xf8, 0x02, 0x26, 0xce, 0xed, 0x76, 0xfd, 0x74, 0xff, 0xd1, | 3347 | 0xb4, 0xb9, 0x43, 0x24, 0x77, 0xad, 0xc7, 0xde, 0x27, 0xa0, 0x0e, 0x56, |
3343 | 0xfd, 0xaf, 0xf8, 0xc2, 0xe2, 0x60, 0x70, 0x25, 0x3f, 0xbb, 0xd5, 0xf4, | 3348 | 0xba, 0xa0, 0xf7, 0x42, 0xd6, 0xdb, 0xd8, 0xaf, 0x8e, 0xf2, 0x41, 0xbb, |
3344 | 0xcc, 0x42, 0x5a, 0xc7, 0xc9, 0x20, 0x3b, 0xe7, 0x46, 0xd5, 0xf9, 0x1f, | 3349 | 0xd6, 0x63, 0xd5, 0xfb, 0xfa, 0xcc, 0xfc, 0xe7, 0x39, 0xc7, 0x41, 0x0f, |
3345 | 0xe6, 0xf8, 0xdf, 0x69, 0xf1, 0x3f, 0xf8, 0x9f, 0x88, 0x3c, 0xaa, 0xdf, | 3350 | 0xdf, 0xaf, 0x49, 0xc4, 0xb1, 0xd6, 0xfe, 0xb5, 0xd2, 0x8b, 0xcf, 0x8f, |
3346 | 0xf3, 0xf5, 0xe5, 0x2f, 0xee, 0x2f, 0xcf, 0x13, 0x35, 0x7f, 0xe1, 0xa1, | 3351 | 0x28, 0x3d, 0x74, 0xf2, 0xd3, 0x78, 0xaf, 0xdc, 0xa7, 0x48, 0x70, 0xd8, |
3347 | 0xfd, 0xb1, 0xbb, 0xdd, 0x6a, 0x7f, 0x83, 0x98, 0x4d, 0x21, 0xbf, 0x7a, | 3352 | 0x88, 0xee, 0x5a, 0xd4, 0xdf, 0xc9, 0x1d, 0xb0, 0xa3, 0xbb, 0x46, 0xea, |
3348 | 0x18, 0x87, 0xfb, 0xb8, 0x5e, 0xdf, 0xf0, 0xab, 0x09, 0x9f, 0xe8, 0xdf, | 3353 | 0x61, 0x78, 0x25, 0x8d, 0x3c, 0x17, 0x7c, 0x1f, 0x7d, 0x3b, 0xe0, 0xe4, |
3349 | 0x49, 0xfe, 0x10, 0xe1, 0x22, 0xf8, 0xa7, 0xff, 0x45, 0xed, 0x4f, 0xcc, | 3354 | 0xd7, 0x4b, 0x2c, 0x57, 0xcc, 0xf6, 0x15, 0xb0, 0x7d, 0x71, 0x91, 0x5b, |
3350 | 0x57, 0x51, 0xbf, 0x75, 0x89, 0x1e, 0xaf, 0x41, 0xfc, 0x55, 0x01, 0xd0, | 3355 | 0xe7, 0xb7, 0x55, 0xd2, 0x7d, 0xc0, 0x72, 0x2f, 0xaa, 0xfb, 0xc0, 0x90, |
3351 | 0x30, 0xd7, 0xf9, 0x59, 0xb3, 0x8f, 0x81, 0x9e, 0xf6, 0xe8, 0xba, 0x8c, | 3356 | 0x93, 0xfb, 0xe4, 0xf1, 0x3e, 0x4e, 0x3c, 0x39, 0xed, 0x33, 0xca, 0x71, |
3352 | 0x7e, 0xfe, 0x95, 0x47, 0x31, 0xc8, 0x20, 0x35, 0xa3, 0x3e, 0x77, 0x35, | 3357 | 0xd0, 0xc9, 0x72, 0x5e, 0x87, 0x7b, 0x05, 0xa3, 0xe9, 0xa5, 0x74, 0xaf, |
3353 | 0x1a, 0xb4, 0xde, 0xdb, 0x0c, 0x3c, 0x89, 0x7a, 0xdd, 0xe7, 0xf0, 0xe1, | 3358 | 0x9c, 0x3c, 0x40, 0xf7, 0x43, 0xc8, 0x8c, 0x53, 0xbb, 0x1d, 0x67, 0x9e, |
3354 | 0x3e, 0x50, 0x95, 0xed, 0x77, 0xd6, 0x7e, 0x58, 0x68, 0xe9, 0x07, 0xfa, | 3359 | 0x20, 0xef, 0x52, 0x3e, 0x2a, 0x76, 0x86, 0xe7, 0xe3, 0xd7, 0x2b, 0xa7, |
3355 | 0x3c, 0xed, 0x47, 0x2d, 0x97, 0x86, 0xb2, 0xaf, 0x58, 0xfb, 0xa1, 0xee, | 3360 | 0x87, 0xa7, 0x46, 0x95, 0x7f, 0x74, 0xb2, 0x77, 0xbc, 0x57, 0xf5, 0xb1, |
3356 | 0x13, 0x8b, 0xdc, 0x27, 0x4a, 0xc5, 0xc5, 0x14, 0xec, 0x9a, 0x4d, 0xe5, | 3361 | 0x56, 0xde, 0xdd, 0x16, 0xde, 0x21, 0xff, 0x74, 0xfc, 0xff, 0xf2, 0xed, |
3357 | 0xe2, 0x4f, 0x9f, 0xa7, 0xe5, 0x41, 0x6f, 0x6d, 0x47, 0x56, 0x3e, 0xce, | 3362 | 0xd4, 0x1f, 0x1c, 0x9d, 0x31, 0xfb, 0x50, 0x9f, 0x53, 0xfd, 0x5f, 0x61, |
3358 | 0x3f, 0xc0, 0x7a, 0xfe, 0x4c, 0xf7, 0xd8, 0x30, 0xdb, 0xa3, 0xe4, 0x62, | 3363 | 0xc6, 0xcb, 0x5e, 0xee, 0xef, 0xa6, 0x75, 0xfa, 0x4f, 0x62, 0x32, 0x43, |
3359 | 0x7e, 0x3b, 0xf7, 0xe7, 0x84, 0x39, 0xb6, 0xf7, 0xd5, 0x1e, 0xd2, 0xab, | 3364 | 0x43, 0xbd, 0xec, 0xb4, 0x94, 0x5b, 0x96, 0xd8, 0xcb, 0x76, 0x5d, 0xf4, |
3360 | 0x84, 0xf1, 0x16, 0xb6, 0xe4, 0x03, 0xf8, 0xcb, 0xda, 0x40, 0x27, 0xdb, | 3365 | 0xc0, 0xee, 0xce, 0x1d, 0x18, 0x5f, 0xe6, 0x7a, 0x7d, 0x97, 0xeb, 0xe3, |
3361 | 0x74, 0x1c, 0x74, 0xbc, 0x74, 0x7c, 0x10, 0xc7, 0xf0, 0x3a, 0x62, 0xeb, | 3366 | 0x16, 0x0d, 0x38, 0x59, 0x4b, 0x7c, 0x24, 0xf6, 0x9e, 0x53, 0xfb, 0xd3, |
3362 | 0xe8, 0x5f, 0x47, 0x7d, 0xa4, 0xad, 0x7f, 0x41, 0xe3, 0x0f, 0xfb, 0x77, | 3367 | 0xbe, 0xfa, 0x34, 0xf3, 0xf9, 0xb2, 0x87, 0xed, 0xac, 0x22, 0x3f, 0x26, |
3363 | 0x47, 0x14, 0xff, 0xeb, 0xe2, 0x2a, 0xe1, 0x50, 0x88, 0x1f, 0x98, 0x66, | 3368 | 0xee, 0x50, 0x3d, 0xf0, 0x8a, 0xa6, 0xc5, 0x12, 0xcb, 0x0c, 0xde, 0x58, |
3364 | 0xfb, 0x15, 0x07, 0xc0, 0xcc, 0x57, 0x8e, 0x5f, 0x01, 0x4f, 0xb7, 0xeb, | 3369 | 0x9f, 0x17, 0x80, 0xad, 0x7e, 0xa6, 0x21, 0x96, 0xeb, 0x67, 0x4c, 0xfb, |
3365 | 0x7a, 0xae, 0xe3, 0x65, 0xcd, 0xd7, 0xd8, 0x32, 0xdc, 0x66, 0xeb, 0xb2, | 3370 | 0xaa, 0x78, 0x7d, 0x1b, 0xc6, 0x7e, 0xae, 0x67, 0x83, 0xac, 0xd7, 0xd1, |
3366 | 0xb6, 0x53, 0xf1, 0x47, 0x18, 0x8f, 0x3e, 0xd1, 0xb5, 0x0d, 0xf7, 0xdc, | 3371 | 0x5a, 0x60, 0x38, 0x86, 0x3e, 0x61, 0x9c, 0xee, 0x85, 0x48, 0xa2, 0x77, |
3367 | 0xa0, 0x17, 0x75, 0x3f, 0xe8, 0xb5, 0xc6, 0x4b, 0xe2, 0xa2, 0xd0, 0xab, | 3372 | 0x14, 0xf6, 0x74, 0xad, 0x87, 0xbd, 0xf7, 0x98, 0x07, 0xc6, 0xf0, 0x89, |
3368 | 0x86, 0x35, 0x25, 0x85, 0x64, 0xcf, 0xa9, 0x4b, 0xdf, 0xd2, 0xf2, 0xfb, | 3373 | 0x3e, 0xba, 0x77, 0xc2, 0xfd, 0xe8, 0x33, 0xc2, 0xbe, 0x3e, 0xd8, 0xd1, |
3369 | 0xd3, 0x45, 0x98, 0x2f, 0xdf, 0x19, 0x22, 0x7f, 0x4c, 0x01, 0xcf, 0xef, | 3374 | 0x35, 0x8d, 0xf1, 0xbd, 0xe7, 0x80, 0x7f, 0x3d, 0x8f, 0x75, 0xfb, 0x0e, |
3370 | 0x4e, 0x82, 0xbe, 0x23, 0x5e, 0xc0, 0xfe, 0x92, 0x13, 0x74, 0x0f, 0xf4, | 3375 | 0x30, 0x3f, 0xeb, 0x9d, 0xd7, 0x75, 0xfe, 0x09, 0xb9, 0xee, 0x5a, 0x79, |
3371 | 0x95, 0x33, 0x3e, 0x2b, 0x50, 0x27, 0x92, 0xd3, 0x74, 0x2f, 0x59, 0x5a, | 3376 | 0xfe, 0xbb, 0xc3, 0xdc, 0x7f, 0x88, 0x14, 0xf5, 0x3b, 0xef, 0xe8, 0xd3, |
3372 | 0x12, 0x01, 0x45, 0x3d, 0x66, 0xbf, 0x01, 0x3e, 0xdd, 0x96, 0x38, 0x3f, | 3377 | 0x3c, 0xde, 0xc5, 0xf7, 0xe2, 0x2d, 0xee, 0x17, 0xba, 0x72, 0xfa, 0x85, |
3373 | 0x08, 0xaf, 0x74, 0xaf, 0x94, 0x78, 0xc4, 0x76, 0xc6, 0xad, 0x2f, 0x17, | 3378 | 0x09, 0xd4, 0xe9, 0xe1, 0xe9, 0x8c, 0x9c, 0x30, 0xea, 0x65, 0xbe, 0x93, |
3374 | 0xb7, 0xda, 0x1f, 0x15, 0xce, 0xbc, 0x38, 0xdd, 0x60, 0xc7, 0xa9, 0x87, | 3379 | 0x7f, 0xf5, 0x44, 0x09, 0xfb, 0xad, 0x78, 0x15, 0xf0, 0xd8, 0x2a, 0xdc, |
3375 | 0x71, 0x7a, 0xcf, 0xec, 0xef, 0xcb, 0xe5, 0xa2, 0xcf, 0x5f, 0xfc, 0xdf, | 3380 | 0xd7, 0x5d, 0xfb, 0x99, 0x9f, 0x46, 0xf2, 0xd3, 0xf2, 0xa9, 0xd1, 0xdc, |
3376 | 0x70, 0x0b, 0xba, 0xbd, 0x41, 0x9d, 0x5f, 0xbe, 0xac, 0x1e, 0xd7, 0xda, | 3381 | 0xf5, 0x32, 0x7e, 0x3a, 0x8d, 0xf8, 0x51, 0xe7, 0x40, 0x3e, 0x19, 0x92, |
3377 | 0xe2, 0xdc, 0x7c, 0x5f, 0xeb, 0x75, 0xc2, 0x63, 0x5d, 0x6f, 0x31, 0xfb, | 3382 | 0xf3, 0xf7, 0xcc, 0xba, 0x3f, 0x41, 0x7a, 0x57, 0x0c, 0x4f, 0xd3, 0xfa, |
3378 | 0xd9, 0x11, 0x7e, 0xe7, 0x65, 0x0c, 0xfa, 0x11, 0xbd, 0x93, 0xa4, 0xa1, | 3383 | 0x72, 0x51, 0x44, 0xf1, 0x57, 0x16, 0x9e, 0x82, 0x1d, 0x89, 0x41, 0xb6, |
3379 | 0x51, 0x79, 0x56, 0xf1, 0x35, 0x45, 0x8f, 0x70, 0xbd, 0xbd, 0xe4, 0x42, | 3384 | 0xbf, 0x67, 0x2d, 0x70, 0x3f, 0xfb, 0x5f, 0xf9, 0xf5, 0xca, 0x1a, 0x9d, |
3380 | 0xbd, 0x19, 0x38, 0x80, 0xf1, 0x65, 0xae, 0x1f, 0x77, 0xd7, 0x50, 0x5d, | 3385 | 0xd6, 0x8d, 0xf7, 0xe2, 0x1c, 0x95, 0x3f, 0xb9, 0xfd, 0xb0, 0x8a, 0x87, |
3381 | 0x8e, 0x1e, 0x39, 0xaf, 0xe5, 0x91, 0x1c, 0x23, 0xc3, 0x75, 0xfd, 0x79, | 3386 | 0xb2, 0x06, 0x1a, 0x8b, 0xce, 0x7d, 0xf2, 0x9c, 0x90, 0xe1, 0x47, 0x19, |
3382 | 0x17, 0xd7, 0x5b, 0xf2, 0x9b, 0x3b, 0xfa, 0x07, 0xdd, 0x67, 0xdc, 0xa2, | 3387 | 0x47, 0x06, 0x47, 0x7c, 0x5f, 0xdb, 0xe3, 0x44, 0xc6, 0x91, 0x8a, 0x57, |
3383 | 0xeb, 0x49, 0x45, 0x2b, 0x65, 0xfd, 0xe6, 0xf3, 0x9f, 0x01, 0xed, 0xf5, | 3388 | 0x6b, 0x7c, 0x59, 0xe3, 0xc7, 0x1e, 0x37, 0x61, 0xba, 0x57, 0x8c, 0x22, |
3384 | 0x82, 0x8a, 0x66, 0x7b, 0x3c, 0x84, 0x69, 0x17, 0x46, 0x9e, 0x7a, 0x96, | 3389 | 0x90, 0xa6, 0x77, 0x44, 0x62, 0x70, 0xe0, 0xc1, 0xfc, 0x9d, 0x00, 0x7f, |
3385 | 0xd3, 0x87, 0xb1, 0x97, 0xef, 0x65, 0xd3, 0xec, 0xa7, 0x20, 0xf9, 0xa3, | 3390 | 0x09, 0xd6, 0x5b, 0x4f, 0x51, 0x1f, 0xfa, 0x94, 0xe8, 0x67, 0x3f, 0x4e, |
3386 | 0x58, 0xda, 0xa9, 0x68, 0x28, 0x3a, 0x9a, 0x86, 0xfe, 0x43, 0x5b, 0x61, | 3391 | 0xd4, 0x72, 0xde, 0x57, 0xc1, 0x8f, 0x3d, 0xcf, 0x40, 0x9f, 0x1e, 0xce, |
3387 | 0xdf, 0x22, 0xdb, 0xcd, 0x34, 0xf8, 0xf6, 0x18, 0xe1, 0x2f, 0x38, 0x8e, | 3392 | 0x9f, 0xdb, 0xdc, 0x5f, 0xc0, 0xff, 0x7e, 0xbd, 0x63, 0x94, 0xfd, 0xcd, |
3388 | 0x77, 0x48, 0xd0, 0x33, 0x06, 0x3b, 0x86, 0x32, 0x18, 0x2f, 0x6e, 0x06, | 3393 | 0x71, 0xb8, 0x8b, 0x79, 0xb8, 0x05, 0x1e, 0x74, 0xc5, 0x43, 0xca, 0xe4, |
3389 | 0xfd, 0x6b, 0x0b, 0xf6, 0x1d, 0x3d, 0xce, 0xfe, 0xd8, 0x9a, 0x7f, 0xdf, | 3394 | 0x41, 0xd5, 0x19, 0xeb, 0x3e, 0x85, 0x46, 0x1c, 0x49, 0x5c, 0xa0, 0x5f, |
3390 | 0xc0, 0x3d, 0xf0, 0x0d, 0x37, 0xa9, 0xf3, 0x07, 0x67, 0xf8, 0xfd, 0x22, | 3395 | 0xa1, 0x3e, 0x2c, 0x8f, 0xed, 0x36, 0xe4, 0x1a, 0xa4, 0x7d, 0x61, 0xb6, |
3391 | 0xe2, 0x2e, 0x35, 0x8e, 0x1b, 0x19, 0x1e, 0x1f, 0xe2, 0xfa, 0x7e, 0x9b, | 3396 | 0x2f, 0x24, 0x76, 0x2e, 0xb7, 0xae, 0x0b, 0xf2, 0xba, 0x80, 0xb1, 0x0e, |
3392 | 0xdf, 0x1b, 0x43, 0x39, 0xef, 0x8d, 0x79, 0xdc, 0x33, 0x67, 0x32, 0x49, | 3397 | 0xf3, 0xc8, 0x53, 0x7d, 0x1e, 0x7e, 0x25, 0x8f, 0x6a, 0xdf, 0xdc, 0x7c, |
3393 | 0xe0, 0x22, 0x51, 0x98, 0xfb, 0x5e, 0x55, 0xe3, 0x9a, 0x68, 0x39, 0xc7, | 3398 | 0xb4, 0xf2, 0x49, 0x15, 0x9a, 0xfe, 0x50, 0x87, 0x0c, 0xbf, 0x51, 0xbd, |
3394 | 0xa9, 0x6c, 0x3d, 0xe8, 0xe4, 0x7a, 0xbc, 0x13, 0x86, 0x8e, 0xb1, 0x5f, | 3399 | 0xd2, 0xcd, 0xfa, 0x73, 0x97, 0xea, 0x79, 0xe0, 0x64, 0x37, 0xea, 0xc5, |
3395 | 0x3a, 0x28, 0x4e, 0xad, 0x0b, 0xe9, 0x95, 0xde, 0xc9, 0xe0, 0x9b, 0xe2, | 3400 | 0xc9, 0xee, 0xd3, 0x7c, 0xff, 0x32, 0x2f, 0x2d, 0xf4, 0x6e, 0x30, 0xb8, |
3396 | 0x73, 0xc3, 0xdc, 0x4f, 0xc2, 0xc8, 0x3f, 0x51, 0x91, 0xe4, 0x77, 0xcb, | 3401 | 0xab, 0xb2, 0xd7, 0x1f, 0xbb, 0x1e, 0x15, 0x16, 0x3d, 0xd4, 0xb9, 0x0f, |
3397 | 0x04, 0xee, 0x9d, 0x53, 0x06, 0x68, 0x38, 0xa0, 0xf5, 0x45, 0x3e, 0x26, | 3402 | 0xeb, 0x0f, 0xd0, 0x9f, 0x6e, 0xa0, 0xfe, 0x40, 0x33, 0xfb, 0x6c, 0xfb, |
3398 | 0x52, 0xc8, 0x3b, 0xac, 0x3b, 0x2c, 0xeb, 0x7c, 0x1f, 0x59, 0xf6, 0xce, | 3403 | 0x3d, 0x72, 0xeb, 0xfe, 0xe3, 0xde, 0x23, 0x5b, 0x1a, 0xac, 0xe7, 0xc5, |
3399 | 0x51, 0x74, 0xd1, 0x51, 0xea, 0xd0, 0x76, 0x62, 0xb5, 0x3f, 0xa0, 0xf0, | 3404 | 0xc4, 0xd8, 0x08, 0xce, 0x69, 0xe1, 0x7b, 0x7b, 0x3b, 0xe7, 0xf7, 0xb5, |
3400 | 0x7b, 0xd3, 0xcc, 0xab, 0x79, 0xf2, 0x5b, 0xf5, 0x4c, 0x86, 0xf4, 0xaf, | 3405 | 0x40, 0x84, 0xce, 0x4d, 0xbe, 0x46, 0xf6, 0x8a, 0x68, 0x10, 0xf6, 0x25, |
3401 | 0x12, 0xa5, 0xd4, 0x87, 0x2b, 0x83, 0x0b, 0xf0, 0x63, 0x74, 0x9a, 0xfd, | 3406 | 0x5f, 0xc7, 0xf7, 0x64, 0x08, 0xf3, 0xe5, 0x21, 0xfc, 0x3e, 0xd0, 0xe2, |
3402 | 0x3f, 0xb2, 0x09, 0xf4, 0x18, 0xe3, 0x4f, 0xe3, 0xea, 0xca, 0x46, 0x83, | 3407 | 0xd7, 0x49, 0xbe, 0x3c, 0x04, 0x8c, 0x72, 0x5d, 0x18, 0x33, 0xdf, 0x11, |
3403 | 0xf6, 0xcd, 0x8d, 0xe2, 0x1c, 0x7d, 0x8f, 0xc8, 0x7d, 0x8f, 0x6b, 0x3c, | 3408 | 0xc0, 0x21, 0xdf, 0x7c, 0xef, 0x08, 0xbc, 0xc7, 0xce, 0xfb, 0x50, 0x37, |
3404 | 0x56, 0xb6, 0xa3, 0x90, 0x0e, 0x1c, 0x55, 0xe7, 0x04, 0x24, 0x8e, 0x94, | 3409 | 0x44, 0x0c, 0xfd, 0x73, 0x53, 0x8d, 0x4e, 0xdf, 0x5b, 0x63, 0xb8, 0x9f, |
3405 | 0xfe, 0xd2, 0x27, 0x9c, 0x8f, 0x76, 0x9c, 0x2a, 0x1c, 0xeb, 0xfc, 0xb0, | 3410 | 0x51, 0x97, 0xe7, 0xda, 0x55, 0x81, 0x78, 0x2d, 0xcf, 0xbe, 0x37, 0xac, |
3406 | 0xe2, 0x3b, 0x37, 0xdf, 0xb3, 0x78, 0x0d, 0xd2, 0xbd, 0x5c, 0x16, 0xb9, | 3411 | 0xef, 0x12, 0x3d, 0x31, 0x68, 0xf6, 0xfd, 0x76, 0x3d, 0x90, 0x67, 0x72, |
3407 | 0x04, 0xbf, 0x9b, 0xf8, 0x7e, 0xb0, 0x52, 0xfc, 0xde, 0x46, 0xfc, 0xa2, | 3412 | 0x7f, 0x1a, 0x1a, 0xfd, 0xf5, 0xa3, 0xbc, 0x47, 0x3c, 0xdc, 0xaf, 0xdd, |
3408 | 0xac, 0xb7, 0x11, 0x1f, 0x43, 0x5f, 0x1c, 0x67, 0x1c, 0xcd, 0x37, 0xf1, | 3413 | 0x99, 0x45, 0xbc, 0x16, 0x89, 0x0b, 0x23, 0xe0, 0x61, 0x6c, 0xc4, 0x29, |
3409 | 0xfd, 0x87, 0xf5, 0xfb, 0x8d, 0xdf, 0x67, 0xc0, 0x9b, 0xd7, 0x88, 0xa5, | 3414 | 0x8f, 0xa5, 0x1e, 0xea, 0x1c, 0xd8, 0xa5, 0xec, 0xcc, 0x9e, 0x0b, 0xbd, |
3410 | 0x19, 0x5f, 0x8c, 0xfb, 0x43, 0x6c, 0xf7, 0x6d, 0xd8, 0x6d, 0x68, 0xbb, | 3415 | 0x76, 0xb0, 0xfe, 0xbf, 0xd2, 0xef, 0x17, 0x51, 0xb6, 0x57, 0xee, 0x8b, |
3411 | 0xe3, 0xa6, 0xdd, 0xfa, 0x7e, 0x65, 0x95, 0x53, 0x22, 0x71, 0xab, 0xe8, | 3416 | 0xf9, 0x8d, 0xf4, 0x6e, 0xca, 0x13, 0x69, 0x73, 0x6c, 0x7f, 0xcf, 0xb4, |
3412 | 0x2a, 0xe3, 0x0a, 0xd5, 0xb3, 0x02, 0xb6, 0x53, 0xf2, 0xb5, 0x2b, 0x7b, | 3417 | 0x90, 0x5e, 0x85, 0x7c, 0xaf, 0x47, 0x2d, 0xfd, 0x07, 0xe4, 0x8b, 0xeb, |
3413 | 0x82, 0x6c, 0x4f, 0x40, 0x1c, 0x6c, 0xb5, 0xee, 0x2b, 0xe2, 0x7d, 0x7e, | 3418 | 0x81, 0xc7, 0xea, 0x95, 0xdf, 0x94, 0x7f, 0x95, 0x3f, 0xe1, 0xf7, 0xe8, |
3414 | 0xb9, 0x0f, 0xf3, 0xa8, 0x0b, 0xc6, 0x0a, 0xfe, 0x54, 0x7e, 0xd3, 0x72, | 3419 | 0x4a, 0x12, 0x6b, 0x4c, 0xae, 0xa4, 0x84, 0xaf, 0x4f, 0x4e, 0xa9, 0x7b, |
3415 | 0x73, 0xf3, 0xde, 0xea, 0x3f, 0xba, 0x91, 0xd2, 0x07, 0xf5, 0x4d, 0xc6, | 3420 | 0x1e, 0xeb, 0xb7, 0xc4, 0xa5, 0xfc, 0x07, 0xe2, 0xfb, 0x38, 0x2e, 0xd6, |
3416 | 0xa9, 0x05, 0xff, 0x1f, 0xe8, 0xfa, 0x76, 0x97, 0xee, 0xaf, 0xfe, 0x33, | 3421 | 0x9f, 0x19, 0xb3, 0xfd, 0xbd, 0xe0, 0x3f, 0xeb, 0x3b, 0xc1, 0x23, 0xce, |
3417 | 0xc3, 0xa8, 0x4f, 0x67, 0x86, 0xcf, 0xf2, 0xbb, 0x83, 0xfd, 0xd2, 0x43, | 3422 | 0xe7, 0xf1, 0x74, 0x83, 0xea, 0x7b, 0xe7, 0x7b, 0xef, 0x48, 0x3b, 0x3e, |
3418 | 0xff, 0x5b, 0xc8, 0xd8, 0xd5, 0xdb, 0xeb, 0x9b, 0x5d, 0x8f, 0x6a, 0x8b, | 3423 | 0xba, 0x9f, 0xdb, 0x47, 0x67, 0xfb, 0x60, 0x65, 0xaf, 0x5c, 0x57, 0xcf, |
3419 | 0x1e, 0xfa, 0xdc, 0x7f, 0x00, 0x5a, 0x33, 0xe6, 0xc0, 0x30, 0x14, 0x00, | 3424 | 0x71, 0xac, 0x89, 0xa6, 0x0d, 0xf8, 0x7d, 0x23, 0xec, 0x47, 0xde, 0x84, |
3420 | 0x00, 0x00 }; | 3425 | 0xfd, 0x4e, 0xef, 0x52, 0x23, 0x8e, 0xf2, 0xa9, 0x60, 0x2c, 0x2c, 0xcc, |
3426 | 0x27, 0xfb, 0x8e, 0x5c, 0xbc, 0x44, 0x62, 0x9f, 0x0d, 0x06, 0x31, 0x5f, | ||
3427 | 0xd2, 0x84, 0x63, 0xbc, 0x14, 0xf7, 0x1e, 0x71, 0x08, 0x79, 0xf1, 0xe9, | ||
3428 | 0x31, 0xe0, 0x27, 0xe2, 0x55, 0xec, 0x53, 0x78, 0x90, 0xee, 0x53, 0xad, | ||
3429 | 0x04, 0x34, 0x67, 0x06, 0x39, 0xde, 0x4b, 0xdd, 0xf4, 0xfb, 0xe2, 0xac, | ||
3430 | 0x08, 0x49, 0xf4, 0x99, 0xf9, 0x8b, 0xb8, 0xf6, 0x5a, 0xfc, 0xff, 0xa8, | ||
3431 | 0x71, 0x4e, 0xf5, 0xc9, 0x88, 0x63, 0x6c, 0xc3, 0xf1, 0xae, 0xe5, 0xc6, | ||
3432 | 0xbb, 0xe2, 0xa9, 0xd4, 0xed, 0x18, 0xdf, 0xab, 0xe7, 0xc6, 0xb7, 0xd2, | ||
3433 | 0x4f, 0xf2, 0x7d, 0xd7, 0xbc, 0x3f, 0xe7, 0xee, 0x8f, 0xf7, 0xd3, 0x85, | ||
3434 | 0x27, 0x16, 0xdf, 0xc0, 0x8d, 0xd5, 0xf2, 0xfc, 0x92, 0x39, 0x7d, 0x72, | ||
3435 | 0x6e, 0xfe, 0xa1, 0xde, 0xbd, 0x61, 0xc4, 0xc3, 0x7f, 0x69, 0x4a, 0x77, | ||
3436 | 0x8f, 0xc8, 0x15, 0x00, 0x00, 0x00 }; | ||
3421 | 3437 | ||
3422 | static u8 bnx2_TPAT_b09FwText[] = { | 3438 | static u8 bnx2_TPAT_b09FwText[] = { |
3423 | 0xbd, 0x58, 0x5d, 0x6c, 0x1c, 0xd5, 0x15, 0x3e, 0x73, 0x67, 0xd6, 0x3b, | 3439 | 0xbd, 0x58, 0x5d, 0x6c, 0x1c, 0xd5, 0x15, 0x3e, 0x73, 0x67, 0xd6, 0x3b, |
diff --git a/drivers/net/bnx2x.c b/drivers/net/bnx2x.c index 7bdb5af35951..70cba64732ca 100644 --- a/drivers/net/bnx2x.c +++ b/drivers/net/bnx2x.c | |||
@@ -6,7 +6,8 @@ | |||
6 | * it under the terms of the GNU General Public License as published by | 6 | * it under the terms of the GNU General Public License as published by |
7 | * the Free Software Foundation. | 7 | * the Free Software Foundation. |
8 | * | 8 | * |
9 | * Written by: Eliezer Tamir <eliezert@broadcom.com> | 9 | * Maintained by: Eilon Greenstein <eilong@broadcom.com> |
10 | * Written by: Eliezer Tamir | ||
10 | * Based on code from Michael Chan's bnx2 driver | 11 | * Based on code from Michael Chan's bnx2 driver |
11 | * UDP CSUM errata workaround by Arik Gendelman | 12 | * UDP CSUM errata workaround by Arik Gendelman |
12 | * Slowpath rework by Vladislav Zolotarov | 13 | * Slowpath rework by Vladislav Zolotarov |
@@ -74,7 +75,7 @@ static char version[] __devinitdata = | |||
74 | "Broadcom NetXtreme II 5771X 10Gigabit Ethernet Driver " | 75 | "Broadcom NetXtreme II 5771X 10Gigabit Ethernet Driver " |
75 | DRV_MODULE_NAME " " DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n"; | 76 | DRV_MODULE_NAME " " DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n"; |
76 | 77 | ||
77 | MODULE_AUTHOR("Eliezer Tamir <eliezert@broadcom.com>"); | 78 | MODULE_AUTHOR("Eliezer Tamir"); |
78 | MODULE_DESCRIPTION("Broadcom NetXtreme II BCM57710 Driver"); | 79 | MODULE_DESCRIPTION("Broadcom NetXtreme II BCM57710 Driver"); |
79 | MODULE_LICENSE("GPL"); | 80 | MODULE_LICENSE("GPL"); |
80 | MODULE_VERSION(DRV_MODULE_VERSION); | 81 | MODULE_VERSION(DRV_MODULE_VERSION); |
diff --git a/drivers/net/bnx2x.h b/drivers/net/bnx2x.h index 4f0c0d31e7c1..8e68d06510a6 100644 --- a/drivers/net/bnx2x.h +++ b/drivers/net/bnx2x.h | |||
@@ -6,7 +6,8 @@ | |||
6 | * it under the terms of the GNU General Public License as published by | 6 | * it under the terms of the GNU General Public License as published by |
7 | * the Free Software Foundation. | 7 | * the Free Software Foundation. |
8 | * | 8 | * |
9 | * Written by: Eliezer Tamir <eliezert@broadcom.com> | 9 | * Maintained by: Eilon Greenstein <eilong@broadcom.com> |
10 | * Written by: Eliezer Tamir | ||
10 | * Based on code from Michael Chan's bnx2 driver | 11 | * Based on code from Michael Chan's bnx2 driver |
11 | */ | 12 | */ |
12 | 13 | ||
diff --git a/drivers/net/bnx2x_init.h b/drivers/net/bnx2x_init.h index dcaecc53bdb1..370686eef97c 100644 --- a/drivers/net/bnx2x_init.h +++ b/drivers/net/bnx2x_init.h | |||
@@ -6,7 +6,8 @@ | |||
6 | * it under the terms of the GNU General Public License as published by | 6 | * it under the terms of the GNU General Public License as published by |
7 | * the Free Software Foundation. | 7 | * the Free Software Foundation. |
8 | * | 8 | * |
9 | * Written by: Eliezer Tamir <eliezert@broadcom.com> | 9 | * Maintained by: Eilon Greenstein <eilong@broadcom.com> |
10 | * Written by: Eliezer Tamir | ||
10 | */ | 11 | */ |
11 | 12 | ||
12 | #ifndef BNX2X_INIT_H | 13 | #ifndef BNX2X_INIT_H |
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 6425603bc379..50a40e433154 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c | |||
@@ -1425,13 +1425,13 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) | |||
1425 | res = netdev_set_master(slave_dev, bond_dev); | 1425 | res = netdev_set_master(slave_dev, bond_dev); |
1426 | if (res) { | 1426 | if (res) { |
1427 | dprintk("Error %d calling netdev_set_master\n", res); | 1427 | dprintk("Error %d calling netdev_set_master\n", res); |
1428 | goto err_close; | 1428 | goto err_restore_mac; |
1429 | } | 1429 | } |
1430 | /* open the slave since the application closed it */ | 1430 | /* open the slave since the application closed it */ |
1431 | res = dev_open(slave_dev); | 1431 | res = dev_open(slave_dev); |
1432 | if (res) { | 1432 | if (res) { |
1433 | dprintk("Openning slave %s failed\n", slave_dev->name); | 1433 | dprintk("Openning slave %s failed\n", slave_dev->name); |
1434 | goto err_restore_mac; | 1434 | goto err_unset_master; |
1435 | } | 1435 | } |
1436 | 1436 | ||
1437 | new_slave->dev = slave_dev; | 1437 | new_slave->dev = slave_dev; |
@@ -1444,7 +1444,7 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) | |||
1444 | */ | 1444 | */ |
1445 | res = bond_alb_init_slave(bond, new_slave); | 1445 | res = bond_alb_init_slave(bond, new_slave); |
1446 | if (res) { | 1446 | if (res) { |
1447 | goto err_unset_master; | 1447 | goto err_close; |
1448 | } | 1448 | } |
1449 | } | 1449 | } |
1450 | 1450 | ||
@@ -1619,7 +1619,7 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) | |||
1619 | 1619 | ||
1620 | res = bond_create_slave_symlinks(bond_dev, slave_dev); | 1620 | res = bond_create_slave_symlinks(bond_dev, slave_dev); |
1621 | if (res) | 1621 | if (res) |
1622 | goto err_unset_master; | 1622 | goto err_close; |
1623 | 1623 | ||
1624 | printk(KERN_INFO DRV_NAME | 1624 | printk(KERN_INFO DRV_NAME |
1625 | ": %s: enslaving %s as a%s interface with a%s link.\n", | 1625 | ": %s: enslaving %s as a%s interface with a%s link.\n", |
@@ -1631,12 +1631,12 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) | |||
1631 | return 0; | 1631 | return 0; |
1632 | 1632 | ||
1633 | /* Undo stages on error */ | 1633 | /* Undo stages on error */ |
1634 | err_unset_master: | ||
1635 | netdev_set_master(slave_dev, NULL); | ||
1636 | |||
1637 | err_close: | 1634 | err_close: |
1638 | dev_close(slave_dev); | 1635 | dev_close(slave_dev); |
1639 | 1636 | ||
1637 | err_unset_master: | ||
1638 | netdev_set_master(slave_dev, NULL); | ||
1639 | |||
1640 | err_restore_mac: | 1640 | err_restore_mac: |
1641 | if (!bond->params.fail_over_mac) { | 1641 | if (!bond->params.fail_over_mac) { |
1642 | memcpy(addr.sa_data, new_slave->perm_hwaddr, ETH_ALEN); | 1642 | memcpy(addr.sa_data, new_slave->perm_hwaddr, ETH_ALEN); |
@@ -4936,7 +4936,9 @@ int bond_create(char *name, struct bond_params *params, struct bonding **newbond | |||
4936 | if (res < 0) { | 4936 | if (res < 0) { |
4937 | rtnl_lock(); | 4937 | rtnl_lock(); |
4938 | down_write(&bonding_rwsem); | 4938 | down_write(&bonding_rwsem); |
4939 | goto out_bond; | 4939 | bond_deinit(bond_dev); |
4940 | unregister_netdevice(bond_dev); | ||
4941 | goto out_rtnl; | ||
4940 | } | 4942 | } |
4941 | 4943 | ||
4942 | return 0; | 4944 | return 0; |
@@ -4990,9 +4992,10 @@ err: | |||
4990 | destroy_workqueue(bond->wq); | 4992 | destroy_workqueue(bond->wq); |
4991 | } | 4993 | } |
4992 | 4994 | ||
4995 | bond_destroy_sysfs(); | ||
4996 | |||
4993 | rtnl_lock(); | 4997 | rtnl_lock(); |
4994 | bond_free_all(); | 4998 | bond_free_all(); |
4995 | bond_destroy_sysfs(); | ||
4996 | rtnl_unlock(); | 4999 | rtnl_unlock(); |
4997 | out: | 5000 | out: |
4998 | return res; | 5001 | return res; |
@@ -5004,9 +5007,10 @@ static void __exit bonding_exit(void) | |||
5004 | unregister_netdevice_notifier(&bond_netdev_notifier); | 5007 | unregister_netdevice_notifier(&bond_netdev_notifier); |
5005 | unregister_inetaddr_notifier(&bond_inetaddr_notifier); | 5008 | unregister_inetaddr_notifier(&bond_inetaddr_notifier); |
5006 | 5009 | ||
5010 | bond_destroy_sysfs(); | ||
5011 | |||
5007 | rtnl_lock(); | 5012 | rtnl_lock(); |
5008 | bond_free_all(); | 5013 | bond_free_all(); |
5009 | bond_destroy_sysfs(); | ||
5010 | rtnl_unlock(); | 5014 | rtnl_unlock(); |
5011 | } | 5015 | } |
5012 | 5016 | ||
diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c index 979c2d05ff9c..08f3d396bcd6 100644 --- a/drivers/net/bonding/bond_sysfs.c +++ b/drivers/net/bonding/bond_sysfs.c | |||
@@ -146,29 +146,29 @@ static ssize_t bonding_store_bonds(struct class *cls, const char *buffer, size_t | |||
146 | ": Unable remove bond %s due to open references.\n", | 146 | ": Unable remove bond %s due to open references.\n", |
147 | ifname); | 147 | ifname); |
148 | res = -EPERM; | 148 | res = -EPERM; |
149 | goto out; | 149 | goto out_unlock; |
150 | } | 150 | } |
151 | printk(KERN_INFO DRV_NAME | 151 | printk(KERN_INFO DRV_NAME |
152 | ": %s is being deleted...\n", | 152 | ": %s is being deleted...\n", |
153 | bond->dev->name); | 153 | bond->dev->name); |
154 | bond_destroy(bond); | 154 | bond_destroy(bond); |
155 | up_write(&bonding_rwsem); | 155 | goto out_unlock; |
156 | rtnl_unlock(); | ||
157 | goto out; | ||
158 | } | 156 | } |
159 | 157 | ||
160 | printk(KERN_ERR DRV_NAME | 158 | printk(KERN_ERR DRV_NAME |
161 | ": unable to delete non-existent bond %s\n", ifname); | 159 | ": unable to delete non-existent bond %s\n", ifname); |
162 | res = -ENODEV; | 160 | res = -ENODEV; |
163 | up_write(&bonding_rwsem); | 161 | goto out_unlock; |
164 | rtnl_unlock(); | ||
165 | goto out; | ||
166 | } | 162 | } |
167 | 163 | ||
168 | err_no_cmd: | 164 | err_no_cmd: |
169 | printk(KERN_ERR DRV_NAME | 165 | printk(KERN_ERR DRV_NAME |
170 | ": no command found in bonding_masters. Use +ifname or -ifname.\n"); | 166 | ": no command found in bonding_masters. Use +ifname or -ifname.\n"); |
171 | res = -EPERM; | 167 | return -EPERM; |
168 | |||
169 | out_unlock: | ||
170 | up_write(&bonding_rwsem); | ||
171 | rtnl_unlock(); | ||
172 | 172 | ||
173 | /* Always return either count or an error. If you return 0, you'll | 173 | /* Always return either count or an error. If you return 0, you'll |
174 | * get called forever, which is bad. | 174 | * get called forever, which is bad. |
@@ -1437,8 +1437,16 @@ int bond_create_sysfs(void) | |||
1437 | * configure multiple bonding devices. | 1437 | * configure multiple bonding devices. |
1438 | */ | 1438 | */ |
1439 | if (ret == -EEXIST) { | 1439 | if (ret == -EEXIST) { |
1440 | netdev_class = NULL; | 1440 | /* Is someone being kinky and naming a device bonding_master? */ |
1441 | return 0; | 1441 | if (__dev_get_by_name(&init_net, |
1442 | class_attr_bonding_masters.attr.name)) | ||
1443 | printk(KERN_ERR | ||
1444 | "network device named %s already exists in sysfs", | ||
1445 | class_attr_bonding_masters.attr.name); | ||
1446 | else { | ||
1447 | netdev_class = NULL; | ||
1448 | return 0; | ||
1449 | } | ||
1442 | } | 1450 | } |
1443 | 1451 | ||
1444 | return ret; | 1452 | return ret; |
diff --git a/drivers/net/cassini.c b/drivers/net/cassini.c index 93e13636f8dd..83768df27806 100644 --- a/drivers/net/cassini.c +++ b/drivers/net/cassini.c | |||
@@ -142,8 +142,8 @@ | |||
142 | 142 | ||
143 | #define DRV_MODULE_NAME "cassini" | 143 | #define DRV_MODULE_NAME "cassini" |
144 | #define PFX DRV_MODULE_NAME ": " | 144 | #define PFX DRV_MODULE_NAME ": " |
145 | #define DRV_MODULE_VERSION "1.5" | 145 | #define DRV_MODULE_VERSION "1.6" |
146 | #define DRV_MODULE_RELDATE "4 Jan 2008" | 146 | #define DRV_MODULE_RELDATE "21 May 2008" |
147 | 147 | ||
148 | #define CAS_DEF_MSG_ENABLE \ | 148 | #define CAS_DEF_MSG_ENABLE \ |
149 | (NETIF_MSG_DRV | \ | 149 | (NETIF_MSG_DRV | \ |
@@ -2136,9 +2136,12 @@ end_copy_pkt: | |||
2136 | if (addr) | 2136 | if (addr) |
2137 | cas_page_unmap(addr); | 2137 | cas_page_unmap(addr); |
2138 | } | 2138 | } |
2139 | skb->csum = csum_unfold(~csum); | ||
2140 | skb->ip_summed = CHECKSUM_COMPLETE; | ||
2141 | skb->protocol = eth_type_trans(skb, cp->dev); | 2139 | skb->protocol = eth_type_trans(skb, cp->dev); |
2140 | if (skb->protocol == htons(ETH_P_IP)) { | ||
2141 | skb->csum = csum_unfold(~csum); | ||
2142 | skb->ip_summed = CHECKSUM_COMPLETE; | ||
2143 | } else | ||
2144 | skb->ip_summed = CHECKSUM_NONE; | ||
2142 | return len; | 2145 | return len; |
2143 | } | 2146 | } |
2144 | 2147 | ||
diff --git a/drivers/net/cpmac.c b/drivers/net/cpmac.c index 2b5740b3d182..7f3f62e1b113 100644 --- a/drivers/net/cpmac.c +++ b/drivers/net/cpmac.c | |||
@@ -38,6 +38,7 @@ | |||
38 | #include <linux/platform_device.h> | 38 | #include <linux/platform_device.h> |
39 | #include <linux/dma-mapping.h> | 39 | #include <linux/dma-mapping.h> |
40 | #include <asm/gpio.h> | 40 | #include <asm/gpio.h> |
41 | #include <asm/atomic.h> | ||
41 | 42 | ||
42 | MODULE_AUTHOR("Eugene Konev <ejka@imfi.kspu.ru>"); | 43 | MODULE_AUTHOR("Eugene Konev <ejka@imfi.kspu.ru>"); |
43 | MODULE_DESCRIPTION("TI AR7 ethernet driver (CPMAC)"); | 44 | MODULE_DESCRIPTION("TI AR7 ethernet driver (CPMAC)"); |
@@ -187,6 +188,7 @@ struct cpmac_desc { | |||
187 | #define CPMAC_EOQ 0x1000 | 188 | #define CPMAC_EOQ 0x1000 |
188 | struct sk_buff *skb; | 189 | struct sk_buff *skb; |
189 | struct cpmac_desc *next; | 190 | struct cpmac_desc *next; |
191 | struct cpmac_desc *prev; | ||
190 | dma_addr_t mapping; | 192 | dma_addr_t mapping; |
191 | dma_addr_t data_mapping; | 193 | dma_addr_t data_mapping; |
192 | }; | 194 | }; |
@@ -208,6 +210,7 @@ struct cpmac_priv { | |||
208 | struct work_struct reset_work; | 210 | struct work_struct reset_work; |
209 | struct platform_device *pdev; | 211 | struct platform_device *pdev; |
210 | struct napi_struct napi; | 212 | struct napi_struct napi; |
213 | atomic_t reset_pending; | ||
211 | }; | 214 | }; |
212 | 215 | ||
213 | static irqreturn_t cpmac_irq(int, void *); | 216 | static irqreturn_t cpmac_irq(int, void *); |
@@ -241,6 +244,16 @@ static void cpmac_dump_desc(struct net_device *dev, struct cpmac_desc *desc) | |||
241 | printk("\n"); | 244 | printk("\n"); |
242 | } | 245 | } |
243 | 246 | ||
247 | static void cpmac_dump_all_desc(struct net_device *dev) | ||
248 | { | ||
249 | struct cpmac_priv *priv = netdev_priv(dev); | ||
250 | struct cpmac_desc *dump = priv->rx_head; | ||
251 | do { | ||
252 | cpmac_dump_desc(dev, dump); | ||
253 | dump = dump->next; | ||
254 | } while (dump != priv->rx_head); | ||
255 | } | ||
256 | |||
244 | static void cpmac_dump_skb(struct net_device *dev, struct sk_buff *skb) | 257 | static void cpmac_dump_skb(struct net_device *dev, struct sk_buff *skb) |
245 | { | 258 | { |
246 | int i; | 259 | int i; |
@@ -412,21 +425,42 @@ static struct sk_buff *cpmac_rx_one(struct cpmac_priv *priv, | |||
412 | static int cpmac_poll(struct napi_struct *napi, int budget) | 425 | static int cpmac_poll(struct napi_struct *napi, int budget) |
413 | { | 426 | { |
414 | struct sk_buff *skb; | 427 | struct sk_buff *skb; |
415 | struct cpmac_desc *desc; | 428 | struct cpmac_desc *desc, *restart; |
416 | int received = 0; | ||
417 | struct cpmac_priv *priv = container_of(napi, struct cpmac_priv, napi); | 429 | struct cpmac_priv *priv = container_of(napi, struct cpmac_priv, napi); |
430 | int received = 0, processed = 0; | ||
418 | 431 | ||
419 | spin_lock(&priv->rx_lock); | 432 | spin_lock(&priv->rx_lock); |
420 | if (unlikely(!priv->rx_head)) { | 433 | if (unlikely(!priv->rx_head)) { |
421 | if (netif_msg_rx_err(priv) && net_ratelimit()) | 434 | if (netif_msg_rx_err(priv) && net_ratelimit()) |
422 | printk(KERN_WARNING "%s: rx: polling, but no queue\n", | 435 | printk(KERN_WARNING "%s: rx: polling, but no queue\n", |
423 | priv->dev->name); | 436 | priv->dev->name); |
437 | spin_unlock(&priv->rx_lock); | ||
424 | netif_rx_complete(priv->dev, napi); | 438 | netif_rx_complete(priv->dev, napi); |
425 | return 0; | 439 | return 0; |
426 | } | 440 | } |
427 | 441 | ||
428 | desc = priv->rx_head; | 442 | desc = priv->rx_head; |
443 | restart = NULL; | ||
429 | while (((desc->dataflags & CPMAC_OWN) == 0) && (received < budget)) { | 444 | while (((desc->dataflags & CPMAC_OWN) == 0) && (received < budget)) { |
445 | processed++; | ||
446 | |||
447 | if ((desc->dataflags & CPMAC_EOQ) != 0) { | ||
448 | /* The last update to eoq->hw_next didn't happen | ||
449 | * soon enough, and the receiver stopped here. | ||
450 | *Remember this descriptor so we can restart | ||
451 | * the receiver after freeing some space. | ||
452 | */ | ||
453 | if (unlikely(restart)) { | ||
454 | if (netif_msg_rx_err(priv)) | ||
455 | printk(KERN_ERR "%s: poll found a" | ||
456 | " duplicate EOQ: %p and %p\n", | ||
457 | priv->dev->name, restart, desc); | ||
458 | goto fatal_error; | ||
459 | } | ||
460 | |||
461 | restart = desc->next; | ||
462 | } | ||
463 | |||
430 | skb = cpmac_rx_one(priv, desc); | 464 | skb = cpmac_rx_one(priv, desc); |
431 | if (likely(skb)) { | 465 | if (likely(skb)) { |
432 | netif_receive_skb(skb); | 466 | netif_receive_skb(skb); |
@@ -435,19 +469,90 @@ static int cpmac_poll(struct napi_struct *napi, int budget) | |||
435 | desc = desc->next; | 469 | desc = desc->next; |
436 | } | 470 | } |
437 | 471 | ||
472 | if (desc != priv->rx_head) { | ||
473 | /* We freed some buffers, but not the whole ring, | ||
474 | * add what we did free to the rx list */ | ||
475 | desc->prev->hw_next = (u32)0; | ||
476 | priv->rx_head->prev->hw_next = priv->rx_head->mapping; | ||
477 | } | ||
478 | |||
479 | /* Optimization: If we did not actually process an EOQ (perhaps because | ||
480 | * of quota limits), check to see if the tail of the queue has EOQ set. | ||
481 | * We should immediately restart in that case so that the receiver can | ||
482 | * restart and run in parallel with more packet processing. | ||
483 | * This lets us handle slightly larger bursts before running | ||
484 | * out of ring space (assuming dev->weight < ring_size) */ | ||
485 | |||
486 | if (!restart && | ||
487 | (priv->rx_head->prev->dataflags & (CPMAC_OWN|CPMAC_EOQ)) | ||
488 | == CPMAC_EOQ && | ||
489 | (priv->rx_head->dataflags & CPMAC_OWN) != 0) { | ||
490 | /* reset EOQ so the poll loop (above) doesn't try to | ||
491 | * restart this when it eventually gets to this descriptor. | ||
492 | */ | ||
493 | priv->rx_head->prev->dataflags &= ~CPMAC_EOQ; | ||
494 | restart = priv->rx_head; | ||
495 | } | ||
496 | |||
497 | if (restart) { | ||
498 | priv->dev->stats.rx_errors++; | ||
499 | priv->dev->stats.rx_fifo_errors++; | ||
500 | if (netif_msg_rx_err(priv) && net_ratelimit()) | ||
501 | printk(KERN_WARNING "%s: rx dma ring overrun\n", | ||
502 | priv->dev->name); | ||
503 | |||
504 | if (unlikely((restart->dataflags & CPMAC_OWN) == 0)) { | ||
505 | if (netif_msg_drv(priv)) | ||
506 | printk(KERN_ERR "%s: cpmac_poll is trying to " | ||
507 | "restart rx from a descriptor that's " | ||
508 | "not free: %p\n", | ||
509 | priv->dev->name, restart); | ||
510 | goto fatal_error; | ||
511 | } | ||
512 | |||
513 | cpmac_write(priv->regs, CPMAC_RX_PTR(0), restart->mapping); | ||
514 | } | ||
515 | |||
438 | priv->rx_head = desc; | 516 | priv->rx_head = desc; |
439 | spin_unlock(&priv->rx_lock); | 517 | spin_unlock(&priv->rx_lock); |
440 | if (unlikely(netif_msg_rx_status(priv))) | 518 | if (unlikely(netif_msg_rx_status(priv))) |
441 | printk(KERN_DEBUG "%s: poll processed %d packets\n", | 519 | printk(KERN_DEBUG "%s: poll processed %d packets\n", |
442 | priv->dev->name, received); | 520 | priv->dev->name, received); |
443 | if (desc->dataflags & CPMAC_OWN) { | 521 | if (processed == 0) { |
522 | /* we ran out of packets to read, | ||
523 | * revert to interrupt-driven mode */ | ||
444 | netif_rx_complete(priv->dev, napi); | 524 | netif_rx_complete(priv->dev, napi); |
445 | cpmac_write(priv->regs, CPMAC_RX_PTR(0), (u32)desc->mapping); | ||
446 | cpmac_write(priv->regs, CPMAC_RX_INT_ENABLE, 1); | 525 | cpmac_write(priv->regs, CPMAC_RX_INT_ENABLE, 1); |
447 | return 0; | 526 | return 0; |
448 | } | 527 | } |
449 | 528 | ||
450 | return 1; | 529 | return 1; |
530 | |||
531 | fatal_error: | ||
532 | /* Something went horribly wrong. | ||
533 | * Reset hardware to try to recover rather than wedging. */ | ||
534 | |||
535 | if (netif_msg_drv(priv)) { | ||
536 | printk(KERN_ERR "%s: cpmac_poll is confused. " | ||
537 | "Resetting hardware\n", priv->dev->name); | ||
538 | cpmac_dump_all_desc(priv->dev); | ||
539 | printk(KERN_DEBUG "%s: RX_PTR(0)=0x%08x RX_ACK(0)=0x%08x\n", | ||
540 | priv->dev->name, | ||
541 | cpmac_read(priv->regs, CPMAC_RX_PTR(0)), | ||
542 | cpmac_read(priv->regs, CPMAC_RX_ACK(0))); | ||
543 | } | ||
544 | |||
545 | spin_unlock(&priv->rx_lock); | ||
546 | netif_rx_complete(priv->dev, napi); | ||
547 | netif_stop_queue(priv->dev); | ||
548 | napi_disable(&priv->napi); | ||
549 | |||
550 | atomic_inc(&priv->reset_pending); | ||
551 | cpmac_hw_stop(priv->dev); | ||
552 | if (!schedule_work(&priv->reset_work)) | ||
553 | atomic_dec(&priv->reset_pending); | ||
554 | return 0; | ||
555 | |||
451 | } | 556 | } |
452 | 557 | ||
453 | static int cpmac_start_xmit(struct sk_buff *skb, struct net_device *dev) | 558 | static int cpmac_start_xmit(struct sk_buff *skb, struct net_device *dev) |
@@ -456,6 +561,9 @@ static int cpmac_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
456 | struct cpmac_desc *desc; | 561 | struct cpmac_desc *desc; |
457 | struct cpmac_priv *priv = netdev_priv(dev); | 562 | struct cpmac_priv *priv = netdev_priv(dev); |
458 | 563 | ||
564 | if (unlikely(atomic_read(&priv->reset_pending))) | ||
565 | return NETDEV_TX_BUSY; | ||
566 | |||
459 | if (unlikely(skb_padto(skb, ETH_ZLEN))) | 567 | if (unlikely(skb_padto(skb, ETH_ZLEN))) |
460 | return NETDEV_TX_OK; | 568 | return NETDEV_TX_OK; |
461 | 569 | ||
@@ -621,8 +729,10 @@ static void cpmac_clear_rx(struct net_device *dev) | |||
621 | desc->dataflags = CPMAC_OWN; | 729 | desc->dataflags = CPMAC_OWN; |
622 | dev->stats.rx_dropped++; | 730 | dev->stats.rx_dropped++; |
623 | } | 731 | } |
732 | desc->hw_next = desc->next->mapping; | ||
624 | desc = desc->next; | 733 | desc = desc->next; |
625 | } | 734 | } |
735 | priv->rx_head->prev->hw_next = 0; | ||
626 | } | 736 | } |
627 | 737 | ||
628 | static void cpmac_clear_tx(struct net_device *dev) | 738 | static void cpmac_clear_tx(struct net_device *dev) |
@@ -635,14 +745,14 @@ static void cpmac_clear_tx(struct net_device *dev) | |||
635 | priv->desc_ring[i].dataflags = 0; | 745 | priv->desc_ring[i].dataflags = 0; |
636 | if (priv->desc_ring[i].skb) { | 746 | if (priv->desc_ring[i].skb) { |
637 | dev_kfree_skb_any(priv->desc_ring[i].skb); | 747 | dev_kfree_skb_any(priv->desc_ring[i].skb); |
638 | if (netif_subqueue_stopped(dev, i)) | 748 | priv->desc_ring[i].skb = NULL; |
639 | netif_wake_subqueue(dev, i); | ||
640 | } | 749 | } |
641 | } | 750 | } |
642 | } | 751 | } |
643 | 752 | ||
644 | static void cpmac_hw_error(struct work_struct *work) | 753 | static void cpmac_hw_error(struct work_struct *work) |
645 | { | 754 | { |
755 | int i; | ||
646 | struct cpmac_priv *priv = | 756 | struct cpmac_priv *priv = |
647 | container_of(work, struct cpmac_priv, reset_work); | 757 | container_of(work, struct cpmac_priv, reset_work); |
648 | 758 | ||
@@ -651,8 +761,48 @@ static void cpmac_hw_error(struct work_struct *work) | |||
651 | spin_unlock(&priv->rx_lock); | 761 | spin_unlock(&priv->rx_lock); |
652 | cpmac_clear_tx(priv->dev); | 762 | cpmac_clear_tx(priv->dev); |
653 | cpmac_hw_start(priv->dev); | 763 | cpmac_hw_start(priv->dev); |
654 | napi_enable(&priv->napi); | 764 | barrier(); |
655 | netif_start_queue(priv->dev); | 765 | atomic_dec(&priv->reset_pending); |
766 | |||
767 | for (i = 0; i < CPMAC_QUEUES; i++) | ||
768 | netif_wake_subqueue(priv->dev, i); | ||
769 | netif_wake_queue(priv->dev); | ||
770 | cpmac_write(priv->regs, CPMAC_MAC_INT_ENABLE, 3); | ||
771 | } | ||
772 | |||
773 | static void cpmac_check_status(struct net_device *dev) | ||
774 | { | ||
775 | struct cpmac_priv *priv = netdev_priv(dev); | ||
776 | |||
777 | u32 macstatus = cpmac_read(priv->regs, CPMAC_MAC_STATUS); | ||
778 | int rx_channel = (macstatus >> 8) & 7; | ||
779 | int rx_code = (macstatus >> 12) & 15; | ||
780 | int tx_channel = (macstatus >> 16) & 7; | ||
781 | int tx_code = (macstatus >> 20) & 15; | ||
782 | |||
783 | if (rx_code || tx_code) { | ||
784 | if (netif_msg_drv(priv) && net_ratelimit()) { | ||
785 | /* Can't find any documentation on what these | ||
786 | *error codes actually are. So just log them and hope.. | ||
787 | */ | ||
788 | if (rx_code) | ||
789 | printk(KERN_WARNING "%s: host error %d on rx " | ||
790 | "channel %d (macstatus %08x), resetting\n", | ||
791 | dev->name, rx_code, rx_channel, macstatus); | ||
792 | if (tx_code) | ||
793 | printk(KERN_WARNING "%s: host error %d on tx " | ||
794 | "channel %d (macstatus %08x), resetting\n", | ||
795 | dev->name, tx_code, tx_channel, macstatus); | ||
796 | } | ||
797 | |||
798 | netif_stop_queue(dev); | ||
799 | cpmac_hw_stop(dev); | ||
800 | if (schedule_work(&priv->reset_work)) | ||
801 | atomic_inc(&priv->reset_pending); | ||
802 | if (unlikely(netif_msg_hw(priv))) | ||
803 | cpmac_dump_regs(dev); | ||
804 | } | ||
805 | cpmac_write(priv->regs, CPMAC_MAC_INT_CLEAR, 0xff); | ||
656 | } | 806 | } |
657 | 807 | ||
658 | static irqreturn_t cpmac_irq(int irq, void *dev_id) | 808 | static irqreturn_t cpmac_irq(int irq, void *dev_id) |
@@ -683,49 +833,32 @@ static irqreturn_t cpmac_irq(int irq, void *dev_id) | |||
683 | 833 | ||
684 | cpmac_write(priv->regs, CPMAC_MAC_EOI_VECTOR, 0); | 834 | cpmac_write(priv->regs, CPMAC_MAC_EOI_VECTOR, 0); |
685 | 835 | ||
686 | if (unlikely(status & (MAC_INT_HOST | MAC_INT_STATUS))) { | 836 | if (unlikely(status & (MAC_INT_HOST | MAC_INT_STATUS))) |
687 | if (netif_msg_drv(priv) && net_ratelimit()) | 837 | cpmac_check_status(dev); |
688 | printk(KERN_ERR "%s: hw error, resetting...\n", | ||
689 | dev->name); | ||
690 | netif_stop_queue(dev); | ||
691 | napi_disable(&priv->napi); | ||
692 | cpmac_hw_stop(dev); | ||
693 | schedule_work(&priv->reset_work); | ||
694 | if (unlikely(netif_msg_hw(priv))) | ||
695 | cpmac_dump_regs(dev); | ||
696 | } | ||
697 | 838 | ||
698 | return IRQ_HANDLED; | 839 | return IRQ_HANDLED; |
699 | } | 840 | } |
700 | 841 | ||
701 | static void cpmac_tx_timeout(struct net_device *dev) | 842 | static void cpmac_tx_timeout(struct net_device *dev) |
702 | { | 843 | { |
703 | struct cpmac_priv *priv = netdev_priv(dev); | ||
704 | int i; | 844 | int i; |
845 | struct cpmac_priv *priv = netdev_priv(dev); | ||
705 | 846 | ||
706 | spin_lock(&priv->lock); | 847 | spin_lock(&priv->lock); |
707 | dev->stats.tx_errors++; | 848 | dev->stats.tx_errors++; |
708 | spin_unlock(&priv->lock); | 849 | spin_unlock(&priv->lock); |
709 | if (netif_msg_tx_err(priv) && net_ratelimit()) | 850 | if (netif_msg_tx_err(priv) && net_ratelimit()) |
710 | printk(KERN_WARNING "%s: transmit timeout\n", dev->name); | 851 | printk(KERN_WARNING "%s: transmit timeout\n", dev->name); |
711 | /* | 852 | |
712 | * FIXME: waking up random queue is not the best thing to | 853 | atomic_inc(&priv->reset_pending); |
713 | * do... on the other hand why we got here at all? | 854 | barrier(); |
714 | */ | 855 | cpmac_clear_tx(dev); |
715 | #ifdef CONFIG_NETDEVICES_MULTIQUEUE | 856 | barrier(); |
857 | atomic_dec(&priv->reset_pending); | ||
858 | |||
859 | netif_wake_queue(priv->dev); | ||
716 | for (i = 0; i < CPMAC_QUEUES; i++) | 860 | for (i = 0; i < CPMAC_QUEUES; i++) |
717 | if (priv->desc_ring[i].skb) { | 861 | netif_wake_subqueue(dev, i); |
718 | priv->desc_ring[i].dataflags = 0; | ||
719 | dev_kfree_skb_any(priv->desc_ring[i].skb); | ||
720 | netif_wake_subqueue(dev, i); | ||
721 | break; | ||
722 | } | ||
723 | #else | ||
724 | priv->desc_ring[0].dataflags = 0; | ||
725 | if (priv->desc_ring[0].skb) | ||
726 | dev_kfree_skb_any(priv->desc_ring[0].skb); | ||
727 | netif_wake_queue(dev); | ||
728 | #endif | ||
729 | } | 862 | } |
730 | 863 | ||
731 | static int cpmac_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) | 864 | static int cpmac_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) |
@@ -901,9 +1034,12 @@ static int cpmac_open(struct net_device *dev) | |||
901 | desc->buflen = CPMAC_SKB_SIZE; | 1034 | desc->buflen = CPMAC_SKB_SIZE; |
902 | desc->dataflags = CPMAC_OWN; | 1035 | desc->dataflags = CPMAC_OWN; |
903 | desc->next = &priv->rx_head[(i + 1) % priv->ring_size]; | 1036 | desc->next = &priv->rx_head[(i + 1) % priv->ring_size]; |
1037 | desc->next->prev = desc; | ||
904 | desc->hw_next = (u32)desc->next->mapping; | 1038 | desc->hw_next = (u32)desc->next->mapping; |
905 | } | 1039 | } |
906 | 1040 | ||
1041 | priv->rx_head->prev->hw_next = (u32)0; | ||
1042 | |||
907 | if ((res = request_irq(dev->irq, cpmac_irq, IRQF_SHARED, | 1043 | if ((res = request_irq(dev->irq, cpmac_irq, IRQF_SHARED, |
908 | dev->name, dev))) { | 1044 | dev->name, dev))) { |
909 | if (netif_msg_drv(priv)) | 1045 | if (netif_msg_drv(priv)) |
@@ -912,6 +1048,7 @@ static int cpmac_open(struct net_device *dev) | |||
912 | goto fail_irq; | 1048 | goto fail_irq; |
913 | } | 1049 | } |
914 | 1050 | ||
1051 | atomic_set(&priv->reset_pending, 0); | ||
915 | INIT_WORK(&priv->reset_work, cpmac_hw_error); | 1052 | INIT_WORK(&priv->reset_work, cpmac_hw_error); |
916 | cpmac_hw_start(dev); | 1053 | cpmac_hw_start(dev); |
917 | 1054 | ||
@@ -1007,21 +1144,10 @@ static int __devinit cpmac_probe(struct platform_device *pdev) | |||
1007 | 1144 | ||
1008 | if (phy_id == PHY_MAX_ADDR) { | 1145 | if (phy_id == PHY_MAX_ADDR) { |
1009 | if (external_switch || dumb_switch) { | 1146 | if (external_switch || dumb_switch) { |
1010 | struct fixed_phy_status status = {}; | 1147 | mdio_bus_id = 0; /* fixed phys bus */ |
1011 | 1148 | phy_id = pdev->id; | |
1012 | /* | ||
1013 | * FIXME: this should be in the platform code! | ||
1014 | * Since there is not platform code at all (that is, | ||
1015 | * no mainline users of that driver), place it here | ||
1016 | * for now. | ||
1017 | */ | ||
1018 | phy_id = 0; | ||
1019 | status.link = 1; | ||
1020 | status.duplex = 1; | ||
1021 | status.speed = 100; | ||
1022 | fixed_phy_add(PHY_POLL, phy_id, &status); | ||
1023 | } else { | 1149 | } else { |
1024 | printk(KERN_ERR "cpmac: no PHY present\n"); | 1150 | dev_err(&pdev->dev, "no PHY present\n"); |
1025 | return -ENODEV; | 1151 | return -ENODEV; |
1026 | } | 1152 | } |
1027 | } | 1153 | } |
@@ -1064,10 +1190,8 @@ static int __devinit cpmac_probe(struct platform_device *pdev) | |||
1064 | priv->msg_enable = netif_msg_init(debug_level, 0xff); | 1190 | priv->msg_enable = netif_msg_init(debug_level, 0xff); |
1065 | memcpy(dev->dev_addr, pdata->dev_addr, sizeof(dev->dev_addr)); | 1191 | memcpy(dev->dev_addr, pdata->dev_addr, sizeof(dev->dev_addr)); |
1066 | 1192 | ||
1067 | snprintf(priv->phy_name, BUS_ID_SIZE, PHY_ID_FMT, mdio_bus_id, phy_id); | 1193 | priv->phy = phy_connect(dev, cpmac_mii.phy_map[phy_id]->dev.bus_id, |
1068 | 1194 | &cpmac_adjust_link, 0, PHY_INTERFACE_MODE_MII); | |
1069 | priv->phy = phy_connect(dev, priv->phy_name, &cpmac_adjust_link, 0, | ||
1070 | PHY_INTERFACE_MODE_MII); | ||
1071 | if (IS_ERR(priv->phy)) { | 1195 | if (IS_ERR(priv->phy)) { |
1072 | if (netif_msg_drv(priv)) | 1196 | if (netif_msg_drv(priv)) |
1073 | printk(KERN_ERR "%s: Could not attach to PHY\n", | 1197 | printk(KERN_ERR "%s: Could not attach to PHY\n", |
diff --git a/drivers/net/cs89x0.c b/drivers/net/cs89x0.c index 348371fda597..fba87abe78ee 100644 --- a/drivers/net/cs89x0.c +++ b/drivers/net/cs89x0.c | |||
@@ -1394,7 +1394,11 @@ net_open(struct net_device *dev) | |||
1394 | #endif | 1394 | #endif |
1395 | if (!result) { | 1395 | if (!result) { |
1396 | printk(KERN_ERR "%s: EEPROM is configured for unavailable media\n", dev->name); | 1396 | printk(KERN_ERR "%s: EEPROM is configured for unavailable media\n", dev->name); |
1397 | release_irq: | 1397 | release_dma: |
1398 | #if ALLOW_DMA | ||
1399 | free_dma(dev->dma); | ||
1400 | #endif | ||
1401 | release_irq: | ||
1398 | #if ALLOW_DMA | 1402 | #if ALLOW_DMA |
1399 | release_dma_buff(lp); | 1403 | release_dma_buff(lp); |
1400 | #endif | 1404 | #endif |
@@ -1442,12 +1446,12 @@ net_open(struct net_device *dev) | |||
1442 | if ((result = detect_bnc(dev)) != DETECTED_NONE) | 1446 | if ((result = detect_bnc(dev)) != DETECTED_NONE) |
1443 | break; | 1447 | break; |
1444 | printk(KERN_ERR "%s: no media detected\n", dev->name); | 1448 | printk(KERN_ERR "%s: no media detected\n", dev->name); |
1445 | goto release_irq; | 1449 | goto release_dma; |
1446 | } | 1450 | } |
1447 | switch(result) { | 1451 | switch(result) { |
1448 | case DETECTED_NONE: | 1452 | case DETECTED_NONE: |
1449 | printk(KERN_ERR "%s: no network cable attached to configured media\n", dev->name); | 1453 | printk(KERN_ERR "%s: no network cable attached to configured media\n", dev->name); |
1450 | goto release_irq; | 1454 | goto release_dma; |
1451 | case DETECTED_RJ45H: | 1455 | case DETECTED_RJ45H: |
1452 | printk(KERN_INFO "%s: using half-duplex 10Base-T (RJ-45)\n", dev->name); | 1456 | printk(KERN_INFO "%s: using half-duplex 10Base-T (RJ-45)\n", dev->name); |
1453 | break; | 1457 | break; |
diff --git a/drivers/net/cxgb3/adapter.h b/drivers/net/cxgb3/adapter.h index 4fdb13f8447b..acebe431d068 100644 --- a/drivers/net/cxgb3/adapter.h +++ b/drivers/net/cxgb3/adapter.h | |||
@@ -71,6 +71,7 @@ enum { /* adapter flags */ | |||
71 | USING_MSIX = (1 << 2), | 71 | USING_MSIX = (1 << 2), |
72 | QUEUES_BOUND = (1 << 3), | 72 | QUEUES_BOUND = (1 << 3), |
73 | TP_PARITY_INIT = (1 << 4), | 73 | TP_PARITY_INIT = (1 << 4), |
74 | NAPI_INIT = (1 << 5), | ||
74 | }; | 75 | }; |
75 | 76 | ||
76 | struct fl_pg_chunk { | 77 | struct fl_pg_chunk { |
diff --git a/drivers/net/cxgb3/common.h b/drivers/net/cxgb3/common.h index 91ee7277b813..579bee42a5cb 100644 --- a/drivers/net/cxgb3/common.h +++ b/drivers/net/cxgb3/common.h | |||
@@ -698,6 +698,7 @@ void mac_prep(struct cmac *mac, struct adapter *adapter, int index); | |||
698 | void early_hw_init(struct adapter *adapter, const struct adapter_info *ai); | 698 | void early_hw_init(struct adapter *adapter, const struct adapter_info *ai); |
699 | int t3_prep_adapter(struct adapter *adapter, const struct adapter_info *ai, | 699 | int t3_prep_adapter(struct adapter *adapter, const struct adapter_info *ai, |
700 | int reset); | 700 | int reset); |
701 | int t3_replay_prep_adapter(struct adapter *adapter); | ||
701 | void t3_led_ready(struct adapter *adapter); | 702 | void t3_led_ready(struct adapter *adapter); |
702 | void t3_fatal_err(struct adapter *adapter); | 703 | void t3_fatal_err(struct adapter *adapter); |
703 | void t3_set_vlan_accel(struct adapter *adapter, unsigned int ports, int on); | 704 | void t3_set_vlan_accel(struct adapter *adapter, unsigned int ports, int on); |
diff --git a/drivers/net/cxgb3/cxgb3_main.c b/drivers/net/cxgb3/cxgb3_main.c index 05e5f59e87fa..3a3127216791 100644 --- a/drivers/net/cxgb3/cxgb3_main.c +++ b/drivers/net/cxgb3/cxgb3_main.c | |||
@@ -421,6 +421,13 @@ static void init_napi(struct adapter *adap) | |||
421 | netif_napi_add(qs->netdev, &qs->napi, qs->napi.poll, | 421 | netif_napi_add(qs->netdev, &qs->napi, qs->napi.poll, |
422 | 64); | 422 | 64); |
423 | } | 423 | } |
424 | |||
425 | /* | ||
426 | * netif_napi_add() can be called only once per napi_struct because it | ||
427 | * adds each new napi_struct to a list. Be careful not to call it a | ||
428 | * second time, e.g., during EEH recovery, by making a note of it. | ||
429 | */ | ||
430 | adap->flags |= NAPI_INIT; | ||
424 | } | 431 | } |
425 | 432 | ||
426 | /* | 433 | /* |
@@ -896,7 +903,8 @@ static int cxgb_up(struct adapter *adap) | |||
896 | goto out; | 903 | goto out; |
897 | 904 | ||
898 | setup_rss(adap); | 905 | setup_rss(adap); |
899 | init_napi(adap); | 906 | if (!(adap->flags & NAPI_INIT)) |
907 | init_napi(adap); | ||
900 | adap->flags |= FULL_INIT_DONE; | 908 | adap->flags |= FULL_INIT_DONE; |
901 | } | 909 | } |
902 | 910 | ||
@@ -999,7 +1007,7 @@ static int offload_open(struct net_device *dev) | |||
999 | return 0; | 1007 | return 0; |
1000 | 1008 | ||
1001 | if (!adap_up && (err = cxgb_up(adapter)) < 0) | 1009 | if (!adap_up && (err = cxgb_up(adapter)) < 0) |
1002 | return err; | 1010 | goto out; |
1003 | 1011 | ||
1004 | t3_tp_set_offload_mode(adapter, 1); | 1012 | t3_tp_set_offload_mode(adapter, 1); |
1005 | tdev->lldev = adapter->port[0]; | 1013 | tdev->lldev = adapter->port[0]; |
@@ -1061,10 +1069,8 @@ static int cxgb_open(struct net_device *dev) | |||
1061 | int other_ports = adapter->open_device_map & PORT_MASK; | 1069 | int other_ports = adapter->open_device_map & PORT_MASK; |
1062 | int err; | 1070 | int err; |
1063 | 1071 | ||
1064 | if (!adapter->open_device_map && (err = cxgb_up(adapter)) < 0) { | 1072 | if (!adapter->open_device_map && (err = cxgb_up(adapter)) < 0) |
1065 | quiesce_rx(adapter); | ||
1066 | return err; | 1073 | return err; |
1067 | } | ||
1068 | 1074 | ||
1069 | set_bit(pi->port_id, &adapter->open_device_map); | 1075 | set_bit(pi->port_id, &adapter->open_device_map); |
1070 | if (is_offload(adapter) && !ofld_disable) { | 1076 | if (is_offload(adapter) && !ofld_disable) { |
@@ -1894,11 +1900,11 @@ static int cxgb_extension_ioctl(struct net_device *dev, void __user *useraddr) | |||
1894 | u8 *fw_data; | 1900 | u8 *fw_data; |
1895 | struct ch_mem_range t; | 1901 | struct ch_mem_range t; |
1896 | 1902 | ||
1897 | if (!capable(CAP_NET_ADMIN)) | 1903 | if (!capable(CAP_SYS_RAWIO)) |
1898 | return -EPERM; | 1904 | return -EPERM; |
1899 | if (copy_from_user(&t, useraddr, sizeof(t))) | 1905 | if (copy_from_user(&t, useraddr, sizeof(t))) |
1900 | return -EFAULT; | 1906 | return -EFAULT; |
1901 | 1907 | /* Check t.len sanity ? */ | |
1902 | fw_data = kmalloc(t.len, GFP_KERNEL); | 1908 | fw_data = kmalloc(t.len, GFP_KERNEL); |
1903 | if (!fw_data) | 1909 | if (!fw_data) |
1904 | return -ENOMEM; | 1910 | return -ENOMEM; |
@@ -2424,14 +2430,11 @@ static pci_ers_result_t t3_io_error_detected(struct pci_dev *pdev, | |||
2424 | test_bit(OFFLOAD_DEVMAP_BIT, &adapter->open_device_map)) | 2430 | test_bit(OFFLOAD_DEVMAP_BIT, &adapter->open_device_map)) |
2425 | offload_close(&adapter->tdev); | 2431 | offload_close(&adapter->tdev); |
2426 | 2432 | ||
2427 | /* Free sge resources */ | ||
2428 | t3_free_sge_resources(adapter); | ||
2429 | |||
2430 | adapter->flags &= ~FULL_INIT_DONE; | 2433 | adapter->flags &= ~FULL_INIT_DONE; |
2431 | 2434 | ||
2432 | pci_disable_device(pdev); | 2435 | pci_disable_device(pdev); |
2433 | 2436 | ||
2434 | /* Request a slot slot reset. */ | 2437 | /* Request a slot reset. */ |
2435 | return PCI_ERS_RESULT_NEED_RESET; | 2438 | return PCI_ERS_RESULT_NEED_RESET; |
2436 | } | 2439 | } |
2437 | 2440 | ||
@@ -2448,13 +2451,20 @@ static pci_ers_result_t t3_io_slot_reset(struct pci_dev *pdev) | |||
2448 | if (pci_enable_device(pdev)) { | 2451 | if (pci_enable_device(pdev)) { |
2449 | dev_err(&pdev->dev, | 2452 | dev_err(&pdev->dev, |
2450 | "Cannot re-enable PCI device after reset.\n"); | 2453 | "Cannot re-enable PCI device after reset.\n"); |
2451 | return PCI_ERS_RESULT_DISCONNECT; | 2454 | goto err; |
2452 | } | 2455 | } |
2453 | pci_set_master(pdev); | 2456 | pci_set_master(pdev); |
2457 | pci_restore_state(pdev); | ||
2454 | 2458 | ||
2455 | t3_prep_adapter(adapter, adapter->params.info, 1); | 2459 | /* Free sge resources */ |
2460 | t3_free_sge_resources(adapter); | ||
2461 | |||
2462 | if (t3_replay_prep_adapter(adapter)) | ||
2463 | goto err; | ||
2456 | 2464 | ||
2457 | return PCI_ERS_RESULT_RECOVERED; | 2465 | return PCI_ERS_RESULT_RECOVERED; |
2466 | err: | ||
2467 | return PCI_ERS_RESULT_DISCONNECT; | ||
2458 | } | 2468 | } |
2459 | 2469 | ||
2460 | /** | 2470 | /** |
@@ -2483,13 +2493,6 @@ static void t3_io_resume(struct pci_dev *pdev) | |||
2483 | netif_device_attach(netdev); | 2493 | netif_device_attach(netdev); |
2484 | } | 2494 | } |
2485 | } | 2495 | } |
2486 | |||
2487 | if (is_offload(adapter)) { | ||
2488 | __set_bit(OFFLOAD_DEVMAP_BIT, &adapter->registered_device_map); | ||
2489 | if (offload_open(adapter->port[0])) | ||
2490 | printk(KERN_WARNING | ||
2491 | "Could not bring back offload capabilities\n"); | ||
2492 | } | ||
2493 | } | 2496 | } |
2494 | 2497 | ||
2495 | static struct pci_error_handlers t3_err_handler = { | 2498 | static struct pci_error_handlers t3_err_handler = { |
@@ -2608,6 +2611,7 @@ static int __devinit init_one(struct pci_dev *pdev, | |||
2608 | } | 2611 | } |
2609 | 2612 | ||
2610 | pci_set_master(pdev); | 2613 | pci_set_master(pdev); |
2614 | pci_save_state(pdev); | ||
2611 | 2615 | ||
2612 | mmio_start = pci_resource_start(pdev, 0); | 2616 | mmio_start = pci_resource_start(pdev, 0); |
2613 | mmio_len = pci_resource_len(pdev, 0); | 2617 | mmio_len = pci_resource_len(pdev, 0); |
diff --git a/drivers/net/cxgb3/regs.h b/drivers/net/cxgb3/regs.h index 02dbbb300929..567178879345 100644 --- a/drivers/net/cxgb3/regs.h +++ b/drivers/net/cxgb3/regs.h | |||
@@ -444,6 +444,14 @@ | |||
444 | 444 | ||
445 | #define A_PCIE_CFG 0x88 | 445 | #define A_PCIE_CFG 0x88 |
446 | 446 | ||
447 | #define S_ENABLELINKDWNDRST 21 | ||
448 | #define V_ENABLELINKDWNDRST(x) ((x) << S_ENABLELINKDWNDRST) | ||
449 | #define F_ENABLELINKDWNDRST V_ENABLELINKDWNDRST(1U) | ||
450 | |||
451 | #define S_ENABLELINKDOWNRST 20 | ||
452 | #define V_ENABLELINKDOWNRST(x) ((x) << S_ENABLELINKDOWNRST) | ||
453 | #define F_ENABLELINKDOWNRST V_ENABLELINKDOWNRST(1U) | ||
454 | |||
447 | #define S_PCIE_CLIDECEN 16 | 455 | #define S_PCIE_CLIDECEN 16 |
448 | #define V_PCIE_CLIDECEN(x) ((x) << S_PCIE_CLIDECEN) | 456 | #define V_PCIE_CLIDECEN(x) ((x) << S_PCIE_CLIDECEN) |
449 | #define F_PCIE_CLIDECEN V_PCIE_CLIDECEN(1U) | 457 | #define F_PCIE_CLIDECEN V_PCIE_CLIDECEN(1U) |
diff --git a/drivers/net/cxgb3/sge.c b/drivers/net/cxgb3/sge.c index 98a6bbd11d4c..796eb305cdc3 100644 --- a/drivers/net/cxgb3/sge.c +++ b/drivers/net/cxgb3/sge.c | |||
@@ -539,6 +539,31 @@ static void *alloc_ring(struct pci_dev *pdev, size_t nelem, size_t elem_size, | |||
539 | } | 539 | } |
540 | 540 | ||
541 | /** | 541 | /** |
542 | * t3_reset_qset - reset a sge qset | ||
543 | * @q: the queue set | ||
544 | * | ||
545 | * Reset the qset structure. | ||
546 | * the NAPI structure is preserved in the event of | ||
547 | * the qset's reincarnation, for example during EEH recovery. | ||
548 | */ | ||
549 | static void t3_reset_qset(struct sge_qset *q) | ||
550 | { | ||
551 | if (q->adap && | ||
552 | !(q->adap->flags & NAPI_INIT)) { | ||
553 | memset(q, 0, sizeof(*q)); | ||
554 | return; | ||
555 | } | ||
556 | |||
557 | q->adap = NULL; | ||
558 | memset(&q->rspq, 0, sizeof(q->rspq)); | ||
559 | memset(q->fl, 0, sizeof(struct sge_fl) * SGE_RXQ_PER_SET); | ||
560 | memset(q->txq, 0, sizeof(struct sge_txq) * SGE_TXQ_PER_SET); | ||
561 | q->txq_stopped = 0; | ||
562 | memset(&q->tx_reclaim_timer, 0, sizeof(q->tx_reclaim_timer)); | ||
563 | } | ||
564 | |||
565 | |||
566 | /** | ||
542 | * free_qset - free the resources of an SGE queue set | 567 | * free_qset - free the resources of an SGE queue set |
543 | * @adapter: the adapter owning the queue set | 568 | * @adapter: the adapter owning the queue set |
544 | * @q: the queue set | 569 | * @q: the queue set |
@@ -594,7 +619,7 @@ static void t3_free_qset(struct adapter *adapter, struct sge_qset *q) | |||
594 | q->rspq.desc, q->rspq.phys_addr); | 619 | q->rspq.desc, q->rspq.phys_addr); |
595 | } | 620 | } |
596 | 621 | ||
597 | memset(q, 0, sizeof(*q)); | 622 | t3_reset_qset(q); |
598 | } | 623 | } |
599 | 624 | ||
600 | /** | 625 | /** |
@@ -1365,7 +1390,7 @@ static void restart_ctrlq(unsigned long data) | |||
1365 | */ | 1390 | */ |
1366 | int t3_mgmt_tx(struct adapter *adap, struct sk_buff *skb) | 1391 | int t3_mgmt_tx(struct adapter *adap, struct sk_buff *skb) |
1367 | { | 1392 | { |
1368 | int ret; | 1393 | int ret; |
1369 | local_bh_disable(); | 1394 | local_bh_disable(); |
1370 | ret = ctrl_xmit(adap, &adap->sge.qs[0].txq[TXQ_CTRL], skb); | 1395 | ret = ctrl_xmit(adap, &adap->sge.qs[0].txq[TXQ_CTRL], skb); |
1371 | local_bh_enable(); | 1396 | local_bh_enable(); |
diff --git a/drivers/net/cxgb3/t3_hw.c b/drivers/net/cxgb3/t3_hw.c index a99496a431c4..d405a932c73a 100644 --- a/drivers/net/cxgb3/t3_hw.c +++ b/drivers/net/cxgb3/t3_hw.c | |||
@@ -3264,6 +3264,7 @@ static void config_pcie(struct adapter *adap) | |||
3264 | 3264 | ||
3265 | t3_write_reg(adap, A_PCIE_PEX_ERR, 0xffffffff); | 3265 | t3_write_reg(adap, A_PCIE_PEX_ERR, 0xffffffff); |
3266 | t3_set_reg_field(adap, A_PCIE_CFG, 0, | 3266 | t3_set_reg_field(adap, A_PCIE_CFG, 0, |
3267 | F_ENABLELINKDWNDRST | F_ENABLELINKDOWNRST | | ||
3267 | F_PCIE_DMASTOPEN | F_PCIE_CLIDECEN); | 3268 | F_PCIE_DMASTOPEN | F_PCIE_CLIDECEN); |
3268 | } | 3269 | } |
3269 | 3270 | ||
@@ -3655,3 +3656,30 @@ void t3_led_ready(struct adapter *adapter) | |||
3655 | t3_set_reg_field(adapter, A_T3DBG_GPIO_EN, F_GPIO0_OUT_VAL, | 3656 | t3_set_reg_field(adapter, A_T3DBG_GPIO_EN, F_GPIO0_OUT_VAL, |
3656 | F_GPIO0_OUT_VAL); | 3657 | F_GPIO0_OUT_VAL); |
3657 | } | 3658 | } |
3659 | |||
3660 | int t3_replay_prep_adapter(struct adapter *adapter) | ||
3661 | { | ||
3662 | const struct adapter_info *ai = adapter->params.info; | ||
3663 | unsigned int i, j = 0; | ||
3664 | int ret; | ||
3665 | |||
3666 | early_hw_init(adapter, ai); | ||
3667 | ret = init_parity(adapter); | ||
3668 | if (ret) | ||
3669 | return ret; | ||
3670 | |||
3671 | for_each_port(adapter, i) { | ||
3672 | struct port_info *p = adap2pinfo(adapter, i); | ||
3673 | while (!adapter->params.vpd.port_type[j]) | ||
3674 | ++j; | ||
3675 | |||
3676 | p->port_type->phy_prep(&p->phy, adapter, ai->phy_base_addr + j, | ||
3677 | ai->mdio_ops); | ||
3678 | |||
3679 | p->phy.ops->power_down(&p->phy, 1); | ||
3680 | ++j; | ||
3681 | } | ||
3682 | |||
3683 | return 0; | ||
3684 | } | ||
3685 | |||
diff --git a/drivers/net/dm9000.c b/drivers/net/dm9000.c index e6fe2614ea6d..864295e081b6 100644 --- a/drivers/net/dm9000.c +++ b/drivers/net/dm9000.c | |||
@@ -117,6 +117,9 @@ typedef struct board_info { | |||
117 | 117 | ||
118 | struct mutex addr_lock; /* phy and eeprom access lock */ | 118 | struct mutex addr_lock; /* phy and eeprom access lock */ |
119 | 119 | ||
120 | struct delayed_work phy_poll; | ||
121 | struct net_device *ndev; | ||
122 | |||
120 | spinlock_t lock; | 123 | spinlock_t lock; |
121 | 124 | ||
122 | struct mii_if_info mii; | 125 | struct mii_if_info mii; |
@@ -297,6 +300,10 @@ static void dm9000_set_io(struct board_info *db, int byte_width) | |||
297 | } | 300 | } |
298 | } | 301 | } |
299 | 302 | ||
303 | static void dm9000_schedule_poll(board_info_t *db) | ||
304 | { | ||
305 | schedule_delayed_work(&db->phy_poll, HZ * 2); | ||
306 | } | ||
300 | 307 | ||
301 | /* Our watchdog timed out. Called by the networking layer */ | 308 | /* Our watchdog timed out. Called by the networking layer */ |
302 | static void dm9000_timeout(struct net_device *dev) | 309 | static void dm9000_timeout(struct net_device *dev) |
@@ -465,6 +472,17 @@ static const struct ethtool_ops dm9000_ethtool_ops = { | |||
465 | .set_eeprom = dm9000_set_eeprom, | 472 | .set_eeprom = dm9000_set_eeprom, |
466 | }; | 473 | }; |
467 | 474 | ||
475 | static void | ||
476 | dm9000_poll_work(struct work_struct *w) | ||
477 | { | ||
478 | struct delayed_work *dw = container_of(w, struct delayed_work, work); | ||
479 | board_info_t *db = container_of(dw, board_info_t, phy_poll); | ||
480 | |||
481 | mii_check_media(&db->mii, netif_msg_link(db), 0); | ||
482 | |||
483 | if (netif_running(db->ndev)) | ||
484 | dm9000_schedule_poll(db); | ||
485 | } | ||
468 | 486 | ||
469 | /* dm9000_release_board | 487 | /* dm9000_release_board |
470 | * | 488 | * |
@@ -503,7 +521,7 @@ dm9000_release_board(struct platform_device *pdev, struct board_info *db) | |||
503 | /* | 521 | /* |
504 | * Search DM9000 board, allocate space and register it | 522 | * Search DM9000 board, allocate space and register it |
505 | */ | 523 | */ |
506 | static int | 524 | static int __devinit |
507 | dm9000_probe(struct platform_device *pdev) | 525 | dm9000_probe(struct platform_device *pdev) |
508 | { | 526 | { |
509 | struct dm9000_plat_data *pdata = pdev->dev.platform_data; | 527 | struct dm9000_plat_data *pdata = pdev->dev.platform_data; |
@@ -525,17 +543,21 @@ dm9000_probe(struct platform_device *pdev) | |||
525 | 543 | ||
526 | SET_NETDEV_DEV(ndev, &pdev->dev); | 544 | SET_NETDEV_DEV(ndev, &pdev->dev); |
527 | 545 | ||
528 | dev_dbg(&pdev->dev, "dm9000_probe()"); | 546 | dev_dbg(&pdev->dev, "dm9000_probe()\n"); |
529 | 547 | ||
530 | /* setup board info structure */ | 548 | /* setup board info structure */ |
531 | db = (struct board_info *) ndev->priv; | 549 | db = (struct board_info *) ndev->priv; |
532 | memset(db, 0, sizeof (*db)); | 550 | memset(db, 0, sizeof (*db)); |
533 | 551 | ||
534 | db->dev = &pdev->dev; | 552 | db->dev = &pdev->dev; |
553 | db->ndev = ndev; | ||
535 | 554 | ||
536 | spin_lock_init(&db->lock); | 555 | spin_lock_init(&db->lock); |
537 | mutex_init(&db->addr_lock); | 556 | mutex_init(&db->addr_lock); |
538 | 557 | ||
558 | INIT_DELAYED_WORK(&db->phy_poll, dm9000_poll_work); | ||
559 | |||
560 | |||
539 | if (pdev->num_resources < 2) { | 561 | if (pdev->num_resources < 2) { |
540 | ret = -ENODEV; | 562 | ret = -ENODEV; |
541 | goto out; | 563 | goto out; |
@@ -761,6 +783,8 @@ dm9000_open(struct net_device *dev) | |||
761 | 783 | ||
762 | mii_check_media(&db->mii, netif_msg_link(db), 1); | 784 | mii_check_media(&db->mii, netif_msg_link(db), 1); |
763 | netif_start_queue(dev); | 785 | netif_start_queue(dev); |
786 | |||
787 | dm9000_schedule_poll(db); | ||
764 | 788 | ||
765 | return 0; | 789 | return 0; |
766 | } | 790 | } |
@@ -879,6 +903,8 @@ dm9000_stop(struct net_device *ndev) | |||
879 | if (netif_msg_ifdown(db)) | 903 | if (netif_msg_ifdown(db)) |
880 | dev_dbg(db->dev, "shutting down %s\n", ndev->name); | 904 | dev_dbg(db->dev, "shutting down %s\n", ndev->name); |
881 | 905 | ||
906 | cancel_delayed_work_sync(&db->phy_poll); | ||
907 | |||
882 | netif_stop_queue(ndev); | 908 | netif_stop_queue(ndev); |
883 | netif_carrier_off(ndev); | 909 | netif_carrier_off(ndev); |
884 | 910 | ||
@@ -1288,6 +1314,8 @@ dm9000_phy_read(struct net_device *dev, int phy_reg_unused, int reg) | |||
1288 | spin_unlock_irqrestore(&db->lock,flags); | 1314 | spin_unlock_irqrestore(&db->lock,flags); |
1289 | 1315 | ||
1290 | mutex_unlock(&db->addr_lock); | 1316 | mutex_unlock(&db->addr_lock); |
1317 | |||
1318 | dm9000_dbg(db, 5, "phy_read[%02x] -> %04x\n", reg, ret); | ||
1291 | return ret; | 1319 | return ret; |
1292 | } | 1320 | } |
1293 | 1321 | ||
@@ -1301,6 +1329,7 @@ dm9000_phy_write(struct net_device *dev, int phyaddr_unused, int reg, int value) | |||
1301 | unsigned long flags; | 1329 | unsigned long flags; |
1302 | unsigned long reg_save; | 1330 | unsigned long reg_save; |
1303 | 1331 | ||
1332 | dm9000_dbg(db, 5, "phy_write[%02x] = %04x\n", reg, value); | ||
1304 | mutex_lock(&db->addr_lock); | 1333 | mutex_lock(&db->addr_lock); |
1305 | 1334 | ||
1306 | spin_lock_irqsave(&db->lock,flags); | 1335 | spin_lock_irqsave(&db->lock,flags); |
@@ -1372,7 +1401,7 @@ dm9000_drv_resume(struct platform_device *dev) | |||
1372 | return 0; | 1401 | return 0; |
1373 | } | 1402 | } |
1374 | 1403 | ||
1375 | static int | 1404 | static int __devexit |
1376 | dm9000_drv_remove(struct platform_device *pdev) | 1405 | dm9000_drv_remove(struct platform_device *pdev) |
1377 | { | 1406 | { |
1378 | struct net_device *ndev = platform_get_drvdata(pdev); | 1407 | struct net_device *ndev = platform_get_drvdata(pdev); |
@@ -1393,7 +1422,7 @@ static struct platform_driver dm9000_driver = { | |||
1393 | .owner = THIS_MODULE, | 1422 | .owner = THIS_MODULE, |
1394 | }, | 1423 | }, |
1395 | .probe = dm9000_probe, | 1424 | .probe = dm9000_probe, |
1396 | .remove = dm9000_drv_remove, | 1425 | .remove = __devexit_p(dm9000_drv_remove), |
1397 | .suspend = dm9000_drv_suspend, | 1426 | .suspend = dm9000_drv_suspend, |
1398 | .resume = dm9000_drv_resume, | 1427 | .resume = dm9000_drv_resume, |
1399 | }; | 1428 | }; |
diff --git a/drivers/net/e100.c b/drivers/net/e100.c index f3cba5e24ec5..1037b1332312 100644 --- a/drivers/net/e100.c +++ b/drivers/net/e100.c | |||
@@ -1803,6 +1803,8 @@ static int e100_rx_alloc_skb(struct nic *nic, struct rx *rx) | |||
1803 | if (rx->prev->skb) { | 1803 | if (rx->prev->skb) { |
1804 | struct rfd *prev_rfd = (struct rfd *)rx->prev->skb->data; | 1804 | struct rfd *prev_rfd = (struct rfd *)rx->prev->skb->data; |
1805 | put_unaligned_le32(rx->dma_addr, &prev_rfd->link); | 1805 | put_unaligned_le32(rx->dma_addr, &prev_rfd->link); |
1806 | pci_dma_sync_single_for_device(nic->pdev, rx->prev->dma_addr, | ||
1807 | sizeof(struct rfd), PCI_DMA_TODEVICE); | ||
1806 | } | 1808 | } |
1807 | 1809 | ||
1808 | return 0; | 1810 | return 0; |
diff --git a/drivers/net/e1000/e1000_ethtool.c b/drivers/net/e1000/e1000_ethtool.c index 701531e72e7b..a3f6a9c72ec8 100644 --- a/drivers/net/e1000/e1000_ethtool.c +++ b/drivers/net/e1000/e1000_ethtool.c | |||
@@ -347,7 +347,7 @@ e1000_set_tso(struct net_device *netdev, u32 data) | |||
347 | else | 347 | else |
348 | netdev->features &= ~NETIF_F_TSO; | 348 | netdev->features &= ~NETIF_F_TSO; |
349 | 349 | ||
350 | if (data) | 350 | if (data && (adapter->hw.mac_type > e1000_82547_rev_2)) |
351 | netdev->features |= NETIF_F_TSO6; | 351 | netdev->features |= NETIF_F_TSO6; |
352 | else | 352 | else |
353 | netdev->features &= ~NETIF_F_TSO6; | 353 | netdev->features &= ~NETIF_F_TSO6; |
diff --git a/drivers/net/e1000e/defines.h b/drivers/net/e1000e/defines.h index 2a53875cddbf..f823b8ba5785 100644 --- a/drivers/net/e1000e/defines.h +++ b/drivers/net/e1000e/defines.h | |||
@@ -648,6 +648,8 @@ | |||
648 | #define IFE_E_PHY_ID 0x02A80330 | 648 | #define IFE_E_PHY_ID 0x02A80330 |
649 | #define IFE_PLUS_E_PHY_ID 0x02A80320 | 649 | #define IFE_PLUS_E_PHY_ID 0x02A80320 |
650 | #define IFE_C_E_PHY_ID 0x02A80310 | 650 | #define IFE_C_E_PHY_ID 0x02A80310 |
651 | #define BME1000_E_PHY_ID 0x01410CB0 | ||
652 | #define BME1000_E_PHY_ID_R2 0x01410CB1 | ||
651 | 653 | ||
652 | /* M88E1000 Specific Registers */ | 654 | /* M88E1000 Specific Registers */ |
653 | #define M88E1000_PHY_SPEC_CTRL 0x10 /* PHY Specific Control Register */ | 655 | #define M88E1000_PHY_SPEC_CTRL 0x10 /* PHY Specific Control Register */ |
@@ -701,6 +703,14 @@ | |||
701 | #define M88EC018_EPSCR_DOWNSHIFT_COUNTER_MASK 0x0E00 | 703 | #define M88EC018_EPSCR_DOWNSHIFT_COUNTER_MASK 0x0E00 |
702 | #define M88EC018_EPSCR_DOWNSHIFT_COUNTER_5X 0x0800 | 704 | #define M88EC018_EPSCR_DOWNSHIFT_COUNTER_5X 0x0800 |
703 | 705 | ||
706 | /* BME1000 PHY Specific Control Register */ | ||
707 | #define BME1000_PSCR_ENABLE_DOWNSHIFT 0x0800 /* 1 = enable downshift */ | ||
708 | |||
709 | |||
710 | #define PHY_PAGE_SHIFT 5 | ||
711 | #define PHY_REG(page, reg) (((page) << PHY_PAGE_SHIFT) | \ | ||
712 | ((reg) & MAX_PHY_REG_ADDRESS)) | ||
713 | |||
704 | /* | 714 | /* |
705 | * Bits... | 715 | * Bits... |
706 | * 15-5: page | 716 | * 15-5: page |
diff --git a/drivers/net/e1000e/e1000.h b/drivers/net/e1000e/e1000.h index 38bfd0d261fe..d3bc6f8101fa 100644 --- a/drivers/net/e1000e/e1000.h +++ b/drivers/net/e1000e/e1000.h | |||
@@ -127,7 +127,7 @@ struct e1000_buffer { | |||
127 | /* arrays of page information for packet split */ | 127 | /* arrays of page information for packet split */ |
128 | struct e1000_ps_page *ps_pages; | 128 | struct e1000_ps_page *ps_pages; |
129 | }; | 129 | }; |
130 | 130 | struct page *page; | |
131 | }; | 131 | }; |
132 | 132 | ||
133 | struct e1000_ring { | 133 | struct e1000_ring { |
@@ -304,6 +304,7 @@ struct e1000_info { | |||
304 | #define FLAG_HAS_CTRLEXT_ON_LOAD (1 << 5) | 304 | #define FLAG_HAS_CTRLEXT_ON_LOAD (1 << 5) |
305 | #define FLAG_HAS_SWSM_ON_LOAD (1 << 6) | 305 | #define FLAG_HAS_SWSM_ON_LOAD (1 << 6) |
306 | #define FLAG_HAS_JUMBO_FRAMES (1 << 7) | 306 | #define FLAG_HAS_JUMBO_FRAMES (1 << 7) |
307 | #define FLAG_IS_ICH (1 << 9) | ||
307 | #define FLAG_HAS_SMART_POWER_DOWN (1 << 11) | 308 | #define FLAG_HAS_SMART_POWER_DOWN (1 << 11) |
308 | #define FLAG_IS_QUAD_PORT_A (1 << 12) | 309 | #define FLAG_IS_QUAD_PORT_A (1 << 12) |
309 | #define FLAG_IS_QUAD_PORT (1 << 13) | 310 | #define FLAG_IS_QUAD_PORT (1 << 13) |
@@ -386,6 +387,7 @@ extern void e1000e_set_kmrn_lock_loss_workaround_ich8lan(struct e1000_hw *hw, | |||
386 | bool state); | 387 | bool state); |
387 | extern void e1000e_igp3_phy_powerdown_workaround_ich8lan(struct e1000_hw *hw); | 388 | extern void e1000e_igp3_phy_powerdown_workaround_ich8lan(struct e1000_hw *hw); |
388 | extern void e1000e_gig_downshift_workaround_ich8lan(struct e1000_hw *hw); | 389 | extern void e1000e_gig_downshift_workaround_ich8lan(struct e1000_hw *hw); |
390 | extern void e1000e_disable_gig_wol_ich8lan(struct e1000_hw *hw); | ||
389 | 391 | ||
390 | extern s32 e1000e_check_for_copper_link(struct e1000_hw *hw); | 392 | extern s32 e1000e_check_for_copper_link(struct e1000_hw *hw); |
391 | extern s32 e1000e_check_for_fiber_link(struct e1000_hw *hw); | 393 | extern s32 e1000e_check_for_fiber_link(struct e1000_hw *hw); |
@@ -443,6 +445,9 @@ extern s32 e1000e_get_phy_info_m88(struct e1000_hw *hw); | |||
443 | extern s32 e1000e_read_phy_reg_m88(struct e1000_hw *hw, u32 offset, u16 *data); | 445 | extern s32 e1000e_read_phy_reg_m88(struct e1000_hw *hw, u32 offset, u16 *data); |
444 | extern s32 e1000e_write_phy_reg_m88(struct e1000_hw *hw, u32 offset, u16 data); | 446 | extern s32 e1000e_write_phy_reg_m88(struct e1000_hw *hw, u32 offset, u16 data); |
445 | extern enum e1000_phy_type e1000e_get_phy_type_from_id(u32 phy_id); | 447 | extern enum e1000_phy_type e1000e_get_phy_type_from_id(u32 phy_id); |
448 | extern s32 e1000e_determine_phy_address(struct e1000_hw *hw); | ||
449 | extern s32 e1000e_write_phy_reg_bm(struct e1000_hw *hw, u32 offset, u16 data); | ||
450 | extern s32 e1000e_read_phy_reg_bm(struct e1000_hw *hw, u32 offset, u16 *data); | ||
446 | extern void e1000e_phy_force_speed_duplex_setup(struct e1000_hw *hw, u16 *phy_ctrl); | 451 | extern void e1000e_phy_force_speed_duplex_setup(struct e1000_hw *hw, u16 *phy_ctrl); |
447 | extern s32 e1000e_write_kmrn_reg(struct e1000_hw *hw, u32 offset, u16 data); | 452 | extern s32 e1000e_write_kmrn_reg(struct e1000_hw *hw, u32 offset, u16 data); |
448 | extern s32 e1000e_read_kmrn_reg(struct e1000_hw *hw, u32 offset, u16 *data); | 453 | extern s32 e1000e_read_kmrn_reg(struct e1000_hw *hw, u32 offset, u16 *data); |
diff --git a/drivers/net/e1000e/ethtool.c b/drivers/net/e1000e/ethtool.c index ce045acce63e..a14561f40db0 100644 --- a/drivers/net/e1000e/ethtool.c +++ b/drivers/net/e1000e/ethtool.c | |||
@@ -494,8 +494,12 @@ static int e1000_get_eeprom(struct net_device *netdev, | |||
494 | for (i = 0; i < last_word - first_word + 1; i++) { | 494 | for (i = 0; i < last_word - first_word + 1; i++) { |
495 | ret_val = e1000_read_nvm(hw, first_word + i, 1, | 495 | ret_val = e1000_read_nvm(hw, first_word + i, 1, |
496 | &eeprom_buff[i]); | 496 | &eeprom_buff[i]); |
497 | if (ret_val) | 497 | if (ret_val) { |
498 | /* a read error occurred, throw away the | ||
499 | * result */ | ||
500 | memset(eeprom_buff, 0xff, sizeof(eeprom_buff)); | ||
498 | break; | 501 | break; |
502 | } | ||
499 | } | 503 | } |
500 | } | 504 | } |
501 | 505 | ||
@@ -803,8 +807,7 @@ static int e1000_reg_test(struct e1000_adapter *adapter, u64 *data) | |||
803 | /* restore previous status */ | 807 | /* restore previous status */ |
804 | ew32(STATUS, before); | 808 | ew32(STATUS, before); |
805 | 809 | ||
806 | if ((mac->type != e1000_ich8lan) && | 810 | if (!(adapter->flags & FLAG_IS_ICH)) { |
807 | (mac->type != e1000_ich9lan)) { | ||
808 | REG_PATTERN_TEST(E1000_FCAL, 0xFFFFFFFF, 0xFFFFFFFF); | 811 | REG_PATTERN_TEST(E1000_FCAL, 0xFFFFFFFF, 0xFFFFFFFF); |
809 | REG_PATTERN_TEST(E1000_FCAH, 0x0000FFFF, 0xFFFFFFFF); | 812 | REG_PATTERN_TEST(E1000_FCAH, 0x0000FFFF, 0xFFFFFFFF); |
810 | REG_PATTERN_TEST(E1000_FCT, 0x0000FFFF, 0xFFFFFFFF); | 813 | REG_PATTERN_TEST(E1000_FCT, 0x0000FFFF, 0xFFFFFFFF); |
@@ -824,15 +827,13 @@ static int e1000_reg_test(struct e1000_adapter *adapter, u64 *data) | |||
824 | 827 | ||
825 | REG_SET_AND_CHECK(E1000_RCTL, 0xFFFFFFFF, 0x00000000); | 828 | REG_SET_AND_CHECK(E1000_RCTL, 0xFFFFFFFF, 0x00000000); |
826 | 829 | ||
827 | before = (((mac->type == e1000_ich8lan) || | 830 | before = ((adapter->flags & FLAG_IS_ICH) ? 0x06C3B33E : 0x06DFB3FE); |
828 | (mac->type == e1000_ich9lan)) ? 0x06C3B33E : 0x06DFB3FE); | ||
829 | REG_SET_AND_CHECK(E1000_RCTL, before, 0x003FFFFB); | 831 | REG_SET_AND_CHECK(E1000_RCTL, before, 0x003FFFFB); |
830 | REG_SET_AND_CHECK(E1000_TCTL, 0xFFFFFFFF, 0x00000000); | 832 | REG_SET_AND_CHECK(E1000_TCTL, 0xFFFFFFFF, 0x00000000); |
831 | 833 | ||
832 | REG_SET_AND_CHECK(E1000_RCTL, before, 0xFFFFFFFF); | 834 | REG_SET_AND_CHECK(E1000_RCTL, before, 0xFFFFFFFF); |
833 | REG_PATTERN_TEST(E1000_RDBAL, 0xFFFFFFF0, 0xFFFFFFFF); | 835 | REG_PATTERN_TEST(E1000_RDBAL, 0xFFFFFFF0, 0xFFFFFFFF); |
834 | if ((mac->type != e1000_ich8lan) && | 836 | if (!(adapter->flags & FLAG_IS_ICH)) |
835 | (mac->type != e1000_ich9lan)) | ||
836 | REG_PATTERN_TEST(E1000_TXCW, 0xC000FFFF, 0x0000FFFF); | 837 | REG_PATTERN_TEST(E1000_TXCW, 0xC000FFFF, 0x0000FFFF); |
837 | REG_PATTERN_TEST(E1000_TDBAL, 0xFFFFFFF0, 0xFFFFFFFF); | 838 | REG_PATTERN_TEST(E1000_TDBAL, 0xFFFFFFF0, 0xFFFFFFFF); |
838 | REG_PATTERN_TEST(E1000_TIDV, 0x0000FFFF, 0x0000FFFF); | 839 | REG_PATTERN_TEST(E1000_TIDV, 0x0000FFFF, 0x0000FFFF); |
@@ -911,9 +912,7 @@ static int e1000_intr_test(struct e1000_adapter *adapter, u64 *data) | |||
911 | 912 | ||
912 | /* Test each interrupt */ | 913 | /* Test each interrupt */ |
913 | for (i = 0; i < 10; i++) { | 914 | for (i = 0; i < 10; i++) { |
914 | 915 | if ((adapter->flags & FLAG_IS_ICH) && (i == 8)) | |
915 | if (((adapter->hw.mac.type == e1000_ich8lan) || | ||
916 | (adapter->hw.mac.type == e1000_ich9lan)) && i == 8) | ||
917 | continue; | 916 | continue; |
918 | 917 | ||
919 | /* Interrupt to test */ | 918 | /* Interrupt to test */ |
@@ -1184,6 +1183,7 @@ static int e1000_integrated_phy_loopback(struct e1000_adapter *adapter) | |||
1184 | struct e1000_hw *hw = &adapter->hw; | 1183 | struct e1000_hw *hw = &adapter->hw; |
1185 | u32 ctrl_reg = 0; | 1184 | u32 ctrl_reg = 0; |
1186 | u32 stat_reg = 0; | 1185 | u32 stat_reg = 0; |
1186 | u16 phy_reg = 0; | ||
1187 | 1187 | ||
1188 | hw->mac.autoneg = 0; | 1188 | hw->mac.autoneg = 0; |
1189 | 1189 | ||
@@ -1211,6 +1211,28 @@ static int e1000_integrated_phy_loopback(struct e1000_adapter *adapter) | |||
1211 | E1000_CTRL_SPD_100 |/* Force Speed to 100 */ | 1211 | E1000_CTRL_SPD_100 |/* Force Speed to 100 */ |
1212 | E1000_CTRL_FD); /* Force Duplex to FULL */ | 1212 | E1000_CTRL_FD); /* Force Duplex to FULL */ |
1213 | break; | 1213 | break; |
1214 | case e1000_phy_bm: | ||
1215 | /* Set Default MAC Interface speed to 1GB */ | ||
1216 | e1e_rphy(hw, PHY_REG(2, 21), &phy_reg); | ||
1217 | phy_reg &= ~0x0007; | ||
1218 | phy_reg |= 0x006; | ||
1219 | e1e_wphy(hw, PHY_REG(2, 21), phy_reg); | ||
1220 | /* Assert SW reset for above settings to take effect */ | ||
1221 | e1000e_commit_phy(hw); | ||
1222 | mdelay(1); | ||
1223 | /* Force Full Duplex */ | ||
1224 | e1e_rphy(hw, PHY_REG(769, 16), &phy_reg); | ||
1225 | e1e_wphy(hw, PHY_REG(769, 16), phy_reg | 0x000C); | ||
1226 | /* Set Link Up (in force link) */ | ||
1227 | e1e_rphy(hw, PHY_REG(776, 16), &phy_reg); | ||
1228 | e1e_wphy(hw, PHY_REG(776, 16), phy_reg | 0x0040); | ||
1229 | /* Force Link */ | ||
1230 | e1e_rphy(hw, PHY_REG(769, 16), &phy_reg); | ||
1231 | e1e_wphy(hw, PHY_REG(769, 16), phy_reg | 0x0040); | ||
1232 | /* Set Early Link Enable */ | ||
1233 | e1e_rphy(hw, PHY_REG(769, 20), &phy_reg); | ||
1234 | e1e_wphy(hw, PHY_REG(769, 20), phy_reg | 0x0400); | ||
1235 | /* fall through */ | ||
1214 | default: | 1236 | default: |
1215 | /* force 1000, set loopback */ | 1237 | /* force 1000, set loopback */ |
1216 | e1e_wphy(hw, PHY_CONTROL, 0x4140); | 1238 | e1e_wphy(hw, PHY_CONTROL, 0x4140); |
@@ -1224,8 +1246,7 @@ static int e1000_integrated_phy_loopback(struct e1000_adapter *adapter) | |||
1224 | E1000_CTRL_SPD_1000 |/* Force Speed to 1000 */ | 1246 | E1000_CTRL_SPD_1000 |/* Force Speed to 1000 */ |
1225 | E1000_CTRL_FD); /* Force Duplex to FULL */ | 1247 | E1000_CTRL_FD); /* Force Duplex to FULL */ |
1226 | 1248 | ||
1227 | if ((adapter->hw.mac.type == e1000_ich8lan) || | 1249 | if (adapter->flags & FLAG_IS_ICH) |
1228 | (adapter->hw.mac.type == e1000_ich9lan)) | ||
1229 | ctrl_reg |= E1000_CTRL_SLU; /* Set Link Up */ | 1250 | ctrl_reg |= E1000_CTRL_SLU; /* Set Link Up */ |
1230 | } | 1251 | } |
1231 | 1252 | ||
diff --git a/drivers/net/e1000e/hw.h b/drivers/net/e1000e/hw.h index a930e6d9cf02..74f263acb172 100644 --- a/drivers/net/e1000e/hw.h +++ b/drivers/net/e1000e/hw.h | |||
@@ -216,6 +216,21 @@ enum e1e_registers { | |||
216 | #define IGP01E1000_PHY_LINK_HEALTH 0x13 /* PHY Link Health */ | 216 | #define IGP01E1000_PHY_LINK_HEALTH 0x13 /* PHY Link Health */ |
217 | #define IGP02E1000_PHY_POWER_MGMT 0x19 /* Power Management */ | 217 | #define IGP02E1000_PHY_POWER_MGMT 0x19 /* Power Management */ |
218 | #define IGP01E1000_PHY_PAGE_SELECT 0x1F /* Page Select */ | 218 | #define IGP01E1000_PHY_PAGE_SELECT 0x1F /* Page Select */ |
219 | #define BM_PHY_PAGE_SELECT 22 /* Page Select for BM */ | ||
220 | #define IGP_PAGE_SHIFT 5 | ||
221 | #define PHY_REG_MASK 0x1F | ||
222 | |||
223 | #define BM_WUC_PAGE 800 | ||
224 | #define BM_WUC_ADDRESS_OPCODE 0x11 | ||
225 | #define BM_WUC_DATA_OPCODE 0x12 | ||
226 | #define BM_WUC_ENABLE_PAGE 769 | ||
227 | #define BM_WUC_ENABLE_REG 17 | ||
228 | #define BM_WUC_ENABLE_BIT (1 << 2) | ||
229 | #define BM_WUC_HOST_WU_BIT (1 << 4) | ||
230 | |||
231 | #define BM_WUC PHY_REG(BM_WUC_PAGE, 1) | ||
232 | #define BM_WUFC PHY_REG(BM_WUC_PAGE, 2) | ||
233 | #define BM_WUS PHY_REG(BM_WUC_PAGE, 3) | ||
219 | 234 | ||
220 | #define IGP01E1000_PHY_PCS_INIT_REG 0x00B4 | 235 | #define IGP01E1000_PHY_PCS_INIT_REG 0x00B4 |
221 | #define IGP01E1000_PHY_POLARITY_MASK 0x0078 | 236 | #define IGP01E1000_PHY_POLARITY_MASK 0x0078 |
@@ -331,10 +346,16 @@ enum e1e_registers { | |||
331 | #define E1000_DEV_ID_ICH8_IFE_G 0x10C5 | 346 | #define E1000_DEV_ID_ICH8_IFE_G 0x10C5 |
332 | #define E1000_DEV_ID_ICH8_IGP_M 0x104D | 347 | #define E1000_DEV_ID_ICH8_IGP_M 0x104D |
333 | #define E1000_DEV_ID_ICH9_IGP_AMT 0x10BD | 348 | #define E1000_DEV_ID_ICH9_IGP_AMT 0x10BD |
349 | #define E1000_DEV_ID_ICH9_IGP_M_AMT 0x10F5 | ||
350 | #define E1000_DEV_ID_ICH9_IGP_M 0x10BF | ||
351 | #define E1000_DEV_ID_ICH9_IGP_M_V 0x10CB | ||
334 | #define E1000_DEV_ID_ICH9_IGP_C 0x294C | 352 | #define E1000_DEV_ID_ICH9_IGP_C 0x294C |
335 | #define E1000_DEV_ID_ICH9_IFE 0x10C0 | 353 | #define E1000_DEV_ID_ICH9_IFE 0x10C0 |
336 | #define E1000_DEV_ID_ICH9_IFE_GT 0x10C3 | 354 | #define E1000_DEV_ID_ICH9_IFE_GT 0x10C3 |
337 | #define E1000_DEV_ID_ICH9_IFE_G 0x10C2 | 355 | #define E1000_DEV_ID_ICH9_IFE_G 0x10C2 |
356 | #define E1000_DEV_ID_ICH10_R_BM_LM 0x10CC | ||
357 | #define E1000_DEV_ID_ICH10_R_BM_LF 0x10CD | ||
358 | #define E1000_DEV_ID_ICH10_R_BM_V 0x10CE | ||
338 | 359 | ||
339 | #define E1000_FUNC_1 1 | 360 | #define E1000_FUNC_1 1 |
340 | 361 | ||
@@ -378,6 +399,7 @@ enum e1000_phy_type { | |||
378 | e1000_phy_gg82563, | 399 | e1000_phy_gg82563, |
379 | e1000_phy_igp_3, | 400 | e1000_phy_igp_3, |
380 | e1000_phy_ife, | 401 | e1000_phy_ife, |
402 | e1000_phy_bm, | ||
381 | }; | 403 | }; |
382 | 404 | ||
383 | enum e1000_bus_width { | 405 | enum e1000_bus_width { |
diff --git a/drivers/net/e1000e/ich8lan.c b/drivers/net/e1000e/ich8lan.c index 768485dbb2c6..9e38452a738c 100644 --- a/drivers/net/e1000e/ich8lan.c +++ b/drivers/net/e1000e/ich8lan.c | |||
@@ -38,6 +38,12 @@ | |||
38 | * 82566DM Gigabit Network Connection | 38 | * 82566DM Gigabit Network Connection |
39 | * 82566MC Gigabit Network Connection | 39 | * 82566MC Gigabit Network Connection |
40 | * 82566MM Gigabit Network Connection | 40 | * 82566MM Gigabit Network Connection |
41 | * 82567LM Gigabit Network Connection | ||
42 | * 82567LF Gigabit Network Connection | ||
43 | * 82567LM-2 Gigabit Network Connection | ||
44 | * 82567LF-2 Gigabit Network Connection | ||
45 | * 82567V-2 Gigabit Network Connection | ||
46 | * 82562GT-3 10/100 Network Connection | ||
41 | */ | 47 | */ |
42 | 48 | ||
43 | #include <linux/netdevice.h> | 49 | #include <linux/netdevice.h> |
@@ -198,6 +204,19 @@ static s32 e1000_init_phy_params_ich8lan(struct e1000_hw *hw) | |||
198 | phy->addr = 1; | 204 | phy->addr = 1; |
199 | phy->reset_delay_us = 100; | 205 | phy->reset_delay_us = 100; |
200 | 206 | ||
207 | /* | ||
208 | * We may need to do this twice - once for IGP and if that fails, | ||
209 | * we'll set BM func pointers and try again | ||
210 | */ | ||
211 | ret_val = e1000e_determine_phy_address(hw); | ||
212 | if (ret_val) { | ||
213 | hw->phy.ops.write_phy_reg = e1000e_write_phy_reg_bm; | ||
214 | hw->phy.ops.read_phy_reg = e1000e_read_phy_reg_bm; | ||
215 | ret_val = e1000e_determine_phy_address(hw); | ||
216 | if (ret_val) | ||
217 | return ret_val; | ||
218 | } | ||
219 | |||
201 | phy->id = 0; | 220 | phy->id = 0; |
202 | while ((e1000_phy_unknown == e1000e_get_phy_type_from_id(phy->id)) && | 221 | while ((e1000_phy_unknown == e1000e_get_phy_type_from_id(phy->id)) && |
203 | (i++ < 100)) { | 222 | (i++ < 100)) { |
@@ -219,6 +238,13 @@ static s32 e1000_init_phy_params_ich8lan(struct e1000_hw *hw) | |||
219 | phy->type = e1000_phy_ife; | 238 | phy->type = e1000_phy_ife; |
220 | phy->autoneg_mask = E1000_ALL_NOT_GIG; | 239 | phy->autoneg_mask = E1000_ALL_NOT_GIG; |
221 | break; | 240 | break; |
241 | case BME1000_E_PHY_ID: | ||
242 | phy->type = e1000_phy_bm; | ||
243 | phy->autoneg_mask = AUTONEG_ADVERTISE_SPEED_DEFAULT; | ||
244 | hw->phy.ops.read_phy_reg = e1000e_read_phy_reg_bm; | ||
245 | hw->phy.ops.write_phy_reg = e1000e_write_phy_reg_bm; | ||
246 | hw->phy.ops.commit_phy = e1000e_phy_sw_reset; | ||
247 | break; | ||
222 | default: | 248 | default: |
223 | return -E1000_ERR_PHY; | 249 | return -E1000_ERR_PHY; |
224 | break; | 250 | break; |
@@ -664,6 +690,7 @@ static s32 e1000_get_phy_info_ich8lan(struct e1000_hw *hw) | |||
664 | return e1000_get_phy_info_ife_ich8lan(hw); | 690 | return e1000_get_phy_info_ife_ich8lan(hw); |
665 | break; | 691 | break; |
666 | case e1000_phy_igp_3: | 692 | case e1000_phy_igp_3: |
693 | case e1000_phy_bm: | ||
667 | return e1000e_get_phy_info_igp(hw); | 694 | return e1000e_get_phy_info_igp(hw); |
668 | break; | 695 | break; |
669 | default: | 696 | default: |
@@ -728,7 +755,7 @@ static s32 e1000_set_d0_lplu_state_ich8lan(struct e1000_hw *hw, bool active) | |||
728 | s32 ret_val = 0; | 755 | s32 ret_val = 0; |
729 | u16 data; | 756 | u16 data; |
730 | 757 | ||
731 | if (phy->type != e1000_phy_igp_3) | 758 | if (phy->type == e1000_phy_ife) |
732 | return ret_val; | 759 | return ret_val; |
733 | 760 | ||
734 | phy_ctrl = er32(PHY_CTRL); | 761 | phy_ctrl = er32(PHY_CTRL); |
@@ -1918,8 +1945,35 @@ static s32 e1000_setup_copper_link_ich8lan(struct e1000_hw *hw) | |||
1918 | ret_val = e1000e_copper_link_setup_igp(hw); | 1945 | ret_val = e1000e_copper_link_setup_igp(hw); |
1919 | if (ret_val) | 1946 | if (ret_val) |
1920 | return ret_val; | 1947 | return ret_val; |
1948 | } else if (hw->phy.type == e1000_phy_bm) { | ||
1949 | ret_val = e1000e_copper_link_setup_m88(hw); | ||
1950 | if (ret_val) | ||
1951 | return ret_val; | ||
1921 | } | 1952 | } |
1922 | 1953 | ||
1954 | if (hw->phy.type == e1000_phy_ife) { | ||
1955 | ret_val = e1e_rphy(hw, IFE_PHY_MDIX_CONTROL, ®_data); | ||
1956 | if (ret_val) | ||
1957 | return ret_val; | ||
1958 | |||
1959 | reg_data &= ~IFE_PMC_AUTO_MDIX; | ||
1960 | |||
1961 | switch (hw->phy.mdix) { | ||
1962 | case 1: | ||
1963 | reg_data &= ~IFE_PMC_FORCE_MDIX; | ||
1964 | break; | ||
1965 | case 2: | ||
1966 | reg_data |= IFE_PMC_FORCE_MDIX; | ||
1967 | break; | ||
1968 | case 0: | ||
1969 | default: | ||
1970 | reg_data |= IFE_PMC_AUTO_MDIX; | ||
1971 | break; | ||
1972 | } | ||
1973 | ret_val = e1e_wphy(hw, IFE_PHY_MDIX_CONTROL, reg_data); | ||
1974 | if (ret_val) | ||
1975 | return ret_val; | ||
1976 | } | ||
1923 | return e1000e_setup_copper_link(hw); | 1977 | return e1000e_setup_copper_link(hw); |
1924 | } | 1978 | } |
1925 | 1979 | ||
@@ -2127,6 +2181,31 @@ void e1000e_gig_downshift_workaround_ich8lan(struct e1000_hw *hw) | |||
2127 | } | 2181 | } |
2128 | 2182 | ||
2129 | /** | 2183 | /** |
2184 | * e1000e_disable_gig_wol_ich8lan - disable gig during WoL | ||
2185 | * @hw: pointer to the HW structure | ||
2186 | * | ||
2187 | * During S0 to Sx transition, it is possible the link remains at gig | ||
2188 | * instead of negotiating to a lower speed. Before going to Sx, set | ||
2189 | * 'LPLU Enabled' and 'Gig Disable' to force link speed negotiation | ||
2190 | * to a lower speed. | ||
2191 | * | ||
2192 | * Should only be called for ICH9 devices. | ||
2193 | **/ | ||
2194 | void e1000e_disable_gig_wol_ich8lan(struct e1000_hw *hw) | ||
2195 | { | ||
2196 | u32 phy_ctrl; | ||
2197 | |||
2198 | if (hw->mac.type == e1000_ich9lan) { | ||
2199 | phy_ctrl = er32(PHY_CTRL); | ||
2200 | phy_ctrl |= E1000_PHY_CTRL_D0A_LPLU | | ||
2201 | E1000_PHY_CTRL_GBE_DISABLE; | ||
2202 | ew32(PHY_CTRL, phy_ctrl); | ||
2203 | } | ||
2204 | |||
2205 | return; | ||
2206 | } | ||
2207 | |||
2208 | /** | ||
2130 | * e1000_cleanup_led_ich8lan - Restore the default LED operation | 2209 | * e1000_cleanup_led_ich8lan - Restore the default LED operation |
2131 | * @hw: pointer to the HW structure | 2210 | * @hw: pointer to the HW structure |
2132 | * | 2211 | * |
@@ -2247,6 +2326,7 @@ static struct e1000_nvm_operations ich8_nvm_ops = { | |||
2247 | struct e1000_info e1000_ich8_info = { | 2326 | struct e1000_info e1000_ich8_info = { |
2248 | .mac = e1000_ich8lan, | 2327 | .mac = e1000_ich8lan, |
2249 | .flags = FLAG_HAS_WOL | 2328 | .flags = FLAG_HAS_WOL |
2329 | | FLAG_IS_ICH | ||
2250 | | FLAG_RX_CSUM_ENABLED | 2330 | | FLAG_RX_CSUM_ENABLED |
2251 | | FLAG_HAS_CTRLEXT_ON_LOAD | 2331 | | FLAG_HAS_CTRLEXT_ON_LOAD |
2252 | | FLAG_HAS_AMT | 2332 | | FLAG_HAS_AMT |
@@ -2262,6 +2342,7 @@ struct e1000_info e1000_ich8_info = { | |||
2262 | struct e1000_info e1000_ich9_info = { | 2342 | struct e1000_info e1000_ich9_info = { |
2263 | .mac = e1000_ich9lan, | 2343 | .mac = e1000_ich9lan, |
2264 | .flags = FLAG_HAS_JUMBO_FRAMES | 2344 | .flags = FLAG_HAS_JUMBO_FRAMES |
2345 | | FLAG_IS_ICH | ||
2265 | | FLAG_HAS_WOL | 2346 | | FLAG_HAS_WOL |
2266 | | FLAG_RX_CSUM_ENABLED | 2347 | | FLAG_RX_CSUM_ENABLED |
2267 | | FLAG_HAS_CTRLEXT_ON_LOAD | 2348 | | FLAG_HAS_CTRLEXT_ON_LOAD |
diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c index 8991ab8911e2..648a87bbf467 100644 --- a/drivers/net/e1000e/netdev.c +++ b/drivers/net/e1000e/netdev.c | |||
@@ -43,10 +43,11 @@ | |||
43 | #include <linux/if_vlan.h> | 43 | #include <linux/if_vlan.h> |
44 | #include <linux/cpu.h> | 44 | #include <linux/cpu.h> |
45 | #include <linux/smp.h> | 45 | #include <linux/smp.h> |
46 | #include <linux/pm_qos_params.h> | ||
46 | 47 | ||
47 | #include "e1000.h" | 48 | #include "e1000.h" |
48 | 49 | ||
49 | #define DRV_VERSION "0.2.1" | 50 | #define DRV_VERSION "0.3.3.3-k2" |
50 | char e1000e_driver_name[] = "e1000e"; | 51 | char e1000e_driver_name[] = "e1000e"; |
51 | const char e1000e_driver_version[] = DRV_VERSION; | 52 | const char e1000e_driver_version[] = DRV_VERSION; |
52 | 53 | ||
@@ -341,6 +342,89 @@ no_buffers: | |||
341 | } | 342 | } |
342 | 343 | ||
343 | /** | 344 | /** |
345 | * e1000_alloc_jumbo_rx_buffers - Replace used jumbo receive buffers | ||
346 | * @adapter: address of board private structure | ||
347 | * @rx_ring: pointer to receive ring structure | ||
348 | * @cleaned_count: number of buffers to allocate this pass | ||
349 | **/ | ||
350 | |||
351 | static void e1000_alloc_jumbo_rx_buffers(struct e1000_adapter *adapter, | ||
352 | int cleaned_count) | ||
353 | { | ||
354 | struct net_device *netdev = adapter->netdev; | ||
355 | struct pci_dev *pdev = adapter->pdev; | ||
356 | struct e1000_rx_desc *rx_desc; | ||
357 | struct e1000_ring *rx_ring = adapter->rx_ring; | ||
358 | struct e1000_buffer *buffer_info; | ||
359 | struct sk_buff *skb; | ||
360 | unsigned int i; | ||
361 | unsigned int bufsz = 256 - | ||
362 | 16 /* for skb_reserve */ - | ||
363 | NET_IP_ALIGN; | ||
364 | |||
365 | i = rx_ring->next_to_use; | ||
366 | buffer_info = &rx_ring->buffer_info[i]; | ||
367 | |||
368 | while (cleaned_count--) { | ||
369 | skb = buffer_info->skb; | ||
370 | if (skb) { | ||
371 | skb_trim(skb, 0); | ||
372 | goto check_page; | ||
373 | } | ||
374 | |||
375 | skb = netdev_alloc_skb(netdev, bufsz); | ||
376 | if (unlikely(!skb)) { | ||
377 | /* Better luck next round */ | ||
378 | adapter->alloc_rx_buff_failed++; | ||
379 | break; | ||
380 | } | ||
381 | |||
382 | /* Make buffer alignment 2 beyond a 16 byte boundary | ||
383 | * this will result in a 16 byte aligned IP header after | ||
384 | * the 14 byte MAC header is removed | ||
385 | */ | ||
386 | skb_reserve(skb, NET_IP_ALIGN); | ||
387 | |||
388 | buffer_info->skb = skb; | ||
389 | check_page: | ||
390 | /* allocate a new page if necessary */ | ||
391 | if (!buffer_info->page) { | ||
392 | buffer_info->page = alloc_page(GFP_ATOMIC); | ||
393 | if (unlikely(!buffer_info->page)) { | ||
394 | adapter->alloc_rx_buff_failed++; | ||
395 | break; | ||
396 | } | ||
397 | } | ||
398 | |||
399 | if (!buffer_info->dma) | ||
400 | buffer_info->dma = pci_map_page(pdev, | ||
401 | buffer_info->page, 0, | ||
402 | PAGE_SIZE, | ||
403 | PCI_DMA_FROMDEVICE); | ||
404 | |||
405 | rx_desc = E1000_RX_DESC(*rx_ring, i); | ||
406 | rx_desc->buffer_addr = cpu_to_le64(buffer_info->dma); | ||
407 | |||
408 | if (unlikely(++i == rx_ring->count)) | ||
409 | i = 0; | ||
410 | buffer_info = &rx_ring->buffer_info[i]; | ||
411 | } | ||
412 | |||
413 | if (likely(rx_ring->next_to_use != i)) { | ||
414 | rx_ring->next_to_use = i; | ||
415 | if (unlikely(i-- == 0)) | ||
416 | i = (rx_ring->count - 1); | ||
417 | |||
418 | /* Force memory writes to complete before letting h/w | ||
419 | * know there are new descriptors to fetch. (Only | ||
420 | * applicable for weak-ordered memory model archs, | ||
421 | * such as IA-64). */ | ||
422 | wmb(); | ||
423 | writel(i, adapter->hw.hw_addr + rx_ring->tail); | ||
424 | } | ||
425 | } | ||
426 | |||
427 | /** | ||
344 | * e1000_clean_rx_irq - Send received data up the network stack; legacy | 428 | * e1000_clean_rx_irq - Send received data up the network stack; legacy |
345 | * @adapter: board private structure | 429 | * @adapter: board private structure |
346 | * | 430 | * |
@@ -783,6 +867,186 @@ next_desc: | |||
783 | } | 867 | } |
784 | 868 | ||
785 | /** | 869 | /** |
870 | * e1000_consume_page - helper function | ||
871 | **/ | ||
872 | static void e1000_consume_page(struct e1000_buffer *bi, struct sk_buff *skb, | ||
873 | u16 length) | ||
874 | { | ||
875 | bi->page = NULL; | ||
876 | skb->len += length; | ||
877 | skb->data_len += length; | ||
878 | skb->truesize += length; | ||
879 | } | ||
880 | |||
881 | /** | ||
882 | * e1000_clean_jumbo_rx_irq - Send received data up the network stack; legacy | ||
883 | * @adapter: board private structure | ||
884 | * | ||
885 | * the return value indicates whether actual cleaning was done, there | ||
886 | * is no guarantee that everything was cleaned | ||
887 | **/ | ||
888 | |||
889 | static bool e1000_clean_jumbo_rx_irq(struct e1000_adapter *adapter, | ||
890 | int *work_done, int work_to_do) | ||
891 | { | ||
892 | struct net_device *netdev = adapter->netdev; | ||
893 | struct pci_dev *pdev = adapter->pdev; | ||
894 | struct e1000_ring *rx_ring = adapter->rx_ring; | ||
895 | struct e1000_rx_desc *rx_desc, *next_rxd; | ||
896 | struct e1000_buffer *buffer_info, *next_buffer; | ||
897 | u32 length; | ||
898 | unsigned int i; | ||
899 | int cleaned_count = 0; | ||
900 | bool cleaned = false; | ||
901 | unsigned int total_rx_bytes=0, total_rx_packets=0; | ||
902 | |||
903 | i = rx_ring->next_to_clean; | ||
904 | rx_desc = E1000_RX_DESC(*rx_ring, i); | ||
905 | buffer_info = &rx_ring->buffer_info[i]; | ||
906 | |||
907 | while (rx_desc->status & E1000_RXD_STAT_DD) { | ||
908 | struct sk_buff *skb; | ||
909 | u8 status; | ||
910 | |||
911 | if (*work_done >= work_to_do) | ||
912 | break; | ||
913 | (*work_done)++; | ||
914 | |||
915 | status = rx_desc->status; | ||
916 | skb = buffer_info->skb; | ||
917 | buffer_info->skb = NULL; | ||
918 | |||
919 | ++i; | ||
920 | if (i == rx_ring->count) | ||
921 | i = 0; | ||
922 | next_rxd = E1000_RX_DESC(*rx_ring, i); | ||
923 | prefetch(next_rxd); | ||
924 | |||
925 | next_buffer = &rx_ring->buffer_info[i]; | ||
926 | |||
927 | cleaned = true; | ||
928 | cleaned_count++; | ||
929 | pci_unmap_page(pdev, buffer_info->dma, PAGE_SIZE, | ||
930 | PCI_DMA_FROMDEVICE); | ||
931 | buffer_info->dma = 0; | ||
932 | |||
933 | length = le16_to_cpu(rx_desc->length); | ||
934 | |||
935 | /* errors is only valid for DD + EOP descriptors */ | ||
936 | if (unlikely((status & E1000_RXD_STAT_EOP) && | ||
937 | (rx_desc->errors & E1000_RXD_ERR_FRAME_ERR_MASK))) { | ||
938 | /* recycle both page and skb */ | ||
939 | buffer_info->skb = skb; | ||
940 | /* an error means any chain goes out the window | ||
941 | * too */ | ||
942 | if (rx_ring->rx_skb_top) | ||
943 | dev_kfree_skb(rx_ring->rx_skb_top); | ||
944 | rx_ring->rx_skb_top = NULL; | ||
945 | goto next_desc; | ||
946 | } | ||
947 | |||
948 | #define rxtop rx_ring->rx_skb_top | ||
949 | if (!(status & E1000_RXD_STAT_EOP)) { | ||
950 | /* this descriptor is only the beginning (or middle) */ | ||
951 | if (!rxtop) { | ||
952 | /* this is the beginning of a chain */ | ||
953 | rxtop = skb; | ||
954 | skb_fill_page_desc(rxtop, 0, buffer_info->page, | ||
955 | 0, length); | ||
956 | } else { | ||
957 | /* this is the middle of a chain */ | ||
958 | skb_fill_page_desc(rxtop, | ||
959 | skb_shinfo(rxtop)->nr_frags, | ||
960 | buffer_info->page, 0, length); | ||
961 | /* re-use the skb, only consumed the page */ | ||
962 | buffer_info->skb = skb; | ||
963 | } | ||
964 | e1000_consume_page(buffer_info, rxtop, length); | ||
965 | goto next_desc; | ||
966 | } else { | ||
967 | if (rxtop) { | ||
968 | /* end of the chain */ | ||
969 | skb_fill_page_desc(rxtop, | ||
970 | skb_shinfo(rxtop)->nr_frags, | ||
971 | buffer_info->page, 0, length); | ||
972 | /* re-use the current skb, we only consumed the | ||
973 | * page */ | ||
974 | buffer_info->skb = skb; | ||
975 | skb = rxtop; | ||
976 | rxtop = NULL; | ||
977 | e1000_consume_page(buffer_info, skb, length); | ||
978 | } else { | ||
979 | /* no chain, got EOP, this buf is the packet | ||
980 | * copybreak to save the put_page/alloc_page */ | ||
981 | if (length <= copybreak && | ||
982 | skb_tailroom(skb) >= length) { | ||
983 | u8 *vaddr; | ||
984 | vaddr = kmap_atomic(buffer_info->page, | ||
985 | KM_SKB_DATA_SOFTIRQ); | ||
986 | memcpy(skb_tail_pointer(skb), vaddr, | ||
987 | length); | ||
988 | kunmap_atomic(vaddr, | ||
989 | KM_SKB_DATA_SOFTIRQ); | ||
990 | /* re-use the page, so don't erase | ||
991 | * buffer_info->page */ | ||
992 | skb_put(skb, length); | ||
993 | } else { | ||
994 | skb_fill_page_desc(skb, 0, | ||
995 | buffer_info->page, 0, | ||
996 | length); | ||
997 | e1000_consume_page(buffer_info, skb, | ||
998 | length); | ||
999 | } | ||
1000 | } | ||
1001 | } | ||
1002 | |||
1003 | /* Receive Checksum Offload XXX recompute due to CRC strip? */ | ||
1004 | e1000_rx_checksum(adapter, | ||
1005 | (u32)(status) | | ||
1006 | ((u32)(rx_desc->errors) << 24), | ||
1007 | le16_to_cpu(rx_desc->csum), skb); | ||
1008 | |||
1009 | /* probably a little skewed due to removing CRC */ | ||
1010 | total_rx_bytes += skb->len; | ||
1011 | total_rx_packets++; | ||
1012 | |||
1013 | /* eth type trans needs skb->data to point to something */ | ||
1014 | if (!pskb_may_pull(skb, ETH_HLEN)) { | ||
1015 | ndev_err(netdev, "pskb_may_pull failed.\n"); | ||
1016 | dev_kfree_skb(skb); | ||
1017 | goto next_desc; | ||
1018 | } | ||
1019 | |||
1020 | e1000_receive_skb(adapter, netdev, skb, status, | ||
1021 | rx_desc->special); | ||
1022 | |||
1023 | next_desc: | ||
1024 | rx_desc->status = 0; | ||
1025 | |||
1026 | /* return some buffers to hardware, one at a time is too slow */ | ||
1027 | if (unlikely(cleaned_count >= E1000_RX_BUFFER_WRITE)) { | ||
1028 | adapter->alloc_rx_buf(adapter, cleaned_count); | ||
1029 | cleaned_count = 0; | ||
1030 | } | ||
1031 | |||
1032 | /* use prefetched values */ | ||
1033 | rx_desc = next_rxd; | ||
1034 | buffer_info = next_buffer; | ||
1035 | } | ||
1036 | rx_ring->next_to_clean = i; | ||
1037 | |||
1038 | cleaned_count = e1000_desc_unused(rx_ring); | ||
1039 | if (cleaned_count) | ||
1040 | adapter->alloc_rx_buf(adapter, cleaned_count); | ||
1041 | |||
1042 | adapter->total_rx_bytes += total_rx_bytes; | ||
1043 | adapter->total_rx_packets += total_rx_packets; | ||
1044 | adapter->net_stats.rx_bytes += total_rx_bytes; | ||
1045 | adapter->net_stats.rx_packets += total_rx_packets; | ||
1046 | return cleaned; | ||
1047 | } | ||
1048 | |||
1049 | /** | ||
786 | * e1000_clean_rx_ring - Free Rx Buffers per Queue | 1050 | * e1000_clean_rx_ring - Free Rx Buffers per Queue |
787 | * @adapter: board private structure | 1051 | * @adapter: board private structure |
788 | **/ | 1052 | **/ |
@@ -802,6 +1066,10 @@ static void e1000_clean_rx_ring(struct e1000_adapter *adapter) | |||
802 | pci_unmap_single(pdev, buffer_info->dma, | 1066 | pci_unmap_single(pdev, buffer_info->dma, |
803 | adapter->rx_buffer_len, | 1067 | adapter->rx_buffer_len, |
804 | PCI_DMA_FROMDEVICE); | 1068 | PCI_DMA_FROMDEVICE); |
1069 | else if (adapter->clean_rx == e1000_clean_jumbo_rx_irq) | ||
1070 | pci_unmap_page(pdev, buffer_info->dma, | ||
1071 | PAGE_SIZE, | ||
1072 | PCI_DMA_FROMDEVICE); | ||
805 | else if (adapter->clean_rx == e1000_clean_rx_irq_ps) | 1073 | else if (adapter->clean_rx == e1000_clean_rx_irq_ps) |
806 | pci_unmap_single(pdev, buffer_info->dma, | 1074 | pci_unmap_single(pdev, buffer_info->dma, |
807 | adapter->rx_ps_bsize0, | 1075 | adapter->rx_ps_bsize0, |
@@ -809,6 +1077,11 @@ static void e1000_clean_rx_ring(struct e1000_adapter *adapter) | |||
809 | buffer_info->dma = 0; | 1077 | buffer_info->dma = 0; |
810 | } | 1078 | } |
811 | 1079 | ||
1080 | if (buffer_info->page) { | ||
1081 | put_page(buffer_info->page); | ||
1082 | buffer_info->page = NULL; | ||
1083 | } | ||
1084 | |||
812 | if (buffer_info->skb) { | 1085 | if (buffer_info->skb) { |
813 | dev_kfree_skb(buffer_info->skb); | 1086 | dev_kfree_skb(buffer_info->skb); |
814 | buffer_info->skb = NULL; | 1087 | buffer_info->skb = NULL; |
@@ -1755,10 +2028,12 @@ static void e1000_setup_rctl(struct e1000_adapter *adapter) | |||
1755 | * a lot of memory, since we allocate 3 pages at all times | 2028 | * a lot of memory, since we allocate 3 pages at all times |
1756 | * per packet. | 2029 | * per packet. |
1757 | */ | 2030 | */ |
1758 | adapter->rx_ps_pages = 0; | ||
1759 | pages = PAGE_USE_COUNT(adapter->netdev->mtu); | 2031 | pages = PAGE_USE_COUNT(adapter->netdev->mtu); |
1760 | if ((pages <= 3) && (PAGE_SIZE <= 16384) && (rctl & E1000_RCTL_LPE)) | 2032 | if (!(adapter->flags & FLAG_IS_ICH) && (pages <= 3) && |
2033 | (PAGE_SIZE <= 16384) && (rctl & E1000_RCTL_LPE)) | ||
1761 | adapter->rx_ps_pages = pages; | 2034 | adapter->rx_ps_pages = pages; |
2035 | else | ||
2036 | adapter->rx_ps_pages = 0; | ||
1762 | 2037 | ||
1763 | if (adapter->rx_ps_pages) { | 2038 | if (adapter->rx_ps_pages) { |
1764 | /* Configure extra packet-split registers */ | 2039 | /* Configure extra packet-split registers */ |
@@ -1819,9 +2094,12 @@ static void e1000_configure_rx(struct e1000_adapter *adapter) | |||
1819 | sizeof(union e1000_rx_desc_packet_split); | 2094 | sizeof(union e1000_rx_desc_packet_split); |
1820 | adapter->clean_rx = e1000_clean_rx_irq_ps; | 2095 | adapter->clean_rx = e1000_clean_rx_irq_ps; |
1821 | adapter->alloc_rx_buf = e1000_alloc_rx_buffers_ps; | 2096 | adapter->alloc_rx_buf = e1000_alloc_rx_buffers_ps; |
2097 | } else if (adapter->netdev->mtu > ETH_FRAME_LEN + ETH_FCS_LEN) { | ||
2098 | rdlen = rx_ring->count * sizeof(struct e1000_rx_desc); | ||
2099 | adapter->clean_rx = e1000_clean_jumbo_rx_irq; | ||
2100 | adapter->alloc_rx_buf = e1000_alloc_jumbo_rx_buffers; | ||
1822 | } else { | 2101 | } else { |
1823 | rdlen = rx_ring->count * | 2102 | rdlen = rx_ring->count * sizeof(struct e1000_rx_desc); |
1824 | sizeof(struct e1000_rx_desc); | ||
1825 | adapter->clean_rx = e1000_clean_rx_irq; | 2103 | adapter->clean_rx = e1000_clean_rx_irq; |
1826 | adapter->alloc_rx_buf = e1000_alloc_rx_buffers; | 2104 | adapter->alloc_rx_buf = e1000_alloc_rx_buffers; |
1827 | } | 2105 | } |
@@ -1885,8 +2163,21 @@ static void e1000_configure_rx(struct e1000_adapter *adapter) | |||
1885 | * units), e.g. using jumbo frames when setting to E1000_ERT_2048 | 2163 | * units), e.g. using jumbo frames when setting to E1000_ERT_2048 |
1886 | */ | 2164 | */ |
1887 | if ((adapter->flags & FLAG_HAS_ERT) && | 2165 | if ((adapter->flags & FLAG_HAS_ERT) && |
1888 | (adapter->netdev->mtu > ETH_DATA_LEN)) | 2166 | (adapter->netdev->mtu > ETH_DATA_LEN)) { |
1889 | ew32(ERT, E1000_ERT_2048); | 2167 | u32 rxdctl = er32(RXDCTL(0)); |
2168 | ew32(RXDCTL(0), rxdctl | 0x3); | ||
2169 | ew32(ERT, E1000_ERT_2048 | (1 << 13)); | ||
2170 | /* | ||
2171 | * With jumbo frames and early-receive enabled, excessive | ||
2172 | * C4->C2 latencies result in dropped transactions. | ||
2173 | */ | ||
2174 | pm_qos_update_requirement(PM_QOS_CPU_DMA_LATENCY, | ||
2175 | e1000e_driver_name, 55); | ||
2176 | } else { | ||
2177 | pm_qos_update_requirement(PM_QOS_CPU_DMA_LATENCY, | ||
2178 | e1000e_driver_name, | ||
2179 | PM_QOS_DEFAULT_VALUE); | ||
2180 | } | ||
1890 | 2181 | ||
1891 | /* Enable Receives */ | 2182 | /* Enable Receives */ |
1892 | ew32(RCTL, rctl); | 2183 | ew32(RCTL, rctl); |
@@ -2155,6 +2446,14 @@ void e1000e_reset(struct e1000_adapter *adapter) | |||
2155 | 2446 | ||
2156 | /* Allow time for pending master requests to run */ | 2447 | /* Allow time for pending master requests to run */ |
2157 | mac->ops.reset_hw(hw); | 2448 | mac->ops.reset_hw(hw); |
2449 | |||
2450 | /* | ||
2451 | * For parts with AMT enabled, let the firmware know | ||
2452 | * that the network interface is in control | ||
2453 | */ | ||
2454 | if ((adapter->flags & FLAG_HAS_AMT) && e1000e_check_mng_mode(hw)) | ||
2455 | e1000_get_hw_control(adapter); | ||
2456 | |||
2158 | ew32(WUC, 0); | 2457 | ew32(WUC, 0); |
2159 | 2458 | ||
2160 | if (mac->ops.init_hw(hw)) | 2459 | if (mac->ops.init_hw(hw)) |
@@ -2236,7 +2535,8 @@ void e1000e_down(struct e1000_adapter *adapter) | |||
2236 | adapter->link_speed = 0; | 2535 | adapter->link_speed = 0; |
2237 | adapter->link_duplex = 0; | 2536 | adapter->link_duplex = 0; |
2238 | 2537 | ||
2239 | e1000e_reset(adapter); | 2538 | if (!pci_channel_offline(adapter->pdev)) |
2539 | e1000e_reset(adapter); | ||
2240 | e1000_clean_tx_ring(adapter); | 2540 | e1000_clean_tx_ring(adapter); |
2241 | e1000_clean_rx_ring(adapter); | 2541 | e1000_clean_rx_ring(adapter); |
2242 | 2542 | ||
@@ -3469,6 +3769,8 @@ static int e1000_change_mtu(struct net_device *netdev, int new_mtu) | |||
3469 | * means we reserve 2 more, this pushes us to allocate from the next | 3769 | * means we reserve 2 more, this pushes us to allocate from the next |
3470 | * larger slab size. | 3770 | * larger slab size. |
3471 | * i.e. RXBUFFER_2048 --> size-4096 slab | 3771 | * i.e. RXBUFFER_2048 --> size-4096 slab |
3772 | * However with the new *_jumbo_rx* routines, jumbo receives will use | ||
3773 | * fragmented skbs | ||
3472 | */ | 3774 | */ |
3473 | 3775 | ||
3474 | if (max_frame <= 256) | 3776 | if (max_frame <= 256) |
@@ -3626,6 +3928,9 @@ static int e1000_suspend(struct pci_dev *pdev, pm_message_t state) | |||
3626 | ew32(CTRL_EXT, ctrl_ext); | 3928 | ew32(CTRL_EXT, ctrl_ext); |
3627 | } | 3929 | } |
3628 | 3930 | ||
3931 | if (adapter->flags & FLAG_IS_ICH) | ||
3932 | e1000e_disable_gig_wol_ich8lan(&adapter->hw); | ||
3933 | |||
3629 | /* Allow time for pending master requests to run */ | 3934 | /* Allow time for pending master requests to run */ |
3630 | e1000e_disable_pcie_master(&adapter->hw); | 3935 | e1000e_disable_pcie_master(&adapter->hw); |
3631 | 3936 | ||
@@ -3897,8 +4202,8 @@ static int __devinit e1000_probe(struct pci_dev *pdev, | |||
3897 | struct e1000_adapter *adapter; | 4202 | struct e1000_adapter *adapter; |
3898 | struct e1000_hw *hw; | 4203 | struct e1000_hw *hw; |
3899 | const struct e1000_info *ei = e1000_info_tbl[ent->driver_data]; | 4204 | const struct e1000_info *ei = e1000_info_tbl[ent->driver_data]; |
3900 | unsigned long mmio_start, mmio_len; | 4205 | resource_size_t mmio_start, mmio_len; |
3901 | unsigned long flash_start, flash_len; | 4206 | resource_size_t flash_start, flash_len; |
3902 | 4207 | ||
3903 | static int cards_found; | 4208 | static int cards_found; |
3904 | int i, err, pci_using_dac; | 4209 | int i, err, pci_using_dac; |
@@ -4292,6 +4597,13 @@ static struct pci_device_id e1000_pci_tbl[] = { | |||
4292 | { PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_IFE_GT), board_ich9lan }, | 4597 | { PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_IFE_GT), board_ich9lan }, |
4293 | { PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_IGP_AMT), board_ich9lan }, | 4598 | { PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_IGP_AMT), board_ich9lan }, |
4294 | { PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_IGP_C), board_ich9lan }, | 4599 | { PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_IGP_C), board_ich9lan }, |
4600 | { PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_IGP_M), board_ich9lan }, | ||
4601 | { PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_IGP_M_AMT), board_ich9lan }, | ||
4602 | { PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_IGP_M_V), board_ich9lan }, | ||
4603 | |||
4604 | { PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH10_R_BM_LM), board_ich9lan }, | ||
4605 | { PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH10_R_BM_LF), board_ich9lan }, | ||
4606 | { PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH10_R_BM_V), board_ich9lan }, | ||
4295 | 4607 | ||
4296 | { } /* terminate list */ | 4608 | { } /* terminate list */ |
4297 | }; | 4609 | }; |
@@ -4326,7 +4638,9 @@ static int __init e1000_init_module(void) | |||
4326 | printk(KERN_INFO "%s: Copyright (c) 1999-2008 Intel Corporation.\n", | 4638 | printk(KERN_INFO "%s: Copyright (c) 1999-2008 Intel Corporation.\n", |
4327 | e1000e_driver_name); | 4639 | e1000e_driver_name); |
4328 | ret = pci_register_driver(&e1000_driver); | 4640 | ret = pci_register_driver(&e1000_driver); |
4329 | 4641 | pm_qos_add_requirement(PM_QOS_CPU_DMA_LATENCY, e1000e_driver_name, | |
4642 | PM_QOS_DEFAULT_VALUE); | ||
4643 | |||
4330 | return ret; | 4644 | return ret; |
4331 | } | 4645 | } |
4332 | module_init(e1000_init_module); | 4646 | module_init(e1000_init_module); |
@@ -4340,6 +4654,7 @@ module_init(e1000_init_module); | |||
4340 | static void __exit e1000_exit_module(void) | 4654 | static void __exit e1000_exit_module(void) |
4341 | { | 4655 | { |
4342 | pci_unregister_driver(&e1000_driver); | 4656 | pci_unregister_driver(&e1000_driver); |
4657 | pm_qos_remove_requirement(PM_QOS_CPU_DMA_LATENCY, e1000e_driver_name); | ||
4343 | } | 4658 | } |
4344 | module_exit(e1000_exit_module); | 4659 | module_exit(e1000_exit_module); |
4345 | 4660 | ||
diff --git a/drivers/net/e1000e/phy.c b/drivers/net/e1000e/phy.c index e102332a6bee..b133dcf0e950 100644 --- a/drivers/net/e1000e/phy.c +++ b/drivers/net/e1000e/phy.c | |||
@@ -34,6 +34,9 @@ static s32 e1000_get_phy_cfg_done(struct e1000_hw *hw); | |||
34 | static s32 e1000_phy_force_speed_duplex(struct e1000_hw *hw); | 34 | static s32 e1000_phy_force_speed_duplex(struct e1000_hw *hw); |
35 | static s32 e1000_set_d0_lplu_state(struct e1000_hw *hw, bool active); | 35 | static s32 e1000_set_d0_lplu_state(struct e1000_hw *hw, bool active); |
36 | static s32 e1000_wait_autoneg(struct e1000_hw *hw); | 36 | static s32 e1000_wait_autoneg(struct e1000_hw *hw); |
37 | static u32 e1000_get_phy_addr_for_bm_page(u32 page, u32 reg); | ||
38 | static s32 e1000_access_phy_wakeup_reg_bm(struct e1000_hw *hw, u32 offset, | ||
39 | u16 *data, bool read); | ||
37 | 40 | ||
38 | /* Cable length tables */ | 41 | /* Cable length tables */ |
39 | static const u16 e1000_m88_cable_length_table[] = | 42 | static const u16 e1000_m88_cable_length_table[] = |
@@ -465,6 +468,10 @@ s32 e1000e_copper_link_setup_m88(struct e1000_hw *hw) | |||
465 | if (phy->disable_polarity_correction == 1) | 468 | if (phy->disable_polarity_correction == 1) |
466 | phy_data |= M88E1000_PSCR_POLARITY_REVERSAL; | 469 | phy_data |= M88E1000_PSCR_POLARITY_REVERSAL; |
467 | 470 | ||
471 | /* Enable downshift on BM (disabled by default) */ | ||
472 | if (phy->type == e1000_phy_bm) | ||
473 | phy_data |= BME1000_PSCR_ENABLE_DOWNSHIFT; | ||
474 | |||
468 | ret_val = e1e_wphy(hw, M88E1000_PHY_SPEC_CTRL, phy_data); | 475 | ret_val = e1e_wphy(hw, M88E1000_PHY_SPEC_CTRL, phy_data); |
469 | if (ret_val) | 476 | if (ret_val) |
470 | return ret_val; | 477 | return ret_val; |
@@ -1776,6 +1783,10 @@ enum e1000_phy_type e1000e_get_phy_type_from_id(u32 phy_id) | |||
1776 | case IFE_C_E_PHY_ID: | 1783 | case IFE_C_E_PHY_ID: |
1777 | phy_type = e1000_phy_ife; | 1784 | phy_type = e1000_phy_ife; |
1778 | break; | 1785 | break; |
1786 | case BME1000_E_PHY_ID: | ||
1787 | case BME1000_E_PHY_ID_R2: | ||
1788 | phy_type = e1000_phy_bm; | ||
1789 | break; | ||
1779 | default: | 1790 | default: |
1780 | phy_type = e1000_phy_unknown; | 1791 | phy_type = e1000_phy_unknown; |
1781 | break; | 1792 | break; |
@@ -1784,6 +1795,273 @@ enum e1000_phy_type e1000e_get_phy_type_from_id(u32 phy_id) | |||
1784 | } | 1795 | } |
1785 | 1796 | ||
1786 | /** | 1797 | /** |
1798 | * e1000e_determine_phy_address - Determines PHY address. | ||
1799 | * @hw: pointer to the HW structure | ||
1800 | * | ||
1801 | * This uses a trial and error method to loop through possible PHY | ||
1802 | * addresses. It tests each by reading the PHY ID registers and | ||
1803 | * checking for a match. | ||
1804 | **/ | ||
1805 | s32 e1000e_determine_phy_address(struct e1000_hw *hw) | ||
1806 | { | ||
1807 | s32 ret_val = -E1000_ERR_PHY_TYPE; | ||
1808 | u32 phy_addr= 0; | ||
1809 | u32 i = 0; | ||
1810 | enum e1000_phy_type phy_type = e1000_phy_unknown; | ||
1811 | |||
1812 | do { | ||
1813 | for (phy_addr = 0; phy_addr < 4; phy_addr++) { | ||
1814 | hw->phy.addr = phy_addr; | ||
1815 | e1000e_get_phy_id(hw); | ||
1816 | phy_type = e1000e_get_phy_type_from_id(hw->phy.id); | ||
1817 | |||
1818 | /* | ||
1819 | * If phy_type is valid, break - we found our | ||
1820 | * PHY address | ||
1821 | */ | ||
1822 | if (phy_type != e1000_phy_unknown) { | ||
1823 | ret_val = 0; | ||
1824 | break; | ||
1825 | } | ||
1826 | } | ||
1827 | i++; | ||
1828 | } while ((ret_val != 0) && (i < 100)); | ||
1829 | |||
1830 | return ret_val; | ||
1831 | } | ||
1832 | |||
1833 | /** | ||
1834 | * e1000_get_phy_addr_for_bm_page - Retrieve PHY page address | ||
1835 | * @page: page to access | ||
1836 | * | ||
1837 | * Returns the phy address for the page requested. | ||
1838 | **/ | ||
1839 | static u32 e1000_get_phy_addr_for_bm_page(u32 page, u32 reg) | ||
1840 | { | ||
1841 | u32 phy_addr = 2; | ||
1842 | |||
1843 | if ((page >= 768) || (page == 0 && reg == 25) || (reg == 31)) | ||
1844 | phy_addr = 1; | ||
1845 | |||
1846 | return phy_addr; | ||
1847 | } | ||
1848 | |||
1849 | /** | ||
1850 | * e1000e_write_phy_reg_bm - Write BM PHY register | ||
1851 | * @hw: pointer to the HW structure | ||
1852 | * @offset: register offset to write to | ||
1853 | * @data: data to write at register offset | ||
1854 | * | ||
1855 | * Acquires semaphore, if necessary, then writes the data to PHY register | ||
1856 | * at the offset. Release any acquired semaphores before exiting. | ||
1857 | **/ | ||
1858 | s32 e1000e_write_phy_reg_bm(struct e1000_hw *hw, u32 offset, u16 data) | ||
1859 | { | ||
1860 | s32 ret_val; | ||
1861 | u32 page_select = 0; | ||
1862 | u32 page = offset >> IGP_PAGE_SHIFT; | ||
1863 | u32 page_shift = 0; | ||
1864 | |||
1865 | /* Page 800 works differently than the rest so it has its own func */ | ||
1866 | if (page == BM_WUC_PAGE) { | ||
1867 | ret_val = e1000_access_phy_wakeup_reg_bm(hw, offset, &data, | ||
1868 | false); | ||
1869 | goto out; | ||
1870 | } | ||
1871 | |||
1872 | ret_val = hw->phy.ops.acquire_phy(hw); | ||
1873 | if (ret_val) | ||
1874 | goto out; | ||
1875 | |||
1876 | hw->phy.addr = e1000_get_phy_addr_for_bm_page(page, offset); | ||
1877 | |||
1878 | if (offset > MAX_PHY_MULTI_PAGE_REG) { | ||
1879 | /* | ||
1880 | * Page select is register 31 for phy address 1 and 22 for | ||
1881 | * phy address 2 and 3. Page select is shifted only for | ||
1882 | * phy address 1. | ||
1883 | */ | ||
1884 | if (hw->phy.addr == 1) { | ||
1885 | page_shift = IGP_PAGE_SHIFT; | ||
1886 | page_select = IGP01E1000_PHY_PAGE_SELECT; | ||
1887 | } else { | ||
1888 | page_shift = 0; | ||
1889 | page_select = BM_PHY_PAGE_SELECT; | ||
1890 | } | ||
1891 | |||
1892 | /* Page is shifted left, PHY expects (page x 32) */ | ||
1893 | ret_val = e1000e_write_phy_reg_mdic(hw, page_select, | ||
1894 | (page << page_shift)); | ||
1895 | if (ret_val) { | ||
1896 | hw->phy.ops.release_phy(hw); | ||
1897 | goto out; | ||
1898 | } | ||
1899 | } | ||
1900 | |||
1901 | ret_val = e1000e_write_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset, | ||
1902 | data); | ||
1903 | |||
1904 | hw->phy.ops.release_phy(hw); | ||
1905 | |||
1906 | out: | ||
1907 | return ret_val; | ||
1908 | } | ||
1909 | |||
1910 | /** | ||
1911 | * e1000e_read_phy_reg_bm - Read BM PHY register | ||
1912 | * @hw: pointer to the HW structure | ||
1913 | * @offset: register offset to be read | ||
1914 | * @data: pointer to the read data | ||
1915 | * | ||
1916 | * Acquires semaphore, if necessary, then reads the PHY register at offset | ||
1917 | * and storing the retrieved information in data. Release any acquired | ||
1918 | * semaphores before exiting. | ||
1919 | **/ | ||
1920 | s32 e1000e_read_phy_reg_bm(struct e1000_hw *hw, u32 offset, u16 *data) | ||
1921 | { | ||
1922 | s32 ret_val; | ||
1923 | u32 page_select = 0; | ||
1924 | u32 page = offset >> IGP_PAGE_SHIFT; | ||
1925 | u32 page_shift = 0; | ||
1926 | |||
1927 | /* Page 800 works differently than the rest so it has its own func */ | ||
1928 | if (page == BM_WUC_PAGE) { | ||
1929 | ret_val = e1000_access_phy_wakeup_reg_bm(hw, offset, data, | ||
1930 | true); | ||
1931 | goto out; | ||
1932 | } | ||
1933 | |||
1934 | ret_val = hw->phy.ops.acquire_phy(hw); | ||
1935 | if (ret_val) | ||
1936 | goto out; | ||
1937 | |||
1938 | hw->phy.addr = e1000_get_phy_addr_for_bm_page(page, offset); | ||
1939 | |||
1940 | if (offset > MAX_PHY_MULTI_PAGE_REG) { | ||
1941 | /* | ||
1942 | * Page select is register 31 for phy address 1 and 22 for | ||
1943 | * phy address 2 and 3. Page select is shifted only for | ||
1944 | * phy address 1. | ||
1945 | */ | ||
1946 | if (hw->phy.addr == 1) { | ||
1947 | page_shift = IGP_PAGE_SHIFT; | ||
1948 | page_select = IGP01E1000_PHY_PAGE_SELECT; | ||
1949 | } else { | ||
1950 | page_shift = 0; | ||
1951 | page_select = BM_PHY_PAGE_SELECT; | ||
1952 | } | ||
1953 | |||
1954 | /* Page is shifted left, PHY expects (page x 32) */ | ||
1955 | ret_val = e1000e_write_phy_reg_mdic(hw, page_select, | ||
1956 | (page << page_shift)); | ||
1957 | if (ret_val) { | ||
1958 | hw->phy.ops.release_phy(hw); | ||
1959 | goto out; | ||
1960 | } | ||
1961 | } | ||
1962 | |||
1963 | ret_val = e1000e_read_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset, | ||
1964 | data); | ||
1965 | hw->phy.ops.release_phy(hw); | ||
1966 | |||
1967 | out: | ||
1968 | return ret_val; | ||
1969 | } | ||
1970 | |||
1971 | /** | ||
1972 | * e1000_access_phy_wakeup_reg_bm - Read BM PHY wakeup register | ||
1973 | * @hw: pointer to the HW structure | ||
1974 | * @offset: register offset to be read or written | ||
1975 | * @data: pointer to the data to read or write | ||
1976 | * @read: determines if operation is read or write | ||
1977 | * | ||
1978 | * Acquires semaphore, if necessary, then reads the PHY register at offset | ||
1979 | * and storing the retrieved information in data. Release any acquired | ||
1980 | * semaphores before exiting. Note that procedure to read the wakeup | ||
1981 | * registers are different. It works as such: | ||
1982 | * 1) Set page 769, register 17, bit 2 = 1 | ||
1983 | * 2) Set page to 800 for host (801 if we were manageability) | ||
1984 | * 3) Write the address using the address opcode (0x11) | ||
1985 | * 4) Read or write the data using the data opcode (0x12) | ||
1986 | * 5) Restore 769_17.2 to its original value | ||
1987 | **/ | ||
1988 | static s32 e1000_access_phy_wakeup_reg_bm(struct e1000_hw *hw, u32 offset, | ||
1989 | u16 *data, bool read) | ||
1990 | { | ||
1991 | s32 ret_val; | ||
1992 | u16 reg = ((u16)offset) & PHY_REG_MASK; | ||
1993 | u16 phy_reg = 0; | ||
1994 | u8 phy_acquired = 1; | ||
1995 | |||
1996 | |||
1997 | ret_val = hw->phy.ops.acquire_phy(hw); | ||
1998 | if (ret_val) { | ||
1999 | phy_acquired = 0; | ||
2000 | goto out; | ||
2001 | } | ||
2002 | |||
2003 | /* All operations in this function are phy address 1 */ | ||
2004 | hw->phy.addr = 1; | ||
2005 | |||
2006 | /* Set page 769 */ | ||
2007 | e1000e_write_phy_reg_mdic(hw, IGP01E1000_PHY_PAGE_SELECT, | ||
2008 | (BM_WUC_ENABLE_PAGE << IGP_PAGE_SHIFT)); | ||
2009 | |||
2010 | ret_val = e1000e_read_phy_reg_mdic(hw, BM_WUC_ENABLE_REG, &phy_reg); | ||
2011 | if (ret_val) | ||
2012 | goto out; | ||
2013 | |||
2014 | /* First clear bit 4 to avoid a power state change */ | ||
2015 | phy_reg &= ~(BM_WUC_HOST_WU_BIT); | ||
2016 | ret_val = e1000e_write_phy_reg_mdic(hw, BM_WUC_ENABLE_REG, phy_reg); | ||
2017 | if (ret_val) | ||
2018 | goto out; | ||
2019 | |||
2020 | /* Write bit 2 = 1, and clear bit 4 to 769_17 */ | ||
2021 | ret_val = e1000e_write_phy_reg_mdic(hw, BM_WUC_ENABLE_REG, | ||
2022 | phy_reg | BM_WUC_ENABLE_BIT); | ||
2023 | if (ret_val) | ||
2024 | goto out; | ||
2025 | |||
2026 | /* Select page 800 */ | ||
2027 | ret_val = e1000e_write_phy_reg_mdic(hw, IGP01E1000_PHY_PAGE_SELECT, | ||
2028 | (BM_WUC_PAGE << IGP_PAGE_SHIFT)); | ||
2029 | |||
2030 | /* Write the page 800 offset value using opcode 0x11 */ | ||
2031 | ret_val = e1000e_write_phy_reg_mdic(hw, BM_WUC_ADDRESS_OPCODE, reg); | ||
2032 | if (ret_val) | ||
2033 | goto out; | ||
2034 | |||
2035 | if (read) { | ||
2036 | /* Read the page 800 value using opcode 0x12 */ | ||
2037 | ret_val = e1000e_read_phy_reg_mdic(hw, BM_WUC_DATA_OPCODE, | ||
2038 | data); | ||
2039 | } else { | ||
2040 | /* Read the page 800 value using opcode 0x12 */ | ||
2041 | ret_val = e1000e_write_phy_reg_mdic(hw, BM_WUC_DATA_OPCODE, | ||
2042 | *data); | ||
2043 | } | ||
2044 | |||
2045 | if (ret_val) | ||
2046 | goto out; | ||
2047 | |||
2048 | /* | ||
2049 | * Restore 769_17.2 to its original value | ||
2050 | * Set page 769 | ||
2051 | */ | ||
2052 | e1000e_write_phy_reg_mdic(hw, IGP01E1000_PHY_PAGE_SELECT, | ||
2053 | (BM_WUC_ENABLE_PAGE << IGP_PAGE_SHIFT)); | ||
2054 | |||
2055 | /* Clear 769_17.2 */ | ||
2056 | ret_val = e1000e_write_phy_reg_mdic(hw, BM_WUC_ENABLE_REG, phy_reg); | ||
2057 | |||
2058 | out: | ||
2059 | if (phy_acquired == 1) | ||
2060 | hw->phy.ops.release_phy(hw); | ||
2061 | return ret_val; | ||
2062 | } | ||
2063 | |||
2064 | /** | ||
1787 | * e1000e_commit_phy - Soft PHY reset | 2065 | * e1000e_commit_phy - Soft PHY reset |
1788 | * @hw: pointer to the HW structure | 2066 | * @hw: pointer to the HW structure |
1789 | * | 2067 | * |
diff --git a/drivers/net/eexpress.c b/drivers/net/eexpress.c index 2eb82aba4a8b..795c594a4b7c 100644 --- a/drivers/net/eexpress.c +++ b/drivers/net/eexpress.c | |||
@@ -202,7 +202,7 @@ static unsigned short start_code[] = { | |||
202 | 0x0000,Cmd_MCast, | 202 | 0x0000,Cmd_MCast, |
203 | 0x0076, /* link to next command */ | 203 | 0x0076, /* link to next command */ |
204 | #define CONF_NR_MULTICAST 0x44 | 204 | #define CONF_NR_MULTICAST 0x44 |
205 | 0x0000, /* number of multicast addresses */ | 205 | 0x0000, /* number of bytes in multicast address(es) */ |
206 | #define CONF_MULTICAST 0x46 | 206 | #define CONF_MULTICAST 0x46 |
207 | 0x0000, 0x0000, 0x0000, /* some addresses */ | 207 | 0x0000, 0x0000, 0x0000, /* some addresses */ |
208 | 0x0000, 0x0000, 0x0000, | 208 | 0x0000, 0x0000, 0x0000, |
@@ -1569,7 +1569,7 @@ static void eexp_hw_init586(struct net_device *dev) | |||
1569 | 1569 | ||
1570 | static void eexp_setup_filter(struct net_device *dev) | 1570 | static void eexp_setup_filter(struct net_device *dev) |
1571 | { | 1571 | { |
1572 | struct dev_mc_list *dmi = dev->mc_list; | 1572 | struct dev_mc_list *dmi; |
1573 | unsigned short ioaddr = dev->base_addr; | 1573 | unsigned short ioaddr = dev->base_addr; |
1574 | int count = dev->mc_count; | 1574 | int count = dev->mc_count; |
1575 | int i; | 1575 | int i; |
@@ -1580,9 +1580,9 @@ static void eexp_setup_filter(struct net_device *dev) | |||
1580 | } | 1580 | } |
1581 | 1581 | ||
1582 | outw(CONF_NR_MULTICAST & ~31, ioaddr+SM_PTR); | 1582 | outw(CONF_NR_MULTICAST & ~31, ioaddr+SM_PTR); |
1583 | outw(count, ioaddr+SHADOW(CONF_NR_MULTICAST)); | 1583 | outw(6*count, ioaddr+SHADOW(CONF_NR_MULTICAST)); |
1584 | for (i = 0; i < count; i++) { | 1584 | for (i = 0, dmi = dev->mc_list; i < count; i++, dmi = dmi->next) { |
1585 | unsigned short *data = (unsigned short *)dmi->dmi_addr; | 1585 | unsigned short *data; |
1586 | if (!dmi) { | 1586 | if (!dmi) { |
1587 | printk(KERN_INFO "%s: too few multicast addresses\n", dev->name); | 1587 | printk(KERN_INFO "%s: too few multicast addresses\n", dev->name); |
1588 | break; | 1588 | break; |
@@ -1591,6 +1591,7 @@ static void eexp_setup_filter(struct net_device *dev) | |||
1591 | printk(KERN_INFO "%s: invalid multicast address length given.\n", dev->name); | 1591 | printk(KERN_INFO "%s: invalid multicast address length given.\n", dev->name); |
1592 | continue; | 1592 | continue; |
1593 | } | 1593 | } |
1594 | data = (unsigned short *)dmi->dmi_addr; | ||
1594 | outw((CONF_MULTICAST+(6*i)) & ~31, ioaddr+SM_PTR); | 1595 | outw((CONF_MULTICAST+(6*i)) & ~31, ioaddr+SM_PTR); |
1595 | outw(data[0], ioaddr+SHADOW(CONF_MULTICAST+(6*i))); | 1596 | outw(data[0], ioaddr+SHADOW(CONF_MULTICAST+(6*i))); |
1596 | outw((CONF_MULTICAST+(6*i)+2) & ~31, ioaddr+SM_PTR); | 1597 | outw((CONF_MULTICAST+(6*i)+2) & ~31, ioaddr+SM_PTR); |
diff --git a/drivers/net/ehea/ehea.h b/drivers/net/ehea/ehea.h index f5dacceab95b..e01926b7b5b7 100644 --- a/drivers/net/ehea/ehea.h +++ b/drivers/net/ehea/ehea.h | |||
@@ -40,7 +40,7 @@ | |||
40 | #include <asm/io.h> | 40 | #include <asm/io.h> |
41 | 41 | ||
42 | #define DRV_NAME "ehea" | 42 | #define DRV_NAME "ehea" |
43 | #define DRV_VERSION "EHEA_0090" | 43 | #define DRV_VERSION "EHEA_0092" |
44 | 44 | ||
45 | /* eHEA capability flags */ | 45 | /* eHEA capability flags */ |
46 | #define DLPAR_PORT_ADD_REM 1 | 46 | #define DLPAR_PORT_ADD_REM 1 |
@@ -118,6 +118,13 @@ | |||
118 | #define EHEA_MR_ACC_CTRL 0x00800000 | 118 | #define EHEA_MR_ACC_CTRL 0x00800000 |
119 | 119 | ||
120 | #define EHEA_BUSMAP_START 0x8000000000000000ULL | 120 | #define EHEA_BUSMAP_START 0x8000000000000000ULL |
121 | #define EHEA_INVAL_ADDR 0xFFFFFFFFFFFFFFFFULL | ||
122 | #define EHEA_DIR_INDEX_SHIFT 13 /* 8k Entries in 64k block */ | ||
123 | #define EHEA_TOP_INDEX_SHIFT (EHEA_DIR_INDEX_SHIFT * 2) | ||
124 | #define EHEA_MAP_ENTRIES (1 << EHEA_DIR_INDEX_SHIFT) | ||
125 | #define EHEA_MAP_SIZE (0x10000) /* currently fixed map size */ | ||
126 | #define EHEA_INDEX_MASK (EHEA_MAP_ENTRIES - 1) | ||
127 | |||
121 | 128 | ||
122 | #define EHEA_WATCH_DOG_TIMEOUT 10*HZ | 129 | #define EHEA_WATCH_DOG_TIMEOUT 10*HZ |
123 | 130 | ||
@@ -192,10 +199,20 @@ struct h_epas { | |||
192 | set to 0 if unused */ | 199 | set to 0 if unused */ |
193 | }; | 200 | }; |
194 | 201 | ||
195 | struct ehea_busmap { | 202 | /* |
196 | unsigned int entries; /* total number of entries */ | 203 | * Memory map data structures |
197 | unsigned int valid_sections; /* number of valid sections */ | 204 | */ |
198 | u64 *vaddr; | 205 | struct ehea_dir_bmap |
206 | { | ||
207 | u64 ent[EHEA_MAP_ENTRIES]; | ||
208 | }; | ||
209 | struct ehea_top_bmap | ||
210 | { | ||
211 | struct ehea_dir_bmap *dir[EHEA_MAP_ENTRIES]; | ||
212 | }; | ||
213 | struct ehea_bmap | ||
214 | { | ||
215 | struct ehea_top_bmap *top[EHEA_MAP_ENTRIES]; | ||
199 | }; | 216 | }; |
200 | 217 | ||
201 | struct ehea_qp; | 218 | struct ehea_qp; |
@@ -435,7 +452,7 @@ struct ehea_bcmc_reg_entry { | |||
435 | struct ehea_bcmc_reg_array { | 452 | struct ehea_bcmc_reg_array { |
436 | struct ehea_bcmc_reg_entry *arr; | 453 | struct ehea_bcmc_reg_entry *arr; |
437 | int num_entries; | 454 | int num_entries; |
438 | struct mutex lock; | 455 | spinlock_t lock; |
439 | }; | 456 | }; |
440 | 457 | ||
441 | #define EHEA_PORT_UP 1 | 458 | #define EHEA_PORT_UP 1 |
@@ -461,6 +478,7 @@ struct ehea_port { | |||
461 | int num_add_tx_qps; | 478 | int num_add_tx_qps; |
462 | int num_mcs; | 479 | int num_mcs; |
463 | int resets; | 480 | int resets; |
481 | u64 flags; | ||
464 | u64 mac_addr; | 482 | u64 mac_addr; |
465 | u32 logical_port_id; | 483 | u32 logical_port_id; |
466 | u32 port_speed; | 484 | u32 port_speed; |
@@ -484,7 +502,8 @@ struct port_res_cfg { | |||
484 | }; | 502 | }; |
485 | 503 | ||
486 | enum ehea_flag_bits { | 504 | enum ehea_flag_bits { |
487 | __EHEA_STOP_XFER | 505 | __EHEA_STOP_XFER, |
506 | __EHEA_DISABLE_PORT_RESET | ||
488 | }; | 507 | }; |
489 | 508 | ||
490 | void ehea_set_ethtool_ops(struct net_device *netdev); | 509 | void ehea_set_ethtool_ops(struct net_device *netdev); |
diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c index f9bc21c74b59..0920b796bd78 100644 --- a/drivers/net/ehea/ehea_main.c +++ b/drivers/net/ehea/ehea_main.c | |||
@@ -35,6 +35,7 @@ | |||
35 | #include <linux/if_ether.h> | 35 | #include <linux/if_ether.h> |
36 | #include <linux/notifier.h> | 36 | #include <linux/notifier.h> |
37 | #include <linux/reboot.h> | 37 | #include <linux/reboot.h> |
38 | #include <linux/memory.h> | ||
38 | #include <asm/kexec.h> | 39 | #include <asm/kexec.h> |
39 | #include <linux/mutex.h> | 40 | #include <linux/mutex.h> |
40 | 41 | ||
@@ -117,6 +118,7 @@ static struct of_device_id ehea_device_table[] = { | |||
117 | }, | 118 | }, |
118 | {}, | 119 | {}, |
119 | }; | 120 | }; |
121 | MODULE_DEVICE_TABLE(of, ehea_device_table); | ||
120 | 122 | ||
121 | static struct of_platform_driver ehea_driver = { | 123 | static struct of_platform_driver ehea_driver = { |
122 | .name = "ehea", | 124 | .name = "ehea", |
@@ -136,6 +138,12 @@ void ehea_dump(void *adr, int len, char *msg) | |||
136 | } | 138 | } |
137 | } | 139 | } |
138 | 140 | ||
141 | void ehea_schedule_port_reset(struct ehea_port *port) | ||
142 | { | ||
143 | if (!test_bit(__EHEA_DISABLE_PORT_RESET, &port->flags)) | ||
144 | schedule_work(&port->reset_task); | ||
145 | } | ||
146 | |||
139 | static void ehea_update_firmware_handles(void) | 147 | static void ehea_update_firmware_handles(void) |
140 | { | 148 | { |
141 | struct ehea_fw_handle_entry *arr = NULL; | 149 | struct ehea_fw_handle_entry *arr = NULL; |
@@ -240,7 +248,7 @@ static void ehea_update_bcmc_registrations(void) | |||
240 | } | 248 | } |
241 | 249 | ||
242 | if (num_registrations) { | 250 | if (num_registrations) { |
243 | arr = kzalloc(num_registrations * sizeof(*arr), GFP_KERNEL); | 251 | arr = kzalloc(num_registrations * sizeof(*arr), GFP_ATOMIC); |
244 | if (!arr) | 252 | if (!arr) |
245 | return; /* Keep the existing array */ | 253 | return; /* Keep the existing array */ |
246 | } else | 254 | } else |
@@ -300,7 +308,7 @@ static struct net_device_stats *ehea_get_stats(struct net_device *dev) | |||
300 | 308 | ||
301 | memset(stats, 0, sizeof(*stats)); | 309 | memset(stats, 0, sizeof(*stats)); |
302 | 310 | ||
303 | cb2 = kzalloc(PAGE_SIZE, GFP_KERNEL); | 311 | cb2 = kzalloc(PAGE_SIZE, GFP_ATOMIC); |
304 | if (!cb2) { | 312 | if (!cb2) { |
305 | ehea_error("no mem for cb2"); | 313 | ehea_error("no mem for cb2"); |
306 | goto out; | 314 | goto out; |
@@ -586,7 +594,7 @@ static int ehea_treat_poll_error(struct ehea_port_res *pr, int rq, | |||
586 | "Resetting port.", pr->qp->init_attr.qp_nr); | 594 | "Resetting port.", pr->qp->init_attr.qp_nr); |
587 | ehea_dump(cqe, sizeof(*cqe), "CQE"); | 595 | ehea_dump(cqe, sizeof(*cqe), "CQE"); |
588 | } | 596 | } |
589 | schedule_work(&pr->port->reset_task); | 597 | ehea_schedule_port_reset(pr->port); |
590 | return 1; | 598 | return 1; |
591 | } | 599 | } |
592 | 600 | ||
@@ -615,7 +623,7 @@ static int get_skb_hdr(struct sk_buff *skb, void **iphdr, | |||
615 | *tcph = tcp_hdr(skb); | 623 | *tcph = tcp_hdr(skb); |
616 | 624 | ||
617 | /* check if ip header and tcp header are complete */ | 625 | /* check if ip header and tcp header are complete */ |
618 | if (iph->tot_len < ip_len + tcp_hdrlen(skb)) | 626 | if (ntohs(iph->tot_len) < ip_len + tcp_hdrlen(skb)) |
619 | return -1; | 627 | return -1; |
620 | 628 | ||
621 | *hdr_flags = LRO_IPV4 | LRO_TCP; | 629 | *hdr_flags = LRO_IPV4 | LRO_TCP; |
@@ -764,7 +772,7 @@ static struct ehea_cqe *ehea_proc_cqes(struct ehea_port_res *pr, int my_quota) | |||
764 | ehea_error("Send Completion Error: Resetting port"); | 772 | ehea_error("Send Completion Error: Resetting port"); |
765 | if (netif_msg_tx_err(pr->port)) | 773 | if (netif_msg_tx_err(pr->port)) |
766 | ehea_dump(cqe, sizeof(*cqe), "Send CQE"); | 774 | ehea_dump(cqe, sizeof(*cqe), "Send CQE"); |
767 | schedule_work(&pr->port->reset_task); | 775 | ehea_schedule_port_reset(pr->port); |
768 | break; | 776 | break; |
769 | } | 777 | } |
770 | 778 | ||
@@ -884,7 +892,7 @@ static irqreturn_t ehea_qp_aff_irq_handler(int irq, void *param) | |||
884 | eqe = ehea_poll_eq(port->qp_eq); | 892 | eqe = ehea_poll_eq(port->qp_eq); |
885 | } | 893 | } |
886 | 894 | ||
887 | schedule_work(&port->reset_task); | 895 | ehea_schedule_port_reset(port); |
888 | 896 | ||
889 | return IRQ_HANDLED; | 897 | return IRQ_HANDLED; |
890 | } | 898 | } |
@@ -1762,25 +1770,29 @@ static int ehea_set_mac_addr(struct net_device *dev, void *sa) | |||
1762 | 1770 | ||
1763 | memcpy(dev->dev_addr, mac_addr->sa_data, dev->addr_len); | 1771 | memcpy(dev->dev_addr, mac_addr->sa_data, dev->addr_len); |
1764 | 1772 | ||
1765 | mutex_lock(&ehea_bcmc_regs.lock); | 1773 | spin_lock(&ehea_bcmc_regs.lock); |
1766 | 1774 | ||
1767 | /* Deregister old MAC in pHYP */ | 1775 | /* Deregister old MAC in pHYP */ |
1768 | ret = ehea_broadcast_reg_helper(port, H_DEREG_BCMC); | 1776 | if (port->state == EHEA_PORT_UP) { |
1769 | if (ret) | 1777 | ret = ehea_broadcast_reg_helper(port, H_DEREG_BCMC); |
1770 | goto out_upregs; | 1778 | if (ret) |
1779 | goto out_upregs; | ||
1780 | } | ||
1771 | 1781 | ||
1772 | port->mac_addr = cb0->port_mac_addr << 16; | 1782 | port->mac_addr = cb0->port_mac_addr << 16; |
1773 | 1783 | ||
1774 | /* Register new MAC in pHYP */ | 1784 | /* Register new MAC in pHYP */ |
1775 | ret = ehea_broadcast_reg_helper(port, H_REG_BCMC); | 1785 | if (port->state == EHEA_PORT_UP) { |
1776 | if (ret) | 1786 | ret = ehea_broadcast_reg_helper(port, H_REG_BCMC); |
1777 | goto out_upregs; | 1787 | if (ret) |
1788 | goto out_upregs; | ||
1789 | } | ||
1778 | 1790 | ||
1779 | ret = 0; | 1791 | ret = 0; |
1780 | 1792 | ||
1781 | out_upregs: | 1793 | out_upregs: |
1782 | ehea_update_bcmc_registrations(); | 1794 | ehea_update_bcmc_registrations(); |
1783 | mutex_unlock(&ehea_bcmc_regs.lock); | 1795 | spin_unlock(&ehea_bcmc_regs.lock); |
1784 | out_free: | 1796 | out_free: |
1785 | kfree(cb0); | 1797 | kfree(cb0); |
1786 | out: | 1798 | out: |
@@ -1942,7 +1954,7 @@ static void ehea_set_multicast_list(struct net_device *dev) | |||
1942 | } | 1954 | } |
1943 | ehea_promiscuous(dev, 0); | 1955 | ehea_promiscuous(dev, 0); |
1944 | 1956 | ||
1945 | mutex_lock(&ehea_bcmc_regs.lock); | 1957 | spin_lock(&ehea_bcmc_regs.lock); |
1946 | 1958 | ||
1947 | if (dev->flags & IFF_ALLMULTI) { | 1959 | if (dev->flags & IFF_ALLMULTI) { |
1948 | ehea_allmulti(dev, 1); | 1960 | ehea_allmulti(dev, 1); |
@@ -1973,7 +1985,7 @@ static void ehea_set_multicast_list(struct net_device *dev) | |||
1973 | } | 1985 | } |
1974 | out: | 1986 | out: |
1975 | ehea_update_bcmc_registrations(); | 1987 | ehea_update_bcmc_registrations(); |
1976 | mutex_unlock(&ehea_bcmc_regs.lock); | 1988 | spin_unlock(&ehea_bcmc_regs.lock); |
1977 | return; | 1989 | return; |
1978 | } | 1990 | } |
1979 | 1991 | ||
@@ -2212,8 +2224,6 @@ static void ehea_vlan_rx_register(struct net_device *dev, | |||
2212 | goto out; | 2224 | goto out; |
2213 | } | 2225 | } |
2214 | 2226 | ||
2215 | memset(cb1->vlan_filter, 0, sizeof(cb1->vlan_filter)); | ||
2216 | |||
2217 | hret = ehea_h_modify_ehea_port(adapter->handle, port->logical_port_id, | 2227 | hret = ehea_h_modify_ehea_port(adapter->handle, port->logical_port_id, |
2218 | H_PORT_CB1, H_PORT_CB1_ALL, cb1); | 2228 | H_PORT_CB1, H_PORT_CB1_ALL, cb1); |
2219 | if (hret != H_SUCCESS) | 2229 | if (hret != H_SUCCESS) |
@@ -2494,7 +2504,7 @@ static int ehea_up(struct net_device *dev) | |||
2494 | } | 2504 | } |
2495 | } | 2505 | } |
2496 | 2506 | ||
2497 | mutex_lock(&ehea_bcmc_regs.lock); | 2507 | spin_lock(&ehea_bcmc_regs.lock); |
2498 | 2508 | ||
2499 | ret = ehea_broadcast_reg_helper(port, H_REG_BCMC); | 2509 | ret = ehea_broadcast_reg_helper(port, H_REG_BCMC); |
2500 | if (ret) { | 2510 | if (ret) { |
@@ -2517,7 +2527,7 @@ out: | |||
2517 | ehea_info("Failed starting %s. ret=%i", dev->name, ret); | 2527 | ehea_info("Failed starting %s. ret=%i", dev->name, ret); |
2518 | 2528 | ||
2519 | ehea_update_bcmc_registrations(); | 2529 | ehea_update_bcmc_registrations(); |
2520 | mutex_unlock(&ehea_bcmc_regs.lock); | 2530 | spin_unlock(&ehea_bcmc_regs.lock); |
2521 | 2531 | ||
2522 | ehea_update_firmware_handles(); | 2532 | ehea_update_firmware_handles(); |
2523 | mutex_unlock(&ehea_fw_handles.lock); | 2533 | mutex_unlock(&ehea_fw_handles.lock); |
@@ -2572,7 +2582,7 @@ static int ehea_down(struct net_device *dev) | |||
2572 | 2582 | ||
2573 | mutex_lock(&ehea_fw_handles.lock); | 2583 | mutex_lock(&ehea_fw_handles.lock); |
2574 | 2584 | ||
2575 | mutex_lock(&ehea_bcmc_regs.lock); | 2585 | spin_lock(&ehea_bcmc_regs.lock); |
2576 | ehea_drop_multicast_list(dev); | 2586 | ehea_drop_multicast_list(dev); |
2577 | ehea_broadcast_reg_helper(port, H_DEREG_BCMC); | 2587 | ehea_broadcast_reg_helper(port, H_DEREG_BCMC); |
2578 | 2588 | ||
@@ -2581,7 +2591,7 @@ static int ehea_down(struct net_device *dev) | |||
2581 | port->state = EHEA_PORT_DOWN; | 2591 | port->state = EHEA_PORT_DOWN; |
2582 | 2592 | ||
2583 | ehea_update_bcmc_registrations(); | 2593 | ehea_update_bcmc_registrations(); |
2584 | mutex_unlock(&ehea_bcmc_regs.lock); | 2594 | spin_unlock(&ehea_bcmc_regs.lock); |
2585 | 2595 | ||
2586 | ret = ehea_clean_all_portres(port); | 2596 | ret = ehea_clean_all_portres(port); |
2587 | if (ret) | 2597 | if (ret) |
@@ -2602,12 +2612,14 @@ static int ehea_stop(struct net_device *dev) | |||
2602 | if (netif_msg_ifdown(port)) | 2612 | if (netif_msg_ifdown(port)) |
2603 | ehea_info("disabling port %s", dev->name); | 2613 | ehea_info("disabling port %s", dev->name); |
2604 | 2614 | ||
2605 | flush_scheduled_work(); | 2615 | set_bit(__EHEA_DISABLE_PORT_RESET, &port->flags); |
2616 | cancel_work_sync(&port->reset_task); | ||
2606 | mutex_lock(&port->port_lock); | 2617 | mutex_lock(&port->port_lock); |
2607 | netif_stop_queue(dev); | 2618 | netif_stop_queue(dev); |
2608 | port_napi_disable(port); | 2619 | port_napi_disable(port); |
2609 | ret = ehea_down(dev); | 2620 | ret = ehea_down(dev); |
2610 | mutex_unlock(&port->port_lock); | 2621 | mutex_unlock(&port->port_lock); |
2622 | clear_bit(__EHEA_DISABLE_PORT_RESET, &port->flags); | ||
2611 | return ret; | 2623 | return ret; |
2612 | } | 2624 | } |
2613 | 2625 | ||
@@ -2937,7 +2949,7 @@ static void ehea_tx_watchdog(struct net_device *dev) | |||
2937 | 2949 | ||
2938 | if (netif_carrier_ok(dev) && | 2950 | if (netif_carrier_ok(dev) && |
2939 | !test_bit(__EHEA_STOP_XFER, &ehea_driver_flags)) | 2951 | !test_bit(__EHEA_STOP_XFER, &ehea_driver_flags)) |
2940 | schedule_work(&port->reset_task); | 2952 | ehea_schedule_port_reset(port); |
2941 | } | 2953 | } |
2942 | 2954 | ||
2943 | int ehea_sense_adapter_attr(struct ehea_adapter *adapter) | 2955 | int ehea_sense_adapter_attr(struct ehea_adapter *adapter) |
@@ -3177,11 +3189,12 @@ out_err: | |||
3177 | 3189 | ||
3178 | static void ehea_shutdown_single_port(struct ehea_port *port) | 3190 | static void ehea_shutdown_single_port(struct ehea_port *port) |
3179 | { | 3191 | { |
3192 | struct ehea_adapter *adapter = port->adapter; | ||
3180 | unregister_netdev(port->netdev); | 3193 | unregister_netdev(port->netdev); |
3181 | ehea_unregister_port(port); | 3194 | ehea_unregister_port(port); |
3182 | kfree(port->mc_list); | 3195 | kfree(port->mc_list); |
3183 | free_netdev(port->netdev); | 3196 | free_netdev(port->netdev); |
3184 | port->adapter->active_ports--; | 3197 | adapter->active_ports--; |
3185 | } | 3198 | } |
3186 | 3199 | ||
3187 | static int ehea_setup_ports(struct ehea_adapter *adapter) | 3200 | static int ehea_setup_ports(struct ehea_adapter *adapter) |
@@ -3503,6 +3516,24 @@ void ehea_crash_handler(void) | |||
3503 | 0, H_DEREG_BCMC); | 3516 | 0, H_DEREG_BCMC); |
3504 | } | 3517 | } |
3505 | 3518 | ||
3519 | static int ehea_mem_notifier(struct notifier_block *nb, | ||
3520 | unsigned long action, void *data) | ||
3521 | { | ||
3522 | switch (action) { | ||
3523 | case MEM_OFFLINE: | ||
3524 | ehea_info("memory has been removed"); | ||
3525 | ehea_rereg_mrs(NULL); | ||
3526 | break; | ||
3527 | default: | ||
3528 | break; | ||
3529 | } | ||
3530 | return NOTIFY_OK; | ||
3531 | } | ||
3532 | |||
3533 | static struct notifier_block ehea_mem_nb = { | ||
3534 | .notifier_call = ehea_mem_notifier, | ||
3535 | }; | ||
3536 | |||
3506 | static int ehea_reboot_notifier(struct notifier_block *nb, | 3537 | static int ehea_reboot_notifier(struct notifier_block *nb, |
3507 | unsigned long action, void *unused) | 3538 | unsigned long action, void *unused) |
3508 | { | 3539 | { |
@@ -3567,7 +3598,7 @@ int __init ehea_module_init(void) | |||
3567 | memset(&ehea_bcmc_regs, 0, sizeof(ehea_bcmc_regs)); | 3598 | memset(&ehea_bcmc_regs, 0, sizeof(ehea_bcmc_regs)); |
3568 | 3599 | ||
3569 | mutex_init(&ehea_fw_handles.lock); | 3600 | mutex_init(&ehea_fw_handles.lock); |
3570 | mutex_init(&ehea_bcmc_regs.lock); | 3601 | spin_lock_init(&ehea_bcmc_regs.lock); |
3571 | 3602 | ||
3572 | ret = check_module_parm(); | 3603 | ret = check_module_parm(); |
3573 | if (ret) | 3604 | if (ret) |
@@ -3581,6 +3612,10 @@ int __init ehea_module_init(void) | |||
3581 | if (ret) | 3612 | if (ret) |
3582 | ehea_info("failed registering reboot notifier"); | 3613 | ehea_info("failed registering reboot notifier"); |
3583 | 3614 | ||
3615 | ret = register_memory_notifier(&ehea_mem_nb); | ||
3616 | if (ret) | ||
3617 | ehea_info("failed registering memory remove notifier"); | ||
3618 | |||
3584 | ret = crash_shutdown_register(&ehea_crash_handler); | 3619 | ret = crash_shutdown_register(&ehea_crash_handler); |
3585 | if (ret) | 3620 | if (ret) |
3586 | ehea_info("failed registering crash handler"); | 3621 | ehea_info("failed registering crash handler"); |
@@ -3604,6 +3639,7 @@ int __init ehea_module_init(void) | |||
3604 | out3: | 3639 | out3: |
3605 | ibmebus_unregister_driver(&ehea_driver); | 3640 | ibmebus_unregister_driver(&ehea_driver); |
3606 | out2: | 3641 | out2: |
3642 | unregister_memory_notifier(&ehea_mem_nb); | ||
3607 | unregister_reboot_notifier(&ehea_reboot_nb); | 3643 | unregister_reboot_notifier(&ehea_reboot_nb); |
3608 | crash_shutdown_unregister(&ehea_crash_handler); | 3644 | crash_shutdown_unregister(&ehea_crash_handler); |
3609 | out: | 3645 | out: |
@@ -3621,6 +3657,7 @@ static void __exit ehea_module_exit(void) | |||
3621 | ret = crash_shutdown_unregister(&ehea_crash_handler); | 3657 | ret = crash_shutdown_unregister(&ehea_crash_handler); |
3622 | if (ret) | 3658 | if (ret) |
3623 | ehea_info("failed unregistering crash handler"); | 3659 | ehea_info("failed unregistering crash handler"); |
3660 | unregister_memory_notifier(&ehea_mem_nb); | ||
3624 | kfree(ehea_fw_handles.arr); | 3661 | kfree(ehea_fw_handles.arr); |
3625 | kfree(ehea_bcmc_regs.arr); | 3662 | kfree(ehea_bcmc_regs.arr); |
3626 | ehea_destroy_busmap(); | 3663 | ehea_destroy_busmap(); |
diff --git a/drivers/net/ehea/ehea_qmr.c b/drivers/net/ehea/ehea_qmr.c index d522e905f460..140f05baafd8 100644 --- a/drivers/net/ehea/ehea_qmr.c +++ b/drivers/net/ehea/ehea_qmr.c | |||
@@ -31,8 +31,8 @@ | |||
31 | #include "ehea_phyp.h" | 31 | #include "ehea_phyp.h" |
32 | #include "ehea_qmr.h" | 32 | #include "ehea_qmr.h" |
33 | 33 | ||
34 | struct ehea_bmap *ehea_bmap = NULL; | ||
34 | 35 | ||
35 | struct ehea_busmap ehea_bmap = { 0, 0, NULL }; | ||
36 | 36 | ||
37 | 37 | ||
38 | static void *hw_qpageit_get_inc(struct hw_queue *queue) | 38 | static void *hw_qpageit_get_inc(struct hw_queue *queue) |
@@ -559,125 +559,253 @@ int ehea_destroy_qp(struct ehea_qp *qp) | |||
559 | return 0; | 559 | return 0; |
560 | } | 560 | } |
561 | 561 | ||
562 | int ehea_create_busmap(void) | 562 | static inline int ehea_calc_index(unsigned long i, unsigned long s) |
563 | { | 563 | { |
564 | u64 vaddr = EHEA_BUSMAP_START; | 564 | return (i >> s) & EHEA_INDEX_MASK; |
565 | unsigned long high_section_index = 0; | 565 | } |
566 | int i; | ||
567 | 566 | ||
568 | /* | 567 | static inline int ehea_init_top_bmap(struct ehea_top_bmap *ehea_top_bmap, |
569 | * Sections are not in ascending order -> Loop over all sections and | 568 | int dir) |
570 | * find the highest PFN to compute the required map size. | 569 | { |
571 | */ | 570 | if(!ehea_top_bmap->dir[dir]) { |
572 | ehea_bmap.valid_sections = 0; | 571 | ehea_top_bmap->dir[dir] = |
572 | kzalloc(sizeof(struct ehea_dir_bmap), GFP_KERNEL); | ||
573 | if (!ehea_top_bmap->dir[dir]) | ||
574 | return -ENOMEM; | ||
575 | } | ||
576 | return 0; | ||
577 | } | ||
573 | 578 | ||
574 | for (i = 0; i < NR_MEM_SECTIONS; i++) | 579 | static inline int ehea_init_bmap(struct ehea_bmap *ehea_bmap, int top, int dir) |
575 | if (valid_section_nr(i)) | 580 | { |
576 | high_section_index = i; | 581 | if(!ehea_bmap->top[top]) { |
582 | ehea_bmap->top[top] = | ||
583 | kzalloc(sizeof(struct ehea_top_bmap), GFP_KERNEL); | ||
584 | if (!ehea_bmap->top[top]) | ||
585 | return -ENOMEM; | ||
586 | } | ||
587 | return ehea_init_top_bmap(ehea_bmap->top[top], dir); | ||
588 | } | ||
577 | 589 | ||
578 | ehea_bmap.entries = high_section_index + 1; | 590 | static int ehea_create_busmap_callback(unsigned long pfn, |
579 | ehea_bmap.vaddr = vmalloc(ehea_bmap.entries * sizeof(*ehea_bmap.vaddr)); | 591 | unsigned long nr_pages, void *arg) |
592 | { | ||
593 | unsigned long i, mr_len, start_section, end_section; | ||
594 | start_section = (pfn * PAGE_SIZE) / EHEA_SECTSIZE; | ||
595 | end_section = start_section + ((nr_pages * PAGE_SIZE) / EHEA_SECTSIZE); | ||
596 | mr_len = *(unsigned long *)arg; | ||
580 | 597 | ||
581 | if (!ehea_bmap.vaddr) | 598 | ehea_bmap = kzalloc(sizeof(struct ehea_bmap), GFP_KERNEL); |
599 | if (!ehea_bmap) | ||
582 | return -ENOMEM; | 600 | return -ENOMEM; |
583 | 601 | ||
584 | for (i = 0 ; i < ehea_bmap.entries; i++) { | 602 | for (i = start_section; i < end_section; i++) { |
585 | unsigned long pfn = section_nr_to_pfn(i); | 603 | int ret; |
604 | int top, dir, idx; | ||
605 | u64 vaddr; | ||
606 | |||
607 | top = ehea_calc_index(i, EHEA_TOP_INDEX_SHIFT); | ||
608 | dir = ehea_calc_index(i, EHEA_DIR_INDEX_SHIFT); | ||
609 | |||
610 | ret = ehea_init_bmap(ehea_bmap, top, dir); | ||
611 | if(ret) | ||
612 | return ret; | ||
586 | 613 | ||
587 | if (pfn_valid(pfn)) { | 614 | idx = i & EHEA_INDEX_MASK; |
588 | ehea_bmap.vaddr[i] = vaddr; | 615 | vaddr = EHEA_BUSMAP_START + mr_len + i * EHEA_SECTSIZE; |
589 | vaddr += EHEA_SECTSIZE; | 616 | |
590 | ehea_bmap.valid_sections++; | 617 | ehea_bmap->top[top]->dir[dir]->ent[idx] = vaddr; |
591 | } else | ||
592 | ehea_bmap.vaddr[i] = 0; | ||
593 | } | 618 | } |
594 | 619 | ||
620 | mr_len += nr_pages * PAGE_SIZE; | ||
621 | *(unsigned long *)arg = mr_len; | ||
622 | |||
595 | return 0; | 623 | return 0; |
596 | } | 624 | } |
597 | 625 | ||
626 | static unsigned long ehea_mr_len; | ||
627 | |||
628 | static DEFINE_MUTEX(ehea_busmap_mutex); | ||
629 | |||
630 | int ehea_create_busmap(void) | ||
631 | { | ||
632 | int ret; | ||
633 | mutex_lock(&ehea_busmap_mutex); | ||
634 | ehea_mr_len = 0; | ||
635 | ret = walk_memory_resource(0, 1ULL << MAX_PHYSMEM_BITS, &ehea_mr_len, | ||
636 | ehea_create_busmap_callback); | ||
637 | mutex_unlock(&ehea_busmap_mutex); | ||
638 | return ret; | ||
639 | } | ||
640 | |||
598 | void ehea_destroy_busmap(void) | 641 | void ehea_destroy_busmap(void) |
599 | { | 642 | { |
600 | vfree(ehea_bmap.vaddr); | 643 | int top, dir; |
644 | mutex_lock(&ehea_busmap_mutex); | ||
645 | if (!ehea_bmap) | ||
646 | goto out_destroy; | ||
647 | |||
648 | for (top = 0; top < EHEA_MAP_ENTRIES; top++) { | ||
649 | if (!ehea_bmap->top[top]) | ||
650 | continue; | ||
651 | |||
652 | for (dir = 0; dir < EHEA_MAP_ENTRIES; dir++) { | ||
653 | if (!ehea_bmap->top[top]->dir[dir]) | ||
654 | continue; | ||
655 | |||
656 | kfree(ehea_bmap->top[top]->dir[dir]); | ||
657 | } | ||
658 | |||
659 | kfree(ehea_bmap->top[top]); | ||
660 | } | ||
661 | |||
662 | kfree(ehea_bmap); | ||
663 | ehea_bmap = NULL; | ||
664 | out_destroy: | ||
665 | mutex_unlock(&ehea_busmap_mutex); | ||
601 | } | 666 | } |
602 | 667 | ||
603 | u64 ehea_map_vaddr(void *caddr) | 668 | u64 ehea_map_vaddr(void *caddr) |
604 | { | 669 | { |
605 | u64 mapped_addr; | 670 | int top, dir, idx; |
606 | unsigned long index = __pa(caddr) >> SECTION_SIZE_BITS; | 671 | unsigned long index, offset; |
607 | 672 | ||
608 | if (likely(index < ehea_bmap.entries)) { | 673 | if (!ehea_bmap) |
609 | mapped_addr = ehea_bmap.vaddr[index]; | 674 | return EHEA_INVAL_ADDR; |
610 | if (likely(mapped_addr)) | 675 | |
611 | mapped_addr |= (((unsigned long)caddr) | 676 | index = virt_to_abs(caddr) >> SECTION_SIZE_BITS; |
612 | & (EHEA_SECTSIZE - 1)); | 677 | top = (index >> EHEA_TOP_INDEX_SHIFT) & EHEA_INDEX_MASK; |
613 | else | 678 | if (!ehea_bmap->top[top]) |
614 | mapped_addr = -1; | 679 | return EHEA_INVAL_ADDR; |
615 | } else | 680 | |
616 | mapped_addr = -1; | 681 | dir = (index >> EHEA_DIR_INDEX_SHIFT) & EHEA_INDEX_MASK; |
617 | 682 | if (!ehea_bmap->top[top]->dir[dir]) | |
618 | if (unlikely(mapped_addr == -1)) | 683 | return EHEA_INVAL_ADDR; |
619 | if (!test_and_set_bit(__EHEA_STOP_XFER, &ehea_driver_flags)) | 684 | |
620 | schedule_work(&ehea_rereg_mr_task); | 685 | idx = index & EHEA_INDEX_MASK; |
621 | 686 | if (!ehea_bmap->top[top]->dir[dir]->ent[idx]) | |
622 | return mapped_addr; | 687 | return EHEA_INVAL_ADDR; |
688 | |||
689 | offset = (unsigned long)caddr & (EHEA_SECTSIZE - 1); | ||
690 | return ehea_bmap->top[top]->dir[dir]->ent[idx] | offset; | ||
691 | } | ||
692 | |||
693 | static inline void *ehea_calc_sectbase(int top, int dir, int idx) | ||
694 | { | ||
695 | unsigned long ret = idx; | ||
696 | ret |= dir << EHEA_DIR_INDEX_SHIFT; | ||
697 | ret |= top << EHEA_TOP_INDEX_SHIFT; | ||
698 | return abs_to_virt(ret << SECTION_SIZE_BITS); | ||
699 | } | ||
700 | |||
701 | static u64 ehea_reg_mr_section(int top, int dir, int idx, u64 *pt, | ||
702 | struct ehea_adapter *adapter, | ||
703 | struct ehea_mr *mr) | ||
704 | { | ||
705 | void *pg; | ||
706 | u64 j, m, hret; | ||
707 | unsigned long k = 0; | ||
708 | u64 pt_abs = virt_to_abs(pt); | ||
709 | |||
710 | void *sectbase = ehea_calc_sectbase(top, dir, idx); | ||
711 | |||
712 | for (j = 0; j < (EHEA_PAGES_PER_SECTION / EHEA_MAX_RPAGE); j++) { | ||
713 | |||
714 | for (m = 0; m < EHEA_MAX_RPAGE; m++) { | ||
715 | pg = sectbase + ((k++) * EHEA_PAGESIZE); | ||
716 | pt[m] = virt_to_abs(pg); | ||
717 | } | ||
718 | hret = ehea_h_register_rpage_mr(adapter->handle, mr->handle, 0, | ||
719 | 0, pt_abs, EHEA_MAX_RPAGE); | ||
720 | |||
721 | if ((hret != H_SUCCESS) | ||
722 | && (hret != H_PAGE_REGISTERED)) { | ||
723 | ehea_h_free_resource(adapter->handle, mr->handle, | ||
724 | FORCE_FREE); | ||
725 | ehea_error("register_rpage_mr failed"); | ||
726 | return hret; | ||
727 | } | ||
728 | } | ||
729 | return hret; | ||
730 | } | ||
731 | |||
732 | static u64 ehea_reg_mr_sections(int top, int dir, u64 *pt, | ||
733 | struct ehea_adapter *adapter, | ||
734 | struct ehea_mr *mr) | ||
735 | { | ||
736 | u64 hret = H_SUCCESS; | ||
737 | int idx; | ||
738 | |||
739 | for (idx = 0; idx < EHEA_MAP_ENTRIES; idx++) { | ||
740 | if (!ehea_bmap->top[top]->dir[dir]->ent[idx]) | ||
741 | continue; | ||
742 | |||
743 | hret = ehea_reg_mr_section(top, dir, idx, pt, adapter, mr); | ||
744 | if ((hret != H_SUCCESS) && (hret != H_PAGE_REGISTERED)) | ||
745 | return hret; | ||
746 | } | ||
747 | return hret; | ||
748 | } | ||
749 | |||
750 | static u64 ehea_reg_mr_dir_sections(int top, u64 *pt, | ||
751 | struct ehea_adapter *adapter, | ||
752 | struct ehea_mr *mr) | ||
753 | { | ||
754 | u64 hret = H_SUCCESS; | ||
755 | int dir; | ||
756 | |||
757 | for (dir = 0; dir < EHEA_MAP_ENTRIES; dir++) { | ||
758 | if (!ehea_bmap->top[top]->dir[dir]) | ||
759 | continue; | ||
760 | |||
761 | hret = ehea_reg_mr_sections(top, dir, pt, adapter, mr); | ||
762 | if ((hret != H_SUCCESS) && (hret != H_PAGE_REGISTERED)) | ||
763 | return hret; | ||
764 | } | ||
765 | return hret; | ||
623 | } | 766 | } |
624 | 767 | ||
625 | int ehea_reg_kernel_mr(struct ehea_adapter *adapter, struct ehea_mr *mr) | 768 | int ehea_reg_kernel_mr(struct ehea_adapter *adapter, struct ehea_mr *mr) |
626 | { | 769 | { |
627 | int ret; | 770 | int ret; |
628 | u64 *pt; | 771 | u64 *pt; |
629 | void *pg; | 772 | u64 hret; |
630 | u64 hret, pt_abs, i, j, m, mr_len; | ||
631 | u32 acc_ctrl = EHEA_MR_ACC_CTRL; | 773 | u32 acc_ctrl = EHEA_MR_ACC_CTRL; |
632 | 774 | ||
633 | mr_len = ehea_bmap.valid_sections * EHEA_SECTSIZE; | 775 | unsigned long top; |
634 | 776 | ||
635 | pt = kzalloc(PAGE_SIZE, GFP_KERNEL); | 777 | pt = kzalloc(PAGE_SIZE, GFP_KERNEL); |
636 | if (!pt) { | 778 | if (!pt) { |
637 | ehea_error("no mem"); | 779 | ehea_error("no mem"); |
638 | ret = -ENOMEM; | 780 | ret = -ENOMEM; |
639 | goto out; | 781 | goto out; |
640 | } | 782 | } |
641 | pt_abs = virt_to_abs(pt); | ||
642 | 783 | ||
643 | hret = ehea_h_alloc_resource_mr(adapter->handle, | 784 | hret = ehea_h_alloc_resource_mr(adapter->handle, EHEA_BUSMAP_START, |
644 | EHEA_BUSMAP_START, mr_len, | 785 | ehea_mr_len, acc_ctrl, adapter->pd, |
645 | acc_ctrl, adapter->pd, | ||
646 | &mr->handle, &mr->lkey); | 786 | &mr->handle, &mr->lkey); |
787 | |||
647 | if (hret != H_SUCCESS) { | 788 | if (hret != H_SUCCESS) { |
648 | ehea_error("alloc_resource_mr failed"); | 789 | ehea_error("alloc_resource_mr failed"); |
649 | ret = -EIO; | 790 | ret = -EIO; |
650 | goto out; | 791 | goto out; |
651 | } | 792 | } |
652 | 793 | ||
653 | for (i = 0 ; i < ehea_bmap.entries; i++) | 794 | if (!ehea_bmap) { |
654 | if (ehea_bmap.vaddr[i]) { | 795 | ehea_h_free_resource(adapter->handle, mr->handle, FORCE_FREE); |
655 | void *sectbase = __va(i << SECTION_SIZE_BITS); | 796 | ehea_error("no busmap available"); |
656 | unsigned long k = 0; | 797 | ret = -EIO; |
657 | 798 | goto out; | |
658 | for (j = 0; j < (EHEA_PAGES_PER_SECTION / | 799 | } |
659 | EHEA_MAX_RPAGE); j++) { | 800 | |
660 | 801 | for (top = 0; top < EHEA_MAP_ENTRIES; top++) { | |
661 | for (m = 0; m < EHEA_MAX_RPAGE; m++) { | 802 | if (!ehea_bmap->top[top]) |
662 | pg = sectbase + ((k++) * EHEA_PAGESIZE); | 803 | continue; |
663 | pt[m] = virt_to_abs(pg); | 804 | |
664 | } | 805 | hret = ehea_reg_mr_dir_sections(top, pt, adapter, mr); |
665 | 806 | if((hret != H_PAGE_REGISTERED) && (hret != H_SUCCESS)) | |
666 | hret = ehea_h_register_rpage_mr(adapter->handle, | 807 | break; |
667 | mr->handle, | 808 | } |
668 | 0, 0, pt_abs, | ||
669 | EHEA_MAX_RPAGE); | ||
670 | if ((hret != H_SUCCESS) | ||
671 | && (hret != H_PAGE_REGISTERED)) { | ||
672 | ehea_h_free_resource(adapter->handle, | ||
673 | mr->handle, | ||
674 | FORCE_FREE); | ||
675 | ehea_error("register_rpage_mr failed"); | ||
676 | ret = -EIO; | ||
677 | goto out; | ||
678 | } | ||
679 | } | ||
680 | } | ||
681 | 809 | ||
682 | if (hret != H_SUCCESS) { | 810 | if (hret != H_SUCCESS) { |
683 | ehea_h_free_resource(adapter->handle, mr->handle, FORCE_FREE); | 811 | ehea_h_free_resource(adapter->handle, mr->handle, FORCE_FREE); |
diff --git a/drivers/net/enc28j60.c b/drivers/net/enc28j60.c index 46a90e9ec563..c05cb159c772 100644 --- a/drivers/net/enc28j60.c +++ b/drivers/net/enc28j60.c | |||
@@ -400,26 +400,31 @@ enc28j60_packet_write(struct enc28j60_net *priv, int len, const u8 *data) | |||
400 | mutex_unlock(&priv->lock); | 400 | mutex_unlock(&priv->lock); |
401 | } | 401 | } |
402 | 402 | ||
403 | /* | 403 | static unsigned long msec20_to_jiffies; |
404 | * Wait until the PHY operation is complete. | 404 | |
405 | */ | 405 | static int poll_ready(struct enc28j60_net *priv, u8 reg, u8 mask, u8 val) |
406 | static int wait_phy_ready(struct enc28j60_net *priv) | ||
407 | { | 406 | { |
408 | unsigned long timeout = jiffies + 20 * HZ / 1000; | 407 | unsigned long timeout = jiffies + msec20_to_jiffies; |
409 | int ret = 1; | ||
410 | 408 | ||
411 | /* 20 msec timeout read */ | 409 | /* 20 msec timeout read */ |
412 | while (nolock_regb_read(priv, MISTAT) & MISTAT_BUSY) { | 410 | while ((nolock_regb_read(priv, reg) & mask) != val) { |
413 | if (time_after(jiffies, timeout)) { | 411 | if (time_after(jiffies, timeout)) { |
414 | if (netif_msg_drv(priv)) | 412 | if (netif_msg_drv(priv)) |
415 | printk(KERN_DEBUG DRV_NAME | 413 | dev_dbg(&priv->spi->dev, |
416 | ": PHY ready timeout!\n"); | 414 | "reg %02x ready timeout!\n", reg); |
417 | ret = 0; | 415 | return -ETIMEDOUT; |
418 | break; | ||
419 | } | 416 | } |
420 | cpu_relax(); | 417 | cpu_relax(); |
421 | } | 418 | } |
422 | return ret; | 419 | return 0; |
420 | } | ||
421 | |||
422 | /* | ||
423 | * Wait until the PHY operation is complete. | ||
424 | */ | ||
425 | static int wait_phy_ready(struct enc28j60_net *priv) | ||
426 | { | ||
427 | return poll_ready(priv, MISTAT, MISTAT_BUSY, 0) ? 0 : 1; | ||
423 | } | 428 | } |
424 | 429 | ||
425 | /* | 430 | /* |
@@ -594,6 +599,32 @@ static void nolock_txfifo_init(struct enc28j60_net *priv, u16 start, u16 end) | |||
594 | nolock_regw_write(priv, ETXNDL, end); | 599 | nolock_regw_write(priv, ETXNDL, end); |
595 | } | 600 | } |
596 | 601 | ||
602 | /* | ||
603 | * Low power mode shrinks power consumption about 100x, so we'd like | ||
604 | * the chip to be in that mode whenever it's inactive. (However, we | ||
605 | * can't stay in lowpower mode during suspend with WOL active.) | ||
606 | */ | ||
607 | static void enc28j60_lowpower(struct enc28j60_net *priv, bool is_low) | ||
608 | { | ||
609 | if (netif_msg_drv(priv)) | ||
610 | dev_dbg(&priv->spi->dev, "%s power...\n", | ||
611 | is_low ? "low" : "high"); | ||
612 | |||
613 | mutex_lock(&priv->lock); | ||
614 | if (is_low) { | ||
615 | nolock_reg_bfclr(priv, ECON1, ECON1_RXEN); | ||
616 | poll_ready(priv, ESTAT, ESTAT_RXBUSY, 0); | ||
617 | poll_ready(priv, ECON1, ECON1_TXRTS, 0); | ||
618 | /* ECON2_VRPS was set during initialization */ | ||
619 | nolock_reg_bfset(priv, ECON2, ECON2_PWRSV); | ||
620 | } else { | ||
621 | nolock_reg_bfclr(priv, ECON2, ECON2_PWRSV); | ||
622 | poll_ready(priv, ESTAT, ESTAT_CLKRDY, ESTAT_CLKRDY); | ||
623 | /* caller sets ECON1_RXEN */ | ||
624 | } | ||
625 | mutex_unlock(&priv->lock); | ||
626 | } | ||
627 | |||
597 | static int enc28j60_hw_init(struct enc28j60_net *priv) | 628 | static int enc28j60_hw_init(struct enc28j60_net *priv) |
598 | { | 629 | { |
599 | u8 reg; | 630 | u8 reg; |
@@ -612,8 +643,8 @@ static int enc28j60_hw_init(struct enc28j60_net *priv) | |||
612 | priv->tx_retry_count = 0; | 643 | priv->tx_retry_count = 0; |
613 | priv->max_pk_counter = 0; | 644 | priv->max_pk_counter = 0; |
614 | priv->rxfilter = RXFILTER_NORMAL; | 645 | priv->rxfilter = RXFILTER_NORMAL; |
615 | /* enable address auto increment */ | 646 | /* enable address auto increment and voltage regulator powersave */ |
616 | nolock_regb_write(priv, ECON2, ECON2_AUTOINC); | 647 | nolock_regb_write(priv, ECON2, ECON2_AUTOINC | ECON2_VRPS); |
617 | 648 | ||
618 | nolock_rxfifo_init(priv, RXSTART_INIT, RXEND_INIT); | 649 | nolock_rxfifo_init(priv, RXSTART_INIT, RXEND_INIT); |
619 | nolock_txfifo_init(priv, TXSTART_INIT, TXEND_INIT); | 650 | nolock_txfifo_init(priv, TXSTART_INIT, TXEND_INIT); |
@@ -690,7 +721,7 @@ static int enc28j60_hw_init(struct enc28j60_net *priv) | |||
690 | 721 | ||
691 | static void enc28j60_hw_enable(struct enc28j60_net *priv) | 722 | static void enc28j60_hw_enable(struct enc28j60_net *priv) |
692 | { | 723 | { |
693 | /* enable interrutps */ | 724 | /* enable interrupts */ |
694 | if (netif_msg_hw(priv)) | 725 | if (netif_msg_hw(priv)) |
695 | printk(KERN_DEBUG DRV_NAME ": %s() enabling interrupts.\n", | 726 | printk(KERN_DEBUG DRV_NAME ": %s() enabling interrupts.\n", |
696 | __FUNCTION__); | 727 | __FUNCTION__); |
@@ -726,15 +757,12 @@ enc28j60_setlink(struct net_device *ndev, u8 autoneg, u16 speed, u8 duplex) | |||
726 | int ret = 0; | 757 | int ret = 0; |
727 | 758 | ||
728 | if (!priv->hw_enable) { | 759 | if (!priv->hw_enable) { |
729 | if (autoneg == AUTONEG_DISABLE && speed == SPEED_10) { | 760 | /* link is in low power mode now; duplex setting |
761 | * will take effect on next enc28j60_hw_init(). | ||
762 | */ | ||
763 | if (autoneg == AUTONEG_DISABLE && speed == SPEED_10) | ||
730 | priv->full_duplex = (duplex == DUPLEX_FULL); | 764 | priv->full_duplex = (duplex == DUPLEX_FULL); |
731 | if (!enc28j60_hw_init(priv)) { | 765 | else { |
732 | if (netif_msg_drv(priv)) | ||
733 | dev_err(&ndev->dev, | ||
734 | "hw_reset() failed\n"); | ||
735 | ret = -EINVAL; | ||
736 | } | ||
737 | } else { | ||
738 | if (netif_msg_link(priv)) | 766 | if (netif_msg_link(priv)) |
739 | dev_warn(&ndev->dev, | 767 | dev_warn(&ndev->dev, |
740 | "unsupported link setting\n"); | 768 | "unsupported link setting\n"); |
@@ -1307,7 +1335,8 @@ static int enc28j60_net_open(struct net_device *dev) | |||
1307 | } | 1335 | } |
1308 | return -EADDRNOTAVAIL; | 1336 | return -EADDRNOTAVAIL; |
1309 | } | 1337 | } |
1310 | /* Reset the hardware here */ | 1338 | /* Reset the hardware here (and take it out of low power mode) */ |
1339 | enc28j60_lowpower(priv, false); | ||
1311 | enc28j60_hw_disable(priv); | 1340 | enc28j60_hw_disable(priv); |
1312 | if (!enc28j60_hw_init(priv)) { | 1341 | if (!enc28j60_hw_init(priv)) { |
1313 | if (netif_msg_ifup(priv)) | 1342 | if (netif_msg_ifup(priv)) |
@@ -1337,6 +1366,7 @@ static int enc28j60_net_close(struct net_device *dev) | |||
1337 | printk(KERN_DEBUG DRV_NAME ": %s() enter\n", __FUNCTION__); | 1366 | printk(KERN_DEBUG DRV_NAME ": %s() enter\n", __FUNCTION__); |
1338 | 1367 | ||
1339 | enc28j60_hw_disable(priv); | 1368 | enc28j60_hw_disable(priv); |
1369 | enc28j60_lowpower(priv, true); | ||
1340 | netif_stop_queue(dev); | 1370 | netif_stop_queue(dev); |
1341 | 1371 | ||
1342 | return 0; | 1372 | return 0; |
@@ -1537,6 +1567,8 @@ static int __devinit enc28j60_probe(struct spi_device *spi) | |||
1537 | dev->watchdog_timeo = TX_TIMEOUT; | 1567 | dev->watchdog_timeo = TX_TIMEOUT; |
1538 | SET_ETHTOOL_OPS(dev, &enc28j60_ethtool_ops); | 1568 | SET_ETHTOOL_OPS(dev, &enc28j60_ethtool_ops); |
1539 | 1569 | ||
1570 | enc28j60_lowpower(priv, true); | ||
1571 | |||
1540 | ret = register_netdev(dev); | 1572 | ret = register_netdev(dev); |
1541 | if (ret) { | 1573 | if (ret) { |
1542 | if (netif_msg_probe(priv)) | 1574 | if (netif_msg_probe(priv)) |
@@ -1556,7 +1588,7 @@ error_alloc: | |||
1556 | return ret; | 1588 | return ret; |
1557 | } | 1589 | } |
1558 | 1590 | ||
1559 | static int enc28j60_remove(struct spi_device *spi) | 1591 | static int __devexit enc28j60_remove(struct spi_device *spi) |
1560 | { | 1592 | { |
1561 | struct enc28j60_net *priv = dev_get_drvdata(&spi->dev); | 1593 | struct enc28j60_net *priv = dev_get_drvdata(&spi->dev); |
1562 | 1594 | ||
@@ -1573,15 +1605,16 @@ static int enc28j60_remove(struct spi_device *spi) | |||
1573 | static struct spi_driver enc28j60_driver = { | 1605 | static struct spi_driver enc28j60_driver = { |
1574 | .driver = { | 1606 | .driver = { |
1575 | .name = DRV_NAME, | 1607 | .name = DRV_NAME, |
1576 | .bus = &spi_bus_type, | ||
1577 | .owner = THIS_MODULE, | 1608 | .owner = THIS_MODULE, |
1578 | }, | 1609 | }, |
1579 | .probe = enc28j60_probe, | 1610 | .probe = enc28j60_probe, |
1580 | .remove = __devexit_p(enc28j60_remove), | 1611 | .remove = __devexit_p(enc28j60_remove), |
1581 | }; | 1612 | }; |
1582 | 1613 | ||
1583 | static int __init enc28j60_init(void) | 1614 | static int __init enc28j60_init(void) |
1584 | { | 1615 | { |
1616 | msec20_to_jiffies = msecs_to_jiffies(20); | ||
1617 | |||
1585 | return spi_register_driver(&enc28j60_driver); | 1618 | return spi_register_driver(&enc28j60_driver); |
1586 | } | 1619 | } |
1587 | 1620 | ||
diff --git a/drivers/net/fec_mpc52xx.c b/drivers/net/fec_mpc52xx.c index d21b7ab64bd1..329edd9c08fc 100644 --- a/drivers/net/fec_mpc52xx.c +++ b/drivers/net/fec_mpc52xx.c | |||
@@ -43,6 +43,29 @@ | |||
43 | 43 | ||
44 | #define DRIVER_NAME "mpc52xx-fec" | 44 | #define DRIVER_NAME "mpc52xx-fec" |
45 | 45 | ||
46 | #define FEC5200_PHYADDR_NONE (-1) | ||
47 | #define FEC5200_PHYADDR_7WIRE (-2) | ||
48 | |||
49 | /* Private driver data structure */ | ||
50 | struct mpc52xx_fec_priv { | ||
51 | int duplex; | ||
52 | int speed; | ||
53 | int r_irq; | ||
54 | int t_irq; | ||
55 | struct mpc52xx_fec __iomem *fec; | ||
56 | struct bcom_task *rx_dmatsk; | ||
57 | struct bcom_task *tx_dmatsk; | ||
58 | spinlock_t lock; | ||
59 | int msg_enable; | ||
60 | |||
61 | /* MDIO link details */ | ||
62 | int phy_addr; | ||
63 | unsigned int phy_speed; | ||
64 | struct phy_device *phydev; | ||
65 | enum phy_state link; | ||
66 | }; | ||
67 | |||
68 | |||
46 | static irqreturn_t mpc52xx_fec_interrupt(int, void *); | 69 | static irqreturn_t mpc52xx_fec_interrupt(int, void *); |
47 | static irqreturn_t mpc52xx_fec_rx_interrupt(int, void *); | 70 | static irqreturn_t mpc52xx_fec_rx_interrupt(int, void *); |
48 | static irqreturn_t mpc52xx_fec_tx_interrupt(int, void *); | 71 | static irqreturn_t mpc52xx_fec_tx_interrupt(int, void *); |
@@ -55,7 +78,7 @@ module_param_array_named(mac, mpc52xx_fec_mac_addr, byte, NULL, 0); | |||
55 | MODULE_PARM_DESC(mac, "six hex digits, ie. 0x1,0x2,0xc0,0x01,0xba,0xbe"); | 78 | MODULE_PARM_DESC(mac, "six hex digits, ie. 0x1,0x2,0xc0,0x01,0xba,0xbe"); |
56 | 79 | ||
57 | #define MPC52xx_MESSAGES_DEFAULT ( NETIF_MSG_DRV | NETIF_MSG_PROBE | \ | 80 | #define MPC52xx_MESSAGES_DEFAULT ( NETIF_MSG_DRV | NETIF_MSG_PROBE | \ |
58 | NETIF_MSG_LINK | NETIF_MSG_IFDOWN | NETIF_MSG_IFDOWN ) | 81 | NETIF_MSG_LINK | NETIF_MSG_IFDOWN | NETIF_MSG_IFUP) |
59 | static int debug = -1; /* the above default */ | 82 | static int debug = -1; /* the above default */ |
60 | module_param(debug, int, 0); | 83 | module_param(debug, int, 0); |
61 | MODULE_PARM_DESC(debug, "debugging messages level"); | 84 | MODULE_PARM_DESC(debug, "debugging messages level"); |
@@ -223,7 +246,7 @@ static int mpc52xx_fec_phy_start(struct net_device *dev) | |||
223 | struct mpc52xx_fec_priv *priv = netdev_priv(dev); | 246 | struct mpc52xx_fec_priv *priv = netdev_priv(dev); |
224 | int err; | 247 | int err; |
225 | 248 | ||
226 | if (!priv->has_phy) | 249 | if (priv->phy_addr < 0) |
227 | return 0; | 250 | return 0; |
228 | 251 | ||
229 | err = mpc52xx_fec_init_phy(dev); | 252 | err = mpc52xx_fec_init_phy(dev); |
@@ -243,7 +266,7 @@ static void mpc52xx_fec_phy_stop(struct net_device *dev) | |||
243 | { | 266 | { |
244 | struct mpc52xx_fec_priv *priv = netdev_priv(dev); | 267 | struct mpc52xx_fec_priv *priv = netdev_priv(dev); |
245 | 268 | ||
246 | if (!priv->has_phy) | 269 | if (!priv->phydev) |
247 | return; | 270 | return; |
248 | 271 | ||
249 | phy_disconnect(priv->phydev); | 272 | phy_disconnect(priv->phydev); |
@@ -255,7 +278,7 @@ static void mpc52xx_fec_phy_stop(struct net_device *dev) | |||
255 | static int mpc52xx_fec_phy_mii_ioctl(struct mpc52xx_fec_priv *priv, | 278 | static int mpc52xx_fec_phy_mii_ioctl(struct mpc52xx_fec_priv *priv, |
256 | struct mii_ioctl_data *mii_data, int cmd) | 279 | struct mii_ioctl_data *mii_data, int cmd) |
257 | { | 280 | { |
258 | if (!priv->has_phy) | 281 | if (!priv->phydev) |
259 | return -ENOTSUPP; | 282 | return -ENOTSUPP; |
260 | 283 | ||
261 | return phy_mii_ioctl(priv->phydev, mii_data, cmd); | 284 | return phy_mii_ioctl(priv->phydev, mii_data, cmd); |
@@ -265,7 +288,7 @@ static void mpc52xx_fec_phy_hw_init(struct mpc52xx_fec_priv *priv) | |||
265 | { | 288 | { |
266 | struct mpc52xx_fec __iomem *fec = priv->fec; | 289 | struct mpc52xx_fec __iomem *fec = priv->fec; |
267 | 290 | ||
268 | if (!priv->has_phy) | 291 | if (priv->phydev) |
269 | return; | 292 | return; |
270 | 293 | ||
271 | out_be32(&fec->mii_speed, priv->phy_speed); | 294 | out_be32(&fec->mii_speed, priv->phy_speed); |
@@ -704,7 +727,7 @@ static void mpc52xx_fec_start(struct net_device *dev) | |||
704 | rcntrl = FEC_RX_BUFFER_SIZE << 16; /* max frame length */ | 727 | rcntrl = FEC_RX_BUFFER_SIZE << 16; /* max frame length */ |
705 | rcntrl |= FEC_RCNTRL_FCE; | 728 | rcntrl |= FEC_RCNTRL_FCE; |
706 | 729 | ||
707 | if (priv->has_phy) | 730 | if (priv->phy_addr != FEC5200_PHYADDR_7WIRE) |
708 | rcntrl |= FEC_RCNTRL_MII_MODE; | 731 | rcntrl |= FEC_RCNTRL_MII_MODE; |
709 | 732 | ||
710 | if (priv->duplex == DUPLEX_FULL) | 733 | if (priv->duplex == DUPLEX_FULL) |
@@ -864,7 +887,10 @@ mpc52xx_fec_probe(struct of_device *op, const struct of_device_id *match) | |||
864 | struct net_device *ndev; | 887 | struct net_device *ndev; |
865 | struct mpc52xx_fec_priv *priv = NULL; | 888 | struct mpc52xx_fec_priv *priv = NULL; |
866 | struct resource mem; | 889 | struct resource mem; |
867 | const phandle *ph; | 890 | struct device_node *phy_node; |
891 | const phandle *phy_handle; | ||
892 | const u32 *prop; | ||
893 | int prop_size; | ||
868 | 894 | ||
869 | phys_addr_t rx_fifo; | 895 | phys_addr_t rx_fifo; |
870 | phys_addr_t tx_fifo; | 896 | phys_addr_t tx_fifo; |
@@ -948,26 +974,37 @@ mpc52xx_fec_probe(struct of_device *op, const struct of_device_id *match) | |||
948 | mpc52xx_fec_get_paddr(ndev, ndev->dev_addr); | 974 | mpc52xx_fec_get_paddr(ndev, ndev->dev_addr); |
949 | 975 | ||
950 | priv->msg_enable = netif_msg_init(debug, MPC52xx_MESSAGES_DEFAULT); | 976 | priv->msg_enable = netif_msg_init(debug, MPC52xx_MESSAGES_DEFAULT); |
951 | priv->duplex = DUPLEX_FULL; | ||
952 | |||
953 | /* is the phy present in device tree? */ | ||
954 | ph = of_get_property(op->node, "phy-handle", NULL); | ||
955 | if (ph) { | ||
956 | const unsigned int *prop; | ||
957 | struct device_node *phy_dn; | ||
958 | priv->has_phy = 1; | ||
959 | 977 | ||
960 | phy_dn = of_find_node_by_phandle(*ph); | 978 | /* |
961 | prop = of_get_property(phy_dn, "reg", NULL); | 979 | * Link mode configuration |
962 | priv->phy_addr = *prop; | 980 | */ |
963 | 981 | ||
964 | of_node_put(phy_dn); | 982 | /* Start with safe defaults for link connection */ |
983 | priv->phy_addr = FEC5200_PHYADDR_NONE; | ||
984 | priv->speed = 100; | ||
985 | priv->duplex = DUPLEX_HALF; | ||
986 | priv->phy_speed = ((mpc52xx_find_ipb_freq(op->node) >> 20) / 5) << 1; | ||
987 | |||
988 | /* the 7-wire property means don't use MII mode */ | ||
989 | if (of_find_property(op->node, "fsl,7-wire-mode", NULL)) | ||
990 | priv->phy_addr = FEC5200_PHYADDR_7WIRE; | ||
991 | |||
992 | /* The current speed preconfigures the speed of the MII link */ | ||
993 | prop = of_get_property(op->node, "current-speed", &prop_size); | ||
994 | if (prop && (prop_size >= sizeof(u32) * 2)) { | ||
995 | priv->speed = prop[0]; | ||
996 | priv->duplex = prop[1] ? DUPLEX_FULL : DUPLEX_HALF; | ||
997 | } | ||
965 | 998 | ||
966 | /* Phy speed */ | 999 | /* If there is a phy handle, setup link to that phy */ |
967 | priv->phy_speed = ((mpc52xx_find_ipb_freq(op->node) >> 20) / 5) << 1; | 1000 | phy_handle = of_get_property(op->node, "phy-handle", &prop_size); |
968 | } else { | 1001 | if (phy_handle && (prop_size >= sizeof(phandle))) { |
969 | dev_info(&ndev->dev, "can't find \"phy-handle\" in device" | 1002 | phy_node = of_find_node_by_phandle(*phy_handle); |
970 | " tree, using 7-wire mode\n"); | 1003 | prop = of_get_property(phy_node, "reg", &prop_size); |
1004 | if (prop && (prop_size >= sizeof(u32))) | ||
1005 | if ((*prop >= 0) && (*prop < PHY_MAX_ADDR)) | ||
1006 | priv->phy_addr = *prop; | ||
1007 | of_node_put(phy_node); | ||
971 | } | 1008 | } |
972 | 1009 | ||
973 | /* Hardware init */ | 1010 | /* Hardware init */ |
@@ -982,6 +1019,20 @@ mpc52xx_fec_probe(struct of_device *op, const struct of_device_id *match) | |||
982 | if (rv < 0) | 1019 | if (rv < 0) |
983 | goto probe_error; | 1020 | goto probe_error; |
984 | 1021 | ||
1022 | /* Now report the link setup */ | ||
1023 | switch (priv->phy_addr) { | ||
1024 | case FEC5200_PHYADDR_NONE: | ||
1025 | dev_info(&ndev->dev, "Fixed speed MII link: %i%cD\n", | ||
1026 | priv->speed, priv->duplex ? 'F' : 'H'); | ||
1027 | break; | ||
1028 | case FEC5200_PHYADDR_7WIRE: | ||
1029 | dev_info(&ndev->dev, "using 7-wire PHY mode\n"); | ||
1030 | break; | ||
1031 | default: | ||
1032 | dev_info(&ndev->dev, "Using PHY at MDIO address %i\n", | ||
1033 | priv->phy_addr); | ||
1034 | } | ||
1035 | |||
985 | /* We're done ! */ | 1036 | /* We're done ! */ |
986 | dev_set_drvdata(&op->dev, ndev); | 1037 | dev_set_drvdata(&op->dev, ndev); |
987 | 1038 | ||
diff --git a/drivers/net/fec_mpc52xx.h b/drivers/net/fec_mpc52xx.h index 8b1f75397b9a..a227a525bdbb 100644 --- a/drivers/net/fec_mpc52xx.h +++ b/drivers/net/fec_mpc52xx.h | |||
@@ -26,25 +26,6 @@ | |||
26 | 26 | ||
27 | #define FEC_WATCHDOG_TIMEOUT ((400*HZ)/1000) | 27 | #define FEC_WATCHDOG_TIMEOUT ((400*HZ)/1000) |
28 | 28 | ||
29 | struct mpc52xx_fec_priv { | ||
30 | int duplex; | ||
31 | int r_irq; | ||
32 | int t_irq; | ||
33 | struct mpc52xx_fec __iomem *fec; | ||
34 | struct bcom_task *rx_dmatsk; | ||
35 | struct bcom_task *tx_dmatsk; | ||
36 | spinlock_t lock; | ||
37 | int msg_enable; | ||
38 | |||
39 | int has_phy; | ||
40 | unsigned int phy_speed; | ||
41 | unsigned int phy_addr; | ||
42 | struct phy_device *phydev; | ||
43 | enum phy_state link; | ||
44 | int speed; | ||
45 | }; | ||
46 | |||
47 | |||
48 | /* ======================================================================== */ | 29 | /* ======================================================================== */ |
49 | /* Hardware register sets & bits */ | 30 | /* Hardware register sets & bits */ |
50 | /* ======================================================================== */ | 31 | /* ======================================================================== */ |
diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c index 35f66d4a4595..20d4fe96a81c 100644 --- a/drivers/net/forcedeth.c +++ b/drivers/net/forcedeth.c | |||
@@ -3273,6 +3273,20 @@ static void nv_link_irq(struct net_device *dev) | |||
3273 | dprintk(KERN_DEBUG "%s: link change notification done.\n", dev->name); | 3273 | dprintk(KERN_DEBUG "%s: link change notification done.\n", dev->name); |
3274 | } | 3274 | } |
3275 | 3275 | ||
3276 | static void nv_msi_workaround(struct fe_priv *np) | ||
3277 | { | ||
3278 | |||
3279 | /* Need to toggle the msi irq mask within the ethernet device, | ||
3280 | * otherwise, future interrupts will not be detected. | ||
3281 | */ | ||
3282 | if (np->msi_flags & NV_MSI_ENABLED) { | ||
3283 | u8 __iomem *base = np->base; | ||
3284 | |||
3285 | writel(0, base + NvRegMSIIrqMask); | ||
3286 | writel(NVREG_MSI_VECTOR_0_ENABLED, base + NvRegMSIIrqMask); | ||
3287 | } | ||
3288 | } | ||
3289 | |||
3276 | static irqreturn_t nv_nic_irq(int foo, void *data) | 3290 | static irqreturn_t nv_nic_irq(int foo, void *data) |
3277 | { | 3291 | { |
3278 | struct net_device *dev = (struct net_device *) data; | 3292 | struct net_device *dev = (struct net_device *) data; |
@@ -3295,6 +3309,8 @@ static irqreturn_t nv_nic_irq(int foo, void *data) | |||
3295 | if (!(events & np->irqmask)) | 3309 | if (!(events & np->irqmask)) |
3296 | break; | 3310 | break; |
3297 | 3311 | ||
3312 | nv_msi_workaround(np); | ||
3313 | |||
3298 | spin_lock(&np->lock); | 3314 | spin_lock(&np->lock); |
3299 | nv_tx_done(dev); | 3315 | nv_tx_done(dev); |
3300 | spin_unlock(&np->lock); | 3316 | spin_unlock(&np->lock); |
@@ -3410,6 +3426,8 @@ static irqreturn_t nv_nic_irq_optimized(int foo, void *data) | |||
3410 | if (!(events & np->irqmask)) | 3426 | if (!(events & np->irqmask)) |
3411 | break; | 3427 | break; |
3412 | 3428 | ||
3429 | nv_msi_workaround(np); | ||
3430 | |||
3413 | spin_lock(&np->lock); | 3431 | spin_lock(&np->lock); |
3414 | nv_tx_done_optimized(dev, TX_WORK_PER_LOOP); | 3432 | nv_tx_done_optimized(dev, TX_WORK_PER_LOOP); |
3415 | spin_unlock(&np->lock); | 3433 | spin_unlock(&np->lock); |
@@ -3750,6 +3768,8 @@ static irqreturn_t nv_nic_irq_test(int foo, void *data) | |||
3750 | if (!(events & NVREG_IRQ_TIMER)) | 3768 | if (!(events & NVREG_IRQ_TIMER)) |
3751 | return IRQ_RETVAL(0); | 3769 | return IRQ_RETVAL(0); |
3752 | 3770 | ||
3771 | nv_msi_workaround(np); | ||
3772 | |||
3753 | spin_lock(&np->lock); | 3773 | spin_lock(&np->lock); |
3754 | np->intr_test = 1; | 3774 | np->intr_test = 1; |
3755 | spin_unlock(&np->lock); | 3775 | spin_unlock(&np->lock); |
@@ -4174,12 +4194,23 @@ static int nv_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd) | |||
4174 | 4194 | ||
4175 | netif_carrier_off(dev); | 4195 | netif_carrier_off(dev); |
4176 | if (netif_running(dev)) { | 4196 | if (netif_running(dev)) { |
4197 | unsigned long flags; | ||
4198 | |||
4177 | nv_disable_irq(dev); | 4199 | nv_disable_irq(dev); |
4178 | netif_tx_lock_bh(dev); | 4200 | netif_tx_lock_bh(dev); |
4179 | spin_lock(&np->lock); | 4201 | /* with plain spinlock lockdep complains */ |
4202 | spin_lock_irqsave(&np->lock, flags); | ||
4180 | /* stop engines */ | 4203 | /* stop engines */ |
4204 | /* FIXME: | ||
4205 | * this can take some time, and interrupts are disabled | ||
4206 | * due to spin_lock_irqsave, but let's hope no daemon | ||
4207 | * is going to change the settings very often... | ||
4208 | * Worst case: | ||
4209 | * NV_RXSTOP_DELAY1MAX + NV_TXSTOP_DELAY1MAX | ||
4210 | * + some minor delays, which is up to a second approximately | ||
4211 | */ | ||
4181 | nv_stop_rxtx(dev); | 4212 | nv_stop_rxtx(dev); |
4182 | spin_unlock(&np->lock); | 4213 | spin_unlock_irqrestore(&np->lock, flags); |
4183 | netif_tx_unlock_bh(dev); | 4214 | netif_tx_unlock_bh(dev); |
4184 | } | 4215 | } |
4185 | 4216 | ||
@@ -5823,6 +5854,7 @@ static int nv_resume(struct pci_dev *pdev) | |||
5823 | writel(txreg, base + NvRegTransmitPoll); | 5854 | writel(txreg, base + NvRegTransmitPoll); |
5824 | 5855 | ||
5825 | rc = nv_open(dev); | 5856 | rc = nv_open(dev); |
5857 | nv_set_multicast(dev); | ||
5826 | out: | 5858 | out: |
5827 | return rc; | 5859 | return rc; |
5828 | } | 5860 | } |
diff --git a/drivers/net/fs_enet/fs_enet-main.c b/drivers/net/fs_enet/fs_enet-main.c index 67b4b0728fce..a5baaf59ff66 100644 --- a/drivers/net/fs_enet/fs_enet-main.c +++ b/drivers/net/fs_enet/fs_enet-main.c | |||
@@ -1093,7 +1093,7 @@ err: | |||
1093 | if (registered) | 1093 | if (registered) |
1094 | unregister_netdev(ndev); | 1094 | unregister_netdev(ndev); |
1095 | 1095 | ||
1096 | if (fep != NULL) { | 1096 | if (fep && fep->ops) { |
1097 | (*fep->ops->free_bd)(ndev); | 1097 | (*fep->ops->free_bd)(ndev); |
1098 | (*fep->ops->cleanup_data)(ndev); | 1098 | (*fep->ops->cleanup_data)(ndev); |
1099 | } | 1099 | } |
diff --git a/drivers/net/fs_enet/mac-fcc.c b/drivers/net/fs_enet/mac-fcc.c index e36321152d50..8268b3535b30 100644 --- a/drivers/net/fs_enet/mac-fcc.c +++ b/drivers/net/fs_enet/mac-fcc.c | |||
@@ -463,6 +463,9 @@ static void restart(struct net_device *dev) | |||
463 | else | 463 | else |
464 | C32(fccp, fcc_fpsmr, FCC_PSMR_FDE | FCC_PSMR_LPB); | 464 | C32(fccp, fcc_fpsmr, FCC_PSMR_FDE | FCC_PSMR_LPB); |
465 | 465 | ||
466 | /* Restore multicast and promiscuous settings */ | ||
467 | set_multicast_list(dev); | ||
468 | |||
466 | S32(fccp, fcc_gfmr, FCC_GFMR_ENR | FCC_GFMR_ENT); | 469 | S32(fccp, fcc_gfmr, FCC_GFMR_ENR | FCC_GFMR_ENT); |
467 | } | 470 | } |
468 | 471 | ||
diff --git a/drivers/net/fs_enet/mii-fec.c b/drivers/net/fs_enet/mii-fec.c index ba75efc9f5b5..f0014cfbb275 100644 --- a/drivers/net/fs_enet/mii-fec.c +++ b/drivers/net/fs_enet/mii-fec.c | |||
@@ -194,7 +194,7 @@ static int __devinit fs_enet_mdio_probe(struct of_device *ofdev, | |||
194 | 194 | ||
195 | ret = of_address_to_resource(ofdev->node, 0, &res); | 195 | ret = of_address_to_resource(ofdev->node, 0, &res); |
196 | if (ret) | 196 | if (ret) |
197 | return ret; | 197 | goto out_res; |
198 | 198 | ||
199 | snprintf(new_bus->id, MII_BUS_ID_SIZE, "%x", res.start); | 199 | snprintf(new_bus->id, MII_BUS_ID_SIZE, "%x", res.start); |
200 | 200 | ||
@@ -236,6 +236,7 @@ out_free_irqs: | |||
236 | kfree(new_bus->irq); | 236 | kfree(new_bus->irq); |
237 | out_unmap_regs: | 237 | out_unmap_regs: |
238 | iounmap(fec->fecp); | 238 | iounmap(fec->fecp); |
239 | out_res: | ||
239 | out_fec: | 240 | out_fec: |
240 | kfree(fec); | 241 | kfree(fec); |
241 | out_mii: | 242 | out_mii: |
diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c index 587afe7be689..25bdd0832df5 100644 --- a/drivers/net/gianfar.c +++ b/drivers/net/gianfar.c | |||
@@ -138,6 +138,7 @@ static int gfar_poll(struct napi_struct *napi, int budget); | |||
138 | static void gfar_netpoll(struct net_device *dev); | 138 | static void gfar_netpoll(struct net_device *dev); |
139 | #endif | 139 | #endif |
140 | int gfar_clean_rx_ring(struct net_device *dev, int rx_work_limit); | 140 | int gfar_clean_rx_ring(struct net_device *dev, int rx_work_limit); |
141 | static int gfar_clean_tx_ring(struct net_device *dev); | ||
141 | static int gfar_process_frame(struct net_device *dev, struct sk_buff *skb, int length); | 142 | static int gfar_process_frame(struct net_device *dev, struct sk_buff *skb, int length); |
142 | static void gfar_vlan_rx_register(struct net_device *netdev, | 143 | static void gfar_vlan_rx_register(struct net_device *netdev, |
143 | struct vlan_group *grp); | 144 | struct vlan_group *grp); |
@@ -634,6 +635,8 @@ static void free_skb_resources(struct gfar_private *priv) | |||
634 | dev_kfree_skb_any(priv->tx_skbuff[i]); | 635 | dev_kfree_skb_any(priv->tx_skbuff[i]); |
635 | priv->tx_skbuff[i] = NULL; | 636 | priv->tx_skbuff[i] = NULL; |
636 | } | 637 | } |
638 | |||
639 | txbdp++; | ||
637 | } | 640 | } |
638 | 641 | ||
639 | kfree(priv->tx_skbuff); | 642 | kfree(priv->tx_skbuff); |
@@ -1141,7 +1144,7 @@ static int gfar_close(struct net_device *dev) | |||
1141 | } | 1144 | } |
1142 | 1145 | ||
1143 | /* Changes the mac address if the controller is not running. */ | 1146 | /* Changes the mac address if the controller is not running. */ |
1144 | int gfar_set_mac_address(struct net_device *dev) | 1147 | static int gfar_set_mac_address(struct net_device *dev) |
1145 | { | 1148 | { |
1146 | gfar_set_mac_for_addr(dev, 0, dev->dev_addr); | 1149 | gfar_set_mac_for_addr(dev, 0, dev->dev_addr); |
1147 | 1150 | ||
@@ -1260,7 +1263,7 @@ static void gfar_timeout(struct net_device *dev) | |||
1260 | } | 1263 | } |
1261 | 1264 | ||
1262 | /* Interrupt Handler for Transmit complete */ | 1265 | /* Interrupt Handler for Transmit complete */ |
1263 | int gfar_clean_tx_ring(struct net_device *dev) | 1266 | static int gfar_clean_tx_ring(struct net_device *dev) |
1264 | { | 1267 | { |
1265 | struct txbd8 *bdp; | 1268 | struct txbd8 *bdp; |
1266 | struct gfar_private *priv = netdev_priv(dev); | 1269 | struct gfar_private *priv = netdev_priv(dev); |
diff --git a/drivers/net/gianfar.h b/drivers/net/gianfar.h index fd487be3993e..27f37c81e52c 100644 --- a/drivers/net/gianfar.h +++ b/drivers/net/gianfar.h | |||
@@ -782,5 +782,8 @@ extern void gfar_halt(struct net_device *dev); | |||
782 | extern void gfar_phy_test(struct mii_bus *bus, struct phy_device *phydev, | 782 | extern void gfar_phy_test(struct mii_bus *bus, struct phy_device *phydev, |
783 | int enable, u32 regnum, u32 read); | 783 | int enable, u32 regnum, u32 read); |
784 | void gfar_init_sysfs(struct net_device *dev); | 784 | void gfar_init_sysfs(struct net_device *dev); |
785 | int gfar_local_mdio_write(struct gfar_mii __iomem *regs, int mii_id, | ||
786 | int regnum, u16 value); | ||
787 | int gfar_local_mdio_read(struct gfar_mii __iomem *regs, int mii_id, int regnum); | ||
785 | 788 | ||
786 | #endif /* __GIANFAR_H */ | 789 | #endif /* __GIANFAR_H */ |
diff --git a/drivers/net/gianfar_sysfs.c b/drivers/net/gianfar_sysfs.c index 230878b94190..5116f68e01b9 100644 --- a/drivers/net/gianfar_sysfs.c +++ b/drivers/net/gianfar_sysfs.c | |||
@@ -103,10 +103,10 @@ static ssize_t gfar_set_rx_stash_size(struct device *dev, | |||
103 | 103 | ||
104 | spin_lock_irqsave(&priv->rxlock, flags); | 104 | spin_lock_irqsave(&priv->rxlock, flags); |
105 | if (length > priv->rx_buffer_size) | 105 | if (length > priv->rx_buffer_size) |
106 | return count; | 106 | goto out; |
107 | 107 | ||
108 | if (length == priv->rx_stash_size) | 108 | if (length == priv->rx_stash_size) |
109 | return count; | 109 | goto out; |
110 | 110 | ||
111 | priv->rx_stash_size = length; | 111 | priv->rx_stash_size = length; |
112 | 112 | ||
@@ -125,6 +125,7 @@ static ssize_t gfar_set_rx_stash_size(struct device *dev, | |||
125 | 125 | ||
126 | gfar_write(&priv->regs->attr, temp); | 126 | gfar_write(&priv->regs->attr, temp); |
127 | 127 | ||
128 | out: | ||
128 | spin_unlock_irqrestore(&priv->rxlock, flags); | 129 | spin_unlock_irqrestore(&priv->rxlock, flags); |
129 | 130 | ||
130 | return count; | 131 | return count; |
@@ -154,10 +155,10 @@ static ssize_t gfar_set_rx_stash_index(struct device *dev, | |||
154 | 155 | ||
155 | spin_lock_irqsave(&priv->rxlock, flags); | 156 | spin_lock_irqsave(&priv->rxlock, flags); |
156 | if (index > priv->rx_stash_size) | 157 | if (index > priv->rx_stash_size) |
157 | return count; | 158 | goto out; |
158 | 159 | ||
159 | if (index == priv->rx_stash_index) | 160 | if (index == priv->rx_stash_index) |
160 | return count; | 161 | goto out; |
161 | 162 | ||
162 | priv->rx_stash_index = index; | 163 | priv->rx_stash_index = index; |
163 | 164 | ||
@@ -166,6 +167,7 @@ static ssize_t gfar_set_rx_stash_index(struct device *dev, | |||
166 | temp |= ATTRELI_EI(index); | 167 | temp |= ATTRELI_EI(index); |
167 | gfar_write(&priv->regs->attreli, flags); | 168 | gfar_write(&priv->regs->attreli, flags); |
168 | 169 | ||
170 | out: | ||
169 | spin_unlock_irqrestore(&priv->rxlock, flags); | 171 | spin_unlock_irqrestore(&priv->rxlock, flags); |
170 | 172 | ||
171 | return count; | 173 | return count; |
diff --git a/drivers/net/hamradio/baycom_epp.c b/drivers/net/hamradio/baycom_epp.c index dde9c7e6408a..00bc7fbb6b37 100644 --- a/drivers/net/hamradio/baycom_epp.c +++ b/drivers/net/hamradio/baycom_epp.c | |||
@@ -959,7 +959,7 @@ static int epp_close(struct net_device *dev) | |||
959 | unsigned char tmp[1]; | 959 | unsigned char tmp[1]; |
960 | 960 | ||
961 | bc->work_running = 0; | 961 | bc->work_running = 0; |
962 | flush_scheduled_work(); | 962 | cancel_delayed_work_sync(&bc->run_work); |
963 | bc->stat = EPP_DCDBIT; | 963 | bc->stat = EPP_DCDBIT; |
964 | tmp[0] = 0; | 964 | tmp[0] = 0; |
965 | pp->ops->epp_write_addr(pp, tmp, 1, 0); | 965 | pp->ops->epp_write_addr(pp, tmp, 1, 0); |
diff --git a/drivers/net/hamradio/dmascc.c b/drivers/net/hamradio/dmascc.c index 0b94833e23f7..e8cfadefa4b6 100644 --- a/drivers/net/hamradio/dmascc.c +++ b/drivers/net/hamradio/dmascc.c | |||
@@ -1077,8 +1077,6 @@ static inline void rx_off(struct scc_priv *priv) | |||
1077 | 1077 | ||
1078 | static void start_timer(struct scc_priv *priv, int t, int r15) | 1078 | static void start_timer(struct scc_priv *priv, int t, int r15) |
1079 | { | 1079 | { |
1080 | unsigned long flags; | ||
1081 | |||
1082 | outb(priv->tmr_mode, priv->tmr_ctrl); | 1080 | outb(priv->tmr_mode, priv->tmr_ctrl); |
1083 | if (t == 0) { | 1081 | if (t == 0) { |
1084 | tm_isr(priv); | 1082 | tm_isr(priv); |
diff --git a/drivers/net/hamradio/scc.c b/drivers/net/hamradio/scc.c index f90515935833..45ae9d1191d7 100644 --- a/drivers/net/hamradio/scc.c +++ b/drivers/net/hamradio/scc.c | |||
@@ -1340,9 +1340,10 @@ static unsigned int scc_set_param(struct scc_channel *scc, unsigned int cmd, uns | |||
1340 | case PARAM_RTS: | 1340 | case PARAM_RTS: |
1341 | if ( !(scc->wreg[R5] & RTS) ) | 1341 | if ( !(scc->wreg[R5] & RTS) ) |
1342 | { | 1342 | { |
1343 | if (arg != TX_OFF) | 1343 | if (arg != TX_OFF) { |
1344 | scc_key_trx(scc, TX_ON); | 1344 | scc_key_trx(scc, TX_ON); |
1345 | scc_start_tx_timer(scc, t_txdelay, scc->kiss.txdelay); | 1345 | scc_start_tx_timer(scc, t_txdelay, scc->kiss.txdelay); |
1346 | } | ||
1346 | } else { | 1347 | } else { |
1347 | if (arg == TX_OFF) | 1348 | if (arg == TX_OFF) |
1348 | { | 1349 | { |
diff --git a/drivers/net/ibm_newemac/Kconfig b/drivers/net/ibm_newemac/Kconfig index 0d3e7380bad0..70a3272ee998 100644 --- a/drivers/net/ibm_newemac/Kconfig +++ b/drivers/net/ibm_newemac/Kconfig | |||
@@ -1,6 +1,7 @@ | |||
1 | config IBM_NEW_EMAC | 1 | config IBM_NEW_EMAC |
2 | tristate "IBM EMAC Ethernet support" | 2 | tristate "IBM EMAC Ethernet support" |
3 | depends on PPC_DCR && PPC_MERGE | 3 | depends on PPC_DCR && PPC_MERGE |
4 | select CRC32 | ||
4 | help | 5 | help |
5 | This driver supports the IBM EMAC family of Ethernet controllers | 6 | This driver supports the IBM EMAC family of Ethernet controllers |
6 | typically found on 4xx embedded PowerPC chips, but also on the | 7 | typically found on 4xx embedded PowerPC chips, but also on the |
diff --git a/drivers/net/ibm_newemac/core.c b/drivers/net/ibm_newemac/core.c index 5d2108c5ac7c..babc79ad490b 100644 --- a/drivers/net/ibm_newemac/core.c +++ b/drivers/net/ibm_newemac/core.c | |||
@@ -1636,6 +1636,12 @@ static int emac_poll_rx(void *param, int budget) | |||
1636 | goto next; | 1636 | goto next; |
1637 | } | 1637 | } |
1638 | 1638 | ||
1639 | if (len < ETH_HLEN) { | ||
1640 | ++dev->estats.rx_dropped_stack; | ||
1641 | emac_recycle_rx_skb(dev, slot, len); | ||
1642 | goto next; | ||
1643 | } | ||
1644 | |||
1639 | if (len && len < EMAC_RX_COPY_THRESH) { | 1645 | if (len && len < EMAC_RX_COPY_THRESH) { |
1640 | struct sk_buff *copy_skb = | 1646 | struct sk_buff *copy_skb = |
1641 | alloc_skb(len + EMAC_RX_SKB_HEADROOM + 2, GFP_ATOMIC); | 1647 | alloc_skb(len + EMAC_RX_SKB_HEADROOM + 2, GFP_ATOMIC); |
@@ -2719,6 +2725,8 @@ static int __devinit emac_probe(struct of_device *ofdev, | |||
2719 | /* Clean rings */ | 2725 | /* Clean rings */ |
2720 | memset(dev->tx_desc, 0, NUM_TX_BUFF * sizeof(struct mal_descriptor)); | 2726 | memset(dev->tx_desc, 0, NUM_TX_BUFF * sizeof(struct mal_descriptor)); |
2721 | memset(dev->rx_desc, 0, NUM_RX_BUFF * sizeof(struct mal_descriptor)); | 2727 | memset(dev->rx_desc, 0, NUM_RX_BUFF * sizeof(struct mal_descriptor)); |
2728 | memset(dev->tx_skb, 0, NUM_TX_BUFF * sizeof(struct sk_buff *)); | ||
2729 | memset(dev->rx_skb, 0, NUM_RX_BUFF * sizeof(struct sk_buff *)); | ||
2722 | 2730 | ||
2723 | /* Attach to ZMII, if needed */ | 2731 | /* Attach to ZMII, if needed */ |
2724 | if (emac_has_feature(dev, EMAC_FTR_HAS_ZMII) && | 2732 | if (emac_has_feature(dev, EMAC_FTR_HAS_ZMII) && |
diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c index ae398f04c7b4..e79a26a886c8 100644 --- a/drivers/net/igb/igb_main.c +++ b/drivers/net/igb/igb_main.c | |||
@@ -718,7 +718,8 @@ void igb_down(struct igb_adapter *adapter) | |||
718 | adapter->link_speed = 0; | 718 | adapter->link_speed = 0; |
719 | adapter->link_duplex = 0; | 719 | adapter->link_duplex = 0; |
720 | 720 | ||
721 | igb_reset(adapter); | 721 | if (!pci_channel_offline(adapter->pdev)) |
722 | igb_reset(adapter); | ||
722 | igb_clean_all_tx_rings(adapter); | 723 | igb_clean_all_tx_rings(adapter); |
723 | igb_clean_all_rx_rings(adapter); | 724 | igb_clean_all_rx_rings(adapter); |
724 | } | 725 | } |
diff --git a/drivers/net/ipg.c b/drivers/net/ipg.c index 9b358f61ed7f..2c03f4e2ccc4 100644 --- a/drivers/net/ipg.c +++ b/drivers/net/ipg.c | |||
@@ -577,12 +577,12 @@ static void ipg_nic_set_multicast_list(struct net_device *dev) | |||
577 | /* NIC to be configured in promiscuous mode. */ | 577 | /* NIC to be configured in promiscuous mode. */ |
578 | receivemode = IPG_RM_RECEIVEALLFRAMES; | 578 | receivemode = IPG_RM_RECEIVEALLFRAMES; |
579 | } else if ((dev->flags & IFF_ALLMULTI) || | 579 | } else if ((dev->flags & IFF_ALLMULTI) || |
580 | (dev->flags & IFF_MULTICAST & | 580 | ((dev->flags & IFF_MULTICAST) && |
581 | (dev->mc_count > IPG_MULTICAST_HASHTABLE_SIZE))) { | 581 | (dev->mc_count > IPG_MULTICAST_HASHTABLE_SIZE))) { |
582 | /* NIC to be configured to receive all multicast | 582 | /* NIC to be configured to receive all multicast |
583 | * frames. */ | 583 | * frames. */ |
584 | receivemode |= IPG_RM_RECEIVEMULTICAST; | 584 | receivemode |= IPG_RM_RECEIVEMULTICAST; |
585 | } else if (dev->flags & IFF_MULTICAST & (dev->mc_count > 0)) { | 585 | } else if ((dev->flags & IFF_MULTICAST) && (dev->mc_count > 0)) { |
586 | /* NIC to be configured to receive selected | 586 | /* NIC to be configured to receive selected |
587 | * multicast addresses. */ | 587 | * multicast addresses. */ |
588 | receivemode |= IPG_RM_RECEIVEMULTICASTHASH; | 588 | receivemode |= IPG_RM_RECEIVEMULTICASTHASH; |
@@ -1271,7 +1271,7 @@ static void ipg_nic_rx_with_end(struct net_device *dev, | |||
1271 | 1271 | ||
1272 | framelen = le64_to_cpu(rxfd->rfs) & IPG_RFS_RXFRAMELEN; | 1272 | framelen = le64_to_cpu(rxfd->rfs) & IPG_RFS_RXFRAMELEN; |
1273 | 1273 | ||
1274 | endframeLen = framelen - jumbo->current_size; | 1274 | endframelen = framelen - jumbo->current_size; |
1275 | /* | 1275 | /* |
1276 | if (framelen > IPG_RXFRAG_SIZE) | 1276 | if (framelen > IPG_RXFRAG_SIZE) |
1277 | framelen=IPG_RXFRAG_SIZE; | 1277 | framelen=IPG_RXFRAG_SIZE; |
@@ -1279,8 +1279,8 @@ static void ipg_nic_rx_with_end(struct net_device *dev, | |||
1279 | if (framelen > IPG_RXSUPPORT_SIZE) | 1279 | if (framelen > IPG_RXSUPPORT_SIZE) |
1280 | dev_kfree_skb_irq(jumbo->skb); | 1280 | dev_kfree_skb_irq(jumbo->skb); |
1281 | else { | 1281 | else { |
1282 | memcpy(skb_put(jumbo->skb, endframeLen), | 1282 | memcpy(skb_put(jumbo->skb, endframelen), |
1283 | skb->data, endframeLen); | 1283 | skb->data, endframelen); |
1284 | 1284 | ||
1285 | jumbo->skb->protocol = | 1285 | jumbo->skb->protocol = |
1286 | eth_type_trans(jumbo->skb, dev); | 1286 | eth_type_trans(jumbo->skb, dev); |
@@ -1352,16 +1352,16 @@ static int ipg_nic_rx(struct net_device *dev) | |||
1352 | 1352 | ||
1353 | switch (ipg_nic_rx_check_frame_type(dev)) { | 1353 | switch (ipg_nic_rx_check_frame_type(dev)) { |
1354 | case FRAME_WITH_START_WITH_END: | 1354 | case FRAME_WITH_START_WITH_END: |
1355 | ipg_nic_rx_with_start_and_end(dev, tp, rxfd, entry); | 1355 | ipg_nic_rx_with_start_and_end(dev, sp, rxfd, entry); |
1356 | break; | 1356 | break; |
1357 | case FRAME_WITH_START: | 1357 | case FRAME_WITH_START: |
1358 | ipg_nic_rx_with_start(dev, tp, rxfd, entry); | 1358 | ipg_nic_rx_with_start(dev, sp, rxfd, entry); |
1359 | break; | 1359 | break; |
1360 | case FRAME_WITH_END: | 1360 | case FRAME_WITH_END: |
1361 | ipg_nic_rx_with_end(dev, tp, rxfd, entry); | 1361 | ipg_nic_rx_with_end(dev, sp, rxfd, entry); |
1362 | break; | 1362 | break; |
1363 | case FRAME_NO_START_NO_END: | 1363 | case FRAME_NO_START_NO_END: |
1364 | ipg_nic_rx_no_start_no_end(dev, tp, rxfd, entry); | 1364 | ipg_nic_rx_no_start_no_end(dev, sp, rxfd, entry); |
1365 | break; | 1365 | break; |
1366 | } | 1366 | } |
1367 | } | 1367 | } |
@@ -1808,7 +1808,7 @@ static int ipg_nic_open(struct net_device *dev) | |||
1808 | /* initialize JUMBO Frame control variable */ | 1808 | /* initialize JUMBO Frame control variable */ |
1809 | sp->jumbo.found_start = 0; | 1809 | sp->jumbo.found_start = 0; |
1810 | sp->jumbo.current_size = 0; | 1810 | sp->jumbo.current_size = 0; |
1811 | sp->jumbo.skb = 0; | 1811 | sp->jumbo.skb = NULL; |
1812 | dev->mtu = IPG_TXFRAG_SIZE; | 1812 | dev->mtu = IPG_TXFRAG_SIZE; |
1813 | #endif | 1813 | #endif |
1814 | 1814 | ||
diff --git a/drivers/net/irda/Kconfig b/drivers/net/irda/Kconfig index ce816ba9c40d..e6317557a531 100644 --- a/drivers/net/irda/Kconfig +++ b/drivers/net/irda/Kconfig | |||
@@ -329,6 +329,7 @@ config PXA_FICP | |||
329 | config MCS_FIR | 329 | config MCS_FIR |
330 | tristate "MosChip MCS7780 IrDA-USB dongle" | 330 | tristate "MosChip MCS7780 IrDA-USB dongle" |
331 | depends on IRDA && USB && EXPERIMENTAL | 331 | depends on IRDA && USB && EXPERIMENTAL |
332 | select CRC32 | ||
332 | help | 333 | help |
333 | Say Y or M here if you want to build support for the MosChip | 334 | Say Y or M here if you want to build support for the MosChip |
334 | MCS7780 IrDA-USB bridge device driver. | 335 | MCS7780 IrDA-USB bridge device driver. |
diff --git a/drivers/net/irda/irda-usb.c b/drivers/net/irda/irda-usb.c index 9081234ab458..6f50ed7b183f 100644 --- a/drivers/net/irda/irda-usb.c +++ b/drivers/net/irda/irda-usb.c | |||
@@ -1120,7 +1120,7 @@ static int stir421x_patch_device(struct irda_usb_cb *self) | |||
1120 | } | 1120 | } |
1121 | } | 1121 | } |
1122 | 1122 | ||
1123 | if (self->usbdev->descriptor.bcdDevice == fw_version) { | 1123 | if (self->usbdev->descriptor.bcdDevice == cpu_to_le16(fw_version)) { |
1124 | /* | 1124 | /* |
1125 | * If we're here, we've found a correct patch | 1125 | * If we're here, we've found a correct patch |
1126 | * The actual image starts after the "STMP" keyword | 1126 | * The actual image starts after the "STMP" keyword |
diff --git a/drivers/net/irda/irda-usb.h b/drivers/net/irda/irda-usb.h index e846c38224a3..a0ca9c1fe196 100644 --- a/drivers/net/irda/irda-usb.h +++ b/drivers/net/irda/irda-usb.h | |||
@@ -117,11 +117,11 @@ | |||
117 | struct irda_class_desc { | 117 | struct irda_class_desc { |
118 | __u8 bLength; | 118 | __u8 bLength; |
119 | __u8 bDescriptorType; | 119 | __u8 bDescriptorType; |
120 | __u16 bcdSpecRevision; | 120 | __le16 bcdSpecRevision; |
121 | __u8 bmDataSize; | 121 | __u8 bmDataSize; |
122 | __u8 bmWindowSize; | 122 | __u8 bmWindowSize; |
123 | __u8 bmMinTurnaroundTime; | 123 | __u8 bmMinTurnaroundTime; |
124 | __u16 wBaudRate; | 124 | __le16 wBaudRate; |
125 | __u8 bmAdditionalBOFs; | 125 | __u8 bmAdditionalBOFs; |
126 | __u8 bIrdaRateSniff; | 126 | __u8 bIrdaRateSniff; |
127 | __u8 bMaxUnicastList; | 127 | __u8 bMaxUnicastList; |
diff --git a/drivers/net/irda/nsc-ircc.c b/drivers/net/irda/nsc-ircc.c index a873d2b315ca..effc1ce8179a 100644 --- a/drivers/net/irda/nsc-ircc.c +++ b/drivers/net/irda/nsc-ircc.c | |||
@@ -100,7 +100,9 @@ static int nsc_ircc_probe_39x(nsc_chip_t *chip, chipio_t *info); | |||
100 | static int nsc_ircc_init_108(nsc_chip_t *chip, chipio_t *info); | 100 | static int nsc_ircc_init_108(nsc_chip_t *chip, chipio_t *info); |
101 | static int nsc_ircc_init_338(nsc_chip_t *chip, chipio_t *info); | 101 | static int nsc_ircc_init_338(nsc_chip_t *chip, chipio_t *info); |
102 | static int nsc_ircc_init_39x(nsc_chip_t *chip, chipio_t *info); | 102 | static int nsc_ircc_init_39x(nsc_chip_t *chip, chipio_t *info); |
103 | #ifdef CONFIG_PNP | ||
103 | static int nsc_ircc_pnp_probe(struct pnp_dev *dev, const struct pnp_device_id *id); | 104 | static int nsc_ircc_pnp_probe(struct pnp_dev *dev, const struct pnp_device_id *id); |
105 | #endif | ||
104 | 106 | ||
105 | /* These are the known NSC chips */ | 107 | /* These are the known NSC chips */ |
106 | static nsc_chip_t chips[] = { | 108 | static nsc_chip_t chips[] = { |
@@ -150,15 +152,18 @@ static chipio_t pnp_info; | |||
150 | static const struct pnp_device_id nsc_ircc_pnp_table[] = { | 152 | static const struct pnp_device_id nsc_ircc_pnp_table[] = { |
151 | { .id = "NSC6001", .driver_data = 0 }, | 153 | { .id = "NSC6001", .driver_data = 0 }, |
152 | { .id = "IBM0071", .driver_data = 0 }, | 154 | { .id = "IBM0071", .driver_data = 0 }, |
155 | { .id = "HWPC224", .driver_data = 0 }, | ||
153 | { } | 156 | { } |
154 | }; | 157 | }; |
155 | 158 | ||
156 | MODULE_DEVICE_TABLE(pnp, nsc_ircc_pnp_table); | 159 | MODULE_DEVICE_TABLE(pnp, nsc_ircc_pnp_table); |
157 | 160 | ||
158 | static struct pnp_driver nsc_ircc_pnp_driver = { | 161 | static struct pnp_driver nsc_ircc_pnp_driver = { |
162 | #ifdef CONFIG_PNP | ||
159 | .name = "nsc-ircc", | 163 | .name = "nsc-ircc", |
160 | .id_table = nsc_ircc_pnp_table, | 164 | .id_table = nsc_ircc_pnp_table, |
161 | .probe = nsc_ircc_pnp_probe, | 165 | .probe = nsc_ircc_pnp_probe, |
166 | #endif | ||
162 | }; | 167 | }; |
163 | 168 | ||
164 | /* Some prototypes */ | 169 | /* Some prototypes */ |
@@ -916,6 +921,7 @@ static int nsc_ircc_probe_39x(nsc_chip_t *chip, chipio_t *info) | |||
916 | return 0; | 921 | return 0; |
917 | } | 922 | } |
918 | 923 | ||
924 | #ifdef CONFIG_PNP | ||
919 | /* PNP probing */ | 925 | /* PNP probing */ |
920 | static int nsc_ircc_pnp_probe(struct pnp_dev *dev, const struct pnp_device_id *id) | 926 | static int nsc_ircc_pnp_probe(struct pnp_dev *dev, const struct pnp_device_id *id) |
921 | { | 927 | { |
@@ -952,6 +958,7 @@ static int nsc_ircc_pnp_probe(struct pnp_dev *dev, const struct pnp_device_id *i | |||
952 | 958 | ||
953 | return 0; | 959 | return 0; |
954 | } | 960 | } |
961 | #endif | ||
955 | 962 | ||
956 | /* | 963 | /* |
957 | * Function nsc_ircc_setup (info) | 964 | * Function nsc_ircc_setup (info) |
diff --git a/drivers/net/irda/smsc-ircc2.c b/drivers/net/irda/smsc-ircc2.c index 1f26da761e9f..cfe0194fef71 100644 --- a/drivers/net/irda/smsc-ircc2.c +++ b/drivers/net/irda/smsc-ircc2.c | |||
@@ -376,6 +376,7 @@ MODULE_DEVICE_TABLE(pnp, smsc_ircc_pnp_table); | |||
376 | 376 | ||
377 | static int pnp_driver_registered; | 377 | static int pnp_driver_registered; |
378 | 378 | ||
379 | #ifdef CONFIG_PNP | ||
379 | static int __init smsc_ircc_pnp_probe(struct pnp_dev *dev, | 380 | static int __init smsc_ircc_pnp_probe(struct pnp_dev *dev, |
380 | const struct pnp_device_id *dev_id) | 381 | const struct pnp_device_id *dev_id) |
381 | { | 382 | { |
@@ -402,7 +403,9 @@ static struct pnp_driver smsc_ircc_pnp_driver = { | |||
402 | .id_table = smsc_ircc_pnp_table, | 403 | .id_table = smsc_ircc_pnp_table, |
403 | .probe = smsc_ircc_pnp_probe, | 404 | .probe = smsc_ircc_pnp_probe, |
404 | }; | 405 | }; |
405 | 406 | #else /* CONFIG_PNP */ | |
407 | static struct pnp_driver smsc_ircc_pnp_driver; | ||
408 | #endif | ||
406 | 409 | ||
407 | /******************************************************************************* | 410 | /******************************************************************************* |
408 | * | 411 | * |
diff --git a/drivers/net/irda/via-ircc.c b/drivers/net/irda/via-ircc.c index 58e128784585..04ad3573b159 100644 --- a/drivers/net/irda/via-ircc.c +++ b/drivers/net/irda/via-ircc.c | |||
@@ -1546,6 +1546,7 @@ static int via_ircc_net_open(struct net_device *dev) | |||
1546 | IRDA_WARNING("%s, unable to allocate dma2=%d\n", | 1546 | IRDA_WARNING("%s, unable to allocate dma2=%d\n", |
1547 | driver_name, self->io.dma2); | 1547 | driver_name, self->io.dma2); |
1548 | free_irq(self->io.irq, self); | 1548 | free_irq(self->io.irq, self); |
1549 | free_dma(self->io.dma); | ||
1549 | return -EAGAIN; | 1550 | return -EAGAIN; |
1550 | } | 1551 | } |
1551 | } | 1552 | } |
@@ -1606,6 +1607,8 @@ static int via_ircc_net_close(struct net_device *dev) | |||
1606 | EnAllInt(iobase, OFF); | 1607 | EnAllInt(iobase, OFF); |
1607 | free_irq(self->io.irq, dev); | 1608 | free_irq(self->io.irq, dev); |
1608 | free_dma(self->io.dma); | 1609 | free_dma(self->io.dma); |
1610 | if (self->io.dma2 != self->io.dma) | ||
1611 | free_dma(self->io.dma2); | ||
1609 | 1612 | ||
1610 | return 0; | 1613 | return 0; |
1611 | } | 1614 | } |
diff --git a/drivers/net/ixgbe/ixgbe_82598.c b/drivers/net/ixgbe/ixgbe_82598.c index 6321b059ce13..2f38e847e2cd 100644 --- a/drivers/net/ixgbe/ixgbe_82598.c +++ b/drivers/net/ixgbe/ixgbe_82598.c | |||
@@ -58,8 +58,8 @@ static s32 ixgbe_reset_hw_82598(struct ixgbe_hw *hw); | |||
58 | 58 | ||
59 | static s32 ixgbe_get_invariants_82598(struct ixgbe_hw *hw) | 59 | static s32 ixgbe_get_invariants_82598(struct ixgbe_hw *hw) |
60 | { | 60 | { |
61 | hw->mac.num_rx_queues = IXGBE_82598_MAX_TX_QUEUES; | 61 | hw->mac.num_rx_queues = IXGBE_82598_MAX_RX_QUEUES; |
62 | hw->mac.num_tx_queues = IXGBE_82598_MAX_RX_QUEUES; | 62 | hw->mac.num_tx_queues = IXGBE_82598_MAX_TX_QUEUES; |
63 | hw->mac.num_rx_addrs = IXGBE_82598_RAR_ENTRIES; | 63 | hw->mac.num_rx_addrs = IXGBE_82598_RAR_ENTRIES; |
64 | 64 | ||
65 | /* PHY ops are filled in by default properly for Fiber only */ | 65 | /* PHY ops are filled in by default properly for Fiber only */ |
diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index 7b859220c255..8f0460901153 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c | |||
@@ -1969,7 +1969,8 @@ void ixgbe_down(struct ixgbe_adapter *adapter) | |||
1969 | netif_carrier_off(netdev); | 1969 | netif_carrier_off(netdev); |
1970 | netif_stop_queue(netdev); | 1970 | netif_stop_queue(netdev); |
1971 | 1971 | ||
1972 | ixgbe_reset(adapter); | 1972 | if (!pci_channel_offline(adapter->pdev)) |
1973 | ixgbe_reset(adapter); | ||
1973 | ixgbe_clean_all_tx_rings(adapter); | 1974 | ixgbe_clean_all_tx_rings(adapter); |
1974 | ixgbe_clean_all_rx_rings(adapter); | 1975 | ixgbe_clean_all_rx_rings(adapter); |
1975 | 1976 | ||
diff --git a/drivers/net/mac89x0.c b/drivers/net/mac89x0.c index 2a66e5b7cebc..4ce8afd481c3 100644 --- a/drivers/net/mac89x0.c +++ b/drivers/net/mac89x0.c | |||
@@ -183,6 +183,9 @@ struct net_device * __init mac89x0_probe(int unit) | |||
183 | int err = -ENODEV; | 183 | int err = -ENODEV; |
184 | DECLARE_MAC_BUF(mac); | 184 | DECLARE_MAC_BUF(mac); |
185 | 185 | ||
186 | if (!MACH_IS_MAC) | ||
187 | return ERR_PTR(-ENODEV); | ||
188 | |||
186 | dev = alloc_etherdev(sizeof(struct net_local)); | 189 | dev = alloc_etherdev(sizeof(struct net_local)); |
187 | if (!dev) | 190 | if (!dev) |
188 | return ERR_PTR(-ENOMEM); | 191 | return ERR_PTR(-ENOMEM); |
diff --git a/drivers/net/macmace.c b/drivers/net/macmace.c index 18770527df99..51ad3765e075 100644 --- a/drivers/net/macmace.c +++ b/drivers/net/macmace.c | |||
@@ -781,6 +781,9 @@ static int __init mac_mace_init_module(void) | |||
781 | { | 781 | { |
782 | int err; | 782 | int err; |
783 | 783 | ||
784 | if (!MACH_IS_MAC) | ||
785 | return -ENODEV; | ||
786 | |||
784 | if ((err = platform_driver_register(&mac_mace_driver))) { | 787 | if ((err = platform_driver_register(&mac_mace_driver))) { |
785 | printk(KERN_ERR "Driver registration failed\n"); | 788 | printk(KERN_ERR "Driver registration failed\n"); |
786 | return err; | 789 | return err; |
diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c index 2056cfc624dc..c36a03ae9bfb 100644 --- a/drivers/net/macvlan.c +++ b/drivers/net/macvlan.c | |||
@@ -450,7 +450,7 @@ static void macvlan_dellink(struct net_device *dev) | |||
450 | unregister_netdevice(dev); | 450 | unregister_netdevice(dev); |
451 | 451 | ||
452 | if (list_empty(&port->vlans)) | 452 | if (list_empty(&port->vlans)) |
453 | macvlan_port_destroy(dev); | 453 | macvlan_port_destroy(port->dev); |
454 | } | 454 | } |
455 | 455 | ||
456 | static struct rtnl_link_ops macvlan_link_ops __read_mostly = { | 456 | static struct rtnl_link_ops macvlan_link_ops __read_mostly = { |
diff --git a/drivers/net/mlx4/mr.c b/drivers/net/mlx4/mr.c index cb46446b2691..03a9abcce524 100644 --- a/drivers/net/mlx4/mr.c +++ b/drivers/net/mlx4/mr.c | |||
@@ -551,7 +551,7 @@ int mlx4_fmr_alloc(struct mlx4_dev *dev, u32 pd, u32 access, int max_pages, | |||
551 | u64 mtt_seg; | 551 | u64 mtt_seg; |
552 | int err = -ENOMEM; | 552 | int err = -ENOMEM; |
553 | 553 | ||
554 | if (page_shift < 12 || page_shift >= 32) | 554 | if (page_shift < (ffs(dev->caps.page_size_cap) - 1) || page_shift >= 32) |
555 | return -EINVAL; | 555 | return -EINVAL; |
556 | 556 | ||
557 | /* All MTTs must fit in the same page */ | 557 | /* All MTTs must fit in the same page */ |
diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c index 381b36e5f64c..b7915cdcc6a5 100644 --- a/drivers/net/mv643xx_eth.c +++ b/drivers/net/mv643xx_eth.c | |||
@@ -91,6 +91,11 @@ | |||
91 | */ | 91 | */ |
92 | #define PHY_ADDR_REG 0x0000 | 92 | #define PHY_ADDR_REG 0x0000 |
93 | #define SMI_REG 0x0004 | 93 | #define SMI_REG 0x0004 |
94 | #define WINDOW_BASE(i) (0x0200 + ((i) << 3)) | ||
95 | #define WINDOW_SIZE(i) (0x0204 + ((i) << 3)) | ||
96 | #define WINDOW_REMAP_HIGH(i) (0x0280 + ((i) << 2)) | ||
97 | #define WINDOW_BAR_ENABLE 0x0290 | ||
98 | #define WINDOW_PROTECT(i) (0x0294 + ((i) << 4)) | ||
94 | 99 | ||
95 | /* | 100 | /* |
96 | * Per-port registers. | 101 | * Per-port registers. |
@@ -507,9 +512,23 @@ struct mv643xx_mib_counters { | |||
507 | u32 late_collision; | 512 | u32 late_collision; |
508 | }; | 513 | }; |
509 | 514 | ||
515 | struct mv643xx_shared_private { | ||
516 | void __iomem *eth_base; | ||
517 | |||
518 | /* used to protect SMI_REG, which is shared across ports */ | ||
519 | spinlock_t phy_lock; | ||
520 | |||
521 | u32 win_protect; | ||
522 | |||
523 | unsigned int t_clk; | ||
524 | }; | ||
525 | |||
510 | struct mv643xx_private { | 526 | struct mv643xx_private { |
527 | struct mv643xx_shared_private *shared; | ||
511 | int port_num; /* User Ethernet port number */ | 528 | int port_num; /* User Ethernet port number */ |
512 | 529 | ||
530 | struct mv643xx_shared_private *shared_smi; | ||
531 | |||
513 | u32 rx_sram_addr; /* Base address of rx sram area */ | 532 | u32 rx_sram_addr; /* Base address of rx sram area */ |
514 | u32 rx_sram_size; /* Size of rx sram area */ | 533 | u32 rx_sram_size; /* Size of rx sram area */ |
515 | u32 tx_sram_addr; /* Base address of tx sram area */ | 534 | u32 tx_sram_addr; /* Base address of tx sram area */ |
@@ -614,19 +633,14 @@ static const struct ethtool_ops mv643xx_ethtool_ops; | |||
614 | static char mv643xx_driver_name[] = "mv643xx_eth"; | 633 | static char mv643xx_driver_name[] = "mv643xx_eth"; |
615 | static char mv643xx_driver_version[] = "1.0"; | 634 | static char mv643xx_driver_version[] = "1.0"; |
616 | 635 | ||
617 | static void __iomem *mv643xx_eth_base; | ||
618 | |||
619 | /* used to protect SMI_REG, which is shared across ports */ | ||
620 | static DEFINE_SPINLOCK(mv643xx_eth_phy_lock); | ||
621 | |||
622 | static inline u32 rdl(struct mv643xx_private *mp, int offset) | 636 | static inline u32 rdl(struct mv643xx_private *mp, int offset) |
623 | { | 637 | { |
624 | return readl(mv643xx_eth_base + offset); | 638 | return readl(mp->shared->eth_base + offset); |
625 | } | 639 | } |
626 | 640 | ||
627 | static inline void wrl(struct mv643xx_private *mp, int offset, u32 data) | 641 | static inline void wrl(struct mv643xx_private *mp, int offset, u32 data) |
628 | { | 642 | { |
629 | writel(data, mv643xx_eth_base + offset); | 643 | writel(data, mp->shared->eth_base + offset); |
630 | } | 644 | } |
631 | 645 | ||
632 | /* | 646 | /* |
@@ -1119,7 +1133,6 @@ static irqreturn_t mv643xx_eth_int_handler(int irq, void *dev_id) | |||
1119 | * | 1133 | * |
1120 | * INPUT: | 1134 | * INPUT: |
1121 | * struct mv643xx_private *mp Ethernet port | 1135 | * struct mv643xx_private *mp Ethernet port |
1122 | * unsigned int t_clk t_clk of the MV-643xx chip in HZ units | ||
1123 | * unsigned int delay Delay in usec | 1136 | * unsigned int delay Delay in usec |
1124 | * | 1137 | * |
1125 | * OUTPUT: | 1138 | * OUTPUT: |
@@ -1130,10 +1143,10 @@ static irqreturn_t mv643xx_eth_int_handler(int irq, void *dev_id) | |||
1130 | * | 1143 | * |
1131 | */ | 1144 | */ |
1132 | static unsigned int eth_port_set_rx_coal(struct mv643xx_private *mp, | 1145 | static unsigned int eth_port_set_rx_coal(struct mv643xx_private *mp, |
1133 | unsigned int t_clk, unsigned int delay) | 1146 | unsigned int delay) |
1134 | { | 1147 | { |
1135 | unsigned int port_num = mp->port_num; | 1148 | unsigned int port_num = mp->port_num; |
1136 | unsigned int coal = ((t_clk / 1000000) * delay) / 64; | 1149 | unsigned int coal = ((mp->shared->t_clk / 1000000) * delay) / 64; |
1137 | 1150 | ||
1138 | /* Set RX Coalescing mechanism */ | 1151 | /* Set RX Coalescing mechanism */ |
1139 | wrl(mp, SDMA_CONFIG_REG(port_num), | 1152 | wrl(mp, SDMA_CONFIG_REG(port_num), |
@@ -1158,7 +1171,6 @@ static unsigned int eth_port_set_rx_coal(struct mv643xx_private *mp, | |||
1158 | * | 1171 | * |
1159 | * INPUT: | 1172 | * INPUT: |
1160 | * struct mv643xx_private *mp Ethernet port | 1173 | * struct mv643xx_private *mp Ethernet port |
1161 | * unsigned int t_clk t_clk of the MV-643xx chip in HZ units | ||
1162 | * unsigned int delay Delay in uSeconds | 1174 | * unsigned int delay Delay in uSeconds |
1163 | * | 1175 | * |
1164 | * OUTPUT: | 1176 | * OUTPUT: |
@@ -1169,9 +1181,9 @@ static unsigned int eth_port_set_rx_coal(struct mv643xx_private *mp, | |||
1169 | * | 1181 | * |
1170 | */ | 1182 | */ |
1171 | static unsigned int eth_port_set_tx_coal(struct mv643xx_private *mp, | 1183 | static unsigned int eth_port_set_tx_coal(struct mv643xx_private *mp, |
1172 | unsigned int t_clk, unsigned int delay) | 1184 | unsigned int delay) |
1173 | { | 1185 | { |
1174 | unsigned int coal = ((t_clk / 1000000) * delay) / 64; | 1186 | unsigned int coal = ((mp->shared->t_clk / 1000000) * delay) / 64; |
1175 | 1187 | ||
1176 | /* Set TX Coalescing mechanism */ | 1188 | /* Set TX Coalescing mechanism */ |
1177 | wrl(mp, TX_FIFO_URGENT_THRESHOLD_REG(mp->port_num), coal << 4); | 1189 | wrl(mp, TX_FIFO_URGENT_THRESHOLD_REG(mp->port_num), coal << 4); |
@@ -1413,11 +1425,11 @@ static int mv643xx_eth_open(struct net_device *dev) | |||
1413 | 1425 | ||
1414 | #ifdef MV643XX_COAL | 1426 | #ifdef MV643XX_COAL |
1415 | mp->rx_int_coal = | 1427 | mp->rx_int_coal = |
1416 | eth_port_set_rx_coal(mp, 133000000, MV643XX_RX_COAL); | 1428 | eth_port_set_rx_coal(mp, MV643XX_RX_COAL); |
1417 | #endif | 1429 | #endif |
1418 | 1430 | ||
1419 | mp->tx_int_coal = | 1431 | mp->tx_int_coal = |
1420 | eth_port_set_tx_coal(mp, 133000000, MV643XX_TX_COAL); | 1432 | eth_port_set_tx_coal(mp, MV643XX_TX_COAL); |
1421 | 1433 | ||
1422 | /* Unmask phy and link status changes interrupts */ | 1434 | /* Unmask phy and link status changes interrupts */ |
1423 | wrl(mp, INTERRUPT_EXTEND_MASK_REG(port_num), ETH_INT_UNMASK_ALL_EXT); | 1435 | wrl(mp, INTERRUPT_EXTEND_MASK_REG(port_num), ETH_INT_UNMASK_ALL_EXT); |
@@ -1827,6 +1839,11 @@ static int mv643xx_eth_probe(struct platform_device *pdev) | |||
1827 | return -ENODEV; | 1839 | return -ENODEV; |
1828 | } | 1840 | } |
1829 | 1841 | ||
1842 | if (pd->shared == NULL) { | ||
1843 | printk(KERN_ERR "No mv643xx_eth_platform_data->shared\n"); | ||
1844 | return -ENODEV; | ||
1845 | } | ||
1846 | |||
1830 | dev = alloc_etherdev(sizeof(struct mv643xx_private)); | 1847 | dev = alloc_etherdev(sizeof(struct mv643xx_private)); |
1831 | if (!dev) | 1848 | if (!dev) |
1832 | return -ENOMEM; | 1849 | return -ENOMEM; |
@@ -1877,8 +1894,16 @@ static int mv643xx_eth_probe(struct platform_device *pdev) | |||
1877 | 1894 | ||
1878 | spin_lock_init(&mp->lock); | 1895 | spin_lock_init(&mp->lock); |
1879 | 1896 | ||
1897 | mp->shared = platform_get_drvdata(pd->shared); | ||
1880 | port_num = mp->port_num = pd->port_number; | 1898 | port_num = mp->port_num = pd->port_number; |
1881 | 1899 | ||
1900 | if (mp->shared->win_protect) | ||
1901 | wrl(mp, WINDOW_PROTECT(port_num), mp->shared->win_protect); | ||
1902 | |||
1903 | mp->shared_smi = mp->shared; | ||
1904 | if (pd->shared_smi != NULL) | ||
1905 | mp->shared_smi = platform_get_drvdata(pd->shared_smi); | ||
1906 | |||
1882 | /* set default config values */ | 1907 | /* set default config values */ |
1883 | eth_port_uc_addr_get(mp, dev->dev_addr); | 1908 | eth_port_uc_addr_get(mp, dev->dev_addr); |
1884 | mp->rx_ring_size = PORT_DEFAULT_RECEIVE_QUEUE_SIZE; | 1909 | mp->rx_ring_size = PORT_DEFAULT_RECEIVE_QUEUE_SIZE; |
@@ -1983,30 +2008,91 @@ static int mv643xx_eth_remove(struct platform_device *pdev) | |||
1983 | return 0; | 2008 | return 0; |
1984 | } | 2009 | } |
1985 | 2010 | ||
2011 | static void mv643xx_eth_conf_mbus_windows(struct mv643xx_shared_private *msp, | ||
2012 | struct mbus_dram_target_info *dram) | ||
2013 | { | ||
2014 | void __iomem *base = msp->eth_base; | ||
2015 | u32 win_enable; | ||
2016 | u32 win_protect; | ||
2017 | int i; | ||
2018 | |||
2019 | for (i = 0; i < 6; i++) { | ||
2020 | writel(0, base + WINDOW_BASE(i)); | ||
2021 | writel(0, base + WINDOW_SIZE(i)); | ||
2022 | if (i < 4) | ||
2023 | writel(0, base + WINDOW_REMAP_HIGH(i)); | ||
2024 | } | ||
2025 | |||
2026 | win_enable = 0x3f; | ||
2027 | win_protect = 0; | ||
2028 | |||
2029 | for (i = 0; i < dram->num_cs; i++) { | ||
2030 | struct mbus_dram_window *cs = dram->cs + i; | ||
2031 | |||
2032 | writel((cs->base & 0xffff0000) | | ||
2033 | (cs->mbus_attr << 8) | | ||
2034 | dram->mbus_dram_target_id, base + WINDOW_BASE(i)); | ||
2035 | writel((cs->size - 1) & 0xffff0000, base + WINDOW_SIZE(i)); | ||
2036 | |||
2037 | win_enable &= ~(1 << i); | ||
2038 | win_protect |= 3 << (2 * i); | ||
2039 | } | ||
2040 | |||
2041 | writel(win_enable, base + WINDOW_BAR_ENABLE); | ||
2042 | msp->win_protect = win_protect; | ||
2043 | } | ||
2044 | |||
1986 | static int mv643xx_eth_shared_probe(struct platform_device *pdev) | 2045 | static int mv643xx_eth_shared_probe(struct platform_device *pdev) |
1987 | { | 2046 | { |
1988 | static int mv643xx_version_printed = 0; | 2047 | static int mv643xx_version_printed = 0; |
2048 | struct mv643xx_eth_shared_platform_data *pd = pdev->dev.platform_data; | ||
2049 | struct mv643xx_shared_private *msp; | ||
1989 | struct resource *res; | 2050 | struct resource *res; |
2051 | int ret; | ||
1990 | 2052 | ||
1991 | if (!mv643xx_version_printed++) | 2053 | if (!mv643xx_version_printed++) |
1992 | printk(KERN_NOTICE "MV-643xx 10/100/1000 Ethernet Driver\n"); | 2054 | printk(KERN_NOTICE "MV-643xx 10/100/1000 Ethernet Driver\n"); |
1993 | 2055 | ||
2056 | ret = -EINVAL; | ||
1994 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 2057 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
1995 | if (res == NULL) | 2058 | if (res == NULL) |
1996 | return -ENODEV; | 2059 | goto out; |
1997 | 2060 | ||
1998 | mv643xx_eth_base = ioremap(res->start, res->end - res->start + 1); | 2061 | ret = -ENOMEM; |
1999 | if (mv643xx_eth_base == NULL) | 2062 | msp = kmalloc(sizeof(*msp), GFP_KERNEL); |
2000 | return -ENOMEM; | 2063 | if (msp == NULL) |
2064 | goto out; | ||
2065 | memset(msp, 0, sizeof(*msp)); | ||
2066 | |||
2067 | msp->eth_base = ioremap(res->start, res->end - res->start + 1); | ||
2068 | if (msp->eth_base == NULL) | ||
2069 | goto out_free; | ||
2070 | |||
2071 | spin_lock_init(&msp->phy_lock); | ||
2072 | msp->t_clk = (pd != NULL && pd->t_clk != 0) ? pd->t_clk : 133000000; | ||
2073 | |||
2074 | platform_set_drvdata(pdev, msp); | ||
2075 | |||
2076 | /* | ||
2077 | * (Re-)program MBUS remapping windows if we are asked to. | ||
2078 | */ | ||
2079 | if (pd != NULL && pd->dram != NULL) | ||
2080 | mv643xx_eth_conf_mbus_windows(msp, pd->dram); | ||
2001 | 2081 | ||
2002 | return 0; | 2082 | return 0; |
2003 | 2083 | ||
2084 | out_free: | ||
2085 | kfree(msp); | ||
2086 | out: | ||
2087 | return ret; | ||
2004 | } | 2088 | } |
2005 | 2089 | ||
2006 | static int mv643xx_eth_shared_remove(struct platform_device *pdev) | 2090 | static int mv643xx_eth_shared_remove(struct platform_device *pdev) |
2007 | { | 2091 | { |
2008 | iounmap(mv643xx_eth_base); | 2092 | struct mv643xx_shared_private *msp = platform_get_drvdata(pdev); |
2009 | mv643xx_eth_base = NULL; | 2093 | |
2094 | iounmap(msp->eth_base); | ||
2095 | kfree(msp); | ||
2010 | 2096 | ||
2011 | return 0; | 2097 | return 0; |
2012 | } | 2098 | } |
@@ -2906,15 +2992,16 @@ static void eth_port_reset(struct mv643xx_private *mp) | |||
2906 | static void eth_port_read_smi_reg(struct mv643xx_private *mp, | 2992 | static void eth_port_read_smi_reg(struct mv643xx_private *mp, |
2907 | unsigned int phy_reg, unsigned int *value) | 2993 | unsigned int phy_reg, unsigned int *value) |
2908 | { | 2994 | { |
2995 | void __iomem *smi_reg = mp->shared_smi->eth_base + SMI_REG; | ||
2909 | int phy_addr = ethernet_phy_get(mp); | 2996 | int phy_addr = ethernet_phy_get(mp); |
2910 | unsigned long flags; | 2997 | unsigned long flags; |
2911 | int i; | 2998 | int i; |
2912 | 2999 | ||
2913 | /* the SMI register is a shared resource */ | 3000 | /* the SMI register is a shared resource */ |
2914 | spin_lock_irqsave(&mv643xx_eth_phy_lock, flags); | 3001 | spin_lock_irqsave(&mp->shared_smi->phy_lock, flags); |
2915 | 3002 | ||
2916 | /* wait for the SMI register to become available */ | 3003 | /* wait for the SMI register to become available */ |
2917 | for (i = 0; rdl(mp, SMI_REG) & ETH_SMI_BUSY; i++) { | 3004 | for (i = 0; readl(smi_reg) & ETH_SMI_BUSY; i++) { |
2918 | if (i == PHY_WAIT_ITERATIONS) { | 3005 | if (i == PHY_WAIT_ITERATIONS) { |
2919 | printk("%s: PHY busy timeout\n", mp->dev->name); | 3006 | printk("%s: PHY busy timeout\n", mp->dev->name); |
2920 | goto out; | 3007 | goto out; |
@@ -2922,11 +3009,11 @@ static void eth_port_read_smi_reg(struct mv643xx_private *mp, | |||
2922 | udelay(PHY_WAIT_MICRO_SECONDS); | 3009 | udelay(PHY_WAIT_MICRO_SECONDS); |
2923 | } | 3010 | } |
2924 | 3011 | ||
2925 | wrl(mp, SMI_REG, | 3012 | writel((phy_addr << 16) | (phy_reg << 21) | ETH_SMI_OPCODE_READ, |
2926 | (phy_addr << 16) | (phy_reg << 21) | ETH_SMI_OPCODE_READ); | 3013 | smi_reg); |
2927 | 3014 | ||
2928 | /* now wait for the data to be valid */ | 3015 | /* now wait for the data to be valid */ |
2929 | for (i = 0; !(rdl(mp, SMI_REG) & ETH_SMI_READ_VALID); i++) { | 3016 | for (i = 0; !(readl(smi_reg) & ETH_SMI_READ_VALID); i++) { |
2930 | if (i == PHY_WAIT_ITERATIONS) { | 3017 | if (i == PHY_WAIT_ITERATIONS) { |
2931 | printk("%s: PHY read timeout\n", mp->dev->name); | 3018 | printk("%s: PHY read timeout\n", mp->dev->name); |
2932 | goto out; | 3019 | goto out; |
@@ -2934,9 +3021,9 @@ static void eth_port_read_smi_reg(struct mv643xx_private *mp, | |||
2934 | udelay(PHY_WAIT_MICRO_SECONDS); | 3021 | udelay(PHY_WAIT_MICRO_SECONDS); |
2935 | } | 3022 | } |
2936 | 3023 | ||
2937 | *value = rdl(mp, SMI_REG) & 0xffff; | 3024 | *value = readl(smi_reg) & 0xffff; |
2938 | out: | 3025 | out: |
2939 | spin_unlock_irqrestore(&mv643xx_eth_phy_lock, flags); | 3026 | spin_unlock_irqrestore(&mp->shared_smi->phy_lock, flags); |
2940 | } | 3027 | } |
2941 | 3028 | ||
2942 | /* | 3029 | /* |
@@ -2962,17 +3049,16 @@ out: | |||
2962 | static void eth_port_write_smi_reg(struct mv643xx_private *mp, | 3049 | static void eth_port_write_smi_reg(struct mv643xx_private *mp, |
2963 | unsigned int phy_reg, unsigned int value) | 3050 | unsigned int phy_reg, unsigned int value) |
2964 | { | 3051 | { |
2965 | int phy_addr; | 3052 | void __iomem *smi_reg = mp->shared_smi->eth_base + SMI_REG; |
2966 | int i; | 3053 | int phy_addr = ethernet_phy_get(mp); |
2967 | unsigned long flags; | 3054 | unsigned long flags; |
2968 | 3055 | int i; | |
2969 | phy_addr = ethernet_phy_get(mp); | ||
2970 | 3056 | ||
2971 | /* the SMI register is a shared resource */ | 3057 | /* the SMI register is a shared resource */ |
2972 | spin_lock_irqsave(&mv643xx_eth_phy_lock, flags); | 3058 | spin_lock_irqsave(&mp->shared_smi->phy_lock, flags); |
2973 | 3059 | ||
2974 | /* wait for the SMI register to become available */ | 3060 | /* wait for the SMI register to become available */ |
2975 | for (i = 0; rdl(mp, SMI_REG) & ETH_SMI_BUSY; i++) { | 3061 | for (i = 0; readl(smi_reg) & ETH_SMI_BUSY; i++) { |
2976 | if (i == PHY_WAIT_ITERATIONS) { | 3062 | if (i == PHY_WAIT_ITERATIONS) { |
2977 | printk("%s: PHY busy timeout\n", mp->dev->name); | 3063 | printk("%s: PHY busy timeout\n", mp->dev->name); |
2978 | goto out; | 3064 | goto out; |
@@ -2980,10 +3066,10 @@ static void eth_port_write_smi_reg(struct mv643xx_private *mp, | |||
2980 | udelay(PHY_WAIT_MICRO_SECONDS); | 3066 | udelay(PHY_WAIT_MICRO_SECONDS); |
2981 | } | 3067 | } |
2982 | 3068 | ||
2983 | wrl(mp, SMI_REG, (phy_addr << 16) | (phy_reg << 21) | | 3069 | writel((phy_addr << 16) | (phy_reg << 21) | |
2984 | ETH_SMI_OPCODE_WRITE | (value & 0xffff)); | 3070 | ETH_SMI_OPCODE_WRITE | (value & 0xffff), smi_reg); |
2985 | out: | 3071 | out: |
2986 | spin_unlock_irqrestore(&mv643xx_eth_phy_lock, flags); | 3072 | spin_unlock_irqrestore(&mp->shared_smi->phy_lock, flags); |
2987 | } | 3073 | } |
2988 | 3074 | ||
2989 | /* | 3075 | /* |
diff --git a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c index ef63c8d2bd7e..e0d76c75aea0 100644 --- a/drivers/net/myri10ge/myri10ge.c +++ b/drivers/net/myri10ge/myri10ge.c | |||
@@ -75,7 +75,7 @@ | |||
75 | #include "myri10ge_mcp.h" | 75 | #include "myri10ge_mcp.h" |
76 | #include "myri10ge_mcp_gen_header.h" | 76 | #include "myri10ge_mcp_gen_header.h" |
77 | 77 | ||
78 | #define MYRI10GE_VERSION_STR "1.3.2-1.287" | 78 | #define MYRI10GE_VERSION_STR "1.3.99-1.347" |
79 | 79 | ||
80 | MODULE_DESCRIPTION("Myricom 10G driver (10GbE)"); | 80 | MODULE_DESCRIPTION("Myricom 10G driver (10GbE)"); |
81 | MODULE_AUTHOR("Maintainer: help@myri.com"); | 81 | MODULE_AUTHOR("Maintainer: help@myri.com"); |
@@ -144,11 +144,13 @@ struct myri10ge_tx_buf { | |||
144 | char *req_bytes; | 144 | char *req_bytes; |
145 | struct myri10ge_tx_buffer_state *info; | 145 | struct myri10ge_tx_buffer_state *info; |
146 | int mask; /* number of transmit slots -1 */ | 146 | int mask; /* number of transmit slots -1 */ |
147 | int boundary; /* boundary transmits cannot cross */ | ||
148 | int req ____cacheline_aligned; /* transmit slots submitted */ | 147 | int req ____cacheline_aligned; /* transmit slots submitted */ |
149 | int pkt_start; /* packets started */ | 148 | int pkt_start; /* packets started */ |
149 | int stop_queue; | ||
150 | int linearized; | ||
150 | int done ____cacheline_aligned; /* transmit slots completed */ | 151 | int done ____cacheline_aligned; /* transmit slots completed */ |
151 | int pkt_done; /* packets completed */ | 152 | int pkt_done; /* packets completed */ |
153 | int wake_queue; | ||
152 | }; | 154 | }; |
153 | 155 | ||
154 | struct myri10ge_rx_done { | 156 | struct myri10ge_rx_done { |
@@ -160,29 +162,50 @@ struct myri10ge_rx_done { | |||
160 | struct net_lro_desc lro_desc[MYRI10GE_MAX_LRO_DESCRIPTORS]; | 162 | struct net_lro_desc lro_desc[MYRI10GE_MAX_LRO_DESCRIPTORS]; |
161 | }; | 163 | }; |
162 | 164 | ||
163 | struct myri10ge_priv { | 165 | struct myri10ge_slice_netstats { |
164 | int running; /* running? */ | 166 | unsigned long rx_packets; |
165 | int csum_flag; /* rx_csums? */ | 167 | unsigned long tx_packets; |
168 | unsigned long rx_bytes; | ||
169 | unsigned long tx_bytes; | ||
170 | unsigned long rx_dropped; | ||
171 | unsigned long tx_dropped; | ||
172 | }; | ||
173 | |||
174 | struct myri10ge_slice_state { | ||
166 | struct myri10ge_tx_buf tx; /* transmit ring */ | 175 | struct myri10ge_tx_buf tx; /* transmit ring */ |
167 | struct myri10ge_rx_buf rx_small; | 176 | struct myri10ge_rx_buf rx_small; |
168 | struct myri10ge_rx_buf rx_big; | 177 | struct myri10ge_rx_buf rx_big; |
169 | struct myri10ge_rx_done rx_done; | 178 | struct myri10ge_rx_done rx_done; |
179 | struct net_device *dev; | ||
180 | struct napi_struct napi; | ||
181 | struct myri10ge_priv *mgp; | ||
182 | struct myri10ge_slice_netstats stats; | ||
183 | __be32 __iomem *irq_claim; | ||
184 | struct mcp_irq_data *fw_stats; | ||
185 | dma_addr_t fw_stats_bus; | ||
186 | int watchdog_tx_done; | ||
187 | int watchdog_tx_req; | ||
188 | }; | ||
189 | |||
190 | struct myri10ge_priv { | ||
191 | struct myri10ge_slice_state ss; | ||
192 | int tx_boundary; /* boundary transmits cannot cross */ | ||
193 | int running; /* running? */ | ||
194 | int csum_flag; /* rx_csums? */ | ||
170 | int small_bytes; | 195 | int small_bytes; |
171 | int big_bytes; | 196 | int big_bytes; |
197 | int max_intr_slots; | ||
172 | struct net_device *dev; | 198 | struct net_device *dev; |
173 | struct napi_struct napi; | ||
174 | struct net_device_stats stats; | 199 | struct net_device_stats stats; |
200 | spinlock_t stats_lock; | ||
175 | u8 __iomem *sram; | 201 | u8 __iomem *sram; |
176 | int sram_size; | 202 | int sram_size; |
177 | unsigned long board_span; | 203 | unsigned long board_span; |
178 | unsigned long iomem_base; | 204 | unsigned long iomem_base; |
179 | __be32 __iomem *irq_claim; | ||
180 | __be32 __iomem *irq_deassert; | 205 | __be32 __iomem *irq_deassert; |
181 | char *mac_addr_string; | 206 | char *mac_addr_string; |
182 | struct mcp_cmd_response *cmd; | 207 | struct mcp_cmd_response *cmd; |
183 | dma_addr_t cmd_bus; | 208 | dma_addr_t cmd_bus; |
184 | struct mcp_irq_data *fw_stats; | ||
185 | dma_addr_t fw_stats_bus; | ||
186 | struct pci_dev *pdev; | 209 | struct pci_dev *pdev; |
187 | int msi_enabled; | 210 | int msi_enabled; |
188 | u32 link_state; | 211 | u32 link_state; |
@@ -191,20 +214,16 @@ struct myri10ge_priv { | |||
191 | __be32 __iomem *intr_coal_delay_ptr; | 214 | __be32 __iomem *intr_coal_delay_ptr; |
192 | int mtrr; | 215 | int mtrr; |
193 | int wc_enabled; | 216 | int wc_enabled; |
194 | int wake_queue; | ||
195 | int stop_queue; | ||
196 | int down_cnt; | 217 | int down_cnt; |
197 | wait_queue_head_t down_wq; | 218 | wait_queue_head_t down_wq; |
198 | struct work_struct watchdog_work; | 219 | struct work_struct watchdog_work; |
199 | struct timer_list watchdog_timer; | 220 | struct timer_list watchdog_timer; |
200 | int watchdog_tx_done; | ||
201 | int watchdog_tx_req; | ||
202 | int watchdog_pause; | ||
203 | int watchdog_resets; | 221 | int watchdog_resets; |
204 | int tx_linearized; | 222 | int watchdog_pause; |
205 | int pause; | 223 | int pause; |
206 | char *fw_name; | 224 | char *fw_name; |
207 | char eeprom_strings[MYRI10GE_EEPROM_STRINGS_SIZE]; | 225 | char eeprom_strings[MYRI10GE_EEPROM_STRINGS_SIZE]; |
226 | char *product_code_string; | ||
208 | char fw_version[128]; | 227 | char fw_version[128]; |
209 | int fw_ver_major; | 228 | int fw_ver_major; |
210 | int fw_ver_minor; | 229 | int fw_ver_minor; |
@@ -228,58 +247,54 @@ static char *myri10ge_fw_aligned = "myri10ge_eth_z8e.dat"; | |||
228 | 247 | ||
229 | static char *myri10ge_fw_name = NULL; | 248 | static char *myri10ge_fw_name = NULL; |
230 | module_param(myri10ge_fw_name, charp, S_IRUGO | S_IWUSR); | 249 | module_param(myri10ge_fw_name, charp, S_IRUGO | S_IWUSR); |
231 | MODULE_PARM_DESC(myri10ge_fw_name, "Firmware image name\n"); | 250 | MODULE_PARM_DESC(myri10ge_fw_name, "Firmware image name"); |
232 | 251 | ||
233 | static int myri10ge_ecrc_enable = 1; | 252 | static int myri10ge_ecrc_enable = 1; |
234 | module_param(myri10ge_ecrc_enable, int, S_IRUGO); | 253 | module_param(myri10ge_ecrc_enable, int, S_IRUGO); |
235 | MODULE_PARM_DESC(myri10ge_ecrc_enable, "Enable Extended CRC on PCI-E\n"); | 254 | MODULE_PARM_DESC(myri10ge_ecrc_enable, "Enable Extended CRC on PCI-E"); |
236 | |||
237 | static int myri10ge_max_intr_slots = 1024; | ||
238 | module_param(myri10ge_max_intr_slots, int, S_IRUGO); | ||
239 | MODULE_PARM_DESC(myri10ge_max_intr_slots, "Interrupt queue slots\n"); | ||
240 | 255 | ||
241 | static int myri10ge_small_bytes = -1; /* -1 == auto */ | 256 | static int myri10ge_small_bytes = -1; /* -1 == auto */ |
242 | module_param(myri10ge_small_bytes, int, S_IRUGO | S_IWUSR); | 257 | module_param(myri10ge_small_bytes, int, S_IRUGO | S_IWUSR); |
243 | MODULE_PARM_DESC(myri10ge_small_bytes, "Threshold of small packets\n"); | 258 | MODULE_PARM_DESC(myri10ge_small_bytes, "Threshold of small packets"); |
244 | 259 | ||
245 | static int myri10ge_msi = 1; /* enable msi by default */ | 260 | static int myri10ge_msi = 1; /* enable msi by default */ |
246 | module_param(myri10ge_msi, int, S_IRUGO | S_IWUSR); | 261 | module_param(myri10ge_msi, int, S_IRUGO | S_IWUSR); |
247 | MODULE_PARM_DESC(myri10ge_msi, "Enable Message Signalled Interrupts\n"); | 262 | MODULE_PARM_DESC(myri10ge_msi, "Enable Message Signalled Interrupts"); |
248 | 263 | ||
249 | static int myri10ge_intr_coal_delay = 75; | 264 | static int myri10ge_intr_coal_delay = 75; |
250 | module_param(myri10ge_intr_coal_delay, int, S_IRUGO); | 265 | module_param(myri10ge_intr_coal_delay, int, S_IRUGO); |
251 | MODULE_PARM_DESC(myri10ge_intr_coal_delay, "Interrupt coalescing delay\n"); | 266 | MODULE_PARM_DESC(myri10ge_intr_coal_delay, "Interrupt coalescing delay"); |
252 | 267 | ||
253 | static int myri10ge_flow_control = 1; | 268 | static int myri10ge_flow_control = 1; |
254 | module_param(myri10ge_flow_control, int, S_IRUGO); | 269 | module_param(myri10ge_flow_control, int, S_IRUGO); |
255 | MODULE_PARM_DESC(myri10ge_flow_control, "Pause parameter\n"); | 270 | MODULE_PARM_DESC(myri10ge_flow_control, "Pause parameter"); |
256 | 271 | ||
257 | static int myri10ge_deassert_wait = 1; | 272 | static int myri10ge_deassert_wait = 1; |
258 | module_param(myri10ge_deassert_wait, int, S_IRUGO | S_IWUSR); | 273 | module_param(myri10ge_deassert_wait, int, S_IRUGO | S_IWUSR); |
259 | MODULE_PARM_DESC(myri10ge_deassert_wait, | 274 | MODULE_PARM_DESC(myri10ge_deassert_wait, |
260 | "Wait when deasserting legacy interrupts\n"); | 275 | "Wait when deasserting legacy interrupts"); |
261 | 276 | ||
262 | static int myri10ge_force_firmware = 0; | 277 | static int myri10ge_force_firmware = 0; |
263 | module_param(myri10ge_force_firmware, int, S_IRUGO); | 278 | module_param(myri10ge_force_firmware, int, S_IRUGO); |
264 | MODULE_PARM_DESC(myri10ge_force_firmware, | 279 | MODULE_PARM_DESC(myri10ge_force_firmware, |
265 | "Force firmware to assume aligned completions\n"); | 280 | "Force firmware to assume aligned completions"); |
266 | 281 | ||
267 | static int myri10ge_initial_mtu = MYRI10GE_MAX_ETHER_MTU - ETH_HLEN; | 282 | static int myri10ge_initial_mtu = MYRI10GE_MAX_ETHER_MTU - ETH_HLEN; |
268 | module_param(myri10ge_initial_mtu, int, S_IRUGO); | 283 | module_param(myri10ge_initial_mtu, int, S_IRUGO); |
269 | MODULE_PARM_DESC(myri10ge_initial_mtu, "Initial MTU\n"); | 284 | MODULE_PARM_DESC(myri10ge_initial_mtu, "Initial MTU"); |
270 | 285 | ||
271 | static int myri10ge_napi_weight = 64; | 286 | static int myri10ge_napi_weight = 64; |
272 | module_param(myri10ge_napi_weight, int, S_IRUGO); | 287 | module_param(myri10ge_napi_weight, int, S_IRUGO); |
273 | MODULE_PARM_DESC(myri10ge_napi_weight, "Set NAPI weight\n"); | 288 | MODULE_PARM_DESC(myri10ge_napi_weight, "Set NAPI weight"); |
274 | 289 | ||
275 | static int myri10ge_watchdog_timeout = 1; | 290 | static int myri10ge_watchdog_timeout = 1; |
276 | module_param(myri10ge_watchdog_timeout, int, S_IRUGO); | 291 | module_param(myri10ge_watchdog_timeout, int, S_IRUGO); |
277 | MODULE_PARM_DESC(myri10ge_watchdog_timeout, "Set watchdog timeout\n"); | 292 | MODULE_PARM_DESC(myri10ge_watchdog_timeout, "Set watchdog timeout"); |
278 | 293 | ||
279 | static int myri10ge_max_irq_loops = 1048576; | 294 | static int myri10ge_max_irq_loops = 1048576; |
280 | module_param(myri10ge_max_irq_loops, int, S_IRUGO); | 295 | module_param(myri10ge_max_irq_loops, int, S_IRUGO); |
281 | MODULE_PARM_DESC(myri10ge_max_irq_loops, | 296 | MODULE_PARM_DESC(myri10ge_max_irq_loops, |
282 | "Set stuck legacy IRQ detection threshold\n"); | 297 | "Set stuck legacy IRQ detection threshold"); |
283 | 298 | ||
284 | #define MYRI10GE_MSG_DEFAULT NETIF_MSG_LINK | 299 | #define MYRI10GE_MSG_DEFAULT NETIF_MSG_LINK |
285 | 300 | ||
@@ -289,21 +304,22 @@ MODULE_PARM_DESC(myri10ge_debug, "Debug level (0=none,...,16=all)"); | |||
289 | 304 | ||
290 | static int myri10ge_lro = 1; | 305 | static int myri10ge_lro = 1; |
291 | module_param(myri10ge_lro, int, S_IRUGO); | 306 | module_param(myri10ge_lro, int, S_IRUGO); |
292 | MODULE_PARM_DESC(myri10ge_lro, "Enable large receive offload\n"); | 307 | MODULE_PARM_DESC(myri10ge_lro, "Enable large receive offload"); |
293 | 308 | ||
294 | static int myri10ge_lro_max_pkts = MYRI10GE_LRO_MAX_PKTS; | 309 | static int myri10ge_lro_max_pkts = MYRI10GE_LRO_MAX_PKTS; |
295 | module_param(myri10ge_lro_max_pkts, int, S_IRUGO); | 310 | module_param(myri10ge_lro_max_pkts, int, S_IRUGO); |
296 | MODULE_PARM_DESC(myri10ge_lro, "Number of LRO packets to be aggregated\n"); | 311 | MODULE_PARM_DESC(myri10ge_lro_max_pkts, |
312 | "Number of LRO packets to be aggregated"); | ||
297 | 313 | ||
298 | static int myri10ge_fill_thresh = 256; | 314 | static int myri10ge_fill_thresh = 256; |
299 | module_param(myri10ge_fill_thresh, int, S_IRUGO | S_IWUSR); | 315 | module_param(myri10ge_fill_thresh, int, S_IRUGO | S_IWUSR); |
300 | MODULE_PARM_DESC(myri10ge_fill_thresh, "Number of empty rx slots allowed\n"); | 316 | MODULE_PARM_DESC(myri10ge_fill_thresh, "Number of empty rx slots allowed"); |
301 | 317 | ||
302 | static int myri10ge_reset_recover = 1; | 318 | static int myri10ge_reset_recover = 1; |
303 | 319 | ||
304 | static int myri10ge_wcfifo = 0; | 320 | static int myri10ge_wcfifo = 0; |
305 | module_param(myri10ge_wcfifo, int, S_IRUGO); | 321 | module_param(myri10ge_wcfifo, int, S_IRUGO); |
306 | MODULE_PARM_DESC(myri10ge_wcfifo, "Enable WC Fifo when WC is enabled\n"); | 322 | MODULE_PARM_DESC(myri10ge_wcfifo, "Enable WC Fifo when WC is enabled"); |
307 | 323 | ||
308 | #define MYRI10GE_FW_OFFSET 1024*1024 | 324 | #define MYRI10GE_FW_OFFSET 1024*1024 |
309 | #define MYRI10GE_HIGHPART_TO_U32(X) \ | 325 | #define MYRI10GE_HIGHPART_TO_U32(X) \ |
@@ -359,8 +375,10 @@ myri10ge_send_cmd(struct myri10ge_priv *mgp, u32 cmd, | |||
359 | for (sleep_total = 0; | 375 | for (sleep_total = 0; |
360 | sleep_total < 1000 | 376 | sleep_total < 1000 |
361 | && response->result == htonl(MYRI10GE_NO_RESPONSE_RESULT); | 377 | && response->result == htonl(MYRI10GE_NO_RESPONSE_RESULT); |
362 | sleep_total += 10) | 378 | sleep_total += 10) { |
363 | udelay(10); | 379 | udelay(10); |
380 | mb(); | ||
381 | } | ||
364 | } else { | 382 | } else { |
365 | /* use msleep for most command */ | 383 | /* use msleep for most command */ |
366 | for (sleep_total = 0; | 384 | for (sleep_total = 0; |
@@ -420,6 +438,10 @@ static int myri10ge_read_mac_addr(struct myri10ge_priv *mgp) | |||
420 | ptr += 1; | 438 | ptr += 1; |
421 | } | 439 | } |
422 | } | 440 | } |
441 | if (memcmp(ptr, "PC=", 3) == 0) { | ||
442 | ptr += 3; | ||
443 | mgp->product_code_string = ptr; | ||
444 | } | ||
423 | if (memcmp((const void *)ptr, "SN=", 3) == 0) { | 445 | if (memcmp((const void *)ptr, "SN=", 3) == 0) { |
424 | ptr += 3; | 446 | ptr += 3; |
425 | mgp->serial_number = simple_strtoul(ptr, &ptr, 10); | 447 | mgp->serial_number = simple_strtoul(ptr, &ptr, 10); |
@@ -442,7 +464,7 @@ abort: | |||
442 | static void myri10ge_dummy_rdma(struct myri10ge_priv *mgp, int enable) | 464 | static void myri10ge_dummy_rdma(struct myri10ge_priv *mgp, int enable) |
443 | { | 465 | { |
444 | char __iomem *submit; | 466 | char __iomem *submit; |
445 | __be32 buf[16]; | 467 | __be32 buf[16] __attribute__ ((__aligned__(8))); |
446 | u32 dma_low, dma_high; | 468 | u32 dma_low, dma_high; |
447 | int i; | 469 | int i; |
448 | 470 | ||
@@ -609,13 +631,38 @@ static int myri10ge_adopt_running_firmware(struct myri10ge_priv *mgp) | |||
609 | return status; | 631 | return status; |
610 | } | 632 | } |
611 | 633 | ||
634 | static int myri10ge_get_firmware_capabilities(struct myri10ge_priv *mgp) | ||
635 | { | ||
636 | struct myri10ge_cmd cmd; | ||
637 | int status; | ||
638 | |||
639 | /* probe for IPv6 TSO support */ | ||
640 | mgp->features = NETIF_F_SG | NETIF_F_HW_CSUM | NETIF_F_TSO; | ||
641 | status = myri10ge_send_cmd(mgp, MXGEFW_CMD_GET_MAX_TSO6_HDR_SIZE, | ||
642 | &cmd, 0); | ||
643 | if (status == 0) { | ||
644 | mgp->max_tso6 = cmd.data0; | ||
645 | mgp->features |= NETIF_F_TSO6; | ||
646 | } | ||
647 | |||
648 | status = myri10ge_send_cmd(mgp, MXGEFW_CMD_GET_RX_RING_SIZE, &cmd, 0); | ||
649 | if (status != 0) { | ||
650 | dev_err(&mgp->pdev->dev, | ||
651 | "failed MXGEFW_CMD_GET_RX_RING_SIZE\n"); | ||
652 | return -ENXIO; | ||
653 | } | ||
654 | |||
655 | mgp->max_intr_slots = 2 * (cmd.data0 / sizeof(struct mcp_dma_addr)); | ||
656 | |||
657 | return 0; | ||
658 | } | ||
659 | |||
612 | static int myri10ge_load_firmware(struct myri10ge_priv *mgp) | 660 | static int myri10ge_load_firmware(struct myri10ge_priv *mgp) |
613 | { | 661 | { |
614 | char __iomem *submit; | 662 | char __iomem *submit; |
615 | __be32 buf[16]; | 663 | __be32 buf[16] __attribute__ ((__aligned__(8))); |
616 | u32 dma_low, dma_high, size; | 664 | u32 dma_low, dma_high, size; |
617 | int status, i; | 665 | int status, i; |
618 | struct myri10ge_cmd cmd; | ||
619 | 666 | ||
620 | size = 0; | 667 | size = 0; |
621 | status = myri10ge_load_hotplug_firmware(mgp, &size); | 668 | status = myri10ge_load_hotplug_firmware(mgp, &size); |
@@ -635,7 +682,7 @@ static int myri10ge_load_firmware(struct myri10ge_priv *mgp) | |||
635 | } | 682 | } |
636 | dev_info(&mgp->pdev->dev, | 683 | dev_info(&mgp->pdev->dev, |
637 | "Successfully adopted running firmware\n"); | 684 | "Successfully adopted running firmware\n"); |
638 | if (mgp->tx.boundary == 4096) { | 685 | if (mgp->tx_boundary == 4096) { |
639 | dev_warn(&mgp->pdev->dev, | 686 | dev_warn(&mgp->pdev->dev, |
640 | "Using firmware currently running on NIC" | 687 | "Using firmware currently running on NIC" |
641 | ". For optimal\n"); | 688 | ". For optimal\n"); |
@@ -646,7 +693,9 @@ static int myri10ge_load_firmware(struct myri10ge_priv *mgp) | |||
646 | } | 693 | } |
647 | 694 | ||
648 | mgp->fw_name = "adopted"; | 695 | mgp->fw_name = "adopted"; |
649 | mgp->tx.boundary = 2048; | 696 | mgp->tx_boundary = 2048; |
697 | myri10ge_dummy_rdma(mgp, 1); | ||
698 | status = myri10ge_get_firmware_capabilities(mgp); | ||
650 | return status; | 699 | return status; |
651 | } | 700 | } |
652 | 701 | ||
@@ -681,26 +730,18 @@ static int myri10ge_load_firmware(struct myri10ge_priv *mgp) | |||
681 | msleep(1); | 730 | msleep(1); |
682 | mb(); | 731 | mb(); |
683 | i = 0; | 732 | i = 0; |
684 | while (mgp->cmd->data != MYRI10GE_NO_CONFIRM_DATA && i < 20) { | 733 | while (mgp->cmd->data != MYRI10GE_NO_CONFIRM_DATA && i < 9) { |
685 | msleep(1); | 734 | msleep(1 << i); |
686 | i++; | 735 | i++; |
687 | } | 736 | } |
688 | if (mgp->cmd->data != MYRI10GE_NO_CONFIRM_DATA) { | 737 | if (mgp->cmd->data != MYRI10GE_NO_CONFIRM_DATA) { |
689 | dev_err(&mgp->pdev->dev, "handoff failed\n"); | 738 | dev_err(&mgp->pdev->dev, "handoff failed\n"); |
690 | return -ENXIO; | 739 | return -ENXIO; |
691 | } | 740 | } |
692 | dev_info(&mgp->pdev->dev, "handoff confirmed\n"); | ||
693 | myri10ge_dummy_rdma(mgp, 1); | 741 | myri10ge_dummy_rdma(mgp, 1); |
742 | status = myri10ge_get_firmware_capabilities(mgp); | ||
694 | 743 | ||
695 | /* probe for IPv6 TSO support */ | 744 | return status; |
696 | mgp->features = NETIF_F_SG | NETIF_F_HW_CSUM | NETIF_F_TSO; | ||
697 | status = myri10ge_send_cmd(mgp, MXGEFW_CMD_GET_MAX_TSO6_HDR_SIZE, | ||
698 | &cmd, 0); | ||
699 | if (status == 0) { | ||
700 | mgp->max_tso6 = cmd.data0; | ||
701 | mgp->features |= NETIF_F_TSO6; | ||
702 | } | ||
703 | return 0; | ||
704 | } | 745 | } |
705 | 746 | ||
706 | static int myri10ge_update_mac_address(struct myri10ge_priv *mgp, u8 * addr) | 747 | static int myri10ge_update_mac_address(struct myri10ge_priv *mgp, u8 * addr) |
@@ -772,7 +813,7 @@ static int myri10ge_dma_test(struct myri10ge_priv *mgp, int test_type) | |||
772 | * transfers took to complete. | 813 | * transfers took to complete. |
773 | */ | 814 | */ |
774 | 815 | ||
775 | len = mgp->tx.boundary; | 816 | len = mgp->tx_boundary; |
776 | 817 | ||
777 | cmd.data0 = MYRI10GE_LOWPART_TO_U32(dmatest_bus); | 818 | cmd.data0 = MYRI10GE_LOWPART_TO_U32(dmatest_bus); |
778 | cmd.data1 = MYRI10GE_HIGHPART_TO_U32(dmatest_bus); | 819 | cmd.data1 = MYRI10GE_HIGHPART_TO_U32(dmatest_bus); |
@@ -834,17 +875,17 @@ static int myri10ge_reset(struct myri10ge_priv *mgp) | |||
834 | 875 | ||
835 | /* Now exchange information about interrupts */ | 876 | /* Now exchange information about interrupts */ |
836 | 877 | ||
837 | bytes = myri10ge_max_intr_slots * sizeof(*mgp->rx_done.entry); | 878 | bytes = mgp->max_intr_slots * sizeof(*mgp->ss.rx_done.entry); |
838 | memset(mgp->rx_done.entry, 0, bytes); | 879 | memset(mgp->ss.rx_done.entry, 0, bytes); |
839 | cmd.data0 = (u32) bytes; | 880 | cmd.data0 = (u32) bytes; |
840 | status = myri10ge_send_cmd(mgp, MXGEFW_CMD_SET_INTRQ_SIZE, &cmd, 0); | 881 | status = myri10ge_send_cmd(mgp, MXGEFW_CMD_SET_INTRQ_SIZE, &cmd, 0); |
841 | cmd.data0 = MYRI10GE_LOWPART_TO_U32(mgp->rx_done.bus); | 882 | cmd.data0 = MYRI10GE_LOWPART_TO_U32(mgp->ss.rx_done.bus); |
842 | cmd.data1 = MYRI10GE_HIGHPART_TO_U32(mgp->rx_done.bus); | 883 | cmd.data1 = MYRI10GE_HIGHPART_TO_U32(mgp->ss.rx_done.bus); |
843 | status |= myri10ge_send_cmd(mgp, MXGEFW_CMD_SET_INTRQ_DMA, &cmd, 0); | 884 | status |= myri10ge_send_cmd(mgp, MXGEFW_CMD_SET_INTRQ_DMA, &cmd, 0); |
844 | 885 | ||
845 | status |= | 886 | status |= |
846 | myri10ge_send_cmd(mgp, MXGEFW_CMD_GET_IRQ_ACK_OFFSET, &cmd, 0); | 887 | myri10ge_send_cmd(mgp, MXGEFW_CMD_GET_IRQ_ACK_OFFSET, &cmd, 0); |
847 | mgp->irq_claim = (__iomem __be32 *) (mgp->sram + cmd.data0); | 888 | mgp->ss.irq_claim = (__iomem __be32 *) (mgp->sram + cmd.data0); |
848 | status |= myri10ge_send_cmd(mgp, MXGEFW_CMD_GET_IRQ_DEASSERT_OFFSET, | 889 | status |= myri10ge_send_cmd(mgp, MXGEFW_CMD_GET_IRQ_DEASSERT_OFFSET, |
849 | &cmd, 0); | 890 | &cmd, 0); |
850 | mgp->irq_deassert = (__iomem __be32 *) (mgp->sram + cmd.data0); | 891 | mgp->irq_deassert = (__iomem __be32 *) (mgp->sram + cmd.data0); |
@@ -858,17 +899,17 @@ static int myri10ge_reset(struct myri10ge_priv *mgp) | |||
858 | } | 899 | } |
859 | put_be32(htonl(mgp->intr_coal_delay), mgp->intr_coal_delay_ptr); | 900 | put_be32(htonl(mgp->intr_coal_delay), mgp->intr_coal_delay_ptr); |
860 | 901 | ||
861 | memset(mgp->rx_done.entry, 0, bytes); | 902 | memset(mgp->ss.rx_done.entry, 0, bytes); |
862 | 903 | ||
863 | /* reset mcp/driver shared state back to 0 */ | 904 | /* reset mcp/driver shared state back to 0 */ |
864 | mgp->tx.req = 0; | 905 | mgp->ss.tx.req = 0; |
865 | mgp->tx.done = 0; | 906 | mgp->ss.tx.done = 0; |
866 | mgp->tx.pkt_start = 0; | 907 | mgp->ss.tx.pkt_start = 0; |
867 | mgp->tx.pkt_done = 0; | 908 | mgp->ss.tx.pkt_done = 0; |
868 | mgp->rx_big.cnt = 0; | 909 | mgp->ss.rx_big.cnt = 0; |
869 | mgp->rx_small.cnt = 0; | 910 | mgp->ss.rx_small.cnt = 0; |
870 | mgp->rx_done.idx = 0; | 911 | mgp->ss.rx_done.idx = 0; |
871 | mgp->rx_done.cnt = 0; | 912 | mgp->ss.rx_done.cnt = 0; |
872 | mgp->link_changes = 0; | 913 | mgp->link_changes = 0; |
873 | status = myri10ge_update_mac_address(mgp, mgp->dev->dev_addr); | 914 | status = myri10ge_update_mac_address(mgp, mgp->dev->dev_addr); |
874 | myri10ge_change_pause(mgp, mgp->pause); | 915 | myri10ge_change_pause(mgp, mgp->pause); |
@@ -1020,9 +1061,10 @@ myri10ge_unmap_rx_page(struct pci_dev *pdev, | |||
1020 | * page into an skb */ | 1061 | * page into an skb */ |
1021 | 1062 | ||
1022 | static inline int | 1063 | static inline int |
1023 | myri10ge_rx_done(struct myri10ge_priv *mgp, struct myri10ge_rx_buf *rx, | 1064 | myri10ge_rx_done(struct myri10ge_slice_state *ss, struct myri10ge_rx_buf *rx, |
1024 | int bytes, int len, __wsum csum) | 1065 | int bytes, int len, __wsum csum) |
1025 | { | 1066 | { |
1067 | struct myri10ge_priv *mgp = ss->mgp; | ||
1026 | struct sk_buff *skb; | 1068 | struct sk_buff *skb; |
1027 | struct skb_frag_struct rx_frags[MYRI10GE_MAX_FRAGS_PER_FRAME]; | 1069 | struct skb_frag_struct rx_frags[MYRI10GE_MAX_FRAGS_PER_FRAME]; |
1028 | int i, idx, hlen, remainder; | 1070 | int i, idx, hlen, remainder; |
@@ -1052,11 +1094,10 @@ myri10ge_rx_done(struct myri10ge_priv *mgp, struct myri10ge_rx_buf *rx, | |||
1052 | rx_frags[0].page_offset += MXGEFW_PAD; | 1094 | rx_frags[0].page_offset += MXGEFW_PAD; |
1053 | rx_frags[0].size -= MXGEFW_PAD; | 1095 | rx_frags[0].size -= MXGEFW_PAD; |
1054 | len -= MXGEFW_PAD; | 1096 | len -= MXGEFW_PAD; |
1055 | lro_receive_frags(&mgp->rx_done.lro_mgr, rx_frags, | 1097 | lro_receive_frags(&ss->rx_done.lro_mgr, rx_frags, |
1056 | len, len, | 1098 | len, len, |
1057 | /* opaque, will come back in get_frag_header */ | 1099 | /* opaque, will come back in get_frag_header */ |
1058 | (void *)(__force unsigned long)csum, | 1100 | (void *)(__force unsigned long)csum, csum); |
1059 | csum); | ||
1060 | return 1; | 1101 | return 1; |
1061 | } | 1102 | } |
1062 | 1103 | ||
@@ -1096,10 +1137,11 @@ myri10ge_rx_done(struct myri10ge_priv *mgp, struct myri10ge_rx_buf *rx, | |||
1096 | return 1; | 1137 | return 1; |
1097 | } | 1138 | } |
1098 | 1139 | ||
1099 | static inline void myri10ge_tx_done(struct myri10ge_priv *mgp, int mcp_index) | 1140 | static inline void |
1141 | myri10ge_tx_done(struct myri10ge_slice_state *ss, int mcp_index) | ||
1100 | { | 1142 | { |
1101 | struct pci_dev *pdev = mgp->pdev; | 1143 | struct pci_dev *pdev = ss->mgp->pdev; |
1102 | struct myri10ge_tx_buf *tx = &mgp->tx; | 1144 | struct myri10ge_tx_buf *tx = &ss->tx; |
1103 | struct sk_buff *skb; | 1145 | struct sk_buff *skb; |
1104 | int idx, len; | 1146 | int idx, len; |
1105 | 1147 | ||
@@ -1117,8 +1159,8 @@ static inline void myri10ge_tx_done(struct myri10ge_priv *mgp, int mcp_index) | |||
1117 | len = pci_unmap_len(&tx->info[idx], len); | 1159 | len = pci_unmap_len(&tx->info[idx], len); |
1118 | pci_unmap_len_set(&tx->info[idx], len, 0); | 1160 | pci_unmap_len_set(&tx->info[idx], len, 0); |
1119 | if (skb) { | 1161 | if (skb) { |
1120 | mgp->stats.tx_bytes += skb->len; | 1162 | ss->stats.tx_bytes += skb->len; |
1121 | mgp->stats.tx_packets++; | 1163 | ss->stats.tx_packets++; |
1122 | dev_kfree_skb_irq(skb); | 1164 | dev_kfree_skb_irq(skb); |
1123 | if (len) | 1165 | if (len) |
1124 | pci_unmap_single(pdev, | 1166 | pci_unmap_single(pdev, |
@@ -1134,16 +1176,18 @@ static inline void myri10ge_tx_done(struct myri10ge_priv *mgp, int mcp_index) | |||
1134 | } | 1176 | } |
1135 | } | 1177 | } |
1136 | /* start the queue if we've stopped it */ | 1178 | /* start the queue if we've stopped it */ |
1137 | if (netif_queue_stopped(mgp->dev) | 1179 | if (netif_queue_stopped(ss->dev) |
1138 | && tx->req - tx->done < (tx->mask >> 1)) { | 1180 | && tx->req - tx->done < (tx->mask >> 1)) { |
1139 | mgp->wake_queue++; | 1181 | tx->wake_queue++; |
1140 | netif_wake_queue(mgp->dev); | 1182 | netif_wake_queue(ss->dev); |
1141 | } | 1183 | } |
1142 | } | 1184 | } |
1143 | 1185 | ||
1144 | static inline int myri10ge_clean_rx_done(struct myri10ge_priv *mgp, int budget) | 1186 | static inline int |
1187 | myri10ge_clean_rx_done(struct myri10ge_slice_state *ss, int budget) | ||
1145 | { | 1188 | { |
1146 | struct myri10ge_rx_done *rx_done = &mgp->rx_done; | 1189 | struct myri10ge_rx_done *rx_done = &ss->rx_done; |
1190 | struct myri10ge_priv *mgp = ss->mgp; | ||
1147 | unsigned long rx_bytes = 0; | 1191 | unsigned long rx_bytes = 0; |
1148 | unsigned long rx_packets = 0; | 1192 | unsigned long rx_packets = 0; |
1149 | unsigned long rx_ok; | 1193 | unsigned long rx_ok; |
@@ -1159,40 +1203,40 @@ static inline int myri10ge_clean_rx_done(struct myri10ge_priv *mgp, int budget) | |||
1159 | rx_done->entry[idx].length = 0; | 1203 | rx_done->entry[idx].length = 0; |
1160 | checksum = csum_unfold(rx_done->entry[idx].checksum); | 1204 | checksum = csum_unfold(rx_done->entry[idx].checksum); |
1161 | if (length <= mgp->small_bytes) | 1205 | if (length <= mgp->small_bytes) |
1162 | rx_ok = myri10ge_rx_done(mgp, &mgp->rx_small, | 1206 | rx_ok = myri10ge_rx_done(ss, &ss->rx_small, |
1163 | mgp->small_bytes, | 1207 | mgp->small_bytes, |
1164 | length, checksum); | 1208 | length, checksum); |
1165 | else | 1209 | else |
1166 | rx_ok = myri10ge_rx_done(mgp, &mgp->rx_big, | 1210 | rx_ok = myri10ge_rx_done(ss, &ss->rx_big, |
1167 | mgp->big_bytes, | 1211 | mgp->big_bytes, |
1168 | length, checksum); | 1212 | length, checksum); |
1169 | rx_packets += rx_ok; | 1213 | rx_packets += rx_ok; |
1170 | rx_bytes += rx_ok * (unsigned long)length; | 1214 | rx_bytes += rx_ok * (unsigned long)length; |
1171 | cnt++; | 1215 | cnt++; |
1172 | idx = cnt & (myri10ge_max_intr_slots - 1); | 1216 | idx = cnt & (mgp->max_intr_slots - 1); |
1173 | work_done++; | 1217 | work_done++; |
1174 | } | 1218 | } |
1175 | rx_done->idx = idx; | 1219 | rx_done->idx = idx; |
1176 | rx_done->cnt = cnt; | 1220 | rx_done->cnt = cnt; |
1177 | mgp->stats.rx_packets += rx_packets; | 1221 | ss->stats.rx_packets += rx_packets; |
1178 | mgp->stats.rx_bytes += rx_bytes; | 1222 | ss->stats.rx_bytes += rx_bytes; |
1179 | 1223 | ||
1180 | if (myri10ge_lro) | 1224 | if (myri10ge_lro) |
1181 | lro_flush_all(&rx_done->lro_mgr); | 1225 | lro_flush_all(&rx_done->lro_mgr); |
1182 | 1226 | ||
1183 | /* restock receive rings if needed */ | 1227 | /* restock receive rings if needed */ |
1184 | if (mgp->rx_small.fill_cnt - mgp->rx_small.cnt < myri10ge_fill_thresh) | 1228 | if (ss->rx_small.fill_cnt - ss->rx_small.cnt < myri10ge_fill_thresh) |
1185 | myri10ge_alloc_rx_pages(mgp, &mgp->rx_small, | 1229 | myri10ge_alloc_rx_pages(mgp, &ss->rx_small, |
1186 | mgp->small_bytes + MXGEFW_PAD, 0); | 1230 | mgp->small_bytes + MXGEFW_PAD, 0); |
1187 | if (mgp->rx_big.fill_cnt - mgp->rx_big.cnt < myri10ge_fill_thresh) | 1231 | if (ss->rx_big.fill_cnt - ss->rx_big.cnt < myri10ge_fill_thresh) |
1188 | myri10ge_alloc_rx_pages(mgp, &mgp->rx_big, mgp->big_bytes, 0); | 1232 | myri10ge_alloc_rx_pages(mgp, &ss->rx_big, mgp->big_bytes, 0); |
1189 | 1233 | ||
1190 | return work_done; | 1234 | return work_done; |
1191 | } | 1235 | } |
1192 | 1236 | ||
1193 | static inline void myri10ge_check_statblock(struct myri10ge_priv *mgp) | 1237 | static inline void myri10ge_check_statblock(struct myri10ge_priv *mgp) |
1194 | { | 1238 | { |
1195 | struct mcp_irq_data *stats = mgp->fw_stats; | 1239 | struct mcp_irq_data *stats = mgp->ss.fw_stats; |
1196 | 1240 | ||
1197 | if (unlikely(stats->stats_updated)) { | 1241 | if (unlikely(stats->stats_updated)) { |
1198 | unsigned link_up = ntohl(stats->link_up); | 1242 | unsigned link_up = ntohl(stats->link_up); |
@@ -1219,9 +1263,9 @@ static inline void myri10ge_check_statblock(struct myri10ge_priv *mgp) | |||
1219 | } | 1263 | } |
1220 | } | 1264 | } |
1221 | if (mgp->rdma_tags_available != | 1265 | if (mgp->rdma_tags_available != |
1222 | ntohl(mgp->fw_stats->rdma_tags_available)) { | 1266 | ntohl(stats->rdma_tags_available)) { |
1223 | mgp->rdma_tags_available = | 1267 | mgp->rdma_tags_available = |
1224 | ntohl(mgp->fw_stats->rdma_tags_available); | 1268 | ntohl(stats->rdma_tags_available); |
1225 | printk(KERN_WARNING "myri10ge: %s: RDMA timed out! " | 1269 | printk(KERN_WARNING "myri10ge: %s: RDMA timed out! " |
1226 | "%d tags left\n", mgp->dev->name, | 1270 | "%d tags left\n", mgp->dev->name, |
1227 | mgp->rdma_tags_available); | 1271 | mgp->rdma_tags_available); |
@@ -1234,26 +1278,27 @@ static inline void myri10ge_check_statblock(struct myri10ge_priv *mgp) | |||
1234 | 1278 | ||
1235 | static int myri10ge_poll(struct napi_struct *napi, int budget) | 1279 | static int myri10ge_poll(struct napi_struct *napi, int budget) |
1236 | { | 1280 | { |
1237 | struct myri10ge_priv *mgp = | 1281 | struct myri10ge_slice_state *ss = |
1238 | container_of(napi, struct myri10ge_priv, napi); | 1282 | container_of(napi, struct myri10ge_slice_state, napi); |
1239 | struct net_device *netdev = mgp->dev; | 1283 | struct net_device *netdev = ss->mgp->dev; |
1240 | int work_done; | 1284 | int work_done; |
1241 | 1285 | ||
1242 | /* process as many rx events as NAPI will allow */ | 1286 | /* process as many rx events as NAPI will allow */ |
1243 | work_done = myri10ge_clean_rx_done(mgp, budget); | 1287 | work_done = myri10ge_clean_rx_done(ss, budget); |
1244 | 1288 | ||
1245 | if (work_done < budget) { | 1289 | if (work_done < budget) { |
1246 | netif_rx_complete(netdev, napi); | 1290 | netif_rx_complete(netdev, napi); |
1247 | put_be32(htonl(3), mgp->irq_claim); | 1291 | put_be32(htonl(3), ss->irq_claim); |
1248 | } | 1292 | } |
1249 | return work_done; | 1293 | return work_done; |
1250 | } | 1294 | } |
1251 | 1295 | ||
1252 | static irqreturn_t myri10ge_intr(int irq, void *arg) | 1296 | static irqreturn_t myri10ge_intr(int irq, void *arg) |
1253 | { | 1297 | { |
1254 | struct myri10ge_priv *mgp = arg; | 1298 | struct myri10ge_slice_state *ss = arg; |
1255 | struct mcp_irq_data *stats = mgp->fw_stats; | 1299 | struct myri10ge_priv *mgp = ss->mgp; |
1256 | struct myri10ge_tx_buf *tx = &mgp->tx; | 1300 | struct mcp_irq_data *stats = ss->fw_stats; |
1301 | struct myri10ge_tx_buf *tx = &ss->tx; | ||
1257 | u32 send_done_count; | 1302 | u32 send_done_count; |
1258 | int i; | 1303 | int i; |
1259 | 1304 | ||
@@ -1264,7 +1309,7 @@ static irqreturn_t myri10ge_intr(int irq, void *arg) | |||
1264 | /* low bit indicates receives are present, so schedule | 1309 | /* low bit indicates receives are present, so schedule |
1265 | * napi poll handler */ | 1310 | * napi poll handler */ |
1266 | if (stats->valid & 1) | 1311 | if (stats->valid & 1) |
1267 | netif_rx_schedule(mgp->dev, &mgp->napi); | 1312 | netif_rx_schedule(ss->dev, &ss->napi); |
1268 | 1313 | ||
1269 | if (!mgp->msi_enabled) { | 1314 | if (!mgp->msi_enabled) { |
1270 | put_be32(0, mgp->irq_deassert); | 1315 | put_be32(0, mgp->irq_deassert); |
@@ -1281,7 +1326,7 @@ static irqreturn_t myri10ge_intr(int irq, void *arg) | |||
1281 | /* check for transmit completes and receives */ | 1326 | /* check for transmit completes and receives */ |
1282 | send_done_count = ntohl(stats->send_done_count); | 1327 | send_done_count = ntohl(stats->send_done_count); |
1283 | if (send_done_count != tx->pkt_done) | 1328 | if (send_done_count != tx->pkt_done) |
1284 | myri10ge_tx_done(mgp, (int)send_done_count); | 1329 | myri10ge_tx_done(ss, (int)send_done_count); |
1285 | if (unlikely(i > myri10ge_max_irq_loops)) { | 1330 | if (unlikely(i > myri10ge_max_irq_loops)) { |
1286 | printk(KERN_WARNING "myri10ge: %s: irq stuck?\n", | 1331 | printk(KERN_WARNING "myri10ge: %s: irq stuck?\n", |
1287 | mgp->dev->name); | 1332 | mgp->dev->name); |
@@ -1296,16 +1341,46 @@ static irqreturn_t myri10ge_intr(int irq, void *arg) | |||
1296 | 1341 | ||
1297 | myri10ge_check_statblock(mgp); | 1342 | myri10ge_check_statblock(mgp); |
1298 | 1343 | ||
1299 | put_be32(htonl(3), mgp->irq_claim + 1); | 1344 | put_be32(htonl(3), ss->irq_claim + 1); |
1300 | return (IRQ_HANDLED); | 1345 | return (IRQ_HANDLED); |
1301 | } | 1346 | } |
1302 | 1347 | ||
1303 | static int | 1348 | static int |
1304 | myri10ge_get_settings(struct net_device *netdev, struct ethtool_cmd *cmd) | 1349 | myri10ge_get_settings(struct net_device *netdev, struct ethtool_cmd *cmd) |
1305 | { | 1350 | { |
1351 | struct myri10ge_priv *mgp = netdev_priv(netdev); | ||
1352 | char *ptr; | ||
1353 | int i; | ||
1354 | |||
1306 | cmd->autoneg = AUTONEG_DISABLE; | 1355 | cmd->autoneg = AUTONEG_DISABLE; |
1307 | cmd->speed = SPEED_10000; | 1356 | cmd->speed = SPEED_10000; |
1308 | cmd->duplex = DUPLEX_FULL; | 1357 | cmd->duplex = DUPLEX_FULL; |
1358 | |||
1359 | /* | ||
1360 | * parse the product code to deterimine the interface type | ||
1361 | * (CX4, XFP, Quad Ribbon Fiber) by looking at the character | ||
1362 | * after the 3rd dash in the driver's cached copy of the | ||
1363 | * EEPROM's product code string. | ||
1364 | */ | ||
1365 | ptr = mgp->product_code_string; | ||
1366 | if (ptr == NULL) { | ||
1367 | printk(KERN_ERR "myri10ge: %s: Missing product code\n", | ||
1368 | netdev->name); | ||
1369 | return 0; | ||
1370 | } | ||
1371 | for (i = 0; i < 3; i++, ptr++) { | ||
1372 | ptr = strchr(ptr, '-'); | ||
1373 | if (ptr == NULL) { | ||
1374 | printk(KERN_ERR "myri10ge: %s: Invalid product " | ||
1375 | "code %s\n", netdev->name, | ||
1376 | mgp->product_code_string); | ||
1377 | return 0; | ||
1378 | } | ||
1379 | } | ||
1380 | if (*ptr == 'R' || *ptr == 'Q') { | ||
1381 | /* We've found either an XFP or quad ribbon fiber */ | ||
1382 | cmd->port = PORT_FIBRE; | ||
1383 | } | ||
1309 | return 0; | 1384 | return 0; |
1310 | } | 1385 | } |
1311 | 1386 | ||
@@ -1324,6 +1399,7 @@ static int | |||
1324 | myri10ge_get_coalesce(struct net_device *netdev, struct ethtool_coalesce *coal) | 1399 | myri10ge_get_coalesce(struct net_device *netdev, struct ethtool_coalesce *coal) |
1325 | { | 1400 | { |
1326 | struct myri10ge_priv *mgp = netdev_priv(netdev); | 1401 | struct myri10ge_priv *mgp = netdev_priv(netdev); |
1402 | |||
1327 | coal->rx_coalesce_usecs = mgp->intr_coal_delay; | 1403 | coal->rx_coalesce_usecs = mgp->intr_coal_delay; |
1328 | return 0; | 1404 | return 0; |
1329 | } | 1405 | } |
@@ -1370,10 +1446,10 @@ myri10ge_get_ringparam(struct net_device *netdev, | |||
1370 | { | 1446 | { |
1371 | struct myri10ge_priv *mgp = netdev_priv(netdev); | 1447 | struct myri10ge_priv *mgp = netdev_priv(netdev); |
1372 | 1448 | ||
1373 | ring->rx_mini_max_pending = mgp->rx_small.mask + 1; | 1449 | ring->rx_mini_max_pending = mgp->ss.rx_small.mask + 1; |
1374 | ring->rx_max_pending = mgp->rx_big.mask + 1; | 1450 | ring->rx_max_pending = mgp->ss.rx_big.mask + 1; |
1375 | ring->rx_jumbo_max_pending = 0; | 1451 | ring->rx_jumbo_max_pending = 0; |
1376 | ring->tx_max_pending = mgp->rx_small.mask + 1; | 1452 | ring->tx_max_pending = mgp->ss.rx_small.mask + 1; |
1377 | ring->rx_mini_pending = ring->rx_mini_max_pending; | 1453 | ring->rx_mini_pending = ring->rx_mini_max_pending; |
1378 | ring->rx_pending = ring->rx_max_pending; | 1454 | ring->rx_pending = ring->rx_max_pending; |
1379 | ring->rx_jumbo_pending = ring->rx_jumbo_max_pending; | 1455 | ring->rx_jumbo_pending = ring->rx_jumbo_max_pending; |
@@ -1383,6 +1459,7 @@ myri10ge_get_ringparam(struct net_device *netdev, | |||
1383 | static u32 myri10ge_get_rx_csum(struct net_device *netdev) | 1459 | static u32 myri10ge_get_rx_csum(struct net_device *netdev) |
1384 | { | 1460 | { |
1385 | struct myri10ge_priv *mgp = netdev_priv(netdev); | 1461 | struct myri10ge_priv *mgp = netdev_priv(netdev); |
1462 | |||
1386 | if (mgp->csum_flag) | 1463 | if (mgp->csum_flag) |
1387 | return 1; | 1464 | return 1; |
1388 | else | 1465 | else |
@@ -1392,6 +1469,7 @@ static u32 myri10ge_get_rx_csum(struct net_device *netdev) | |||
1392 | static int myri10ge_set_rx_csum(struct net_device *netdev, u32 csum_enabled) | 1469 | static int myri10ge_set_rx_csum(struct net_device *netdev, u32 csum_enabled) |
1393 | { | 1470 | { |
1394 | struct myri10ge_priv *mgp = netdev_priv(netdev); | 1471 | struct myri10ge_priv *mgp = netdev_priv(netdev); |
1472 | |||
1395 | if (csum_enabled) | 1473 | if (csum_enabled) |
1396 | mgp->csum_flag = MXGEFW_FLAGS_CKSUM; | 1474 | mgp->csum_flag = MXGEFW_FLAGS_CKSUM; |
1397 | else | 1475 | else |
@@ -1411,7 +1489,7 @@ static int myri10ge_set_tso(struct net_device *netdev, u32 tso_enabled) | |||
1411 | return 0; | 1489 | return 0; |
1412 | } | 1490 | } |
1413 | 1491 | ||
1414 | static const char myri10ge_gstrings_stats[][ETH_GSTRING_LEN] = { | 1492 | static const char myri10ge_gstrings_main_stats[][ETH_GSTRING_LEN] = { |
1415 | "rx_packets", "tx_packets", "rx_bytes", "tx_bytes", "rx_errors", | 1493 | "rx_packets", "tx_packets", "rx_bytes", "tx_bytes", "rx_errors", |
1416 | "tx_errors", "rx_dropped", "tx_dropped", "multicast", "collisions", | 1494 | "tx_errors", "rx_dropped", "tx_dropped", "multicast", "collisions", |
1417 | "rx_length_errors", "rx_over_errors", "rx_crc_errors", | 1495 | "rx_length_errors", "rx_over_errors", "rx_crc_errors", |
@@ -1421,28 +1499,39 @@ static const char myri10ge_gstrings_stats[][ETH_GSTRING_LEN] = { | |||
1421 | /* device-specific stats */ | 1499 | /* device-specific stats */ |
1422 | "tx_boundary", "WC", "irq", "MSI", | 1500 | "tx_boundary", "WC", "irq", "MSI", |
1423 | "read_dma_bw_MBs", "write_dma_bw_MBs", "read_write_dma_bw_MBs", | 1501 | "read_dma_bw_MBs", "write_dma_bw_MBs", "read_write_dma_bw_MBs", |
1424 | "serial_number", "tx_pkt_start", "tx_pkt_done", | 1502 | "serial_number", "watchdog_resets", |
1425 | "tx_req", "tx_done", "rx_small_cnt", "rx_big_cnt", | ||
1426 | "wake_queue", "stop_queue", "watchdog_resets", "tx_linearized", | ||
1427 | "link_changes", "link_up", "dropped_link_overflow", | 1503 | "link_changes", "link_up", "dropped_link_overflow", |
1428 | "dropped_link_error_or_filtered", | 1504 | "dropped_link_error_or_filtered", |
1429 | "dropped_pause", "dropped_bad_phy", "dropped_bad_crc32", | 1505 | "dropped_pause", "dropped_bad_phy", "dropped_bad_crc32", |
1430 | "dropped_unicast_filtered", "dropped_multicast_filtered", | 1506 | "dropped_unicast_filtered", "dropped_multicast_filtered", |
1431 | "dropped_runt", "dropped_overrun", "dropped_no_small_buffer", | 1507 | "dropped_runt", "dropped_overrun", "dropped_no_small_buffer", |
1432 | "dropped_no_big_buffer", "LRO aggregated", "LRO flushed", | 1508 | "dropped_no_big_buffer" |
1509 | }; | ||
1510 | |||
1511 | static const char myri10ge_gstrings_slice_stats[][ETH_GSTRING_LEN] = { | ||
1512 | "----------- slice ---------", | ||
1513 | "tx_pkt_start", "tx_pkt_done", "tx_req", "tx_done", | ||
1514 | "rx_small_cnt", "rx_big_cnt", | ||
1515 | "wake_queue", "stop_queue", "tx_linearized", "LRO aggregated", | ||
1516 | "LRO flushed", | ||
1433 | "LRO avg aggr", "LRO no_desc" | 1517 | "LRO avg aggr", "LRO no_desc" |
1434 | }; | 1518 | }; |
1435 | 1519 | ||
1436 | #define MYRI10GE_NET_STATS_LEN 21 | 1520 | #define MYRI10GE_NET_STATS_LEN 21 |
1437 | #define MYRI10GE_STATS_LEN ARRAY_SIZE(myri10ge_gstrings_stats) | 1521 | #define MYRI10GE_MAIN_STATS_LEN ARRAY_SIZE(myri10ge_gstrings_main_stats) |
1522 | #define MYRI10GE_SLICE_STATS_LEN ARRAY_SIZE(myri10ge_gstrings_slice_stats) | ||
1438 | 1523 | ||
1439 | static void | 1524 | static void |
1440 | myri10ge_get_strings(struct net_device *netdev, u32 stringset, u8 * data) | 1525 | myri10ge_get_strings(struct net_device *netdev, u32 stringset, u8 * data) |
1441 | { | 1526 | { |
1442 | switch (stringset) { | 1527 | switch (stringset) { |
1443 | case ETH_SS_STATS: | 1528 | case ETH_SS_STATS: |
1444 | memcpy(data, *myri10ge_gstrings_stats, | 1529 | memcpy(data, *myri10ge_gstrings_main_stats, |
1445 | sizeof(myri10ge_gstrings_stats)); | 1530 | sizeof(myri10ge_gstrings_main_stats)); |
1531 | data += sizeof(myri10ge_gstrings_main_stats); | ||
1532 | memcpy(data, *myri10ge_gstrings_slice_stats, | ||
1533 | sizeof(myri10ge_gstrings_slice_stats)); | ||
1534 | data += sizeof(myri10ge_gstrings_slice_stats); | ||
1446 | break; | 1535 | break; |
1447 | } | 1536 | } |
1448 | } | 1537 | } |
@@ -1451,7 +1540,7 @@ static int myri10ge_get_sset_count(struct net_device *netdev, int sset) | |||
1451 | { | 1540 | { |
1452 | switch (sset) { | 1541 | switch (sset) { |
1453 | case ETH_SS_STATS: | 1542 | case ETH_SS_STATS: |
1454 | return MYRI10GE_STATS_LEN; | 1543 | return MYRI10GE_MAIN_STATS_LEN + MYRI10GE_SLICE_STATS_LEN; |
1455 | default: | 1544 | default: |
1456 | return -EOPNOTSUPP; | 1545 | return -EOPNOTSUPP; |
1457 | } | 1546 | } |
@@ -1462,12 +1551,13 @@ myri10ge_get_ethtool_stats(struct net_device *netdev, | |||
1462 | struct ethtool_stats *stats, u64 * data) | 1551 | struct ethtool_stats *stats, u64 * data) |
1463 | { | 1552 | { |
1464 | struct myri10ge_priv *mgp = netdev_priv(netdev); | 1553 | struct myri10ge_priv *mgp = netdev_priv(netdev); |
1554 | struct myri10ge_slice_state *ss; | ||
1465 | int i; | 1555 | int i; |
1466 | 1556 | ||
1467 | for (i = 0; i < MYRI10GE_NET_STATS_LEN; i++) | 1557 | for (i = 0; i < MYRI10GE_NET_STATS_LEN; i++) |
1468 | data[i] = ((unsigned long *)&mgp->stats)[i]; | 1558 | data[i] = ((unsigned long *)&mgp->stats)[i]; |
1469 | 1559 | ||
1470 | data[i++] = (unsigned int)mgp->tx.boundary; | 1560 | data[i++] = (unsigned int)mgp->tx_boundary; |
1471 | data[i++] = (unsigned int)mgp->wc_enabled; | 1561 | data[i++] = (unsigned int)mgp->wc_enabled; |
1472 | data[i++] = (unsigned int)mgp->pdev->irq; | 1562 | data[i++] = (unsigned int)mgp->pdev->irq; |
1473 | data[i++] = (unsigned int)mgp->msi_enabled; | 1563 | data[i++] = (unsigned int)mgp->msi_enabled; |
@@ -1475,40 +1565,44 @@ myri10ge_get_ethtool_stats(struct net_device *netdev, | |||
1475 | data[i++] = (unsigned int)mgp->write_dma; | 1565 | data[i++] = (unsigned int)mgp->write_dma; |
1476 | data[i++] = (unsigned int)mgp->read_write_dma; | 1566 | data[i++] = (unsigned int)mgp->read_write_dma; |
1477 | data[i++] = (unsigned int)mgp->serial_number; | 1567 | data[i++] = (unsigned int)mgp->serial_number; |
1478 | data[i++] = (unsigned int)mgp->tx.pkt_start; | ||
1479 | data[i++] = (unsigned int)mgp->tx.pkt_done; | ||
1480 | data[i++] = (unsigned int)mgp->tx.req; | ||
1481 | data[i++] = (unsigned int)mgp->tx.done; | ||
1482 | data[i++] = (unsigned int)mgp->rx_small.cnt; | ||
1483 | data[i++] = (unsigned int)mgp->rx_big.cnt; | ||
1484 | data[i++] = (unsigned int)mgp->wake_queue; | ||
1485 | data[i++] = (unsigned int)mgp->stop_queue; | ||
1486 | data[i++] = (unsigned int)mgp->watchdog_resets; | 1568 | data[i++] = (unsigned int)mgp->watchdog_resets; |
1487 | data[i++] = (unsigned int)mgp->tx_linearized; | ||
1488 | data[i++] = (unsigned int)mgp->link_changes; | 1569 | data[i++] = (unsigned int)mgp->link_changes; |
1489 | data[i++] = (unsigned int)ntohl(mgp->fw_stats->link_up); | 1570 | |
1490 | data[i++] = (unsigned int)ntohl(mgp->fw_stats->dropped_link_overflow); | 1571 | /* firmware stats are useful only in the first slice */ |
1491 | data[i++] = | 1572 | ss = &mgp->ss; |
1492 | (unsigned int)ntohl(mgp->fw_stats->dropped_link_error_or_filtered); | 1573 | data[i++] = (unsigned int)ntohl(ss->fw_stats->link_up); |
1493 | data[i++] = (unsigned int)ntohl(mgp->fw_stats->dropped_pause); | 1574 | data[i++] = (unsigned int)ntohl(ss->fw_stats->dropped_link_overflow); |
1494 | data[i++] = (unsigned int)ntohl(mgp->fw_stats->dropped_bad_phy); | ||
1495 | data[i++] = (unsigned int)ntohl(mgp->fw_stats->dropped_bad_crc32); | ||
1496 | data[i++] = | 1575 | data[i++] = |
1497 | (unsigned int)ntohl(mgp->fw_stats->dropped_unicast_filtered); | 1576 | (unsigned int)ntohl(ss->fw_stats->dropped_link_error_or_filtered); |
1577 | data[i++] = (unsigned int)ntohl(ss->fw_stats->dropped_pause); | ||
1578 | data[i++] = (unsigned int)ntohl(ss->fw_stats->dropped_bad_phy); | ||
1579 | data[i++] = (unsigned int)ntohl(ss->fw_stats->dropped_bad_crc32); | ||
1580 | data[i++] = (unsigned int)ntohl(ss->fw_stats->dropped_unicast_filtered); | ||
1498 | data[i++] = | 1581 | data[i++] = |
1499 | (unsigned int)ntohl(mgp->fw_stats->dropped_multicast_filtered); | 1582 | (unsigned int)ntohl(ss->fw_stats->dropped_multicast_filtered); |
1500 | data[i++] = (unsigned int)ntohl(mgp->fw_stats->dropped_runt); | 1583 | data[i++] = (unsigned int)ntohl(ss->fw_stats->dropped_runt); |
1501 | data[i++] = (unsigned int)ntohl(mgp->fw_stats->dropped_overrun); | 1584 | data[i++] = (unsigned int)ntohl(ss->fw_stats->dropped_overrun); |
1502 | data[i++] = (unsigned int)ntohl(mgp->fw_stats->dropped_no_small_buffer); | 1585 | data[i++] = (unsigned int)ntohl(ss->fw_stats->dropped_no_small_buffer); |
1503 | data[i++] = (unsigned int)ntohl(mgp->fw_stats->dropped_no_big_buffer); | 1586 | data[i++] = (unsigned int)ntohl(ss->fw_stats->dropped_no_big_buffer); |
1504 | data[i++] = mgp->rx_done.lro_mgr.stats.aggregated; | 1587 | |
1505 | data[i++] = mgp->rx_done.lro_mgr.stats.flushed; | 1588 | data[i++] = 0; |
1506 | if (mgp->rx_done.lro_mgr.stats.flushed) | 1589 | data[i++] = (unsigned int)ss->tx.pkt_start; |
1507 | data[i++] = mgp->rx_done.lro_mgr.stats.aggregated / | 1590 | data[i++] = (unsigned int)ss->tx.pkt_done; |
1508 | mgp->rx_done.lro_mgr.stats.flushed; | 1591 | data[i++] = (unsigned int)ss->tx.req; |
1592 | data[i++] = (unsigned int)ss->tx.done; | ||
1593 | data[i++] = (unsigned int)ss->rx_small.cnt; | ||
1594 | data[i++] = (unsigned int)ss->rx_big.cnt; | ||
1595 | data[i++] = (unsigned int)ss->tx.wake_queue; | ||
1596 | data[i++] = (unsigned int)ss->tx.stop_queue; | ||
1597 | data[i++] = (unsigned int)ss->tx.linearized; | ||
1598 | data[i++] = ss->rx_done.lro_mgr.stats.aggregated; | ||
1599 | data[i++] = ss->rx_done.lro_mgr.stats.flushed; | ||
1600 | if (ss->rx_done.lro_mgr.stats.flushed) | ||
1601 | data[i++] = ss->rx_done.lro_mgr.stats.aggregated / | ||
1602 | ss->rx_done.lro_mgr.stats.flushed; | ||
1509 | else | 1603 | else |
1510 | data[i++] = 0; | 1604 | data[i++] = 0; |
1511 | data[i++] = mgp->rx_done.lro_mgr.stats.no_desc; | 1605 | data[i++] = ss->rx_done.lro_mgr.stats.no_desc; |
1512 | } | 1606 | } |
1513 | 1607 | ||
1514 | static void myri10ge_set_msglevel(struct net_device *netdev, u32 value) | 1608 | static void myri10ge_set_msglevel(struct net_device *netdev, u32 value) |
@@ -1544,19 +1638,17 @@ static const struct ethtool_ops myri10ge_ethtool_ops = { | |||
1544 | .get_msglevel = myri10ge_get_msglevel | 1638 | .get_msglevel = myri10ge_get_msglevel |
1545 | }; | 1639 | }; |
1546 | 1640 | ||
1547 | static int myri10ge_allocate_rings(struct net_device *dev) | 1641 | static int myri10ge_allocate_rings(struct myri10ge_slice_state *ss) |
1548 | { | 1642 | { |
1549 | struct myri10ge_priv *mgp; | 1643 | struct myri10ge_priv *mgp = ss->mgp; |
1550 | struct myri10ge_cmd cmd; | 1644 | struct myri10ge_cmd cmd; |
1645 | struct net_device *dev = mgp->dev; | ||
1551 | int tx_ring_size, rx_ring_size; | 1646 | int tx_ring_size, rx_ring_size; |
1552 | int tx_ring_entries, rx_ring_entries; | 1647 | int tx_ring_entries, rx_ring_entries; |
1553 | int i, status; | 1648 | int i, status; |
1554 | size_t bytes; | 1649 | size_t bytes; |
1555 | 1650 | ||
1556 | mgp = netdev_priv(dev); | ||
1557 | |||
1558 | /* get ring sizes */ | 1651 | /* get ring sizes */ |
1559 | |||
1560 | status = myri10ge_send_cmd(mgp, MXGEFW_CMD_GET_SEND_RING_SIZE, &cmd, 0); | 1652 | status = myri10ge_send_cmd(mgp, MXGEFW_CMD_GET_SEND_RING_SIZE, &cmd, 0); |
1561 | tx_ring_size = cmd.data0; | 1653 | tx_ring_size = cmd.data0; |
1562 | status |= myri10ge_send_cmd(mgp, MXGEFW_CMD_GET_RX_RING_SIZE, &cmd, 0); | 1654 | status |= myri10ge_send_cmd(mgp, MXGEFW_CMD_GET_RX_RING_SIZE, &cmd, 0); |
@@ -1566,144 +1658,142 @@ static int myri10ge_allocate_rings(struct net_device *dev) | |||
1566 | 1658 | ||
1567 | tx_ring_entries = tx_ring_size / sizeof(struct mcp_kreq_ether_send); | 1659 | tx_ring_entries = tx_ring_size / sizeof(struct mcp_kreq_ether_send); |
1568 | rx_ring_entries = rx_ring_size / sizeof(struct mcp_dma_addr); | 1660 | rx_ring_entries = rx_ring_size / sizeof(struct mcp_dma_addr); |
1569 | mgp->tx.mask = tx_ring_entries - 1; | 1661 | ss->tx.mask = tx_ring_entries - 1; |
1570 | mgp->rx_small.mask = mgp->rx_big.mask = rx_ring_entries - 1; | 1662 | ss->rx_small.mask = ss->rx_big.mask = rx_ring_entries - 1; |
1571 | 1663 | ||
1572 | status = -ENOMEM; | 1664 | status = -ENOMEM; |
1573 | 1665 | ||
1574 | /* allocate the host shadow rings */ | 1666 | /* allocate the host shadow rings */ |
1575 | 1667 | ||
1576 | bytes = 8 + (MYRI10GE_MAX_SEND_DESC_TSO + 4) | 1668 | bytes = 8 + (MYRI10GE_MAX_SEND_DESC_TSO + 4) |
1577 | * sizeof(*mgp->tx.req_list); | 1669 | * sizeof(*ss->tx.req_list); |
1578 | mgp->tx.req_bytes = kzalloc(bytes, GFP_KERNEL); | 1670 | ss->tx.req_bytes = kzalloc(bytes, GFP_KERNEL); |
1579 | if (mgp->tx.req_bytes == NULL) | 1671 | if (ss->tx.req_bytes == NULL) |
1580 | goto abort_with_nothing; | 1672 | goto abort_with_nothing; |
1581 | 1673 | ||
1582 | /* ensure req_list entries are aligned to 8 bytes */ | 1674 | /* ensure req_list entries are aligned to 8 bytes */ |
1583 | mgp->tx.req_list = (struct mcp_kreq_ether_send *) | 1675 | ss->tx.req_list = (struct mcp_kreq_ether_send *) |
1584 | ALIGN((unsigned long)mgp->tx.req_bytes, 8); | 1676 | ALIGN((unsigned long)ss->tx.req_bytes, 8); |
1585 | 1677 | ||
1586 | bytes = rx_ring_entries * sizeof(*mgp->rx_small.shadow); | 1678 | bytes = rx_ring_entries * sizeof(*ss->rx_small.shadow); |
1587 | mgp->rx_small.shadow = kzalloc(bytes, GFP_KERNEL); | 1679 | ss->rx_small.shadow = kzalloc(bytes, GFP_KERNEL); |
1588 | if (mgp->rx_small.shadow == NULL) | 1680 | if (ss->rx_small.shadow == NULL) |
1589 | goto abort_with_tx_req_bytes; | 1681 | goto abort_with_tx_req_bytes; |
1590 | 1682 | ||
1591 | bytes = rx_ring_entries * sizeof(*mgp->rx_big.shadow); | 1683 | bytes = rx_ring_entries * sizeof(*ss->rx_big.shadow); |
1592 | mgp->rx_big.shadow = kzalloc(bytes, GFP_KERNEL); | 1684 | ss->rx_big.shadow = kzalloc(bytes, GFP_KERNEL); |
1593 | if (mgp->rx_big.shadow == NULL) | 1685 | if (ss->rx_big.shadow == NULL) |
1594 | goto abort_with_rx_small_shadow; | 1686 | goto abort_with_rx_small_shadow; |
1595 | 1687 | ||
1596 | /* allocate the host info rings */ | 1688 | /* allocate the host info rings */ |
1597 | 1689 | ||
1598 | bytes = tx_ring_entries * sizeof(*mgp->tx.info); | 1690 | bytes = tx_ring_entries * sizeof(*ss->tx.info); |
1599 | mgp->tx.info = kzalloc(bytes, GFP_KERNEL); | 1691 | ss->tx.info = kzalloc(bytes, GFP_KERNEL); |
1600 | if (mgp->tx.info == NULL) | 1692 | if (ss->tx.info == NULL) |
1601 | goto abort_with_rx_big_shadow; | 1693 | goto abort_with_rx_big_shadow; |
1602 | 1694 | ||
1603 | bytes = rx_ring_entries * sizeof(*mgp->rx_small.info); | 1695 | bytes = rx_ring_entries * sizeof(*ss->rx_small.info); |
1604 | mgp->rx_small.info = kzalloc(bytes, GFP_KERNEL); | 1696 | ss->rx_small.info = kzalloc(bytes, GFP_KERNEL); |
1605 | if (mgp->rx_small.info == NULL) | 1697 | if (ss->rx_small.info == NULL) |
1606 | goto abort_with_tx_info; | 1698 | goto abort_with_tx_info; |
1607 | 1699 | ||
1608 | bytes = rx_ring_entries * sizeof(*mgp->rx_big.info); | 1700 | bytes = rx_ring_entries * sizeof(*ss->rx_big.info); |
1609 | mgp->rx_big.info = kzalloc(bytes, GFP_KERNEL); | 1701 | ss->rx_big.info = kzalloc(bytes, GFP_KERNEL); |
1610 | if (mgp->rx_big.info == NULL) | 1702 | if (ss->rx_big.info == NULL) |
1611 | goto abort_with_rx_small_info; | 1703 | goto abort_with_rx_small_info; |
1612 | 1704 | ||
1613 | /* Fill the receive rings */ | 1705 | /* Fill the receive rings */ |
1614 | mgp->rx_big.cnt = 0; | 1706 | ss->rx_big.cnt = 0; |
1615 | mgp->rx_small.cnt = 0; | 1707 | ss->rx_small.cnt = 0; |
1616 | mgp->rx_big.fill_cnt = 0; | 1708 | ss->rx_big.fill_cnt = 0; |
1617 | mgp->rx_small.fill_cnt = 0; | 1709 | ss->rx_small.fill_cnt = 0; |
1618 | mgp->rx_small.page_offset = MYRI10GE_ALLOC_SIZE; | 1710 | ss->rx_small.page_offset = MYRI10GE_ALLOC_SIZE; |
1619 | mgp->rx_big.page_offset = MYRI10GE_ALLOC_SIZE; | 1711 | ss->rx_big.page_offset = MYRI10GE_ALLOC_SIZE; |
1620 | mgp->rx_small.watchdog_needed = 0; | 1712 | ss->rx_small.watchdog_needed = 0; |
1621 | mgp->rx_big.watchdog_needed = 0; | 1713 | ss->rx_big.watchdog_needed = 0; |
1622 | myri10ge_alloc_rx_pages(mgp, &mgp->rx_small, | 1714 | myri10ge_alloc_rx_pages(mgp, &ss->rx_small, |
1623 | mgp->small_bytes + MXGEFW_PAD, 0); | 1715 | mgp->small_bytes + MXGEFW_PAD, 0); |
1624 | 1716 | ||
1625 | if (mgp->rx_small.fill_cnt < mgp->rx_small.mask + 1) { | 1717 | if (ss->rx_small.fill_cnt < ss->rx_small.mask + 1) { |
1626 | printk(KERN_ERR "myri10ge: %s: alloced only %d small bufs\n", | 1718 | printk(KERN_ERR "myri10ge: %s: alloced only %d small bufs\n", |
1627 | dev->name, mgp->rx_small.fill_cnt); | 1719 | dev->name, ss->rx_small.fill_cnt); |
1628 | goto abort_with_rx_small_ring; | 1720 | goto abort_with_rx_small_ring; |
1629 | } | 1721 | } |
1630 | 1722 | ||
1631 | myri10ge_alloc_rx_pages(mgp, &mgp->rx_big, mgp->big_bytes, 0); | 1723 | myri10ge_alloc_rx_pages(mgp, &ss->rx_big, mgp->big_bytes, 0); |
1632 | if (mgp->rx_big.fill_cnt < mgp->rx_big.mask + 1) { | 1724 | if (ss->rx_big.fill_cnt < ss->rx_big.mask + 1) { |
1633 | printk(KERN_ERR "myri10ge: %s: alloced only %d big bufs\n", | 1725 | printk(KERN_ERR "myri10ge: %s: alloced only %d big bufs\n", |
1634 | dev->name, mgp->rx_big.fill_cnt); | 1726 | dev->name, ss->rx_big.fill_cnt); |
1635 | goto abort_with_rx_big_ring; | 1727 | goto abort_with_rx_big_ring; |
1636 | } | 1728 | } |
1637 | 1729 | ||
1638 | return 0; | 1730 | return 0; |
1639 | 1731 | ||
1640 | abort_with_rx_big_ring: | 1732 | abort_with_rx_big_ring: |
1641 | for (i = mgp->rx_big.cnt; i < mgp->rx_big.fill_cnt; i++) { | 1733 | for (i = ss->rx_big.cnt; i < ss->rx_big.fill_cnt; i++) { |
1642 | int idx = i & mgp->rx_big.mask; | 1734 | int idx = i & ss->rx_big.mask; |
1643 | myri10ge_unmap_rx_page(mgp->pdev, &mgp->rx_big.info[idx], | 1735 | myri10ge_unmap_rx_page(mgp->pdev, &ss->rx_big.info[idx], |
1644 | mgp->big_bytes); | 1736 | mgp->big_bytes); |
1645 | put_page(mgp->rx_big.info[idx].page); | 1737 | put_page(ss->rx_big.info[idx].page); |
1646 | } | 1738 | } |
1647 | 1739 | ||
1648 | abort_with_rx_small_ring: | 1740 | abort_with_rx_small_ring: |
1649 | for (i = mgp->rx_small.cnt; i < mgp->rx_small.fill_cnt; i++) { | 1741 | for (i = ss->rx_small.cnt; i < ss->rx_small.fill_cnt; i++) { |
1650 | int idx = i & mgp->rx_small.mask; | 1742 | int idx = i & ss->rx_small.mask; |
1651 | myri10ge_unmap_rx_page(mgp->pdev, &mgp->rx_small.info[idx], | 1743 | myri10ge_unmap_rx_page(mgp->pdev, &ss->rx_small.info[idx], |
1652 | mgp->small_bytes + MXGEFW_PAD); | 1744 | mgp->small_bytes + MXGEFW_PAD); |
1653 | put_page(mgp->rx_small.info[idx].page); | 1745 | put_page(ss->rx_small.info[idx].page); |
1654 | } | 1746 | } |
1655 | 1747 | ||
1656 | kfree(mgp->rx_big.info); | 1748 | kfree(ss->rx_big.info); |
1657 | 1749 | ||
1658 | abort_with_rx_small_info: | 1750 | abort_with_rx_small_info: |
1659 | kfree(mgp->rx_small.info); | 1751 | kfree(ss->rx_small.info); |
1660 | 1752 | ||
1661 | abort_with_tx_info: | 1753 | abort_with_tx_info: |
1662 | kfree(mgp->tx.info); | 1754 | kfree(ss->tx.info); |
1663 | 1755 | ||
1664 | abort_with_rx_big_shadow: | 1756 | abort_with_rx_big_shadow: |
1665 | kfree(mgp->rx_big.shadow); | 1757 | kfree(ss->rx_big.shadow); |
1666 | 1758 | ||
1667 | abort_with_rx_small_shadow: | 1759 | abort_with_rx_small_shadow: |
1668 | kfree(mgp->rx_small.shadow); | 1760 | kfree(ss->rx_small.shadow); |
1669 | 1761 | ||
1670 | abort_with_tx_req_bytes: | 1762 | abort_with_tx_req_bytes: |
1671 | kfree(mgp->tx.req_bytes); | 1763 | kfree(ss->tx.req_bytes); |
1672 | mgp->tx.req_bytes = NULL; | 1764 | ss->tx.req_bytes = NULL; |
1673 | mgp->tx.req_list = NULL; | 1765 | ss->tx.req_list = NULL; |
1674 | 1766 | ||
1675 | abort_with_nothing: | 1767 | abort_with_nothing: |
1676 | return status; | 1768 | return status; |
1677 | } | 1769 | } |
1678 | 1770 | ||
1679 | static void myri10ge_free_rings(struct net_device *dev) | 1771 | static void myri10ge_free_rings(struct myri10ge_slice_state *ss) |
1680 | { | 1772 | { |
1681 | struct myri10ge_priv *mgp; | 1773 | struct myri10ge_priv *mgp = ss->mgp; |
1682 | struct sk_buff *skb; | 1774 | struct sk_buff *skb; |
1683 | struct myri10ge_tx_buf *tx; | 1775 | struct myri10ge_tx_buf *tx; |
1684 | int i, len, idx; | 1776 | int i, len, idx; |
1685 | 1777 | ||
1686 | mgp = netdev_priv(dev); | 1778 | for (i = ss->rx_big.cnt; i < ss->rx_big.fill_cnt; i++) { |
1687 | 1779 | idx = i & ss->rx_big.mask; | |
1688 | for (i = mgp->rx_big.cnt; i < mgp->rx_big.fill_cnt; i++) { | 1780 | if (i == ss->rx_big.fill_cnt - 1) |
1689 | idx = i & mgp->rx_big.mask; | 1781 | ss->rx_big.info[idx].page_offset = MYRI10GE_ALLOC_SIZE; |
1690 | if (i == mgp->rx_big.fill_cnt - 1) | 1782 | myri10ge_unmap_rx_page(mgp->pdev, &ss->rx_big.info[idx], |
1691 | mgp->rx_big.info[idx].page_offset = MYRI10GE_ALLOC_SIZE; | ||
1692 | myri10ge_unmap_rx_page(mgp->pdev, &mgp->rx_big.info[idx], | ||
1693 | mgp->big_bytes); | 1783 | mgp->big_bytes); |
1694 | put_page(mgp->rx_big.info[idx].page); | 1784 | put_page(ss->rx_big.info[idx].page); |
1695 | } | 1785 | } |
1696 | 1786 | ||
1697 | for (i = mgp->rx_small.cnt; i < mgp->rx_small.fill_cnt; i++) { | 1787 | for (i = ss->rx_small.cnt; i < ss->rx_small.fill_cnt; i++) { |
1698 | idx = i & mgp->rx_small.mask; | 1788 | idx = i & ss->rx_small.mask; |
1699 | if (i == mgp->rx_small.fill_cnt - 1) | 1789 | if (i == ss->rx_small.fill_cnt - 1) |
1700 | mgp->rx_small.info[idx].page_offset = | 1790 | ss->rx_small.info[idx].page_offset = |
1701 | MYRI10GE_ALLOC_SIZE; | 1791 | MYRI10GE_ALLOC_SIZE; |
1702 | myri10ge_unmap_rx_page(mgp->pdev, &mgp->rx_small.info[idx], | 1792 | myri10ge_unmap_rx_page(mgp->pdev, &ss->rx_small.info[idx], |
1703 | mgp->small_bytes + MXGEFW_PAD); | 1793 | mgp->small_bytes + MXGEFW_PAD); |
1704 | put_page(mgp->rx_small.info[idx].page); | 1794 | put_page(ss->rx_small.info[idx].page); |
1705 | } | 1795 | } |
1706 | tx = &mgp->tx; | 1796 | tx = &ss->tx; |
1707 | while (tx->done != tx->req) { | 1797 | while (tx->done != tx->req) { |
1708 | idx = tx->done & tx->mask; | 1798 | idx = tx->done & tx->mask; |
1709 | skb = tx->info[idx].skb; | 1799 | skb = tx->info[idx].skb; |
@@ -1714,7 +1804,7 @@ static void myri10ge_free_rings(struct net_device *dev) | |||
1714 | len = pci_unmap_len(&tx->info[idx], len); | 1804 | len = pci_unmap_len(&tx->info[idx], len); |
1715 | pci_unmap_len_set(&tx->info[idx], len, 0); | 1805 | pci_unmap_len_set(&tx->info[idx], len, 0); |
1716 | if (skb) { | 1806 | if (skb) { |
1717 | mgp->stats.tx_dropped++; | 1807 | ss->stats.tx_dropped++; |
1718 | dev_kfree_skb_any(skb); | 1808 | dev_kfree_skb_any(skb); |
1719 | if (len) | 1809 | if (len) |
1720 | pci_unmap_single(mgp->pdev, | 1810 | pci_unmap_single(mgp->pdev, |
@@ -1729,19 +1819,19 @@ static void myri10ge_free_rings(struct net_device *dev) | |||
1729 | PCI_DMA_TODEVICE); | 1819 | PCI_DMA_TODEVICE); |
1730 | } | 1820 | } |
1731 | } | 1821 | } |
1732 | kfree(mgp->rx_big.info); | 1822 | kfree(ss->rx_big.info); |
1733 | 1823 | ||
1734 | kfree(mgp->rx_small.info); | 1824 | kfree(ss->rx_small.info); |
1735 | 1825 | ||
1736 | kfree(mgp->tx.info); | 1826 | kfree(ss->tx.info); |
1737 | 1827 | ||
1738 | kfree(mgp->rx_big.shadow); | 1828 | kfree(ss->rx_big.shadow); |
1739 | 1829 | ||
1740 | kfree(mgp->rx_small.shadow); | 1830 | kfree(ss->rx_small.shadow); |
1741 | 1831 | ||
1742 | kfree(mgp->tx.req_bytes); | 1832 | kfree(ss->tx.req_bytes); |
1743 | mgp->tx.req_bytes = NULL; | 1833 | ss->tx.req_bytes = NULL; |
1744 | mgp->tx.req_list = NULL; | 1834 | ss->tx.req_list = NULL; |
1745 | } | 1835 | } |
1746 | 1836 | ||
1747 | static int myri10ge_request_irq(struct myri10ge_priv *mgp) | 1837 | static int myri10ge_request_irq(struct myri10ge_priv *mgp) |
@@ -1840,13 +1930,11 @@ myri10ge_get_frag_header(struct skb_frag_struct *frag, void **mac_hdr, | |||
1840 | 1930 | ||
1841 | static int myri10ge_open(struct net_device *dev) | 1931 | static int myri10ge_open(struct net_device *dev) |
1842 | { | 1932 | { |
1843 | struct myri10ge_priv *mgp; | 1933 | struct myri10ge_priv *mgp = netdev_priv(dev); |
1844 | struct myri10ge_cmd cmd; | 1934 | struct myri10ge_cmd cmd; |
1845 | struct net_lro_mgr *lro_mgr; | 1935 | struct net_lro_mgr *lro_mgr; |
1846 | int status, big_pow2; | 1936 | int status, big_pow2; |
1847 | 1937 | ||
1848 | mgp = netdev_priv(dev); | ||
1849 | |||
1850 | if (mgp->running != MYRI10GE_ETH_STOPPED) | 1938 | if (mgp->running != MYRI10GE_ETH_STOPPED) |
1851 | return -EBUSY; | 1939 | return -EBUSY; |
1852 | 1940 | ||
@@ -1883,16 +1971,16 @@ static int myri10ge_open(struct net_device *dev) | |||
1883 | /* get the lanai pointers to the send and receive rings */ | 1971 | /* get the lanai pointers to the send and receive rings */ |
1884 | 1972 | ||
1885 | status |= myri10ge_send_cmd(mgp, MXGEFW_CMD_GET_SEND_OFFSET, &cmd, 0); | 1973 | status |= myri10ge_send_cmd(mgp, MXGEFW_CMD_GET_SEND_OFFSET, &cmd, 0); |
1886 | mgp->tx.lanai = | 1974 | mgp->ss.tx.lanai = |
1887 | (struct mcp_kreq_ether_send __iomem *)(mgp->sram + cmd.data0); | 1975 | (struct mcp_kreq_ether_send __iomem *)(mgp->sram + cmd.data0); |
1888 | 1976 | ||
1889 | status |= | 1977 | status |= |
1890 | myri10ge_send_cmd(mgp, MXGEFW_CMD_GET_SMALL_RX_OFFSET, &cmd, 0); | 1978 | myri10ge_send_cmd(mgp, MXGEFW_CMD_GET_SMALL_RX_OFFSET, &cmd, 0); |
1891 | mgp->rx_small.lanai = | 1979 | mgp->ss.rx_small.lanai = |
1892 | (struct mcp_kreq_ether_recv __iomem *)(mgp->sram + cmd.data0); | 1980 | (struct mcp_kreq_ether_recv __iomem *)(mgp->sram + cmd.data0); |
1893 | 1981 | ||
1894 | status |= myri10ge_send_cmd(mgp, MXGEFW_CMD_GET_BIG_RX_OFFSET, &cmd, 0); | 1982 | status |= myri10ge_send_cmd(mgp, MXGEFW_CMD_GET_BIG_RX_OFFSET, &cmd, 0); |
1895 | mgp->rx_big.lanai = | 1983 | mgp->ss.rx_big.lanai = |
1896 | (struct mcp_kreq_ether_recv __iomem *)(mgp->sram + cmd.data0); | 1984 | (struct mcp_kreq_ether_recv __iomem *)(mgp->sram + cmd.data0); |
1897 | 1985 | ||
1898 | if (status != 0) { | 1986 | if (status != 0) { |
@@ -1904,15 +1992,15 @@ static int myri10ge_open(struct net_device *dev) | |||
1904 | } | 1992 | } |
1905 | 1993 | ||
1906 | if (myri10ge_wcfifo && mgp->wc_enabled) { | 1994 | if (myri10ge_wcfifo && mgp->wc_enabled) { |
1907 | mgp->tx.wc_fifo = (u8 __iomem *) mgp->sram + MXGEFW_ETH_SEND_4; | 1995 | mgp->ss.tx.wc_fifo = (u8 __iomem *) mgp->sram + MXGEFW_ETH_SEND_4; |
1908 | mgp->rx_small.wc_fifo = | 1996 | mgp->ss.rx_small.wc_fifo = |
1909 | (u8 __iomem *) mgp->sram + MXGEFW_ETH_RECV_SMALL; | 1997 | (u8 __iomem *) mgp->sram + MXGEFW_ETH_RECV_SMALL; |
1910 | mgp->rx_big.wc_fifo = | 1998 | mgp->ss.rx_big.wc_fifo = |
1911 | (u8 __iomem *) mgp->sram + MXGEFW_ETH_RECV_BIG; | 1999 | (u8 __iomem *) mgp->sram + MXGEFW_ETH_RECV_BIG; |
1912 | } else { | 2000 | } else { |
1913 | mgp->tx.wc_fifo = NULL; | 2001 | mgp->ss.tx.wc_fifo = NULL; |
1914 | mgp->rx_small.wc_fifo = NULL; | 2002 | mgp->ss.rx_small.wc_fifo = NULL; |
1915 | mgp->rx_big.wc_fifo = NULL; | 2003 | mgp->ss.rx_big.wc_fifo = NULL; |
1916 | } | 2004 | } |
1917 | 2005 | ||
1918 | /* Firmware needs the big buff size as a power of 2. Lie and | 2006 | /* Firmware needs the big buff size as a power of 2. Lie and |
@@ -1929,7 +2017,7 @@ static int myri10ge_open(struct net_device *dev) | |||
1929 | mgp->big_bytes = big_pow2; | 2017 | mgp->big_bytes = big_pow2; |
1930 | } | 2018 | } |
1931 | 2019 | ||
1932 | status = myri10ge_allocate_rings(dev); | 2020 | status = myri10ge_allocate_rings(&mgp->ss); |
1933 | if (status != 0) | 2021 | if (status != 0) |
1934 | goto abort_with_irq; | 2022 | goto abort_with_irq; |
1935 | 2023 | ||
@@ -1948,12 +2036,12 @@ static int myri10ge_open(struct net_device *dev) | |||
1948 | goto abort_with_rings; | 2036 | goto abort_with_rings; |
1949 | } | 2037 | } |
1950 | 2038 | ||
1951 | cmd.data0 = MYRI10GE_LOWPART_TO_U32(mgp->fw_stats_bus); | 2039 | cmd.data0 = MYRI10GE_LOWPART_TO_U32(mgp->ss.fw_stats_bus); |
1952 | cmd.data1 = MYRI10GE_HIGHPART_TO_U32(mgp->fw_stats_bus); | 2040 | cmd.data1 = MYRI10GE_HIGHPART_TO_U32(mgp->ss.fw_stats_bus); |
1953 | cmd.data2 = sizeof(struct mcp_irq_data); | 2041 | cmd.data2 = sizeof(struct mcp_irq_data); |
1954 | status = myri10ge_send_cmd(mgp, MXGEFW_CMD_SET_STATS_DMA_V2, &cmd, 0); | 2042 | status = myri10ge_send_cmd(mgp, MXGEFW_CMD_SET_STATS_DMA_V2, &cmd, 0); |
1955 | if (status == -ENOSYS) { | 2043 | if (status == -ENOSYS) { |
1956 | dma_addr_t bus = mgp->fw_stats_bus; | 2044 | dma_addr_t bus = mgp->ss.fw_stats_bus; |
1957 | bus += offsetof(struct mcp_irq_data, send_done_count); | 2045 | bus += offsetof(struct mcp_irq_data, send_done_count); |
1958 | cmd.data0 = MYRI10GE_LOWPART_TO_U32(bus); | 2046 | cmd.data0 = MYRI10GE_LOWPART_TO_U32(bus); |
1959 | cmd.data1 = MYRI10GE_HIGHPART_TO_U32(bus); | 2047 | cmd.data1 = MYRI10GE_HIGHPART_TO_U32(bus); |
@@ -1974,20 +2062,20 @@ static int myri10ge_open(struct net_device *dev) | |||
1974 | mgp->link_state = ~0U; | 2062 | mgp->link_state = ~0U; |
1975 | mgp->rdma_tags_available = 15; | 2063 | mgp->rdma_tags_available = 15; |
1976 | 2064 | ||
1977 | lro_mgr = &mgp->rx_done.lro_mgr; | 2065 | lro_mgr = &mgp->ss.rx_done.lro_mgr; |
1978 | lro_mgr->dev = dev; | 2066 | lro_mgr->dev = dev; |
1979 | lro_mgr->features = LRO_F_NAPI; | 2067 | lro_mgr->features = LRO_F_NAPI; |
1980 | lro_mgr->ip_summed = CHECKSUM_COMPLETE; | 2068 | lro_mgr->ip_summed = CHECKSUM_COMPLETE; |
1981 | lro_mgr->ip_summed_aggr = CHECKSUM_UNNECESSARY; | 2069 | lro_mgr->ip_summed_aggr = CHECKSUM_UNNECESSARY; |
1982 | lro_mgr->max_desc = MYRI10GE_MAX_LRO_DESCRIPTORS; | 2070 | lro_mgr->max_desc = MYRI10GE_MAX_LRO_DESCRIPTORS; |
1983 | lro_mgr->lro_arr = mgp->rx_done.lro_desc; | 2071 | lro_mgr->lro_arr = mgp->ss.rx_done.lro_desc; |
1984 | lro_mgr->get_frag_header = myri10ge_get_frag_header; | 2072 | lro_mgr->get_frag_header = myri10ge_get_frag_header; |
1985 | lro_mgr->max_aggr = myri10ge_lro_max_pkts; | 2073 | lro_mgr->max_aggr = myri10ge_lro_max_pkts; |
1986 | lro_mgr->frag_align_pad = 2; | 2074 | lro_mgr->frag_align_pad = 2; |
1987 | if (lro_mgr->max_aggr > MAX_SKB_FRAGS) | 2075 | if (lro_mgr->max_aggr > MAX_SKB_FRAGS) |
1988 | lro_mgr->max_aggr = MAX_SKB_FRAGS; | 2076 | lro_mgr->max_aggr = MAX_SKB_FRAGS; |
1989 | 2077 | ||
1990 | napi_enable(&mgp->napi); /* must happen prior to any irq */ | 2078 | napi_enable(&mgp->ss.napi); /* must happen prior to any irq */ |
1991 | 2079 | ||
1992 | status = myri10ge_send_cmd(mgp, MXGEFW_CMD_ETHERNET_UP, &cmd, 0); | 2080 | status = myri10ge_send_cmd(mgp, MXGEFW_CMD_ETHERNET_UP, &cmd, 0); |
1993 | if (status) { | 2081 | if (status) { |
@@ -1996,8 +2084,8 @@ static int myri10ge_open(struct net_device *dev) | |||
1996 | goto abort_with_rings; | 2084 | goto abort_with_rings; |
1997 | } | 2085 | } |
1998 | 2086 | ||
1999 | mgp->wake_queue = 0; | 2087 | mgp->ss.tx.wake_queue = 0; |
2000 | mgp->stop_queue = 0; | 2088 | mgp->ss.tx.stop_queue = 0; |
2001 | mgp->running = MYRI10GE_ETH_RUNNING; | 2089 | mgp->running = MYRI10GE_ETH_RUNNING; |
2002 | mgp->watchdog_timer.expires = jiffies + myri10ge_watchdog_timeout * HZ; | 2090 | mgp->watchdog_timer.expires = jiffies + myri10ge_watchdog_timeout * HZ; |
2003 | add_timer(&mgp->watchdog_timer); | 2091 | add_timer(&mgp->watchdog_timer); |
@@ -2005,7 +2093,7 @@ static int myri10ge_open(struct net_device *dev) | |||
2005 | return 0; | 2093 | return 0; |
2006 | 2094 | ||
2007 | abort_with_rings: | 2095 | abort_with_rings: |
2008 | myri10ge_free_rings(dev); | 2096 | myri10ge_free_rings(&mgp->ss); |
2009 | 2097 | ||
2010 | abort_with_irq: | 2098 | abort_with_irq: |
2011 | myri10ge_free_irq(mgp); | 2099 | myri10ge_free_irq(mgp); |
@@ -2017,21 +2105,19 @@ abort_with_nothing: | |||
2017 | 2105 | ||
2018 | static int myri10ge_close(struct net_device *dev) | 2106 | static int myri10ge_close(struct net_device *dev) |
2019 | { | 2107 | { |
2020 | struct myri10ge_priv *mgp; | 2108 | struct myri10ge_priv *mgp = netdev_priv(dev); |
2021 | struct myri10ge_cmd cmd; | 2109 | struct myri10ge_cmd cmd; |
2022 | int status, old_down_cnt; | 2110 | int status, old_down_cnt; |
2023 | 2111 | ||
2024 | mgp = netdev_priv(dev); | ||
2025 | |||
2026 | if (mgp->running != MYRI10GE_ETH_RUNNING) | 2112 | if (mgp->running != MYRI10GE_ETH_RUNNING) |
2027 | return 0; | 2113 | return 0; |
2028 | 2114 | ||
2029 | if (mgp->tx.req_bytes == NULL) | 2115 | if (mgp->ss.tx.req_bytes == NULL) |
2030 | return 0; | 2116 | return 0; |
2031 | 2117 | ||
2032 | del_timer_sync(&mgp->watchdog_timer); | 2118 | del_timer_sync(&mgp->watchdog_timer); |
2033 | mgp->running = MYRI10GE_ETH_STOPPING; | 2119 | mgp->running = MYRI10GE_ETH_STOPPING; |
2034 | napi_disable(&mgp->napi); | 2120 | napi_disable(&mgp->ss.napi); |
2035 | netif_carrier_off(dev); | 2121 | netif_carrier_off(dev); |
2036 | netif_stop_queue(dev); | 2122 | netif_stop_queue(dev); |
2037 | old_down_cnt = mgp->down_cnt; | 2123 | old_down_cnt = mgp->down_cnt; |
@@ -2047,7 +2133,7 @@ static int myri10ge_close(struct net_device *dev) | |||
2047 | 2133 | ||
2048 | netif_tx_disable(dev); | 2134 | netif_tx_disable(dev); |
2049 | myri10ge_free_irq(mgp); | 2135 | myri10ge_free_irq(mgp); |
2050 | myri10ge_free_rings(dev); | 2136 | myri10ge_free_rings(&mgp->ss); |
2051 | 2137 | ||
2052 | mgp->running = MYRI10GE_ETH_STOPPED; | 2138 | mgp->running = MYRI10GE_ETH_STOPPED; |
2053 | return 0; | 2139 | return 0; |
@@ -2143,7 +2229,7 @@ myri10ge_submit_req_wc(struct myri10ge_tx_buf *tx, | |||
2143 | 2229 | ||
2144 | /* | 2230 | /* |
2145 | * Transmit a packet. We need to split the packet so that a single | 2231 | * Transmit a packet. We need to split the packet so that a single |
2146 | * segment does not cross myri10ge->tx.boundary, so this makes segment | 2232 | * segment does not cross myri10ge->tx_boundary, so this makes segment |
2147 | * counting tricky. So rather than try to count segments up front, we | 2233 | * counting tricky. So rather than try to count segments up front, we |
2148 | * just give up if there are too few segments to hold a reasonably | 2234 | * just give up if there are too few segments to hold a reasonably |
2149 | * fragmented packet currently available. If we run | 2235 | * fragmented packet currently available. If we run |
@@ -2154,8 +2240,9 @@ myri10ge_submit_req_wc(struct myri10ge_tx_buf *tx, | |||
2154 | static int myri10ge_xmit(struct sk_buff *skb, struct net_device *dev) | 2240 | static int myri10ge_xmit(struct sk_buff *skb, struct net_device *dev) |
2155 | { | 2241 | { |
2156 | struct myri10ge_priv *mgp = netdev_priv(dev); | 2242 | struct myri10ge_priv *mgp = netdev_priv(dev); |
2243 | struct myri10ge_slice_state *ss; | ||
2157 | struct mcp_kreq_ether_send *req; | 2244 | struct mcp_kreq_ether_send *req; |
2158 | struct myri10ge_tx_buf *tx = &mgp->tx; | 2245 | struct myri10ge_tx_buf *tx; |
2159 | struct skb_frag_struct *frag; | 2246 | struct skb_frag_struct *frag; |
2160 | dma_addr_t bus; | 2247 | dma_addr_t bus; |
2161 | u32 low; | 2248 | u32 low; |
@@ -2166,6 +2253,9 @@ static int myri10ge_xmit(struct sk_buff *skb, struct net_device *dev) | |||
2166 | int cum_len, seglen, boundary, rdma_count; | 2253 | int cum_len, seglen, boundary, rdma_count; |
2167 | u8 flags, odd_flag; | 2254 | u8 flags, odd_flag; |
2168 | 2255 | ||
2256 | /* always transmit through slot 0 */ | ||
2257 | ss = &mgp->ss; | ||
2258 | tx = &ss->tx; | ||
2169 | again: | 2259 | again: |
2170 | req = tx->req_list; | 2260 | req = tx->req_list; |
2171 | avail = tx->mask - 1 - (tx->req - tx->done); | 2261 | avail = tx->mask - 1 - (tx->req - tx->done); |
@@ -2180,7 +2270,7 @@ again: | |||
2180 | 2270 | ||
2181 | if ((unlikely(avail < max_segments))) { | 2271 | if ((unlikely(avail < max_segments))) { |
2182 | /* we are out of transmit resources */ | 2272 | /* we are out of transmit resources */ |
2183 | mgp->stop_queue++; | 2273 | tx->stop_queue++; |
2184 | netif_stop_queue(dev); | 2274 | netif_stop_queue(dev); |
2185 | return 1; | 2275 | return 1; |
2186 | } | 2276 | } |
@@ -2242,7 +2332,7 @@ again: | |||
2242 | if (skb_padto(skb, ETH_ZLEN)) { | 2332 | if (skb_padto(skb, ETH_ZLEN)) { |
2243 | /* The packet is gone, so we must | 2333 | /* The packet is gone, so we must |
2244 | * return 0 */ | 2334 | * return 0 */ |
2245 | mgp->stats.tx_dropped += 1; | 2335 | ss->stats.tx_dropped += 1; |
2246 | return 0; | 2336 | return 0; |
2247 | } | 2337 | } |
2248 | /* adjust the len to account for the zero pad | 2338 | /* adjust the len to account for the zero pad |
@@ -2284,7 +2374,7 @@ again: | |||
2284 | 2374 | ||
2285 | while (1) { | 2375 | while (1) { |
2286 | /* Break the SKB or Fragment up into pieces which | 2376 | /* Break the SKB or Fragment up into pieces which |
2287 | * do not cross mgp->tx.boundary */ | 2377 | * do not cross mgp->tx_boundary */ |
2288 | low = MYRI10GE_LOWPART_TO_U32(bus); | 2378 | low = MYRI10GE_LOWPART_TO_U32(bus); |
2289 | high_swapped = htonl(MYRI10GE_HIGHPART_TO_U32(bus)); | 2379 | high_swapped = htonl(MYRI10GE_HIGHPART_TO_U32(bus)); |
2290 | while (len) { | 2380 | while (len) { |
@@ -2294,7 +2384,8 @@ again: | |||
2294 | if (unlikely(count == max_segments)) | 2384 | if (unlikely(count == max_segments)) |
2295 | goto abort_linearize; | 2385 | goto abort_linearize; |
2296 | 2386 | ||
2297 | boundary = (low + tx->boundary) & ~(tx->boundary - 1); | 2387 | boundary = |
2388 | (low + mgp->tx_boundary) & ~(mgp->tx_boundary - 1); | ||
2298 | seglen = boundary - low; | 2389 | seglen = boundary - low; |
2299 | if (seglen > len) | 2390 | if (seglen > len) |
2300 | seglen = len; | 2391 | seglen = len; |
@@ -2378,7 +2469,7 @@ again: | |||
2378 | myri10ge_submit_req_wc(tx, tx->req_list, count); | 2469 | myri10ge_submit_req_wc(tx, tx->req_list, count); |
2379 | tx->pkt_start++; | 2470 | tx->pkt_start++; |
2380 | if ((avail - count) < MXGEFW_MAX_SEND_DESC) { | 2471 | if ((avail - count) < MXGEFW_MAX_SEND_DESC) { |
2381 | mgp->stop_queue++; | 2472 | tx->stop_queue++; |
2382 | netif_stop_queue(dev); | 2473 | netif_stop_queue(dev); |
2383 | } | 2474 | } |
2384 | dev->trans_start = jiffies; | 2475 | dev->trans_start = jiffies; |
@@ -2420,12 +2511,12 @@ abort_linearize: | |||
2420 | if (skb_linearize(skb)) | 2511 | if (skb_linearize(skb)) |
2421 | goto drop; | 2512 | goto drop; |
2422 | 2513 | ||
2423 | mgp->tx_linearized++; | 2514 | tx->linearized++; |
2424 | goto again; | 2515 | goto again; |
2425 | 2516 | ||
2426 | drop: | 2517 | drop: |
2427 | dev_kfree_skb_any(skb); | 2518 | dev_kfree_skb_any(skb); |
2428 | mgp->stats.tx_dropped += 1; | 2519 | ss->stats.tx_dropped += 1; |
2429 | return 0; | 2520 | return 0; |
2430 | 2521 | ||
2431 | } | 2522 | } |
@@ -2433,7 +2524,7 @@ drop: | |||
2433 | static int myri10ge_sw_tso(struct sk_buff *skb, struct net_device *dev) | 2524 | static int myri10ge_sw_tso(struct sk_buff *skb, struct net_device *dev) |
2434 | { | 2525 | { |
2435 | struct sk_buff *segs, *curr; | 2526 | struct sk_buff *segs, *curr; |
2436 | struct myri10ge_priv *mgp = dev->priv; | 2527 | struct myri10ge_priv *mgp = netdev_priv(dev); |
2437 | int status; | 2528 | int status; |
2438 | 2529 | ||
2439 | segs = skb_gso_segment(skb, dev->features & ~NETIF_F_TSO6); | 2530 | segs = skb_gso_segment(skb, dev->features & ~NETIF_F_TSO6); |
@@ -2473,14 +2564,13 @@ static struct net_device_stats *myri10ge_get_stats(struct net_device *dev) | |||
2473 | 2564 | ||
2474 | static void myri10ge_set_multicast_list(struct net_device *dev) | 2565 | static void myri10ge_set_multicast_list(struct net_device *dev) |
2475 | { | 2566 | { |
2567 | struct myri10ge_priv *mgp = netdev_priv(dev); | ||
2476 | struct myri10ge_cmd cmd; | 2568 | struct myri10ge_cmd cmd; |
2477 | struct myri10ge_priv *mgp; | ||
2478 | struct dev_mc_list *mc_list; | 2569 | struct dev_mc_list *mc_list; |
2479 | __be32 data[2] = { 0, 0 }; | 2570 | __be32 data[2] = { 0, 0 }; |
2480 | int err; | 2571 | int err; |
2481 | DECLARE_MAC_BUF(mac); | 2572 | DECLARE_MAC_BUF(mac); |
2482 | 2573 | ||
2483 | mgp = netdev_priv(dev); | ||
2484 | /* can be called from atomic contexts, | 2574 | /* can be called from atomic contexts, |
2485 | * pass 1 to force atomicity in myri10ge_send_cmd() */ | 2575 | * pass 1 to force atomicity in myri10ge_send_cmd() */ |
2486 | myri10ge_change_promisc(mgp, dev->flags & IFF_PROMISC, 1); | 2576 | myri10ge_change_promisc(mgp, dev->flags & IFF_PROMISC, 1); |
@@ -2616,13 +2706,14 @@ static void myri10ge_enable_ecrc(struct myri10ge_priv *mgp) | |||
2616 | ext_type = (val & PCI_EXP_FLAGS_TYPE) >> 4; | 2706 | ext_type = (val & PCI_EXP_FLAGS_TYPE) >> 4; |
2617 | if (ext_type != PCI_EXP_TYPE_ROOT_PORT) { | 2707 | if (ext_type != PCI_EXP_TYPE_ROOT_PORT) { |
2618 | if (myri10ge_ecrc_enable > 1) { | 2708 | if (myri10ge_ecrc_enable > 1) { |
2619 | struct pci_dev *old_bridge = bridge; | 2709 | struct pci_dev *prev_bridge, *old_bridge = bridge; |
2620 | 2710 | ||
2621 | /* Walk the hierarchy up to the root port | 2711 | /* Walk the hierarchy up to the root port |
2622 | * where ECRC has to be enabled */ | 2712 | * where ECRC has to be enabled */ |
2623 | do { | 2713 | do { |
2714 | prev_bridge = bridge; | ||
2624 | bridge = bridge->bus->self; | 2715 | bridge = bridge->bus->self; |
2625 | if (!bridge) { | 2716 | if (!bridge || prev_bridge == bridge) { |
2626 | dev_err(dev, | 2717 | dev_err(dev, |
2627 | "Failed to find root port" | 2718 | "Failed to find root port" |
2628 | " to force ECRC\n"); | 2719 | " to force ECRC\n"); |
@@ -2681,9 +2772,9 @@ static void myri10ge_enable_ecrc(struct myri10ge_priv *mgp) | |||
2681 | * already been enabled, then it must use a firmware image which works | 2772 | * already been enabled, then it must use a firmware image which works |
2682 | * around unaligned completion packets (myri10ge_ethp_z8e.dat), and it | 2773 | * around unaligned completion packets (myri10ge_ethp_z8e.dat), and it |
2683 | * should also ensure that it never gives the device a Read-DMA which is | 2774 | * should also ensure that it never gives the device a Read-DMA which is |
2684 | * larger than 2KB by setting the tx.boundary to 2KB. If ECRC is | 2775 | * larger than 2KB by setting the tx_boundary to 2KB. If ECRC is |
2685 | * enabled, then the driver should use the aligned (myri10ge_eth_z8e.dat) | 2776 | * enabled, then the driver should use the aligned (myri10ge_eth_z8e.dat) |
2686 | * firmware image, and set tx.boundary to 4KB. | 2777 | * firmware image, and set tx_boundary to 4KB. |
2687 | */ | 2778 | */ |
2688 | 2779 | ||
2689 | static void myri10ge_firmware_probe(struct myri10ge_priv *mgp) | 2780 | static void myri10ge_firmware_probe(struct myri10ge_priv *mgp) |
@@ -2692,7 +2783,7 @@ static void myri10ge_firmware_probe(struct myri10ge_priv *mgp) | |||
2692 | struct device *dev = &pdev->dev; | 2783 | struct device *dev = &pdev->dev; |
2693 | int status; | 2784 | int status; |
2694 | 2785 | ||
2695 | mgp->tx.boundary = 4096; | 2786 | mgp->tx_boundary = 4096; |
2696 | /* | 2787 | /* |
2697 | * Verify the max read request size was set to 4KB | 2788 | * Verify the max read request size was set to 4KB |
2698 | * before trying the test with 4KB. | 2789 | * before trying the test with 4KB. |
@@ -2704,7 +2795,7 @@ static void myri10ge_firmware_probe(struct myri10ge_priv *mgp) | |||
2704 | } | 2795 | } |
2705 | if (status != 4096) { | 2796 | if (status != 4096) { |
2706 | dev_warn(dev, "Max Read Request size != 4096 (%d)\n", status); | 2797 | dev_warn(dev, "Max Read Request size != 4096 (%d)\n", status); |
2707 | mgp->tx.boundary = 2048; | 2798 | mgp->tx_boundary = 2048; |
2708 | } | 2799 | } |
2709 | /* | 2800 | /* |
2710 | * load the optimized firmware (which assumes aligned PCIe | 2801 | * load the optimized firmware (which assumes aligned PCIe |
@@ -2737,7 +2828,7 @@ static void myri10ge_firmware_probe(struct myri10ge_priv *mgp) | |||
2737 | "Please install up to date fw\n"); | 2828 | "Please install up to date fw\n"); |
2738 | abort: | 2829 | abort: |
2739 | /* fall back to using the unaligned firmware */ | 2830 | /* fall back to using the unaligned firmware */ |
2740 | mgp->tx.boundary = 2048; | 2831 | mgp->tx_boundary = 2048; |
2741 | mgp->fw_name = myri10ge_fw_unaligned; | 2832 | mgp->fw_name = myri10ge_fw_unaligned; |
2742 | 2833 | ||
2743 | } | 2834 | } |
@@ -2758,7 +2849,7 @@ static void myri10ge_select_firmware(struct myri10ge_priv *mgp) | |||
2758 | if (link_width < 8) { | 2849 | if (link_width < 8) { |
2759 | dev_info(&mgp->pdev->dev, "PCIE x%d Link\n", | 2850 | dev_info(&mgp->pdev->dev, "PCIE x%d Link\n", |
2760 | link_width); | 2851 | link_width); |
2761 | mgp->tx.boundary = 4096; | 2852 | mgp->tx_boundary = 4096; |
2762 | mgp->fw_name = myri10ge_fw_aligned; | 2853 | mgp->fw_name = myri10ge_fw_aligned; |
2763 | } else { | 2854 | } else { |
2764 | myri10ge_firmware_probe(mgp); | 2855 | myri10ge_firmware_probe(mgp); |
@@ -2767,12 +2858,12 @@ static void myri10ge_select_firmware(struct myri10ge_priv *mgp) | |||
2767 | if (myri10ge_force_firmware == 1) { | 2858 | if (myri10ge_force_firmware == 1) { |
2768 | dev_info(&mgp->pdev->dev, | 2859 | dev_info(&mgp->pdev->dev, |
2769 | "Assuming aligned completions (forced)\n"); | 2860 | "Assuming aligned completions (forced)\n"); |
2770 | mgp->tx.boundary = 4096; | 2861 | mgp->tx_boundary = 4096; |
2771 | mgp->fw_name = myri10ge_fw_aligned; | 2862 | mgp->fw_name = myri10ge_fw_aligned; |
2772 | } else { | 2863 | } else { |
2773 | dev_info(&mgp->pdev->dev, | 2864 | dev_info(&mgp->pdev->dev, |
2774 | "Assuming unaligned completions (forced)\n"); | 2865 | "Assuming unaligned completions (forced)\n"); |
2775 | mgp->tx.boundary = 2048; | 2866 | mgp->tx_boundary = 2048; |
2776 | mgp->fw_name = myri10ge_fw_unaligned; | 2867 | mgp->fw_name = myri10ge_fw_unaligned; |
2777 | } | 2868 | } |
2778 | } | 2869 | } |
@@ -2889,6 +2980,7 @@ static void myri10ge_watchdog(struct work_struct *work) | |||
2889 | { | 2980 | { |
2890 | struct myri10ge_priv *mgp = | 2981 | struct myri10ge_priv *mgp = |
2891 | container_of(work, struct myri10ge_priv, watchdog_work); | 2982 | container_of(work, struct myri10ge_priv, watchdog_work); |
2983 | struct myri10ge_tx_buf *tx; | ||
2892 | u32 reboot; | 2984 | u32 reboot; |
2893 | int status; | 2985 | int status; |
2894 | u16 cmd, vendor; | 2986 | u16 cmd, vendor; |
@@ -2938,15 +3030,16 @@ static void myri10ge_watchdog(struct work_struct *work) | |||
2938 | 3030 | ||
2939 | printk(KERN_ERR "myri10ge: %s: device timeout, resetting\n", | 3031 | printk(KERN_ERR "myri10ge: %s: device timeout, resetting\n", |
2940 | mgp->dev->name); | 3032 | mgp->dev->name); |
3033 | tx = &mgp->ss.tx; | ||
2941 | printk(KERN_INFO "myri10ge: %s: %d %d %d %d %d\n", | 3034 | printk(KERN_INFO "myri10ge: %s: %d %d %d %d %d\n", |
2942 | mgp->dev->name, mgp->tx.req, mgp->tx.done, | 3035 | mgp->dev->name, tx->req, tx->done, |
2943 | mgp->tx.pkt_start, mgp->tx.pkt_done, | 3036 | tx->pkt_start, tx->pkt_done, |
2944 | (int)ntohl(mgp->fw_stats->send_done_count)); | 3037 | (int)ntohl(mgp->ss.fw_stats->send_done_count)); |
2945 | msleep(2000); | 3038 | msleep(2000); |
2946 | printk(KERN_INFO "myri10ge: %s: %d %d %d %d %d\n", | 3039 | printk(KERN_INFO "myri10ge: %s: %d %d %d %d %d\n", |
2947 | mgp->dev->name, mgp->tx.req, mgp->tx.done, | 3040 | mgp->dev->name, tx->req, tx->done, |
2948 | mgp->tx.pkt_start, mgp->tx.pkt_done, | 3041 | tx->pkt_start, tx->pkt_done, |
2949 | (int)ntohl(mgp->fw_stats->send_done_count)); | 3042 | (int)ntohl(mgp->ss.fw_stats->send_done_count)); |
2950 | } | 3043 | } |
2951 | rtnl_lock(); | 3044 | rtnl_lock(); |
2952 | myri10ge_close(mgp->dev); | 3045 | myri10ge_close(mgp->dev); |
@@ -2969,28 +3062,31 @@ static void myri10ge_watchdog(struct work_struct *work) | |||
2969 | static void myri10ge_watchdog_timer(unsigned long arg) | 3062 | static void myri10ge_watchdog_timer(unsigned long arg) |
2970 | { | 3063 | { |
2971 | struct myri10ge_priv *mgp; | 3064 | struct myri10ge_priv *mgp; |
3065 | struct myri10ge_slice_state *ss; | ||
2972 | u32 rx_pause_cnt; | 3066 | u32 rx_pause_cnt; |
2973 | 3067 | ||
2974 | mgp = (struct myri10ge_priv *)arg; | 3068 | mgp = (struct myri10ge_priv *)arg; |
2975 | 3069 | ||
2976 | if (mgp->rx_small.watchdog_needed) { | 3070 | rx_pause_cnt = ntohl(mgp->ss.fw_stats->dropped_pause); |
2977 | myri10ge_alloc_rx_pages(mgp, &mgp->rx_small, | 3071 | |
3072 | ss = &mgp->ss; | ||
3073 | if (ss->rx_small.watchdog_needed) { | ||
3074 | myri10ge_alloc_rx_pages(mgp, &ss->rx_small, | ||
2978 | mgp->small_bytes + MXGEFW_PAD, 1); | 3075 | mgp->small_bytes + MXGEFW_PAD, 1); |
2979 | if (mgp->rx_small.fill_cnt - mgp->rx_small.cnt >= | 3076 | if (ss->rx_small.fill_cnt - ss->rx_small.cnt >= |
2980 | myri10ge_fill_thresh) | 3077 | myri10ge_fill_thresh) |
2981 | mgp->rx_small.watchdog_needed = 0; | 3078 | ss->rx_small.watchdog_needed = 0; |
2982 | } | 3079 | } |
2983 | if (mgp->rx_big.watchdog_needed) { | 3080 | if (ss->rx_big.watchdog_needed) { |
2984 | myri10ge_alloc_rx_pages(mgp, &mgp->rx_big, mgp->big_bytes, 1); | 3081 | myri10ge_alloc_rx_pages(mgp, &ss->rx_big, mgp->big_bytes, 1); |
2985 | if (mgp->rx_big.fill_cnt - mgp->rx_big.cnt >= | 3082 | if (ss->rx_big.fill_cnt - ss->rx_big.cnt >= |
2986 | myri10ge_fill_thresh) | 3083 | myri10ge_fill_thresh) |
2987 | mgp->rx_big.watchdog_needed = 0; | 3084 | ss->rx_big.watchdog_needed = 0; |
2988 | } | 3085 | } |
2989 | rx_pause_cnt = ntohl(mgp->fw_stats->dropped_pause); | ||
2990 | 3086 | ||
2991 | if (mgp->tx.req != mgp->tx.done && | 3087 | if (ss->tx.req != ss->tx.done && |
2992 | mgp->tx.done == mgp->watchdog_tx_done && | 3088 | ss->tx.done == ss->watchdog_tx_done && |
2993 | mgp->watchdog_tx_req != mgp->watchdog_tx_done) { | 3089 | ss->watchdog_tx_req != ss->watchdog_tx_done) { |
2994 | /* nic seems like it might be stuck.. */ | 3090 | /* nic seems like it might be stuck.. */ |
2995 | if (rx_pause_cnt != mgp->watchdog_pause) { | 3091 | if (rx_pause_cnt != mgp->watchdog_pause) { |
2996 | if (net_ratelimit()) | 3092 | if (net_ratelimit()) |
@@ -3005,8 +3101,8 @@ static void myri10ge_watchdog_timer(unsigned long arg) | |||
3005 | /* rearm timer */ | 3101 | /* rearm timer */ |
3006 | mod_timer(&mgp->watchdog_timer, | 3102 | mod_timer(&mgp->watchdog_timer, |
3007 | jiffies + myri10ge_watchdog_timeout * HZ); | 3103 | jiffies + myri10ge_watchdog_timeout * HZ); |
3008 | mgp->watchdog_tx_done = mgp->tx.done; | 3104 | ss->watchdog_tx_done = ss->tx.done; |
3009 | mgp->watchdog_tx_req = mgp->tx.req; | 3105 | ss->watchdog_tx_req = ss->tx.req; |
3010 | mgp->watchdog_pause = rx_pause_cnt; | 3106 | mgp->watchdog_pause = rx_pause_cnt; |
3011 | } | 3107 | } |
3012 | 3108 | ||
@@ -3030,7 +3126,7 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
3030 | 3126 | ||
3031 | mgp = netdev_priv(netdev); | 3127 | mgp = netdev_priv(netdev); |
3032 | mgp->dev = netdev; | 3128 | mgp->dev = netdev; |
3033 | netif_napi_add(netdev, &mgp->napi, myri10ge_poll, myri10ge_napi_weight); | 3129 | netif_napi_add(netdev, &mgp->ss.napi, myri10ge_poll, myri10ge_napi_weight); |
3034 | mgp->pdev = pdev; | 3130 | mgp->pdev = pdev; |
3035 | mgp->csum_flag = MXGEFW_FLAGS_CKSUM; | 3131 | mgp->csum_flag = MXGEFW_FLAGS_CKSUM; |
3036 | mgp->pause = myri10ge_flow_control; | 3132 | mgp->pause = myri10ge_flow_control; |
@@ -3076,9 +3172,9 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
3076 | if (mgp->cmd == NULL) | 3172 | if (mgp->cmd == NULL) |
3077 | goto abort_with_netdev; | 3173 | goto abort_with_netdev; |
3078 | 3174 | ||
3079 | mgp->fw_stats = dma_alloc_coherent(&pdev->dev, sizeof(*mgp->fw_stats), | 3175 | mgp->ss.fw_stats = dma_alloc_coherent(&pdev->dev, sizeof(*mgp->ss.fw_stats), |
3080 | &mgp->fw_stats_bus, GFP_KERNEL); | 3176 | &mgp->ss.fw_stats_bus, GFP_KERNEL); |
3081 | if (mgp->fw_stats == NULL) | 3177 | if (mgp->ss.fw_stats == NULL) |
3082 | goto abort_with_cmd; | 3178 | goto abort_with_cmd; |
3083 | 3179 | ||
3084 | mgp->board_span = pci_resource_len(pdev, 0); | 3180 | mgp->board_span = pci_resource_len(pdev, 0); |
@@ -3118,12 +3214,12 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
3118 | netdev->dev_addr[i] = mgp->mac_addr[i]; | 3214 | netdev->dev_addr[i] = mgp->mac_addr[i]; |
3119 | 3215 | ||
3120 | /* allocate rx done ring */ | 3216 | /* allocate rx done ring */ |
3121 | bytes = myri10ge_max_intr_slots * sizeof(*mgp->rx_done.entry); | 3217 | bytes = mgp->max_intr_slots * sizeof(*mgp->ss.rx_done.entry); |
3122 | mgp->rx_done.entry = dma_alloc_coherent(&pdev->dev, bytes, | 3218 | mgp->ss.rx_done.entry = dma_alloc_coherent(&pdev->dev, bytes, |
3123 | &mgp->rx_done.bus, GFP_KERNEL); | 3219 | &mgp->ss.rx_done.bus, GFP_KERNEL); |
3124 | if (mgp->rx_done.entry == NULL) | 3220 | if (mgp->ss.rx_done.entry == NULL) |
3125 | goto abort_with_ioremap; | 3221 | goto abort_with_ioremap; |
3126 | memset(mgp->rx_done.entry, 0, bytes); | 3222 | memset(mgp->ss.rx_done.entry, 0, bytes); |
3127 | 3223 | ||
3128 | myri10ge_select_firmware(mgp); | 3224 | myri10ge_select_firmware(mgp); |
3129 | 3225 | ||
@@ -3183,7 +3279,7 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
3183 | } | 3279 | } |
3184 | dev_info(dev, "%s IRQ %d, tx bndry %d, fw %s, WC %s\n", | 3280 | dev_info(dev, "%s IRQ %d, tx bndry %d, fw %s, WC %s\n", |
3185 | (mgp->msi_enabled ? "MSI" : "xPIC"), | 3281 | (mgp->msi_enabled ? "MSI" : "xPIC"), |
3186 | netdev->irq, mgp->tx.boundary, mgp->fw_name, | 3282 | netdev->irq, mgp->tx_boundary, mgp->fw_name, |
3187 | (mgp->wc_enabled ? "Enabled" : "Disabled")); | 3283 | (mgp->wc_enabled ? "Enabled" : "Disabled")); |
3188 | 3284 | ||
3189 | return 0; | 3285 | return 0; |
@@ -3195,9 +3291,9 @@ abort_with_firmware: | |||
3195 | myri10ge_dummy_rdma(mgp, 0); | 3291 | myri10ge_dummy_rdma(mgp, 0); |
3196 | 3292 | ||
3197 | abort_with_rx_done: | 3293 | abort_with_rx_done: |
3198 | bytes = myri10ge_max_intr_slots * sizeof(*mgp->rx_done.entry); | 3294 | bytes = mgp->max_intr_slots * sizeof(*mgp->ss.rx_done.entry); |
3199 | dma_free_coherent(&pdev->dev, bytes, | 3295 | dma_free_coherent(&pdev->dev, bytes, |
3200 | mgp->rx_done.entry, mgp->rx_done.bus); | 3296 | mgp->ss.rx_done.entry, mgp->ss.rx_done.bus); |
3201 | 3297 | ||
3202 | abort_with_ioremap: | 3298 | abort_with_ioremap: |
3203 | iounmap(mgp->sram); | 3299 | iounmap(mgp->sram); |
@@ -3207,8 +3303,8 @@ abort_with_wc: | |||
3207 | if (mgp->mtrr >= 0) | 3303 | if (mgp->mtrr >= 0) |
3208 | mtrr_del(mgp->mtrr, mgp->iomem_base, mgp->board_span); | 3304 | mtrr_del(mgp->mtrr, mgp->iomem_base, mgp->board_span); |
3209 | #endif | 3305 | #endif |
3210 | dma_free_coherent(&pdev->dev, sizeof(*mgp->fw_stats), | 3306 | dma_free_coherent(&pdev->dev, sizeof(*mgp->ss.fw_stats), |
3211 | mgp->fw_stats, mgp->fw_stats_bus); | 3307 | mgp->ss.fw_stats, mgp->ss.fw_stats_bus); |
3212 | 3308 | ||
3213 | abort_with_cmd: | 3309 | abort_with_cmd: |
3214 | dma_free_coherent(&pdev->dev, sizeof(*mgp->cmd), | 3310 | dma_free_coherent(&pdev->dev, sizeof(*mgp->cmd), |
@@ -3246,9 +3342,9 @@ static void myri10ge_remove(struct pci_dev *pdev) | |||
3246 | /* avoid a memory leak */ | 3342 | /* avoid a memory leak */ |
3247 | pci_restore_state(pdev); | 3343 | pci_restore_state(pdev); |
3248 | 3344 | ||
3249 | bytes = myri10ge_max_intr_slots * sizeof(*mgp->rx_done.entry); | 3345 | bytes = mgp->max_intr_slots * sizeof(*mgp->ss.rx_done.entry); |
3250 | dma_free_coherent(&pdev->dev, bytes, | 3346 | dma_free_coherent(&pdev->dev, bytes, |
3251 | mgp->rx_done.entry, mgp->rx_done.bus); | 3347 | mgp->ss.rx_done.entry, mgp->ss.rx_done.bus); |
3252 | 3348 | ||
3253 | iounmap(mgp->sram); | 3349 | iounmap(mgp->sram); |
3254 | 3350 | ||
@@ -3256,8 +3352,8 @@ static void myri10ge_remove(struct pci_dev *pdev) | |||
3256 | if (mgp->mtrr >= 0) | 3352 | if (mgp->mtrr >= 0) |
3257 | mtrr_del(mgp->mtrr, mgp->iomem_base, mgp->board_span); | 3353 | mtrr_del(mgp->mtrr, mgp->iomem_base, mgp->board_span); |
3258 | #endif | 3354 | #endif |
3259 | dma_free_coherent(&pdev->dev, sizeof(*mgp->fw_stats), | 3355 | dma_free_coherent(&pdev->dev, sizeof(*mgp->ss.fw_stats), |
3260 | mgp->fw_stats, mgp->fw_stats_bus); | 3356 | mgp->ss.fw_stats, mgp->ss.fw_stats_bus); |
3261 | 3357 | ||
3262 | dma_free_coherent(&pdev->dev, sizeof(*mgp->cmd), | 3358 | dma_free_coherent(&pdev->dev, sizeof(*mgp->cmd), |
3263 | mgp->cmd, mgp->cmd_bus); | 3359 | mgp->cmd, mgp->cmd_bus); |
diff --git a/drivers/net/myri10ge/myri10ge_mcp.h b/drivers/net/myri10ge/myri10ge_mcp.h index 58e57178c563..fdbeeee07372 100644 --- a/drivers/net/myri10ge/myri10ge_mcp.h +++ b/drivers/net/myri10ge/myri10ge_mcp.h | |||
@@ -10,7 +10,7 @@ struct mcp_dma_addr { | |||
10 | __be32 low; | 10 | __be32 low; |
11 | }; | 11 | }; |
12 | 12 | ||
13 | /* 4 Bytes. 8 Bytes for NDIS drivers. */ | 13 | /* 4 Bytes */ |
14 | struct mcp_slot { | 14 | struct mcp_slot { |
15 | __sum16 checksum; | 15 | __sum16 checksum; |
16 | __be16 length; | 16 | __be16 length; |
@@ -144,6 +144,7 @@ enum myri10ge_mcp_cmd_type { | |||
144 | * a power of 2 number of entries. */ | 144 | * a power of 2 number of entries. */ |
145 | 145 | ||
146 | MXGEFW_CMD_SET_INTRQ_SIZE, /* in bytes */ | 146 | MXGEFW_CMD_SET_INTRQ_SIZE, /* in bytes */ |
147 | #define MXGEFW_CMD_SET_INTRQ_SIZE_FLAG_NO_STRICT_SIZE_CHECK (1 << 31) | ||
147 | 148 | ||
148 | /* command to bring ethernet interface up. Above parameters | 149 | /* command to bring ethernet interface up. Above parameters |
149 | * (plus mtu & mac address) must have been exchanged prior | 150 | * (plus mtu & mac address) must have been exchanged prior |
@@ -221,10 +222,14 @@ enum myri10ge_mcp_cmd_type { | |||
221 | MXGEFW_CMD_GET_MAX_RSS_QUEUES, | 222 | MXGEFW_CMD_GET_MAX_RSS_QUEUES, |
222 | MXGEFW_CMD_ENABLE_RSS_QUEUES, | 223 | MXGEFW_CMD_ENABLE_RSS_QUEUES, |
223 | /* data0 = number of slices n (0, 1, ..., n-1) to enable | 224 | /* data0 = number of slices n (0, 1, ..., n-1) to enable |
224 | * data1 = interrupt mode. 0=share one INTx/MSI, 1=use one MSI-X per queue. | 225 | * data1 = interrupt mode. |
226 | * 0=share one INTx/MSI, 1=use one MSI-X per queue. | ||
225 | * If all queues share one interrupt, the driver must have set | 227 | * If all queues share one interrupt, the driver must have set |
226 | * RSS_SHARED_INTERRUPT_DMA before enabling queues. | 228 | * RSS_SHARED_INTERRUPT_DMA before enabling queues. |
227 | */ | 229 | */ |
230 | #define MXGEFW_SLICE_INTR_MODE_SHARED 0 | ||
231 | #define MXGEFW_SLICE_INTR_MODE_ONE_PER_SLICE 1 | ||
232 | |||
228 | MXGEFW_CMD_GET_RSS_SHARED_INTERRUPT_MASK_OFFSET, | 233 | MXGEFW_CMD_GET_RSS_SHARED_INTERRUPT_MASK_OFFSET, |
229 | MXGEFW_CMD_SET_RSS_SHARED_INTERRUPT_DMA, | 234 | MXGEFW_CMD_SET_RSS_SHARED_INTERRUPT_DMA, |
230 | /* data0, data1 = bus address lsw, msw */ | 235 | /* data0, data1 = bus address lsw, msw */ |
@@ -241,10 +246,14 @@ enum myri10ge_mcp_cmd_type { | |||
241 | * 0: disable rss. nic does not distribute receive packets. | 246 | * 0: disable rss. nic does not distribute receive packets. |
242 | * 1: enable rss. nic distributes receive packets among queues. | 247 | * 1: enable rss. nic distributes receive packets among queues. |
243 | * data1 = hash type | 248 | * data1 = hash type |
244 | * 1: IPV4 | 249 | * 1: IPV4 (required by RSS) |
245 | * 2: TCP_IPV4 | 250 | * 2: TCP_IPV4 (required by RSS) |
246 | * 3: IPV4 | TCP_IPV4 | 251 | * 3: IPV4 | TCP_IPV4 (required by RSS) |
252 | * 4: source port | ||
247 | */ | 253 | */ |
254 | #define MXGEFW_RSS_HASH_TYPE_IPV4 0x1 | ||
255 | #define MXGEFW_RSS_HASH_TYPE_TCP_IPV4 0x2 | ||
256 | #define MXGEFW_RSS_HASH_TYPE_SRC_PORT 0x4 | ||
248 | 257 | ||
249 | MXGEFW_CMD_GET_MAX_TSO6_HDR_SIZE, | 258 | MXGEFW_CMD_GET_MAX_TSO6_HDR_SIZE, |
250 | /* Return data = the max. size of the entire headers of a IPv6 TSO packet. | 259 | /* Return data = the max. size of the entire headers of a IPv6 TSO packet. |
@@ -260,6 +269,8 @@ enum myri10ge_mcp_cmd_type { | |||
260 | * 0: Linux/FreeBSD style (NIC default) | 269 | * 0: Linux/FreeBSD style (NIC default) |
261 | * 1: NDIS/NetBSD style | 270 | * 1: NDIS/NetBSD style |
262 | */ | 271 | */ |
272 | #define MXGEFW_TSO_MODE_LINUX 0 | ||
273 | #define MXGEFW_TSO_MODE_NDIS 1 | ||
263 | 274 | ||
264 | MXGEFW_CMD_MDIO_READ, | 275 | MXGEFW_CMD_MDIO_READ, |
265 | /* data0 = dev_addr (PMA/PMD or PCS ...), data1 = register/addr */ | 276 | /* data0 = dev_addr (PMA/PMD or PCS ...), data1 = register/addr */ |
@@ -286,6 +297,38 @@ enum myri10ge_mcp_cmd_type { | |||
286 | /* Return data = NIC memory offset of mcp_vpump_public_global */ | 297 | /* Return data = NIC memory offset of mcp_vpump_public_global */ |
287 | MXGEFW_CMD_RESET_VPUMP, | 298 | MXGEFW_CMD_RESET_VPUMP, |
288 | /* Resets the VPUMP state */ | 299 | /* Resets the VPUMP state */ |
300 | |||
301 | MXGEFW_CMD_SET_RSS_MCP_SLOT_TYPE, | ||
302 | /* data0 = mcp_slot type to use. | ||
303 | * 0 = the default 4B mcp_slot | ||
304 | * 1 = 8B mcp_slot_8 | ||
305 | */ | ||
306 | #define MXGEFW_RSS_MCP_SLOT_TYPE_MIN 0 | ||
307 | #define MXGEFW_RSS_MCP_SLOT_TYPE_WITH_HASH 1 | ||
308 | |||
309 | MXGEFW_CMD_SET_THROTTLE_FACTOR, | ||
310 | /* set the throttle factor for ethp_z8e | ||
311 | * data0 = throttle_factor | ||
312 | * throttle_factor = 256 * pcie-raw-speed / tx_speed | ||
313 | * tx_speed = 256 * pcie-raw-speed / throttle_factor | ||
314 | * | ||
315 | * For PCI-E x8: pcie-raw-speed == 16Gb/s | ||
316 | * For PCI-E x4: pcie-raw-speed == 8Gb/s | ||
317 | * | ||
318 | * ex1: throttle_factor == 0x1a0 (416), tx_speed == 1.23GB/s == 9.846 Gb/s | ||
319 | * ex2: throttle_factor == 0x200 (512), tx_speed == 1.0GB/s == 8 Gb/s | ||
320 | * | ||
321 | * with tx_boundary == 2048, max-throttle-factor == 8191 => min-speed == 500Mb/s | ||
322 | * with tx_boundary == 4096, max-throttle-factor == 4095 => min-speed == 1Gb/s | ||
323 | */ | ||
324 | |||
325 | MXGEFW_CMD_VPUMP_UP, | ||
326 | /* Allocates VPump Connection, Send Request and Zero copy buffer address tables */ | ||
327 | MXGEFW_CMD_GET_VPUMP_CLK, | ||
328 | /* Get the lanai clock */ | ||
329 | |||
330 | MXGEFW_CMD_GET_DCA_OFFSET, | ||
331 | /* offset of dca control for WDMAs */ | ||
289 | }; | 332 | }; |
290 | 333 | ||
291 | enum myri10ge_mcp_cmd_status { | 334 | enum myri10ge_mcp_cmd_status { |
@@ -302,7 +345,8 @@ enum myri10ge_mcp_cmd_status { | |||
302 | MXGEFW_CMD_ERROR_UNALIGNED, | 345 | MXGEFW_CMD_ERROR_UNALIGNED, |
303 | MXGEFW_CMD_ERROR_NO_MDIO, | 346 | MXGEFW_CMD_ERROR_NO_MDIO, |
304 | MXGEFW_CMD_ERROR_XFP_FAILURE, | 347 | MXGEFW_CMD_ERROR_XFP_FAILURE, |
305 | MXGEFW_CMD_ERROR_XFP_ABSENT | 348 | MXGEFW_CMD_ERROR_XFP_ABSENT, |
349 | MXGEFW_CMD_ERROR_BAD_PCIE_LINK | ||
306 | }; | 350 | }; |
307 | 351 | ||
308 | #define MXGEFW_OLD_IRQ_DATA_LEN 40 | 352 | #define MXGEFW_OLD_IRQ_DATA_LEN 40 |
diff --git a/drivers/net/myri10ge/myri10ge_mcp_gen_header.h b/drivers/net/myri10ge/myri10ge_mcp_gen_header.h index 16a810dd6d51..07d65c2cbb24 100644 --- a/drivers/net/myri10ge/myri10ge_mcp_gen_header.h +++ b/drivers/net/myri10ge/myri10ge_mcp_gen_header.h | |||
@@ -1,30 +1,6 @@ | |||
1 | #ifndef __MYRI10GE_MCP_GEN_HEADER_H__ | 1 | #ifndef __MYRI10GE_MCP_GEN_HEADER_H__ |
2 | #define __MYRI10GE_MCP_GEN_HEADER_H__ | 2 | #define __MYRI10GE_MCP_GEN_HEADER_H__ |
3 | 3 | ||
4 | /* this file define a standard header used as a first entry point to | ||
5 | * exchange information between firmware/driver and driver. The | ||
6 | * header structure can be anywhere in the mcp. It will usually be in | ||
7 | * the .data section, because some fields needs to be initialized at | ||
8 | * compile time. | ||
9 | * The 32bit word at offset MX_HEADER_PTR_OFFSET in the mcp must | ||
10 | * contains the location of the header. | ||
11 | * | ||
12 | * Typically a MCP will start with the following: | ||
13 | * .text | ||
14 | * .space 52 ! to help catch MEMORY_INT errors | ||
15 | * bt start ! jump to real code | ||
16 | * nop | ||
17 | * .long _gen_mcp_header | ||
18 | * | ||
19 | * The source will have a definition like: | ||
20 | * | ||
21 | * mcp_gen_header_t gen_mcp_header = { | ||
22 | * .header_length = sizeof(mcp_gen_header_t), | ||
23 | * .mcp_type = MCP_TYPE_XXX, | ||
24 | * .version = "something $Id: mcp_gen_header.h,v 1.2 2006/05/13 10:04:35 bgoglin Exp $", | ||
25 | * .mcp_globals = (unsigned)&Globals | ||
26 | * }; | ||
27 | */ | ||
28 | 4 | ||
29 | #define MCP_HEADER_PTR_OFFSET 0x3c | 5 | #define MCP_HEADER_PTR_OFFSET 0x3c |
30 | 6 | ||
@@ -32,13 +8,14 @@ | |||
32 | #define MCP_TYPE_PCIE 0x70636965 /* "PCIE" pcie-only MCP */ | 8 | #define MCP_TYPE_PCIE 0x70636965 /* "PCIE" pcie-only MCP */ |
33 | #define MCP_TYPE_ETH 0x45544820 /* "ETH " */ | 9 | #define MCP_TYPE_ETH 0x45544820 /* "ETH " */ |
34 | #define MCP_TYPE_MCP0 0x4d435030 /* "MCP0" */ | 10 | #define MCP_TYPE_MCP0 0x4d435030 /* "MCP0" */ |
11 | #define MCP_TYPE_DFLT 0x20202020 /* " " */ | ||
35 | 12 | ||
36 | struct mcp_gen_header { | 13 | struct mcp_gen_header { |
37 | /* the first 4 fields are filled at compile time */ | 14 | /* the first 4 fields are filled at compile time */ |
38 | unsigned header_length; | 15 | unsigned header_length; |
39 | __be32 mcp_type; | 16 | __be32 mcp_type; |
40 | char version[128]; | 17 | char version[128]; |
41 | unsigned mcp_globals; /* pointer to mcp-type specific structure */ | 18 | unsigned mcp_private; /* pointer to mcp-type specific structure */ |
42 | 19 | ||
43 | /* filled by the MCP at run-time */ | 20 | /* filled by the MCP at run-time */ |
44 | unsigned sram_size; | 21 | unsigned sram_size; |
@@ -53,6 +30,18 @@ struct mcp_gen_header { | |||
53 | * | 30 | * |
54 | * Never remove any field. Keep everything naturally align. | 31 | * Never remove any field. Keep everything naturally align. |
55 | */ | 32 | */ |
33 | |||
34 | /* Specifies if the running mcp is mcp0, 1, or 2. */ | ||
35 | unsigned char mcp_index; | ||
36 | unsigned char disable_rabbit; | ||
37 | unsigned char unaligned_tlp; | ||
38 | unsigned char pad1; | ||
39 | unsigned counters_addr; | ||
40 | unsigned copy_block_info; /* for small mcps loaded with "lload -d" */ | ||
41 | unsigned short handoff_id_major; /* must be equal */ | ||
42 | unsigned short handoff_id_caps; /* bitfield: new mcp must have superset */ | ||
43 | unsigned msix_table_addr; /* start address of msix table in firmware */ | ||
44 | /* 8 */ | ||
56 | }; | 45 | }; |
57 | 46 | ||
58 | #endif /* __MYRI10GE_MCP_GEN_HEADER_H__ */ | 47 | #endif /* __MYRI10GE_MCP_GEN_HEADER_H__ */ |
diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h index 8cb29f5b1038..da4c4fb97064 100644 --- a/drivers/net/netxen/netxen_nic.h +++ b/drivers/net/netxen/netxen_nic.h | |||
@@ -776,7 +776,6 @@ struct netxen_hardware_context { | |||
776 | 776 | ||
777 | u8 revision_id; | 777 | u8 revision_id; |
778 | u16 board_type; | 778 | u16 board_type; |
779 | u16 max_ports; | ||
780 | struct netxen_board_info boardcfg; | 779 | struct netxen_board_info boardcfg; |
781 | u32 xg_linkup; | 780 | u32 xg_linkup; |
782 | u32 qg_linksup; | 781 | u32 qg_linksup; |
@@ -863,6 +862,7 @@ struct netxen_adapter { | |||
863 | unsigned char mac_addr[ETH_ALEN]; | 862 | unsigned char mac_addr[ETH_ALEN]; |
864 | int mtu; | 863 | int mtu; |
865 | int portnum; | 864 | int portnum; |
865 | u8 physical_port; | ||
866 | 866 | ||
867 | struct work_struct watchdog_task; | 867 | struct work_struct watchdog_task; |
868 | struct timer_list watchdog_timer; | 868 | struct timer_list watchdog_timer; |
@@ -1034,7 +1034,6 @@ int netxen_rom_se(struct netxen_adapter *adapter, int addr); | |||
1034 | 1034 | ||
1035 | /* Functions from netxen_nic_isr.c */ | 1035 | /* Functions from netxen_nic_isr.c */ |
1036 | void netxen_initialize_adapter_sw(struct netxen_adapter *adapter); | 1036 | void netxen_initialize_adapter_sw(struct netxen_adapter *adapter); |
1037 | void netxen_initialize_adapter_hw(struct netxen_adapter *adapter); | ||
1038 | void *netxen_alloc(struct pci_dev *pdev, size_t sz, dma_addr_t * ptr, | 1037 | void *netxen_alloc(struct pci_dev *pdev, size_t sz, dma_addr_t * ptr, |
1039 | struct pci_dev **used_dev); | 1038 | struct pci_dev **used_dev); |
1040 | void netxen_initialize_adapter_ops(struct netxen_adapter *adapter); | 1039 | void netxen_initialize_adapter_ops(struct netxen_adapter *adapter); |
@@ -1077,20 +1076,6 @@ static const struct netxen_brdinfo netxen_boards[] = { | |||
1077 | 1076 | ||
1078 | #define NUM_SUPPORTED_BOARDS ARRAY_SIZE(netxen_boards) | 1077 | #define NUM_SUPPORTED_BOARDS ARRAY_SIZE(netxen_boards) |
1079 | 1078 | ||
1080 | static inline void get_brd_port_by_type(u32 type, int *ports) | ||
1081 | { | ||
1082 | int i, found = 0; | ||
1083 | for (i = 0; i < NUM_SUPPORTED_BOARDS; ++i) { | ||
1084 | if (netxen_boards[i].brdtype == type) { | ||
1085 | *ports = netxen_boards[i].ports; | ||
1086 | found = 1; | ||
1087 | break; | ||
1088 | } | ||
1089 | } | ||
1090 | if (!found) | ||
1091 | *ports = 0; | ||
1092 | } | ||
1093 | |||
1094 | static inline void get_brd_name_by_type(u32 type, char *name) | 1079 | static inline void get_brd_name_by_type(u32 type, char *name) |
1095 | { | 1080 | { |
1096 | int i, found = 0; | 1081 | int i, found = 0; |
@@ -1169,5 +1154,4 @@ extern int netxen_rom_fast_read(struct netxen_adapter *adapter, int addr, | |||
1169 | 1154 | ||
1170 | extern struct ethtool_ops netxen_nic_ethtool_ops; | 1155 | extern struct ethtool_ops netxen_nic_ethtool_ops; |
1171 | 1156 | ||
1172 | extern int physical_port[]; /* physical port # from virtual port.*/ | ||
1173 | #endif /* __NETXEN_NIC_H_ */ | 1157 | #endif /* __NETXEN_NIC_H_ */ |
diff --git a/drivers/net/netxen/netxen_nic_ethtool.c b/drivers/net/netxen/netxen_nic_ethtool.c index 6e98d830eefb..723487bf200c 100644 --- a/drivers/net/netxen/netxen_nic_ethtool.c +++ b/drivers/net/netxen/netxen_nic_ethtool.c | |||
@@ -369,7 +369,7 @@ netxen_nic_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *p) | |||
369 | for (i = 3; niu_registers[mode].reg[i - 3] != -1; i++) { | 369 | for (i = 3; niu_registers[mode].reg[i - 3] != -1; i++) { |
370 | /* GB: port specific registers */ | 370 | /* GB: port specific registers */ |
371 | if (mode == 0 && i >= 19) | 371 | if (mode == 0 && i >= 19) |
372 | window = physical_port[adapter->portnum] * | 372 | window = adapter->physical_port * |
373 | NETXEN_NIC_PORT_WINDOW; | 373 | NETXEN_NIC_PORT_WINDOW; |
374 | 374 | ||
375 | NETXEN_NIC_LOCKED_READ_REG(niu_registers[mode]. | 375 | NETXEN_NIC_LOCKED_READ_REG(niu_registers[mode]. |
@@ -527,7 +527,7 @@ netxen_nic_get_pauseparam(struct net_device *dev, | |||
527 | { | 527 | { |
528 | struct netxen_adapter *adapter = netdev_priv(dev); | 528 | struct netxen_adapter *adapter = netdev_priv(dev); |
529 | __u32 val; | 529 | __u32 val; |
530 | int port = physical_port[adapter->portnum]; | 530 | int port = adapter->physical_port; |
531 | 531 | ||
532 | if (adapter->ahw.board_type == NETXEN_NIC_GBE) { | 532 | if (adapter->ahw.board_type == NETXEN_NIC_GBE) { |
533 | if ((port < 0) || (port > NETXEN_NIU_MAX_GBE_PORTS)) | 533 | if ((port < 0) || (port > NETXEN_NIU_MAX_GBE_PORTS)) |
@@ -573,7 +573,7 @@ netxen_nic_set_pauseparam(struct net_device *dev, | |||
573 | { | 573 | { |
574 | struct netxen_adapter *adapter = netdev_priv(dev); | 574 | struct netxen_adapter *adapter = netdev_priv(dev); |
575 | __u32 val; | 575 | __u32 val; |
576 | int port = physical_port[adapter->portnum]; | 576 | int port = adapter->physical_port; |
577 | /* read mode */ | 577 | /* read mode */ |
578 | if (adapter->ahw.board_type == NETXEN_NIC_GBE) { | 578 | if (adapter->ahw.board_type == NETXEN_NIC_GBE) { |
579 | if ((port < 0) || (port > NETXEN_NIU_MAX_GBE_PORTS)) | 579 | if ((port < 0) || (port > NETXEN_NIU_MAX_GBE_PORTS)) |
diff --git a/drivers/net/netxen/netxen_nic_hw.c b/drivers/net/netxen/netxen_nic_hw.c index af7356468251..c43d06b8de9b 100644 --- a/drivers/net/netxen/netxen_nic_hw.c +++ b/drivers/net/netxen/netxen_nic_hw.c | |||
@@ -396,11 +396,8 @@ int netxen_nic_hw_resources(struct netxen_adapter *adapter) | |||
396 | } | 396 | } |
397 | adapter->intr_scheme = readl( | 397 | adapter->intr_scheme = readl( |
398 | NETXEN_CRB_NORMALIZE(adapter, CRB_NIC_CAPABILITIES_FW)); | 398 | NETXEN_CRB_NORMALIZE(adapter, CRB_NIC_CAPABILITIES_FW)); |
399 | printk(KERN_NOTICE "%s: FW capabilities:0x%x\n", netxen_nic_driver_name, | ||
400 | adapter->intr_scheme); | ||
401 | adapter->msi_mode = readl( | 399 | adapter->msi_mode = readl( |
402 | NETXEN_CRB_NORMALIZE(adapter, CRB_NIC_MSI_MODE_FW)); | 400 | NETXEN_CRB_NORMALIZE(adapter, CRB_NIC_MSI_MODE_FW)); |
403 | DPRINTK(INFO, "Receive Peg ready too. starting stuff\n"); | ||
404 | 401 | ||
405 | addr = netxen_alloc(adapter->ahw.pdev, | 402 | addr = netxen_alloc(adapter->ahw.pdev, |
406 | sizeof(struct netxen_ring_ctx) + | 403 | sizeof(struct netxen_ring_ctx) + |
@@ -408,8 +405,6 @@ int netxen_nic_hw_resources(struct netxen_adapter *adapter) | |||
408 | (dma_addr_t *) & adapter->ctx_desc_phys_addr, | 405 | (dma_addr_t *) & adapter->ctx_desc_phys_addr, |
409 | &adapter->ctx_desc_pdev); | 406 | &adapter->ctx_desc_pdev); |
410 | 407 | ||
411 | printk(KERN_INFO "ctx_desc_phys_addr: 0x%llx\n", | ||
412 | (unsigned long long) adapter->ctx_desc_phys_addr); | ||
413 | if (addr == NULL) { | 408 | if (addr == NULL) { |
414 | DPRINTK(ERR, "bad return from pci_alloc_consistent\n"); | 409 | DPRINTK(ERR, "bad return from pci_alloc_consistent\n"); |
415 | err = -ENOMEM; | 410 | err = -ENOMEM; |
@@ -429,8 +424,6 @@ int netxen_nic_hw_resources(struct netxen_adapter *adapter) | |||
429 | adapter->max_tx_desc_count, | 424 | adapter->max_tx_desc_count, |
430 | (dma_addr_t *) & hw->cmd_desc_phys_addr, | 425 | (dma_addr_t *) & hw->cmd_desc_phys_addr, |
431 | &adapter->ahw.cmd_desc_pdev); | 426 | &adapter->ahw.cmd_desc_pdev); |
432 | printk(KERN_INFO "cmd_desc_phys_addr: 0x%llx\n", | ||
433 | (unsigned long long) hw->cmd_desc_phys_addr); | ||
434 | 427 | ||
435 | if (addr == NULL) { | 428 | if (addr == NULL) { |
436 | DPRINTK(ERR, "bad return from pci_alloc_consistent\n"); | 429 | DPRINTK(ERR, "bad return from pci_alloc_consistent\n"); |
@@ -1032,15 +1025,15 @@ int netxen_nic_get_board_info(struct netxen_adapter *adapter) | |||
1032 | int netxen_nic_set_mtu_gb(struct netxen_adapter *adapter, int new_mtu) | 1025 | int netxen_nic_set_mtu_gb(struct netxen_adapter *adapter, int new_mtu) |
1033 | { | 1026 | { |
1034 | netxen_nic_write_w0(adapter, | 1027 | netxen_nic_write_w0(adapter, |
1035 | NETXEN_NIU_GB_MAX_FRAME_SIZE( | 1028 | NETXEN_NIU_GB_MAX_FRAME_SIZE(adapter->physical_port), |
1036 | physical_port[adapter->portnum]), new_mtu); | 1029 | new_mtu); |
1037 | return 0; | 1030 | return 0; |
1038 | } | 1031 | } |
1039 | 1032 | ||
1040 | int netxen_nic_set_mtu_xgb(struct netxen_adapter *adapter, int new_mtu) | 1033 | int netxen_nic_set_mtu_xgb(struct netxen_adapter *adapter, int new_mtu) |
1041 | { | 1034 | { |
1042 | new_mtu += NETXEN_NIU_HDRSIZE + NETXEN_NIU_TLRSIZE; | 1035 | new_mtu += NETXEN_NIU_HDRSIZE + NETXEN_NIU_TLRSIZE; |
1043 | if (physical_port[adapter->portnum] == 0) | 1036 | if (adapter->physical_port == 0) |
1044 | netxen_nic_write_w0(adapter, NETXEN_NIU_XGE_MAX_FRAME_SIZE, | 1037 | netxen_nic_write_w0(adapter, NETXEN_NIU_XGE_MAX_FRAME_SIZE, |
1045 | new_mtu); | 1038 | new_mtu); |
1046 | else | 1039 | else |
@@ -1051,7 +1044,7 @@ int netxen_nic_set_mtu_xgb(struct netxen_adapter *adapter, int new_mtu) | |||
1051 | 1044 | ||
1052 | void netxen_nic_init_niu_gb(struct netxen_adapter *adapter) | 1045 | void netxen_nic_init_niu_gb(struct netxen_adapter *adapter) |
1053 | { | 1046 | { |
1054 | netxen_niu_gbe_init_port(adapter, physical_port[adapter->portnum]); | 1047 | netxen_niu_gbe_init_port(adapter, adapter->physical_port); |
1055 | } | 1048 | } |
1056 | 1049 | ||
1057 | void | 1050 | void |
@@ -1127,7 +1120,6 @@ void netxen_nic_set_link_parameters(struct netxen_adapter *adapter) | |||
1127 | 1120 | ||
1128 | void netxen_nic_flash_print(struct netxen_adapter *adapter) | 1121 | void netxen_nic_flash_print(struct netxen_adapter *adapter) |
1129 | { | 1122 | { |
1130 | int valid = 1; | ||
1131 | u32 fw_major = 0; | 1123 | u32 fw_major = 0; |
1132 | u32 fw_minor = 0; | 1124 | u32 fw_minor = 0; |
1133 | u32 fw_build = 0; | 1125 | u32 fw_build = 0; |
@@ -1137,70 +1129,62 @@ void netxen_nic_flash_print(struct netxen_adapter *adapter) | |||
1137 | __le32 *ptr32; | 1129 | __le32 *ptr32; |
1138 | 1130 | ||
1139 | struct netxen_board_info *board_info = &(adapter->ahw.boardcfg); | 1131 | struct netxen_board_info *board_info = &(adapter->ahw.boardcfg); |
1140 | if (board_info->magic != NETXEN_BDINFO_MAGIC) { | 1132 | |
1141 | printk | 1133 | adapter->driver_mismatch = 0; |
1142 | ("NetXen Unknown board config, Read 0x%x expected as 0x%x\n", | 1134 | |
1143 | board_info->magic, NETXEN_BDINFO_MAGIC); | 1135 | ptr32 = (u32 *)&serial_num; |
1144 | valid = 0; | 1136 | addr = NETXEN_USER_START + |
1145 | } | 1137 | offsetof(struct netxen_new_user_info, serial_num); |
1146 | if (board_info->header_version != NETXEN_BDINFO_VERSION) { | 1138 | for (i = 0; i < 8; i++) { |
1147 | printk("NetXen Unknown board config version." | 1139 | if (netxen_rom_fast_read(adapter, addr, ptr32) == -1) { |
1148 | " Read %x, expected %x\n", | 1140 | printk("%s: ERROR reading %s board userarea.\n", |
1149 | board_info->header_version, NETXEN_BDINFO_VERSION); | 1141 | netxen_nic_driver_name, |
1150 | valid = 0; | 1142 | netxen_nic_driver_name); |
1151 | } | 1143 | adapter->driver_mismatch = 1; |
1152 | if (valid) { | 1144 | return; |
1153 | ptr32 = (u32 *)&serial_num; | ||
1154 | addr = NETXEN_USER_START + | ||
1155 | offsetof(struct netxen_new_user_info, serial_num); | ||
1156 | for (i = 0; i < 8; i++) { | ||
1157 | if (netxen_rom_fast_read(adapter, addr, ptr32) == -1) { | ||
1158 | printk("%s: ERROR reading %s board userarea.\n", | ||
1159 | netxen_nic_driver_name, | ||
1160 | netxen_nic_driver_name); | ||
1161 | return; | ||
1162 | } | ||
1163 | ptr32++; | ||
1164 | addr += sizeof(u32); | ||
1165 | } | 1145 | } |
1146 | ptr32++; | ||
1147 | addr += sizeof(u32); | ||
1148 | } | ||
1149 | |||
1150 | fw_major = readl(NETXEN_CRB_NORMALIZE(adapter, | ||
1151 | NETXEN_FW_VERSION_MAJOR)); | ||
1152 | fw_minor = readl(NETXEN_CRB_NORMALIZE(adapter, | ||
1153 | NETXEN_FW_VERSION_MINOR)); | ||
1154 | fw_build = | ||
1155 | readl(NETXEN_CRB_NORMALIZE(adapter, NETXEN_FW_VERSION_SUB)); | ||
1166 | 1156 | ||
1157 | if (adapter->portnum == 0) { | ||
1167 | get_brd_name_by_type(board_info->board_type, brd_name); | 1158 | get_brd_name_by_type(board_info->board_type, brd_name); |
1168 | 1159 | ||
1169 | printk("NetXen %s Board S/N %s Chip id 0x%x\n", | 1160 | printk("NetXen %s Board S/N %s Chip id 0x%x\n", |
1170 | brd_name, serial_num, board_info->chip_id); | 1161 | brd_name, serial_num, board_info->chip_id); |
1171 | 1162 | printk("NetXen Firmware version %d.%d.%d\n", fw_major, | |
1172 | printk("NetXen %s Board #%d, Chip id 0x%x\n", | 1163 | fw_minor, fw_build); |
1173 | board_info->board_type == 0x0b ? "XGB" : "GBE", | ||
1174 | board_info->board_num, board_info->chip_id); | ||
1175 | fw_major = readl(NETXEN_CRB_NORMALIZE(adapter, | ||
1176 | NETXEN_FW_VERSION_MAJOR)); | ||
1177 | fw_minor = readl(NETXEN_CRB_NORMALIZE(adapter, | ||
1178 | NETXEN_FW_VERSION_MINOR)); | ||
1179 | fw_build = | ||
1180 | readl(NETXEN_CRB_NORMALIZE(adapter, NETXEN_FW_VERSION_SUB)); | ||
1181 | |||
1182 | printk("NetXen Firmware version %d.%d.%d\n", fw_major, fw_minor, | ||
1183 | fw_build); | ||
1184 | } | 1164 | } |
1165 | |||
1185 | if (fw_major != _NETXEN_NIC_LINUX_MAJOR) { | 1166 | if (fw_major != _NETXEN_NIC_LINUX_MAJOR) { |
1186 | printk(KERN_ERR "The mismatch in driver version and firmware " | ||
1187 | "version major number\n" | ||
1188 | "Driver version major number = %d \t" | ||
1189 | "Firmware version major number = %d \n", | ||
1190 | _NETXEN_NIC_LINUX_MAJOR, fw_major); | ||
1191 | adapter->driver_mismatch = 1; | 1167 | adapter->driver_mismatch = 1; |
1192 | } | 1168 | } |
1193 | if (fw_minor != _NETXEN_NIC_LINUX_MINOR && | 1169 | if (fw_minor != _NETXEN_NIC_LINUX_MINOR && |
1194 | fw_minor != (_NETXEN_NIC_LINUX_MINOR + 1)) { | 1170 | fw_minor != (_NETXEN_NIC_LINUX_MINOR + 1)) { |
1195 | printk(KERN_ERR "The mismatch in driver version and firmware " | ||
1196 | "version minor number\n" | ||
1197 | "Driver version minor number = %d \t" | ||
1198 | "Firmware version minor number = %d \n", | ||
1199 | _NETXEN_NIC_LINUX_MINOR, fw_minor); | ||
1200 | adapter->driver_mismatch = 1; | 1171 | adapter->driver_mismatch = 1; |
1201 | } | 1172 | } |
1202 | if (adapter->driver_mismatch) | 1173 | if (adapter->driver_mismatch) { |
1203 | printk(KERN_INFO "Use the driver with version no %d.%d.xxx\n", | 1174 | printk(KERN_ERR "%s: driver and firmware version mismatch\n", |
1204 | fw_major, fw_minor); | 1175 | adapter->netdev->name); |
1176 | return; | ||
1177 | } | ||
1178 | |||
1179 | switch (adapter->ahw.board_type) { | ||
1180 | case NETXEN_NIC_GBE: | ||
1181 | dev_info(&adapter->pdev->dev, "%s: GbE port initialized\n", | ||
1182 | adapter->netdev->name); | ||
1183 | break; | ||
1184 | case NETXEN_NIC_XGBE: | ||
1185 | dev_info(&adapter->pdev->dev, "%s: XGbE port initialized\n", | ||
1186 | adapter->netdev->name); | ||
1187 | break; | ||
1188 | } | ||
1205 | } | 1189 | } |
1206 | 1190 | ||
diff --git a/drivers/net/netxen/netxen_nic_init.c b/drivers/net/netxen/netxen_nic_init.c index 45fa33e0cb90..70d1b22ced22 100644 --- a/drivers/net/netxen/netxen_nic_init.c +++ b/drivers/net/netxen/netxen_nic_init.c | |||
@@ -203,21 +203,6 @@ void netxen_initialize_adapter_sw(struct netxen_adapter *adapter) | |||
203 | } | 203 | } |
204 | } | 204 | } |
205 | 205 | ||
206 | void netxen_initialize_adapter_hw(struct netxen_adapter *adapter) | ||
207 | { | ||
208 | int ports = 0; | ||
209 | struct netxen_board_info *board_info = &(adapter->ahw.boardcfg); | ||
210 | |||
211 | if (netxen_nic_get_board_info(adapter) != 0) | ||
212 | printk("%s: Error getting board config info.\n", | ||
213 | netxen_nic_driver_name); | ||
214 | get_brd_port_by_type(board_info->board_type, &ports); | ||
215 | if (ports == 0) | ||
216 | printk(KERN_ERR "%s: Unknown board type\n", | ||
217 | netxen_nic_driver_name); | ||
218 | adapter->ahw.max_ports = ports; | ||
219 | } | ||
220 | |||
221 | void netxen_initialize_adapter_ops(struct netxen_adapter *adapter) | 206 | void netxen_initialize_adapter_ops(struct netxen_adapter *adapter) |
222 | { | 207 | { |
223 | switch (adapter->ahw.board_type) { | 208 | switch (adapter->ahw.board_type) { |
@@ -765,18 +750,13 @@ int netxen_flash_unlock(struct netxen_adapter *adapter) | |||
765 | 750 | ||
766 | int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose) | 751 | int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose) |
767 | { | 752 | { |
768 | int addr, val, status; | 753 | int addr, val; |
769 | int n, i; | 754 | int n, i; |
770 | int init_delay = 0; | 755 | int init_delay = 0; |
771 | struct crb_addr_pair *buf; | 756 | struct crb_addr_pair *buf; |
772 | u32 off; | 757 | u32 off; |
773 | 758 | ||
774 | /* resetall */ | 759 | /* resetall */ |
775 | status = netxen_nic_get_board_info(adapter); | ||
776 | if (status) | ||
777 | printk("%s: netxen_pinit_from_rom: Error getting board info\n", | ||
778 | netxen_nic_driver_name); | ||
779 | |||
780 | netxen_crb_writelit_adapter(adapter, NETXEN_ROMUSB_GLB_SW_RESET, | 760 | netxen_crb_writelit_adapter(adapter, NETXEN_ROMUSB_GLB_SW_RESET, |
781 | NETXEN_ROMBUS_RESET); | 761 | NETXEN_ROMBUS_RESET); |
782 | 762 | ||
@@ -860,10 +840,10 @@ int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose) | |||
860 | netxen_nic_pci_change_crbwindow(adapter, 1); | 840 | netxen_nic_pci_change_crbwindow(adapter, 1); |
861 | } | 841 | } |
862 | if (init_delay == 1) { | 842 | if (init_delay == 1) { |
863 | msleep(2000); | 843 | msleep(1000); |
864 | init_delay = 0; | 844 | init_delay = 0; |
865 | } | 845 | } |
866 | msleep(20); | 846 | msleep(1); |
867 | } | 847 | } |
868 | kfree(buf); | 848 | kfree(buf); |
869 | 849 | ||
@@ -938,12 +918,28 @@ int netxen_initialize_adapter_offload(struct netxen_adapter *adapter) | |||
938 | 918 | ||
939 | void netxen_free_adapter_offload(struct netxen_adapter *adapter) | 919 | void netxen_free_adapter_offload(struct netxen_adapter *adapter) |
940 | { | 920 | { |
921 | int i; | ||
922 | |||
941 | if (adapter->dummy_dma.addr) { | 923 | if (adapter->dummy_dma.addr) { |
942 | pci_free_consistent(adapter->ahw.pdev, | 924 | i = 100; |
925 | do { | ||
926 | if (dma_watchdog_shutdown_request(adapter) == 1) | ||
927 | break; | ||
928 | msleep(50); | ||
929 | if (dma_watchdog_shutdown_poll_result(adapter) == 1) | ||
930 | break; | ||
931 | } while (--i); | ||
932 | |||
933 | if (i) { | ||
934 | pci_free_consistent(adapter->ahw.pdev, | ||
943 | NETXEN_HOST_DUMMY_DMA_SIZE, | 935 | NETXEN_HOST_DUMMY_DMA_SIZE, |
944 | adapter->dummy_dma.addr, | 936 | adapter->dummy_dma.addr, |
945 | adapter->dummy_dma.phys_addr); | 937 | adapter->dummy_dma.phys_addr); |
946 | adapter->dummy_dma.addr = NULL; | 938 | adapter->dummy_dma.addr = NULL; |
939 | } else { | ||
940 | printk(KERN_ERR "%s: dma_watchdog_shutdown failed\n", | ||
941 | adapter->netdev->name); | ||
942 | } | ||
947 | } | 943 | } |
948 | } | 944 | } |
949 | 945 | ||
diff --git a/drivers/net/netxen/netxen_nic_isr.c b/drivers/net/netxen/netxen_nic_isr.c index f487615f4063..96cec41f9019 100644 --- a/drivers/net/netxen/netxen_nic_isr.c +++ b/drivers/net/netxen/netxen_nic_isr.c | |||
@@ -145,7 +145,7 @@ static void netxen_nic_isr_other(struct netxen_adapter *adapter) | |||
145 | 145 | ||
146 | /* verify the offset */ | 146 | /* verify the offset */ |
147 | val = readl(NETXEN_CRB_NORMALIZE(adapter, CRB_XG_STATE)); | 147 | val = readl(NETXEN_CRB_NORMALIZE(adapter, CRB_XG_STATE)); |
148 | val = val >> physical_port[adapter->portnum]; | 148 | val = val >> adapter->physical_port; |
149 | if (val == adapter->ahw.qg_linksup) | 149 | if (val == adapter->ahw.qg_linksup) |
150 | return; | 150 | return; |
151 | 151 | ||
@@ -199,7 +199,7 @@ void netxen_nic_xgbe_handle_phy_intr(struct netxen_adapter *adapter) | |||
199 | 199 | ||
200 | /* WINDOW = 1 */ | 200 | /* WINDOW = 1 */ |
201 | val = readl(NETXEN_CRB_NORMALIZE(adapter, CRB_XG_STATE)); | 201 | val = readl(NETXEN_CRB_NORMALIZE(adapter, CRB_XG_STATE)); |
202 | val >>= (physical_port[adapter->portnum] * 8); | 202 | val >>= (adapter->physical_port * 8); |
203 | val &= 0xff; | 203 | val &= 0xff; |
204 | 204 | ||
205 | if (adapter->ahw.xg_linkup == 1 && val != XG_LINK_UP) { | 205 | if (adapter->ahw.xg_linkup == 1 && val != XG_LINK_UP) { |
diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c index 7144c255ce54..63cd67b931e7 100644 --- a/drivers/net/netxen/netxen_nic_main.c +++ b/drivers/net/netxen/netxen_nic_main.c | |||
@@ -70,17 +70,19 @@ static void netxen_nic_poll_controller(struct net_device *netdev); | |||
70 | static irqreturn_t netxen_intr(int irq, void *data); | 70 | static irqreturn_t netxen_intr(int irq, void *data); |
71 | static irqreturn_t netxen_msi_intr(int irq, void *data); | 71 | static irqreturn_t netxen_msi_intr(int irq, void *data); |
72 | 72 | ||
73 | int physical_port[] = {0, 1, 2, 3}; | ||
74 | |||
75 | /* PCI Device ID Table */ | 73 | /* PCI Device ID Table */ |
74 | #define ENTRY(device) \ | ||
75 | {PCI_DEVICE(0x4040, (device)), \ | ||
76 | .class = PCI_CLASS_NETWORK_ETHERNET << 8, .class_mask = ~0} | ||
77 | |||
76 | static struct pci_device_id netxen_pci_tbl[] __devinitdata = { | 78 | static struct pci_device_id netxen_pci_tbl[] __devinitdata = { |
77 | {PCI_DEVICE(0x4040, 0x0001)}, | 79 | ENTRY(0x0001), |
78 | {PCI_DEVICE(0x4040, 0x0002)}, | 80 | ENTRY(0x0002), |
79 | {PCI_DEVICE(0x4040, 0x0003)}, | 81 | ENTRY(0x0003), |
80 | {PCI_DEVICE(0x4040, 0x0004)}, | 82 | ENTRY(0x0004), |
81 | {PCI_DEVICE(0x4040, 0x0005)}, | 83 | ENTRY(0x0005), |
82 | {PCI_DEVICE(0x4040, 0x0024)}, | 84 | ENTRY(0x0024), |
83 | {PCI_DEVICE(0x4040, 0x0025)}, | 85 | ENTRY(0x0025), |
84 | {0,} | 86 | {0,} |
85 | }; | 87 | }; |
86 | 88 | ||
@@ -288,10 +290,11 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
288 | int pci_func_id = PCI_FUNC(pdev->devfn); | 290 | int pci_func_id = PCI_FUNC(pdev->devfn); |
289 | DECLARE_MAC_BUF(mac); | 291 | DECLARE_MAC_BUF(mac); |
290 | 292 | ||
291 | printk(KERN_INFO "%s \n", netxen_nic_driver_string); | 293 | if (pci_func_id == 0) |
294 | printk(KERN_INFO "%s \n", netxen_nic_driver_string); | ||
292 | 295 | ||
293 | if (pdev->class != 0x020000) { | 296 | if (pdev->class != 0x020000) { |
294 | printk(KERN_ERR"NetXen function %d, class %x will not " | 297 | printk(KERN_DEBUG "NetXen function %d, class %x will not " |
295 | "be enabled.\n",pci_func_id, pdev->class); | 298 | "be enabled.\n",pci_func_id, pdev->class); |
296 | return -ENODEV; | 299 | return -ENODEV; |
297 | } | 300 | } |
@@ -450,8 +453,12 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
450 | */ | 453 | */ |
451 | adapter->curr_window = 255; | 454 | adapter->curr_window = 255; |
452 | 455 | ||
453 | /* initialize the adapter */ | 456 | if (netxen_nic_get_board_info(adapter) != 0) { |
454 | netxen_initialize_adapter_hw(adapter); | 457 | printk("%s: Error getting board config info.\n", |
458 | netxen_nic_driver_name); | ||
459 | err = -EIO; | ||
460 | goto err_out_iounmap; | ||
461 | } | ||
455 | 462 | ||
456 | /* | 463 | /* |
457 | * Adapter in our case is quad port so initialize it before | 464 | * Adapter in our case is quad port so initialize it before |
@@ -530,17 +537,15 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
530 | netxen_initialize_adapter_sw(adapter); /* initialize the buffers in adapter */ | 537 | netxen_initialize_adapter_sw(adapter); /* initialize the buffers in adapter */ |
531 | 538 | ||
532 | /* Mezz cards have PCI function 0,2,3 enabled */ | 539 | /* Mezz cards have PCI function 0,2,3 enabled */ |
533 | if ((adapter->ahw.boardcfg.board_type == NETXEN_BRDTYPE_P2_SB31_10G_IMEZ) | 540 | switch (adapter->ahw.boardcfg.board_type) { |
534 | && (pci_func_id >= 2)) | 541 | case NETXEN_BRDTYPE_P2_SB31_10G_IMEZ: |
542 | case NETXEN_BRDTYPE_P2_SB31_10G_HMEZ: | ||
543 | if (pci_func_id >= 2) | ||
535 | adapter->portnum = pci_func_id - 2; | 544 | adapter->portnum = pci_func_id - 2; |
536 | 545 | break; | |
537 | #ifdef CONFIG_IA64 | 546 | default: |
538 | if(adapter->portnum == 0) { | 547 | break; |
539 | netxen_pinit_from_rom(adapter, 0); | ||
540 | udelay(500); | ||
541 | netxen_load_firmware(adapter); | ||
542 | } | 548 | } |
543 | #endif | ||
544 | 549 | ||
545 | init_timer(&adapter->watchdog_timer); | 550 | init_timer(&adapter->watchdog_timer); |
546 | adapter->ahw.xg_linkup = 0; | 551 | adapter->ahw.xg_linkup = 0; |
@@ -613,11 +618,18 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
613 | err = -ENODEV; | 618 | err = -ENODEV; |
614 | goto err_out_free_dev; | 619 | goto err_out_free_dev; |
615 | } | 620 | } |
621 | } else { | ||
622 | writel(0, NETXEN_CRB_NORMALIZE(adapter, | ||
623 | CRB_CMDPEG_STATE)); | ||
624 | netxen_pinit_from_rom(adapter, 0); | ||
625 | msleep(1); | ||
626 | netxen_load_firmware(adapter); | ||
627 | netxen_phantom_init(adapter, NETXEN_NIC_PEG_TUNE); | ||
616 | } | 628 | } |
617 | 629 | ||
618 | /* clear the register for future unloads/loads */ | 630 | /* clear the register for future unloads/loads */ |
619 | writel(0, NETXEN_CRB_NORMALIZE(adapter, NETXEN_CAM_RAM(0x1fc))); | 631 | writel(0, NETXEN_CRB_NORMALIZE(adapter, NETXEN_CAM_RAM(0x1fc))); |
620 | printk(KERN_INFO "State: 0x%0x\n", | 632 | dev_info(&pdev->dev, "cmdpeg state: 0x%0x\n", |
621 | readl(NETXEN_CRB_NORMALIZE(adapter, CRB_CMDPEG_STATE))); | 633 | readl(NETXEN_CRB_NORMALIZE(adapter, CRB_CMDPEG_STATE))); |
622 | 634 | ||
623 | /* | 635 | /* |
@@ -639,9 +651,10 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
639 | /* | 651 | /* |
640 | * See if the firmware gave us a virtual-physical port mapping. | 652 | * See if the firmware gave us a virtual-physical port mapping. |
641 | */ | 653 | */ |
654 | adapter->physical_port = adapter->portnum; | ||
642 | i = readl(NETXEN_CRB_NORMALIZE(adapter, CRB_V2P(adapter->portnum))); | 655 | i = readl(NETXEN_CRB_NORMALIZE(adapter, CRB_V2P(adapter->portnum))); |
643 | if (i != 0x55555555) | 656 | if (i != 0x55555555) |
644 | physical_port[adapter->portnum] = i; | 657 | adapter->physical_port = i; |
645 | 658 | ||
646 | netif_carrier_off(netdev); | 659 | netif_carrier_off(netdev); |
647 | netif_stop_queue(netdev); | 660 | netif_stop_queue(netdev); |
@@ -654,22 +667,9 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
654 | goto err_out_free_dev; | 667 | goto err_out_free_dev; |
655 | } | 668 | } |
656 | 669 | ||
670 | netxen_nic_flash_print(adapter); | ||
657 | pci_set_drvdata(pdev, adapter); | 671 | pci_set_drvdata(pdev, adapter); |
658 | 672 | ||
659 | switch (adapter->ahw.board_type) { | ||
660 | case NETXEN_NIC_GBE: | ||
661 | printk(KERN_INFO "%s: QUAD GbE board initialized\n", | ||
662 | netxen_nic_driver_name); | ||
663 | break; | ||
664 | |||
665 | case NETXEN_NIC_XGBE: | ||
666 | printk(KERN_INFO "%s: XGbE board initialized\n", | ||
667 | netxen_nic_driver_name); | ||
668 | break; | ||
669 | } | ||
670 | |||
671 | adapter->driver_mismatch = 0; | ||
672 | |||
673 | return 0; | 673 | return 0; |
674 | 674 | ||
675 | err_out_free_dev: | 675 | err_out_free_dev: |
@@ -760,55 +760,8 @@ static void __devexit netxen_nic_remove(struct pci_dev *pdev) | |||
760 | 760 | ||
761 | vfree(adapter->cmd_buf_arr); | 761 | vfree(adapter->cmd_buf_arr); |
762 | 762 | ||
763 | if (adapter->portnum == 0) { | 763 | if (adapter->portnum == 0) |
764 | if (init_firmware_done) { | 764 | netxen_free_adapter_offload(adapter); |
765 | i = 100; | ||
766 | do { | ||
767 | if (dma_watchdog_shutdown_request(adapter) == 1) | ||
768 | break; | ||
769 | msleep(100); | ||
770 | if (dma_watchdog_shutdown_poll_result(adapter) == 1) | ||
771 | break; | ||
772 | } while (--i); | ||
773 | |||
774 | if (i == 0) | ||
775 | printk(KERN_ERR "%s: dma_watchdog_shutdown failed\n", | ||
776 | netdev->name); | ||
777 | |||
778 | /* clear the register for future unloads/loads */ | ||
779 | writel(0, NETXEN_CRB_NORMALIZE(adapter, NETXEN_CAM_RAM(0x1fc))); | ||
780 | printk(KERN_INFO "State: 0x%0x\n", | ||
781 | readl(NETXEN_CRB_NORMALIZE(adapter, CRB_CMDPEG_STATE))); | ||
782 | |||
783 | /* leave the hw in the same state as reboot */ | ||
784 | writel(0, NETXEN_CRB_NORMALIZE(adapter, CRB_CMDPEG_STATE)); | ||
785 | netxen_pinit_from_rom(adapter, 0); | ||
786 | msleep(1); | ||
787 | netxen_load_firmware(adapter); | ||
788 | netxen_phantom_init(adapter, NETXEN_NIC_PEG_TUNE); | ||
789 | } | ||
790 | |||
791 | /* clear the register for future unloads/loads */ | ||
792 | writel(0, NETXEN_CRB_NORMALIZE(adapter, NETXEN_CAM_RAM(0x1fc))); | ||
793 | printk(KERN_INFO "State: 0x%0x\n", | ||
794 | readl(NETXEN_CRB_NORMALIZE(adapter, CRB_CMDPEG_STATE))); | ||
795 | |||
796 | i = 100; | ||
797 | do { | ||
798 | if (dma_watchdog_shutdown_request(adapter) == 1) | ||
799 | break; | ||
800 | msleep(100); | ||
801 | if (dma_watchdog_shutdown_poll_result(adapter) == 1) | ||
802 | break; | ||
803 | } while (--i); | ||
804 | |||
805 | if (i) { | ||
806 | netxen_free_adapter_offload(adapter); | ||
807 | } else { | ||
808 | printk(KERN_ERR "%s: dma_watchdog_shutdown failed\n", | ||
809 | netdev->name); | ||
810 | } | ||
811 | } | ||
812 | 765 | ||
813 | if (adapter->irq) | 766 | if (adapter->irq) |
814 | free_irq(adapter->irq, adapter); | 767 | free_irq(adapter->irq, adapter); |
@@ -840,13 +793,15 @@ static int netxen_nic_open(struct net_device *netdev) | |||
840 | irq_handler_t handler; | 793 | irq_handler_t handler; |
841 | unsigned long flags = IRQF_SAMPLE_RANDOM; | 794 | unsigned long flags = IRQF_SAMPLE_RANDOM; |
842 | 795 | ||
796 | if (adapter->driver_mismatch) | ||
797 | return -EIO; | ||
798 | |||
843 | if (adapter->is_up != NETXEN_ADAPTER_UP_MAGIC) { | 799 | if (adapter->is_up != NETXEN_ADAPTER_UP_MAGIC) { |
844 | err = netxen_init_firmware(adapter); | 800 | err = netxen_init_firmware(adapter); |
845 | if (err != 0) { | 801 | if (err != 0) { |
846 | printk(KERN_ERR "Failed to init firmware\n"); | 802 | printk(KERN_ERR "Failed to init firmware\n"); |
847 | return -EIO; | 803 | return -EIO; |
848 | } | 804 | } |
849 | netxen_nic_flash_print(adapter); | ||
850 | 805 | ||
851 | /* setup all the resources for the Phantom... */ | 806 | /* setup all the resources for the Phantom... */ |
852 | /* this include the descriptors for rcv, tx, and status */ | 807 | /* this include the descriptors for rcv, tx, and status */ |
@@ -895,14 +850,12 @@ static int netxen_nic_open(struct net_device *netdev) | |||
895 | if (adapter->set_mtu) | 850 | if (adapter->set_mtu) |
896 | adapter->set_mtu(adapter, netdev->mtu); | 851 | adapter->set_mtu(adapter, netdev->mtu); |
897 | 852 | ||
898 | if (!adapter->driver_mismatch) | 853 | mod_timer(&adapter->watchdog_timer, jiffies); |
899 | mod_timer(&adapter->watchdog_timer, jiffies); | ||
900 | 854 | ||
901 | napi_enable(&adapter->napi); | 855 | napi_enable(&adapter->napi); |
902 | netxen_nic_enable_int(adapter); | 856 | netxen_nic_enable_int(adapter); |
903 | 857 | ||
904 | if (!adapter->driver_mismatch) | 858 | netif_start_queue(netdev); |
905 | netif_start_queue(netdev); | ||
906 | 859 | ||
907 | return 0; | 860 | return 0; |
908 | } | 861 | } |
diff --git a/drivers/net/netxen/netxen_nic_niu.c b/drivers/net/netxen/netxen_nic_niu.c index 1c852a76c80d..a3bc7cc67a6f 100644 --- a/drivers/net/netxen/netxen_nic_niu.c +++ b/drivers/net/netxen/netxen_nic_niu.c | |||
@@ -94,7 +94,7 @@ int netxen_niu_gbe_phy_read(struct netxen_adapter *adapter, long reg, | |||
94 | long timeout = 0; | 94 | long timeout = 0; |
95 | long result = 0; | 95 | long result = 0; |
96 | long restore = 0; | 96 | long restore = 0; |
97 | long phy = physical_port[adapter->portnum]; | 97 | long phy = adapter->physical_port; |
98 | __u32 address; | 98 | __u32 address; |
99 | __u32 command; | 99 | __u32 command; |
100 | __u32 status; | 100 | __u32 status; |
@@ -190,7 +190,7 @@ int netxen_niu_gbe_phy_write(struct netxen_adapter *adapter, long reg, | |||
190 | long timeout = 0; | 190 | long timeout = 0; |
191 | long result = 0; | 191 | long result = 0; |
192 | long restore = 0; | 192 | long restore = 0; |
193 | long phy = physical_port[adapter->portnum]; | 193 | long phy = adapter->physical_port; |
194 | __u32 address; | 194 | __u32 address; |
195 | __u32 command; | 195 | __u32 command; |
196 | __u32 status; | 196 | __u32 status; |
@@ -456,7 +456,7 @@ int netxen_niu_gbe_init_port(struct netxen_adapter *adapter, int port) | |||
456 | 456 | ||
457 | int netxen_niu_xg_init_port(struct netxen_adapter *adapter, int port) | 457 | int netxen_niu_xg_init_port(struct netxen_adapter *adapter, int port) |
458 | { | 458 | { |
459 | u32 portnum = physical_port[adapter->portnum]; | 459 | u32 portnum = adapter->physical_port; |
460 | 460 | ||
461 | netxen_crb_writelit_adapter(adapter, | 461 | netxen_crb_writelit_adapter(adapter, |
462 | NETXEN_NIU_XGE_CONFIG_1+(0x10000*portnum), 0x1447); | 462 | NETXEN_NIU_XGE_CONFIG_1+(0x10000*portnum), 0x1447); |
@@ -573,7 +573,7 @@ static int netxen_niu_macaddr_get(struct netxen_adapter *adapter, | |||
573 | { | 573 | { |
574 | u32 stationhigh; | 574 | u32 stationhigh; |
575 | u32 stationlow; | 575 | u32 stationlow; |
576 | int phy = physical_port[adapter->portnum]; | 576 | int phy = adapter->physical_port; |
577 | u8 val[8]; | 577 | u8 val[8]; |
578 | 578 | ||
579 | if (addr == NULL) | 579 | if (addr == NULL) |
@@ -604,7 +604,7 @@ int netxen_niu_macaddr_set(struct netxen_adapter *adapter, | |||
604 | { | 604 | { |
605 | u8 temp[4]; | 605 | u8 temp[4]; |
606 | u32 val; | 606 | u32 val; |
607 | int phy = physical_port[adapter->portnum]; | 607 | int phy = adapter->physical_port; |
608 | unsigned char mac_addr[6]; | 608 | unsigned char mac_addr[6]; |
609 | int i; | 609 | int i; |
610 | DECLARE_MAC_BUF(mac); | 610 | DECLARE_MAC_BUF(mac); |
@@ -724,7 +724,7 @@ int netxen_niu_enable_gbe_port(struct netxen_adapter *adapter, | |||
724 | int netxen_niu_disable_gbe_port(struct netxen_adapter *adapter) | 724 | int netxen_niu_disable_gbe_port(struct netxen_adapter *adapter) |
725 | { | 725 | { |
726 | __u32 mac_cfg0; | 726 | __u32 mac_cfg0; |
727 | u32 port = physical_port[adapter->portnum]; | 727 | u32 port = adapter->physical_port; |
728 | 728 | ||
729 | if (port > NETXEN_NIU_MAX_GBE_PORTS) | 729 | if (port > NETXEN_NIU_MAX_GBE_PORTS) |
730 | return -EINVAL; | 730 | return -EINVAL; |
@@ -740,7 +740,7 @@ int netxen_niu_disable_gbe_port(struct netxen_adapter *adapter) | |||
740 | int netxen_niu_disable_xg_port(struct netxen_adapter *adapter) | 740 | int netxen_niu_disable_xg_port(struct netxen_adapter *adapter) |
741 | { | 741 | { |
742 | __u32 mac_cfg; | 742 | __u32 mac_cfg; |
743 | u32 port = physical_port[adapter->portnum]; | 743 | u32 port = adapter->physical_port; |
744 | 744 | ||
745 | if (port > NETXEN_NIU_MAX_XG_PORTS) | 745 | if (port > NETXEN_NIU_MAX_XG_PORTS) |
746 | return -EINVAL; | 746 | return -EINVAL; |
@@ -757,7 +757,7 @@ int netxen_niu_set_promiscuous_mode(struct netxen_adapter *adapter, | |||
757 | netxen_niu_prom_mode_t mode) | 757 | netxen_niu_prom_mode_t mode) |
758 | { | 758 | { |
759 | __u32 reg; | 759 | __u32 reg; |
760 | u32 port = physical_port[adapter->portnum]; | 760 | u32 port = adapter->physical_port; |
761 | 761 | ||
762 | if (port > NETXEN_NIU_MAX_GBE_PORTS) | 762 | if (port > NETXEN_NIU_MAX_GBE_PORTS) |
763 | return -EINVAL; | 763 | return -EINVAL; |
@@ -814,7 +814,7 @@ int netxen_niu_set_promiscuous_mode(struct netxen_adapter *adapter, | |||
814 | int netxen_niu_xg_macaddr_set(struct netxen_adapter *adapter, | 814 | int netxen_niu_xg_macaddr_set(struct netxen_adapter *adapter, |
815 | netxen_ethernet_macaddr_t addr) | 815 | netxen_ethernet_macaddr_t addr) |
816 | { | 816 | { |
817 | int phy = physical_port[adapter->portnum]; | 817 | int phy = adapter->physical_port; |
818 | u8 temp[4]; | 818 | u8 temp[4]; |
819 | u32 val; | 819 | u32 val; |
820 | 820 | ||
@@ -867,7 +867,7 @@ int netxen_niu_xg_macaddr_set(struct netxen_adapter *adapter, | |||
867 | int netxen_niu_xg_macaddr_get(struct netxen_adapter *adapter, | 867 | int netxen_niu_xg_macaddr_get(struct netxen_adapter *adapter, |
868 | netxen_ethernet_macaddr_t * addr) | 868 | netxen_ethernet_macaddr_t * addr) |
869 | { | 869 | { |
870 | int phy = physical_port[adapter->portnum]; | 870 | int phy = adapter->physical_port; |
871 | u32 stationhigh; | 871 | u32 stationhigh; |
872 | u32 stationlow; | 872 | u32 stationlow; |
873 | u8 val[8]; | 873 | u8 val[8]; |
@@ -896,7 +896,7 @@ int netxen_niu_xg_set_promiscuous_mode(struct netxen_adapter *adapter, | |||
896 | netxen_niu_prom_mode_t mode) | 896 | netxen_niu_prom_mode_t mode) |
897 | { | 897 | { |
898 | __u32 reg; | 898 | __u32 reg; |
899 | u32 port = physical_port[adapter->portnum]; | 899 | u32 port = adapter->physical_port; |
900 | 900 | ||
901 | if (port > NETXEN_NIU_MAX_XG_PORTS) | 901 | if (port > NETXEN_NIU_MAX_XG_PORTS) |
902 | return -EINVAL; | 902 | return -EINVAL; |
diff --git a/drivers/net/niu.c b/drivers/net/niu.c index 4009c4ce96b4..918f802fe089 100644 --- a/drivers/net/niu.c +++ b/drivers/net/niu.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* niu.c: Neptune ethernet driver. | 1 | /* niu.c: Neptune ethernet driver. |
2 | * | 2 | * |
3 | * Copyright (C) 2007 David S. Miller (davem@davemloft.net) | 3 | * Copyright (C) 2007, 2008 David S. Miller (davem@davemloft.net) |
4 | */ | 4 | */ |
5 | 5 | ||
6 | #include <linux/module.h> | 6 | #include <linux/module.h> |
@@ -33,8 +33,8 @@ | |||
33 | 33 | ||
34 | #define DRV_MODULE_NAME "niu" | 34 | #define DRV_MODULE_NAME "niu" |
35 | #define PFX DRV_MODULE_NAME ": " | 35 | #define PFX DRV_MODULE_NAME ": " |
36 | #define DRV_MODULE_VERSION "0.8" | 36 | #define DRV_MODULE_VERSION "0.9" |
37 | #define DRV_MODULE_RELDATE "April 24, 2008" | 37 | #define DRV_MODULE_RELDATE "May 4, 2008" |
38 | 38 | ||
39 | static char version[] __devinitdata = | 39 | static char version[] __devinitdata = |
40 | DRV_MODULE_NAME ".c:v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n"; | 40 | DRV_MODULE_NAME ".c:v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n"; |
@@ -865,7 +865,6 @@ static int link_status_1g_serdes(struct niu *np, int *link_up_p) | |||
865 | return 0; | 865 | return 0; |
866 | } | 866 | } |
867 | 867 | ||
868 | |||
869 | static int link_status_10g_serdes(struct niu *np, int *link_up_p) | 868 | static int link_status_10g_serdes(struct niu *np, int *link_up_p) |
870 | { | 869 | { |
871 | unsigned long flags; | 870 | unsigned long flags; |
@@ -900,7 +899,6 @@ static int link_status_10g_serdes(struct niu *np, int *link_up_p) | |||
900 | return 0; | 899 | return 0; |
901 | } | 900 | } |
902 | 901 | ||
903 | |||
904 | static int link_status_1g_rgmii(struct niu *np, int *link_up_p) | 902 | static int link_status_1g_rgmii(struct niu *np, int *link_up_p) |
905 | { | 903 | { |
906 | struct niu_link_config *lp = &np->link_config; | 904 | struct niu_link_config *lp = &np->link_config; |
@@ -957,7 +955,6 @@ out: | |||
957 | return err; | 955 | return err; |
958 | } | 956 | } |
959 | 957 | ||
960 | |||
961 | static int bcm8704_reset(struct niu *np) | 958 | static int bcm8704_reset(struct niu *np) |
962 | { | 959 | { |
963 | int err, limit; | 960 | int err, limit; |
@@ -1357,8 +1354,6 @@ static int mii_reset(struct niu *np) | |||
1357 | return 0; | 1354 | return 0; |
1358 | } | 1355 | } |
1359 | 1356 | ||
1360 | |||
1361 | |||
1362 | static int xcvr_init_1g_rgmii(struct niu *np) | 1357 | static int xcvr_init_1g_rgmii(struct niu *np) |
1363 | { | 1358 | { |
1364 | int err; | 1359 | int err; |
@@ -1419,7 +1414,6 @@ static int xcvr_init_1g_rgmii(struct niu *np) | |||
1419 | return 0; | 1414 | return 0; |
1420 | } | 1415 | } |
1421 | 1416 | ||
1422 | |||
1423 | static int mii_init_common(struct niu *np) | 1417 | static int mii_init_common(struct niu *np) |
1424 | { | 1418 | { |
1425 | struct niu_link_config *lp = &np->link_config; | 1419 | struct niu_link_config *lp = &np->link_config; |
@@ -7008,31 +7002,20 @@ static int __devinit niu_phy_type_prop_decode(struct niu *np, | |||
7008 | return 0; | 7002 | return 0; |
7009 | } | 7003 | } |
7010 | 7004 | ||
7011 | /* niu board models have a trailing dash version incremented | ||
7012 | * with HW rev change. Need to ingnore the dash version while | ||
7013 | * checking for match | ||
7014 | * | ||
7015 | * for example, for the 10G card the current vpd.board_model | ||
7016 | * is 501-5283-04, of which -04 is the dash version and have | ||
7017 | * to be ignored | ||
7018 | */ | ||
7019 | static int niu_board_model_match(struct niu *np, const char *model) | ||
7020 | { | ||
7021 | return !strncmp(np->vpd.board_model, model, strlen(model)); | ||
7022 | } | ||
7023 | |||
7024 | static int niu_pci_vpd_get_nports(struct niu *np) | 7005 | static int niu_pci_vpd_get_nports(struct niu *np) |
7025 | { | 7006 | { |
7026 | int ports = 0; | 7007 | int ports = 0; |
7027 | 7008 | ||
7028 | if ((niu_board_model_match(np, NIU_QGC_LP_BM_STR)) || | 7009 | if ((!strcmp(np->vpd.model, NIU_QGC_LP_MDL_STR)) || |
7029 | (niu_board_model_match(np, NIU_QGC_PEM_BM_STR)) || | 7010 | (!strcmp(np->vpd.model, NIU_QGC_PEM_MDL_STR)) || |
7030 | (niu_board_model_match(np, NIU_ALONSO_BM_STR))) { | 7011 | (!strcmp(np->vpd.model, NIU_MARAMBA_MDL_STR)) || |
7012 | (!strcmp(np->vpd.model, NIU_KIMI_MDL_STR)) || | ||
7013 | (!strcmp(np->vpd.model, NIU_ALONSO_MDL_STR))) { | ||
7031 | ports = 4; | 7014 | ports = 4; |
7032 | } else if ((niu_board_model_match(np, NIU_2XGF_LP_BM_STR)) || | 7015 | } else if ((!strcmp(np->vpd.model, NIU_2XGF_LP_MDL_STR)) || |
7033 | (niu_board_model_match(np, NIU_2XGF_PEM_BM_STR)) || | 7016 | (!strcmp(np->vpd.model, NIU_2XGF_PEM_MDL_STR)) || |
7034 | (niu_board_model_match(np, NIU_FOXXY_BM_STR)) || | 7017 | (!strcmp(np->vpd.model, NIU_FOXXY_MDL_STR)) || |
7035 | (niu_board_model_match(np, NIU_2XGF_MRVL_BM_STR))) { | 7018 | (!strcmp(np->vpd.model, NIU_2XGF_MRVL_MDL_STR))) { |
7036 | ports = 2; | 7019 | ports = 2; |
7037 | } | 7020 | } |
7038 | 7021 | ||
@@ -7053,8 +7036,8 @@ static void __devinit niu_pci_vpd_validate(struct niu *np) | |||
7053 | return; | 7036 | return; |
7054 | } | 7037 | } |
7055 | 7038 | ||
7056 | if (!strcmp(np->vpd.model, "SUNW,CP3220") || | 7039 | if (!strcmp(np->vpd.model, NIU_ALONSO_MDL_STR) || |
7057 | !strcmp(np->vpd.model, "SUNW,CP3260")) { | 7040 | !strcmp(np->vpd.model, NIU_KIMI_MDL_STR)) { |
7058 | np->flags |= NIU_FLAGS_10G; | 7041 | np->flags |= NIU_FLAGS_10G; |
7059 | np->flags &= ~NIU_FLAGS_FIBER; | 7042 | np->flags &= ~NIU_FLAGS_FIBER; |
7060 | np->flags |= NIU_FLAGS_XCVR_SERDES; | 7043 | np->flags |= NIU_FLAGS_XCVR_SERDES; |
@@ -7065,7 +7048,7 @@ static void __devinit niu_pci_vpd_validate(struct niu *np) | |||
7065 | } | 7048 | } |
7066 | if (np->flags & NIU_FLAGS_10G) | 7049 | if (np->flags & NIU_FLAGS_10G) |
7067 | np->mac_xcvr = MAC_XCVR_XPCS; | 7050 | np->mac_xcvr = MAC_XCVR_XPCS; |
7068 | } else if (niu_board_model_match(np, NIU_FOXXY_BM_STR)) { | 7051 | } else if (!strcmp(np->vpd.model, NIU_FOXXY_MDL_STR)) { |
7069 | np->flags |= (NIU_FLAGS_10G | NIU_FLAGS_FIBER | | 7052 | np->flags |= (NIU_FLAGS_10G | NIU_FLAGS_FIBER | |
7070 | NIU_FLAGS_HOTPLUG_PHY); | 7053 | NIU_FLAGS_HOTPLUG_PHY); |
7071 | } else if (niu_phy_type_prop_decode(np, np->vpd.phy_type)) { | 7054 | } else if (niu_phy_type_prop_decode(np, np->vpd.phy_type)) { |
@@ -7264,8 +7247,11 @@ static int __devinit niu_get_and_validate_port(struct niu *np) | |||
7264 | parent->num_ports = nr64(ESPC_NUM_PORTS_MACS) & | 7247 | parent->num_ports = nr64(ESPC_NUM_PORTS_MACS) & |
7265 | ESPC_NUM_PORTS_MACS_VAL; | 7248 | ESPC_NUM_PORTS_MACS_VAL; |
7266 | 7249 | ||
7250 | /* All of the current probing methods fail on | ||
7251 | * Maramba on-board parts. | ||
7252 | */ | ||
7267 | if (!parent->num_ports) | 7253 | if (!parent->num_ports) |
7268 | return -ENODEV; | 7254 | parent->num_ports = 4; |
7269 | } | 7255 | } |
7270 | } | 7256 | } |
7271 | } | 7257 | } |
@@ -7538,8 +7524,8 @@ static int __devinit walk_phys(struct niu *np, struct niu_parent *parent) | |||
7538 | u32 val; | 7524 | u32 val; |
7539 | int err; | 7525 | int err; |
7540 | 7526 | ||
7541 | if (!strcmp(np->vpd.model, "SUNW,CP3220") || | 7527 | if (!strcmp(np->vpd.model, NIU_ALONSO_MDL_STR) || |
7542 | !strcmp(np->vpd.model, "SUNW,CP3260")) { | 7528 | !strcmp(np->vpd.model, NIU_KIMI_MDL_STR)) { |
7543 | num_10g = 0; | 7529 | num_10g = 0; |
7544 | num_1g = 2; | 7530 | num_1g = 2; |
7545 | parent->plat_type = PLAT_TYPE_ATCA_CP3220; | 7531 | parent->plat_type = PLAT_TYPE_ATCA_CP3220; |
@@ -7548,7 +7534,7 @@ static int __devinit walk_phys(struct niu *np, struct niu_parent *parent) | |||
7548 | phy_encode(PORT_TYPE_1G, 1) | | 7534 | phy_encode(PORT_TYPE_1G, 1) | |
7549 | phy_encode(PORT_TYPE_1G, 2) | | 7535 | phy_encode(PORT_TYPE_1G, 2) | |
7550 | phy_encode(PORT_TYPE_1G, 3)); | 7536 | phy_encode(PORT_TYPE_1G, 3)); |
7551 | } else if (niu_board_model_match(np, NIU_FOXXY_BM_STR)) { | 7537 | } else if (!strcmp(np->vpd.model, NIU_FOXXY_MDL_STR)) { |
7552 | num_10g = 2; | 7538 | num_10g = 2; |
7553 | num_1g = 0; | 7539 | num_1g = 0; |
7554 | parent->num_ports = 2; | 7540 | parent->num_ports = 2; |
@@ -7943,6 +7929,7 @@ static int __devinit niu_get_of_props(struct niu *np) | |||
7943 | struct device_node *dp; | 7929 | struct device_node *dp; |
7944 | const char *phy_type; | 7930 | const char *phy_type; |
7945 | const u8 *mac_addr; | 7931 | const u8 *mac_addr; |
7932 | const char *model; | ||
7946 | int prop_len; | 7933 | int prop_len; |
7947 | 7934 | ||
7948 | if (np->parent->plat_type == PLAT_TYPE_NIU) | 7935 | if (np->parent->plat_type == PLAT_TYPE_NIU) |
@@ -7997,6 +7984,11 @@ static int __devinit niu_get_of_props(struct niu *np) | |||
7997 | 7984 | ||
7998 | memcpy(dev->dev_addr, dev->perm_addr, dev->addr_len); | 7985 | memcpy(dev->dev_addr, dev->perm_addr, dev->addr_len); |
7999 | 7986 | ||
7987 | model = of_get_property(dp, "model", &prop_len); | ||
7988 | |||
7989 | if (model) | ||
7990 | strcpy(np->vpd.model, model); | ||
7991 | |||
8000 | return 0; | 7992 | return 0; |
8001 | #else | 7993 | #else |
8002 | return -EINVAL; | 7994 | return -EINVAL; |
diff --git a/drivers/net/niu.h b/drivers/net/niu.h index 97ffbe137bcb..12fd570b9423 100644 --- a/drivers/net/niu.h +++ b/drivers/net/niu.h | |||
@@ -2946,6 +2946,15 @@ struct rx_ring_info { | |||
2946 | #define NIU_ALONSO_BM_STR "373-0202" | 2946 | #define NIU_ALONSO_BM_STR "373-0202" |
2947 | #define NIU_FOXXY_BM_STR "501-7961" | 2947 | #define NIU_FOXXY_BM_STR "501-7961" |
2948 | #define NIU_2XGF_MRVL_BM_STR "SK-6E82" | 2948 | #define NIU_2XGF_MRVL_BM_STR "SK-6E82" |
2949 | #define NIU_QGC_LP_MDL_STR "SUNW,pcie-qgc" | ||
2950 | #define NIU_2XGF_LP_MDL_STR "SUNW,pcie-2xgf" | ||
2951 | #define NIU_QGC_PEM_MDL_STR "SUNW,pcie-qgc-pem" | ||
2952 | #define NIU_2XGF_PEM_MDL_STR "SUNW,pcie-2xgf-pem" | ||
2953 | #define NIU_ALONSO_MDL_STR "SUNW,CP3220" | ||
2954 | #define NIU_KIMI_MDL_STR "SUNW,CP3260" | ||
2955 | #define NIU_MARAMBA_MDL_STR "SUNW,pcie-neptune" | ||
2956 | #define NIU_FOXXY_MDL_STR "SUNW,pcie-rfem" | ||
2957 | #define NIU_2XGF_MRVL_MDL_STR "SysKonnect,pcie-2xgf" | ||
2949 | 2958 | ||
2950 | #define NIU_VPD_MIN_MAJOR 3 | 2959 | #define NIU_VPD_MIN_MAJOR 3 |
2951 | #define NIU_VPD_MIN_MINOR 4 | 2960 | #define NIU_VPD_MIN_MINOR 4 |
diff --git a/drivers/net/pasemi_mac.c b/drivers/net/pasemi_mac.c index 3b2a6c598088..993d87c9296f 100644 --- a/drivers/net/pasemi_mac.c +++ b/drivers/net/pasemi_mac.c | |||
@@ -277,7 +277,7 @@ static int get_skb_hdr(struct sk_buff *skb, void **iphdr, | |||
277 | *tcph = tcp_hdr(skb); | 277 | *tcph = tcp_hdr(skb); |
278 | 278 | ||
279 | /* check if ip header and tcp header are complete */ | 279 | /* check if ip header and tcp header are complete */ |
280 | if (iph->tot_len < ip_len + tcp_hdrlen(skb)) | 280 | if (ntohs(iph->tot_len) < ip_len + tcp_hdrlen(skb)) |
281 | return -1; | 281 | return -1; |
282 | 282 | ||
283 | *hdr_flags = LRO_IPV4 | LRO_TCP; | 283 | *hdr_flags = LRO_IPV4 | LRO_TCP; |
diff --git a/drivers/net/pcmcia/axnet_cs.c b/drivers/net/pcmcia/axnet_cs.c index ce95c5d168fe..70d012e90dcf 100644 --- a/drivers/net/pcmcia/axnet_cs.c +++ b/drivers/net/pcmcia/axnet_cs.c | |||
@@ -525,12 +525,14 @@ static int axnet_open(struct net_device *dev) | |||
525 | int ret; | 525 | int ret; |
526 | axnet_dev_t *info = PRIV(dev); | 526 | axnet_dev_t *info = PRIV(dev); |
527 | struct pcmcia_device *link = info->p_dev; | 527 | struct pcmcia_device *link = info->p_dev; |
528 | unsigned int nic_base = dev->base_addr; | ||
528 | 529 | ||
529 | DEBUG(2, "axnet_open('%s')\n", dev->name); | 530 | DEBUG(2, "axnet_open('%s')\n", dev->name); |
530 | 531 | ||
531 | if (!pcmcia_dev_present(link)) | 532 | if (!pcmcia_dev_present(link)) |
532 | return -ENODEV; | 533 | return -ENODEV; |
533 | 534 | ||
535 | outb_p(0xFF, nic_base + EN0_ISR); /* Clear bogus intr. */ | ||
534 | ret = request_irq(dev->irq, ei_irq_wrapper, IRQF_SHARED, "axnet_cs", dev); | 536 | ret = request_irq(dev->irq, ei_irq_wrapper, IRQF_SHARED, "axnet_cs", dev); |
535 | if (ret) | 537 | if (ret) |
536 | return ret; | 538 | return ret; |
diff --git a/drivers/net/pcmcia/fmvj18x_cs.c b/drivers/net/pcmcia/fmvj18x_cs.c index 8f328a03847b..a550c9bd126f 100644 --- a/drivers/net/pcmcia/fmvj18x_cs.c +++ b/drivers/net/pcmcia/fmvj18x_cs.c | |||
@@ -391,7 +391,9 @@ static int fmvj18x_config(struct pcmcia_device *link) | |||
391 | cardtype = CONTEC; | 391 | cardtype = CONTEC; |
392 | break; | 392 | break; |
393 | case MANFID_FUJITSU: | 393 | case MANFID_FUJITSU: |
394 | if (link->card_id == PRODID_FUJITSU_MBH10302) | 394 | if (link->conf.ConfigBase == 0x0fe0) |
395 | cardtype = MBH10302; | ||
396 | else if (link->card_id == PRODID_FUJITSU_MBH10302) | ||
395 | /* RATOC REX-5588/9822/4886's PRODID are 0004(=MBH10302), | 397 | /* RATOC REX-5588/9822/4886's PRODID are 0004(=MBH10302), |
396 | but these are MBH10304 based card. */ | 398 | but these are MBH10304 based card. */ |
397 | cardtype = MBH10304; | 399 | cardtype = MBH10304; |
diff --git a/drivers/net/pcmcia/pcnet_cs.c b/drivers/net/pcmcia/pcnet_cs.c index fd8158a86f64..2d4c4ad89b8d 100644 --- a/drivers/net/pcmcia/pcnet_cs.c +++ b/drivers/net/pcmcia/pcnet_cs.c | |||
@@ -969,6 +969,7 @@ static int pcnet_open(struct net_device *dev) | |||
969 | int ret; | 969 | int ret; |
970 | pcnet_dev_t *info = PRIV(dev); | 970 | pcnet_dev_t *info = PRIV(dev); |
971 | struct pcmcia_device *link = info->p_dev; | 971 | struct pcmcia_device *link = info->p_dev; |
972 | unsigned int nic_base = dev->base_addr; | ||
972 | 973 | ||
973 | DEBUG(2, "pcnet_open('%s')\n", dev->name); | 974 | DEBUG(2, "pcnet_open('%s')\n", dev->name); |
974 | 975 | ||
@@ -976,6 +977,8 @@ static int pcnet_open(struct net_device *dev) | |||
976 | return -ENODEV; | 977 | return -ENODEV; |
977 | 978 | ||
978 | set_misc_reg(dev); | 979 | set_misc_reg(dev); |
980 | |||
981 | outb_p(0xFF, nic_base + EN0_ISR); /* Clear bogus intr. */ | ||
979 | ret = request_irq(dev->irq, ei_irq_wrapper, IRQF_SHARED, dev_info, dev); | 982 | ret = request_irq(dev->irq, ei_irq_wrapper, IRQF_SHARED, dev_info, dev); |
980 | if (ret) | 983 | if (ret) |
981 | return ret; | 984 | return ret; |
diff --git a/drivers/net/pcmcia/xirc2ps_cs.c b/drivers/net/pcmcia/xirc2ps_cs.c index d041f831a18d..f6c4698ce738 100644 --- a/drivers/net/pcmcia/xirc2ps_cs.c +++ b/drivers/net/pcmcia/xirc2ps_cs.c | |||
@@ -1461,22 +1461,25 @@ static void | |||
1461 | set_multicast_list(struct net_device *dev) | 1461 | set_multicast_list(struct net_device *dev) |
1462 | { | 1462 | { |
1463 | unsigned int ioaddr = dev->base_addr; | 1463 | unsigned int ioaddr = dev->base_addr; |
1464 | unsigned value; | ||
1464 | 1465 | ||
1465 | SelectPage(0x42); | 1466 | SelectPage(0x42); |
1467 | value = GetByte(XIRCREG42_SWC1) & 0xC0; | ||
1468 | |||
1466 | if (dev->flags & IFF_PROMISC) { /* snoop */ | 1469 | if (dev->flags & IFF_PROMISC) { /* snoop */ |
1467 | PutByte(XIRCREG42_SWC1, 0x06); /* set MPE and PME */ | 1470 | PutByte(XIRCREG42_SWC1, value | 0x06); /* set MPE and PME */ |
1468 | } else if (dev->mc_count > 9 || (dev->flags & IFF_ALLMULTI)) { | 1471 | } else if (dev->mc_count > 9 || (dev->flags & IFF_ALLMULTI)) { |
1469 | PutByte(XIRCREG42_SWC1, 0x02); /* set MPE */ | 1472 | PutByte(XIRCREG42_SWC1, value | 0x02); /* set MPE */ |
1470 | } else if (dev->mc_count) { | 1473 | } else if (dev->mc_count) { |
1471 | /* the chip can filter 9 addresses perfectly */ | 1474 | /* the chip can filter 9 addresses perfectly */ |
1472 | PutByte(XIRCREG42_SWC1, 0x01); | 1475 | PutByte(XIRCREG42_SWC1, value | 0x01); |
1473 | SelectPage(0x40); | 1476 | SelectPage(0x40); |
1474 | PutByte(XIRCREG40_CMD0, Offline); | 1477 | PutByte(XIRCREG40_CMD0, Offline); |
1475 | set_addresses(dev); | 1478 | set_addresses(dev); |
1476 | SelectPage(0x40); | 1479 | SelectPage(0x40); |
1477 | PutByte(XIRCREG40_CMD0, EnableRecv | Online); | 1480 | PutByte(XIRCREG40_CMD0, EnableRecv | Online); |
1478 | } else { /* standard usage */ | 1481 | } else { /* standard usage */ |
1479 | PutByte(XIRCREG42_SWC1, 0x00); | 1482 | PutByte(XIRCREG42_SWC1, value | 0x00); |
1480 | } | 1483 | } |
1481 | SelectPage(0); | 1484 | SelectPage(0); |
1482 | } | 1485 | } |
@@ -1722,6 +1725,7 @@ do_reset(struct net_device *dev, int full) | |||
1722 | 1725 | ||
1723 | /* enable receiver and put the mac online */ | 1726 | /* enable receiver and put the mac online */ |
1724 | if (full) { | 1727 | if (full) { |
1728 | set_multicast_list(dev); | ||
1725 | SelectPage(0x40); | 1729 | SelectPage(0x40); |
1726 | PutByte(XIRCREG40_CMD0, EnableRecv | Online); | 1730 | PutByte(XIRCREG40_CMD0, EnableRecv | Online); |
1727 | } | 1731 | } |
diff --git a/drivers/net/pcnet32.c b/drivers/net/pcnet32.c index 4eb322e5273d..1c89b97f4e09 100644 --- a/drivers/net/pcnet32.c +++ b/drivers/net/pcnet32.c | |||
@@ -22,12 +22,8 @@ | |||
22 | *************************************************************************/ | 22 | *************************************************************************/ |
23 | 23 | ||
24 | #define DRV_NAME "pcnet32" | 24 | #define DRV_NAME "pcnet32" |
25 | #ifdef CONFIG_PCNET32_NAPI | 25 | #define DRV_VERSION "1.35" |
26 | #define DRV_VERSION "1.34-NAPI" | 26 | #define DRV_RELDATE "21.Apr.2008" |
27 | #else | ||
28 | #define DRV_VERSION "1.34" | ||
29 | #endif | ||
30 | #define DRV_RELDATE "14.Aug.2007" | ||
31 | #define PFX DRV_NAME ": " | 27 | #define PFX DRV_NAME ": " |
32 | 28 | ||
33 | static const char *const version = | 29 | static const char *const version = |
@@ -329,7 +325,7 @@ static int pcnet32_get_regs_len(struct net_device *dev); | |||
329 | static void pcnet32_get_regs(struct net_device *dev, struct ethtool_regs *regs, | 325 | static void pcnet32_get_regs(struct net_device *dev, struct ethtool_regs *regs, |
330 | void *ptr); | 326 | void *ptr); |
331 | static void pcnet32_purge_tx_ring(struct net_device *dev); | 327 | static void pcnet32_purge_tx_ring(struct net_device *dev); |
332 | static int pcnet32_alloc_ring(struct net_device *dev, char *name); | 328 | static int pcnet32_alloc_ring(struct net_device *dev, const char *name); |
333 | static void pcnet32_free_ring(struct net_device *dev); | 329 | static void pcnet32_free_ring(struct net_device *dev); |
334 | static void pcnet32_check_media(struct net_device *dev, int verbose); | 330 | static void pcnet32_check_media(struct net_device *dev, int verbose); |
335 | 331 | ||
@@ -445,30 +441,24 @@ static struct pcnet32_access pcnet32_dwio = { | |||
445 | 441 | ||
446 | static void pcnet32_netif_stop(struct net_device *dev) | 442 | static void pcnet32_netif_stop(struct net_device *dev) |
447 | { | 443 | { |
448 | #ifdef CONFIG_PCNET32_NAPI | ||
449 | struct pcnet32_private *lp = netdev_priv(dev); | 444 | struct pcnet32_private *lp = netdev_priv(dev); |
450 | #endif | 445 | |
451 | dev->trans_start = jiffies; | 446 | dev->trans_start = jiffies; |
452 | #ifdef CONFIG_PCNET32_NAPI | ||
453 | napi_disable(&lp->napi); | 447 | napi_disable(&lp->napi); |
454 | #endif | ||
455 | netif_tx_disable(dev); | 448 | netif_tx_disable(dev); |
456 | } | 449 | } |
457 | 450 | ||
458 | static void pcnet32_netif_start(struct net_device *dev) | 451 | static void pcnet32_netif_start(struct net_device *dev) |
459 | { | 452 | { |
460 | #ifdef CONFIG_PCNET32_NAPI | ||
461 | struct pcnet32_private *lp = netdev_priv(dev); | 453 | struct pcnet32_private *lp = netdev_priv(dev); |
462 | ulong ioaddr = dev->base_addr; | 454 | ulong ioaddr = dev->base_addr; |
463 | u16 val; | 455 | u16 val; |
464 | #endif | 456 | |
465 | netif_wake_queue(dev); | 457 | netif_wake_queue(dev); |
466 | #ifdef CONFIG_PCNET32_NAPI | ||
467 | val = lp->a.read_csr(ioaddr, CSR3); | 458 | val = lp->a.read_csr(ioaddr, CSR3); |
468 | val &= 0x00ff; | 459 | val &= 0x00ff; |
469 | lp->a.write_csr(ioaddr, CSR3, val); | 460 | lp->a.write_csr(ioaddr, CSR3, val); |
470 | napi_enable(&lp->napi); | 461 | napi_enable(&lp->napi); |
471 | #endif | ||
472 | } | 462 | } |
473 | 463 | ||
474 | /* | 464 | /* |
@@ -911,11 +901,7 @@ static int pcnet32_loopback_test(struct net_device *dev, uint64_t * data1) | |||
911 | rc = 1; /* default to fail */ | 901 | rc = 1; /* default to fail */ |
912 | 902 | ||
913 | if (netif_running(dev)) | 903 | if (netif_running(dev)) |
914 | #ifdef CONFIG_PCNET32_NAPI | ||
915 | pcnet32_netif_stop(dev); | 904 | pcnet32_netif_stop(dev); |
916 | #else | ||
917 | pcnet32_close(dev); | ||
918 | #endif | ||
919 | 905 | ||
920 | spin_lock_irqsave(&lp->lock, flags); | 906 | spin_lock_irqsave(&lp->lock, flags); |
921 | lp->a.write_csr(ioaddr, CSR0, CSR0_STOP); /* stop the chip */ | 907 | lp->a.write_csr(ioaddr, CSR0, CSR0_STOP); /* stop the chip */ |
@@ -1046,7 +1032,6 @@ static int pcnet32_loopback_test(struct net_device *dev, uint64_t * data1) | |||
1046 | x = a->read_bcr(ioaddr, 32); /* reset internal loopback */ | 1032 | x = a->read_bcr(ioaddr, 32); /* reset internal loopback */ |
1047 | a->write_bcr(ioaddr, 32, (x & ~0x0002)); | 1033 | a->write_bcr(ioaddr, 32, (x & ~0x0002)); |
1048 | 1034 | ||
1049 | #ifdef CONFIG_PCNET32_NAPI | ||
1050 | if (netif_running(dev)) { | 1035 | if (netif_running(dev)) { |
1051 | pcnet32_netif_start(dev); | 1036 | pcnet32_netif_start(dev); |
1052 | pcnet32_restart(dev, CSR0_NORMAL); | 1037 | pcnet32_restart(dev, CSR0_NORMAL); |
@@ -1055,16 +1040,6 @@ static int pcnet32_loopback_test(struct net_device *dev, uint64_t * data1) | |||
1055 | lp->a.write_bcr(ioaddr, 20, 4); /* return to 16bit mode */ | 1040 | lp->a.write_bcr(ioaddr, 20, 4); /* return to 16bit mode */ |
1056 | } | 1041 | } |
1057 | spin_unlock_irqrestore(&lp->lock, flags); | 1042 | spin_unlock_irqrestore(&lp->lock, flags); |
1058 | #else | ||
1059 | if (netif_running(dev)) { | ||
1060 | spin_unlock_irqrestore(&lp->lock, flags); | ||
1061 | pcnet32_open(dev); | ||
1062 | } else { | ||
1063 | pcnet32_purge_rx_ring(dev); | ||
1064 | lp->a.write_bcr(ioaddr, 20, 4); /* return to 16bit mode */ | ||
1065 | spin_unlock_irqrestore(&lp->lock, flags); | ||
1066 | } | ||
1067 | #endif | ||
1068 | 1043 | ||
1069 | return (rc); | 1044 | return (rc); |
1070 | } /* end pcnet32_loopback_test */ | 1045 | } /* end pcnet32_loopback_test */ |
@@ -1270,11 +1245,7 @@ static void pcnet32_rx_entry(struct net_device *dev, | |||
1270 | } | 1245 | } |
1271 | dev->stats.rx_bytes += skb->len; | 1246 | dev->stats.rx_bytes += skb->len; |
1272 | skb->protocol = eth_type_trans(skb, dev); | 1247 | skb->protocol = eth_type_trans(skb, dev); |
1273 | #ifdef CONFIG_PCNET32_NAPI | ||
1274 | netif_receive_skb(skb); | 1248 | netif_receive_skb(skb); |
1275 | #else | ||
1276 | netif_rx(skb); | ||
1277 | #endif | ||
1278 | dev->last_rx = jiffies; | 1249 | dev->last_rx = jiffies; |
1279 | dev->stats.rx_packets++; | 1250 | dev->stats.rx_packets++; |
1280 | return; | 1251 | return; |
@@ -1403,7 +1374,6 @@ static int pcnet32_tx(struct net_device *dev) | |||
1403 | return must_restart; | 1374 | return must_restart; |
1404 | } | 1375 | } |
1405 | 1376 | ||
1406 | #ifdef CONFIG_PCNET32_NAPI | ||
1407 | static int pcnet32_poll(struct napi_struct *napi, int budget) | 1377 | static int pcnet32_poll(struct napi_struct *napi, int budget) |
1408 | { | 1378 | { |
1409 | struct pcnet32_private *lp = container_of(napi, struct pcnet32_private, napi); | 1379 | struct pcnet32_private *lp = container_of(napi, struct pcnet32_private, napi); |
@@ -1442,7 +1412,6 @@ static int pcnet32_poll(struct napi_struct *napi, int budget) | |||
1442 | } | 1412 | } |
1443 | return work_done; | 1413 | return work_done; |
1444 | } | 1414 | } |
1445 | #endif | ||
1446 | 1415 | ||
1447 | #define PCNET32_REGS_PER_PHY 32 | 1416 | #define PCNET32_REGS_PER_PHY 32 |
1448 | #define PCNET32_MAX_PHYS 32 | 1417 | #define PCNET32_MAX_PHYS 32 |
@@ -1864,9 +1833,7 @@ pcnet32_probe1(unsigned long ioaddr, int shared, struct pci_dev *pdev) | |||
1864 | /* napi.weight is used in both the napi and non-napi cases */ | 1833 | /* napi.weight is used in both the napi and non-napi cases */ |
1865 | lp->napi.weight = lp->rx_ring_size / 2; | 1834 | lp->napi.weight = lp->rx_ring_size / 2; |
1866 | 1835 | ||
1867 | #ifdef CONFIG_PCNET32_NAPI | ||
1868 | netif_napi_add(dev, &lp->napi, pcnet32_poll, lp->rx_ring_size / 2); | 1836 | netif_napi_add(dev, &lp->napi, pcnet32_poll, lp->rx_ring_size / 2); |
1869 | #endif | ||
1870 | 1837 | ||
1871 | if (fdx && !(lp->options & PCNET32_PORT_ASEL) && | 1838 | if (fdx && !(lp->options & PCNET32_PORT_ASEL) && |
1872 | ((cards_found >= MAX_UNITS) || full_duplex[cards_found])) | 1839 | ((cards_found >= MAX_UNITS) || full_duplex[cards_found])) |
@@ -2016,7 +1983,7 @@ pcnet32_probe1(unsigned long ioaddr, int shared, struct pci_dev *pdev) | |||
2016 | } | 1983 | } |
2017 | 1984 | ||
2018 | /* if any allocation fails, caller must also call pcnet32_free_ring */ | 1985 | /* if any allocation fails, caller must also call pcnet32_free_ring */ |
2019 | static int pcnet32_alloc_ring(struct net_device *dev, char *name) | 1986 | static int pcnet32_alloc_ring(struct net_device *dev, const char *name) |
2020 | { | 1987 | { |
2021 | struct pcnet32_private *lp = netdev_priv(dev); | 1988 | struct pcnet32_private *lp = netdev_priv(dev); |
2022 | 1989 | ||
@@ -2297,9 +2264,7 @@ static int pcnet32_open(struct net_device *dev) | |||
2297 | goto err_free_ring; | 2264 | goto err_free_ring; |
2298 | } | 2265 | } |
2299 | 2266 | ||
2300 | #ifdef CONFIG_PCNET32_NAPI | ||
2301 | napi_enable(&lp->napi); | 2267 | napi_enable(&lp->napi); |
2302 | #endif | ||
2303 | 2268 | ||
2304 | /* Re-initialize the PCNET32, and start it when done. */ | 2269 | /* Re-initialize the PCNET32, and start it when done. */ |
2305 | lp->a.write_csr(ioaddr, 1, (lp->init_dma_addr & 0xffff)); | 2270 | lp->a.write_csr(ioaddr, 1, (lp->init_dma_addr & 0xffff)); |
@@ -2623,7 +2588,6 @@ pcnet32_interrupt(int irq, void *dev_id) | |||
2623 | dev->name, csr0); | 2588 | dev->name, csr0); |
2624 | /* unlike for the lance, there is no restart needed */ | 2589 | /* unlike for the lance, there is no restart needed */ |
2625 | } | 2590 | } |
2626 | #ifdef CONFIG_PCNET32_NAPI | ||
2627 | if (netif_rx_schedule_prep(dev, &lp->napi)) { | 2591 | if (netif_rx_schedule_prep(dev, &lp->napi)) { |
2628 | u16 val; | 2592 | u16 val; |
2629 | /* set interrupt masks */ | 2593 | /* set interrupt masks */ |
@@ -2634,24 +2598,9 @@ pcnet32_interrupt(int irq, void *dev_id) | |||
2634 | __netif_rx_schedule(dev, &lp->napi); | 2598 | __netif_rx_schedule(dev, &lp->napi); |
2635 | break; | 2599 | break; |
2636 | } | 2600 | } |
2637 | #else | ||
2638 | pcnet32_rx(dev, lp->napi.weight); | ||
2639 | if (pcnet32_tx(dev)) { | ||
2640 | /* reset the chip to clear the error condition, then restart */ | ||
2641 | lp->a.reset(ioaddr); | ||
2642 | lp->a.write_csr(ioaddr, CSR4, 0x0915); /* auto tx pad */ | ||
2643 | pcnet32_restart(dev, CSR0_START); | ||
2644 | netif_wake_queue(dev); | ||
2645 | } | ||
2646 | #endif | ||
2647 | csr0 = lp->a.read_csr(ioaddr, CSR0); | 2601 | csr0 = lp->a.read_csr(ioaddr, CSR0); |
2648 | } | 2602 | } |
2649 | 2603 | ||
2650 | #ifndef CONFIG_PCNET32_NAPI | ||
2651 | /* Set interrupt enable. */ | ||
2652 | lp->a.write_csr(ioaddr, CSR0, CSR0_INTEN); | ||
2653 | #endif | ||
2654 | |||
2655 | if (netif_msg_intr(lp)) | 2604 | if (netif_msg_intr(lp)) |
2656 | printk(KERN_DEBUG "%s: exiting interrupt, csr0=%#4.4x.\n", | 2605 | printk(KERN_DEBUG "%s: exiting interrupt, csr0=%#4.4x.\n", |
2657 | dev->name, lp->a.read_csr(ioaddr, CSR0)); | 2606 | dev->name, lp->a.read_csr(ioaddr, CSR0)); |
@@ -2670,9 +2619,7 @@ static int pcnet32_close(struct net_device *dev) | |||
2670 | del_timer_sync(&lp->watchdog_timer); | 2619 | del_timer_sync(&lp->watchdog_timer); |
2671 | 2620 | ||
2672 | netif_stop_queue(dev); | 2621 | netif_stop_queue(dev); |
2673 | #ifdef CONFIG_PCNET32_NAPI | ||
2674 | napi_disable(&lp->napi); | 2622 | napi_disable(&lp->napi); |
2675 | #endif | ||
2676 | 2623 | ||
2677 | spin_lock_irqsave(&lp->lock, flags); | 2624 | spin_lock_irqsave(&lp->lock, flags); |
2678 | 2625 | ||
diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig index 6bf9e76b0a00..6eb2d31d1e34 100644 --- a/drivers/net/phy/Kconfig +++ b/drivers/net/phy/Kconfig | |||
@@ -5,7 +5,7 @@ | |||
5 | menuconfig PHYLIB | 5 | menuconfig PHYLIB |
6 | tristate "PHY Device support and infrastructure" | 6 | tristate "PHY Device support and infrastructure" |
7 | depends on !S390 | 7 | depends on !S390 |
8 | depends on NET_ETHERNET && (BROKEN || !S390) | 8 | depends on NET_ETHERNET |
9 | help | 9 | help |
10 | Ethernet controllers are usually attached to PHY | 10 | Ethernet controllers are usually attached to PHY |
11 | devices. This option provides infrastructure for | 11 | devices. This option provides infrastructure for |
diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c index 3c18bb594957..45cc2914d347 100644 --- a/drivers/net/phy/phy.c +++ b/drivers/net/phy/phy.c | |||
@@ -547,7 +547,7 @@ static void phy_force_reduction(struct phy_device *phydev) | |||
547 | * Must not be called from interrupt context, or while the | 547 | * Must not be called from interrupt context, or while the |
548 | * phydev->lock is held. | 548 | * phydev->lock is held. |
549 | */ | 549 | */ |
550 | void phy_error(struct phy_device *phydev) | 550 | static void phy_error(struct phy_device *phydev) |
551 | { | 551 | { |
552 | mutex_lock(&phydev->lock); | 552 | mutex_lock(&phydev->lock); |
553 | phydev->state = PHY_HALTED; | 553 | phydev->state = PHY_HALTED; |
diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c index ac3c01d28fdf..16a0e7de5888 100644 --- a/drivers/net/phy/phy_device.c +++ b/drivers/net/phy/phy_device.c | |||
@@ -207,6 +207,7 @@ int get_phy_id(struct mii_bus *bus, int addr, u32 *phy_id) | |||
207 | 207 | ||
208 | return 0; | 208 | return 0; |
209 | } | 209 | } |
210 | EXPORT_SYMBOL(get_phy_id); | ||
210 | 211 | ||
211 | /** | 212 | /** |
212 | * get_phy_device - reads the specified PHY device and returns its @phy_device struct | 213 | * get_phy_device - reads the specified PHY device and returns its @phy_device struct |
diff --git a/drivers/net/ppp_generic.c b/drivers/net/ppp_generic.c index d3207c0da895..1f4ca2b54a73 100644 --- a/drivers/net/ppp_generic.c +++ b/drivers/net/ppp_generic.c | |||
@@ -2458,6 +2458,7 @@ ppp_create_interface(int unit, int *retp) | |||
2458 | 2458 | ||
2459 | out3: | 2459 | out3: |
2460 | atomic_dec(&ppp_unit_count); | 2460 | atomic_dec(&ppp_unit_count); |
2461 | unregister_netdev(dev); | ||
2461 | out2: | 2462 | out2: |
2462 | mutex_unlock(&all_ppp_mutex); | 2463 | mutex_unlock(&all_ppp_mutex); |
2463 | free_netdev(dev); | 2464 | free_netdev(dev); |
diff --git a/drivers/net/pppoe.c b/drivers/net/pppoe.c index 58a26a47af29..fc6f4b8c64b3 100644 --- a/drivers/net/pppoe.c +++ b/drivers/net/pppoe.c | |||
@@ -341,12 +341,6 @@ static int pppoe_rcv_core(struct sock *sk, struct sk_buff *skb) | |||
341 | struct pppox_sock *relay_po; | 341 | struct pppox_sock *relay_po; |
342 | 342 | ||
343 | if (sk->sk_state & PPPOX_BOUND) { | 343 | if (sk->sk_state & PPPOX_BOUND) { |
344 | struct pppoe_hdr *ph = pppoe_hdr(skb); | ||
345 | int len = ntohs(ph->length); | ||
346 | skb_pull_rcsum(skb, sizeof(struct pppoe_hdr)); | ||
347 | if (pskb_trim_rcsum(skb, len)) | ||
348 | goto abort_kfree; | ||
349 | |||
350 | ppp_input(&po->chan, skb); | 344 | ppp_input(&po->chan, skb); |
351 | } else if (sk->sk_state & PPPOX_RELAY) { | 345 | } else if (sk->sk_state & PPPOX_RELAY) { |
352 | relay_po = get_item_by_addr(&po->pppoe_relay); | 346 | relay_po = get_item_by_addr(&po->pppoe_relay); |
@@ -357,7 +351,6 @@ static int pppoe_rcv_core(struct sock *sk, struct sk_buff *skb) | |||
357 | if ((sk_pppox(relay_po)->sk_state & PPPOX_CONNECTED) == 0) | 351 | if ((sk_pppox(relay_po)->sk_state & PPPOX_CONNECTED) == 0) |
358 | goto abort_put; | 352 | goto abort_put; |
359 | 353 | ||
360 | skb_pull(skb, sizeof(struct pppoe_hdr)); | ||
361 | if (!__pppoe_xmit(sk_pppox(relay_po), skb)) | 354 | if (!__pppoe_xmit(sk_pppox(relay_po), skb)) |
362 | goto abort_put; | 355 | goto abort_put; |
363 | } else { | 356 | } else { |
@@ -388,6 +381,7 @@ static int pppoe_rcv(struct sk_buff *skb, | |||
388 | { | 381 | { |
389 | struct pppoe_hdr *ph; | 382 | struct pppoe_hdr *ph; |
390 | struct pppox_sock *po; | 383 | struct pppox_sock *po; |
384 | int len; | ||
391 | 385 | ||
392 | if (!(skb = skb_share_check(skb, GFP_ATOMIC))) | 386 | if (!(skb = skb_share_check(skb, GFP_ATOMIC))) |
393 | goto out; | 387 | goto out; |
@@ -399,10 +393,21 @@ static int pppoe_rcv(struct sk_buff *skb, | |||
399 | goto drop; | 393 | goto drop; |
400 | 394 | ||
401 | ph = pppoe_hdr(skb); | 395 | ph = pppoe_hdr(skb); |
396 | len = ntohs(ph->length); | ||
397 | |||
398 | skb_pull_rcsum(skb, sizeof(*ph)); | ||
399 | if (skb->len < len) | ||
400 | goto drop; | ||
402 | 401 | ||
403 | po = get_item(ph->sid, eth_hdr(skb)->h_source, dev->ifindex); | 402 | po = get_item(ph->sid, eth_hdr(skb)->h_source, dev->ifindex); |
404 | if (po != NULL) | 403 | if (!po) |
405 | return sk_receive_skb(sk_pppox(po), skb, 0); | 404 | goto drop; |
405 | |||
406 | if (pskb_trim_rcsum(skb, len)) | ||
407 | goto drop; | ||
408 | |||
409 | return sk_receive_skb(sk_pppox(po), skb, 0); | ||
410 | |||
406 | drop: | 411 | drop: |
407 | kfree_skb(skb); | 412 | kfree_skb(skb); |
408 | out: | 413 | out: |
@@ -427,12 +432,12 @@ static int pppoe_disc_rcv(struct sk_buff *skb, | |||
427 | if (dev_net(dev) != &init_net) | 432 | if (dev_net(dev) != &init_net) |
428 | goto abort; | 433 | goto abort; |
429 | 434 | ||
430 | if (!pskb_may_pull(skb, sizeof(struct pppoe_hdr))) | ||
431 | goto abort; | ||
432 | |||
433 | if (!(skb = skb_share_check(skb, GFP_ATOMIC))) | 435 | if (!(skb = skb_share_check(skb, GFP_ATOMIC))) |
434 | goto out; | 436 | goto out; |
435 | 437 | ||
438 | if (!pskb_may_pull(skb, sizeof(struct pppoe_hdr))) | ||
439 | goto abort; | ||
440 | |||
436 | ph = pppoe_hdr(skb); | 441 | ph = pppoe_hdr(skb); |
437 | if (ph->code != PADT_CODE) | 442 | if (ph->code != PADT_CODE) |
438 | goto abort; | 443 | goto abort; |
@@ -937,12 +942,10 @@ static int pppoe_recvmsg(struct kiocb *iocb, struct socket *sock, | |||
937 | m->msg_namelen = 0; | 942 | m->msg_namelen = 0; |
938 | 943 | ||
939 | if (skb) { | 944 | if (skb) { |
940 | struct pppoe_hdr *ph = pppoe_hdr(skb); | 945 | total_len = min_t(size_t, total_len, skb->len); |
941 | const int len = ntohs(ph->length); | 946 | error = skb_copy_datagram_iovec(skb, 0, m->msg_iov, total_len); |
942 | |||
943 | error = memcpy_toiovec(m->msg_iov, (unsigned char *) &ph->tag[0], len); | ||
944 | if (error == 0) | 947 | if (error == 0) |
945 | error = len; | 948 | error = total_len; |
946 | } | 949 | } |
947 | 950 | ||
948 | kfree_skb(skb); | 951 | kfree_skb(skb); |
diff --git a/drivers/net/pppol2tp.c b/drivers/net/pppol2tp.c index 244d7830c92a..f9298827a76c 100644 --- a/drivers/net/pppol2tp.c +++ b/drivers/net/pppol2tp.c | |||
@@ -240,12 +240,15 @@ static inline struct pppol2tp_session *pppol2tp_sock_to_session(struct sock *sk) | |||
240 | if (sk == NULL) | 240 | if (sk == NULL) |
241 | return NULL; | 241 | return NULL; |
242 | 242 | ||
243 | sock_hold(sk); | ||
243 | session = (struct pppol2tp_session *)(sk->sk_user_data); | 244 | session = (struct pppol2tp_session *)(sk->sk_user_data); |
244 | if (session == NULL) | 245 | if (session == NULL) { |
245 | return NULL; | 246 | sock_put(sk); |
247 | goto out; | ||
248 | } | ||
246 | 249 | ||
247 | BUG_ON(session->magic != L2TP_SESSION_MAGIC); | 250 | BUG_ON(session->magic != L2TP_SESSION_MAGIC); |
248 | 251 | out: | |
249 | return session; | 252 | return session; |
250 | } | 253 | } |
251 | 254 | ||
@@ -256,12 +259,15 @@ static inline struct pppol2tp_tunnel *pppol2tp_sock_to_tunnel(struct sock *sk) | |||
256 | if (sk == NULL) | 259 | if (sk == NULL) |
257 | return NULL; | 260 | return NULL; |
258 | 261 | ||
262 | sock_hold(sk); | ||
259 | tunnel = (struct pppol2tp_tunnel *)(sk->sk_user_data); | 263 | tunnel = (struct pppol2tp_tunnel *)(sk->sk_user_data); |
260 | if (tunnel == NULL) | 264 | if (tunnel == NULL) { |
261 | return NULL; | 265 | sock_put(sk); |
266 | goto out; | ||
267 | } | ||
262 | 268 | ||
263 | BUG_ON(tunnel->magic != L2TP_TUNNEL_MAGIC); | 269 | BUG_ON(tunnel->magic != L2TP_TUNNEL_MAGIC); |
264 | 270 | out: | |
265 | return tunnel; | 271 | return tunnel; |
266 | } | 272 | } |
267 | 273 | ||
@@ -716,12 +722,14 @@ discard: | |||
716 | session->stats.rx_errors++; | 722 | session->stats.rx_errors++; |
717 | kfree_skb(skb); | 723 | kfree_skb(skb); |
718 | sock_put(session->sock); | 724 | sock_put(session->sock); |
725 | sock_put(sock); | ||
719 | 726 | ||
720 | return 0; | 727 | return 0; |
721 | 728 | ||
722 | error: | 729 | error: |
723 | /* Put UDP header back */ | 730 | /* Put UDP header back */ |
724 | __skb_push(skb, sizeof(struct udphdr)); | 731 | __skb_push(skb, sizeof(struct udphdr)); |
732 | sock_put(sock); | ||
725 | 733 | ||
726 | no_tunnel: | 734 | no_tunnel: |
727 | return 1; | 735 | return 1; |
@@ -745,10 +753,13 @@ static int pppol2tp_udp_encap_recv(struct sock *sk, struct sk_buff *skb) | |||
745 | "%s: received %d bytes\n", tunnel->name, skb->len); | 753 | "%s: received %d bytes\n", tunnel->name, skb->len); |
746 | 754 | ||
747 | if (pppol2tp_recv_core(sk, skb)) | 755 | if (pppol2tp_recv_core(sk, skb)) |
748 | goto pass_up; | 756 | goto pass_up_put; |
749 | 757 | ||
758 | sock_put(sk); | ||
750 | return 0; | 759 | return 0; |
751 | 760 | ||
761 | pass_up_put: | ||
762 | sock_put(sk); | ||
752 | pass_up: | 763 | pass_up: |
753 | return 1; | 764 | return 1; |
754 | } | 765 | } |
@@ -772,14 +783,18 @@ static int pppol2tp_recvmsg(struct kiocb *iocb, struct socket *sock, | |||
772 | err = 0; | 783 | err = 0; |
773 | skb = skb_recv_datagram(sk, flags & ~MSG_DONTWAIT, | 784 | skb = skb_recv_datagram(sk, flags & ~MSG_DONTWAIT, |
774 | flags & MSG_DONTWAIT, &err); | 785 | flags & MSG_DONTWAIT, &err); |
775 | if (skb) { | 786 | if (!skb) |
776 | err = memcpy_toiovec(msg->msg_iov, (unsigned char *) skb->data, | 787 | goto end; |
777 | skb->len); | 788 | |
778 | if (err < 0) | 789 | if (len > skb->len) |
779 | goto do_skb_free; | 790 | len = skb->len; |
780 | err = skb->len; | 791 | else if (len < skb->len) |
781 | } | 792 | msg->msg_flags |= MSG_TRUNC; |
782 | do_skb_free: | 793 | |
794 | err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, len); | ||
795 | if (likely(err == 0)) | ||
796 | err = len; | ||
797 | |||
783 | kfree_skb(skb); | 798 | kfree_skb(skb); |
784 | end: | 799 | end: |
785 | return err; | 800 | return err; |
@@ -858,7 +873,7 @@ static int pppol2tp_sendmsg(struct kiocb *iocb, struct socket *sock, struct msgh | |||
858 | 873 | ||
859 | tunnel = pppol2tp_sock_to_tunnel(session->tunnel_sock); | 874 | tunnel = pppol2tp_sock_to_tunnel(session->tunnel_sock); |
860 | if (tunnel == NULL) | 875 | if (tunnel == NULL) |
861 | goto error; | 876 | goto error_put_sess; |
862 | 877 | ||
863 | /* What header length is configured for this session? */ | 878 | /* What header length is configured for this session? */ |
864 | hdr_len = pppol2tp_l2tp_header_len(session); | 879 | hdr_len = pppol2tp_l2tp_header_len(session); |
@@ -870,7 +885,7 @@ static int pppol2tp_sendmsg(struct kiocb *iocb, struct socket *sock, struct msgh | |||
870 | sizeof(ppph) + total_len, | 885 | sizeof(ppph) + total_len, |
871 | 0, GFP_KERNEL); | 886 | 0, GFP_KERNEL); |
872 | if (!skb) | 887 | if (!skb) |
873 | goto error; | 888 | goto error_put_sess_tun; |
874 | 889 | ||
875 | /* Reserve space for headers. */ | 890 | /* Reserve space for headers. */ |
876 | skb_reserve(skb, NET_SKB_PAD); | 891 | skb_reserve(skb, NET_SKB_PAD); |
@@ -900,7 +915,7 @@ static int pppol2tp_sendmsg(struct kiocb *iocb, struct socket *sock, struct msgh | |||
900 | error = memcpy_fromiovec(skb->data, m->msg_iov, total_len); | 915 | error = memcpy_fromiovec(skb->data, m->msg_iov, total_len); |
901 | if (error < 0) { | 916 | if (error < 0) { |
902 | kfree_skb(skb); | 917 | kfree_skb(skb); |
903 | goto error; | 918 | goto error_put_sess_tun; |
904 | } | 919 | } |
905 | skb_put(skb, total_len); | 920 | skb_put(skb, total_len); |
906 | 921 | ||
@@ -947,10 +962,33 @@ static int pppol2tp_sendmsg(struct kiocb *iocb, struct socket *sock, struct msgh | |||
947 | session->stats.tx_errors++; | 962 | session->stats.tx_errors++; |
948 | } | 963 | } |
949 | 964 | ||
965 | return error; | ||
966 | |||
967 | error_put_sess_tun: | ||
968 | sock_put(session->tunnel_sock); | ||
969 | error_put_sess: | ||
970 | sock_put(sk); | ||
950 | error: | 971 | error: |
951 | return error; | 972 | return error; |
952 | } | 973 | } |
953 | 974 | ||
975 | /* Automatically called when the skb is freed. | ||
976 | */ | ||
977 | static void pppol2tp_sock_wfree(struct sk_buff *skb) | ||
978 | { | ||
979 | sock_put(skb->sk); | ||
980 | } | ||
981 | |||
982 | /* For data skbs that we transmit, we associate with the tunnel socket | ||
983 | * but don't do accounting. | ||
984 | */ | ||
985 | static inline void pppol2tp_skb_set_owner_w(struct sk_buff *skb, struct sock *sk) | ||
986 | { | ||
987 | sock_hold(sk); | ||
988 | skb->sk = sk; | ||
989 | skb->destructor = pppol2tp_sock_wfree; | ||
990 | } | ||
991 | |||
954 | /* Transmit function called by generic PPP driver. Sends PPP frame | 992 | /* Transmit function called by generic PPP driver. Sends PPP frame |
955 | * over PPPoL2TP socket. | 993 | * over PPPoL2TP socket. |
956 | * | 994 | * |
@@ -980,6 +1018,8 @@ static int pppol2tp_xmit(struct ppp_channel *chan, struct sk_buff *skb) | |||
980 | __wsum csum = 0; | 1018 | __wsum csum = 0; |
981 | struct udphdr *uh; | 1019 | struct udphdr *uh; |
982 | unsigned int len; | 1020 | unsigned int len; |
1021 | int old_headroom; | ||
1022 | int new_headroom; | ||
983 | 1023 | ||
984 | if (sock_flag(sk, SOCK_DEAD) || !(sk->sk_state & PPPOX_CONNECTED)) | 1024 | if (sock_flag(sk, SOCK_DEAD) || !(sk->sk_state & PPPOX_CONNECTED)) |
985 | goto abort; | 1025 | goto abort; |
@@ -991,25 +1031,27 @@ static int pppol2tp_xmit(struct ppp_channel *chan, struct sk_buff *skb) | |||
991 | 1031 | ||
992 | sk_tun = session->tunnel_sock; | 1032 | sk_tun = session->tunnel_sock; |
993 | if (sk_tun == NULL) | 1033 | if (sk_tun == NULL) |
994 | goto abort; | 1034 | goto abort_put_sess; |
995 | tunnel = pppol2tp_sock_to_tunnel(sk_tun); | 1035 | tunnel = pppol2tp_sock_to_tunnel(sk_tun); |
996 | if (tunnel == NULL) | 1036 | if (tunnel == NULL) |
997 | goto abort; | 1037 | goto abort_put_sess; |
998 | 1038 | ||
999 | /* What header length is configured for this session? */ | 1039 | /* What header length is configured for this session? */ |
1000 | hdr_len = pppol2tp_l2tp_header_len(session); | 1040 | hdr_len = pppol2tp_l2tp_header_len(session); |
1001 | 1041 | ||
1002 | /* Check that there's enough headroom in the skb to insert IP, | 1042 | /* Check that there's enough headroom in the skb to insert IP, |
1003 | * UDP and L2TP and PPP headers. If not enough, expand it to | 1043 | * UDP and L2TP and PPP headers. If not enough, expand it to |
1004 | * make room. Note that a new skb (or a clone) is | 1044 | * make room. Adjust truesize. |
1005 | * allocated. If we return an error from this point on, make | ||
1006 | * sure we free the new skb but do not free the original skb | ||
1007 | * since that is done by the caller for the error case. | ||
1008 | */ | 1045 | */ |
1009 | headroom = NET_SKB_PAD + sizeof(struct iphdr) + | 1046 | headroom = NET_SKB_PAD + sizeof(struct iphdr) + |
1010 | sizeof(struct udphdr) + hdr_len + sizeof(ppph); | 1047 | sizeof(struct udphdr) + hdr_len + sizeof(ppph); |
1048 | old_headroom = skb_headroom(skb); | ||
1011 | if (skb_cow_head(skb, headroom)) | 1049 | if (skb_cow_head(skb, headroom)) |
1012 | goto abort; | 1050 | goto abort_put_sess_tun; |
1051 | |||
1052 | new_headroom = skb_headroom(skb); | ||
1053 | skb_orphan(skb); | ||
1054 | skb->truesize += new_headroom - old_headroom; | ||
1013 | 1055 | ||
1014 | /* Setup PPP header */ | 1056 | /* Setup PPP header */ |
1015 | __skb_push(skb, sizeof(ppph)); | 1057 | __skb_push(skb, sizeof(ppph)); |
@@ -1065,8 +1107,7 @@ static int pppol2tp_xmit(struct ppp_channel *chan, struct sk_buff *skb) | |||
1065 | /* Get routing info from the tunnel socket */ | 1107 | /* Get routing info from the tunnel socket */ |
1066 | dst_release(skb->dst); | 1108 | dst_release(skb->dst); |
1067 | skb->dst = dst_clone(__sk_dst_get(sk_tun)); | 1109 | skb->dst = dst_clone(__sk_dst_get(sk_tun)); |
1068 | skb_orphan(skb); | 1110 | pppol2tp_skb_set_owner_w(skb, sk_tun); |
1069 | skb->sk = sk_tun; | ||
1070 | 1111 | ||
1071 | /* Queue the packet to IP for output */ | 1112 | /* Queue the packet to IP for output */ |
1072 | len = skb->len; | 1113 | len = skb->len; |
@@ -1083,8 +1124,14 @@ static int pppol2tp_xmit(struct ppp_channel *chan, struct sk_buff *skb) | |||
1083 | session->stats.tx_errors++; | 1124 | session->stats.tx_errors++; |
1084 | } | 1125 | } |
1085 | 1126 | ||
1127 | sock_put(sk_tun); | ||
1128 | sock_put(sk); | ||
1086 | return 1; | 1129 | return 1; |
1087 | 1130 | ||
1131 | abort_put_sess_tun: | ||
1132 | sock_put(sk_tun); | ||
1133 | abort_put_sess: | ||
1134 | sock_put(sk); | ||
1088 | abort: | 1135 | abort: |
1089 | /* Free the original skb */ | 1136 | /* Free the original skb */ |
1090 | kfree_skb(skb); | 1137 | kfree_skb(skb); |
@@ -1188,7 +1235,7 @@ static void pppol2tp_tunnel_destruct(struct sock *sk) | |||
1188 | { | 1235 | { |
1189 | struct pppol2tp_tunnel *tunnel; | 1236 | struct pppol2tp_tunnel *tunnel; |
1190 | 1237 | ||
1191 | tunnel = pppol2tp_sock_to_tunnel(sk); | 1238 | tunnel = sk->sk_user_data; |
1192 | if (tunnel == NULL) | 1239 | if (tunnel == NULL) |
1193 | goto end; | 1240 | goto end; |
1194 | 1241 | ||
@@ -1227,10 +1274,12 @@ static void pppol2tp_session_destruct(struct sock *sk) | |||
1227 | if (sk->sk_user_data != NULL) { | 1274 | if (sk->sk_user_data != NULL) { |
1228 | struct pppol2tp_tunnel *tunnel; | 1275 | struct pppol2tp_tunnel *tunnel; |
1229 | 1276 | ||
1230 | session = pppol2tp_sock_to_session(sk); | 1277 | session = sk->sk_user_data; |
1231 | if (session == NULL) | 1278 | if (session == NULL) |
1232 | goto out; | 1279 | goto out; |
1233 | 1280 | ||
1281 | BUG_ON(session->magic != L2TP_SESSION_MAGIC); | ||
1282 | |||
1234 | /* Don't use pppol2tp_sock_to_tunnel() here to | 1283 | /* Don't use pppol2tp_sock_to_tunnel() here to |
1235 | * get the tunnel context because the tunnel | 1284 | * get the tunnel context because the tunnel |
1236 | * socket might have already been closed (its | 1285 | * socket might have already been closed (its |
@@ -1276,6 +1325,7 @@ out: | |||
1276 | static int pppol2tp_release(struct socket *sock) | 1325 | static int pppol2tp_release(struct socket *sock) |
1277 | { | 1326 | { |
1278 | struct sock *sk = sock->sk; | 1327 | struct sock *sk = sock->sk; |
1328 | struct pppol2tp_session *session; | ||
1279 | int error; | 1329 | int error; |
1280 | 1330 | ||
1281 | if (!sk) | 1331 | if (!sk) |
@@ -1293,9 +1343,18 @@ static int pppol2tp_release(struct socket *sock) | |||
1293 | sock_orphan(sk); | 1343 | sock_orphan(sk); |
1294 | sock->sk = NULL; | 1344 | sock->sk = NULL; |
1295 | 1345 | ||
1346 | session = pppol2tp_sock_to_session(sk); | ||
1347 | |||
1296 | /* Purge any queued data */ | 1348 | /* Purge any queued data */ |
1297 | skb_queue_purge(&sk->sk_receive_queue); | 1349 | skb_queue_purge(&sk->sk_receive_queue); |
1298 | skb_queue_purge(&sk->sk_write_queue); | 1350 | skb_queue_purge(&sk->sk_write_queue); |
1351 | if (session != NULL) { | ||
1352 | struct sk_buff *skb; | ||
1353 | while ((skb = skb_dequeue(&session->reorder_q))) { | ||
1354 | kfree_skb(skb); | ||
1355 | sock_put(sk); | ||
1356 | } | ||
1357 | } | ||
1299 | 1358 | ||
1300 | release_sock(sk); | 1359 | release_sock(sk); |
1301 | 1360 | ||
@@ -1598,7 +1657,7 @@ static int pppol2tp_connect(struct socket *sock, struct sockaddr *uservaddr, | |||
1598 | 1657 | ||
1599 | error = ppp_register_channel(&po->chan); | 1658 | error = ppp_register_channel(&po->chan); |
1600 | if (error) | 1659 | if (error) |
1601 | goto end; | 1660 | goto end_put_tun; |
1602 | 1661 | ||
1603 | /* This is how we get the session context from the socket. */ | 1662 | /* This is how we get the session context from the socket. */ |
1604 | sk->sk_user_data = session; | 1663 | sk->sk_user_data = session; |
@@ -1618,12 +1677,21 @@ out_no_ppp: | |||
1618 | PRINTK(session->debug, PPPOL2TP_MSG_CONTROL, KERN_INFO, | 1677 | PRINTK(session->debug, PPPOL2TP_MSG_CONTROL, KERN_INFO, |
1619 | "%s: created\n", session->name); | 1678 | "%s: created\n", session->name); |
1620 | 1679 | ||
1680 | end_put_tun: | ||
1681 | sock_put(tunnel_sock); | ||
1621 | end: | 1682 | end: |
1622 | release_sock(sk); | 1683 | release_sock(sk); |
1623 | 1684 | ||
1624 | if (error != 0) | 1685 | if (error != 0) { |
1625 | PRINTK(session ? session->debug : -1, PPPOL2TP_MSG_CONTROL, KERN_WARNING, | 1686 | if (session) |
1626 | "%s: connect failed: %d\n", session->name, error); | 1687 | PRINTK(session->debug, |
1688 | PPPOL2TP_MSG_CONTROL, KERN_WARNING, | ||
1689 | "%s: connect failed: %d\n", | ||
1690 | session->name, error); | ||
1691 | else | ||
1692 | PRINTK(-1, PPPOL2TP_MSG_CONTROL, KERN_WARNING, | ||
1693 | "connect failed: %d\n", error); | ||
1694 | } | ||
1627 | 1695 | ||
1628 | return error; | 1696 | return error; |
1629 | } | 1697 | } |
@@ -1658,6 +1726,7 @@ static int pppol2tp_getname(struct socket *sock, struct sockaddr *uaddr, | |||
1658 | *usockaddr_len = len; | 1726 | *usockaddr_len = len; |
1659 | 1727 | ||
1660 | error = 0; | 1728 | error = 0; |
1729 | sock_put(sock->sk); | ||
1661 | 1730 | ||
1662 | end: | 1731 | end: |
1663 | return error; | 1732 | return error; |
@@ -1896,14 +1965,17 @@ static int pppol2tp_ioctl(struct socket *sock, unsigned int cmd, | |||
1896 | err = -EBADF; | 1965 | err = -EBADF; |
1897 | tunnel = pppol2tp_sock_to_tunnel(session->tunnel_sock); | 1966 | tunnel = pppol2tp_sock_to_tunnel(session->tunnel_sock); |
1898 | if (tunnel == NULL) | 1967 | if (tunnel == NULL) |
1899 | goto end; | 1968 | goto end_put_sess; |
1900 | 1969 | ||
1901 | err = pppol2tp_tunnel_ioctl(tunnel, cmd, arg); | 1970 | err = pppol2tp_tunnel_ioctl(tunnel, cmd, arg); |
1902 | goto end; | 1971 | sock_put(session->tunnel_sock); |
1972 | goto end_put_sess; | ||
1903 | } | 1973 | } |
1904 | 1974 | ||
1905 | err = pppol2tp_session_ioctl(session, cmd, arg); | 1975 | err = pppol2tp_session_ioctl(session, cmd, arg); |
1906 | 1976 | ||
1977 | end_put_sess: | ||
1978 | sock_put(sk); | ||
1907 | end: | 1979 | end: |
1908 | return err; | 1980 | return err; |
1909 | } | 1981 | } |
@@ -2049,14 +2121,17 @@ static int pppol2tp_setsockopt(struct socket *sock, int level, int optname, | |||
2049 | err = -EBADF; | 2121 | err = -EBADF; |
2050 | tunnel = pppol2tp_sock_to_tunnel(session->tunnel_sock); | 2122 | tunnel = pppol2tp_sock_to_tunnel(session->tunnel_sock); |
2051 | if (tunnel == NULL) | 2123 | if (tunnel == NULL) |
2052 | goto end; | 2124 | goto end_put_sess; |
2053 | 2125 | ||
2054 | err = pppol2tp_tunnel_setsockopt(sk, tunnel, optname, val); | 2126 | err = pppol2tp_tunnel_setsockopt(sk, tunnel, optname, val); |
2127 | sock_put(session->tunnel_sock); | ||
2055 | } else | 2128 | } else |
2056 | err = pppol2tp_session_setsockopt(sk, session, optname, val); | 2129 | err = pppol2tp_session_setsockopt(sk, session, optname, val); |
2057 | 2130 | ||
2058 | err = 0; | 2131 | err = 0; |
2059 | 2132 | ||
2133 | end_put_sess: | ||
2134 | sock_put(sk); | ||
2060 | end: | 2135 | end: |
2061 | return err; | 2136 | return err; |
2062 | } | 2137 | } |
@@ -2171,20 +2246,24 @@ static int pppol2tp_getsockopt(struct socket *sock, int level, | |||
2171 | err = -EBADF; | 2246 | err = -EBADF; |
2172 | tunnel = pppol2tp_sock_to_tunnel(session->tunnel_sock); | 2247 | tunnel = pppol2tp_sock_to_tunnel(session->tunnel_sock); |
2173 | if (tunnel == NULL) | 2248 | if (tunnel == NULL) |
2174 | goto end; | 2249 | goto end_put_sess; |
2175 | 2250 | ||
2176 | err = pppol2tp_tunnel_getsockopt(sk, tunnel, optname, &val); | 2251 | err = pppol2tp_tunnel_getsockopt(sk, tunnel, optname, &val); |
2252 | sock_put(session->tunnel_sock); | ||
2177 | } else | 2253 | } else |
2178 | err = pppol2tp_session_getsockopt(sk, session, optname, &val); | 2254 | err = pppol2tp_session_getsockopt(sk, session, optname, &val); |
2179 | 2255 | ||
2180 | err = -EFAULT; | 2256 | err = -EFAULT; |
2181 | if (put_user(len, (int __user *) optlen)) | 2257 | if (put_user(len, (int __user *) optlen)) |
2182 | goto end; | 2258 | goto end_put_sess; |
2183 | 2259 | ||
2184 | if (copy_to_user((void __user *) optval, &val, len)) | 2260 | if (copy_to_user((void __user *) optval, &val, len)) |
2185 | goto end; | 2261 | goto end_put_sess; |
2186 | 2262 | ||
2187 | err = 0; | 2263 | err = 0; |
2264 | |||
2265 | end_put_sess: | ||
2266 | sock_put(sk); | ||
2188 | end: | 2267 | end: |
2189 | return err; | 2268 | return err; |
2190 | } | 2269 | } |
diff --git a/drivers/net/ps3_gelic_wireless.c b/drivers/net/ps3_gelic_wireless.c index 0d32123085e9..1dae1f2ed813 100644 --- a/drivers/net/ps3_gelic_wireless.c +++ b/drivers/net/ps3_gelic_wireless.c | |||
@@ -2474,6 +2474,8 @@ static void gelic_wl_free(struct gelic_wl_info *wl) | |||
2474 | 2474 | ||
2475 | pr_debug("%s: <-\n", __func__); | 2475 | pr_debug("%s: <-\n", __func__); |
2476 | 2476 | ||
2477 | free_page((unsigned long)wl->buf); | ||
2478 | |||
2477 | pr_debug("%s: destroy queues\n", __func__); | 2479 | pr_debug("%s: destroy queues\n", __func__); |
2478 | destroy_workqueue(wl->eurus_cmd_queue); | 2480 | destroy_workqueue(wl->eurus_cmd_queue); |
2479 | destroy_workqueue(wl->event_queue); | 2481 | destroy_workqueue(wl->event_queue); |
diff --git a/drivers/net/qla3xxx.c b/drivers/net/qla3xxx.c index b7f7b2227d56..bccee68bd48a 100644 --- a/drivers/net/qla3xxx.c +++ b/drivers/net/qla3xxx.c | |||
@@ -3701,7 +3701,9 @@ static int ql_cycle_adapter(struct ql3_adapter *qdev, int reset) | |||
3701 | printk(KERN_ERR PFX | 3701 | printk(KERN_ERR PFX |
3702 | "%s: Driver up/down cycle failed, " | 3702 | "%s: Driver up/down cycle failed, " |
3703 | "closing device\n",qdev->ndev->name); | 3703 | "closing device\n",qdev->ndev->name); |
3704 | rtnl_lock(); | ||
3704 | dev_close(qdev->ndev); | 3705 | dev_close(qdev->ndev); |
3706 | rtnl_unlock(); | ||
3705 | return -1; | 3707 | return -1; |
3706 | } | 3708 | } |
3707 | return 0; | 3709 | return 0; |
diff --git a/drivers/net/r6040.c b/drivers/net/r6040.c index 169edc154928..504a48ff73c8 100644 --- a/drivers/net/r6040.c +++ b/drivers/net/r6040.c | |||
@@ -273,7 +273,7 @@ static void r6040_init_ring_desc(struct r6040_descriptor *desc_ring, | |||
273 | dma_addr_t mapping = desc_dma; | 273 | dma_addr_t mapping = desc_dma; |
274 | 274 | ||
275 | while (size-- > 0) { | 275 | while (size-- > 0) { |
276 | mapping += sizeof(sizeof(*desc)); | 276 | mapping += sizeof(*desc); |
277 | desc->ndesc = cpu_to_le32(mapping); | 277 | desc->ndesc = cpu_to_le32(mapping); |
278 | desc->vndescp = desc + 1; | 278 | desc->vndescp = desc + 1; |
279 | desc++; | 279 | desc++; |
@@ -733,7 +733,7 @@ static void r6040_timer(unsigned long data) | |||
733 | } | 733 | } |
734 | 734 | ||
735 | /* Timer active again */ | 735 | /* Timer active again */ |
736 | mod_timer(&lp->timer, jiffies + round_jiffies(HZ)); | 736 | mod_timer(&lp->timer, round_jiffies(jiffies + HZ)); |
737 | } | 737 | } |
738 | 738 | ||
739 | /* Read/set MAC address routines */ | 739 | /* Read/set MAC address routines */ |
diff --git a/drivers/net/s2io-regs.h b/drivers/net/s2io-regs.h index 2109508c047a..f8274f8941ea 100644 --- a/drivers/net/s2io-regs.h +++ b/drivers/net/s2io-regs.h | |||
@@ -250,7 +250,7 @@ struct XENA_dev_config { | |||
250 | u64 tx_mat0_n[0x8]; | 250 | u64 tx_mat0_n[0x8]; |
251 | #define TX_MAT_SET(fifo, msi) vBIT(msi, (8 * fifo), 8) | 251 | #define TX_MAT_SET(fifo, msi) vBIT(msi, (8 * fifo), 8) |
252 | 252 | ||
253 | u8 unused_1[0x8]; | 253 | u64 xmsi_mask_reg; |
254 | u64 stat_byte_cnt; | 254 | u64 stat_byte_cnt; |
255 | #define STAT_BC(n) vBIT(n,4,12) | 255 | #define STAT_BC(n) vBIT(n,4,12) |
256 | 256 | ||
diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c index 523478ebfd69..ae7b697456b4 100644 --- a/drivers/net/s2io.c +++ b/drivers/net/s2io.c | |||
@@ -86,7 +86,7 @@ | |||
86 | #include "s2io.h" | 86 | #include "s2io.h" |
87 | #include "s2io-regs.h" | 87 | #include "s2io-regs.h" |
88 | 88 | ||
89 | #define DRV_VERSION "2.0.26.23" | 89 | #define DRV_VERSION "2.0.26.24" |
90 | 90 | ||
91 | /* S2io Driver name & version. */ | 91 | /* S2io Driver name & version. */ |
92 | static char s2io_driver_name[] = "Neterion"; | 92 | static char s2io_driver_name[] = "Neterion"; |
@@ -1113,9 +1113,10 @@ static int s2io_on_nec_bridge(struct pci_dev *s2io_pdev) | |||
1113 | struct pci_dev *tdev = NULL; | 1113 | struct pci_dev *tdev = NULL; |
1114 | while ((tdev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, tdev)) != NULL) { | 1114 | while ((tdev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, tdev)) != NULL) { |
1115 | if (tdev->vendor == NEC_VENID && tdev->device == NEC_DEVID) { | 1115 | if (tdev->vendor == NEC_VENID && tdev->device == NEC_DEVID) { |
1116 | if (tdev->bus == s2io_pdev->bus->parent) | 1116 | if (tdev->bus == s2io_pdev->bus->parent) { |
1117 | pci_dev_put(tdev); | 1117 | pci_dev_put(tdev); |
1118 | return 1; | 1118 | return 1; |
1119 | } | ||
1119 | } | 1120 | } |
1120 | } | 1121 | } |
1121 | return 0; | 1122 | return 0; |
@@ -1219,15 +1220,33 @@ static int init_tti(struct s2io_nic *nic, int link) | |||
1219 | TTI_DATA1_MEM_TX_URNG_B(0x10) | | 1220 | TTI_DATA1_MEM_TX_URNG_B(0x10) | |
1220 | TTI_DATA1_MEM_TX_URNG_C(0x30) | | 1221 | TTI_DATA1_MEM_TX_URNG_C(0x30) | |
1221 | TTI_DATA1_MEM_TX_TIMER_AC_EN; | 1222 | TTI_DATA1_MEM_TX_TIMER_AC_EN; |
1222 | 1223 | if (i == 0) | |
1223 | if (use_continuous_tx_intrs && (link == LINK_UP)) | 1224 | if (use_continuous_tx_intrs && (link == LINK_UP)) |
1224 | val64 |= TTI_DATA1_MEM_TX_TIMER_CI_EN; | 1225 | val64 |= TTI_DATA1_MEM_TX_TIMER_CI_EN; |
1225 | writeq(val64, &bar0->tti_data1_mem); | 1226 | writeq(val64, &bar0->tti_data1_mem); |
1226 | 1227 | ||
1227 | val64 = TTI_DATA2_MEM_TX_UFC_A(0x10) | | 1228 | if (nic->config.intr_type == MSI_X) { |
1228 | TTI_DATA2_MEM_TX_UFC_B(0x20) | | 1229 | val64 = TTI_DATA2_MEM_TX_UFC_A(0x10) | |
1229 | TTI_DATA2_MEM_TX_UFC_C(0x40) | | 1230 | TTI_DATA2_MEM_TX_UFC_B(0x100) | |
1230 | TTI_DATA2_MEM_TX_UFC_D(0x80); | 1231 | TTI_DATA2_MEM_TX_UFC_C(0x200) | |
1232 | TTI_DATA2_MEM_TX_UFC_D(0x300); | ||
1233 | } else { | ||
1234 | if ((nic->config.tx_steering_type == | ||
1235 | TX_DEFAULT_STEERING) && | ||
1236 | (config->tx_fifo_num > 1) && | ||
1237 | (i >= nic->udp_fifo_idx) && | ||
1238 | (i < (nic->udp_fifo_idx + | ||
1239 | nic->total_udp_fifos))) | ||
1240 | val64 = TTI_DATA2_MEM_TX_UFC_A(0x50) | | ||
1241 | TTI_DATA2_MEM_TX_UFC_B(0x80) | | ||
1242 | TTI_DATA2_MEM_TX_UFC_C(0x100) | | ||
1243 | TTI_DATA2_MEM_TX_UFC_D(0x120); | ||
1244 | else | ||
1245 | val64 = TTI_DATA2_MEM_TX_UFC_A(0x10) | | ||
1246 | TTI_DATA2_MEM_TX_UFC_B(0x20) | | ||
1247 | TTI_DATA2_MEM_TX_UFC_C(0x40) | | ||
1248 | TTI_DATA2_MEM_TX_UFC_D(0x80); | ||
1249 | } | ||
1231 | 1250 | ||
1232 | writeq(val64, &bar0->tti_data2_mem); | 1251 | writeq(val64, &bar0->tti_data2_mem); |
1233 | 1252 | ||
@@ -2606,9 +2625,7 @@ static int fill_rx_buffers(struct ring_info *ring) | |||
2606 | rxdp1->Buffer0_ptr = pci_map_single | 2625 | rxdp1->Buffer0_ptr = pci_map_single |
2607 | (ring->pdev, skb->data, size - NET_IP_ALIGN, | 2626 | (ring->pdev, skb->data, size - NET_IP_ALIGN, |
2608 | PCI_DMA_FROMDEVICE); | 2627 | PCI_DMA_FROMDEVICE); |
2609 | if( (rxdp1->Buffer0_ptr == 0) || | 2628 | if(pci_dma_mapping_error(rxdp1->Buffer0_ptr)) |
2610 | (rxdp1->Buffer0_ptr == | ||
2611 | DMA_ERROR_CODE)) | ||
2612 | goto pci_map_failed; | 2629 | goto pci_map_failed; |
2613 | 2630 | ||
2614 | rxdp->Control_2 = | 2631 | rxdp->Control_2 = |
@@ -2638,6 +2655,7 @@ static int fill_rx_buffers(struct ring_info *ring) | |||
2638 | skb->data = (void *) (unsigned long)tmp; | 2655 | skb->data = (void *) (unsigned long)tmp; |
2639 | skb_reset_tail_pointer(skb); | 2656 | skb_reset_tail_pointer(skb); |
2640 | 2657 | ||
2658 | /* AK: check is wrong. 0 can be valid dma address */ | ||
2641 | if (!(rxdp3->Buffer0_ptr)) | 2659 | if (!(rxdp3->Buffer0_ptr)) |
2642 | rxdp3->Buffer0_ptr = | 2660 | rxdp3->Buffer0_ptr = |
2643 | pci_map_single(ring->pdev, ba->ba_0, | 2661 | pci_map_single(ring->pdev, ba->ba_0, |
@@ -2646,8 +2664,7 @@ static int fill_rx_buffers(struct ring_info *ring) | |||
2646 | pci_dma_sync_single_for_device(ring->pdev, | 2664 | pci_dma_sync_single_for_device(ring->pdev, |
2647 | (dma_addr_t) rxdp3->Buffer0_ptr, | 2665 | (dma_addr_t) rxdp3->Buffer0_ptr, |
2648 | BUF0_LEN, PCI_DMA_FROMDEVICE); | 2666 | BUF0_LEN, PCI_DMA_FROMDEVICE); |
2649 | if( (rxdp3->Buffer0_ptr == 0) || | 2667 | if (pci_dma_mapping_error(rxdp3->Buffer0_ptr)) |
2650 | (rxdp3->Buffer0_ptr == DMA_ERROR_CODE)) | ||
2651 | goto pci_map_failed; | 2668 | goto pci_map_failed; |
2652 | 2669 | ||
2653 | rxdp->Control_2 = SET_BUFFER0_SIZE_3(BUF0_LEN); | 2670 | rxdp->Control_2 = SET_BUFFER0_SIZE_3(BUF0_LEN); |
@@ -2662,18 +2679,17 @@ static int fill_rx_buffers(struct ring_info *ring) | |||
2662 | (ring->pdev, skb->data, ring->mtu + 4, | 2679 | (ring->pdev, skb->data, ring->mtu + 4, |
2663 | PCI_DMA_FROMDEVICE); | 2680 | PCI_DMA_FROMDEVICE); |
2664 | 2681 | ||
2665 | if( (rxdp3->Buffer2_ptr == 0) || | 2682 | if (pci_dma_mapping_error(rxdp3->Buffer2_ptr)) |
2666 | (rxdp3->Buffer2_ptr == DMA_ERROR_CODE)) | ||
2667 | goto pci_map_failed; | 2683 | goto pci_map_failed; |
2668 | 2684 | ||
2685 | /* AK: check is wrong */ | ||
2669 | if (!rxdp3->Buffer1_ptr) | 2686 | if (!rxdp3->Buffer1_ptr) |
2670 | rxdp3->Buffer1_ptr = | 2687 | rxdp3->Buffer1_ptr = |
2671 | pci_map_single(ring->pdev, | 2688 | pci_map_single(ring->pdev, |
2672 | ba->ba_1, BUF1_LEN, | 2689 | ba->ba_1, BUF1_LEN, |
2673 | PCI_DMA_FROMDEVICE); | 2690 | PCI_DMA_FROMDEVICE); |
2674 | 2691 | ||
2675 | if( (rxdp3->Buffer1_ptr == 0) || | 2692 | if (pci_dma_mapping_error(rxdp3->Buffer1_ptr)) { |
2676 | (rxdp3->Buffer1_ptr == DMA_ERROR_CODE)) { | ||
2677 | pci_unmap_single | 2693 | pci_unmap_single |
2678 | (ring->pdev, | 2694 | (ring->pdev, |
2679 | (dma_addr_t)(unsigned long) | 2695 | (dma_addr_t)(unsigned long) |
@@ -2813,6 +2829,15 @@ static void free_rx_buffers(struct s2io_nic *sp) | |||
2813 | } | 2829 | } |
2814 | } | 2830 | } |
2815 | 2831 | ||
2832 | static int s2io_chk_rx_buffers(struct ring_info *ring) | ||
2833 | { | ||
2834 | if (fill_rx_buffers(ring) == -ENOMEM) { | ||
2835 | DBG_PRINT(INFO_DBG, "%s:Out of memory", ring->dev->name); | ||
2836 | DBG_PRINT(INFO_DBG, " in Rx Intr!!\n"); | ||
2837 | } | ||
2838 | return 0; | ||
2839 | } | ||
2840 | |||
2816 | /** | 2841 | /** |
2817 | * s2io_poll - Rx interrupt handler for NAPI support | 2842 | * s2io_poll - Rx interrupt handler for NAPI support |
2818 | * @napi : pointer to the napi structure. | 2843 | * @napi : pointer to the napi structure. |
@@ -2826,57 +2851,73 @@ static void free_rx_buffers(struct s2io_nic *sp) | |||
2826 | * 0 on success and 1 if there are No Rx packets to be processed. | 2851 | * 0 on success and 1 if there are No Rx packets to be processed. |
2827 | */ | 2852 | */ |
2828 | 2853 | ||
2829 | static int s2io_poll(struct napi_struct *napi, int budget) | 2854 | static int s2io_poll_msix(struct napi_struct *napi, int budget) |
2830 | { | 2855 | { |
2831 | struct s2io_nic *nic = container_of(napi, struct s2io_nic, napi); | 2856 | struct ring_info *ring = container_of(napi, struct ring_info, napi); |
2832 | struct net_device *dev = nic->dev; | 2857 | struct net_device *dev = ring->dev; |
2833 | int pkt_cnt = 0, org_pkts_to_process; | ||
2834 | struct mac_info *mac_control; | ||
2835 | struct config_param *config; | 2858 | struct config_param *config; |
2859 | struct mac_info *mac_control; | ||
2860 | int pkts_processed = 0; | ||
2861 | u8 __iomem *addr = NULL; | ||
2862 | u8 val8 = 0; | ||
2863 | struct s2io_nic *nic = dev->priv; | ||
2836 | struct XENA_dev_config __iomem *bar0 = nic->bar0; | 2864 | struct XENA_dev_config __iomem *bar0 = nic->bar0; |
2837 | int i; | 2865 | int budget_org = budget; |
2838 | 2866 | ||
2839 | mac_control = &nic->mac_control; | ||
2840 | config = &nic->config; | 2867 | config = &nic->config; |
2868 | mac_control = &nic->mac_control; | ||
2841 | 2869 | ||
2842 | nic->pkts_to_process = budget; | 2870 | if (unlikely(!is_s2io_card_up(nic))) |
2843 | org_pkts_to_process = nic->pkts_to_process; | 2871 | return 0; |
2844 | 2872 | ||
2845 | writeq(S2IO_MINUS_ONE, &bar0->rx_traffic_int); | 2873 | pkts_processed = rx_intr_handler(ring, budget); |
2846 | readl(&bar0->rx_traffic_int); | 2874 | s2io_chk_rx_buffers(ring); |
2847 | 2875 | ||
2848 | for (i = 0; i < config->rx_ring_num; i++) { | 2876 | if (pkts_processed < budget_org) { |
2849 | rx_intr_handler(&mac_control->rings[i]); | 2877 | netif_rx_complete(dev, napi); |
2850 | pkt_cnt = org_pkts_to_process - nic->pkts_to_process; | 2878 | /*Re Enable MSI-Rx Vector*/ |
2851 | if (!nic->pkts_to_process) { | 2879 | addr = (u8 __iomem *)&bar0->xmsi_mask_reg; |
2852 | /* Quota for the current iteration has been met */ | 2880 | addr += 7 - ring->ring_no; |
2853 | goto no_rx; | 2881 | val8 = (ring->ring_no == 0) ? 0x3f : 0xbf; |
2854 | } | 2882 | writeb(val8, addr); |
2883 | val8 = readb(addr); | ||
2855 | } | 2884 | } |
2885 | return pkts_processed; | ||
2886 | } | ||
2887 | static int s2io_poll_inta(struct napi_struct *napi, int budget) | ||
2888 | { | ||
2889 | struct s2io_nic *nic = container_of(napi, struct s2io_nic, napi); | ||
2890 | struct ring_info *ring; | ||
2891 | struct net_device *dev = nic->dev; | ||
2892 | struct config_param *config; | ||
2893 | struct mac_info *mac_control; | ||
2894 | int pkts_processed = 0; | ||
2895 | int ring_pkts_processed, i; | ||
2896 | struct XENA_dev_config __iomem *bar0 = nic->bar0; | ||
2897 | int budget_org = budget; | ||
2856 | 2898 | ||
2857 | netif_rx_complete(dev, napi); | 2899 | config = &nic->config; |
2900 | mac_control = &nic->mac_control; | ||
2858 | 2901 | ||
2859 | for (i = 0; i < config->rx_ring_num; i++) { | 2902 | if (unlikely(!is_s2io_card_up(nic))) |
2860 | if (fill_rx_buffers(&mac_control->rings[i]) == -ENOMEM) { | 2903 | return 0; |
2861 | DBG_PRINT(INFO_DBG, "%s:Out of memory", dev->name); | ||
2862 | DBG_PRINT(INFO_DBG, " in Rx Poll!!\n"); | ||
2863 | break; | ||
2864 | } | ||
2865 | } | ||
2866 | /* Re enable the Rx interrupts. */ | ||
2867 | writeq(0x0, &bar0->rx_traffic_mask); | ||
2868 | readl(&bar0->rx_traffic_mask); | ||
2869 | return pkt_cnt; | ||
2870 | 2904 | ||
2871 | no_rx: | ||
2872 | for (i = 0; i < config->rx_ring_num; i++) { | 2905 | for (i = 0; i < config->rx_ring_num; i++) { |
2873 | if (fill_rx_buffers(&mac_control->rings[i]) == -ENOMEM) { | 2906 | ring = &mac_control->rings[i]; |
2874 | DBG_PRINT(INFO_DBG, "%s:Out of memory", dev->name); | 2907 | ring_pkts_processed = rx_intr_handler(ring, budget); |
2875 | DBG_PRINT(INFO_DBG, " in Rx Poll!!\n"); | 2908 | s2io_chk_rx_buffers(ring); |
2909 | pkts_processed += ring_pkts_processed; | ||
2910 | budget -= ring_pkts_processed; | ||
2911 | if (budget <= 0) | ||
2876 | break; | 2912 | break; |
2877 | } | ||
2878 | } | 2913 | } |
2879 | return pkt_cnt; | 2914 | if (pkts_processed < budget_org) { |
2915 | netif_rx_complete(dev, napi); | ||
2916 | /* Re enable the Rx interrupts for the ring */ | ||
2917 | writeq(0, &bar0->rx_traffic_mask); | ||
2918 | readl(&bar0->rx_traffic_mask); | ||
2919 | } | ||
2920 | return pkts_processed; | ||
2880 | } | 2921 | } |
2881 | 2922 | ||
2882 | #ifdef CONFIG_NET_POLL_CONTROLLER | 2923 | #ifdef CONFIG_NET_POLL_CONTROLLER |
@@ -2918,7 +2959,7 @@ static void s2io_netpoll(struct net_device *dev) | |||
2918 | 2959 | ||
2919 | /* check for received packet and indicate up to network */ | 2960 | /* check for received packet and indicate up to network */ |
2920 | for (i = 0; i < config->rx_ring_num; i++) | 2961 | for (i = 0; i < config->rx_ring_num; i++) |
2921 | rx_intr_handler(&mac_control->rings[i]); | 2962 | rx_intr_handler(&mac_control->rings[i], 0); |
2922 | 2963 | ||
2923 | for (i = 0; i < config->rx_ring_num; i++) { | 2964 | for (i = 0; i < config->rx_ring_num; i++) { |
2924 | if (fill_rx_buffers(&mac_control->rings[i]) == -ENOMEM) { | 2965 | if (fill_rx_buffers(&mac_control->rings[i]) == -ENOMEM) { |
@@ -2934,7 +2975,8 @@ static void s2io_netpoll(struct net_device *dev) | |||
2934 | 2975 | ||
2935 | /** | 2976 | /** |
2936 | * rx_intr_handler - Rx interrupt handler | 2977 | * rx_intr_handler - Rx interrupt handler |
2937 | * @nic: device private variable. | 2978 | * @ring_info: per ring structure. |
2979 | * @budget: budget for napi processing. | ||
2938 | * Description: | 2980 | * Description: |
2939 | * If the interrupt is because of a received frame or if the | 2981 | * If the interrupt is because of a received frame or if the |
2940 | * receive ring contains fresh as yet un-processed frames,this function is | 2982 | * receive ring contains fresh as yet un-processed frames,this function is |
@@ -2942,15 +2984,15 @@ static void s2io_netpoll(struct net_device *dev) | |||
2942 | * stopped and sends the skb to the OSM's Rx handler and then increments | 2984 | * stopped and sends the skb to the OSM's Rx handler and then increments |
2943 | * the offset. | 2985 | * the offset. |
2944 | * Return Value: | 2986 | * Return Value: |
2945 | * NONE. | 2987 | * No. of napi packets processed. |
2946 | */ | 2988 | */ |
2947 | static void rx_intr_handler(struct ring_info *ring_data) | 2989 | static int rx_intr_handler(struct ring_info *ring_data, int budget) |
2948 | { | 2990 | { |
2949 | int get_block, put_block; | 2991 | int get_block, put_block; |
2950 | struct rx_curr_get_info get_info, put_info; | 2992 | struct rx_curr_get_info get_info, put_info; |
2951 | struct RxD_t *rxdp; | 2993 | struct RxD_t *rxdp; |
2952 | struct sk_buff *skb; | 2994 | struct sk_buff *skb; |
2953 | int pkt_cnt = 0; | 2995 | int pkt_cnt = 0, napi_pkts = 0; |
2954 | int i; | 2996 | int i; |
2955 | struct RxD1* rxdp1; | 2997 | struct RxD1* rxdp1; |
2956 | struct RxD3* rxdp3; | 2998 | struct RxD3* rxdp3; |
@@ -2977,7 +3019,7 @@ static void rx_intr_handler(struct ring_info *ring_data) | |||
2977 | DBG_PRINT(ERR_DBG, "%s: The skb is ", | 3019 | DBG_PRINT(ERR_DBG, "%s: The skb is ", |
2978 | ring_data->dev->name); | 3020 | ring_data->dev->name); |
2979 | DBG_PRINT(ERR_DBG, "Null in Rx Intr\n"); | 3021 | DBG_PRINT(ERR_DBG, "Null in Rx Intr\n"); |
2980 | return; | 3022 | return 0; |
2981 | } | 3023 | } |
2982 | if (ring_data->rxd_mode == RXD_MODE_1) { | 3024 | if (ring_data->rxd_mode == RXD_MODE_1) { |
2983 | rxdp1 = (struct RxD1*)rxdp; | 3025 | rxdp1 = (struct RxD1*)rxdp; |
@@ -3014,9 +3056,10 @@ static void rx_intr_handler(struct ring_info *ring_data) | |||
3014 | rxdp = ring_data->rx_blocks[get_block].block_virt_addr; | 3056 | rxdp = ring_data->rx_blocks[get_block].block_virt_addr; |
3015 | } | 3057 | } |
3016 | 3058 | ||
3017 | if(ring_data->nic->config.napi){ | 3059 | if (ring_data->nic->config.napi) { |
3018 | ring_data->nic->pkts_to_process -= 1; | 3060 | budget--; |
3019 | if (!ring_data->nic->pkts_to_process) | 3061 | napi_pkts++; |
3062 | if (!budget) | ||
3020 | break; | 3063 | break; |
3021 | } | 3064 | } |
3022 | pkt_cnt++; | 3065 | pkt_cnt++; |
@@ -3034,6 +3077,7 @@ static void rx_intr_handler(struct ring_info *ring_data) | |||
3034 | } | 3077 | } |
3035 | } | 3078 | } |
3036 | } | 3079 | } |
3080 | return(napi_pkts); | ||
3037 | } | 3081 | } |
3038 | 3082 | ||
3039 | /** | 3083 | /** |
@@ -3730,14 +3774,19 @@ static void restore_xmsi_data(struct s2io_nic *nic) | |||
3730 | { | 3774 | { |
3731 | struct XENA_dev_config __iomem *bar0 = nic->bar0; | 3775 | struct XENA_dev_config __iomem *bar0 = nic->bar0; |
3732 | u64 val64; | 3776 | u64 val64; |
3733 | int i; | 3777 | int i, msix_index; |
3778 | |||
3779 | |||
3780 | if (nic->device_type == XFRAME_I_DEVICE) | ||
3781 | return; | ||
3734 | 3782 | ||
3735 | for (i=0; i < MAX_REQUESTED_MSI_X; i++) { | 3783 | for (i=0; i < MAX_REQUESTED_MSI_X; i++) { |
3784 | msix_index = (i) ? ((i-1) * 8 + 1): 0; | ||
3736 | writeq(nic->msix_info[i].addr, &bar0->xmsi_address); | 3785 | writeq(nic->msix_info[i].addr, &bar0->xmsi_address); |
3737 | writeq(nic->msix_info[i].data, &bar0->xmsi_data); | 3786 | writeq(nic->msix_info[i].data, &bar0->xmsi_data); |
3738 | val64 = (s2BIT(7) | s2BIT(15) | vBIT(i, 26, 6)); | 3787 | val64 = (s2BIT(7) | s2BIT(15) | vBIT(msix_index, 26, 6)); |
3739 | writeq(val64, &bar0->xmsi_access); | 3788 | writeq(val64, &bar0->xmsi_access); |
3740 | if (wait_for_msix_trans(nic, i)) { | 3789 | if (wait_for_msix_trans(nic, msix_index)) { |
3741 | DBG_PRINT(ERR_DBG, "failed in %s\n", __FUNCTION__); | 3790 | DBG_PRINT(ERR_DBG, "failed in %s\n", __FUNCTION__); |
3742 | continue; | 3791 | continue; |
3743 | } | 3792 | } |
@@ -3748,13 +3797,17 @@ static void store_xmsi_data(struct s2io_nic *nic) | |||
3748 | { | 3797 | { |
3749 | struct XENA_dev_config __iomem *bar0 = nic->bar0; | 3798 | struct XENA_dev_config __iomem *bar0 = nic->bar0; |
3750 | u64 val64, addr, data; | 3799 | u64 val64, addr, data; |
3751 | int i; | 3800 | int i, msix_index; |
3801 | |||
3802 | if (nic->device_type == XFRAME_I_DEVICE) | ||
3803 | return; | ||
3752 | 3804 | ||
3753 | /* Store and display */ | 3805 | /* Store and display */ |
3754 | for (i=0; i < MAX_REQUESTED_MSI_X; i++) { | 3806 | for (i=0; i < MAX_REQUESTED_MSI_X; i++) { |
3755 | val64 = (s2BIT(15) | vBIT(i, 26, 6)); | 3807 | msix_index = (i) ? ((i-1) * 8 + 1): 0; |
3808 | val64 = (s2BIT(15) | vBIT(msix_index, 26, 6)); | ||
3756 | writeq(val64, &bar0->xmsi_access); | 3809 | writeq(val64, &bar0->xmsi_access); |
3757 | if (wait_for_msix_trans(nic, i)) { | 3810 | if (wait_for_msix_trans(nic, msix_index)) { |
3758 | DBG_PRINT(ERR_DBG, "failed in %s\n", __FUNCTION__); | 3811 | DBG_PRINT(ERR_DBG, "failed in %s\n", __FUNCTION__); |
3759 | continue; | 3812 | continue; |
3760 | } | 3813 | } |
@@ -3770,11 +3823,11 @@ static void store_xmsi_data(struct s2io_nic *nic) | |||
3770 | static int s2io_enable_msi_x(struct s2io_nic *nic) | 3823 | static int s2io_enable_msi_x(struct s2io_nic *nic) |
3771 | { | 3824 | { |
3772 | struct XENA_dev_config __iomem *bar0 = nic->bar0; | 3825 | struct XENA_dev_config __iomem *bar0 = nic->bar0; |
3773 | u64 tx_mat, rx_mat; | 3826 | u64 rx_mat; |
3774 | u16 msi_control; /* Temp variable */ | 3827 | u16 msi_control; /* Temp variable */ |
3775 | int ret, i, j, msix_indx = 1; | 3828 | int ret, i, j, msix_indx = 1; |
3776 | 3829 | ||
3777 | nic->entries = kcalloc(MAX_REQUESTED_MSI_X, sizeof(struct msix_entry), | 3830 | nic->entries = kmalloc(nic->num_entries * sizeof(struct msix_entry), |
3778 | GFP_KERNEL); | 3831 | GFP_KERNEL); |
3779 | if (!nic->entries) { | 3832 | if (!nic->entries) { |
3780 | DBG_PRINT(INFO_DBG, "%s: Memory allocation failed\n", \ | 3833 | DBG_PRINT(INFO_DBG, "%s: Memory allocation failed\n", \ |
@@ -3783,10 +3836,12 @@ static int s2io_enable_msi_x(struct s2io_nic *nic) | |||
3783 | return -ENOMEM; | 3836 | return -ENOMEM; |
3784 | } | 3837 | } |
3785 | nic->mac_control.stats_info->sw_stat.mem_allocated | 3838 | nic->mac_control.stats_info->sw_stat.mem_allocated |
3786 | += (MAX_REQUESTED_MSI_X * sizeof(struct msix_entry)); | 3839 | += (nic->num_entries * sizeof(struct msix_entry)); |
3840 | |||
3841 | memset(nic->entries, 0, nic->num_entries * sizeof(struct msix_entry)); | ||
3787 | 3842 | ||
3788 | nic->s2io_entries = | 3843 | nic->s2io_entries = |
3789 | kcalloc(MAX_REQUESTED_MSI_X, sizeof(struct s2io_msix_entry), | 3844 | kmalloc(nic->num_entries * sizeof(struct s2io_msix_entry), |
3790 | GFP_KERNEL); | 3845 | GFP_KERNEL); |
3791 | if (!nic->s2io_entries) { | 3846 | if (!nic->s2io_entries) { |
3792 | DBG_PRINT(INFO_DBG, "%s: Memory allocation failed\n", | 3847 | DBG_PRINT(INFO_DBG, "%s: Memory allocation failed\n", |
@@ -3794,60 +3849,52 @@ static int s2io_enable_msi_x(struct s2io_nic *nic) | |||
3794 | nic->mac_control.stats_info->sw_stat.mem_alloc_fail_cnt++; | 3849 | nic->mac_control.stats_info->sw_stat.mem_alloc_fail_cnt++; |
3795 | kfree(nic->entries); | 3850 | kfree(nic->entries); |
3796 | nic->mac_control.stats_info->sw_stat.mem_freed | 3851 | nic->mac_control.stats_info->sw_stat.mem_freed |
3797 | += (MAX_REQUESTED_MSI_X * sizeof(struct msix_entry)); | 3852 | += (nic->num_entries * sizeof(struct msix_entry)); |
3798 | return -ENOMEM; | 3853 | return -ENOMEM; |
3799 | } | 3854 | } |
3800 | nic->mac_control.stats_info->sw_stat.mem_allocated | 3855 | nic->mac_control.stats_info->sw_stat.mem_allocated |
3801 | += (MAX_REQUESTED_MSI_X * sizeof(struct s2io_msix_entry)); | 3856 | += (nic->num_entries * sizeof(struct s2io_msix_entry)); |
3802 | 3857 | memset(nic->s2io_entries, 0, | |
3803 | for (i=0; i< MAX_REQUESTED_MSI_X; i++) { | 3858 | nic->num_entries * sizeof(struct s2io_msix_entry)); |
3804 | nic->entries[i].entry = i; | 3859 | |
3805 | nic->s2io_entries[i].entry = i; | 3860 | nic->entries[0].entry = 0; |
3861 | nic->s2io_entries[0].entry = 0; | ||
3862 | nic->s2io_entries[0].in_use = MSIX_FLG; | ||
3863 | nic->s2io_entries[0].type = MSIX_ALARM_TYPE; | ||
3864 | nic->s2io_entries[0].arg = &nic->mac_control.fifos; | ||
3865 | |||
3866 | for (i = 1; i < nic->num_entries; i++) { | ||
3867 | nic->entries[i].entry = ((i - 1) * 8) + 1; | ||
3868 | nic->s2io_entries[i].entry = ((i - 1) * 8) + 1; | ||
3806 | nic->s2io_entries[i].arg = NULL; | 3869 | nic->s2io_entries[i].arg = NULL; |
3807 | nic->s2io_entries[i].in_use = 0; | 3870 | nic->s2io_entries[i].in_use = 0; |
3808 | } | 3871 | } |
3809 | 3872 | ||
3810 | tx_mat = readq(&bar0->tx_mat0_n[0]); | ||
3811 | for (i=0; i<nic->config.tx_fifo_num; i++, msix_indx++) { | ||
3812 | tx_mat |= TX_MAT_SET(i, msix_indx); | ||
3813 | nic->s2io_entries[msix_indx].arg = &nic->mac_control.fifos[i]; | ||
3814 | nic->s2io_entries[msix_indx].type = MSIX_FIFO_TYPE; | ||
3815 | nic->s2io_entries[msix_indx].in_use = MSIX_FLG; | ||
3816 | } | ||
3817 | writeq(tx_mat, &bar0->tx_mat0_n[0]); | ||
3818 | |||
3819 | rx_mat = readq(&bar0->rx_mat); | 3873 | rx_mat = readq(&bar0->rx_mat); |
3820 | for (j = 0; j < nic->config.rx_ring_num; j++, msix_indx++) { | 3874 | for (j = 0; j < nic->config.rx_ring_num; j++) { |
3821 | rx_mat |= RX_MAT_SET(j, msix_indx); | 3875 | rx_mat |= RX_MAT_SET(j, msix_indx); |
3822 | nic->s2io_entries[msix_indx].arg | 3876 | nic->s2io_entries[j+1].arg = &nic->mac_control.rings[j]; |
3823 | = &nic->mac_control.rings[j]; | 3877 | nic->s2io_entries[j+1].type = MSIX_RING_TYPE; |
3824 | nic->s2io_entries[msix_indx].type = MSIX_RING_TYPE; | 3878 | nic->s2io_entries[j+1].in_use = MSIX_FLG; |
3825 | nic->s2io_entries[msix_indx].in_use = MSIX_FLG; | 3879 | msix_indx += 8; |
3826 | } | 3880 | } |
3827 | writeq(rx_mat, &bar0->rx_mat); | 3881 | writeq(rx_mat, &bar0->rx_mat); |
3882 | readq(&bar0->rx_mat); | ||
3828 | 3883 | ||
3829 | nic->avail_msix_vectors = 0; | 3884 | ret = pci_enable_msix(nic->pdev, nic->entries, nic->num_entries); |
3830 | ret = pci_enable_msix(nic->pdev, nic->entries, MAX_REQUESTED_MSI_X); | ||
3831 | /* We fail init if error or we get less vectors than min required */ | 3885 | /* We fail init if error or we get less vectors than min required */ |
3832 | if (ret >= (nic->config.tx_fifo_num + nic->config.rx_ring_num + 1)) { | ||
3833 | nic->avail_msix_vectors = ret; | ||
3834 | ret = pci_enable_msix(nic->pdev, nic->entries, ret); | ||
3835 | } | ||
3836 | if (ret) { | 3886 | if (ret) { |
3837 | DBG_PRINT(ERR_DBG, "%s: Enabling MSIX failed\n", nic->dev->name); | 3887 | DBG_PRINT(ERR_DBG, "%s: Enabling MSIX failed\n", nic->dev->name); |
3838 | kfree(nic->entries); | 3888 | kfree(nic->entries); |
3839 | nic->mac_control.stats_info->sw_stat.mem_freed | 3889 | nic->mac_control.stats_info->sw_stat.mem_freed |
3840 | += (MAX_REQUESTED_MSI_X * sizeof(struct msix_entry)); | 3890 | += (nic->num_entries * sizeof(struct msix_entry)); |
3841 | kfree(nic->s2io_entries); | 3891 | kfree(nic->s2io_entries); |
3842 | nic->mac_control.stats_info->sw_stat.mem_freed | 3892 | nic->mac_control.stats_info->sw_stat.mem_freed |
3843 | += (MAX_REQUESTED_MSI_X * sizeof(struct s2io_msix_entry)); | 3893 | += (nic->num_entries * sizeof(struct s2io_msix_entry)); |
3844 | nic->entries = NULL; | 3894 | nic->entries = NULL; |
3845 | nic->s2io_entries = NULL; | 3895 | nic->s2io_entries = NULL; |
3846 | nic->avail_msix_vectors = 0; | ||
3847 | return -ENOMEM; | 3896 | return -ENOMEM; |
3848 | } | 3897 | } |
3849 | if (!nic->avail_msix_vectors) | ||
3850 | nic->avail_msix_vectors = MAX_REQUESTED_MSI_X; | ||
3851 | 3898 | ||
3852 | /* | 3899 | /* |
3853 | * To enable MSI-X, MSI also needs to be enabled, due to a bug | 3900 | * To enable MSI-X, MSI also needs to be enabled, due to a bug |
@@ -3919,7 +3966,7 @@ static void remove_msix_isr(struct s2io_nic *sp) | |||
3919 | int i; | 3966 | int i; |
3920 | u16 msi_control; | 3967 | u16 msi_control; |
3921 | 3968 | ||
3922 | for (i = 0; i < MAX_REQUESTED_MSI_X; i++) { | 3969 | for (i = 0; i < sp->num_entries; i++) { |
3923 | if (sp->s2io_entries[i].in_use == | 3970 | if (sp->s2io_entries[i].in_use == |
3924 | MSIX_REGISTERED_SUCCESS) { | 3971 | MSIX_REGISTERED_SUCCESS) { |
3925 | int vector = sp->entries[i].vector; | 3972 | int vector = sp->entries[i].vector; |
@@ -3975,29 +4022,6 @@ static int s2io_open(struct net_device *dev) | |||
3975 | netif_carrier_off(dev); | 4022 | netif_carrier_off(dev); |
3976 | sp->last_link_state = 0; | 4023 | sp->last_link_state = 0; |
3977 | 4024 | ||
3978 | if (sp->config.intr_type == MSI_X) { | ||
3979 | int ret = s2io_enable_msi_x(sp); | ||
3980 | |||
3981 | if (!ret) { | ||
3982 | ret = s2io_test_msi(sp); | ||
3983 | /* rollback MSI-X, will re-enable during add_isr() */ | ||
3984 | remove_msix_isr(sp); | ||
3985 | } | ||
3986 | if (ret) { | ||
3987 | |||
3988 | DBG_PRINT(ERR_DBG, | ||
3989 | "%s: MSI-X requested but failed to enable\n", | ||
3990 | dev->name); | ||
3991 | sp->config.intr_type = INTA; | ||
3992 | } | ||
3993 | } | ||
3994 | |||
3995 | /* NAPI doesn't work well with MSI(X) */ | ||
3996 | if (sp->config.intr_type != INTA) { | ||
3997 | if(sp->config.napi) | ||
3998 | sp->config.napi = 0; | ||
3999 | } | ||
4000 | |||
4001 | /* Initialize H/W and enable interrupts */ | 4025 | /* Initialize H/W and enable interrupts */ |
4002 | err = s2io_card_up(sp); | 4026 | err = s2io_card_up(sp); |
4003 | if (err) { | 4027 | if (err) { |
@@ -4020,12 +4044,12 @@ hw_init_failed: | |||
4020 | if (sp->entries) { | 4044 | if (sp->entries) { |
4021 | kfree(sp->entries); | 4045 | kfree(sp->entries); |
4022 | sp->mac_control.stats_info->sw_stat.mem_freed | 4046 | sp->mac_control.stats_info->sw_stat.mem_freed |
4023 | += (MAX_REQUESTED_MSI_X * sizeof(struct msix_entry)); | 4047 | += (sp->num_entries * sizeof(struct msix_entry)); |
4024 | } | 4048 | } |
4025 | if (sp->s2io_entries) { | 4049 | if (sp->s2io_entries) { |
4026 | kfree(sp->s2io_entries); | 4050 | kfree(sp->s2io_entries); |
4027 | sp->mac_control.stats_info->sw_stat.mem_freed | 4051 | sp->mac_control.stats_info->sw_stat.mem_freed |
4028 | += (MAX_REQUESTED_MSI_X * sizeof(struct s2io_msix_entry)); | 4052 | += (sp->num_entries * sizeof(struct s2io_msix_entry)); |
4029 | } | 4053 | } |
4030 | } | 4054 | } |
4031 | return err; | 4055 | return err; |
@@ -4237,16 +4261,14 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev) | |||
4237 | txdp->Buffer_Pointer = pci_map_single(sp->pdev, | 4261 | txdp->Buffer_Pointer = pci_map_single(sp->pdev, |
4238 | fifo->ufo_in_band_v, | 4262 | fifo->ufo_in_band_v, |
4239 | sizeof(u64), PCI_DMA_TODEVICE); | 4263 | sizeof(u64), PCI_DMA_TODEVICE); |
4240 | if((txdp->Buffer_Pointer == 0) || | 4264 | if (pci_dma_mapping_error(txdp->Buffer_Pointer)) |
4241 | (txdp->Buffer_Pointer == DMA_ERROR_CODE)) | ||
4242 | goto pci_map_failed; | 4265 | goto pci_map_failed; |
4243 | txdp++; | 4266 | txdp++; |
4244 | } | 4267 | } |
4245 | 4268 | ||
4246 | txdp->Buffer_Pointer = pci_map_single | 4269 | txdp->Buffer_Pointer = pci_map_single |
4247 | (sp->pdev, skb->data, frg_len, PCI_DMA_TODEVICE); | 4270 | (sp->pdev, skb->data, frg_len, PCI_DMA_TODEVICE); |
4248 | if((txdp->Buffer_Pointer == 0) || | 4271 | if (pci_dma_mapping_error(txdp->Buffer_Pointer)) |
4249 | (txdp->Buffer_Pointer == DMA_ERROR_CODE)) | ||
4250 | goto pci_map_failed; | 4272 | goto pci_map_failed; |
4251 | 4273 | ||
4252 | txdp->Host_Control = (unsigned long) skb; | 4274 | txdp->Host_Control = (unsigned long) skb; |
@@ -4327,40 +4349,65 @@ s2io_alarm_handle(unsigned long data) | |||
4327 | mod_timer(&sp->alarm_timer, jiffies + HZ / 2); | 4349 | mod_timer(&sp->alarm_timer, jiffies + HZ / 2); |
4328 | } | 4350 | } |
4329 | 4351 | ||
4330 | static int s2io_chk_rx_buffers(struct ring_info *ring) | ||
4331 | { | ||
4332 | if (fill_rx_buffers(ring) == -ENOMEM) { | ||
4333 | DBG_PRINT(INFO_DBG, "%s:Out of memory", ring->dev->name); | ||
4334 | DBG_PRINT(INFO_DBG, " in Rx Intr!!\n"); | ||
4335 | } | ||
4336 | return 0; | ||
4337 | } | ||
4338 | |||
4339 | static irqreturn_t s2io_msix_ring_handle(int irq, void *dev_id) | 4352 | static irqreturn_t s2io_msix_ring_handle(int irq, void *dev_id) |
4340 | { | 4353 | { |
4341 | struct ring_info *ring = (struct ring_info *)dev_id; | 4354 | struct ring_info *ring = (struct ring_info *)dev_id; |
4342 | struct s2io_nic *sp = ring->nic; | 4355 | struct s2io_nic *sp = ring->nic; |
4356 | struct XENA_dev_config __iomem *bar0 = sp->bar0; | ||
4357 | struct net_device *dev = sp->dev; | ||
4343 | 4358 | ||
4344 | if (!is_s2io_card_up(sp)) | 4359 | if (unlikely(!is_s2io_card_up(sp))) |
4345 | return IRQ_HANDLED; | 4360 | return IRQ_HANDLED; |
4346 | 4361 | ||
4347 | rx_intr_handler(ring); | 4362 | if (sp->config.napi) { |
4348 | s2io_chk_rx_buffers(ring); | 4363 | u8 __iomem *addr = NULL; |
4364 | u8 val8 = 0; | ||
4365 | |||
4366 | addr = (u8 __iomem *)&bar0->xmsi_mask_reg; | ||
4367 | addr += (7 - ring->ring_no); | ||
4368 | val8 = (ring->ring_no == 0) ? 0x7f : 0xff; | ||
4369 | writeb(val8, addr); | ||
4370 | val8 = readb(addr); | ||
4371 | netif_rx_schedule(dev, &ring->napi); | ||
4372 | } else { | ||
4373 | rx_intr_handler(ring, 0); | ||
4374 | s2io_chk_rx_buffers(ring); | ||
4375 | } | ||
4349 | 4376 | ||
4350 | return IRQ_HANDLED; | 4377 | return IRQ_HANDLED; |
4351 | } | 4378 | } |
4352 | 4379 | ||
4353 | static irqreturn_t s2io_msix_fifo_handle(int irq, void *dev_id) | 4380 | static irqreturn_t s2io_msix_fifo_handle(int irq, void *dev_id) |
4354 | { | 4381 | { |
4355 | struct fifo_info *fifo = (struct fifo_info *)dev_id; | 4382 | int i; |
4356 | struct s2io_nic *sp = fifo->nic; | 4383 | struct fifo_info *fifos = (struct fifo_info *)dev_id; |
4384 | struct s2io_nic *sp = fifos->nic; | ||
4385 | struct XENA_dev_config __iomem *bar0 = sp->bar0; | ||
4386 | struct config_param *config = &sp->config; | ||
4387 | u64 reason; | ||
4357 | 4388 | ||
4358 | if (!is_s2io_card_up(sp)) | 4389 | if (unlikely(!is_s2io_card_up(sp))) |
4390 | return IRQ_NONE; | ||
4391 | |||
4392 | reason = readq(&bar0->general_int_status); | ||
4393 | if (unlikely(reason == S2IO_MINUS_ONE)) | ||
4394 | /* Nothing much can be done. Get out */ | ||
4359 | return IRQ_HANDLED; | 4395 | return IRQ_HANDLED; |
4360 | 4396 | ||
4361 | tx_intr_handler(fifo); | 4397 | writeq(S2IO_MINUS_ONE, &bar0->general_int_mask); |
4398 | |||
4399 | if (reason & GEN_INTR_TXTRAFFIC) | ||
4400 | writeq(S2IO_MINUS_ONE, &bar0->tx_traffic_int); | ||
4401 | |||
4402 | for (i = 0; i < config->tx_fifo_num; i++) | ||
4403 | tx_intr_handler(&fifos[i]); | ||
4404 | |||
4405 | writeq(sp->general_int_mask, &bar0->general_int_mask); | ||
4406 | readl(&bar0->general_int_status); | ||
4407 | |||
4362 | return IRQ_HANDLED; | 4408 | return IRQ_HANDLED; |
4363 | } | 4409 | } |
4410 | |||
4364 | static void s2io_txpic_intr_handle(struct s2io_nic *sp) | 4411 | static void s2io_txpic_intr_handle(struct s2io_nic *sp) |
4365 | { | 4412 | { |
4366 | struct XENA_dev_config __iomem *bar0 = sp->bar0; | 4413 | struct XENA_dev_config __iomem *bar0 = sp->bar0; |
@@ -4762,14 +4809,10 @@ static irqreturn_t s2io_isr(int irq, void *dev_id) | |||
4762 | 4809 | ||
4763 | if (config->napi) { | 4810 | if (config->napi) { |
4764 | if (reason & GEN_INTR_RXTRAFFIC) { | 4811 | if (reason & GEN_INTR_RXTRAFFIC) { |
4765 | if (likely(netif_rx_schedule_prep(dev, | 4812 | netif_rx_schedule(dev, &sp->napi); |
4766 | &sp->napi))) { | 4813 | writeq(S2IO_MINUS_ONE, &bar0->rx_traffic_mask); |
4767 | __netif_rx_schedule(dev, &sp->napi); | 4814 | writeq(S2IO_MINUS_ONE, &bar0->rx_traffic_int); |
4768 | writeq(S2IO_MINUS_ONE, | 4815 | readl(&bar0->rx_traffic_int); |
4769 | &bar0->rx_traffic_mask); | ||
4770 | } else | ||
4771 | writeq(S2IO_MINUS_ONE, | ||
4772 | &bar0->rx_traffic_int); | ||
4773 | } | 4816 | } |
4774 | } else { | 4817 | } else { |
4775 | /* | 4818 | /* |
@@ -4781,7 +4824,7 @@ static irqreturn_t s2io_isr(int irq, void *dev_id) | |||
4781 | writeq(S2IO_MINUS_ONE, &bar0->rx_traffic_int); | 4824 | writeq(S2IO_MINUS_ONE, &bar0->rx_traffic_int); |
4782 | 4825 | ||
4783 | for (i = 0; i < config->rx_ring_num; i++) | 4826 | for (i = 0; i < config->rx_ring_num; i++) |
4784 | rx_intr_handler(&mac_control->rings[i]); | 4827 | rx_intr_handler(&mac_control->rings[i], 0); |
4785 | } | 4828 | } |
4786 | 4829 | ||
4787 | /* | 4830 | /* |
@@ -6836,10 +6879,8 @@ static int set_rxd_buffer_pointer(struct s2io_nic *sp, struct RxD_t *rxdp, | |||
6836 | pci_map_single( sp->pdev, (*skb)->data, | 6879 | pci_map_single( sp->pdev, (*skb)->data, |
6837 | size - NET_IP_ALIGN, | 6880 | size - NET_IP_ALIGN, |
6838 | PCI_DMA_FROMDEVICE); | 6881 | PCI_DMA_FROMDEVICE); |
6839 | if( (rxdp1->Buffer0_ptr == 0) || | 6882 | if (pci_dma_mapping_error(rxdp1->Buffer0_ptr)) |
6840 | (rxdp1->Buffer0_ptr == DMA_ERROR_CODE)) { | ||
6841 | goto memalloc_failed; | 6883 | goto memalloc_failed; |
6842 | } | ||
6843 | rxdp->Host_Control = (unsigned long) (*skb); | 6884 | rxdp->Host_Control = (unsigned long) (*skb); |
6844 | } | 6885 | } |
6845 | } else if ((sp->rxd_mode == RXD_MODE_3B) && (rxdp->Host_Control == 0)) { | 6886 | } else if ((sp->rxd_mode == RXD_MODE_3B) && (rxdp->Host_Control == 0)) { |
@@ -6865,15 +6906,12 @@ static int set_rxd_buffer_pointer(struct s2io_nic *sp, struct RxD_t *rxdp, | |||
6865 | pci_map_single(sp->pdev, (*skb)->data, | 6906 | pci_map_single(sp->pdev, (*skb)->data, |
6866 | dev->mtu + 4, | 6907 | dev->mtu + 4, |
6867 | PCI_DMA_FROMDEVICE); | 6908 | PCI_DMA_FROMDEVICE); |
6868 | if( (rxdp3->Buffer2_ptr == 0) || | 6909 | if (pci_dma_mapping_error(rxdp3->Buffer2_ptr)) |
6869 | (rxdp3->Buffer2_ptr == DMA_ERROR_CODE)) { | ||
6870 | goto memalloc_failed; | 6910 | goto memalloc_failed; |
6871 | } | ||
6872 | rxdp3->Buffer0_ptr = *temp0 = | 6911 | rxdp3->Buffer0_ptr = *temp0 = |
6873 | pci_map_single( sp->pdev, ba->ba_0, BUF0_LEN, | 6912 | pci_map_single( sp->pdev, ba->ba_0, BUF0_LEN, |
6874 | PCI_DMA_FROMDEVICE); | 6913 | PCI_DMA_FROMDEVICE); |
6875 | if( (rxdp3->Buffer0_ptr == 0) || | 6914 | if (pci_dma_mapping_error(rxdp3->Buffer0_ptr)) { |
6876 | (rxdp3->Buffer0_ptr == DMA_ERROR_CODE)) { | ||
6877 | pci_unmap_single (sp->pdev, | 6915 | pci_unmap_single (sp->pdev, |
6878 | (dma_addr_t)rxdp3->Buffer2_ptr, | 6916 | (dma_addr_t)rxdp3->Buffer2_ptr, |
6879 | dev->mtu + 4, PCI_DMA_FROMDEVICE); | 6917 | dev->mtu + 4, PCI_DMA_FROMDEVICE); |
@@ -6885,8 +6923,7 @@ static int set_rxd_buffer_pointer(struct s2io_nic *sp, struct RxD_t *rxdp, | |||
6885 | rxdp3->Buffer1_ptr = *temp1 = | 6923 | rxdp3->Buffer1_ptr = *temp1 = |
6886 | pci_map_single(sp->pdev, ba->ba_1, BUF1_LEN, | 6924 | pci_map_single(sp->pdev, ba->ba_1, BUF1_LEN, |
6887 | PCI_DMA_FROMDEVICE); | 6925 | PCI_DMA_FROMDEVICE); |
6888 | if( (rxdp3->Buffer1_ptr == 0) || | 6926 | if (pci_dma_mapping_error(rxdp3->Buffer1_ptr)) { |
6889 | (rxdp3->Buffer1_ptr == DMA_ERROR_CODE)) { | ||
6890 | pci_unmap_single (sp->pdev, | 6927 | pci_unmap_single (sp->pdev, |
6891 | (dma_addr_t)rxdp3->Buffer0_ptr, | 6928 | (dma_addr_t)rxdp3->Buffer0_ptr, |
6892 | BUF0_LEN, PCI_DMA_FROMDEVICE); | 6929 | BUF0_LEN, PCI_DMA_FROMDEVICE); |
@@ -6984,62 +7021,62 @@ static int s2io_add_isr(struct s2io_nic * sp) | |||
6984 | 7021 | ||
6985 | /* After proper initialization of H/W, register ISR */ | 7022 | /* After proper initialization of H/W, register ISR */ |
6986 | if (sp->config.intr_type == MSI_X) { | 7023 | if (sp->config.intr_type == MSI_X) { |
6987 | int i, msix_tx_cnt=0,msix_rx_cnt=0; | 7024 | int i, msix_rx_cnt = 0; |
6988 | 7025 | ||
6989 | for (i=1; (sp->s2io_entries[i].in_use == MSIX_FLG); i++) { | 7026 | for (i = 0; i < sp->num_entries; i++) { |
6990 | if (sp->s2io_entries[i].type == MSIX_FIFO_TYPE) { | 7027 | if (sp->s2io_entries[i].in_use == MSIX_FLG) { |
6991 | sprintf(sp->desc[i], "%s:MSI-X-%d-TX", | 7028 | if (sp->s2io_entries[i].type == |
7029 | MSIX_RING_TYPE) { | ||
7030 | sprintf(sp->desc[i], "%s:MSI-X-%d-RX", | ||
7031 | dev->name, i); | ||
7032 | err = request_irq(sp->entries[i].vector, | ||
7033 | s2io_msix_ring_handle, 0, | ||
7034 | sp->desc[i], | ||
7035 | sp->s2io_entries[i].arg); | ||
7036 | } else if (sp->s2io_entries[i].type == | ||
7037 | MSIX_ALARM_TYPE) { | ||
7038 | sprintf(sp->desc[i], "%s:MSI-X-%d-TX", | ||
6992 | dev->name, i); | 7039 | dev->name, i); |
6993 | err = request_irq(sp->entries[i].vector, | 7040 | err = request_irq(sp->entries[i].vector, |
6994 | s2io_msix_fifo_handle, 0, sp->desc[i], | 7041 | s2io_msix_fifo_handle, 0, |
6995 | sp->s2io_entries[i].arg); | 7042 | sp->desc[i], |
6996 | /* If either data or addr is zero print it */ | 7043 | sp->s2io_entries[i].arg); |
6997 | if(!(sp->msix_info[i].addr && | 7044 | |
6998 | sp->msix_info[i].data)) { | ||
6999 | DBG_PRINT(ERR_DBG, "%s @ Addr:0x%llx " | ||
7000 | "Data:0x%llx\n",sp->desc[i], | ||
7001 | (unsigned long long) | ||
7002 | sp->msix_info[i].addr, | ||
7003 | (unsigned long long) | ||
7004 | sp->msix_info[i].data); | ||
7005 | } else { | ||
7006 | msix_tx_cnt++; | ||
7007 | } | 7045 | } |
7008 | } else { | 7046 | /* if either data or addr is zero print it. */ |
7009 | sprintf(sp->desc[i], "%s:MSI-X-%d-RX", | 7047 | if (!(sp->msix_info[i].addr && |
7010 | dev->name, i); | ||
7011 | err = request_irq(sp->entries[i].vector, | ||
7012 | s2io_msix_ring_handle, 0, sp->desc[i], | ||
7013 | sp->s2io_entries[i].arg); | ||
7014 | /* If either data or addr is zero print it */ | ||
7015 | if(!(sp->msix_info[i].addr && | ||
7016 | sp->msix_info[i].data)) { | 7048 | sp->msix_info[i].data)) { |
7017 | DBG_PRINT(ERR_DBG, "%s @ Addr:0x%llx " | 7049 | DBG_PRINT(ERR_DBG, |
7018 | "Data:0x%llx\n",sp->desc[i], | 7050 | "%s @Addr:0x%llx Data:0x%llx\n", |
7051 | sp->desc[i], | ||
7019 | (unsigned long long) | 7052 | (unsigned long long) |
7020 | sp->msix_info[i].addr, | 7053 | sp->msix_info[i].addr, |
7021 | (unsigned long long) | 7054 | (unsigned long long) |
7022 | sp->msix_info[i].data); | 7055 | ntohl(sp->msix_info[i].data)); |
7023 | } else { | 7056 | } else |
7024 | msix_rx_cnt++; | 7057 | msix_rx_cnt++; |
7058 | if (err) { | ||
7059 | remove_msix_isr(sp); | ||
7060 | |||
7061 | DBG_PRINT(ERR_DBG, | ||
7062 | "%s:MSI-X-%d registration " | ||
7063 | "failed\n", dev->name, i); | ||
7064 | |||
7065 | DBG_PRINT(ERR_DBG, | ||
7066 | "%s: Defaulting to INTA\n", | ||
7067 | dev->name); | ||
7068 | sp->config.intr_type = INTA; | ||
7069 | break; | ||
7025 | } | 7070 | } |
7071 | sp->s2io_entries[i].in_use = | ||
7072 | MSIX_REGISTERED_SUCCESS; | ||
7026 | } | 7073 | } |
7027 | if (err) { | ||
7028 | remove_msix_isr(sp); | ||
7029 | DBG_PRINT(ERR_DBG,"%s:MSI-X-%d registration " | ||
7030 | "failed\n", dev->name, i); | ||
7031 | DBG_PRINT(ERR_DBG, "%s: defaulting to INTA\n", | ||
7032 | dev->name); | ||
7033 | sp->config.intr_type = INTA; | ||
7034 | break; | ||
7035 | } | ||
7036 | sp->s2io_entries[i].in_use = MSIX_REGISTERED_SUCCESS; | ||
7037 | } | 7074 | } |
7038 | if (!err) { | 7075 | if (!err) { |
7039 | printk(KERN_INFO "MSI-X-TX %d entries enabled\n", | ||
7040 | msix_tx_cnt); | ||
7041 | printk(KERN_INFO "MSI-X-RX %d entries enabled\n", | 7076 | printk(KERN_INFO "MSI-X-RX %d entries enabled\n", |
7042 | msix_rx_cnt); | 7077 | --msix_rx_cnt); |
7078 | DBG_PRINT(INFO_DBG, "MSI-X-TX entries enabled" | ||
7079 | " through alarm vector\n"); | ||
7043 | } | 7080 | } |
7044 | } | 7081 | } |
7045 | if (sp->config.intr_type == INTA) { | 7082 | if (sp->config.intr_type == INTA) { |
@@ -7080,8 +7117,15 @@ static void do_s2io_card_down(struct s2io_nic * sp, int do_io) | |||
7080 | clear_bit(__S2IO_STATE_CARD_UP, &sp->state); | 7117 | clear_bit(__S2IO_STATE_CARD_UP, &sp->state); |
7081 | 7118 | ||
7082 | /* Disable napi */ | 7119 | /* Disable napi */ |
7083 | if (config->napi) | 7120 | if (sp->config.napi) { |
7084 | napi_disable(&sp->napi); | 7121 | int off = 0; |
7122 | if (config->intr_type == MSI_X) { | ||
7123 | for (; off < sp->config.rx_ring_num; off++) | ||
7124 | napi_disable(&sp->mac_control.rings[off].napi); | ||
7125 | } | ||
7126 | else | ||
7127 | napi_disable(&sp->napi); | ||
7128 | } | ||
7085 | 7129 | ||
7086 | /* disable Tx and Rx traffic on the NIC */ | 7130 | /* disable Tx and Rx traffic on the NIC */ |
7087 | if (do_io) | 7131 | if (do_io) |
@@ -7173,8 +7217,15 @@ static int s2io_card_up(struct s2io_nic * sp) | |||
7173 | } | 7217 | } |
7174 | 7218 | ||
7175 | /* Initialise napi */ | 7219 | /* Initialise napi */ |
7176 | if (config->napi) | 7220 | if (config->napi) { |
7177 | napi_enable(&sp->napi); | 7221 | int i; |
7222 | if (config->intr_type == MSI_X) { | ||
7223 | for (i = 0; i < sp->config.rx_ring_num; i++) | ||
7224 | napi_enable(&sp->mac_control.rings[i].napi); | ||
7225 | } else { | ||
7226 | napi_enable(&sp->napi); | ||
7227 | } | ||
7228 | } | ||
7178 | 7229 | ||
7179 | /* Maintain the state prior to the open */ | 7230 | /* Maintain the state prior to the open */ |
7180 | if (sp->promisc_flg) | 7231 | if (sp->promisc_flg) |
@@ -7217,7 +7268,7 @@ static int s2io_card_up(struct s2io_nic * sp) | |||
7217 | /* Enable select interrupts */ | 7268 | /* Enable select interrupts */ |
7218 | en_dis_err_alarms(sp, ENA_ALL_INTRS, ENABLE_INTRS); | 7269 | en_dis_err_alarms(sp, ENA_ALL_INTRS, ENABLE_INTRS); |
7219 | if (sp->config.intr_type != INTA) | 7270 | if (sp->config.intr_type != INTA) |
7220 | en_dis_able_nic_intrs(sp, ENA_ALL_INTRS, DISABLE_INTRS); | 7271 | en_dis_able_nic_intrs(sp, TX_TRAFFIC_INTR, ENABLE_INTRS); |
7221 | else { | 7272 | else { |
7222 | interruptible = TX_TRAFFIC_INTR | RX_TRAFFIC_INTR; | 7273 | interruptible = TX_TRAFFIC_INTR | RX_TRAFFIC_INTR; |
7223 | interruptible |= TX_PIC_INTR; | 7274 | interruptible |= TX_PIC_INTR; |
@@ -7615,9 +7666,6 @@ static int s2io_verify_parm(struct pci_dev *pdev, u8 *dev_intr_type, | |||
7615 | rx_ring_num = MAX_RX_RINGS; | 7666 | rx_ring_num = MAX_RX_RINGS; |
7616 | } | 7667 | } |
7617 | 7668 | ||
7618 | if (*dev_intr_type != INTA) | ||
7619 | napi = 0; | ||
7620 | |||
7621 | if ((*dev_intr_type != INTA) && (*dev_intr_type != MSI_X)) { | 7669 | if ((*dev_intr_type != INTA) && (*dev_intr_type != MSI_X)) { |
7622 | DBG_PRINT(ERR_DBG, "s2io: Wrong intr_type requested. " | 7670 | DBG_PRINT(ERR_DBG, "s2io: Wrong intr_type requested. " |
7623 | "Defaulting to INTA\n"); | 7671 | "Defaulting to INTA\n"); |
@@ -7918,8 +7966,6 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) | |||
7918 | * will use eth_mac_addr() for dev->set_mac_address | 7966 | * will use eth_mac_addr() for dev->set_mac_address |
7919 | * mac address will be set every time dev->open() is called | 7967 | * mac address will be set every time dev->open() is called |
7920 | */ | 7968 | */ |
7921 | netif_napi_add(dev, &sp->napi, s2io_poll, 32); | ||
7922 | |||
7923 | #ifdef CONFIG_NET_POLL_CONTROLLER | 7969 | #ifdef CONFIG_NET_POLL_CONTROLLER |
7924 | dev->poll_controller = s2io_netpoll; | 7970 | dev->poll_controller = s2io_netpoll; |
7925 | #endif | 7971 | #endif |
@@ -7963,6 +8009,32 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) | |||
7963 | } | 8009 | } |
7964 | } | 8010 | } |
7965 | 8011 | ||
8012 | if (sp->config.intr_type == MSI_X) { | ||
8013 | sp->num_entries = config->rx_ring_num + 1; | ||
8014 | ret = s2io_enable_msi_x(sp); | ||
8015 | |||
8016 | if (!ret) { | ||
8017 | ret = s2io_test_msi(sp); | ||
8018 | /* rollback MSI-X, will re-enable during add_isr() */ | ||
8019 | remove_msix_isr(sp); | ||
8020 | } | ||
8021 | if (ret) { | ||
8022 | |||
8023 | DBG_PRINT(ERR_DBG, | ||
8024 | "%s: MSI-X requested but failed to enable\n", | ||
8025 | dev->name); | ||
8026 | sp->config.intr_type = INTA; | ||
8027 | } | ||
8028 | } | ||
8029 | |||
8030 | if (config->intr_type == MSI_X) { | ||
8031 | for (i = 0; i < config->rx_ring_num ; i++) | ||
8032 | netif_napi_add(dev, &mac_control->rings[i].napi, | ||
8033 | s2io_poll_msix, 64); | ||
8034 | } else { | ||
8035 | netif_napi_add(dev, &sp->napi, s2io_poll_inta, 64); | ||
8036 | } | ||
8037 | |||
7966 | /* Not needed for Herc */ | 8038 | /* Not needed for Herc */ |
7967 | if (sp->device_type & XFRAME_I_DEVICE) { | 8039 | if (sp->device_type & XFRAME_I_DEVICE) { |
7968 | /* | 8040 | /* |
@@ -8013,6 +8085,11 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) | |||
8013 | /* store mac addresses from CAM to s2io_nic structure */ | 8085 | /* store mac addresses from CAM to s2io_nic structure */ |
8014 | do_s2io_store_unicast_mc(sp); | 8086 | do_s2io_store_unicast_mc(sp); |
8015 | 8087 | ||
8088 | /* Configure MSIX vector for number of rings configured plus one */ | ||
8089 | if ((sp->device_type == XFRAME_II_DEVICE) && | ||
8090 | (config->intr_type == MSI_X)) | ||
8091 | sp->num_entries = config->rx_ring_num + 1; | ||
8092 | |||
8016 | /* Store the values of the MSIX table in the s2io_nic structure */ | 8093 | /* Store the values of the MSIX table in the s2io_nic structure */ |
8017 | store_xmsi_data(sp); | 8094 | store_xmsi_data(sp); |
8018 | /* reset Nic and bring it to known state */ | 8095 | /* reset Nic and bring it to known state */ |
@@ -8078,8 +8155,14 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) | |||
8078 | break; | 8155 | break; |
8079 | } | 8156 | } |
8080 | 8157 | ||
8081 | if (napi) | 8158 | switch (sp->config.napi) { |
8159 | case 0: | ||
8160 | DBG_PRINT(ERR_DBG, "%s: NAPI disabled\n", dev->name); | ||
8161 | break; | ||
8162 | case 1: | ||
8082 | DBG_PRINT(ERR_DBG, "%s: NAPI enabled\n", dev->name); | 8163 | DBG_PRINT(ERR_DBG, "%s: NAPI enabled\n", dev->name); |
8164 | break; | ||
8165 | } | ||
8083 | 8166 | ||
8084 | DBG_PRINT(ERR_DBG, "%s: Using %d Tx fifo(s)\n", dev->name, | 8167 | DBG_PRINT(ERR_DBG, "%s: Using %d Tx fifo(s)\n", dev->name, |
8085 | sp->config.tx_fifo_num); | 8168 | sp->config.tx_fifo_num); |
diff --git a/drivers/net/s2io.h b/drivers/net/s2io.h index 0709ebae9139..1827b6686c98 100644 --- a/drivers/net/s2io.h +++ b/drivers/net/s2io.h | |||
@@ -75,10 +75,6 @@ static int debug_level = ERR_DBG; | |||
75 | /* DEBUG message print. */ | 75 | /* DEBUG message print. */ |
76 | #define DBG_PRINT(dbg_level, args...) if(!(debug_level<dbg_level)) printk(args) | 76 | #define DBG_PRINT(dbg_level, args...) if(!(debug_level<dbg_level)) printk(args) |
77 | 77 | ||
78 | #ifndef DMA_ERROR_CODE | ||
79 | #define DMA_ERROR_CODE (~(dma_addr_t)0x0) | ||
80 | #endif | ||
81 | |||
82 | /* Protocol assist features of the NIC */ | 78 | /* Protocol assist features of the NIC */ |
83 | #define L3_CKSUM_OK 0xFFFF | 79 | #define L3_CKSUM_OK 0xFFFF |
84 | #define L4_CKSUM_OK 0xFFFF | 80 | #define L4_CKSUM_OK 0xFFFF |
@@ -706,7 +702,7 @@ struct ring_info { | |||
706 | /* per-ring buffer counter */ | 702 | /* per-ring buffer counter */ |
707 | u32 rx_bufs_left; | 703 | u32 rx_bufs_left; |
708 | 704 | ||
709 | #define MAX_LRO_SESSIONS 32 | 705 | #define MAX_LRO_SESSIONS 32 |
710 | struct lro lro0_n[MAX_LRO_SESSIONS]; | 706 | struct lro lro0_n[MAX_LRO_SESSIONS]; |
711 | u8 lro; | 707 | u8 lro; |
712 | 708 | ||
@@ -725,6 +721,11 @@ struct ring_info { | |||
725 | /* copy of sp->pdev pointer */ | 721 | /* copy of sp->pdev pointer */ |
726 | struct pci_dev *pdev; | 722 | struct pci_dev *pdev; |
727 | 723 | ||
724 | /* Per ring napi struct */ | ||
725 | struct napi_struct napi; | ||
726 | |||
727 | unsigned long interrupt_count; | ||
728 | |||
728 | /* | 729 | /* |
729 | * Place holders for the virtual and physical addresses of | 730 | * Place holders for the virtual and physical addresses of |
730 | * all the Rx Blocks | 731 | * all the Rx Blocks |
@@ -841,7 +842,7 @@ struct usr_addr { | |||
841 | * Structure to keep track of the MSI-X vectors and the corresponding | 842 | * Structure to keep track of the MSI-X vectors and the corresponding |
842 | * argument registered against each vector | 843 | * argument registered against each vector |
843 | */ | 844 | */ |
844 | #define MAX_REQUESTED_MSI_X 17 | 845 | #define MAX_REQUESTED_MSI_X 9 |
845 | struct s2io_msix_entry | 846 | struct s2io_msix_entry |
846 | { | 847 | { |
847 | u16 vector; | 848 | u16 vector; |
@@ -849,8 +850,8 @@ struct s2io_msix_entry | |||
849 | void *arg; | 850 | void *arg; |
850 | 851 | ||
851 | u8 type; | 852 | u8 type; |
852 | #define MSIX_FIFO_TYPE 1 | 853 | #define MSIX_ALARM_TYPE 1 |
853 | #define MSIX_RING_TYPE 2 | 854 | #define MSIX_RING_TYPE 2 |
854 | 855 | ||
855 | u8 in_use; | 856 | u8 in_use; |
856 | #define MSIX_REGISTERED_SUCCESS 0xAA | 857 | #define MSIX_REGISTERED_SUCCESS 0xAA |
@@ -877,7 +878,6 @@ struct s2io_nic { | |||
877 | */ | 878 | */ |
878 | int pkts_to_process; | 879 | int pkts_to_process; |
879 | struct net_device *dev; | 880 | struct net_device *dev; |
880 | struct napi_struct napi; | ||
881 | struct mac_info mac_control; | 881 | struct mac_info mac_control; |
882 | struct config_param config; | 882 | struct config_param config; |
883 | struct pci_dev *pdev; | 883 | struct pci_dev *pdev; |
@@ -948,6 +948,7 @@ struct s2io_nic { | |||
948 | */ | 948 | */ |
949 | u8 other_fifo_idx; | 949 | u8 other_fifo_idx; |
950 | 950 | ||
951 | struct napi_struct napi; | ||
951 | /* after blink, the adapter must be restored with original | 952 | /* after blink, the adapter must be restored with original |
952 | * values. | 953 | * values. |
953 | */ | 954 | */ |
@@ -962,6 +963,7 @@ struct s2io_nic { | |||
962 | unsigned long long start_time; | 963 | unsigned long long start_time; |
963 | struct vlan_group *vlgrp; | 964 | struct vlan_group *vlgrp; |
964 | #define MSIX_FLG 0xA5 | 965 | #define MSIX_FLG 0xA5 |
966 | int num_entries; | ||
965 | struct msix_entry *entries; | 967 | struct msix_entry *entries; |
966 | int msi_detected; | 968 | int msi_detected; |
967 | wait_queue_head_t msi_wait; | 969 | wait_queue_head_t msi_wait; |
@@ -982,6 +984,7 @@ struct s2io_nic { | |||
982 | u16 lro_max_aggr_per_sess; | 984 | u16 lro_max_aggr_per_sess; |
983 | volatile unsigned long state; | 985 | volatile unsigned long state; |
984 | u64 general_int_mask; | 986 | u64 general_int_mask; |
987 | |||
985 | #define VPD_STRING_LEN 80 | 988 | #define VPD_STRING_LEN 80 |
986 | u8 product_name[VPD_STRING_LEN]; | 989 | u8 product_name[VPD_STRING_LEN]; |
987 | u8 serial_num[VPD_STRING_LEN]; | 990 | u8 serial_num[VPD_STRING_LEN]; |
@@ -1103,7 +1106,7 @@ static void __devexit s2io_rem_nic(struct pci_dev *pdev); | |||
1103 | static int init_shared_mem(struct s2io_nic *sp); | 1106 | static int init_shared_mem(struct s2io_nic *sp); |
1104 | static void free_shared_mem(struct s2io_nic *sp); | 1107 | static void free_shared_mem(struct s2io_nic *sp); |
1105 | static int init_nic(struct s2io_nic *nic); | 1108 | static int init_nic(struct s2io_nic *nic); |
1106 | static void rx_intr_handler(struct ring_info *ring_data); | 1109 | static int rx_intr_handler(struct ring_info *ring_data, int budget); |
1107 | static void tx_intr_handler(struct fifo_info *fifo_data); | 1110 | static void tx_intr_handler(struct fifo_info *fifo_data); |
1108 | static void s2io_handle_errors(void * dev_id); | 1111 | static void s2io_handle_errors(void * dev_id); |
1109 | 1112 | ||
@@ -1114,7 +1117,8 @@ static void s2io_set_multicast(struct net_device *dev); | |||
1114 | static int rx_osm_handler(struct ring_info *ring_data, struct RxD_t * rxdp); | 1117 | static int rx_osm_handler(struct ring_info *ring_data, struct RxD_t * rxdp); |
1115 | static void s2io_link(struct s2io_nic * sp, int link); | 1118 | static void s2io_link(struct s2io_nic * sp, int link); |
1116 | static void s2io_reset(struct s2io_nic * sp); | 1119 | static void s2io_reset(struct s2io_nic * sp); |
1117 | static int s2io_poll(struct napi_struct *napi, int budget); | 1120 | static int s2io_poll_msix(struct napi_struct *napi, int budget); |
1121 | static int s2io_poll_inta(struct napi_struct *napi, int budget); | ||
1118 | static void s2io_init_pci(struct s2io_nic * sp); | 1122 | static void s2io_init_pci(struct s2io_nic * sp); |
1119 | static int do_s2io_prog_unicast(struct net_device *dev, u8 *addr); | 1123 | static int do_s2io_prog_unicast(struct net_device *dev, u8 *addr); |
1120 | static void s2io_alarm_handle(unsigned long data); | 1124 | static void s2io_alarm_handle(unsigned long data); |
diff --git a/drivers/net/sb1250-mac.c b/drivers/net/sb1250-mac.c index 888b7dec9866..33bb18f810fb 100644 --- a/drivers/net/sb1250-mac.c +++ b/drivers/net/sb1250-mac.c | |||
@@ -179,8 +179,7 @@ enum sbmac_state { | |||
179 | #define SBMAC_MAX_TXDESCR 256 | 179 | #define SBMAC_MAX_TXDESCR 256 |
180 | #define SBMAC_MAX_RXDESCR 256 | 180 | #define SBMAC_MAX_RXDESCR 256 |
181 | 181 | ||
182 | #define ETHER_ALIGN 2 | 182 | #define ETHER_ADDR_LEN 6 |
183 | #define ETHER_ADDR_LEN 6 | ||
184 | #define ENET_PACKET_SIZE 1518 | 183 | #define ENET_PACKET_SIZE 1518 |
185 | /*#define ENET_PACKET_SIZE 9216 */ | 184 | /*#define ENET_PACKET_SIZE 9216 */ |
186 | 185 | ||
@@ -262,8 +261,6 @@ struct sbmac_softc { | |||
262 | spinlock_t sbm_lock; /* spin lock */ | 261 | spinlock_t sbm_lock; /* spin lock */ |
263 | int sbm_devflags; /* current device flags */ | 262 | int sbm_devflags; /* current device flags */ |
264 | 263 | ||
265 | int sbm_buffersize; | ||
266 | |||
267 | /* | 264 | /* |
268 | * Controller-specific things | 265 | * Controller-specific things |
269 | */ | 266 | */ |
@@ -305,10 +302,11 @@ struct sbmac_softc { | |||
305 | static void sbdma_initctx(struct sbmacdma *d, struct sbmac_softc *s, int chan, | 302 | static void sbdma_initctx(struct sbmacdma *d, struct sbmac_softc *s, int chan, |
306 | int txrx, int maxdescr); | 303 | int txrx, int maxdescr); |
307 | static void sbdma_channel_start(struct sbmacdma *d, int rxtx); | 304 | static void sbdma_channel_start(struct sbmacdma *d, int rxtx); |
308 | static int sbdma_add_rcvbuffer(struct sbmacdma *d, struct sk_buff *m); | 305 | static int sbdma_add_rcvbuffer(struct sbmac_softc *sc, struct sbmacdma *d, |
306 | struct sk_buff *m); | ||
309 | static int sbdma_add_txbuffer(struct sbmacdma *d, struct sk_buff *m); | 307 | static int sbdma_add_txbuffer(struct sbmacdma *d, struct sk_buff *m); |
310 | static void sbdma_emptyring(struct sbmacdma *d); | 308 | static void sbdma_emptyring(struct sbmacdma *d); |
311 | static void sbdma_fillring(struct sbmacdma *d); | 309 | static void sbdma_fillring(struct sbmac_softc *sc, struct sbmacdma *d); |
312 | static int sbdma_rx_process(struct sbmac_softc *sc, struct sbmacdma *d, | 310 | static int sbdma_rx_process(struct sbmac_softc *sc, struct sbmacdma *d, |
313 | int work_to_do, int poll); | 311 | int work_to_do, int poll); |
314 | static void sbdma_tx_process(struct sbmac_softc *sc, struct sbmacdma *d, | 312 | static void sbdma_tx_process(struct sbmac_softc *sc, struct sbmacdma *d, |
@@ -777,16 +775,13 @@ static void sbdma_channel_stop(struct sbmacdma *d) | |||
777 | d->sbdma_remptr = NULL; | 775 | d->sbdma_remptr = NULL; |
778 | } | 776 | } |
779 | 777 | ||
780 | static void sbdma_align_skb(struct sk_buff *skb,int power2,int offset) | 778 | static inline void sbdma_align_skb(struct sk_buff *skb, |
779 | unsigned int power2, unsigned int offset) | ||
781 | { | 780 | { |
782 | unsigned long addr; | 781 | unsigned char *addr = skb->data; |
783 | unsigned long newaddr; | 782 | unsigned char *newaddr = PTR_ALIGN(addr, power2); |
784 | |||
785 | addr = (unsigned long) skb->data; | ||
786 | |||
787 | newaddr = (addr + power2 - 1) & ~(power2 - 1); | ||
788 | 783 | ||
789 | skb_reserve(skb,newaddr-addr+offset); | 784 | skb_reserve(skb, newaddr - addr + offset); |
790 | } | 785 | } |
791 | 786 | ||
792 | 787 | ||
@@ -797,7 +792,8 @@ static void sbdma_align_skb(struct sk_buff *skb,int power2,int offset) | |||
797 | * this queues a buffer for inbound packets. | 792 | * this queues a buffer for inbound packets. |
798 | * | 793 | * |
799 | * Input parameters: | 794 | * Input parameters: |
800 | * d - DMA channel descriptor | 795 | * sc - softc structure |
796 | * d - DMA channel descriptor | ||
801 | * sb - sk_buff to add, or NULL if we should allocate one | 797 | * sb - sk_buff to add, or NULL if we should allocate one |
802 | * | 798 | * |
803 | * Return value: | 799 | * Return value: |
@@ -806,8 +802,10 @@ static void sbdma_align_skb(struct sk_buff *skb,int power2,int offset) | |||
806 | ********************************************************************* */ | 802 | ********************************************************************* */ |
807 | 803 | ||
808 | 804 | ||
809 | static int sbdma_add_rcvbuffer(struct sbmacdma *d, struct sk_buff *sb) | 805 | static int sbdma_add_rcvbuffer(struct sbmac_softc *sc, struct sbmacdma *d, |
806 | struct sk_buff *sb) | ||
810 | { | 807 | { |
808 | struct net_device *dev = sc->sbm_dev; | ||
811 | struct sbdmadscr *dsc; | 809 | struct sbdmadscr *dsc; |
812 | struct sbdmadscr *nextdsc; | 810 | struct sbdmadscr *nextdsc; |
813 | struct sk_buff *sb_new = NULL; | 811 | struct sk_buff *sb_new = NULL; |
@@ -848,14 +846,16 @@ static int sbdma_add_rcvbuffer(struct sbmacdma *d, struct sk_buff *sb) | |||
848 | */ | 846 | */ |
849 | 847 | ||
850 | if (sb == NULL) { | 848 | if (sb == NULL) { |
851 | sb_new = dev_alloc_skb(ENET_PACKET_SIZE + SMP_CACHE_BYTES * 2 + ETHER_ALIGN); | 849 | sb_new = netdev_alloc_skb(dev, ENET_PACKET_SIZE + |
850 | SMP_CACHE_BYTES * 2 + | ||
851 | NET_IP_ALIGN); | ||
852 | if (sb_new == NULL) { | 852 | if (sb_new == NULL) { |
853 | pr_info("%s: sk_buff allocation failed\n", | 853 | pr_info("%s: sk_buff allocation failed\n", |
854 | d->sbdma_eth->sbm_dev->name); | 854 | d->sbdma_eth->sbm_dev->name); |
855 | return -ENOBUFS; | 855 | return -ENOBUFS; |
856 | } | 856 | } |
857 | 857 | ||
858 | sbdma_align_skb(sb_new, SMP_CACHE_BYTES, ETHER_ALIGN); | 858 | sbdma_align_skb(sb_new, SMP_CACHE_BYTES, NET_IP_ALIGN); |
859 | } | 859 | } |
860 | else { | 860 | else { |
861 | sb_new = sb; | 861 | sb_new = sb; |
@@ -874,10 +874,10 @@ static int sbdma_add_rcvbuffer(struct sbmacdma *d, struct sk_buff *sb) | |||
874 | * Do not interrupt per DMA transfer. | 874 | * Do not interrupt per DMA transfer. |
875 | */ | 875 | */ |
876 | dsc->dscr_a = virt_to_phys(sb_new->data) | | 876 | dsc->dscr_a = virt_to_phys(sb_new->data) | |
877 | V_DMA_DSCRA_A_SIZE(NUMCACHEBLKS(pktsize+ETHER_ALIGN)) | 0; | 877 | V_DMA_DSCRA_A_SIZE(NUMCACHEBLKS(pktsize + NET_IP_ALIGN)) | 0; |
878 | #else | 878 | #else |
879 | dsc->dscr_a = virt_to_phys(sb_new->data) | | 879 | dsc->dscr_a = virt_to_phys(sb_new->data) | |
880 | V_DMA_DSCRA_A_SIZE(NUMCACHEBLKS(pktsize+ETHER_ALIGN)) | | 880 | V_DMA_DSCRA_A_SIZE(NUMCACHEBLKS(pktsize + NET_IP_ALIGN)) | |
881 | M_DMA_DSCRA_INTERRUPT; | 881 | M_DMA_DSCRA_INTERRUPT; |
882 | #endif | 882 | #endif |
883 | 883 | ||
@@ -1032,18 +1032,19 @@ static void sbdma_emptyring(struct sbmacdma *d) | |||
1032 | * with sk_buffs | 1032 | * with sk_buffs |
1033 | * | 1033 | * |
1034 | * Input parameters: | 1034 | * Input parameters: |
1035 | * d - DMA channel | 1035 | * sc - softc structure |
1036 | * d - DMA channel | ||
1036 | * | 1037 | * |
1037 | * Return value: | 1038 | * Return value: |
1038 | * nothing | 1039 | * nothing |
1039 | ********************************************************************* */ | 1040 | ********************************************************************* */ |
1040 | 1041 | ||
1041 | static void sbdma_fillring(struct sbmacdma *d) | 1042 | static void sbdma_fillring(struct sbmac_softc *sc, struct sbmacdma *d) |
1042 | { | 1043 | { |
1043 | int idx; | 1044 | int idx; |
1044 | 1045 | ||
1045 | for (idx = 0; idx < SBMAC_MAX_RXDESCR-1; idx++) { | 1046 | for (idx = 0; idx < SBMAC_MAX_RXDESCR - 1; idx++) { |
1046 | if (sbdma_add_rcvbuffer(d,NULL) != 0) | 1047 | if (sbdma_add_rcvbuffer(sc, d, NULL) != 0) |
1047 | break; | 1048 | break; |
1048 | } | 1049 | } |
1049 | } | 1050 | } |
@@ -1159,10 +1160,11 @@ again: | |||
1159 | * packet and put it right back on the receive ring. | 1160 | * packet and put it right back on the receive ring. |
1160 | */ | 1161 | */ |
1161 | 1162 | ||
1162 | if (unlikely (sbdma_add_rcvbuffer(d,NULL) == | 1163 | if (unlikely(sbdma_add_rcvbuffer(sc, d, NULL) == |
1163 | -ENOBUFS)) { | 1164 | -ENOBUFS)) { |
1164 | dev->stats.rx_dropped++; | 1165 | dev->stats.rx_dropped++; |
1165 | sbdma_add_rcvbuffer(d,sb); /* re-add old buffer */ | 1166 | /* Re-add old buffer */ |
1167 | sbdma_add_rcvbuffer(sc, d, sb); | ||
1166 | /* No point in continuing at the moment */ | 1168 | /* No point in continuing at the moment */ |
1167 | printk(KERN_ERR "dropped packet (1)\n"); | 1169 | printk(KERN_ERR "dropped packet (1)\n"); |
1168 | d->sbdma_remptr = SBDMA_NEXTBUF(d,sbdma_remptr); | 1170 | d->sbdma_remptr = SBDMA_NEXTBUF(d,sbdma_remptr); |
@@ -1212,7 +1214,7 @@ again: | |||
1212 | * put it back on the receive ring. | 1214 | * put it back on the receive ring. |
1213 | */ | 1215 | */ |
1214 | dev->stats.rx_errors++; | 1216 | dev->stats.rx_errors++; |
1215 | sbdma_add_rcvbuffer(d,sb); | 1217 | sbdma_add_rcvbuffer(sc, d, sb); |
1216 | } | 1218 | } |
1217 | 1219 | ||
1218 | 1220 | ||
@@ -1570,7 +1572,7 @@ static void sbmac_channel_start(struct sbmac_softc *s) | |||
1570 | * Fill the receive ring | 1572 | * Fill the receive ring |
1571 | */ | 1573 | */ |
1572 | 1574 | ||
1573 | sbdma_fillring(&(s->sbm_rxdma)); | 1575 | sbdma_fillring(s, &(s->sbm_rxdma)); |
1574 | 1576 | ||
1575 | /* | 1577 | /* |
1576 | * Turn on the rest of the bits in the enable register | 1578 | * Turn on the rest of the bits in the enable register |
@@ -2312,13 +2314,6 @@ static int sbmac_init(struct platform_device *pldev, long long base) | |||
2312 | dev->dev_addr[i] = eaddr[i]; | 2314 | dev->dev_addr[i] = eaddr[i]; |
2313 | } | 2315 | } |
2314 | 2316 | ||
2315 | |||
2316 | /* | ||
2317 | * Init packet size | ||
2318 | */ | ||
2319 | |||
2320 | sc->sbm_buffersize = ENET_PACKET_SIZE + SMP_CACHE_BYTES * 2 + ETHER_ALIGN; | ||
2321 | |||
2322 | /* | 2317 | /* |
2323 | * Initialize context (get pointers to registers and stuff), then | 2318 | * Initialize context (get pointers to registers and stuff), then |
2324 | * allocate the memory for the descriptor tables. | 2319 | * allocate the memory for the descriptor tables. |
diff --git a/drivers/net/sc92031.c b/drivers/net/sc92031.c index f64a860029b7..61955f8d8011 100644 --- a/drivers/net/sc92031.c +++ b/drivers/net/sc92031.c | |||
@@ -953,9 +953,6 @@ static int sc92031_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
953 | unsigned entry; | 953 | unsigned entry; |
954 | u32 tx_status; | 954 | u32 tx_status; |
955 | 955 | ||
956 | if (skb_padto(skb, ETH_ZLEN)) | ||
957 | return NETDEV_TX_OK; | ||
958 | |||
959 | if (unlikely(skb->len > TX_BUF_SIZE)) { | 956 | if (unlikely(skb->len > TX_BUF_SIZE)) { |
960 | dev->stats.tx_dropped++; | 957 | dev->stats.tx_dropped++; |
961 | goto out; | 958 | goto out; |
@@ -975,6 +972,11 @@ static int sc92031_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
975 | skb_copy_and_csum_dev(skb, priv->tx_bufs + entry * TX_BUF_SIZE); | 972 | skb_copy_and_csum_dev(skb, priv->tx_bufs + entry * TX_BUF_SIZE); |
976 | 973 | ||
977 | len = skb->len; | 974 | len = skb->len; |
975 | if (len < ETH_ZLEN) { | ||
976 | memset(priv->tx_bufs + entry * TX_BUF_SIZE + len, | ||
977 | 0, ETH_ZLEN - len); | ||
978 | len = ETH_ZLEN; | ||
979 | } | ||
978 | 980 | ||
979 | wmb(); | 981 | wmb(); |
980 | 982 | ||
diff --git a/drivers/net/sfc/Makefile b/drivers/net/sfc/Makefile index 0f023447eafd..1d2daeec7ac1 100644 --- a/drivers/net/sfc/Makefile +++ b/drivers/net/sfc/Makefile | |||
@@ -1,5 +1,5 @@ | |||
1 | sfc-y += efx.o falcon.o tx.o rx.o falcon_xmac.o \ | 1 | sfc-y += efx.o falcon.o tx.o rx.o falcon_xmac.o \ |
2 | i2c-direct.o ethtool.o xfp_phy.o mdio_10g.o \ | 2 | i2c-direct.o selftest.o ethtool.o xfp_phy.o \ |
3 | tenxpress.o boards.o sfe4001.o | 3 | mdio_10g.o tenxpress.o boards.o sfe4001.o |
4 | 4 | ||
5 | obj-$(CONFIG_SFC) += sfc.o | 5 | obj-$(CONFIG_SFC) += sfc.o |
diff --git a/drivers/net/sfc/bitfield.h b/drivers/net/sfc/bitfield.h index 2806201644cc..2c79d27404e0 100644 --- a/drivers/net/sfc/bitfield.h +++ b/drivers/net/sfc/bitfield.h | |||
@@ -483,7 +483,7 @@ typedef union efx_oword { | |||
483 | #endif | 483 | #endif |
484 | 484 | ||
485 | #define EFX_SET_OWORD_FIELD_VER(efx, oword, field, value) do { \ | 485 | #define EFX_SET_OWORD_FIELD_VER(efx, oword, field, value) do { \ |
486 | if (FALCON_REV(efx) >= FALCON_REV_B0) { \ | 486 | if (falcon_rev(efx) >= FALCON_REV_B0) { \ |
487 | EFX_SET_OWORD_FIELD((oword), field##_B0, (value)); \ | 487 | EFX_SET_OWORD_FIELD((oword), field##_B0, (value)); \ |
488 | } else { \ | 488 | } else { \ |
489 | EFX_SET_OWORD_FIELD((oword), field##_A1, (value)); \ | 489 | EFX_SET_OWORD_FIELD((oword), field##_A1, (value)); \ |
@@ -491,7 +491,7 @@ typedef union efx_oword { | |||
491 | } while (0) | 491 | } while (0) |
492 | 492 | ||
493 | #define EFX_QWORD_FIELD_VER(efx, qword, field) \ | 493 | #define EFX_QWORD_FIELD_VER(efx, qword, field) \ |
494 | (FALCON_REV(efx) >= FALCON_REV_B0 ? \ | 494 | (falcon_rev(efx) >= FALCON_REV_B0 ? \ |
495 | EFX_QWORD_FIELD((qword), field##_B0) : \ | 495 | EFX_QWORD_FIELD((qword), field##_B0) : \ |
496 | EFX_QWORD_FIELD((qword), field##_A1)) | 496 | EFX_QWORD_FIELD((qword), field##_A1)) |
497 | 497 | ||
@@ -501,8 +501,5 @@ typedef union efx_oword { | |||
501 | #define DMA_ADDR_T_WIDTH (8 * sizeof(dma_addr_t)) | 501 | #define DMA_ADDR_T_WIDTH (8 * sizeof(dma_addr_t)) |
502 | #define EFX_DMA_TYPE_WIDTH(width) \ | 502 | #define EFX_DMA_TYPE_WIDTH(width) \ |
503 | (((width) < DMA_ADDR_T_WIDTH) ? (width) : DMA_ADDR_T_WIDTH) | 503 | (((width) < DMA_ADDR_T_WIDTH) ? (width) : DMA_ADDR_T_WIDTH) |
504 | #define EFX_DMA_MAX_MASK ((DMA_ADDR_T_WIDTH == 64) ? \ | ||
505 | ~((u64) 0) : ~((u32) 0)) | ||
506 | #define EFX_DMA_MASK(mask) ((mask) & EFX_DMA_MAX_MASK) | ||
507 | 504 | ||
508 | #endif /* EFX_BITFIELD_H */ | 505 | #endif /* EFX_BITFIELD_H */ |
diff --git a/drivers/net/sfc/boards.c b/drivers/net/sfc/boards.c index eecaa6d58584..7fc0328dc055 100644 --- a/drivers/net/sfc/boards.c +++ b/drivers/net/sfc/boards.c | |||
@@ -27,10 +27,8 @@ static void blink_led_timer(unsigned long context) | |||
27 | struct efx_blinker *bl = &efx->board_info.blinker; | 27 | struct efx_blinker *bl = &efx->board_info.blinker; |
28 | efx->board_info.set_fault_led(efx, bl->state); | 28 | efx->board_info.set_fault_led(efx, bl->state); |
29 | bl->state = !bl->state; | 29 | bl->state = !bl->state; |
30 | if (bl->resubmit) { | 30 | if (bl->resubmit) |
31 | bl->timer.expires = jiffies + BLINK_INTERVAL; | 31 | mod_timer(&bl->timer, jiffies + BLINK_INTERVAL); |
32 | add_timer(&bl->timer); | ||
33 | } | ||
34 | } | 32 | } |
35 | 33 | ||
36 | static void board_blink(struct efx_nic *efx, int blink) | 34 | static void board_blink(struct efx_nic *efx, int blink) |
@@ -44,8 +42,7 @@ static void board_blink(struct efx_nic *efx, int blink) | |||
44 | blinker->state = 0; | 42 | blinker->state = 0; |
45 | setup_timer(&blinker->timer, blink_led_timer, | 43 | setup_timer(&blinker->timer, blink_led_timer, |
46 | (unsigned long)efx); | 44 | (unsigned long)efx); |
47 | blinker->timer.expires = jiffies + BLINK_INTERVAL; | 45 | mod_timer(&blinker->timer, jiffies + BLINK_INTERVAL); |
48 | add_timer(&blinker->timer); | ||
49 | } else { | 46 | } else { |
50 | blinker->resubmit = 0; | 47 | blinker->resubmit = 0; |
51 | if (blinker->timer.function) | 48 | if (blinker->timer.function) |
diff --git a/drivers/net/sfc/boards.h b/drivers/net/sfc/boards.h index f56341d428e1..695764dc2e64 100644 --- a/drivers/net/sfc/boards.h +++ b/drivers/net/sfc/boards.h | |||
@@ -22,5 +22,7 @@ enum efx_board_type { | |||
22 | extern int efx_set_board_info(struct efx_nic *efx, u16 revision_info); | 22 | extern int efx_set_board_info(struct efx_nic *efx, u16 revision_info); |
23 | extern int sfe4001_poweron(struct efx_nic *efx); | 23 | extern int sfe4001_poweron(struct efx_nic *efx); |
24 | extern void sfe4001_poweroff(struct efx_nic *efx); | 24 | extern void sfe4001_poweroff(struct efx_nic *efx); |
25 | /* Are we putting the PHY into flash config mode */ | ||
26 | extern unsigned int sfe4001_phy_flash_cfg; | ||
25 | 27 | ||
26 | #endif | 28 | #endif |
diff --git a/drivers/net/sfc/efx.c b/drivers/net/sfc/efx.c index 59edcf793c19..449760642e31 100644 --- a/drivers/net/sfc/efx.c +++ b/drivers/net/sfc/efx.c | |||
@@ -199,11 +199,12 @@ static inline int efx_process_channel(struct efx_channel *channel, int rx_quota) | |||
199 | */ | 199 | */ |
200 | static inline void efx_channel_processed(struct efx_channel *channel) | 200 | static inline void efx_channel_processed(struct efx_channel *channel) |
201 | { | 201 | { |
202 | /* Write to EVQ_RPTR_REG. If a new event arrived in a race | 202 | /* The interrupt handler for this channel may set work_pending |
203 | * with finishing processing, a new interrupt will be raised. | 203 | * as soon as we acknowledge the events we've seen. Make sure |
204 | */ | 204 | * it's cleared before then. */ |
205 | channel->work_pending = 0; | 205 | channel->work_pending = 0; |
206 | smp_wmb(); /* Ensure channel updated before any new interrupt. */ | 206 | smp_wmb(); |
207 | |||
207 | falcon_eventq_read_ack(channel); | 208 | falcon_eventq_read_ack(channel); |
208 | } | 209 | } |
209 | 210 | ||
@@ -265,7 +266,7 @@ void efx_process_channel_now(struct efx_channel *channel) | |||
265 | napi_disable(&channel->napi_str); | 266 | napi_disable(&channel->napi_str); |
266 | 267 | ||
267 | /* Poll the channel */ | 268 | /* Poll the channel */ |
268 | (void) efx_process_channel(channel, efx->type->evq_size); | 269 | efx_process_channel(channel, efx->type->evq_size); |
269 | 270 | ||
270 | /* Ack the eventq. This may cause an interrupt to be generated | 271 | /* Ack the eventq. This may cause an interrupt to be generated |
271 | * when they are reenabled */ | 272 | * when they are reenabled */ |
@@ -317,26 +318,6 @@ static void efx_remove_eventq(struct efx_channel *channel) | |||
317 | * | 318 | * |
318 | *************************************************************************/ | 319 | *************************************************************************/ |
319 | 320 | ||
320 | /* Setup per-NIC RX buffer parameters. | ||
321 | * Calculate the rx buffer allocation parameters required to support | ||
322 | * the current MTU, including padding for header alignment and overruns. | ||
323 | */ | ||
324 | static void efx_calc_rx_buffer_params(struct efx_nic *efx) | ||
325 | { | ||
326 | unsigned int order, len; | ||
327 | |||
328 | len = (max(EFX_PAGE_IP_ALIGN, NET_IP_ALIGN) + | ||
329 | EFX_MAX_FRAME_LEN(efx->net_dev->mtu) + | ||
330 | efx->type->rx_buffer_padding); | ||
331 | |||
332 | /* Calculate page-order */ | ||
333 | for (order = 0; ((1u << order) * PAGE_SIZE) < len; ++order) | ||
334 | ; | ||
335 | |||
336 | efx->rx_buffer_len = len; | ||
337 | efx->rx_buffer_order = order; | ||
338 | } | ||
339 | |||
340 | static int efx_probe_channel(struct efx_channel *channel) | 321 | static int efx_probe_channel(struct efx_channel *channel) |
341 | { | 322 | { |
342 | struct efx_tx_queue *tx_queue; | 323 | struct efx_tx_queue *tx_queue; |
@@ -387,7 +368,14 @@ static int efx_init_channels(struct efx_nic *efx) | |||
387 | struct efx_channel *channel; | 368 | struct efx_channel *channel; |
388 | int rc = 0; | 369 | int rc = 0; |
389 | 370 | ||
390 | efx_calc_rx_buffer_params(efx); | 371 | /* Calculate the rx buffer allocation parameters required to |
372 | * support the current MTU, including padding for header | ||
373 | * alignment and overruns. | ||
374 | */ | ||
375 | efx->rx_buffer_len = (max(EFX_PAGE_IP_ALIGN, NET_IP_ALIGN) + | ||
376 | EFX_MAX_FRAME_LEN(efx->net_dev->mtu) + | ||
377 | efx->type->rx_buffer_padding); | ||
378 | efx->rx_buffer_order = get_order(efx->rx_buffer_len); | ||
391 | 379 | ||
392 | /* Initialise the channels */ | 380 | /* Initialise the channels */ |
393 | efx_for_each_channel(channel, efx) { | 381 | efx_for_each_channel(channel, efx) { |
@@ -440,9 +428,12 @@ static void efx_start_channel(struct efx_channel *channel) | |||
440 | netif_napi_add(channel->napi_dev, &channel->napi_str, | 428 | netif_napi_add(channel->napi_dev, &channel->napi_str, |
441 | efx_poll, napi_weight); | 429 | efx_poll, napi_weight); |
442 | 430 | ||
431 | /* The interrupt handler for this channel may set work_pending | ||
432 | * as soon as we enable it. Make sure it's cleared before | ||
433 | * then. Similarly, make sure it sees the enabled flag set. */ | ||
443 | channel->work_pending = 0; | 434 | channel->work_pending = 0; |
444 | channel->enabled = 1; | 435 | channel->enabled = 1; |
445 | smp_wmb(); /* ensure channel updated before first interrupt */ | 436 | smp_wmb(); |
446 | 437 | ||
447 | napi_enable(&channel->napi_str); | 438 | napi_enable(&channel->napi_str); |
448 | 439 | ||
@@ -704,7 +695,7 @@ static void efx_stop_port(struct efx_nic *efx) | |||
704 | mutex_unlock(&efx->mac_lock); | 695 | mutex_unlock(&efx->mac_lock); |
705 | 696 | ||
706 | /* Serialise against efx_set_multicast_list() */ | 697 | /* Serialise against efx_set_multicast_list() */ |
707 | if (NET_DEV_REGISTERED(efx)) { | 698 | if (efx_dev_registered(efx)) { |
708 | netif_tx_lock_bh(efx->net_dev); | 699 | netif_tx_lock_bh(efx->net_dev); |
709 | netif_tx_unlock_bh(efx->net_dev); | 700 | netif_tx_unlock_bh(efx->net_dev); |
710 | } | 701 | } |
@@ -791,22 +782,23 @@ static int efx_init_io(struct efx_nic *efx) | |||
791 | efx->membase = ioremap_nocache(efx->membase_phys, | 782 | efx->membase = ioremap_nocache(efx->membase_phys, |
792 | efx->type->mem_map_size); | 783 | efx->type->mem_map_size); |
793 | if (!efx->membase) { | 784 | if (!efx->membase) { |
794 | EFX_ERR(efx, "could not map memory BAR %d at %lx+%x\n", | 785 | EFX_ERR(efx, "could not map memory BAR %d at %llx+%x\n", |
795 | efx->type->mem_bar, efx->membase_phys, | 786 | efx->type->mem_bar, |
787 | (unsigned long long)efx->membase_phys, | ||
796 | efx->type->mem_map_size); | 788 | efx->type->mem_map_size); |
797 | rc = -ENOMEM; | 789 | rc = -ENOMEM; |
798 | goto fail4; | 790 | goto fail4; |
799 | } | 791 | } |
800 | EFX_LOG(efx, "memory BAR %u at %lx+%x (virtual %p)\n", | 792 | EFX_LOG(efx, "memory BAR %u at %llx+%x (virtual %p)\n", |
801 | efx->type->mem_bar, efx->membase_phys, efx->type->mem_map_size, | 793 | efx->type->mem_bar, (unsigned long long)efx->membase_phys, |
802 | efx->membase); | 794 | efx->type->mem_map_size, efx->membase); |
803 | 795 | ||
804 | return 0; | 796 | return 0; |
805 | 797 | ||
806 | fail4: | 798 | fail4: |
807 | release_mem_region(efx->membase_phys, efx->type->mem_map_size); | 799 | release_mem_region(efx->membase_phys, efx->type->mem_map_size); |
808 | fail3: | 800 | fail3: |
809 | efx->membase_phys = 0UL; | 801 | efx->membase_phys = 0; |
810 | fail2: | 802 | fail2: |
811 | pci_disable_device(efx->pci_dev); | 803 | pci_disable_device(efx->pci_dev); |
812 | fail1: | 804 | fail1: |
@@ -824,7 +816,7 @@ static void efx_fini_io(struct efx_nic *efx) | |||
824 | 816 | ||
825 | if (efx->membase_phys) { | 817 | if (efx->membase_phys) { |
826 | pci_release_region(efx->pci_dev, efx->type->mem_bar); | 818 | pci_release_region(efx->pci_dev, efx->type->mem_bar); |
827 | efx->membase_phys = 0UL; | 819 | efx->membase_phys = 0; |
828 | } | 820 | } |
829 | 821 | ||
830 | pci_disable_device(efx->pci_dev); | 822 | pci_disable_device(efx->pci_dev); |
@@ -1043,7 +1035,7 @@ static void efx_start_all(struct efx_nic *efx) | |||
1043 | return; | 1035 | return; |
1044 | if ((efx->state != STATE_RUNNING) && (efx->state != STATE_INIT)) | 1036 | if ((efx->state != STATE_RUNNING) && (efx->state != STATE_INIT)) |
1045 | return; | 1037 | return; |
1046 | if (NET_DEV_REGISTERED(efx) && !netif_running(efx->net_dev)) | 1038 | if (efx_dev_registered(efx) && !netif_running(efx->net_dev)) |
1047 | return; | 1039 | return; |
1048 | 1040 | ||
1049 | /* Mark the port as enabled so port reconfigurations can start, then | 1041 | /* Mark the port as enabled so port reconfigurations can start, then |
@@ -1073,9 +1065,8 @@ static void efx_flush_all(struct efx_nic *efx) | |||
1073 | cancel_delayed_work_sync(&efx->monitor_work); | 1065 | cancel_delayed_work_sync(&efx->monitor_work); |
1074 | 1066 | ||
1075 | /* Ensure that all RX slow refills are complete. */ | 1067 | /* Ensure that all RX slow refills are complete. */ |
1076 | efx_for_each_rx_queue(rx_queue, efx) { | 1068 | efx_for_each_rx_queue(rx_queue, efx) |
1077 | cancel_delayed_work_sync(&rx_queue->work); | 1069 | cancel_delayed_work_sync(&rx_queue->work); |
1078 | } | ||
1079 | 1070 | ||
1080 | /* Stop scheduled port reconfigurations */ | 1071 | /* Stop scheduled port reconfigurations */ |
1081 | cancel_work_sync(&efx->reconfigure_work); | 1072 | cancel_work_sync(&efx->reconfigure_work); |
@@ -1101,9 +1092,10 @@ static void efx_stop_all(struct efx_nic *efx) | |||
1101 | falcon_disable_interrupts(efx); | 1092 | falcon_disable_interrupts(efx); |
1102 | if (efx->legacy_irq) | 1093 | if (efx->legacy_irq) |
1103 | synchronize_irq(efx->legacy_irq); | 1094 | synchronize_irq(efx->legacy_irq); |
1104 | efx_for_each_channel_with_interrupt(channel, efx) | 1095 | efx_for_each_channel_with_interrupt(channel, efx) { |
1105 | if (channel->irq) | 1096 | if (channel->irq) |
1106 | synchronize_irq(channel->irq); | 1097 | synchronize_irq(channel->irq); |
1098 | } | ||
1107 | 1099 | ||
1108 | /* Stop all NAPI processing and synchronous rx refills */ | 1100 | /* Stop all NAPI processing and synchronous rx refills */ |
1109 | efx_for_each_channel(channel, efx) | 1101 | efx_for_each_channel(channel, efx) |
@@ -1125,7 +1117,7 @@ static void efx_stop_all(struct efx_nic *efx) | |||
1125 | /* Stop the kernel transmit interface late, so the watchdog | 1117 | /* Stop the kernel transmit interface late, so the watchdog |
1126 | * timer isn't ticking over the flush */ | 1118 | * timer isn't ticking over the flush */ |
1127 | efx_stop_queue(efx); | 1119 | efx_stop_queue(efx); |
1128 | if (NET_DEV_REGISTERED(efx)) { | 1120 | if (efx_dev_registered(efx)) { |
1129 | netif_tx_lock_bh(efx->net_dev); | 1121 | netif_tx_lock_bh(efx->net_dev); |
1130 | netif_tx_unlock_bh(efx->net_dev); | 1122 | netif_tx_unlock_bh(efx->net_dev); |
1131 | } | 1123 | } |
@@ -1344,13 +1336,17 @@ static int efx_net_stop(struct net_device *net_dev) | |||
1344 | return 0; | 1336 | return 0; |
1345 | } | 1337 | } |
1346 | 1338 | ||
1347 | /* Context: process, dev_base_lock held, non-blocking. */ | 1339 | /* Context: process, dev_base_lock or RTNL held, non-blocking. */ |
1348 | static struct net_device_stats *efx_net_stats(struct net_device *net_dev) | 1340 | static struct net_device_stats *efx_net_stats(struct net_device *net_dev) |
1349 | { | 1341 | { |
1350 | struct efx_nic *efx = net_dev->priv; | 1342 | struct efx_nic *efx = net_dev->priv; |
1351 | struct efx_mac_stats *mac_stats = &efx->mac_stats; | 1343 | struct efx_mac_stats *mac_stats = &efx->mac_stats; |
1352 | struct net_device_stats *stats = &net_dev->stats; | 1344 | struct net_device_stats *stats = &net_dev->stats; |
1353 | 1345 | ||
1346 | /* Update stats if possible, but do not wait if another thread | ||
1347 | * is updating them (or resetting the NIC); slightly stale | ||
1348 | * stats are acceptable. | ||
1349 | */ | ||
1354 | if (!spin_trylock(&efx->stats_lock)) | 1350 | if (!spin_trylock(&efx->stats_lock)) |
1355 | return stats; | 1351 | return stats; |
1356 | if (efx->state == STATE_RUNNING) { | 1352 | if (efx->state == STATE_RUNNING) { |
@@ -1494,7 +1490,7 @@ static void efx_set_multicast_list(struct net_device *net_dev) | |||
1494 | static int efx_netdev_event(struct notifier_block *this, | 1490 | static int efx_netdev_event(struct notifier_block *this, |
1495 | unsigned long event, void *ptr) | 1491 | unsigned long event, void *ptr) |
1496 | { | 1492 | { |
1497 | struct net_device *net_dev = (struct net_device *)ptr; | 1493 | struct net_device *net_dev = ptr; |
1498 | 1494 | ||
1499 | if (net_dev->open == efx_net_open && event == NETDEV_CHANGENAME) { | 1495 | if (net_dev->open == efx_net_open && event == NETDEV_CHANGENAME) { |
1500 | struct efx_nic *efx = net_dev->priv; | 1496 | struct efx_nic *efx = net_dev->priv; |
@@ -1563,7 +1559,7 @@ static void efx_unregister_netdev(struct efx_nic *efx) | |||
1563 | efx_for_each_tx_queue(tx_queue, efx) | 1559 | efx_for_each_tx_queue(tx_queue, efx) |
1564 | efx_release_tx_buffers(tx_queue); | 1560 | efx_release_tx_buffers(tx_queue); |
1565 | 1561 | ||
1566 | if (NET_DEV_REGISTERED(efx)) { | 1562 | if (efx_dev_registered(efx)) { |
1567 | strlcpy(efx->name, pci_name(efx->pci_dev), sizeof(efx->name)); | 1563 | strlcpy(efx->name, pci_name(efx->pci_dev), sizeof(efx->name)); |
1568 | unregister_netdev(efx->net_dev); | 1564 | unregister_netdev(efx->net_dev); |
1569 | } | 1565 | } |
@@ -1688,7 +1684,7 @@ static int efx_reset(struct efx_nic *efx) | |||
1688 | if (method == RESET_TYPE_DISABLE) { | 1684 | if (method == RESET_TYPE_DISABLE) { |
1689 | /* Reinitialise the device anyway so the driver unload sequence | 1685 | /* Reinitialise the device anyway so the driver unload sequence |
1690 | * can talk to the external SRAM */ | 1686 | * can talk to the external SRAM */ |
1691 | (void) falcon_init_nic(efx); | 1687 | falcon_init_nic(efx); |
1692 | rc = -EIO; | 1688 | rc = -EIO; |
1693 | goto fail4; | 1689 | goto fail4; |
1694 | } | 1690 | } |
@@ -1873,6 +1869,7 @@ static int efx_init_struct(struct efx_nic *efx, struct efx_nic_type *type, | |||
1873 | tx_queue->queue = i; | 1869 | tx_queue->queue = i; |
1874 | tx_queue->buffer = NULL; | 1870 | tx_queue->buffer = NULL; |
1875 | tx_queue->channel = &efx->channel[0]; /* for safety */ | 1871 | tx_queue->channel = &efx->channel[0]; /* for safety */ |
1872 | tx_queue->tso_headers_free = NULL; | ||
1876 | } | 1873 | } |
1877 | for (i = 0; i < EFX_MAX_RX_QUEUES; i++) { | 1874 | for (i = 0; i < EFX_MAX_RX_QUEUES; i++) { |
1878 | rx_queue = &efx->rx_queue[i]; | 1875 | rx_queue = &efx->rx_queue[i]; |
@@ -2071,7 +2068,8 @@ static int __devinit efx_pci_probe(struct pci_dev *pci_dev, | |||
2071 | net_dev = alloc_etherdev(sizeof(*efx)); | 2068 | net_dev = alloc_etherdev(sizeof(*efx)); |
2072 | if (!net_dev) | 2069 | if (!net_dev) |
2073 | return -ENOMEM; | 2070 | return -ENOMEM; |
2074 | net_dev->features |= NETIF_F_IP_CSUM | NETIF_F_SG | NETIF_F_HIGHDMA; | 2071 | net_dev->features |= (NETIF_F_IP_CSUM | NETIF_F_SG | |
2072 | NETIF_F_HIGHDMA | NETIF_F_TSO); | ||
2075 | if (lro) | 2073 | if (lro) |
2076 | net_dev->features |= NETIF_F_LRO; | 2074 | net_dev->features |= NETIF_F_LRO; |
2077 | efx = net_dev->priv; | 2075 | efx = net_dev->priv; |
diff --git a/drivers/net/sfc/enum.h b/drivers/net/sfc/enum.h index 43663a4619da..c53290d08e2b 100644 --- a/drivers/net/sfc/enum.h +++ b/drivers/net/sfc/enum.h | |||
@@ -10,6 +10,55 @@ | |||
10 | #ifndef EFX_ENUM_H | 10 | #ifndef EFX_ENUM_H |
11 | #define EFX_ENUM_H | 11 | #define EFX_ENUM_H |
12 | 12 | ||
13 | /** | ||
14 | * enum efx_loopback_mode - loopback modes | ||
15 | * @LOOPBACK_NONE: no loopback | ||
16 | * @LOOPBACK_XGMII: loopback within MAC at XGMII level | ||
17 | * @LOOPBACK_XGXS: loopback within MAC at XGXS level | ||
18 | * @LOOPBACK_XAUI: loopback within MAC at XAUI level | ||
19 | * @LOOPBACK_PHYXS: loopback within PHY at PHYXS level | ||
20 | * @LOOPBACK_PCS: loopback within PHY at PCS level | ||
21 | * @LOOPBACK_PMAPMD: loopback within PHY at PMAPMD level | ||
22 | * @LOOPBACK_NETWORK: reflecting loopback (even further than furthest!) | ||
23 | */ | ||
24 | /* Please keep in order and up-to-date w.r.t the following two #defines */ | ||
25 | enum efx_loopback_mode { | ||
26 | LOOPBACK_NONE = 0, | ||
27 | LOOPBACK_MAC = 1, | ||
28 | LOOPBACK_XGMII = 2, | ||
29 | LOOPBACK_XGXS = 3, | ||
30 | LOOPBACK_XAUI = 4, | ||
31 | LOOPBACK_PHY = 5, | ||
32 | LOOPBACK_PHYXS = 6, | ||
33 | LOOPBACK_PCS = 7, | ||
34 | LOOPBACK_PMAPMD = 8, | ||
35 | LOOPBACK_NETWORK = 9, | ||
36 | LOOPBACK_MAX | ||
37 | }; | ||
38 | |||
39 | #define LOOPBACK_TEST_MAX LOOPBACK_PMAPMD | ||
40 | |||
41 | extern const char *efx_loopback_mode_names[]; | ||
42 | #define LOOPBACK_MODE_NAME(mode) \ | ||
43 | STRING_TABLE_LOOKUP(mode, efx_loopback_mode) | ||
44 | #define LOOPBACK_MODE(efx) \ | ||
45 | LOOPBACK_MODE_NAME(efx->loopback_mode) | ||
46 | |||
47 | /* These loopbacks occur within the controller */ | ||
48 | #define LOOPBACKS_10G_INTERNAL ((1 << LOOPBACK_XGMII)| \ | ||
49 | (1 << LOOPBACK_XGXS) | \ | ||
50 | (1 << LOOPBACK_XAUI)) | ||
51 | |||
52 | #define LOOPBACK_MASK(_efx) \ | ||
53 | (1 << (_efx)->loopback_mode) | ||
54 | |||
55 | #define LOOPBACK_INTERNAL(_efx) \ | ||
56 | ((LOOPBACKS_10G_INTERNAL & LOOPBACK_MASK(_efx)) ? 1 : 0) | ||
57 | |||
58 | #define LOOPBACK_OUT_OF(_from, _to, _mask) \ | ||
59 | (((LOOPBACK_MASK(_from) & (_mask)) && \ | ||
60 | ((LOOPBACK_MASK(_to) & (_mask)) == 0)) ? 1 : 0) | ||
61 | |||
13 | /*****************************************************************************/ | 62 | /*****************************************************************************/ |
14 | 63 | ||
15 | /** | 64 | /** |
diff --git a/drivers/net/sfc/ethtool.c b/drivers/net/sfc/ethtool.c index ad541badbd98..e2c75d101610 100644 --- a/drivers/net/sfc/ethtool.c +++ b/drivers/net/sfc/ethtool.c | |||
@@ -12,12 +12,26 @@ | |||
12 | #include <linux/ethtool.h> | 12 | #include <linux/ethtool.h> |
13 | #include <linux/rtnetlink.h> | 13 | #include <linux/rtnetlink.h> |
14 | #include "net_driver.h" | 14 | #include "net_driver.h" |
15 | #include "selftest.h" | ||
15 | #include "efx.h" | 16 | #include "efx.h" |
16 | #include "ethtool.h" | 17 | #include "ethtool.h" |
17 | #include "falcon.h" | 18 | #include "falcon.h" |
18 | #include "gmii.h" | 19 | #include "gmii.h" |
19 | #include "mac.h" | 20 | #include "mac.h" |
20 | 21 | ||
22 | const char *efx_loopback_mode_names[] = { | ||
23 | [LOOPBACK_NONE] = "NONE", | ||
24 | [LOOPBACK_MAC] = "MAC", | ||
25 | [LOOPBACK_XGMII] = "XGMII", | ||
26 | [LOOPBACK_XGXS] = "XGXS", | ||
27 | [LOOPBACK_XAUI] = "XAUI", | ||
28 | [LOOPBACK_PHY] = "PHY", | ||
29 | [LOOPBACK_PHYXS] = "PHY(XS)", | ||
30 | [LOOPBACK_PCS] = "PHY(PCS)", | ||
31 | [LOOPBACK_PMAPMD] = "PHY(PMAPMD)", | ||
32 | [LOOPBACK_NETWORK] = "NETWORK", | ||
33 | }; | ||
34 | |||
21 | static int efx_ethtool_set_tx_csum(struct net_device *net_dev, u32 enable); | 35 | static int efx_ethtool_set_tx_csum(struct net_device *net_dev, u32 enable); |
22 | 36 | ||
23 | struct ethtool_string { | 37 | struct ethtool_string { |
@@ -217,23 +231,179 @@ static void efx_ethtool_get_drvinfo(struct net_device *net_dev, | |||
217 | strlcpy(info->bus_info, pci_name(efx->pci_dev), sizeof(info->bus_info)); | 231 | strlcpy(info->bus_info, pci_name(efx->pci_dev), sizeof(info->bus_info)); |
218 | } | 232 | } |
219 | 233 | ||
234 | /** | ||
235 | * efx_fill_test - fill in an individual self-test entry | ||
236 | * @test_index: Index of the test | ||
237 | * @strings: Ethtool strings, or %NULL | ||
238 | * @data: Ethtool test results, or %NULL | ||
239 | * @test: Pointer to test result (used only if data != %NULL) | ||
240 | * @unit_format: Unit name format (e.g. "channel\%d") | ||
241 | * @unit_id: Unit id (e.g. 0 for "channel0") | ||
242 | * @test_format: Test name format (e.g. "loopback.\%s.tx.sent") | ||
243 | * @test_id: Test id (e.g. "PHY" for "loopback.PHY.tx_sent") | ||
244 | * | ||
245 | * Fill in an individual self-test entry. | ||
246 | */ | ||
247 | static void efx_fill_test(unsigned int test_index, | ||
248 | struct ethtool_string *strings, u64 *data, | ||
249 | int *test, const char *unit_format, int unit_id, | ||
250 | const char *test_format, const char *test_id) | ||
251 | { | ||
252 | struct ethtool_string unit_str, test_str; | ||
253 | |||
254 | /* Fill data value, if applicable */ | ||
255 | if (data) | ||
256 | data[test_index] = *test; | ||
257 | |||
258 | /* Fill string, if applicable */ | ||
259 | if (strings) { | ||
260 | snprintf(unit_str.name, sizeof(unit_str.name), | ||
261 | unit_format, unit_id); | ||
262 | snprintf(test_str.name, sizeof(test_str.name), | ||
263 | test_format, test_id); | ||
264 | snprintf(strings[test_index].name, | ||
265 | sizeof(strings[test_index].name), | ||
266 | "%-9s%-17s", unit_str.name, test_str.name); | ||
267 | } | ||
268 | } | ||
269 | |||
270 | #define EFX_PORT_NAME "port%d", 0 | ||
271 | #define EFX_CHANNEL_NAME(_channel) "channel%d", _channel->channel | ||
272 | #define EFX_TX_QUEUE_NAME(_tx_queue) "txq%d", _tx_queue->queue | ||
273 | #define EFX_RX_QUEUE_NAME(_rx_queue) "rxq%d", _rx_queue->queue | ||
274 | #define EFX_LOOPBACK_NAME(_mode, _counter) \ | ||
275 | "loopback.%s." _counter, LOOPBACK_MODE_NAME(mode) | ||
276 | |||
277 | /** | ||
278 | * efx_fill_loopback_test - fill in a block of loopback self-test entries | ||
279 | * @efx: Efx NIC | ||
280 | * @lb_tests: Efx loopback self-test results structure | ||
281 | * @mode: Loopback test mode | ||
282 | * @test_index: Starting index of the test | ||
283 | * @strings: Ethtool strings, or %NULL | ||
284 | * @data: Ethtool test results, or %NULL | ||
285 | */ | ||
286 | static int efx_fill_loopback_test(struct efx_nic *efx, | ||
287 | struct efx_loopback_self_tests *lb_tests, | ||
288 | enum efx_loopback_mode mode, | ||
289 | unsigned int test_index, | ||
290 | struct ethtool_string *strings, u64 *data) | ||
291 | { | ||
292 | struct efx_tx_queue *tx_queue; | ||
293 | |||
294 | efx_for_each_tx_queue(tx_queue, efx) { | ||
295 | efx_fill_test(test_index++, strings, data, | ||
296 | &lb_tests->tx_sent[tx_queue->queue], | ||
297 | EFX_TX_QUEUE_NAME(tx_queue), | ||
298 | EFX_LOOPBACK_NAME(mode, "tx_sent")); | ||
299 | efx_fill_test(test_index++, strings, data, | ||
300 | &lb_tests->tx_done[tx_queue->queue], | ||
301 | EFX_TX_QUEUE_NAME(tx_queue), | ||
302 | EFX_LOOPBACK_NAME(mode, "tx_done")); | ||
303 | } | ||
304 | efx_fill_test(test_index++, strings, data, | ||
305 | &lb_tests->rx_good, | ||
306 | EFX_PORT_NAME, | ||
307 | EFX_LOOPBACK_NAME(mode, "rx_good")); | ||
308 | efx_fill_test(test_index++, strings, data, | ||
309 | &lb_tests->rx_bad, | ||
310 | EFX_PORT_NAME, | ||
311 | EFX_LOOPBACK_NAME(mode, "rx_bad")); | ||
312 | |||
313 | return test_index; | ||
314 | } | ||
315 | |||
316 | /** | ||
317 | * efx_ethtool_fill_self_tests - get self-test details | ||
318 | * @efx: Efx NIC | ||
319 | * @tests: Efx self-test results structure, or %NULL | ||
320 | * @strings: Ethtool strings, or %NULL | ||
321 | * @data: Ethtool test results, or %NULL | ||
322 | */ | ||
323 | static int efx_ethtool_fill_self_tests(struct efx_nic *efx, | ||
324 | struct efx_self_tests *tests, | ||
325 | struct ethtool_string *strings, | ||
326 | u64 *data) | ||
327 | { | ||
328 | struct efx_channel *channel; | ||
329 | unsigned int n = 0; | ||
330 | enum efx_loopback_mode mode; | ||
331 | |||
332 | /* Interrupt */ | ||
333 | efx_fill_test(n++, strings, data, &tests->interrupt, | ||
334 | "core", 0, "interrupt", NULL); | ||
335 | |||
336 | /* Event queues */ | ||
337 | efx_for_each_channel(channel, efx) { | ||
338 | efx_fill_test(n++, strings, data, | ||
339 | &tests->eventq_dma[channel->channel], | ||
340 | EFX_CHANNEL_NAME(channel), | ||
341 | "eventq.dma", NULL); | ||
342 | efx_fill_test(n++, strings, data, | ||
343 | &tests->eventq_int[channel->channel], | ||
344 | EFX_CHANNEL_NAME(channel), | ||
345 | "eventq.int", NULL); | ||
346 | efx_fill_test(n++, strings, data, | ||
347 | &tests->eventq_poll[channel->channel], | ||
348 | EFX_CHANNEL_NAME(channel), | ||
349 | "eventq.poll", NULL); | ||
350 | } | ||
351 | |||
352 | /* PHY presence */ | ||
353 | efx_fill_test(n++, strings, data, &tests->phy_ok, | ||
354 | EFX_PORT_NAME, "phy_ok", NULL); | ||
355 | |||
356 | /* Loopback tests */ | ||
357 | efx_fill_test(n++, strings, data, &tests->loopback_speed, | ||
358 | EFX_PORT_NAME, "loopback.speed", NULL); | ||
359 | efx_fill_test(n++, strings, data, &tests->loopback_full_duplex, | ||
360 | EFX_PORT_NAME, "loopback.full_duplex", NULL); | ||
361 | for (mode = LOOPBACK_NONE; mode < LOOPBACK_TEST_MAX; mode++) { | ||
362 | if (!(efx->loopback_modes & (1 << mode))) | ||
363 | continue; | ||
364 | n = efx_fill_loopback_test(efx, | ||
365 | &tests->loopback[mode], mode, n, | ||
366 | strings, data); | ||
367 | } | ||
368 | |||
369 | return n; | ||
370 | } | ||
371 | |||
220 | static int efx_ethtool_get_stats_count(struct net_device *net_dev) | 372 | static int efx_ethtool_get_stats_count(struct net_device *net_dev) |
221 | { | 373 | { |
222 | return EFX_ETHTOOL_NUM_STATS; | 374 | return EFX_ETHTOOL_NUM_STATS; |
223 | } | 375 | } |
224 | 376 | ||
377 | static int efx_ethtool_self_test_count(struct net_device *net_dev) | ||
378 | { | ||
379 | struct efx_nic *efx = net_dev->priv; | ||
380 | |||
381 | return efx_ethtool_fill_self_tests(efx, NULL, NULL, NULL); | ||
382 | } | ||
383 | |||
225 | static void efx_ethtool_get_strings(struct net_device *net_dev, | 384 | static void efx_ethtool_get_strings(struct net_device *net_dev, |
226 | u32 string_set, u8 *strings) | 385 | u32 string_set, u8 *strings) |
227 | { | 386 | { |
387 | struct efx_nic *efx = net_dev->priv; | ||
228 | struct ethtool_string *ethtool_strings = | 388 | struct ethtool_string *ethtool_strings = |
229 | (struct ethtool_string *)strings; | 389 | (struct ethtool_string *)strings; |
230 | int i; | 390 | int i; |
231 | 391 | ||
232 | if (string_set == ETH_SS_STATS) | 392 | switch (string_set) { |
393 | case ETH_SS_STATS: | ||
233 | for (i = 0; i < EFX_ETHTOOL_NUM_STATS; i++) | 394 | for (i = 0; i < EFX_ETHTOOL_NUM_STATS; i++) |
234 | strncpy(ethtool_strings[i].name, | 395 | strncpy(ethtool_strings[i].name, |
235 | efx_ethtool_stats[i].name, | 396 | efx_ethtool_stats[i].name, |
236 | sizeof(ethtool_strings[i].name)); | 397 | sizeof(ethtool_strings[i].name)); |
398 | break; | ||
399 | case ETH_SS_TEST: | ||
400 | efx_ethtool_fill_self_tests(efx, NULL, | ||
401 | ethtool_strings, NULL); | ||
402 | break; | ||
403 | default: | ||
404 | /* No other string sets */ | ||
405 | break; | ||
406 | } | ||
237 | } | 407 | } |
238 | 408 | ||
239 | static void efx_ethtool_get_stats(struct net_device *net_dev, | 409 | static void efx_ethtool_get_stats(struct net_device *net_dev, |
@@ -272,6 +442,22 @@ static void efx_ethtool_get_stats(struct net_device *net_dev, | |||
272 | } | 442 | } |
273 | } | 443 | } |
274 | 444 | ||
445 | static int efx_ethtool_set_tso(struct net_device *net_dev, u32 enable) | ||
446 | { | ||
447 | int rc; | ||
448 | |||
449 | /* Our TSO requires TX checksumming, so force TX checksumming | ||
450 | * on when TSO is enabled. | ||
451 | */ | ||
452 | if (enable) { | ||
453 | rc = efx_ethtool_set_tx_csum(net_dev, 1); | ||
454 | if (rc) | ||
455 | return rc; | ||
456 | } | ||
457 | |||
458 | return ethtool_op_set_tso(net_dev, enable); | ||
459 | } | ||
460 | |||
275 | static int efx_ethtool_set_tx_csum(struct net_device *net_dev, u32 enable) | 461 | static int efx_ethtool_set_tx_csum(struct net_device *net_dev, u32 enable) |
276 | { | 462 | { |
277 | struct efx_nic *efx = net_dev->priv; | 463 | struct efx_nic *efx = net_dev->priv; |
@@ -283,6 +469,15 @@ static int efx_ethtool_set_tx_csum(struct net_device *net_dev, u32 enable) | |||
283 | 469 | ||
284 | efx_flush_queues(efx); | 470 | efx_flush_queues(efx); |
285 | 471 | ||
472 | /* Our TSO requires TX checksumming, so disable TSO when | ||
473 | * checksumming is disabled | ||
474 | */ | ||
475 | if (!enable) { | ||
476 | rc = efx_ethtool_set_tso(net_dev, 0); | ||
477 | if (rc) | ||
478 | return rc; | ||
479 | } | ||
480 | |||
286 | return 0; | 481 | return 0; |
287 | } | 482 | } |
288 | 483 | ||
@@ -305,6 +500,64 @@ static u32 efx_ethtool_get_rx_csum(struct net_device *net_dev) | |||
305 | return efx->rx_checksum_enabled; | 500 | return efx->rx_checksum_enabled; |
306 | } | 501 | } |
307 | 502 | ||
503 | static void efx_ethtool_self_test(struct net_device *net_dev, | ||
504 | struct ethtool_test *test, u64 *data) | ||
505 | { | ||
506 | struct efx_nic *efx = net_dev->priv; | ||
507 | struct efx_self_tests efx_tests; | ||
508 | int offline, already_up; | ||
509 | int rc; | ||
510 | |||
511 | ASSERT_RTNL(); | ||
512 | if (efx->state != STATE_RUNNING) { | ||
513 | rc = -EIO; | ||
514 | goto fail1; | ||
515 | } | ||
516 | |||
517 | /* We need rx buffers and interrupts. */ | ||
518 | already_up = (efx->net_dev->flags & IFF_UP); | ||
519 | if (!already_up) { | ||
520 | rc = dev_open(efx->net_dev); | ||
521 | if (rc) { | ||
522 | EFX_ERR(efx, "failed opening device.\n"); | ||
523 | goto fail2; | ||
524 | } | ||
525 | } | ||
526 | |||
527 | memset(&efx_tests, 0, sizeof(efx_tests)); | ||
528 | offline = (test->flags & ETH_TEST_FL_OFFLINE); | ||
529 | |||
530 | /* Perform online self tests first */ | ||
531 | rc = efx_online_test(efx, &efx_tests); | ||
532 | if (rc) | ||
533 | goto out; | ||
534 | |||
535 | /* Perform offline tests only if online tests passed */ | ||
536 | if (offline) { | ||
537 | /* Stop the kernel from sending packets during the test. */ | ||
538 | efx_stop_queue(efx); | ||
539 | rc = efx_flush_queues(efx); | ||
540 | if (!rc) | ||
541 | rc = efx_offline_test(efx, &efx_tests, | ||
542 | efx->loopback_modes); | ||
543 | efx_wake_queue(efx); | ||
544 | } | ||
545 | |||
546 | out: | ||
547 | if (!already_up) | ||
548 | dev_close(efx->net_dev); | ||
549 | |||
550 | EFX_LOG(efx, "%s all %sline self-tests\n", | ||
551 | rc == 0 ? "passed" : "failed", offline ? "off" : "on"); | ||
552 | |||
553 | fail2: | ||
554 | fail1: | ||
555 | /* Fill ethtool results structures */ | ||
556 | efx_ethtool_fill_self_tests(efx, &efx_tests, NULL, data); | ||
557 | if (rc) | ||
558 | test->flags |= ETH_TEST_FL_FAILED; | ||
559 | } | ||
560 | |||
308 | /* Restart autonegotiation */ | 561 | /* Restart autonegotiation */ |
309 | static int efx_ethtool_nway_reset(struct net_device *net_dev) | 562 | static int efx_ethtool_nway_reset(struct net_device *net_dev) |
310 | { | 563 | { |
@@ -451,8 +704,12 @@ struct ethtool_ops efx_ethtool_ops = { | |||
451 | .set_tx_csum = efx_ethtool_set_tx_csum, | 704 | .set_tx_csum = efx_ethtool_set_tx_csum, |
452 | .get_sg = ethtool_op_get_sg, | 705 | .get_sg = ethtool_op_get_sg, |
453 | .set_sg = ethtool_op_set_sg, | 706 | .set_sg = ethtool_op_set_sg, |
707 | .get_tso = ethtool_op_get_tso, | ||
708 | .set_tso = efx_ethtool_set_tso, | ||
454 | .get_flags = ethtool_op_get_flags, | 709 | .get_flags = ethtool_op_get_flags, |
455 | .set_flags = ethtool_op_set_flags, | 710 | .set_flags = ethtool_op_set_flags, |
711 | .self_test_count = efx_ethtool_self_test_count, | ||
712 | .self_test = efx_ethtool_self_test, | ||
456 | .get_strings = efx_ethtool_get_strings, | 713 | .get_strings = efx_ethtool_get_strings, |
457 | .phys_id = efx_ethtool_phys_id, | 714 | .phys_id = efx_ethtool_phys_id, |
458 | .get_stats_count = efx_ethtool_get_stats_count, | 715 | .get_stats_count = efx_ethtool_get_stats_count, |
diff --git a/drivers/net/sfc/falcon.c b/drivers/net/sfc/falcon.c index 46db549ce580..790db89db345 100644 --- a/drivers/net/sfc/falcon.c +++ b/drivers/net/sfc/falcon.c | |||
@@ -116,17 +116,8 @@ MODULE_PARM_DESC(rx_xon_thresh_bytes, "RX fifo XON threshold"); | |||
116 | ************************************************************************** | 116 | ************************************************************************** |
117 | */ | 117 | */ |
118 | 118 | ||
119 | /* DMA address mask (up to 46-bit, avoiding compiler warnings) | 119 | /* DMA address mask */ |
120 | * | 120 | #define FALCON_DMA_MASK DMA_BIT_MASK(46) |
121 | * Note that it is possible to have a platform with 64-bit longs and | ||
122 | * 32-bit DMA addresses, or vice versa. EFX_DMA_MASK takes care of the | ||
123 | * platform DMA mask. | ||
124 | */ | ||
125 | #if BITS_PER_LONG == 64 | ||
126 | #define FALCON_DMA_MASK EFX_DMA_MASK(0x00003fffffffffffUL) | ||
127 | #else | ||
128 | #define FALCON_DMA_MASK EFX_DMA_MASK(0x00003fffffffffffULL) | ||
129 | #endif | ||
130 | 121 | ||
131 | /* TX DMA length mask (13-bit) */ | 122 | /* TX DMA length mask (13-bit) */ |
132 | #define FALCON_TX_DMA_MASK (4096 - 1) | 123 | #define FALCON_TX_DMA_MASK (4096 - 1) |
@@ -145,7 +136,7 @@ MODULE_PARM_DESC(rx_xon_thresh_bytes, "RX fifo XON threshold"); | |||
145 | #define PCI_EXP_LNKSTA_LNK_WID_LBN 4 | 136 | #define PCI_EXP_LNKSTA_LNK_WID_LBN 4 |
146 | 137 | ||
147 | #define FALCON_IS_DUAL_FUNC(efx) \ | 138 | #define FALCON_IS_DUAL_FUNC(efx) \ |
148 | (FALCON_REV(efx) < FALCON_REV_B0) | 139 | (falcon_rev(efx) < FALCON_REV_B0) |
149 | 140 | ||
150 | /************************************************************************** | 141 | /************************************************************************** |
151 | * | 142 | * |
@@ -465,7 +456,7 @@ int falcon_init_tx(struct efx_tx_queue *tx_queue) | |||
465 | TX_DESCQ_TYPE, 0, | 456 | TX_DESCQ_TYPE, 0, |
466 | TX_NON_IP_DROP_DIS_B0, 1); | 457 | TX_NON_IP_DROP_DIS_B0, 1); |
467 | 458 | ||
468 | if (FALCON_REV(efx) >= FALCON_REV_B0) { | 459 | if (falcon_rev(efx) >= FALCON_REV_B0) { |
469 | int csum = !(efx->net_dev->features & NETIF_F_IP_CSUM); | 460 | int csum = !(efx->net_dev->features & NETIF_F_IP_CSUM); |
470 | EFX_SET_OWORD_FIELD(tx_desc_ptr, TX_IP_CHKSM_DIS_B0, csum); | 461 | EFX_SET_OWORD_FIELD(tx_desc_ptr, TX_IP_CHKSM_DIS_B0, csum); |
471 | EFX_SET_OWORD_FIELD(tx_desc_ptr, TX_TCP_CHKSM_DIS_B0, csum); | 462 | EFX_SET_OWORD_FIELD(tx_desc_ptr, TX_TCP_CHKSM_DIS_B0, csum); |
@@ -474,7 +465,7 @@ int falcon_init_tx(struct efx_tx_queue *tx_queue) | |||
474 | falcon_write_table(efx, &tx_desc_ptr, efx->type->txd_ptr_tbl_base, | 465 | falcon_write_table(efx, &tx_desc_ptr, efx->type->txd_ptr_tbl_base, |
475 | tx_queue->queue); | 466 | tx_queue->queue); |
476 | 467 | ||
477 | if (FALCON_REV(efx) < FALCON_REV_B0) { | 468 | if (falcon_rev(efx) < FALCON_REV_B0) { |
478 | efx_oword_t reg; | 469 | efx_oword_t reg; |
479 | 470 | ||
480 | BUG_ON(tx_queue->queue >= 128); /* HW limit */ | 471 | BUG_ON(tx_queue->queue >= 128); /* HW limit */ |
@@ -635,7 +626,7 @@ int falcon_init_rx(struct efx_rx_queue *rx_queue) | |||
635 | efx_oword_t rx_desc_ptr; | 626 | efx_oword_t rx_desc_ptr; |
636 | struct efx_nic *efx = rx_queue->efx; | 627 | struct efx_nic *efx = rx_queue->efx; |
637 | int rc; | 628 | int rc; |
638 | int is_b0 = FALCON_REV(efx) >= FALCON_REV_B0; | 629 | int is_b0 = falcon_rev(efx) >= FALCON_REV_B0; |
639 | int iscsi_digest_en = is_b0; | 630 | int iscsi_digest_en = is_b0; |
640 | 631 | ||
641 | EFX_LOG(efx, "RX queue %d ring in special buffers %d-%d\n", | 632 | EFX_LOG(efx, "RX queue %d ring in special buffers %d-%d\n", |
@@ -742,8 +733,10 @@ void falcon_fini_rx(struct efx_rx_queue *rx_queue) | |||
742 | continue; | 733 | continue; |
743 | break; | 734 | break; |
744 | } | 735 | } |
745 | if (rc) | 736 | if (rc) { |
746 | EFX_ERR(efx, "failed to flush rx queue %d\n", rx_queue->queue); | 737 | EFX_ERR(efx, "failed to flush rx queue %d\n", rx_queue->queue); |
738 | efx_schedule_reset(efx, RESET_TYPE_INVISIBLE); | ||
739 | } | ||
747 | 740 | ||
748 | /* Remove RX descriptor ring from card */ | 741 | /* Remove RX descriptor ring from card */ |
749 | EFX_ZERO_OWORD(rx_desc_ptr); | 742 | EFX_ZERO_OWORD(rx_desc_ptr); |
@@ -822,10 +815,10 @@ static inline void falcon_handle_tx_event(struct efx_channel *channel, | |||
822 | tx_ev_q_label = EFX_QWORD_FIELD(*event, TX_EV_Q_LABEL); | 815 | tx_ev_q_label = EFX_QWORD_FIELD(*event, TX_EV_Q_LABEL); |
823 | tx_queue = &efx->tx_queue[tx_ev_q_label]; | 816 | tx_queue = &efx->tx_queue[tx_ev_q_label]; |
824 | 817 | ||
825 | if (NET_DEV_REGISTERED(efx)) | 818 | if (efx_dev_registered(efx)) |
826 | netif_tx_lock(efx->net_dev); | 819 | netif_tx_lock(efx->net_dev); |
827 | falcon_notify_tx_desc(tx_queue); | 820 | falcon_notify_tx_desc(tx_queue); |
828 | if (NET_DEV_REGISTERED(efx)) | 821 | if (efx_dev_registered(efx)) |
829 | netif_tx_unlock(efx->net_dev); | 822 | netif_tx_unlock(efx->net_dev); |
830 | } else if (EFX_QWORD_FIELD(*event, TX_EV_PKT_ERR) && | 823 | } else if (EFX_QWORD_FIELD(*event, TX_EV_PKT_ERR) && |
831 | EFX_WORKAROUND_10727(efx)) { | 824 | EFX_WORKAROUND_10727(efx)) { |
@@ -884,7 +877,7 @@ static void falcon_handle_rx_not_ok(struct efx_rx_queue *rx_queue, | |||
884 | RX_EV_TCP_UDP_CHKSUM_ERR); | 877 | RX_EV_TCP_UDP_CHKSUM_ERR); |
885 | rx_ev_eth_crc_err = EFX_QWORD_FIELD(*event, RX_EV_ETH_CRC_ERR); | 878 | rx_ev_eth_crc_err = EFX_QWORD_FIELD(*event, RX_EV_ETH_CRC_ERR); |
886 | rx_ev_frm_trunc = EFX_QWORD_FIELD(*event, RX_EV_FRM_TRUNC); | 879 | rx_ev_frm_trunc = EFX_QWORD_FIELD(*event, RX_EV_FRM_TRUNC); |
887 | rx_ev_drib_nib = ((FALCON_REV(efx) >= FALCON_REV_B0) ? | 880 | rx_ev_drib_nib = ((falcon_rev(efx) >= FALCON_REV_B0) ? |
888 | 0 : EFX_QWORD_FIELD(*event, RX_EV_DRIB_NIB)); | 881 | 0 : EFX_QWORD_FIELD(*event, RX_EV_DRIB_NIB)); |
889 | rx_ev_pause_frm = EFX_QWORD_FIELD(*event, RX_EV_PAUSE_FRM_ERR); | 882 | rx_ev_pause_frm = EFX_QWORD_FIELD(*event, RX_EV_PAUSE_FRM_ERR); |
890 | 883 | ||
@@ -1065,7 +1058,7 @@ static void falcon_handle_global_event(struct efx_channel *channel, | |||
1065 | EFX_QWORD_FIELD(*event, XG_PHY_INTR)) | 1058 | EFX_QWORD_FIELD(*event, XG_PHY_INTR)) |
1066 | is_phy_event = 1; | 1059 | is_phy_event = 1; |
1067 | 1060 | ||
1068 | if ((FALCON_REV(efx) >= FALCON_REV_B0) && | 1061 | if ((falcon_rev(efx) >= FALCON_REV_B0) && |
1069 | EFX_OWORD_FIELD(*event, XG_MNT_INTR_B0)) | 1062 | EFX_OWORD_FIELD(*event, XG_MNT_INTR_B0)) |
1070 | is_phy_event = 1; | 1063 | is_phy_event = 1; |
1071 | 1064 | ||
@@ -1129,6 +1122,7 @@ static void falcon_handle_driver_event(struct efx_channel *channel, | |||
1129 | case RX_RECOVERY_EV_DECODE: | 1122 | case RX_RECOVERY_EV_DECODE: |
1130 | EFX_ERR(efx, "channel %d seen DRIVER RX_RESET event. " | 1123 | EFX_ERR(efx, "channel %d seen DRIVER RX_RESET event. " |
1131 | "Resetting.\n", channel->channel); | 1124 | "Resetting.\n", channel->channel); |
1125 | atomic_inc(&efx->rx_reset); | ||
1132 | efx_schedule_reset(efx, | 1126 | efx_schedule_reset(efx, |
1133 | EFX_WORKAROUND_6555(efx) ? | 1127 | EFX_WORKAROUND_6555(efx) ? |
1134 | RESET_TYPE_RX_RECOVERY : | 1128 | RESET_TYPE_RX_RECOVERY : |
@@ -1404,7 +1398,7 @@ static inline void falcon_irq_ack_a1(struct efx_nic *efx) | |||
1404 | static irqreturn_t falcon_fatal_interrupt(struct efx_nic *efx) | 1398 | static irqreturn_t falcon_fatal_interrupt(struct efx_nic *efx) |
1405 | { | 1399 | { |
1406 | struct falcon_nic_data *nic_data = efx->nic_data; | 1400 | struct falcon_nic_data *nic_data = efx->nic_data; |
1407 | efx_oword_t *int_ker = (efx_oword_t *) efx->irq_status.addr; | 1401 | efx_oword_t *int_ker = efx->irq_status.addr; |
1408 | efx_oword_t fatal_intr; | 1402 | efx_oword_t fatal_intr; |
1409 | int error, mem_perr; | 1403 | int error, mem_perr; |
1410 | static int n_int_errors; | 1404 | static int n_int_errors; |
@@ -1450,8 +1444,8 @@ out: | |||
1450 | */ | 1444 | */ |
1451 | static irqreturn_t falcon_legacy_interrupt_b0(int irq, void *dev_id) | 1445 | static irqreturn_t falcon_legacy_interrupt_b0(int irq, void *dev_id) |
1452 | { | 1446 | { |
1453 | struct efx_nic *efx = (struct efx_nic *)dev_id; | 1447 | struct efx_nic *efx = dev_id; |
1454 | efx_oword_t *int_ker = (efx_oword_t *) efx->irq_status.addr; | 1448 | efx_oword_t *int_ker = efx->irq_status.addr; |
1455 | struct efx_channel *channel; | 1449 | struct efx_channel *channel; |
1456 | efx_dword_t reg; | 1450 | efx_dword_t reg; |
1457 | u32 queues; | 1451 | u32 queues; |
@@ -1488,8 +1482,8 @@ static irqreturn_t falcon_legacy_interrupt_b0(int irq, void *dev_id) | |||
1488 | 1482 | ||
1489 | static irqreturn_t falcon_legacy_interrupt_a1(int irq, void *dev_id) | 1483 | static irqreturn_t falcon_legacy_interrupt_a1(int irq, void *dev_id) |
1490 | { | 1484 | { |
1491 | struct efx_nic *efx = (struct efx_nic *)dev_id; | 1485 | struct efx_nic *efx = dev_id; |
1492 | efx_oword_t *int_ker = (efx_oword_t *) efx->irq_status.addr; | 1486 | efx_oword_t *int_ker = efx->irq_status.addr; |
1493 | struct efx_channel *channel; | 1487 | struct efx_channel *channel; |
1494 | int syserr; | 1488 | int syserr; |
1495 | int queues; | 1489 | int queues; |
@@ -1541,9 +1535,9 @@ static irqreturn_t falcon_legacy_interrupt_a1(int irq, void *dev_id) | |||
1541 | */ | 1535 | */ |
1542 | static irqreturn_t falcon_msi_interrupt(int irq, void *dev_id) | 1536 | static irqreturn_t falcon_msi_interrupt(int irq, void *dev_id) |
1543 | { | 1537 | { |
1544 | struct efx_channel *channel = (struct efx_channel *)dev_id; | 1538 | struct efx_channel *channel = dev_id; |
1545 | struct efx_nic *efx = channel->efx; | 1539 | struct efx_nic *efx = channel->efx; |
1546 | efx_oword_t *int_ker = (efx_oword_t *) efx->irq_status.addr; | 1540 | efx_oword_t *int_ker = efx->irq_status.addr; |
1547 | int syserr; | 1541 | int syserr; |
1548 | 1542 | ||
1549 | efx->last_irq_cpu = raw_smp_processor_id(); | 1543 | efx->last_irq_cpu = raw_smp_processor_id(); |
@@ -1571,7 +1565,7 @@ static void falcon_setup_rss_indir_table(struct efx_nic *efx) | |||
1571 | unsigned long offset; | 1565 | unsigned long offset; |
1572 | efx_dword_t dword; | 1566 | efx_dword_t dword; |
1573 | 1567 | ||
1574 | if (FALCON_REV(efx) < FALCON_REV_B0) | 1568 | if (falcon_rev(efx) < FALCON_REV_B0) |
1575 | return; | 1569 | return; |
1576 | 1570 | ||
1577 | for (offset = RX_RSS_INDIR_TBL_B0; | 1571 | for (offset = RX_RSS_INDIR_TBL_B0; |
@@ -1594,7 +1588,7 @@ int falcon_init_interrupt(struct efx_nic *efx) | |||
1594 | 1588 | ||
1595 | if (!EFX_INT_MODE_USE_MSI(efx)) { | 1589 | if (!EFX_INT_MODE_USE_MSI(efx)) { |
1596 | irq_handler_t handler; | 1590 | irq_handler_t handler; |
1597 | if (FALCON_REV(efx) >= FALCON_REV_B0) | 1591 | if (falcon_rev(efx) >= FALCON_REV_B0) |
1598 | handler = falcon_legacy_interrupt_b0; | 1592 | handler = falcon_legacy_interrupt_b0; |
1599 | else | 1593 | else |
1600 | handler = falcon_legacy_interrupt_a1; | 1594 | handler = falcon_legacy_interrupt_a1; |
@@ -1635,12 +1629,13 @@ void falcon_fini_interrupt(struct efx_nic *efx) | |||
1635 | efx_oword_t reg; | 1629 | efx_oword_t reg; |
1636 | 1630 | ||
1637 | /* Disable MSI/MSI-X interrupts */ | 1631 | /* Disable MSI/MSI-X interrupts */ |
1638 | efx_for_each_channel_with_interrupt(channel, efx) | 1632 | efx_for_each_channel_with_interrupt(channel, efx) { |
1639 | if (channel->irq) | 1633 | if (channel->irq) |
1640 | free_irq(channel->irq, channel); | 1634 | free_irq(channel->irq, channel); |
1635 | } | ||
1641 | 1636 | ||
1642 | /* ACK legacy interrupt */ | 1637 | /* ACK legacy interrupt */ |
1643 | if (FALCON_REV(efx) >= FALCON_REV_B0) | 1638 | if (falcon_rev(efx) >= FALCON_REV_B0) |
1644 | falcon_read(efx, ®, INT_ISR0_B0); | 1639 | falcon_read(efx, ®, INT_ISR0_B0); |
1645 | else | 1640 | else |
1646 | falcon_irq_ack_a1(efx); | 1641 | falcon_irq_ack_a1(efx); |
@@ -1731,7 +1726,8 @@ void falcon_drain_tx_fifo(struct efx_nic *efx) | |||
1731 | efx_oword_t temp; | 1726 | efx_oword_t temp; |
1732 | int count; | 1727 | int count; |
1733 | 1728 | ||
1734 | if (FALCON_REV(efx) < FALCON_REV_B0) | 1729 | if ((falcon_rev(efx) < FALCON_REV_B0) || |
1730 | (efx->loopback_mode != LOOPBACK_NONE)) | ||
1735 | return; | 1731 | return; |
1736 | 1732 | ||
1737 | falcon_read(efx, &temp, MAC0_CTRL_REG_KER); | 1733 | falcon_read(efx, &temp, MAC0_CTRL_REG_KER); |
@@ -1783,7 +1779,7 @@ void falcon_deconfigure_mac_wrapper(struct efx_nic *efx) | |||
1783 | { | 1779 | { |
1784 | efx_oword_t temp; | 1780 | efx_oword_t temp; |
1785 | 1781 | ||
1786 | if (FALCON_REV(efx) < FALCON_REV_B0) | 1782 | if (falcon_rev(efx) < FALCON_REV_B0) |
1787 | return; | 1783 | return; |
1788 | 1784 | ||
1789 | /* Isolate the MAC -> RX */ | 1785 | /* Isolate the MAC -> RX */ |
@@ -1821,7 +1817,7 @@ void falcon_reconfigure_mac_wrapper(struct efx_nic *efx) | |||
1821 | MAC_SPEED, link_speed); | 1817 | MAC_SPEED, link_speed); |
1822 | /* On B0, MAC backpressure can be disabled and packets get | 1818 | /* On B0, MAC backpressure can be disabled and packets get |
1823 | * discarded. */ | 1819 | * discarded. */ |
1824 | if (FALCON_REV(efx) >= FALCON_REV_B0) { | 1820 | if (falcon_rev(efx) >= FALCON_REV_B0) { |
1825 | EFX_SET_OWORD_FIELD(reg, TXFIFO_DRAIN_EN_B0, | 1821 | EFX_SET_OWORD_FIELD(reg, TXFIFO_DRAIN_EN_B0, |
1826 | !efx->link_up); | 1822 | !efx->link_up); |
1827 | } | 1823 | } |
@@ -1839,7 +1835,7 @@ void falcon_reconfigure_mac_wrapper(struct efx_nic *efx) | |||
1839 | EFX_SET_OWORD_FIELD_VER(efx, reg, RX_XOFF_MAC_EN, tx_fc); | 1835 | EFX_SET_OWORD_FIELD_VER(efx, reg, RX_XOFF_MAC_EN, tx_fc); |
1840 | 1836 | ||
1841 | /* Unisolate the MAC -> RX */ | 1837 | /* Unisolate the MAC -> RX */ |
1842 | if (FALCON_REV(efx) >= FALCON_REV_B0) | 1838 | if (falcon_rev(efx) >= FALCON_REV_B0) |
1843 | EFX_SET_OWORD_FIELD(reg, RX_INGR_EN_B0, 1); | 1839 | EFX_SET_OWORD_FIELD(reg, RX_INGR_EN_B0, 1); |
1844 | falcon_write(efx, ®, RX_CFG_REG_KER); | 1840 | falcon_write(efx, ®, RX_CFG_REG_KER); |
1845 | } | 1841 | } |
@@ -1854,7 +1850,7 @@ int falcon_dma_stats(struct efx_nic *efx, unsigned int done_offset) | |||
1854 | return 0; | 1850 | return 0; |
1855 | 1851 | ||
1856 | /* Statistics fetch will fail if the MAC is in TX drain */ | 1852 | /* Statistics fetch will fail if the MAC is in TX drain */ |
1857 | if (FALCON_REV(efx) >= FALCON_REV_B0) { | 1853 | if (falcon_rev(efx) >= FALCON_REV_B0) { |
1858 | efx_oword_t temp; | 1854 | efx_oword_t temp; |
1859 | falcon_read(efx, &temp, MAC0_CTRL_REG_KER); | 1855 | falcon_read(efx, &temp, MAC0_CTRL_REG_KER); |
1860 | if (EFX_OWORD_FIELD(temp, TXFIFO_DRAIN_EN_B0)) | 1856 | if (EFX_OWORD_FIELD(temp, TXFIFO_DRAIN_EN_B0)) |
@@ -1938,7 +1934,7 @@ static int falcon_gmii_wait(struct efx_nic *efx) | |||
1938 | static void falcon_mdio_write(struct net_device *net_dev, int phy_id, | 1934 | static void falcon_mdio_write(struct net_device *net_dev, int phy_id, |
1939 | int addr, int value) | 1935 | int addr, int value) |
1940 | { | 1936 | { |
1941 | struct efx_nic *efx = (struct efx_nic *)net_dev->priv; | 1937 | struct efx_nic *efx = net_dev->priv; |
1942 | unsigned int phy_id2 = phy_id & FALCON_PHY_ID_ID_MASK; | 1938 | unsigned int phy_id2 = phy_id & FALCON_PHY_ID_ID_MASK; |
1943 | efx_oword_t reg; | 1939 | efx_oword_t reg; |
1944 | 1940 | ||
@@ -2006,7 +2002,7 @@ static void falcon_mdio_write(struct net_device *net_dev, int phy_id, | |||
2006 | * could be read, -1 will be returned. */ | 2002 | * could be read, -1 will be returned. */ |
2007 | static int falcon_mdio_read(struct net_device *net_dev, int phy_id, int addr) | 2003 | static int falcon_mdio_read(struct net_device *net_dev, int phy_id, int addr) |
2008 | { | 2004 | { |
2009 | struct efx_nic *efx = (struct efx_nic *)net_dev->priv; | 2005 | struct efx_nic *efx = net_dev->priv; |
2010 | unsigned int phy_addr = phy_id & FALCON_PHY_ID_ID_MASK; | 2006 | unsigned int phy_addr = phy_id & FALCON_PHY_ID_ID_MASK; |
2011 | efx_oword_t reg; | 2007 | efx_oword_t reg; |
2012 | int value = -1; | 2008 | int value = -1; |
@@ -2091,6 +2087,8 @@ static int falcon_probe_phy(struct efx_nic *efx) | |||
2091 | efx->phy_type); | 2087 | efx->phy_type); |
2092 | return -1; | 2088 | return -1; |
2093 | } | 2089 | } |
2090 | |||
2091 | efx->loopback_modes = LOOPBACKS_10G_INTERNAL | efx->phy_op->loopbacks; | ||
2094 | return 0; | 2092 | return 0; |
2095 | } | 2093 | } |
2096 | 2094 | ||
@@ -2109,7 +2107,7 @@ int falcon_probe_port(struct efx_nic *efx) | |||
2109 | falcon_init_mdio(&efx->mii); | 2107 | falcon_init_mdio(&efx->mii); |
2110 | 2108 | ||
2111 | /* Hardware flow ctrl. FalconA RX FIFO too small for pause generation */ | 2109 | /* Hardware flow ctrl. FalconA RX FIFO too small for pause generation */ |
2112 | if (FALCON_REV(efx) >= FALCON_REV_B0) | 2110 | if (falcon_rev(efx) >= FALCON_REV_B0) |
2113 | efx->flow_control = EFX_FC_RX | EFX_FC_TX; | 2111 | efx->flow_control = EFX_FC_RX | EFX_FC_TX; |
2114 | else | 2112 | else |
2115 | efx->flow_control = EFX_FC_RX; | 2113 | efx->flow_control = EFX_FC_RX; |
@@ -2369,7 +2367,7 @@ static int falcon_probe_nic_variant(struct efx_nic *efx) | |||
2369 | return -ENODEV; | 2367 | return -ENODEV; |
2370 | } | 2368 | } |
2371 | 2369 | ||
2372 | switch (FALCON_REV(efx)) { | 2370 | switch (falcon_rev(efx)) { |
2373 | case FALCON_REV_A0: | 2371 | case FALCON_REV_A0: |
2374 | case 0xff: | 2372 | case 0xff: |
2375 | EFX_ERR(efx, "Falcon rev A0 not supported\n"); | 2373 | EFX_ERR(efx, "Falcon rev A0 not supported\n"); |
@@ -2395,7 +2393,7 @@ static int falcon_probe_nic_variant(struct efx_nic *efx) | |||
2395 | break; | 2393 | break; |
2396 | 2394 | ||
2397 | default: | 2395 | default: |
2398 | EFX_ERR(efx, "Unknown Falcon rev %d\n", FALCON_REV(efx)); | 2396 | EFX_ERR(efx, "Unknown Falcon rev %d\n", falcon_rev(efx)); |
2399 | return -ENODEV; | 2397 | return -ENODEV; |
2400 | } | 2398 | } |
2401 | 2399 | ||
@@ -2415,7 +2413,7 @@ int falcon_probe_nic(struct efx_nic *efx) | |||
2415 | 2413 | ||
2416 | /* Allocate storage for hardware specific data */ | 2414 | /* Allocate storage for hardware specific data */ |
2417 | nic_data = kzalloc(sizeof(*nic_data), GFP_KERNEL); | 2415 | nic_data = kzalloc(sizeof(*nic_data), GFP_KERNEL); |
2418 | efx->nic_data = (void *) nic_data; | 2416 | efx->nic_data = nic_data; |
2419 | 2417 | ||
2420 | /* Determine number of ports etc. */ | 2418 | /* Determine number of ports etc. */ |
2421 | rc = falcon_probe_nic_variant(efx); | 2419 | rc = falcon_probe_nic_variant(efx); |
@@ -2468,14 +2466,12 @@ int falcon_probe_nic(struct efx_nic *efx) | |||
2468 | fail5: | 2466 | fail5: |
2469 | falcon_free_buffer(efx, &efx->irq_status); | 2467 | falcon_free_buffer(efx, &efx->irq_status); |
2470 | fail4: | 2468 | fail4: |
2471 | /* fall-thru */ | ||
2472 | fail3: | 2469 | fail3: |
2473 | if (nic_data->pci_dev2) { | 2470 | if (nic_data->pci_dev2) { |
2474 | pci_dev_put(nic_data->pci_dev2); | 2471 | pci_dev_put(nic_data->pci_dev2); |
2475 | nic_data->pci_dev2 = NULL; | 2472 | nic_data->pci_dev2 = NULL; |
2476 | } | 2473 | } |
2477 | fail2: | 2474 | fail2: |
2478 | /* fall-thru */ | ||
2479 | fail1: | 2475 | fail1: |
2480 | kfree(efx->nic_data); | 2476 | kfree(efx->nic_data); |
2481 | return rc; | 2477 | return rc; |
@@ -2487,13 +2483,10 @@ int falcon_probe_nic(struct efx_nic *efx) | |||
2487 | */ | 2483 | */ |
2488 | int falcon_init_nic(struct efx_nic *efx) | 2484 | int falcon_init_nic(struct efx_nic *efx) |
2489 | { | 2485 | { |
2490 | struct falcon_nic_data *data; | ||
2491 | efx_oword_t temp; | 2486 | efx_oword_t temp; |
2492 | unsigned thresh; | 2487 | unsigned thresh; |
2493 | int rc; | 2488 | int rc; |
2494 | 2489 | ||
2495 | data = (struct falcon_nic_data *)efx->nic_data; | ||
2496 | |||
2497 | /* Set up the address region register. This is only needed | 2490 | /* Set up the address region register. This is only needed |
2498 | * for the B0 FPGA, but since we are just pushing in the | 2491 | * for the B0 FPGA, but since we are just pushing in the |
2499 | * reset defaults this may as well be unconditional. */ | 2492 | * reset defaults this may as well be unconditional. */ |
@@ -2560,7 +2553,7 @@ int falcon_init_nic(struct efx_nic *efx) | |||
2560 | 2553 | ||
2561 | /* Set number of RSS queues for receive path. */ | 2554 | /* Set number of RSS queues for receive path. */ |
2562 | falcon_read(efx, &temp, RX_FILTER_CTL_REG); | 2555 | falcon_read(efx, &temp, RX_FILTER_CTL_REG); |
2563 | if (FALCON_REV(efx) >= FALCON_REV_B0) | 2556 | if (falcon_rev(efx) >= FALCON_REV_B0) |
2564 | EFX_SET_OWORD_FIELD(temp, NUM_KER, 0); | 2557 | EFX_SET_OWORD_FIELD(temp, NUM_KER, 0); |
2565 | else | 2558 | else |
2566 | EFX_SET_OWORD_FIELD(temp, NUM_KER, efx->rss_queues - 1); | 2559 | EFX_SET_OWORD_FIELD(temp, NUM_KER, efx->rss_queues - 1); |
@@ -2598,7 +2591,7 @@ int falcon_init_nic(struct efx_nic *efx) | |||
2598 | /* Prefetch threshold 2 => fetch when descriptor cache half empty */ | 2591 | /* Prefetch threshold 2 => fetch when descriptor cache half empty */ |
2599 | EFX_SET_OWORD_FIELD(temp, TX_PREF_THRESHOLD, 2); | 2592 | EFX_SET_OWORD_FIELD(temp, TX_PREF_THRESHOLD, 2); |
2600 | /* Squash TX of packets of 16 bytes or less */ | 2593 | /* Squash TX of packets of 16 bytes or less */ |
2601 | if (FALCON_REV(efx) >= FALCON_REV_B0 && EFX_WORKAROUND_9141(efx)) | 2594 | if (falcon_rev(efx) >= FALCON_REV_B0 && EFX_WORKAROUND_9141(efx)) |
2602 | EFX_SET_OWORD_FIELD(temp, TX_FLUSH_MIN_LEN_EN_B0, 1); | 2595 | EFX_SET_OWORD_FIELD(temp, TX_FLUSH_MIN_LEN_EN_B0, 1); |
2603 | falcon_write(efx, &temp, TX_CFG2_REG_KER); | 2596 | falcon_write(efx, &temp, TX_CFG2_REG_KER); |
2604 | 2597 | ||
@@ -2615,7 +2608,7 @@ int falcon_init_nic(struct efx_nic *efx) | |||
2615 | if (EFX_WORKAROUND_7575(efx)) | 2608 | if (EFX_WORKAROUND_7575(efx)) |
2616 | EFX_SET_OWORD_FIELD_VER(efx, temp, RX_USR_BUF_SIZE, | 2609 | EFX_SET_OWORD_FIELD_VER(efx, temp, RX_USR_BUF_SIZE, |
2617 | (3 * 4096) / 32); | 2610 | (3 * 4096) / 32); |
2618 | if (FALCON_REV(efx) >= FALCON_REV_B0) | 2611 | if (falcon_rev(efx) >= FALCON_REV_B0) |
2619 | EFX_SET_OWORD_FIELD(temp, RX_INGR_EN_B0, 1); | 2612 | EFX_SET_OWORD_FIELD(temp, RX_INGR_EN_B0, 1); |
2620 | 2613 | ||
2621 | /* RX FIFO flow control thresholds */ | 2614 | /* RX FIFO flow control thresholds */ |
@@ -2631,7 +2624,7 @@ int falcon_init_nic(struct efx_nic *efx) | |||
2631 | falcon_write(efx, &temp, RX_CFG_REG_KER); | 2624 | falcon_write(efx, &temp, RX_CFG_REG_KER); |
2632 | 2625 | ||
2633 | /* Set destination of both TX and RX Flush events */ | 2626 | /* Set destination of both TX and RX Flush events */ |
2634 | if (FALCON_REV(efx) >= FALCON_REV_B0) { | 2627 | if (falcon_rev(efx) >= FALCON_REV_B0) { |
2635 | EFX_POPULATE_OWORD_1(temp, FLS_EVQ_ID, 0); | 2628 | EFX_POPULATE_OWORD_1(temp, FLS_EVQ_ID, 0); |
2636 | falcon_write(efx, &temp, DP_CTRL_REG); | 2629 | falcon_write(efx, &temp, DP_CTRL_REG); |
2637 | } | 2630 | } |
@@ -2645,7 +2638,7 @@ void falcon_remove_nic(struct efx_nic *efx) | |||
2645 | 2638 | ||
2646 | falcon_free_buffer(efx, &efx->irq_status); | 2639 | falcon_free_buffer(efx, &efx->irq_status); |
2647 | 2640 | ||
2648 | (void) falcon_reset_hw(efx, RESET_TYPE_ALL); | 2641 | falcon_reset_hw(efx, RESET_TYPE_ALL); |
2649 | 2642 | ||
2650 | /* Release the second function after the reset */ | 2643 | /* Release the second function after the reset */ |
2651 | if (nic_data->pci_dev2) { | 2644 | if (nic_data->pci_dev2) { |
diff --git a/drivers/net/sfc/falcon.h b/drivers/net/sfc/falcon.h index 6117403b0c03..492f9bc28840 100644 --- a/drivers/net/sfc/falcon.h +++ b/drivers/net/sfc/falcon.h | |||
@@ -23,7 +23,10 @@ enum falcon_revision { | |||
23 | FALCON_REV_B0 = 2, | 23 | FALCON_REV_B0 = 2, |
24 | }; | 24 | }; |
25 | 25 | ||
26 | #define FALCON_REV(efx) ((efx)->pci_dev->revision) | 26 | static inline int falcon_rev(struct efx_nic *efx) |
27 | { | ||
28 | return efx->pci_dev->revision; | ||
29 | } | ||
27 | 30 | ||
28 | extern struct efx_nic_type falcon_a_nic_type; | 31 | extern struct efx_nic_type falcon_a_nic_type; |
29 | extern struct efx_nic_type falcon_b_nic_type; | 32 | extern struct efx_nic_type falcon_b_nic_type; |
diff --git a/drivers/net/sfc/falcon_hwdefs.h b/drivers/net/sfc/falcon_hwdefs.h index 0485a63eaff6..6d003114eeab 100644 --- a/drivers/net/sfc/falcon_hwdefs.h +++ b/drivers/net/sfc/falcon_hwdefs.h | |||
@@ -636,6 +636,14 @@ | |||
636 | #define XX_HIDRVA_WIDTH 1 | 636 | #define XX_HIDRVA_WIDTH 1 |
637 | #define XX_LODRVA_LBN 8 | 637 | #define XX_LODRVA_LBN 8 |
638 | #define XX_LODRVA_WIDTH 1 | 638 | #define XX_LODRVA_WIDTH 1 |
639 | #define XX_LPBKD_LBN 3 | ||
640 | #define XX_LPBKD_WIDTH 1 | ||
641 | #define XX_LPBKC_LBN 2 | ||
642 | #define XX_LPBKC_WIDTH 1 | ||
643 | #define XX_LPBKB_LBN 1 | ||
644 | #define XX_LPBKB_WIDTH 1 | ||
645 | #define XX_LPBKA_LBN 0 | ||
646 | #define XX_LPBKA_WIDTH 1 | ||
639 | 647 | ||
640 | #define XX_TXDRV_CTL_REG_MAC 0x12 | 648 | #define XX_TXDRV_CTL_REG_MAC 0x12 |
641 | #define XX_DEQD_LBN 28 | 649 | #define XX_DEQD_LBN 28 |
@@ -656,8 +664,14 @@ | |||
656 | #define XX_DTXA_WIDTH 4 | 664 | #define XX_DTXA_WIDTH 4 |
657 | 665 | ||
658 | /* XAUI XGXS core status register */ | 666 | /* XAUI XGXS core status register */ |
659 | #define XX_FORCE_SIG_DECODE_FORCED 0xff | ||
660 | #define XX_CORE_STAT_REG_MAC 0x16 | 667 | #define XX_CORE_STAT_REG_MAC 0x16 |
668 | #define XX_FORCE_SIG_LBN 24 | ||
669 | #define XX_FORCE_SIG_WIDTH 8 | ||
670 | #define XX_FORCE_SIG_DECODE_FORCED 0xff | ||
671 | #define XX_XGXS_LB_EN_LBN 23 | ||
672 | #define XX_XGXS_LB_EN_WIDTH 1 | ||
673 | #define XX_XGMII_LB_EN_LBN 22 | ||
674 | #define XX_XGMII_LB_EN_WIDTH 1 | ||
661 | #define XX_ALIGN_DONE_LBN 20 | 675 | #define XX_ALIGN_DONE_LBN 20 |
662 | #define XX_ALIGN_DONE_WIDTH 1 | 676 | #define XX_ALIGN_DONE_WIDTH 1 |
663 | #define XX_SYNC_STAT_LBN 16 | 677 | #define XX_SYNC_STAT_LBN 16 |
@@ -1111,7 +1125,7 @@ struct falcon_nvconfig_board_v2 { | |||
1111 | u8 port1_phy_type; | 1125 | u8 port1_phy_type; |
1112 | __le16 asic_sub_revision; | 1126 | __le16 asic_sub_revision; |
1113 | __le16 board_revision; | 1127 | __le16 board_revision; |
1114 | } __attribute__ ((packed)); | 1128 | } __packed; |
1115 | 1129 | ||
1116 | #define NVCONFIG_BASE 0x300 | 1130 | #define NVCONFIG_BASE 0x300 |
1117 | #define NVCONFIG_BOARD_MAGIC_NUM 0xFA1C | 1131 | #define NVCONFIG_BOARD_MAGIC_NUM 0xFA1C |
@@ -1130,6 +1144,6 @@ struct falcon_nvconfig { | |||
1130 | __le16 board_struct_ver; | 1144 | __le16 board_struct_ver; |
1131 | __le16 board_checksum; | 1145 | __le16 board_checksum; |
1132 | struct falcon_nvconfig_board_v2 board_v2; | 1146 | struct falcon_nvconfig_board_v2 board_v2; |
1133 | } __attribute__ ((packed)); | 1147 | } __packed; |
1134 | 1148 | ||
1135 | #endif /* EFX_FALCON_HWDEFS_H */ | 1149 | #endif /* EFX_FALCON_HWDEFS_H */ |
diff --git a/drivers/net/sfc/falcon_io.h b/drivers/net/sfc/falcon_io.h index ea08184ddfa9..6670cdfc41ab 100644 --- a/drivers/net/sfc/falcon_io.h +++ b/drivers/net/sfc/falcon_io.h | |||
@@ -56,14 +56,27 @@ | |||
56 | #define FALCON_USE_QWORD_IO 1 | 56 | #define FALCON_USE_QWORD_IO 1 |
57 | #endif | 57 | #endif |
58 | 58 | ||
59 | #define _falcon_writeq(efx, value, reg) \ | 59 | #ifdef FALCON_USE_QWORD_IO |
60 | __raw_writeq((__force u64) (value), (efx)->membase + (reg)) | 60 | static inline void _falcon_writeq(struct efx_nic *efx, __le64 value, |
61 | #define _falcon_writel(efx, value, reg) \ | 61 | unsigned int reg) |
62 | __raw_writel((__force u32) (value), (efx)->membase + (reg)) | 62 | { |
63 | #define _falcon_readq(efx, reg) \ | 63 | __raw_writeq((__force u64)value, efx->membase + reg); |
64 | ((__force __le64) __raw_readq((efx)->membase + (reg))) | 64 | } |
65 | #define _falcon_readl(efx, reg) \ | 65 | static inline __le64 _falcon_readq(struct efx_nic *efx, unsigned int reg) |
66 | ((__force __le32) __raw_readl((efx)->membase + (reg))) | 66 | { |
67 | return (__force __le64)__raw_readq(efx->membase + reg); | ||
68 | } | ||
69 | #endif | ||
70 | |||
71 | static inline void _falcon_writel(struct efx_nic *efx, __le32 value, | ||
72 | unsigned int reg) | ||
73 | { | ||
74 | __raw_writel((__force u32)value, efx->membase + reg); | ||
75 | } | ||
76 | static inline __le32 _falcon_readl(struct efx_nic *efx, unsigned int reg) | ||
77 | { | ||
78 | return (__force __le32)__raw_readl(efx->membase + reg); | ||
79 | } | ||
67 | 80 | ||
68 | /* Writes to a normal 16-byte Falcon register, locking as appropriate. */ | 81 | /* Writes to a normal 16-byte Falcon register, locking as appropriate. */ |
69 | static inline void falcon_write(struct efx_nic *efx, efx_oword_t *value, | 82 | static inline void falcon_write(struct efx_nic *efx, efx_oword_t *value, |
diff --git a/drivers/net/sfc/falcon_xmac.c b/drivers/net/sfc/falcon_xmac.c index aa7521b24a5d..55c0d9760be8 100644 --- a/drivers/net/sfc/falcon_xmac.c +++ b/drivers/net/sfc/falcon_xmac.c | |||
@@ -32,7 +32,7 @@ | |||
32 | (FALCON_XMAC_REGBANK + ((mac_reg) * FALCON_XMAC_REG_SIZE)) | 32 | (FALCON_XMAC_REGBANK + ((mac_reg) * FALCON_XMAC_REG_SIZE)) |
33 | 33 | ||
34 | void falcon_xmac_writel(struct efx_nic *efx, | 34 | void falcon_xmac_writel(struct efx_nic *efx, |
35 | efx_dword_t *value, unsigned int mac_reg) | 35 | efx_dword_t *value, unsigned int mac_reg) |
36 | { | 36 | { |
37 | efx_oword_t temp; | 37 | efx_oword_t temp; |
38 | 38 | ||
@@ -69,6 +69,10 @@ static int falcon_reset_xmac(struct efx_nic *efx) | |||
69 | udelay(10); | 69 | udelay(10); |
70 | } | 70 | } |
71 | 71 | ||
72 | /* This often fails when DSP is disabled, ignore it */ | ||
73 | if (sfe4001_phy_flash_cfg != 0) | ||
74 | return 0; | ||
75 | |||
72 | EFX_ERR(efx, "timed out waiting for XMAC core reset\n"); | 76 | EFX_ERR(efx, "timed out waiting for XMAC core reset\n"); |
73 | return -ETIMEDOUT; | 77 | return -ETIMEDOUT; |
74 | } | 78 | } |
@@ -217,13 +221,13 @@ static int falcon_xgmii_status(struct efx_nic *efx) | |||
217 | { | 221 | { |
218 | efx_dword_t reg; | 222 | efx_dword_t reg; |
219 | 223 | ||
220 | if (FALCON_REV(efx) < FALCON_REV_B0) | 224 | if (falcon_rev(efx) < FALCON_REV_B0) |
221 | return 1; | 225 | return 1; |
222 | 226 | ||
223 | /* The ISR latches, so clear it and re-read */ | 227 | /* The ISR latches, so clear it and re-read */ |
224 | falcon_xmac_readl(efx, ®, XM_MGT_INT_REG_MAC_B0); | 228 | falcon_xmac_readl(efx, ®, XM_MGT_INT_REG_MAC_B0); |
225 | falcon_xmac_readl(efx, ®, XM_MGT_INT_REG_MAC_B0); | 229 | falcon_xmac_readl(efx, ®, XM_MGT_INT_REG_MAC_B0); |
226 | 230 | ||
227 | if (EFX_DWORD_FIELD(reg, XM_LCLFLT) || | 231 | if (EFX_DWORD_FIELD(reg, XM_LCLFLT) || |
228 | EFX_DWORD_FIELD(reg, XM_RMTFLT)) { | 232 | EFX_DWORD_FIELD(reg, XM_RMTFLT)) { |
229 | EFX_INFO(efx, "MGT_INT: "EFX_DWORD_FMT"\n", EFX_DWORD_VAL(reg)); | 233 | EFX_INFO(efx, "MGT_INT: "EFX_DWORD_FMT"\n", EFX_DWORD_VAL(reg)); |
@@ -237,7 +241,7 @@ static void falcon_mask_status_intr(struct efx_nic *efx, int enable) | |||
237 | { | 241 | { |
238 | efx_dword_t reg; | 242 | efx_dword_t reg; |
239 | 243 | ||
240 | if (FALCON_REV(efx) < FALCON_REV_B0) | 244 | if ((falcon_rev(efx) < FALCON_REV_B0) || LOOPBACK_INTERNAL(efx)) |
241 | return; | 245 | return; |
242 | 246 | ||
243 | /* Flush the ISR */ | 247 | /* Flush the ISR */ |
@@ -284,6 +288,9 @@ int falcon_xaui_link_ok(struct efx_nic *efx) | |||
284 | efx_dword_t reg; | 288 | efx_dword_t reg; |
285 | int align_done, sync_status, link_ok = 0; | 289 | int align_done, sync_status, link_ok = 0; |
286 | 290 | ||
291 | if (LOOPBACK_INTERNAL(efx)) | ||
292 | return 1; | ||
293 | |||
287 | /* Read link status */ | 294 | /* Read link status */ |
288 | falcon_xmac_readl(efx, ®, XX_CORE_STAT_REG_MAC); | 295 | falcon_xmac_readl(efx, ®, XX_CORE_STAT_REG_MAC); |
289 | 296 | ||
@@ -374,6 +381,61 @@ static void falcon_reconfigure_xmac_core(struct efx_nic *efx) | |||
374 | falcon_xmac_writel(efx, ®, XM_ADR_HI_REG_MAC); | 381 | falcon_xmac_writel(efx, ®, XM_ADR_HI_REG_MAC); |
375 | } | 382 | } |
376 | 383 | ||
384 | static void falcon_reconfigure_xgxs_core(struct efx_nic *efx) | ||
385 | { | ||
386 | efx_dword_t reg; | ||
387 | int xgxs_loopback = (efx->loopback_mode == LOOPBACK_XGXS) ? 1 : 0; | ||
388 | int xaui_loopback = (efx->loopback_mode == LOOPBACK_XAUI) ? 1 : 0; | ||
389 | int xgmii_loopback = | ||
390 | (efx->loopback_mode == LOOPBACK_XGMII) ? 1 : 0; | ||
391 | |||
392 | /* XGXS block is flaky and will need to be reset if moving | ||
393 | * into our out of XGMII, XGXS or XAUI loopbacks. */ | ||
394 | if (EFX_WORKAROUND_5147(efx)) { | ||
395 | int old_xgmii_loopback, old_xgxs_loopback, old_xaui_loopback; | ||
396 | int reset_xgxs; | ||
397 | |||
398 | falcon_xmac_readl(efx, ®, XX_CORE_STAT_REG_MAC); | ||
399 | old_xgxs_loopback = EFX_DWORD_FIELD(reg, XX_XGXS_LB_EN); | ||
400 | old_xgmii_loopback = EFX_DWORD_FIELD(reg, XX_XGMII_LB_EN); | ||
401 | |||
402 | falcon_xmac_readl(efx, ®, XX_SD_CTL_REG_MAC); | ||
403 | old_xaui_loopback = EFX_DWORD_FIELD(reg, XX_LPBKA); | ||
404 | |||
405 | /* The PHY driver may have turned XAUI off */ | ||
406 | reset_xgxs = ((xgxs_loopback != old_xgxs_loopback) || | ||
407 | (xaui_loopback != old_xaui_loopback) || | ||
408 | (xgmii_loopback != old_xgmii_loopback)); | ||
409 | if (reset_xgxs) { | ||
410 | falcon_xmac_readl(efx, ®, XX_PWR_RST_REG_MAC); | ||
411 | EFX_SET_DWORD_FIELD(reg, XX_RSTXGXSTX_EN, 1); | ||
412 | EFX_SET_DWORD_FIELD(reg, XX_RSTXGXSRX_EN, 1); | ||
413 | falcon_xmac_writel(efx, ®, XX_PWR_RST_REG_MAC); | ||
414 | udelay(1); | ||
415 | EFX_SET_DWORD_FIELD(reg, XX_RSTXGXSTX_EN, 0); | ||
416 | EFX_SET_DWORD_FIELD(reg, XX_RSTXGXSRX_EN, 0); | ||
417 | falcon_xmac_writel(efx, ®, XX_PWR_RST_REG_MAC); | ||
418 | udelay(1); | ||
419 | } | ||
420 | } | ||
421 | |||
422 | falcon_xmac_readl(efx, ®, XX_CORE_STAT_REG_MAC); | ||
423 | EFX_SET_DWORD_FIELD(reg, XX_FORCE_SIG, | ||
424 | (xgxs_loopback || xaui_loopback) ? | ||
425 | XX_FORCE_SIG_DECODE_FORCED : 0); | ||
426 | EFX_SET_DWORD_FIELD(reg, XX_XGXS_LB_EN, xgxs_loopback); | ||
427 | EFX_SET_DWORD_FIELD(reg, XX_XGMII_LB_EN, xgmii_loopback); | ||
428 | falcon_xmac_writel(efx, ®, XX_CORE_STAT_REG_MAC); | ||
429 | |||
430 | falcon_xmac_readl(efx, ®, XX_SD_CTL_REG_MAC); | ||
431 | EFX_SET_DWORD_FIELD(reg, XX_LPBKD, xaui_loopback); | ||
432 | EFX_SET_DWORD_FIELD(reg, XX_LPBKC, xaui_loopback); | ||
433 | EFX_SET_DWORD_FIELD(reg, XX_LPBKB, xaui_loopback); | ||
434 | EFX_SET_DWORD_FIELD(reg, XX_LPBKA, xaui_loopback); | ||
435 | falcon_xmac_writel(efx, ®, XX_SD_CTL_REG_MAC); | ||
436 | } | ||
437 | |||
438 | |||
377 | /* Try and bring the Falcon side of the Falcon-Phy XAUI link fails | 439 | /* Try and bring the Falcon side of the Falcon-Phy XAUI link fails |
378 | * to come back up. Bash it until it comes back up */ | 440 | * to come back up. Bash it until it comes back up */ |
379 | static int falcon_check_xaui_link_up(struct efx_nic *efx) | 441 | static int falcon_check_xaui_link_up(struct efx_nic *efx) |
@@ -382,7 +444,8 @@ static int falcon_check_xaui_link_up(struct efx_nic *efx) | |||
382 | tries = EFX_WORKAROUND_5147(efx) ? 5 : 1; | 444 | tries = EFX_WORKAROUND_5147(efx) ? 5 : 1; |
383 | max_tries = tries; | 445 | max_tries = tries; |
384 | 446 | ||
385 | if (efx->phy_type == PHY_TYPE_NONE) | 447 | if ((efx->loopback_mode == LOOPBACK_NETWORK) || |
448 | (efx->phy_type == PHY_TYPE_NONE)) | ||
386 | return 0; | 449 | return 0; |
387 | 450 | ||
388 | while (tries) { | 451 | while (tries) { |
@@ -391,12 +454,12 @@ static int falcon_check_xaui_link_up(struct efx_nic *efx) | |||
391 | 454 | ||
392 | EFX_LOG(efx, "%s Clobbering XAUI (%d tries left).\n", | 455 | EFX_LOG(efx, "%s Clobbering XAUI (%d tries left).\n", |
393 | __func__, tries); | 456 | __func__, tries); |
394 | (void) falcon_reset_xaui(efx); | 457 | falcon_reset_xaui(efx); |
395 | udelay(200); | 458 | udelay(200); |
396 | tries--; | 459 | tries--; |
397 | } | 460 | } |
398 | 461 | ||
399 | EFX_ERR(efx, "Failed to bring XAUI link back up in %d tries!\n", | 462 | EFX_LOG(efx, "Failed to bring XAUI link back up in %d tries!\n", |
400 | max_tries); | 463 | max_tries); |
401 | return 0; | 464 | return 0; |
402 | } | 465 | } |
@@ -408,8 +471,13 @@ void falcon_reconfigure_xmac(struct efx_nic *efx) | |||
408 | falcon_mask_status_intr(efx, 0); | 471 | falcon_mask_status_intr(efx, 0); |
409 | 472 | ||
410 | falcon_deconfigure_mac_wrapper(efx); | 473 | falcon_deconfigure_mac_wrapper(efx); |
474 | |||
475 | efx->tx_disabled = LOOPBACK_INTERNAL(efx); | ||
411 | efx->phy_op->reconfigure(efx); | 476 | efx->phy_op->reconfigure(efx); |
477 | |||
478 | falcon_reconfigure_xgxs_core(efx); | ||
412 | falcon_reconfigure_xmac_core(efx); | 479 | falcon_reconfigure_xmac_core(efx); |
480 | |||
413 | falcon_reconfigure_mac_wrapper(efx); | 481 | falcon_reconfigure_mac_wrapper(efx); |
414 | 482 | ||
415 | /* Ensure XAUI link is up */ | 483 | /* Ensure XAUI link is up */ |
@@ -491,18 +559,20 @@ void falcon_update_stats_xmac(struct efx_nic *efx) | |||
491 | (mac_stats->rx_bytes - mac_stats->rx_good_bytes); | 559 | (mac_stats->rx_bytes - mac_stats->rx_good_bytes); |
492 | } | 560 | } |
493 | 561 | ||
494 | #define EFX_XAUI_RETRAIN_MAX 8 | ||
495 | |||
496 | int falcon_check_xmac(struct efx_nic *efx) | 562 | int falcon_check_xmac(struct efx_nic *efx) |
497 | { | 563 | { |
498 | unsigned xaui_link_ok; | 564 | unsigned xaui_link_ok; |
499 | int rc; | 565 | int rc; |
500 | 566 | ||
567 | if ((efx->loopback_mode == LOOPBACK_NETWORK) || | ||
568 | (efx->phy_type == PHY_TYPE_NONE)) | ||
569 | return 0; | ||
570 | |||
501 | falcon_mask_status_intr(efx, 0); | 571 | falcon_mask_status_intr(efx, 0); |
502 | xaui_link_ok = falcon_xaui_link_ok(efx); | 572 | xaui_link_ok = falcon_xaui_link_ok(efx); |
503 | 573 | ||
504 | if (EFX_WORKAROUND_5147(efx) && !xaui_link_ok) | 574 | if (EFX_WORKAROUND_5147(efx) && !xaui_link_ok) |
505 | (void) falcon_reset_xaui(efx); | 575 | falcon_reset_xaui(efx); |
506 | 576 | ||
507 | /* Call the PHY check_hw routine */ | 577 | /* Call the PHY check_hw routine */ |
508 | rc = efx->phy_op->check_hw(efx); | 578 | rc = efx->phy_op->check_hw(efx); |
@@ -569,7 +639,7 @@ int falcon_xmac_set_pause(struct efx_nic *efx, enum efx_fc_type flow_control) | |||
569 | reset = ((flow_control & EFX_FC_TX) && | 639 | reset = ((flow_control & EFX_FC_TX) && |
570 | !(efx->flow_control & EFX_FC_TX)); | 640 | !(efx->flow_control & EFX_FC_TX)); |
571 | if (EFX_WORKAROUND_11482(efx) && reset) { | 641 | if (EFX_WORKAROUND_11482(efx) && reset) { |
572 | if (FALCON_REV(efx) >= FALCON_REV_B0) { | 642 | if (falcon_rev(efx) >= FALCON_REV_B0) { |
573 | /* Recover by resetting the EM block */ | 643 | /* Recover by resetting the EM block */ |
574 | if (efx->link_up) | 644 | if (efx->link_up) |
575 | falcon_drain_tx_fifo(efx); | 645 | falcon_drain_tx_fifo(efx); |
diff --git a/drivers/net/sfc/mdio_10g.c b/drivers/net/sfc/mdio_10g.c index dc06bb0aa575..c4f540e93b79 100644 --- a/drivers/net/sfc/mdio_10g.c +++ b/drivers/net/sfc/mdio_10g.c | |||
@@ -44,6 +44,9 @@ static int mdio_clause45_check_mmd(struct efx_nic *efx, int mmd, | |||
44 | int status; | 44 | int status; |
45 | int phy_id = efx->mii.phy_id; | 45 | int phy_id = efx->mii.phy_id; |
46 | 46 | ||
47 | if (LOOPBACK_INTERNAL(efx)) | ||
48 | return 0; | ||
49 | |||
47 | /* Read MMD STATUS2 to check it is responding. */ | 50 | /* Read MMD STATUS2 to check it is responding. */ |
48 | status = mdio_clause45_read(efx, phy_id, mmd, MDIO_MMDREG_STAT2); | 51 | status = mdio_clause45_read(efx, phy_id, mmd, MDIO_MMDREG_STAT2); |
49 | if (((status >> MDIO_MMDREG_STAT2_PRESENT_LBN) & | 52 | if (((status >> MDIO_MMDREG_STAT2_PRESENT_LBN) & |
@@ -164,6 +167,22 @@ int mdio_clause45_links_ok(struct efx_nic *efx, unsigned int mmd_mask) | |||
164 | int mmd = 0; | 167 | int mmd = 0; |
165 | int good; | 168 | int good; |
166 | 169 | ||
170 | /* If the port is in loopback, then we should only consider a subset | ||
171 | * of mmd's */ | ||
172 | if (LOOPBACK_INTERNAL(efx)) | ||
173 | return 1; | ||
174 | else if (efx->loopback_mode == LOOPBACK_NETWORK) | ||
175 | return 0; | ||
176 | else if (efx->loopback_mode == LOOPBACK_PHYXS) | ||
177 | mmd_mask &= ~(MDIO_MMDREG_DEVS0_PHYXS | | ||
178 | MDIO_MMDREG_DEVS0_PCS | | ||
179 | MDIO_MMDREG_DEVS0_PMAPMD); | ||
180 | else if (efx->loopback_mode == LOOPBACK_PCS) | ||
181 | mmd_mask &= ~(MDIO_MMDREG_DEVS0_PCS | | ||
182 | MDIO_MMDREG_DEVS0_PMAPMD); | ||
183 | else if (efx->loopback_mode == LOOPBACK_PMAPMD) | ||
184 | mmd_mask &= ~MDIO_MMDREG_DEVS0_PMAPMD; | ||
185 | |||
167 | while (mmd_mask) { | 186 | while (mmd_mask) { |
168 | if (mmd_mask & 1) { | 187 | if (mmd_mask & 1) { |
169 | /* Double reads because link state is latched, and a | 188 | /* Double reads because link state is latched, and a |
@@ -182,6 +201,65 @@ int mdio_clause45_links_ok(struct efx_nic *efx, unsigned int mmd_mask) | |||
182 | return ok; | 201 | return ok; |
183 | } | 202 | } |
184 | 203 | ||
204 | void mdio_clause45_transmit_disable(struct efx_nic *efx) | ||
205 | { | ||
206 | int phy_id = efx->mii.phy_id; | ||
207 | int ctrl1, ctrl2; | ||
208 | |||
209 | ctrl1 = ctrl2 = mdio_clause45_read(efx, phy_id, MDIO_MMD_PMAPMD, | ||
210 | MDIO_MMDREG_TXDIS); | ||
211 | if (efx->tx_disabled) | ||
212 | ctrl2 |= (1 << MDIO_MMDREG_TXDIS_GLOBAL_LBN); | ||
213 | else | ||
214 | ctrl1 &= ~(1 << MDIO_MMDREG_TXDIS_GLOBAL_LBN); | ||
215 | if (ctrl1 != ctrl2) | ||
216 | mdio_clause45_write(efx, phy_id, MDIO_MMD_PMAPMD, | ||
217 | MDIO_MMDREG_TXDIS, ctrl2); | ||
218 | } | ||
219 | |||
220 | void mdio_clause45_phy_reconfigure(struct efx_nic *efx) | ||
221 | { | ||
222 | int phy_id = efx->mii.phy_id; | ||
223 | int ctrl1, ctrl2; | ||
224 | |||
225 | /* Handle (with debouncing) PMA/PMD loopback */ | ||
226 | ctrl1 = ctrl2 = mdio_clause45_read(efx, phy_id, MDIO_MMD_PMAPMD, | ||
227 | MDIO_MMDREG_CTRL1); | ||
228 | |||
229 | if (efx->loopback_mode == LOOPBACK_PMAPMD) | ||
230 | ctrl2 |= (1 << MDIO_PMAPMD_CTRL1_LBACK_LBN); | ||
231 | else | ||
232 | ctrl2 &= ~(1 << MDIO_PMAPMD_CTRL1_LBACK_LBN); | ||
233 | |||
234 | if (ctrl1 != ctrl2) | ||
235 | mdio_clause45_write(efx, phy_id, MDIO_MMD_PMAPMD, | ||
236 | MDIO_MMDREG_CTRL1, ctrl2); | ||
237 | |||
238 | /* Handle (with debouncing) PCS loopback */ | ||
239 | ctrl1 = ctrl2 = mdio_clause45_read(efx, phy_id, MDIO_MMD_PCS, | ||
240 | MDIO_MMDREG_CTRL1); | ||
241 | if (efx->loopback_mode == LOOPBACK_PCS) | ||
242 | ctrl2 |= (1 << MDIO_MMDREG_CTRL1_LBACK_LBN); | ||
243 | else | ||
244 | ctrl2 &= ~(1 << MDIO_MMDREG_CTRL1_LBACK_LBN); | ||
245 | |||
246 | if (ctrl1 != ctrl2) | ||
247 | mdio_clause45_write(efx, phy_id, MDIO_MMD_PCS, | ||
248 | MDIO_MMDREG_CTRL1, ctrl2); | ||
249 | |||
250 | /* Handle (with debouncing) PHYXS network loopback */ | ||
251 | ctrl1 = ctrl2 = mdio_clause45_read(efx, phy_id, MDIO_MMD_PHYXS, | ||
252 | MDIO_MMDREG_CTRL1); | ||
253 | if (efx->loopback_mode == LOOPBACK_NETWORK) | ||
254 | ctrl2 |= (1 << MDIO_MMDREG_CTRL1_LBACK_LBN); | ||
255 | else | ||
256 | ctrl2 &= ~(1 << MDIO_MMDREG_CTRL1_LBACK_LBN); | ||
257 | |||
258 | if (ctrl1 != ctrl2) | ||
259 | mdio_clause45_write(efx, phy_id, MDIO_MMD_PHYXS, | ||
260 | MDIO_MMDREG_CTRL1, ctrl2); | ||
261 | } | ||
262 | |||
185 | /** | 263 | /** |
186 | * mdio_clause45_get_settings - Read (some of) the PHY settings over MDIO. | 264 | * mdio_clause45_get_settings - Read (some of) the PHY settings over MDIO. |
187 | * @efx: Efx NIC | 265 | * @efx: Efx NIC |
diff --git a/drivers/net/sfc/mdio_10g.h b/drivers/net/sfc/mdio_10g.h index 2214b6d820a7..cb99f3f4491c 100644 --- a/drivers/net/sfc/mdio_10g.h +++ b/drivers/net/sfc/mdio_10g.h | |||
@@ -44,11 +44,16 @@ | |||
44 | #define MDIO_MMDREG_DEVS1 (6) | 44 | #define MDIO_MMDREG_DEVS1 (6) |
45 | #define MDIO_MMDREG_CTRL2 (7) | 45 | #define MDIO_MMDREG_CTRL2 (7) |
46 | #define MDIO_MMDREG_STAT2 (8) | 46 | #define MDIO_MMDREG_STAT2 (8) |
47 | #define MDIO_MMDREG_TXDIS (9) | ||
47 | 48 | ||
48 | /* Bits in MMDREG_CTRL1 */ | 49 | /* Bits in MMDREG_CTRL1 */ |
49 | /* Reset */ | 50 | /* Reset */ |
50 | #define MDIO_MMDREG_CTRL1_RESET_LBN (15) | 51 | #define MDIO_MMDREG_CTRL1_RESET_LBN (15) |
51 | #define MDIO_MMDREG_CTRL1_RESET_WIDTH (1) | 52 | #define MDIO_MMDREG_CTRL1_RESET_WIDTH (1) |
53 | /* Loopback */ | ||
54 | /* Loopback bit for WIS, PCS, PHYSX and DTEXS */ | ||
55 | #define MDIO_MMDREG_CTRL1_LBACK_LBN (14) | ||
56 | #define MDIO_MMDREG_CTRL1_LBACK_WIDTH (1) | ||
52 | 57 | ||
53 | /* Bits in MMDREG_STAT1 */ | 58 | /* Bits in MMDREG_STAT1 */ |
54 | #define MDIO_MMDREG_STAT1_FAULT_LBN (7) | 59 | #define MDIO_MMDREG_STAT1_FAULT_LBN (7) |
@@ -56,6 +61,9 @@ | |||
56 | /* Link state */ | 61 | /* Link state */ |
57 | #define MDIO_MMDREG_STAT1_LINK_LBN (2) | 62 | #define MDIO_MMDREG_STAT1_LINK_LBN (2) |
58 | #define MDIO_MMDREG_STAT1_LINK_WIDTH (1) | 63 | #define MDIO_MMDREG_STAT1_LINK_WIDTH (1) |
64 | /* Low power ability */ | ||
65 | #define MDIO_MMDREG_STAT1_LPABLE_LBN (1) | ||
66 | #define MDIO_MMDREG_STAT1_LPABLE_WIDTH (1) | ||
59 | 67 | ||
60 | /* Bits in ID reg */ | 68 | /* Bits in ID reg */ |
61 | #define MDIO_ID_REV(_id32) (_id32 & 0xf) | 69 | #define MDIO_ID_REV(_id32) (_id32 & 0xf) |
@@ -76,6 +84,14 @@ | |||
76 | #define MDIO_MMDREG_STAT2_PRESENT_LBN (14) | 84 | #define MDIO_MMDREG_STAT2_PRESENT_LBN (14) |
77 | #define MDIO_MMDREG_STAT2_PRESENT_WIDTH (2) | 85 | #define MDIO_MMDREG_STAT2_PRESENT_WIDTH (2) |
78 | 86 | ||
87 | /* Bits in MMDREG_TXDIS */ | ||
88 | #define MDIO_MMDREG_TXDIS_GLOBAL_LBN (0) | ||
89 | #define MDIO_MMDREG_TXDIS_GLOBAL_WIDTH (1) | ||
90 | |||
91 | /* MMD-specific bits, ordered by MMD, then register */ | ||
92 | #define MDIO_PMAPMD_CTRL1_LBACK_LBN (0) | ||
93 | #define MDIO_PMAPMD_CTRL1_LBACK_WIDTH (1) | ||
94 | |||
79 | /* PMA type (4 bits) */ | 95 | /* PMA type (4 bits) */ |
80 | #define MDIO_PMAPMD_CTRL2_10G_CX4 (0x0) | 96 | #define MDIO_PMAPMD_CTRL2_10G_CX4 (0x0) |
81 | #define MDIO_PMAPMD_CTRL2_10G_EW (0x1) | 97 | #define MDIO_PMAPMD_CTRL2_10G_EW (0x1) |
@@ -95,7 +111,7 @@ | |||
95 | #define MDIO_PMAPMD_CTRL2_10_BT (0xf) | 111 | #define MDIO_PMAPMD_CTRL2_10_BT (0xf) |
96 | #define MDIO_PMAPMD_CTRL2_TYPE_MASK (0xf) | 112 | #define MDIO_PMAPMD_CTRL2_TYPE_MASK (0xf) |
97 | 113 | ||
98 | /* /\* PHY XGXS lane state *\/ */ | 114 | /* PHY XGXS lane state */ |
99 | #define MDIO_PHYXS_LANE_STATE (0x18) | 115 | #define MDIO_PHYXS_LANE_STATE (0x18) |
100 | #define MDIO_PHYXS_LANE_ALIGNED_LBN (12) | 116 | #define MDIO_PHYXS_LANE_ALIGNED_LBN (12) |
101 | 117 | ||
@@ -217,6 +233,12 @@ int mdio_clause45_check_mmds(struct efx_nic *efx, | |||
217 | extern int mdio_clause45_links_ok(struct efx_nic *efx, | 233 | extern int mdio_clause45_links_ok(struct efx_nic *efx, |
218 | unsigned int mmd_mask); | 234 | unsigned int mmd_mask); |
219 | 235 | ||
236 | /* Generic transmit disable support though PMAPMD */ | ||
237 | extern void mdio_clause45_transmit_disable(struct efx_nic *efx); | ||
238 | |||
239 | /* Generic part of reconfigure: set/clear loopback bits */ | ||
240 | extern void mdio_clause45_phy_reconfigure(struct efx_nic *efx); | ||
241 | |||
220 | /* Read (some of) the PHY settings over MDIO */ | 242 | /* Read (some of) the PHY settings over MDIO */ |
221 | extern void mdio_clause45_get_settings(struct efx_nic *efx, | 243 | extern void mdio_clause45_get_settings(struct efx_nic *efx, |
222 | struct ethtool_cmd *ecmd); | 244 | struct ethtool_cmd *ecmd); |
diff --git a/drivers/net/sfc/net_driver.h b/drivers/net/sfc/net_driver.h index c505482c2520..5e20e7551dae 100644 --- a/drivers/net/sfc/net_driver.h +++ b/drivers/net/sfc/net_driver.h | |||
@@ -42,7 +42,7 @@ | |||
42 | #ifndef EFX_DRIVER_NAME | 42 | #ifndef EFX_DRIVER_NAME |
43 | #define EFX_DRIVER_NAME "sfc" | 43 | #define EFX_DRIVER_NAME "sfc" |
44 | #endif | 44 | #endif |
45 | #define EFX_DRIVER_VERSION "2.2.0136" | 45 | #define EFX_DRIVER_VERSION "2.2" |
46 | 46 | ||
47 | #ifdef EFX_ENABLE_DEBUG | 47 | #ifdef EFX_ENABLE_DEBUG |
48 | #define EFX_BUG_ON_PARANOID(x) BUG_ON(x) | 48 | #define EFX_BUG_ON_PARANOID(x) BUG_ON(x) |
@@ -52,28 +52,19 @@ | |||
52 | #define EFX_WARN_ON_PARANOID(x) do {} while (0) | 52 | #define EFX_WARN_ON_PARANOID(x) do {} while (0) |
53 | #endif | 53 | #endif |
54 | 54 | ||
55 | #define NET_DEV_REGISTERED(efx) \ | ||
56 | ((efx)->net_dev->reg_state == NETREG_REGISTERED) | ||
57 | |||
58 | /* Include net device name in log messages if it has been registered. | ||
59 | * Use efx->name not efx->net_dev->name so that races with (un)registration | ||
60 | * are harmless. | ||
61 | */ | ||
62 | #define NET_DEV_NAME(efx) (NET_DEV_REGISTERED(efx) ? (efx)->name : "") | ||
63 | |||
64 | /* Un-rate-limited logging */ | 55 | /* Un-rate-limited logging */ |
65 | #define EFX_ERR(efx, fmt, args...) \ | 56 | #define EFX_ERR(efx, fmt, args...) \ |
66 | dev_err(&((efx)->pci_dev->dev), "ERR: %s " fmt, NET_DEV_NAME(efx), ##args) | 57 | dev_err(&((efx)->pci_dev->dev), "ERR: %s " fmt, efx_dev_name(efx), ##args) |
67 | 58 | ||
68 | #define EFX_INFO(efx, fmt, args...) \ | 59 | #define EFX_INFO(efx, fmt, args...) \ |
69 | dev_info(&((efx)->pci_dev->dev), "INFO: %s " fmt, NET_DEV_NAME(efx), ##args) | 60 | dev_info(&((efx)->pci_dev->dev), "INFO: %s " fmt, efx_dev_name(efx), ##args) |
70 | 61 | ||
71 | #ifdef EFX_ENABLE_DEBUG | 62 | #ifdef EFX_ENABLE_DEBUG |
72 | #define EFX_LOG(efx, fmt, args...) \ | 63 | #define EFX_LOG(efx, fmt, args...) \ |
73 | dev_info(&((efx)->pci_dev->dev), "DBG: %s " fmt, NET_DEV_NAME(efx), ##args) | 64 | dev_info(&((efx)->pci_dev->dev), "DBG: %s " fmt, efx_dev_name(efx), ##args) |
74 | #else | 65 | #else |
75 | #define EFX_LOG(efx, fmt, args...) \ | 66 | #define EFX_LOG(efx, fmt, args...) \ |
76 | dev_dbg(&((efx)->pci_dev->dev), "DBG: %s " fmt, NET_DEV_NAME(efx), ##args) | 67 | dev_dbg(&((efx)->pci_dev->dev), "DBG: %s " fmt, efx_dev_name(efx), ##args) |
77 | #endif | 68 | #endif |
78 | 69 | ||
79 | #define EFX_TRACE(efx, fmt, args...) do {} while (0) | 70 | #define EFX_TRACE(efx, fmt, args...) do {} while (0) |
@@ -90,11 +81,6 @@ do {if (net_ratelimit()) EFX_INFO(efx, fmt, ##args); } while (0) | |||
90 | #define EFX_LOG_RL(efx, fmt, args...) \ | 81 | #define EFX_LOG_RL(efx, fmt, args...) \ |
91 | do {if (net_ratelimit()) EFX_LOG(efx, fmt, ##args); } while (0) | 82 | do {if (net_ratelimit()) EFX_LOG(efx, fmt, ##args); } while (0) |
92 | 83 | ||
93 | /* Kernel headers may redefine inline anyway */ | ||
94 | #ifndef inline | ||
95 | #define inline inline __attribute__ ((always_inline)) | ||
96 | #endif | ||
97 | |||
98 | /************************************************************************** | 84 | /************************************************************************** |
99 | * | 85 | * |
100 | * Efx data structures | 86 | * Efx data structures |
@@ -134,6 +120,8 @@ struct efx_special_buffer { | |||
134 | * Set only on the final fragment of a packet; %NULL for all other | 120 | * Set only on the final fragment of a packet; %NULL for all other |
135 | * fragments. When this fragment completes, then we can free this | 121 | * fragments. When this fragment completes, then we can free this |
136 | * skb. | 122 | * skb. |
123 | * @tsoh: The associated TSO header structure, or %NULL if this | ||
124 | * buffer is not a TSO header. | ||
137 | * @dma_addr: DMA address of the fragment. | 125 | * @dma_addr: DMA address of the fragment. |
138 | * @len: Length of this fragment. | 126 | * @len: Length of this fragment. |
139 | * This field is zero when the queue slot is empty. | 127 | * This field is zero when the queue slot is empty. |
@@ -144,6 +132,7 @@ struct efx_special_buffer { | |||
144 | */ | 132 | */ |
145 | struct efx_tx_buffer { | 133 | struct efx_tx_buffer { |
146 | const struct sk_buff *skb; | 134 | const struct sk_buff *skb; |
135 | struct efx_tso_header *tsoh; | ||
147 | dma_addr_t dma_addr; | 136 | dma_addr_t dma_addr; |
148 | unsigned short len; | 137 | unsigned short len; |
149 | unsigned char continuation; | 138 | unsigned char continuation; |
@@ -187,6 +176,13 @@ struct efx_tx_buffer { | |||
187 | * variable indicates that the queue is full. This is to | 176 | * variable indicates that the queue is full. This is to |
188 | * avoid cache-line ping-pong between the xmit path and the | 177 | * avoid cache-line ping-pong between the xmit path and the |
189 | * completion path. | 178 | * completion path. |
179 | * @tso_headers_free: A list of TSO headers allocated for this TX queue | ||
180 | * that are not in use, and so available for new TSO sends. The list | ||
181 | * is protected by the TX queue lock. | ||
182 | * @tso_bursts: Number of times TSO xmit invoked by kernel | ||
183 | * @tso_long_headers: Number of packets with headers too long for standard | ||
184 | * blocks | ||
185 | * @tso_packets: Number of packets via the TSO xmit path | ||
190 | */ | 186 | */ |
191 | struct efx_tx_queue { | 187 | struct efx_tx_queue { |
192 | /* Members which don't change on the fast path */ | 188 | /* Members which don't change on the fast path */ |
@@ -206,6 +202,10 @@ struct efx_tx_queue { | |||
206 | unsigned int insert_count ____cacheline_aligned_in_smp; | 202 | unsigned int insert_count ____cacheline_aligned_in_smp; |
207 | unsigned int write_count; | 203 | unsigned int write_count; |
208 | unsigned int old_read_count; | 204 | unsigned int old_read_count; |
205 | struct efx_tso_header *tso_headers_free; | ||
206 | unsigned int tso_bursts; | ||
207 | unsigned int tso_long_headers; | ||
208 | unsigned int tso_packets; | ||
209 | }; | 209 | }; |
210 | 210 | ||
211 | /** | 211 | /** |
@@ -434,6 +434,9 @@ struct efx_board { | |||
434 | struct efx_blinker blinker; | 434 | struct efx_blinker blinker; |
435 | }; | 435 | }; |
436 | 436 | ||
437 | #define STRING_TABLE_LOOKUP(val, member) \ | ||
438 | member ## _names[val] | ||
439 | |||
437 | enum efx_int_mode { | 440 | enum efx_int_mode { |
438 | /* Be careful if altering to correct macro below */ | 441 | /* Be careful if altering to correct macro below */ |
439 | EFX_INT_MODE_MSIX = 0, | 442 | EFX_INT_MODE_MSIX = 0, |
@@ -506,6 +509,7 @@ enum efx_fc_type { | |||
506 | * @check_hw: Check hardware | 509 | * @check_hw: Check hardware |
507 | * @reset_xaui: Reset XAUI side of PHY for (software sequenced reset) | 510 | * @reset_xaui: Reset XAUI side of PHY for (software sequenced reset) |
508 | * @mmds: MMD presence mask | 511 | * @mmds: MMD presence mask |
512 | * @loopbacks: Supported loopback modes mask | ||
509 | */ | 513 | */ |
510 | struct efx_phy_operations { | 514 | struct efx_phy_operations { |
511 | int (*init) (struct efx_nic *efx); | 515 | int (*init) (struct efx_nic *efx); |
@@ -515,6 +519,7 @@ struct efx_phy_operations { | |||
515 | int (*check_hw) (struct efx_nic *efx); | 519 | int (*check_hw) (struct efx_nic *efx); |
516 | void (*reset_xaui) (struct efx_nic *efx); | 520 | void (*reset_xaui) (struct efx_nic *efx); |
517 | int mmds; | 521 | int mmds; |
522 | unsigned loopbacks; | ||
518 | }; | 523 | }; |
519 | 524 | ||
520 | /* | 525 | /* |
@@ -653,7 +658,6 @@ union efx_multicast_hash { | |||
653 | * @phy_op: PHY interface | 658 | * @phy_op: PHY interface |
654 | * @phy_data: PHY private data (including PHY-specific stats) | 659 | * @phy_data: PHY private data (including PHY-specific stats) |
655 | * @mii: PHY interface | 660 | * @mii: PHY interface |
656 | * @phy_powered: PHY power state | ||
657 | * @tx_disabled: PHY transmitter turned off | 661 | * @tx_disabled: PHY transmitter turned off |
658 | * @link_up: Link status | 662 | * @link_up: Link status |
659 | * @link_options: Link options (MII/GMII format) | 663 | * @link_options: Link options (MII/GMII format) |
@@ -662,6 +666,9 @@ union efx_multicast_hash { | |||
662 | * @multicast_hash: Multicast hash table | 666 | * @multicast_hash: Multicast hash table |
663 | * @flow_control: Flow control flags - separate RX/TX so can't use link_options | 667 | * @flow_control: Flow control flags - separate RX/TX so can't use link_options |
664 | * @reconfigure_work: work item for dealing with PHY events | 668 | * @reconfigure_work: work item for dealing with PHY events |
669 | * @loopback_mode: Loopback status | ||
670 | * @loopback_modes: Supported loopback mode bitmask | ||
671 | * @loopback_selftest: Offline self-test private state | ||
665 | * | 672 | * |
666 | * The @priv field of the corresponding &struct net_device points to | 673 | * The @priv field of the corresponding &struct net_device points to |
667 | * this. | 674 | * this. |
@@ -674,7 +681,7 @@ struct efx_nic { | |||
674 | struct workqueue_struct *workqueue; | 681 | struct workqueue_struct *workqueue; |
675 | struct work_struct reset_work; | 682 | struct work_struct reset_work; |
676 | struct delayed_work monitor_work; | 683 | struct delayed_work monitor_work; |
677 | unsigned long membase_phys; | 684 | resource_size_t membase_phys; |
678 | void __iomem *membase; | 685 | void __iomem *membase; |
679 | spinlock_t biu_lock; | 686 | spinlock_t biu_lock; |
680 | enum efx_int_mode interrupt_mode; | 687 | enum efx_int_mode interrupt_mode; |
@@ -698,7 +705,7 @@ struct efx_nic { | |||
698 | 705 | ||
699 | unsigned n_rx_nodesc_drop_cnt; | 706 | unsigned n_rx_nodesc_drop_cnt; |
700 | 707 | ||
701 | void *nic_data; | 708 | struct falcon_nic_data *nic_data; |
702 | 709 | ||
703 | struct mutex mac_lock; | 710 | struct mutex mac_lock; |
704 | int port_enabled; | 711 | int port_enabled; |
@@ -721,6 +728,7 @@ struct efx_nic { | |||
721 | struct efx_phy_operations *phy_op; | 728 | struct efx_phy_operations *phy_op; |
722 | void *phy_data; | 729 | void *phy_data; |
723 | struct mii_if_info mii; | 730 | struct mii_if_info mii; |
731 | unsigned tx_disabled; | ||
724 | 732 | ||
725 | int link_up; | 733 | int link_up; |
726 | unsigned int link_options; | 734 | unsigned int link_options; |
@@ -732,8 +740,26 @@ struct efx_nic { | |||
732 | struct work_struct reconfigure_work; | 740 | struct work_struct reconfigure_work; |
733 | 741 | ||
734 | atomic_t rx_reset; | 742 | atomic_t rx_reset; |
743 | enum efx_loopback_mode loopback_mode; | ||
744 | unsigned int loopback_modes; | ||
745 | |||
746 | void *loopback_selftest; | ||
735 | }; | 747 | }; |
736 | 748 | ||
749 | static inline int efx_dev_registered(struct efx_nic *efx) | ||
750 | { | ||
751 | return efx->net_dev->reg_state == NETREG_REGISTERED; | ||
752 | } | ||
753 | |||
754 | /* Net device name, for inclusion in log messages if it has been registered. | ||
755 | * Use efx->name not efx->net_dev->name so that races with (un)registration | ||
756 | * are harmless. | ||
757 | */ | ||
758 | static inline const char *efx_dev_name(struct efx_nic *efx) | ||
759 | { | ||
760 | return efx_dev_registered(efx) ? efx->name : ""; | ||
761 | } | ||
762 | |||
737 | /** | 763 | /** |
738 | * struct efx_nic_type - Efx device type definition | 764 | * struct efx_nic_type - Efx device type definition |
739 | * @mem_bar: Memory BAR number | 765 | * @mem_bar: Memory BAR number |
@@ -769,7 +795,7 @@ struct efx_nic_type { | |||
769 | unsigned int txd_ring_mask; | 795 | unsigned int txd_ring_mask; |
770 | unsigned int rxd_ring_mask; | 796 | unsigned int rxd_ring_mask; |
771 | unsigned int evq_size; | 797 | unsigned int evq_size; |
772 | dma_addr_t max_dma_mask; | 798 | u64 max_dma_mask; |
773 | unsigned int tx_dma_mask; | 799 | unsigned int tx_dma_mask; |
774 | unsigned bug5391_mask; | 800 | unsigned bug5391_mask; |
775 | 801 | ||
diff --git a/drivers/net/sfc/rx.c b/drivers/net/sfc/rx.c index 551299b462ae..601b001437c0 100644 --- a/drivers/net/sfc/rx.c +++ b/drivers/net/sfc/rx.c | |||
@@ -19,6 +19,7 @@ | |||
19 | #include "rx.h" | 19 | #include "rx.h" |
20 | #include "efx.h" | 20 | #include "efx.h" |
21 | #include "falcon.h" | 21 | #include "falcon.h" |
22 | #include "selftest.h" | ||
22 | #include "workarounds.h" | 23 | #include "workarounds.h" |
23 | 24 | ||
24 | /* Number of RX descriptors pushed at once. */ | 25 | /* Number of RX descriptors pushed at once. */ |
@@ -85,14 +86,17 @@ static unsigned int rx_refill_limit = 95; | |||
85 | */ | 86 | */ |
86 | #define EFX_RXD_HEAD_ROOM 2 | 87 | #define EFX_RXD_HEAD_ROOM 2 |
87 | 88 | ||
88 | /* Macros for zero-order pages (potentially) containing multiple RX buffers */ | 89 | static inline unsigned int efx_rx_buf_offset(struct efx_rx_buffer *buf) |
89 | #define RX_DATA_OFFSET(_data) \ | 90 | { |
90 | (((unsigned long) (_data)) & (PAGE_SIZE-1)) | 91 | /* Offset is always within one page, so we don't need to consider |
91 | #define RX_BUF_OFFSET(_rx_buf) \ | 92 | * the page order. |
92 | RX_DATA_OFFSET((_rx_buf)->data) | 93 | */ |
93 | 94 | return (__force unsigned long) buf->data & (PAGE_SIZE - 1); | |
94 | #define RX_PAGE_SIZE(_efx) \ | 95 | } |
95 | (PAGE_SIZE * (1u << (_efx)->rx_buffer_order)) | 96 | static inline unsigned int efx_rx_buf_size(struct efx_nic *efx) |
97 | { | ||
98 | return PAGE_SIZE << efx->rx_buffer_order; | ||
99 | } | ||
96 | 100 | ||
97 | 101 | ||
98 | /************************************************************************** | 102 | /************************************************************************** |
@@ -105,7 +109,7 @@ static unsigned int rx_refill_limit = 95; | |||
105 | static int efx_lro_get_skb_hdr(struct sk_buff *skb, void **ip_hdr, | 109 | static int efx_lro_get_skb_hdr(struct sk_buff *skb, void **ip_hdr, |
106 | void **tcpudp_hdr, u64 *hdr_flags, void *priv) | 110 | void **tcpudp_hdr, u64 *hdr_flags, void *priv) |
107 | { | 111 | { |
108 | struct efx_channel *channel = (struct efx_channel *)priv; | 112 | struct efx_channel *channel = priv; |
109 | struct iphdr *iph; | 113 | struct iphdr *iph; |
110 | struct tcphdr *th; | 114 | struct tcphdr *th; |
111 | 115 | ||
@@ -130,12 +134,12 @@ static int efx_get_frag_hdr(struct skb_frag_struct *frag, void **mac_hdr, | |||
130 | void **ip_hdr, void **tcpudp_hdr, u64 *hdr_flags, | 134 | void **ip_hdr, void **tcpudp_hdr, u64 *hdr_flags, |
131 | void *priv) | 135 | void *priv) |
132 | { | 136 | { |
133 | struct efx_channel *channel = (struct efx_channel *)priv; | 137 | struct efx_channel *channel = priv; |
134 | struct ethhdr *eh; | 138 | struct ethhdr *eh; |
135 | struct iphdr *iph; | 139 | struct iphdr *iph; |
136 | 140 | ||
137 | /* We support EtherII and VLAN encapsulated IPv4 */ | 141 | /* We support EtherII and VLAN encapsulated IPv4 */ |
138 | eh = (struct ethhdr *)(page_address(frag->page) + frag->page_offset); | 142 | eh = page_address(frag->page) + frag->page_offset; |
139 | *mac_hdr = eh; | 143 | *mac_hdr = eh; |
140 | 144 | ||
141 | if (eh->h_proto == htons(ETH_P_IP)) { | 145 | if (eh->h_proto == htons(ETH_P_IP)) { |
@@ -268,7 +272,7 @@ static inline int efx_init_rx_buffer_page(struct efx_rx_queue *rx_queue, | |||
268 | return -ENOMEM; | 272 | return -ENOMEM; |
269 | 273 | ||
270 | dma_addr = pci_map_page(efx->pci_dev, rx_buf->page, | 274 | dma_addr = pci_map_page(efx->pci_dev, rx_buf->page, |
271 | 0, RX_PAGE_SIZE(efx), | 275 | 0, efx_rx_buf_size(efx), |
272 | PCI_DMA_FROMDEVICE); | 276 | PCI_DMA_FROMDEVICE); |
273 | 277 | ||
274 | if (unlikely(pci_dma_mapping_error(dma_addr))) { | 278 | if (unlikely(pci_dma_mapping_error(dma_addr))) { |
@@ -279,14 +283,14 @@ static inline int efx_init_rx_buffer_page(struct efx_rx_queue *rx_queue, | |||
279 | 283 | ||
280 | rx_queue->buf_page = rx_buf->page; | 284 | rx_queue->buf_page = rx_buf->page; |
281 | rx_queue->buf_dma_addr = dma_addr; | 285 | rx_queue->buf_dma_addr = dma_addr; |
282 | rx_queue->buf_data = ((char *) page_address(rx_buf->page) + | 286 | rx_queue->buf_data = (page_address(rx_buf->page) + |
283 | EFX_PAGE_IP_ALIGN); | 287 | EFX_PAGE_IP_ALIGN); |
284 | } | 288 | } |
285 | 289 | ||
286 | offset = RX_DATA_OFFSET(rx_queue->buf_data); | ||
287 | rx_buf->len = bytes; | 290 | rx_buf->len = bytes; |
288 | rx_buf->dma_addr = rx_queue->buf_dma_addr + offset; | ||
289 | rx_buf->data = rx_queue->buf_data; | 291 | rx_buf->data = rx_queue->buf_data; |
292 | offset = efx_rx_buf_offset(rx_buf); | ||
293 | rx_buf->dma_addr = rx_queue->buf_dma_addr + offset; | ||
290 | 294 | ||
291 | /* Try to pack multiple buffers per page */ | 295 | /* Try to pack multiple buffers per page */ |
292 | if (efx->rx_buffer_order == 0) { | 296 | if (efx->rx_buffer_order == 0) { |
@@ -294,7 +298,7 @@ static inline int efx_init_rx_buffer_page(struct efx_rx_queue *rx_queue, | |||
294 | rx_queue->buf_data += ((bytes + 0x1ff) & ~0x1ff); | 298 | rx_queue->buf_data += ((bytes + 0x1ff) & ~0x1ff); |
295 | offset += ((bytes + 0x1ff) & ~0x1ff); | 299 | offset += ((bytes + 0x1ff) & ~0x1ff); |
296 | 300 | ||
297 | space = RX_PAGE_SIZE(efx) - offset; | 301 | space = efx_rx_buf_size(efx) - offset; |
298 | if (space >= bytes) { | 302 | if (space >= bytes) { |
299 | /* Refs dropped on kernel releasing each skb */ | 303 | /* Refs dropped on kernel releasing each skb */ |
300 | get_page(rx_queue->buf_page); | 304 | get_page(rx_queue->buf_page); |
@@ -343,7 +347,8 @@ static inline void efx_unmap_rx_buffer(struct efx_nic *efx, | |||
343 | EFX_BUG_ON_PARANOID(rx_buf->skb); | 347 | EFX_BUG_ON_PARANOID(rx_buf->skb); |
344 | if (rx_buf->unmap_addr) { | 348 | if (rx_buf->unmap_addr) { |
345 | pci_unmap_page(efx->pci_dev, rx_buf->unmap_addr, | 349 | pci_unmap_page(efx->pci_dev, rx_buf->unmap_addr, |
346 | RX_PAGE_SIZE(efx), PCI_DMA_FROMDEVICE); | 350 | efx_rx_buf_size(efx), |
351 | PCI_DMA_FROMDEVICE); | ||
347 | rx_buf->unmap_addr = 0; | 352 | rx_buf->unmap_addr = 0; |
348 | } | 353 | } |
349 | } else if (likely(rx_buf->skb)) { | 354 | } else if (likely(rx_buf->skb)) { |
@@ -399,9 +404,10 @@ static int __efx_fast_push_rx_descriptors(struct efx_rx_queue *rx_queue, | |||
399 | return 0; | 404 | return 0; |
400 | 405 | ||
401 | /* Record minimum fill level */ | 406 | /* Record minimum fill level */ |
402 | if (unlikely(fill_level < rx_queue->min_fill)) | 407 | if (unlikely(fill_level < rx_queue->min_fill)) { |
403 | if (fill_level) | 408 | if (fill_level) |
404 | rx_queue->min_fill = fill_level; | 409 | rx_queue->min_fill = fill_level; |
410 | } | ||
405 | 411 | ||
406 | /* Acquire RX add lock. If this lock is contended, then a fast | 412 | /* Acquire RX add lock. If this lock is contended, then a fast |
407 | * fill must already be in progress (e.g. in the refill | 413 | * fill must already be in progress (e.g. in the refill |
@@ -551,7 +557,7 @@ static inline void efx_rx_packet_lro(struct efx_channel *channel, | |||
551 | struct skb_frag_struct frags; | 557 | struct skb_frag_struct frags; |
552 | 558 | ||
553 | frags.page = rx_buf->page; | 559 | frags.page = rx_buf->page; |
554 | frags.page_offset = RX_BUF_OFFSET(rx_buf); | 560 | frags.page_offset = efx_rx_buf_offset(rx_buf); |
555 | frags.size = rx_buf->len; | 561 | frags.size = rx_buf->len; |
556 | 562 | ||
557 | lro_receive_frags(lro_mgr, &frags, rx_buf->len, | 563 | lro_receive_frags(lro_mgr, &frags, rx_buf->len, |
@@ -596,7 +602,7 @@ static inline struct sk_buff *efx_rx_mk_skb(struct efx_rx_buffer *rx_buf, | |||
596 | if (unlikely(rx_buf->len > hdr_len)) { | 602 | if (unlikely(rx_buf->len > hdr_len)) { |
597 | struct skb_frag_struct *frag = skb_shinfo(skb)->frags; | 603 | struct skb_frag_struct *frag = skb_shinfo(skb)->frags; |
598 | frag->page = rx_buf->page; | 604 | frag->page = rx_buf->page; |
599 | frag->page_offset = RX_BUF_OFFSET(rx_buf) + hdr_len; | 605 | frag->page_offset = efx_rx_buf_offset(rx_buf) + hdr_len; |
600 | frag->size = skb->len - hdr_len; | 606 | frag->size = skb->len - hdr_len; |
601 | skb_shinfo(skb)->nr_frags = 1; | 607 | skb_shinfo(skb)->nr_frags = 1; |
602 | skb->data_len = frag->size; | 608 | skb->data_len = frag->size; |
@@ -683,6 +689,15 @@ void __efx_rx_packet(struct efx_channel *channel, | |||
683 | struct sk_buff *skb; | 689 | struct sk_buff *skb; |
684 | int lro = efx->net_dev->features & NETIF_F_LRO; | 690 | int lro = efx->net_dev->features & NETIF_F_LRO; |
685 | 691 | ||
692 | /* If we're in loopback test, then pass the packet directly to the | ||
693 | * loopback layer, and free the rx_buf here | ||
694 | */ | ||
695 | if (unlikely(efx->loopback_selftest)) { | ||
696 | efx_loopback_rx_packet(efx, rx_buf->data, rx_buf->len); | ||
697 | efx_free_rx_buffer(efx, rx_buf); | ||
698 | goto done; | ||
699 | } | ||
700 | |||
686 | if (rx_buf->skb) { | 701 | if (rx_buf->skb) { |
687 | prefetch(skb_shinfo(rx_buf->skb)); | 702 | prefetch(skb_shinfo(rx_buf->skb)); |
688 | 703 | ||
@@ -736,7 +751,6 @@ void __efx_rx_packet(struct efx_channel *channel, | |||
736 | /* Update allocation strategy method */ | 751 | /* Update allocation strategy method */ |
737 | channel->rx_alloc_level += RX_ALLOC_FACTOR_SKB; | 752 | channel->rx_alloc_level += RX_ALLOC_FACTOR_SKB; |
738 | 753 | ||
739 | /* fall-thru */ | ||
740 | done: | 754 | done: |
741 | efx->net_dev->last_rx = jiffies; | 755 | efx->net_dev->last_rx = jiffies; |
742 | } | 756 | } |
@@ -842,7 +856,8 @@ void efx_fini_rx_queue(struct efx_rx_queue *rx_queue) | |||
842 | /* For a page that is part-way through splitting into RX buffers */ | 856 | /* For a page that is part-way through splitting into RX buffers */ |
843 | if (rx_queue->buf_page != NULL) { | 857 | if (rx_queue->buf_page != NULL) { |
844 | pci_unmap_page(rx_queue->efx->pci_dev, rx_queue->buf_dma_addr, | 858 | pci_unmap_page(rx_queue->efx->pci_dev, rx_queue->buf_dma_addr, |
845 | RX_PAGE_SIZE(rx_queue->efx), PCI_DMA_FROMDEVICE); | 859 | efx_rx_buf_size(rx_queue->efx), |
860 | PCI_DMA_FROMDEVICE); | ||
846 | __free_pages(rx_queue->buf_page, | 861 | __free_pages(rx_queue->buf_page, |
847 | rx_queue->efx->rx_buffer_order); | 862 | rx_queue->efx->rx_buffer_order); |
848 | rx_queue->buf_page = NULL; | 863 | rx_queue->buf_page = NULL; |
diff --git a/drivers/net/sfc/selftest.c b/drivers/net/sfc/selftest.c new file mode 100644 index 000000000000..3b2de9fe7f27 --- /dev/null +++ b/drivers/net/sfc/selftest.c | |||
@@ -0,0 +1,719 @@ | |||
1 | /**************************************************************************** | ||
2 | * Driver for Solarflare Solarstorm network controllers and boards | ||
3 | * Copyright 2005-2006 Fen Systems Ltd. | ||
4 | * Copyright 2006-2008 Solarflare Communications Inc. | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify it | ||
7 | * under the terms of the GNU General Public License version 2 as published | ||
8 | * by the Free Software Foundation, incorporated herein by reference. | ||
9 | */ | ||
10 | |||
11 | #include <linux/netdevice.h> | ||
12 | #include <linux/module.h> | ||
13 | #include <linux/delay.h> | ||
14 | #include <linux/kernel_stat.h> | ||
15 | #include <linux/pci.h> | ||
16 | #include <linux/ethtool.h> | ||
17 | #include <linux/ip.h> | ||
18 | #include <linux/in.h> | ||
19 | #include <linux/udp.h> | ||
20 | #include <linux/rtnetlink.h> | ||
21 | #include <asm/io.h> | ||
22 | #include "net_driver.h" | ||
23 | #include "ethtool.h" | ||
24 | #include "efx.h" | ||
25 | #include "falcon.h" | ||
26 | #include "selftest.h" | ||
27 | #include "boards.h" | ||
28 | #include "workarounds.h" | ||
29 | #include "mac.h" | ||
30 | |||
31 | /* | ||
32 | * Loopback test packet structure | ||
33 | * | ||
34 | * The self-test should stress every RSS vector, and unfortunately | ||
35 | * Falcon only performs RSS on TCP/UDP packets. | ||
36 | */ | ||
37 | struct efx_loopback_payload { | ||
38 | struct ethhdr header; | ||
39 | struct iphdr ip; | ||
40 | struct udphdr udp; | ||
41 | __be16 iteration; | ||
42 | const char msg[64]; | ||
43 | } __attribute__ ((packed)); | ||
44 | |||
45 | /* Loopback test source MAC address */ | ||
46 | static const unsigned char payload_source[ETH_ALEN] = { | ||
47 | 0x00, 0x0f, 0x53, 0x1b, 0x1b, 0x1b, | ||
48 | }; | ||
49 | |||
50 | static const char *payload_msg = | ||
51 | "Hello world! This is an Efx loopback test in progress!"; | ||
52 | |||
53 | /** | ||
54 | * efx_selftest_state - persistent state during a selftest | ||
55 | * @flush: Drop all packets in efx_loopback_rx_packet | ||
56 | * @packet_count: Number of packets being used in this test | ||
57 | * @skbs: An array of skbs transmitted | ||
58 | * @rx_good: RX good packet count | ||
59 | * @rx_bad: RX bad packet count | ||
60 | * @payload: Payload used in tests | ||
61 | */ | ||
62 | struct efx_selftest_state { | ||
63 | int flush; | ||
64 | int packet_count; | ||
65 | struct sk_buff **skbs; | ||
66 | atomic_t rx_good; | ||
67 | atomic_t rx_bad; | ||
68 | struct efx_loopback_payload payload; | ||
69 | }; | ||
70 | |||
71 | /************************************************************************** | ||
72 | * | ||
73 | * Configurable values | ||
74 | * | ||
75 | **************************************************************************/ | ||
76 | |||
77 | /* Level of loopback testing | ||
78 | * | ||
79 | * The maximum packet burst length is 16**(n-1), i.e. | ||
80 | * | ||
81 | * - Level 0 : no packets | ||
82 | * - Level 1 : 1 packet | ||
83 | * - Level 2 : 17 packets (1 * 1 packet, 1 * 16 packets) | ||
84 | * - Level 3 : 273 packets (1 * 1 packet, 1 * 16 packet, 1 * 256 packets) | ||
85 | * | ||
86 | */ | ||
87 | static unsigned int loopback_test_level = 3; | ||
88 | |||
89 | /************************************************************************** | ||
90 | * | ||
91 | * Interrupt and event queue testing | ||
92 | * | ||
93 | **************************************************************************/ | ||
94 | |||
95 | /* Test generation and receipt of interrupts */ | ||
96 | static int efx_test_interrupts(struct efx_nic *efx, | ||
97 | struct efx_self_tests *tests) | ||
98 | { | ||
99 | struct efx_channel *channel; | ||
100 | |||
101 | EFX_LOG(efx, "testing interrupts\n"); | ||
102 | tests->interrupt = -1; | ||
103 | |||
104 | /* Reset interrupt flag */ | ||
105 | efx->last_irq_cpu = -1; | ||
106 | smp_wmb(); | ||
107 | |||
108 | /* ACK each interrupting event queue. Receiving an interrupt due to | ||
109 | * traffic before a test event is raised is considered a pass */ | ||
110 | efx_for_each_channel_with_interrupt(channel, efx) { | ||
111 | if (channel->work_pending) | ||
112 | efx_process_channel_now(channel); | ||
113 | if (efx->last_irq_cpu >= 0) | ||
114 | goto success; | ||
115 | } | ||
116 | |||
117 | falcon_generate_interrupt(efx); | ||
118 | |||
119 | /* Wait for arrival of test interrupt. */ | ||
120 | EFX_LOG(efx, "waiting for test interrupt\n"); | ||
121 | schedule_timeout_uninterruptible(HZ / 10); | ||
122 | if (efx->last_irq_cpu >= 0) | ||
123 | goto success; | ||
124 | |||
125 | EFX_ERR(efx, "timed out waiting for interrupt\n"); | ||
126 | return -ETIMEDOUT; | ||
127 | |||
128 | success: | ||
129 | EFX_LOG(efx, "test interrupt (mode %d) seen on CPU%d\n", | ||
130 | efx->interrupt_mode, efx->last_irq_cpu); | ||
131 | tests->interrupt = 1; | ||
132 | return 0; | ||
133 | } | ||
134 | |||
135 | /* Test generation and receipt of non-interrupting events */ | ||
136 | static int efx_test_eventq(struct efx_channel *channel, | ||
137 | struct efx_self_tests *tests) | ||
138 | { | ||
139 | unsigned int magic; | ||
140 | |||
141 | /* Channel specific code, limited to 20 bits */ | ||
142 | magic = (0x00010150 + channel->channel); | ||
143 | EFX_LOG(channel->efx, "channel %d testing event queue with code %x\n", | ||
144 | channel->channel, magic); | ||
145 | |||
146 | tests->eventq_dma[channel->channel] = -1; | ||
147 | tests->eventq_int[channel->channel] = 1; /* fake pass */ | ||
148 | tests->eventq_poll[channel->channel] = 1; /* fake pass */ | ||
149 | |||
150 | /* Reset flag and zero magic word */ | ||
151 | channel->efx->last_irq_cpu = -1; | ||
152 | channel->eventq_magic = 0; | ||
153 | smp_wmb(); | ||
154 | |||
155 | falcon_generate_test_event(channel, magic); | ||
156 | udelay(1); | ||
157 | |||
158 | efx_process_channel_now(channel); | ||
159 | if (channel->eventq_magic != magic) { | ||
160 | EFX_ERR(channel->efx, "channel %d failed to see test event\n", | ||
161 | channel->channel); | ||
162 | return -ETIMEDOUT; | ||
163 | } else { | ||
164 | tests->eventq_dma[channel->channel] = 1; | ||
165 | } | ||
166 | |||
167 | return 0; | ||
168 | } | ||
169 | |||
170 | /* Test generation and receipt of interrupting events */ | ||
171 | static int efx_test_eventq_irq(struct efx_channel *channel, | ||
172 | struct efx_self_tests *tests) | ||
173 | { | ||
174 | unsigned int magic, count; | ||
175 | |||
176 | /* Channel specific code, limited to 20 bits */ | ||
177 | magic = (0x00010150 + channel->channel); | ||
178 | EFX_LOG(channel->efx, "channel %d testing event queue with code %x\n", | ||
179 | channel->channel, magic); | ||
180 | |||
181 | tests->eventq_dma[channel->channel] = -1; | ||
182 | tests->eventq_int[channel->channel] = -1; | ||
183 | tests->eventq_poll[channel->channel] = -1; | ||
184 | |||
185 | /* Reset flag and zero magic word */ | ||
186 | channel->efx->last_irq_cpu = -1; | ||
187 | channel->eventq_magic = 0; | ||
188 | smp_wmb(); | ||
189 | |||
190 | falcon_generate_test_event(channel, magic); | ||
191 | |||
192 | /* Wait for arrival of interrupt */ | ||
193 | count = 0; | ||
194 | do { | ||
195 | schedule_timeout_uninterruptible(HZ / 100); | ||
196 | |||
197 | if (channel->work_pending) | ||
198 | efx_process_channel_now(channel); | ||
199 | |||
200 | if (channel->eventq_magic == magic) | ||
201 | goto eventq_ok; | ||
202 | } while (++count < 2); | ||
203 | |||
204 | EFX_ERR(channel->efx, "channel %d timed out waiting for event queue\n", | ||
205 | channel->channel); | ||
206 | |||
207 | /* See if interrupt arrived */ | ||
208 | if (channel->efx->last_irq_cpu >= 0) { | ||
209 | EFX_ERR(channel->efx, "channel %d saw interrupt on CPU%d " | ||
210 | "during event queue test\n", channel->channel, | ||
211 | raw_smp_processor_id()); | ||
212 | tests->eventq_int[channel->channel] = 1; | ||
213 | } | ||
214 | |||
215 | /* Check to see if event was received even if interrupt wasn't */ | ||
216 | efx_process_channel_now(channel); | ||
217 | if (channel->eventq_magic == magic) { | ||
218 | EFX_ERR(channel->efx, "channel %d event was generated, but " | ||
219 | "failed to trigger an interrupt\n", channel->channel); | ||
220 | tests->eventq_dma[channel->channel] = 1; | ||
221 | } | ||
222 | |||
223 | return -ETIMEDOUT; | ||
224 | eventq_ok: | ||
225 | EFX_LOG(channel->efx, "channel %d event queue passed\n", | ||
226 | channel->channel); | ||
227 | tests->eventq_dma[channel->channel] = 1; | ||
228 | tests->eventq_int[channel->channel] = 1; | ||
229 | tests->eventq_poll[channel->channel] = 1; | ||
230 | return 0; | ||
231 | } | ||
232 | |||
233 | /************************************************************************** | ||
234 | * | ||
235 | * PHY testing | ||
236 | * | ||
237 | **************************************************************************/ | ||
238 | |||
239 | /* Check PHY presence by reading the PHY ID registers */ | ||
240 | static int efx_test_phy(struct efx_nic *efx, | ||
241 | struct efx_self_tests *tests) | ||
242 | { | ||
243 | u16 physid1, physid2; | ||
244 | struct mii_if_info *mii = &efx->mii; | ||
245 | struct net_device *net_dev = efx->net_dev; | ||
246 | |||
247 | if (efx->phy_type == PHY_TYPE_NONE) | ||
248 | return 0; | ||
249 | |||
250 | EFX_LOG(efx, "testing PHY presence\n"); | ||
251 | tests->phy_ok = -1; | ||
252 | |||
253 | physid1 = mii->mdio_read(net_dev, mii->phy_id, MII_PHYSID1); | ||
254 | physid2 = mii->mdio_read(net_dev, mii->phy_id, MII_PHYSID2); | ||
255 | |||
256 | if ((physid1 != 0x0000) && (physid1 != 0xffff) && | ||
257 | (physid2 != 0x0000) && (physid2 != 0xffff)) { | ||
258 | EFX_LOG(efx, "found MII PHY %d ID 0x%x:%x\n", | ||
259 | mii->phy_id, physid1, physid2); | ||
260 | tests->phy_ok = 1; | ||
261 | return 0; | ||
262 | } | ||
263 | |||
264 | EFX_ERR(efx, "no MII PHY present with ID %d\n", mii->phy_id); | ||
265 | return -ENODEV; | ||
266 | } | ||
267 | |||
268 | /************************************************************************** | ||
269 | * | ||
270 | * Loopback testing | ||
271 | * NB Only one loopback test can be executing concurrently. | ||
272 | * | ||
273 | **************************************************************************/ | ||
274 | |||
275 | /* Loopback test RX callback | ||
276 | * This is called for each received packet during loopback testing. | ||
277 | */ | ||
278 | void efx_loopback_rx_packet(struct efx_nic *efx, | ||
279 | const char *buf_ptr, int pkt_len) | ||
280 | { | ||
281 | struct efx_selftest_state *state = efx->loopback_selftest; | ||
282 | struct efx_loopback_payload *received; | ||
283 | struct efx_loopback_payload *payload; | ||
284 | |||
285 | BUG_ON(!buf_ptr); | ||
286 | |||
287 | /* If we are just flushing, then drop the packet */ | ||
288 | if ((state == NULL) || state->flush) | ||
289 | return; | ||
290 | |||
291 | payload = &state->payload; | ||
292 | |||
293 | received = (struct efx_loopback_payload *) buf_ptr; | ||
294 | received->ip.saddr = payload->ip.saddr; | ||
295 | received->ip.check = payload->ip.check; | ||
296 | |||
297 | /* Check that header exists */ | ||
298 | if (pkt_len < sizeof(received->header)) { | ||
299 | EFX_ERR(efx, "saw runt RX packet (length %d) in %s loopback " | ||
300 | "test\n", pkt_len, LOOPBACK_MODE(efx)); | ||
301 | goto err; | ||
302 | } | ||
303 | |||
304 | /* Check that the ethernet header exists */ | ||
305 | if (memcmp(&received->header, &payload->header, ETH_HLEN) != 0) { | ||
306 | EFX_ERR(efx, "saw non-loopback RX packet in %s loopback test\n", | ||
307 | LOOPBACK_MODE(efx)); | ||
308 | goto err; | ||
309 | } | ||
310 | |||
311 | /* Check packet length */ | ||
312 | if (pkt_len != sizeof(*payload)) { | ||
313 | EFX_ERR(efx, "saw incorrect RX packet length %d (wanted %d) in " | ||
314 | "%s loopback test\n", pkt_len, (int)sizeof(*payload), | ||
315 | LOOPBACK_MODE(efx)); | ||
316 | goto err; | ||
317 | } | ||
318 | |||
319 | /* Check that IP header matches */ | ||
320 | if (memcmp(&received->ip, &payload->ip, sizeof(payload->ip)) != 0) { | ||
321 | EFX_ERR(efx, "saw corrupted IP header in %s loopback test\n", | ||
322 | LOOPBACK_MODE(efx)); | ||
323 | goto err; | ||
324 | } | ||
325 | |||
326 | /* Check that msg and padding matches */ | ||
327 | if (memcmp(&received->msg, &payload->msg, sizeof(received->msg)) != 0) { | ||
328 | EFX_ERR(efx, "saw corrupted RX packet in %s loopback test\n", | ||
329 | LOOPBACK_MODE(efx)); | ||
330 | goto err; | ||
331 | } | ||
332 | |||
333 | /* Check that iteration matches */ | ||
334 | if (received->iteration != payload->iteration) { | ||
335 | EFX_ERR(efx, "saw RX packet from iteration %d (wanted %d) in " | ||
336 | "%s loopback test\n", ntohs(received->iteration), | ||
337 | ntohs(payload->iteration), LOOPBACK_MODE(efx)); | ||
338 | goto err; | ||
339 | } | ||
340 | |||
341 | /* Increase correct RX count */ | ||
342 | EFX_TRACE(efx, "got loopback RX in %s loopback test\n", | ||
343 | LOOPBACK_MODE(efx)); | ||
344 | |||
345 | atomic_inc(&state->rx_good); | ||
346 | return; | ||
347 | |||
348 | err: | ||
349 | #ifdef EFX_ENABLE_DEBUG | ||
350 | if (atomic_read(&state->rx_bad) == 0) { | ||
351 | EFX_ERR(efx, "received packet:\n"); | ||
352 | print_hex_dump(KERN_ERR, "", DUMP_PREFIX_OFFSET, 0x10, 1, | ||
353 | buf_ptr, pkt_len, 0); | ||
354 | EFX_ERR(efx, "expected packet:\n"); | ||
355 | print_hex_dump(KERN_ERR, "", DUMP_PREFIX_OFFSET, 0x10, 1, | ||
356 | &state->payload, sizeof(state->payload), 0); | ||
357 | } | ||
358 | #endif | ||
359 | atomic_inc(&state->rx_bad); | ||
360 | } | ||
361 | |||
362 | /* Initialise an efx_selftest_state for a new iteration */ | ||
363 | static void efx_iterate_state(struct efx_nic *efx) | ||
364 | { | ||
365 | struct efx_selftest_state *state = efx->loopback_selftest; | ||
366 | struct net_device *net_dev = efx->net_dev; | ||
367 | struct efx_loopback_payload *payload = &state->payload; | ||
368 | |||
369 | /* Initialise the layerII header */ | ||
370 | memcpy(&payload->header.h_dest, net_dev->dev_addr, ETH_ALEN); | ||
371 | memcpy(&payload->header.h_source, &payload_source, ETH_ALEN); | ||
372 | payload->header.h_proto = htons(ETH_P_IP); | ||
373 | |||
374 | /* saddr set later and used as incrementing count */ | ||
375 | payload->ip.daddr = htonl(INADDR_LOOPBACK); | ||
376 | payload->ip.ihl = 5; | ||
377 | payload->ip.check = htons(0xdead); | ||
378 | payload->ip.tot_len = htons(sizeof(*payload) - sizeof(struct ethhdr)); | ||
379 | payload->ip.version = IPVERSION; | ||
380 | payload->ip.protocol = IPPROTO_UDP; | ||
381 | |||
382 | /* Initialise udp header */ | ||
383 | payload->udp.source = 0; | ||
384 | payload->udp.len = htons(sizeof(*payload) - sizeof(struct ethhdr) - | ||
385 | sizeof(struct iphdr)); | ||
386 | payload->udp.check = 0; /* checksum ignored */ | ||
387 | |||
388 | /* Fill out payload */ | ||
389 | payload->iteration = htons(ntohs(payload->iteration) + 1); | ||
390 | memcpy(&payload->msg, payload_msg, sizeof(payload_msg)); | ||
391 | |||
392 | /* Fill out remaining state members */ | ||
393 | atomic_set(&state->rx_good, 0); | ||
394 | atomic_set(&state->rx_bad, 0); | ||
395 | smp_wmb(); | ||
396 | } | ||
397 | |||
398 | static int efx_tx_loopback(struct efx_tx_queue *tx_queue) | ||
399 | { | ||
400 | struct efx_nic *efx = tx_queue->efx; | ||
401 | struct efx_selftest_state *state = efx->loopback_selftest; | ||
402 | struct efx_loopback_payload *payload; | ||
403 | struct sk_buff *skb; | ||
404 | int i, rc; | ||
405 | |||
406 | /* Transmit N copies of buffer */ | ||
407 | for (i = 0; i < state->packet_count; i++) { | ||
408 | /* Allocate an skb, holding an extra reference for | ||
409 | * transmit completion counting */ | ||
410 | skb = alloc_skb(sizeof(state->payload), GFP_KERNEL); | ||
411 | if (!skb) | ||
412 | return -ENOMEM; | ||
413 | state->skbs[i] = skb; | ||
414 | skb_get(skb); | ||
415 | |||
416 | /* Copy the payload in, incrementing the source address to | ||
417 | * exercise the rss vectors */ | ||
418 | payload = ((struct efx_loopback_payload *) | ||
419 | skb_put(skb, sizeof(state->payload))); | ||
420 | memcpy(payload, &state->payload, sizeof(state->payload)); | ||
421 | payload->ip.saddr = htonl(INADDR_LOOPBACK | (i << 2)); | ||
422 | |||
423 | /* Ensure everything we've written is visible to the | ||
424 | * interrupt handler. */ | ||
425 | smp_wmb(); | ||
426 | |||
427 | if (efx_dev_registered(efx)) | ||
428 | netif_tx_lock_bh(efx->net_dev); | ||
429 | rc = efx_xmit(efx, tx_queue, skb); | ||
430 | if (efx_dev_registered(efx)) | ||
431 | netif_tx_unlock_bh(efx->net_dev); | ||
432 | |||
433 | if (rc != NETDEV_TX_OK) { | ||
434 | EFX_ERR(efx, "TX queue %d could not transmit packet %d " | ||
435 | "of %d in %s loopback test\n", tx_queue->queue, | ||
436 | i + 1, state->packet_count, LOOPBACK_MODE(efx)); | ||
437 | |||
438 | /* Defer cleaning up the other skbs for the caller */ | ||
439 | kfree_skb(skb); | ||
440 | return -EPIPE; | ||
441 | } | ||
442 | } | ||
443 | |||
444 | return 0; | ||
445 | } | ||
446 | |||
447 | static int efx_rx_loopback(struct efx_tx_queue *tx_queue, | ||
448 | struct efx_loopback_self_tests *lb_tests) | ||
449 | { | ||
450 | struct efx_nic *efx = tx_queue->efx; | ||
451 | struct efx_selftest_state *state = efx->loopback_selftest; | ||
452 | struct sk_buff *skb; | ||
453 | int tx_done = 0, rx_good, rx_bad; | ||
454 | int i, rc = 0; | ||
455 | |||
456 | if (efx_dev_registered(efx)) | ||
457 | netif_tx_lock_bh(efx->net_dev); | ||
458 | |||
459 | /* Count the number of tx completions, and decrement the refcnt. Any | ||
460 | * skbs not already completed will be free'd when the queue is flushed */ | ||
461 | for (i=0; i < state->packet_count; i++) { | ||
462 | skb = state->skbs[i]; | ||
463 | if (skb && !skb_shared(skb)) | ||
464 | ++tx_done; | ||
465 | dev_kfree_skb_any(skb); | ||
466 | } | ||
467 | |||
468 | if (efx_dev_registered(efx)) | ||
469 | netif_tx_unlock_bh(efx->net_dev); | ||
470 | |||
471 | /* Check TX completion and received packet counts */ | ||
472 | rx_good = atomic_read(&state->rx_good); | ||
473 | rx_bad = atomic_read(&state->rx_bad); | ||
474 | if (tx_done != state->packet_count) { | ||
475 | /* Don't free the skbs; they will be picked up on TX | ||
476 | * overflow or channel teardown. | ||
477 | */ | ||
478 | EFX_ERR(efx, "TX queue %d saw only %d out of an expected %d " | ||
479 | "TX completion events in %s loopback test\n", | ||
480 | tx_queue->queue, tx_done, state->packet_count, | ||
481 | LOOPBACK_MODE(efx)); | ||
482 | rc = -ETIMEDOUT; | ||
483 | /* Allow to fall through so we see the RX errors as well */ | ||
484 | } | ||
485 | |||
486 | /* We may always be up to a flush away from our desired packet total */ | ||
487 | if (rx_good != state->packet_count) { | ||
488 | EFX_LOG(efx, "TX queue %d saw only %d out of an expected %d " | ||
489 | "received packets in %s loopback test\n", | ||
490 | tx_queue->queue, rx_good, state->packet_count, | ||
491 | LOOPBACK_MODE(efx)); | ||
492 | rc = -ETIMEDOUT; | ||
493 | /* Fall through */ | ||
494 | } | ||
495 | |||
496 | /* Update loopback test structure */ | ||
497 | lb_tests->tx_sent[tx_queue->queue] += state->packet_count; | ||
498 | lb_tests->tx_done[tx_queue->queue] += tx_done; | ||
499 | lb_tests->rx_good += rx_good; | ||
500 | lb_tests->rx_bad += rx_bad; | ||
501 | |||
502 | return rc; | ||
503 | } | ||
504 | |||
505 | static int | ||
506 | efx_test_loopback(struct efx_tx_queue *tx_queue, | ||
507 | struct efx_loopback_self_tests *lb_tests) | ||
508 | { | ||
509 | struct efx_nic *efx = tx_queue->efx; | ||
510 | struct efx_selftest_state *state = efx->loopback_selftest; | ||
511 | struct efx_channel *channel; | ||
512 | int i, rc = 0; | ||
513 | |||
514 | for (i = 0; i < loopback_test_level; i++) { | ||
515 | /* Determine how many packets to send */ | ||
516 | state->packet_count = (efx->type->txd_ring_mask + 1) / 3; | ||
517 | state->packet_count = min(1 << (i << 2), state->packet_count); | ||
518 | state->skbs = kzalloc(sizeof(state->skbs[0]) * | ||
519 | state->packet_count, GFP_KERNEL); | ||
520 | if (!state->skbs) | ||
521 | return -ENOMEM; | ||
522 | state->flush = 0; | ||
523 | |||
524 | EFX_LOG(efx, "TX queue %d testing %s loopback with %d " | ||
525 | "packets\n", tx_queue->queue, LOOPBACK_MODE(efx), | ||
526 | state->packet_count); | ||
527 | |||
528 | efx_iterate_state(efx); | ||
529 | rc = efx_tx_loopback(tx_queue); | ||
530 | |||
531 | /* NAPI polling is not enabled, so process channels synchronously */ | ||
532 | schedule_timeout_uninterruptible(HZ / 50); | ||
533 | efx_for_each_channel_with_interrupt(channel, efx) { | ||
534 | if (channel->work_pending) | ||
535 | efx_process_channel_now(channel); | ||
536 | } | ||
537 | |||
538 | rc |= efx_rx_loopback(tx_queue, lb_tests); | ||
539 | kfree(state->skbs); | ||
540 | |||
541 | if (rc) { | ||
542 | /* Wait a while to ensure there are no packets | ||
543 | * floating around after a failure. */ | ||
544 | schedule_timeout_uninterruptible(HZ / 10); | ||
545 | return rc; | ||
546 | } | ||
547 | } | ||
548 | |||
549 | EFX_LOG(efx, "TX queue %d passed %s loopback test with a burst length " | ||
550 | "of %d packets\n", tx_queue->queue, LOOPBACK_MODE(efx), | ||
551 | state->packet_count); | ||
552 | |||
553 | return rc; | ||
554 | } | ||
555 | |||
556 | static int efx_test_loopbacks(struct efx_nic *efx, | ||
557 | struct efx_self_tests *tests, | ||
558 | unsigned int loopback_modes) | ||
559 | { | ||
560 | struct efx_selftest_state *state = efx->loopback_selftest; | ||
561 | struct ethtool_cmd ecmd, ecmd_loopback; | ||
562 | struct efx_tx_queue *tx_queue; | ||
563 | enum efx_loopback_mode old_mode, mode; | ||
564 | int count, rc = 0, link_up; | ||
565 | |||
566 | rc = efx_ethtool_get_settings(efx->net_dev, &ecmd); | ||
567 | if (rc) { | ||
568 | EFX_ERR(efx, "could not get GMII settings\n"); | ||
569 | return rc; | ||
570 | } | ||
571 | old_mode = efx->loopback_mode; | ||
572 | |||
573 | /* Disable autonegotiation for the purposes of loopback */ | ||
574 | memcpy(&ecmd_loopback, &ecmd, sizeof(ecmd_loopback)); | ||
575 | if (ecmd_loopback.autoneg == AUTONEG_ENABLE) { | ||
576 | ecmd_loopback.autoneg = AUTONEG_DISABLE; | ||
577 | ecmd_loopback.duplex = DUPLEX_FULL; | ||
578 | ecmd_loopback.speed = SPEED_10000; | ||
579 | } | ||
580 | |||
581 | rc = efx_ethtool_set_settings(efx->net_dev, &ecmd_loopback); | ||
582 | if (rc) { | ||
583 | EFX_ERR(efx, "could not disable autonegotiation\n"); | ||
584 | goto out; | ||
585 | } | ||
586 | tests->loopback_speed = ecmd_loopback.speed; | ||
587 | tests->loopback_full_duplex = ecmd_loopback.duplex; | ||
588 | |||
589 | /* Test all supported loopback modes */ | ||
590 | for (mode = LOOPBACK_NONE; mode < LOOPBACK_TEST_MAX; mode++) { | ||
591 | if (!(loopback_modes & (1 << mode))) | ||
592 | continue; | ||
593 | |||
594 | /* Move the port into the specified loopback mode. */ | ||
595 | state->flush = 1; | ||
596 | efx->loopback_mode = mode; | ||
597 | efx_reconfigure_port(efx); | ||
598 | |||
599 | /* Wait for the PHY to signal the link is up */ | ||
600 | count = 0; | ||
601 | do { | ||
602 | struct efx_channel *channel = &efx->channel[0]; | ||
603 | |||
604 | falcon_check_xmac(efx); | ||
605 | schedule_timeout_uninterruptible(HZ / 10); | ||
606 | if (channel->work_pending) | ||
607 | efx_process_channel_now(channel); | ||
608 | /* Wait for PHY events to be processed */ | ||
609 | flush_workqueue(efx->workqueue); | ||
610 | rmb(); | ||
611 | |||
612 | /* efx->link_up can be 1 even if the XAUI link is down, | ||
613 | * (bug5762). Usually, it's not worth bothering with the | ||
614 | * difference, but for selftests, we need that extra | ||
615 | * guarantee that the link is really, really, up. | ||
616 | */ | ||
617 | link_up = efx->link_up; | ||
618 | if (!falcon_xaui_link_ok(efx)) | ||
619 | link_up = 0; | ||
620 | |||
621 | } while ((++count < 20) && !link_up); | ||
622 | |||
623 | /* The link should now be up. If it isn't, there is no point | ||
624 | * in attempting a loopback test */ | ||
625 | if (!link_up) { | ||
626 | EFX_ERR(efx, "loopback %s never came up\n", | ||
627 | LOOPBACK_MODE(efx)); | ||
628 | rc = -EIO; | ||
629 | goto out; | ||
630 | } | ||
631 | |||
632 | EFX_LOG(efx, "link came up in %s loopback in %d iterations\n", | ||
633 | LOOPBACK_MODE(efx), count); | ||
634 | |||
635 | /* Test every TX queue */ | ||
636 | efx_for_each_tx_queue(tx_queue, efx) { | ||
637 | rc |= efx_test_loopback(tx_queue, | ||
638 | &tests->loopback[mode]); | ||
639 | if (rc) | ||
640 | goto out; | ||
641 | } | ||
642 | } | ||
643 | |||
644 | out: | ||
645 | /* Take out of loopback and restore PHY settings */ | ||
646 | state->flush = 1; | ||
647 | efx->loopback_mode = old_mode; | ||
648 | efx_ethtool_set_settings(efx->net_dev, &ecmd); | ||
649 | |||
650 | return rc; | ||
651 | } | ||
652 | |||
653 | /************************************************************************** | ||
654 | * | ||
655 | * Entry points | ||
656 | * | ||
657 | *************************************************************************/ | ||
658 | |||
659 | /* Online (i.e. non-disruptive) testing | ||
660 | * This checks interrupt generation, event delivery and PHY presence. */ | ||
661 | int efx_online_test(struct efx_nic *efx, struct efx_self_tests *tests) | ||
662 | { | ||
663 | struct efx_channel *channel; | ||
664 | int rc = 0; | ||
665 | |||
666 | EFX_LOG(efx, "performing online self-tests\n"); | ||
667 | |||
668 | rc |= efx_test_interrupts(efx, tests); | ||
669 | efx_for_each_channel(channel, efx) { | ||
670 | if (channel->has_interrupt) | ||
671 | rc |= efx_test_eventq_irq(channel, tests); | ||
672 | else | ||
673 | rc |= efx_test_eventq(channel, tests); | ||
674 | } | ||
675 | rc |= efx_test_phy(efx, tests); | ||
676 | |||
677 | if (rc) | ||
678 | EFX_ERR(efx, "failed online self-tests\n"); | ||
679 | |||
680 | return rc; | ||
681 | } | ||
682 | |||
683 | /* Offline (i.e. disruptive) testing | ||
684 | * This checks MAC and PHY loopback on the specified port. */ | ||
685 | int efx_offline_test(struct efx_nic *efx, | ||
686 | struct efx_self_tests *tests, unsigned int loopback_modes) | ||
687 | { | ||
688 | struct efx_selftest_state *state; | ||
689 | int rc = 0; | ||
690 | |||
691 | EFX_LOG(efx, "performing offline self-tests\n"); | ||
692 | |||
693 | /* Create a selftest_state structure to hold state for the test */ | ||
694 | state = kzalloc(sizeof(*state), GFP_KERNEL); | ||
695 | if (state == NULL) { | ||
696 | rc = -ENOMEM; | ||
697 | goto out; | ||
698 | } | ||
699 | |||
700 | /* Set the port loopback_selftest member. From this point on | ||
701 | * all received packets will be dropped. Mark the state as | ||
702 | * "flushing" so all inflight packets are dropped */ | ||
703 | BUG_ON(efx->loopback_selftest); | ||
704 | state->flush = 1; | ||
705 | efx->loopback_selftest = state; | ||
706 | |||
707 | rc = efx_test_loopbacks(efx, tests, loopback_modes); | ||
708 | |||
709 | efx->loopback_selftest = NULL; | ||
710 | wmb(); | ||
711 | kfree(state); | ||
712 | |||
713 | out: | ||
714 | if (rc) | ||
715 | EFX_ERR(efx, "failed offline self-tests\n"); | ||
716 | |||
717 | return rc; | ||
718 | } | ||
719 | |||
diff --git a/drivers/net/sfc/selftest.h b/drivers/net/sfc/selftest.h new file mode 100644 index 000000000000..f6999c2b622d --- /dev/null +++ b/drivers/net/sfc/selftest.h | |||
@@ -0,0 +1,50 @@ | |||
1 | /**************************************************************************** | ||
2 | * Driver for Solarflare Solarstorm network controllers and boards | ||
3 | * Copyright 2005-2006 Fen Systems Ltd. | ||
4 | * Copyright 2006-2008 Solarflare Communications Inc. | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify it | ||
7 | * under the terms of the GNU General Public License version 2 as published | ||
8 | * by the Free Software Foundation, incorporated herein by reference. | ||
9 | */ | ||
10 | |||
11 | #ifndef EFX_SELFTEST_H | ||
12 | #define EFX_SELFTEST_H | ||
13 | |||
14 | #include "net_driver.h" | ||
15 | |||
16 | /* | ||
17 | * Self tests | ||
18 | */ | ||
19 | |||
20 | struct efx_loopback_self_tests { | ||
21 | int tx_sent[EFX_MAX_TX_QUEUES]; | ||
22 | int tx_done[EFX_MAX_TX_QUEUES]; | ||
23 | int rx_good; | ||
24 | int rx_bad; | ||
25 | }; | ||
26 | |||
27 | /* Efx self test results | ||
28 | * For fields which are not counters, 1 indicates success and -1 | ||
29 | * indicates failure. | ||
30 | */ | ||
31 | struct efx_self_tests { | ||
32 | int interrupt; | ||
33 | int eventq_dma[EFX_MAX_CHANNELS]; | ||
34 | int eventq_int[EFX_MAX_CHANNELS]; | ||
35 | int eventq_poll[EFX_MAX_CHANNELS]; | ||
36 | int phy_ok; | ||
37 | int loopback_speed; | ||
38 | int loopback_full_duplex; | ||
39 | struct efx_loopback_self_tests loopback[LOOPBACK_TEST_MAX]; | ||
40 | }; | ||
41 | |||
42 | extern void efx_loopback_rx_packet(struct efx_nic *efx, | ||
43 | const char *buf_ptr, int pkt_len); | ||
44 | extern int efx_online_test(struct efx_nic *efx, | ||
45 | struct efx_self_tests *tests); | ||
46 | extern int efx_offline_test(struct efx_nic *efx, | ||
47 | struct efx_self_tests *tests, | ||
48 | unsigned int loopback_modes); | ||
49 | |||
50 | #endif /* EFX_SELFTEST_H */ | ||
diff --git a/drivers/net/sfc/sfe4001.c b/drivers/net/sfc/sfe4001.c index 11fa9fb8f48b..66a0d1442aba 100644 --- a/drivers/net/sfc/sfe4001.c +++ b/drivers/net/sfc/sfe4001.c | |||
@@ -116,20 +116,29 @@ void sfe4001_poweroff(struct efx_nic *efx) | |||
116 | 116 | ||
117 | /* Turn off all power rails */ | 117 | /* Turn off all power rails */ |
118 | out = 0xff; | 118 | out = 0xff; |
119 | (void) efx_i2c_write(i2c, PCA9539, P0_OUT, &out, 1); | 119 | efx_i2c_write(i2c, PCA9539, P0_OUT, &out, 1); |
120 | 120 | ||
121 | /* Disable port 1 outputs on IO expander */ | 121 | /* Disable port 1 outputs on IO expander */ |
122 | cfg = 0xff; | 122 | cfg = 0xff; |
123 | (void) efx_i2c_write(i2c, PCA9539, P1_CONFIG, &cfg, 1); | 123 | efx_i2c_write(i2c, PCA9539, P1_CONFIG, &cfg, 1); |
124 | 124 | ||
125 | /* Disable port 0 outputs on IO expander */ | 125 | /* Disable port 0 outputs on IO expander */ |
126 | cfg = 0xff; | 126 | cfg = 0xff; |
127 | (void) efx_i2c_write(i2c, PCA9539, P0_CONFIG, &cfg, 1); | 127 | efx_i2c_write(i2c, PCA9539, P0_CONFIG, &cfg, 1); |
128 | 128 | ||
129 | /* Clear any over-temperature alert */ | 129 | /* Clear any over-temperature alert */ |
130 | (void) efx_i2c_read(i2c, MAX6647, RSL, &in, 1); | 130 | efx_i2c_read(i2c, MAX6647, RSL, &in, 1); |
131 | } | 131 | } |
132 | 132 | ||
133 | /* The P0_EN_3V3X line on SFE4001 boards (from A2 onward) is connected | ||
134 | * to the FLASH_CFG_1 input on the DSP. We must keep it high at power- | ||
135 | * up to allow writing the flash (done through MDIO from userland). | ||
136 | */ | ||
137 | unsigned int sfe4001_phy_flash_cfg; | ||
138 | module_param_named(phy_flash_cfg, sfe4001_phy_flash_cfg, uint, 0444); | ||
139 | MODULE_PARM_DESC(phy_flash_cfg, | ||
140 | "Force PHY to enter flash configuration mode"); | ||
141 | |||
133 | /* This board uses an I2C expander to provider power to the PHY, which needs to | 142 | /* This board uses an I2C expander to provider power to the PHY, which needs to |
134 | * be turned on before the PHY can be used. | 143 | * be turned on before the PHY can be used. |
135 | * Context: Process context, rtnl lock held | 144 | * Context: Process context, rtnl lock held |
@@ -203,6 +212,8 @@ int sfe4001_poweron(struct efx_nic *efx) | |||
203 | out = 0xff & ~((1 << P0_EN_1V2_LBN) | (1 << P0_EN_2V5_LBN) | | 212 | out = 0xff & ~((1 << P0_EN_1V2_LBN) | (1 << P0_EN_2V5_LBN) | |
204 | (1 << P0_EN_3V3X_LBN) | (1 << P0_EN_5V_LBN) | | 213 | (1 << P0_EN_3V3X_LBN) | (1 << P0_EN_5V_LBN) | |
205 | (1 << P0_X_TRST_LBN)); | 214 | (1 << P0_X_TRST_LBN)); |
215 | if (sfe4001_phy_flash_cfg) | ||
216 | out |= 1 << P0_EN_3V3X_LBN; | ||
206 | 217 | ||
207 | rc = efx_i2c_write(i2c, PCA9539, P0_OUT, &out, 1); | 218 | rc = efx_i2c_write(i2c, PCA9539, P0_OUT, &out, 1); |
208 | if (rc) | 219 | if (rc) |
@@ -226,6 +237,9 @@ int sfe4001_poweron(struct efx_nic *efx) | |||
226 | if (in & (1 << P1_AFE_PWD_LBN)) | 237 | if (in & (1 << P1_AFE_PWD_LBN)) |
227 | goto done; | 238 | goto done; |
228 | 239 | ||
240 | /* DSP doesn't look powered in flash config mode */ | ||
241 | if (sfe4001_phy_flash_cfg) | ||
242 | goto done; | ||
229 | } while (++count < 20); | 243 | } while (++count < 20); |
230 | 244 | ||
231 | EFX_INFO(efx, "timed out waiting for power\n"); | 245 | EFX_INFO(efx, "timed out waiting for power\n"); |
@@ -239,14 +253,14 @@ done: | |||
239 | fail3: | 253 | fail3: |
240 | /* Turn off all power rails */ | 254 | /* Turn off all power rails */ |
241 | out = 0xff; | 255 | out = 0xff; |
242 | (void) efx_i2c_write(i2c, PCA9539, P0_OUT, &out, 1); | 256 | efx_i2c_write(i2c, PCA9539, P0_OUT, &out, 1); |
243 | /* Disable port 1 outputs on IO expander */ | 257 | /* Disable port 1 outputs on IO expander */ |
244 | out = 0xff; | 258 | out = 0xff; |
245 | (void) efx_i2c_write(i2c, PCA9539, P1_CONFIG, &out, 1); | 259 | efx_i2c_write(i2c, PCA9539, P1_CONFIG, &out, 1); |
246 | fail2: | 260 | fail2: |
247 | /* Disable port 0 outputs on IO expander */ | 261 | /* Disable port 0 outputs on IO expander */ |
248 | out = 0xff; | 262 | out = 0xff; |
249 | (void) efx_i2c_write(i2c, PCA9539, P0_CONFIG, &out, 1); | 263 | efx_i2c_write(i2c, PCA9539, P0_CONFIG, &out, 1); |
250 | fail1: | 264 | fail1: |
251 | return rc; | 265 | return rc; |
252 | } | 266 | } |
diff --git a/drivers/net/sfc/tenxpress.c b/drivers/net/sfc/tenxpress.c index a2e9f79e47b1..c0146061c326 100644 --- a/drivers/net/sfc/tenxpress.c +++ b/drivers/net/sfc/tenxpress.c | |||
@@ -24,6 +24,11 @@ | |||
24 | MDIO_MMDREG_DEVS0_PCS | \ | 24 | MDIO_MMDREG_DEVS0_PCS | \ |
25 | MDIO_MMDREG_DEVS0_PHYXS) | 25 | MDIO_MMDREG_DEVS0_PHYXS) |
26 | 26 | ||
27 | #define TENXPRESS_LOOPBACKS ((1 << LOOPBACK_PHYXS) | \ | ||
28 | (1 << LOOPBACK_PCS) | \ | ||
29 | (1 << LOOPBACK_PMAPMD) | \ | ||
30 | (1 << LOOPBACK_NETWORK)) | ||
31 | |||
27 | /* We complain if we fail to see the link partner as 10G capable this many | 32 | /* We complain if we fail to see the link partner as 10G capable this many |
28 | * times in a row (must be > 1 as sampling the autoneg. registers is racy) | 33 | * times in a row (must be > 1 as sampling the autoneg. registers is racy) |
29 | */ | 34 | */ |
@@ -72,6 +77,10 @@ | |||
72 | #define PMA_PMD_BIST_RXD_LBN (1) | 77 | #define PMA_PMD_BIST_RXD_LBN (1) |
73 | #define PMA_PMD_BIST_AFE_LBN (0) | 78 | #define PMA_PMD_BIST_AFE_LBN (0) |
74 | 79 | ||
80 | /* Special Software reset register */ | ||
81 | #define PMA_PMD_EXT_CTRL_REG 49152 | ||
82 | #define PMA_PMD_EXT_SSR_LBN 15 | ||
83 | |||
75 | #define BIST_MAX_DELAY (1000) | 84 | #define BIST_MAX_DELAY (1000) |
76 | #define BIST_POLL_DELAY (10) | 85 | #define BIST_POLL_DELAY (10) |
77 | 86 | ||
@@ -86,6 +95,11 @@ | |||
86 | #define PCS_TEST_SELECT_REG 0xd807 /* PRM 10.5.8 */ | 95 | #define PCS_TEST_SELECT_REG 0xd807 /* PRM 10.5.8 */ |
87 | #define CLK312_EN_LBN 3 | 96 | #define CLK312_EN_LBN 3 |
88 | 97 | ||
98 | /* PHYXS registers */ | ||
99 | #define PHYXS_TEST1 (49162) | ||
100 | #define LOOPBACK_NEAR_LBN (8) | ||
101 | #define LOOPBACK_NEAR_WIDTH (1) | ||
102 | |||
89 | /* Boot status register */ | 103 | /* Boot status register */ |
90 | #define PCS_BOOT_STATUS_REG (0xd000) | 104 | #define PCS_BOOT_STATUS_REG (0xd000) |
91 | #define PCS_BOOT_FATAL_ERR_LBN (0) | 105 | #define PCS_BOOT_FATAL_ERR_LBN (0) |
@@ -106,7 +120,9 @@ MODULE_PARM_DESC(crc_error_reset_threshold, | |||
106 | 120 | ||
107 | struct tenxpress_phy_data { | 121 | struct tenxpress_phy_data { |
108 | enum tenxpress_state state; | 122 | enum tenxpress_state state; |
123 | enum efx_loopback_mode loopback_mode; | ||
109 | atomic_t bad_crc_count; | 124 | atomic_t bad_crc_count; |
125 | int tx_disabled; | ||
110 | int bad_lp_tries; | 126 | int bad_lp_tries; |
111 | }; | 127 | }; |
112 | 128 | ||
@@ -195,14 +211,18 @@ static int tenxpress_phy_init(struct efx_nic *efx) | |||
195 | int rc = 0; | 211 | int rc = 0; |
196 | 212 | ||
197 | phy_data = kzalloc(sizeof(*phy_data), GFP_KERNEL); | 213 | phy_data = kzalloc(sizeof(*phy_data), GFP_KERNEL); |
214 | if (!phy_data) | ||
215 | return -ENOMEM; | ||
198 | efx->phy_data = phy_data; | 216 | efx->phy_data = phy_data; |
199 | 217 | ||
200 | tenxpress_set_state(efx, TENXPRESS_STATUS_NORMAL); | 218 | tenxpress_set_state(efx, TENXPRESS_STATUS_NORMAL); |
201 | 219 | ||
202 | rc = mdio_clause45_wait_reset_mmds(efx, | 220 | if (!sfe4001_phy_flash_cfg) { |
203 | TENXPRESS_REQUIRED_DEVS); | 221 | rc = mdio_clause45_wait_reset_mmds(efx, |
204 | if (rc < 0) | 222 | TENXPRESS_REQUIRED_DEVS); |
205 | goto fail; | 223 | if (rc < 0) |
224 | goto fail; | ||
225 | } | ||
206 | 226 | ||
207 | rc = mdio_clause45_check_mmds(efx, TENXPRESS_REQUIRED_DEVS, 0); | 227 | rc = mdio_clause45_check_mmds(efx, TENXPRESS_REQUIRED_DEVS, 0); |
208 | if (rc < 0) | 228 | if (rc < 0) |
@@ -225,6 +245,35 @@ static int tenxpress_phy_init(struct efx_nic *efx) | |||
225 | return rc; | 245 | return rc; |
226 | } | 246 | } |
227 | 247 | ||
248 | static int tenxpress_special_reset(struct efx_nic *efx) | ||
249 | { | ||
250 | int rc, reg; | ||
251 | |||
252 | EFX_TRACE(efx, "%s\n", __func__); | ||
253 | |||
254 | /* Initiate reset */ | ||
255 | reg = mdio_clause45_read(efx, efx->mii.phy_id, | ||
256 | MDIO_MMD_PMAPMD, PMA_PMD_EXT_CTRL_REG); | ||
257 | reg |= (1 << PMA_PMD_EXT_SSR_LBN); | ||
258 | mdio_clause45_write(efx, efx->mii.phy_id, MDIO_MMD_PMAPMD, | ||
259 | PMA_PMD_EXT_CTRL_REG, reg); | ||
260 | |||
261 | msleep(200); | ||
262 | |||
263 | /* Wait for the blocks to come out of reset */ | ||
264 | rc = mdio_clause45_wait_reset_mmds(efx, | ||
265 | TENXPRESS_REQUIRED_DEVS); | ||
266 | if (rc < 0) | ||
267 | return rc; | ||
268 | |||
269 | /* Try and reconfigure the device */ | ||
270 | rc = tenxpress_init(efx); | ||
271 | if (rc < 0) | ||
272 | return rc; | ||
273 | |||
274 | return 0; | ||
275 | } | ||
276 | |||
228 | static void tenxpress_set_bad_lp(struct efx_nic *efx, int bad_lp) | 277 | static void tenxpress_set_bad_lp(struct efx_nic *efx, int bad_lp) |
229 | { | 278 | { |
230 | struct tenxpress_phy_data *pd = efx->phy_data; | 279 | struct tenxpress_phy_data *pd = efx->phy_data; |
@@ -299,11 +348,46 @@ static int tenxpress_link_ok(struct efx_nic *efx, int check_lp) | |||
299 | return ok; | 348 | return ok; |
300 | } | 349 | } |
301 | 350 | ||
351 | static void tenxpress_phyxs_loopback(struct efx_nic *efx) | ||
352 | { | ||
353 | int phy_id = efx->mii.phy_id; | ||
354 | int ctrl1, ctrl2; | ||
355 | |||
356 | ctrl1 = ctrl2 = mdio_clause45_read(efx, phy_id, MDIO_MMD_PHYXS, | ||
357 | PHYXS_TEST1); | ||
358 | if (efx->loopback_mode == LOOPBACK_PHYXS) | ||
359 | ctrl2 |= (1 << LOOPBACK_NEAR_LBN); | ||
360 | else | ||
361 | ctrl2 &= ~(1 << LOOPBACK_NEAR_LBN); | ||
362 | if (ctrl1 != ctrl2) | ||
363 | mdio_clause45_write(efx, phy_id, MDIO_MMD_PHYXS, | ||
364 | PHYXS_TEST1, ctrl2); | ||
365 | } | ||
366 | |||
302 | static void tenxpress_phy_reconfigure(struct efx_nic *efx) | 367 | static void tenxpress_phy_reconfigure(struct efx_nic *efx) |
303 | { | 368 | { |
369 | struct tenxpress_phy_data *phy_data = efx->phy_data; | ||
370 | int loop_change = LOOPBACK_OUT_OF(phy_data, efx, | ||
371 | TENXPRESS_LOOPBACKS); | ||
372 | |||
304 | if (!tenxpress_state_is(efx, TENXPRESS_STATUS_NORMAL)) | 373 | if (!tenxpress_state_is(efx, TENXPRESS_STATUS_NORMAL)) |
305 | return; | 374 | return; |
306 | 375 | ||
376 | /* When coming out of transmit disable, coming out of low power | ||
377 | * mode, or moving out of any PHY internal loopback mode, | ||
378 | * perform a special software reset */ | ||
379 | if ((phy_data->tx_disabled && !efx->tx_disabled) || | ||
380 | loop_change) { | ||
381 | tenxpress_special_reset(efx); | ||
382 | falcon_reset_xaui(efx); | ||
383 | } | ||
384 | |||
385 | mdio_clause45_transmit_disable(efx); | ||
386 | mdio_clause45_phy_reconfigure(efx); | ||
387 | tenxpress_phyxs_loopback(efx); | ||
388 | |||
389 | phy_data->tx_disabled = efx->tx_disabled; | ||
390 | phy_data->loopback_mode = efx->loopback_mode; | ||
307 | efx->link_up = tenxpress_link_ok(efx, 0); | 391 | efx->link_up = tenxpress_link_ok(efx, 0); |
308 | efx->link_options = GM_LPA_10000FULL; | 392 | efx->link_options = GM_LPA_10000FULL; |
309 | } | 393 | } |
@@ -431,4 +515,5 @@ struct efx_phy_operations falcon_tenxpress_phy_ops = { | |||
431 | .clear_interrupt = tenxpress_phy_clear_interrupt, | 515 | .clear_interrupt = tenxpress_phy_clear_interrupt, |
432 | .reset_xaui = tenxpress_reset_xaui, | 516 | .reset_xaui = tenxpress_reset_xaui, |
433 | .mmds = TENXPRESS_REQUIRED_DEVS, | 517 | .mmds = TENXPRESS_REQUIRED_DEVS, |
518 | .loopbacks = TENXPRESS_LOOPBACKS, | ||
434 | }; | 519 | }; |
diff --git a/drivers/net/sfc/tx.c b/drivers/net/sfc/tx.c index fbb866b2185e..5cdd082ab8f6 100644 --- a/drivers/net/sfc/tx.c +++ b/drivers/net/sfc/tx.c | |||
@@ -82,6 +82,46 @@ static inline void efx_dequeue_buffer(struct efx_tx_queue *tx_queue, | |||
82 | } | 82 | } |
83 | } | 83 | } |
84 | 84 | ||
85 | /** | ||
86 | * struct efx_tso_header - a DMA mapped buffer for packet headers | ||
87 | * @next: Linked list of free ones. | ||
88 | * The list is protected by the TX queue lock. | ||
89 | * @dma_unmap_len: Length to unmap for an oversize buffer, or 0. | ||
90 | * @dma_addr: The DMA address of the header below. | ||
91 | * | ||
92 | * This controls the memory used for a TSO header. Use TSOH_DATA() | ||
93 | * to find the packet header data. Use TSOH_SIZE() to calculate the | ||
94 | * total size required for a given packet header length. TSO headers | ||
95 | * in the free list are exactly %TSOH_STD_SIZE bytes in size. | ||
96 | */ | ||
97 | struct efx_tso_header { | ||
98 | union { | ||
99 | struct efx_tso_header *next; | ||
100 | size_t unmap_len; | ||
101 | }; | ||
102 | dma_addr_t dma_addr; | ||
103 | }; | ||
104 | |||
105 | static int efx_enqueue_skb_tso(struct efx_tx_queue *tx_queue, | ||
106 | const struct sk_buff *skb); | ||
107 | static void efx_fini_tso(struct efx_tx_queue *tx_queue); | ||
108 | static void efx_tsoh_heap_free(struct efx_tx_queue *tx_queue, | ||
109 | struct efx_tso_header *tsoh); | ||
110 | |||
111 | static inline void efx_tsoh_free(struct efx_tx_queue *tx_queue, | ||
112 | struct efx_tx_buffer *buffer) | ||
113 | { | ||
114 | if (buffer->tsoh) { | ||
115 | if (likely(!buffer->tsoh->unmap_len)) { | ||
116 | buffer->tsoh->next = tx_queue->tso_headers_free; | ||
117 | tx_queue->tso_headers_free = buffer->tsoh; | ||
118 | } else { | ||
119 | efx_tsoh_heap_free(tx_queue, buffer->tsoh); | ||
120 | } | ||
121 | buffer->tsoh = NULL; | ||
122 | } | ||
123 | } | ||
124 | |||
85 | 125 | ||
86 | /* | 126 | /* |
87 | * Add a socket buffer to a TX queue | 127 | * Add a socket buffer to a TX queue |
@@ -114,6 +154,9 @@ static inline int efx_enqueue_skb(struct efx_tx_queue *tx_queue, | |||
114 | 154 | ||
115 | EFX_BUG_ON_PARANOID(tx_queue->write_count != tx_queue->insert_count); | 155 | EFX_BUG_ON_PARANOID(tx_queue->write_count != tx_queue->insert_count); |
116 | 156 | ||
157 | if (skb_shinfo((struct sk_buff *)skb)->gso_size) | ||
158 | return efx_enqueue_skb_tso(tx_queue, skb); | ||
159 | |||
117 | /* Get size of the initial fragment */ | 160 | /* Get size of the initial fragment */ |
118 | len = skb_headlen(skb); | 161 | len = skb_headlen(skb); |
119 | 162 | ||
@@ -166,6 +209,8 @@ static inline int efx_enqueue_skb(struct efx_tx_queue *tx_queue, | |||
166 | insert_ptr = (tx_queue->insert_count & | 209 | insert_ptr = (tx_queue->insert_count & |
167 | efx->type->txd_ring_mask); | 210 | efx->type->txd_ring_mask); |
168 | buffer = &tx_queue->buffer[insert_ptr]; | 211 | buffer = &tx_queue->buffer[insert_ptr]; |
212 | efx_tsoh_free(tx_queue, buffer); | ||
213 | EFX_BUG_ON_PARANOID(buffer->tsoh); | ||
169 | EFX_BUG_ON_PARANOID(buffer->skb); | 214 | EFX_BUG_ON_PARANOID(buffer->skb); |
170 | EFX_BUG_ON_PARANOID(buffer->len); | 215 | EFX_BUG_ON_PARANOID(buffer->len); |
171 | EFX_BUG_ON_PARANOID(buffer->continuation != 1); | 216 | EFX_BUG_ON_PARANOID(buffer->continuation != 1); |
@@ -342,7 +387,7 @@ void efx_xmit_done(struct efx_tx_queue *tx_queue, unsigned int index) | |||
342 | if (unlikely(tx_queue->stopped)) { | 387 | if (unlikely(tx_queue->stopped)) { |
343 | fill_level = tx_queue->insert_count - tx_queue->read_count; | 388 | fill_level = tx_queue->insert_count - tx_queue->read_count; |
344 | if (fill_level < EFX_NETDEV_TX_THRESHOLD(tx_queue)) { | 389 | if (fill_level < EFX_NETDEV_TX_THRESHOLD(tx_queue)) { |
345 | EFX_BUG_ON_PARANOID(!NET_DEV_REGISTERED(efx)); | 390 | EFX_BUG_ON_PARANOID(!efx_dev_registered(efx)); |
346 | 391 | ||
347 | /* Do this under netif_tx_lock(), to avoid racing | 392 | /* Do this under netif_tx_lock(), to avoid racing |
348 | * with efx_xmit(). */ | 393 | * with efx_xmit(). */ |
@@ -432,6 +477,9 @@ void efx_fini_tx_queue(struct efx_tx_queue *tx_queue) | |||
432 | 477 | ||
433 | efx_release_tx_buffers(tx_queue); | 478 | efx_release_tx_buffers(tx_queue); |
434 | 479 | ||
480 | /* Free up TSO header cache */ | ||
481 | efx_fini_tso(tx_queue); | ||
482 | |||
435 | /* Release queue's stop on port, if any */ | 483 | /* Release queue's stop on port, if any */ |
436 | if (tx_queue->stopped) { | 484 | if (tx_queue->stopped) { |
437 | tx_queue->stopped = 0; | 485 | tx_queue->stopped = 0; |
@@ -450,3 +498,622 @@ void efx_remove_tx_queue(struct efx_tx_queue *tx_queue) | |||
450 | } | 498 | } |
451 | 499 | ||
452 | 500 | ||
501 | /* Efx TCP segmentation acceleration. | ||
502 | * | ||
503 | * Why? Because by doing it here in the driver we can go significantly | ||
504 | * faster than the GSO. | ||
505 | * | ||
506 | * Requires TX checksum offload support. | ||
507 | */ | ||
508 | |||
509 | /* Number of bytes inserted at the start of a TSO header buffer, | ||
510 | * similar to NET_IP_ALIGN. | ||
511 | */ | ||
512 | #if defined(__i386__) || defined(__x86_64__) | ||
513 | #define TSOH_OFFSET 0 | ||
514 | #else | ||
515 | #define TSOH_OFFSET NET_IP_ALIGN | ||
516 | #endif | ||
517 | |||
518 | #define TSOH_BUFFER(tsoh) ((u8 *)(tsoh + 1) + TSOH_OFFSET) | ||
519 | |||
520 | /* Total size of struct efx_tso_header, buffer and padding */ | ||
521 | #define TSOH_SIZE(hdr_len) \ | ||
522 | (sizeof(struct efx_tso_header) + TSOH_OFFSET + hdr_len) | ||
523 | |||
524 | /* Size of blocks on free list. Larger blocks must be allocated from | ||
525 | * the heap. | ||
526 | */ | ||
527 | #define TSOH_STD_SIZE 128 | ||
528 | |||
529 | #define PTR_DIFF(p1, p2) ((u8 *)(p1) - (u8 *)(p2)) | ||
530 | #define ETH_HDR_LEN(skb) (skb_network_header(skb) - (skb)->data) | ||
531 | #define SKB_TCP_OFF(skb) PTR_DIFF(tcp_hdr(skb), (skb)->data) | ||
532 | #define SKB_IPV4_OFF(skb) PTR_DIFF(ip_hdr(skb), (skb)->data) | ||
533 | |||
534 | /** | ||
535 | * struct tso_state - TSO state for an SKB | ||
536 | * @remaining_len: Bytes of data we've yet to segment | ||
537 | * @seqnum: Current sequence number | ||
538 | * @packet_space: Remaining space in current packet | ||
539 | * @ifc: Input fragment cursor. | ||
540 | * Where we are in the current fragment of the incoming SKB. These | ||
541 | * values get updated in place when we split a fragment over | ||
542 | * multiple packets. | ||
543 | * @p: Parameters. | ||
544 | * These values are set once at the start of the TSO send and do | ||
545 | * not get changed as the routine progresses. | ||
546 | * | ||
547 | * The state used during segmentation. It is put into this data structure | ||
548 | * just to make it easy to pass into inline functions. | ||
549 | */ | ||
550 | struct tso_state { | ||
551 | unsigned remaining_len; | ||
552 | unsigned seqnum; | ||
553 | unsigned packet_space; | ||
554 | |||
555 | struct { | ||
556 | /* DMA address of current position */ | ||
557 | dma_addr_t dma_addr; | ||
558 | /* Remaining length */ | ||
559 | unsigned int len; | ||
560 | /* DMA address and length of the whole fragment */ | ||
561 | unsigned int unmap_len; | ||
562 | dma_addr_t unmap_addr; | ||
563 | struct page *page; | ||
564 | unsigned page_off; | ||
565 | } ifc; | ||
566 | |||
567 | struct { | ||
568 | /* The number of bytes of header */ | ||
569 | unsigned int header_length; | ||
570 | |||
571 | /* The number of bytes to put in each outgoing segment. */ | ||
572 | int full_packet_size; | ||
573 | |||
574 | /* Current IPv4 ID, host endian. */ | ||
575 | unsigned ipv4_id; | ||
576 | } p; | ||
577 | }; | ||
578 | |||
579 | |||
580 | /* | ||
581 | * Verify that our various assumptions about sk_buffs and the conditions | ||
582 | * under which TSO will be attempted hold true. | ||
583 | */ | ||
584 | static inline void efx_tso_check_safe(const struct sk_buff *skb) | ||
585 | { | ||
586 | EFX_BUG_ON_PARANOID(skb->protocol != htons(ETH_P_IP)); | ||
587 | EFX_BUG_ON_PARANOID(((struct ethhdr *)skb->data)->h_proto != | ||
588 | skb->protocol); | ||
589 | EFX_BUG_ON_PARANOID(ip_hdr(skb)->protocol != IPPROTO_TCP); | ||
590 | EFX_BUG_ON_PARANOID((PTR_DIFF(tcp_hdr(skb), skb->data) | ||
591 | + (tcp_hdr(skb)->doff << 2u)) > | ||
592 | skb_headlen(skb)); | ||
593 | } | ||
594 | |||
595 | |||
596 | /* | ||
597 | * Allocate a page worth of efx_tso_header structures, and string them | ||
598 | * into the tx_queue->tso_headers_free linked list. Return 0 or -ENOMEM. | ||
599 | */ | ||
600 | static int efx_tsoh_block_alloc(struct efx_tx_queue *tx_queue) | ||
601 | { | ||
602 | |||
603 | struct pci_dev *pci_dev = tx_queue->efx->pci_dev; | ||
604 | struct efx_tso_header *tsoh; | ||
605 | dma_addr_t dma_addr; | ||
606 | u8 *base_kva, *kva; | ||
607 | |||
608 | base_kva = pci_alloc_consistent(pci_dev, PAGE_SIZE, &dma_addr); | ||
609 | if (base_kva == NULL) { | ||
610 | EFX_ERR(tx_queue->efx, "Unable to allocate page for TSO" | ||
611 | " headers\n"); | ||
612 | return -ENOMEM; | ||
613 | } | ||
614 | |||
615 | /* pci_alloc_consistent() allocates pages. */ | ||
616 | EFX_BUG_ON_PARANOID(dma_addr & (PAGE_SIZE - 1u)); | ||
617 | |||
618 | for (kva = base_kva; kva < base_kva + PAGE_SIZE; kva += TSOH_STD_SIZE) { | ||
619 | tsoh = (struct efx_tso_header *)kva; | ||
620 | tsoh->dma_addr = dma_addr + (TSOH_BUFFER(tsoh) - base_kva); | ||
621 | tsoh->next = tx_queue->tso_headers_free; | ||
622 | tx_queue->tso_headers_free = tsoh; | ||
623 | } | ||
624 | |||
625 | return 0; | ||
626 | } | ||
627 | |||
628 | |||
629 | /* Free up a TSO header, and all others in the same page. */ | ||
630 | static void efx_tsoh_block_free(struct efx_tx_queue *tx_queue, | ||
631 | struct efx_tso_header *tsoh, | ||
632 | struct pci_dev *pci_dev) | ||
633 | { | ||
634 | struct efx_tso_header **p; | ||
635 | unsigned long base_kva; | ||
636 | dma_addr_t base_dma; | ||
637 | |||
638 | base_kva = (unsigned long)tsoh & PAGE_MASK; | ||
639 | base_dma = tsoh->dma_addr & PAGE_MASK; | ||
640 | |||
641 | p = &tx_queue->tso_headers_free; | ||
642 | while (*p != NULL) { | ||
643 | if (((unsigned long)*p & PAGE_MASK) == base_kva) | ||
644 | *p = (*p)->next; | ||
645 | else | ||
646 | p = &(*p)->next; | ||
647 | } | ||
648 | |||
649 | pci_free_consistent(pci_dev, PAGE_SIZE, (void *)base_kva, base_dma); | ||
650 | } | ||
651 | |||
652 | static struct efx_tso_header * | ||
653 | efx_tsoh_heap_alloc(struct efx_tx_queue *tx_queue, size_t header_len) | ||
654 | { | ||
655 | struct efx_tso_header *tsoh; | ||
656 | |||
657 | tsoh = kmalloc(TSOH_SIZE(header_len), GFP_ATOMIC | GFP_DMA); | ||
658 | if (unlikely(!tsoh)) | ||
659 | return NULL; | ||
660 | |||
661 | tsoh->dma_addr = pci_map_single(tx_queue->efx->pci_dev, | ||
662 | TSOH_BUFFER(tsoh), header_len, | ||
663 | PCI_DMA_TODEVICE); | ||
664 | if (unlikely(pci_dma_mapping_error(tsoh->dma_addr))) { | ||
665 | kfree(tsoh); | ||
666 | return NULL; | ||
667 | } | ||
668 | |||
669 | tsoh->unmap_len = header_len; | ||
670 | return tsoh; | ||
671 | } | ||
672 | |||
673 | static void | ||
674 | efx_tsoh_heap_free(struct efx_tx_queue *tx_queue, struct efx_tso_header *tsoh) | ||
675 | { | ||
676 | pci_unmap_single(tx_queue->efx->pci_dev, | ||
677 | tsoh->dma_addr, tsoh->unmap_len, | ||
678 | PCI_DMA_TODEVICE); | ||
679 | kfree(tsoh); | ||
680 | } | ||
681 | |||
682 | /** | ||
683 | * efx_tx_queue_insert - push descriptors onto the TX queue | ||
684 | * @tx_queue: Efx TX queue | ||
685 | * @dma_addr: DMA address of fragment | ||
686 | * @len: Length of fragment | ||
687 | * @skb: Only non-null for end of last segment | ||
688 | * @end_of_packet: True if last fragment in a packet | ||
689 | * @unmap_addr: DMA address of fragment for unmapping | ||
690 | * @unmap_len: Only set this in last segment of a fragment | ||
691 | * | ||
692 | * Push descriptors onto the TX queue. Return 0 on success or 1 if | ||
693 | * @tx_queue full. | ||
694 | */ | ||
695 | static int efx_tx_queue_insert(struct efx_tx_queue *tx_queue, | ||
696 | dma_addr_t dma_addr, unsigned len, | ||
697 | const struct sk_buff *skb, int end_of_packet, | ||
698 | dma_addr_t unmap_addr, unsigned unmap_len) | ||
699 | { | ||
700 | struct efx_tx_buffer *buffer; | ||
701 | struct efx_nic *efx = tx_queue->efx; | ||
702 | unsigned dma_len, fill_level, insert_ptr, misalign; | ||
703 | int q_space; | ||
704 | |||
705 | EFX_BUG_ON_PARANOID(len <= 0); | ||
706 | |||
707 | fill_level = tx_queue->insert_count - tx_queue->old_read_count; | ||
708 | /* -1 as there is no way to represent all descriptors used */ | ||
709 | q_space = efx->type->txd_ring_mask - 1 - fill_level; | ||
710 | |||
711 | while (1) { | ||
712 | if (unlikely(q_space-- <= 0)) { | ||
713 | /* It might be that completions have happened | ||
714 | * since the xmit path last checked. Update | ||
715 | * the xmit path's copy of read_count. | ||
716 | */ | ||
717 | ++tx_queue->stopped; | ||
718 | /* This memory barrier protects the change of | ||
719 | * stopped from the access of read_count. */ | ||
720 | smp_mb(); | ||
721 | tx_queue->old_read_count = | ||
722 | *(volatile unsigned *)&tx_queue->read_count; | ||
723 | fill_level = (tx_queue->insert_count | ||
724 | - tx_queue->old_read_count); | ||
725 | q_space = efx->type->txd_ring_mask - 1 - fill_level; | ||
726 | if (unlikely(q_space-- <= 0)) | ||
727 | return 1; | ||
728 | smp_mb(); | ||
729 | --tx_queue->stopped; | ||
730 | } | ||
731 | |||
732 | insert_ptr = tx_queue->insert_count & efx->type->txd_ring_mask; | ||
733 | buffer = &tx_queue->buffer[insert_ptr]; | ||
734 | ++tx_queue->insert_count; | ||
735 | |||
736 | EFX_BUG_ON_PARANOID(tx_queue->insert_count - | ||
737 | tx_queue->read_count > | ||
738 | efx->type->txd_ring_mask); | ||
739 | |||
740 | efx_tsoh_free(tx_queue, buffer); | ||
741 | EFX_BUG_ON_PARANOID(buffer->len); | ||
742 | EFX_BUG_ON_PARANOID(buffer->unmap_len); | ||
743 | EFX_BUG_ON_PARANOID(buffer->skb); | ||
744 | EFX_BUG_ON_PARANOID(buffer->continuation != 1); | ||
745 | EFX_BUG_ON_PARANOID(buffer->tsoh); | ||
746 | |||
747 | buffer->dma_addr = dma_addr; | ||
748 | |||
749 | /* Ensure we do not cross a boundary unsupported by H/W */ | ||
750 | dma_len = (~dma_addr & efx->type->tx_dma_mask) + 1; | ||
751 | |||
752 | misalign = (unsigned)dma_addr & efx->type->bug5391_mask; | ||
753 | if (misalign && dma_len + misalign > 512) | ||
754 | dma_len = 512 - misalign; | ||
755 | |||
756 | /* If there is enough space to send then do so */ | ||
757 | if (dma_len >= len) | ||
758 | break; | ||
759 | |||
760 | buffer->len = dma_len; /* Don't set the other members */ | ||
761 | dma_addr += dma_len; | ||
762 | len -= dma_len; | ||
763 | } | ||
764 | |||
765 | EFX_BUG_ON_PARANOID(!len); | ||
766 | buffer->len = len; | ||
767 | buffer->skb = skb; | ||
768 | buffer->continuation = !end_of_packet; | ||
769 | buffer->unmap_addr = unmap_addr; | ||
770 | buffer->unmap_len = unmap_len; | ||
771 | return 0; | ||
772 | } | ||
773 | |||
774 | |||
775 | /* | ||
776 | * Put a TSO header into the TX queue. | ||
777 | * | ||
778 | * This is special-cased because we know that it is small enough to fit in | ||
779 | * a single fragment, and we know it doesn't cross a page boundary. It | ||
780 | * also allows us to not worry about end-of-packet etc. | ||
781 | */ | ||
782 | static inline void efx_tso_put_header(struct efx_tx_queue *tx_queue, | ||
783 | struct efx_tso_header *tsoh, unsigned len) | ||
784 | { | ||
785 | struct efx_tx_buffer *buffer; | ||
786 | |||
787 | buffer = &tx_queue->buffer[tx_queue->insert_count & | ||
788 | tx_queue->efx->type->txd_ring_mask]; | ||
789 | efx_tsoh_free(tx_queue, buffer); | ||
790 | EFX_BUG_ON_PARANOID(buffer->len); | ||
791 | EFX_BUG_ON_PARANOID(buffer->unmap_len); | ||
792 | EFX_BUG_ON_PARANOID(buffer->skb); | ||
793 | EFX_BUG_ON_PARANOID(buffer->continuation != 1); | ||
794 | EFX_BUG_ON_PARANOID(buffer->tsoh); | ||
795 | buffer->len = len; | ||
796 | buffer->dma_addr = tsoh->dma_addr; | ||
797 | buffer->tsoh = tsoh; | ||
798 | |||
799 | ++tx_queue->insert_count; | ||
800 | } | ||
801 | |||
802 | |||
803 | /* Remove descriptors put into a tx_queue. */ | ||
804 | static void efx_enqueue_unwind(struct efx_tx_queue *tx_queue) | ||
805 | { | ||
806 | struct efx_tx_buffer *buffer; | ||
807 | |||
808 | /* Work backwards until we hit the original insert pointer value */ | ||
809 | while (tx_queue->insert_count != tx_queue->write_count) { | ||
810 | --tx_queue->insert_count; | ||
811 | buffer = &tx_queue->buffer[tx_queue->insert_count & | ||
812 | tx_queue->efx->type->txd_ring_mask]; | ||
813 | efx_tsoh_free(tx_queue, buffer); | ||
814 | EFX_BUG_ON_PARANOID(buffer->skb); | ||
815 | buffer->len = 0; | ||
816 | buffer->continuation = 1; | ||
817 | if (buffer->unmap_len) { | ||
818 | pci_unmap_page(tx_queue->efx->pci_dev, | ||
819 | buffer->unmap_addr, | ||
820 | buffer->unmap_len, PCI_DMA_TODEVICE); | ||
821 | buffer->unmap_len = 0; | ||
822 | } | ||
823 | } | ||
824 | } | ||
825 | |||
826 | |||
827 | /* Parse the SKB header and initialise state. */ | ||
828 | static inline void tso_start(struct tso_state *st, const struct sk_buff *skb) | ||
829 | { | ||
830 | /* All ethernet/IP/TCP headers combined size is TCP header size | ||
831 | * plus offset of TCP header relative to start of packet. | ||
832 | */ | ||
833 | st->p.header_length = ((tcp_hdr(skb)->doff << 2u) | ||
834 | + PTR_DIFF(tcp_hdr(skb), skb->data)); | ||
835 | st->p.full_packet_size = (st->p.header_length | ||
836 | + skb_shinfo(skb)->gso_size); | ||
837 | |||
838 | st->p.ipv4_id = ntohs(ip_hdr(skb)->id); | ||
839 | st->seqnum = ntohl(tcp_hdr(skb)->seq); | ||
840 | |||
841 | EFX_BUG_ON_PARANOID(tcp_hdr(skb)->urg); | ||
842 | EFX_BUG_ON_PARANOID(tcp_hdr(skb)->syn); | ||
843 | EFX_BUG_ON_PARANOID(tcp_hdr(skb)->rst); | ||
844 | |||
845 | st->packet_space = st->p.full_packet_size; | ||
846 | st->remaining_len = skb->len - st->p.header_length; | ||
847 | } | ||
848 | |||
849 | |||
850 | /** | ||
851 | * tso_get_fragment - record fragment details and map for DMA | ||
852 | * @st: TSO state | ||
853 | * @efx: Efx NIC | ||
854 | * @data: Pointer to fragment data | ||
855 | * @len: Length of fragment | ||
856 | * | ||
857 | * Record fragment details and map for DMA. Return 0 on success, or | ||
858 | * -%ENOMEM if DMA mapping fails. | ||
859 | */ | ||
860 | static inline int tso_get_fragment(struct tso_state *st, struct efx_nic *efx, | ||
861 | int len, struct page *page, int page_off) | ||
862 | { | ||
863 | |||
864 | st->ifc.unmap_addr = pci_map_page(efx->pci_dev, page, page_off, | ||
865 | len, PCI_DMA_TODEVICE); | ||
866 | if (likely(!pci_dma_mapping_error(st->ifc.unmap_addr))) { | ||
867 | st->ifc.unmap_len = len; | ||
868 | st->ifc.len = len; | ||
869 | st->ifc.dma_addr = st->ifc.unmap_addr; | ||
870 | st->ifc.page = page; | ||
871 | st->ifc.page_off = page_off; | ||
872 | return 0; | ||
873 | } | ||
874 | return -ENOMEM; | ||
875 | } | ||
876 | |||
877 | |||
878 | /** | ||
879 | * tso_fill_packet_with_fragment - form descriptors for the current fragment | ||
880 | * @tx_queue: Efx TX queue | ||
881 | * @skb: Socket buffer | ||
882 | * @st: TSO state | ||
883 | * | ||
884 | * Form descriptors for the current fragment, until we reach the end | ||
885 | * of fragment or end-of-packet. Return 0 on success, 1 if not enough | ||
886 | * space in @tx_queue. | ||
887 | */ | ||
888 | static inline int tso_fill_packet_with_fragment(struct efx_tx_queue *tx_queue, | ||
889 | const struct sk_buff *skb, | ||
890 | struct tso_state *st) | ||
891 | { | ||
892 | |||
893 | int n, end_of_packet, rc; | ||
894 | |||
895 | if (st->ifc.len == 0) | ||
896 | return 0; | ||
897 | if (st->packet_space == 0) | ||
898 | return 0; | ||
899 | |||
900 | EFX_BUG_ON_PARANOID(st->ifc.len <= 0); | ||
901 | EFX_BUG_ON_PARANOID(st->packet_space <= 0); | ||
902 | |||
903 | n = min(st->ifc.len, st->packet_space); | ||
904 | |||
905 | st->packet_space -= n; | ||
906 | st->remaining_len -= n; | ||
907 | st->ifc.len -= n; | ||
908 | st->ifc.page_off += n; | ||
909 | end_of_packet = st->remaining_len == 0 || st->packet_space == 0; | ||
910 | |||
911 | rc = efx_tx_queue_insert(tx_queue, st->ifc.dma_addr, n, | ||
912 | st->remaining_len ? NULL : skb, | ||
913 | end_of_packet, st->ifc.unmap_addr, | ||
914 | st->ifc.len ? 0 : st->ifc.unmap_len); | ||
915 | |||
916 | st->ifc.dma_addr += n; | ||
917 | |||
918 | return rc; | ||
919 | } | ||
920 | |||
921 | |||
922 | /** | ||
923 | * tso_start_new_packet - generate a new header and prepare for the new packet | ||
924 | * @tx_queue: Efx TX queue | ||
925 | * @skb: Socket buffer | ||
926 | * @st: TSO state | ||
927 | * | ||
928 | * Generate a new header and prepare for the new packet. Return 0 on | ||
929 | * success, or -1 if failed to alloc header. | ||
930 | */ | ||
931 | static inline int tso_start_new_packet(struct efx_tx_queue *tx_queue, | ||
932 | const struct sk_buff *skb, | ||
933 | struct tso_state *st) | ||
934 | { | ||
935 | struct efx_tso_header *tsoh; | ||
936 | struct iphdr *tsoh_iph; | ||
937 | struct tcphdr *tsoh_th; | ||
938 | unsigned ip_length; | ||
939 | u8 *header; | ||
940 | |||
941 | /* Allocate a DMA-mapped header buffer. */ | ||
942 | if (likely(TSOH_SIZE(st->p.header_length) <= TSOH_STD_SIZE)) { | ||
943 | if (tx_queue->tso_headers_free == NULL) { | ||
944 | if (efx_tsoh_block_alloc(tx_queue)) | ||
945 | return -1; | ||
946 | } | ||
947 | EFX_BUG_ON_PARANOID(!tx_queue->tso_headers_free); | ||
948 | tsoh = tx_queue->tso_headers_free; | ||
949 | tx_queue->tso_headers_free = tsoh->next; | ||
950 | tsoh->unmap_len = 0; | ||
951 | } else { | ||
952 | tx_queue->tso_long_headers++; | ||
953 | tsoh = efx_tsoh_heap_alloc(tx_queue, st->p.header_length); | ||
954 | if (unlikely(!tsoh)) | ||
955 | return -1; | ||
956 | } | ||
957 | |||
958 | header = TSOH_BUFFER(tsoh); | ||
959 | tsoh_th = (struct tcphdr *)(header + SKB_TCP_OFF(skb)); | ||
960 | tsoh_iph = (struct iphdr *)(header + SKB_IPV4_OFF(skb)); | ||
961 | |||
962 | /* Copy and update the headers. */ | ||
963 | memcpy(header, skb->data, st->p.header_length); | ||
964 | |||
965 | tsoh_th->seq = htonl(st->seqnum); | ||
966 | st->seqnum += skb_shinfo(skb)->gso_size; | ||
967 | if (st->remaining_len > skb_shinfo(skb)->gso_size) { | ||
968 | /* This packet will not finish the TSO burst. */ | ||
969 | ip_length = st->p.full_packet_size - ETH_HDR_LEN(skb); | ||
970 | tsoh_th->fin = 0; | ||
971 | tsoh_th->psh = 0; | ||
972 | } else { | ||
973 | /* This packet will be the last in the TSO burst. */ | ||
974 | ip_length = (st->p.header_length - ETH_HDR_LEN(skb) | ||
975 | + st->remaining_len); | ||
976 | tsoh_th->fin = tcp_hdr(skb)->fin; | ||
977 | tsoh_th->psh = tcp_hdr(skb)->psh; | ||
978 | } | ||
979 | tsoh_iph->tot_len = htons(ip_length); | ||
980 | |||
981 | /* Linux leaves suitable gaps in the IP ID space for us to fill. */ | ||
982 | tsoh_iph->id = htons(st->p.ipv4_id); | ||
983 | st->p.ipv4_id++; | ||
984 | |||
985 | st->packet_space = skb_shinfo(skb)->gso_size; | ||
986 | ++tx_queue->tso_packets; | ||
987 | |||
988 | /* Form a descriptor for this header. */ | ||
989 | efx_tso_put_header(tx_queue, tsoh, st->p.header_length); | ||
990 | |||
991 | return 0; | ||
992 | } | ||
993 | |||
994 | |||
995 | /** | ||
996 | * efx_enqueue_skb_tso - segment and transmit a TSO socket buffer | ||
997 | * @tx_queue: Efx TX queue | ||
998 | * @skb: Socket buffer | ||
999 | * | ||
1000 | * Context: You must hold netif_tx_lock() to call this function. | ||
1001 | * | ||
1002 | * Add socket buffer @skb to @tx_queue, doing TSO or return != 0 if | ||
1003 | * @skb was not enqueued. In all cases @skb is consumed. Return | ||
1004 | * %NETDEV_TX_OK or %NETDEV_TX_BUSY. | ||
1005 | */ | ||
1006 | static int efx_enqueue_skb_tso(struct efx_tx_queue *tx_queue, | ||
1007 | const struct sk_buff *skb) | ||
1008 | { | ||
1009 | int frag_i, rc, rc2 = NETDEV_TX_OK; | ||
1010 | struct tso_state state; | ||
1011 | skb_frag_t *f; | ||
1012 | |||
1013 | /* Verify TSO is safe - these checks should never fail. */ | ||
1014 | efx_tso_check_safe(skb); | ||
1015 | |||
1016 | EFX_BUG_ON_PARANOID(tx_queue->write_count != tx_queue->insert_count); | ||
1017 | |||
1018 | tso_start(&state, skb); | ||
1019 | |||
1020 | /* Assume that skb header area contains exactly the headers, and | ||
1021 | * all payload is in the frag list. | ||
1022 | */ | ||
1023 | if (skb_headlen(skb) == state.p.header_length) { | ||
1024 | /* Grab the first payload fragment. */ | ||
1025 | EFX_BUG_ON_PARANOID(skb_shinfo(skb)->nr_frags < 1); | ||
1026 | frag_i = 0; | ||
1027 | f = &skb_shinfo(skb)->frags[frag_i]; | ||
1028 | rc = tso_get_fragment(&state, tx_queue->efx, | ||
1029 | f->size, f->page, f->page_offset); | ||
1030 | if (rc) | ||
1031 | goto mem_err; | ||
1032 | } else { | ||
1033 | /* It may look like this code fragment assumes that the | ||
1034 | * skb->data portion does not cross a page boundary, but | ||
1035 | * that is not the case. It is guaranteed to be direct | ||
1036 | * mapped memory, and therefore is physically contiguous, | ||
1037 | * and so DMA will work fine. kmap_atomic() on this region | ||
1038 | * will just return the direct mapping, so that will work | ||
1039 | * too. | ||
1040 | */ | ||
1041 | int page_off = (unsigned long)skb->data & (PAGE_SIZE - 1); | ||
1042 | int hl = state.p.header_length; | ||
1043 | rc = tso_get_fragment(&state, tx_queue->efx, | ||
1044 | skb_headlen(skb) - hl, | ||
1045 | virt_to_page(skb->data), page_off + hl); | ||
1046 | if (rc) | ||
1047 | goto mem_err; | ||
1048 | frag_i = -1; | ||
1049 | } | ||
1050 | |||
1051 | if (tso_start_new_packet(tx_queue, skb, &state) < 0) | ||
1052 | goto mem_err; | ||
1053 | |||
1054 | while (1) { | ||
1055 | rc = tso_fill_packet_with_fragment(tx_queue, skb, &state); | ||
1056 | if (unlikely(rc)) | ||
1057 | goto stop; | ||
1058 | |||
1059 | /* Move onto the next fragment? */ | ||
1060 | if (state.ifc.len == 0) { | ||
1061 | if (++frag_i >= skb_shinfo(skb)->nr_frags) | ||
1062 | /* End of payload reached. */ | ||
1063 | break; | ||
1064 | f = &skb_shinfo(skb)->frags[frag_i]; | ||
1065 | rc = tso_get_fragment(&state, tx_queue->efx, | ||
1066 | f->size, f->page, f->page_offset); | ||
1067 | if (rc) | ||
1068 | goto mem_err; | ||
1069 | } | ||
1070 | |||
1071 | /* Start at new packet? */ | ||
1072 | if (state.packet_space == 0 && | ||
1073 | tso_start_new_packet(tx_queue, skb, &state) < 0) | ||
1074 | goto mem_err; | ||
1075 | } | ||
1076 | |||
1077 | /* Pass off to hardware */ | ||
1078 | falcon_push_buffers(tx_queue); | ||
1079 | |||
1080 | tx_queue->tso_bursts++; | ||
1081 | return NETDEV_TX_OK; | ||
1082 | |||
1083 | mem_err: | ||
1084 | EFX_ERR(tx_queue->efx, "Out of memory for TSO headers, or PCI mapping" | ||
1085 | " error\n"); | ||
1086 | dev_kfree_skb_any((struct sk_buff *)skb); | ||
1087 | goto unwind; | ||
1088 | |||
1089 | stop: | ||
1090 | rc2 = NETDEV_TX_BUSY; | ||
1091 | |||
1092 | /* Stop the queue if it wasn't stopped before. */ | ||
1093 | if (tx_queue->stopped == 1) | ||
1094 | efx_stop_queue(tx_queue->efx); | ||
1095 | |||
1096 | unwind: | ||
1097 | efx_enqueue_unwind(tx_queue); | ||
1098 | return rc2; | ||
1099 | } | ||
1100 | |||
1101 | |||
1102 | /* | ||
1103 | * Free up all TSO datastructures associated with tx_queue. This | ||
1104 | * routine should be called only once the tx_queue is both empty and | ||
1105 | * will no longer be used. | ||
1106 | */ | ||
1107 | static void efx_fini_tso(struct efx_tx_queue *tx_queue) | ||
1108 | { | ||
1109 | unsigned i; | ||
1110 | |||
1111 | if (tx_queue->buffer) { | ||
1112 | for (i = 0; i <= tx_queue->efx->type->txd_ring_mask; ++i) | ||
1113 | efx_tsoh_free(tx_queue, &tx_queue->buffer[i]); | ||
1114 | } | ||
1115 | |||
1116 | while (tx_queue->tso_headers_free != NULL) | ||
1117 | efx_tsoh_block_free(tx_queue, tx_queue->tso_headers_free, | ||
1118 | tx_queue->efx->pci_dev); | ||
1119 | } | ||
diff --git a/drivers/net/sfc/workarounds.h b/drivers/net/sfc/workarounds.h index dca62f190198..35ab19c27f8d 100644 --- a/drivers/net/sfc/workarounds.h +++ b/drivers/net/sfc/workarounds.h | |||
@@ -16,7 +16,7 @@ | |||
16 | */ | 16 | */ |
17 | 17 | ||
18 | #define EFX_WORKAROUND_ALWAYS(efx) 1 | 18 | #define EFX_WORKAROUND_ALWAYS(efx) 1 |
19 | #define EFX_WORKAROUND_FALCON_A(efx) (FALCON_REV(efx) <= FALCON_REV_A1) | 19 | #define EFX_WORKAROUND_FALCON_A(efx) (falcon_rev(efx) <= FALCON_REV_A1) |
20 | 20 | ||
21 | /* XAUI resets if link not detected */ | 21 | /* XAUI resets if link not detected */ |
22 | #define EFX_WORKAROUND_5147 EFX_WORKAROUND_ALWAYS | 22 | #define EFX_WORKAROUND_5147 EFX_WORKAROUND_ALWAYS |
diff --git a/drivers/net/sfc/xfp_phy.c b/drivers/net/sfc/xfp_phy.c index 66dd5bf1eaa9..f3684ad28887 100644 --- a/drivers/net/sfc/xfp_phy.c +++ b/drivers/net/sfc/xfp_phy.c | |||
@@ -24,6 +24,10 @@ | |||
24 | MDIO_MMDREG_DEVS0_PMAPMD | \ | 24 | MDIO_MMDREG_DEVS0_PMAPMD | \ |
25 | MDIO_MMDREG_DEVS0_PHYXS) | 25 | MDIO_MMDREG_DEVS0_PHYXS) |
26 | 26 | ||
27 | #define XFP_LOOPBACKS ((1 << LOOPBACK_PCS) | \ | ||
28 | (1 << LOOPBACK_PMAPMD) | \ | ||
29 | (1 << LOOPBACK_NETWORK)) | ||
30 | |||
27 | /****************************************************************************/ | 31 | /****************************************************************************/ |
28 | /* Quake-specific MDIO registers */ | 32 | /* Quake-specific MDIO registers */ |
29 | #define MDIO_QUAKE_LED0_REG (0xD006) | 33 | #define MDIO_QUAKE_LED0_REG (0xD006) |
@@ -35,6 +39,10 @@ void xfp_set_led(struct efx_nic *p, int led, int mode) | |||
35 | mode); | 39 | mode); |
36 | } | 40 | } |
37 | 41 | ||
42 | struct xfp_phy_data { | ||
43 | int tx_disabled; | ||
44 | }; | ||
45 | |||
38 | #define XFP_MAX_RESET_TIME 500 | 46 | #define XFP_MAX_RESET_TIME 500 |
39 | #define XFP_RESET_WAIT 10 | 47 | #define XFP_RESET_WAIT 10 |
40 | 48 | ||
@@ -72,18 +80,33 @@ static int xfp_reset_phy(struct efx_nic *efx) | |||
72 | 80 | ||
73 | static int xfp_phy_init(struct efx_nic *efx) | 81 | static int xfp_phy_init(struct efx_nic *efx) |
74 | { | 82 | { |
83 | struct xfp_phy_data *phy_data; | ||
75 | u32 devid = mdio_clause45_read_id(efx, MDIO_MMD_PHYXS); | 84 | u32 devid = mdio_clause45_read_id(efx, MDIO_MMD_PHYXS); |
76 | int rc; | 85 | int rc; |
77 | 86 | ||
87 | phy_data = kzalloc(sizeof(struct xfp_phy_data), GFP_KERNEL); | ||
88 | if (!phy_data) | ||
89 | return -ENOMEM; | ||
90 | efx->phy_data = phy_data; | ||
91 | |||
78 | EFX_INFO(efx, "XFP: PHY ID reg %x (OUI %x model %x revision" | 92 | EFX_INFO(efx, "XFP: PHY ID reg %x (OUI %x model %x revision" |
79 | " %x)\n", devid, MDIO_ID_OUI(devid), MDIO_ID_MODEL(devid), | 93 | " %x)\n", devid, MDIO_ID_OUI(devid), MDIO_ID_MODEL(devid), |
80 | MDIO_ID_REV(devid)); | 94 | MDIO_ID_REV(devid)); |
81 | 95 | ||
96 | phy_data->tx_disabled = efx->tx_disabled; | ||
97 | |||
82 | rc = xfp_reset_phy(efx); | 98 | rc = xfp_reset_phy(efx); |
83 | 99 | ||
84 | EFX_INFO(efx, "XFP: PHY init %s.\n", | 100 | EFX_INFO(efx, "XFP: PHY init %s.\n", |
85 | rc ? "failed" : "successful"); | 101 | rc ? "failed" : "successful"); |
102 | if (rc < 0) | ||
103 | goto fail; | ||
86 | 104 | ||
105 | return 0; | ||
106 | |||
107 | fail: | ||
108 | kfree(efx->phy_data); | ||
109 | efx->phy_data = NULL; | ||
87 | return rc; | 110 | return rc; |
88 | } | 111 | } |
89 | 112 | ||
@@ -110,6 +133,16 @@ static int xfp_phy_check_hw(struct efx_nic *efx) | |||
110 | 133 | ||
111 | static void xfp_phy_reconfigure(struct efx_nic *efx) | 134 | static void xfp_phy_reconfigure(struct efx_nic *efx) |
112 | { | 135 | { |
136 | struct xfp_phy_data *phy_data = efx->phy_data; | ||
137 | |||
138 | /* Reset the PHY when moving from tx off to tx on */ | ||
139 | if (phy_data->tx_disabled && !efx->tx_disabled) | ||
140 | xfp_reset_phy(efx); | ||
141 | |||
142 | mdio_clause45_transmit_disable(efx); | ||
143 | mdio_clause45_phy_reconfigure(efx); | ||
144 | |||
145 | phy_data->tx_disabled = efx->tx_disabled; | ||
113 | efx->link_up = xfp_link_ok(efx); | 146 | efx->link_up = xfp_link_ok(efx); |
114 | efx->link_options = GM_LPA_10000FULL; | 147 | efx->link_options = GM_LPA_10000FULL; |
115 | } | 148 | } |
@@ -119,6 +152,10 @@ static void xfp_phy_fini(struct efx_nic *efx) | |||
119 | { | 152 | { |
120 | /* Clobber the LED if it was blinking */ | 153 | /* Clobber the LED if it was blinking */ |
121 | efx->board_info.blink(efx, 0); | 154 | efx->board_info.blink(efx, 0); |
155 | |||
156 | /* Free the context block */ | ||
157 | kfree(efx->phy_data); | ||
158 | efx->phy_data = NULL; | ||
122 | } | 159 | } |
123 | 160 | ||
124 | struct efx_phy_operations falcon_xfp_phy_ops = { | 161 | struct efx_phy_operations falcon_xfp_phy_ops = { |
@@ -129,4 +166,5 @@ struct efx_phy_operations falcon_xfp_phy_ops = { | |||
129 | .clear_interrupt = xfp_phy_clear_interrupt, | 166 | .clear_interrupt = xfp_phy_clear_interrupt, |
130 | .reset_xaui = efx_port_dummy_op_void, | 167 | .reset_xaui = efx_port_dummy_op_void, |
131 | .mmds = XFP_REQUIRED_DEVS, | 168 | .mmds = XFP_REQUIRED_DEVS, |
169 | .loopbacks = XFP_LOOPBACKS, | ||
132 | }; | 170 | }; |
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index f226bcac7d17..c8a5ef2d75f4 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c | |||
@@ -118,6 +118,7 @@ static const struct pci_device_id sky2_id_table[] = { | |||
118 | { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4352) }, /* 88E8038 */ | 118 | { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4352) }, /* 88E8038 */ |
119 | { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4353) }, /* 88E8039 */ | 119 | { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4353) }, /* 88E8039 */ |
120 | { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4354) }, /* 88E8040 */ | 120 | { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4354) }, /* 88E8040 */ |
121 | { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4355) }, /* 88E8040T */ | ||
121 | { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4356) }, /* 88EC033 */ | 122 | { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4356) }, /* 88EC033 */ |
122 | { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4357) }, /* 88E8042 */ | 123 | { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4357) }, /* 88E8042 */ |
123 | { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x435A) }, /* 88E8048 */ | 124 | { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x435A) }, /* 88E8048 */ |
@@ -1159,17 +1160,9 @@ static int sky2_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) | |||
1159 | } | 1160 | } |
1160 | 1161 | ||
1161 | #ifdef SKY2_VLAN_TAG_USED | 1162 | #ifdef SKY2_VLAN_TAG_USED |
1162 | static void sky2_vlan_rx_register(struct net_device *dev, struct vlan_group *grp) | 1163 | static void sky2_set_vlan_mode(struct sky2_hw *hw, u16 port, bool onoff) |
1163 | { | 1164 | { |
1164 | struct sky2_port *sky2 = netdev_priv(dev); | 1165 | if (onoff) { |
1165 | struct sky2_hw *hw = sky2->hw; | ||
1166 | u16 port = sky2->port; | ||
1167 | |||
1168 | netif_tx_lock_bh(dev); | ||
1169 | napi_disable(&hw->napi); | ||
1170 | |||
1171 | sky2->vlgrp = grp; | ||
1172 | if (grp) { | ||
1173 | sky2_write32(hw, SK_REG(port, RX_GMF_CTRL_T), | 1166 | sky2_write32(hw, SK_REG(port, RX_GMF_CTRL_T), |
1174 | RX_VLAN_STRIP_ON); | 1167 | RX_VLAN_STRIP_ON); |
1175 | sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T), | 1168 | sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T), |
@@ -1180,6 +1173,19 @@ static void sky2_vlan_rx_register(struct net_device *dev, struct vlan_group *grp | |||
1180 | sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T), | 1173 | sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T), |
1181 | TX_VLAN_TAG_OFF); | 1174 | TX_VLAN_TAG_OFF); |
1182 | } | 1175 | } |
1176 | } | ||
1177 | |||
1178 | static void sky2_vlan_rx_register(struct net_device *dev, struct vlan_group *grp) | ||
1179 | { | ||
1180 | struct sky2_port *sky2 = netdev_priv(dev); | ||
1181 | struct sky2_hw *hw = sky2->hw; | ||
1182 | u16 port = sky2->port; | ||
1183 | |||
1184 | netif_tx_lock_bh(dev); | ||
1185 | napi_disable(&hw->napi); | ||
1186 | |||
1187 | sky2->vlgrp = grp; | ||
1188 | sky2_set_vlan_mode(hw, port, grp != NULL); | ||
1183 | 1189 | ||
1184 | sky2_read32(hw, B0_Y2_SP_LISR); | 1190 | sky2_read32(hw, B0_Y2_SP_LISR); |
1185 | napi_enable(&hw->napi); | 1191 | napi_enable(&hw->napi); |
@@ -1418,6 +1424,10 @@ static int sky2_up(struct net_device *dev) | |||
1418 | sky2_prefetch_init(hw, txqaddr[port], sky2->tx_le_map, | 1424 | sky2_prefetch_init(hw, txqaddr[port], sky2->tx_le_map, |
1419 | TX_RING_SIZE - 1); | 1425 | TX_RING_SIZE - 1); |
1420 | 1426 | ||
1427 | #ifdef SKY2_VLAN_TAG_USED | ||
1428 | sky2_set_vlan_mode(hw, port, sky2->vlgrp != NULL); | ||
1429 | #endif | ||
1430 | |||
1421 | err = sky2_rx_start(sky2); | 1431 | err = sky2_rx_start(sky2); |
1422 | if (err) | 1432 | if (err) |
1423 | goto err_out; | 1433 | goto err_out; |
@@ -4395,7 +4405,9 @@ static int sky2_resume(struct pci_dev *pdev) | |||
4395 | if (err) { | 4405 | if (err) { |
4396 | printk(KERN_ERR PFX "%s: could not up: %d\n", | 4406 | printk(KERN_ERR PFX "%s: could not up: %d\n", |
4397 | dev->name, err); | 4407 | dev->name, err); |
4408 | rtnl_lock(); | ||
4398 | dev_close(dev); | 4409 | dev_close(dev); |
4410 | rtnl_unlock(); | ||
4399 | goto out; | 4411 | goto out; |
4400 | } | 4412 | } |
4401 | } | 4413 | } |
diff --git a/drivers/net/sky2.h b/drivers/net/sky2.h index 7bb3ba9bcbd8..c0a5eea20007 100644 --- a/drivers/net/sky2.h +++ b/drivers/net/sky2.h | |||
@@ -1966,13 +1966,13 @@ struct sky2_status_le { | |||
1966 | struct tx_ring_info { | 1966 | struct tx_ring_info { |
1967 | struct sk_buff *skb; | 1967 | struct sk_buff *skb; |
1968 | DECLARE_PCI_UNMAP_ADDR(mapaddr); | 1968 | DECLARE_PCI_UNMAP_ADDR(mapaddr); |
1969 | DECLARE_PCI_UNMAP_ADDR(maplen); | 1969 | DECLARE_PCI_UNMAP_LEN(maplen); |
1970 | }; | 1970 | }; |
1971 | 1971 | ||
1972 | struct rx_ring_info { | 1972 | struct rx_ring_info { |
1973 | struct sk_buff *skb; | 1973 | struct sk_buff *skb; |
1974 | dma_addr_t data_addr; | 1974 | dma_addr_t data_addr; |
1975 | DECLARE_PCI_UNMAP_ADDR(data_size); | 1975 | DECLARE_PCI_UNMAP_LEN(data_size); |
1976 | dma_addr_t frag_addr[ETH_JUMBO_MTU >> PAGE_SHIFT]; | 1976 | dma_addr_t frag_addr[ETH_JUMBO_MTU >> PAGE_SHIFT]; |
1977 | }; | 1977 | }; |
1978 | 1978 | ||
diff --git a/drivers/net/smc911x.c b/drivers/net/smc911x.c index 4e2800205189..e2ee91a6ae7e 100644 --- a/drivers/net/smc911x.c +++ b/drivers/net/smc911x.c | |||
@@ -136,7 +136,6 @@ struct smc911x_local { | |||
136 | 136 | ||
137 | /* work queue */ | 137 | /* work queue */ |
138 | struct work_struct phy_configure; | 138 | struct work_struct phy_configure; |
139 | int work_pending; | ||
140 | 139 | ||
141 | int tx_throttle; | 140 | int tx_throttle; |
142 | spinlock_t lock; | 141 | spinlock_t lock; |
@@ -960,11 +959,11 @@ static void smc911x_phy_configure(struct work_struct *work) | |||
960 | * We should not be called if phy_type is zero. | 959 | * We should not be called if phy_type is zero. |
961 | */ | 960 | */ |
962 | if (lp->phy_type == 0) | 961 | if (lp->phy_type == 0) |
963 | goto smc911x_phy_configure_exit_nolock; | 962 | return; |
964 | 963 | ||
965 | if (smc911x_phy_reset(dev, phyaddr)) { | 964 | if (smc911x_phy_reset(dev, phyaddr)) { |
966 | printk("%s: PHY reset timed out\n", dev->name); | 965 | printk("%s: PHY reset timed out\n", dev->name); |
967 | goto smc911x_phy_configure_exit_nolock; | 966 | return; |
968 | } | 967 | } |
969 | spin_lock_irqsave(&lp->lock, flags); | 968 | spin_lock_irqsave(&lp->lock, flags); |
970 | 969 | ||
@@ -1033,8 +1032,6 @@ static void smc911x_phy_configure(struct work_struct *work) | |||
1033 | 1032 | ||
1034 | smc911x_phy_configure_exit: | 1033 | smc911x_phy_configure_exit: |
1035 | spin_unlock_irqrestore(&lp->lock, flags); | 1034 | spin_unlock_irqrestore(&lp->lock, flags); |
1036 | smc911x_phy_configure_exit_nolock: | ||
1037 | lp->work_pending = 0; | ||
1038 | } | 1035 | } |
1039 | 1036 | ||
1040 | /* | 1037 | /* |
@@ -1356,11 +1353,8 @@ static void smc911x_timeout(struct net_device *dev) | |||
1356 | * smc911x_phy_configure() calls msleep() which calls schedule_timeout() | 1353 | * smc911x_phy_configure() calls msleep() which calls schedule_timeout() |
1357 | * which calls schedule(). Hence we use a work queue. | 1354 | * which calls schedule(). Hence we use a work queue. |
1358 | */ | 1355 | */ |
1359 | if (lp->phy_type != 0) { | 1356 | if (lp->phy_type != 0) |
1360 | if (schedule_work(&lp->phy_configure)) { | 1357 | schedule_work(&lp->phy_configure); |
1361 | lp->work_pending = 1; | ||
1362 | } | ||
1363 | } | ||
1364 | 1358 | ||
1365 | /* We can accept TX packets again */ | 1359 | /* We can accept TX packets again */ |
1366 | dev->trans_start = jiffies; | 1360 | dev->trans_start = jiffies; |
@@ -1531,16 +1525,8 @@ static int smc911x_close(struct net_device *dev) | |||
1531 | if (lp->phy_type != 0) { | 1525 | if (lp->phy_type != 0) { |
1532 | /* We need to ensure that no calls to | 1526 | /* We need to ensure that no calls to |
1533 | * smc911x_phy_configure are pending. | 1527 | * smc911x_phy_configure are pending. |
1534 | |||
1535 | * flush_scheduled_work() cannot be called because we | ||
1536 | * are running with the netlink semaphore held (from | ||
1537 | * devinet_ioctl()) and the pending work queue | ||
1538 | * contains linkwatch_event() (scheduled by | ||
1539 | * netif_carrier_off() above). linkwatch_event() also | ||
1540 | * wants the netlink semaphore. | ||
1541 | */ | 1528 | */ |
1542 | while (lp->work_pending) | 1529 | cancel_work_sync(&lp->phy_configure); |
1543 | schedule(); | ||
1544 | smc911x_phy_powerdown(dev, lp->mii.phy_id); | 1530 | smc911x_phy_powerdown(dev, lp->mii.phy_id); |
1545 | } | 1531 | } |
1546 | 1532 | ||
diff --git a/drivers/net/smc91x.c b/drivers/net/smc91x.c index a188e33484e6..f2051b209da2 100644 --- a/drivers/net/smc91x.c +++ b/drivers/net/smc91x.c | |||
@@ -1016,15 +1016,8 @@ static void smc_phy_powerdown(struct net_device *dev) | |||
1016 | 1016 | ||
1017 | /* We need to ensure that no calls to smc_phy_configure are | 1017 | /* We need to ensure that no calls to smc_phy_configure are |
1018 | pending. | 1018 | pending. |
1019 | |||
1020 | flush_scheduled_work() cannot be called because we are | ||
1021 | running with the netlink semaphore held (from | ||
1022 | devinet_ioctl()) and the pending work queue contains | ||
1023 | linkwatch_event() (scheduled by netif_carrier_off() | ||
1024 | above). linkwatch_event() also wants the netlink semaphore. | ||
1025 | */ | 1019 | */ |
1026 | while(lp->work_pending) | 1020 | cancel_work_sync(&lp->phy_configure); |
1027 | yield(); | ||
1028 | 1021 | ||
1029 | bmcr = smc_phy_read(dev, phy, MII_BMCR); | 1022 | bmcr = smc_phy_read(dev, phy, MII_BMCR); |
1030 | smc_phy_write(dev, phy, MII_BMCR, bmcr | BMCR_PDOWN); | 1023 | smc_phy_write(dev, phy, MII_BMCR, bmcr | BMCR_PDOWN); |
@@ -1161,7 +1154,6 @@ static void smc_phy_configure(struct work_struct *work) | |||
1161 | smc_phy_configure_exit: | 1154 | smc_phy_configure_exit: |
1162 | SMC_SELECT_BANK(lp, 2); | 1155 | SMC_SELECT_BANK(lp, 2); |
1163 | spin_unlock_irq(&lp->lock); | 1156 | spin_unlock_irq(&lp->lock); |
1164 | lp->work_pending = 0; | ||
1165 | } | 1157 | } |
1166 | 1158 | ||
1167 | /* | 1159 | /* |
@@ -1389,11 +1381,8 @@ static void smc_timeout(struct net_device *dev) | |||
1389 | * smc_phy_configure() calls msleep() which calls schedule_timeout() | 1381 | * smc_phy_configure() calls msleep() which calls schedule_timeout() |
1390 | * which calls schedule(). Hence we use a work queue. | 1382 | * which calls schedule(). Hence we use a work queue. |
1391 | */ | 1383 | */ |
1392 | if (lp->phy_type != 0) { | 1384 | if (lp->phy_type != 0) |
1393 | if (schedule_work(&lp->phy_configure)) { | 1385 | schedule_work(&lp->phy_configure); |
1394 | lp->work_pending = 1; | ||
1395 | } | ||
1396 | } | ||
1397 | 1386 | ||
1398 | /* We can accept TX packets again */ | 1387 | /* We can accept TX packets again */ |
1399 | dev->trans_start = jiffies; | 1388 | dev->trans_start = jiffies; |
diff --git a/drivers/net/smc91x.h b/drivers/net/smc91x.h index 69e97a1cb1c4..8606818653f8 100644 --- a/drivers/net/smc91x.h +++ b/drivers/net/smc91x.h | |||
@@ -93,14 +93,14 @@ | |||
93 | #define SMC_insw(a, r, p, l) insw ((unsigned long *)((a) + (r)), p, l) | 93 | #define SMC_insw(a, r, p, l) insw ((unsigned long *)((a) + (r)), p, l) |
94 | # endif | 94 | # endif |
95 | /* check if the mac in reg is valid */ | 95 | /* check if the mac in reg is valid */ |
96 | #define SMC_GET_MAC_ADDR(addr) \ | 96 | #define SMC_GET_MAC_ADDR(lp, addr) \ |
97 | do { \ | 97 | do { \ |
98 | unsigned int __v; \ | 98 | unsigned int __v; \ |
99 | __v = SMC_inw(ioaddr, ADDR0_REG); \ | 99 | __v = SMC_inw(ioaddr, ADDR0_REG(lp)); \ |
100 | addr[0] = __v; addr[1] = __v >> 8; \ | 100 | addr[0] = __v; addr[1] = __v >> 8; \ |
101 | __v = SMC_inw(ioaddr, ADDR1_REG); \ | 101 | __v = SMC_inw(ioaddr, ADDR1_REG(lp)); \ |
102 | addr[2] = __v; addr[3] = __v >> 8; \ | 102 | addr[2] = __v; addr[3] = __v >> 8; \ |
103 | __v = SMC_inw(ioaddr, ADDR2_REG); \ | 103 | __v = SMC_inw(ioaddr, ADDR2_REG(lp)); \ |
104 | addr[4] = __v; addr[5] = __v >> 8; \ | 104 | addr[4] = __v; addr[5] = __v >> 8; \ |
105 | if (*(u32 *)(&addr[0]) == 0xFFFFFFFF) { \ | 105 | if (*(u32 *)(&addr[0]) == 0xFFFFFFFF) { \ |
106 | random_ether_addr(addr); \ | 106 | random_ether_addr(addr); \ |
diff --git a/drivers/net/sun3lance.c b/drivers/net/sun3lance.c index f8d46134daca..359452a06c67 100644 --- a/drivers/net/sun3lance.c +++ b/drivers/net/sun3lance.c | |||
@@ -250,6 +250,9 @@ struct net_device * __init sun3lance_probe(int unit) | |||
250 | static int found; | 250 | static int found; |
251 | int err = -ENODEV; | 251 | int err = -ENODEV; |
252 | 252 | ||
253 | if (!MACH_IS_SUN3 && !MACH_IS_SUN3X) | ||
254 | return ERR_PTR(-ENODEV); | ||
255 | |||
253 | /* check that this machine has an onboard lance */ | 256 | /* check that this machine has an onboard lance */ |
254 | switch(idprom->id_machtype) { | 257 | switch(idprom->id_machtype) { |
255 | case SM_SUN3|SM_3_50: | 258 | case SM_SUN3|SM_3_50: |
diff --git a/drivers/net/sunhme.c b/drivers/net/sunhme.c index b4e7f30ea4e8..1aa425be3067 100644 --- a/drivers/net/sunhme.c +++ b/drivers/net/sunhme.c | |||
@@ -111,7 +111,7 @@ static __inline__ void tx_add_log(struct happy_meal *hp, unsigned int a, unsigne | |||
111 | struct hme_tx_logent *tlp; | 111 | struct hme_tx_logent *tlp; |
112 | unsigned long flags; | 112 | unsigned long flags; |
113 | 113 | ||
114 | save_and_cli(flags); | 114 | local_irq_save(flags); |
115 | tlp = &tx_log[txlog_cur_entry]; | 115 | tlp = &tx_log[txlog_cur_entry]; |
116 | tlp->tstamp = (unsigned int)jiffies; | 116 | tlp->tstamp = (unsigned int)jiffies; |
117 | tlp->tx_new = hp->tx_new; | 117 | tlp->tx_new = hp->tx_new; |
@@ -119,7 +119,7 @@ static __inline__ void tx_add_log(struct happy_meal *hp, unsigned int a, unsigne | |||
119 | tlp->action = a; | 119 | tlp->action = a; |
120 | tlp->status = s; | 120 | tlp->status = s; |
121 | txlog_cur_entry = (txlog_cur_entry + 1) & (TX_LOG_LEN - 1); | 121 | txlog_cur_entry = (txlog_cur_entry + 1) & (TX_LOG_LEN - 1); |
122 | restore_flags(flags); | 122 | local_irq_restore(flags); |
123 | } | 123 | } |
124 | static __inline__ void tx_dump_log(void) | 124 | static __inline__ void tx_dump_log(void) |
125 | { | 125 | { |
diff --git a/drivers/net/tc35815.c b/drivers/net/tc35815.c index 10e4e85da3fc..b07b8cbadeaf 100644 --- a/drivers/net/tc35815.c +++ b/drivers/net/tc35815.c | |||
@@ -1394,6 +1394,7 @@ tc35815_open(struct net_device *dev) | |||
1394 | tc35815_chip_init(dev); | 1394 | tc35815_chip_init(dev); |
1395 | spin_unlock_irq(&lp->lock); | 1395 | spin_unlock_irq(&lp->lock); |
1396 | 1396 | ||
1397 | netif_carrier_off(dev); | ||
1397 | /* schedule a link state check */ | 1398 | /* schedule a link state check */ |
1398 | phy_start(lp->phy_dev); | 1399 | phy_start(lp->phy_dev); |
1399 | 1400 | ||
@@ -1735,7 +1736,6 @@ tc35815_rx(struct net_device *dev) | |||
1735 | skb = lp->rx_skbs[cur_bd].skb; | 1736 | skb = lp->rx_skbs[cur_bd].skb; |
1736 | prefetch(skb->data); | 1737 | prefetch(skb->data); |
1737 | lp->rx_skbs[cur_bd].skb = NULL; | 1738 | lp->rx_skbs[cur_bd].skb = NULL; |
1738 | lp->fbl_count--; | ||
1739 | pci_unmap_single(lp->pci_dev, | 1739 | pci_unmap_single(lp->pci_dev, |
1740 | lp->rx_skbs[cur_bd].skb_dma, | 1740 | lp->rx_skbs[cur_bd].skb_dma, |
1741 | RX_BUF_SIZE, PCI_DMA_FROMDEVICE); | 1741 | RX_BUF_SIZE, PCI_DMA_FROMDEVICE); |
@@ -1791,6 +1791,7 @@ tc35815_rx(struct net_device *dev) | |||
1791 | #ifdef TC35815_USE_PACKEDBUFFER | 1791 | #ifdef TC35815_USE_PACKEDBUFFER |
1792 | while (lp->fbl_curid != id) | 1792 | while (lp->fbl_curid != id) |
1793 | #else | 1793 | #else |
1794 | lp->fbl_count--; | ||
1794 | while (lp->fbl_count < RX_BUF_NUM) | 1795 | while (lp->fbl_count < RX_BUF_NUM) |
1795 | #endif | 1796 | #endif |
1796 | { | 1797 | { |
@@ -2453,6 +2454,7 @@ static int tc35815_resume(struct pci_dev *pdev) | |||
2453 | return 0; | 2454 | return 0; |
2454 | pci_set_power_state(pdev, PCI_D0); | 2455 | pci_set_power_state(pdev, PCI_D0); |
2455 | tc35815_restart(dev); | 2456 | tc35815_restart(dev); |
2457 | netif_carrier_off(dev); | ||
2456 | if (lp->phy_dev) | 2458 | if (lp->phy_dev) |
2457 | phy_start(lp->phy_dev); | 2459 | phy_start(lp->phy_dev); |
2458 | netif_device_attach(dev); | 2460 | netif_device_attach(dev); |
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index b66c75e3b8a1..cc4bde852542 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c | |||
@@ -64,8 +64,8 @@ | |||
64 | 64 | ||
65 | #define DRV_MODULE_NAME "tg3" | 65 | #define DRV_MODULE_NAME "tg3" |
66 | #define PFX DRV_MODULE_NAME ": " | 66 | #define PFX DRV_MODULE_NAME ": " |
67 | #define DRV_MODULE_VERSION "3.91" | 67 | #define DRV_MODULE_VERSION "3.92.1" |
68 | #define DRV_MODULE_RELDATE "April 18, 2008" | 68 | #define DRV_MODULE_RELDATE "June 9, 2008" |
69 | 69 | ||
70 | #define TG3_DEF_MAC_MODE 0 | 70 | #define TG3_DEF_MAC_MODE 0 |
71 | #define TG3_DEF_RX_MODE 0 | 71 | #define TG3_DEF_RX_MODE 0 |
@@ -1295,6 +1295,21 @@ static void tg3_frob_aux_power(struct tg3 *tp) | |||
1295 | GRC_LCLCTRL_GPIO_OUTPUT0 | | 1295 | GRC_LCLCTRL_GPIO_OUTPUT0 | |
1296 | GRC_LCLCTRL_GPIO_OUTPUT1), | 1296 | GRC_LCLCTRL_GPIO_OUTPUT1), |
1297 | 100); | 1297 | 100); |
1298 | } else if (tp->pdev->device == PCI_DEVICE_ID_TIGON3_5761) { | ||
1299 | /* The 5761 non-e device swaps GPIO 0 and GPIO 2. */ | ||
1300 | u32 grc_local_ctrl = GRC_LCLCTRL_GPIO_OE0 | | ||
1301 | GRC_LCLCTRL_GPIO_OE1 | | ||
1302 | GRC_LCLCTRL_GPIO_OE2 | | ||
1303 | GRC_LCLCTRL_GPIO_OUTPUT0 | | ||
1304 | GRC_LCLCTRL_GPIO_OUTPUT1 | | ||
1305 | tp->grc_local_ctrl; | ||
1306 | tw32_wait_f(GRC_LOCAL_CTRL, grc_local_ctrl, 100); | ||
1307 | |||
1308 | grc_local_ctrl |= GRC_LCLCTRL_GPIO_OUTPUT2; | ||
1309 | tw32_wait_f(GRC_LOCAL_CTRL, grc_local_ctrl, 100); | ||
1310 | |||
1311 | grc_local_ctrl &= ~GRC_LCLCTRL_GPIO_OUTPUT0; | ||
1312 | tw32_wait_f(GRC_LOCAL_CTRL, grc_local_ctrl, 100); | ||
1298 | } else { | 1313 | } else { |
1299 | u32 no_gpio2; | 1314 | u32 no_gpio2; |
1300 | u32 grc_local_ctrl = 0; | 1315 | u32 grc_local_ctrl = 0; |
@@ -1656,12 +1671,76 @@ static int tg3_set_power_state(struct tg3 *tp, pci_power_t state) | |||
1656 | return 0; | 1671 | return 0; |
1657 | } | 1672 | } |
1658 | 1673 | ||
1674 | /* tp->lock is held. */ | ||
1675 | static void tg3_wait_for_event_ack(struct tg3 *tp) | ||
1676 | { | ||
1677 | int i; | ||
1678 | |||
1679 | /* Wait for up to 2.5 milliseconds */ | ||
1680 | for (i = 0; i < 250000; i++) { | ||
1681 | if (!(tr32(GRC_RX_CPU_EVENT) & GRC_RX_CPU_DRIVER_EVENT)) | ||
1682 | break; | ||
1683 | udelay(10); | ||
1684 | } | ||
1685 | } | ||
1686 | |||
1687 | /* tp->lock is held. */ | ||
1688 | static void tg3_ump_link_report(struct tg3 *tp) | ||
1689 | { | ||
1690 | u32 reg; | ||
1691 | u32 val; | ||
1692 | |||
1693 | if (!(tp->tg3_flags2 & TG3_FLG2_5780_CLASS) || | ||
1694 | !(tp->tg3_flags & TG3_FLAG_ENABLE_ASF)) | ||
1695 | return; | ||
1696 | |||
1697 | tg3_wait_for_event_ack(tp); | ||
1698 | |||
1699 | tg3_write_mem(tp, NIC_SRAM_FW_CMD_MBOX, FWCMD_NICDRV_LINK_UPDATE); | ||
1700 | |||
1701 | tg3_write_mem(tp, NIC_SRAM_FW_CMD_LEN_MBOX, 14); | ||
1702 | |||
1703 | val = 0; | ||
1704 | if (!tg3_readphy(tp, MII_BMCR, ®)) | ||
1705 | val = reg << 16; | ||
1706 | if (!tg3_readphy(tp, MII_BMSR, ®)) | ||
1707 | val |= (reg & 0xffff); | ||
1708 | tg3_write_mem(tp, NIC_SRAM_FW_CMD_DATA_MBOX, val); | ||
1709 | |||
1710 | val = 0; | ||
1711 | if (!tg3_readphy(tp, MII_ADVERTISE, ®)) | ||
1712 | val = reg << 16; | ||
1713 | if (!tg3_readphy(tp, MII_LPA, ®)) | ||
1714 | val |= (reg & 0xffff); | ||
1715 | tg3_write_mem(tp, NIC_SRAM_FW_CMD_DATA_MBOX + 4, val); | ||
1716 | |||
1717 | val = 0; | ||
1718 | if (!(tp->tg3_flags2 & TG3_FLG2_MII_SERDES)) { | ||
1719 | if (!tg3_readphy(tp, MII_CTRL1000, ®)) | ||
1720 | val = reg << 16; | ||
1721 | if (!tg3_readphy(tp, MII_STAT1000, ®)) | ||
1722 | val |= (reg & 0xffff); | ||
1723 | } | ||
1724 | tg3_write_mem(tp, NIC_SRAM_FW_CMD_DATA_MBOX + 8, val); | ||
1725 | |||
1726 | if (!tg3_readphy(tp, MII_PHYADDR, ®)) | ||
1727 | val = reg << 16; | ||
1728 | else | ||
1729 | val = 0; | ||
1730 | tg3_write_mem(tp, NIC_SRAM_FW_CMD_DATA_MBOX + 12, val); | ||
1731 | |||
1732 | val = tr32(GRC_RX_CPU_EVENT); | ||
1733 | val |= GRC_RX_CPU_DRIVER_EVENT; | ||
1734 | tw32_f(GRC_RX_CPU_EVENT, val); | ||
1735 | } | ||
1736 | |||
1659 | static void tg3_link_report(struct tg3 *tp) | 1737 | static void tg3_link_report(struct tg3 *tp) |
1660 | { | 1738 | { |
1661 | if (!netif_carrier_ok(tp->dev)) { | 1739 | if (!netif_carrier_ok(tp->dev)) { |
1662 | if (netif_msg_link(tp)) | 1740 | if (netif_msg_link(tp)) |
1663 | printk(KERN_INFO PFX "%s: Link is down.\n", | 1741 | printk(KERN_INFO PFX "%s: Link is down.\n", |
1664 | tp->dev->name); | 1742 | tp->dev->name); |
1743 | tg3_ump_link_report(tp); | ||
1665 | } else if (netif_msg_link(tp)) { | 1744 | } else if (netif_msg_link(tp)) { |
1666 | printk(KERN_INFO PFX "%s: Link is up at %d Mbps, %s duplex.\n", | 1745 | printk(KERN_INFO PFX "%s: Link is up at %d Mbps, %s duplex.\n", |
1667 | tp->dev->name, | 1746 | tp->dev->name, |
@@ -1679,6 +1758,7 @@ static void tg3_link_report(struct tg3 *tp) | |||
1679 | "on" : "off", | 1758 | "on" : "off", |
1680 | (tp->link_config.active_flowctrl & TG3_FLOW_CTRL_RX) ? | 1759 | (tp->link_config.active_flowctrl & TG3_FLOW_CTRL_RX) ? |
1681 | "on" : "off"); | 1760 | "on" : "off"); |
1761 | tg3_ump_link_report(tp); | ||
1682 | } | 1762 | } |
1683 | } | 1763 | } |
1684 | 1764 | ||
@@ -2097,9 +2177,11 @@ static int tg3_setup_copper_phy(struct tg3 *tp, int force_reset) | |||
2097 | MAC_STATUS_LNKSTATE_CHANGED)); | 2177 | MAC_STATUS_LNKSTATE_CHANGED)); |
2098 | udelay(40); | 2178 | udelay(40); |
2099 | 2179 | ||
2100 | tp->mi_mode = MAC_MI_MODE_BASE; | 2180 | if ((tp->mi_mode & MAC_MI_MODE_AUTO_POLL) != 0) { |
2101 | tw32_f(MAC_MI_MODE, tp->mi_mode); | 2181 | tw32_f(MAC_MI_MODE, |
2102 | udelay(80); | 2182 | (tp->mi_mode & ~MAC_MI_MODE_AUTO_POLL)); |
2183 | udelay(80); | ||
2184 | } | ||
2103 | 2185 | ||
2104 | tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x02); | 2186 | tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x02); |
2105 | 2187 | ||
@@ -3101,8 +3183,7 @@ static int tg3_setup_fiber_mii_phy(struct tg3 *tp, int force_reset) | |||
3101 | err |= tg3_readphy(tp, MII_BMCR, &bmcr); | 3183 | err |= tg3_readphy(tp, MII_BMCR, &bmcr); |
3102 | 3184 | ||
3103 | if ((tp->link_config.autoneg == AUTONEG_ENABLE) && !force_reset && | 3185 | if ((tp->link_config.autoneg == AUTONEG_ENABLE) && !force_reset && |
3104 | (tp->tg3_flags2 & TG3_FLG2_PARALLEL_DETECT) && | 3186 | (tp->tg3_flags2 & TG3_FLG2_PARALLEL_DETECT)) { |
3105 | tp->link_config.flowctrl == tp->link_config.active_flowctrl) { | ||
3106 | /* do nothing, just check for link up at the end */ | 3187 | /* do nothing, just check for link up at the end */ |
3107 | } else if (tp->link_config.autoneg == AUTONEG_ENABLE) { | 3188 | } else if (tp->link_config.autoneg == AUTONEG_ENABLE) { |
3108 | u32 adv, new_adv; | 3189 | u32 adv, new_adv; |
@@ -5498,19 +5579,17 @@ static void tg3_stop_fw(struct tg3 *tp) | |||
5498 | if ((tp->tg3_flags & TG3_FLAG_ENABLE_ASF) && | 5579 | if ((tp->tg3_flags & TG3_FLAG_ENABLE_ASF) && |
5499 | !(tp->tg3_flags3 & TG3_FLG3_ENABLE_APE)) { | 5580 | !(tp->tg3_flags3 & TG3_FLG3_ENABLE_APE)) { |
5500 | u32 val; | 5581 | u32 val; |
5501 | int i; | 5582 | |
5583 | /* Wait for RX cpu to ACK the previous event. */ | ||
5584 | tg3_wait_for_event_ack(tp); | ||
5502 | 5585 | ||
5503 | tg3_write_mem(tp, NIC_SRAM_FW_CMD_MBOX, FWCMD_NICDRV_PAUSE_FW); | 5586 | tg3_write_mem(tp, NIC_SRAM_FW_CMD_MBOX, FWCMD_NICDRV_PAUSE_FW); |
5504 | val = tr32(GRC_RX_CPU_EVENT); | 5587 | val = tr32(GRC_RX_CPU_EVENT); |
5505 | val |= (1 << 14); | 5588 | val |= GRC_RX_CPU_DRIVER_EVENT; |
5506 | tw32(GRC_RX_CPU_EVENT, val); | 5589 | tw32(GRC_RX_CPU_EVENT, val); |
5507 | 5590 | ||
5508 | /* Wait for RX cpu to ACK the event. */ | 5591 | /* Wait for RX cpu to ACK this event. */ |
5509 | for (i = 0; i < 100; i++) { | 5592 | tg3_wait_for_event_ack(tp); |
5510 | if (!(tr32(GRC_RX_CPU_EVENT) & (1 << 14))) | ||
5511 | break; | ||
5512 | udelay(1); | ||
5513 | } | ||
5514 | } | 5593 | } |
5515 | } | 5594 | } |
5516 | 5595 | ||
@@ -7102,7 +7181,7 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy) | |||
7102 | tp->link_config.autoneg = tp->link_config.orig_autoneg; | 7181 | tp->link_config.autoneg = tp->link_config.orig_autoneg; |
7103 | } | 7182 | } |
7104 | 7183 | ||
7105 | tp->mi_mode = MAC_MI_MODE_BASE; | 7184 | tp->mi_mode &= ~MAC_MI_MODE_AUTO_POLL; |
7106 | tw32_f(MAC_MI_MODE, tp->mi_mode); | 7185 | tw32_f(MAC_MI_MODE, tp->mi_mode); |
7107 | udelay(80); | 7186 | udelay(80); |
7108 | 7187 | ||
@@ -7400,14 +7479,16 @@ static void tg3_timer(unsigned long __opaque) | |||
7400 | if (tp->tg3_flags & TG3_FLAG_ENABLE_ASF) { | 7479 | if (tp->tg3_flags & TG3_FLAG_ENABLE_ASF) { |
7401 | u32 val; | 7480 | u32 val; |
7402 | 7481 | ||
7482 | tg3_wait_for_event_ack(tp); | ||
7483 | |||
7403 | tg3_write_mem(tp, NIC_SRAM_FW_CMD_MBOX, | 7484 | tg3_write_mem(tp, NIC_SRAM_FW_CMD_MBOX, |
7404 | FWCMD_NICDRV_ALIVE3); | 7485 | FWCMD_NICDRV_ALIVE3); |
7405 | tg3_write_mem(tp, NIC_SRAM_FW_CMD_LEN_MBOX, 4); | 7486 | tg3_write_mem(tp, NIC_SRAM_FW_CMD_LEN_MBOX, 4); |
7406 | /* 5 seconds timeout */ | 7487 | /* 5 seconds timeout */ |
7407 | tg3_write_mem(tp, NIC_SRAM_FW_CMD_DATA_MBOX, 5); | 7488 | tg3_write_mem(tp, NIC_SRAM_FW_CMD_DATA_MBOX, 5); |
7408 | val = tr32(GRC_RX_CPU_EVENT); | 7489 | val = tr32(GRC_RX_CPU_EVENT); |
7409 | val |= (1 << 14); | 7490 | val |= GRC_RX_CPU_DRIVER_EVENT; |
7410 | tw32(GRC_RX_CPU_EVENT, val); | 7491 | tw32_f(GRC_RX_CPU_EVENT, val); |
7411 | } | 7492 | } |
7412 | tp->asf_counter = tp->asf_multiplier; | 7493 | tp->asf_counter = tp->asf_multiplier; |
7413 | } | 7494 | } |
@@ -8532,7 +8613,7 @@ static int tg3_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) | |||
8532 | (cmd->speed == SPEED_1000)) | 8613 | (cmd->speed == SPEED_1000)) |
8533 | return -EINVAL; | 8614 | return -EINVAL; |
8534 | else if ((cmd->speed == SPEED_1000) && | 8615 | else if ((cmd->speed == SPEED_1000) && |
8535 | (tp->tg3_flags2 & TG3_FLAG_10_100_ONLY)) | 8616 | (tp->tg3_flags & TG3_FLAG_10_100_ONLY)) |
8536 | return -EINVAL; | 8617 | return -EINVAL; |
8537 | 8618 | ||
8538 | tg3_full_lock(tp, 0); | 8619 | tg3_full_lock(tp, 0); |
@@ -9568,14 +9649,9 @@ static int tg3_test_loopback(struct tg3 *tp) | |||
9568 | 9649 | ||
9569 | /* Turn off link-based power management. */ | 9650 | /* Turn off link-based power management. */ |
9570 | cpmuctrl = tr32(TG3_CPMU_CTRL); | 9651 | cpmuctrl = tr32(TG3_CPMU_CTRL); |
9571 | if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784 || | 9652 | tw32(TG3_CPMU_CTRL, |
9572 | GET_CHIP_REV(tp->pci_chip_rev_id) == CHIPREV_5761_AX) | 9653 | cpmuctrl & ~(CPMU_CTRL_LINK_SPEED_MODE | |
9573 | tw32(TG3_CPMU_CTRL, | 9654 | CPMU_CTRL_LINK_AWARE_MODE)); |
9574 | cpmuctrl & ~(CPMU_CTRL_LINK_SPEED_MODE | | ||
9575 | CPMU_CTRL_LINK_AWARE_MODE)); | ||
9576 | else | ||
9577 | tw32(TG3_CPMU_CTRL, | ||
9578 | cpmuctrl & ~CPMU_CTRL_LINK_AWARE_MODE); | ||
9579 | } | 9655 | } |
9580 | 9656 | ||
9581 | if (tg3_run_loopback(tp, TG3_MAC_LOOPBACK)) | 9657 | if (tg3_run_loopback(tp, TG3_MAC_LOOPBACK)) |
@@ -9892,7 +9968,7 @@ static void __devinit tg3_get_nvram_size(struct tg3 *tp) | |||
9892 | return; | 9968 | return; |
9893 | } | 9969 | } |
9894 | } | 9970 | } |
9895 | tp->nvram_size = 0x80000; | 9971 | tp->nvram_size = TG3_NVRAM_SIZE_512KB; |
9896 | } | 9972 | } |
9897 | 9973 | ||
9898 | static void __devinit tg3_get_nvram_info(struct tg3 *tp) | 9974 | static void __devinit tg3_get_nvram_info(struct tg3 *tp) |
@@ -10033,11 +10109,14 @@ static void __devinit tg3_get_5755_nvram_info(struct tg3 *tp) | |||
10033 | tp->nvram_pagesize = 264; | 10109 | tp->nvram_pagesize = 264; |
10034 | if (nvcfg1 == FLASH_5755VENDOR_ATMEL_FLASH_1 || | 10110 | if (nvcfg1 == FLASH_5755VENDOR_ATMEL_FLASH_1 || |
10035 | nvcfg1 == FLASH_5755VENDOR_ATMEL_FLASH_5) | 10111 | nvcfg1 == FLASH_5755VENDOR_ATMEL_FLASH_5) |
10036 | tp->nvram_size = (protect ? 0x3e200 : 0x80000); | 10112 | tp->nvram_size = (protect ? 0x3e200 : |
10113 | TG3_NVRAM_SIZE_512KB); | ||
10037 | else if (nvcfg1 == FLASH_5755VENDOR_ATMEL_FLASH_2) | 10114 | else if (nvcfg1 == FLASH_5755VENDOR_ATMEL_FLASH_2) |
10038 | tp->nvram_size = (protect ? 0x1f200 : 0x40000); | 10115 | tp->nvram_size = (protect ? 0x1f200 : |
10116 | TG3_NVRAM_SIZE_256KB); | ||
10039 | else | 10117 | else |
10040 | tp->nvram_size = (protect ? 0x1f200 : 0x20000); | 10118 | tp->nvram_size = (protect ? 0x1f200 : |
10119 | TG3_NVRAM_SIZE_128KB); | ||
10041 | break; | 10120 | break; |
10042 | case FLASH_5752VENDOR_ST_M45PE10: | 10121 | case FLASH_5752VENDOR_ST_M45PE10: |
10043 | case FLASH_5752VENDOR_ST_M45PE20: | 10122 | case FLASH_5752VENDOR_ST_M45PE20: |
@@ -10047,11 +10126,17 @@ static void __devinit tg3_get_5755_nvram_info(struct tg3 *tp) | |||
10047 | tp->tg3_flags2 |= TG3_FLG2_FLASH; | 10126 | tp->tg3_flags2 |= TG3_FLG2_FLASH; |
10048 | tp->nvram_pagesize = 256; | 10127 | tp->nvram_pagesize = 256; |
10049 | if (nvcfg1 == FLASH_5752VENDOR_ST_M45PE10) | 10128 | if (nvcfg1 == FLASH_5752VENDOR_ST_M45PE10) |
10050 | tp->nvram_size = (protect ? 0x10000 : 0x20000); | 10129 | tp->nvram_size = (protect ? |
10130 | TG3_NVRAM_SIZE_64KB : | ||
10131 | TG3_NVRAM_SIZE_128KB); | ||
10051 | else if (nvcfg1 == FLASH_5752VENDOR_ST_M45PE20) | 10132 | else if (nvcfg1 == FLASH_5752VENDOR_ST_M45PE20) |
10052 | tp->nvram_size = (protect ? 0x10000 : 0x40000); | 10133 | tp->nvram_size = (protect ? |
10134 | TG3_NVRAM_SIZE_64KB : | ||
10135 | TG3_NVRAM_SIZE_256KB); | ||
10053 | else | 10136 | else |
10054 | tp->nvram_size = (protect ? 0x20000 : 0x80000); | 10137 | tp->nvram_size = (protect ? |
10138 | TG3_NVRAM_SIZE_128KB : | ||
10139 | TG3_NVRAM_SIZE_512KB); | ||
10055 | break; | 10140 | break; |
10056 | } | 10141 | } |
10057 | } | 10142 | } |
@@ -10145,25 +10230,25 @@ static void __devinit tg3_get_5761_nvram_info(struct tg3 *tp) | |||
10145 | case FLASH_5761VENDOR_ATMEL_MDB161D: | 10230 | case FLASH_5761VENDOR_ATMEL_MDB161D: |
10146 | case FLASH_5761VENDOR_ST_A_M45PE16: | 10231 | case FLASH_5761VENDOR_ST_A_M45PE16: |
10147 | case FLASH_5761VENDOR_ST_M_M45PE16: | 10232 | case FLASH_5761VENDOR_ST_M_M45PE16: |
10148 | tp->nvram_size = 0x100000; | 10233 | tp->nvram_size = TG3_NVRAM_SIZE_2MB; |
10149 | break; | 10234 | break; |
10150 | case FLASH_5761VENDOR_ATMEL_ADB081D: | 10235 | case FLASH_5761VENDOR_ATMEL_ADB081D: |
10151 | case FLASH_5761VENDOR_ATMEL_MDB081D: | 10236 | case FLASH_5761VENDOR_ATMEL_MDB081D: |
10152 | case FLASH_5761VENDOR_ST_A_M45PE80: | 10237 | case FLASH_5761VENDOR_ST_A_M45PE80: |
10153 | case FLASH_5761VENDOR_ST_M_M45PE80: | 10238 | case FLASH_5761VENDOR_ST_M_M45PE80: |
10154 | tp->nvram_size = 0x80000; | 10239 | tp->nvram_size = TG3_NVRAM_SIZE_1MB; |
10155 | break; | 10240 | break; |
10156 | case FLASH_5761VENDOR_ATMEL_ADB041D: | 10241 | case FLASH_5761VENDOR_ATMEL_ADB041D: |
10157 | case FLASH_5761VENDOR_ATMEL_MDB041D: | 10242 | case FLASH_5761VENDOR_ATMEL_MDB041D: |
10158 | case FLASH_5761VENDOR_ST_A_M45PE40: | 10243 | case FLASH_5761VENDOR_ST_A_M45PE40: |
10159 | case FLASH_5761VENDOR_ST_M_M45PE40: | 10244 | case FLASH_5761VENDOR_ST_M_M45PE40: |
10160 | tp->nvram_size = 0x40000; | 10245 | tp->nvram_size = TG3_NVRAM_SIZE_512KB; |
10161 | break; | 10246 | break; |
10162 | case FLASH_5761VENDOR_ATMEL_ADB021D: | 10247 | case FLASH_5761VENDOR_ATMEL_ADB021D: |
10163 | case FLASH_5761VENDOR_ATMEL_MDB021D: | 10248 | case FLASH_5761VENDOR_ATMEL_MDB021D: |
10164 | case FLASH_5761VENDOR_ST_A_M45PE20: | 10249 | case FLASH_5761VENDOR_ST_A_M45PE20: |
10165 | case FLASH_5761VENDOR_ST_M_M45PE20: | 10250 | case FLASH_5761VENDOR_ST_M_M45PE20: |
10166 | tp->nvram_size = 0x20000; | 10251 | tp->nvram_size = TG3_NVRAM_SIZE_256KB; |
10167 | break; | 10252 | break; |
10168 | } | 10253 | } |
10169 | } | 10254 | } |
@@ -11697,6 +11782,15 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) | |||
11697 | if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755) | 11782 | if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755) |
11698 | tp->grc_local_ctrl |= GRC_LCLCTRL_GPIO_UART_SEL; | 11783 | tp->grc_local_ctrl |= GRC_LCLCTRL_GPIO_UART_SEL; |
11699 | 11784 | ||
11785 | if (tp->pdev->device == PCI_DEVICE_ID_TIGON3_5761) { | ||
11786 | /* Turn off the debug UART. */ | ||
11787 | tp->grc_local_ctrl |= GRC_LCLCTRL_GPIO_UART_SEL; | ||
11788 | if (tp->tg3_flags2 & TG3_FLG2_IS_NIC) | ||
11789 | /* Keep VMain power. */ | ||
11790 | tp->grc_local_ctrl |= GRC_LCLCTRL_GPIO_OE0 | | ||
11791 | GRC_LCLCTRL_GPIO_OUTPUT0; | ||
11792 | } | ||
11793 | |||
11700 | /* Force the chip into D0. */ | 11794 | /* Force the chip into D0. */ |
11701 | err = tg3_set_power_state(tp, PCI_D0); | 11795 | err = tg3_set_power_state(tp, PCI_D0); |
11702 | if (err) { | 11796 | if (err) { |
@@ -11764,6 +11858,12 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) | |||
11764 | tp->phy_otp = TG3_OTP_DEFAULT; | 11858 | tp->phy_otp = TG3_OTP_DEFAULT; |
11765 | } | 11859 | } |
11766 | 11860 | ||
11861 | if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784 || | ||
11862 | GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761) | ||
11863 | tp->mi_mode = MAC_MI_MODE_500KHZ_CONST; | ||
11864 | else | ||
11865 | tp->mi_mode = MAC_MI_MODE_BASE; | ||
11866 | |||
11767 | tp->coalesce_mode = 0; | 11867 | tp->coalesce_mode = 0; |
11768 | if (GET_CHIP_REV(tp->pci_chip_rev_id) != CHIPREV_5700_AX && | 11868 | if (GET_CHIP_REV(tp->pci_chip_rev_id) != CHIPREV_5700_AX && |
11769 | GET_CHIP_REV(tp->pci_chip_rev_id) != CHIPREV_5700_BX) | 11869 | GET_CHIP_REV(tp->pci_chip_rev_id) != CHIPREV_5700_BX) |
@@ -12692,7 +12792,7 @@ static int __devinit tg3_init_one(struct pci_dev *pdev, | |||
12692 | tp->mac_mode = TG3_DEF_MAC_MODE; | 12792 | tp->mac_mode = TG3_DEF_MAC_MODE; |
12693 | tp->rx_mode = TG3_DEF_RX_MODE; | 12793 | tp->rx_mode = TG3_DEF_RX_MODE; |
12694 | tp->tx_mode = TG3_DEF_TX_MODE; | 12794 | tp->tx_mode = TG3_DEF_TX_MODE; |
12695 | tp->mi_mode = MAC_MI_MODE_BASE; | 12795 | |
12696 | if (tg3_debug > 0) | 12796 | if (tg3_debug > 0) |
12697 | tp->msg_enable = tg3_debug; | 12797 | tp->msg_enable = tg3_debug; |
12698 | else | 12798 | else |
diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h index c688c3ac5035..0404f93baa29 100644 --- a/drivers/net/tg3.h +++ b/drivers/net/tg3.h | |||
@@ -415,7 +415,7 @@ | |||
415 | #define MAC_MI_MODE_CLK_10MHZ 0x00000001 | 415 | #define MAC_MI_MODE_CLK_10MHZ 0x00000001 |
416 | #define MAC_MI_MODE_SHORT_PREAMBLE 0x00000002 | 416 | #define MAC_MI_MODE_SHORT_PREAMBLE 0x00000002 |
417 | #define MAC_MI_MODE_AUTO_POLL 0x00000010 | 417 | #define MAC_MI_MODE_AUTO_POLL 0x00000010 |
418 | #define MAC_MI_MODE_CORE_CLK_62MHZ 0x00008000 | 418 | #define MAC_MI_MODE_500KHZ_CONST 0x00008000 |
419 | #define MAC_MI_MODE_BASE 0x000c0000 /* XXX magic values XXX */ | 419 | #define MAC_MI_MODE_BASE 0x000c0000 /* XXX magic values XXX */ |
420 | #define MAC_AUTO_POLL_STATUS 0x00000458 | 420 | #define MAC_AUTO_POLL_STATUS 0x00000458 |
421 | #define MAC_AUTO_POLL_ERROR 0x00000001 | 421 | #define MAC_AUTO_POLL_ERROR 0x00000001 |
@@ -1429,6 +1429,7 @@ | |||
1429 | #define GRC_LCLCTRL_AUTO_SEEPROM 0x01000000 | 1429 | #define GRC_LCLCTRL_AUTO_SEEPROM 0x01000000 |
1430 | #define GRC_TIMER 0x0000680c | 1430 | #define GRC_TIMER 0x0000680c |
1431 | #define GRC_RX_CPU_EVENT 0x00006810 | 1431 | #define GRC_RX_CPU_EVENT 0x00006810 |
1432 | #define GRC_RX_CPU_DRIVER_EVENT 0x00004000 | ||
1432 | #define GRC_RX_TIMER_REF 0x00006814 | 1433 | #define GRC_RX_TIMER_REF 0x00006814 |
1433 | #define GRC_RX_CPU_SEM 0x00006818 | 1434 | #define GRC_RX_CPU_SEM 0x00006818 |
1434 | #define GRC_REMOTE_RX_CPU_ATTN 0x0000681c | 1435 | #define GRC_REMOTE_RX_CPU_ATTN 0x0000681c |
@@ -1676,6 +1677,7 @@ | |||
1676 | #define FWCMD_NICDRV_IPV6ADDR_CHG 0x00000004 | 1677 | #define FWCMD_NICDRV_IPV6ADDR_CHG 0x00000004 |
1677 | #define FWCMD_NICDRV_FIX_DMAR 0x00000005 | 1678 | #define FWCMD_NICDRV_FIX_DMAR 0x00000005 |
1678 | #define FWCMD_NICDRV_FIX_DMAW 0x00000006 | 1679 | #define FWCMD_NICDRV_FIX_DMAW 0x00000006 |
1680 | #define FWCMD_NICDRV_LINK_UPDATE 0x0000000c | ||
1679 | #define FWCMD_NICDRV_ALIVE2 0x0000000d | 1681 | #define FWCMD_NICDRV_ALIVE2 0x0000000d |
1680 | #define FWCMD_NICDRV_ALIVE3 0x0000000e | 1682 | #define FWCMD_NICDRV_ALIVE3 0x0000000e |
1681 | #define NIC_SRAM_FW_CMD_LEN_MBOX 0x00000b7c | 1683 | #define NIC_SRAM_FW_CMD_LEN_MBOX 0x00000b7c |
@@ -2576,6 +2578,13 @@ struct tg3 { | |||
2576 | 2578 | ||
2577 | int nvram_lock_cnt; | 2579 | int nvram_lock_cnt; |
2578 | u32 nvram_size; | 2580 | u32 nvram_size; |
2581 | #define TG3_NVRAM_SIZE_64KB 0x00010000 | ||
2582 | #define TG3_NVRAM_SIZE_128KB 0x00020000 | ||
2583 | #define TG3_NVRAM_SIZE_256KB 0x00040000 | ||
2584 | #define TG3_NVRAM_SIZE_512KB 0x00080000 | ||
2585 | #define TG3_NVRAM_SIZE_1MB 0x00100000 | ||
2586 | #define TG3_NVRAM_SIZE_2MB 0x00200000 | ||
2587 | |||
2579 | u32 nvram_pagesize; | 2588 | u32 nvram_pagesize; |
2580 | u32 nvram_jedecnum; | 2589 | u32 nvram_jedecnum; |
2581 | 2590 | ||
@@ -2584,10 +2593,10 @@ struct tg3 { | |||
2584 | #define JEDEC_SAIFUN 0x4f | 2593 | #define JEDEC_SAIFUN 0x4f |
2585 | #define JEDEC_SST 0xbf | 2594 | #define JEDEC_SST 0xbf |
2586 | 2595 | ||
2587 | #define ATMEL_AT24C64_CHIP_SIZE (64 * 1024) | 2596 | #define ATMEL_AT24C64_CHIP_SIZE TG3_NVRAM_SIZE_64KB |
2588 | #define ATMEL_AT24C64_PAGE_SIZE (32) | 2597 | #define ATMEL_AT24C64_PAGE_SIZE (32) |
2589 | 2598 | ||
2590 | #define ATMEL_AT24C512_CHIP_SIZE (512 * 1024) | 2599 | #define ATMEL_AT24C512_CHIP_SIZE TG3_NVRAM_SIZE_512KB |
2591 | #define ATMEL_AT24C512_PAGE_SIZE (128) | 2600 | #define ATMEL_AT24C512_PAGE_SIZE (128) |
2592 | 2601 | ||
2593 | #define ATMEL_AT45DB0X1B_PAGE_POS 9 | 2602 | #define ATMEL_AT45DB0X1B_PAGE_POS 9 |
diff --git a/drivers/net/tokenring/3c359.h b/drivers/net/tokenring/3c359.h index b880cba0f6fd..74cf8e1a181b 100644 --- a/drivers/net/tokenring/3c359.h +++ b/drivers/net/tokenring/3c359.h | |||
@@ -264,7 +264,7 @@ struct xl_private { | |||
264 | u16 asb; | 264 | u16 asb; |
265 | 265 | ||
266 | u8 __iomem *xl_mmio; | 266 | u8 __iomem *xl_mmio; |
267 | char *xl_card_name; | 267 | const char *xl_card_name; |
268 | struct pci_dev *pdev ; | 268 | struct pci_dev *pdev ; |
269 | 269 | ||
270 | spinlock_t xl_lock ; | 270 | spinlock_t xl_lock ; |
diff --git a/drivers/net/tokenring/olympic.h b/drivers/net/tokenring/olympic.h index c91956310fb2..10fbba08978f 100644 --- a/drivers/net/tokenring/olympic.h +++ b/drivers/net/tokenring/olympic.h | |||
@@ -254,7 +254,7 @@ struct olympic_private { | |||
254 | u8 __iomem *olympic_mmio; | 254 | u8 __iomem *olympic_mmio; |
255 | u8 __iomem *olympic_lap; | 255 | u8 __iomem *olympic_lap; |
256 | struct pci_dev *pdev ; | 256 | struct pci_dev *pdev ; |
257 | char *olympic_card_name ; | 257 | const char *olympic_card_name; |
258 | 258 | ||
259 | spinlock_t olympic_lock ; | 259 | spinlock_t olympic_lock ; |
260 | 260 | ||
diff --git a/drivers/net/tulip/tulip_core.c b/drivers/net/tulip/tulip_core.c index f9d13fa05d64..af8d2c436efd 100644 --- a/drivers/net/tulip/tulip_core.c +++ b/drivers/net/tulip/tulip_core.c | |||
@@ -731,7 +731,7 @@ static void tulip_down (struct net_device *dev) | |||
731 | void __iomem *ioaddr = tp->base_addr; | 731 | void __iomem *ioaddr = tp->base_addr; |
732 | unsigned long flags; | 732 | unsigned long flags; |
733 | 733 | ||
734 | flush_scheduled_work(); | 734 | cancel_work_sync(&tp->media_work); |
735 | 735 | ||
736 | #ifdef CONFIG_TULIP_NAPI | 736 | #ifdef CONFIG_TULIP_NAPI |
737 | napi_disable(&tp->napi); | 737 | napi_disable(&tp->napi); |
@@ -1729,12 +1729,15 @@ static int tulip_suspend (struct pci_dev *pdev, pm_message_t state) | |||
1729 | if (!dev) | 1729 | if (!dev) |
1730 | return -EINVAL; | 1730 | return -EINVAL; |
1731 | 1731 | ||
1732 | if (netif_running(dev)) | 1732 | if (!netif_running(dev)) |
1733 | tulip_down(dev); | 1733 | goto save_state; |
1734 | |||
1735 | tulip_down(dev); | ||
1734 | 1736 | ||
1735 | netif_device_detach(dev); | 1737 | netif_device_detach(dev); |
1736 | free_irq(dev->irq, dev); | 1738 | free_irq(dev->irq, dev); |
1737 | 1739 | ||
1740 | save_state: | ||
1738 | pci_save_state(pdev); | 1741 | pci_save_state(pdev); |
1739 | pci_disable_device(pdev); | 1742 | pci_disable_device(pdev); |
1740 | pci_set_power_state(pdev, pci_choose_state(pdev, state)); | 1743 | pci_set_power_state(pdev, pci_choose_state(pdev, state)); |
@@ -1754,6 +1757,9 @@ static int tulip_resume(struct pci_dev *pdev) | |||
1754 | pci_set_power_state(pdev, PCI_D0); | 1757 | pci_set_power_state(pdev, PCI_D0); |
1755 | pci_restore_state(pdev); | 1758 | pci_restore_state(pdev); |
1756 | 1759 | ||
1760 | if (!netif_running(dev)) | ||
1761 | return 0; | ||
1762 | |||
1757 | if ((retval = pci_enable_device(pdev))) { | 1763 | if ((retval = pci_enable_device(pdev))) { |
1758 | printk (KERN_ERR "tulip: pci_enable_device failed in resume\n"); | 1764 | printk (KERN_ERR "tulip: pci_enable_device failed in resume\n"); |
1759 | return retval; | 1765 | return retval; |
diff --git a/drivers/net/tulip/uli526x.c b/drivers/net/tulip/uli526x.c index a59c1f224aa8..e9e628621639 100644 --- a/drivers/net/tulip/uli526x.c +++ b/drivers/net/tulip/uli526x.c | |||
@@ -225,6 +225,9 @@ static void uli526x_set_filter_mode(struct net_device *); | |||
225 | static const struct ethtool_ops netdev_ethtool_ops; | 225 | static const struct ethtool_ops netdev_ethtool_ops; |
226 | static u16 read_srom_word(long, int); | 226 | static u16 read_srom_word(long, int); |
227 | static irqreturn_t uli526x_interrupt(int, void *); | 227 | static irqreturn_t uli526x_interrupt(int, void *); |
228 | #ifdef CONFIG_NET_POLL_CONTROLLER | ||
229 | static void uli526x_poll(struct net_device *dev); | ||
230 | #endif | ||
228 | static void uli526x_descriptor_init(struct uli526x_board_info *, unsigned long); | 231 | static void uli526x_descriptor_init(struct uli526x_board_info *, unsigned long); |
229 | static void allocate_rx_buffer(struct uli526x_board_info *); | 232 | static void allocate_rx_buffer(struct uli526x_board_info *); |
230 | static void update_cr6(u32, unsigned long); | 233 | static void update_cr6(u32, unsigned long); |
@@ -339,6 +342,9 @@ static int __devinit uli526x_init_one (struct pci_dev *pdev, | |||
339 | dev->get_stats = &uli526x_get_stats; | 342 | dev->get_stats = &uli526x_get_stats; |
340 | dev->set_multicast_list = &uli526x_set_filter_mode; | 343 | dev->set_multicast_list = &uli526x_set_filter_mode; |
341 | dev->ethtool_ops = &netdev_ethtool_ops; | 344 | dev->ethtool_ops = &netdev_ethtool_ops; |
345 | #ifdef CONFIG_NET_POLL_CONTROLLER | ||
346 | dev->poll_controller = &uli526x_poll; | ||
347 | #endif | ||
342 | spin_lock_init(&db->lock); | 348 | spin_lock_init(&db->lock); |
343 | 349 | ||
344 | 350 | ||
@@ -434,10 +440,6 @@ static int uli526x_open(struct net_device *dev) | |||
434 | 440 | ||
435 | ULI526X_DBUG(0, "uli526x_open", 0); | 441 | ULI526X_DBUG(0, "uli526x_open", 0); |
436 | 442 | ||
437 | ret = request_irq(dev->irq, &uli526x_interrupt, IRQF_SHARED, dev->name, dev); | ||
438 | if (ret) | ||
439 | return ret; | ||
440 | |||
441 | /* system variable init */ | 443 | /* system variable init */ |
442 | db->cr6_data = CR6_DEFAULT | uli526x_cr6_user_set; | 444 | db->cr6_data = CR6_DEFAULT | uli526x_cr6_user_set; |
443 | db->tx_packet_cnt = 0; | 445 | db->tx_packet_cnt = 0; |
@@ -456,6 +458,10 @@ static int uli526x_open(struct net_device *dev) | |||
456 | /* Initialize ULI526X board */ | 458 | /* Initialize ULI526X board */ |
457 | uli526x_init(dev); | 459 | uli526x_init(dev); |
458 | 460 | ||
461 | ret = request_irq(dev->irq, &uli526x_interrupt, IRQF_SHARED, dev->name, dev); | ||
462 | if (ret) | ||
463 | return ret; | ||
464 | |||
459 | /* Active System Interface */ | 465 | /* Active System Interface */ |
460 | netif_wake_queue(dev); | 466 | netif_wake_queue(dev); |
461 | 467 | ||
@@ -681,8 +687,9 @@ static irqreturn_t uli526x_interrupt(int irq, void *dev_id) | |||
681 | db->cr5_data = inl(ioaddr + DCR5); | 687 | db->cr5_data = inl(ioaddr + DCR5); |
682 | outl(db->cr5_data, ioaddr + DCR5); | 688 | outl(db->cr5_data, ioaddr + DCR5); |
683 | if ( !(db->cr5_data & 0x180c1) ) { | 689 | if ( !(db->cr5_data & 0x180c1) ) { |
684 | spin_unlock_irqrestore(&db->lock, flags); | 690 | /* Restore CR7 to enable interrupt mask */ |
685 | outl(db->cr7_data, ioaddr + DCR7); | 691 | outl(db->cr7_data, ioaddr + DCR7); |
692 | spin_unlock_irqrestore(&db->lock, flags); | ||
686 | return IRQ_HANDLED; | 693 | return IRQ_HANDLED; |
687 | } | 694 | } |
688 | 695 | ||
@@ -715,6 +722,13 @@ static irqreturn_t uli526x_interrupt(int irq, void *dev_id) | |||
715 | return IRQ_HANDLED; | 722 | return IRQ_HANDLED; |
716 | } | 723 | } |
717 | 724 | ||
725 | #ifdef CONFIG_NET_POLL_CONTROLLER | ||
726 | static void uli526x_poll(struct net_device *dev) | ||
727 | { | ||
728 | /* ISR grabs the irqsave lock, so this should be safe */ | ||
729 | uli526x_interrupt(dev->irq, dev); | ||
730 | } | ||
731 | #endif | ||
718 | 732 | ||
719 | /* | 733 | /* |
720 | * Free TX resource after TX complete | 734 | * Free TX resource after TX complete |
@@ -1368,6 +1382,12 @@ static void update_cr6(u32 cr6_data, unsigned long ioaddr) | |||
1368 | * This setup frame initialize ULI526X address filter mode | 1382 | * This setup frame initialize ULI526X address filter mode |
1369 | */ | 1383 | */ |
1370 | 1384 | ||
1385 | #ifdef __BIG_ENDIAN | ||
1386 | #define FLT_SHIFT 16 | ||
1387 | #else | ||
1388 | #define FLT_SHIFT 0 | ||
1389 | #endif | ||
1390 | |||
1371 | static void send_filter_frame(struct net_device *dev, int mc_cnt) | 1391 | static void send_filter_frame(struct net_device *dev, int mc_cnt) |
1372 | { | 1392 | { |
1373 | struct uli526x_board_info *db = netdev_priv(dev); | 1393 | struct uli526x_board_info *db = netdev_priv(dev); |
@@ -1384,27 +1404,27 @@ static void send_filter_frame(struct net_device *dev, int mc_cnt) | |||
1384 | 1404 | ||
1385 | /* Node address */ | 1405 | /* Node address */ |
1386 | addrptr = (u16 *) dev->dev_addr; | 1406 | addrptr = (u16 *) dev->dev_addr; |
1387 | *suptr++ = addrptr[0]; | 1407 | *suptr++ = addrptr[0] << FLT_SHIFT; |
1388 | *suptr++ = addrptr[1]; | 1408 | *suptr++ = addrptr[1] << FLT_SHIFT; |
1389 | *suptr++ = addrptr[2]; | 1409 | *suptr++ = addrptr[2] << FLT_SHIFT; |
1390 | 1410 | ||
1391 | /* broadcast address */ | 1411 | /* broadcast address */ |
1392 | *suptr++ = 0xffff; | 1412 | *suptr++ = 0xffff << FLT_SHIFT; |
1393 | *suptr++ = 0xffff; | 1413 | *suptr++ = 0xffff << FLT_SHIFT; |
1394 | *suptr++ = 0xffff; | 1414 | *suptr++ = 0xffff << FLT_SHIFT; |
1395 | 1415 | ||
1396 | /* fit the multicast address */ | 1416 | /* fit the multicast address */ |
1397 | for (mcptr = dev->mc_list, i = 0; i < mc_cnt; i++, mcptr = mcptr->next) { | 1417 | for (mcptr = dev->mc_list, i = 0; i < mc_cnt; i++, mcptr = mcptr->next) { |
1398 | addrptr = (u16 *) mcptr->dmi_addr; | 1418 | addrptr = (u16 *) mcptr->dmi_addr; |
1399 | *suptr++ = addrptr[0]; | 1419 | *suptr++ = addrptr[0] << FLT_SHIFT; |
1400 | *suptr++ = addrptr[1]; | 1420 | *suptr++ = addrptr[1] << FLT_SHIFT; |
1401 | *suptr++ = addrptr[2]; | 1421 | *suptr++ = addrptr[2] << FLT_SHIFT; |
1402 | } | 1422 | } |
1403 | 1423 | ||
1404 | for (; i<14; i++) { | 1424 | for (; i<14; i++) { |
1405 | *suptr++ = 0xffff; | 1425 | *suptr++ = 0xffff << FLT_SHIFT; |
1406 | *suptr++ = 0xffff; | 1426 | *suptr++ = 0xffff << FLT_SHIFT; |
1407 | *suptr++ = 0xffff; | 1427 | *suptr++ = 0xffff << FLT_SHIFT; |
1408 | } | 1428 | } |
1409 | 1429 | ||
1410 | /* prepare the setup frame */ | 1430 | /* prepare the setup frame */ |
diff --git a/drivers/net/tun.c b/drivers/net/tun.c index 0ce07a339c7e..b9018bfa0a97 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c | |||
@@ -313,6 +313,21 @@ static __inline__ ssize_t tun_get_user(struct tun_struct *tun, struct iovec *iv, | |||
313 | 313 | ||
314 | switch (tun->flags & TUN_TYPE_MASK) { | 314 | switch (tun->flags & TUN_TYPE_MASK) { |
315 | case TUN_TUN_DEV: | 315 | case TUN_TUN_DEV: |
316 | if (tun->flags & TUN_NO_PI) { | ||
317 | switch (skb->data[0] & 0xf0) { | ||
318 | case 0x40: | ||
319 | pi.proto = htons(ETH_P_IP); | ||
320 | break; | ||
321 | case 0x60: | ||
322 | pi.proto = htons(ETH_P_IPV6); | ||
323 | break; | ||
324 | default: | ||
325 | tun->dev->stats.rx_dropped++; | ||
326 | kfree_skb(skb); | ||
327 | return -EINVAL; | ||
328 | } | ||
329 | } | ||
330 | |||
316 | skb_reset_mac_header(skb); | 331 | skb_reset_mac_header(skb); |
317 | skb->protocol = pi.proto; | 332 | skb->protocol = pi.proto; |
318 | skb->dev = tun->dev; | 333 | skb->dev = tun->dev; |
@@ -587,6 +602,12 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr) | |||
587 | tun->attached = 1; | 602 | tun->attached = 1; |
588 | get_net(dev_net(tun->dev)); | 603 | get_net(dev_net(tun->dev)); |
589 | 604 | ||
605 | /* Make sure persistent devices do not get stuck in | ||
606 | * xoff state. | ||
607 | */ | ||
608 | if (netif_running(tun->dev)) | ||
609 | netif_wake_queue(tun->dev); | ||
610 | |||
590 | strcpy(ifr->ifr_name, tun->dev->name); | 611 | strcpy(ifr->ifr_name, tun->dev->name); |
591 | return 0; | 612 | return 0; |
592 | 613 | ||
diff --git a/drivers/net/ucc_geth.c b/drivers/net/ucc_geth.c index 281ce3d39532..fb0b918e5ccb 100644 --- a/drivers/net/ucc_geth.c +++ b/drivers/net/ucc_geth.c | |||
@@ -62,7 +62,6 @@ | |||
62 | #endif /* UGETH_VERBOSE_DEBUG */ | 62 | #endif /* UGETH_VERBOSE_DEBUG */ |
63 | #define UGETH_MSG_DEFAULT (NETIF_MSG_IFUP << 1 ) - 1 | 63 | #define UGETH_MSG_DEFAULT (NETIF_MSG_IFUP << 1 ) - 1 |
64 | 64 | ||
65 | void uec_set_ethtool_ops(struct net_device *netdev); | ||
66 | 65 | ||
67 | static DEFINE_SPINLOCK(ugeth_lock); | 66 | static DEFINE_SPINLOCK(ugeth_lock); |
68 | 67 | ||
@@ -216,7 +215,8 @@ static struct list_head *dequeue(struct list_head *lh) | |||
216 | } | 215 | } |
217 | } | 216 | } |
218 | 217 | ||
219 | static struct sk_buff *get_new_skb(struct ucc_geth_private *ugeth, u8 *bd) | 218 | static struct sk_buff *get_new_skb(struct ucc_geth_private *ugeth, |
219 | u8 __iomem *bd) | ||
220 | { | 220 | { |
221 | struct sk_buff *skb = NULL; | 221 | struct sk_buff *skb = NULL; |
222 | 222 | ||
@@ -236,21 +236,22 @@ static struct sk_buff *get_new_skb(struct ucc_geth_private *ugeth, u8 *bd) | |||
236 | 236 | ||
237 | skb->dev = ugeth->dev; | 237 | skb->dev = ugeth->dev; |
238 | 238 | ||
239 | out_be32(&((struct qe_bd *)bd)->buf, | 239 | out_be32(&((struct qe_bd __iomem *)bd)->buf, |
240 | dma_map_single(NULL, | 240 | dma_map_single(&ugeth->dev->dev, |
241 | skb->data, | 241 | skb->data, |
242 | ugeth->ug_info->uf_info.max_rx_buf_length + | 242 | ugeth->ug_info->uf_info.max_rx_buf_length + |
243 | UCC_GETH_RX_DATA_BUF_ALIGNMENT, | 243 | UCC_GETH_RX_DATA_BUF_ALIGNMENT, |
244 | DMA_FROM_DEVICE)); | 244 | DMA_FROM_DEVICE)); |
245 | 245 | ||
246 | out_be32((u32 *)bd, (R_E | R_I | (in_be32((u32 *)bd) & R_W))); | 246 | out_be32((u32 __iomem *)bd, |
247 | (R_E | R_I | (in_be32((u32 __iomem*)bd) & R_W))); | ||
247 | 248 | ||
248 | return skb; | 249 | return skb; |
249 | } | 250 | } |
250 | 251 | ||
251 | static int rx_bd_buffer_set(struct ucc_geth_private *ugeth, u8 rxQ) | 252 | static int rx_bd_buffer_set(struct ucc_geth_private *ugeth, u8 rxQ) |
252 | { | 253 | { |
253 | u8 *bd; | 254 | u8 __iomem *bd; |
254 | u32 bd_status; | 255 | u32 bd_status; |
255 | struct sk_buff *skb; | 256 | struct sk_buff *skb; |
256 | int i; | 257 | int i; |
@@ -259,7 +260,7 @@ static int rx_bd_buffer_set(struct ucc_geth_private *ugeth, u8 rxQ) | |||
259 | i = 0; | 260 | i = 0; |
260 | 261 | ||
261 | do { | 262 | do { |
262 | bd_status = in_be32((u32*)bd); | 263 | bd_status = in_be32((u32 __iomem *)bd); |
263 | skb = get_new_skb(ugeth, bd); | 264 | skb = get_new_skb(ugeth, bd); |
264 | 265 | ||
265 | if (!skb) /* If can not allocate data buffer, | 266 | if (!skb) /* If can not allocate data buffer, |
@@ -277,7 +278,7 @@ static int rx_bd_buffer_set(struct ucc_geth_private *ugeth, u8 rxQ) | |||
277 | } | 278 | } |
278 | 279 | ||
279 | static int fill_init_enet_entries(struct ucc_geth_private *ugeth, | 280 | static int fill_init_enet_entries(struct ucc_geth_private *ugeth, |
280 | volatile u32 *p_start, | 281 | u32 *p_start, |
281 | u8 num_entries, | 282 | u8 num_entries, |
282 | u32 thread_size, | 283 | u32 thread_size, |
283 | u32 thread_alignment, | 284 | u32 thread_alignment, |
@@ -316,7 +317,7 @@ static int fill_init_enet_entries(struct ucc_geth_private *ugeth, | |||
316 | } | 317 | } |
317 | 318 | ||
318 | static int return_init_enet_entries(struct ucc_geth_private *ugeth, | 319 | static int return_init_enet_entries(struct ucc_geth_private *ugeth, |
319 | volatile u32 *p_start, | 320 | u32 *p_start, |
320 | u8 num_entries, | 321 | u8 num_entries, |
321 | enum qe_risc_allocation risc, | 322 | enum qe_risc_allocation risc, |
322 | int skip_page_for_first_entry) | 323 | int skip_page_for_first_entry) |
@@ -326,21 +327,22 @@ static int return_init_enet_entries(struct ucc_geth_private *ugeth, | |||
326 | int snum; | 327 | int snum; |
327 | 328 | ||
328 | for (i = 0; i < num_entries; i++) { | 329 | for (i = 0; i < num_entries; i++) { |
330 | u32 val = *p_start; | ||
331 | |||
329 | /* Check that this entry was actually valid -- | 332 | /* Check that this entry was actually valid -- |
330 | needed in case failed in allocations */ | 333 | needed in case failed in allocations */ |
331 | if ((*p_start & ENET_INIT_PARAM_RISC_MASK) == risc) { | 334 | if ((val & ENET_INIT_PARAM_RISC_MASK) == risc) { |
332 | snum = | 335 | snum = |
333 | (u32) (*p_start & ENET_INIT_PARAM_SNUM_MASK) >> | 336 | (u32) (val & ENET_INIT_PARAM_SNUM_MASK) >> |
334 | ENET_INIT_PARAM_SNUM_SHIFT; | 337 | ENET_INIT_PARAM_SNUM_SHIFT; |
335 | qe_put_snum((u8) snum); | 338 | qe_put_snum((u8) snum); |
336 | if (!((i == 0) && skip_page_for_first_entry)) { | 339 | if (!((i == 0) && skip_page_for_first_entry)) { |
337 | /* First entry of Rx does not have page */ | 340 | /* First entry of Rx does not have page */ |
338 | init_enet_offset = | 341 | init_enet_offset = |
339 | (in_be32(p_start) & | 342 | (val & ENET_INIT_PARAM_PTR_MASK); |
340 | ENET_INIT_PARAM_PTR_MASK); | ||
341 | qe_muram_free(init_enet_offset); | 343 | qe_muram_free(init_enet_offset); |
342 | } | 344 | } |
343 | *(p_start++) = 0; /* Just for cosmetics */ | 345 | *p_start++ = 0; |
344 | } | 346 | } |
345 | } | 347 | } |
346 | 348 | ||
@@ -349,7 +351,7 @@ static int return_init_enet_entries(struct ucc_geth_private *ugeth, | |||
349 | 351 | ||
350 | #ifdef DEBUG | 352 | #ifdef DEBUG |
351 | static int dump_init_enet_entries(struct ucc_geth_private *ugeth, | 353 | static int dump_init_enet_entries(struct ucc_geth_private *ugeth, |
352 | volatile u32 *p_start, | 354 | u32 __iomem *p_start, |
353 | u8 num_entries, | 355 | u8 num_entries, |
354 | u32 thread_size, | 356 | u32 thread_size, |
355 | enum qe_risc_allocation risc, | 357 | enum qe_risc_allocation risc, |
@@ -360,11 +362,13 @@ static int dump_init_enet_entries(struct ucc_geth_private *ugeth, | |||
360 | int snum; | 362 | int snum; |
361 | 363 | ||
362 | for (i = 0; i < num_entries; i++) { | 364 | for (i = 0; i < num_entries; i++) { |
365 | u32 val = in_be32(p_start); | ||
366 | |||
363 | /* Check that this entry was actually valid -- | 367 | /* Check that this entry was actually valid -- |
364 | needed in case failed in allocations */ | 368 | needed in case failed in allocations */ |
365 | if ((*p_start & ENET_INIT_PARAM_RISC_MASK) == risc) { | 369 | if ((val & ENET_INIT_PARAM_RISC_MASK) == risc) { |
366 | snum = | 370 | snum = |
367 | (u32) (*p_start & ENET_INIT_PARAM_SNUM_MASK) >> | 371 | (u32) (val & ENET_INIT_PARAM_SNUM_MASK) >> |
368 | ENET_INIT_PARAM_SNUM_SHIFT; | 372 | ENET_INIT_PARAM_SNUM_SHIFT; |
369 | qe_put_snum((u8) snum); | 373 | qe_put_snum((u8) snum); |
370 | if (!((i == 0) && skip_page_for_first_entry)) { | 374 | if (!((i == 0) && skip_page_for_first_entry)) { |
@@ -440,7 +444,7 @@ static int hw_add_addr_in_paddr(struct ucc_geth_private *ugeth, | |||
440 | 444 | ||
441 | static int hw_clear_addr_in_paddr(struct ucc_geth_private *ugeth, u8 paddr_num) | 445 | static int hw_clear_addr_in_paddr(struct ucc_geth_private *ugeth, u8 paddr_num) |
442 | { | 446 | { |
443 | struct ucc_geth_82xx_address_filtering_pram *p_82xx_addr_filt; | 447 | struct ucc_geth_82xx_address_filtering_pram __iomem *p_82xx_addr_filt; |
444 | 448 | ||
445 | if (!(paddr_num < NUM_OF_PADDRS)) { | 449 | if (!(paddr_num < NUM_OF_PADDRS)) { |
446 | ugeth_warn("%s: Illagel paddr_num.", __FUNCTION__); | 450 | ugeth_warn("%s: Illagel paddr_num.", __FUNCTION__); |
@@ -448,7 +452,7 @@ static int hw_clear_addr_in_paddr(struct ucc_geth_private *ugeth, u8 paddr_num) | |||
448 | } | 452 | } |
449 | 453 | ||
450 | p_82xx_addr_filt = | 454 | p_82xx_addr_filt = |
451 | (struct ucc_geth_82xx_address_filtering_pram *) ugeth->p_rx_glbl_pram-> | 455 | (struct ucc_geth_82xx_address_filtering_pram __iomem *) ugeth->p_rx_glbl_pram-> |
452 | addressfiltering; | 456 | addressfiltering; |
453 | 457 | ||
454 | /* Writing address ff.ff.ff.ff.ff.ff disables address | 458 | /* Writing address ff.ff.ff.ff.ff.ff disables address |
@@ -463,11 +467,11 @@ static int hw_clear_addr_in_paddr(struct ucc_geth_private *ugeth, u8 paddr_num) | |||
463 | static void hw_add_addr_in_hash(struct ucc_geth_private *ugeth, | 467 | static void hw_add_addr_in_hash(struct ucc_geth_private *ugeth, |
464 | u8 *p_enet_addr) | 468 | u8 *p_enet_addr) |
465 | { | 469 | { |
466 | struct ucc_geth_82xx_address_filtering_pram *p_82xx_addr_filt; | 470 | struct ucc_geth_82xx_address_filtering_pram __iomem *p_82xx_addr_filt; |
467 | u32 cecr_subblock; | 471 | u32 cecr_subblock; |
468 | 472 | ||
469 | p_82xx_addr_filt = | 473 | p_82xx_addr_filt = |
470 | (struct ucc_geth_82xx_address_filtering_pram *) ugeth->p_rx_glbl_pram-> | 474 | (struct ucc_geth_82xx_address_filtering_pram __iomem *) ugeth->p_rx_glbl_pram-> |
471 | addressfiltering; | 475 | addressfiltering; |
472 | 476 | ||
473 | cecr_subblock = | 477 | cecr_subblock = |
@@ -487,7 +491,7 @@ static void hw_add_addr_in_hash(struct ucc_geth_private *ugeth, | |||
487 | static void magic_packet_detection_enable(struct ucc_geth_private *ugeth) | 491 | static void magic_packet_detection_enable(struct ucc_geth_private *ugeth) |
488 | { | 492 | { |
489 | struct ucc_fast_private *uccf; | 493 | struct ucc_fast_private *uccf; |
490 | struct ucc_geth *ug_regs; | 494 | struct ucc_geth __iomem *ug_regs; |
491 | u32 maccfg2, uccm; | 495 | u32 maccfg2, uccm; |
492 | 496 | ||
493 | uccf = ugeth->uccf; | 497 | uccf = ugeth->uccf; |
@@ -507,7 +511,7 @@ static void magic_packet_detection_enable(struct ucc_geth_private *ugeth) | |||
507 | static void magic_packet_detection_disable(struct ucc_geth_private *ugeth) | 511 | static void magic_packet_detection_disable(struct ucc_geth_private *ugeth) |
508 | { | 512 | { |
509 | struct ucc_fast_private *uccf; | 513 | struct ucc_fast_private *uccf; |
510 | struct ucc_geth *ug_regs; | 514 | struct ucc_geth __iomem *ug_regs; |
511 | u32 maccfg2, uccm; | 515 | u32 maccfg2, uccm; |
512 | 516 | ||
513 | uccf = ugeth->uccf; | 517 | uccf = ugeth->uccf; |
@@ -538,13 +542,13 @@ static void get_statistics(struct ucc_geth_private *ugeth, | |||
538 | rx_firmware_statistics, | 542 | rx_firmware_statistics, |
539 | struct ucc_geth_hardware_statistics *hardware_statistics) | 543 | struct ucc_geth_hardware_statistics *hardware_statistics) |
540 | { | 544 | { |
541 | struct ucc_fast *uf_regs; | 545 | struct ucc_fast __iomem *uf_regs; |
542 | struct ucc_geth *ug_regs; | 546 | struct ucc_geth __iomem *ug_regs; |
543 | struct ucc_geth_tx_firmware_statistics_pram *p_tx_fw_statistics_pram; | 547 | struct ucc_geth_tx_firmware_statistics_pram *p_tx_fw_statistics_pram; |
544 | struct ucc_geth_rx_firmware_statistics_pram *p_rx_fw_statistics_pram; | 548 | struct ucc_geth_rx_firmware_statistics_pram *p_rx_fw_statistics_pram; |
545 | 549 | ||
546 | ug_regs = ugeth->ug_regs; | 550 | ug_regs = ugeth->ug_regs; |
547 | uf_regs = (struct ucc_fast *) ug_regs; | 551 | uf_regs = (struct ucc_fast __iomem *) ug_regs; |
548 | p_tx_fw_statistics_pram = ugeth->p_tx_fw_statistics_pram; | 552 | p_tx_fw_statistics_pram = ugeth->p_tx_fw_statistics_pram; |
549 | p_rx_fw_statistics_pram = ugeth->p_rx_fw_statistics_pram; | 553 | p_rx_fw_statistics_pram = ugeth->p_rx_fw_statistics_pram; |
550 | 554 | ||
@@ -1132,9 +1136,9 @@ static void dump_regs(struct ucc_geth_private *ugeth) | |||
1132 | } | 1136 | } |
1133 | #endif /* DEBUG */ | 1137 | #endif /* DEBUG */ |
1134 | 1138 | ||
1135 | static void init_default_reg_vals(volatile u32 *upsmr_register, | 1139 | static void init_default_reg_vals(u32 __iomem *upsmr_register, |
1136 | volatile u32 *maccfg1_register, | 1140 | u32 __iomem *maccfg1_register, |
1137 | volatile u32 *maccfg2_register) | 1141 | u32 __iomem *maccfg2_register) |
1138 | { | 1142 | { |
1139 | out_be32(upsmr_register, UCC_GETH_UPSMR_INIT); | 1143 | out_be32(upsmr_register, UCC_GETH_UPSMR_INIT); |
1140 | out_be32(maccfg1_register, UCC_GETH_MACCFG1_INIT); | 1144 | out_be32(maccfg1_register, UCC_GETH_MACCFG1_INIT); |
@@ -1148,7 +1152,7 @@ static int init_half_duplex_params(int alt_beb, | |||
1148 | u8 alt_beb_truncation, | 1152 | u8 alt_beb_truncation, |
1149 | u8 max_retransmissions, | 1153 | u8 max_retransmissions, |
1150 | u8 collision_window, | 1154 | u8 collision_window, |
1151 | volatile u32 *hafdup_register) | 1155 | u32 __iomem *hafdup_register) |
1152 | { | 1156 | { |
1153 | u32 value = 0; | 1157 | u32 value = 0; |
1154 | 1158 | ||
@@ -1180,7 +1184,7 @@ static int init_inter_frame_gap_params(u8 non_btb_cs_ipg, | |||
1180 | u8 non_btb_ipg, | 1184 | u8 non_btb_ipg, |
1181 | u8 min_ifg, | 1185 | u8 min_ifg, |
1182 | u8 btb_ipg, | 1186 | u8 btb_ipg, |
1183 | volatile u32 *ipgifg_register) | 1187 | u32 __iomem *ipgifg_register) |
1184 | { | 1188 | { |
1185 | u32 value = 0; | 1189 | u32 value = 0; |
1186 | 1190 | ||
@@ -1215,9 +1219,9 @@ int init_flow_control_params(u32 automatic_flow_control_mode, | |||
1215 | int tx_flow_control_enable, | 1219 | int tx_flow_control_enable, |
1216 | u16 pause_period, | 1220 | u16 pause_period, |
1217 | u16 extension_field, | 1221 | u16 extension_field, |
1218 | volatile u32 *upsmr_register, | 1222 | u32 __iomem *upsmr_register, |
1219 | volatile u32 *uempr_register, | 1223 | u32 __iomem *uempr_register, |
1220 | volatile u32 *maccfg1_register) | 1224 | u32 __iomem *maccfg1_register) |
1221 | { | 1225 | { |
1222 | u32 value = 0; | 1226 | u32 value = 0; |
1223 | 1227 | ||
@@ -1243,8 +1247,8 @@ int init_flow_control_params(u32 automatic_flow_control_mode, | |||
1243 | 1247 | ||
1244 | static int init_hw_statistics_gathering_mode(int enable_hardware_statistics, | 1248 | static int init_hw_statistics_gathering_mode(int enable_hardware_statistics, |
1245 | int auto_zero_hardware_statistics, | 1249 | int auto_zero_hardware_statistics, |
1246 | volatile u32 *upsmr_register, | 1250 | u32 __iomem *upsmr_register, |
1247 | volatile u16 *uescr_register) | 1251 | u16 __iomem *uescr_register) |
1248 | { | 1252 | { |
1249 | u32 upsmr_value = 0; | 1253 | u32 upsmr_value = 0; |
1250 | u16 uescr_value = 0; | 1254 | u16 uescr_value = 0; |
@@ -1270,12 +1274,12 @@ static int init_hw_statistics_gathering_mode(int enable_hardware_statistics, | |||
1270 | static int init_firmware_statistics_gathering_mode(int | 1274 | static int init_firmware_statistics_gathering_mode(int |
1271 | enable_tx_firmware_statistics, | 1275 | enable_tx_firmware_statistics, |
1272 | int enable_rx_firmware_statistics, | 1276 | int enable_rx_firmware_statistics, |
1273 | volatile u32 *tx_rmon_base_ptr, | 1277 | u32 __iomem *tx_rmon_base_ptr, |
1274 | u32 tx_firmware_statistics_structure_address, | 1278 | u32 tx_firmware_statistics_structure_address, |
1275 | volatile u32 *rx_rmon_base_ptr, | 1279 | u32 __iomem *rx_rmon_base_ptr, |
1276 | u32 rx_firmware_statistics_structure_address, | 1280 | u32 rx_firmware_statistics_structure_address, |
1277 | volatile u16 *temoder_register, | 1281 | u16 __iomem *temoder_register, |
1278 | volatile u32 *remoder_register) | 1282 | u32 __iomem *remoder_register) |
1279 | { | 1283 | { |
1280 | /* Note: this function does not check if */ | 1284 | /* Note: this function does not check if */ |
1281 | /* the parameters it receives are NULL */ | 1285 | /* the parameters it receives are NULL */ |
@@ -1307,8 +1311,8 @@ static int init_mac_station_addr_regs(u8 address_byte_0, | |||
1307 | u8 address_byte_3, | 1311 | u8 address_byte_3, |
1308 | u8 address_byte_4, | 1312 | u8 address_byte_4, |
1309 | u8 address_byte_5, | 1313 | u8 address_byte_5, |
1310 | volatile u32 *macstnaddr1_register, | 1314 | u32 __iomem *macstnaddr1_register, |
1311 | volatile u32 *macstnaddr2_register) | 1315 | u32 __iomem *macstnaddr2_register) |
1312 | { | 1316 | { |
1313 | u32 value = 0; | 1317 | u32 value = 0; |
1314 | 1318 | ||
@@ -1344,7 +1348,7 @@ static int init_mac_station_addr_regs(u8 address_byte_0, | |||
1344 | } | 1348 | } |
1345 | 1349 | ||
1346 | static int init_check_frame_length_mode(int length_check, | 1350 | static int init_check_frame_length_mode(int length_check, |
1347 | volatile u32 *maccfg2_register) | 1351 | u32 __iomem *maccfg2_register) |
1348 | { | 1352 | { |
1349 | u32 value = 0; | 1353 | u32 value = 0; |
1350 | 1354 | ||
@@ -1360,7 +1364,7 @@ static int init_check_frame_length_mode(int length_check, | |||
1360 | } | 1364 | } |
1361 | 1365 | ||
1362 | static int init_preamble_length(u8 preamble_length, | 1366 | static int init_preamble_length(u8 preamble_length, |
1363 | volatile u32 *maccfg2_register) | 1367 | u32 __iomem *maccfg2_register) |
1364 | { | 1368 | { |
1365 | u32 value = 0; | 1369 | u32 value = 0; |
1366 | 1370 | ||
@@ -1376,7 +1380,7 @@ static int init_preamble_length(u8 preamble_length, | |||
1376 | 1380 | ||
1377 | static int init_rx_parameters(int reject_broadcast, | 1381 | static int init_rx_parameters(int reject_broadcast, |
1378 | int receive_short_frames, | 1382 | int receive_short_frames, |
1379 | int promiscuous, volatile u32 *upsmr_register) | 1383 | int promiscuous, u32 __iomem *upsmr_register) |
1380 | { | 1384 | { |
1381 | u32 value = 0; | 1385 | u32 value = 0; |
1382 | 1386 | ||
@@ -1403,7 +1407,7 @@ static int init_rx_parameters(int reject_broadcast, | |||
1403 | } | 1407 | } |
1404 | 1408 | ||
1405 | static int init_max_rx_buff_len(u16 max_rx_buf_len, | 1409 | static int init_max_rx_buff_len(u16 max_rx_buf_len, |
1406 | volatile u16 *mrblr_register) | 1410 | u16 __iomem *mrblr_register) |
1407 | { | 1411 | { |
1408 | /* max_rx_buf_len value must be a multiple of 128 */ | 1412 | /* max_rx_buf_len value must be a multiple of 128 */ |
1409 | if ((max_rx_buf_len == 0) | 1413 | if ((max_rx_buf_len == 0) |
@@ -1415,8 +1419,8 @@ static int init_max_rx_buff_len(u16 max_rx_buf_len, | |||
1415 | } | 1419 | } |
1416 | 1420 | ||
1417 | static int init_min_frame_len(u16 min_frame_length, | 1421 | static int init_min_frame_len(u16 min_frame_length, |
1418 | volatile u16 *minflr_register, | 1422 | u16 __iomem *minflr_register, |
1419 | volatile u16 *mrblr_register) | 1423 | u16 __iomem *mrblr_register) |
1420 | { | 1424 | { |
1421 | u16 mrblr_value = 0; | 1425 | u16 mrblr_value = 0; |
1422 | 1426 | ||
@@ -1431,8 +1435,8 @@ static int init_min_frame_len(u16 min_frame_length, | |||
1431 | static int adjust_enet_interface(struct ucc_geth_private *ugeth) | 1435 | static int adjust_enet_interface(struct ucc_geth_private *ugeth) |
1432 | { | 1436 | { |
1433 | struct ucc_geth_info *ug_info; | 1437 | struct ucc_geth_info *ug_info; |
1434 | struct ucc_geth *ug_regs; | 1438 | struct ucc_geth __iomem *ug_regs; |
1435 | struct ucc_fast *uf_regs; | 1439 | struct ucc_fast __iomem *uf_regs; |
1436 | int ret_val; | 1440 | int ret_val; |
1437 | u32 upsmr, maccfg2, tbiBaseAddress; | 1441 | u32 upsmr, maccfg2, tbiBaseAddress; |
1438 | u16 value; | 1442 | u16 value; |
@@ -1517,8 +1521,8 @@ static int adjust_enet_interface(struct ucc_geth_private *ugeth) | |||
1517 | static void adjust_link(struct net_device *dev) | 1521 | static void adjust_link(struct net_device *dev) |
1518 | { | 1522 | { |
1519 | struct ucc_geth_private *ugeth = netdev_priv(dev); | 1523 | struct ucc_geth_private *ugeth = netdev_priv(dev); |
1520 | struct ucc_geth *ug_regs; | 1524 | struct ucc_geth __iomem *ug_regs; |
1521 | struct ucc_fast *uf_regs; | 1525 | struct ucc_fast __iomem *uf_regs; |
1522 | struct phy_device *phydev = ugeth->phydev; | 1526 | struct phy_device *phydev = ugeth->phydev; |
1523 | unsigned long flags; | 1527 | unsigned long flags; |
1524 | int new_state = 0; | 1528 | int new_state = 0; |
@@ -1678,9 +1682,9 @@ static int ugeth_graceful_stop_rx(struct ucc_geth_private * ugeth) | |||
1678 | uccf = ugeth->uccf; | 1682 | uccf = ugeth->uccf; |
1679 | 1683 | ||
1680 | /* Clear acknowledge bit */ | 1684 | /* Clear acknowledge bit */ |
1681 | temp = ugeth->p_rx_glbl_pram->rxgstpack; | 1685 | temp = in_8(&ugeth->p_rx_glbl_pram->rxgstpack); |
1682 | temp &= ~GRACEFUL_STOP_ACKNOWLEDGE_RX; | 1686 | temp &= ~GRACEFUL_STOP_ACKNOWLEDGE_RX; |
1683 | ugeth->p_rx_glbl_pram->rxgstpack = temp; | 1687 | out_8(&ugeth->p_rx_glbl_pram->rxgstpack, temp); |
1684 | 1688 | ||
1685 | /* Keep issuing command and checking acknowledge bit until | 1689 | /* Keep issuing command and checking acknowledge bit until |
1686 | it is asserted, according to spec */ | 1690 | it is asserted, according to spec */ |
@@ -1692,7 +1696,7 @@ static int ugeth_graceful_stop_rx(struct ucc_geth_private * ugeth) | |||
1692 | qe_issue_cmd(QE_GRACEFUL_STOP_RX, cecr_subblock, | 1696 | qe_issue_cmd(QE_GRACEFUL_STOP_RX, cecr_subblock, |
1693 | QE_CR_PROTOCOL_ETHERNET, 0); | 1697 | QE_CR_PROTOCOL_ETHERNET, 0); |
1694 | 1698 | ||
1695 | temp = ugeth->p_rx_glbl_pram->rxgstpack; | 1699 | temp = in_8(&ugeth->p_rx_glbl_pram->rxgstpack); |
1696 | } while (!(temp & GRACEFUL_STOP_ACKNOWLEDGE_RX)); | 1700 | } while (!(temp & GRACEFUL_STOP_ACKNOWLEDGE_RX)); |
1697 | 1701 | ||
1698 | uccf->stopped_rx = 1; | 1702 | uccf->stopped_rx = 1; |
@@ -1991,19 +1995,20 @@ static int ugeth_82xx_filtering_clear_all_addr_in_hash(struct ucc_geth_private * | |||
1991 | enum enet_addr_type | 1995 | enum enet_addr_type |
1992 | enet_addr_type) | 1996 | enet_addr_type) |
1993 | { | 1997 | { |
1994 | struct ucc_geth_82xx_address_filtering_pram *p_82xx_addr_filt; | 1998 | struct ucc_geth_82xx_address_filtering_pram __iomem *p_82xx_addr_filt; |
1995 | struct ucc_fast_private *uccf; | 1999 | struct ucc_fast_private *uccf; |
1996 | enum comm_dir comm_dir; | 2000 | enum comm_dir comm_dir; |
1997 | struct list_head *p_lh; | 2001 | struct list_head *p_lh; |
1998 | u16 i, num; | 2002 | u16 i, num; |
1999 | u32 *addr_h, *addr_l; | 2003 | u32 __iomem *addr_h; |
2004 | u32 __iomem *addr_l; | ||
2000 | u8 *p_counter; | 2005 | u8 *p_counter; |
2001 | 2006 | ||
2002 | uccf = ugeth->uccf; | 2007 | uccf = ugeth->uccf; |
2003 | 2008 | ||
2004 | p_82xx_addr_filt = | 2009 | p_82xx_addr_filt = |
2005 | (struct ucc_geth_82xx_address_filtering_pram *) ugeth->p_rx_glbl_pram-> | 2010 | (struct ucc_geth_82xx_address_filtering_pram __iomem *) |
2006 | addressfiltering; | 2011 | ugeth->p_rx_glbl_pram->addressfiltering; |
2007 | 2012 | ||
2008 | if (enet_addr_type == ENET_ADDR_TYPE_GROUP) { | 2013 | if (enet_addr_type == ENET_ADDR_TYPE_GROUP) { |
2009 | addr_h = &(p_82xx_addr_filt->gaddr_h); | 2014 | addr_h = &(p_82xx_addr_filt->gaddr_h); |
@@ -2079,7 +2084,7 @@ static int ugeth_82xx_filtering_clear_addr_in_paddr(struct ucc_geth_private *uge | |||
2079 | static void ucc_geth_memclean(struct ucc_geth_private *ugeth) | 2084 | static void ucc_geth_memclean(struct ucc_geth_private *ugeth) |
2080 | { | 2085 | { |
2081 | u16 i, j; | 2086 | u16 i, j; |
2082 | u8 *bd; | 2087 | u8 __iomem *bd; |
2083 | 2088 | ||
2084 | if (!ugeth) | 2089 | if (!ugeth) |
2085 | return; | 2090 | return; |
@@ -2153,9 +2158,9 @@ static void ucc_geth_memclean(struct ucc_geth_private *ugeth) | |||
2153 | continue; | 2158 | continue; |
2154 | for (j = 0; j < ugeth->ug_info->bdRingLenTx[i]; j++) { | 2159 | for (j = 0; j < ugeth->ug_info->bdRingLenTx[i]; j++) { |
2155 | if (ugeth->tx_skbuff[i][j]) { | 2160 | if (ugeth->tx_skbuff[i][j]) { |
2156 | dma_unmap_single(NULL, | 2161 | dma_unmap_single(&ugeth->dev->dev, |
2157 | ((struct qe_bd *)bd)->buf, | 2162 | in_be32(&((struct qe_bd __iomem *)bd)->buf), |
2158 | (in_be32((u32 *)bd) & | 2163 | (in_be32((u32 __iomem *)bd) & |
2159 | BD_LENGTH_MASK), | 2164 | BD_LENGTH_MASK), |
2160 | DMA_TO_DEVICE); | 2165 | DMA_TO_DEVICE); |
2161 | dev_kfree_skb_any(ugeth->tx_skbuff[i][j]); | 2166 | dev_kfree_skb_any(ugeth->tx_skbuff[i][j]); |
@@ -2181,8 +2186,8 @@ static void ucc_geth_memclean(struct ucc_geth_private *ugeth) | |||
2181 | bd = ugeth->p_rx_bd_ring[i]; | 2186 | bd = ugeth->p_rx_bd_ring[i]; |
2182 | for (j = 0; j < ugeth->ug_info->bdRingLenRx[i]; j++) { | 2187 | for (j = 0; j < ugeth->ug_info->bdRingLenRx[i]; j++) { |
2183 | if (ugeth->rx_skbuff[i][j]) { | 2188 | if (ugeth->rx_skbuff[i][j]) { |
2184 | dma_unmap_single(NULL, | 2189 | dma_unmap_single(&ugeth->dev->dev, |
2185 | ((struct qe_bd *)bd)->buf, | 2190 | in_be32(&((struct qe_bd __iomem *)bd)->buf), |
2186 | ugeth->ug_info-> | 2191 | ugeth->ug_info-> |
2187 | uf_info.max_rx_buf_length + | 2192 | uf_info.max_rx_buf_length + |
2188 | UCC_GETH_RX_DATA_BUF_ALIGNMENT, | 2193 | UCC_GETH_RX_DATA_BUF_ALIGNMENT, |
@@ -2218,8 +2223,8 @@ static void ucc_geth_set_multi(struct net_device *dev) | |||
2218 | { | 2223 | { |
2219 | struct ucc_geth_private *ugeth; | 2224 | struct ucc_geth_private *ugeth; |
2220 | struct dev_mc_list *dmi; | 2225 | struct dev_mc_list *dmi; |
2221 | struct ucc_fast *uf_regs; | 2226 | struct ucc_fast __iomem *uf_regs; |
2222 | struct ucc_geth_82xx_address_filtering_pram *p_82xx_addr_filt; | 2227 | struct ucc_geth_82xx_address_filtering_pram __iomem *p_82xx_addr_filt; |
2223 | int i; | 2228 | int i; |
2224 | 2229 | ||
2225 | ugeth = netdev_priv(dev); | 2230 | ugeth = netdev_priv(dev); |
@@ -2228,14 +2233,14 @@ static void ucc_geth_set_multi(struct net_device *dev) | |||
2228 | 2233 | ||
2229 | if (dev->flags & IFF_PROMISC) { | 2234 | if (dev->flags & IFF_PROMISC) { |
2230 | 2235 | ||
2231 | uf_regs->upsmr |= UPSMR_PRO; | 2236 | out_be32(&uf_regs->upsmr, in_be32(&uf_regs->upsmr) | UPSMR_PRO); |
2232 | 2237 | ||
2233 | } else { | 2238 | } else { |
2234 | 2239 | ||
2235 | uf_regs->upsmr &= ~UPSMR_PRO; | 2240 | out_be32(&uf_regs->upsmr, in_be32(&uf_regs->upsmr)&~UPSMR_PRO); |
2236 | 2241 | ||
2237 | p_82xx_addr_filt = | 2242 | p_82xx_addr_filt = |
2238 | (struct ucc_geth_82xx_address_filtering_pram *) ugeth-> | 2243 | (struct ucc_geth_82xx_address_filtering_pram __iomem *) ugeth-> |
2239 | p_rx_glbl_pram->addressfiltering; | 2244 | p_rx_glbl_pram->addressfiltering; |
2240 | 2245 | ||
2241 | if (dev->flags & IFF_ALLMULTI) { | 2246 | if (dev->flags & IFF_ALLMULTI) { |
@@ -2270,7 +2275,7 @@ static void ucc_geth_set_multi(struct net_device *dev) | |||
2270 | 2275 | ||
2271 | static void ucc_geth_stop(struct ucc_geth_private *ugeth) | 2276 | static void ucc_geth_stop(struct ucc_geth_private *ugeth) |
2272 | { | 2277 | { |
2273 | struct ucc_geth *ug_regs = ugeth->ug_regs; | 2278 | struct ucc_geth __iomem *ug_regs = ugeth->ug_regs; |
2274 | struct phy_device *phydev = ugeth->phydev; | 2279 | struct phy_device *phydev = ugeth->phydev; |
2275 | u32 tempval; | 2280 | u32 tempval; |
2276 | 2281 | ||
@@ -2419,20 +2424,20 @@ static int ucc_struct_init(struct ucc_geth_private *ugeth) | |||
2419 | return -ENOMEM; | 2424 | return -ENOMEM; |
2420 | } | 2425 | } |
2421 | 2426 | ||
2422 | ugeth->ug_regs = (struct ucc_geth *) ioremap(uf_info->regs, sizeof(struct ucc_geth)); | 2427 | ugeth->ug_regs = (struct ucc_geth __iomem *) ioremap(uf_info->regs, sizeof(struct ucc_geth)); |
2423 | 2428 | ||
2424 | return 0; | 2429 | return 0; |
2425 | } | 2430 | } |
2426 | 2431 | ||
2427 | static int ucc_geth_startup(struct ucc_geth_private *ugeth) | 2432 | static int ucc_geth_startup(struct ucc_geth_private *ugeth) |
2428 | { | 2433 | { |
2429 | struct ucc_geth_82xx_address_filtering_pram *p_82xx_addr_filt; | 2434 | struct ucc_geth_82xx_address_filtering_pram __iomem *p_82xx_addr_filt; |
2430 | struct ucc_geth_init_pram *p_init_enet_pram; | 2435 | struct ucc_geth_init_pram __iomem *p_init_enet_pram; |
2431 | struct ucc_fast_private *uccf; | 2436 | struct ucc_fast_private *uccf; |
2432 | struct ucc_geth_info *ug_info; | 2437 | struct ucc_geth_info *ug_info; |
2433 | struct ucc_fast_info *uf_info; | 2438 | struct ucc_fast_info *uf_info; |
2434 | struct ucc_fast *uf_regs; | 2439 | struct ucc_fast __iomem *uf_regs; |
2435 | struct ucc_geth *ug_regs; | 2440 | struct ucc_geth __iomem *ug_regs; |
2436 | int ret_val = -EINVAL; | 2441 | int ret_val = -EINVAL; |
2437 | u32 remoder = UCC_GETH_REMODER_INIT; | 2442 | u32 remoder = UCC_GETH_REMODER_INIT; |
2438 | u32 init_enet_pram_offset, cecr_subblock, command, maccfg1; | 2443 | u32 init_enet_pram_offset, cecr_subblock, command, maccfg1; |
@@ -2440,7 +2445,8 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth) | |||
2440 | u16 temoder = UCC_GETH_TEMODER_INIT; | 2445 | u16 temoder = UCC_GETH_TEMODER_INIT; |
2441 | u16 test; | 2446 | u16 test; |
2442 | u8 function_code = 0; | 2447 | u8 function_code = 0; |
2443 | u8 *bd, *endOfRing; | 2448 | u8 __iomem *bd; |
2449 | u8 __iomem *endOfRing; | ||
2444 | u8 numThreadsRxNumerical, numThreadsTxNumerical; | 2450 | u8 numThreadsRxNumerical, numThreadsTxNumerical; |
2445 | 2451 | ||
2446 | ugeth_vdbg("%s: IN", __FUNCTION__); | 2452 | ugeth_vdbg("%s: IN", __FUNCTION__); |
@@ -2602,11 +2608,11 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth) | |||
2602 | if (UCC_GETH_TX_BD_RING_ALIGNMENT > 4) | 2608 | if (UCC_GETH_TX_BD_RING_ALIGNMENT > 4) |
2603 | align = UCC_GETH_TX_BD_RING_ALIGNMENT; | 2609 | align = UCC_GETH_TX_BD_RING_ALIGNMENT; |
2604 | ugeth->tx_bd_ring_offset[j] = | 2610 | ugeth->tx_bd_ring_offset[j] = |
2605 | kmalloc((u32) (length + align), GFP_KERNEL); | 2611 | (u32) kmalloc((u32) (length + align), GFP_KERNEL); |
2606 | 2612 | ||
2607 | if (ugeth->tx_bd_ring_offset[j] != 0) | 2613 | if (ugeth->tx_bd_ring_offset[j] != 0) |
2608 | ugeth->p_tx_bd_ring[j] = | 2614 | ugeth->p_tx_bd_ring[j] = |
2609 | (void*)((ugeth->tx_bd_ring_offset[j] + | 2615 | (u8 __iomem *)((ugeth->tx_bd_ring_offset[j] + |
2610 | align) & ~(align - 1)); | 2616 | align) & ~(align - 1)); |
2611 | } else if (uf_info->bd_mem_part == MEM_PART_MURAM) { | 2617 | } else if (uf_info->bd_mem_part == MEM_PART_MURAM) { |
2612 | ugeth->tx_bd_ring_offset[j] = | 2618 | ugeth->tx_bd_ring_offset[j] = |
@@ -2614,7 +2620,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth) | |||
2614 | UCC_GETH_TX_BD_RING_ALIGNMENT); | 2620 | UCC_GETH_TX_BD_RING_ALIGNMENT); |
2615 | if (!IS_ERR_VALUE(ugeth->tx_bd_ring_offset[j])) | 2621 | if (!IS_ERR_VALUE(ugeth->tx_bd_ring_offset[j])) |
2616 | ugeth->p_tx_bd_ring[j] = | 2622 | ugeth->p_tx_bd_ring[j] = |
2617 | (u8 *) qe_muram_addr(ugeth-> | 2623 | (u8 __iomem *) qe_muram_addr(ugeth-> |
2618 | tx_bd_ring_offset[j]); | 2624 | tx_bd_ring_offset[j]); |
2619 | } | 2625 | } |
2620 | if (!ugeth->p_tx_bd_ring[j]) { | 2626 | if (!ugeth->p_tx_bd_ring[j]) { |
@@ -2626,8 +2632,8 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth) | |||
2626 | return -ENOMEM; | 2632 | return -ENOMEM; |
2627 | } | 2633 | } |
2628 | /* Zero unused end of bd ring, according to spec */ | 2634 | /* Zero unused end of bd ring, according to spec */ |
2629 | memset(ugeth->p_tx_bd_ring[j] + | 2635 | memset_io((void __iomem *)(ugeth->p_tx_bd_ring[j] + |
2630 | ug_info->bdRingLenTx[j] * sizeof(struct qe_bd), 0, | 2636 | ug_info->bdRingLenTx[j] * sizeof(struct qe_bd)), 0, |
2631 | length - ug_info->bdRingLenTx[j] * sizeof(struct qe_bd)); | 2637 | length - ug_info->bdRingLenTx[j] * sizeof(struct qe_bd)); |
2632 | } | 2638 | } |
2633 | 2639 | ||
@@ -2639,10 +2645,10 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth) | |||
2639 | if (UCC_GETH_RX_BD_RING_ALIGNMENT > 4) | 2645 | if (UCC_GETH_RX_BD_RING_ALIGNMENT > 4) |
2640 | align = UCC_GETH_RX_BD_RING_ALIGNMENT; | 2646 | align = UCC_GETH_RX_BD_RING_ALIGNMENT; |
2641 | ugeth->rx_bd_ring_offset[j] = | 2647 | ugeth->rx_bd_ring_offset[j] = |
2642 | kmalloc((u32) (length + align), GFP_KERNEL); | 2648 | (u32) kmalloc((u32) (length + align), GFP_KERNEL); |
2643 | if (ugeth->rx_bd_ring_offset[j] != 0) | 2649 | if (ugeth->rx_bd_ring_offset[j] != 0) |
2644 | ugeth->p_rx_bd_ring[j] = | 2650 | ugeth->p_rx_bd_ring[j] = |
2645 | (void*)((ugeth->rx_bd_ring_offset[j] + | 2651 | (u8 __iomem *)((ugeth->rx_bd_ring_offset[j] + |
2646 | align) & ~(align - 1)); | 2652 | align) & ~(align - 1)); |
2647 | } else if (uf_info->bd_mem_part == MEM_PART_MURAM) { | 2653 | } else if (uf_info->bd_mem_part == MEM_PART_MURAM) { |
2648 | ugeth->rx_bd_ring_offset[j] = | 2654 | ugeth->rx_bd_ring_offset[j] = |
@@ -2650,7 +2656,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth) | |||
2650 | UCC_GETH_RX_BD_RING_ALIGNMENT); | 2656 | UCC_GETH_RX_BD_RING_ALIGNMENT); |
2651 | if (!IS_ERR_VALUE(ugeth->rx_bd_ring_offset[j])) | 2657 | if (!IS_ERR_VALUE(ugeth->rx_bd_ring_offset[j])) |
2652 | ugeth->p_rx_bd_ring[j] = | 2658 | ugeth->p_rx_bd_ring[j] = |
2653 | (u8 *) qe_muram_addr(ugeth-> | 2659 | (u8 __iomem *) qe_muram_addr(ugeth-> |
2654 | rx_bd_ring_offset[j]); | 2660 | rx_bd_ring_offset[j]); |
2655 | } | 2661 | } |
2656 | if (!ugeth->p_rx_bd_ring[j]) { | 2662 | if (!ugeth->p_rx_bd_ring[j]) { |
@@ -2685,14 +2691,14 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth) | |||
2685 | bd = ugeth->confBd[j] = ugeth->txBd[j] = ugeth->p_tx_bd_ring[j]; | 2691 | bd = ugeth->confBd[j] = ugeth->txBd[j] = ugeth->p_tx_bd_ring[j]; |
2686 | for (i = 0; i < ug_info->bdRingLenTx[j]; i++) { | 2692 | for (i = 0; i < ug_info->bdRingLenTx[j]; i++) { |
2687 | /* clear bd buffer */ | 2693 | /* clear bd buffer */ |
2688 | out_be32(&((struct qe_bd *)bd)->buf, 0); | 2694 | out_be32(&((struct qe_bd __iomem *)bd)->buf, 0); |
2689 | /* set bd status and length */ | 2695 | /* set bd status and length */ |
2690 | out_be32((u32 *)bd, 0); | 2696 | out_be32((u32 __iomem *)bd, 0); |
2691 | bd += sizeof(struct qe_bd); | 2697 | bd += sizeof(struct qe_bd); |
2692 | } | 2698 | } |
2693 | bd -= sizeof(struct qe_bd); | 2699 | bd -= sizeof(struct qe_bd); |
2694 | /* set bd status and length */ | 2700 | /* set bd status and length */ |
2695 | out_be32((u32 *)bd, T_W); /* for last BD set Wrap bit */ | 2701 | out_be32((u32 __iomem *)bd, T_W); /* for last BD set Wrap bit */ |
2696 | } | 2702 | } |
2697 | 2703 | ||
2698 | /* Init Rx bds */ | 2704 | /* Init Rx bds */ |
@@ -2717,14 +2723,14 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth) | |||
2717 | bd = ugeth->rxBd[j] = ugeth->p_rx_bd_ring[j]; | 2723 | bd = ugeth->rxBd[j] = ugeth->p_rx_bd_ring[j]; |
2718 | for (i = 0; i < ug_info->bdRingLenRx[j]; i++) { | 2724 | for (i = 0; i < ug_info->bdRingLenRx[j]; i++) { |
2719 | /* set bd status and length */ | 2725 | /* set bd status and length */ |
2720 | out_be32((u32 *)bd, R_I); | 2726 | out_be32((u32 __iomem *)bd, R_I); |
2721 | /* clear bd buffer */ | 2727 | /* clear bd buffer */ |
2722 | out_be32(&((struct qe_bd *)bd)->buf, 0); | 2728 | out_be32(&((struct qe_bd __iomem *)bd)->buf, 0); |
2723 | bd += sizeof(struct qe_bd); | 2729 | bd += sizeof(struct qe_bd); |
2724 | } | 2730 | } |
2725 | bd -= sizeof(struct qe_bd); | 2731 | bd -= sizeof(struct qe_bd); |
2726 | /* set bd status and length */ | 2732 | /* set bd status and length */ |
2727 | out_be32((u32 *)bd, R_W); /* for last BD set Wrap bit */ | 2733 | out_be32((u32 __iomem *)bd, R_W); /* for last BD set Wrap bit */ |
2728 | } | 2734 | } |
2729 | 2735 | ||
2730 | /* | 2736 | /* |
@@ -2744,10 +2750,10 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth) | |||
2744 | return -ENOMEM; | 2750 | return -ENOMEM; |
2745 | } | 2751 | } |
2746 | ugeth->p_tx_glbl_pram = | 2752 | ugeth->p_tx_glbl_pram = |
2747 | (struct ucc_geth_tx_global_pram *) qe_muram_addr(ugeth-> | 2753 | (struct ucc_geth_tx_global_pram __iomem *) qe_muram_addr(ugeth-> |
2748 | tx_glbl_pram_offset); | 2754 | tx_glbl_pram_offset); |
2749 | /* Zero out p_tx_glbl_pram */ | 2755 | /* Zero out p_tx_glbl_pram */ |
2750 | memset(ugeth->p_tx_glbl_pram, 0, sizeof(struct ucc_geth_tx_global_pram)); | 2756 | memset_io((void __iomem *)ugeth->p_tx_glbl_pram, 0, sizeof(struct ucc_geth_tx_global_pram)); |
2751 | 2757 | ||
2752 | /* Fill global PRAM */ | 2758 | /* Fill global PRAM */ |
2753 | 2759 | ||
@@ -2768,7 +2774,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth) | |||
2768 | } | 2774 | } |
2769 | 2775 | ||
2770 | ugeth->p_thread_data_tx = | 2776 | ugeth->p_thread_data_tx = |
2771 | (struct ucc_geth_thread_data_tx *) qe_muram_addr(ugeth-> | 2777 | (struct ucc_geth_thread_data_tx __iomem *) qe_muram_addr(ugeth-> |
2772 | thread_dat_tx_offset); | 2778 | thread_dat_tx_offset); |
2773 | out_be32(&ugeth->p_tx_glbl_pram->tqptr, ugeth->thread_dat_tx_offset); | 2779 | out_be32(&ugeth->p_tx_glbl_pram->tqptr, ugeth->thread_dat_tx_offset); |
2774 | 2780 | ||
@@ -2779,7 +2785,8 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth) | |||
2779 | 2785 | ||
2780 | /* iphoffset */ | 2786 | /* iphoffset */ |
2781 | for (i = 0; i < TX_IP_OFFSET_ENTRY_MAX; i++) | 2787 | for (i = 0; i < TX_IP_OFFSET_ENTRY_MAX; i++) |
2782 | ugeth->p_tx_glbl_pram->iphoffset[i] = ug_info->iphoffset[i]; | 2788 | out_8(&ugeth->p_tx_glbl_pram->iphoffset[i], |
2789 | ug_info->iphoffset[i]); | ||
2783 | 2790 | ||
2784 | /* SQPTR */ | 2791 | /* SQPTR */ |
2785 | /* Size varies with number of Tx queues */ | 2792 | /* Size varies with number of Tx queues */ |
@@ -2797,7 +2804,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth) | |||
2797 | } | 2804 | } |
2798 | 2805 | ||
2799 | ugeth->p_send_q_mem_reg = | 2806 | ugeth->p_send_q_mem_reg = |
2800 | (struct ucc_geth_send_queue_mem_region *) qe_muram_addr(ugeth-> | 2807 | (struct ucc_geth_send_queue_mem_region __iomem *) qe_muram_addr(ugeth-> |
2801 | send_q_mem_reg_offset); | 2808 | send_q_mem_reg_offset); |
2802 | out_be32(&ugeth->p_tx_glbl_pram->sqptr, ugeth->send_q_mem_reg_offset); | 2809 | out_be32(&ugeth->p_tx_glbl_pram->sqptr, ugeth->send_q_mem_reg_offset); |
2803 | 2810 | ||
@@ -2841,25 +2848,26 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth) | |||
2841 | } | 2848 | } |
2842 | 2849 | ||
2843 | ugeth->p_scheduler = | 2850 | ugeth->p_scheduler = |
2844 | (struct ucc_geth_scheduler *) qe_muram_addr(ugeth-> | 2851 | (struct ucc_geth_scheduler __iomem *) qe_muram_addr(ugeth-> |
2845 | scheduler_offset); | 2852 | scheduler_offset); |
2846 | out_be32(&ugeth->p_tx_glbl_pram->schedulerbasepointer, | 2853 | out_be32(&ugeth->p_tx_glbl_pram->schedulerbasepointer, |
2847 | ugeth->scheduler_offset); | 2854 | ugeth->scheduler_offset); |
2848 | /* Zero out p_scheduler */ | 2855 | /* Zero out p_scheduler */ |
2849 | memset(ugeth->p_scheduler, 0, sizeof(struct ucc_geth_scheduler)); | 2856 | memset_io((void __iomem *)ugeth->p_scheduler, 0, sizeof(struct ucc_geth_scheduler)); |
2850 | 2857 | ||
2851 | /* Set values in scheduler */ | 2858 | /* Set values in scheduler */ |
2852 | out_be32(&ugeth->p_scheduler->mblinterval, | 2859 | out_be32(&ugeth->p_scheduler->mblinterval, |
2853 | ug_info->mblinterval); | 2860 | ug_info->mblinterval); |
2854 | out_be16(&ugeth->p_scheduler->nortsrbytetime, | 2861 | out_be16(&ugeth->p_scheduler->nortsrbytetime, |
2855 | ug_info->nortsrbytetime); | 2862 | ug_info->nortsrbytetime); |
2856 | ugeth->p_scheduler->fracsiz = ug_info->fracsiz; | 2863 | out_8(&ugeth->p_scheduler->fracsiz, ug_info->fracsiz); |
2857 | ugeth->p_scheduler->strictpriorityq = ug_info->strictpriorityq; | 2864 | out_8(&ugeth->p_scheduler->strictpriorityq, |
2858 | ugeth->p_scheduler->txasap = ug_info->txasap; | 2865 | ug_info->strictpriorityq); |
2859 | ugeth->p_scheduler->extrabw = ug_info->extrabw; | 2866 | out_8(&ugeth->p_scheduler->txasap, ug_info->txasap); |
2867 | out_8(&ugeth->p_scheduler->extrabw, ug_info->extrabw); | ||
2860 | for (i = 0; i < NUM_TX_QUEUES; i++) | 2868 | for (i = 0; i < NUM_TX_QUEUES; i++) |
2861 | ugeth->p_scheduler->weightfactor[i] = | 2869 | out_8(&ugeth->p_scheduler->weightfactor[i], |
2862 | ug_info->weightfactor[i]; | 2870 | ug_info->weightfactor[i]); |
2863 | 2871 | ||
2864 | /* Set pointers to cpucount registers in scheduler */ | 2872 | /* Set pointers to cpucount registers in scheduler */ |
2865 | ugeth->p_cpucount[0] = &(ugeth->p_scheduler->cpucount0); | 2873 | ugeth->p_cpucount[0] = &(ugeth->p_scheduler->cpucount0); |
@@ -2890,10 +2898,10 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth) | |||
2890 | return -ENOMEM; | 2898 | return -ENOMEM; |
2891 | } | 2899 | } |
2892 | ugeth->p_tx_fw_statistics_pram = | 2900 | ugeth->p_tx_fw_statistics_pram = |
2893 | (struct ucc_geth_tx_firmware_statistics_pram *) | 2901 | (struct ucc_geth_tx_firmware_statistics_pram __iomem *) |
2894 | qe_muram_addr(ugeth->tx_fw_statistics_pram_offset); | 2902 | qe_muram_addr(ugeth->tx_fw_statistics_pram_offset); |
2895 | /* Zero out p_tx_fw_statistics_pram */ | 2903 | /* Zero out p_tx_fw_statistics_pram */ |
2896 | memset(ugeth->p_tx_fw_statistics_pram, | 2904 | memset_io((void __iomem *)ugeth->p_tx_fw_statistics_pram, |
2897 | 0, sizeof(struct ucc_geth_tx_firmware_statistics_pram)); | 2905 | 0, sizeof(struct ucc_geth_tx_firmware_statistics_pram)); |
2898 | } | 2906 | } |
2899 | 2907 | ||
@@ -2930,10 +2938,10 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth) | |||
2930 | return -ENOMEM; | 2938 | return -ENOMEM; |
2931 | } | 2939 | } |
2932 | ugeth->p_rx_glbl_pram = | 2940 | ugeth->p_rx_glbl_pram = |
2933 | (struct ucc_geth_rx_global_pram *) qe_muram_addr(ugeth-> | 2941 | (struct ucc_geth_rx_global_pram __iomem *) qe_muram_addr(ugeth-> |
2934 | rx_glbl_pram_offset); | 2942 | rx_glbl_pram_offset); |
2935 | /* Zero out p_rx_glbl_pram */ | 2943 | /* Zero out p_rx_glbl_pram */ |
2936 | memset(ugeth->p_rx_glbl_pram, 0, sizeof(struct ucc_geth_rx_global_pram)); | 2944 | memset_io((void __iomem *)ugeth->p_rx_glbl_pram, 0, sizeof(struct ucc_geth_rx_global_pram)); |
2937 | 2945 | ||
2938 | /* Fill global PRAM */ | 2946 | /* Fill global PRAM */ |
2939 | 2947 | ||
@@ -2953,7 +2961,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth) | |||
2953 | } | 2961 | } |
2954 | 2962 | ||
2955 | ugeth->p_thread_data_rx = | 2963 | ugeth->p_thread_data_rx = |
2956 | (struct ucc_geth_thread_data_rx *) qe_muram_addr(ugeth-> | 2964 | (struct ucc_geth_thread_data_rx __iomem *) qe_muram_addr(ugeth-> |
2957 | thread_dat_rx_offset); | 2965 | thread_dat_rx_offset); |
2958 | out_be32(&ugeth->p_rx_glbl_pram->rqptr, ugeth->thread_dat_rx_offset); | 2966 | out_be32(&ugeth->p_rx_glbl_pram->rqptr, ugeth->thread_dat_rx_offset); |
2959 | 2967 | ||
@@ -2976,10 +2984,10 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth) | |||
2976 | return -ENOMEM; | 2984 | return -ENOMEM; |
2977 | } | 2985 | } |
2978 | ugeth->p_rx_fw_statistics_pram = | 2986 | ugeth->p_rx_fw_statistics_pram = |
2979 | (struct ucc_geth_rx_firmware_statistics_pram *) | 2987 | (struct ucc_geth_rx_firmware_statistics_pram __iomem *) |
2980 | qe_muram_addr(ugeth->rx_fw_statistics_pram_offset); | 2988 | qe_muram_addr(ugeth->rx_fw_statistics_pram_offset); |
2981 | /* Zero out p_rx_fw_statistics_pram */ | 2989 | /* Zero out p_rx_fw_statistics_pram */ |
2982 | memset(ugeth->p_rx_fw_statistics_pram, 0, | 2990 | memset_io((void __iomem *)ugeth->p_rx_fw_statistics_pram, 0, |
2983 | sizeof(struct ucc_geth_rx_firmware_statistics_pram)); | 2991 | sizeof(struct ucc_geth_rx_firmware_statistics_pram)); |
2984 | } | 2992 | } |
2985 | 2993 | ||
@@ -3000,7 +3008,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth) | |||
3000 | } | 3008 | } |
3001 | 3009 | ||
3002 | ugeth->p_rx_irq_coalescing_tbl = | 3010 | ugeth->p_rx_irq_coalescing_tbl = |
3003 | (struct ucc_geth_rx_interrupt_coalescing_table *) | 3011 | (struct ucc_geth_rx_interrupt_coalescing_table __iomem *) |
3004 | qe_muram_addr(ugeth->rx_irq_coalescing_tbl_offset); | 3012 | qe_muram_addr(ugeth->rx_irq_coalescing_tbl_offset); |
3005 | out_be32(&ugeth->p_rx_glbl_pram->intcoalescingptr, | 3013 | out_be32(&ugeth->p_rx_glbl_pram->intcoalescingptr, |
3006 | ugeth->rx_irq_coalescing_tbl_offset); | 3014 | ugeth->rx_irq_coalescing_tbl_offset); |
@@ -3069,11 +3077,11 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth) | |||
3069 | } | 3077 | } |
3070 | 3078 | ||
3071 | ugeth->p_rx_bd_qs_tbl = | 3079 | ugeth->p_rx_bd_qs_tbl = |
3072 | (struct ucc_geth_rx_bd_queues_entry *) qe_muram_addr(ugeth-> | 3080 | (struct ucc_geth_rx_bd_queues_entry __iomem *) qe_muram_addr(ugeth-> |
3073 | rx_bd_qs_tbl_offset); | 3081 | rx_bd_qs_tbl_offset); |
3074 | out_be32(&ugeth->p_rx_glbl_pram->rbdqptr, ugeth->rx_bd_qs_tbl_offset); | 3082 | out_be32(&ugeth->p_rx_glbl_pram->rbdqptr, ugeth->rx_bd_qs_tbl_offset); |
3075 | /* Zero out p_rx_bd_qs_tbl */ | 3083 | /* Zero out p_rx_bd_qs_tbl */ |
3076 | memset(ugeth->p_rx_bd_qs_tbl, | 3084 | memset_io((void __iomem *)ugeth->p_rx_bd_qs_tbl, |
3077 | 0, | 3085 | 0, |
3078 | ug_info->numQueuesRx * (sizeof(struct ucc_geth_rx_bd_queues_entry) + | 3086 | ug_info->numQueuesRx * (sizeof(struct ucc_geth_rx_bd_queues_entry) + |
3079 | sizeof(struct ucc_geth_rx_prefetched_bds))); | 3087 | sizeof(struct ucc_geth_rx_prefetched_bds))); |
@@ -3133,7 +3141,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth) | |||
3133 | &ugeth->p_rx_glbl_pram->remoder); | 3141 | &ugeth->p_rx_glbl_pram->remoder); |
3134 | 3142 | ||
3135 | /* function code register */ | 3143 | /* function code register */ |
3136 | ugeth->p_rx_glbl_pram->rstate = function_code; | 3144 | out_8(&ugeth->p_rx_glbl_pram->rstate, function_code); |
3137 | 3145 | ||
3138 | /* initialize extended filtering */ | 3146 | /* initialize extended filtering */ |
3139 | if (ug_info->rxExtendedFiltering) { | 3147 | if (ug_info->rxExtendedFiltering) { |
@@ -3160,7 +3168,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth) | |||
3160 | } | 3168 | } |
3161 | 3169 | ||
3162 | ugeth->p_exf_glbl_param = | 3170 | ugeth->p_exf_glbl_param = |
3163 | (struct ucc_geth_exf_global_pram *) qe_muram_addr(ugeth-> | 3171 | (struct ucc_geth_exf_global_pram __iomem *) qe_muram_addr(ugeth-> |
3164 | exf_glbl_param_offset); | 3172 | exf_glbl_param_offset); |
3165 | out_be32(&ugeth->p_rx_glbl_pram->exfGlobalParam, | 3173 | out_be32(&ugeth->p_rx_glbl_pram->exfGlobalParam, |
3166 | ugeth->exf_glbl_param_offset); | 3174 | ugeth->exf_glbl_param_offset); |
@@ -3175,7 +3183,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth) | |||
3175 | ugeth_82xx_filtering_clear_addr_in_paddr(ugeth, (u8) j); | 3183 | ugeth_82xx_filtering_clear_addr_in_paddr(ugeth, (u8) j); |
3176 | 3184 | ||
3177 | p_82xx_addr_filt = | 3185 | p_82xx_addr_filt = |
3178 | (struct ucc_geth_82xx_address_filtering_pram *) ugeth-> | 3186 | (struct ucc_geth_82xx_address_filtering_pram __iomem *) ugeth-> |
3179 | p_rx_glbl_pram->addressfiltering; | 3187 | p_rx_glbl_pram->addressfiltering; |
3180 | 3188 | ||
3181 | ugeth_82xx_filtering_clear_all_addr_in_hash(ugeth, | 3189 | ugeth_82xx_filtering_clear_all_addr_in_hash(ugeth, |
@@ -3307,17 +3315,21 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth) | |||
3307 | return -ENOMEM; | 3315 | return -ENOMEM; |
3308 | } | 3316 | } |
3309 | p_init_enet_pram = | 3317 | p_init_enet_pram = |
3310 | (struct ucc_geth_init_pram *) qe_muram_addr(init_enet_pram_offset); | 3318 | (struct ucc_geth_init_pram __iomem *) qe_muram_addr(init_enet_pram_offset); |
3311 | 3319 | ||
3312 | /* Copy shadow InitEnet command parameter structure into PRAM */ | 3320 | /* Copy shadow InitEnet command parameter structure into PRAM */ |
3313 | p_init_enet_pram->resinit1 = ugeth->p_init_enet_param_shadow->resinit1; | 3321 | out_8(&p_init_enet_pram->resinit1, |
3314 | p_init_enet_pram->resinit2 = ugeth->p_init_enet_param_shadow->resinit2; | 3322 | ugeth->p_init_enet_param_shadow->resinit1); |
3315 | p_init_enet_pram->resinit3 = ugeth->p_init_enet_param_shadow->resinit3; | 3323 | out_8(&p_init_enet_pram->resinit2, |
3316 | p_init_enet_pram->resinit4 = ugeth->p_init_enet_param_shadow->resinit4; | 3324 | ugeth->p_init_enet_param_shadow->resinit2); |
3325 | out_8(&p_init_enet_pram->resinit3, | ||
3326 | ugeth->p_init_enet_param_shadow->resinit3); | ||
3327 | out_8(&p_init_enet_pram->resinit4, | ||
3328 | ugeth->p_init_enet_param_shadow->resinit4); | ||
3317 | out_be16(&p_init_enet_pram->resinit5, | 3329 | out_be16(&p_init_enet_pram->resinit5, |
3318 | ugeth->p_init_enet_param_shadow->resinit5); | 3330 | ugeth->p_init_enet_param_shadow->resinit5); |
3319 | p_init_enet_pram->largestexternallookupkeysize = | 3331 | out_8(&p_init_enet_pram->largestexternallookupkeysize, |
3320 | ugeth->p_init_enet_param_shadow->largestexternallookupkeysize; | 3332 | ugeth->p_init_enet_param_shadow->largestexternallookupkeysize); |
3321 | out_be32(&p_init_enet_pram->rgftgfrxglobal, | 3333 | out_be32(&p_init_enet_pram->rgftgfrxglobal, |
3322 | ugeth->p_init_enet_param_shadow->rgftgfrxglobal); | 3334 | ugeth->p_init_enet_param_shadow->rgftgfrxglobal); |
3323 | for (i = 0; i < ENET_INIT_PARAM_MAX_ENTRIES_RX; i++) | 3335 | for (i = 0; i < ENET_INIT_PARAM_MAX_ENTRIES_RX; i++) |
@@ -3371,7 +3383,7 @@ static int ucc_geth_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
3371 | #ifdef CONFIG_UGETH_TX_ON_DEMAND | 3383 | #ifdef CONFIG_UGETH_TX_ON_DEMAND |
3372 | struct ucc_fast_private *uccf; | 3384 | struct ucc_fast_private *uccf; |
3373 | #endif | 3385 | #endif |
3374 | u8 *bd; /* BD pointer */ | 3386 | u8 __iomem *bd; /* BD pointer */ |
3375 | u32 bd_status; | 3387 | u32 bd_status; |
3376 | u8 txQ = 0; | 3388 | u8 txQ = 0; |
3377 | 3389 | ||
@@ -3383,7 +3395,7 @@ static int ucc_geth_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
3383 | 3395 | ||
3384 | /* Start from the next BD that should be filled */ | 3396 | /* Start from the next BD that should be filled */ |
3385 | bd = ugeth->txBd[txQ]; | 3397 | bd = ugeth->txBd[txQ]; |
3386 | bd_status = in_be32((u32 *)bd); | 3398 | bd_status = in_be32((u32 __iomem *)bd); |
3387 | /* Save the skb pointer so we can free it later */ | 3399 | /* Save the skb pointer so we can free it later */ |
3388 | ugeth->tx_skbuff[txQ][ugeth->skb_curtx[txQ]] = skb; | 3400 | ugeth->tx_skbuff[txQ][ugeth->skb_curtx[txQ]] = skb; |
3389 | 3401 | ||
@@ -3393,15 +3405,16 @@ static int ucc_geth_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
3393 | 1) & TX_RING_MOD_MASK(ugeth->ug_info->bdRingLenTx[txQ]); | 3405 | 1) & TX_RING_MOD_MASK(ugeth->ug_info->bdRingLenTx[txQ]); |
3394 | 3406 | ||
3395 | /* set up the buffer descriptor */ | 3407 | /* set up the buffer descriptor */ |
3396 | out_be32(&((struct qe_bd *)bd)->buf, | 3408 | out_be32(&((struct qe_bd __iomem *)bd)->buf, |
3397 | dma_map_single(NULL, skb->data, skb->len, DMA_TO_DEVICE)); | 3409 | dma_map_single(&ugeth->dev->dev, skb->data, |
3410 | skb->len, DMA_TO_DEVICE)); | ||
3398 | 3411 | ||
3399 | /* printk(KERN_DEBUG"skb->data is 0x%x\n",skb->data); */ | 3412 | /* printk(KERN_DEBUG"skb->data is 0x%x\n",skb->data); */ |
3400 | 3413 | ||
3401 | bd_status = (bd_status & T_W) | T_R | T_I | T_L | skb->len; | 3414 | bd_status = (bd_status & T_W) | T_R | T_I | T_L | skb->len; |
3402 | 3415 | ||
3403 | /* set bd status and length */ | 3416 | /* set bd status and length */ |
3404 | out_be32((u32 *)bd, bd_status); | 3417 | out_be32((u32 __iomem *)bd, bd_status); |
3405 | 3418 | ||
3406 | dev->trans_start = jiffies; | 3419 | dev->trans_start = jiffies; |
3407 | 3420 | ||
@@ -3441,7 +3454,7 @@ static int ucc_geth_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
3441 | static int ucc_geth_rx(struct ucc_geth_private *ugeth, u8 rxQ, int rx_work_limit) | 3454 | static int ucc_geth_rx(struct ucc_geth_private *ugeth, u8 rxQ, int rx_work_limit) |
3442 | { | 3455 | { |
3443 | struct sk_buff *skb; | 3456 | struct sk_buff *skb; |
3444 | u8 *bd; | 3457 | u8 __iomem *bd; |
3445 | u16 length, howmany = 0; | 3458 | u16 length, howmany = 0; |
3446 | u32 bd_status; | 3459 | u32 bd_status; |
3447 | u8 *bdBuffer; | 3460 | u8 *bdBuffer; |
@@ -3454,11 +3467,11 @@ static int ucc_geth_rx(struct ucc_geth_private *ugeth, u8 rxQ, int rx_work_limit | |||
3454 | /* collect received buffers */ | 3467 | /* collect received buffers */ |
3455 | bd = ugeth->rxBd[rxQ]; | 3468 | bd = ugeth->rxBd[rxQ]; |
3456 | 3469 | ||
3457 | bd_status = in_be32((u32 *)bd); | 3470 | bd_status = in_be32((u32 __iomem *)bd); |
3458 | 3471 | ||
3459 | /* while there are received buffers and BD is full (~R_E) */ | 3472 | /* while there are received buffers and BD is full (~R_E) */ |
3460 | while (!((bd_status & (R_E)) || (--rx_work_limit < 0))) { | 3473 | while (!((bd_status & (R_E)) || (--rx_work_limit < 0))) { |
3461 | bdBuffer = (u8 *) in_be32(&((struct qe_bd *)bd)->buf); | 3474 | bdBuffer = (u8 *) in_be32(&((struct qe_bd __iomem *)bd)->buf); |
3462 | length = (u16) ((bd_status & BD_LENGTH_MASK) - 4); | 3475 | length = (u16) ((bd_status & BD_LENGTH_MASK) - 4); |
3463 | skb = ugeth->rx_skbuff[rxQ][ugeth->skb_currx[rxQ]]; | 3476 | skb = ugeth->rx_skbuff[rxQ][ugeth->skb_currx[rxQ]]; |
3464 | 3477 | ||
@@ -3516,7 +3529,7 @@ static int ucc_geth_rx(struct ucc_geth_private *ugeth, u8 rxQ, int rx_work_limit | |||
3516 | else | 3529 | else |
3517 | bd += sizeof(struct qe_bd); | 3530 | bd += sizeof(struct qe_bd); |
3518 | 3531 | ||
3519 | bd_status = in_be32((u32 *)bd); | 3532 | bd_status = in_be32((u32 __iomem *)bd); |
3520 | } | 3533 | } |
3521 | 3534 | ||
3522 | ugeth->rxBd[rxQ] = bd; | 3535 | ugeth->rxBd[rxQ] = bd; |
@@ -3527,11 +3540,11 @@ static int ucc_geth_tx(struct net_device *dev, u8 txQ) | |||
3527 | { | 3540 | { |
3528 | /* Start from the next BD that should be filled */ | 3541 | /* Start from the next BD that should be filled */ |
3529 | struct ucc_geth_private *ugeth = netdev_priv(dev); | 3542 | struct ucc_geth_private *ugeth = netdev_priv(dev); |
3530 | u8 *bd; /* BD pointer */ | 3543 | u8 __iomem *bd; /* BD pointer */ |
3531 | u32 bd_status; | 3544 | u32 bd_status; |
3532 | 3545 | ||
3533 | bd = ugeth->confBd[txQ]; | 3546 | bd = ugeth->confBd[txQ]; |
3534 | bd_status = in_be32((u32 *)bd); | 3547 | bd_status = in_be32((u32 __iomem *)bd); |
3535 | 3548 | ||
3536 | /* Normal processing. */ | 3549 | /* Normal processing. */ |
3537 | while ((bd_status & T_R) == 0) { | 3550 | while ((bd_status & T_R) == 0) { |
@@ -3561,7 +3574,7 @@ static int ucc_geth_tx(struct net_device *dev, u8 txQ) | |||
3561 | bd += sizeof(struct qe_bd); | 3574 | bd += sizeof(struct qe_bd); |
3562 | else | 3575 | else |
3563 | bd = ugeth->p_tx_bd_ring[txQ]; | 3576 | bd = ugeth->p_tx_bd_ring[txQ]; |
3564 | bd_status = in_be32((u32 *)bd); | 3577 | bd_status = in_be32((u32 __iomem *)bd); |
3565 | } | 3578 | } |
3566 | ugeth->confBd[txQ] = bd; | 3579 | ugeth->confBd[txQ] = bd; |
3567 | return 0; | 3580 | return 0; |
@@ -3910,7 +3923,7 @@ static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *ma | |||
3910 | return -EINVAL; | 3923 | return -EINVAL; |
3911 | } | 3924 | } |
3912 | } else { | 3925 | } else { |
3913 | prop = of_get_property(np, "rx-clock", NULL); | 3926 | prop = of_get_property(np, "tx-clock", NULL); |
3914 | if (!prop) { | 3927 | if (!prop) { |
3915 | printk(KERN_ERR | 3928 | printk(KERN_ERR |
3916 | "ucc_geth: mising tx-clock-name property\n"); | 3929 | "ucc_geth: mising tx-clock-name property\n"); |
diff --git a/drivers/net/ucc_geth.h b/drivers/net/ucc_geth.h index 9f8b7580a3a4..abc0e2242634 100644 --- a/drivers/net/ucc_geth.h +++ b/drivers/net/ucc_geth.h | |||
@@ -700,8 +700,8 @@ struct ucc_geth_82xx_address_filtering_pram { | |||
700 | u32 iaddr_l; /* individual address filter, low */ | 700 | u32 iaddr_l; /* individual address filter, low */ |
701 | u32 gaddr_h; /* group address filter, high */ | 701 | u32 gaddr_h; /* group address filter, high */ |
702 | u32 gaddr_l; /* group address filter, low */ | 702 | u32 gaddr_l; /* group address filter, low */ |
703 | struct ucc_geth_82xx_enet_address taddr; | 703 | struct ucc_geth_82xx_enet_address __iomem taddr; |
704 | struct ucc_geth_82xx_enet_address paddr[NUM_OF_PADDRS]; | 704 | struct ucc_geth_82xx_enet_address __iomem paddr[NUM_OF_PADDRS]; |
705 | u8 res0[0x40 - 0x38]; | 705 | u8 res0[0x40 - 0x38]; |
706 | } __attribute__ ((packed)); | 706 | } __attribute__ ((packed)); |
707 | 707 | ||
@@ -1186,40 +1186,40 @@ struct ucc_geth_private { | |||
1186 | struct ucc_fast_private *uccf; | 1186 | struct ucc_fast_private *uccf; |
1187 | struct net_device *dev; | 1187 | struct net_device *dev; |
1188 | struct napi_struct napi; | 1188 | struct napi_struct napi; |
1189 | struct ucc_geth *ug_regs; | 1189 | struct ucc_geth __iomem *ug_regs; |
1190 | struct ucc_geth_init_pram *p_init_enet_param_shadow; | 1190 | struct ucc_geth_init_pram *p_init_enet_param_shadow; |
1191 | struct ucc_geth_exf_global_pram *p_exf_glbl_param; | 1191 | struct ucc_geth_exf_global_pram __iomem *p_exf_glbl_param; |
1192 | u32 exf_glbl_param_offset; | 1192 | u32 exf_glbl_param_offset; |
1193 | struct ucc_geth_rx_global_pram *p_rx_glbl_pram; | 1193 | struct ucc_geth_rx_global_pram __iomem *p_rx_glbl_pram; |
1194 | u32 rx_glbl_pram_offset; | 1194 | u32 rx_glbl_pram_offset; |
1195 | struct ucc_geth_tx_global_pram *p_tx_glbl_pram; | 1195 | struct ucc_geth_tx_global_pram __iomem *p_tx_glbl_pram; |
1196 | u32 tx_glbl_pram_offset; | 1196 | u32 tx_glbl_pram_offset; |
1197 | struct ucc_geth_send_queue_mem_region *p_send_q_mem_reg; | 1197 | struct ucc_geth_send_queue_mem_region __iomem *p_send_q_mem_reg; |
1198 | u32 send_q_mem_reg_offset; | 1198 | u32 send_q_mem_reg_offset; |
1199 | struct ucc_geth_thread_data_tx *p_thread_data_tx; | 1199 | struct ucc_geth_thread_data_tx __iomem *p_thread_data_tx; |
1200 | u32 thread_dat_tx_offset; | 1200 | u32 thread_dat_tx_offset; |
1201 | struct ucc_geth_thread_data_rx *p_thread_data_rx; | 1201 | struct ucc_geth_thread_data_rx __iomem *p_thread_data_rx; |
1202 | u32 thread_dat_rx_offset; | 1202 | u32 thread_dat_rx_offset; |
1203 | struct ucc_geth_scheduler *p_scheduler; | 1203 | struct ucc_geth_scheduler __iomem *p_scheduler; |
1204 | u32 scheduler_offset; | 1204 | u32 scheduler_offset; |
1205 | struct ucc_geth_tx_firmware_statistics_pram *p_tx_fw_statistics_pram; | 1205 | struct ucc_geth_tx_firmware_statistics_pram __iomem *p_tx_fw_statistics_pram; |
1206 | u32 tx_fw_statistics_pram_offset; | 1206 | u32 tx_fw_statistics_pram_offset; |
1207 | struct ucc_geth_rx_firmware_statistics_pram *p_rx_fw_statistics_pram; | 1207 | struct ucc_geth_rx_firmware_statistics_pram __iomem *p_rx_fw_statistics_pram; |
1208 | u32 rx_fw_statistics_pram_offset; | 1208 | u32 rx_fw_statistics_pram_offset; |
1209 | struct ucc_geth_rx_interrupt_coalescing_table *p_rx_irq_coalescing_tbl; | 1209 | struct ucc_geth_rx_interrupt_coalescing_table __iomem *p_rx_irq_coalescing_tbl; |
1210 | u32 rx_irq_coalescing_tbl_offset; | 1210 | u32 rx_irq_coalescing_tbl_offset; |
1211 | struct ucc_geth_rx_bd_queues_entry *p_rx_bd_qs_tbl; | 1211 | struct ucc_geth_rx_bd_queues_entry __iomem *p_rx_bd_qs_tbl; |
1212 | u32 rx_bd_qs_tbl_offset; | 1212 | u32 rx_bd_qs_tbl_offset; |
1213 | u8 *p_tx_bd_ring[NUM_TX_QUEUES]; | 1213 | u8 __iomem *p_tx_bd_ring[NUM_TX_QUEUES]; |
1214 | u32 tx_bd_ring_offset[NUM_TX_QUEUES]; | 1214 | u32 tx_bd_ring_offset[NUM_TX_QUEUES]; |
1215 | u8 *p_rx_bd_ring[NUM_RX_QUEUES]; | 1215 | u8 __iomem *p_rx_bd_ring[NUM_RX_QUEUES]; |
1216 | u32 rx_bd_ring_offset[NUM_RX_QUEUES]; | 1216 | u32 rx_bd_ring_offset[NUM_RX_QUEUES]; |
1217 | u8 *confBd[NUM_TX_QUEUES]; | 1217 | u8 __iomem *confBd[NUM_TX_QUEUES]; |
1218 | u8 *txBd[NUM_TX_QUEUES]; | 1218 | u8 __iomem *txBd[NUM_TX_QUEUES]; |
1219 | u8 *rxBd[NUM_RX_QUEUES]; | 1219 | u8 __iomem *rxBd[NUM_RX_QUEUES]; |
1220 | int badFrame[NUM_RX_QUEUES]; | 1220 | int badFrame[NUM_RX_QUEUES]; |
1221 | u16 cpucount[NUM_TX_QUEUES]; | 1221 | u16 cpucount[NUM_TX_QUEUES]; |
1222 | volatile u16 *p_cpucount[NUM_TX_QUEUES]; | 1222 | u16 __iomem *p_cpucount[NUM_TX_QUEUES]; |
1223 | int indAddrRegUsed[NUM_OF_PADDRS]; | 1223 | int indAddrRegUsed[NUM_OF_PADDRS]; |
1224 | u8 paddr[NUM_OF_PADDRS][ENET_NUM_OCTETS_PER_ADDRESS]; /* ethernet address */ | 1224 | u8 paddr[NUM_OF_PADDRS][ENET_NUM_OCTETS_PER_ADDRESS]; /* ethernet address */ |
1225 | u8 numGroupAddrInHash; | 1225 | u8 numGroupAddrInHash; |
@@ -1251,4 +1251,12 @@ struct ucc_geth_private { | |||
1251 | int oldlink; | 1251 | int oldlink; |
1252 | }; | 1252 | }; |
1253 | 1253 | ||
1254 | void uec_set_ethtool_ops(struct net_device *netdev); | ||
1255 | int init_flow_control_params(u32 automatic_flow_control_mode, | ||
1256 | int rx_flow_control_enable, int tx_flow_control_enable, | ||
1257 | u16 pause_period, u16 extension_field, | ||
1258 | u32 __iomem *upsmr_register, u32 __iomem *uempr_register, | ||
1259 | u32 __iomem *maccfg1_register); | ||
1260 | |||
1261 | |||
1254 | #endif /* __UCC_GETH_H__ */ | 1262 | #endif /* __UCC_GETH_H__ */ |
diff --git a/drivers/net/ucc_geth_ethtool.c b/drivers/net/ucc_geth_ethtool.c index 9a9622c13e2b..f5839c4a5cbd 100644 --- a/drivers/net/ucc_geth_ethtool.c +++ b/drivers/net/ucc_geth_ethtool.c | |||
@@ -73,6 +73,7 @@ static char tx_fw_stat_gstrings[][ETH_GSTRING_LEN] = { | |||
73 | "tx-frames-ok", | 73 | "tx-frames-ok", |
74 | "tx-excessive-differ-frames", | 74 | "tx-excessive-differ-frames", |
75 | "tx-256-511-frames", | 75 | "tx-256-511-frames", |
76 | "tx-512-1023-frames", | ||
76 | "tx-1024-1518-frames", | 77 | "tx-1024-1518-frames", |
77 | "tx-jumbo-frames", | 78 | "tx-jumbo-frames", |
78 | }; | 79 | }; |
@@ -108,12 +109,6 @@ static char rx_fw_stat_gstrings[][ETH_GSTRING_LEN] = { | |||
108 | #define UEC_TX_FW_STATS_LEN ARRAY_SIZE(tx_fw_stat_gstrings) | 109 | #define UEC_TX_FW_STATS_LEN ARRAY_SIZE(tx_fw_stat_gstrings) |
109 | #define UEC_RX_FW_STATS_LEN ARRAY_SIZE(rx_fw_stat_gstrings) | 110 | #define UEC_RX_FW_STATS_LEN ARRAY_SIZE(rx_fw_stat_gstrings) |
110 | 111 | ||
111 | extern int init_flow_control_params(u32 automatic_flow_control_mode, | ||
112 | int rx_flow_control_enable, | ||
113 | int tx_flow_control_enable, u16 pause_period, | ||
114 | u16 extension_field, volatile u32 *upsmr_register, | ||
115 | volatile u32 *uempr_register, volatile u32 *maccfg1_register); | ||
116 | |||
117 | static int | 112 | static int |
118 | uec_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd) | 113 | uec_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd) |
119 | { | 114 | { |
@@ -314,7 +309,7 @@ static void uec_get_strings(struct net_device *netdev, u32 stringset, u8 *buf) | |||
314 | buf += UEC_TX_FW_STATS_LEN * ETH_GSTRING_LEN; | 309 | buf += UEC_TX_FW_STATS_LEN * ETH_GSTRING_LEN; |
315 | } | 310 | } |
316 | if (stats_mode & UCC_GETH_STATISTICS_GATHERING_MODE_FIRMWARE_RX) | 311 | if (stats_mode & UCC_GETH_STATISTICS_GATHERING_MODE_FIRMWARE_RX) |
317 | memcpy(buf, tx_fw_stat_gstrings, UEC_RX_FW_STATS_LEN * | 312 | memcpy(buf, rx_fw_stat_gstrings, UEC_RX_FW_STATS_LEN * |
318 | ETH_GSTRING_LEN); | 313 | ETH_GSTRING_LEN); |
319 | } | 314 | } |
320 | 315 | ||
diff --git a/drivers/net/ucc_geth_mii.c b/drivers/net/ucc_geth_mii.c index 2af490781005..940474736922 100644 --- a/drivers/net/ucc_geth_mii.c +++ b/drivers/net/ucc_geth_mii.c | |||
@@ -104,7 +104,7 @@ int uec_mdio_read(struct mii_bus *bus, int mii_id, int regnum) | |||
104 | } | 104 | } |
105 | 105 | ||
106 | /* Reset the MIIM registers, and wait for the bus to free */ | 106 | /* Reset the MIIM registers, and wait for the bus to free */ |
107 | int uec_mdio_reset(struct mii_bus *bus) | 107 | static int uec_mdio_reset(struct mii_bus *bus) |
108 | { | 108 | { |
109 | struct ucc_mii_mng __iomem *regs = (void __iomem *)bus->priv; | 109 | struct ucc_mii_mng __iomem *regs = (void __iomem *)bus->priv; |
110 | unsigned int timeout = PHY_INIT_TIMEOUT; | 110 | unsigned int timeout = PHY_INIT_TIMEOUT; |
@@ -240,7 +240,7 @@ reg_map_fail: | |||
240 | return err; | 240 | return err; |
241 | } | 241 | } |
242 | 242 | ||
243 | int uec_mdio_remove(struct of_device *ofdev) | 243 | static int uec_mdio_remove(struct of_device *ofdev) |
244 | { | 244 | { |
245 | struct device *device = &ofdev->dev; | 245 | struct device *device = &ofdev->dev; |
246 | struct mii_bus *bus = dev_get_drvdata(device); | 246 | struct mii_bus *bus = dev_get_drvdata(device); |
diff --git a/drivers/net/usb/asix.c b/drivers/net/usb/asix.c index 6f245cfb6624..37ecf845edfe 100644 --- a/drivers/net/usb/asix.c +++ b/drivers/net/usb/asix.c | |||
@@ -1381,6 +1381,10 @@ static const struct usb_device_id products [] = { | |||
1381 | USB_DEVICE (0x0411, 0x003d), | 1381 | USB_DEVICE (0x0411, 0x003d), |
1382 | .driver_info = (unsigned long) &ax8817x_info, | 1382 | .driver_info = (unsigned long) &ax8817x_info, |
1383 | }, { | 1383 | }, { |
1384 | // Buffalo LUA-U2-GT 10/100/1000 | ||
1385 | USB_DEVICE (0x0411, 0x006e), | ||
1386 | .driver_info = (unsigned long) &ax88178_info, | ||
1387 | }, { | ||
1384 | // Sitecom LN-029 "USB 2.0 10/100 Ethernet adapter" | 1388 | // Sitecom LN-029 "USB 2.0 10/100 Ethernet adapter" |
1385 | USB_DEVICE (0x6189, 0x182d), | 1389 | USB_DEVICE (0x6189, 0x182d), |
1386 | .driver_info = (unsigned long) &ax8817x_info, | 1390 | .driver_info = (unsigned long) &ax8817x_info, |
@@ -1436,6 +1440,10 @@ static const struct usb_device_id products [] = { | |||
1436 | // Belkin F5D5055 | 1440 | // Belkin F5D5055 |
1437 | USB_DEVICE(0x050d, 0x5055), | 1441 | USB_DEVICE(0x050d, 0x5055), |
1438 | .driver_info = (unsigned long) &ax88178_info, | 1442 | .driver_info = (unsigned long) &ax88178_info, |
1443 | }, { | ||
1444 | // Apple USB Ethernet Adapter | ||
1445 | USB_DEVICE(0x05ac, 0x1402), | ||
1446 | .driver_info = (unsigned long) &ax88772_info, | ||
1439 | }, | 1447 | }, |
1440 | { }, // END | 1448 | { }, // END |
1441 | }; | 1449 | }; |
diff --git a/drivers/net/usb/catc.c b/drivers/net/usb/catc.c index 76752d84a30f..22c17bbacb69 100644 --- a/drivers/net/usb/catc.c +++ b/drivers/net/usb/catc.c | |||
@@ -423,7 +423,10 @@ static int catc_hard_start_xmit(struct sk_buff *skb, struct net_device *netdev) | |||
423 | 423 | ||
424 | catc->tx_ptr = (((catc->tx_ptr - 1) >> 6) + 1) << 6; | 424 | catc->tx_ptr = (((catc->tx_ptr - 1) >> 6) + 1) << 6; |
425 | tx_buf = catc->tx_buf[catc->tx_idx] + catc->tx_ptr; | 425 | tx_buf = catc->tx_buf[catc->tx_idx] + catc->tx_ptr; |
426 | *((u16*)tx_buf) = (catc->is_f5u011) ? cpu_to_be16((u16)skb->len) : cpu_to_le16((u16)skb->len); | 426 | if (catc->is_f5u011) |
427 | *(__be16 *)tx_buf = cpu_to_be16(skb->len); | ||
428 | else | ||
429 | *(__le16 *)tx_buf = cpu_to_le16(skb->len); | ||
427 | skb_copy_from_linear_data(skb, tx_buf + 2, skb->len); | 430 | skb_copy_from_linear_data(skb, tx_buf + 2, skb->len); |
428 | catc->tx_ptr += skb->len + 2; | 431 | catc->tx_ptr += skb->len + 2; |
429 | 432 | ||
diff --git a/drivers/net/usb/cdc_subset.c b/drivers/net/usb/cdc_subset.c index 0ec7936cbe21..c66b9c324f54 100644 --- a/drivers/net/usb/cdc_subset.c +++ b/drivers/net/usb/cdc_subset.c | |||
@@ -218,7 +218,7 @@ static const struct driver_info blob_info = { | |||
218 | /*-------------------------------------------------------------------------*/ | 218 | /*-------------------------------------------------------------------------*/ |
219 | 219 | ||
220 | #ifndef HAVE_HARDWARE | 220 | #ifndef HAVE_HARDWARE |
221 | #error You need to configure some hardware for this driver | 221 | #warning You need to configure some hardware for this driver |
222 | #endif | 222 | #endif |
223 | 223 | ||
224 | /* | 224 | /* |
diff --git a/drivers/net/usb/kaweth.c b/drivers/net/usb/kaweth.c index 0dcfc0310264..7c66b052f55a 100644 --- a/drivers/net/usb/kaweth.c +++ b/drivers/net/usb/kaweth.c | |||
@@ -706,7 +706,7 @@ static void kaweth_kill_urbs(struct kaweth_device *kaweth) | |||
706 | usb_kill_urb(kaweth->rx_urb); | 706 | usb_kill_urb(kaweth->rx_urb); |
707 | usb_kill_urb(kaweth->tx_urb); | 707 | usb_kill_urb(kaweth->tx_urb); |
708 | 708 | ||
709 | flush_scheduled_work(); | 709 | cancel_delayed_work_sync(&kaweth->lowmem_work); |
710 | 710 | ||
711 | /* a scheduled work may have resubmitted, | 711 | /* a scheduled work may have resubmitted, |
712 | we hit them again */ | 712 | we hit them again */ |
diff --git a/drivers/net/usb/rndis_host.c b/drivers/net/usb/rndis_host.c index 21a7785cb8b6..ae467f182c40 100644 --- a/drivers/net/usb/rndis_host.c +++ b/drivers/net/usb/rndis_host.c | |||
@@ -194,7 +194,7 @@ int rndis_command(struct usbnet *dev, struct rndis_msg_hdr *buf) | |||
194 | dev_dbg(&info->control->dev, | 194 | dev_dbg(&info->control->dev, |
195 | "rndis response error, code %d\n", retval); | 195 | "rndis response error, code %d\n", retval); |
196 | } | 196 | } |
197 | msleep(2); | 197 | msleep(20); |
198 | } | 198 | } |
199 | dev_dbg(&info->control->dev, "rndis response timeout\n"); | 199 | dev_dbg(&info->control->dev, "rndis response timeout\n"); |
200 | return -ETIMEDOUT; | 200 | return -ETIMEDOUT; |
@@ -283,8 +283,8 @@ generic_rndis_bind(struct usbnet *dev, struct usb_interface *intf, int flags) | |||
283 | struct rndis_set_c *set_c; | 283 | struct rndis_set_c *set_c; |
284 | struct rndis_halt *halt; | 284 | struct rndis_halt *halt; |
285 | } u; | 285 | } u; |
286 | u32 tmp, phym_unspec; | 286 | u32 tmp; |
287 | __le32 *phym; | 287 | __le32 phym_unspec, *phym; |
288 | int reply_len; | 288 | int reply_len; |
289 | unsigned char *bp; | 289 | unsigned char *bp; |
290 | 290 | ||
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index 555b70c8b863..4452306d5328 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c | |||
@@ -41,9 +41,19 @@ struct virtnet_info | |||
41 | struct net_device *dev; | 41 | struct net_device *dev; |
42 | struct napi_struct napi; | 42 | struct napi_struct napi; |
43 | 43 | ||
44 | /* The skb we couldn't send because buffers were full. */ | ||
45 | struct sk_buff *last_xmit_skb; | ||
46 | |||
47 | /* If we need to free in a timer, this is it. */ | ||
48 | struct timer_list xmit_free_timer; | ||
49 | |||
44 | /* Number of input buffers, and max we've ever had. */ | 50 | /* Number of input buffers, and max we've ever had. */ |
45 | unsigned int num, max; | 51 | unsigned int num, max; |
46 | 52 | ||
53 | /* For cleaning up after transmission. */ | ||
54 | struct tasklet_struct tasklet; | ||
55 | bool free_in_tasklet; | ||
56 | |||
47 | /* Receive & send queues. */ | 57 | /* Receive & send queues. */ |
48 | struct sk_buff_head recv; | 58 | struct sk_buff_head recv; |
49 | struct sk_buff_head send; | 59 | struct sk_buff_head send; |
@@ -65,8 +75,13 @@ static void skb_xmit_done(struct virtqueue *svq) | |||
65 | 75 | ||
66 | /* Suppress further interrupts. */ | 76 | /* Suppress further interrupts. */ |
67 | svq->vq_ops->disable_cb(svq); | 77 | svq->vq_ops->disable_cb(svq); |
68 | /* We were waiting for more output buffers. */ | 78 | |
79 | /* We were probably waiting for more output buffers. */ | ||
69 | netif_wake_queue(vi->dev); | 80 | netif_wake_queue(vi->dev); |
81 | |||
82 | /* Make sure we re-xmit last_xmit_skb: if there are no more packets | ||
83 | * queued, start_xmit won't be called. */ | ||
84 | tasklet_schedule(&vi->tasklet); | ||
70 | } | 85 | } |
71 | 86 | ||
72 | static void receive_skb(struct net_device *dev, struct sk_buff *skb, | 87 | static void receive_skb(struct net_device *dev, struct sk_buff *skb, |
@@ -83,9 +98,7 @@ static void receive_skb(struct net_device *dev, struct sk_buff *skb, | |||
83 | BUG_ON(len > MAX_PACKET_LEN); | 98 | BUG_ON(len > MAX_PACKET_LEN); |
84 | 99 | ||
85 | skb_trim(skb, len); | 100 | skb_trim(skb, len); |
86 | skb->protocol = eth_type_trans(skb, dev); | 101 | |
87 | pr_debug("Receiving skb proto 0x%04x len %i type %i\n", | ||
88 | ntohs(skb->protocol), skb->len, skb->pkt_type); | ||
89 | dev->stats.rx_bytes += skb->len; | 102 | dev->stats.rx_bytes += skb->len; |
90 | dev->stats.rx_packets++; | 103 | dev->stats.rx_packets++; |
91 | 104 | ||
@@ -95,6 +108,10 @@ static void receive_skb(struct net_device *dev, struct sk_buff *skb, | |||
95 | goto frame_err; | 108 | goto frame_err; |
96 | } | 109 | } |
97 | 110 | ||
111 | skb->protocol = eth_type_trans(skb, dev); | ||
112 | pr_debug("Receiving skb proto 0x%04x len %i type %i\n", | ||
113 | ntohs(skb->protocol), skb->len, skb->pkt_type); | ||
114 | |||
98 | if (hdr->gso_type != VIRTIO_NET_HDR_GSO_NONE) { | 115 | if (hdr->gso_type != VIRTIO_NET_HDR_GSO_NONE) { |
99 | pr_debug("GSO!\n"); | 116 | pr_debug("GSO!\n"); |
100 | switch (hdr->gso_type & ~VIRTIO_NET_HDR_GSO_ECN) { | 117 | switch (hdr->gso_type & ~VIRTIO_NET_HDR_GSO_ECN) { |
@@ -142,10 +159,10 @@ drop: | |||
142 | static void try_fill_recv(struct virtnet_info *vi) | 159 | static void try_fill_recv(struct virtnet_info *vi) |
143 | { | 160 | { |
144 | struct sk_buff *skb; | 161 | struct sk_buff *skb; |
145 | struct scatterlist sg[1+MAX_SKB_FRAGS]; | 162 | struct scatterlist sg[2+MAX_SKB_FRAGS]; |
146 | int num, err; | 163 | int num, err; |
147 | 164 | ||
148 | sg_init_table(sg, 1+MAX_SKB_FRAGS); | 165 | sg_init_table(sg, 2+MAX_SKB_FRAGS); |
149 | for (;;) { | 166 | for (;;) { |
150 | skb = netdev_alloc_skb(vi->dev, MAX_PACKET_LEN); | 167 | skb = netdev_alloc_skb(vi->dev, MAX_PACKET_LEN); |
151 | if (unlikely(!skb)) | 168 | if (unlikely(!skb)) |
@@ -221,23 +238,38 @@ static void free_old_xmit_skbs(struct virtnet_info *vi) | |||
221 | while ((skb = vi->svq->vq_ops->get_buf(vi->svq, &len)) != NULL) { | 238 | while ((skb = vi->svq->vq_ops->get_buf(vi->svq, &len)) != NULL) { |
222 | pr_debug("Sent skb %p\n", skb); | 239 | pr_debug("Sent skb %p\n", skb); |
223 | __skb_unlink(skb, &vi->send); | 240 | __skb_unlink(skb, &vi->send); |
224 | vi->dev->stats.tx_bytes += len; | 241 | vi->dev->stats.tx_bytes += skb->len; |
225 | vi->dev->stats.tx_packets++; | 242 | vi->dev->stats.tx_packets++; |
226 | kfree_skb(skb); | 243 | kfree_skb(skb); |
227 | } | 244 | } |
228 | } | 245 | } |
229 | 246 | ||
230 | static int start_xmit(struct sk_buff *skb, struct net_device *dev) | 247 | /* If the virtio transport doesn't always notify us when all in-flight packets |
248 | * are consumed, we fall back to using this function on a timer to free them. */ | ||
249 | static void xmit_free(unsigned long data) | ||
250 | { | ||
251 | struct virtnet_info *vi = (void *)data; | ||
252 | |||
253 | netif_tx_lock(vi->dev); | ||
254 | |||
255 | free_old_xmit_skbs(vi); | ||
256 | |||
257 | if (!skb_queue_empty(&vi->send)) | ||
258 | mod_timer(&vi->xmit_free_timer, jiffies + (HZ/10)); | ||
259 | |||
260 | netif_tx_unlock(vi->dev); | ||
261 | } | ||
262 | |||
263 | static int xmit_skb(struct virtnet_info *vi, struct sk_buff *skb) | ||
231 | { | 264 | { |
232 | struct virtnet_info *vi = netdev_priv(dev); | ||
233 | int num, err; | 265 | int num, err; |
234 | struct scatterlist sg[1+MAX_SKB_FRAGS]; | 266 | struct scatterlist sg[2+MAX_SKB_FRAGS]; |
235 | struct virtio_net_hdr *hdr; | 267 | struct virtio_net_hdr *hdr; |
236 | const unsigned char *dest = ((struct ethhdr *)skb->data)->h_dest; | 268 | const unsigned char *dest = ((struct ethhdr *)skb->data)->h_dest; |
237 | 269 | ||
238 | sg_init_table(sg, 1+MAX_SKB_FRAGS); | 270 | sg_init_table(sg, 2+MAX_SKB_FRAGS); |
239 | 271 | ||
240 | pr_debug("%s: xmit %p " MAC_FMT "\n", dev->name, skb, | 272 | pr_debug("%s: xmit %p " MAC_FMT "\n", vi->dev->name, skb, |
241 | dest[0], dest[1], dest[2], | 273 | dest[0], dest[1], dest[2], |
242 | dest[3], dest[4], dest[5]); | 274 | dest[3], dest[4], dest[5]); |
243 | 275 | ||
@@ -272,30 +304,73 @@ static int start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
272 | 304 | ||
273 | vnet_hdr_to_sg(sg, skb); | 305 | vnet_hdr_to_sg(sg, skb); |
274 | num = skb_to_sgvec(skb, sg+1, 0, skb->len) + 1; | 306 | num = skb_to_sgvec(skb, sg+1, 0, skb->len) + 1; |
275 | __skb_queue_head(&vi->send, skb); | 307 | |
308 | err = vi->svq->vq_ops->add_buf(vi->svq, sg, num, 0, skb); | ||
309 | if (!err && !vi->free_in_tasklet) | ||
310 | mod_timer(&vi->xmit_free_timer, jiffies + (HZ/10)); | ||
311 | |||
312 | return err; | ||
313 | } | ||
314 | |||
315 | static void xmit_tasklet(unsigned long data) | ||
316 | { | ||
317 | struct virtnet_info *vi = (void *)data; | ||
318 | |||
319 | netif_tx_lock_bh(vi->dev); | ||
320 | if (vi->last_xmit_skb && xmit_skb(vi, vi->last_xmit_skb) == 0) { | ||
321 | vi->svq->vq_ops->kick(vi->svq); | ||
322 | vi->last_xmit_skb = NULL; | ||
323 | } | ||
324 | if (vi->free_in_tasklet) | ||
325 | free_old_xmit_skbs(vi); | ||
326 | netif_tx_unlock_bh(vi->dev); | ||
327 | } | ||
328 | |||
329 | static int start_xmit(struct sk_buff *skb, struct net_device *dev) | ||
330 | { | ||
331 | struct virtnet_info *vi = netdev_priv(dev); | ||
276 | 332 | ||
277 | again: | 333 | again: |
278 | /* Free up any pending old buffers before queueing new ones. */ | 334 | /* Free up any pending old buffers before queueing new ones. */ |
279 | free_old_xmit_skbs(vi); | 335 | free_old_xmit_skbs(vi); |
280 | err = vi->svq->vq_ops->add_buf(vi->svq, sg, num, 0, skb); | 336 | |
281 | if (err) { | 337 | /* If we has a buffer left over from last time, send it now. */ |
282 | pr_debug("%s: virtio not prepared to send\n", dev->name); | 338 | if (unlikely(vi->last_xmit_skb)) { |
283 | netif_stop_queue(dev); | 339 | if (xmit_skb(vi, vi->last_xmit_skb) != 0) { |
284 | 340 | /* Drop this skb: we only queue one. */ | |
285 | /* Activate callback for using skbs: if this returns false it | 341 | vi->dev->stats.tx_dropped++; |
286 | * means some were used in the meantime. */ | 342 | kfree_skb(skb); |
287 | if (unlikely(!vi->svq->vq_ops->enable_cb(vi->svq))) { | 343 | skb = NULL; |
288 | vi->svq->vq_ops->disable_cb(vi->svq); | 344 | goto stop_queue; |
289 | netif_start_queue(dev); | ||
290 | goto again; | ||
291 | } | 345 | } |
292 | __skb_unlink(skb, &vi->send); | 346 | vi->last_xmit_skb = NULL; |
347 | } | ||
293 | 348 | ||
294 | return NETDEV_TX_BUSY; | 349 | /* Put new one in send queue and do transmit */ |
350 | if (likely(skb)) { | ||
351 | __skb_queue_head(&vi->send, skb); | ||
352 | if (xmit_skb(vi, skb) != 0) { | ||
353 | vi->last_xmit_skb = skb; | ||
354 | skb = NULL; | ||
355 | goto stop_queue; | ||
356 | } | ||
295 | } | 357 | } |
358 | done: | ||
296 | vi->svq->vq_ops->kick(vi->svq); | 359 | vi->svq->vq_ops->kick(vi->svq); |
297 | 360 | return NETDEV_TX_OK; | |
298 | return 0; | 361 | |
362 | stop_queue: | ||
363 | pr_debug("%s: virtio not prepared to send\n", dev->name); | ||
364 | netif_stop_queue(dev); | ||
365 | |||
366 | /* Activate callback for using skbs: if this returns false it | ||
367 | * means some were used in the meantime. */ | ||
368 | if (unlikely(!vi->svq->vq_ops->enable_cb(vi->svq))) { | ||
369 | vi->svq->vq_ops->disable_cb(vi->svq); | ||
370 | netif_start_queue(dev); | ||
371 | goto again; | ||
372 | } | ||
373 | goto done; | ||
299 | } | 374 | } |
300 | 375 | ||
301 | #ifdef CONFIG_NET_POLL_CONTROLLER | 376 | #ifdef CONFIG_NET_POLL_CONTROLLER |
@@ -355,17 +430,26 @@ static int virtnet_probe(struct virtio_device *vdev) | |||
355 | SET_NETDEV_DEV(dev, &vdev->dev); | 430 | SET_NETDEV_DEV(dev, &vdev->dev); |
356 | 431 | ||
357 | /* Do we support "hardware" checksums? */ | 432 | /* Do we support "hardware" checksums? */ |
358 | if (csum && vdev->config->feature(vdev, VIRTIO_NET_F_CSUM)) { | 433 | if (csum && virtio_has_feature(vdev, VIRTIO_NET_F_CSUM)) { |
359 | /* This opens up the world of extra features. */ | 434 | /* This opens up the world of extra features. */ |
360 | dev->features |= NETIF_F_HW_CSUM|NETIF_F_SG|NETIF_F_FRAGLIST; | 435 | dev->features |= NETIF_F_HW_CSUM|NETIF_F_SG|NETIF_F_FRAGLIST; |
361 | if (gso && vdev->config->feature(vdev, VIRTIO_NET_F_GSO)) { | 436 | if (gso && virtio_has_feature(vdev, VIRTIO_NET_F_GSO)) { |
362 | dev->features |= NETIF_F_TSO | NETIF_F_UFO | 437 | dev->features |= NETIF_F_TSO | NETIF_F_UFO |
363 | | NETIF_F_TSO_ECN | NETIF_F_TSO6; | 438 | | NETIF_F_TSO_ECN | NETIF_F_TSO6; |
364 | } | 439 | } |
440 | /* Individual feature bits: what can host handle? */ | ||
441 | if (gso && virtio_has_feature(vdev, VIRTIO_NET_F_HOST_TSO4)) | ||
442 | dev->features |= NETIF_F_TSO; | ||
443 | if (gso && virtio_has_feature(vdev, VIRTIO_NET_F_HOST_TSO6)) | ||
444 | dev->features |= NETIF_F_TSO6; | ||
445 | if (gso && virtio_has_feature(vdev, VIRTIO_NET_F_HOST_ECN)) | ||
446 | dev->features |= NETIF_F_TSO_ECN; | ||
447 | if (gso && virtio_has_feature(vdev, VIRTIO_NET_F_HOST_UFO)) | ||
448 | dev->features |= NETIF_F_UFO; | ||
365 | } | 449 | } |
366 | 450 | ||
367 | /* Configuration may specify what MAC to use. Otherwise random. */ | 451 | /* Configuration may specify what MAC to use. Otherwise random. */ |
368 | if (vdev->config->feature(vdev, VIRTIO_NET_F_MAC)) { | 452 | if (virtio_has_feature(vdev, VIRTIO_NET_F_MAC)) { |
369 | vdev->config->get(vdev, | 453 | vdev->config->get(vdev, |
370 | offsetof(struct virtio_net_config, mac), | 454 | offsetof(struct virtio_net_config, mac), |
371 | dev->dev_addr, dev->addr_len); | 455 | dev->dev_addr, dev->addr_len); |
@@ -379,6 +463,10 @@ static int virtnet_probe(struct virtio_device *vdev) | |||
379 | vi->vdev = vdev; | 463 | vi->vdev = vdev; |
380 | vdev->priv = vi; | 464 | vdev->priv = vi; |
381 | 465 | ||
466 | /* If they give us a callback when all buffers are done, we don't need | ||
467 | * the timer. */ | ||
468 | vi->free_in_tasklet = virtio_has_feature(vdev,VIRTIO_F_NOTIFY_ON_EMPTY); | ||
469 | |||
382 | /* We expect two virtqueues, receive then send. */ | 470 | /* We expect two virtqueues, receive then send. */ |
383 | vi->rvq = vdev->config->find_vq(vdev, 0, skb_recv_done); | 471 | vi->rvq = vdev->config->find_vq(vdev, 0, skb_recv_done); |
384 | if (IS_ERR(vi->rvq)) { | 472 | if (IS_ERR(vi->rvq)) { |
@@ -396,6 +484,11 @@ static int virtnet_probe(struct virtio_device *vdev) | |||
396 | skb_queue_head_init(&vi->recv); | 484 | skb_queue_head_init(&vi->recv); |
397 | skb_queue_head_init(&vi->send); | 485 | skb_queue_head_init(&vi->send); |
398 | 486 | ||
487 | tasklet_init(&vi->tasklet, xmit_tasklet, (unsigned long)vi); | ||
488 | |||
489 | if (!vi->free_in_tasklet) | ||
490 | setup_timer(&vi->xmit_free_timer, xmit_free, (unsigned long)vi); | ||
491 | |||
399 | err = register_netdev(dev); | 492 | err = register_netdev(dev); |
400 | if (err) { | 493 | if (err) { |
401 | pr_debug("virtio_net: registering device failed\n"); | 494 | pr_debug("virtio_net: registering device failed\n"); |
@@ -433,13 +526,15 @@ static void virtnet_remove(struct virtio_device *vdev) | |||
433 | /* Stop all the virtqueues. */ | 526 | /* Stop all the virtqueues. */ |
434 | vdev->config->reset(vdev); | 527 | vdev->config->reset(vdev); |
435 | 528 | ||
529 | if (!vi->free_in_tasklet) | ||
530 | del_timer_sync(&vi->xmit_free_timer); | ||
531 | |||
436 | /* Free our skbs in send and recv queues, if any. */ | 532 | /* Free our skbs in send and recv queues, if any. */ |
437 | while ((skb = __skb_dequeue(&vi->recv)) != NULL) { | 533 | while ((skb = __skb_dequeue(&vi->recv)) != NULL) { |
438 | kfree_skb(skb); | 534 | kfree_skb(skb); |
439 | vi->num--; | 535 | vi->num--; |
440 | } | 536 | } |
441 | while ((skb = __skb_dequeue(&vi->send)) != NULL) | 537 | __skb_queue_purge(&vi->send); |
442 | kfree_skb(skb); | ||
443 | 538 | ||
444 | BUG_ON(vi->num != 0); | 539 | BUG_ON(vi->num != 0); |
445 | 540 | ||
@@ -454,7 +549,15 @@ static struct virtio_device_id id_table[] = { | |||
454 | { 0 }, | 549 | { 0 }, |
455 | }; | 550 | }; |
456 | 551 | ||
552 | static unsigned int features[] = { | ||
553 | VIRTIO_NET_F_CSUM, VIRTIO_NET_F_GSO, VIRTIO_NET_F_MAC, | ||
554 | VIRTIO_NET_F_HOST_TSO4, VIRTIO_NET_F_HOST_UFO, VIRTIO_NET_F_HOST_TSO6, | ||
555 | VIRTIO_NET_F_HOST_ECN, VIRTIO_F_NOTIFY_ON_EMPTY, | ||
556 | }; | ||
557 | |||
457 | static struct virtio_driver virtio_net = { | 558 | static struct virtio_driver virtio_net = { |
559 | .feature_table = features, | ||
560 | .feature_table_size = ARRAY_SIZE(features), | ||
458 | .driver.name = KBUILD_MODNAME, | 561 | .driver.name = KBUILD_MODNAME, |
459 | .driver.owner = THIS_MODULE, | 562 | .driver.owner = THIS_MODULE, |
460 | .id_table = id_table, | 563 | .id_table = id_table, |
diff --git a/drivers/net/wan/Kconfig b/drivers/net/wan/Kconfig index 8005dd16fb4e..d5140aed7b79 100644 --- a/drivers/net/wan/Kconfig +++ b/drivers/net/wan/Kconfig | |||
@@ -150,11 +150,9 @@ config HDLC_FR | |||
150 | 150 | ||
151 | config HDLC_PPP | 151 | config HDLC_PPP |
152 | tristate "Synchronous Point-to-Point Protocol (PPP) support" | 152 | tristate "Synchronous Point-to-Point Protocol (PPP) support" |
153 | depends on HDLC && BROKEN | 153 | depends on HDLC |
154 | help | 154 | help |
155 | Generic HDLC driver supporting PPP over WAN connections. | 155 | Generic HDLC driver supporting PPP over WAN connections. |
156 | This module is currently broken and will cause a kernel panic | ||
157 | when a device configured in PPP mode is activated. | ||
158 | 156 | ||
159 | It will be replaced by new PPP implementation in Linux 2.6.26. | 157 | It will be replaced by new PPP implementation in Linux 2.6.26. |
160 | 158 | ||
diff --git a/drivers/net/wan/cosa.c b/drivers/net/wan/cosa.c index 45ddfc9763cc..b0fce1387eaf 100644 --- a/drivers/net/wan/cosa.c +++ b/drivers/net/wan/cosa.c | |||
@@ -629,7 +629,7 @@ static void sppp_channel_init(struct channel_data *chan) | |||
629 | d->base_addr = chan->cosa->datareg; | 629 | d->base_addr = chan->cosa->datareg; |
630 | d->irq = chan->cosa->irq; | 630 | d->irq = chan->cosa->irq; |
631 | d->dma = chan->cosa->dma; | 631 | d->dma = chan->cosa->dma; |
632 | d->priv = chan; | 632 | d->ml_priv = chan; |
633 | sppp_attach(&chan->pppdev); | 633 | sppp_attach(&chan->pppdev); |
634 | if (register_netdev(d)) { | 634 | if (register_netdev(d)) { |
635 | printk(KERN_WARNING "%s: register_netdev failed.\n", d->name); | 635 | printk(KERN_WARNING "%s: register_netdev failed.\n", d->name); |
@@ -650,7 +650,7 @@ static void sppp_channel_delete(struct channel_data *chan) | |||
650 | 650 | ||
651 | static int cosa_sppp_open(struct net_device *d) | 651 | static int cosa_sppp_open(struct net_device *d) |
652 | { | 652 | { |
653 | struct channel_data *chan = d->priv; | 653 | struct channel_data *chan = d->ml_priv; |
654 | int err; | 654 | int err; |
655 | unsigned long flags; | 655 | unsigned long flags; |
656 | 656 | ||
@@ -690,7 +690,7 @@ static int cosa_sppp_open(struct net_device *d) | |||
690 | 690 | ||
691 | static int cosa_sppp_tx(struct sk_buff *skb, struct net_device *dev) | 691 | static int cosa_sppp_tx(struct sk_buff *skb, struct net_device *dev) |
692 | { | 692 | { |
693 | struct channel_data *chan = dev->priv; | 693 | struct channel_data *chan = dev->ml_priv; |
694 | 694 | ||
695 | netif_stop_queue(dev); | 695 | netif_stop_queue(dev); |
696 | 696 | ||
@@ -701,7 +701,7 @@ static int cosa_sppp_tx(struct sk_buff *skb, struct net_device *dev) | |||
701 | 701 | ||
702 | static void cosa_sppp_timeout(struct net_device *dev) | 702 | static void cosa_sppp_timeout(struct net_device *dev) |
703 | { | 703 | { |
704 | struct channel_data *chan = dev->priv; | 704 | struct channel_data *chan = dev->ml_priv; |
705 | 705 | ||
706 | if (test_bit(RXBIT, &chan->cosa->rxtx)) { | 706 | if (test_bit(RXBIT, &chan->cosa->rxtx)) { |
707 | chan->stats.rx_errors++; | 707 | chan->stats.rx_errors++; |
@@ -720,7 +720,7 @@ static void cosa_sppp_timeout(struct net_device *dev) | |||
720 | 720 | ||
721 | static int cosa_sppp_close(struct net_device *d) | 721 | static int cosa_sppp_close(struct net_device *d) |
722 | { | 722 | { |
723 | struct channel_data *chan = d->priv; | 723 | struct channel_data *chan = d->ml_priv; |
724 | unsigned long flags; | 724 | unsigned long flags; |
725 | 725 | ||
726 | netif_stop_queue(d); | 726 | netif_stop_queue(d); |
@@ -800,7 +800,7 @@ static int sppp_tx_done(struct channel_data *chan, int size) | |||
800 | 800 | ||
801 | static struct net_device_stats *cosa_net_stats(struct net_device *dev) | 801 | static struct net_device_stats *cosa_net_stats(struct net_device *dev) |
802 | { | 802 | { |
803 | struct channel_data *chan = dev->priv; | 803 | struct channel_data *chan = dev->ml_priv; |
804 | return &chan->stats; | 804 | return &chan->stats; |
805 | } | 805 | } |
806 | 806 | ||
@@ -1217,7 +1217,7 @@ static int cosa_sppp_ioctl(struct net_device *dev, struct ifreq *ifr, | |||
1217 | int cmd) | 1217 | int cmd) |
1218 | { | 1218 | { |
1219 | int rv; | 1219 | int rv; |
1220 | struct channel_data *chan = dev->priv; | 1220 | struct channel_data *chan = dev->ml_priv; |
1221 | rv = cosa_ioctl_common(chan->cosa, chan, cmd, (unsigned long)ifr->ifr_data); | 1221 | rv = cosa_ioctl_common(chan->cosa, chan, cmd, (unsigned long)ifr->ifr_data); |
1222 | if (rv == -ENOIOCTLCMD) { | 1222 | if (rv == -ENOIOCTLCMD) { |
1223 | return sppp_do_ioctl(dev, ifr, cmd); | 1223 | return sppp_do_ioctl(dev, ifr, cmd); |
diff --git a/drivers/net/wan/hdlc.c b/drivers/net/wan/hdlc.c index 9a83c9d5b8cf..7f984895b0d5 100644 --- a/drivers/net/wan/hdlc.c +++ b/drivers/net/wan/hdlc.c | |||
@@ -43,8 +43,7 @@ static const char* version = "HDLC support module revision 1.22"; | |||
43 | 43 | ||
44 | #undef DEBUG_LINK | 44 | #undef DEBUG_LINK |
45 | 45 | ||
46 | static struct hdlc_proto *first_proto = NULL; | 46 | static struct hdlc_proto *first_proto; |
47 | |||
48 | 47 | ||
49 | static int hdlc_change_mtu(struct net_device *dev, int new_mtu) | 48 | static int hdlc_change_mtu(struct net_device *dev, int new_mtu) |
50 | { | 49 | { |
@@ -314,21 +313,25 @@ void detach_hdlc_protocol(struct net_device *dev) | |||
314 | 313 | ||
315 | void register_hdlc_protocol(struct hdlc_proto *proto) | 314 | void register_hdlc_protocol(struct hdlc_proto *proto) |
316 | { | 315 | { |
316 | rtnl_lock(); | ||
317 | proto->next = first_proto; | 317 | proto->next = first_proto; |
318 | first_proto = proto; | 318 | first_proto = proto; |
319 | rtnl_unlock(); | ||
319 | } | 320 | } |
320 | 321 | ||
321 | 322 | ||
322 | void unregister_hdlc_protocol(struct hdlc_proto *proto) | 323 | void unregister_hdlc_protocol(struct hdlc_proto *proto) |
323 | { | 324 | { |
324 | struct hdlc_proto **p = &first_proto; | 325 | struct hdlc_proto **p; |
325 | while (*p) { | 326 | |
326 | if (*p == proto) { | 327 | rtnl_lock(); |
327 | *p = proto->next; | 328 | p = &first_proto; |
328 | return; | 329 | while (*p != proto) { |
329 | } | 330 | BUG_ON(!*p); |
330 | p = &((*p)->next); | 331 | p = &((*p)->next); |
331 | } | 332 | } |
333 | *p = proto->next; | ||
334 | rtnl_unlock(); | ||
332 | } | 335 | } |
333 | 336 | ||
334 | 337 | ||
diff --git a/drivers/net/wan/hdlc_cisco.c b/drivers/net/wan/hdlc_cisco.c index 7133c688cf20..762d21c1c703 100644 --- a/drivers/net/wan/hdlc_cisco.c +++ b/drivers/net/wan/hdlc_cisco.c | |||
@@ -56,6 +56,7 @@ struct cisco_state { | |||
56 | cisco_proto settings; | 56 | cisco_proto settings; |
57 | 57 | ||
58 | struct timer_list timer; | 58 | struct timer_list timer; |
59 | spinlock_t lock; | ||
59 | unsigned long last_poll; | 60 | unsigned long last_poll; |
60 | int up; | 61 | int up; |
61 | int request_sent; | 62 | int request_sent; |
@@ -158,6 +159,7 @@ static int cisco_rx(struct sk_buff *skb) | |||
158 | { | 159 | { |
159 | struct net_device *dev = skb->dev; | 160 | struct net_device *dev = skb->dev; |
160 | hdlc_device *hdlc = dev_to_hdlc(dev); | 161 | hdlc_device *hdlc = dev_to_hdlc(dev); |
162 | struct cisco_state *st = state(hdlc); | ||
161 | struct hdlc_header *data = (struct hdlc_header*)skb->data; | 163 | struct hdlc_header *data = (struct hdlc_header*)skb->data; |
162 | struct cisco_packet *cisco_data; | 164 | struct cisco_packet *cisco_data; |
163 | struct in_device *in_dev; | 165 | struct in_device *in_dev; |
@@ -220,11 +222,12 @@ static int cisco_rx(struct sk_buff *skb) | |||
220 | goto rx_error; | 222 | goto rx_error; |
221 | 223 | ||
222 | case CISCO_KEEPALIVE_REQ: | 224 | case CISCO_KEEPALIVE_REQ: |
223 | state(hdlc)->rxseq = ntohl(cisco_data->par1); | 225 | spin_lock(&st->lock); |
224 | if (state(hdlc)->request_sent && | 226 | st->rxseq = ntohl(cisco_data->par1); |
225 | ntohl(cisco_data->par2) == state(hdlc)->txseq) { | 227 | if (st->request_sent && |
226 | state(hdlc)->last_poll = jiffies; | 228 | ntohl(cisco_data->par2) == st->txseq) { |
227 | if (!state(hdlc)->up) { | 229 | st->last_poll = jiffies; |
230 | if (!st->up) { | ||
228 | u32 sec, min, hrs, days; | 231 | u32 sec, min, hrs, days; |
229 | sec = ntohl(cisco_data->time) / 1000; | 232 | sec = ntohl(cisco_data->time) / 1000; |
230 | min = sec / 60; sec -= min * 60; | 233 | min = sec / 60; sec -= min * 60; |
@@ -232,12 +235,12 @@ static int cisco_rx(struct sk_buff *skb) | |||
232 | days = hrs / 24; hrs -= days * 24; | 235 | days = hrs / 24; hrs -= days * 24; |
233 | printk(KERN_INFO "%s: Link up (peer " | 236 | printk(KERN_INFO "%s: Link up (peer " |
234 | "uptime %ud%uh%um%us)\n", | 237 | "uptime %ud%uh%um%us)\n", |
235 | dev->name, days, hrs, | 238 | dev->name, days, hrs, min, sec); |
236 | min, sec); | ||
237 | netif_dormant_off(dev); | 239 | netif_dormant_off(dev); |
238 | state(hdlc)->up = 1; | 240 | st->up = 1; |
239 | } | 241 | } |
240 | } | 242 | } |
243 | spin_unlock(&st->lock); | ||
241 | 244 | ||
242 | dev_kfree_skb_any(skb); | 245 | dev_kfree_skb_any(skb); |
243 | return NET_RX_SUCCESS; | 246 | return NET_RX_SUCCESS; |
@@ -261,24 +264,25 @@ static void cisco_timer(unsigned long arg) | |||
261 | { | 264 | { |
262 | struct net_device *dev = (struct net_device *)arg; | 265 | struct net_device *dev = (struct net_device *)arg; |
263 | hdlc_device *hdlc = dev_to_hdlc(dev); | 266 | hdlc_device *hdlc = dev_to_hdlc(dev); |
267 | struct cisco_state *st = state(hdlc); | ||
264 | 268 | ||
265 | if (state(hdlc)->up && | 269 | spin_lock(&st->lock); |
266 | time_after(jiffies, state(hdlc)->last_poll + | 270 | if (st->up && |
267 | state(hdlc)->settings.timeout * HZ)) { | 271 | time_after(jiffies, st->last_poll + st->settings.timeout * HZ)) { |
268 | state(hdlc)->up = 0; | 272 | st->up = 0; |
269 | printk(KERN_INFO "%s: Link down\n", dev->name); | 273 | printk(KERN_INFO "%s: Link down\n", dev->name); |
270 | netif_dormant_on(dev); | 274 | netif_dormant_on(dev); |
271 | } | 275 | } |
272 | 276 | ||
273 | cisco_keepalive_send(dev, CISCO_KEEPALIVE_REQ, | 277 | cisco_keepalive_send(dev, CISCO_KEEPALIVE_REQ, htonl(++st->txseq), |
274 | htonl(++state(hdlc)->txseq), | 278 | htonl(st->rxseq)); |
275 | htonl(state(hdlc)->rxseq)); | 279 | st->request_sent = 1; |
276 | state(hdlc)->request_sent = 1; | 280 | spin_unlock(&st->lock); |
277 | state(hdlc)->timer.expires = jiffies + | 281 | |
278 | state(hdlc)->settings.interval * HZ; | 282 | st->timer.expires = jiffies + st->settings.interval * HZ; |
279 | state(hdlc)->timer.function = cisco_timer; | 283 | st->timer.function = cisco_timer; |
280 | state(hdlc)->timer.data = arg; | 284 | st->timer.data = arg; |
281 | add_timer(&state(hdlc)->timer); | 285 | add_timer(&st->timer); |
282 | } | 286 | } |
283 | 287 | ||
284 | 288 | ||
@@ -286,15 +290,20 @@ static void cisco_timer(unsigned long arg) | |||
286 | static void cisco_start(struct net_device *dev) | 290 | static void cisco_start(struct net_device *dev) |
287 | { | 291 | { |
288 | hdlc_device *hdlc = dev_to_hdlc(dev); | 292 | hdlc_device *hdlc = dev_to_hdlc(dev); |
289 | state(hdlc)->up = 0; | 293 | struct cisco_state *st = state(hdlc); |
290 | state(hdlc)->request_sent = 0; | 294 | unsigned long flags; |
291 | state(hdlc)->txseq = state(hdlc)->rxseq = 0; | 295 | |
292 | 296 | spin_lock_irqsave(&st->lock, flags); | |
293 | init_timer(&state(hdlc)->timer); | 297 | st->up = 0; |
294 | state(hdlc)->timer.expires = jiffies + HZ; /*First poll after 1s*/ | 298 | st->request_sent = 0; |
295 | state(hdlc)->timer.function = cisco_timer; | 299 | st->txseq = st->rxseq = 0; |
296 | state(hdlc)->timer.data = (unsigned long)dev; | 300 | spin_unlock_irqrestore(&st->lock, flags); |
297 | add_timer(&state(hdlc)->timer); | 301 | |
302 | init_timer(&st->timer); | ||
303 | st->timer.expires = jiffies + HZ; /* First poll after 1 s */ | ||
304 | st->timer.function = cisco_timer; | ||
305 | st->timer.data = (unsigned long)dev; | ||
306 | add_timer(&st->timer); | ||
298 | } | 307 | } |
299 | 308 | ||
300 | 309 | ||
@@ -302,10 +311,16 @@ static void cisco_start(struct net_device *dev) | |||
302 | static void cisco_stop(struct net_device *dev) | 311 | static void cisco_stop(struct net_device *dev) |
303 | { | 312 | { |
304 | hdlc_device *hdlc = dev_to_hdlc(dev); | 313 | hdlc_device *hdlc = dev_to_hdlc(dev); |
305 | del_timer_sync(&state(hdlc)->timer); | 314 | struct cisco_state *st = state(hdlc); |
315 | unsigned long flags; | ||
316 | |||
317 | del_timer_sync(&st->timer); | ||
318 | |||
319 | spin_lock_irqsave(&st->lock, flags); | ||
306 | netif_dormant_on(dev); | 320 | netif_dormant_on(dev); |
307 | state(hdlc)->up = 0; | 321 | st->up = 0; |
308 | state(hdlc)->request_sent = 0; | 322 | st->request_sent = 0; |
323 | spin_unlock_irqrestore(&st->lock, flags); | ||
309 | } | 324 | } |
310 | 325 | ||
311 | 326 | ||
@@ -367,6 +382,7 @@ static int cisco_ioctl(struct net_device *dev, struct ifreq *ifr) | |||
367 | return result; | 382 | return result; |
368 | 383 | ||
369 | memcpy(&state(hdlc)->settings, &new_settings, size); | 384 | memcpy(&state(hdlc)->settings, &new_settings, size); |
385 | spin_lock_init(&state(hdlc)->lock); | ||
370 | dev->hard_start_xmit = hdlc->xmit; | 386 | dev->hard_start_xmit = hdlc->xmit; |
371 | dev->header_ops = &cisco_header_ops; | 387 | dev->header_ops = &cisco_header_ops; |
372 | dev->type = ARPHRD_CISCO; | 388 | dev->type = ARPHRD_CISCO; |
diff --git a/drivers/net/wan/hdlc_fr.c b/drivers/net/wan/hdlc_fr.c index 520bb0b1a9a2..6d35155c7145 100644 --- a/drivers/net/wan/hdlc_fr.c +++ b/drivers/net/wan/hdlc_fr.c | |||
@@ -1008,6 +1008,7 @@ static int fr_rx(struct sk_buff *skb) | |||
1008 | stats->rx_bytes += skb->len; | 1008 | stats->rx_bytes += skb->len; |
1009 | if (pvc->state.becn) | 1009 | if (pvc->state.becn) |
1010 | stats->rx_compressed++; | 1010 | stats->rx_compressed++; |
1011 | skb->dev = dev; | ||
1011 | netif_rx(skb); | 1012 | netif_rx(skb); |
1012 | return NET_RX_SUCCESS; | 1013 | return NET_RX_SUCCESS; |
1013 | } else { | 1014 | } else { |
diff --git a/drivers/net/wan/hdlc_ppp.c b/drivers/net/wan/hdlc_ppp.c index 10396d9686f4..00308337928e 100644 --- a/drivers/net/wan/hdlc_ppp.c +++ b/drivers/net/wan/hdlc_ppp.c | |||
@@ -45,7 +45,7 @@ static int ppp_open(struct net_device *dev) | |||
45 | int (*old_ioctl)(struct net_device *, struct ifreq *, int); | 45 | int (*old_ioctl)(struct net_device *, struct ifreq *, int); |
46 | int result; | 46 | int result; |
47 | 47 | ||
48 | dev->priv = &state(hdlc)->syncppp_ptr; | 48 | dev->ml_priv = &state(hdlc)->syncppp_ptr; |
49 | state(hdlc)->syncppp_ptr = &state(hdlc)->pppdev; | 49 | state(hdlc)->syncppp_ptr = &state(hdlc)->pppdev; |
50 | state(hdlc)->pppdev.dev = dev; | 50 | state(hdlc)->pppdev.dev = dev; |
51 | 51 | ||
diff --git a/drivers/net/wan/hostess_sv11.c b/drivers/net/wan/hostess_sv11.c index 83dbc924fcb5..f3065d3473fd 100644 --- a/drivers/net/wan/hostess_sv11.c +++ b/drivers/net/wan/hostess_sv11.c | |||
@@ -75,7 +75,7 @@ static void hostess_input(struct z8530_channel *c, struct sk_buff *skb) | |||
75 | 75 | ||
76 | static int hostess_open(struct net_device *d) | 76 | static int hostess_open(struct net_device *d) |
77 | { | 77 | { |
78 | struct sv11_device *sv11=d->priv; | 78 | struct sv11_device *sv11=d->ml_priv; |
79 | int err = -1; | 79 | int err = -1; |
80 | 80 | ||
81 | /* | 81 | /* |
@@ -128,7 +128,7 @@ static int hostess_open(struct net_device *d) | |||
128 | 128 | ||
129 | static int hostess_close(struct net_device *d) | 129 | static int hostess_close(struct net_device *d) |
130 | { | 130 | { |
131 | struct sv11_device *sv11=d->priv; | 131 | struct sv11_device *sv11=d->ml_priv; |
132 | /* | 132 | /* |
133 | * Discard new frames | 133 | * Discard new frames |
134 | */ | 134 | */ |
@@ -159,14 +159,14 @@ static int hostess_close(struct net_device *d) | |||
159 | 159 | ||
160 | static int hostess_ioctl(struct net_device *d, struct ifreq *ifr, int cmd) | 160 | static int hostess_ioctl(struct net_device *d, struct ifreq *ifr, int cmd) |
161 | { | 161 | { |
162 | /* struct sv11_device *sv11=d->priv; | 162 | /* struct sv11_device *sv11=d->ml_priv; |
163 | z8530_ioctl(d,&sv11->sync.chanA,ifr,cmd) */ | 163 | z8530_ioctl(d,&sv11->sync.chanA,ifr,cmd) */ |
164 | return sppp_do_ioctl(d, ifr,cmd); | 164 | return sppp_do_ioctl(d, ifr,cmd); |
165 | } | 165 | } |
166 | 166 | ||
167 | static struct net_device_stats *hostess_get_stats(struct net_device *d) | 167 | static struct net_device_stats *hostess_get_stats(struct net_device *d) |
168 | { | 168 | { |
169 | struct sv11_device *sv11=d->priv; | 169 | struct sv11_device *sv11=d->ml_priv; |
170 | if(sv11) | 170 | if(sv11) |
171 | return z8530_get_stats(&sv11->sync.chanA); | 171 | return z8530_get_stats(&sv11->sync.chanA); |
172 | else | 172 | else |
@@ -179,7 +179,7 @@ static struct net_device_stats *hostess_get_stats(struct net_device *d) | |||
179 | 179 | ||
180 | static int hostess_queue_xmit(struct sk_buff *skb, struct net_device *d) | 180 | static int hostess_queue_xmit(struct sk_buff *skb, struct net_device *d) |
181 | { | 181 | { |
182 | struct sv11_device *sv11=d->priv; | 182 | struct sv11_device *sv11=d->ml_priv; |
183 | return z8530_queue_xmit(&sv11->sync.chanA, skb); | 183 | return z8530_queue_xmit(&sv11->sync.chanA, skb); |
184 | } | 184 | } |
185 | 185 | ||
@@ -325,6 +325,7 @@ static struct sv11_device *sv11_init(int iobase, int irq) | |||
325 | /* | 325 | /* |
326 | * Initialise the PPP components | 326 | * Initialise the PPP components |
327 | */ | 327 | */ |
328 | d->ml_priv = sv; | ||
328 | sppp_attach(&sv->netdev); | 329 | sppp_attach(&sv->netdev); |
329 | 330 | ||
330 | /* | 331 | /* |
@@ -333,7 +334,6 @@ static struct sv11_device *sv11_init(int iobase, int irq) | |||
333 | 334 | ||
334 | d->base_addr = iobase; | 335 | d->base_addr = iobase; |
335 | d->irq = irq; | 336 | d->irq = irq; |
336 | d->priv = sv; | ||
337 | 337 | ||
338 | if(register_netdev(d)) | 338 | if(register_netdev(d)) |
339 | { | 339 | { |
diff --git a/drivers/net/wan/lapbether.c b/drivers/net/wan/lapbether.c index b5860b97a93e..24fd613466b7 100644 --- a/drivers/net/wan/lapbether.c +++ b/drivers/net/wan/lapbether.c | |||
@@ -459,6 +459,7 @@ static void __exit lapbeth_cleanup_driver(void) | |||
459 | list_for_each_safe(entry, tmp, &lapbeth_devices) { | 459 | list_for_each_safe(entry, tmp, &lapbeth_devices) { |
460 | lapbeth = list_entry(entry, struct lapbethdev, node); | 460 | lapbeth = list_entry(entry, struct lapbethdev, node); |
461 | 461 | ||
462 | dev_put(lapbeth->ethdev); | ||
462 | unregister_netdevice(lapbeth->axdev); | 463 | unregister_netdevice(lapbeth->axdev); |
463 | } | 464 | } |
464 | rtnl_unlock(); | 465 | rtnl_unlock(); |
diff --git a/drivers/net/wan/lmc/lmc_main.c b/drivers/net/wan/lmc/lmc_main.c index 6635ecef36e5..62133cee446a 100644 --- a/drivers/net/wan/lmc/lmc_main.c +++ b/drivers/net/wan/lmc/lmc_main.c | |||
@@ -891,6 +891,7 @@ static int __devinit lmc_init_one(struct pci_dev *pdev, | |||
891 | 891 | ||
892 | /* Initialize the sppp layer */ | 892 | /* Initialize the sppp layer */ |
893 | /* An ioctl can cause a subsequent detach for raw frame interface */ | 893 | /* An ioctl can cause a subsequent detach for raw frame interface */ |
894 | dev->ml_priv = sc; | ||
894 | sc->if_type = LMC_PPP; | 895 | sc->if_type = LMC_PPP; |
895 | sc->check = 0xBEAFCAFE; | 896 | sc->check = 0xBEAFCAFE; |
896 | dev->base_addr = pci_resource_start(pdev, 0); | 897 | dev->base_addr = pci_resource_start(pdev, 0); |
diff --git a/drivers/net/wan/sealevel.c b/drivers/net/wan/sealevel.c index 11276bf3149f..44a89df1b8bf 100644 --- a/drivers/net/wan/sealevel.c +++ b/drivers/net/wan/sealevel.c | |||
@@ -241,6 +241,7 @@ static inline struct slvl_device *slvl_alloc(int iobase, int irq) | |||
241 | return NULL; | 241 | return NULL; |
242 | 242 | ||
243 | sv = d->priv; | 243 | sv = d->priv; |
244 | d->ml_priv = sv; | ||
244 | sv->if_ptr = &sv->pppdev; | 245 | sv->if_ptr = &sv->pppdev; |
245 | sv->pppdev.dev = d; | 246 | sv->pppdev.dev = d; |
246 | d->base_addr = iobase; | 247 | d->base_addr = iobase; |
diff --git a/drivers/net/wan/x25_asy.c b/drivers/net/wan/x25_asy.c index 249e18053d5f..069f8bb0a99f 100644 --- a/drivers/net/wan/x25_asy.c +++ b/drivers/net/wan/x25_asy.c | |||
@@ -32,6 +32,7 @@ | |||
32 | #include <linux/x25.h> | 32 | #include <linux/x25.h> |
33 | #include <linux/lapb.h> | 33 | #include <linux/lapb.h> |
34 | #include <linux/init.h> | 34 | #include <linux/init.h> |
35 | #include <linux/rtnetlink.h> | ||
35 | #include "x25_asy.h" | 36 | #include "x25_asy.h" |
36 | 37 | ||
37 | #include <net/x25device.h> | 38 | #include <net/x25device.h> |
@@ -601,8 +602,10 @@ static void x25_asy_close_tty(struct tty_struct *tty) | |||
601 | if (!sl || sl->magic != X25_ASY_MAGIC) | 602 | if (!sl || sl->magic != X25_ASY_MAGIC) |
602 | return; | 603 | return; |
603 | 604 | ||
605 | rtnl_lock(); | ||
604 | if (sl->dev->flags & IFF_UP) | 606 | if (sl->dev->flags & IFF_UP) |
605 | dev_close(sl->dev); | 607 | dev_close(sl->dev); |
608 | rtnl_unlock(); | ||
606 | 609 | ||
607 | tty->disc_data = NULL; | 610 | tty->disc_data = NULL; |
608 | sl->tty = NULL; | 611 | sl->tty = NULL; |
diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c index 45f47c1c0a35..32019fb878d8 100644 --- a/drivers/net/wireless/airo.c +++ b/drivers/net/wireless/airo.c | |||
@@ -2668,6 +2668,7 @@ static struct net_device *init_wifidev(struct airo_info *ai, | |||
2668 | dev->irq = ethdev->irq; | 2668 | dev->irq = ethdev->irq; |
2669 | dev->base_addr = ethdev->base_addr; | 2669 | dev->base_addr = ethdev->base_addr; |
2670 | dev->wireless_data = ethdev->wireless_data; | 2670 | dev->wireless_data = ethdev->wireless_data; |
2671 | SET_NETDEV_DEV(dev, ethdev->dev.parent); | ||
2671 | memcpy(dev->dev_addr, ethdev->dev_addr, dev->addr_len); | 2672 | memcpy(dev->dev_addr, ethdev->dev_addr, dev->addr_len); |
2672 | err = register_netdev(dev); | 2673 | err = register_netdev(dev); |
2673 | if (err<0) { | 2674 | if (err<0) { |
@@ -2904,7 +2905,7 @@ EXPORT_SYMBOL(init_airo_card); | |||
2904 | 2905 | ||
2905 | static int waitbusy (struct airo_info *ai) { | 2906 | static int waitbusy (struct airo_info *ai) { |
2906 | int delay = 0; | 2907 | int delay = 0; |
2907 | while ((IN4500 (ai, COMMAND) & COMMAND_BUSY) & (delay < 10000)) { | 2908 | while ((IN4500(ai, COMMAND) & COMMAND_BUSY) && (delay < 10000)) { |
2908 | udelay (10); | 2909 | udelay (10); |
2909 | if ((++delay % 20) == 0) | 2910 | if ((++delay % 20) == 0) |
2910 | OUT4500(ai, EVACK, EV_CLEARCOMMANDBUSY); | 2911 | OUT4500(ai, EVACK, EV_CLEARCOMMANDBUSY); |
diff --git a/drivers/net/wireless/ath5k/base.c b/drivers/net/wireless/ath5k/base.c index 4e5c8fc35200..635b9ac9aaa1 100644 --- a/drivers/net/wireless/ath5k/base.c +++ b/drivers/net/wireless/ath5k/base.c | |||
@@ -1787,6 +1787,8 @@ ath5k_tasklet_rx(unsigned long data) | |||
1787 | 1787 | ||
1788 | spin_lock(&sc->rxbuflock); | 1788 | spin_lock(&sc->rxbuflock); |
1789 | do { | 1789 | do { |
1790 | rxs.flag = 0; | ||
1791 | |||
1790 | if (unlikely(list_empty(&sc->rxbuf))) { | 1792 | if (unlikely(list_empty(&sc->rxbuf))) { |
1791 | ATH5K_WARN(sc, "empty rx buf pool\n"); | 1793 | ATH5K_WARN(sc, "empty rx buf pool\n"); |
1792 | break; | 1794 | break; |
diff --git a/drivers/net/wireless/ath5k/hw.c b/drivers/net/wireless/ath5k/hw.c index 5fb1ae6ad3e2..77990b56860b 100644 --- a/drivers/net/wireless/ath5k/hw.c +++ b/drivers/net/wireless/ath5k/hw.c | |||
@@ -4119,6 +4119,7 @@ static int ath5k_hw_proc_5210_rx_status(struct ath5k_hw *ah, | |||
4119 | rs->rs_tstamp = AR5K_REG_MS(rx_status->rx_status_1, | 4119 | rs->rs_tstamp = AR5K_REG_MS(rx_status->rx_status_1, |
4120 | AR5K_5210_RX_DESC_STATUS1_RECEIVE_TIMESTAMP); | 4120 | AR5K_5210_RX_DESC_STATUS1_RECEIVE_TIMESTAMP); |
4121 | rs->rs_status = 0; | 4121 | rs->rs_status = 0; |
4122 | rs->rs_phyerr = 0; | ||
4122 | 4123 | ||
4123 | /* | 4124 | /* |
4124 | * Key table status | 4125 | * Key table status |
@@ -4145,7 +4146,7 @@ static int ath5k_hw_proc_5210_rx_status(struct ath5k_hw *ah, | |||
4145 | if (rx_status->rx_status_1 & | 4146 | if (rx_status->rx_status_1 & |
4146 | AR5K_5210_RX_DESC_STATUS1_PHY_ERROR) { | 4147 | AR5K_5210_RX_DESC_STATUS1_PHY_ERROR) { |
4147 | rs->rs_status |= AR5K_RXERR_PHY; | 4148 | rs->rs_status |= AR5K_RXERR_PHY; |
4148 | rs->rs_phyerr = AR5K_REG_MS(rx_status->rx_status_1, | 4149 | rs->rs_phyerr |= AR5K_REG_MS(rx_status->rx_status_1, |
4149 | AR5K_5210_RX_DESC_STATUS1_PHY_ERROR); | 4150 | AR5K_5210_RX_DESC_STATUS1_PHY_ERROR); |
4150 | } | 4151 | } |
4151 | 4152 | ||
@@ -4193,6 +4194,7 @@ static int ath5k_hw_proc_5212_rx_status(struct ath5k_hw *ah, | |||
4193 | rs->rs_tstamp = AR5K_REG_MS(rx_status->rx_status_1, | 4194 | rs->rs_tstamp = AR5K_REG_MS(rx_status->rx_status_1, |
4194 | AR5K_5212_RX_DESC_STATUS1_RECEIVE_TIMESTAMP); | 4195 | AR5K_5212_RX_DESC_STATUS1_RECEIVE_TIMESTAMP); |
4195 | rs->rs_status = 0; | 4196 | rs->rs_status = 0; |
4197 | rs->rs_phyerr = 0; | ||
4196 | 4198 | ||
4197 | /* | 4199 | /* |
4198 | * Key table status | 4200 | * Key table status |
@@ -4215,7 +4217,7 @@ static int ath5k_hw_proc_5212_rx_status(struct ath5k_hw *ah, | |||
4215 | if (rx_status->rx_status_1 & | 4217 | if (rx_status->rx_status_1 & |
4216 | AR5K_5212_RX_DESC_STATUS1_PHY_ERROR) { | 4218 | AR5K_5212_RX_DESC_STATUS1_PHY_ERROR) { |
4217 | rs->rs_status |= AR5K_RXERR_PHY; | 4219 | rs->rs_status |= AR5K_RXERR_PHY; |
4218 | rs->rs_phyerr = AR5K_REG_MS(rx_err->rx_error_1, | 4220 | rs->rs_phyerr |= AR5K_REG_MS(rx_err->rx_error_1, |
4219 | AR5K_RX_DESC_ERROR1_PHY_ERROR_CODE); | 4221 | AR5K_RX_DESC_ERROR1_PHY_ERROR_CODE); |
4220 | } | 4222 | } |
4221 | 4223 | ||
diff --git a/drivers/net/wireless/atmel.c b/drivers/net/wireless/atmel.c index ef2da4023d68..438e63ecccf1 100644 --- a/drivers/net/wireless/atmel.c +++ b/drivers/net/wireless/atmel.c | |||
@@ -47,6 +47,7 @@ | |||
47 | #include <linux/string.h> | 47 | #include <linux/string.h> |
48 | #include <linux/ctype.h> | 48 | #include <linux/ctype.h> |
49 | #include <linux/timer.h> | 49 | #include <linux/timer.h> |
50 | #include <asm/byteorder.h> | ||
50 | #include <asm/io.h> | 51 | #include <asm/io.h> |
51 | #include <asm/system.h> | 52 | #include <asm/system.h> |
52 | #include <asm/uaccess.h> | 53 | #include <asm/uaccess.h> |
@@ -60,7 +61,6 @@ | |||
60 | #include <linux/delay.h> | 61 | #include <linux/delay.h> |
61 | #include <linux/wireless.h> | 62 | #include <linux/wireless.h> |
62 | #include <net/iw_handler.h> | 63 | #include <net/iw_handler.h> |
63 | #include <linux/byteorder/generic.h> | ||
64 | #include <linux/crc32.h> | 64 | #include <linux/crc32.h> |
65 | #include <linux/proc_fs.h> | 65 | #include <linux/proc_fs.h> |
66 | #include <linux/device.h> | 66 | #include <linux/device.h> |
diff --git a/drivers/net/wireless/b43/Kconfig b/drivers/net/wireless/b43/Kconfig index f51b2d9b085b..1fa043d1802c 100644 --- a/drivers/net/wireless/b43/Kconfig +++ b/drivers/net/wireless/b43/Kconfig | |||
@@ -1,6 +1,6 @@ | |||
1 | config B43 | 1 | config B43 |
2 | tristate "Broadcom 43xx wireless support (mac80211 stack)" | 2 | tristate "Broadcom 43xx wireless support (mac80211 stack)" |
3 | depends on SSB_POSSIBLE && MAC80211 && WLAN_80211 | 3 | depends on SSB_POSSIBLE && MAC80211 && WLAN_80211 && HAS_DMA |
4 | select SSB | 4 | select SSB |
5 | select FW_LOADER | 5 | select FW_LOADER |
6 | select HW_RANDOM | 6 | select HW_RANDOM |
diff --git a/drivers/net/wireless/b43/b43.h b/drivers/net/wireless/b43/b43.h index eff2a158a411..d3db298c05fc 100644 --- a/drivers/net/wireless/b43/b43.h +++ b/drivers/net/wireless/b43/b43.h | |||
@@ -630,7 +630,6 @@ struct b43_pio { | |||
630 | 630 | ||
631 | /* Context information for a noise calculation (Link Quality). */ | 631 | /* Context information for a noise calculation (Link Quality). */ |
632 | struct b43_noise_calculation { | 632 | struct b43_noise_calculation { |
633 | u8 channel_at_start; | ||
634 | bool calculation_running; | 633 | bool calculation_running; |
635 | u8 nr_samples; | 634 | u8 nr_samples; |
636 | s8 samples[8][4]; | 635 | s8 samples[8][4]; |
@@ -691,6 +690,10 @@ struct b43_wl { | |||
691 | 690 | ||
692 | struct mutex mutex; | 691 | struct mutex mutex; |
693 | spinlock_t irq_lock; | 692 | spinlock_t irq_lock; |
693 | /* R/W lock for data transmission. | ||
694 | * Transmissions on 2+ queues can run concurrently, but somebody else | ||
695 | * might sync with TX by write_lock_irqsave()'ing. */ | ||
696 | rwlock_t tx_lock; | ||
694 | /* Lock for LEDs access. */ | 697 | /* Lock for LEDs access. */ |
695 | spinlock_t leds_lock; | 698 | spinlock_t leds_lock; |
696 | /* Lock for SHM access. */ | 699 | /* Lock for SHM access. */ |
@@ -733,6 +736,7 @@ struct b43_wl { | |||
733 | struct ieee80211_tx_control beacon_txctl; | 736 | struct ieee80211_tx_control beacon_txctl; |
734 | bool beacon0_uploaded; | 737 | bool beacon0_uploaded; |
735 | bool beacon1_uploaded; | 738 | bool beacon1_uploaded; |
739 | bool beacon_templates_virgin; /* Never wrote the templates? */ | ||
736 | struct work_struct beacon_update_trigger; | 740 | struct work_struct beacon_update_trigger; |
737 | 741 | ||
738 | /* The current QOS parameters for the 4 queues. | 742 | /* The current QOS parameters for the 4 queues. |
diff --git a/drivers/net/wireless/b43/dma.c b/drivers/net/wireless/b43/dma.c index 6dcbb3c87e72..e23f2f172bd7 100644 --- a/drivers/net/wireless/b43/dma.c +++ b/drivers/net/wireless/b43/dma.c | |||
@@ -795,24 +795,49 @@ struct b43_dmaring *b43_setup_dmaring(struct b43_wldev *dev, | |||
795 | { | 795 | { |
796 | struct b43_dmaring *ring; | 796 | struct b43_dmaring *ring; |
797 | int err; | 797 | int err; |
798 | int nr_slots; | ||
799 | dma_addr_t dma_test; | 798 | dma_addr_t dma_test; |
800 | 799 | ||
801 | ring = kzalloc(sizeof(*ring), GFP_KERNEL); | 800 | ring = kzalloc(sizeof(*ring), GFP_KERNEL); |
802 | if (!ring) | 801 | if (!ring) |
803 | goto out; | 802 | goto out; |
804 | ring->type = type; | ||
805 | 803 | ||
806 | nr_slots = B43_RXRING_SLOTS; | 804 | ring->nr_slots = B43_RXRING_SLOTS; |
807 | if (for_tx) | 805 | if (for_tx) |
808 | nr_slots = B43_TXRING_SLOTS; | 806 | ring->nr_slots = B43_TXRING_SLOTS; |
809 | 807 | ||
810 | ring->meta = kcalloc(nr_slots, sizeof(struct b43_dmadesc_meta), | 808 | ring->meta = kcalloc(ring->nr_slots, sizeof(struct b43_dmadesc_meta), |
811 | GFP_KERNEL); | 809 | GFP_KERNEL); |
812 | if (!ring->meta) | 810 | if (!ring->meta) |
813 | goto err_kfree_ring; | 811 | goto err_kfree_ring; |
812 | |||
813 | ring->type = type; | ||
814 | ring->dev = dev; | ||
815 | ring->mmio_base = b43_dmacontroller_base(type, controller_index); | ||
816 | ring->index = controller_index; | ||
817 | if (type == B43_DMA_64BIT) | ||
818 | ring->ops = &dma64_ops; | ||
819 | else | ||
820 | ring->ops = &dma32_ops; | ||
814 | if (for_tx) { | 821 | if (for_tx) { |
815 | ring->txhdr_cache = kcalloc(nr_slots, | 822 | ring->tx = 1; |
823 | ring->current_slot = -1; | ||
824 | } else { | ||
825 | if (ring->index == 0) { | ||
826 | ring->rx_buffersize = B43_DMA0_RX_BUFFERSIZE; | ||
827 | ring->frameoffset = B43_DMA0_RX_FRAMEOFFSET; | ||
828 | } else if (ring->index == 3) { | ||
829 | ring->rx_buffersize = B43_DMA3_RX_BUFFERSIZE; | ||
830 | ring->frameoffset = B43_DMA3_RX_FRAMEOFFSET; | ||
831 | } else | ||
832 | B43_WARN_ON(1); | ||
833 | } | ||
834 | spin_lock_init(&ring->lock); | ||
835 | #ifdef CONFIG_B43_DEBUG | ||
836 | ring->last_injected_overflow = jiffies; | ||
837 | #endif | ||
838 | |||
839 | if (for_tx) { | ||
840 | ring->txhdr_cache = kcalloc(ring->nr_slots, | ||
816 | b43_txhdr_size(dev), | 841 | b43_txhdr_size(dev), |
817 | GFP_KERNEL); | 842 | GFP_KERNEL); |
818 | if (!ring->txhdr_cache) | 843 | if (!ring->txhdr_cache) |
@@ -828,7 +853,7 @@ struct b43_dmaring *b43_setup_dmaring(struct b43_wldev *dev, | |||
828 | b43_txhdr_size(dev), 1)) { | 853 | b43_txhdr_size(dev), 1)) { |
829 | /* ugh realloc */ | 854 | /* ugh realloc */ |
830 | kfree(ring->txhdr_cache); | 855 | kfree(ring->txhdr_cache); |
831 | ring->txhdr_cache = kcalloc(nr_slots, | 856 | ring->txhdr_cache = kcalloc(ring->nr_slots, |
832 | b43_txhdr_size(dev), | 857 | b43_txhdr_size(dev), |
833 | GFP_KERNEL | GFP_DMA); | 858 | GFP_KERNEL | GFP_DMA); |
834 | if (!ring->txhdr_cache) | 859 | if (!ring->txhdr_cache) |
@@ -853,32 +878,6 @@ struct b43_dmaring *b43_setup_dmaring(struct b43_wldev *dev, | |||
853 | DMA_TO_DEVICE); | 878 | DMA_TO_DEVICE); |
854 | } | 879 | } |
855 | 880 | ||
856 | ring->dev = dev; | ||
857 | ring->nr_slots = nr_slots; | ||
858 | ring->mmio_base = b43_dmacontroller_base(type, controller_index); | ||
859 | ring->index = controller_index; | ||
860 | if (type == B43_DMA_64BIT) | ||
861 | ring->ops = &dma64_ops; | ||
862 | else | ||
863 | ring->ops = &dma32_ops; | ||
864 | if (for_tx) { | ||
865 | ring->tx = 1; | ||
866 | ring->current_slot = -1; | ||
867 | } else { | ||
868 | if (ring->index == 0) { | ||
869 | ring->rx_buffersize = B43_DMA0_RX_BUFFERSIZE; | ||
870 | ring->frameoffset = B43_DMA0_RX_FRAMEOFFSET; | ||
871 | } else if (ring->index == 3) { | ||
872 | ring->rx_buffersize = B43_DMA3_RX_BUFFERSIZE; | ||
873 | ring->frameoffset = B43_DMA3_RX_FRAMEOFFSET; | ||
874 | } else | ||
875 | B43_WARN_ON(1); | ||
876 | } | ||
877 | spin_lock_init(&ring->lock); | ||
878 | #ifdef CONFIG_B43_DEBUG | ||
879 | ring->last_injected_overflow = jiffies; | ||
880 | #endif | ||
881 | |||
882 | err = alloc_ringmemory(ring); | 881 | err = alloc_ringmemory(ring); |
883 | if (err) | 882 | if (err) |
884 | goto err_kfree_txhdr_cache; | 883 | goto err_kfree_txhdr_cache; |
diff --git a/drivers/net/wireless/b43/leds.c b/drivers/net/wireless/b43/leds.c index 36a9c42df835..76f4c7bad8b8 100644 --- a/drivers/net/wireless/b43/leds.c +++ b/drivers/net/wireless/b43/leds.c | |||
@@ -72,6 +72,9 @@ static void b43_led_brightness_set(struct led_classdev *led_dev, | |||
72 | struct b43_wldev *dev = led->dev; | 72 | struct b43_wldev *dev = led->dev; |
73 | bool radio_enabled; | 73 | bool radio_enabled; |
74 | 74 | ||
75 | if (unlikely(b43_status(dev) < B43_STAT_INITIALIZED)) | ||
76 | return; | ||
77 | |||
75 | /* Checking the radio-enabled status here is slightly racy, | 78 | /* Checking the radio-enabled status here is slightly racy, |
76 | * but we want to avoid the locking overhead and we don't care | 79 | * but we want to avoid the locking overhead and we don't care |
77 | * whether the LED has the wrong state for a second. */ | 80 | * whether the LED has the wrong state for a second. */ |
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index 8c24cd72aaca..a70827793086 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c | |||
@@ -729,6 +729,7 @@ static void b43_synchronize_irq(struct b43_wldev *dev) | |||
729 | */ | 729 | */ |
730 | void b43_dummy_transmission(struct b43_wldev *dev) | 730 | void b43_dummy_transmission(struct b43_wldev *dev) |
731 | { | 731 | { |
732 | struct b43_wl *wl = dev->wl; | ||
732 | struct b43_phy *phy = &dev->phy; | 733 | struct b43_phy *phy = &dev->phy; |
733 | unsigned int i, max_loop; | 734 | unsigned int i, max_loop; |
734 | u16 value; | 735 | u16 value; |
@@ -755,6 +756,9 @@ void b43_dummy_transmission(struct b43_wldev *dev) | |||
755 | return; | 756 | return; |
756 | } | 757 | } |
757 | 758 | ||
759 | spin_lock_irq(&wl->irq_lock); | ||
760 | write_lock(&wl->tx_lock); | ||
761 | |||
758 | for (i = 0; i < 5; i++) | 762 | for (i = 0; i < 5; i++) |
759 | b43_ram_write(dev, i * 4, buffer[i]); | 763 | b43_ram_write(dev, i * 4, buffer[i]); |
760 | 764 | ||
@@ -795,6 +799,9 @@ void b43_dummy_transmission(struct b43_wldev *dev) | |||
795 | } | 799 | } |
796 | if (phy->radio_ver == 0x2050 && phy->radio_rev <= 0x5) | 800 | if (phy->radio_ver == 0x2050 && phy->radio_rev <= 0x5) |
797 | b43_radio_write16(dev, 0x0051, 0x0037); | 801 | b43_radio_write16(dev, 0x0051, 0x0037); |
802 | |||
803 | write_unlock(&wl->tx_lock); | ||
804 | spin_unlock_irq(&wl->irq_lock); | ||
798 | } | 805 | } |
799 | 806 | ||
800 | static void key_write(struct b43_wldev *dev, | 807 | static void key_write(struct b43_wldev *dev, |
@@ -1138,7 +1145,6 @@ static void b43_generate_noise_sample(struct b43_wldev *dev) | |||
1138 | b43_jssi_write(dev, 0x7F7F7F7F); | 1145 | b43_jssi_write(dev, 0x7F7F7F7F); |
1139 | b43_write32(dev, B43_MMIO_MACCMD, | 1146 | b43_write32(dev, B43_MMIO_MACCMD, |
1140 | b43_read32(dev, B43_MMIO_MACCMD) | B43_MACCMD_BGNOISE); | 1147 | b43_read32(dev, B43_MMIO_MACCMD) | B43_MACCMD_BGNOISE); |
1141 | B43_WARN_ON(dev->noisecalc.channel_at_start != dev->phy.channel); | ||
1142 | } | 1148 | } |
1143 | 1149 | ||
1144 | static void b43_calculate_link_quality(struct b43_wldev *dev) | 1150 | static void b43_calculate_link_quality(struct b43_wldev *dev) |
@@ -1147,7 +1153,6 @@ static void b43_calculate_link_quality(struct b43_wldev *dev) | |||
1147 | 1153 | ||
1148 | if (dev->noisecalc.calculation_running) | 1154 | if (dev->noisecalc.calculation_running) |
1149 | return; | 1155 | return; |
1150 | dev->noisecalc.channel_at_start = dev->phy.channel; | ||
1151 | dev->noisecalc.calculation_running = 1; | 1156 | dev->noisecalc.calculation_running = 1; |
1152 | dev->noisecalc.nr_samples = 0; | 1157 | dev->noisecalc.nr_samples = 0; |
1153 | 1158 | ||
@@ -1164,9 +1169,16 @@ static void handle_irq_noise(struct b43_wldev *dev) | |||
1164 | 1169 | ||
1165 | /* Bottom half of Link Quality calculation. */ | 1170 | /* Bottom half of Link Quality calculation. */ |
1166 | 1171 | ||
1172 | /* Possible race condition: It might be possible that the user | ||
1173 | * changed to a different channel in the meantime since we | ||
1174 | * started the calculation. We ignore that fact, since it's | ||
1175 | * not really that much of a problem. The background noise is | ||
1176 | * an estimation only anyway. Slightly wrong results will get damped | ||
1177 | * by the averaging of the 8 sample rounds. Additionally the | ||
1178 | * value is shortlived. So it will be replaced by the next noise | ||
1179 | * calculation round soon. */ | ||
1180 | |||
1167 | B43_WARN_ON(!dev->noisecalc.calculation_running); | 1181 | B43_WARN_ON(!dev->noisecalc.calculation_running); |
1168 | if (dev->noisecalc.channel_at_start != phy->channel) | ||
1169 | goto drop_calculation; | ||
1170 | *((__le32 *)noise) = cpu_to_le32(b43_jssi_read(dev)); | 1182 | *((__le32 *)noise) = cpu_to_le32(b43_jssi_read(dev)); |
1171 | if (noise[0] == 0x7F || noise[1] == 0x7F || | 1183 | if (noise[0] == 0x7F || noise[1] == 0x7F || |
1172 | noise[2] == 0x7F || noise[3] == 0x7F) | 1184 | noise[2] == 0x7F || noise[3] == 0x7F) |
@@ -1207,11 +1219,10 @@ static void handle_irq_noise(struct b43_wldev *dev) | |||
1207 | average -= 48; | 1219 | average -= 48; |
1208 | 1220 | ||
1209 | dev->stats.link_noise = average; | 1221 | dev->stats.link_noise = average; |
1210 | drop_calculation: | ||
1211 | dev->noisecalc.calculation_running = 0; | 1222 | dev->noisecalc.calculation_running = 0; |
1212 | return; | 1223 | return; |
1213 | } | 1224 | } |
1214 | generate_new: | 1225 | generate_new: |
1215 | b43_generate_noise_sample(dev); | 1226 | b43_generate_noise_sample(dev); |
1216 | } | 1227 | } |
1217 | 1228 | ||
@@ -1537,6 +1548,30 @@ static void b43_write_probe_resp_template(struct b43_wldev *dev, | |||
1537 | kfree(probe_resp_data); | 1548 | kfree(probe_resp_data); |
1538 | } | 1549 | } |
1539 | 1550 | ||
1551 | static void b43_upload_beacon0(struct b43_wldev *dev) | ||
1552 | { | ||
1553 | struct b43_wl *wl = dev->wl; | ||
1554 | |||
1555 | if (wl->beacon0_uploaded) | ||
1556 | return; | ||
1557 | b43_write_beacon_template(dev, 0x68, 0x18); | ||
1558 | /* FIXME: Probe resp upload doesn't really belong here, | ||
1559 | * but we don't use that feature anyway. */ | ||
1560 | b43_write_probe_resp_template(dev, 0x268, 0x4A, | ||
1561 | &__b43_ratetable[3]); | ||
1562 | wl->beacon0_uploaded = 1; | ||
1563 | } | ||
1564 | |||
1565 | static void b43_upload_beacon1(struct b43_wldev *dev) | ||
1566 | { | ||
1567 | struct b43_wl *wl = dev->wl; | ||
1568 | |||
1569 | if (wl->beacon1_uploaded) | ||
1570 | return; | ||
1571 | b43_write_beacon_template(dev, 0x468, 0x1A); | ||
1572 | wl->beacon1_uploaded = 1; | ||
1573 | } | ||
1574 | |||
1540 | static void handle_irq_beacon(struct b43_wldev *dev) | 1575 | static void handle_irq_beacon(struct b43_wldev *dev) |
1541 | { | 1576 | { |
1542 | struct b43_wl *wl = dev->wl; | 1577 | struct b43_wl *wl = dev->wl; |
@@ -1561,24 +1596,27 @@ static void handle_irq_beacon(struct b43_wldev *dev) | |||
1561 | return; | 1596 | return; |
1562 | } | 1597 | } |
1563 | 1598 | ||
1564 | if (!beacon0_valid) { | 1599 | if (unlikely(wl->beacon_templates_virgin)) { |
1565 | if (!wl->beacon0_uploaded) { | 1600 | /* We never uploaded a beacon before. |
1566 | b43_write_beacon_template(dev, 0x68, 0x18); | 1601 | * Upload both templates now, but only mark one valid. */ |
1567 | b43_write_probe_resp_template(dev, 0x268, 0x4A, | 1602 | wl->beacon_templates_virgin = 0; |
1568 | &__b43_ratetable[3]); | 1603 | b43_upload_beacon0(dev); |
1569 | wl->beacon0_uploaded = 1; | 1604 | b43_upload_beacon1(dev); |
1570 | } | ||
1571 | cmd = b43_read32(dev, B43_MMIO_MACCMD); | 1605 | cmd = b43_read32(dev, B43_MMIO_MACCMD); |
1572 | cmd |= B43_MACCMD_BEACON0_VALID; | 1606 | cmd |= B43_MACCMD_BEACON0_VALID; |
1573 | b43_write32(dev, B43_MMIO_MACCMD, cmd); | 1607 | b43_write32(dev, B43_MMIO_MACCMD, cmd); |
1574 | } else if (!beacon1_valid) { | 1608 | } else { |
1575 | if (!wl->beacon1_uploaded) { | 1609 | if (!beacon0_valid) { |
1576 | b43_write_beacon_template(dev, 0x468, 0x1A); | 1610 | b43_upload_beacon0(dev); |
1577 | wl->beacon1_uploaded = 1; | 1611 | cmd = b43_read32(dev, B43_MMIO_MACCMD); |
1612 | cmd |= B43_MACCMD_BEACON0_VALID; | ||
1613 | b43_write32(dev, B43_MMIO_MACCMD, cmd); | ||
1614 | } else if (!beacon1_valid) { | ||
1615 | b43_upload_beacon1(dev); | ||
1616 | cmd = b43_read32(dev, B43_MMIO_MACCMD); | ||
1617 | cmd |= B43_MACCMD_BEACON1_VALID; | ||
1618 | b43_write32(dev, B43_MMIO_MACCMD, cmd); | ||
1578 | } | 1619 | } |
1579 | cmd = b43_read32(dev, B43_MMIO_MACCMD); | ||
1580 | cmd |= B43_MACCMD_BEACON1_VALID; | ||
1581 | b43_write32(dev, B43_MMIO_MACCMD, cmd); | ||
1582 | } | 1620 | } |
1583 | } | 1621 | } |
1584 | 1622 | ||
@@ -2840,26 +2878,37 @@ static int b43_op_tx(struct ieee80211_hw *hw, | |||
2840 | { | 2878 | { |
2841 | struct b43_wl *wl = hw_to_b43_wl(hw); | 2879 | struct b43_wl *wl = hw_to_b43_wl(hw); |
2842 | struct b43_wldev *dev = wl->current_dev; | 2880 | struct b43_wldev *dev = wl->current_dev; |
2843 | int err = -ENODEV; | 2881 | unsigned long flags; |
2882 | int err; | ||
2844 | 2883 | ||
2845 | if (unlikely(skb->len < 2 + 2 + 6)) { | 2884 | if (unlikely(skb->len < 2 + 2 + 6)) { |
2846 | /* Too short, this can't be a valid frame. */ | 2885 | /* Too short, this can't be a valid frame. */ |
2847 | return -EINVAL; | 2886 | goto drop_packet; |
2848 | } | 2887 | } |
2849 | B43_WARN_ON(skb_shinfo(skb)->nr_frags); | 2888 | B43_WARN_ON(skb_shinfo(skb)->nr_frags); |
2850 | |||
2851 | if (unlikely(!dev)) | 2889 | if (unlikely(!dev)) |
2852 | goto out; | 2890 | goto drop_packet; |
2853 | if (unlikely(b43_status(dev) < B43_STAT_STARTED)) | 2891 | |
2854 | goto out; | 2892 | /* Transmissions on seperate queues can run concurrently. */ |
2855 | /* TX is done without a global lock. */ | 2893 | read_lock_irqsave(&wl->tx_lock, flags); |
2856 | if (b43_using_pio_transfers(dev)) | 2894 | |
2857 | err = b43_pio_tx(dev, skb, ctl); | 2895 | err = -ENODEV; |
2858 | else | 2896 | if (likely(b43_status(dev) >= B43_STAT_STARTED)) { |
2859 | err = b43_dma_tx(dev, skb, ctl); | 2897 | if (b43_using_pio_transfers(dev)) |
2860 | out: | 2898 | err = b43_pio_tx(dev, skb, ctl); |
2899 | else | ||
2900 | err = b43_dma_tx(dev, skb, ctl); | ||
2901 | } | ||
2902 | |||
2903 | read_unlock_irqrestore(&wl->tx_lock, flags); | ||
2904 | |||
2861 | if (unlikely(err)) | 2905 | if (unlikely(err)) |
2862 | return NETDEV_TX_BUSY; | 2906 | goto drop_packet; |
2907 | return NETDEV_TX_OK; | ||
2908 | |||
2909 | drop_packet: | ||
2910 | /* We can not transmit this packet. Drop it. */ | ||
2911 | dev_kfree_skb_any(skb); | ||
2863 | return NETDEV_TX_OK; | 2912 | return NETDEV_TX_OK; |
2864 | } | 2913 | } |
2865 | 2914 | ||
@@ -3476,7 +3525,9 @@ static void b43_wireless_core_stop(struct b43_wldev *dev) | |||
3476 | spin_unlock_irqrestore(&wl->irq_lock, flags); | 3525 | spin_unlock_irqrestore(&wl->irq_lock, flags); |
3477 | b43_synchronize_irq(dev); | 3526 | b43_synchronize_irq(dev); |
3478 | 3527 | ||
3528 | write_lock_irqsave(&wl->tx_lock, flags); | ||
3479 | b43_set_status(dev, B43_STAT_INITIALIZED); | 3529 | b43_set_status(dev, B43_STAT_INITIALIZED); |
3530 | write_unlock_irqrestore(&wl->tx_lock, flags); | ||
3480 | 3531 | ||
3481 | b43_pio_stop(dev); | 3532 | b43_pio_stop(dev); |
3482 | mutex_unlock(&wl->mutex); | 3533 | mutex_unlock(&wl->mutex); |
@@ -3485,8 +3536,6 @@ static void b43_wireless_core_stop(struct b43_wldev *dev) | |||
3485 | cancel_delayed_work_sync(&dev->periodic_work); | 3536 | cancel_delayed_work_sync(&dev->periodic_work); |
3486 | mutex_lock(&wl->mutex); | 3537 | mutex_lock(&wl->mutex); |
3487 | 3538 | ||
3488 | ieee80211_stop_queues(wl->hw); //FIXME this could cause a deadlock, as mac80211 seems buggy. | ||
3489 | |||
3490 | b43_mac_suspend(dev); | 3539 | b43_mac_suspend(dev); |
3491 | free_irq(dev->dev->irq, dev); | 3540 | free_irq(dev->dev->irq, dev); |
3492 | b43dbg(wl, "Wireless interface stopped\n"); | 3541 | b43dbg(wl, "Wireless interface stopped\n"); |
@@ -4059,6 +4108,9 @@ static int b43_op_start(struct ieee80211_hw *hw) | |||
4059 | wl->filter_flags = 0; | 4108 | wl->filter_flags = 0; |
4060 | wl->radiotap_enabled = 0; | 4109 | wl->radiotap_enabled = 0; |
4061 | b43_qos_clear(wl); | 4110 | b43_qos_clear(wl); |
4111 | wl->beacon0_uploaded = 0; | ||
4112 | wl->beacon1_uploaded = 0; | ||
4113 | wl->beacon_templates_virgin = 1; | ||
4062 | 4114 | ||
4063 | /* First register RFkill. | 4115 | /* First register RFkill. |
4064 | * LEDs that are registered later depend on it. */ | 4116 | * LEDs that are registered later depend on it. */ |
@@ -4227,7 +4279,9 @@ static void b43_chip_reset(struct work_struct *work) | |||
4227 | goto out; | 4279 | goto out; |
4228 | } | 4280 | } |
4229 | } | 4281 | } |
4230 | out: | 4282 | out: |
4283 | if (err) | ||
4284 | wl->current_dev = NULL; /* Failed to init the dev. */ | ||
4231 | mutex_unlock(&wl->mutex); | 4285 | mutex_unlock(&wl->mutex); |
4232 | if (err) | 4286 | if (err) |
4233 | b43err(wl, "Controller restart FAILED\n"); | 4287 | b43err(wl, "Controller restart FAILED\n"); |
@@ -4326,6 +4380,14 @@ static int b43_wireless_core_attach(struct b43_wldev *dev) | |||
4326 | err = -EOPNOTSUPP; | 4380 | err = -EOPNOTSUPP; |
4327 | goto err_powerdown; | 4381 | goto err_powerdown; |
4328 | } | 4382 | } |
4383 | if (1 /* disable A-PHY */) { | ||
4384 | /* FIXME: For now we disable the A-PHY on multi-PHY devices. */ | ||
4385 | if (dev->phy.type != B43_PHYTYPE_N) { | ||
4386 | have_2ghz_phy = 1; | ||
4387 | have_5ghz_phy = 0; | ||
4388 | } | ||
4389 | } | ||
4390 | |||
4329 | dev->phy.gmode = have_2ghz_phy; | 4391 | dev->phy.gmode = have_2ghz_phy; |
4330 | tmp = dev->phy.gmode ? B43_TMSLOW_GMODE : 0; | 4392 | tmp = dev->phy.gmode ? B43_TMSLOW_GMODE : 0; |
4331 | b43_wireless_core_reset(dev, tmp); | 4393 | b43_wireless_core_reset(dev, tmp); |
@@ -4360,9 +4422,11 @@ static void b43_one_core_detach(struct ssb_device *dev) | |||
4360 | struct b43_wldev *wldev; | 4422 | struct b43_wldev *wldev; |
4361 | struct b43_wl *wl; | 4423 | struct b43_wl *wl; |
4362 | 4424 | ||
4425 | /* Do not cancel ieee80211-workqueue based work here. | ||
4426 | * See comment in b43_remove(). */ | ||
4427 | |||
4363 | wldev = ssb_get_drvdata(dev); | 4428 | wldev = ssb_get_drvdata(dev); |
4364 | wl = wldev->wl; | 4429 | wl = wldev->wl; |
4365 | cancel_work_sync(&wldev->restart_work); | ||
4366 | b43_debugfs_remove_device(wldev); | 4430 | b43_debugfs_remove_device(wldev); |
4367 | b43_wireless_core_detach(wldev); | 4431 | b43_wireless_core_detach(wldev); |
4368 | list_del(&wldev->list); | 4432 | list_del(&wldev->list); |
@@ -4490,6 +4554,7 @@ static int b43_wireless_init(struct ssb_device *dev) | |||
4490 | memset(wl, 0, sizeof(*wl)); | 4554 | memset(wl, 0, sizeof(*wl)); |
4491 | wl->hw = hw; | 4555 | wl->hw = hw; |
4492 | spin_lock_init(&wl->irq_lock); | 4556 | spin_lock_init(&wl->irq_lock); |
4557 | rwlock_init(&wl->tx_lock); | ||
4493 | spin_lock_init(&wl->leds_lock); | 4558 | spin_lock_init(&wl->leds_lock); |
4494 | spin_lock_init(&wl->shm_lock); | 4559 | spin_lock_init(&wl->shm_lock); |
4495 | mutex_init(&wl->mutex); | 4560 | mutex_init(&wl->mutex); |
@@ -4546,6 +4611,10 @@ static void b43_remove(struct ssb_device *dev) | |||
4546 | struct b43_wl *wl = ssb_get_devtypedata(dev); | 4611 | struct b43_wl *wl = ssb_get_devtypedata(dev); |
4547 | struct b43_wldev *wldev = ssb_get_drvdata(dev); | 4612 | struct b43_wldev *wldev = ssb_get_drvdata(dev); |
4548 | 4613 | ||
4614 | /* We must cancel any work here before unregistering from ieee80211, | ||
4615 | * as the ieee80211 unreg will destroy the workqueue. */ | ||
4616 | cancel_work_sync(&wldev->restart_work); | ||
4617 | |||
4549 | B43_WARN_ON(!wl); | 4618 | B43_WARN_ON(!wl); |
4550 | if (wl->current_dev == wldev) | 4619 | if (wl->current_dev == wldev) |
4551 | ieee80211_unregister_hw(wl->hw); | 4620 | ieee80211_unregister_hw(wl->hw); |
diff --git a/drivers/net/wireless/b43legacy/Kconfig b/drivers/net/wireless/b43legacy/Kconfig index 13c65faf0247..aef2298d37ac 100644 --- a/drivers/net/wireless/b43legacy/Kconfig +++ b/drivers/net/wireless/b43legacy/Kconfig | |||
@@ -1,6 +1,6 @@ | |||
1 | config B43LEGACY | 1 | config B43LEGACY |
2 | tristate "Broadcom 43xx-legacy wireless support (mac80211 stack)" | 2 | tristate "Broadcom 43xx-legacy wireless support (mac80211 stack)" |
3 | depends on SSB_POSSIBLE && MAC80211 && WLAN_80211 | 3 | depends on SSB_POSSIBLE && MAC80211 && WLAN_80211 && HAS_DMA |
4 | select SSB | 4 | select SSB |
5 | select FW_LOADER | 5 | select FW_LOADER |
6 | select HW_RANDOM | 6 | select HW_RANDOM |
diff --git a/drivers/net/wireless/b43legacy/dma.c b/drivers/net/wireless/b43legacy/dma.c index c990f87b107a..93ddc1cbcc8b 100644 --- a/drivers/net/wireless/b43legacy/dma.c +++ b/drivers/net/wireless/b43legacy/dma.c | |||
@@ -876,6 +876,7 @@ struct b43legacy_dmaring *b43legacy_setup_dmaring(struct b43legacy_wldev *dev, | |||
876 | if (!ring) | 876 | if (!ring) |
877 | goto out; | 877 | goto out; |
878 | ring->type = type; | 878 | ring->type = type; |
879 | ring->dev = dev; | ||
879 | 880 | ||
880 | nr_slots = B43legacy_RXRING_SLOTS; | 881 | nr_slots = B43legacy_RXRING_SLOTS; |
881 | if (for_tx) | 882 | if (for_tx) |
@@ -922,7 +923,6 @@ struct b43legacy_dmaring *b43legacy_setup_dmaring(struct b43legacy_wldev *dev, | |||
922 | DMA_TO_DEVICE); | 923 | DMA_TO_DEVICE); |
923 | } | 924 | } |
924 | 925 | ||
925 | ring->dev = dev; | ||
926 | ring->nr_slots = nr_slots; | 926 | ring->nr_slots = nr_slots; |
927 | ring->mmio_base = b43legacy_dmacontroller_base(type, controller_index); | 927 | ring->mmio_base = b43legacy_dmacontroller_base(type, controller_index); |
928 | ring->index = controller_index; | 928 | ring->index = controller_index; |
diff --git a/drivers/net/wireless/b43legacy/main.c b/drivers/net/wireless/b43legacy/main.c index 14a5eea2573e..3e612d0a13e8 100644 --- a/drivers/net/wireless/b43legacy/main.c +++ b/drivers/net/wireless/b43legacy/main.c | |||
@@ -2378,8 +2378,10 @@ static int b43legacy_op_tx(struct ieee80211_hw *hw, | |||
2378 | } else | 2378 | } else |
2379 | err = b43legacy_dma_tx(dev, skb, ctl); | 2379 | err = b43legacy_dma_tx(dev, skb, ctl); |
2380 | out: | 2380 | out: |
2381 | if (unlikely(err)) | 2381 | if (unlikely(err)) { |
2382 | return NETDEV_TX_BUSY; | 2382 | /* Drop the packet. */ |
2383 | dev_kfree_skb_any(skb); | ||
2384 | } | ||
2383 | return NETDEV_TX_OK; | 2385 | return NETDEV_TX_OK; |
2384 | } | 2386 | } |
2385 | 2387 | ||
@@ -3039,7 +3041,6 @@ static void b43legacy_set_pretbtt(struct b43legacy_wldev *dev) | |||
3039 | /* Locking: wl->mutex */ | 3041 | /* Locking: wl->mutex */ |
3040 | static void b43legacy_wireless_core_exit(struct b43legacy_wldev *dev) | 3042 | static void b43legacy_wireless_core_exit(struct b43legacy_wldev *dev) |
3041 | { | 3043 | { |
3042 | struct b43legacy_wl *wl = dev->wl; | ||
3043 | struct b43legacy_phy *phy = &dev->phy; | 3044 | struct b43legacy_phy *phy = &dev->phy; |
3044 | u32 macctl; | 3045 | u32 macctl; |
3045 | 3046 | ||
@@ -3054,12 +3055,6 @@ static void b43legacy_wireless_core_exit(struct b43legacy_wldev *dev) | |||
3054 | macctl |= B43legacy_MACCTL_PSM_JMP0; | 3055 | macctl |= B43legacy_MACCTL_PSM_JMP0; |
3055 | b43legacy_write32(dev, B43legacy_MMIO_MACCTL, macctl); | 3056 | b43legacy_write32(dev, B43legacy_MMIO_MACCTL, macctl); |
3056 | 3057 | ||
3057 | mutex_unlock(&wl->mutex); | ||
3058 | /* Must unlock as it would otherwise deadlock. No races here. | ||
3059 | * Cancel possibly pending workqueues. */ | ||
3060 | cancel_work_sync(&dev->restart_work); | ||
3061 | mutex_lock(&wl->mutex); | ||
3062 | |||
3063 | b43legacy_leds_exit(dev); | 3058 | b43legacy_leds_exit(dev); |
3064 | b43legacy_rng_exit(dev->wl); | 3059 | b43legacy_rng_exit(dev->wl); |
3065 | b43legacy_pio_free(dev); | 3060 | b43legacy_pio_free(dev); |
@@ -3486,6 +3481,8 @@ static void b43legacy_chip_reset(struct work_struct *work) | |||
3486 | } | 3481 | } |
3487 | } | 3482 | } |
3488 | out: | 3483 | out: |
3484 | if (err) | ||
3485 | wl->current_dev = NULL; /* Failed to init the dev. */ | ||
3489 | mutex_unlock(&wl->mutex); | 3486 | mutex_unlock(&wl->mutex); |
3490 | if (err) | 3487 | if (err) |
3491 | b43legacyerr(wl, "Controller restart FAILED\n"); | 3488 | b43legacyerr(wl, "Controller restart FAILED\n"); |
@@ -3618,9 +3615,11 @@ static void b43legacy_one_core_detach(struct ssb_device *dev) | |||
3618 | struct b43legacy_wldev *wldev; | 3615 | struct b43legacy_wldev *wldev; |
3619 | struct b43legacy_wl *wl; | 3616 | struct b43legacy_wl *wl; |
3620 | 3617 | ||
3618 | /* Do not cancel ieee80211-workqueue based work here. | ||
3619 | * See comment in b43legacy_remove(). */ | ||
3620 | |||
3621 | wldev = ssb_get_drvdata(dev); | 3621 | wldev = ssb_get_drvdata(dev); |
3622 | wl = wldev->wl; | 3622 | wl = wldev->wl; |
3623 | cancel_work_sync(&wldev->restart_work); | ||
3624 | b43legacy_debugfs_remove_device(wldev); | 3623 | b43legacy_debugfs_remove_device(wldev); |
3625 | b43legacy_wireless_core_detach(wldev); | 3624 | b43legacy_wireless_core_detach(wldev); |
3626 | list_del(&wldev->list); | 3625 | list_del(&wldev->list); |
@@ -3789,6 +3788,10 @@ static void b43legacy_remove(struct ssb_device *dev) | |||
3789 | struct b43legacy_wl *wl = ssb_get_devtypedata(dev); | 3788 | struct b43legacy_wl *wl = ssb_get_devtypedata(dev); |
3790 | struct b43legacy_wldev *wldev = ssb_get_drvdata(dev); | 3789 | struct b43legacy_wldev *wldev = ssb_get_drvdata(dev); |
3791 | 3790 | ||
3791 | /* We must cancel any work here before unregistering from ieee80211, | ||
3792 | * as the ieee80211 unreg will destroy the workqueue. */ | ||
3793 | cancel_work_sync(&wldev->restart_work); | ||
3794 | |||
3792 | B43legacy_WARN_ON(!wl); | 3795 | B43legacy_WARN_ON(!wl); |
3793 | if (wl->current_dev == wldev) | 3796 | if (wl->current_dev == wldev) |
3794 | ieee80211_unregister_hw(wl->hw); | 3797 | ieee80211_unregister_hw(wl->hw); |
diff --git a/drivers/net/wireless/hostap/hostap_80211_rx.c b/drivers/net/wireless/hostap/hostap_80211_rx.c index 4fd73809602e..020f450e9dba 100644 --- a/drivers/net/wireless/hostap/hostap_80211_rx.c +++ b/drivers/net/wireless/hostap/hostap_80211_rx.c | |||
@@ -64,7 +64,7 @@ int prism2_rx_80211(struct net_device *dev, struct sk_buff *skb, | |||
64 | int hdrlen, phdrlen, head_need, tail_need; | 64 | int hdrlen, phdrlen, head_need, tail_need; |
65 | u16 fc; | 65 | u16 fc; |
66 | int prism_header, ret; | 66 | int prism_header, ret; |
67 | struct ieee80211_hdr_4addr *hdr; | 67 | struct ieee80211_hdr_4addr *fhdr; |
68 | 68 | ||
69 | iface = netdev_priv(dev); | 69 | iface = netdev_priv(dev); |
70 | local = iface->local; | 70 | local = iface->local; |
@@ -83,8 +83,8 @@ int prism2_rx_80211(struct net_device *dev, struct sk_buff *skb, | |||
83 | phdrlen = 0; | 83 | phdrlen = 0; |
84 | } | 84 | } |
85 | 85 | ||
86 | hdr = (struct ieee80211_hdr_4addr *) skb->data; | 86 | fhdr = (struct ieee80211_hdr_4addr *) skb->data; |
87 | fc = le16_to_cpu(hdr->frame_ctl); | 87 | fc = le16_to_cpu(fhdr->frame_ctl); |
88 | 88 | ||
89 | if (type == PRISM2_RX_MGMT && (fc & IEEE80211_FCTL_VERS)) { | 89 | if (type == PRISM2_RX_MGMT && (fc & IEEE80211_FCTL_VERS)) { |
90 | printk(KERN_DEBUG "%s: dropped management frame with header " | 90 | printk(KERN_DEBUG "%s: dropped management frame with header " |
@@ -551,7 +551,7 @@ hostap_rx_frame_wds(local_info_t *local, struct ieee80211_hdr_4addr *hdr, | |||
551 | hdr->addr1[2] != 0xff || hdr->addr1[3] != 0xff || | 551 | hdr->addr1[2] != 0xff || hdr->addr1[3] != 0xff || |
552 | hdr->addr1[4] != 0xff || hdr->addr1[5] != 0xff)) { | 552 | hdr->addr1[4] != 0xff || hdr->addr1[5] != 0xff)) { |
553 | /* RA (or BSSID) is not ours - drop */ | 553 | /* RA (or BSSID) is not ours - drop */ |
554 | PDEBUG(DEBUG_EXTRA, "%s: received WDS frame with " | 554 | PDEBUG(DEBUG_EXTRA2, "%s: received WDS frame with " |
555 | "not own or broadcast %s=%s\n", | 555 | "not own or broadcast %s=%s\n", |
556 | local->dev->name, | 556 | local->dev->name, |
557 | fc & IEEE80211_FCTL_FROMDS ? "RA" : "BSSID", | 557 | fc & IEEE80211_FCTL_FROMDS ? "RA" : "BSSID", |
diff --git a/drivers/net/wireless/hostap/hostap_ap.c b/drivers/net/wireless/hostap/hostap_ap.c index 0acd9589c48c..ab981afd481d 100644 --- a/drivers/net/wireless/hostap/hostap_ap.c +++ b/drivers/net/wireless/hostap/hostap_ap.c | |||
@@ -1930,7 +1930,7 @@ static void handle_pspoll(local_info_t *local, | |||
1930 | PDEBUG(DEBUG_PS, " PSPOLL and AID[15:14] not set\n"); | 1930 | PDEBUG(DEBUG_PS, " PSPOLL and AID[15:14] not set\n"); |
1931 | return; | 1931 | return; |
1932 | } | 1932 | } |
1933 | aid &= ~BIT(15) & ~BIT(14); | 1933 | aid &= ~(BIT(15) | BIT(14)); |
1934 | if (aid == 0 || aid > MAX_AID_TABLE_SIZE) { | 1934 | if (aid == 0 || aid > MAX_AID_TABLE_SIZE) { |
1935 | PDEBUG(DEBUG_PS, " invalid aid=%d\n", aid); | 1935 | PDEBUG(DEBUG_PS, " invalid aid=%d\n", aid); |
1936 | return; | 1936 | return; |
diff --git a/drivers/net/wireless/hostap/hostap_cs.c b/drivers/net/wireless/hostap/hostap_cs.c index 437a9bcc9bd3..3b4e55cf33cd 100644 --- a/drivers/net/wireless/hostap/hostap_cs.c +++ b/drivers/net/wireless/hostap/hostap_cs.c | |||
@@ -533,10 +533,10 @@ static void prism2_detach(struct pcmcia_device *link) | |||
533 | do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) | 533 | do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) |
534 | 534 | ||
535 | #define CFG_CHECK2(fn, retf) \ | 535 | #define CFG_CHECK2(fn, retf) \ |
536 | do { int ret = (retf); \ | 536 | do { int _ret = (retf); \ |
537 | if (ret != 0) { \ | 537 | if (_ret != 0) { \ |
538 | PDEBUG(DEBUG_EXTRA, "CardServices(" #fn ") returned %d\n", ret); \ | 538 | PDEBUG(DEBUG_EXTRA, "CardServices(" #fn ") returned %d\n", _ret); \ |
539 | cs_error(link, fn, ret); \ | 539 | cs_error(link, fn, _ret); \ |
540 | goto next_entry; \ | 540 | goto next_entry; \ |
541 | } \ | 541 | } \ |
542 | } while (0) | 542 | } while (0) |
@@ -777,8 +777,10 @@ static int hostap_cs_suspend(struct pcmcia_device *link) | |||
777 | int dev_open = 0; | 777 | int dev_open = 0; |
778 | struct hostap_interface *iface = NULL; | 778 | struct hostap_interface *iface = NULL; |
779 | 779 | ||
780 | if (dev) | 780 | if (!dev) |
781 | iface = netdev_priv(dev); | 781 | return -ENODEV; |
782 | |||
783 | iface = netdev_priv(dev); | ||
782 | 784 | ||
783 | PDEBUG(DEBUG_EXTRA, "%s: CS_EVENT_PM_SUSPEND\n", dev_info); | 785 | PDEBUG(DEBUG_EXTRA, "%s: CS_EVENT_PM_SUSPEND\n", dev_info); |
784 | if (iface && iface->local) | 786 | if (iface && iface->local) |
@@ -798,8 +800,10 @@ static int hostap_cs_resume(struct pcmcia_device *link) | |||
798 | int dev_open = 0; | 800 | int dev_open = 0; |
799 | struct hostap_interface *iface = NULL; | 801 | struct hostap_interface *iface = NULL; |
800 | 802 | ||
801 | if (dev) | 803 | if (!dev) |
802 | iface = netdev_priv(dev); | 804 | return -ENODEV; |
805 | |||
806 | iface = netdev_priv(dev); | ||
803 | 807 | ||
804 | PDEBUG(DEBUG_EXTRA, "%s: CS_EVENT_PM_RESUME\n", dev_info); | 808 | PDEBUG(DEBUG_EXTRA, "%s: CS_EVENT_PM_RESUME\n", dev_info); |
805 | 809 | ||
@@ -833,6 +837,7 @@ static struct pcmcia_device_id hostap_cs_ids[] = { | |||
833 | PCMCIA_DEVICE_MANF_CARD(0x50c2, 0x0001), | 837 | PCMCIA_DEVICE_MANF_CARD(0x50c2, 0x0001), |
834 | PCMCIA_DEVICE_MANF_CARD(0x50c2, 0x7300), | 838 | PCMCIA_DEVICE_MANF_CARD(0x50c2, 0x7300), |
835 | /* PCMCIA_DEVICE_MANF_CARD(0xc00f, 0x0000), conflict with pcnet_cs */ | 839 | /* PCMCIA_DEVICE_MANF_CARD(0xc00f, 0x0000), conflict with pcnet_cs */ |
840 | PCMCIA_DEVICE_MANF_CARD(0xc250, 0x0002), | ||
836 | PCMCIA_DEVICE_MANF_CARD(0xd601, 0x0002), | 841 | PCMCIA_DEVICE_MANF_CARD(0xd601, 0x0002), |
837 | PCMCIA_DEVICE_MANF_CARD(0xd601, 0x0005), | 842 | PCMCIA_DEVICE_MANF_CARD(0xd601, 0x0005), |
838 | PCMCIA_DEVICE_MANF_CARD(0xd601, 0x0010), | 843 | PCMCIA_DEVICE_MANF_CARD(0xd601, 0x0010), |
diff --git a/drivers/net/wireless/hostap/hostap_hw.c b/drivers/net/wireless/hostap/hostap_hw.c index 7be68db6f300..936f52e3d95c 100644 --- a/drivers/net/wireless/hostap/hostap_hw.c +++ b/drivers/net/wireless/hostap/hostap_hw.c | |||
@@ -2835,7 +2835,7 @@ static void hostap_passive_scan(unsigned long data) | |||
2835 | { | 2835 | { |
2836 | local_info_t *local = (local_info_t *) data; | 2836 | local_info_t *local = (local_info_t *) data; |
2837 | struct net_device *dev = local->dev; | 2837 | struct net_device *dev = local->dev; |
2838 | u16 channel; | 2838 | u16 chan; |
2839 | 2839 | ||
2840 | if (local->passive_scan_interval <= 0) | 2840 | if (local->passive_scan_interval <= 0) |
2841 | return; | 2841 | return; |
@@ -2872,11 +2872,11 @@ static void hostap_passive_scan(unsigned long data) | |||
2872 | 2872 | ||
2873 | printk(KERN_DEBUG "%s: passive scan channel %d\n", | 2873 | printk(KERN_DEBUG "%s: passive scan channel %d\n", |
2874 | dev->name, local->passive_scan_channel); | 2874 | dev->name, local->passive_scan_channel); |
2875 | channel = local->passive_scan_channel; | 2875 | chan = local->passive_scan_channel; |
2876 | local->passive_scan_state = PASSIVE_SCAN_WAIT; | 2876 | local->passive_scan_state = PASSIVE_SCAN_WAIT; |
2877 | local->passive_scan_timer.expires = jiffies + HZ / 10; | 2877 | local->passive_scan_timer.expires = jiffies + HZ / 10; |
2878 | } else { | 2878 | } else { |
2879 | channel = local->channel; | 2879 | chan = local->channel; |
2880 | local->passive_scan_state = PASSIVE_SCAN_LISTEN; | 2880 | local->passive_scan_state = PASSIVE_SCAN_LISTEN; |
2881 | local->passive_scan_timer.expires = jiffies + | 2881 | local->passive_scan_timer.expires = jiffies + |
2882 | local->passive_scan_interval * HZ; | 2882 | local->passive_scan_interval * HZ; |
@@ -2884,9 +2884,9 @@ static void hostap_passive_scan(unsigned long data) | |||
2884 | 2884 | ||
2885 | if (hfa384x_cmd_callback(dev, HFA384X_CMDCODE_TEST | | 2885 | if (hfa384x_cmd_callback(dev, HFA384X_CMDCODE_TEST | |
2886 | (HFA384X_TEST_CHANGE_CHANNEL << 8), | 2886 | (HFA384X_TEST_CHANGE_CHANNEL << 8), |
2887 | channel, NULL, 0)) | 2887 | chan, NULL, 0)) |
2888 | printk(KERN_ERR "%s: passive scan channel set %d " | 2888 | printk(KERN_ERR "%s: passive scan channel set %d " |
2889 | "failed\n", dev->name, channel); | 2889 | "failed\n", dev->name, chan); |
2890 | 2890 | ||
2891 | add_timer(&local->passive_scan_timer); | 2891 | add_timer(&local->passive_scan_timer); |
2892 | } | 2892 | } |
@@ -3276,11 +3276,6 @@ while (0) | |||
3276 | } | 3276 | } |
3277 | printk(KERN_INFO "%s: Registered netdevice %s\n", dev_info, dev->name); | 3277 | printk(KERN_INFO "%s: Registered netdevice %s\n", dev_info, dev->name); |
3278 | 3278 | ||
3279 | #ifndef PRISM2_NO_PROCFS_DEBUG | ||
3280 | create_proc_read_entry("registers", 0, local->proc, | ||
3281 | prism2_registers_proc_read, local); | ||
3282 | #endif /* PRISM2_NO_PROCFS_DEBUG */ | ||
3283 | |||
3284 | hostap_init_data(local); | 3279 | hostap_init_data(local); |
3285 | return dev; | 3280 | return dev; |
3286 | 3281 | ||
@@ -3307,6 +3302,10 @@ static int hostap_hw_ready(struct net_device *dev) | |||
3307 | netif_carrier_off(local->ddev); | 3302 | netif_carrier_off(local->ddev); |
3308 | } | 3303 | } |
3309 | hostap_init_proc(local); | 3304 | hostap_init_proc(local); |
3305 | #ifndef PRISM2_NO_PROCFS_DEBUG | ||
3306 | create_proc_read_entry("registers", 0, local->proc, | ||
3307 | prism2_registers_proc_read, local); | ||
3308 | #endif /* PRISM2_NO_PROCFS_DEBUG */ | ||
3310 | hostap_init_ap_proc(local); | 3309 | hostap_init_ap_proc(local); |
3311 | return 0; | 3310 | return 0; |
3312 | } | 3311 | } |
diff --git a/drivers/net/wireless/hostap/hostap_main.c b/drivers/net/wireless/hostap/hostap_main.c index 20d387f6658c..a38e85f334df 100644 --- a/drivers/net/wireless/hostap/hostap_main.c +++ b/drivers/net/wireless/hostap/hostap_main.c | |||
@@ -594,7 +594,8 @@ void hostap_dump_tx_header(const char *name, const struct hfa384x_tx_frame *tx) | |||
594 | } | 594 | } |
595 | 595 | ||
596 | 596 | ||
597 | int hostap_80211_header_parse(const struct sk_buff *skb, unsigned char *haddr) | 597 | static int hostap_80211_header_parse(const struct sk_buff *skb, |
598 | unsigned char *haddr) | ||
598 | { | 599 | { |
599 | struct hostap_interface *iface = netdev_priv(skb->dev); | 600 | struct hostap_interface *iface = netdev_priv(skb->dev); |
600 | local_info_t *local = iface->local; | 601 | local_info_t *local = iface->local; |
@@ -682,7 +683,13 @@ static int prism2_close(struct net_device *dev) | |||
682 | netif_device_detach(dev); | 683 | netif_device_detach(dev); |
683 | } | 684 | } |
684 | 685 | ||
685 | flush_scheduled_work(); | 686 | cancel_work_sync(&local->reset_queue); |
687 | cancel_work_sync(&local->set_multicast_list_queue); | ||
688 | cancel_work_sync(&local->set_tim_queue); | ||
689 | #ifndef PRISM2_NO_STATION_MODES | ||
690 | cancel_work_sync(&local->info_queue); | ||
691 | #endif | ||
692 | cancel_work_sync(&local->comms_qual_update); | ||
686 | 693 | ||
687 | module_put(local->hw_module); | 694 | module_put(local->hw_module); |
688 | 695 | ||
@@ -851,7 +858,6 @@ const struct header_ops hostap_80211_ops = { | |||
851 | .rebuild = eth_rebuild_header, | 858 | .rebuild = eth_rebuild_header, |
852 | .cache = eth_header_cache, | 859 | .cache = eth_header_cache, |
853 | .cache_update = eth_header_cache_update, | 860 | .cache_update = eth_header_cache_update, |
854 | |||
855 | .parse = hostap_80211_header_parse, | 861 | .parse = hostap_80211_header_parse, |
856 | }; | 862 | }; |
857 | EXPORT_SYMBOL(hostap_80211_ops); | 863 | EXPORT_SYMBOL(hostap_80211_ops); |
@@ -1144,7 +1150,6 @@ EXPORT_SYMBOL(hostap_set_roaming); | |||
1144 | EXPORT_SYMBOL(hostap_set_auth_algs); | 1150 | EXPORT_SYMBOL(hostap_set_auth_algs); |
1145 | EXPORT_SYMBOL(hostap_dump_rx_header); | 1151 | EXPORT_SYMBOL(hostap_dump_rx_header); |
1146 | EXPORT_SYMBOL(hostap_dump_tx_header); | 1152 | EXPORT_SYMBOL(hostap_dump_tx_header); |
1147 | EXPORT_SYMBOL(hostap_80211_header_parse); | ||
1148 | EXPORT_SYMBOL(hostap_80211_get_hdrlen); | 1153 | EXPORT_SYMBOL(hostap_80211_get_hdrlen); |
1149 | EXPORT_SYMBOL(hostap_get_stats); | 1154 | EXPORT_SYMBOL(hostap_get_stats); |
1150 | EXPORT_SYMBOL(hostap_setup_dev); | 1155 | EXPORT_SYMBOL(hostap_setup_dev); |
diff --git a/drivers/net/wireless/ipw2200.c b/drivers/net/wireless/ipw2200.c index fa87c5c2ae0b..6e704608947c 100644 --- a/drivers/net/wireless/ipw2200.c +++ b/drivers/net/wireless/ipw2200.c | |||
@@ -1753,6 +1753,8 @@ static int ipw_radio_kill_sw(struct ipw_priv *priv, int disable_radio) | |||
1753 | 1753 | ||
1754 | if (priv->workqueue) { | 1754 | if (priv->workqueue) { |
1755 | cancel_delayed_work(&priv->request_scan); | 1755 | cancel_delayed_work(&priv->request_scan); |
1756 | cancel_delayed_work(&priv->request_direct_scan); | ||
1757 | cancel_delayed_work(&priv->request_passive_scan); | ||
1756 | cancel_delayed_work(&priv->scan_event); | 1758 | cancel_delayed_work(&priv->scan_event); |
1757 | } | 1759 | } |
1758 | queue_work(priv->workqueue, &priv->down); | 1760 | queue_work(priv->workqueue, &priv->down); |
@@ -2005,6 +2007,8 @@ static void ipw_irq_tasklet(struct ipw_priv *priv) | |||
2005 | wake_up_interruptible(&priv->wait_command_queue); | 2007 | wake_up_interruptible(&priv->wait_command_queue); |
2006 | priv->status &= ~(STATUS_ASSOCIATED | STATUS_ASSOCIATING); | 2008 | priv->status &= ~(STATUS_ASSOCIATED | STATUS_ASSOCIATING); |
2007 | cancel_delayed_work(&priv->request_scan); | 2009 | cancel_delayed_work(&priv->request_scan); |
2010 | cancel_delayed_work(&priv->request_direct_scan); | ||
2011 | cancel_delayed_work(&priv->request_passive_scan); | ||
2008 | cancel_delayed_work(&priv->scan_event); | 2012 | cancel_delayed_work(&priv->scan_event); |
2009 | schedule_work(&priv->link_down); | 2013 | schedule_work(&priv->link_down); |
2010 | queue_delayed_work(priv->workqueue, &priv->rf_kill, 2 * HZ); | 2014 | queue_delayed_work(priv->workqueue, &priv->rf_kill, 2 * HZ); |
@@ -4712,6 +4716,12 @@ static void ipw_rx_notification(struct ipw_priv *priv, | |||
4712 | priv->status &= ~STATUS_SCAN_FORCED; | 4716 | priv->status &= ~STATUS_SCAN_FORCED; |
4713 | #endif /* CONFIG_IPW2200_MONITOR */ | 4717 | #endif /* CONFIG_IPW2200_MONITOR */ |
4714 | 4718 | ||
4719 | /* Do queued direct scans first */ | ||
4720 | if (priv->status & STATUS_DIRECT_SCAN_PENDING) { | ||
4721 | queue_delayed_work(priv->workqueue, | ||
4722 | &priv->request_direct_scan, 0); | ||
4723 | } | ||
4724 | |||
4715 | if (!(priv->status & (STATUS_ASSOCIATED | | 4725 | if (!(priv->status & (STATUS_ASSOCIATED | |
4716 | STATUS_ASSOCIATING | | 4726 | STATUS_ASSOCIATING | |
4717 | STATUS_ROAMING | | 4727 | STATUS_ROAMING | |
@@ -6267,7 +6277,7 @@ static void ipw_add_scan_channels(struct ipw_priv *priv, | |||
6267 | } | 6277 | } |
6268 | } | 6278 | } |
6269 | 6279 | ||
6270 | static int ipw_request_scan_helper(struct ipw_priv *priv, int type) | 6280 | static int ipw_request_scan_helper(struct ipw_priv *priv, int type, int direct) |
6271 | { | 6281 | { |
6272 | struct ipw_scan_request_ext scan; | 6282 | struct ipw_scan_request_ext scan; |
6273 | int err = 0, scan_type; | 6283 | int err = 0, scan_type; |
@@ -6278,22 +6288,31 @@ static int ipw_request_scan_helper(struct ipw_priv *priv, int type) | |||
6278 | 6288 | ||
6279 | mutex_lock(&priv->mutex); | 6289 | mutex_lock(&priv->mutex); |
6280 | 6290 | ||
6291 | if (direct && (priv->direct_scan_ssid_len == 0)) { | ||
6292 | IPW_DEBUG_HC("Direct scan requested but no SSID to scan for\n"); | ||
6293 | priv->status &= ~STATUS_DIRECT_SCAN_PENDING; | ||
6294 | goto done; | ||
6295 | } | ||
6296 | |||
6281 | if (priv->status & STATUS_SCANNING) { | 6297 | if (priv->status & STATUS_SCANNING) { |
6282 | IPW_DEBUG_HC("Concurrent scan requested. Ignoring.\n"); | 6298 | IPW_DEBUG_HC("Concurrent scan requested. Queuing.\n"); |
6283 | priv->status |= STATUS_SCAN_PENDING; | 6299 | priv->status |= direct ? STATUS_DIRECT_SCAN_PENDING : |
6300 | STATUS_SCAN_PENDING; | ||
6284 | goto done; | 6301 | goto done; |
6285 | } | 6302 | } |
6286 | 6303 | ||
6287 | if (!(priv->status & STATUS_SCAN_FORCED) && | 6304 | if (!(priv->status & STATUS_SCAN_FORCED) && |
6288 | priv->status & STATUS_SCAN_ABORTING) { | 6305 | priv->status & STATUS_SCAN_ABORTING) { |
6289 | IPW_DEBUG_HC("Scan request while abort pending. Queuing.\n"); | 6306 | IPW_DEBUG_HC("Scan request while abort pending. Queuing.\n"); |
6290 | priv->status |= STATUS_SCAN_PENDING; | 6307 | priv->status |= direct ? STATUS_DIRECT_SCAN_PENDING : |
6308 | STATUS_SCAN_PENDING; | ||
6291 | goto done; | 6309 | goto done; |
6292 | } | 6310 | } |
6293 | 6311 | ||
6294 | if (priv->status & STATUS_RF_KILL_MASK) { | 6312 | if (priv->status & STATUS_RF_KILL_MASK) { |
6295 | IPW_DEBUG_HC("Aborting scan due to RF Kill activation\n"); | 6313 | IPW_DEBUG_HC("Queuing scan due to RF Kill activation\n"); |
6296 | priv->status |= STATUS_SCAN_PENDING; | 6314 | priv->status |= direct ? STATUS_DIRECT_SCAN_PENDING : |
6315 | STATUS_SCAN_PENDING; | ||
6297 | goto done; | 6316 | goto done; |
6298 | } | 6317 | } |
6299 | 6318 | ||
@@ -6321,6 +6340,7 @@ static int ipw_request_scan_helper(struct ipw_priv *priv, int type) | |||
6321 | cpu_to_le16(20); | 6340 | cpu_to_le16(20); |
6322 | 6341 | ||
6323 | scan.dwell_time[IPW_SCAN_PASSIVE_FULL_DWELL_SCAN] = cpu_to_le16(120); | 6342 | scan.dwell_time[IPW_SCAN_PASSIVE_FULL_DWELL_SCAN] = cpu_to_le16(120); |
6343 | scan.dwell_time[IPW_SCAN_ACTIVE_DIRECT_SCAN] = cpu_to_le16(20); | ||
6324 | 6344 | ||
6325 | #ifdef CONFIG_IPW2200_MONITOR | 6345 | #ifdef CONFIG_IPW2200_MONITOR |
6326 | if (priv->ieee->iw_mode == IW_MODE_MONITOR) { | 6346 | if (priv->ieee->iw_mode == IW_MODE_MONITOR) { |
@@ -6360,13 +6380,23 @@ static int ipw_request_scan_helper(struct ipw_priv *priv, int type) | |||
6360 | cpu_to_le16(2000); | 6380 | cpu_to_le16(2000); |
6361 | } else { | 6381 | } else { |
6362 | #endif /* CONFIG_IPW2200_MONITOR */ | 6382 | #endif /* CONFIG_IPW2200_MONITOR */ |
6363 | /* If we are roaming, then make this a directed scan for the | 6383 | /* Honor direct scans first, otherwise if we are roaming make |
6364 | * current network. Otherwise, ensure that every other scan | 6384 | * this a direct scan for the current network. Finally, |
6365 | * is a fast channel hop scan */ | 6385 | * ensure that every other scan is a fast channel hop scan */ |
6366 | if ((priv->status & STATUS_ROAMING) | 6386 | if (direct) { |
6367 | || (!(priv->status & STATUS_ASSOCIATED) | 6387 | err = ipw_send_ssid(priv, priv->direct_scan_ssid, |
6368 | && (priv->config & CFG_STATIC_ESSID) | 6388 | priv->direct_scan_ssid_len); |
6369 | && (le32_to_cpu(scan.full_scan_index) % 2))) { | 6389 | if (err) { |
6390 | IPW_DEBUG_HC("Attempt to send SSID command " | ||
6391 | "failed\n"); | ||
6392 | goto done; | ||
6393 | } | ||
6394 | |||
6395 | scan_type = IPW_SCAN_ACTIVE_BROADCAST_AND_DIRECT_SCAN; | ||
6396 | } else if ((priv->status & STATUS_ROAMING) | ||
6397 | || (!(priv->status & STATUS_ASSOCIATED) | ||
6398 | && (priv->config & CFG_STATIC_ESSID) | ||
6399 | && (le32_to_cpu(scan.full_scan_index) % 2))) { | ||
6370 | err = ipw_send_ssid(priv, priv->essid, priv->essid_len); | 6400 | err = ipw_send_ssid(priv, priv->essid, priv->essid_len); |
6371 | if (err) { | 6401 | if (err) { |
6372 | IPW_DEBUG_HC("Attempt to send SSID command " | 6402 | IPW_DEBUG_HC("Attempt to send SSID command " |
@@ -6391,7 +6421,12 @@ send_request: | |||
6391 | } | 6421 | } |
6392 | 6422 | ||
6393 | priv->status |= STATUS_SCANNING; | 6423 | priv->status |= STATUS_SCANNING; |
6394 | priv->status &= ~STATUS_SCAN_PENDING; | 6424 | if (direct) { |
6425 | priv->status &= ~STATUS_DIRECT_SCAN_PENDING; | ||
6426 | priv->direct_scan_ssid_len = 0; | ||
6427 | } else | ||
6428 | priv->status &= ~STATUS_SCAN_PENDING; | ||
6429 | |||
6395 | queue_delayed_work(priv->workqueue, &priv->scan_check, | 6430 | queue_delayed_work(priv->workqueue, &priv->scan_check, |
6396 | IPW_SCAN_CHECK_WATCHDOG); | 6431 | IPW_SCAN_CHECK_WATCHDOG); |
6397 | done: | 6432 | done: |
@@ -6402,15 +6437,22 @@ done: | |||
6402 | static void ipw_request_passive_scan(struct work_struct *work) | 6437 | static void ipw_request_passive_scan(struct work_struct *work) |
6403 | { | 6438 | { |
6404 | struct ipw_priv *priv = | 6439 | struct ipw_priv *priv = |
6405 | container_of(work, struct ipw_priv, request_passive_scan); | 6440 | container_of(work, struct ipw_priv, request_passive_scan.work); |
6406 | ipw_request_scan_helper(priv, IW_SCAN_TYPE_PASSIVE); | 6441 | ipw_request_scan_helper(priv, IW_SCAN_TYPE_PASSIVE, 0); |
6407 | } | 6442 | } |
6408 | 6443 | ||
6409 | static void ipw_request_scan(struct work_struct *work) | 6444 | static void ipw_request_scan(struct work_struct *work) |
6410 | { | 6445 | { |
6411 | struct ipw_priv *priv = | 6446 | struct ipw_priv *priv = |
6412 | container_of(work, struct ipw_priv, request_scan.work); | 6447 | container_of(work, struct ipw_priv, request_scan.work); |
6413 | ipw_request_scan_helper(priv, IW_SCAN_TYPE_ACTIVE); | 6448 | ipw_request_scan_helper(priv, IW_SCAN_TYPE_ACTIVE, 0); |
6449 | } | ||
6450 | |||
6451 | static void ipw_request_direct_scan(struct work_struct *work) | ||
6452 | { | ||
6453 | struct ipw_priv *priv = | ||
6454 | container_of(work, struct ipw_priv, request_direct_scan.work); | ||
6455 | ipw_request_scan_helper(priv, IW_SCAN_TYPE_ACTIVE, 1); | ||
6414 | } | 6456 | } |
6415 | 6457 | ||
6416 | static void ipw_bg_abort_scan(struct work_struct *work) | 6458 | static void ipw_bg_abort_scan(struct work_struct *work) |
@@ -7558,8 +7600,31 @@ static int ipw_associate(void *data) | |||
7558 | priv->ieee->iw_mode == IW_MODE_ADHOC && | 7600 | priv->ieee->iw_mode == IW_MODE_ADHOC && |
7559 | priv->config & CFG_ADHOC_CREATE && | 7601 | priv->config & CFG_ADHOC_CREATE && |
7560 | priv->config & CFG_STATIC_ESSID && | 7602 | priv->config & CFG_STATIC_ESSID && |
7561 | priv->config & CFG_STATIC_CHANNEL && | 7603 | priv->config & CFG_STATIC_CHANNEL) { |
7562 | !list_empty(&priv->ieee->network_free_list)) { | 7604 | /* Use oldest network if the free list is empty */ |
7605 | if (list_empty(&priv->ieee->network_free_list)) { | ||
7606 | struct ieee80211_network *oldest = NULL; | ||
7607 | struct ieee80211_network *target; | ||
7608 | DECLARE_MAC_BUF(mac); | ||
7609 | |||
7610 | list_for_each_entry(target, &priv->ieee->network_list, list) { | ||
7611 | if ((oldest == NULL) || | ||
7612 | (target->last_scanned < oldest->last_scanned)) | ||
7613 | oldest = target; | ||
7614 | } | ||
7615 | |||
7616 | /* If there are no more slots, expire the oldest */ | ||
7617 | list_del(&oldest->list); | ||
7618 | target = oldest; | ||
7619 | IPW_DEBUG_ASSOC("Expired '%s' (%s) from " | ||
7620 | "network list.\n", | ||
7621 | escape_essid(target->ssid, | ||
7622 | target->ssid_len), | ||
7623 | print_mac(mac, target->bssid)); | ||
7624 | list_add_tail(&target->list, | ||
7625 | &priv->ieee->network_free_list); | ||
7626 | } | ||
7627 | |||
7563 | element = priv->ieee->network_free_list.next; | 7628 | element = priv->ieee->network_free_list.next; |
7564 | network = list_entry(element, struct ieee80211_network, list); | 7629 | network = list_entry(element, struct ieee80211_network, list); |
7565 | ipw_adhoc_create(priv, network); | 7630 | ipw_adhoc_create(priv, network); |
@@ -9454,99 +9519,38 @@ static int ipw_wx_get_retry(struct net_device *dev, | |||
9454 | return 0; | 9519 | return 0; |
9455 | } | 9520 | } |
9456 | 9521 | ||
9457 | static int ipw_request_direct_scan(struct ipw_priv *priv, char *essid, | ||
9458 | int essid_len) | ||
9459 | { | ||
9460 | struct ipw_scan_request_ext scan; | ||
9461 | int err = 0, scan_type; | ||
9462 | |||
9463 | if (!(priv->status & STATUS_INIT) || | ||
9464 | (priv->status & STATUS_EXIT_PENDING)) | ||
9465 | return 0; | ||
9466 | |||
9467 | mutex_lock(&priv->mutex); | ||
9468 | |||
9469 | if (priv->status & STATUS_RF_KILL_MASK) { | ||
9470 | IPW_DEBUG_HC("Aborting scan due to RF kill activation\n"); | ||
9471 | priv->status |= STATUS_SCAN_PENDING; | ||
9472 | goto done; | ||
9473 | } | ||
9474 | |||
9475 | IPW_DEBUG_HC("starting request direct scan!\n"); | ||
9476 | |||
9477 | if (priv->status & (STATUS_SCANNING | STATUS_SCAN_ABORTING)) { | ||
9478 | /* We should not sleep here; otherwise we will block most | ||
9479 | * of the system (for instance, we hold rtnl_lock when we | ||
9480 | * get here). | ||
9481 | */ | ||
9482 | err = -EAGAIN; | ||
9483 | goto done; | ||
9484 | } | ||
9485 | memset(&scan, 0, sizeof(scan)); | ||
9486 | |||
9487 | if (priv->config & CFG_SPEED_SCAN) | ||
9488 | scan.dwell_time[IPW_SCAN_ACTIVE_BROADCAST_SCAN] = | ||
9489 | cpu_to_le16(30); | ||
9490 | else | ||
9491 | scan.dwell_time[IPW_SCAN_ACTIVE_BROADCAST_SCAN] = | ||
9492 | cpu_to_le16(20); | ||
9493 | |||
9494 | scan.dwell_time[IPW_SCAN_ACTIVE_BROADCAST_AND_DIRECT_SCAN] = | ||
9495 | cpu_to_le16(20); | ||
9496 | scan.dwell_time[IPW_SCAN_PASSIVE_FULL_DWELL_SCAN] = cpu_to_le16(120); | ||
9497 | scan.dwell_time[IPW_SCAN_ACTIVE_DIRECT_SCAN] = cpu_to_le16(20); | ||
9498 | |||
9499 | scan.full_scan_index = cpu_to_le32(ieee80211_get_scans(priv->ieee)); | ||
9500 | |||
9501 | err = ipw_send_ssid(priv, essid, essid_len); | ||
9502 | if (err) { | ||
9503 | IPW_DEBUG_HC("Attempt to send SSID command failed\n"); | ||
9504 | goto done; | ||
9505 | } | ||
9506 | scan_type = IPW_SCAN_ACTIVE_BROADCAST_AND_DIRECT_SCAN; | ||
9507 | |||
9508 | ipw_add_scan_channels(priv, &scan, scan_type); | ||
9509 | |||
9510 | err = ipw_send_scan_request_ext(priv, &scan); | ||
9511 | if (err) { | ||
9512 | IPW_DEBUG_HC("Sending scan command failed: %08X\n", err); | ||
9513 | goto done; | ||
9514 | } | ||
9515 | |||
9516 | priv->status |= STATUS_SCANNING; | ||
9517 | |||
9518 | done: | ||
9519 | mutex_unlock(&priv->mutex); | ||
9520 | return err; | ||
9521 | } | ||
9522 | |||
9523 | static int ipw_wx_set_scan(struct net_device *dev, | 9522 | static int ipw_wx_set_scan(struct net_device *dev, |
9524 | struct iw_request_info *info, | 9523 | struct iw_request_info *info, |
9525 | union iwreq_data *wrqu, char *extra) | 9524 | union iwreq_data *wrqu, char *extra) |
9526 | { | 9525 | { |
9527 | struct ipw_priv *priv = ieee80211_priv(dev); | 9526 | struct ipw_priv *priv = ieee80211_priv(dev); |
9528 | struct iw_scan_req *req = (struct iw_scan_req *)extra; | 9527 | struct iw_scan_req *req = (struct iw_scan_req *)extra; |
9528 | struct delayed_work *work = NULL; | ||
9529 | 9529 | ||
9530 | mutex_lock(&priv->mutex); | 9530 | mutex_lock(&priv->mutex); |
9531 | |||
9531 | priv->user_requested_scan = 1; | 9532 | priv->user_requested_scan = 1; |
9532 | mutex_unlock(&priv->mutex); | ||
9533 | 9533 | ||
9534 | if (wrqu->data.length == sizeof(struct iw_scan_req)) { | 9534 | if (wrqu->data.length == sizeof(struct iw_scan_req)) { |
9535 | if (wrqu->data.flags & IW_SCAN_THIS_ESSID) { | 9535 | if (wrqu->data.flags & IW_SCAN_THIS_ESSID) { |
9536 | ipw_request_direct_scan(priv, req->essid, | 9536 | int len = min((int)req->essid_len, |
9537 | req->essid_len); | 9537 | (int)sizeof(priv->direct_scan_ssid)); |
9538 | return 0; | 9538 | memcpy(priv->direct_scan_ssid, req->essid, len); |
9539 | } | 9539 | priv->direct_scan_ssid_len = len; |
9540 | if (req->scan_type == IW_SCAN_TYPE_PASSIVE) { | 9540 | work = &priv->request_direct_scan; |
9541 | queue_work(priv->workqueue, | 9541 | } else if (req->scan_type == IW_SCAN_TYPE_PASSIVE) { |
9542 | &priv->request_passive_scan); | 9542 | work = &priv->request_passive_scan; |
9543 | return 0; | ||
9544 | } | 9543 | } |
9544 | } else { | ||
9545 | /* Normal active broadcast scan */ | ||
9546 | work = &priv->request_scan; | ||
9545 | } | 9547 | } |
9546 | 9548 | ||
9549 | mutex_unlock(&priv->mutex); | ||
9550 | |||
9547 | IPW_DEBUG_WX("Start scan\n"); | 9551 | IPW_DEBUG_WX("Start scan\n"); |
9548 | 9552 | ||
9549 | queue_delayed_work(priv->workqueue, &priv->request_scan, 0); | 9553 | queue_delayed_work(priv->workqueue, work, 0); |
9550 | 9554 | ||
9551 | return 0; | 9555 | return 0; |
9552 | } | 9556 | } |
@@ -10708,6 +10712,8 @@ static void ipw_link_up(struct ipw_priv *priv) | |||
10708 | } | 10712 | } |
10709 | 10713 | ||
10710 | cancel_delayed_work(&priv->request_scan); | 10714 | cancel_delayed_work(&priv->request_scan); |
10715 | cancel_delayed_work(&priv->request_direct_scan); | ||
10716 | cancel_delayed_work(&priv->request_passive_scan); | ||
10711 | cancel_delayed_work(&priv->scan_event); | 10717 | cancel_delayed_work(&priv->scan_event); |
10712 | ipw_reset_stats(priv); | 10718 | ipw_reset_stats(priv); |
10713 | /* Ensure the rate is updated immediately */ | 10719 | /* Ensure the rate is updated immediately */ |
@@ -10738,6 +10744,8 @@ static void ipw_link_down(struct ipw_priv *priv) | |||
10738 | 10744 | ||
10739 | /* Cancel any queued work ... */ | 10745 | /* Cancel any queued work ... */ |
10740 | cancel_delayed_work(&priv->request_scan); | 10746 | cancel_delayed_work(&priv->request_scan); |
10747 | cancel_delayed_work(&priv->request_direct_scan); | ||
10748 | cancel_delayed_work(&priv->request_passive_scan); | ||
10741 | cancel_delayed_work(&priv->adhoc_check); | 10749 | cancel_delayed_work(&priv->adhoc_check); |
10742 | cancel_delayed_work(&priv->gather_stats); | 10750 | cancel_delayed_work(&priv->gather_stats); |
10743 | 10751 | ||
@@ -10777,8 +10785,9 @@ static int __devinit ipw_setup_deferred_work(struct ipw_priv *priv) | |||
10777 | INIT_WORK(&priv->up, ipw_bg_up); | 10785 | INIT_WORK(&priv->up, ipw_bg_up); |
10778 | INIT_WORK(&priv->down, ipw_bg_down); | 10786 | INIT_WORK(&priv->down, ipw_bg_down); |
10779 | INIT_DELAYED_WORK(&priv->request_scan, ipw_request_scan); | 10787 | INIT_DELAYED_WORK(&priv->request_scan, ipw_request_scan); |
10788 | INIT_DELAYED_WORK(&priv->request_direct_scan, ipw_request_direct_scan); | ||
10789 | INIT_DELAYED_WORK(&priv->request_passive_scan, ipw_request_passive_scan); | ||
10780 | INIT_DELAYED_WORK(&priv->scan_event, ipw_scan_event); | 10790 | INIT_DELAYED_WORK(&priv->scan_event, ipw_scan_event); |
10781 | INIT_WORK(&priv->request_passive_scan, ipw_request_passive_scan); | ||
10782 | INIT_DELAYED_WORK(&priv->gather_stats, ipw_bg_gather_stats); | 10791 | INIT_DELAYED_WORK(&priv->gather_stats, ipw_bg_gather_stats); |
10783 | INIT_WORK(&priv->abort_scan, ipw_bg_abort_scan); | 10792 | INIT_WORK(&priv->abort_scan, ipw_bg_abort_scan); |
10784 | INIT_WORK(&priv->roam, ipw_bg_roam); | 10793 | INIT_WORK(&priv->roam, ipw_bg_roam); |
@@ -11584,6 +11593,7 @@ static int ipw_prom_alloc(struct ipw_priv *priv) | |||
11584 | priv->prom_net_dev->hard_start_xmit = ipw_prom_hard_start_xmit; | 11593 | priv->prom_net_dev->hard_start_xmit = ipw_prom_hard_start_xmit; |
11585 | 11594 | ||
11586 | priv->prom_priv->ieee->iw_mode = IW_MODE_MONITOR; | 11595 | priv->prom_priv->ieee->iw_mode = IW_MODE_MONITOR; |
11596 | SET_NETDEV_DEV(priv->prom_net_dev, &priv->pci_dev->dev); | ||
11587 | 11597 | ||
11588 | rc = register_netdev(priv->prom_net_dev); | 11598 | rc = register_netdev(priv->prom_net_dev); |
11589 | if (rc) { | 11599 | if (rc) { |
@@ -11811,6 +11821,8 @@ static void __devexit ipw_pci_remove(struct pci_dev *pdev) | |||
11811 | cancel_delayed_work(&priv->adhoc_check); | 11821 | cancel_delayed_work(&priv->adhoc_check); |
11812 | cancel_delayed_work(&priv->gather_stats); | 11822 | cancel_delayed_work(&priv->gather_stats); |
11813 | cancel_delayed_work(&priv->request_scan); | 11823 | cancel_delayed_work(&priv->request_scan); |
11824 | cancel_delayed_work(&priv->request_direct_scan); | ||
11825 | cancel_delayed_work(&priv->request_passive_scan); | ||
11814 | cancel_delayed_work(&priv->scan_event); | 11826 | cancel_delayed_work(&priv->scan_event); |
11815 | cancel_delayed_work(&priv->rf_kill); | 11827 | cancel_delayed_work(&priv->rf_kill); |
11816 | cancel_delayed_work(&priv->scan_check); | 11828 | cancel_delayed_work(&priv->scan_check); |
diff --git a/drivers/net/wireless/ipw2200.h b/drivers/net/wireless/ipw2200.h index cd3295b66dd6..d4ab28b73b32 100644 --- a/drivers/net/wireless/ipw2200.h +++ b/drivers/net/wireless/ipw2200.h | |||
@@ -1037,6 +1037,7 @@ struct ipw_cmd { /* XXX */ | |||
1037 | #define STATUS_DISASSOC_PENDING (1<<12) | 1037 | #define STATUS_DISASSOC_PENDING (1<<12) |
1038 | #define STATUS_STATE_PENDING (1<<13) | 1038 | #define STATUS_STATE_PENDING (1<<13) |
1039 | 1039 | ||
1040 | #define STATUS_DIRECT_SCAN_PENDING (1<<19) | ||
1040 | #define STATUS_SCAN_PENDING (1<<20) | 1041 | #define STATUS_SCAN_PENDING (1<<20) |
1041 | #define STATUS_SCANNING (1<<21) | 1042 | #define STATUS_SCANNING (1<<21) |
1042 | #define STATUS_SCAN_ABORTING (1<<22) | 1043 | #define STATUS_SCAN_ABORTING (1<<22) |
@@ -1292,6 +1293,8 @@ struct ipw_priv { | |||
1292 | struct iw_public_data wireless_data; | 1293 | struct iw_public_data wireless_data; |
1293 | 1294 | ||
1294 | int user_requested_scan; | 1295 | int user_requested_scan; |
1296 | u8 direct_scan_ssid[IW_ESSID_MAX_SIZE]; | ||
1297 | u8 direct_scan_ssid_len; | ||
1295 | 1298 | ||
1296 | struct workqueue_struct *workqueue; | 1299 | struct workqueue_struct *workqueue; |
1297 | 1300 | ||
@@ -1301,8 +1304,9 @@ struct ipw_priv { | |||
1301 | struct work_struct system_config; | 1304 | struct work_struct system_config; |
1302 | struct work_struct rx_replenish; | 1305 | struct work_struct rx_replenish; |
1303 | struct delayed_work request_scan; | 1306 | struct delayed_work request_scan; |
1307 | struct delayed_work request_direct_scan; | ||
1308 | struct delayed_work request_passive_scan; | ||
1304 | struct delayed_work scan_event; | 1309 | struct delayed_work scan_event; |
1305 | struct work_struct request_passive_scan; | ||
1306 | struct work_struct adapter_restart; | 1310 | struct work_struct adapter_restart; |
1307 | struct delayed_work rf_kill; | 1311 | struct delayed_work rf_kill; |
1308 | struct work_struct up; | 1312 | struct work_struct up; |
diff --git a/drivers/net/wireless/iwlwifi/Kconfig b/drivers/net/wireless/iwlwifi/Kconfig index d5b7a76fcaad..62fb89d82318 100644 --- a/drivers/net/wireless/iwlwifi/Kconfig +++ b/drivers/net/wireless/iwlwifi/Kconfig | |||
@@ -1,6 +1,5 @@ | |||
1 | config IWLWIFI | 1 | config IWLWIFI |
2 | bool | 2 | tristate |
3 | default n | ||
4 | 3 | ||
5 | config IWLCORE | 4 | config IWLCORE |
6 | tristate "Intel Wireless Wifi Core" | 5 | tristate "Intel Wireless Wifi Core" |
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-led.c b/drivers/net/wireless/iwlwifi/iwl-3945-led.c index d200d08fb086..8b1528e52d43 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945-led.c +++ b/drivers/net/wireless/iwlwifi/iwl-3945-led.c | |||
@@ -229,14 +229,15 @@ static int iwl3945_led_register_led(struct iwl3945_priv *priv, | |||
229 | led->led_dev.brightness_set = iwl3945_led_brightness_set; | 229 | led->led_dev.brightness_set = iwl3945_led_brightness_set; |
230 | led->led_dev.default_trigger = trigger; | 230 | led->led_dev.default_trigger = trigger; |
231 | 231 | ||
232 | led->priv = priv; | ||
233 | led->type = type; | ||
234 | |||
232 | ret = led_classdev_register(device, &led->led_dev); | 235 | ret = led_classdev_register(device, &led->led_dev); |
233 | if (ret) { | 236 | if (ret) { |
234 | IWL_ERROR("Error: failed to register led handler.\n"); | 237 | IWL_ERROR("Error: failed to register led handler.\n"); |
235 | return ret; | 238 | return ret; |
236 | } | 239 | } |
237 | 240 | ||
238 | led->priv = priv; | ||
239 | led->type = type; | ||
240 | led->registered = 1; | 241 | led->registered = 1; |
241 | 242 | ||
242 | if (set_led && led->led_on) | 243 | if (set_led && led->led_on) |
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c index d3406830c8e3..55ac850744b3 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945.c +++ b/drivers/net/wireless/iwlwifi/iwl-3945.c | |||
@@ -449,7 +449,7 @@ static void iwl3945_dbg_report_frame(struct iwl3945_priv *priv, | |||
449 | 449 | ||
450 | if (print_summary) { | 450 | if (print_summary) { |
451 | char *title; | 451 | char *title; |
452 | u32 rate; | 452 | int rate; |
453 | 453 | ||
454 | if (hundred) | 454 | if (hundred) |
455 | title = "100Frames"; | 455 | title = "100Frames"; |
@@ -487,7 +487,7 @@ static void iwl3945_dbg_report_frame(struct iwl3945_priv *priv, | |||
487 | * but you can hack it to show more, if you'd like to. */ | 487 | * but you can hack it to show more, if you'd like to. */ |
488 | if (dataframe) | 488 | if (dataframe) |
489 | IWL_DEBUG_RX("%s: mhd=0x%04x, dst=0x%02x, " | 489 | IWL_DEBUG_RX("%s: mhd=0x%04x, dst=0x%02x, " |
490 | "len=%u, rssi=%d, chnl=%d, rate=%u, \n", | 490 | "len=%u, rssi=%d, chnl=%d, rate=%d, \n", |
491 | title, fc, header->addr1[5], | 491 | title, fc, header->addr1[5], |
492 | length, rssi, channel, rate); | 492 | length, rssi, channel, rate); |
493 | else { | 493 | else { |
@@ -588,8 +588,12 @@ static void iwl3945_add_radiotap(struct iwl3945_priv *priv, | |||
588 | 588 | ||
589 | if (rate == -1) | 589 | if (rate == -1) |
590 | iwl3945_rt->rt_rate = 0; | 590 | iwl3945_rt->rt_rate = 0; |
591 | else | 591 | else { |
592 | if (stats->band == IEEE80211_BAND_5GHZ) | ||
593 | rate += IWL_FIRST_OFDM_RATE; | ||
594 | |||
592 | iwl3945_rt->rt_rate = iwl3945_rates[rate].ieee; | 595 | iwl3945_rt->rt_rate = iwl3945_rates[rate].ieee; |
596 | } | ||
593 | 597 | ||
594 | /* antenna number */ | 598 | /* antenna number */ |
595 | antenna = phy_flags_hw & RX_RES_PHY_FLAGS_ANTENNA_MSK; | 599 | antenna = phy_flags_hw & RX_RES_PHY_FLAGS_ANTENNA_MSK; |
@@ -666,7 +670,7 @@ static void iwl3945_rx_reply_rx(struct iwl3945_priv *priv, | |||
666 | rx_status.flag = 0; | 670 | rx_status.flag = 0; |
667 | rx_status.mactime = le64_to_cpu(rx_end->timestamp); | 671 | rx_status.mactime = le64_to_cpu(rx_end->timestamp); |
668 | rx_status.freq = | 672 | rx_status.freq = |
669 | ieee80211_frequency_to_channel(le16_to_cpu(rx_hdr->channel)); | 673 | ieee80211_channel_to_frequency(le16_to_cpu(rx_hdr->channel)); |
670 | rx_status.band = (rx_hdr->phy_flags & RX_RES_PHY_FLAGS_BAND_24_MSK) ? | 674 | rx_status.band = (rx_hdr->phy_flags & RX_RES_PHY_FLAGS_BAND_24_MSK) ? |
671 | IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ; | 675 | IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ; |
672 | 676 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.h b/drivers/net/wireless/iwlwifi/iwl-3945.h index 45c1c5533bf0..c7695a215a39 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945.h +++ b/drivers/net/wireless/iwlwifi/iwl-3945.h | |||
@@ -742,7 +742,6 @@ struct iwl3945_priv { | |||
742 | u8 direct_ssid_len; | 742 | u8 direct_ssid_len; |
743 | u8 direct_ssid[IW_ESSID_MAX_SIZE]; | 743 | u8 direct_ssid[IW_ESSID_MAX_SIZE]; |
744 | struct iwl3945_scan_cmd *scan; | 744 | struct iwl3945_scan_cmd *scan; |
745 | u8 only_active_channel; | ||
746 | 745 | ||
747 | /* spinlock */ | 746 | /* spinlock */ |
748 | spinlock_t lock; /* protect general shared data */ | 747 | spinlock_t lock; /* protect general shared data */ |
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965-rs.c b/drivers/net/wireless/iwlwifi/iwl-4965-rs.c index b608e1ca8b40..3a7f0cb710ec 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965-rs.c +++ b/drivers/net/wireless/iwlwifi/iwl-4965-rs.c | |||
@@ -163,8 +163,8 @@ struct iwl4965_lq_sta { | |||
163 | struct dentry *rs_sta_dbgfs_tx_agg_tid_en_file; | 163 | struct dentry *rs_sta_dbgfs_tx_agg_tid_en_file; |
164 | #endif | 164 | #endif |
165 | struct iwl4965_rate dbg_fixed; | 165 | struct iwl4965_rate dbg_fixed; |
166 | struct iwl_priv *drv; | ||
167 | #endif | 166 | #endif |
167 | struct iwl_priv *drv; | ||
168 | }; | 168 | }; |
169 | 169 | ||
170 | static void rs_rate_scale_perform(struct iwl_priv *priv, | 170 | static void rs_rate_scale_perform(struct iwl_priv *priv, |
@@ -1162,7 +1162,6 @@ static s32 rs_get_best_rate(struct iwl_priv *priv, | |||
1162 | 1162 | ||
1163 | /* Higher rate not available, use the original */ | 1163 | /* Higher rate not available, use the original */ |
1164 | } else { | 1164 | } else { |
1165 | new_rate = rate; | ||
1166 | break; | 1165 | break; |
1167 | } | 1166 | } |
1168 | } | 1167 | } |
@@ -2009,7 +2008,7 @@ static void rs_rate_scale_perform(struct iwl_priv *priv, | |||
2009 | * 2) Not just finishing up a search | 2008 | * 2) Not just finishing up a search |
2010 | * 3) Allowing a new search | 2009 | * 3) Allowing a new search |
2011 | */ | 2010 | */ |
2012 | if (!update_lq && !done_search && !lq_sta->stay_in_tbl) { | 2011 | if (!update_lq && !done_search && !lq_sta->stay_in_tbl && window->counter) { |
2013 | /* Save current throughput to compare with "search" throughput*/ | 2012 | /* Save current throughput to compare with "search" throughput*/ |
2014 | lq_sta->last_tpt = current_tpt; | 2013 | lq_sta->last_tpt = current_tpt; |
2015 | 2014 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c index 17f629fb96ff..de330ae0ca95 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965.c +++ b/drivers/net/wireless/iwlwifi/iwl-4965.c | |||
@@ -3528,8 +3528,12 @@ static void iwl4965_add_radiotap(struct iwl_priv *priv, | |||
3528 | 3528 | ||
3529 | if (rate == -1) | 3529 | if (rate == -1) |
3530 | iwl4965_rt->rt_rate = 0; | 3530 | iwl4965_rt->rt_rate = 0; |
3531 | else | 3531 | else { |
3532 | if (stats->band == IEEE80211_BAND_5GHZ) | ||
3533 | rate += IWL_FIRST_OFDM_RATE; | ||
3534 | |||
3532 | iwl4965_rt->rt_rate = iwl4965_rates[rate].ieee; | 3535 | iwl4965_rt->rt_rate = iwl4965_rates[rate].ieee; |
3536 | } | ||
3533 | 3537 | ||
3534 | /* | 3538 | /* |
3535 | * "antenna number" | 3539 | * "antenna number" |
@@ -3978,7 +3982,7 @@ static void iwl4965_rx_reply_rx(struct iwl_priv *priv, | |||
3978 | 3982 | ||
3979 | rx_status.mactime = le64_to_cpu(rx_start->timestamp); | 3983 | rx_status.mactime = le64_to_cpu(rx_start->timestamp); |
3980 | rx_status.freq = | 3984 | rx_status.freq = |
3981 | ieee80211_frequency_to_channel(le16_to_cpu(rx_start->channel)); | 3985 | ieee80211_channel_to_frequency(le16_to_cpu(rx_start->channel)); |
3982 | rx_status.band = (rx_start->phy_flags & RX_RES_PHY_FLAGS_BAND_24_MSK) ? | 3986 | rx_status.band = (rx_start->phy_flags & RX_RES_PHY_FLAGS_BAND_24_MSK) ? |
3983 | IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ; | 3987 | IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ; |
3984 | rx_status.rate_idx = | 3988 | rx_status.rate_idx = |
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.h b/drivers/net/wireless/iwlwifi/iwl-4965.h index 9ed13cb0a2a9..581b98556c86 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965.h +++ b/drivers/net/wireless/iwlwifi/iwl-4965.h | |||
@@ -996,7 +996,6 @@ struct iwl_priv { | |||
996 | u8 direct_ssid_len; | 996 | u8 direct_ssid_len; |
997 | u8 direct_ssid[IW_ESSID_MAX_SIZE]; | 997 | u8 direct_ssid[IW_ESSID_MAX_SIZE]; |
998 | struct iwl4965_scan_cmd *scan; | 998 | struct iwl4965_scan_cmd *scan; |
999 | u8 only_active_channel; | ||
1000 | 999 | ||
1001 | /* spinlock */ | 1000 | /* spinlock */ |
1002 | spinlock_t lock; /* protect general shared data */ | 1001 | spinlock_t lock; /* protect general shared data */ |
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index a1a0b3c581f1..6027e1119c3f 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c | |||
@@ -2227,7 +2227,10 @@ static int iwl3945_scan_initiate(struct iwl3945_priv *priv) | |||
2227 | } | 2227 | } |
2228 | 2228 | ||
2229 | IWL_DEBUG_INFO("Starting scan...\n"); | 2229 | IWL_DEBUG_INFO("Starting scan...\n"); |
2230 | priv->scan_bands = 2; | 2230 | if (priv->cfg->sku & IWL_SKU_G) |
2231 | priv->scan_bands |= BIT(IEEE80211_BAND_2GHZ); | ||
2232 | if (priv->cfg->sku & IWL_SKU_A) | ||
2233 | priv->scan_bands |= BIT(IEEE80211_BAND_5GHZ); | ||
2231 | set_bit(STATUS_SCANNING, &priv->status); | 2234 | set_bit(STATUS_SCANNING, &priv->status); |
2232 | priv->scan_start = jiffies; | 2235 | priv->scan_start = jiffies; |
2233 | priv->scan_pass_start = priv->scan_start; | 2236 | priv->scan_pass_start = priv->scan_start; |
@@ -3352,13 +3355,18 @@ static void iwl3945_rx_scan_complete_notif(struct iwl3945_priv *priv, | |||
3352 | cancel_delayed_work(&priv->scan_check); | 3355 | cancel_delayed_work(&priv->scan_check); |
3353 | 3356 | ||
3354 | IWL_DEBUG_INFO("Scan pass on %sGHz took %dms\n", | 3357 | IWL_DEBUG_INFO("Scan pass on %sGHz took %dms\n", |
3355 | (priv->scan_bands == 2) ? "2.4" : "5.2", | 3358 | (priv->scan_bands & BIT(IEEE80211_BAND_2GHZ)) ? |
3359 | "2.4" : "5.2", | ||
3356 | jiffies_to_msecs(elapsed_jiffies | 3360 | jiffies_to_msecs(elapsed_jiffies |
3357 | (priv->scan_pass_start, jiffies))); | 3361 | (priv->scan_pass_start, jiffies))); |
3358 | 3362 | ||
3359 | /* Remove this scanned band from the list | 3363 | /* Remove this scanned band from the list of pending |
3360 | * of pending bands to scan */ | 3364 | * bands to scan, band G precedes A in order of scanning |
3361 | priv->scan_bands--; | 3365 | * as seen in iwl3945_bg_request_scan */ |
3366 | if (priv->scan_bands & BIT(IEEE80211_BAND_2GHZ)) | ||
3367 | priv->scan_bands &= ~BIT(IEEE80211_BAND_2GHZ); | ||
3368 | else if (priv->scan_bands & BIT(IEEE80211_BAND_5GHZ)) | ||
3369 | priv->scan_bands &= ~BIT(IEEE80211_BAND_5GHZ); | ||
3362 | 3370 | ||
3363 | /* If a request to abort was given, or the scan did not succeed | 3371 | /* If a request to abort was given, or the scan did not succeed |
3364 | * then we reset the scan state machine and terminate, | 3372 | * then we reset the scan state machine and terminate, |
@@ -4968,22 +4976,11 @@ static int iwl3945_get_channels_for_scan(struct iwl3945_priv *priv, | |||
4968 | if (channels[i].flags & IEEE80211_CHAN_DISABLED) | 4976 | if (channels[i].flags & IEEE80211_CHAN_DISABLED) |
4969 | continue; | 4977 | continue; |
4970 | 4978 | ||
4971 | if (channels[i].hw_value == | ||
4972 | le16_to_cpu(priv->active_rxon.channel)) { | ||
4973 | if (iwl3945_is_associated(priv)) { | ||
4974 | IWL_DEBUG_SCAN | ||
4975 | ("Skipping current channel %d\n", | ||
4976 | le16_to_cpu(priv->active_rxon.channel)); | ||
4977 | continue; | ||
4978 | } | ||
4979 | } else if (priv->only_active_channel) | ||
4980 | continue; | ||
4981 | |||
4982 | scan_ch->channel = channels[i].hw_value; | 4979 | scan_ch->channel = channels[i].hw_value; |
4983 | 4980 | ||
4984 | ch_info = iwl3945_get_channel_info(priv, band, scan_ch->channel); | 4981 | ch_info = iwl3945_get_channel_info(priv, band, scan_ch->channel); |
4985 | if (!is_channel_valid(ch_info)) { | 4982 | if (!is_channel_valid(ch_info)) { |
4986 | IWL_DEBUG_SCAN("Channel %d is INVALID for this SKU.\n", | 4983 | IWL_DEBUG_SCAN("Channel %d is INVALID for this band.\n", |
4987 | scan_ch->channel); | 4984 | scan_ch->channel); |
4988 | continue; | 4985 | continue; |
4989 | } | 4986 | } |
@@ -6303,12 +6300,17 @@ static void iwl3945_bg_request_scan(struct work_struct *data) | |||
6303 | priv->direct_ssid, priv->direct_ssid_len); | 6300 | priv->direct_ssid, priv->direct_ssid_len); |
6304 | direct_mask = 1; | 6301 | direct_mask = 1; |
6305 | } else if (!iwl3945_is_associated(priv) && priv->essid_len) { | 6302 | } else if (!iwl3945_is_associated(priv) && priv->essid_len) { |
6303 | IWL_DEBUG_SCAN | ||
6304 | ("Kicking off one direct scan for '%s' when not associated\n", | ||
6305 | iwl3945_escape_essid(priv->essid, priv->essid_len)); | ||
6306 | scan->direct_scan[0].id = WLAN_EID_SSID; | 6306 | scan->direct_scan[0].id = WLAN_EID_SSID; |
6307 | scan->direct_scan[0].len = priv->essid_len; | 6307 | scan->direct_scan[0].len = priv->essid_len; |
6308 | memcpy(scan->direct_scan[0].ssid, priv->essid, priv->essid_len); | 6308 | memcpy(scan->direct_scan[0].ssid, priv->essid, priv->essid_len); |
6309 | direct_mask = 1; | 6309 | direct_mask = 1; |
6310 | } else | 6310 | } else { |
6311 | IWL_DEBUG_SCAN("Kicking off one indirect scan.\n"); | ||
6311 | direct_mask = 0; | 6312 | direct_mask = 0; |
6313 | } | ||
6312 | 6314 | ||
6313 | /* We don't build a direct scan probe request; the uCode will do | 6315 | /* We don't build a direct scan probe request; the uCode will do |
6314 | * that based on the direct_mask added to each channel entry */ | 6316 | * that based on the direct_mask added to each channel entry */ |
@@ -6321,21 +6323,16 @@ static void iwl3945_bg_request_scan(struct work_struct *data) | |||
6321 | 6323 | ||
6322 | /* flags + rate selection */ | 6324 | /* flags + rate selection */ |
6323 | 6325 | ||
6324 | switch (priv->scan_bands) { | 6326 | if (priv->scan_bands & BIT(IEEE80211_BAND_2GHZ)) { |
6325 | case 2: | ||
6326 | scan->flags = RXON_FLG_BAND_24G_MSK | RXON_FLG_AUTO_DETECT_MSK; | 6327 | scan->flags = RXON_FLG_BAND_24G_MSK | RXON_FLG_AUTO_DETECT_MSK; |
6327 | scan->tx_cmd.rate = IWL_RATE_1M_PLCP; | 6328 | scan->tx_cmd.rate = IWL_RATE_1M_PLCP; |
6328 | scan->good_CRC_th = 0; | 6329 | scan->good_CRC_th = 0; |
6329 | band = IEEE80211_BAND_2GHZ; | 6330 | band = IEEE80211_BAND_2GHZ; |
6330 | break; | 6331 | } else if (priv->scan_bands & BIT(IEEE80211_BAND_5GHZ)) { |
6331 | |||
6332 | case 1: | ||
6333 | scan->tx_cmd.rate = IWL_RATE_6M_PLCP; | 6332 | scan->tx_cmd.rate = IWL_RATE_6M_PLCP; |
6334 | scan->good_CRC_th = IWL_GOOD_CRC_TH; | 6333 | scan->good_CRC_th = IWL_GOOD_CRC_TH; |
6335 | band = IEEE80211_BAND_5GHZ; | 6334 | band = IEEE80211_BAND_5GHZ; |
6336 | break; | 6335 | } else { |
6337 | |||
6338 | default: | ||
6339 | IWL_WARNING("Invalid scan band count\n"); | 6336 | IWL_WARNING("Invalid scan band count\n"); |
6340 | goto done; | 6337 | goto done; |
6341 | } | 6338 | } |
@@ -6346,23 +6343,18 @@ static void iwl3945_bg_request_scan(struct work_struct *data) | |||
6346 | if (priv->iw_mode == IEEE80211_IF_TYPE_MNTR) | 6343 | if (priv->iw_mode == IEEE80211_IF_TYPE_MNTR) |
6347 | scan->filter_flags = RXON_FILTER_PROMISC_MSK; | 6344 | scan->filter_flags = RXON_FILTER_PROMISC_MSK; |
6348 | 6345 | ||
6349 | if (direct_mask) { | 6346 | if (direct_mask) |
6350 | IWL_DEBUG_SCAN | ||
6351 | ("Initiating direct scan for %s.\n", | ||
6352 | iwl3945_escape_essid(priv->essid, priv->essid_len)); | ||
6353 | scan->channel_count = | 6347 | scan->channel_count = |
6354 | iwl3945_get_channels_for_scan( | 6348 | iwl3945_get_channels_for_scan( |
6355 | priv, band, 1, /* active */ | 6349 | priv, band, 1, /* active */ |
6356 | direct_mask, | 6350 | direct_mask, |
6357 | (void *)&scan->data[le16_to_cpu(scan->tx_cmd.len)]); | 6351 | (void *)&scan->data[le16_to_cpu(scan->tx_cmd.len)]); |
6358 | } else { | 6352 | else |
6359 | IWL_DEBUG_SCAN("Initiating indirect scan.\n"); | ||
6360 | scan->channel_count = | 6353 | scan->channel_count = |
6361 | iwl3945_get_channels_for_scan( | 6354 | iwl3945_get_channels_for_scan( |
6362 | priv, band, 0, /* passive */ | 6355 | priv, band, 0, /* passive */ |
6363 | direct_mask, | 6356 | direct_mask, |
6364 | (void *)&scan->data[le16_to_cpu(scan->tx_cmd.len)]); | 6357 | (void *)&scan->data[le16_to_cpu(scan->tx_cmd.len)]); |
6365 | } | ||
6366 | 6358 | ||
6367 | cmd.len += le16_to_cpu(scan->tx_cmd.len) + | 6359 | cmd.len += le16_to_cpu(scan->tx_cmd.len) + |
6368 | scan->channel_count * sizeof(struct iwl3945_scan_channel); | 6360 | scan->channel_count * sizeof(struct iwl3945_scan_channel); |
@@ -6695,7 +6687,8 @@ static int iwl3945_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
6695 | 6687 | ||
6696 | if (priv->iw_mode == IEEE80211_IF_TYPE_MNTR) { | 6688 | if (priv->iw_mode == IEEE80211_IF_TYPE_MNTR) { |
6697 | IWL_DEBUG_MAC80211("leave - monitor\n"); | 6689 | IWL_DEBUG_MAC80211("leave - monitor\n"); |
6698 | return -1; | 6690 | dev_kfree_skb_any(skb); |
6691 | return 0; | ||
6699 | } | 6692 | } |
6700 | 6693 | ||
6701 | IWL_DEBUG_TX("dev->xmit(%d bytes) at rate 0x%02x\n", skb->len, | 6694 | IWL_DEBUG_TX("dev->xmit(%d bytes) at rate 0x%02x\n", skb->len, |
@@ -6781,7 +6774,7 @@ static int iwl3945_mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *co | |||
6781 | ch_info = iwl3945_get_channel_info(priv, conf->channel->band, | 6774 | ch_info = iwl3945_get_channel_info(priv, conf->channel->band, |
6782 | conf->channel->hw_value); | 6775 | conf->channel->hw_value); |
6783 | if (!is_channel_valid(ch_info)) { | 6776 | if (!is_channel_valid(ch_info)) { |
6784 | IWL_DEBUG_SCAN("Channel %d [%d] is INVALID for this SKU.\n", | 6777 | IWL_DEBUG_SCAN("Channel %d [%d] is INVALID for this band.\n", |
6785 | conf->channel->hw_value, conf->channel->band); | 6778 | conf->channel->hw_value, conf->channel->band); |
6786 | IWL_DEBUG_MAC80211("leave - invalid channel\n"); | 6779 | IWL_DEBUG_MAC80211("leave - invalid channel\n"); |
6787 | spin_unlock_irqrestore(&priv->lock, flags); | 6780 | spin_unlock_irqrestore(&priv->lock, flags); |
@@ -7314,8 +7307,6 @@ static void iwl3945_mac_reset_tsf(struct ieee80211_hw *hw) | |||
7314 | return; | 7307 | return; |
7315 | } | 7308 | } |
7316 | 7309 | ||
7317 | priv->only_active_channel = 0; | ||
7318 | |||
7319 | iwl3945_set_rate(priv); | 7310 | iwl3945_set_rate(priv); |
7320 | 7311 | ||
7321 | mutex_unlock(&priv->mutex); | 7312 | mutex_unlock(&priv->mutex); |
diff --git a/drivers/net/wireless/iwlwifi/iwl4965-base.c b/drivers/net/wireless/iwlwifi/iwl4965-base.c index d0bbcaaeb94c..0bd55bb19739 100644 --- a/drivers/net/wireless/iwlwifi/iwl4965-base.c +++ b/drivers/net/wireless/iwlwifi/iwl4965-base.c | |||
@@ -1774,7 +1774,10 @@ static int iwl4965_scan_initiate(struct iwl_priv *priv) | |||
1774 | } | 1774 | } |
1775 | 1775 | ||
1776 | IWL_DEBUG_INFO("Starting scan...\n"); | 1776 | IWL_DEBUG_INFO("Starting scan...\n"); |
1777 | priv->scan_bands = 2; | 1777 | if (priv->cfg->sku & IWL_SKU_G) |
1778 | priv->scan_bands |= BIT(IEEE80211_BAND_2GHZ); | ||
1779 | if (priv->cfg->sku & IWL_SKU_A) | ||
1780 | priv->scan_bands |= BIT(IEEE80211_BAND_5GHZ); | ||
1778 | set_bit(STATUS_SCANNING, &priv->status); | 1781 | set_bit(STATUS_SCANNING, &priv->status); |
1779 | priv->scan_start = jiffies; | 1782 | priv->scan_start = jiffies; |
1780 | priv->scan_pass_start = priv->scan_start; | 1783 | priv->scan_pass_start = priv->scan_start; |
@@ -3023,8 +3026,9 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv, | |||
3023 | 3026 | ||
3024 | IWL_DEBUG_TX_REPLY("Tx queue reclaim %d\n", index); | 3027 | IWL_DEBUG_TX_REPLY("Tx queue reclaim %d\n", index); |
3025 | if (index != -1) { | 3028 | if (index != -1) { |
3026 | int freed = iwl4965_tx_queue_reclaim(priv, txq_id, index); | ||
3027 | #ifdef CONFIG_IWL4965_HT | 3029 | #ifdef CONFIG_IWL4965_HT |
3030 | int freed = iwl4965_tx_queue_reclaim(priv, txq_id, index); | ||
3031 | |||
3028 | if (tid != MAX_TID_COUNT) | 3032 | if (tid != MAX_TID_COUNT) |
3029 | priv->stations[sta_id].tid[tid].tfds_in_queue -= freed; | 3033 | priv->stations[sta_id].tid[tid].tfds_in_queue -= freed; |
3030 | if (iwl4965_queue_space(&txq->q) > txq->q.low_mark && | 3034 | if (iwl4965_queue_space(&txq->q) > txq->q.low_mark && |
@@ -3276,13 +3280,18 @@ static void iwl4965_rx_scan_complete_notif(struct iwl_priv *priv, | |||
3276 | cancel_delayed_work(&priv->scan_check); | 3280 | cancel_delayed_work(&priv->scan_check); |
3277 | 3281 | ||
3278 | IWL_DEBUG_INFO("Scan pass on %sGHz took %dms\n", | 3282 | IWL_DEBUG_INFO("Scan pass on %sGHz took %dms\n", |
3279 | (priv->scan_bands == 2) ? "2.4" : "5.2", | 3283 | (priv->scan_bands & BIT(IEEE80211_BAND_2GHZ)) ? |
3284 | "2.4" : "5.2", | ||
3280 | jiffies_to_msecs(elapsed_jiffies | 3285 | jiffies_to_msecs(elapsed_jiffies |
3281 | (priv->scan_pass_start, jiffies))); | 3286 | (priv->scan_pass_start, jiffies))); |
3282 | 3287 | ||
3283 | /* Remove this scanned band from the list | 3288 | /* Remove this scanned band from the list of pending |
3284 | * of pending bands to scan */ | 3289 | * bands to scan, band G precedes A in order of scanning |
3285 | priv->scan_bands--; | 3290 | * as seen in iwl_bg_request_scan */ |
3291 | if (priv->scan_bands & BIT(IEEE80211_BAND_2GHZ)) | ||
3292 | priv->scan_bands &= ~BIT(IEEE80211_BAND_2GHZ); | ||
3293 | else if (priv->scan_bands & BIT(IEEE80211_BAND_5GHZ)) | ||
3294 | priv->scan_bands &= ~BIT(IEEE80211_BAND_5GHZ); | ||
3286 | 3295 | ||
3287 | /* If a request to abort was given, or the scan did not succeed | 3296 | /* If a request to abort was given, or the scan did not succeed |
3288 | * then we reset the scan state machine and terminate, | 3297 | * then we reset the scan state machine and terminate, |
@@ -3292,7 +3301,7 @@ static void iwl4965_rx_scan_complete_notif(struct iwl_priv *priv, | |||
3292 | clear_bit(STATUS_SCAN_ABORTING, &priv->status); | 3301 | clear_bit(STATUS_SCAN_ABORTING, &priv->status); |
3293 | } else { | 3302 | } else { |
3294 | /* If there are more bands on this scan pass reschedule */ | 3303 | /* If there are more bands on this scan pass reschedule */ |
3295 | if (priv->scan_bands > 0) | 3304 | if (priv->scan_bands) |
3296 | goto reschedule; | 3305 | goto reschedule; |
3297 | } | 3306 | } |
3298 | 3307 | ||
@@ -4633,23 +4642,11 @@ static int iwl4965_get_channels_for_scan(struct iwl_priv *priv, | |||
4633 | if (channels[i].flags & IEEE80211_CHAN_DISABLED) | 4642 | if (channels[i].flags & IEEE80211_CHAN_DISABLED) |
4634 | continue; | 4643 | continue; |
4635 | 4644 | ||
4636 | if (ieee80211_frequency_to_channel(channels[i].center_freq) == | ||
4637 | le16_to_cpu(priv->active_rxon.channel)) { | ||
4638 | if (iwl_is_associated(priv)) { | ||
4639 | IWL_DEBUG_SCAN | ||
4640 | ("Skipping current channel %d\n", | ||
4641 | le16_to_cpu(priv->active_rxon.channel)); | ||
4642 | continue; | ||
4643 | } | ||
4644 | } else if (priv->only_active_channel) | ||
4645 | continue; | ||
4646 | |||
4647 | scan_ch->channel = ieee80211_frequency_to_channel(channels[i].center_freq); | 4645 | scan_ch->channel = ieee80211_frequency_to_channel(channels[i].center_freq); |
4648 | 4646 | ||
4649 | ch_info = iwl_get_channel_info(priv, band, | 4647 | ch_info = iwl_get_channel_info(priv, band, scan_ch->channel); |
4650 | scan_ch->channel); | ||
4651 | if (!is_channel_valid(ch_info)) { | 4648 | if (!is_channel_valid(ch_info)) { |
4652 | IWL_DEBUG_SCAN("Channel %d is INVALID for this SKU.\n", | 4649 | IWL_DEBUG_SCAN("Channel %d is INVALID for this band.\n", |
4653 | scan_ch->channel); | 4650 | scan_ch->channel); |
4654 | continue; | 4651 | continue; |
4655 | } | 4652 | } |
@@ -5824,11 +5821,15 @@ static void iwl4965_bg_request_scan(struct work_struct *data) | |||
5824 | priv->direct_ssid, priv->direct_ssid_len); | 5821 | priv->direct_ssid, priv->direct_ssid_len); |
5825 | direct_mask = 1; | 5822 | direct_mask = 1; |
5826 | } else if (!iwl_is_associated(priv) && priv->essid_len) { | 5823 | } else if (!iwl_is_associated(priv) && priv->essid_len) { |
5824 | IWL_DEBUG_SCAN | ||
5825 | ("Kicking off one direct scan for '%s' when not associated\n", | ||
5826 | iwl4965_escape_essid(priv->essid, priv->essid_len)); | ||
5827 | scan->direct_scan[0].id = WLAN_EID_SSID; | 5827 | scan->direct_scan[0].id = WLAN_EID_SSID; |
5828 | scan->direct_scan[0].len = priv->essid_len; | 5828 | scan->direct_scan[0].len = priv->essid_len; |
5829 | memcpy(scan->direct_scan[0].ssid, priv->essid, priv->essid_len); | 5829 | memcpy(scan->direct_scan[0].ssid, priv->essid, priv->essid_len); |
5830 | direct_mask = 1; | 5830 | direct_mask = 1; |
5831 | } else { | 5831 | } else { |
5832 | IWL_DEBUG_SCAN("Kicking off one indirect scan.\n"); | ||
5832 | direct_mask = 0; | 5833 | direct_mask = 0; |
5833 | } | 5834 | } |
5834 | 5835 | ||
@@ -5837,8 +5838,7 @@ static void iwl4965_bg_request_scan(struct work_struct *data) | |||
5837 | scan->tx_cmd.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE; | 5838 | scan->tx_cmd.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE; |
5838 | 5839 | ||
5839 | 5840 | ||
5840 | switch (priv->scan_bands) { | 5841 | if (priv->scan_bands & BIT(IEEE80211_BAND_2GHZ)) { |
5841 | case 2: | ||
5842 | scan->flags = RXON_FLG_BAND_24G_MSK | RXON_FLG_AUTO_DETECT_MSK; | 5842 | scan->flags = RXON_FLG_BAND_24G_MSK | RXON_FLG_AUTO_DETECT_MSK; |
5843 | scan->tx_cmd.rate_n_flags = | 5843 | scan->tx_cmd.rate_n_flags = |
5844 | iwl4965_hw_set_rate_n_flags(IWL_RATE_1M_PLCP, | 5844 | iwl4965_hw_set_rate_n_flags(IWL_RATE_1M_PLCP, |
@@ -5846,17 +5846,13 @@ static void iwl4965_bg_request_scan(struct work_struct *data) | |||
5846 | 5846 | ||
5847 | scan->good_CRC_th = 0; | 5847 | scan->good_CRC_th = 0; |
5848 | band = IEEE80211_BAND_2GHZ; | 5848 | band = IEEE80211_BAND_2GHZ; |
5849 | break; | 5849 | } else if (priv->scan_bands & BIT(IEEE80211_BAND_5GHZ)) { |
5850 | |||
5851 | case 1: | ||
5852 | scan->tx_cmd.rate_n_flags = | 5850 | scan->tx_cmd.rate_n_flags = |
5853 | iwl4965_hw_set_rate_n_flags(IWL_RATE_6M_PLCP, | 5851 | iwl4965_hw_set_rate_n_flags(IWL_RATE_6M_PLCP, |
5854 | RATE_MCS_ANT_B_MSK); | 5852 | RATE_MCS_ANT_B_MSK); |
5855 | scan->good_CRC_th = IWL_GOOD_CRC_TH; | 5853 | scan->good_CRC_th = IWL_GOOD_CRC_TH; |
5856 | band = IEEE80211_BAND_5GHZ; | 5854 | band = IEEE80211_BAND_5GHZ; |
5857 | break; | 5855 | } else { |
5858 | |||
5859 | default: | ||
5860 | IWL_WARNING("Invalid scan band count\n"); | 5856 | IWL_WARNING("Invalid scan band count\n"); |
5861 | goto done; | 5857 | goto done; |
5862 | } | 5858 | } |
@@ -5881,23 +5877,18 @@ static void iwl4965_bg_request_scan(struct work_struct *data) | |||
5881 | if (priv->iw_mode == IEEE80211_IF_TYPE_MNTR) | 5877 | if (priv->iw_mode == IEEE80211_IF_TYPE_MNTR) |
5882 | scan->filter_flags = RXON_FILTER_PROMISC_MSK; | 5878 | scan->filter_flags = RXON_FILTER_PROMISC_MSK; |
5883 | 5879 | ||
5884 | if (direct_mask) { | 5880 | if (direct_mask) |
5885 | IWL_DEBUG_SCAN | ||
5886 | ("Initiating direct scan for %s.\n", | ||
5887 | iwl4965_escape_essid(priv->essid, priv->essid_len)); | ||
5888 | scan->channel_count = | 5881 | scan->channel_count = |
5889 | iwl4965_get_channels_for_scan( | 5882 | iwl4965_get_channels_for_scan( |
5890 | priv, band, 1, /* active */ | 5883 | priv, band, 1, /* active */ |
5891 | direct_mask, | 5884 | direct_mask, |
5892 | (void *)&scan->data[le16_to_cpu(scan->tx_cmd.len)]); | 5885 | (void *)&scan->data[le16_to_cpu(scan->tx_cmd.len)]); |
5893 | } else { | 5886 | else |
5894 | IWL_DEBUG_SCAN("Initiating indirect scan.\n"); | ||
5895 | scan->channel_count = | 5887 | scan->channel_count = |
5896 | iwl4965_get_channels_for_scan( | 5888 | iwl4965_get_channels_for_scan( |
5897 | priv, band, 0, /* passive */ | 5889 | priv, band, 0, /* passive */ |
5898 | direct_mask, | 5890 | direct_mask, |
5899 | (void *)&scan->data[le16_to_cpu(scan->tx_cmd.len)]); | 5891 | (void *)&scan->data[le16_to_cpu(scan->tx_cmd.len)]); |
5900 | } | ||
5901 | 5892 | ||
5902 | cmd.len += le16_to_cpu(scan->tx_cmd.len) + | 5893 | cmd.len += le16_to_cpu(scan->tx_cmd.len) + |
5903 | scan->channel_count * sizeof(struct iwl4965_scan_channel); | 5894 | scan->channel_count * sizeof(struct iwl4965_scan_channel); |
@@ -6246,7 +6237,8 @@ static int iwl4965_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
6246 | 6237 | ||
6247 | if (priv->iw_mode == IEEE80211_IF_TYPE_MNTR) { | 6238 | if (priv->iw_mode == IEEE80211_IF_TYPE_MNTR) { |
6248 | IWL_DEBUG_MAC80211("leave - monitor\n"); | 6239 | IWL_DEBUG_MAC80211("leave - monitor\n"); |
6249 | return -1; | 6240 | dev_kfree_skb_any(skb); |
6241 | return 0; | ||
6250 | } | 6242 | } |
6251 | 6243 | ||
6252 | IWL_DEBUG_TX("dev->xmit(%d bytes) at rate 0x%02x\n", skb->len, | 6244 | IWL_DEBUG_TX("dev->xmit(%d bytes) at rate 0x%02x\n", skb->len, |
@@ -7061,8 +7053,6 @@ static void iwl4965_mac_reset_tsf(struct ieee80211_hw *hw) | |||
7061 | return; | 7053 | return; |
7062 | } | 7054 | } |
7063 | 7055 | ||
7064 | priv->only_active_channel = 0; | ||
7065 | |||
7066 | iwl4965_set_rate(priv); | 7056 | iwl4965_set_rate(priv); |
7067 | 7057 | ||
7068 | mutex_unlock(&priv->mutex); | 7058 | mutex_unlock(&priv->mutex); |
diff --git a/drivers/net/wireless/libertas/cmd.c b/drivers/net/wireless/libertas/cmd.c index 6328b9593877..8124fd9b1353 100644 --- a/drivers/net/wireless/libertas/cmd.c +++ b/drivers/net/wireless/libertas/cmd.c | |||
@@ -1842,6 +1842,9 @@ static void lbs_send_confirmsleep(struct lbs_private *priv) | |||
1842 | 1842 | ||
1843 | spin_lock_irqsave(&priv->driver_lock, flags); | 1843 | spin_lock_irqsave(&priv->driver_lock, flags); |
1844 | 1844 | ||
1845 | /* We don't get a response on the sleep-confirmation */ | ||
1846 | priv->dnld_sent = DNLD_RES_RECEIVED; | ||
1847 | |||
1845 | /* If nothing to do, go back to sleep (?) */ | 1848 | /* If nothing to do, go back to sleep (?) */ |
1846 | if (!__kfifo_len(priv->event_fifo) && !priv->resp_len[priv->resp_idx]) | 1849 | if (!__kfifo_len(priv->event_fifo) && !priv->resp_len[priv->resp_idx]) |
1847 | priv->psstate = PS_STATE_SLEEP; | 1850 | priv->psstate = PS_STATE_SLEEP; |
@@ -1904,12 +1907,12 @@ void lbs_ps_confirm_sleep(struct lbs_private *priv) | |||
1904 | 1907 | ||
1905 | lbs_deb_enter(LBS_DEB_HOST); | 1908 | lbs_deb_enter(LBS_DEB_HOST); |
1906 | 1909 | ||
1910 | spin_lock_irqsave(&priv->driver_lock, flags); | ||
1907 | if (priv->dnld_sent) { | 1911 | if (priv->dnld_sent) { |
1908 | allowed = 0; | 1912 | allowed = 0; |
1909 | lbs_deb_host("dnld_sent was set\n"); | 1913 | lbs_deb_host("dnld_sent was set\n"); |
1910 | } | 1914 | } |
1911 | 1915 | ||
1912 | spin_lock_irqsave(&priv->driver_lock, flags); | ||
1913 | /* In-progress command? */ | 1916 | /* In-progress command? */ |
1914 | if (priv->cur_cmd) { | 1917 | if (priv->cur_cmd) { |
1915 | allowed = 0; | 1918 | allowed = 0; |
diff --git a/drivers/net/wireless/libertas/debugfs.c b/drivers/net/wireless/libertas/debugfs.c index ad2fabca9116..0aa0ce3b2c42 100644 --- a/drivers/net/wireless/libertas/debugfs.c +++ b/drivers/net/wireless/libertas/debugfs.c | |||
@@ -312,8 +312,8 @@ static ssize_t lbs_threshold_write(uint16_t tlv_type, uint16_t event_mask, | |||
312 | if (tlv_type != TLV_TYPE_BCNMISS) | 312 | if (tlv_type != TLV_TYPE_BCNMISS) |
313 | tlv->freq = freq; | 313 | tlv->freq = freq; |
314 | 314 | ||
315 | /* The command header, the event mask, and the one TLV */ | 315 | /* The command header, the action, the event mask, and one TLV */ |
316 | events->hdr.size = cpu_to_le16(sizeof(events->hdr) + 2 + sizeof(*tlv)); | 316 | events->hdr.size = cpu_to_le16(sizeof(events->hdr) + 4 + sizeof(*tlv)); |
317 | 317 | ||
318 | ret = lbs_cmd_with_response(priv, CMD_802_11_SUBSCRIBE_EVENT, events); | 318 | ret = lbs_cmd_with_response(priv, CMD_802_11_SUBSCRIBE_EVENT, events); |
319 | 319 | ||
diff --git a/drivers/net/wireless/libertas/ethtool.c b/drivers/net/wireless/libertas/ethtool.c index dcfdb404678b..688d60de55cb 100644 --- a/drivers/net/wireless/libertas/ethtool.c +++ b/drivers/net/wireless/libertas/ethtool.c | |||
@@ -73,8 +73,8 @@ out: | |||
73 | return ret; | 73 | return ret; |
74 | } | 74 | } |
75 | 75 | ||
76 | static void lbs_ethtool_get_stats(struct net_device * dev, | 76 | static void lbs_ethtool_get_stats(struct net_device *dev, |
77 | struct ethtool_stats * stats, u64 * data) | 77 | struct ethtool_stats *stats, uint64_t *data) |
78 | { | 78 | { |
79 | struct lbs_private *priv = dev->priv; | 79 | struct lbs_private *priv = dev->priv; |
80 | struct cmd_ds_mesh_access mesh_access; | 80 | struct cmd_ds_mesh_access mesh_access; |
@@ -83,12 +83,12 @@ static void lbs_ethtool_get_stats(struct net_device * dev, | |||
83 | lbs_deb_enter(LBS_DEB_ETHTOOL); | 83 | lbs_deb_enter(LBS_DEB_ETHTOOL); |
84 | 84 | ||
85 | /* Get Mesh Statistics */ | 85 | /* Get Mesh Statistics */ |
86 | ret = lbs_prepare_and_send_command(priv, | 86 | ret = lbs_mesh_access(priv, CMD_ACT_MESH_GET_STATS, &mesh_access); |
87 | CMD_MESH_ACCESS, CMD_ACT_MESH_GET_STATS, | ||
88 | CMD_OPTION_WAITFORRSP, 0, &mesh_access); | ||
89 | 87 | ||
90 | if (ret) | 88 | if (ret) { |
89 | memset(data, 0, MESH_STATS_NUM*(sizeof(uint64_t))); | ||
91 | return; | 90 | return; |
91 | } | ||
92 | 92 | ||
93 | priv->mstats.fwd_drop_rbt = le32_to_cpu(mesh_access.data[0]); | 93 | priv->mstats.fwd_drop_rbt = le32_to_cpu(mesh_access.data[0]); |
94 | priv->mstats.fwd_drop_ttl = le32_to_cpu(mesh_access.data[1]); | 94 | priv->mstats.fwd_drop_ttl = le32_to_cpu(mesh_access.data[1]); |
@@ -111,19 +111,18 @@ static void lbs_ethtool_get_stats(struct net_device * dev, | |||
111 | lbs_deb_enter(LBS_DEB_ETHTOOL); | 111 | lbs_deb_enter(LBS_DEB_ETHTOOL); |
112 | } | 112 | } |
113 | 113 | ||
114 | static int lbs_ethtool_get_sset_count(struct net_device * dev, int sset) | 114 | static int lbs_ethtool_get_sset_count(struct net_device *dev, int sset) |
115 | { | 115 | { |
116 | switch (sset) { | 116 | struct lbs_private *priv = dev->priv; |
117 | case ETH_SS_STATS: | 117 | |
118 | if (sset == ETH_SS_STATS && dev == priv->mesh_dev) | ||
118 | return MESH_STATS_NUM; | 119 | return MESH_STATS_NUM; |
119 | default: | 120 | |
120 | return -EOPNOTSUPP; | 121 | return -EOPNOTSUPP; |
121 | } | ||
122 | } | 122 | } |
123 | 123 | ||
124 | static void lbs_ethtool_get_strings(struct net_device *dev, | 124 | static void lbs_ethtool_get_strings(struct net_device *dev, |
125 | u32 stringset, | 125 | uint32_t stringset, uint8_t *s) |
126 | u8 * s) | ||
127 | { | 126 | { |
128 | int i; | 127 | int i; |
129 | 128 | ||
diff --git a/drivers/net/wireless/libertas/if_usb.c b/drivers/net/wireless/libertas/if_usb.c index 8032df72aaab..36288b29abf7 100644 --- a/drivers/net/wireless/libertas/if_usb.c +++ b/drivers/net/wireless/libertas/if_usb.c | |||
@@ -925,6 +925,7 @@ static struct usb_driver if_usb_driver = { | |||
925 | .id_table = if_usb_table, | 925 | .id_table = if_usb_table, |
926 | .suspend = if_usb_suspend, | 926 | .suspend = if_usb_suspend, |
927 | .resume = if_usb_resume, | 927 | .resume = if_usb_resume, |
928 | .reset_resume = if_usb_resume, | ||
928 | }; | 929 | }; |
929 | 930 | ||
930 | static int __init if_usb_init_module(void) | 931 | static int __init if_usb_init_module(void) |
diff --git a/drivers/net/wireless/libertas/main.c b/drivers/net/wireless/libertas/main.c index 406f54d40956..acfc4bfcc262 100644 --- a/drivers/net/wireless/libertas/main.c +++ b/drivers/net/wireless/libertas/main.c | |||
@@ -732,8 +732,8 @@ static int lbs_thread(void *data) | |||
732 | lbs_deb_thread("4: currenttxskb %p, dnld_sent %d\n", | 732 | lbs_deb_thread("4: currenttxskb %p, dnld_sent %d\n", |
733 | priv->currenttxskb, priv->dnld_sent); | 733 | priv->currenttxskb, priv->dnld_sent); |
734 | 734 | ||
735 | spin_lock_irq(&priv->driver_lock); | ||
736 | /* Process any pending command response */ | 735 | /* Process any pending command response */ |
736 | spin_lock_irq(&priv->driver_lock); | ||
737 | resp_idx = priv->resp_idx; | 737 | resp_idx = priv->resp_idx; |
738 | if (priv->resp_len[resp_idx]) { | 738 | if (priv->resp_len[resp_idx]) { |
739 | spin_unlock_irq(&priv->driver_lock); | 739 | spin_unlock_irq(&priv->driver_lock); |
@@ -756,6 +756,7 @@ static int lbs_thread(void *data) | |||
756 | priv->nr_retries = 0; | 756 | priv->nr_retries = 0; |
757 | } else { | 757 | } else { |
758 | priv->cur_cmd = NULL; | 758 | priv->cur_cmd = NULL; |
759 | priv->dnld_sent = DNLD_RES_RECEIVED; | ||
759 | lbs_pr_info("requeueing command %x due to timeout (#%d)\n", | 760 | lbs_pr_info("requeueing command %x due to timeout (#%d)\n", |
760 | le16_to_cpu(cmdnode->cmdbuf->command), priv->nr_retries); | 761 | le16_to_cpu(cmdnode->cmdbuf->command), priv->nr_retries); |
761 | 762 | ||
@@ -1564,6 +1565,7 @@ static int lbs_add_rtap(struct lbs_private *priv) | |||
1564 | rtap_dev->hard_start_xmit = lbs_rtap_hard_start_xmit; | 1565 | rtap_dev->hard_start_xmit = lbs_rtap_hard_start_xmit; |
1565 | rtap_dev->set_multicast_list = lbs_set_multicast_list; | 1566 | rtap_dev->set_multicast_list = lbs_set_multicast_list; |
1566 | rtap_dev->priv = priv; | 1567 | rtap_dev->priv = priv; |
1568 | SET_NETDEV_DEV(rtap_dev, priv->dev->dev.parent); | ||
1567 | 1569 | ||
1568 | ret = register_netdev(rtap_dev); | 1570 | ret = register_netdev(rtap_dev); |
1569 | if (ret) { | 1571 | if (ret) { |
diff --git a/drivers/net/wireless/libertas/scan.c b/drivers/net/wireless/libertas/scan.c index 1a409fcc80d3..387d4878af2f 100644 --- a/drivers/net/wireless/libertas/scan.c +++ b/drivers/net/wireless/libertas/scan.c | |||
@@ -298,7 +298,8 @@ static int lbs_do_scan(struct lbs_private *priv, uint8_t bsstype, | |||
298 | uint8_t *tlv; /* pointer into our current, growing TLV storage area */ | 298 | uint8_t *tlv; /* pointer into our current, growing TLV storage area */ |
299 | 299 | ||
300 | lbs_deb_enter_args(LBS_DEB_SCAN, "bsstype %d, chanlist[].chan %d, chan_count %d", | 300 | lbs_deb_enter_args(LBS_DEB_SCAN, "bsstype %d, chanlist[].chan %d, chan_count %d", |
301 | bsstype, chan_list[0].channumber, chan_count); | 301 | bsstype, chan_list ? chan_list[0].channumber : -1, |
302 | chan_count); | ||
302 | 303 | ||
303 | /* create the fixed part for scan command */ | 304 | /* create the fixed part for scan command */ |
304 | scan_cmd = kzalloc(MAX_SCAN_CFG_ALLOC, GFP_KERNEL); | 305 | scan_cmd = kzalloc(MAX_SCAN_CFG_ALLOC, GFP_KERNEL); |
@@ -566,11 +567,11 @@ static int lbs_process_bss(struct bss_descriptor *bss, | |||
566 | pos += 8; | 567 | pos += 8; |
567 | 568 | ||
568 | /* beacon interval is 2 bytes long */ | 569 | /* beacon interval is 2 bytes long */ |
569 | bss->beaconperiod = le16_to_cpup((void *) pos); | 570 | bss->beaconperiod = get_unaligned_le16(pos); |
570 | pos += 2; | 571 | pos += 2; |
571 | 572 | ||
572 | /* capability information is 2 bytes long */ | 573 | /* capability information is 2 bytes long */ |
573 | bss->capability = le16_to_cpup((void *) pos); | 574 | bss->capability = get_unaligned_le16(pos); |
574 | lbs_deb_scan("process_bss: capabilities 0x%04x\n", bss->capability); | 575 | lbs_deb_scan("process_bss: capabilities 0x%04x\n", bss->capability); |
575 | pos += 2; | 576 | pos += 2; |
576 | 577 | ||
diff --git a/drivers/net/wireless/orinoco_cs.c b/drivers/net/wireless/orinoco_cs.c index 8b7f5768a103..1c216e015f64 100644 --- a/drivers/net/wireless/orinoco_cs.c +++ b/drivers/net/wireless/orinoco_cs.c | |||
@@ -461,6 +461,7 @@ static struct pcmcia_device_id orinoco_cs_ids[] = { | |||
461 | PCMCIA_DEVICE_MANF_CARD(0x028a, 0x0673), /* Linksys WCF12 Wireless CompactFlash Card */ | 461 | PCMCIA_DEVICE_MANF_CARD(0x028a, 0x0673), /* Linksys WCF12 Wireless CompactFlash Card */ |
462 | PCMCIA_DEVICE_MANF_CARD(0x02aa, 0x0002), /* ASUS SpaceLink WL-100 */ | 462 | PCMCIA_DEVICE_MANF_CARD(0x02aa, 0x0002), /* ASUS SpaceLink WL-100 */ |
463 | PCMCIA_DEVICE_MANF_CARD(0x02ac, 0x0002), /* SpeedStream SS1021 Wireless Adapter */ | 463 | PCMCIA_DEVICE_MANF_CARD(0x02ac, 0x0002), /* SpeedStream SS1021 Wireless Adapter */ |
464 | PCMCIA_DEVICE_MANF_CARD(0x02ac, 0x3021), /* SpeedStream Wireless Adapter */ | ||
464 | PCMCIA_DEVICE_MANF_CARD(0x14ea, 0xb001), /* PLANEX RoadLannerWave GW-NS11H */ | 465 | PCMCIA_DEVICE_MANF_CARD(0x14ea, 0xb001), /* PLANEX RoadLannerWave GW-NS11H */ |
465 | PCMCIA_DEVICE_MANF_CARD(0x50c2, 0x7300), /* Airvast WN-100 */ | 466 | PCMCIA_DEVICE_MANF_CARD(0x50c2, 0x7300), /* Airvast WN-100 */ |
466 | PCMCIA_DEVICE_MANF_CARD(0x9005, 0x0021), /* Adaptec Ultra Wireless ANW-8030 */ | 467 | PCMCIA_DEVICE_MANF_CARD(0x9005, 0x0021), /* Adaptec Ultra Wireless ANW-8030 */ |
diff --git a/drivers/net/wireless/p54/p54usb.c b/drivers/net/wireless/p54/p54usb.c index 98ddbb3b3273..1610a7308c1d 100644 --- a/drivers/net/wireless/p54/p54usb.c +++ b/drivers/net/wireless/p54/p54usb.c | |||
@@ -49,6 +49,7 @@ static struct usb_device_id p54u_table[] __devinitdata = { | |||
49 | {USB_DEVICE(0x5041, 0x2235)}, /* Linksys WUSB54G Portable */ | 49 | {USB_DEVICE(0x5041, 0x2235)}, /* Linksys WUSB54G Portable */ |
50 | 50 | ||
51 | /* Version 2 devices (3887) */ | 51 | /* Version 2 devices (3887) */ |
52 | {USB_DEVICE(0x0471, 0x1230)}, /* Philips CPWUA054/00 */ | ||
52 | {USB_DEVICE(0x050d, 0x7050)}, /* Belkin F5D7050 ver 1000 */ | 53 | {USB_DEVICE(0x050d, 0x7050)}, /* Belkin F5D7050 ver 1000 */ |
53 | {USB_DEVICE(0x0572, 0x2000)}, /* Cohiba Proto board */ | 54 | {USB_DEVICE(0x0572, 0x2000)}, /* Cohiba Proto board */ |
54 | {USB_DEVICE(0x0572, 0x2002)}, /* Cohiba Proto board */ | 55 | {USB_DEVICE(0x0572, 0x2002)}, /* Cohiba Proto board */ |
diff --git a/drivers/net/wireless/prism54/islpci_dev.c b/drivers/net/wireless/prism54/islpci_dev.c index 04c2638d75ad..9196825ed1b5 100644 --- a/drivers/net/wireless/prism54/islpci_dev.c +++ b/drivers/net/wireless/prism54/islpci_dev.c | |||
@@ -388,8 +388,15 @@ islpci_open(struct net_device *ndev) | |||
388 | 388 | ||
389 | netif_start_queue(ndev); | 389 | netif_start_queue(ndev); |
390 | 390 | ||
391 | /* Turn off carrier unless we know we have associated */ | 391 | /* Turn off carrier if in STA or Ad-hoc mode. It will be turned on |
392 | netif_carrier_off(ndev); | 392 | * once the firmware receives a trap of being associated |
393 | * (GEN_OID_LINKSTATE). In other modes (AP or WDS or monitor) we | ||
394 | * should just leave the carrier on as its expected the firmware | ||
395 | * won't send us a trigger. */ | ||
396 | if (priv->iw_mode == IW_MODE_INFRA || priv->iw_mode == IW_MODE_ADHOC) | ||
397 | netif_carrier_off(ndev); | ||
398 | else | ||
399 | netif_carrier_on(ndev); | ||
393 | 400 | ||
394 | return 0; | 401 | return 0; |
395 | } | 402 | } |
diff --git a/drivers/net/wireless/prism54/islpci_eth.c b/drivers/net/wireless/prism54/islpci_eth.c index 762e85bef55d..e43bae97ed8f 100644 --- a/drivers/net/wireless/prism54/islpci_eth.c +++ b/drivers/net/wireless/prism54/islpci_eth.c | |||
@@ -290,7 +290,7 @@ islpci_monitor_rx(islpci_private *priv, struct sk_buff **skb) | |||
290 | 290 | ||
291 | avs->version = cpu_to_be32(P80211CAPTURE_VERSION); | 291 | avs->version = cpu_to_be32(P80211CAPTURE_VERSION); |
292 | avs->length = cpu_to_be32(sizeof (struct avs_80211_1_header)); | 292 | avs->length = cpu_to_be32(sizeof (struct avs_80211_1_header)); |
293 | avs->mactime = cpu_to_be64(le64_to_cpu(clock)); | 293 | avs->mactime = cpu_to_be64(clock); |
294 | avs->hosttime = cpu_to_be64(jiffies); | 294 | avs->hosttime = cpu_to_be64(jiffies); |
295 | avs->phytype = cpu_to_be32(6); /*OFDM: 6 for (g), 8 for (a) */ | 295 | avs->phytype = cpu_to_be32(6); /*OFDM: 6 for (g), 8 for (a) */ |
296 | avs->channel = cpu_to_be32(channel_of_freq(freq)); | 296 | avs->channel = cpu_to_be32(channel_of_freq(freq)); |
diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c index d0b1fb15c709..18c9931e3267 100644 --- a/drivers/net/wireless/rndis_wlan.c +++ b/drivers/net/wireless/rndis_wlan.c | |||
@@ -116,6 +116,7 @@ MODULE_PARM_DESC(workaround_interval, | |||
116 | #define OID_802_11_ENCRYPTION_STATUS ccpu2(0x0d01011b) | 116 | #define OID_802_11_ENCRYPTION_STATUS ccpu2(0x0d01011b) |
117 | #define OID_802_11_ADD_KEY ccpu2(0x0d01011d) | 117 | #define OID_802_11_ADD_KEY ccpu2(0x0d01011d) |
118 | #define OID_802_11_REMOVE_KEY ccpu2(0x0d01011e) | 118 | #define OID_802_11_REMOVE_KEY ccpu2(0x0d01011e) |
119 | #define OID_802_11_ASSOCIATION_INFORMATION ccpu2(0x0d01011f) | ||
119 | #define OID_802_11_PMKID ccpu2(0x0d010123) | 120 | #define OID_802_11_PMKID ccpu2(0x0d010123) |
120 | #define OID_802_11_NETWORK_TYPES_SUPPORTED ccpu2(0x0d010203) | 121 | #define OID_802_11_NETWORK_TYPES_SUPPORTED ccpu2(0x0d010203) |
121 | #define OID_802_11_NETWORK_TYPE_IN_USE ccpu2(0x0d010204) | 122 | #define OID_802_11_NETWORK_TYPE_IN_USE ccpu2(0x0d010204) |
@@ -271,6 +272,26 @@ struct ndis_config_param { | |||
271 | __le32 value_length; | 272 | __le32 value_length; |
272 | } __attribute__((packed)); | 273 | } __attribute__((packed)); |
273 | 274 | ||
275 | struct ndis_80211_assoc_info { | ||
276 | __le32 length; | ||
277 | __le16 req_ies; | ||
278 | struct req_ie { | ||
279 | __le16 capa; | ||
280 | __le16 listen_interval; | ||
281 | u8 cur_ap_address[6]; | ||
282 | } req_ie; | ||
283 | __le32 req_ie_length; | ||
284 | __le32 offset_req_ies; | ||
285 | __le16 resp_ies; | ||
286 | struct resp_ie { | ||
287 | __le16 capa; | ||
288 | __le16 status_code; | ||
289 | __le16 assoc_id; | ||
290 | } resp_ie; | ||
291 | __le32 resp_ie_length; | ||
292 | __le32 offset_resp_ies; | ||
293 | } __attribute__((packed)); | ||
294 | |||
274 | /* these have to match what is in wpa_supplicant */ | 295 | /* these have to match what is in wpa_supplicant */ |
275 | enum wpa_alg { WPA_ALG_NONE, WPA_ALG_WEP, WPA_ALG_TKIP, WPA_ALG_CCMP }; | 296 | enum wpa_alg { WPA_ALG_NONE, WPA_ALG_WEP, WPA_ALG_TKIP, WPA_ALG_CCMP }; |
276 | enum wpa_cipher { CIPHER_NONE, CIPHER_WEP40, CIPHER_TKIP, CIPHER_CCMP, | 297 | enum wpa_cipher { CIPHER_NONE, CIPHER_WEP40, CIPHER_TKIP, CIPHER_CCMP, |
@@ -674,6 +695,12 @@ static int get_bssid(struct usbnet *usbdev, u8 bssid[ETH_ALEN]) | |||
674 | return ret; | 695 | return ret; |
675 | } | 696 | } |
676 | 697 | ||
698 | static int get_association_info(struct usbnet *usbdev, | ||
699 | struct ndis_80211_assoc_info *info, int len) | ||
700 | { | ||
701 | return rndis_query_oid(usbdev, OID_802_11_ASSOCIATION_INFORMATION, | ||
702 | info, &len); | ||
703 | } | ||
677 | 704 | ||
678 | static int is_associated(struct usbnet *usbdev) | 705 | static int is_associated(struct usbnet *usbdev) |
679 | { | 706 | { |
@@ -2182,11 +2209,40 @@ static void rndis_wext_worker(struct work_struct *work) | |||
2182 | struct usbnet *usbdev = priv->usbdev; | 2209 | struct usbnet *usbdev = priv->usbdev; |
2183 | union iwreq_data evt; | 2210 | union iwreq_data evt; |
2184 | unsigned char bssid[ETH_ALEN]; | 2211 | unsigned char bssid[ETH_ALEN]; |
2185 | int ret; | 2212 | struct ndis_80211_assoc_info *info; |
2213 | int assoc_size = sizeof(*info) + IW_CUSTOM_MAX + 32; | ||
2214 | int ret, offset; | ||
2186 | 2215 | ||
2187 | if (test_and_clear_bit(WORK_CONNECTION_EVENT, &priv->work_pending)) { | 2216 | if (test_and_clear_bit(WORK_CONNECTION_EVENT, &priv->work_pending)) { |
2188 | ret = get_bssid(usbdev, bssid); | 2217 | info = kzalloc(assoc_size, GFP_KERNEL); |
2218 | if (!info) | ||
2219 | goto get_bssid; | ||
2220 | |||
2221 | /* Get association info IEs from device and send them back to | ||
2222 | * userspace. */ | ||
2223 | ret = get_association_info(usbdev, info, assoc_size); | ||
2224 | if (!ret) { | ||
2225 | evt.data.length = le32_to_cpu(info->req_ie_length); | ||
2226 | if (evt.data.length > 0) { | ||
2227 | offset = le32_to_cpu(info->offset_req_ies); | ||
2228 | wireless_send_event(usbdev->net, | ||
2229 | IWEVASSOCREQIE, &evt, | ||
2230 | (char *)info + offset); | ||
2231 | } | ||
2232 | |||
2233 | evt.data.length = le32_to_cpu(info->resp_ie_length); | ||
2234 | if (evt.data.length > 0) { | ||
2235 | offset = le32_to_cpu(info->offset_resp_ies); | ||
2236 | wireless_send_event(usbdev->net, | ||
2237 | IWEVASSOCRESPIE, &evt, | ||
2238 | (char *)info + offset); | ||
2239 | } | ||
2240 | } | ||
2241 | |||
2242 | kfree(info); | ||
2189 | 2243 | ||
2244 | get_bssid: | ||
2245 | ret = get_bssid(usbdev, bssid); | ||
2190 | if (!ret) { | 2246 | if (!ret) { |
2191 | evt.data.flags = 0; | 2247 | evt.data.flags = 0; |
2192 | evt.data.length = 0; | 2248 | evt.data.length = 0; |
@@ -2414,6 +2470,11 @@ static int bcm4320_early_init(struct usbnet *dev) | |||
2414 | else if (priv->param_power_save > 2) | 2470 | else if (priv->param_power_save > 2) |
2415 | priv->param_power_save = 2; | 2471 | priv->param_power_save = 2; |
2416 | 2472 | ||
2473 | if (priv->param_power_output < 0) | ||
2474 | priv->param_power_output = 0; | ||
2475 | else if (priv->param_power_output > 3) | ||
2476 | priv->param_power_output = 3; | ||
2477 | |||
2417 | if (priv->param_roamtrigger < -80) | 2478 | if (priv->param_roamtrigger < -80) |
2418 | priv->param_roamtrigger = -80; | 2479 | priv->param_roamtrigger = -80; |
2419 | else if (priv->param_roamtrigger > -60) | 2480 | else if (priv->param_roamtrigger > -60) |
diff --git a/drivers/net/wireless/rt2x00/Kconfig b/drivers/net/wireless/rt2x00/Kconfig index ab1029e79884..2d611876bbe0 100644 --- a/drivers/net/wireless/rt2x00/Kconfig +++ b/drivers/net/wireless/rt2x00/Kconfig | |||
@@ -32,12 +32,13 @@ config RT2X00_LIB_FIRMWARE | |||
32 | config RT2X00_LIB_RFKILL | 32 | config RT2X00_LIB_RFKILL |
33 | boolean | 33 | boolean |
34 | depends on RT2X00_LIB | 34 | depends on RT2X00_LIB |
35 | depends on INPUT | ||
35 | select RFKILL | 36 | select RFKILL |
36 | select INPUT_POLLDEV | 37 | select INPUT_POLLDEV |
37 | 38 | ||
38 | config RT2X00_LIB_LEDS | 39 | config RT2X00_LIB_LEDS |
39 | boolean | 40 | boolean |
40 | depends on RT2X00_LIB | 41 | depends on RT2X00_LIB && NEW_LEDS |
41 | 42 | ||
42 | config RT2400PCI | 43 | config RT2400PCI |
43 | tristate "Ralink rt2400 pci/pcmcia support" | 44 | tristate "Ralink rt2400 pci/pcmcia support" |
@@ -51,7 +52,7 @@ config RT2400PCI | |||
51 | 52 | ||
52 | config RT2400PCI_RFKILL | 53 | config RT2400PCI_RFKILL |
53 | bool "RT2400 rfkill support" | 54 | bool "RT2400 rfkill support" |
54 | depends on RT2400PCI | 55 | depends on RT2400PCI && INPUT |
55 | select RT2X00_LIB_RFKILL | 56 | select RT2X00_LIB_RFKILL |
56 | ---help--- | 57 | ---help--- |
57 | This adds support for integrated rt2400 devices that feature a | 58 | This adds support for integrated rt2400 devices that feature a |
@@ -60,7 +61,7 @@ config RT2400PCI_RFKILL | |||
60 | 61 | ||
61 | config RT2400PCI_LEDS | 62 | config RT2400PCI_LEDS |
62 | bool "RT2400 leds support" | 63 | bool "RT2400 leds support" |
63 | depends on RT2400PCI | 64 | depends on RT2400PCI && NEW_LEDS |
64 | select LEDS_CLASS | 65 | select LEDS_CLASS |
65 | select RT2X00_LIB_LEDS | 66 | select RT2X00_LIB_LEDS |
66 | ---help--- | 67 | ---help--- |
@@ -78,7 +79,7 @@ config RT2500PCI | |||
78 | 79 | ||
79 | config RT2500PCI_RFKILL | 80 | config RT2500PCI_RFKILL |
80 | bool "RT2500 rfkill support" | 81 | bool "RT2500 rfkill support" |
81 | depends on RT2500PCI | 82 | depends on RT2500PCI && INPUT |
82 | select RT2X00_LIB_RFKILL | 83 | select RT2X00_LIB_RFKILL |
83 | ---help--- | 84 | ---help--- |
84 | This adds support for integrated rt2500 devices that feature a | 85 | This adds support for integrated rt2500 devices that feature a |
@@ -87,7 +88,7 @@ config RT2500PCI_RFKILL | |||
87 | 88 | ||
88 | config RT2500PCI_LEDS | 89 | config RT2500PCI_LEDS |
89 | bool "RT2500 leds support" | 90 | bool "RT2500 leds support" |
90 | depends on RT2500PCI | 91 | depends on RT2500PCI && NEW_LEDS |
91 | select LEDS_CLASS | 92 | select LEDS_CLASS |
92 | select RT2X00_LIB_LEDS | 93 | select RT2X00_LIB_LEDS |
93 | ---help--- | 94 | ---help--- |
@@ -107,7 +108,7 @@ config RT61PCI | |||
107 | 108 | ||
108 | config RT61PCI_RFKILL | 109 | config RT61PCI_RFKILL |
109 | bool "RT61 rfkill support" | 110 | bool "RT61 rfkill support" |
110 | depends on RT61PCI | 111 | depends on RT61PCI && INPUT |
111 | select RT2X00_LIB_RFKILL | 112 | select RT2X00_LIB_RFKILL |
112 | ---help--- | 113 | ---help--- |
113 | This adds support for integrated rt61 devices that feature a | 114 | This adds support for integrated rt61 devices that feature a |
@@ -116,7 +117,7 @@ config RT61PCI_RFKILL | |||
116 | 117 | ||
117 | config RT61PCI_LEDS | 118 | config RT61PCI_LEDS |
118 | bool "RT61 leds support" | 119 | bool "RT61 leds support" |
119 | depends on RT61PCI | 120 | depends on RT61PCI && NEW_LEDS |
120 | select LEDS_CLASS | 121 | select LEDS_CLASS |
121 | select RT2X00_LIB_LEDS | 122 | select RT2X00_LIB_LEDS |
122 | ---help--- | 123 | ---help--- |
@@ -133,7 +134,7 @@ config RT2500USB | |||
133 | 134 | ||
134 | config RT2500USB_LEDS | 135 | config RT2500USB_LEDS |
135 | bool "RT2500 leds support" | 136 | bool "RT2500 leds support" |
136 | depends on RT2500USB | 137 | depends on RT2500USB && NEW_LEDS |
137 | select LEDS_CLASS | 138 | select LEDS_CLASS |
138 | select RT2X00_LIB_LEDS | 139 | select RT2X00_LIB_LEDS |
139 | ---help--- | 140 | ---help--- |
@@ -152,7 +153,7 @@ config RT73USB | |||
152 | 153 | ||
153 | config RT73USB_LEDS | 154 | config RT73USB_LEDS |
154 | bool "RT73 leds support" | 155 | bool "RT73 leds support" |
155 | depends on RT73USB | 156 | depends on RT73USB && NEW_LEDS |
156 | select LEDS_CLASS | 157 | select LEDS_CLASS |
157 | select RT2X00_LIB_LEDS | 158 | select RT2X00_LIB_LEDS |
158 | ---help--- | 159 | ---help--- |
diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c index b41187af1306..b36ed1c6c746 100644 --- a/drivers/net/wireless/rt2x00/rt2400pci.c +++ b/drivers/net/wireless/rt2x00/rt2400pci.c | |||
@@ -363,7 +363,7 @@ static void rt2400pci_config_erp(struct rt2x00_dev *rt2x00dev, | |||
363 | rt2x00pci_register_write(rt2x00dev, TXCSR1, reg); | 363 | rt2x00pci_register_write(rt2x00dev, TXCSR1, reg); |
364 | 364 | ||
365 | rt2x00pci_register_read(rt2x00dev, ARCSR2, ®); | 365 | rt2x00pci_register_read(rt2x00dev, ARCSR2, ®); |
366 | rt2x00_set_field32(®, ARCSR2_SIGNAL, 0x00 | preamble_mask); | 366 | rt2x00_set_field32(®, ARCSR2_SIGNAL, 0x00); |
367 | rt2x00_set_field32(®, ARCSR2_SERVICE, 0x04); | 367 | rt2x00_set_field32(®, ARCSR2_SERVICE, 0x04); |
368 | rt2x00_set_field32(®, ARCSR2_LENGTH, get_duration(ACK_SIZE, 10)); | 368 | rt2x00_set_field32(®, ARCSR2_LENGTH, get_duration(ACK_SIZE, 10)); |
369 | rt2x00pci_register_write(rt2x00dev, ARCSR2, reg); | 369 | rt2x00pci_register_write(rt2x00dev, ARCSR2, reg); |
@@ -731,6 +731,17 @@ static int rt2400pci_init_registers(struct rt2x00_dev *rt2x00dev) | |||
731 | (rt2x00dev->rx->data_size / 128)); | 731 | (rt2x00dev->rx->data_size / 128)); |
732 | rt2x00pci_register_write(rt2x00dev, CSR9, reg); | 732 | rt2x00pci_register_write(rt2x00dev, CSR9, reg); |
733 | 733 | ||
734 | rt2x00pci_register_read(rt2x00dev, CSR14, ®); | ||
735 | rt2x00_set_field32(®, CSR14_TSF_COUNT, 0); | ||
736 | rt2x00_set_field32(®, CSR14_TSF_SYNC, 0); | ||
737 | rt2x00_set_field32(®, CSR14_TBCN, 0); | ||
738 | rt2x00_set_field32(®, CSR14_TCFP, 0); | ||
739 | rt2x00_set_field32(®, CSR14_TATIMW, 0); | ||
740 | rt2x00_set_field32(®, CSR14_BEACON_GEN, 0); | ||
741 | rt2x00_set_field32(®, CSR14_CFP_COUNT_PRELOAD, 0); | ||
742 | rt2x00_set_field32(®, CSR14_TBCM_PRELOAD, 0); | ||
743 | rt2x00pci_register_write(rt2x00dev, CSR14, reg); | ||
744 | |||
734 | rt2x00pci_register_write(rt2x00dev, CNT3, 0x3f080000); | 745 | rt2x00pci_register_write(rt2x00dev, CNT3, 0x3f080000); |
735 | 746 | ||
736 | rt2x00pci_register_read(rt2x00dev, ARCSR0, ®); | 747 | rt2x00pci_register_read(rt2x00dev, ARCSR0, ®); |
@@ -1308,7 +1319,7 @@ static int rt2400pci_init_eeprom(struct rt2x00_dev *rt2x00dev) | |||
1308 | 1319 | ||
1309 | if (value == LED_MODE_TXRX_ACTIVITY) { | 1320 | if (value == LED_MODE_TXRX_ACTIVITY) { |
1310 | rt2x00dev->led_qual.rt2x00dev = rt2x00dev; | 1321 | rt2x00dev->led_qual.rt2x00dev = rt2x00dev; |
1311 | rt2x00dev->led_radio.type = LED_TYPE_ACTIVITY; | 1322 | rt2x00dev->led_qual.type = LED_TYPE_ACTIVITY; |
1312 | rt2x00dev->led_qual.led_dev.brightness_set = | 1323 | rt2x00dev->led_qual.led_dev.brightness_set = |
1313 | rt2400pci_brightness_set; | 1324 | rt2400pci_brightness_set; |
1314 | rt2x00dev->led_qual.led_dev.blink_set = | 1325 | rt2x00dev->led_qual.led_dev.blink_set = |
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c index 5ade097ed45e..f7731fb82555 100644 --- a/drivers/net/wireless/rt2x00/rt2500pci.c +++ b/drivers/net/wireless/rt2x00/rt2500pci.c | |||
@@ -370,7 +370,7 @@ static void rt2500pci_config_erp(struct rt2x00_dev *rt2x00dev, | |||
370 | rt2x00pci_register_write(rt2x00dev, TXCSR1, reg); | 370 | rt2x00pci_register_write(rt2x00dev, TXCSR1, reg); |
371 | 371 | ||
372 | rt2x00pci_register_read(rt2x00dev, ARCSR2, ®); | 372 | rt2x00pci_register_read(rt2x00dev, ARCSR2, ®); |
373 | rt2x00_set_field32(®, ARCSR2_SIGNAL, 0x00 | preamble_mask); | 373 | rt2x00_set_field32(®, ARCSR2_SIGNAL, 0x00); |
374 | rt2x00_set_field32(®, ARCSR2_SERVICE, 0x04); | 374 | rt2x00_set_field32(®, ARCSR2_SERVICE, 0x04); |
375 | rt2x00_set_field32(®, ARCSR2_LENGTH, get_duration(ACK_SIZE, 10)); | 375 | rt2x00_set_field32(®, ARCSR2_LENGTH, get_duration(ACK_SIZE, 10)); |
376 | rt2x00pci_register_write(rt2x00dev, ARCSR2, reg); | 376 | rt2x00pci_register_write(rt2x00dev, ARCSR2, reg); |
@@ -824,6 +824,17 @@ static int rt2500pci_init_registers(struct rt2x00_dev *rt2x00dev) | |||
824 | rt2x00_set_field32(®, CSR11_CW_SELECT, 0); | 824 | rt2x00_set_field32(®, CSR11_CW_SELECT, 0); |
825 | rt2x00pci_register_write(rt2x00dev, CSR11, reg); | 825 | rt2x00pci_register_write(rt2x00dev, CSR11, reg); |
826 | 826 | ||
827 | rt2x00pci_register_read(rt2x00dev, CSR14, ®); | ||
828 | rt2x00_set_field32(®, CSR14_TSF_COUNT, 0); | ||
829 | rt2x00_set_field32(®, CSR14_TSF_SYNC, 0); | ||
830 | rt2x00_set_field32(®, CSR14_TBCN, 0); | ||
831 | rt2x00_set_field32(®, CSR14_TCFP, 0); | ||
832 | rt2x00_set_field32(®, CSR14_TATIMW, 0); | ||
833 | rt2x00_set_field32(®, CSR14_BEACON_GEN, 0); | ||
834 | rt2x00_set_field32(®, CSR14_CFP_COUNT_PRELOAD, 0); | ||
835 | rt2x00_set_field32(®, CSR14_TBCM_PRELOAD, 0); | ||
836 | rt2x00pci_register_write(rt2x00dev, CSR14, reg); | ||
837 | |||
827 | rt2x00pci_register_write(rt2x00dev, CNT3, 0); | 838 | rt2x00pci_register_write(rt2x00dev, CNT3, 0); |
828 | 839 | ||
829 | rt2x00pci_register_read(rt2x00dev, TXCSR8, ®); | 840 | rt2x00pci_register_read(rt2x00dev, TXCSR8, ®); |
@@ -1485,7 +1496,7 @@ static int rt2500pci_init_eeprom(struct rt2x00_dev *rt2x00dev) | |||
1485 | 1496 | ||
1486 | if (value == LED_MODE_TXRX_ACTIVITY) { | 1497 | if (value == LED_MODE_TXRX_ACTIVITY) { |
1487 | rt2x00dev->led_qual.rt2x00dev = rt2x00dev; | 1498 | rt2x00dev->led_qual.rt2x00dev = rt2x00dev; |
1488 | rt2x00dev->led_radio.type = LED_TYPE_ACTIVITY; | 1499 | rt2x00dev->led_qual.type = LED_TYPE_ACTIVITY; |
1489 | rt2x00dev->led_qual.led_dev.brightness_set = | 1500 | rt2x00dev->led_qual.led_dev.brightness_set = |
1490 | rt2500pci_brightness_set; | 1501 | rt2500pci_brightness_set; |
1491 | rt2x00dev->led_qual.led_dev.blink_set = | 1502 | rt2x00dev->led_qual.led_dev.blink_set = |
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c index 6bb07b339325..d90512f97b39 100644 --- a/drivers/net/wireless/rt2x00/rt2500usb.c +++ b/drivers/net/wireless/rt2x00/rt2500usb.c | |||
@@ -138,11 +138,8 @@ static void rt2500usb_bbp_write(struct rt2x00_dev *rt2x00dev, | |||
138 | * Wait until the BBP becomes ready. | 138 | * Wait until the BBP becomes ready. |
139 | */ | 139 | */ |
140 | reg = rt2500usb_bbp_check(rt2x00dev); | 140 | reg = rt2500usb_bbp_check(rt2x00dev); |
141 | if (rt2x00_get_field16(reg, PHY_CSR8_BUSY)) { | 141 | if (rt2x00_get_field16(reg, PHY_CSR8_BUSY)) |
142 | ERROR(rt2x00dev, "PHY_CSR8 register busy. Write failed.\n"); | 142 | goto exit_fail; |
143 | mutex_unlock(&rt2x00dev->usb_cache_mutex); | ||
144 | return; | ||
145 | } | ||
146 | 143 | ||
147 | /* | 144 | /* |
148 | * Write the data into the BBP. | 145 | * Write the data into the BBP. |
@@ -155,6 +152,13 @@ static void rt2500usb_bbp_write(struct rt2x00_dev *rt2x00dev, | |||
155 | rt2500usb_register_write_lock(rt2x00dev, PHY_CSR7, reg); | 152 | rt2500usb_register_write_lock(rt2x00dev, PHY_CSR7, reg); |
156 | 153 | ||
157 | mutex_unlock(&rt2x00dev->usb_cache_mutex); | 154 | mutex_unlock(&rt2x00dev->usb_cache_mutex); |
155 | |||
156 | return; | ||
157 | |||
158 | exit_fail: | ||
159 | mutex_unlock(&rt2x00dev->usb_cache_mutex); | ||
160 | |||
161 | ERROR(rt2x00dev, "PHY_CSR8 register busy. Write failed.\n"); | ||
158 | } | 162 | } |
159 | 163 | ||
160 | static void rt2500usb_bbp_read(struct rt2x00_dev *rt2x00dev, | 164 | static void rt2500usb_bbp_read(struct rt2x00_dev *rt2x00dev, |
@@ -168,10 +172,8 @@ static void rt2500usb_bbp_read(struct rt2x00_dev *rt2x00dev, | |||
168 | * Wait until the BBP becomes ready. | 172 | * Wait until the BBP becomes ready. |
169 | */ | 173 | */ |
170 | reg = rt2500usb_bbp_check(rt2x00dev); | 174 | reg = rt2500usb_bbp_check(rt2x00dev); |
171 | if (rt2x00_get_field16(reg, PHY_CSR8_BUSY)) { | 175 | if (rt2x00_get_field16(reg, PHY_CSR8_BUSY)) |
172 | ERROR(rt2x00dev, "PHY_CSR8 register busy. Read failed.\n"); | 176 | goto exit_fail; |
173 | return; | ||
174 | } | ||
175 | 177 | ||
176 | /* | 178 | /* |
177 | * Write the request into the BBP. | 179 | * Write the request into the BBP. |
@@ -186,17 +188,21 @@ static void rt2500usb_bbp_read(struct rt2x00_dev *rt2x00dev, | |||
186 | * Wait until the BBP becomes ready. | 188 | * Wait until the BBP becomes ready. |
187 | */ | 189 | */ |
188 | reg = rt2500usb_bbp_check(rt2x00dev); | 190 | reg = rt2500usb_bbp_check(rt2x00dev); |
189 | if (rt2x00_get_field16(reg, PHY_CSR8_BUSY)) { | 191 | if (rt2x00_get_field16(reg, PHY_CSR8_BUSY)) |
190 | ERROR(rt2x00dev, "PHY_CSR8 register busy. Read failed.\n"); | 192 | goto exit_fail; |
191 | *value = 0xff; | ||
192 | mutex_unlock(&rt2x00dev->usb_cache_mutex); | ||
193 | return; | ||
194 | } | ||
195 | 193 | ||
196 | rt2500usb_register_read_lock(rt2x00dev, PHY_CSR7, ®); | 194 | rt2500usb_register_read_lock(rt2x00dev, PHY_CSR7, ®); |
197 | *value = rt2x00_get_field16(reg, PHY_CSR7_DATA); | 195 | *value = rt2x00_get_field16(reg, PHY_CSR7_DATA); |
198 | 196 | ||
199 | mutex_unlock(&rt2x00dev->usb_cache_mutex); | 197 | mutex_unlock(&rt2x00dev->usb_cache_mutex); |
198 | |||
199 | return; | ||
200 | |||
201 | exit_fail: | ||
202 | mutex_unlock(&rt2x00dev->usb_cache_mutex); | ||
203 | |||
204 | ERROR(rt2x00dev, "PHY_CSR8 register busy. Read failed.\n"); | ||
205 | *value = 0xff; | ||
200 | } | 206 | } |
201 | 207 | ||
202 | static void rt2500usb_rf_write(struct rt2x00_dev *rt2x00dev, | 208 | static void rt2500usb_rf_write(struct rt2x00_dev *rt2x00dev, |
@@ -795,6 +801,13 @@ static int rt2500usb_init_registers(struct rt2x00_dev *rt2x00dev) | |||
795 | rt2x00_set_field16(®, TXRX_CSR8_BBP_ID1_VALID, 0); | 801 | rt2x00_set_field16(®, TXRX_CSR8_BBP_ID1_VALID, 0); |
796 | rt2500usb_register_write(rt2x00dev, TXRX_CSR8, reg); | 802 | rt2500usb_register_write(rt2x00dev, TXRX_CSR8, reg); |
797 | 803 | ||
804 | rt2500usb_register_read(rt2x00dev, TXRX_CSR19, ®); | ||
805 | rt2x00_set_field16(®, TXRX_CSR19_TSF_COUNT, 0); | ||
806 | rt2x00_set_field16(®, TXRX_CSR19_TSF_SYNC, 0); | ||
807 | rt2x00_set_field16(®, TXRX_CSR19_TBCN, 0); | ||
808 | rt2x00_set_field16(®, TXRX_CSR19_BEACON_GEN, 0); | ||
809 | rt2500usb_register_write(rt2x00dev, TXRX_CSR19, reg); | ||
810 | |||
798 | rt2500usb_register_write(rt2x00dev, TXRX_CSR21, 0xe78f); | 811 | rt2500usb_register_write(rt2x00dev, TXRX_CSR21, 0xe78f); |
799 | rt2500usb_register_write(rt2x00dev, MAC_CSR9, 0xff1d); | 812 | rt2500usb_register_write(rt2x00dev, MAC_CSR9, 0xff1d); |
800 | 813 | ||
@@ -1394,7 +1407,7 @@ static int rt2500usb_init_eeprom(struct rt2x00_dev *rt2x00dev) | |||
1394 | 1407 | ||
1395 | if (value == LED_MODE_TXRX_ACTIVITY) { | 1408 | if (value == LED_MODE_TXRX_ACTIVITY) { |
1396 | rt2x00dev->led_qual.rt2x00dev = rt2x00dev; | 1409 | rt2x00dev->led_qual.rt2x00dev = rt2x00dev; |
1397 | rt2x00dev->led_radio.type = LED_TYPE_ACTIVITY; | 1410 | rt2x00dev->led_qual.type = LED_TYPE_ACTIVITY; |
1398 | rt2x00dev->led_qual.led_dev.brightness_set = | 1411 | rt2x00dev->led_qual.led_dev.brightness_set = |
1399 | rt2500usb_brightness_set; | 1412 | rt2500usb_brightness_set; |
1400 | rt2x00dev->led_qual.led_dev.blink_set = | 1413 | rt2x00dev->led_qual.led_dev.blink_set = |
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h index 57bdc153952f..b4bf1e09cf9a 100644 --- a/drivers/net/wireless/rt2x00/rt2x00.h +++ b/drivers/net/wireless/rt2x00/rt2x00.h | |||
@@ -328,6 +328,11 @@ static inline int rt2x00_get_link_ant_rssi(struct link *link) | |||
328 | return DEFAULT_RSSI; | 328 | return DEFAULT_RSSI; |
329 | } | 329 | } |
330 | 330 | ||
331 | static inline void rt2x00_reset_link_ant_rssi(struct link *link) | ||
332 | { | ||
333 | link->ant.rssi_ant = 0; | ||
334 | } | ||
335 | |||
331 | static inline int rt2x00_get_link_ant_rssi_history(struct link *link, | 336 | static inline int rt2x00_get_link_ant_rssi_history(struct link *link, |
332 | enum antenna ant) | 337 | enum antenna ant) |
333 | { | 338 | { |
@@ -816,6 +821,7 @@ struct rt2x00_dev { | |||
816 | /* | 821 | /* |
817 | * Scheduled work. | 822 | * Scheduled work. |
818 | */ | 823 | */ |
824 | struct workqueue_struct *workqueue; | ||
819 | struct work_struct intf_work; | 825 | struct work_struct intf_work; |
820 | struct work_struct filter_work; | 826 | struct work_struct filter_work; |
821 | 827 | ||
diff --git a/drivers/net/wireless/rt2x00/rt2x00config.c b/drivers/net/wireless/rt2x00/rt2x00config.c index a9930a03f450..48608e8cc8b4 100644 --- a/drivers/net/wireless/rt2x00/rt2x00config.c +++ b/drivers/net/wireless/rt2x00/rt2x00config.c | |||
@@ -129,6 +129,7 @@ void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev, | |||
129 | */ | 129 | */ |
130 | rt2x00dev->ops->lib->config(rt2x00dev, &libconf, CONFIG_UPDATE_ANTENNA); | 130 | rt2x00dev->ops->lib->config(rt2x00dev, &libconf, CONFIG_UPDATE_ANTENNA); |
131 | rt2x00lib_reset_link_tuner(rt2x00dev); | 131 | rt2x00lib_reset_link_tuner(rt2x00dev); |
132 | rt2x00_reset_link_ant_rssi(&rt2x00dev->link); | ||
132 | 133 | ||
133 | rt2x00dev->link.ant.active.rx = libconf.ant.rx; | 134 | rt2x00dev->link.ant.active.rx = libconf.ant.rx; |
134 | rt2x00dev->link.ant.active.tx = libconf.ant.tx; | 135 | rt2x00dev->link.ant.active.tx = libconf.ant.tx; |
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c index f8fe7a139a8a..c997d4f28ab3 100644 --- a/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c | |||
@@ -75,7 +75,7 @@ static void rt2x00lib_start_link_tuner(struct rt2x00_dev *rt2x00dev) | |||
75 | 75 | ||
76 | rt2x00lib_reset_link_tuner(rt2x00dev); | 76 | rt2x00lib_reset_link_tuner(rt2x00dev); |
77 | 77 | ||
78 | queue_delayed_work(rt2x00dev->hw->workqueue, | 78 | queue_delayed_work(rt2x00dev->workqueue, |
79 | &rt2x00dev->link.work, LINK_TUNE_INTERVAL); | 79 | &rt2x00dev->link.work, LINK_TUNE_INTERVAL); |
80 | } | 80 | } |
81 | 81 | ||
@@ -114,6 +114,7 @@ int rt2x00lib_enable_radio(struct rt2x00_dev *rt2x00dev) | |||
114 | return status; | 114 | return status; |
115 | 115 | ||
116 | rt2x00leds_led_radio(rt2x00dev, true); | 116 | rt2x00leds_led_radio(rt2x00dev, true); |
117 | rt2x00led_led_activity(rt2x00dev, true); | ||
117 | 118 | ||
118 | __set_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags); | 119 | __set_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags); |
119 | 120 | ||
@@ -136,14 +137,6 @@ void rt2x00lib_disable_radio(struct rt2x00_dev *rt2x00dev) | |||
136 | return; | 137 | return; |
137 | 138 | ||
138 | /* | 139 | /* |
139 | * Stop all scheduled work. | ||
140 | */ | ||
141 | if (work_pending(&rt2x00dev->intf_work)) | ||
142 | cancel_work_sync(&rt2x00dev->intf_work); | ||
143 | if (work_pending(&rt2x00dev->filter_work)) | ||
144 | cancel_work_sync(&rt2x00dev->filter_work); | ||
145 | |||
146 | /* | ||
147 | * Stop the TX queues. | 140 | * Stop the TX queues. |
148 | */ | 141 | */ |
149 | ieee80211_stop_queues(rt2x00dev->hw); | 142 | ieee80211_stop_queues(rt2x00dev->hw); |
@@ -157,6 +150,7 @@ void rt2x00lib_disable_radio(struct rt2x00_dev *rt2x00dev) | |||
157 | * Disable radio. | 150 | * Disable radio. |
158 | */ | 151 | */ |
159 | rt2x00dev->ops->lib->set_device_state(rt2x00dev, STATE_RADIO_OFF); | 152 | rt2x00dev->ops->lib->set_device_state(rt2x00dev, STATE_RADIO_OFF); |
153 | rt2x00led_led_activity(rt2x00dev, false); | ||
160 | rt2x00leds_led_radio(rt2x00dev, false); | 154 | rt2x00leds_led_radio(rt2x00dev, false); |
161 | } | 155 | } |
162 | 156 | ||
@@ -396,8 +390,8 @@ static void rt2x00lib_link_tuner(struct work_struct *work) | |||
396 | * Increase tuner counter, and reschedule the next link tuner run. | 390 | * Increase tuner counter, and reschedule the next link tuner run. |
397 | */ | 391 | */ |
398 | rt2x00dev->link.count++; | 392 | rt2x00dev->link.count++; |
399 | queue_delayed_work(rt2x00dev->hw->workqueue, &rt2x00dev->link.work, | 393 | queue_delayed_work(rt2x00dev->workqueue, |
400 | LINK_TUNE_INTERVAL); | 394 | &rt2x00dev->link.work, LINK_TUNE_INTERVAL); |
401 | } | 395 | } |
402 | 396 | ||
403 | static void rt2x00lib_packetfilter_scheduled(struct work_struct *work) | 397 | static void rt2x00lib_packetfilter_scheduled(struct work_struct *work) |
@@ -431,6 +425,15 @@ static void rt2x00lib_intf_scheduled_iter(void *data, u8 *mac, | |||
431 | 425 | ||
432 | spin_unlock(&intf->lock); | 426 | spin_unlock(&intf->lock); |
433 | 427 | ||
428 | /* | ||
429 | * It is possible the radio was disabled while the work had been | ||
430 | * scheduled. If that happens we should return here immediately, | ||
431 | * note that in the spinlock protected area above the delayed_flags | ||
432 | * have been cleared correctly. | ||
433 | */ | ||
434 | if (!test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags)) | ||
435 | return; | ||
436 | |||
434 | if (delayed_flags & DELAYED_UPDATE_BEACON) { | 437 | if (delayed_flags & DELAYED_UPDATE_BEACON) { |
435 | skb = ieee80211_beacon_get(rt2x00dev->hw, vif, &control); | 438 | skb = ieee80211_beacon_get(rt2x00dev->hw, vif, &control); |
436 | if (skb && rt2x00dev->ops->hw->beacon_update(rt2x00dev->hw, | 439 | if (skb && rt2x00dev->ops->hw->beacon_update(rt2x00dev->hw, |
@@ -439,7 +442,7 @@ static void rt2x00lib_intf_scheduled_iter(void *data, u8 *mac, | |||
439 | } | 442 | } |
440 | 443 | ||
441 | if (delayed_flags & DELAYED_CONFIG_ERP) | 444 | if (delayed_flags & DELAYED_CONFIG_ERP) |
442 | rt2x00lib_config_erp(rt2x00dev, intf, &intf->conf); | 445 | rt2x00lib_config_erp(rt2x00dev, intf, &conf); |
443 | 446 | ||
444 | if (delayed_flags & DELAYED_LED_ASSOC) | 447 | if (delayed_flags & DELAYED_LED_ASSOC) |
445 | rt2x00leds_led_assoc(rt2x00dev, !!rt2x00dev->intf_associated); | 448 | rt2x00leds_led_assoc(rt2x00dev, !!rt2x00dev->intf_associated); |
@@ -481,11 +484,11 @@ void rt2x00lib_beacondone(struct rt2x00_dev *rt2x00dev) | |||
481 | if (!test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags)) | 484 | if (!test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags)) |
482 | return; | 485 | return; |
483 | 486 | ||
484 | ieee80211_iterate_active_interfaces(rt2x00dev->hw, | 487 | ieee80211_iterate_active_interfaces_atomic(rt2x00dev->hw, |
485 | rt2x00lib_beacondone_iter, | 488 | rt2x00lib_beacondone_iter, |
486 | rt2x00dev); | 489 | rt2x00dev); |
487 | 490 | ||
488 | queue_work(rt2x00dev->hw->workqueue, &rt2x00dev->intf_work); | 491 | queue_work(rt2x00dev->workqueue, &rt2x00dev->intf_work); |
489 | } | 492 | } |
490 | EXPORT_SYMBOL_GPL(rt2x00lib_beacondone); | 493 | EXPORT_SYMBOL_GPL(rt2x00lib_beacondone); |
491 | 494 | ||
@@ -505,7 +508,7 @@ void rt2x00lib_txdone(struct queue_entry *entry, | |||
505 | * Update TX statistics. | 508 | * Update TX statistics. |
506 | */ | 509 | */ |
507 | rt2x00dev->link.qual.tx_success += success; | 510 | rt2x00dev->link.qual.tx_success += success; |
508 | rt2x00dev->link.qual.tx_failed += txdesc->retry + fail; | 511 | rt2x00dev->link.qual.tx_failed += fail; |
509 | 512 | ||
510 | /* | 513 | /* |
511 | * Initialize TX status | 514 | * Initialize TX status |
@@ -1030,8 +1033,10 @@ static int rt2x00lib_initialize(struct rt2x00_dev *rt2x00dev) | |||
1030 | * Initialize the device. | 1033 | * Initialize the device. |
1031 | */ | 1034 | */ |
1032 | status = rt2x00dev->ops->lib->initialize(rt2x00dev); | 1035 | status = rt2x00dev->ops->lib->initialize(rt2x00dev); |
1033 | if (status) | 1036 | if (status) { |
1034 | goto exit; | 1037 | rt2x00queue_uninitialize(rt2x00dev); |
1038 | return status; | ||
1039 | } | ||
1035 | 1040 | ||
1036 | __set_bit(DEVICE_INITIALIZED, &rt2x00dev->flags); | 1041 | __set_bit(DEVICE_INITIALIZED, &rt2x00dev->flags); |
1037 | 1042 | ||
@@ -1041,11 +1046,6 @@ static int rt2x00lib_initialize(struct rt2x00_dev *rt2x00dev) | |||
1041 | rt2x00rfkill_register(rt2x00dev); | 1046 | rt2x00rfkill_register(rt2x00dev); |
1042 | 1047 | ||
1043 | return 0; | 1048 | return 0; |
1044 | |||
1045 | exit: | ||
1046 | rt2x00lib_uninitialize(rt2x00dev); | ||
1047 | |||
1048 | return status; | ||
1049 | } | 1049 | } |
1050 | 1050 | ||
1051 | int rt2x00lib_start(struct rt2x00_dev *rt2x00dev) | 1051 | int rt2x00lib_start(struct rt2x00_dev *rt2x00dev) |
@@ -1131,6 +1131,10 @@ int rt2x00lib_probe_dev(struct rt2x00_dev *rt2x00dev) | |||
1131 | /* | 1131 | /* |
1132 | * Initialize configuration work. | 1132 | * Initialize configuration work. |
1133 | */ | 1133 | */ |
1134 | rt2x00dev->workqueue = create_singlethread_workqueue("rt2x00lib"); | ||
1135 | if (!rt2x00dev->workqueue) | ||
1136 | goto exit; | ||
1137 | |||
1134 | INIT_WORK(&rt2x00dev->intf_work, rt2x00lib_intf_scheduled); | 1138 | INIT_WORK(&rt2x00dev->intf_work, rt2x00lib_intf_scheduled); |
1135 | INIT_WORK(&rt2x00dev->filter_work, rt2x00lib_packetfilter_scheduled); | 1139 | INIT_WORK(&rt2x00dev->filter_work, rt2x00lib_packetfilter_scheduled); |
1136 | INIT_DELAYED_WORK(&rt2x00dev->link.work, rt2x00lib_link_tuner); | 1140 | INIT_DELAYED_WORK(&rt2x00dev->link.work, rt2x00lib_link_tuner); |
@@ -1191,6 +1195,13 @@ void rt2x00lib_remove_dev(struct rt2x00_dev *rt2x00dev) | |||
1191 | rt2x00leds_unregister(rt2x00dev); | 1195 | rt2x00leds_unregister(rt2x00dev); |
1192 | 1196 | ||
1193 | /* | 1197 | /* |
1198 | * Stop all queued work. Note that most tasks will already be halted | ||
1199 | * during rt2x00lib_disable_radio() and rt2x00lib_uninitialize(). | ||
1200 | */ | ||
1201 | flush_workqueue(rt2x00dev->workqueue); | ||
1202 | destroy_workqueue(rt2x00dev->workqueue); | ||
1203 | |||
1204 | /* | ||
1194 | * Free ieee80211_hw memory. | 1205 | * Free ieee80211_hw memory. |
1195 | */ | 1206 | */ |
1196 | rt2x00lib_remove_hw(rt2x00dev); | 1207 | rt2x00lib_remove_hw(rt2x00dev); |
diff --git a/drivers/net/wireless/rt2x00/rt2x00leds.c b/drivers/net/wireless/rt2x00/rt2x00leds.c index 40c1f5c1b805..b362a1cf3f8d 100644 --- a/drivers/net/wireless/rt2x00/rt2x00leds.c +++ b/drivers/net/wireless/rt2x00/rt2x00leds.c | |||
@@ -72,6 +72,21 @@ void rt2x00leds_led_quality(struct rt2x00_dev *rt2x00dev, int rssi) | |||
72 | } | 72 | } |
73 | } | 73 | } |
74 | 74 | ||
75 | void rt2x00led_led_activity(struct rt2x00_dev *rt2x00dev, bool enabled) | ||
76 | { | ||
77 | struct rt2x00_led *led = &rt2x00dev->led_qual; | ||
78 | unsigned int brightness; | ||
79 | |||
80 | if ((led->type != LED_TYPE_ACTIVITY) || !(led->flags & LED_REGISTERED)) | ||
81 | return; | ||
82 | |||
83 | brightness = enabled ? LED_FULL : LED_OFF; | ||
84 | if (brightness != led->led_dev.brightness) { | ||
85 | led->led_dev.brightness_set(&led->led_dev, brightness); | ||
86 | led->led_dev.brightness = brightness; | ||
87 | } | ||
88 | } | ||
89 | |||
75 | void rt2x00leds_led_assoc(struct rt2x00_dev *rt2x00dev, bool enabled) | 90 | void rt2x00leds_led_assoc(struct rt2x00_dev *rt2x00dev, bool enabled) |
76 | { | 91 | { |
77 | struct rt2x00_led *led = &rt2x00dev->led_assoc; | 92 | struct rt2x00_led *led = &rt2x00dev->led_assoc; |
diff --git a/drivers/net/wireless/rt2x00/rt2x00lib.h b/drivers/net/wireless/rt2x00/rt2x00lib.h index 5be32fffc74c..41ee02cd2825 100644 --- a/drivers/net/wireless/rt2x00/rt2x00lib.h +++ b/drivers/net/wireless/rt2x00/rt2x00lib.h | |||
@@ -185,6 +185,7 @@ static inline void rt2x00rfkill_resume(struct rt2x00_dev *rt2x00dev) | |||
185 | */ | 185 | */ |
186 | #ifdef CONFIG_RT2X00_LIB_LEDS | 186 | #ifdef CONFIG_RT2X00_LIB_LEDS |
187 | void rt2x00leds_led_quality(struct rt2x00_dev *rt2x00dev, int rssi); | 187 | void rt2x00leds_led_quality(struct rt2x00_dev *rt2x00dev, int rssi); |
188 | void rt2x00led_led_activity(struct rt2x00_dev *rt2x00dev, bool enabled); | ||
188 | void rt2x00leds_led_assoc(struct rt2x00_dev *rt2x00dev, bool enabled); | 189 | void rt2x00leds_led_assoc(struct rt2x00_dev *rt2x00dev, bool enabled); |
189 | void rt2x00leds_led_radio(struct rt2x00_dev *rt2x00dev, bool enabled); | 190 | void rt2x00leds_led_radio(struct rt2x00_dev *rt2x00dev, bool enabled); |
190 | void rt2x00leds_register(struct rt2x00_dev *rt2x00dev); | 191 | void rt2x00leds_register(struct rt2x00_dev *rt2x00dev); |
@@ -197,6 +198,11 @@ static inline void rt2x00leds_led_quality(struct rt2x00_dev *rt2x00dev, | |||
197 | { | 198 | { |
198 | } | 199 | } |
199 | 200 | ||
201 | static inline void rt2x00led_led_activity(struct rt2x00_dev *rt2x00dev, | ||
202 | bool enabled) | ||
203 | { | ||
204 | } | ||
205 | |||
200 | static inline void rt2x00leds_led_assoc(struct rt2x00_dev *rt2x00dev, | 206 | static inline void rt2x00leds_led_assoc(struct rt2x00_dev *rt2x00dev, |
201 | bool enabled) | 207 | bool enabled) |
202 | { | 208 | { |
diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c index c206b5092070..9cb023edd2e9 100644 --- a/drivers/net/wireless/rt2x00/rt2x00mac.c +++ b/drivers/net/wireless/rt2x00/rt2x00mac.c | |||
@@ -93,6 +93,7 @@ int rt2x00mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
93 | */ | 93 | */ |
94 | if (!test_bit(DEVICE_PRESENT, &rt2x00dev->flags)) { | 94 | if (!test_bit(DEVICE_PRESENT, &rt2x00dev->flags)) { |
95 | ieee80211_stop_queues(hw); | 95 | ieee80211_stop_queues(hw); |
96 | dev_kfree_skb_any(skb); | ||
96 | return NETDEV_TX_OK; | 97 | return NETDEV_TX_OK; |
97 | } | 98 | } |
98 | 99 | ||
@@ -427,7 +428,7 @@ void rt2x00mac_configure_filter(struct ieee80211_hw *hw, | |||
427 | if (!test_bit(DRIVER_REQUIRE_SCHEDULED, &rt2x00dev->flags)) | 428 | if (!test_bit(DRIVER_REQUIRE_SCHEDULED, &rt2x00dev->flags)) |
428 | rt2x00dev->ops->lib->config_filter(rt2x00dev, *total_flags); | 429 | rt2x00dev->ops->lib->config_filter(rt2x00dev, *total_flags); |
429 | else | 430 | else |
430 | queue_work(rt2x00dev->hw->workqueue, &rt2x00dev->filter_work); | 431 | queue_work(rt2x00dev->workqueue, &rt2x00dev->filter_work); |
431 | } | 432 | } |
432 | EXPORT_SYMBOL_GPL(rt2x00mac_configure_filter); | 433 | EXPORT_SYMBOL_GPL(rt2x00mac_configure_filter); |
433 | 434 | ||
@@ -508,7 +509,7 @@ void rt2x00mac_bss_info_changed(struct ieee80211_hw *hw, | |||
508 | memcpy(&intf->conf, bss_conf, sizeof(*bss_conf)); | 509 | memcpy(&intf->conf, bss_conf, sizeof(*bss_conf)); |
509 | if (delayed) { | 510 | if (delayed) { |
510 | intf->delayed_flags |= delayed; | 511 | intf->delayed_flags |= delayed; |
511 | queue_work(rt2x00dev->hw->workqueue, &rt2x00dev->intf_work); | 512 | queue_work(rt2x00dev->workqueue, &rt2x00dev->intf_work); |
512 | } | 513 | } |
513 | spin_unlock(&intf->lock); | 514 | spin_unlock(&intf->lock); |
514 | } | 515 | } |
diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.c b/drivers/net/wireless/rt2x00/rt2x00pci.c index 7867ec64bd2c..60893de3bf8f 100644 --- a/drivers/net/wireless/rt2x00/rt2x00pci.c +++ b/drivers/net/wireless/rt2x00/rt2x00pci.c | |||
@@ -314,13 +314,14 @@ int rt2x00pci_initialize(struct rt2x00_dev *rt2x00dev) | |||
314 | if (status) { | 314 | if (status) { |
315 | ERROR(rt2x00dev, "IRQ %d allocation failed (error %d).\n", | 315 | ERROR(rt2x00dev, "IRQ %d allocation failed (error %d).\n", |
316 | pci_dev->irq, status); | 316 | pci_dev->irq, status); |
317 | return status; | 317 | goto exit; |
318 | } | 318 | } |
319 | 319 | ||
320 | return 0; | 320 | return 0; |
321 | 321 | ||
322 | exit: | 322 | exit: |
323 | rt2x00pci_uninitialize(rt2x00dev); | 323 | queue_for_each(rt2x00dev, queue) |
324 | rt2x00pci_free_queue_dma(rt2x00dev, queue); | ||
324 | 325 | ||
325 | return status; | 326 | return status; |
326 | } | 327 | } |
@@ -411,8 +412,7 @@ int rt2x00pci_probe(struct pci_dev *pci_dev, const struct pci_device_id *id) | |||
411 | if (pci_set_mwi(pci_dev)) | 412 | if (pci_set_mwi(pci_dev)) |
412 | ERROR_PROBE("MWI not available.\n"); | 413 | ERROR_PROBE("MWI not available.\n"); |
413 | 414 | ||
414 | if (pci_set_dma_mask(pci_dev, DMA_64BIT_MASK) && | 415 | if (pci_set_dma_mask(pci_dev, DMA_32BIT_MASK)) { |
415 | pci_set_dma_mask(pci_dev, DMA_32BIT_MASK)) { | ||
416 | ERROR_PROBE("PCI DMA not supported.\n"); | 416 | ERROR_PROBE("PCI DMA not supported.\n"); |
417 | retval = -EIO; | 417 | retval = -EIO; |
418 | goto exit_disable_device; | 418 | goto exit_disable_device; |
diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c index 5a331674dcb2..e5ceae805b57 100644 --- a/drivers/net/wireless/rt2x00/rt2x00usb.c +++ b/drivers/net/wireless/rt2x00/rt2x00usb.c | |||
@@ -362,6 +362,12 @@ void rt2x00usb_disable_radio(struct rt2x00_dev *rt2x00dev) | |||
362 | } | 362 | } |
363 | } | 363 | } |
364 | 364 | ||
365 | /* | ||
366 | * Kill guardian urb (if required by driver). | ||
367 | */ | ||
368 | if (!test_bit(DRIVER_REQUIRE_BEACON_GUARD, &rt2x00dev->flags)) | ||
369 | return; | ||
370 | |||
365 | for (i = 0; i < rt2x00dev->bcn->limit; i++) { | 371 | for (i = 0; i < rt2x00dev->bcn->limit; i++) { |
366 | priv_bcn = rt2x00dev->bcn->entries[i].priv_data; | 372 | priv_bcn = rt2x00dev->bcn->entries[i].priv_data; |
367 | usb_kill_urb(priv_bcn->urb); | 373 | usb_kill_urb(priv_bcn->urb); |
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c index 468a31c8c113..c3afb5cbe807 100644 --- a/drivers/net/wireless/rt2x00/rt61pci.c +++ b/drivers/net/wireless/rt2x00/rt61pci.c | |||
@@ -1201,6 +1201,15 @@ static int rt61pci_init_registers(struct rt2x00_dev *rt2x00dev) | |||
1201 | rt2x00_set_field32(®, TXRX_CSR8_ACK_CTS_54MBS, 42); | 1201 | rt2x00_set_field32(®, TXRX_CSR8_ACK_CTS_54MBS, 42); |
1202 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR8, reg); | 1202 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR8, reg); |
1203 | 1203 | ||
1204 | rt2x00pci_register_read(rt2x00dev, TXRX_CSR9, ®); | ||
1205 | rt2x00_set_field32(®, TXRX_CSR9_BEACON_INTERVAL, 0); | ||
1206 | rt2x00_set_field32(®, TXRX_CSR9_TSF_TICKING, 0); | ||
1207 | rt2x00_set_field32(®, TXRX_CSR9_TSF_SYNC, 0); | ||
1208 | rt2x00_set_field32(®, TXRX_CSR9_TBTT_ENABLE, 0); | ||
1209 | rt2x00_set_field32(®, TXRX_CSR9_BEACON_GEN, 0); | ||
1210 | rt2x00_set_field32(®, TXRX_CSR9_TIMESTAMP_COMPENSATE, 0); | ||
1211 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, reg); | ||
1212 | |||
1204 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR15, 0x0000000f); | 1213 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR15, 0x0000000f); |
1205 | 1214 | ||
1206 | rt2x00pci_register_write(rt2x00dev, MAC_CSR6, 0x00000fff); | 1215 | rt2x00pci_register_write(rt2x00dev, MAC_CSR6, 0x00000fff); |
@@ -2087,7 +2096,7 @@ static int rt61pci_init_eeprom(struct rt2x00_dev *rt2x00dev) | |||
2087 | 2096 | ||
2088 | if (value == LED_MODE_SIGNAL_STRENGTH) { | 2097 | if (value == LED_MODE_SIGNAL_STRENGTH) { |
2089 | rt2x00dev->led_qual.rt2x00dev = rt2x00dev; | 2098 | rt2x00dev->led_qual.rt2x00dev = rt2x00dev; |
2090 | rt2x00dev->led_radio.type = LED_TYPE_QUALITY; | 2099 | rt2x00dev->led_qual.type = LED_TYPE_QUALITY; |
2091 | rt2x00dev->led_qual.led_dev.brightness_set = | 2100 | rt2x00dev->led_qual.led_dev.brightness_set = |
2092 | rt61pci_brightness_set; | 2101 | rt61pci_brightness_set; |
2093 | rt2x00dev->led_qual.led_dev.blink_set = | 2102 | rt2x00dev->led_qual.led_dev.blink_set = |
@@ -2366,6 +2375,7 @@ static int rt61pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
2366 | { | 2375 | { |
2367 | struct rt2x00_dev *rt2x00dev = hw->priv; | 2376 | struct rt2x00_dev *rt2x00dev = hw->priv; |
2368 | struct rt2x00_intf *intf = vif_to_intf(control->vif); | 2377 | struct rt2x00_intf *intf = vif_to_intf(control->vif); |
2378 | struct queue_entry_priv_pci_tx *priv_tx; | ||
2369 | struct skb_frame_desc *skbdesc; | 2379 | struct skb_frame_desc *skbdesc; |
2370 | unsigned int beacon_base; | 2380 | unsigned int beacon_base; |
2371 | u32 reg; | 2381 | u32 reg; |
@@ -2373,21 +2383,8 @@ static int rt61pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
2373 | if (unlikely(!intf->beacon)) | 2383 | if (unlikely(!intf->beacon)) |
2374 | return -ENOBUFS; | 2384 | return -ENOBUFS; |
2375 | 2385 | ||
2376 | /* | 2386 | priv_tx = intf->beacon->priv_data; |
2377 | * We need to append the descriptor in front of the | 2387 | memset(priv_tx->desc, 0, intf->beacon->queue->desc_size); |
2378 | * beacon frame. | ||
2379 | */ | ||
2380 | if (skb_headroom(skb) < intf->beacon->queue->desc_size) { | ||
2381 | if (pskb_expand_head(skb, intf->beacon->queue->desc_size, | ||
2382 | 0, GFP_ATOMIC)) | ||
2383 | return -ENOMEM; | ||
2384 | } | ||
2385 | |||
2386 | /* | ||
2387 | * Add the descriptor in front of the skb. | ||
2388 | */ | ||
2389 | skb_push(skb, intf->beacon->queue->desc_size); | ||
2390 | memset(skb->data, 0, intf->beacon->queue->desc_size); | ||
2391 | 2388 | ||
2392 | /* | 2389 | /* |
2393 | * Fill in skb descriptor | 2390 | * Fill in skb descriptor |
@@ -2395,9 +2392,9 @@ static int rt61pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
2395 | skbdesc = get_skb_frame_desc(skb); | 2392 | skbdesc = get_skb_frame_desc(skb); |
2396 | memset(skbdesc, 0, sizeof(*skbdesc)); | 2393 | memset(skbdesc, 0, sizeof(*skbdesc)); |
2397 | skbdesc->flags |= FRAME_DESC_DRIVER_GENERATED; | 2394 | skbdesc->flags |= FRAME_DESC_DRIVER_GENERATED; |
2398 | skbdesc->data = skb->data + intf->beacon->queue->desc_size; | 2395 | skbdesc->data = skb->data; |
2399 | skbdesc->data_len = skb->len - intf->beacon->queue->desc_size; | 2396 | skbdesc->data_len = skb->len; |
2400 | skbdesc->desc = skb->data; | 2397 | skbdesc->desc = priv_tx->desc; |
2401 | skbdesc->desc_len = intf->beacon->queue->desc_size; | 2398 | skbdesc->desc_len = intf->beacon->queue->desc_size; |
2402 | skbdesc->entry = intf->beacon; | 2399 | skbdesc->entry = intf->beacon; |
2403 | 2400 | ||
@@ -2425,7 +2422,10 @@ static int rt61pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
2425 | */ | 2422 | */ |
2426 | beacon_base = HW_BEACON_OFFSET(intf->beacon->entry_idx); | 2423 | beacon_base = HW_BEACON_OFFSET(intf->beacon->entry_idx); |
2427 | rt2x00pci_register_multiwrite(rt2x00dev, beacon_base, | 2424 | rt2x00pci_register_multiwrite(rt2x00dev, beacon_base, |
2428 | skb->data, skb->len); | 2425 | skbdesc->desc, skbdesc->desc_len); |
2426 | rt2x00pci_register_multiwrite(rt2x00dev, | ||
2427 | beacon_base + skbdesc->desc_len, | ||
2428 | skbdesc->data, skbdesc->data_len); | ||
2429 | rt61pci_kick_tx_queue(rt2x00dev, control->queue); | 2429 | rt61pci_kick_tx_queue(rt2x00dev, control->queue); |
2430 | 2430 | ||
2431 | return 0; | 2431 | return 0; |
@@ -2490,7 +2490,7 @@ static const struct data_queue_desc rt61pci_queue_tx = { | |||
2490 | 2490 | ||
2491 | static const struct data_queue_desc rt61pci_queue_bcn = { | 2491 | static const struct data_queue_desc rt61pci_queue_bcn = { |
2492 | .entry_num = 4 * BEACON_ENTRIES, | 2492 | .entry_num = 4 * BEACON_ENTRIES, |
2493 | .data_size = MGMT_FRAME_SIZE, | 2493 | .data_size = 0, /* No DMA required for beacons */ |
2494 | .desc_size = TXINFO_SIZE, | 2494 | .desc_size = TXINFO_SIZE, |
2495 | .priv_size = sizeof(struct queue_entry_priv_pci_tx), | 2495 | .priv_size = sizeof(struct queue_entry_priv_pci_tx), |
2496 | }; | 2496 | }; |
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c index a9efe25f1ea7..46e9e081fbf1 100644 --- a/drivers/net/wireless/rt2x00/rt73usb.c +++ b/drivers/net/wireless/rt2x00/rt73usb.c | |||
@@ -134,11 +134,8 @@ static void rt73usb_bbp_write(struct rt2x00_dev *rt2x00dev, | |||
134 | * Wait until the BBP becomes ready. | 134 | * Wait until the BBP becomes ready. |
135 | */ | 135 | */ |
136 | reg = rt73usb_bbp_check(rt2x00dev); | 136 | reg = rt73usb_bbp_check(rt2x00dev); |
137 | if (rt2x00_get_field32(reg, PHY_CSR3_BUSY)) { | 137 | if (rt2x00_get_field32(reg, PHY_CSR3_BUSY)) |
138 | ERROR(rt2x00dev, "PHY_CSR3 register busy. Write failed.\n"); | 138 | goto exit_fail; |
139 | mutex_unlock(&rt2x00dev->usb_cache_mutex); | ||
140 | return; | ||
141 | } | ||
142 | 139 | ||
143 | /* | 140 | /* |
144 | * Write the data into the BBP. | 141 | * Write the data into the BBP. |
@@ -151,6 +148,13 @@ static void rt73usb_bbp_write(struct rt2x00_dev *rt2x00dev, | |||
151 | 148 | ||
152 | rt73usb_register_write_lock(rt2x00dev, PHY_CSR3, reg); | 149 | rt73usb_register_write_lock(rt2x00dev, PHY_CSR3, reg); |
153 | mutex_unlock(&rt2x00dev->usb_cache_mutex); | 150 | mutex_unlock(&rt2x00dev->usb_cache_mutex); |
151 | |||
152 | return; | ||
153 | |||
154 | exit_fail: | ||
155 | mutex_unlock(&rt2x00dev->usb_cache_mutex); | ||
156 | |||
157 | ERROR(rt2x00dev, "PHY_CSR3 register busy. Write failed.\n"); | ||
154 | } | 158 | } |
155 | 159 | ||
156 | static void rt73usb_bbp_read(struct rt2x00_dev *rt2x00dev, | 160 | static void rt73usb_bbp_read(struct rt2x00_dev *rt2x00dev, |
@@ -164,11 +168,8 @@ static void rt73usb_bbp_read(struct rt2x00_dev *rt2x00dev, | |||
164 | * Wait until the BBP becomes ready. | 168 | * Wait until the BBP becomes ready. |
165 | */ | 169 | */ |
166 | reg = rt73usb_bbp_check(rt2x00dev); | 170 | reg = rt73usb_bbp_check(rt2x00dev); |
167 | if (rt2x00_get_field32(reg, PHY_CSR3_BUSY)) { | 171 | if (rt2x00_get_field32(reg, PHY_CSR3_BUSY)) |
168 | ERROR(rt2x00dev, "PHY_CSR3 register busy. Read failed.\n"); | 172 | goto exit_fail; |
169 | mutex_unlock(&rt2x00dev->usb_cache_mutex); | ||
170 | return; | ||
171 | } | ||
172 | 173 | ||
173 | /* | 174 | /* |
174 | * Write the request into the BBP. | 175 | * Write the request into the BBP. |
@@ -184,14 +185,19 @@ static void rt73usb_bbp_read(struct rt2x00_dev *rt2x00dev, | |||
184 | * Wait until the BBP becomes ready. | 185 | * Wait until the BBP becomes ready. |
185 | */ | 186 | */ |
186 | reg = rt73usb_bbp_check(rt2x00dev); | 187 | reg = rt73usb_bbp_check(rt2x00dev); |
187 | if (rt2x00_get_field32(reg, PHY_CSR3_BUSY)) { | 188 | if (rt2x00_get_field32(reg, PHY_CSR3_BUSY)) |
188 | ERROR(rt2x00dev, "PHY_CSR3 register busy. Read failed.\n"); | 189 | goto exit_fail; |
189 | *value = 0xff; | ||
190 | return; | ||
191 | } | ||
192 | 190 | ||
193 | *value = rt2x00_get_field32(reg, PHY_CSR3_VALUE); | 191 | *value = rt2x00_get_field32(reg, PHY_CSR3_VALUE); |
194 | mutex_unlock(&rt2x00dev->usb_cache_mutex); | 192 | mutex_unlock(&rt2x00dev->usb_cache_mutex); |
193 | |||
194 | return; | ||
195 | |||
196 | exit_fail: | ||
197 | mutex_unlock(&rt2x00dev->usb_cache_mutex); | ||
198 | |||
199 | ERROR(rt2x00dev, "PHY_CSR3 register busy. Read failed.\n"); | ||
200 | *value = 0xff; | ||
195 | } | 201 | } |
196 | 202 | ||
197 | static void rt73usb_rf_write(struct rt2x00_dev *rt2x00dev, | 203 | static void rt73usb_rf_write(struct rt2x00_dev *rt2x00dev, |
@@ -1000,6 +1006,15 @@ static int rt73usb_init_registers(struct rt2x00_dev *rt2x00dev) | |||
1000 | rt2x00_set_field32(®, TXRX_CSR8_ACK_CTS_54MBS, 42); | 1006 | rt2x00_set_field32(®, TXRX_CSR8_ACK_CTS_54MBS, 42); |
1001 | rt73usb_register_write(rt2x00dev, TXRX_CSR8, reg); | 1007 | rt73usb_register_write(rt2x00dev, TXRX_CSR8, reg); |
1002 | 1008 | ||
1009 | rt73usb_register_read(rt2x00dev, TXRX_CSR9, ®); | ||
1010 | rt2x00_set_field32(®, TXRX_CSR9_BEACON_INTERVAL, 0); | ||
1011 | rt2x00_set_field32(®, TXRX_CSR9_TSF_TICKING, 0); | ||
1012 | rt2x00_set_field32(®, TXRX_CSR9_TSF_SYNC, 0); | ||
1013 | rt2x00_set_field32(®, TXRX_CSR9_TBTT_ENABLE, 0); | ||
1014 | rt2x00_set_field32(®, TXRX_CSR9_BEACON_GEN, 0); | ||
1015 | rt2x00_set_field32(®, TXRX_CSR9_TIMESTAMP_COMPENSATE, 0); | ||
1016 | rt73usb_register_write(rt2x00dev, TXRX_CSR9, reg); | ||
1017 | |||
1003 | rt73usb_register_write(rt2x00dev, TXRX_CSR15, 0x0000000f); | 1018 | rt73usb_register_write(rt2x00dev, TXRX_CSR15, 0x0000000f); |
1004 | 1019 | ||
1005 | rt73usb_register_read(rt2x00dev, MAC_CSR6, ®); | 1020 | rt73usb_register_read(rt2x00dev, MAC_CSR6, ®); |
@@ -1647,7 +1662,7 @@ static int rt73usb_init_eeprom(struct rt2x00_dev *rt2x00dev) | |||
1647 | 1662 | ||
1648 | if (value == LED_MODE_SIGNAL_STRENGTH) { | 1663 | if (value == LED_MODE_SIGNAL_STRENGTH) { |
1649 | rt2x00dev->led_qual.rt2x00dev = rt2x00dev; | 1664 | rt2x00dev->led_qual.rt2x00dev = rt2x00dev; |
1650 | rt2x00dev->led_radio.type = LED_TYPE_QUALITY; | 1665 | rt2x00dev->led_qual.type = LED_TYPE_QUALITY; |
1651 | rt2x00dev->led_qual.led_dev.brightness_set = | 1666 | rt2x00dev->led_qual.led_dev.brightness_set = |
1652 | rt73usb_brightness_set; | 1667 | rt73usb_brightness_set; |
1653 | rt2x00dev->led_qual.led_dev.blink_set = | 1668 | rt2x00dev->led_qual.led_dev.blink_set = |
@@ -2131,6 +2146,7 @@ static struct usb_device_id rt73usb_device_table[] = { | |||
2131 | /* D-Link */ | 2146 | /* D-Link */ |
2132 | { USB_DEVICE(0x07d1, 0x3c03), USB_DEVICE_DATA(&rt73usb_ops) }, | 2147 | { USB_DEVICE(0x07d1, 0x3c03), USB_DEVICE_DATA(&rt73usb_ops) }, |
2133 | { USB_DEVICE(0x07d1, 0x3c04), USB_DEVICE_DATA(&rt73usb_ops) }, | 2148 | { USB_DEVICE(0x07d1, 0x3c04), USB_DEVICE_DATA(&rt73usb_ops) }, |
2149 | { USB_DEVICE(0x07d1, 0x3c06), USB_DEVICE_DATA(&rt73usb_ops) }, | ||
2134 | { USB_DEVICE(0x07d1, 0x3c07), USB_DEVICE_DATA(&rt73usb_ops) }, | 2150 | { USB_DEVICE(0x07d1, 0x3c07), USB_DEVICE_DATA(&rt73usb_ops) }, |
2135 | /* Gemtek */ | 2151 | /* Gemtek */ |
2136 | { USB_DEVICE(0x15a9, 0x0004), USB_DEVICE_DATA(&rt73usb_ops) }, | 2152 | { USB_DEVICE(0x15a9, 0x0004), USB_DEVICE_DATA(&rt73usb_ops) }, |
diff --git a/drivers/net/wireless/rtl8180_grf5101.c b/drivers/net/wireless/rtl8180_grf5101.c index 5d47935dbac3..947ee55f18b2 100644 --- a/drivers/net/wireless/rtl8180_grf5101.c +++ b/drivers/net/wireless/rtl8180_grf5101.c | |||
@@ -88,7 +88,7 @@ static void grf5101_rf_set_channel(struct ieee80211_hw *dev, | |||
88 | write_grf5101(dev, 0x0B, chan); | 88 | write_grf5101(dev, 0x0B, chan); |
89 | write_grf5101(dev, 0x07, 0x1000); | 89 | write_grf5101(dev, 0x07, 0x1000); |
90 | 90 | ||
91 | grf5101_write_phy_antenna(dev, chan); | 91 | grf5101_write_phy_antenna(dev, channel); |
92 | } | 92 | } |
93 | 93 | ||
94 | static void grf5101_rf_stop(struct ieee80211_hw *dev) | 94 | static void grf5101_rf_stop(struct ieee80211_hw *dev) |
diff --git a/drivers/net/wireless/rtl8180_max2820.c b/drivers/net/wireless/rtl8180_max2820.c index a34dfd382b6d..6c825fd7f3b6 100644 --- a/drivers/net/wireless/rtl8180_max2820.c +++ b/drivers/net/wireless/rtl8180_max2820.c | |||
@@ -78,7 +78,8 @@ static void max2820_rf_set_channel(struct ieee80211_hw *dev, | |||
78 | struct ieee80211_conf *conf) | 78 | struct ieee80211_conf *conf) |
79 | { | 79 | { |
80 | struct rtl8180_priv *priv = dev->priv; | 80 | struct rtl8180_priv *priv = dev->priv; |
81 | int channel = ieee80211_frequency_to_channel(conf->channel->center_freq); | 81 | int channel = conf ? |
82 | ieee80211_frequency_to_channel(conf->channel->center_freq) : 1; | ||
82 | unsigned int chan_idx = channel - 1; | 83 | unsigned int chan_idx = channel - 1; |
83 | u32 txpw = priv->channels[chan_idx].hw_value & 0xFF; | 84 | u32 txpw = priv->channels[chan_idx].hw_value & 0xFF; |
84 | u32 chan = max2820_chan[chan_idx]; | 85 | u32 chan = max2820_chan[chan_idx]; |
@@ -87,7 +88,7 @@ static void max2820_rf_set_channel(struct ieee80211_hw *dev, | |||
87 | * sa2400, for MAXIM we do this directly from BB */ | 88 | * sa2400, for MAXIM we do this directly from BB */ |
88 | rtl8180_write_phy(dev, 3, txpw); | 89 | rtl8180_write_phy(dev, 3, txpw); |
89 | 90 | ||
90 | max2820_write_phy_antenna(dev, chan); | 91 | max2820_write_phy_antenna(dev, channel); |
91 | write_max2820(dev, 3, chan); | 92 | write_max2820(dev, 3, chan); |
92 | } | 93 | } |
93 | 94 | ||
diff --git a/drivers/net/wireless/rtl8180_sa2400.c b/drivers/net/wireless/rtl8180_sa2400.c index 0311b4ea124c..cea4e0ccb92d 100644 --- a/drivers/net/wireless/rtl8180_sa2400.c +++ b/drivers/net/wireless/rtl8180_sa2400.c | |||
@@ -86,7 +86,7 @@ static void sa2400_rf_set_channel(struct ieee80211_hw *dev, | |||
86 | 86 | ||
87 | write_sa2400(dev, 7, txpw); | 87 | write_sa2400(dev, 7, txpw); |
88 | 88 | ||
89 | sa2400_write_phy_antenna(dev, chan); | 89 | sa2400_write_phy_antenna(dev, channel); |
90 | 90 | ||
91 | write_sa2400(dev, 0, chan); | 91 | write_sa2400(dev, 0, chan); |
92 | write_sa2400(dev, 1, 0xbb50); | 92 | write_sa2400(dev, 1, 0xbb50); |
diff --git a/drivers/net/wireless/rtl8187_dev.c b/drivers/net/wireless/rtl8187_dev.c index d5787b37e1fb..9223ada5f00e 100644 --- a/drivers/net/wireless/rtl8187_dev.c +++ b/drivers/net/wireless/rtl8187_dev.c | |||
@@ -92,6 +92,7 @@ static void rtl8187_iowrite_async(struct rtl8187_priv *priv, __le16 addr, | |||
92 | u8 data[4]; | 92 | u8 data[4]; |
93 | struct usb_ctrlrequest dr; | 93 | struct usb_ctrlrequest dr; |
94 | } *buf; | 94 | } *buf; |
95 | int rc; | ||
95 | 96 | ||
96 | buf = kmalloc(sizeof(*buf), GFP_ATOMIC); | 97 | buf = kmalloc(sizeof(*buf), GFP_ATOMIC); |
97 | if (!buf) | 98 | if (!buf) |
@@ -116,7 +117,11 @@ static void rtl8187_iowrite_async(struct rtl8187_priv *priv, __le16 addr, | |||
116 | usb_fill_control_urb(urb, priv->udev, usb_sndctrlpipe(priv->udev, 0), | 117 | usb_fill_control_urb(urb, priv->udev, usb_sndctrlpipe(priv->udev, 0), |
117 | (unsigned char *)dr, buf, len, | 118 | (unsigned char *)dr, buf, len, |
118 | rtl8187_iowrite_async_cb, buf); | 119 | rtl8187_iowrite_async_cb, buf); |
119 | usb_submit_urb(urb, GFP_ATOMIC); | 120 | rc = usb_submit_urb(urb, GFP_ATOMIC); |
121 | if (rc < 0) { | ||
122 | kfree(buf); | ||
123 | usb_free_urb(urb); | ||
124 | } | ||
120 | } | 125 | } |
121 | 126 | ||
122 | static inline void rtl818x_iowrite32_async(struct rtl8187_priv *priv, | 127 | static inline void rtl818x_iowrite32_async(struct rtl8187_priv *priv, |
@@ -169,6 +174,7 @@ static int rtl8187_tx(struct ieee80211_hw *dev, struct sk_buff *skb, | |||
169 | struct urb *urb; | 174 | struct urb *urb; |
170 | __le16 rts_dur = 0; | 175 | __le16 rts_dur = 0; |
171 | u32 flags; | 176 | u32 flags; |
177 | int rc; | ||
172 | 178 | ||
173 | urb = usb_alloc_urb(0, GFP_ATOMIC); | 179 | urb = usb_alloc_urb(0, GFP_ATOMIC); |
174 | if (!urb) { | 180 | if (!urb) { |
@@ -208,7 +214,11 @@ static int rtl8187_tx(struct ieee80211_hw *dev, struct sk_buff *skb, | |||
208 | info->dev = dev; | 214 | info->dev = dev; |
209 | usb_fill_bulk_urb(urb, priv->udev, usb_sndbulkpipe(priv->udev, 2), | 215 | usb_fill_bulk_urb(urb, priv->udev, usb_sndbulkpipe(priv->udev, 2), |
210 | hdr, skb->len, rtl8187_tx_cb, skb); | 216 | hdr, skb->len, rtl8187_tx_cb, skb); |
211 | usb_submit_urb(urb, GFP_ATOMIC); | 217 | rc = usb_submit_urb(urb, GFP_ATOMIC); |
218 | if (rc < 0) { | ||
219 | usb_free_urb(urb); | ||
220 | kfree_skb(skb); | ||
221 | } | ||
212 | 222 | ||
213 | return 0; | 223 | return 0; |
214 | } | 224 | } |
diff --git a/drivers/net/wireless/strip.c b/drivers/net/wireless/strip.c index 5dd23c93497d..883af891ebfb 100644 --- a/drivers/net/wireless/strip.c +++ b/drivers/net/wireless/strip.c | |||
@@ -2611,7 +2611,7 @@ static int strip_open(struct tty_struct *tty) | |||
2611 | * We need a write method. | 2611 | * We need a write method. |
2612 | */ | 2612 | */ |
2613 | 2613 | ||
2614 | if (tty->ops->write == NULL) | 2614 | if (tty->ops->write == NULL || tty->ops->set_termios == NULL) |
2615 | return -EOPNOTSUPP; | 2615 | return -EOPNOTSUPP; |
2616 | 2616 | ||
2617 | /* | 2617 | /* |
diff --git a/drivers/net/wireless/wavelan.c b/drivers/net/wireless/wavelan.c index 03384a43186b..49ae97003952 100644 --- a/drivers/net/wireless/wavelan.c +++ b/drivers/net/wireless/wavelan.c | |||
@@ -908,9 +908,9 @@ static void wv_psa_show(psa_t * p) | |||
908 | p->psa_call_code[3], p->psa_call_code[4], p->psa_call_code[5], | 908 | p->psa_call_code[3], p->psa_call_code[4], p->psa_call_code[5], |
909 | p->psa_call_code[6], p->psa_call_code[7]); | 909 | p->psa_call_code[6], p->psa_call_code[7]); |
910 | #ifdef DEBUG_SHOW_UNUSED | 910 | #ifdef DEBUG_SHOW_UNUSED |
911 | printk(KERN_DEBUG "psa_reserved[]: %02X:%02X:%02X:%02X\n", | 911 | printk(KERN_DEBUG "psa_reserved[]: %02X:%02X\n", |
912 | p->psa_reserved[0], | 912 | p->psa_reserved[0], |
913 | p->psa_reserved[1], p->psa_reserved[2], p->psa_reserved[3]); | 913 | p->psa_reserved[1]); |
914 | #endif /* DEBUG_SHOW_UNUSED */ | 914 | #endif /* DEBUG_SHOW_UNUSED */ |
915 | printk(KERN_DEBUG "psa_conf_status: %d, ", p->psa_conf_status); | 915 | printk(KERN_DEBUG "psa_conf_status: %d, ", p->psa_conf_status); |
916 | printk("psa_crc: 0x%02x%02x, ", p->psa_crc[0], p->psa_crc[1]); | 916 | printk("psa_crc: 0x%02x%02x, ", p->psa_crc[0], p->psa_crc[1]); |
diff --git a/drivers/net/wireless/wavelan_cs.c b/drivers/net/wireless/wavelan_cs.c index baf74015751c..b584c0ecc62d 100644 --- a/drivers/net/wireless/wavelan_cs.c +++ b/drivers/net/wireless/wavelan_cs.c | |||
@@ -1074,11 +1074,9 @@ wv_psa_show(psa_t * p) | |||
1074 | p->psa_call_code[6], | 1074 | p->psa_call_code[6], |
1075 | p->psa_call_code[7]); | 1075 | p->psa_call_code[7]); |
1076 | #ifdef DEBUG_SHOW_UNUSED | 1076 | #ifdef DEBUG_SHOW_UNUSED |
1077 | printk(KERN_DEBUG "psa_reserved[]: %02X:%02X:%02X:%02X\n", | 1077 | printk(KERN_DEBUG "psa_reserved[]: %02X:%02X\n", |
1078 | p->psa_reserved[0], | 1078 | p->psa_reserved[0], |
1079 | p->psa_reserved[1], | 1079 | p->psa_reserved[1]); |
1080 | p->psa_reserved[2], | ||
1081 | p->psa_reserved[3]); | ||
1082 | #endif /* DEBUG_SHOW_UNUSED */ | 1080 | #endif /* DEBUG_SHOW_UNUSED */ |
1083 | printk(KERN_DEBUG "psa_conf_status: %d, ", p->psa_conf_status); | 1081 | printk(KERN_DEBUG "psa_conf_status: %d, ", p->psa_conf_status); |
1084 | printk("psa_crc: 0x%02x%02x, ", p->psa_crc[0], p->psa_crc[1]); | 1082 | printk("psa_crc: 0x%02x%02x, ", p->psa_crc[0], p->psa_crc[1]); |
diff --git a/drivers/net/wireless/zd1211rw/zd_mac.c b/drivers/net/wireless/zd1211rw/zd_mac.c index 69c45ca99051..694e95d35fd4 100644 --- a/drivers/net/wireless/zd1211rw/zd_mac.c +++ b/drivers/net/wireless/zd1211rw/zd_mac.c | |||
@@ -719,7 +719,7 @@ int zd_mac_rx(struct ieee80211_hw *hw, const u8 *buffer, unsigned int length) | |||
719 | fc = le16_to_cpu(*((__le16 *) buffer)); | 719 | fc = le16_to_cpu(*((__le16 *) buffer)); |
720 | 720 | ||
721 | is_qos = ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA) && | 721 | is_qos = ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA) && |
722 | ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_QOS_DATA); | 722 | (fc & IEEE80211_STYPE_QOS_DATA); |
723 | is_4addr = (fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) == | 723 | is_4addr = (fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) == |
724 | (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS); | 724 | (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS); |
725 | need_padding = is_qos ^ is_4addr; | 725 | need_padding = is_qos ^ is_4addr; |
@@ -765,6 +765,7 @@ static void zd_op_remove_interface(struct ieee80211_hw *hw, | |||
765 | { | 765 | { |
766 | struct zd_mac *mac = zd_hw_mac(hw); | 766 | struct zd_mac *mac = zd_hw_mac(hw); |
767 | mac->type = IEEE80211_IF_TYPE_INVALID; | 767 | mac->type = IEEE80211_IF_TYPE_INVALID; |
768 | zd_set_beacon_interval(&mac->chip, 0); | ||
768 | zd_write_mac_addr(&mac->chip, NULL); | 769 | zd_write_mac_addr(&mac->chip, NULL); |
769 | } | 770 | } |
770 | 771 | ||
@@ -805,7 +806,7 @@ void zd_process_intr(struct work_struct *work) | |||
805 | u16 int_status; | 806 | u16 int_status; |
806 | struct zd_mac *mac = container_of(work, struct zd_mac, process_intr); | 807 | struct zd_mac *mac = container_of(work, struct zd_mac, process_intr); |
807 | 808 | ||
808 | int_status = le16_to_cpu(*(u16 *)(mac->intr_buffer+4)); | 809 | int_status = le16_to_cpu(*(__le16 *)(mac->intr_buffer+4)); |
809 | if (int_status & INT_CFG_NEXT_BCN) { | 810 | if (int_status & INT_CFG_NEXT_BCN) { |
810 | if (net_ratelimit()) | 811 | if (net_ratelimit()) |
811 | dev_dbg_f(zd_mac_dev(mac), "INT_CFG_NEXT_BCN\n"); | 812 | dev_dbg_f(zd_mac_dev(mac), "INT_CFG_NEXT_BCN\n"); |
diff --git a/drivers/net/wireless/zd1211rw/zd_usb.c b/drivers/net/wireless/zd1211rw/zd_usb.c index 5316074f39f0..6cdad9764604 100644 --- a/drivers/net/wireless/zd1211rw/zd_usb.c +++ b/drivers/net/wireless/zd1211rw/zd_usb.c | |||
@@ -64,6 +64,7 @@ static struct usb_device_id usb_ids[] = { | |||
64 | { USB_DEVICE(0x079b, 0x0062), .driver_info = DEVICE_ZD1211B }, | 64 | { USB_DEVICE(0x079b, 0x0062), .driver_info = DEVICE_ZD1211B }, |
65 | { USB_DEVICE(0x1582, 0x6003), .driver_info = DEVICE_ZD1211B }, | 65 | { USB_DEVICE(0x1582, 0x6003), .driver_info = DEVICE_ZD1211B }, |
66 | { USB_DEVICE(0x050d, 0x705c), .driver_info = DEVICE_ZD1211B }, | 66 | { USB_DEVICE(0x050d, 0x705c), .driver_info = DEVICE_ZD1211B }, |
67 | { USB_DEVICE(0x083a, 0xe506), .driver_info = DEVICE_ZD1211B }, | ||
67 | { USB_DEVICE(0x083a, 0x4505), .driver_info = DEVICE_ZD1211B }, | 68 | { USB_DEVICE(0x083a, 0x4505), .driver_info = DEVICE_ZD1211B }, |
68 | { USB_DEVICE(0x0471, 0x1236), .driver_info = DEVICE_ZD1211B }, | 69 | { USB_DEVICE(0x0471, 0x1236), .driver_info = DEVICE_ZD1211B }, |
69 | { USB_DEVICE(0x13b1, 0x0024), .driver_info = DEVICE_ZD1211B }, | 70 | { USB_DEVICE(0x13b1, 0x0024), .driver_info = DEVICE_ZD1211B }, |
@@ -342,7 +343,7 @@ static inline void handle_regs_int(struct urb *urb) | |||
342 | ZD_ASSERT(in_interrupt()); | 343 | ZD_ASSERT(in_interrupt()); |
343 | spin_lock(&intr->lock); | 344 | spin_lock(&intr->lock); |
344 | 345 | ||
345 | int_num = le16_to_cpu(*(u16 *)(urb->transfer_buffer+2)); | 346 | int_num = le16_to_cpu(*(__le16 *)(urb->transfer_buffer+2)); |
346 | if (int_num == CR_INTERRUPT) { | 347 | if (int_num == CR_INTERRUPT) { |
347 | struct zd_mac *mac = zd_hw_mac(zd_usb_to_hw(urb->context)); | 348 | struct zd_mac *mac = zd_hw_mac(zd_usb_to_hw(urb->context)); |
348 | memcpy(&mac->intr_buffer, urb->transfer_buffer, | 349 | memcpy(&mac->intr_buffer, urb->transfer_buffer, |
@@ -889,9 +890,13 @@ static void tx_urb_complete(struct urb *urb) | |||
889 | } | 890 | } |
890 | free_urb: | 891 | free_urb: |
891 | skb = (struct sk_buff *)urb->context; | 892 | skb = (struct sk_buff *)urb->context; |
892 | zd_mac_tx_to_dev(skb, urb->status); | 893 | /* |
894 | * grab 'usb' pointer before handing off the skb (since | ||
895 | * it might be freed by zd_mac_tx_to_dev or mac80211) | ||
896 | */ | ||
893 | cb = (struct zd_tx_skb_control_block *)skb->cb; | 897 | cb = (struct zd_tx_skb_control_block *)skb->cb; |
894 | usb = &zd_hw_mac(cb->hw)->chip.usb; | 898 | usb = &zd_hw_mac(cb->hw)->chip.usb; |
899 | zd_mac_tx_to_dev(skb, urb->status); | ||
895 | free_tx_urb(usb, urb); | 900 | free_tx_urb(usb, urb); |
896 | tx_dec_submitted_urbs(usb); | 901 | tx_dec_submitted_urbs(usb); |
897 | return; | 902 | return; |
diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c index e62018a36133..d26f69b0184f 100644 --- a/drivers/net/xen-netfront.c +++ b/drivers/net/xen-netfront.c | |||
@@ -946,8 +946,7 @@ err: | |||
946 | work_done++; | 946 | work_done++; |
947 | } | 947 | } |
948 | 948 | ||
949 | while ((skb = __skb_dequeue(&errq))) | 949 | __skb_queue_purge(&errq); |
950 | kfree_skb(skb); | ||
951 | 950 | ||
952 | work_done -= handle_incoming_queue(dev, &rxq); | 951 | work_done -= handle_incoming_queue(dev, &rxq); |
953 | 952 | ||
@@ -1079,8 +1078,7 @@ static void xennet_release_rx_bufs(struct netfront_info *np) | |||
1079 | } | 1078 | } |
1080 | } | 1079 | } |
1081 | 1080 | ||
1082 | while ((skb = __skb_dequeue(&free_list)) != NULL) | 1081 | __skb_queue_purge(&free_list); |
1083 | dev_kfree_skb(skb); | ||
1084 | 1082 | ||
1085 | spin_unlock_bh(&np->rx_lock); | 1083 | spin_unlock_bh(&np->rx_lock); |
1086 | } | 1084 | } |
@@ -1803,7 +1801,7 @@ static void __exit netif_exit(void) | |||
1803 | if (is_initial_xendomain()) | 1801 | if (is_initial_xendomain()) |
1804 | return; | 1802 | return; |
1805 | 1803 | ||
1806 | return xenbus_unregister_driver(&netfront); | 1804 | xenbus_unregister_driver(&netfront); |
1807 | } | 1805 | } |
1808 | module_exit(netif_exit); | 1806 | module_exit(netif_exit); |
1809 | 1807 | ||