redesign of eMAC interrupt handler
This commit is contained in:
parent
1683610e53
commit
f8413774da
2 changed files with 32 additions and 27 deletions
|
@ -92,15 +92,24 @@
|
|||
#define EMAC_TX_MODE 0x0400
|
||||
#define EMAC_TX_NETWORK_PORT_ENABLE 0x0500
|
||||
|
||||
#if 1
|
||||
// Using of LVT0 as interrupt line
|
||||
#define EMAC_IRQ_MASK 0x00000002
|
||||
#define EMAC_IRQ_NR 4
|
||||
#define EMAC_LVT APIC_LVT0
|
||||
#define EMAC_IRQ_CONFIG 0
|
||||
#else
|
||||
// Using of LVT1 as interrupt line
|
||||
#define EMAC_IRQ_MASK 0x00000001
|
||||
#define EMAC_IRQ_NR 3
|
||||
#define EMAC_LVT APIC_LVT1
|
||||
#define EMAC_IRQ_CONFIG 1
|
||||
#endif
|
||||
|
||||
#define IRQ_STATUS 0xD000
|
||||
#define IRQ_MASK 0xD200
|
||||
#define IRQ_RESET 0xD400
|
||||
#define IRQ_REQUEST 0xD600
|
||||
#define IRQ_CONFIG 0xD800
|
||||
|
||||
/* Cache line wrappers */
|
||||
|
@ -514,8 +523,10 @@ rxDone:
|
|||
goto again;
|
||||
|
||||
/* Enable eMAC interrupt */
|
||||
int tmp = *((volatile int*) (FPGA_BASE + IRQ_MASK + rckemacif->core * 2 * 4));
|
||||
*((volatile int*) (FPGA_BASE + IRQ_MASK + rckemacif->core * 2 * 4)) = tmp & ~(1 << rckemacif->num_emac);
|
||||
unsigned int tmp = *((volatile unsigned int*) (FPGA_BASE + IRQ_MASK + rckemacif->core * 2 * 4));
|
||||
// read twice to be sure
|
||||
tmp = *((volatile unsigned int*) (FPGA_BASE + IRQ_MASK + rckemacif->core * 2 * 4));
|
||||
*((volatile unsigned int*) (FPGA_BASE + IRQ_MASK + rckemacif->core * 2 * 4)) = tmp & ~(1 << rckemacif->num_emac);
|
||||
rckemacif->polling = 0;
|
||||
}
|
||||
|
||||
|
@ -527,41 +538,29 @@ static void rckemacif_poll(void* ctx)
|
|||
rckemacif_rx_handler(mynetif, write_offset);
|
||||
}
|
||||
|
||||
static void rckemacif_handler(struct state* s)
|
||||
void rckemacif_handler(struct state* s, uint32_t status)
|
||||
{
|
||||
unsigned int status, tmp;
|
||||
unsigned int write_offset;
|
||||
rckemacif_t* rckemacif = mynetif->state;
|
||||
|
||||
status = *((volatile int*) (FPGA_BASE + IRQ_STATUS + rckemacif->core * 2 * 4));
|
||||
// read twice to be sure
|
||||
status = *((volatile int*) (FPGA_BASE + IRQ_STATUS + rckemacif->core * 2 * 4));
|
||||
if (!(status & (1 << rckemacif->num_emac))) {
|
||||
LWIP_DEBUGF(NETIF_DEBUG, ("rckemacif_handler: no interrupt\n"));
|
||||
if (!(status & (1 << rckemacif->num_emac)))
|
||||
return;
|
||||
}
|
||||
|
||||
/* check for updated write offset */
|
||||
write_offset = *((volatile unsigned int*) (rckemacif->rx_buffer)) & 0xFFFF;
|
||||
//write_offset = read_emac(rckemacif->num_emac, EMAC_RX_CONTROL + EMAC_RX_BUFFER_WRITE_OFFSET, rckemacif->core);
|
||||
if ((write_offset != 0) && (rckemacif->rx_read_offset != write_offset) && !rckemacif->polling) {
|
||||
if (tcpip_callback_with_block(rckemacif_poll, (void*) write_offset, 0) == ERR_OK) {
|
||||
/* Maks eMAC interrupt */
|
||||
int tmp = *((volatile int*) (FPGA_BASE + IRQ_MASK + rckemacif->core * 2 * 4));
|
||||
*((volatile int*) (FPGA_BASE + IRQ_MASK + rckemacif->core * 2 * 4)) = tmp | (1 << rckemacif->num_emac);
|
||||
/* Mask eMAC interrupt */
|
||||
unsigned int tmp = *((volatile unsigned int*) (FPGA_BASE + IRQ_MASK + rckemacif->core * 2 * 4));
|
||||
// read twice to be sure
|
||||
tmp = *((volatile unsigned int*) (FPGA_BASE + IRQ_MASK + rckemacif->core * 2 * 4));
|
||||
*((volatile unsigned int*) (FPGA_BASE + IRQ_MASK + rckemacif->core * 2 * 4)) = tmp | (1 << rckemacif->num_emac);
|
||||
rckemacif->polling = 1;
|
||||
} else {
|
||||
LWIP_DEBUGF(NETIF_DEBUG, ("rckemacif_handler: unable to send a poll request to the tcpip thread\n"));
|
||||
}
|
||||
}
|
||||
|
||||
/* Set interrupt bit */
|
||||
tmp = *((volatile unsigned int*) rckemacif->irq_address);
|
||||
tmp &= ~(EMAC_IRQ_MASK);
|
||||
*((volatile unsigned int*) rckemacif->irq_address) = tmp;
|
||||
|
||||
/* Reset */
|
||||
*((volatile unsigned*) (FPGA_BASE + IRQ_RESET + rckemacif->core * 2 * 4)) = (1 << rckemacif->num_emac);
|
||||
}
|
||||
|
||||
err_t rckemacif_init(struct netif* netif)
|
||||
|
@ -843,13 +842,11 @@ err_t rckemacif_init(struct netif* netif)
|
|||
write_emac(num_emac, EMAC_TX_CONTROL + EMAC_TX_NETWORK_PORT_ENABLE, core, 0x01);
|
||||
LWIP_DEBUGF(NETIF_DEBUG, (" TX Port enable set to %x\n", read_emac(num_emac, EMAC_TX_CONTROL + EMAC_TX_NETWORK_PORT_ENABLE, core)));
|
||||
|
||||
// set interrupt handler (INTR/LINT0)
|
||||
irq_install_handler(125, rckemacif_handler);
|
||||
|
||||
/* Enable interrupt */
|
||||
tmp = *((volatile int*) (FPGA_BASE + IRQ_MASK + core * 2 * 4));
|
||||
*((volatile int*) (FPGA_BASE + IRQ_MASK + core * 2 * 4)) = tmp & ~(1 << num_emac);
|
||||
*((volatile int*) (FPGA_BASE + IRQ_CONFIG + core * 4)) = EMAC_IRQ_CONFIG;
|
||||
*((volatile unsigned int*) (FPGA_BASE + IRQ_MASK + core * 2 * 4)) &= ~(1 << num_emac);
|
||||
*((volatile unsigned int*) (FPGA_BASE + IRQ_CONFIG + core * 4)) = EMAC_IRQ_CONFIG;
|
||||
LWIP_DEBUGF(NETIF_DEBUG, (" IRQ_MASK set to 0x%x\n", *((volatile unsigned int*) (FPGA_BASE + IRQ_MASK + core * 2 * 4))));
|
||||
LWIP_DEBUGF(NETIF_DEBUG, (" IRQ_CONFIG set to 0x%x\n", *((volatile unsigned int*) (FPGA_BASE + IRQ_CONFIG + core * 2 * 4))));
|
||||
|
||||
/*
|
||||
* Initialize the snmp variables and counters inside the struct netif.
|
||||
|
|
|
@ -24,6 +24,9 @@
|
|||
|
||||
#if defined(CONFIG_LWIP) && defined(CONFIG_ROCKCREEK)
|
||||
|
||||
#include <lwip/err.h>
|
||||
#include <lwip/netif.h>
|
||||
|
||||
/*
|
||||
* Helper struct to hold private data used to operate your ethernet interface.
|
||||
*/
|
||||
|
@ -47,6 +50,11 @@ typedef struct rckemacif {
|
|||
*/
|
||||
err_t rckemacif_init(struct netif* netif);
|
||||
|
||||
/*
|
||||
* global interrupt handler uses this helper handler
|
||||
*/
|
||||
void rckemacif_handler(struct state* s, uint32_t status);
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Add table
Reference in a new issue