// Callback from device manager static void idc_queue_terminated(struct e10k_binding *b) { errval_t err; INITDEBUG("idc_queue_terminated()\n"); // Free memory for hardware ring buffers err = vspace_unmap(q->tx_ring); assert(err_is_ok(err)); err = vspace_unmap(q->rx_ring); assert(err_is_ok(err)); err = cap_delete(tx_frame); assert(err_is_ok(err)); err = cap_delete(rx_frame); assert(err_is_ok(err)); if (!capref_is_null(txhwb_frame)) { err = vspace_unmap(q->tx_hwb); assert(err_is_ok(err)); err = cap_delete(txhwb_frame); assert(err_is_ok(err)); } exit(0); }
// Callback from device manager void qd_write_queue_tails(struct e10k_binding *b) { INITDEBUG("idc_write_queue_tails()\n"); e10k_queue_bump_rxtail(q); e10k_queue_bump_txtail(q); }
/** Connect to the management interface */ static void connect_to_mngif(void) { errval_t r; iref_t iref; const char *suffix = "_e10kmng"; char name[strlen(service_name) + strlen(suffix) + 1]; // Build label for interal management service sprintf(name, "%s%s", service_name, suffix); // Connect to service INITDEBUG("Looking up management interface (%s)\n", name); r = nameservice_blocking_lookup(name, &iref); assert(err_is_ok(r)); INITDEBUG("Binding to management interface\n"); r = e10k_bind(iref, bind_cb, NULL, get_default_waitset(), IDC_BIND_FLAGS_DEFAULT); assert(err_is_ok(r)); }
static void bind_cb(void *st, errval_t err, struct e10k_binding *b) { assert(err_is_ok(err)); INITDEBUG("Sucessfully connected to management interface\n"); b->rx_vtbl = rx_vtbl; binding = b; idc_request_device_info(); }
static void eventloop_ints(void) { struct waitset *ws; INITDEBUG("eventloop_ints()\n"); ws = get_default_waitset(); while (1) { event_dispatch(ws); do_pending_work_for_all(); } }
/** Tell card driver to stop this queue. */ static void idc_terminate_queue(void) { errval_t r; INITDEBUG("idc_terminate_queue()\n"); if (!standalone) { USER_PANIC("Terminating monolithic driver is not a good idea"); } r = e10k_terminate_queue__tx(binding, NOP_CONT, qi); // TODO: handle busy assert(err_is_ok(r)); }
// Callback from device manager void qd_queue_init_data(struct e10k_binding *b, struct capref registers, uint64_t macaddr) { struct frame_identity frameid = { .base = 0, .bits = 0 }; errval_t err; void *virt; INITDEBUG("idc_queue_init_data\n"); mac_address = macaddr; // Map device registers invoke_frame_identify(registers, &frameid); err = vspace_map_one_frame_attr(&virt, 1 << frameid.bits, registers, VREGION_FLAGS_READ_WRITE_NOCACHE, NULL, NULL); assert(err_is_ok(err)); // Initialize mackerel device d = malloc(sizeof(*d)); #ifndef VF e10k_initialize(d, virt); #else e10k_vf_initialize(d, virt); #endif // Initialize queue setup_queue(); } // Callback from device manager void qd_queue_memory_registered(struct e10k_binding *b) { initialized = 1; hwqueue_initialized(); // Register queue with queue_mgr library #ifndef LIBRARY ethersrv_init((char*) service_name, qi, get_mac_addr_fn, terminate_queue_fn, transmit_pbuf_list_fn, find_tx_free_slot_count_fn, handle_free_tx_slot_fn, RXBUFSZ, register_rx_buffer_fn, find_rx_free_slot_count_fn); #else ethernetif_backend_init((char*) service_name, qi, get_mac_addr_fn, terminate_queue_fn, transmit_pbuf_list_fn, find_tx_free_slot_count_fn, handle_free_tx_slot_fn, RXBUFSZ, register_rx_buffer_fn, find_rx_free_slot_count_fn); #endif }
/** Request device register cap from card driver */ static void idc_request_device_info(void) { errval_t r; INITDEBUG("idc_request_device_info()\n"); if (!standalone) { cd_request_device_info(NULL); return; } r = e10k_request_device_info__tx(binding, NOP_CONT); // TODO: handle busy assert(err_is_ok(r)); }
/** Modify interrupt rate for queue */ static void idc_set_interrupt_rate(uint8_t queue, uint16_t rate) { errval_t r; INITDEBUG("idc_set_interrupt_rate()\n"); if (!standalone) { cd_set_interrupt_rate(NULL, queue, rate); return; } r = e10k_set_interrupt_rate__tx(binding, NOP_CONT, queue, rate); // TODO: handle busy assert(err_is_ok(r)); }
/** Send memory caps to card driver */ static void idc_register_queue_memory(uint8_t queue, struct capref tx, struct capref txhwb, struct capref rx, uint32_t rxbufsz, int16_t msix_intvec, uint8_t msix_intdest) { errval_t r; INITDEBUG("idc_register_queue_memory()\n"); if (!standalone) { cd_register_queue_memory(NULL, queue, tx, txhwb, rx, rxbufsz, msix_intvec, msix_intdest, use_interrupts, use_rsc); return; } r = e10k_register_queue_memory__tx(binding, NOP_CONT, queue, tx, txhwb, rx, rxbufsz, 0, msix_intvec, msix_intdest, use_interrupts, use_rsc); // TODO: handle busy assert(err_is_ok(r)); }
/** Allocate queue n and return handle for queue manager */ static void setup_queue(void) { struct e10k_queue_ops ops = { .update_txtail = update_txtail, .update_rxtail = update_rxtail }; size_t tx_size, txhwb_size, rx_size; void *tx_virt, *txhwb_virt, *rx_virt; vregion_flags_t flags; uint8_t vector, core; errval_t err; INITDEBUG("setup_queue\n"); // Decide on which flags to use for the mappings flags = (cache_coherence ? VREGION_FLAGS_READ_WRITE : VREGION_FLAGS_READ_WRITE_NOCACHE); // Allocate memory for descriptor rings tx_size = e10k_q_tdesc_legacy_size * NTXDESCS; tx_virt = alloc_map_frame(flags, tx_size, &tx_frame); assert(tx_virt != NULL); rx_size = e10k_q_rdesc_legacy_size * NRXDESCS; rx_virt = alloc_map_frame(flags, rx_size, &rx_frame); assert(rx_virt != NULL); #ifdef PRINT_QUEUES glbl_rx_virt = rx_virt; glbl_rx_size = rx_size; #endif // Register memory with device manager txhwb_virt = NULL; if (use_txhwb) { INITDEBUG("Using transmit write-back\n"); txhwb_size = BASE_PAGE_SIZE; txhwb_virt = alloc_map_frame(flags, txhwb_size, &txhwb_frame); assert(txhwb_virt != NULL); memset(txhwb_virt, 0, sizeof(uint32_t)); assert(txhwb_virt != NULL); } // Initialize queue manager q = e10k_queue_init(tx_virt, NTXDESCS, txhwb_virt, rx_virt, NRXDESCS, &ops, NULL); if (use_interrupts && use_msix) { INITDEBUG("Enabling MSI-X interrupts\n"); err = pci_setup_inthandler(interrupt_handler, NULL, &vector); assert(err_is_ok(err)); core = disp_get_core_id(); } else { if (use_interrupts) { INITDEBUG("Enabling legacy interrupts\n"); } vector = 0; core = 0; } idc_register_queue_memory(qi, tx_frame, txhwb_frame, rx_frame, RXBUFSZ, vector, core); }
int main(int argc, char *argv[]) { int setflags, clrflags, ver, nochk; int db_ver, db_format, db_flags, do_check, do_write; char *fp; FILE *f_ptr; char s_filename[120]; f_ptr = NULL; nochk = 0; if (argc == 3) { for (fp = argv[2]; *fp; fp++) { if (*fp == 'x') { nochk = 1; break; } } } if (!nochk) { sprintf(s_filename, "%.115s.db", argv[1]); if ( (f_ptr = fopen(s_filename, "r")) != NULL ) { fprintf(stderr, "GDBM file(s) already exist for %s\n", s_filename); fclose(f_ptr); exit(1); } sprintf(s_filename, "%.115s.dir", argv[1]); if ( (f_ptr = fopen(s_filename, "r")) != NULL ) { fprintf(stderr, "GDBM file(s) already exist for %s\n", s_filename); fclose(f_ptr); exit(1); } sprintf(s_filename, "%.115s.pag", argv[1]); if ( (f_ptr = fopen(s_filename, "r")) != NULL ) { fprintf(stderr, "GDBM file(s) already exist for %s\n", s_filename); fclose(f_ptr); exit(1); } } debugmem = (Debugmem *)malloc(sizeof(Debugmem)); if( !debugmem ) abort(); INITDEBUG(debugmem); if ((argc < 2) || (argc > 3)) { usage(argv[0]); exit(1); } dddb_var_init(); cache_var_init(); cf_init(); /* Decide what conversions to do and how to format the output file */ setflags = clrflags = ver = do_check = 0; do_write = 1; if (argc == 3) { for (fp = argv[2]; *fp; fp++) { switch (*fp) { case 'C': do_check = 1; break; case 'G': setflags |= V_GDBM; break; case 'g': clrflags |= V_GDBM; break; case 'Z': setflags |= V_ZONE; break; case 'z': clrflags |= V_ZONE; break; case 'L': setflags |= V_LINK; break; case 'l': clrflags |= V_LINK; break; case 'N': setflags |= V_ATRNAME; break; case 'n': clrflags |= V_ATRNAME; break; case 'K': setflags |= V_ATRKEY; break; case 'k': clrflags |= V_ATRKEY; break; case 'P': setflags |= V_PARENT; break; case 'p': clrflags |= V_PARENT; break; case 'W': do_write = 1; break; case 'w': do_write = 0; break; case 'X': clrflags = 0xffffffff; setflags = OUTPUT_FLAGS; ver = OUTPUT_VERSION; break; case 'x': clrflags = 0xffffffff; setflags = UNLOAD_OUTFLAGS; ver = UNLOAD_VERSION; break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': ver = ver * 10 + (*fp - '0'); break; default: fprintf(stderr, "Unknown flag: '%c'\n", *fp); usage(argv[0]); exit(1); } } } /* Open the gdbm file */ if (init_gdbm_db(argv[1]) < 0) { fprintf(stderr, "Can't open GDBM file\n"); exit(1); } /* Go do it */ db_read(stdin, &db_format, &db_ver, &db_flags); fprintf(stderr, "Input: "); info(db_format, db_flags, db_ver); val_count(); if (do_check) do_dbck(NOTHING, NOTHING, DBCK_FULL); if (do_write) { db_flags = (db_flags & ~clrflags) | setflags; if (db_format != F_MUSH) db_ver = 3; if (ver != 0) db_ver = ver; fprintf(stderr, "Output: "); info(F_MUSH, db_flags, db_ver); db_write(stdout, F_MUSH, db_ver | db_flags); } CLOSE; return(0); }