Commit 42c9bdae authored by David S. Miller's avatar David S. Miller

Merge branch 'Fixes-for-SONIC-ethernet-driver'

Finn Thain says:

====================
Fixes for SONIC ethernet driver

Various SONIC driver problems have become apparent over the years,
including tx watchdog timeouts, lost packets and duplicated packets.

The problems are mostly caused by bugs in buffer handling, locking and
(re-)initialization code.

This patch series resolves these problems.

This series has been tested on National Semiconductor hardware (macsonic),
qemu-system-m68k (macsonic) and qemu-system-mips64el (jazzsonic).

The emulated dp8393x device used in QEMU also has bugs.
I have fixed the bugs that I know of in a series of patches at,
https://github.com/fthain/qemu/commits/sonic

Changed since v1:
 - Minor revisions as described in commit logs.
 - Deferred net-next patches.
Changed since v2:
 - Minor revisions as described in commit logs.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 457bfc0a 686f85d7
This diff is collapsed.
......@@ -110,6 +110,9 @@
#define SONIC_CR_TXP 0x0002
#define SONIC_CR_HTX 0x0001
#define SONIC_CR_ALL (SONIC_CR_LCAM | SONIC_CR_RRRA | \
SONIC_CR_RXEN | SONIC_CR_TXP)
/*
* SONIC data configuration bits
*/
......@@ -175,6 +178,7 @@
#define SONIC_TCR_NCRS 0x0100
#define SONIC_TCR_CRLS 0x0080
#define SONIC_TCR_EXC 0x0040
#define SONIC_TCR_OWC 0x0020
#define SONIC_TCR_PMB 0x0008
#define SONIC_TCR_FU 0x0004
#define SONIC_TCR_BCM 0x0002
......@@ -274,8 +278,9 @@
#define SONIC_NUM_RDS SONIC_NUM_RRS /* number of receive descriptors */
#define SONIC_NUM_TDS 16 /* number of transmit descriptors */
#define SONIC_RDS_MASK (SONIC_NUM_RDS-1)
#define SONIC_TDS_MASK (SONIC_NUM_TDS-1)
#define SONIC_RRS_MASK (SONIC_NUM_RRS - 1)
#define SONIC_RDS_MASK (SONIC_NUM_RDS - 1)
#define SONIC_TDS_MASK (SONIC_NUM_TDS - 1)
#define SONIC_RBSIZE 1520 /* size of one resource buffer */
......@@ -312,8 +317,6 @@ struct sonic_local {
u32 rda_laddr; /* logical DMA address of RDA */
dma_addr_t rx_laddr[SONIC_NUM_RRS]; /* logical DMA addresses of rx skbuffs */
dma_addr_t tx_laddr[SONIC_NUM_TDS]; /* logical DMA addresses of tx skbuffs */
unsigned int rra_end;
unsigned int cur_rwp;
unsigned int cur_rx;
unsigned int cur_tx; /* first unacked transmit packet */
unsigned int eol_rx;
......@@ -322,6 +325,7 @@ struct sonic_local {
int msg_enable;
struct device *device; /* generic device */
struct net_device_stats stats;
spinlock_t lock;
};
#define TX_TIMEOUT (3 * HZ)
......@@ -344,30 +348,30 @@ static void sonic_msg_init(struct net_device *dev);
as far as we can tell. */
/* OpenBSD calls this "SWO". I'd like to think that sonic_buf_put()
is a much better name. */
static inline void sonic_buf_put(void* base, int bitmode,
static inline void sonic_buf_put(u16 *base, int bitmode,
int offset, __u16 val)
{
if (bitmode)
#ifdef __BIG_ENDIAN
((__u16 *) base + (offset*2))[1] = val;
__raw_writew(val, base + (offset * 2) + 1);
#else
((__u16 *) base + (offset*2))[0] = val;
__raw_writew(val, base + (offset * 2) + 0);
#endif
else
((__u16 *) base)[offset] = val;
__raw_writew(val, base + (offset * 1) + 0);
}
static inline __u16 sonic_buf_get(void* base, int bitmode,
static inline __u16 sonic_buf_get(u16 *base, int bitmode,
int offset)
{
if (bitmode)
#ifdef __BIG_ENDIAN
return ((volatile __u16 *) base + (offset*2))[1];
return __raw_readw(base + (offset * 2) + 1);
#else
return ((volatile __u16 *) base + (offset*2))[0];
return __raw_readw(base + (offset * 2) + 0);
#endif
else
return ((volatile __u16 *) base)[offset];
return __raw_readw(base + (offset * 1) + 0);
}
/* Inlines that you should actually use for reading/writing DMA buffers */
......@@ -447,6 +451,22 @@ static inline __u16 sonic_rra_get(struct net_device* dev, int entry,
(entry * SIZEOF_SONIC_RR) + offset);
}
static inline u16 sonic_rr_addr(struct net_device *dev, int entry)
{
struct sonic_local *lp = netdev_priv(dev);
return lp->rra_laddr +
entry * SIZEOF_SONIC_RR * SONIC_BUS_SCALE(lp->dma_bitmode);
}
static inline u16 sonic_rr_entry(struct net_device *dev, u16 addr)
{
struct sonic_local *lp = netdev_priv(dev);
return (addr - (u16)lp->rra_laddr) / (SIZEOF_SONIC_RR *
SONIC_BUS_SCALE(lp->dma_bitmode));
}
static const char version[] =
"sonic.c:v0.92 20.9.98 tsbogend@alpha.franken.de\n";
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment