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
3f8e1a1d
Commit
3f8e1a1d
authored
Jun 25, 2003
by
Ralf Bächle
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[netdrvr] update declance
parent
022dc70e
Changes
2
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
243 additions
and
212 deletions
+243
-212
drivers/net/Kconfig
drivers/net/Kconfig
+1
-1
drivers/net/declance.c
drivers/net/declance.c
+242
-211
No files found.
drivers/net/Kconfig
View file @
3f8e1a1d
...
@@ -1850,7 +1850,7 @@ config SGISEEQ
...
@@ -1850,7 +1850,7 @@ config SGISEEQ
used in many Silicon Graphics machines.
used in many Silicon Graphics machines.
config DECLANCE
config DECLANCE
bool
"DEC LANCE ethernet controller support"
tristate
"DEC LANCE ethernet controller support"
depends on NET_ETHERNET && DECSTATION
depends on NET_ETHERNET && DECSTATION
help
help
This driver is for the series of Ethernet controllers produced by
This driver is for the series of Ethernet controllers produced by
...
...
drivers/net/declance.c
View file @
3f8e1a1d
...
@@ -5,6 +5,8 @@
...
@@ -5,6 +5,8 @@
*
*
* adopted from sunlance.c by Richard van den Berg
* adopted from sunlance.c by Richard van den Berg
*
*
* Copyright (C) 2002, 2003 Maciej W. Rozycki
*
* additional sources:
* additional sources:
* - PMAD-AA TURBOchannel Ethernet Module Functional Specification,
* - PMAD-AA TURBOchannel Ethernet Module Functional Specification,
* Revision 1.2
* Revision 1.2
...
@@ -21,71 +23,66 @@
...
@@ -21,71 +23,66 @@
* v0.004: lance-regs is pointing at the right addresses, added prom
* v0.004: lance-regs is pointing at the right addresses, added prom
* check. First start of address mapping and DMA.
* check. First start of address mapping and DMA.
*
*
* v0.005: started to play around with LANCE-DMA. This driver will not
work
* v0.005: started to play around with LANCE-DMA. This driver will not
* for non IOASIC lances. HK
*
work
for non IOASIC lances. HK
*
*
* v0.006: added pointer arrays to lance_private and setup routine for
them
* v0.006: added pointer arrays to lance_private and setup routine for
* in dec_lance_init. HK
*
them
in dec_lance_init. HK
*
*
* v0.007: Big shit. The LANCE seems to use a different DMA mechanism to access
* v0.007: Big shit. The LANCE seems to use a different DMA mechanism to
* the init block. This looks like one (short) word at a time, but the smallest
* access the init block. This looks like one (short) word at a
* amount the IOASIC can transfer is a (long) word. So we have a 2-2 padding here.
* time, but the smallest amount the IOASIC can transfer is a
* Changed lance_init_block accordingly. The 16-16 padding for the buffers
* (long) word. So we have a 2-2 padding here. Changed
* lance_init_block accordingly. The 16-16 padding for the buffers
* seems to be correct. HK
* seems to be correct. HK
*
*
* v0.008 - mods to make PMAX_LANCE work. 01/09/1999 triemer
* v0.008: mods to make PMAX_LANCE work. 01/09/1999 triemer
*/
*
* v0.009: Module support fixes, multiple interfaces support, various
#undef DEBUG_DRIVER
* bits. macro
static
char
*
version
=
"declance.c: v0.008 by Linux Mips DECstation task force
\n
"
;
static
char
*
lancestr
=
"LANCE"
;
/*
* card types
*/
*/
#define ASIC_LANCE 1
#define PMAD_LANCE 2
#define PMAX_LANCE 3
#include <linux/config.h>
#include <linux/crc32.h>
#include <linux/delay.h>
#include <linux/errno.h>
#include <linux/if_ether.h>
#include <linux/init.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/netdevice.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/spinlock.h>
#include <linux/stddef.h>
#include <linux/string.h>
#include <asm/addrspace.h>
#include <asm/dec/interrupts.h>
#include <asm/dec/interrupts.h>
#include <asm/dec/ioasic
_ints
.h>
#include <asm/dec/ioasic.h>
#include <asm/dec/ioasic_addrs.h>
#include <asm/dec/ioasic_addrs.h>
#include <asm/dec/kn01.h>
#include <asm/dec/machtype.h>
#include <asm/dec/machtype.h>
#include <asm/dec/tc.h>
#include <asm/dec/tc.h>
#include <asm/dec/kn01.h>
#include <asm/system.h>
#include <asm/wbflush.h>
#include <asm/addrspace.h>
#include <linux/config.h>
static
char
version
[]
__devinitdata
=
#include <linux/errno.h>
"declance.c: v0.009 by Linux MIPS DECstation task force
\n
"
;
#include <linux/hdreg.h>
#include <linux/ioport.h>
MODULE_AUTHOR
(
"Linux MIPS DECstation task force"
);
#include <linux/mm.h>
MODULE_DESCRIPTION
(
"DEC LANCE (DECstation onboard, PMAD-xx) driver"
);
#include <linux/stddef.h>
MODULE_LICENSE
(
"GPL"
);
#include <linux/string.h>
#include <linux/unistd.h>
/*
#include <linux/slab.h>
* card types
#include <linux/user.h>
*/
#include <linux/utsname.h>
#define ASIC_LANCE 1
#include <linux/a.out.h>
#define PMAD_LANCE 2
#include <linux/tty.h>
#define PMAX_LANCE 3
#include <linux/delay.h>
#include <linux/crc32.h>
#include <asm/io.h>
#include <linux/etherdevice.h>
#ifndef CONFIG_TC
#ifndef CONFIG_TC
unsigned
long
system_base
;
unsigned
long
system_base
;
unsigned
long
dmaptr
;
unsigned
long
dmaptr
;
#endif
#endif
static
int
type
;
#define LE_CSR0 0
#define LE_CSR0 0
#define LE_CSR1 1
#define LE_CSR1 1
...
@@ -160,8 +157,6 @@ static int type;
...
@@ -160,8 +157,6 @@ static int type;
#define TX_BUFF_SIZE PKT_BUF_SZ
#define TX_BUFF_SIZE PKT_BUF_SZ
#undef TEST_HITS
#undef TEST_HITS
#define DEBUG_DRIVER 1
#define ZERO 0
#define ZERO 0
/* The DS2000/3000 have a linear 64 KB buffer.
/* The DS2000/3000 have a linear 64 KB buffer.
...
@@ -184,11 +179,10 @@ struct lance_rx_desc {
...
@@ -184,11 +179,10 @@ struct lance_rx_desc {
unsigned
char
rmd1_hadr
;
/* high address of packet */
unsigned
char
rmd1_hadr
;
/* high address of packet */
unsigned
char
rmd1_bits
;
/* descriptor bits */
unsigned
char
rmd1_bits
;
/* descriptor bits */
short
gap1
;
short
gap1
;
short
length
;
/* This length is 2s complement (negative)!
short
length
;
/* 2s complement (negative!)
* Buffer length
of buffer length */
*/
short
gap2
;
short
gap2
;
unsigned
short
mblength
;
/*
This is the
actual number of bytes received */
unsigned
short
mblength
;
/* actual number of bytes received */
short
gap3
;
short
gap3
;
};
};
...
@@ -198,7 +192,8 @@ struct lance_tx_desc {
...
@@ -198,7 +192,8 @@ struct lance_tx_desc {
unsigned
char
tmd1_hadr
;
/* high address of packet */
unsigned
char
tmd1_hadr
;
/* high address of packet */
unsigned
char
tmd1_bits
;
/* descriptor bits */
unsigned
char
tmd1_bits
;
/* descriptor bits */
short
gap1
;
short
gap1
;
short
length
;
/* Length is 2s complement (negative)! */
short
length
;
/* 2s complement (negative!)
of buffer length */
short
gap2
;
short
gap2
;
unsigned
short
misc
;
unsigned
short
misc
;
short
gap3
;
short
gap3
;
...
@@ -207,17 +202,15 @@ struct lance_tx_desc {
...
@@ -207,17 +202,15 @@ struct lance_tx_desc {
/* First part of the LANCE initialization block, described in databook. */
/* First part of the LANCE initialization block, described in databook. */
struct
lance_init_block
{
struct
lance_init_block
{
unsigned
short
mode
;
/* P
re-set mode (reg. 15) */
unsigned
short
mode
;
/* p
re-set mode (reg. 15) */
short
gap0
;
short
gap0
;
unsigned
char
phys_addr
[
12
];
/* Physical ethernet address
unsigned
char
phys_addr
[
12
];
/* physical ethernet address
* only 0, 1, 4, 5, 8, 9 are valid
only 0, 1, 4, 5, 8, 9 are valid
* 2, 3, 6, 7, 10, 11 are gaps
2, 3, 6, 7, 10, 11 are gaps */
*/
unsigned
short
filter
[
8
];
/* multicast filter
unsigned
short
filter
[
8
];
/* Multicast filter.
only 0, 2, 4, 6 are valid
* only 0, 2, 4, 6 are valid
1, 3, 5, 7 are gaps */
* 1, 3, 5, 7 are gaps
*/
/* Receive and transmit ring base, along with extra bits. */
/* Receive and transmit ring base, along with extra bits. */
unsigned
short
rx_ptr
;
/* receive descriptor addr */
unsigned
short
rx_ptr
;
/* receive descriptor addr */
...
@@ -228,7 +221,7 @@ struct lance_init_block {
...
@@ -228,7 +221,7 @@ struct lance_init_block {
short
gap3
;
short
gap3
;
unsigned
short
tx_len
;
/* transmit len and high addr */
unsigned
short
tx_len
;
/* transmit len and high addr */
short
gap4
;
short
gap4
;
char
gap5
[
16
];
short
gap5
[
8
];
/* The buffer descriptors */
/* The buffer descriptors */
struct
lance_rx_desc
brx_ring
[
RX_RING_SIZE
];
struct
lance_rx_desc
brx_ring
[
RX_RING_SIZE
];
...
@@ -247,10 +240,12 @@ struct lance_init_block {
...
@@ -247,10 +240,12 @@ struct lance_init_block {
#define LANCE_ADDR(x) (PHYSADDR(x) >> 1)
#define LANCE_ADDR(x) (PHYSADDR(x) >> 1)
struct
lance_private
{
struct
lance_private
{
char
*
name
;
struct
net_device
*
next
;
int
type
;
int
slot
;
int
dma_irq
;
volatile
struct
lance_regs
*
ll
;
volatile
struct
lance_regs
*
ll
;
volatile
struct
lance_init_block
*
init_block
;
volatile
struct
lance_init_block
*
init_block
;
volatile
unsigned
long
*
dma_ptr_reg
;
spinlock_t
lock
;
spinlock_t
lock
;
...
@@ -261,8 +256,6 @@ struct lance_private {
...
@@ -261,8 +256,6 @@ struct lance_private {
unsigned
short
busmaster_regval
;
unsigned
short
busmaster_regval
;
struct
net_device
*
dev
;
/* Backpointer */
struct
lance_private
*
next_module
;
struct
timer_list
multicast_timer
;
struct
timer_list
multicast_timer
;
/* Pointers to the ring buffers as seen from the CPU */
/* Pointers to the ring buffers as seen from the CPU */
...
@@ -292,16 +285,12 @@ struct lance_regs {
...
@@ -292,16 +285,12 @@ struct lance_regs {
int
dec_lance_debug
=
2
;
int
dec_lance_debug
=
2
;
/*
static
struct
net_device
*
root_lance_dev
;
#ifdef MODULE
static struct lance_private *root_lance_dev = NULL;
#endif
*/
static
inline
void
writereg
(
volatile
unsigned
short
*
regptr
,
short
value
)
static
inline
void
writereg
(
volatile
unsigned
short
*
regptr
,
short
value
)
{
{
*
regptr
=
value
;
*
regptr
=
value
;
wbflush
();
iob
();
}
}
/* Load the CSR registers */
/* Load the CSR registers */
...
@@ -330,7 +319,7 @@ static void load_csrs(struct lance_private *lp)
...
@@ -330,7 +319,7 @@ static void load_csrs(struct lance_private *lp)
* Our specialized copy routines
* Our specialized copy routines
*
*
*/
*/
void
cp_to_buf
(
void
*
to
,
const
void
*
from
,
__kernel_size_
t
len
)
void
cp_to_buf
(
const
int
type
,
void
*
to
,
const
void
*
from
,
in
t
len
)
{
{
unsigned
short
*
tp
,
*
fp
,
clen
;
unsigned
short
*
tp
,
*
fp
,
clen
;
unsigned
char
*
rtp
,
*
rfp
;
unsigned
char
*
rtp
,
*
rfp
;
...
@@ -381,10 +370,10 @@ void cp_to_buf(void *to, const void *from, __kernel_size_t len)
...
@@ -381,10 +370,10 @@ void cp_to_buf(void *to, const void *from, __kernel_size_t len)
}
}
}
}
wbflush
();
iob
();
}
}
void
cp_from_buf
(
void
*
to
,
unsigned
char
*
from
,
int
len
)
void
cp_from_buf
(
const
int
type
,
void
*
to
,
const
void
*
from
,
int
len
)
{
{
unsigned
short
*
tp
,
*
fp
,
clen
;
unsigned
short
*
tp
,
*
fp
,
clen
;
unsigned
char
*
rtp
,
*
rfp
;
unsigned
char
*
rtp
,
*
rfp
;
...
@@ -509,7 +498,7 @@ static void lance_init_ring(struct net_device *dev)
...
@@ -509,7 +498,7 @@ static void lance_init_ring(struct net_device *dev)
if
(
i
<
3
&&
ZERO
)
if
(
i
<
3
&&
ZERO
)
printk
(
"%d: 0x%8.8x(0x%8.8x)
\n
"
,
i
,
leptr
,
(
int
)
lp
->
rx_buf_ptr_cpu
[
i
]);
printk
(
"%d: 0x%8.8x(0x%8.8x)
\n
"
,
i
,
leptr
,
(
int
)
lp
->
rx_buf_ptr_cpu
[
i
]);
}
}
wbflush
();
iob
();
}
}
static
int
init_restart_lance
(
struct
lance_private
*
lp
)
static
int
init_restart_lance
(
struct
lance_private
*
lp
)
...
@@ -556,17 +545,16 @@ static int lance_rx(struct net_device *dev)
...
@@ -556,17 +545,16 @@ static int lance_rx(struct net_device *dev)
printk
(
"["
);
printk
(
"["
);
for
(
i
=
0
;
i
<
RX_RING_SIZE
;
i
++
)
{
for
(
i
=
0
;
i
<
RX_RING_SIZE
;
i
++
)
{
if
(
i
==
lp
->
rx_new
)
if
(
i
==
lp
->
rx_new
)
printk
(
"%s"
,
printk
(
"%s"
,
ib
->
brx_ring
[
i
].
rmd1_bits
&
ib
->
brx_ring
[
i
].
rmd1_bits
&
LE_R1_OWN
?
"_"
:
"X"
);
LE_R1_OWN
?
"_"
:
"X"
);
else
else
printk
(
"%s"
,
printk
(
"%s"
,
ib
->
brx_ring
[
i
].
rmd1_bits
&
ib
->
brx_ring
[
i
].
rmd1_bits
&
LE_R1_OWN
?
"."
:
"1"
);
LE_R1_OWN
?
"."
:
"1"
);
}
}
printk
(
"]"
);
printk
(
"]"
);
}
}
#endif
#endif
for
(
rd
=
&
ib
->
brx_ring
[
lp
->
rx_new
];
for
(
rd
=
&
ib
->
brx_ring
[
lp
->
rx_new
];
!
((
bits
=
rd
->
rmd1_bits
)
&
LE_R1_OWN
);
!
((
bits
=
rd
->
rmd1_bits
)
&
LE_R1_OWN
);
rd
=
&
ib
->
brx_ring
[
lp
->
rx_new
])
{
rd
=
&
ib
->
brx_ring
[
lp
->
rx_new
])
{
...
@@ -608,8 +596,8 @@ static int lance_rx(struct net_device *dev)
...
@@ -608,8 +596,8 @@ static int lance_rx(struct net_device *dev)
skb_reserve
(
skb
,
2
);
/* 16 byte align */
skb_reserve
(
skb
,
2
);
/* 16 byte align */
skb_put
(
skb
,
len
);
/* make room */
skb_put
(
skb
,
len
);
/* make room */
cp_from_buf
(
skb
->
data
,
cp_from_buf
(
lp
->
type
,
skb
->
data
,
(
char
*
)
lp
->
rx_buf_ptr_cpu
[
lp
->
rx_new
],
(
char
*
)
lp
->
rx_buf_ptr_cpu
[
lp
->
rx_new
],
len
);
len
);
skb
->
protocol
=
eth_type_trans
(
skb
,
dev
);
skb
->
protocol
=
eth_type_trans
(
skb
,
dev
);
...
@@ -709,6 +697,14 @@ static void lance_tx(struct net_device *dev)
...
@@ -709,6 +697,14 @@ static void lance_tx(struct net_device *dev)
spin_unlock
(
&
lp
->
lock
);
spin_unlock
(
&
lp
->
lock
);
}
}
static
void
lance_dma_merr_int
(
const
int
irq
,
void
*
dev_id
,
struct
pt_regs
*
regs
)
{
struct
net_device
*
dev
=
(
struct
net_device
*
)
dev_id
;
printk
(
"%s: DMA error
\n
"
,
dev
->
name
);
}
static
irqreturn_t
static
irqreturn_t
lance_interrupt
(
const
int
irq
,
void
*
dev_id
,
struct
pt_regs
*
regs
)
lance_interrupt
(
const
int
irq
,
void
*
dev_id
,
struct
pt_regs
*
regs
)
{
{
...
@@ -741,19 +737,8 @@ lance_interrupt(const int irq, void *dev_id, struct pt_regs *regs)
...
@@ -741,19 +737,8 @@ lance_interrupt(const int irq, void *dev_id, struct pt_regs *regs)
lp
->
stats
.
rx_errors
++
;
lp
->
stats
.
rx_errors
++
;
if
(
csr0
&
LE_C0_MERR
)
{
if
(
csr0
&
LE_C0_MERR
)
{
volatile
unsigned
long
int_stat
=
*
(
unsigned
long
*
)
(
system_base
+
IOCTL
+
SIR
);
printk
(
"%s: Memory error, status %04x
\n
"
,
dev
->
name
,
csr0
);
printk
(
"%s: Memory error, status %04x
\n
"
,
dev
->
name
,
csr0
);
if
(
int_stat
&
LANCE_DMA_MEMRDERR
)
{
printk
(
"%s: DMA error
\n
"
,
dev
->
name
);
int_stat
|=
LANCE_DMA_MEMRDERR
;
/*
* re-enable LANCE DMA
*/
*
(
unsigned
long
*
)
(
system_base
+
IOCTL
+
SSR
)
|=
(
1
<<
16
);
wbflush
();
}
writereg
(
&
ll
->
rdp
,
LE_C0_STOP
);
writereg
(
&
ll
->
rdp
,
LE_C0_STOP
);
lance_init_ring
(
dev
);
lance_init_ring
(
dev
);
...
@@ -800,10 +785,30 @@ static int lance_open(struct net_device *dev)
...
@@ -800,10 +785,30 @@ static int lance_open(struct net_device *dev)
netif_start_queue
(
dev
);
netif_start_queue
(
dev
);
/* Associate IRQ with lance_interrupt */
/* Associate IRQ with lance_interrupt */
if
(
request_irq
(
dev
->
irq
,
&
lance_interrupt
,
0
,
lp
->
name
,
dev
))
{
if
(
request_irq
(
dev
->
irq
,
&
lance_interrupt
,
0
,
"lance"
,
dev
))
{
printk
(
"
Lance: Can't get irq
%d
\n
"
,
dev
->
irq
);
printk
(
"
lance: Can't get IRQ
%d
\n
"
,
dev
->
irq
);
return
-
EAGAIN
;
return
-
EAGAIN
;
}
}
if
(
lp
->
dma_irq
>=
0
)
{
unsigned
long
flags
;
if
(
request_irq
(
lp
->
dma_irq
,
&
lance_dma_merr_int
,
0
,
"lance error"
,
dev
))
{
free_irq
(
dev
->
irq
,
dev
);
printk
(
"lance: Can't get DMA IRQ %d
\n
"
,
lp
->
dma_irq
);
return
-
EAGAIN
;
}
spin_lock_irqsave
(
&
ioasic_ssr_lock
,
flags
);
fast_mb
();
/* Enable I/O ASIC LANCE DMA. */
ioasic_write
(
IO_REG_SSR
,
ioasic_read
(
IO_REG_SSR
)
|
IO_SSR_LANCE_DMA_EN
);
fast_mb
();
spin_unlock_irqrestore
(
&
ioasic_ssr_lock
,
flags
);
}
status
=
init_restart_lance
(
lp
);
status
=
init_restart_lance
(
lp
);
...
@@ -827,7 +832,22 @@ static int lance_close(struct net_device *dev)
...
@@ -827,7 +832,22 @@ static int lance_close(struct net_device *dev)
writereg
(
&
ll
->
rap
,
LE_CSR0
);
writereg
(
&
ll
->
rap
,
LE_CSR0
);
writereg
(
&
ll
->
rdp
,
LE_C0_STOP
);
writereg
(
&
ll
->
rdp
,
LE_C0_STOP
);
free_irq
(
dev
->
irq
,
(
void
*
)
dev
);
if
(
lp
->
dma_irq
>=
0
)
{
unsigned
long
flags
;
spin_lock_irqsave
(
&
ioasic_ssr_lock
,
flags
);
fast_mb
();
/* Disable I/O ASIC LANCE DMA. */
ioasic_write
(
IO_REG_SSR
,
ioasic_read
(
IO_REG_SSR
)
&
~
IO_SSR_LANCE_DMA_EN
);
fast_iob
();
spin_unlock_irqrestore
(
&
ioasic_ssr_lock
,
flags
);
free_irq
(
lp
->
dma_irq
,
dev
);
}
free_irq
(
dev
->
irq
,
dev
);
/*
/*
MOD_DEC_USE_COUNT;
MOD_DEC_USE_COUNT;
*/
*/
...
@@ -886,7 +906,8 @@ static int lance_start_xmit(struct sk_buff *skb, struct net_device *dev)
...
@@ -886,7 +906,8 @@ static int lance_start_xmit(struct sk_buff *skb, struct net_device *dev)
ib
->
btx_ring
[
entry
].
length
=
(
-
len
);
ib
->
btx_ring
[
entry
].
length
=
(
-
len
);
ib
->
btx_ring
[
entry
].
misc
=
0
;
ib
->
btx_ring
[
entry
].
misc
=
0
;
cp_to_buf
((
char
*
)
lp
->
tx_buf_ptr_cpu
[
entry
],
skb
->
data
,
skblen
);
cp_to_buf
(
lp
->
type
,
(
char
*
)
lp
->
tx_buf_ptr_cpu
[
entry
],
skb
->
data
,
skblen
);
/* Clear the slack of the packet, do I need this? */
/* Clear the slack of the packet, do I need this? */
/* For a firewall it's a good idea - AC */
/* For a firewall it's a good idea - AC */
...
@@ -926,7 +947,7 @@ static void lance_load_multicast(struct net_device *dev)
...
@@ -926,7 +947,7 @@ static void lance_load_multicast(struct net_device *dev)
volatile
u16
*
mcast_table
=
(
u16
*
)
&
ib
->
filter
;
volatile
u16
*
mcast_table
=
(
u16
*
)
&
ib
->
filter
;
struct
dev_mc_list
*
dmi
=
dev
->
mc_list
;
struct
dev_mc_list
*
dmi
=
dev
->
mc_list
;
char
*
addrs
;
char
*
addrs
;
int
i
,
j
,
bit
,
byte
;
int
i
;
u32
crc
;
u32
crc
;
/* set all multicast bits */
/* set all multicast bits */
...
@@ -952,7 +973,7 @@ static void lance_load_multicast(struct net_device *dev)
...
@@ -952,7 +973,7 @@ static void lance_load_multicast(struct net_device *dev)
if
(
!
(
*
addrs
&
1
))
if
(
!
(
*
addrs
&
1
))
continue
;
continue
;
crc
=
ether_crc_le
(
6
,
addrs
);
crc
=
ether_crc_le
(
ETH_ALEN
,
addrs
);
crc
=
crc
>>
26
;
crc
=
crc
>>
26
;
mcast_table
[
2
*
(
crc
>>
4
)]
|=
1
<<
(
crc
&
0xf
);
mcast_table
[
2
*
(
crc
>>
4
)]
|=
1
<<
(
crc
&
0xf
);
}
}
...
@@ -1001,7 +1022,7 @@ static void lance_set_multicast_retry(unsigned long _opaque)
...
@@ -1001,7 +1022,7 @@ static void lance_set_multicast_retry(unsigned long _opaque)
lance_set_multicast
(
dev
);
lance_set_multicast
(
dev
);
}
}
static
int
__init
dec_lance_init
(
struct
net_device
*
dev
,
const
int
type
)
static
int
__init
dec_lance_init
(
const
int
type
,
const
int
slot
)
{
{
static
unsigned
version_printed
;
static
unsigned
version_printed
;
struct
net_device
*
dev
;
struct
net_device
*
dev
;
...
@@ -1013,25 +1034,29 @@ static int __init dec_lance_init(struct net_device *dev, const int type)
...
@@ -1013,25 +1034,29 @@ static int __init dec_lance_init(struct net_device *dev, const int type)
#ifndef CONFIG_TC
#ifndef CONFIG_TC
system_base
=
KN01_LANCE_BASE
;
system_base
=
KN01_LANCE_BASE
;
#else
int
slot
;
#endif
#endif
if
(
dec_lance_debug
&&
version_printed
++
==
0
)
if
(
dec_lance_debug
&&
version_printed
++
==
0
)
printk
(
version
);
printk
(
version
);
dev
=
init_etherdev
(
0
,
sizeof
(
struct
lance_private
));
dev
=
init_etherdev
(
NULL
,
sizeof
(
struct
lance_private
));
if
(
!
dev
)
if
(
!
dev
)
return
-
ENOMEM
;
return
-
ENOMEM
;
SET_MODULE_OWNER
(
dev
);
/* init_etherdev ensures the data structures used by the LANCE are aligned. */
/*
* init_etherdev ensures the data structures used by the LANCE
* are aligned.
*/
lp
=
(
struct
lance_private
*
)
dev
->
priv
;
lp
=
(
struct
lance_private
*
)
dev
->
priv
;
spin_lock_init
(
&
lp
->
lock
);
spin_lock_init
(
&
lp
->
lock
);
lp
->
type
=
type
;
lp
->
slot
=
slot
;
switch
(
type
)
{
switch
(
type
)
{
#ifdef CONFIG_TC
#ifdef CONFIG_TC
case
ASIC_LANCE
:
case
ASIC_LANCE
:
dev
->
base_addr
=
system_base
+
LANCE
;
dev
->
base_addr
=
system_base
+
IOASIC_
LANCE
;
/* buffer space for the on-board LANCE shared memory */
/* buffer space for the on-board LANCE shared memory */
/*
/*
...
@@ -1039,78 +1064,101 @@ static int __init dec_lance_init(struct net_device *dev, const int type)
...
@@ -1039,78 +1064,101 @@ static int __init dec_lance_init(struct net_device *dev, const int type)
*/
*/
dev
->
mem_start
=
KSEG1ADDR
(
0x00020000
);
dev
->
mem_start
=
KSEG1ADDR
(
0x00020000
);
dev
->
mem_end
=
dev
->
mem_start
+
0x00020000
;
dev
->
mem_end
=
dev
->
mem_start
+
0x00020000
;
dev
->
irq
=
ETHER
;
dev
->
irq
=
dec_interrupt
[
DEC_IRQ_LANCE
]
;
esar_base
=
system_base
+
ESAR
;
esar_base
=
system_base
+
IOASIC_
ESAR
;
/* Workaround crash with booting KN04 2.1k from Disk */
/* Workaround crash with booting KN04 2.1k from Disk */
memset
(
dev
->
mem_start
,
0
,
dev
->
mem_end
-
dev
->
mem_start
);
memset
((
void
*
)
dev
->
mem_start
,
0
,
dev
->
mem_end
-
dev
->
mem_start
);
/*
/*
* setup the pointer arrays, this sucks [tm] :-(
* setup the pointer arrays, this sucks [tm] :-(
*/
*/
for
(
i
=
0
;
i
<
RX_RING_SIZE
;
i
++
)
{
for
(
i
=
0
;
i
<
RX_RING_SIZE
;
i
++
)
{
lp
->
rx_buf_ptr_cpu
[
i
]
=
(
char
*
)
(
dev
->
mem_start
+
BUF_OFFSET_CPU
lp
->
rx_buf_ptr_cpu
[
i
]
=
+
2
*
i
*
RX_BUFF_SIZE
);
(
char
*
)(
dev
->
mem_start
+
BUF_OFFSET_CPU
+
lp
->
rx_buf_ptr_lnc
[
i
]
=
(
char
*
)
(
BUF_OFFSET_LNC
2
*
i
*
RX_BUFF_SIZE
);
+
i
*
RX_BUFF_SIZE
);
lp
->
rx_buf_ptr_lnc
[
i
]
=
(
char
*
)(
BUF_OFFSET_LNC
+
i
*
RX_BUFF_SIZE
);
}
}
for
(
i
=
0
;
i
<
TX_RING_SIZE
;
i
++
)
{
for
(
i
=
0
;
i
<
TX_RING_SIZE
;
i
++
)
{
lp
->
tx_buf_ptr_cpu
[
i
]
=
(
char
*
)
(
dev
->
mem_start
+
BUF_OFFSET_CPU
lp
->
tx_buf_ptr_cpu
[
i
]
=
+
2
*
RX_RING_SIZE
*
RX_BUFF_SIZE
(
char
*
)(
dev
->
mem_start
+
BUF_OFFSET_CPU
+
+
2
*
i
*
TX_BUFF_SIZE
);
2
*
RX_RING_SIZE
*
RX_BUFF_SIZE
+
lp
->
tx_buf_ptr_lnc
[
i
]
=
(
char
*
)
(
BUF_OFFSET_LNC
2
*
i
*
TX_BUFF_SIZE
);
+
RX_RING_SIZE
*
RX_BUFF_SIZE
lp
->
tx_buf_ptr_lnc
[
i
]
=
+
i
*
TX_BUFF_SIZE
);
(
char
*
)(
BUF_OFFSET_LNC
+
RX_RING_SIZE
*
RX_BUFF_SIZE
+
i
*
TX_BUFF_SIZE
);
}
}
/*
/* Setup I/O ASIC LANCE DMA. */
* setup and enable IOASIC LANCE DMA
lp
->
dma_irq
=
dec_interrupt
[
DEC_IRQ_LANCE_MERR
];
*/
ioasic_write
(
IO_REG_LANCE_DMA_P
,
lp
->
dma_ptr_reg
=
(
unsigned
long
*
)
(
system_base
+
IOCTL
+
LANCE_DMA_P
);
PHYSADDR
(
dev
->
mem_start
)
<<
3
);
*
(
lp
->
dma_ptr_reg
)
=
PHYSADDR
(
dev
->
mem_start
)
<<
3
;
*
(
unsigned
long
*
)
(
system_base
+
IOCTL
+
SSR
)
|=
(
1
<<
16
);
wbflush
();
break
;
break
;
case
PMAD_LANCE
:
case
PMAD_LANCE
:
slot
=
search_tc_card
(
"PMAD-AA"
);
claim_tc_card
(
slot
);
claim_tc_card
(
slot
);
dev
->
mem_start
=
get_tc_base_addr
(
slot
);
dev
->
mem_start
=
get_tc_base_addr
(
slot
);
dev
->
base_addr
=
dev
->
mem_start
+
0x100000
;
dev
->
base_addr
=
dev
->
mem_start
+
0x100000
;
dev
->
irq
=
get_tc_irq_nr
(
slot
);
dev
->
irq
=
get_tc_irq_nr
(
slot
);
esar_base
=
dev
->
mem_start
+
0x1c0002
;
esar_base
=
dev
->
mem_start
+
0x1c0002
;
lp
->
dma_irq
=
-
1
;
for
(
i
=
0
;
i
<
RX_RING_SIZE
;
i
++
)
{
lp
->
rx_buf_ptr_cpu
[
i
]
=
(
char
*
)(
dev
->
mem_start
+
BUF_OFFSET_CPU
+
i
*
RX_BUFF_SIZE
);
lp
->
rx_buf_ptr_lnc
[
i
]
=
(
char
*
)(
BUF_OFFSET_LNC
+
i
*
RX_BUFF_SIZE
);
}
for
(
i
=
0
;
i
<
TX_RING_SIZE
;
i
++
)
{
lp
->
tx_buf_ptr_cpu
[
i
]
=
(
char
*
)(
dev
->
mem_start
+
BUF_OFFSET_CPU
+
RX_RING_SIZE
*
RX_BUFF_SIZE
+
i
*
TX_BUFF_SIZE
);
lp
->
tx_buf_ptr_lnc
[
i
]
=
(
char
*
)(
BUF_OFFSET_LNC
+
RX_RING_SIZE
*
RX_BUFF_SIZE
+
i
*
TX_BUFF_SIZE
);
}
break
;
break
;
#endif
#endif
case
PMAX_LANCE
:
case
PMAX_LANCE
:
dev
->
irq
=
ETHER
;
dev
->
irq
=
dec_interrupt
[
DEC_IRQ_LANCE
]
;
dev
->
base_addr
=
KN01_LANCE_BASE
;
dev
->
base_addr
=
KN01_LANCE_BASE
;
dev
->
mem_start
=
KN01_LANCE_BASE
+
0x01000000
;
dev
->
mem_start
=
KN01_LANCE_BASE
+
0x01000000
;
esar_base
=
KN01_RTC_BASE
+
1
;
esar_base
=
KN01_RTC_BASE
+
1
;
lp
->
dma_irq
=
-
1
;
/*
/*
* setup the pointer arrays, this sucks [tm] :-(
* setup the pointer arrays, this sucks [tm] :-(
*/
*/
for
(
i
=
0
;
i
<
RX_RING_SIZE
;
i
++
)
{
for
(
i
=
0
;
i
<
RX_RING_SIZE
;
i
++
)
{
lp
->
rx_buf_ptr_cpu
[
i
]
=
lp
->
rx_buf_ptr_cpu
[
i
]
=
(
char
*
)
(
dev
->
mem_start
+
BUF_OFFSET_CPU
(
char
*
)(
dev
->
mem_start
+
BUF_OFFSET_CPU
+
+
2
*
i
*
RX_BUFF_SIZE
);
2
*
i
*
RX_BUFF_SIZE
);
lp
->
rx_buf_ptr_lnc
[
i
]
=
lp
->
rx_buf_ptr_lnc
[
i
]
=
(
char
*
)
(
BUF_OFFSET_LNC
(
char
*
)(
BUF_OFFSET_LNC
+
i
*
RX_BUFF_SIZE
);
+
i
*
RX_BUFF_SIZE
);
}
}
for
(
i
=
0
;
i
<
TX_RING_SIZE
;
i
++
)
{
for
(
i
=
0
;
i
<
TX_RING_SIZE
;
i
++
)
{
lp
->
tx_buf_ptr_cpu
[
i
]
=
lp
->
tx_buf_ptr_cpu
[
i
]
=
(
char
*
)
(
dev
->
mem_start
+
BUF_OFFSET_CPU
(
char
*
)(
dev
->
mem_start
+
BUF_OFFSET_CPU
+
+
2
*
RX_RING_SIZE
*
RX_BUFF_SIZE
2
*
RX_RING_SIZE
*
RX_BUFF_SIZE
+
+
2
*
i
*
TX_BUFF_SIZE
);
2
*
i
*
TX_BUFF_SIZE
);
lp
->
tx_buf_ptr_lnc
[
i
]
=
(
char
*
)
(
BUF_OFFSET_LNC
lp
->
tx_buf_ptr_lnc
[
i
]
=
+
RX_RING_SIZE
*
RX_BUFF_SIZE
(
char
*
)(
BUF_OFFSET_LNC
+
+
i
*
TX_BUFF_SIZE
);
RX_RING_SIZE
*
RX_BUFF_SIZE
+
i
*
TX_BUFF_SIZE
);
}
}
break
;
break
;
default:
default:
printk
(
"declance_init called with unknown type
\n
"
);
printk
(
"declance_init called with unknown type
\n
"
);
ret
=
-
ENODEV
;
ret
=
-
ENODEV
;
...
@@ -1140,6 +1188,9 @@ static int __init dec_lance_init(struct net_device *dev, const int type)
...
@@ -1140,6 +1188,9 @@ static int __init dec_lance_init(struct net_device *dev, const int type)
}
}
}
}
lp
->
next
=
root_lance_dev
;
root_lance_dev
=
dev
;
/* Copy the ethernet address to the device structure, later to the
/* Copy the ethernet address to the device structure, later to the
* lance initialization block so the lance gets it every time it's
* lance initialization block so the lance gets it every time it's
* (re)initialized.
* (re)initialized.
...
@@ -1162,7 +1213,6 @@ static int __init dec_lance_init(struct net_device *dev, const int type)
...
@@ -1162,7 +1213,6 @@ static int __init dec_lance_init(struct net_device *dev, const int type)
printk
(
" irq = %d
\n
"
,
dev
->
irq
);
printk
(
" irq = %d
\n
"
,
dev
->
irq
);
lp
->
dev
=
dev
;
dev
->
open
=
&
lance_open
;
dev
->
open
=
&
lance_open
;
dev
->
stop
=
&
lance_close
;
dev
->
stop
=
&
lance_close
;
dev
->
hard_start_xmit
=
&
lance_start_xmit
;
dev
->
hard_start_xmit
=
&
lance_start_xmit
;
...
@@ -1174,8 +1224,6 @@ static int __init dec_lance_init(struct net_device *dev, const int type)
...
@@ -1174,8 +1224,6 @@ static int __init dec_lance_init(struct net_device *dev, const int type)
/* lp->ll is the location of the registers for lance card */
/* lp->ll is the location of the registers for lance card */
lp
->
ll
=
ll
;
lp
->
ll
=
ll
;
lp
->
name
=
lancestr
;
/* busmaster_regval (CSR3) should be zero according to the PMAD-AA
/* busmaster_regval (CSR3) should be zero according to the PMAD-AA
* specification.
* specification.
*/
*/
...
@@ -1183,8 +1231,6 @@ static int __init dec_lance_init(struct net_device *dev, const int type)
...
@@ -1183,8 +1231,6 @@ static int __init dec_lance_init(struct net_device *dev, const int type)
dev
->
dma
=
0
;
dev
->
dma
=
0
;
ether_setup
(
dev
);
/* We cannot sleep if the chip is busy during a
/* We cannot sleep if the chip is busy during a
* multicast list update event, because such events
* multicast list update event, because such events
* can occur from interrupts (ex. IPv6). So we
* can occur from interrupts (ex. IPv6). So we
...
@@ -1194,11 +1240,6 @@ static int __init dec_lance_init(struct net_device *dev, const int type)
...
@@ -1194,11 +1240,6 @@ static int __init dec_lance_init(struct net_device *dev, const int type)
lp
->
multicast_timer
.
data
=
(
unsigned
long
)
dev
;
lp
->
multicast_timer
.
data
=
(
unsigned
long
)
dev
;
lp
->
multicast_timer
.
function
=
&
lance_set_multicast_retry
;
lp
->
multicast_timer
.
function
=
&
lance_set_multicast_retry
;
#ifdef MODULE
dev
->
ifindex
=
dev_new_index
();
lp
->
next_module
=
root_lance_dev
;
root_lance_dev
=
lp
;
#endif
return
0
;
return
0
;
err_out:
err_out:
...
@@ -1211,61 +1252,51 @@ static int __init dec_lance_init(struct net_device *dev, const int type)
...
@@ -1211,61 +1252,51 @@ static int __init dec_lance_init(struct net_device *dev, const int type)
/* Find all the lance cards on the system and initialize them */
/* Find all the lance cards on the system and initialize them */
static
int
__init
dec_lance_probe
(
void
)
static
int
__init
dec_lance_probe
(
void
)
{
{
struct
net_device
*
dev
=
NULL
;
int
count
=
0
;
static
int
called
;
#ifdef MODULE
root_lance_dev
=
NULL
;
#endif
/* Scan slots for PMAD-AA cards first. */
#ifdef CONFIG_TC
#ifdef CONFIG_TC
int
slot
=
-
1
;
if
(
TURBOCHANNEL
)
{
if
(
TURBOCHANNEL
)
{
if
(
IOASIC
&&
!
called
)
{
int
slot
;
called
=
1
;
type
=
ASIC_LANCE
;
while
((
slot
=
search_tc_card
(
"PMAD-AA"
))
>=
0
)
{
}
else
{
if
(
dec_lance_init
(
PMAD_LANCE
,
slot
)
<
0
)
if
((
slot
=
search_tc_card
(
"PMAD-AA"
))
>=
0
)
{
break
;
type
=
PMAD_LANCE
;
count
++
;
}
else
{
return
-
ENODEV
;
}
}
}
}
else
{
if
(
!
called
)
{
called
=
1
;
type
=
PMAX_LANCE
;
}
else
{
return
-
ENODEV
;
}
}
#endif
/* Then handle onboard devices. */
if
(
dec_interrupt
[
DEC_IRQ_LANCE
]
>=
0
)
{
if
(
dec_interrupt
[
DEC_IRQ_LANCE_MERR
]
>=
0
)
{
#ifdef CONFIG_TC
if
(
dec_lance_init
(
ASIC_LANCE
,
-
1
)
>=
0
)
count
++
;
#endif
}
else
if
(
!
TURBOCHANNEL
)
{
if
(
dec_lance_init
(
PMAX_LANCE
,
-
1
)
>=
0
)
count
++
;
}
}
#else
if
(
!
called
&&
!
TURBOCHANNEL
)
{
called
=
1
;
type
=
PMAX_LANCE
;
}
else
{
return
-
ENODEV
;
}
}
#endif
return
dec_lance_init
(
dev
,
type
)
;
return
(
count
>
0
)
?
0
:
-
ENODEV
;
}
}
static
void
__exit
dec_lance_cleanup
(
void
)
static
void
__exit
dec_lance_cleanup
(
void
)
{
{
#ifdef MODULE
struct
lance_private
*
lp
;
while
(
root_lance_dev
)
{
while
(
root_lance_dev
)
{
lp
=
root_lance_dev
->
next_module
;
struct
net_device
*
dev
=
root_lance_dev
;
struct
lance_private
*
lp
=
(
struct
lance_private
*
)
dev
->
priv
;
unregister_netdev
(
root_lance_dev
->
dev
);
#ifdef CONFIG_TC
kfree
(
root_lance_dev
->
dev
);
if
(
lp
->
slot
>=
0
)
root_lance_dev
=
lp
;
release_tc_card
(
lp
->
slot
);
#endif
root_lance_dev
=
lp
->
next
;
unregister_netdev
(
dev
);
kfree
(
dev
);
}
}
#endif
/* MODULE */
}
}
module_init
(
dec_lance_probe
);
module_init
(
dec_lance_probe
);
...
...
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