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