dc9413943dea802ae3764d316bfb49aa851254fd
[akaros.git] / kern / arch / i386 / rl8168.c
1 /** @filec
2  * @brief RL8168 Driver       
3  *
4  * EXPERIMENTAL. DO NOT USE IF YOU DONT KNOW WHAT YOU ARE DOING
5  *
6  * See Info below 
7  *
8  * @author Paul Pearce <pearce@eecs.berkeley.edu>
9  *
10  */
11
12 #ifdef __SHARC__
13 #pragma nosharc
14 #endif
15
16 #include <arch/mmu.h>
17 #include <arch/x86.h>
18 #include <arch/smp.h>
19 #include <arch/apic.h>
20 #include <arch/pci.h>
21 #include <arch/rl8168.h>
22
23 #include <ros/memlayout.h>
24
25 #include <atomic.h>
26 #include <stdio.h>
27 #include <string.h>
28 #include <trap.h>
29 #include <kmalloc.h>
30
31 #include <pmap.h>
32
33 /** @file
34  * @brief Realtek RL8168 Driver
35  *
36  * EXPERIMENTAL. DO NOT USE IF YOU DONT KNOW WHAT YOU ARE DOING
37  *
38  * This is a function rl8168 driver, that uses some really ugly hacks to achieve
39  * UDP communication with a remote syscall server, without a network stack.
40  *
41  * To enable use, define __NETWORK__ in your Makelocal
42  *
43  * @author Paul Pearce <pearce@eecs.berkeley.edu>
44  *
45  * @todo Move documention below into doxygen format.
46  * @todo See list in code
47  */
48
49
50 /* RealTek 8168d (8111d) NIC Driver
51  *
52  * Written by Paul Pearce.
53  *
54  * This is a really rough "driver". Really, its not a driver, just a kernel hack to give
55  * the kernel a way to receive and send packets. The basis of the init code is the OSDEV
56  * page on the 8169 chipset, which is a varient of this chipset (most 8169 drivers work 
57  * on the 8168d). http://wiki.osdev.org/RTL8169
58  * 
59  * Basic ideas (although no direct code) were gleamed from the OpenBSD re(4) driver,
60  * which can be found in sys/dev/ic/re.c. sys/dev/ic/rtl81x9reg.h is needed to make
61  * sense of the constants used in re.c.
62  *
63  * This is an ongoing work in progress. Main thing is we need a kernel interface for PCI
64  * devices and network devices, that we can hook into, instead of providing arbitary functions
65  * 
66  * TODO: Remove hacky syscall hack stuff (once we get a real stack).
67  * TODO: Jumbo frame support
68  * TODO: Use high priority transmit ring for syscall stuff.
69  * TODO: Discuss panic conditions.
70  * TODO: Shutdown cleanup kfrees()
71  * TODO: Use onboard timer interrupt to check for packets, instead of writing a bit each time we have a packet.
72  * TODO: CONCURRENCY!
73  */
74
75 struct Descriptor
76 {
77     unsigned int command,  /* command/status dword */
78                  vlan,     /* currently unused */
79                  low_buf,  /* low 32-bits of physical buffer address */
80                  high_buf; /* high 32-bits of physical buffer address */
81 };
82
83
84 uint32_t rl8168_io_base_addr = 0;
85 uint32_t rl8168_irq = 0;
86 char device_mac[6];
87
88 struct Descriptor *CT(NUM_RX_DESCRIPTORS) rx_des_kva;
89 unsigned long rx_des_pa;
90
91 struct Descriptor *CT(NUM_TX_DESCRIPTORS) tx_des_kva;
92 unsigned long tx_des_pa;
93
94 uint32_t rx_des_cur = 0;
95 uint32_t tx_des_cur = 0;
96
97 extern int eth_up;
98 extern int packet_waiting;
99 extern int packet_buffer_size;
100 extern char *CT(MAX_FRAME_SIZE - PACKET_HEADER_SIZE) packet_buffer;
101 extern char *CT(MAX_FRAME_SIZE) packet_buffer_orig;
102 extern int packet_buffer_pos;
103
104 extern char *CT(PACKET_HEADER_SIZE + len) (*packet_wrap)(const char *CT(len) data, size_t len);
105 extern int (*send_frame)(const char *CT(len) data, size_t len);
106
107
108 void rl8168_init() {
109
110         if (rl8168_scan_pci() < 0) return;
111         rl8168_read_mac();
112         rl8168_setup_descriptors();
113         rl8168_configure();
114         rl8168_setup_interrupts();
115         packet_wrap = &rl8168_packet_wrap;
116         send_frame = &rl8168_send_frame;
117
118         eth_up = 1;
119         
120         //Trigger sw based nic interrupt
121 /*      cprintf("Generating interrupt...\n");
122         outb(rl8168_io_base_addr + 0x38, 0x1);
123         cprintf("sleeping\n");
124         udelay(3000000);
125         cprintf("done\n");
126 */
127         return;
128 }
129
130
131 int rl8168_scan_pci() {
132         
133         extern pci_dev_entry_t pci_dev_map[PCI_MAX_BUS][PCI_MAX_DEV][PCI_MAX_FUNC];
134         extern uint16_t pci_irq_map[PCI_MAX_BUS][PCI_MAX_DEV][PCI_MAX_FUNC];
135
136         cprintf("Searching for RealTek 8168 Network device...");
137
138         for (int i = 0; i < PCI_MAX_BUS; i++)
139                 for (int j = 0; j < PCI_MAX_DEV; j++)
140                         for (int k = 0; k < PCI_MAX_FUNC; k++) {
141                                 uint32_t address;
142                                 uint32_t bus = i;
143                                 uint32_t dev = j;
144                                 uint32_t func = k;
145                                 uint32_t reg = 0; 
146                                 uint32_t result  = 0;
147         
148                                 uint16_t dev_id = pci_dev_map[i][j][k].dev_id;
149                                 uint16_t ven_id = pci_dev_map[i][j][k].ven_id;
150
151                                 // Vender DNE
152                                 if (ven_id == INVALID_VENDOR_ID) 
153                                         continue;
154
155                                 // Ignore non RealTek 8168 Devices
156                                 if (ven_id != REALTEK_VENDOR_ID || dev_id != REALTEK_DEV_ID)
157                                         continue;
158                                 cprintf(" found on BUS %x DEV %x\n", i, j);
159
160                                 // Find the IRQ
161                                 rl8168_irq = pci_irq_map[i][j][k];
162                                 rl8168_debug("-->IRQ: %u\n", rl8168_irq);
163
164                                 // Loop over the BARs
165                                 for (int k = 0; k <= 5; k++) {
166                                         reg = 4 + k;
167                                         address = MK_CONFIG_ADDR(bus, dev, func, reg << 2);     
168                                 outl(PCI_CONFIG_ADDR, address);
169                                 result = inl(PCI_CONFIG_DATA);
170                                         
171                                         if (result == 0) // (0 denotes no valid data)
172                                                 continue;
173
174                                         // Read the bottom bit of the BAR. 
175                                         if (result & PCI_BAR_IO_MASK) {
176                                                 result = result & PCI_IO_MASK;
177                                                 rl8168_debug("-->BAR%u: %s --> %x\n", k, "IO", result);
178                                         } else {
179                                                 result = result & PCI_MEM_MASK;
180                                                 rl8168_debug("-->BAR%u: %s --> %x\n", k, "MEM", result);
181                                         }
182                         
183                                         // TODO Switch to memory mapped instead of IO?
184                                         if (k == 0) // BAR0 denotes the IO Addr for the device
185                                                 rl8168_io_base_addr = result;                                           
186                                 }
187                 
188                 rl8168_debug("-->hwrev: %x\n", inl(rl8168_io_base_addr + RL_HWREV_REG) & RL_HWREV_MASK);
189                 
190                 return 0;
191         }
192         cprintf(" not found. No device configured.\n");
193         
194         return -1;
195 }
196
197 void rl8168_read_mac() {
198         
199         for (int i = 0; i < 6; i++)
200            device_mac[i] = inb(rl8168_io_base_addr + RL_MAC_OFFSET + i); 
201         
202         rl8168_debug("-->DEVICE MAC: %02x:%02x:%02x:%02x:%02x:%02x\n", 0xFF & device_mac[0], 0xFF & device_mac[1],      
203                                                                     0xFF & device_mac[2], 0xFF & device_mac[3], 
204                                                                 0xFF & device_mac[4], 0xFF & device_mac[5]);
205         return;
206 }
207
208 void rl8168_setup_descriptors() {
209         
210         rl8168_debug("-->Setting up tx/rx descriptors.\n");
211                         
212         // Allocate room for the buffers. 
213         // Buffers need to be on 256 byte boundries.
214         // Note: We use get_cont_pages to force page alignment, and thus 256 byte aligned
215
216         uint32_t num_rx_pages = ROUNDUP(NUM_RX_DESCRIPTORS * sizeof(struct Descriptor), PGSIZE) / PGSIZE;
217         uint32_t num_tx_pages = ROUNDUP(NUM_TX_DESCRIPTORS * sizeof(struct Descriptor), PGSIZE) / PGSIZE;
218         
219         rx_des_kva = get_cont_pages(LOG2_UP(num_rx_pages), 0);
220         tx_des_kva = get_cont_pages(LOG2_UP(num_tx_pages), 0);
221
222         if (rx_des_kva == NULL) panic("Can't allocate page for RX Ring");
223         if (tx_des_kva == NULL) panic("Can't allocate page for TX Ring");
224         
225         rx_des_pa = PADDR(rx_des_kva);
226         tx_des_pa = PADDR(tx_des_kva);
227         
228     for (int i = 0; i < NUM_RX_DESCRIPTORS; i++) 
229                 rl8168_set_rx_descriptor(i, TRUE); // Allocate memory for the descriptor
230                 
231         for (int i = 0; i < NUM_TX_DESCRIPTORS; i++) 
232                 rl8168_set_tx_descriptor(i);
233                 
234         return;
235 }
236
237
238 void rl8168_set_rx_descriptor(uint32_t des_num, uint8_t reset_buffer) {
239         
240         // Set the OWN bit on all descriptors. Also set the buffer size.
241         rx_des_kva[des_num].command = (DES_OWN_MASK | (RL_RX_MAX_BUFFER_SIZE & DES_RX_SIZE_MASK));
242         
243         if (des_num == (NUM_RX_DESCRIPTORS - 1)) 
244                 rx_des_kva[des_num].command = rx_des_kva[des_num].command | DES_EOR_MASK;
245         
246         if (reset_buffer) {
247                 // Must be aligned on 8 byte boundries. Taken care of by kmalloc.
248                 char *rx_buffer = kmalloc(RL_RX_MAX_BUFFER_SIZE, 0);
249         
250                 if (rx_buffer == NULL) panic ("Can't allocate page for RX Buffer");
251
252                 rx_des_kva[des_num].low_buf = PADDR(rx_buffer);
253                 //.high_buf used if we do 64bit.
254         }
255         
256         return;
257 }
258
259 void rl8168_set_tx_descriptor(uint32_t des_num) {
260         
261         // Clear the command bits.
262         tx_des_kva[des_num].command = 0;
263         
264         // Set EOR bit on last descriptor
265         if (des_num == (NUM_TX_DESCRIPTORS - 1))
266                 tx_des_kva[des_num].command = DES_EOR_MASK;     
267                 
268         char *tx_buffer = kmalloc(RL_TX_MAX_BUFFER_SIZE, 0);
269
270         if (tx_buffer == NULL) panic ("Can't allocate page for TX Buffer");
271
272         tx_des_kva[des_num].low_buf = PADDR(tx_buffer);
273         //.high_buf used if we do 64bit.
274                 
275         return;
276 }
277
278 void rl8168_configure() {
279         
280         // TODO: Weigh resetting the nic. Not really needed. Remove?
281         // TODO Check ordering of what we set.
282         // TODO Remove C+ register setting?
283         
284         rl8168_debug("-->Configuring Device.\n");
285         rl8168_reset();
286
287         // Magic to handle the C+ register. Completely undocumented, ripped from the BSE RE driver.
288         outl(rl8168_io_base_addr + RL_CP_CTRL_REG, RL_CP_MAGIC_MASK);
289
290         // Unlock EPPROM CTRL REG
291         outb(rl8168_io_base_addr + RL_EP_CTRL_REG, RL_EP_CTRL_UL_MASK);         
292         
293         // Set max RX Packet Size
294     outw(rl8168_io_base_addr + RL_RX_MXPKT_REG, RL_RX_MAX_SIZE);        
295                 
296         // Set max TX Packet Size
297     outb(rl8168_io_base_addr + RL_TX_MXPKT_REG, RL_TX_MAX_SIZE);                        
298
299         // Set TX Des Ring Start Addr
300     outl(rl8168_io_base_addr + RL_TX_DES_REG, (unsigned long)tx_des_pa); 
301         
302         // Set RX Des Ring Start Addr
303     outl(rl8168_io_base_addr + RL_RX_DES_REG, (unsigned long)rx_des_pa);        
304
305         // Configure TX
306         outl(rl8168_io_base_addr + RL_TX_CFG_REG, RL_TX_CFG_MASK); 
307         
308         // Configure RX
309         outl(rl8168_io_base_addr + RL_TX_CFG_REG, RL_RX_CFG_MASK);                      
310
311         // Enable RX and TX in the CTRL Reg
312         outb(rl8168_io_base_addr + RL_CTRL_REG, RL_CTRL_RXTX_MASK);                     
313
314         // Lock the EPPROM Ctrl REG
315     outl(rl8168_io_base_addr + RL_EP_CTRL_REG, RL_EP_CTRL_L_MASK);              
316         
317         return;
318 }
319
320 void rl8168_reset() {
321         
322         rl8168_debug("-->Resetting device..... ");
323         outb(rl8168_io_base_addr + RL_CTRL_REG, RL_CTRL_RESET_MASK);
324         
325         // Wait for NIC to answer "done resetting" before continuing on
326         while (inb(rl8168_io_base_addr + RL_CTRL_REG) & RL_CTRL_RESET_MASK);
327         rl8168_debug(" done.\n");
328         
329         return;
330 }
331
332 void rl8168_setup_interrupts() {
333         
334         extern handler_t interrupt_handlers[];
335         
336         rl8168_debug("-->Setting interrupts.\n");
337         
338         // Enable NIC interrupts
339         outw(rl8168_io_base_addr + RL_IM_REG, RL_INTERRUPT_MASK);
340         
341         //Clear the current interrupts.
342         outw(rl8168_io_base_addr + RL_IS_REG, RL_INTRRUPT_CLEAR);
343         
344         // Kernel based interrupt stuff
345 #ifdef __IVY__
346         register_interrupt_handler(interrupt_handlers, KERNEL_IRQ_OFFSET + rl8168_irq, rl8168_interrupt_handler, (void *)0);
347 #else
348         register_interrupt_handler(interrupt_handlers, KERNEL_IRQ_OFFSET + rl8168_irq, rl8168_interrupt_handler, 0);
349 #endif
350         ioapic_route_irq(rl8168_irq, NE2K_IRQ_CPU);     
351         
352         return;
353 }
354
355 // We need to evaluate this routine in terms of concurrency.
356 // We also need to figure out whats up with different core interrupts
357 void rl8168_interrupt_handler(trapframe_t *tf, void* data) {
358         
359         rl8168_interrupt_debug("\nNic interrupt on core %u!\n", lapic_get_id());
360                                 
361         // Read the offending interrupt(s)
362         uint16_t interrupt_status = inw(rl8168_io_base_addr + RL_IS_REG);
363
364         // Clear interrupts immediately so we can get the flag raised again.
365         outw(rl8168_io_base_addr + RL_IS_REG, interrupt_status);
366         
367         // Loop to deal with TOCTOU 
368         while (interrupt_status != 0x0000) {
369                 // We can have multiple interrupts fire at once. I've personally seen this.
370                 // This means we need to handle this as a series of independent if's
371                 if (interrupt_status & RL_INT_ROK) {
372                         rl8168_interrupt_debug("-->RX OK\n");
373                         rl8168_handle_rx_packet();
374                 }       
375         
376                 if (interrupt_status & RL_INT_RERR) {
377                         rl8168_interrupt_debug("-->RX ERR\n");                  
378                 }
379         
380                 if (interrupt_status & RL_INT_TOK) {
381                         rl8168_interrupt_debug("-->TX OK\n");
382                 }
383         
384                 if (interrupt_status & RL_INT_TERR) {
385                         rl8168_interrupt_debug("-->TX ERR\n");                  
386                 }
387         
388                 if (interrupt_status & RL_INT_RDU) {
389                         rl8168_interrupt_debug("-->RX Descriptor Unavailable\n");                       
390                 }
391         
392                 if (interrupt_status & RL_INT_LINKCHG) {
393                         rl8168_interrupt_debug("-->Link Status Changed\n");                     
394                 }
395         
396                 if (interrupt_status & RL_INT_FOVW) {
397                         rl8168_interrupt_debug("-->RX Fifo Overflow\n");                        
398                 }
399         
400                 if (interrupt_status & RL_INT_TDU) {
401                         rl8168_interrupt_debug("-->TX Descriptor Unavailable\n");                       
402                 }
403         
404                 if (interrupt_status & RL_INT_SWINT) {
405                         rl8168_interrupt_debug("-->Software Generated Interrupt\n");
406                 }
407         
408                 if (interrupt_status & RL_INT_TIMEOUT) {
409                         rl8168_interrupt_debug("-->Timer Expired\n");
410                 }
411         
412                 if (interrupt_status & RL_INT_SERR) {
413                         rl8168_interrupt_debug("-->PCI Bus System Error\n");                    
414                 }
415         
416                 rl8168_interrupt_debug("\n");
417                 
418                 // Clear interrupts     
419                 interrupt_status = inw(rl8168_io_base_addr + RL_IS_REG);
420                 outw(rl8168_io_base_addr + RL_IS_REG, interrupt_status);
421         }
422         
423         // In the event that we got really unlucky and more data arrived after we set 
424         //  set the bit last, try one more check
425         rl8168_handle_rx_packet();
426         return;
427 }
428
429 // TODO: Does a packet too large get dropped or just set the error bits in the descriptor? Find out.
430 // TODO: Should we move on to look for the next descriptor? is it safe? TOCTOU
431 void rl8168_handle_rx_packet() {
432         
433         uint32_t current_command = rx_des_kva[rx_des_cur].command;
434         uint16_t packet_size;
435         
436         if (current_command & DES_OWN_MASK) {
437                 rl8168_frame_debug("-->Nothing to process. Returning.");
438                 return;
439         }
440                 
441         rl8168_frame_debug("-->RX Des: %u\n", rx_des_cur);
442         
443         // Make sure we are processing from the start of a packet segment
444         if (!(current_command & DES_FS_MASK)) {
445                 rl8168_frame_debug("-->ERR: Current RX descriptor not marked with FS mask. Panic!");
446                 panic("RX Descriptor Ring FS out of sync");
447         }
448         
449         // NOTE: We are currently configured that the max packet size is large enough to fit inside 1 descriptor buffer,
450         // So we should never be in a situation where a packet spans multiple descriptors.
451         // When we change this, this should operate in a loop until the LS mask is found
452         // Loop would begin here.
453         
454         uint32_t rx_des_loop_cur = rx_des_cur;
455         uint32_t frame_size = 0;
456         uint32_t fragment_size = 0;
457         uint32_t num_frags = 0;
458         
459         char *rx_buffer = kmalloc(MAX_FRAME_SIZE, 0);
460         
461         if (rx_buffer == NULL) panic ("Can't allocate page for incoming packet.");
462         
463         do {
464                 current_command =  rx_des_kva[rx_des_loop_cur].command;
465                 fragment_size = rx_des_kva[rx_des_loop_cur].command & DES_RX_SIZE_MASK;
466                 
467                 // If we've looped through the entire ring and not found a terminating packet, bad nic state.
468                 // Panic or clear all descriptors? This is a nic hardware error. 
469                 if (num_frags && (rx_des_loop_cur == rx_des_cur)) {
470                         //for (int i = 0; i < NUM_RX_DESCRIPTORS; i++) 
471                         //      set_rx_descriptor(i, FALSE); // Dont reallocate memory for the descriptor
472                         // rx_des_cur = 0;
473                         // return;
474                         rl8168_frame_debug("-->ERR: No ending segment found in RX buffer.\n");
475                         panic("RX Descriptor Ring out of sync.");
476                 }
477                 
478                 num_frags++;
479                 
480                 
481                 // Make sure we own the current packet. Kernel ownership is denoted by a 0. Nic by a 1.
482                 if (current_command & DES_OWN_MASK) {
483                         rl8168_frame_debug("-->ERR: Current RX descriptor not owned by kernel. Panic!");
484                         panic("RX Descriptor Ring OWN out of sync");
485                 }
486                 
487                 // Make sure if we are at the end of the buffer, the des is marked as end
488                 if ((rx_des_loop_cur == (NUM_RX_DESCRIPTORS - 1)) && !(current_command & DES_EOR_MASK)) {
489                         rl8168_frame_debug("-->ERR: Last RX descriptor not marked with EOR mask. Panic!\n");
490                         panic("RX Descriptor Ring EOR Missing");
491                 }
492                 
493                 // We set a max frame size and the nic violated that. 
494                 // Panic or clear all desriptors?
495                 if ((frame_size + fragment_size) > MAX_FRAME_SIZE) {
496                         //for (int i = 0; i < NUM_RX_DESCRIPTORS; i++) 
497                         //      set_rx_descriptor(i, FALSE); // Dont reallocate memory for the descriptor
498                         // rx_des_cur = 0;
499                         // return;
500                         rl8168_frame_debug("-->ERR: Nic sent %u byte packet. Max is %u\n", frame_size, MAX_FRAME_SIZE);
501                         panic("NIC Sent packets larger than configured.");
502                 }
503                 
504                 // Move the fragment data into the buffer
505                 memcpy(rx_buffer + frame_size, KADDR(rx_des_kva[rx_des_loop_cur].low_buf), fragment_size);
506                 
507                 // Reset the descriptor. No reuse buffer.
508                 rl8168_set_rx_descriptor(rx_des_loop_cur, FALSE);
509                 
510                 // Note: We mask out fragment sizes at 0x3FFFF. There can be at most 1024 of them.
511                 // This can not overflow the uint32_t we allocated for frame size, so
512                 // we dont need to worry about mallocing too little then overflowing when we read.
513                 frame_size = frame_size + fragment_size;
514                 
515                 // Advance to the next descriptor
516                 rx_des_loop_cur = (rx_des_loop_cur + 1) % NUM_RX_DESCRIPTORS;
517                 
518         } while (!(current_command & DES_LS_MASK));
519         
520         // Hack for UDP syscall hack. 
521         // This is a quick hack to let us deal with where to put packets coming in. This is not concurrency friendly
522         // In the event that we get 2 incoming frames for our syscall test (shouldnt happen)
523         // We cant process more until another packet comes in. This is ugly, but this code goes away as soon as we integrate a real stack.
524         // This keys off the source port, fix it for dest port. 
525         // Also this may access packet regions that are wrong. If someone addresses empty packet for our interface
526         // and the bits that happened to be in memory before are the right port, this will trigger. this is bad
527         // but since syscalls are a hack for only 1 machine connected, we dont care for now.
528         
529         if ((current_command & DES_PAM_MASK) && (*((uint16_t*)(rx_buffer + 36)) == 0x9bad)) {
530                 
531                 if (packet_waiting) return;
532                 
533                 // So ugly I want to cry
534                 packet_buffer_size = *((uint16_t*)(rx_buffer + 38)); 
535                 packet_buffer_size = (((uint16_t)packet_buffer_size & 0xff00) >> 8) |  (((uint16_t)packet_buffer_size & 0x00ff) << 8);          
536                 packet_buffer_size = packet_buffer_size - 8;
537
538                 packet_buffer = rx_buffer + PACKET_HEADER_SIZE;
539
540                 packet_buffer_orig = rx_buffer;
541                 packet_buffer_pos = 0;
542                 
543                 packet_waiting = 1;
544                 
545                 rl8168_process_frame(rx_buffer, frame_size, current_command);
546                 
547                 rx_des_cur = rx_des_loop_cur;
548                 
549                 return;
550         }
551         
552         // END HACKY STUFF
553         
554         // Chew on the frame data. Command bits should be the same for all frags.
555         rl8168_process_frame(rx_buffer, frame_size, current_command);
556
557         rx_des_cur = rx_des_loop_cur;
558         
559         kfree(rx_buffer);
560         
561         return;
562 }
563
564 // This is really more of a debug level function. Will probably go away once we get a stack going.
565 void rl8168_process_frame(char *frame_buffer, uint32_t frame_size, uint32_t command) {
566                 
567         rl8168_frame_debug("-->Command: %x\n", command);
568         rl8168_frame_debug("-->Size: %u\n", frame_size);
569         
570         if (frame_buffer == NULL)
571                 return;
572         
573         // This is hacky. Once we know what our stack will look like, change this.
574         // Once remove check for 0 size.
575         if (frame_size < MINIMUM_PACKET_SIZE) {
576                 rl8168_frame_debug("-->Packet too small. Discarding.\n");
577                 return;
578         }
579         
580         char dest_mac[6];
581         char source_mac[6];
582         char eth_type[2];
583         
584         for (int i = 0; i < 6; i++) {
585                 dest_mac[i] = frame_buffer[i];
586         }
587         
588         for (int i = 0; i < 6; i++) {
589                 source_mac[i] = frame_buffer[i+6];
590         }
591         
592         eth_type[0] = frame_buffer[12];
593         eth_type[1] = frame_buffer[13];
594         
595         if (command & DES_MAR_MASK) {
596                 rl8168_frame_debug("-->Multicast Packet.\n");
597         }
598         
599         if (command & DES_PAM_MASK) {
600                 rl8168_frame_debug("-->Physical Address Matched.\n");
601         }
602         
603         if (command & DES_BAR_MASK) {
604                 rl8168_frame_debug("-->Broadcast Packet.\n");
605         }
606         
607         // Note: DEST comes before SRC in the ethernet frame, but that 
608         
609         rl8168_frame_debug("-->DEST   MAC: %02x:%02x:%02x:%02x:%02x:%02x\n", 0xFF & dest_mac[0], 0xFF & dest_mac[1],    
610                                                                              0xFF & dest_mac[2], 0xFF & dest_mac[3],    
611                                                                              0xFF & dest_mac[4], 0xFF & dest_mac[5]);
612         
613         rl8168_frame_debug("-->SOURCE MAC: %02x:%02x:%02x:%02x:%02x:%02x\n", 0xFF & source_mac[0], 0xFF & source_mac[1],        
614                                                                              0xFF & source_mac[2], 0xFF & source_mac[3],        
615                                                                              0xFF & source_mac[4], 0xFF & source_mac[5]);
616
617         rl8168_frame_debug("-->ETHR MODE: %02x%02x\n", 0xFF & eth_type[0], 0xFF & eth_type[1]);
618                 
619         return;
620 }
621
622 // Main routine to send a frame. Just sends it and goes.
623 // Card supports sending across multiple fragments.
624 // Would we want to write a function that takes a larger packet and generates fragments?
625 // This seems like the stacks responsibility. Leave this for now. may in future
626 // Remove the max size cap and generate multiple packets.
627 int rl8168_send_frame(const char *data, size_t len) {
628
629         if (data == NULL)
630                 return -1;
631         if (len == 0)
632                 return 0;
633
634         if (tx_des_kva[tx_des_cur].command & DES_OWN_MASK) {
635                 rl8168_frame_debug("-->TX Ring Buffer Full!\n");
636                 return -1;
637         }
638         
639         if (len > MAX_FRAME_SIZE) {
640                 rl8168_frame_debug("-->Frame Too Large!\n");
641                 return -1;
642         }
643         
644         memcpy(KADDR(tx_des_kva[tx_des_cur].low_buf), data, len);
645
646         tx_des_kva[tx_des_cur].command = tx_des_kva[tx_des_cur].command | len | DES_OWN_MASK | DES_FS_MASK | DES_LS_MASK;
647
648         // For this revision of the NIC, the checksum bits get set in the vlan field not the command field.
649         // THIS IS A HACK: Need to reach inside the frame we are sending and detect if its of type ip/udp/tcp and set right flag
650         // For now, for the syscall hack, force ip checksum on. (we dont care about udp checksum).
651         // Add an argument to function to specify packet type?
652         //tx_des_kva[tx_des_cur].vlan = DES_TX_IP_CHK_MASK;
653         tx_des_kva[tx_des_cur].vlan = 0;
654
655
656         tx_des_cur = (tx_des_cur + 1) % NUM_TX_DESCRIPTORS;
657         
658         //rl8168_frame_debug("-->Sent packet.\n");
659         
660         outb(rl8168_io_base_addr + RL_TX_CTRL_REG, RL_TX_SEND_MASK);
661         
662         return len;
663 }
664
665 // This function is a complete hack for syscalls until we get a stack.
666 // the day I delete this monstrosity of code I will be a happy man --Paul
667 char *CT(PACKET_HEADER_SIZE + len) rl8168_packet_wrap(const char* data, size_t len) {
668         
669         #define htons(A) ((((uint16_t)(A) & 0xff00) >> 8) | \
670                             (((uint16_t)(A) & 0x00ff) << 8))
671         #define htonl(A) ((((uint32_t)(A) & 0xff000000) >> 24) | \
672                             (((uint32_t)(A) & 0x00ff0000) >> 8)  | \
673                             (((uint32_t)(A) & 0x0000ff00) << 8)  | \
674                             (((uint32_t)(A) & 0x000000ff) << 24))
675
676         #define ntohs  htons
677         #define ntohl  htohl
678
679         if ((len == 0) || (data == NULL))
680                 return NULL;
681
682         // Hard coded to paul's laptop's mac
683         //Format for Makelocal file: -DUSER_MAC_ADDRESS="{0x00, 0x23, 0x32, 0xd5, 0xae, 0x82}"
684         char dest_mac_address[6] = USER_MAC_ADDRESS;
685         
686         
687         uint32_t source_ip = 0xC0A8000A; // 192.168.0.10
688         uint32_t dest_ip   = 0xC0A8000B; // 192.168.0.11
689  
690         
691         if (len > MAX_PACKET_DATA) {
692                 rl8168_frame_debug("Bad packet size for packet wrapping");
693                 return NULL;
694         }
695         
696         struct eth_packet* wrap_buffer = kmalloc(MAX_PACKET_SIZE, 0);
697         
698         if (wrap_buffer == NULL) {
699                 rl8168_frame_debug("Can't allocate page for packet wrapping");
700                 return NULL;
701         }
702         
703
704         struct ETH_Header *eth_header = &wrap_buffer->eth_head.eth_head;
705         struct IP_Header *ip_header = &wrap_buffer->eth_head.ip_head;
706         struct UDP_Header *udp_header = &wrap_buffer->eth_head.udp_head;
707         
708         // Setup eth data
709         for (int i = 0; i < 6; i++) 
710                 eth_header->dest_mac[i] = dest_mac_address[i];
711                 
712         for (int i = 0; i < 6; i++) 
713                 eth_header->source_mac[i] = device_mac[i];
714                 
715         eth_header->eth_type = htons(0x0800);
716         
717         // Setup IP data
718         ip_header->ip_opts0 = htonl((4<<28) | (5 << 24) | (len + 28));
719         ip_header->ip_opts1 = 0;
720         ip_header->ip_opts2 = 0x00110a;
721         ip_header->source_ip = htonl(source_ip);
722         ip_header->dest_ip = htonl(dest_ip);
723         
724         // Setup UDP Data
725         udp_header->source_port = htons(44443);
726         udp_header->dest_port = htons(44444);
727         udp_header->length = htons(8 + len);
728         udp_header->checksum = 0;
729         
730         memcpy (&wrap_buffer->data[0], data, len);
731         
732         return (char *CT(PACKET_HEADER_SIZE + len))wrap_buffer; 
733 }