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
948d8589
Commit
948d8589
authored
Feb 06, 2002
by
Jeff Garzik
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fix several bugs in DL2K Gigabit Ethernet driver, updating to
vendor revision 1.08. Contributed by the vendor, D-Link.
parent
d4446f7a
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
166 additions
and
120 deletions
+166
-120
Documentation/networking/dl2k.txt
Documentation/networking/dl2k.txt
+24
-11
drivers/net/dl2k.c
drivers/net/dl2k.c
+123
-95
drivers/net/dl2k.h
drivers/net/dl2k.h
+19
-14
No files found.
Documentation/networking/dl2k.txt
View file @
948d8589
D-Link DL2000-based Gigabit Ethernet Adapter Installation
for Linux
Nov 12, 2001
Jan 02, 2002
Contents
========
...
...
@@ -182,7 +182,7 @@ driver.
mtu=packet_size - Specifies the maximum packet size. default
is 1500.
media=
xxxxxxxxx
- Specifies the media type the NIC operates at.
media=
media_type
- Specifies the media type the NIC operates at.
autosense Autosensing active media.
10mbps_hd 10Mbps half duplex.
10mbps_fd 10Mbps full duplex.
...
...
@@ -195,28 +195,41 @@ media=xxxxxxxxx - Specifies the media type the NIC operates at.
2 10Mbps full duplex.
3 100Mbps half duplex.
4 100Mbps full duplex.
5 1000Mbps
full
duplex.
6 1000Mbps
half
duplex.
5 1000Mbps
half
duplex.
6 1000Mbps
full
duplex.
By default, the NIC operates at autosense.
Note that only 1000mbps_fd and 1000mbps_hd
types are available for fiber adapter.
vlan=
x
- Specifies the VLAN ID. If vlan=0, the
vlan=
[0|1]
- Specifies the VLAN ID. If vlan=0, the
Virtual Local Area Network (VLAN) function is
disable.
jumbo=
x
- Specifies the jumbo frame support. If jumbo=1,
jumbo=
[0|1]
- Specifies the jumbo frame support. If jumbo=1,
the NIC accept jumbo frames. By default, this
function is disabled.
Jumbo frame usually improve the performance
int gigabit.
int_count - Rx frame count each interrupt.
int_timeout - Rx DMA wait time for an interrupt. Proper
values of int_count and int_timeout bring
a conspicuous performance in the fast machine.
Ex. int_count=5 and int_timeout=750
rx_coalesce=n - Rx frame count each interrupt.
rx_timeout=n - Rx DMA wait time for an interrupt. Proper
values of rx_coalesce and rx_timeout bring
a conspicuous performance in the fast machine.
Ex. rx_coalesce=5 and rx_timeout=750
tx_coalesce=n - Tx transmit count each TxComp interrupt.
Setting value larger than 1 will improve
performance, but this is possible to lower
stability in slow UP machines. By default,
tx_coalesce=1. (dl2k)
tx_flow=[1|0] - Specifies the Tx flow control. If tx_flow=1,
the Tx flow control enable.
rx_flow=[1|0] - Specifies the Rx flow control. If rx_flow=1,
the Rx flow control enable.
Configuration Script Sample
===========================
...
...
drivers/net/dl2k.c
View file @
948d8589
...
...
@@ -15,18 +15,24 @@
0.01 2001/05/03 Created DL2000-based linux driver
0.02 2001/05/21 Added VLAN and hardware checksum support.
1.00 2001/06/26 Added jumbo frame support.
1.01 2001/08/21 Added two parameters,
int_count and int
_timeout.
1.01 2001/08/21 Added two parameters,
rx_coalesce and rx
_timeout.
1.02 2001/10/08 Supported fiber media.
Added flow control parameters.
1.03 2001/10/12 Changed the default media to 1000mbps_fd for the
fiber devices.
1.04 2001/11/08 Fixed a bug which Tx stop when a very busy case.
*/
1.03 2001/10/12 Changed the default media to 1000mbps_fd for
the fiber devices.
1.04 2001/11/08 Fixed Tx stopped when tx very busy.
1.05 2001/11/22 Fixed Tx stopped when unidirectional tx busy.
1.06 2001/12/13 Fixed disconnect bug at 10Mbps mode.
Fixed tx_full flag incorrect.
Added tx_coalesce paramter.
1.07 2002/01/03 Fixed miscount of RX frame error.
1.08 2002/01/17 Fixed the multicast bug.
*/
#include "dl2k.h"
static
char
version
[]
__devinitdata
=
KERN_INFO
"D-Link DL2000-based linux driver v1.0
4 2001/11/08
\n
"
;
KERN_INFO
"D-Link DL2000-based linux driver v1.0
8 2002/01/17
\n
"
;
#define MAX_UNITS 8
static
int
mtu
[
MAX_UNITS
];
...
...
@@ -36,11 +42,13 @@ static char *media[MAX_UNITS];
static
int
tx_flow
[
MAX_UNITS
];
static
int
rx_flow
[
MAX_UNITS
];
static
int
copy_thresh
;
static
int
int_count
;
/* Rx frame count each interrupt */
static
int
int_timeout
;
/* Rx DMA wait time in 64ns increments */
static
int
rx_coalesce
=
DEFAULT_RXC
;
static
int
rx_timeout
=
DEFAULT_RXT
;
static
int
tx_coalesce
=
DEFAULT_TXC
;
MODULE_AUTHOR
(
"Edward Peng"
);
MODULE_DESCRIPTION
(
"D-Link DL2000-based Gigabit Ethernet Adapter"
);
MODULE_LICENSE
(
"GPL"
);
MODULE_PARM
(
mtu
,
"1-"
__MODULE_STRING
(
MAX_UNITS
)
"i"
);
MODULE_PARM
(
media
,
"1-"
__MODULE_STRING
(
MAX_UNITS
)
"s"
);
MODULE_PARM
(
vlan
,
"1-"
__MODULE_STRING
(
MAX_UNITS
)
"i"
);
...
...
@@ -48,13 +56,16 @@ MODULE_PARM (jumbo, "1-" __MODULE_STRING (MAX_UNITS) "i");
MODULE_PARM
(
tx_flow
,
"1-"
__MODULE_STRING
(
MAX_UNITS
)
"i"
);
MODULE_PARM
(
rx_flow
,
"1-"
__MODULE_STRING
(
MAX_UNITS
)
"i"
);
MODULE_PARM
(
copy_thresh
,
"i"
);
MODULE_PARM
(
int_count
,
"i"
);
MODULE_PARM
(
int_timeout
,
"i"
);
MODULE_PARM
(
rx_coalesce
,
"i"
);
/* Rx frame count each interrupt */
MODULE_PARM
(
rx_timeout
,
"i"
);
/* Rx DMA wait time in 64ns increments */
MODULE_PARM
(
tx_coalesce
,
"i"
);
/* HW xmit count each TxComplete [1-8] */
/* Enable the default interrupts */
#define DEFAULT_INTR (RxDMAComplete | HostError | IntRequested | TxComplete| \
UpdateStats | LinkEvent)
#define EnableInt() \
writew(RxDMAComplete | HostError | IntRequested | TxComplete| \
UpdateStats | LinkEvent, ioaddr + IntEnable)
writew(DEFAULT_INTR, ioaddr + IntEnable)
static
int
max_intrloop
=
50
;
static
int
multicast_filter_limit
=
0x40
;
...
...
@@ -162,11 +173,11 @@ rio_probe1 (struct pci_dev *pdev, const struct pci_device_id *ent)
np
->
speed
=
10
;
np
->
full_duplex
=
0
;
}
else
if
(
strcmp
(
media
[
card_idx
],
"1000mbps_fd"
)
==
0
||
strcmp
(
media
[
card_idx
],
"
5
"
)
==
0
)
{
strcmp
(
media
[
card_idx
],
"
6
"
)
==
0
)
{
np
->
speed
=
1000
;
np
->
full_duplex
=
1
;
}
else
if
(
strcmp
(
media
[
card_idx
],
"1000mbps_hd"
)
==
0
||
strcmp
(
media
[
card_idx
],
"
6
"
)
==
0
)
{
strcmp
(
media
[
card_idx
],
"
5
"
)
==
0
)
{
np
->
speed
=
1000
;
np
->
full_duplex
=
0
;
}
else
{
...
...
@@ -175,7 +186,7 @@ rio_probe1 (struct pci_dev *pdev, const struct pci_device_id *ent)
}
if
(
jumbo
[
card_idx
]
!=
0
)
{
np
->
jumbo
=
1
;
dev
->
mtu
=
9000
;
dev
->
mtu
=
MAX_JUMBO
;
}
else
{
np
->
jumbo
=
0
;
if
(
mtu
[
card_idx
]
>
0
&&
mtu
[
card_idx
]
<
PACKET_SIZE
)
...
...
@@ -183,14 +194,17 @@ rio_probe1 (struct pci_dev *pdev, const struct pci_device_id *ent)
}
np
->
vlan
=
(
vlan
[
card_idx
]
>
0
&&
vlan
[
card_idx
]
<
4096
)
?
vlan
[
card_idx
]
:
0
;
if
(
int_count
!=
0
&&
int
_timeout
!=
0
)
{
np
->
int_count
=
int_count
;
np
->
int_timeout
=
int
_timeout
;
if
(
rx_coalesce
!=
0
&&
rx
_timeout
!=
0
)
{
np
->
rx_coalesce
=
rx_coalesce
;
np
->
rx_timeout
=
rx
_timeout
;
np
->
coalesce
=
1
;
}
np
->
tx_flow
=
(
tx_flow
[
card_idx
])
?
1
:
0
;
np
->
rx_flow
=
(
rx_flow
[
card_idx
])
?
1
:
0
;
if
(
tx_coalesce
<
1
)
tx_coalesce
=
1
;
if
(
tx_coalesce
>
8
)
tx_coalesce
=
8
;
}
dev
->
open
=
&
rio_open
;
dev
->
hard_start_xmit
=
&
start_xmit
;
...
...
@@ -201,8 +215,8 @@ rio_probe1 (struct pci_dev *pdev, const struct pci_device_id *ent)
dev
->
tx_timeout
=
&
tx_timeout
;
dev
->
watchdog_timeo
=
TX_TIMEOUT
;
dev
->
change_mtu
=
&
change_mtu
;
#if
def TX_HW_CHECKSUM
dev
->
features
=
NETIF_F_
SG
|
NETIF_F_HW
_CSUM
;
#if
0
dev->features = NETIF_F_
IP
_CSUM;
#endif
pci_set_drvdata
(
pdev
,
dev
);
...
...
@@ -326,7 +340,7 @@ parse_eeprom (struct net_device *dev)
}
/* Check CRC */
crc
=
~
ether_crc_le
(
256
-
4
,
sromdata
);
crc
=
~
ether_crc_le
(
256
-
4
,
sromdata
);
if
(
psrom
->
crc
!=
crc
)
{
printk
(
KERN_ERR
"%s: EEPROM data CRC error.
\n
"
,
dev
->
name
);
return
-
1
;
...
...
@@ -388,13 +402,12 @@ rio_open (struct net_device *dev)
i
=
request_irq
(
dev
->
irq
,
&
rio_interrupt
,
SA_SHIRQ
,
dev
->
name
,
dev
);
if
(
i
)
return
i
;
/* DebugCtrl bit 4, 5, 9 must set */
writel
(
readl
(
ioaddr
+
DebugCtrl
)
|
0x0230
,
ioaddr
+
DebugCtrl
);
/* Jumbo frame */
if
(
np
->
jumbo
!=
0
)
writew
(
90
14
,
ioaddr
+
MaxFrameSize
);
writew
(
MAX_JUMBO
+
14
,
ioaddr
+
MaxFrameSize
);
alloc_list
(
dev
);
...
...
@@ -404,7 +417,7 @@ rio_open (struct net_device *dev)
set_multicast
(
dev
);
if
(
np
->
coalesce
)
{
writel
(
np
->
int_count
|
np
->
int
_timeout
<<
16
,
writel
(
np
->
rx_coalesce
|
np
->
rx
_timeout
<<
16
,
ioaddr
+
RxDMAIntCtrl
);
}
/* Set RIO to poll every N*320nsec. */
...
...
@@ -441,13 +454,31 @@ tx_timeout (struct net_device *dev)
struct
netdev_private
*
np
=
dev
->
priv
;
long
ioaddr
=
dev
->
base_addr
;
printk
(
KERN_
WARNING
"%s: Transmit timed out, TxStatus %4.4x.
\n
"
,
printk
(
KERN_
INFO
"%s: Tx timed out (%4.4x), is buffer full?
\n
"
,
dev
->
name
,
readl
(
ioaddr
+
TxStatus
));
/* Free used tx skbuffs */
for
(;
np
->
cur_tx
-
np
->
old_tx
>
0
;
np
->
old_tx
++
)
{
int
entry
=
np
->
old_tx
%
TX_RING_SIZE
;
struct
sk_buff
*
skb
;
if
(
!
(
np
->
tx_ring
[
entry
].
status
&
TFDDone
))
break
;
skb
=
np
->
tx_skbuff
[
entry
];
pci_unmap_single
(
np
->
pdev
,
np
->
tx_ring
[
entry
].
fraginfo
,
skb
->
len
,
PCI_DMA_TODEVICE
);
dev_kfree_skb_irq
(
skb
);
np
->
tx_skbuff
[
entry
]
=
0
;
}
dev
->
if_port
=
0
;
dev
->
trans_start
=
jiffies
;
np
->
stats
.
tx_errors
++
;
if
(
!
np
->
tx_full
)
/* If the ring is no longer full, clear tx_full and
call netif_wake_queue() */
if
(
np
->
tx_full
&&
np
->
cur_tx
-
np
->
old_tx
<
TX_QUEUE_LEN
-
1
)
{
np
->
tx_full
=
0
;
netif_wake_queue
(
dev
);
}
}
/* allocate and initialize Tx and Rx descriptors */
...
...
@@ -465,16 +496,19 @@ alloc_list (struct net_device *dev)
/* Initialize Tx descriptors, TFDListPtr leaves in start_xmit(). */
for
(
i
=
0
;
i
<
TX_RING_SIZE
;
i
++
)
{
np
->
tx_skbuff
[
i
]
=
0
;
np
->
tx_ring
[
i
].
status
=
0
;
np
->
tx_ring
[
i
].
status
=
cpu_to_le64
(
TFDDone
);
np
->
tx_ring
[
i
].
next_desc
=
cpu_to_le64
(
np
->
tx_ring_dma
+
((
i
+
1
)
%
TX_RING_SIZE
)
*
sizeof
(
struct
netdev_desc
));
}
/* Initialize Rx descriptors */
for
(
i
=
0
;
i
<
RX_RING_SIZE
;
i
++
)
{
np
->
rx_ring
[
i
].
next_desc
=
cpu_to_le64
(
np
->
rx_ring_dma
+
((
i
+
1
)
%
RX_RING_SIZE
)
*
sizeof
(
struct
netdev_desc
));
((
i
+
1
)
%
RX_RING_SIZE
)
*
sizeof
(
struct
netdev_desc
));
np
->
rx_ring
[
i
].
status
=
0
;
np
->
rx_ring
[
i
].
fraginfo
=
0
;
np
->
rx_skbuff
[
i
]
=
0
;
...
...
@@ -522,13 +556,12 @@ start_xmit (struct sk_buff *skb, struct net_device *dev)
entry
=
np
->
cur_tx
%
TX_RING_SIZE
;
np
->
tx_skbuff
[
entry
]
=
skb
;
txdesc
=
&
np
->
tx_ring
[
entry
];
txdesc
->
next_desc
=
0
;
/* Set TFDDone to avoid TxDMA gather this descriptor */
txdesc
->
status
=
cpu_to_le64
(
TFDDone
);
txdesc
->
status
|=
cpu_to_le64
(
entry
|
WordAlignDisable
|
(
1
<<
FragCountShift
));
#if
def TX_HW_CHECKSUM
#if
0
if (skb->ip_summed == CHECKSUM_HW) {
txdesc->status |=
cpu_to_le64 (TCPChecksumEnable | UDPChecksumEnable |
...
...
@@ -544,21 +577,13 @@ start_xmit (struct sk_buff *skb, struct net_device *dev)
/* Send one packet each time at 10Mbps mode */
/* Tx coalescing loop do not exceed 8 */
if
(
entry
%
0x08
==
0
||
np
->
speed
==
10
)
if
(
entry
%
tx_coalesce
==
0
||
np
->
speed
==
10
)
txdesc
->
status
|=
cpu_to_le64
(
TxIndicate
);
txdesc
->
fraginfo
=
cpu_to_le64
(
pci_map_single
(
np
->
pdev
,
skb
->
data
,
skb
->
len
,
PCI_DMA_TODEVICE
));
txdesc
->
fraginfo
|=
cpu_to_le64
(
skb
->
len
)
<<
48
;
/* Chain the last descriptor's pointer to this one */
if
(
np
->
last_tx
)
np
->
last_tx
->
next_desc
=
cpu_to_le64
(
np
->
tx_ring_dma
+
entry
*
sizeof
(
struct
netdev_desc
));
np
->
last_tx
=
txdesc
;
/* Clear TFDDone, then TxDMA start to send this descriptor */
txdesc
->
status
&=
~
cpu_to_le64
(
TFDDone
);
...
...
@@ -570,8 +595,10 @@ start_xmit (struct sk_buff *skb, struct net_device *dev)
if
(
np
->
cur_tx
-
np
->
old_tx
<
TX_QUEUE_LEN
-
1
&&
np
->
speed
!=
10
)
{
/* do nothing */
}
else
{
spin_lock_irqsave
(
&
np
->
lock
,
flags
);
np
->
tx_full
=
1
;
netif_stop_queue
(
dev
);
spin_unlock_irqrestore
(
&
np
->
lock
,
flags
);
}
/* The first TFDListPtr */
...
...
@@ -580,15 +607,15 @@ start_xmit (struct sk_buff *skb, struct net_device *dev)
dev
->
base_addr
+
TFDListPtr0
);
writel
(
0
,
dev
->
base_addr
+
TFDListPtr1
);
}
spin_lock_irqsave
(
&
np
->
lock
,
flags
);
if
(
np
->
old_tx
>
TX_RING_SIZE
)
{
spin_lock_irqsave
(
&
np
->
lock
,
flags
);
tx_shift
=
TX_RING_SIZE
;
np
->
old_tx
-=
tx_shift
;
np
->
cur_tx
-=
tx_shift
;
spin_unlock_irqrestore
(
&
np
->
lock
,
flags
);
}
spin_unlock_irqrestore
(
&
np
->
lock
,
flags
);
/* NETDEV WATCHDOG timer */
dev
->
trans_start
=
jiffies
;
return
0
;
...
...
@@ -605,33 +632,24 @@ rio_interrupt (int irq, void *dev_instance, struct pt_regs *rgs)
ioaddr
=
dev
->
base_addr
;
np
=
dev
->
priv
;
spin_lock
(
&
np
->
lock
);
spin_lock
(
&
np
->
lock
);
while
(
1
)
{
int_status
=
readw
(
ioaddr
+
IntStatus
)
&
(
HostError
|
TxComplete
|
IntRequested
|
UpdateStats
|
LinkEvent
|
RxDMAComplete
);
writew
(
int_status
&
(
HostError
|
TxComplete
|
RxComplete
|
IntRequested
|
UpdateStats
|
LinkEvent
|
TxDMAComplete
|
RxDMAComplete
|
RFDListEnd
|
RxDMAPriority
),
ioaddr
+
IntStatus
);
int_status
=
readw
(
ioaddr
+
IntStatus
);
writew
(
int_status
,
ioaddr
+
IntStatus
);
int_status
&=
DEFAULT_INTR
;
if
(
int_status
==
0
)
break
;
/* Processing received packets */
if
(
int_status
&
RxDMAComplete
)
receive_packet
(
dev
);
/* TxComplete interrupt */
if
(
int_status
&
TxComplete
||
np
->
tx_full
)
{
int
tx_status
=
readl
(
ioaddr
+
TxStatus
);
if
((
int_status
&
TxComplete
)
||
np
->
tx_full
)
{
int
tx_status
;
tx_status
=
readl
(
ioaddr
+
TxStatus
);
if
(
tx_status
&
0x01
)
tx_error
(
dev
,
tx_status
);
/* Send one packet each time at 10Mbps mode */
if
(
np
->
speed
==
10
)
{
np
->
tx_full
=
0
;
netif_wake_queue
(
dev
);
}
/* Free used tx skbuffs */
for
(;
np
->
cur_tx
-
np
->
old_tx
>
0
;
np
->
old_tx
++
)
{
for
(;
np
->
cur_tx
-
np
->
old_tx
>
0
;
np
->
old_tx
++
)
{
int
entry
=
np
->
old_tx
%
TX_RING_SIZE
;
struct
sk_buff
*
skb
;
...
...
@@ -648,9 +666,12 @@ rio_interrupt (int irq, void *dev_instance, struct pt_regs *rgs)
/* If the ring is no longer full, clear tx_full and
call netif_wake_queue() */
if
(
np
->
tx_full
&&
np
->
cur_tx
-
np
->
old_tx
<
TX_QUEUE_LEN
-
1
)
{
np
->
tx_full
=
0
;
netif_wake_queue
(
dev
);
if
(
np
->
speed
!=
10
||
int_status
&
TxComplete
)
{
np
->
tx_full
=
0
;
netif_wake_queue
(
dev
);
}
}
/* Handle uncommon events */
if
(
int_status
&
(
IntRequested
|
HostError
|
LinkEvent
|
UpdateStats
))
...
...
@@ -665,7 +686,7 @@ rio_interrupt (int irq, void *dev_instance, struct pt_regs *rgs)
break
;
}
}
spin_unlock
(
&
np
->
lock
);
spin_unlock
(
&
np
->
lock
);
}
static
void
...
...
@@ -741,7 +762,7 @@ tx_error (struct net_device *dev, int tx_status)
np
->
stats
.
collisions
++
;
#endif
/* Restart the Tx
.
*/
/* Restart the Tx */
writel
(
readw
(
dev
->
base_addr
+
MACCtrl
)
|
TxEnable
,
ioaddr
+
MACCtrl
);
}
...
...
@@ -782,7 +803,7 @@ receive_packet (struct net_device *dev)
if
(
frame_status
&
0x00300000
)
np
->
stats
.
rx_length_errors
++
;
if
(
frame_status
&
0x00010000
)
np
->
stats
.
rx_fifo_errors
++
;
np
->
stats
.
rx_fifo_errors
++
;
if
(
frame_status
&
0x00060000
)
np
->
stats
.
rx_frame_errors
++
;
if
(
frame_status
&
0x00080000
)
...
...
@@ -807,7 +828,7 @@ receive_packet (struct net_device *dev)
skb_put
(
skb
,
pkt_len
);
}
skb
->
protocol
=
eth_type_trans
(
skb
,
dev
);
#if
def RX_HW_CHECKSUM
#if
0
/* Checksum done by hw, but csum value unavailable. */
if (!(frame_status & (TCPError | UDPError | IPError))) {
skb->ip_summed = CHECKSUM_UNNECESSARY;
...
...
@@ -898,7 +919,7 @@ rio_error (struct net_device *dev, int int_status)
/* PCI Error, a catastronphic error related to the bus interface
occurs, set GlobalReset and HostReset to reset. */
if
(
int_status
&
HostError
)
{
printk
(
KERN_ERR
"%s:
PCI
Error! IntStatus %4.4x.
\n
"
,
printk
(
KERN_ERR
"%s:
Host
Error! IntStatus %4.4x.
\n
"
,
dev
->
name
,
int_status
);
writew
(
GlobalReset
|
HostReset
,
ioaddr
+
ASICCtrl
+
2
);
mdelay
(
500
);
...
...
@@ -913,8 +934,8 @@ get_stats (struct net_device *dev)
u16
temp1
;
u16
temp2
;
int
i
;
/* All statistics registers need to
acknowledge
,
else
overflow could cause some problem
*/
/* All statistics registers need to
be acknowledged
,
else
statistic overflow could cause problems
*/
np
->
stats
.
rx_packets
+=
readl
(
ioaddr
+
FramesRcvOk
);
np
->
stats
.
tx_packets
+=
readl
(
ioaddr
+
FramesXmtOk
);
np
->
stats
.
rx_bytes
+=
readl
(
ioaddr
+
OctetRcvOk
);
...
...
@@ -931,11 +952,11 @@ get_stats (struct net_device *dev)
readl
(
ioaddr
+
FramesWDeferredXmt
)
+
temp2
;
/* detailed rx_error */
np
->
stats
.
rx_length_errors
+=
readw
(
ioaddr
+
InRangeLengthErrors
)
+
readw
(
ioaddr
+
FrameTooLongErrors
);
np
->
stats
.
rx_length_errors
+=
readw
(
ioaddr
+
FrameTooLongErrors
);
np
->
stats
.
rx_crc_errors
+=
readw
(
ioaddr
+
FrameCheckSeqError
);
/* Clear all other statistic register. */
readw
(
ioaddr
+
InRangeLengthErrors
);
readw
(
ioaddr
+
MacControlFramesXmtd
);
readw
(
ioaddr
+
BcstFramesXmtdOk
);
readl
(
ioaddr
+
McstFramesXmtdOk
);
...
...
@@ -960,7 +981,7 @@ int
change_mtu
(
struct
net_device
*
dev
,
int
new_mtu
)
{
struct
netdev_private
*
np
=
dev
->
priv
;
int
max
=
(
np
->
jumbo
)
?
9000
:
1536
;
int
max
=
(
np
->
jumbo
)
?
MAX_JUMBO
:
1536
;
if
((
new_mtu
<
68
)
||
(
new_mtu
>
max
))
{
return
-
EINVAL
;
...
...
@@ -978,36 +999,42 @@ set_multicast (struct net_device *dev)
u32
hash_table
[
2
];
u16
rx_mode
=
0
;
int
i
;
int
bit
;
int
index
,
crc
;
struct
dev_mc_list
*
mclist
;
struct
netdev_private
*
np
=
dev
->
priv
;
/* Default: receive broadcast and unicast */
rx_mode
=
ReceiveBroadcast
|
ReceiveUnicast
;
hash_table
[
0
]
=
hash_table
[
1
]
=
0
;
/* RxFlowcontrol DA: 01-80-C2-00-00-01. Hash index=0x39 */
hash_table
[
1
]
|=
0x02000000
;
if
(
dev
->
flags
&
IFF_PROMISC
)
{
/* Receive all frames promiscuously. */
rx_mode
|=
ReceiveAllFrames
;
}
else
if
(((
dev
->
flags
&
IFF_MULTICAST
)
&&
(
dev
->
mc_count
>
multicast_filter_limit
))
||
(
dev
->
flags
&
IFF_ALLMULTI
))
{
rx_mode
=
ReceiveAllFrames
;
}
else
if
((
dev
->
flags
&
IFF_ALLMULTI
)
||
(
dev
->
mc_count
>
multicast_filter_limit
))
{
/* Receive broadcast and multicast frames */
rx_mode
|=
ReceiveBroadcast
|
ReceiveMulticast
|
ReceiveUnicast
;
}
else
if
((
dev
->
flags
&
IFF_MULTICAST
)
&
(
dev
->
mc_count
>
0
))
{
/* Receive broadcast frames and multicast frames filtering by Hashtable */
rx_mode
|=
rx_mode
=
ReceiveBroadcast
|
ReceiveMulticast
|
ReceiveUnicast
;
}
else
if
(
dev
->
mc_count
>
0
)
{
/* Receive broadcast frames and multicast frames filtering
by Hashtable */
rx_mode
=
ReceiveBroadcast
|
ReceiveMulticastHash
|
ReceiveUnicast
;
for
(
i
=
0
,
mclist
=
dev
->
mc_list
;
mclist
&&
i
<
dev
->
mc_count
;
i
++
,
mclist
=
mclist
->
next
)
{
crc
=
ether_crc_le
(
ETH_ALEN
,
mclist
->
dmi_addr
);
for
(
index
=
0
,
bit
=
0
;
bit
<
6
;
bit
++
,
crc
<<=
1
)
{
if
(
crc
&
0x80000000
)
index
|=
1
<<
bit
;
}
hash_table
[
index
/
32
]
|=
(
1
<<
(
index
%
32
));
}
}
else
{
rx_mode
=
ReceiveBroadcast
|
ReceiveUnicast
;
}
if
(
np
->
vlan
)
{
/* ReceiveVLANMatch field in ReceiveMode */
rx_mode
|=
ReceiveVLANMatch
;
}
hash_table
[
0
]
=
0x00000000
;
hash_table
[
1
]
=
0x00000000
;
for
(
i
=
0
,
mclist
=
dev
->
mc_list
;
mclist
&&
i
<
dev
->
mc_count
;
i
++
,
mclist
=
mclist
->
next
)
{
set_bit
(
ether_crc_le
(
ETH_ALEN
,
mclist
->
dmi_addr
)
&
0x3f
,
hash_table
);
}
writel
(
hash_table
[
0
],
ioaddr
+
HashTable0
);
writel
(
hash_table
[
1
],
ioaddr
+
HashTable1
);
writew
(
rx_mode
,
ioaddr
+
ReceiveMode
);
...
...
@@ -1677,8 +1704,9 @@ module_exit (rio_exit);
Compile command:
gcc -D__KERNEL__ -DMODULE -I/usr/src/linux/include -Wall -Wstrict-prototypes -O2 -c dl2
x
.c
gcc -D__KERNEL__ -DMODULE -I/usr/src/linux/include -Wall -Wstrict-prototypes -O2 -c dl2
k
.c
Read Documentation/networking/dl2k.txt for details.
*/
drivers/net/dl2k.h
View file @
948d8589
...
...
@@ -34,7 +34,7 @@
#include <linux/spinlock.h>
#include <linux/time.h>
#define TX_RING_SIZE 128
#define TX_QUEUE_LEN
96
/* Limit ring entries actually used. */
#define TX_QUEUE_LEN
120
/* Limit ring entries actually used. */
#define RX_RING_SIZE 128
#define TX_TOTAL_SIZE TX_RING_SIZE*sizeof(struct netdev_desc)
#define RX_TOTAL_SIZE RX_RING_SIZE*sizeof(struct netdev_desc)
...
...
@@ -183,12 +183,12 @@ enum IntStatus_bits {
/* Bits in the ReceiveMode register. */
enum
ReceiveMode_bits
{
ReceiveIPMulticast
=
0x0020
,
ReceiveMulticastHash
=
0x0010
,
ReceiveAllFrames
=
0x0008
,
ReceiveBroadcast
=
0x0004
,
ReceiveMulticast
=
0x0002
,
ReceiveUnicast
=
0x0001
,
ReceiveMulticast
=
0x0002
,
ReceiveBroadcast
=
0x0004
,
ReceiveAllFrames
=
0x0008
,
ReceiveMulticastHash
=
0x0010
,
ReceiveIPMulticast
=
0x0020
,
ReceiveVLANMatch
=
0x0100
,
ReceiveVLANHash
=
0x0200
,
};
...
...
@@ -650,20 +650,20 @@ struct netdev_private {
struct
pci_dev
*
pdev
;
spinlock_t
lock
;
struct
net_device_stats
stats
;
unsigned
int
rx_buf_sz
;
/* Based on MTU+slack. */
unsigned
int
speed
;
/* Operating speed */
unsigned
int
vlan
;
/* VLAN Id */
unsigned
int
chip_id
;
/* PCI table chip id */
unsigned
int
int_count
;
/* Maximum frames each RxDMAComplete intr */
unsigned
int
int_timeout
;
/* Wait time between RxDMAComplete intr */
unsigned
int
tx_full
:
1
;
/* The Tx queue is full. */
unsigned
int
rx_buf_sz
;
/* Based on MTU+slack. */
unsigned
int
speed
;
/* Operating speed */
unsigned
int
vlan
;
/* VLAN Id */
unsigned
int
chip_id
;
/* PCI table chip id */
unsigned
int
rx_coalesce
;
/* Maximum frames each RxDMAComplete intr */
unsigned
int
rx_timeout
;
/* Wait time between RxDMAComplete intr */
unsigned
int
tx_full
:
1
;
/* The Tx queue is full. */
unsigned
int
full_duplex
:
1
;
/* Full-duplex operation requested. */
unsigned
int
an_enable
:
2
;
/* Auto-Negotiated Enable */
unsigned
int
jumbo
:
1
;
/* Jumbo frame enable */
unsigned
int
coalesce
:
1
;
/* Rx coalescing enable */
unsigned
int
tx_flow
:
1
;
/* Tx flow control enable */
unsigned
int
rx_flow
:
1
;
/* Rx flow control enable */
unsigned
int
phy_media
:
1
;
/* 1: fiber, 0: copper */
unsigned
int
phy_media
:
1
;
/* 1: fiber, 0: copper */
struct
netdev_desc
*
last_tx
;
/* Last Tx descriptor used. */
unsigned
long
cur_rx
,
old_rx
;
/* Producer/consumer ring indices */
unsigned
long
cur_tx
,
old_tx
;
...
...
@@ -698,7 +698,12 @@ static struct pci_device_id rio_pci_tbl[] __devinitdata = {
MODULE_DEVICE_TABLE
(
pci
,
rio_pci_tbl
);
#define TX_TIMEOUT (4*HZ)
#define PACKET_SIZE 1536
#define MAX_JUMBO 8000
#define RIO_IO_SIZE 340
#define DEFAULT_RXC 5
#define DEFAULT_RXT 750
#define DEFAULT_TXC 1
#define MAX_TXC 8
#ifdef RIO_DEBUG
#define DEBUG_TFD_DUMP(x) debug_tfd_dump(x)
#define DEBUG_RFD_DUMP(x,flag) debug_rfd_dump(x,flag)
...
...
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