1 #include <geekos/ne2k.h>
2 #include <geekos/debug.h>
4 #include <geekos/irq.h>
5 #include <geekos/malloc.h>
8 #define RX_START_BUFF 0x4c
10 static uint_t received = 0;
11 static uint_t send_done = 1;
12 uint_t next = (RX_START_BUFF<<8);
14 static void Dump_Registers()
17 PrintBoth("Dumping NIC registers for page %x...\n", (In_Byte(NE2K_CR) & 0xc0) >> 6);
19 for(i = 0; i <= 0x0f; i += 0x01) {
20 data = In_Byte(NE2K_BASE_ADDR+i);
21 PrintBoth("\t%x: %x\n", NE2K_BASE_ADDR + i, data);
25 static void NE2K_Interrupt_Handler(struct Interrupt_State * state)
28 PrintBoth("NIC Interrupt Occured!\n");
29 uchar_t isr_content = In_Byte(NE2K_ISR);
30 // Out_Byte(NE2K_ISR, 0xff); /* Clear all interrupts */
32 PrintBoth("Contents of ISR: %x\n", isr_content);
33 if(isr_content & 0x01)
36 Out_Byte(NE2K_ISR, 0x01);
40 if(isr_content & 0x02)
47 PrintBoth("Initializing network card...\n");
48 Out_Byte(NE2K_CR+0x1f, In_Byte(NE2K_CR+0x1f)); /* Reset? */
50 struct NE2K_REGS* regs = Malloc(sizeof(struct NE2K_REGS));
51 struct _CR * cr = (struct _CR *)&(regs->cr);
52 struct _RCR * rcr = (struct _RCR*)&(regs->rcr);
53 struct _IMR * imr = (struct _IMR *)&(regs->imr);
61 Out_Byte(NE2K_CR, regs->cr);
62 Out_Byte(NE2K_DCR, regs->dcr);
63 Out_Byte(NE2K_ISR, regs->isr);
64 Out_Byte(NE2K_RCR, regs->rcr);
65 Out_Byte(NE2K_TCR, regs->tcr);
66 Out_Byte(NE2K_IMR, regs->imr);
68 Out_Byte(NE2K_RBCR0, 0x00);
69 Out_Byte(NE2K_RBCR1, 0x00);
70 Out_Byte(NE2K_RSAR0, 0x00);
71 Out_Byte(NE2K_RSAR1, 0x00);
73 Out_Byte(NE2K_TPSR, 0x40); // Set TPSR
74 Out_Byte(NE2K_PSTART, RX_START_BUFF); // Set PSTART
75 Out_Byte(NE2K_BNRY, 0x59); // Set BNRY
76 Out_Byte(NE2K_PSTOP, 0x80); // Set PSTOP
78 cr->ps = 0x01; //switch to reg page 1
79 Out_Byte(NE2K_CR, regs->cr);
80 Out_Byte(NE2K_CURR, RX_START_BUFF);
83 Out_Byte(NE2K_CR, regs->cr);
84 Out_Byte(NE2K_BNRY, RX_START_BUFF);
86 Out_Byte(NE2K_ISR, regs->isr);
94 Out_Byte(NE2K_IMR, regs->imr);
96 cr->ps = 0x01; //switch to reg page 1
97 Out_Byte(NE2K_CR, regs->cr);
99 /* Set the physical address of the card to 52:54:00:12:34:58 */
100 Out_Byte(NE2K_CR+0x01, 0x52);
101 Out_Byte(NE2K_CR+0x02, 0x54);
102 Out_Byte(NE2K_CR+0x03, 0x00);
103 Out_Byte(NE2K_CR+0x04, 0x12);
104 Out_Byte(NE2K_CR+0x05, 0x34);
105 Out_Byte(NE2K_CR+0x06, 0x58);
107 /* Accept all multicast packets */
109 for(i = 0x08; i <= 0x0f; i++) {
110 Out_Byte(NE2K_CR+i, 0xff);
113 regs->cr = 0x21; //set CR to start value
114 Out_Byte(NE2K_CR, regs->cr);
117 Out_Byte(NE2K_TCR, regs->tcr);
123 rcr->pro = 0x1; // promiscuous mode, accept all packets
125 Out_Byte(NE2K_RCR, regs->rcr);
127 cr->sta = 0x1; // toggle start bit
129 Out_Byte(NE2K_CR, regs->cr);
134 Out_Byte(NE2K_CR, regs->cr);
138 Out_Byte(NE2K_CR, regs->cr);
142 Out_Byte(NE2K_CR, regs->cr);
145 // Out_Byte(NE2K_CR+0x1f, In_Byte(NE2K_CR+0x1f));
147 Install_IRQ(NE2K_IRQ, NE2K_Interrupt_Handler);
148 Enable_IRQ(NE2K_IRQ);
150 for(i = 0; i < 1; i++)
153 PrintBoth("Transmitting a packet\n");
159 int NE2K_Transmit(struct NE2K_REGS *regs)
164 struct _CR * cr = (struct _CR*)&(regs->cr);
165 uint_t packet_size = 80;
167 cr->stp = 0x0; //toggle start on
169 Out_Byte(NE2K_CR, regs->cr);
171 // Read-before-write bug fix?
172 Out_Byte(NE2K_RBCR0, 0x42);
173 Out_Byte(NE2K_RBCR1, 0x00);
174 Out_Byte(NE2K_RSAR0, 0x42);
175 Out_Byte(NE2K_RSAR1, 0x00);
177 cr->rd = 0x01; // set remote DMA to 'remote read'
178 Out_Byte(NE2K_CR, regs->cr);
180 regs->isr = 0x40; // clear and set Remote DMA high
181 Out_Byte(NE2K_ISR, regs->isr);
183 Out_Byte(NE2K_RBCR0, packet_size);
184 Out_Byte(NE2K_RBCR1, 0x00);
186 Out_Byte(NE2K_TBCR0, packet_size);
187 Out_Byte(NE2K_TBCR1, 0x00);
189 Out_Byte(NE2K_RSAR0, 0x00);
190 Out_Byte(NE2K_RSAR1, 0x40);
193 Out_Byte(NE2K_CR, regs->cr);
195 /* Begin pushing the packet into the dataport (located at 0x10 from the base address) */
196 /* Destination address = 52:54:00:12:34:56 */
197 Out_Word(NE2K_CR+0x10, 0x5452);
198 Out_Word(NE2K_CR+0x10, 0x1200);
199 Out_Word(NE2K_CR+0x10, 0x5634);
201 /* Source address = 52:54:00:12:34:58 */
202 Out_Word(NE2K_CR+0x10, 0x5452);
203 Out_Word(NE2K_CR+0x10, 0x1200);
204 Out_Word(NE2K_CR+0x10, 0x5834);
206 /* Type length and data; currently random data */
209 for(i = 1; i <= packet_size/2-12; i++, n+=2) {
210 //Out_Word(NE2K_CR+0x10, 0x0f0b);
211 Out_Word(NE2K_CR+0x10, (n<<8) | (n+1));
215 //Out_Byte(NE2K_ISR, regs->isr); /* Do we need this here? */
222 PrintBoth("Packet Received\n");
224 // uint_t packet_size = 80;
226 Out_Byte(NE2K_CR, 0x22);
228 Out_Byte(NE2K_RBCR1, 0x00);
229 // Out_Byte(NE2K_RBCR0, 0x60);
231 // Out_Byte(NE2K_RSAR0, 0x42);
232 Out_Byte(NE2K_RSAR1, next >> 8);
233 Out_Byte(NE2K_RSAR0, next & 0xff);
234 Out_Byte(NE2K_CR, 0x0a);
238 PrintBoth("\nPacket data:\n\t");
240 data = In_Word(NE2K_CR + 0x10);
241 PrintBoth("%x ", data);
243 /* The first byte is the page number where the next packet in the ring buffer is stored */
244 next = data & 0xff00;
246 uint_t packet_size = In_Word(NE2K_CR + 0x10) - 4;
247 Out_Byte(NE2K_RBCR0, packet_size & 0xff);
248 Out_Byte(NE2K_RBCR1, (packet_size>>8) & 0xff);
251 PrintBoth("packetsize = %x\n\t", packet_size);
254 for(i = 2; i < packet_size; i+=2) {
255 data = In_Word(NE2K_CR + 0x10);
256 PrintBoth("%x ", data);
259 PrintBoth("BNRY = %x\n", In_Byte(NE2K_BNRY));
260 Out_Byte(NE2K_CR, 0x4a);
261 PrintBoth("CURR = %x\n", In_Byte(NE2K_CURR));
262 Out_Byte(NE2K_CR, 0x0a);
269 //Out_Byte(NE2K_RBCR0, (In_Byte(NE2K_RBCR0))-2);
270 //Out_Byte(NE2K_RSAR0, (In_Byte(NE2K_RSAR0))+2);
272 PrintBoth("\n%d packets have been received", ++received);
275 Out_Byte(NE2K_ISR, 0x40);
277 /* The BNRY register stores the location of the first packet that hasn't been read yet */
278 Out_Byte(NE2K_BNRY, next >> 8);