From 6d8a787f6795a40cd4b285ee5fda78306d51b55d Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Tue, 29 May 2012 21:02:09 -0700 Subject: [PATCH] pxe: force polling on if we receive no interrupts Some PXE stacks will claim to support interrupts and don't. If 3 seconds after the first packet transmission we still have not received any interrupt at all, activate the polling thread. Signed-off-by: H. Peter Anvin --- core/lwip/src/netif/undiif.c | 16 ++++++++++++++++ core/pxeisr.inc | 13 ++++++++----- 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/core/lwip/src/netif/undiif.c b/core/lwip/src/netif/undiif.c index fbb0a853..b82b6f32 100644 --- a/core/lwip/src/netif/undiif.c +++ b/core/lwip/src/netif/undiif.c @@ -286,6 +286,9 @@ low_level_init(struct netif *netif) * to become availale since the stack doesn't retry to send a packet * dropped because of memory failure (except for the TCP timers). */ +extern volatile uint32_t pxe_irq_count; +extern volatile uint8_t pxe_need_poll; + static err_t undi_transmit(struct netif *netif, struct pbuf *pbuf, hwaddr_t *dest, uint16_t undi_protocol) @@ -297,11 +300,24 @@ undi_transmit(struct netif *netif, struct pbuf *pbuf, static __lowmem struct pxe_xmit pxe; static __lowmem hwaddr_t low_dest; static __lowmem char pkt_buf[PKTBUF_SIZE]; + uint32_t now; + static uint32_t first_xmit; /* Drop jumbo frames */ if ((pbuf->tot_len > sizeof(pkt_buf)) || (pbuf->tot_len > netif->mtu)) return ERR_ARG; + if (__unlikely(!pxe_irq_count)) { + now = ms_timer(); + if (!first_xmit) { + first_xmit = now; + } else if (now - first_xmit > 3000) { + /* 3 seconds after first transmit, and no interrupts */ + pxe_need_poll |= 1; + pxe_irq_count++; /* We don't need to do this again... */ + } + } + pbuf_copy_partial( pbuf, pkt_buf, pbuf->tot_len, 0); if (dest) memcpy(low_dest, dest, netif->hwaddr_len); diff --git a/core/pxeisr.inc b/core/pxeisr.inc index 5bcb9244..93c73ed5 100644 --- a/core/pxeisr.inc +++ b/core/pxeisr.inc @@ -39,6 +39,7 @@ pxe_isr: ; We need to EOI this ourselves, so that the ; leftover BC doesn't get control. mov byte [pxe_irq_pending],1 + inc dword [pxe_irq_count] cmp byte [pxe_irq_vector], 8 mov al,0x20 ; Non-specific EOI @@ -49,7 +50,7 @@ pxe_isr: out 0x20,al ; Primary PIC mov [pxeirq_last],ax - mov word [pxeirq_count],PXEIRQ_MAX + mov word [pxeirq_deadman],PXEIRQ_MAX .exit: pop gs @@ -62,7 +63,7 @@ pxe_isr: .notus: cmp ax,[pxeirq_last] jne .reset_timeout - dec word [pxeirq_count] + dec word [pxeirq_deadman] jz .timeout .chain: @@ -77,7 +78,7 @@ pxe_irq_chain equ $-4 .reset_timeout: mov [pxeirq_last],ax - mov word [pxeirq_count],PXEIRQ_MAX + mov word [pxeirq_deadman],PXEIRQ_MAX jmp .chain ; Too many spurious interrupts, shut off the interrupts @@ -154,10 +155,12 @@ pxenv_undi_isr_buf: .pkttype: resb 1 .size equ $-pxenv_undi_isr_buf - alignb 2 + alignb 4 pxeirq_last resw 1 -pxeirq_count resw 1 +pxeirq_deadman resw 1 + global pxe_irq_count +pxe_irq_count resd 1 ; PXE IRQ counter global pxe_irq_vector pxe_irq_vector resb 1 ; PXE IRQ vector global pxe_irq_pending -- 2.11.4.GIT