summaryrefslogtreecommitdiffstats
path: root/sys/dev/fxp
diff options
context:
space:
mode:
authormux <mux@FreeBSD.org>2003-04-06 23:09:57 +0000
committermux <mux@FreeBSD.org>2003-04-06 23:09:57 +0000
commitf11ab00778097668bfe1184c9f66e961a84e5df6 (patch)
tree628fd6c495198c8b34c9af68220993d8b3136694 /sys/dev/fxp
parent32862f82ea93f1c7f99b1d617f0fb03f5f9d93c1 (diff)
downloadFreeBSD-src-f11ab00778097668bfe1184c9f66e961a84e5df6.zip
FreeBSD-src-f11ab00778097668bfe1184c9f66e961a84e5df6.tar.gz
Because alpha can't access memory in 16-bit granularity,
we're using an atomic operation to clear the suspend flag in fxp_start(). Since other architectures may need the same thing, we want to do it all the time and not only in the __alpha__ case. However, we don't want to use atomic operations on 16-bit integers, because those may not be available on any architecture. We're thus faking a 32-bit atomic operation here. This patch also deals with endianness here.
Diffstat (limited to 'sys/dev/fxp')
-rw-r--r--sys/dev/fxp/if_fxp.c18
1 files changed, 11 insertions, 7 deletions
diff --git a/sys/dev/fxp/if_fxp.c b/sys/dev/fxp/if_fxp.c
index 5e035db..77204c3 100644
--- a/sys/dev/fxp/if_fxp.c
+++ b/sys/dev/fxp/if_fxp.c
@@ -57,6 +57,7 @@ __FBSDID("$FreeBSD$");
#include <net/ethernet.h>
#include <net/if_arp.h>
+#include <machine/atomic.h>
#include <machine/clock.h> /* for DELAY */
#include <net/if_types.h>
@@ -1207,7 +1208,7 @@ static void
fxp_start(struct ifnet *ifp)
{
struct fxp_softc *sc = ifp->if_softc;
- struct fxp_tx *txp;
+ struct fxp_tx *txp, *last;
struct mbuf *mb_head;
int error;
@@ -1377,18 +1378,21 @@ fxp_start(struct ifnet *ifp)
* Advance the end of list forward.
*/
-#ifdef __alpha__
/*
* On platforms which can't access memory in 16-bit
* granularities, we must prevent the card from DMA'ing
* up the status while we update the command field.
* This could cause us to overwrite the completion status.
+ *
+ * This is a bit tricky, because we want to avoid using
+ * atomic operations on 16bits values, since they may not
+ * be available on any architecture or may be very
+ * inefficient.
*/
- atomic_clear_short(&sc->fxp_desc.tx_last->tx_cb->cb_command,
- FXP_CB_COMMAND_S);
-#else
- sc->fxp_desc.tx_last->tx_cb->cb_command &= ~FXP_CB_COMMAND_S;
-#endif /*__alpha__*/
+ last = sc->fxp_desc.tx_last;
+ atomic_clear_32((u_int32_t *)&last->tx_cb->cb_status,
+ htobe32(bswap16(FXP_CB_COMMAND_S)));
+
sc->fxp_desc.tx_last = txp;
/*
OpenPOWER on IntegriCloud