#include <sys/param.h>
__KERNEL_RCSID(0, "$NetBSD: dp83905.c,v 1.4 2007/10/19 11:59:50 ad Exp $");
#include <sys/device.h>
#include <sys/mbuf.h>
#include <sys/socket.h>
#include <sys/systm.h>
#include <net/if.h>
#include <net/if_ether.h>
#include <net/if_media.h>
#include <sys/bus.h>
#include <dev/ic/dp8390reg.h>
#include <dev/ic/dp8390var.h>
#include <dev/ic/dp83905reg.h>
#include <dev/ic/dp83905var.h>
int
dp83905_mediachange(struct dp8390_softc *sc)
{
dp8390_reset(sc);
return (0);
}
void
dp83905_mediastatus(struct dp8390_softc *sc, struct ifmediareq *ifmr)
{
bus_space_tag_t nict = sc->sc_regt;
bus_space_handle_t nich = sc->sc_regh;
u_int8_t mcrb;
bus_space_write_1(nict, nich, ED_P0_CR,
ED_CR_RD2 | ED_CR_PAGE_0 | ED_CR_STA);
mcrb = bus_space_read_1(nict, nich, DP83905_MCRB);
bus_space_write_1(nict, nich, ED_P0_CR,
ED_CR_RD2 | ED_CR_PAGE_0 | ED_CR_STA);
switch (mcrb & DP83905_MCRB_PHY_MASK) {
case DP83905_MCRB_PHY_10_T:
case DP83905_MCRB_PHY_TPI_NONSPEC:
ifmr->ifm_active = IFM_ETHER | IFM_10_T;
ifmr->ifm_status = IFM_AVALID;
if (mcrb & DP83905_MCRB_GDLNK)
ifmr->ifm_status |= IFM_ACTIVE;
break;
case DP83905_MCRB_PHY_10_2:
ifmr->ifm_active = IFM_ETHER | IFM_10_2;
break;
case DP83905_MCRB_PHY_AUI:
ifmr->ifm_active = IFM_ETHER | IFM_10_5;
break;
}
}
void dp83905_init_card(struct dp8390_softc *sc)
{
struct ifmedia *ifm = &sc->sc_media;
bus_space_tag_t nict = sc->sc_regt;
bus_space_handle_t nich = sc->sc_regh;
u_int8_t mcrb;
switch (IFM_SUBTYPE(ifm->ifm_cur->ifm_media)) {
case IFM_AUTO:
mcrb = bus_space_read_1(nict, nich, DP83905_MCRB);
mcrb &= ~(DP83905_MCRB_PHY_MASK | DP83905_MCRB_GDLNK |
DP83905_MCRB_BE);
mcrb |= DP83905_MCRB_PHY_10_T;
bus_space_write_1(nict, nich, DP83905_MCRB, mcrb);
mcrb = bus_space_read_1(nict, nich, DP83905_MCRB);
if (mcrb & DP83905_MCRB_GDLNK)
break;
case IFM_10_2:
mcrb = bus_space_read_1(nict, nich, DP83905_MCRB);
mcrb &= ~(DP83905_MCRB_PHY_MASK | DP83905_MCRB_GDLNK |
DP83905_MCRB_BE);
mcrb |= DP83905_MCRB_PHY_10_2;
bus_space_write_1(nict, nich, DP83905_MCRB, mcrb);
bus_space_read_1(nict, nich, DP83905_MCRB);
break;
case IFM_10_T:
mcrb = bus_space_read_1(nict, nich, DP83905_MCRB);
mcrb &= ~(DP83905_MCRB_PHY_MASK | DP83905_MCRB_GDLNK |
DP83905_MCRB_BE);
mcrb |= DP83905_MCRB_PHY_10_T;
bus_space_write_1(nict, nich, DP83905_MCRB, mcrb);
bus_space_read_1(nict, nich, DP83905_MCRB);
break;
case IFM_10_5:
mcrb = bus_space_read_1(nict, nich, DP83905_MCRB);
mcrb &= ~(DP83905_MCRB_PHY_MASK | DP83905_MCRB_GDLNK |
DP83905_MCRB_BE);
mcrb |= DP83905_MCRB_PHY_AUI;
bus_space_write_1(nict, nich, DP83905_MCRB, mcrb);
bus_space_read_1(nict, nich, DP83905_MCRB);
break;
}
}