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
a49b9154
Commit
a49b9154
authored
May 10, 2004
by
Linus Torvalds
Browse files
Options
Browse Files
Download
Plain Diff
Merge
bk://gkernel.bkbits.net/net-drivers-2.6
into ppc970.osdl.org:/home/torvalds/v2.6/linux
parents
fec95414
6b5501ef
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
384 additions
and
297 deletions
+384
-297
drivers/net/8139too.c
drivers/net/8139too.c
+11
-15
drivers/net/b44.c
drivers/net/b44.c
+252
-271
drivers/net/b44.h
drivers/net/b44.h
+2
-0
drivers/net/pcnet32.c
drivers/net/pcnet32.c
+119
-11
No files found.
drivers/net/8139too.c
View file @
a49b9154
...
...
@@ -1677,11 +1677,17 @@ static void rtl8139_tx_timeout (struct net_device *dev)
u8
tmp8
;
unsigned
long
flags
;
DPRINTK
(
"%s: Transmit timeout, status %2.2x %4.4x "
"media %2.2x.
\n
"
,
dev
->
name
,
RTL_R8
(
ChipCmd
),
RTL_R16
(
IntrStatus
),
RTL_R8
(
MediaStatus
));
printk
(
KERN_DEBUG
"%s: Transmit timeout, status %2.2x %4.4x %4.4x "
"media %2.2x.
\n
"
,
dev
->
name
,
RTL_R8
(
ChipCmd
),
RTL_R16
(
IntrStatus
),
RTL_R16
(
IntrMask
),
RTL_R8
(
MediaStatus
));
/* Emit info to figure out what went wrong. */
printk
(
KERN_DEBUG
"%s: Tx queue start entry %ld dirty entry %ld.
\n
"
,
dev
->
name
,
tp
->
cur_tx
,
tp
->
dirty_tx
);
for
(
i
=
0
;
i
<
NUM_TX_DESC
;
i
++
)
printk
(
KERN_DEBUG
"%s: Tx descriptor %d is %8.8lx.%s
\n
"
,
dev
->
name
,
i
,
RTL_R32
(
TxStatus0
+
(
i
*
4
)),
i
==
tp
->
dirty_tx
%
NUM_TX_DESC
?
" (queue head)"
:
""
);
tp
->
xstats
.
tx_timeouts
++
;
...
...
@@ -1694,15 +1700,6 @@ static void rtl8139_tx_timeout (struct net_device *dev)
/* Disable interrupts by clearing the interrupt mask. */
RTL_W16
(
IntrMask
,
0x0000
);
/* Emit info to figure out what went wrong. */
printk
(
KERN_DEBUG
"%s: Tx queue start entry %ld dirty entry %ld.
\n
"
,
dev
->
name
,
tp
->
cur_tx
,
tp
->
dirty_tx
);
for
(
i
=
0
;
i
<
NUM_TX_DESC
;
i
++
)
printk
(
KERN_DEBUG
"%s: Tx descriptor %d is %8.8lx.%s
\n
"
,
dev
->
name
,
i
,
RTL_R32
(
TxStatus0
+
(
i
*
4
)),
i
==
tp
->
dirty_tx
%
NUM_TX_DESC
?
" (queue head)"
:
""
);
/* Stop a shared interrupt from scavenging while we are. */
spin_lock_irqsave
(
&
tp
->
lock
,
flags
);
rtl8139_tx_clear
(
tp
);
...
...
@@ -1714,7 +1711,6 @@ static void rtl8139_tx_timeout (struct net_device *dev)
netif_wake_queue
(
dev
);
}
spin_unlock
(
&
tp
->
rx_lock
);
}
...
...
drivers/net/b44.c
View file @
a49b9154
...
...
@@ -27,8 +27,8 @@
#define DRV_MODULE_NAME "b44"
#define PFX DRV_MODULE_NAME ": "
#define DRV_MODULE_VERSION "0.9
3
"
#define DRV_MODULE_RELDATE "Ma
r
, 2004"
#define DRV_MODULE_VERSION "0.9
4
"
#define DRV_MODULE_RELDATE "Ma
y 4
, 2004"
#define B44_DEF_MSG_ENABLE \
(NETIF_MSG_DRV | \
...
...
@@ -96,7 +96,7 @@ MODULE_DEVICE_TABLE(pci, b44_pci_tbl);
static
void
b44_halt
(
struct
b44
*
);
static
void
b44_init_rings
(
struct
b44
*
);
static
int
b44_init_hw
(
struct
b44
*
);
static
void
b44_init_hw
(
struct
b44
*
);
static
int
b44_wait_bit
(
struct
b44
*
bp
,
unsigned
long
reg
,
u32
bit
,
unsigned
long
timeout
,
const
int
clear
)
...
...
@@ -331,6 +331,29 @@ static int b44_writephy(struct b44 *bp, int reg, u32 val)
return
b44_wait_bit
(
bp
,
B44_EMAC_ISTAT
,
EMAC_INT_MII
,
100
,
0
);
}
/* miilib interface */
/* FIXME FIXME: phy_id is ignored, bp->phy_addr use is unconditional
* due to code existing before miilib use was added to this driver.
* Someone should remove this artificial driver limitation in
* b44_{read,write}phy. bp->phy_addr itself is fine (and needed).
*/
static
int
b44_mii_read
(
struct
net_device
*
dev
,
int
phy_id
,
int
location
)
{
u32
val
;
struct
b44
*
bp
=
netdev_priv
(
dev
);
int
rc
=
b44_readphy
(
bp
,
location
,
&
val
);
if
(
rc
)
return
0xffffffff
;
return
val
;
}
static
void
b44_mii_write
(
struct
net_device
*
dev
,
int
phy_id
,
int
location
,
int
val
)
{
struct
b44
*
bp
=
netdev_priv
(
dev
);
b44_writephy
(
bp
,
location
,
val
);
}
static
int
b44_phy_reset
(
struct
b44
*
bp
)
{
u32
val
;
...
...
@@ -771,7 +794,7 @@ static int b44_rx(struct b44 *bp, int budget)
static
int
b44_poll
(
struct
net_device
*
netdev
,
int
*
budget
)
{
struct
b44
*
bp
=
netdev
->
priv
;
struct
b44
*
bp
=
netdev
_priv
(
netdev
)
;
int
done
;
spin_lock_irq
(
&
bp
->
lock
);
...
...
@@ -821,7 +844,7 @@ static int b44_poll(struct net_device *netdev, int *budget)
static
irqreturn_t
b44_interrupt
(
int
irq
,
void
*
dev_id
,
struct
pt_regs
*
regs
)
{
struct
net_device
*
dev
=
dev_id
;
struct
b44
*
bp
=
dev
->
priv
;
struct
b44
*
bp
=
netdev_priv
(
dev
)
;
unsigned
long
flags
;
u32
istat
,
imask
;
int
handled
=
0
;
...
...
@@ -858,7 +881,7 @@ static irqreturn_t b44_interrupt(int irq, void *dev_id, struct pt_regs *regs)
static
void
b44_tx_timeout
(
struct
net_device
*
dev
)
{
struct
b44
*
bp
=
dev
->
priv
;
struct
b44
*
bp
=
netdev_priv
(
dev
)
;
printk
(
KERN_ERR
PFX
"%s: transmit timed out, resetting
\n
"
,
dev
->
name
);
...
...
@@ -878,7 +901,7 @@ static void b44_tx_timeout(struct net_device *dev)
static
int
b44_start_xmit
(
struct
sk_buff
*
skb
,
struct
net_device
*
dev
)
{
struct
b44
*
bp
=
dev
->
priv
;
struct
b44
*
bp
=
netdev_priv
(
dev
)
;
dma_addr_t
mapping
;
u32
len
,
entry
,
ctrl
;
...
...
@@ -932,7 +955,7 @@ static int b44_start_xmit(struct sk_buff *skb, struct net_device *dev)
static
int
b44_change_mtu
(
struct
net_device
*
dev
,
int
new_mtu
)
{
struct
b44
*
bp
=
dev
->
priv
;
struct
b44
*
bp
=
netdev_priv
(
dev
)
;
if
(
new_mtu
<
B44_MIN_MTU
||
new_mtu
>
B44_MAX_MTU
)
return
-
EINVAL
;
...
...
@@ -1161,7 +1184,7 @@ static void __b44_set_mac_addr(struct b44 *bp)
static
int
b44_set_mac_addr
(
struct
net_device
*
dev
,
void
*
p
)
{
struct
b44
*
bp
=
dev
->
priv
;
struct
b44
*
bp
=
netdev_priv
(
dev
)
;
struct
sockaddr
*
addr
=
p
;
if
(
netif_running
(
dev
))
...
...
@@ -1180,7 +1203,7 @@ static int b44_set_mac_addr(struct net_device *dev, void *p)
* packet processing. Invoked with bp->lock held.
*/
static
void
__b44_set_rx_mode
(
struct
net_device
*
);
static
int
b44_init_hw
(
struct
b44
*
bp
)
static
void
b44_init_hw
(
struct
b44
*
bp
)
{
u32
val
;
...
...
@@ -1212,13 +1235,11 @@ static int b44_init_hw(struct b44 *bp)
val
=
br32
(
B44_ENET_CTRL
);
bw32
(
B44_ENET_CTRL
,
(
val
|
ENET_CTRL_ENABLE
));
return
0
;
}
static
int
b44_open
(
struct
net_device
*
dev
)
{
struct
b44
*
bp
=
dev
->
priv
;
struct
b44
*
bp
=
netdev_priv
(
dev
)
;
int
err
;
err
=
b44_alloc_consistent
(
bp
);
...
...
@@ -1232,9 +1253,7 @@ static int b44_open(struct net_device *dev)
spin_lock_irq
(
&
bp
->
lock
);
b44_init_rings
(
bp
);
err
=
b44_init_hw
(
bp
);
if
(
err
)
goto
err_out_noinit
;
b44_init_hw
(
bp
);
bp
->
flags
|=
B44_FLAG_INIT_COMPLETE
;
spin_unlock_irq
(
&
bp
->
lock
);
...
...
@@ -1249,11 +1268,6 @@ static int b44_open(struct net_device *dev)
return
0
;
err_out_noinit:
b44_halt
(
bp
);
b44_free_rings
(
bp
);
spin_unlock_irq
(
&
bp
->
lock
);
free_irq
(
dev
->
irq
,
dev
);
err_out_free:
b44_free_consistent
(
bp
);
return
err
;
...
...
@@ -1273,7 +1287,7 @@ static int b44_open(struct net_device *dev)
static
int
b44_close
(
struct
net_device
*
dev
)
{
struct
b44
*
bp
=
dev
->
priv
;
struct
b44
*
bp
=
netdev_priv
(
dev
)
;
netif_stop_queue
(
dev
);
...
...
@@ -1300,7 +1314,7 @@ static int b44_close(struct net_device *dev)
static
struct
net_device_stats
*
b44_get_stats
(
struct
net_device
*
dev
)
{
struct
b44
*
bp
=
dev
->
priv
;
struct
b44
*
bp
=
netdev_priv
(
dev
)
;
struct
net_device_stats
*
nstat
=
&
bp
->
stats
;
struct
b44_hw_stats
*
hwstat
=
&
bp
->
hw_stats
;
...
...
@@ -1351,7 +1365,7 @@ static void __b44_load_mcast(struct b44 *bp, struct net_device *dev)
static
void
__b44_set_rx_mode
(
struct
net_device
*
dev
)
{
struct
b44
*
bp
=
dev
->
priv
;
struct
b44
*
bp
=
netdev_priv
(
dev
)
;
u32
val
;
val
=
br32
(
B44_RXCONFIG
);
...
...
@@ -1375,295 +1389,252 @@ static void __b44_set_rx_mode(struct net_device *dev)
static
void
b44_set_rx_mode
(
struct
net_device
*
dev
)
{
struct
b44
*
bp
=
dev
->
priv
;
struct
b44
*
bp
=
netdev_priv
(
dev
)
;
spin_lock_irq
(
&
bp
->
lock
);
__b44_set_rx_mode
(
dev
);
spin_unlock_irq
(
&
bp
->
lock
);
}
static
int
b44_ethtool_ioctl
(
struct
net_device
*
dev
,
void
__user
*
useraddr
)
static
u32
b44_get_msglevel
(
struct
net_device
*
dev
)
{
struct
b44
*
bp
=
dev
->
priv
;
struct
b44
*
bp
=
netdev_priv
(
dev
);
return
bp
->
msg_enable
;
}
static
void
b44_set_msglevel
(
struct
net_device
*
dev
,
u32
value
)
{
struct
b44
*
bp
=
netdev_priv
(
dev
);
bp
->
msg_enable
=
value
;
}
static
void
b44_get_drvinfo
(
struct
net_device
*
dev
,
struct
ethtool_drvinfo
*
info
)
{
struct
b44
*
bp
=
netdev_priv
(
dev
);
struct
pci_dev
*
pci_dev
=
bp
->
pdev
;
u32
ethcmd
;
if
(
copy_from_user
(
&
ethcmd
,
useraddr
,
sizeof
(
ethcmd
)))
return
-
EFAULT
;
switch
(
ethcmd
)
{
case
ETHTOOL_GDRVINFO
:{
struct
ethtool_drvinfo
info
=
{
ETHTOOL_GDRVINFO
};
strcpy
(
info
.
driver
,
DRV_MODULE_NAME
);
strcpy
(
info
.
version
,
DRV_MODULE_VERSION
);
memset
(
&
info
.
fw_version
,
0
,
sizeof
(
info
.
fw_version
));
strcpy
(
info
.
bus_info
,
pci_name
(
pci_dev
));
info
.
eedump_len
=
0
;
info
.
regdump_len
=
0
;
if
(
copy_to_user
(
useraddr
,
&
info
,
sizeof
(
info
)))
return
-
EFAULT
;
return
0
;
}
case
ETHTOOL_GSET
:
{
struct
ethtool_cmd
cmd
=
{
ETHTOOL_GSET
};
strcpy
(
info
->
driver
,
DRV_MODULE_NAME
);
strcpy
(
info
->
version
,
DRV_MODULE_VERSION
);
strcpy
(
info
->
bus_info
,
pci_name
(
pci_dev
));
}
if
(
!
(
bp
->
flags
&
B44_FLAG_INIT_COMPLETE
))
return
-
EAGAIN
;
cmd
.
supported
=
(
SUPPORTED_Autoneg
);
cmd
.
supported
|=
(
SUPPORTED_100baseT_Half
|
SUPPORTED_100baseT_Full
|
SUPPORTED_10baseT_Half
|
SUPPORTED_10baseT_Full
|
SUPPORTED_MII
);
static
int
b44_nway_reset
(
struct
net_device
*
dev
)
{
struct
b44
*
bp
=
netdev_priv
(
dev
);
u32
bmcr
;
int
r
;
cmd
.
advertising
=
0
;
if
(
bp
->
flags
&
B44_FLAG_ADV_10HALF
)
cmd
.
advertising
|=
ADVERTISE_10HALF
;
if
(
bp
->
flags
&
B44_FLAG_ADV_10FULL
)
cmd
.
advertising
|=
ADVERTISE_10FULL
;
if
(
bp
->
flags
&
B44_FLAG_ADV_100HALF
)
cmd
.
advertising
|=
ADVERTISE_100HALF
;
if
(
bp
->
flags
&
B44_FLAG_ADV_100FULL
)
cmd
.
advertising
|=
ADVERTISE_100FULL
;
cmd
.
advertising
|=
ADVERTISE_PAUSE_CAP
|
ADVERTISE_PAUSE_ASYM
;
cmd
.
speed
=
(
bp
->
flags
&
B44_FLAG_100_BASE_T
)
?
SPEED_100
:
SPEED_10
;
cmd
.
duplex
=
(
bp
->
flags
&
B44_FLAG_FULL_DUPLEX
)
?
DUPLEX_FULL
:
DUPLEX_HALF
;
cmd
.
port
=
0
;
cmd
.
phy_address
=
bp
->
phy_addr
;
cmd
.
transceiver
=
(
bp
->
flags
&
B44_FLAG_INTERNAL_PHY
)
?
XCVR_INTERNAL
:
XCVR_EXTERNAL
;
cmd
.
autoneg
=
(
bp
->
flags
&
B44_FLAG_FORCE_LINK
)
?
AUTONEG_DISABLE
:
AUTONEG_ENABLE
;
cmd
.
maxtxpkt
=
0
;
cmd
.
maxrxpkt
=
0
;
if
(
copy_to_user
(
useraddr
,
&
cmd
,
sizeof
(
cmd
)))
return
-
EFAULT
;
return
0
;
spin_lock_irq
(
&
bp
->
lock
);
b44_readphy
(
bp
,
MII_BMCR
,
&
bmcr
);
b44_readphy
(
bp
,
MII_BMCR
,
&
bmcr
);
r
=
-
EINVAL
;
if
(
bmcr
&
BMCR_ANENABLE
)
{
b44_writephy
(
bp
,
MII_BMCR
,
bmcr
|
BMCR_ANRESTART
);
r
=
0
;
}
case
ETHTOOL_SSET
:
{
struct
ethtool_cmd
cmd
;
if
(
!
(
bp
->
flags
&
B44_FLAG_INIT_COMPLETE
))
return
-
EAGAIN
;
if
(
copy_from_user
(
&
cmd
,
useraddr
,
sizeof
(
cmd
)))
return
-
EFAULT
;
/* We do not support gigabit. */
if
(
cmd
.
autoneg
==
AUTONEG_ENABLE
)
{
if
(
cmd
.
advertising
&
(
ADVERTISED_1000baseT_Half
|
ADVERTISED_1000baseT_Full
))
return
-
EINVAL
;
}
else
if
((
cmd
.
speed
!=
SPEED_100
&&
cmd
.
speed
!=
SPEED_10
)
||
(
cmd
.
duplex
!=
DUPLEX_HALF
&&
cmd
.
duplex
!=
DUPLEX_FULL
))
{
return
-
EINVAL
;
}
spin_unlock_irq
(
&
bp
->
lock
);
spin_lock_irq
(
&
bp
->
lock
);
return
r
;
}
if
(
cmd
.
autoneg
==
AUTONEG_ENABLE
)
{
bp
->
flags
&=
~
B44_FLAG_FORCE_LINK
;
bp
->
flags
&=
~
(
B44_FLAG_ADV_10HALF
|
B44_FLAG_ADV_10FULL
|
B44_FLAG_ADV_100HALF
|
B44_FLAG_ADV_100FULL
);
if
(
cmd
.
advertising
&
ADVERTISE_10HALF
)
bp
->
flags
|=
B44_FLAG_ADV_10HALF
;
if
(
cmd
.
advertising
&
ADVERTISE_10FULL
)
bp
->
flags
|=
B44_FLAG_ADV_10FULL
;
if
(
cmd
.
advertising
&
ADVERTISE_100HALF
)
bp
->
flags
|=
B44_FLAG_ADV_100HALF
;
if
(
cmd
.
advertising
&
ADVERTISE_100FULL
)
bp
->
flags
|=
B44_FLAG_ADV_100FULL
;
}
else
{
bp
->
flags
|=
B44_FLAG_FORCE_LINK
;
if
(
cmd
.
speed
==
SPEED_100
)
bp
->
flags
|=
B44_FLAG_100_BASE_T
;
if
(
cmd
.
duplex
==
DUPLEX_FULL
)
bp
->
flags
|=
B44_FLAG_FULL_DUPLEX
;
}
static
int
b44_get_settings
(
struct
net_device
*
dev
,
struct
ethtool_cmd
*
cmd
)
{
struct
b44
*
bp
=
netdev_priv
(
dev
);
if
(
!
(
bp
->
flags
&
B44_FLAG_INIT_COMPLETE
))
return
-
EAGAIN
;
cmd
->
supported
=
(
SUPPORTED_Autoneg
);
cmd
->
supported
|=
(
SUPPORTED_100baseT_Half
|
SUPPORTED_100baseT_Full
|
SUPPORTED_10baseT_Half
|
SUPPORTED_10baseT_Full
|
SUPPORTED_MII
);
cmd
->
advertising
=
0
;
if
(
bp
->
flags
&
B44_FLAG_ADV_10HALF
)
cmd
->
advertising
|=
ADVERTISE_10HALF
;
if
(
bp
->
flags
&
B44_FLAG_ADV_10FULL
)
cmd
->
advertising
|=
ADVERTISE_10FULL
;
if
(
bp
->
flags
&
B44_FLAG_ADV_100HALF
)
cmd
->
advertising
|=
ADVERTISE_100HALF
;
if
(
bp
->
flags
&
B44_FLAG_ADV_100FULL
)
cmd
->
advertising
|=
ADVERTISE_100FULL
;
cmd
->
advertising
|=
ADVERTISE_PAUSE_CAP
|
ADVERTISE_PAUSE_ASYM
;
cmd
->
speed
=
(
bp
->
flags
&
B44_FLAG_100_BASE_T
)
?
SPEED_100
:
SPEED_10
;
cmd
->
duplex
=
(
bp
->
flags
&
B44_FLAG_FULL_DUPLEX
)
?
DUPLEX_FULL
:
DUPLEX_HALF
;
cmd
->
port
=
0
;
cmd
->
phy_address
=
bp
->
phy_addr
;
cmd
->
transceiver
=
(
bp
->
flags
&
B44_FLAG_INTERNAL_PHY
)
?
XCVR_INTERNAL
:
XCVR_EXTERNAL
;
cmd
->
autoneg
=
(
bp
->
flags
&
B44_FLAG_FORCE_LINK
)
?
AUTONEG_DISABLE
:
AUTONEG_ENABLE
;
cmd
->
maxtxpkt
=
0
;
cmd
->
maxrxpkt
=
0
;
return
0
;
}
b44_setup_phy
(
bp
);
static
int
b44_set_settings
(
struct
net_device
*
dev
,
struct
ethtool_cmd
*
cmd
)
{
struct
b44
*
bp
=
netdev_priv
(
dev
);
spin_unlock_irq
(
&
bp
->
lock
);
if
(
!
(
bp
->
flags
&
B44_FLAG_INIT_COMPLETE
))
return
-
EAGAIN
;
return
0
;
/* We do not support gigabit. */
if
(
cmd
->
autoneg
==
AUTONEG_ENABLE
)
{
if
(
cmd
->
advertising
&
(
ADVERTISED_1000baseT_Half
|
ADVERTISED_1000baseT_Full
))
return
-
EINVAL
;
}
else
if
((
cmd
->
speed
!=
SPEED_100
&&
cmd
->
speed
!=
SPEED_10
)
||
(
cmd
->
duplex
!=
DUPLEX_HALF
&&
cmd
->
duplex
!=
DUPLEX_FULL
))
{
return
-
EINVAL
;
}
case
ETHTOOL_GMSGLVL
:
{
struct
ethtool_value
edata
=
{
ETHTOOL_GMSGLVL
};
edata
.
data
=
bp
->
msg_enable
;
if
(
copy_to_user
(
useraddr
,
&
edata
,
sizeof
(
edata
)))
return
-
EFAULT
;
return
0
;
}
case
ETHTOOL_SMSGLVL
:
{
struct
ethtool_value
edata
;
if
(
copy_from_user
(
&
edata
,
useraddr
,
sizeof
(
edata
)))
return
-
EFAULT
;
bp
->
msg_enable
=
edata
.
data
;
return
0
;
spin_lock_irq
(
&
bp
->
lock
);
if
(
cmd
->
autoneg
==
AUTONEG_ENABLE
)
{
bp
->
flags
&=
~
B44_FLAG_FORCE_LINK
;
bp
->
flags
&=
~
(
B44_FLAG_ADV_10HALF
|
B44_FLAG_ADV_10FULL
|
B44_FLAG_ADV_100HALF
|
B44_FLAG_ADV_100FULL
);
if
(
cmd
->
advertising
&
ADVERTISE_10HALF
)
bp
->
flags
|=
B44_FLAG_ADV_10HALF
;
if
(
cmd
->
advertising
&
ADVERTISE_10FULL
)
bp
->
flags
|=
B44_FLAG_ADV_10FULL
;
if
(
cmd
->
advertising
&
ADVERTISE_100HALF
)
bp
->
flags
|=
B44_FLAG_ADV_100HALF
;
if
(
cmd
->
advertising
&
ADVERTISE_100FULL
)
bp
->
flags
|=
B44_FLAG_ADV_100FULL
;
}
else
{
bp
->
flags
|=
B44_FLAG_FORCE_LINK
;
if
(
cmd
->
speed
==
SPEED_100
)
bp
->
flags
|=
B44_FLAG_100_BASE_T
;
if
(
cmd
->
duplex
==
DUPLEX_FULL
)
bp
->
flags
|=
B44_FLAG_FULL_DUPLEX
;
}
case
ETHTOOL_NWAY_RST
:
{
u32
bmcr
;
int
r
;
spin_lock_irq
(
&
bp
->
lock
);
b44_readphy
(
bp
,
MII_BMCR
,
&
bmcr
);
b44_readphy
(
bp
,
MII_BMCR
,
&
bmcr
);
r
=
-
EINVAL
;
if
(
bmcr
&
BMCR_ANENABLE
)
{
b44_writephy
(
bp
,
MII_BMCR
,
bmcr
|
BMCR_ANRESTART
);
r
=
0
;
}
spin_unlock_irq
(
&
bp
->
lock
);
b44_setup_phy
(
bp
);
return
r
;
}
case
ETHTOOL_GLINK
:
{
struct
ethtool_value
edata
=
{
ETHTOOL_GLINK
};
edata
.
data
=
netif_carrier_ok
(
bp
->
dev
)
?
1
:
0
;
if
(
copy_to_user
(
useraddr
,
&
edata
,
sizeof
(
edata
)))
return
-
EFAULT
;
return
0
;
}
case
ETHTOOL_GRINGPARAM
:
{
struct
ethtool_ringparam
ering
=
{
ETHTOOL_GRINGPARAM
};
spin_unlock_irq
(
&
bp
->
lock
);
ering
.
rx_max_pending
=
B44_RX_RING_SIZE
-
1
;
ering
.
rx_pending
=
bp
->
rx_pending
;
return
0
;
}
/* XXX ethtool lacks a tx_max_pending, oops... */
static
void
b44_get_ringparam
(
struct
net_device
*
dev
,
struct
ethtool_ringparam
*
ering
)
{
struct
b44
*
bp
=
netdev_priv
(
dev
);
if
(
copy_to_user
(
useraddr
,
&
ering
,
sizeof
(
ering
)))
return
-
EFAULT
;
return
0
;
}
case
ETHTOOL_SRINGPARAM
:
{
struct
ethtool_ringparam
ering
;
ering
->
rx_max_pending
=
B44_RX_RING_SIZE
-
1
;
ering
->
rx_pending
=
bp
->
rx_pending
;
if
(
copy_from_user
(
&
ering
,
useraddr
,
sizeof
(
ering
)))
return
-
EFAULT
;
/* XXX ethtool lacks a tx_max_pending, oops... */
}
if
((
ering
.
rx_pending
>
B44_RX_RING_SIZE
-
1
)
||
(
ering
.
rx_mini_pending
!=
0
)
||
(
ering
.
rx_jumbo_pending
!=
0
)
||
(
ering
.
tx_pending
>
B44_TX_RING_SIZE
-
1
))
return
-
EINVAL
;
static
int
b44_set_ringparam
(
struct
net_device
*
dev
,
struct
ethtool_ringparam
*
ering
)
{
struct
b44
*
bp
=
netdev_priv
(
dev
);
spin_lock_irq
(
&
bp
->
lock
);
if
((
ering
->
rx_pending
>
B44_RX_RING_SIZE
-
1
)
||
(
ering
->
rx_mini_pending
!=
0
)
||
(
ering
->
rx_jumbo_pending
!=
0
)
||
(
ering
->
tx_pending
>
B44_TX_RING_SIZE
-
1
))
return
-
EINVAL
;
bp
->
rx_pending
=
ering
.
rx_pending
;
bp
->
tx_pending
=
ering
.
tx_pending
;
spin_lock_irq
(
&
bp
->
lock
);
b44_halt
(
bp
);
b44_init_rings
(
bp
);
b44_init_hw
(
bp
);
netif_wake_queue
(
bp
->
dev
);
spin_unlock_irq
(
&
bp
->
lock
);
bp
->
rx_pending
=
ering
->
rx_pending
;
bp
->
tx_pending
=
ering
->
tx_pending
;
b44_enable_ints
(
bp
);
return
0
;
}
case
ETHTOOL_GPAUSEPARAM
:
{
struct
ethtool_pauseparam
epause
=
{
ETHTOOL_GPAUSEPARAM
};
epause
.
autoneg
=
(
bp
->
flags
&
B44_FLAG_PAUSE_AUTO
)
!=
0
;
epause
.
rx_pause
=
(
bp
->
flags
&
B44_FLAG_RX_PAUSE
)
!=
0
;
epause
.
tx_pause
=
(
bp
->
flags
&
B44_FLAG_TX_PAUSE
)
!=
0
;
if
(
copy_to_user
(
useraddr
,
&
epause
,
sizeof
(
epause
)))
return
-
EFAULT
;
return
0
;
}
case
ETHTOOL_SPAUSEPARAM
:
{
struct
ethtool_pauseparam
epause
;
b44_halt
(
bp
);
b44_init_rings
(
bp
);
b44_init_hw
(
bp
);
netif_wake_queue
(
bp
->
dev
);
spin_unlock_irq
(
&
bp
->
lock
);
if
(
copy_from_user
(
&
epause
,
useraddr
,
sizeof
(
epause
)))
return
-
EFAULT
;
b44_enable_ints
(
bp
);
return
0
;
}
spin_lock_irq
(
&
bp
->
lock
);
if
(
epause
.
autoneg
)
bp
->
flags
|=
B44_FLAG_PAUSE_AUTO
;
else
bp
->
flags
&=
~
B44_FLAG_PAUSE_AUTO
;
if
(
epause
.
rx_pause
)
bp
->
flags
|=
B44_FLAG_RX_PAUSE
;
else
bp
->
flags
&=
~
B44_FLAG_RX_PAUSE
;
if
(
epause
.
tx_pause
)
bp
->
flags
|=
B44_FLAG_TX_PAUSE
;
else
bp
->
flags
&=
~
B44_FLAG_TX_PAUSE
;
if
(
bp
->
flags
&
B44_FLAG_PAUSE_AUTO
)
{
b44_halt
(
bp
);
b44_init_rings
(
bp
);
b44_init_hw
(
bp
);
}
else
{
__b44_set_flow_ctrl
(
bp
,
bp
->
flags
);
}
spin_unlock_irq
(
&
bp
->
lock
);
static
void
b44_get_pauseparam
(
struct
net_device
*
dev
,
struct
ethtool_pauseparam
*
epause
)
{
struct
b44
*
bp
=
netdev_priv
(
dev
);
epause
->
autoneg
=
(
bp
->
flags
&
B44_FLAG_PAUSE_AUTO
)
!=
0
;
epause
->
rx_pause
=
(
bp
->
flags
&
B44_FLAG_RX_PAUSE
)
!=
0
;
epause
->
tx_pause
=
(
bp
->
flags
&
B44_FLAG_TX_PAUSE
)
!=
0
;
}
b44_enable_ints
(
bp
);
return
0
;
static
int
b44_set_pauseparam
(
struct
net_device
*
dev
,
struct
ethtool_pauseparam
*
epause
)
{
struct
b44
*
bp
=
netdev_priv
(
dev
);
spin_lock_irq
(
&
bp
->
lock
);
if
(
epause
->
autoneg
)
bp
->
flags
|=
B44_FLAG_PAUSE_AUTO
;
else
bp
->
flags
&=
~
B44_FLAG_PAUSE_AUTO
;
if
(
epause
->
rx_pause
)
bp
->
flags
|=
B44_FLAG_RX_PAUSE
;
else
bp
->
flags
&=
~
B44_FLAG_RX_PAUSE
;
if
(
epause
->
tx_pause
)
bp
->
flags
|=
B44_FLAG_TX_PAUSE
;
else
bp
->
flags
&=
~
B44_FLAG_TX_PAUSE
;
if
(
bp
->
flags
&
B44_FLAG_PAUSE_AUTO
)
{
b44_halt
(
bp
);
b44_init_rings
(
bp
);
b44_init_hw
(
bp
);
}
else
{
__b44_set_flow_ctrl
(
bp
,
bp
->
flags
);
}
}
;
spin_unlock_irq
(
&
bp
->
lock
)
;
return
-
EOPNOTSUPP
;
b44_enable_ints
(
bp
);
return
0
;
}
static
struct
ethtool_ops
b44_ethtool_ops
=
{
.
get_drvinfo
=
b44_get_drvinfo
,
.
get_settings
=
b44_get_settings
,
.
set_settings
=
b44_set_settings
,
.
nway_reset
=
b44_nway_reset
,
.
get_link
=
ethtool_op_get_link
,
.
get_ringparam
=
b44_get_ringparam
,
.
set_ringparam
=
b44_set_ringparam
,
.
get_pauseparam
=
b44_get_pauseparam
,
.
set_pauseparam
=
b44_set_pauseparam
,
.
get_msglevel
=
b44_get_msglevel
,
.
set_msglevel
=
b44_set_msglevel
,
};
static
int
b44_ioctl
(
struct
net_device
*
dev
,
struct
ifreq
*
ifr
,
int
cmd
)
{
struct
mii_ioctl_data
__user
*
data
=
(
struct
mii_ioctl_data
__user
*
)
&
ifr
->
ifr_data
;
struct
b44
*
bp
=
dev
->
priv
;
struct
b44
*
bp
=
netdev_priv
(
dev
)
;
int
err
;
switch
(
cmd
)
{
case
SIOCETHTOOL
:
return
b44_ethtool_ioctl
(
dev
,
(
void
__user
*
)
ifr
->
ifr_data
);
case
SIOCGMIIPHY
:
data
->
phy_id
=
bp
->
phy_addr
;
/* fallthru */
case
SIOCGMIIREG
:
{
u32
mii_regval
;
spin_lock_irq
(
&
bp
->
lock
);
err
=
b44_readphy
(
bp
,
data
->
reg_num
&
0x1f
,
&
mii_regval
);
spin_unlock_irq
(
&
bp
->
lock
);
data
->
val_out
=
mii_regval
;
return
err
;
}
case
SIOCSMIIREG
:
if
(
!
capable
(
CAP_NET_ADMIN
))
return
-
EPERM
;
spin_lock_irq
(
&
bp
->
lock
);
err
=
b44_writephy
(
bp
,
data
->
reg_num
&
0x1f
,
data
->
val_in
);
spin_unlock_irq
(
&
bp
->
lock
);
return
err
;
spin_lock_irq
(
&
bp
->
lock
);
err
=
generic_mii_ioctl
(
&
bp
->
mii_if
,
data
,
cmd
,
NULL
);
spin_unlock_irq
(
&
bp
->
lock
);
default:
/* do nothing */
break
;
};
return
-
EOPNOTSUPP
;
return
err
;
}
/* Read 128-bytes of EEPROM. */
...
...
@@ -1772,7 +1743,7 @@ static int __devinit b44_init_one(struct pci_dev *pdev,
/* No interesting netdevice features in this card... */
dev
->
features
|=
0
;
bp
=
dev
->
priv
;
bp
=
netdev_priv
(
dev
)
;
bp
->
pdev
=
pdev
;
bp
->
dev
=
dev
;
if
(
b44_debug
>=
0
)
...
...
@@ -1806,6 +1777,7 @@ static int __devinit b44_init_one(struct pci_dev *pdev,
dev
->
watchdog_timeo
=
B44_TX_TIMEOUT
;
dev
->
change_mtu
=
b44_change_mtu
;
dev
->
irq
=
pdev
->
irq
;
SET_ETHTOOL_OPS
(
dev
,
&
b44_ethtool_ops
);
err
=
b44_get_invariants
(
bp
);
if
(
err
)
{
...
...
@@ -1814,6 +1786,13 @@ static int __devinit b44_init_one(struct pci_dev *pdev,
goto
err_out_iounmap
;
}
bp
->
mii_if
.
dev
=
dev
;
bp
->
mii_if
.
mdio_read
=
b44_mii_read
;
bp
->
mii_if
.
mdio_write
=
b44_mii_write
;
bp
->
mii_if
.
phy_id
=
bp
->
phy_addr
;
bp
->
mii_if
.
phy_id_mask
=
0x1f
;
bp
->
mii_if
.
reg_num_mask
=
0x1f
;
/* By default, advertise all speed/duplex settings. */
bp
->
flags
|=
(
B44_FLAG_ADV_10HALF
|
B44_FLAG_ADV_10FULL
|
B44_FLAG_ADV_100HALF
|
B44_FLAG_ADV_100FULL
);
...
...
@@ -1859,8 +1838,10 @@ static void __devexit b44_remove_one(struct pci_dev *pdev)
struct
net_device
*
dev
=
pci_get_drvdata
(
pdev
);
if
(
dev
)
{
struct
b44
*
bp
=
netdev_priv
(
dev
);
unregister_netdev
(
dev
);
iounmap
((
void
*
)
((
struct
b44
*
)(
dev
->
priv
))
->
regs
);
iounmap
((
void
*
)
bp
->
regs
);
free_netdev
(
dev
);
pci_release_regions
(
pdev
);
pci_disable_device
(
pdev
);
...
...
drivers/net/b44.h
View file @
a49b9154
...
...
@@ -542,6 +542,8 @@ struct b44 {
u8
phy_addr
;
u8
mdc_port
;
u8
core_unit
;
struct
mii_if_info
mii_if
;
};
#endif
/* _B44_H */
drivers/net/pcnet32.c
View file @
a49b9154
...
...
@@ -132,6 +132,8 @@ static const char pcnet32_gstrings_test[][ETH_GSTRING_LEN] = {
};
#define PCNET32_TEST_LEN (sizeof(pcnet32_gstrings_test) / ETH_GSTRING_LEN)
#define PCNET32_NUM_REGS 146
#define MAX_UNITS 8
/* More are supported, limit only on options */
static
int
options
[
MAX_UNITS
];
static
int
full_duplex
[
MAX_UNITS
];
...
...
@@ -234,7 +236,9 @@ static int full_duplex[MAX_UNITS];
* Jim Lewis <jklewis@us.ibm.com> added ethernet loopback test.
* Thomas Munck Steenholdt <tmus@tmus.dk> non-mii ioctl corrections.
* v1.29 6 Apr 2004 Jim Lewis <jklewis@us.ibm.com> added physical
* identification code (blink led's).
* identification code (blink led's) and register dump.
* Don Fry added timer for 971/972 so skbufs don't remain on tx ring
* forever.
*/
...
...
@@ -372,6 +376,9 @@ static void pcnet32_ethtool_test(struct net_device *dev,
static
int
pcnet32_loopback_test
(
struct
net_device
*
dev
,
uint64_t
*
data1
);
static
int
pcnet32_phys_id
(
struct
net_device
*
dev
,
u32
data
);
static
void
pcnet32_led_blink_callback
(
struct
net_device
*
dev
);
static
int
pcnet32_get_regs_len
(
struct
net_device
*
dev
);
static
void
pcnet32_get_regs
(
struct
net_device
*
dev
,
struct
ethtool_regs
*
regs
,
void
*
ptr
);
enum
pci_flags_bit
{
PCI_USES_IO
=
1
,
PCI_USES_MEM
=
2
,
PCI_USES_MASTER
=
4
,
...
...
@@ -492,9 +499,9 @@ static struct pcnet32_access pcnet32_dwio = {
#ifdef CONFIG_NET_POLL_CONTROLLER
static
void
pcnet32_poll_controller
(
struct
net_device
*
dev
)
{
disable_irq
(
dev
->
irq
);
pcnet32_interrupt
(
0
,
dev
,
NULL
);
enable_irq
(
dev
->
irq
);
disable_irq
(
dev
->
irq
);
pcnet32_interrupt
(
0
,
dev
,
NULL
);
enable_irq
(
dev
->
irq
);
}
#endif
...
...
@@ -681,7 +688,7 @@ static int pcnet32_loopback_test(struct net_device *dev, uint64_t *data1)
for
(
i
=
0
;
i
<
6
;
i
++
)
*
packet
++
=
dev
->
dev_addr
[
i
];
for
(
i
=
0
;
i
<
6
;
i
++
)
*
packet
++
=
dev
->
dev_addr
[
i
];
*
packet
++
=
dev
->
dev_addr
[
i
];
/* type */
*
packet
++
=
0x08
;
*
packet
++
=
0x06
;
...
...
@@ -837,6 +844,72 @@ static int pcnet32_phys_id(struct net_device *dev, u32 data)
return
0
;
}
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
,
void
*
ptr
)
{
int
i
,
csr0
;
u16
*
buff
=
ptr
;
struct
pcnet32_private
*
lp
=
dev
->
priv
;
struct
pcnet32_access
*
a
=
&
lp
->
a
;
ulong
ioaddr
=
dev
->
base_addr
;
int
ticks
;
unsigned
long
flags
;
spin_lock_irqsave
(
&
lp
->
lock
,
flags
);
csr0
=
a
->
read_csr
(
ioaddr
,
0
);
if
(
!
(
csr0
&
0x0004
))
{
/* If not stopped */
/* set SUSPEND (SPND) - CSR5 bit 0 */
a
->
write_csr
(
ioaddr
,
5
,
0x0001
);
/* poll waiting for bit to be set */
ticks
=
0
;
while
(
!
(
a
->
read_csr
(
ioaddr
,
5
)
&
0x0001
))
{
spin_unlock_irqrestore
(
&
lp
->
lock
,
flags
);
mdelay
(
1
);
spin_lock_irqsave
(
&
lp
->
lock
,
flags
);
ticks
++
;
if
(
ticks
>
200
)
{
if
(
netif_msg_hw
(
lp
))
printk
(
KERN_DEBUG
"%s: Error getting into suspend!
\n
"
,
dev
->
name
);
break
;
}
}
}
/* read address PROM */
for
(
i
=
0
;
i
<
16
;
i
+=
2
)
*
buff
++
=
inw
(
ioaddr
+
i
);
for
(
i
=
0
;
i
<=
89
;
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
++
)
{
*
buff
++
=
a
->
read_bcr
(
ioaddr
,
i
);
}
if
(
!
(
csr0
&
0x0004
))
{
/* If not stopped */
/* clear SUSPEND (SPND) - CSR5 bit 0 */
a
->
write_csr
(
ioaddr
,
5
,
0x0000
);
}
i
=
buff
-
(
u16
*
)
ptr
;
for
(;
i
<
PCNET32_NUM_REGS
;
i
++
)
*
buff
++
=
0
;
spin_unlock_irqrestore
(
&
lp
->
lock
,
flags
);
}
static
struct
ethtool_ops
pcnet32_ethtool_ops
=
{
.
get_settings
=
pcnet32_get_settings
,
.
set_settings
=
pcnet32_set_settings
,
...
...
@@ -853,6 +926,8 @@ static struct ethtool_ops pcnet32_ethtool_ops = {
.
self_test_count
=
pcnet32_self_test_count
,
.
self_test
=
pcnet32_ethtool_test
,
.
phys_id
=
pcnet32_phys_id
,
.
get_regs_len
=
pcnet32_get_regs_len
,
.
get_regs
=
pcnet32_get_regs
,
};
/* only probes for non-PCI devices, the rest are handled by
...
...
@@ -1032,6 +1107,13 @@ pcnet32_probe1(unsigned long ioaddr, unsigned int irq_line, int shared,
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
);
if
(
!
dev
)
{
if
(
pcnet32_debug
&
NETIF_MSG_PROBE
)
...
...
@@ -1371,13 +1453,18 @@ pcnet32_open(struct net_device *dev)
/* Re-initialize the PCNET32, and start it when done. */
lp
->
a
.
write_csr
(
ioaddr
,
1
,
(
lp
->
dma_addr
+
offsetof
(
struct
pcnet32_private
,
init_block
))
&
0xffff
);
offsetof
(
struct
pcnet32_private
,
init_block
))
&
0xffff
);
lp
->
a
.
write_csr
(
ioaddr
,
2
,
(
lp
->
dma_addr
+
offsetof
(
struct
pcnet32_private
,
init_block
))
>>
16
);
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 */
...
...
@@ -1579,13 +1666,13 @@ pcnet32_start_xmit(struct sk_buff *skb, struct net_device *dev)
int
entry
;
unsigned
long
flags
;
spin_lock_irqsave
(
&
lp
->
lock
,
flags
);
if
(
netif_msg_tx_queued
(
lp
))
{
printk
(
KERN_DEBUG
"%s: pcnet32_start_xmit() called, csr0 %4.4x.
\n
"
,
dev
->
name
,
lp
->
a
.
read_csr
(
ioaddr
,
0
));
}
spin_lock_irqsave
(
&
lp
->
lock
,
flags
);
/* Default status -- will not enable Successful-TxDone
* interrupt when that option is available to us.
*/
...
...
@@ -1646,7 +1733,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
,
rap
;
u16
csr0
,
csr7
,
rap
;
int
boguscnt
=
max_interrupt_work
;
int
must_restart
;
...
...
@@ -1663,13 +1750,19 @@ pcnet32_interrupt(int irq, void *dev_id, struct pt_regs * regs)
spin_lock
(
&
lp
->
lock
);
rap
=
lp
->
a
.
read_rap
(
ioaddr
);
while
((
csr0
=
lp
->
a
.
read_csr
(
ioaddr
,
0
))
&
0x8600
&&
--
boguscnt
>=
0
)
{
csr0
=
lp
->
a
.
read_csr
(
ioaddr
,
0
);
csr7
=
lp
->
ltint
?
lp
->
a
.
read_csr
(
ioaddr
,
7
)
:
0
;
while
((
csr0
&
0x8600
||
csr7
&
0x0800
)
&&
--
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
))
...
...
@@ -1679,7 +1772,7 @@ pcnet32_interrupt(int irq, void *dev_id, struct pt_regs * regs)
if
(
csr0
&
0x0400
)
/* Rx interrupt */
pcnet32_rx
(
dev
);
if
(
csr0
&
0x0200
)
{
/* Tx-done
interrupt */
if
(
csr0
&
0x0200
||
csr7
&
0x0800
)
{
/* Tx-done or Timer
interrupt */
unsigned
int
dirty_tx
=
lp
->
dirty_tx
;
int
delta
;
...
...
@@ -1786,6 +1879,9 @@ pcnet32_interrupt(int irq, void *dev_id, struct pt_regs * regs)
lp
->
a
.
write_csr
(
ioaddr
,
0
,
0x0004
);
pcnet32_restart
(
dev
,
0x0002
);
}
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. */
...
...
@@ -1872,6 +1968,7 @@ pcnet32_rx(struct net_device *dev)
if
(
i
>
RX_RING_SIZE
-
2
)
{
lp
->
stats
.
rx_dropped
++
;
lp
->
rx_ring
[
entry
].
status
|=
le16_to_cpu
(
0x8000
);
wmb
();
/* Make sure adapter sees owner change */
lp
->
cur_rx
++
;
}
break
;
...
...
@@ -1935,6 +2032,10 @@ 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
...
...
@@ -1945,9 +2046,12 @@ pcnet32_close(struct net_device *dev)
free_irq
(
dev
->
irq
,
dev
);
spin_lock_irqsave
(
&
lp
->
lock
,
flags
);
/* free all allocated skbuffs */
for
(
i
=
0
;
i
<
RX_RING_SIZE
;
i
++
)
{
lp
->
rx_ring
[
i
].
status
=
0
;
wmb
();
/* Make sure adapter sees owner change */
if
(
lp
->
rx_skbuff
[
i
])
{
pci_unmap_single
(
lp
->
pci_dev
,
lp
->
rx_dma_addr
[
i
],
PKT_BUF_SZ
-
2
,
PCI_DMA_FROMDEVICE
);
...
...
@@ -1958,6 +2062,8 @@ pcnet32_close(struct net_device *dev)
}
for
(
i
=
0
;
i
<
TX_RING_SIZE
;
i
++
)
{
lp
->
tx_ring
[
i
].
status
=
0
;
/* CPU owns buffer */
wmb
();
/* Make sure adapter sees owner change */
if
(
lp
->
tx_skbuff
[
i
])
{
pci_unmap_single
(
lp
->
pci_dev
,
lp
->
tx_dma_addr
[
i
],
lp
->
tx_skbuff
[
i
]
->
len
,
PCI_DMA_TODEVICE
);
...
...
@@ -1967,6 +2073,8 @@ pcnet32_close(struct net_device *dev)
lp
->
tx_dma_addr
[
i
]
=
0
;
}
spin_unlock_irqrestore
(
&
lp
->
lock
,
flags
);
return
0
;
}
...
...
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