static struct page *alloc_new_pde(void) { struct page *page; size_t size = PDE_TABLE_SIZE; u32 align = PDE_TABLE_ALIGN_SIZE; spin_lock_irqsave(&pgt_buffer.pgt_lock); if (pgt_buffer.nr_free == 0) { /* * alloc new pgt from system */ page = get_free_pages_align(page_nr(size), align, GFP_PGT); if (!page) { spin_unlock_irqstore(&pgt_buffer.pgt_lock); return NULL; } pgt_buffer.alloc_nr++; } else { page = list_to_page(list_next(&pgt_buffer.list)); list_del(list_next(&pgt_buffer.list)); pgt_buffer.nr_free--; } spin_unlock_irqstore(&pgt_buffer.pgt_lock); return page; }
void net_set_state(net_interface_t *interface, net_state_t state) { if(interface->state == state) return; //FIXME locking interface->state = state; //TODO better handle active devices, etc switch(state) { case IF_DOWN: { logf("net - interface is DOWN"); break; } case IF_UP: { logf("net - interface is UP"); break; } case IF_READY: { logf("net - interface is READY"); break; } case IF_ERROR: { logf("net - interface error"); break; } default: break; } uint32_t flags; spin_lock_irqsave(&listener_lock, &flags); listener_chain_fire(state, interface, &listeners); spin_unlock_irqstore(&listener_lock, flags); }
void net_put_hostname() { uint32_t flags; spin_lock_irqsave(&interface_lock, &flags); hostname_handles--; spin_unlock_irqstore(&interface_lock, flags); }
void unregister_net_state_listener(listener_t *listener) { uint32_t flags; spin_lock_irqsave(&listener_lock, &flags); listener_chain_rm(listener); spin_unlock_irqstore(&listener_lock, flags); }
void unregister_net_interface(net_interface_t *interface) { uint32_t flags; spin_lock_irqsave(&interface_lock, &flags); list_rm(&interface->list); spin_unlock_irqstore(&interface_lock, flags); }
const char * net_get_hostname() { uint32_t flags; spin_lock_irqsave(&interface_lock, &flags); hostname_handles++; char *local_name = ACCESS_ONCE(hostname); spin_unlock_irqstore(&interface_lock, flags); return local_name; }
static int release_pde(unsigned long base) { struct page *page = va_to_page(base); spin_lock_irqsave(&pgt_buffer.pgt_lock); add_page_to_list_tail(page, &pgt_buffer.list); pgt_buffer.nr_free++; spin_unlock_irqstore(&pgt_buffer.pgt_lock); return 0; }
void register_net_interface(net_interface_t *interface) { interface->rx_total = 0; interface->tx_total = 0; interface->ip_data = 0; uint32_t flags; spin_lock_irqsave(&interface_lock, &flags); list_add(&interface->list, &interfaces); spin_unlock_irqstore(&interface_lock, flags); net_set_state(interface, IF_DOWN); }