[syslinux:lwip] pxe: force polling on if we receive no interrupts

syslinux-bot for H. Peter Anvin hpa at zytor.com
Tue May 29 21:06:02 PDT 2012


Commit-ID:  6d8a787f6795a40cd4b285ee5fda78306d51b55d
Gitweb:     http://www.syslinux.org/commit/6d8a787f6795a40cd4b285ee5fda78306d51b55d
Author:     H. Peter Anvin <hpa at zytor.com>
AuthorDate: Tue, 29 May 2012 21:02:09 -0700
Committer:  H. Peter Anvin <hpa at zytor.com>
CommitDate: Tue, 29 May 2012 21:02:09 -0700

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 at zytor.com>

---
 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 fbb0a85..b82b6f3 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 5bcb924..93c73ed 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


More information about the Syslinux-commits mailing list