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
nexedi
linux
Commits
64de62b4
Commit
64de62b4
authored
May 27, 2004
by
Jeff Garzik
Browse files
Options
Browse Files
Download
Plain Diff
Merge redhat.com:/spare/repo/netdev-2.6/pcnet32
into redhat.com:/spare/repo/net-drivers-2.6
parents
ee86da9d
3c08665c
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
49 additions
and
76 deletions
+49
-76
drivers/net/pcnet32.c
drivers/net/pcnet32.c
+49
-76
No files found.
drivers/net/pcnet32.c
View file @
64de62b4
...
...
@@ -22,8 +22,8 @@
*************************************************************************/
#define DRV_NAME "pcnet32"
#define DRV_VERSION "1.
29
"
#define DRV_RELDATE "0
4.06
.2004"
#define DRV_VERSION "1.
30c
"
#define DRV_RELDATE "0
5.25
.2004"
#define PFX DRV_NAME ": "
static
const
char
*
version
=
...
...
@@ -86,7 +86,7 @@ static int pcnet32vlb; /* check for VLB cards ? */
static
struct
net_device
*
pcnet32_dev
;
static
int
max_interrupt_work
=
80
;
static
int
max_interrupt_work
=
2
;
static
int
rx_copybreak
=
200
;
#define PCNET32_PORT_AUI 0x00
...
...
@@ -132,7 +132,7 @@ static const char pcnet32_gstrings_test[][ETH_GSTRING_LEN] = {
};
#define PCNET32_TEST_LEN (sizeof(pcnet32_gstrings_test) / ETH_GSTRING_LEN)
#define PCNET32_NUM_REGS 1
46
#define PCNET32_NUM_REGS 1
68
#define MAX_UNITS 8
/* More are supported, limit only on options */
static
int
options
[
MAX_UNITS
];
...
...
@@ -239,6 +239,12 @@ static int full_duplex[MAX_UNITS];
* identification code (blink led's) and register dump.
* Don Fry added timer for 971/972 so skbufs don't remain on tx ring
* forever.
* v1.30 18 May 2004 Don Fry removed timer and Last Transmit Interrupt
* (ltint) as they added complexity and didn't give good throughput.
* v1.30a 22 May 2004 Don Fry limit frames received during interrupt.
* v1.30b 24 May 2004 Don Fry fix bogus tx carrier errors with 79c973,
* assisted by Bruce Penrod <bmpenrod@endruntechnologies.com>.
* v1.30c 25 May 2004 Don Fry added netif_wake_queue after pcnet32_restart.
*/
...
...
@@ -343,7 +349,6 @@ struct pcnet32_private {
char
tx_full
;
int
options
;
int
shared_irq
:
1
,
/* shared irq possible */
ltint:
1
,
/* enable TxDone-intr inhibitor */
dxsuflo:
1
,
/* disable transmit stop on uflo */
mii:
1
;
/* mii port available */
struct
net_device
*
next
;
...
...
@@ -844,12 +849,12 @@ static int pcnet32_phys_id(struct net_device *dev, u32 data)
return
0
;
}
int
pcnet32_get_regs_len
(
struct
net_device
*
dev
)
static
int
pcnet32_get_regs_len
(
struct
net_device
*
dev
)
{
return
(
PCNET32_NUM_REGS
*
sizeof
(
u16
));
}
void
pcnet32_get_regs
(
struct
net_device
*
dev
,
struct
ethtool_regs
*
regs
,
static
void
pcnet32_get_regs
(
struct
net_device
*
dev
,
struct
ethtool_regs
*
regs
,
void
*
ptr
)
{
int
i
,
csr0
;
...
...
@@ -887,17 +892,27 @@ void pcnet32_get_regs(struct net_device *dev, struct ethtool_regs *regs,
for
(
i
=
0
;
i
<
16
;
i
+=
2
)
*
buff
++
=
inw
(
ioaddr
+
i
);
for
(
i
=
0
;
i
<=
89
;
i
++
)
{
/* read control and status registers */
for
(
i
=
0
;
i
<
90
;
i
++
)
{
*
buff
++
=
a
->
read_csr
(
ioaddr
,
i
);
}
*
buff
++
=
a
->
read_csr
(
ioaddr
,
112
);
*
buff
++
=
a
->
read_csr
(
ioaddr
,
114
);
for
(
i
=
0
;
i
<=
35
;
i
++
)
{
/* read bus configuration registers */
for
(
i
=
0
;
i
<
36
;
i
++
)
{
*
buff
++
=
a
->
read_bcr
(
ioaddr
,
i
);
}
/* read mii phy registers */
if
(
lp
->
mii
)
{
for
(
i
=
0
;
i
<
32
;
i
++
)
{
lp
->
a
.
write_bcr
(
ioaddr
,
33
,
((
lp
->
mii_if
.
phy_id
)
<<
5
)
|
i
);
*
buff
++
=
lp
->
a
.
read_bcr
(
ioaddr
,
34
);
}
}
if
(
!
(
csr0
&
0x0004
))
{
/* If not stopped */
/* clear SUSPEND (SPND) - CSR5 bit 0 */
a
->
write_csr
(
ioaddr
,
5
,
0x0000
);
...
...
@@ -999,7 +1014,7 @@ pcnet32_probe1(unsigned long ioaddr, unsigned int irq_line, int shared,
struct
pcnet32_private
*
lp
;
dma_addr_t
lp_dma_addr
;
int
i
,
media
;
int
fdx
,
mii
,
fset
,
dxsuflo
,
ltint
;
int
fdx
,
mii
,
fset
,
dxsuflo
;
int
chip_version
;
char
*
chipname
;
struct
net_device
*
dev
;
...
...
@@ -1031,7 +1046,7 @@ pcnet32_probe1(unsigned long ioaddr, unsigned int irq_line, int shared,
}
/* initialize variables */
fdx
=
mii
=
fset
=
dxsuflo
=
ltint
=
0
;
fdx
=
mii
=
fset
=
dxsuflo
=
0
;
chip_version
=
(
chip_version
>>
12
)
&
0xffff
;
switch
(
chip_version
)
{
...
...
@@ -1051,7 +1066,6 @@ pcnet32_probe1(unsigned long ioaddr, unsigned int irq_line, int shared,
case
0x2623
:
chipname
=
"PCnet/FAST 79C971"
;
/* PCI */
fdx
=
1
;
mii
=
1
;
fset
=
1
;
ltint
=
1
;
break
;
case
0x2624
:
chipname
=
"PCnet/FAST+ 79C972"
;
/* PCI */
...
...
@@ -1082,7 +1096,7 @@ pcnet32_probe1(unsigned long ioaddr, unsigned int irq_line, int shared,
fdx
=
1
;
mii
=
1
;
break
;
case
0x2628
:
chipname
=
"PCnet/
FAST III
79C976"
;
chipname
=
"PCnet/
PRO
79C976"
;
fdx
=
1
;
mii
=
1
;
break
;
default:
...
...
@@ -1104,14 +1118,6 @@ pcnet32_probe1(unsigned long ioaddr, unsigned int irq_line, int shared,
a
->
write_bcr
(
ioaddr
,
18
,
(
a
->
read_bcr
(
ioaddr
,
18
)
|
0x0860
));
a
->
write_csr
(
ioaddr
,
80
,
(
a
->
read_csr
(
ioaddr
,
80
)
&
0x0C00
)
|
0x0c00
);
dxsuflo
=
1
;
ltint
=
1
;
}
if
(
ltint
)
{
/* Enable timer to prevent skbuffs from remaining on the tx ring
* forever if no other tx being done. Set timer period to about
* 122 ms */
a
->
write_bcr
(
ioaddr
,
31
,
0x253b
);
}
dev
=
alloc_etherdev
(
0
);
...
...
@@ -1218,7 +1224,6 @@ pcnet32_probe1(unsigned long ioaddr, unsigned int irq_line, int shared,
lp
->
mii_if
.
phy_id_mask
=
0x1f
;
lp
->
mii_if
.
reg_num_mask
=
0x1f
;
lp
->
dxsuflo
=
dxsuflo
;
lp
->
ltint
=
ltint
;
lp
->
mii
=
mii
;
lp
->
msg_enable
=
pcnet32_debug
;
if
((
cards_found
>=
MAX_UNITS
)
||
(
options
[
cards_found
]
>
sizeof
(
options_mapping
)))
...
...
@@ -1437,12 +1442,6 @@ pcnet32_open(struct net_device *dev)
}
#endif
if
(
lp
->
ltint
)
{
/* Enable TxDone-intr inhibitor */
val
=
lp
->
a
.
read_csr
(
ioaddr
,
5
);
val
|=
(
1
<<
14
);
lp
->
a
.
write_csr
(
ioaddr
,
5
,
val
);
}
lp
->
init_block
.
mode
=
le16_to_cpu
((
lp
->
options
&
PCNET32_PORT_PORTSEL
)
<<
7
);
pcnet32_load_multicast
(
dev
);
...
...
@@ -1460,11 +1459,6 @@ pcnet32_open(struct net_device *dev)
lp
->
a
.
write_csr
(
ioaddr
,
4
,
0x0915
);
lp
->
a
.
write_csr
(
ioaddr
,
0
,
0x0001
);
if
(
lp
->
ltint
)
{
/* start the software timer */
lp
->
a
.
write_csr
(
ioaddr
,
7
,
0x0400
);
/* set STINTE */
}
netif_start_queue
(
dev
);
/* If we have mii, print the link status and start the watchdog */
...
...
@@ -1640,12 +1634,16 @@ pcnet32_tx_timeout (struct net_device *dev)
lp
->
cur_rx
);
for
(
i
=
0
;
i
<
RX_RING_SIZE
;
i
++
)
printk
(
"%s %08x %04x %08x %04x"
,
i
&
1
?
""
:
"
\n
"
,
lp
->
rx_ring
[
i
].
base
,
-
lp
->
rx_ring
[
i
].
buf_length
,
lp
->
rx_ring
[
i
].
msg_length
,
(
unsigned
)
lp
->
rx_ring
[
i
].
status
);
le32_to_cpu
(
lp
->
rx_ring
[
i
].
base
),
(
-
le16_to_cpu
(
lp
->
rx_ring
[
i
].
buf_length
))
&
0xffff
,
le32_to_cpu
(
lp
->
rx_ring
[
i
].
msg_length
),
le16_to_cpu
(
lp
->
rx_ring
[
i
].
status
));
for
(
i
=
0
;
i
<
TX_RING_SIZE
;
i
++
)
printk
(
"%s %08x %04x %08x %04x"
,
i
&
1
?
""
:
"
\n
"
,
lp
->
tx_ring
[
i
].
base
,
-
lp
->
tx_ring
[
i
].
length
,
lp
->
tx_ring
[
i
].
misc
,
(
unsigned
)
lp
->
tx_ring
[
i
].
status
);
le32_to_cpu
(
lp
->
tx_ring
[
i
].
base
),
(
-
le16_to_cpu
(
lp
->
tx_ring
[
i
].
length
))
&
0xffff
,
le32_to_cpu
(
lp
->
tx_ring
[
i
].
misc
),
le16_to_cpu
(
lp
->
tx_ring
[
i
].
status
));
printk
(
"
\n
"
);
}
pcnet32_restart
(
dev
,
0x0042
);
...
...
@@ -1677,19 +1675,6 @@ pcnet32_start_xmit(struct sk_buff *skb, struct net_device *dev)
* interrupt when that option is available to us.
*/
status
=
0x8300
;
entry
=
(
lp
->
cur_tx
-
lp
->
dirty_tx
)
&
TX_RING_MOD_MASK
;
if
((
lp
->
ltint
)
&&
((
entry
==
TX_RING_SIZE
/
3
)
||
(
entry
==
(
TX_RING_SIZE
*
2
)
/
3
)
||
(
entry
>=
TX_RING_SIZE
-
2
)))
{
/* Enable Successful-TxDone interrupt if we have
* 1/3, 2/3 or nearly all of, our ring buffer Tx'd
* but not yet cleaned up. Thus, most of the time,
* we will not enable Successful-TxDone interrupts.
*/
status
=
0x9300
;
}
/* Fill in a Tx ring entry */
...
...
@@ -1733,7 +1718,7 @@ pcnet32_interrupt(int irq, void *dev_id, struct pt_regs * regs)
struct
net_device
*
dev
=
dev_id
;
struct
pcnet32_private
*
lp
;
unsigned
long
ioaddr
;
u16
csr0
,
csr7
,
rap
;
u16
csr0
,
rap
;
int
boguscnt
=
max_interrupt_work
;
int
must_restart
;
...
...
@@ -1750,19 +1735,13 @@ pcnet32_interrupt(int irq, void *dev_id, struct pt_regs * regs)
spin_lock
(
&
lp
->
lock
);
rap
=
lp
->
a
.
read_rap
(
ioaddr
);
csr0
=
lp
->
a
.
read_csr
(
ioaddr
,
0
);
csr7
=
lp
->
ltint
?
lp
->
a
.
read_csr
(
ioaddr
,
7
)
:
0
;
while
((
csr0
&
0x8600
||
csr7
&
0x0800
)
&&
--
boguscnt
>=
0
)
{
while
((
csr0
=
lp
->
a
.
read_csr
(
ioaddr
,
0
))
&
0x8600
&&
--
boguscnt
>=
0
)
{
if
(
csr0
==
0xffff
)
{
break
;
/* PCMCIA remove happened */
}
/* Acknowledge all of the current interrupt sources ASAP. */
lp
->
a
.
write_csr
(
ioaddr
,
0
,
csr0
&
~
0x004f
);
if
(
csr7
&
0x0800
)
lp
->
a
.
write_csr
(
ioaddr
,
7
,
csr7
);
must_restart
=
0
;
if
(
netif_msg_intr
(
lp
))
...
...
@@ -1772,7 +1751,7 @@ pcnet32_interrupt(int irq, void *dev_id, struct pt_regs * regs)
if
(
csr0
&
0x0400
)
/* Rx interrupt */
pcnet32_rx
(
dev
);
if
(
csr0
&
0x0200
||
csr7
&
0x0800
)
{
/* Tx-done or Timer
interrupt */
if
(
csr0
&
0x0200
)
{
/* Tx-done
interrupt */
unsigned
int
dirty_tx
=
lp
->
dirty_tx
;
int
delta
;
...
...
@@ -1789,6 +1768,9 @@ pcnet32_interrupt(int irq, void *dev_id, struct pt_regs * regs)
/* There was an major error, log it. */
int
err_status
=
le32_to_cpu
(
lp
->
tx_ring
[
entry
].
misc
);
lp
->
stats
.
tx_errors
++
;
if
(
netif_msg_tx_err
(
lp
))
printk
(
KERN_ERR
"%s: Tx error status=%04x err_status=%08x
\n
"
,
dev
->
name
,
status
,
err_status
);
if
(
err_status
&
0x04000000
)
lp
->
stats
.
tx_aborted_errors
++
;
if
(
err_status
&
0x08000000
)
lp
->
stats
.
tx_carrier_errors
++
;
if
(
err_status
&
0x10000000
)
lp
->
stats
.
tx_window_errors
++
;
...
...
@@ -1833,7 +1815,7 @@ pcnet32_interrupt(int irq, void *dev_id, struct pt_regs * regs)
}
delta
=
(
lp
->
cur_tx
-
dirty_tx
)
&
(
TX_RING_MOD_MASK
+
TX_RING_SIZE
);
if
(
delta
>
=
TX_RING_SIZE
)
{
if
(
delta
>
TX_RING_SIZE
)
{
if
(
netif_msg_drv
(
lp
))
printk
(
KERN_ERR
"%s: out-of-sync dirty pointer, %d vs. %d, full=%d.
\n
"
,
dev
->
name
,
dirty_tx
,
lp
->
cur_tx
,
lp
->
tx_full
);
...
...
@@ -1878,10 +1860,8 @@ pcnet32_interrupt(int irq, void *dev_id, struct pt_regs * regs)
/* stop the chip to clear the error condition, then restart */
lp
->
a
.
write_csr
(
ioaddr
,
0
,
0x0004
);
pcnet32_restart
(
dev
,
0x0002
);
netif_wake_queue
(
dev
);
}
csr0
=
lp
->
a
.
read_csr
(
ioaddr
,
0
);
csr7
=
lp
->
ltint
?
lp
->
a
.
read_csr
(
ioaddr
,
7
)
:
0
;
}
/* Clear any other interrupt, and set interrupt enable. */
...
...
@@ -1902,6 +1882,7 @@ pcnet32_rx(struct net_device *dev)
{
struct
pcnet32_private
*
lp
=
dev
->
priv
;
int
entry
=
lp
->
cur_rx
&
RX_RING_MOD_MASK
;
int
boguscnt
=
RX_RING_SIZE
/
2
;
/* If we own the next entry, it's a new packet. Send it up. */
while
((
short
)
le16_to_cpu
(
lp
->
rx_ring
[
entry
].
status
)
>=
0
)
{
...
...
@@ -2004,6 +1985,7 @@ pcnet32_rx(struct net_device *dev)
wmb
();
/* Make sure owner changes after all others are visible */
lp
->
rx_ring
[
entry
].
status
|=
le16_to_cpu
(
0x8000
);
entry
=
(
++
lp
->
cur_rx
)
&
RX_RING_MOD_MASK
;
if
(
--
boguscnt
<=
0
)
break
;
/* don't stay in loop forever */
}
return
0
;
...
...
@@ -2032,10 +2014,6 @@ pcnet32_close(struct net_device *dev)
/* We stop the PCNET32 here -- it occasionally polls memory if we don't. */
lp
->
a
.
write_csr
(
ioaddr
,
0
,
0x0004
);
if
(
lp
->
ltint
)
{
/* Disable timer interrupts */
lp
->
a
.
write_csr
(
ioaddr
,
7
,
0x0000
);
}
/*
* Switch back to 16bit mode to avoid problems with dumb
* DOS packet driver after a warm reboot
...
...
@@ -2154,44 +2132,39 @@ static void pcnet32_set_multicast_list(struct net_device *dev)
}
lp
->
a
.
write_csr
(
ioaddr
,
0
,
0x0004
);
/* Temporarily stop the lance. */
pcnet32_restart
(
dev
,
0x0042
);
/* Resume normal operation */
netif_wake_queue
(
dev
);
spin_unlock_irqrestore
(
&
lp
->
lock
,
flags
);
}
/* This routine assumes that the lp->lock is held */
static
int
mdio_read
(
struct
net_device
*
dev
,
int
phy_id
,
int
reg_num
)
{
struct
pcnet32_private
*
lp
=
dev
->
priv
;
unsigned
long
ioaddr
=
dev
->
base_addr
;
u16
val_out
;
int
phyaddr
;
if
(
!
lp
->
mii
)
return
0
;
phyaddr
=
lp
->
a
.
read_bcr
(
ioaddr
,
33
);
lp
->
a
.
write_bcr
(
ioaddr
,
33
,
((
phy_id
&
0x1f
)
<<
5
)
|
(
reg_num
&
0x1f
));
val_out
=
lp
->
a
.
read_bcr
(
ioaddr
,
34
);
lp
->
a
.
write_bcr
(
ioaddr
,
33
,
phyaddr
);
return
val_out
;
}
/* This routine assumes that the lp->lock is held */
static
void
mdio_write
(
struct
net_device
*
dev
,
int
phy_id
,
int
reg_num
,
int
val
)
{
struct
pcnet32_private
*
lp
=
dev
->
priv
;
unsigned
long
ioaddr
=
dev
->
base_addr
;
int
phyaddr
;
if
(
!
lp
->
mii
)
return
;
phyaddr
=
lp
->
a
.
read_bcr
(
ioaddr
,
33
);
lp
->
a
.
write_bcr
(
ioaddr
,
33
,
((
phy_id
&
0x1f
)
<<
5
)
|
(
reg_num
&
0x1f
));
lp
->
a
.
write_bcr
(
ioaddr
,
34
,
val
);
lp
->
a
.
write_bcr
(
ioaddr
,
33
,
phyaddr
);
}
static
int
pcnet32_ioctl
(
struct
net_device
*
dev
,
struct
ifreq
*
rq
,
int
cmd
)
...
...
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