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