aboutsummaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorIan Dowse <iedowse@FreeBSD.org>2002-11-07 16:04:07 +0000
committerIan Dowse <iedowse@FreeBSD.org>2002-11-07 16:04:07 +0000
commit947e38159738b8cdee93045ce310fdf261e7bba2 (patch)
tree28a2b5699d9effc331188af35ac235d9d5108d07 /sys
parentbec89d6c574667e1032b13ec9f03ddaa0cf00d05 (diff)
Notes
Diffstat (limited to 'sys')
-rw-r--r--sys/dev/fxp/if_fxp.c54
-rw-r--r--sys/dev/fxp/if_fxpvar.h1
2 files changed, 24 insertions, 31 deletions
diff --git a/sys/dev/fxp/if_fxp.c b/sys/dev/fxp/if_fxp.c
index 63b2b9ec9d7e0..9befadbf41bd9 100644
--- a/sys/dev/fxp/if_fxp.c
+++ b/sys/dev/fxp/if_fxp.c
@@ -1239,6 +1239,13 @@ fxp_intr_body(struct fxp_softc *sc, u_int8_t statack, int count)
if (rnr)
fxp_rnr++;
+#ifdef DEVICE_POLLING
+ /* Pick up a deferred RNR condition if `count' ran out last time. */
+ if (sc->flags & FXP_FLAG_DEFERRED_RNR) {
+ sc->flags &= ~FXP_FLAG_DEFERRED_RNR;
+ rnr = 1;
+ }
+#endif
/*
* Free any finished transmit mbuf chains.
@@ -1281,47 +1288,40 @@ fxp_intr_body(struct fxp_softc *sc, u_int8_t statack, int count)
/*
* Just return if nothing happened on the receive side.
*/
- if ( (statack & (FXP_SCB_STATACK_FR | FXP_SCB_STATACK_RNR)) == 0)
+ if (!rnr && (statack & FXP_SCB_STATACK_FR) == 0)
return;
/*
* Process receiver interrupts. If a no-resource (RNR)
* condition exists, get whatever packets we can and
* re-start the receiver.
- */
-
-#ifdef DEVICE_POLLING
- /*
+ *
* When using polling, we do not process the list to completion,
* so when we get an RNR interrupt we must defer the restart
* until we hit the last buffer with the C bit set.
* If we run out of cycles and rfa_headm has the C bit set,
- * record the pending RNR in an unused status bit, so that the
- * info will be used in the subsequent polling cycle.
- *
- * XXX there is absolutely no guarantee that this reserved bit
- * will be ignored by the hardware!
+ * record the pending RNR in the FXP_FLAG_DEFERRED_RNR flag so
+ * that the info will be used in the subsequent polling cycle.
*/
-#define FXP_RFA_RNRMARK 0x4000 /* used to mark a pending RNR intr */
-#endif
-
for (;;) {
m = sc->rfa_headm;
rfa = (struct fxp_rfa *)(m->m_ext.ext_buf +
RFA_ALIGNMENT_FUDGE);
#ifdef DEVICE_POLLING /* loop at most count times if count >=0 */
- if (count >= 0 && count-- == 0)
+ if (count >= 0 && count-- == 0) {
+ if (rnr) {
+ /* Defer RNR processing until the next time. */
+ sc->flags |= FXP_FLAG_DEFERRED_RNR;
+ rnr = 0;
+ }
break;
+ }
#endif /* DEVICE_POLLING */
if ( (rfa->rfa_status & FXP_RFA_STATUS_C) == 0)
break;
-#ifdef DEVICE_POLLING
- if (rfa->rfa_status & FXP_RFA_RNRMARK)
- rnr = 1;
-#endif
/*
* Remove first packet from the chain.
*/
@@ -1356,19 +1356,11 @@ fxp_intr_body(struct fxp_softc *sc, u_int8_t statack, int count)
}
}
if (rnr) {
-#ifdef DEVICE_POLLING
- if (rfa->rfa_status & FXP_RFA_STATUS_C)
- rfa->rfa_status |= FXP_RFA_RNRMARK;
- else {
-#endif
- fxp_scb_wait(sc);
- CSR_WRITE_4(sc, FXP_CSR_SCB_GENERAL,
- vtophys(sc->rfa_headm->m_ext.ext_buf) +
- RFA_ALIGNMENT_FUDGE);
- fxp_scb_cmd(sc, FXP_SCB_COMMAND_RU_START);
-#ifdef DEVICE_POLLING
- }
-#endif
+ fxp_scb_wait(sc);
+ CSR_WRITE_4(sc, FXP_CSR_SCB_GENERAL,
+ vtophys(sc->rfa_headm->m_ext.ext_buf) +
+ RFA_ALIGNMENT_FUDGE);
+ fxp_scb_cmd(sc, FXP_SCB_COMMAND_RU_START);
}
}
diff --git a/sys/dev/fxp/if_fxpvar.h b/sys/dev/fxp/if_fxpvar.h
index d18ca393b0e86..1042f1f2f0f36 100644
--- a/sys/dev/fxp/if_fxpvar.h
+++ b/sys/dev/fxp/if_fxpvar.h
@@ -157,6 +157,7 @@ struct fxp_softc {
#define FXP_FLAG_ALL_MCAST 0x0040 /* accept all multicast frames */
#define FXP_FLAG_CU_RESUME_BUG 0x0080 /* requires workaround for CU_RESUME */
#define FXP_FLAG_UCODE 0x0100 /* ucode is loaded */
+#define FXP_FLAG_DEFERRED_RNR 0x0200 /* DEVICE_POLLING deferred RNR */
/* Macros to ease CSR access. */
#define CSR_READ_1(sc, reg) \