- Use callout_*() rather than timeout() to periodically poll the media.
- Add locking to protect the softc and mark this driver as MP safe. There are still some edge cases with multiport cards that need more locking work. MFC after: 1 week Tested on: alpha
This commit is contained in:
parent
53b633e139
commit
d675d9c68f
@ -128,6 +128,7 @@ static void tulip_mii_writereg(tulip_softc_t * const sc, unsigned devaddr,
|
||||
static void tulip_reset(tulip_softc_t * const sc);
|
||||
static void tulip_rx_intr(tulip_softc_t * const sc);
|
||||
static int tulip_srom_decode(tulip_softc_t * const sc);
|
||||
static void tulip_start(tulip_softc_t * const sc);
|
||||
static struct mbuf *
|
||||
tulip_txput(tulip_softc_t * const sc, struct mbuf *m);
|
||||
static void tulip_txput_setup(tulip_softc_t * const sc);
|
||||
@ -137,26 +138,28 @@ tulip_timeout_callback(
|
||||
void *arg)
|
||||
{
|
||||
tulip_softc_t * const sc = arg;
|
||||
int s = splimp();
|
||||
|
||||
TULIP_PERFSTART(timeout)
|
||||
TULIP_LOCK(sc);
|
||||
|
||||
sc->tulip_flags &= ~TULIP_TIMEOUTPENDING;
|
||||
sc->tulip_probe_timeout -= 1000 / TULIP_HZ;
|
||||
(sc->tulip_boardsw->bd_media_poll)(sc, TULIP_MEDIAPOLL_TIMER);
|
||||
|
||||
TULIP_PERFEND(timeout);
|
||||
splx(s);
|
||||
TULIP_UNLOCK(sc);
|
||||
}
|
||||
|
||||
static void
|
||||
tulip_timeout(
|
||||
tulip_softc_t * const sc)
|
||||
{
|
||||
TULIP_LOCK_ASSERT(sc);
|
||||
if (sc->tulip_flags & TULIP_TIMEOUTPENDING)
|
||||
return;
|
||||
sc->tulip_flags |= TULIP_TIMEOUTPENDING;
|
||||
timeout(tulip_timeout_callback, sc, (hz + TULIP_HZ / 2) / TULIP_HZ);
|
||||
callout_reset(&sc->tulip_callout, (hz + TULIP_HZ / 2) / TULIP_HZ,
|
||||
tulip_timeout_callback, sc);
|
||||
}
|
||||
|
||||
|
||||
@ -172,6 +175,7 @@ tulip_txprobe(
|
||||
* either is connected so the transmit is the only way
|
||||
* to verify the connectivity.
|
||||
*/
|
||||
TULIP_LOCK_ASSERT(sc);
|
||||
MGETHDR(m, M_DONTWAIT, MT_DATA);
|
||||
if (m == NULL)
|
||||
return 0;
|
||||
@ -207,6 +211,7 @@ tulip_media_set(
|
||||
{
|
||||
const tulip_media_info_t *mi = sc->tulip_mediums[media];
|
||||
|
||||
TULIP_LOCK_ASSERT(sc);
|
||||
if (mi == NULL)
|
||||
return;
|
||||
|
||||
@ -299,6 +304,7 @@ tulip_linkup(
|
||||
tulip_softc_t * const sc,
|
||||
tulip_media_t media)
|
||||
{
|
||||
TULIP_LOCK_ASSERT(sc);
|
||||
if ((sc->tulip_flags & TULIP_LINKUP) == 0)
|
||||
sc->tulip_flags |= TULIP_PRINTLINKUP;
|
||||
sc->tulip_flags |= TULIP_LINKUP;
|
||||
@ -354,6 +360,7 @@ tulip_media_print(
|
||||
{
|
||||
struct ifnet *ifp = sc->tulip_ifp;
|
||||
|
||||
TULIP_LOCK_ASSERT(sc);
|
||||
if ((sc->tulip_flags & TULIP_LINKUP) == 0)
|
||||
return;
|
||||
if (sc->tulip_flags & TULIP_PRINTMEDIA) {
|
||||
@ -376,6 +383,8 @@ tulip_21140_gpr_media_sense(
|
||||
tulip_media_t last_media = TULIP_MEDIA_UNKNOWN;
|
||||
tulip_media_t media;
|
||||
|
||||
TULIP_LOCK_ASSERT(sc);
|
||||
|
||||
/*
|
||||
* If one of the media blocks contained a default media flag,
|
||||
* use that.
|
||||
@ -438,6 +447,7 @@ tulip_media_link_monitor(
|
||||
const tulip_media_info_t * const mi = sc->tulip_mediums[sc->tulip_media];
|
||||
tulip_link_status_t linkup = TULIP_LINK_DOWN;
|
||||
|
||||
TULIP_LOCK_ASSERT(sc);
|
||||
if (mi == NULL) {
|
||||
#if defined(DIAGNOSTIC) || defined(TULIP_DEBUG)
|
||||
panic("tulip_media_link_monitor: %s: botch at line %d\n",
|
||||
@ -548,6 +558,7 @@ tulip_media_poll(
|
||||
{
|
||||
struct ifnet *ifp = sc->tulip_ifp;
|
||||
|
||||
TULIP_LOCK_ASSERT(sc);
|
||||
#if defined(TULIP_DEBUG)
|
||||
sc->tulip_dbg.dbg_events[event]++;
|
||||
#endif
|
||||
@ -835,6 +846,7 @@ static void
|
||||
tulip_media_select(
|
||||
tulip_softc_t * const sc)
|
||||
{
|
||||
TULIP_LOCK_ASSERT(sc);
|
||||
if (sc->tulip_features & TULIP_HAVE_GPR) {
|
||||
TULIP_CSR_WRITE(sc, csr_gp, TULIP_GP_PINSET|sc->tulip_gpinit);
|
||||
DELAY(10);
|
||||
@ -859,6 +871,7 @@ tulip_21040_mediainfo_init(
|
||||
tulip_softc_t * const sc,
|
||||
tulip_media_t media)
|
||||
{
|
||||
TULIP_LOCK_ASSERT(sc);
|
||||
sc->tulip_cmdmode |= TULIP_CMD_CAPTREFFCT|TULIP_CMD_THRSHLD160
|
||||
|TULIP_CMD_BACKOFFCTR;
|
||||
sc->tulip_ifp->if_baudrate = 10000000;
|
||||
@ -882,6 +895,7 @@ static void
|
||||
tulip_21040_media_probe(
|
||||
tulip_softc_t * const sc)
|
||||
{
|
||||
TULIP_LOCK_ASSERT(sc);
|
||||
tulip_21040_mediainfo_init(sc, TULIP_MEDIA_UNKNOWN);
|
||||
return;
|
||||
}
|
||||
@ -890,6 +904,7 @@ static void
|
||||
tulip_21040_10baset_only_media_probe(
|
||||
tulip_softc_t * const sc)
|
||||
{
|
||||
TULIP_LOCK_ASSERT(sc);
|
||||
tulip_21040_mediainfo_init(sc, TULIP_MEDIA_10BASET);
|
||||
tulip_media_set(sc, TULIP_MEDIA_10BASET);
|
||||
sc->tulip_media = TULIP_MEDIA_10BASET;
|
||||
@ -899,6 +914,7 @@ static void
|
||||
tulip_21040_10baset_only_media_select(
|
||||
tulip_softc_t * const sc)
|
||||
{
|
||||
TULIP_LOCK_ASSERT(sc);
|
||||
sc->tulip_flags |= TULIP_LINKUP;
|
||||
if (sc->tulip_media == TULIP_MEDIA_10BASET_FD) {
|
||||
sc->tulip_cmdmode |= TULIP_CMD_FULLDUPLEX;
|
||||
@ -914,6 +930,7 @@ static void
|
||||
tulip_21040_auibnc_only_media_probe(
|
||||
tulip_softc_t * const sc)
|
||||
{
|
||||
TULIP_LOCK_ASSERT(sc);
|
||||
tulip_21040_mediainfo_init(sc, TULIP_MEDIA_AUIBNC);
|
||||
sc->tulip_flags |= TULIP_SQETEST|TULIP_LINKUP;
|
||||
tulip_media_set(sc, TULIP_MEDIA_AUIBNC);
|
||||
@ -924,6 +941,7 @@ static void
|
||||
tulip_21040_auibnc_only_media_select(
|
||||
tulip_softc_t * const sc)
|
||||
{
|
||||
TULIP_LOCK_ASSERT(sc);
|
||||
tulip_media_set(sc, TULIP_MEDIA_AUIBNC);
|
||||
sc->tulip_cmdmode &= ~TULIP_CMD_FULLDUPLEX;
|
||||
}
|
||||
@ -955,6 +973,7 @@ tulip_21041_mediainfo_init(
|
||||
{
|
||||
tulip_media_info_t * const mi = sc->tulip_mediainfo;
|
||||
|
||||
TULIP_LOCK_ASSERT(sc);
|
||||
#ifdef notyet
|
||||
if (sc->tulip_revinfo >= 0x20) {
|
||||
TULIP_MEDIAINFO_SIA_INIT(sc, &mi[0], 21041P2, 10BASET);
|
||||
@ -974,6 +993,7 @@ static void
|
||||
tulip_21041_media_probe(
|
||||
tulip_softc_t * const sc)
|
||||
{
|
||||
TULIP_LOCK_ASSERT(sc);
|
||||
sc->tulip_ifp->if_baudrate = 10000000;
|
||||
sc->tulip_cmdmode |= TULIP_CMD_CAPTREFFCT|TULIP_CMD_ENHCAPTEFFCT
|
||||
|TULIP_CMD_THRSHLD160|TULIP_CMD_BACKOFFCTR;
|
||||
@ -988,6 +1008,7 @@ tulip_21041_media_poll(
|
||||
{
|
||||
u_int32_t sia_status;
|
||||
|
||||
TULIP_LOCK_ASSERT(sc);
|
||||
#if defined(TULIP_DEBUG)
|
||||
sc->tulip_dbg.dbg_events[event]++;
|
||||
#endif
|
||||
@ -1209,6 +1230,8 @@ tulip_mii_phy_readspecific(
|
||||
TULIP_MEDIA_UNKNOWN
|
||||
};
|
||||
|
||||
TULIP_LOCK_ASSERT(sc);
|
||||
|
||||
/*
|
||||
* Don't read phy specific registers if link is not up.
|
||||
*/
|
||||
@ -1258,6 +1281,7 @@ tulip_mii_get_phyaddr(
|
||||
{
|
||||
unsigned phyaddr;
|
||||
|
||||
TULIP_LOCK_ASSERT(sc);
|
||||
for (phyaddr = 1; phyaddr < 32; phyaddr++) {
|
||||
unsigned status = tulip_mii_readreg(sc, phyaddr, PHYREG_STATUS);
|
||||
if (status == 0 || status == 0xFFFF || status < PHYSTS_10BASET)
|
||||
@ -1280,6 +1304,7 @@ tulip_mii_map_abilities(
|
||||
tulip_softc_t * const sc,
|
||||
unsigned abilities)
|
||||
{
|
||||
TULIP_LOCK_ASSERT(sc);
|
||||
sc->tulip_abilities = abilities;
|
||||
if (abilities & PHYSTS_100BASETX_FD) {
|
||||
sc->tulip_probe_media = TULIP_MEDIA_100BASETX_FD;
|
||||
@ -1306,6 +1331,7 @@ tulip_mii_autonegotiate(
|
||||
{
|
||||
struct ifnet *ifp = sc->tulip_ifp;
|
||||
|
||||
TULIP_LOCK_ASSERT(sc);
|
||||
switch (sc->tulip_probe_state) {
|
||||
case TULIP_PROBE_MEDIATEST:
|
||||
case TULIP_PROBE_INACTIVE: {
|
||||
@ -1406,6 +1432,7 @@ tulip_2114x_media_preset(
|
||||
const tulip_media_info_t *mi = NULL;
|
||||
tulip_media_t media = sc->tulip_media;
|
||||
|
||||
TULIP_LOCK_ASSERT(sc);
|
||||
if (sc->tulip_probe_state == TULIP_PROBE_INACTIVE)
|
||||
media = sc->tulip_media;
|
||||
else
|
||||
@ -1496,6 +1523,7 @@ tulip_21140_mediainit(
|
||||
unsigned gpdata,
|
||||
unsigned cmdmode)
|
||||
{
|
||||
TULIP_LOCK_ASSERT(sc);
|
||||
sc->tulip_mediums[media] = mip;
|
||||
mip->mi_type = TULIP_MEDIAINFO_GPR;
|
||||
mip->mi_cmdmode = cmdmode;
|
||||
@ -1508,6 +1536,7 @@ tulip_21140_evalboard_media_probe(
|
||||
{
|
||||
tulip_media_info_t *mip = sc->tulip_mediainfo;
|
||||
|
||||
TULIP_LOCK_ASSERT(sc);
|
||||
sc->tulip_gpinit = TULIP_GP_EB_PINS;
|
||||
sc->tulip_gpdata = TULIP_GP_EB_INIT;
|
||||
TULIP_CSR_WRITE(sc, csr_gp, TULIP_GP_EB_PINS);
|
||||
@ -1554,6 +1583,7 @@ tulip_21140_accton_media_probe(
|
||||
tulip_media_info_t *mip = sc->tulip_mediainfo;
|
||||
unsigned gpdata;
|
||||
|
||||
TULIP_LOCK_ASSERT(sc);
|
||||
sc->tulip_gpinit = TULIP_GP_EB_PINS;
|
||||
sc->tulip_gpdata = TULIP_GP_EB_INIT;
|
||||
TULIP_CSR_WRITE(sc, csr_gp, TULIP_GP_EB_PINS);
|
||||
@ -1608,6 +1638,7 @@ tulip_21140_smc9332_media_probe(
|
||||
tulip_media_info_t *mip = sc->tulip_mediainfo;
|
||||
int idx, cnt = 0;
|
||||
|
||||
TULIP_LOCK_ASSERT(sc);
|
||||
TULIP_CSR_WRITE(sc, csr_command, TULIP_CMD_PORTSELECT|TULIP_CMD_MUSTBEONE);
|
||||
TULIP_CSR_WRITE(sc, csr_busmode, TULIP_BUSMODE_SWRESET);
|
||||
DELAY(10); /* Wait 10 microseconds (actually 50 PCI cycles but at
|
||||
@ -1664,6 +1695,7 @@ tulip_21140_cogent_em100_media_probe(
|
||||
tulip_media_info_t *mip = sc->tulip_mediainfo;
|
||||
u_int32_t cmdmode = TULIP_CSR_READ(sc, csr_command);
|
||||
|
||||
TULIP_LOCK_ASSERT(sc);
|
||||
sc->tulip_gpinit = TULIP_GP_EM100_PINS;
|
||||
sc->tulip_gpdata = TULIP_GP_EM100_INIT;
|
||||
TULIP_CSR_WRITE(sc, csr_gp, TULIP_GP_EM100_PINS);
|
||||
@ -1711,6 +1743,7 @@ tulip_21140_znyx_zx34x_media_probe(
|
||||
tulip_media_info_t *mip = sc->tulip_mediainfo;
|
||||
int cnt10 = 0, cnt100 = 0, idx;
|
||||
|
||||
TULIP_LOCK_ASSERT(sc);
|
||||
sc->tulip_gpinit = TULIP_GP_ZX34X_PINS;
|
||||
sc->tulip_gpdata = TULIP_GP_ZX34X_INIT;
|
||||
TULIP_CSR_WRITE(sc, csr_gp, TULIP_GP_ZX34X_PINS);
|
||||
@ -1765,6 +1798,7 @@ static void
|
||||
tulip_2114x_media_probe(
|
||||
tulip_softc_t * const sc)
|
||||
{
|
||||
TULIP_LOCK_ASSERT(sc);
|
||||
sc->tulip_cmdmode |= TULIP_CMD_MUSTBEONE
|
||||
|TULIP_CMD_BACKOFFCTR|TULIP_CMD_THRSHLD72;
|
||||
}
|
||||
@ -1869,6 +1903,7 @@ tulip_mii_writebits(
|
||||
unsigned csr = TULIP_CSR_READ(sc, csr_srom_mii) & (MII_RD|MII_DOUT|MII_CLK);
|
||||
unsigned lastbit = (csr & MII_DOUT) ? msb : 0;
|
||||
|
||||
TULIP_LOCK_ASSERT(sc);
|
||||
csr |= MII_WR; MII_EMIT; /* clock low; assert write */
|
||||
|
||||
for (; bits > 0; bits--, data <<= 1) {
|
||||
@ -1889,6 +1924,7 @@ tulip_mii_turnaround(
|
||||
{
|
||||
unsigned csr = TULIP_CSR_READ(sc, csr_srom_mii) & (MII_RD|MII_DOUT|MII_CLK);
|
||||
|
||||
TULIP_LOCK_ASSERT(sc);
|
||||
if (cmd == MII_WRCMD) {
|
||||
csr |= MII_DOUT; MII_EMIT; /* clock low; change data */
|
||||
csr ^= MII_CLKON; MII_EMIT; /* clock high; data valid */
|
||||
@ -1909,6 +1945,7 @@ tulip_mii_readbits(
|
||||
unsigned csr = TULIP_CSR_READ(sc, csr_srom_mii) & (MII_RD|MII_DOUT|MII_CLK);
|
||||
int idx;
|
||||
|
||||
TULIP_LOCK_ASSERT(sc);
|
||||
for (idx = 0, data = 0; idx < 16; idx++) {
|
||||
data <<= 1; /* this is NOOP on the first pass through */
|
||||
csr ^= MII_CLKON; MII_EMIT; /* clock high; data valid */
|
||||
@ -1930,6 +1967,7 @@ tulip_mii_readreg(
|
||||
unsigned csr = TULIP_CSR_READ(sc, csr_srom_mii) & (MII_RD|MII_DOUT|MII_CLK);
|
||||
unsigned data;
|
||||
|
||||
TULIP_LOCK_ASSERT(sc);
|
||||
csr &= ~(MII_RD|MII_CLK); MII_EMIT;
|
||||
tulip_mii_writebits(sc, MII_PREAMBLE, 32);
|
||||
tulip_mii_writebits(sc, MII_RDCMD, 8);
|
||||
@ -1953,6 +1991,8 @@ tulip_mii_writereg(
|
||||
unsigned data)
|
||||
{
|
||||
unsigned csr = TULIP_CSR_READ(sc, csr_srom_mii) & (MII_RD|MII_DOUT|MII_CLK);
|
||||
|
||||
TULIP_LOCK_ASSERT(sc);
|
||||
csr &= ~(MII_RD|MII_CLK); MII_EMIT;
|
||||
tulip_mii_writebits(sc, MII_PREAMBLE, 32);
|
||||
tulip_mii_writebits(sc, MII_WRCMD, 8);
|
||||
@ -1975,6 +2015,7 @@ static void
|
||||
tulip_identify_dec_nic(
|
||||
tulip_softc_t * const sc)
|
||||
{
|
||||
TULIP_LOCK_ASSERT(sc);
|
||||
strcpy(sc->tulip_boardid, "DEC ");
|
||||
#define D0 4
|
||||
if (sc->tulip_chipid <= TULIP_21040)
|
||||
@ -1992,6 +2033,8 @@ tulip_identify_znyx_nic(
|
||||
tulip_softc_t * const sc)
|
||||
{
|
||||
unsigned id = 0;
|
||||
|
||||
TULIP_LOCK_ASSERT(sc);
|
||||
strcpy(sc->tulip_boardid, "ZNYX ZX3XX ");
|
||||
if (sc->tulip_chipid == TULIP_21140 || sc->tulip_chipid == TULIP_21140A) {
|
||||
unsigned znyx_ptr;
|
||||
@ -2088,6 +2131,7 @@ tulip_identify_smc_nic(
|
||||
int auibnc = 0, utp = 0;
|
||||
char *cp;
|
||||
|
||||
TULIP_LOCK_ASSERT(sc);
|
||||
strcpy(sc->tulip_boardid, "SMC ");
|
||||
if (sc->tulip_chipid == TULIP_21041)
|
||||
return;
|
||||
@ -2133,6 +2177,7 @@ static void
|
||||
tulip_identify_cogent_nic(
|
||||
tulip_softc_t * const sc)
|
||||
{
|
||||
TULIP_LOCK_ASSERT(sc);
|
||||
strcpy(sc->tulip_boardid, "Cogent ");
|
||||
if (sc->tulip_chipid == TULIP_21140 || sc->tulip_chipid == TULIP_21140A) {
|
||||
if (sc->tulip_rombuf[32] == TULIP_COGENT_EM100TX_ID) {
|
||||
@ -2169,6 +2214,7 @@ static void
|
||||
tulip_identify_accton_nic(
|
||||
tulip_softc_t * const sc)
|
||||
{
|
||||
TULIP_LOCK_ASSERT(sc);
|
||||
strcpy(sc->tulip_boardid, "ACCTON ");
|
||||
switch (sc->tulip_chipid) {
|
||||
case TULIP_21140A:
|
||||
@ -2199,6 +2245,7 @@ static void
|
||||
tulip_identify_asante_nic(
|
||||
tulip_softc_t * const sc)
|
||||
{
|
||||
TULIP_LOCK_ASSERT(sc);
|
||||
strcpy(sc->tulip_boardid, "Asante ");
|
||||
if ((sc->tulip_chipid == TULIP_21140 || sc->tulip_chipid == TULIP_21140A)
|
||||
&& sc->tulip_boardsw != &tulip_2114x_isv_boardsw) {
|
||||
@ -2255,6 +2302,7 @@ static void
|
||||
tulip_identify_compex_nic(
|
||||
tulip_softc_t * const sc)
|
||||
{
|
||||
TULIP_LOCK_ASSERT(sc);
|
||||
strcpy(sc->tulip_boardid, "COMPEX ");
|
||||
if (sc->tulip_chipid == TULIP_21140A) {
|
||||
int root_unit;
|
||||
@ -2303,6 +2351,7 @@ tulip_srom_decode(
|
||||
const u_int8_t *dp;
|
||||
u_int32_t leaf_offset, blocks, data;
|
||||
|
||||
TULIP_LOCK_ASSERT(sc);
|
||||
for (idx1 = 0; idx1 < shp->sh_adapter_count; idx1++, saip++) {
|
||||
if (shp->sh_adapter_count == 1)
|
||||
break;
|
||||
@ -2882,6 +2931,7 @@ tulip_ifmedia_add(
|
||||
tulip_media_t media;
|
||||
int medias = 0;
|
||||
|
||||
TULIP_LOCK_ASSERT(sc);
|
||||
for (media = TULIP_MEDIA_UNKNOWN; media < TULIP_MEDIA_MAX; media++) {
|
||||
if (sc->tulip_mediums[media] != NULL) {
|
||||
ifmedia_add(&sc->tulip_ifmedia, tulip_media_to_ifmedia[media],
|
||||
@ -2909,6 +2959,7 @@ tulip_ifmedia_change(
|
||||
{
|
||||
tulip_softc_t * const sc = (tulip_softc_t *)ifp->if_softc;
|
||||
|
||||
TULIP_LOCK(sc);
|
||||
sc->tulip_flags |= TULIP_NEEDRESET;
|
||||
sc->tulip_probe_state = TULIP_PROBE_INACTIVE;
|
||||
sc->tulip_media = TULIP_MEDIA_UNKNOWN;
|
||||
@ -2920,6 +2971,7 @@ tulip_ifmedia_change(
|
||||
sc->tulip_flags |= TULIP_PRINTMEDIA;
|
||||
sc->tulip_flags &= ~TULIP_DIDNWAY;
|
||||
tulip_linkup(sc, media);
|
||||
TULIP_UNLOCK(sc);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@ -2927,6 +2979,7 @@ tulip_ifmedia_change(
|
||||
sc->tulip_flags &= ~(TULIP_TXPROBE_ACTIVE|TULIP_WANTRXACT);
|
||||
tulip_reset(sc);
|
||||
tulip_init(sc);
|
||||
TULIP_UNLOCK(sc);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -2940,14 +2993,18 @@ tulip_ifmedia_status(
|
||||
{
|
||||
tulip_softc_t *sc = (tulip_softc_t *)ifp->if_softc;
|
||||
|
||||
if (sc->tulip_media == TULIP_MEDIA_UNKNOWN)
|
||||
TULIP_LOCK(sc);
|
||||
if (sc->tulip_media == TULIP_MEDIA_UNKNOWN) {
|
||||
TULIP_UNLOCK(sc);
|
||||
return;
|
||||
}
|
||||
|
||||
req->ifm_status = IFM_AVALID;
|
||||
if (sc->tulip_flags & TULIP_LINKUP)
|
||||
req->ifm_status |= IFM_ACTIVE;
|
||||
|
||||
req->ifm_active = tulip_media_to_ifmedia[sc->tulip_media];
|
||||
TULIP_UNLOCK(sc);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -2958,6 +3015,7 @@ tulip_addr_filter(
|
||||
u_char *addrp;
|
||||
int multicnt;
|
||||
|
||||
TULIP_LOCK_ASSERT(sc);
|
||||
sc->tulip_flags &= ~(TULIP_WANTHASHPERFECT|TULIP_WANTHASHONLY|TULIP_ALLMULTI);
|
||||
sc->tulip_flags |= TULIP_WANTSETUP|TULIP_WANTTXSTART;
|
||||
sc->tulip_cmdmode &= ~TULIP_CMD_RXRUN;
|
||||
@ -3103,6 +3161,8 @@ tulip_reset(
|
||||
tulip_desc_t *di;
|
||||
u_int32_t inreset = (sc->tulip_flags & TULIP_INRESET);
|
||||
|
||||
TULIP_LOCK_ASSERT(sc);
|
||||
|
||||
/*
|
||||
* Brilliant. Simply brilliant. When switching modes/speeds
|
||||
* on a 2114*, you need to set the appriopriate MII/PCS/SCL/PS
|
||||
@ -3242,9 +3302,13 @@ tulip_reset(
|
||||
|
||||
static void
|
||||
tulip_ifinit(
|
||||
void * sc)
|
||||
void *arg)
|
||||
{
|
||||
tulip_init((tulip_softc_t *)sc);
|
||||
tulip_softc_t *sc = (tulip_softc_t *)arg;
|
||||
|
||||
TULIP_LOCK(sc);
|
||||
tulip_init(sc);
|
||||
TULIP_UNLOCK(sc);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -3302,6 +3366,7 @@ tulip_rx_intr(
|
||||
int cnt = 0;
|
||||
#endif
|
||||
|
||||
TULIP_LOCK_ASSERT(sc);
|
||||
for (;;) {
|
||||
TULIP_PERFSTART(rxget)
|
||||
tulip_desc_t *eop = ri->ri_nextin;
|
||||
@ -3499,6 +3564,7 @@ tulip_rx_intr(
|
||||
&& m0 != NULL
|
||||
#endif
|
||||
) {
|
||||
TULIP_UNLOCK(sc);
|
||||
#if !defined(TULIP_COPY_RXDATA)
|
||||
ms->m_pkthdr.len = total_len;
|
||||
ms->m_pkthdr.rcvif = ifp;
|
||||
@ -3511,6 +3577,7 @@ tulip_rx_intr(
|
||||
(*ifp->if_input)(ifp, m0);
|
||||
m0 = ms;
|
||||
#endif /* ! TULIP_COPY_RXDATA */
|
||||
TULIP_LOCK(sc);
|
||||
}
|
||||
ms = m0;
|
||||
}
|
||||
@ -3597,6 +3664,7 @@ tulip_tx_intr(
|
||||
int xmits = 0;
|
||||
int descs = 0;
|
||||
|
||||
TULIP_LOCK_ASSERT(sc);
|
||||
while (ri->ri_free < ri->ri_max) {
|
||||
u_int32_t d_flag;
|
||||
|
||||
@ -3729,6 +3797,7 @@ tulip_print_abnormal_interrupt(
|
||||
u_int32_t mask;
|
||||
const char thrsh[] = "72|128\0\0\0" "96|256\0\0\0" "128|512\0\0" "160|1024";
|
||||
|
||||
TULIP_LOCK_ASSERT(sc);
|
||||
csr &= (1 << (sizeof(tulip_status_bits)/sizeof(tulip_status_bits[0]))) - 1;
|
||||
if_printf(sc->tulip_ifp, "abnormal interrupt:");
|
||||
for (sep = " ", mask = 1; mask <= csr; mask <<= 1, msgp++) {
|
||||
@ -3756,6 +3825,7 @@ tulip_intr_handler(
|
||||
TULIP_PERFSTART(intr)
|
||||
u_int32_t csr;
|
||||
|
||||
TULIP_LOCK_ASSERT(sc);
|
||||
while ((csr = TULIP_CSR_READ(sc, csr_status)) & sc->tulip_intrmask) {
|
||||
TULIP_CSR_WRITE(sc, csr_status, csr);
|
||||
|
||||
@ -3852,10 +3922,12 @@ tulip_intr_shared(
|
||||
tulip_softc_t * sc = arg;
|
||||
|
||||
for (; sc != NULL; sc = sc->tulip_slaves) {
|
||||
TULIP_LOCK(sc);
|
||||
#if defined(TULIP_DEBUG)
|
||||
sc->tulip_dbg.dbg_intrs++;
|
||||
#endif
|
||||
tulip_intr_handler(sc);
|
||||
TULIP_UNLOCK(sc);
|
||||
}
|
||||
}
|
||||
|
||||
@ -3865,10 +3937,12 @@ tulip_intr_normal(
|
||||
{
|
||||
tulip_softc_t * sc = (tulip_softc_t *) arg;
|
||||
|
||||
TULIP_LOCK(sc);
|
||||
#if defined(TULIP_DEBUG)
|
||||
sc->tulip_dbg.dbg_intrs++;
|
||||
#endif
|
||||
tulip_intr_handler(sc);
|
||||
TULIP_UNLOCK(sc);
|
||||
}
|
||||
|
||||
static struct mbuf *
|
||||
@ -3946,6 +4020,7 @@ tulip_txput(
|
||||
struct mbuf *m0;
|
||||
#endif
|
||||
|
||||
TULIP_LOCK_ASSERT(sc);
|
||||
#if defined(TULIP_DEBUG)
|
||||
if ((sc->tulip_cmdmode & TULIP_CMD_TXRUN) == 0) {
|
||||
if_printf(sc->tulip_ifp, "txput%s: tx not running\n",
|
||||
@ -4254,7 +4329,9 @@ tulip_txput_setup(
|
||||
{
|
||||
tulip_ringinfo_t * const ri = &sc->tulip_txinfo;
|
||||
tulip_desc_t *nextout;
|
||||
|
||||
|
||||
TULIP_LOCK_ASSERT(sc);
|
||||
|
||||
/*
|
||||
* We will transmit, at most, one setup packet per call to ifstart.
|
||||
*/
|
||||
@ -4343,14 +4420,14 @@ tulip_ifioctl(
|
||||
TULIP_PERFSTART(ifioctl)
|
||||
tulip_softc_t * const sc = (tulip_softc_t *)ifp->if_softc;
|
||||
struct ifreq *ifr = (struct ifreq *) data;
|
||||
int s;
|
||||
int error = 0;
|
||||
|
||||
s = splimp();
|
||||
switch (cmd) {
|
||||
case SIOCSIFFLAGS: {
|
||||
TULIP_LOCK(sc);
|
||||
tulip_addr_filter(sc); /* reinit multicast filter */
|
||||
tulip_init(sc);
|
||||
TULIP_UNLOCK(sc);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -4365,8 +4442,10 @@ tulip_ifioctl(
|
||||
/*
|
||||
* Update multicast listeners
|
||||
*/
|
||||
TULIP_LOCK(sc);
|
||||
tulip_addr_filter(sc); /* reset multicast filtering */
|
||||
tulip_init(sc);
|
||||
TULIP_UNLOCK(sc);
|
||||
error = 0;
|
||||
break;
|
||||
}
|
||||
@ -4375,11 +4454,13 @@ tulip_ifioctl(
|
||||
/*
|
||||
* Set the interface MTU.
|
||||
*/
|
||||
TULIP_LOCK(sc);
|
||||
if (ifr->ifr_mtu > ETHERMTU) {
|
||||
error = EINVAL;
|
||||
break;
|
||||
}
|
||||
ifp->if_mtu = ifr->ifr_mtu;
|
||||
TULIP_UNLOCK(sc);
|
||||
break;
|
||||
|
||||
#ifdef SIOCGADDRROM
|
||||
@ -4400,7 +4481,6 @@ tulip_ifioctl(
|
||||
}
|
||||
}
|
||||
|
||||
splx(s);
|
||||
TULIP_PERFEND(ifioctl);
|
||||
return error;
|
||||
}
|
||||
@ -4412,25 +4492,35 @@ tulip_ifstart(
|
||||
TULIP_PERFSTART(ifstart)
|
||||
tulip_softc_t * const sc = (tulip_softc_t *)ifp->if_softc;
|
||||
|
||||
if (sc->tulip_ifp->if_flags & IFF_RUNNING) {
|
||||
|
||||
if ((sc->tulip_flags & (TULIP_WANTSETUP|TULIP_TXPROBE_ACTIVE)) == TULIP_WANTSETUP)
|
||||
tulip_txput_setup(sc);
|
||||
|
||||
while (!IFQ_DRV_IS_EMPTY(&sc->tulip_ifp->if_snd)) {
|
||||
struct mbuf *m;
|
||||
IFQ_DRV_DEQUEUE(&sc->tulip_ifp->if_snd, m);
|
||||
if(m == NULL)
|
||||
break;
|
||||
if ((m = tulip_txput(sc, m)) != NULL) {
|
||||
IFQ_DRV_PREPEND(&sc->tulip_ifp->if_snd, m);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (ifp->if_flags & IFF_RUNNING) {
|
||||
TULIP_LOCK(sc);
|
||||
tulip_start(sc);
|
||||
TULIP_UNLOCK(sc);
|
||||
}
|
||||
|
||||
TULIP_PERFEND(ifstart);
|
||||
}
|
||||
|
||||
static void
|
||||
tulip_start(tulip_softc_t * const sc)
|
||||
{
|
||||
struct mbuf *m;
|
||||
|
||||
TULIP_LOCK_ASSERT(sc);
|
||||
|
||||
if ((sc->tulip_flags & (TULIP_WANTSETUP|TULIP_TXPROBE_ACTIVE)) == TULIP_WANTSETUP)
|
||||
tulip_txput_setup(sc);
|
||||
|
||||
while (!IFQ_DRV_IS_EMPTY(&sc->tulip_ifp->if_snd)) {
|
||||
IFQ_DRV_DEQUEUE(&sc->tulip_ifp->if_snd, m);
|
||||
if(m == NULL)
|
||||
break;
|
||||
if ((m = tulip_txput(sc, m)) != NULL) {
|
||||
IFQ_DRV_PREPEND(&sc->tulip_ifp->if_snd, m);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Even though this routine runs at device spl, it does not break
|
||||
@ -4445,9 +4535,13 @@ tulip_ifwatchdog(
|
||||
{
|
||||
TULIP_PERFSTART(ifwatchdog)
|
||||
tulip_softc_t * const sc = (tulip_softc_t *)ifp->if_softc;
|
||||
|
||||
#if defined(TULIP_DEBUG)
|
||||
u_int32_t rxintrs = sc->tulip_dbg.dbg_rxintrs - sc->tulip_dbg.dbg_last_rxintrs;
|
||||
u_int32_t rxintrs;
|
||||
#endif
|
||||
|
||||
TULIP_LOCK(sc);
|
||||
#if defined(TULIP_DEBUG)
|
||||
rxintrs = sc->tulip_dbg.dbg_rxintrs - sc->tulip_dbg.dbg_last_rxintrs;
|
||||
if (rxintrs > sc->tulip_dbg.dbg_high_rxintrs_hz)
|
||||
sc->tulip_dbg.dbg_high_rxintrs_hz = rxintrs;
|
||||
sc->tulip_dbg.dbg_last_rxintrs = sc->tulip_dbg.dbg_rxintrs;
|
||||
@ -4512,6 +4606,7 @@ tulip_ifwatchdog(
|
||||
TULIP_PERFMERGE(sc, perf_txintr);
|
||||
TULIP_PERFMERGE(sc, perf_rxintr);
|
||||
TULIP_PERFMERGE(sc, perf_rxget);
|
||||
TULIP_UNLOCK(sc);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -4532,12 +4627,15 @@ tulip_attach(
|
||||
/* XXX: driver name/unit should be set some other way */
|
||||
if_initname(ifp, "de", sc->tulip_unit);
|
||||
ifp->if_softc = sc;
|
||||
ifp->if_flags = IFF_BROADCAST|IFF_SIMPLEX|IFF_MULTICAST|IFF_NEEDSGIANT;
|
||||
ifp->if_flags = IFF_BROADCAST|IFF_SIMPLEX|IFF_MULTICAST;
|
||||
ifp->if_ioctl = tulip_ifioctl;
|
||||
ifp->if_start = tulip_ifstart;
|
||||
ifp->if_watchdog = tulip_ifwatchdog;
|
||||
ifp->if_timer = 1;
|
||||
ifp->if_init = tulip_ifinit;
|
||||
IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen);
|
||||
ifp->if_snd.ifq_drv_maxlen = ifqmaxlen;
|
||||
IFQ_SET_READY(&ifp->if_snd);
|
||||
|
||||
if_printf(ifp, "%s%s pass %d.%d%s\n",
|
||||
sc->tulip_boardid,
|
||||
@ -4547,6 +4645,7 @@ tulip_attach(
|
||||
(sc->tulip_features & (TULIP_HAVE_ISVSROM|TULIP_HAVE_OKSROM))
|
||||
== TULIP_HAVE_ISVSROM ? " (invalid EESPROM checksum)" : "");
|
||||
|
||||
TULIP_LOCK(sc);
|
||||
#if defined(__alpha__)
|
||||
/*
|
||||
* In case the SRM console told us about a bogus media,
|
||||
@ -4564,11 +4663,9 @@ tulip_attach(
|
||||
tulip_ifmedia_add(sc);
|
||||
|
||||
tulip_reset(sc);
|
||||
TULIP_UNLOCK(sc);
|
||||
|
||||
ether_ifattach(sc->tulip_ifp, sc->tulip_enaddr);
|
||||
IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen);
|
||||
ifp->if_snd.ifq_drv_maxlen = ifqmaxlen;
|
||||
IFQ_SET_READY(&ifp->if_snd);
|
||||
}
|
||||
|
||||
#if defined(TULIP_BUS_DMA)
|
||||
@ -4916,6 +5013,9 @@ tulip_pci_attach(device_t dev)
|
||||
sc->tulip_csrs_bsh = rman_get_bushandle(res);
|
||||
csr_base = 0;
|
||||
|
||||
mtx_init(TULIP_MUTEX(sc), MTX_NETWORK_LOCK, device_get_nameunit(dev),
|
||||
MTX_DEF);
|
||||
callout_init(&sc->tulip_callout, CALLOUT_MPSAFE);
|
||||
tulips[unit] = sc;
|
||||
|
||||
tulip_initcsrs(sc, csr_base + csroffset, csrsize);
|
||||
@ -4923,6 +5023,7 @@ tulip_pci_attach(device_t dev)
|
||||
#if defined(TULIP_BUS_DMA)
|
||||
if ((retval = tulip_busdma_init(sc)) != 0) {
|
||||
printf("error initing bus_dma: %d\n", retval);
|
||||
mtx_destroy(TULIP_MUTEX(sc));
|
||||
return ENXIO;
|
||||
}
|
||||
#else
|
||||
@ -4934,6 +5035,7 @@ tulip_pci_attach(device_t dev)
|
||||
free((caddr_t) sc->tulip_rxdescs, M_DEVBUF);
|
||||
if (sc->tulip_txdescs)
|
||||
free((caddr_t) sc->tulip_txdescs, M_DEVBUF);
|
||||
mtx_destroy(TULIP_MUTEX(sc));
|
||||
return ENXIO;
|
||||
}
|
||||
#endif
|
||||
@ -4949,7 +5051,10 @@ tulip_pci_attach(device_t dev)
|
||||
33MHz that comes to two microseconds but wait a
|
||||
bit longer anyways) */
|
||||
|
||||
if ((retval = tulip_read_macaddr(sc)) < 0) {
|
||||
TULIP_LOCK(sc);
|
||||
retval = tulip_read_macaddr(sc);
|
||||
TULIP_UNLOCK(sc);
|
||||
if (retval < 0) {
|
||||
device_printf(dev, "can't read ENET ROM (why=%d) (", retval);
|
||||
for (idx = 0; idx < 32; idx++)
|
||||
printf("%02x", sc->tulip_rombuf[idx]);
|
||||
@ -4959,37 +5064,41 @@ tulip_pci_attach(device_t dev)
|
||||
(sc->tulip_revinfo & 0xF0) >> 4, sc->tulip_revinfo & 0x0F);
|
||||
device_printf(dev, "address unknown\n");
|
||||
} else {
|
||||
int s;
|
||||
void (*intr_rtn)(void *) = tulip_intr_normal;
|
||||
|
||||
if (sc->tulip_features & TULIP_HAVE_SHAREDINTR)
|
||||
intr_rtn = tulip_intr_shared;
|
||||
|
||||
#if defined(__alpha__)
|
||||
sc->tulip_media = media;
|
||||
#endif
|
||||
tulip_attach(sc);
|
||||
|
||||
/* Setup interrupt last. */
|
||||
if ((sc->tulip_features & TULIP_HAVE_SLAVEDINTR) == 0) {
|
||||
void *ih;
|
||||
|
||||
rid = 0;
|
||||
res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
|
||||
RF_SHAREABLE | RF_ACTIVE);
|
||||
if (res == 0 || bus_setup_intr(dev, res, INTR_TYPE_NET,
|
||||
intr_rtn, sc, &ih)) {
|
||||
if (res == 0 || bus_setup_intr(dev, res, INTR_TYPE_NET |
|
||||
INTR_MPSAFE, intr_rtn, sc, &ih)) {
|
||||
device_printf(dev, "couldn't map interrupt\n");
|
||||
free((caddr_t) sc->tulip_rxdescs, M_DEVBUF);
|
||||
free((caddr_t) sc->tulip_txdescs, M_DEVBUF);
|
||||
ether_ifdetach(sc->tulip_ifp);
|
||||
if_free(sc->tulip_ifp);
|
||||
mtx_destroy(TULIP_MUTEX(sc));
|
||||
return ENXIO;
|
||||
}
|
||||
}
|
||||
|
||||
s = splimp();
|
||||
#if defined(__alpha__)
|
||||
sc->tulip_media = media;
|
||||
#endif
|
||||
tulip_attach(sc);
|
||||
#if defined(__alpha__)
|
||||
#if defined(__alpha__)
|
||||
TULIP_LOCK(sc);
|
||||
if (sc->tulip_media != TULIP_MEDIA_UNKNOWN)
|
||||
tulip_linkup(sc, media);
|
||||
TULIP_UNLOCK(sc);
|
||||
#endif
|
||||
splx(s);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -582,6 +582,8 @@ struct tulip_softc {
|
||||
tulip_srom_connection_t tulip_conntype;
|
||||
tulip_desc_t *tulip_rxdescs;
|
||||
tulip_desc_t *tulip_txdescs;
|
||||
struct callout tulip_callout;
|
||||
struct mtx tulip_mutex;
|
||||
};
|
||||
|
||||
#define tulip_curperfstats tulip_perfstats[TULIP_PERF_CURRENT]
|
||||
@ -975,4 +977,9 @@ TULIP_PERFREAD(void)
|
||||
&& ((u_int16_t *)a1)[1] == 0xFFFFU \
|
||||
&& ((u_int16_t *)a1)[2] == 0xFFFFU)
|
||||
|
||||
#define TULIP_MUTEX(sc) (&(sc)->tulip_mutex)
|
||||
#define TULIP_LOCK(sc) mtx_lock(TULIP_MUTEX(sc))
|
||||
#define TULIP_UNLOCK(sc) mtx_unlock(TULIP_MUTEX(sc))
|
||||
#define TULIP_LOCK_ASSERT(sc) mtx_assert(TULIP_MUTEX(sc), MA_OWNED)
|
||||
|
||||
#endif /* _DEVAR_H */
|
||||
|
193
sys/pci/if_de.c
193
sys/pci/if_de.c
@ -128,6 +128,7 @@ static void tulip_mii_writereg(tulip_softc_t * const sc, unsigned devaddr,
|
||||
static void tulip_reset(tulip_softc_t * const sc);
|
||||
static void tulip_rx_intr(tulip_softc_t * const sc);
|
||||
static int tulip_srom_decode(tulip_softc_t * const sc);
|
||||
static void tulip_start(tulip_softc_t * const sc);
|
||||
static struct mbuf *
|
||||
tulip_txput(tulip_softc_t * const sc, struct mbuf *m);
|
||||
static void tulip_txput_setup(tulip_softc_t * const sc);
|
||||
@ -137,26 +138,28 @@ tulip_timeout_callback(
|
||||
void *arg)
|
||||
{
|
||||
tulip_softc_t * const sc = arg;
|
||||
int s = splimp();
|
||||
|
||||
TULIP_PERFSTART(timeout)
|
||||
TULIP_LOCK(sc);
|
||||
|
||||
sc->tulip_flags &= ~TULIP_TIMEOUTPENDING;
|
||||
sc->tulip_probe_timeout -= 1000 / TULIP_HZ;
|
||||
(sc->tulip_boardsw->bd_media_poll)(sc, TULIP_MEDIAPOLL_TIMER);
|
||||
|
||||
TULIP_PERFEND(timeout);
|
||||
splx(s);
|
||||
TULIP_UNLOCK(sc);
|
||||
}
|
||||
|
||||
static void
|
||||
tulip_timeout(
|
||||
tulip_softc_t * const sc)
|
||||
{
|
||||
TULIP_LOCK_ASSERT(sc);
|
||||
if (sc->tulip_flags & TULIP_TIMEOUTPENDING)
|
||||
return;
|
||||
sc->tulip_flags |= TULIP_TIMEOUTPENDING;
|
||||
timeout(tulip_timeout_callback, sc, (hz + TULIP_HZ / 2) / TULIP_HZ);
|
||||
callout_reset(&sc->tulip_callout, (hz + TULIP_HZ / 2) / TULIP_HZ,
|
||||
tulip_timeout_callback, sc);
|
||||
}
|
||||
|
||||
|
||||
@ -172,6 +175,7 @@ tulip_txprobe(
|
||||
* either is connected so the transmit is the only way
|
||||
* to verify the connectivity.
|
||||
*/
|
||||
TULIP_LOCK_ASSERT(sc);
|
||||
MGETHDR(m, M_DONTWAIT, MT_DATA);
|
||||
if (m == NULL)
|
||||
return 0;
|
||||
@ -207,6 +211,7 @@ tulip_media_set(
|
||||
{
|
||||
const tulip_media_info_t *mi = sc->tulip_mediums[media];
|
||||
|
||||
TULIP_LOCK_ASSERT(sc);
|
||||
if (mi == NULL)
|
||||
return;
|
||||
|
||||
@ -299,6 +304,7 @@ tulip_linkup(
|
||||
tulip_softc_t * const sc,
|
||||
tulip_media_t media)
|
||||
{
|
||||
TULIP_LOCK_ASSERT(sc);
|
||||
if ((sc->tulip_flags & TULIP_LINKUP) == 0)
|
||||
sc->tulip_flags |= TULIP_PRINTLINKUP;
|
||||
sc->tulip_flags |= TULIP_LINKUP;
|
||||
@ -354,6 +360,7 @@ tulip_media_print(
|
||||
{
|
||||
struct ifnet *ifp = sc->tulip_ifp;
|
||||
|
||||
TULIP_LOCK_ASSERT(sc);
|
||||
if ((sc->tulip_flags & TULIP_LINKUP) == 0)
|
||||
return;
|
||||
if (sc->tulip_flags & TULIP_PRINTMEDIA) {
|
||||
@ -376,6 +383,8 @@ tulip_21140_gpr_media_sense(
|
||||
tulip_media_t last_media = TULIP_MEDIA_UNKNOWN;
|
||||
tulip_media_t media;
|
||||
|
||||
TULIP_LOCK_ASSERT(sc);
|
||||
|
||||
/*
|
||||
* If one of the media blocks contained a default media flag,
|
||||
* use that.
|
||||
@ -438,6 +447,7 @@ tulip_media_link_monitor(
|
||||
const tulip_media_info_t * const mi = sc->tulip_mediums[sc->tulip_media];
|
||||
tulip_link_status_t linkup = TULIP_LINK_DOWN;
|
||||
|
||||
TULIP_LOCK_ASSERT(sc);
|
||||
if (mi == NULL) {
|
||||
#if defined(DIAGNOSTIC) || defined(TULIP_DEBUG)
|
||||
panic("tulip_media_link_monitor: %s: botch at line %d\n",
|
||||
@ -548,6 +558,7 @@ tulip_media_poll(
|
||||
{
|
||||
struct ifnet *ifp = sc->tulip_ifp;
|
||||
|
||||
TULIP_LOCK_ASSERT(sc);
|
||||
#if defined(TULIP_DEBUG)
|
||||
sc->tulip_dbg.dbg_events[event]++;
|
||||
#endif
|
||||
@ -835,6 +846,7 @@ static void
|
||||
tulip_media_select(
|
||||
tulip_softc_t * const sc)
|
||||
{
|
||||
TULIP_LOCK_ASSERT(sc);
|
||||
if (sc->tulip_features & TULIP_HAVE_GPR) {
|
||||
TULIP_CSR_WRITE(sc, csr_gp, TULIP_GP_PINSET|sc->tulip_gpinit);
|
||||
DELAY(10);
|
||||
@ -859,6 +871,7 @@ tulip_21040_mediainfo_init(
|
||||
tulip_softc_t * const sc,
|
||||
tulip_media_t media)
|
||||
{
|
||||
TULIP_LOCK_ASSERT(sc);
|
||||
sc->tulip_cmdmode |= TULIP_CMD_CAPTREFFCT|TULIP_CMD_THRSHLD160
|
||||
|TULIP_CMD_BACKOFFCTR;
|
||||
sc->tulip_ifp->if_baudrate = 10000000;
|
||||
@ -882,6 +895,7 @@ static void
|
||||
tulip_21040_media_probe(
|
||||
tulip_softc_t * const sc)
|
||||
{
|
||||
TULIP_LOCK_ASSERT(sc);
|
||||
tulip_21040_mediainfo_init(sc, TULIP_MEDIA_UNKNOWN);
|
||||
return;
|
||||
}
|
||||
@ -890,6 +904,7 @@ static void
|
||||
tulip_21040_10baset_only_media_probe(
|
||||
tulip_softc_t * const sc)
|
||||
{
|
||||
TULIP_LOCK_ASSERT(sc);
|
||||
tulip_21040_mediainfo_init(sc, TULIP_MEDIA_10BASET);
|
||||
tulip_media_set(sc, TULIP_MEDIA_10BASET);
|
||||
sc->tulip_media = TULIP_MEDIA_10BASET;
|
||||
@ -899,6 +914,7 @@ static void
|
||||
tulip_21040_10baset_only_media_select(
|
||||
tulip_softc_t * const sc)
|
||||
{
|
||||
TULIP_LOCK_ASSERT(sc);
|
||||
sc->tulip_flags |= TULIP_LINKUP;
|
||||
if (sc->tulip_media == TULIP_MEDIA_10BASET_FD) {
|
||||
sc->tulip_cmdmode |= TULIP_CMD_FULLDUPLEX;
|
||||
@ -914,6 +930,7 @@ static void
|
||||
tulip_21040_auibnc_only_media_probe(
|
||||
tulip_softc_t * const sc)
|
||||
{
|
||||
TULIP_LOCK_ASSERT(sc);
|
||||
tulip_21040_mediainfo_init(sc, TULIP_MEDIA_AUIBNC);
|
||||
sc->tulip_flags |= TULIP_SQETEST|TULIP_LINKUP;
|
||||
tulip_media_set(sc, TULIP_MEDIA_AUIBNC);
|
||||
@ -924,6 +941,7 @@ static void
|
||||
tulip_21040_auibnc_only_media_select(
|
||||
tulip_softc_t * const sc)
|
||||
{
|
||||
TULIP_LOCK_ASSERT(sc);
|
||||
tulip_media_set(sc, TULIP_MEDIA_AUIBNC);
|
||||
sc->tulip_cmdmode &= ~TULIP_CMD_FULLDUPLEX;
|
||||
}
|
||||
@ -955,6 +973,7 @@ tulip_21041_mediainfo_init(
|
||||
{
|
||||
tulip_media_info_t * const mi = sc->tulip_mediainfo;
|
||||
|
||||
TULIP_LOCK_ASSERT(sc);
|
||||
#ifdef notyet
|
||||
if (sc->tulip_revinfo >= 0x20) {
|
||||
TULIP_MEDIAINFO_SIA_INIT(sc, &mi[0], 21041P2, 10BASET);
|
||||
@ -974,6 +993,7 @@ static void
|
||||
tulip_21041_media_probe(
|
||||
tulip_softc_t * const sc)
|
||||
{
|
||||
TULIP_LOCK_ASSERT(sc);
|
||||
sc->tulip_ifp->if_baudrate = 10000000;
|
||||
sc->tulip_cmdmode |= TULIP_CMD_CAPTREFFCT|TULIP_CMD_ENHCAPTEFFCT
|
||||
|TULIP_CMD_THRSHLD160|TULIP_CMD_BACKOFFCTR;
|
||||
@ -988,6 +1008,7 @@ tulip_21041_media_poll(
|
||||
{
|
||||
u_int32_t sia_status;
|
||||
|
||||
TULIP_LOCK_ASSERT(sc);
|
||||
#if defined(TULIP_DEBUG)
|
||||
sc->tulip_dbg.dbg_events[event]++;
|
||||
#endif
|
||||
@ -1209,6 +1230,8 @@ tulip_mii_phy_readspecific(
|
||||
TULIP_MEDIA_UNKNOWN
|
||||
};
|
||||
|
||||
TULIP_LOCK_ASSERT(sc);
|
||||
|
||||
/*
|
||||
* Don't read phy specific registers if link is not up.
|
||||
*/
|
||||
@ -1258,6 +1281,7 @@ tulip_mii_get_phyaddr(
|
||||
{
|
||||
unsigned phyaddr;
|
||||
|
||||
TULIP_LOCK_ASSERT(sc);
|
||||
for (phyaddr = 1; phyaddr < 32; phyaddr++) {
|
||||
unsigned status = tulip_mii_readreg(sc, phyaddr, PHYREG_STATUS);
|
||||
if (status == 0 || status == 0xFFFF || status < PHYSTS_10BASET)
|
||||
@ -1280,6 +1304,7 @@ tulip_mii_map_abilities(
|
||||
tulip_softc_t * const sc,
|
||||
unsigned abilities)
|
||||
{
|
||||
TULIP_LOCK_ASSERT(sc);
|
||||
sc->tulip_abilities = abilities;
|
||||
if (abilities & PHYSTS_100BASETX_FD) {
|
||||
sc->tulip_probe_media = TULIP_MEDIA_100BASETX_FD;
|
||||
@ -1306,6 +1331,7 @@ tulip_mii_autonegotiate(
|
||||
{
|
||||
struct ifnet *ifp = sc->tulip_ifp;
|
||||
|
||||
TULIP_LOCK_ASSERT(sc);
|
||||
switch (sc->tulip_probe_state) {
|
||||
case TULIP_PROBE_MEDIATEST:
|
||||
case TULIP_PROBE_INACTIVE: {
|
||||
@ -1406,6 +1432,7 @@ tulip_2114x_media_preset(
|
||||
const tulip_media_info_t *mi = NULL;
|
||||
tulip_media_t media = sc->tulip_media;
|
||||
|
||||
TULIP_LOCK_ASSERT(sc);
|
||||
if (sc->tulip_probe_state == TULIP_PROBE_INACTIVE)
|
||||
media = sc->tulip_media;
|
||||
else
|
||||
@ -1496,6 +1523,7 @@ tulip_21140_mediainit(
|
||||
unsigned gpdata,
|
||||
unsigned cmdmode)
|
||||
{
|
||||
TULIP_LOCK_ASSERT(sc);
|
||||
sc->tulip_mediums[media] = mip;
|
||||
mip->mi_type = TULIP_MEDIAINFO_GPR;
|
||||
mip->mi_cmdmode = cmdmode;
|
||||
@ -1508,6 +1536,7 @@ tulip_21140_evalboard_media_probe(
|
||||
{
|
||||
tulip_media_info_t *mip = sc->tulip_mediainfo;
|
||||
|
||||
TULIP_LOCK_ASSERT(sc);
|
||||
sc->tulip_gpinit = TULIP_GP_EB_PINS;
|
||||
sc->tulip_gpdata = TULIP_GP_EB_INIT;
|
||||
TULIP_CSR_WRITE(sc, csr_gp, TULIP_GP_EB_PINS);
|
||||
@ -1554,6 +1583,7 @@ tulip_21140_accton_media_probe(
|
||||
tulip_media_info_t *mip = sc->tulip_mediainfo;
|
||||
unsigned gpdata;
|
||||
|
||||
TULIP_LOCK_ASSERT(sc);
|
||||
sc->tulip_gpinit = TULIP_GP_EB_PINS;
|
||||
sc->tulip_gpdata = TULIP_GP_EB_INIT;
|
||||
TULIP_CSR_WRITE(sc, csr_gp, TULIP_GP_EB_PINS);
|
||||
@ -1608,6 +1638,7 @@ tulip_21140_smc9332_media_probe(
|
||||
tulip_media_info_t *mip = sc->tulip_mediainfo;
|
||||
int idx, cnt = 0;
|
||||
|
||||
TULIP_LOCK_ASSERT(sc);
|
||||
TULIP_CSR_WRITE(sc, csr_command, TULIP_CMD_PORTSELECT|TULIP_CMD_MUSTBEONE);
|
||||
TULIP_CSR_WRITE(sc, csr_busmode, TULIP_BUSMODE_SWRESET);
|
||||
DELAY(10); /* Wait 10 microseconds (actually 50 PCI cycles but at
|
||||
@ -1664,6 +1695,7 @@ tulip_21140_cogent_em100_media_probe(
|
||||
tulip_media_info_t *mip = sc->tulip_mediainfo;
|
||||
u_int32_t cmdmode = TULIP_CSR_READ(sc, csr_command);
|
||||
|
||||
TULIP_LOCK_ASSERT(sc);
|
||||
sc->tulip_gpinit = TULIP_GP_EM100_PINS;
|
||||
sc->tulip_gpdata = TULIP_GP_EM100_INIT;
|
||||
TULIP_CSR_WRITE(sc, csr_gp, TULIP_GP_EM100_PINS);
|
||||
@ -1711,6 +1743,7 @@ tulip_21140_znyx_zx34x_media_probe(
|
||||
tulip_media_info_t *mip = sc->tulip_mediainfo;
|
||||
int cnt10 = 0, cnt100 = 0, idx;
|
||||
|
||||
TULIP_LOCK_ASSERT(sc);
|
||||
sc->tulip_gpinit = TULIP_GP_ZX34X_PINS;
|
||||
sc->tulip_gpdata = TULIP_GP_ZX34X_INIT;
|
||||
TULIP_CSR_WRITE(sc, csr_gp, TULIP_GP_ZX34X_PINS);
|
||||
@ -1765,6 +1798,7 @@ static void
|
||||
tulip_2114x_media_probe(
|
||||
tulip_softc_t * const sc)
|
||||
{
|
||||
TULIP_LOCK_ASSERT(sc);
|
||||
sc->tulip_cmdmode |= TULIP_CMD_MUSTBEONE
|
||||
|TULIP_CMD_BACKOFFCTR|TULIP_CMD_THRSHLD72;
|
||||
}
|
||||
@ -1869,6 +1903,7 @@ tulip_mii_writebits(
|
||||
unsigned csr = TULIP_CSR_READ(sc, csr_srom_mii) & (MII_RD|MII_DOUT|MII_CLK);
|
||||
unsigned lastbit = (csr & MII_DOUT) ? msb : 0;
|
||||
|
||||
TULIP_LOCK_ASSERT(sc);
|
||||
csr |= MII_WR; MII_EMIT; /* clock low; assert write */
|
||||
|
||||
for (; bits > 0; bits--, data <<= 1) {
|
||||
@ -1889,6 +1924,7 @@ tulip_mii_turnaround(
|
||||
{
|
||||
unsigned csr = TULIP_CSR_READ(sc, csr_srom_mii) & (MII_RD|MII_DOUT|MII_CLK);
|
||||
|
||||
TULIP_LOCK_ASSERT(sc);
|
||||
if (cmd == MII_WRCMD) {
|
||||
csr |= MII_DOUT; MII_EMIT; /* clock low; change data */
|
||||
csr ^= MII_CLKON; MII_EMIT; /* clock high; data valid */
|
||||
@ -1909,6 +1945,7 @@ tulip_mii_readbits(
|
||||
unsigned csr = TULIP_CSR_READ(sc, csr_srom_mii) & (MII_RD|MII_DOUT|MII_CLK);
|
||||
int idx;
|
||||
|
||||
TULIP_LOCK_ASSERT(sc);
|
||||
for (idx = 0, data = 0; idx < 16; idx++) {
|
||||
data <<= 1; /* this is NOOP on the first pass through */
|
||||
csr ^= MII_CLKON; MII_EMIT; /* clock high; data valid */
|
||||
@ -1930,6 +1967,7 @@ tulip_mii_readreg(
|
||||
unsigned csr = TULIP_CSR_READ(sc, csr_srom_mii) & (MII_RD|MII_DOUT|MII_CLK);
|
||||
unsigned data;
|
||||
|
||||
TULIP_LOCK_ASSERT(sc);
|
||||
csr &= ~(MII_RD|MII_CLK); MII_EMIT;
|
||||
tulip_mii_writebits(sc, MII_PREAMBLE, 32);
|
||||
tulip_mii_writebits(sc, MII_RDCMD, 8);
|
||||
@ -1953,6 +1991,8 @@ tulip_mii_writereg(
|
||||
unsigned data)
|
||||
{
|
||||
unsigned csr = TULIP_CSR_READ(sc, csr_srom_mii) & (MII_RD|MII_DOUT|MII_CLK);
|
||||
|
||||
TULIP_LOCK_ASSERT(sc);
|
||||
csr &= ~(MII_RD|MII_CLK); MII_EMIT;
|
||||
tulip_mii_writebits(sc, MII_PREAMBLE, 32);
|
||||
tulip_mii_writebits(sc, MII_WRCMD, 8);
|
||||
@ -1975,6 +2015,7 @@ static void
|
||||
tulip_identify_dec_nic(
|
||||
tulip_softc_t * const sc)
|
||||
{
|
||||
TULIP_LOCK_ASSERT(sc);
|
||||
strcpy(sc->tulip_boardid, "DEC ");
|
||||
#define D0 4
|
||||
if (sc->tulip_chipid <= TULIP_21040)
|
||||
@ -1992,6 +2033,8 @@ tulip_identify_znyx_nic(
|
||||
tulip_softc_t * const sc)
|
||||
{
|
||||
unsigned id = 0;
|
||||
|
||||
TULIP_LOCK_ASSERT(sc);
|
||||
strcpy(sc->tulip_boardid, "ZNYX ZX3XX ");
|
||||
if (sc->tulip_chipid == TULIP_21140 || sc->tulip_chipid == TULIP_21140A) {
|
||||
unsigned znyx_ptr;
|
||||
@ -2088,6 +2131,7 @@ tulip_identify_smc_nic(
|
||||
int auibnc = 0, utp = 0;
|
||||
char *cp;
|
||||
|
||||
TULIP_LOCK_ASSERT(sc);
|
||||
strcpy(sc->tulip_boardid, "SMC ");
|
||||
if (sc->tulip_chipid == TULIP_21041)
|
||||
return;
|
||||
@ -2133,6 +2177,7 @@ static void
|
||||
tulip_identify_cogent_nic(
|
||||
tulip_softc_t * const sc)
|
||||
{
|
||||
TULIP_LOCK_ASSERT(sc);
|
||||
strcpy(sc->tulip_boardid, "Cogent ");
|
||||
if (sc->tulip_chipid == TULIP_21140 || sc->tulip_chipid == TULIP_21140A) {
|
||||
if (sc->tulip_rombuf[32] == TULIP_COGENT_EM100TX_ID) {
|
||||
@ -2169,6 +2214,7 @@ static void
|
||||
tulip_identify_accton_nic(
|
||||
tulip_softc_t * const sc)
|
||||
{
|
||||
TULIP_LOCK_ASSERT(sc);
|
||||
strcpy(sc->tulip_boardid, "ACCTON ");
|
||||
switch (sc->tulip_chipid) {
|
||||
case TULIP_21140A:
|
||||
@ -2199,6 +2245,7 @@ static void
|
||||
tulip_identify_asante_nic(
|
||||
tulip_softc_t * const sc)
|
||||
{
|
||||
TULIP_LOCK_ASSERT(sc);
|
||||
strcpy(sc->tulip_boardid, "Asante ");
|
||||
if ((sc->tulip_chipid == TULIP_21140 || sc->tulip_chipid == TULIP_21140A)
|
||||
&& sc->tulip_boardsw != &tulip_2114x_isv_boardsw) {
|
||||
@ -2255,6 +2302,7 @@ static void
|
||||
tulip_identify_compex_nic(
|
||||
tulip_softc_t * const sc)
|
||||
{
|
||||
TULIP_LOCK_ASSERT(sc);
|
||||
strcpy(sc->tulip_boardid, "COMPEX ");
|
||||
if (sc->tulip_chipid == TULIP_21140A) {
|
||||
int root_unit;
|
||||
@ -2303,6 +2351,7 @@ tulip_srom_decode(
|
||||
const u_int8_t *dp;
|
||||
u_int32_t leaf_offset, blocks, data;
|
||||
|
||||
TULIP_LOCK_ASSERT(sc);
|
||||
for (idx1 = 0; idx1 < shp->sh_adapter_count; idx1++, saip++) {
|
||||
if (shp->sh_adapter_count == 1)
|
||||
break;
|
||||
@ -2882,6 +2931,7 @@ tulip_ifmedia_add(
|
||||
tulip_media_t media;
|
||||
int medias = 0;
|
||||
|
||||
TULIP_LOCK_ASSERT(sc);
|
||||
for (media = TULIP_MEDIA_UNKNOWN; media < TULIP_MEDIA_MAX; media++) {
|
||||
if (sc->tulip_mediums[media] != NULL) {
|
||||
ifmedia_add(&sc->tulip_ifmedia, tulip_media_to_ifmedia[media],
|
||||
@ -2909,6 +2959,7 @@ tulip_ifmedia_change(
|
||||
{
|
||||
tulip_softc_t * const sc = (tulip_softc_t *)ifp->if_softc;
|
||||
|
||||
TULIP_LOCK(sc);
|
||||
sc->tulip_flags |= TULIP_NEEDRESET;
|
||||
sc->tulip_probe_state = TULIP_PROBE_INACTIVE;
|
||||
sc->tulip_media = TULIP_MEDIA_UNKNOWN;
|
||||
@ -2920,6 +2971,7 @@ tulip_ifmedia_change(
|
||||
sc->tulip_flags |= TULIP_PRINTMEDIA;
|
||||
sc->tulip_flags &= ~TULIP_DIDNWAY;
|
||||
tulip_linkup(sc, media);
|
||||
TULIP_UNLOCK(sc);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@ -2927,6 +2979,7 @@ tulip_ifmedia_change(
|
||||
sc->tulip_flags &= ~(TULIP_TXPROBE_ACTIVE|TULIP_WANTRXACT);
|
||||
tulip_reset(sc);
|
||||
tulip_init(sc);
|
||||
TULIP_UNLOCK(sc);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -2940,14 +2993,18 @@ tulip_ifmedia_status(
|
||||
{
|
||||
tulip_softc_t *sc = (tulip_softc_t *)ifp->if_softc;
|
||||
|
||||
if (sc->tulip_media == TULIP_MEDIA_UNKNOWN)
|
||||
TULIP_LOCK(sc);
|
||||
if (sc->tulip_media == TULIP_MEDIA_UNKNOWN) {
|
||||
TULIP_UNLOCK(sc);
|
||||
return;
|
||||
}
|
||||
|
||||
req->ifm_status = IFM_AVALID;
|
||||
if (sc->tulip_flags & TULIP_LINKUP)
|
||||
req->ifm_status |= IFM_ACTIVE;
|
||||
|
||||
req->ifm_active = tulip_media_to_ifmedia[sc->tulip_media];
|
||||
TULIP_UNLOCK(sc);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -2958,6 +3015,7 @@ tulip_addr_filter(
|
||||
u_char *addrp;
|
||||
int multicnt;
|
||||
|
||||
TULIP_LOCK_ASSERT(sc);
|
||||
sc->tulip_flags &= ~(TULIP_WANTHASHPERFECT|TULIP_WANTHASHONLY|TULIP_ALLMULTI);
|
||||
sc->tulip_flags |= TULIP_WANTSETUP|TULIP_WANTTXSTART;
|
||||
sc->tulip_cmdmode &= ~TULIP_CMD_RXRUN;
|
||||
@ -3103,6 +3161,8 @@ tulip_reset(
|
||||
tulip_desc_t *di;
|
||||
u_int32_t inreset = (sc->tulip_flags & TULIP_INRESET);
|
||||
|
||||
TULIP_LOCK_ASSERT(sc);
|
||||
|
||||
/*
|
||||
* Brilliant. Simply brilliant. When switching modes/speeds
|
||||
* on a 2114*, you need to set the appriopriate MII/PCS/SCL/PS
|
||||
@ -3242,9 +3302,13 @@ tulip_reset(
|
||||
|
||||
static void
|
||||
tulip_ifinit(
|
||||
void * sc)
|
||||
void *arg)
|
||||
{
|
||||
tulip_init((tulip_softc_t *)sc);
|
||||
tulip_softc_t *sc = (tulip_softc_t *)arg;
|
||||
|
||||
TULIP_LOCK(sc);
|
||||
tulip_init(sc);
|
||||
TULIP_UNLOCK(sc);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -3302,6 +3366,7 @@ tulip_rx_intr(
|
||||
int cnt = 0;
|
||||
#endif
|
||||
|
||||
TULIP_LOCK_ASSERT(sc);
|
||||
for (;;) {
|
||||
TULIP_PERFSTART(rxget)
|
||||
tulip_desc_t *eop = ri->ri_nextin;
|
||||
@ -3499,6 +3564,7 @@ tulip_rx_intr(
|
||||
&& m0 != NULL
|
||||
#endif
|
||||
) {
|
||||
TULIP_UNLOCK(sc);
|
||||
#if !defined(TULIP_COPY_RXDATA)
|
||||
ms->m_pkthdr.len = total_len;
|
||||
ms->m_pkthdr.rcvif = ifp;
|
||||
@ -3511,6 +3577,7 @@ tulip_rx_intr(
|
||||
(*ifp->if_input)(ifp, m0);
|
||||
m0 = ms;
|
||||
#endif /* ! TULIP_COPY_RXDATA */
|
||||
TULIP_LOCK(sc);
|
||||
}
|
||||
ms = m0;
|
||||
}
|
||||
@ -3597,6 +3664,7 @@ tulip_tx_intr(
|
||||
int xmits = 0;
|
||||
int descs = 0;
|
||||
|
||||
TULIP_LOCK_ASSERT(sc);
|
||||
while (ri->ri_free < ri->ri_max) {
|
||||
u_int32_t d_flag;
|
||||
|
||||
@ -3729,6 +3797,7 @@ tulip_print_abnormal_interrupt(
|
||||
u_int32_t mask;
|
||||
const char thrsh[] = "72|128\0\0\0" "96|256\0\0\0" "128|512\0\0" "160|1024";
|
||||
|
||||
TULIP_LOCK_ASSERT(sc);
|
||||
csr &= (1 << (sizeof(tulip_status_bits)/sizeof(tulip_status_bits[0]))) - 1;
|
||||
if_printf(sc->tulip_ifp, "abnormal interrupt:");
|
||||
for (sep = " ", mask = 1; mask <= csr; mask <<= 1, msgp++) {
|
||||
@ -3756,6 +3825,7 @@ tulip_intr_handler(
|
||||
TULIP_PERFSTART(intr)
|
||||
u_int32_t csr;
|
||||
|
||||
TULIP_LOCK_ASSERT(sc);
|
||||
while ((csr = TULIP_CSR_READ(sc, csr_status)) & sc->tulip_intrmask) {
|
||||
TULIP_CSR_WRITE(sc, csr_status, csr);
|
||||
|
||||
@ -3852,10 +3922,12 @@ tulip_intr_shared(
|
||||
tulip_softc_t * sc = arg;
|
||||
|
||||
for (; sc != NULL; sc = sc->tulip_slaves) {
|
||||
TULIP_LOCK(sc);
|
||||
#if defined(TULIP_DEBUG)
|
||||
sc->tulip_dbg.dbg_intrs++;
|
||||
#endif
|
||||
tulip_intr_handler(sc);
|
||||
TULIP_UNLOCK(sc);
|
||||
}
|
||||
}
|
||||
|
||||
@ -3865,10 +3937,12 @@ tulip_intr_normal(
|
||||
{
|
||||
tulip_softc_t * sc = (tulip_softc_t *) arg;
|
||||
|
||||
TULIP_LOCK(sc);
|
||||
#if defined(TULIP_DEBUG)
|
||||
sc->tulip_dbg.dbg_intrs++;
|
||||
#endif
|
||||
tulip_intr_handler(sc);
|
||||
TULIP_UNLOCK(sc);
|
||||
}
|
||||
|
||||
static struct mbuf *
|
||||
@ -3946,6 +4020,7 @@ tulip_txput(
|
||||
struct mbuf *m0;
|
||||
#endif
|
||||
|
||||
TULIP_LOCK_ASSERT(sc);
|
||||
#if defined(TULIP_DEBUG)
|
||||
if ((sc->tulip_cmdmode & TULIP_CMD_TXRUN) == 0) {
|
||||
if_printf(sc->tulip_ifp, "txput%s: tx not running\n",
|
||||
@ -4254,7 +4329,9 @@ tulip_txput_setup(
|
||||
{
|
||||
tulip_ringinfo_t * const ri = &sc->tulip_txinfo;
|
||||
tulip_desc_t *nextout;
|
||||
|
||||
|
||||
TULIP_LOCK_ASSERT(sc);
|
||||
|
||||
/*
|
||||
* We will transmit, at most, one setup packet per call to ifstart.
|
||||
*/
|
||||
@ -4343,14 +4420,14 @@ tulip_ifioctl(
|
||||
TULIP_PERFSTART(ifioctl)
|
||||
tulip_softc_t * const sc = (tulip_softc_t *)ifp->if_softc;
|
||||
struct ifreq *ifr = (struct ifreq *) data;
|
||||
int s;
|
||||
int error = 0;
|
||||
|
||||
s = splimp();
|
||||
switch (cmd) {
|
||||
case SIOCSIFFLAGS: {
|
||||
TULIP_LOCK(sc);
|
||||
tulip_addr_filter(sc); /* reinit multicast filter */
|
||||
tulip_init(sc);
|
||||
TULIP_UNLOCK(sc);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -4365,8 +4442,10 @@ tulip_ifioctl(
|
||||
/*
|
||||
* Update multicast listeners
|
||||
*/
|
||||
TULIP_LOCK(sc);
|
||||
tulip_addr_filter(sc); /* reset multicast filtering */
|
||||
tulip_init(sc);
|
||||
TULIP_UNLOCK(sc);
|
||||
error = 0;
|
||||
break;
|
||||
}
|
||||
@ -4375,11 +4454,13 @@ tulip_ifioctl(
|
||||
/*
|
||||
* Set the interface MTU.
|
||||
*/
|
||||
TULIP_LOCK(sc);
|
||||
if (ifr->ifr_mtu > ETHERMTU) {
|
||||
error = EINVAL;
|
||||
break;
|
||||
}
|
||||
ifp->if_mtu = ifr->ifr_mtu;
|
||||
TULIP_UNLOCK(sc);
|
||||
break;
|
||||
|
||||
#ifdef SIOCGADDRROM
|
||||
@ -4400,7 +4481,6 @@ tulip_ifioctl(
|
||||
}
|
||||
}
|
||||
|
||||
splx(s);
|
||||
TULIP_PERFEND(ifioctl);
|
||||
return error;
|
||||
}
|
||||
@ -4412,25 +4492,35 @@ tulip_ifstart(
|
||||
TULIP_PERFSTART(ifstart)
|
||||
tulip_softc_t * const sc = (tulip_softc_t *)ifp->if_softc;
|
||||
|
||||
if (sc->tulip_ifp->if_flags & IFF_RUNNING) {
|
||||
|
||||
if ((sc->tulip_flags & (TULIP_WANTSETUP|TULIP_TXPROBE_ACTIVE)) == TULIP_WANTSETUP)
|
||||
tulip_txput_setup(sc);
|
||||
|
||||
while (!IFQ_DRV_IS_EMPTY(&sc->tulip_ifp->if_snd)) {
|
||||
struct mbuf *m;
|
||||
IFQ_DRV_DEQUEUE(&sc->tulip_ifp->if_snd, m);
|
||||
if(m == NULL)
|
||||
break;
|
||||
if ((m = tulip_txput(sc, m)) != NULL) {
|
||||
IFQ_DRV_PREPEND(&sc->tulip_ifp->if_snd, m);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (ifp->if_flags & IFF_RUNNING) {
|
||||
TULIP_LOCK(sc);
|
||||
tulip_start(sc);
|
||||
TULIP_UNLOCK(sc);
|
||||
}
|
||||
|
||||
TULIP_PERFEND(ifstart);
|
||||
}
|
||||
|
||||
static void
|
||||
tulip_start(tulip_softc_t * const sc)
|
||||
{
|
||||
struct mbuf *m;
|
||||
|
||||
TULIP_LOCK_ASSERT(sc);
|
||||
|
||||
if ((sc->tulip_flags & (TULIP_WANTSETUP|TULIP_TXPROBE_ACTIVE)) == TULIP_WANTSETUP)
|
||||
tulip_txput_setup(sc);
|
||||
|
||||
while (!IFQ_DRV_IS_EMPTY(&sc->tulip_ifp->if_snd)) {
|
||||
IFQ_DRV_DEQUEUE(&sc->tulip_ifp->if_snd, m);
|
||||
if(m == NULL)
|
||||
break;
|
||||
if ((m = tulip_txput(sc, m)) != NULL) {
|
||||
IFQ_DRV_PREPEND(&sc->tulip_ifp->if_snd, m);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Even though this routine runs at device spl, it does not break
|
||||
@ -4445,9 +4535,13 @@ tulip_ifwatchdog(
|
||||
{
|
||||
TULIP_PERFSTART(ifwatchdog)
|
||||
tulip_softc_t * const sc = (tulip_softc_t *)ifp->if_softc;
|
||||
|
||||
#if defined(TULIP_DEBUG)
|
||||
u_int32_t rxintrs = sc->tulip_dbg.dbg_rxintrs - sc->tulip_dbg.dbg_last_rxintrs;
|
||||
u_int32_t rxintrs;
|
||||
#endif
|
||||
|
||||
TULIP_LOCK(sc);
|
||||
#if defined(TULIP_DEBUG)
|
||||
rxintrs = sc->tulip_dbg.dbg_rxintrs - sc->tulip_dbg.dbg_last_rxintrs;
|
||||
if (rxintrs > sc->tulip_dbg.dbg_high_rxintrs_hz)
|
||||
sc->tulip_dbg.dbg_high_rxintrs_hz = rxintrs;
|
||||
sc->tulip_dbg.dbg_last_rxintrs = sc->tulip_dbg.dbg_rxintrs;
|
||||
@ -4512,6 +4606,7 @@ tulip_ifwatchdog(
|
||||
TULIP_PERFMERGE(sc, perf_txintr);
|
||||
TULIP_PERFMERGE(sc, perf_rxintr);
|
||||
TULIP_PERFMERGE(sc, perf_rxget);
|
||||
TULIP_UNLOCK(sc);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -4532,12 +4627,15 @@ tulip_attach(
|
||||
/* XXX: driver name/unit should be set some other way */
|
||||
if_initname(ifp, "de", sc->tulip_unit);
|
||||
ifp->if_softc = sc;
|
||||
ifp->if_flags = IFF_BROADCAST|IFF_SIMPLEX|IFF_MULTICAST|IFF_NEEDSGIANT;
|
||||
ifp->if_flags = IFF_BROADCAST|IFF_SIMPLEX|IFF_MULTICAST;
|
||||
ifp->if_ioctl = tulip_ifioctl;
|
||||
ifp->if_start = tulip_ifstart;
|
||||
ifp->if_watchdog = tulip_ifwatchdog;
|
||||
ifp->if_timer = 1;
|
||||
ifp->if_init = tulip_ifinit;
|
||||
IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen);
|
||||
ifp->if_snd.ifq_drv_maxlen = ifqmaxlen;
|
||||
IFQ_SET_READY(&ifp->if_snd);
|
||||
|
||||
if_printf(ifp, "%s%s pass %d.%d%s\n",
|
||||
sc->tulip_boardid,
|
||||
@ -4547,6 +4645,7 @@ tulip_attach(
|
||||
(sc->tulip_features & (TULIP_HAVE_ISVSROM|TULIP_HAVE_OKSROM))
|
||||
== TULIP_HAVE_ISVSROM ? " (invalid EESPROM checksum)" : "");
|
||||
|
||||
TULIP_LOCK(sc);
|
||||
#if defined(__alpha__)
|
||||
/*
|
||||
* In case the SRM console told us about a bogus media,
|
||||
@ -4564,11 +4663,9 @@ tulip_attach(
|
||||
tulip_ifmedia_add(sc);
|
||||
|
||||
tulip_reset(sc);
|
||||
TULIP_UNLOCK(sc);
|
||||
|
||||
ether_ifattach(sc->tulip_ifp, sc->tulip_enaddr);
|
||||
IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen);
|
||||
ifp->if_snd.ifq_drv_maxlen = ifqmaxlen;
|
||||
IFQ_SET_READY(&ifp->if_snd);
|
||||
}
|
||||
|
||||
#if defined(TULIP_BUS_DMA)
|
||||
@ -4916,6 +5013,9 @@ tulip_pci_attach(device_t dev)
|
||||
sc->tulip_csrs_bsh = rman_get_bushandle(res);
|
||||
csr_base = 0;
|
||||
|
||||
mtx_init(TULIP_MUTEX(sc), MTX_NETWORK_LOCK, device_get_nameunit(dev),
|
||||
MTX_DEF);
|
||||
callout_init(&sc->tulip_callout, CALLOUT_MPSAFE);
|
||||
tulips[unit] = sc;
|
||||
|
||||
tulip_initcsrs(sc, csr_base + csroffset, csrsize);
|
||||
@ -4923,6 +5023,7 @@ tulip_pci_attach(device_t dev)
|
||||
#if defined(TULIP_BUS_DMA)
|
||||
if ((retval = tulip_busdma_init(sc)) != 0) {
|
||||
printf("error initing bus_dma: %d\n", retval);
|
||||
mtx_destroy(TULIP_MUTEX(sc));
|
||||
return ENXIO;
|
||||
}
|
||||
#else
|
||||
@ -4934,6 +5035,7 @@ tulip_pci_attach(device_t dev)
|
||||
free((caddr_t) sc->tulip_rxdescs, M_DEVBUF);
|
||||
if (sc->tulip_txdescs)
|
||||
free((caddr_t) sc->tulip_txdescs, M_DEVBUF);
|
||||
mtx_destroy(TULIP_MUTEX(sc));
|
||||
return ENXIO;
|
||||
}
|
||||
#endif
|
||||
@ -4949,7 +5051,10 @@ tulip_pci_attach(device_t dev)
|
||||
33MHz that comes to two microseconds but wait a
|
||||
bit longer anyways) */
|
||||
|
||||
if ((retval = tulip_read_macaddr(sc)) < 0) {
|
||||
TULIP_LOCK(sc);
|
||||
retval = tulip_read_macaddr(sc);
|
||||
TULIP_UNLOCK(sc);
|
||||
if (retval < 0) {
|
||||
device_printf(dev, "can't read ENET ROM (why=%d) (", retval);
|
||||
for (idx = 0; idx < 32; idx++)
|
||||
printf("%02x", sc->tulip_rombuf[idx]);
|
||||
@ -4959,37 +5064,41 @@ tulip_pci_attach(device_t dev)
|
||||
(sc->tulip_revinfo & 0xF0) >> 4, sc->tulip_revinfo & 0x0F);
|
||||
device_printf(dev, "address unknown\n");
|
||||
} else {
|
||||
int s;
|
||||
void (*intr_rtn)(void *) = tulip_intr_normal;
|
||||
|
||||
if (sc->tulip_features & TULIP_HAVE_SHAREDINTR)
|
||||
intr_rtn = tulip_intr_shared;
|
||||
|
||||
#if defined(__alpha__)
|
||||
sc->tulip_media = media;
|
||||
#endif
|
||||
tulip_attach(sc);
|
||||
|
||||
/* Setup interrupt last. */
|
||||
if ((sc->tulip_features & TULIP_HAVE_SLAVEDINTR) == 0) {
|
||||
void *ih;
|
||||
|
||||
rid = 0;
|
||||
res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
|
||||
RF_SHAREABLE | RF_ACTIVE);
|
||||
if (res == 0 || bus_setup_intr(dev, res, INTR_TYPE_NET,
|
||||
intr_rtn, sc, &ih)) {
|
||||
if (res == 0 || bus_setup_intr(dev, res, INTR_TYPE_NET |
|
||||
INTR_MPSAFE, intr_rtn, sc, &ih)) {
|
||||
device_printf(dev, "couldn't map interrupt\n");
|
||||
free((caddr_t) sc->tulip_rxdescs, M_DEVBUF);
|
||||
free((caddr_t) sc->tulip_txdescs, M_DEVBUF);
|
||||
ether_ifdetach(sc->tulip_ifp);
|
||||
if_free(sc->tulip_ifp);
|
||||
mtx_destroy(TULIP_MUTEX(sc));
|
||||
return ENXIO;
|
||||
}
|
||||
}
|
||||
|
||||
s = splimp();
|
||||
#if defined(__alpha__)
|
||||
sc->tulip_media = media;
|
||||
#endif
|
||||
tulip_attach(sc);
|
||||
#if defined(__alpha__)
|
||||
#if defined(__alpha__)
|
||||
TULIP_LOCK(sc);
|
||||
if (sc->tulip_media != TULIP_MEDIA_UNKNOWN)
|
||||
tulip_linkup(sc, media);
|
||||
TULIP_UNLOCK(sc);
|
||||
#endif
|
||||
splx(s);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -582,6 +582,8 @@ struct tulip_softc {
|
||||
tulip_srom_connection_t tulip_conntype;
|
||||
tulip_desc_t *tulip_rxdescs;
|
||||
tulip_desc_t *tulip_txdescs;
|
||||
struct callout tulip_callout;
|
||||
struct mtx tulip_mutex;
|
||||
};
|
||||
|
||||
#define tulip_curperfstats tulip_perfstats[TULIP_PERF_CURRENT]
|
||||
@ -975,4 +977,9 @@ TULIP_PERFREAD(void)
|
||||
&& ((u_int16_t *)a1)[1] == 0xFFFFU \
|
||||
&& ((u_int16_t *)a1)[2] == 0xFFFFU)
|
||||
|
||||
#define TULIP_MUTEX(sc) (&(sc)->tulip_mutex)
|
||||
#define TULIP_LOCK(sc) mtx_lock(TULIP_MUTEX(sc))
|
||||
#define TULIP_UNLOCK(sc) mtx_unlock(TULIP_MUTEX(sc))
|
||||
#define TULIP_LOCK_ASSERT(sc) mtx_assert(TULIP_MUTEX(sc), MA_OWNED)
|
||||
|
||||
#endif /* _DEVAR_H */
|
||||
|
Loading…
Reference in New Issue
Block a user