lnc.c

Go to the documentation of this file.
00001 /*****************************************************************************************
00002  Copyright (c) 2002 The UbixOS Project
00003  All rights reserved.
00004 
00005 Redistribution and use in source and binary forms, with or without modification, are
00006 permitted provided that the following conditions are met:
00007 
00008 Redistributions of source code must retain the above copyright notice, this list of
00009 conditions, the following disclaimer and the list of authors.  Redistributions in binary
00010 form must reproduce the above copyright notice, this list of conditions, the following
00011 disclaimer and the list of authors in the documentation and/or other materials provided
00012 with the distribution. Neither the name of the UbixOS Project nor the names of its
00013 contributors may be used to endorse or promote products derived from this software
00014 without specific prior written permission.
00015 
00016 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
00017 EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
00018 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
00019 THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
00020 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
00021 OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00022 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
00023 TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00024 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00025 
00026  $Log: lnc_8c-source.html,v $
00026  Revision 1.7  2006/12/15 17:47:06  reddawg
00026  Updates
00026 
00027  Revision 1.1.1.1  2006/06/01 12:46:16  reddawg
00028  ubix2
00029 
00030  Revision 1.2  2005/10/12 00:13:37  reddawg
00031  Removed
00032 
00033  Revision 1.1.1.1  2005/09/26 17:24:35  reddawg
00034  no message
00035 
00036  Revision 1.1.1.1  2004/04/15 12:07:15  reddawg
00037  UbixOS v1.0
00038 
00039  Revision 1.4  2004/04/13 16:36:33  reddawg
00040  Changed our copyright, it is all now under a BSD-Style license
00041 
00042 
00043 
00044  $Id: lnc_8c-source.html 88 2016-01-12 00:11:29Z reddawg $
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",      /* PC-98 */
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     /* Extract MAC address from PROM */
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      * sc->arpcom.ac_if.if_flags |= IFF_RUNNING;
00143      * sc->arpcom.ac_if.if_flags &= ~IFF_OACTIVE;
00144      * lnc_start(&sc->arpcom.ac_if);
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" /* Save all registers           */
00233   "  pushw %ds            \n" /* Set up the data segment      */
00234   "  pushw %es            \n"
00235   "  pushw %ss            \n" /* Note that ss is always valid */
00236   "  pushw %ss            \n"
00237   "  popw %ds             \n"
00238   "  popw %es             \n"
00239   "  call lncInt \n"
00240   "  popw %es             \n"
00241   "  popw %ds             \n" /* Restore registers            */
00242   "  popa                 \n"
00243   "  iret                 \n" /* Exit interrupt               */    
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       /* ISA based cards */
00260       kprintf("ISA Board\n");
00261       /* sc->recv_ring = contigmalloc(lnc_mem_size, M_DEVBUF, M_NOWAIT,0ul, 0xfffffful, 4ul, 0x1000000); */
00262       }
00263     else {
00264       /*
00265       * For now it still needs to be below 16MB because the
00266       * descriptor's can only hold 16 bit addresses.
00267       */
00268       /* sc->recv_ring = contigmalloc(lnc_mem_size, M_DEVBUF, M_NOWAIT,0ul, 0xfffffful, 4ul, 0x1000000); */
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   /* Fill in arpcom structure entries */
00282   /*
00283   lnc->arpcom.ac_if.if_softc = sc;
00284   lnc->arpcom.ac_if.if_name = lncdriver.name;
00285   lnc->arpcom.ac_if.if_unit = unit;
00286   lnc->arpcom.ac_if.if_mtu = ETHERMTU;
00287   lnc->arpcom.ac_if.if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
00288   lnc->arpcom.ac_if.if_timer = 0;
00289   lnc->arpcom.ac_if.if_output = ether_output;
00290   lnc->arpcom.ac_if.if_start = lnc_start;
00291   lnc->arpcom.ac_if.if_ioctl = lnc_ioctl;
00292   lnc->arpcom.ac_if.if_watchdog = lnc_watchdog;
00293   lnc->arpcom.ac_if.if_init = lnc_init;
00294   lnc->arpcom.ac_if.if_type = IFT_ETHER;
00295   lnc->arpcom.ac_if.if_addrlen = ETHER_ADDR_LEN;
00296   lnc->arpcom.ac_if.if_hdrlen = ETHER_HDR_LEN;
00297   lnc->arpcom.ac_if.if_snd.ifq_maxlen = IFQ_MAXLEN;
00298   */
00299   /* ether_ifattach(&sc->arpcom.ac_if, ETHER_BPF_SUPPORTED); */
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  END
00312  ***/
00313 

Generated on Fri Dec 15 11:18:55 2006 for UbixOS V2 by  doxygen 1.4.7