Newer
Older
dev->stats.rx_bytes += pkt_size;
dev->stats.rx_packets++;
if (net_ratelimit())
netdev_warn(dev, "Memory squeeze, dropping packet\n");
dev->stats.rx_dropped++;
}
received++;
cur_rx = (cur_rx + rx_size + 4 + 3) & ~3;
RTL_W16 (RxBufPtr, (u16) (cur_rx - 16));
rtl8139_isr_ack(tp);
}
if (unlikely(!received || rx_size == 0xfff0))
rtl8139_isr_ack(tp);
netdev_dbg(dev, "Done %s(), current %04x BufAddr %04x, free to %04x, Cmd %02x\n",
__func__, cur_rx,
RTL_R16(RxBufAddr), RTL_R16(RxBufPtr), RTL_R8(ChipCmd));
tp->cur_rx = cur_rx;
/*
* The receive buffer should be mostly empty.
* Tell NAPI to reenable the Rx irq.
*/
if (tp->fifo_copy_timeout)
received = budget;
out:
return received;
}
static void rtl8139_weird_interrupt (struct net_device *dev,
struct rtl8139_private *tp,
netdev_dbg(dev, "Abnormal interrupt, status %08x\n", status);
assert (dev != NULL);
assert (tp != NULL);
assert (ioaddr != NULL);
/* Update the error count. */
dev->stats.rx_missed_errors += RTL_R32 (RxMissed);
RTL_W32 (RxMissed, 0);
if ((status & RxUnderrun) && link_changed &&
(tp->drv_flags & HAS_LNK_CHNG)) {
rtl_check_media(dev, 0);
status &= ~RxUnderrun;
}
if (status & (RxUnderrun | RxErr))
dev->stats.rx_errors++;
dev->stats.rx_length_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);
pci_write_config_word (tp->pci_dev, PCI_STATUS, pci_cmd_status);
netdev_err(dev, "PCI Bus error %04x\n", pci_cmd_status);
static int rtl8139_poll(struct napi_struct *napi, int budget)
struct rtl8139_private *tp = container_of(napi, struct rtl8139_private, napi);
struct net_device *dev = tp->dev;
void __iomem *ioaddr = tp->mmio_addr;
int work_done;
work_done = 0;
if (likely(RTL_R16(IntrStatus) & RxAckBits))
work_done += rtl8139_rx(dev, tp, budget);
if (work_done < budget) {
/*
* Order is important since data can get interrupted
* again when we think we are done.
*/
spin_lock_irqsave(&tp->lock, flags);
RTL_W16_F(IntrMask, rtl8139_intr_mask);
spin_unlock_irqrestore(&tp->lock, flags);
return work_done;
}
/* The interrupt handler does all of the Rx thread work and cleans up
after the Tx thread. */
static irqreturn_t rtl8139_interrupt (int irq, void *dev_instance)
{
struct net_device *dev = (struct net_device *) dev_instance;
struct rtl8139_private *tp = netdev_priv(dev);
void __iomem *ioaddr = tp->mmio_addr;
u16 status, ackstat;
int link_changed = 0; /* avoid bogus "uninit" warning */
int handled = 0;
spin_lock (&tp->lock);
status = RTL_R16 (IntrStatus);
/* shared irq? */
if (unlikely((status & rtl8139_intr_mask) == 0))
goto out;
handled = 1;
/* h/w no longer present (hotplug?) or major error, bail */
if (unlikely(status == 0xFFFF))
goto out;
/* close possible race's with dev_close */
if (unlikely(!netif_running(dev))) {
RTL_W16 (IntrMask, 0);
goto out;
}
/* Acknowledge all of the current interrupt sources ASAP, but
an first get an additional status bit from CSCR. */
if (unlikely(status & RxUnderrun))
link_changed = RTL_R16 (CSCR) & CSCR_LinkChangeBit;
ackstat = status & ~(RxAckBits | TxErr);
if (ackstat)
RTL_W16 (IntrStatus, ackstat);
/* Receive packets are processed by poll routine.
If not running start it now. */
if (status & RxAckBits){
if (napi_schedule_prep(&tp->napi)) {
}
}
/* Check uncommon events with one test. */
if (unlikely(status & (PCIErr | PCSTimeout | RxUnderrun | RxErr)))
rtl8139_weird_interrupt (dev, tp, ioaddr,
status, link_changed);
if (status & (TxOK | TxErr)) {
rtl8139_tx_interrupt (dev, tp, ioaddr);
if (status & TxErr)
RTL_W16 (IntrStatus, TxErr);
}
out:
spin_unlock (&tp->lock);
netdev_dbg(dev, "exiting interrupt, intr_status=%#4.4x\n",
RTL_R16(IntrStatus));
return IRQ_RETVAL(handled);
}
#ifdef CONFIG_NET_POLL_CONTROLLER
/*
* Polling receive - used by netconsole and other diagnostic tools
* to allow network i/o with interrupts disabled.
*/
static void rtl8139_poll_controller(struct net_device *dev)
{
disable_irq(dev->irq);
rtl8139_interrupt(dev->irq, dev);
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
static int rtl8139_set_mac_address(struct net_device *dev, void *p)
{
struct rtl8139_private *tp = netdev_priv(dev);
void __iomem *ioaddr = tp->mmio_addr;
struct sockaddr *addr = p;
if (!is_valid_ether_addr(addr->sa_data))
return -EADDRNOTAVAIL;
memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
spin_lock_irq(&tp->lock);
RTL_W8_F(Cfg9346, Cfg9346_Unlock);
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_W8_F(Cfg9346, Cfg9346_Lock);
spin_unlock_irq(&tp->lock);
return 0;
}
static int rtl8139_close (struct net_device *dev)
{
struct rtl8139_private *tp = netdev_priv(dev);
void __iomem *ioaddr = tp->mmio_addr;
netif_stop_queue(dev);
napi_disable(&tp->napi);
netif_dbg(tp, ifdown, dev, "Shutting down ethercard, status was 0x%04x\n",
RTL_R16(IntrStatus));
spin_lock_irqsave (&tp->lock, flags);
/* Stop the chip's Tx and Rx DMA processes. */
RTL_W8 (ChipCmd, 0);
/* Disable interrupts by clearing the interrupt mask. */
RTL_W16 (IntrMask, 0);
/* Update the error counts. */
dev->stats.rx_missed_errors += RTL_R32 (RxMissed);
RTL_W32 (RxMissed, 0);
spin_unlock_irqrestore (&tp->lock, flags);
free_irq (dev->irq, dev);
rtl8139_tx_clear (tp);
dma_free_coherent(&tp->pci_dev->dev, RX_BUF_TOT_LEN,
tp->rx_ring, tp->rx_ring_dma);
dma_free_coherent(&tp->pci_dev->dev, TX_BUF_TOT_LEN,
tp->tx_bufs, tp->tx_bufs_dma);
tp->rx_ring = NULL;
tp->tx_bufs = NULL;
/* Green! Put the chip in low-power mode. */
RTL_W8 (Cfg9346, Cfg9346_Unlock);
if (rtl_chip_info[tp->chipset].flags & HasHltClk)
RTL_W8 (HltClk, 'H'); /* 'R' would leave the clock running. */
return 0;
}
/* Get the ethtool Wake-on-LAN settings. Assumes that wol points to
kernel memory, *wol has been initialized as {ETHTOOL_GWOL}, and
other threads or interrupts aren't messing with the 8139. */
static void rtl8139_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
{
struct rtl8139_private *tp = netdev_priv(dev);
void __iomem *ioaddr = tp->mmio_addr;
spin_lock_irq(&tp->lock);
if (rtl_chip_info[tp->chipset].flags & HasLWake) {
u8 cfg3 = RTL_R8 (Config3);
u8 cfg5 = RTL_R8 (Config5);
wol->supported = WAKE_PHY | WAKE_MAGIC
| WAKE_UCAST | WAKE_MCAST | WAKE_BCAST;
wol->wolopts = 0;
if (cfg3 & Cfg3_LinkUp)
wol->wolopts |= WAKE_PHY;
if (cfg3 & Cfg3_Magic)
wol->wolopts |= WAKE_MAGIC;
/* (KON)FIXME: See how netdev_set_wol() handles the
following constants. */
if (cfg5 & Cfg5_UWF)
wol->wolopts |= WAKE_UCAST;
if (cfg5 & Cfg5_MWF)
wol->wolopts |= WAKE_MCAST;
if (cfg5 & Cfg5_BWF)
wol->wolopts |= WAKE_BCAST;
}
}
/* Set the ethtool Wake-on-LAN settings. Return 0 or -errno. Assumes
that wol points to kernel memory and other threads or interrupts
aren't messing with the 8139. */
static int rtl8139_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
{
struct rtl8139_private *tp = netdev_priv(dev);
void __iomem *ioaddr = tp->mmio_addr;
support = ((rtl_chip_info[tp->chipset].flags & HasLWake)
? (WAKE_PHY | WAKE_MAGIC
| WAKE_UCAST | WAKE_MCAST | WAKE_BCAST)
: 0);
if (wol->wolopts & ~support)
return -EINVAL;
cfg3 = RTL_R8 (Config3) & ~(Cfg3_LinkUp | Cfg3_Magic);
if (wol->wolopts & WAKE_PHY)
cfg3 |= Cfg3_LinkUp;
if (wol->wolopts & WAKE_MAGIC)
cfg3 |= Cfg3_Magic;
RTL_W8 (Cfg9346, Cfg9346_Unlock);
RTL_W8 (Config3, cfg3);
RTL_W8 (Cfg9346, Cfg9346_Lock);
cfg5 = RTL_R8 (Config5) & ~(Cfg5_UWF | Cfg5_MWF | Cfg5_BWF);
/* (KON)FIXME: These are untested. We may have to set the
CRC0, Wakeup0 and LSBCRC0 registers too, but I have no
documentation. */
if (wol->wolopts & WAKE_UCAST)
cfg5 |= Cfg5_UWF;
if (wol->wolopts & WAKE_MCAST)
cfg5 |= Cfg5_MWF;
if (wol->wolopts & WAKE_BCAST)
cfg5 |= Cfg5_BWF;
RTL_W8 (Config5, cfg5); /* need not unlock via Cfg9346 */
return 0;
}
static void rtl8139_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
{
struct rtl8139_private *tp = netdev_priv(dev);
strcpy(info->driver, DRV_NAME);
strcpy(info->version, DRV_VERSION);
strcpy(info->bus_info, pci_name(tp->pci_dev));
info->regdump_len = tp->regs_len;
}
static int rtl8139_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
{
struct rtl8139_private *tp = netdev_priv(dev);
spin_lock_irq(&tp->lock);
mii_ethtool_gset(&tp->mii, cmd);
spin_unlock_irq(&tp->lock);
return 0;
}
static int rtl8139_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
{
struct rtl8139_private *tp = netdev_priv(dev);
spin_lock_irq(&tp->lock);
rc = mii_ethtool_sset(&tp->mii, cmd);
spin_unlock_irq(&tp->lock);
return rc;
}
static int rtl8139_nway_reset(struct net_device *dev)
{
struct rtl8139_private *tp = netdev_priv(dev);
return mii_nway_restart(&tp->mii);
}
static u32 rtl8139_get_link(struct net_device *dev)
{
struct rtl8139_private *tp = netdev_priv(dev);
return mii_link_ok(&tp->mii);
}
static u32 rtl8139_get_msglevel(struct net_device *dev)
{
struct rtl8139_private *tp = netdev_priv(dev);
return tp->msg_enable;
}
static void rtl8139_set_msglevel(struct net_device *dev, u32 datum)
{
struct rtl8139_private *tp = netdev_priv(dev);
tp->msg_enable = datum;
}
static int rtl8139_get_regs_len(struct net_device *dev)
{
/* TODO: we are too slack to do reg dumping for pio, for now */
if (use_io)
return 0;
tp = netdev_priv(dev);
return tp->regs_len;
}
static void rtl8139_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *regbuf)
{
/* TODO: we are too slack to do reg dumping for pio, for now */
if (use_io)
return;
spin_lock_irq(&tp->lock);
memcpy_fromio(regbuf, tp->mmio_addr, regs->len);
spin_unlock_irq(&tp->lock);
static int rtl8139_get_sset_count(struct net_device *dev, int sset)
switch (sset) {
case ETH_SS_STATS:
return RTL_NUM_STATS;
default:
return -EOPNOTSUPP;
}
}
static void rtl8139_get_ethtool_stats(struct net_device *dev, struct ethtool_stats *stats, u64 *data)
{
struct rtl8139_private *tp = netdev_priv(dev);
data[0] = tp->xstats.early_rx;
data[1] = tp->xstats.tx_buf_mapped;
data[2] = tp->xstats.tx_timeouts;
data[3] = tp->xstats.rx_lost_in_ring;
}
static void rtl8139_get_strings(struct net_device *dev, u32 stringset, u8 *data)
{
memcpy(data, ethtool_stats_keys, sizeof(ethtool_stats_keys));
}
static const struct ethtool_ops rtl8139_ethtool_ops = {
.get_drvinfo = rtl8139_get_drvinfo,
.get_settings = rtl8139_get_settings,
.set_settings = rtl8139_set_settings,
.get_regs_len = rtl8139_get_regs_len,
.get_regs = rtl8139_get_regs,
.nway_reset = rtl8139_nway_reset,
.get_link = rtl8139_get_link,
.get_msglevel = rtl8139_get_msglevel,
.set_msglevel = rtl8139_set_msglevel,
.get_wol = rtl8139_get_wol,
.set_wol = rtl8139_set_wol,
.get_strings = rtl8139_get_strings,
.get_sset_count = rtl8139_get_sset_count,
.get_ethtool_stats = rtl8139_get_ethtool_stats,
};
static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
{
struct rtl8139_private *tp = netdev_priv(dev);
int rc;
if (!netif_running(dev))
return -EINVAL;
spin_lock_irq(&tp->lock);
rc = generic_mii_ioctl(&tp->mii, if_mii(rq), cmd, NULL);
spin_unlock_irq(&tp->lock);
return rc;
}
static struct net_device_stats *rtl8139_get_stats (struct net_device *dev)
{
struct rtl8139_private *tp = netdev_priv(dev);
void __iomem *ioaddr = tp->mmio_addr;
unsigned long flags;
if (netif_running(dev)) {
spin_lock_irqsave (&tp->lock, flags);
dev->stats.rx_missed_errors += RTL_R32 (RxMissed);
RTL_W32 (RxMissed, 0);
spin_unlock_irqrestore (&tp->lock, flags);
}
}
/* Set or clear the multicast filter for this adaptor.
This routine is not state sensitive and need not be SMP locked. */
static void __set_rx_mode (struct net_device *dev)
{
struct rtl8139_private *tp = netdev_priv(dev);
void __iomem *ioaddr = tp->mmio_addr;
netdev_dbg(dev, "rtl8139_set_rx_mode(%04x) done -- Rx config %08x\n",
dev->flags, RTL_R32(RxConfig));
/* Note: do not reorder, GCC is clever about common statements. */
if (dev->flags & IFF_PROMISC) {
rx_mode =
AcceptBroadcast | AcceptMulticast | AcceptMyPhys |
AcceptAllPhys;
mc_filter[1] = mc_filter[0] = 0xffffffff;
} else if ((netdev_mc_count(dev) > multicast_filter_limit) ||
(dev->flags & IFF_ALLMULTI)) {
/* Too many to filter perfectly -- accept all multicasts. */
rx_mode = AcceptBroadcast | AcceptMulticast | AcceptMyPhys;
mc_filter[1] = mc_filter[0] = 0xffffffff;
} else {
rx_mode = AcceptBroadcast | AcceptMyPhys;
mc_filter[1] = mc_filter[0] = 0;
netdev_for_each_mc_addr(ha, dev) {
int bit_nr = ether_crc(ETH_ALEN, ha->addr) >> 26;
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
mc_filter[bit_nr >> 5] |= 1 << (bit_nr & 31);
rx_mode |= AcceptMulticast;
}
}
/* We can safely update without stopping the chip. */
tmp = rtl8139_rx_config | rx_mode;
if (tp->rx_config != tmp) {
RTL_W32_F (RxConfig, tmp);
tp->rx_config = tmp;
}
RTL_W32_F (MAR0 + 0, mc_filter[0]);
RTL_W32_F (MAR0 + 4, mc_filter[1]);
}
static void rtl8139_set_rx_mode (struct net_device *dev)
{
unsigned long flags;
struct rtl8139_private *tp = netdev_priv(dev);
spin_lock_irqsave (&tp->lock, flags);
__set_rx_mode(dev);
spin_unlock_irqrestore (&tp->lock, flags);
}
#ifdef CONFIG_PM
static int rtl8139_suspend (struct pci_dev *pdev, pm_message_t state)
{
struct net_device *dev = pci_get_drvdata (pdev);
struct rtl8139_private *tp = netdev_priv(dev);
void __iomem *ioaddr = tp->mmio_addr;
unsigned long flags;
pci_save_state (pdev);
if (!netif_running (dev))
return 0;
netif_device_detach (dev);
spin_lock_irqsave (&tp->lock, flags);
/* Disable interrupts, stop Tx and Rx. */
RTL_W16 (IntrMask, 0);
RTL_W8 (ChipCmd, 0);
/* Update the error counts. */
dev->stats.rx_missed_errors += RTL_R32 (RxMissed);
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
RTL_W32 (RxMissed, 0);
spin_unlock_irqrestore (&tp->lock, flags);
pci_set_power_state (pdev, PCI_D3hot);
return 0;
}
static int rtl8139_resume (struct pci_dev *pdev)
{
struct net_device *dev = pci_get_drvdata (pdev);
pci_restore_state (pdev);
if (!netif_running (dev))
return 0;
pci_set_power_state (pdev, PCI_D0);
rtl8139_init_ring (dev);
rtl8139_hw_start (dev);
netif_device_attach (dev);
return 0;
}
#endif /* CONFIG_PM */
static struct pci_driver rtl8139_pci_driver = {
.name = DRV_NAME,
.id_table = rtl8139_pci_tbl,
.probe = rtl8139_init_one,
.remove = __devexit_p(rtl8139_remove_one),
#ifdef CONFIG_PM
.suspend = rtl8139_suspend,
.resume = rtl8139_resume,
#endif /* CONFIG_PM */
};
static int __init rtl8139_init_module (void)
{
/* when we're a module, we always print a version message,
* even if no 8139 board is found.
*/
#ifdef MODULE
pr_info(RTL8139_DRIVER_NAME "\n");
return pci_register_driver(&rtl8139_pci_driver);