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
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