several changes, stats, optimizing copy process etc
This commit is contained in:
parent
8c6e679ba0
commit
243a2b4f92
1 changed files with 179 additions and 21 deletions
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue