X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?a=blobdiff_plain;f=palacios%2Fsrc%2Fgeekos%2Fne2k.c;h=a093ed4be8d2ec3e784fc039086a86dddb6393a1;hb=c07f7f11e5d781b90f4d8876d12f3fc4e47309ad;hp=1cc54576905163e08155caacd1e7dd73bf9002af;hpb=7b2624b13da9f3e4871903e4ef4ae6f77975e79e;p=palacios.releases.git diff --git a/palacios/src/geekos/ne2k.c b/palacios/src/geekos/ne2k.c index 1cc5457..a093ed4 100644 --- a/palacios/src/geekos/ne2k.c +++ b/palacios/src/geekos/ne2k.c @@ -10,14 +10,17 @@ #define RX_START_BUFF 0x4c #define RX_END_BUFF 0x80 -uint_t next = (RX_START_BUFF << 8); +static uint_t next = (RX_START_BUFF << 8); static uint_t received = 0; static uint_t send_done = 1; +struct NE2K_REGS* regs; + struct callback { int (*packet_received)(struct NE2K_Packet_Info *info, uchar_t *packet); } callbacks; +#if DEBUG static void Dump_Registers() { uint_t data; @@ -28,7 +31,8 @@ static void Dump_Registers() PrintBoth("\t%x: %x\n", NE2K_BASE_ADDR + i, data); } } - +#endif +#if 0 static int NE2K_Transmit(struct NE2K_REGS *regs) { while(!send_done); @@ -89,7 +93,7 @@ static int NE2K_Transmit(struct NE2K_REGS *regs) return 0; } - +#endif static void NE2K_Interrupt_Handler(struct Interrupt_State * state) { Begin_IRQ(state); @@ -101,14 +105,15 @@ static void NE2K_Interrupt_Handler(struct Interrupt_State * state) if(isr_content & 0x01) /* A packet has been received. */ { uchar_t current; - do{ - Out_Byte(NE2K_CR, 0x4a); - current = In_Byte(NE2K_CURR); - Out_Byte(NE2K_CR, 0x0a); - NE2K_Receive(); - Out_Byte(NE2K_ISR, 0x01); - /* If BNRY and CURR aren't equal, more than one packet has been received. */ - }while (current > In_Byte(NE2K_BNRY)); + Out_Byte(NE2K_CR, 0x4a); /* Page 1 */ + current = In_Byte(NE2K_CURR); + Out_Byte(NE2K_CR, 0x0a); /* Page 0 */ + NE2K_Receive(); + + /* When CURR equals BNRY, all packets in the receive ring buffer have been read, and + the packet received bit in the interrupt status register can be cleared. */ + if(current == In_Byte(NE2K_BNRY)) + Out_Byte(NE2K_ISR, 0x01); } End_IRQ(state); @@ -117,7 +122,8 @@ static void NE2K_Interrupt_Handler(struct Interrupt_State * state) send_done = 1; Out_Byte(NE2K_ISR, 0x02); } - Out_Byte(NE2K_ISR, 0xff); /* Clear all interrupts. */ + + //Out_Byte(NE2K_ISR, 0xff); /* Clear all interrupts. */ } int Init_Ne2k(int (*rcvd_fn)(struct NE2K_Packet_Info *info, uchar_t *packet)) @@ -125,9 +131,9 @@ int Init_Ne2k(int (*rcvd_fn)(struct NE2K_Packet_Info *info, uchar_t *packet)) callbacks.packet_received = rcvd_fn; PrintBoth("Initializing network card...\n"); - Out_Byte(NE2K_CR+0x1f, In_Byte(NE2K_CR+0x1f)); /* Reset? */ + Out_Byte(NE2K_CR+0x1f, In_Byte(NE2K_CR+0x1f)); /* Reset */ - struct NE2K_REGS* regs = Malloc(sizeof(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); @@ -210,29 +216,32 @@ int Init_Ne2k(int (*rcvd_fn)(struct NE2K_Packet_Info *info, uchar_t *packet)) cr->sta = 0x1; // toggle start bit cr->stp = 0x0; Out_Byte(NE2K_CR, regs->cr); - + +#if DEBUG Dump_Registers(); - cr->ps = NE2K_PAGE1; + cr->ps = 0x01; Out_Byte(NE2K_CR, regs->cr); Dump_Registers(); - cr->ps = NE2K_PAGE2; + cr->ps = 0x02; Out_Byte(NE2K_CR, regs->cr); Dump_Registers(); - cr->ps = NE2K_PAGE0; + cr->ps = 0x00; Out_Byte(NE2K_CR, regs->cr); +#endif Install_IRQ(NE2K_IRQ, NE2K_Interrupt_Handler); Enable_IRQ(NE2K_IRQ); - +#if 0 for(i = 0; i < 0; i++) { NE2K_Transmit(regs); PrintBoth("Transmitting a packet\n"); } - +#endif +/* uchar_t src_addr[6] = { 0x52, 0x54, 0x00, 0x12, 0x34, 0x58 }; uchar_t dest_addr[6] = { 0x52, 0x54, 0x00, 0x12, 0x34, 0x56 }; @@ -243,19 +252,19 @@ int Init_Ne2k(int (*rcvd_fn)(struct NE2K_Packet_Info *info, uchar_t *packet)) for(i = 0; i < 0; i++) { NE2K_Send(regs, src_addr, dest_addr, 0x01, data, size); } - +*/ //Free(data); // Why does this crash? return 0; } /* Assumes src and dest are arrays of 6 characters. */ -int NE2K_Send(struct NE2K_REGS *regs, uchar_t src[], uchar_t dest[], uint_t type, uchar_t *data, uint_t size) +int NE2K_Send(uchar_t src[], uchar_t dest[], uint_t type, uchar_t *data, uint_t size) { struct _CR * cr = (struct _CR*)&(regs->cr); uint_t packet_size = size + 16; - regs->cr = 0x21; - cr->stp = 0x0; //toggle start on + regs->cr = 0x21; /* Turn off remote DMA, stop command */ + cr->stp = 0x0; /* toggle start on */ cr->sta = 0x1; Out_Byte(NE2K_CR, regs->cr); @@ -265,10 +274,10 @@ int NE2K_Send(struct NE2K_REGS *regs, uchar_t src[], uchar_t dest[], uint_t type Out_Byte(NE2K_RSAR0, 0x42); Out_Byte(NE2K_RSAR1, 0x00); - cr->rd = 0x01; // set remote DMA to 'remote read' + cr->rd = 0x01; /* set remote DMA to 'remote read' */ Out_Byte(NE2K_CR, regs->cr); - regs->isr = 0x40; // clear and set Remote DMA high + regs->isr = 0x40; /* clear 'remote DMA complete' interrupt */ Out_Byte(NE2K_ISR, regs->isr); /* Set remote byte count registers */ @@ -279,12 +288,14 @@ int NE2K_Send(struct NE2K_REGS *regs, uchar_t src[], uchar_t dest[], uint_t type Out_Byte(NE2K_TBCR0, packet_size & 0xff); Out_Byte(NE2K_TBCR1, (packet_size >> 8) & 0xff); + /* Set remote start address registers to the first page of the transmit ring buffer. */ Out_Byte(NE2K_RSAR0, 0x00); Out_Byte(NE2K_RSAR1, TX_START_BUFF); - regs->cr = 0x16; + cr->rd = 0x02; /* Set remote DMA to 'remote write' */ Out_Byte(NE2K_CR, regs->cr); + /* Begin pushing the packet into the dataport (located at 0x10 from the base address). */ /* Destination Address */ Out_Word(NE2K_CR + 0x10, (dest[1] << 8) | dest[0]); Out_Word(NE2K_CR + 0x10, (dest[3] << 8) | dest[2]); @@ -298,11 +309,15 @@ int NE2K_Send(struct NE2K_REGS *regs, uchar_t src[], uchar_t dest[], uint_t type /* Type */ Out_Word(NE2K_CR + 0x10, packet_size); + /* Packet data */ uint_t i; for(i = 0; i < size; i += 2) { Out_Word(NE2K_CR + 0x10, (*(data + i + 1) << 8) | *(data + i)); } + cr->txp = 0x1; /* Start transmission */ + Out_Byte(NE2K_CR, regs->cr); + return 0; } @@ -325,10 +340,12 @@ int NE2K_Receive() uint_t i; uint_t data; - PrintBoth("\nPacket data:\n\t"); - data = In_Word(NE2K_CR + 0x10); + +#if DEBUG + PrintBoth("\nPacket data:\n\t"); PrintBoth("%x ", data); +#endif /* Get the location of the next packet */ next = data & 0xff00; @@ -346,7 +363,6 @@ int NE2K_Receive() /* Copy the received packet over from the ring buffer. */ for(i = 0; i < packet_size; i+=2) { data = In_Word(NE2K_CR + 0x10); - //PrintBoth("%x ", data); *(packet + i) = data & 0x00ff; *(packet + i + 1) = (data & 0xff00) >> 8; #if 0 @@ -355,9 +371,6 @@ int NE2K_Receive() 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);