Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
5cc31d9b
Commit
5cc31d9b
authored
Oct 08, 2002
by
Alan Cox
Committed by
Linus Torvalds
Oct 08, 2002
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[PATCH] 2.5 clean up of DE600
parent
9910fa6d
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
255 additions
and
391 deletions
+255
-391
drivers/net/de600.c
drivers/net/de600.c
+85
-391
drivers/net/de600.h
drivers/net/de600.h
+170
-0
No files found.
drivers/net/de600.c
View file @
5cc31d9b
static
const
char
version
[]
=
static
const
char
version
[]
=
"de600.c: $Revision: 1.41-2.5 $, Bjorn Ekwall (bj0rn@blox.se)
\n
"
;
"de600.c: $Revision: 1.40 $, Bjorn Ekwall (bj0rn@blox.se)
\n
"
;
/*
/*
* de600.c
* de600.c
*
*
...
@@ -18,10 +17,6 @@ static const char version[] =
...
@@ -18,10 +17,6 @@ static const char version[] =
* written by: Donald Becker <becker@super.org>
* written by: Donald Becker <becker@super.org>
* (Now at <becker@scyld.com>)
* (Now at <becker@scyld.com>)
*
*
* compile-command:
* "gcc -D__KERNEL__ -Wall -Wstrict-prototypes -O6 -fomit-frame-pointer \
* -m486 -c de600.c
*
**************************************************************/
**************************************************************/
/*
/*
* This program is free software; you can redistribute it and/or modify
* This program is free software; you can redistribute it and/or modify
...
@@ -39,8 +34,9 @@ static const char version[] =
...
@@ -39,8 +34,9 @@ static const char version[] =
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*
**************************************************************/
**************************************************************/
/* Add more time here if your adapter won't work OK: */
/* Add more time here if your adapter won't work OK: */
#define DE600_SLOW_DOWN
udelay(delay_time)
#define DE600_SLOW_DOWN
udelay(delay_time)
/*
/*
* If you still have trouble reading/writing to the adapter,
* If you still have trouble reading/writing to the adapter,
...
@@ -49,38 +45,6 @@ static const char version[] =
...
@@ -49,38 +45,6 @@ static const char version[] =
*/
*/
#define SLOW_IO_BY_JUMPING
/* Looks "better" than dummy write to port 0x80 :-) */
#define SLOW_IO_BY_JUMPING
/* Looks "better" than dummy write to port 0x80 :-) */
/*
* If you want to enable automatic continuous checking for the DE600,
* keep this #define enabled.
* It doesn't cost much per packet, so I think it is worth it!
* If you disagree, comment away the #define, and live with it...
*
*/
#define CHECK_LOST_DE600
/*
* Enable this #define if you want the adapter to do a "ifconfig down" on
* itself when we have detected that something is possibly wrong with it.
* The default behaviour is to retry with "adapter_init()" until success.
* This should be used for debugging purposes only.
* (Depends on the CHECK_LOST_DE600 above)
*
*/
#define SHUTDOWN_WHEN_LOST
/*
* See comment at "de600_rspace()"!
* This is an *ugly* hack, but for now it achieves its goal of
* faking a TCP flow-control that will not flood the poor DE600.
*
* Tricks TCP to announce a small max window (max 2 fast packets please :-)
*
* Comment away at your own risk!
*
* Update: Use the more general per-device maxwindow parameter instead.
*/
#undef FAKE_SMALL_MAX
/* use 0 for production, 1 for verification, >2 for debug */
/* use 0 for production, 1 for verification, >2 for debug */
#ifdef DE600_DEBUG
#ifdef DE600_DEBUG
#define PRINTK(x) if (de600_debug >= 2) printk x
#define PRINTK(x) if (de600_debug >= 2) printk x
...
@@ -88,7 +52,7 @@ static const char version[] =
...
@@ -88,7 +52,7 @@ static const char version[] =
#define DE600_DEBUG 0
#define DE600_DEBUG 0
#define PRINTK(x)
/**/
#define PRINTK(x)
/**/
#endif
#endif
#include <linux/module.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/kernel.h>
...
@@ -110,162 +74,25 @@ static const char version[] =
...
@@ -110,162 +74,25 @@ static const char version[] =
#include <linux/etherdevice.h>
#include <linux/etherdevice.h>
#include <linux/skbuff.h>
#include <linux/skbuff.h>
#include "de600.h"
static
unsigned
int
de600_debug
=
DE600_DEBUG
;
static
unsigned
int
de600_debug
=
DE600_DEBUG
;
MODULE_PARM
(
de600_debug
,
"i"
);
MODULE_PARM
(
de600_debug
,
"i"
);
MODULE_PARM_DESC
(
de600_debug
,
"DE-600 debug level (0-2)"
);
MODULE_PARM_DESC
(
de600_debug
,
"DE-600 debug level (0-2)"
);
static
unsigned
int
check_lost
=
1
;
MODULE_PARM
(
check_lost
,
"i"
);
MODULE_PARM_DESC
(
check_lost
,
"If set then check for unplugged de600"
);
static
unsigned
int
delay_time
=
10
;
static
unsigned
int
delay_time
=
10
;
MODULE_PARM
(
delay_time
,
"i"
);
MODULE_PARM
(
delay_time
,
"i"
);
MODULE_PARM_DESC
(
delay_time
,
"DE-600 deley on I/O in microseconds"
);
MODULE_PARM_DESC
(
delay_time
,
"DE-600 deley on I/O in microseconds"
);
#ifdef FAKE_SMALL_MAX
static
unsigned
long
de600_rspace
(
struct
sock
*
sk
);
#include <net/sock.h>
#endif
typedef
unsigned
char
byte
;
/**************************************************
* *
* Definition of D-Link Ethernet Pocket adapter *
* *
**************************************************/
/*
* D-Link Ethernet pocket adapter ports
*/
/*
* OK, so I'm cheating, but there are an awful lot of
* reads and writes in order to get anything in and out
* of the DE-600 with 4 bits at a time in the parallel port,
* so every saved instruction really helps :-)
*
* That is, I don't care what the device struct says
* but hope that Space.c will keep the rest of the drivers happy.
*/
#ifndef DE600_IO
#define DE600_IO 0x378
#endif
#define DATA_PORT (DE600_IO)
#define STATUS_PORT (DE600_IO + 1)
#define COMMAND_PORT (DE600_IO + 2)
#ifndef DE600_IRQ
#define DE600_IRQ 7
#endif
/*
* It really should look like this, and autoprobing as well...
*
#define DATA_PORT (dev->base_addr + 0)
#define STATUS_PORT (dev->base_addr + 1)
#define COMMAND_PORT (dev->base_addr + 2)
#define DE600_IRQ dev->irq
*/
/*
* D-Link COMMAND_PORT commands
*/
#define SELECT_NIC 0x04
/* select Network Interface Card */
#define SELECT_PRN 0x1c
/* select Printer */
#define NML_PRN 0xec
/* normal Printer situation */
#define IRQEN 0x10
/* enable IRQ line */
/*
* D-Link STATUS_PORT
*/
#define RX_BUSY 0x80
#define RX_GOOD 0x40
#define TX_FAILED16 0x10
#define TX_BUSY 0x08
/*
* D-Link DATA_PORT commands
* command in low 4 bits
* data in high 4 bits
* select current data nibble with HI_NIBBLE bit
*/
#define WRITE_DATA 0x00
/* write memory */
#define READ_DATA 0x01
/* read memory */
#define STATUS 0x02
/* read status register */
#define COMMAND 0x03
/* write command register (see COMMAND below) */
#define NULL_COMMAND 0x04
/* null command */
#define RX_LEN 0x05
/* read received packet length */
#define TX_ADDR 0x06
/* set adapter transmit memory address */
#define RW_ADDR 0x07
/* set adapter read/write memory address */
#define HI_NIBBLE 0x08
/* read/write the high nibble of data,
or-ed with rest of command */
/*
* command register, accessed through DATA_PORT with low bits = COMMAND
*/
#define RX_ALL 0x01
/* PROMISCUOUS */
#define RX_BP 0x02
/* default: BROADCAST & PHYSICAL ADDRESS */
#define RX_MBP 0x03
/* MULTICAST, BROADCAST & PHYSICAL ADDRESS */
#define TX_ENABLE 0x04
/* bit 2 */
#define RX_ENABLE 0x08
/* bit 3 */
#define RESET 0x80
/* set bit 7 high */
#define STOP_RESET 0x00
/* set bit 7 low */
/*
* data to command register
* (high 4 bits in write to DATA_PORT)
*/
#define RX_PAGE2_SELECT 0x10
/* bit 4, only 2 pages to select */
#define RX_BASE_PAGE 0x20
/* bit 5, always set when specifying RX_ADDR */
#define FLIP_IRQ 0x40
/* bit 6 */
/*
* D-Link adapter internal memory:
*
* 0-2K 1:st transmit page (send from pointer up to 2K)
* 2-4K 2:nd transmit page (send from pointer up to 4K)
*
* 4-6K 1:st receive page (data from 4K upwards)
* 6-8K 2:nd receive page (data from 6K upwards)
*
* 8K+ Adapter ROM (contains magic code and last 3 bytes of Ethernet address)
*/
#define MEM_2K 0x0800
/* 2048 */
#define MEM_4K 0x1000
/* 4096 */
#define MEM_6K 0x1800
/* 6144 */
#define NODE_ADDRESS 0x2000
/* 8192 */
#define RUNT 60
/* Too small Ethernet packet */
/**************************************************
* *
* End of definition *
* *
**************************************************/
/*
* Index to functions, as function prototypes.
*/
/* Routines used internally. (See "convenience macros") */
static
byte
de600_read_status
(
struct
net_device
*
dev
);
static
byte
de600_read_byte
(
unsigned
char
type
,
struct
net_device
*
dev
);
/* Put in the device structure. */
static
int
de600_open
(
struct
net_device
*
dev
);
static
int
de600_close
(
struct
net_device
*
dev
);
static
struct
net_device_stats
*
get_stats
(
struct
net_device
*
dev
);
static
int
de600_start_xmit
(
struct
sk_buff
*
skb
,
struct
net_device
*
dev
);
/* Dispatch from interrupts. */
static
void
de600_interrupt
(
int
irq
,
void
*
dev_id
,
struct
pt_regs
*
regs
);
static
int
de600_tx_intr
(
struct
net_device
*
dev
,
int
irq_status
);
static
void
de600_rx_intr
(
struct
net_device
*
dev
);
/* Initialization */
static
void
trigger_interrupt
(
struct
net_device
*
dev
);
int
de600_probe
(
struct
net_device
*
dev
);
static
int
adapter_init
(
struct
net_device
*
dev
);
/*
/*
* D-Link driver variables:
* D-Link driver variables:
*/
*/
static
volatile
int
rx_page
;
static
volatile
int
rx_page
;
#define TX_PAGES 2
#define TX_PAGES 2
...
@@ -274,46 +101,11 @@ static volatile int tx_fifo_in;
...
@@ -274,46 +101,11 @@ static volatile int tx_fifo_in;
static
volatile
int
tx_fifo_out
;
static
volatile
int
tx_fifo_out
;
static
volatile
int
free_tx_pages
=
TX_PAGES
;
static
volatile
int
free_tx_pages
=
TX_PAGES
;
static
int
was_down
;
static
int
was_down
;
static
spinlock_t
de600_lock
;
/*
static
inline
u8
de600_read_status
(
struct
net_device
*
dev
)
* Convenience macros/functions for D-Link adapter
*/
#define select_prn() outb_p(SELECT_PRN, COMMAND_PORT); DE600_SLOW_DOWN
#define select_nic() outb_p(SELECT_NIC, COMMAND_PORT); DE600_SLOW_DOWN
/* Thanks for hints from Mark Burton <markb@ordern.demon.co.uk> */
#define de600_put_byte(data) ( \
outb_p(((data) << 4) | WRITE_DATA , DATA_PORT), \
outb_p(((data) & 0xf0) | WRITE_DATA | HI_NIBBLE, DATA_PORT))
/*
* The first two outb_p()'s below could perhaps be deleted if there
* would be more delay in the last two. Not certain about it yet...
*/
#define de600_put_command(cmd) ( \
outb_p(( rx_page << 4) | COMMAND , DATA_PORT), \
outb_p(( rx_page & 0xf0) | COMMAND | HI_NIBBLE, DATA_PORT), \
outb_p(((rx_page | cmd) << 4) | COMMAND , DATA_PORT), \
outb_p(((rx_page | cmd) & 0xf0) | COMMAND | HI_NIBBLE, DATA_PORT))
#define de600_setup_address(addr,type) ( \
outb_p((((addr) << 4) & 0xf0) | type , DATA_PORT), \
outb_p(( (addr) & 0xf0) | type | HI_NIBBLE, DATA_PORT), \
outb_p((((addr) >> 4) & 0xf0) | type , DATA_PORT), \
outb_p((((addr) >> 8) & 0xf0) | type | HI_NIBBLE, DATA_PORT))
#define rx_page_adr() ((rx_page & RX_PAGE2_SELECT)?(MEM_6K):(MEM_4K))
/* Flip bit, only 2 pages */
#define next_rx_page() (rx_page ^= RX_PAGE2_SELECT)
#define tx_page_adr(a) (((a) + 1) * MEM_2K)
static
inline
byte
de600_read_status
(
struct
net_device
*
dev
)
{
{
byte
status
;
u8
status
;
outb_p
(
STATUS
,
DATA_PORT
);
outb_p
(
STATUS
,
DATA_PORT
);
status
=
inb
(
STATUS_PORT
);
status
=
inb
(
STATUS_PORT
);
...
@@ -322,16 +114,16 @@ de600_read_status(struct net_device *dev)
...
@@ -322,16 +114,16 @@ de600_read_status(struct net_device *dev)
return
status
;
return
status
;
}
}
static
inline
byte
static
inline
u8
de600_read_byte
(
unsigned
char
type
,
struct
net_device
*
dev
)
de600_read_byte
(
unsigned
char
type
,
struct
net_device
*
dev
)
{
/* dev used by macros */
{
byte
lo
;
/* dev used by macros */
u8
lo
;
(
void
)
outb_p
((
type
),
DATA_PORT
);
outb_p
((
type
),
DATA_PORT
);
lo
=
((
unsigned
char
)
inb
(
STATUS_PORT
))
>>
4
;
lo
=
((
unsigned
char
)
inb
(
STATUS_PORT
))
>>
4
;
(
void
)
outb_p
((
type
)
|
HI_NIBBLE
,
DATA_PORT
);
outb_p
((
type
)
|
HI_NIBBLE
,
DATA_PORT
);
return
((
unsigned
char
)
inb
(
STATUS_PORT
)
&
(
unsigned
char
)
0xf0
)
|
lo
;
return
((
unsigned
char
)
inb
(
STATUS_PORT
)
&
(
unsigned
char
)
0xf0
)
|
lo
;
}
}
/*
/*
* Open/initialize the board. This is called (in the current kernel)
* Open/initialize the board. This is called (in the current kernel)
* after booting when 'ifconfig <dev->name> $IP_ADDR' is run (in rc.inet1).
* after booting when 'ifconfig <dev->name> $IP_ADDR' is run (in rc.inet1).
...
@@ -340,26 +132,26 @@ de600_read_byte(unsigned char type, struct net_device *dev) { /* dev used by mac
...
@@ -340,26 +132,26 @@ de600_read_byte(unsigned char type, struct net_device *dev) { /* dev used by mac
* registers that "should" only need to be set once at boot, so that
* registers that "should" only need to be set once at boot, so that
* there is a non-reboot way to recover if something goes wrong.
* there is a non-reboot way to recover if something goes wrong.
*/
*/
static
int
de600_open
(
struct
net_device
*
dev
)
static
int
de600_open
(
struct
net_device
*
dev
)
{
{
unsigned
long
flags
;
int
ret
=
request_irq
(
DE600_IRQ
,
de600_interrupt
,
0
,
dev
->
name
,
dev
);
int
ret
=
request_irq
(
DE600_IRQ
,
de600_interrupt
,
0
,
dev
->
name
,
dev
);
if
(
ret
)
{
if
(
ret
)
{
printk
(
"%s: unable to get IRQ %d
\n
"
,
dev
->
name
,
DE600_IRQ
);
printk
(
KERN_ERR
"%s: unable to get IRQ %d
\n
"
,
dev
->
name
,
DE600_IRQ
);
return
ret
;
return
ret
;
}
}
spin_lock_irqsave
(
&
de600_lock
,
flags
);
if
(
adapter_init
(
dev
))
ret
=
adapter_init
(
dev
);
return
-
EIO
;
spin_unlock_irqrestore
(
&
de600_lock
,
flags
);
return
ret
;
return
0
;
}
}
/*
/*
* The inverse routine to de600_open().
* The inverse routine to de600_open().
*/
*/
static
int
de600_close
(
struct
net_device
*
dev
)
static
int
de600_close
(
struct
net_device
*
dev
)
{
{
select_nic
();
select_nic
();
rx_page
=
0
;
rx_page
=
0
;
...
@@ -367,21 +159,16 @@ de600_close(struct net_device *dev)
...
@@ -367,21 +159,16 @@ de600_close(struct net_device *dev)
de600_put_command
(
STOP_RESET
);
de600_put_command
(
STOP_RESET
);
de600_put_command
(
0
);
de600_put_command
(
0
);
select_prn
();
select_prn
();
free_irq
(
DE600_IRQ
,
dev
);
if
(
netif_running
(
dev
))
{
/* perhaps not needed? */
free_irq
(
DE600_IRQ
,
dev
);
}
return
0
;
return
0
;
}
}
static
struct
net_device_stats
*
static
struct
net_device_stats
*
get_stats
(
struct
net_device
*
dev
)
get_stats
(
struct
net_device
*
dev
)
{
{
return
(
struct
net_device_stats
*
)(
dev
->
priv
);
return
(
struct
net_device_stats
*
)(
dev
->
priv
);
}
}
static
inline
void
static
inline
void
trigger_interrupt
(
struct
net_device
*
dev
)
trigger_interrupt
(
struct
net_device
*
dev
)
{
{
de600_put_command
(
FLIP_IRQ
);
de600_put_command
(
FLIP_IRQ
);
select_prn
();
select_prn
();
...
@@ -394,31 +181,28 @@ trigger_interrupt(struct net_device *dev)
...
@@ -394,31 +181,28 @@ trigger_interrupt(struct net_device *dev)
* Copy a buffer to the adapter transmit page memory.
* Copy a buffer to the adapter transmit page memory.
* Start sending.
* Start sending.
*/
*/
static
int
de600_start_xmit
(
struct
sk_buff
*
skb
,
struct
net_device
*
dev
)
static
int
de600_start_xmit
(
struct
sk_buff
*
skb
,
struct
net_device
*
dev
)
{
{
unsigned
long
flags
;
unsigned
long
flags
;
int
transmit_from
;
int
transmit_from
;
int
len
;
int
len
;
int
tickssofar
;
int
tickssofar
;
byte
*
buffer
=
skb
->
data
;
u8
*
buffer
=
skb
->
data
;
if
(
free_tx_pages
<=
0
)
{
/* Do timeouts, to avoid hangs. */
if
(
free_tx_pages
<=
0
)
{
/* Do timeouts, to avoid hangs. */
tickssofar
=
jiffies
-
dev
->
trans_start
;
tickssofar
=
jiffies
-
dev
->
trans_start
;
if
(
tickssofar
<
5
)
if
(
tickssofar
<
5
)
return
1
;
return
1
;
/* else */
/* else */
printk
(
"%s: transmit timed out (%d), %s?
\n
"
,
printk
(
KERN_WARNING
"%s: transmit timed out (%d), %s?
\n
"
,
dev
->
name
,
tickssofar
,
"network cable problem"
);
dev
->
name
,
tickssofar
,
"network cable problem"
);
/* Restart the adapter. */
/* Restart the adapter. */
spin_lock_irqsave
(
&
de600_lock
,
flags
);
if
(
adapter_init
(
dev
))
{
if
(
adapter_init
(
dev
))
{
spin_unlock_irqrestore
(
&
de600_lock
,
flags
);
return
1
;
return
1
;
}
}
spin_unlock_irqrestore
(
&
de600_lock
,
flags
);
}
}
/* Start real output */
/* Start real output */
...
@@ -427,23 +211,23 @@ de600_start_xmit(struct sk_buff *skb, struct net_device *dev)
...
@@ -427,23 +211,23 @@ de600_start_xmit(struct sk_buff *skb, struct net_device *dev)
if
((
len
=
skb
->
len
)
<
RUNT
)
if
((
len
=
skb
->
len
)
<
RUNT
)
len
=
RUNT
;
len
=
RUNT
;
save_flags
(
flags
);
spin_lock_irqsave
(
&
de600_lock
,
flags
);
cli
();
select_nic
();
select_nic
();
tx_fifo
[
tx_fifo_in
]
=
transmit_from
=
tx_page_adr
(
tx_fifo_in
)
-
len
;
tx_fifo
[
tx_fifo_in
]
=
transmit_from
=
tx_page_adr
(
tx_fifo_in
)
-
len
;
tx_fifo_in
=
(
tx_fifo_in
+
1
)
%
TX_PAGES
;
/* Next free tx page */
tx_fifo_in
=
(
tx_fifo_in
+
1
)
%
TX_PAGES
;
/* Next free tx page */
#ifdef CHECK_LOST_DE600
if
(
check_lost
)
/* This costs about 40 instructions per packet... */
{
de600_setup_address
(
NODE_ADDRESS
,
RW_ADDR
);
/* This costs about 40 instructions per packet... */
de600_read_byte
(
READ_DATA
,
dev
);
de600_setup_address
(
NODE_ADDRESS
,
RW_ADDR
);
if
(
was_down
||
(
de600_read_byte
(
READ_DATA
,
dev
)
!=
0xde
))
{
de600_read_byte
(
READ_DATA
,
dev
);
if
(
adapter_init
(
dev
))
{
if
(
was_down
||
(
de600_read_byte
(
READ_DATA
,
dev
)
!=
0xde
))
{
restore_flags
(
flags
);
if
(
adapter_init
(
dev
))
{
return
1
;
spin_unlock_irqrestore
(
&
de600_lock
,
flags
);
return
1
;
}
}
}
}
}
#endif
de600_setup_address
(
transmit_from
,
RW_ADDR
);
de600_setup_address
(
transmit_from
,
RW_ADDR
);
for
(
;
len
>
0
;
--
len
,
++
buffer
)
for
(
;
len
>
0
;
--
len
,
++
buffer
)
...
@@ -463,39 +247,31 @@ de600_start_xmit(struct sk_buff *skb, struct net_device *dev)
...
@@ -463,39 +247,31 @@ de600_start_xmit(struct sk_buff *skb, struct net_device *dev)
netif_stop_queue
(
dev
);
netif_stop_queue
(
dev
);
select_prn
();
select_prn
();
}
}
spin_unlock_irqrestore
(
&
de600_lock
,
flags
);
restore_flags
(
flags
);
dev_kfree_skb
(
skb
);
#ifdef FAKE_SMALL_MAX
/* This will "patch" the socket TCP proto at an early moment */
if
(
skb
->
sk
&&
(
skb
->
sk
->
protocol
==
IPPROTO_TCP
)
&&
(
skb
->
sk
->
prot
->
rspace
!=
&
de600_rspace
))
skb
->
sk
->
prot
->
rspace
=
de600_rspace
;
/* Ugh! */
#endif
dev_kfree_skb
(
skb
);
return
0
;
return
0
;
}
}
/*
/*
* The typical workload of the driver:
* The typical workload of the driver:
* Handle the network interface interrupts.
* Handle the network interface interrupts.
*/
*/
static
void
de600_interrupt
(
int
irq
,
void
*
dev_id
,
struct
pt_regs
*
regs
)
static
void
de600_interrupt
(
int
irq
,
void
*
dev_id
,
struct
pt_regs
*
regs
)
{
{
struct
net_device
*
dev
=
dev_id
;
struct
net_device
*
dev
=
dev_id
;
byte
irq_status
;
u8
irq_status
;
int
retrig
=
0
;
int
retrig
=
0
;
int
boguscount
=
0
;
int
boguscount
=
0
;
/* This might just as well be deleted now, no crummy drivers present :-) */
/* This might just as well be deleted now, no crummy drivers present :-) */
if
((
dev
==
NULL
)
||
(
DE600_IRQ
!=
irq
))
{
if
((
dev
==
NULL
)
||
(
DE600_IRQ
!=
irq
))
{
printk
(
"%s: bogus interrupt %d
\n
"
,
dev
?
dev
->
name
:
"DE-600"
,
irq
);
printk
(
KERN_ERR
"%s: bogus interrupt %d
\n
"
,
dev
?
dev
->
name
:
"DE-600"
,
irq
);
return
;
return
;
}
}
spin_lock
(
&
de600_lock
);
select_nic
();
select_nic
();
irq_status
=
de600_read_status
(
dev
);
irq_status
=
de600_read_status
(
dev
);
...
@@ -523,15 +299,13 @@ de600_interrupt(int irq, void *dev_id, struct pt_regs * regs)
...
@@ -523,15 +299,13 @@ de600_interrupt(int irq, void *dev_id, struct pt_regs * regs)
/* Enable adapter interrupts */
/* Enable adapter interrupts */
select_prn
();
select_prn
();
if
(
retrig
)
if
(
retrig
)
trigger_interrupt
(
dev
);
trigger_interrupt
(
dev
);
spin_unlock
(
&
de600_lock
);
return
;
return
;
}
}
static
int
static
int
de600_tx_intr
(
struct
net_device
*
dev
,
int
irq_status
)
de600_tx_intr
(
struct
net_device
*
dev
,
int
irq_status
)
{
{
/*
/*
* Returns 1 if tx still not done
* Returns 1 if tx still not done
...
@@ -565,18 +339,13 @@ de600_tx_intr(struct net_device *dev, int irq_status)
...
@@ -565,18 +339,13 @@ de600_tx_intr(struct net_device *dev, int irq_status)
/*
/*
* We have a good packet, get it out of the adapter.
* We have a good packet, get it out of the adapter.
*/
*/
static
void
static
void
de600_rx_intr
(
struct
net_device
*
dev
)
de600_rx_intr
(
struct
net_device
*
dev
)
{
{
struct
sk_buff
*
skb
;
struct
sk_buff
*
skb
;
unsigned
long
flags
;
int
i
;
int
i
;
int
read_from
;
int
read_from
;
int
size
;
int
size
;
register
unsigned
char
*
buffer
;
unsigned
char
*
buffer
;
save_flags
(
flags
);
cli
();
/* Get size of received packet */
/* Get size of received packet */
size
=
de600_read_byte
(
RX_LEN
,
dev
);
/* low byte */
size
=
de600_read_byte
(
RX_LEN
,
dev
);
/* low byte */
...
@@ -588,10 +357,8 @@ de600_rx_intr(struct net_device *dev)
...
@@ -588,10 +357,8 @@ de600_rx_intr(struct net_device *dev)
next_rx_page
();
next_rx_page
();
de600_put_command
(
RX_ENABLE
);
de600_put_command
(
RX_ENABLE
);
restore_flags
(
flags
);
if
((
size
<
32
)
||
(
size
>
1535
))
{
if
((
size
<
32
)
||
(
size
>
1535
))
{
printk
(
"%s: Bogus packet size %d.
\n
"
,
dev
->
name
,
size
);
printk
(
KERN_WARNING
"%s: Bogus packet size %d.
\n
"
,
dev
->
name
,
size
);
if
(
size
>
10000
)
if
(
size
>
10000
)
adapter_init
(
dev
);
adapter_init
(
dev
);
return
;
return
;
...
@@ -599,8 +366,7 @@ de600_rx_intr(struct net_device *dev)
...
@@ -599,8 +366,7 @@ de600_rx_intr(struct net_device *dev)
skb
=
dev_alloc_skb
(
size
+
2
);
skb
=
dev_alloc_skb
(
size
+
2
);
if
(
skb
==
NULL
)
{
if
(
skb
==
NULL
)
{
printk
(
"%s: Couldn't allocate a sk_buff of size %d.
\n
"
,
printk
(
"%s: Couldn't allocate a sk_buff of size %d.
\n
"
,
dev
->
name
,
size
);
dev
->
name
,
size
);
return
;
return
;
}
}
/* else */
/* else */
...
@@ -627,13 +393,11 @@ de600_rx_intr(struct net_device *dev)
...
@@ -627,13 +393,11 @@ de600_rx_intr(struct net_device *dev)
/*
/*
* If any worth-while packets have been received, netif_rx()
* If any worth-while packets have been received, netif_rx()
* has done a mark_bh(INET_BH) for us and will work on them
* will work on them when we get to the tasklets.
* when we get to the bottom-half routine.
*/
*/
}
}
int
__init
int
__init
de600_probe
(
struct
net_device
*
dev
)
de600_probe
(
struct
net_device
*
dev
)
{
{
int
i
;
int
i
;
static
struct
net_device_stats
de600_netstats
;
static
struct
net_device_stats
de600_netstats
;
...
@@ -641,7 +405,7 @@ de600_probe(struct net_device *dev)
...
@@ -641,7 +405,7 @@ de600_probe(struct net_device *dev)
SET_MODULE_OWNER
(
dev
);
SET_MODULE_OWNER
(
dev
);
printk
(
"%s: D-Link DE-600 pocket adapter"
,
dev
->
name
);
printk
(
KERN_INFO
"%s: D-Link DE-600 pocket adapter"
,
dev
->
name
);
/* Alpha testers must have the version number to report bugs. */
/* Alpha testers must have the version number to report bugs. */
if
(
de600_debug
>
1
)
if
(
de600_debug
>
1
)
printk
(
version
);
printk
(
version
);
...
@@ -682,12 +446,6 @@ de600_probe(struct net_device *dev)
...
@@ -682,12 +446,6 @@ de600_probe(struct net_device *dev)
return
-
ENODEV
;
return
-
ENODEV
;
}
}
#if 0 /* Not yet */
if (check_region(DE600_IO, 3)) {
printk(", port 0x%x busy\n", DE600_IO);
return -EBUSY;
}
#endif
request_region
(
DE600_IO
,
3
,
"de600"
);
request_region
(
DE600_IO
,
3
,
"de600"
);
printk
(
", Ethernet Address: %02X"
,
dev
->
dev_addr
[
0
]);
printk
(
", Ethernet Address: %02X"
,
dev
->
dev_addr
[
0
]);
...
@@ -713,20 +471,15 @@ de600_probe(struct net_device *dev)
...
@@ -713,20 +471,15 @@ de600_probe(struct net_device *dev)
return
0
;
return
0
;
}
}
static
int
static
int
adapter_init
(
struct
net_device
*
dev
)
adapter_init
(
struct
net_device
*
dev
)
{
{
int
i
;
int
i
;
unsigned
long
flags
;
save_flags
(
flags
);
cli
();
select_nic
();
select_nic
();
rx_page
=
0
;
/* used by RESET */
rx_page
=
0
;
/* used by RESET */
de600_put_command
(
RESET
);
de600_put_command
(
RESET
);
de600_put_command
(
STOP_RESET
);
de600_put_command
(
STOP_RESET
);
#ifdef CHECK_LOST_DE600
/* Check if it is still there... */
/* Check if it is still there... */
/* Get the some bytes of the adapter ethernet address from the ROM */
/* Get the some bytes of the adapter ethernet address from the ROM */
de600_setup_address
(
NODE_ADDRESS
,
RW_ADDR
);
de600_setup_address
(
NODE_ADDRESS
,
RW_ADDR
);
...
@@ -734,32 +487,25 @@ adapter_init(struct net_device *dev)
...
@@ -734,32 +487,25 @@ adapter_init(struct net_device *dev)
if
((
de600_read_byte
(
READ_DATA
,
dev
)
!=
0xde
)
||
if
((
de600_read_byte
(
READ_DATA
,
dev
)
!=
0xde
)
||
(
de600_read_byte
(
READ_DATA
,
dev
)
!=
0x15
))
{
(
de600_read_byte
(
READ_DATA
,
dev
)
!=
0x15
))
{
/* was: if (de600_read_status(dev) & 0xf0) { */
/* was: if (de600_read_status(dev) & 0xf0) { */
printk
(
"Something has happened to the DE-600! Please check it"
printk
(
"Something has happened to the DE-600! Please check it and do a new ifconfig!
\n
"
);
#ifdef SHUTDOWN_WHEN_LOST
" and do a new ifconfig"
#endif
/* SHUTDOWN_WHEN_LOST */
"!
\n
"
);
#ifdef SHUTDOWN_WHEN_LOST
/* Goodbye, cruel world... */
/* Goodbye, cruel world... */
dev
->
flags
&=
~
IFF_UP
;
dev
->
flags
&=
~
IFF_UP
;
de600_close
(
dev
);
de600_close
(
dev
);
#endif
/* SHUTDOWN_WHEN_LOST */
was_down
=
1
;
was_down
=
1
;
netif_stop_queue
(
dev
);
/* Transmit busy... */
netif_stop_queue
(
dev
);
/* Transmit busy... */
restore_flags
(
flags
);
return
1
;
/* failed */
return
1
;
/* failed */
}
}
#endif
/* CHECK_LOST_DE600 */
if
(
was_down
)
{
if
(
was_down
)
{
printk
(
"Thanks, I feel much better now!
\n
"
);
printk
(
KERN_INFO
"%s: Thanks, I feel much better now!
\n
"
,
dev
->
name
);
was_down
=
0
;
was_down
=
0
;
}
}
netif_start_queue
(
dev
);
tx_fifo_in
=
0
;
tx_fifo_in
=
0
;
tx_fifo_out
=
0
;
tx_fifo_out
=
0
;
free_tx_pages
=
TX_PAGES
;
free_tx_pages
=
TX_PAGES
;
/* set the ether address. */
/* set the ether address. */
de600_setup_address
(
NODE_ADDRESS
,
RW_ADDR
);
de600_setup_address
(
NODE_ADDRESS
,
RW_ADDR
);
for
(
i
=
0
;
i
<
ETH_ALEN
;
i
++
)
for
(
i
=
0
;
i
<
ETH_ALEN
;
i
++
)
...
@@ -771,82 +517,30 @@ adapter_init(struct net_device *dev)
...
@@ -771,82 +517,30 @@ adapter_init(struct net_device *dev)
/* Enable receiver */
/* Enable receiver */
de600_put_command
(
RX_ENABLE
);
de600_put_command
(
RX_ENABLE
);
select_prn
();
select_prn
();
restore_flags
(
flags
);
netif_start_queue
(
dev
);
return
0
;
/* OK */
return
0
;
/* OK */
}
}
#ifdef FAKE_SMALL_MAX
/*
* The new router code (coming soon 8-) ) will fix this properly.
*/
#define DE600_MIN_WINDOW 1024
#define DE600_MAX_WINDOW 2048
#define DE600_TCP_WINDOW_DIFF 1024
/*
* Copied from "net/inet/sock.c"
*
* Sets a lower max receive window in order to achieve <= 2
* packets arriving at the adapter in fast succession.
* (No way that a DE-600 can keep up with a net saturated
* with packets homing in on it :-( )
*
* Since there are only 2 receive buffers in the DE-600
* and it takes some time to copy from the adapter,
* this is absolutely necessary for any TCP performance whatsoever!
*
* Note that the returned window info will never be smaller than
* DE600_MIN_WINDOW, i.e. 1024
* This differs from the standard function, that can return an
* arbitrarily small window!
*/
static
unsigned
long
de600_rspace
(
struct
sock
*
sk
)
{
int
amt
;
if
(
sk
!=
NULL
)
{
/*
* Hack! You might want to play with commenting away the following line,
* if you know what you do!
sk->max_unacked = DE600_MAX_WINDOW - DE600_TCP_WINDOW_DIFF;
*/
if
(
atomic_read
(
&
sk
->
rmem_alloc
)
>=
sk
->
rcvbuf
-
2
*
DE600_MIN_WINDOW
)
return
(
0
);
amt
=
min_t
(
int
,
(
sk
->
rcvbuf
-
atomic_read
(
&
sk
->
rmem_alloc
))
/
2
/*-DE600_MIN_WINDOW*/
,
DE600_MAX_WINDOW
);
if
(
amt
<
0
)
return
(
0
);
return
(
amt
);
}
return
(
0
);
}
#endif
#ifdef MODULE
static
struct
net_device
de600_dev
;
static
struct
net_device
de600_dev
;
int
static
int
__init
de600_init
(
void
)
init_module
(
void
)
{
{
spin_lock_init
(
&
de600_lock
);
de600_dev
.
init
=
de600_probe
;
de600_dev
.
init
=
de600_probe
;
if
(
register_netdev
(
&
de600_dev
)
!=
0
)
if
(
register_netdev
(
&
de600_dev
)
!=
0
)
return
-
EIO
;
return
-
EIO
;
return
0
;
return
0
;
}
}
void
static
void
__exit
de600_exit
(
void
)
cleanup_module
(
void
)
{
{
unregister_netdev
(
&
de600_dev
);
unregister_netdev
(
&
de600_dev
);
release_region
(
DE600_IO
,
3
);
release_region
(
DE600_IO
,
3
);
}
}
#endif
/* MODULE */
MODULE_LICENSE
(
"GPL"
);
module_init
(
de600_init
);
module_exit
(
de600_exit
);
/*
MODULE_LICENSE
(
"GPL"
);
* Local variables:
* kernel-compile-command: "gcc -D__KERNEL__ -Ilinux/include -I../../net/inet -Wall -Wstrict-prototypes -O2 -m486 -c de600.c"
* module-compile-command: "gcc -D__KERNEL__ -DMODULE -Ilinux/include -I../../net/inet -Wall -Wstrict-prototypes -O2 -m486 -c de600.c"
* compile-command: "gcc -D__KERNEL__ -DMODULE -Ilinux/include -I../../net/inet -Wall -Wstrict-prototypes -O2 -m486 -c de600.c"
* End:
*/
drivers/net/de600.h
0 → 100644
View file @
5cc31d9b
/**************************************************
* *
* Definition of D-Link Ethernet Pocket adapter *
* *
**************************************************/
/*
* D-Link Ethernet pocket adapter ports
*/
/*
* OK, so I'm cheating, but there are an awful lot of
* reads and writes in order to get anything in and out
* of the DE-600 with 4 bits at a time in the parallel port,
* so every saved instruction really helps :-)
*/
#ifndef DE600_IO
#define DE600_IO 0x378
#endif
#define DATA_PORT (DE600_IO)
#define STATUS_PORT (DE600_IO + 1)
#define COMMAND_PORT (DE600_IO + 2)
#ifndef DE600_IRQ
#define DE600_IRQ 7
#endif
/*
* It really should look like this, and autoprobing as well...
*
#define DATA_PORT (dev->base_addr + 0)
#define STATUS_PORT (dev->base_addr + 1)
#define COMMAND_PORT (dev->base_addr + 2)
#define DE600_IRQ dev->irq
*/
/*
* D-Link COMMAND_PORT commands
*/
#define SELECT_NIC 0x04
/* select Network Interface Card */
#define SELECT_PRN 0x1c
/* select Printer */
#define NML_PRN 0xec
/* normal Printer situation */
#define IRQEN 0x10
/* enable IRQ line */
/*
* D-Link STATUS_PORT
*/
#define RX_BUSY 0x80
#define RX_GOOD 0x40
#define TX_FAILED16 0x10
#define TX_BUSY 0x08
/*
* D-Link DATA_PORT commands
* command in low 4 bits
* data in high 4 bits
* select current data nibble with HI_NIBBLE bit
*/
#define WRITE_DATA 0x00
/* write memory */
#define READ_DATA 0x01
/* read memory */
#define STATUS 0x02
/* read status register */
#define COMMAND 0x03
/* write command register (see COMMAND below) */
#define NULL_COMMAND 0x04
/* null command */
#define RX_LEN 0x05
/* read received packet length */
#define TX_ADDR 0x06
/* set adapter transmit memory address */
#define RW_ADDR 0x07
/* set adapter read/write memory address */
#define HI_NIBBLE 0x08
/* read/write the high nibble of data,
or-ed with rest of command */
/*
* command register, accessed through DATA_PORT with low bits = COMMAND
*/
#define RX_ALL 0x01
/* PROMISCUOUS */
#define RX_BP 0x02
/* default: BROADCAST & PHYSICAL ADDRESS */
#define RX_MBP 0x03
/* MULTICAST, BROADCAST & PHYSICAL ADDRESS */
#define TX_ENABLE 0x04
/* bit 2 */
#define RX_ENABLE 0x08
/* bit 3 */
#define RESET 0x80
/* set bit 7 high */
#define STOP_RESET 0x00
/* set bit 7 low */
/*
* data to command register
* (high 4 bits in write to DATA_PORT)
*/
#define RX_PAGE2_SELECT 0x10
/* bit 4, only 2 pages to select */
#define RX_BASE_PAGE 0x20
/* bit 5, always set when specifying RX_ADDR */
#define FLIP_IRQ 0x40
/* bit 6 */
/*
* D-Link adapter internal memory:
*
* 0-2K 1:st transmit page (send from pointer up to 2K)
* 2-4K 2:nd transmit page (send from pointer up to 4K)
*
* 4-6K 1:st receive page (data from 4K upwards)
* 6-8K 2:nd receive page (data from 6K upwards)
*
* 8K+ Adapter ROM (contains magic code and last 3 bytes of Ethernet address)
*/
#define MEM_2K 0x0800
/* 2048 */
#define MEM_4K 0x1000
/* 4096 */
#define MEM_6K 0x1800
/* 6144 */
#define NODE_ADDRESS 0x2000
/* 8192 */
#define RUNT 60
/* Too small Ethernet packet */
/**************************************************
* *
* End of definition *
* *
**************************************************/
/*
* Index to functions, as function prototypes.
*/
/* Routines used internally. (See "convenience macros") */
static
u8
de600_read_status
(
struct
net_device
*
dev
);
static
u8
de600_read_byte
(
unsigned
char
type
,
struct
net_device
*
dev
);
/* Put in the device structure. */
static
int
de600_open
(
struct
net_device
*
dev
);
static
int
de600_close
(
struct
net_device
*
dev
);
static
struct
net_device_stats
*
get_stats
(
struct
net_device
*
dev
);
static
int
de600_start_xmit
(
struct
sk_buff
*
skb
,
struct
net_device
*
dev
);
/* Dispatch from interrupts. */
static
void
de600_interrupt
(
int
irq
,
void
*
dev_id
,
struct
pt_regs
*
regs
);
static
int
de600_tx_intr
(
struct
net_device
*
dev
,
int
irq_status
);
static
void
de600_rx_intr
(
struct
net_device
*
dev
);
/* Initialization */
static
void
trigger_interrupt
(
struct
net_device
*
dev
);
int
de600_probe
(
struct
net_device
*
dev
);
static
int
adapter_init
(
struct
net_device
*
dev
);
/*
* Convenience macros/functions for D-Link adapter
*/
#define select_prn() outb_p(SELECT_PRN, COMMAND_PORT); DE600_SLOW_DOWN
#define select_nic() outb_p(SELECT_NIC, COMMAND_PORT); DE600_SLOW_DOWN
/* Thanks for hints from Mark Burton <markb@ordern.demon.co.uk> */
#define de600_put_byte(data) ( \
outb_p(((data) << 4) | WRITE_DATA , DATA_PORT), \
outb_p(((data) & 0xf0) | WRITE_DATA | HI_NIBBLE, DATA_PORT))
/*
* The first two outb_p()'s below could perhaps be deleted if there
* would be more delay in the last two. Not certain about it yet...
*/
#define de600_put_command(cmd) ( \
outb_p(( rx_page << 4) | COMMAND , DATA_PORT), \
outb_p(( rx_page & 0xf0) | COMMAND | HI_NIBBLE, DATA_PORT), \
outb_p(((rx_page | cmd) << 4) | COMMAND , DATA_PORT), \
outb_p(((rx_page | cmd) & 0xf0) | COMMAND | HI_NIBBLE, DATA_PORT))
#define de600_setup_address(addr,type) ( \
outb_p((((addr) << 4) & 0xf0) | type , DATA_PORT), \
outb_p(( (addr) & 0xf0) | type | HI_NIBBLE, DATA_PORT), \
outb_p((((addr) >> 4) & 0xf0) | type , DATA_PORT), \
outb_p((((addr) >> 8) & 0xf0) | type | HI_NIBBLE, DATA_PORT))
#define rx_page_adr() ((rx_page & RX_PAGE2_SELECT)?(MEM_6K):(MEM_4K))
/* Flip bit, only 2 pages */
#define next_rx_page() (rx_page ^= RX_PAGE2_SELECT)
#define tx_page_adr(a) (((a) + 1) * MEM_2K)
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