The following diff rewrites the interface flag handling case code
for bnx(4) and updates the receive filter handling to take advantage
of ac_multirangecnt and have correct IFF_ALLMULTI handling.


Index: if_bnx.c
===================================================================
RCS file: /cvs/src/sys/dev/pci/if_bnx.c,v
retrieving revision 1.78
diff -u -p -r1.78 if_bnx.c
--- if_bnx.c    22 Apr 2009 01:17:26 -0000      1.78
+++ if_bnx.c    6 Jun 2009 10:05:01 -0000
@@ -397,7 +397,7 @@ void        bnx_disable_intr(struct bnx_softc *
 void   bnx_enable_intr(struct bnx_softc *);
 
 int    bnx_intr(void *);
-void   bnx_set_rx_mode(struct bnx_softc *);
+void   bnx_iff(struct bnx_softc *);
 void   bnx_stats_update(struct bnx_softc *);
 void   bnx_tick(void *);
 
@@ -4314,7 +4314,7 @@ bnx_init(void *xsc)
            sc->mbuf_alloc_size, sc->max_frame_size);
 
        /* Program appropriate promiscuous/multicast filtering. */
-       bnx_set_rx_mode(sc);
+       bnx_iff(sc);
 
        /* Init RX buffer descriptor chain. */
        bnx_init_rx_chain(sc);
@@ -4639,19 +4639,14 @@ bnx_ioctl(struct ifnet *ifp, u_long comm
 
        case SIOCSIFFLAGS:
                if (ifp->if_flags & IFF_UP) {
-                       if ((ifp->if_flags & IFF_RUNNING) &&
-                           ((ifp->if_flags ^ sc->bnx_if_flags) &
-                           (IFF_ALLMULTI | IFF_PROMISC)) != 0) {
-                               bnx_set_rx_mode(sc);
-                       } else {
-                               if (!(ifp->if_flags & IFF_RUNNING))
-                                       bnx_init(sc);
-                       }
+                       if (ifp->if_flags & IFF_RUNNING)
+                               error = ENETRESET;
+                       else
+                               bnx_init(sc);
                } else {
                        if (ifp->if_flags & IFF_RUNNING)
                                bnx_stop(sc);
                }
-               sc->bnx_if_flags = ifp->if_flags;
                break;
 
        case SIOCSIFMEDIA:
@@ -4668,7 +4663,7 @@ bnx_ioctl(struct ifnet *ifp, u_long comm
 
        if (error == ENETRESET) {
                if (ifp->if_flags & IFF_RUNNING)
-                       bnx_set_rx_mode(sc);
+                       bnx_iff(sc);
                error = 0;
        }
 
@@ -4837,7 +4832,7 @@ bnx_intr(void *xsc)
 /*   Nothing.                                                               */
 /****************************************************************************/
 void
-bnx_set_rx_mode(struct bnx_softc *sc)
+bnx_iff(struct bnx_softc *sc)
 {
        struct arpcom           *ac = &sc->arpcom;
        struct ifnet            *ifp = &ac->ac_if;
@@ -4851,6 +4846,7 @@ bnx_set_rx_mode(struct bnx_softc *sc)
        rx_mode = sc->rx_mode & ~(BNX_EMAC_RX_MODE_PROMISCUOUS |
            BNX_EMAC_RX_MODE_KEEP_VLAN_TAG);
        sort_mode = 1 | BNX_RPM_SORT_USER0_BC_EN;
+       ifp->if_flags &= ~IFF_ALLMULTI;
 
        /*
         * ASF/IPMI/UMP firmware requires that VLAN tag stripping
@@ -4867,13 +4863,14 @@ bnx_set_rx_mode(struct bnx_softc *sc)
        if (ifp->if_flags & IFF_PROMISC) {
                DBPRINT(sc, BNX_INFO, "Enabling promiscuous mode.\n");
 
+               ifp->if_flags |= IFF_ALLMULTI;
                /* Enable promiscuous mode. */
                rx_mode |= BNX_EMAC_RX_MODE_PROMISCUOUS;
                sort_mode |= BNX_RPM_SORT_USER0_PROM_EN;
-       } else if (ifp->if_flags & IFF_ALLMULTI) {
-allmulti:
+       } else if (ac->ac_multirangecnt > 0) {
                DBPRINT(sc, BNX_INFO, "Enabling all multicast mode.\n");
 
+               ifp->if_flags |= IFF_ALLMULTI;
                /* Enable all multicast addresses. */
                for (i = 0; i < NUM_MC_HASH_REGISTERS; i++)
                        REG_WR(sc, BNX_EMAC_MULTICAST_HASH0 + (i * 4),
@@ -4885,14 +4882,11 @@ allmulti:
 
                ETHER_FIRST_MULTI(step, ac, enm);
                while (enm != NULL) {
-                       if (bcmp(enm->enm_addrlo, enm->enm_addrhi,
-                           ETHER_ADDR_LEN)) {
-                               ifp->if_flags |= IFF_ALLMULTI;
-                               goto allmulti;
-                       }
                        h = ether_crc32_le(enm->enm_addrlo, ETHER_ADDR_LEN) &
                            0xFF;
+
                        hashes[(h & 0xE0) >> 5] |= 1 << (h & 0x1F);
+
                        ETHER_NEXT_MULTI(step, enm);
                }
 
Index: if_bnxreg.h
===================================================================
RCS file: /cvs/src/sys/dev/pci/if_bnxreg.h,v
retrieving revision 1.28
diff -u -p -r1.28 if_bnxreg.h
--- if_bnxreg.h 22 Apr 2009 00:38:04 -0000      1.28
+++ if_bnxreg.h 23 Apr 2009 06:41:47 -0000
@@ -4643,8 +4643,6 @@ struct bnx_softc {
        u_int32_t               bnx_shared_hw_cfg;
        u_int32_t               bnx_port_hw_cfg;
 
-       int                     bnx_if_flags;
-
        u_int16_t               bus_speed_mhz;          /* PCI bus speed */
        struct flash_spec       *bnx_flash_info;        /* Flash NVRAM settings 
*/
        u_int32_t               bnx_flash_size;         /* Flash NVRAM size */

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

Reply via email to