Update of /cvsroot/blob/blob/src/lib
In directory sc8-pr-cvs1:/tmp/cvs-serv1524
Modified Files:
ether-s3c2500.c
Log Message:
fix halts in s3c2500 ether driver
Index: ether-s3c2500.c
===================================================================
RCS file: /cvsroot/blob/blob/src/lib/ether-s3c2500.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- ether-s3c2500.c 5 Sep 2003 01:09:45 -0000 1.2
+++ ether-s3c2500.c 27 Nov 2003 03:30:50 -0000 1.3
@@ -1,3 +1,4 @@
+
/*
* ether-s3c2500.c: Low-level ethernet polling functions
*
@@ -55,10 +56,9 @@
#define NFRAMESB 4
#define NFRAMES (1 << NFRAMESB)
-struct buffer_t tx_buffer, rx_buffer[NFRAMES];
+#define __uncached __attribute__ ((__section__(".uncached")))
-/* rx buffers */
-u8 pkts[NFRAMES][PKT_SIZE];
+struct buffer_t *tx_buffer, *rx_buffer;
static int dbg = 0;
static u32 s3c2500_ether_chip_base = 0;
@@ -125,31 +125,41 @@
u32 stat, len, base, pos, desc, copy_len;
int ret = 0, i;
u8 *copy_base;
+ int error = 0;
if (!(base = s3c2500_ether_chip_base))
return -EINVAL;
i = curr_desc;
- /* do we own it yet? */
- if (rx_buffer[i].desc & BDMA_owner) return 0;
-
/* Read/clear stat */
stat = se_inw(base + BMRXSTAT);
se_outw(base + BMRXSTAT, 0);
+ /* do we own it yet? */
+ if (rx_buffer[i].desc & BDMA_owner) goto done;
+
/* do we have a packet? */
- if (!(rx_buffer[i].desc & BRxDone)) return 0;
+ if (!(rx_buffer[i].desc & BRxDone)) {
+ /* We have one, either there is a problem with it,
+ * or the engine isn't truly done yet */
+ if (rx_buffer[i].desc & (DescMSO | DescHalted | DescRxParErr |
+ DescMUFS | DescOverflow | DescCRCErr |
+ DescAlignErr))
+ error = 1;
+ else goto done; /* not quite ready yet */
+ }
pos = 0;
len = rx_buffer[i].desc & 0xffff;
len -= 4; /* Strip the FCS */
+ if (len > length) error = 1;
do {
desc = rx_buffer[i].desc;
- /* only do the copying if it will fit */
- if (len <= length) {
+ /* only do the copying if its ok */
+ if (!error) {
copy_base = rx_buffer[i].ptr;
if (desc & DescEOF) copy_len = len - pos;
else copy_len = PKT_SIZE;
@@ -163,17 +173,21 @@
i = (i + 1) % NFRAMES;
} while (!(desc & DescEOF));
- /* Reenable used (or discarded) for reception */
+ /* Reenable used (or discarded) buffers for reception */
do {
rx_buffer[curr_desc++].desc = BDMA_owner;
if (curr_desc >= NFRAMES) curr_desc = 0;
} while (i != curr_desc);
+ if (!error) ret = len;
+
+done:
/* Make sure transmission is still enabled */
- se_bset(base + BDMARXCON, BRxEn);
- se_bset(base + MACRXCON, MRxEn);
+ se_outw(base + BDMARXCON, BRxEn | (0x2 << BRxMSL) |
+ (NFRAMESB << BRxNBD));
+ se_outw(base + MACRXCON, MRxEn);
- return (len <= length) ? len : 0;
+ return ret;
}
@@ -193,11 +207,11 @@
}
/* wait for the descriptor to free up */
- while (tx_buffer.desc & BDMA_owner);
+ while (tx_buffer->desc & BDMA_owner);
/* Setup the descriptor */
- tx_buffer.ptr = (u8 *) data;
- tx_buffer.desc = length | ((((u32) data) % 4) << 16) | BDMA_owner;
+ tx_buffer->ptr = (u8 *) data;
+ tx_buffer->desc = length | ((((u32) data) % 4) << 16) | BDMA_owner;
/* Make sure everything is ready to go */
se_bset(base + BDMATXCON, BTxEn);
@@ -210,7 +224,7 @@
se_outw(base + BMTXSTAT, 0x0);
/* give it back */
- tx_buffer.desc = 0;
+ tx_buffer->desc = 0;
return 0;
}
@@ -243,10 +257,20 @@
}
+void *malloc_uncached(u32 size)
+{
+ static char *uncached_area = (char *) 0x1F00000L;
+ char *ret = uncached_area;
+ uncached_area += size;
+ return ret;
+}
+
+
/* Enable everything */
static void s3c2500_ether_enable(u32 base)
{
int i;
+
/* Set the MAC to full duplex */
se_outw(base + MACCON, MACFD);
@@ -254,14 +278,14 @@
se_outw(base + BDMARXLEN, PKT_SIZE | MAX_FRAME << 16);
/* point the chip to our buffers */
- se_outw(base + BDMATXDPTR, (u32) &tx_buffer);
- se_outw(base + BDMARXDPTR, (u32) &rx_buffer);
+ se_outw(base + BDMATXDPTR, (u32) tx_buffer);
+ se_outw(base + BDMARXDPTR, (u32) rx_buffer);
/* setup our buffer descriptors */
- tx_buffer.ptr = 0;
- tx_buffer.desc = 0;
+ tx_buffer->ptr = 0;
+ tx_buffer->desc = 0;
for (i = 0; i < NFRAMES; i++) {
- rx_buffer[i].ptr = (u8 *) pkts[i];
+ rx_buffer[i].ptr = malloc_uncached(PKT_SIZE);
rx_buffer[i].desc = BDMA_owner;
}
curr_desc = 0;
@@ -289,8 +313,10 @@
static int s3c2500_ether_init(u32 base)
{
-
DBG(1, "%s(%08x)\n", __FUNCTION__, base);
+
+ tx_buffer = malloc_uncached(sizeof(struct buffer_t));
+ rx_buffer = malloc_uncached(sizeof(struct buffer_t) * NFRAMES);
s3c2500_ether_chip_base = base;
|