diff options
Diffstat (limited to 'sys/dev')
-rw-r--r-- | sys/dev/pci/if_ix.c | 125 |
1 files changed, 38 insertions, 87 deletions
diff --git a/sys/dev/pci/if_ix.c b/sys/dev/pci/if_ix.c index 9649ff8af94..a364fd8f4df 100644 --- a/sys/dev/pci/if_ix.c +++ b/sys/dev/pci/if_ix.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_ix.c,v 1.64 2012/07/05 14:47:28 mikeb Exp $ */ +/* $OpenBSD: if_ix.c,v 1.65 2012/07/06 11:08:44 mikeb Exp $ */ /****************************************************************************** @@ -123,9 +123,7 @@ void ixgbe_update_stats_counters(struct ix_softc *); int ixgbe_txeof(struct tx_ring *); int ixgbe_rxeof(struct ix_queue *, int); void ixgbe_rx_checksum(uint32_t, struct mbuf *, uint32_t); -void ixgbe_set_promisc(struct ix_softc *); -void ixgbe_disable_promisc(struct ix_softc *); -void ixgbe_set_multi(struct ix_softc *); +void ixgbe_iff(struct ix_softc *); #ifdef IX_DEBUG void ixgbe_print_hw_stats(struct ix_softc *); #endif @@ -517,18 +515,14 @@ ixgbe_ioctl(struct ifnet * ifp, u_long command, caddr_t data) case SIOCSIFFLAGS: IOCTL_DEBUGOUT("ioctl: SIOCSIFFLAGS (Set Interface Flags)"); if (ifp->if_flags & IFF_UP) { - if ((ifp->if_flags & IFF_RUNNING)) { - if ((ifp->if_flags ^ sc->if_flags) & - (IFF_PROMISC | IFF_ALLMULTI)) { - ixgbe_disable_promisc(sc); - ixgbe_set_promisc(sc); - } - } else + if (ifp->if_flags & IFF_RUNNING) + error = ENETRESET; + else ixgbe_init(sc); - } else + } else { if (ifp->if_flags & IFF_RUNNING) ixgbe_stop(sc); - sc->if_flags = ifp->if_flags; + } break; case SIOCSIFMEDIA: @@ -544,7 +538,7 @@ ixgbe_ioctl(struct ifnet * ifp, u_long command, caddr_t data) if (error == ENETRESET) { if (ifp->if_flags & IFF_RUNNING) { ixgbe_disable_intr(sc); - ixgbe_set_multi(sc); + ixgbe_iff(sc); ixgbe_enable_intr(sc); } error = 0; @@ -664,9 +658,6 @@ ixgbe_init(void *arg) ixgbe_hw0(&sc->hw, init_hw); ixgbe_initialize_transmit_units(sc); - /* Setup Multicast table */ - ixgbe_set_multi(sc); - /* Determine the correct buffer size for jumbo/headersplit */ if (sc->max_frame_size <= 2048) sc->rx_mbuf_sz = MCLBYTES; @@ -689,6 +680,9 @@ ixgbe_init(void *arg) /* Configure RX settings */ ixgbe_initialize_receive_units(sc); + /* Program promiscuous mode and multicast filters. */ + ixgbe_iff(sc); + gpie = IXGBE_READ_REG(&sc->hw, IXGBE_GPIE); /* Enable Fan Failure Interrupt */ @@ -1169,99 +1163,56 @@ xmit_fail: } void -ixgbe_set_promisc(struct ix_softc *sc) +ixgbe_iff(struct ix_softc *sc) { - - uint32_t reg_rctl; struct ifnet *ifp = &sc->arpcom.ac_if; - - reg_rctl = IXGBE_READ_REG(&sc->hw, IXGBE_FCTRL); - - if (ifp->if_flags & IFF_PROMISC) { - reg_rctl |= (IXGBE_FCTRL_UPE | IXGBE_FCTRL_MPE); - IXGBE_WRITE_REG(&sc->hw, IXGBE_FCTRL, reg_rctl); - } else if (ifp->if_flags & IFF_ALLMULTI) { - reg_rctl |= IXGBE_FCTRL_MPE; - reg_rctl &= ~IXGBE_FCTRL_UPE; - IXGBE_WRITE_REG(&sc->hw, IXGBE_FCTRL, reg_rctl); - } - return; -} - -void -ixgbe_disable_promisc(struct ix_softc * sc) -{ - uint32_t reg_rctl; - - reg_rctl = IXGBE_READ_REG(&sc->hw, IXGBE_FCTRL); - reg_rctl &= ~(IXGBE_FCTRL_UPE | IXGBE_FCTRL_MPE); - IXGBE_WRITE_REG(&sc->hw, IXGBE_FCTRL, reg_rctl); - - return; -} - - -/********************************************************************* - * Multicast Update - * - * This routine is called whenever multicast address list is updated. - * - **********************************************************************/ -void -ixgbe_set_multi(struct ix_softc *sc) -{ + struct arpcom *ac = &sc->arpcom; uint32_t fctrl; uint8_t *mta; uint8_t *update_ptr; struct ether_multi *enm; struct ether_multistep step; int mcnt = 0; - struct ifnet *ifp = &sc->arpcom.ac_if; - IOCTL_DEBUGOUT("ixgbe_set_multi: begin"); + IOCTL_DEBUGOUT("ixgbe_iff: begin"); mta = sc->mta; bzero(mta, sizeof(uint8_t) * IXGBE_ETH_LENGTH_OF_ADDRESS * MAX_NUM_MULTICAST_ADDRESSES); fctrl = IXGBE_READ_REG(&sc->hw, IXGBE_FCTRL); - fctrl |= (IXGBE_FCTRL_UPE | IXGBE_FCTRL_MPE); - if (ifp->if_flags & IFF_PROMISC) - fctrl |= (IXGBE_FCTRL_UPE | IXGBE_FCTRL_MPE); - else if (ifp->if_flags & IFF_ALLMULTI) { - fctrl |= IXGBE_FCTRL_MPE; - fctrl &= ~IXGBE_FCTRL_UPE; - } else - fctrl &= ~(IXGBE_FCTRL_UPE | IXGBE_FCTRL_MPE); - - IXGBE_WRITE_REG(&sc->hw, IXGBE_FCTRL, fctrl); + fctrl &= ~(IXGBE_FCTRL_MPE | IXGBE_FCTRL_UPE); + ifp->if_flags &= ~IFF_ALLMULTI; - ETHER_FIRST_MULTI(step, &sc->arpcom, enm); - while (enm != NULL) { - if (bcmp(enm->enm_addrlo, enm->enm_addrhi, ETHER_ADDR_LEN)) { - ifp->if_flags |= IFF_ALLMULTI; - mcnt = MAX_NUM_MULTICAST_ADDRESSES; + if (ifp->if_flags & IFF_PROMISC || ac->ac_multirangecnt > 0 || + ac->ac_multicnt > MAX_NUM_MULTICAST_ADDRESSES) { + ifp->if_flags |= IFF_ALLMULTI; + fctrl |= IXGBE_FCTRL_MPE; + if (ifp->if_flags & IFF_PROMISC) + fctrl |= IXGBE_FCTRL_UPE; + } else { + ETHER_FIRST_MULTI(step, &sc->arpcom, enm); + while (enm != NULL) { + bcopy(enm->enm_addrlo, + &mta[mcnt * IXGBE_ETH_LENGTH_OF_ADDRESS], + IXGBE_ETH_LENGTH_OF_ADDRESS); + mcnt++; + + ETHER_NEXT_MULTI(step, enm); } - if (mcnt == MAX_NUM_MULTICAST_ADDRESSES) - break; - bcopy(enm->enm_addrlo, - &mta[mcnt * IXGBE_ETH_LENGTH_OF_ADDRESS], - IXGBE_ETH_LENGTH_OF_ADDRESS); - mcnt++; - ETHER_NEXT_MULTI(step, enm); - } - update_ptr = mta; - ixgbe_hw(&sc->hw, update_mc_addr_list, - update_ptr, mcnt, ixgbe_mc_array_itr); + update_ptr = mta; + ixgbe_hw(&sc->hw, update_mc_addr_list, + update_ptr, mcnt, ixgbe_mc_array_itr); + } - return; + IXGBE_WRITE_REG(&sc->hw, IXGBE_FCTRL, fctrl); } /* * This is an iterator function now needed by the multicast * shared code. It simply feeds the shared code routine the - * addresses in the array of ixgbe_set_multi() one by one. + * addresses in the array of ixgbe_iff() one by one. */ uint8_t * ixgbe_mc_array_itr(struct ixgbe_hw *hw, uint8_t **update_ptr, uint32_t *vmdq) @@ -1708,7 +1659,7 @@ void ixgbe_config_link(struct ix_softc *sc) { uint32_t autoneg, err = 0; - int sfp, negotiate; + int sfp, negotiate = FALSE; switch (sc->hw.phy.type) { case ixgbe_phy_sfp_avago: |