Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
8d139952
Commit
8d139952
authored
Sep 18, 2002
by
Jeff Garzik
Browse files
Options
Browse Files
Download
Plain Diff
Merge
http://suncobalt.bkbits.net/net-drivers-2.5
into mandrakesoft.com:/home/jgarzik/repo/net-drivers-2.5
parents
05fd0be9
91f6fbd1
Changes
3
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
288 additions
and
212 deletions
+288
-212
drivers/net/Config.help
drivers/net/Config.help
+0
-11
drivers/net/Config.in
drivers/net/Config.in
+0
-3
drivers/net/natsemi.c
drivers/net/natsemi.c
+288
-198
No files found.
drivers/net/Config.help
View file @
8d139952
...
@@ -1226,17 +1226,6 @@ CONFIG_NATSEMI
...
@@ -1226,17 +1226,6 @@ CONFIG_NATSEMI
More specific information and updates are available from
More specific information and updates are available from
<http://www.scyld.com/network/natsemi.html>.
<http://www.scyld.com/network/natsemi.html>.
CONFIG_NATSEMI_CABLE_MAGIC
Some systems see lots of errors with NatSemi ethernet controllers
on certain cables. If you are seeing lots of errors, try turning
this option on. Some boards have incorrect values for supporting
resistors that can cause this change to break. If you turn this
option on and your network suddenly stops working, turn this
option off.
Say N unless you are certain you need this option.
Vendors should not enable this option by default.
CONFIG_SK_G16
CONFIG_SK_G16
If you have a network (Ethernet) card of this type, say Y and read
If you have a network (Ethernet) card of this type, say Y and read
the Ethernet-HOWTO, available from
the Ethernet-HOWTO, available from
...
...
drivers/net/Config.in
View file @
8d139952
...
@@ -165,9 +165,6 @@ if [ "$CONFIG_NET_ETHERNET" = "y" ]; then
...
@@ -165,9 +165,6 @@ if [ "$CONFIG_NET_ETHERNET" = "y" ]; then
dep_tristate ' Mylex EISA LNE390A/B support (EXPERIMENTAL)' CONFIG_LNE390 $CONFIG_EISA $CONFIG_EXPERIMENTAL
dep_tristate ' Mylex EISA LNE390A/B support (EXPERIMENTAL)' CONFIG_LNE390 $CONFIG_EISA $CONFIG_EXPERIMENTAL
dep_tristate ' Myson MTD-8xx PCI Ethernet support' CONFIG_FEALNX $CONFIG_PCI
dep_tristate ' Myson MTD-8xx PCI Ethernet support' CONFIG_FEALNX $CONFIG_PCI
dep_tristate ' National Semiconductor DP8381x series PCI Ethernet support' CONFIG_NATSEMI $CONFIG_PCI
dep_tristate ' National Semiconductor DP8381x series PCI Ethernet support' CONFIG_NATSEMI $CONFIG_PCI
if [ "$CONFIG_NATSEMI" = "y" -o "$CONFIG_NATSEMI" = "m" ]; then
bool ' NatSemi workaround for high errors' CONFIG_NATSEMI_CABLE_MAGIC
fi
dep_tristate ' PCI NE2000 and clones support (see help)' CONFIG_NE2K_PCI $CONFIG_PCI
dep_tristate ' PCI NE2000 and clones support (see help)' CONFIG_NE2K_PCI $CONFIG_PCI
dep_tristate ' Novell/Eagle/Microdyne NE3210 EISA support (EXPERIMENTAL)' CONFIG_NE3210 $CONFIG_EISA $CONFIG_EXPERIMENTAL
dep_tristate ' Novell/Eagle/Microdyne NE3210 EISA support (EXPERIMENTAL)' CONFIG_NE3210 $CONFIG_EISA $CONFIG_EXPERIMENTAL
dep_tristate ' Racal-Interlan EISA ES3210 support (EXPERIMENTAL)' CONFIG_ES3210 $CONFIG_EISA $CONFIG_EXPERIMENTAL
dep_tristate ' Racal-Interlan EISA ES3210 support (EXPERIMENTAL)' CONFIG_ES3210 $CONFIG_EISA $CONFIG_EXPERIMENTAL
...
...
drivers/net/natsemi.c
View file @
8d139952
...
@@ -100,20 +100,65 @@
...
@@ -100,20 +100,65 @@
* ETHTOOL_* further support (Tim Hockin)
* ETHTOOL_* further support (Tim Hockin)
version 1.0.13:
version 1.0.13:
* ETHTOOL_[G
S
]EEPROM support (Tim Hockin)
* ETHTOOL_[G]EEPROM support (Tim Hockin)
version 1.0.13:
version 1.0.13:
* crc cleanup (Matt Domsch <Matt_Domsch@dell.com>)
* crc cleanup (Matt Domsch <Matt_Domsch@dell.com>)
version 1.0.14:
* Cleanup some messages and autoneg in ethtool (Tim Hockin)
version 1.0.15:
* Get rid of cable_magic flag
* use new (National provided) solution for cable magic issue
version 1.0.16:
* call netdev_rx() for RxErrors (Manfred Spraul)
* formatting and cleanups
* change options and full_duplex arrays to be zero
initialized
* enable only the WoL and PHY interrupts in wol mode
TODO:
TODO:
* big endian support with CFG:BEM instead of cpu_to_le32
* big endian support with CFG:BEM instead of cpu_to_le32
* support for an external PHY
* support for an external PHY
* flow control
* flow control
*/
*/
#if !defined(__OPTIMIZE__)
#warning You must compile this file with the correct options!
#warning See the last lines of the source file.
#error You must compile this driver with "-O".
#endif
#include <linux/config.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/timer.h>
#include <linux/errno.h>
#include <linux/ioport.h>
#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/pci.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/skbuff.h>
#include <linux/init.h>
#include <linux/spinlock.h>
#include <linux/ethtool.h>
#include <linux/delay.h>
#include <linux/rtnetlink.h>
#include <linux/mii.h>
#include <asm/processor.h>
/* Processor type for cache alignment. */
#include <asm/bitops.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/uaccess.h>
#define DRV_NAME "natsemi"
#define DRV_NAME "natsemi"
#define DRV_VERSION "1.07+LK1.0.1
3
"
#define DRV_VERSION "1.07+LK1.0.1
6
"
#define DRV_RELDATE "
Nov 12, 2001
"
#define DRV_RELDATE "
Aug 28, 2002
"
/* Updated to recommendations in pci-skeleton v2.03. */
/* Updated to recommendations in pci-skeleton v2.03. */
...
@@ -132,7 +177,12 @@ c-help: http://www.scyld.com/network/natsemi.html
...
@@ -132,7 +177,12 @@ c-help: http://www.scyld.com/network/natsemi.html
/* The user-configurable values.
/* The user-configurable values.
These may be modified when a driver module is loaded.*/
These may be modified when a driver module is loaded.*/
static
int
debug
=
1
;
/* 1 normal messages, 0 quiet .. 7 verbose. */
#define NATSEMI_DEF_MSG (NETIF_MSG_DRV | \
NETIF_MSG_LINK | \
NETIF_MSG_WOL | \
NETIF_MSG_RX_ERR | \
NETIF_MSG_TX_ERR)
static
int
debug
=
NATSEMI_DEF_MSG
;
/* Maximum events (Rx packets, etc.) to handle at each interrupt. */
/* Maximum events (Rx packets, etc.) to handle at each interrupt. */
static
int
max_interrupt_work
=
20
;
static
int
max_interrupt_work
=
20
;
...
@@ -152,8 +202,8 @@ static int rx_copybreak;
...
@@ -152,8 +202,8 @@ static int rx_copybreak;
The media type is usually passed in 'options[]'.
The media type is usually passed in 'options[]'.
*/
*/
#define MAX_UNITS 8
/* More are supported, limit only on options */
#define MAX_UNITS 8
/* More are supported, limit only on options */
static
int
options
[
MAX_UNITS
]
=
{
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
}
;
static
int
options
[
MAX_UNITS
];
static
int
full_duplex
[
MAX_UNITS
]
=
{
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
}
;
static
int
full_duplex
[
MAX_UNITS
];
/* Operational parameters that are set at compile time. */
/* Operational parameters that are set at compile time. */
...
@@ -164,7 +214,7 @@ static int full_duplex[MAX_UNITS] = {-1, -1, -1, -1, -1, -1, -1, -1};
...
@@ -164,7 +214,7 @@ static int full_duplex[MAX_UNITS] = {-1, -1, -1, -1, -1, -1, -1, -1};
There are no ill effects from too-large receive rings. */
There are no ill effects from too-large receive rings. */
#define TX_RING_SIZE 16
#define TX_RING_SIZE 16
#define TX_QUEUE_LEN 10
/* Limit ring entries actually used, min 4. */
#define TX_QUEUE_LEN 10
/* Limit ring entries actually used, min 4. */
#define RX_RING_SIZE
64
#define RX_RING_SIZE
32
/* Operational parameters that usually are not changed. */
/* Operational parameters that usually are not changed. */
/* Time in jiffies before concluding the transmitter is hung. */
/* Time in jiffies before concluding the transmitter is hung. */
...
@@ -183,37 +233,6 @@ static int full_duplex[MAX_UNITS] = {-1, -1, -1, -1, -1, -1, -1, -1};
...
@@ -183,37 +233,6 @@ static int full_duplex[MAX_UNITS] = {-1, -1, -1, -1, -1, -1, -1, -1};
#define PKT_BUF_SZ 1536
/* Size of each temporary Rx buffer. */
#define PKT_BUF_SZ 1536
/* Size of each temporary Rx buffer. */
#if !defined(__OPTIMIZE__)
#warning You must compile this file with the correct options!
#warning See the last lines of the source file.
#error You must compile this driver with "-O".
#endif
#include <linux/config.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/timer.h>
#include <linux/errno.h>
#include <linux/ioport.h>
#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/pci.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/skbuff.h>
#include <linux/init.h>
#include <linux/spinlock.h>
#include <linux/ethtool.h>
#include <linux/delay.h>
#include <linux/rtnetlink.h>
#include <linux/mii.h>
#include <asm/processor.h>
/* Processor type for cache alignment. */
#include <asm/bitops.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/uaccess.h>
/* These identify the driver base version and may not be removed. */
/* These identify the driver base version and may not be removed. */
static
char
version
[]
__devinitdata
=
static
char
version
[]
__devinitdata
=
KERN_INFO
DRV_NAME
".c:v1.07 1/9/2001 Written by Donald Becker <becker@scyld.com>
\n
"
KERN_INFO
DRV_NAME
".c:v1.07 1/9/2001 Written by Donald Becker <becker@scyld.com>
\n
"
...
@@ -232,7 +251,7 @@ MODULE_PARM(options, "1-" __MODULE_STRING(MAX_UNITS) "i");
...
@@ -232,7 +251,7 @@ MODULE_PARM(options, "1-" __MODULE_STRING(MAX_UNITS) "i");
MODULE_PARM
(
full_duplex
,
"1-"
__MODULE_STRING
(
MAX_UNITS
)
"i"
);
MODULE_PARM
(
full_duplex
,
"1-"
__MODULE_STRING
(
MAX_UNITS
)
"i"
);
MODULE_PARM_DESC
(
max_interrupt_work
,
"DP8381x maximum events handled per interrupt"
);
MODULE_PARM_DESC
(
max_interrupt_work
,
"DP8381x maximum events handled per interrupt"
);
MODULE_PARM_DESC
(
mtu
,
"DP8381x MTU (all boards)"
);
MODULE_PARM_DESC
(
mtu
,
"DP8381x MTU (all boards)"
);
MODULE_PARM_DESC
(
debug
,
"DP8381x de
bug level (0-5)
"
);
MODULE_PARM_DESC
(
debug
,
"DP8381x de
fault debug bitmask
"
);
MODULE_PARM_DESC
(
rx_copybreak
,
"DP8381x copy breakpoint for copy-only-tiny-frames"
);
MODULE_PARM_DESC
(
rx_copybreak
,
"DP8381x copy breakpoint for copy-only-tiny-frames"
);
MODULE_PARM_DESC
(
options
,
"DP8381x: Bits 0-3: media type, bit 17: full duplex"
);
MODULE_PARM_DESC
(
options
,
"DP8381x: Bits 0-3: media type, bit 17: full duplex"
);
MODULE_PARM_DESC
(
full_duplex
,
"DP8381x full duplex setting(s) (1)"
);
MODULE_PARM_DESC
(
full_duplex
,
"DP8381x full duplex setting(s) (1)"
);
...
@@ -394,14 +413,12 @@ enum register_offsets {
...
@@ -394,14 +413,12 @@ enum register_offsets {
SDCFG
=
0xF8
SDCFG
=
0xF8
};
};
/* the values for the 'magic' registers above (PGSEL=1) */
/* the values for the 'magic' registers above (PGSEL=1) */
#ifdef CONFIG_NATSEMI_CABLE_MAGIC
#define PMDCSR_VAL 0x189c
/* enable preferred adaptation circuitry */
#define PMDCSR_VAL 0x1898
#else
#define PMDCSR_VAL 0x189C
#endif
#define TSTDAT_VAL 0x0
#define TSTDAT_VAL 0x0
#define DSPCFG_VAL 0x5040
#define DSPCFG_VAL 0x5040
#define SDCFG_VAL 0x008c
#define SDCFG_VAL 0x008c
/* set voltage thresholds for Signal Detect */
#define DSPCFG_LOCK 0x20
/* coefficient lock bit in DSPCFG */
#define TSTDAT_FIXED 0xe8
/* magic number for bad coefficients */
/* misc PCI space registers */
/* misc PCI space registers */
enum
pci_register_offsets
{
enum
pci_register_offsets
{
...
@@ -421,6 +438,7 @@ enum ChipCmd_bits {
...
@@ -421,6 +438,7 @@ enum ChipCmd_bits {
enum
ChipConfig_bits
{
enum
ChipConfig_bits
{
CfgPhyDis
=
0x200
,
CfgPhyDis
=
0x200
,
CfgPhyRst
=
0x400
,
CfgPhyRst
=
0x400
,
CfgExtPhy
=
0x1000
,
CfgAnegEnable
=
0x2000
,
CfgAnegEnable
=
0x2000
,
CfgAneg100
=
0x4000
,
CfgAneg100
=
0x4000
,
CfgAnegFull
=
0x8000
,
CfgAnegFull
=
0x8000
,
...
@@ -630,10 +648,13 @@ struct netdev_private {
...
@@ -630,10 +648,13 @@ struct netdev_private {
u32
SavedClkRun
;
u32
SavedClkRun
;
/* silicon revision */
/* silicon revision */
u32
srr
;
u32
srr
;
/* expected DSPCFG value */
u16
dspcfg
;
/* MII transceiver section. */
/* MII transceiver section. */
u16
advertising
;
/* NWay media advertisement */
u16
advertising
;
/* NWay media advertisement */
unsigned
int
iosize
;
unsigned
int
iosize
;
spinlock_t
lock
;
spinlock_t
lock
;
u32
msg_enable
;
};
};
static
int
eeprom_read
(
long
ioaddr
,
int
location
);
static
int
eeprom_read
(
long
ioaddr
,
int
location
);
...
@@ -643,6 +664,8 @@ static void natsemi_reset(struct net_device *dev);
...
@@ -643,6 +664,8 @@ static void natsemi_reset(struct net_device *dev);
static
void
natsemi_reload_eeprom
(
struct
net_device
*
dev
);
static
void
natsemi_reload_eeprom
(
struct
net_device
*
dev
);
static
void
natsemi_stop_rxtx
(
struct
net_device
*
dev
);
static
void
natsemi_stop_rxtx
(
struct
net_device
*
dev
);
static
int
netdev_open
(
struct
net_device
*
dev
);
static
int
netdev_open
(
struct
net_device
*
dev
);
static
void
do_cable_magic
(
struct
net_device
*
dev
);
static
void
undo_cable_magic
(
struct
net_device
*
dev
);
static
void
check_link
(
struct
net_device
*
dev
);
static
void
check_link
(
struct
net_device
*
dev
);
static
void
netdev_timer
(
unsigned
long
data
);
static
void
netdev_timer
(
unsigned
long
data
);
static
void
tx_timeout
(
struct
net_device
*
dev
);
static
void
tx_timeout
(
struct
net_device
*
dev
);
...
@@ -753,6 +776,7 @@ static int __devinit natsemi_probe1 (struct pci_dev *pdev,
...
@@ -753,6 +776,7 @@ static int __devinit natsemi_probe1 (struct pci_dev *pdev,
pci_set_drvdata
(
pdev
,
dev
);
pci_set_drvdata
(
pdev
,
dev
);
np
->
iosize
=
iosize
;
np
->
iosize
=
iosize
;
spin_lock_init
(
&
np
->
lock
);
spin_lock_init
(
&
np
->
lock
);
np
->
msg_enable
=
debug
;
/* Reset the chip to erase previous misconfiguration. */
/* Reset the chip to erase previous misconfiguration. */
natsemi_reload_eeprom
(
dev
);
natsemi_reload_eeprom
(
dev
);
...
@@ -763,14 +787,15 @@ static int __devinit natsemi_probe1 (struct pci_dev *pdev,
...
@@ -763,14 +787,15 @@ static int __devinit natsemi_probe1 (struct pci_dev *pdev,
option
=
dev
->
mem_start
;
option
=
dev
->
mem_start
;
/* The lower four bits are the media type. */
/* The lower four bits are the media type. */
if
(
option
>
0
)
{
if
(
option
)
{
if
(
option
&
0x200
)
if
(
option
&
0x200
)
np
->
full_duplex
=
1
;
np
->
full_duplex
=
1
;
if
(
option
&
15
)
if
(
option
&
15
)
printk
(
KERN_INFO
"%s: ignoring user supplied media type %d"
,
printk
(
KERN_INFO
"%s: ignoring user supplied media type %d"
,
dev
->
name
,
option
&
15
);
dev
->
name
,
option
&
15
);
}
}
if
(
find_cnt
<
MAX_UNITS
&&
full_duplex
[
find_cnt
]
>
0
)
if
(
find_cnt
<
MAX_UNITS
&&
full_duplex
[
find_cnt
])
np
->
full_duplex
=
1
;
np
->
full_duplex
=
1
;
/* The chip-specific entries in the device structure. */
/* The chip-specific entries in the device structure. */
...
@@ -796,14 +821,17 @@ static int __devinit natsemi_probe1 (struct pci_dev *pdev,
...
@@ -796,14 +821,17 @@ static int __devinit natsemi_probe1 (struct pci_dev *pdev,
}
}
netif_carrier_off
(
dev
);
netif_carrier_off
(
dev
);
printk
(
KERN_INFO
"%s: %s at 0x%lx, "
,
if
(
netif_msg_drv
(
np
))
{
printk
(
KERN_INFO
"%s: %s at %#08lx, "
,
dev
->
name
,
natsemi_pci_info
[
chip_idx
].
name
,
ioaddr
);
dev
->
name
,
natsemi_pci_info
[
chip_idx
].
name
,
ioaddr
);
for
(
i
=
0
;
i
<
ETH_ALEN
-
1
;
i
++
)
for
(
i
=
0
;
i
<
ETH_ALEN
-
1
;
i
++
)
printk
(
"%2.2x:"
,
dev
->
dev_addr
[
i
]);
printk
(
"%02x:"
,
dev
->
dev_addr
[
i
]);
printk
(
"%2.2x, IRQ %d.
\n
"
,
dev
->
dev_addr
[
i
],
irq
);
printk
(
"%02x, IRQ %d.
\n
"
,
dev
->
dev_addr
[
i
],
irq
);
}
np
->
advertising
=
mdio_read
(
dev
,
1
,
MII_ADVERTISE
);
np
->
advertising
=
mdio_read
(
dev
,
1
,
MII_ADVERTISE
);
if
((
readl
(
ioaddr
+
ChipConfig
)
&
0xe000
)
!=
0xe000
)
{
if
((
readl
(
ioaddr
+
ChipConfig
)
&
0xe000
)
!=
0xe000
&&
netif_msg_probe
(
np
))
{
u32
chip_config
=
readl
(
ioaddr
+
ChipConfig
);
u32
chip_config
=
readl
(
ioaddr
+
ChipConfig
);
printk
(
KERN_INFO
"%s: Transceiver default autonegotiation %s "
printk
(
KERN_INFO
"%s: Transceiver default autonegotiation %s "
"10%s %s duplex.
\n
"
,
"10%s %s duplex.
\n
"
,
...
@@ -812,12 +840,18 @@ static int __devinit natsemi_probe1 (struct pci_dev *pdev,
...
@@ -812,12 +840,18 @@ static int __devinit natsemi_probe1 (struct pci_dev *pdev,
chip_config
&
CfgAneg100
?
"0"
:
""
,
chip_config
&
CfgAneg100
?
"0"
:
""
,
chip_config
&
CfgAnegFull
?
"full"
:
"half"
);
chip_config
&
CfgAnegFull
?
"full"
:
"half"
);
}
}
printk
(
KERN_INFO
"%s: Transceiver status 0x%4.4x advertising %4.4x.
\n
"
,
if
(
netif_msg_probe
(
np
))
printk
(
KERN_INFO
"%s: Transceiver status %#04x advertising %#04x.
\n
"
,
dev
->
name
,
mdio_read
(
dev
,
1
,
MII_BMSR
),
dev
->
name
,
mdio_read
(
dev
,
1
,
MII_BMSR
),
np
->
advertising
);
np
->
advertising
);
/* save the silicon revision for later querying */
/* save the silicon revision for later querying */
np
->
srr
=
readl
(
ioaddr
+
SiliconRev
);
np
->
srr
=
readl
(
ioaddr
+
SiliconRev
);
if
(
netif_msg_hw
(
np
))
printk
(
KERN_INFO
"%s: silicon revision %#04x.
\n
"
,
dev
->
name
,
np
->
srr
);
return
0
;
return
0
;
}
}
...
@@ -914,6 +948,7 @@ static void natsemi_reset(struct net_device *dev)
...
@@ -914,6 +948,7 @@ static void natsemi_reset(struct net_device *dev)
u32
rfcr
;
u32
rfcr
;
u16
pmatch
[
3
];
u16
pmatch
[
3
];
u16
sopass
[
3
];
u16
sopass
[
3
];
struct
netdev_private
*
np
=
dev
->
priv
;
/*
/*
* Resetting the chip causes some registers to be lost.
* Resetting the chip causes some registers to be lost.
...
@@ -947,10 +982,10 @@ static void natsemi_reset(struct net_device *dev)
...
@@ -947,10 +982,10 @@ static void natsemi_reset(struct net_device *dev)
break
;
break
;
udelay
(
5
);
udelay
(
5
);
}
}
if
(
i
==
NATSEMI_HW_TIMEOUT
&&
debug
)
{
if
(
i
==
NATSEMI_HW_TIMEOUT
&&
netif_msg_hw
(
np
)
)
{
printk
(
KERN_INFO
"%s: reset did not complete in %d usec.
\n
"
,
printk
(
KERN_INFO
"%s: reset did not complete in %d usec.
\n
"
,
dev
->
name
,
i
*
5
);
dev
->
name
,
i
*
5
);
}
else
if
(
debug
>
2
)
{
}
else
if
(
netif_msg_hw
(
np
)
)
{
printk
(
KERN_DEBUG
"%s: reset completed in %d usec.
\n
"
,
printk
(
KERN_DEBUG
"%s: reset completed in %d usec.
\n
"
,
dev
->
name
,
i
*
5
);
dev
->
name
,
i
*
5
);
}
}
...
@@ -979,6 +1014,7 @@ static void natsemi_reset(struct net_device *dev)
...
@@ -979,6 +1014,7 @@ static void natsemi_reset(struct net_device *dev)
static
void
natsemi_reload_eeprom
(
struct
net_device
*
dev
)
static
void
natsemi_reload_eeprom
(
struct
net_device
*
dev
)
{
{
struct
netdev_private
*
np
=
dev
->
priv
;
int
i
;
int
i
;
writel
(
EepromReload
,
dev
->
base_addr
+
PCIBusCfg
);
writel
(
EepromReload
,
dev
->
base_addr
+
PCIBusCfg
);
...
@@ -987,10 +1023,10 @@ static void natsemi_reload_eeprom(struct net_device *dev)
...
@@ -987,10 +1023,10 @@ static void natsemi_reload_eeprom(struct net_device *dev)
break
;
break
;
udelay
(
5
);
udelay
(
5
);
}
}
if
(
i
==
NATSEMI_HW_TIMEOUT
&&
debug
)
{
if
(
i
==
NATSEMI_HW_TIMEOUT
&&
netif_msg_hw
(
np
)
)
{
printk
(
KERN_INFO
"%s: EEPROM did not reload in %d usec.
\n
"
,
printk
(
KERN_INFO
"%s: EEPROM did not reload in %d usec.
\n
"
,
dev
->
name
,
i
*
5
);
dev
->
name
,
i
*
5
);
}
else
if
(
debug
>
2
)
{
}
else
if
(
netif_msg_hw
(
np
)
)
{
printk
(
KERN_DEBUG
"%s: EEPROM reloaded in %d usec.
\n
"
,
printk
(
KERN_DEBUG
"%s: EEPROM reloaded in %d usec.
\n
"
,
dev
->
name
,
i
*
5
);
dev
->
name
,
i
*
5
);
}
}
...
@@ -999,6 +1035,7 @@ static void natsemi_reload_eeprom(struct net_device *dev)
...
@@ -999,6 +1035,7 @@ static void natsemi_reload_eeprom(struct net_device *dev)
static
void
natsemi_stop_rxtx
(
struct
net_device
*
dev
)
static
void
natsemi_stop_rxtx
(
struct
net_device
*
dev
)
{
{
long
ioaddr
=
dev
->
base_addr
;
long
ioaddr
=
dev
->
base_addr
;
struct
netdev_private
*
np
=
dev
->
priv
;
int
i
;
int
i
;
writel
(
RxOff
|
TxOff
,
ioaddr
+
ChipCmd
);
writel
(
RxOff
|
TxOff
,
ioaddr
+
ChipCmd
);
...
@@ -1007,10 +1044,10 @@ static void natsemi_stop_rxtx(struct net_device *dev)
...
@@ -1007,10 +1044,10 @@ static void natsemi_stop_rxtx(struct net_device *dev)
break
;
break
;
udelay
(
5
);
udelay
(
5
);
}
}
if
(
i
==
NATSEMI_HW_TIMEOUT
&&
debug
)
{
if
(
i
==
NATSEMI_HW_TIMEOUT
&&
netif_msg_hw
(
np
)
)
{
printk
(
KERN_INFO
"%s: Tx/Rx process did not stop in %d usec.
\n
"
,
printk
(
KERN_INFO
"%s: Tx/Rx process did not stop in %d usec.
\n
"
,
dev
->
name
,
i
*
5
);
dev
->
name
,
i
*
5
);
}
else
if
(
debug
>
2
)
{
}
else
if
(
netif_msg_hw
(
np
)
)
{
printk
(
KERN_DEBUG
"%s: Tx/Rx process stopped in %d usec.
\n
"
,
printk
(
KERN_DEBUG
"%s: Tx/Rx process stopped in %d usec.
\n
"
,
dev
->
name
,
i
*
5
);
dev
->
name
,
i
*
5
);
}
}
...
@@ -1028,7 +1065,7 @@ static int netdev_open(struct net_device *dev)
...
@@ -1028,7 +1065,7 @@ static int netdev_open(struct net_device *dev)
i
=
request_irq
(
dev
->
irq
,
&
intr_handler
,
SA_SHIRQ
,
dev
->
name
,
dev
);
i
=
request_irq
(
dev
->
irq
,
&
intr_handler
,
SA_SHIRQ
,
dev
->
name
,
dev
);
if
(
i
)
return
i
;
if
(
i
)
return
i
;
if
(
debug
>
1
)
if
(
netif_msg_ifup
(
np
)
)
printk
(
KERN_DEBUG
"%s: netdev_open() irq %d.
\n
"
,
printk
(
KERN_DEBUG
"%s: netdev_open() irq %d.
\n
"
,
dev
->
name
,
dev
->
irq
);
dev
->
name
,
dev
->
irq
);
i
=
alloc_ring
(
dev
);
i
=
alloc_ring
(
dev
);
...
@@ -1043,8 +1080,8 @@ static int netdev_open(struct net_device *dev)
...
@@ -1043,8 +1080,8 @@ static int netdev_open(struct net_device *dev)
netif_start_queue
(
dev
);
netif_start_queue
(
dev
);
if
(
debug
>
2
)
if
(
netif_msg_ifup
(
np
)
)
printk
(
KERN_DEBUG
"%s: Done netdev_open(), status: %x.
\n
"
,
printk
(
KERN_DEBUG
"%s: Done netdev_open(), status: %
#08
x.
\n
"
,
dev
->
name
,
(
int
)
readl
(
ioaddr
+
ChipCmd
));
dev
->
name
,
(
int
)
readl
(
ioaddr
+
ChipCmd
));
/* Set the timer to check for link beat. */
/* Set the timer to check for link beat. */
...
@@ -1057,6 +1094,54 @@ static int netdev_open(struct net_device *dev)
...
@@ -1057,6 +1094,54 @@ static int netdev_open(struct net_device *dev)
return
0
;
return
0
;
}
}
static
void
do_cable_magic
(
struct
net_device
*
dev
)
{
/*
* 100 MBit links with short cables can trip an issue with the chip.
* The problem manifests as lots of CRC errors and/or flickering
* activity LED while idle. This process is based on instructions
* from engineers at National.
*/
if
(
readl
(
dev
->
base_addr
+
ChipConfig
)
&
CfgSpeed100
)
{
u16
data
;
writew
(
1
,
dev
->
base_addr
+
PGSEL
);
/*
* coefficient visibility should already be enabled via
* DSPCFG | 0x1000
*/
data
=
readw
(
dev
->
base_addr
+
TSTDAT
)
&
0xff
;
/*
* the value must be negative, and within certain values
* (these values all come from National)
*/
if
(
!
(
data
&
0x80
)
||
((
data
>=
0xd8
)
&&
(
data
<=
0xff
)))
{
struct
netdev_private
*
np
=
dev
->
priv
;
/* the bug has been triggered - fix the coefficient */
writew
(
TSTDAT_FIXED
,
dev
->
base_addr
+
TSTDAT
);
/* lock the value */
data
=
readw
(
dev
->
base_addr
+
DSPCFG
);
np
->
dspcfg
=
data
|
DSPCFG_LOCK
;
writew
(
np
->
dspcfg
,
dev
->
base_addr
+
DSPCFG
);
}
writew
(
0
,
dev
->
base_addr
+
PGSEL
);
}
}
static
void
undo_cable_magic
(
struct
net_device
*
dev
)
{
u16
data
;
struct
netdev_private
*
np
=
dev
->
priv
;
writew
(
1
,
dev
->
base_addr
+
PGSEL
);
/* make sure the lock bit is clear */
data
=
readw
(
dev
->
base_addr
+
DSPCFG
);
np
->
dspcfg
=
data
&
~
DSPCFG_LOCK
;
writew
(
np
->
dspcfg
,
dev
->
base_addr
+
DSPCFG
);
writew
(
0
,
dev
->
base_addr
+
PGSEL
);
}
static
void
check_link
(
struct
net_device
*
dev
)
static
void
check_link
(
struct
net_device
*
dev
)
{
{
struct
netdev_private
*
np
=
dev
->
priv
;
struct
netdev_private
*
np
=
dev
->
priv
;
...
@@ -1064,29 +1149,31 @@ static void check_link(struct net_device *dev)
...
@@ -1064,29 +1149,31 @@ static void check_link(struct net_device *dev)
int
duplex
;
int
duplex
;
int
chipcfg
=
readl
(
ioaddr
+
ChipConfig
);
int
chipcfg
=
readl
(
ioaddr
+
ChipConfig
);
if
(
!
(
chipcfg
&
CfgLink
))
{
if
(
!
(
chipcfg
&
CfgLink
))
{
if
(
netif_carrier_ok
(
dev
))
{
if
(
netif_carrier_ok
(
dev
))
{
if
(
debug
)
if
(
netif_msg_link
(
np
)
)
printk
(
KERN_
INFO
"%s: no link. Disabling watchdog.
\n
"
,
printk
(
KERN_
NOTICE
"%s: link down.
\n
"
,
dev
->
name
);
dev
->
name
);
netif_carrier_off
(
dev
);
netif_carrier_off
(
dev
);
undo_cable_magic
(
dev
);
}
}
return
;
return
;
}
}
if
(
!
netif_carrier_ok
(
dev
))
{
if
(
!
netif_carrier_ok
(
dev
))
{
if
(
debug
)
if
(
netif_msg_link
(
np
))
printk
(
KERN_INFO
"%s: link is back. Enabling watchdog.
\n
"
,
printk
(
KERN_NOTICE
"%s: link up.
\n
"
,
dev
->
name
);
dev
->
name
);
netif_carrier_on
(
dev
);
netif_carrier_on
(
dev
);
do_cable_magic
(
dev
);
}
}
duplex
=
np
->
full_duplex
||
(
chipcfg
&
CfgFullDuplex
?
1
:
0
);
duplex
=
np
->
full_duplex
||
(
chipcfg
&
CfgFullDuplex
?
1
:
0
);
/* if duplex is set then bit 28 must be set, too */
/* if duplex is set then bit 28 must be set, too */
if
(
duplex
^
!!
(
np
->
rx_config
&
RxAcceptTx
))
{
if
(
duplex
^
!!
(
np
->
rx_config
&
RxAcceptTx
))
{
if
(
debug
)
if
(
netif_msg_link
(
np
))
printk
(
KERN_INFO
"%s: Setting %s-duplex based on negotiated link"
printk
(
KERN_INFO
" capability.
\n
"
,
dev
->
name
,
"%s: Setting %s-duplex based on negotiated "
"link capability.
\n
"
,
dev
->
name
,
duplex
?
"full"
:
"half"
);
duplex
?
"full"
:
"half"
);
if
(
duplex
)
{
if
(
duplex
)
{
np
->
rx_config
|=
RxAcceptTx
;
np
->
rx_config
|=
RxAcceptTx
;
...
@@ -1106,17 +1193,12 @@ static void init_registers(struct net_device *dev)
...
@@ -1106,17 +1193,12 @@ static void init_registers(struct net_device *dev)
long
ioaddr
=
dev
->
base_addr
;
long
ioaddr
=
dev
->
base_addr
;
int
i
;
int
i
;
/* save the silicon revision for later */
if
(
debug
>
4
)
printk
(
KERN_DEBUG
"%s: found silicon revision %xh.
\n
"
,
dev
->
name
,
np
->
srr
);
for
(
i
=
0
;
i
<
NATSEMI_HW_TIMEOUT
;
i
++
)
{
for
(
i
=
0
;
i
<
NATSEMI_HW_TIMEOUT
;
i
++
)
{
if
(
readl
(
dev
->
base_addr
+
ChipConfig
)
&
CfgAnegDone
)
if
(
readl
(
dev
->
base_addr
+
ChipConfig
)
&
CfgAnegDone
)
break
;
break
;
udelay
(
10
);
udelay
(
10
);
}
}
if
(
i
==
NATSEMI_HW_TIMEOUT
&&
debug
)
{
if
(
i
==
NATSEMI_HW_TIMEOUT
&&
netif_msg_link
(
np
)
)
{
printk
(
KERN_INFO
printk
(
KERN_INFO
"%s: autonegotiation did not complete in %d usec.
\n
"
,
"%s: autonegotiation did not complete in %d usec.
\n
"
,
dev
->
name
,
i
*
10
);
dev
->
name
,
i
*
10
);
...
@@ -1135,6 +1217,7 @@ static void init_registers(struct net_device *dev)
...
@@ -1135,6 +1217,7 @@ static void init_registers(struct net_device *dev)
writew
(
DSPCFG_VAL
,
ioaddr
+
DSPCFG
);
writew
(
DSPCFG_VAL
,
ioaddr
+
DSPCFG
);
writew
(
SDCFG_VAL
,
ioaddr
+
SDCFG
);
writew
(
SDCFG_VAL
,
ioaddr
+
SDCFG
);
writew
(
0
,
ioaddr
+
PGSEL
);
writew
(
0
,
ioaddr
+
PGSEL
);
np
->
dspcfg
=
DSPCFG_VAL
;
/* Enable PHY Specific event based interrupts. Link state change
/* Enable PHY Specific event based interrupts. Link state change
and Auto-Negotiation Completion are among the affected.
and Auto-Negotiation Completion are among the affected.
...
@@ -1181,8 +1264,8 @@ static void init_registers(struct net_device *dev)
...
@@ -1181,8 +1264,8 @@ static void init_registers(struct net_device *dev)
* nothing will be written to memory. */
* nothing will be written to memory. */
np
->
SavedClkRun
=
readl
(
ioaddr
+
ClkRun
);
np
->
SavedClkRun
=
readl
(
ioaddr
+
ClkRun
);
writel
(
np
->
SavedClkRun
&
~
PMEEnable
,
ioaddr
+
ClkRun
);
writel
(
np
->
SavedClkRun
&
~
PMEEnable
,
ioaddr
+
ClkRun
);
if
(
np
->
SavedClkRun
&
PMEStatus
)
{
if
(
np
->
SavedClkRun
&
PMEStatus
&&
netif_msg_wol
(
np
)
)
{
printk
(
KERN_NOTICE
"%s: Wake-up event %
8.
8x
\n
"
,
printk
(
KERN_NOTICE
"%s: Wake-up event %
#0
8x
\n
"
,
dev
->
name
,
readl
(
ioaddr
+
WOLCmd
));
dev
->
name
,
readl
(
ioaddr
+
WOLCmd
));
}
}
...
@@ -1198,7 +1281,9 @@ static void init_registers(struct net_device *dev)
...
@@ -1198,7 +1281,9 @@ static void init_registers(struct net_device *dev)
}
}
/*
/*
* The frequency on this has been increased because of a nasty little problem.
* Purpose:
* check for sudden death of the NIC:
*
* It seems that a reference set for this chip went out with incorrect info,
* It seems that a reference set for this chip went out with incorrect info,
* and there exist boards that aren't quite right. An unexpected voltage drop
* and there exist boards that aren't quite right. An unexpected voltage drop
* can cause the PHY to get itself in a weird state (basically reset..).
* can cause the PHY to get itself in a weird state (basically reset..).
...
@@ -1212,7 +1297,7 @@ static void netdev_timer(unsigned long data)
...
@@ -1212,7 +1297,7 @@ static void netdev_timer(unsigned long data)
long
ioaddr
=
dev
->
base_addr
;
long
ioaddr
=
dev
->
base_addr
;
u16
dspcfg
;
u16
dspcfg
;
if
(
debug
>
3
)
{
if
(
netif_msg_timer
(
np
)
)
{
/* DO NOT read the IntrStatus register,
/* DO NOT read the IntrStatus register,
* a read clears any pending interrupts.
* a read clears any pending interrupts.
*/
*/
...
@@ -1220,15 +1305,18 @@ static void netdev_timer(unsigned long data)
...
@@ -1220,15 +1305,18 @@ static void netdev_timer(unsigned long data)
dev
->
name
);
dev
->
name
);
}
}
spin_lock_irq
(
&
np
->
lock
);
/* check for a nasty random phy-reset - use dspcfg as a flag */
/* check for a nasty random phy-reset - use dspcfg as a flag */
writew
(
1
,
ioaddr
+
PGSEL
);
writew
(
1
,
ioaddr
+
PGSEL
);
dspcfg
=
readw
(
ioaddr
+
DSPCFG
);
dspcfg
=
readw
(
ioaddr
+
DSPCFG
);
writew
(
0
,
ioaddr
+
PGSEL
);
writew
(
0
,
ioaddr
+
PGSEL
);
if
(
dspcfg
!=
DSPCFG_VAL
)
{
if
(
dspcfg
!=
np
->
dspcfg
)
{
if
(
!
netif_queue_stopped
(
dev
))
{
if
(
!
netif_queue_stopped
(
dev
))
{
printk
(
KERN_INFO
spin_unlock_irq
(
&
np
->
lock
);
"%s: possible phy reset: re-initializing
\n
"
,
if
(
netif_msg_hw
(
np
))
dev
->
name
);
printk
(
KERN_NOTICE
"%s: possible phy reset: "
"re-initializing
\n
"
,
dev
->
name
);
disable_irq
(
dev
->
irq
);
disable_irq
(
dev
->
irq
);
spin_lock_irq
(
&
np
->
lock
);
spin_lock_irq
(
&
np
->
lock
);
init_registers
(
dev
);
init_registers
(
dev
);
...
@@ -1237,10 +1325,10 @@ static void netdev_timer(unsigned long data)
...
@@ -1237,10 +1325,10 @@ static void netdev_timer(unsigned long data)
}
else
{
}
else
{
/* hurry back */
/* hurry back */
next_tick
=
HZ
;
next_tick
=
HZ
;
spin_unlock_irq
(
&
np
->
lock
);
}
}
}
else
{
}
else
{
/* init_registers() calls check_link() for the above case */
/* init_registers() calls check_link() for the above case */
spin_lock_irq
(
&
np
->
lock
);
check_link
(
dev
);
check_link
(
dev
);
spin_unlock_irq
(
&
np
->
lock
);
spin_unlock_irq
(
&
np
->
lock
);
}
}
...
@@ -1251,18 +1339,18 @@ static void dump_ring(struct net_device *dev)
...
@@ -1251,18 +1339,18 @@ static void dump_ring(struct net_device *dev)
{
{
struct
netdev_private
*
np
=
dev
->
priv
;
struct
netdev_private
*
np
=
dev
->
priv
;
if
(
debug
>
2
)
{
if
(
netif_msg_pktdata
(
np
)
)
{
int
i
;
int
i
;
printk
(
KERN_DEBUG
" Tx ring at %p:
\n
"
,
np
->
tx_ring
);
printk
(
KERN_DEBUG
" Tx ring at %p:
\n
"
,
np
->
tx_ring
);
for
(
i
=
0
;
i
<
TX_RING_SIZE
;
i
++
)
{
for
(
i
=
0
;
i
<
TX_RING_SIZE
;
i
++
)
{
printk
(
KERN_DEBUG
" #%d desc. %
8.8x %8.8x %8.
8x.
\n
"
,
printk
(
KERN_DEBUG
" #%d desc. %
#08x %#08x %#0
8x.
\n
"
,
i
,
np
->
tx_ring
[
i
].
next_desc
,
i
,
np
->
tx_ring
[
i
].
next_desc
,
np
->
tx_ring
[
i
].
cmd_status
,
np
->
tx_ring
[
i
].
cmd_status
,
np
->
tx_ring
[
i
].
addr
);
np
->
tx_ring
[
i
].
addr
);
}
}
printk
(
KERN_DEBUG
" Rx ring %p:
\n
"
,
np
->
rx_ring
);
printk
(
KERN_DEBUG
" Rx ring %p:
\n
"
,
np
->
rx_ring
);
for
(
i
=
0
;
i
<
RX_RING_SIZE
;
i
++
)
{
for
(
i
=
0
;
i
<
RX_RING_SIZE
;
i
++
)
{
printk
(
KERN_DEBUG
" #%d desc. %
8.8x %8.8x %8.
8x.
\n
"
,
printk
(
KERN_DEBUG
" #%d desc. %
#08x %#08x %#0
8x.
\n
"
,
i
,
np
->
rx_ring
[
i
].
next_desc
,
i
,
np
->
rx_ring
[
i
].
next_desc
,
np
->
rx_ring
[
i
].
cmd_status
,
np
->
rx_ring
[
i
].
cmd_status
,
np
->
rx_ring
[
i
].
addr
);
np
->
rx_ring
[
i
].
addr
);
...
@@ -1278,7 +1366,9 @@ static void tx_timeout(struct net_device *dev)
...
@@ -1278,7 +1366,9 @@ static void tx_timeout(struct net_device *dev)
disable_irq
(
dev
->
irq
);
disable_irq
(
dev
->
irq
);
spin_lock_irq
(
&
np
->
lock
);
spin_lock_irq
(
&
np
->
lock
);
if
(
netif_device_present
(
dev
))
{
if
(
netif_device_present
(
dev
))
{
printk
(
KERN_WARNING
"%s: Transmit timed out, status %8.8x,"
if
(
netif_msg_tx_err
(
np
))
printk
(
KERN_WARNING
"%s: Transmit timed out, status %#08x,"
" resetting...
\n
"
,
" resetting...
\n
"
,
dev
->
name
,
readl
(
ioaddr
+
IntrStatus
));
dev
->
name
,
readl
(
ioaddr
+
IntrStatus
));
dump_ring
(
dev
);
dump_ring
(
dev
);
...
@@ -1438,7 +1528,7 @@ static int start_tx(struct sk_buff *skb, struct net_device *dev)
...
@@ -1438,7 +1528,7 @@ static int start_tx(struct sk_buff *skb, struct net_device *dev)
dev
->
trans_start
=
jiffies
;
dev
->
trans_start
=
jiffies
;
if
(
debug
>
4
)
{
if
(
netif_msg_tx_queued
(
np
)
)
{
printk
(
KERN_DEBUG
"%s: Transmit frame #%d queued in slot %d.
\n
"
,
printk
(
KERN_DEBUG
"%s: Transmit frame #%d queued in slot %d.
\n
"
,
dev
->
name
,
np
->
cur_tx
,
entry
);
dev
->
name
,
np
->
cur_tx
,
entry
);
}
}
...
@@ -1451,14 +1541,11 @@ static void netdev_tx_done(struct net_device *dev)
...
@@ -1451,14 +1541,11 @@ static void netdev_tx_done(struct net_device *dev)
for
(;
np
->
cur_tx
-
np
->
dirty_tx
>
0
;
np
->
dirty_tx
++
)
{
for
(;
np
->
cur_tx
-
np
->
dirty_tx
>
0
;
np
->
dirty_tx
++
)
{
int
entry
=
np
->
dirty_tx
%
TX_RING_SIZE
;
int
entry
=
np
->
dirty_tx
%
TX_RING_SIZE
;
if
(
np
->
tx_ring
[
entry
].
cmd_status
&
cpu_to_le32
(
DescOwn
))
{
if
(
np
->
tx_ring
[
entry
].
cmd_status
&
cpu_to_le32
(
DescOwn
))
if
(
debug
>
4
)
printk
(
KERN_DEBUG
"%s: tx frame #%d is busy.
\n
"
,
dev
->
name
,
np
->
dirty_tx
);
break
;
break
;
}
if
(
netif_msg_tx_done
(
np
))
if
(
debug
>
4
)
printk
(
KERN_DEBUG
printk
(
KERN_DEBUG
"%s: tx frame #%d finished with status %8.8xh
.
\n
"
,
"%s: tx frame #%d finished, status %#08x
.
\n
"
,
dev
->
name
,
np
->
dirty_tx
,
dev
->
name
,
np
->
dirty_tx
,
le32_to_cpu
(
np
->
tx_ring
[
entry
].
cmd_status
));
le32_to_cpu
(
np
->
tx_ring
[
entry
].
cmd_status
));
if
(
np
->
tx_ring
[
entry
].
cmd_status
&
cpu_to_le32
(
DescPktOK
))
{
if
(
np
->
tx_ring
[
entry
].
cmd_status
&
cpu_to_le32
(
DescPktOK
))
{
...
@@ -1495,30 +1582,31 @@ static void netdev_tx_done(struct net_device *dev)
...
@@ -1495,30 +1582,31 @@ static void netdev_tx_done(struct net_device *dev)
static
void
intr_handler
(
int
irq
,
void
*
dev_instance
,
struct
pt_regs
*
rgs
)
static
void
intr_handler
(
int
irq
,
void
*
dev_instance
,
struct
pt_regs
*
rgs
)
{
{
struct
net_device
*
dev
=
dev_instance
;
struct
net_device
*
dev
=
dev_instance
;
struct
netdev_private
*
np
;
struct
netdev_private
*
np
=
dev
->
priv
;
long
ioaddr
;
long
ioaddr
=
dev
->
base_addr
;
int
boguscnt
=
max_interrupt_work
;
int
boguscnt
=
max_interrupt_work
;
ioaddr
=
dev
->
base_addr
;
np
=
dev
->
priv
;
if
(
!
netif_device_present
(
dev
))
if
(
!
netif_device_present
(
dev
))
return
;
return
;
do
{
do
{
/* Reading automatically acknowledges all int sources. */
/* Reading automatically acknowledges all int sources. */
u32
intr_status
=
readl
(
ioaddr
+
IntrStatus
);
u32
intr_status
=
readl
(
ioaddr
+
IntrStatus
);
if
(
debug
>
4
)
if
(
netif_msg_intr
(
np
)
)
printk
(
KERN_DEBUG
"%s: Interrupt, status %
4.4
x.
\n
"
,
printk
(
KERN_DEBUG
"%s: Interrupt, status %
#08
x.
\n
"
,
dev
->
name
,
intr_status
);
dev
->
name
,
intr_status
);
if
(
intr_status
==
0
)
if
(
intr_status
==
0
)
break
;
break
;
if
(
intr_status
&
(
IntrRxDone
|
IntrRxIntr
|
RxStatusFIFOOver
|
IntrRxErr
|
IntrRxOverrun
))
if
(
intr_status
&
(
IntrRxDone
|
IntrRxIntr
|
RxStatusFIFOOver
|
IntrRxErr
|
IntrRxOverrun
))
{
netdev_rx
(
dev
);
netdev_rx
(
dev
);
}
if
(
intr_status
&
(
IntrTxDone
|
IntrTxIntr
|
IntrTxIdle
|
IntrTxErr
)
)
{
if
(
intr_status
&
(
IntrTxDone
|
IntrTxIntr
|
IntrTxIdle
|
IntrTxErr
))
{
spin_lock
(
&
np
->
lock
);
spin_lock
(
&
np
->
lock
);
netdev_tx_done
(
dev
);
netdev_tx_done
(
dev
);
spin_unlock
(
&
np
->
lock
);
spin_unlock
(
&
np
->
lock
);
...
@@ -1529,16 +1617,16 @@ static void intr_handler(int irq, void *dev_instance, struct pt_regs *rgs)
...
@@ -1529,16 +1617,16 @@ static void intr_handler(int irq, void *dev_instance, struct pt_regs *rgs)
netdev_error
(
dev
,
intr_status
);
netdev_error
(
dev
,
intr_status
);
if
(
--
boguscnt
<
0
)
{
if
(
--
boguscnt
<
0
)
{
printk
(
KERN_WARNING
"%s: Too much work at interrupt, "
if
(
netif_msg_intr
(
np
))
"status=0x%4.4x.
\n
"
,
printk
(
KERN_WARNING
dev
->
name
,
intr_status
);
"%s: Too much work at interrupt, "
"status=%#08x.
\n
"
,
dev
->
name
,
intr_status
);
break
;
break
;
}
}
}
while
(
1
);
}
while
(
1
);
if
(
debug
>
4
)
if
(
netif_msg_intr
(
np
))
printk
(
KERN_DEBUG
"%s: exiting interrupt.
\n
"
,
printk
(
KERN_DEBUG
"%s: exiting interrupt.
\n
"
,
dev
->
name
);
dev
->
name
);
}
}
/* This routine is logically part of the interrupt handler, but separated
/* This routine is logically part of the interrupt handler, but separated
...
@@ -1552,22 +1640,24 @@ static void netdev_rx(struct net_device *dev)
...
@@ -1552,22 +1640,24 @@ static void netdev_rx(struct net_device *dev)
/* If the driver owns the next entry it's a new packet. Send it up. */
/* If the driver owns the next entry it's a new packet. Send it up. */
while
(
desc_status
<
0
)
{
/* e.g. & DescOwn */
while
(
desc_status
<
0
)
{
/* e.g. & DescOwn */
if
(
debug
>
4
)
if
(
netif_msg_rx_status
(
np
))
printk
(
KERN_DEBUG
" In netdev_rx() entry %d status was %8.8x.
\n
"
,
printk
(
KERN_DEBUG
" netdev_rx() entry %d status was %#08x.
\n
"
,
entry
,
desc_status
);
entry
,
desc_status
);
if
(
--
boguscnt
<
0
)
if
(
--
boguscnt
<
0
)
break
;
break
;
if
((
desc_status
&
(
DescMore
|
DescPktOK
|
DescRxLong
))
!=
DescPktOK
)
{
if
((
desc_status
&
(
DescMore
|
DescPktOK
|
DescRxLong
))
!=
DescPktOK
)
{
if
(
desc_status
&
DescMore
)
{
if
(
desc_status
&
DescMore
)
{
printk
(
KERN_WARNING
"%s: Oversized(?) Ethernet frame spanned "
if
(
netif_msg_rx_err
(
np
))
"multiple buffers, entry %#x status %x.
\n
"
,
printk
(
KERN_WARNING
dev
->
name
,
np
->
cur_rx
,
desc_status
);
"%s: Oversized(?) Ethernet "
"frame spanned multiple "
"buffers, entry %#08x "
"status %#08x.
\n
"
,
dev
->
name
,
np
->
cur_rx
,
desc_status
);
np
->
stats
.
rx_length_errors
++
;
np
->
stats
.
rx_length_errors
++
;
}
else
{
}
else
{
/* There was a error. */
/* There was an error. */
if
(
debug
>
2
)
printk
(
KERN_DEBUG
" netdev_rx() Rx error was %8.8x.
\n
"
,
desc_status
);
np
->
stats
.
rx_errors
++
;
np
->
stats
.
rx_errors
++
;
if
(
desc_status
&
(
DescRxAbort
|
DescRxOver
))
if
(
desc_status
&
(
DescRxAbort
|
DescRxOver
))
np
->
stats
.
rx_over_errors
++
;
np
->
stats
.
rx_over_errors
++
;
...
@@ -1582,8 +1672,8 @@ static void netdev_rx(struct net_device *dev)
...
@@ -1582,8 +1672,8 @@ static void netdev_rx(struct net_device *dev)
struct
sk_buff
*
skb
;
struct
sk_buff
*
skb
;
/* Omit CRC size. */
/* Omit CRC size. */
int
pkt_len
=
(
desc_status
&
DescSizeMask
)
-
4
;
int
pkt_len
=
(
desc_status
&
DescSizeMask
)
-
4
;
/* Check if the packet is long enough to accept
without copying
/* Check if the packet is long enough to accept
to a minimally-sized skbuff. */
* without copying
to a minimally-sized skbuff. */
if
(
pkt_len
<
rx_copybreak
if
(
pkt_len
<
rx_copybreak
&&
(
skb
=
dev_alloc_skb
(
pkt_len
+
2
))
!=
NULL
)
{
&&
(
skb
=
dev_alloc_skb
(
pkt_len
+
2
))
!=
NULL
)
{
skb
->
dev
=
dev
;
skb
->
dev
=
dev
;
...
@@ -1646,11 +1736,16 @@ static void netdev_error(struct net_device *dev, int intr_status)
...
@@ -1646,11 +1736,16 @@ static void netdev_error(struct net_device *dev, int intr_status)
spin_lock
(
&
np
->
lock
);
spin_lock
(
&
np
->
lock
);
if
(
intr_status
&
LinkChange
)
{
if
(
intr_status
&
LinkChange
)
{
printk
(
KERN_NOTICE
u16
adv
=
mdio_read
(
dev
,
1
,
MII_ADVERTISE
);
"%s: Link changed: Autonegotiation advertising"
u16
lpa
=
mdio_read
(
dev
,
1
,
MII_LPA
);
" %4.4x partner %4.4x.
\n
"
,
dev
->
name
,
if
(
mdio_read
(
dev
,
1
,
MII_BMCR
)
&
BMCR_ANENABLE
(
int
)
mdio_read
(
dev
,
1
,
MII_ADVERTISE
),
&&
netif_msg_link
(
np
))
{
(
int
)
mdio_read
(
dev
,
1
,
MII_LPA
));
printk
(
KERN_INFO
"%s: Autonegotiation advertising"
" %#04x partner %#04x.
\n
"
,
dev
->
name
,
adv
,
lpa
);
}
/* read MII int status to clear the flag */
/* read MII int status to clear the flag */
readw
(
ioaddr
+
MIntrStatus
);
readw
(
ioaddr
+
MIntrStatus
);
check_link
(
dev
);
check_link
(
dev
);
...
@@ -1661,18 +1756,19 @@ static void netdev_error(struct net_device *dev, int intr_status)
...
@@ -1661,18 +1756,19 @@ static void netdev_error(struct net_device *dev, int intr_status)
if
(
intr_status
&
IntrTxUnderrun
)
{
if
(
intr_status
&
IntrTxUnderrun
)
{
if
((
np
->
tx_config
&
TxDrthMask
)
<
62
)
if
((
np
->
tx_config
&
TxDrthMask
)
<
62
)
np
->
tx_config
+=
2
;
np
->
tx_config
+=
2
;
if
(
debug
>
2
)
if
(
netif_msg_tx_err
(
np
))
printk
(
KERN_NOTICE
"%s: increasing Tx threshold, new tx cfg %8.8xh.
\n
"
,
printk
(
KERN_NOTICE
"%s: increased Tx threshold, txcfg %#08x.
\n
"
,
dev
->
name
,
np
->
tx_config
);
dev
->
name
,
np
->
tx_config
);
writel
(
np
->
tx_config
,
ioaddr
+
TxConfig
);
writel
(
np
->
tx_config
,
ioaddr
+
TxConfig
);
}
}
if
(
intr_status
&
WOLPkt
)
{
if
(
intr_status
&
WOLPkt
&&
netif_msg_wol
(
np
)
)
{
int
wol_status
=
readl
(
ioaddr
+
WOLCmd
);
int
wol_status
=
readl
(
ioaddr
+
WOLCmd
);
printk
(
KERN_NOTICE
"%s: Link wake-up event %
8.
8x
\n
"
,
printk
(
KERN_NOTICE
"%s: Link wake-up event %
#0
8x
\n
"
,
dev
->
name
,
wol_status
);
dev
->
name
,
wol_status
);
}
}
if
(
intr_status
&
RxStatusFIFOOver
)
{
if
(
intr_status
&
RxStatusFIFOOver
)
{
if
(
debug
>=
2
)
{
if
(
netif_msg_rx_err
(
np
)
&&
netif_msg_intr
(
np
)
)
{
printk
(
KERN_NOTICE
"%s: Rx status FIFO overrun
\n
"
,
printk
(
KERN_NOTICE
"%s: Rx status FIFO overrun
\n
"
,
dev
->
name
);
dev
->
name
);
}
}
...
@@ -1680,10 +1776,8 @@ static void netdev_error(struct net_device *dev, int intr_status)
...
@@ -1680,10 +1776,8 @@ static void netdev_error(struct net_device *dev, int intr_status)
}
}
/* Hmmmmm, it's not clear how to recover from PCI faults. */
/* Hmmmmm, it's not clear how to recover from PCI faults. */
if
(
intr_status
&
IntrPCIErr
)
{
if
(
intr_status
&
IntrPCIErr
)
{
if
(
debug
)
{
printk
(
KERN_NOTICE
"%s: PCI error %#08x
\n
"
,
dev
->
name
,
printk
(
KERN_NOTICE
"%s: PCI error %08x
\n
"
,
dev
->
name
,
intr_status
&
IntrPCIErr
);
intr_status
&
IntrPCIErr
);
}
np
->
stats
.
tx_fifo_errors
++
;
np
->
stats
.
tx_fifo_errors
++
;
np
->
stats
.
rx_fifo_errors
++
;
np
->
stats
.
rx_fifo_errors
++
;
}
}
...
@@ -1761,7 +1855,8 @@ static void __set_rx_mode(struct net_device *dev)
...
@@ -1761,7 +1855,8 @@ static void __set_rx_mode(struct net_device *dev)
if
(
dev
->
flags
&
IFF_PROMISC
)
{
/* Set promiscuous. */
if
(
dev
->
flags
&
IFF_PROMISC
)
{
/* Set promiscuous. */
/* Unconditionally log net taps. */
/* Unconditionally log net taps. */
printk
(
KERN_NOTICE
"%s: Promiscuous mode enabled.
\n
"
,
dev
->
name
);
printk
(
KERN_NOTICE
"%s: Promiscuous mode enabled.
\n
"
,
dev
->
name
);
rx_mode
=
RxFilterEnable
|
AcceptBroadcast
rx_mode
=
RxFilterEnable
|
AcceptBroadcast
|
AcceptAllMulticast
|
AcceptAllPhys
|
AcceptMyPhys
;
|
AcceptAllMulticast
|
AcceptAllPhys
|
AcceptMyPhys
;
}
else
if
((
dev
->
mc_count
>
multicast_filter_limit
)
}
else
if
((
dev
->
mc_count
>
multicast_filter_limit
)
...
@@ -1896,7 +1991,7 @@ static int netdev_ethtool_ioctl(struct net_device *dev, void *useraddr)
...
@@ -1896,7 +1991,7 @@ static int netdev_ethtool_ioctl(struct net_device *dev, void *useraddr)
/* get message-level */
/* get message-level */
case
ETHTOOL_GMSGLVL
:
{
case
ETHTOOL_GMSGLVL
:
{
struct
ethtool_value
edata
=
{
ETHTOOL_GMSGLVL
};
struct
ethtool_value
edata
=
{
ETHTOOL_GMSGLVL
};
edata
.
data
=
debug
;
edata
.
data
=
np
->
msg_enable
;
if
(
copy_to_user
(
useraddr
,
&
edata
,
sizeof
(
edata
)))
if
(
copy_to_user
(
useraddr
,
&
edata
,
sizeof
(
edata
)))
return
-
EFAULT
;
return
-
EFAULT
;
return
0
;
return
0
;
...
@@ -1906,7 +2001,7 @@ static int netdev_ethtool_ioctl(struct net_device *dev, void *useraddr)
...
@@ -1906,7 +2001,7 @@ static int netdev_ethtool_ioctl(struct net_device *dev, void *useraddr)
struct
ethtool_value
edata
;
struct
ethtool_value
edata
;
if
(
copy_from_user
(
&
edata
,
useraddr
,
sizeof
(
edata
)))
if
(
copy_from_user
(
&
edata
,
useraddr
,
sizeof
(
edata
)))
return
-
EFAULT
;
return
-
EFAULT
;
debug
=
edata
.
data
;
np
->
msg_enable
=
edata
.
data
;
return
0
;
return
0
;
}
}
/* restart autonegotiation */
/* restart autonegotiation */
...
@@ -1941,6 +2036,9 @@ static int netdev_ethtool_ioctl(struct net_device *dev, void *useraddr)
...
@@ -1941,6 +2036,9 @@ static int netdev_ethtool_ioctl(struct net_device *dev, void *useraddr)
if
(
copy_from_user
(
&
eeprom
,
useraddr
,
sizeof
(
eeprom
)))
if
(
copy_from_user
(
&
eeprom
,
useraddr
,
sizeof
(
eeprom
)))
return
-
EFAULT
;
return
-
EFAULT
;
if
(
eeprom
.
offset
>
eeprom
.
offset
+
eeprom
.
len
)
return
-
EINVAL
;
if
((
eeprom
.
offset
+
eeprom
.
len
)
>
NATSEMI_EEPROM_SIZE
)
{
if
((
eeprom
.
offset
+
eeprom
.
len
)
>
NATSEMI_EEPROM_SIZE
)
{
eeprom
.
len
=
NATSEMI_EEPROM_SIZE
-
eeprom
.
offset
;
eeprom
.
len
=
NATSEMI_EEPROM_SIZE
-
eeprom
.
offset
;
}
}
...
@@ -2096,18 +2194,22 @@ static int netdev_get_ecmd(struct net_device *dev, struct ethtool_cmd *ecmd)
...
@@ -2096,18 +2194,22 @@ static int netdev_get_ecmd(struct net_device *dev, struct ethtool_cmd *ecmd)
ecmd
->
supported
=
ecmd
->
supported
=
(
SUPPORTED_10baseT_Half
|
SUPPORTED_10baseT_Full
|
(
SUPPORTED_10baseT_Half
|
SUPPORTED_10baseT_Full
|
SUPPORTED_100baseT_Half
|
SUPPORTED_100baseT_Full
|
SUPPORTED_100baseT_Half
|
SUPPORTED_100baseT_Full
|
SUPPORTED_Autoneg
|
SUPPORTED_TP
);
SUPPORTED_Autoneg
|
SUPPORTED_TP
|
SUPPORTED_MII
);
/* only supports twisted-pair */
/* only supports twisted-pair or MII */
tmp
=
readl
(
dev
->
base_addr
+
ChipConfig
);
if
(
tmp
&
CfgExtPhy
)
ecmd
->
port
=
PORT_MII
;
else
ecmd
->
port
=
PORT_TP
;
ecmd
->
port
=
PORT_TP
;
/* only supports internal transceiver */
/* only supports internal transceiver */
ecmd
->
transceiver
=
XCVR_INTERNAL
;
ecmd
->
transceiver
=
XCVR_INTERNAL
;
/*
this isn't fully supported at higher layers
*/
/*
not sure what this is for
*/
ecmd
->
phy_address
=
readw
(
dev
->
base_addr
+
PhyCtrl
)
&
PhyAddrMask
;
ecmd
->
phy_address
=
readw
(
dev
->
base_addr
+
PhyCtrl
)
&
PhyAddrMask
;
ecmd
->
advertising
=
ADVERTISED_TP
;
ecmd
->
advertising
=
ADVERTISED_TP
|
ADVERTISED_MII
;
tmp
=
mdio_read
(
dev
,
1
,
MII_ADVERTISE
);
tmp
=
mdio_read
(
dev
,
1
,
MII_ADVERTISE
);
if
(
tmp
&
ADVERTISE_10HALF
)
if
(
tmp
&
ADVERTISE_10HALF
)
ecmd
->
advertising
|=
ADVERTISED_10baseT_Half
;
ecmd
->
advertising
|=
ADVERTISED_10baseT_Half
;
...
@@ -2118,14 +2220,15 @@ static int netdev_get_ecmd(struct net_device *dev, struct ethtool_cmd *ecmd)
...
@@ -2118,14 +2220,15 @@ static int netdev_get_ecmd(struct net_device *dev, struct ethtool_cmd *ecmd)
if
(
tmp
&
ADVERTISE_100FULL
)
if
(
tmp
&
ADVERTISE_100FULL
)
ecmd
->
advertising
|=
ADVERTISED_100baseT_Full
;
ecmd
->
advertising
|=
ADVERTISED_100baseT_Full
;
tmp
=
readl
(
dev
->
base_addr
+
ChipConfig
);
tmp
=
mdio_read
(
dev
,
1
,
MII_BMCR
);
if
(
tmp
&
CfgAnegEnable
)
{
if
(
tmp
&
BMCR_ANENABLE
)
{
ecmd
->
advertising
|=
ADVERTISED_Autoneg
;
ecmd
->
advertising
|=
ADVERTISED_Autoneg
;
ecmd
->
autoneg
=
AUTONEG_ENABLE
;
ecmd
->
autoneg
=
AUTONEG_ENABLE
;
}
else
{
}
else
{
ecmd
->
autoneg
=
AUTONEG_DISABLE
;
ecmd
->
autoneg
=
AUTONEG_DISABLE
;
}
}
tmp
=
readl
(
dev
->
base_addr
+
ChipConfig
);
if
(
tmp
&
CfgSpeed100
)
{
if
(
tmp
&
CfgSpeed100
)
{
ecmd
->
speed
=
SPEED_100
;
ecmd
->
speed
=
SPEED_100
;
}
else
{
}
else
{
...
@@ -2152,7 +2255,7 @@ static int netdev_set_ecmd(struct net_device *dev, struct ethtool_cmd *ecmd)
...
@@ -2152,7 +2255,7 @@ static int netdev_set_ecmd(struct net_device *dev, struct ethtool_cmd *ecmd)
return
-
EINVAL
;
return
-
EINVAL
;
if
(
ecmd
->
duplex
!=
DUPLEX_HALF
&&
ecmd
->
duplex
!=
DUPLEX_FULL
)
if
(
ecmd
->
duplex
!=
DUPLEX_HALF
&&
ecmd
->
duplex
!=
DUPLEX_FULL
)
return
-
EINVAL
;
return
-
EINVAL
;
if
(
ecmd
->
port
!=
PORT_TP
)
if
(
ecmd
->
port
!=
PORT_TP
&&
ecmd
->
port
!=
PORT_MII
)
return
-
EINVAL
;
return
-
EINVAL
;
if
(
ecmd
->
transceiver
!=
XCVR_INTERNAL
)
if
(
ecmd
->
transceiver
!=
XCVR_INTERNAL
)
return
-
EINVAL
;
return
-
EINVAL
;
...
@@ -2162,39 +2265,22 @@ static int netdev_set_ecmd(struct net_device *dev, struct ethtool_cmd *ecmd)
...
@@ -2162,39 +2265,22 @@ static int netdev_set_ecmd(struct net_device *dev, struct ethtool_cmd *ecmd)
/* WHEW! now lets bang some bits */
/* WHEW! now lets bang some bits */
if
(
ecmd
->
autoneg
==
AUTONEG_ENABLE
)
{
/* advertise only what has been requested */
tmp
=
readl
(
dev
->
base_addr
+
ChipConfig
);
tmp
&=
~
(
CfgAneg100
|
CfgAnegFull
);
tmp
|=
CfgAnegEnable
;
if
(
ecmd
->
advertising
&
ADVERTISED_100baseT_Half
||
ecmd
->
advertising
&
ADVERTISED_100baseT_Full
)
{
tmp
|=
CfgAneg100
;
}
if
(
ecmd
->
advertising
&
ADVERTISED_10baseT_Full
||
ecmd
->
advertising
&
ADVERTISED_100baseT_Full
)
{
tmp
|=
CfgAnegFull
;
}
writel
(
tmp
,
dev
->
base_addr
+
ChipConfig
);
/* turn on autonegotiation, and force a renegotiate */
tmp
=
mdio_read
(
dev
,
1
,
MII_BMCR
);
tmp
=
mdio_read
(
dev
,
1
,
MII_BMCR
);
tmp
|=
(
BMCR_ANENABLE
|
BMCR_ANRESTART
);
if
(
ecmd
->
autoneg
==
AUTONEG_ENABLE
)
{
mdio_write
(
dev
,
1
,
MII_BMCR
,
tmp
);
/* turn on autonegotiation */
tmp
|=
BMCR_ANENABLE
;
np
->
advertising
=
mdio_read
(
dev
,
1
,
MII_ADVERTISE
);
np
->
advertising
=
mdio_read
(
dev
,
1
,
MII_ADVERTISE
);
}
else
{
}
else
{
/* turn off auto negotiation, set speed and duplexity */
/* turn off auto negotiation, set speed and duplexity */
tmp
=
mdio_read
(
dev
,
1
,
MII_BMCR
);
tmp
&=
~
(
BMCR_ANENABLE
|
BMCR_SPEED100
|
BMCR_FULLDPLX
);
tmp
&=
~
(
BMCR_ANENABLE
|
BMCR_SPEED100
|
BMCR_FULLDPLX
);
if
(
ecmd
->
speed
==
SPEED_100
)
{
if
(
ecmd
->
speed
==
SPEED_100
)
tmp
|=
BMCR_SPEED100
;
tmp
|=
BMCR_SPEED100
;
}
if
(
ecmd
->
duplex
==
DUPLEX_FULL
)
if
(
ecmd
->
duplex
==
DUPLEX_FULL
)
{
tmp
|=
BMCR_FULLDPLX
;
tmp
|=
BMCR_FULLDPLX
;
}
else
{
else
np
->
full_duplex
=
0
;
np
->
full_duplex
=
0
;
}
}
mdio_write
(
dev
,
1
,
MII_BMCR
,
tmp
);
mdio_write
(
dev
,
1
,
MII_BMCR
,
tmp
);
}
return
0
;
return
0
;
}
}
...
@@ -2229,7 +2315,7 @@ static int netdev_get_regs(struct net_device *dev, u8 *buf)
...
@@ -2229,7 +2315,7 @@ static int netdev_get_regs(struct net_device *dev, u8 *buf)
/* the interrupt status is clear-on-read - see if we missed any */
/* the interrupt status is clear-on-read - see if we missed any */
if
(
rbuf
[
4
]
&
rbuf
[
5
])
{
if
(
rbuf
[
4
]
&
rbuf
[
5
])
{
printk
(
KERN_WARNING
printk
(
KERN_WARNING
"%s: shoot, we dropped an interrupt (
0x%
x)
\n
"
,
"%s: shoot, we dropped an interrupt (
%#08
x)
\n
"
,
dev
->
name
,
rbuf
[
4
]
&
rbuf
[
5
]);
dev
->
name
,
rbuf
[
4
]
&
rbuf
[
5
]);
}
}
...
@@ -2296,7 +2382,7 @@ static void enable_wol_mode(struct net_device *dev, int enable_intr)
...
@@ -2296,7 +2382,7 @@ static void enable_wol_mode(struct net_device *dev, int enable_intr)
long
ioaddr
=
dev
->
base_addr
;
long
ioaddr
=
dev
->
base_addr
;
struct
netdev_private
*
np
=
dev
->
priv
;
struct
netdev_private
*
np
=
dev
->
priv
;
if
(
debug
>
1
)
if
(
netif_msg_wol
(
np
)
)
printk
(
KERN_INFO
"%s: remaining active for wake-on-lan
\n
"
,
printk
(
KERN_INFO
"%s: remaining active for wake-on-lan
\n
"
,
dev
->
name
);
dev
->
name
);
...
@@ -2319,7 +2405,8 @@ static void enable_wol_mode(struct net_device *dev, int enable_intr)
...
@@ -2319,7 +2405,8 @@ static void enable_wol_mode(struct net_device *dev, int enable_intr)
/* enable the WOL interrupt.
/* enable the WOL interrupt.
* Could be used to send a netlink message.
* Could be used to send a netlink message.
*/
*/
writel
(
readl
(
ioaddr
+
IntrMask
)
|
WOLPkt
,
ioaddr
+
IntrMask
);
writel
(
WOLPkt
|
LinkChange
,
ioaddr
+
IntrMask
);
writel
(
1
,
ioaddr
+
IntrEnable
);
}
}
}
}
...
@@ -2331,12 +2418,15 @@ static int netdev_close(struct net_device *dev)
...
@@ -2331,12 +2418,15 @@ static int netdev_close(struct net_device *dev)
netif_stop_queue
(
dev
);
netif_stop_queue
(
dev
);
netif_carrier_off
(
dev
);
netif_carrier_off
(
dev
);
if
(
debug
>
1
)
{
if
(
netif_msg_ifdown
(
np
))
printk
(
KERN_DEBUG
"%s: Shutting down ethercard, status was %4.4x.
\n
"
,
printk
(
KERN_DEBUG
"%s: Shutting down ethercard, status was %#04x.
\n
"
,
dev
->
name
,
(
int
)
readl
(
ioaddr
+
ChipCmd
));
dev
->
name
,
(
int
)
readl
(
ioaddr
+
ChipCmd
));
printk
(
KERN_DEBUG
"%s: Queue pointers were Tx %d / %d, Rx %d / %d.
\n
"
,
if
(
netif_msg_pktdata
(
np
))
dev
->
name
,
np
->
cur_tx
,
np
->
dirty_tx
,
np
->
cur_rx
,
np
->
dirty_rx
);
printk
(
KERN_DEBUG
}
"%s: Queue pointers were Tx %d / %d, Rx %d / %d.
\n
"
,
dev
->
name
,
np
->
cur_tx
,
np
->
dirty_tx
,
np
->
cur_rx
,
np
->
dirty_rx
);
del_timer_sync
(
&
np
->
timer
);
del_timer_sync
(
&
np
->
timer
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment