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
38 changed files with 9410 additions and 3851 deletions
|
@ -1,21 +1,21 @@
|
||||||
Generic HDLC layer
|
Generic HDLC layer
|
||||||
Krzysztof Halasa <khc@pm.waw.pl>
|
Krzysztof Halasa <khc@pm.waw.pl>
|
||||||
January, 2003
|
|
||||||
|
|
||||||
|
|
||||||
Generic HDLC layer currently supports:
|
Generic HDLC layer currently supports:
|
||||||
- Frame Relay (ANSI, CCITT and no LMI), with ARP support (no InARP).
|
1. Frame Relay (ANSI, CCITT, Cisco and no LMI).
|
||||||
Normal (routed) and Ethernet-bridged (Ethernet device emulation)
|
- Normal (routed) and Ethernet-bridged (Ethernet device emulation)
|
||||||
interfaces can share a single PVC.
|
interfaces can share a single PVC.
|
||||||
- raw HDLC - either IP (IPv4) interface or Ethernet device emulation.
|
- ARP support (no InARP support in the kernel - there is an
|
||||||
- Cisco HDLC,
|
experimental InARP user-space daemon available on:
|
||||||
- PPP (uses syncppp.c),
|
http://www.kernel.org/pub/linux/utils/net/hdlc/).
|
||||||
- X.25 (uses X.25 routines).
|
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:
|
Generic HDLC is a protocol driver only - it needs a low-level driver
|
||||||
- C101 by Moxa Technologies Co., Ltd.
|
for your particular hardware.
|
||||||
- RISCom/N2 by SDL Communications Inc.
|
|
||||||
- and others, some not in the official kernel.
|
|
||||||
|
|
||||||
Ethernet device emulation (using HDLC or Frame-Relay PVC) is compatible
|
Ethernet device emulation (using HDLC or Frame-Relay PVC) is compatible
|
||||||
with IEEE 802.1Q (VLANs) and 802.1D (Ethernet bridging).
|
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
|
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
|
create a number of "hdlc" (hdlc0 etc) network devices, one for each
|
||||||
WAN port. You'll need the "sethdlc" utility, get it from:
|
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:
|
Compile sethdlc.c utility:
|
||||||
gcc -O2 -Wall -o sethdlc sethdlc.c
|
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
|
* v35 | rs232 | x21 | t1 | e1 - sets physical interface for a given port
|
||||||
if the card has software-selectable interfaces
|
if the card has software-selectable interfaces
|
||||||
loopback - activate hardware loopback (for testing only)
|
loopback - activate hardware loopback (for testing only)
|
||||||
* clock ext - external clock (uses DTE RX and TX clock)
|
* clock ext - both RX clock and TX clock external
|
||||||
* clock int - internal clock (provides clock signal on DCE clock output)
|
* clock int - both RX clock and TX clock internal
|
||||||
* clock txint - TX internal, RX external (provides TX clock on DCE output)
|
* clock txint - RX clock external, TX clock internal
|
||||||
* clock txfromrx - TX clock derived from RX clock (TX clock on DCE output)
|
* clock txfromrx - RX clock external, TX clock derived from RX clock
|
||||||
* rate - sets clock rate in bps (not required for external clock or
|
* rate - sets clock rate in bps (for "int" or "txint" clock only)
|
||||||
for txfromrx)
|
|
||||||
|
|
||||||
Setting protocol:
|
Setting protocol:
|
||||||
|
|
||||||
|
@ -79,7 +79,7 @@ Setting protocol:
|
||||||
* x25 - sets X.25 mode
|
* x25 - sets X.25 mode
|
||||||
|
|
||||||
* fr - Frame Relay 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).
|
dce - Frame Relay DCE (network) side LMI instead of default DTE (user).
|
||||||
It has nothing to do with clocks!
|
It has nothing to do with clocks!
|
||||||
t391 - link integrity verification polling timer (in seconds) - user
|
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"
|
If you have a problem with N2, C101 or PLX200SYN card, you can issue the
|
||||||
command to see port's packet descriptor rings (in kernel logs):
|
"private" command to see port's packet descriptor rings (in kernel logs):
|
||||||
|
|
||||||
sethdlc hdlc0 private
|
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
|
Attaching this info to bug reports would be helpful. Anyway, let me know
|
||||||
if you have problems using this.
|
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(#)
|
ni65 YES YES YES Software(#)
|
||||||
seeq NO NO NO N/A
|
seeq NO NO NO N/A
|
||||||
sgiseek <------------------ Buggy ------------------>
|
sgiseek <------------------ Buggy ------------------>
|
||||||
sk_g16 NO NO YES N/A
|
|
||||||
smc-ultra YES YES YES Hardware
|
smc-ultra YES YES YES Hardware
|
||||||
sunlance YES YES YES Hardware
|
sunlance YES YES YES Hardware
|
||||||
tulip YES YES YES Hardware
|
tulip YES YES YES Hardware
|
||||||
|
|
|
@ -284,9 +284,6 @@ ppp.c:
|
||||||
seeq8005.c: *Not modularized*
|
seeq8005.c: *Not modularized*
|
||||||
(Probes ports: 0x300, 0x320, 0x340, 0x360)
|
(Probes ports: 0x300, 0x320, 0x340, 0x360)
|
||||||
|
|
||||||
sk_g16.c: *Not modularized*
|
|
||||||
(Probes ports: 0x100, 0x180, 0x208, 0x220m 0x288, 0x320, 0x328, 0x390)
|
|
||||||
|
|
||||||
skeleton.c: *Skeleton*
|
skeleton.c: *Skeleton*
|
||||||
|
|
||||||
slhc.c:
|
slhc.c:
|
||||||
|
|
|
@ -54,6 +54,7 @@
|
||||||
|
|
||||||
#include <linux/config.h>
|
#include <linux/config.h>
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
|
#include <linux/moduleparam.h>
|
||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
#include <linux/compiler.h>
|
#include <linux/compiler.h>
|
||||||
#include <linux/netdevice.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_AUTHOR("Jeff Garzik <jgarzik@pobox.com>");
|
||||||
MODULE_DESCRIPTION("RealTek RTL-8139C+ series 10/100 PCI Ethernet driver");
|
MODULE_DESCRIPTION("RealTek RTL-8139C+ series 10/100 PCI Ethernet driver");
|
||||||
|
MODULE_VERSION(DRV_VERSION);
|
||||||
MODULE_LICENSE("GPL");
|
MODULE_LICENSE("GPL");
|
||||||
|
|
||||||
static int debug = -1;
|
static int debug = -1;
|
||||||
MODULE_PARM (debug, "i");
|
module_param(debug, int, 0);
|
||||||
MODULE_PARM_DESC (debug, "8139cp: bitmapped message enable number");
|
MODULE_PARM_DESC (debug, "8139cp: bitmapped message enable number");
|
||||||
|
|
||||||
/* Maximum number of multicast addresses to filter (vs. Rx-all-multicast).
|
/* 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. */
|
The RTL chips use a 64 element hash table based on the Ethernet CRC. */
|
||||||
static int multicast_filter_limit = 32;
|
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");
|
MODULE_PARM_DESC (multicast_filter_limit, "8139cp: maximum number of filtered multicast addresses");
|
||||||
|
|
||||||
#define PFX DRV_NAME ": "
|
#define PFX DRV_NAME ": "
|
||||||
|
@ -186,6 +188,9 @@ enum {
|
||||||
RingEnd = (1 << 30), /* End of descriptor ring */
|
RingEnd = (1 << 30), /* End of descriptor ring */
|
||||||
FirstFrag = (1 << 29), /* First segment of a packet */
|
FirstFrag = (1 << 29), /* First segment of a packet */
|
||||||
LastFrag = (1 << 28), /* Final 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 */
|
TxError = (1 << 23), /* Tx error summary */
|
||||||
RxError = (1 << 20), /* Rx error summary */
|
RxError = (1 << 20), /* Rx error summary */
|
||||||
IPCS = (1 << 18), /* Calculate IP checksum */
|
IPCS = (1 << 18), /* Calculate IP checksum */
|
||||||
|
@ -312,7 +317,7 @@ struct cp_desc {
|
||||||
struct ring_info {
|
struct ring_info {
|
||||||
struct sk_buff *skb;
|
struct sk_buff *skb;
|
||||||
dma_addr_t mapping;
|
dma_addr_t mapping;
|
||||||
unsigned frag;
|
u32 len;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct cp_dma_stats {
|
struct cp_dma_stats {
|
||||||
|
@ -394,6 +399,9 @@ struct cp_private {
|
||||||
static void __cp_set_rx_mode (struct net_device *dev);
|
static void __cp_set_rx_mode (struct net_device *dev);
|
||||||
static void cp_tx (struct cp_private *cp);
|
static void cp_tx (struct cp_private *cp);
|
||||||
static void cp_clean_rings (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[] = {
|
static struct pci_device_id cp_pci_tbl[] = {
|
||||||
{ PCI_VENDOR_ID_REALTEK, PCI_DEVICE_ID_REALTEK_8139,
|
{ 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;
|
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)
|
static void cp_tx (struct cp_private *cp)
|
||||||
{
|
{
|
||||||
unsigned tx_head = cp->tx_head;
|
unsigned tx_head = cp->tx_head;
|
||||||
|
@ -707,7 +728,7 @@ static void cp_tx (struct cp_private *cp)
|
||||||
BUG();
|
BUG();
|
||||||
|
|
||||||
pci_unmap_single(cp->pdev, cp->tx_skb[tx_tail].mapping,
|
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 & LastFrag) {
|
||||||
if (status & (TxError | TxFIFOUnder)) {
|
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);
|
struct cp_private *cp = netdev_priv(dev);
|
||||||
unsigned entry;
|
unsigned entry;
|
||||||
u32 eor;
|
u32 eor, flags;
|
||||||
#if CP_VLAN_TAG_USED
|
#if CP_VLAN_TAG_USED
|
||||||
u32 vlan_tag = 0;
|
u32 vlan_tag = 0;
|
||||||
#endif
|
#endif
|
||||||
|
int mss = 0;
|
||||||
|
|
||||||
spin_lock_irq(&cp->lock);
|
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;
|
entry = cp->tx_head;
|
||||||
eor = (entry == (CP_TX_RING_SIZE - 1)) ? RingEnd : 0;
|
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) {
|
if (skb_shinfo(skb)->nr_frags == 0) {
|
||||||
struct cp_desc *txd = &cp->tx_ring[entry];
|
struct cp_desc *txd = &cp->tx_ring[entry];
|
||||||
u32 len;
|
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);
|
txd->addr = cpu_to_le64(mapping);
|
||||||
wmb();
|
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;
|
const struct iphdr *ip = skb->nh.iph;
|
||||||
if (ip->protocol == IPPROTO_TCP)
|
if (ip->protocol == IPPROTO_TCP)
|
||||||
txd->opts1 = cpu_to_le32(eor | len | DescOwn |
|
flags |= IPCS | TCPCS;
|
||||||
FirstFrag | LastFrag |
|
|
||||||
IPCS | TCPCS);
|
|
||||||
else if (ip->protocol == IPPROTO_UDP)
|
else if (ip->protocol == IPPROTO_UDP)
|
||||||
txd->opts1 = cpu_to_le32(eor | len | DescOwn |
|
flags |= IPCS | UDPCS;
|
||||||
FirstFrag | LastFrag |
|
|
||||||
IPCS | UDPCS);
|
|
||||||
else
|
else
|
||||||
BUG();
|
WARN_ON(1); /* we need a WARN() */
|
||||||
} else
|
}
|
||||||
txd->opts1 = cpu_to_le32(eor | len | DescOwn |
|
|
||||||
FirstFrag | LastFrag);
|
txd->opts1 = cpu_to_le32(flags);
|
||||||
wmb();
|
wmb();
|
||||||
|
|
||||||
cp->tx_skb[entry].skb = skb;
|
cp->tx_skb[entry].skb = skb;
|
||||||
cp->tx_skb[entry].mapping = mapping;
|
cp->tx_skb[entry].mapping = mapping;
|
||||||
cp->tx_skb[entry].frag = 0;
|
cp->tx_skb[entry].len = len;
|
||||||
entry = NEXT_TX(entry);
|
entry = NEXT_TX(entry);
|
||||||
} else {
|
} else {
|
||||||
struct cp_desc *txd;
|
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);
|
first_len, PCI_DMA_TODEVICE);
|
||||||
cp->tx_skb[entry].skb = skb;
|
cp->tx_skb[entry].skb = skb;
|
||||||
cp->tx_skb[entry].mapping = first_mapping;
|
cp->tx_skb[entry].mapping = first_mapping;
|
||||||
cp->tx_skb[entry].frag = 1;
|
cp->tx_skb[entry].len = first_len;
|
||||||
entry = NEXT_TX(entry);
|
entry = NEXT_TX(entry);
|
||||||
|
|
||||||
for (frag = 0; frag < skb_shinfo(skb)->nr_frags; frag++) {
|
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);
|
len, PCI_DMA_TODEVICE);
|
||||||
eor = (entry == (CP_TX_RING_SIZE - 1)) ? RingEnd : 0;
|
eor = (entry == (CP_TX_RING_SIZE - 1)) ? RingEnd : 0;
|
||||||
|
|
||||||
if (skb->ip_summed == CHECKSUM_HW) {
|
ctrl = eor | len | DescOwn;
|
||||||
ctrl = eor | len | DescOwn | IPCS;
|
|
||||||
|
if (mss)
|
||||||
|
ctrl |= LargeSend |
|
||||||
|
((mss & MSSMask) << MSSShift);
|
||||||
|
else if (skb->ip_summed == CHECKSUM_HW) {
|
||||||
if (ip->protocol == IPPROTO_TCP)
|
if (ip->protocol == IPPROTO_TCP)
|
||||||
ctrl |= TCPCS;
|
ctrl |= IPCS | TCPCS;
|
||||||
else if (ip->protocol == IPPROTO_UDP)
|
else if (ip->protocol == IPPROTO_UDP)
|
||||||
ctrl |= UDPCS;
|
ctrl |= IPCS | UDPCS;
|
||||||
else
|
else
|
||||||
BUG();
|
BUG();
|
||||||
} else
|
}
|
||||||
ctrl = eor | len | DescOwn;
|
|
||||||
|
|
||||||
if (frag == skb_shinfo(skb)->nr_frags - 1)
|
if (frag == skb_shinfo(skb)->nr_frags - 1)
|
||||||
ctrl |= LastFrag;
|
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].skb = skb;
|
||||||
cp->tx_skb[entry].mapping = mapping;
|
cp->tx_skb[entry].mapping = mapping;
|
||||||
cp->tx_skb[entry].frag = frag + 2;
|
cp->tx_skb[entry].len = len;
|
||||||
entry = NEXT_TX(entry);
|
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,
|
cp->rx_skb[i].mapping = pci_map_single(cp->pdev,
|
||||||
skb->tail, cp->rx_buf_sz, PCI_DMA_FROMDEVICE);
|
skb->tail, cp->rx_buf_sz, PCI_DMA_FROMDEVICE);
|
||||||
cp->rx_skb[i].skb = skb;
|
cp->rx_skb[i].skb = skb;
|
||||||
cp->rx_skb[i].frag = 0;
|
|
||||||
|
|
||||||
cp->rx_ring[i].opts2 = 0;
|
cp->rx_ring[i].opts2 = 0;
|
||||||
cp->rx_ring[i].addr = cpu_to_le64(cp->rx_skb[i].mapping);
|
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;
|
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++) {
|
for (i = 0; i < CP_RX_RING_SIZE; i++) {
|
||||||
if (cp->rx_skb[i].skb) {
|
if (cp->rx_skb[i].skb) {
|
||||||
pci_unmap_single(cp->pdev, cp->rx_skb[i].mapping,
|
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++) {
|
for (i = 0; i < CP_TX_RING_SIZE; i++) {
|
||||||
if (cp->tx_skb[i].skb) {
|
if (cp->tx_skb[i].skb) {
|
||||||
struct sk_buff *skb = cp->tx_skb[i].skb;
|
struct sk_buff *skb = cp->tx_skb[i].skb;
|
||||||
|
|
||||||
pci_unmap_single(cp->pdev, cp->tx_skb[i].mapping,
|
pci_unmap_single(cp->pdev, cp->tx_skb[i].mapping,
|
||||||
skb->len, PCI_DMA_TODEVICE);
|
cp->tx_skb[i].len, PCI_DMA_TODEVICE);
|
||||||
dev_kfree_skb(skb);
|
if (le32_to_cpu(cp->tx_ring[i].opts1) & LastFrag)
|
||||||
|
dev_kfree_skb(skb);
|
||||||
cp->net_stats.tx_dropped++;
|
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->rx_skb, 0, sizeof(struct ring_info) * CP_RX_RING_SIZE);
|
||||||
memset(&cp->tx_skb, 0, sizeof(struct ring_info) * CP_TX_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! */
|
.set_tx_csum = ethtool_op_set_tx_csum, /* local! */
|
||||||
.get_sg = ethtool_op_get_sg,
|
.get_sg = ethtool_op_get_sg,
|
||||||
.set_sg = ethtool_op_set_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_regs = cp_get_regs,
|
||||||
.get_wol = cp_get_wol,
|
.get_wol = cp_get_wol,
|
||||||
.set_wol = cp_set_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->get_stats = cp_get_stats;
|
||||||
dev->do_ioctl = cp_ioctl;
|
dev->do_ioctl = cp_ioctl;
|
||||||
dev->poll = cp_rx_poll;
|
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. */
|
dev->weight = 16; /* arbitrary? from NAPI_HOWTO.txt. */
|
||||||
#ifdef BROKEN
|
#ifdef BROKEN
|
||||||
dev->change_mtu = cp_change_mtu;
|
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)
|
if (pci_using_dac)
|
||||||
dev->features |= NETIF_F_HIGHDMA;
|
dev->features |= NETIF_F_HIGHDMA;
|
||||||
|
|
||||||
|
#if 0 /* disabled by default until verified */
|
||||||
|
dev->features |= NETIF_F_TSO;
|
||||||
|
#endif
|
||||||
|
|
||||||
dev->irq = pdev->irq;
|
dev->irq = pdev->irq;
|
||||||
|
|
||||||
rc = register_netdev(dev);
|
rc = register_netdev(dev);
|
||||||
|
|
|
@ -569,7 +569,7 @@ struct rtl_extra_stats {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct rtl8139_private {
|
struct rtl8139_private {
|
||||||
void *mmio_addr;
|
void __iomem *mmio_addr;
|
||||||
int drv_flags;
|
int drv_flags;
|
||||||
struct pci_dev *pci_dev;
|
struct pci_dev *pci_dev;
|
||||||
u32 msg_enable;
|
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 (media, "8139too: Bits 4+9: force full duplex, bit 5: 100Mbps");
|
||||||
MODULE_PARM_DESC (full_duplex, "8139too: Force full duplex for board(s) (1)");
|
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 rtl8139_open (struct net_device *dev);
|
||||||
static int mdio_read (struct net_device *dev, int phy_id, int location);
|
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,
|
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 void rtl8139_hw_start (struct net_device *dev);
|
||||||
static struct ethtool_ops rtl8139_ethtool_ops;
|
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 */
|
/* write MMIO register, with flush */
|
||||||
/* Flush avoids rtl8139 bug w/ posted MMIO writes */
|
/* 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_W8_F(reg, val8) do { iowrite8 ((val8), ioaddr + (reg)); ioread8 (ioaddr + (reg)); } while (0)
|
||||||
#define RTL_W16_F(reg, val16) do { writew ((val16), ioaddr + (reg)); readw (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 { writel ((val32), ioaddr + (reg)); readl (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
|
#define MMIO_FLUSH_AUDIT_COMPLETE 1
|
||||||
#if MMIO_FLUSH_AUDIT_COMPLETE
|
#if MMIO_FLUSH_AUDIT_COMPLETE
|
||||||
|
|
||||||
/* write MMIO register */
|
/* write MMIO register */
|
||||||
#define RTL_W8(reg, val8) writeb ((val8), ioaddr + (reg))
|
#define RTL_W8(reg, val8) iowrite8 ((val8), ioaddr + (reg))
|
||||||
#define RTL_W16(reg, val16) writew ((val16), ioaddr + (reg))
|
#define RTL_W16(reg, val16) iowrite16 ((val16), ioaddr + (reg))
|
||||||
#define RTL_W32(reg, val32) writel ((val32), ioaddr + (reg))
|
#define RTL_W32(reg, val32) iowrite32 ((val32), ioaddr + (reg))
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
|
@ -689,11 +663,9 @@ static struct ethtool_ops rtl8139_ethtool_ops;
|
||||||
#endif /* MMIO_FLUSH_AUDIT_COMPLETE */
|
#endif /* MMIO_FLUSH_AUDIT_COMPLETE */
|
||||||
|
|
||||||
/* read MMIO register */
|
/* read MMIO register */
|
||||||
#define RTL_R8(reg) readb (ioaddr + (reg))
|
#define RTL_R8(reg) ioread8 (ioaddr + (reg))
|
||||||
#define RTL_R16(reg) readw (ioaddr + (reg))
|
#define RTL_R16(reg) ioread16 (ioaddr + (reg))
|
||||||
#define RTL_R32(reg) ((unsigned long) readl (ioaddr + (reg)))
|
#define RTL_R32(reg) ((unsigned long) ioread32 (ioaddr + (reg)))
|
||||||
|
|
||||||
#endif /* USE_IO_OPS */
|
|
||||||
|
|
||||||
|
|
||||||
static const u16 rtl8139_intr_mask =
|
static const u16 rtl8139_intr_mask =
|
||||||
|
@ -740,10 +712,13 @@ static void __rtl8139_cleanup_dev (struct net_device *dev)
|
||||||
assert (tp->pci_dev != NULL);
|
assert (tp->pci_dev != NULL);
|
||||||
pdev = tp->pci_dev;
|
pdev = tp->pci_dev;
|
||||||
|
|
||||||
#ifndef USE_IO_OPS
|
#ifdef USE_IO_OPS
|
||||||
if (tp->mmio_addr)
|
if (tp->mmio_addr)
|
||||||
iounmap (tp->mmio_addr);
|
ioport_unmap (tp->mmio_addr);
|
||||||
#endif /* !USE_IO_OPS */
|
#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 */
|
/* it's ok to call this even if we have no regions to free */
|
||||||
pci_release_regions (pdev);
|
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;
|
int i;
|
||||||
|
|
||||||
|
@ -773,7 +748,7 @@ static void rtl8139_chip_reset (void *ioaddr)
|
||||||
static int __devinit rtl8139_init_board (struct pci_dev *pdev,
|
static int __devinit rtl8139_init_board (struct pci_dev *pdev,
|
||||||
struct net_device **dev_out)
|
struct net_device **dev_out)
|
||||||
{
|
{
|
||||||
void *ioaddr;
|
void __iomem *ioaddr;
|
||||||
struct net_device *dev;
|
struct net_device *dev;
|
||||||
struct rtl8139_private *tp;
|
struct rtl8139_private *tp;
|
||||||
u8 tmp8;
|
u8 tmp8;
|
||||||
|
@ -855,13 +830,18 @@ static int __devinit rtl8139_init_board (struct pci_dev *pdev,
|
||||||
pci_set_master (pdev);
|
pci_set_master (pdev);
|
||||||
|
|
||||||
#ifdef USE_IO_OPS
|
#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;
|
dev->base_addr = pio_start;
|
||||||
tp->mmio_addr = ioaddr;
|
tp->mmio_addr = ioaddr;
|
||||||
tp->regs_len = pio_len;
|
tp->regs_len = pio_len;
|
||||||
#else
|
#else
|
||||||
/* ioremap MMIO region */
|
/* ioremap MMIO region */
|
||||||
ioaddr = ioremap (mmio_start, mmio_len);
|
ioaddr = pci_iomap(pdev, 1, 0);
|
||||||
if (ioaddr == NULL) {
|
if (ioaddr == NULL) {
|
||||||
printk (KERN_ERR PFX "%s: cannot remap MMIO, aborting\n", pci_name(pdev));
|
printk (KERN_ERR PFX "%s: cannot remap MMIO, aborting\n", pci_name(pdev));
|
||||||
rc = -EIO;
|
rc = -EIO;
|
||||||
|
@ -947,7 +927,7 @@ static int __devinit rtl8139_init_one (struct pci_dev *pdev,
|
||||||
struct net_device *dev = NULL;
|
struct net_device *dev = NULL;
|
||||||
struct rtl8139_private *tp;
|
struct rtl8139_private *tp;
|
||||||
int i, addr_len, option;
|
int i, addr_len, option;
|
||||||
void *ioaddr;
|
void __iomem *ioaddr;
|
||||||
static int board_idx = -1;
|
static int board_idx = -1;
|
||||||
u8 pci_rev;
|
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.
|
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. */
|
/* The EEPROM commands include the alway-set leading bit. */
|
||||||
#define EE_WRITE_CMD (5)
|
#define EE_WRITE_CMD (5)
|
||||||
#define EE_READ_CMD (6)
|
#define EE_READ_CMD (6)
|
||||||
#define EE_ERASE_CMD (7)
|
#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;
|
int i;
|
||||||
unsigned retval = 0;
|
unsigned retval = 0;
|
||||||
void *ee_addr = ioaddr + Cfg9346;
|
|
||||||
int read_cmd = location | (EE_READ_CMD << addr_len);
|
int read_cmd = location | (EE_READ_CMD << addr_len);
|
||||||
|
|
||||||
writeb (EE_ENB & ~EE_CS, ee_addr);
|
RTL_W8 (Cfg9346, EE_ENB & ~EE_CS);
|
||||||
writeb (EE_ENB, ee_addr);
|
RTL_W8 (Cfg9346, EE_ENB);
|
||||||
eeprom_delay ();
|
eeprom_delay ();
|
||||||
|
|
||||||
/* Shift the read command bits out. */
|
/* Shift the read command bits out. */
|
||||||
for (i = 4 + addr_len; i >= 0; i--) {
|
for (i = 4 + addr_len; i >= 0; i--) {
|
||||||
int dataval = (read_cmd & (1 << i)) ? EE_DATA_WRITE : 0;
|
int dataval = (read_cmd & (1 << i)) ? EE_DATA_WRITE : 0;
|
||||||
writeb (EE_ENB | dataval, ee_addr);
|
RTL_W8 (Cfg9346, EE_ENB | dataval);
|
||||||
eeprom_delay ();
|
eeprom_delay ();
|
||||||
writeb (EE_ENB | dataval | EE_SHIFT_CLK, ee_addr);
|
RTL_W8 (Cfg9346, EE_ENB | dataval | EE_SHIFT_CLK);
|
||||||
eeprom_delay ();
|
eeprom_delay ();
|
||||||
}
|
}
|
||||||
writeb (EE_ENB, ee_addr);
|
RTL_W8 (Cfg9346, EE_ENB);
|
||||||
eeprom_delay ();
|
eeprom_delay ();
|
||||||
|
|
||||||
for (i = 16; i > 0; i--) {
|
for (i = 16; i > 0; i--) {
|
||||||
writeb (EE_ENB | EE_SHIFT_CLK, ee_addr);
|
RTL_W8 (Cfg9346, EE_ENB | EE_SHIFT_CLK);
|
||||||
eeprom_delay ();
|
eeprom_delay ();
|
||||||
retval =
|
retval =
|
||||||
(retval << 1) | ((readb (ee_addr) & EE_DATA_READ) ? 1 :
|
(retval << 1) | ((RTL_R8 (Cfg9346) & EE_DATA_READ) ? 1 :
|
||||||
0);
|
0);
|
||||||
writeb (EE_ENB, ee_addr);
|
RTL_W8 (Cfg9346, EE_ENB);
|
||||||
eeprom_delay ();
|
eeprom_delay ();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Terminate the EEPROM access. */
|
/* Terminate the EEPROM access. */
|
||||||
writeb (~EE_CS, ee_addr);
|
RTL_W8 (Cfg9346, ~EE_CS);
|
||||||
eeprom_delay ();
|
eeprom_delay ();
|
||||||
|
|
||||||
return retval;
|
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_WRITE0 (MDIO_DIR)
|
||||||
#define MDIO_WRITE1 (MDIO_DIR | MDIO_DATA_OUT)
|
#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] = {
|
static char mii_2_8139_map[8] = {
|
||||||
|
@ -1223,15 +1202,15 @@ static char mii_2_8139_map[8] = {
|
||||||
|
|
||||||
#ifdef CONFIG_8139TOO_8129
|
#ifdef CONFIG_8139TOO_8129
|
||||||
/* Syncronize the MII management interface by shifting 32 one bits out. */
|
/* 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;
|
int i;
|
||||||
|
|
||||||
for (i = 32; i >= 0; i--) {
|
for (i = 32; i >= 0; i--) {
|
||||||
writeb (MDIO_WRITE1, mdio_addr);
|
RTL_W8 (Config4, MDIO_WRITE1);
|
||||||
mdio_delay (mdio_addr);
|
mdio_delay ();
|
||||||
writeb (MDIO_WRITE1 | MDIO_CLK, mdio_addr);
|
RTL_W8 (Config4, MDIO_WRITE1 | MDIO_CLK);
|
||||||
mdio_delay (mdio_addr);
|
mdio_delay ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#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);
|
struct rtl8139_private *tp = netdev_priv(dev);
|
||||||
int retval = 0;
|
int retval = 0;
|
||||||
#ifdef CONFIG_8139TOO_8129
|
#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 mii_cmd = (0xf6 << 10) | (phy_id << 5) | location;
|
||||||
int i;
|
int i;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (phy_id > 31) { /* Really a 8139. Use internal registers. */
|
if (phy_id > 31) { /* Really a 8139. Use internal registers. */
|
||||||
|
void __iomem *ioaddr = tp->mmio_addr;
|
||||||
return location < 8 && mii_2_8139_map[location] ?
|
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
|
#ifdef CONFIG_8139TOO_8129
|
||||||
mdio_sync (mdio_addr);
|
mdio_sync (ioaddr);
|
||||||
/* Shift the read command bits out. */
|
/* Shift the read command bits out. */
|
||||||
for (i = 15; i >= 0; i--) {
|
for (i = 15; i >= 0; i--) {
|
||||||
int dataval = (mii_cmd & (1 << i)) ? MDIO_DATA_OUT : 0;
|
int dataval = (mii_cmd & (1 << i)) ? MDIO_DATA_OUT : 0;
|
||||||
|
|
||||||
writeb (MDIO_DIR | dataval, mdio_addr);
|
RTL_W8 (Config4, MDIO_DIR | dataval);
|
||||||
mdio_delay (mdio_addr);
|
mdio_delay ();
|
||||||
writeb (MDIO_DIR | dataval | MDIO_CLK, mdio_addr);
|
RTL_W8 (Config4, MDIO_DIR | dataval | MDIO_CLK);
|
||||||
mdio_delay (mdio_addr);
|
mdio_delay ();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Read the two transition, 16 data, and wire-idle bits. */
|
/* Read the two transition, 16 data, and wire-idle bits. */
|
||||||
for (i = 19; i > 0; i--) {
|
for (i = 19; i > 0; i--) {
|
||||||
writeb (0, mdio_addr);
|
RTL_W8 (Config4, 0);
|
||||||
mdio_delay (mdio_addr);
|
mdio_delay ();
|
||||||
retval = (retval << 1) | ((readb (mdio_addr) & MDIO_DATA_IN) ? 1 : 0);
|
retval = (retval << 1) | ((RTL_R8 (Config4) & MDIO_DATA_IN) ? 1 : 0);
|
||||||
writeb (MDIO_CLK, mdio_addr);
|
RTL_W8 (Config4, MDIO_CLK);
|
||||||
mdio_delay (mdio_addr);
|
mdio_delay ();
|
||||||
}
|
}
|
||||||
#endif
|
#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);
|
struct rtl8139_private *tp = netdev_priv(dev);
|
||||||
#ifdef CONFIG_8139TOO_8129
|
#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 mii_cmd = (0x5002 << 16) | (phy_id << 23) | (location << 18) | value;
|
||||||
int i;
|
int i;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (phy_id > 31) { /* Really a 8139. Use internal registers. */
|
if (phy_id > 31) { /* Really a 8139. Use internal registers. */
|
||||||
void *ioaddr = tp->mmio_addr;
|
void __iomem *ioaddr = tp->mmio_addr;
|
||||||
if (location == 0) {
|
if (location == 0) {
|
||||||
RTL_W8 (Cfg9346, Cfg9346_Unlock);
|
RTL_W8 (Cfg9346, Cfg9346_Unlock);
|
||||||
RTL_W16 (BasicModeCtrl, value);
|
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
|
#ifdef CONFIG_8139TOO_8129
|
||||||
mdio_sync (mdio_addr);
|
mdio_sync (ioaddr);
|
||||||
|
|
||||||
/* Shift the command bits out. */
|
/* Shift the command bits out. */
|
||||||
for (i = 31; i >= 0; i--) {
|
for (i = 31; i >= 0; i--) {
|
||||||
int dataval =
|
int dataval =
|
||||||
(mii_cmd & (1 << i)) ? MDIO_WRITE1 : MDIO_WRITE0;
|
(mii_cmd & (1 << i)) ? MDIO_WRITE1 : MDIO_WRITE0;
|
||||||
writeb (dataval, mdio_addr);
|
RTL_W8 (Config4, dataval);
|
||||||
mdio_delay (mdio_addr);
|
mdio_delay ();
|
||||||
writeb (dataval | MDIO_CLK, mdio_addr);
|
RTL_W8 (Config4, dataval | MDIO_CLK);
|
||||||
mdio_delay (mdio_addr);
|
mdio_delay ();
|
||||||
}
|
}
|
||||||
/* Clear out extra bits. */
|
/* Clear out extra bits. */
|
||||||
for (i = 2; i > 0; i--) {
|
for (i = 2; i > 0; i--) {
|
||||||
writeb (0, mdio_addr);
|
RTL_W8 (Config4, 0);
|
||||||
mdio_delay (mdio_addr);
|
mdio_delay ();
|
||||||
writeb (MDIO_CLK, mdio_addr);
|
RTL_W8 (Config4, MDIO_CLK);
|
||||||
mdio_delay (mdio_addr);
|
mdio_delay ();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -1325,7 +1305,7 @@ static int rtl8139_open (struct net_device *dev)
|
||||||
{
|
{
|
||||||
struct rtl8139_private *tp = netdev_priv(dev);
|
struct rtl8139_private *tp = netdev_priv(dev);
|
||||||
int retval;
|
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);
|
retval = request_irq (dev->irq, rtl8139_interrupt, SA_SHIRQ, dev->name, dev);
|
||||||
if (retval)
|
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)
|
static void rtl8139_hw_start (struct net_device *dev)
|
||||||
{
|
{
|
||||||
struct rtl8139_private *tp = netdev_priv(dev);
|
struct rtl8139_private *tp = netdev_priv(dev);
|
||||||
void *ioaddr = tp->mmio_addr;
|
void __iomem *ioaddr = tp->mmio_addr;
|
||||||
u32 i;
|
u32 i;
|
||||||
u8 tmp;
|
u8 tmp;
|
||||||
|
|
||||||
|
@ -1484,7 +1464,7 @@ static void rtl8139_tune_twister (struct net_device *dev,
|
||||||
struct rtl8139_private *tp)
|
struct rtl8139_private *tp)
|
||||||
{
|
{
|
||||||
int linkcase;
|
int linkcase;
|
||||||
void *ioaddr = tp->mmio_addr;
|
void __iomem *ioaddr = tp->mmio_addr;
|
||||||
|
|
||||||
/* This is a complicated state machine to configure the "twister" for
|
/* This is a complicated state machine to configure the "twister" for
|
||||||
impedance/echos based on the cable length.
|
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,
|
static inline void rtl8139_thread_iter (struct net_device *dev,
|
||||||
struct rtl8139_private *tp,
|
struct rtl8139_private *tp,
|
||||||
void *ioaddr)
|
void __iomem *ioaddr)
|
||||||
{
|
{
|
||||||
int mii_lpa;
|
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)
|
static void rtl8139_tx_timeout (struct net_device *dev)
|
||||||
{
|
{
|
||||||
struct rtl8139_private *tp = netdev_priv(dev);
|
struct rtl8139_private *tp = netdev_priv(dev);
|
||||||
void *ioaddr = tp->mmio_addr;
|
void __iomem *ioaddr = tp->mmio_addr;
|
||||||
int i;
|
int i;
|
||||||
u8 tmp8;
|
u8 tmp8;
|
||||||
unsigned long flags;
|
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)
|
static int rtl8139_start_xmit (struct sk_buff *skb, struct net_device *dev)
|
||||||
{
|
{
|
||||||
struct rtl8139_private *tp = netdev_priv(dev);
|
struct rtl8139_private *tp = netdev_priv(dev);
|
||||||
void *ioaddr = tp->mmio_addr;
|
void __iomem *ioaddr = tp->mmio_addr;
|
||||||
unsigned int entry;
|
unsigned int entry;
|
||||||
unsigned int len = skb->len;
|
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,
|
static void rtl8139_tx_interrupt (struct net_device *dev,
|
||||||
struct rtl8139_private *tp,
|
struct rtl8139_private *tp,
|
||||||
void *ioaddr)
|
void __iomem *ioaddr)
|
||||||
{
|
{
|
||||||
unsigned long dirty_tx, tx_left;
|
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 */
|
/* TODO: clean this up! Rx reset need not be this intensive */
|
||||||
static void rtl8139_rx_err (u32 rx_status, struct net_device *dev,
|
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;
|
u8 tmp8;
|
||||||
#ifdef CONFIG_8139_OLD_RX_RESET
|
#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)
|
static void rtl8139_isr_ack(struct rtl8139_private *tp)
|
||||||
{
|
{
|
||||||
void *ioaddr = tp->mmio_addr;
|
void __iomem *ioaddr = tp->mmio_addr;
|
||||||
u16 status;
|
u16 status;
|
||||||
|
|
||||||
status = RTL_R16 (IntrStatus) & RxAckBits;
|
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,
|
static int rtl8139_rx(struct net_device *dev, struct rtl8139_private *tp,
|
||||||
int budget)
|
int budget)
|
||||||
{
|
{
|
||||||
void *ioaddr = tp->mmio_addr;
|
void __iomem *ioaddr = tp->mmio_addr;
|
||||||
int received = 0;
|
int received = 0;
|
||||||
unsigned char *rx_ring = tp->rx_ring;
|
unsigned char *rx_ring = tp->rx_ring;
|
||||||
unsigned int cur_rx = tp->cur_rx;
|
unsigned int cur_rx = tp->cur_rx;
|
||||||
|
@ -2087,7 +2067,7 @@ out:
|
||||||
|
|
||||||
static void rtl8139_weird_interrupt (struct net_device *dev,
|
static void rtl8139_weird_interrupt (struct net_device *dev,
|
||||||
struct rtl8139_private *tp,
|
struct rtl8139_private *tp,
|
||||||
void *ioaddr,
|
void __iomem *ioaddr,
|
||||||
int status, int link_changed)
|
int status, int link_changed)
|
||||||
{
|
{
|
||||||
DPRINTK ("%s: Abnormal interrupt, status %8.8x.\n",
|
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)
|
static int rtl8139_poll(struct net_device *dev, int *budget)
|
||||||
{
|
{
|
||||||
struct rtl8139_private *tp = netdev_priv(dev);
|
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 orig_budget = min(*budget, dev->quota);
|
||||||
int done = 1;
|
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 net_device *dev = (struct net_device *) dev_instance;
|
||||||
struct rtl8139_private *tp = netdev_priv(dev);
|
struct rtl8139_private *tp = netdev_priv(dev);
|
||||||
void *ioaddr = tp->mmio_addr;
|
void __iomem *ioaddr = tp->mmio_addr;
|
||||||
u16 status, ackstat;
|
u16 status, ackstat;
|
||||||
int link_changed = 0; /* avoid bogus "uninit" warning */
|
int link_changed = 0; /* avoid bogus "uninit" warning */
|
||||||
int handled = 0;
|
int handled = 0;
|
||||||
|
@ -2241,7 +2221,7 @@ static void rtl8139_poll_controller(struct net_device *dev)
|
||||||
static int rtl8139_close (struct net_device *dev)
|
static int rtl8139_close (struct net_device *dev)
|
||||||
{
|
{
|
||||||
struct rtl8139_private *tp = netdev_priv(dev);
|
struct rtl8139_private *tp = netdev_priv(dev);
|
||||||
void *ioaddr = tp->mmio_addr;
|
void __iomem *ioaddr = tp->mmio_addr;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
unsigned long flags;
|
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)
|
static void rtl8139_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
|
||||||
{
|
{
|
||||||
struct rtl8139_private *np = netdev_priv(dev);
|
struct rtl8139_private *np = netdev_priv(dev);
|
||||||
void *ioaddr = np->mmio_addr;
|
void __iomem *ioaddr = np->mmio_addr;
|
||||||
|
|
||||||
spin_lock_irq(&np->lock);
|
spin_lock_irq(&np->lock);
|
||||||
if (rtl_chip_info[np->chipset].flags & HasLWake) {
|
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)
|
static int rtl8139_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
|
||||||
{
|
{
|
||||||
struct rtl8139_private *np = netdev_priv(dev);
|
struct rtl8139_private *np = netdev_priv(dev);
|
||||||
void *ioaddr = np->mmio_addr;
|
void __iomem *ioaddr = np->mmio_addr;
|
||||||
u32 support;
|
u32 support;
|
||||||
u8 cfg3, cfg5;
|
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)
|
static struct net_device_stats *rtl8139_get_stats (struct net_device *dev)
|
||||||
{
|
{
|
||||||
struct rtl8139_private *tp = netdev_priv(dev);
|
struct rtl8139_private *tp = netdev_priv(dev);
|
||||||
void *ioaddr = tp->mmio_addr;
|
void __iomem *ioaddr = tp->mmio_addr;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
if (netif_running(dev)) {
|
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)
|
static void __set_rx_mode (struct net_device *dev)
|
||||||
{
|
{
|
||||||
struct rtl8139_private *tp = netdev_priv(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 */
|
u32 mc_filter[2]; /* Multicast hash filter */
|
||||||
int i, rx_mode;
|
int i, rx_mode;
|
||||||
u32 tmp;
|
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 net_device *dev = pci_get_drvdata (pdev);
|
||||||
struct rtl8139_private *tp = netdev_priv(dev);
|
struct rtl8139_private *tp = netdev_priv(dev);
|
||||||
void *ioaddr = tp->mmio_addr;
|
void __iomem *ioaddr = tp->mmio_addr;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
pci_save_state (pdev);
|
pci_save_state (pdev);
|
||||||
|
|
|
@ -824,6 +824,18 @@ config SMC9194
|
||||||
<file:Documentation/networking/net-modules.txt>. The module
|
<file:Documentation/networking/net-modules.txt>. The module
|
||||||
will be called smc9194.
|
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
|
config NET_VENDOR_RACAL
|
||||||
bool "Racal-Interlan (Micom) NI cards"
|
bool "Racal-Interlan (Micom) NI cards"
|
||||||
depends on NET_ETHERNET && ISA
|
depends on NET_ETHERNET && ISA
|
||||||
|
@ -989,21 +1001,6 @@ config EEXPRESS_PRO
|
||||||
<file:Documentation/networking/net-modules.txt>. The module
|
<file:Documentation/networking/net-modules.txt>. The module
|
||||||
will be called eepro.
|
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
|
config HPLAN_PLUS
|
||||||
tristate "HP PCLAN+ (27247B and 27252A) support"
|
tristate "HP PCLAN+ (27247B and 27252A) support"
|
||||||
depends on NET_ISA
|
depends on NET_ISA
|
||||||
|
@ -1092,14 +1089,6 @@ config SEEQ8005
|
||||||
<file:Documentation/networking/net-modules.txt>. The module
|
<file:Documentation/networking/net-modules.txt>. The module
|
||||||
will be called seeq8005.
|
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
|
config SKMC
|
||||||
tristate "SKnet MCA support"
|
tristate "SKnet MCA support"
|
||||||
depends on NET_ETHERNET && MCA && BROKEN
|
depends on NET_ETHERNET && MCA && BROKEN
|
||||||
|
@ -1932,6 +1921,18 @@ config R8169_VLAN
|
||||||
|
|
||||||
If in doubt, say Y.
|
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
|
config SK98LIN
|
||||||
tristate "Marvell Yukon Chipset / SysKonnect SK-98xx Support"
|
tristate "Marvell Yukon Chipset / SysKonnect SK-98xx Support"
|
||||||
depends on PCI
|
depends on PCI
|
||||||
|
|
|
@ -53,6 +53,7 @@ obj-$(CONFIG_FEALNX) += fealnx.o
|
||||||
obj-$(CONFIG_TIGON3) += tg3.o
|
obj-$(CONFIG_TIGON3) += tg3.o
|
||||||
obj-$(CONFIG_BNX2) += bnx2.o
|
obj-$(CONFIG_BNX2) += bnx2.o
|
||||||
obj-$(CONFIG_TC35815) += tc35815.o
|
obj-$(CONFIG_TC35815) += tc35815.o
|
||||||
|
obj-$(CONFIG_SKGE) += skge.o
|
||||||
obj-$(CONFIG_SK98LIN) += sk98lin/
|
obj-$(CONFIG_SK98LIN) += sk98lin/
|
||||||
obj-$(CONFIG_SKFP) += skfp/
|
obj-$(CONFIG_SKFP) += skfp/
|
||||||
obj-$(CONFIG_VIA_RHINE) += via-rhine.o
|
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_APNE) += apne.o 8390.o
|
||||||
obj-$(CONFIG_PCMCIA_PCNET) += 8390.o
|
obj-$(CONFIG_PCMCIA_PCNET) += 8390.o
|
||||||
obj-$(CONFIG_SHAPER) += shaper.o
|
obj-$(CONFIG_SHAPER) += shaper.o
|
||||||
obj-$(CONFIG_SK_G16) += sk_g16.o
|
|
||||||
obj-$(CONFIG_HP100) += hp100.o
|
obj-$(CONFIG_HP100) += hp100.o
|
||||||
obj-$(CONFIG_SMC9194) += smc9194.o
|
obj-$(CONFIG_SMC9194) += smc9194.o
|
||||||
obj-$(CONFIG_FEC) += fec.o
|
obj-$(CONFIG_FEC) += fec.o
|
||||||
|
@ -122,7 +122,6 @@ obj-$(CONFIG_DEFXX) += defxx.o
|
||||||
obj-$(CONFIG_SGISEEQ) += sgiseeq.o
|
obj-$(CONFIG_SGISEEQ) += sgiseeq.o
|
||||||
obj-$(CONFIG_SGI_O2MACE_ETH) += meth.o
|
obj-$(CONFIG_SGI_O2MACE_ETH) += meth.o
|
||||||
obj-$(CONFIG_AT1700) += at1700.o
|
obj-$(CONFIG_AT1700) += at1700.o
|
||||||
obj-$(CONFIG_FMV18X) += fmv18x.o
|
|
||||||
obj-$(CONFIG_EL1) += 3c501.o
|
obj-$(CONFIG_EL1) += 3c501.o
|
||||||
obj-$(CONFIG_EL16) += 3c507.o
|
obj-$(CONFIG_EL16) += 3c507.o
|
||||||
obj-$(CONFIG_ELMC) += 3c523.o
|
obj-$(CONFIG_ELMC) += 3c523.o
|
||||||
|
@ -180,6 +179,7 @@ obj-$(CONFIG_AMD8111_ETH) += amd8111e.o
|
||||||
obj-$(CONFIG_IBMVETH) += ibmveth.o
|
obj-$(CONFIG_IBMVETH) += ibmveth.o
|
||||||
obj-$(CONFIG_S2IO) += s2io.o
|
obj-$(CONFIG_S2IO) += s2io.o
|
||||||
obj-$(CONFIG_SMC91X) += smc91x.o
|
obj-$(CONFIG_SMC91X) += smc91x.o
|
||||||
|
obj-$(CONFIG_DM9000) += dm9000.o
|
||||||
obj-$(CONFIG_FEC_8XX) += fec_8xx/
|
obj-$(CONFIG_FEC_8XX) += fec_8xx/
|
||||||
|
|
||||||
obj-$(CONFIG_ARM) += arm/
|
obj-$(CONFIG_ARM) += arm/
|
||||||
|
|
|
@ -210,9 +210,6 @@ static struct devprobe2 isa_probes[] __initdata = {
|
||||||
#ifdef CONFIG_AT1700
|
#ifdef CONFIG_AT1700
|
||||||
{at1700_probe, 0},
|
{at1700_probe, 0},
|
||||||
#endif
|
#endif
|
||||||
#ifdef CONFIG_FMV18X /* Fujitsu FMV-181/182 */
|
|
||||||
{fmv18x_probe, 0},
|
|
||||||
#endif
|
|
||||||
#ifdef CONFIG_ETH16I
|
#ifdef CONFIG_ETH16I
|
||||||
{eth16i_probe, 0}, /* ICL EtherTeam 16i/32 */
|
{eth16i_probe, 0}, /* ICL EtherTeam 16i/32 */
|
||||||
#endif
|
#endif
|
||||||
|
@ -243,9 +240,6 @@ static struct devprobe2 isa_probes[] __initdata = {
|
||||||
#ifdef CONFIG_ELPLUS /* 3c505 */
|
#ifdef CONFIG_ELPLUS /* 3c505 */
|
||||||
{elplus_probe, 0},
|
{elplus_probe, 0},
|
||||||
#endif
|
#endif
|
||||||
#ifdef CONFIG_SK_G16
|
|
||||||
{SK_init, 0},
|
|
||||||
#endif
|
|
||||||
#ifdef CONFIG_NI5010
|
#ifdef CONFIG_NI5010
|
||||||
{ni5010_probe, 0},
|
{ni5010_probe, 0},
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -68,6 +68,7 @@ struct etherh_priv {
|
||||||
void __iomem *dma_base;
|
void __iomem *dma_base;
|
||||||
unsigned int id;
|
unsigned int id;
|
||||||
void __iomem *ctrl_port;
|
void __iomem *ctrl_port;
|
||||||
|
void __iomem *base;
|
||||||
unsigned char ctrl;
|
unsigned char ctrl;
|
||||||
u32 supported;
|
u32 supported;
|
||||||
};
|
};
|
||||||
|
@ -177,7 +178,7 @@ etherh_setif(struct net_device *dev)
|
||||||
switch (etherh_priv(dev)->id) {
|
switch (etherh_priv(dev)->id) {
|
||||||
case PROD_I3_ETHERLAN600:
|
case PROD_I3_ETHERLAN600:
|
||||||
case PROD_I3_ETHERLAN600A:
|
case PROD_I3_ETHERLAN600A:
|
||||||
addr = (void *)dev->base_addr + EN0_RCNTHI;
|
addr = etherh_priv(dev)->base + EN0_RCNTHI;
|
||||||
|
|
||||||
switch (dev->if_port) {
|
switch (dev->if_port) {
|
||||||
case IF_PORT_10BASE2:
|
case IF_PORT_10BASE2:
|
||||||
|
@ -218,7 +219,7 @@ etherh_getifstat(struct net_device *dev)
|
||||||
switch (etherh_priv(dev)->id) {
|
switch (etherh_priv(dev)->id) {
|
||||||
case PROD_I3_ETHERLAN600:
|
case PROD_I3_ETHERLAN600:
|
||||||
case PROD_I3_ETHERLAN600A:
|
case PROD_I3_ETHERLAN600A:
|
||||||
addr = (void *)dev->base_addr + EN0_RCNTHI;
|
addr = etherh_priv(dev)->base + EN0_RCNTHI;
|
||||||
switch (dev->if_port) {
|
switch (dev->if_port) {
|
||||||
case IF_PORT_10BASE2:
|
case IF_PORT_10BASE2:
|
||||||
stat = 1;
|
stat = 1;
|
||||||
|
@ -281,7 +282,7 @@ static void
|
||||||
etherh_reset(struct net_device *dev)
|
etherh_reset(struct net_device *dev)
|
||||||
{
|
{
|
||||||
struct ei_device *ei_local = netdev_priv(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);
|
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;
|
ei_local->dmaing = 1;
|
||||||
|
|
||||||
addr = (void *)dev->base_addr;
|
addr = etherh_priv(dev)->base;
|
||||||
dma_base = etherh_priv(dev)->dma_base;
|
dma_base = etherh_priv(dev)->dma_base;
|
||||||
|
|
||||||
count = (count + 1) & ~1;
|
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;
|
ei_local->dmaing = 1;
|
||||||
|
|
||||||
addr = (void *)dev->base_addr;
|
addr = etherh_priv(dev)->base;
|
||||||
dma_base = etherh_priv(dev)->dma_base;
|
dma_base = etherh_priv(dev)->dma_base;
|
||||||
|
|
||||||
buf = skb->data;
|
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;
|
ei_local->dmaing = 1;
|
||||||
|
|
||||||
addr = (void *)dev->base_addr;
|
addr = etherh_priv(dev)->base;
|
||||||
dma_base = etherh_priv(dev)->dma_base;
|
dma_base = etherh_priv(dev)->dma_base;
|
||||||
|
|
||||||
writeb (E8390_NODMA | E8390_PAGE0 | E8390_START, addr + E8390_CMD);
|
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;
|
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->dma_base = eh->memc + data->dataport_offset;
|
||||||
eh->ctrl_port += data->ctrlport_offset;
|
eh->ctrl_port += data->ctrlport_offset;
|
||||||
|
|
||||||
|
|
|
@ -1681,10 +1681,6 @@ static int au1000_init(struct net_device *dev)
|
||||||
control |= MAC_FULL_DUPLEX;
|
control |= MAC_FULL_DUPLEX;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* fix for startup without cable */
|
|
||||||
if (!link)
|
|
||||||
dev->flags &= ~IFF_RUNNING;
|
|
||||||
|
|
||||||
aup->mac->control = control;
|
aup->mac->control = control;
|
||||||
aup->mac->vlan1_tag = 0x8100; /* activate vlan support */
|
aup->mac->vlan1_tag = 0x8100; /* activate vlan support */
|
||||||
au_sync();
|
au_sync();
|
||||||
|
@ -1709,16 +1705,14 @@ static void au1000_timer(unsigned long data)
|
||||||
if_port = dev->if_port;
|
if_port = dev->if_port;
|
||||||
if (aup->phy_ops->phy_status(dev, aup->phy_addr, &link, &speed) == 0) {
|
if (aup->phy_ops->phy_status(dev, aup->phy_addr, &link, &speed) == 0) {
|
||||||
if (link) {
|
if (link) {
|
||||||
if (!(dev->flags & IFF_RUNNING)) {
|
if (!netif_carrier_ok(dev)) {
|
||||||
netif_carrier_on(dev);
|
netif_carrier_on(dev);
|
||||||
dev->flags |= IFF_RUNNING;
|
|
||||||
printk(KERN_INFO "%s: link up\n", dev->name);
|
printk(KERN_INFO "%s: link up\n", dev->name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (dev->flags & IFF_RUNNING) {
|
if (netif_carrier_ok(dev)) {
|
||||||
netif_carrier_off(dev);
|
netif_carrier_off(dev);
|
||||||
dev->flags &= ~IFF_RUNNING;
|
|
||||||
dev->if_port = 0;
|
dev->if_port = 0;
|
||||||
printk(KERN_INFO "%s: link down\n", dev->name);
|
printk(KERN_INFO "%s: link down\n", dev->name);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1412,7 +1412,6 @@ static int bmac_open(struct net_device *dev)
|
||||||
bp->opened = 1;
|
bp->opened = 1;
|
||||||
bmac_reset_and_enable(dev);
|
bmac_reset_and_enable(dev);
|
||||||
enable_irq(dev->irq);
|
enable_irq(dev->irq);
|
||||||
dev->flags |= IFF_RUNNING;
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1425,7 +1424,6 @@ static int bmac_close(struct net_device *dev)
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
bp->sleeping = 1;
|
bp->sleeping = 1;
|
||||||
dev->flags &= ~(IFF_UP | IFF_RUNNING);
|
|
||||||
|
|
||||||
/* disable rx and tx */
|
/* disable rx and tx */
|
||||||
config = bmread(dev, RXCFG);
|
config = bmread(dev, RXCFG);
|
||||||
|
|
1219
drivers/net/dm9000.c
Normal file
1219
drivers/net/dm9000.c
Normal file
File diff suppressed because it is too large
Load diff
135
drivers/net/dm9000.h
Normal file
135
drivers/net/dm9000.h
Normal file
|
@ -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,
|
static void shmem_block_input(struct net_device *dev, int count,
|
||||||
struct sk_buff *skb, int ring_offset)
|
struct sk_buff *skb, int ring_offset)
|
||||||
{
|
{
|
||||||
void __iomem *xfer_start = ei_status.mem + (TX_PAGES<<8)
|
void __iomem *base = ei_status.mem;
|
||||||
+ ring_offset
|
unsigned long offset = (TX_PAGES<<8) + ring_offset
|
||||||
- (ei_status.rx_start_page << 8);
|
- (ei_status.rx_start_page << 8);
|
||||||
char *buf = skb->data;
|
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. */
|
/* We must wrap the input move. */
|
||||||
int semi_count = (void __iomem *)ei_status.rmem_end - xfer_start;
|
int semi_count = ei_status.priv - offset;
|
||||||
copyin(buf, xfer_start, semi_count);
|
copyin(buf, base + offset, semi_count);
|
||||||
buf += semi_count;
|
buf += semi_count;
|
||||||
xfer_start = ei_status.mem + (TX_PAGES<<8);
|
offset = TX_PAGES<<8;
|
||||||
count -= semi_count;
|
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.mem = info->base + offset;
|
||||||
|
ei_status.priv = req.Size;
|
||||||
dev->mem_start = (u_long)ei_status.mem;
|
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.tx_start_page = start_pg;
|
||||||
ei_status.rx_start_page = start_pg + TX_PAGES;
|
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)
|
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 i, bits, hdrlen, mtu;
|
||||||
int flen, fnb;
|
int flen;
|
||||||
|
int navail, nfree;
|
||||||
|
int nbigger;
|
||||||
unsigned char *p, *q;
|
unsigned char *p, *q;
|
||||||
struct list_head *list;
|
struct list_head *list;
|
||||||
struct channel *pch;
|
struct channel *pch;
|
||||||
struct sk_buff *frag;
|
struct sk_buff *frag;
|
||||||
struct ppp_channel *chan;
|
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;
|
hdrlen = (ppp->flags & SC_MP_XSHORTSEQ)? MPHDRLEN_SSN: MPHDRLEN;
|
||||||
|
i = 0;
|
||||||
list = &ppp->channels;
|
list = &ppp->channels;
|
||||||
while ((list = list->next) != &ppp->channels) {
|
while ((list = list->next) != &ppp->channels) {
|
||||||
pch = list_entry(list, struct channel, clist);
|
pch = list_entry(list, struct channel, clist);
|
||||||
nch += pch->avail = (skb_queue_len(&pch->file.xq) == 0);
|
navail += pch->avail = (pch->chan != NULL);
|
||||||
/*
|
if (pch->avail) {
|
||||||
* If a channel hasn't had a fragment yet, it has to get
|
if (skb_queue_len(&pch->file.xq) == 0
|
||||||
* one before we send any fragments on later channels.
|
|| !pch->had_frag) {
|
||||||
* If it can't take a fragment now, don't give any
|
pch->avail = 2;
|
||||||
* to subsequent channels.
|
++nfree;
|
||||||
*/
|
|
||||||
if (!pch->had_frag && !pch->avail) {
|
|
||||||
while ((list = list->next) != &ppp->channels) {
|
|
||||||
pch = list_entry(list, struct channel, clist);
|
|
||||||
pch->avail = 0;
|
|
||||||
}
|
}
|
||||||
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 */
|
return 0; /* can't take now, leave it in xmit_pending */
|
||||||
|
|
||||||
/* Do protocol field compression (XXX this should be optional) */
|
/* 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;
|
--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;
|
fragsize = len;
|
||||||
if (nch > 1) {
|
if (nfree > 1)
|
||||||
int maxch = ROUNDUP(len, MIN_FRAG_SIZE);
|
fragsize = ROUNDUP(fragsize, nfree);
|
||||||
if (nch > maxch)
|
/* nbigger channels get fragsize bytes, the rest get fragsize-1,
|
||||||
nch = maxch;
|
except if nbigger==0, then they all get fragsize. */
|
||||||
fragsize = ROUNDUP(fragsize, nch);
|
nbigger = len % nfree;
|
||||||
}
|
|
||||||
|
|
||||||
/* skip to the channel after the one we last used
|
/* skip to the channel after the one we last used
|
||||||
and start at that one */
|
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 */
|
/* create a fragment for each channel */
|
||||||
bits = B;
|
bits = B;
|
||||||
do {
|
while (nfree > 0 || len > 0) {
|
||||||
list = list->next;
|
list = list->next;
|
||||||
if (list == &ppp->channels) {
|
if (list == &ppp->channels) {
|
||||||
i = 0;
|
i = 0;
|
||||||
|
@ -1289,61 +1301,92 @@ static int ppp_mp_explode(struct ppp *ppp, struct sk_buff *skb)
|
||||||
if (!pch->avail)
|
if (!pch->avail)
|
||||||
continue;
|
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. */
|
/* check the channel's mtu and whether it is still attached. */
|
||||||
spin_lock_bh(&pch->downl);
|
spin_lock_bh(&pch->downl);
|
||||||
if (pch->chan == 0 || (mtu = pch->chan->mtu) < hdrlen) {
|
if (pch->chan == NULL) {
|
||||||
/* can't use this channel */
|
/* can't use this channel, it's being deregistered */
|
||||||
spin_unlock_bh(&pch->downl);
|
spin_unlock_bh(&pch->downl);
|
||||||
pch->avail = 0;
|
pch->avail = 0;
|
||||||
if (--nch == 0)
|
if (--navail == 0)
|
||||||
break;
|
break;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We have to create multiple fragments for this channel
|
* Create a fragment for this channel of
|
||||||
* if fragsize is greater than the channel's mtu.
|
* 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)
|
if (fragsize > len)
|
||||||
fragsize = len;
|
fragsize = len;
|
||||||
for (flen = fragsize; flen > 0; flen -= fnb) {
|
flen = fragsize;
|
||||||
fnb = flen;
|
mtu = pch->chan->mtu + 2 - hdrlen;
|
||||||
if (fnb > mtu + 2 - hdrlen)
|
if (mtu < 4)
|
||||||
fnb = mtu + 2 - hdrlen;
|
mtu = 4;
|
||||||
if (fnb >= len)
|
if (flen > mtu)
|
||||||
bits |= E;
|
flen = mtu;
|
||||||
frag = alloc_skb(fnb + hdrlen, GFP_ATOMIC);
|
if (flen == len && nfree == 0)
|
||||||
if (frag == 0)
|
bits |= E;
|
||||||
goto noskb;
|
frag = alloc_skb(flen + hdrlen + (flen == 0), GFP_ATOMIC);
|
||||||
q = skb_put(frag, fnb + hdrlen);
|
if (frag == 0)
|
||||||
/* make the MP header */
|
goto noskb;
|
||||||
q[0] = PPP_MP >> 8;
|
q = skb_put(frag, flen + hdrlen);
|
||||||
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 */
|
/* make the MP header */
|
||||||
memcpy(q + hdrlen, p, fnb);
|
q[0] = PPP_MP >> 8;
|
||||||
|
q[1] = PPP_MP;
|
||||||
/* try to send it down the channel */
|
if (ppp->flags & SC_MP_XSHORTSEQ) {
|
||||||
chan = pch->chan;
|
q[2] = bits + ((ppp->nxseq >> 8) & 0xf);
|
||||||
if (!chan->ops->start_xmit(chan, frag))
|
q[3] = ppp->nxseq;
|
||||||
skb_queue_tail(&pch->file.xq, frag);
|
} else {
|
||||||
pch->had_frag = 1;
|
q[2] = bits;
|
||||||
p += fnb;
|
q[3] = ppp->nxseq >> 16;
|
||||||
len -= fnb;
|
q[4] = ppp->nxseq >> 8;
|
||||||
++ppp->nxseq;
|
q[5] = ppp->nxseq;
|
||||||
bits = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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);
|
spin_unlock_bh(&pch->downl);
|
||||||
} while (len > 0);
|
|
||||||
|
if (--nbigger == 0 && fragsize > 0)
|
||||||
|
--fragsize;
|
||||||
|
}
|
||||||
ppp->nxchan = i;
|
ppp->nxchan = i;
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -1422,7 +1465,7 @@ ppp_input(struct ppp_channel *chan, struct sk_buff *skb)
|
||||||
kfree_skb(skb);
|
kfree_skb(skb);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
proto = PPP_PROTO(skb);
|
proto = PPP_PROTO(skb);
|
||||||
read_lock_bh(&pch->upl);
|
read_lock_bh(&pch->upl);
|
||||||
if (pch->ppp == 0 || proto >= 0xc000 || proto == PPP_CCPFRAG) {
|
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;
|
struct list_head *l;
|
||||||
int mphdrlen = (ppp->flags & SC_MP_SHORTSEQ)? MPHDRLEN_SSN: MPHDRLEN;
|
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 */
|
goto err; /* no good, throw it away */
|
||||||
|
|
||||||
/* Decode sequence number and begin/end bits */
|
/* Decode sequence number and begin/end bits */
|
||||||
|
|
|
@ -69,7 +69,13 @@ VERSION 2.2LK <2005/01/25>
|
||||||
#include <asm/io.h>
|
#include <asm/io.h>
|
||||||
#include <asm/irq.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 MODULENAME "r8169"
|
||||||
#define PFX MODULENAME ": "
|
#define PFX MODULENAME ": "
|
||||||
|
|
||||||
|
@ -85,6 +91,10 @@ VERSION 2.2LK <2005/01/25>
|
||||||
#define dprintk(fmt, args...) do {} while (0)
|
#define dprintk(fmt, args...) do {} while (0)
|
||||||
#endif /* RTL8169_DEBUG */
|
#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) \
|
#define TX_BUFFS_AVAIL(tp) \
|
||||||
(tp->dirty_tx + NUM_TX_DESC - tp->cur_tx - 1)
|
(tp->dirty_tx + NUM_TX_DESC - tp->cur_tx - 1)
|
||||||
|
|
||||||
|
@ -174,8 +184,9 @@ const static struct {
|
||||||
#undef _R
|
#undef _R
|
||||||
|
|
||||||
static struct pci_device_id rtl8169_pci_tbl[] = {
|
static struct pci_device_id rtl8169_pci_tbl[] = {
|
||||||
{0x10ec, 0x8169, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
|
{ PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8169), },
|
||||||
{0x1186, 0x4300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
|
{ PCI_DEVICE(PCI_VENDOR_ID_DLINK, 0x4300), },
|
||||||
|
{ PCI_DEVICE(0x16ec, 0x0116), },
|
||||||
{0,},
|
{0,},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -183,10 +194,15 @@ MODULE_DEVICE_TABLE(pci, rtl8169_pci_tbl);
|
||||||
|
|
||||||
static int rx_copybreak = 200;
|
static int rx_copybreak = 200;
|
||||||
static int use_dac;
|
static int use_dac;
|
||||||
|
static struct {
|
||||||
|
u32 msg_enable;
|
||||||
|
} debug = { -1 };
|
||||||
|
|
||||||
enum RTL8169_registers {
|
enum RTL8169_registers {
|
||||||
MAC0 = 0, /* Ethernet hardware address. */
|
MAC0 = 0, /* Ethernet hardware address. */
|
||||||
MAR0 = 8, /* Multicast filter. */
|
MAR0 = 8, /* Multicast filter. */
|
||||||
|
CounterAddrLow = 0x10,
|
||||||
|
CounterAddrHigh = 0x14,
|
||||||
TxDescStartAddrLow = 0x20,
|
TxDescStartAddrLow = 0x20,
|
||||||
TxDescStartAddrHigh = 0x24,
|
TxDescStartAddrHigh = 0x24,
|
||||||
TxHDescStartAddrLow = 0x28,
|
TxHDescStartAddrLow = 0x28,
|
||||||
|
@ -328,6 +344,9 @@ enum RTL8169_register_content {
|
||||||
|
|
||||||
/* _TBICSRBit */
|
/* _TBICSRBit */
|
||||||
TBILinkOK = 0x02000000,
|
TBILinkOK = 0x02000000,
|
||||||
|
|
||||||
|
/* DumpCounterCommand */
|
||||||
|
CounterDump = 0x8,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum _DescStatusBit {
|
enum _DescStatusBit {
|
||||||
|
@ -385,6 +404,7 @@ struct rtl8169_private {
|
||||||
struct pci_dev *pci_dev; /* Index of PCI device */
|
struct pci_dev *pci_dev; /* Index of PCI device */
|
||||||
struct net_device_stats stats; /* statistics of net device */
|
struct net_device_stats stats; /* statistics of net device */
|
||||||
spinlock_t lock; /* spin lock flag */
|
spinlock_t lock; /* spin lock flag */
|
||||||
|
u32 msg_enable;
|
||||||
int chipset;
|
int chipset;
|
||||||
int mac_version;
|
int mac_version;
|
||||||
int phy_version;
|
int phy_version;
|
||||||
|
@ -418,9 +438,13 @@ struct rtl8169_private {
|
||||||
MODULE_AUTHOR("Realtek and the Linux r8169 crew <netdev@vger.kernel.org>");
|
MODULE_AUTHOR("Realtek and the Linux r8169 crew <netdev@vger.kernel.org>");
|
||||||
MODULE_DESCRIPTION("RealTek RTL-8169 Gigabit Ethernet driver");
|
MODULE_DESCRIPTION("RealTek RTL-8169 Gigabit Ethernet driver");
|
||||||
module_param_array(media, int, &num_media, 0);
|
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_param(rx_copybreak, int, 0);
|
||||||
|
MODULE_PARM_DESC(rx_copybreak, "Copy breakpoint for copy-only-tiny-frames");
|
||||||
module_param(use_dac, int, 0);
|
module_param(use_dac, int, 0);
|
||||||
MODULE_PARM_DESC(use_dac, "Enable PCI DAC. Unsafe on 32 bit PCI slot.");
|
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_LICENSE("GPL");
|
||||||
MODULE_VERSION(RTL8169_VERSION);
|
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 int rtl8169_close(struct net_device *dev);
|
||||||
static void rtl8169_set_rx_mode(struct net_device *dev);
|
static void rtl8169_set_rx_mode(struct net_device *dev);
|
||||||
static void rtl8169_tx_timeout(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 *,
|
static int rtl8169_rx_interrupt(struct net_device *, struct rtl8169_private *,
|
||||||
void __iomem *);
|
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);
|
static void rtl8169_down(struct net_device *dev);
|
||||||
|
|
||||||
#ifdef CONFIG_R8169_NAPI
|
#ifdef CONFIG_R8169_NAPI
|
||||||
|
@ -543,9 +567,13 @@ static void rtl8169_check_link_status(struct net_device *dev,
|
||||||
spin_lock_irqsave(&tp->lock, flags);
|
spin_lock_irqsave(&tp->lock, flags);
|
||||||
if (tp->link_ok(ioaddr)) {
|
if (tp->link_ok(ioaddr)) {
|
||||||
netif_carrier_on(dev);
|
netif_carrier_on(dev);
|
||||||
printk(KERN_INFO PFX "%s: link up\n", dev->name);
|
if (netif_msg_ifup(tp))
|
||||||
} else
|
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);
|
netif_carrier_off(dev);
|
||||||
|
}
|
||||||
spin_unlock_irqrestore(&tp->lock, flags);
|
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;
|
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");
|
printk(KERN_WARNING PFX "media option is deprecated.\n");
|
||||||
|
|
||||||
for (p = link_settings; p->media != 0xff; p++) {
|
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)
|
} else if (autoneg == AUTONEG_ENABLE)
|
||||||
RTL_W32(TBICSR, reg | TBINwEnable | TBINwRestart);
|
RTL_W32(TBICSR, reg | TBINwEnable | TBINwRestart);
|
||||||
else {
|
else {
|
||||||
printk(KERN_WARNING PFX
|
if (netif_msg_link(tp)) {
|
||||||
"%s: incorrect speed setting refused in TBI mode\n",
|
printk(KERN_WARNING "%s: "
|
||||||
dev->name);
|
"incorrect speed setting refused in TBI mode\n",
|
||||||
|
dev->name);
|
||||||
|
}
|
||||||
ret = -EOPNOTSUPP;
|
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);
|
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 = {
|
static struct ethtool_ops rtl8169_ethtool_ops = {
|
||||||
.get_drvinfo = rtl8169_get_drvinfo,
|
.get_drvinfo = rtl8169_get_drvinfo,
|
||||||
.get_regs_len = rtl8169_get_regs_len,
|
.get_regs_len = rtl8169_get_regs_len,
|
||||||
.get_link = ethtool_op_get_link,
|
.get_link = ethtool_op_get_link,
|
||||||
.get_settings = rtl8169_get_settings,
|
.get_settings = rtl8169_get_settings,
|
||||||
.set_settings = rtl8169_set_settings,
|
.set_settings = rtl8169_set_settings,
|
||||||
|
.get_msglevel = rtl8169_get_msglevel,
|
||||||
|
.set_msglevel = rtl8169_set_msglevel,
|
||||||
.get_rx_csum = rtl8169_get_rx_csum,
|
.get_rx_csum = rtl8169_get_rx_csum,
|
||||||
.set_rx_csum = rtl8169_set_rx_csum,
|
.set_rx_csum = rtl8169_set_rx_csum,
|
||||||
.get_tx_csum = ethtool_op_get_tx_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,
|
.get_tso = ethtool_op_get_tso,
|
||||||
.set_tso = ethtool_op_set_tso,
|
.set_tso = ethtool_op_set_tso,
|
||||||
.get_regs = rtl8169_get_regs,
|
.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,
|
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))
|
if (tp->link_ok(ioaddr))
|
||||||
goto out_unlock;
|
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);
|
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 zeroed in alloc_etherdev */
|
||||||
dev = alloc_etherdev(sizeof (*tp));
|
dev = alloc_etherdev(sizeof (*tp));
|
||||||
if (dev == NULL) {
|
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;
|
goto err_out;
|
||||||
}
|
}
|
||||||
|
|
||||||
SET_MODULE_OWNER(dev);
|
SET_MODULE_OWNER(dev);
|
||||||
SET_NETDEV_DEV(dev, &pdev->dev);
|
SET_NETDEV_DEV(dev, &pdev->dev);
|
||||||
tp = netdev_priv(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) */
|
/* enable device (incl. PCI PM wakeup and hotplug setup) */
|
||||||
rc = pci_enable_device(pdev);
|
rc = pci_enable_device(pdev);
|
||||||
if (rc) {
|
if (rc < 0) {
|
||||||
printk(KERN_ERR PFX "%s: enable failure\n", pci_name(pdev));
|
if (netif_msg_probe(tp)) {
|
||||||
|
printk(KERN_ERR PFX "%s: enable failure\n",
|
||||||
|
pci_name(pdev));
|
||||||
|
}
|
||||||
goto err_out_free_dev;
|
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);
|
pci_read_config_word(pdev, pm_cap + PCI_PM_CTRL, &pwr_command);
|
||||||
acpi_idle_state = pwr_command & PCI_PM_CTRL_STATE_MASK;
|
acpi_idle_state = pwr_command & PCI_PM_CTRL_STATE_MASK;
|
||||||
} else {
|
} else {
|
||||||
printk(KERN_ERR PFX
|
if (netif_msg_probe(tp)) {
|
||||||
"Cannot find PowerManagement capability, aborting.\n");
|
printk(KERN_ERR PFX
|
||||||
|
"Cannot find PowerManagement capability. "
|
||||||
|
"Aborting.\n");
|
||||||
|
}
|
||||||
goto err_out_mwi;
|
goto err_out_mwi;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* make sure PCI base addr 1 is MMIO */
|
/* make sure PCI base addr 1 is MMIO */
|
||||||
if (!(pci_resource_flags(pdev, 1) & IORESOURCE_MEM)) {
|
if (!(pci_resource_flags(pdev, 1) & IORESOURCE_MEM)) {
|
||||||
printk(KERN_ERR PFX
|
if (netif_msg_probe(tp)) {
|
||||||
"region #1 not an MMIO resource, aborting\n");
|
printk(KERN_ERR PFX
|
||||||
|
"region #1 not an MMIO resource, aborting\n");
|
||||||
|
}
|
||||||
rc = -ENODEV;
|
rc = -ENODEV;
|
||||||
goto err_out_mwi;
|
goto err_out_mwi;
|
||||||
}
|
}
|
||||||
/* check for weird/broken PCI region reporting */
|
/* check for weird/broken PCI region reporting */
|
||||||
if (pci_resource_len(pdev, 1) < R8169_REGS_SIZE) {
|
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;
|
rc = -ENODEV;
|
||||||
goto err_out_mwi;
|
goto err_out_mwi;
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = pci_request_regions(pdev, MODULENAME);
|
rc = pci_request_regions(pdev, MODULENAME);
|
||||||
if (rc) {
|
if (rc < 0) {
|
||||||
printk(KERN_ERR PFX "%s: could not request regions.\n",
|
if (netif_msg_probe(tp)) {
|
||||||
pci_name(pdev));
|
printk(KERN_ERR PFX "%s: could not request regions.\n",
|
||||||
|
pci_name(pdev));
|
||||||
|
}
|
||||||
goto err_out_mwi;
|
goto err_out_mwi;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1231,7 +1388,10 @@ rtl8169_init_board(struct pci_dev *pdev, struct net_device **dev_out,
|
||||||
} else {
|
} else {
|
||||||
rc = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
|
rc = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
|
||||||
if (rc < 0) {
|
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;
|
goto err_out_free_res;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1241,7 +1401,8 @@ rtl8169_init_board(struct pci_dev *pdev, struct net_device **dev_out,
|
||||||
/* ioremap MMIO region */
|
/* ioremap MMIO region */
|
||||||
ioaddr = ioremap(pci_resource_start(pdev, 1), R8169_REGS_SIZE);
|
ioaddr = ioremap(pci_resource_start(pdev, 1), R8169_REGS_SIZE);
|
||||||
if (ioaddr == NULL) {
|
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;
|
rc = -EIO;
|
||||||
goto err_out_free_res;
|
goto err_out_free_res;
|
||||||
}
|
}
|
||||||
|
@ -1272,9 +1433,11 @@ rtl8169_init_board(struct pci_dev *pdev, struct net_device **dev_out,
|
||||||
}
|
}
|
||||||
if (i < 0) {
|
if (i < 0) {
|
||||||
/* Unknown chip: assume array element #0, original RTL-8169 */
|
/* Unknown chip: assume array element #0, original RTL-8169 */
|
||||||
printk(KERN_DEBUG PFX
|
if (netif_msg_probe(tp)) {
|
||||||
"PCI device %s: unknown chip version, assuming %s\n",
|
printk(KERN_DEBUG PFX "PCI device %s: "
|
||||||
pci_name(pdev), rtl_chip_info[0].name);
|
"unknown chip version, assuming %s\n",
|
||||||
|
pci_name(pdev), rtl_chip_info[0].name);
|
||||||
|
}
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
tp->chipset = 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;
|
struct rtl8169_private *tp;
|
||||||
void __iomem *ioaddr = NULL;
|
void __iomem *ioaddr = NULL;
|
||||||
static int board_idx = -1;
|
static int board_idx = -1;
|
||||||
static int printed_version = 0;
|
|
||||||
u8 autoneg, duplex;
|
u8 autoneg, duplex;
|
||||||
u16 speed;
|
u16 speed;
|
||||||
int i, rc;
|
int i, rc;
|
||||||
|
@ -1318,10 +1480,9 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||||
|
|
||||||
board_idx++;
|
board_idx++;
|
||||||
|
|
||||||
if (!printed_version) {
|
if (netif_msg_drv(&debug)) {
|
||||||
printk(KERN_INFO "%s Gigabit Ethernet driver %s loaded\n",
|
printk(KERN_INFO "%s Gigabit Ethernet driver %s loaded\n",
|
||||||
MODULENAME, RTL8169_VERSION);
|
MODULENAME, RTL8169_VERSION);
|
||||||
printed_version = 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = rtl8169_init_board(pdev, &dev, &ioaddr);
|
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
|
#ifdef CONFIG_R8169_NAPI
|
||||||
dev->poll = rtl8169_poll;
|
dev->poll = rtl8169_poll;
|
||||||
dev->weight = R8169_NAPI_WEIGHT;
|
dev->weight = R8169_NAPI_WEIGHT;
|
||||||
printk(KERN_INFO PFX "NAPI enabled\n");
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_R8169_VLAN
|
#ifdef CONFIG_R8169_VLAN
|
||||||
|
@ -1391,20 +1551,24 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
printk(KERN_DEBUG "%s: Identified chip type is '%s'.\n", dev->name,
|
if (netif_msg_probe(tp)) {
|
||||||
rtl_chip_info[tp->chipset].name);
|
printk(KERN_DEBUG "%s: Identified chip type is '%s'.\n",
|
||||||
|
dev->name, rtl_chip_info[tp->chipset].name);
|
||||||
|
}
|
||||||
|
|
||||||
pci_set_drvdata(pdev, dev);
|
pci_set_drvdata(pdev, dev);
|
||||||
|
|
||||||
printk(KERN_INFO "%s: %s at 0x%lx, "
|
if (netif_msg_probe(tp)) {
|
||||||
"%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x, "
|
printk(KERN_INFO "%s: %s at 0x%lx, "
|
||||||
"IRQ %d\n",
|
"%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x, "
|
||||||
dev->name,
|
"IRQ %d\n",
|
||||||
rtl_chip_info[ent->driver_data].name,
|
dev->name,
|
||||||
dev->base_addr,
|
rtl_chip_info[ent->driver_data].name,
|
||||||
dev->dev_addr[0], dev->dev_addr[1],
|
dev->base_addr,
|
||||||
dev->dev_addr[2], dev->dev_addr[3],
|
dev->dev_addr[0], dev->dev_addr[1],
|
||||||
dev->dev_addr[4], dev->dev_addr[5], dev->irq);
|
dev->dev_addr[2], dev->dev_addr[3],
|
||||||
|
dev->dev_addr[4], dev->dev_addr[5], dev->irq);
|
||||||
|
}
|
||||||
|
|
||||||
rtl8169_hw_phy_config(dev);
|
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);
|
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);
|
printk(KERN_INFO PFX "%s: TBI auto-negotiating\n", dev->name);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1860,8 +2024,13 @@ static void rtl8169_reinit_task(void *_data)
|
||||||
ret = rtl8169_open(dev);
|
ret = rtl8169_open(dev);
|
||||||
if (unlikely(ret < 0)) {
|
if (unlikely(ret < 0)) {
|
||||||
if (net_ratelimit()) {
|
if (net_ratelimit()) {
|
||||||
printk(PFX KERN_ERR "%s: reinit failure (status = %d)."
|
struct rtl8169_private *tp = netdev_priv(dev);
|
||||||
" Rescheduling.\n", dev->name, ret);
|
|
||||||
|
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);
|
rtl8169_schedule_work(dev, rtl8169_reinit_task);
|
||||||
}
|
}
|
||||||
|
@ -1886,8 +2055,12 @@ static void rtl8169_reset_task(void *_data)
|
||||||
netif_wake_queue(dev);
|
netif_wake_queue(dev);
|
||||||
} else {
|
} else {
|
||||||
if (net_ratelimit()) {
|
if (net_ratelimit()) {
|
||||||
printk(PFX KERN_EMERG "%s: Rx buffers shortage\n",
|
struct rtl8169_private *tp = netdev_priv(dev);
|
||||||
dev->name);
|
|
||||||
|
if (netif_msg_intr(tp)) {
|
||||||
|
printk(PFX KERN_EMERG
|
||||||
|
"%s: Rx buffers shortage\n", dev->name);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
rtl8169_schedule_work(dev, rtl8169_reset_task);
|
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;
|
int ret = 0;
|
||||||
|
|
||||||
if (unlikely(TX_BUFFS_AVAIL(tp) < skb_shinfo(skb)->nr_frags)) {
|
if (unlikely(TX_BUFFS_AVAIL(tp) < skb_shinfo(skb)->nr_frags)) {
|
||||||
printk(KERN_ERR PFX "%s: BUG! Tx Ring full when queue awake!\n",
|
if (netif_msg_drv(tp)) {
|
||||||
dev->name);
|
printk(KERN_ERR
|
||||||
|
"%s: BUG! Tx Ring full when queue awake!\n",
|
||||||
|
dev->name);
|
||||||
|
}
|
||||||
goto err_stop;
|
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_COMMAND, &pci_cmd);
|
||||||
pci_read_config_word(pdev, PCI_STATUS, &pci_status);
|
pci_read_config_word(pdev, PCI_STATUS, &pci_status);
|
||||||
|
|
||||||
printk(KERN_ERR PFX "%s: PCI error (cmd = 0x%04x, status = 0x%04x).\n",
|
if (netif_msg_intr(tp)) {
|
||||||
dev->name, pci_cmd, pci_status);
|
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:
|
* 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 */
|
/* The infamous DAC f*ckup only happens at boot time */
|
||||||
if ((tp->cp_cmd & PCIDAC) && !tp->dirty_rx && !tp->cur_rx) {
|
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;
|
tp->cp_cmd &= ~PCIDAC;
|
||||||
RTL_W16(CPlusCmd, tp->cp_cmd);
|
RTL_W16(CPlusCmd, tp->cp_cmd);
|
||||||
dev->features &= ~NETIF_F_HIGHDMA;
|
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 = NUM_RX_DESC + tp->dirty_rx - cur_rx;
|
||||||
rx_left = rtl8169_rx_quota(rx_left, (u32) dev->quota);
|
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;
|
unsigned int entry = cur_rx % NUM_RX_DESC;
|
||||||
struct RxDesc *desc = tp->RxDescArray + entry;
|
struct RxDesc *desc = tp->RxDescArray + entry;
|
||||||
u32 status;
|
u32 status;
|
||||||
|
@ -2190,9 +2370,12 @@ rtl8169_rx_interrupt(struct net_device *dev, struct rtl8169_private *tp,
|
||||||
|
|
||||||
if (status & DescOwn)
|
if (status & DescOwn)
|
||||||
break;
|
break;
|
||||||
if (status & RxRES) {
|
if (unlikely(status & RxRES)) {
|
||||||
printk(KERN_INFO "%s: Rx ERROR. status = %08x\n",
|
if (netif_msg_rx_err(tp)) {
|
||||||
dev->name, status);
|
printk(KERN_INFO
|
||||||
|
"%s: Rx ERROR. status = %08x\n",
|
||||||
|
dev->name, status);
|
||||||
|
}
|
||||||
tp->stats.rx_errors++;
|
tp->stats.rx_errors++;
|
||||||
if (status & (RxRWT | RxRUNT))
|
if (status & (RxRWT | RxRUNT))
|
||||||
tp->stats.rx_length_errors++;
|
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_dropped++;
|
||||||
tp->stats.rx_length_errors++;
|
tp->stats.rx_length_errors++;
|
||||||
rtl8169_mark_to_asic(desc, tp->rx_buf_sz);
|
rtl8169_mark_to_asic(desc, tp->rx_buf_sz);
|
||||||
goto move_on;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
rtl8169_rx_csum(skb, desc);
|
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_bytes += pkt_size;
|
||||||
tp->stats.rx_packets++;
|
tp->stats.rx_packets++;
|
||||||
}
|
}
|
||||||
move_on:
|
|
||||||
cur_rx++;
|
|
||||||
rx_left--;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
count = cur_rx - tp->cur_rx;
|
count = cur_rx - tp->cur_rx;
|
||||||
tp->cur_rx = cur_rx;
|
tp->cur_rx = cur_rx;
|
||||||
|
|
||||||
delta = rtl8169_rx_fill(tp, dev, tp->dirty_rx, tp->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);
|
printk(KERN_INFO "%s: no Rx buffer allocated\n", dev->name);
|
||||||
tp->dirty_rx += delta;
|
tp->dirty_rx += delta;
|
||||||
|
|
||||||
|
@ -2263,7 +2443,7 @@ move_on:
|
||||||
* after refill ?
|
* after refill ?
|
||||||
* - how do others driver handle this condition (Uh oh...).
|
* - 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);
|
printk(KERN_EMERG "%s: Rx buffers exhausted\n", dev->name);
|
||||||
|
|
||||||
return count;
|
return count;
|
||||||
|
@ -2315,7 +2495,7 @@ rtl8169_interrupt(int irq, void *dev_instance, struct pt_regs *regs)
|
||||||
|
|
||||||
if (likely(netif_rx_schedule_prep(dev)))
|
if (likely(netif_rx_schedule_prep(dev)))
|
||||||
__netif_rx_schedule(dev);
|
__netif_rx_schedule(dev);
|
||||||
else {
|
else if (netif_msg_intr(tp)) {
|
||||||
printk(KERN_INFO "%s: interrupt %04x taken in poll\n",
|
printk(KERN_INFO "%s: interrupt %04x taken in poll\n",
|
||||||
dev->name, status);
|
dev->name, status);
|
||||||
}
|
}
|
||||||
|
@ -2334,8 +2514,10 @@ rtl8169_interrupt(int irq, void *dev_instance, struct pt_regs *regs)
|
||||||
} while (boguscnt > 0);
|
} while (boguscnt > 0);
|
||||||
|
|
||||||
if (boguscnt <= 0) {
|
if (boguscnt <= 0) {
|
||||||
printk(KERN_WARNING "%s: Too much work at interrupt!\n",
|
if (net_ratelimit() && netif_msg_intr(tp)) {
|
||||||
dev->name);
|
printk(KERN_WARNING
|
||||||
|
"%s: Too much work at interrupt!\n", dev->name);
|
||||||
|
}
|
||||||
/* Clear all interrupt sources. */
|
/* Clear all interrupt sources. */
|
||||||
RTL_W16(IntrStatus, 0xffff);
|
RTL_W16(IntrStatus, 0xffff);
|
||||||
}
|
}
|
||||||
|
@ -2458,8 +2640,10 @@ rtl8169_set_rx_mode(struct net_device *dev)
|
||||||
|
|
||||||
if (dev->flags & IFF_PROMISC) {
|
if (dev->flags & IFF_PROMISC) {
|
||||||
/* Unconditionally log net taps. */
|
/* Unconditionally log net taps. */
|
||||||
printk(KERN_NOTICE "%s: Promiscuous mode enabled.\n",
|
if (netif_msg_link(tp)) {
|
||||||
dev->name);
|
printk(KERN_NOTICE "%s: Promiscuous mode enabled.\n",
|
||||||
|
dev->name);
|
||||||
|
}
|
||||||
rx_mode =
|
rx_mode =
|
||||||
AcceptBroadcast | AcceptMulticast | AcceptMyPhys |
|
AcceptBroadcast | AcceptMulticast | AcceptMyPhys |
|
||||||
AcceptAllPhys;
|
AcceptAllPhys;
|
||||||
|
|
|
@ -4212,7 +4212,7 @@ SK_BOOL DualNet;
|
||||||
Flags);
|
Flags);
|
||||||
|
|
||||||
SkGeStopPort(pAC, IoC, FromPort, SK_STOP_ALL, SK_HARD_RST);
|
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(
|
spin_unlock_irqrestore(
|
||||||
&pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock,
|
&pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock,
|
||||||
Flags);
|
Flags);
|
||||||
|
@ -4355,7 +4355,7 @@ SK_BOOL DualNet;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Inform the world that link protocol is up. */
|
/* 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;
|
break;
|
||||||
case SK_DRV_NET_DOWN: /* SK_U32 Reason */
|
case SK_DRV_NET_DOWN: /* SK_U32 Reason */
|
||||||
|
@ -4368,7 +4368,7 @@ SK_BOOL DualNet;
|
||||||
} else {
|
} else {
|
||||||
DoPrintInterfaceChange = SK_TRUE;
|
DoPrintInterfaceChange = SK_TRUE;
|
||||||
}
|
}
|
||||||
pAC->dev[Param.Para32[1]]->flags &= ~IFF_RUNNING;
|
netif_carrier_off(pAC->dev[Param.Para32[1]]);
|
||||||
break;
|
break;
|
||||||
case SK_DRV_SWITCH_HARD: /* SK_U32 FromPortIdx SK_U32 ToPortIdx */
|
case SK_DRV_SWITCH_HARD: /* SK_U32 FromPortIdx SK_U32 ToPortIdx */
|
||||||
SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT,
|
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
|
#ifdef CONFIG_NET_POLL_CONTROLLER
|
||||||
dev->poll_controller = &SkGePollController;
|
dev->poll_controller = &SkGePollController;
|
||||||
#endif
|
#endif
|
||||||
dev->flags &= ~IFF_RUNNING;
|
|
||||||
SET_NETDEV_DEV(dev, &pdev->dev);
|
SET_NETDEV_DEV(dev, &pdev->dev);
|
||||||
SET_ETHTOOL_OPS(dev, &SkGeEthtoolOps);
|
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->set_mac_address = &SkGeSetMacAddr;
|
||||||
dev->do_ioctl = &SkGeIoctl;
|
dev->do_ioctl = &SkGeIoctl;
|
||||||
dev->change_mtu = &SkGeChangeMtu;
|
dev->change_mtu = &SkGeChangeMtu;
|
||||||
dev->flags &= ~IFF_RUNNING;
|
|
||||||
SET_NETDEV_DEV(dev, &pdev->dev);
|
SET_NETDEV_DEV(dev, &pdev->dev);
|
||||||
SET_ETHTOOL_OPS(dev, &SkGeEthtoolOps);
|
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 */
|
|
3386
drivers/net/skge.c
Normal file
3386
drivers/net/skge.c
Normal file
File diff suppressed because it is too large
Load diff
3005
drivers/net/skge.h
Normal file
3005
drivers/net/skge.h
Normal file
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.
|
* Transmit timeout, default 5 seconds.
|
||||||
*/
|
*/
|
||||||
static int watchdog = 5000;
|
static int watchdog = 1000;
|
||||||
module_param(watchdog, int, 0400);
|
module_param(watchdog, int, 0400);
|
||||||
MODULE_PARM_DESC(watchdog, "transmit timeout in milliseconds");
|
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);
|
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
|
* If THROTTLE_TX_PKTS is set, we stop the queue here. This will
|
||||||
* before queueing this packet for TX, and if it's clear then
|
* have the effect of having at most one packet queued for TX
|
||||||
* we stop the queue here. This will have the effect of
|
* in the chip's memory at all time.
|
||||||
* 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
|
* If THROTTLE_TX_PKTS is not set then the queue is stopped only
|
||||||
* is stopped only when memory allocation (MC_ALLOC) does not
|
* when memory allocation (MC_ALLOC) does not succeed right away.
|
||||||
* succeed right away.
|
|
||||||
*/
|
*/
|
||||||
if (THROTTLE_TX_PKTS && !(SMC_GET_INT() & IM_TX_EMPTY_INT))
|
if (THROTTLE_TX_PKTS)
|
||||||
netif_stop_queue(dev);
|
netif_stop_queue(dev);
|
||||||
|
|
||||||
/* queue the packet for TX */
|
/* 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",
|
DBG(2, "%s: TX STATUS 0x%04x PNR 0x%02x\n",
|
||||||
dev->name, tx_status, packet_no);
|
dev->name, tx_status, packet_no);
|
||||||
|
|
||||||
if (!(tx_status & TS_SUCCESS))
|
if (!(tx_status & ES_TX_SUC))
|
||||||
lp->stats.tx_errors++;
|
lp->stats.tx_errors++;
|
||||||
if (tx_status & TS_LOSTCAR)
|
|
||||||
|
if (tx_status & ES_LOSTCARR)
|
||||||
lp->stats.tx_carrier_errors++;
|
lp->stats.tx_carrier_errors++;
|
||||||
|
|
||||||
if (tx_status & TS_LATCOL) {
|
if (tx_status & (ES_LATCOL | ES_16COL)) {
|
||||||
PRINTK("%s: late collision occurred on last xmit\n", dev->name);
|
PRINTK("%s: %s occurred on last xmit\n", dev->name,
|
||||||
|
(tx_status & ES_LATCOL) ?
|
||||||
|
"late collision" : "too many collisions");
|
||||||
lp->stats.tx_window_errors++;
|
lp->stats.tx_window_errors++;
|
||||||
if (!(lp->stats.tx_window_errors & 63) && net_ratelimit()) {
|
if (!(lp->stats.tx_window_errors & 63) && net_ratelimit()) {
|
||||||
printk(KERN_INFO "%s: unexpectedly large numbers of "
|
printk(KERN_INFO "%s: unexpectedly large number of "
|
||||||
"late collisions. Please check duplex "
|
"bad collisions. Please check duplex "
|
||||||
"setting.\n", dev->name);
|
"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;
|
old_carrier = netif_carrier_ok(dev) ? 1 : 0;
|
||||||
|
|
||||||
SMC_SELECT_BANK(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);
|
SMC_SELECT_BANK(2);
|
||||||
|
|
||||||
if (init || (old_carrier != new_carrier)) {
|
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)
|
if (!status)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (status & IM_RCV_INT) {
|
if (status & IM_TX_INT) {
|
||||||
DBG(3, "%s: RX irq\n", dev->name);
|
/* do this before RX as it will free memory quickly */
|
||||||
smc_rcv(dev);
|
|
||||||
} else if (status & IM_TX_INT) {
|
|
||||||
DBG(3, "%s: TX int\n", dev->name);
|
DBG(3, "%s: TX int\n", dev->name);
|
||||||
smc_tx(dev);
|
smc_tx(dev);
|
||||||
SMC_ACK_INT(IM_TX_INT);
|
SMC_ACK_INT(IM_TX_INT);
|
||||||
if (THROTTLE_TX_PKTS)
|
if (THROTTLE_TX_PKTS)
|
||||||
netif_wake_queue(dev);
|
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) {
|
} else if (status & IM_ALLOC_INT) {
|
||||||
DBG(3, "%s: Allocation irq\n", dev->name);
|
DBG(3, "%s: Allocation irq\n", dev->name);
|
||||||
tasklet_hi_schedule(&lp->tx_task);
|
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 */
|
/* multiple collisions */
|
||||||
lp->stats.collisions += card_stats & 0xF;
|
lp->stats.collisions += card_stats & 0xF;
|
||||||
} else if (status & IM_RX_OVRN_INT) {
|
} 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);
|
SMC_ACK_INT(IM_RX_OVRN_INT);
|
||||||
lp->stats.rx_errors++;
|
lp->stats.rx_errors++;
|
||||||
lp->stats.rx_fifo_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);
|
struct smc_local *lp = netdev_priv(dev);
|
||||||
void __iomem *ioaddr = lp->base;
|
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__);
|
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();
|
mask = SMC_GET_INT_MASK();
|
||||||
fifo = SMC_GET_FIFO();
|
fifo = SMC_GET_FIFO();
|
||||||
SMC_SELECT_BANK(0);
|
SMC_SELECT_BANK(0);
|
||||||
|
eph_st = SMC_GET_EPH_STATUS();
|
||||||
meminfo = SMC_GET_MIR();
|
meminfo = SMC_GET_MIR();
|
||||||
SMC_SELECT_BANK(2);
|
SMC_SELECT_BANK(2);
|
||||||
spin_unlock_irq(&lp->lock);
|
spin_unlock_irq(&lp->lock);
|
||||||
PRINTK( "%s: INT 0x%02x MASK 0x%02x MEM 0x%04x FIFO 0x%04x\n",
|
PRINTK( "%s: TX timeout (INT 0x%02x INTMASK 0x%02x "
|
||||||
dev->name, status, mask, meminfo, fifo );
|
"MEM 0x%04x FIFO 0x%04x EPH_ST 0x%04x)\n",
|
||||||
|
dev->name, status, mask, meminfo, fifo, eph_st );
|
||||||
|
|
||||||
smc_reset(dev);
|
smc_reset(dev);
|
||||||
smc_enable(dev);
|
smc_enable(dev);
|
||||||
|
@ -1863,7 +1871,7 @@ static int __init smc_probe(struct net_device *dev, void __iomem *ioaddr)
|
||||||
SMC_SELECT_BANK(1);
|
SMC_SELECT_BANK(1);
|
||||||
val = SMC_GET_BASE();
|
val = SMC_GET_BASE();
|
||||||
val = ((val & 0x1F00) >> 3) << SMC_IO_SHIFT;
|
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",
|
printk("%s: IOADDR %p doesn't match configuration (%x).\n",
|
||||||
CARDNAME, ioaddr, val);
|
CARDNAME, ioaddr, val);
|
||||||
}
|
}
|
||||||
|
|
|
@ -151,7 +151,7 @@
|
||||||
|
|
||||||
/* We actually can't write halfwords properly if not word aligned */
|
/* We actually can't write halfwords properly if not word aligned */
|
||||||
static inline void
|
static inline void
|
||||||
SMC_outw(u16 val, unsigned long ioaddr, int reg)
|
SMC_outw(u16 val, void __iomem *ioaddr, int reg)
|
||||||
{
|
{
|
||||||
if (reg & 2) {
|
if (reg & 2) {
|
||||||
unsigned int v = val << 16;
|
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) \
|
#define SMC_insl(a, r, p, l) \
|
||||||
smc_pxa_dma_insl(a, lp->physaddr, r, dev->dma, p, l)
|
smc_pxa_dma_insl(a, lp->physaddr, r, dev->dma, p, l)
|
||||||
static inline void
|
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)
|
u_char *buf, int len)
|
||||||
{
|
{
|
||||||
dma_addr_t dmabuf;
|
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) \
|
#define SMC_insw(a, r, p, l) \
|
||||||
smc_pxa_dma_insw(a, lp->physaddr, r, dev->dma, p, l)
|
smc_pxa_dma_insw(a, lp->physaddr, r, dev->dma, p, l)
|
||||||
static inline void
|
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)
|
u_char *buf, int len)
|
||||||
{
|
{
|
||||||
dma_addr_t dmabuf;
|
dma_addr_t dmabuf;
|
||||||
|
@ -680,14 +680,6 @@ static const char * chip_ids[ 16 ] = {
|
||||||
NULL, NULL, NULL};
|
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
|
. 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_FIFO() SMC_inw( ioaddr, FIFO_REG )
|
||||||
#define SMC_GET_PTR() SMC_inw( ioaddr, PTR_REG )
|
#define SMC_GET_PTR() SMC_inw( ioaddr, PTR_REG )
|
||||||
#define SMC_SET_PTR(x) SMC_outw( x, 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_GET_RCR() SMC_inw( ioaddr, RCR_REG )
|
||||||
#define SMC_SET_RCR(x) SMC_outw( x, ioaddr, RCR_REG )
|
#define SMC_SET_RCR(x) SMC_outw( x, ioaddr, RCR_REG )
|
||||||
#define SMC_GET_REV() SMC_inw( ioaddr, REV_REG )
|
#define SMC_GET_REV() SMC_inw( ioaddr, REV_REG )
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
/*
|
/*
|
||||||
Written 1998-2000 by Donald Becker.
|
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
|
send all bug reports to me, and not to Donald Becker, as this code
|
||||||
has been heavily modified from Donald's original version.
|
has been heavily modified from Donald's original version.
|
||||||
|
|
||||||
|
@ -129,12 +129,18 @@
|
||||||
- put the chip to a D3 slumber on driver unload
|
- put the chip to a D3 slumber on driver unload
|
||||||
- added config option to enable/disable NAPI
|
- 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_NAME "starfire"
|
||||||
#define DRV_VERSION "1.03+LK1.4.1"
|
#define DRV_VERSION "1.03+LK1.4.2"
|
||||||
#define DRV_RELDATE "February 10, 2002"
|
#define DRV_RELDATE "January 19, 2005"
|
||||||
|
|
||||||
#include <linux/config.h>
|
#include <linux/config.h>
|
||||||
#include <linux/version.h>
|
#include <linux/version.h>
|
||||||
|
@ -145,25 +151,15 @@ TODO: bugfixes (no bugs known as of right now)
|
||||||
#include <linux/etherdevice.h>
|
#include <linux/etherdevice.h>
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
#include <linux/delay.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/processor.h> /* Processor type for cache alignment. */
|
||||||
#include <asm/uaccess.h>
|
#include <asm/uaccess.h>
|
||||||
#include <asm/io.h>
|
#include <asm/io.h>
|
||||||
|
|
||||||
/*
|
#include "starfire_firmware.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
|
|
||||||
/*
|
/*
|
||||||
* The current frame processor firmware fails to checksum a fragment
|
* 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.
|
* 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
|
* Define this if using the driver with the zero-copy patch
|
||||||
*/
|
*/
|
||||||
#if defined(HAS_FIRMWARE) && defined(MAX_SKB_FRAGS)
|
|
||||||
#define ZEROCOPY
|
#define ZEROCOPY
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAS_FIRMWARE
|
|
||||||
#include "starfire_firmware.h"
|
|
||||||
#endif /* HAS_FIRMWARE */
|
|
||||||
|
|
||||||
#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
|
#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
|
||||||
#define VLAN_SUPPORT
|
#define VLAN_SUPPORT
|
||||||
|
@ -202,11 +192,7 @@ static int mtu;
|
||||||
The Starfire has a 512 element hash table based on the Ethernet CRC. */
|
The Starfire has a 512 element hash table based on the Ethernet CRC. */
|
||||||
static int multicast_filter_limit = 512;
|
static int multicast_filter_limit = 512;
|
||||||
/* Whether to do TCP/UDP checksums in hardware */
|
/* Whether to do TCP/UDP checksums in hardware */
|
||||||
#ifdef HAS_FIRMWARE
|
|
||||||
static int enable_hw_cksum = 1;
|
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.*/
|
#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
|
#define RX_DESC_ADDR_SIZE RxDescAddr32bit
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef MAX_SKB_FRAGS
|
|
||||||
#define skb_first_frag_len(skb) skb_headlen(skb)
|
#define skb_first_frag_len(skb) skb_headlen(skb)
|
||||||
#define skb_num_frags(skb) (skb_shinfo(skb)->nr_frags + 1)
|
#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
|
#ifdef HAVE_NETDEV_POLL
|
||||||
#define init_poll(dev) \
|
#define init_poll(dev) \
|
||||||
|
do { \
|
||||||
dev->poll = &netdev_poll; \
|
dev->poll = &netdev_poll; \
|
||||||
dev->weight = max_interrupt_work;
|
dev->weight = max_interrupt_work; \
|
||||||
|
} while (0)
|
||||||
#define netdev_rx(dev, ioaddr) \
|
#define netdev_rx(dev, ioaddr) \
|
||||||
do { \
|
do { \
|
||||||
u32 intr_enable; \
|
u32 intr_enable; \
|
||||||
|
@ -341,7 +299,7 @@ do { \
|
||||||
/* Paranoia check */ \
|
/* Paranoia check */ \
|
||||||
intr_enable = readl(ioaddr + IntrEnable); \
|
intr_enable = readl(ioaddr + IntrEnable); \
|
||||||
if (intr_enable & (IntrRxDone | IntrRxEmpty)) { \
|
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); \
|
intr_enable &= ~(IntrRxDone | IntrRxEmpty); \
|
||||||
writel(intr_enable, ioaddr + IntrEnable); \
|
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_AUTHOR("Donald Becker <becker@scyld.com>");
|
||||||
MODULE_DESCRIPTION("Adaptec Starfire Ethernet driver");
|
MODULE_DESCRIPTION("Adaptec Starfire Ethernet driver");
|
||||||
MODULE_LICENSE("GPL");
|
MODULE_LICENSE("GPL");
|
||||||
|
MODULE_VERSION(DRV_VERSION);
|
||||||
|
|
||||||
module_param(max_interrupt_work, int, 0);
|
module_param(max_interrupt_work, int, 0);
|
||||||
module_param(mtu, 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
|
minimum-length padding. It does not use the completion queue
|
||||||
consumer index, but instead checks for non-zero status entries.
|
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
|
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
|
should fit in a single descriptor. The driver does not use the completion
|
||||||
queue consumer index, but instead checks for non-zero status entries.
|
queue consumer index, but instead checks for non-zero status entries.
|
||||||
|
@ -476,7 +435,7 @@ IVc. Errata
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
enum chip_capability_flags {CanHaveMII=1, };
|
enum chip_capability_flags {CanHaveMII=1, };
|
||||||
|
|
||||||
|
@ -670,7 +629,6 @@ struct full_rx_done_desc {
|
||||||
u32 timestamp;
|
u32 timestamp;
|
||||||
};
|
};
|
||||||
/* XXX: this is ugly and I'm not sure it's worth the trouble -Ion */
|
/* XXX: this is ugly and I'm not sure it's worth the trouble -Ion */
|
||||||
#ifdef HAS_FIRMWARE
|
|
||||||
#ifdef VLAN_SUPPORT
|
#ifdef VLAN_SUPPORT
|
||||||
typedef struct full_rx_done_desc rx_done_desc;
|
typedef struct full_rx_done_desc rx_done_desc;
|
||||||
#define RxComplType RxComplType3
|
#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;
|
typedef struct csum_rx_done_desc rx_done_desc;
|
||||||
#define RxComplType RxComplType2
|
#define RxComplType RxComplType2
|
||||||
#endif /* not VLAN_SUPPORT */
|
#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 {
|
enum rx_done_bits {
|
||||||
RxOK=0x20000000, RxFIFOErr=0x10000000, RxBufQ2=0x08000000,
|
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 */
|
/* enable MWI -- it vastly improves Rx performance on sparc64 */
|
||||||
pci_set_mwi(pdev);
|
pci_set_mwi(pdev);
|
||||||
|
|
||||||
#ifdef MAX_SKB_FRAGS
|
|
||||||
dev->features |= NETIF_F_SG;
|
|
||||||
#endif /* MAX_SKB_FRAGS */
|
|
||||||
#ifdef ZEROCOPY
|
#ifdef ZEROCOPY
|
||||||
/* Starfire can do TCP/UDP checksumming */
|
/* Starfire can do TCP/UDP checksumming */
|
||||||
if (enable_hw_cksum)
|
if (enable_hw_cksum)
|
||||||
dev->features |= NETIF_F_IP_CSUM;
|
dev->features |= NETIF_F_IP_CSUM | NETIF_F_SG;
|
||||||
#endif /* ZEROCOPY */
|
#endif /* ZEROCOPY */
|
||||||
#ifdef VLAN_SUPPORT
|
#ifdef VLAN_SUPPORT
|
||||||
dev->features |= NETIF_F_HW_VLAN_RX | NETIF_F_HW_VLAN_FILTER;
|
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. */
|
/* The chip-specific entries in the device structure. */
|
||||||
dev->open = &netdev_open;
|
dev->open = &netdev_open;
|
||||||
dev->hard_start_xmit = &start_tx;
|
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);
|
init_poll(dev);
|
||||||
dev->stop = &netdev_close;
|
dev->stop = &netdev_close;
|
||||||
dev->get_stats = &get_stats;
|
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)
|
if ((mdio_read(dev, phy, MII_BMCR) & BMCR_RESET) == 0)
|
||||||
break;
|
break;
|
||||||
if (boguscnt == 0) {
|
if (boguscnt == 0) {
|
||||||
printk("%s: PHY reset never completed!\n", dev->name);
|
printk("%s: PHY#%d reset never completed!\n", dev->name, phy);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
mii_status = mdio_read(dev, phy, MII_BMSR);
|
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;
|
size_t tx_done_q_size, rx_done_q_size, tx_ring_size, rx_ring_size;
|
||||||
|
|
||||||
/* Do we ever need to reset the chip??? */
|
/* Do we ever need to reset the chip??? */
|
||||||
|
|
||||||
retval = request_irq(dev->irq, &intr_handler, SA_SHIRQ, dev->name, dev);
|
retval = request_irq(dev->irq, &intr_handler, SA_SHIRQ, dev->name, dev);
|
||||||
if (retval)
|
if (retval)
|
||||||
return retval;
|
return retval;
|
||||||
|
@ -1211,7 +1159,6 @@ static int netdev_open(struct net_device *dev)
|
||||||
|
|
||||||
writel(np->intr_timer_ctrl, ioaddr + IntrTimerCtrl);
|
writel(np->intr_timer_ctrl, ioaddr + IntrTimerCtrl);
|
||||||
|
|
||||||
netif_start_if(dev);
|
|
||||||
netif_start_queue(dev);
|
netif_start_queue(dev);
|
||||||
|
|
||||||
if (debug > 1)
|
if (debug > 1)
|
||||||
|
@ -1238,13 +1185,11 @@ static int netdev_open(struct net_device *dev)
|
||||||
writel(ETH_P_8021Q, ioaddr + VlanType);
|
writel(ETH_P_8021Q, ioaddr + VlanType);
|
||||||
#endif /* VLAN_SUPPORT */
|
#endif /* VLAN_SUPPORT */
|
||||||
|
|
||||||
#ifdef HAS_FIRMWARE
|
|
||||||
/* Load Rx/Tx firmware into the frame processors */
|
/* Load Rx/Tx firmware into the frame processors */
|
||||||
for (i = 0; i < FIRMWARE_RX_SIZE * 2; i++)
|
for (i = 0; i < FIRMWARE_RX_SIZE * 2; i++)
|
||||||
writel(firmware_rx[i], ioaddr + RxGfpMem + i * 4);
|
writel(firmware_rx[i], ioaddr + RxGfpMem + i * 4);
|
||||||
for (i = 0; i < FIRMWARE_TX_SIZE * 2; i++)
|
for (i = 0; i < FIRMWARE_TX_SIZE * 2; i++)
|
||||||
writel(firmware_tx[i], ioaddr + TxGfpMem + i * 4);
|
writel(firmware_tx[i], ioaddr + TxGfpMem + i * 4);
|
||||||
#endif /* HAS_FIRMWARE */
|
|
||||||
if (enable_hw_cksum)
|
if (enable_hw_cksum)
|
||||||
/* Enable the Rx and Tx units, and the Rx/Tx frame processors. */
|
/* Enable the Rx and Tx units, and the Rx/Tx frame processors. */
|
||||||
writel(TxEnable|TxGFPEnable|RxEnable|RxGFPEnable, ioaddr + GenCtrl);
|
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;
|
u32 status;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
kick_tx_timer(dev, tx_timeout, TX_TIMEOUT);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* be cautious here, wrapping the queue has weird semantics
|
* be cautious here, wrapping the queue has weird semantics
|
||||||
* and we may not have enough slots even when it seems we do.
|
* 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)
|
if (has_bad_length)
|
||||||
skb_checksum_help(skb);
|
skb_checksum_help(skb, 0);
|
||||||
}
|
}
|
||||||
#endif /* ZEROCOPY && HAS_BROKEN_FIRMWARE */
|
#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 =
|
np->tx_info[entry].mapping =
|
||||||
pci_map_single(np->pci_dev, skb->data, skb_first_frag_len(skb), PCI_DMA_TODEVICE);
|
pci_map_single(np->pci_dev, skb->data, skb_first_frag_len(skb), PCI_DMA_TODEVICE);
|
||||||
} else {
|
} else {
|
||||||
#ifdef MAX_SKB_FRAGS
|
|
||||||
skb_frag_t *this_frag = &skb_shinfo(skb)->frags[i - 1];
|
skb_frag_t *this_frag = &skb_shinfo(skb)->frags[i - 1];
|
||||||
status |= this_frag->size;
|
status |= this_frag->size;
|
||||||
np->tx_info[entry].mapping =
|
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);
|
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);
|
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->tx_info[entry].mapping = 0;
|
||||||
np->dirty_tx += np->tx_info[entry].used_slots;
|
np->dirty_tx += np->tx_info[entry].used_slots;
|
||||||
entry = (entry + np->tx_info[entry].used_slots) % TX_RING_SIZE;
|
entry = (entry + np->tx_info[entry].used_slots) % TX_RING_SIZE;
|
||||||
#ifdef MAX_SKB_FRAGS
|
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < skb_shinfo(skb)->nr_frags; 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++;
|
entry++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif /* MAX_SKB_FRAGS */
|
|
||||||
dev_kfree_skb_irq(skb);
|
dev_kfree_skb_irq(skb);
|
||||||
}
|
}
|
||||||
np->tx_done_q[np->tx_done].status = 0;
|
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)
|
if (debug > 4)
|
||||||
printk(KERN_DEBUG " netdev_rx() status of %d was %#8.8x.\n", np->rx_done, desc_status);
|
printk(KERN_DEBUG " netdev_rx() status of %d was %#8.8x.\n", np->rx_done, desc_status);
|
||||||
if (!(desc_status & RxOK)) {
|
if (!(desc_status & RxOK)) {
|
||||||
/* There was a error. */
|
/* There was an error. */
|
||||||
if (debug > 2)
|
if (debug > 2)
|
||||||
printk(KERN_DEBUG " netdev_rx() Rx error was %#8.8x.\n", desc_status);
|
printk(KERN_DEBUG " netdev_rx() Rx error was %#8.8x.\n", desc_status);
|
||||||
np->stats.rx_errors++;
|
np->stats.rx_errors++;
|
||||||
|
@ -1656,11 +1596,10 @@ static int __netdev_rx(struct net_device *dev, int *quota)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
skb->protocol = eth_type_trans(skb, dev);
|
skb->protocol = eth_type_trans(skb, dev);
|
||||||
#if defined(HAS_FIRMWARE) || defined(VLAN_SUPPORT)
|
#ifdef VLAN_SUPPORT
|
||||||
if (debug > 4)
|
if (debug > 4)
|
||||||
printk(KERN_DEBUG " netdev_rx() status2 of %d was %#4.4x.\n", np->rx_done, le16_to_cpu(desc->status2));
|
printk(KERN_DEBUG " netdev_rx() status2 of %d was %#4.4x.\n", np->rx_done, le16_to_cpu(desc->status2));
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAS_FIRMWARE
|
|
||||||
if (le16_to_cpu(desc->status2) & 0x0100) {
|
if (le16_to_cpu(desc->status2) & 0x0100) {
|
||||||
skb->ip_summed = CHECKSUM_UNNECESSARY;
|
skb->ip_summed = CHECKSUM_UNNECESSARY;
|
||||||
np->stats.rx_compressed++;
|
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);
|
skb->csum = le16_to_cpu(desc->csum);
|
||||||
printk(KERN_DEBUG "%s: checksum_hw, status2 = %#x\n", dev->name, le16_to_cpu(desc->status2));
|
printk(KERN_DEBUG "%s: checksum_hw, status2 = %#x\n", dev->name, le16_to_cpu(desc->status2));
|
||||||
}
|
}
|
||||||
#endif /* HAS_FIRMWARE */
|
|
||||||
#ifdef VLAN_SUPPORT
|
#ifdef VLAN_SUPPORT
|
||||||
if (np->vlgrp && le16_to_cpu(desc->status2) & 0x0200) {
|
if (np->vlgrp && le16_to_cpu(desc->status2) & 0x0200) {
|
||||||
if (debug > 4)
|
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)
|
static void set_rx_mode(struct net_device *dev)
|
||||||
{
|
{
|
||||||
struct netdev_private *np = netdev_priv(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));
|
memset(mc_filter, 0, sizeof(mc_filter));
|
||||||
for (i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count;
|
for (i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count;
|
||||||
i++, mclist = mclist->next) {
|
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;
|
int bit_nr = ether_crc_le(ETH_ALEN, mclist->dmi_addr) >> 23;
|
||||||
__u32 *fptr = (__u32 *) &mc_filter[(bit_nr >> 4) & ~1];
|
__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);
|
struct netdev_private *np = netdev_priv(dev);
|
||||||
strcpy(info->driver, DRV_NAME);
|
strcpy(info->driver, DRV_NAME);
|
||||||
strcpy(info->version, DRV_VERSION);
|
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)
|
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;
|
int i;
|
||||||
|
|
||||||
netif_stop_queue(dev);
|
netif_stop_queue(dev);
|
||||||
netif_stop_if(dev);
|
|
||||||
|
|
||||||
if (debug > 1) {
|
if (debug > 1) {
|
||||||
printk(KERN_DEBUG "%s: Shutting down ethercard, Intr status %#8.8x.\n",
|
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 */
|
/* when a module, this is printed whether or not devices are found in probe */
|
||||||
#ifdef MODULE
|
#ifdef MODULE
|
||||||
printk(version);
|
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
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef ADDR_64BITS
|
#ifndef ADDR_64BITS
|
||||||
/* we can do this test only at run-time... sigh */
|
/* we can do this test only at run-time... sigh */
|
||||||
if (sizeof(dma_addr_t) == sizeof(u64)) {
|
if (sizeof(dma_addr_t) == sizeof(u64)) {
|
||||||
|
@ -2192,10 +2134,6 @@ static int __init starfire_init (void)
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
#endif /* not ADDR_64BITS */
|
#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);
|
return pci_module_init (&starfire_driver);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
346
drivers/net/starfire_firmware.h
Normal file
346
drivers/net/starfire_firmware.h
Normal file
|
@ -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) {
|
if (priv->link) {
|
||||||
priv->link = 0;
|
priv->link = 0;
|
||||||
printk(KERN_DEBUG "TLAN: %s has lost link\n", dev->name);
|
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 );
|
TLan_SetTimer( dev, (2*HZ), TLAN_TIMER_LINK_BEAT );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -2829,7 +2829,7 @@ void TLan_PhyMonitor( struct net_device *dev )
|
||||||
if ((phy_status & MII_GS_LINK) && !priv->link) {
|
if ((phy_status & MII_GS_LINK) && !priv->link) {
|
||||||
priv->link = 1;
|
priv->link = 1;
|
||||||
printk(KERN_DEBUG "TLAN: %s has reestablished link\n", dev->name);
|
printk(KERN_DEBUG "TLAN: %s has reestablished link\n", dev->name);
|
||||||
dev->flags |= IFF_RUNNING;
|
netif_carrier_on(dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Setup a new monitor */
|
/* Setup a new monitor */
|
||||||
|
|
|
@ -888,11 +888,6 @@ static int tok_open(struct net_device *dev)
|
||||||
ti->sap_status = CLOSED; /* CLOSED or OPEN */
|
ti->sap_status = CLOSED; /* CLOSED or OPEN */
|
||||||
ti->open_failure = NO; /* NO or YES */
|
ti->open_failure = NO; /* NO or YES */
|
||||||
ti->open_mode = MANUAL; /* MANUAL or AUTOMATIC */
|
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 */
|
ti->sram_phys &= ~1; /* to reverse what we do in tok_close */
|
||||||
/* init the spinlock */
|
/* 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->open_status = CLOSED;
|
||||||
ti->sap_status = CLOSED;
|
ti->sap_status = CLOSED;
|
||||||
ti->open_mode = AUTOMATIC;
|
ti->open_mode = AUTOMATIC;
|
||||||
dev->flags &= ~IFF_RUNNING;
|
netif_carrier_off(dev);
|
||||||
netif_stop_queue(dev);
|
netif_stop_queue(dev);
|
||||||
ti->open_action = RESTART;
|
ti->open_action = RESTART;
|
||||||
outb(0, dev->base_addr + ADAPTRESET);
|
outb(0, dev->base_addr + ADAPTRESET);
|
||||||
|
@ -1323,7 +1318,7 @@ irqreturn_t tok_interrupt(int irq, void *dev_id, struct pt_regs *regs)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
netif_wake_queue(dev);
|
netif_wake_queue(dev);
|
||||||
dev->flags |= IFF_RUNNING;/*BMS 12/2000*/
|
netif_carrier_on(dev);
|
||||||
break;
|
break;
|
||||||
case DIR_INTERRUPT:
|
case DIR_INTERRUPT:
|
||||||
case DIR_MOD_OPEN_PARAMS:
|
case DIR_MOD_OPEN_PARAMS:
|
||||||
|
@ -1427,7 +1422,7 @@ irqreturn_t tok_interrupt(int irq, void *dev_id, struct pt_regs *regs)
|
||||||
ring_status);
|
ring_status);
|
||||||
if(ring_status& (REMOVE_RECV|AUTO_REMOVAL|LOBE_FAULT)){
|
if(ring_status& (REMOVE_RECV|AUTO_REMOVAL|LOBE_FAULT)){
|
||||||
netif_stop_queue(dev);
|
netif_stop_queue(dev);
|
||||||
dev->flags &= ~IFF_RUNNING;/*not typical Linux*/
|
netif_carrier_off(dev);
|
||||||
DPRINTK("Remove received, or Auto-removal error"
|
DPRINTK("Remove received, or Auto-removal error"
|
||||||
", or Lobe fault\n");
|
", or Lobe fault\n");
|
||||||
DPRINTK("We'll try to reopen the closed adapter"
|
DPRINTK("We'll try to reopen the closed adapter"
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
* Generic HDLC support routines for Linux
|
* Generic HDLC support routines for Linux
|
||||||
* Frame Relay support
|
* 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
|
* 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
|
* under the terms of version 2 of the GNU General Public License
|
||||||
|
@ -27,6 +27,10 @@
|
||||||
active = open and "link reliable"
|
active = open and "link reliable"
|
||||||
exist = new = not used
|
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>
|
#include <linux/module.h>
|
||||||
|
@ -49,45 +53,41 @@
|
||||||
#undef DEBUG_ECN
|
#undef DEBUG_ECN
|
||||||
#undef DEBUG_LINK
|
#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 NLPID_IP 0xCC
|
||||||
#define PVC_STATE_ACTIVE 0x02
|
#define NLPID_IPV6 0x8E
|
||||||
#define PVC_STATE_FECN 0x08 /* FECN condition */
|
#define NLPID_SNAP 0x80
|
||||||
#define PVC_STATE_BECN 0x10 /* BECN condition */
|
#define NLPID_PAD 0x00
|
||||||
|
#define NLPID_CCITT_ANSI_LMI 0x08
|
||||||
|
#define NLPID_CISCO_LMI 0x09
|
||||||
|
|
||||||
|
|
||||||
#define FR_UI 0x03
|
#define LMI_CCITT_ANSI_DLCI 0 /* LMI DLCI */
|
||||||
#define FR_PAD 0x00
|
#define LMI_CISCO_DLCI 1023
|
||||||
|
|
||||||
#define NLPID_IP 0xCC
|
#define LMI_CALLREF 0x00 /* Call Reference */
|
||||||
#define NLPID_IPV6 0x8E
|
#define LMI_ANSI_LOCKSHIFT 0x95 /* ANSI locking shift */
|
||||||
#define NLPID_SNAP 0x80
|
#define LMI_ANSI_CISCO_REPTYPE 0x01 /* report type */
|
||||||
#define NLPID_PAD 0x00
|
#define LMI_CCITT_REPTYPE 0x51
|
||||||
#define NLPID_Q933 0x08
|
#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_ENQUIRY 0x75
|
||||||
#define LMI_STATUS 0x7D /* reply */
|
#define LMI_STATUS 0x7D /* reply */
|
||||||
|
|
||||||
#define LMI_REPT_LEN 1 /* report type element length */
|
#define LMI_REPT_LEN 1 /* report type element length */
|
||||||
#define LMI_INTEG_LEN 2 /* link integrity element length */
|
#define LMI_INTEG_LEN 2 /* link integrity element length */
|
||||||
|
|
||||||
#define LMI_LENGTH 13 /* standard LMI frame length */
|
#define LMI_CCITT_CISCO_LENGTH 13 /* LMI frame lengths */
|
||||||
#define LMI_ANSI_LENGTH 14
|
#define LMI_ANSI_LENGTH 14
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
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)
|
static int fr_hard_header(struct sk_buff **skb_p, u16 dlci)
|
||||||
{
|
{
|
||||||
u16 head_len;
|
u16 head_len;
|
||||||
struct sk_buff *skb = *skb_p;
|
struct sk_buff *skb = *skb_p;
|
||||||
|
|
||||||
switch (skb->protocol) {
|
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):
|
case __constant_ntohs(ETH_P_IP):
|
||||||
head_len = 4;
|
head_len = 4;
|
||||||
skb_push(skb, head_len);
|
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;
|
skb->data[3] = NLPID_IPV6;
|
||||||
break;
|
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):
|
case __constant_ntohs(ETH_P_802_3):
|
||||||
head_len = 10;
|
head_len = 10;
|
||||||
if (skb_headroom(skb) < head_len) {
|
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);
|
hdlc_device *hdlc = dev_to_hdlc(dev);
|
||||||
struct sk_buff *skb;
|
struct sk_buff *skb;
|
||||||
pvc_device *pvc = hdlc->state.fr.first_pvc;
|
pvc_device *pvc = hdlc->state.fr.first_pvc;
|
||||||
int len = (hdlc->state.fr.settings.lmi == LMI_ANSI) ? LMI_ANSI_LENGTH
|
int lmi = hdlc->state.fr.settings.lmi;
|
||||||
: LMI_LENGTH;
|
int dce = hdlc->state.fr.settings.dce;
|
||||||
int stat_len = 3;
|
int len = lmi == LMI_ANSI ? LMI_ANSI_LENGTH : LMI_CCITT_CISCO_LENGTH;
|
||||||
|
int stat_len = (lmi == LMI_CISCO) ? 6 : 3;
|
||||||
u8 *data;
|
u8 *data;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
if (hdlc->state.fr.settings.dce && fullrep) {
|
if (dce && fullrep) {
|
||||||
len += hdlc->state.fr.dce_pvc_count * (2 + stat_len);
|
len += hdlc->state.fr.dce_pvc_count * (2 + stat_len);
|
||||||
if (len > HDLC_MAX_MRU) {
|
if (len > HDLC_MAX_MRU) {
|
||||||
printk(KERN_WARNING "%s: Too many PVCs while sending "
|
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);
|
memset(skb->data, 0, len);
|
||||||
skb_reserve(skb, 4);
|
skb_reserve(skb, 4);
|
||||||
skb->protocol = __constant_htons(LMI_PROTO);
|
if (lmi == LMI_CISCO) {
|
||||||
fr_hard_header(&skb, LMI_DLCI);
|
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 = skb->tail;
|
||||||
data[i++] = LMI_CALLREF;
|
data[i++] = LMI_CALLREF;
|
||||||
data[i++] = hdlc->state.fr.settings.dce
|
data[i++] = dce ? LMI_STATUS : LMI_STATUS_ENQUIRY;
|
||||||
? LMI_STATUS : LMI_STATUS_ENQUIRY;
|
if (lmi == LMI_ANSI)
|
||||||
if (hdlc->state.fr.settings.lmi == LMI_ANSI)
|
|
||||||
data[i++] = LMI_ANSI_LOCKSHIFT;
|
data[i++] = LMI_ANSI_LOCKSHIFT;
|
||||||
data[i++] = (hdlc->state.fr.settings.lmi == LMI_CCITT)
|
data[i++] = lmi == LMI_CCITT ? LMI_CCITT_REPTYPE :
|
||||||
? LMI_CCITT_REPTYPE : LMI_REPTYPE;
|
LMI_ANSI_CISCO_REPTYPE;
|
||||||
data[i++] = LMI_REPT_LEN;
|
data[i++] = LMI_REPT_LEN;
|
||||||
data[i++] = fullrep ? LMI_FULLREP : LMI_INTEGRITY;
|
data[i++] = fullrep ? LMI_FULLREP : LMI_INTEGRITY;
|
||||||
|
data[i++] = lmi == LMI_CCITT ? LMI_CCITT_ALIVE : LMI_ANSI_CISCO_ALIVE;
|
||||||
data[i++] = (hdlc->state.fr.settings.lmi == LMI_CCITT)
|
|
||||||
? LMI_CCITT_ALIVE : LMI_ALIVE;
|
|
||||||
data[i++] = LMI_INTEG_LEN;
|
data[i++] = LMI_INTEG_LEN;
|
||||||
data[i++] = hdlc->state.fr.txseq =fr_lmi_nextseq(hdlc->state.fr.txseq);
|
data[i++] = hdlc->state.fr.txseq =fr_lmi_nextseq(hdlc->state.fr.txseq);
|
||||||
data[i++] = hdlc->state.fr.rxseq;
|
data[i++] = hdlc->state.fr.rxseq;
|
||||||
|
|
||||||
if (hdlc->state.fr.settings.dce && fullrep) {
|
if (dce && fullrep) {
|
||||||
while (pvc) {
|
while (pvc) {
|
||||||
data[i++] = (hdlc->state.fr.settings.lmi == LMI_CCITT)
|
data[i++] = lmi == LMI_CCITT ? LMI_CCITT_PVCSTAT :
|
||||||
? LMI_CCITT_PVCSTAT : LMI_PVCSTAT;
|
LMI_ANSI_CISCO_PVCSTAT;
|
||||||
data[i++] = stat_len;
|
data[i++] = stat_len;
|
||||||
|
|
||||||
/* LMI start/restart */
|
/* LMI start/restart */
|
||||||
|
@ -523,8 +509,20 @@ static void fr_lmi_send(struct net_device *dev, int fullrep)
|
||||||
fr_log_dlci_active(pvc);
|
fr_log_dlci_active(pvc);
|
||||||
}
|
}
|
||||||
|
|
||||||
dlci_to_status(pvc->dlci, data + i,
|
if (lmi == LMI_CISCO) {
|
||||||
pvc->state.active, pvc->state.new);
|
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;
|
i += stat_len;
|
||||||
pvc = pvc->next;
|
pvc = pvc->next;
|
||||||
}
|
}
|
||||||
|
@ -569,6 +567,8 @@ static void fr_set_link_state(int reliable, struct net_device *dev)
|
||||||
pvc_carrier(0, pvc);
|
pvc_carrier(0, pvc);
|
||||||
pvc->state.exist = pvc->state.active = 0;
|
pvc->state.exist = pvc->state.active = 0;
|
||||||
pvc->state.new = 0;
|
pvc->state.new = 0;
|
||||||
|
if (!hdlc->state.fr.settings.dce)
|
||||||
|
pvc->state.bandwidth = 0;
|
||||||
pvc = pvc->next;
|
pvc = pvc->next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -583,11 +583,12 @@ static void fr_timer(unsigned long arg)
|
||||||
int i, cnt = 0, reliable;
|
int i, cnt = 0, reliable;
|
||||||
u32 list;
|
u32 list;
|
||||||
|
|
||||||
if (hdlc->state.fr.settings.dce)
|
if (hdlc->state.fr.settings.dce) {
|
||||||
reliable = hdlc->state.fr.request &&
|
reliable = hdlc->state.fr.request &&
|
||||||
time_before(jiffies, hdlc->state.fr.last_poll +
|
time_before(jiffies, hdlc->state.fr.last_poll +
|
||||||
hdlc->state.fr.settings.t392 * HZ);
|
hdlc->state.fr.settings.t392 * HZ);
|
||||||
else {
|
hdlc->state.fr.request = 0;
|
||||||
|
} else {
|
||||||
hdlc->state.fr.last_errors <<= 1; /* Shift the list */
|
hdlc->state.fr.last_errors <<= 1; /* Shift the list */
|
||||||
if (hdlc->state.fr.request) {
|
if (hdlc->state.fr.request) {
|
||||||
if (hdlc->state.fr.reliable)
|
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)
|
static int fr_lmi_recv(struct net_device *dev, struct sk_buff *skb)
|
||||||
{
|
{
|
||||||
hdlc_device *hdlc = dev_to_hdlc(dev);
|
hdlc_device *hdlc = dev_to_hdlc(dev);
|
||||||
int stat_len;
|
|
||||||
pvc_device *pvc;
|
pvc_device *pvc;
|
||||||
int reptype = -1, error, no_ram;
|
|
||||||
u8 rxseq, txseq;
|
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)
|
if (skb->len < (lmi == LMI_ANSI ? LMI_ANSI_LENGTH :
|
||||||
? LMI_ANSI_LENGTH : LMI_LENGTH)) {
|
LMI_CCITT_CISCO_LENGTH)) {
|
||||||
printk(KERN_INFO "%s: Short LMI frame\n", dev->name);
|
printk(KERN_INFO "%s: Short LMI frame\n", dev->name);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (skb->data[5] != (!hdlc->state.fr.settings.dce ?
|
if (skb->data[3] != (lmi == LMI_CISCO ? NLPID_CISCO_LMI :
|
||||||
LMI_STATUS : LMI_STATUS_ENQUIRY)) {
|
NLPID_CCITT_ANSI_LMI)) {
|
||||||
printk(KERN_INFO "%s: LMI msgtype=%x, Not LMI status %s\n",
|
printk(KERN_INFO "%s: Received non-LMI frame with LMI"
|
||||||
dev->name, skb->data[2],
|
" DLCI\n", dev->name);
|
||||||
hdlc->state.fr.settings.dce ? "enquiry" : "reply");
|
|
||||||
return 1;
|
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] !=
|
if (skb->data[5] != (dce ? LMI_STATUS_ENQUIRY : LMI_STATUS)) {
|
||||||
((hdlc->state.fr.settings.lmi == LMI_CCITT)
|
printk(KERN_INFO "%s: Invalid LMI Message type (0x%02X)\n",
|
||||||
? LMI_CCITT_REPTYPE : LMI_REPTYPE)) {
|
dev->name, skb->data[5]);
|
||||||
printk(KERN_INFO "%s: Not a report type=%x\n",
|
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]);
|
dev->name, skb->data[i]);
|
||||||
return 1;
|
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]!=
|
if (skb->data[++i] != (lmi == LMI_CCITT ? LMI_CCITT_ALIVE :
|
||||||
((hdlc->state.fr.settings.lmi == LMI_CCITT)
|
LMI_ANSI_CISCO_ALIVE)) {
|
||||||
? LMI_CCITT_ALIVE : LMI_ALIVE)) {
|
printk(KERN_INFO "%s: Not an LMI Link integrity verification"
|
||||||
printk(KERN_INFO "%s: Unsupported status element=%x\n",
|
" IE (0x%02X)\n", dev->name, skb->data[i]);
|
||||||
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;
|
return 1;
|
||||||
}
|
}
|
||||||
i++;
|
i++;
|
||||||
|
|
||||||
i++; /* Skip length field */
|
|
||||||
|
|
||||||
hdlc->state.fr.rxseq = skb->data[i++]; /* TX sequence from peer */
|
hdlc->state.fr.rxseq = skb->data[i++]; /* TX sequence from peer */
|
||||||
rxseq = skb->data[i++]; /* Should confirm our sequence */
|
rxseq = skb->data[i++]; /* Should confirm our sequence */
|
||||||
|
|
||||||
txseq = hdlc->state.fr.txseq;
|
txseq = hdlc->state.fr.txseq;
|
||||||
|
|
||||||
if (hdlc->state.fr.settings.dce) {
|
if (dce)
|
||||||
if (reptype != LMI_FULLREP && reptype != LMI_INTEGRITY) {
|
|
||||||
printk(KERN_INFO "%s: Unsupported report type=%x\n",
|
|
||||||
dev->name, reptype);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
hdlc->state.fr.last_poll = jiffies;
|
hdlc->state.fr.last_poll = jiffies;
|
||||||
}
|
|
||||||
|
|
||||||
error = 0;
|
error = 0;
|
||||||
if (!hdlc->state.fr.reliable)
|
if (!hdlc->state.fr.reliable)
|
||||||
|
@ -703,7 +727,7 @@ static int fr_lmi_recv(struct net_device *dev, struct sk_buff *skb)
|
||||||
error = 1;
|
error = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hdlc->state.fr.settings.dce) {
|
if (dce) {
|
||||||
if (hdlc->state.fr.fullrep_sent && !error) {
|
if (hdlc->state.fr.fullrep_sent && !error) {
|
||||||
/* Stop sending full report - the last one has been confirmed by DTE */
|
/* Stop sending full report - the last one has been confirmed by DTE */
|
||||||
hdlc->state.fr.fullrep_sent = 0;
|
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.dce_changed = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hdlc->state.fr.request = 1; /* got request */
|
||||||
fr_lmi_send(dev, reptype == LMI_FULLREP ? 1 : 0);
|
fr_lmi_send(dev, reptype == LMI_FULLREP ? 1 : 0);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -739,7 +764,6 @@ static int fr_lmi_recv(struct net_device *dev, struct sk_buff *skb)
|
||||||
if (reptype != LMI_FULLREP)
|
if (reptype != LMI_FULLREP)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
stat_len = 3;
|
|
||||||
pvc = hdlc->state.fr.first_pvc;
|
pvc = hdlc->state.fr.first_pvc;
|
||||||
|
|
||||||
while (pvc) {
|
while (pvc) {
|
||||||
|
@ -750,24 +774,35 @@ static int fr_lmi_recv(struct net_device *dev, struct sk_buff *skb)
|
||||||
no_ram = 0;
|
no_ram = 0;
|
||||||
while (skb->len >= i + 2 + stat_len) {
|
while (skb->len >= i + 2 + stat_len) {
|
||||||
u16 dlci;
|
u16 dlci;
|
||||||
|
u32 bw;
|
||||||
unsigned int active, new;
|
unsigned int active, new;
|
||||||
|
|
||||||
if (skb->data[i] != ((hdlc->state.fr.settings.lmi == LMI_CCITT)
|
if (skb->data[i] != (lmi == LMI_CCITT ? LMI_CCITT_PVCSTAT :
|
||||||
? LMI_CCITT_PVCSTAT : LMI_PVCSTAT)) {
|
LMI_ANSI_CISCO_PVCSTAT)) {
|
||||||
printk(KERN_WARNING "%s: Invalid PVCSTAT ID: %x\n",
|
printk(KERN_INFO "%s: Not an LMI PVC status IE"
|
||||||
dev->name, skb->data[i]);
|
" (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;
|
return 1;
|
||||||
}
|
}
|
||||||
i++;
|
i++;
|
||||||
|
|
||||||
if (skb->data[i] != stat_len) {
|
new = !! (skb->data[i + 2] & 0x08);
|
||||||
printk(KERN_WARNING "%s: Invalid PVCSTAT length: %x\n",
|
active = !! (skb->data[i + 2] & 0x02);
|
||||||
dev->name, skb->data[i]);
|
if (lmi == LMI_CISCO) {
|
||||||
return 1;
|
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);
|
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;
|
pvc->state.deleted = 0;
|
||||||
if (active != pvc->state.active ||
|
if (active != pvc->state.active ||
|
||||||
new != pvc->state.new ||
|
new != pvc->state.new ||
|
||||||
|
bw != pvc->state.bandwidth ||
|
||||||
!pvc->state.exist) {
|
!pvc->state.exist) {
|
||||||
pvc->state.new = new;
|
pvc->state.new = new;
|
||||||
pvc->state.active = active;
|
pvc->state.active = active;
|
||||||
|
pvc->state.bandwidth = bw;
|
||||||
pvc_carrier(active, pvc);
|
pvc_carrier(active, pvc);
|
||||||
fr_log_dlci_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_carrier(0, pvc);
|
||||||
pvc->state.active = pvc->state.new = 0;
|
pvc->state.active = pvc->state.new = 0;
|
||||||
pvc->state.exist = 0;
|
pvc->state.exist = 0;
|
||||||
|
pvc->state.bandwidth = 0;
|
||||||
fr_log_dlci_active(pvc);
|
fr_log_dlci_active(pvc);
|
||||||
}
|
}
|
||||||
pvc = pvc->next;
|
pvc = pvc->next;
|
||||||
|
@ -829,22 +867,15 @@ static int fr_rx(struct sk_buff *skb)
|
||||||
|
|
||||||
dlci = q922_to_dlci(skb->data);
|
dlci = q922_to_dlci(skb->data);
|
||||||
|
|
||||||
if (dlci == LMI_DLCI) {
|
if ((dlci == LMI_CCITT_ANSI_DLCI &&
|
||||||
if (hdlc->state.fr.settings.lmi == LMI_NONE)
|
(hdlc->state.fr.settings.lmi == LMI_ANSI ||
|
||||||
goto rx_error; /* LMI packet with no LMI? */
|
hdlc->state.fr.settings.lmi == LMI_CCITT)) ||
|
||||||
|
(dlci == LMI_CISCO_DLCI &&
|
||||||
if (data[3] == LMI_PROTO) {
|
hdlc->state.fr.settings.lmi == LMI_CISCO)) {
|
||||||
if (fr_lmi_recv(ndev, skb))
|
if (fr_lmi_recv(ndev, skb))
|
||||||
goto rx_error;
|
goto rx_error;
|
||||||
else {
|
dev_kfree_skb_any(skb);
|
||||||
dev_kfree_skb_any(skb);
|
return NET_RX_SUCCESS;
|
||||||
return NET_RX_SUCCESS;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
printk(KERN_INFO "%s: Received non-LMI frame with LMI DLCI\n",
|
|
||||||
ndev->name);
|
|
||||||
goto rx_error;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pvc = find_pvc(hdlc, dlci);
|
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 &&
|
if ((new_settings.lmi != LMI_NONE &&
|
||||||
new_settings.lmi != LMI_ANSI &&
|
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.t391 < 1 ||
|
||||||
new_settings.t392 < 2 ||
|
new_settings.t392 < 2 ||
|
||||||
new_settings.n391 < 1 ||
|
new_settings.n391 < 1 ||
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* Generic HDLC support routines for Linux
|
* 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
|
* 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
|
* under the terms of version 2 of the GNU General Public License
|
||||||
|
@ -38,7 +38,7 @@
|
||||||
#include <linux/hdlc.h>
|
#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
|
#undef DEBUG_LINK
|
||||||
|
|
||||||
|
@ -126,10 +126,13 @@ void hdlc_set_carrier(int on, struct net_device *dev)
|
||||||
if (!hdlc->open)
|
if (!hdlc->open)
|
||||||
goto carrier_exit;
|
goto carrier_exit;
|
||||||
|
|
||||||
if (hdlc->carrier)
|
if (hdlc->carrier) {
|
||||||
|
printk(KERN_INFO "%s: Carrier detected\n", dev->name);
|
||||||
__hdlc_set_carrier_on(dev);
|
__hdlc_set_carrier_on(dev);
|
||||||
else
|
} else {
|
||||||
|
printk(KERN_INFO "%s: Carrier lost\n", dev->name);
|
||||||
__hdlc_set_carrier_off(dev);
|
__hdlc_set_carrier_off(dev);
|
||||||
|
}
|
||||||
|
|
||||||
carrier_exit:
|
carrier_exit:
|
||||||
spin_unlock_irqrestore(&hdlc->state_lock, flags);
|
spin_unlock_irqrestore(&hdlc->state_lock, flags);
|
||||||
|
@ -157,8 +160,11 @@ int hdlc_open(struct net_device *dev)
|
||||||
|
|
||||||
spin_lock_irq(&hdlc->state_lock);
|
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);
|
__hdlc_set_carrier_on(dev);
|
||||||
|
} else
|
||||||
|
printk(KERN_INFO "%s: No carrier\n", dev->name);
|
||||||
|
|
||||||
hdlc->open = 1;
|
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 */
|
/* lmc_reset (sc); Why reset??? The link can go down ok */
|
||||||
|
|
||||||
/* Inform the world that link has been lost */
|
/* 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??? */
|
/* lmc_reset (sc); Again why reset??? */
|
||||||
|
|
||||||
/* Inform the world that link protocol is back up. */
|
/* 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
|
/* Now we have to tell the syncppp that we had an outage
|
||||||
* and that it should deal. Calling sppp_reopen here
|
* 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_link_status (sc, 1);
|
||||||
sc->lmc_media->set_status (sc, NULL);
|
sc->lmc_media->set_status (sc, NULL);
|
||||||
|
|
||||||
//dev->flags |= IFF_RUNNING;
|
|
||||||
|
|
||||||
netif_wake_queue(dev);
|
netif_wake_queue(dev);
|
||||||
|
|
||||||
sc->lmc_txfull = 0;
|
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 */
|
csr6 &= ~LMC_DEC_SR; /* Turn off the Receive bit */
|
||||||
LMC_CSR_WRITE (sc, csr_command, csr6);
|
LMC_CSR_WRITE (sc, csr_command, csr6);
|
||||||
|
|
||||||
dev->flags &= ~IFF_RUNNING;
|
|
||||||
|
|
||||||
sc->stats.rx_missed_errors +=
|
sc->stats.rx_missed_errors +=
|
||||||
LMC_CSR_READ (sc, csr_missed_frames) & 0xffff;
|
LMC_CSR_READ (sc, csr_missed_frames) & 0xffff;
|
||||||
|
|
||||||
|
|
|
@ -492,6 +492,9 @@ EXPORT_SYMBOL(orinoco_debug);
|
||||||
static int suppress_linkstatus; /* = 0 */
|
static int suppress_linkstatus; /* = 0 */
|
||||||
module_param(suppress_linkstatus, bool, 0644);
|
module_param(suppress_linkstatus, bool, 0644);
|
||||||
MODULE_PARM_DESC(suppress_linkstatus, "Don't log link status changes");
|
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 */
|
/* 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_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
|
||||||
static int __orinoco_program_rids(struct net_device *dev);
|
static int __orinoco_program_rids(struct net_device *dev);
|
||||||
static void __orinoco_set_multicast_list(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 */
|
/* Internal helper functions */
|
||||||
|
@ -655,7 +657,7 @@ static int orinoco_open(struct net_device *dev)
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
int orinoco_stop(struct net_device *dev)
|
static int orinoco_stop(struct net_device *dev)
|
||||||
{
|
{
|
||||||
struct orinoco_private *priv = netdev_priv(dev);
|
struct orinoco_private *priv = netdev_priv(dev);
|
||||||
int err = 0;
|
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);
|
struct orinoco_private *priv = netdev_priv(dev);
|
||||||
hermes_t *hw = &priv->hw;
|
hermes_t *hw = &priv->hw;
|
||||||
struct iw_statistics *wstats = &priv->wstats;
|
struct iw_statistics *wstats = &priv->wstats;
|
||||||
int err = 0;
|
int err;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
if (! netif_device_present(dev)) {
|
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? */
|
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)
|
if (orinoco_lock(priv, &flags) != 0)
|
||||||
return NULL; /* FIXME: Erg, we've been signalled, how
|
return wstats;
|
||||||
* do we propagate this back up? */
|
|
||||||
|
/* 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) {
|
if (priv->iw_mode == IW_MODE_ADHOC) {
|
||||||
memset(&wstats->qual, 0, sizeof(wstats->qual));
|
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,
|
err = HERMES_READ_RECORD(hw, USER_BAP,
|
||||||
HERMES_RID_COMMSQUALITY, &cq);
|
HERMES_RID_COMMSQUALITY, &cq);
|
||||||
|
|
||||||
wstats->qual.qual = (int)le16_to_cpu(cq.qual);
|
if (!err) {
|
||||||
wstats->qual.level = (int)le16_to_cpu(cq.signal) - 0x95;
|
wstats->qual.qual = (int)le16_to_cpu(cq.qual);
|
||||||
wstats->qual.noise = (int)le16_to_cpu(cq.noise) - 0x95;
|
wstats->qual.level = (int)le16_to_cpu(cq.signal) - 0x95;
|
||||||
wstats->qual.updated = 7;
|
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);
|
orinoco_unlock(priv, &flags);
|
||||||
|
|
||||||
if (err)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
return wstats;
|
return wstats;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1275,9 +1280,10 @@ static void __orinoco_ev_info(struct net_device *dev, hermes_t *hw)
|
||||||
len = sizeof(tallies);
|
len = sizeof(tallies);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Read directly the data (no seek) */
|
err = hermes_bap_pread(hw, IRQ_BAP, &tallies, len,
|
||||||
hermes_read_words(hw, HERMES_DATA1, (void *) &tallies,
|
infofid, sizeof(info));
|
||||||
len / 2); /* FIXME: blech! */
|
if (err)
|
||||||
|
break;
|
||||||
|
|
||||||
/* Increment our various counters */
|
/* Increment our various counters */
|
||||||
/* wstats->discard.nwid - no wrong BSSID stuff */
|
/* wstats->discard.nwid - no wrong BSSID stuff */
|
||||||
|
@ -1307,8 +1313,10 @@ static void __orinoco_ev_info(struct net_device *dev, hermes_t *hw)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
hermes_read_words(hw, HERMES_DATA1, (void *) &linkstatus,
|
err = hermes_bap_pread(hw, IRQ_BAP, &linkstatus, len,
|
||||||
len / 2);
|
infofid, sizeof(info));
|
||||||
|
if (err)
|
||||||
|
break;
|
||||||
newstatus = le16_to_cpu(linkstatus.linkstatus);
|
newstatus = le16_to_cpu(linkstatus.linkstatus);
|
||||||
|
|
||||||
connected = (newstatus == HERMES_LINKSTATUS_CONNECTED)
|
connected = (newstatus == HERMES_LINKSTATUS_CONNECTED)
|
||||||
|
@ -1317,7 +1325,7 @@ static void __orinoco_ev_info(struct net_device *dev, hermes_t *hw)
|
||||||
|
|
||||||
if (connected)
|
if (connected)
|
||||||
netif_carrier_on(dev);
|
netif_carrier_on(dev);
|
||||||
else
|
else if (!ignore_disconnect)
|
||||||
netif_carrier_off(dev);
|
netif_carrier_off(dev);
|
||||||
|
|
||||||
if (newstatus != priv->last_linkstatus)
|
if (newstatus != priv->last_linkstatus)
|
||||||
|
@ -1350,6 +1358,8 @@ int __orinoco_up(struct net_device *dev)
|
||||||
struct hermes *hw = &priv->hw;
|
struct hermes *hw = &priv->hw;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
|
netif_carrier_off(dev); /* just to make sure */
|
||||||
|
|
||||||
err = __orinoco_program_rids(dev);
|
err = __orinoco_program_rids(dev);
|
||||||
if (err) {
|
if (err) {
|
||||||
printk(KERN_ERR "%s: Error %d configuring card\n",
|
printk(KERN_ERR "%s: Error %d configuring card\n",
|
||||||
|
@ -1413,7 +1423,7 @@ int orinoco_reinit_firmware(struct net_device *dev)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
err = hermes_allocate(hw, priv->nicbuf_size, &priv->txfid);
|
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 */
|
/* Try workaround for old Symbol firmware bug */
|
||||||
printk(KERN_WARNING "%s: firmware ALLOC bug detected "
|
printk(KERN_WARNING "%s: firmware ALLOC bug detected "
|
||||||
"(old Symbol firmware?). Trying to work around... ",
|
"(old Symbol firmware?). Trying to work around... ",
|
||||||
|
@ -1610,17 +1620,15 @@ static int __orinoco_program_rids(struct net_device *dev)
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
/* Set the channel/frequency */
|
/* Set the channel/frequency */
|
||||||
if (priv->channel == 0) {
|
if (priv->channel != 0 && priv->iw_mode != IW_MODE_INFRA) {
|
||||||
printk(KERN_DEBUG "%s: Channel is 0 in __orinoco_program_rids()\n", dev->name);
|
err = hermes_write_wordrec(hw, USER_BAP,
|
||||||
if (priv->createibss)
|
HERMES_RID_CNFOWNCHANNEL,
|
||||||
priv->channel = 10;
|
priv->channel);
|
||||||
}
|
if (err) {
|
||||||
err = hermes_write_wordrec(hw, USER_BAP, HERMES_RID_CNFOWNCHANNEL,
|
printk(KERN_ERR "%s: Error %d setting channel %d\n",
|
||||||
priv->channel);
|
dev->name, err, priv->channel);
|
||||||
if (err) {
|
return err;
|
||||||
printk(KERN_ERR "%s: Error %d setting channel\n",
|
}
|
||||||
dev->name, err);
|
|
||||||
return err;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (priv->has_ibss) {
|
if (priv->has_ibss) {
|
||||||
|
@ -1916,7 +1924,7 @@ static void orinoco_reset(struct net_device *dev)
|
||||||
{
|
{
|
||||||
struct orinoco_private *priv = netdev_priv(dev);
|
struct orinoco_private *priv = netdev_priv(dev);
|
||||||
struct hermes *hw = &priv->hw;
|
struct hermes *hw = &priv->hw;
|
||||||
int err = 0;
|
int err;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
if (orinoco_lock(priv, &flags) != 0)
|
if (orinoco_lock(priv, &flags) != 0)
|
||||||
|
@ -1938,20 +1946,20 @@ static void orinoco_reset(struct net_device *dev)
|
||||||
|
|
||||||
orinoco_unlock(priv, &flags);
|
orinoco_unlock(priv, &flags);
|
||||||
|
|
||||||
if (priv->hard_reset)
|
if (priv->hard_reset) {
|
||||||
err = (*priv->hard_reset)(priv);
|
err = (*priv->hard_reset)(priv);
|
||||||
if (err) {
|
if (err) {
|
||||||
printk(KERN_ERR "%s: orinoco_reset: Error %d "
|
printk(KERN_ERR "%s: orinoco_reset: Error %d "
|
||||||
"performing hard reset\n", dev->name, err);
|
"performing hard reset\n", dev->name, err);
|
||||||
/* FIXME: shutdown of some sort */
|
goto disable;
|
||||||
return;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
err = orinoco_reinit_firmware(dev);
|
err = orinoco_reinit_firmware(dev);
|
||||||
if (err) {
|
if (err) {
|
||||||
printk(KERN_ERR "%s: orinoco_reset: Error %d re-initializing firmware\n",
|
printk(KERN_ERR "%s: orinoco_reset: Error %d re-initializing firmware\n",
|
||||||
dev->name, err);
|
dev->name, err);
|
||||||
return;
|
goto disable;
|
||||||
}
|
}
|
||||||
|
|
||||||
spin_lock_irq(&priv->lock); /* This has to be called from user context */
|
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);
|
spin_unlock_irq(&priv->lock);
|
||||||
|
|
||||||
return;
|
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)
|
if (events & HERMES_EV_ALLOC)
|
||||||
__orinoco_ev_alloc(dev, hw);
|
__orinoco_ev_alloc(dev, hw);
|
||||||
|
|
||||||
hermes_write_regn(hw, EVACK, events);
|
hermes_write_regn(hw, EVACK, evstat);
|
||||||
|
|
||||||
evstat = hermes_read_regn(hw, EVSTAT);
|
evstat = hermes_read_regn(hw, EVSTAT);
|
||||||
events = evstat & hw->inten;
|
events = evstat & hw->inten;
|
||||||
|
@ -2215,6 +2227,8 @@ static int determine_firmware(struct net_device *dev)
|
||||||
firmver >= 0x31000;
|
firmver >= 0x31000;
|
||||||
priv->has_preamble = (firmver >= 0x20000);
|
priv->has_preamble = (firmver >= 0x20000);
|
||||||
priv->ibss_port = 4;
|
priv->ibss_port = 4;
|
||||||
|
priv->broken_disableport = (firmver == 0x25013) ||
|
||||||
|
(firmver >= 0x30000 && firmver <= 0x31000);
|
||||||
/* Tested with Intel firmware : 0x20015 => Jean II */
|
/* Tested with Intel firmware : 0x20015 => Jean II */
|
||||||
/* Tested with 3Com firmware : 0x15012 & 0x22001 => Jean II */
|
/* Tested with 3Com firmware : 0x15012 & 0x22001 => Jean II */
|
||||||
break;
|
break;
|
||||||
|
@ -2267,7 +2281,7 @@ static int orinoco_init(struct net_device *dev)
|
||||||
priv->nicbuf_size = IEEE802_11_FRAME_LEN + ETH_HLEN;
|
priv->nicbuf_size = IEEE802_11_FRAME_LEN + ETH_HLEN;
|
||||||
|
|
||||||
/* Initialize the firmware */
|
/* Initialize the firmware */
|
||||||
err = hermes_init(hw);
|
err = orinoco_reinit_firmware(dev);
|
||||||
if (err != 0) {
|
if (err != 0) {
|
||||||
printk(KERN_ERR "%s: failed to initialize firmware (err = %d)\n",
|
printk(KERN_ERR "%s: failed to initialize firmware (err = %d)\n",
|
||||||
dev->name, err);
|
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 */
|
/* By default use IEEE/IBSS ad-hoc mode if we have it */
|
||||||
priv->prefer_port3 = priv->has_port3 && (! priv->has_ibss);
|
priv->prefer_port3 = priv->has_port3 && (! priv->has_ibss);
|
||||||
set_port_type(priv);
|
set_port_type(priv);
|
||||||
priv->channel = 10; /* default channel, more-or-less arbitrary */
|
priv->channel = 0; /* use firmware default */
|
||||||
|
|
||||||
priv->promiscuous = 0;
|
priv->promiscuous = 0;
|
||||||
priv->wep_on = 0;
|
priv->wep_on = 0;
|
||||||
priv->tx_key = 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
|
/* Make the hardware available, as long as it hasn't been
|
||||||
* removed elsewhere (e.g. by PCMCIA hot unplug) */
|
* removed elsewhere (e.g. by PCMCIA hot unplug) */
|
||||||
spin_lock_irq(&priv->lock);
|
spin_lock_irq(&priv->lock);
|
||||||
|
@ -2450,7 +2445,7 @@ struct net_device *alloc_orinocodev(int sizeof_card,
|
||||||
priv = netdev_priv(dev);
|
priv = netdev_priv(dev);
|
||||||
priv->ndev = dev;
|
priv->ndev = dev;
|
||||||
if (sizeof_card)
|
if (sizeof_card)
|
||||||
priv->card = (void *)((unsigned long)netdev_priv(dev)
|
priv->card = (void *)((unsigned long)priv
|
||||||
+ sizeof(struct orinoco_private));
|
+ sizeof(struct orinoco_private));
|
||||||
else
|
else
|
||||||
priv->card = NULL;
|
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);
|
len = le16_to_cpu(essidbuf.len);
|
||||||
|
BUG_ON(len > IW_ESSID_MAX_SIZE);
|
||||||
|
|
||||||
memset(buf, 0, IW_ESSID_MAX_SIZE+1);
|
memset(buf, 0, IW_ESSID_MAX_SIZE+1);
|
||||||
memcpy(buf, p, len);
|
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));
|
memset(&essidbuf, 0, sizeof(essidbuf));
|
||||||
|
|
||||||
if (erq->flags) {
|
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;
|
return -E2BIG;
|
||||||
|
|
||||||
if (copy_from_user(&essidbuf, erq->pointer, erq->length))
|
if (copy_from_user(&essidbuf, erq->pointer, erq->length))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
|
|
||||||
essidbuf[erq->length] = '\0';
|
essidbuf[IW_ESSID_MAX_SIZE] = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (orinoco_lock(priv, &flags) != 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,
|
{ SIOCIWFIRSTPRIV + 0x7, 0,
|
||||||
IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
|
IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
|
||||||
"get_ibssport" },
|
"get_ibssport" },
|
||||||
{ SIOCIWLASTPRIV, 0, 0, "dump_recs" },
|
|
||||||
};
|
};
|
||||||
|
|
||||||
wrq->u.data.length = sizeof(privtab) / sizeof(privtab[0]);
|
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);
|
err = orinoco_ioctl_getibssport(dev, wrq);
|
||||||
break;
|
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:
|
default:
|
||||||
err = -EOPNOTSUPP;
|
err = -EOPNOTSUPP;
|
||||||
}
|
}
|
||||||
|
@ -3964,187 +3952,6 @@ orinoco_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
|
||||||
return err;
|
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 */
|
/* Debugging */
|
||||||
|
@ -4218,7 +4025,6 @@ EXPORT_SYMBOL(free_orinocodev);
|
||||||
|
|
||||||
EXPORT_SYMBOL(__orinoco_up);
|
EXPORT_SYMBOL(__orinoco_up);
|
||||||
EXPORT_SYMBOL(__orinoco_down);
|
EXPORT_SYMBOL(__orinoco_down);
|
||||||
EXPORT_SYMBOL(orinoco_stop);
|
|
||||||
EXPORT_SYMBOL(orinoco_reinit_firmware);
|
EXPORT_SYMBOL(orinoco_reinit_firmware);
|
||||||
|
|
||||||
EXPORT_SYMBOL(orinoco_interrupt);
|
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 void free_orinocodev(struct net_device *dev);
|
||||||
extern int __orinoco_up(struct net_device *dev);
|
extern int __orinoco_up(struct net_device *dev);
|
||||||
extern int __orinoco_down(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 int orinoco_reinit_firmware(struct net_device *dev);
|
||||||
extern irqreturn_t orinoco_interrupt(int irq, void * dev_id, struct pt_regs *regs);
|
extern irqreturn_t orinoco_interrupt(int irq, void * dev_id, struct pt_regs *regs);
|
||||||
|
|
||||||
|
|
36
include/linux/dm9000.h
Normal file
36
include/linux/dm9000.h
Normal file
|
@ -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
|
* 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
|
* 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
|
* 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_NONE 1 /* No LMI, all PVCs are static */
|
||||||
#define LMI_ANSI 2 /* ANSI Annex D */
|
#define LMI_ANSI 2 /* ANSI Annex D */
|
||||||
#define LMI_CCITT 3 /* ITU-T Annex A */
|
#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_MTU 1500 /* Ethernet 1500 bytes */
|
||||||
#define HDLC_MAX_MRU (HDLC_MAX_MTU + 10 + 14 + 4) /* for ETH+VLAN over FR */
|
#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 deleted: 1;
|
||||||
unsigned int fecn: 1;
|
unsigned int fecn: 1;
|
||||||
unsigned int becn: 1;
|
unsigned int becn: 1;
|
||||||
|
unsigned int bandwidth; /* Cisco LMI reporting only */
|
||||||
}state;
|
}state;
|
||||||
}pvc_device;
|
}pvc_device;
|
||||||
|
|
||||||
|
|
|
@ -33,7 +33,7 @@
|
||||||
#define IFF_LOOPBACK 0x8 /* is a loopback net */
|
#define IFF_LOOPBACK 0x8 /* is a loopback net */
|
||||||
#define IFF_POINTOPOINT 0x10 /* interface is has p-p link */
|
#define IFF_POINTOPOINT 0x10 /* interface is has p-p link */
|
||||||
#define IFF_NOTRAILERS 0x20 /* avoid use of trailers */
|
#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_NOARP 0x80 /* no ARP protocol */
|
||||||
#define IFF_PROMISC 0x100 /* receive all packets */
|
#define IFF_PROMISC 0x100 /* receive all packets */
|
||||||
#define IFF_ALLMULTI 0x200 /* receive all multicast packets*/
|
#define IFF_ALLMULTI 0x200 /* receive all multicast packets*/
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
/*
|
/*
|
||||||
* This file define a set of standard wireless extensions
|
* 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>
|
* 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
|
#ifndef _LINUX_WIRELESS_H
|
||||||
|
@ -82,7 +82,7 @@
|
||||||
* (there is some stuff that will be added in the future...)
|
* (there is some stuff that will be added in the future...)
|
||||||
* I just plan to increment with each new version.
|
* I just plan to increment with each new version.
|
||||||
*/
|
*/
|
||||||
#define WIRELESS_EXT 17
|
#define WIRELESS_EXT 18
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Changes :
|
* Changes :
|
||||||
|
@ -182,6 +182,21 @@
|
||||||
* - Document (struct iw_quality *)->updated, add new flags (INVALID)
|
* - Document (struct iw_quality *)->updated, add new flags (INVALID)
|
||||||
* - Wireless Event capability in struct iw_range
|
* - Wireless Event capability in struct iw_range
|
||||||
* - Add support for relative TxPower (yick !)
|
* - 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 ****************************/
|
/**************************** CONSTANTS ****************************/
|
||||||
|
@ -256,6 +271,30 @@
|
||||||
#define SIOCSIWPOWER 0x8B2C /* set Power Management settings */
|
#define SIOCSIWPOWER 0x8B2C /* set Power Management settings */
|
||||||
#define SIOCGIWPOWER 0x8B2D /* get 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 -------------------- */
|
/* -------------------- DEV PRIVATE IOCTL LIST -------------------- */
|
||||||
|
|
||||||
/* These 32 ioctl are wireless device private, for 16 commands.
|
/* These 32 ioctl are wireless device private, for 16 commands.
|
||||||
|
@ -297,6 +336,34 @@
|
||||||
#define IWEVCUSTOM 0x8C02 /* Driver specific ascii string */
|
#define IWEVCUSTOM 0x8C02 /* Driver specific ascii string */
|
||||||
#define IWEVREGISTERED 0x8C03 /* Discovered a new node (AP mode) */
|
#define IWEVREGISTERED 0x8C03 /* Discovered a new node (AP mode) */
|
||||||
#define IWEVEXPIRED 0x8C04 /* Expired a 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
|
#define IWEVFIRST 0x8C00
|
||||||
|
|
||||||
|
@ -432,12 +499,94 @@
|
||||||
#define IW_SCAN_THIS_MODE 0x0020 /* Scan only this Mode */
|
#define IW_SCAN_THIS_MODE 0x0020 /* Scan only this Mode */
|
||||||
#define IW_SCAN_ALL_RATE 0x0040 /* Scan all Bit-Rates */
|
#define IW_SCAN_ALL_RATE 0x0040 /* Scan all Bit-Rates */
|
||||||
#define IW_SCAN_THIS_RATE 0x0080 /* Scan only this Bit-Rate */
|
#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 */
|
/* Maximum size of returned data */
|
||||||
#define IW_SCAN_MAX_DATA 4096 /* In bytes */
|
#define IW_SCAN_MAX_DATA 4096 /* In bytes */
|
||||||
|
|
||||||
/* Max number of char in custom event - use multiple of them if needed */
|
/* Max number of char in custom event - use multiple of them if needed */
|
||||||
#define IW_CUSTOM_MAX 256 /* In bytes */
|
#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
|
/* Event capability macros - in (struct iw_range *)->event_capa
|
||||||
* Because we have more than 32 possible events, we use an array of
|
* Because we have more than 32 possible events, we use an array of
|
||||||
* 32 bit bitmasks. Note : 32 bits = 0x20 = 2^5. */
|
* 32 bit bitmasks. Note : 32 bits = 0x20 = 2^5. */
|
||||||
|
@ -546,6 +695,132 @@ struct iw_thrspy
|
||||||
struct iw_quality high; /* High threshold */
|
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 STATS ------------------------ */
|
||||||
/*
|
/*
|
||||||
* Wireless statistics (used for /proc/net/wireless)
|
* Wireless statistics (used for /proc/net/wireless)
|
||||||
|
@ -725,6 +1000,8 @@ struct iw_range
|
||||||
struct iw_freq freq[IW_MAX_FREQUENCIES]; /* list */
|
struct iw_freq freq[IW_MAX_FREQUENCIES]; /* list */
|
||||||
/* Note : this frequency list doesn't need to fit channel numbers,
|
/* Note : this frequency list doesn't need to fit channel numbers,
|
||||||
* because each entry contain its channel index */
|
* 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.
|
* This file implement the Wireless Extensions APIs.
|
||||||
*
|
*
|
||||||
* Authors : Jean Tourrilhes - HPL - <jt@hpl.hp.com>
|
* 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)
|
* (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,
|
.header_type = IW_HEADER_TYPE_ADDR,
|
||||||
.flags = IW_DESCR_FLAG_DUMP,
|
.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] = {
|
[SIOCGIWAPLIST - SIOCIWFIRST] = {
|
||||||
.header_type = IW_HEADER_TYPE_POINT,
|
.header_type = IW_HEADER_TYPE_POINT,
|
||||||
.token_size = sizeof(struct sockaddr) +
|
.token_size = sizeof(struct sockaddr) +
|
||||||
|
@ -195,7 +201,10 @@ static const struct iw_ioctl_description standard_ioctl[] = {
|
||||||
.flags = IW_DESCR_FLAG_NOMAX,
|
.flags = IW_DESCR_FLAG_NOMAX,
|
||||||
},
|
},
|
||||||
[SIOCSIWSCAN - SIOCIWFIRST] = {
|
[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] = {
|
[SIOCGIWSCAN - SIOCIWFIRST] = {
|
||||||
.header_type = IW_HEADER_TYPE_POINT,
|
.header_type = IW_HEADER_TYPE_POINT,
|
||||||
|
@ -273,6 +282,42 @@ static const struct iw_ioctl_description standard_ioctl[] = {
|
||||||
[SIOCGIWPOWER - SIOCIWFIRST] = {
|
[SIOCGIWPOWER - SIOCIWFIRST] = {
|
||||||
.header_type = IW_HEADER_TYPE_PARAM,
|
.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) /
|
static const int standard_ioctl_num = (sizeof(standard_ioctl) /
|
||||||
sizeof(struct iw_ioctl_description));
|
sizeof(struct iw_ioctl_description));
|
||||||
|
@ -299,6 +344,31 @@ static const struct iw_ioctl_description standard_event[] = {
|
||||||
[IWEVEXPIRED - IWEVFIRST] = {
|
[IWEVEXPIRED - IWEVFIRST] = {
|
||||||
.header_type = IW_HEADER_TYPE_ADDR,
|
.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) /
|
static const int standard_event_num = (sizeof(standard_event) /
|
||||||
sizeof(struct iw_ioctl_description));
|
sizeof(struct iw_ioctl_description));
|
||||||
|
|
Loading…
Add table
Reference in a new issue