aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/forcedeth.c406
1 files changed, 398 insertions, 8 deletions
diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c
index 8d7666856420..6ee3e8d5a04d 100644
--- a/drivers/net/forcedeth.c
+++ b/drivers/net/forcedeth.c
@@ -166,6 +166,7 @@
166#define DEV_HAS_POWER_CNTRL 0x0100 /* device supports power savings */ 166#define DEV_HAS_POWER_CNTRL 0x0100 /* device supports power savings */
167#define DEV_HAS_PAUSEFRAME_TX 0x0200 /* device supports tx pause frames */ 167#define DEV_HAS_PAUSEFRAME_TX 0x0200 /* device supports tx pause frames */
168#define DEV_HAS_STATISTICS 0x0400 /* device supports hw statistics */ 168#define DEV_HAS_STATISTICS 0x0400 /* device supports hw statistics */
169#define DEV_HAS_TEST_EXTENDED 0x0800 /* device supports extended diagnostic test */
169 170
170enum { 171enum {
171 NvRegIrqStatus = 0x000, 172 NvRegIrqStatus = 0x000,
@@ -222,6 +223,7 @@ enum {
222#define NVREG_PFF_ALWAYS 0x7F0000 223#define NVREG_PFF_ALWAYS 0x7F0000
223#define NVREG_PFF_PROMISC 0x80 224#define NVREG_PFF_PROMISC 0x80
224#define NVREG_PFF_MYADDR 0x20 225#define NVREG_PFF_MYADDR 0x20
226#define NVREG_PFF_LOOPBACK 0x10
225 227
226 NvRegOffloadConfig = 0x90, 228 NvRegOffloadConfig = 0x90,
227#define NVREG_OFFLOAD_HOMEPHY 0x601 229#define NVREG_OFFLOAD_HOMEPHY 0x601
@@ -634,6 +636,32 @@ struct nv_ethtool_stats {
634 u64 rx_errors_total; 636 u64 rx_errors_total;
635}; 637};
636 638
639/* diagnostics */
640#define NV_TEST_COUNT_BASE 3
641#define NV_TEST_COUNT_EXTENDED 4
642
643static const struct nv_ethtool_str nv_etests_str[] = {
644 { "link (online/offline)" },
645 { "register (offline) " },
646 { "interrupt (offline) " },
647 { "loopback (offline) " }
648};
649
650struct register_test {
651 u32 reg;
652 u32 mask;
653};
654
655static const struct register_test nv_registers_test[] = {
656 { NvRegUnknownSetupReg6, 0x01 },
657 { NvRegMisc1, 0x03c },
658 { NvRegOffloadConfig, 0x03ff },
659 { NvRegMulticastAddrA, 0xffffffff },
660 { NvRegUnknownSetupReg3, 0x0ff },
661 { NvRegWakeUpFlags, 0x07777 },
662 { 0,0 }
663};
664
637/* 665/*
638 * SMP locking: 666 * SMP locking:
639 * All hardware access under dev->priv->lock, except the performance 667 * All hardware access under dev->priv->lock, except the performance
@@ -662,6 +690,7 @@ struct fe_priv {
662 int wolenabled; 690 int wolenabled;
663 unsigned int phy_oui; 691 unsigned int phy_oui;
664 u16 gigabit; 692 u16 gigabit;
693 int intr_test;
665 694
666 /* General data: RO fields */ 695 /* General data: RO fields */
667 dma_addr_t ring_addr; 696 dma_addr_t ring_addr;
@@ -2502,6 +2531,36 @@ static irqreturn_t nv_nic_irq_other(int foo, void *data, struct pt_regs *regs)
2502 return IRQ_RETVAL(i); 2531 return IRQ_RETVAL(i);
2503} 2532}
2504 2533
2534static irqreturn_t nv_nic_irq_test(int foo, void *data, struct pt_regs *regs)
2535{
2536 struct net_device *dev = (struct net_device *) data;
2537 struct fe_priv *np = netdev_priv(dev);
2538 u8 __iomem *base = get_hwbase(dev);
2539 u32 events;
2540
2541 dprintk(KERN_DEBUG "%s: nv_nic_irq_test\n", dev->name);
2542
2543 if (!(np->msi_flags & NV_MSI_X_ENABLED)) {
2544 events = readl(base + NvRegIrqStatus) & NVREG_IRQSTAT_MASK;
2545 writel(NVREG_IRQ_TIMER, base + NvRegIrqStatus);
2546 } else {
2547 events = readl(base + NvRegMSIXIrqStatus) & NVREG_IRQSTAT_MASK;
2548 writel(NVREG_IRQ_TIMER, base + NvRegMSIXIrqStatus);
2549 }
2550 pci_push(base);
2551 dprintk(KERN_DEBUG "%s: irq: %08x\n", dev->name, events);
2552 if (!(events & NVREG_IRQ_TIMER))
2553 return IRQ_RETVAL(0);
2554
2555 spin_lock(&np->lock);
2556 np->intr_test = 1;
2557 spin_unlock(&np->lock);
2558
2559 dprintk(KERN_DEBUG "%s: nv_nic_irq_test completed\n", dev->name);
2560
2561 return IRQ_RETVAL(1);
2562}
2563
2505static void set_msix_vector_map(struct net_device *dev, u32 vector, u32 irqmask) 2564static void set_msix_vector_map(struct net_device *dev, u32 vector, u32 irqmask)
2506{ 2565{
2507 u8 __iomem *base = get_hwbase(dev); 2566 u8 __iomem *base = get_hwbase(dev);
@@ -2528,7 +2587,7 @@ static void set_msix_vector_map(struct net_device *dev, u32 vector, u32 irqmask)
2528 writel(readl(base + NvRegMSIXMap1) | msixmap, base + NvRegMSIXMap1); 2587 writel(readl(base + NvRegMSIXMap1) | msixmap, base + NvRegMSIXMap1);
2529} 2588}
2530 2589
2531static int nv_request_irq(struct net_device *dev) 2590static int nv_request_irq(struct net_device *dev, int intr_test)
2532{ 2591{
2533 struct fe_priv *np = get_nvpriv(dev); 2592 struct fe_priv *np = get_nvpriv(dev);
2534 u8 __iomem *base = get_hwbase(dev); 2593 u8 __iomem *base = get_hwbase(dev);
@@ -2541,7 +2600,7 @@ static int nv_request_irq(struct net_device *dev)
2541 } 2600 }
2542 if ((ret = pci_enable_msix(np->pci_dev, np->msi_x_entry, (np->msi_flags & NV_MSI_X_VECTORS_MASK))) == 0) { 2601 if ((ret = pci_enable_msix(np->pci_dev, np->msi_x_entry, (np->msi_flags & NV_MSI_X_VECTORS_MASK))) == 0) {
2543 np->msi_flags |= NV_MSI_X_ENABLED; 2602 np->msi_flags |= NV_MSI_X_ENABLED;
2544 if (optimization_mode == NV_OPTIMIZATION_MODE_THROUGHPUT) { 2603 if (optimization_mode == NV_OPTIMIZATION_MODE_THROUGHPUT && !intr_test) {
2545 /* Request irq for rx handling */ 2604 /* Request irq for rx handling */
2546 if (request_irq(np->msi_x_entry[NV_MSI_X_VECTOR_RX].vector, &nv_nic_irq_rx, SA_SHIRQ, dev->name, dev) != 0) { 2605 if (request_irq(np->msi_x_entry[NV_MSI_X_VECTOR_RX].vector, &nv_nic_irq_rx, SA_SHIRQ, dev->name, dev) != 0) {
2547 printk(KERN_INFO "forcedeth: request_irq failed for rx %d\n", ret); 2606 printk(KERN_INFO "forcedeth: request_irq failed for rx %d\n", ret);
@@ -2571,7 +2630,10 @@ static int nv_request_irq(struct net_device *dev)
2571 set_msix_vector_map(dev, NV_MSI_X_VECTOR_OTHER, NVREG_IRQ_OTHER); 2630 set_msix_vector_map(dev, NV_MSI_X_VECTOR_OTHER, NVREG_IRQ_OTHER);
2572 } else { 2631 } else {
2573 /* Request irq for all interrupts */ 2632 /* Request irq for all interrupts */
2574 if (request_irq(np->msi_x_entry[NV_MSI_X_VECTOR_ALL].vector, &nv_nic_irq, SA_SHIRQ, dev->name, dev) != 0) { 2633 if ((!intr_test &&
2634 request_irq(np->msi_x_entry[NV_MSI_X_VECTOR_ALL].vector, &nv_nic_irq, SA_SHIRQ, dev->name, dev) != 0) ||
2635 (intr_test &&
2636 request_irq(np->msi_x_entry[NV_MSI_X_VECTOR_ALL].vector, &nv_nic_irq_test, SA_SHIRQ, dev->name, dev) != 0)) {
2575 printk(KERN_INFO "forcedeth: request_irq failed %d\n", ret); 2637 printk(KERN_INFO "forcedeth: request_irq failed %d\n", ret);
2576 pci_disable_msix(np->pci_dev); 2638 pci_disable_msix(np->pci_dev);
2577 np->msi_flags &= ~NV_MSI_X_ENABLED; 2639 np->msi_flags &= ~NV_MSI_X_ENABLED;
@@ -2587,7 +2649,8 @@ static int nv_request_irq(struct net_device *dev)
2587 if (ret != 0 && np->msi_flags & NV_MSI_CAPABLE) { 2649 if (ret != 0 && np->msi_flags & NV_MSI_CAPABLE) {
2588 if ((ret = pci_enable_msi(np->pci_dev)) == 0) { 2650 if ((ret = pci_enable_msi(np->pci_dev)) == 0) {
2589 np->msi_flags |= NV_MSI_ENABLED; 2651 np->msi_flags |= NV_MSI_ENABLED;
2590 if (request_irq(np->pci_dev->irq, &nv_nic_irq, SA_SHIRQ, dev->name, dev) != 0) { 2652 if ((!intr_test && request_irq(np->pci_dev->irq, &nv_nic_irq, SA_SHIRQ, dev->name, dev) != 0) ||
2653 (intr_test && request_irq(np->pci_dev->irq, &nv_nic_irq_test, SA_SHIRQ, dev->name, dev) != 0)) {
2591 printk(KERN_INFO "forcedeth: request_irq failed %d\n", ret); 2654 printk(KERN_INFO "forcedeth: request_irq failed %d\n", ret);
2592 pci_disable_msi(np->pci_dev); 2655 pci_disable_msi(np->pci_dev);
2593 np->msi_flags &= ~NV_MSI_ENABLED; 2656 np->msi_flags &= ~NV_MSI_ENABLED;
@@ -2602,8 +2665,10 @@ static int nv_request_irq(struct net_device *dev)
2602 } 2665 }
2603 } 2666 }
2604 if (ret != 0) { 2667 if (ret != 0) {
2605 if (request_irq(np->pci_dev->irq, &nv_nic_irq, SA_SHIRQ, dev->name, dev) != 0) 2668 if ((!intr_test && request_irq(np->pci_dev->irq, &nv_nic_irq, SA_SHIRQ, dev->name, dev) != 0) ||
2669 (intr_test && request_irq(np->pci_dev->irq, &nv_nic_irq_test, SA_SHIRQ, dev->name, dev) != 0))
2606 goto out_err; 2670 goto out_err;
2671
2607 } 2672 }
2608 2673
2609 return 0; 2674 return 0;
@@ -3387,12 +3452,335 @@ static void nv_get_ethtool_stats(struct net_device *dev, struct ethtool_stats *e
3387 memcpy(buffer, &np->estats, nv_get_stats_count(dev)*sizeof(u64)); 3452 memcpy(buffer, &np->estats, nv_get_stats_count(dev)*sizeof(u64));
3388} 3453}
3389 3454
3455static int nv_self_test_count(struct net_device *dev)
3456{
3457 struct fe_priv *np = netdev_priv(dev);
3458
3459 if (np->driver_data & DEV_HAS_TEST_EXTENDED)
3460 return NV_TEST_COUNT_EXTENDED;
3461 else
3462 return NV_TEST_COUNT_BASE;
3463}
3464
3465static int nv_link_test(struct net_device *dev)
3466{
3467 struct fe_priv *np = netdev_priv(dev);
3468 int mii_status;
3469
3470 mii_rw(dev, np->phyaddr, MII_BMSR, MII_READ);
3471 mii_status = mii_rw(dev, np->phyaddr, MII_BMSR, MII_READ);
3472
3473 /* check phy link status */
3474 if (!(mii_status & BMSR_LSTATUS))
3475 return 0;
3476 else
3477 return 1;
3478}
3479
3480static int nv_register_test(struct net_device *dev)
3481{
3482 u8 __iomem *base = get_hwbase(dev);
3483 int i = 0;
3484 u32 orig_read, new_read;
3485
3486 do {
3487 orig_read = readl(base + nv_registers_test[i].reg);
3488
3489 /* xor with mask to toggle bits */
3490 orig_read ^= nv_registers_test[i].mask;
3491
3492 writel(orig_read, base + nv_registers_test[i].reg);
3493
3494 new_read = readl(base + nv_registers_test[i].reg);
3495
3496 if ((new_read & nv_registers_test[i].mask) != (orig_read & nv_registers_test[i].mask))
3497 return 0;
3498
3499 /* restore original value */
3500 orig_read ^= nv_registers_test[i].mask;
3501 writel(orig_read, base + nv_registers_test[i].reg);
3502
3503 } while (nv_registers_test[++i].reg != 0);
3504
3505 return 1;
3506}
3507
3508static int nv_interrupt_test(struct net_device *dev)
3509{
3510 struct fe_priv *np = netdev_priv(dev);
3511 u8 __iomem *base = get_hwbase(dev);
3512 int ret = 1;
3513 int testcnt;
3514 u32 save_msi_flags, save_poll_interval = 0;
3515
3516 if (netif_running(dev)) {
3517 /* free current irq */
3518 nv_free_irq(dev);
3519 save_poll_interval = readl(base+NvRegPollingInterval);
3520 }
3521
3522 /* flag to test interrupt handler */
3523 np->intr_test = 0;
3524
3525 /* setup test irq */
3526 save_msi_flags = np->msi_flags;
3527 np->msi_flags &= ~NV_MSI_X_VECTORS_MASK;
3528 np->msi_flags |= 0x001; /* setup 1 vector */
3529 if (nv_request_irq(dev, 1))
3530 return 0;
3531
3532 /* setup timer interrupt */
3533 writel(NVREG_POLL_DEFAULT_CPU, base + NvRegPollingInterval);
3534 writel(NVREG_UNKSETUP6_VAL, base + NvRegUnknownSetupReg6);
3535
3536 nv_enable_hw_interrupts(dev, NVREG_IRQ_TIMER);
3537
3538 /* wait for at least one interrupt */
3539 msleep(100);
3540
3541 spin_lock_irq(&np->lock);
3542
3543 /* flag should be set within ISR */
3544 testcnt = np->intr_test;
3545 if (!testcnt)
3546 ret = 2;
3547
3548 nv_disable_hw_interrupts(dev, NVREG_IRQ_TIMER);
3549 if (!(np->msi_flags & NV_MSI_X_ENABLED))
3550 writel(NVREG_IRQSTAT_MASK, base + NvRegIrqStatus);
3551 else
3552 writel(NVREG_IRQSTAT_MASK, base + NvRegMSIXIrqStatus);
3553
3554 spin_unlock_irq(&np->lock);
3555
3556 nv_free_irq(dev);
3557
3558 np->msi_flags = save_msi_flags;
3559
3560 if (netif_running(dev)) {
3561 writel(save_poll_interval, base + NvRegPollingInterval);
3562 writel(NVREG_UNKSETUP6_VAL, base + NvRegUnknownSetupReg6);
3563 /* restore original irq */
3564 if (nv_request_irq(dev, 0))
3565 return 0;
3566 }
3567
3568 return ret;
3569}
3570
3571static int nv_loopback_test(struct net_device *dev)
3572{
3573 struct fe_priv *np = netdev_priv(dev);
3574 u8 __iomem *base = get_hwbase(dev);
3575 struct sk_buff *tx_skb, *rx_skb;
3576 dma_addr_t test_dma_addr;
3577 u32 tx_flags_extra = (np->desc_ver == DESC_VER_1 ? NV_TX_LASTPACKET : NV_TX2_LASTPACKET);
3578 u32 Flags;
3579 int len, i, pkt_len;
3580 u8 *pkt_data;
3581 u32 filter_flags = 0;
3582 u32 misc1_flags = 0;
3583 int ret = 1;
3584
3585 if (netif_running(dev)) {
3586 nv_disable_irq(dev);
3587 filter_flags = readl(base + NvRegPacketFilterFlags);
3588 misc1_flags = readl(base + NvRegMisc1);
3589 } else {
3590 nv_txrx_reset(dev);
3591 }
3592
3593 /* reinit driver view of the rx queue */
3594 set_bufsize(dev);
3595 nv_init_ring(dev);
3596
3597 /* setup hardware for loopback */
3598 writel(NVREG_MISC1_FORCE, base + NvRegMisc1);
3599 writel(NVREG_PFF_ALWAYS | NVREG_PFF_LOOPBACK, base + NvRegPacketFilterFlags);
3600
3601 /* reinit nic view of the rx queue */
3602 writel(np->rx_buf_sz, base + NvRegOffloadConfig);
3603 setup_hw_rings(dev, NV_SETUP_RX_RING | NV_SETUP_TX_RING);
3604 writel( ((np->rx_ring_size-1) << NVREG_RINGSZ_RXSHIFT) + ((np->tx_ring_size-1) << NVREG_RINGSZ_TXSHIFT),
3605 base + NvRegRingSizes);
3606 pci_push(base);
3607
3608 /* restart rx engine */
3609 nv_start_rx(dev);
3610 nv_start_tx(dev);
3611
3612 /* setup packet for tx */
3613 pkt_len = ETH_DATA_LEN;
3614 tx_skb = dev_alloc_skb(pkt_len);
3615 pkt_data = skb_put(tx_skb, pkt_len);
3616 for (i = 0; i < pkt_len; i++)
3617 pkt_data[i] = (u8)(i & 0xff);
3618 test_dma_addr = pci_map_single(np->pci_dev, tx_skb->data,
3619 tx_skb->end-tx_skb->data, PCI_DMA_FROMDEVICE);
3620
3621 if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2) {
3622 np->tx_ring.orig[0].PacketBuffer = cpu_to_le32(test_dma_addr);
3623 np->tx_ring.orig[0].FlagLen = cpu_to_le32((pkt_len-1) | np->tx_flags | tx_flags_extra);
3624 } else {
3625 np->tx_ring.ex[0].PacketBufferHigh = cpu_to_le64(test_dma_addr) >> 32;
3626 np->tx_ring.ex[0].PacketBufferLow = cpu_to_le64(test_dma_addr) & 0x0FFFFFFFF;
3627 np->tx_ring.ex[0].FlagLen = cpu_to_le32((pkt_len-1) | np->tx_flags | tx_flags_extra);
3628 }
3629 writel(NVREG_TXRXCTL_KICK|np->txrxctl_bits, get_hwbase(dev) + NvRegTxRxControl);
3630 pci_push(get_hwbase(dev));
3631
3632 msleep(500);
3633
3634 /* check for rx of the packet */
3635 if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2) {
3636 Flags = le32_to_cpu(np->rx_ring.orig[0].FlagLen);
3637 len = nv_descr_getlength(&np->rx_ring.orig[0], np->desc_ver);
3638
3639 } else {
3640 Flags = le32_to_cpu(np->rx_ring.ex[0].FlagLen);
3641 len = nv_descr_getlength_ex(&np->rx_ring.ex[0], np->desc_ver);
3642 }
3643
3644 if (Flags & NV_RX_AVAIL) {
3645 ret = 0;
3646 } else if (np->desc_ver == DESC_VER_1) {
3647 if (Flags & NV_RX_ERROR)
3648 ret = 0;
3649 } else {
3650 if (Flags & NV_RX2_ERROR) {
3651 ret = 0;
3652 }
3653 }
3654
3655 if (ret) {
3656 if (len != pkt_len) {
3657 ret = 0;
3658 dprintk(KERN_DEBUG "%s: loopback len mismatch %d vs %d\n",
3659 dev->name, len, pkt_len);
3660 } else {
3661 rx_skb = np->rx_skbuff[0];
3662 for (i = 0; i < pkt_len; i++) {
3663 if (rx_skb->data[i] != (u8)(i & 0xff)) {
3664 ret = 0;
3665 dprintk(KERN_DEBUG "%s: loopback pattern check failed on byte %d\n",
3666 dev->name, i);
3667 break;
3668 }
3669 }
3670 }
3671 } else {
3672 dprintk(KERN_DEBUG "%s: loopback - did not receive test packet\n", dev->name);
3673 }
3674
3675 pci_unmap_page(np->pci_dev, test_dma_addr,
3676 tx_skb->end-tx_skb->data,
3677 PCI_DMA_TODEVICE);
3678 dev_kfree_skb_any(tx_skb);
3679
3680 /* stop engines */
3681 nv_stop_rx(dev);
3682 nv_stop_tx(dev);
3683 nv_txrx_reset(dev);
3684 /* drain rx queue */
3685 nv_drain_rx(dev);
3686 nv_drain_tx(dev);
3687
3688 if (netif_running(dev)) {
3689 writel(misc1_flags, base + NvRegMisc1);
3690 writel(filter_flags, base + NvRegPacketFilterFlags);
3691 nv_enable_irq(dev);
3692 }
3693
3694 return ret;
3695}
3696
3697static void nv_self_test(struct net_device *dev, struct ethtool_test *test, u64 *buffer)
3698{
3699 struct fe_priv *np = netdev_priv(dev);
3700 u8 __iomem *base = get_hwbase(dev);
3701 int result;
3702 memset(buffer, 0, nv_self_test_count(dev)*sizeof(u64));
3703
3704 if (!nv_link_test(dev)) {
3705 test->flags |= ETH_TEST_FL_FAILED;
3706 buffer[0] = 1;
3707 }
3708
3709 if (test->flags & ETH_TEST_FL_OFFLINE) {
3710 if (netif_running(dev)) {
3711 netif_stop_queue(dev);
3712 spin_lock_bh(&dev->xmit_lock);
3713 spin_lock_irq(&np->lock);
3714 nv_disable_hw_interrupts(dev, np->irqmask);
3715 if (!(np->msi_flags & NV_MSI_X_ENABLED)) {
3716 writel(NVREG_IRQSTAT_MASK, base + NvRegIrqStatus);
3717 } else {
3718 writel(NVREG_IRQSTAT_MASK, base + NvRegMSIXIrqStatus);
3719 }
3720 /* stop engines */
3721 nv_stop_rx(dev);
3722 nv_stop_tx(dev);
3723 nv_txrx_reset(dev);
3724 /* drain rx queue */
3725 nv_drain_rx(dev);
3726 nv_drain_tx(dev);
3727 spin_unlock_irq(&np->lock);
3728 spin_unlock_bh(&dev->xmit_lock);
3729 }
3730
3731 if (!nv_register_test(dev)) {
3732 test->flags |= ETH_TEST_FL_FAILED;
3733 buffer[1] = 1;
3734 }
3735
3736 result = nv_interrupt_test(dev);
3737 if (result != 1) {
3738 test->flags |= ETH_TEST_FL_FAILED;
3739 buffer[2] = 1;
3740 }
3741 if (result == 0) {
3742 /* bail out */
3743 return;
3744 }
3745
3746 if (!nv_loopback_test(dev)) {
3747 test->flags |= ETH_TEST_FL_FAILED;
3748 buffer[3] = 1;
3749 }
3750
3751 if (netif_running(dev)) {
3752 /* reinit driver view of the rx queue */
3753 set_bufsize(dev);
3754 if (nv_init_ring(dev)) {
3755 if (!np->in_shutdown)
3756 mod_timer(&np->oom_kick, jiffies + OOM_REFILL);
3757 }
3758 /* reinit nic view of the rx queue */
3759 writel(np->rx_buf_sz, base + NvRegOffloadConfig);
3760 setup_hw_rings(dev, NV_SETUP_RX_RING | NV_SETUP_TX_RING);
3761 writel( ((np->rx_ring_size-1) << NVREG_RINGSZ_RXSHIFT) + ((np->tx_ring_size-1) << NVREG_RINGSZ_TXSHIFT),
3762 base + NvRegRingSizes);
3763 pci_push(base);
3764 writel(NVREG_TXRXCTL_KICK|np->txrxctl_bits, get_hwbase(dev) + NvRegTxRxControl);
3765 pci_push(base);
3766 /* restart rx engine */
3767 nv_start_rx(dev);
3768 nv_start_tx(dev);
3769 netif_start_queue(dev);
3770 nv_enable_hw_interrupts(dev, np->irqmask);
3771 }
3772 }
3773}
3774
3390static void nv_get_strings(struct net_device *dev, u32 stringset, u8 *buffer) 3775static void nv_get_strings(struct net_device *dev, u32 stringset, u8 *buffer)
3391{ 3776{
3392 switch (stringset) { 3777 switch (stringset) {
3393 case ETH_SS_STATS: 3778 case ETH_SS_STATS:
3394 memcpy(buffer, &nv_estats_str, nv_get_stats_count(dev)*sizeof(struct nv_ethtool_str)); 3779 memcpy(buffer, &nv_estats_str, nv_get_stats_count(dev)*sizeof(struct nv_ethtool_str));
3395 break; 3780 break;
3781 case ETH_SS_TEST:
3782 memcpy(buffer, &nv_etests_str, nv_self_test_count(dev)*sizeof(struct nv_ethtool_str));
3783 break;
3396 } 3784 }
3397} 3785}
3398 3786
@@ -3422,6 +3810,8 @@ static struct ethtool_ops ops = {
3422 .get_strings = nv_get_strings, 3810 .get_strings = nv_get_strings,
3423 .get_stats_count = nv_get_stats_count, 3811 .get_stats_count = nv_get_stats_count,
3424 .get_ethtool_stats = nv_get_ethtool_stats, 3812 .get_ethtool_stats = nv_get_ethtool_stats,
3813 .self_test_count = nv_self_test_count,
3814 .self_test = nv_self_test,
3425}; 3815};
3426 3816
3427static void nv_vlan_rx_register(struct net_device *dev, struct vlan_group *grp) 3817static void nv_vlan_rx_register(struct net_device *dev, struct vlan_group *grp)
@@ -3554,7 +3944,7 @@ static int nv_open(struct net_device *dev)
3554 writel(NVREG_IRQSTAT_MASK, base + NvRegIrqStatus); 3944 writel(NVREG_IRQSTAT_MASK, base + NvRegIrqStatus);
3555 pci_push(base); 3945 pci_push(base);
3556 3946
3557 if (nv_request_irq(dev)) { 3947 if (nv_request_irq(dev, 0)) {
3558 goto out_drain; 3948 goto out_drain;
3559 } 3949 }
3560 3950
@@ -4049,11 +4439,11 @@ static struct pci_device_id pci_tbl[] = {
4049 }, 4439 },
4050 { /* MCP55 Ethernet Controller */ 4440 { /* MCP55 Ethernet Controller */
4051 PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_14), 4441 PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_14),
4052 .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_VLAN|DEV_HAS_MSI|DEV_HAS_MSI_X|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS, 4442 .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_VLAN|DEV_HAS_MSI|DEV_HAS_MSI_X|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS|DEV_HAS_TEST_EXTENDED,
4053 }, 4443 },
4054 { /* MCP55 Ethernet Controller */ 4444 { /* MCP55 Ethernet Controller */
4055 PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_15), 4445 PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_15),
4056 .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_VLAN|DEV_HAS_MSI|DEV_HAS_MSI_X|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS, 4446 .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_VLAN|DEV_HAS_MSI|DEV_HAS_MSI_X|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS|DEV_HAS_TEST_EXTENDED,
4057 }, 4447 },
4058 {0,}, 4448 {0,},
4059}; 4449};