#include <geekos/irq.h>
#include <geekos/malloc.h>
-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) {
{
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);
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);
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);
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);
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;
}
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(){
-
-