29ece818c9e99c315b233449ea74696f8adfd5b7
[akaros.git] / kern / arch / i686 / 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 __CONFIG_NETWORKING__ 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
87 struct Descriptor *CT(NUM_RX_DESCRIPTORS) rx_des_kva;
88 unsigned long rx_des_pa;
89
90 struct Descriptor *CT(NUM_TX_DESCRIPTORS) tx_des_kva;
91 unsigned long tx_des_pa;
92
93 uint32_t rx_des_cur = 0;
94 uint32_t tx_des_cur = 0;
95
96
97
98 void rl8168_init() {
99
100         if (rl8168_scan_pci() < 0) return;
101         rl8168_read_mac();
102         printk("Network Card MAC Address: %02x:%02x:%02x:%02x:%02x:%02x\n", 
103            device_mac[0],device_mac[1],device_mac[2],
104            device_mac[3],device_mac[4],device_mac[5]);
105         rl8168_setup_descriptors();
106         rl8168_configure();
107         rl8168_setup_interrupts();
108         send_frame = &rl8168_send_frame;
109
110         eth_up = 1;
111         
112         //Trigger sw based nic interrupt
113 /*      cprintf("Generating interrupt...\n");
114         outb(rl8168_io_base_addr + 0x38, 0x1);
115         cprintf("sleeping\n");
116         udelay(3000000);
117         cprintf("done\n");
118 */
119         return;
120 }
121
122
123 int rl8168_scan_pci() {
124         
125         extern pci_dev_entry_t pci_dev_map[PCI_MAX_BUS][PCI_MAX_DEV][PCI_MAX_FUNC];
126         extern uint16_t pci_irq_map[PCI_MAX_BUS][PCI_MAX_DEV][PCI_MAX_FUNC];
127
128         cprintf("Searching for RealTek 8168 Network device...");
129
130         for (int i = 0; i < PCI_MAX_BUS; i++)
131                 for (int j = 0; j < PCI_MAX_DEV; j++)
132                         for (int k = 0; k < PCI_MAX_FUNC; k++) {
133                                 uint32_t address;
134                                 uint32_t bus = i;
135                                 uint32_t dev = j;
136                                 uint32_t func = k;
137                                 uint32_t reg = 0; 
138                                 uint32_t result  = 0;
139         
140                                 uint16_t dev_id = pci_dev_map[i][j][k].dev_id;
141                                 uint16_t ven_id = pci_dev_map[i][j][k].ven_id;
142
143                                 // Vender DNE
144                                 if (ven_id == INVALID_VENDOR_ID) 
145                                         continue;
146
147                                 // Ignore non RealTek 8168 Devices
148                                 if (ven_id != REALTEK_VENDOR_ID || dev_id != REALTEK_DEV_ID)
149                                         continue;
150                                 cprintf(" found on BUS %x DEV %x\n", i, j);
151
152                                 // Find the IRQ
153                                 rl8168_irq = pci_irq_map[i][j][k];
154                                 rl8168_debug("-->IRQ: %u\n", rl8168_irq);
155
156                                 // Loop over the BARs
157                                 for (int k = 0; k <= 5; k++) {
158                                         reg = 4 + k;
159                                         address = MK_CONFIG_ADDR(bus, dev, func, reg << 2);     
160                                 outl(PCI_CONFIG_ADDR, address);
161                                 result = inl(PCI_CONFIG_DATA);
162                                         
163                                         if (result == 0) // (0 denotes no valid data)
164                                                 continue;
165
166                                         // Read the bottom bit of the BAR. 
167                                         if (result & PCI_BAR_IO_MASK) {
168                                                 result = result & PCI_IO_MASK;
169                                                 rl8168_debug("-->BAR%u: %s --> %x\n", k, "IO", result);
170                                         } else {
171                                                 result = result & PCI_MEM_MASK;
172                                                 rl8168_debug("-->BAR%u: %s --> %x\n", k, "MEM", result);
173                                         }
174                         
175                                         // TODO Switch to memory mapped instead of IO?
176                                         if (k == 0) // BAR0 denotes the IO Addr for the device
177                                                 rl8168_io_base_addr = result;                                           
178                                 }
179                 
180                 rl8168_debug("-->hwrev: %x\n", inl(rl8168_io_base_addr + RL_HWREV_REG) & RL_HWREV_MASK);
181                 
182                 return 0;
183         }
184         cprintf(" not found. No device configured.\n");
185         
186         return -1;
187 }
188
189 void rl8168_read_mac() {
190         
191         for (int i = 0; i < 6; i++)
192            device_mac[i] = inb(rl8168_io_base_addr + RL_MAC_OFFSET + i); 
193         
194         rl8168_debug("-->DEVICE MAC: %02x:%02x:%02x:%02x:%02x:%02x\n", 0xFF & device_mac[0], 0xFF & device_mac[1],      
195                                                                     0xFF & device_mac[2], 0xFF & device_mac[3], 
196                                                                 0xFF & device_mac[4], 0xFF & device_mac[5]);
197         return;
198 }
199
200 void rl8168_setup_descriptors() {
201         
202         rl8168_debug("-->Setting up tx/rx descriptors.\n");
203                         
204         // Allocate room for the buffers. 
205         // Buffers need to be on 256 byte boundries.
206         // Note: We use get_cont_pages to force page alignment, and thus 256 byte aligned
207
208         uint32_t num_rx_pages = ROUNDUP(NUM_RX_DESCRIPTORS * sizeof(struct Descriptor), PGSIZE) / PGSIZE;
209         uint32_t num_tx_pages = ROUNDUP(NUM_TX_DESCRIPTORS * sizeof(struct Descriptor), PGSIZE) / PGSIZE;
210         
211         rx_des_kva = get_cont_pages(LOG2_UP(num_rx_pages), 0);
212         tx_des_kva = get_cont_pages(LOG2_UP(num_tx_pages), 0);
213
214         if (rx_des_kva == NULL) panic("Can't allocate page for RX Ring");
215         if (tx_des_kva == NULL) panic("Can't allocate page for TX Ring");
216         
217         rx_des_pa = PADDR(rx_des_kva);
218         tx_des_pa = PADDR(tx_des_kva);
219         
220     for (int i = 0; i < NUM_RX_DESCRIPTORS; i++) 
221                 rl8168_set_rx_descriptor(i, TRUE); // Allocate memory for the descriptor
222                 
223         for (int i = 0; i < NUM_TX_DESCRIPTORS; i++) 
224                 rl8168_set_tx_descriptor(i);
225                 
226         return;
227 }
228
229
230 void rl8168_set_rx_descriptor(uint32_t des_num, uint8_t reset_buffer) {
231         
232         // Set the OWN bit on all descriptors. Also set the buffer size.
233         rx_des_kva[des_num].command = (DES_OWN_MASK | (RL_RX_MAX_BUFFER_SIZE & DES_RX_SIZE_MASK));
234         
235         if (des_num == (NUM_RX_DESCRIPTORS - 1)) 
236                 rx_des_kva[des_num].command = rx_des_kva[des_num].command | DES_EOR_MASK;
237         
238         if (reset_buffer) {
239                 // Must be aligned on 8 byte boundries. Taken care of by kmalloc.
240                 char *rx_buffer = kmalloc(RL_RX_MAX_BUFFER_SIZE, 0);
241         
242                 if (rx_buffer == NULL) panic ("Can't allocate page for RX Buffer");
243
244                 rx_des_kva[des_num].low_buf = PADDR(rx_buffer);
245                 //.high_buf used if we do 64bit.
246         }
247         
248         return;
249 }
250
251 void rl8168_set_tx_descriptor(uint32_t des_num) {
252         
253         // Clear the command bits.
254         tx_des_kva[des_num].command = 0;
255         
256         // Set EOR bit on last descriptor
257         if (des_num == (NUM_TX_DESCRIPTORS - 1))
258                 tx_des_kva[des_num].command = DES_EOR_MASK;     
259                 
260         char *tx_buffer = kmalloc(RL_TX_MAX_BUFFER_SIZE, 0);
261
262         if (tx_buffer == NULL) panic ("Can't allocate page for TX Buffer");
263
264         tx_des_kva[des_num].low_buf = PADDR(tx_buffer);
265         //.high_buf used if we do 64bit.
266                 
267         return;
268 }
269
270 void rl8168_configure() {
271         
272         // TODO: Weigh resetting the nic. Not really needed. Remove?
273         // TODO Check ordering of what we set.
274         // TODO Remove C+ register setting?
275         
276         rl8168_debug("-->Configuring Device.\n");
277         rl8168_reset();
278
279         // Magic to handle the C+ register. Completely undocumented, ripped from the BSE RE driver.
280         outl(rl8168_io_base_addr + RL_CP_CTRL_REG, RL_CP_MAGIC_MASK);
281
282         // Unlock EPPROM CTRL REG
283         outb(rl8168_io_base_addr + RL_EP_CTRL_REG, RL_EP_CTRL_UL_MASK);         
284         
285         // Set max RX Packet Size
286     outw(rl8168_io_base_addr + RL_RX_MXPKT_REG, RL_RX_MAX_SIZE);        
287                 
288         // Set max TX Packet Size
289     outb(rl8168_io_base_addr + RL_TX_MXPKT_REG, RL_TX_MAX_SIZE);                        
290
291         // Set TX Des Ring Start Addr
292     outl(rl8168_io_base_addr + RL_TX_DES_REG, (unsigned long)tx_des_pa); 
293         
294         // Set RX Des Ring Start Addr
295     outl(rl8168_io_base_addr + RL_RX_DES_REG, (unsigned long)rx_des_pa);        
296
297         // Configure TX
298         outl(rl8168_io_base_addr + RL_TX_CFG_REG, RL_TX_CFG_MASK); 
299         
300         // Configure RX
301         outl(rl8168_io_base_addr + RL_TX_CFG_REG, RL_RX_CFG_MASK);                      
302
303         // Enable RX and TX in the CTRL Reg
304         outb(rl8168_io_base_addr + RL_CTRL_REG, RL_CTRL_RXTX_MASK);                     
305
306         // Lock the EPPROM Ctrl REG
307     outl(rl8168_io_base_addr + RL_EP_CTRL_REG, RL_EP_CTRL_L_MASK);              
308         
309         return;
310 }
311
312 void rl8168_reset() {
313         
314         rl8168_debug("-->Resetting device..... ");
315         outb(rl8168_io_base_addr + RL_CTRL_REG, RL_CTRL_RESET_MASK);
316         
317         // Wait for NIC to answer "done resetting" before continuing on
318         while (inb(rl8168_io_base_addr + RL_CTRL_REG) & RL_CTRL_RESET_MASK);
319         rl8168_debug(" done.\n");
320         
321         return;
322 }
323
324 void rl8168_setup_interrupts() {
325         
326         extern handler_t interrupt_handlers[];
327         
328         rl8168_debug("-->Setting interrupts.\n");
329         
330         // Enable NIC interrupts
331         outw(rl8168_io_base_addr + RL_IM_REG, RL_INTERRUPT_MASK);
332         
333         //Clear the current interrupts.
334         outw(rl8168_io_base_addr + RL_IS_REG, RL_INTRRUPT_CLEAR);
335         
336         // Kernel based interrupt stuff
337         register_interrupt_handler(interrupt_handlers, KERNEL_IRQ_OFFSET + rl8168_irq, rl8168_interrupt_handler, 0);
338 #ifdef __CONFIG_DISABLE_MPTABLES__
339         pic_unmask_irq(rl8168_irq);
340         unmask_lapic_lvt(LAPIC_LVT_LINT0);
341         enable_irq();
342 #else
343         ioapic_route_irq(rl8168_irq, 1);        
344 #endif
345         
346         return;
347 }
348
349 // We need to evaluate this routine in terms of concurrency.
350 // We also need to figure out whats up with different core interrupts
351 void rl8168_interrupt_handler(trapframe_t *tf, void* data) {
352
353         rl8168_interrupt_debug("\nNic interrupt on core %u!\n", lapic_get_id());
354                                 
355         // Read the offending interrupt(s)
356         uint16_t interrupt_status = inw(rl8168_io_base_addr + RL_IS_REG);
357
358         // Clear interrupts immediately so we can get the flag raised again.
359         outw(rl8168_io_base_addr + RL_IS_REG, interrupt_status);
360         
361         // Loop to deal with TOCTOU 
362         while (interrupt_status != 0x0000) {
363                 // We can have multiple interrupts fire at once. I've personally seen this.
364                 // This means we need to handle this as a series of independent if's
365                 if (interrupt_status & RL_INT_ROK) {
366                         rl8168_interrupt_debug("-->RX OK\n");
367                         rl8168_handle_rx_packet();
368                 }       
369         
370                 if (interrupt_status & RL_INT_RERR) {
371                         rl8168_interrupt_debug("-->RX ERR\n");                  
372                 }
373         
374                 if (interrupt_status & RL_INT_TOK) {
375                         rl8168_interrupt_debug("-->TX OK\n");
376                 }
377         
378                 if (interrupt_status & RL_INT_TERR) {
379                         rl8168_interrupt_debug("-->TX ERR\n");                  
380                 }
381         
382                 if (interrupt_status & RL_INT_RDU) {
383                         rl8168_interrupt_debug("-->RX Descriptor Unavailable\n");                       
384                 }
385         
386                 if (interrupt_status & RL_INT_LINKCHG) {
387                         rl8168_interrupt_debug("-->Link Status Changed\n");                     
388                 }
389         
390                 if (interrupt_status & RL_INT_FOVW) {
391                         rl8168_interrupt_debug("-->RX Fifo Overflow\n");                        
392                 }
393         
394                 if (interrupt_status & RL_INT_TDU) {
395                         rl8168_interrupt_debug("-->TX Descriptor Unavailable\n");                       
396                 }
397         
398                 if (interrupt_status & RL_INT_SWINT) {
399                         rl8168_interrupt_debug("-->Software Generated Interrupt\n");
400                 }
401         
402                 if (interrupt_status & RL_INT_TIMEOUT) {
403                         rl8168_interrupt_debug("-->Timer Expired\n");
404                 }
405         
406                 if (interrupt_status & RL_INT_SERR) {
407                         rl8168_interrupt_debug("-->PCI Bus System Error\n");                    
408                 }
409         
410                 rl8168_interrupt_debug("\n");
411                 
412                 // Clear interrupts     
413                 interrupt_status = inw(rl8168_io_base_addr + RL_IS_REG);
414                 outw(rl8168_io_base_addr + RL_IS_REG, interrupt_status);
415         }
416         
417         // In the event that we got really unlucky and more data arrived after we set 
418         //  set the bit last, try one more check
419         rl8168_handle_rx_packet();
420
421         return;
422 }
423
424 // TODO: Does a packet too large get dropped or just set the error bits in the descriptor? Find out.
425 // TODO: Should we move on to look for the next descriptor? is it safe? TOCTOU
426 void rl8168_handle_rx_packet() {
427         
428         uint32_t current_command = rx_des_kva[rx_des_cur].command;
429         uint16_t packet_size;
430         
431         if (current_command & DES_OWN_MASK) {
432                 rl8168_frame_debug("-->Nothing to process. Returning.");
433                 return;
434         }
435                 
436         rl8168_frame_debug("-->RX Des: %u\n", rx_des_cur);
437         
438         // Make sure we are processing from the start of a packet segment
439         if (!(current_command & DES_FS_MASK)) {
440                 rl8168_frame_debug("-->ERR: Current RX descriptor not marked with FS mask. Panic!");
441                 panic("RX Descriptor Ring FS out of sync");
442         }
443         
444         // NOTE: We are currently configured that the max packet size is large enough to fit inside 1 descriptor buffer,
445         // So we should never be in a situation where a packet spans multiple descriptors.
446         // When we change this, this should operate in a loop until the LS mask is found
447         // Loop would begin here.
448         
449         uint32_t rx_des_loop_cur = rx_des_cur;
450         uint32_t frame_size = 0;
451         uint32_t fragment_size = 0;
452         uint32_t num_frags = 0;
453         
454         char *rx_buffer = kmalloc(MAX_FRAME_SIZE, 0);
455         
456         if (rx_buffer == NULL) panic ("Can't allocate page for incoming packet.");
457         
458         do {
459                 current_command =  rx_des_kva[rx_des_loop_cur].command;
460                 fragment_size = rx_des_kva[rx_des_loop_cur].command & DES_RX_SIZE_MASK;
461                 
462                 // If we've looped through the entire ring and not found a terminating packet, bad nic state.
463                 // Panic or clear all descriptors? This is a nic hardware error. 
464                 if (num_frags && (rx_des_loop_cur == rx_des_cur)) {
465                         //for (int i = 0; i < NUM_RX_DESCRIPTORS; i++) 
466                         //      set_rx_descriptor(i, FALSE); // Dont reallocate memory for the descriptor
467                         // rx_des_cur = 0;
468                         // return;
469                         rl8168_frame_debug("-->ERR: No ending segment found in RX buffer.\n");
470                         panic("RX Descriptor Ring out of sync.");
471                 }
472                 
473                 num_frags++;
474                 
475                 
476                 // Make sure we own the current packet. Kernel ownership is denoted by a 0. Nic by a 1.
477                 if (current_command & DES_OWN_MASK) {
478                         rl8168_frame_debug("-->ERR: Current RX descriptor not owned by kernel. Panic!");
479                         panic("RX Descriptor Ring OWN out of sync");
480                 }
481                 
482                 // Make sure if we are at the end of the buffer, the des is marked as end
483                 if ((rx_des_loop_cur == (NUM_RX_DESCRIPTORS - 1)) && !(current_command & DES_EOR_MASK)) {
484                         rl8168_frame_debug("-->ERR: Last RX descriptor not marked with EOR mask. Panic!\n");
485                         panic("RX Descriptor Ring EOR Missing");
486                 }
487                 
488                 // We set a max frame size and the nic violated that. 
489                 // Panic or clear all desriptors?
490                 if ((frame_size + fragment_size) > MAX_FRAME_SIZE) {
491                         //for (int i = 0; i < NUM_RX_DESCRIPTORS; i++) 
492                         //      set_rx_descriptor(i, FALSE); // Dont reallocate memory for the descriptor
493                         // rx_des_cur = 0;
494                         // return;
495                         rl8168_frame_debug("-->ERR: Nic sent %u byte packet. Max is %u\n", frame_size, MAX_FRAME_SIZE);
496                         panic("NIC Sent packets larger than configured.");
497                 }
498                 
499                 // Move the fragment data into the buffer
500                 memcpy(rx_buffer + frame_size, KADDR(rx_des_kva[rx_des_loop_cur].low_buf), fragment_size);
501                 
502                 // Reset the descriptor. No reuse buffer.
503                 rl8168_set_rx_descriptor(rx_des_loop_cur, FALSE);
504                 
505                 // Note: We mask out fragment sizes at 0x3FFFF. There can be at most 1024 of them.
506                 // This can not overflow the uint32_t we allocated for frame size, so
507                 // we dont need to worry about mallocing too little then overflowing when we read.
508                 frame_size = frame_size + fragment_size;
509                 
510                 // Advance to the next descriptor
511                 rx_des_loop_cur = (rx_des_loop_cur + 1) % NUM_RX_DESCRIPTORS;
512                 
513         } while (!(current_command & DES_LS_MASK));
514
515         // Treat as a syscall frontend response packet if eth_type says so
516         // Will eventually go away, so not too worried about elegance here...
517         #include <frontend.h>
518         #include <arch/frontend.h>
519         uint16_t eth_type = htons(*(uint16_t*)(rx_buffer + 12));
520         if(eth_type == APPSERVER_ETH_TYPE) {
521                 rx_des_cur = rx_des_loop_cur;
522                 rl8168_process_frame(rx_buffer, frame_size, current_command);
523                 handle_appserver_packet(rx_buffer, frame_size);
524                 kfree(rx_buffer);
525                 return;
526         }
527
528         spin_lock(&packet_buffers_lock);
529
530         if (num_packet_buffers >= MAX_PACKET_BUFFERS) {
531                 //printk("WARNING: DROPPING PACKET!\n");
532                 spin_unlock(&packet_buffers_lock);
533                 rx_des_cur = rx_des_loop_cur;
534                 kfree(rx_buffer);
535                 return;
536         }
537
538         packet_buffers[packet_buffers_tail] = rx_buffer;
539         packet_buffers_sizes[packet_buffers_tail] = frame_size;
540                 
541         packet_buffers_tail = (packet_buffers_tail + 1) % MAX_PACKET_BUFFERS;
542         num_packet_buffers++;
543
544         spin_unlock(&packet_buffers_lock);
545                                 
546         rx_des_cur = rx_des_loop_cur;
547
548         // Chew on the frame data. Command bits should be the same for all frags.
549         rl8168_process_frame(rx_buffer, frame_size, current_command);
550         
551         return;
552 }
553
554 // This is really more of a debug level function. Will probably go away once we get a stack going.
555 void rl8168_process_frame(char *frame_buffer, uint32_t frame_size, uint32_t command) {
556                 
557         rl8168_frame_debug("-->Command: %x\n", command);
558         rl8168_frame_debug("-->Size: %u\n", frame_size);
559         
560         if (frame_buffer == NULL)
561                 return;
562         
563         // This is hacky. Once we know what our stack will look like, change this.
564         // Once remove check for 0 size.
565         if (frame_size < MIN_FRAME_SIZE) {
566                 rl8168_frame_debug("-->Packet too small. Discarding.\n");
567                 return;
568         }
569         
570         char dest_mac[6];
571         char source_mac[6];
572         char eth_type[2];
573         
574         for (int i = 0; i < 6; i++) {
575                 dest_mac[i] = frame_buffer[i];
576         }
577         
578         for (int i = 0; i < 6; i++) {
579                 source_mac[i] = frame_buffer[i+6];
580         }
581         
582         eth_type[0] = frame_buffer[12];
583         eth_type[1] = frame_buffer[13];
584         
585         if (command & DES_MAR_MASK) {
586                 rl8168_frame_debug("-->Multicast Packet.\n");
587         }
588         
589         if (command & DES_PAM_MASK) {
590                 rl8168_frame_debug("-->Physical Address Matched.\n");
591         }
592         
593         if (command & DES_BAR_MASK) {
594                 rl8168_frame_debug("-->Broadcast Packet.\n");
595         }
596         
597         // Note: DEST comes before SRC in the ethernet frame, but that 
598         
599         rl8168_frame_debug("-->DEST   MAC: %02x:%02x:%02x:%02x:%02x:%02x\n", 0xFF & dest_mac[0], 0xFF & dest_mac[1],    
600                                                                              0xFF & dest_mac[2], 0xFF & dest_mac[3],    
601                                                                              0xFF & dest_mac[4], 0xFF & dest_mac[5]);
602         
603         rl8168_frame_debug("-->SOURCE MAC: %02x:%02x:%02x:%02x:%02x:%02x\n", 0xFF & source_mac[0], 0xFF & source_mac[1],        
604                                                                              0xFF & source_mac[2], 0xFF & source_mac[3],        
605                                                                              0xFF & source_mac[4], 0xFF & source_mac[5]);
606
607         rl8168_frame_debug("-->ETHR MODE: %02x%02x\n", 0xFF & eth_type[0], 0xFF & eth_type[1]);
608                 
609         return;
610 }
611
612 // Main routine to send a frame. Just sends it and goes.
613 // Card supports sending across multiple fragments.
614 // Would we want to write a function that takes a larger packet and generates fragments?
615 // This seems like the stacks responsibility. Leave this for now. may in future
616 // Remove the max size cap and generate multiple packets.
617 int rl8168_send_frame(const char *data, size_t len) {
618
619         if (data == NULL)
620                 return -1;
621         if (len == 0)
622                 return 0;
623
624         if (tx_des_kva[tx_des_cur].command & DES_OWN_MASK) {
625                 rl8168_frame_debug("-->TX Ring Buffer Full!\n");
626                 return -1;
627         }
628         
629         if (len > MAX_FRAME_SIZE) {
630                 rl8168_frame_debug("-->Frame Too Large!\n");
631                 return -1;
632         }
633         
634         memcpy(KADDR(tx_des_kva[tx_des_cur].low_buf), data, len);
635
636         tx_des_kva[tx_des_cur].command = tx_des_kva[tx_des_cur].command | len | DES_OWN_MASK | DES_FS_MASK | DES_LS_MASK;
637
638         // For this revision of the NIC, the checksum bits get set in the vlan field not the command field.
639         // 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
640         // For now, for the syscall hack, force ip checksum on. (we dont care about udp checksum).
641         // Add an argument to function to specify packet type?
642         //tx_des_kva[tx_des_cur].vlan = DES_TX_IP_CHK_MASK;
643         tx_des_kva[tx_des_cur].vlan = 0;
644
645
646         tx_des_cur = (tx_des_cur + 1) % NUM_TX_DESCRIPTORS;
647         
648         rl8168_frame_debug("--> Sending Packet\n");
649         for(int i=0; i<len; i++)
650                 rl8168_frame_debug("%x ", (unsigned int)(unsigned char)(data[i]));
651         rl8168_frame_debug("\n");
652         rl8168_frame_debug("--> Sent packet.\n");
653         
654         outb(rl8168_io_base_addr + RL_TX_CTRL_REG, RL_TX_SEND_MASK);
655         
656         return len;
657 }
658