diff --git a/drivers/net/mmnif.c b/drivers/net/mmnif.c index a8a728ac..6ca4a96b 100644 --- a/drivers/net/mmnif.c +++ b/drivers/net/mmnif.c @@ -85,10 +85,8 @@ #define MMNIF_AUTO_SOCKET_TIMEOUT 500 -#define MMNIF_FAST_SOCKET_BLOCK 0 - #ifdef DEBUG_MMNIF -#include "util.h" /* hex dump */ +#include /* hex dump */ #endif /* define constants @@ -145,7 +143,6 @@ typedef struct acceptor { /* stat: status of the acceptor * src_ip: where did the connect request came from * port: port on which the acceptor is listening - * alock : acceptor lock * nsock : next pseudo socket which is used in further connection * rsock : remote socket which has to be assosicated with the nsock */ @@ -161,13 +158,13 @@ typedef struct acceptor { typedef struct bypass_rxdesc { /* socket : hashtarget * remote_socket: socket on the remote end - * cnt : atomic counter for the recv function + * counter : packet counter + * last_id : last packet id * dest_ip : associated destination ip/core */ int socket; int remote_socket; sem_t sem; - atomic_int32_t cnt; uint8_t dest_ip; } bypass_rxdesc_t; @@ -205,6 +202,7 @@ typedef struct rx_desc { * addr : memory address of the packet * fast_sock: (-1) if no socket is associated * else the socket n of the fast socket + * id : packet id */ uint8_t stat; uint16_t len; @@ -251,12 +249,12 @@ typedef struct mmnif { uint32_t ipaddr; // checks the TCPIP thread already the rx buffers? - uint8_t check_in_progress; + volatile uint8_t check_in_progress; /* memory interaction variables: * - pointer to recive buffer */ - mm_rx_buffer_t *rx_buff; + volatile mm_rx_buffer_t *rx_buff; uint8_t *rx_heap; /* semaphore to regulate polling vs. interrupts @@ -326,7 +324,7 @@ inline static void* memcpy_to_nc(void* dest, const void *src, size_t count) /* trigger an interrupt on the remote processor * so he knows there is a packet to read */ -inline static int mmnif_trigger_irq(dest_ip) +inline static int mmnif_trigger_irq(int dest_ip, int safe) { int tmp, x, y, z, addr; int ue = dest_ip - 1; @@ -336,32 +334,19 @@ inline static int mmnif_trigger_irq(dest_ip) y = Y_PID(RC_COREID[ue]); addr = CRB_ADDR(x, y) + (z == 0 ? GLCFG0 : GLCFG1); - // send interrupt to ue - //do { - // NOP1; - tmp = ReadConfigReg(addr); - //} while (tmp & 1); + if (safe) { + // send interrupt to ue + do { + NOP8; + tmp = ReadConfigReg(addr); + } while (tmp & 1); + } else tmp = ReadConfigReg(addr); tmp |= 1; SetConfigReg(addr, tmp); return 0; } -/* mmnif_get_device_stats(): Returns a copy of the - * current device - */ -static mmnif_device_stats_t mmnif_get_device_stats(void) -{ - mmnif_device_stats_t stats = { 0 }; - - if (!mmnif_dev) - DEBUGPRINTF("mmnif_get_device_stats(): the device is not initialized yet.\n"); - else - stats = ((mmnif_t *) mmnif_dev->state)->stats; - - return stats; -} - /* mmnif_print_stats(): Print the devices stats of the * current device */ @@ -452,7 +437,6 @@ static uint8_t mmnif_get_destination(struct netif *netif, struct pbuf *p) /* check if the address is legitimata else return router core again */ if ((core) < 1 || (core > MMNIF_CORES)) core = 1; - kprintf("core %d\n", (int) core); return core; } @@ -461,7 +445,7 @@ static uint8_t mmnif_get_destination(struct netif *netif, struct pbuf *p) * right inside of the buffer which is used for communication * with the remote end */ -static uint32_t mmnif_rxbuff_alloc(uint8_t dest, uint16_t len) +static uint32_t mmnif_rxbuff_alloc(uint8_t dest, uint16_t len/*, uint32_t id*/) { uint32_t ret = 0; volatile mm_rx_buffer_t *rb = (mm_rx_buffer_t *) ((char *)header_start_address + (dest - 1) * header_size); @@ -631,7 +615,6 @@ static err_t mmnif_tx(struct netif *netif, struct pbuf *p) uint32_t i; struct pbuf *q; /* interator */ uint32_t dest_ip = mmnif_get_destination(netif, p); - //int32_t chances = 4000; /* check for over/underflow */ if (BUILTIN_EXPECT((p->tot_len < 20 /* IP header size */) || (p->tot_len > 1536), 0)) { @@ -646,14 +629,7 @@ realloc: { //DEBUGPRINTF("mmnif_tx(): concurrency"); - //chances--; - //if (chances <= 0) - // goto drop_packet; - //if (chances % 17 == 0) - // mmnif_trigger_irq(dest_ip); - NOP8;NOP8;NOP8;NOP8;NOP8;NOP8;NOP8;NOP8; - //udelay(10); goto realloc; } @@ -691,7 +667,7 @@ realloc: mmnif->stats.tx++; mmnif->stats.tx_bytes += p->tot_len; - mmnif_trigger_irq(dest_ip); + mmnif_trigger_irq(dest_ip, 1); return ERR_OK; @@ -787,20 +763,16 @@ static err_t mmnif_tx_bypass(struct netif * netif, void *pbuff, uint16_t size, i { mmnif_t *mmnif = netif->state; uint32_t write_address; + //uint32_t id; bypass_rxdesc_t *dest = mmnif_hashlookup(s); - //uint32_t exp_delay = 2; //mm_rx_buffer_t *rb = (mm_rx_buffer_t *) ((char *)header_start_address + (dest->dest_ip - 1) * header_size); /* allocate memory for the packet in the remote buffer */ + //id = ++dest->counter; realloc: write_address = mmnif_rxbuff_alloc(dest->dest_ip, size); if (!write_address) { - - // DEBUGPRINTF("mmnif_tx_bypass(): concurrency"); - // udelay(exp_delay); - // exp_delay << 1; - // reschedule(); NOP8;NOP8;NOP8;NOP8;NOP8;NOP8;NOP8;NOP8; goto realloc; } @@ -817,7 +789,7 @@ realloc: #if !MMNIF_USE_MPB memcpy_to_nc((void*) write_address, pbuff, size); #else - memcpy_put(write_address, pbuff, size); + memcpy_put((void*) write_address, pbuff, size); #endif *((int *)RCCE_fool_write_combine_buffer) = 1; @@ -839,16 +811,10 @@ realloc: mmnif->stats.tx++; mmnif->stats.tx_bytes += size; - mmnif_trigger_irq(dest->dest_ip); + if (size >= ((MMNIF_RX_BUFFERLEN / 2) - 1)) + mmnif_trigger_irq(dest->dest_ip, 0); return ERR_OK; - -drop_packet: - /* drop packet for one or another reason - */ - LINK_STATS_INC(link.drop); - mmnif->stats.tx_err++; - return ERR_IF; } /* mmnif_send(): is going to be used as replacement of @@ -864,24 +830,24 @@ int mmnif_send(int s, void *data, size_t size, int flags) { if (size < ((MMNIF_RX_BUFFERLEN / 2) - 1)) { if (mmnif_tx_bypass(mmnif_dev, data, size, s) == ERR_OK) - return size; - else - return -1; + total_size = size; } else { j = size / (((MMNIF_RX_BUFFERLEN / 2) - 1)); k = size - (j * (((MMNIF_RX_BUFFERLEN / 2) - 1))); for (i = 0; i < j; i++) { - if (mmnif_tx_bypass(mmnif_dev, data + i * ((MMNIF_RX_BUFFERLEN / 2) - 1), ((MMNIF_RX_BUFFERLEN / 2) - 1), s) != ERR_OK) - return total_size; + if (mmnif_tx_bypass(mmnif_dev, (char*) data + i * ((MMNIF_RX_BUFFERLEN / 2) - 1), ((MMNIF_RX_BUFFERLEN / 2) - 1), s) != ERR_OK) + goto out; total_size += (MMNIF_RX_BUFFERLEN / 2) - 1; } - if (mmnif_tx_bypass(mmnif_dev, data + (j - 1) * ((MMNIF_RX_BUFFERLEN / 2) - 1), k, s) != ERR_OK) - return total_size; - return total_size + k; + if (mmnif_tx_bypass(mmnif_dev, data + (j - 1) * ((MMNIF_RX_BUFFERLEN / 2) - 1), k, s) == ERR_OK) + total_size += k; } +out: + mmnif_trigger_irq(p->dest_ip, 1); + return total_size; } return lwip_send(s, data, size, flags); @@ -1014,10 +980,9 @@ err_t mmnif_init(struct netif *netif) mmnif_hashtable[i].socket = -1; mmnif_hashtable[i].remote_socket = -1; mmnif_hashtable[i].dest_ip = 0; + //mmnif_hashtable[i].counter = 0; -#if MMNIF_FAST_SOCKET_BLOCK sem_init(&mmnif_hashtable[i].sem, 0); -#endif } for (i=0; idesc_table[rdesc].stat = MMNIF_STATUS_INPROC; -#if MMNIF_FAST_SOCKET_BLOCK sem_post(&bp->sem); -#else - atomic_int32_inc(&bp->cnt); -#endif - goto anotherpacket; + irq_nested_enable(flags); + return; } } } @@ -1140,6 +1103,8 @@ anotherpacket: goto out; } + irq_nested_enable(flags); + /* check for over/underflow */ if (BUILTIN_EXPECT((length < 20 /* IP header size */) || (length > 1536), 0)) { @@ -1217,9 +1182,12 @@ drop_packet: /* TODO: error handling */ LINK_STATS_INC(link.drop); mmnif->stats.rx_err++; + mmnif->check_in_progress = 0; + return; out: mmnif->check_in_progress = 0; + irq_nested_enable(flags); return; } @@ -1327,27 +1295,49 @@ drop_packet: */ int mmnif_recv(int s, void *data, uint32_t len, int flags) { + mmnif_t* mmnif = (mmnif_t *) mmnif_dev->state; bypass_rxdesc_t *p = mmnif_hashlookup(s); int ret; if (p == 0) return lwip_recv(s, data, len, flags); -#if MMNIF_FAST_SOCKET_BLOCK + if (sem_trywait(&p->sem) == 0) + return mmnif_rx_bypass(mmnif_dev, s, data, len); + + uint32_t state = irq_nested_disable(); + if (mmnif->check_in_progress) { + uint32_t i,j; + volatile mm_rx_buffer_t *b = mmnif->rx_buff; + bypass_rxdesc_t *bp; + uint8_t rdesc; + + /* search the packet whose transmission is finished + */ + for (i = 0, j = b->dread; i < MMNIF_MAX_DESCRIPTORS; i++) + { + if (b->desc_table[(j + i) % MMNIF_MAX_DESCRIPTORS].stat == MMNIF_STATUS_RDY) + { + rdesc = (j + i) % MMNIF_MAX_DESCRIPTORS; + if (b->desc_table[(j + i) % MMNIF_MAX_DESCRIPTORS].fast_sock != -1) { + bp = mmnif_hashlookup(b->desc_table[rdesc].fast_sock); + if (bp) { + b->desc_table[rdesc].stat = MMNIF_STATUS_INPROC; + ret = mmnif_rx_bypass(mmnif_dev, s, data, len); + irq_nested_enable(state); + return ret; + } + } + } + } + + mmnif->check_in_progress = 0; + } + irq_nested_enable(state); + sem_wait(&p->sem, 0); -#else - while (!atomic_int32_read(&p->cnt)) - { - //reschedule(); - NOP8; - } -#endif - - ret = mmnif_rx_bypass(mmnif_dev, s, data, len); - atomic_int32_dec(&p->cnt); - - return ret; + return mmnif_rx_bypass(mmnif_dev, s, data, len); } /* mmnif_socket(): replacement of lwip_socket for @@ -1586,7 +1576,7 @@ static void mmnif_irqhandler(struct state* s) mmnif = (mmnif_t *) mmnif_dev->state; if (!mmnif->check_in_progress) { if (tcpip_callback_with_block(mmnif_rx, (void*) mmnif_dev, 0) == ERR_OK) { - mmnif->check_in_progress = 1; + mmnif->check_in_progress = 1; } else { DEBUGPRINTF("rckemacif_handler: unable to send a poll request to the tcpip thread\n"); } diff --git a/drivers/net/mmnif.h b/drivers/net/mmnif.h index c3030aae..67fd46a7 100644 --- a/drivers/net/mmnif.h +++ b/drivers/net/mmnif.h @@ -31,9 +31,6 @@ #define MMNIF_AUTOACTIVATE_FAST_SOCKETS 1 #if MMNIF_AUTOACTIVATE_FAST_SOCKETS -//#ifndef socklen_t -//# define socklen_t u32_t -//#endif int mmnif_socket(int domain, int type, int protocol); int mmnif_send(int s, void *data, size_t size, int flags);