1/* 2 * Copyright (c) 2014, University of Washington. 3 * All rights reserved. 4 * 5 * This file is distributed under the terms in the attached LICENSE file. 6 * If you do not find this file, copies can be found by writing to: 7 * ETH Zurich D-INFK, CAB F.78, Universitaetstr. 6, CH-8092 Zurich. 8 * Attn: Systems Group. 9 */ 10 11#include <stdio.h> 12#include <assert.h> 13#include <barrelfish/barrelfish.h> 14#include <barrelfish/inthandler.h> 15#include <barrelfish/sys_debug.h> 16#include <skb/skb.h> 17#include <sys/socket.h> 18#include <netif/e1000.h> 19#include <limits.h> 20#include <barrelfish/waitset.h> 21#include <barrelfish/waitset_chan.h> 22#include <lwip/sock_chan_support.h> 23#include <netdb.h> 24#include <arranet.h> 25#include <arranet_impl.h> 26#include <acpi_client/acpi_client.h> 27#include <arranet_debug.h> 28 29static ether_terminate_queue ether_terminate_queue_ptr = NULL; 30static ether_get_mac_address_t ether_get_mac_address_ptr = NULL; 31static ether_transmit_pbuf_list_t ether_transmit_pbuf_list_ptr = NULL; 32static ether_get_tx_free_slots tx_free_slots_fn_ptr = NULL; 33static ether_handle_free_TX_slot handle_free_tx_slot_fn_ptr = NULL; 34static ether_rx_register_buffer rx_register_buffer_fn_ptr = NULL; 35static ether_rx_get_free_slots rx_get_free_slots_fn_ptr = NULL; 36 37uint64_t interrupt_counter = 0; 38uint64_t total_rx_p_count = 0; 39uint64_t total_rx_datasize = 0; 40struct client_closure *g_cl = NULL; 41 42#define MAX_PACKETS 2000 43#define PACKET_SIZE 2048 44#define MAX_PEERS 256 45 46static int use_vtd = 0; 47static int vtd_coherency = 1; 48 49struct peer { 50 uint32_t ip; 51 struct eth_addr mac; 52}; 53 54// Configure static ARP entries here 55// IP addresses are in network byte order! 56static struct peer peers[MAX_PEERS] = { 57 { 58 // XXX: This needs to be updated each time the tap interface is re-initialized 59 .ip = 0x0102000a, // 10.0.2.1 60 /* .mac.addr = "\x86\x86\x0b\xda\x22\xd7", */ 61 .mac.addr = "\x12\x67\xb9\x3e\xe2\x2c", 62 }, 63 { 64 // XXX: This needs to be updated each time the tap interface is re-initialized 65 .ip = 0x0164a8c0, // 192.168.100.1 66 .mac.addr = "\x5e\x93\xf2\xf1\xeb\xfa", 67 }, 68 { 69 .ip = 0xaf06d080, // 128.208.6.175 - swingout2 70 .mac.addr = "\x90\xe2\xba\x3a\x2e\xdd", 71 }, 72 { 73 .ip = 0xec06d080, // 128.208.6.236 - swingout3 74 .mac.addr = "\xa0\x36\x9f\x0f\xfb\xe2", 75 }, 76 { 77 .ip = 0x8106d080, // 128.208.6.129 - swingout4 78 .mac.addr = "\xa0\x36\x9f\x10\x01\x6e", 79 }, 80 { 81 .ip = 0x8206d080, // 128.208.6.130 - swingout5 82 .mac.addr = "\xa0\x36\x9f\x10\x00\xa2", 83 }, 84 { 85 .ip = 0xc506d080, // 128.208.6.197 - swingout6 86 .mac.addr = "\xa0\x36\x9f\x10\x03\x52", 87 }, 88}; 89static int peers_alloc = 7; // Set number of static ARP here! 90 91struct pkt_ip_headers { 92 struct eth_hdr eth; 93 struct ip_hdr ip; 94} __attribute__ ((packed)); 95 96struct pkt_udp_headers { 97 struct eth_hdr eth; 98 struct ip_hdr ip; 99 struct udp_hdr udp; 100} __attribute__ ((packed)); 101 102struct pkt_tcp_headers { 103 struct eth_hdr eth; 104 struct ip_hdr ip; 105 struct tcp_hdr tcp; 106} __attribute__ ((packed)); 107 108static struct packet rx_packets[MAX_PACKETS]; 109 110/******** IP config *********/ 111 112struct mac2ip { 113 uint8_t mac[ETHARP_HWADDR_LEN]; 114 uint32_t ip; 115}; 116 117static struct mac2ip ip_config[] = { 118 { // QEMU 119 .mac = "\x52\x54\x00\x12\x34\x56", 120 /* .ip = 0x0a00020f, // 10.0.2.15 */ 121 .ip = 0xc0a8640f, // 192.168.100.15 122 }, 123 { 124 // QEMU2 125 .mac = "\x52\x54\x00\x12\x34\x57", 126 .ip = 0xc0a80102, // 192.168.1.2 127 }, 128 { // swingout1 (and swingout1-vf0) 129 .mac = "\xa0\x36\x9f\x10\x00\xa6", 130 .ip = 0x80d00643, // 128.208.6.67 131 }, 132 { // swingout1-vf1 133 .mac = "\x22\xc9\xfc\x96\x83\xfc", 134 .ip = 0x80d00644, // 128.208.6.68 135 }, 136 { // swingout1-vf2 137 .mac = "\xce\x43\x5b\xf7\x3e\x60", 138 .ip = 0x80d00602, // 128.208.6.2 139 }, 140 { // swingout1-vf3 141 .mac = "\x6a\xb0\x62\xf6\xa7\x21", 142 .ip = 0x80d00603, // 128.208.6.3 143 }, 144 { // swingout1-vf4 145 .mac = "\xb2\xdf\xf9\x39\xc6\x10", 146 .ip = 0x80d00604, // 128.208.6.4 147 }, 148 { // swingout1-vf5 149 .mac = "\x92\x77\xe7\x3f\x80\x30", 150 .ip = 0x80d0060c, // 128.208.6.12 151 }, 152 { // swingout5 153 .mac = "\xa0\x36\x9f\x10\x00\xa2", 154 .ip = 0x80d00682, // 128.208.6.130 155 }, 156}; 157 158static uint8_t arranet_mymac[ETHARP_HWADDR_LEN]; 159static uint32_t arranet_myip = 0; 160 161void ethernetif_backend_init(char *service_name, uint64_t queueid, 162 ether_get_mac_address_t get_mac_ptr, 163 ether_terminate_queue terminate_queue_ptr, 164 ether_transmit_pbuf_list_t transmit_ptr, 165 ether_get_tx_free_slots tx_free_slots_ptr, 166 ether_handle_free_TX_slot handle_free_tx_slot_ptr, 167 size_t rx_bufsz, 168 ether_rx_register_buffer rx_register_buffer_ptr, 169 ether_rx_get_free_slots rx_get_free_slots_ptr) 170{ 171 ether_terminate_queue_ptr = terminate_queue_ptr; 172 ether_get_mac_address_ptr = get_mac_ptr; 173 ether_transmit_pbuf_list_ptr = transmit_ptr; 174 tx_free_slots_fn_ptr = tx_free_slots_ptr; 175 handle_free_tx_slot_fn_ptr = handle_free_tx_slot_ptr; 176 rx_register_buffer_fn_ptr = rx_register_buffer_ptr; 177 rx_get_free_slots_fn_ptr = rx_get_free_slots_ptr; 178 /* printf("PBUF_POOL_BUFSIZE = %u, rx buffer size = %zu\n", PBUF_POOL_BUFSIZE, */ 179 /* rx_bufsz); */ 180} 181 182#define MAX_DRIVER_BUFS 16 183 184static genpaddr_t rx_pbase = 0, tx_pbase = 0; 185static genvaddr_t rx_vbase = 0, tx_vbase = 0; 186 187static struct packet tx_packets[MAX_PACKETS]; 188/* static uint8_t tx_bufs[MAX_PACKETS][PACKET_SIZE]; */ 189static unsigned int tx_idx = 0; 190/* static ssize_t tx_packets_available = MAX_PACKETS; */ 191 192#include <barrelfish/deferred.h> 193 194static void packet_output(struct packet *p) 195{ 196 struct driver_buffer bufs[MAX_DRIVER_BUFS]; 197 int n = 0; 198 199 for (struct packet *q = p; q != NULL; q = q->next) { 200 struct driver_buffer *buf = &bufs[n]; 201 202 /* if(q->payload < &tx_bufs[0][0] || q->payload >= &tx_bufs[MAX_PACKETS][PACKET_SIZE]) { */ 203 /* printf("Called from %p %p\n", */ 204 /* __builtin_return_address(0), */ 205 /* __builtin_return_address(1)); */ 206 /* assert(q->payload >= &tx_bufs[0][0] && q->payload < &tx_bufs[MAX_PACKETS][PACKET_SIZE]); */ 207 /* } */ 208 209 /* Send the data from the pbuf to the interface, one pbuf at a 210 time. The size of the data in each pbuf is kept in the ->len 211 variable. */ 212 assert(q->len > 0); 213 214 // Check if it's from the RX region 215 /* printf("RX region: Comparing %p against [%p:%p]\n", */ 216 /* q->payload, */ 217 /* (void *)rx_vbase, */ 218 /* (void *)(rx_vbase + (MAX_PACKETS * PACKET_SIZE + 4096))); */ 219 if (!use_vtd) { 220 if(((genvaddr_t)q->payload) >= rx_vbase && 221 ((genvaddr_t)q->payload) < rx_vbase + (MAX_PACKETS * PACKET_SIZE + 4096)) { 222 buf->pa = rx_pbase + ((genvaddr_t)q->payload - rx_vbase); 223 } else if(((genvaddr_t)q->payload) >= tx_vbase && 224 ((genvaddr_t)q->payload) < tx_vbase + (MAX_PACKETS * PACKET_SIZE)) { 225 // It is from the TX region! 226 buf->pa = tx_pbase + ((genvaddr_t)q->payload - tx_vbase); 227 } else { 228 // Check if it's in morecore's region 229 struct morecore_state *mc_state = get_morecore_state(); 230 struct vspace_mmu_aware *mmu_state = &mc_state->mmu_state; 231 genvaddr_t base = vregion_get_base_addr(&mmu_state->vregion); 232 struct memobj_frame_list *i; 233 234 // Walk frame list 235 for(i = mmu_state->memobj.frame_list; i != NULL; i = i->next) { 236 // If address is completely within frame, we can resolve 237 // XXX: Everything else would be easier with an IOMMU 238 /* printf("Heap: Comparing [%p:%p] against [%p:%p]\n", */ 239 /* q->payload, q->payload + q->len, */ 240 /* (void *)(base + i->offset), */ 241 /* (void *)(base + i->offset + i->size)); */ 242 if(base + i->offset <= (genvaddr_t)q->payload && 243 ((genvaddr_t)q->payload) + q->len < base + i->offset + i->size) { 244 assert(i->pa != 0); 245 246 /* buf->pa = id.base + ((genvaddr_t)q->payload - base - i->offset); */ 247 buf->pa = i->pa + ((genvaddr_t)q->payload - base - i->offset); 248 break; 249 } 250 } 251 252 if(i == NULL) { 253 // Check if it's in text/data region 254 int entry; 255 for(entry = 0; entry < mc_state->v2p_entries; entry++) { 256 struct v2pmap *pmap = &mc_state->v2p_mappings[entry]; 257 258 // If address is completely within frame, we can resolve 259 // XXX: Everything else would be easier with an IOMMU 260 /* printf("BSS: Comparing [%p:%p] against [%p:%p]\n", */ 261 /* q->payload, q->payload + q->len, */ 262 /* (void *)(pmap->va), */ 263 /* (void *)(pmap->va + pmap->size)); */ 264 if(pmap->va <= (genvaddr_t)q->payload && 265 ((genvaddr_t)q->payload) + q->len < pmap->va + pmap->size) { 266 buf->pa = pmap->pa + ((genvaddr_t)q->payload - pmap->va); 267 break; 268 } 269 270 } 271 272 if(entry == mc_state->v2p_entries) { 273 printf("Called from %p %p %p\n", 274 __builtin_return_address(0), 275 __builtin_return_address(1), 276 __builtin_return_address(2)); 277 278 USER_PANIC("Invalid pbuf! payload = %p, pa = %p, subpacket = %d\n", 279 q->payload, buf->pa, n); 280 } 281 } 282 } 283 } 284 /* printf("Sending: '%s'\n", (char *)q->payload); */ 285 286 buf->va = q->payload; 287 buf->len = q->len; 288#ifndef SENDMSG_WITH_COPY 289 buf->opaque = q->opaque; 290#else 291 buf->opaque = q; 292#endif 293 buf->flags = q->flags; 294 295 n++; 296 } 297 298 errval_t err = ether_transmit_pbuf_list_ptr(bufs, n); 299 assert(err_is_ok(err)); 300} 301 302static struct pkt_ip_headers packet_ip_header; 303static struct pkt_udp_headers packet_udp_header; 304static struct pkt_tcp_headers packet_tcp_header; 305 306static struct peer *peers_get_from_ip(uint32_t ip) 307{ 308 for(int i = 0; i < MAX_PEERS; i++) { 309 if(ip == peers[i].ip) { 310 return &peers[i]; 311 } 312 } 313 314 /* printf("NOT FOUND: %x\n", ip); */ 315 316 return NULL; 317} 318 319static struct peer *peers_get_next_free(void) 320{ 321 if(peers_alloc < MAX_PEERS) { 322 return &peers[peers_alloc++]; 323 } else { 324 return NULL; 325 } 326} 327 328static struct packet *get_tx_packet(void) 329{ 330 struct packet *p = &tx_packets[tx_idx]; 331 332 // Busy-wait until packet not in flight 333 while(p->len != 0) { 334 /* printf("Pipeline stalled! tx_packets_available = %zd\n", tx_packets_available); */ 335 handle_free_tx_slot_fn_ptr(); 336 /* if(!handle_free_tx_slot_fn_ptr()) { */ 337 /* printf("No packets could be freed!\n"); */ 338 /* } */ 339 } 340 341 /* tx_packets_available--; */ 342 343 tx_idx = (tx_idx + 1) % MAX_PACKETS; 344 return p; 345} 346 347void process_received_packet(struct driver_rx_buffer *buffer, size_t count, 348 uint64_t flags) 349{ 350 351 struct packet *p = buffer->opaque; 352 assert(p != NULL); 353 assert(count == 1); 354 p->len = buffer->len; 355 356 /* printf("Incoming packet\n"); */ 357 /* printf("Got %p from driver\n", p); */ 358 359 assert(p >= rx_packets && p < &rx_packets[MAX_PACKETS]); 360 361 // Drop packets with invalid checksums 362 if(flags & NETIF_RXFLAG_IPCHECKSUM) { 363 if(!(flags & NETIF_RXFLAG_IPCHECKSUM_GOOD)) { 364 goto out; 365 } 366 } 367 368 if(flags & NETIF_RXFLAG_L4CHECKSUM) { 369 if(!(flags & NETIF_RXFLAG_L4CHECKSUM_GOOD)) { 370 goto out; 371 } 372 } 373 374 struct eth_hdr *ethhdr = (struct eth_hdr *)p->payload; 375 switch (htons(ethhdr->type)) { 376 case ETHTYPE_ARP: 377 { 378 struct etharp_hdr *arphdr = (struct etharp_hdr *)(p->payload + SIZEOF_ETH_HDR); 379 uint32_t dipaddr = (arphdr->dipaddr.addrw[1] << 16) | arphdr->dipaddr.addrw[0]; 380 381 /* printf("%d: ARP request, dip = %x\n", disp_get_core_id(), dipaddr); */ 382 383 if(htons(arphdr->opcode) == ARP_REQUEST && 384 dipaddr == arranet_myip) { 385 // Send reply 386 struct packet outp; 387 // XXX: Static payload! Need to lock if multithreaded! 388 static uint8_t payload[PACKET_SIZE]; 389 struct eth_hdr *myeth = (struct eth_hdr *)payload; 390 struct etharp_hdr *myarp = (struct etharp_hdr *)(payload + SIZEOF_ETH_HDR); 391 392 /* printf("%d: ARP request for us!\n", disp_get_core_id()); */ 393 394 // ETH header 395 memcpy(&myeth->dest, &arphdr->shwaddr, ETHARP_HWADDR_LEN); 396 memcpy(&myeth->src, arranet_mymac, ETHARP_HWADDR_LEN); 397 myeth->type = htons(ETHTYPE_ARP); 398 399 // ARP header 400 myarp->hwtype = htons(1); 401 myarp->proto = htons(ETHTYPE_IP); 402 myarp->hwlen = 6; 403 myarp->protolen = 4; 404 myarp->opcode = htons(ARP_REPLY); 405 memcpy(&myarp->shwaddr, arranet_mymac, ETHARP_HWADDR_LEN); 406 memcpy(&myarp->sipaddr, &arphdr->dipaddr, sizeof(myarp->sipaddr)); 407 memcpy(&myarp->dhwaddr, &arphdr->shwaddr, ETHARP_HWADDR_LEN); 408 memcpy(&myarp->dipaddr, &arphdr->sipaddr, sizeof(myarp->dipaddr)); 409 410 outp.payload = payload; 411 outp.len = SIZEOF_ETHARP_PACKET; 412 /* outp.len = p->len; */ 413 outp.next = NULL; 414 outp.flags = 0; 415 outp.opaque = NULL; 416 417 packet_output(&outp); 418 static int arp_count = 0; 419 arp_count++; 420 if(arp_count > 100) { 421 printf("High ARP count!\n"); 422 } 423 while(!e1000n_queue_empty()) thread_yield(); 424 } 425 } 426 break; 427 428 case ETHTYPE_IP: 429 { 430 struct ip_hdr *iphdr = (struct ip_hdr *)(p->payload + SIZEOF_ETH_HDR); 431 432 printf("%d: Is an IP packet, type %x\n", disp_get_core_id(), IPH_PROTO(iphdr)); 433 434 // Has to be UDP or TCP 435 if(IPH_PROTO(iphdr) != IP_PROTO_UDP && IPH_PROTO(iphdr) != IP_PROTO_TCP) { 436 goto out; 437 } 438 439 // XXX: Filter for our IP 440 if(iphdr->dest.addr != arranet_myip) { 441 goto out; 442 } 443 444 if(IPH_PROTO(iphdr) == IP_PROTO_UDP) { 445 struct udp_hdr *udphdr = (struct udp_hdr *)(p->payload + SIZEOF_ETH_HDR + (IPH_HL(iphdr) * 4)); 446 uint8_t *payload = p->payload + SIZEOF_ETH_HDR + (IPH_HL(iphdr) * 4) + sizeof(struct udp_hdr); 447 448 printf("Got UDP packet, dest IP %x, dest port %u\n", 449 htonl(iphdr->dest.addr), htons(udphdr->dest)); 450 451 // XXX: Filter for UDP ports 1234 452 // TODO: Done in hardware soon 453 if(htons(udphdr->dest) != 1234) { 454 goto out; 455 } 456 457 printf("payload '%s'\n", payload); 458 459 struct packet *outp = get_tx_packet(); 460 struct eth_hdr *myeth = (struct eth_hdr *)outp->payload; 461 struct ip_hdr *myip = (struct ip_hdr *)(outp->payload + SIZEOF_ETH_HDR); 462 struct udp_hdr *myudp = (struct udp_hdr *)(outp->payload + SIZEOF_ETH_HDR + (IPH_HL(iphdr) * 4)); 463 uint8_t *mypayload = outp->payload + SIZEOF_ETH_HDR + (IPH_HL(iphdr) * 4) + sizeof(struct udp_hdr); 464 465 // ETH header 466 memcpy(&myeth->dest, ðhdr->src, ETHARP_HWADDR_LEN); 467 memcpy(&myeth->src, ðhdr->dest, ETHARP_HWADDR_LEN); 468 myeth->type = htons(ETHTYPE_IP); 469 470 // IP header 471 memcpy(myip, iphdr, sizeof(struct ip_hdr)); 472 memcpy(&myip->src, &iphdr->dest, sizeof(ip_addr_p_t)); 473 memcpy(&myip->dest, &iphdr->src, sizeof(ip_addr_p_t)); 474 475 // UDP header 476 memcpy(myudp, udphdr, sizeof(struct udp_hdr)); 477 myudp->src = udphdr->dest; 478 myudp->dest = udphdr->src; 479 480 // Payload 481 memcpy(mypayload, payload, htons(udphdr->len) - 8); 482 483 outp->len = p->len; 484 outp->next = NULL; 485 outp->flags = 0; 486 packet_output(outp); 487 } 488 489 // ARP management 490 if(peers_get_from_ip(iphdr->src.addr) == NULL) { 491 struct peer *newpeer = peers_get_next_free(); 492 assert(p != NULL); 493 newpeer->ip = iphdr->src.addr; 494 memcpy(&newpeer->mac.addr, ðhdr->src.addr, ETHARP_HWADDR_LEN); 495 } 496#if 0 497 // Push packets up - signal channel 498 assert(inpkt == NULL); 499 inpkt = p; 500 if (waitset_chan_is_registered(&recv_chanstate)) { 501 errval_t err = waitset_chan_trigger(&recv_chanstate); 502 assert(err_is_ok(err)); 503 } 504 505 // Return here, packet is in flight to user-space 506 return; 507#endif 508 } 509 break; 510 511 default: 512 break; 513 } 514 515 out: 516 { 517 //now we have consumed the preregistered pbuf containing a received packet 518 //which was processed in this function. Therefore we have to register a new 519 //free buffer for receiving packets. 520 errval_t err = rx_register_buffer_fn_ptr(p->pa, p->payload, p); 521 assert(err_is_ok(err)); 522 } 523} 524 525bool handle_tx_done(void *opaque) 526{ 527 struct packet *p = opaque; 528 if(p >= tx_packets && p < &tx_packets[MAX_PACKETS]) { 529 /* printf("Packet from TX ring, marking available\n"); */ 530 // Mark packet as available, if coming from TX packet array 531 p->len = 0; 532 /* tx_packets_available++; */ 533#ifndef SENDMSG_WITH_COPY 534 } else { 535 if(opaque != NULL && arranet_tx_done_callback != NULL) { 536 /* printf("Packet from app, handing up\n"); */ 537 arranet_tx_done_callback(opaque); 538 /* } else { */ 539 /* if(opaque == NULL) { */ 540 /* printf("NULL packet\n"); */ 541 /* } */ 542 } 543#endif 544 } 545 546 return true; 547} 548 549/* allocate a single frame, mapping it into our vspace with given attributes */ 550static void *alloc_map_frame(vregion_flags_t attr, size_t size, struct capref *retcap) 551{ 552 struct capref frame; 553 errval_t r; 554 555 r = frame_alloc(&frame, size, NULL); 556 assert(err_is_ok(r)); 557 void *va; 558 r = vspace_map_one_frame_attr(&va, size, frame, attr, 559 NULL, NULL); 560 if (err_is_fail(r)) { 561 DEBUG_ERR(r, "vspace_map_one_frame failed"); 562 return NULL; 563 } 564 565 if (retcap != NULL) { 566 *retcap = frame; 567 } 568 569 return va; 570} 571 572static const char *eat_opts[] = { 573 "function=", "interrupts=", "queue=", "msix=", "vf=", "device=", "bus=", "use_vtd=", 574 NULL 575}; 576 577int main(int argc, char *argv[]) 578{ 579 uint8_t mac[6]; 580 581 errval_t err = skb_client_connect(); 582 assert(err_is_ok(err)); 583 584 err = skb_execute_query("vtd_enabled(0,C), write(vtd_coherency(C))."); 585 if (err_is_ok(err)) { 586 use_vtd = 1; 587 for(int i = 0; i < argc; i++) { 588 if(!strncmp(argv[i], "use_vtd=", strlen("use_vtd=") - 1)) { 589 use_vtd = !!atol(argv[i] + strlen("use_vtd=")); 590 break; 591 } 592 } 593 err = skb_read_output("vtd_coherency(%d)", &vtd_coherency); 594 assert(err_is_ok(err)); 595 } 596 597 if (use_vtd) { 598 err = connect_to_acpi(); 599 assert(err_is_ok(err)); 600 err = vtd_create_domain(cap_vroot); 601 assert(err_is_ok(err)); 602 err = vtd_domain_add_device(0, 13, 16, 1, cap_vroot); 603 assert(err_is_ok(err)); 604 } 605 606 e1000n_driver_init(argc, argv); 607 608 ether_get_mac_address_ptr(mac); 609 printf("Arranet MAC address %02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx\n", 610 mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); 611 612 struct capref frame; 613 uint8_t *ram_base = alloc_map_frame(VREGION_FLAGS_READ_WRITE, 614 MAX_PACKETS * PACKET_SIZE + 4096, &frame); 615 assert(ram_base != NULL); 616 617 struct frame_identity id; 618 err = invoke_frame_identify(frame, &id); 619 assert(err_is_ok(err)); 620 621 rx_pbase = id.base; 622 rx_vbase = (genvaddr_t)ram_base; 623 624 // Add buffers to RX ring for packet reception 625 for(int i = 0; i < MAX_PACKETS; i++) { 626 struct packet *p = &rx_packets[i]; 627 628 // XXX: Use this for recvfrom_arranet to get alignment 629 /* p->payload = ram_base + (i * PACKET_SIZE) + 6; */ 630 /* p->pa = id.base + (i * PACKET_SIZE) + 6; */ 631 p->payload = ram_base + (i * PACKET_SIZE); 632 p->pa = id.base + (i * PACKET_SIZE); 633 p->len = PACKET_SIZE; 634 p->flags = 0; 635 636 err = rx_register_buffer_fn_ptr(p->pa, p->payload, p); 637 assert(err_is_ok(err)); 638 } 639 640 // Allocate TX buffers (to have them all backed by one frame) 641 uint8_t *tx_bufs = alloc_map_frame(VREGION_FLAGS_READ_WRITE, 642 MAX_PACKETS * PACKET_SIZE, &frame); 643 assert(tx_bufs != NULL); 644 645 err = invoke_frame_identify(frame, &id); 646 assert(err_is_ok(err)); 647 tx_pbase = id.base; 648 tx_vbase = (genvaddr_t)tx_bufs; 649 650 // Initialize TX packet descriptors 651 for(int i = 0; i < MAX_PACKETS; i++) { 652 /* tx_packets[i].payload = tx_bufs[i]; */ 653 tx_packets[i].payload = tx_bufs + (i * PACKET_SIZE); 654 } 655 656 if (!vtd_coherency) {// For the UDP echo server 657 sys_debug_flush_cache(); 658 } 659 660 // Determine my static IP address 661 for(int i = 0; i < sizeof(ip_config) / sizeof(struct mac2ip); i++) { 662 struct mac2ip *e = &ip_config[i]; 663 if(!memcmp(mac, e->mac, ETHARP_HWADDR_LEN)) { 664 arranet_myip = htonl(e->ip); 665 memcpy(arranet_mymac, e->mac, ETHARP_HWADDR_LEN); 666 break; 667 } 668 } 669 670 if(arranet_myip == 0) { 671 USER_PANIC("Arranet: No static IP config for this MAC address!\n"); 672 } 673 674 /***** Initialize IP/Ethernet packet header template *****/ 675 { 676 struct pkt_ip_headers *p = &packet_ip_header; 677 678 // Initialize Ethernet header 679 memcpy(&p->eth.src, mac, ETHARP_HWADDR_LEN); 680 p->eth.type = htons(ETHTYPE_IP); 681 682 // Initialize IP header 683 p->ip._v_hl = 69; 684 p->ip._tos = 0; 685 p->ip._id = htons(3); 686 p->ip._offset = 0; 687 p->ip._ttl = 0xff; 688 p->ip._proto = 0; 689 p->ip._chksum = 0; 690 p->ip.src.addr = arranet_myip; 691 } 692 693 /***** Initialize UDP/IP/Ethernet packet header template *****/ 694 { 695 struct pkt_udp_headers *p = &packet_udp_header; 696 697 // Initialize Ethernet header 698 memcpy(&p->eth.src, mac, ETHARP_HWADDR_LEN); 699 p->eth.type = htons(ETHTYPE_IP); 700 701 // Initialize IP header 702 p->ip._v_hl = 69; 703 p->ip._tos = 0; 704 p->ip._id = htons(3); 705 p->ip._offset = 0; 706 p->ip._ttl = 0xff; 707 p->ip._proto = IP_PROTO_UDP; 708 p->ip._chksum = 0; 709 p->ip.src.addr = arranet_myip; 710 711 // Initialize UDP header 712 p->udp.chksum = 0; 713 } 714 715 /***** Initialize TCP/IP/Ethernet packet header template *****/ 716 { 717 struct pkt_tcp_headers *p = &packet_tcp_header; 718 719 // Initialize Ethernet header 720 memcpy(&p->eth.src, mac, ETHARP_HWADDR_LEN); 721 p->eth.type = htons(ETHTYPE_IP); 722 723 // Initialize IP header 724 p->ip._v_hl = 69; 725 p->ip._tos = 0; 726 p->ip._id = htons(3); 727 p->ip._offset = 0; 728 p->ip._ttl = 0xff; 729 p->ip._proto = IP_PROTO_TCP; 730 p->ip._chksum = 0; 731 p->ip.src.addr = arranet_myip; 732 733 // Initialize TCP header 734 p->tcp.chksum = 0; 735 p->tcp.wnd = 65535; 736 } 737 738 /***** Eat driver-specific options *****/ 739 static char *new_argv[ARG_MAX]; 740 int new_argc = 0; 741 for(int i = 0; i < argc; i++) { 742 int j; 743 744 for(j = 0; eat_opts[j] != NULL; j++) { 745 if(!strncmp(argv[i], eat_opts[j], strlen(eat_opts[j]) - 1)) { 746 // Option matches -- delete! 747 break; 748 } 749 } 750 751 if(eat_opts[j] == NULL) { 752 // Option doesn't match -- keep! 753 new_argv[new_argc++] = argv[i]; 754 } 755 } 756 757 argc = new_argc; 758 argv = new_argv; 759 760 printf("e10ktest initialized.\n"); 761 762 for(;;) { 763 arranet_polling_loop(); 764 // e1000n_polling_loop(get_default_waitset()); 765 } 766} 767