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
7af60616
Commit
7af60616
authored
Mar 02, 2005
by
Russell King
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[ARM] Net: add macro to access driver specific netdev data.
Signed-off-by:
Russell King
<
rmk@arm.linux.org.uk
>
parent
38a45f47
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
159 additions
and
186 deletions
+159
-186
drivers/net/arm/ether1.c
drivers/net/arm/ether1.c
+58
-70
drivers/net/arm/ether1.h
drivers/net/arm/ether1.h
+2
-0
drivers/net/arm/ether3.c
drivers/net/arm/ether3.c
+97
-116
drivers/net/arm/ether3.h
drivers/net/arm/ether3.h
+2
-0
No files found.
drivers/net/arm/ether1.c
View file @
7af60616
...
@@ -447,7 +447,6 @@ static rbd_t init_rbd = {
...
@@ -447,7 +447,6 @@ static rbd_t init_rbd = {
static
int
static
int
ether1_init_for_open
(
struct
net_device
*
dev
)
ether1_init_for_open
(
struct
net_device
*
dev
)
{
{
struct
ether1_priv
*
priv
=
netdev_priv
(
dev
);
int
i
,
status
,
addr
,
next
,
next2
;
int
i
,
status
,
addr
,
next
,
next2
;
int
failures
=
0
;
int
failures
=
0
;
unsigned
long
timeout
;
unsigned
long
timeout
;
...
@@ -487,7 +486,7 @@ ether1_init_for_open (struct net_device *dev)
...
@@ -487,7 +486,7 @@ ether1_init_for_open (struct net_device *dev)
if
(
next2
>=
RX_AREA_END
)
{
if
(
next2
>=
RX_AREA_END
)
{
next
=
RX_AREA_START
;
next
=
RX_AREA_START
;
init_rfd
.
rfd_command
=
RFD_CMDEL
|
RFD_CMDSUSPEND
;
init_rfd
.
rfd_command
=
RFD_CMDEL
|
RFD_CMDSUSPEND
;
priv
->
rx_tail
=
addr
;
priv
(
dev
)
->
rx_tail
=
addr
;
}
else
}
else
init_rfd
.
rfd_command
=
0
;
init_rfd
.
rfd_command
=
0
;
if
(
addr
==
RX_AREA_START
)
if
(
addr
==
RX_AREA_START
)
...
@@ -503,14 +502,14 @@ ether1_init_for_open (struct net_device *dev)
...
@@ -503,14 +502,14 @@ ether1_init_for_open (struct net_device *dev)
addr
=
next
;
addr
=
next
;
}
while
(
next2
<
RX_AREA_END
);
}
while
(
next2
<
RX_AREA_END
);
priv
->
tx_link
=
NOP_ADDR
;
priv
(
dev
)
->
tx_link
=
NOP_ADDR
;
priv
->
tx_head
=
NOP_ADDR
+
NOP_SIZE
;
priv
(
dev
)
->
tx_head
=
NOP_ADDR
+
NOP_SIZE
;
priv
->
tx_tail
=
TDR_ADDR
;
priv
(
dev
)
->
tx_tail
=
TDR_ADDR
;
priv
->
rx_head
=
RX_AREA_START
;
priv
(
dev
)
->
rx_head
=
RX_AREA_START
;
/* release reset & give 586 a prod */
/* release reset & give 586 a prod */
priv
->
resetting
=
1
;
priv
(
dev
)
->
resetting
=
1
;
priv
->
initialising
=
1
;
priv
(
dev
)
->
initialising
=
1
;
outb
(
CTRL_RST
,
REG_CONTROL
);
outb
(
CTRL_RST
,
REG_CONTROL
);
outb
(
0
,
REG_CONTROL
);
outb
(
0
,
REG_CONTROL
);
outb
(
CTRL_CA
,
REG_CONTROL
);
outb
(
CTRL_CA
,
REG_CONTROL
);
...
@@ -616,24 +615,23 @@ ether1_init_for_open (struct net_device *dev)
...
@@ -616,24 +615,23 @@ ether1_init_for_open (struct net_device *dev)
static
int
static
int
ether1_txalloc
(
struct
net_device
*
dev
,
int
size
)
ether1_txalloc
(
struct
net_device
*
dev
,
int
size
)
{
{
struct
ether1_priv
*
priv
=
netdev_priv
(
dev
);
int
start
,
tail
;
int
start
,
tail
;
size
=
(
size
+
1
)
&
~
1
;
size
=
(
size
+
1
)
&
~
1
;
tail
=
priv
->
tx_tail
;
tail
=
priv
(
dev
)
->
tx_tail
;
if
(
priv
->
tx_head
+
size
>
TX_AREA_END
)
{
if
(
priv
(
dev
)
->
tx_head
+
size
>
TX_AREA_END
)
{
if
(
tail
>
priv
->
tx_head
)
if
(
tail
>
priv
(
dev
)
->
tx_head
)
return
-
1
;
return
-
1
;
start
=
TX_AREA_START
;
start
=
TX_AREA_START
;
if
(
start
+
size
>
tail
)
if
(
start
+
size
>
tail
)
return
-
1
;
return
-
1
;
priv
->
tx_head
=
start
+
size
;
priv
(
dev
)
->
tx_head
=
start
+
size
;
}
else
{
}
else
{
if
(
priv
->
tx_head
<
tail
&&
(
priv
->
tx_head
+
size
)
>
tail
)
if
(
priv
(
dev
)
->
tx_head
<
tail
&&
(
priv
(
dev
)
->
tx_head
+
size
)
>
tail
)
return
-
1
;
return
-
1
;
start
=
priv
->
tx_head
;
start
=
priv
(
dev
)
->
tx_head
;
priv
->
tx_head
+=
size
;
priv
(
dev
)
->
tx_head
+=
size
;
}
}
return
start
;
return
start
;
...
@@ -642,8 +640,6 @@ ether1_txalloc (struct net_device *dev, int size)
...
@@ -642,8 +640,6 @@ ether1_txalloc (struct net_device *dev, int size)
static
int
static
int
ether1_open
(
struct
net_device
*
dev
)
ether1_open
(
struct
net_device
*
dev
)
{
{
struct
ether1_priv
*
priv
=
netdev_priv
(
dev
);
if
(
!
is_valid_ether_addr
(
dev
->
dev_addr
))
{
if
(
!
is_valid_ether_addr
(
dev
->
dev_addr
))
{
printk
(
KERN_WARNING
"%s: invalid ethernet MAC address
\n
"
,
printk
(
KERN_WARNING
"%s: invalid ethernet MAC address
\n
"
,
dev
->
name
);
dev
->
name
);
...
@@ -653,7 +649,7 @@ ether1_open (struct net_device *dev)
...
@@ -653,7 +649,7 @@ ether1_open (struct net_device *dev)
if
(
request_irq
(
dev
->
irq
,
ether1_interrupt
,
0
,
"ether1"
,
dev
))
if
(
request_irq
(
dev
->
irq
,
ether1_interrupt
,
0
,
"ether1"
,
dev
))
return
-
EAGAIN
;
return
-
EAGAIN
;
memset
(
&
priv
->
stats
,
0
,
sizeof
(
struct
net_device_stats
));
memset
(
&
priv
(
dev
)
->
stats
,
0
,
sizeof
(
struct
net_device_stats
));
if
(
ether1_init_for_open
(
dev
))
{
if
(
ether1_init_for_open
(
dev
))
{
free_irq
(
dev
->
irq
,
dev
);
free_irq
(
dev
->
irq
,
dev
);
...
@@ -668,8 +664,6 @@ ether1_open (struct net_device *dev)
...
@@ -668,8 +664,6 @@ ether1_open (struct net_device *dev)
static
void
static
void
ether1_timeout
(
struct
net_device
*
dev
)
ether1_timeout
(
struct
net_device
*
dev
)
{
{
struct
ether1_priv
*
priv
=
netdev_priv
(
dev
);
printk
(
KERN_WARNING
"%s: transmit timeout, network cable problem?
\n
"
,
printk
(
KERN_WARNING
"%s: transmit timeout, network cable problem?
\n
"
,
dev
->
name
);
dev
->
name
);
printk
(
KERN_WARNING
"%s: resetting device
\n
"
,
dev
->
name
);
printk
(
KERN_WARNING
"%s: resetting device
\n
"
,
dev
->
name
);
...
@@ -679,21 +673,20 @@ ether1_timeout(struct net_device *dev)
...
@@ -679,21 +673,20 @@ ether1_timeout(struct net_device *dev)
if
(
ether1_init_for_open
(
dev
))
if
(
ether1_init_for_open
(
dev
))
printk
(
KERN_ERR
"%s: unable to restart interface
\n
"
,
dev
->
name
);
printk
(
KERN_ERR
"%s: unable to restart interface
\n
"
,
dev
->
name
);
priv
->
stats
.
tx_errors
++
;
priv
(
dev
)
->
stats
.
tx_errors
++
;
netif_wake_queue
(
dev
);
netif_wake_queue
(
dev
);
}
}
static
int
static
int
ether1_sendpacket
(
struct
sk_buff
*
skb
,
struct
net_device
*
dev
)
ether1_sendpacket
(
struct
sk_buff
*
skb
,
struct
net_device
*
dev
)
{
{
struct
ether1_priv
*
priv
=
netdev_priv
(
dev
);
int
tmp
,
tst
,
nopaddr
,
txaddr
,
tbdaddr
,
dataddr
;
int
tmp
,
tst
,
nopaddr
,
txaddr
,
tbdaddr
,
dataddr
;
unsigned
long
flags
;
unsigned
long
flags
;
tx_t
tx
;
tx_t
tx
;
tbd_t
tbd
;
tbd_t
tbd
;
nop_t
nop
;
nop_t
nop
;
if
(
priv
->
restart
)
{
if
(
priv
(
dev
)
->
restart
)
{
printk
(
KERN_WARNING
"%s: resetting device
\n
"
,
dev
->
name
);
printk
(
KERN_WARNING
"%s: resetting device
\n
"
,
dev
->
name
);
ether1_reset
(
dev
);
ether1_reset
(
dev
);
...
@@ -701,7 +694,7 @@ ether1_sendpacket (struct sk_buff *skb, struct net_device *dev)
...
@@ -701,7 +694,7 @@ ether1_sendpacket (struct sk_buff *skb, struct net_device *dev)
if
(
ether1_init_for_open
(
dev
))
if
(
ether1_init_for_open
(
dev
))
printk
(
KERN_ERR
"%s: unable to restart interface
\n
"
,
dev
->
name
);
printk
(
KERN_ERR
"%s: unable to restart interface
\n
"
,
dev
->
name
);
else
else
priv
->
restart
=
0
;
priv
(
dev
)
->
restart
=
0
;
}
}
if
(
skb
->
len
<
ETH_ZLEN
)
{
if
(
skb
->
len
<
ETH_ZLEN
)
{
...
@@ -735,8 +728,8 @@ ether1_sendpacket (struct sk_buff *skb, struct net_device *dev)
...
@@ -735,8 +728,8 @@ ether1_sendpacket (struct sk_buff *skb, struct net_device *dev)
ether1_writebuffer
(
dev
,
&
tbd
,
tbdaddr
,
TBD_SIZE
);
ether1_writebuffer
(
dev
,
&
tbd
,
tbdaddr
,
TBD_SIZE
);
ether1_writebuffer
(
dev
,
skb
->
data
,
dataddr
,
skb
->
len
);
ether1_writebuffer
(
dev
,
skb
->
data
,
dataddr
,
skb
->
len
);
ether1_writebuffer
(
dev
,
&
nop
,
nopaddr
,
NOP_SIZE
);
ether1_writebuffer
(
dev
,
&
nop
,
nopaddr
,
NOP_SIZE
);
tmp
=
priv
->
tx_link
;
tmp
=
priv
(
dev
)
->
tx_link
;
priv
->
tx_link
=
nopaddr
;
priv
(
dev
)
->
tx_link
=
nopaddr
;
/* now reset the previous nop pointer */
/* now reset the previous nop pointer */
ether1_outw
(
dev
,
txaddr
,
tmp
,
nop_t
,
nop_link
,
NORMALIRQS
);
ether1_outw
(
dev
,
txaddr
,
tmp
,
nop_t
,
nop_link
,
NORMALIRQS
);
...
@@ -747,9 +740,9 @@ ether1_sendpacket (struct sk_buff *skb, struct net_device *dev)
...
@@ -747,9 +740,9 @@ ether1_sendpacket (struct sk_buff *skb, struct net_device *dev)
dev
->
trans_start
=
jiffies
;
dev
->
trans_start
=
jiffies
;
/* check to see if we have room for a full sized ether frame */
/* check to see if we have room for a full sized ether frame */
tmp
=
priv
->
tx_head
;
tmp
=
priv
(
dev
)
->
tx_head
;
tst
=
ether1_txalloc
(
dev
,
TX_SIZE
+
TBD_SIZE
+
NOP_SIZE
+
ETH_FRAME_LEN
);
tst
=
ether1_txalloc
(
dev
,
TX_SIZE
+
TBD_SIZE
+
NOP_SIZE
+
ETH_FRAME_LEN
);
priv
->
tx_head
=
tmp
;
priv
(
dev
)
->
tx_head
=
tmp
;
dev_kfree_skb
(
skb
);
dev_kfree_skb
(
skb
);
if
(
tst
==
-
1
)
if
(
tst
==
-
1
)
...
@@ -762,11 +755,10 @@ ether1_sendpacket (struct sk_buff *skb, struct net_device *dev)
...
@@ -762,11 +755,10 @@ ether1_sendpacket (struct sk_buff *skb, struct net_device *dev)
static
void
static
void
ether1_xmit_done
(
struct
net_device
*
dev
)
ether1_xmit_done
(
struct
net_device
*
dev
)
{
{
struct
ether1_priv
*
priv
=
netdev_priv
(
dev
);
nop_t
nop
;
nop_t
nop
;
int
caddr
,
tst
;
int
caddr
,
tst
;
caddr
=
priv
->
tx_tail
;
caddr
=
priv
(
dev
)
->
tx_tail
;
again:
again:
ether1_readbuffer
(
dev
,
&
nop
,
caddr
,
NOP_SIZE
);
ether1_readbuffer
(
dev
,
&
nop
,
caddr
,
NOP_SIZE
);
...
@@ -780,15 +772,15 @@ ether1_xmit_done (struct net_device *dev)
...
@@ -780,15 +772,15 @@ ether1_xmit_done (struct net_device *dev)
scb_command
,
NORMALIRQS
);
scb_command
,
NORMALIRQS
);
outb
(
CTRL_CA
,
REG_CONTROL
);
outb
(
CTRL_CA
,
REG_CONTROL
);
}
}
priv
->
tx_tail
=
NOP_ADDR
;
priv
(
dev
)
->
tx_tail
=
NOP_ADDR
;
return
;
return
;
case
CMD_NOP
:
case
CMD_NOP
:
if
(
nop
.
nop_link
==
caddr
)
{
if
(
nop
.
nop_link
==
caddr
)
{
if
(
priv
->
initialising
==
0
)
if
(
priv
(
dev
)
->
initialising
==
0
)
printk
(
KERN_WARNING
"%s: strange command complete with no tx command!
\n
"
,
dev
->
name
);
printk
(
KERN_WARNING
"%s: strange command complete with no tx command!
\n
"
,
dev
->
name
);
else
else
priv
->
initialising
=
0
;
priv
(
dev
)
->
initialising
=
0
;
return
;
return
;
}
}
if
(
caddr
==
nop
.
nop_link
)
if
(
caddr
==
nop
.
nop_link
)
...
@@ -800,33 +792,33 @@ ether1_xmit_done (struct net_device *dev)
...
@@ -800,33 +792,33 @@ ether1_xmit_done (struct net_device *dev)
if
(
nop
.
nop_status
&
STAT_COMPLETE
)
if
(
nop
.
nop_status
&
STAT_COMPLETE
)
break
;
break
;
printk
(
KERN_ERR
"%s: strange command complete without completed command
\n
"
,
dev
->
name
);
printk
(
KERN_ERR
"%s: strange command complete without completed command
\n
"
,
dev
->
name
);
priv
->
restart
=
1
;
priv
(
dev
)
->
restart
=
1
;
return
;
return
;
default:
default:
printk
(
KERN_WARNING
"%s: strange command %d complete! (offset %04X)"
,
dev
->
name
,
printk
(
KERN_WARNING
"%s: strange command %d complete! (offset %04X)"
,
dev
->
name
,
nop
.
nop_command
&
CMD_MASK
,
caddr
);
nop
.
nop_command
&
CMD_MASK
,
caddr
);
priv
->
restart
=
1
;
priv
(
dev
)
->
restart
=
1
;
return
;
return
;
}
}
while
(
nop
.
nop_status
&
STAT_COMPLETE
)
{
while
(
nop
.
nop_status
&
STAT_COMPLETE
)
{
if
(
nop
.
nop_status
&
STAT_OK
)
{
if
(
nop
.
nop_status
&
STAT_OK
)
{
priv
->
stats
.
tx_packets
++
;
priv
(
dev
)
->
stats
.
tx_packets
++
;
priv
->
stats
.
collisions
+=
(
nop
.
nop_status
&
STAT_COLLISIONS
);
priv
(
dev
)
->
stats
.
collisions
+=
(
nop
.
nop_status
&
STAT_COLLISIONS
);
}
else
{
}
else
{
priv
->
stats
.
tx_errors
++
;
priv
(
dev
)
->
stats
.
tx_errors
++
;
if
(
nop
.
nop_status
&
STAT_COLLAFTERTX
)
if
(
nop
.
nop_status
&
STAT_COLLAFTERTX
)
priv
->
stats
.
collisions
++
;
priv
(
dev
)
->
stats
.
collisions
++
;
if
(
nop
.
nop_status
&
STAT_NOCARRIER
)
if
(
nop
.
nop_status
&
STAT_NOCARRIER
)
priv
->
stats
.
tx_carrier_errors
++
;
priv
(
dev
)
->
stats
.
tx_carrier_errors
++
;
if
(
nop
.
nop_status
&
STAT_TXLOSTCTS
)
if
(
nop
.
nop_status
&
STAT_TXLOSTCTS
)
printk
(
KERN_WARNING
"%s: cts lost
\n
"
,
dev
->
name
);
printk
(
KERN_WARNING
"%s: cts lost
\n
"
,
dev
->
name
);
if
(
nop
.
nop_status
&
STAT_TXSLOWDMA
)
if
(
nop
.
nop_status
&
STAT_TXSLOWDMA
)
priv
->
stats
.
tx_fifo_errors
++
;
priv
(
dev
)
->
stats
.
tx_fifo_errors
++
;
if
(
nop
.
nop_status
&
STAT_COLLEXCESSIVE
)
if
(
nop
.
nop_status
&
STAT_COLLEXCESSIVE
)
priv
->
stats
.
collisions
+=
16
;
priv
(
dev
)
->
stats
.
collisions
+=
16
;
}
}
if
(
nop
.
nop_link
==
caddr
)
{
if
(
nop
.
nop_link
==
caddr
)
{
...
@@ -851,11 +843,11 @@ ether1_xmit_done (struct net_device *dev)
...
@@ -851,11 +843,11 @@ ether1_xmit_done (struct net_device *dev)
break
;
break
;
}
}
}
}
priv
->
tx_tail
=
caddr
;
priv
(
dev
)
->
tx_tail
=
caddr
;
caddr
=
priv
->
tx_head
;
caddr
=
priv
(
dev
)
->
tx_head
;
tst
=
ether1_txalloc
(
dev
,
TX_SIZE
+
TBD_SIZE
+
NOP_SIZE
+
ETH_FRAME_LEN
);
tst
=
ether1_txalloc
(
dev
,
TX_SIZE
+
TBD_SIZE
+
NOP_SIZE
+
ETH_FRAME_LEN
);
priv
->
tx_head
=
caddr
;
priv
(
dev
)
->
tx_head
=
caddr
;
if
(
tst
!=
-
1
)
if
(
tst
!=
-
1
)
netif_wake_queue
(
dev
);
netif_wake_queue
(
dev
);
}
}
...
@@ -863,17 +855,16 @@ ether1_xmit_done (struct net_device *dev)
...
@@ -863,17 +855,16 @@ ether1_xmit_done (struct net_device *dev)
static
void
static
void
ether1_recv_done
(
struct
net_device
*
dev
)
ether1_recv_done
(
struct
net_device
*
dev
)
{
{
struct
ether1_priv
*
priv
=
netdev_priv
(
dev
);
int
status
;
int
status
;
int
nexttail
,
rbdaddr
;
int
nexttail
,
rbdaddr
;
rbd_t
rbd
;
rbd_t
rbd
;
do
{
do
{
status
=
ether1_inw
(
dev
,
priv
->
rx_head
,
rfd_t
,
rfd_status
,
NORMALIRQS
);
status
=
ether1_inw
(
dev
,
priv
(
dev
)
->
rx_head
,
rfd_t
,
rfd_status
,
NORMALIRQS
);
if
((
status
&
RFD_COMPLETE
)
==
0
)
if
((
status
&
RFD_COMPLETE
)
==
0
)
break
;
break
;
rbdaddr
=
ether1_inw
(
dev
,
priv
->
rx_head
,
rfd_t
,
rfd_rbdoffset
,
NORMALIRQS
);
rbdaddr
=
ether1_inw
(
dev
,
priv
(
dev
)
->
rx_head
,
rfd_t
,
rfd_rbdoffset
,
NORMALIRQS
);
ether1_readbuffer
(
dev
,
&
rbd
,
rbdaddr
,
RBD_SIZE
);
ether1_readbuffer
(
dev
,
&
rbd
,
rbdaddr
,
RBD_SIZE
);
if
((
rbd
.
rbd_status
&
(
RBD_EOF
|
RBD_ACNTVALID
))
==
(
RBD_EOF
|
RBD_ACNTVALID
))
{
if
((
rbd
.
rbd_status
&
(
RBD_EOF
|
RBD_ACNTVALID
))
==
(
RBD_EOF
|
RBD_ACNTVALID
))
{
...
@@ -891,27 +882,27 @@ ether1_recv_done (struct net_device *dev)
...
@@ -891,27 +882,27 @@ ether1_recv_done (struct net_device *dev)
skb
->
protocol
=
eth_type_trans
(
skb
,
dev
);
skb
->
protocol
=
eth_type_trans
(
skb
,
dev
);
netif_rx
(
skb
);
netif_rx
(
skb
);
priv
->
stats
.
rx_packets
++
;
priv
(
dev
)
->
stats
.
rx_packets
++
;
}
else
}
else
priv
->
stats
.
rx_dropped
++
;
priv
(
dev
)
->
stats
.
rx_dropped
++
;
}
else
{
}
else
{
printk
(
KERN_WARNING
"%s: %s
\n
"
,
dev
->
name
,
printk
(
KERN_WARNING
"%s: %s
\n
"
,
dev
->
name
,
(
rbd
.
rbd_status
&
RBD_EOF
)
?
"oversized packet"
:
"acnt not valid"
);
(
rbd
.
rbd_status
&
RBD_EOF
)
?
"oversized packet"
:
"acnt not valid"
);
priv
->
stats
.
rx_dropped
++
;
priv
(
dev
)
->
stats
.
rx_dropped
++
;
}
}
nexttail
=
ether1_inw
(
dev
,
priv
->
rx_tail
,
rfd_t
,
rfd_link
,
NORMALIRQS
);
nexttail
=
ether1_inw
(
dev
,
priv
(
dev
)
->
rx_tail
,
rfd_t
,
rfd_link
,
NORMALIRQS
);
/* nexttail should be rx_head */
/* nexttail should be rx_head */
if
(
nexttail
!=
priv
->
rx_head
)
if
(
nexttail
!=
priv
(
dev
)
->
rx_head
)
printk
(
KERN_ERR
"%s: receiver buffer chaining error (%04X != %04X)
\n
"
,
printk
(
KERN_ERR
"%s: receiver buffer chaining error (%04X != %04X)
\n
"
,
dev
->
name
,
nexttail
,
priv
->
rx_head
);
dev
->
name
,
nexttail
,
priv
(
dev
)
->
rx_head
);
ether1_outw
(
dev
,
RFD_CMDEL
|
RFD_CMDSUSPEND
,
nexttail
,
rfd_t
,
rfd_command
,
NORMALIRQS
);
ether1_outw
(
dev
,
RFD_CMDEL
|
RFD_CMDSUSPEND
,
nexttail
,
rfd_t
,
rfd_command
,
NORMALIRQS
);
ether1_outw
(
dev
,
0
,
priv
->
rx_tail
,
rfd_t
,
rfd_command
,
NORMALIRQS
);
ether1_outw
(
dev
,
0
,
priv
(
dev
)
->
rx_tail
,
rfd_t
,
rfd_command
,
NORMALIRQS
);
ether1_outw
(
dev
,
0
,
priv
->
rx_tail
,
rfd_t
,
rfd_status
,
NORMALIRQS
);
ether1_outw
(
dev
,
0
,
priv
(
dev
)
->
rx_tail
,
rfd_t
,
rfd_status
,
NORMALIRQS
);
ether1_outw
(
dev
,
0
,
priv
->
rx_tail
,
rfd_t
,
rfd_rbdoffset
,
NORMALIRQS
);
ether1_outw
(
dev
,
0
,
priv
(
dev
)
->
rx_tail
,
rfd_t
,
rfd_rbdoffset
,
NORMALIRQS
);
priv
->
rx_tail
=
nexttail
;
priv
(
dev
)
->
rx_tail
=
nexttail
;
priv
->
rx_head
=
ether1_inw
(
dev
,
priv
->
rx_head
,
rfd_t
,
rfd_link
,
NORMALIRQS
);
priv
(
dev
)
->
rx_head
=
ether1_inw
(
dev
,
priv
(
dev
)
->
rx_head
,
rfd_t
,
rfd_link
,
NORMALIRQS
);
}
while
(
1
);
}
while
(
1
);
}
}
...
@@ -919,7 +910,6 @@ static irqreturn_t
...
@@ -919,7 +910,6 @@ static irqreturn_t
ether1_interrupt
(
int
irq
,
void
*
dev_id
,
struct
pt_regs
*
regs
)
ether1_interrupt
(
int
irq
,
void
*
dev_id
,
struct
pt_regs
*
regs
)
{
{
struct
net_device
*
dev
=
(
struct
net_device
*
)
dev_id
;
struct
net_device
*
dev
=
(
struct
net_device
*
)
dev_id
;
struct
ether1_priv
*
priv
=
netdev_priv
(
dev
);
int
status
;
int
status
;
status
=
ether1_inw
(
dev
,
SCB_ADDR
,
scb_t
,
scb_status
,
NORMALIRQS
);
status
=
ether1_inw
(
dev
,
SCB_ADDR
,
scb_t
,
scb_status
,
NORMALIRQS
);
...
@@ -932,17 +922,17 @@ ether1_interrupt (int irq, void *dev_id, struct pt_regs *regs)
...
@@ -932,17 +922,17 @@ ether1_interrupt (int irq, void *dev_id, struct pt_regs *regs)
ether1_xmit_done
(
dev
);
ether1_xmit_done
(
dev
);
}
}
if
(
status
&
SCB_STCNA
)
{
if
(
status
&
SCB_STCNA
)
{
if
(
priv
->
resetting
==
0
)
if
(
priv
(
dev
)
->
resetting
==
0
)
printk
(
KERN_WARNING
"%s: CU went not ready ???
\n
"
,
dev
->
name
);
printk
(
KERN_WARNING
"%s: CU went not ready ???
\n
"
,
dev
->
name
);
else
else
priv
->
resetting
+=
1
;
priv
(
dev
)
->
resetting
+=
1
;
if
(
ether1_inw
(
dev
,
SCB_ADDR
,
scb_t
,
scb_cbl_offset
,
NORMALIRQS
)
if
(
ether1_inw
(
dev
,
SCB_ADDR
,
scb_t
,
scb_cbl_offset
,
NORMALIRQS
)
!=
(
unsigned
short
)
I82586_NULL
)
{
!=
(
unsigned
short
)
I82586_NULL
)
{
ether1_outw
(
dev
,
SCB_CMDCUCSTART
,
SCB_ADDR
,
scb_t
,
scb_command
,
NORMALIRQS
);
ether1_outw
(
dev
,
SCB_CMDCUCSTART
,
SCB_ADDR
,
scb_t
,
scb_command
,
NORMALIRQS
);
outb
(
CTRL_CA
,
REG_CONTROL
);
outb
(
CTRL_CA
,
REG_CONTROL
);
}
}
if
(
priv
->
resetting
==
2
)
if
(
priv
(
dev
)
->
resetting
==
2
)
priv
->
resetting
=
0
;
priv
(
dev
)
->
resetting
=
0
;
}
}
if
(
status
&
SCB_STFR
)
{
if
(
status
&
SCB_STFR
)
{
ether1_recv_done
(
dev
);
ether1_recv_done
(
dev
);
...
@@ -952,7 +942,7 @@ ether1_interrupt (int irq, void *dev_id, struct pt_regs *regs)
...
@@ -952,7 +942,7 @@ ether1_interrupt (int irq, void *dev_id, struct pt_regs *regs)
printk
(
KERN_WARNING
"%s: RU went not ready: RU suspended
\n
"
,
dev
->
name
);
printk
(
KERN_WARNING
"%s: RU went not ready: RU suspended
\n
"
,
dev
->
name
);
ether1_outw
(
dev
,
SCB_CMDRXRESUME
,
SCB_ADDR
,
scb_t
,
scb_command
,
NORMALIRQS
);
ether1_outw
(
dev
,
SCB_CMDRXRESUME
,
SCB_ADDR
,
scb_t
,
scb_command
,
NORMALIRQS
);
outb
(
CTRL_CA
,
REG_CONTROL
);
outb
(
CTRL_CA
,
REG_CONTROL
);
priv
->
stats
.
rx_dropped
++
;
/* we suspended due to lack of buffer space */
priv
(
dev
)
->
stats
.
rx_dropped
++
;
/* we suspended due to lack of buffer space */
}
else
}
else
printk
(
KERN_WARNING
"%s: RU went not ready: %04X
\n
"
,
dev
->
name
,
printk
(
KERN_WARNING
"%s: RU went not ready: %04X
\n
"
,
dev
->
name
,
ether1_inw
(
dev
,
SCB_ADDR
,
scb_t
,
scb_status
,
NORMALIRQS
));
ether1_inw
(
dev
,
SCB_ADDR
,
scb_t
,
scb_status
,
NORMALIRQS
));
...
@@ -978,8 +968,7 @@ ether1_close (struct net_device *dev)
...
@@ -978,8 +968,7 @@ ether1_close (struct net_device *dev)
static
struct
net_device_stats
*
static
struct
net_device_stats
*
ether1_getstats
(
struct
net_device
*
dev
)
ether1_getstats
(
struct
net_device
*
dev
)
{
{
struct
ether1_priv
*
priv
=
netdev_priv
(
dev
);
return
&
priv
(
dev
)
->
stats
;
return
&
priv
->
stats
;
}
}
/*
/*
...
@@ -1030,8 +1019,7 @@ ether1_probe(struct expansion_card *ec, const struct ecard_id *id)
...
@@ -1030,8 +1019,7 @@ ether1_probe(struct expansion_card *ec, const struct ecard_id *id)
request_region
(
dev
->
base_addr
,
16
,
dev
->
name
);
request_region
(
dev
->
base_addr
,
16
,
dev
->
name
);
request_region
(
dev
->
base_addr
+
0x800
,
4096
,
dev
->
name
);
request_region
(
dev
->
base_addr
+
0x800
,
4096
,
dev
->
name
);
priv
=
netdev_priv
(
dev
);
if
((
priv
(
dev
)
->
bus_type
=
ether1_reset
(
dev
))
==
0
)
{
if
((
priv
->
bus_type
=
ether1_reset
(
dev
))
==
0
)
{
ret
=
-
ENODEV
;
ret
=
-
ENODEV
;
goto
release
;
goto
release
;
}
}
...
...
drivers/net/arm/ether1.h
View file @
7af60616
...
@@ -19,6 +19,8 @@
...
@@ -19,6 +19,8 @@
#define NET_DEBUG 0
#define NET_DEBUG 0
#endif
#endif
#define priv(dev) ((struct ether1_priv *)netdev_priv(dev))
/* Page register */
/* Page register */
#define REG_PAGE (dev->base_addr + 0x00)
#define REG_PAGE (dev->base_addr + 0x00)
...
...
drivers/net/arm/ether3.c
View file @
7af60616
...
@@ -78,8 +78,8 @@ static char version[] __initdata = "ether3 ethernet driver (c) 1995-2000 R.M.Kin
...
@@ -78,8 +78,8 @@ static char version[] __initdata = "ether3 ethernet driver (c) 1995-2000 R.M.Kin
static
unsigned
int
net_debug
=
NET_DEBUG
;
static
unsigned
int
net_debug
=
NET_DEBUG
;
static
void
ether3_setmulticastlist
(
struct
net_device
*
dev
);
static
void
ether3_setmulticastlist
(
struct
net_device
*
dev
);
static
int
ether3_rx
(
struct
net_device
*
dev
,
struct
dev_priv
*
priv
,
unsigned
int
maxcnt
);
static
int
ether3_rx
(
struct
net_device
*
dev
,
unsigned
int
maxcnt
);
static
void
ether3_tx
(
struct
net_device
*
dev
,
struct
dev_priv
*
priv
);
static
void
ether3_tx
(
struct
net_device
*
dev
);
static
int
ether3_open
(
struct
net_device
*
dev
);
static
int
ether3_open
(
struct
net_device
*
dev
);
static
int
ether3_sendpacket
(
struct
sk_buff
*
skb
,
struct
net_device
*
dev
);
static
int
ether3_sendpacket
(
struct
sk_buff
*
skb
,
struct
net_device
*
dev
);
static
irqreturn_t
ether3_interrupt
(
int
irq
,
void
*
dev_id
,
struct
pt_regs
*
regs
);
static
irqreturn_t
ether3_interrupt
(
int
irq
,
void
*
dev_id
,
struct
pt_regs
*
regs
);
...
@@ -121,16 +121,15 @@ static inline void ether3_outw(int v, const int r)
...
@@ -121,16 +121,15 @@ static inline void ether3_outw(int v, const int r)
static
int
static
int
ether3_setbuffer
(
struct
net_device
*
dev
,
buffer_rw_t
read
,
int
start
)
ether3_setbuffer
(
struct
net_device
*
dev
,
buffer_rw_t
read
,
int
start
)
{
{
struct
dev_priv
*
priv
=
netdev_priv
(
dev
);
int
timeout
=
1000
;
int
timeout
=
1000
;
ether3_outw
(
priv
->
regs
.
config1
|
CFG1_LOCBUFMEM
,
REG_CONFIG1
);
ether3_outw
(
priv
(
dev
)
->
regs
.
config1
|
CFG1_LOCBUFMEM
,
REG_CONFIG1
);
ether3_outw
(
priv
->
regs
.
command
|
CMD_FIFOWRITE
,
REG_COMMAND
);
ether3_outw
(
priv
(
dev
)
->
regs
.
command
|
CMD_FIFOWRITE
,
REG_COMMAND
);
while
((
ether3_inw
(
REG_STATUS
)
&
STAT_FIFOEMPTY
)
==
0
)
{
while
((
ether3_inw
(
REG_STATUS
)
&
STAT_FIFOEMPTY
)
==
0
)
{
if
(
!
timeout
--
)
{
if
(
!
timeout
--
)
{
printk
(
"%s: setbuffer broken
\n
"
,
dev
->
name
);
printk
(
"%s: setbuffer broken
\n
"
,
dev
->
name
);
priv
->
broken
=
1
;
priv
(
dev
)
->
broken
=
1
;
return
1
;
return
1
;
}
}
udelay
(
1
);
udelay
(
1
);
...
@@ -138,9 +137,9 @@ ether3_setbuffer(struct net_device *dev, buffer_rw_t read, int start)
...
@@ -138,9 +137,9 @@ ether3_setbuffer(struct net_device *dev, buffer_rw_t read, int start)
if
(
read
==
buffer_read
)
{
if
(
read
==
buffer_read
)
{
ether3_outw
(
start
,
REG_DMAADDR
);
ether3_outw
(
start
,
REG_DMAADDR
);
ether3_outw
(
priv
->
regs
.
command
|
CMD_FIFOREAD
,
REG_COMMAND
);
ether3_outw
(
priv
(
dev
)
->
regs
.
command
|
CMD_FIFOREAD
,
REG_COMMAND
);
}
else
{
}
else
{
ether3_outw
(
priv
->
regs
.
command
|
CMD_FIFOWRITE
,
REG_COMMAND
);
ether3_outw
(
priv
(
dev
)
->
regs
.
command
|
CMD_FIFOWRITE
,
REG_COMMAND
);
ether3_outw
(
start
,
REG_DMAADDR
);
ether3_outw
(
start
,
REG_DMAADDR
);
}
}
return
0
;
return
0
;
...
@@ -176,27 +175,24 @@ ether3_setbuffer(struct net_device *dev, buffer_rw_t read, int start)
...
@@ -176,27 +175,24 @@ ether3_setbuffer(struct net_device *dev, buffer_rw_t read, int start)
/*
/*
* Switch LED off...
* Switch LED off...
*/
*/
static
void
static
void
ether3_ledoff
(
unsigned
long
data
)
ether3_ledoff
(
unsigned
long
data
)
{
{
struct
net_device
*
dev
=
(
struct
net_device
*
)
data
;
struct
net_device
*
dev
=
(
struct
net_device
*
)
data
;
struct
dev_priv
*
priv
=
netdev_priv
(
dev
);
ether3_outw
(
priv
(
dev
)
->
regs
.
config2
|=
CFG2_CTRLO
,
REG_CONFIG2
);
ether3_outw
(
priv
->
regs
.
config2
|=
CFG2_CTRLO
,
REG_CONFIG2
);
}
}
/*
/*
* switch LED on...
* switch LED on...
*/
*/
static
inline
void
static
inline
void
ether3_ledon
(
struct
net_device
*
dev
)
ether3_ledon
(
struct
net_device
*
dev
,
struct
dev_priv
*
priv
)
{
{
del_timer
(
&
priv
->
timer
);
del_timer
(
&
priv
(
dev
)
->
timer
);
priv
->
timer
.
expires
=
jiffies
+
HZ
/
50
;
/* leave on for 1/50th second */
priv
(
dev
)
->
timer
.
expires
=
jiffies
+
HZ
/
50
;
/* leave on for 1/50th second */
priv
->
timer
.
data
=
(
unsigned
long
)
dev
;
priv
(
dev
)
->
timer
.
data
=
(
unsigned
long
)
dev
;
priv
->
timer
.
function
=
ether3_ledoff
;
priv
(
dev
)
->
timer
.
function
=
ether3_ledoff
;
add_timer
(
&
priv
->
timer
);
add_timer
(
&
priv
(
dev
)
->
timer
);
if
(
priv
->
regs
.
config2
&
CFG2_CTRLO
)
if
(
priv
(
dev
)
->
regs
.
config2
&
CFG2_CTRLO
)
ether3_outw
(
priv
->
regs
.
config2
&=
~
CFG2_CTRLO
,
REG_CONFIG2
);
ether3_outw
(
priv
(
dev
)
->
regs
.
config2
&=
~
CFG2_CTRLO
,
REG_CONFIG2
);
}
}
/*
/*
...
@@ -277,43 +273,41 @@ ether3_ramtest(struct net_device *dev, unsigned char byte)
...
@@ -277,43 +273,41 @@ ether3_ramtest(struct net_device *dev, unsigned char byte)
/* ------------------------------------------------------------------------------- */
/* ------------------------------------------------------------------------------- */
static
int
__init
static
int
__init
ether3_init_2
(
struct
net_device
*
dev
)
ether3_init_2
(
struct
net_device
*
dev
)
{
{
struct
dev_priv
*
priv
=
netdev_priv
(
dev
);
int
i
;
int
i
;
priv
->
regs
.
config1
=
CFG1_RECVCOMPSTAT0
|
CFG1_DMABURST8
;
priv
(
dev
)
->
regs
.
config1
=
CFG1_RECVCOMPSTAT0
|
CFG1_DMABURST8
;
priv
->
regs
.
config2
=
CFG2_CTRLO
|
CFG2_RECVCRC
|
CFG2_ERRENCRC
;
priv
(
dev
)
->
regs
.
config2
=
CFG2_CTRLO
|
CFG2_RECVCRC
|
CFG2_ERRENCRC
;
priv
->
regs
.
command
=
0
;
priv
(
dev
)
->
regs
.
command
=
0
;
/*
/*
* Set up our hardware address
* Set up our hardware address
*/
*/
ether3_outw
(
priv
->
regs
.
config1
|
CFG1_BUFSELSTAT0
,
REG_CONFIG1
);
ether3_outw
(
priv
(
dev
)
->
regs
.
config1
|
CFG1_BUFSELSTAT0
,
REG_CONFIG1
);
for
(
i
=
0
;
i
<
6
;
i
++
)
for
(
i
=
0
;
i
<
6
;
i
++
)
ether3_outb
(
dev
->
dev_addr
[
i
],
REG_BUFWIN
);
ether3_outb
(
dev
->
dev_addr
[
i
],
REG_BUFWIN
);
if
(
dev
->
flags
&
IFF_PROMISC
)
if
(
dev
->
flags
&
IFF_PROMISC
)
priv
->
regs
.
config1
|=
CFG1_RECVPROMISC
;
priv
(
dev
)
->
regs
.
config1
|=
CFG1_RECVPROMISC
;
else
if
(
dev
->
flags
&
IFF_MULTICAST
)
else
if
(
dev
->
flags
&
IFF_MULTICAST
)
priv
->
regs
.
config1
|=
CFG1_RECVSPECBRMULTI
;
priv
(
dev
)
->
regs
.
config1
|=
CFG1_RECVSPECBRMULTI
;
else
else
priv
->
regs
.
config1
|=
CFG1_RECVSPECBROAD
;
priv
(
dev
)
->
regs
.
config1
|=
CFG1_RECVSPECBROAD
;
/*
/*
* There is a problem with the NQ8005 in that it occasionally loses the
* There is a problem with the NQ8005 in that it occasionally loses the
* last two bytes. To get round this problem, we receive the CRC as
* last two bytes. To get round this problem, we receive the CRC as
* well. That way, if we do lose the last two, then it doesn't matter.
* well. That way, if we do lose the last two, then it doesn't matter.
*/
*/
ether3_outw
(
priv
->
regs
.
config1
|
CFG1_TRANSEND
,
REG_CONFIG1
);
ether3_outw
(
priv
(
dev
)
->
regs
.
config1
|
CFG1_TRANSEND
,
REG_CONFIG1
);
ether3_outw
((
TX_END
>>
8
)
-
1
,
REG_BUFWIN
);
ether3_outw
((
TX_END
>>
8
)
-
1
,
REG_BUFWIN
);
ether3_outw
(
priv
->
rx_head
,
REG_RECVPTR
);
ether3_outw
(
priv
(
dev
)
->
rx_head
,
REG_RECVPTR
);
ether3_outw
(
0
,
REG_TRANSMITPTR
);
ether3_outw
(
0
,
REG_TRANSMITPTR
);
ether3_outw
(
priv
->
rx_head
>>
8
,
REG_RECVEND
);
ether3_outw
(
priv
(
dev
)
->
rx_head
>>
8
,
REG_RECVEND
);
ether3_outw
(
priv
->
regs
.
config2
,
REG_CONFIG2
);
ether3_outw
(
priv
(
dev
)
->
regs
.
config2
,
REG_CONFIG2
);
ether3_outw
(
priv
->
regs
.
config1
|
CFG1_LOCBUFMEM
,
REG_CONFIG1
);
ether3_outw
(
priv
(
dev
)
->
regs
.
config1
|
CFG1_LOCBUFMEM
,
REG_CONFIG1
);
ether3_outw
(
priv
->
regs
.
command
,
REG_COMMAND
);
ether3_outw
(
priv
(
dev
)
->
regs
.
command
,
REG_COMMAND
);
i
=
ether3_ramtest
(
dev
,
0x5A
);
i
=
ether3_ramtest
(
dev
,
0x5A
);
if
(
i
)
if
(
i
)
...
@@ -330,41 +324,40 @@ ether3_init_2(struct net_device *dev)
...
@@ -330,41 +324,40 @@ ether3_init_2(struct net_device *dev)
static
void
static
void
ether3_init_for_open
(
struct
net_device
*
dev
)
ether3_init_for_open
(
struct
net_device
*
dev
)
{
{
struct
dev_priv
*
priv
=
netdev_priv
(
dev
);
int
i
;
int
i
;
memset
(
&
priv
->
stats
,
0
,
sizeof
(
struct
net_device_stats
));
memset
(
&
priv
(
dev
)
->
stats
,
0
,
sizeof
(
struct
net_device_stats
));
/* Reset the chip */
/* Reset the chip */
ether3_outw
(
CFG2_RESET
,
REG_CONFIG2
);
ether3_outw
(
CFG2_RESET
,
REG_CONFIG2
);
udelay
(
4
);
udelay
(
4
);
priv
->
regs
.
command
=
0
;
priv
(
dev
)
->
regs
.
command
=
0
;
ether3_outw
(
CMD_RXOFF
|
CMD_TXOFF
,
REG_COMMAND
);
ether3_outw
(
CMD_RXOFF
|
CMD_TXOFF
,
REG_COMMAND
);
while
(
ether3_inw
(
REG_STATUS
)
&
(
STAT_RXON
|
STAT_TXON
));
while
(
ether3_inw
(
REG_STATUS
)
&
(
STAT_RXON
|
STAT_TXON
));
ether3_outw
(
priv
->
regs
.
config1
|
CFG1_BUFSELSTAT0
,
REG_CONFIG1
);
ether3_outw
(
priv
(
dev
)
->
regs
.
config1
|
CFG1_BUFSELSTAT0
,
REG_CONFIG1
);
for
(
i
=
0
;
i
<
6
;
i
++
)
for
(
i
=
0
;
i
<
6
;
i
++
)
ether3_outb
(
dev
->
dev_addr
[
i
],
REG_BUFWIN
);
ether3_outb
(
dev
->
dev_addr
[
i
],
REG_BUFWIN
);
priv
->
tx_head
=
0
;
priv
(
dev
)
->
tx_head
=
0
;
priv
->
tx_tail
=
0
;
priv
(
dev
)
->
tx_tail
=
0
;
priv
->
regs
.
config2
|=
CFG2_CTRLO
;
priv
(
dev
)
->
regs
.
config2
|=
CFG2_CTRLO
;
priv
->
rx_head
=
RX_START
;
priv
(
dev
)
->
rx_head
=
RX_START
;
ether3_outw
(
priv
->
regs
.
config1
|
CFG1_TRANSEND
,
REG_CONFIG1
);
ether3_outw
(
priv
(
dev
)
->
regs
.
config1
|
CFG1_TRANSEND
,
REG_CONFIG1
);
ether3_outw
((
TX_END
>>
8
)
-
1
,
REG_BUFWIN
);
ether3_outw
((
TX_END
>>
8
)
-
1
,
REG_BUFWIN
);
ether3_outw
(
priv
->
rx_head
,
REG_RECVPTR
);
ether3_outw
(
priv
(
dev
)
->
rx_head
,
REG_RECVPTR
);
ether3_outw
(
priv
->
rx_head
>>
8
,
REG_RECVEND
);
ether3_outw
(
priv
(
dev
)
->
rx_head
>>
8
,
REG_RECVEND
);
ether3_outw
(
0
,
REG_TRANSMITPTR
);
ether3_outw
(
0
,
REG_TRANSMITPTR
);
ether3_outw
(
priv
->
regs
.
config2
,
REG_CONFIG2
);
ether3_outw
(
priv
(
dev
)
->
regs
.
config2
,
REG_CONFIG2
);
ether3_outw
(
priv
->
regs
.
config1
|
CFG1_LOCBUFMEM
,
REG_CONFIG1
);
ether3_outw
(
priv
(
dev
)
->
regs
.
config1
|
CFG1_LOCBUFMEM
,
REG_CONFIG1
);
ether3_setbuffer
(
dev
,
buffer_write
,
0
);
ether3_setbuffer
(
dev
,
buffer_write
,
0
);
ether3_writelong
(
dev
,
0
);
ether3_writelong
(
dev
,
0
);
priv
->
regs
.
command
=
CMD_ENINTRX
|
CMD_ENINTTX
;
priv
(
dev
)
->
regs
.
command
=
CMD_ENINTRX
|
CMD_ENINTTX
;
ether3_outw
(
priv
->
regs
.
command
|
CMD_RXON
,
REG_COMMAND
);
ether3_outw
(
priv
(
dev
)
->
regs
.
command
|
CMD_RXON
,
REG_COMMAND
);
}
}
static
inline
int
static
inline
int
...
@@ -434,14 +427,12 @@ ether3_open(struct net_device *dev)
...
@@ -434,14 +427,12 @@ ether3_open(struct net_device *dev)
static
int
static
int
ether3_close
(
struct
net_device
*
dev
)
ether3_close
(
struct
net_device
*
dev
)
{
{
struct
dev_priv
*
priv
=
netdev_priv
(
dev
);
netif_stop_queue
(
dev
);
netif_stop_queue
(
dev
);
disable_irq
(
dev
->
irq
);
disable_irq
(
dev
->
irq
);
ether3_outw
(
CMD_RXOFF
|
CMD_TXOFF
,
REG_COMMAND
);
ether3_outw
(
CMD_RXOFF
|
CMD_TXOFF
,
REG_COMMAND
);
priv
->
regs
.
command
=
0
;
priv
(
dev
)
->
regs
.
command
=
0
;
while
(
ether3_inw
(
REG_STATUS
)
&
(
STAT_RXON
|
STAT_TXON
));
while
(
ether3_inw
(
REG_STATUS
)
&
(
STAT_RXON
|
STAT_TXON
));
ether3_outb
(
0x80
,
REG_CONFIG2
+
1
);
ether3_outb
(
0x80
,
REG_CONFIG2
+
1
);
ether3_outw
(
0
,
REG_COMMAND
);
ether3_outw
(
0
,
REG_COMMAND
);
...
@@ -457,8 +448,7 @@ ether3_close(struct net_device *dev)
...
@@ -457,8 +448,7 @@ ether3_close(struct net_device *dev)
*/
*/
static
struct
net_device_stats
*
ether3_getstats
(
struct
net_device
*
dev
)
static
struct
net_device_stats
*
ether3_getstats
(
struct
net_device
*
dev
)
{
{
struct
dev_priv
*
priv
=
netdev_priv
(
dev
);
return
&
priv
(
dev
)
->
stats
;
return
&
priv
->
stats
;
}
}
/*
/*
...
@@ -469,28 +459,24 @@ static struct net_device_stats *ether3_getstats(struct net_device *dev)
...
@@ -469,28 +459,24 @@ static struct net_device_stats *ether3_getstats(struct net_device *dev)
*/
*/
static
void
ether3_setmulticastlist
(
struct
net_device
*
dev
)
static
void
ether3_setmulticastlist
(
struct
net_device
*
dev
)
{
{
struct
dev_priv
*
priv
=
netdev_priv
(
dev
);
priv
(
dev
)
->
regs
.
config1
&=
~
CFG1_RECVPROMISC
;
priv
->
regs
.
config1
&=
~
CFG1_RECVPROMISC
;
if
(
dev
->
flags
&
IFF_PROMISC
)
{
if
(
dev
->
flags
&
IFF_PROMISC
)
{
/* promiscuous mode */
/* promiscuous mode */
priv
->
regs
.
config1
|=
CFG1_RECVPROMISC
;
priv
(
dev
)
->
regs
.
config1
|=
CFG1_RECVPROMISC
;
}
else
if
(
dev
->
flags
&
IFF_ALLMULTI
)
{
}
else
if
(
dev
->
flags
&
IFF_ALLMULTI
)
{
priv
->
regs
.
config1
|=
CFG1_RECVSPECBRMULTI
;
priv
(
dev
)
->
regs
.
config1
|=
CFG1_RECVSPECBRMULTI
;
}
else
}
else
priv
->
regs
.
config1
|=
CFG1_RECVSPECBROAD
;
priv
(
dev
)
->
regs
.
config1
|=
CFG1_RECVSPECBROAD
;
ether3_outw
(
priv
->
regs
.
config1
|
CFG1_LOCBUFMEM
,
REG_CONFIG1
);
ether3_outw
(
priv
(
dev
)
->
regs
.
config1
|
CFG1_LOCBUFMEM
,
REG_CONFIG1
);
}
}
static
void
static
void
ether3_timeout
(
struct
net_device
*
dev
)
ether3_timeout
(
struct
net_device
*
dev
)
{
{
struct
dev_priv
*
priv
=
netdev_priv
(
dev
);
unsigned
long
flags
;
unsigned
long
flags
;
del_timer
(
&
priv
->
timer
);
del_timer
(
&
priv
(
dev
)
->
timer
);
local_irq_save
(
flags
);
local_irq_save
(
flags
);
printk
(
KERN_ERR
"%s: transmit timed out, network cable problem?
\n
"
,
dev
->
name
);
printk
(
KERN_ERR
"%s: transmit timed out, network cable problem?
\n
"
,
dev
->
name
);
...
@@ -499,15 +485,15 @@ ether3_timeout(struct net_device *dev)
...
@@ -499,15 +485,15 @@ ether3_timeout(struct net_device *dev)
printk
(
KERN_ERR
"%s: { rpr=%04X rea=%04X tpr=%04X }
\n
"
,
dev
->
name
,
printk
(
KERN_ERR
"%s: { rpr=%04X rea=%04X tpr=%04X }
\n
"
,
dev
->
name
,
ether3_inw
(
REG_RECVPTR
),
ether3_inw
(
REG_RECVEND
),
ether3_inw
(
REG_TRANSMITPTR
));
ether3_inw
(
REG_RECVPTR
),
ether3_inw
(
REG_RECVEND
),
ether3_inw
(
REG_TRANSMITPTR
));
printk
(
KERN_ERR
"%s: tx head=%X tx tail=%X
\n
"
,
dev
->
name
,
printk
(
KERN_ERR
"%s: tx head=%X tx tail=%X
\n
"
,
dev
->
name
,
priv
->
tx_head
,
priv
->
tx_tail
);
priv
(
dev
)
->
tx_head
,
priv
(
dev
)
->
tx_tail
);
ether3_setbuffer
(
dev
,
buffer_read
,
priv
->
tx_tail
);
ether3_setbuffer
(
dev
,
buffer_read
,
priv
(
dev
)
->
tx_tail
);
printk
(
KERN_ERR
"%s: packet status = %08X
\n
"
,
dev
->
name
,
ether3_readlong
(
dev
));
printk
(
KERN_ERR
"%s: packet status = %08X
\n
"
,
dev
->
name
,
ether3_readlong
(
dev
));
local_irq_restore
(
flags
);
local_irq_restore
(
flags
);
priv
->
regs
.
config2
|=
CFG2_CTRLO
;
priv
(
dev
)
->
regs
.
config2
|=
CFG2_CTRLO
;
priv
->
stats
.
tx_errors
+=
1
;
priv
(
dev
)
->
stats
.
tx_errors
+=
1
;
ether3_outw
(
priv
->
regs
.
config2
,
REG_CONFIG2
);
ether3_outw
(
priv
(
dev
)
->
regs
.
config2
,
REG_CONFIG2
);
priv
->
tx_head
=
priv
->
tx_tail
=
0
;
priv
(
dev
)
->
tx_head
=
priv
(
dev
)
->
tx_tail
=
0
;
netif_wake_queue
(
dev
);
netif_wake_queue
(
dev
);
}
}
...
@@ -518,14 +504,13 @@ ether3_timeout(struct net_device *dev)
...
@@ -518,14 +504,13 @@ ether3_timeout(struct net_device *dev)
static
int
static
int
ether3_sendpacket
(
struct
sk_buff
*
skb
,
struct
net_device
*
dev
)
ether3_sendpacket
(
struct
sk_buff
*
skb
,
struct
net_device
*
dev
)
{
{
struct
dev_priv
*
priv
=
netdev_priv
(
dev
);
unsigned
long
flags
;
unsigned
long
flags
;
unsigned
int
length
=
ETH_ZLEN
<
skb
->
len
?
skb
->
len
:
ETH_ZLEN
;
unsigned
int
length
=
ETH_ZLEN
<
skb
->
len
?
skb
->
len
:
ETH_ZLEN
;
unsigned
int
ptr
,
next_ptr
;
unsigned
int
ptr
,
next_ptr
;
if
(
priv
->
broken
)
{
if
(
priv
(
dev
)
->
broken
)
{
dev_kfree_skb
(
skb
);
dev_kfree_skb
(
skb
);
priv
->
stats
.
tx_dropped
++
;
priv
(
dev
)
->
stats
.
tx_dropped
++
;
netif_start_queue
(
dev
);
netif_start_queue
(
dev
);
return
0
;
return
0
;
}
}
...
@@ -537,18 +522,18 @@ ether3_sendpacket(struct sk_buff *skb, struct net_device *dev)
...
@@ -537,18 +522,18 @@ ether3_sendpacket(struct sk_buff *skb, struct net_device *dev)
goto
out
;
goto
out
;
}
}
next_ptr
=
(
priv
->
tx_head
+
1
)
&
15
;
next_ptr
=
(
priv
(
dev
)
->
tx_head
+
1
)
&
15
;
local_irq_save
(
flags
);
local_irq_save
(
flags
);
if
(
priv
->
tx_tail
==
next_ptr
)
{
if
(
priv
(
dev
)
->
tx_tail
==
next_ptr
)
{
local_irq_restore
(
flags
);
local_irq_restore
(
flags
);
return
1
;
/* unable to queue */
return
1
;
/* unable to queue */
}
}
dev
->
trans_start
=
jiffies
;
dev
->
trans_start
=
jiffies
;
ptr
=
0x600
*
priv
->
tx_head
;
ptr
=
0x600
*
priv
(
dev
)
->
tx_head
;
priv
->
tx_head
=
next_ptr
;
priv
(
dev
)
->
tx_head
=
next_ptr
;
next_ptr
*=
0x600
;
next_ptr
*=
0x600
;
#define TXHDR_FLAGS (TXHDR_TRANSMIT|TXHDR_CHAINCONTINUE|TXHDR_DATAFOLLOWS|TXHDR_ENSUCCESS)
#define TXHDR_FLAGS (TXHDR_TRANSMIT|TXHDR_CHAINCONTINUE|TXHDR_DATAFOLLOWS|TXHDR_ENSUCCESS)
...
@@ -563,19 +548,19 @@ ether3_sendpacket(struct sk_buff *skb, struct net_device *dev)
...
@@ -563,19 +548,19 @@ ether3_sendpacket(struct sk_buff *skb, struct net_device *dev)
ether3_setbuffer
(
dev
,
buffer_write
,
ptr
);
ether3_setbuffer
(
dev
,
buffer_write
,
ptr
);
ether3_writeword
(
dev
,
htons
((
ptr
+
length
+
4
)));
ether3_writeword
(
dev
,
htons
((
ptr
+
length
+
4
)));
ether3_writeword
(
dev
,
TXHDR_FLAGS
>>
16
);
ether3_writeword
(
dev
,
TXHDR_FLAGS
>>
16
);
ether3_ledon
(
dev
,
priv
);
ether3_ledon
(
dev
);
if
(
!
(
ether3_inw
(
REG_STATUS
)
&
STAT_TXON
))
{
if
(
!
(
ether3_inw
(
REG_STATUS
)
&
STAT_TXON
))
{
ether3_outw
(
ptr
,
REG_TRANSMITPTR
);
ether3_outw
(
ptr
,
REG_TRANSMITPTR
);
ether3_outw
(
priv
->
regs
.
command
|
CMD_TXON
,
REG_COMMAND
);
ether3_outw
(
priv
(
dev
)
->
regs
.
command
|
CMD_TXON
,
REG_COMMAND
);
}
}
next_ptr
=
(
priv
->
tx_head
+
1
)
&
15
;
next_ptr
=
(
priv
(
dev
)
->
tx_head
+
1
)
&
15
;
local_irq_restore
(
flags
);
local_irq_restore
(
flags
);
dev_kfree_skb
(
skb
);
dev_kfree_skb
(
skb
);
if
(
priv
->
tx_tail
==
next_ptr
)
if
(
priv
(
dev
)
->
tx_tail
==
next_ptr
)
netif_stop_queue
(
dev
);
netif_stop_queue
(
dev
);
out:
out:
...
@@ -586,7 +571,6 @@ static irqreturn_t
...
@@ -586,7 +571,6 @@ static irqreturn_t
ether3_interrupt
(
int
irq
,
void
*
dev_id
,
struct
pt_regs
*
regs
)
ether3_interrupt
(
int
irq
,
void
*
dev_id
,
struct
pt_regs
*
regs
)
{
{
struct
net_device
*
dev
=
(
struct
net_device
*
)
dev_id
;
struct
net_device
*
dev
=
(
struct
net_device
*
)
dev_id
;
struct
dev_priv
*
priv
;
unsigned
int
status
,
handled
=
IRQ_NONE
;
unsigned
int
status
,
handled
=
IRQ_NONE
;
#if NET_DEBUG > 1
#if NET_DEBUG > 1
...
@@ -594,19 +578,17 @@ ether3_interrupt(int irq, void *dev_id, struct pt_regs *regs)
...
@@ -594,19 +578,17 @@ ether3_interrupt(int irq, void *dev_id, struct pt_regs *regs)
printk
(
"eth3irq: %d "
,
irq
);
printk
(
"eth3irq: %d "
,
irq
);
#endif
#endif
priv
=
netdev_priv
(
dev
);
status
=
ether3_inw
(
REG_STATUS
);
status
=
ether3_inw
(
REG_STATUS
);
if
(
status
&
STAT_INTRX
)
{
if
(
status
&
STAT_INTRX
)
{
ether3_outw
(
CMD_ACKINTRX
|
priv
->
regs
.
command
,
REG_COMMAND
);
ether3_outw
(
CMD_ACKINTRX
|
priv
(
dev
)
->
regs
.
command
,
REG_COMMAND
);
ether3_rx
(
dev
,
priv
,
12
);
ether3_rx
(
dev
,
12
);
handled
=
IRQ_HANDLED
;
handled
=
IRQ_HANDLED
;
}
}
if
(
status
&
STAT_INTTX
)
{
if
(
status
&
STAT_INTTX
)
{
ether3_outw
(
CMD_ACKINTTX
|
priv
->
regs
.
command
,
REG_COMMAND
);
ether3_outw
(
CMD_ACKINTTX
|
priv
(
dev
)
->
regs
.
command
,
REG_COMMAND
);
ether3_tx
(
dev
,
priv
);
ether3_tx
(
dev
);
handled
=
IRQ_HANDLED
;
handled
=
IRQ_HANDLED
;
}
}
...
@@ -620,11 +602,11 @@ ether3_interrupt(int irq, void *dev_id, struct pt_regs *regs)
...
@@ -620,11 +602,11 @@ ether3_interrupt(int irq, void *dev_id, struct pt_regs *regs)
/*
/*
* If we have a good packet(s), get it/them out of the buffers.
* If we have a good packet(s), get it/them out of the buffers.
*/
*/
static
int
static
int
ether3_rx
(
struct
net_device
*
dev
,
unsigned
int
maxcnt
)
ether3_rx
(
struct
net_device
*
dev
,
struct
dev_priv
*
priv
,
unsigned
int
maxcnt
)
{
{
unsigned
int
next_ptr
=
priv
->
rx_head
,
received
=
0
;
unsigned
int
next_ptr
=
priv
(
dev
)
->
rx_head
,
received
=
0
;
ether3_ledon
(
dev
,
priv
);
ether3_ledon
(
dev
);
do
{
do
{
unsigned
int
this_ptr
,
status
;
unsigned
int
this_ptr
,
status
;
...
@@ -653,12 +635,12 @@ ether3_rx(struct net_device *dev, struct dev_priv *priv, unsigned int maxcnt)
...
@@ -653,12 +635,12 @@ ether3_rx(struct net_device *dev, struct dev_priv *priv, unsigned int maxcnt)
if
(
next_ptr
<
RX_START
||
next_ptr
>=
RX_END
)
{
if
(
next_ptr
<
RX_START
||
next_ptr
>=
RX_END
)
{
int
i
;
int
i
;
printk
(
"%s: bad next pointer @%04X: "
,
dev
->
name
,
priv
->
rx_head
);
printk
(
"%s: bad next pointer @%04X: "
,
dev
->
name
,
priv
(
dev
)
->
rx_head
);
printk
(
"%02X %02X %02X %02X "
,
next_ptr
>>
8
,
next_ptr
&
255
,
status
&
255
,
status
>>
8
);
printk
(
"%02X %02X %02X %02X "
,
next_ptr
>>
8
,
next_ptr
&
255
,
status
&
255
,
status
>>
8
);
for
(
i
=
2
;
i
<
14
;
i
++
)
for
(
i
=
2
;
i
<
14
;
i
++
)
printk
(
"%02X "
,
addrs
[
i
]);
printk
(
"%02X "
,
addrs
[
i
]);
printk
(
"
\n
"
);
printk
(
"
\n
"
);
next_ptr
=
priv
->
rx_head
;
next_ptr
=
priv
(
dev
)
->
rx_head
;
break
;
break
;
}
}
/*
/*
...
@@ -695,7 +677,7 @@ if (next_ptr < RX_START || next_ptr >= RX_END) {
...
@@ -695,7 +677,7 @@ if (next_ptr < RX_START || next_ptr >= RX_END) {
}
else
}
else
goto
dropping
;
goto
dropping
;
}
else
{
}
else
{
struct
net_device_stats
*
stats
=
&
priv
->
stats
;
struct
net_device_stats
*
stats
=
&
priv
(
dev
)
->
stats
;
ether3_outw
(
next_ptr
>>
8
,
REG_RECVEND
);
ether3_outw
(
next_ptr
>>
8
,
REG_RECVEND
);
if
(
status
&
RXSTAT_OVERSIZE
)
stats
->
rx_over_errors
++
;
if
(
status
&
RXSTAT_OVERSIZE
)
stats
->
rx_over_errors
++
;
if
(
status
&
RXSTAT_CRCERROR
)
stats
->
rx_crc_errors
++
;
if
(
status
&
RXSTAT_CRCERROR
)
stats
->
rx_crc_errors
++
;
...
@@ -707,16 +689,16 @@ if (next_ptr < RX_START || next_ptr >= RX_END) {
...
@@ -707,16 +689,16 @@ if (next_ptr < RX_START || next_ptr >= RX_END) {
while
(
--
maxcnt
);
while
(
--
maxcnt
);
done:
done:
priv
->
stats
.
rx_packets
+=
received
;
priv
(
dev
)
->
stats
.
rx_packets
+=
received
;
priv
->
rx_head
=
next_ptr
;
priv
(
dev
)
->
rx_head
=
next_ptr
;
/*
/*
* If rx went off line, then that means that the buffer may be full. We
* If rx went off line, then that means that the buffer may be full. We
* have dropped at least one packet.
* have dropped at least one packet.
*/
*/
if
(
!
(
ether3_inw
(
REG_STATUS
)
&
STAT_RXON
))
{
if
(
!
(
ether3_inw
(
REG_STATUS
)
&
STAT_RXON
))
{
priv
->
stats
.
rx_dropped
++
;
priv
(
dev
)
->
stats
.
rx_dropped
++
;
ether3_outw
(
next_ptr
,
REG_RECVPTR
);
ether3_outw
(
next_ptr
,
REG_RECVPTR
);
ether3_outw
(
priv
->
regs
.
command
|
CMD_RXON
,
REG_COMMAND
);
ether3_outw
(
priv
(
dev
)
->
regs
.
command
|
CMD_RXON
,
REG_COMMAND
);
}
}
return
maxcnt
;
return
maxcnt
;
...
@@ -732,7 +714,7 @@ dropping:{
...
@@ -732,7 +714,7 @@ dropping:{
last_warned
=
jiffies
;
last_warned
=
jiffies
;
printk
(
"%s: memory squeeze, dropping packet.
\n
"
,
dev
->
name
);
printk
(
"%s: memory squeeze, dropping packet.
\n
"
,
dev
->
name
);
}
}
priv
->
stats
.
rx_dropped
++
;
priv
(
dev
)
->
stats
.
rx_dropped
++
;
goto
done
;
goto
done
;
}
}
}
}
...
@@ -740,10 +722,9 @@ dropping:{
...
@@ -740,10 +722,9 @@ dropping:{
/*
/*
* Update stats for the transmitted packet(s)
* Update stats for the transmitted packet(s)
*/
*/
static
void
static
void
ether3_tx
(
struct
net_device
*
dev
)
ether3_tx
(
struct
net_device
*
dev
,
struct
dev_priv
*
priv
)
{
{
unsigned
int
tx_tail
=
priv
->
tx_tail
;
unsigned
int
tx_tail
=
priv
(
dev
)
->
tx_tail
;
int
max_work
=
14
;
int
max_work
=
14
;
do
{
do
{
...
@@ -766,18 +747,20 @@ ether3_tx(struct net_device *dev, struct dev_priv *priv)
...
@@ -766,18 +747,20 @@ ether3_tx(struct net_device *dev, struct dev_priv *priv)
* Update errors
* Update errors
*/
*/
if
(
!
(
status
&
(
TXSTAT_BABBLED
|
TXSTAT_16COLLISIONS
)))
if
(
!
(
status
&
(
TXSTAT_BABBLED
|
TXSTAT_16COLLISIONS
)))
priv
->
stats
.
tx_packets
++
;
priv
(
dev
)
->
stats
.
tx_packets
++
;
else
{
else
{
priv
->
stats
.
tx_errors
++
;
priv
(
dev
)
->
stats
.
tx_errors
++
;
if
(
status
&
TXSTAT_16COLLISIONS
)
priv
->
stats
.
collisions
+=
16
;
if
(
status
&
TXSTAT_16COLLISIONS
)
if
(
status
&
TXSTAT_BABBLED
)
priv
->
stats
.
tx_fifo_errors
++
;
priv
(
dev
)
->
stats
.
collisions
+=
16
;
if
(
status
&
TXSTAT_BABBLED
)
priv
(
dev
)
->
stats
.
tx_fifo_errors
++
;
}
}
tx_tail
=
(
tx_tail
+
1
)
&
15
;
tx_tail
=
(
tx_tail
+
1
)
&
15
;
}
while
(
--
max_work
);
}
while
(
--
max_work
);
if
(
priv
->
tx_tail
!=
tx_tail
)
{
if
(
priv
(
dev
)
->
tx_tail
!=
tx_tail
)
{
priv
->
tx_tail
=
tx_tail
;
priv
(
dev
)
->
tx_tail
=
tx_tail
;
netif_wake_queue
(
dev
);
netif_wake_queue
(
dev
);
}
}
}
}
...
@@ -816,7 +799,6 @@ static int __devinit
...
@@ -816,7 +799,6 @@ static int __devinit
ether3_probe
(
struct
expansion_card
*
ec
,
const
struct
ecard_id
*
id
)
ether3_probe
(
struct
expansion_card
*
ec
,
const
struct
ecard_id
*
id
)
{
{
struct
net_device
*
dev
;
struct
net_device
*
dev
;
struct
dev_priv
*
priv
;
const
char
*
name
;
const
char
*
name
;
int
i
,
bus_type
,
ret
;
int
i
,
bus_type
,
ret
;
...
@@ -844,8 +826,7 @@ ether3_probe(struct expansion_card *ec, const struct ecard_id *id)
...
@@ -844,8 +826,7 @@ ether3_probe(struct expansion_card *ec, const struct ecard_id *id)
goto
free
;
goto
free
;
}
}
priv
=
netdev_priv
(
dev
);
init_timer
(
&
priv
(
dev
)
->
timer
);
init_timer
(
&
priv
->
timer
);
/* Reset card...
/* Reset card...
*/
*/
...
...
drivers/net/arm/ether3.h
View file @
7af60616
...
@@ -22,6 +22,8 @@
...
@@ -22,6 +22,8 @@
#define NET_DEBUG 0
#define NET_DEBUG 0
#endif
#endif
#define priv(dev) ((struct dev_priv *)netdev_priv(dev))
/* Command register definitions & bits */
/* Command register definitions & bits */
#define REG_COMMAND (dev->base_addr + 0x00)
#define REG_COMMAND (dev->base_addr + 0x00)
#define CMD_ENINTDMA 0x0001
#define CMD_ENINTDMA 0x0001
...
...
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