ne2k.c
isa/ne2k.h
isa/8259.h
sys/device.old.h
sys/io.h
sys/idt.h
lib/kmalloc.h
lib/kprintf.h
string.h
ubixos/kpanic.h
ubixos/vitals.h
ubixos/spinlock.h
assert.h
sys/thread.h
ubixos/kpanic.h
ubixos/sched.h
ubixos/spinlock.h
sys/device.old.h
isa/ne2k.h
ubixos/vitals.h
ubixos/types.h
sys/_types.h
string.h
ubixos/time.h
vfs/file.h
sys/tss.h
lib/kmalloc.h
sys/idt.h
vfs/vfs.h
vfs/mount.h
lib/kprintf.h
sys/gdt.h
assert.h
ubixos/ubthread.h
ubixfs/dirCache.h
src/sys/isa/ne2k.c
sys/sysproto.h
sys/signal.h
ubixos/tty.h
sys/io.h
isa/8259.h
asm
(".globl ne2kISR \n""ne2kISR: \n"" pusha \n"" call ne2kHandler \n"" popa \n"" iret \n")
asm
".globl ne2kISR \n""ne2kISR: \n"" pusha \n"" call ne2kHandler \n"" popa \n"" iret \n"
int static int dp_pkt2user (struct device *dev, int page, int length) dp_pkt2user struct device * dev int page int length nicBuffer::buffer DP_PAGESIZE kprintf ne2kAllocBuffer NICtoPC OK stopPage dp_recv
int static int dp_recv (struct device *) dp_recv struct device * dev dp_pkt2user getblock inportByte device::ioAddr kpanic kprintf NE_BNRY NE_CMD NE_CURRENT OK outportByte RSR_FO RSR_PRX startPage stopPage ne2kHandler
void static void getblock (struct device *dev, int page, size_t offset, size_t size, void *dst) getblock struct device * dev int page size_t offset size_t size void * dst DP_PAGESIZE E8390_RREAD E8390_START EN0_ISR EN0_RSARHI EN0_RSARLO inportWord device::ioAddr NE_CMD NE_DATAPORT NE_RBCR0 NE_RBCR1 outportByte dp_recv
int int ne2k_init () ne2k_init dDpl0 dInt DP_CNTR0 DP_CNTR1 DP_CNTR2 DP_CURR DP_MAR0 DP_MAR1 DP_MAR2 DP_MAR3 DP_MAR4 DP_MAR5 DP_MAR6 DP_MAR7 dPresent inportByte device::ioAddr device::irq irqEnable kmalloc kprintf mDev mVec ne2kISR NE_BNRY NE_CMD NE_DCR NE_IMR NE_ISR NE_PSTART NE_PSTOP NE_RBCR0 NE_RBCR1 NE_RCR NE_TCR outportByte setVector startPage stopPage x20
nicBuffer * struct nicBuffer* ne2kAllocBuffer (int length) ne2kAllocBuffer int length nicBuffer::buffer kmalloc nicBuffer::length ne2k_spinLock ne2kBuffer nicBuffer::next spinLock spinUnlock dp_pkt2user
void void ne2kFreeBuffer (struct nicBuffer *buf) ne2kFreeBuffer struct nicBuffer * buf nicBuffer::buffer kfree
nicBuffer * struct nicBuffer* ne2kGetBuffer () ne2kGetBuffer ne2k_spinLock ne2kBuffer nicBuffer::next x1
void void ne2kHandler () ne2kHandler dp_recv eoi inportByte device::ioAddr irqDisable irqEnable kprintf mDev mPic NE_IMR NE_ISR NE_TPSR outportByte sPic status
int int NICtoPC (struct device *dev, void *packet, int length, int nic_addr) NICtoPC struct device * dev void * packet int length int nic_addr assert EN0_ISR EN0_RCNTHI EN0_RCNTLO EN0_RSARHI EN0_RSARLO inportWord device::ioAddr NE_DATAPORT outportByte dp_pkt2user
int int PCtoNIC (struct device *dev, void *packet, int length) PCtoNIC struct device * dev void * packet int length assert E8390_RWRITE E8390_START EN0_ISR EN0_RCNTHI EN0_RCNTLO EN0_RSARHI EN0_RSARLO inportByte device::ioAddr kpanic NE_DATAPORT outportByte outportWord
struct device * struct device* mDev mDev 0x0 ne2k_init ne2kHandler
spinLock_t spinLock_t ne2k_spinLock ne2k_spinLock SPIN_LOCK_INITIALIZER ne2kAllocBuffer ne2kGetBuffer
struct nicBuffer * struct nicBuffer* ne2kBuffer ne2kBuffer 0x0 ne2kAllocBuffer ne2kGetBuffer

    /*****************************************************************************************
    Copyright(c)2002-2004TheUbixOSProject
    Allrightsreserved.

    Redistributionanduseinsourceandbinaryforms,withorwithoutmodification,are
    permittedprovidedthatthefollowingconditionsaremet:

    Redistributionsofsourcecodemustretaintheabovecopyrightnotice,thislistof
    conditions,thefollowingdisclaimerandthelistofauthors.Redistributionsinbinary
    formmustreproducetheabovecopyrightnotice,thislistofconditions,thefollowing
    disclaimerandthelistofauthorsinthedocumentationand/orothermaterialsprovided
    withthedistribution.NeitherthenameoftheUbixOSProjectnorthenamesofits
    contributorsmaybeusedtoendorseorpromoteproductsderivedfromthissoftware
    withoutspecificpriorwrittenpermission.

    THISSOFTWAREISPROVIDEDBYTHECOPYRIGHTHOLDERSANDCONTRIBUTORS"ASIS"ANDANY
    EXPRESSORIMPLIEDWARRANTIES,INCLUDING,BUTNOTLIMITEDTO,THEIMPLIEDWARRANTIESOF
    MERCHANTABILITYANDFITNESSFORAPARTICULARPURPOSEAREDISCLAIMED.INNOEVENTSHALL
    THECOPYRIGHTOWNERORCONTRIBUTORSBELIABLEFORANYDIRECT,INDIRECT,INCIDENTAL,
    SPECIAL,EXEMPLARY,ORCONSEQUENTIALDAMAGES(INCLUDING,BUTNOTLIMITEDTO,PROCUREMENT
    OFSUBSTITUTEGOODSORSERVICES;LOSSOFUSE,DATA,ORPROFITS;ORBUSINESSINTERRUPTION)
    HOWEVERCAUSEDANDONANYTHEORYOFLIABILITY,WHETHERINCONTRACT,STRICTLIABILITY,OR
    TORT(INCLUDINGNEGLIGENCEOROTHERWISE)ARISINGINANYWAYOUTOFTHEUSEOFTHIS
    SOFTWARE,EVENIFADVISEDOFTHEPOSSIBILITYOFSUCHDAMAGE.

    $Id: ne2k_8c.xml 88 2016-01-12 00:11:29Z reddawg $

    *****************************************************************************************/

    #include<isa/ne2k.h>
    #include<isa/8259.h>
    #include<sys/device.old.h>
    #include<sys/io.h>
    #include<sys/idt.h>
    #include<lib/kmalloc.h>
    #include<lib/kprintf.h>
    #include<string.h>
    #include<ubixos/kpanic.h>
    #include<ubixos/vitals.h>
    #include<ubixos/spinlock.h>
    #include<assert.h>

    staticspinLock_tne2k_spinLock=SPIN_LOCK_INITIALIZER;

    staticintdp_pkt2user(structdevice*dev,intpage,intlength);
    staticvoidgetblock(structdevice*dev,intpage,size_toffset,size_tsize,void*dst);
    staticintdp_recv(structdevice*);

    staticstructnicBuffer*ne2kBuffer=0x0;
    staticstructdevice*mDev=0x0;

    asm(
    ".globlne2kISR\n"
    "ne2kISR:\n"
    "pusha\n"/*Saveallregisters*/
    "callne2kHandler\n"
    "popa\n"
    "iret\n"/*Exitinterrupt*/
    );

    /************************************************************************

    Function:intne2kInit(uInt32ioAddr)
    Description:ThisFunctionWillInitializeTheProgrammableTimer

    Notes:

    ************************************************************************/
    intne2k_init(){
    mDev=(structdevice*)kmalloc(sizeof(structdevice));
    mDev->ioAddr=0x280;
    mDev->irq=10;
    setVector(&ne2kISR,mVec+10,dPresent+dInt+dDpl0);
    irqEnable(10);
    //kprintf("ne0-irq:%i,ioAddr:0x%XMAC:%X:%X:%X:%X:%X:%X\n",dev->irq,dev->ioAddr,dev->net->mac[0]&0xFF,dev->net->mac[1]&0xFF,dev->net->mac[2]&0xFF,dev->net->mac[3]&0xFF,dev->net->mac[4]&0xFF,dev->net->mac[5]&0xFF);

    outportByte(mDev->ioAddr+NE_CMD,0x21);//stopmode
    outportByte(mDev->ioAddr+NE_DCR,0x29);//0x29dataconfigreg
    outportByte(mDev->ioAddr+NE_RBCR0,0x00);//LOWbytecount(remote)
    outportByte(mDev->ioAddr+NE_RBCR1,0x00);//HIGHbytecount(remote)
    outportByte(mDev->ioAddr+NE_RCR,0x3C);//receiveconfigreg
    outportByte(mDev->ioAddr+NE_TCR,0x02);//LOOPmode(temp)
    outportByte(mDev->ioAddr+NE_PSTART,startPage);//0x26PAGEstart
    outportByte(mDev->ioAddr+NE_BNRY,startPage);//0x26BOUNDARY
    outportByte(mDev->ioAddr+NE_PSTOP,stopPage);//0x40PAGEstop
    outportByte(mDev->ioAddr+NE_ISR,0xFF);//interruptstatusreg
    outportByte(mDev->ioAddr+NE_IMR,0x0B);
    outportByte(mDev->ioAddr+NE_CMD,0x61);//PAGE1regs

    outportByte(mDev->ioAddr+DP_MAR0,0xFF);
    outportByte(mDev->ioAddr+DP_MAR1,0xFF);
    outportByte(mDev->ioAddr+DP_MAR2,0xFF);
    outportByte(mDev->ioAddr+DP_MAR3,0xFF);
    outportByte(mDev->ioAddr+DP_MAR4,0xFF);
    outportByte(mDev->ioAddr+DP_MAR5,0xFF);
    outportByte(mDev->ioAddr+DP_MAR6,0xFF);
    outportByte(mDev->ioAddr+DP_MAR7,0xFF);
    outportByte(mDev->ioAddr+DP_CURR,startPage+1);
    outportByte(mDev->ioAddr+NE_CMD,0x20);
    inportByte(mDev->ioAddr+DP_CNTR0);/*resetcountersbyreading*/
    inportByte(mDev->ioAddr+DP_CNTR1);
    inportByte(mDev->ioAddr+DP_CNTR2);

    outportByte(mDev->ioAddr+NE_TCR,0x00);

    outportByte(mDev->ioAddr+NE_CMD,0x0);
    outportByte(mDev->ioAddr+NE_DCR,0x29);

    kprintf("Initialized");
    /*Returnsoweknoweverythingwentwell*/
    return(0x0);
    }

    intPCtoNIC(structdevice*dev,void*packet,intlength){
    inti=0x0;
    uInt16*packet16=(uInt16*)packet;
    uInt8*packet8=(uInt8*)packet;
    uInt8word16=0x1;

    if((inportByte(dev->ioAddr)&0x04)==0x04){
    kpanic("DeviceNotReady\n");
    }

    assert(length);
    if((word16==1)&&(length&0x01)){
    length++;
    }

    outportByte(dev->ioAddr+EN0_RCNTLO,(length&0xFF));
    outportByte(dev->ioAddr+EN0_RCNTHI,(length>>8));

    outportByte(dev->ioAddr+EN0_RSARLO,0x0);
    outportByte(dev->ioAddr+EN0_RSARHI,0x41);

    outportByte(dev->ioAddr,E8390_RWRITE+E8390_START);

    if(word16!=0x0){
    for(i=0;i<length/2;i++){
    outportWord(dev->ioAddr+NE_DATAPORT,packet16[i]);
    }
    }
    else{
    for(i=0;i<length;i++){
    outportByte(dev->ioAddr+NE_DATAPORT,packet8[i]);
    }
    }

    for(i=0;i<=100;i++){
    if((inportByte(dev->ioAddr+EN0_ISR)&0x40)==0x40){
    break;
    }
    }

    outportByte(dev->ioAddr+EN0_ISR,0x40);
    outportByte(dev->ioAddr+EN0_TPSR,0x41);//ei_local->txStartPage);
    outportByte(dev->ioAddr+0x05,(length&0xFF));
    outportByte(dev->ioAddr+0x06,(length>>8));
    outportByteP(dev->ioAddr,0x26);
    //kprintf("SENT\n");
    return(length);
    }

    intNICtoPC(structdevice*dev,void*packet,intlength,intnic_addr){
    inti=0x0;
    uInt16*packet16=(uInt16*)packet;

    assert(length);

    if(length&0x01)
    length++;

    outportByte(dev->ioAddr+EN0_RCNTLO,(length&0xFF));
    outportByte(dev->ioAddr+EN0_RCNTHI,(length>>8));

    outportByte(dev->ioAddr+EN0_RSARLO,nic_addr&0xFF);
    outportByte(dev->ioAddr+EN0_RSARHI,nic_addr>>8);

    outportByte(dev->ioAddr,0x0A);

    for(i=0;i<length/2;i++){
    packet16[i]=inportWord(dev->ioAddr+NE_DATAPORT);
    }

    outportByte(dev->ioAddr+EN0_ISR,0x40);
    return(length);
    }

    voidne2kHandler(){
    uInt16isr=0x0;
    uInt16status=0x0;

    irqDisable(10);
    outportByte(mPic,eoi);
    outportByte(sPic,eoi);

    asm("sti");

    isr=inportByte(mDev->ioAddr+NE_ISR);

    if((isr&0x02)==0x02){
    outportByte(mDev->ioAddr+NE_ISR,0x0A);
    status=inportByte(0x280+NE_TPSR);
    }
    if((isr&0x01)==0x01){
    if(dp_recv(mDev)){
    kprintf("ErrorGettingPacket\n");
    }
    outportByte(mDev->ioAddr+NE_ISR,0x05);
    }

    outportByte(mDev->ioAddr+NE_IMR,0x0);
    outportByte(mDev->ioAddr+NE_IMR,0x0B);

    asm("cli");
    irqEnable(10);

    return;
    }

    staticintdp_recv(structdevice*dev){
    dp_rcvhdr_theader;
    unsignedintpageno=0x0,curr=0x0,next=0x0;
    intpacket_processed=0x0,r=0x0;
    uInt16eth_type=0x0;

    uInt32length=0x0;

    pageno=inportByte(dev->ioAddr+NE_BNRY)+1;
    if(pageno==stopPage)pageno=startPage;

    do{
    outportByte(dev->ioAddr+NE_CMD,0x40);
    curr=inportByte(dev->ioAddr+NE_CURRENT);
    outportByte(dev->ioAddr,0x0);
    if(curr==pageno)break;
    getblock(dev,pageno,(size_t)0,sizeof(header),&header);
    getblock(dev,pageno,sizeof(header)+2*sizeof(ether_addr_t),sizeof(eth_type),&eth_type);

    length=(header.dr_rbcl|(header.dr_rbch<<8))-sizeof(dp_rcvhdr_t);
    next=header.dr_next;

    //kprintf("length:[0x%X:0x%X:0x%X]\n",header.dr_next,header.dr_status,length);

    if(length<60||length>1514){
    kprintf("dp8390:packetwithstrangelengtharrived:%d\n",length);
    next=curr;
    }
    elseif(next<startPage||next>=stopPage){
    kprintf("dp8390:strangenextpage\n");
    next=curr;
    }
    elseif(header.dr_status&RSR_FO){
    kpanic("dp8390:fifooverrun,resettingreceivebuffer\n");
    next=curr;
    }
    elseif(header.dr_status&RSR_PRX){
    r=dp_pkt2user(dev,pageno,length);
    if(r!=OK){
    kprintf("FRUIT");
    return(0x0);
    }

    packet_processed=0x1;
    }
    if(next==startPage)
    outportByte(dev->ioAddr+NE_BNRY,stopPage-1);
    else
    outportByte(dev->ioAddr+NE_BNRY,next-1);

    pageno=next;

    }while(packet_processed==0x0);
    return(0x0);
    }

    staticvoidgetblock(structdevice*dev,intpage,size_toffset,size_tsize,void*dst){
    uInt16*ha=0x0;
    inti=0x0;

    ha=(uInt16*)dst;
    offset=page*DP_PAGESIZE+offset;
    outportByte(dev->ioAddr+NE_RBCR0,size&0xFF);
    outportByte(dev->ioAddr+NE_RBCR1,size>>8);
    outportByte(dev->ioAddr+EN0_RSARLO,offset&0xFF);
    outportByte(dev->ioAddr+EN0_RSARHI,offset>>8);
    outportByte(dev->ioAddr+NE_CMD,E8390_RREAD|E8390_START);

    size/=2;
    for(i=0;i<size;i++)
    ha[i]=inportWord(dev->ioAddr+NE_DATAPORT);
    outportByte(dev->ioAddr+EN0_ISR,0x40);
    }

    staticintdp_pkt2user(structdevice*dev,intpage,intlength){
    intlast=0x0;
    structnicBuffer*tmpBuf=0x0;

    last=page+(length-1)/DP_PAGESIZE;

    if(last>=stopPage){
    kprintf("FOOKSTOPPAGE!!!");
    }
    else{
    tmpBuf=ne2kAllocBuffer(length);
    NICtoPC(dev,tmpBuf->buffer,length,page*DP_PAGESIZE+sizeof(dp_rcvhdr_t));
    }
    return(OK);
    }

    structnicBuffer*ne2kAllocBuffer(intlength){
    structnicBuffer*tmpBuf=0x0;

    spinLock(&ne2k_spinLock);

    if(ne2kBuffer==0x0){
    ne2kBuffer=(structnicBuffer*)kmalloc(sizeof(structnicBuffer));
    ne2kBuffer->next=0x0;
    ne2kBuffer->length=length;
    ne2kBuffer->buffer=(char*)kmalloc(length);
    spinUnlock(&ne2k_spinLock);
    return(ne2kBuffer);
    }
    else{
    for(tmpBuf=ne2kBuffer;tmpBuf->next!=0x0;tmpBuf=tmpBuf->next);

    tmpBuf->next=(structnicBuffer*)kmalloc(sizeof(structnicBuffer));
    tmpBuf=tmpBuf->next;
    tmpBuf->next=0x0;
    tmpBuf->length=length;
    tmpBuf->buffer=(char*)kmalloc(length);
    spinUnlock(&ne2k_spinLock);
    return(tmpBuf);
    }
    spinUnlock(&ne2k_spinLock);
    return(0x0);
    }

    structnicBuffer*ne2kGetBuffer(){
    structnicBuffer*tmpBuf=0x0;

    if(ne2k_spinLock==0x1)
    return(0x0);

    tmpBuf=ne2kBuffer;
    if(ne2kBuffer!=0x0)
    ne2kBuffer=ne2kBuffer->next;
    return(tmpBuf);
    }

    voidne2kFreeBuffer(structnicBuffer*buf){
    kfree(buf->buffer);
    kfree(buf);
    return;
    }

    /***

    $Log: ne2k_8c.xml,v $
    Revision 1.6  2006/12/19 14:12:52  reddawg
    rtld-elf almost workign

    Revision1.1.1.12006/06/0112:46:12reddawg
    ubix2

    Revision1.22005/10/1200:13:37reddawg
    Removed

    Revision1.1.1.12005/09/2617:24:02reddawg
    nomessage

    Revision1.242004/09/2821:47:56reddawg
    Fixeddeadlocknowsafetouseinbochs

    Revision1.232004/09/1622:35:28reddawg
    DemoRelease

    Revision1.222004/09/1521:25:33reddawg
    Fixens

    Revision1.212004/09/1119:15:37reddawg
    hereyougoirq10io240foryourne2knic

    Revision1.202004/09/0722:26:04reddawg
    syncedin

    Revision1.192004/09/0721:54:38reddawg
    okrevertedbacktooldschedulingfornow....

    Revision1.182004/09/0615:13:25reddawg
    LastcommitbeforeFreeBSD6.0

    Revision1.172004/08/0120:40:45reddawg
    Netrelatedfixes

    Revision1.162004/07/2822:23:02reddawg
    makesureitstillworksbeforeIgotobed

    Revision1.152004/07/1717:04:47reddawg
    ne2k:addedasserthopefullyitwillhelpmesolvethisdmasize0randomerror

    Revision1.142004/07/1412:03:50reddawg
    ne2k:ne2kInittone2k_init
    ChangedStartupRoutines

    Revision1.132004/06/0410:19:42reddawg
    notes:wecompileagain,thankg-danywaysiwasabouttocry

    Revision1.122004/05/2112:48:22reddawg
    Cleanedup

    Revision1.112004/05/1904:07:42reddawg
    kmalloc(size,pid)nomoreitisnokmalloc(size);thewayitshouldofbeen

    Revision1.102004/05/1002:23:24reddawg
    MinorChangesToSourceCodeToPrepareItForOpenSourceRelease

    END
    ***/