diff --git a/drivers/net/mmnif.c b/drivers/net/mmnif.c index a8d47d15..616652cc 100644 --- a/drivers/net/mmnif.c +++ b/drivers/net/mmnif.c @@ -70,7 +70,10 @@ extern HANDLE hProc; #define MMNIF_CORES 2 -#define MMNIF_WORKER_BUDGET 5 +#define MMNIF_WORKER_BUDGET 2 + +#define MMNIF_POLL_BUDGET 0x100000 +#define MMNIF_WAIT_BUDGET 0x2 /* decide whether it's polling mode or not */ @@ -84,6 +87,10 @@ static int active = 0; */ static int disable_locking = 0; +/* decide whether deliver work to a worker thread or instantly process all packets + */ +static int instant_process = 1; + /* IP address of the local core and the router core to get packets forwarded */ static unsigned int own_ip_address = 0xC0A80000; /* 192.168.0.0 */ @@ -115,8 +122,6 @@ static int pulse_irq = 0; #define RCK_INTR_MASK 0x00000002 #define RCK_NMI_MASK 0x00000001 - - /* * the memory mapped network device */ @@ -131,8 +136,10 @@ typedef struct mmnif_device_stats /* device stats (granularity in packets): * - recieve errors * - recieve successes + * - recieved bytes * - transmit errors * - transmit successes + * - transmitted bytes */ unsigned int rx_err; unsigned int rx; @@ -145,7 +152,10 @@ typedef struct mmnif_device_stats unsigned int tx_bytes; /* Heuristics : - * + * - how many times an budget overflow occured + * - how many times the polling thread polled without recieving a new message + * - how many messages are recieved via interrupt + * - how many messages are recieved via the polling thread */ unsigned int bdg_overflow; unsigned int pll_empty; @@ -167,8 +177,8 @@ typedef struct mm_rx_buffer * I won't use a single buffer the whole time. I think i will use an descripor table * and a table which descriptor is in use and use the buffer space dynamically with * descriptors - * - * And this buffer needs a lock as soon as more as cores are availible =/ + * Also timeouts should be checked so if one core dies the buffer space is not blocked + * all the time */ uint8_t queued; uint8_t pos; @@ -178,6 +188,9 @@ typedef struct mm_rx_buffer sem_t lock; +// uint32_t timestamp[MMNIF_RX_QUEUELEN]; +// uint32_t bitmap[MMNIF_RX_QUEUELEN]; + // void* rx_desc[MMNIF_CORES * MMNIF_RX_QUEUELEN]; // uint8_t rx_inuse[MMNIF_CORES * MMNIF_RX_QUEUELEN]; /* bits 1: pending 2: finished 3: free ...*/ // uint8_t fin; @@ -502,11 +515,6 @@ __inline int mmnif_worker_schedule() */ __inline void* mmnif_shmalloc() { - /* Right now every core has the same buffer for every incoming packet - * this will be removed and a buffer for each Core will be implemented - * - * but i'm first testing with two cores/processes. - */ #ifdef WIN32 mpb_size = sizeof(mm_rx_buffer_t) + MMNIF_RX_QUEUELEN* MMNIF_RX_BUFFERLEN; mpb_start_address = VirtualAlloc((char*)0x41000000 /*+ @@ -516,15 +524,8 @@ __inline void* mmnif_shmalloc() return (char*)0x41000000 + (mpb_size) * (own_ip_address - router_ip_address); #else mpb_size = (sizeof(mm_rx_buffer_t) + MMNIF_RX_QUEUELEN* MMNIF_RX_BUFFERLEN); - /* We choose a arbitrary address first - * until i know how to properly allocate shared memory - */ -// RCCE_shmalloc_init(0x80000000,48*8192); + mpb_start_address = RCCE_shmalloc(mpb_size*MMNIF_CORES); - //mpb_start_address = 0x8000000+ mpb_size * (own_ip_address - router_ip_address); - //SHMalloc(&mpb_start_address); - //mpb_start_address = kmalloc(mpb_size*MMNIF_CORES); -// mpb_start_address = 0xC0000000; return mpb_start_address + (mpb_size) * (own_ip_address - router_ip_address); #endif } @@ -773,8 +774,6 @@ err_t mmnif_tx(struct netif* netif, struct pbuf* p) else mmnif_write_rx_buffl(dest_ip, pos, p->payload,p->tot_len); -// udelay(50000); - /* like above ensure we are the only ones editing the hdr */ mmnif_lock_rx_hdr(dest_ip); @@ -881,6 +880,9 @@ err_t mmnif_init(struct netif* netif) */ sem_init(&mmnif->com_poll,1); + + /* since there is no possibilty to create a full semaphore we just block it manually + */ sem_wait(&mmnif->com_poll); /* inform via interrupt should be the dafault @@ -1085,20 +1087,23 @@ static int mmnif_wait(struct netif* netif, uint32_t poll, int budget) quota = budget; mmnif->stats.bdg_overflow++; - if (mmnif->stats.bdg_overflow >= 0x10) + if (mmnif->stats.bdg_overflow >= MMNIF_WAIT_BUDGET) { /* enable polling and disable interrupts - * - - */ - mmnif_lock_rx_hdr(own_ip_address && 0xff); - mmnif->rx_buff->iv_intr = FALSE; - mmnif_unlock_rx_hdr(own_ip_address && 0xff); + * (only if polling isn't enabled anyways) + */ + if (mmnif->rx_buff->iv_intr == TRUE) + { + mmnif_lock_rx_hdr(own_ip_address && 0xff); + mmnif->rx_buff->iv_intr = FALSE; + mmnif_unlock_rx_hdr(own_ip_address && 0xff); #ifdef DEBUG_MMNIF - DEBUGPRINTF("mmnif_wait(): heuristical polling enables\n"); + DEBUGPRINTF("mmnif_wait(): heuristical polling enables\n"); #endif - sem_post(&mmnif->com_poll); - mmnif->stats.bdg_overflow = 0; + sem_post(&mmnif->com_poll); + } + + mmnif->stats.bdg_overflow = 0; } } @@ -1109,7 +1114,7 @@ static int mmnif_wait(struct netif* netif, uint32_t poll, int budget) /* fetch new data from mmnif_rx() if there is any */ if (poll) { - /* if there is no data return immeadieatly*/ + /* if there is no data return immeadieatly */ if (mailbox_ptr_tryfetch(&(mmnif->mbox), (void**) &p)) return err; } @@ -1160,7 +1165,6 @@ int mmnif_poll(void* e) { mmnif_t* mmnif; unsigned int diff = mmnif_timestamp(); - unsigned int tmp32 = 0; if (!mmnif_dev) { @@ -1184,10 +1188,7 @@ int mmnif_poll(void* e) { while (!mmnif->rx_buff->queued) { - tmp32 = mmnif_timestamp(); - diff = diff - tmp32 > 0 ? diff - tmp32 : tmp32 - diff; - mmnif->stats.pll_empty++; - if (mmnif->stats.pll_empty >= 0x100000) + if (mmnif->stats.pll_empty >= MMNIF_POLL_BUDGET) { /* enable interrupts and suspend polling * @@ -1203,9 +1204,10 @@ int mmnif_poll(void* e) } } mmnif->stats.pll_empty--; -// udelay(30000); mmnif_rx(mmnif_dev); -// mmnif_wait(mmnif_dev,0,MMNIF_WORKER_BUDGET); + + if (instant_process) + mmnif_wait(mmnif_dev,0,MMNIF_WORKER_BUDGET); } return NULL; @@ -1227,7 +1229,12 @@ void mmnif_irqhandler() mmnif = (mmnif_t*) mmnif_dev->state; while (mmnif->rx_buff->queued) + { mmnif_rx(mmnif_dev); + + if (instant_process) + mmnif_wait(mmnif_dev,0,MMNIF_WORKER_BUDGET); + } } /* @@ -1244,7 +1251,7 @@ int mmnif_open() */ IP4_ADDR(&gw, 0,0,0,0); IP4_ADDR(&ipaddr, 192,168,0,get_my_core_no() +1); - IP4_ADDR(&netmask, 255,0,0,0); + IP4_ADDR(&netmask, 255,255,255,0); own_ip_address+= get_my_core_no() +1; @@ -1288,13 +1295,13 @@ int mmnif_open() /* If interrupts are not used we immediately add the polling function * to the queue which would otherwise be done through the IRQ handler. */ -// if (no_irq) - mmnif_device_schedule(); + mmnif_device_schedule(); /* Start the device worker thread wich actually processes the incoming * packet's this is not done in the "interrupt handler" to shorten them up */ - mmnif_worker_schedule(); + if (!instant_process) + mmnif_worker_schedule(); #ifdef DEBUG_MMNIF DEBUGPRINTF("mmnif_dev is open\n"); @@ -1330,9 +1337,11 @@ int mmnif_close() #ifdef WIN32 free(mmnif->tx_buff); free(mmnif_dev); + VirtualFree(mpb_start_address,NULL,NULL); #else -// kfree(mmnif->tx_buff); -// kfree(mmnif_dev); + kfree(mmnif->tx_buff[0],MMNIF_TX_QUEUELEN * MMNIF_TX_BUFFERLEN); + kfree(mmnif_dev,sizeof(mmnif_t)); + RCCE_shfree(mpb_start_address); #endif return NULL; }