diff --git a/drivers/net/rckemac.c b/drivers/net/rckemac.c index 24aa7d34..e095899c 100644 --- a/drivers/net/rckemac.c +++ b/drivers/net/rckemac.c @@ -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. diff --git a/drivers/net/rckemac.h b/drivers/net/rckemac.h index f6710594..38a55e51 100644 --- a/drivers/net/rckemac.h +++ b/drivers/net/rckemac.h @@ -24,6 +24,9 @@ #if defined(CONFIG_LWIP) && defined(CONFIG_ROCKCREEK) +#include +#include + /* * 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