Rewrite and simplify the ix(4) promiscuous mode/multicast setup code and
interface flag handling code in the ioctl handler.

Please test with any ix(4) adapters. Please provide a dmesg.


Index: if_ix.c
===================================================================
RCS file: /cvs/src/sys/dev/pci/if_ix.c,v
retrieving revision 1.17
diff -u -p -r1.17 if_ix.c
--- if_ix.c     29 Apr 2009 13:18:58 -0000      1.17
+++ if_ix.c     28 May 2009 00:19:10 -0000
@@ -104,9 +104,7 @@ void        ixgbe_update_stats_counters(struct 
 int    ixgbe_txeof(struct tx_ring *);
 int    ixgbe_rxeof(struct rx_ring *, int);
 void   ixgbe_rx_checksum(struct ix_softc *, uint32_t, struct mbuf *);
-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
@@ -458,18 +456,14 @@ ixgbe_ioctl(struct ifnet * ifp, u_long c
        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:
@@ -485,7 +479,7 @@ ixgbe_ioctl(struct ifnet * ifp, u_long c
        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;
@@ -611,9 +605,6 @@ ixgbe_init(void *arg)
 
        ixgbe_initialize_transmit_units(sc);
 
-       /* Setup Multicast table */
-       ixgbe_set_multi(sc);
-
        /*
         * If we are resetting MTU smaller than 2K
         * drop to small RX buffers
@@ -632,6 +623,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 */
        if (sc->hw.phy.media_type == ixgbe_media_type_copper)
@@ -956,100 +950,55 @@ xmit_fail:
 
 }
 
-void
-ixgbe_set_promisc(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);
-       reg_rctl &= (~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.
- *
- **********************************************************************/
 #define IXGBE_RAR_ENTRIES 16
 
 void
-ixgbe_set_multi(struct ix_softc *sc)
+ixgbe_iff(struct ix_softc *sc)
 {
+       struct ifnet *ifp = &sc->arpcom.ac_if;
+       struct arpcom *ac = &sc->arpcom;
        uint32_t        fctrl;
        uint8_t mta[MAX_NUM_MULTICAST_ADDRESSES * IXGBE_ETH_LENGTH_OF_ADDRESS];
        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");
 
        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)
Index: if_ix.h
===================================================================
RCS file: /cvs/src/sys/dev/pci/if_ix.h,v
retrieving revision 1.4
diff -u -p -r1.4 if_ix.h
--- if_ix.h     24 Apr 2009 12:54:15 -0000      1.4
+++ if_ix.h     28 May 2009 00:13:32 -0000
@@ -255,7 +255,6 @@ struct ix_softc {
        struct ifmedia  media;
        struct timeout  timer;
        int             msix;
-       int             if_flags;
 
        struct mutex    core_mtx;
 

-- 
This message has been scanned for viruses and
dangerous content by MailScanner, and is
believed to be clean.

Reply via email to