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
3af5b745
Commit
3af5b745
authored
Dec 26, 2004
by
Jeff Garzik
Browse files
Options
Browse Files
Download
Plain Diff
Merge pobox.com:/garz/repo/netdev-2.6/via-rhine
into pobox.com:/garz/repo/net-drivers-2.6
parents
25d477da
182181d0
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
143 additions
and
147 deletions
+143
-147
drivers/net/via-rhine.c
drivers/net/via-rhine.c
+143
-147
No files found.
drivers/net/via-rhine.c
View file @
3af5b745
...
...
@@ -177,6 +177,7 @@ static const int multicast_filter_limit = 32;
#define PKT_BUF_SZ 1536
/* Size of each temporary Rx buffer.*/
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/timer.h>
...
...
@@ -208,27 +209,15 @@ KERN_INFO DRV_NAME ".c:v1.10-LK" DRV_VERSION " " DRV_RELDATE " Written by Donald
#ifdef CONFIG_VIA_RHINE_MMIO
#define USE_MMIO
#else
#undef readb
#undef readw
#undef readl
#undef writeb
#undef writew
#undef writel
#define readb inb
#define readw inw
#define readl inl
#define writeb outb
#define writew outw
#define writel outl
#endif
MODULE_AUTHOR
(
"Donald Becker <becker@scyld.com>"
);
MODULE_DESCRIPTION
(
"VIA Rhine PCI Fast Ethernet driver"
);
MODULE_LICENSE
(
"GPL"
);
MODULE_PARM
(
max_interrupt_work
,
"i"
);
MODULE_PARM
(
debug
,
"i"
);
MODULE_PARM
(
rx_copybreak
,
"i"
);
module_param
(
max_interrupt_work
,
int
,
0
);
module_param
(
debug
,
int
,
0
);
module_param
(
rx_copybreak
,
int
,
0
);
MODULE_PARM_DESC
(
max_interrupt_work
,
"VIA Rhine maximum events handled per interrupt"
);
MODULE_PARM_DESC
(
debug
,
"VIA Rhine debug level (0-7)"
);
MODULE_PARM_DESC
(
rx_copybreak
,
"VIA Rhine copy breakpoint for copy-only-tiny-frames"
);
...
...
@@ -363,7 +352,7 @@ enum rhine_quirks {
*/
/* Beware of PCI posted writes */
#define IOSYNC do {
readb(dev->base_
addr + StationAddr); } while (0)
#define IOSYNC do {
ioread8(io
addr + StationAddr); } while (0)
static
struct
pci_device_id
rhine_pci_tbl
[]
=
{
...
...
@@ -500,6 +489,7 @@ struct rhine_private {
u8
tx_thresh
,
rx_thresh
;
struct
mii_if_info
mii_if
;
void
__iomem
*
base
;
};
static
int
mdio_read
(
struct
net_device
*
dev
,
int
phy_id
,
int
location
);
...
...
@@ -529,14 +519,14 @@ static void rhine_shutdown (struct device *gdev);
static
inline
u32
get_intr_status
(
struct
net_device
*
dev
)
{
long
ioaddr
=
dev
->
base_addr
;
struct
rhine_private
*
rp
=
netdev_priv
(
dev
);
void
__iomem
*
ioaddr
=
rp
->
base
;
u32
intr_status
;
intr_status
=
readw
(
ioaddr
+
IntrStatus
);
intr_status
=
ioread16
(
ioaddr
+
IntrStatus
);
/* On Rhine-II, Bit 3 indicates Tx descriptor write-back race. */
if
(
rp
->
quirks
&
rqStatusWBRace
)
intr_status
|=
readb
(
ioaddr
+
IntrStatus2
)
<<
16
;
intr_status
|=
ioread8
(
ioaddr
+
IntrStatus2
)
<<
16
;
return
intr_status
;
}
...
...
@@ -546,32 +536,32 @@ static inline u32 get_intr_status(struct net_device *dev)
*/
static
void
rhine_power_init
(
struct
net_device
*
dev
)
{
long
ioaddr
=
dev
->
base_addr
;
struct
rhine_private
*
rp
=
netdev_priv
(
dev
);
void
__iomem
*
ioaddr
=
rp
->
base
;
u16
wolstat
;
if
(
rp
->
quirks
&
rqWOL
)
{
/* Make sure chip is in power state D0 */
writeb
(
readb
(
ioaddr
+
StickyHW
)
&
0xFC
,
ioaddr
+
StickyHW
);
iowrite8
(
ioread8
(
ioaddr
+
StickyHW
)
&
0xFC
,
ioaddr
+
StickyHW
);
/* Disable "force PME-enable" */
writeb
(
0x80
,
ioaddr
+
WOLcgClr
);
iowrite8
(
0x80
,
ioaddr
+
WOLcgClr
);
/* Clear power-event config bits (WOL) */
writeb
(
0xFF
,
ioaddr
+
WOLcrClr
);
iowrite8
(
0xFF
,
ioaddr
+
WOLcrClr
);
/* More recent cards can manage two additional patterns */
if
(
rp
->
quirks
&
rq6patterns
)
writeb
(
0x03
,
ioaddr
+
WOLcrClr1
);
iowrite8
(
0x03
,
ioaddr
+
WOLcrClr1
);
/* Save power-event status bits */
wolstat
=
readb
(
ioaddr
+
PwrcsrSet
);
wolstat
=
ioread8
(
ioaddr
+
PwrcsrSet
);
if
(
rp
->
quirks
&
rq6patterns
)
wolstat
|=
(
readb
(
ioaddr
+
PwrcsrSet1
)
&
0x03
)
<<
8
;
wolstat
|=
(
ioread8
(
ioaddr
+
PwrcsrSet1
)
&
0x03
)
<<
8
;
/* Clear power-event status bits */
writeb
(
0xFF
,
ioaddr
+
PwrcsrClr
);
iowrite8
(
0xFF
,
ioaddr
+
PwrcsrClr
);
if
(
rp
->
quirks
&
rq6patterns
)
writeb
(
0x03
,
ioaddr
+
PwrcsrClr1
);
iowrite8
(
0x03
,
ioaddr
+
PwrcsrClr1
);
if
(
wolstat
)
{
char
*
reason
;
...
...
@@ -602,27 +592,27 @@ static void rhine_power_init(struct net_device *dev)
static
void
rhine_chip_reset
(
struct
net_device
*
dev
)
{
long
ioaddr
=
dev
->
base_addr
;
struct
rhine_private
*
rp
=
netdev_priv
(
dev
);
void
__iomem
*
ioaddr
=
rp
->
base
;
writeb
(
Cmd1Reset
,
ioaddr
+
ChipCmd1
);
iowrite8
(
Cmd1Reset
,
ioaddr
+
ChipCmd1
);
IOSYNC
;
if
(
readb
(
ioaddr
+
ChipCmd1
)
&
Cmd1Reset
)
{
if
(
ioread8
(
ioaddr
+
ChipCmd1
)
&
Cmd1Reset
)
{
printk
(
KERN_INFO
"%s: Reset not complete yet. "
"Trying harder.
\n
"
,
DRV_NAME
);
/* Force reset */
if
(
rp
->
quirks
&
rqForceReset
)
writeb
(
0x40
,
ioaddr
+
MiscCmd
);
iowrite8
(
0x40
,
ioaddr
+
MiscCmd
);
/* Reset can take somewhat longer (rare) */
RHINE_WAIT_FOR
(
!
(
readb
(
ioaddr
+
ChipCmd1
)
&
Cmd1Reset
));
RHINE_WAIT_FOR
(
!
(
ioread8
(
ioaddr
+
ChipCmd1
)
&
Cmd1Reset
));
}
if
(
debug
>
1
)
printk
(
KERN_INFO
"%s: Reset %s.
\n
"
,
dev
->
name
,
(
readb
(
ioaddr
+
ChipCmd1
)
&
Cmd1Reset
)
?
(
ioread8
(
ioaddr
+
ChipCmd1
)
&
Cmd1Reset
)
?
"failed"
:
"succeeded"
);
}
...
...
@@ -647,8 +637,8 @@ static void enable_mmio(long pioaddr, u32 quirks)
*/
static
void
__devinit
rhine_reload_eeprom
(
long
pioaddr
,
struct
net_device
*
dev
)
{
long
ioaddr
=
dev
->
base_addr
;
struct
rhine_private
*
rp
=
netdev_priv
(
dev
);
void
__iomem
*
ioaddr
=
rp
->
base
;
outb
(
0x20
,
pioaddr
+
MACRegEEcsr
);
RHINE_WAIT_FOR
(
!
(
inb
(
pioaddr
+
MACRegEEcsr
)
&
0x20
));
...
...
@@ -664,7 +654,7 @@ static void __devinit rhine_reload_eeprom(long pioaddr, struct net_device *dev)
/* Turn off EEPROM-controlled wake-up (magic packet) */
if
(
rp
->
quirks
&
rqWOL
)
writeb
(
readb
(
ioaddr
+
ConfigA
)
&
0xFE
,
ioaddr
+
ConfigA
);
iowrite8
(
ioread8
(
ioaddr
+
ConfigA
)
&
0xFC
,
ioaddr
+
ConfigA
);
}
...
...
@@ -702,9 +692,14 @@ static int __devinit rhine_init_one(struct pci_dev *pdev,
u32
quirks
;
long
pioaddr
;
long
memaddr
;
long
ioaddr
;
void
__iomem
*
ioaddr
;
int
io_size
,
phy_id
;
const
char
*
name
;
#ifdef USE_MMIO
int
bar
=
1
;
#else
int
bar
=
0
;
#endif
/* when built into the kernel, we only print version if device is found */
#ifndef MODULE
...
...
@@ -783,10 +778,7 @@ static int __devinit rhine_init_one(struct pci_dev *pdev,
if
(
rc
)
goto
err_out_free_netdev
;
#ifdef USE_MMIO
enable_mmio
(
pioaddr
,
quirks
);
ioaddr
=
(
long
)
ioremap
(
memaddr
,
io_size
);
ioaddr
=
pci_iomap
(
pdev
,
bar
,
io_size
);
if
(
!
ioaddr
)
{
rc
=
-
EIO
;
printk
(
KERN_ERR
"ioremap failed for device %s, region 0x%X "
...
...
@@ -794,6 +786,9 @@ static int __devinit rhine_init_one(struct pci_dev *pdev,
goto
err_out_free_res
;
}
#ifdef USE_MMIO
enable_mmio
(
pioaddr
,
quirks
);
/* Check that selected MMIO registers match the PIO ones */
i
=
0
;
while
(
mmio_verify_registers
[
i
])
{
...
...
@@ -807,18 +802,17 @@ static int __devinit rhine_init_one(struct pci_dev *pdev,
goto
err_out_unmap
;
}
}
#else
ioaddr
=
pioaddr
;
#endif
/* USE_MMIO */
dev
->
base_addr
=
ioaddr
;
dev
->
base_addr
=
(
unsigned
long
)
ioaddr
;
rp
->
base
=
ioaddr
;
/* Get chip registers into a sane state */
rhine_power_init
(
dev
);
rhine_hw_init
(
dev
,
pioaddr
);
for
(
i
=
0
;
i
<
6
;
i
++
)
dev
->
dev_addr
[
i
]
=
readb
(
ioaddr
+
StationAddr
+
i
);
dev
->
dev_addr
[
i
]
=
ioread8
(
ioaddr
+
StationAddr
+
i
);
if
(
!
is_valid_ether_addr
(
dev
->
dev_addr
))
{
rc
=
-
EIO
;
...
...
@@ -828,7 +822,7 @@ static int __devinit rhine_init_one(struct pci_dev *pdev,
/* For Rhine-I/II, phy_id is loaded from EEPROM */
if
(
!
phy_id
)
phy_id
=
readb
(
ioaddr
+
0x6C
);
phy_id
=
ioread8
(
ioaddr
+
0x6C
);
dev
->
irq
=
pdev
->
irq
;
...
...
@@ -901,10 +895,8 @@ static int __devinit rhine_init_one(struct pci_dev *pdev,
return
0
;
err_out_unmap:
#ifdef USE_MMIO
iounmap
((
void
*
)
ioaddr
);
pci_iounmap
(
pdev
,
ioaddr
);
err_out_free_res:
#endif
pci_release_regions
(
pdev
);
err_out_free_netdev:
free_netdev
(
dev
);
...
...
@@ -947,7 +939,7 @@ static int alloc_ring(struct net_device* dev)
return
0
;
}
void
free_ring
(
struct
net_device
*
dev
)
static
void
free_ring
(
struct
net_device
*
dev
)
{
struct
rhine_private
*
rp
=
netdev_priv
(
dev
);
...
...
@@ -1071,102 +1063,102 @@ static void free_tbufs(struct net_device* dev)
static
void
rhine_check_media
(
struct
net_device
*
dev
,
unsigned
int
init_media
)
{
struct
rhine_private
*
rp
=
netdev_priv
(
dev
);
long
ioaddr
=
dev
->
base_addr
;
void
__iomem
*
ioaddr
=
rp
->
base
;
mii_check_media
(
&
rp
->
mii_if
,
debug
,
init_media
);
if
(
rp
->
mii_if
.
full_duplex
)
writeb
(
readb
(
ioaddr
+
ChipCmd1
)
|
Cmd1FDuplex
,
iowrite8
(
ioread8
(
ioaddr
+
ChipCmd1
)
|
Cmd1FDuplex
,
ioaddr
+
ChipCmd1
);
else
writeb
(
readb
(
ioaddr
+
ChipCmd1
)
&
~
Cmd1FDuplex
,
iowrite8
(
ioread8
(
ioaddr
+
ChipCmd1
)
&
~
Cmd1FDuplex
,
ioaddr
+
ChipCmd1
);
}
static
void
init_registers
(
struct
net_device
*
dev
)
{
struct
rhine_private
*
rp
=
netdev_priv
(
dev
);
long
ioaddr
=
dev
->
base_addr
;
void
__iomem
*
ioaddr
=
rp
->
base
;
int
i
;
for
(
i
=
0
;
i
<
6
;
i
++
)
writeb
(
dev
->
dev_addr
[
i
],
ioaddr
+
StationAddr
+
i
);
iowrite8
(
dev
->
dev_addr
[
i
],
ioaddr
+
StationAddr
+
i
);
/* Initialize other registers. */
writew
(
0x0006
,
ioaddr
+
PCIBusConfig
);
/* Tune configuration??? */
iowrite16
(
0x0006
,
ioaddr
+
PCIBusConfig
);
/* Tune configuration??? */
/* Configure initial FIFO thresholds. */
writeb
(
0x20
,
ioaddr
+
TxConfig
);
iowrite8
(
0x20
,
ioaddr
+
TxConfig
);
rp
->
tx_thresh
=
0x20
;
rp
->
rx_thresh
=
0x60
;
/* Written in rhine_set_rx_mode(). */
writel
(
rp
->
rx_ring_dma
,
ioaddr
+
RxRingPtr
);
writel
(
rp
->
tx_ring_dma
,
ioaddr
+
TxRingPtr
);
iowrite32
(
rp
->
rx_ring_dma
,
ioaddr
+
RxRingPtr
);
iowrite32
(
rp
->
tx_ring_dma
,
ioaddr
+
TxRingPtr
);
rhine_set_rx_mode
(
dev
);
/* Enable interrupts by setting the interrupt mask. */
writew
(
IntrRxDone
|
IntrRxErr
|
IntrRxEmpty
|
IntrRxOverflow
|
iowrite16
(
IntrRxDone
|
IntrRxErr
|
IntrRxEmpty
|
IntrRxOverflow
|
IntrRxDropped
|
IntrRxNoBuf
|
IntrTxAborted
|
IntrTxDone
|
IntrTxError
|
IntrTxUnderrun
|
IntrPCIErr
|
IntrStatsMax
|
IntrLinkChange
,
ioaddr
+
IntrEnable
);
writew
(
CmdStart
|
CmdTxOn
|
CmdRxOn
|
(
Cmd1NoTxPoll
<<
8
),
iowrite16
(
CmdStart
|
CmdTxOn
|
CmdRxOn
|
(
Cmd1NoTxPoll
<<
8
),
ioaddr
+
ChipCmd
);
rhine_check_media
(
dev
,
1
);
}
/* Enable MII link status auto-polling (required for IntrLinkChange) */
static
void
rhine_enable_linkmon
(
long
ioaddr
)
static
void
rhine_enable_linkmon
(
void
__iomem
*
ioaddr
)
{
writeb
(
0
,
ioaddr
+
MIICmd
);
writeb
(
MII_BMSR
,
ioaddr
+
MIIRegAddr
);
writeb
(
0x80
,
ioaddr
+
MIICmd
);
iowrite8
(
0
,
ioaddr
+
MIICmd
);
iowrite8
(
MII_BMSR
,
ioaddr
+
MIIRegAddr
);
iowrite8
(
0x80
,
ioaddr
+
MIICmd
);
RHINE_WAIT_FOR
((
readb
(
ioaddr
+
MIIRegAddr
)
&
0x20
));
RHINE_WAIT_FOR
((
ioread8
(
ioaddr
+
MIIRegAddr
)
&
0x20
));
writeb
(
MII_BMSR
|
0x40
,
ioaddr
+
MIIRegAddr
);
iowrite8
(
MII_BMSR
|
0x40
,
ioaddr
+
MIIRegAddr
);
}
/* Disable MII link status auto-polling (required for MDIO access) */
static
void
rhine_disable_linkmon
(
long
ioaddr
,
u32
quirks
)
static
void
rhine_disable_linkmon
(
void
__iomem
*
ioaddr
,
u32
quirks
)
{
writeb
(
0
,
ioaddr
+
MIICmd
);
iowrite8
(
0
,
ioaddr
+
MIICmd
);
if
(
quirks
&
rqRhineI
)
{
writeb
(
0x01
,
ioaddr
+
MIIRegAddr
);
// MII_BMSR
iowrite8
(
0x01
,
ioaddr
+
MIIRegAddr
);
// MII_BMSR
/* Can be called from ISR. Evil. */
mdelay
(
1
);
/* 0x80 must be set immediately before turning it off */
writeb
(
0x80
,
ioaddr
+
MIICmd
);
iowrite8
(
0x80
,
ioaddr
+
MIICmd
);
RHINE_WAIT_FOR
(
readb
(
ioaddr
+
MIIRegAddr
)
&
0x20
);
RHINE_WAIT_FOR
(
ioread8
(
ioaddr
+
MIIRegAddr
)
&
0x20
);
/* Heh. Now clear 0x80 again. */
writeb
(
0
,
ioaddr
+
MIICmd
);
iowrite8
(
0
,
ioaddr
+
MIICmd
);
}
else
RHINE_WAIT_FOR
(
readb
(
ioaddr
+
MIIRegAddr
)
&
0x80
);
RHINE_WAIT_FOR
(
ioread8
(
ioaddr
+
MIIRegAddr
)
&
0x80
);
}
/* Read and write over the MII Management Data I/O (MDIO) interface. */
static
int
mdio_read
(
struct
net_device
*
dev
,
int
phy_id
,
int
regnum
)
{
long
ioaddr
=
dev
->
base_addr
;
struct
rhine_private
*
rp
=
netdev_priv
(
dev
);
void
__iomem
*
ioaddr
=
rp
->
base
;
int
result
;
rhine_disable_linkmon
(
ioaddr
,
rp
->
quirks
);
/* rhine_disable_linkmon already cleared MIICmd */
writeb
(
phy_id
,
ioaddr
+
MIIPhyAddr
);
writeb
(
regnum
,
ioaddr
+
MIIRegAddr
);
writeb
(
0x40
,
ioaddr
+
MIICmd
);
/* Trigger read */
RHINE_WAIT_FOR
(
!
(
readb
(
ioaddr
+
MIICmd
)
&
0x40
));
result
=
readw
(
ioaddr
+
MIIData
);
iowrite8
(
phy_id
,
ioaddr
+
MIIPhyAddr
);
iowrite8
(
regnum
,
ioaddr
+
MIIRegAddr
);
iowrite8
(
0x40
,
ioaddr
+
MIICmd
);
/* Trigger read */
RHINE_WAIT_FOR
(
!
(
ioread8
(
ioaddr
+
MIICmd
)
&
0x40
));
result
=
ioread16
(
ioaddr
+
MIIData
);
rhine_enable_linkmon
(
ioaddr
);
return
result
;
...
...
@@ -1175,16 +1167,16 @@ static int mdio_read(struct net_device *dev, int phy_id, int regnum)
static
void
mdio_write
(
struct
net_device
*
dev
,
int
phy_id
,
int
regnum
,
int
value
)
{
struct
rhine_private
*
rp
=
netdev_priv
(
dev
);
long
ioaddr
=
dev
->
base_addr
;
void
__iomem
*
ioaddr
=
rp
->
base
;
rhine_disable_linkmon
(
ioaddr
,
rp
->
quirks
);
/* rhine_disable_linkmon already cleared MIICmd */
writeb
(
phy_id
,
ioaddr
+
MIIPhyAddr
);
writeb
(
regnum
,
ioaddr
+
MIIRegAddr
);
writew
(
value
,
ioaddr
+
MIIData
);
writeb
(
0x20
,
ioaddr
+
MIICmd
);
/* Trigger write */
RHINE_WAIT_FOR
(
!
(
readb
(
ioaddr
+
MIICmd
)
&
0x20
));
iowrite8
(
phy_id
,
ioaddr
+
MIIPhyAddr
);
iowrite8
(
regnum
,
ioaddr
+
MIIRegAddr
);
iowrite16
(
value
,
ioaddr
+
MIIData
);
iowrite8
(
0x20
,
ioaddr
+
MIICmd
);
/* Trigger write */
RHINE_WAIT_FOR
(
!
(
ioread8
(
ioaddr
+
MIICmd
)
&
0x20
));
rhine_enable_linkmon
(
ioaddr
);
}
...
...
@@ -1192,7 +1184,7 @@ static void mdio_write(struct net_device *dev, int phy_id, int regnum, int value
static
int
rhine_open
(
struct
net_device
*
dev
)
{
struct
rhine_private
*
rp
=
netdev_priv
(
dev
);
long
ioaddr
=
dev
->
base_addr
;
void
__iomem
*
ioaddr
=
rp
->
base
;
int
rc
;
rc
=
request_irq
(
rp
->
pdev
->
irq
,
&
rhine_interrupt
,
SA_SHIRQ
,
dev
->
name
,
...
...
@@ -1214,7 +1206,7 @@ static int rhine_open(struct net_device *dev)
if
(
debug
>
2
)
printk
(
KERN_DEBUG
"%s: Done rhine_open(), status %4.4x "
"MII status: %4.4x.
\n
"
,
dev
->
name
,
readw
(
ioaddr
+
ChipCmd
),
dev
->
name
,
ioread16
(
ioaddr
+
ChipCmd
),
mdio_read
(
dev
,
rp
->
mii_if
.
phy_id
,
MII_BMSR
));
netif_start_queue
(
dev
);
...
...
@@ -1225,11 +1217,11 @@ static int rhine_open(struct net_device *dev)
static
void
rhine_tx_timeout
(
struct
net_device
*
dev
)
{
struct
rhine_private
*
rp
=
netdev_priv
(
dev
);
long
ioaddr
=
dev
->
base_addr
;
void
__iomem
*
ioaddr
=
rp
->
base
;
printk
(
KERN_WARNING
"%s: Transmit timed out, status %4.4x, PHY status "
"%4.4x, resetting...
\n
"
,
dev
->
name
,
readw
(
ioaddr
+
IntrStatus
),
dev
->
name
,
ioread16
(
ioaddr
+
IntrStatus
),
mdio_read
(
dev
,
rp
->
mii_if
.
phy_id
,
MII_BMSR
));
/* protect against concurrent rx interrupts */
...
...
@@ -1258,7 +1250,7 @@ static void rhine_tx_timeout(struct net_device *dev)
static
int
rhine_start_tx
(
struct
sk_buff
*
skb
,
struct
net_device
*
dev
)
{
struct
rhine_private
*
rp
=
netdev_priv
(
dev
);
long
ioaddr
=
dev
->
base_addr
;
void
__iomem
*
ioaddr
=
rp
->
base
;
unsigned
entry
;
/* Caution: the write order is important here, set the field
...
...
@@ -1276,7 +1268,7 @@ static int rhine_start_tx(struct sk_buff *skb, struct net_device *dev)
rp
->
tx_skbuff
[
entry
]
=
skb
;
if
((
rp
->
quirks
&
rqRhineI
)
&&
(((
long
)
skb
->
data
&
3
)
||
skb_shinfo
(
skb
)
->
nr_frags
!=
0
||
skb
->
ip_summed
==
CHECKSUM_HW
))
{
(((
unsigned
long
)
skb
->
data
&
3
)
||
skb_shinfo
(
skb
)
->
nr_frags
!=
0
||
skb
->
ip_summed
==
CHECKSUM_HW
))
{
/* Must use alignment buffer. */
if
(
skb
->
len
>
PKT_BUF_SZ
)
{
/* packet too long, drop it */
...
...
@@ -1311,7 +1303,7 @@ static int rhine_start_tx(struct sk_buff *skb, struct net_device *dev)
/* Non-x86 Todo: explicitly flush cache lines here. */
/* Wake the potentially-idle transmit channel */
writeb
(
readb
(
ioaddr
+
ChipCmd1
)
|
Cmd1TxDemand
,
iowrite8
(
ioread8
(
ioaddr
+
ChipCmd1
)
|
Cmd1TxDemand
,
ioaddr
+
ChipCmd1
);
IOSYNC
;
...
...
@@ -1334,20 +1326,19 @@ static int rhine_start_tx(struct sk_buff *skb, struct net_device *dev)
static
irqreturn_t
rhine_interrupt
(
int
irq
,
void
*
dev_instance
,
struct
pt_regs
*
rgs
)
{
struct
net_device
*
dev
=
dev_instance
;
long
ioaddr
;
struct
rhine_private
*
rp
=
netdev_priv
(
dev
);
void
__iomem
*
ioaddr
=
rp
->
base
;
u32
intr_status
;
int
boguscnt
=
max_interrupt_work
;
int
handled
=
0
;
ioaddr
=
dev
->
base_addr
;
while
((
intr_status
=
get_intr_status
(
dev
)))
{
handled
=
1
;
/* Acknowledge all of the current interrupt sources ASAP. */
if
(
intr_status
&
IntrTxDescRace
)
writeb
(
0x08
,
ioaddr
+
IntrStatus2
);
writew
(
intr_status
&
0xffff
,
ioaddr
+
IntrStatus
);
iowrite8
(
0x08
,
ioaddr
+
IntrStatus2
);
iowrite16
(
intr_status
&
0xffff
,
ioaddr
+
IntrStatus
);
IOSYNC
;
if
(
debug
>
4
)
...
...
@@ -1361,9 +1352,9 @@ static irqreturn_t rhine_interrupt(int irq, void *dev_instance, struct pt_regs *
if
(
intr_status
&
(
IntrTxErrSummary
|
IntrTxDone
))
{
if
(
intr_status
&
IntrTxErrSummary
)
{
/* Avoid scavenging before Tx engine turned off */
RHINE_WAIT_FOR
(
!
(
readb
(
ioaddr
+
ChipCmd
)
&
CmdTxOn
));
RHINE_WAIT_FOR
(
!
(
ioread8
(
ioaddr
+
ChipCmd
)
&
CmdTxOn
));
if
(
debug
>
2
&&
readb
(
ioaddr
+
ChipCmd
)
&
CmdTxOn
)
ioread8
(
ioaddr
+
ChipCmd
)
&
CmdTxOn
)
printk
(
KERN_WARNING
"%s: "
"rhine_interrupt() Tx engine"
"still on.
\n
"
,
dev
->
name
);
...
...
@@ -1387,7 +1378,7 @@ static irqreturn_t rhine_interrupt(int irq, void *dev_instance, struct pt_regs *
if
(
debug
>
3
)
printk
(
KERN_DEBUG
"%s: exiting interrupt, status=%8.8x.
\n
"
,
dev
->
name
,
readw
(
ioaddr
+
IntrStatus
));
dev
->
name
,
ioread16
(
ioaddr
+
IntrStatus
));
return
IRQ_RETVAL
(
handled
);
}
...
...
@@ -1582,16 +1573,16 @@ static void rhine_rx(struct net_device *dev)
* these, for others the counters are set to 1 when written to and
* instead cleared when read. So we clear them both ways ...
*/
static
inline
void
clear_tally_counters
(
const
long
ioaddr
)
static
inline
void
clear_tally_counters
(
void
__iomem
*
ioaddr
)
{
writel
(
0
,
ioaddr
+
RxMissed
);
readw
(
ioaddr
+
RxCRCErrs
);
readw
(
ioaddr
+
RxMissed
);
iowrite32
(
0
,
ioaddr
+
RxMissed
);
ioread16
(
ioaddr
+
RxCRCErrs
);
ioread16
(
ioaddr
+
RxMissed
);
}
static
void
rhine_restart_tx
(
struct
net_device
*
dev
)
{
struct
rhine_private
*
rp
=
netdev_priv
(
dev
);
long
ioaddr
=
dev
->
base_addr
;
void
__iomem
*
ioaddr
=
rp
->
base
;
int
entry
=
rp
->
dirty_tx
%
TX_RING_SIZE
;
u32
intr_status
;
...
...
@@ -1604,12 +1595,12 @@ static void rhine_restart_tx(struct net_device *dev) {
if
((
intr_status
&
IntrTxErrSummary
)
==
0
)
{
/* We know better than the chip where it should continue. */
writel
(
rp
->
tx_ring_dma
+
entry
*
sizeof
(
struct
tx_desc
),
iowrite32
(
rp
->
tx_ring_dma
+
entry
*
sizeof
(
struct
tx_desc
),
ioaddr
+
TxRingPtr
);
writeb
(
readb
(
ioaddr
+
ChipCmd
)
|
CmdTxOn
,
iowrite8
(
ioread8
(
ioaddr
+
ChipCmd
)
|
CmdTxOn
,
ioaddr
+
ChipCmd
);
writeb
(
readb
(
ioaddr
+
ChipCmd1
)
|
Cmd1TxDemand
,
iowrite8
(
ioread8
(
ioaddr
+
ChipCmd1
)
|
Cmd1TxDemand
,
ioaddr
+
ChipCmd1
);
IOSYNC
;
}
...
...
@@ -1626,15 +1617,15 @@ static void rhine_restart_tx(struct net_device *dev) {
static
void
rhine_error
(
struct
net_device
*
dev
,
int
intr_status
)
{
struct
rhine_private
*
rp
=
netdev_priv
(
dev
);
long
ioaddr
=
dev
->
base_addr
;
void
__iomem
*
ioaddr
=
rp
->
base
;
spin_lock
(
&
rp
->
lock
);
if
(
intr_status
&
IntrLinkChange
)
rhine_check_media
(
dev
,
0
);
if
(
intr_status
&
IntrStatsMax
)
{
rp
->
stats
.
rx_crc_errors
+=
readw
(
ioaddr
+
RxCRCErrs
);
rp
->
stats
.
rx_missed_errors
+=
readw
(
ioaddr
+
RxMissed
);
rp
->
stats
.
rx_crc_errors
+=
ioread16
(
ioaddr
+
RxCRCErrs
);
rp
->
stats
.
rx_missed_errors
+=
ioread16
(
ioaddr
+
RxMissed
);
clear_tally_counters
(
ioaddr
);
}
if
(
intr_status
&
IntrTxAborted
)
{
...
...
@@ -1644,7 +1635,7 @@ static void rhine_error(struct net_device *dev, int intr_status)
}
if
(
intr_status
&
IntrTxUnderrun
)
{
if
(
rp
->
tx_thresh
<
0xE0
)
writeb
(
rp
->
tx_thresh
+=
0x20
,
ioaddr
+
TxConfig
);
iowrite8
(
rp
->
tx_thresh
+=
0x20
,
ioaddr
+
TxConfig
);
if
(
debug
>
1
)
printk
(
KERN_INFO
"%s: Transmitter underrun, Tx "
"threshold now %2.2x.
\n
"
,
...
...
@@ -1659,7 +1650,7 @@ static void rhine_error(struct net_device *dev, int intr_status)
(
intr_status
&
(
IntrTxAborted
|
IntrTxUnderrun
|
IntrTxDescRace
))
==
0
)
{
if
(
rp
->
tx_thresh
<
0xE0
)
{
writeb
(
rp
->
tx_thresh
+=
0x20
,
ioaddr
+
TxConfig
);
iowrite8
(
rp
->
tx_thresh
+=
0x20
,
ioaddr
+
TxConfig
);
}
if
(
debug
>
1
)
printk
(
KERN_INFO
"%s: Unspecified error. Tx "
...
...
@@ -1684,12 +1675,12 @@ static void rhine_error(struct net_device *dev, int intr_status)
static
struct
net_device_stats
*
rhine_get_stats
(
struct
net_device
*
dev
)
{
struct
rhine_private
*
rp
=
netdev_priv
(
dev
);
long
ioaddr
=
dev
->
base_addr
;
void
__iomem
*
ioaddr
=
rp
->
base
;
unsigned
long
flags
;
spin_lock_irqsave
(
&
rp
->
lock
,
flags
);
rp
->
stats
.
rx_crc_errors
+=
readw
(
ioaddr
+
RxCRCErrs
);
rp
->
stats
.
rx_missed_errors
+=
readw
(
ioaddr
+
RxMissed
);
rp
->
stats
.
rx_crc_errors
+=
ioread16
(
ioaddr
+
RxCRCErrs
);
rp
->
stats
.
rx_missed_errors
+=
ioread16
(
ioaddr
+
RxMissed
);
clear_tally_counters
(
ioaddr
);
spin_unlock_irqrestore
(
&
rp
->
lock
,
flags
);
...
...
@@ -1699,7 +1690,7 @@ static struct net_device_stats *rhine_get_stats(struct net_device *dev)
static
void
rhine_set_rx_mode
(
struct
net_device
*
dev
)
{
struct
rhine_private
*
rp
=
netdev_priv
(
dev
);
long
ioaddr
=
dev
->
base_addr
;
void
__iomem
*
ioaddr
=
rp
->
base
;
u32
mc_filter
[
2
];
/* Multicast hash filter */
u8
rx_mode
;
/* Note: 0x02=accept runt, 0x01=accept errs */
...
...
@@ -1708,13 +1699,13 @@ static void rhine_set_rx_mode(struct net_device *dev)
printk
(
KERN_NOTICE
"%s: Promiscuous mode enabled.
\n
"
,
dev
->
name
);
rx_mode
=
0x1C
;
writel
(
0xffffffff
,
ioaddr
+
MulticastFilter0
);
writel
(
0xffffffff
,
ioaddr
+
MulticastFilter1
);
iowrite32
(
0xffffffff
,
ioaddr
+
MulticastFilter0
);
iowrite32
(
0xffffffff
,
ioaddr
+
MulticastFilter1
);
}
else
if
((
dev
->
mc_count
>
multicast_filter_limit
)
||
(
dev
->
flags
&
IFF_ALLMULTI
))
{
/* Too many to match, or accept all multicasts. */
writel
(
0xffffffff
,
ioaddr
+
MulticastFilter0
);
writel
(
0xffffffff
,
ioaddr
+
MulticastFilter1
);
iowrite32
(
0xffffffff
,
ioaddr
+
MulticastFilter0
);
iowrite32
(
0xffffffff
,
ioaddr
+
MulticastFilter1
);
rx_mode
=
0x0C
;
}
else
{
struct
dev_mc_list
*
mclist
;
...
...
@@ -1726,11 +1717,11 @@ static void rhine_set_rx_mode(struct net_device *dev)
mc_filter
[
bit_nr
>>
5
]
|=
1
<<
(
bit_nr
&
31
);
}
writel
(
mc_filter
[
0
],
ioaddr
+
MulticastFilter0
);
writel
(
mc_filter
[
1
],
ioaddr
+
MulticastFilter1
);
iowrite32
(
mc_filter
[
0
],
ioaddr
+
MulticastFilter0
);
iowrite32
(
mc_filter
[
1
],
ioaddr
+
MulticastFilter1
);
rx_mode
=
0x0C
;
}
writeb
(
rp
->
rx_thresh
|
rx_mode
,
ioaddr
+
RxConfig
);
iowrite8
(
rp
->
rx_thresh
|
rx_mode
,
ioaddr
+
RxConfig
);
}
static
void
netdev_get_drvinfo
(
struct
net_device
*
dev
,
struct
ethtool_drvinfo
*
info
)
...
...
@@ -1854,8 +1845,8 @@ static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
static
int
rhine_close
(
struct
net_device
*
dev
)
{
long
ioaddr
=
dev
->
base_addr
;
struct
rhine_private
*
rp
=
netdev_priv
(
dev
);
void
__iomem
*
ioaddr
=
rp
->
base
;
spin_lock_irq
(
&
rp
->
lock
);
...
...
@@ -1864,16 +1855,16 @@ static int rhine_close(struct net_device *dev)
if
(
debug
>
1
)
printk
(
KERN_DEBUG
"%s: Shutting down ethercard, "
"status was %4.4x.
\n
"
,
dev
->
name
,
readw
(
ioaddr
+
ChipCmd
));
dev
->
name
,
ioread16
(
ioaddr
+
ChipCmd
));
/* Switch to loopback mode to avoid hardware races. */
writeb
(
rp
->
tx_thresh
|
0x02
,
ioaddr
+
TxConfig
);
iowrite8
(
rp
->
tx_thresh
|
0x02
,
ioaddr
+
TxConfig
);
/* Disable interrupts by clearing the interrupt mask. */
writew
(
0x0000
,
ioaddr
+
IntrEnable
);
iowrite16
(
0x0000
,
ioaddr
+
IntrEnable
);
/* Stop the chip's Tx and Rx processes. */
writew
(
CmdStop
,
ioaddr
+
ChipCmd
);
iowrite16
(
CmdStop
,
ioaddr
+
ChipCmd
);
spin_unlock_irq
(
&
rp
->
lock
);
...
...
@@ -1889,15 +1880,13 @@ static int rhine_close(struct net_device *dev)
static
void
__devexit
rhine_remove_one
(
struct
pci_dev
*
pdev
)
{
struct
net_device
*
dev
=
pci_get_drvdata
(
pdev
);
struct
rhine_private
*
rp
=
netdev_priv
(
dev
);
unregister_netdev
(
dev
);
pci_iounmap
(
pdev
,
rp
->
base
);
pci_release_regions
(
pdev
);
#ifdef USE_MMIO
iounmap
((
char
*
)(
dev
->
base_addr
));
#endif
free_netdev
(
dev
);
pci_disable_device
(
pdev
);
pci_set_drvdata
(
pdev
,
NULL
);
...
...
@@ -1908,33 +1897,40 @@ static void rhine_shutdown (struct device *gendev)
struct
pci_dev
*
pdev
=
to_pci_dev
(
gendev
);
struct
net_device
*
dev
=
pci_get_drvdata
(
pdev
);
struct
rhine_private
*
rp
=
netdev_priv
(
dev
);
long
ioaddr
=
dev
->
base_addr
;
void
__iomem
*
ioaddr
=
rp
->
base
;
rhine_power_init
(
dev
);
/* Make sure we use pattern 0, 1 and not 4, 5 */
if
(
rp
->
quirks
&
rq6patterns
)
writeb
(
0x04
,
ioaddr
+
0xA7
);
if
(
rp
->
wolopts
&
WAKE_MAGIC
)
writeb
(
WOLmagic
,
ioaddr
+
WOLcrSet
);
iowrite8
(
0x04
,
ioaddr
+
0xA7
);
if
(
rp
->
wolopts
&
WAKE_MAGIC
)
{
iowrite8
(
WOLmagic
,
ioaddr
+
WOLcrSet
);
/*
* Turn EEPROM-controlled wake-up back on -- some hardware may
* not cooperate otherwise.
*/
iowrite8
(
ioread8
(
ioaddr
+
ConfigA
)
|
0x03
,
ioaddr
+
ConfigA
);
}
if
(
rp
->
wolopts
&
(
WAKE_BCAST
|
WAKE_MCAST
))
writeb
(
WOLbmcast
,
ioaddr
+
WOLcgSet
);
iowrite8
(
WOLbmcast
,
ioaddr
+
WOLcgSet
);
if
(
rp
->
wolopts
&
WAKE_PHY
)
writeb
(
WOLlnkon
|
WOLlnkoff
,
ioaddr
+
WOLcrSet
);
iowrite8
(
WOLlnkon
|
WOLlnkoff
,
ioaddr
+
WOLcrSet
);
if
(
rp
->
wolopts
&
WAKE_UCAST
)
writeb
(
WOLucast
,
ioaddr
+
WOLcrSet
);
iowrite8
(
WOLucast
,
ioaddr
+
WOLcrSet
);
/* Enable legacy WOL (for old motherboards) */
writeb
(
0x01
,
ioaddr
+
PwcfgSet
);
writeb
(
readb
(
ioaddr
+
StickyHW
)
|
0x04
,
ioaddr
+
StickyHW
);
if
(
rp
->
wolopts
)
{
/* Enable legacy WOL (for old motherboards) */
iowrite8
(
0x01
,
ioaddr
+
PwcfgSet
);
iowrite8
(
ioread8
(
ioaddr
+
StickyHW
)
|
0x04
,
ioaddr
+
StickyHW
);
}
/* Hit power state D3 (sleep) */
writeb
(
readb
(
ioaddr
+
StickyHW
)
|
0x03
,
ioaddr
+
StickyHW
);
iowrite8
(
ioread8
(
ioaddr
+
StickyHW
)
|
0x03
,
ioaddr
+
StickyHW
);
/* TODO: Check use of pci_enable_wake() */
...
...
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