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 
00362 
00363 
00364 
00365 
00366 
00367 
00368 
00369 
00370 
00371 
00372 
00373 
00374 
00375 
00376 
00377 
00378 
00379 
00380 
00381 
00382 
00383 
00384 
00385 
00386 
00387 
00388 
00389 
00390 
00391 
00392 
00393 
00394 
00395 
00396 
00397 
00398 
00399 
00400 
00401 
00402 
00403 
00404 
00405 
00406 
00407 
00408 
00409 
00410 
00411 
00412 
00413 
00414 
00415 
00416 
00417 
00418 
00419