#else
#define DRIVERNAPI
#endif
-#define FORCEDETH_VERSION "0.60"
+#define FORCEDETH_VERSION "0.61"
#define DRV_NAME "forcedeth"
#include <linux/module.h>
/* General data:
* Locking: spin_lock(&np->lock); */
- struct net_device_stats stats;
struct nv_ethtool_stats estats;
int in_shutdown;
u32 linkspeed;
if (np->msi_flags & NV_MSI_X_ENABLED)
enable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_ALL].vector);
else
- enable_irq(dev->irq);
+ enable_irq(np->pci_dev->irq);
} else {
enable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_RX].vector);
enable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_TX].vector);
if (np->msi_flags & NV_MSI_X_ENABLED)
disable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_ALL].vector);
else
- disable_irq(dev->irq);
+ disable_irq(np->pci_dev->irq);
} else {
disable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_RX].vector);
disable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_TX].vector);
nv_get_hw_stats(dev);
/* copy to net_device stats */
- np->stats.tx_bytes = np->estats.tx_bytes;
- np->stats.tx_fifo_errors = np->estats.tx_fifo_errors;
- np->stats.tx_carrier_errors = np->estats.tx_carrier_errors;
- np->stats.rx_crc_errors = np->estats.rx_crc_errors;
- np->stats.rx_over_errors = np->estats.rx_over_errors;
- np->stats.rx_errors = np->estats.rx_errors_total;
- np->stats.tx_errors = np->estats.tx_errors_total;
- }
- return &np->stats;
+ dev->stats.tx_bytes = np->estats.tx_bytes;
+ dev->stats.tx_fifo_errors = np->estats.tx_fifo_errors;
+ dev->stats.tx_carrier_errors = np->estats.tx_carrier_errors;
+ dev->stats.rx_crc_errors = np->estats.rx_crc_errors;
+ dev->stats.rx_over_errors = np->estats.rx_over_errors;
+ dev->stats.rx_errors = np->estats.rx_errors_total;
+ dev->stats.tx_errors = np->estats.tx_errors_total;
+ }
+
+ return &dev->stats;
}
/*
if (np->msi_flags & NV_MSI_X_ENABLED)
disable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_ALL].vector);
else
- disable_irq(dev->irq);
+ disable_irq(np->pci_dev->irq);
} else {
disable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_RX].vector);
}
if (np->msi_flags & NV_MSI_X_ENABLED)
enable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_ALL].vector);
else
- enable_irq(dev->irq);
+ enable_irq(np->pci_dev->irq);
} else {
enable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_RX].vector);
}
np->tx_ring.ex[i].buflow = 0;
}
if (nv_release_txskb(dev, &np->tx_skb[i]))
- np->stats.tx_dropped++;
+ dev->stats.tx_dropped++;
}
}
if (flags & NV_TX_LASTPACKET) {
if (flags & NV_TX_ERROR) {
if (flags & NV_TX_UNDERFLOW)
- np->stats.tx_fifo_errors++;
+ dev->stats.tx_fifo_errors++;
if (flags & NV_TX_CARRIERLOST)
- np->stats.tx_carrier_errors++;
- np->stats.tx_errors++;
+ dev->stats.tx_carrier_errors++;
+ dev->stats.tx_errors++;
} else {
- np->stats.tx_packets++;
- np->stats.tx_bytes += np->get_tx_ctx->skb->len;
+ dev->stats.tx_packets++;
+ dev->stats.tx_bytes += np->get_tx_ctx->skb->len;
}
dev_kfree_skb_any(np->get_tx_ctx->skb);
np->get_tx_ctx->skb = NULL;
if (flags & NV_TX2_LASTPACKET) {
if (flags & NV_TX2_ERROR) {
if (flags & NV_TX2_UNDERFLOW)
- np->stats.tx_fifo_errors++;
+ dev->stats.tx_fifo_errors++;
if (flags & NV_TX2_CARRIERLOST)
- np->stats.tx_carrier_errors++;
- np->stats.tx_errors++;
+ dev->stats.tx_carrier_errors++;
+ dev->stats.tx_errors++;
} else {
- np->stats.tx_packets++;
- np->stats.tx_bytes += np->get_tx_ctx->skb->len;
+ dev->stats.tx_packets++;
+ dev->stats.tx_bytes += np->get_tx_ctx->skb->len;
}
dev_kfree_skb_any(np->get_tx_ctx->skb);
np->get_tx_ctx->skb = NULL;
if (flags & NV_TX2_LASTPACKET) {
if (!(flags & NV_TX2_ERROR))
- np->stats.tx_packets++;
+ dev->stats.tx_packets++;
dev_kfree_skb_any(np->get_tx_ctx->skb);
np->get_tx_ctx->skb = NULL;
}
if (flags & NV_RX_ERROR4) {
len = nv_getlen(dev, skb->data, len);
if (len < 0) {
- np->stats.rx_errors++;
+ dev->stats.rx_errors++;
dev_kfree_skb(skb);
goto next_pkt;
}
/* the rest are hard errors */
else {
if (flags & NV_RX_MISSEDFRAME)
- np->stats.rx_missed_errors++;
+ dev->stats.rx_missed_errors++;
if (flags & NV_RX_CRCERR)
- np->stats.rx_crc_errors++;
+ dev->stats.rx_crc_errors++;
if (flags & NV_RX_OVERFLOW)
- np->stats.rx_over_errors++;
- np->stats.rx_errors++;
+ dev->stats.rx_over_errors++;
+ dev->stats.rx_errors++;
dev_kfree_skb(skb);
goto next_pkt;
}
if (flags & NV_RX2_ERROR4) {
len = nv_getlen(dev, skb->data, len);
if (len < 0) {
- np->stats.rx_errors++;
+ dev->stats.rx_errors++;
dev_kfree_skb(skb);
goto next_pkt;
}
/* the rest are hard errors */
else {
if (flags & NV_RX2_CRCERR)
- np->stats.rx_crc_errors++;
+ dev->stats.rx_crc_errors++;
if (flags & NV_RX2_OVERFLOW)
- np->stats.rx_over_errors++;
- np->stats.rx_errors++;
+ dev->stats.rx_over_errors++;
+ dev->stats.rx_errors++;
dev_kfree_skb(skb);
goto next_pkt;
}
netif_rx(skb);
#endif
dev->last_rx = jiffies;
- np->stats.rx_packets++;
- np->stats.rx_bytes += len;
+ dev->stats.rx_packets++;
+ dev->stats.rx_bytes += len;
next_pkt:
if (unlikely(np->get_rx.orig++ == np->last_rx.orig))
np->get_rx.orig = np->first_rx.orig;
struct fe_priv *np = netdev_priv(dev);
u32 flags;
u32 vlanflags = 0;
- u32 rx_processed_cnt = 0;
+ int rx_work = 0;
struct sk_buff *skb;
int len;
while((np->get_rx.ex != np->put_rx.ex) &&
!((flags = le32_to_cpu(np->get_rx.ex->flaglen)) & NV_RX2_AVAIL) &&
- (rx_processed_cnt++ < limit)) {
+ (rx_work < limit)) {
dprintk(KERN_DEBUG "%s: nv_rx_process_optimized: flags 0x%x.\n",
dev->name, flags);
}
dev->last_rx = jiffies;
- np->stats.rx_packets++;
- np->stats.rx_bytes += len;
+ dev->stats.rx_packets++;
+ dev->stats.rx_bytes += len;
} else {
dev_kfree_skb(skb);
}
np->get_rx.ex = np->first_rx.ex;
if (unlikely(np->get_rx_ctx++ == np->last_rx_ctx))
np->get_rx_ctx = np->first_rx_ctx;
+
+ rx_work++;
}
- return rx_processed_cnt;
+ return rx_work;
}
static void set_bufsize(struct net_device *dev)
if (ret != 0 && np->msi_flags & NV_MSI_CAPABLE) {
if ((ret = pci_enable_msi(np->pci_dev)) == 0) {
np->msi_flags |= NV_MSI_ENABLED;
+ dev->irq = np->pci_dev->irq;
if (request_irq(np->pci_dev->irq, handler, IRQF_SHARED, dev->name, dev) != 0) {
printk(KERN_INFO "forcedeth: request_irq failed %d\n", ret);
pci_disable_msi(np->pci_dev);
np->msi_flags &= ~NV_MSI_ENABLED;
+ dev->irq = np->pci_dev->irq;
goto out_err;
}
if (np->msi_flags & NV_MSI_X_ENABLED)
disable_irq_lockdep(np->msi_x_entry[NV_MSI_X_VECTOR_ALL].vector);
else
- disable_irq_lockdep(dev->irq);
+ disable_irq_lockdep(np->pci_dev->irq);
mask = np->irqmask;
} else {
if (np->nic_poll_irq & NVREG_IRQ_RX_ALL) {
}
np->nic_poll_irq = 0;
+ /* disable_irq() contains synchronize_irq, thus no irq handler can run now */
+
if (np->recover_error) {
np->recover_error = 0;
printk(KERN_INFO "forcedeth: MAC in recoverable error state\n");
}
}
- /* FIXME: Do we need synchronize_irq(dev->irq) here? */
writel(mask, base + NvRegIrqMask);
pci_push(base);
if (np->msi_flags & NV_MSI_X_ENABLED)
enable_irq_lockdep(np->msi_x_entry[NV_MSI_X_VECTOR_ALL].vector);
else
- enable_irq_lockdep(dev->irq);
+ enable_irq_lockdep(np->pci_dev->irq);
} else {
if (np->nic_poll_irq & NVREG_IRQ_RX_ALL) {
nv_nic_irq_rx(0, dev);
static void nv_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
{
struct fe_priv *np = netdev_priv(dev);
- strcpy(info->driver, "forcedeth");
+ strcpy(info->driver, DRV_NAME);
strcpy(info->version, FORCEDETH_VERSION);
strcpy(info->bus_info, pci_name(np->pci_dev));
}
#ifdef CONFIG_FORCEDETH_NAPI
napi_disable(&np->napi);
#endif
- synchronize_irq(dev->irq);
+ synchronize_irq(np->pci_dev->irq);
del_timer_sync(&np->oom_kick);
del_timer_sync(&np->nic_poll);
u32 phystate_orig = 0, phystate;
int phyinitialized = 0;
DECLARE_MAC_BUF(mac);
+ static int printed_version;
+
+ if (!printed_version++)
+ printk(KERN_INFO "%s: Reverse Engineered nForce ethernet"
+ " driver. Version %s.\n", DRV_NAME, FORCEDETH_VERSION);
dev = alloc_etherdev(sizeof(struct fe_priv));
err = -ENOMEM;
np->stats_poll.function = &nv_do_stats_poll; /* timer handler */
err = pci_enable_device(pci_dev);
- if (err) {
- printk(KERN_INFO "forcedeth: pci_enable_dev failed (%d) for device %s\n",
- err, pci_name(pci_dev));
+ if (err)
goto out_free;
- }
pci_set_master(pci_dev);
}
}
if (i == DEVICE_COUNT_RESOURCE) {
- printk(KERN_INFO "forcedeth: Couldn't find register window for device %s.\n",
- pci_name(pci_dev));
+ dev_printk(KERN_INFO, &pci_dev->dev,
+ "Couldn't find register window\n");
goto out_relreg;
}
np->desc_ver = DESC_VER_3;
np->txrxctl_bits = NVREG_TXRXCTL_DESC_3;
if (dma_64bit) {
- if (pci_set_dma_mask(pci_dev, DMA_39BIT_MASK)) {
- printk(KERN_INFO "forcedeth: 64-bit DMA failed, using 32-bit addressing for device %s.\n",
- pci_name(pci_dev));
- } else {
+ if (pci_set_dma_mask(pci_dev, DMA_39BIT_MASK))
+ dev_printk(KERN_INFO, &pci_dev->dev,
+ "64-bit DMA failed, using 32-bit addressing\n");
+ else
dev->features |= NETIF_F_HIGHDMA;
- printk(KERN_INFO "forcedeth: using HIGHDMA\n");
- }
if (pci_set_consistent_dma_mask(pci_dev, DMA_39BIT_MASK)) {
- printk(KERN_INFO "forcedeth: 64-bit DMA (consistent) failed, using 32-bit ring buffers for device %s.\n",
- pci_name(pci_dev));
+ dev_printk(KERN_INFO, &pci_dev->dev,
+ "64-bit DMA (consistent) failed, using 32-bit ring buffers\n");
}
}
} else if (id->driver_data & DEV_HAS_LARGEDESC) {
dev->dev_addr[3] = (np->orig_mac[0] >> 16) & 0xff;
dev->dev_addr[4] = (np->orig_mac[0] >> 8) & 0xff;
dev->dev_addr[5] = (np->orig_mac[0] >> 0) & 0xff;
- /* set permanent address to be correct aswell */
- np->orig_mac[0] = (dev->dev_addr[0] << 0) + (dev->dev_addr[1] << 8) +
- (dev->dev_addr[2] << 16) + (dev->dev_addr[3] << 24);
- np->orig_mac[1] = (dev->dev_addr[4] << 0) + (dev->dev_addr[5] << 8);
writel(txreg|NVREG_TRANSMITPOLL_MAC_ADDR_REV, base + NvRegTransmitPoll);
}
memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
* Bad mac address. At least one bios sets the mac address
* to 01:23:45:67:89:ab
*/
- printk(KERN_ERR "%s: Invalid Mac address detected: %s\n",
- pci_name(pci_dev), print_mac(mac, dev->dev_addr));
- printk(KERN_ERR "Please complain to your hardware vendor. Switching to a random MAC.\n");
+ dev_printk(KERN_ERR, &pci_dev->dev,
+ "Invalid Mac address detected: %s\n",
+ print_mac(mac, dev->dev_addr));
+ dev_printk(KERN_ERR, &pci_dev->dev,
+ "Please complain to your hardware vendor. Switching to a random MAC.\n");
dev->dev_addr[0] = 0x00;
dev->dev_addr[1] = 0x00;
dev->dev_addr[2] = 0x6c;
if (readl(base + NvRegTransmitterControl) & NVREG_XMITCTL_SYNC_PHY_INIT) {
np->mac_in_use = readl(base + NvRegTransmitterControl) & NVREG_XMITCTL_MGMT_ST;
dprintk(KERN_INFO "%s: mgmt unit is running. mac in use %x.\n", pci_name(pci_dev), np->mac_in_use);
- for (i = 0; i < 5000; i++) {
- msleep(1);
- if (nv_mgmt_acquire_sema(dev)) {
- /* management unit setup the phy already? */
- if ((readl(base + NvRegTransmitterControl) & NVREG_XMITCTL_SYNC_MASK) ==
- NVREG_XMITCTL_SYNC_PHY_INIT) {
- /* phy is inited by mgmt unit */
- phyinitialized = 1;
- dprintk(KERN_INFO "%s: Phy already initialized by mgmt unit.\n", pci_name(pci_dev));
- } else {
- /* we need to init the phy */
- }
- break;
+ if (nv_mgmt_acquire_sema(dev)) {
+ /* management unit setup the phy already? */
+ if ((readl(base + NvRegTransmitterControl) & NVREG_XMITCTL_SYNC_MASK) ==
+ NVREG_XMITCTL_SYNC_PHY_INIT) {
+ /* phy is inited by mgmt unit */
+ phyinitialized = 1;
+ dprintk(KERN_INFO "%s: Phy already initialized by mgmt unit.\n", pci_name(pci_dev));
+ } else {
+ /* we need to init the phy */
}
}
}
break;
}
if (i == 33) {
- printk(KERN_INFO "%s: open: Could not find a valid PHY.\n",
- pci_name(pci_dev));
+ dev_printk(KERN_INFO, &pci_dev->dev,
+ "open: Could not find a valid PHY.\n");
goto out_error;
}
err = register_netdev(dev);
if (err) {
- printk(KERN_INFO "forcedeth: unable to register netdev: %d\n", err);
+ dev_printk(KERN_INFO, &pci_dev->dev,
+ "unable to register netdev: %d\n", err);
goto out_error;
}
- printk(KERN_INFO "%s: forcedeth.c: subsystem: %05x:%04x bound to %s\n",
- dev->name, pci_dev->subsystem_vendor, pci_dev->subsystem_device,
- pci_name(pci_dev));
+
+ dev_printk(KERN_INFO, &pci_dev->dev, "ifname %s, PHY OUI 0x%x @ %d, "
+ "addr %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x\n",
+ dev->name,
+ np->phy_oui,
+ np->phyaddr,
+ dev->dev_addr[0],
+ dev->dev_addr[1],
+ dev->dev_addr[2],
+ dev->dev_addr[3],
+ dev->dev_addr[4],
+ dev->dev_addr[5]);
+
+ dev_printk(KERN_INFO, &pci_dev->dev, "%s%s%s%s%s%s%s%s%s%sdesc-v%u\n",
+ dev->features & NETIF_F_HIGHDMA ? "highdma " : "",
+ dev->features & (NETIF_F_HW_CSUM | NETIF_F_SG) ?
+ "csum " : "",
+ dev->features & (NETIF_F_HW_VLAN_RX | NETIF_F_HW_VLAN_TX) ?
+ "vlan " : "",
+ id->driver_data & DEV_HAS_POWER_CNTRL ? "pwrctl " : "",
+ id->driver_data & DEV_HAS_MGMT_UNIT ? "mgmt " : "",
+ id->driver_data & DEV_NEED_TIMERIRQ ? "timirq " : "",
+ np->gigabit == PHY_GIGABIT ? "gbit " : "",
+ np->need_linktimer ? "lnktim " : "",
+ np->msi_flags & NV_MSI_CAPABLE ? "msi " : "",
+ np->msi_flags & NV_MSI_X_CAPABLE ? "msi-x " : "",
+ np->desc_ver);
return 0;
*/
writel(np->orig_mac[0], base + NvRegMacAddrA);
writel(np->orig_mac[1], base + NvRegMacAddrB);
+ writel(readl(base + NvRegTransmitPoll) & ~NVREG_TRANSMITPOLL_MAC_ADDR_REV,
+ base + NvRegTransmitPoll);
/* free all structures */
free_rings(dev);
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_31),
.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
},
+ { /* MCP77 Ethernet Controller */
+ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_32),
+ .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
+ },
+ { /* MCP77 Ethernet Controller */
+ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_33),
+ .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
+ },
+ { /* MCP77 Ethernet Controller */
+ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_34),
+ .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
+ },
+ { /* MCP77 Ethernet Controller */
+ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_35),
+ .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
+ },
+ { /* MCP79 Ethernet Controller */
+ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_36),
+ .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
+ },
+ { /* MCP79 Ethernet Controller */
+ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_37),
+ .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
+ },
+ { /* MCP79 Ethernet Controller */
+ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_38),
+ .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
+ },
+ { /* MCP79 Ethernet Controller */
+ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_39),
+ .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
+ },
{0,},
};
static struct pci_driver driver = {
- .name = "forcedeth",
- .id_table = pci_tbl,
- .probe = nv_probe,
- .remove = __devexit_p(nv_remove),
- .suspend = nv_suspend,
- .resume = nv_resume,
+ .name = DRV_NAME,
+ .id_table = pci_tbl,
+ .probe = nv_probe,
+ .remove = __devexit_p(nv_remove),
+ .suspend = nv_suspend,
+ .resume = nv_resume,
};
static int __init init_nic(void)
{
- printk(KERN_INFO "forcedeth.c: Reverse Engineered nForce ethernet driver. Version %s.\n", FORCEDETH_VERSION);
return pci_register_driver(&driver);
}