several changes, stats, optimizing copy process etc

This commit is contained in:
Carl-Benedikt Krger 2011-06-10 18:04:21 +02:00
parent 8c6e679ba0
commit 243a2b4f92

View file

@ -59,6 +59,8 @@ extern HANDLE hProc;
#define MMNIF_CORES 2
#define MMNIF_WORKER_BUDGET 5
/* decide whether it's polling mode or not
*/
static int no_irq = 0;
@ -86,10 +88,24 @@ unsigned int mpb_size = NULL;
/* Register offset for the CONFIG and LOCK registers */
#define RCK_GLCFG0 0x10
#define RCK_GLCFG1 0x18
#define RCK_TILEID 0x100
#define RCK_TILE_SIZE 0x01000000
/* Start address of the local register bank */
static int local_crb = 0xF8000000;
static int crb = 0xE0000000;
/* just set and reset the irq */
static int pulse_irq = 1;
/* Mask of the interrupt bits */
#define RCK_INTR_MASK 0x00000002
#define RCK_NMI_MASK 0x00000001
/*
* the memory mapped network device
@ -111,11 +127,21 @@ typedef struct mmnif_device_stats
unsigned int rx_err;
unsigned int rx;
unsigned int rx_intr;
unsigned int rx_poll;
unsigned int rx_bytes;
unsigned int tx_err;
unsigned int tx;
unsigned int tx_bytes;
/* Heuristics :
*
*/
unsigned int bdg_overflow;
unsigned int pll_empty;
unsigned int rx_intr;
unsigned int rx_poll;
} mmnif_device_stats_t;
typedef struct mm_rx_buffer
@ -123,6 +149,7 @@ typedef struct mm_rx_buffer
/* memory rx buffer build
* - queued : how many packets are in the queue
* - pos : which is the next packet to be worked on
* - pending : how many packets are pending
* - iv_intr : inform via interrupt or not
* - lock: semaphore to lock the local variables to be multi access save
*
@ -135,6 +162,7 @@ typedef struct mm_rx_buffer
*/
uint8_t queued;
uint8_t pos;
uint8_t pending;
uint8_t iv_intr;
@ -165,6 +193,9 @@ typedef struct mmnif
uint8_t tx_queue;
uint8_t* tx_buff[MMNIF_TX_QUEUELEN];
mm_rx_buffer_t* rx_buff;
/* config register banks */
void* crb[MMNIF_CORES];
/* comunication mailbox
*/
@ -243,14 +274,14 @@ __inline uint8_t mmnif_read_rx_pos(uint32_t dest_ip)
#endif
};
/* read the pos value from the remote buffer
/* read the inv_intr from the remote buffer
* and return it.
*/
__inline uint8_t mmnif_read_rx_inv_intr(uint32_t dest_ip)
{
#ifdef WIN32
/* Read the value of the forgein process
* form rx_buff->pos
* form rx_buff->inv_intr
*/
mm_rx_buffer_t hdr;
while(!ReadProcessMemory(hProc,(char*)mpb_start_address + ( dest_ip -1 ) * mpb_size,&hdr,sizeof(hdr),NULL));
@ -260,6 +291,23 @@ __inline uint8_t mmnif_read_rx_inv_intr(uint32_t dest_ip)
#endif
};
/* read the pending value from the remote buffer
* and return it.
*/
__inline uint8_t mmnif_read_rx_pending(uint32_t dest_ip)
{
#ifdef WIN32
/* Read the value of the forgein process
* form rx_buff->pending
*/
mm_rx_buffer_t hdr;
while(!ReadProcessMemory(hProc,(char*)mpb_start_address + ( dest_ip -1 ) * mpb_size,&hdr,sizeof(hdr),NULL));
return hdr.pending;
#else
return *(uint8_t*)(mpb_start_address + (dest_ip -1 ) * mpb_size +2);
#endif
};
/* write data to the remote buffer
*
*/
@ -318,6 +366,26 @@ __inline int mmnif_write_rx_queue(uint32_t dest_ip,uint8_t queue)
#endif
};
/* write the new queue value to the remote buffer
*
*/
__inline int mmnif_write_rx_pending(uint32_t dest_ip,uint8_t pending)
{
/* tell the remote buffer/process
* that there is another packet in the queue
*/
#ifdef WIN32
uint32_t nr_of_bytes_written = 0;
while(!WriteProcessMemory(hProc,(char*)mpb_start_address + ( dest_ip -1 ) * mpb_size + 2 ,&pending,1,&nr_of_bytes_written));
return nr_of_bytes_written;
#else
memcpy((char*)mpb_start_address + ( dest_ip -1 ) * mpb_size ,&queue,1);
return 1;
#endif
};
/* trigger an interrupt on the remote processor
*
*/
@ -329,7 +397,33 @@ __inline int mmnif_trigger_irq(dest_ip)
/* NOTE: have to check how the remote interrupt managment works
* on the SCC
*/
return NULL;
mmnif_t* mmnif = mmnif_dev->state;
int core = (dest_ip - 1) % 2;
int irq_address = mmnif->crb[dest_ip-1];
unsigned int value;
if (core == 0) irq_address += RCK_GLCFG0;
else irq_address += RCK_GLCFG1;
/**/
value = inportl((void*)irq_address);
if (!pulse_irq) && (value & RCK_INTR_MASK))
{
value &= (~(RCK_INTR_MASK|RCK_NMI_MASK));
outportl((void*)irq_address,value);
}
value |= RCK_INTR_MASK;
outportl((void*) irq_address,value);
/**/
if (pulse_irq)
{
value &= (~(RCK_INTR_MASK|NMI_MASK));
outportl((void*)irq_address,value);
}
#endif
};
@ -430,17 +524,15 @@ __inline int mmnif_timestamp()
}
/* mmnif_get_device_stats():
*
/* mmnif_get_device_stats(): Returns a copy of the
* current device
*/
mmnif_device_stats_t mmnif_get_device_stats()
{
mmnif_device_stats_t stats = {0};
if(!mmnif_dev)
{
DEBUGPRINTF("mmnif_get_device_stats(): the device is not initialized yet.");
}
else
stats = ((mmnif_t*)mmnif_dev->state)->stats;
@ -448,8 +540,8 @@ mmnif_device_stats_t mmnif_get_device_stats()
}
/* mmnif_print_stats():
*
/* mmnif_print_stats(): Print the devices stats of the
* current device
*/
void mmnif_print_stats()
{
@ -465,10 +557,12 @@ void mmnif_print_stats()
DEBUGPRINTF("/dev/mmnif - stats: \n");
DEBUGPRINTF("Received: %d packets successfull\n",mmnif->stats.rx);
DEBUGPRINTF("Received: %d bytes",mmnif->stats.rx_bytes);
DEBUGPRINTF("interrupts: %d\n",mmnif->stats.rx_intr);
DEBUGPRINTF("polling: %d\n",mmnif->stats.rx_poll);
DEBUGPRINTF("Received: %d packets containuing errors\n",mmnif->stats.rx_err);
DEBUGPRINTF("Transmitted: %d packests successfull",mmnif->stats.tx);
DEBUGPRINTF("Transmitted: %d bytes",mmnif->stats.tx_bytes);
DEBUGPRINTF("Transmitted: %d packests were dropped due to errors",mmnif->stats.tx_err);
}
@ -530,10 +624,11 @@ err_t mmnif_tx(struct netif* netif, struct pbuf* p)
{
mmnif_t* mmnif = netif->state;
uint8_t slot = mmnif->tx_queue;
uint32_t i;
struct pbuf* q; /* interator */
uint8_t queued;
uint8_t pos;
uint8_t pending;
uint32_t i;
struct pbuf* q; /* interator */
uint8_t build_buff = TRUE;
uint8_t dest_intr = FALSE;
uint32_t dest_ip = mmnif_get_destination(netif,p);
@ -593,26 +688,51 @@ err_t mmnif_tx(struct netif* netif, struct pbuf* p)
}
/* get the palce the router core is looking for the packet */
/* lock the dest_ip mm_rx_buffer_hdr */
mmnif_lock_rx_hdr(dest_ip);
/* read and edit needed values */
queued = mmnif_read_rx_queue(dest_ip);
pos = mmnif_read_rx_pos(dest_ip);
pending = mmnif_read_rx_pending(dest_ip);
pending++;
mmnif_write_rx_pending(dest_ip,pending);
/* and unlock the dest_ip mm_rx_buffer_hdr */
mmnif_unlock_rx_hdr(dest_ip);
pos = (pos + queued) % MMNIF_RX_QUEUELEN;
/* check if there is a space in the queue without overwriting another packet */
if ((queued + pending) > MMNIF_RX_QUEUELEN)
{
DEBUGPRINTF("mmnif_tx(): too many packet's at once for the remote queue\n");
goto drop_packet;
}
/* write buffer to buffer & increment the queued packet count */
pos = (pos + queued + pending -1) % MMNIF_RX_QUEUELEN;
/* write buffer to buffer & increment the queued packet count
* this can be safely done without locking because this place is
* reserved for us because it has the status "pending"
*/
if (build_buff)
mmnif_write_rx_buff(dest_ip, pos, mmnif->tx_buff[slot]);
else
mmnif_write_rx_buffl(dest_ip, pos, p->payload,p->tot_len);
queued++;
/* like above ensure we are the only ones editing the hdr */
mmnif_lock_rx_hdr(dest_ip);
queued = mmnif_read_rx_queue(dest_ip);
pending = mmnif_read_rx_pending(dest_ip);
queued++;
pending--;
dest_intr = mmnif_read_rx_inv_intr(dest_ip);
mmnif_write_rx_queue(dest_ip, queued);
mmnif_write_rx_pending(dest_ip, pending);
mmnif_unlock_rx_hdr(dest_ip);
@ -622,7 +742,7 @@ err_t mmnif_tx(struct netif* netif, struct pbuf* p)
#endif
/* if driver is not in polling mode inform core that a message has arrived */
if (!no_irq)
if (dest_intr)
mmnif_trigger_irq(dest_ip);
/* free the transmid queue*/
@ -637,6 +757,7 @@ err_t mmnif_tx(struct netif* netif, struct pbuf* p)
LINK_STATS_INC(link.xmit);
mmnif->stats.tx++;
mmnif->stats.tx_bytes += p->tot_len;
return ERR_OK;
@ -697,8 +818,21 @@ err_t mmnif_init(struct netif* netif)
}
memset(mmnif->rx_buff, 0, (sizeof(mm_rx_buffer_t) + MMNIF_RX_QUEUELEN* MMNIF_RX_BUFFERLEN)* (MMNIF_CORES-1));
/* init the lock for the hdr
*/
sem_init(&mmnif->rx_buff->lock,1);
/* inform via interrupt should be the dafault
*/
if (!no_irq)
mmnif->rx_buff->iv_intr = TRUE;
for (i = 0; i < MMNIF_CORES;i+=2)
{
mmnif->crb[i] = crb + RCK_TILE_SIZE*(i/2);
mmnif->crb[i+1] = crb + RCK_TILE_SIZE*(i/2);
}
/* Alloc and clear internal memory for tx_buff
*/
#ifdef WIN32
@ -851,6 +985,8 @@ static void mmnif_rx(struct netif* netif)
LINK_STATS_INC(link.xmit);
mmnif->stats.rx++;
mmnif->stats.rx_bytes += p->tot_len;
if (no_irq)
mmnif->stats.rx_poll++;
else
@ -877,7 +1013,22 @@ static int mmnif_wait(struct netif* netif, uint32_t poll, int budget)
struct pbuf* p = NULL;
int err = ERR_OK;
unsigned int npackets = 0;
unsigned int quota = budget > mmnif->rx_buff->queued ? mmnif->rx_buff->queued : budget;
unsigned int quota = 0;
if (budget > mmnif->rx_buff->queued)
{
quota = mmnif->rx_buff->queued;
}
else
{
quota = budget;
mmnif->stats.bdg_overflow++;
/* if (budget overflow too often)
* {
* enable polling and disable interrupts
* }
*/
}
/* process up to quota packets from the receive queue */
while (npackets <= quota)
@ -921,7 +1072,7 @@ static int mmnif_wait(struct netif* netif, uint32_t poll, int budget)
int mmnif_worker(void* e)
{
while (active)
mmnif_wait(mmnif_dev,0,5);
mmnif_wait(mmnif_dev,0,MMNIF_WORKER_BUDGET);
return NULL;
}
@ -946,11 +1097,18 @@ int mmnif_poll(void* e)
/*run while driver is up*/
while (active)
{
while (mmnif->rx_buff->queued)
while (!mmnif->rx_buff->queued)
{
tmp32 = mmnif_timestamp();
diff = diff - tmp32 > 0 ? diff - tmp32 : tmp32 - diff;
mmnif->stats.pll_empty++;
/* if (too many emtpy runs)
* {
* enable interrupts and suspend polling
* }
*/
}
mmnif->stats.pll_empty--;
// Sleep(10);
mmnif_rx(mmnif_dev);
}