提交 0e396ee4 编写于 作者: L Linus Torvalds

Manual merge of rsync://rsync.kernel.org/pub/scm/linux/kernel/git/jgarzik/netdev-2.6.git

This is a fixed-up version of the broken "upstream-2.6.13" branch, where
I re-did the manual merge of drivers/net/r8169.c by hand, and made sure
the history is all good.
Generic HDLC layer
Krzysztof Halasa <khc@pm.waw.pl>
January, 2003
Generic HDLC layer currently supports:
- Frame Relay (ANSI, CCITT and no LMI), with ARP support (no InARP).
Normal (routed) and Ethernet-bridged (Ethernet device emulation)
interfaces can share a single PVC.
- raw HDLC - either IP (IPv4) interface or Ethernet device emulation.
- Cisco HDLC,
- PPP (uses syncppp.c),
- X.25 (uses X.25 routines).
There are hardware drivers for the following cards:
- C101 by Moxa Technologies Co., Ltd.
- RISCom/N2 by SDL Communications Inc.
- and others, some not in the official kernel.
1. Frame Relay (ANSI, CCITT, Cisco and no LMI).
- Normal (routed) and Ethernet-bridged (Ethernet device emulation)
interfaces can share a single PVC.
- ARP support (no InARP support in the kernel - there is an
experimental InARP user-space daemon available on:
http://www.kernel.org/pub/linux/utils/net/hdlc/).
2. raw HDLC - either IP (IPv4) interface or Ethernet device emulation.
3. Cisco HDLC.
4. PPP (uses syncppp.c).
5. X.25 (uses X.25 routines).
Generic HDLC is a protocol driver only - it needs a low-level driver
for your particular hardware.
Ethernet device emulation (using HDLC or Frame-Relay PVC) is compatible
with IEEE 802.1Q (VLANs) and 802.1D (Ethernet bridging).
......@@ -24,7 +24,7 @@ with IEEE 802.1Q (VLANs) and 802.1D (Ethernet bridging).
Make sure the hdlc.o and the hardware driver are loaded. It should
create a number of "hdlc" (hdlc0 etc) network devices, one for each
WAN port. You'll need the "sethdlc" utility, get it from:
http://hq.pm.waw.pl/hdlc/
http://www.kernel.org/pub/linux/utils/net/hdlc/
Compile sethdlc.c utility:
gcc -O2 -Wall -o sethdlc sethdlc.c
......@@ -52,12 +52,12 @@ Setting interface:
* v35 | rs232 | x21 | t1 | e1 - sets physical interface for a given port
if the card has software-selectable interfaces
loopback - activate hardware loopback (for testing only)
* clock ext - external clock (uses DTE RX and TX clock)
* clock int - internal clock (provides clock signal on DCE clock output)
* clock txint - TX internal, RX external (provides TX clock on DCE output)
* clock txfromrx - TX clock derived from RX clock (TX clock on DCE output)
* rate - sets clock rate in bps (not required for external clock or
for txfromrx)
* clock ext - both RX clock and TX clock external
* clock int - both RX clock and TX clock internal
* clock txint - RX clock external, TX clock internal
* clock txfromrx - RX clock external, TX clock derived from RX clock
* rate - sets clock rate in bps (for "int" or "txint" clock only)
Setting protocol:
......@@ -79,7 +79,7 @@ Setting protocol:
* x25 - sets X.25 mode
* fr - Frame Relay mode
lmi ansi / ccitt / none - LMI (link management) type
lmi ansi / ccitt / cisco / none - LMI (link management) type
dce - Frame Relay DCE (network) side LMI instead of default DTE (user).
It has nothing to do with clocks!
t391 - link integrity verification polling timer (in seconds) - user
......@@ -119,13 +119,14 @@ or
If you have a problem with N2 or C101 card, you can issue the "private"
command to see port's packet descriptor rings (in kernel logs):
If you have a problem with N2, C101 or PLX200SYN card, you can issue the
"private" command to see port's packet descriptor rings (in kernel logs):
sethdlc hdlc0 private
The hardware driver has to be build with CONFIG_HDLC_DEBUG_RINGS.
The hardware driver has to be build with #define DEBUG_RINGS.
Attaching this info to bug reports would be helpful. Anyway, let me know
if you have problems using this.
For patches and other info look at http://hq.pm.waw.pl/hdlc/
For patches and other info look at:
<http://www.kernel.org/pub/linux/utils/net/hdlc/>.
......@@ -47,7 +47,6 @@ ni52 <------------------ Buggy ------------------>
ni65 YES YES YES Software(#)
seeq NO NO NO N/A
sgiseek <------------------ Buggy ------------------>
sk_g16 NO NO YES N/A
smc-ultra YES YES YES Hardware
sunlance YES YES YES Hardware
tulip YES YES YES Hardware
......
......@@ -284,9 +284,6 @@ ppp.c:
seeq8005.c: *Not modularized*
(Probes ports: 0x300, 0x320, 0x340, 0x360)
sk_g16.c: *Not modularized*
(Probes ports: 0x100, 0x180, 0x208, 0x220m 0x288, 0x320, 0x328, 0x390)
skeleton.c: *Skeleton*
slhc.c:
......
......@@ -54,6 +54,7 @@
#include <linux/config.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/kernel.h>
#include <linux/compiler.h>
#include <linux/netdevice.h>
......@@ -91,16 +92,17 @@ KERN_INFO DRV_NAME ": 10/100 PCI Ethernet driver v" DRV_VERSION " (" DRV_RELDATE
MODULE_AUTHOR("Jeff Garzik <jgarzik@pobox.com>");
MODULE_DESCRIPTION("RealTek RTL-8139C+ series 10/100 PCI Ethernet driver");
MODULE_VERSION(DRV_VERSION);
MODULE_LICENSE("GPL");
static int debug = -1;
MODULE_PARM (debug, "i");
module_param(debug, int, 0);
MODULE_PARM_DESC (debug, "8139cp: bitmapped message enable number");
/* 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;
MODULE_PARM (multicast_filter_limit, "i");
module_param(multicast_filter_limit, int, 0);
MODULE_PARM_DESC (multicast_filter_limit, "8139cp: maximum number of filtered multicast addresses");
#define PFX DRV_NAME ": "
......@@ -186,6 +188,9 @@ enum {
RingEnd = (1 << 30), /* End of descriptor ring */
FirstFrag = (1 << 29), /* First segment of a packet */
LastFrag = (1 << 28), /* Final segment of a packet */
LargeSend = (1 << 27), /* TCP Large Send Offload (TSO) */
MSSShift = 16, /* MSS value position */
MSSMask = 0xfff, /* MSS value: 11 bits */
TxError = (1 << 23), /* Tx error summary */
RxError = (1 << 20), /* Rx error summary */
IPCS = (1 << 18), /* Calculate IP checksum */
......@@ -312,7 +317,7 @@ struct cp_desc {
struct ring_info {
struct sk_buff *skb;
dma_addr_t mapping;
unsigned frag;
u32 len;
};
struct cp_dma_stats {
......@@ -394,6 +399,9 @@ struct cp_private {
static void __cp_set_rx_mode (struct net_device *dev);
static void cp_tx (struct cp_private *cp);
static void cp_clean_rings (struct cp_private *cp);
#ifdef CONFIG_NET_POLL_CONTROLLER
static void cp_poll_controller(struct net_device *dev);
#endif
static struct pci_device_id cp_pci_tbl[] = {
{ PCI_VENDOR_ID_REALTEK, PCI_DEVICE_ID_REALTEK_8139,
......@@ -688,6 +696,19 @@ cp_interrupt (int irq, void *dev_instance, struct pt_regs *regs)
return IRQ_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 cp_poll_controller(struct net_device *dev)
{
disable_irq(dev->irq);
cp_interrupt(dev->irq, dev, NULL);
enable_irq(dev->irq);
}
#endif
static void cp_tx (struct cp_private *cp)
{
unsigned tx_head = cp->tx_head;
......@@ -707,7 +728,7 @@ static void cp_tx (struct cp_private *cp)
BUG();
pci_unmap_single(cp->pdev, cp->tx_skb[tx_tail].mapping,
skb->len, PCI_DMA_TODEVICE);
cp->tx_skb[tx_tail].len, PCI_DMA_TODEVICE);
if (status & LastFrag) {
if (status & (TxError | TxFIFOUnder)) {
......@@ -749,10 +770,11 @@ static int cp_start_xmit (struct sk_buff *skb, struct net_device *dev)
{
struct cp_private *cp = netdev_priv(dev);
unsigned entry;
u32 eor;
u32 eor, flags;
#if CP_VLAN_TAG_USED
u32 vlan_tag = 0;
#endif
int mss = 0;
spin_lock_irq(&cp->lock);
......@@ -772,6 +794,9 @@ static int cp_start_xmit (struct sk_buff *skb, struct net_device *dev)
entry = cp->tx_head;
eor = (entry == (CP_TX_RING_SIZE - 1)) ? RingEnd : 0;
if (dev->features & NETIF_F_TSO)
mss = skb_shinfo(skb)->tso_size;
if (skb_shinfo(skb)->nr_frags == 0) {
struct cp_desc *txd = &cp->tx_ring[entry];
u32 len;
......@@ -783,26 +808,26 @@ static int cp_start_xmit (struct sk_buff *skb, struct net_device *dev)
txd->addr = cpu_to_le64(mapping);
wmb();
if (skb->ip_summed == CHECKSUM_HW) {
flags = eor | len | DescOwn | FirstFrag | LastFrag;
if (mss)
flags |= LargeSend | ((mss & MSSMask) << MSSShift);
else if (skb->ip_summed == CHECKSUM_HW) {
const struct iphdr *ip = skb->nh.iph;
if (ip->protocol == IPPROTO_TCP)
txd->opts1 = cpu_to_le32(eor | len | DescOwn |
FirstFrag | LastFrag |
IPCS | TCPCS);
flags |= IPCS | TCPCS;
else if (ip->protocol == IPPROTO_UDP)
txd->opts1 = cpu_to_le32(eor | len | DescOwn |
FirstFrag | LastFrag |
IPCS | UDPCS);
flags |= IPCS | UDPCS;
else
BUG();
} else
txd->opts1 = cpu_to_le32(eor | len | DescOwn |
FirstFrag | LastFrag);
WARN_ON(1); /* we need a WARN() */
}
txd->opts1 = cpu_to_le32(flags);
wmb();
cp->tx_skb[entry].skb = skb;
cp->tx_skb[entry].mapping = mapping;
cp->tx_skb[entry].frag = 0;
cp->tx_skb[entry].len = len;
entry = NEXT_TX(entry);
} else {
struct cp_desc *txd;
......@@ -820,7 +845,7 @@ static int cp_start_xmit (struct sk_buff *skb, struct net_device *dev)
first_len, PCI_DMA_TODEVICE);
cp->tx_skb[entry].skb = skb;
cp->tx_skb[entry].mapping = first_mapping;
cp->tx_skb[entry].frag = 1;
cp->tx_skb[entry].len = first_len;
entry = NEXT_TX(entry);
for (frag = 0; frag < skb_shinfo(skb)->nr_frags; frag++) {
......@@ -836,16 +861,19 @@ static int cp_start_xmit (struct sk_buff *skb, struct net_device *dev)
len, PCI_DMA_TODEVICE);
eor = (entry == (CP_TX_RING_SIZE - 1)) ? RingEnd : 0;
if (skb->ip_summed == CHECKSUM_HW) {
ctrl = eor | len | DescOwn | IPCS;
ctrl = eor | len | DescOwn;
if (mss)
ctrl |= LargeSend |
((mss & MSSMask) << MSSShift);
else if (skb->ip_summed == CHECKSUM_HW) {
if (ip->protocol == IPPROTO_TCP)
ctrl |= TCPCS;
ctrl |= IPCS | TCPCS;
else if (ip->protocol == IPPROTO_UDP)
ctrl |= UDPCS;
ctrl |= IPCS | UDPCS;
else
BUG();
} else
ctrl = eor | len | DescOwn;
}
if (frag == skb_shinfo(skb)->nr_frags - 1)
ctrl |= LastFrag;
......@@ -860,7 +888,7 @@ static int cp_start_xmit (struct sk_buff *skb, struct net_device *dev)
cp->tx_skb[entry].skb = skb;
cp->tx_skb[entry].mapping = mapping;
cp->tx_skb[entry].frag = frag + 2;
cp->tx_skb[entry].len = len;
entry = NEXT_TX(entry);
}
......@@ -1074,7 +1102,6 @@ static int cp_refill_rx (struct cp_private *cp)
cp->rx_skb[i].mapping = pci_map_single(cp->pdev,
skb->tail, cp->rx_buf_sz, PCI_DMA_FROMDEVICE);
cp->rx_skb[i].skb = skb;
cp->rx_skb[i].frag = 0;
cp->rx_ring[i].opts2 = 0;
cp->rx_ring[i].addr = cpu_to_le64(cp->rx_skb[i].mapping);
......@@ -1126,9 +1153,6 @@ static void cp_clean_rings (struct cp_private *cp)
{
unsigned i;
memset(cp->rx_ring, 0, sizeof(struct cp_desc) * CP_RX_RING_SIZE);
memset(cp->tx_ring, 0, sizeof(struct cp_desc) * CP_TX_RING_SIZE);
for (i = 0; i < CP_RX_RING_SIZE; i++) {
if (cp->rx_skb[i].skb) {
pci_unmap_single(cp->pdev, cp->rx_skb[i].mapping,
......@@ -1140,13 +1164,18 @@ static void cp_clean_rings (struct cp_private *cp)
for (i = 0; i < CP_TX_RING_SIZE; i++) {
if (cp->tx_skb[i].skb) {
struct sk_buff *skb = cp->tx_skb[i].skb;
pci_unmap_single(cp->pdev, cp->tx_skb[i].mapping,
skb->len, PCI_DMA_TODEVICE);
dev_kfree_skb(skb);
cp->tx_skb[i].len, PCI_DMA_TODEVICE);
if (le32_to_cpu(cp->tx_ring[i].opts1) & LastFrag)
dev_kfree_skb(skb);
cp->net_stats.tx_dropped++;
}
}
memset(cp->rx_ring, 0, sizeof(struct cp_desc) * CP_RX_RING_SIZE);
memset(cp->tx_ring, 0, sizeof(struct cp_desc) * CP_TX_RING_SIZE);
memset(&cp->rx_skb, 0, sizeof(struct ring_info) * CP_RX_RING_SIZE);
memset(&cp->tx_skb, 0, sizeof(struct ring_info) * CP_TX_RING_SIZE);
}
......@@ -1538,6 +1567,8 @@ static struct ethtool_ops cp_ethtool_ops = {
.set_tx_csum = ethtool_op_set_tx_csum, /* local! */
.get_sg = ethtool_op_get_sg,
.set_sg = ethtool_op_set_sg,
.get_tso = ethtool_op_get_tso,
.set_tso = ethtool_op_set_tso,
.get_regs = cp_get_regs,
.get_wol = cp_get_wol,
.set_wol = cp_set_wol,
......@@ -1749,6 +1780,9 @@ static int cp_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
dev->get_stats = cp_get_stats;
dev->do_ioctl = cp_ioctl;
dev->poll = cp_rx_poll;
#ifdef CONFIG_NET_POLL_CONTROLLER
dev->poll_controller = cp_poll_controller;
#endif
dev->weight = 16; /* arbitrary? from NAPI_HOWTO.txt. */
#ifdef BROKEN
dev->change_mtu = cp_change_mtu;
......@@ -1768,6 +1802,10 @@ static int cp_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
if (pci_using_dac)
dev->features |= NETIF_F_HIGHDMA;
#if 0 /* disabled by default until verified */
dev->features |= NETIF_F_TSO;
#endif
dev->irq = pdev->irq;
rc = register_netdev(dev);
......
......@@ -569,7 +569,7 @@ struct rtl_extra_stats {
};
struct rtl8139_private {
void *mmio_addr;
void __iomem *mmio_addr;
int drv_flags;
struct pci_dev *pci_dev;
u32 msg_enable;
......@@ -614,7 +614,7 @@ MODULE_PARM_DESC (multicast_filter_limit, "8139too maximum number of filtered mu
MODULE_PARM_DESC (media, "8139too: Bits 4+9: force full duplex, bit 5: 100Mbps");
MODULE_PARM_DESC (full_duplex, "8139too: Force full duplex for board(s) (1)");
static int read_eeprom (void *ioaddr, int location, int addr_len);
static int read_eeprom (void __iomem *ioaddr, int location, int addr_len);
static int rtl8139_open (struct net_device *dev);
static int mdio_read (struct net_device *dev, int phy_id, int location);
static void mdio_write (struct net_device *dev, int phy_id, int location,
......@@ -638,46 +638,20 @@ static void __set_rx_mode (struct net_device *dev);
static void rtl8139_hw_start (struct net_device *dev);
static struct ethtool_ops rtl8139_ethtool_ops;
#ifdef USE_IO_OPS
#define RTL_R8(reg) inb (((unsigned long)ioaddr) + (reg))
#define RTL_R16(reg) inw (((unsigned long)ioaddr) + (reg))
#define RTL_R32(reg) ((unsigned long) inl (((unsigned long)ioaddr) + (reg)))
#define RTL_W8(reg, val8) outb ((val8), ((unsigned long)ioaddr) + (reg))
#define RTL_W16(reg, val16) outw ((val16), ((unsigned long)ioaddr) + (reg))
#define RTL_W32(reg, val32) outl ((val32), ((unsigned long)ioaddr) + (reg))
#define RTL_W8_F RTL_W8
#define RTL_W16_F RTL_W16
#define RTL_W32_F RTL_W32
#undef readb
#undef readw
#undef readl
#undef writeb
#undef writew
#undef writel
#define readb(addr) inb((unsigned long)(addr))
#define readw(addr) inw((unsigned long)(addr))
#define readl(addr) inl((unsigned long)(addr))
#define writeb(val,addr) outb((val),(unsigned long)(addr))
#define writew(val,addr) outw((val),(unsigned long)(addr))
#define writel(val,addr) outl((val),(unsigned long)(addr))
#else
/* write MMIO register, with flush */
/* Flush avoids rtl8139 bug w/ posted MMIO writes */
#define RTL_W8_F(reg, val8) do { writeb ((val8), ioaddr + (reg)); readb (ioaddr + (reg)); } while (0)
#define RTL_W16_F(reg, val16) do { writew ((val16), ioaddr + (reg)); readw (ioaddr + (reg)); } while (0)
#define RTL_W32_F(reg, val32) do { writel ((val32), ioaddr + (reg)); readl (ioaddr + (reg)); } while (0)
#define RTL_W8_F(reg, val8) do { iowrite8 ((val8), ioaddr + (reg)); ioread8 (ioaddr + (reg)); } while (0)
#define RTL_W16_F(reg, val16) do { iowrite16 ((val16), ioaddr + (reg)); ioread16 (ioaddr + (reg)); } while (0)
#define RTL_W32_F(reg, val32) do { iowrite32 ((val32), ioaddr + (reg)); ioread32 (ioaddr + (reg)); } while (0)
#define MMIO_FLUSH_AUDIT_COMPLETE 1
#if MMIO_FLUSH_AUDIT_COMPLETE
/* write MMIO register */
#define RTL_W8(reg, val8) writeb ((val8), ioaddr + (reg))
#define RTL_W16(reg, val16) writew ((val16), ioaddr + (reg))
#define RTL_W32(reg, val32) writel ((val32), ioaddr + (reg))
#define RTL_W8(reg, val8) iowrite8 ((val8), ioaddr + (reg))
#define RTL_W16(reg, val16) iowrite16 ((val16), ioaddr + (reg))
#define RTL_W32(reg, val32) iowrite32 ((val32), ioaddr + (reg))
#else
......@@ -689,11 +663,9 @@ static struct ethtool_ops rtl8139_ethtool_ops;
#endif /* MMIO_FLUSH_AUDIT_COMPLETE */
/* read MMIO register */
#define RTL_R8(reg) readb (ioaddr + (reg))
#define RTL_R16(reg) readw (ioaddr + (reg))
#define RTL_R32(reg) ((unsigned long) readl (ioaddr + (reg)))
#endif /* USE_IO_OPS */
#define RTL_R8(reg) ioread8 (ioaddr + (reg))
#define RTL_R16(reg) ioread16 (ioaddr + (reg))
#define RTL_R32(reg) ((unsigned long) ioread32 (ioaddr + (reg)))
static const u16 rtl8139_intr_mask =
......@@ -740,10 +712,13 @@ static void __rtl8139_cleanup_dev (struct net_device *dev)
assert (tp->pci_dev != NULL);
pdev = tp->pci_dev;
#ifndef USE_IO_OPS
#ifdef USE_IO_OPS
if (tp->mmio_addr)
ioport_unmap (tp->mmio_addr);
#else
if (tp->mmio_addr)
iounmap (tp->mmio_addr);
#endif /* !USE_IO_OPS */
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);
......@@ -753,7 +728,7 @@ static void __rtl8139_cleanup_dev (struct net_device *dev)
}
static void rtl8139_chip_reset (void *ioaddr)
static void rtl8139_chip_reset (void __iomem *ioaddr)
{
int i;
......@@ -773,7 +748,7 @@ static void rtl8139_chip_reset (void *ioaddr)
static int __devinit rtl8139_init_board (struct pci_dev *pdev,
struct net_device **dev_out)
{
void *ioaddr;
void __iomem *ioaddr;
struct net_device *dev;
struct rtl8139_private *tp;
u8 tmp8;
......@@ -855,13 +830,18 @@ static int __devinit rtl8139_init_board (struct pci_dev *pdev,
pci_set_master (pdev);
#ifdef USE_IO_OPS
ioaddr = (void *) pio_start;
ioaddr = ioport_map(pio_start, pio_len);
if (!ioaddr) {
printk (KERN_ERR PFX "%s: cannot map PIO, aborting\n", pci_name(pdev));
rc = -EIO;
goto err_out;
}
dev->base_addr = pio_start;
tp->mmio_addr = ioaddr;
tp->regs_len = pio_len;
#else
/* ioremap MMIO region */
ioaddr = ioremap (mmio_start, mmio_len);
ioaddr = pci_iomap(pdev, 1, 0);
if (ioaddr == NULL) {
printk (KERN_ERR PFX "%s: cannot remap MMIO, aborting\n", pci_name(pdev));
rc = -EIO;
......@@ -947,7 +927,7 @@ static int __devinit rtl8139_init_one (struct pci_dev *pdev,
struct net_device *dev = NULL;
struct rtl8139_private *tp;
int i, addr_len, option;
void *ioaddr;
void __iomem *ioaddr;
static int board_idx = -1;
u8 pci_rev;
......@@ -1147,47 +1127,46 @@ static void __devexit rtl8139_remove_one (struct pci_dev *pdev)
No extra delay is needed with 33Mhz PCI, but 66Mhz may change this.
*/
#define eeprom_delay() readl(ee_addr)
#define eeprom_delay() RTL_R32(Cfg9346)
/* The EEPROM commands include the alway-set leading bit. */
#define EE_WRITE_CMD (5)
#define EE_READ_CMD (6)
#define EE_ERASE_CMD (7)
static int __devinit read_eeprom (void *ioaddr, int location, int addr_len)
static int __devinit read_eeprom (void __iomem *ioaddr, int location, int addr_len)
{
int i;
unsigned retval = 0;
void *ee_addr = ioaddr + Cfg9346;
int read_cmd = location | (EE_READ_CMD << addr_len);
writeb (EE_ENB & ~EE_CS, ee_addr);
writeb (EE_ENB, ee_addr);
RTL_W8 (Cfg9346, EE_ENB & ~EE_CS);
RTL_W8 (Cfg9346, EE_ENB);
eeprom_delay ();
/* Shift the read command bits out. */
for (i = 4 + addr_len; i >= 0; i--) {
int dataval = (read_cmd & (1 << i)) ? EE_DATA_WRITE : 0;
writeb (EE_ENB | dataval, ee_addr);
RTL_W8 (Cfg9346, EE_ENB | dataval);
eeprom_delay ();
writeb (EE_ENB | dataval | EE_SHIFT_CLK, ee_addr);
RTL_W8 (Cfg9346, EE_ENB | dataval | EE_SHIFT_CLK);
eeprom_delay ();
}
writeb (EE_ENB, ee_addr);
RTL_W8 (Cfg9346, EE_ENB);
eeprom_delay ();
for (i = 16; i > 0; i--) {
writeb (EE_ENB | EE_SHIFT_CLK, ee_addr);
RTL_W8 (Cfg9346, EE_ENB | EE_SHIFT_CLK);
eeprom_delay ();
retval =
(retval << 1) | ((readb (ee_addr) & EE_DATA_READ) ? 1 :
(retval << 1) | ((RTL_R8 (Cfg9346) & EE_DATA_READ) ? 1 :
0);
writeb (EE_ENB, ee_addr);
RTL_W8 (Cfg9346, EE_ENB);
eeprom_delay ();
}
/* Terminate the EEPROM access. */
writeb (~EE_CS, ee_addr);
RTL_W8 (Cfg9346, ~EE_CS);
eeprom_delay ();
return retval;
......@@ -1206,7 +1185,7 @@ static int __devinit read_eeprom (void *ioaddr, int location, int addr_len)
#define MDIO_WRITE0 (MDIO_DIR)
#define MDIO_WRITE1 (MDIO_DIR | MDIO_DATA_OUT)
#define mdio_delay(mdio_addr) readb(mdio_addr)
#define mdio_delay() RTL_R8(Config4)
static char mii_2_8139_map[8] = {
......@@ -1223,15 +1202,15 @@ static char mii_2_8139_map[8] = {
#ifdef CONFIG_8139TOO_8129
/* Syncronize the MII management interface by shifting 32 one bits out. */
static void mdio_sync (void *mdio_addr)
static void mdio_sync (void __iomem *ioaddr)
{
int i;
for (i = 32; i >= 0; i--) {
writeb (MDIO_WRITE1, mdio_addr);
mdio_delay (mdio_addr);
writeb (MDIO_WRITE1 | MDIO_CLK, mdio_addr);
mdio_delay (mdio_addr);
RTL_W8 (Config4, MDIO_WRITE1);
mdio_delay ();
RTL_W8 (Config4, MDIO_WRITE1 | MDIO_CLK);
mdio_delay ();
}
}
#endif
......@@ -1241,35 +1220,36 @@ static int mdio_read (struct net_device *dev, int phy_id, int location)
struct rtl8139_private *tp = netdev_priv(dev);
int retval = 0;
#ifdef CONFIG_8139TOO_8129
void *mdio_addr = tp->mmio_addr + Config4;
void __iomem *ioaddr = tp->mmio_addr;
int mii_cmd = (0xf6 << 10) | (phy_id << 5) | location;
int i;
#endif
if (phy_id > 31) { /* Really a 8139. Use internal registers. */
void __iomem *ioaddr = tp->mmio_addr;
return location < 8 && mii_2_8139_map[location] ?
readw (tp->mmio_addr + mii_2_8139_map[location]) : 0;
RTL_R16 (mii_2_8139_map[location]) : 0;
}
#ifdef CONFIG_8139TOO_8129
mdio_sync (mdio_addr);
mdio_sync (ioaddr);
/* Shift the read command bits out. */
for (i = 15; i >= 0; i--) {
int dataval = (mii_cmd & (1 << i)) ? MDIO_DATA_OUT : 0;
writeb (MDIO_DIR | dataval, mdio_addr);
mdio_delay (mdio_addr);
writeb (MDIO_DIR | dataval | MDIO_CLK, mdio_addr);
mdio_delay (mdio_addr);
RTL_W8 (Config4, MDIO_DIR | dataval);
mdio_delay ();
RTL_W8 (Config4, MDIO_DIR | dataval | MDIO_CLK);
mdio_delay ();
}
/* Read the two transition, 16 data, and wire-idle bits. */
for (i = 19; i > 0; i--) {
writeb (0, mdio_addr);
mdio_delay (mdio_addr);
retval = (retval << 1) | ((readb (mdio_addr) & MDIO_DATA_IN) ? 1 : 0);
writeb (MDIO_CLK, mdio_addr);
mdio_delay (mdio_addr);
RTL_W8 (Config4, 0);
mdio_delay ();
retval = (retval << 1) | ((RTL_R8 (Config4) & MDIO_DATA_IN) ? 1 : 0);
RTL_W8 (Config4, MDIO_CLK);
mdio_delay ();
}
#endif
......@@ -1282,13 +1262,13 @@ static void mdio_write (struct net_device *dev, int phy_id, int location,
{
struct rtl8139_private *tp = netdev_priv(dev);
#ifdef CONFIG_8139TOO_8129
void *mdio_addr = tp->mmio_addr + Config4;
void __iomem *ioaddr = tp->mmio_addr;
int mii_cmd = (0x5002 << 16) | (phy_id << 23) | (location << 18) | value;
int i;
#endif
if (phy_id > 31) { /* Really a 8139. Use internal registers. */
void *ioaddr = tp->mmio_addr;
void __iomem *ioaddr = tp->mmio_addr;
if (location == 0) {
RTL_W8 (Cfg9346, Cfg9346_Unlock);
RTL_W16 (BasicModeCtrl, value);
......@@ -1299,23 +1279,23 @@ static void mdio_write (struct net_device *dev, int phy_id, int location,
}
#ifdef CONFIG_8139TOO_8129
mdio_sync (mdio_addr);
mdio_sync (ioaddr);
/* Shift the command bits out. */
for (i = 31; i >= 0; i--) {
int dataval =
(mii_cmd & (1 << i)) ? MDIO_WRITE1 : MDIO_WRITE0;
writeb (dataval, mdio_addr);
mdio_delay (mdio_addr);
writeb (dataval | MDIO_CLK, mdio_addr);
mdio_delay (mdio_addr);
RTL_W8 (Config4, dataval);
mdio_delay ();
RTL_W8 (Config4, dataval | MDIO_CLK);
mdio_delay ();
}
/* Clear out extra bits. */
for (i = 2; i > 0; i--) {
writeb (0, mdio_addr);
mdio_delay (mdio_addr);
writeb (MDIO_CLK, mdio_addr);
mdio_delay (mdio_addr);
RTL_W8 (Config4, 0);
mdio_delay ();
RTL_W8 (Config4, MDIO_CLK);
mdio_delay ();
}
#endif
}
......@@ -1325,7 +1305,7 @@ static int rtl8139_open (struct net_device *dev)
{
struct rtl8139_private *tp = netdev_priv(dev);
int retval;
void *ioaddr = tp->mmio_addr;
void __iomem *ioaddr = tp->mmio_addr;
retval = request_irq (dev->irq, rtl8139_interrupt, SA_SHIRQ, dev->name, dev);
if (retval)
......@@ -1382,7 +1362,7 @@ static void rtl_check_media (struct net_device *dev, unsigned int init_media)
static void rtl8139_hw_start (struct net_device *dev)
{
struct rtl8139_private *tp = netdev_priv(dev);
void *ioaddr = tp->mmio_addr;
void __iomem *ioaddr = tp->mmio_addr;
u32 i;
u8 tmp;
......@@ -1484,7 +1464,7 @@ static void rtl8139_tune_twister (struct net_device *dev,
struct rtl8139_private *tp)
{
int linkcase;
void *ioaddr = tp->mmio_addr;
void __iomem *ioaddr = tp->mmio_addr;
/* This is a complicated state machine to configure the "twister" for
impedance/echos based on the cable length.
......@@ -1568,7 +1548,7 @@ static void rtl8139_tune_twister (struct net_device *dev,
static inline void rtl8139_thread_iter (struct net_device *dev,
struct rtl8139_private *tp,
void *ioaddr)
void __iomem *ioaddr)
{
int mii_lpa;
......@@ -1676,7 +1656,7 @@ static inline void rtl8139_tx_clear (struct rtl8139_private *tp)
static void rtl8139_tx_timeout (struct net_device *dev)
{
struct rtl8139_private *tp = netdev_priv(dev);
void *ioaddr = tp->mmio_addr;
void __iomem *ioaddr = tp->mmio_addr;
int i;
u8 tmp8;
unsigned long flags;
......@@ -1721,7 +1701,7 @@ static void rtl8139_tx_timeout (struct net_device *dev)
static int rtl8139_start_xmit (struct sk_buff *skb, struct net_device *dev)
{
struct rtl8139_private *tp = netdev_priv(dev);
void *ioaddr = tp->mmio_addr;
void __iomem *ioaddr = tp->mmio_addr;
unsigned int entry;
unsigned int len = skb->len;
......@@ -1763,7 +1743,7 @@ static int rtl8139_start_xmit (struct sk_buff *skb, struct net_device *dev)
static void rtl8139_tx_interrupt (struct net_device *dev,
struct rtl8139_private *tp,
void *ioaddr)
void __iomem *ioaddr)
{
unsigned long dirty_tx, tx_left;
......@@ -1833,7 +1813,7 @@ static void rtl8139_tx_interrupt (struct net_device *dev,
/* TODO: clean this up! Rx reset need not be this intensive */
static void rtl8139_rx_err (u32 rx_status, struct net_device *dev,
struct rtl8139_private *tp, void *ioaddr)
struct rtl8139_private *tp, void __iomem *ioaddr)
{
u8 tmp8;
#ifdef CONFIG_8139_OLD_RX_RESET
......@@ -1930,7 +1910,7 @@ static __inline__ void wrap_copy(struct sk_buff *skb, const unsigned char *ring,
static void rtl8139_isr_ack(struct rtl8139_private *tp)
{
void *ioaddr = tp->mmio_addr;
void __iomem *ioaddr = tp->mmio_addr;
u16 status;
status = RTL_R16 (IntrStatus) & RxAckBits;
......@@ -1949,7 +1929,7 @@ static void rtl8139_isr_ack(struct rtl8139_private *tp)
static int rtl8139_rx(struct net_device *dev, struct rtl8139_private *tp,
int budget)
{
void *ioaddr = tp->mmio_addr;
void __iomem *ioaddr = tp->mmio_addr;
int received = 0;
unsigned char *rx_ring = tp->rx_ring;
unsigned int cur_rx = tp->cur_rx;
......@@ -2087,7 +2067,7 @@ static int rtl8139_rx(struct net_device *dev, struct rtl8139_private *tp,
static void rtl8139_weird_interrupt (struct net_device *dev,
struct rtl8139_private *tp,
void *ioaddr,
void __iomem *ioaddr,
int status, int link_changed)
{
DPRINTK ("%s: Abnormal interrupt, status %8.8x.\n",
......@@ -2127,7 +2107,7 @@ static void rtl8139_weird_interrupt (struct net_device *dev,
static int rtl8139_poll(struct net_device *dev, int *budget)
{
struct rtl8139_private *tp = netdev_priv(dev);
void *ioaddr = tp->mmio_addr;
void __iomem *ioaddr = tp->mmio_addr;
int orig_budget = min(*budget, dev->quota);
int done = 1;
......@@ -2165,7 +2145,7 @@ 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 *ioaddr = tp->mmio_addr;
void __iomem *ioaddr = tp->mmio_addr;
u16 status, ackstat;
int link_changed = 0; /* avoid bogus "uninit" warning */
int handled = 0;
......@@ -2241,7 +2221,7 @@ static void rtl8139_poll_controller(struct net_device *dev)
static int rtl8139_close (struct net_device *dev)
{
struct rtl8139_private *tp = netdev_priv(dev);
void *ioaddr = tp->mmio_addr;
void __iomem *ioaddr = tp->mmio_addr;
int ret = 0;
unsigned long flags;
......@@ -2304,7 +2284,7 @@ static int rtl8139_close (struct net_device *dev)
static void rtl8139_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
{
struct rtl8139_private *np = netdev_priv(dev);
void *ioaddr = np->mmio_addr;
void __iomem *ioaddr = np->mmio_addr;
spin_lock_irq(&np->lock);
if (rtl_chip_info[np->chipset].flags & HasLWake) {
......@@ -2338,7 +2318,7 @@ static void rtl8139_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
static int rtl8139_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
{
struct rtl8139_private *np = netdev_priv(dev);
void *ioaddr = np->mmio_addr;
void __iomem *ioaddr = np->mmio_addr;
u32 support;
u8 cfg3, cfg5;
......@@ -2506,7 +2486,7 @@ static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
static struct net_device_stats *rtl8139_get_stats (struct net_device *dev)
{
struct rtl8139_private *tp = netdev_priv(dev);
void *ioaddr = tp->mmio_addr;
void __iomem *ioaddr = tp->mmio_addr;
unsigned long flags;
if (netif_running(dev)) {
......@@ -2525,7 +2505,7 @@ static struct net_device_stats *rtl8139_get_stats (struct net_device *dev)
static void __set_rx_mode (struct net_device *dev)
{
struct rtl8139_private *tp = netdev_priv(dev);
void *ioaddr = tp->mmio_addr;
void __iomem *ioaddr = tp->mmio_addr;
u32 mc_filter[2]; /* Multicast hash filter */
int i, rx_mode;
u32 tmp;
......@@ -2586,7 +2566,7 @@ 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 *ioaddr = tp->mmio_addr;
void __iomem *ioaddr = tp->mmio_addr;
unsigned long flags;
pci_save_state (pdev);
......
......@@ -824,6 +824,18 @@ config SMC9194
<file:Documentation/networking/net-modules.txt>. The module
will be called smc9194.
config DM9000
tristate "DM9000 support"
depends on ARM && NET_ETHERNET
select CRC32
select MII
---help---
Support for DM9000 chipset.
To compile this driver as a module, choose M here and read
<file:Documentation/networking/net-modules.txt>. The module will be
called dm9000.
config NET_VENDOR_RACAL
bool "Racal-Interlan (Micom) NI cards"
depends on NET_ETHERNET && ISA
......@@ -989,21 +1001,6 @@ config EEXPRESS_PRO
<file:Documentation/networking/net-modules.txt>. The module
will be called eepro.
config FMV18X
tristate "FMV-181/182/183/184 support (OBSOLETE)"
depends on NET_ISA && OBSOLETE
---help---
If you have a Fujitsu FMV-181/182/183/184 network (Ethernet) card,
say Y and read the Ethernet-HOWTO, available from
<http://www.tldp.org/docs.html#howto>.
If you use an FMV-183 or FMV-184 and it is not working, you may need
to disable Plug & Play mode of the card.
To compile this driver as a module, choose M here and read
<file:Documentation/networking/net-modules.txt>. The module
will be called fmv18x.
config HPLAN_PLUS
tristate "HP PCLAN+ (27247B and 27252A) support"
depends on NET_ISA
......@@ -1092,14 +1089,6 @@ config SEEQ8005
<file:Documentation/networking/net-modules.txt>. The module
will be called seeq8005.
config SK_G16
tristate "SK_G16 support (OBSOLETE)"
depends on NET_ISA && OBSOLETE
help
If you have a network (Ethernet) card of this type, say Y and read
the Ethernet-HOWTO, available from
<http://www.tldp.org/docs.html#howto>.
config SKMC
tristate "SKnet MCA support"
depends on NET_ETHERNET && MCA && BROKEN
......@@ -1932,6 +1921,18 @@ config R8169_VLAN
If in doubt, say Y.
config SKGE
tristate "New SysKonnect GigaEthernet support (EXPERIMENTAL)"
depends on PCI && EXPERIMENTAL
select CRC32
---help---
This driver support the Marvell Yukon or SysKonnect SK-98xx/SK-95xx
and related Gigabit Ethernet adapters. It is a new smaller driver
driver with better performance and more complete ethtool support.
It does not support the link failover and network management
features that "portable" vendor supplied sk98lin driver does.
config SK98LIN
tristate "Marvell Yukon Chipset / SysKonnect SK-98xx Support"
depends on PCI
......
......@@ -53,6 +53,7 @@ obj-$(CONFIG_FEALNX) += fealnx.o
obj-$(CONFIG_TIGON3) += tg3.o
obj-$(CONFIG_BNX2) += bnx2.o
obj-$(CONFIG_TC35815) += tc35815.o
obj-$(CONFIG_SKGE) += skge.o
obj-$(CONFIG_SK98LIN) += sk98lin/
obj-$(CONFIG_SKFP) += skfp/
obj-$(CONFIG_VIA_RHINE) += via-rhine.o
......@@ -74,7 +75,6 @@ obj-$(CONFIG_MAC8390) += mac8390.o 8390.o
obj-$(CONFIG_APNE) += apne.o 8390.o
obj-$(CONFIG_PCMCIA_PCNET) += 8390.o
obj-$(CONFIG_SHAPER) += shaper.o
obj-$(CONFIG_SK_G16) += sk_g16.o
obj-$(CONFIG_HP100) += hp100.o
obj-$(CONFIG_SMC9194) += smc9194.o
obj-$(CONFIG_FEC) += fec.o
......@@ -122,7 +122,6 @@ obj-$(CONFIG_DEFXX) += defxx.o
obj-$(CONFIG_SGISEEQ) += sgiseeq.o
obj-$(CONFIG_SGI_O2MACE_ETH) += meth.o
obj-$(CONFIG_AT1700) += at1700.o
obj-$(CONFIG_FMV18X) += fmv18x.o
obj-$(CONFIG_EL1) += 3c501.o
obj-$(CONFIG_EL16) += 3c507.o
obj-$(CONFIG_ELMC) += 3c523.o
......@@ -180,6 +179,7 @@ obj-$(CONFIG_AMD8111_ETH) += amd8111e.o
obj-$(CONFIG_IBMVETH) += ibmveth.o
obj-$(CONFIG_S2IO) += s2io.o
obj-$(CONFIG_SMC91X) += smc91x.o
obj-$(CONFIG_DM9000) += dm9000.o
obj-$(CONFIG_FEC_8XX) += fec_8xx/
obj-$(CONFIG_ARM) += arm/
......
......@@ -210,9 +210,6 @@ static struct devprobe2 isa_probes[] __initdata = {
#ifdef CONFIG_AT1700
{at1700_probe, 0},
#endif
#ifdef CONFIG_FMV18X /* Fujitsu FMV-181/182 */
{fmv18x_probe, 0},
#endif
#ifdef CONFIG_ETH16I
{eth16i_probe, 0}, /* ICL EtherTeam 16i/32 */
#endif
......@@ -243,9 +240,6 @@ static struct devprobe2 isa_probes[] __initdata = {
#ifdef CONFIG_ELPLUS /* 3c505 */
{elplus_probe, 0},
#endif
#ifdef CONFIG_SK_G16
{SK_init, 0},
#endif
#ifdef CONFIG_NI5010
{ni5010_probe, 0},
#endif
......
......@@ -68,6 +68,7 @@ struct etherh_priv {
void __iomem *dma_base;
unsigned int id;
void __iomem *ctrl_port;
void __iomem *base;
unsigned char ctrl;
u32 supported;
};
......@@ -177,7 +178,7 @@ etherh_setif(struct net_device *dev)
switch (etherh_priv(dev)->id) {
case PROD_I3_ETHERLAN600:
case PROD_I3_ETHERLAN600A:
addr = (void *)dev->base_addr + EN0_RCNTHI;
addr = etherh_priv(dev)->base + EN0_RCNTHI;
switch (dev->if_port) {
case IF_PORT_10BASE2:
......@@ -218,7 +219,7 @@ etherh_getifstat(struct net_device *dev)
switch (etherh_priv(dev)->id) {
case PROD_I3_ETHERLAN600:
case PROD_I3_ETHERLAN600A:
addr = (void *)dev->base_addr + EN0_RCNTHI;
addr = etherh_priv(dev)->base + EN0_RCNTHI;
switch (dev->if_port) {
case IF_PORT_10BASE2:
stat = 1;
......@@ -281,7 +282,7 @@ static void
etherh_reset(struct net_device *dev)
{
struct ei_device *ei_local = netdev_priv(dev);
void __iomem *addr = (void *)dev->base_addr;
void __iomem *addr = etherh_priv(dev)->base;
writeb(E8390_NODMA+E8390_PAGE0+E8390_STOP, addr);
......@@ -327,7 +328,7 @@ etherh_block_output (struct net_device *dev, int count, const unsigned char *buf
ei_local->dmaing = 1;
addr = (void *)dev->base_addr;
addr = etherh_priv(dev)->base;
dma_base = etherh_priv(dev)->dma_base;
count = (count + 1) & ~1;
......@@ -387,7 +388,7 @@ etherh_block_input (struct net_device *dev, int count, struct sk_buff *skb, int
ei_local->dmaing = 1;
addr = (void *)dev->base_addr;
addr = etherh_priv(dev)->base;
dma_base = etherh_priv(dev)->dma_base;
buf = skb->data;
......@@ -427,7 +428,7 @@ etherh_get_header (struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_p
ei_local->dmaing = 1;
addr = (void *)dev->base_addr;
addr = etherh_priv(dev)->base;
dma_base = etherh_priv(dev)->dma_base;
writeb (E8390_NODMA | E8390_PAGE0 | E8390_START, addr + E8390_CMD);
......@@ -696,7 +697,8 @@ etherh_probe(struct expansion_card *ec, const struct ecard_id *id)
eh->ctrl_port = eh->ioc_fast;
}
dev->base_addr = (unsigned long)eh->memc + data->ns8390_offset;
eh->base = eh->memc + data->ns8390_offset;
dev->base_addr = (unsigned long)eh->base;
eh->dma_base = eh->memc + data->dataport_offset;
eh->ctrl_port += data->ctrlport_offset;
......
......@@ -1681,10 +1681,6 @@ static int au1000_init(struct net_device *dev)
control |= MAC_FULL_DUPLEX;
}
/* fix for startup without cable */
if (!link)
dev->flags &= ~IFF_RUNNING;
aup->mac->control = control;
aup->mac->vlan1_tag = 0x8100; /* activate vlan support */
au_sync();
......@@ -1709,16 +1705,14 @@ static void au1000_timer(unsigned long data)
if_port = dev->if_port;
if (aup->phy_ops->phy_status(dev, aup->phy_addr, &link, &speed) == 0) {
if (link) {
if (!(dev->flags & IFF_RUNNING)) {
if (!netif_carrier_ok(dev)) {
netif_carrier_on(dev);
dev->flags |= IFF_RUNNING;
printk(KERN_INFO "%s: link up\n", dev->name);
}
}
else {
if (dev->flags & IFF_RUNNING) {
if (netif_carrier_ok(dev)) {
netif_carrier_off(dev);
dev->flags &= ~IFF_RUNNING;
dev->if_port = 0;
printk(KERN_INFO "%s: link down\n", dev->name);
}
......
......@@ -1412,7 +1412,6 @@ static int bmac_open(struct net_device *dev)
bp->opened = 1;
bmac_reset_and_enable(dev);
enable_irq(dev->irq);
dev->flags |= IFF_RUNNING;
return 0;
}
......@@ -1425,7 +1424,6 @@ static int bmac_close(struct net_device *dev)
int i;
bp->sleeping = 1;
dev->flags &= ~(IFF_UP | IFF_RUNNING);
/* disable rx and tx */
config = bmread(dev, RXCFG);
......
此差异已折叠。
/*
* dm9000 Ethernet
*/
#ifndef _DM9000X_H_
#define _DM9000X_H_
#define DM9000_ID 0x90000A46
/* although the registers are 16 bit, they are 32-bit aligned.
*/
#define DM9000_NCR 0x00
#define DM9000_NSR 0x01
#define DM9000_TCR 0x02
#define DM9000_TSR1 0x03
#define DM9000_TSR2 0x04
#define DM9000_RCR 0x05
#define DM9000_RSR 0x06
#define DM9000_ROCR 0x07
#define DM9000_BPTR 0x08
#define DM9000_FCTR 0x09
#define DM9000_FCR 0x0A
#define DM9000_EPCR 0x0B
#define DM9000_EPAR 0x0C
#define DM9000_EPDRL 0x0D
#define DM9000_EPDRH 0x0E
#define DM9000_WCR 0x0F
#define DM9000_PAR 0x10
#define DM9000_MAR 0x16
#define DM9000_GPCR 0x1e
#define DM9000_GPR 0x1f
#define DM9000_TRPAL 0x22
#define DM9000_TRPAH 0x23
#define DM9000_RWPAL 0x24
#define DM9000_RWPAH 0x25
#define DM9000_VIDL 0x28
#define DM9000_VIDH 0x29
#define DM9000_PIDL 0x2A
#define DM9000_PIDH 0x2B
#define DM9000_CHIPR 0x2C
#define DM9000_SMCR 0x2F
#define DM9000_MRCMDX 0xF0
#define DM9000_MRCMD 0xF2
#define DM9000_MRRL 0xF4
#define DM9000_MRRH 0xF5
#define DM9000_MWCMDX 0xF6
#define DM9000_MWCMD 0xF8
#define DM9000_MWRL 0xFA
#define DM9000_MWRH 0xFB
#define DM9000_TXPLL 0xFC
#define DM9000_TXPLH 0xFD
#define DM9000_ISR 0xFE
#define DM9000_IMR 0xFF
#define NCR_EXT_PHY (1<<7)
#define NCR_WAKEEN (1<<6)
#define NCR_FCOL (1<<4)
#define NCR_FDX (1<<3)
#define NCR_LBK (3<<1)
#define NCR_RST (1<<0)
#define NSR_SPEED (1<<7)
#define NSR_LINKST (1<<6)
#define NSR_WAKEST (1<<5)
#define NSR_TX2END (1<<3)
#define NSR_TX1END (1<<2)
#define NSR_RXOV (1<<1)
#define TCR_TJDIS (1<<6)
#define TCR_EXCECM (1<<5)
#define TCR_PAD_DIS2 (1<<4)
#define TCR_CRC_DIS2 (1<<3)
#define TCR_PAD_DIS1 (1<<2)
#define TCR_CRC_DIS1 (1<<1)
#define TCR_TXREQ (1<<0)
#define TSR_TJTO (1<<7)
#define TSR_LC (1<<6)
#define TSR_NC (1<<5)
#define TSR_LCOL (1<<4)
#define TSR_COL (1<<3)
#define TSR_EC (1<<2)
#define RCR_WTDIS (1<<6)
#define RCR_DIS_LONG (1<<5)
#define RCR_DIS_CRC (1<<4)
#define RCR_ALL (1<<3)
#define RCR_RUNT (1<<2)
#define RCR_PRMSC (1<<1)
#define RCR_RXEN (1<<0)
#define RSR_RF (1<<7)
#define RSR_MF (1<<6)
#define RSR_LCS (1<<5)
#define RSR_RWTO (1<<4)
#define RSR_PLE (1<<3)
#define RSR_AE (1<<2)
#define RSR_CE (1<<1)
#define RSR_FOE (1<<0)
#define FCTR_HWOT(ot) (( ot & 0xf ) << 4 )
#define FCTR_LWOT(ot) ( ot & 0xf )
#define IMR_PAR (1<<7)
#define IMR_ROOM (1<<3)
#define IMR_ROM (1<<2)
#define IMR_PTM (1<<1)
#define IMR_PRM (1<<0)
#define ISR_ROOS (1<<3)
#define ISR_ROS (1<<2)
#define ISR_PTS (1<<1)
#define ISR_PRS (1<<0)
#define ISR_CLR_STATUS (ISR_ROOS | ISR_ROS | ISR_PTS | ISR_PRS)
#define EPCR_REEP (1<<5)
#define EPCR_WEP (1<<4)
#define EPCR_EPOS (1<<3)
#define EPCR_ERPRR (1<<2)
#define EPCR_ERPRW (1<<1)
#define EPCR_ERRE (1<<0)
#define GPCR_GEP_CNTL (1<<0)
#define DM9000_PKT_RDY 0x01 /* Packet ready to receive */
#define DM9000_PKT_MAX 1536 /* Received packet max size */
#endif /* _DM9000X_H_ */
/* fmv18x.c: A network device driver for the Fujitsu FMV-181/182/183/184.
Original: at1700.c (1993-94 by Donald Becker).
Copyright 1993 United States Government as represented by the
Director, National Security Agency.
The author may be reached as becker@scyld.com, or C/O
Scyld Computing Corporation
410 Severn Ave., Suite 210
Annapolis MD 21403
Modified by Yutaka TAMIYA (tamy@flab.fujitsu.co.jp)
Copyright 1994 Fujitsu Laboratories Ltd.
Special thanks to:
Masayoshi UTAKA (utaka@ace.yk.fujitsu.co.jp)
for testing this driver.
H. NEGISHI (agy, negishi@sun45.psd.cs.fujitsu.co.jp)
for suggestion of some program modification.
Masahiro SEKIGUCHI <seki@sysrap.cs.fujitsu.co.jp>
for suggestion of some program modification.
Kazutoshi MORIOKA (morioka@aurora.oaks.cs.fujitsu.co.jp)
for testing this driver.
This software may be used and distributed according to the terms
of the GNU General Public License, incorporated herein by reference.
This is a device driver for the Fujitsu FMV-181/182/183/184, which
is a straight-forward Fujitsu MB86965 implementation.
Sources:
at1700.c
The Fujitsu MB86965 datasheet.
The Fujitsu FMV-181/182 user's guide
*/
static const char version[] =
"fmv18x.c:v2.2.0 09/24/98 Yutaka TAMIYA (tamy@flab.fujitsu.co.jp)\n";
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/fcntl.h>
#include <linux/interrupt.h>
#include <linux/ioport.h>
#include <linux/in.h>
#include <linux/slab.h>
#include <linux/string.h>
#include <linux/init.h>
#include <linux/errno.h>
#include <linux/spinlock.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/skbuff.h>
#include <linux/delay.h>
#include <linux/bitops.h>
#include <asm/system.h>
#include <asm/io.h>
#include <asm/dma.h>
#define DRV_NAME "fmv18x"
static unsigned fmv18x_probe_list[] __initdata = {
0x220, 0x240, 0x260, 0x280, 0x2a0, 0x2c0, 0x300, 0x340, 0
};
/* use 0 for production, 1 for verification, >2 for debug */
#ifndef NET_DEBUG
#define NET_DEBUG 1
#endif
static unsigned int net_debug = NET_DEBUG;
typedef unsigned char uchar;
/* Information that need to be kept for each board. */
struct net_local {
struct net_device_stats stats;
long open_time; /* Useless example local info. */
uint tx_started:1; /* Number of packet on the Tx queue. */
uint tx_queue_ready:1; /* Tx queue is ready to be sent. */
uint rx_started:1; /* Packets are Rxing. */
uchar tx_queue; /* Number of packet on the Tx queue. */
ushort tx_queue_len; /* Current length of the Tx queue. */
spinlock_t lock;
};
/* Offsets from the base address. */
#define STATUS 0
#define TX_STATUS 0
#define RX_STATUS 1
#define TX_INTR 2 /* Bit-mapped interrupt enable registers. */
#define RX_INTR 3
#define TX_MODE 4
#define RX_MODE 5
#define CONFIG_0 6 /* Misc. configuration settings. */
#define CONFIG_1 7
/* Run-time register bank 2 definitions. */
#define DATAPORT 8 /* Word-wide DMA or programmed-I/O dataport. */
#define TX_START 10
#define COL16CNTL 11 /* Controll Reg for 16 collisions */
#define MODE13 13
/* Fujitsu FMV-18x Card Configuration */
#define FJ_STATUS0 0x10
#define FJ_STATUS1 0x11
#define FJ_CONFIG0 0x12
#define FJ_CONFIG1 0x13
#define FJ_MACADDR 0x14 /* 0x14 - 0x19 */
#define FJ_BUFCNTL 0x1A
#define FJ_BUFDATA 0x1C
#define FMV18X_IO_EXTENT 32
/* Index to functions, as function prototypes. */
static int fmv18x_probe1(struct net_device *dev, short ioaddr);
static int net_open(struct net_device *dev);
static int net_send_packet(struct sk_buff *skb, struct net_device *dev);
static irqreturn_t net_interrupt(int irq, void *dev_id, struct pt_regs *regs);
static void net_rx(struct net_device *dev);
static void net_timeout(struct net_device *dev);
static int net_close(struct net_device *dev);
static struct net_device_stats *net_get_stats(struct net_device *dev);
static void set_multicast_list(struct net_device *dev);
/* Check for a network adaptor of this type, and return '0' iff one exists.
If dev->base_addr == 0, probe all likely locations.
If dev->base_addr == 1, always return failure.
If dev->base_addr == 2, allocate space for the device and return success
(detachable devices only).
*/
static int io = 0x220;
static int irq;
struct net_device * __init fmv18x_probe(int unit)
{
struct net_device *dev = alloc_etherdev(sizeof(struct net_local));
unsigned *port;
int err = 0;
if (!dev)
return ERR_PTR(-ENODEV);
if (unit >= 0) {
sprintf(dev->name, "eth%d", unit);
netdev_boot_setup_check(dev);
io = dev->base_addr;
irq = dev->irq;
}
SET_MODULE_OWNER(dev);
if (io > 0x1ff) { /* Check a single specified location. */
err = fmv18x_probe1(dev, io);
} else if (io != 0) { /* Don't probe at all. */
err = -ENXIO;
} else {
for (port = fmv18x_probe_list; *port; port++)
if (fmv18x_probe1(dev, *port) == 0)
break;
if (!*port)
err = -ENODEV;
}
if (err)
goto out;
err = register_netdev(dev);
if (err)
goto out1;
return dev;
out1:
free_irq(dev->irq, dev);
release_region(dev->base_addr, FMV18X_IO_EXTENT);
out:
free_netdev(dev);
return ERR_PTR(err);
}
/* The Fujitsu datasheet suggests that the NIC be probed for by checking its
"signature", the default bit pattern after a reset. This *doesn't* work --
there is no way to reset the bus interface without a complete power-cycle!
It turns out that ATI came to the same conclusion I did: the only thing
that can be done is checking a few bits and then diving right into MAC
address check. */
static int __init fmv18x_probe1(struct net_device *dev, short ioaddr)
{
char irqmap[4] = {3, 7, 10, 15};
char irqmap_pnp[8] = {3, 4, 5, 7, 9, 10, 11, 15};
unsigned int i, retval;
struct net_local *lp;
/* Resetting the chip doesn't reset the ISA interface, so don't bother.
That means we have to be careful with the register values we probe for.
*/
if (!request_region(ioaddr, FMV18X_IO_EXTENT, DRV_NAME))
return -EBUSY;
dev->irq = irq;
dev->base_addr = ioaddr;
/* Check I/O address configuration and Fujitsu vendor code */
if (inb(ioaddr+FJ_MACADDR ) != 0x00
|| inb(ioaddr+FJ_MACADDR+1) != 0x00
|| inb(ioaddr+FJ_MACADDR+2) != 0x0e) {
retval = -ENODEV;
goto out;
}
/* Check PnP mode for FMV-183/184/183A/184A. */
/* This PnP routine is very poor. IO and IRQ should be known. */
if (inb(ioaddr + FJ_STATUS1) & 0x20) {
for (i = 0; i < 8; i++) {
if (dev->irq == irqmap_pnp[i])
break;
}
if (i == 8) {
retval = -ENODEV;
goto out;
}
} else {
if (fmv18x_probe_list[inb(ioaddr + FJ_CONFIG0) & 0x07] != ioaddr)
return -ENODEV;
dev->irq = irqmap[(inb(ioaddr + FJ_CONFIG0)>>6) & 0x03];
}
/* Snarf the interrupt vector now. */
retval = request_irq(dev->irq, &net_interrupt, 0, DRV_NAME, dev);
if (retval) {
printk ("FMV-18x found at %#3x, but it's unusable due to a conflict on"
"IRQ %d.\n", ioaddr, dev->irq);
goto out;
}
printk("%s: FMV-18x found at %#3x, IRQ %d, address ", dev->name,
ioaddr, dev->irq);
for(i = 0; i < 6; i++) {
unsigned char val = inb(ioaddr + FJ_MACADDR + i);
printk("%02x", val);
dev->dev_addr[i] = val;
}
/* "FJ_STATUS0" 12 bit 0x0400 means use regular 100 ohm 10baseT signals,
rather than 150 ohm shielded twisted pair compensation.
0x0000 == auto-sense the interface
0x0800 == use TP interface
0x1800 == use coax interface
*/
{
const char *porttype[] = {"auto-sense", "10baseT", "auto-sense", "10base2/5"};
ushort setup_value = inb(ioaddr + FJ_STATUS0);
switch( setup_value & 0x07 ){
case 0x01 /* 10base5 */:
case 0x02 /* 10base2 */: dev->if_port = 0x18; break;
case 0x04 /* 10baseT */: dev->if_port = 0x08; break;
default /* auto-sense*/: dev->if_port = 0x00; break;
}
printk(" %s interface.\n", porttype[(dev->if_port>>3) & 3]);
}
/* Initialize LAN Controller and LAN Card */
outb(0xda, ioaddr + CONFIG_0); /* Initialize LAN Controller */
outb(0x00, ioaddr + CONFIG_1); /* Stand by mode */
outb(0x00, ioaddr + FJ_CONFIG1); /* Disable IRQ of LAN Card */
outb(0x00, ioaddr + FJ_BUFCNTL); /* Reset ? I'm not sure (TAMIYA) */
/* wait for a while */
udelay(200);
/* Set the station address in bank zero. */
outb(0x00, ioaddr + CONFIG_1);
for (i = 0; i < 6; i++)
outb(dev->dev_addr[i], ioaddr + 8 + i);
/* Switch to bank 1 and set the multicast table to accept none. */
outb(0x04, ioaddr + CONFIG_1);
for (i = 0; i < 8; i++)
outb(0x00, ioaddr + 8 + i);
/* Switch to bank 2 and lock our I/O address. */
outb(0x08, ioaddr + CONFIG_1);
outb(dev->if_port, ioaddr + MODE13);
outb(0x00, ioaddr + COL16CNTL);
if (net_debug)
printk(version);
/* Initialize the device structure. */
dev->priv = kmalloc(sizeof(struct net_local), GFP_KERNEL);
if (!dev->priv) {
retval = -ENOMEM;
goto out_irq;
}
memset(dev->priv, 0, sizeof(struct net_local));
lp = dev->priv;
spin_lock_init(&lp->lock);
dev->open = net_open;
dev->stop = net_close;
dev->hard_start_xmit = net_send_packet;
dev->tx_timeout = net_timeout;
dev->watchdog_timeo = HZ/10;
dev->get_stats = net_get_stats;
dev->set_multicast_list = set_multicast_list;
return 0;
out_irq:
free_irq(dev->irq, dev);
out:
release_region(ioaddr, FMV18X_IO_EXTENT);
return retval;
}
static int net_open(struct net_device *dev)
{
struct net_local *lp = dev->priv;
int ioaddr = dev->base_addr;
/* Set the configuration register 0 to 32K 100ns. byte-wide memory,
16 bit bus access, and two 4K Tx, enable the Rx and Tx. */
outb(0x5a, ioaddr + CONFIG_0);
/* Powerup and switch to register bank 2 for the run-time registers. */
outb(0xe8, ioaddr + CONFIG_1);
lp->tx_started = 0;
lp->tx_queue_ready = 1;
lp->rx_started = 0;
lp->tx_queue = 0;
lp->tx_queue_len = 0;
/* Clear Tx and Rx Status */
outb(0xff, ioaddr + TX_STATUS);
outb(0xff, ioaddr + RX_STATUS);
lp->open_time = jiffies;
netif_start_queue(dev);
/* Enable the IRQ of the LAN Card */
outb(0x80, ioaddr + FJ_CONFIG1);
/* Enable both Tx and Rx interrupts */
outw(0x8182, ioaddr+TX_INTR);
return 0;
}
static void net_timeout(struct net_device *dev)
{
struct net_local *lp = dev->priv;
int ioaddr = dev->base_addr;
unsigned long flags;
printk(KERN_WARNING "%s: transmit timed out with status %04x, %s?\n", dev->name,
htons(inw(ioaddr + TX_STATUS)),
inb(ioaddr + TX_STATUS) & 0x80
? "IRQ conflict" : "network cable problem");
printk(KERN_WARNING "%s: timeout registers: %04x %04x %04x %04x %04x %04x %04x %04x.\n",
dev->name, htons(inw(ioaddr + 0)),
htons(inw(ioaddr + 2)), htons(inw(ioaddr + 4)),
htons(inw(ioaddr + 6)), htons(inw(ioaddr + 8)),
htons(inw(ioaddr +10)), htons(inw(ioaddr +12)),
htons(inw(ioaddr +14)));
printk(KERN_WARNING "eth card: %04x %04x\n",
htons(inw(ioaddr+FJ_STATUS0)),
htons(inw(ioaddr+FJ_CONFIG0)));
lp->stats.tx_errors++;
/* ToDo: We should try to restart the adaptor... */
spin_lock_irqsave(&lp->lock, flags);
/* Initialize LAN Controller and LAN Card */
outb(0xda, ioaddr + CONFIG_0); /* Initialize LAN Controller */
outb(0x00, ioaddr + CONFIG_1); /* Stand by mode */
outb(0x00, ioaddr + FJ_CONFIG1); /* Disable IRQ of LAN Card */
outb(0x00, ioaddr + FJ_BUFCNTL); /* Reset ? I'm not sure */
net_open(dev);
spin_unlock_irqrestore(&lp->lock, flags);
netif_wake_queue(dev);
}
static int net_send_packet(struct sk_buff *skb, struct net_device *dev)
{
struct net_local *lp = dev->priv;
int ioaddr = dev->base_addr;
short length = skb->len;
unsigned char *buf;
unsigned long flags;
/* Block a transmit from overlapping. */
if (length > ETH_FRAME_LEN) {
if (net_debug)
printk("%s: Attempting to send a large packet (%d bytes).\n",
dev->name, length);
return 1;
}
if (length < ETH_ZLEN) {
skb = skb_padto(skb, ETH_ZLEN);
if (skb == NULL)
return 0;
length = ETH_ZLEN;
}
buf = skb->data;
if (net_debug > 4)
printk("%s: Transmitting a packet of length %lu.\n", dev->name,
(unsigned long)skb->len);
/* We may not start transmitting unless we finish transferring
a packet into the Tx queue. During executing the following
codes we possibly catch a Tx interrupt. Thus we flag off
tx_queue_ready, so that we prevent the interrupt routine
(net_interrupt) to start transmitting. */
spin_lock_irqsave(&lp->lock, flags);
lp->tx_queue_ready = 0;
{
outw(length, ioaddr + DATAPORT);
outsw(ioaddr + DATAPORT, buf, (length + 1) >> 1);
lp->tx_queue++;
lp->tx_queue_len += length + 2;
}
lp->tx_queue_ready = 1;
spin_unlock_irqrestore(&lp->lock, flags);
if (lp->tx_started == 0) {
/* If the Tx is idle, always trigger a transmit. */
outb(0x80 | lp->tx_queue, ioaddr + TX_START);
lp->tx_queue = 0;
lp->tx_queue_len = 0;
dev->trans_start = jiffies;
lp->tx_started = 1;
} else if (lp->tx_queue_len >= 4096 - 1502) /* No room for a packet */
netif_stop_queue(dev);
dev_kfree_skb(skb);
return 0;
}
/* The typical workload of the driver:
Handle the network interface interrupts. */
static irqreturn_t
net_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
struct net_device *dev = dev_id;
struct net_local *lp;
int ioaddr, status;
ioaddr = dev->base_addr;
lp = dev->priv;
status = inw(ioaddr + TX_STATUS);
outw(status, ioaddr + TX_STATUS);
if (net_debug > 4)
printk("%s: Interrupt with status %04x.\n", dev->name, status);
if (lp->rx_started == 0 &&
(status & 0xff00 || (inb(ioaddr + RX_MODE) & 0x40) == 0)) {
/* Got a packet(s).
We cannot execute net_rx more than once at the same time for
the same device. During executing net_rx, we possibly catch a
Tx interrupt. Thus we flag on rx_started, so that we prevent
the interrupt routine (net_interrupt) to dive into net_rx
again. */
lp->rx_started = 1;
outb(0x00, ioaddr + RX_INTR); /* Disable RX intr. */
net_rx(dev);
outb(0x81, ioaddr + RX_INTR); /* Enable RX intr. */
lp->rx_started = 0;
}
if (status & 0x00ff) {
if (status & 0x02) {
/* More than 16 collisions occurred */
if (net_debug > 4)
printk("%s: 16 Collision occur during Txing.\n", dev->name);
/* Cancel sending a packet. */
outb(0x03, ioaddr + COL16CNTL);
lp->stats.collisions++;
}
if (status & 0x82) {
spin_lock(&lp->lock);
lp->stats.tx_packets++;
if (lp->tx_queue && lp->tx_queue_ready) {
outb(0x80 | lp->tx_queue, ioaddr + TX_START);
lp->tx_queue = 0;
lp->tx_queue_len = 0;
dev->trans_start = jiffies;
netif_wake_queue(dev); /* Inform upper layers. */
} else {
lp->tx_started = 0;
netif_wake_queue(dev); /* Inform upper layers. */
}
spin_unlock(&lp->lock);
}
}
return IRQ_RETVAL(status);
}
/* We have a good packet(s), get it/them out of the buffers. */
static void net_rx(struct net_device *dev)
{
struct net_local *lp = dev->priv;
int ioaddr = dev->base_addr;
int boguscount = 5;
while ((inb(ioaddr + RX_MODE) & 0x40) == 0) {
/* Clear PKT_RDY bit: by agy 19940922 */
/* outb(0x80, ioaddr + RX_STATUS); */
ushort status = inw(ioaddr + DATAPORT);
if (net_debug > 4)
printk("%s: Rxing packet mode %02x status %04x.\n",
dev->name, inb(ioaddr + RX_MODE), status);
#ifndef final_version
if (status == 0) {
outb(0x05, ioaddr + 14);
break;
}
#endif
if ((status & 0xF0) != 0x20) { /* There was an error. */
lp->stats.rx_errors++;
if (status & 0x08) lp->stats.rx_length_errors++;
if (status & 0x04) lp->stats.rx_frame_errors++;
if (status & 0x02) lp->stats.rx_crc_errors++;
if (status & 0x01) lp->stats.rx_over_errors++;
} else {
ushort pkt_len = inw(ioaddr + DATAPORT);
/* Malloc up new buffer. */
struct sk_buff *skb;
if (pkt_len > 1550) {
printk("%s: The FMV-18x claimed a very large packet, size %d.\n",
dev->name, pkt_len);
outb(0x05, ioaddr + 14);
lp->stats.rx_errors++;
break;
}
skb = dev_alloc_skb(pkt_len+3);
if (skb == NULL) {
printk("%s: Memory squeeze, dropping packet (len %d).\n",
dev->name, pkt_len);
outb(0x05, ioaddr + 14);
lp->stats.rx_dropped++;
break;
}
skb->dev = dev;
skb_reserve(skb,2);
insw(ioaddr + DATAPORT, skb_put(skb,pkt_len), (pkt_len + 1) >> 1);
if (net_debug > 5) {
int i;
printk("%s: Rxed packet of length %d: ", dev->name, pkt_len);
for (i = 0; i < 14; i++)
printk(" %02x", skb->data[i]);
printk(".\n");
}
skb->protocol=eth_type_trans(skb, dev);
netif_rx(skb);
dev->last_rx = jiffies;
lp->stats.rx_packets++;
lp->stats.rx_bytes += pkt_len;
}
if (--boguscount <= 0)
break;
}
/* If any worth-while packets have been received, dev_rint()
has done a mark_bh(NET_BH) for us and will work on them
when we get to the bottom-half routine. */
{
int i;
for (i = 0; i < 20; i++) {
if ((inb(ioaddr + RX_MODE) & 0x40) == 0x40)
break;
(void)inw(ioaddr + DATAPORT); /* dummy status read */
outb(0x05, ioaddr + 14);
}
if (net_debug > 5 && i > 0)
printk("%s: Exint Rx packet with mode %02x after %d ticks.\n",
dev->name, inb(ioaddr + RX_MODE), i);
}
return;
}
/* The inverse routine to net_open(). */
static int net_close(struct net_device *dev)
{
int ioaddr = dev->base_addr;
((struct net_local *)dev->priv)->open_time = 0;
netif_stop_queue(dev);
/* Set configuration register 0 to disable Tx and Rx. */
outb(0xda, ioaddr + CONFIG_0);
/* Update the statistics -- ToDo. */
/* Power-down the chip. Green, green, green! */
outb(0x00, ioaddr + CONFIG_1);
/* Set the ethernet adaptor disable IRQ */
outb(0x00, ioaddr + FJ_CONFIG1);
return 0;
}
/* Get the current statistics. This may be called with the card open or
closed. */
static struct net_device_stats *net_get_stats(struct net_device *dev)
{
struct net_local *lp = dev->priv;
return &lp->stats;
}
/* Set or clear the multicast filter for this adaptor.
num_addrs == -1 Promiscuous mode, receive all packets
num_addrs == 0 Normal mode, clear multicast list
num_addrs > 0 Multicast mode, receive normal and MC packets, and do
best-effort filtering.
*/
static void set_multicast_list(struct net_device *dev)
{
short ioaddr = dev->base_addr;
if (dev->mc_count || dev->flags&(IFF_PROMISC|IFF_ALLMULTI))
{
/*
* We must make the kernel realise we had to move
* into promisc mode or we start all out war on
* the cable. - AC
*/
dev->flags|=IFF_PROMISC;
outb(3, ioaddr + RX_MODE); /* Enable promiscuous mode */
}
else
outb(2, ioaddr + RX_MODE); /* Disable promiscuous, use normal mode */
}
#ifdef MODULE
static struct net_device *dev_fmv18x;
MODULE_PARM(io, "i");
MODULE_PARM(irq, "i");
MODULE_PARM(net_debug, "i");
MODULE_PARM_DESC(io, "FMV-18X I/O address");
MODULE_PARM_DESC(irq, "FMV-18X IRQ number");
MODULE_PARM_DESC(net_debug, "FMV-18X debug level (0-1,5-6)");
MODULE_LICENSE("GPL");
int init_module(void)
{
if (io == 0)
printk("fmv18x: You should not use auto-probing with insmod!\n");
dev_fmv18x = fmv18x_probe(-1);
if (IS_ERR(dev_fmv18x))
return PTR_ERR(dev_fmv18x);
return 0;
}
void
cleanup_module(void)
{
unregister_netdev(dev_fmv18x);
free_irq(dev_fmv18x->irq, dev_fmv18x);
release_region(dev_fmv18x->base_addr, FMV18X_IO_EXTENT);
free_netdev(dev_fmv18x);
}
#endif /* MODULE */
/*
* Local variables:
* compile-command: "gcc -D__KERNEL__ -I/usr/src/linux/net/inet -Wall -Wstrict-prototypes -O6 -m486 -c fmv18x.c"
* version-control: t
* kept-new-versions: 5
* tab-width: 4
* c-indent-level: 4
* End:
*/
......@@ -1537,20 +1537,20 @@ static void shmem_get_8390_hdr(struct net_device *dev,
static void shmem_block_input(struct net_device *dev, int count,
struct sk_buff *skb, int ring_offset)
{
void __iomem *xfer_start = ei_status.mem + (TX_PAGES<<8)
+ ring_offset
void __iomem *base = ei_status.mem;
unsigned long offset = (TX_PAGES<<8) + ring_offset
- (ei_status.rx_start_page << 8);
char *buf = skb->data;
if (xfer_start + count > (void __iomem *)ei_status.rmem_end) {
if (offset + count > ei_status.priv) {
/* We must wrap the input move. */
int semi_count = (void __iomem *)ei_status.rmem_end - xfer_start;
copyin(buf, xfer_start, semi_count);
int semi_count = ei_status.priv - offset;
copyin(buf, base + offset, semi_count);
buf += semi_count;
xfer_start = ei_status.mem + (TX_PAGES<<8);
offset = TX_PAGES<<8;
count -= semi_count;
}
copyin(buf, xfer_start, count);
copyin(buf, base + offset, count);
}
/*====================================================================*/
......@@ -1611,8 +1611,9 @@ static int setup_shmem_window(dev_link_t *link, int start_pg,
}
ei_status.mem = info->base + offset;
ei_status.priv = req.Size;
dev->mem_start = (u_long)ei_status.mem;
dev->mem_end = ei_status.rmem_end = (u_long)info->base + req.Size;
dev->mem_end = dev->mem_start + req.Size;
ei_status.tx_start_page = start_pg;
ei_status.rx_start_page = start_pg + TX_PAGES;
......
......@@ -1217,36 +1217,43 @@ ppp_push(struct ppp *ppp)
*/
static int ppp_mp_explode(struct ppp *ppp, struct sk_buff *skb)
{
int nch, len, fragsize;
int len, fragsize;
int i, bits, hdrlen, mtu;
int flen, fnb;
int flen;
int navail, nfree;
int nbigger;
unsigned char *p, *q;
struct list_head *list;
struct channel *pch;
struct sk_buff *frag;
struct ppp_channel *chan;
nch = 0;
nfree = 0; /* # channels which have no packet already queued */
navail = 0; /* total # of usable channels (not deregistered) */
hdrlen = (ppp->flags & SC_MP_XSHORTSEQ)? MPHDRLEN_SSN: MPHDRLEN;
i = 0;
list = &ppp->channels;
while ((list = list->next) != &ppp->channels) {
pch = list_entry(list, struct channel, clist);
nch += pch->avail = (skb_queue_len(&pch->file.xq) == 0);
/*
* If a channel hasn't had a fragment yet, it has to get
* one before we send any fragments on later channels.
* If it can't take a fragment now, don't give any
* to subsequent channels.
*/
if (!pch->had_frag && !pch->avail) {
while ((list = list->next) != &ppp->channels) {
pch = list_entry(list, struct channel, clist);
pch->avail = 0;
navail += pch->avail = (pch->chan != NULL);
if (pch->avail) {
if (skb_queue_len(&pch->file.xq) == 0
|| !pch->had_frag) {
pch->avail = 2;
++nfree;
}
break;
if (!pch->had_frag && i < ppp->nxchan)
ppp->nxchan = i;
}
++i;
}
if (nch == 0)
/*
* Don't start sending this packet unless at least half of
* the channels are free. This gives much better TCP
* performance if we have a lot of channels.
*/
if (nfree == 0 || nfree < navail / 2)
return 0; /* can't take now, leave it in xmit_pending */
/* Do protocol field compression (XXX this should be optional) */
......@@ -1257,14 +1264,19 @@ static int ppp_mp_explode(struct ppp *ppp, struct sk_buff *skb)
--len;
}
/* decide on fragment size */
/*
* Decide on fragment size.
* We create a fragment for each free channel regardless of
* how small they are (i.e. even 0 length) in order to minimize
* the time that it will take to detect when a channel drops
* a fragment.
*/
fragsize = len;
if (nch > 1) {
int maxch = ROUNDUP(len, MIN_FRAG_SIZE);
if (nch > maxch)
nch = maxch;
fragsize = ROUNDUP(fragsize, nch);
}
if (nfree > 1)
fragsize = ROUNDUP(fragsize, nfree);
/* nbigger channels get fragsize bytes, the rest get fragsize-1,
except if nbigger==0, then they all get fragsize. */
nbigger = len % nfree;
/* skip to the channel after the one we last used
and start at that one */
......@@ -1278,7 +1290,7 @@ static int ppp_mp_explode(struct ppp *ppp, struct sk_buff *skb)
/* create a fragment for each channel */
bits = B;
do {
while (nfree > 0 || len > 0) {
list = list->next;
if (list == &ppp->channels) {
i = 0;
......@@ -1289,61 +1301,92 @@ static int ppp_mp_explode(struct ppp *ppp, struct sk_buff *skb)
if (!pch->avail)
continue;
/*
* Skip this channel if it has a fragment pending already and
* we haven't given a fragment to all of the free channels.
*/
if (pch->avail == 1) {
if (nfree > 0)
continue;
} else {
--nfree;
pch->avail = 1;
}
/* check the channel's mtu and whether it is still attached. */
spin_lock_bh(&pch->downl);
if (pch->chan == 0 || (mtu = pch->chan->mtu) < hdrlen) {
/* can't use this channel */
if (pch->chan == NULL) {
/* can't use this channel, it's being deregistered */
spin_unlock_bh(&pch->downl);
pch->avail = 0;
if (--nch == 0)
if (--navail == 0)
break;
continue;
}
/*
* We have to create multiple fragments for this channel
* if fragsize is greater than the channel's mtu.
* Create a fragment for this channel of
* min(max(mtu+2-hdrlen, 4), fragsize, len) bytes.
* If mtu+2-hdrlen < 4, that is a ridiculously small
* MTU, so we use mtu = 2 + hdrlen.
*/
if (fragsize > len)
fragsize = len;
for (flen = fragsize; flen > 0; flen -= fnb) {
fnb = flen;
if (fnb > mtu + 2 - hdrlen)
fnb = mtu + 2 - hdrlen;
if (fnb >= len)
bits |= E;
frag = alloc_skb(fnb + hdrlen, GFP_ATOMIC);
if (frag == 0)
goto noskb;
q = skb_put(frag, fnb + hdrlen);
/* make the MP header */
q[0] = PPP_MP >> 8;
q[1] = PPP_MP;
if (ppp->flags & SC_MP_XSHORTSEQ) {
q[2] = bits + ((ppp->nxseq >> 8) & 0xf);
q[3] = ppp->nxseq;
} else {
q[2] = bits;
q[3] = ppp->nxseq >> 16;
q[4] = ppp->nxseq >> 8;
q[5] = ppp->nxseq;
}
/* copy the data in */
memcpy(q + hdrlen, p, fnb);
/* try to send it down the channel */
chan = pch->chan;
if (!chan->ops->start_xmit(chan, frag))
skb_queue_tail(&pch->file.xq, frag);
pch->had_frag = 1;
p += fnb;
len -= fnb;
++ppp->nxseq;
bits = 0;
flen = fragsize;
mtu = pch->chan->mtu + 2 - hdrlen;
if (mtu < 4)
mtu = 4;
if (flen > mtu)
flen = mtu;
if (flen == len && nfree == 0)
bits |= E;
frag = alloc_skb(flen + hdrlen + (flen == 0), GFP_ATOMIC);
if (frag == 0)
goto noskb;
q = skb_put(frag, flen + hdrlen);
/* make the MP header */
q[0] = PPP_MP >> 8;
q[1] = PPP_MP;
if (ppp->flags & SC_MP_XSHORTSEQ) {
q[2] = bits + ((ppp->nxseq >> 8) & 0xf);
q[3] = ppp->nxseq;
} else {
q[2] = bits;
q[3] = ppp->nxseq >> 16;
q[4] = ppp->nxseq >> 8;
q[5] = ppp->nxseq;
}
/*
* Copy the data in.
* Unfortunately there is a bug in older versions of
* the Linux PPP multilink reconstruction code where it
* drops 0-length fragments. Therefore we make sure the
* fragment has at least one byte of data. Any bytes
* we add in this situation will end up as padding on the
* end of the reconstructed packet.
*/
if (flen == 0)
*skb_put(frag, 1) = 0;
else
memcpy(q + hdrlen, p, flen);
/* try to send it down the channel */
chan = pch->chan;
if (skb_queue_len(&pch->file.xq)
|| !chan->ops->start_xmit(chan, frag))
skb_queue_tail(&pch->file.xq, frag);
pch->had_frag = 1;
p += flen;
len -= flen;
++ppp->nxseq;
bits = 0;
spin_unlock_bh(&pch->downl);
} while (len > 0);
if (--nbigger == 0 && fragsize > 0)
--fragsize;
}
ppp->nxchan = i;
return 1;
......@@ -1422,7 +1465,7 @@ ppp_input(struct ppp_channel *chan, struct sk_buff *skb)
kfree_skb(skb);
return;
}
proto = PPP_PROTO(skb);
read_lock_bh(&pch->upl);
if (pch->ppp == 0 || proto >= 0xc000 || proto == PPP_CCPFRAG) {
......@@ -1691,7 +1734,7 @@ ppp_receive_mp_frame(struct ppp *ppp, struct sk_buff *skb, struct channel *pch)
struct list_head *l;
int mphdrlen = (ppp->flags & SC_MP_SHORTSEQ)? MPHDRLEN_SSN: MPHDRLEN;
if (!pskb_may_pull(skb, mphdrlen + 1) || ppp->mrru == 0)
if (!pskb_may_pull(skb, mphdrlen) || ppp->mrru == 0)
goto err; /* no good, throw it away */
/* Decode sequence number and begin/end bits */
......
......@@ -69,7 +69,13 @@ VERSION 2.2LK <2005/01/25>
#include <asm/io.h>
#include <asm/irq.h>
#define RTL8169_VERSION "2.2LK"
#ifdef CONFIG_R8169_NAPI
#define NAPI_SUFFIX "-NAPI"
#else
#define NAPI_SUFFIX ""
#endif
#define RTL8169_VERSION "2.2LK" NAPI_SUFFIX
#define MODULENAME "r8169"
#define PFX MODULENAME ": "
......@@ -85,6 +91,10 @@ VERSION 2.2LK <2005/01/25>
#define dprintk(fmt, args...) do {} while (0)
#endif /* RTL8169_DEBUG */
#define R8169_MSG_DEFAULT \
(NETIF_MSG_DRV | NETIF_MSG_PROBE | NETIF_MSG_LINK | NETIF_MSG_IFUP | \
NETIF_MSG_IFDOWN)
#define TX_BUFFS_AVAIL(tp) \
(tp->dirty_tx + NUM_TX_DESC - tp->cur_tx - 1)
......@@ -174,8 +184,9 @@ const static struct {
#undef _R
static struct pci_device_id rtl8169_pci_tbl[] = {
{0x10ec, 0x8169, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
{0x1186, 0x4300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
{ PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8169), },
{ PCI_DEVICE(PCI_VENDOR_ID_DLINK, 0x4300), },
{ PCI_DEVICE(0x16ec, 0x0116), },
{0,},
};
......@@ -183,10 +194,15 @@ MODULE_DEVICE_TABLE(pci, rtl8169_pci_tbl);
static int rx_copybreak = 200;
static int use_dac;
static struct {
u32 msg_enable;
} debug = { -1 };
enum RTL8169_registers {
MAC0 = 0, /* Ethernet hardware address. */
MAR0 = 8, /* Multicast filter. */
CounterAddrLow = 0x10,
CounterAddrHigh = 0x14,
TxDescStartAddrLow = 0x20,
TxDescStartAddrHigh = 0x24,
TxHDescStartAddrLow = 0x28,
......@@ -328,6 +344,9 @@ enum RTL8169_register_content {
/* _TBICSRBit */
TBILinkOK = 0x02000000,
/* DumpCounterCommand */
CounterDump = 0x8,
};
enum _DescStatusBit {
......@@ -385,6 +404,7 @@ struct rtl8169_private {
struct pci_dev *pci_dev; /* Index of PCI device */
struct net_device_stats stats; /* statistics of net device */
spinlock_t lock; /* spin lock flag */
u32 msg_enable;
int chipset;
int mac_version;
int phy_version;
......@@ -418,9 +438,13 @@ struct rtl8169_private {
MODULE_AUTHOR("Realtek and the Linux r8169 crew <netdev@vger.kernel.org>");
MODULE_DESCRIPTION("RealTek RTL-8169 Gigabit Ethernet driver");
module_param_array(media, int, &num_media, 0);
MODULE_PARM_DESC(media, "force phy operation. Deprecated by ethtool (8).");
module_param(rx_copybreak, int, 0);
MODULE_PARM_DESC(rx_copybreak, "Copy breakpoint for copy-only-tiny-frames");
module_param(use_dac, int, 0);
MODULE_PARM_DESC(use_dac, "Enable PCI DAC. Unsafe on 32 bit PCI slot.");
module_param_named(debug, debug.msg_enable, int, 0);
MODULE_PARM_DESC(debug, "Debug verbosity level (0=none, ..., 16=all)");
MODULE_LICENSE("GPL");
MODULE_VERSION(RTL8169_VERSION);
......@@ -433,10 +457,10 @@ static void rtl8169_hw_start(struct net_device *dev);
static int rtl8169_close(struct net_device *dev);
static void rtl8169_set_rx_mode(struct net_device *dev);
static void rtl8169_tx_timeout(struct net_device *dev);
static struct net_device_stats *rtl8169_get_stats(struct net_device *netdev);
static struct net_device_stats *rtl8169_get_stats(struct net_device *dev);
static int rtl8169_rx_interrupt(struct net_device *, struct rtl8169_private *,
void __iomem *);
static int rtl8169_change_mtu(struct net_device *netdev, int new_mtu);
static int rtl8169_change_mtu(struct net_device *dev, int new_mtu);
static void rtl8169_down(struct net_device *dev);
#ifdef CONFIG_R8169_NAPI
......@@ -543,9 +567,13 @@ static void rtl8169_check_link_status(struct net_device *dev,
spin_lock_irqsave(&tp->lock, flags);
if (tp->link_ok(ioaddr)) {
netif_carrier_on(dev);
printk(KERN_INFO PFX "%s: link up\n", dev->name);
} else
if (netif_msg_ifup(tp))
printk(KERN_INFO PFX "%s: link up\n", dev->name);
} else {
if (netif_msg_ifdown(tp))
printk(KERN_INFO PFX "%s: link down\n", dev->name);
netif_carrier_off(dev);
}
spin_unlock_irqrestore(&tp->lock, flags);
}
......@@ -569,7 +597,7 @@ static void rtl8169_link_option(int idx, u8 *autoneg, u16 *speed, u8 *duplex)
option = ((idx < MAX_UNITS) && (idx >= 0)) ? media[idx] : 0xff;
if ((option != 0xff) && !idx)
if ((option != 0xff) && !idx && netif_msg_drv(&debug))
printk(KERN_WARNING PFX "media option is deprecated.\n");
for (p = link_settings; p->media != 0xff; p++) {
......@@ -611,9 +639,11 @@ static int rtl8169_set_speed_tbi(struct net_device *dev,
} else if (autoneg == AUTONEG_ENABLE)
RTL_W32(TBICSR, reg | TBINwEnable | TBINwRestart);
else {
printk(KERN_WARNING PFX
"%s: incorrect speed setting refused in TBI mode\n",
dev->name);
if (netif_msg_link(tp)) {
printk(KERN_WARNING "%s: "
"incorrect speed setting refused in TBI mode\n",
dev->name);
}
ret = -EOPNOTSUPP;
}
......@@ -871,12 +901,120 @@ static void rtl8169_get_regs(struct net_device *dev, struct ethtool_regs *regs,
spin_unlock_irqrestore(&tp->lock, flags);
}
static u32 rtl8169_get_msglevel(struct net_device *dev)
{
struct rtl8169_private *tp = netdev_priv(dev);
return tp->msg_enable;
}
static void rtl8169_set_msglevel(struct net_device *dev, u32 value)
{
struct rtl8169_private *tp = netdev_priv(dev);
tp->msg_enable = value;
}
static const char rtl8169_gstrings[][ETH_GSTRING_LEN] = {
"tx_packets",
"rx_packets",
"tx_errors",
"rx_errors",
"rx_missed",
"align_errors",
"tx_single_collisions",
"tx_multi_collisions",
"unicast",
"broadcast",
"multicast",
"tx_aborted",
"tx_underrun",
};
struct rtl8169_counters {
u64 tx_packets;
u64 rx_packets;
u64 tx_errors;
u32 rx_errors;
u16 rx_missed;
u16 align_errors;
u32 tx_one_collision;
u32 tx_multi_collision;
u64 rx_unicast;
u64 rx_broadcast;
u32 rx_multicast;
u16 tx_aborted;
u16 tx_underun;
};
static int rtl8169_get_stats_count(struct net_device *dev)
{
return ARRAY_SIZE(rtl8169_gstrings);
}
static void rtl8169_get_ethtool_stats(struct net_device *dev,
struct ethtool_stats *stats, u64 *data)
{
struct rtl8169_private *tp = netdev_priv(dev);
void __iomem *ioaddr = tp->mmio_addr;
struct rtl8169_counters *counters;
dma_addr_t paddr;
u32 cmd;
ASSERT_RTNL();
counters = pci_alloc_consistent(tp->pci_dev, sizeof(*counters), &paddr);
if (!counters)
return;
RTL_W32(CounterAddrHigh, (u64)paddr >> 32);
cmd = (u64)paddr & DMA_32BIT_MASK;
RTL_W32(CounterAddrLow, cmd);
RTL_W32(CounterAddrLow, cmd | CounterDump);
while (RTL_R32(CounterAddrLow) & CounterDump) {
if (msleep_interruptible(1))
break;
}
RTL_W32(CounterAddrLow, 0);
RTL_W32(CounterAddrHigh, 0);
data[0] = le64_to_cpu(counters->tx_packets);
data[1] = le64_to_cpu(counters->rx_packets);
data[2] = le64_to_cpu(counters->tx_errors);
data[3] = le32_to_cpu(counters->rx_errors);
data[4] = le16_to_cpu(counters->rx_missed);
data[5] = le16_to_cpu(counters->align_errors);
data[6] = le32_to_cpu(counters->tx_one_collision);
data[7] = le32_to_cpu(counters->tx_multi_collision);
data[8] = le64_to_cpu(counters->rx_unicast);
data[9] = le64_to_cpu(counters->rx_broadcast);
data[10] = le32_to_cpu(counters->rx_multicast);
data[11] = le16_to_cpu(counters->tx_aborted);
data[12] = le16_to_cpu(counters->tx_underun);
pci_free_consistent(tp->pci_dev, sizeof(*counters), counters, paddr);
}
static void rtl8169_get_strings(struct net_device *dev, u32 stringset, u8 *data)
{
switch(stringset) {
case ETH_SS_STATS:
memcpy(data, *rtl8169_gstrings, sizeof(rtl8169_gstrings));
break;
}
}
static struct ethtool_ops rtl8169_ethtool_ops = {
.get_drvinfo = rtl8169_get_drvinfo,
.get_regs_len = rtl8169_get_regs_len,
.get_link = ethtool_op_get_link,
.get_settings = rtl8169_get_settings,
.set_settings = rtl8169_set_settings,
.get_msglevel = rtl8169_get_msglevel,
.set_msglevel = rtl8169_set_msglevel,
.get_rx_csum = rtl8169_get_rx_csum,
.set_rx_csum = rtl8169_set_rx_csum,
.get_tx_csum = ethtool_op_get_tx_csum,
......@@ -886,6 +1024,9 @@ static struct ethtool_ops rtl8169_ethtool_ops = {
.get_tso = ethtool_op_get_tso,
.set_tso = ethtool_op_set_tso,
.get_regs = rtl8169_get_regs,
.get_strings = rtl8169_get_strings,
.get_stats_count = rtl8169_get_stats_count,
.get_ethtool_stats = rtl8169_get_ethtool_stats,
};
static void rtl8169_write_gmii_reg_bit(void __iomem *ioaddr, int reg, int bitnum,
......@@ -1091,7 +1232,8 @@ static void rtl8169_phy_timer(unsigned long __opaque)
if (tp->link_ok(ioaddr))
goto out_unlock;
printk(KERN_WARNING PFX "%s: PHY reset until link up\n", dev->name);
if (netif_msg_link(tp))
printk(KERN_WARNING "%s: PHY reset until link up\n", dev->name);
tp->phy_reset_enable(ioaddr);
......@@ -1169,18 +1311,23 @@ rtl8169_init_board(struct pci_dev *pdev, struct net_device **dev_out,
/* dev zeroed in alloc_etherdev */
dev = alloc_etherdev(sizeof (*tp));
if (dev == NULL) {
printk(KERN_ERR PFX "unable to alloc new ethernet\n");
if (netif_msg_drv(&debug))
printk(KERN_ERR PFX "unable to alloc new ethernet\n");
goto err_out;
}
SET_MODULE_OWNER(dev);
SET_NETDEV_DEV(dev, &pdev->dev);
tp = netdev_priv(dev);
tp->msg_enable = netif_msg_init(debug.msg_enable, R8169_MSG_DEFAULT);
/* enable device (incl. PCI PM wakeup and hotplug setup) */
rc = pci_enable_device(pdev);
if (rc) {
printk(KERN_ERR PFX "%s: enable failure\n", pci_name(pdev));
if (rc < 0) {
if (netif_msg_probe(tp)) {
printk(KERN_ERR PFX "%s: enable failure\n",
pci_name(pdev));
}
goto err_out_free_dev;
}
......@@ -1196,29 +1343,39 @@ rtl8169_init_board(struct pci_dev *pdev, struct net_device **dev_out,
pci_read_config_word(pdev, pm_cap + PCI_PM_CTRL, &pwr_command);
acpi_idle_state = pwr_command & PCI_PM_CTRL_STATE_MASK;
} else {
printk(KERN_ERR PFX
"Cannot find PowerManagement capability, aborting.\n");
if (netif_msg_probe(tp)) {
printk(KERN_ERR PFX
"Cannot find PowerManagement capability. "
"Aborting.\n");
}
goto err_out_mwi;
}
/* make sure PCI base addr 1 is MMIO */
if (!(pci_resource_flags(pdev, 1) & IORESOURCE_MEM)) {
printk(KERN_ERR PFX
"region #1 not an MMIO resource, aborting\n");
if (netif_msg_probe(tp)) {
printk(KERN_ERR PFX
"region #1 not an MMIO resource, aborting\n");
}
rc = -ENODEV;
goto err_out_mwi;
}
/* check for weird/broken PCI region reporting */
if (pci_resource_len(pdev, 1) < R8169_REGS_SIZE) {
printk(KERN_ERR PFX "Invalid PCI region size(s), aborting\n");
if (netif_msg_probe(tp)) {
printk(KERN_ERR PFX
"Invalid PCI region size(s), aborting\n");
}
rc = -ENODEV;
goto err_out_mwi;
}
rc = pci_request_regions(pdev, MODULENAME);
if (rc) {
printk(KERN_ERR PFX "%s: could not request regions.\n",
pci_name(pdev));
if (rc < 0) {
if (netif_msg_probe(tp)) {
printk(KERN_ERR PFX "%s: could not request regions.\n",
pci_name(pdev));
}
goto err_out_mwi;
}
......@@ -1231,7 +1388,10 @@ rtl8169_init_board(struct pci_dev *pdev, struct net_device **dev_out,
} else {
rc = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
if (rc < 0) {
printk(KERN_ERR PFX "DMA configuration failed.\n");
if (netif_msg_probe(tp)) {
printk(KERN_ERR PFX
"DMA configuration failed.\n");
}
goto err_out_free_res;
}
}
......@@ -1241,7 +1401,8 @@ rtl8169_init_board(struct pci_dev *pdev, struct net_device **dev_out,
/* ioremap MMIO region */
ioaddr = ioremap(pci_resource_start(pdev, 1), R8169_REGS_SIZE);
if (ioaddr == NULL) {
printk(KERN_ERR PFX "cannot remap MMIO, aborting\n");
if (netif_msg_probe(tp))
printk(KERN_ERR PFX "cannot remap MMIO, aborting\n");
rc = -EIO;
goto err_out_free_res;
}
......@@ -1272,9 +1433,11 @@ rtl8169_init_board(struct pci_dev *pdev, struct net_device **dev_out,
}
if (i < 0) {
/* Unknown chip: assume array element #0, original RTL-8169 */
printk(KERN_DEBUG PFX
"PCI device %s: unknown chip version, assuming %s\n",
pci_name(pdev), rtl_chip_info[0].name);
if (netif_msg_probe(tp)) {
printk(KERN_DEBUG PFX "PCI device %s: "
"unknown chip version, assuming %s\n",
pci_name(pdev), rtl_chip_info[0].name);
}
i++;
}
tp->chipset = i;
......@@ -1308,7 +1471,6 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
struct rtl8169_private *tp;
void __iomem *ioaddr = NULL;
static int board_idx = -1;
static int printed_version = 0;
u8 autoneg, duplex;
u16 speed;
int i, rc;
......@@ -1318,10 +1480,9 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
board_idx++;
if (!printed_version) {
if (netif_msg_drv(&debug)) {
printk(KERN_INFO "%s Gigabit Ethernet driver %s loaded\n",
MODULENAME, RTL8169_VERSION);
printed_version = 1;
}
rc = rtl8169_init_board(pdev, &dev, &ioaddr);
......@@ -1366,7 +1527,6 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
#ifdef CONFIG_R8169_NAPI
dev->poll = rtl8169_poll;
dev->weight = R8169_NAPI_WEIGHT;
printk(KERN_INFO PFX "NAPI enabled\n");
#endif
#ifdef CONFIG_R8169_VLAN
......@@ -1391,20 +1551,24 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
return rc;
}
printk(KERN_DEBUG "%s: Identified chip type is '%s'.\n", dev->name,
rtl_chip_info[tp->chipset].name);
if (netif_msg_probe(tp)) {
printk(KERN_DEBUG "%s: Identified chip type is '%s'.\n",
dev->name, rtl_chip_info[tp->chipset].name);
}
pci_set_drvdata(pdev, dev);
printk(KERN_INFO "%s: %s at 0x%lx, "
"%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x, "
"IRQ %d\n",
dev->name,
rtl_chip_info[ent->driver_data].name,
dev->base_addr,
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->irq);
if (netif_msg_probe(tp)) {
printk(KERN_INFO "%s: %s at 0x%lx, "
"%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x, "
"IRQ %d\n",
dev->name,
rtl_chip_info[ent->driver_data].name,
dev->base_addr,
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->irq);
}
rtl8169_hw_phy_config(dev);
......@@ -1427,7 +1591,7 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
rtl8169_set_speed(dev, autoneg, speed, duplex);
if (RTL_R8(PHYstatus) & TBI_Enable)
if ((RTL_R8(PHYstatus) & TBI_Enable) && netif_msg_link(tp))
printk(KERN_INFO PFX "%s: TBI auto-negotiating\n", dev->name);
return 0;
......@@ -1860,8 +2024,13 @@ static void rtl8169_reinit_task(void *_data)
ret = rtl8169_open(dev);
if (unlikely(ret < 0)) {
if (net_ratelimit()) {
printk(PFX KERN_ERR "%s: reinit failure (status = %d)."
" Rescheduling.\n", dev->name, ret);
struct rtl8169_private *tp = netdev_priv(dev);
if (netif_msg_drv(tp)) {
printk(PFX KERN_ERR
"%s: reinit failure (status = %d)."
" Rescheduling.\n", dev->name, ret);
}
}
rtl8169_schedule_work(dev, rtl8169_reinit_task);
}
......@@ -1886,8 +2055,12 @@ static void rtl8169_reset_task(void *_data)
netif_wake_queue(dev);
} else {
if (net_ratelimit()) {
printk(PFX KERN_EMERG "%s: Rx buffers shortage\n",
dev->name);
struct rtl8169_private *tp = netdev_priv(dev);
if (netif_msg_intr(tp)) {
printk(PFX KERN_EMERG
"%s: Rx buffers shortage\n", dev->name);
}
}
rtl8169_schedule_work(dev, rtl8169_reset_task);
}
......@@ -1973,8 +2146,11 @@ static int rtl8169_start_xmit(struct sk_buff *skb, struct net_device *dev)
int ret = 0;
if (unlikely(TX_BUFFS_AVAIL(tp) < skb_shinfo(skb)->nr_frags)) {
printk(KERN_ERR PFX "%s: BUG! Tx Ring full when queue awake!\n",
dev->name);
if (netif_msg_drv(tp)) {
printk(KERN_ERR
"%s: BUG! Tx Ring full when queue awake!\n",
dev->name);
}
goto err_stop;
}
......@@ -2049,8 +2225,11 @@ static void rtl8169_pcierr_interrupt(struct net_device *dev)
pci_read_config_word(pdev, PCI_COMMAND, &pci_cmd);
pci_read_config_word(pdev, PCI_STATUS, &pci_status);
printk(KERN_ERR PFX "%s: PCI error (cmd = 0x%04x, status = 0x%04x).\n",
dev->name, pci_cmd, pci_status);
if (netif_msg_intr(tp)) {
printk(KERN_ERR
"%s: PCI error (cmd = 0x%04x, status = 0x%04x).\n",
dev->name, pci_cmd, pci_status);
}
/*
* The recovery sequence below admits a very elaborated explanation:
......@@ -2069,7 +2248,8 @@ static void rtl8169_pcierr_interrupt(struct net_device *dev)
/* The infamous DAC f*ckup only happens at boot time */
if ((tp->cp_cmd & PCIDAC) && !tp->dirty_rx && !tp->cur_rx) {
printk(KERN_INFO PFX "%s: disabling PCI DAC.\n", dev->name);
if (netif_msg_intr(tp))
printk(KERN_INFO "%s: disabling PCI DAC.\n", dev->name);
tp->cp_cmd &= ~PCIDAC;
RTL_W16(CPlusCmd, tp->cp_cmd);
dev->features &= ~NETIF_F_HIGHDMA;
......@@ -2180,7 +2360,7 @@ rtl8169_rx_interrupt(struct net_device *dev, struct rtl8169_private *tp,
rx_left = NUM_RX_DESC + tp->dirty_rx - cur_rx;
rx_left = rtl8169_rx_quota(rx_left, (u32) dev->quota);
while (rx_left > 0) {
for (; rx_left > 0; rx_left--, cur_rx++) {
unsigned int entry = cur_rx % NUM_RX_DESC;
struct RxDesc *desc = tp->RxDescArray + entry;
u32 status;
......@@ -2190,9 +2370,12 @@ rtl8169_rx_interrupt(struct net_device *dev, struct rtl8169_private *tp,
if (status & DescOwn)
break;
if (status & RxRES) {
printk(KERN_INFO "%s: Rx ERROR. status = %08x\n",
dev->name, status);
if (unlikely(status & RxRES)) {
if (netif_msg_rx_err(tp)) {
printk(KERN_INFO
"%s: Rx ERROR. status = %08x\n",
dev->name, status);
}
tp->stats.rx_errors++;
if (status & (RxRWT | RxRUNT))
tp->stats.rx_length_errors++;
......@@ -2214,7 +2397,7 @@ rtl8169_rx_interrupt(struct net_device *dev, struct rtl8169_private *tp,
tp->stats.rx_dropped++;
tp->stats.rx_length_errors++;
rtl8169_mark_to_asic(desc, tp->rx_buf_sz);
goto move_on;
continue;
}
rtl8169_rx_csum(skb, desc);
......@@ -2243,16 +2426,13 @@ rtl8169_rx_interrupt(struct net_device *dev, struct rtl8169_private *tp,
tp->stats.rx_bytes += pkt_size;
tp->stats.rx_packets++;
}
move_on:
cur_rx++;
rx_left--;
}
count = cur_rx - tp->cur_rx;
tp->cur_rx = cur_rx;
delta = rtl8169_rx_fill(tp, dev, tp->dirty_rx, tp->cur_rx);
if (!delta && count)
if (!delta && count && netif_msg_intr(tp))
printk(KERN_INFO "%s: no Rx buffer allocated\n", dev->name);
tp->dirty_rx += delta;
......@@ -2263,7 +2443,7 @@ rtl8169_rx_interrupt(struct net_device *dev, struct rtl8169_private *tp,
* after refill ?
* - how do others driver handle this condition (Uh oh...).
*/
if (tp->dirty_rx + NUM_RX_DESC == tp->cur_rx)
if ((tp->dirty_rx + NUM_RX_DESC == tp->cur_rx) && netif_msg_intr(tp))
printk(KERN_EMERG "%s: Rx buffers exhausted\n", dev->name);
return count;
......@@ -2315,7 +2495,7 @@ rtl8169_interrupt(int irq, void *dev_instance, struct pt_regs *regs)
if (likely(netif_rx_schedule_prep(dev)))
__netif_rx_schedule(dev);
else {
else if (netif_msg_intr(tp)) {
printk(KERN_INFO "%s: interrupt %04x taken in poll\n",
dev->name, status);
}
......@@ -2334,8 +2514,10 @@ rtl8169_interrupt(int irq, void *dev_instance, struct pt_regs *regs)
} while (boguscnt > 0);
if (boguscnt <= 0) {
printk(KERN_WARNING "%s: Too much work at interrupt!\n",
dev->name);
if (net_ratelimit() && netif_msg_intr(tp)) {
printk(KERN_WARNING
"%s: Too much work at interrupt!\n", dev->name);
}
/* Clear all interrupt sources. */
RTL_W16(IntrStatus, 0xffff);
}
......@@ -2458,8 +2640,10 @@ rtl8169_set_rx_mode(struct net_device *dev)
if (dev->flags & IFF_PROMISC) {
/* Unconditionally log net taps. */
printk(KERN_NOTICE "%s: Promiscuous mode enabled.\n",
dev->name);
if (netif_msg_link(tp)) {
printk(KERN_NOTICE "%s: Promiscuous mode enabled.\n",
dev->name);
}
rx_mode =
AcceptBroadcast | AcceptMulticast | AcceptMyPhys |
AcceptAllPhys;
......
......@@ -4212,7 +4212,7 @@ SK_BOOL DualNet;
Flags);
SkGeStopPort(pAC, IoC, FromPort, SK_STOP_ALL, SK_HARD_RST);
pAC->dev[Param.Para32[0]]->flags &= ~IFF_RUNNING;
netif_carrier_off(pAC->dev[Param.Para32[0]]);
spin_unlock_irqrestore(
&pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock,
Flags);
......@@ -4355,7 +4355,7 @@ SK_BOOL DualNet;
}
/* Inform the world that link protocol is up. */
pAC->dev[Param.Para32[0]]->flags |= IFF_RUNNING;
netif_carrier_on(pAC->dev[Param.Para32[0]]);
break;
case SK_DRV_NET_DOWN: /* SK_U32 Reason */
......@@ -4368,7 +4368,7 @@ SK_BOOL DualNet;
} else {
DoPrintInterfaceChange = SK_TRUE;
}
pAC->dev[Param.Para32[1]]->flags &= ~IFF_RUNNING;
netif_carrier_off(pAC->dev[Param.Para32[1]]);
break;
case SK_DRV_SWITCH_HARD: /* SK_U32 FromPortIdx SK_U32 ToPortIdx */
SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT,
......@@ -4961,7 +4961,6 @@ static int __devinit skge_probe_one(struct pci_dev *pdev,
#ifdef CONFIG_NET_POLL_CONTROLLER
dev->poll_controller = &SkGePollController;
#endif
dev->flags &= ~IFF_RUNNING;
SET_NETDEV_DEV(dev, &pdev->dev);
SET_ETHTOOL_OPS(dev, &SkGeEthtoolOps);
......@@ -5035,7 +5034,6 @@ static int __devinit skge_probe_one(struct pci_dev *pdev,
dev->set_mac_address = &SkGeSetMacAddr;
dev->do_ioctl = &SkGeIoctl;
dev->change_mtu = &SkGeChangeMtu;
dev->flags &= ~IFF_RUNNING;
SET_NETDEV_DEV(dev, &pdev->dev);
SET_ETHTOOL_OPS(dev, &SkGeEthtoolOps);
......
此差异已折叠。
/*-
*
* This software may be used and distributed according to the terms
* of the GNU General Public License, incorporated herein by reference.
*
* Module : sk_g16.h
* Version : $Revision$
*
* Author : M.Hipp (mhipp@student.uni-tuebingen.de)
* changes by : Patrick J.D. Weichmann
*
* Date Created : 94/05/25
*
* Description : In here are all necessary definitions of
* the am7990 (LANCE) chip used for writing a
* network device driver which uses this chip
*
* $Log$
-*/
#ifndef SK_G16_H
#define SK_G16_H
/*
* Control and Status Register 0 (CSR0) bit definitions
*
* (R=Readable) (W=Writeable) (S=Set on write) (C-Clear on write)
*
*/
#define CSR0_ERR 0x8000 /* Error summary (R) */
#define CSR0_BABL 0x4000 /* Babble transmitter timeout error (RC) */
#define CSR0_CERR 0x2000 /* Collision Error (RC) */
#define CSR0_MISS 0x1000 /* Missed packet (RC) */
#define CSR0_MERR 0x0800 /* Memory Error (RC) */
#define CSR0_RINT 0x0400 /* Receiver Interrupt (RC) */
#define CSR0_TINT 0x0200 /* Transmit Interrupt (RC) */
#define CSR0_IDON 0x0100 /* Initialization Done (RC) */
#define CSR0_INTR 0x0080 /* Interrupt Flag (R) */
#define CSR0_INEA 0x0040 /* Interrupt Enable (RW) */
#define CSR0_RXON 0x0020 /* Receiver on (R) */
#define CSR0_TXON 0x0010 /* Transmitter on (R) */
#define CSR0_TDMD 0x0008 /* Transmit Demand (RS) */
#define CSR0_STOP 0x0004 /* Stop (RS) */
#define CSR0_STRT 0x0002 /* Start (RS) */
#define CSR0_INIT 0x0001 /* Initialize (RS) */
#define CSR0_CLRALL 0x7f00 /* mask for all clearable bits */
/*
* Control and Status Register 3 (CSR3) bit definitions
*
*/
#define CSR3_BSWAP 0x0004 /* Byte Swap (RW) */
#define CSR3_ACON 0x0002 /* ALE Control (RW) */
#define CSR3_BCON 0x0001 /* Byte Control (RW) */
/*
* Initialization Block Mode operation Bit Definitions.
*/
#define MODE_PROM 0x8000 /* Promiscuous Mode */
#define MODE_INTL 0x0040 /* Internal Loopback */
#define MODE_DRTY 0x0020 /* Disable Retry */
#define MODE_COLL 0x0010 /* Force Collision */
#define MODE_DTCR 0x0008 /* Disable Transmit CRC) */
#define MODE_LOOP 0x0004 /* Loopback */
#define MODE_DTX 0x0002 /* Disable the Transmitter */
#define MODE_DRX 0x0001 /* Disable the Receiver */
#define MODE_NORMAL 0x0000 /* Normal operation mode */
/*
* Receive message descriptor status bit definitions.
*/
#define RX_OWN 0x80 /* Owner bit 0 = host, 1 = lance */
#define RX_ERR 0x40 /* Error Summary */
#define RX_FRAM 0x20 /* Framing Error */
#define RX_OFLO 0x10 /* Overflow Error */
#define RX_CRC 0x08 /* CRC Error */
#define RX_BUFF 0x04 /* Buffer Error */
#define RX_STP 0x02 /* Start of Packet */
#define RX_ENP 0x01 /* End of Packet */
/*
* Transmit message descriptor status bit definitions.
*/
#define TX_OWN 0x80 /* Owner bit 0 = host, 1 = lance */
#define TX_ERR 0x40 /* Error Summary */
#define TX_MORE 0x10 /* More the 1 retry needed to Xmit */
#define TX_ONE 0x08 /* One retry needed to Xmit */
#define TX_DEF 0x04 /* Deferred */
#define TX_STP 0x02 /* Start of Packet */
#define TX_ENP 0x01 /* End of Packet */
/*
* Transmit status (2) (valid if TX_ERR == 1)
*/
#define TX_BUFF 0x8000 /* Buffering error (no ENP) */
#define TX_UFLO 0x4000 /* Underflow (late memory) */
#define TX_LCOL 0x1000 /* Late collision */
#define TX_LCAR 0x0400 /* Loss of Carrier */
#define TX_RTRY 0x0200 /* Failed after 16 retransmissions */
#define TX_TDR 0x003f /* Time-domain-reflectometer-value */
/*
* Structures used for Communication with the LANCE
*/
/* LANCE Initialize Block */
struct init_block
{
unsigned short mode; /* Mode Register */
unsigned char paddr[6]; /* Physical Address (MAC) */
unsigned char laddr[8]; /* Logical Filter Address (not used) */
unsigned int rdrp; /* Receive Descriptor Ring pointer */
unsigned int tdrp; /* Transmit Descriptor Ring pointer */
};
/* Receive Message Descriptor Entry */
struct rmd
{
union
{
unsigned long buffer; /* Address of buffer */
struct
{
unsigned char unused[3];
unsigned volatile char status; /* Status Bits */
} s;
} u;
volatile short blen; /* Buffer Length (two's complement) */
unsigned short mlen; /* Message Byte Count */
};
/* Transmit Message Descriptor Entry */
struct tmd
{
union
{
unsigned long buffer; /* Address of buffer */
struct
{
unsigned char unused[3];
unsigned volatile char status; /* Status Bits */
} s;
} u;
unsigned short blen; /* Buffer Length (two's complement) */
unsigned volatile short status2; /* Error Status Bits */
};
#endif /* End of SK_G16_H */
此差异已折叠。
此差异已折叠。
......@@ -129,7 +129,7 @@ MODULE_PARM_DESC(nowait, "set to 1 for no wait state");
/*
* Transmit timeout, default 5 seconds.
*/
static int watchdog = 5000;
static int watchdog = 1000;
module_param(watchdog, int, 0400);
MODULE_PARM_DESC(watchdog, "transmit timeout in milliseconds");
......@@ -660,15 +660,14 @@ static void smc_hardware_send_pkt(unsigned long data)
SMC_outw(((len & 1) ? (0x2000 | buf[len-1]) : 0), ioaddr, DATA_REG);
/*
* If THROTTLE_TX_PKTS is set, we look at the TX_EMPTY flag
* before queueing this packet for TX, and if it's clear then
* we stop the queue here. This will have the effect of
* having at most 2 packets queued for TX in the chip's memory
* at all time. If THROTTLE_TX_PKTS is not set then the queue
* is stopped only when memory allocation (MC_ALLOC) does not
* succeed right away.
* If THROTTLE_TX_PKTS is set, we stop the queue here. This will
* have the effect of having at most one packet queued for TX
* in the chip's memory at all time.
*
* If THROTTLE_TX_PKTS is not set then the queue is stopped only
* when memory allocation (MC_ALLOC) does not succeed right away.
*/
if (THROTTLE_TX_PKTS && !(SMC_GET_INT() & IM_TX_EMPTY_INT))
if (THROTTLE_TX_PKTS)
netif_stop_queue(dev);
/* queue the packet for TX */
......@@ -792,17 +791,20 @@ static void smc_tx(struct net_device *dev)
DBG(2, "%s: TX STATUS 0x%04x PNR 0x%02x\n",
dev->name, tx_status, packet_no);
if (!(tx_status & TS_SUCCESS))
if (!(tx_status & ES_TX_SUC))
lp->stats.tx_errors++;
if (tx_status & TS_LOSTCAR)
if (tx_status & ES_LOSTCARR)
lp->stats.tx_carrier_errors++;
if (tx_status & TS_LATCOL) {
PRINTK("%s: late collision occurred on last xmit\n", dev->name);
if (tx_status & (ES_LATCOL | ES_16COL)) {
PRINTK("%s: %s occurred on last xmit\n", dev->name,
(tx_status & ES_LATCOL) ?
"late collision" : "too many collisions");
lp->stats.tx_window_errors++;
if (!(lp->stats.tx_window_errors & 63) && net_ratelimit()) {
printk(KERN_INFO "%s: unexpectedly large numbers of "
"late collisions. Please check duplex "
printk(KERN_INFO "%s: unexpectedly large number of "
"bad collisions. Please check duplex "
"setting.\n", dev->name);
}
}
......@@ -1236,7 +1238,7 @@ static void smc_10bt_check_media(struct net_device *dev, int init)
old_carrier = netif_carrier_ok(dev) ? 1 : 0;
SMC_SELECT_BANK(0);
new_carrier = SMC_inw(ioaddr, EPH_STATUS_REG) & ES_LINK_OK ? 1 : 0;
new_carrier = (SMC_GET_EPH_STATUS() & ES_LINK_OK) ? 1 : 0;
SMC_SELECT_BANK(2);
if (init || (old_carrier != new_carrier)) {
......@@ -1308,15 +1310,16 @@ static irqreturn_t smc_interrupt(int irq, void *dev_id, struct pt_regs *regs)
if (!status)
break;
if (status & IM_RCV_INT) {
DBG(3, "%s: RX irq\n", dev->name);
smc_rcv(dev);
} else if (status & IM_TX_INT) {
if (status & IM_TX_INT) {
/* do this before RX as it will free memory quickly */
DBG(3, "%s: TX int\n", dev->name);
smc_tx(dev);
SMC_ACK_INT(IM_TX_INT);
if (THROTTLE_TX_PKTS)
netif_wake_queue(dev);
} else if (status & IM_RCV_INT) {
DBG(3, "%s: RX irq\n", dev->name);
smc_rcv(dev);
} else if (status & IM_ALLOC_INT) {
DBG(3, "%s: Allocation irq\n", dev->name);
tasklet_hi_schedule(&lp->tx_task);
......@@ -1337,7 +1340,10 @@ static irqreturn_t smc_interrupt(int irq, void *dev_id, struct pt_regs *regs)
/* multiple collisions */
lp->stats.collisions += card_stats & 0xF;
} else if (status & IM_RX_OVRN_INT) {
DBG(1, "%s: RX overrun\n", dev->name);
DBG(1, "%s: RX overrun (EPH_ST 0x%04x)\n", dev->name,
({ int eph_st; SMC_SELECT_BANK(0);
eph_st = SMC_GET_EPH_STATUS();
SMC_SELECT_BANK(2); eph_st; }) );
SMC_ACK_INT(IM_RX_OVRN_INT);
lp->stats.rx_errors++;
lp->stats.rx_fifo_errors++;
......@@ -1389,7 +1395,7 @@ static void smc_timeout(struct net_device *dev)
{
struct smc_local *lp = netdev_priv(dev);
void __iomem *ioaddr = lp->base;
int status, mask, meminfo, fifo;
int status, mask, eph_st, meminfo, fifo;
DBG(2, "%s: %s\n", dev->name, __FUNCTION__);
......@@ -1398,11 +1404,13 @@ static void smc_timeout(struct net_device *dev)
mask = SMC_GET_INT_MASK();
fifo = SMC_GET_FIFO();
SMC_SELECT_BANK(0);
eph_st = SMC_GET_EPH_STATUS();
meminfo = SMC_GET_MIR();
SMC_SELECT_BANK(2);
spin_unlock_irq(&lp->lock);
PRINTK( "%s: INT 0x%02x MASK 0x%02x MEM 0x%04x FIFO 0x%04x\n",
dev->name, status, mask, meminfo, fifo );
PRINTK( "%s: TX timeout (INT 0x%02x INTMASK 0x%02x "
"MEM 0x%04x FIFO 0x%04x EPH_ST 0x%04x)\n",
dev->name, status, mask, meminfo, fifo, eph_st );
smc_reset(dev);
smc_enable(dev);
......@@ -1863,7 +1871,7 @@ static int __init smc_probe(struct net_device *dev, void __iomem *ioaddr)
SMC_SELECT_BANK(1);
val = SMC_GET_BASE();
val = ((val & 0x1F00) >> 3) << SMC_IO_SHIFT;
if (((unsigned long)ioaddr & ((PAGE_SIZE-1)<<SMC_IO_SHIFT)) != val) { /*XXX: WTF? */
if (((unsigned int)ioaddr & (0x3e0 << SMC_IO_SHIFT)) != val) {
printk("%s: IOADDR %p doesn't match configuration (%x).\n",
CARDNAME, ioaddr, val);
}
......
......@@ -151,7 +151,7 @@
/* We actually can't write halfwords properly if not word aligned */
static inline void
SMC_outw(u16 val, unsigned long ioaddr, int reg)
SMC_outw(u16 val, void __iomem *ioaddr, int reg)
{
if (reg & 2) {
unsigned int v = val << 16;
......@@ -317,7 +317,7 @@ static inline void SMC_outsw (unsigned long a, int r, unsigned char* p, int l)
#define SMC_insl(a, r, p, l) \
smc_pxa_dma_insl(a, lp->physaddr, r, dev->dma, p, l)
static inline void
smc_pxa_dma_insl(u_long ioaddr, u_long physaddr, int reg, int dma,
smc_pxa_dma_insl(void __iomem *ioaddr, u_long physaddr, int reg, int dma,
u_char *buf, int len)
{
dma_addr_t dmabuf;
......@@ -355,7 +355,7 @@ smc_pxa_dma_insl(u_long ioaddr, u_long physaddr, int reg, int dma,
#define SMC_insw(a, r, p, l) \
smc_pxa_dma_insw(a, lp->physaddr, r, dev->dma, p, l)
static inline void
smc_pxa_dma_insw(u_long ioaddr, u_long physaddr, int reg, int dma,
smc_pxa_dma_insw(void __iomem *ioaddr, u_long physaddr, int reg, int dma,
u_char *buf, int len)
{
dma_addr_t dmabuf;
......@@ -680,14 +680,6 @@ static const char * chip_ids[ 16 ] = {
NULL, NULL, NULL};
/*
. Transmit status bits
*/
#define TS_SUCCESS 0x0001
#define TS_LOSTCAR 0x0400
#define TS_LATCOL 0x0200
#define TS_16COL 0x0010
/*
. Receive status bits
*/
......@@ -845,6 +837,7 @@ static const char * chip_ids[ 16 ] = {
#define SMC_GET_FIFO() SMC_inw( ioaddr, FIFO_REG )
#define SMC_GET_PTR() SMC_inw( ioaddr, PTR_REG )
#define SMC_SET_PTR(x) SMC_outw( x, ioaddr, PTR_REG )
#define SMC_GET_EPH_STATUS() SMC_inw( ioaddr, EPH_STATUS_REG )
#define SMC_GET_RCR() SMC_inw( ioaddr, RCR_REG )
#define SMC_SET_RCR(x) SMC_outw( x, ioaddr, RCR_REG )
#define SMC_GET_REV() SMC_inw( ioaddr, REV_REG )
......
......@@ -2,7 +2,7 @@
/*
Written 1998-2000 by Donald Becker.
Current maintainer is Ion Badulescu <ionut@cs.columbia.edu>. Please
Current maintainer is Ion Badulescu <ionut ta badula tod org>. Please
send all bug reports to me, and not to Donald Becker, as this code
has been heavily modified from Donald's original version.
......@@ -129,12 +129,18 @@
- put the chip to a D3 slumber on driver unload
- added config option to enable/disable NAPI
TODO: bugfixes (no bugs known as of right now)
LK1.4.2 (Ion Badulescu)
- finally added firmware (GPL'ed by Adaptec)
- removed compatibility code for 2.2.x
TODO: - fix forced speed/duplexing code (broken a long time ago, when
somebody converted the driver to use the generic MII code)
- fix VLAN support
*/
#define DRV_NAME "starfire"
#define DRV_VERSION "1.03+LK1.4.1"
#define DRV_RELDATE "February 10, 2002"
#define DRV_VERSION "1.03+LK1.4.2"
#define DRV_RELDATE "January 19, 2005"
#include <linux/config.h>
#include <linux/version.h>
......@@ -145,25 +151,15 @@ TODO: bugfixes (no bugs known as of right now)
#include <linux/etherdevice.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/crc32.h>
#include <linux/ethtool.h>
#include <linux/mii.h>
#include <linux/if_vlan.h>
#include <asm/processor.h> /* Processor type for cache alignment. */
#include <asm/uaccess.h>
#include <asm/io.h>
/*
* Adaptec's license for their drivers (which is where I got the
* firmware files) does not allow one to redistribute them. Thus, we can't
* include the firmware with this driver.
*
* However, should a legal-to-distribute firmware become available,
* the driver developer would need only to obtain the firmware in the
* form of a C header file.
* Once that's done, the #undef below must be changed into a #define
* for this driver to really use the firmware. Note that Rx/Tx
* hardware TCP checksumming is not possible without the firmware.
*
* WANTED: legal firmware to include with this GPL'd driver.
*/
#undef HAS_FIRMWARE
#include "starfire_firmware.h"
/*
* The current frame processor firmware fails to checksum a fragment
* of length 1. If and when this is fixed, the #define below can be removed.
......@@ -172,13 +168,7 @@ TODO: bugfixes (no bugs known as of right now)
/*
* Define this if using the driver with the zero-copy patch
*/
#if defined(HAS_FIRMWARE) && defined(MAX_SKB_FRAGS)
#define ZEROCOPY
#endif
#ifdef HAS_FIRMWARE
#include "starfire_firmware.h"
#endif /* HAS_FIRMWARE */
#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
#define VLAN_SUPPORT
......@@ -202,11 +192,7 @@ static int mtu;
The Starfire has a 512 element hash table based on the Ethernet CRC. */
static int multicast_filter_limit = 512;
/* Whether to do TCP/UDP checksums in hardware */
#ifdef HAS_FIRMWARE
static int enable_hw_cksum = 1;
#else
static int enable_hw_cksum = 0;
#endif
#define PKT_BUF_SZ 1536 /* Size of each temporary Rx buffer.*/
/*
......@@ -291,43 +277,15 @@ static int full_duplex[MAX_UNITS] = {0, };
#define RX_DESC_ADDR_SIZE RxDescAddr32bit
#endif
#ifdef MAX_SKB_FRAGS
#define skb_first_frag_len(skb) skb_headlen(skb)
#define skb_num_frags(skb) (skb_shinfo(skb)->nr_frags + 1)
#else /* not MAX_SKB_FRAGS */
#define skb_first_frag_len(skb) (skb->len)
#define skb_num_frags(skb) 1
#endif /* not MAX_SKB_FRAGS */
/* 2.2.x compatibility code */
#if LINUX_VERSION_CODE < 0x20300
#include "starfire-kcomp22.h"
#else /* LINUX_VERSION_CODE > 0x20300 */
#include <linux/crc32.h>
#include <linux/ethtool.h>
#include <linux/mii.h>
#include <linux/if_vlan.h>
#define init_tx_timer(dev, func, timeout) \
dev->tx_timeout = func; \
dev->watchdog_timeo = timeout;
#define kick_tx_timer(dev, func, timeout)
#define netif_start_if(dev)
#define netif_stop_if(dev)
#define PCI_SLOT_NAME(pci_dev) pci_name(pci_dev)
#endif /* LINUX_VERSION_CODE > 0x20300 */
#ifdef HAVE_NETDEV_POLL
#define init_poll(dev) \
do { \
dev->poll = &netdev_poll; \
dev->weight = max_interrupt_work;
dev->weight = max_interrupt_work; \
} while (0)
#define netdev_rx(dev, ioaddr) \
do { \
u32 intr_enable; \
......@@ -341,7 +299,7 @@ do { \
/* Paranoia check */ \
intr_enable = readl(ioaddr + IntrEnable); \
if (intr_enable & (IntrRxDone | IntrRxEmpty)) { \
printk("%s: interrupt while in polling mode!\n", dev->name); \
printk(KERN_INFO "%s: interrupt while in polling mode!\n", dev->name); \
intr_enable &= ~(IntrRxDone | IntrRxEmpty); \
writel(intr_enable, ioaddr + IntrEnable); \
} \
......@@ -371,6 +329,7 @@ KERN_INFO " (unofficial 2.2/2.4 kernel port, version " DRV_VERSION ", " DRV_RELD
MODULE_AUTHOR("Donald Becker <becker@scyld.com>");
MODULE_DESCRIPTION("Adaptec Starfire Ethernet driver");
MODULE_LICENSE("GPL");
MODULE_VERSION(DRV_VERSION);
module_param(max_interrupt_work, int, 0);
module_param(mtu, int, 0);
......@@ -425,7 +384,7 @@ on the 32/64 bitness of the architecture), and relies on automatic
minimum-length padding. It does not use the completion queue
consumer index, but instead checks for non-zero status entries.
For receive this driver uses type 0/1/2/3 receive descriptors. The driver
For receive this driver uses type 2/3 receive descriptors. The driver
allocates full frame size skbuffs for the Rx ring buffers, so all frames
should fit in a single descriptor. The driver does not use the completion
queue consumer index, but instead checks for non-zero status entries.
......@@ -476,7 +435,7 @@ IVc. Errata
*/
enum chip_capability_flags {CanHaveMII=1, };
......@@ -670,7 +629,6 @@ struct full_rx_done_desc {
u32 timestamp;
};
/* XXX: this is ugly and I'm not sure it's worth the trouble -Ion */
#ifdef HAS_FIRMWARE
#ifdef VLAN_SUPPORT
typedef struct full_rx_done_desc rx_done_desc;
#define RxComplType RxComplType3
......@@ -678,15 +636,6 @@ typedef struct full_rx_done_desc rx_done_desc;
typedef struct csum_rx_done_desc rx_done_desc;
#define RxComplType RxComplType2
#endif /* not VLAN_SUPPORT */
#else /* not HAS_FIRMWARE */
#ifdef VLAN_SUPPORT
typedef struct basic_rx_done_desc rx_done_desc;
#define RxComplType RxComplType1
#else /* not VLAN_SUPPORT */
typedef struct short_rx_done_desc rx_done_desc;
#define RxComplType RxComplType0
#endif /* not VLAN_SUPPORT */
#endif /* not HAS_FIRMWARE */
enum rx_done_bits {
RxOK=0x20000000, RxFIFOErr=0x10000000, RxBufQ2=0x08000000,
......@@ -898,13 +847,10 @@ static int __devinit starfire_init_one(struct pci_dev *pdev,
/* enable MWI -- it vastly improves Rx performance on sparc64 */
pci_set_mwi(pdev);
#ifdef MAX_SKB_FRAGS
dev->features |= NETIF_F_SG;
#endif /* MAX_SKB_FRAGS */
#ifdef ZEROCOPY
/* Starfire can do TCP/UDP checksumming */
if (enable_hw_cksum)
dev->features |= NETIF_F_IP_CSUM;
dev->features |= NETIF_F_IP_CSUM | NETIF_F_SG;
#endif /* ZEROCOPY */
#ifdef VLAN_SUPPORT
dev->features |= NETIF_F_HW_VLAN_RX | NETIF_F_HW_VLAN_FILTER;
......@@ -1008,7 +954,8 @@ static int __devinit starfire_init_one(struct pci_dev *pdev,
/* The chip-specific entries in the device structure. */
dev->open = &netdev_open;
dev->hard_start_xmit = &start_tx;
init_tx_timer(dev, tx_timeout, TX_TIMEOUT);
dev->tx_timeout = tx_timeout;
dev->watchdog_timeo = TX_TIMEOUT;
init_poll(dev);
dev->stop = &netdev_close;
dev->get_stats = &get_stats;
......@@ -1039,7 +986,7 @@ static int __devinit starfire_init_one(struct pci_dev *pdev,
if ((mdio_read(dev, phy, MII_BMCR) & BMCR_RESET) == 0)
break;
if (boguscnt == 0) {
printk("%s: PHY reset never completed!\n", dev->name);
printk("%s: PHY#%d reset never completed!\n", dev->name, phy);
continue;
}
mii_status = mdio_read(dev, phy, MII_BMSR);
......@@ -1110,6 +1057,7 @@ static int netdev_open(struct net_device *dev)
size_t tx_done_q_size, rx_done_q_size, tx_ring_size, rx_ring_size;
/* Do we ever need to reset the chip??? */
retval = request_irq(dev->irq, &intr_handler, SA_SHIRQ, dev->name, dev);
if (retval)
return retval;
......@@ -1211,7 +1159,6 @@ static int netdev_open(struct net_device *dev)
writel(np->intr_timer_ctrl, ioaddr + IntrTimerCtrl);
netif_start_if(dev);
netif_start_queue(dev);
if (debug > 1)
......@@ -1238,13 +1185,11 @@ static int netdev_open(struct net_device *dev)
writel(ETH_P_8021Q, ioaddr + VlanType);
#endif /* VLAN_SUPPORT */
#ifdef HAS_FIRMWARE
/* Load Rx/Tx firmware into the frame processors */
for (i = 0; i < FIRMWARE_RX_SIZE * 2; i++)
writel(firmware_rx[i], ioaddr + RxGfpMem + i * 4);
for (i = 0; i < FIRMWARE_TX_SIZE * 2; i++)
writel(firmware_tx[i], ioaddr + TxGfpMem + i * 4);
#endif /* HAS_FIRMWARE */
if (enable_hw_cksum)
/* Enable the Rx and Tx units, and the Rx/Tx frame processors. */
writel(TxEnable|TxGFPEnable|RxEnable|RxGFPEnable, ioaddr + GenCtrl);
......@@ -1378,8 +1323,6 @@ static int start_tx(struct sk_buff *skb, struct net_device *dev)
u32 status;
int i;
kick_tx_timer(dev, tx_timeout, TX_TIMEOUT);
/*
* be cautious here, wrapping the queue has weird semantics
* and we may not have enough slots even when it seems we do.
......@@ -1404,7 +1347,7 @@ static int start_tx(struct sk_buff *skb, struct net_device *dev)
}
if (has_bad_length)
skb_checksum_help(skb);
skb_checksum_help(skb, 0);
}
#endif /* ZEROCOPY && HAS_BROKEN_FIRMWARE */
......@@ -1433,12 +1376,10 @@ static int start_tx(struct sk_buff *skb, struct net_device *dev)
np->tx_info[entry].mapping =
pci_map_single(np->pci_dev, skb->data, skb_first_frag_len(skb), PCI_DMA_TODEVICE);
} else {
#ifdef MAX_SKB_FRAGS
skb_frag_t *this_frag = &skb_shinfo(skb)->frags[i - 1];
status |= this_frag->size;
np->tx_info[entry].mapping =
pci_map_single(np->pci_dev, page_address(this_frag->page) + this_frag->page_offset, this_frag->size, PCI_DMA_TODEVICE);
#endif /* MAX_SKB_FRAGS */
}
np->tx_ring[entry].addr = cpu_to_dma(np->tx_info[entry].mapping);
......@@ -1531,7 +1472,6 @@ static irqreturn_t intr_handler(int irq, void *dev_instance, struct pt_regs *rgs
np->tx_info[entry].mapping = 0;
np->dirty_tx += np->tx_info[entry].used_slots;
entry = (entry + np->tx_info[entry].used_slots) % TX_RING_SIZE;
#ifdef MAX_SKB_FRAGS
{
int i;
for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
......@@ -1543,7 +1483,7 @@ static irqreturn_t intr_handler(int irq, void *dev_instance, struct pt_regs *rgs
entry++;
}
}
#endif /* MAX_SKB_FRAGS */
dev_kfree_skb_irq(skb);
}
np->tx_done_q[np->tx_done].status = 0;
......@@ -1603,7 +1543,7 @@ static int __netdev_rx(struct net_device *dev, int *quota)
if (debug > 4)
printk(KERN_DEBUG " netdev_rx() status of %d was %#8.8x.\n", np->rx_done, desc_status);
if (!(desc_status & RxOK)) {
/* There was a error. */
/* There was an error. */
if (debug > 2)
printk(KERN_DEBUG " netdev_rx() Rx error was %#8.8x.\n", desc_status);
np->stats.rx_errors++;
......@@ -1656,11 +1596,10 @@ static int __netdev_rx(struct net_device *dev, int *quota)
#endif
skb->protocol = eth_type_trans(skb, dev);
#if defined(HAS_FIRMWARE) || defined(VLAN_SUPPORT)
#ifdef VLAN_SUPPORT
if (debug > 4)
printk(KERN_DEBUG " netdev_rx() status2 of %d was %#4.4x.\n", np->rx_done, le16_to_cpu(desc->status2));
#endif
#ifdef HAS_FIRMWARE
if (le16_to_cpu(desc->status2) & 0x0100) {
skb->ip_summed = CHECKSUM_UNNECESSARY;
np->stats.rx_compressed++;
......@@ -1679,7 +1618,6 @@ static int __netdev_rx(struct net_device *dev, int *quota)
skb->csum = le16_to_cpu(desc->csum);
printk(KERN_DEBUG "%s: checksum_hw, status2 = %#x\n", dev->name, le16_to_cpu(desc->status2));
}
#endif /* HAS_FIRMWARE */
#ifdef VLAN_SUPPORT
if (np->vlgrp && le16_to_cpu(desc->status2) & 0x0200) {
if (debug > 4)
......@@ -1900,9 +1838,6 @@ static struct net_device_stats *get_stats(struct net_device *dev)
}
/* Chips may use the upper or lower CRC bits, and may reverse and/or invert
them. Select the endian-ness that results in minimal calculations.
*/
static void set_rx_mode(struct net_device *dev)
{
struct netdev_private *np = netdev_priv(dev);
......@@ -1969,6 +1904,8 @@ static void set_rx_mode(struct net_device *dev)
memset(mc_filter, 0, sizeof(mc_filter));
for (i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count;
i++, mclist = mclist->next) {
/* The chip uses the upper 9 CRC bits
as index into the hash table */
int bit_nr = ether_crc_le(ETH_ALEN, mclist->dmi_addr) >> 23;
__u32 *fptr = (__u32 *) &mc_filter[(bit_nr >> 4) & ~1];
......@@ -2001,7 +1938,7 @@ static void get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
struct netdev_private *np = netdev_priv(dev);
strcpy(info->driver, DRV_NAME);
strcpy(info->version, DRV_VERSION);
strcpy(info->bus_info, PCI_SLOT_NAME(np->pci_dev));
strcpy(info->bus_info, pci_name(np->pci_dev));
}
static int get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
......@@ -2083,7 +2020,6 @@ static int netdev_close(struct net_device *dev)
int i;
netif_stop_queue(dev);
netif_stop_if(dev);
if (debug > 1) {
printk(KERN_DEBUG "%s: Shutting down ethercard, Intr status %#8.8x.\n",
......@@ -2184,7 +2120,13 @@ static int __init starfire_init (void)
/* when a module, this is printed whether or not devices are found in probe */
#ifdef MODULE
printk(version);
#ifdef HAVE_NETDEV_POLL
printk(KERN_INFO DRV_NAME ": polling (NAPI) enabled\n");
#else
printk(KERN_INFO DRV_NAME ": polling (NAPI) disabled\n");
#endif
#endif
#ifndef ADDR_64BITS
/* we can do this test only at run-time... sigh */
if (sizeof(dma_addr_t) == sizeof(u64)) {
......@@ -2192,10 +2134,6 @@ static int __init starfire_init (void)
return -ENODEV;
}
#endif /* not ADDR_64BITS */
#ifndef HAS_FIRMWARE
/* unconditionally disable hw cksums if firmware is not present */
enable_hw_cksum = 0;
#endif /* not HAS_FIRMWARE */
return pci_module_init (&starfire_driver);
}
......
此差异已折叠。
......@@ -2819,7 +2819,7 @@ void TLan_PhyMonitor( struct net_device *dev )
if (priv->link) {
priv->link = 0;
printk(KERN_DEBUG "TLAN: %s has lost link\n", dev->name);
dev->flags &= ~IFF_RUNNING;
netif_carrier_off(dev);
TLan_SetTimer( dev, (2*HZ), TLAN_TIMER_LINK_BEAT );
return;
}
......@@ -2829,7 +2829,7 @@ void TLan_PhyMonitor( struct net_device *dev )
if ((phy_status & MII_GS_LINK) && !priv->link) {
priv->link = 1;
printk(KERN_DEBUG "TLAN: %s has reestablished link\n", dev->name);
dev->flags |= IFF_RUNNING;
netif_carrier_on(dev);
}
/* Setup a new monitor */
......
......@@ -888,11 +888,6 @@ static int tok_open(struct net_device *dev)
ti->sap_status = CLOSED; /* CLOSED or OPEN */
ti->open_failure = NO; /* NO or YES */
ti->open_mode = MANUAL; /* MANUAL or AUTOMATIC */
/* 12/2000 not typical Linux, but we can use RUNNING to let us know when
the network has crapped out or cables are disconnected. Useful because
the IFF_UP flag stays up the whole time, until ifconfig tr0 down.
*/
dev->flags &= ~IFF_RUNNING;
ti->sram_phys &= ~1; /* to reverse what we do in tok_close */
/* init the spinlock */
......@@ -1242,7 +1237,7 @@ irqreturn_t tok_interrupt(int irq, void *dev_id, struct pt_regs *regs)
ti->open_status = CLOSED;
ti->sap_status = CLOSED;
ti->open_mode = AUTOMATIC;
dev->flags &= ~IFF_RUNNING;
netif_carrier_off(dev);
netif_stop_queue(dev);
ti->open_action = RESTART;
outb(0, dev->base_addr + ADAPTRESET);
......@@ -1323,7 +1318,7 @@ irqreturn_t tok_interrupt(int irq, void *dev_id, struct pt_regs *regs)
break;
}
netif_wake_queue(dev);
dev->flags |= IFF_RUNNING;/*BMS 12/2000*/
netif_carrier_on(dev);
break;
case DIR_INTERRUPT:
case DIR_MOD_OPEN_PARAMS:
......@@ -1427,7 +1422,7 @@ irqreturn_t tok_interrupt(int irq, void *dev_id, struct pt_regs *regs)
ring_status);
if(ring_status& (REMOVE_RECV|AUTO_REMOVAL|LOBE_FAULT)){
netif_stop_queue(dev);
dev->flags &= ~IFF_RUNNING;/*not typical Linux*/
netif_carrier_off(dev);
DPRINTK("Remove received, or Auto-removal error"
", or Lobe fault\n");
DPRINTK("We'll try to reopen the closed adapter"
......
此差异已折叠。
/*
* Generic HDLC support routines for Linux
*
* Copyright (C) 1999 - 2003 Krzysztof Halasa <khc@pm.waw.pl>
* Copyright (C) 1999 - 2005 Krzysztof Halasa <khc@pm.waw.pl>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License
......@@ -38,7 +38,7 @@
#include <linux/hdlc.h>
static const char* version = "HDLC support module revision 1.17";
static const char* version = "HDLC support module revision 1.18";
#undef DEBUG_LINK
......@@ -126,10 +126,13 @@ void hdlc_set_carrier(int on, struct net_device *dev)
if (!hdlc->open)
goto carrier_exit;
if (hdlc->carrier)
if (hdlc->carrier) {
printk(KERN_INFO "%s: Carrier detected\n", dev->name);
__hdlc_set_carrier_on(dev);
else
} else {
printk(KERN_INFO "%s: Carrier lost\n", dev->name);
__hdlc_set_carrier_off(dev);
}
carrier_exit:
spin_unlock_irqrestore(&hdlc->state_lock, flags);
......@@ -157,8 +160,11 @@ int hdlc_open(struct net_device *dev)
spin_lock_irq(&hdlc->state_lock);
if (hdlc->carrier)
if (hdlc->carrier) {
printk(KERN_INFO "%s: Carrier detected\n", dev->name);
__hdlc_set_carrier_on(dev);
} else
printk(KERN_INFO "%s: No carrier\n", dev->name);
hdlc->open = 1;
......
......@@ -723,7 +723,7 @@ static void lmc_watchdog (unsigned long data) /*fold00*/
/* lmc_reset (sc); Why reset??? The link can go down ok */
/* Inform the world that link has been lost */
dev->flags &= ~IFF_RUNNING;
netif_carrier_off(dev);
}
/*
......@@ -736,7 +736,7 @@ static void lmc_watchdog (unsigned long data) /*fold00*/
/* lmc_reset (sc); Again why reset??? */
/* Inform the world that link protocol is back up. */
dev->flags |= IFF_RUNNING;
netif_carrier_on(dev);
/* Now we have to tell the syncppp that we had an outage
* and that it should deal. Calling sppp_reopen here
......@@ -1168,8 +1168,6 @@ static void lmc_running_reset (struct net_device *dev) /*fold00*/
sc->lmc_media->set_link_status (sc, 1);
sc->lmc_media->set_status (sc, NULL);
//dev->flags |= IFF_RUNNING;
netif_wake_queue(dev);
sc->lmc_txfull = 0;
......@@ -1233,8 +1231,6 @@ static int lmc_ifdown (struct net_device *dev) /*fold00*/
csr6 &= ~LMC_DEC_SR; /* Turn off the Receive bit */
LMC_CSR_WRITE (sc, csr_command, csr6);
dev->flags &= ~IFF_RUNNING;
sc->stats.rx_missed_errors +=
LMC_CSR_READ (sc, csr_missed_frames) & 0xffff;
......
此差异已折叠。
......@@ -119,7 +119,6 @@ extern struct net_device *alloc_orinocodev(int sizeof_card,
extern void free_orinocodev(struct net_device *dev);
extern int __orinoco_up(struct net_device *dev);
extern int __orinoco_down(struct net_device *dev);
extern int orinoco_stop(struct net_device *dev);
extern int orinoco_reinit_firmware(struct net_device *dev);
extern irqreturn_t orinoco_interrupt(int irq, void * dev_id, struct pt_regs *regs);
......
/* include/linux/dm9000.h
*
* Copyright (c) 2004 Simtec Electronics
* Ben Dooks <ben@simtec.co.uk>
*
* Header file for dm9000 platform data
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
*/
#ifndef __DM9000_PLATFORM_DATA
#define __DM9000_PLATFORM_DATA __FILE__
/* IO control flags */
#define DM9000_PLATF_8BITONLY (0x0001)
#define DM9000_PLATF_16BITONLY (0x0002)
#define DM9000_PLATF_32BITONLY (0x0004)
/* platfrom data for platfrom device structure's platfrom_data field */
struct dm9000_plat_data {
unsigned int flags;
/* allow replacement IO routines */
void (*inblk)(void __iomem *reg, void *data, int len);
void (*outblk)(void __iomem *reg, void *data, int len);
void (*dumpblk)(void __iomem *reg, int len);
};
#endif /* __DM9000_PLATFORM_DATA */
/*
* Generic HDLC support routines for Linux
*
* Copyright (C) 1999-2003 Krzysztof Halasa <khc@pm.waw.pl>
* Copyright (C) 1999-2005 Krzysztof Halasa <khc@pm.waw.pl>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License
......@@ -41,6 +41,7 @@
#define LMI_NONE 1 /* No LMI, all PVCs are static */
#define LMI_ANSI 2 /* ANSI Annex D */
#define LMI_CCITT 3 /* ITU-T Annex A */
#define LMI_CISCO 4 /* The "original" LMI, aka Gang of Four */
#define HDLC_MAX_MTU 1500 /* Ethernet 1500 bytes */
#define HDLC_MAX_MRU (HDLC_MAX_MTU + 10 + 14 + 4) /* for ETH+VLAN over FR */
......@@ -89,6 +90,7 @@ typedef struct pvc_device_struct {
unsigned int deleted: 1;
unsigned int fecn: 1;
unsigned int becn: 1;
unsigned int bandwidth; /* Cisco LMI reporting only */
}state;
}pvc_device;
......
......@@ -33,7 +33,7 @@
#define IFF_LOOPBACK 0x8 /* is a loopback net */
#define IFF_POINTOPOINT 0x10 /* interface is has p-p link */
#define IFF_NOTRAILERS 0x20 /* avoid use of trailers */
#define IFF_RUNNING 0x40 /* resources allocated */
#define IFF_RUNNING 0x40 /* interface running and carrier ok */
#define IFF_NOARP 0x80 /* no ARP protocol */
#define IFF_PROMISC 0x100 /* receive all packets */
#define IFF_ALLMULTI 0x200 /* receive all multicast packets*/
......
此差异已折叠。
......@@ -2,7 +2,7 @@
* This file implement the Wireless Extensions APIs.
*
* Authors : Jean Tourrilhes - HPL - <jt@hpl.hp.com>
* Copyright (c) 1997-2004 Jean Tourrilhes, All Rights Reserved.
* Copyright (c) 1997-2005 Jean Tourrilhes, All Rights Reserved.
*
* (As all part of the Linux kernel, this file is GPL)
*/
......@@ -187,6 +187,12 @@ static const struct iw_ioctl_description standard_ioctl[] = {
.header_type = IW_HEADER_TYPE_ADDR,
.flags = IW_DESCR_FLAG_DUMP,
},
[SIOCSIWMLME - SIOCIWFIRST] = {
.header_type = IW_HEADER_TYPE_POINT,
.token_size = 1,
.min_tokens = sizeof(struct iw_mlme),
.max_tokens = sizeof(struct iw_mlme),
},
[SIOCGIWAPLIST - SIOCIWFIRST] = {
.header_type = IW_HEADER_TYPE_POINT,
.token_size = sizeof(struct sockaddr) +
......@@ -195,7 +201,10 @@ static const struct iw_ioctl_description standard_ioctl[] = {
.flags = IW_DESCR_FLAG_NOMAX,
},
[SIOCSIWSCAN - SIOCIWFIRST] = {
.header_type = IW_HEADER_TYPE_PARAM,
.header_type = IW_HEADER_TYPE_POINT,
.token_size = 1,
.min_tokens = 0,
.max_tokens = sizeof(struct iw_scan_req),
},
[SIOCGIWSCAN - SIOCIWFIRST] = {
.header_type = IW_HEADER_TYPE_POINT,
......@@ -273,6 +282,42 @@ static const struct iw_ioctl_description standard_ioctl[] = {
[SIOCGIWPOWER - SIOCIWFIRST] = {
.header_type = IW_HEADER_TYPE_PARAM,
},
[SIOCSIWGENIE - SIOCIWFIRST] = {
.header_type = IW_HEADER_TYPE_POINT,
.token_size = 1,
.max_tokens = IW_GENERIC_IE_MAX,
},
[SIOCGIWGENIE - SIOCIWFIRST] = {
.header_type = IW_HEADER_TYPE_POINT,
.token_size = 1,
.max_tokens = IW_GENERIC_IE_MAX,
},
[SIOCSIWAUTH - SIOCIWFIRST] = {
.header_type = IW_HEADER_TYPE_PARAM,
},
[SIOCGIWAUTH - SIOCIWFIRST] = {
.header_type = IW_HEADER_TYPE_PARAM,
},
[SIOCSIWENCODEEXT - SIOCIWFIRST] = {
.header_type = IW_HEADER_TYPE_POINT,
.token_size = 1,
.min_tokens = sizeof(struct iw_encode_ext),
.max_tokens = sizeof(struct iw_encode_ext) +
IW_ENCODING_TOKEN_MAX,
},
[SIOCGIWENCODEEXT - SIOCIWFIRST] = {
.header_type = IW_HEADER_TYPE_POINT,
.token_size = 1,
.min_tokens = sizeof(struct iw_encode_ext),
.max_tokens = sizeof(struct iw_encode_ext) +
IW_ENCODING_TOKEN_MAX,
},
[SIOCSIWPMKSA - SIOCIWFIRST] = {
.header_type = IW_HEADER_TYPE_POINT,
.token_size = 1,
.min_tokens = sizeof(struct iw_pmksa),
.max_tokens = sizeof(struct iw_pmksa),
},
};
static const int standard_ioctl_num = (sizeof(standard_ioctl) /
sizeof(struct iw_ioctl_description));
......@@ -299,6 +344,31 @@ static const struct iw_ioctl_description standard_event[] = {
[IWEVEXPIRED - IWEVFIRST] = {
.header_type = IW_HEADER_TYPE_ADDR,
},
[IWEVGENIE - IWEVFIRST] = {
.header_type = IW_HEADER_TYPE_POINT,
.token_size = 1,
.max_tokens = IW_GENERIC_IE_MAX,
},
[IWEVMICHAELMICFAILURE - IWEVFIRST] = {
.header_type = IW_HEADER_TYPE_POINT,
.token_size = 1,
.max_tokens = sizeof(struct iw_michaelmicfailure),
},
[IWEVASSOCREQIE - IWEVFIRST] = {
.header_type = IW_HEADER_TYPE_POINT,
.token_size = 1,
.max_tokens = IW_GENERIC_IE_MAX,
},
[IWEVASSOCRESPIE - IWEVFIRST] = {
.header_type = IW_HEADER_TYPE_POINT,
.token_size = 1,
.max_tokens = IW_GENERIC_IE_MAX,
},
[IWEVPMKIDCAND - IWEVFIRST] = {
.header_type = IW_HEADER_TYPE_POINT,
.token_size = 1,
.max_tokens = sizeof(struct iw_pmkid_cand),
},
};
static const int standard_event_num = (sizeof(standard_event) /
sizeof(struct iw_ioctl_description));
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册