home *** CD-ROM | disk | FTP | other *** search
/ The Datafile PD-CD 3 / PDCD_3.iso / internet / tcpipsrc / Drivers / c / ethernet < prev    next >
Encoding:
Text File  |  1995-01-18  |  4.5 KB  |  184 lines

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <time.h>
  5. #include "werr.h"
  6. #include "kernel.h"
  7. #include "global.h"
  8. #include "mbuf.h"
  9. #include "internet.h"
  10. #include "iface.h"
  11. #include "cmdparse.h"
  12. #include "misc.h"
  13. #include "ethernet.h"
  14. #include "arc.h"
  15. #include "os.h"
  16. #include "swis.h"
  17. #include "timer.h"
  18. #include "ip.h"
  19. #include "trace.h"
  20.  
  21. struct ether ether[ETHER_MAX];
  22. unsigned int nether;
  23. extern struct interface *ifaces;
  24.  
  25. extern char nospace[];
  26.  
  27. static int ether_init(int16, struct interface *, int);
  28. static int ether_stop(struct interface *);
  29. static int ether_send(struct mbuf *, struct interface *, int32, int, int, int, int);
  30. static void ether_recv(struct interface *);
  31.  
  32. static char *ether_codes[] = 
  33. {
  34.   "",
  35.   "Invalid Port",
  36.   "Open",
  37.   "Closed",
  38.   "No Driver",
  39.   "No Memory",
  40.   "Too Big",
  41.   "Too Small"
  42. };
  43.  
  44. /* Attach an ethernet interface to the system
  45.  * argv[0]: hardware type, must be "ether"
  46.  * argv[1]: port number
  47.  * argv[2]: interface label, e.g., "et0"
  48.  * argv[3]: maximum transmission unit, bytes
  49.  */
  50. int ether_attach(int argc, char **argv)
  51. {
  52.         struct interface *if_ether;
  53.         int16 dev;
  54.  
  55.         argc = argc;
  56.  
  57.         if (nether >= ETHER_MAX){
  58.                 werr(1,"Too many ethernet controllers\n");
  59.                 return -1;
  60.         }
  61.  
  62.         dev = nether++;
  63.  
  64.         /* Create interface structure and fill in details */
  65.         if_ether = (struct interface *)calloc(1,sizeof(struct interface));
  66.         if_ether->name   = strdup(argv[2]);
  67.         if_ether->mtu    = atoi(argv[3]);
  68.         if_ether->dev    = dev;
  69.         if_ether->recv   = ether_recv;
  70.         if_ether->stop   = ether_stop;
  71.         if_ether->send   = ether_send;
  72.         if_ether->output = NULLFP;
  73.         if_ether->raw    = NULLFP;
  74.         if_ether->ioctl  = NULLFP;
  75.         if_ether->flags  = 0;
  76.         if_ether->next   = ifaces;
  77.         if_ether->trace  = 0;
  78.         if_ether->forw   = NULLIF;
  79.         ifaces = if_ether;
  80.         ether_init(dev, if_ether, atoi(argv[1]));
  81.  
  82.         return 0;
  83. }
  84.  
  85. /* Initialize ether port "dev" */
  86. static int ether_init(int16 dev, struct interface *iface, int port)
  87. {
  88.         _kernel_swi_regs rin, rout;
  89.  
  90.         ether[dev].iface = iface;
  91.         ether[dev].port  = port;
  92.  
  93.         rin.r[0] = port;
  94.         rin.r[1] = ip_addr;
  95.         _kernel_swi(ETHER_OPEN, &rin, &rout);
  96.  
  97.         if (rout.r[1] != ETHER_ERR_OK)
  98.         {
  99.               werr(1, "Error %d (%s) when opening DCI driver", rout.r[1], ether_codes[rout.r[1]]);
  100.               return(0);
  101.         }
  102.  
  103.         return(1);
  104. }
  105.  
  106. static int ether_stop(struct interface *iface)
  107. {
  108.         _kernel_swi_regs rin, rout;
  109.  
  110.         rin.r[0] = ether[iface->dev].port;
  111.         _kernel_swi(ETHER_CLOSE, &rin, &rout);
  112.  
  113.         return(0);
  114. }
  115.  
  116. /* Send a packet to transmitter */
  117. static int ether_send(struct mbuf *bp, struct interface *iface, int32 gateway, int precedence, int delay, int throughput, int reliability)
  118. {
  119.         _kernel_swi_regs rin, rout;
  120.         char buffer[1500];
  121.         int size;
  122.  
  123.         precedence  = precedence;
  124.         delay       = delay;
  125.         throughput  = throughput;
  126.         reliability = reliability;
  127.  
  128.         size = dqdata(bp, buffer, 1500);
  129.  
  130.         dump(iface, IF_TRACE_OUT, TRACE_IP, bp);
  131.  
  132.         rin.r[0] = ether[iface->dev].port;
  133.         rin.r[1] = (int)buffer;
  134.         rin.r[2] = size;
  135.         rin.r[3] = gateway;
  136.         _kernel_swi(ETHER_WRITE, &rin, &rout);
  137.  
  138.         if (rout.r[3] != ETHER_ERR_OK)
  139.         {
  140.                werr(0, "Error %d (%s) when writing to DCI driver", rout.r[3], ether_codes[rout.r[3]]);
  141.                return(0);
  142.         }
  143.  
  144.         return(0);
  145. }
  146.  
  147. /* Receive characters from line
  148.  * Returns count of characters read
  149.  */
  150. static void ether_recv(struct interface *iface)
  151. {
  152.         _kernel_swi_regs rin, rout;
  153.         struct mbuf *bp;
  154.  
  155.         while (1)
  156.         {
  157.                 if ((bp = alloc_mbuf(1500)) == NULLBUF) return;
  158.  
  159.                 rin.r[0] = ether[iface->dev].port;
  160.                 rin.r[1] = (int)bp->data;
  161.                 rin.r[2] = 1500;
  162.                 _kernel_swi(ETHER_READ, &rin, &rout);
  163.  
  164.                 if (rout.r[4] != ETHER_ERR_OK)
  165.                 {
  166.                        werr(0, "Error %d (%s) when reading from DCI driver", rout.r[4], ether_codes[rout.r[4]]);
  167.                        free_p(bp);
  168.                        return;
  169.                 }
  170.  
  171.                 if ((bp->cnt = rout.r[2]) == 0)
  172.                 {
  173.                        free_p(bp);
  174.                        return;
  175.                 }
  176.  
  177.                 dump(iface, IF_TRACE_IN, TRACE_IP, bp);
  178.                 ip_route(bp, rout.r[3]);
  179.         }
  180.  
  181.         return;
  182. }
  183.  
  184.