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 
00031 
00032 
00033 
00034 
00035 
00036 
00037 
00038 
00039 
00040 
00041 
00042 
00043 
00044 
00045 
00046 
00047 
00048 #include <pci/lnc.h>
00049 #include <sys/io.h>
00050 #include <ubixos/types.h>
00051 #include <sys/idt.h>
00052 #include <sys/gdt.h>
00053 #include <lib/kmalloc.h>
00054 #include <lib/kprintf.h>
00055 #include <sys/video.h>
00056 #include <isa/8259.h>
00057 
00058 struct lncInfo *lnc = 0x0;
00059 
00060 static char const * const nicIdent[] = {
00061   "Unknown",
00062   "BICC",
00063   "NE2100",
00064   "DEPCA",
00065   "CNET98S",      
00066   };
00067 
00068 static char const * const icIdent[] = {
00069   "Unknown",
00070   "LANCE",
00071   "C-LANCE",
00072   "PCnet-ISA",
00073   "PCnet-ISA+",
00074   "PCnet-ISA II",
00075   "PCnet-32 VL-Bus",
00076   "PCnet-PCI",
00077   "PCnet-PCI II",
00078   "PCnet-FAST",
00079   "PCnet-FAST+",
00080   "PCnet-Home",
00081   };  
00082 
00083 void writeCsr(struct lncInfo *lnc, uInt16 port, uInt16 val) {
00084   outportWord(lnc->rap, port);
00085   outportWord(lnc->rdp, val);
00086   }
00087 
00088 uInt16 readCsr(struct lncInfo *lnc, uInt16 port) {
00089   outportWord(lnc->rap, port);
00090   return(inportWord(lnc->rdp));
00091   }
00092 
00093 void writeBcr(struct lncInfo *lnc, uInt16 port, uInt16 val) {
00094   outportWord(lnc->rap, port);
00095   outportWord(lnc->bdp, val);
00096   }
00097 
00098 uInt16 readBcr(struct lncInfo *sc, uInt16 port) {
00099   outportWord(sc->rap, port);
00100   return (inportWord(sc->bdp));
00101   }
00102 
00103 
00104 void initLNC() {
00105   int            i    = 0x0;
00106   lnc = kmalloc(sizeof(struct lncInfo),-2);
00107   
00108   lnc->rap = 0x1000 + PCNET_RAP;
00109   lnc->rdp = 0x1000 + PCNET_RDP;
00110   lnc->bdp = 0x1000 + PCNET_BDP;
00111 
00112   lnc->nic.ic = probe(lnc);
00113   if ((lnc->nic.ic > 0) && (lnc->nic.ic >= PCnet_32)) {
00114     lnc->nic.ident = NE2100;
00115     lnc->nic.memMode = DMA_FIXED;
00116 
00117     lnc->nrdre = NRDRE;
00118     lnc->ntdre = NTDRE;
00119 
00120     
00121     for (i = 0; i < ETHER_ADDR_LEN; i++) {
00122       lnc->arpcom.ac_enaddr[i] = inportByte(0x1000 + i);
00123       kprintf("[0x%X]",lnc->arpcom.ac_enaddr[i]);
00124       }
00125     }
00126   else {
00127     kprintf("LNC Init Error\n");
00128     return;
00129     }
00130   lncAttach(lnc,0);
00131   writeCsr(lnc, CSR3, 0);
00132   writeCsr(lnc, CSR0, INIT);
00133   for (i = 0; i < 1000; i++)
00134     if (readCsr(lnc, CSR0) & IDON)
00135       break;
00136 
00137   if (readCsr(lnc, CSR0) & IDON) {
00138     writeCsr(lnc, CSR0, STRT | INEA);
00139     setVector(_lncInt,mVec+9, (dInt + dPresent + dDpl3));
00140     enableIrq(9);
00141     
00142 
00143 
00144 
00145 
00146     }
00147   else {
00148     kprintf("LNC init Error\n");
00149     return;
00150     }
00151   return;
00152   }
00153 
00154 int probe(struct lncInfo *lnc) {
00155   uInt32 chipId = 0x0;
00156   int    type   = 0x0;
00157 
00158   if ((type = lanceProbe(lnc))) {
00159     chipId = readCsr(lnc, CSR89);
00160     chipId <<= 16;
00161     chipId |= readCsr(lnc, CSR88);
00162     if (chipId & AMD_MASK) {
00163       chipId >>= 12;
00164       switch (chipId & PART_MASK) {
00165         case Am79C960:
00166           return(PCnet_ISA);
00167         case Am79C961:
00168           return (PCnet_ISAplus);
00169         case Am79C961A:
00170           return (PCnet_ISA_II);
00171         case Am79C965:
00172           return (PCnet_32);
00173         case Am79C970:
00174           return (PCnet_PCI);
00175         case Am79C970A:
00176           return (PCnet_PCI_II);
00177         case Am79C971:
00178           return (PCnet_FAST);
00179         case Am79C972:
00180         case Am79C973:
00181           return (PCnet_FASTplus);
00182         case Am79C978:
00183           return (PCnet_Home);
00184         default:
00185           break;
00186         }
00187       }
00188     }
00189   return (type);
00190   }
00191 
00192 int lanceProbe(struct lncInfo *lnc) {
00193   writeCsr(lnc, CSR0, STOP);
00194   if ((inportWord(lnc->rdp) & STOP) && !(readCsr(lnc, CSR3))) {
00195     writeCsr(lnc, CSR0, INEA);
00196     if (readCsr(lnc, CSR0) & INEA) {
00197       return(C_LANCE);
00198       }
00199     else {
00200       return(LANCE);
00201       }
00202     }
00203   else {
00204     return(UNKNOWN);
00205     }
00206   }
00207 
00208 void lncInt() {
00209   uInt16 csr0 = 0x0;
00210   while ((csr0 = inportWord(lnc->rdp)) & INTR) {
00211     outportWord(lnc->rdp, csr0);
00212     kprintf("CSR0: [0x%X]\n",csr0);
00213     if (csr0 & ERR) {
00214       kprintf("Error: [0x%X]\n",csr0);
00215       }
00216     if (csr0 & RINT) {
00217       kprintf("RINT\n");
00218       }
00219     if (csr0 & TINT) {
00220       kprintf("TINT\n");
00221       }
00222     }
00223   kprintf("Finished!!!\n");
00224   outportByte(0x20,0x20);
00225   return;
00226   }
00227 
00228 asm(
00229     ".global _lncInt     \n"
00230     "_lncInt   :         \n"
00231 
00232   "  pusha                \n" 
00233   "  pushw %ds            \n" 
00234   "  pushw %es            \n"
00235   "  pushw %ss            \n" 
00236   "  pushw %ss            \n"
00237   "  popw %ds             \n"
00238   "  popw %es             \n"
00239   "  call lncInt \n"
00240   "  popw %es             \n"
00241   "  popw %ds             \n" 
00242   "  popa                 \n"
00243   "  iret                 \n"     
00244     );
00245 
00246 int lncAttach(struct lncInfo *lnc,int unit) {
00247   int lncMemSize = 0x0;
00248 
00249   lncMemSize = ((NDESC(lnc->nrdre) + NDESC(lnc->ntdre)) * sizeof(struct hostRingEntry));
00250 
00251   if (lnc->nic.memMode != SHMEM)
00252     lncMemSize += sizeof(struct initBlock) + (sizeof(struct mds) * (NDESC(lnc->nrdre) + NDESC(lnc->ntdre))) + MEM_SLEW;
00253 
00254   if (lnc->nic.memMode == DMA_FIXED)
00255     lncMemSize += (NDESC(lnc->nrdre) * RECVBUFSIZE) + (NDESC(lnc->ntdre) * TRANSBUFSIZE);
00256 
00257   if (lnc->nic.memMode != SHMEM) {
00258     if (lnc->nic.ic < PCnet_32) {
00259       
00260       kprintf("ISA Board\n");
00261       
00262       }
00263     else {
00264       
00265 
00266 
00267 
00268       
00269       lnc->recvRing = kmalloc(lncMemSize,-2);
00270       kprintf("PCI Board\n");
00271       }      
00272     }
00273 
00274   if (!lnc->recvRing) {
00275     kprintf("lnc%d: Couldn't allocate memory for NIC\n", unit);
00276     return (0);
00277     }
00278 
00279   lnc->nic.mode = NORMAL;
00280 
00281   
00282   
00283 
00284 
00285 
00286 
00287 
00288 
00289 
00290 
00291 
00292 
00293 
00294 
00295 
00296 
00297 
00298 
00299   
00300 
00301   kprintf("lnc%d: ", unit);
00302   if (lnc->nic.ic == LANCE || lnc->nic.ic == C_LANCE)
00303     kprintf("%s (%s)",nicIdent[lnc->nic.ident], icIdent[lnc->nic.ic]);
00304   else
00305     kprintf("%s", icIdent[lnc->nic.ic]);
00306   kprintf(" address 0x%X\n", lnc->arpcom.ac_enaddr);   
00307   return(1);
00308   }
00309 
00310 
00311 
00312 
00313