Skip to content
Snippets Groups Projects
Commit f30add70 authored by Grzegorz Daniluk's avatar Grzegorz Daniluk
Browse files

dev/minic: bugfixes to prevent WRPC from hanging on ping flood

parent 8bca95be
No related merge requests found
...@@ -62,46 +62,53 @@ static inline uint32_t minic_readl(uint32_t reg) ...@@ -62,46 +62,53 @@ static inline uint32_t minic_readl(uint32_t reg)
return *(volatile uint32_t *)(BASE_MINIC + reg); return *(volatile uint32_t *)(BASE_MINIC + reg);
} }
/*
* uint32_t size - in bytes
*/
static uint8_t * minic_rx_memcpy( uint8_t *dst, uint8_t *src, uint32_t size) static uint8_t * minic_rx_memcpy( uint8_t *dst, uint8_t *src, uint32_t size)
{ {
uint32_t part; uint32_t part;
//if src is outside the circular buffer, bring it back to the beginning //if src is outside the circular buffer, bring it back to the beginning
src = (uint8_t *) ((uint32_t)minic.rx_base + ((uint32_t)src - (uint32_t)minic.rx_base) % minic.rx_size); src = (uint8_t *) ((uint32_t)minic.rx_base + ((uint32_t)src - (uint32_t)minic.rx_base) % (minic.rx_size<<2));
if((uint32_t)src + size <= (uint32_t)minic.rx_base + minic.rx_size) if((uint32_t)src + size <= (uint32_t)minic.rx_base + (minic.rx_size<<2))
return memcpy(dst, src, size); return memcpy(dst, src, size);
part = (uint32_t)minic.rx_base + minic.rx_size - (uint32_t)src; part = (uint32_t)minic.rx_base + (minic.rx_size<<2) - (uint32_t)src;
memcpy(dst, src, part); memcpy(dst, src, part);
memcpy((void*) (dst+part), (void*)minic.rx_base, size - part); memcpy((void*) (dst+part), (void*)minic.rx_base, size - part);
return dst; return dst;
} }
/*
* uint32_t size - in bytes
*/
static uint8_t *minic_rx_memset( uint8_t *mem, uint8_t c, uint32_t size) static uint8_t *minic_rx_memset( uint8_t *mem, uint8_t c, uint32_t size)
{ {
uint32_t part; uint32_t part;
uint8_t *src; uint32_t *src;
//if src is outside the circular buffer, bring it back to the beginning //if src is outside the circular buffer, bring it back to the beginning
src = (uint8_t *) ((uint32_t)minic.rx_base + ((uint32_t)mem - (uint32_t)minic.rx_base) % minic.rx_size); src = (uint32_t*)((uint32_t)minic.rx_base + ((uint32_t)mem - (uint32_t)minic.rx_base) % (minic.rx_size<<2));
if((uint32_t)src + size <= (uint32_t)minic.rx_base + minic.rx_size) if((uint32_t)src + size <= (uint32_t)minic.rx_base + (minic.rx_size<<2))
return memset(src, c, size); return memset((void*)src, c, size);
part = (uint32_t)minic.rx_base + minic.rx_size - (uint32_t)src; part = (uint32_t)minic.rx_base + (minic.rx_size<<2) - (uint32_t)src;
memset(src, c, part); memset(src, c, part);
memset((void*)minic.rx_base, c, size - part); memset((void*)minic.rx_base, c, size - part);
return src; return (uint8_t*)src;
} }
static void minic_new_rx_buffer() static void minic_new_rx_buffer()
{ {
minic_writel(MINIC_REG_MCR, 0); minic_writel(MINIC_REG_MCR, 0);
minic.rx_base = dma_rx_buf;
minic.rx_size = MINIC_DMA_RX_BUF_SIZE/4;
minic.rx_head = minic.rx_base; minic.rx_head = minic.rx_base;
minic_rx_memset((uint8_t*)minic.rx_base, 0x00, minic.rx_size); minic_rx_memset((uint8_t*)minic.rx_base, 0x00, minic.rx_size<<2);
memset((void*)minic.rx_base, 0x0, minic.rx_size);
minic_writel(MINIC_REG_RX_ADDR, (uint32_t) minic.rx_base); minic_writel(MINIC_REG_RX_ADDR, (uint32_t) minic.rx_base);
minic_writel(MINIC_REG_RX_SIZE, minic.rx_size>>2); minic_writel(MINIC_REG_RX_SIZE, minic.rx_size);
//new buffer allocated, clear any old RX interrupts //new buffer allocated, clear any old RX interrupts
minic_writel(MINIC_REG_EIC_ISR, MINIC_EIC_ISR_RX); minic_writel(MINIC_REG_EIC_ISR, MINIC_EIC_ISR_RX);
minic_writel(MINIC_REG_MCR, MINIC_MCR_RX_EN); minic_writel(MINIC_REG_MCR, MINIC_MCR_RX_EN);
...@@ -115,8 +122,11 @@ static void minic_rxbuf_free(uint32_t words) ...@@ -115,8 +122,11 @@ static void minic_rxbuf_free(uint32_t words)
static void minic_new_tx_buffer() static void minic_new_tx_buffer()
{ {
minic.tx_base = dma_tx_buf;
minic.tx_size = MINIC_DMA_TX_BUF_SIZE>>2;
minic.tx_head = minic.tx_base; minic.tx_head = minic.tx_base;
minic.tx_avail = minic.tx_size>>2; minic.tx_avail = minic.tx_size;
minic_writel(MINIC_REG_TX_ADDR, (uint32_t) minic.tx_base); minic_writel(MINIC_REG_TX_ADDR, (uint32_t) minic.tx_base);
} }
...@@ -140,7 +150,7 @@ void minic_init() ...@@ -140,7 +150,7 @@ void minic_init()
minic_writel(MINIC_REG_MPROT, MINIC_MPROT_LO_W(lo) | MINIC_MPROT_HI_W(hi)); minic_writel(MINIC_REG_MPROT, MINIC_MPROT_LO_W(lo) | MINIC_MPROT_HI_W(hi));
minic.tx_base = dma_tx_buf; minic.tx_base = dma_tx_buf;
minic.tx_size = sizeof(dma_tx_buf); minic.tx_size = MINIC_DMA_TX_BUF_SIZE>>2;
minic.tx_count = 0; minic.tx_count = 0;
minic.rx_count = 0; minic.rx_count = 0;
...@@ -174,14 +184,19 @@ int minic_rx_frame(uint8_t *hdr, uint8_t *payload, uint32_t buf_size, struct hw_ ...@@ -174,14 +184,19 @@ int minic_rx_frame(uint8_t *hdr, uint8_t *payload, uint32_t buf_size, struct hw_
if(! (minic_readl(MINIC_REG_EIC_ISR) & MINIC_EIC_ISR_RX)) if(! (minic_readl(MINIC_REG_EIC_ISR) & MINIC_EIC_ISR_RX))
return 0; return 0;
//TRACE_DEV("minic: got sthx \n");
desc_hdr = *minic.rx_head; desc_hdr = *minic.rx_head;
if(!RX_DESC_VALID(desc_hdr)) /* invalid descriptor? Weird, the RX_ADDR seems to be saying something different. Ignore the packet and purge the RX buffer. */ if(!RX_DESC_VALID(desc_hdr)) /* invalid descriptor? Weird, the RX_ADDR seems to be saying something different. Ignore the packet and purge the RX buffer. */
{ {
mprintf("invalid descriptor\n"); //invalid descriptor ? then probably the interrupt was generated by full rx buffer
minic_new_rx_buffer(); if(minic_readl(MINIC_REG_MCR) & MINIC_MCR_RX_FULL)
minic_new_rx_buffer();
else
{
//otherwise, weird !!
mprintf("invalid descriptor @%x = %x\n", (uint32_t)minic.rx_head, desc_hdr);
minic_new_rx_buffer();
}
return 0; return 0;
} }
payload_size = RX_DESC_SIZE(desc_hdr); payload_size = RX_DESC_SIZE(desc_hdr);
...@@ -195,7 +210,7 @@ int minic_rx_frame(uint8_t *hdr, uint8_t *payload, uint32_t buf_size, struct hw_ ...@@ -195,7 +210,7 @@ int minic_rx_frame(uint8_t *hdr, uint8_t *payload, uint32_t buf_size, struct hw_
if(RX_DESC_HAS_OOB(desc_hdr) && hwts != NULL) if(RX_DESC_HAS_OOB(desc_hdr) && hwts != NULL)
{ {
uint32_t counter_r, counter_f, counter_ppsg; uint32_t counter_r, counter_f, counter_ppsg;
uint64_t sec; uint64_t sec;
int cntr_diff; int cntr_diff;
uint16_t dhdr; uint16_t dhdr;
...@@ -228,17 +243,17 @@ int minic_rx_frame(uint8_t *hdr, uint8_t *payload, uint32_t buf_size, struct hw_ ...@@ -228,17 +243,17 @@ int minic_rx_frame(uint8_t *hdr, uint8_t *payload, uint32_t buf_size, struct hw_
minic_rx_memcpy(hdr, (void*)minic.rx_head + 4, ETH_HEADER_SIZE); minic_rx_memcpy(hdr, (void*)minic.rx_head + 4, ETH_HEADER_SIZE);
minic_rx_memcpy(payload, (void*)minic.rx_head + 4 + ETH_HEADER_SIZE, n_recvd - ETH_HEADER_SIZE); minic_rx_memcpy(payload, (void*)minic.rx_head + 4 + ETH_HEADER_SIZE, n_recvd - ETH_HEADER_SIZE);
}
} else { else {
n_recvd = -1; n_recvd = -1;
} }
minic_rxbuf_free(num_words); minic_rxbuf_free(num_words);
minic.rx_head = (uint32_t * ) ((uint32_t)minic.rx_base + ((uint32_t)minic.rx_head+(num_words<<2) - (uint32_t)minic.rx_base) % minic.rx_size); minic.rx_head = (uint32_t *)((uint32_t)minic.rx_base + ((uint32_t)minic.rx_head+(num_words<<2) - (uint32_t)minic.rx_base) % (minic.rx_size<<2));
cur_avail = minic_readl(MINIC_REG_RX_AVAIL); cur_avail = minic_readl(MINIC_REG_RX_AVAIL);
/*empty buffer->no more received packets, or packet reception in progress but not done*/ /*empty buffer->no more received packets, or packet reception in progress but not done*/
if( cur_avail == (minic.rx_size>>2) || !RX_DESC_VALID(*minic.rx_head)) if( !RX_DESC_VALID(*minic.rx_head))
{ {
if(minic_readl(MINIC_REG_MCR) & MINIC_MCR_RX_FULL) if(minic_readl(MINIC_REG_MCR) & MINIC_MCR_RX_FULL)
minic_new_rx_buffer(); minic_new_rx_buffer();
...@@ -258,8 +273,6 @@ int minic_tx_frame(uint8_t *hdr, uint8_t *payload, uint32_t size, struct hw_time ...@@ -258,8 +273,6 @@ int minic_tx_frame(uint8_t *hdr, uint8_t *payload, uint32_t size, struct hw_time
uint8_t ts_valid; uint8_t ts_valid;
minic_new_tx_buffer(); minic_new_tx_buffer();
// TRACE_DEV("minic_tx_frame: head %x size %d\n", minic.tx_head, size);
memset((void*)minic.tx_head, 0x0, size + 16); memset((void*)minic.tx_head, 0x0, size + 16);
memset((void*)minic.tx_head + 4, 0, size < 60 ? 60 : size); memset((void*)minic.tx_head + 4, 0, size < 60 ? 60 : size);
memcpy((void*)minic.tx_head + 4, hdr, ETH_HEADER_SIZE); memcpy((void*)minic.tx_head + 4, hdr, ETH_HEADER_SIZE);
......
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment