mirror of https://gitee.com/openkylin/linux.git
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.
This commit is contained in:
commit
0e396ee43e
|
@ -1,21 +1,21 @@
|
|||
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).
|
||||
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).
|
||||
|
||||
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.
|
||||
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)
|
||||
iounmap (tp->mmio_addr);
|
||||
#endif /* !USE_IO_OPS */
|
||||
ioport_unmap (tp->mmio_addr);
|
||||
#else
|
||||
if (tp->mmio_addr)
|
||||
pci_iounmap (pdev, tp->mmio_addr);
|
||||
#endif /* USE_IO_OPS */
|
||||
|
||||
/* it's ok to call this even if we have no regions to free */
|
||||
pci_release_regions (pdev);
|
||||
|
@ -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);
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,135 @@
|
|||
/*
|
||||
* 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_ */
|
||||
|
|
@ -1,689 +0,0 @@
|
|||
/* 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;
|
||||
}
|
||||
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);
|
||||
|
||||
/* 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;
|
||||
/* 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);
|
||||
|
||||
|
|
2066
drivers/net/sk_g16.c
2066
drivers/net/sk_g16.c
File diff suppressed because it is too large
Load Diff
|
@ -1,165 +0,0 @@
|
|||
/*-
|
||||
*
|
||||
* 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 */
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,346 @@
|
|||
/*
|
||||
* Copyright 2003 Adaptec, Inc.
|
||||
*
|
||||
* Please read the following license before using the Adaptec Software
|
||||
* ("Program"). If you do not agree to the license terms, do not use the
|
||||
* Program:
|
||||
*
|
||||
* You agree to be bound by version 2 of the General Public License ("GPL")
|
||||
* dated June 1991, which can be found at http://www.fsf.org/licenses/gpl.html.
|
||||
* If the link is broken, write to Free Software Foundation, 59 Temple Place,
|
||||
* Boston, Massachusetts 02111-1307.
|
||||
*
|
||||
* BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE IT IS LICENSED "AS IS" AND
|
||||
* THERE IS NO WARRANTY FOR THE PROGRAM, INCLUDING BUT NOT LIMITED TO THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTIBILITY OR FITNESS FOR A PARTICULAR PURPOSE
|
||||
* (TO THE EXTENT PERMITTED BY APPLICABLE LAW). USE OF THE PROGRAM IS AT YOUR
|
||||
* OWN RISK. IN NO EVENT WILL ADAPTEC OR ITS LICENSORS BE LIABLE TO YOU FOR
|
||||
* DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES
|
||||
* ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM.
|
||||
*
|
||||
*/
|
||||
|
||||
static const u32 firmware_rx[] = {
|
||||
0x010003dc, 0x00000000,
|
||||
0x04000421, 0x00000086,
|
||||
0x80000015, 0x0000180e,
|
||||
0x81000015, 0x00006664,
|
||||
0x1a0040ab, 0x00000b06,
|
||||
0x14200011, 0x00000000,
|
||||
0x14204022, 0x0000aaaa,
|
||||
0x14204022, 0x00000300,
|
||||
0x14204022, 0x00000000,
|
||||
0x1a0040ab, 0x00000b14,
|
||||
0x14200011, 0x00000000,
|
||||
0x83000015, 0x00000002,
|
||||
0x04000021, 0x00000000,
|
||||
0x00000010, 0x00000000,
|
||||
0x04000421, 0x00000087,
|
||||
0x00000010, 0x00000000,
|
||||
0x00000010, 0x00000000,
|
||||
0x00008015, 0x00000000,
|
||||
0x0000003e, 0x00000000,
|
||||
0x00000010, 0x00000000,
|
||||
0x82000015, 0x00004000,
|
||||
0x009e8050, 0x00000000,
|
||||
0x03008015, 0x00000000,
|
||||
0x86008015, 0x00000000,
|
||||
0x82000015, 0x00008000,
|
||||
0x0100001c, 0x00000000,
|
||||
0x000050a0, 0x0000010c,
|
||||
0x4e20d011, 0x00006008,
|
||||
0x1420d012, 0x00004008,
|
||||
0x0000f090, 0x00007000,
|
||||
0x0000c8b0, 0x00003000,
|
||||
0x00004040, 0x00000000,
|
||||
0x00108015, 0x00000000,
|
||||
0x00a2c150, 0x00004000,
|
||||
0x00a400b0, 0x00000014,
|
||||
0x00000020, 0x00000000,
|
||||
0x2500400d, 0x00002525,
|
||||
0x00047220, 0x00003100,
|
||||
0x00934070, 0x00000000,
|
||||
0x00000020, 0x00000000,
|
||||
0x00924460, 0x00000184,
|
||||
0x2b20c011, 0x00000000,
|
||||
0x0000c420, 0x00000540,
|
||||
0x36014018, 0x0000422d,
|
||||
0x14200011, 0x00000000,
|
||||
0x00924460, 0x00000183,
|
||||
0x3200001f, 0x00000034,
|
||||
0x02ac0015, 0x00000002,
|
||||
0x00a60110, 0x00000008,
|
||||
0x42200011, 0x00000000,
|
||||
0x00924060, 0x00000103,
|
||||
0x0000001e, 0x00000000,
|
||||
0x00000020, 0x00000100,
|
||||
0x0000001e, 0x00000000,
|
||||
0x00924460, 0x00000086,
|
||||
0x00004080, 0x00000000,
|
||||
0x0092c070, 0x00000000,
|
||||
0x00924060, 0x00000100,
|
||||
0x0000c890, 0x00005000,
|
||||
0x00a6c110, 0x00000000,
|
||||
0x00b0c090, 0x00000012,
|
||||
0x021c0015, 0x00000000,
|
||||
0x3200001f, 0x00000034,
|
||||
0x00924460, 0x00000510,
|
||||
0x44210011, 0x00000000,
|
||||
0x42000011, 0x00000000,
|
||||
0x83000015, 0x00000040,
|
||||
0x00924460, 0x00000508,
|
||||
0x45014018, 0x00004545,
|
||||
0x00808050, 0x00000000,
|
||||
0x62208012, 0x00000000,
|
||||
0x82000015, 0x00000800,
|
||||
0x15200011, 0x00000000,
|
||||
0x00000010, 0x00000000,
|
||||
0x00000010, 0x00000000,
|
||||
0x00000010, 0x00000000,
|
||||
0x00000010, 0x00000000,
|
||||
0x00000010, 0x00000000,
|
||||
0x80000015, 0x0000eea4,
|
||||
0x81000015, 0x0000005f,
|
||||
0x00000060, 0x00000000,
|
||||
0x00004120, 0x00000000,
|
||||
0x00004a00, 0x00004000,
|
||||
0x00924460, 0x00000190,
|
||||
0x5601401a, 0x00005956,
|
||||
0x14000011, 0x00000000,
|
||||
0x00934050, 0x00000018,
|
||||
0x00930050, 0x00000018,
|
||||
0x3601403a, 0x0000002d,
|
||||
0x000643a9, 0x00000000,
|
||||
0x0000c420, 0x00000140,
|
||||
0x5601401a, 0x00005956,
|
||||
0x14000011, 0x00000000,
|
||||
0x00000010, 0x00000000,
|
||||
0x00000010, 0x00000000,
|
||||
0x000642a9, 0x00000000,
|
||||
0x00024420, 0x00000183,
|
||||
0x5601401a, 0x00005956,
|
||||
0x82000015, 0x00002000,
|
||||
0x15200011, 0x00000000,
|
||||
0x82000015, 0x00000010,
|
||||
0x15200011, 0x00000000,
|
||||
0x82000015, 0x00000010,
|
||||
0x15200011, 0x00000000,
|
||||
}; /* 104 Rx instructions */
|
||||
#define FIRMWARE_RX_SIZE 104
|
||||
|
||||
static const u32 firmware_tx[] = {
|
||||
0x010003dc, 0x00000000,
|
||||
0x04000421, 0x00000086,
|
||||
0x80000015, 0x0000180e,
|
||||
0x81000015, 0x00006664,
|
||||
0x1a0040ab, 0x00000b06,
|
||||
0x14200011, 0x00000000,
|
||||
0x14204022, 0x0000aaaa,
|
||||
0x14204022, 0x00000300,
|
||||
0x14204022, 0x00000000,
|
||||
0x1a0040ab, 0x00000b14,
|
||||
0x14200011, 0x00000000,
|
||||
0x83000015, 0x00000002,
|
||||
0x04000021, 0x00000000,
|
||||
0x00000010, 0x00000000,
|
||||
0x04000421, 0x00000087,
|
||||
0x00000010, 0x00000000,
|
||||
0x00000010, 0x00000000,
|
||||
0x00008015, 0x00000000,
|
||||
0x0000003e, 0x00000000,
|
||||
0x00000010, 0x00000000,
|
||||
0x82000015, 0x00004000,
|
||||
0x009e8050, 0x00000000,
|
||||
0x03008015, 0x00000000,
|
||||
0x86008015, 0x00000000,
|
||||
0x82000015, 0x00008000,
|
||||
0x0100001c, 0x00000000,
|
||||
0x000050a0, 0x0000010c,
|
||||
0x4e20d011, 0x00006008,
|
||||
0x1420d012, 0x00004008,
|
||||
0x0000f090, 0x00007000,
|
||||
0x0000c8b0, 0x00003000,
|
||||
0x00004040, 0x00000000,
|
||||
0x00108015, 0x00000000,
|
||||
0x00a2c150, 0x00004000,
|
||||
0x00a400b0, 0x00000014,
|
||||
0x00000020, 0x00000000,
|
||||
0x2500400d, 0x00002525,
|
||||
0x00047220, 0x00003100,
|
||||
0x00934070, 0x00000000,
|
||||
0x00000020, 0x00000000,
|
||||
0x00924460, 0x00000184,
|
||||
0x2b20c011, 0x00000000,
|
||||
0x0000c420, 0x00000540,
|
||||
0x36014018, 0x0000422d,
|
||||
0x14200011, 0x00000000,
|
||||
0x00924460, 0x00000183,
|
||||
0x3200001f, 0x00000034,
|
||||
0x02ac0015, 0x00000002,
|
||||
0x00a60110, 0x00000008,
|
||||
0x42200011, 0x00000000,
|
||||
0x00924060, 0x00000103,
|
||||
0x0000001e, 0x00000000,
|
||||
0x00000020, 0x00000100,
|
||||
0x0000001e, 0x00000000,
|
||||
0x00924460, 0x00000086,
|
||||
0x00004080, 0x00000000,
|
||||
0x0092c070, 0x00000000,
|
||||
0x00924060, 0x00000100,
|
||||
0x0000c890, 0x00005000,
|
||||
0x00a6c110, 0x00000000,
|
||||
0x00b0c090, 0x00000012,
|
||||
0x021c0015, 0x00000000,
|
||||
0x3200001f, 0x00000034,
|
||||
0x00924460, 0x00000510,
|
||||
0x44210011, 0x00000000,
|
||||
0x42000011, 0x00000000,
|
||||
0x83000015, 0x00000040,
|
||||
0x00924460, 0x00000508,
|
||||
0x45014018, 0x00004545,
|
||||
0x00808050, 0x00000000,
|
||||
0x62208012, 0x00000000,
|
||||
0x82000015, 0x00000800,
|
||||
0x15200011, 0x00000000,
|
||||
0x00000010, 0x00000000,
|
||||
0x00000010, 0x00000000,
|
||||
0x00000010, 0x00000000,
|
||||
0x00000010, 0x00000000,
|
||||
0x00000010, 0x00000000,
|
||||
0x80000015, 0x0000eea4,
|
||||
0x81000015, 0x0000005f,
|
||||
0x00000060, 0x00000000,
|
||||
0x00004120, 0x00000000,
|
||||
0x00004a00, 0x00004000,
|
||||
0x00924460, 0x00000190,
|
||||
0x5601401a, 0x00005956,
|
||||
0x14000011, 0x00000000,
|
||||
0x00934050, 0x00000018,
|
||||
0x00930050, 0x00000018,
|
||||
0x3601403a, 0x0000002d,
|
||||
0x000643a9, 0x00000000,
|
||||
0x0000c420, 0x00000140,
|
||||
0x5601401a, 0x00005956,
|
||||
0x14000011, 0x00000000,
|
||||
0x00000010, 0x00000000,
|
||||
0x00000010, 0x00000000,
|
||||
0x000642a9, 0x00000000,
|
||||
0x00024420, 0x00000183,
|
||||
0x5601401a, 0x00005956,
|
||||
0x82000015, 0x00002000,
|
||||
0x15200011, 0x00000000,
|
||||
0x82000015, 0x00000010,
|
||||
0x15200011, 0x00000000,
|
||||
0x82000015, 0x00000010,
|
||||
0x15200011, 0x00000000,
|
||||
}; /* 104 Tx instructions */
|
||||
#define FIRMWARE_TX_SIZE 104
|
||||
#if 0
|
||||
static const u32 firmware_wol[] = {
|
||||
0x010003dc, 0x00000000,
|
||||
0x19000421, 0x00000087,
|
||||
0x80000015, 0x00001a1a,
|
||||
0x81000015, 0x00001a1a,
|
||||
0x1a0040ab, 0x00000b06,
|
||||
0x15200011, 0x00000000,
|
||||
0x15204022, 0x0000aaaa,
|
||||
0x15204022, 0x00000300,
|
||||
0x15204022, 0x00000000,
|
||||
0x1a0040ab, 0x00000b15,
|
||||
0x15200011, 0x00000000,
|
||||
0x83000015, 0x00000002,
|
||||
0x04000021, 0x00000000,
|
||||
0x00000010, 0x00000000,
|
||||
0x04000421, 0x00000087,
|
||||
0x00000010, 0x00000000,
|
||||
0x00000010, 0x00000000,
|
||||
0x00008015, 0x00000000,
|
||||
0x0000003e, 0x00000000,
|
||||
0x00000010, 0x00000000,
|
||||
0x00000010, 0x00000000,
|
||||
0x82000015, 0x00004000,
|
||||
0x82000015, 0x00008000,
|
||||
0x0000000c, 0x00000000,
|
||||
0x00000010, 0x00000000,
|
||||
0x00004080, 0x00000100,
|
||||
0x1f20c011, 0x00001122,
|
||||
0x2720f011, 0x00003011,
|
||||
0x19200071, 0x00000000,
|
||||
0x1a200051, 0x00000000,
|
||||
0x00000010, 0x00000000,
|
||||
0x00000010, 0x00000000,
|
||||
0x1d2040a4, 0x00003344,
|
||||
0x1d2040a2, 0x00005566,
|
||||
0x000040a0, 0x00000100,
|
||||
0x00108050, 0x00000001,
|
||||
0x1a208012, 0x00000006,
|
||||
0x82000015, 0x00008080,
|
||||
0x010003dc, 0x00000000,
|
||||
0x1d2040a4, 0x00002233,
|
||||
0x1d2040a4, 0x00004455,
|
||||
0x2d208011, 0x00000005,
|
||||
0x1d2040a4, 0x00006611,
|
||||
0x00108050, 0x00000001,
|
||||
0x27200011, 0x00000000,
|
||||
0x1d2050a4, 0x00006600,
|
||||
0x82000015, 0x00008080,
|
||||
0x010003dc, 0x00000000,
|
||||
0x00000050, 0x00000000,
|
||||
0x1b200031, 0x00000000,
|
||||
0x0000001e, 0x00000000,
|
||||
0x0000001e, 0x00000000,
|
||||
0x0000001e, 0x00000000,
|
||||
0x0000001e, 0x00000000,
|
||||
0x00924460, 0x00000086,
|
||||
0x00004080, 0x00000000,
|
||||
0x0092c070, 0x00000000,
|
||||
0x00924060, 0x00000100,
|
||||
0x0000c890, 0x00005000,
|
||||
0x00a6c110, 0x00000000,
|
||||
0x00b0c090, 0x00000012,
|
||||
0x021c0015, 0x00000000,
|
||||
0x3200001f, 0x00000034,
|
||||
0x00924460, 0x00000510,
|
||||
0x44210011, 0x00000000,
|
||||
0x42000011, 0x00000000,
|
||||
0x83000015, 0x00000040,
|
||||
0x00924460, 0x00000508,
|
||||
0x476a0012, 0x00000100,
|
||||
0x83000015, 0x00000008,
|
||||
0x16200011, 0x00000000,
|
||||
0x001e8050, 0x00000000,
|
||||
0x001e8050, 0x00000000,
|
||||
0x00808050, 0x00000000,
|
||||
0x03008015, 0x00000000,
|
||||
0x62208012, 0x00000000,
|
||||
0x82000015, 0x00000800,
|
||||
0x16200011, 0x00000000,
|
||||
0x80000015, 0x0000eea4,
|
||||
0x81000015, 0x0000005f,
|
||||
0x00000020, 0x00000000,
|
||||
0x00004120, 0x00000000,
|
||||
0x00004a00, 0x00004000,
|
||||
0x00924460, 0x00000190,
|
||||
0x5c01401a, 0x0000595c,
|
||||
0x15000011, 0x00000000,
|
||||
0x00934050, 0x00000018,
|
||||
0x00930050, 0x00000018,
|
||||
0x3601403a, 0x0000002d,
|
||||
0x00064029, 0x00000000,
|
||||
0x0000c420, 0x00000140,
|
||||
0x5c01401a, 0x0000595c,
|
||||
0x15000011, 0x00000000,
|
||||
0x00000010, 0x00000000,
|
||||
0x00000010, 0x00000000,
|
||||
0x00064029, 0x00000000,
|
||||
0x00024420, 0x00000183,
|
||||
0x5c01401a, 0x0000595c,
|
||||
0x82000015, 0x00002000,
|
||||
0x16200011, 0x00000000,
|
||||
0x82000015, 0x00000010,
|
||||
0x16200011, 0x00000000,
|
||||
0x82000015, 0x00000010,
|
||||
0x16200011, 0x00000000,
|
||||
}; /* 104 WoL instructions */
|
||||
#define FIRMWARE_WOL_SIZE 104
|
||||
#endif
|
|
@ -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"
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* Generic HDLC support routines for Linux
|
||||
* Frame Relay support
|
||||
*
|
||||
* 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
|
||||
|
@ -27,6 +27,10 @@
|
|||
active = open and "link reliable"
|
||||
exist = new = not used
|
||||
|
||||
CCITT LMI: ITU-T Q.933 Annex A
|
||||
ANSI LMI: ANSI T1.617 Annex D
|
||||
CISCO LMI: the original, aka "Gang of Four" LMI
|
||||
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
|
@ -49,45 +53,41 @@
|
|||
#undef DEBUG_ECN
|
||||
#undef DEBUG_LINK
|
||||
|
||||
#define MAXLEN_LMISTAT 20 /* max size of status enquiry frame */
|
||||
#define FR_UI 0x03
|
||||
#define FR_PAD 0x00
|
||||
|
||||
#define PVC_STATE_NEW 0x01
|
||||
#define PVC_STATE_ACTIVE 0x02
|
||||
#define PVC_STATE_FECN 0x08 /* FECN condition */
|
||||
#define PVC_STATE_BECN 0x10 /* BECN condition */
|
||||
#define NLPID_IP 0xCC
|
||||
#define NLPID_IPV6 0x8E
|
||||
#define NLPID_SNAP 0x80
|
||||
#define NLPID_PAD 0x00
|
||||
#define NLPID_CCITT_ANSI_LMI 0x08
|
||||
#define NLPID_CISCO_LMI 0x09
|
||||
|
||||
|
||||
#define FR_UI 0x03
|
||||
#define FR_PAD 0x00
|
||||
#define LMI_CCITT_ANSI_DLCI 0 /* LMI DLCI */
|
||||
#define LMI_CISCO_DLCI 1023
|
||||
|
||||
#define NLPID_IP 0xCC
|
||||
#define NLPID_IPV6 0x8E
|
||||
#define NLPID_SNAP 0x80
|
||||
#define NLPID_PAD 0x00
|
||||
#define NLPID_Q933 0x08
|
||||
#define LMI_CALLREF 0x00 /* Call Reference */
|
||||
#define LMI_ANSI_LOCKSHIFT 0x95 /* ANSI locking shift */
|
||||
#define LMI_ANSI_CISCO_REPTYPE 0x01 /* report type */
|
||||
#define LMI_CCITT_REPTYPE 0x51
|
||||
#define LMI_ANSI_CISCO_ALIVE 0x03 /* keep alive */
|
||||
#define LMI_CCITT_ALIVE 0x53
|
||||
#define LMI_ANSI_CISCO_PVCSTAT 0x07 /* PVC status */
|
||||
#define LMI_CCITT_PVCSTAT 0x57
|
||||
|
||||
#define LMI_FULLREP 0x00 /* full report */
|
||||
#define LMI_INTEGRITY 0x01 /* link integrity report */
|
||||
#define LMI_SINGLE 0x02 /* single PVC report */
|
||||
|
||||
#define LMI_DLCI 0 /* LMI DLCI */
|
||||
#define LMI_PROTO 0x08
|
||||
#define LMI_CALLREF 0x00 /* Call Reference */
|
||||
#define LMI_ANSI_LOCKSHIFT 0x95 /* ANSI lockshift */
|
||||
#define LMI_REPTYPE 1 /* report type */
|
||||
#define LMI_CCITT_REPTYPE 0x51
|
||||
#define LMI_ALIVE 3 /* keep alive */
|
||||
#define LMI_CCITT_ALIVE 0x53
|
||||
#define LMI_PVCSTAT 7 /* pvc status */
|
||||
#define LMI_CCITT_PVCSTAT 0x57
|
||||
#define LMI_FULLREP 0 /* full report */
|
||||
#define LMI_INTEGRITY 1 /* link integrity report */
|
||||
#define LMI_SINGLE 2 /* single pvc report */
|
||||
#define LMI_STATUS_ENQUIRY 0x75
|
||||
#define LMI_STATUS 0x7D /* reply */
|
||||
|
||||
#define LMI_REPT_LEN 1 /* report type element length */
|
||||
#define LMI_INTEG_LEN 2 /* link integrity element length */
|
||||
|
||||
#define LMI_LENGTH 13 /* standard LMI frame length */
|
||||
#define LMI_ANSI_LENGTH 14
|
||||
#define LMI_CCITT_CISCO_LENGTH 13 /* LMI frame lengths */
|
||||
#define LMI_ANSI_LENGTH 14
|
||||
|
||||
|
||||
typedef struct {
|
||||
|
@ -223,35 +223,24 @@ static inline struct net_device** get_dev_p(pvc_device *pvc, int type)
|
|||
}
|
||||
|
||||
|
||||
static inline u16 status_to_dlci(u8 *status, int *active, int *new)
|
||||
{
|
||||
*new = (status[2] & 0x08) ? 1 : 0;
|
||||
*active = (status[2] & 0x02) ? 1 : 0;
|
||||
|
||||
return ((status[0] & 0x3F) << 4) | ((status[1] & 0x78) >> 3);
|
||||
}
|
||||
|
||||
|
||||
static inline void dlci_to_status(u16 dlci, u8 *status, int active, int new)
|
||||
{
|
||||
status[0] = (dlci >> 4) & 0x3F;
|
||||
status[1] = ((dlci << 3) & 0x78) | 0x80;
|
||||
status[2] = 0x80;
|
||||
|
||||
if (new)
|
||||
status[2] |= 0x08;
|
||||
else if (active)
|
||||
status[2] |= 0x02;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int fr_hard_header(struct sk_buff **skb_p, u16 dlci)
|
||||
{
|
||||
u16 head_len;
|
||||
struct sk_buff *skb = *skb_p;
|
||||
|
||||
switch (skb->protocol) {
|
||||
case __constant_ntohs(NLPID_CCITT_ANSI_LMI):
|
||||
head_len = 4;
|
||||
skb_push(skb, head_len);
|
||||
skb->data[3] = NLPID_CCITT_ANSI_LMI;
|
||||
break;
|
||||
|
||||
case __constant_ntohs(NLPID_CISCO_LMI):
|
||||
head_len = 4;
|
||||
skb_push(skb, head_len);
|
||||
skb->data[3] = NLPID_CISCO_LMI;
|
||||
break;
|
||||
|
||||
case __constant_ntohs(ETH_P_IP):
|
||||
head_len = 4;
|
||||
skb_push(skb, head_len);
|
||||
|
@ -264,12 +253,6 @@ static int fr_hard_header(struct sk_buff **skb_p, u16 dlci)
|
|||
skb->data[3] = NLPID_IPV6;
|
||||
break;
|
||||
|
||||
case __constant_ntohs(LMI_PROTO):
|
||||
head_len = 4;
|
||||
skb_push(skb, head_len);
|
||||
skb->data[3] = LMI_PROTO;
|
||||
break;
|
||||
|
||||
case __constant_ntohs(ETH_P_802_3):
|
||||
head_len = 10;
|
||||
if (skb_headroom(skb) < head_len) {
|
||||
|
@ -461,13 +444,14 @@ static void fr_lmi_send(struct net_device *dev, int fullrep)
|
|||
hdlc_device *hdlc = dev_to_hdlc(dev);
|
||||
struct sk_buff *skb;
|
||||
pvc_device *pvc = hdlc->state.fr.first_pvc;
|
||||
int len = (hdlc->state.fr.settings.lmi == LMI_ANSI) ? LMI_ANSI_LENGTH
|
||||
: LMI_LENGTH;
|
||||
int stat_len = 3;
|
||||
int lmi = hdlc->state.fr.settings.lmi;
|
||||
int dce = hdlc->state.fr.settings.dce;
|
||||
int len = lmi == LMI_ANSI ? LMI_ANSI_LENGTH : LMI_CCITT_CISCO_LENGTH;
|
||||
int stat_len = (lmi == LMI_CISCO) ? 6 : 3;
|
||||
u8 *data;
|
||||
int i = 0;
|
||||
|
||||
if (hdlc->state.fr.settings.dce && fullrep) {
|
||||
if (dce && fullrep) {
|
||||
len += hdlc->state.fr.dce_pvc_count * (2 + stat_len);
|
||||
if (len > HDLC_MAX_MRU) {
|
||||
printk(KERN_WARNING "%s: Too many PVCs while sending "
|
||||
|
@ -484,29 +468,31 @@ static void fr_lmi_send(struct net_device *dev, int fullrep)
|
|||
}
|
||||
memset(skb->data, 0, len);
|
||||
skb_reserve(skb, 4);
|
||||
skb->protocol = __constant_htons(LMI_PROTO);
|
||||
fr_hard_header(&skb, LMI_DLCI);
|
||||
if (lmi == LMI_CISCO) {
|
||||
skb->protocol = __constant_htons(NLPID_CISCO_LMI);
|
||||
fr_hard_header(&skb, LMI_CISCO_DLCI);
|
||||
} else {
|
||||
skb->protocol = __constant_htons(NLPID_CCITT_ANSI_LMI);
|
||||
fr_hard_header(&skb, LMI_CCITT_ANSI_DLCI);
|
||||
}
|
||||
data = skb->tail;
|
||||
data[i++] = LMI_CALLREF;
|
||||
data[i++] = hdlc->state.fr.settings.dce
|
||||
? LMI_STATUS : LMI_STATUS_ENQUIRY;
|
||||
if (hdlc->state.fr.settings.lmi == LMI_ANSI)
|
||||
data[i++] = dce ? LMI_STATUS : LMI_STATUS_ENQUIRY;
|
||||
if (lmi == LMI_ANSI)
|
||||
data[i++] = LMI_ANSI_LOCKSHIFT;
|
||||
data[i++] = (hdlc->state.fr.settings.lmi == LMI_CCITT)
|
||||
? LMI_CCITT_REPTYPE : LMI_REPTYPE;
|
||||
data[i++] = lmi == LMI_CCITT ? LMI_CCITT_REPTYPE :
|
||||
LMI_ANSI_CISCO_REPTYPE;
|
||||
data[i++] = LMI_REPT_LEN;
|
||||
data[i++] = fullrep ? LMI_FULLREP : LMI_INTEGRITY;
|
||||
|
||||
data[i++] = (hdlc->state.fr.settings.lmi == LMI_CCITT)
|
||||
? LMI_CCITT_ALIVE : LMI_ALIVE;
|
||||
data[i++] = lmi == LMI_CCITT ? LMI_CCITT_ALIVE : LMI_ANSI_CISCO_ALIVE;
|
||||
data[i++] = LMI_INTEG_LEN;
|
||||
data[i++] = hdlc->state.fr.txseq =fr_lmi_nextseq(hdlc->state.fr.txseq);
|
||||
data[i++] = hdlc->state.fr.rxseq;
|
||||
|
||||
if (hdlc->state.fr.settings.dce && fullrep) {
|
||||
if (dce && fullrep) {
|
||||
while (pvc) {
|
||||
data[i++] = (hdlc->state.fr.settings.lmi == LMI_CCITT)
|
||||
? LMI_CCITT_PVCSTAT : LMI_PVCSTAT;
|
||||
data[i++] = lmi == LMI_CCITT ? LMI_CCITT_PVCSTAT :
|
||||
LMI_ANSI_CISCO_PVCSTAT;
|
||||
data[i++] = stat_len;
|
||||
|
||||
/* LMI start/restart */
|
||||
|
@ -523,8 +509,20 @@ static void fr_lmi_send(struct net_device *dev, int fullrep)
|
|||
fr_log_dlci_active(pvc);
|
||||
}
|
||||
|
||||
dlci_to_status(pvc->dlci, data + i,
|
||||
pvc->state.active, pvc->state.new);
|
||||
if (lmi == LMI_CISCO) {
|
||||
data[i] = pvc->dlci >> 8;
|
||||
data[i + 1] = pvc->dlci & 0xFF;
|
||||
} else {
|
||||
data[i] = (pvc->dlci >> 4) & 0x3F;
|
||||
data[i + 1] = ((pvc->dlci << 3) & 0x78) | 0x80;
|
||||
data[i + 2] = 0x80;
|
||||
}
|
||||
|
||||
if (pvc->state.new)
|
||||
data[i + 2] |= 0x08;
|
||||
else if (pvc->state.active)
|
||||
data[i + 2] |= 0x02;
|
||||
|
||||
i += stat_len;
|
||||
pvc = pvc->next;
|
||||
}
|
||||
|
@ -569,6 +567,8 @@ static void fr_set_link_state(int reliable, struct net_device *dev)
|
|||
pvc_carrier(0, pvc);
|
||||
pvc->state.exist = pvc->state.active = 0;
|
||||
pvc->state.new = 0;
|
||||
if (!hdlc->state.fr.settings.dce)
|
||||
pvc->state.bandwidth = 0;
|
||||
pvc = pvc->next;
|
||||
}
|
||||
}
|
||||
|
@ -583,11 +583,12 @@ static void fr_timer(unsigned long arg)
|
|||
int i, cnt = 0, reliable;
|
||||
u32 list;
|
||||
|
||||
if (hdlc->state.fr.settings.dce)
|
||||
if (hdlc->state.fr.settings.dce) {
|
||||
reliable = hdlc->state.fr.request &&
|
||||
time_before(jiffies, hdlc->state.fr.last_poll +
|
||||
hdlc->state.fr.settings.t392 * HZ);
|
||||
else {
|
||||
hdlc->state.fr.request = 0;
|
||||
} else {
|
||||
hdlc->state.fr.last_errors <<= 1; /* Shift the list */
|
||||
if (hdlc->state.fr.request) {
|
||||
if (hdlc->state.fr.reliable)
|
||||
|
@ -634,65 +635,88 @@ static void fr_timer(unsigned long arg)
|
|||
static int fr_lmi_recv(struct net_device *dev, struct sk_buff *skb)
|
||||
{
|
||||
hdlc_device *hdlc = dev_to_hdlc(dev);
|
||||
int stat_len;
|
||||
pvc_device *pvc;
|
||||
int reptype = -1, error, no_ram;
|
||||
u8 rxseq, txseq;
|
||||
int i;
|
||||
int lmi = hdlc->state.fr.settings.lmi;
|
||||
int dce = hdlc->state.fr.settings.dce;
|
||||
int stat_len = (lmi == LMI_CISCO) ? 6 : 3, reptype, error, no_ram, i;
|
||||
|
||||
if (skb->len < ((hdlc->state.fr.settings.lmi == LMI_ANSI)
|
||||
? LMI_ANSI_LENGTH : LMI_LENGTH)) {
|
||||
if (skb->len < (lmi == LMI_ANSI ? LMI_ANSI_LENGTH :
|
||||
LMI_CCITT_CISCO_LENGTH)) {
|
||||
printk(KERN_INFO "%s: Short LMI frame\n", dev->name);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (skb->data[5] != (!hdlc->state.fr.settings.dce ?
|
||||
LMI_STATUS : LMI_STATUS_ENQUIRY)) {
|
||||
printk(KERN_INFO "%s: LMI msgtype=%x, Not LMI status %s\n",
|
||||
dev->name, skb->data[2],
|
||||
hdlc->state.fr.settings.dce ? "enquiry" : "reply");
|
||||
if (skb->data[3] != (lmi == LMI_CISCO ? NLPID_CISCO_LMI :
|
||||
NLPID_CCITT_ANSI_LMI)) {
|
||||
printk(KERN_INFO "%s: Received non-LMI frame with LMI"
|
||||
" DLCI\n", dev->name);
|
||||
return 1;
|
||||
}
|
||||
|
||||
i = (hdlc->state.fr.settings.lmi == LMI_ANSI) ? 7 : 6;
|
||||
if (skb->data[4] != LMI_CALLREF) {
|
||||
printk(KERN_INFO "%s: Invalid LMI Call reference (0x%02X)\n",
|
||||
dev->name, skb->data[4]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (skb->data[i] !=
|
||||
((hdlc->state.fr.settings.lmi == LMI_CCITT)
|
||||
? LMI_CCITT_REPTYPE : LMI_REPTYPE)) {
|
||||
printk(KERN_INFO "%s: Not a report type=%x\n",
|
||||
if (skb->data[5] != (dce ? LMI_STATUS_ENQUIRY : LMI_STATUS)) {
|
||||
printk(KERN_INFO "%s: Invalid LMI Message type (0x%02X)\n",
|
||||
dev->name, skb->data[5]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (lmi == LMI_ANSI) {
|
||||
if (skb->data[6] != LMI_ANSI_LOCKSHIFT) {
|
||||
printk(KERN_INFO "%s: Not ANSI locking shift in LMI"
|
||||
" message (0x%02X)\n", dev->name, skb->data[6]);
|
||||
return 1;
|
||||
}
|
||||
i = 7;
|
||||
} else
|
||||
i = 6;
|
||||
|
||||
if (skb->data[i] != (lmi == LMI_CCITT ? LMI_CCITT_REPTYPE :
|
||||
LMI_ANSI_CISCO_REPTYPE)) {
|
||||
printk(KERN_INFO "%s: Not an LMI Report type IE (0x%02X)\n",
|
||||
dev->name, skb->data[i]);
|
||||
return 1;
|
||||
}
|
||||
i++;
|
||||
|
||||
i++; /* Skip length field */
|
||||
if (skb->data[++i] != LMI_REPT_LEN) {
|
||||
printk(KERN_INFO "%s: Invalid LMI Report type IE length"
|
||||
" (%u)\n", dev->name, skb->data[i]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
reptype = skb->data[i++];
|
||||
reptype = skb->data[++i];
|
||||
if (reptype != LMI_INTEGRITY && reptype != LMI_FULLREP) {
|
||||
printk(KERN_INFO "%s: Unsupported LMI Report type (0x%02X)\n",
|
||||
dev->name, reptype);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (skb->data[i]!=
|
||||
((hdlc->state.fr.settings.lmi == LMI_CCITT)
|
||||
? LMI_CCITT_ALIVE : LMI_ALIVE)) {
|
||||
printk(KERN_INFO "%s: Unsupported status element=%x\n",
|
||||
dev->name, skb->data[i]);
|
||||
if (skb->data[++i] != (lmi == LMI_CCITT ? LMI_CCITT_ALIVE :
|
||||
LMI_ANSI_CISCO_ALIVE)) {
|
||||
printk(KERN_INFO "%s: Not an LMI Link integrity verification"
|
||||
" IE (0x%02X)\n", dev->name, skb->data[i]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (skb->data[++i] != LMI_INTEG_LEN) {
|
||||
printk(KERN_INFO "%s: Invalid LMI Link integrity verification"
|
||||
" IE length (%u)\n", dev->name, skb->data[i]);
|
||||
return 1;
|
||||
}
|
||||
i++;
|
||||
|
||||
i++; /* Skip length field */
|
||||
|
||||
hdlc->state.fr.rxseq = skb->data[i++]; /* TX sequence from peer */
|
||||
rxseq = skb->data[i++]; /* Should confirm our sequence */
|
||||
|
||||
txseq = hdlc->state.fr.txseq;
|
||||
|
||||
if (hdlc->state.fr.settings.dce) {
|
||||
if (reptype != LMI_FULLREP && reptype != LMI_INTEGRITY) {
|
||||
printk(KERN_INFO "%s: Unsupported report type=%x\n",
|
||||
dev->name, reptype);
|
||||
return 1;
|
||||
}
|
||||
if (dce)
|
||||
hdlc->state.fr.last_poll = jiffies;
|
||||
}
|
||||
|
||||
error = 0;
|
||||
if (!hdlc->state.fr.reliable)
|
||||
|
@ -703,7 +727,7 @@ static int fr_lmi_recv(struct net_device *dev, struct sk_buff *skb)
|
|||
error = 1;
|
||||
}
|
||||
|
||||
if (hdlc->state.fr.settings.dce) {
|
||||
if (dce) {
|
||||
if (hdlc->state.fr.fullrep_sent && !error) {
|
||||
/* Stop sending full report - the last one has been confirmed by DTE */
|
||||
hdlc->state.fr.fullrep_sent = 0;
|
||||
|
@ -725,6 +749,7 @@ static int fr_lmi_recv(struct net_device *dev, struct sk_buff *skb)
|
|||
hdlc->state.fr.dce_changed = 0;
|
||||
}
|
||||
|
||||
hdlc->state.fr.request = 1; /* got request */
|
||||
fr_lmi_send(dev, reptype == LMI_FULLREP ? 1 : 0);
|
||||
return 0;
|
||||
}
|
||||
|
@ -739,7 +764,6 @@ static int fr_lmi_recv(struct net_device *dev, struct sk_buff *skb)
|
|||
if (reptype != LMI_FULLREP)
|
||||
return 0;
|
||||
|
||||
stat_len = 3;
|
||||
pvc = hdlc->state.fr.first_pvc;
|
||||
|
||||
while (pvc) {
|
||||
|
@ -750,24 +774,35 @@ static int fr_lmi_recv(struct net_device *dev, struct sk_buff *skb)
|
|||
no_ram = 0;
|
||||
while (skb->len >= i + 2 + stat_len) {
|
||||
u16 dlci;
|
||||
u32 bw;
|
||||
unsigned int active, new;
|
||||
|
||||
if (skb->data[i] != ((hdlc->state.fr.settings.lmi == LMI_CCITT)
|
||||
? LMI_CCITT_PVCSTAT : LMI_PVCSTAT)) {
|
||||
printk(KERN_WARNING "%s: Invalid PVCSTAT ID: %x\n",
|
||||
dev->name, skb->data[i]);
|
||||
if (skb->data[i] != (lmi == LMI_CCITT ? LMI_CCITT_PVCSTAT :
|
||||
LMI_ANSI_CISCO_PVCSTAT)) {
|
||||
printk(KERN_INFO "%s: Not an LMI PVC status IE"
|
||||
" (0x%02X)\n", dev->name, skb->data[i]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (skb->data[++i] != stat_len) {
|
||||
printk(KERN_INFO "%s: Invalid LMI PVC status IE length"
|
||||
" (%u)\n", dev->name, skb->data[i]);
|
||||
return 1;
|
||||
}
|
||||
i++;
|
||||
|
||||
if (skb->data[i] != stat_len) {
|
||||
printk(KERN_WARNING "%s: Invalid PVCSTAT length: %x\n",
|
||||
dev->name, skb->data[i]);
|
||||
return 1;
|
||||
new = !! (skb->data[i + 2] & 0x08);
|
||||
active = !! (skb->data[i + 2] & 0x02);
|
||||
if (lmi == LMI_CISCO) {
|
||||
dlci = (skb->data[i] << 8) | skb->data[i + 1];
|
||||
bw = (skb->data[i + 3] << 16) |
|
||||
(skb->data[i + 4] << 8) |
|
||||
(skb->data[i + 5]);
|
||||
} else {
|
||||
dlci = ((skb->data[i] & 0x3F) << 4) |
|
||||
((skb->data[i + 1] & 0x78) >> 3);
|
||||
bw = 0;
|
||||
}
|
||||
i++;
|
||||
|
||||
dlci = status_to_dlci(skb->data + i, &active, &new);
|
||||
|
||||
pvc = add_pvc(dev, dlci);
|
||||
|
||||
|
@ -783,9 +818,11 @@ static int fr_lmi_recv(struct net_device *dev, struct sk_buff *skb)
|
|||
pvc->state.deleted = 0;
|
||||
if (active != pvc->state.active ||
|
||||
new != pvc->state.new ||
|
||||
bw != pvc->state.bandwidth ||
|
||||
!pvc->state.exist) {
|
||||
pvc->state.new = new;
|
||||
pvc->state.active = active;
|
||||
pvc->state.bandwidth = bw;
|
||||
pvc_carrier(active, pvc);
|
||||
fr_log_dlci_active(pvc);
|
||||
}
|
||||
|
@ -801,6 +838,7 @@ static int fr_lmi_recv(struct net_device *dev, struct sk_buff *skb)
|
|||
pvc_carrier(0, pvc);
|
||||
pvc->state.active = pvc->state.new = 0;
|
||||
pvc->state.exist = 0;
|
||||
pvc->state.bandwidth = 0;
|
||||
fr_log_dlci_active(pvc);
|
||||
}
|
||||
pvc = pvc->next;
|
||||
|
@ -829,22 +867,15 @@ static int fr_rx(struct sk_buff *skb)
|
|||
|
||||
dlci = q922_to_dlci(skb->data);
|
||||
|
||||
if (dlci == LMI_DLCI) {
|
||||
if (hdlc->state.fr.settings.lmi == LMI_NONE)
|
||||
goto rx_error; /* LMI packet with no LMI? */
|
||||
|
||||
if (data[3] == LMI_PROTO) {
|
||||
if (fr_lmi_recv(ndev, skb))
|
||||
goto rx_error;
|
||||
else {
|
||||
dev_kfree_skb_any(skb);
|
||||
return NET_RX_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
printk(KERN_INFO "%s: Received non-LMI frame with LMI DLCI\n",
|
||||
ndev->name);
|
||||
goto rx_error;
|
||||
if ((dlci == LMI_CCITT_ANSI_DLCI &&
|
||||
(hdlc->state.fr.settings.lmi == LMI_ANSI ||
|
||||
hdlc->state.fr.settings.lmi == LMI_CCITT)) ||
|
||||
(dlci == LMI_CISCO_DLCI &&
|
||||
hdlc->state.fr.settings.lmi == LMI_CISCO)) {
|
||||
if (fr_lmi_recv(ndev, skb))
|
||||
goto rx_error;
|
||||
dev_kfree_skb_any(skb);
|
||||
return NET_RX_SUCCESS;
|
||||
}
|
||||
|
||||
pvc = find_pvc(hdlc, dlci);
|
||||
|
@ -1170,7 +1201,8 @@ int hdlc_fr_ioctl(struct net_device *dev, struct ifreq *ifr)
|
|||
|
||||
if ((new_settings.lmi != LMI_NONE &&
|
||||
new_settings.lmi != LMI_ANSI &&
|
||||
new_settings.lmi != LMI_CCITT) ||
|
||||
new_settings.lmi != LMI_CCITT &&
|
||||
new_settings.lmi != LMI_CISCO) ||
|
||||
new_settings.t391 < 1 ||
|
||||
new_settings.t392 < 2 ||
|
||||
new_settings.n391 < 1 ||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* 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;
|
||||
|
||||
|
|
|
@ -492,6 +492,9 @@ EXPORT_SYMBOL(orinoco_debug);
|
|||
static int suppress_linkstatus; /* = 0 */
|
||||
module_param(suppress_linkstatus, bool, 0644);
|
||||
MODULE_PARM_DESC(suppress_linkstatus, "Don't log link status changes");
|
||||
static int ignore_disconnect; /* = 0 */
|
||||
module_param(ignore_disconnect, int, 0644);
|
||||
MODULE_PARM_DESC(ignore_disconnect, "Don't report lost link to the network layer");
|
||||
|
||||
/********************************************************************/
|
||||
/* Compile time configuration and compatibility stuff */
|
||||
|
@ -604,7 +607,6 @@ struct hermes_rx_descriptor {
|
|||
static int orinoco_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
|
||||
static int __orinoco_program_rids(struct net_device *dev);
|
||||
static void __orinoco_set_multicast_list(struct net_device *dev);
|
||||
static int orinoco_debug_dump_recs(struct net_device *dev);
|
||||
|
||||
/********************************************************************/
|
||||
/* Internal helper functions */
|
||||
|
@ -655,7 +657,7 @@ static int orinoco_open(struct net_device *dev)
|
|||
return err;
|
||||
}
|
||||
|
||||
int orinoco_stop(struct net_device *dev)
|
||||
static int orinoco_stop(struct net_device *dev)
|
||||
{
|
||||
struct orinoco_private *priv = netdev_priv(dev);
|
||||
int err = 0;
|
||||
|
@ -686,7 +688,7 @@ static struct iw_statistics *orinoco_get_wireless_stats(struct net_device *dev)
|
|||
struct orinoco_private *priv = netdev_priv(dev);
|
||||
hermes_t *hw = &priv->hw;
|
||||
struct iw_statistics *wstats = &priv->wstats;
|
||||
int err = 0;
|
||||
int err;
|
||||
unsigned long flags;
|
||||
|
||||
if (! netif_device_present(dev)) {
|
||||
|
@ -695,9 +697,21 @@ static struct iw_statistics *orinoco_get_wireless_stats(struct net_device *dev)
|
|||
return NULL; /* FIXME: Can we do better than this? */
|
||||
}
|
||||
|
||||
/* If busy, return the old stats. Returning NULL may cause
|
||||
* the interface to disappear from /proc/net/wireless */
|
||||
if (orinoco_lock(priv, &flags) != 0)
|
||||
return NULL; /* FIXME: Erg, we've been signalled, how
|
||||
* do we propagate this back up? */
|
||||
return wstats;
|
||||
|
||||
/* We can't really wait for the tallies inquiry command to
|
||||
* complete, so we just use the previous results and trigger
|
||||
* a new tallies inquiry command for next time - Jean II */
|
||||
/* FIXME: Really we should wait for the inquiry to come back -
|
||||
* as it is the stats we give don't make a whole lot of sense.
|
||||
* Unfortunately, it's not clear how to do that within the
|
||||
* wireless extensions framework: I think we're in user
|
||||
* context, but a lock seems to be held by the time we get in
|
||||
* here so we're not safe to sleep here. */
|
||||
hermes_inquire(hw, HERMES_INQ_TALLIES);
|
||||
|
||||
if (priv->iw_mode == IW_MODE_ADHOC) {
|
||||
memset(&wstats->qual, 0, sizeof(wstats->qual));
|
||||
|
@ -716,25 +730,16 @@ static struct iw_statistics *orinoco_get_wireless_stats(struct net_device *dev)
|
|||
|
||||
err = HERMES_READ_RECORD(hw, USER_BAP,
|
||||
HERMES_RID_COMMSQUALITY, &cq);
|
||||
|
||||
wstats->qual.qual = (int)le16_to_cpu(cq.qual);
|
||||
wstats->qual.level = (int)le16_to_cpu(cq.signal) - 0x95;
|
||||
wstats->qual.noise = (int)le16_to_cpu(cq.noise) - 0x95;
|
||||
wstats->qual.updated = 7;
|
||||
|
||||
if (!err) {
|
||||
wstats->qual.qual = (int)le16_to_cpu(cq.qual);
|
||||
wstats->qual.level = (int)le16_to_cpu(cq.signal) - 0x95;
|
||||
wstats->qual.noise = (int)le16_to_cpu(cq.noise) - 0x95;
|
||||
wstats->qual.updated = 7;
|
||||
}
|
||||
}
|
||||
|
||||
/* We can't really wait for the tallies inquiry command to
|
||||
* complete, so we just use the previous results and trigger
|
||||
* a new tallies inquiry command for next time - Jean II */
|
||||
/* FIXME: We're in user context (I think?), so we should just
|
||||
wait for the tallies to come through */
|
||||
err = hermes_inquire(hw, HERMES_INQ_TALLIES);
|
||||
|
||||
orinoco_unlock(priv, &flags);
|
||||
|
||||
if (err)
|
||||
return NULL;
|
||||
|
||||
return wstats;
|
||||
}
|
||||
|
||||
|
@ -1275,9 +1280,10 @@ static void __orinoco_ev_info(struct net_device *dev, hermes_t *hw)
|
|||
len = sizeof(tallies);
|
||||
}
|
||||
|
||||
/* Read directly the data (no seek) */
|
||||
hermes_read_words(hw, HERMES_DATA1, (void *) &tallies,
|
||||
len / 2); /* FIXME: blech! */
|
||||
err = hermes_bap_pread(hw, IRQ_BAP, &tallies, len,
|
||||
infofid, sizeof(info));
|
||||
if (err)
|
||||
break;
|
||||
|
||||
/* Increment our various counters */
|
||||
/* wstats->discard.nwid - no wrong BSSID stuff */
|
||||
|
@ -1307,8 +1313,10 @@ static void __orinoco_ev_info(struct net_device *dev, hermes_t *hw)
|
|||
break;
|
||||
}
|
||||
|
||||
hermes_read_words(hw, HERMES_DATA1, (void *) &linkstatus,
|
||||
len / 2);
|
||||
err = hermes_bap_pread(hw, IRQ_BAP, &linkstatus, len,
|
||||
infofid, sizeof(info));
|
||||
if (err)
|
||||
break;
|
||||
newstatus = le16_to_cpu(linkstatus.linkstatus);
|
||||
|
||||
connected = (newstatus == HERMES_LINKSTATUS_CONNECTED)
|
||||
|
@ -1317,7 +1325,7 @@ static void __orinoco_ev_info(struct net_device *dev, hermes_t *hw)
|
|||
|
||||
if (connected)
|
||||
netif_carrier_on(dev);
|
||||
else
|
||||
else if (!ignore_disconnect)
|
||||
netif_carrier_off(dev);
|
||||
|
||||
if (newstatus != priv->last_linkstatus)
|
||||
|
@ -1350,6 +1358,8 @@ int __orinoco_up(struct net_device *dev)
|
|||
struct hermes *hw = &priv->hw;
|
||||
int err;
|
||||
|
||||
netif_carrier_off(dev); /* just to make sure */
|
||||
|
||||
err = __orinoco_program_rids(dev);
|
||||
if (err) {
|
||||
printk(KERN_ERR "%s: Error %d configuring card\n",
|
||||
|
@ -1413,7 +1423,7 @@ int orinoco_reinit_firmware(struct net_device *dev)
|
|||
return err;
|
||||
|
||||
err = hermes_allocate(hw, priv->nicbuf_size, &priv->txfid);
|
||||
if (err == -EIO) {
|
||||
if (err == -EIO && priv->nicbuf_size > TX_NICBUF_SIZE_BUG) {
|
||||
/* Try workaround for old Symbol firmware bug */
|
||||
printk(KERN_WARNING "%s: firmware ALLOC bug detected "
|
||||
"(old Symbol firmware?). Trying to work around... ",
|
||||
|
@ -1610,17 +1620,15 @@ static int __orinoco_program_rids(struct net_device *dev)
|
|||
return err;
|
||||
}
|
||||
/* Set the channel/frequency */
|
||||
if (priv->channel == 0) {
|
||||
printk(KERN_DEBUG "%s: Channel is 0 in __orinoco_program_rids()\n", dev->name);
|
||||
if (priv->createibss)
|
||||
priv->channel = 10;
|
||||
}
|
||||
err = hermes_write_wordrec(hw, USER_BAP, HERMES_RID_CNFOWNCHANNEL,
|
||||
priv->channel);
|
||||
if (err) {
|
||||
printk(KERN_ERR "%s: Error %d setting channel\n",
|
||||
dev->name, err);
|
||||
return err;
|
||||
if (priv->channel != 0 && priv->iw_mode != IW_MODE_INFRA) {
|
||||
err = hermes_write_wordrec(hw, USER_BAP,
|
||||
HERMES_RID_CNFOWNCHANNEL,
|
||||
priv->channel);
|
||||
if (err) {
|
||||
printk(KERN_ERR "%s: Error %d setting channel %d\n",
|
||||
dev->name, err, priv->channel);
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
if (priv->has_ibss) {
|
||||
|
@ -1916,7 +1924,7 @@ static void orinoco_reset(struct net_device *dev)
|
|||
{
|
||||
struct orinoco_private *priv = netdev_priv(dev);
|
||||
struct hermes *hw = &priv->hw;
|
||||
int err = 0;
|
||||
int err;
|
||||
unsigned long flags;
|
||||
|
||||
if (orinoco_lock(priv, &flags) != 0)
|
||||
|
@ -1938,20 +1946,20 @@ static void orinoco_reset(struct net_device *dev)
|
|||
|
||||
orinoco_unlock(priv, &flags);
|
||||
|
||||
if (priv->hard_reset)
|
||||
if (priv->hard_reset) {
|
||||
err = (*priv->hard_reset)(priv);
|
||||
if (err) {
|
||||
printk(KERN_ERR "%s: orinoco_reset: Error %d "
|
||||
"performing hard reset\n", dev->name, err);
|
||||
/* FIXME: shutdown of some sort */
|
||||
return;
|
||||
if (err) {
|
||||
printk(KERN_ERR "%s: orinoco_reset: Error %d "
|
||||
"performing hard reset\n", dev->name, err);
|
||||
goto disable;
|
||||
}
|
||||
}
|
||||
|
||||
err = orinoco_reinit_firmware(dev);
|
||||
if (err) {
|
||||
printk(KERN_ERR "%s: orinoco_reset: Error %d re-initializing firmware\n",
|
||||
dev->name, err);
|
||||
return;
|
||||
goto disable;
|
||||
}
|
||||
|
||||
spin_lock_irq(&priv->lock); /* This has to be called from user context */
|
||||
|
@ -1972,6 +1980,10 @@ static void orinoco_reset(struct net_device *dev)
|
|||
spin_unlock_irq(&priv->lock);
|
||||
|
||||
return;
|
||||
disable:
|
||||
hermes_set_irqmask(hw, 0);
|
||||
netif_device_detach(dev);
|
||||
printk(KERN_ERR "%s: Device has been disabled!\n", dev->name);
|
||||
}
|
||||
|
||||
/********************************************************************/
|
||||
|
@ -2056,7 +2068,7 @@ irqreturn_t orinoco_interrupt(int irq, void *dev_id, struct pt_regs *regs)
|
|||
if (events & HERMES_EV_ALLOC)
|
||||
__orinoco_ev_alloc(dev, hw);
|
||||
|
||||
hermes_write_regn(hw, EVACK, events);
|
||||
hermes_write_regn(hw, EVACK, evstat);
|
||||
|
||||
evstat = hermes_read_regn(hw, EVSTAT);
|
||||
events = evstat & hw->inten;
|
||||
|
@ -2215,6 +2227,8 @@ static int determine_firmware(struct net_device *dev)
|
|||
firmver >= 0x31000;
|
||||
priv->has_preamble = (firmver >= 0x20000);
|
||||
priv->ibss_port = 4;
|
||||
priv->broken_disableport = (firmver == 0x25013) ||
|
||||
(firmver >= 0x30000 && firmver <= 0x31000);
|
||||
/* Tested with Intel firmware : 0x20015 => Jean II */
|
||||
/* Tested with 3Com firmware : 0x15012 & 0x22001 => Jean II */
|
||||
break;
|
||||
|
@ -2267,7 +2281,7 @@ static int orinoco_init(struct net_device *dev)
|
|||
priv->nicbuf_size = IEEE802_11_FRAME_LEN + ETH_HLEN;
|
||||
|
||||
/* Initialize the firmware */
|
||||
err = hermes_init(hw);
|
||||
err = orinoco_reinit_firmware(dev);
|
||||
if (err != 0) {
|
||||
printk(KERN_ERR "%s: failed to initialize firmware (err = %d)\n",
|
||||
dev->name, err);
|
||||
|
@ -2400,31 +2414,12 @@ static int orinoco_init(struct net_device *dev)
|
|||
/* By default use IEEE/IBSS ad-hoc mode if we have it */
|
||||
priv->prefer_port3 = priv->has_port3 && (! priv->has_ibss);
|
||||
set_port_type(priv);
|
||||
priv->channel = 10; /* default channel, more-or-less arbitrary */
|
||||
priv->channel = 0; /* use firmware default */
|
||||
|
||||
priv->promiscuous = 0;
|
||||
priv->wep_on = 0;
|
||||
priv->tx_key = 0;
|
||||
|
||||
err = hermes_allocate(hw, priv->nicbuf_size, &priv->txfid);
|
||||
if (err == -EIO) {
|
||||
/* Try workaround for old Symbol firmware bug */
|
||||
printk(KERN_WARNING "%s: firmware ALLOC bug detected "
|
||||
"(old Symbol firmware?). Trying to work around... ",
|
||||
dev->name);
|
||||
|
||||
priv->nicbuf_size = TX_NICBUF_SIZE_BUG;
|
||||
err = hermes_allocate(hw, priv->nicbuf_size, &priv->txfid);
|
||||
if (err)
|
||||
printk("failed!\n");
|
||||
else
|
||||
printk("ok.\n");
|
||||
}
|
||||
if (err) {
|
||||
printk("%s: Error %d allocating Tx buffer\n", dev->name, err);
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Make the hardware available, as long as it hasn't been
|
||||
* removed elsewhere (e.g. by PCMCIA hot unplug) */
|
||||
spin_lock_irq(&priv->lock);
|
||||
|
@ -2450,7 +2445,7 @@ struct net_device *alloc_orinocodev(int sizeof_card,
|
|||
priv = netdev_priv(dev);
|
||||
priv->ndev = dev;
|
||||
if (sizeof_card)
|
||||
priv->card = (void *)((unsigned long)netdev_priv(dev)
|
||||
priv->card = (void *)((unsigned long)priv
|
||||
+ sizeof(struct orinoco_private));
|
||||
else
|
||||
priv->card = NULL;
|
||||
|
@ -2555,6 +2550,7 @@ static int orinoco_hw_get_essid(struct orinoco_private *priv, int *active,
|
|||
}
|
||||
|
||||
len = le16_to_cpu(essidbuf.len);
|
||||
BUG_ON(len > IW_ESSID_MAX_SIZE);
|
||||
|
||||
memset(buf, 0, IW_ESSID_MAX_SIZE+1);
|
||||
memcpy(buf, p, len);
|
||||
|
@ -2923,13 +2919,14 @@ static int orinoco_ioctl_setessid(struct net_device *dev, struct iw_point *erq)
|
|||
memset(&essidbuf, 0, sizeof(essidbuf));
|
||||
|
||||
if (erq->flags) {
|
||||
if (erq->length > IW_ESSID_MAX_SIZE)
|
||||
/* iwconfig includes the NUL in the specified length */
|
||||
if (erq->length > IW_ESSID_MAX_SIZE+1)
|
||||
return -E2BIG;
|
||||
|
||||
if (copy_from_user(&essidbuf, erq->pointer, erq->length))
|
||||
return -EFAULT;
|
||||
|
||||
essidbuf[erq->length] = '\0';
|
||||
essidbuf[IW_ESSID_MAX_SIZE] = '\0';
|
||||
}
|
||||
|
||||
if (orinoco_lock(priv, &flags) != 0)
|
||||
|
@ -3855,7 +3852,6 @@ orinoco_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
|
|||
{ SIOCIWFIRSTPRIV + 0x7, 0,
|
||||
IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
|
||||
"get_ibssport" },
|
||||
{ SIOCIWLASTPRIV, 0, 0, "dump_recs" },
|
||||
};
|
||||
|
||||
wrq->u.data.length = sizeof(privtab) / sizeof(privtab[0]);
|
||||
|
@ -3943,14 +3939,6 @@ orinoco_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
|
|||
err = orinoco_ioctl_getibssport(dev, wrq);
|
||||
break;
|
||||
|
||||
case SIOCIWLASTPRIV:
|
||||
err = orinoco_debug_dump_recs(dev);
|
||||
if (err)
|
||||
printk(KERN_ERR "%s: Unable to dump records (%d)\n",
|
||||
dev->name, err);
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
err = -EOPNOTSUPP;
|
||||
}
|
||||
|
@ -3964,187 +3952,6 @@ orinoco_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
|
|||
return err;
|
||||
}
|
||||
|
||||
struct {
|
||||
u16 rid;
|
||||
char *name;
|
||||
int displaytype;
|
||||
#define DISPLAY_WORDS 0
|
||||
#define DISPLAY_BYTES 1
|
||||
#define DISPLAY_STRING 2
|
||||
#define DISPLAY_XSTRING 3
|
||||
} record_table[] = {
|
||||
#define DEBUG_REC(name,type) { HERMES_RID_##name, #name, DISPLAY_##type }
|
||||
DEBUG_REC(CNFPORTTYPE,WORDS),
|
||||
DEBUG_REC(CNFOWNMACADDR,BYTES),
|
||||
DEBUG_REC(CNFDESIREDSSID,STRING),
|
||||
DEBUG_REC(CNFOWNCHANNEL,WORDS),
|
||||
DEBUG_REC(CNFOWNSSID,STRING),
|
||||
DEBUG_REC(CNFOWNATIMWINDOW,WORDS),
|
||||
DEBUG_REC(CNFSYSTEMSCALE,WORDS),
|
||||
DEBUG_REC(CNFMAXDATALEN,WORDS),
|
||||
DEBUG_REC(CNFPMENABLED,WORDS),
|
||||
DEBUG_REC(CNFPMEPS,WORDS),
|
||||
DEBUG_REC(CNFMULTICASTRECEIVE,WORDS),
|
||||
DEBUG_REC(CNFMAXSLEEPDURATION,WORDS),
|
||||
DEBUG_REC(CNFPMHOLDOVERDURATION,WORDS),
|
||||
DEBUG_REC(CNFOWNNAME,STRING),
|
||||
DEBUG_REC(CNFOWNDTIMPERIOD,WORDS),
|
||||
DEBUG_REC(CNFMULTICASTPMBUFFERING,WORDS),
|
||||
DEBUG_REC(CNFWEPENABLED_AGERE,WORDS),
|
||||
DEBUG_REC(CNFMANDATORYBSSID_SYMBOL,WORDS),
|
||||
DEBUG_REC(CNFWEPDEFAULTKEYID,WORDS),
|
||||
DEBUG_REC(CNFDEFAULTKEY0,BYTES),
|
||||
DEBUG_REC(CNFDEFAULTKEY1,BYTES),
|
||||
DEBUG_REC(CNFMWOROBUST_AGERE,WORDS),
|
||||
DEBUG_REC(CNFDEFAULTKEY2,BYTES),
|
||||
DEBUG_REC(CNFDEFAULTKEY3,BYTES),
|
||||
DEBUG_REC(CNFWEPFLAGS_INTERSIL,WORDS),
|
||||
DEBUG_REC(CNFWEPKEYMAPPINGTABLE,WORDS),
|
||||
DEBUG_REC(CNFAUTHENTICATION,WORDS),
|
||||
DEBUG_REC(CNFMAXASSOCSTA,WORDS),
|
||||
DEBUG_REC(CNFKEYLENGTH_SYMBOL,WORDS),
|
||||
DEBUG_REC(CNFTXCONTROL,WORDS),
|
||||
DEBUG_REC(CNFROAMINGMODE,WORDS),
|
||||
DEBUG_REC(CNFHOSTAUTHENTICATION,WORDS),
|
||||
DEBUG_REC(CNFRCVCRCERROR,WORDS),
|
||||
DEBUG_REC(CNFMMLIFE,WORDS),
|
||||
DEBUG_REC(CNFALTRETRYCOUNT,WORDS),
|
||||
DEBUG_REC(CNFBEACONINT,WORDS),
|
||||
DEBUG_REC(CNFAPPCFINFO,WORDS),
|
||||
DEBUG_REC(CNFSTAPCFINFO,WORDS),
|
||||
DEBUG_REC(CNFPRIORITYQUSAGE,WORDS),
|
||||
DEBUG_REC(CNFTIMCTRL,WORDS),
|
||||
DEBUG_REC(CNFTHIRTY2TALLY,WORDS),
|
||||
DEBUG_REC(CNFENHSECURITY,WORDS),
|
||||
DEBUG_REC(CNFGROUPADDRESSES,BYTES),
|
||||
DEBUG_REC(CNFCREATEIBSS,WORDS),
|
||||
DEBUG_REC(CNFFRAGMENTATIONTHRESHOLD,WORDS),
|
||||
DEBUG_REC(CNFRTSTHRESHOLD,WORDS),
|
||||
DEBUG_REC(CNFTXRATECONTROL,WORDS),
|
||||
DEBUG_REC(CNFPROMISCUOUSMODE,WORDS),
|
||||
DEBUG_REC(CNFBASICRATES_SYMBOL,WORDS),
|
||||
DEBUG_REC(CNFPREAMBLE_SYMBOL,WORDS),
|
||||
DEBUG_REC(CNFSHORTPREAMBLE,WORDS),
|
||||
DEBUG_REC(CNFWEPKEYS_AGERE,BYTES),
|
||||
DEBUG_REC(CNFEXCLUDELONGPREAMBLE,WORDS),
|
||||
DEBUG_REC(CNFTXKEY_AGERE,WORDS),
|
||||
DEBUG_REC(CNFAUTHENTICATIONRSPTO,WORDS),
|
||||
DEBUG_REC(CNFBASICRATES,WORDS),
|
||||
DEBUG_REC(CNFSUPPORTEDRATES,WORDS),
|
||||
DEBUG_REC(CNFTICKTIME,WORDS),
|
||||
DEBUG_REC(CNFSCANREQUEST,WORDS),
|
||||
DEBUG_REC(CNFJOINREQUEST,WORDS),
|
||||
DEBUG_REC(CNFAUTHENTICATESTATION,WORDS),
|
||||
DEBUG_REC(CNFCHANNELINFOREQUEST,WORDS),
|
||||
DEBUG_REC(MAXLOADTIME,WORDS),
|
||||
DEBUG_REC(DOWNLOADBUFFER,WORDS),
|
||||
DEBUG_REC(PRIID,WORDS),
|
||||
DEBUG_REC(PRISUPRANGE,WORDS),
|
||||
DEBUG_REC(CFIACTRANGES,WORDS),
|
||||
DEBUG_REC(NICSERNUM,XSTRING),
|
||||
DEBUG_REC(NICID,WORDS),
|
||||
DEBUG_REC(MFISUPRANGE,WORDS),
|
||||
DEBUG_REC(CFISUPRANGE,WORDS),
|
||||
DEBUG_REC(CHANNELLIST,WORDS),
|
||||
DEBUG_REC(REGULATORYDOMAINS,WORDS),
|
||||
DEBUG_REC(TEMPTYPE,WORDS),
|
||||
/* DEBUG_REC(CIS,BYTES), */
|
||||
DEBUG_REC(STAID,WORDS),
|
||||
DEBUG_REC(CURRENTSSID,STRING),
|
||||
DEBUG_REC(CURRENTBSSID,BYTES),
|
||||
DEBUG_REC(COMMSQUALITY,WORDS),
|
||||
DEBUG_REC(CURRENTTXRATE,WORDS),
|
||||
DEBUG_REC(CURRENTBEACONINTERVAL,WORDS),
|
||||
DEBUG_REC(CURRENTSCALETHRESHOLDS,WORDS),
|
||||
DEBUG_REC(PROTOCOLRSPTIME,WORDS),
|
||||
DEBUG_REC(SHORTRETRYLIMIT,WORDS),
|
||||
DEBUG_REC(LONGRETRYLIMIT,WORDS),
|
||||
DEBUG_REC(MAXTRANSMITLIFETIME,WORDS),
|
||||
DEBUG_REC(MAXRECEIVELIFETIME,WORDS),
|
||||
DEBUG_REC(CFPOLLABLE,WORDS),
|
||||
DEBUG_REC(AUTHENTICATIONALGORITHMS,WORDS),
|
||||
DEBUG_REC(PRIVACYOPTIONIMPLEMENTED,WORDS),
|
||||
DEBUG_REC(OWNMACADDR,BYTES),
|
||||
DEBUG_REC(SCANRESULTSTABLE,WORDS),
|
||||
DEBUG_REC(PHYTYPE,WORDS),
|
||||
DEBUG_REC(CURRENTCHANNEL,WORDS),
|
||||
DEBUG_REC(CURRENTPOWERSTATE,WORDS),
|
||||
DEBUG_REC(CCAMODE,WORDS),
|
||||
DEBUG_REC(SUPPORTEDDATARATES,WORDS),
|
||||
DEBUG_REC(BUILDSEQ,BYTES),
|
||||
DEBUG_REC(FWID,XSTRING)
|
||||
#undef DEBUG_REC
|
||||
};
|
||||
|
||||
#define DEBUG_LTV_SIZE 128
|
||||
|
||||
static int orinoco_debug_dump_recs(struct net_device *dev)
|
||||
{
|
||||
struct orinoco_private *priv = netdev_priv(dev);
|
||||
hermes_t *hw = &priv->hw;
|
||||
u8 *val8;
|
||||
u16 *val16;
|
||||
int i,j;
|
||||
u16 length;
|
||||
int err;
|
||||
|
||||
/* I'm not sure: we might have a lock here, so we'd better go
|
||||
atomic, just in case. */
|
||||
val8 = kmalloc(DEBUG_LTV_SIZE + 2, GFP_ATOMIC);
|
||||
if (! val8)
|
||||
return -ENOMEM;
|
||||
val16 = (u16 *)val8;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(record_table); i++) {
|
||||
u16 rid = record_table[i].rid;
|
||||
int len;
|
||||
|
||||
memset(val8, 0, DEBUG_LTV_SIZE + 2);
|
||||
|
||||
err = hermes_read_ltv(hw, USER_BAP, rid, DEBUG_LTV_SIZE,
|
||||
&length, val8);
|
||||
if (err) {
|
||||
DEBUG(0, "Error %d reading RID 0x%04x\n", err, rid);
|
||||
continue;
|
||||
}
|
||||
val16 = (u16 *)val8;
|
||||
if (length == 0)
|
||||
continue;
|
||||
|
||||
printk(KERN_DEBUG "%-15s (0x%04x): length=%d (%d bytes)\tvalue=",
|
||||
record_table[i].name,
|
||||
rid, length, (length-1)*2);
|
||||
len = min(((int)length-1)*2, DEBUG_LTV_SIZE);
|
||||
|
||||
switch (record_table[i].displaytype) {
|
||||
case DISPLAY_WORDS:
|
||||
for (j = 0; j < len / 2; j++)
|
||||
printk("%04X-", le16_to_cpu(val16[j]));
|
||||
break;
|
||||
|
||||
case DISPLAY_BYTES:
|
||||
default:
|
||||
for (j = 0; j < len; j++)
|
||||
printk("%02X:", val8[j]);
|
||||
break;
|
||||
|
||||
case DISPLAY_STRING:
|
||||
len = min(len, le16_to_cpu(val16[0])+2);
|
||||
val8[len] = '\0';
|
||||
printk("\"%s\"", (char *)&val16[1]);
|
||||
break;
|
||||
|
||||
case DISPLAY_XSTRING:
|
||||
printk("'%s'", (char *)val8);
|
||||
}
|
||||
|
||||
printk("\n");
|
||||
}
|
||||
|
||||
kfree(val8);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/********************************************************************/
|
||||
/* Debugging */
|
||||
|
@ -4218,7 +4025,6 @@ EXPORT_SYMBOL(free_orinocodev);
|
|||
|
||||
EXPORT_SYMBOL(__orinoco_up);
|
||||
EXPORT_SYMBOL(__orinoco_down);
|
||||
EXPORT_SYMBOL(orinoco_stop);
|
||||
EXPORT_SYMBOL(orinoco_reinit_firmware);
|
||||
|
||||
EXPORT_SYMBOL(orinoco_interrupt);
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
/* 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 */
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* 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*/
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
/*
|
||||
* This file define a set of standard wireless extensions
|
||||
*
|
||||
* Version : 17 21.6.04
|
||||
* Version : 18 12.3.05
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef _LINUX_WIRELESS_H
|
||||
|
@ -82,7 +82,7 @@
|
|||
* (there is some stuff that will be added in the future...)
|
||||
* I just plan to increment with each new version.
|
||||
*/
|
||||
#define WIRELESS_EXT 17
|
||||
#define WIRELESS_EXT 18
|
||||
|
||||
/*
|
||||
* Changes :
|
||||
|
@ -182,6 +182,21 @@
|
|||
* - Document (struct iw_quality *)->updated, add new flags (INVALID)
|
||||
* - Wireless Event capability in struct iw_range
|
||||
* - Add support for relative TxPower (yick !)
|
||||
*
|
||||
* V17 to V18 (From Jouni Malinen <jkmaline@cc.hut.fi>)
|
||||
* ----------
|
||||
* - Add support for WPA/WPA2
|
||||
* - Add extended encoding configuration (SIOCSIWENCODEEXT and
|
||||
* SIOCGIWENCODEEXT)
|
||||
* - Add SIOCSIWGENIE/SIOCGIWGENIE
|
||||
* - Add SIOCSIWMLME
|
||||
* - Add SIOCSIWPMKSA
|
||||
* - Add struct iw_range bit field for supported encoding capabilities
|
||||
* - Add optional scan request parameters for SIOCSIWSCAN
|
||||
* - Add SIOCSIWAUTH/SIOCGIWAUTH for setting authentication and WPA
|
||||
* related parameters (extensible up to 4096 parameter values)
|
||||
* - Add wireless events: IWEVGENIE, IWEVMICHAELMICFAILURE,
|
||||
* IWEVASSOCREQIE, IWEVASSOCRESPIE, IWEVPMKIDCAND
|
||||
*/
|
||||
|
||||
/**************************** CONSTANTS ****************************/
|
||||
|
@ -256,6 +271,30 @@
|
|||
#define SIOCSIWPOWER 0x8B2C /* set Power Management settings */
|
||||
#define SIOCGIWPOWER 0x8B2D /* get Power Management settings */
|
||||
|
||||
/* WPA : Generic IEEE 802.11 informatiom element (e.g., for WPA/RSN/WMM).
|
||||
* This ioctl uses struct iw_point and data buffer that includes IE id and len
|
||||
* fields. More than one IE may be included in the request. Setting the generic
|
||||
* IE to empty buffer (len=0) removes the generic IE from the driver. Drivers
|
||||
* are allowed to generate their own WPA/RSN IEs, but in these cases, drivers
|
||||
* are required to report the used IE as a wireless event, e.g., when
|
||||
* associating with an AP. */
|
||||
#define SIOCSIWGENIE 0x8B30 /* set generic IE */
|
||||
#define SIOCGIWGENIE 0x8B31 /* get generic IE */
|
||||
|
||||
/* WPA : IEEE 802.11 MLME requests */
|
||||
#define SIOCSIWMLME 0x8B16 /* request MLME operation; uses
|
||||
* struct iw_mlme */
|
||||
/* WPA : Authentication mode parameters */
|
||||
#define SIOCSIWAUTH 0x8B32 /* set authentication mode params */
|
||||
#define SIOCGIWAUTH 0x8B33 /* get authentication mode params */
|
||||
|
||||
/* WPA : Extended version of encoding configuration */
|
||||
#define SIOCSIWENCODEEXT 0x8B34 /* set encoding token & mode */
|
||||
#define SIOCGIWENCODEEXT 0x8B35 /* get encoding token & mode */
|
||||
|
||||
/* WPA2 : PMKSA cache management */
|
||||
#define SIOCSIWPMKSA 0x8B36 /* PMKSA cache operation */
|
||||
|
||||
/* -------------------- DEV PRIVATE IOCTL LIST -------------------- */
|
||||
|
||||
/* These 32 ioctl are wireless device private, for 16 commands.
|
||||
|
@ -297,6 +336,34 @@
|
|||
#define IWEVCUSTOM 0x8C02 /* Driver specific ascii string */
|
||||
#define IWEVREGISTERED 0x8C03 /* Discovered a new node (AP mode) */
|
||||
#define IWEVEXPIRED 0x8C04 /* Expired a node (AP mode) */
|
||||
#define IWEVGENIE 0x8C05 /* Generic IE (WPA, RSN, WMM, ..)
|
||||
* (scan results); This includes id and
|
||||
* length fields. One IWEVGENIE may
|
||||
* contain more than one IE. Scan
|
||||
* results may contain one or more
|
||||
* IWEVGENIE events. */
|
||||
#define IWEVMICHAELMICFAILURE 0x8C06 /* Michael MIC failure
|
||||
* (struct iw_michaelmicfailure)
|
||||
*/
|
||||
#define IWEVASSOCREQIE 0x8C07 /* IEs used in (Re)Association Request.
|
||||
* The data includes id and length
|
||||
* fields and may contain more than one
|
||||
* IE. This event is required in
|
||||
* Managed mode if the driver
|
||||
* generates its own WPA/RSN IE. This
|
||||
* should be sent just before
|
||||
* IWEVREGISTERED event for the
|
||||
* association. */
|
||||
#define IWEVASSOCRESPIE 0x8C08 /* IEs used in (Re)Association
|
||||
* Response. The data includes id and
|
||||
* length fields and may contain more
|
||||
* than one IE. This may be sent
|
||||
* between IWEVASSOCREQIE and
|
||||
* IWEVREGISTERED events for the
|
||||
* association. */
|
||||
#define IWEVPMKIDCAND 0x8C09 /* PMKID candidate for RSN
|
||||
* pre-authentication
|
||||
* (struct iw_pmkid_cand) */
|
||||
|
||||
#define IWEVFIRST 0x8C00
|
||||
|
||||
|
@ -432,12 +499,94 @@
|
|||
#define IW_SCAN_THIS_MODE 0x0020 /* Scan only this Mode */
|
||||
#define IW_SCAN_ALL_RATE 0x0040 /* Scan all Bit-Rates */
|
||||
#define IW_SCAN_THIS_RATE 0x0080 /* Scan only this Bit-Rate */
|
||||
/* struct iw_scan_req scan_type */
|
||||
#define IW_SCAN_TYPE_ACTIVE 0
|
||||
#define IW_SCAN_TYPE_PASSIVE 1
|
||||
/* Maximum size of returned data */
|
||||
#define IW_SCAN_MAX_DATA 4096 /* In bytes */
|
||||
|
||||
/* Max number of char in custom event - use multiple of them if needed */
|
||||
#define IW_CUSTOM_MAX 256 /* In bytes */
|
||||
|
||||
/* Generic information element */
|
||||
#define IW_GENERIC_IE_MAX 1024
|
||||
|
||||
/* MLME requests (SIOCSIWMLME / struct iw_mlme) */
|
||||
#define IW_MLME_DEAUTH 0
|
||||
#define IW_MLME_DISASSOC 1
|
||||
|
||||
/* SIOCSIWAUTH/SIOCGIWAUTH struct iw_param flags */
|
||||
#define IW_AUTH_INDEX 0x0FFF
|
||||
#define IW_AUTH_FLAGS 0xF000
|
||||
/* SIOCSIWAUTH/SIOCGIWAUTH parameters (0 .. 4095)
|
||||
* (IW_AUTH_INDEX mask in struct iw_param flags; this is the index of the
|
||||
* parameter that is being set/get to; value will be read/written to
|
||||
* struct iw_param value field) */
|
||||
#define IW_AUTH_WPA_VERSION 0
|
||||
#define IW_AUTH_CIPHER_PAIRWISE 1
|
||||
#define IW_AUTH_CIPHER_GROUP 2
|
||||
#define IW_AUTH_KEY_MGMT 3
|
||||
#define IW_AUTH_TKIP_COUNTERMEASURES 4
|
||||
#define IW_AUTH_DROP_UNENCRYPTED 5
|
||||
#define IW_AUTH_80211_AUTH_ALG 6
|
||||
#define IW_AUTH_WPA_ENABLED 7
|
||||
#define IW_AUTH_RX_UNENCRYPTED_EAPOL 8
|
||||
#define IW_AUTH_ROAMING_CONTROL 9
|
||||
#define IW_AUTH_PRIVACY_INVOKED 10
|
||||
|
||||
/* IW_AUTH_WPA_VERSION values (bit field) */
|
||||
#define IW_AUTH_WPA_VERSION_DISABLED 0x00000001
|
||||
#define IW_AUTH_WPA_VERSION_WPA 0x00000002
|
||||
#define IW_AUTH_WPA_VERSION_WPA2 0x00000004
|
||||
|
||||
/* IW_AUTH_PAIRWISE_CIPHER and IW_AUTH_GROUP_CIPHER values (bit field) */
|
||||
#define IW_AUTH_CIPHER_NONE 0x00000001
|
||||
#define IW_AUTH_CIPHER_WEP40 0x00000002
|
||||
#define IW_AUTH_CIPHER_TKIP 0x00000004
|
||||
#define IW_AUTH_CIPHER_CCMP 0x00000008
|
||||
#define IW_AUTH_CIPHER_WEP104 0x00000010
|
||||
|
||||
/* IW_AUTH_KEY_MGMT values (bit field) */
|
||||
#define IW_AUTH_KEY_MGMT_802_1X 1
|
||||
#define IW_AUTH_KEY_MGMT_PSK 2
|
||||
|
||||
/* IW_AUTH_80211_AUTH_ALG values (bit field) */
|
||||
#define IW_AUTH_ALG_OPEN_SYSTEM 0x00000001
|
||||
#define IW_AUTH_ALG_SHARED_KEY 0x00000002
|
||||
#define IW_AUTH_ALG_LEAP 0x00000004
|
||||
|
||||
/* IW_AUTH_ROAMING_CONTROL values */
|
||||
#define IW_AUTH_ROAMING_ENABLE 0 /* driver/firmware based roaming */
|
||||
#define IW_AUTH_ROAMING_DISABLE 1 /* user space program used for roaming
|
||||
* control */
|
||||
|
||||
/* SIOCSIWENCODEEXT definitions */
|
||||
#define IW_ENCODE_SEQ_MAX_SIZE 8
|
||||
/* struct iw_encode_ext ->alg */
|
||||
#define IW_ENCODE_ALG_NONE 0
|
||||
#define IW_ENCODE_ALG_WEP 1
|
||||
#define IW_ENCODE_ALG_TKIP 2
|
||||
#define IW_ENCODE_ALG_CCMP 3
|
||||
/* struct iw_encode_ext ->ext_flags */
|
||||
#define IW_ENCODE_EXT_TX_SEQ_VALID 0x00000001
|
||||
#define IW_ENCODE_EXT_RX_SEQ_VALID 0x00000002
|
||||
#define IW_ENCODE_EXT_GROUP_KEY 0x00000004
|
||||
#define IW_ENCODE_EXT_SET_TX_KEY 0x00000008
|
||||
|
||||
/* IWEVMICHAELMICFAILURE : struct iw_michaelmicfailure ->flags */
|
||||
#define IW_MICFAILURE_KEY_ID 0x00000003 /* Key ID 0..3 */
|
||||
#define IW_MICFAILURE_GROUP 0x00000004
|
||||
#define IW_MICFAILURE_PAIRWISE 0x00000008
|
||||
#define IW_MICFAILURE_STAKEY 0x00000010
|
||||
#define IW_MICFAILURE_COUNT 0x00000060 /* 1 or 2 (0 = count not supported)
|
||||
*/
|
||||
|
||||
/* Bit field values for enc_capa in struct iw_range */
|
||||
#define IW_ENC_CAPA_WPA 0x00000001
|
||||
#define IW_ENC_CAPA_WPA2 0x00000002
|
||||
#define IW_ENC_CAPA_CIPHER_TKIP 0x00000004
|
||||
#define IW_ENC_CAPA_CIPHER_CCMP 0x00000008
|
||||
|
||||
/* Event capability macros - in (struct iw_range *)->event_capa
|
||||
* Because we have more than 32 possible events, we use an array of
|
||||
* 32 bit bitmasks. Note : 32 bits = 0x20 = 2^5. */
|
||||
|
@ -546,6 +695,132 @@ struct iw_thrspy
|
|||
struct iw_quality high; /* High threshold */
|
||||
};
|
||||
|
||||
/*
|
||||
* Optional data for scan request
|
||||
*
|
||||
* Note: these optional parameters are controlling parameters for the
|
||||
* scanning behavior, these do not apply to getting scan results
|
||||
* (SIOCGIWSCAN). Drivers are expected to keep a local BSS table and
|
||||
* provide a merged results with all BSSes even if the previous scan
|
||||
* request limited scanning to a subset, e.g., by specifying an SSID.
|
||||
* Especially, scan results are required to include an entry for the
|
||||
* current BSS if the driver is in Managed mode and associated with an AP.
|
||||
*/
|
||||
struct iw_scan_req
|
||||
{
|
||||
__u8 scan_type; /* IW_SCAN_TYPE_{ACTIVE,PASSIVE} */
|
||||
__u8 essid_len;
|
||||
__u8 num_channels; /* num entries in channel_list;
|
||||
* 0 = scan all allowed channels */
|
||||
__u8 flags; /* reserved as padding; use zero, this may
|
||||
* be used in the future for adding flags
|
||||
* to request different scan behavior */
|
||||
struct sockaddr bssid; /* ff:ff:ff:ff:ff:ff for broadcast BSSID or
|
||||
* individual address of a specific BSS */
|
||||
|
||||
/*
|
||||
* Use this ESSID if IW_SCAN_THIS_ESSID flag is used instead of using
|
||||
* the current ESSID. This allows scan requests for specific ESSID
|
||||
* without having to change the current ESSID and potentially breaking
|
||||
* the current association.
|
||||
*/
|
||||
__u8 essid[IW_ESSID_MAX_SIZE];
|
||||
|
||||
/*
|
||||
* Optional parameters for changing the default scanning behavior.
|
||||
* These are based on the MLME-SCAN.request from IEEE Std 802.11.
|
||||
* TU is 1.024 ms. If these are set to 0, driver is expected to use
|
||||
* reasonable default values. min_channel_time defines the time that
|
||||
* will be used to wait for the first reply on each channel. If no
|
||||
* replies are received, next channel will be scanned after this. If
|
||||
* replies are received, total time waited on the channel is defined by
|
||||
* max_channel_time.
|
||||
*/
|
||||
__u32 min_channel_time; /* in TU */
|
||||
__u32 max_channel_time; /* in TU */
|
||||
|
||||
struct iw_freq channel_list[IW_MAX_FREQUENCIES];
|
||||
};
|
||||
|
||||
/* ------------------------- WPA SUPPORT ------------------------- */
|
||||
|
||||
/*
|
||||
* Extended data structure for get/set encoding (this is used with
|
||||
* SIOCSIWENCODEEXT/SIOCGIWENCODEEXT. struct iw_point and IW_ENCODE_*
|
||||
* flags are used in the same way as with SIOCSIWENCODE/SIOCGIWENCODE and
|
||||
* only the data contents changes (key data -> this structure, including
|
||||
* key data).
|
||||
*
|
||||
* If the new key is the first group key, it will be set as the default
|
||||
* TX key. Otherwise, default TX key index is only changed if
|
||||
* IW_ENCODE_EXT_SET_TX_KEY flag is set.
|
||||
*
|
||||
* Key will be changed with SIOCSIWENCODEEXT in all cases except for
|
||||
* special "change TX key index" operation which is indicated by setting
|
||||
* key_len = 0 and ext_flags |= IW_ENCODE_EXT_SET_TX_KEY.
|
||||
*
|
||||
* tx_seq/rx_seq are only used when respective
|
||||
* IW_ENCODE_EXT_{TX,RX}_SEQ_VALID flag is set in ext_flags. Normal
|
||||
* TKIP/CCMP operation is to set RX seq with SIOCSIWENCODEEXT and start
|
||||
* TX seq from zero whenever key is changed. SIOCGIWENCODEEXT is normally
|
||||
* used only by an Authenticator (AP or an IBSS station) to get the
|
||||
* current TX sequence number. Using TX_SEQ_VALID for SIOCSIWENCODEEXT and
|
||||
* RX_SEQ_VALID for SIOCGIWENCODEEXT are optional, but can be useful for
|
||||
* debugging/testing.
|
||||
*/
|
||||
struct iw_encode_ext
|
||||
{
|
||||
__u32 ext_flags; /* IW_ENCODE_EXT_* */
|
||||
__u8 tx_seq[IW_ENCODE_SEQ_MAX_SIZE]; /* LSB first */
|
||||
__u8 rx_seq[IW_ENCODE_SEQ_MAX_SIZE]; /* LSB first */
|
||||
struct sockaddr addr; /* ff:ff:ff:ff:ff:ff for broadcast/multicast
|
||||
* (group) keys or unicast address for
|
||||
* individual keys */
|
||||
__u16 alg; /* IW_ENCODE_ALG_* */
|
||||
__u16 key_len;
|
||||
__u8 key[0];
|
||||
};
|
||||
|
||||
/* SIOCSIWMLME data */
|
||||
struct iw_mlme
|
||||
{
|
||||
__u16 cmd; /* IW_MLME_* */
|
||||
__u16 reason_code;
|
||||
struct sockaddr addr;
|
||||
};
|
||||
|
||||
/* SIOCSIWPMKSA data */
|
||||
#define IW_PMKSA_ADD 1
|
||||
#define IW_PMKSA_REMOVE 2
|
||||
#define IW_PMKSA_FLUSH 3
|
||||
|
||||
#define IW_PMKID_LEN 16
|
||||
|
||||
struct iw_pmksa
|
||||
{
|
||||
__u32 cmd; /* IW_PMKSA_* */
|
||||
struct sockaddr bssid;
|
||||
__u8 pmkid[IW_PMKID_LEN];
|
||||
};
|
||||
|
||||
/* IWEVMICHAELMICFAILURE data */
|
||||
struct iw_michaelmicfailure
|
||||
{
|
||||
__u32 flags;
|
||||
struct sockaddr src_addr;
|
||||
__u8 tsc[IW_ENCODE_SEQ_MAX_SIZE]; /* LSB first */
|
||||
};
|
||||
|
||||
/* IWEVPMKIDCAND data */
|
||||
#define IW_PMKID_CAND_PREAUTH 0x00000001 /* RNS pre-authentication enabled */
|
||||
struct iw_pmkid_cand
|
||||
{
|
||||
__u32 flags; /* IW_PMKID_CAND_* */
|
||||
__u32 index; /* the smaller the index, the higher the
|
||||
* priority */
|
||||
struct sockaddr bssid;
|
||||
};
|
||||
|
||||
/* ------------------------ WIRELESS STATS ------------------------ */
|
||||
/*
|
||||
* Wireless statistics (used for /proc/net/wireless)
|
||||
|
@ -725,6 +1000,8 @@ struct iw_range
|
|||
struct iw_freq freq[IW_MAX_FREQUENCIES]; /* list */
|
||||
/* Note : this frequency list doesn't need to fit channel numbers,
|
||||
* because each entry contain its channel index */
|
||||
|
||||
__u32 enc_capa; /* IW_ENC_CAPA_* bit field */
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
|
@ -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));
|
||||
|
|
Loading…
Reference in New Issue