00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 #include <isa/ne2k.h>
00031 #include <isa/8259.h>
00032 #include <sys/device.old.h>
00033 #include <sys/io.h>
00034 #include <sys/idt.h>
00035 #include <lib/kmalloc.h>
00036 #include <lib/kprintf.h>
00037 #include <string.h>
00038 #include <ubixos/kpanic.h>
00039 #include <ubixos/vitals.h>
00040 #include <ubixos/spinlock.h>
00041 #include <assert.h>
00042 
00043 
00044 static spinLock_t ne2k_spinLock = SPIN_LOCK_INITIALIZER;
00045 
00046 static int dp_pkt2user(struct device *dev,int page,int length);
00047 static void getblock(struct device *dev,int page,size_t offset,size_t size,void *dst);
00048 static int dp_recv(struct device *);
00049 
00050 static struct nicBuffer *ne2kBuffer = 0x0;
00051 static struct device    *mDev        = 0x0;
00052 
00053 asm(
00054   ".globl ne2kISR         \n"
00055   "ne2kISR:               \n"
00056   "  pusha                \n" 
00057   "  call ne2kHandler     \n"
00058   "  popa                 \n"
00059   "  iret                 \n" 
00060   );
00061 
00062 
00063 
00064 
00065 
00066 
00067 
00068 
00069 
00070 int ne2k_init() {
00071   mDev = (struct device *)kmalloc(sizeof(struct device));
00072   mDev->ioAddr = 0x280;
00073   mDev->irq    = 10;
00074   setVector(&ne2kISR, mVec+10, dPresent + dInt + dDpl0);
00075   irqEnable(10);
00076 
00077 
00078   outportByte(mDev->ioAddr + NE_CMD, 0x21);        
00079   outportByte(mDev->ioAddr + NE_DCR,0x29);         
00080   outportByte(mDev->ioAddr + NE_RBCR0,0x00);       
00081   outportByte(mDev->ioAddr + NE_RBCR1,0x00);       
00082   outportByte(mDev->ioAddr + NE_RCR,0x3C);         
00083   outportByte(mDev->ioAddr + NE_TCR,0x02);         
00084   outportByte(mDev->ioAddr + NE_PSTART,startPage); 
00085   outportByte(mDev->ioAddr + NE_BNRY,startPage);   
00086   outportByte(mDev->ioAddr + NE_PSTOP,stopPage);   
00087   outportByte(mDev->ioAddr + NE_ISR,0xFF);         
00088   outportByte(mDev->ioAddr + NE_IMR,0x0B);
00089   outportByte(mDev->ioAddr + NE_CMD,0x61);         
00090 
00091   outportByte(mDev->ioAddr + DP_MAR0, 0xFF);
00092   outportByte(mDev->ioAddr + DP_MAR1, 0xFF);
00093   outportByte(mDev->ioAddr + DP_MAR2, 0xFF);
00094   outportByte(mDev->ioAddr + DP_MAR3, 0xFF);
00095   outportByte(mDev->ioAddr + DP_MAR4, 0xFF);
00096   outportByte(mDev->ioAddr + DP_MAR5, 0xFF);
00097   outportByte(mDev->ioAddr + DP_MAR6, 0xFF);
00098   outportByte(mDev->ioAddr + DP_MAR7, 0xFF);
00099   outportByte(mDev->ioAddr + DP_CURR, startPage + 1);
00100   outportByte(mDev->ioAddr + NE_CMD,  0x20);
00101   inportByte(mDev->ioAddr + DP_CNTR0);                
00102   inportByte(mDev->ioAddr + DP_CNTR1);
00103   inportByte(mDev->ioAddr + DP_CNTR2);
00104 
00105   outportByte(mDev->ioAddr + NE_TCR,  0x00);
00106 
00107   outportByte(mDev->ioAddr + NE_CMD, 0x0);
00108   outportByte(mDev->ioAddr + NE_DCR, 0x29);
00109 
00110   kprintf("Initialized");
00111   
00112   return(0x0);
00113   }
00114 
00115 int PCtoNIC(struct device *dev,void *packet,int length) {
00116   int     i        = 0x0;
00117   uInt16 *packet16 = (uInt16 *)packet;
00118   uInt8  *packet8  = (uInt8  *)packet;
00119   uInt8   word16   = 0x1;
00120 
00121   if ((inportByte(dev->ioAddr) & 0x04) == 0x04) {
00122     kpanic("Device Not Ready\n");
00123     }
00124 
00125   assert(length);
00126   if ((word16 == 1) && (length & 0x01)) {
00127     length++;
00128     }
00129 
00130   outportByte(dev->ioAddr+EN0_RCNTLO,(length & 0xFF));
00131   outportByte(dev->ioAddr+EN0_RCNTHI,(length >> 8));
00132 
00133   outportByte(dev->ioAddr+EN0_RSARLO,0x0);
00134   outportByte(dev->ioAddr+EN0_RSARHI,0x41);
00135 
00136   outportByte(dev->ioAddr,E8390_RWRITE+E8390_START);
00137 
00138   if (word16 != 0x0) {
00139     for(i=0;i<length/2;i++){
00140       outportWord(dev->ioAddr + NE_DATAPORT,packet16[i]);
00141       }
00142     }
00143   else {
00144     for(i=0;i<length;i++){
00145       outportByte(dev->ioAddr + NE_DATAPORT,packet8[i]);
00146       }
00147     }
00148   
00149   for (i = 0;i<=100;i++) {
00150     if ((inportByte(dev->ioAddr+EN0_ISR) & 0x40) == 0x40) {
00151       break;
00152       }
00153     }
00154 
00155   outportByte(dev->ioAddr+EN0_ISR,0x40);
00156   outportByte(dev->ioAddr+EN0_TPSR,0x41);
00157   outportByte(dev->ioAddr+0x05,(length & 0xFF));
00158   outportByte(dev->ioAddr+0x06,(length >> 8));
00159   outportByteP(dev->ioAddr,0x26);
00160   
00161   return(length);
00162   }
00163 
00164 int NICtoPC(struct device *dev,void *packet,int length,int nic_addr) {
00165   int i = 0x0;
00166   uInt16 *packet16 = (uInt16 *)packet;
00167 
00168   assert(length);
00169   
00170   if (length & 0x01)
00171     length++;
00172 
00173    
00174 
00175   outportByte(dev->ioAddr+EN0_RCNTLO,(length & 0xFF));
00176   outportByte(dev->ioAddr+EN0_RCNTHI,(length >> 8));
00177 
00178   outportByte(dev->ioAddr+EN0_RSARLO,nic_addr & 0xFF);
00179   outportByte(dev->ioAddr+EN0_RSARHI,nic_addr >> 8);
00180 
00181   outportByte(dev->ioAddr,0x0A);
00182 
00183   for(i=0;i<length/2;i++){
00184     packet16[i] = inportWord(dev->ioAddr + NE_DATAPORT);
00185     }
00186 
00187   outportByte(dev->ioAddr+EN0_ISR,0x40);
00188   return(length);
00189   }
00190 
00191 void ne2kHandler() {
00192   uInt16 isr    = 0x0;
00193   uInt16 status = 0x0;
00194   
00195   irqDisable(10);
00196   outportByte(mPic, eoi);
00197   outportByte(sPic, eoi);
00198   
00199   asm("sti");
00200 
00201   isr = inportByte(mDev->ioAddr + NE_ISR);
00202   
00203   if ((isr & 0x02) == 0x02) {
00204     outportByte(mDev->ioAddr + NE_ISR, 0x0A);
00205     status = inportByte(0x280 + NE_TPSR);
00206     } 
00207   if ((isr & 0x01) == 0x01) {
00208     if (dp_recv(mDev)) {
00209       kprintf("Error Getting Packet\n");
00210       }
00211     outportByte(mDev->ioAddr + NE_ISR, 0x05);
00212     }
00213     
00214   outportByte(mDev->ioAddr + NE_IMR,0x0);
00215   outportByte(mDev->ioAddr + NE_IMR,0x0B);
00216   
00217   asm("cli");
00218   irqEnable(10);
00219 
00220   return;
00221   }
00222 
00223 static int dp_recv(struct device *dev) {
00224   dp_rcvhdr_t header;
00225   unsigned int pageno = 0x0, curr = 0x0, next = 0x0;
00226   int packet_processed = 0x0, r = 0x0;
00227   uInt16 eth_type = 0x0;  
00228 
00229   uInt32 length = 0x0;
00230 
00231   pageno = inportByte(dev->ioAddr + NE_BNRY) + 1;
00232   if (pageno == stopPage) pageno = startPage;
00233 
00234   do {
00235     outportByte(dev->ioAddr + NE_CMD, 0x40);
00236     curr = inportByte(dev->ioAddr + NE_CURRENT);
00237     outportByte(dev->ioAddr, 0x0);
00238     if (curr == pageno) break;
00239     getblock(dev, pageno, (size_t)0, sizeof(header), &header);
00240     getblock(dev, pageno, sizeof(header) + 2*sizeof(ether_addr_t), sizeof(eth_type), ð_type);
00241 
00242     length = (header.dr_rbcl | (header.dr_rbch << 8)) - sizeof(dp_rcvhdr_t);
00243     next = header.dr_next;
00244 
00245     
00246 
00247     if (length < 60 || length > 1514) {
00248       kprintf("dp8390: packet with strange length arrived: %d\n",length);
00249       next= curr;
00250       }
00251     else if (next < startPage || next >= stopPage) {
00252       kprintf("dp8390: strange next page\n");
00253       next= curr;
00254       }
00255     else if (header.dr_status & RSR_FO) {
00256       kpanic("dp8390: fifo overrun, resetting receive buffer\n");
00257       next = curr;
00258       }
00259     else if (header.dr_status & RSR_PRX) {
00260       r = dp_pkt2user(dev, pageno, length);
00261       if (r != OK) {
00262         kprintf("FRUIT");
00263         return(0x0);
00264         }
00265 
00266       packet_processed = 0x1;
00267       }
00268     if (next == startPage)
00269       outportByte(dev->ioAddr + NE_BNRY, stopPage - 1);
00270     else
00271       outportByte(dev->ioAddr + NE_BNRY, next - 1);
00272 
00273     pageno = next;
00274 
00275     } while (packet_processed == 0x0);
00276   return(0x0);
00277   }
00278 
00279 static void getblock(struct device *dev,int page,size_t offset,size_t size,void *dst) {
00280         uInt16 *ha = 0x0;
00281         int i      = 0x0;
00282 
00283         ha = (uInt16 *) dst;
00284         offset = page * DP_PAGESIZE + offset;
00285         outportByte(dev->ioAddr + NE_RBCR0, size & 0xFF);
00286         outportByte(dev->ioAddr + NE_RBCR1, size >> 8);
00287         outportByte(dev->ioAddr + EN0_RSARLO, offset & 0xFF);
00288         outportByte(dev->ioAddr + EN0_RSARHI, offset >> 8);
00289         outportByte(dev->ioAddr + NE_CMD, E8390_RREAD | E8390_START);
00290 
00291         size /= 2;
00292         for (i= 0; i<size; i++)
00293                 ha[i]= inportWord(dev->ioAddr + NE_DATAPORT);
00294   outportByte(dev->ioAddr+EN0_ISR,0x40);
00295   }
00296   
00297 static int dp_pkt2user(struct device *dev,int page,int length) {
00298   int last = 0x0;
00299   struct nicBuffer *tmpBuf = 0x0;
00300  
00301   last = page + (length - 1) / DP_PAGESIZE;
00302 
00303   if (last >= stopPage) {
00304     kprintf("FOOK STOP PAGE!!!");
00305     }
00306   else {
00307     tmpBuf = ne2kAllocBuffer(length);
00308     NICtoPC(dev,tmpBuf->buffer,length,page * DP_PAGESIZE + sizeof(dp_rcvhdr_t));
00309     }
00310   return(OK);
00311   }
00312 
00313 struct nicBuffer *ne2kAllocBuffer(int length) {
00314   struct nicBuffer *tmpBuf = 0x0;
00315   
00316   spinLock(&ne2k_spinLock);
00317   
00318   if (ne2kBuffer == 0x0) {
00319     ne2kBuffer = (struct nicBuffer *)kmalloc(sizeof(struct nicBuffer));
00320     ne2kBuffer->next   = 0x0;
00321     ne2kBuffer->length = length;
00322     ne2kBuffer->buffer = (char *)kmalloc(length);
00323     spinUnlock(&ne2k_spinLock);
00324     return(ne2kBuffer);
00325     }
00326   else {
00327     for (tmpBuf = ne2kBuffer;tmpBuf->next != 0x0;tmpBuf = tmpBuf->next);
00328     
00329     tmpBuf->next   = (struct nicBuffer *)kmalloc(sizeof(struct nicBuffer));
00330     tmpBuf         = tmpBuf->next;
00331     tmpBuf->next   = 0x0;
00332     tmpBuf->length = length;
00333     tmpBuf->buffer = (char *)kmalloc(length);
00334     spinUnlock(&ne2k_spinLock);
00335     return(tmpBuf);
00336     }
00337   spinUnlock(&ne2k_spinLock);
00338   return(0x0);
00339   }
00340 
00341 struct nicBuffer *ne2kGetBuffer() {
00342   struct nicBuffer *tmpBuf = 0x0;
00343   
00344   if (ne2k_spinLock == 0x1)
00345     return(0x0);
00346     
00347   tmpBuf     = ne2kBuffer;
00348   if (ne2kBuffer != 0x0)
00349     ne2kBuffer = ne2kBuffer->next;
00350   return(tmpBuf);
00351   }
00352 
00353 void ne2kFreeBuffer(struct nicBuffer *buf) {
00354   kfree(buf->buffer);
00355   kfree(buf);
00356   return;
00357   }
00358 
00359 
00360 
00361