Multicast support.
This commit is contained in:
parent
c0ca4781ed
commit
8bd9c69e11
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: if_iy.c,v 1.25 1998/07/28 16:02:34 is Exp $ */
|
||||
/* $NetBSD: if_iy.c,v 1.26 1998/07/30 16:40:19 is Exp $ */
|
||||
/* #define IYDEBUG */
|
||||
/* #define IYMEMDEBUG */
|
||||
/*-
|
||||
@ -119,6 +119,7 @@ struct iy_softc {
|
||||
int tx_start, tx_end, tx_last;
|
||||
int rx_start;
|
||||
|
||||
int doing_mc_setup;
|
||||
#ifdef IYDEBUG
|
||||
int sc_debug;
|
||||
#endif
|
||||
@ -145,16 +146,14 @@ void iy_find_mem_size __P((struct iy_softc *));
|
||||
void iyrint __P((struct iy_softc *));
|
||||
void iytint __P((struct iy_softc *));
|
||||
void iyxmit __P((struct iy_softc *));
|
||||
static void iy_mc_setup __P((struct iy_softc *));
|
||||
static void iy_mc_reset __P((struct iy_softc *));
|
||||
void iyget __P((struct iy_softc *, bus_space_tag_t, bus_space_handle_t, int));
|
||||
void iyprobemem __P((struct iy_softc *));
|
||||
static __inline void eepromwritebit __P((bus_space_tag_t, bus_space_handle_t,
|
||||
int));
|
||||
static __inline int eepromreadbit __P((bus_space_tag_t, bus_space_handle_t));
|
||||
/*
|
||||
* void iymeminit __P((void *, struct iy_softc *));
|
||||
* static int iy_mc_setup __P((struct iy_softc *, void *));
|
||||
* static void iy_mc_reset __P((struct iy_softc *));
|
||||
*/
|
||||
|
||||
#ifdef IYDEBUGX
|
||||
void print_rbd __P((volatile struct iy_recv_buf_desc *));
|
||||
|
||||
@ -303,8 +302,10 @@ iyattach(parent, self, aux)
|
||||
bcopy(sc->sc_dev.dv_xname, ifp->if_xname, IFNAMSIZ);
|
||||
ifp->if_softc = sc;
|
||||
ifp->if_start = iystart;
|
||||
ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_NOTRAILERS;
|
||||
/* XXX todo: | IFF_MULTICAST */
|
||||
ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_NOTRAILERS
|
||||
| IFF_MULTICAST;
|
||||
|
||||
sc->doing_mc_setup = 0;
|
||||
|
||||
ifp->if_ioctl = iyioctl;
|
||||
ifp->if_watchdog = iywatchdog;
|
||||
@ -450,10 +451,6 @@ struct iy_softc *sc;
|
||||
bus_space_write_1(iot, ioh, REG1,
|
||||
temp | XMT_CHAIN_INT | XMT_CHAIN_ERRSTOP | RCV_DISCARD_BAD);
|
||||
|
||||
#ifdef IYUSEOLD
|
||||
temp = bus_space_read_1(iot, ioh, RECV_MODES_REG);
|
||||
bus_space_write_1(iot, ioh, RECV_MODES_REG, temp | MATCH_BRDCST);
|
||||
#else
|
||||
if (ifp->if_flags & (IFF_PROMISC|IFF_ALLMULTI)) {
|
||||
temp = MATCH_ALL;
|
||||
} else if (sc->sc_ethercom.ec_multicnt) {
|
||||
@ -462,14 +459,15 @@ struct iy_softc *sc;
|
||||
temp = MATCH_ID;
|
||||
|
||||
bus_space_write_1(iot, ioh, RECV_MODES_REG, temp);
|
||||
#endif
|
||||
|
||||
#ifdef IYDEBUG
|
||||
printf("%s: RECV_MODES were %b set to %b\n",
|
||||
sc->sc_dev.dv_xname,
|
||||
temp, "\020\1PRMSC\2NOBRDST\3SEECRC\4LENGTH\5NOSaIns\6MultiIA",
|
||||
temp|MATCH_BRDCST,
|
||||
"\020\1PRMSC\2NOBRDST\3SEECRC\4LENGTH\5NOSaIns\6MultiIA");
|
||||
printf("%s: RECV_MODES set to %b\n", sc->sc_dev.dv_xname,
|
||||
temp, "\020\1PRMSC\2NOBRDST\3SEECRC\4LENGTH\5NOSaIns\6MultiIA");
|
||||
#endif
|
||||
/* XXX VOODOO */
|
||||
temp = bus_space_read_1(iot, ioh, MEDIA_SELECT);
|
||||
bus_space_write_1(iot, ioh, MEDIA_SELECT, temp);
|
||||
/* XXX END OF VOODOO */
|
||||
|
||||
|
||||
delay(500000); /* for the hardware to test for the connector */
|
||||
@ -589,10 +587,11 @@ struct ifnet *ifp;
|
||||
#ifdef IYDEBUG
|
||||
printf("iystart called\n");
|
||||
#endif
|
||||
sc = ifp->if_softc;
|
||||
|
||||
if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING)
|
||||
return;
|
||||
|
||||
sc = ifp->if_softc;
|
||||
iot = sc->sc_iot;
|
||||
ioh = sc->sc_ioh;
|
||||
|
||||
@ -870,13 +869,14 @@ iyintr(arg)
|
||||
printf("\n");
|
||||
}
|
||||
#endif
|
||||
if (((status & (RX_INT | TX_INT)) == 0))
|
||||
if ((status & (RX_INT | TX_INT)) == 0)
|
||||
return 0;
|
||||
|
||||
if (status & RX_INT) {
|
||||
iy_intr_rx(sc);
|
||||
bus_space_write_1(iot, ioh, STATUS_REG, RX_INT);
|
||||
} else if (status & TX_INT) {
|
||||
}
|
||||
if (status & TX_INT) {
|
||||
iy_intr_tx(sc);
|
||||
bus_space_write_1(iot, ioh, STATUS_REG, TX_INT);
|
||||
}
|
||||
@ -974,6 +974,7 @@ dropped:
|
||||
++ifp->if_ierrors;
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
iy_intr_rx(sc)
|
||||
struct iy_softc *sc;
|
||||
@ -1150,7 +1151,6 @@ iyioctl(ifp, cmd, data)
|
||||
#endif
|
||||
break;
|
||||
|
||||
#if 0 /* XXX */
|
||||
case SIOCADDMULTI:
|
||||
case SIOCDELMULTI:
|
||||
error = (cmd == SIOCADDMULTI) ?
|
||||
@ -1162,11 +1162,12 @@ iyioctl(ifp, cmd, data)
|
||||
* Multicast list has changed; set the hardware filter
|
||||
* accordingly.
|
||||
*/
|
||||
iy_mc_reset(sc); /* XXX */
|
||||
iyreset(sc); /* XXX can't make it work otherwise */
|
||||
iy_mc_reset(sc);
|
||||
error = 0;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
#endif /* XXX???XXX */
|
||||
case SIOCSIFMEDIA:
|
||||
case SIOCGIFMEDIA:
|
||||
error = ifmedia_ioctl(ifp, ifr, &sc->iy_ifmedia, cmd);
|
||||
@ -1210,7 +1211,91 @@ iy_mediastatus(ifp, ifmr)
|
||||
ifmr->ifm_status = IFM_AVALID | IFM_ACTIVE;
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
||||
static void
|
||||
iy_mc_setup(sc)
|
||||
struct iy_softc *sc;
|
||||
{
|
||||
struct ether_multi *enm;
|
||||
struct ether_multistep step;
|
||||
struct ethercom *ecp;
|
||||
struct ifnet *ifp;
|
||||
bus_space_tag_t iot;
|
||||
bus_space_handle_t ioh;
|
||||
int avail, last /*, end*/ , len;
|
||||
int timeout;
|
||||
u_int8_t temp;
|
||||
|
||||
|
||||
ecp = &sc->sc_ethercom;
|
||||
ifp = &ecp->ec_if;
|
||||
|
||||
iot = sc->sc_iot;
|
||||
ioh = sc->sc_ioh;
|
||||
|
||||
len = 6 * ecp->ec_multicnt + 6;
|
||||
|
||||
avail = sc->tx_start - sc->tx_end;
|
||||
if (avail <= 0)
|
||||
avail += sc->tx_size;
|
||||
printf("iy_mc_setup called, %d addresses, %d/%d bytes needed/avail\n",
|
||||
ecp->ec_multicnt, len + I595_XMT_HDRLEN, avail);
|
||||
|
||||
last = sc->rx_size;
|
||||
|
||||
bus_space_write_1(iot, ioh, 0, BANK_SEL(2));
|
||||
bus_space_write_1(iot, ioh, RECV_MODES_REG, MATCH_MULTI);
|
||||
/* XXX VOODOO */
|
||||
temp = bus_space_read_1(iot, ioh, MEDIA_SELECT);
|
||||
bus_space_write_1(iot, ioh, MEDIA_SELECT, temp);
|
||||
/* XXX END OF VOODOO */
|
||||
bus_space_write_1(iot, ioh, 0, BANK_SEL(0));
|
||||
bus_space_write_2(iot, ioh, HOST_ADDR_REG, last);
|
||||
bus_space_write_2(iot, ioh, MEM_PORT_REG, MC_SETUP_CMD);
|
||||
bus_space_write_2(iot, ioh, MEM_PORT_REG, 0);
|
||||
bus_space_write_2(iot, ioh, MEM_PORT_REG, 0);
|
||||
bus_space_write_2(iot, ioh, MEM_PORT_REG, len);
|
||||
|
||||
bus_space_write_multi_2(iot, ioh, MEM_PORT_REG,
|
||||
LLADDR(ifp->if_sadl), 3);
|
||||
|
||||
ETHER_FIRST_MULTI(step, ecp, enm);
|
||||
while(enm) {
|
||||
bus_space_write_multi_2(iot, ioh, MEM_PORT_REG,
|
||||
enm->enm_addrlo, 3);
|
||||
|
||||
ETHER_NEXT_MULTI(step, enm);
|
||||
}
|
||||
bus_space_write_2(iot, ioh, XMT_ADDR_REG, last);
|
||||
bus_space_write_1(iot, ioh, 0, MC_SETUP_CMD);
|
||||
|
||||
|
||||
sc->tx_start = sc->rx_size;
|
||||
sc->tx_end = sc->rx_size + I595_XMT_HDRLEN + len;
|
||||
|
||||
for (timeout=0; timeout<100; timeout++) {
|
||||
DELAY(2);
|
||||
if ((bus_space_read_1(iot, ioh, STATUS_REG) & EXEC_INT) == 0)
|
||||
continue;
|
||||
|
||||
temp = bus_space_read_1(iot, ioh, 0);
|
||||
bus_space_write_1(iot, ioh, STATUS_REG, EXEC_INT);
|
||||
#ifdef DIAGNOSTIC
|
||||
if (temp & 0x20) {
|
||||
printf("%s: mc setup failed, %d usec\n",
|
||||
sc->sc_dev.dv_xname, timeout * 2);
|
||||
} else if ((temp & 0x0f) == 0x03) {
|
||||
printf("%s: mc setup done, %d usec\n",
|
||||
sc->sc_dev.dv_xname, timeout * 2);
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
sc->tx_start = sc->tx_end;
|
||||
sc->sc_ethercom.ec_if.if_flags &= ~IFF_OACTIVE;
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
iy_mc_reset(sc)
|
||||
struct iy_softc *sc;
|
||||
@ -1219,45 +1304,62 @@ iy_mc_reset(sc)
|
||||
struct ether_multistep step;
|
||||
struct ethercom *ecp;
|
||||
struct ifnet *ifp;
|
||||
bus_space_tag_t iot;
|
||||
bus_space_handle_t ioh;
|
||||
u_int16_t temp;
|
||||
|
||||
ecp = &sc->sc_ethercom;
|
||||
ifp = &ecp->ec_if;
|
||||
|
||||
if (ecp->ec_multicnt > 63) {
|
||||
goto needallmulti;
|
||||
iot = sc->sc_iot;
|
||||
ioh = sc->sc_ioh;
|
||||
|
||||
} else if (ec->ec_multicnt > 0) {
|
||||
if (ecp->ec_multicnt > 63) {
|
||||
ifp->if_flags |= IFF_ALLMULTI;
|
||||
|
||||
} else if (ecp->ec_multicnt > 0) {
|
||||
/*
|
||||
* Step through the list of addresses.
|
||||
*/
|
||||
ETHER_FIRST_MULTI(step, ecp, enm);
|
||||
while(enm) {
|
||||
if (bcmp(enm->enm_addrlo, enm->enm_addrhi, 6) != 0) {
|
||||
goto needallmulti;
|
||||
ifp->if_flags |= IFF_ALLMULTI;
|
||||
goto setupmulti;
|
||||
}
|
||||
ETHER_NEXT_MULTI(step, enm);
|
||||
}
|
||||
/* OK, we really need to do it now: */
|
||||
ETHER_FIRST_MULTI(step, ecp, enm);
|
||||
/*
|
||||
* XXX TBD: find a suitable place in the TX buffer for the
|
||||
* setup command, and write its header and our unicast address
|
||||
*/
|
||||
while(enm) {
|
||||
/* XXX TBD: write the next multicast address */
|
||||
ETHER_NEXT_MULTI(step, enm);
|
||||
#if 0
|
||||
if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE))
|
||||
!= IFF_RUNNING) {
|
||||
ifp->if_flags |= IFF_OACTIVE;
|
||||
sc->want_mc_setup = 1;
|
||||
return;
|
||||
}
|
||||
/* XXX TBD: write command and wait for the result */
|
||||
|
||||
#endif
|
||||
iy_mc_setup(sc);
|
||||
} else {
|
||||
/* XXX TBD: setup for no multicasts */
|
||||
ifp->if_flags &= ~IFF_ALLMULTI;
|
||||
}
|
||||
return;
|
||||
|
||||
needallmulti:
|
||||
ifp->if_flags |= IFF_ALLMULTI;
|
||||
iyioctl(ifp, SIOCSIFFLAGS, (void *)0);
|
||||
/* XXX TBD: and setup hardware for all multicasts */
|
||||
setupmulti:
|
||||
bus_space_write_1(iot, ioh, 0, BANK_SEL(2));
|
||||
if (ifp->if_flags & (IFF_PROMISC|IFF_ALLMULTI)) {
|
||||
temp = MATCH_ALL;
|
||||
} else if (sc->sc_ethercom.ec_multicnt) {
|
||||
temp = MATCH_MULTI;
|
||||
} else
|
||||
temp = MATCH_ID;
|
||||
|
||||
bus_space_write_1(iot, ioh, RECV_MODES_REG, temp);
|
||||
/* XXX VOODOO */
|
||||
temp = bus_space_read_1(iot, ioh, MEDIA_SELECT);
|
||||
bus_space_write_1(iot, ioh, MEDIA_SELECT, temp);
|
||||
/* XXX END OF VOODOO */
|
||||
|
||||
/* XXX TBD: setup hardware for all multicasts */
|
||||
bus_space_write_1(iot, ioh, 0, BANK_SEL(0));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1273,7 +1375,6 @@ print_rbd(rbd)
|
||||
rbd->mbz);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
void
|
||||
iyprobemem(sc)
|
||||
|
Loading…
Reference in New Issue
Block a user