static int msk_phy_readreg(struct msk_if_softc *, int, int);
static int msk_phy_writereg(struct msk_if_softc *, int, int, int);
-static void msk_setmulti(struct msk_if_softc *);
+static void msk_rxfilter(struct msk_if_softc *);
static void msk_setvlan(struct msk_if_softc *, struct ifnet *);
-static void msk_setpromisc(struct msk_if_softc *);
static int msk_dmamem_create(device_t, bus_size_t, bus_dma_tag_t *,
void **, bus_addr_t *, bus_dmamap_t *);
}
static void
-msk_setmulti(struct msk_if_softc *sc_if)
+msk_rxfilter(struct msk_if_softc *sc_if)
{
struct msk_softc *sc;
struct ifnet *ifp;
bzero(mchash, sizeof(mchash));
mode = GMAC_READ_2(sc, sc_if->msk_port, GM_RX_CTRL);
- mode |= GM_RXCR_UCF_ENA;
- if ((ifp->if_flags & (IFF_PROMISC | IFF_ALLMULTI)) != 0) {
- if ((ifp->if_flags & IFF_PROMISC) != 0)
- mode &= ~(GM_RXCR_UCF_ENA | GM_RXCR_MCF_ENA);
- else if ((ifp->if_flags & IFF_ALLMULTI) != 0) {
- mchash[0] = 0xffff;
- mchash[1] = 0xffff;
- }
+ if ((ifp->if_flags & IFF_PROMISC) != 0) {
+ mode &= ~(GM_RXCR_UCF_ENA | GM_RXCR_MCF_ENA);
+ } else if ((ifp->if_flags & IFF_ALLMULTI) != 0) {
+ mode |= (GM_RXCR_UCF_ENA | GM_RXCR_MCF_ENA);
+ mchash[0] = 0xffff;
+ mchash[1] = 0xffff;
} else {
+ mode |= GM_RXCR_UCF_ENA;
TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
if (ifma->ifma_addr->sa_family != AF_LINK)
continue;
/* Set the corresponding bit in the hash table. */
mchash[crc >> 5] |= 1 << (crc & 0x1f);
}
- mode |= GM_RXCR_MCF_ENA;
+ if (mchash[0] != 0 || mchash[1] != 0)
+ mode |= GM_RXCR_MCF_ENA;
}
GMAC_WRITE_2(sc, sc_if->msk_port, GM_MC_ADDR_H1,
}
}
-static void
-msk_setpromisc(struct msk_if_softc *sc_if)
-{
- struct msk_softc *sc;
- struct ifnet *ifp;
- uint16_t mode;
-
- sc = sc_if->msk_softc;
- ifp = sc_if->msk_ifp;
-
- mode = GMAC_READ_2(sc, sc_if->msk_port, GM_RX_CTRL);
- if (ifp->if_flags & IFF_PROMISC)
- mode &= ~(GM_RXCR_UCF_ENA | GM_RXCR_MCF_ENA);
- else
- mode |= (GM_RXCR_UCF_ENA | GM_RXCR_MCF_ENA);
- GMAC_WRITE_2(sc, sc_if->msk_port, GM_RX_CTRL, mode);
-}
-
static int
msk_init_rx_ring(struct msk_if_softc *sc_if)
{
if (ifp->if_flags & IFF_UP) {
if (ifp->if_flags & IFF_RUNNING) {
if (((ifp->if_flags ^ sc_if->msk_if_flags)
- & IFF_PROMISC) != 0) {
- msk_setpromisc(sc_if);
- msk_setmulti(sc_if);
- }
+ & (IFF_PROMISC | IFF_ALLMULTI)) != 0)
+ msk_rxfilter(sc_if);
} else {
if (sc_if->msk_detach == 0)
msk_init(sc_if);
case SIOCADDMULTI:
case SIOCDELMULTI:
if (ifp->if_flags & IFF_RUNNING)
- msk_setmulti(sc_if);
+ msk_rxfilter(sc_if);
break;
case SIOCGIFMEDIA:
CSR_WRITE_4(sc, MR_ADDR(sc_if->msk_port, RX_GMF_CTRL_T),
GMF_OPER_ON | GMF_RX_F_FL_ON);
- /* Set promiscuous mode. */
- msk_setpromisc(sc_if);
-
- /* Set multicast filter. */
- msk_setmulti(sc_if);
+ /* Set receive filter. */
+ msk_rxfilter(sc_if);
/* Flush Rx MAC FIFO on any flow control or error. */
CSR_WRITE_4(sc, MR_ADDR(sc_if->msk_port, RX_GMF_FL_MSK),