home *** CD-ROM | disk | FTP | other *** search
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include "kernel.h"
- #include "swis.h"
- #include "global.h"
-
- static _kernel_oserror error;
-
- char bcast_hwaddr[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
- struct port port[4];
-
- struct mbuf *rxfreeq_first = NULLMBUF;
- struct mbuf *rxfreeq_last = NULLMBUF;
-
- struct mbuf *txfreeq_first = NULLMBUF;
- struct mbuf *txfreeq_last = NULLMBUF;
-
- struct mbuf *lfreeq = NULLMBUF;
-
- struct packet *tx_first = NULLPACKET;
- struct packet *tx_last = NULLPACKET;
-
- int tx = FALSE;
-
- int nounits = 0;
- int swibase = 0;
-
- int Driver_State = DRIVER_NONE;
-
- /* Errors */
- int memout = 0;
- int txqfull = 0;
- int rxqfull = 0;
-
- extern int dci_event_entry(_kernel_swi_regs *, void *);
- extern int dci_timer_entry(_kernel_swi_regs *, void *);
- static void *private_pw;
-
- void dci_finalisation(void)
- {
- _kernel_swi_regs rin, rout;
-
- rin.r[0] = 13;
- rin.r[1] = EVENT_TX;
- _kernel_swi(XOS_Bit | OS_Byte, &rin, &rout);
-
- rin.r[0] = 13;
- rin.r[1] = EVENT_RX;
- _kernel_swi(XOS_Bit | OS_Byte, &rin, &rout);
-
- rin.r[0] = 0x10;
- rin.r[1] = (int)dci_event_entry;
- rin.r[2] = (int)private_pw;
- _kernel_swi(XOS_Bit | OS_Release, &rin, &rout);
-
- rin.r[0] = 0x1C;
- rin.r[1] = (int)dci_timer_entry;
- rin.r[2] = (int)private_pw;
- _kernel_swi(XOS_Bit | OS_Release, &rin, &rout);
-
- rin.r[1] = Service_ProtocolDying;
- rin.r[2] = 1;
- _kernel_swi(XOS_Bit | OS_ServiceCall, &rin, &rout);
- }
-
- _kernel_oserror *dci_initialise(char *cmd, int base, void *pw)
- {
- _kernel_swi_regs rin, rout;
- register int i;
- static int claimed = FALSE;
-
- cmd = cmd;
- base = base;
-
- private_pw = pw;
-
- atexit(dci_finalisation);
-
- for (i = 0; i < 4; i++)
- {
- port[i].status = STATUS_NODRVR;
- port[i].ipaddr = 0;
- port[i].rx_first = NULLPACKET;
- port[i].rx_last = NULLPACKET;
- port[i].iprx = port[i].iptx = 0;
- port[i].arpreqrx = port[i].arpreqtx = 0;
- port[i].arpresrx = port[i].arprestx = 0;
- }
-
- initialise_rx_mbuf(400);
- initialise_tx_mbuf(300);
- initialise_packet();
- Initialise_ARP_Cache();
-
- rin.r[1] = Service_FindNetworkDriver;
- rin.r[2] = 0;
- rin.r[3] = 0;
- _kernel_swi(XOS_Bit | OS_ServiceCall, &rin, &rout);
-
- if (rout.r[1] == 0)
- {
- Attach_Driver();
-
- if (Driver_State != DRIVER_INITED)
- {
- error.errnum = 3;
- strcpy(error.errmess, "Could not attach driver");
- return(&error);
- }
- }
-
- if (!claimed)
- {
- rin.r[0] = 0x1C;
- rin.r[1] = (int)dci_timer_entry;
- rin.r[2] = (int)private_pw;
- _kernel_swi(XOS_Bit | OS_Claim, &rin, &rout);
-
- rin.r[0] = 0x10;
- rin.r[1] = (int)dci_event_entry;
- rin.r[2] = (int)private_pw;
- _kernel_swi(XOS_Bit | OS_Claim, &rin, &rout);
-
- rin.r[0] = 14;
- rin.r[1] = EVENT_TX;
- _kernel_swi(XOS_Bit | OS_Byte, &rin, &rout);
-
- rin.r[0] = 14;
- rin.r[1] = EVENT_RX;
- _kernel_swi(XOS_Bit | OS_Byte, &rin, &rout);
-
- claimed = TRUE;
- }
-
- return(NULL);
- }
-
- void Attach_Driver(void)
- {
- _kernel_swi_regs rin, rout;
- struct dib *dib;
- struct pib pib;
- register int i;
-
- pib.pib_frtypecnt = 2;
- pib.pib_frtype[0] = FRAME_IP;
- pib.pib_frtype[1] = FRAME_ARP;
- pib.pib_rxevent = EVENT_RX;
- pib.pib_freeq = &rxfreeq_first;
- pib.pib_sccall = 1;
- pib.pib_lfreeq = &lfreeq;
-
- rin.r[1] = Service_FindNetworkDriver;
- rin.r[2] = (int)"ea";
- rin.r[3] = (int)&pib;
- _kernel_swi(XOS_Bit | OS_ServiceCall, &rin, &rout);
-
- if (rout.r[1] != 0) return;
-
- dib = (struct dib *)rout.r[3];
-
- nounits = dib->dib_units;
- swibase = dib->dib_swibase;
-
- for (i = 0; i < nounits; i++)
- {
- port[i].status = STATUS_DOWN;
- port[i].hwaddr[0] = dib->dib_address[i][0];
- port[i].hwaddr[1] = dib->dib_address[i][1];
- port[i].hwaddr[2] = dib->dib_address[i][2];
- port[i].hwaddr[3] = dib->dib_address[i][3];
- port[i].hwaddr[4] = dib->dib_address[i][4];
- port[i].hwaddr[5] = dib->dib_address[i][5];
-
- rin.r[0] = i;
- _kernel_swi(XOS_Bit | (swibase + SWI_NetworkIfStart), &rin, &rout);
-
- rin.r[0] = i;
- _kernel_swi(XOS_Bit | (swibase + SWI_NetworkIfDown), &rin, &rout);
- }
-
- Driver_State = DRIVER_INITED;
- }
-
- void dci_service(int snum, _kernel_swi_regs *r, void *pw)
- {
- int i;
-
- snum = snum;
- pw = pw;
-
- switch (r->r[2])
- {
- case 0:
- Attach_Driver();
- break;
- case 1:
- Driver_State = DRIVER_NONE;
- for (i = 0; i < 4; i++)
- port[i].status = STATUS_NODRVR;
- break;
- default:
- break;
- }
- }
-
- _kernel_oserror *dci_command(char *arg, int argc, int cmd, void *pw)
- {
- arg = arg;
- argc = argc;
- pw = pw;
-
- printf("Statistics for DCI Driver\n");
-
- switch (cmd)
- {
- case COMMAND_PORT:
- Port_Stats();
- break;
- case COMMAND_ARP:
- ARP_Stats();
- break;
- case COMMAND_QUEUE:
- Queue_Stats();
- break;
- case COMMAND_ERROR:
- Error_Stats();
- break;
- default:
- break;
- }
-
- printf("\n");
-
- return(NULL);
- }
-
- _kernel_oserror *dci_swi(int swino, _kernel_swi_regs *r, void *pw)
- {
- pw = pw;
-
- switch (swino)
- {
- case NETLITE_OPEN:
- Open_Port(r);
- break;
- case NETLITE_READ:
- Read_Port(r);
- break;
- case NETLITE_WRITE:
- Write_Port(r);
- break;
- case NETLITE_CLOSE:
- Close_Port(r);
- break;
- default:
- error.errnum = 1;
- strcpy(error.errmess, "Invalid SWI");
- return(&error);
-
- }
-
- return(NULL);
- }
-
- int dci_event_handler(_kernel_swi_regs *r, void *pw)
- {
- pw = pw;
-
- switch (r->r[0])
- {
- case EVENT_RX:
- Receive_Upcall(r);
- break;
- case EVENT_TX:
- Transmit_Upcall(r);
- break;
- default:
- break;
- }
-
- return(1);
- }
-
- int dci_timer_handler(_kernel_swi_regs *r, void *pw)
- {
- pw = pw;
- r = r;
-
- Timeout_ARP_Cache();
-
- if (!tx && tx_first != NULLPACKET)
- Transmit_Packet();
-
- return(1);
- }
-
- void Open_Port(register _kernel_swi_regs *r)
- {
- _kernel_swi_regs rin, rout;
- register int portno = r->r[0];
-
- if (Driver_State == DRIVER_NONE)
- {
- r->r[1] = SWI_NODRIVER;
- return;
- }
-
- if (portno < 0 || portno >= nounits)
- {
- r->r[1] = SWI_INVPORT;
- return;
- }
-
- if (port[portno].status == STATUS_UP)
- {
- r->r[1] = SWI_OK;
- return;
- }
-
- if (port[portno].status != STATUS_DOWN)
- {
- r->r[1] = SWI_OPEN;
- return;
- }
-
- port[portno].status = STATUS_UP;
- port[portno].ipaddr = r->r[1];
-
- rin.r[0] = portno;
- _kernel_swi(XOS_Bit | (swibase + SWI_NetworkIfUp), &rin, &rout);
-
- r->r[1] = SWI_OK;
- }
-
- void Close_Port(_kernel_swi_regs *r)
- {
- _kernel_swi_regs rin, rout;
- register int portno = r->r[0];
-
- if (Driver_State == DRIVER_NONE)
- {
- r->r[1] = SWI_NODRIVER;
- return;
- }
-
- if (portno < 0 || portno >= nounits)
- {
- r->r[1] = SWI_INVPORT;
- return;
- }
-
- if (port[portno].status == STATUS_DOWN)
- {
- r->r[1] = SWI_OK;
- return;
- }
-
- if (port[portno].status != STATUS_UP)
- {
- r->r[1] = SWI_CLOSED;
- return;
- }
-
- port[portno].status = STATUS_DOWN;
-
- rin.r[0] = portno;
- _kernel_swi(XOS_Bit | (swibase + SWI_NetworkIfDown), &rin, &rout);
-
- r->r[1] = SWI_OK;
- }
-
- void Port_Stats(void)
- {
- register int i;
-
- for (i = 0; i < nounits; i++)
- {
- if (port[i].status != STATUS_NODRVR)
- {
- printf("Port:%d HwAddr:%02X:%02X:%02X:%02X:%02X:%02X State:%s\n", i,
- port[i].hwaddr[0], port[i].hwaddr[1], port[i].hwaddr[2],
- port[i].hwaddr[3], port[i].hwaddr[4], port[i].hwaddr[5],
- (port[i].status == STATUS_UP) ? "UP" : "DOWN");
- printf("IP In:%d IP Out:%d\n", port[i].iprx, port[i].iptx);
- printf("ARP Request In:%d ARP Request Out:%d\n", port[i].arpreqrx, port[i].arpreqtx);
- printf("ARP Response In:%d ARP Response Out:%d\n", port[i].arpresrx, port[i].arprestx);
- }
- }
- }
-
- void Queue_Stats(void)
- {
- register struct mbuf *bp;
- register int i, n;
-
- printf("TX Port: Packets:%d\n", len_q(tx_first));
-
- for (i = 0; i < 4; i++)
- if (port[i].status == STATUS_UP)
- printf("RX Port:%d Packets:%d\n", i, len_q(port[i].rx_first));
-
- i = n = 0;
- for (bp = rxfreeq_first; bp != NULLMBUF; bp = bp->m_next)
- {
- if (bp->m_type == MT_DATA)
- {
- i++;
- printf("mbuf %d in use\n", n);
- }
-
- n++;
- }
-
- printf("RX Free queue=%d mbufs, %d K, %d used\n", n, n * MLEN, i);
-
- i = n = 0;
- for (bp = txfreeq_first; bp != NULLMBUF; bp = bp->m_next)
- {
- if (bp->m_type == MT_DATA)
- {
- i++;
- printf("mbuf %d in use\n", n);
- }
-
- n++;
- }
-
- printf("TX Free queue=%d mbufs, %d K, %d used\n", n, n * MLEN, i);
- }
-
- void Error_Stats(void)
- {
- printf("Out of Memory:%d\n", memout);
- printf("TX queue full:%d\n", txqfull);
- printf("RX queue full:%d\n", rxqfull);
- }
-
- char *put32(register char *cp, int x)
- {
- *cp++ = (char)(x >> 24);
- *cp++ = (char)(x >> 16);
- *cp++ = (char)(x >> 8);
- *cp++ = (char)(x);
-
- return(cp);
- }
-
- char *put16(register char *cp, short x)
- {
- *cp++ = (char)(x >> 8);
- *cp++ = (char)(x);
-
- return(cp);
- }
-
- short get16(register char *cp)
- {
- register short x;
-
- x = (char)(*cp++);
- x <<= 8;
- x |= (char)(*cp);
-
- return(x);
- }
-
- int get32(register char *cp)
- {
- register int x;
-
- x = (char)(*cp++);
- x <<= 8;
- x |= (char)(*cp++);
- x <<= 8;
- x |= (char)(*cp++);
- x <<= 8;
- x |= (char)(*cp);
-
- return(x);
- }
-
-