#include <linux/compiler.h>
#include <linux/pci.h>
#include <linux/init.h>
-#include <linux/ioport.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/rtnetlink.h>
#include <linux/mii.h>
#include <linux/completion.h>
#include <linux/crc32.h>
-#include <asm/io.h>
-#include <asm/uaccess.h>
+#include <linux/io.h>
+#include <linux/uaccess.h>
#include <asm/irq.h>
#define RTL8139_DRIVER_NAME DRV_NAME " Fast Ethernet driver " DRV_VERSION
NETIF_MSG_LINK)
-/* enable PIO instead of MMIO, if CONFIG_8139TOO_PIO is selected */
-#ifdef CONFIG_8139TOO_PIO
-#define USE_IO_OPS 1
-#endif
-
/* define to 1, 2 or 3 to enable copious debugging info */
#define RTL8139_DEBUG 0
#if RTL8139_DEBUG
/* note: prints function name for you */
-# define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt, __FUNCTION__ , ## args)
+# define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt, __func__ , ## args)
#else
# define DPRINTK(fmt, args...)
#endif
# define assert(expr) \
if(unlikely(!(expr))) { \
printk(KERN_ERR "Assertion failed! %s,%s,%s,line=%d\n", \
- #expr,__FILE__,__FUNCTION__,__LINE__); \
+ #expr, __FILE__, __func__, __LINE__); \
}
#endif
static int media[MAX_UNITS] = {-1, -1, -1, -1, -1, -1, -1, -1};
static int full_duplex[MAX_UNITS] = {-1, -1, -1, -1, -1, -1, -1, -1};
+/* Whether to use MMIO or PIO. Default to MMIO. */
+#ifdef CONFIG_8139TOO_PIO
+static int use_io = 1;
+#else
+static int use_io = 0;
+#endif
+
/* Maximum number of multicast addresses to filter (vs. Rx-all-multicast).
The RTL chips use a 64 element hash table based on the Ethernet CRC. */
static int multicast_filter_limit = 32;
#define RTL8139B_IO_SIZE 256
#define RTL8129_CAPS HAS_MII_XCVR
-#define RTL8139_CAPS HAS_CHIP_XCVR|HAS_LNK_CHNG
+#define RTL8139_CAPS (HAS_CHIP_XCVR|HAS_LNK_CHNG)
typedef enum {
RTL8139 = 0,
u32 msg_enable;
struct napi_struct napi;
struct net_device *dev;
- struct net_device_stats stats;
unsigned char *rx_ring;
unsigned int cur_rx; /* RX buf index of next pkt */
MODULE_LICENSE("GPL");
MODULE_VERSION(DRV_VERSION);
+module_param(use_io, int, 0);
+MODULE_PARM_DESC(use_io, "Force use of I/O access mode. 0=MMIO 1=PIO");
module_param(multicast_filter_limit, int, 0);
module_param_array(media, int, NULL, 0);
module_param_array(full_duplex, int, NULL, 0);
assert (tp->pci_dev != NULL);
pdev = tp->pci_dev;
-#ifdef USE_IO_OPS
- if (tp->mmio_addr)
- ioport_unmap (tp->mmio_addr);
-#else
if (tp->mmio_addr)
pci_iounmap (pdev, tp->mmio_addr);
-#endif /* USE_IO_OPS */
/* it's ok to call this even if we have no regions to free */
pci_release_regions (pdev);
DPRINTK("PIO region size == 0x%02X\n", pio_len);
DPRINTK("MMIO region size == 0x%02lX\n", mmio_len);
-#ifdef USE_IO_OPS
- /* make sure PCI base addr 0 is PIO */
- if (!(pio_flags & IORESOURCE_IO)) {
- dev_err(&pdev->dev, "region #0 not a PIO resource, aborting\n");
- rc = -ENODEV;
- goto err_out;
- }
- /* check for weird/broken PCI region reporting */
- if (pio_len < RTL_MIN_IO_SIZE) {
- dev_err(&pdev->dev, "Invalid PCI I/O region size(s), aborting\n");
- rc = -ENODEV;
- goto err_out;
- }
-#else
- /* make sure PCI base addr 1 is MMIO */
- if (!(mmio_flags & IORESOURCE_MEM)) {
- dev_err(&pdev->dev, "region #1 not an MMIO resource, aborting\n");
- rc = -ENODEV;
- goto err_out;
- }
- if (mmio_len < RTL_MIN_IO_SIZE) {
- dev_err(&pdev->dev, "Invalid PCI mem region size(s), aborting\n");
- rc = -ENODEV;
- goto err_out;
+ if (use_io) {
+ /* make sure PCI base addr 0 is PIO */
+ if (!(pio_flags & IORESOURCE_IO)) {
+ dev_err(&pdev->dev, "region #0 not a PIO resource, aborting\n");
+ rc = -ENODEV;
+ goto err_out;
+ }
+ /* check for weird/broken PCI region reporting */
+ if (pio_len < RTL_MIN_IO_SIZE) {
+ dev_err(&pdev->dev, "Invalid PCI I/O region size(s), aborting\n");
+ rc = -ENODEV;
+ goto err_out;
+ }
+ } else {
+ /* make sure PCI base addr 1 is MMIO */
+ if (!(mmio_flags & IORESOURCE_MEM)) {
+ dev_err(&pdev->dev, "region #1 not an MMIO resource, aborting\n");
+ rc = -ENODEV;
+ goto err_out;
+ }
+ if (mmio_len < RTL_MIN_IO_SIZE) {
+ dev_err(&pdev->dev, "Invalid PCI mem region size(s), aborting\n");
+ rc = -ENODEV;
+ goto err_out;
+ }
}
-#endif
rc = pci_request_regions (pdev, DRV_NAME);
if (rc)
/* enable PCI bus-mastering */
pci_set_master (pdev);
-#ifdef USE_IO_OPS
- ioaddr = ioport_map(pio_start, pio_len);
- if (!ioaddr) {
- dev_err(&pdev->dev, "cannot map PIO, aborting\n");
- rc = -EIO;
- goto err_out;
- }
- dev->base_addr = pio_start;
- tp->mmio_addr = ioaddr;
- tp->regs_len = pio_len;
-#else
- /* ioremap MMIO region */
- ioaddr = pci_iomap(pdev, 1, 0);
- if (ioaddr == NULL) {
- dev_err(&pdev->dev, "cannot remap MMIO, aborting\n");
- rc = -EIO;
- goto err_out;
+ if (use_io) {
+ ioaddr = pci_iomap(pdev, 0, 0);
+ if (!ioaddr) {
+ dev_err(&pdev->dev, "cannot map PIO, aborting\n");
+ rc = -EIO;
+ goto err_out;
+ }
+ dev->base_addr = pio_start;
+ tp->regs_len = pio_len;
+ } else {
+ /* ioremap MMIO region */
+ ioaddr = pci_iomap(pdev, 1, 0);
+ if (ioaddr == NULL) {
+ dev_err(&pdev->dev, "cannot remap MMIO, aborting\n");
+ rc = -EIO;
+ goto err_out;
+ }
+ dev->base_addr = (long) ioaddr;
+ tp->regs_len = mmio_len;
}
- dev->base_addr = (long) ioaddr;
tp->mmio_addr = ioaddr;
- tp->regs_len = mmio_len;
-#endif /* USE_IO_OPS */
/* Bring old chips out of low-power mode. */
RTL_W8 (HltClk, 'R');
addr_len = read_eeprom (ioaddr, 0, 8) == 0x8129 ? 8 : 6;
for (i = 0; i < 3; i++)
- ((u16 *) (dev->dev_addr))[i] =
- le16_to_cpu (read_eeprom (ioaddr, i + 7, addr_len));
+ ((__le16 *) (dev->dev_addr))[i] =
+ cpu_to_le16(read_eeprom (ioaddr, i + 7, addr_len));
memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
/* The Rtl8139-specific entries in the device structure. */
/* unlock Config[01234] and BMCR register writes */
RTL_W8_F (Cfg9346, Cfg9346_Unlock);
/* Restore our idea of the MAC address. */
- RTL_W32_F (MAC0 + 0, cpu_to_le32 (*(u32 *) (dev->dev_addr + 0)));
- RTL_W32_F (MAC0 + 4, cpu_to_le32 (*(u32 *) (dev->dev_addr + 4)));
+ RTL_W32_F (MAC0 + 0, le32_to_cpu (*(__le32 *) (dev->dev_addr + 0)));
+ RTL_W32_F (MAC0 + 4, le16_to_cpu (*(__le16 *) (dev->dev_addr + 4)));
/* Must enable Tx/Rx before setting transfer thresholds! */
RTL_W8 (ChipCmd, CmdRxEnb | CmdTxEnb);
dev_kfree_skb(skb);
} else {
dev_kfree_skb(skb);
- tp->stats.tx_dropped++;
+ dev->stats.tx_dropped++;
return 0;
}
if (netif_msg_tx_err(tp))
printk(KERN_DEBUG "%s: Transmit error, Tx status %8.8x.\n",
dev->name, txstatus);
- tp->stats.tx_errors++;
+ dev->stats.tx_errors++;
if (txstatus & TxAborted) {
- tp->stats.tx_aborted_errors++;
+ dev->stats.tx_aborted_errors++;
RTL_W32 (TxConfig, TxClearAbt);
RTL_W16 (IntrStatus, TxErr);
wmb();
}
if (txstatus & TxCarrierLost)
- tp->stats.tx_carrier_errors++;
+ dev->stats.tx_carrier_errors++;
if (txstatus & TxOutOfWindow)
- tp->stats.tx_window_errors++;
+ dev->stats.tx_window_errors++;
} else {
if (txstatus & TxUnderrun) {
/* Add 64 to the Tx FIFO threshold. */
if (tp->tx_flag < 0x00300000)
tp->tx_flag += 0x00020000;
- tp->stats.tx_fifo_errors++;
+ dev->stats.tx_fifo_errors++;
}
- tp->stats.collisions += (txstatus >> 24) & 15;
- tp->stats.tx_bytes += txstatus & 0x7ff;
- tp->stats.tx_packets++;
+ dev->stats.collisions += (txstatus >> 24) & 15;
+ dev->stats.tx_bytes += txstatus & 0x7ff;
+ dev->stats.tx_packets++;
}
dirty_tx++;
if (netif_msg_rx_err (tp))
printk(KERN_DEBUG "%s: Ethernet frame had errors, status %8.8x.\n",
dev->name, rx_status);
- tp->stats.rx_errors++;
+ dev->stats.rx_errors++;
if (!(rx_status & RxStatusOK)) {
if (rx_status & RxTooLong) {
DPRINTK ("%s: Oversized Ethernet frame, status %4.4x!\n",
/* A.C.: The chip hangs here. */
}
if (rx_status & (RxBadSymbol | RxBadAlign))
- tp->stats.rx_frame_errors++;
+ dev->stats.rx_frame_errors++;
if (rx_status & (RxRunt | RxTooLong))
- tp->stats.rx_length_errors++;
+ dev->stats.rx_length_errors++;
if (rx_status & RxCRCErr)
- tp->stats.rx_crc_errors++;
+ dev->stats.rx_crc_errors++;
} else {
tp->xstats.rx_lost_in_ring++;
}
}
#if RX_BUF_IDX == 3
-static __inline__ void wrap_copy(struct sk_buff *skb, const unsigned char *ring,
+static inline void wrap_copy(struct sk_buff *skb, const unsigned char *ring,
u32 offset, unsigned int size)
{
u32 left = RX_BUF_LEN - offset;
/* Clear out errors and receive interrupts */
if (likely(status != 0)) {
if (unlikely(status & (RxFIFOOver | RxOverflow))) {
- tp->stats.rx_errors++;
+ tp->dev->stats.rx_errors++;
if (status & RxFIFOOver)
- tp->stats.rx_fifo_errors++;
+ tp->dev->stats.rx_fifo_errors++;
}
RTL_W16_F (IntrStatus, RxAckBits);
}
rmb();
/* read size+status of next frame from DMA ring buffer */
- rx_status = le32_to_cpu (*(u32 *) (rx_ring + ring_offset));
+ rx_status = le32_to_cpu (*(__le32 *) (rx_ring + ring_offset));
rx_size = rx_status >> 16;
pkt_size = rx_size - 4;
skb->protocol = eth_type_trans (skb, dev);
dev->last_rx = jiffies;
- tp->stats.rx_bytes += pkt_size;
- tp->stats.rx_packets++;
+ dev->stats.rx_bytes += pkt_size;
+ dev->stats.rx_packets++;
netif_receive_skb (skb);
} else {
printk (KERN_WARNING
"%s: Memory squeeze, dropping packet.\n",
dev->name);
- tp->stats.rx_dropped++;
+ dev->stats.rx_dropped++;
}
received++;
assert (ioaddr != NULL);
/* Update the error count. */
- tp->stats.rx_missed_errors += RTL_R32 (RxMissed);
+ dev->stats.rx_missed_errors += RTL_R32 (RxMissed);
RTL_W32 (RxMissed, 0);
if ((status & RxUnderrun) && link_changed &&
}
if (status & (RxUnderrun | RxErr))
- tp->stats.rx_errors++;
+ dev->stats.rx_errors++;
if (status & PCSTimeout)
- tp->stats.rx_length_errors++;
+ dev->stats.rx_length_errors++;
if (status & RxUnderrun)
- tp->stats.rx_fifo_errors++;
+ dev->stats.rx_fifo_errors++;
if (status & PCIErr) {
u16 pci_cmd_status;
pci_read_config_word (tp->pci_dev, PCI_STATUS, &pci_cmd_status);
RTL_W16 (IntrMask, 0);
/* Update the error counts. */
- tp->stats.rx_missed_errors += RTL_R32 (RxMissed);
+ dev->stats.rx_missed_errors += RTL_R32 (RxMissed);
RTL_W32 (RxMissed, 0);
spin_unlock_irqrestore (&tp->lock, flags);
- synchronize_irq (dev->irq); /* racy, but that's ok here */
free_irq (dev->irq, dev);
rtl8139_tx_clear (tp);
np->msg_enable = datum;
}
-/* TODO: we are too slack to do reg dumping for pio, for now */
-#ifdef CONFIG_8139TOO_PIO
-#define rtl8139_get_regs_len NULL
-#define rtl8139_get_regs NULL
-#else
static int rtl8139_get_regs_len(struct net_device *dev)
{
- struct rtl8139_private *np = netdev_priv(dev);
+ struct rtl8139_private *np;
+ /* TODO: we are too slack to do reg dumping for pio, for now */
+ if (use_io)
+ return 0;
+ np = netdev_priv(dev);
return np->regs_len;
}
static void rtl8139_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *regbuf)
{
- struct rtl8139_private *np = netdev_priv(dev);
+ struct rtl8139_private *np;
+
+ /* TODO: we are too slack to do reg dumping for pio, for now */
+ if (use_io)
+ return;
+ np = netdev_priv(dev);
regs->version = RTL_REGS_VER;
memcpy_fromio(regbuf, np->mmio_addr, regs->len);
spin_unlock_irq(&np->lock);
}
-#endif /* CONFIG_8139TOO_MMIO */
static int rtl8139_get_sset_count(struct net_device *dev, int sset)
{
if (netif_running(dev)) {
spin_lock_irqsave (&tp->lock, flags);
- tp->stats.rx_missed_errors += RTL_R32 (RxMissed);
+ dev->stats.rx_missed_errors += RTL_R32 (RxMissed);
RTL_W32 (RxMissed, 0);
spin_unlock_irqrestore (&tp->lock, flags);
}
- return &tp->stats;
+ return &dev->stats;
}
/* Set or clear the multicast filter for this adaptor.
RTL_W8 (ChipCmd, 0);
/* Update the error counts. */
- tp->stats.rx_missed_errors += RTL_R32 (RxMissed);
+ dev->stats.rx_missed_errors += RTL_R32 (RxMissed);
RTL_W32 (RxMissed, 0);
spin_unlock_irqrestore (&tp->lock, flags);