/************************************************************************ * DESCRIPTION: RAW send function. *************************************************************************/ static fnet_int32_t fnet_raw_snd( fnet_socket_if_t *sk, fnet_uint8_t *buf, fnet_size_t len, fnet_flag_t flags, const struct sockaddr *addr) { fnet_netbuf_t *nb; fnet_error_t error = FNET_ERR_OK; const struct sockaddr *foreign_addr; fnet_bool_t flags_save = FNET_FALSE; fnet_isr_lock(); if(len > sk->send_buffer.count_max) { error = FNET_ERR_MSGSIZE; /* Message too long. */ goto ERROR; } if(addr) { foreign_addr = addr; } else { foreign_addr = &sk->foreign_addr; } if((nb = fnet_netbuf_from_buf(buf, len, FNET_FALSE)) == 0) { error = FNET_ERR_NOMEM; /* Cannot allocate memory.*/ goto ERROR; } if((flags & MSG_DONTROUTE) != 0u) /* Save */ { flags_save = sk->options.so_dontroute; sk->options.so_dontroute = FNET_TRUE; } error = fnet_raw_output(&sk->local_addr, foreign_addr, (fnet_uint8_t)sk->protocol_number, &(sk->options), nb); if((flags & MSG_DONTROUTE) != 0u) /* Restore.*/ { sk->options.so_dontroute = flags_save; } if((error == FNET_ERR_OK) && (sk->options.local_error == FNET_ERR_OK)) /* We get RAW or ICMP error.*/ { fnet_isr_unlock(); return (fnet_int32_t)(len); } ERROR: fnet_socket_set_error(sk, error); fnet_isr_unlock(); return (FNET_ERR); }
/************************************************************************ * NAME: fnet_free_mem_status * * DESCRIPTION: Returns a quantity of free memory (for debug needs) * *************************************************************************/ unsigned long fnet_mempool_free_mem_status( fnet_mempool_desc_t mpool) { struct fnet_mempool * mempool = (struct fnet_mempool *)mpool; unsigned long total_size = 0; fnet_mempool_unit_header_t *t_mem; fnet_isr_lock(); t_mem = mempool->free_ptr; if(t_mem == 0) return 0; total_size += t_mem->size; /* FNET_DEBUG("%d,",t_mem->size*sizeof(FNET_ALLOC_HDR_T));*/ while(t_mem->ptr != mempool->free_ptr) { t_mem = t_mem->ptr; total_size += t_mem->size; /* FNET_DEBUG("%d,",t_mem->size*sizeof(FNET_ALLOC_HDR_T));*/ } /*FNET_DEBUG("");*/ fnet_isr_unlock(); return (total_size * mempool->unit_size); }
/************************************************************************ * NAME: fnet_malloc_max * * DESCRIPTION: Returns a maximum size of posible allocated memory chunk. * *************************************************************************/ unsigned long fnet_mempool_malloc_max( fnet_mempool_desc_t mpool ) { struct fnet_mempool * mempool = (struct fnet_mempool *)mpool; unsigned long max = 0; fnet_mempool_unit_header_t *t_mem; fnet_isr_lock(); t_mem = mempool->free_ptr; if(t_mem == 0) return 0; max = t_mem->size; /*FNET_DEBUG("%d,", t_mem->size * sizeof(FNET_ALLOC_HDR_T));*/ while(t_mem->ptr && (t_mem->ptr != mempool->free_ptr)) { t_mem = t_mem->ptr; if(t_mem->size > max) max = t_mem->size; /*FNET_DEBUG("%d,", t_mem->size * sizeof(FNET_ALLOC_HDR_T));*/ } /*FNET_DEBUG("");*/ fnet_isr_unlock(); return (max * mempool->unit_size); }
/************************************************************************ * NAME: fnet_udp_detach * * DESCRIPTION: UDP close function. *************************************************************************/ static fnet_return_t fnet_udp_detach( fnet_socket_if_t *sk ) { fnet_isr_lock(); fnet_socket_release(&fnet_udp_prot_if.head, sk); fnet_isr_unlock(); return (FNET_OK); }
/************************************************************************ * NAME: fnet_raw_detach * * DESCRIPTION: RAW close function. *************************************************************************/ static int fnet_raw_detach( fnet_socket_t *sk ) { fnet_isr_lock(); fnet_socket_release(&fnet_raw_prot_if.head, sk); fnet_isr_unlock(); return (FNET_OK); }
/************************************************************************ * NAME: fnet_event_raise * * DESCRIPTION: This function raise registerted event. *************************************************************************/ void fnet_event_raise( fnet_event_desc_t event_number ) { unsigned int vector_number = (unsigned int)(event_number); fnet_isr_entry_t *isr_temp; isr_temp = fnet_isr_table; fnet_isr_lock(); while(isr_temp != 0) { if(isr_temp->vector_number == vector_number) { if(isr_temp->handler_top) isr_temp->handler_top(isr_temp->cookie); if(fnet_locked == 1) { isr_temp->pended = 0; if(isr_temp->handler_bottom) isr_temp->handler_bottom(isr_temp->cookie); } else isr_temp->pended = 1; break; } isr_temp = isr_temp->next; } fnet_isr_unlock(); }
/************************************************************************ * NAME: fnet_free_mem_status * * DESCRIPTION: Returns a quantity of free memory (for debug needs) * *************************************************************************/ fnet_size_t fnet_mempool_free_mem_status( fnet_mempool_desc_t mpool) { struct fnet_mempool * mempool = (struct fnet_mempool *)mpool; fnet_size_t total_size = 0u; fnet_mempool_unit_header_t *t_mem; fnet_isr_lock(); t_mem = mempool->free_ptr; if(t_mem) { total_size += t_mem->size; #if 0 FNET_DEBUG("%d,",t_mem->size*sizeof(FNET_ALLOC_HDR_T)); #endif while(t_mem->ptr != mempool->free_ptr) { t_mem = t_mem->ptr; total_size += t_mem->size; #if 0 FNET_DEBUG("%d,",t_mem->size*sizeof(FNET_ALLOC_HDR_T));*/ #endif } } fnet_isr_unlock(); return (total_size * mempool->unit_size); }
/************************************************************************ * NAME: fnet_arp_get_mac * * DESCRIPTION: Gets MAC address of valid ARP cache entry. *************************************************************************/ fnet_bool_t fnet_arp_get_mac( fnet_netif_desc_t netif_desc, fnet_ip4_addr_t ip_addr, fnet_mac_addr_t mac_addr) { fnet_netif_t *netif = (fnet_netif_t *)netif_desc; fnet_arp_if_t *arpif; fnet_mac_addr_t *macaddr_p; fnet_bool_t result = FNET_FALSE; if(netif) { arpif = netif->arp_if_ptr; if(arpif) { fnet_isr_lock(); macaddr_p = fnet_arp_lookup(netif, ip_addr); if(macaddr_p) { if(mac_addr) { fnet_memcpy (mac_addr, *macaddr_p, sizeof(fnet_mac_addr_t)); } result = FNET_TRUE; } fnet_isr_unlock(); } } return result; }
void *fnet_mempool_malloc(fnet_mempool_desc_t mpool, unsigned nbytes ) { struct fnet_mempool * mempool = (struct fnet_mempool *)mpool; fnet_mempool_unit_header_t *p, *prevp; unsigned nunits; fnet_isr_lock(); nunits = ((nbytes + mempool->unit_size - 1) / mempool->unit_size) + 1; prevp = mempool->free_ptr; for (p = prevp->ptr; ; prevp = p, p = p->ptr) { if(p->size >= nunits) { if(p->size == nunits) { prevp->ptr = p->ptr; } else { p->size -= nunits; /* Put to the top. */ p = (fnet_mempool_unit_header_t *)((unsigned long)p + p->size*mempool->unit_size); p->size = nunits; } mempool->free_ptr = prevp; fnet_isr_unlock(); return (void *)((unsigned long)p + mempool->unit_size); } if(p == mempool->free_ptr) { fnet_isr_unlock(); return 0; } } fnet_isr_unlock(); return 0; }
/************************************************************************ * NAME: fnet_udp_connect * * DESCRIPTION: UDP connect function. *************************************************************************/ static fnet_return_t fnet_udp_connect( fnet_socket_if_t *sk, struct sockaddr *foreign_addr) { fnet_isr_lock(); fnet_memcpy(&sk->foreign_addr, foreign_addr, sizeof(sk->foreign_addr)); sk->state = SS_CONNECTED; fnet_socket_buffer_release(&sk->receive_buffer); fnet_isr_unlock(); return (FNET_OK); }
/************************************************************************ * NAME: fnet_raw_connect * * DESCRIPTION: RAW connect function. *************************************************************************/ static int fnet_raw_connect( fnet_socket_t *sk, struct sockaddr *foreign_addr) { fnet_isr_lock(); sk->foreign_addr = *foreign_addr; sk->local_addr.sa_port = 0; sk->foreign_addr.sa_port = 0; sk->state = SS_CONNECTED; fnet_socket_buffer_release(&sk->receive_buffer); fnet_isr_unlock(); return (FNET_OK); }
/************************************************************************ * NAME: fnet_netif_drain * * DESCRIPTION: This function calls "drain" functions of all currently * installed network interfaces. *************************************************************************/ void fnet_netif_drain( void ) { fnet_netif_t *net_if_ptr; fnet_isr_lock(); for (net_if_ptr = fnet_netif_list; net_if_ptr; net_if_ptr = net_if_ptr->next) { if(net_if_ptr->api->drain) net_if_ptr->api->drain(net_if_ptr); } fnet_isr_unlock(); }
void fnet_loop_output_ip4(fnet_netif_t *netif, fnet_ip4_addr_t dest_ip_addr, fnet_netbuf_t* nb) { FNET_COMP_UNUSED_ARG(dest_ip_addr); fnet_isr_lock(); /* MTU check */ if (nb->total_length <= netif->mtu) fnet_ip_input(netif, nb); else fnet_netbuf_free_chain(nb); fnet_isr_unlock(); }
/************************************************************************ * NAME: fnet_arp_send_request * * DESCRIPTION: Public function. Sends ARP request. *************************************************************************/ void fnet_arp_send_request( fnet_netif_desc_t netif_desc, fnet_ip4_addr_t ip_addr ) { fnet_netif_t *netif = (fnet_netif_t *)netif_desc; fnet_arp_if_t *arpif; if(netif) { arpif = netif->arp_if_ptr; if(arpif) { fnet_isr_lock(); fnet_arp_request(netif, ip_addr); fnet_isr_unlock(); } } }
/************************************************************************ * DESCRIPTION: RAW shutdown function. *************************************************************************/ static fnet_return_t fnet_raw_shutdown( fnet_socket_if_t *sk, fnet_sd_flags_t how ) { fnet_isr_lock(); if((how & SD_READ) != 0u) { sk->receive_buffer.is_shutdown = FNET_TRUE; fnet_socket_buffer_release(&sk->receive_buffer); } if((how & SD_WRITE) != 0u) { sk->send_buffer.is_shutdown = FNET_TRUE; } fnet_isr_unlock(); return (FNET_OK); }
/************************************************************************ * NAME: fnet_raw_shutdown * * DESCRIPTION: RAW shutdown function. *************************************************************************/ static int fnet_raw_shutdown( fnet_socket_t *sk, int how ) { fnet_isr_lock(); if((how & SD_READ) != 0) { sk->receive_buffer.is_shutdown = 1; fnet_socket_buffer_release(&sk->receive_buffer); } if((how & SD_WRITE) != 0) { sk->send_buffer.is_shutdown = 1; } fnet_isr_unlock(); return (FNET_OK); }
/************************************************************************ * NAME: fnet_arp_resolve * * DESCRIPTION: This function finds the first unused or the oldest * ARP table entry and makes a new entry * to prepare it for an ARP reply. *************************************************************************/ void fnet_arp_resolve(fnet_netif_t *netif, fnet_ip4_addr_t ipaddr, fnet_netbuf_t *nb) { fnet_arp_if_t *arpif = netif->arp_if_ptr; fnet_index_t i; fnet_arp_entry_t *entry; fnet_isr_lock(); for (i = 0U; i < FNET_CFG_ARP_TABLE_SIZE; i++) { if (ipaddr == arpif->arp_table[i].prot_addr) { break; } } /* If no unused entry is found, create it. */ if (i == FNET_CFG_ARP_TABLE_SIZE) { entry = fnet_arp_add_entry(netif, ipaddr, fnet_eth_null_addr); } else { entry = &arpif->arp_table[i]; } if (entry->hold) { fnet_netbuf_free_chain(entry->hold); entry->hold = NULL; } if ((i == FNET_CFG_ARP_TABLE_SIZE) || ((entry->hold) && (((fnet_timer_ticks() - entry->hold_time) * FNET_TIMER_PERIOD_MS) > 1000U)) || (!entry->hold)) { entry->hold_time = fnet_timer_ticks(); entry->hold = nb; fnet_arp_request(netif, ipaddr); } else { entry->hold = nb; } fnet_isr_unlock(); }
/************************************************************************ * NAME: fnet_arp_drain * * DESCRIPTION: This function tries to free not critical parts * of memory used by ARP protocol. *************************************************************************/ void fnet_arp_drain(fnet_netif_t *netif) { fnet_index_t i; fnet_arp_if_t *arpif = netif->arp_if_ptr; fnet_isr_lock(); /* ARP table drain.*/ for (i = 0U; i < FNET_CFG_ARP_TABLE_SIZE; i++) { if (arpif->arp_table[i].hold) { fnet_netbuf_free_chain(arpif->arp_table[i].hold); arpif->arp_table[i].hold = 0; arpif->arp_table[i].hold_time = 0U; } } fnet_isr_unlock(); }
/************************************************************************ * NAME: fnet_arp_drain * * DESCRIPTION: This function tries to free not critical parts * of memory used by ARP protocol. *************************************************************************/ void fnet_arp_drain(fnet_netif_t *netif) { int i; fnet_arp_if_t * arpif = &(((fnet_eth_if_t *)(netif->if_ptr))->arp_if); //PFI fnet_isr_lock(); /* ARP table drain.*/ for(i=0;i<FNET_ARP_TABLE_SIZE;i++) { if(arpif->arp_table[i].hold) { fnet_netbuf_free_chain(arpif->arp_table[i].hold); arpif->arp_table[i].hold=0; arpif->arp_table[i].hold_time=0; } } fnet_isr_unlock(); }
/************************************************************************ * NAME: fnet_event_raise * * DESCRIPTION: This function raise registerted event. *************************************************************************/ void fnet_event_raise(fnet_event_desc_t event_number) { fnet_uint32_t vector_number = (fnet_uint32_t)(event_number); fnet_isr_entry_t *isr_temp; isr_temp = fnet_isr_table; fnet_isr_lock(); while (isr_temp != 0) { if (isr_temp->vector_number == vector_number) { if (isr_temp->handler_top) { isr_temp->handler_top(isr_temp->cookie); } if (fnet_locked == 1u) { isr_temp->pended = FNET_FALSE; if (isr_temp->handler_bottom) { isr_temp->handler_bottom(isr_temp->cookie); } } else { isr_temp->pended = FNET_TRUE; } break; } isr_temp = isr_temp->next; } fnet_isr_unlock(); }
/*FNET_DEBUG("");*/ fnet_isr_unlock(); return (max * mempool->unit_size); } #if 0 /* For Debug needs.*/ int fnet_mempool_check( fnet_mempool_desc_t mpool ) { volatile struct fnet_mempool * mempool = (struct fnet_mempool *)mpool; volatile fnet_mempool_unit_header_t *t_mem; int i = 0; fnet_isr_lock(); t_mem = mempool->free_ptr; if(t_mem == 0) return 0; while(t_mem->ptr != mempool->free_ptr) { i++; if((i>100)||(t_mem->ptr == 0)||(t_mem->ptr == (void *)0xFFFFFFFF)) { fnet_println("!!!MEMPOOL CRASH!!!"); return FNET_ERR; } if( (((unsigned long)t_mem) < (unsigned long)t_mem->ptr) && ((t_mem->size + (unsigned long)t_mem) > (unsigned long)t_mem->ptr)) { fnet_println("!!!MEMPOOL FREE CRASH!!!"); return FNET_ERR; } t_mem = t_mem->ptr; } fnet_isr_unlock(); return FNET_OK; }
/************************************************************************ * NAME: fnet_malloc_max * * DESCRIPTION: Returns a maximum size of posible allocated memory chunk. * *************************************************************************/ fnet_size_t fnet_mempool_malloc_max( fnet_mempool_desc_t mpool ) { struct fnet_mempool *mempool = (struct fnet_mempool *)mpool; fnet_size_t max = 0u; fnet_mempool_unit_header_t *t_mem; fnet_isr_lock(); t_mem = mempool->free_ptr; if(t_mem) { max = t_mem->size; #if 0 FNET_DEBUG("%d,", t_mem->size * sizeof(FNET_ALLOC_HDR_T)); #endif while((t_mem->ptr) && (t_mem->ptr != mempool->free_ptr)) { t_mem = t_mem->ptr; if(t_mem->size > max) { max = t_mem->size; } #if 0 FNET_DEBUG("%d,", t_mem->size * sizeof(FNET_ALLOC_HDR_T)); #endif } #if 0 FNET_DEBUG(""); #endif } fnet_isr_unlock(); return (max * mempool->unit_size); }
/************************************************************************ * NAME: fnet_malloc_max * * DESCRIPTION: Returns a maximum size of posible allocated memory chunk. * *************************************************************************/ fnet_size_t fnet_mempool_malloc_max( fnet_mempool_desc_t mpool ) { struct fnet_mempool *mempool = (struct fnet_mempool *)mpool; fnet_size_t max = 0u; fnet_mempool_unit_header_t *t_mem; fnet_isr_lock(); t_mem = mempool->free_ptr; if(t_mem) { max = t_mem->size; #if 0 FNET_DEBUG("%d,", t_mem->size * sizeof(FNET_ALLOC_HDR_T)); #endif while((t_mem->ptr) && (t_mem->ptr != mempool->free_ptr)) { t_mem = t_mem->ptr; if(t_mem->size > max) { max = t_mem->size; } #if 0 FNET_DEBUG("%d,", t_mem->size * sizeof(FNET_ALLOC_HDR_T)); #endif } #if 0 FNET_DEBUG(""); #endif } fnet_isr_unlock(); return (max * mempool->unit_size); } #if 0 /* For Debug needs.*/ fnet_return_t fnet_mempool_check( fnet_mempool_desc_t mpool ) { volatile struct fnet_mempool * mempool = (struct fnet_mempool *)mpool; volatile fnet_mempool_unit_header_t *t_mem; fnet_index_t i = 0u; fnet_isr_lock(); t_mem = mempool->free_ptr; if(t_mem) { while(t_mem->ptr != mempool->free_ptr) { i++; if((i>100u)||(t_mem->ptr == 0)||(t_mem->ptr == (void *)0xFFFFFFFF)) { fnet_println("!!!MEMPOOL CRASH!!!"); return FNET_ERR; } if( (((fnet_uint32_t)t_mem) < (fnet_uint32_t)t_mem->ptr) && ((t_mem->size + (fnet_uint32_t)t_mem) > (fnet_uint32_t)t_mem->ptr)) { fnet_println("!!!MEMPOOL FREE CRASH!!!"); return FNET_ERR; } t_mem = t_mem->ptr; } } fnet_isr_unlock(); return FNET_OK; }
/************************************************************************ * NAME: fnet_arp_get_entry * * DESCRIPTION: This function Retrieves ARP cache entry of * the specified network interface. *************************************************************************/ fnet_bool_t fnet_arp_get_entry ( fnet_netif_desc_t netif_desc, fnet_index_t n, fnet_arp_entry_info_t *entry_info ) { fnet_netif_t *netif = (fnet_netif_t *)netif_desc; fnet_bool_t result = FNET_FALSE; fnet_arp_if_t *arpif; fnet_index_t i; if(netif && entry_info) { arpif = netif->arp_if_ptr; if(arpif) { for(i = 0u; i < FNET_CFG_ARP_TABLE_SIZE; i++) { /* Skip NOT_USED prefixes. */ if(arpif->arp_table[i].prot_addr != 0U) { if(n == 0u) { fnet_isr_lock(); /* Fill entry.*/ entry_info->ip_addr = arpif->arp_table[i].prot_addr; fnet_memcpy(entry_info->mac_addr, arpif->arp_table[i].hard_addr, sizeof(fnet_mac_addr_t)); fnet_isr_unlock(); result = FNET_TRUE; break; } n--; } } } } return result; }
/************************************************************************ * NAME: fnet_udp_snd * * DESCRIPTION: UDP send function. *************************************************************************/ static fnet_int32_t fnet_udp_snd( fnet_socket_if_t *sk, fnet_uint8_t *buf, fnet_size_t len, fnet_flag_t flags, const struct sockaddr *addr) { fnet_netbuf_t *nb; fnet_error_t error = FNET_ERR_OK; const struct sockaddr *foreign_addr; fnet_bool_t flags_save = FNET_FALSE; fnet_isr_lock(); #if FNET_CFG_TCP_URGENT if(flags & MSG_OOB) { error = FNET_ERR_OPNOTSUPP; /* Operation not supported.*/ goto ERROR; } #endif /* FNET_CFG_TCP_URGENT */ if(len > sk->send_buffer.count_max) { error = FNET_ERR_MSGSIZE; /* Message too long. */ goto ERROR; } if(addr) { foreign_addr = addr; } else { foreign_addr = &sk->foreign_addr; } if((nb = fnet_netbuf_from_buf(buf, len, FNET_FALSE)) == 0) { error = FNET_ERR_NOMEM; /* Cannot allocate memory.*/ goto ERROR; } if(sk->local_addr.sa_port == 0u) { sk->local_addr.sa_port = fnet_socket_get_uniqueport(sk->protocol_interface->head, &sk->local_addr); /* Get ephemeral port.*/ } if((flags & MSG_DONTROUTE) != 0u) /* Save */ { flags_save = sk->options.so_dontroute; sk->options.so_dontroute = FNET_TRUE; } error = fnet_udp_output(&sk->local_addr, foreign_addr, &(sk->options), nb); if((flags & MSG_DONTROUTE) != 0u) /* Restore.*/ { sk->options.so_dontroute = flags_save; } if((error == FNET_ERR_OK) && (sk->options.local_error == FNET_ERR_OK)) /* We get UDP or ICMP error.*/ { fnet_isr_unlock(); return (fnet_int32_t)(len); } ERROR: fnet_socket_set_error(sk, error); fnet_isr_unlock(); return (FNET_ERR); }
/************************************************************************ * NAME: fnet_netif_init * * DESCRIPTION: This function installs & inits a network interface. *************************************************************************/ int fnet_netif_init( fnet_netif_t *netif, unsigned char *hw_addr, unsigned int hw_addr_size ) { int result = FNET_OK; if(netif && netif->api) { fnet_os_mutex_lock(); fnet_isr_lock(); netif->next = fnet_netif_list; if(netif->next != 0) netif->next->prev = netif; netif->prev = 0; fnet_netif_list = netif; fnet_netif_assign_scope_id( netif ); /* Asign Scope ID.*/ netif->features = FNET_NETIF_FEATURE_NONE; /* Interface HW initialization.*/ if(netif->api->init && ((result = netif->api->init(netif)) == FNET_OK)) { #if FNET_CFG_IGMP && FNET_CFG_IP4 /************************************************************** * RFC1112 7.2 * To support IGMP, every level 2 host must * join the "all-hosts" group (address 224.0.0.1) on each network * interface at initialization time and must remain a member for as long * as the host is active. * * NOTE:(224.0.0.1) membership is never reported by IGMP. **************************************************************/ /* Join HW interface. */ fnet_netif_join_ip4_multicast ( netif, FNET_IP4_ADDR_INIT(224, 0, 0, 1) ); #endif /* FNET_CFG_IGMP */ /* Set HW Address.*/ fnet_netif_set_hw_addr(netif, hw_addr, hw_addr_size); /* Interface-Type specific initialisation. */ switch(netif->api->type) { #if (FNET_CFG_CPU_ETH0 ||FNET_CFG_CPU_ETH1) case (FNET_NETIF_TYPE_ETHERNET): result = fnet_eth_init(netif); break; #endif /* FNET_CFG_ETH */ default: break; } } fnet_printf("ETH - Initialization: %s, ID:%d\n", netif->name, netif->scope_id); fnet_printf(" - IP: %x, GW: %x\n", netif->ip4_addr.address, netif->ip4_addr.gateway); fnet_printf(" - MASK: %x, DHCP?: %d\n", netif->ip4_addr.netmask, netif->ip4_addr.is_automatic); fnet_printf(" - MTU: %d\n", netif->mtu); fnet_printf(" - MTU: %x\n", netif->if_ptr); fnet_isr_unlock(); fnet_os_mutex_unlock(); } return result; }
/************************************************************************ * NAME: fnet_netif_init_all * * DESCRIPTION: Initialization of all supported interfaces. *************************************************************************/ int fnet_netif_init_all( void ) { int result = FNET_OK; fnet_isr_lock(); fnet_netif_list = fnet_netif_default = 0; /*********************************** * Initialize IFs. ************************************/ #if FNET_CFG_CPU_ETH0 /* Initialise eth0 interface.*/ { fnet_mac_addr_t macaddr = {0x00,0x11,0x22,0x33,0x44,0x55}; /* Set MAC Address.*/ fnet_str_to_mac(FNET_CFG_CPU_ETH0_MAC_ADDR, macaddr); result = fnet_netif_init(FNET_ETH0_IF, macaddr, sizeof(fnet_mac_addr_t)); if(result == FNET_ERR) goto INIT_ERR; } #endif #if FNET_CFG_CPU_ETH1 /* Initialise eth0 interface.*/ { fnet_mac_addr_t macaddr = {0x00,0x11,0x22,0x33,0x33,0x55}; /* Set MAC Address.*/ fnet_str_to_mac(FNET_CFG_CPU_ETH1_MAC_ADDR, macaddr); result = fnet_netif_init(FNET_ETH1_IF, macaddr, sizeof(fnet_mac_addr_t)); if(result == FNET_ERR) goto INIT_ERR; } #endif #if FNET_CFG_LOOPBACK /* Initialise Loop-back interface.*/ result = fnet_netif_init(FNET_LOOP_IF); if(result == FNET_ERR) goto INIT_ERR; #endif /* FNET_CFG_LOOPBACK */ /*********************************** * Set default parameters. ************************************/ fnet_netif_set_default(FNET_CFG_DEFAULT_IF); /* Default interface.*/ /* Set address parameters of the Ethernet interface.*/ #if FNET_CFG_IP4 #if FNET_CFG_CPU_ETH0 { fnet_netif_set_ip4_addr(FNET_ETH0_IF, FNET_CFG_ETH0_IP4_ADDR); fnet_netif_set_ip4_subnet_mask(FNET_ETH0_IF, (unsigned long)FNET_CFG_ETH0_IP4_MASK); fnet_netif_set_ip4_gateway(FNET_ETH0_IF, FNET_CFG_ETH0_IP4_GW); #if FNET_CFG_DNS fnet_netif_set_ip4_dns(FNET_ETH0_IF, FNET_CFG_ETH0_IP4_DNS); #endif } #endif /* FNET_CFG_CPU_ETH0 */ #if FNET_CFG_CPU_ETH1 { fnet_netif_set_ip4_addr(FNET_ETH1_IF, FNET_CFG_ETH1_IP4_ADDR); fnet_netif_set_ip4_subnet_mask(FNET_ETH1_IF, (unsigned long)FNET_CFG_ETH1_IP4_MASK); fnet_netif_set_ip4_gateway(FNET_ETH1_IF, FNET_CFG_ETH1_IP4_GW); #if FNET_CFG_DNS fnet_netif_set_ip4_dns(FNET_ETH1_IF, FNET_CFG_ETH1_IP4_DNS); #endif } #endif /* FNET_CFG_CPU_ETH0 */ #endif /* FNET_CFG_ETH */ /* Set address parameters of the Loopback interface.*/ #if FNET_CFG_LOOPBACK && FNET_CFG_IP4 fnet_netif_set_ip4_addr(FNET_LOOP_IF, FNET_CFG_LOOPBACK_IP4_ADDR); #endif /* FNET_CFG_LOOPBACK */ INIT_ERR: fnet_isr_unlock(); return result; }
/************************************************************************ * NAME: fnet_malloc * * DESCRIPTION: Allocates memory in the memory pool. * *************************************************************************/ #if FNET_MEMPOOL_MALLOC_BEST_CHOICE /* Choose the best. */ void *fnet_mempool_malloc(fnet_mempool_desc_t mpool, unsigned nbytes ) { struct fnet_mempool * mempool = (struct fnet_mempool *)mpool; fnet_mempool_unit_header_t *p, *prevp; fnet_mempool_unit_header_t *best_p =0; fnet_mempool_unit_header_t *best_p_prev =0; unsigned nunits; void * res; fnet_isr_lock(); nunits = ((nbytes + mempool->unit_size - 1) / mempool->unit_size) + 1; prevp = mempool->free_ptr; best_p_prev = prevp; /* Find the best one. */ for(p = prevp->ptr; ; prevp = p, p = p->ptr) { if( (p->size >= nunits) && ( (best_p==0) || ((best_p)&&(best_p->size > p->size)) ) ) { best_p_prev = prevp; best_p = p; } if(p == mempool->free_ptr) break; /* End of list is reached. */ } if(best_p) { if(best_p->size == nunits) { best_p_prev->ptr = best_p->ptr; } else { best_p->size -= nunits; /* Put to the top. */ best_p = (fnet_mempool_unit_header_t *)((unsigned long)best_p + best_p->size*mempool->unit_size); best_p->size = nunits; } mempool->free_ptr = best_p_prev; res = (void *)((unsigned long)best_p + mempool->unit_size); #if 0 /* Clear mem.*/ fnet_memset_zero( res, (nunits-1)* mempool->unit_size ); #endif } else { /* Break here to detect allocation errors */ res = 0; } #if FNET_DEBUG_MEMPOOL_CHECK if(res) { int i; for(i=DEBUG_last_free_addr_num; i<DEBUG_ALLOCATED_ADDR_MAX; i++) { if(DEBUG_allocated_addr[i].address == 0) { /* Save allocated address */ DEBUG_allocated_addr[i].address = res; DEBUG_allocated_addr[i].size = nunits; break; } } if( i==DEBUG_ALLOCATED_ADDR_MAX) fnet_println ("Addr_table_overload!!!"); } #endif fnet_isr_unlock(); return res; }
/************************************************************************ * NAME: fnet_free * * DESCRIPTION: Frees memory in the mempool. * *************************************************************************/ void fnet_mempool_free( fnet_mempool_desc_t mpool, void *ap ) { struct fnet_mempool * mempool = (struct fnet_mempool *)mpool; fnet_mempool_unit_header_t *bp, *p; if(ap != 0) { fnet_isr_lock(); /* Block pointer = allocated memory block addr - allocation unit size.*/ bp = (fnet_mempool_unit_header_t *)((unsigned long)ap - mempool->unit_size); /* Point to block header. */ #if FNET_DEBUG_MEMPOOL_CHECK { int i; for(i=0; i<DEBUG_ALLOCATED_ADDR_MAX; i++) { if(DEBUG_allocated_addr[i].address == ap) { if(DEBUG_allocated_addr[i].size == bp->size) { DEBUG_allocated_addr[i].address = 0; // Clear; DEBUG_last_free_addr_num = i-50; if (DEBUG_last_free_addr_num < 0) DEBUG_last_free_addr_num = 0; break; } else { fnet_println ("Wrong free size!!!!!!!!"); break; } } } if( i==DEBUG_ALLOCATED_ADDR_MAX) fnet_println ("This addr never allocated before!!!!!!!!"); } #endif for (p = mempool->free_ptr; !((bp > p) && (bp < p->ptr)); p = p->ptr) { #if FNET_DEBUG_MEMPOOL_CHECK /* Debug Check. */ if( (p <= bp) && ((unsigned long)bp <= ((unsigned long)p + p->size)) )/* The block is already free */ { fnet_println("Already Free UPS"); fnet_isr_unlock(); return; } #endif if((p >= p->ptr) && ((bp > p) || (bp < p->ptr))) { break; /* Freed block at start or end of arena. */ } } if((fnet_mempool_unit_header_t *)((unsigned long)bp + bp->size*mempool->unit_size) == p->ptr) { bp->size += p->ptr->size; bp->ptr = p->ptr->ptr; } else { bp->ptr = p->ptr; } if((fnet_mempool_unit_header_t *)((unsigned long)p + p->size*mempool->unit_size) == bp) { p->size += bp->size; p->ptr = bp->ptr; } else { p->ptr = bp; } mempool->free_ptr = p; fnet_isr_unlock(); } }