From: Matt Wojcik Date: Wed, 30 Jul 2008 16:58:22 +0000 (+0000) Subject: Initial working version of NE2K_Receive() added. X-Git-Tag: vmmhack1-ramdisk-boot-iso-puppy~37 X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?p=palacios.git;a=commitdiff_plain;h=76f560bd0d3812c00cda65c1395290daa0145339 Initial working version of NE2K_Receive() added. --- diff --git a/palacios/src/geekos/ne2k.c b/palacios/src/geekos/ne2k.c index 5beb967..45fb49b 100644 --- a/palacios/src/geekos/ne2k.c +++ b/palacios/src/geekos/ne2k.c @@ -4,92 +4,16 @@ #include #include -static uint_t received = 0; - -struct _CR { //COMMAND REG - uint_t stp: 1; //STOP- software reset - uint_t sta: 1; //START- activates NIC - uint_t txp: 1; //TRANSMIT- set to send - uint_t rd: 3; //REMOTE DMA - uint_t ps: 2; //PAGE SELECT -}; - -struct _ISR{ //INTERRUPT STATUS REG - uint_t prx: 1; //PACKET RECIEVED - uint_t ptx: 1; //PACKET TRANSMITTED - uint_t rxe: 1; //TRANSMIT ERROR - uint_t txe: 1; //RECEIVE ERROR - uint_t ovw: 1; //OVERWRITE WARNING - uint_t cnt: 1; //COUNTER OVERFLOW - uint_t rdc: 1; //REMOTE DMA COMPLETE - uint_t rst: 1; //RESET STATUS -}; - -struct _IMR { //INTERRUPT MASK REG - uint_t prxe: 1; //PACKET RX INTRPT - uint_t ptxe: 1; //PACKET TX INTRPT - uint_t rxee: 1; //RX ERROR INTRPT - uint_t txee: 1; //TX ERROR INTRPt - uint_t ovwe: 1; //OVERWRITE WARNING INTRPT - uint_t cnte: 1; //COUNTER OVERFLOW INTRPT - uint_t rdce: 1; //DMA COMLETE INTRPT - uint_t rsvd: 1; -}; - -struct _DCR { //DATA CONFIG REGISTER - uint_t wts: 1; //WORD TRANSFER SELECT - uint_t bos: 1; //BYTE ORDER SELECT - uint_t las: 1; //LONG ADDR SELECT - uint_t ls: 1; //LOOPBACK SELECT - uint_t arm: 1; //AUTO-INITIALIZE REMOTE - uint_t ft: 2; //FIFO THRESH SELECT -}; - -struct _TCR { //TX CONFIG REGISTER - uint_t crc: 1; //INHIBIT CRC - uint_t lb: 2; //ENCODED LOOPBACK - uint_t atd: 1; //AUTO TRANSMIT - uint_t ofst: 1; //COLLISION OFFSET ENABLE - uint_t rsvd: 3; -}; - -struct _TSR { - uint_t ptx: 1; //PACKET TX - uint_t rsvd: 1; - uint_t col: 1; //TX COLLIDED - uint_t abt: 1; //TX ABORTED - uint_t crs: 1; //CARRIER SENSE LOST - uint_t fu: 1; //FIFO UNDERRUN - uint_t cdh: 1; //CD HEARTBEAT - uint_t owc: 1; //OUT OF WINDOW COLLISION -}; - -struct _RCR { //RECEIVE CONFIGURATION REGISTER - uint_t sep: 1; //SAVE ERRORED PACKETS - uint_t ar: 1; //ACCEPT RUNT PACKETS - uint_t ab: 1; //ACCEPT BROADCAST - uint_t am: 1; //ACCEPT MULTICAST - uint_t pro: 1; //PROMISCUOUS PHYSICAL - uint_t mon: 1; //MONITOR MODE - uint_t rsvd: 2; -}; - -struct _RSR { //RECEIVE STATUS REG - uint_t prx: 1; //PACKET RX INTACT - uint_t crc: 1; //CRC ERROR - uint_t fae: 1; //FRAME ALIGNMENT ERROR - uint_t fo: 1; //FIFO OVERRUN - uint_t mpa: 1; //MISSED PACKET - uint_t phy: 1; //PHYSICAL/MULTICAST ADDR - uint_t dis: 1; //RX DISABLED - uint_t dfr: 1; //DEFERRING -}; +#define DEBUG 0 +#define RX_START_BUFF 0x4c +static uint_t received = 0; +static uint_t send_done = 1; +uint_t next = (RX_START_BUFF<<8); static void Dump_Registers() { uint_t data; - PrintBoth("Dumping NIC registers for page %x...\n", (In_Byte(NE2K_CR) & 0xc0) >> 6); uint_t i = 0; for(i = 0; i <= 0x0f; i += 0x01) { @@ -102,70 +26,74 @@ static void NE2K_Interrupt_Handler(struct Interrupt_State * state) { Begin_IRQ(state); PrintBoth("NIC Interrupt Occured!\n"); - uint_t isr_content = In_Byte(NE2K_ISR); + uchar_t isr_content = In_Byte(NE2K_ISR); + Out_Byte(NE2K_ISR, 0xff); /* Clear all interrupts */ +/* if( !isr_content ) + return; +*/ + PrintBoth("Contents of ISR: %x\n", isr_content); - if(In_Byte(NE2K_ISR) & 0x01) + if(isr_content & 0x01) NE2K_Receive(); - Out_Byte(NE2K_ISR, 0xff); End_IRQ(state); + if(isr_content & 0x02) + send_done = 1; } - int Init_Ne2k() { - -uint_t CR_START_VAL = 0x21; -static const uint_t DCR_START_VAL = 0x49; -static const uint_t ISR_START_VAL = 0xff; -static const uint_t RCR_START_VAL = 0x20; -static const uint_t TCR_START_VAL = 0x02; -//static const uint_t IMR_START_VAL = 0x00; -PrintBoth("location Startval first = %x\n", &CR_START_VAL); - PrintBoth("Initializing network card...\n"); + Out_Byte(NE2K_CR+0x1f, In_Byte(NE2K_CR+0x1f)); /* Reset? */ struct NE2K_REGS* regs = Malloc(sizeof(struct NE2K_REGS)); + struct _CR * cr = (struct _CR *)&(regs->cr); + struct _RCR * rcr = (struct _RCR*)&(regs->rcr); + struct _IMR * imr = (struct _IMR *)&(regs->imr); + + regs->cr = 0x21; + regs->dcr = 0x49; + regs->isr = 0xff; + regs->rcr = 0x20; + regs->tcr = 0x02; + + Out_Byte(NE2K_CR, regs->cr); + Out_Byte(NE2K_DCR, regs->dcr); + Out_Byte(NE2K_ISR, regs->isr); + Out_Byte(NE2K_RCR, regs->rcr); + Out_Byte(NE2K_TCR, regs->tcr); + Out_Byte(NE2K_IMR, regs->imr); - regs->cr = (struct _CR*)&CR_START_VAL; - regs->dcr = (struct _DCR*)&DCR_START_VAL; - regs->isr = (struct _ISR*)&ISR_START_VAL; - regs->rcr = (struct _RCR*)&RCR_START_VAL; - regs->tcr = (struct _TCR*)&TCR_START_VAL; - - Out_Byte(NE2K_CR, *(uint_t *)regs->cr); - Out_Byte(NE2K_DCR, *(uint_t *)regs->dcr); - Out_Byte(NE2K_ISR, *(uint_t *)regs->isr); - Out_Byte(NE2K_RCR, *(uint_t *)regs->rcr); - Out_Byte(NE2K_TCR, *(uint_t *)regs->tcr); - Out_Byte(NE2K_IMR, *(uint_t *)regs->imr); Out_Byte(NE2K_RBCR0, 0x00); Out_Byte(NE2K_RBCR1, 0x00); Out_Byte(NE2K_RSAR0, 0x00); Out_Byte(NE2K_RSAR1, 0x00); Out_Byte(NE2K_TPSR, 0x40); // Set TPSR - Out_Byte(NE2K_PSTART, 0x42); // Set PSTART + Out_Byte(NE2K_PSTART, RX_START_BUFF); // Set PSTART Out_Byte(NE2K_BNRY, 0x59); // Set BNRY - Out_Byte(NE2K_PSTOP, 0x60); // Set PSTOP + Out_Byte(NE2K_PSTOP, 0x80); // Set PSTOP - Out_Byte(NE2K_ISR, *(uint_t *)regs->isr); + cr->ps = 0x01; //switch to reg page 1 + Out_Byte(NE2K_CR, regs->cr); + Out_Byte(NE2K_CURR, RX_START_BUFF); + cr->ps = 0x00; - regs->imr->prxe = 0x1; - regs->imr->ptxe = 0x1; - regs->imr->rxee = 0x1; - regs->imr->txee = 0x1; - regs->imr->ovwe = 0x1; - regs->imr->cnte = 0x1; - Out_Byte(NE2K_IMR, *(uint_t *)regs->imr); + Out_Byte(NE2K_CR, regs->cr); + Out_Byte(NE2K_BNRY, RX_START_BUFF); - regs->cr->ps = 0x01; //switch to reg page 1 - Out_Byte(NE2K_CR, *(uint_t *)regs->cr); + Out_Byte(NE2K_ISR, regs->isr); -PrintBoth("Startval 2= %x\n", CR_START_VAL); + imr->prxe = 0x1; + imr->ptxe = 0x1; + imr->rxee = 0x1; + imr->txee = 0x1; + imr->ovwe = 0x1; + imr->cnte = 0x1; + Out_Byte(NE2K_IMR, regs->imr); -PrintBoth("regs locat = %x\n", (uint_t *)regs->cr); -PrintBoth("regs = %x\n", *(uint_t *)regs->cr); + cr->ps = 0x01; //switch to reg page 1 + Out_Byte(NE2K_CR, regs->cr); /* Set the physical address of the card to 52:54:00:12:34:58 */ Out_Byte(NE2K_CR+0x01, 0x52); @@ -175,62 +103,69 @@ PrintBoth("regs = %x\n", *(uint_t *)regs->cr); Out_Byte(NE2K_CR+0x05, 0x34); Out_Byte(NE2K_CR+0x06, 0x58); + /* Accept all multicast packets */ uint_t i; for(i = 0x08; i <= 0x0f; i++) { Out_Byte(NE2K_CR+i, 0xff); } - *(uint_t *)regs->cr = 0x21; //set CR to start value - Out_Byte(NE2K_CR, *(uint_t *)regs->cr); - -PrintBoth("startval 3 = %x\n", CR_START_VAL); -PrintBoth("location Startval 2 = %x\n", &CR_START_VAL); -PrintBoth("regs = %x\n", (uint_t *)regs->cr); + regs->cr = 0x21; //set CR to start value + Out_Byte(NE2K_CR, regs->cr); regs->tcr = 0x00; - Out_Byte(NE2K_TCR, *(uint_t *)regs->tcr); - - regs->rcr->sep = 0x1; - regs->rcr->ar = 0x1; - regs->rcr->ab = 0x1; - regs->rcr->am = 0x1; - regs->rcr->pro = 0x1; //promiscuous mode, accept all packets - regs->rcr->mon = 0x0; - Out_Byte(NE2K_RCR, *(uint_t *)regs->rcr); - - regs->cr->sta = 0x1; //toggle start bit - regs->cr->stp = 0x0; - Out_Byte(NE2K_CR, *(uint_t *)regs->cr); + Out_Byte(NE2K_TCR, regs->tcr); + + rcr->sep = 0x1; + rcr->ar = 0x1; + rcr->ab = 0x1; + rcr->am = 0x1; + rcr->pro = 0x1; // promiscuous mode, accept all packets + rcr->mon = 0x0; + Out_Byte(NE2K_RCR, regs->rcr); + + cr->sta = 0x1; // toggle start bit + cr->stp = 0x0; + Out_Byte(NE2K_CR, regs->cr); Dump_Registers(); - Out_Byte(NE2K_CR, (*(uint_t *)regs->cr & 0x3f) | NE2K_PAGE1); + cr->ps = NE2K_PAGE1; + Out_Byte(NE2K_CR, regs->cr); Dump_Registers(); - Out_Byte(NE2K_CR, (*(uint_t *)regs->cr & 0x3f) | NE2K_PAGE2); + cr->ps = NE2K_PAGE2; + Out_Byte(NE2K_CR, regs->cr); Dump_Registers(); + cr->ps = NE2K_PAGE0; + Out_Byte(NE2K_CR, regs->cr); + // Reset? - Out_Byte(NE2K_CR+0x1f, In_Byte(NE2K_CR+0x1f)); +// Out_Byte(NE2K_CR+0x1f, In_Byte(NE2K_CR+0x1f)); Install_IRQ(NE2K_IRQ, NE2K_Interrupt_Handler); Enable_IRQ(NE2K_IRQ); - - for(i = 0; i < 4; i++) +/* + for(i = 0; i < 1; i++) { NE2K_Transmit(regs); PrintBoth("Transmitting a packet\n"); } - +*/ return 0; } + int NE2K_Transmit(struct NE2K_REGS *regs) { + while(!send_done); + send_done = 0; + + struct _CR * cr = (struct _CR*)&(regs->cr); uint_t packet_size = 80; - *(uint_t *)regs->cr = 0x21; - regs->cr->stp = 0x0; //toggle start on - regs->cr->sta = 0x1; - Out_Byte(NE2K_CR, *(uint_t *)regs->cr); + regs->cr = 0x21; + cr->stp = 0x0; //toggle start on + cr->sta = 0x1; + Out_Byte(NE2K_CR, regs->cr); // Read-before-write bug fix? Out_Byte(NE2K_RBCR0, 0x42); @@ -238,11 +173,11 @@ int NE2K_Transmit(struct NE2K_REGS *regs) Out_Byte(NE2K_RSAR0, 0x42); Out_Byte(NE2K_RSAR1, 0x00); - regs->cr->rd = 0x01; //set remote DMA to 'remote read' - Out_Byte(NE2K_CR, *(uint_t *)regs->cr); + cr->rd = 0x01; // set remote DMA to 'remote read' + Out_Byte(NE2K_CR, regs->cr); - *(uint_t*)regs->isr = 0x40; //clear and set Remote DMA high - Out_Byte(NE2K_ISR, *(uint_t *)regs->isr); + regs->isr = 0x40; // clear and set Remote DMA high + Out_Byte(NE2K_ISR, regs->isr); Out_Byte(NE2K_RBCR0, packet_size); Out_Byte(NE2K_RBCR1, 0x00); @@ -253,9 +188,9 @@ int NE2K_Transmit(struct NE2K_REGS *regs) Out_Byte(NE2K_RSAR0, 0x00); Out_Byte(NE2K_RSAR1, 0x40); - *(uint_t*)regs->cr = 0x16; - Out_Byte(NE2K_CR, *(uint_t *)regs->cr); - + regs->cr = 0x16; + Out_Byte(NE2K_CR, regs->cr); + /* Begin pushing the packet into the dataport (located at 0x10 from the base address) */ /* Destination address = 52:54:00:12:34:56 */ Out_Word(NE2K_CR+0x10, 0x5452); @@ -275,7 +210,8 @@ int NE2K_Transmit(struct NE2K_REGS *regs) Out_Word(NE2K_CR+0x10, (n<<8) | (n+1)); } - Out_Byte(NE2K_ISR, 0x40); + //regs->isr = 0x40; + //Out_Byte(NE2K_ISR, regs->isr); /* Do we need this here? */ return 0; } @@ -290,30 +226,46 @@ int NE2K_Receive() Out_Byte(NE2K_RBCR0, packet_size); Out_Byte(NE2K_RBCR1, 0x00); // Out_Byte(NE2K_RSAR0, 0x42); - Out_Byte(NE2K_RSAR0, 0x4c); - Out_Byte(NE2K_RSAR1, 0x00); + Out_Byte(NE2K_RSAR1, next >> 8); + Out_Byte(NE2K_RSAR0, next & 0xff); Out_Byte(NE2K_CR, 0x0a); uint_t i; uint_t data; PrintBoth("\nPacket data:\n\t"); - for(i = 0; i < packet_size; i+=2) { + data = In_Word(NE2K_CR + 0x10); + PrintBoth("%x ", data); + + /* The first byte is the page number where the next packet in the ring buffer is stored */ + next = data & 0xff00; + + for(i = 2; i < packet_size; i+=2) { data = In_Word(NE2K_CR + 0x10); PrintBoth("%x ", data); + +#if DEBUG + PrintBoth("BNRY = %x\n", In_Byte(NE2K_BNRY)); + Out_Byte(NE2K_CR, 0x4a); + PrintBoth("CURR = %x\n", In_Byte(NE2K_CURR)); + Out_Byte(NE2K_CR, 0x0a); +#endif + if(!(i%10)) PrintBoth("\n\t"); } +//Out_Byte(NE2K_RBCR0, (In_Byte(NE2K_RBCR0))-2); +//Out_Byte(NE2K_RSAR0, (In_Byte(NE2K_RSAR0))+2); + PrintBoth("\n%d packets have been received", ++received); PrintBoth("\n\n"); Out_Byte(NE2K_ISR, 0x40); + /* The BNRY register stores the location of the first packet that hasn't been read yet */ + Out_Byte(NE2K_BNRY, next >> 8); + return 0; } - -//int NE2K_Ringbuff_Overflow(){ - -