summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorimp <imp@FreeBSD.org>2003-10-25 04:09:49 +0000
committerimp <imp@FreeBSD.org>2003-10-25 04:09:49 +0000
commitcdc83babef20f1fd97d3bbab52fb817c3f07a8bf (patch)
tree306fb7c20a7cc6e221f64a629bd2a576a92cad01 /sys
parent7359197bf845da073539c45aeeef9002129cd1bb (diff)
downloadFreeBSD-src-cdc83babef20f1fd97d3bbab52fb817c3f07a8bf.zip
FreeBSD-src-cdc83babef20f1fd97d3bbab52fb817c3f07a8bf.tar.gz
Whole grab-bag of changes:
o Make the driver MPSAFE o Some changes due to diff reduction effort with vx. o Removed some obsolete junk. Reviewed by: sam, modd
Diffstat (limited to 'sys')
-rw-r--r--sys/dev/ep/if_ep.c298
-rw-r--r--sys/dev/ep/if_ep_eisa.c2
-rw-r--r--sys/dev/ep/if_ep_isa.c2
-rw-r--r--sys/dev/ep/if_ep_mca.c2
-rw-r--r--sys/dev/ep/if_ep_pccard.c20
-rw-r--r--sys/dev/ep/if_epreg.h76
-rw-r--r--sys/dev/ep/if_epvar.h24
7 files changed, 216 insertions, 208 deletions
diff --git a/sys/dev/ep/if_ep.c b/sys/dev/ep/if_ep.c
index 3b591d3..e1132b2 100644
--- a/sys/dev/ep/if_ep.c
+++ b/sys/dev/ep/if_ep.c
@@ -90,10 +90,13 @@ static int ep_media2if_media[] =
{IFM_10_T, IFM_10_5, IFM_NONE, IFM_10_2, IFM_NONE};
/* if functions */
-static void ep_if_init(void *);
-static int ep_if_ioctl(struct ifnet *, u_long, caddr_t);
-static void ep_if_start(struct ifnet *);
-static void ep_if_watchdog(struct ifnet *);
+static void epinit(void *);
+static int epioctl(struct ifnet *, u_long, caddr_t);
+static void epstart(struct ifnet *);
+static void epwatchdog(struct ifnet *);
+
+static void epstart_body(struct ifnet *);
+static void epinit_body(struct ep_softc *);
/* if_media functions */
static int ep_ifmedia_upd(struct ifnet *);
@@ -134,13 +137,13 @@ get_e(struct ep_softc *sc, u_int16_t offset, u_int16_t *result)
if (eeprom_rdy(sc))
return (ENXIO);
- EP_WRITE_2(sc, EP_W0_EEPROM_COMMAND,
+ CSR_WRITE_2(sc, EP_W0_EEPROM_COMMAND,
(EEPROM_CMD_RD << sc->epb.cmd_off) | offset);
if (eeprom_rdy(sc))
return (ENXIO);
- (*result) = EP_READ_2(sc, EP_W0_EEPROM_DATA);
+ (*result) = CSR_READ_2(sc, EP_W0_EEPROM_DATA);
return (0);
}
@@ -223,7 +226,7 @@ ep_get_media(struct ep_softc *sc)
u_int16_t config;
GO_WINDOW(0);
- config = EP_READ_2(sc, EP_W0_CONFIG_CTRL);
+ config = CSR_READ_2(sc, EP_W0_CONFIG_CTRL);
if (config & IS_AUI)
sc->ep_connectors |= AUI;
if (config & IS_BNC)
@@ -240,7 +243,7 @@ ep_get_media(struct ep_softc *sc)
* The cards that require something different can override
* this later on.
*/
- sc->ep_connector = EP_READ_2(sc, EP_W0_ADDRESS_CFG) >> ACF_CONNECTOR_BITS;
+ sc->ep_connector = CSR_READ_2(sc, EP_W0_ADDRESS_CFG) >> ACF_CONNECTOR_BITS;
}
void
@@ -267,10 +270,12 @@ ep_attach(struct ep_softc *sc)
int error;
sc->gone = 0;
-
+ mtx_init(&sc->sc_mtx, device_get_nameunit(sc->dev), MTX_NETWORK_LOCK,
+ MTX_DEF);
error = ep_get_macaddr(sc, (u_char *)&sc->arpcom.ac_enaddr);
if (error) {
device_printf(sc->dev, "Unable to get Ethernet address!\n");
+ mtx_destroy(&sc->sc_mtx);
return (ENXIO);
}
/*
@@ -279,7 +284,7 @@ ep_attach(struct ep_softc *sc)
p = (u_short *)&sc->arpcom.ac_enaddr;
GO_WINDOW(2);
for (i = 0; i < 3; i++)
- EP_WRITE_2(sc, EP_W2_ADDR_0 + (i * 2), ntohs(p[i]));
+ CSR_WRITE_2(sc, EP_W2_ADDR_0 + (i * 2), ntohs(p[i]));
device_printf(sc->dev, "Ethernet address %6D\n",
sc->arpcom.ac_enaddr, ":");
@@ -293,10 +298,10 @@ ep_attach(struct ep_softc *sc)
ifp->if_mtu = ETHERMTU;
ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
ifp->if_output = ether_output;
- ifp->if_start = ep_if_start;
- ifp->if_ioctl = ep_if_ioctl;
- ifp->if_watchdog = ep_if_watchdog;
- ifp->if_init = ep_if_init;
+ ifp->if_start = epstart;
+ ifp->if_ioctl = epioctl;
+ ifp->if_watchdog = epwatchdog;
+ ifp->if_init = epinit;
ifp->if_snd.ifq_maxlen = IFQ_MAXLEN;
if (!sc->epb.mii_trans) {
@@ -358,73 +363,81 @@ ep_detach(device_t dev)
sc->gone = 1;
ep_free(dev);
+ mtx_destroy(&sc->sc_mtx);
return (0);
}
+static void
+epinit(void *xsc)
+{
+ struct ep_softc *sc = xsc;
+ EP_LOCK(sc);
+ epinit_body(sc);
+ EP_UNLOCK(sc);
+}
+
/*
* The order in here seems important. Otherwise we may not receive
* interrupts. ?!
*/
static void
-ep_if_init(void *xsc)
+epinit_body(struct ep_softc *sc)
{
- struct ep_softc *sc = xsc;
struct ifnet *ifp = &sc->arpcom.ac_if;
- int s, i;
+ int i;
if (sc->gone)
return;
- s = splimp();
- while (EP_READ_2(sc, EP_STATUS) & S_COMMAND_IN_PROGRESS);
+ EP_BUSY_WAIT;
GO_WINDOW(0);
- EP_WRITE_2(sc, EP_COMMAND, STOP_TRANSCEIVER);
+ CSR_WRITE_2(sc, EP_COMMAND, STOP_TRANSCEIVER);
GO_WINDOW(4);
- EP_WRITE_2(sc, EP_W4_MEDIA_TYPE, DISABLE_UTP);
+ CSR_WRITE_2(sc, EP_W4_MEDIA_TYPE, DISABLE_UTP);
GO_WINDOW(0);
/* Disable the card */
- EP_WRITE_2(sc, EP_W0_CONFIG_CTRL, 0);
+ CSR_WRITE_2(sc, EP_W0_CONFIG_CTRL, 0);
/* Enable the card */
- EP_WRITE_2(sc, EP_W0_CONFIG_CTRL, ENABLE_DRQ_IRQ);
+ CSR_WRITE_2(sc, EP_W0_CONFIG_CTRL, ENABLE_DRQ_IRQ);
GO_WINDOW(2);
/* Reload the ether_addr. */
for (i = 0; i < 6; i++)
- EP_WRITE_1(sc, EP_W2_ADDR_0 + i, sc->arpcom.ac_enaddr[i]);
+ CSR_WRITE_1(sc, EP_W2_ADDR_0 + i, sc->arpcom.ac_enaddr[i]);
- EP_WRITE_2(sc, EP_COMMAND, RX_RESET);
- EP_WRITE_2(sc, EP_COMMAND, TX_RESET);
- while (EP_READ_2(sc, EP_STATUS) & S_COMMAND_IN_PROGRESS);
+ CSR_WRITE_2(sc, EP_COMMAND, RX_RESET);
+ CSR_WRITE_2(sc, EP_COMMAND, TX_RESET);
+ EP_BUSY_WAIT;
/* Window 1 is operating window */
GO_WINDOW(1);
for (i = 0; i < 31; i++)
- EP_READ_1(sc, EP_W1_TX_STATUS);
+ CSR_READ_1(sc, EP_W1_TX_STATUS);
/* get rid of stray intr's */
- EP_WRITE_2(sc, EP_COMMAND, ACK_INTR | 0xff);
+ CSR_WRITE_2(sc, EP_COMMAND, ACK_INTR | 0xff);
- EP_WRITE_2(sc, EP_COMMAND, SET_RD_0_MASK | S_5_INTS);
+ CSR_WRITE_2(sc, EP_COMMAND, SET_RD_0_MASK | S_5_INTS);
- EP_WRITE_2(sc, EP_COMMAND, SET_INTR_MASK | S_5_INTS);
+ CSR_WRITE_2(sc, EP_COMMAND, SET_INTR_MASK | S_5_INTS);
if (ifp->if_flags & IFF_PROMISC)
- EP_WRITE_2(sc, EP_COMMAND, SET_RX_FILTER | FIL_INDIVIDUAL |
- FIL_GROUP | FIL_BRDCST | FIL_ALL);
+ CSR_WRITE_2(sc, EP_COMMAND, SET_RX_FILTER | FIL_INDIVIDUAL |
+ FIL_MULTICAST | FIL_BRDCST | FIL_PROMISC);
else
- EP_WRITE_2(sc, EP_COMMAND, SET_RX_FILTER | FIL_INDIVIDUAL |
- FIL_GROUP | FIL_BRDCST);
+ CSR_WRITE_2(sc, EP_COMMAND, SET_RX_FILTER | FIL_INDIVIDUAL |
+ FIL_MULTICAST | FIL_BRDCST);
if (!sc->epb.mii_trans)
ep_ifmedia_upd(ifp);
- EP_WRITE_2(sc, EP_COMMAND, RX_ENABLE);
- EP_WRITE_2(sc, EP_COMMAND, TX_ENABLE);
+ CSR_WRITE_2(sc, EP_COMMAND, RX_ENABLE);
+ CSR_WRITE_2(sc, EP_COMMAND, TX_ENABLE);
ifp->if_flags |= IFF_RUNNING;
ifp->if_flags &= ~IFF_OACTIVE; /* just in case */
@@ -438,8 +451,8 @@ ep_if_init(void *xsc)
m_freem(sc->top);
sc->top = sc->mcur = 0;
}
- EP_WRITE_2(sc, EP_COMMAND, SET_RX_EARLY_THRESH | RX_INIT_EARLY_THRESH);
- EP_WRITE_2(sc, EP_COMMAND, SET_TX_START_THRESH | 16);
+ CSR_WRITE_2(sc, EP_COMMAND, SET_RX_EARLY_THRESH | RX_INIT_EARLY_THRESH);
+ CSR_WRITE_2(sc, EP_COMMAND, SET_TX_START_THRESH | 16);
/*
* Store up a bunch of mbuf's for use later. (MAX_MBS).
@@ -448,27 +461,34 @@ ep_if_init(void *xsc)
*/
GO_WINDOW(1);
- ep_if_start(ifp);
-
- splx(s);
+ epstart_body(ifp);
}
static void
-ep_if_start(struct ifnet *ifp)
+epstart(struct ifnet *ifp)
+{
+ struct ep_softc *sc;
+ sc = ifp->if_softc;
+ EP_LOCK(sc);
+ epstart_body(ifp);
+ EP_UNLOCK(sc);
+}
+
+static void
+epstart_body(struct ifnet *ifp)
{
struct ep_softc *sc;
u_int len;
struct mbuf *m, *m0;
- int s, pad;
+ int pad;
sc = ifp->if_softc;
if (sc->gone)
return;
- while (EP_READ_2(sc, EP_STATUS) & S_COMMAND_IN_PROGRESS);
+ EP_BUSY_WAIT;
if (ifp->if_flags & IFF_OACTIVE)
return;
-
startagain:
/* Sneak a peek at the next packet */
IF_DEQUEUE(&ifp->if_snd, m0);
@@ -490,50 +510,50 @@ startagain:
m_freem(m0);
goto readcheck;
}
- if (EP_READ_2(sc, EP_W1_FREE_TX) < len + pad + 4) {
+ if (CSR_READ_2(sc, EP_W1_FREE_TX) < len + pad + 4) {
/* no room in FIFO */
- EP_WRITE_2(sc, EP_COMMAND, SET_TX_AVAIL_THRESH | (len + pad + 4));
+ CSR_WRITE_2(sc, EP_COMMAND, SET_TX_AVAIL_THRESH | (len + pad + 4));
/* make sure */
- if (EP_READ_2(sc, EP_W1_FREE_TX) < len + pad + 4) {
+ if (CSR_READ_2(sc, EP_W1_FREE_TX) < len + pad + 4) {
ifp->if_flags |= IFF_OACTIVE;
IF_PREPEND(&ifp->if_snd, m0);
- return;
+ goto done;
}
} else
- EP_WRITE_2(sc, EP_COMMAND,
+ CSR_WRITE_2(sc, EP_COMMAND,
SET_TX_AVAIL_THRESH | EP_THRESH_DISABLE);
- s = splhigh();
+ /* XXX 4.x and earlier would splhigh here */
- EP_WRITE_2(sc, EP_W1_TX_PIO_WR_1, len);
+ CSR_WRITE_2(sc, EP_W1_TX_PIO_WR_1, len);
/* Second dword meaningless */
- EP_WRITE_2(sc, EP_W1_TX_PIO_WR_1, 0x0);
+ CSR_WRITE_2(sc, EP_W1_TX_PIO_WR_1, 0x0);
if (EP_FTST(sc, F_ACCESS_32_BITS)) {
for (m = m0; m != NULL; m = m->m_next) {
if (m->m_len > 3)
- EP_WRITE_MULTI_4(sc, EP_W1_TX_PIO_WR_1,
+ CSR_WRITE_MULTI_4(sc, EP_W1_TX_PIO_WR_1,
mtod(m, uint32_t *), m->m_len / 4);
if (m->m_len & 3)
- EP_WRITE_MULTI_1(sc, EP_W1_TX_PIO_WR_1,
+ CSR_WRITE_MULTI_1(sc, EP_W1_TX_PIO_WR_1,
mtod(m, uint8_t *)+(m->m_len & (~3)),
m->m_len & 3);
}
} else {
for (m = m0; m != NULL; m = m->m_next) {
if (m->m_len > 1)
- EP_WRITE_MULTI_2(sc, EP_W1_TX_PIO_WR_1,
+ CSR_WRITE_MULTI_2(sc, EP_W1_TX_PIO_WR_1,
mtod(m, uint16_t *), m->m_len / 2);
if (m->m_len & 1)
- EP_WRITE_1(sc, EP_W1_TX_PIO_WR_1,
+ CSR_WRITE_1(sc, EP_W1_TX_PIO_WR_1,
*(mtod(m, uint8_t *)+m->m_len - 1));
}
}
while (pad--)
- EP_WRITE_1(sc, EP_W1_TX_PIO_WR_1, 0); /* Padding */
+ CSR_WRITE_1(sc, EP_W1_TX_PIO_WR_1, 0); /* Padding */
- splx(s);
+ /* XXX and drop splhigh here */
BPF_MTAP(ifp, m0);
@@ -546,16 +566,18 @@ startagain:
* the tiny RX fifo.
*/
readcheck:
- if (EP_READ_2(sc, EP_W1_RX_STATUS) & RX_BYTES_MASK) {
+ if (CSR_READ_2(sc, EP_W1_RX_STATUS) & RX_BYTES_MASK) {
/*
* we check if we have packets left, in that case
* we prepare to come back later
*/
if (ifp->if_snd.ifq_head)
- EP_WRITE_2(sc, EP_COMMAND, SET_TX_AVAIL_THRESH | 8);
- return;
+ CSR_WRITE_2(sc, EP_COMMAND, SET_TX_AVAIL_THRESH | 8);
+ goto done;
}
goto startagain;
+done:;
+ return;
}
void
@@ -564,29 +586,28 @@ ep_intr(void *arg)
struct ep_softc *sc;
int status;
struct ifnet *ifp;
- int x;
-
- x = splbio();
sc = (struct ep_softc *) arg;
+ EP_LOCK(sc);
+ /* XXX 4.x splbio'd here to reduce interruptability */
/*
* quick fix: Try to detect an interrupt when the card goes away.
*/
- if (sc->gone || EP_READ_2(sc, EP_STATUS) == 0xffff) {
- splx(x);
+ if (sc->gone || CSR_READ_2(sc, EP_STATUS) == 0xffff) {
+ EP_UNLOCK(sc);
return;
}
ifp = &sc->arpcom.ac_if;
- EP_WRITE_2(sc, EP_COMMAND, SET_INTR_MASK); /* disable all Ints */
+ CSR_WRITE_2(sc, EP_COMMAND, SET_INTR_MASK); /* disable all Ints */
rescan:
- while ((status = EP_READ_2(sc, EP_STATUS)) & S_5_INTS) {
+ while ((status = CSR_READ_2(sc, EP_STATUS)) & S_5_INTS) {
/* first acknowledge all interrupt sources */
- EP_WRITE_2(sc, EP_COMMAND, ACK_INTR | (status & S_MASK));
+ CSR_WRITE_2(sc, EP_COMMAND, ACK_INTR | (status & S_MASK));
if (status & (S_RX_COMPLETE | S_RX_EARLY))
epread(sc);
@@ -595,8 +616,8 @@ rescan:
ifp->if_timer = 0;
ifp->if_flags &= ~IFF_OACTIVE;
GO_WINDOW(1);
- EP_READ_2(sc, EP_W1_FREE_TX);
- ep_if_start(ifp);
+ CSR_READ_2(sc, EP_W1_FREE_TX);
+ epstart_body(ifp);
}
if (status & S_CARD_FAILURE) {
ifp->if_timer = 0;
@@ -604,7 +625,7 @@ rescan:
printf("\nep%d:\n\tStatus: %x\n", sc->unit, status);
GO_WINDOW(4);
printf("\tFIFO Diagnostic: %x\n",
- EP_READ_2(sc, EP_W4_FIFO_DIAG));
+ CSR_READ_2(sc, EP_W4_FIFO_DIAG));
printf("\tStat: %x\n", sc->stat);
printf("\tIpackets=%d, Opackets=%d\n",
ifp->if_ipackets, ifp->if_opackets);
@@ -621,8 +642,8 @@ rescan:
#endif
#endif
- ep_if_init(sc);
- splx(x);
+ epinit_body(sc);
+ EP_UNLOCK(sc);
return;
}
if (status & S_TX_COMPLETE) {
@@ -633,13 +654,13 @@ rescan:
* We need to read TX_STATUS until we get a
* 0 status in order to turn off the interrupt flag.
*/
- while ((status = EP_READ_1(sc, EP_W1_TX_STATUS)) &
+ while ((status = CSR_READ_1(sc, EP_W1_TX_STATUS)) &
TXS_COMPLETE) {
if (status & TXS_SUCCES_INTR_REQ);
else if (status &
(TXS_UNDERRUN | TXS_JABBER |
TXS_MAX_COLLISION)) {
- EP_WRITE_2(sc, EP_COMMAND, TX_RESET);
+ CSR_WRITE_2(sc, EP_COMMAND, TX_RESET);
if (status & TXS_UNDERRUN) {
#ifdef EP_LOCAL_STATS
sc->tx_underrun++;
@@ -654,34 +675,33 @@ rescan:
*/
}
++ifp->if_oerrors;
- EP_WRITE_2(sc, EP_COMMAND, TX_ENABLE);
+ CSR_WRITE_2(sc, EP_COMMAND, TX_ENABLE);
/*
* To have a tx_avail_int but giving
* the chance to the Reception
*/
if (ifp->if_snd.ifq_head)
- EP_WRITE_2(sc, EP_COMMAND,
+ CSR_WRITE_2(sc, EP_COMMAND,
SET_TX_AVAIL_THRESH | 8);
}
/* pops up the next status */
- EP_WRITE_1(sc, EP_W1_TX_STATUS, 0x0);
+ CSR_WRITE_1(sc, EP_W1_TX_STATUS, 0x0);
} /* while */
ifp->if_flags &= ~IFF_OACTIVE;
GO_WINDOW(1);
- EP_READ_2(sc, EP_W1_FREE_TX);
- ep_if_start(ifp);
+ CSR_READ_2(sc, EP_W1_FREE_TX);
+ epstart_body(ifp);
} /* end TX_COMPLETE */
}
- EP_WRITE_2(sc, EP_COMMAND, C_INTR_LATCH); /* ACK int Latch */
+ CSR_WRITE_2(sc, EP_COMMAND, C_INTR_LATCH); /* ACK int Latch */
- if ((status = EP_READ_2(sc, EP_STATUS)) & S_5_INTS)
+ if ((status = CSR_READ_2(sc, EP_STATUS)) & S_5_INTS)
goto rescan;
/* re-enable Ints */
- EP_WRITE_2(sc, EP_COMMAND, SET_INTR_MASK | S_5_INTS);
-
- splx(x);
+ CSR_WRITE_2(sc, EP_COMMAND, SET_INTR_MASK | S_5_INTS);
+ EP_UNLOCK(sc);
}
static void
@@ -690,12 +710,13 @@ epread(struct ep_softc *sc)
struct mbuf *top, *mcur, *m;
struct ifnet *ifp;
int lenthisone;
-
short rx_fifo2, status;
short rx_fifo;
+/* XXX Must be called with sc locked */
+
ifp = &sc->arpcom.ac_if;
- status = EP_READ_2(sc, EP_W1_RX_STATUS);
+ status = CSR_READ_2(sc, EP_W1_RX_STATUS);
read_again:
@@ -729,7 +750,7 @@ read_again:
top->m_data += EOFF;
/* Read what should be the header. */
- EP_READ_MULTI_2(sc, EP_W1_RX_PIO_RD_1,
+ CSR_READ_MULTI_2(sc, EP_W1_RX_PIO_RD_1,
mtod(top, uint16_t *), sizeof(struct ether_header) / 2);
top->m_len = sizeof(struct ether_header);
rx_fifo -= sizeof(struct ether_header);
@@ -757,22 +778,22 @@ read_again:
}
if (EP_FTST(sc, F_ACCESS_32_BITS)) {
/* default for EISA configured cards */
- EP_READ_MULTI_4(sc, EP_W1_RX_PIO_RD_1,
+ CSR_READ_MULTI_4(sc, EP_W1_RX_PIO_RD_1,
(uint32_t *)(mtod(m, caddr_t)+m->m_len),
lenthisone / 4);
m->m_len += (lenthisone & ~3);
if (lenthisone & 3)
- EP_READ_MULTI_1(sc, EP_W1_RX_PIO_RD_1,
+ CSR_READ_MULTI_1(sc, EP_W1_RX_PIO_RD_1,
mtod(m, caddr_t)+m->m_len, lenthisone & 3);
m->m_len += (lenthisone & 3);
} else {
- EP_READ_MULTI_2(sc, EP_W1_RX_PIO_RD_1,
+ CSR_READ_MULTI_2(sc, EP_W1_RX_PIO_RD_1,
(uint16_t *)(mtod(m, caddr_t)+m->m_len),
lenthisone / 2);
m->m_len += lenthisone;
if (lenthisone & 1)
*(mtod(m, caddr_t)+m->m_len - 1) =
- EP_READ_1(sc, EP_W1_RX_PIO_RD_1);
+ CSR_READ_1(sc, EP_W1_RX_PIO_RD_1);
}
rx_fifo -= lenthisone;
}
@@ -785,7 +806,7 @@ read_again:
sc->rx_no_first++;
#endif
EP_FRST(sc, F_RX_FIRST);
- status = EP_READ_2(sc, EP_W1_RX_STATUS);
+ status = CSR_READ_2(sc, EP_W1_RX_STATUS);
if (!status & ERR_RX_INCOMPLETE) {
/*
* We see if by now, the packet has completly
@@ -793,24 +814,33 @@ read_again:
*/
goto read_again;
}
- EP_WRITE_2(sc, EP_COMMAND,
+ CSR_WRITE_2(sc, EP_COMMAND,
SET_RX_EARLY_THRESH | RX_NEXT_EARLY_THRESH);
return;
}
- EP_WRITE_2(sc, EP_COMMAND, RX_DISCARD_TOP_PACK);
+ CSR_WRITE_2(sc, EP_COMMAND, RX_DISCARD_TOP_PACK);
++ifp->if_ipackets;
EP_FSET(sc, F_RX_FIRST);
top->m_pkthdr.rcvif = &sc->arpcom.ac_if;
top->m_pkthdr.len = sc->cur_len;
+ /*
+ * Drop locks before calling if_input() since it may re-enter
+ * ep_start() in the netisr case. This would result in a
+ * lock reversal. Better performance might be obtained by
+ * chaining all packets received, dropping the lock, and then
+ * calling if_input() on each one.
+ */
+ EP_UNLOCK(sc);
(*ifp->if_input) (ifp, top);
+ EP_LOCK(sc);
sc->top = 0;
- while (EP_READ_2(sc, EP_STATUS) & S_COMMAND_IN_PROGRESS);
- EP_WRITE_2(sc, EP_COMMAND, SET_RX_EARLY_THRESH | RX_INIT_EARLY_THRESH);
+ EP_BUSY_WAIT;
+ CSR_WRITE_2(sc, EP_COMMAND, SET_RX_EARLY_THRESH | RX_INIT_EARLY_THRESH);
return;
out:
- EP_WRITE_2(sc, EP_COMMAND, RX_DISCARD_TOP_PACK);
+ CSR_WRITE_2(sc, EP_COMMAND, RX_DISCARD_TOP_PACK);
if (sc->top) {
m_freem(sc->top);
sc->top = 0;
@@ -819,8 +849,8 @@ out:
#endif
}
EP_FSET(sc, F_RX_FIRST);
- while (EP_READ_2(sc, EP_STATUS) & S_COMMAND_IN_PROGRESS);
- EP_WRITE_2(sc, EP_COMMAND, SET_RX_EARLY_THRESH | RX_INIT_EARLY_THRESH);
+ EP_BUSY_WAIT;
+ CSR_WRITE_2(sc, EP_COMMAND, SET_RX_EARLY_THRESH | RX_INIT_EARLY_THRESH);
}
static int
@@ -830,9 +860,9 @@ ep_ifmedia_upd(struct ifnet *ifp)
int i = 0, j;
GO_WINDOW(0);
- EP_WRITE_2(sc, EP_COMMAND, STOP_TRANSCEIVER);
+ CSR_WRITE_2(sc, EP_COMMAND, STOP_TRANSCEIVER);
GO_WINDOW(4);
- EP_WRITE_2(sc, EP_W4_MEDIA_TYPE, DISABLE_UTP);
+ CSR_WRITE_2(sc, EP_W4_MEDIA_TYPE, DISABLE_UTP);
GO_WINDOW(0);
switch (IFM_SUBTYPE(sc->ifmedia.ifm_media)) {
@@ -840,13 +870,13 @@ ep_ifmedia_upd(struct ifnet *ifp)
if (sc->ep_connectors & UTP) {
i = ACF_CONNECTOR_UTP;
GO_WINDOW(4);
- EP_WRITE_2(sc, EP_W4_MEDIA_TYPE, ENABLE_UTP);
+ CSR_WRITE_2(sc, EP_W4_MEDIA_TYPE, ENABLE_UTP);
}
break;
case IFM_10_2:
if (sc->ep_connectors & BNC) {
i = ACF_CONNECTOR_BNC;
- EP_WRITE_2(sc, EP_COMMAND, START_TRANSCEIVER);
+ CSR_WRITE_2(sc, EP_COMMAND, START_TRANSCEIVER);
DELAY(DELAY_MULTIPLE * 1000);
}
break;
@@ -861,8 +891,8 @@ ep_ifmedia_upd(struct ifnet *ifp)
}
GO_WINDOW(0);
- j = EP_READ_2(sc, EP_W0_ADDRESS_CFG) & 0x3fff;
- EP_WRITE_2(sc, EP_W0_ADDRESS_CFG, j | (i << ACF_CONNECTOR_BITS));
+ j = CSR_READ_2(sc, EP_W0_ADDRESS_CFG) & 0x3fff;
+ CSR_WRITE_2(sc, EP_W0_ADDRESS_CFG, j | (i << ACF_CONNECTOR_BITS));
return (0);
}
@@ -876,23 +906,23 @@ ep_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr)
}
static int
-ep_if_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
+epioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
{
struct ep_softc *sc = ifp->if_softc;
struct ifreq *ifr = (struct ifreq *) data;
- int s, error = 0;
-
- s = splimp();
+ int error = 0;
switch (cmd) {
case SIOCSIFFLAGS:
+ EP_LOCK(sc);
if (((ifp->if_flags & IFF_UP) == 0) &&
(ifp->if_flags & IFF_RUNNING)) {
ifp->if_flags &= ~IFF_RUNNING;
epstop(sc);
} else
/* reinitialize card on any parameter change */
- ep_if_init(sc);
+ epinit_body(sc);
+ EP_UNLOCK(sc);
break;
#ifdef notdef
case SIOCGHWADDR:
@@ -922,28 +952,18 @@ ep_if_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
error = ether_ioctl(ifp, cmd, data);
break;
}
-
- (void)splx(s);
-
return (error);
}
static void
-ep_if_watchdog(struct ifnet *ifp)
+epwatchdog(struct ifnet *ifp)
{
struct ep_softc *sc = ifp->if_softc;
-/*
- printf("ep: watchdog\n");
-
- log(LOG_ERR, "ep%d: watchdog\n", ifp->if_unit);
- ifp->if_oerrors++;
-*/
-
if (sc->gone)
return;
ifp->if_flags &= ~IFF_OACTIVE;
- ep_if_start(ifp);
+ epstart(ifp);
ep_intr(ifp->if_softc);
}
@@ -952,21 +972,21 @@ epstop(struct ep_softc *sc)
{
if (sc->gone)
return;
- EP_WRITE_2(sc, EP_COMMAND, RX_DISABLE);
- EP_WRITE_2(sc, EP_COMMAND, RX_DISCARD_TOP_PACK);
- while (EP_READ_2(sc, EP_STATUS) & S_COMMAND_IN_PROGRESS);
+ CSR_WRITE_2(sc, EP_COMMAND, RX_DISABLE);
+ CSR_WRITE_2(sc, EP_COMMAND, RX_DISCARD_TOP_PACK);
+ EP_BUSY_WAIT;
- EP_WRITE_2(sc, EP_COMMAND, TX_DISABLE);
- EP_WRITE_2(sc, EP_COMMAND, STOP_TRANSCEIVER);
+ CSR_WRITE_2(sc, EP_COMMAND, TX_DISABLE);
+ CSR_WRITE_2(sc, EP_COMMAND, STOP_TRANSCEIVER);
DELAY(800);
- EP_WRITE_2(sc, EP_COMMAND, RX_RESET);
- while (EP_READ_2(sc, EP_STATUS) & S_COMMAND_IN_PROGRESS);
- EP_WRITE_2(sc, EP_COMMAND, TX_RESET);
- while (EP_READ_2(sc, EP_STATUS) & S_COMMAND_IN_PROGRESS);
+ CSR_WRITE_2(sc, EP_COMMAND, RX_RESET);
+ EP_BUSY_WAIT;
+ CSR_WRITE_2(sc, EP_COMMAND, TX_RESET);
+ EP_BUSY_WAIT;
- EP_WRITE_2(sc, EP_COMMAND, C_INTR_LATCH);
- EP_WRITE_2(sc, EP_COMMAND, SET_RD_0_MASK);
- EP_WRITE_2(sc, EP_COMMAND, SET_INTR_MASK);
- EP_WRITE_2(sc, EP_COMMAND, SET_RX_FILTER);
+ CSR_WRITE_2(sc, EP_COMMAND, C_INTR_LATCH);
+ CSR_WRITE_2(sc, EP_COMMAND, SET_RD_0_MASK);
+ CSR_WRITE_2(sc, EP_COMMAND, SET_INTR_MASK);
+ CSR_WRITE_2(sc, EP_COMMAND, SET_RX_FILTER);
}
diff --git a/sys/dev/ep/if_ep_eisa.c b/sys/dev/ep/if_ep_eisa.c
index e6f658a..ad2ebdc 100644
--- a/sys/dev/ep/if_ep_eisa.c
+++ b/sys/dev/ep/if_ep_eisa.c
@@ -221,7 +221,7 @@ ep_eisa_attach(device_t dev)
device_printf(dev, "ep_attach() failed! (%d)\n", error);
goto bad;
}
- if ((error = bus_setup_intr(dev, sc->irq, INTR_TYPE_NET, ep_intr,
+ if ((error = bus_setup_intr(dev, sc->irq, INTR_TYPE_NET | INTR_MPSAFE, ep_intr,
sc, &sc->ep_intrhand))) {
device_printf(dev, "bus_setup_intr() failed! (%d)\n", error);
goto bad;
diff --git a/sys/dev/ep/if_ep_isa.c b/sys/dev/ep/if_ep_isa.c
index 9c1fccd..546e9bb 100644
--- a/sys/dev/ep/if_ep_isa.c
+++ b/sys/dev/ep/if_ep_isa.c
@@ -343,7 +343,7 @@ ep_isa_attach(device_t dev)
device_printf(sc->dev, "Invalid EEPROM checksum!\n");
goto bad;
}
- if ((error = bus_setup_intr(dev, sc->irq, INTR_TYPE_NET, ep_intr,
+ if ((error = bus_setup_intr(dev, sc->irq, INTR_TYPE_NET | INTR_MPSAFE, ep_intr,
sc, &sc->ep_intrhand))) {
device_printf(dev, "bus_setup_intr() failed! (%d)\n", error);
goto bad;
diff --git a/sys/dev/ep/if_ep_mca.c b/sys/dev/ep/if_ep_mca.c
index 8c7d85c..b603bba 100644
--- a/sys/dev/ep/if_ep_mca.c
+++ b/sys/dev/ep/if_ep_mca.c
@@ -135,7 +135,7 @@ ep_mca_attach(device_t dev)
device_printf(dev, "ep_attach() failed! (%d)\n", error);
goto bad;
}
- if ((error = bus_setup_intr(dev, sc->irq, INTR_TYPE_NET, ep_intr,
+ if ((error = bus_setup_intr(dev, sc->irq, INTR_TYPE_NET | INTR_MPSAFE, ep_intr,
sc, &sc->ep_intrhand))) {
device_printf(dev, "bus_setup_intr() failed! (%d)\n", error);
goto bad;
diff --git a/sys/dev/ep/if_ep_pccard.c b/sys/dev/ep/if_ep_pccard.c
index 623ace7..67efa1b 100644
--- a/sys/dev/ep/if_ep_pccard.c
+++ b/sys/dev/ep/if_ep_pccard.c
@@ -207,26 +207,26 @@ ep_pccard_attach(device_t dev)
/* ROM size = 0, ROM base = 0 */
/* For now, ignore AUTO SELECT feature of 3C589B and later. */
- EP_WRITE_2(sc, EP_W0_ADDRESS_CFG, result & 0xc000);
+ CSR_WRITE_2(sc, EP_W0_ADDRESS_CFG, result & 0xc000);
/* Fake IRQ must be 3 */
- EP_WRITE_2(sc, EP_W0_RESOURCE_CFG, (sc->epb.res_cfg & 0x0fff) | 0x3000);
+ CSR_WRITE_2(sc, EP_W0_RESOURCE_CFG, (sc->epb.res_cfg & 0x0fff) | 0x3000);
- EP_WRITE_2(sc, EP_W0_PRODUCT_ID, sc->epb.prod_id);
+ CSR_WRITE_2(sc, EP_W0_PRODUCT_ID, sc->epb.prod_id);
if (sc->epb.mii_trans) {
/*
* turn on the MII transciever
*/
GO_WINDOW(3);
- EP_WRITE_2(sc, EP_W3_OPTIONS, 0x8040);
+ CSR_WRITE_2(sc, EP_W3_OPTIONS, 0x8040);
DELAY(1000);
- EP_WRITE_2(sc, EP_W3_OPTIONS, 0xc040);
- EP_WRITE_2(sc, EP_COMMAND, RX_RESET);
- EP_WRITE_2(sc, EP_COMMAND, TX_RESET);
- while (EP_READ_2(sc, EP_STATUS) & S_COMMAND_IN_PROGRESS);
+ CSR_WRITE_2(sc, EP_W3_OPTIONS, 0xc040);
+ CSR_WRITE_2(sc, EP_COMMAND, RX_RESET);
+ CSR_WRITE_2(sc, EP_COMMAND, TX_RESET);
+ EP_BUSY_WAIT;
DELAY(1000);
- EP_WRITE_2(sc, EP_W3_OPTIONS, 0x8040);
+ CSR_WRITE_2(sc, EP_W3_OPTIONS, 0x8040);
} else
ep_get_media(sc);
@@ -234,7 +234,7 @@ ep_pccard_attach(device_t dev)
device_printf(dev, "ep_attach() failed! (%d)\n", error);
goto bad;
}
- if ((error = bus_setup_intr(dev, sc->irq, INTR_TYPE_NET, ep_intr,
+ if ((error = bus_setup_intr(dev, sc->irq, INTR_TYPE_NET | INTR_MPSAFE, ep_intr,
sc, &sc->ep_intrhand))) {
device_printf(dev, "bus_setup_intr() failed! (%d)\n", error);
goto bad;
diff --git a/sys/dev/ep/if_epreg.h b/sys/dev/ep/if_epreg.h
index cc80901..3a5fb8b 100644
--- a/sys/dev/ep/if_epreg.h
+++ b/sys/dev/ep/if_epreg.h
@@ -42,21 +42,6 @@
#define MAX_EEPROMBUSY 1000
#define EP_LAST_TAG 0xd7
#define EP_MAX_BOARDS 16
-/*
- * This `ID' port is a mere hack. There's currently no chance to register
- * it with config's idea of the ports that are in use.
- *
- * "After the automatic configuration is completed, the IDS is in its initial
- * state (ID-WAIT), and it monitors all write access to I/O port 01x0h, where
- * 'x' is any hex digit. If a zero is written to any one of these ports, then
- * that address is remembered and becomes the ID port. A second zero written
- * to that port resets the ID sequence to its initial state. The IDS watches
- * for the ID sequence to be written to the ID port."
- *
- * We prefer 0x110 over 0x100 so to not conflict with the Plaque&Pray
- * ports.
- */
-#define EP_ID_PORT 0x110
#define EP_IOSIZE 16 /* 16 bytes of I/O space used. */
/*
@@ -74,8 +59,8 @@
/*
* Some short functions, worth to let them be a macro
*/
-#define is_eeprom_busy(sc) (EP_READ_2(sc, EP_W0_EEPROM_COMMAND)&EEPROM_BUSY)
-#define GO_WINDOW(x) EP_WRITE_2(sc, EP_COMMAND, WINDOW_SELECT|(x))
+#define is_eeprom_busy(sc) (CSR_READ_2(sc, EP_W0_EEPROM_COMMAND)&EEPROM_BUSY)
+#define GO_WINDOW(x) CSR_WRITE_2(sc, EP_COMMAND, WINDOW_SELECT|(x))
/**************************************************************************
* *
@@ -149,7 +134,7 @@
#define EP_W0_RESOURCE_CFG 0x08
#define EP_W0_ADDRESS_CFG 0x06
#define EP_W0_CONFIG_CTRL 0x04
-/* Read */
+ /* Read */
#define EP_W0_PRODUCT_ID 0x02
#define EP_W0_MFG_ID 0x00
@@ -265,33 +250,32 @@
#define TX_DISABLE (u_short) (0xa<<11)
#define TX_RESET (u_short) (0xb<<11)
#define REQ_INTR (u_short) (0xc<<11)
+/*
+ * The following C_* acknowledge the various interrupts. Some of them don't
+ * do anything. See the manual.
+ */
+#define ACK_INTR (u_short) (0x6800)
+# define C_INTR_LATCH (u_short) (ACK_INTR|0x1)
+# define C_CARD_FAILURE (u_short) (ACK_INTR|0x2)
+# define C_TX_COMPLETE (u_short) (ACK_INTR|0x4)
+# define C_TX_AVAIL (u_short) (ACK_INTR|0x8)
+# define C_RX_COMPLETE (u_short) (ACK_INTR|0x10)
+# define C_RX_EARLY (u_short) (ACK_INTR|0x20)
+# define C_INT_RQD (u_short) (ACK_INTR|0x40)
+# define C_UPD_STATS (u_short) (ACK_INTR|0x80)
#define SET_INTR_MASK (u_short) (0xe<<11)
#define SET_RD_0_MASK (u_short) (0xf<<11)
#define SET_RX_FILTER (u_short) (0x10<<11)
-#define FIL_INDIVIDUAL (u_short) (0x1)
-#define FIL_GROUP (u_short) (0x2)
-#define FIL_BRDCST (u_short) (0x4)
-#define FIL_ALL (u_short) (0x8)
+# define FIL_INDIVIDUAL (u_short) (0x1)
+# define FIL_MULTICAST (u_short) (0x02)
+# define FIL_BRDCST (u_short) (0x04)
+# define FIL_PROMISC (u_short) (0x08)
#define SET_RX_EARLY_THRESH (u_short) (0x11<<11)
#define SET_TX_AVAIL_THRESH (u_short) (0x12<<11)
#define SET_TX_START_THRESH (u_short) (0x13<<11)
#define STATS_ENABLE (u_short) (0x15<<11)
#define STATS_DISABLE (u_short) (0x16<<11)
#define STOP_TRANSCEIVER (u_short) (0x17<<11)
-/*
- * The following C_* acknowledge the various interrupts. Some of them don't
- * do anything. See the manual.
- */
-#define ACK_INTR (u_short) (0x6800)
-#define C_INTR_LATCH (u_short) (ACK_INTR|0x1)
-#define C_CARD_FAILURE (u_short) (ACK_INTR|0x2)
-#define C_TX_COMPLETE (u_short) (ACK_INTR|0x4)
-#define C_TX_AVAIL (u_short) (ACK_INTR|0x8)
-#define C_RX_COMPLETE (u_short) (ACK_INTR|0x10)
-#define C_RX_EARLY (u_short) (ACK_INTR|0x20)
-#define C_INT_RQD (u_short) (ACK_INTR|0x40)
-#define C_UPD_STATS (u_short) (ACK_INTR|0x80)
-#define C_MASK (u_short) 0xFF /* mask of C_* */
/*
* Status register. All windows.
@@ -324,6 +308,8 @@
S_TX_AVAIL|S_RX_COMPLETE|S_RX_EARLY)
#define S_COMMAND_IN_PROGRESS (u_short) (0x1000)
+#define EP_BUSY_WAIT while (CSR_READ_2(sc, EP_STATUS) & S_COMMAND_IN_PROGRESS)
+
/* Address Config. Register.
* Window 0/Port 06
*/
@@ -338,9 +324,9 @@
*
*/
-#define SET_IRQ(sc, irq) EP_WRITE_2((sc), EP_W0_RESOURCE_CFG, \
- ((EP_READ_2((sc), EP_W0_RESOURCE_CFG) & 0x0fff) | \
- ((u_short)(irq)<<12)) ) /* set IRQ i */
+#define SET_IRQ(sc, irq) CSR_WRITE_2((sc), EP_W0_RESOURCE_CFG, \
+ ((CSR_READ_2((sc), EP_W0_RESOURCE_CFG) & 0x0fff) | \
+ ((u_short)(irq)<<12)) ) /* set IRQ i */
/*
* FIFO Registers.
@@ -405,12 +391,15 @@
#define ENABLE_DRQ_IRQ 0x0001
#define W0_P4_CMD_RESET_ADAPTER 0x4
#define W0_P4_CMD_ENABLE_ADAPTER 0x1
+
/*
* Media type and status.
* Window 4/Port 0A
*/
-#define ENABLE_UTP 0xc0
-#define DISABLE_UTP 0x0
+#define JABBER_GUARD_ENABLE 0x40
+#define LINKBEAT_ENABLE 0x80
+#define ENABLE_UTP (JABBER_GUARD_ENABLE | LINKBEAT_ENABLE)
+#define DISABLE_UTP 0x0
/*
* Misc defines for various things.
@@ -425,8 +414,3 @@
#define UTP 0x4
#define RX_BYTES_MASK (u_short) (0x07ff)
-
-/*
- * Config flags
- */
-#define EP_FLAGS_100TX 0x1
diff --git a/sys/dev/ep/if_epvar.h b/sys/dev/ep/if_epvar.h
index 122b0b8..ec41616 100644
--- a/sys/dev/ep/if_epvar.h
+++ b/sys/dev/ep/if_epvar.h
@@ -38,6 +38,7 @@ struct ep_softc {
device_t dev;
+ struct mtx sc_mtx;
struct resource *iobase;
struct resource *irq;
@@ -81,21 +82,24 @@ void ep_intr(void *);
int get_e(struct ep_softc *, u_int16_t, u_int16_t *);
int ep_get_macaddr(struct ep_softc *, u_char *);
-#define EP_READ_1(sc, off) (bus_space_read_1((sc)->bst, (sc)->bsh, off))
-#define EP_READ_2(sc, off) (bus_space_read_2((sc)->bst, (sc)->bsh, off))
-#define EP_WRITE_1(sc, off, val) \
+#define CSR_READ_1(sc, off) (bus_space_read_1((sc)->bst, (sc)->bsh, off))
+#define CSR_READ_2(sc, off) (bus_space_read_2((sc)->bst, (sc)->bsh, off))
+#define CSR_WRITE_1(sc, off, val) \
bus_space_write_1(sc->bst, sc->bsh, off, val)
-#define EP_WRITE_2(sc, off, val) \
+#define CSR_WRITE_2(sc, off, val) \
bus_space_write_2(sc->bst, sc->bsh, off, val)
-#define EP_WRITE_MULTI_1(sc, off, addr, count) \
+#define CSR_WRITE_MULTI_1(sc, off, addr, count) \
bus_space_write_multi_1(sc->bst, sc->bsh, off, addr, count)
-#define EP_WRITE_MULTI_2(sc, off, addr, count) \
+#define CSR_WRITE_MULTI_2(sc, off, addr, count) \
bus_space_write_multi_2(sc->bst, sc->bsh, off, addr, count)
-#define EP_WRITE_MULTI_4(sc, off, addr, count) \
+#define CSR_WRITE_MULTI_4(sc, off, addr, count) \
bus_space_write_multi_4(sc->bst, sc->bsh, off, addr, count)
-#define EP_READ_MULTI_1(sc, off, addr, count) \
+#define CSR_READ_MULTI_1(sc, off, addr, count) \
bus_space_read_multi_1(sc->bst, sc->bsh, off, addr, count)
-#define EP_READ_MULTI_2(sc, off, addr, count) \
+#define CSR_READ_MULTI_2(sc, off, addr, count) \
bus_space_read_multi_2(sc->bst, sc->bsh, off, addr, count)
-#define EP_READ_MULTI_4(sc, off, addr, count) \
+#define CSR_READ_MULTI_4(sc, off, addr, count) \
bus_space_read_multi_4(sc->bst, sc->bsh, off, addr, count)
+
+#define EP_LOCK(_sc) mtx_lock(&(_sc)->sc_mtx)
+#define EP_UNLOCK(_sc) mtx_unlock(&(_sc)->sc_mtx)
OpenPOWER on IntegriCloud