net_wiznet: initial Wiznet 5100 support
authorAlan Cox <alan@linux.intel.com>
Fri, 7 Sep 2018 01:30:26 +0000 (02:30 +0100)
committerAlan Cox <alan@linux.intel.com>
Fri, 7 Sep 2018 01:30:26 +0000 (02:30 +0100)
Some elements of the code come under the category of 'sufficiently rigged demo'
but as a basis it seems to be workable now.

Kernel/dev/net/net_wiznet.c
Kernel/dev/net/net_wiznet.h [new file with mode: 0644]

index cf007a0..382f86a 100644 (file)
     socket and when it connects allocate another one. That means we need to
     use to break the 1:1 mapping between wiznet and OS socket numbering
   - handle address collision interrupt
+  - rework disconnect state machine
  */
 
+#include <kernel.h>
+#include <kdata.h>
+#include <netdev.h>
+#include <net_wiznet.h>
+#include <printf.h>
+
+#ifdef CONFIG_NET_WIZNET
+
 static uint8_t irqmask;
 
-#define RX_MASK        0x1FFF
-#define TX_MASK                0x1FFF
+#define RX_MASK        0x07FF
+#define TX_MASK                0x07FF
+
+#define MR             0x0000
+#define                MR_RESET        0x80
+#define                MR_PB           0x10
+#define                MR_PPPOE        0x08
+#define                MR_AUTOINC      0x02
+#define                MR_INDIRECT     0x01
+
+#define GAR0           0x0001
+#define SUBR0          0x0005
+#define SHAR0          0x0009
+#define SIPR0          0x000F
+#define IR             0x0015
+#define IMR            0x0016
+#define RTR0           0x0017
+#define RCR            0x0019
+#define RMSR           0x001A
+#define TMSR           0x001B
+#define PATR0          0x001C
+#define PTIMER         0x0028
+#define PMAGIC         0x0029
+#define UIPR0          0x002A
+#define UPORT0         0x002E
+
+#define Sn_MR          0x0400
+#define Sn_CR          0x0401
+#define        OPEN            0x01
+#define                LISTEN          0x02
+#define                CONNECT         0x04
+#define                DISCON          0x08
+#define                CLOSE           0x10
+#define                SEND            0x20
+#define                SEND_MAC        0x21
+#define                SEND_KEEP       0x22
+#define                RECV            0x40
+#define        Sn_IR           0x0402
+#define                I_SEND_OK       0x10
+#define                I_TIMEOUT       0x08
+#define                I_RECV          0x04
+#define                I_DISCON        0x02
+#define                I_CON           0x01
+#define Sn_SR          0x0403
+#define                SOCK_CLOSED             0x00
+#define                SOCK_ARP                0x01
+#define                SOCK_INIT               0x13
+#define                SOCK_LISTEN             0x14
+#define                SOCK_SYNSENT            0x15
+#define                SOCK_SYNRECV            0x16
+#define                SOCK_ESTABLISHED        0x17
+#define                SOCK_FIN_WAIT           0x18
+#define                SOCK_CLOSING            0x1A
+#define                SOCK_TIME_WAIT          0x1B
+#define                SOCK_CLOSE_WAIT         0x1C
+#define                SOCK_LAST_ACK           0x1D
+#define                SOCK_UDP                0x22
+#define                SOCK_IPRAW              0x32
+#define                SOCK_MACROW             0x42
+#define                SOC_PPPOE               0x5F
+#define Sn_PORT0       0x0404
+#define Sn_DHAR0       0x0406
+#define Sn_DIPR0       0x040C
+#define Sn_DPORT0      0x0410
+#define Sn_MSSR0       0x0412
+#define Sn_PROTO       0x0414
+#define Sn_TOS         0x0415
+#define Sn_TTL         0x0416
+#define Sn_TX_FSR      0x0420
+#define Sn_TX_RD0      0x0422
+#define Sn_TX_WR0      0x0424
+#define Sn_RX_RSR      0x0426
+#define Sn_RX_RD0      0x0428
+
+
+
 
 /* Core helpers: platform supplies wiz_bread{_u} and wiz_bwrite{_u} */
 
-/* Might be worth inlining these on some platforms - need to think about
-   that carefully */
+__sfr __at 0x28 mr;
+__sfr __at 0x29 idm_ar0;
+__sfr __at 0x2A idm_ar1;
+__sfr __at 0x2B idm_dr;
 
-static uint8_t wiz_readb(uint16_t offset)
+/* We assume indirect, autoinc is always set */
+static uint8_t wiz_readb(uint16_t off)
 {
-       uint8_t n;
-       wiz_bread(offset, &n, 1);
-       return n;
+       idm_ar0 = off >> 8;
+       idm_ar1 = off;
+       return idm_dr;
 }
 
-static uint16_t wiz_readw(uint16_t offset)
+static uint16_t wiz_readw(uint16_t off)
 {
        uint16_t n;
-       wiz_bread(offset, &n, 2);
+       idm_ar0 = off >> 8;
+       idm_ar1 = off;
+       n = ((uint16_t)idm_dr) << 8;
+       n |= idm_dr;
        return n;
 }
 
-static uint32_t wiz_readl(uint16_t offset)
+static uint32_t wiz_readl(uint16_t off)
 {
        uint32_t n;
-       wiz_bread(offset, &n, 4);
+       idm_ar0 = off >> 8;
+       idm_ar1 = off;
+       n = ((uint32_t)idm_dr) << 24;
+       n |= ((uint32_t)idm_dr) << 16;
+       n |= ((uint16_t)idm_dr) << 8;
+       n |= idm_dr;
        return n;
 }
 
-static void wiz_writeb(uint16_t offset, uint8_t n)
+static void wiz_bread(uint16_t off, uint8_t *p, uint8_t n)
 {
-       wiz_bwrite(offset, &n, 1);
+       idm_ar0 = off >> 8;
+       idm_ar1 = off;
+       while(n--)
+               *p++ = idm_dr;
 }
 
-static void wiz_writew(uint16_t offset, uint16_t n)
+static void wiz_breadu(uint16_t off, uint8_t *p, uint8_t n)
 {
-       wiz_bwrite(offset, &n, 2);
+       idm_ar0 = off >> 8;
+       idm_ar1 = off;
+       while(n--)
+               uputc(idm_dr, p++);
 }
 
-#ifdef BIG_ENDIAN
-#define wiz_writew_n(a,b)      wiz_writew(a,b)
-#define wiz_readw_n(a)         wiz_readw(a)
-#else
+static void wiz_writeb(uint16_t off, uint8_t n)
+{
+       idm_ar0 = off >> 8;
+       idm_ar1 = off;
+       idm_dr = n;
+}
 
-static void wiz_writew_n(uint16_t offset, uint16_t n)
+static void wiz_writew(uint16_t off, uint16_t n)
 {
-       n = htons(n);
-       wiz_bwrite(offset, &n, 2);
+       idm_ar0 = off >> 8;
+       idm_ar1 = off;
+       idm_dr = n >> 8;
+       idm_dr = n;
 }
 
-static uint16_t wiz_readw_n(uint16_t offset)
+static void wiz_writel(uint16_t off, uint32_t n)
 {
-       uint16_t n;
-       wiz_bread(offset, &n, 2);
-       return ntohs(n);
+       idm_ar0 = off >> 8;
+       idm_ar1 = off;
+       idm_dr = n >> 24;
+       idm_dr = n >> 16;
+       idm_dr = n >> 8;
+       idm_dr = n;
 }
-#endif
 
+static void wiz_bwrite(uint16_t off, uint8_t *p, uint8_t n)
+{
+       idm_ar0 = off >> 8;
+       idm_ar1 = off;
+       while(n--)
+               idm_dr = *p++;
+}
+
+static void wiz_bwriteu(uint16_t off, uint8_t *p, uint8_t n)
+{
+       idm_ar0 = off >> 8;
+       idm_ar1 = off;
+       while(n--)
+               idm_dr = ugetc(p++);
+}
 
 /* FIXME: look for ways to fold these four together */
 static void wiz_queue(uint16_t i, uint16_t n, uint8_t * p)
 {
        uint16_t dm = wiz_readw(Sn_TX_WR0 + i) & TX_MASK;
-       uint16_t tx_base = 0x8000 + (i << 3);   /* i is already << 8 */
+       uint16_t tx_base = 0x4000 + (i << 3);   /* i is already << 8 */
 
        if (dm + n >= TX_MASK) {
                uint16_t us = TX_MASK + 1 - dm;
@@ -90,21 +211,21 @@ static void wiz_queue(uint16_t i, uint16_t n, uint8_t * p)
 
 static void wiz_queue_u(uint16_t i, uint16_t n, uint8_t * p)
 {
-       uint16_t dm = wiz_readw_n(Sn_TX_WR0 + i) & TX_MASK;
-       uint16_t tx_base = 0x8000 + (i << 3);   /* i is already << 8 */
+       uint16_t dm = wiz_readw(Sn_TX_WR0 + i) & TX_MASK;
+       uint16_t tx_base = 0x4000 + (i << 3);   /* i is already << 8 */
 
        if (dm + n >= TX_MASK) {
                uint16_t us = TX_MASK + 1 - dm;
-               wiz_bwrite_u(dm + tx_base, p, us);
-               wiz_bwrite_u(tx_base, p + us, n - us);
+               wiz_bwriteu(dm + tx_base, p, us);
+               wiz_bwriteu(tx_base, p + us, n - us);
        } else
-               wiz_bwrite_u(dm + tx_base, p, n);
+               wiz_bwriteu(dm + tx_base, p, n);
 }
 
 static void wiz_dequeue(uint16_t i, uint16_t n, uint8_t * p)
 {
-       uint16_t dm = wiz_readw_n(Sn_RX0 + i) & RX_MASK;
-       uint16_t rx_base = 0xC000 + (i << 3);   /* i is already << 8 */
+       uint16_t dm = wiz_readw(Sn_RX_RD0 + i) & RX_MASK;
+       uint16_t rx_base = 0x6000 + (i << 3);   /* i is already << 8 */
 
        if (dm + n >= RX_MASK) {
                uint16_t us = RX_MASK + 1 - dm;
@@ -116,15 +237,15 @@ static void wiz_dequeue(uint16_t i, uint16_t n, uint8_t * p)
 
 static void wiz_dequeue_u(uint16_t i, uint16_t n, uint8_t * p)
 {
-       uint16_t dm = wiz_readw_n(Sn_RX0 + i) & RX_MASK;
-       uint16_t rx_base = 0xC000 + (i << 3);   /* i is already << 8 */
+       uint16_t dm = wiz_readw(Sn_RX_RD0 + i) & RX_MASK;
+       uint16_t rx_base = 0x6000 + (i << 3);   /* i is already << 8 */
 
        if (dm + n >= RX_MASK) {
                uint16_t us = RX_MASK + 1 - dm;
-               wiz_bread_u(dm + rx_base, p, us);
-               wiz_bread_u(rx_base, p + us, n - us);
+               wiz_breadu(dm + rx_base, p, us);
+               wiz_breadu(rx_base, p + us, n - us);
        } else
-               wiz_bread_u(dm + rx_base, p, n);
+               wiz_breadu(dm + rx_base, p, n);
 }
 
 static void wiz_wakeall(struct socket *s)
@@ -143,18 +264,27 @@ static void wiz_eof(struct socket *s)
 /*
  *     Process interrupts from the WizNet device
  */
-void wiz_event_s(uint8_t i)
+static void wiz_event_s(uint8_t i)
 {
        struct socket *s = &sockets[i];
        uint16_t stat = wiz_readw(Sn_IR + (i << 8));    /* BE read of reg pair */
 
-       if (stat & 0x800) {
+       if (stat & 0x1000) {
                /* Transmit completed: window re-open. We can allow more
                   data to flow from the user */
                s->s_iflag &= ~SI_THROTTLE;
-               wiz_writeb(Sn_IR + (i << 8), 0x08);     /* Clear the flag down */
+               wiz_writeb(Sn_IR + (i << 8), 0x10);     /* Clear the flag down */
                wakeup(&s->s_data);
        }
+       if (stat & 0x800) {
+               /* Timeout */
+               s->s_error = ETIMEDOUT;
+               wiz_writeb(Sn_CR + (i << 8), CLOSE);
+               wiz_wakeall(s);
+               wiz_writeb(Sn_IR + (i << 8), 0x08);
+               wiz_eof(s);
+               /* Fall through and let CLOSE state processing do the work */
+       }
        if (stat & 0x400) {
                /* Receive wake: Poke the user in case they are reading */
                s->s_iflag |= SI_DATA;
@@ -164,8 +294,11 @@ void wiz_event_s(uint8_t i)
        if (stat & 0x200) {
                /* Disconnect: Just kill our host socket. Not clear if this
                   is right or we need to drain data first */
-               s->state = SS_CLOSED;
+               wiz_writeb(Sn_IR + (i << 8), 0x02);     /* Clear the flag down */
+               wiz_writeb(Sn_CR + (i << 8), CLOSE);
                wiz_eof(s);
+               /* When we fall through we'll see CLOSE state and do the
+                  actual shutting down */
        }
        if (stat & 0x100) {
                /* Connect: Move into connected state */
@@ -173,20 +306,26 @@ void wiz_event_s(uint8_t i)
                        s->s_state = SS_CONNECTED;
                        wakeup(s);
                }
+               wiz_writeb(Sn_IR + (i << 8), 0x01);     /* Clear the flag down */
        }
        /* ??? return if high bits set here ?? */
        switch (stat & 0xFF) {
        case 0:         /* SOCK_CLOSED */
                if (s->s_state != SS_CLOSED && s->s_state != SS_UNUSED) {
-                       s->s_state = SS_CLOSED;
-                       if (s->s_state != SS_CLOSING) {
+                       if (s->s_state != SS_CLOSING && s->s_state != SS_DEAD) {
                                s->s_error = ECONNRESET;        /* Sort of a guess */
                                wiz_wakeall(s);
                        } else
                                wakeup(s);
+                       irqmask &= ~(1 << i);
+                       wiz_writeb(IMR, irqmask);
+                       wiz_eof(s);
+                       /* Net layer wants us to burn the socket */
+                       if (s->s_state == SS_DEAD)
+                               sock_closed(s);
+                       else    /* so net_close() burns the socket */
+                               s->s_state = SS_CLOSED;
                }
-               irqmask &= ~(1 << i);
-               wiz_writeb(Sn_IMR, irqmask);
                break;
        case 0x13:              /* SOCK_INIT */
                break;
@@ -196,7 +335,7 @@ void wiz_event_s(uint8_t i)
                if (s->s_state == SS_CONNECTING) {
                        s->s_state == SS_CONNECTED;
                        wakeup(s);
-               } else if (s->s_state == SS_LISTEN) {
+               } else if (s->s_state == SS_LISTENING) {
                        /* TODO: We actually have to split the association between
                           wiznet and host sockets as we have multiple wiznet sockets
                           in the accept queue and a listener that is not really a
@@ -206,7 +345,7 @@ void wiz_event_s(uint8_t i)
        case 0x1C:              /* SOCK_CLOSE_WAIT */
                if (s->s_state == SS_CONNECTED
                    || s->s_state == SS_CONNECTING)
-                       s->s_state == SS_CLOSEWAIT;
+                       s->s_state = SS_CLOSEWAIT;
                wiz_eof(s);
                if (s->s_state == SS_ACCEPTWAIT) {
                        /* HUM ??? */
@@ -226,10 +365,11 @@ void wiz_event(void)
 {
        uint8_t irq;
        uint8_t i = 0;
+       struct socket *s = sockets;
 
 
        /* Polling cases */
-       irq = wiz_readb(IR2);
+       irq = wiz_readb(IR) & 0x0F;
        if (irq == 0)
                return;
 
@@ -261,30 +401,35 @@ int net_bind(struct socket *s)
 {
        uint16_t i = s - sockets;
        uint8_t r = SOCK_INIT;
+       uint16_t off = i << 8;
 
-       switch (s->sock_type) {
+       switch (s->s_type) {
        case SOCKTYPE_TCP:
-               wiz_writeb(Sn_MR + (i << 8), 0x01);     /* TCP */
-               wiz_writew(Sn_PORT0 + (i << 8), s->s_addr[SADDR_SRC].port);
+               wiz_writeb(Sn_MR + off, 0x21);  /* TCP, delayed ack */
+               /* We keep ports net endian so don't byte swap */
+               wiz_bwrite(Sn_PORT0 + off, &s->s_addr[SADDR_SRC].port, 2);
                break;
        case SOCKTYPE_UDP:
-               wiz_writeb(Sn_MR + (i << 8), 0x02);     /* UDP */
-               wiz_writew(Sn_PORT0 + (i << 8), s->s_addr[SADDR_SRC].port);
+               wiz_writeb(Sn_MR + off, 0x02);  /* UDP */
+               wiz_bwrite(Sn_PORT0 + off, &s->s_addr[SADDR_SRC].port, 2);
                r = SOCK_UDP;
                break;
        case SOCKTYPE_RAW:
-               wiz_writeb(Sn_PROTO + (i << 8), s->s_addr[ADDR_SRC].port);      /* hack */
-               wiz_writeb(Sn_MR + (i << 8), 0x03);     /* RAW */
+               wiz_writeb(Sn_PROTO + off, s->s_addr[SADDR_SRC].port);  /* hack */
+               wiz_writeb(Sn_MR + off, 0x03);  /* RAW */
                r = SOCK_IPRAW;
        }
-       wiz_writeb(Sn_CR + (i << 8), OPEN);
+       /* Make an open request to open the socket */
+       wiz_writeb(Sn_CR + off, OPEN);
 
-       if (wiz_readb(Sn_SR + (i << 8)) != r) {
+       /* If the reply is not immediately SOCK_INT we failed */
+       if (wiz_readb(Sn_SR + off) != r) {
                udata.u_error = EADDRINUSE;     /* Something broke ? */
                return -1;
        }
+       /* Interrupt on if available mark as bound */
        irqmask |= 1 << i;
-       wiz_writeb(Sn_IMR, irqmask);
+       wiz_writeb(IMR, irqmask);
        s->s_state = SS_BOUND;
        /* Do we need to delay the SS_BOUND until the chip interrupts ? */
        return 0;
@@ -303,9 +448,10 @@ int net_listen(struct socket *s)
 
        i <<= 8;
 
+       /* Issue a listen command. Check the state went to SOCK_LISTEN */
        wiz_writeb(Sn_CR + i, LISTEN);
        if (wiz_readb(Sn_SR + i) != SOCK_LISTEN) {
-               udata.u_error = EPROTO; /* ??? */
+               udata.u_error = EIO;//FIXME EPROTO;     /* ??? */
                return -1;
        }
        s->s_state = SS_LISTENING;
@@ -322,9 +468,10 @@ int net_connect(struct socket *s)
                uint16_t i;
                i = s - sockets;
                i <<= 8;
-               wiz_writel(Sn_DIRP0 + i, s->s_addr[SADDR_DST].addr);
-               wiz_writew(Sn_DPORT0 + i, s->s_addr[SADDR_DST].port);
-               wiz_writeb(Sn_NR + i, CONNECT);
+               /* Already net endian */
+               wiz_bwrite(Sn_DIPR0 + i, &s->s_addr[SADDR_DST].addr, 4);
+               wiz_bwrite(Sn_DPORT0 + i, &s->s_addr[SADDR_DST].port, 2);
+               wiz_writeb(Sn_CR + i, CONNECT);
                s->s_state = SS_CONNECTING;
        } else {
                /* UDP/RAW - note have to do our own filtering for 'connect' */
@@ -337,25 +484,30 @@ int net_connect(struct socket *s)
 void net_close(struct socket *s)
 {
        uint16_t i = s - sockets;
+       uint16_t off = i << 8;
 
-       if (s->s_type == SOCKTYPE_TCP) {
-               wiz_writeb(Sn_CR + (i << 8), DISCON);
+       if (s->s_type == SOCKTYPE_TCP && s->s_state != SS_CLOSED) {
+               wiz_writeb(Sn_CR + off, DISCON);
                s->s_state = SS_CLOSING;
        } else {
-               wiz_clear_int(i);
-               wiz_writeb(Sn_CR + (i << 8), CLOSE);
-               s->s_state = SS_UNINIT;
+               irqmask &= ~(1 << i);
+               wiz_writeb(IMR, irqmask);
+               wiz_writeb(Sn_CR + off, CLOSE);
+               sock_closed(s);
        }
 }
 
 arg_t net_read(struct socket *s, uint8_t flag)
 {
-       uint16_t n;
+       uint16_t n = 0xFFFF;
        uint16_t r;
        uint16_t i = s - sockets;
+       uint8_t st;
 
        i <<= 8;
 
+       s->s_iflag &= ~SI_DATA;
+
        /* FIXME: IRQ protection */
        /* Wait for data - push int core code ? */
        while ((s->s_iflag & SI_DATA) == 0) {
@@ -367,14 +519,19 @@ arg_t net_read(struct socket *s, uint8_t flag)
                /* Check for an EOF (covers post close cases too) */
                if (s->s_iflag & SI_EOF)
                        return 0;
-               /* Needs irq protection */
-               if (psleep_flags(&s->iflag, flag))
-                       return -1;
                /* Keep waiting until we get the right state */
                /* Bytes available */
-               n = wiz_readw_n(Sn_RX_RSR + i);
-               if (n)
+               n = wiz_readw(Sn_RX_RSR + i);
+               if (n) {
                        s->s_iflag |= SI_DATA;
+                       break;
+               }
+               st = wiz_readb(Sn_SR);
+               if (st >= SOCK_CLOSING && st <= SOCK_UDP)
+                       return 0;
+               /* Need IRQ protection to avoid sleep race */
+               if (psleep_flags(&s->s_iflag, flag))
+                       return -1;
        }
        switch (s->s_type) {
        case SOCKTYPE_RAW:
@@ -394,38 +551,44 @@ arg_t net_read(struct socket *s, uint8_t flag)
                /* Now dequeue some bytes into udata.u_base */
                wiz_dequeue_u(i, r, udata.u_base);
                /* For datagrams we always discard the entire frame */
-               wiz_writew_n(Sn_TX_WR0 + i, wiz_readw_n(Sn_TX_WR0 + i)
-                            + s->s_type == SOCKTYPE_TCP ? r : (n + 8));
+               if (s->s_type == SOCKTYPE_UDP)
+                       r = n + 8;
+               wiz_writew(Sn_RX_RD0 + i, wiz_readw(Sn_RX_RD0 + i) + r);
                /* FIXME: figure out if SI_DATA should be cleared */
-               return r;
+               /* Now tell the device we ate the data */
+               wiz_writeb(Sn_CR, RECV);
        }
+       return r;
 }
 
 arg_t net_write(struct socket * s, uint8_t flag)
 {
        uint16_t i = s - sockets;
        uint16_t room;
-       uint16_t n;
-       uint8_t a = s->s_flag & SFLAG_ATMP ? SADDR_TMP : SADDR_SADDR_DST;
+       uint16_t n = 0;;
+       uint8_t a = s->s_flag & SFLAG_ATMP ? SADDR_TMP : SADDR_DST;
+
+       /* FIXME: blocking ?? */
+       used(flag);
 
        i <<= 8;
 
-       room = wiz_readw_n(Sn_TX_FSR + i);
+       room = wiz_readw(Sn_TX_FSR + i);
 
-       switch (s->s_socktype) {
+       switch (s->s_type) {
        case SOCKTYPE_UDP:
                if (udata.u_count > 1472) {
                        udata.u_error = EMSGSIZE;
                        return -1;
                }
-       case SOCKTYPE_IPRAW:
+       case SOCKTYPE_RAW:
                if (udata.u_count > 1500) {
                        udata.u_error = EMSGSIZE;
                        return -1;
                }
                if (room < udata.u_count)
                        return -2;
-               wiz_writel(Sn_DIRPO + i, s->s_addr[a].addr);
+               wiz_writel(Sn_DIPR0 + i, s->s_addr[a].addr);
                wiz_writel(Sn_DPORT0 + i, s->s_addr[a].port);
                /* Fall through */
        case SOCKTYPE_TCP:
@@ -433,14 +596,24 @@ arg_t net_write(struct socket * s, uint8_t flag)
                        return -2;
                n = min(room, udata.u_count);
                wiz_queue_u(i, n, udata.u_base);
-               wiz_writew_n(Sn_TX_WR0 + i,
-                            wiz_readw_n(Sn_TX_WR0 + i) + n);
+               wiz_writew(Sn_TX_WR0 + i,
+                            wiz_readw(Sn_TX_WR0 + i) + n);
+               wiz_writeb(Sn_CR, SEND);
                break;
        }
-       udata.u_count = n;
        return n;
 }
 
+arg_t net_shutdown(struct socket *s, uint8_t flag)
+{
+       s->s_iflag |= flag;
+       if (s->s_iflag & SI_SHUTW)
+               wiz_writeb(Sn_CR, DISCON);
+       /* Really we need to look for SHUTR and received data and CLOSE if
+          so - FIXME */
+       return 0;
+}
+
 /* Everything below this line is still pure sketching of ideas as we don't
    really have a configuration interface designed yet ! */
 
@@ -449,7 +622,7 @@ struct netdevice net_dev = {
        "eth0",                 /* Good a name as any */
        0,                      /* No special flags */
 };
-
+#if 0
 /* Only some of these hit this code, most are handled by the core */
 arg_t net_ioctl(uint8_t op, void *p)
 {
@@ -472,18 +645,36 @@ arg_t net_ioctl(uint8_t op, void *p)
                wiz_bwrite(SHAR0, p, 6);
                break;
        case OP_GPHY:
-               return (wiz_bread(PSTATUS) & 0x20) ? LINK_UP : LINK_DOWN;
+               return (wiz_readb(PSTATUS) & 0x20) ? LINK_UP : LINK_DOWN;
        default:
                return -EINVAL;
        }
        return 0;
 }
+#endif
+static uint32_t ipa = 0x00000000;      /* Tmp hack */
+static uint8_t fakeaddr[6] = { 0xC0, 0xFF, 0xEE, 0xC0, 0xFF, 0xEE };
+static uint32_t iga = 0x020000C0;
+static uint32_t igm = 0x00FFFFFF;
 
 void netdev_init(void)
 {
        uint16_t i;
-       for (i = 0; i < 8; i++) {
-               wiz_writeb(Sn_RXMEM_SIZE + (i << 8), 0x2000);
-               wiz_writeb(Sn_TXMEM_SIZE + (i << 8), 0x2000);
+       /* We run all the time in indirect, autoinc */
+       mr = MR_AUTOINC|MR_INDIRECT;
+       wiz_writeb(IMR, 0);
+//     wiz_writeb(RTR, );
+//     wiz_writeb(RCR, );
+       /* Set GAR, SHAR, SUBR, SIPR to defaults ? */
+       wiz_bwrite(SIPR0, &ipa, 4);
+       wiz_bwrite(GAR0, &iga, 4);
+       wiz_bwrite(SUBR0, &igm, 4);
+       wiz_bwrite(SHAR0, fakeaddr, 6);
+       wiz_writeb(RMSR, 0x55); /* 2k a socket */
+       wiz_writeb(TMSR, 0x55); /* 2k a socket */
+       for (i = 0; i < 4 * 256; i += 256) {
+               /* Do we need to set anything here */
        }
 }
+
+#endif
diff --git a/Kernel/dev/net/net_wiznet.h b/Kernel/dev/net/net_wiznet.h
new file mode 100644 (file)
index 0000000..cc3362b
--- /dev/null
@@ -0,0 +1,3 @@
+
+extern void wiz_event(void);
+extern void wiz_poll(void);