redesign of eMAC interrupt handler

This commit is contained in:
Stefan Lankes 2011-10-08 23:09:51 -07:00
parent 1683610e53
commit f8413774da
2 changed files with 32 additions and 27 deletions

View file

@ -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.

View file

@ -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