diff options
author | H. Peter Anvin <hpa@zytor.com> | 2012-05-29 21:02:09 -0700 |
---|---|---|
committer | H. Peter Anvin <hpa@zytor.com> | 2012-05-29 21:02:09 -0700 |
commit | 6d8a787f6795a40cd4b285ee5fda78306d51b55d (patch) | |
tree | 28c043613cd476a67fda92e2de722e3b191edfa1 | |
parent | 7699e996c613e51049e0bad6ade32215ac263289 (diff) | |
download | syslinux-6d8a787f6795a40cd4b285ee5fda78306d51b55d.tar.gz syslinux-6d8a787f6795a40cd4b285ee5fda78306d51b55d.tar.xz syslinux-6d8a787f6795a40cd4b285ee5fda78306d51b55d.zip |
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 <hpa@zytor.com>
-rw-r--r-- | core/lwip/src/netif/undiif.c | 16 | ||||
-rw-r--r-- | 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 |