Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/dev/pci Fix a bug that IFF_ALLMULTI is almost always set.



details:   https://anonhg.NetBSD.org/src/rev/747ddffa4d56
branches:  trunk
changeset: 461259:747ddffa4d56
user:      msaitoh <msaitoh%NetBSD.org@localhost>
date:      Thu Nov 21 09:12:30 2019 +0000

description:
Fix a bug that IFF_ALLMULTI is almost always set.

 OpenBSD's ac_multirangecnt is not NetBSD's ec_multicnt.

diffstat:

 sys/dev/pci/if_age.c |   48 ++++++++++-------
 sys/dev/pci/if_alc.c |   46 ++++++++++------
 sys/dev/pci/if_ale.c |  138 ++++++++++++++++++++++++++++++++------------------
 sys/dev/pci/if_cas.c |   88 ++++++++++++++++++--------------
 4 files changed, 194 insertions(+), 126 deletions(-)

diffs (truncated from 572 to 300 lines):

diff -r 26601d759a2f -r 747ddffa4d56 sys/dev/pci/if_age.c
--- a/sys/dev/pci/if_age.c      Thu Nov 21 07:56:58 2019 +0000
+++ b/sys/dev/pci/if_age.c      Thu Nov 21 09:12:30 2019 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: if_age.c,v 1.63 2019/11/21 06:22:09 msaitoh Exp $ */
+/*     $NetBSD: if_age.c,v 1.64 2019/11/21 09:12:30 msaitoh Exp $ */
 /*     $OpenBSD: if_age.c,v 1.1 2009/01/16 05:00:34 kevlo Exp $        */
 
 /*-
@@ -31,7 +31,7 @@
 /* Driver for Attansic Technology Corp. L1 Gigabit Ethernet. */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_age.c,v 1.63 2019/11/21 06:22:09 msaitoh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_age.c,v 1.64 2019/11/21 09:12:30 msaitoh Exp $");
 
 #include "vlan.h"
 
@@ -2275,27 +2275,37 @@
         */
        rxcfg |= MAC_CFG_BCAST;
 
-       if (ifp->if_flags & IFF_PROMISC || ec->ec_multicnt > 0) {
-               ifp->if_flags |= IFF_ALLMULTI;
-               if (ifp->if_flags & IFF_PROMISC)
+       /* Program new filter. */
+       if ((ifp->if_flags & IFF_PROMISC) != 0)
+               goto update;
+
+       memset(mchash, 0, sizeof(mchash));
+
+       ETHER_LOCK(ec);
+       ETHER_FIRST_MULTI(step, ec, enm);
+       while (enm != NULL) {
+               if (memcmp(enm->enm_addrlo, enm->enm_addrhi, ETHER_ADDR_LEN)) {
+                       /* XXX Use ETHER_F_ALLMULTI in future. */
+                       ifp->if_flags |= IFF_ALLMULTI;
+                       ETHER_UNLOCK(ec);
+                       goto update;
+               }
+               crc = ether_crc32_be(enm->enm_addrlo, ETHER_ADDR_LEN);
+               mchash[crc >> 31] |= 1 << ((crc >> 26) & 0x1f);
+               ETHER_NEXT_MULTI(step, enm);
+       }
+       ETHER_UNLOCK(ec);
+
+update:
+       if ((ifp->if_flags & (IFF_PROMISC | IFF_ALLMULTI)) != 0) {
+               if (ifp->if_flags & IFF_PROMISC) {
                        rxcfg |= MAC_CFG_PROMISC;
-               else
+                       /* XXX Use ETHER_F_ALLMULTI in future. */
+                       ifp->if_flags |= IFF_ALLMULTI;
+               } else
                        rxcfg |= MAC_CFG_ALLMULTI;
                mchash[0] = mchash[1] = 0xFFFFFFFF;
-       } else {
-               /* Program new filter. */
-               memset(mchash, 0, sizeof(mchash));
-
-               ETHER_LOCK(ec);
-               ETHER_FIRST_MULTI(step, ec, enm);
-               while (enm != NULL) {
-                       crc = ether_crc32_be(enm->enm_addrlo, ETHER_ADDR_LEN);
-                       mchash[crc >> 31] |= 1 << ((crc >> 26) & 0x1f);
-                       ETHER_NEXT_MULTI(step, enm);
-               }
-               ETHER_UNLOCK(ec);
        }
-
        CSR_WRITE_4(sc, AGE_MAR0, mchash[0]);
        CSR_WRITE_4(sc, AGE_MAR1, mchash[1]);
        CSR_WRITE_4(sc, AGE_MAC_CFG, rxcfg);
diff -r 26601d759a2f -r 747ddffa4d56 sys/dev/pci/if_alc.c
--- a/sys/dev/pci/if_alc.c      Thu Nov 21 07:56:58 2019 +0000
+++ b/sys/dev/pci/if_alc.c      Thu Nov 21 09:12:30 2019 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: if_alc.c,v 1.43 2019/10/30 07:26:28 msaitoh Exp $      */
+/*     $NetBSD: if_alc.c,v 1.44 2019/11/21 09:12:30 msaitoh Exp $      */
 /*     $OpenBSD: if_alc.c,v 1.1 2009/08/08 09:31:13 kevlo Exp $        */
 /*-
  * Copyright (c) 2009, Pyun YongHyeon <yongari%FreeBSD.org@localhost>
@@ -3443,27 +3443,37 @@
         */
        rxcfg |= MAC_CFG_BCAST;
 
-       if (ifp->if_flags & IFF_PROMISC || ec->ec_multicnt > 0) {
-               ifp->if_flags |= IFF_ALLMULTI;
-               if (ifp->if_flags & IFF_PROMISC)
+       /* Program new filter. */
+       if ((ifp->if_flags & IFF_PROMISC) != 0)
+               goto update;
+
+       memset(mchash, 0, sizeof(mchash));
+
+       ETHER_LOCK(ec);
+       ETHER_FIRST_MULTI(step, ec, enm);
+       while (enm != NULL) {
+               if (memcmp(enm->enm_addrlo, enm->enm_addrhi, ETHER_ADDR_LEN)) {
+                       /* XXX Use ETHER_F_ALLMULTI in future. */
+                       ifp->if_flags |= IFF_ALLMULTI;
+                       ETHER_UNLOCK(ec);
+                       goto update;
+               }
+               crc = ether_crc32_be(enm->enm_addrlo, ETHER_ADDR_LEN);
+               mchash[crc >> 31] |= 1 << ((crc >> 26) & 0x1f);
+               ETHER_NEXT_MULTI(step, enm);
+       }
+       ETHER_UNLOCK(ec);
+
+update:
+       if ((ifp->if_flags & (IFF_PROMISC | IFF_ALLMULTI)) != 0) {
+               if (ifp->if_flags & IFF_PROMISC) {
                        rxcfg |= MAC_CFG_PROMISC;
-               else
+                       /* XXX Use ETHER_F_ALLMULTI in future. */
+                       ifp->if_flags |= IFF_ALLMULTI;
+               } else
                        rxcfg |= MAC_CFG_ALLMULTI;
                mchash[0] = mchash[1] = 0xFFFFFFFF;
-       } else {
-               /* Program new filter. */
-               memset(mchash, 0, sizeof(mchash));
-
-               ETHER_LOCK(ec);
-               ETHER_FIRST_MULTI(step, ec, enm);
-               while (enm != NULL) {
-                       crc = ether_crc32_be(enm->enm_addrlo, ETHER_ADDR_LEN);
-                       mchash[crc >> 31] |= 1 << ((crc >> 26) & 0x1f);
-                       ETHER_NEXT_MULTI(step, enm);
-               }
-               ETHER_UNLOCK(ec);
        }
-
        CSR_WRITE_4(sc, ALC_MAR0, mchash[0]);
        CSR_WRITE_4(sc, ALC_MAR1, mchash[1]);
        CSR_WRITE_4(sc, ALC_MAC_CFG, rxcfg);
diff -r 26601d759a2f -r 747ddffa4d56 sys/dev/pci/if_ale.c
--- a/sys/dev/pci/if_ale.c      Thu Nov 21 07:56:58 2019 +0000
+++ b/sys/dev/pci/if_ale.c      Thu Nov 21 09:12:30 2019 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: if_ale.c,v 1.34 2019/10/30 07:26:28 msaitoh Exp $      */
+/*     $NetBSD: if_ale.c,v 1.35 2019/11/21 09:12:30 msaitoh Exp $      */
 
 /*-
  * Copyright (c) 2008, Pyun YongHyeon <yongari%FreeBSD.org@localhost>
@@ -32,7 +32,7 @@
 /* Driver for Atheros AR8121/AR8113/AR8114 PCIe Ethernet. */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_ale.c,v 1.34 2019/10/30 07:26:28 msaitoh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_ale.c,v 1.35 2019/11/21 09:12:30 msaitoh Exp $");
 
 #include "vlan.h"
 
@@ -136,10 +136,9 @@
        if (phy != sc->ale_phyaddr)
                return -1;
 
+#if 1
        if (sc->ale_flags & ALE_FLAG_FASTETHER) {
                switch (reg) {
-               case MII_100T2CR:
-               case MII_100T2SR:
                case MII_EXTSR:
                        *val = 0;
                        return 0;
@@ -147,6 +146,7 @@
                        break;
                }
        }
+#endif
 
        CSR_WRITE_4(sc, ALE_MDIO, MDIO_OP_EXECUTE | MDIO_OP_READ |
            MDIO_SUP_PREAMBLE | MDIO_CLK_25_4 | MDIO_REG_ADDR(reg));
@@ -177,19 +177,23 @@
        if (phy != sc->ale_phyaddr)
                return -1;
 
+#if 1
        if (sc->ale_flags & ALE_FLAG_FASTETHER) {
+#if 0
                switch (reg) {
-               case MII_100T2CR:
-               case MII_100T2SR:
                case MII_EXTSR:
+                       printf("%s: XXXX write EXTSR with %04hx\n", __func__,
+                               val);
                        return 0;
                default:
                        break;
                }
+#endif
        }
+#endif
 
        CSR_WRITE_4(sc, ALE_MDIO, MDIO_OP_EXECUTE | MDIO_OP_WRITE |
-           (val & MDIO_DATA_MASK) << MDIO_DATA_SHIFT |
+                   ((uint32_t)val & MDIO_DATA_MASK) << MDIO_DATA_SHIFT |
            MDIO_SUP_PREAMBLE | MDIO_CLK_25_4 | MDIO_REG_ADDR(reg));
        for (i = ALE_PHY_TIMEOUT; i > 0; i--) {
                DELAY(5);
@@ -255,6 +259,9 @@
        struct ale_softc *sc = ifp->if_softc;
        struct mii_data *mii = &sc->sc_miibus;
 
+       if ((ifp->if_flags & IFF_UP) == 0)
+               return;
+
        mii_pollstat(mii);
        ifmr->ifm_status = mii->mii_media_status;
        ifmr->ifm_active = mii->mii_media_active;
@@ -267,6 +274,7 @@
        struct mii_data *mii = &sc->sc_miibus;
        int error;
 
+       printf("%s: called\n", __func__);
        if (mii->mii_instance != 0) {
                struct mii_softc *miisc;
 
@@ -335,16 +343,20 @@
 void
 ale_phy_reset(struct ale_softc *sc)
 {
+//     int error;
+
+       printf("%s: called\n", __func__);
        /* Reset magic from Linux. */
        CSR_WRITE_2(sc, ALE_GPHY_CTRL,
            GPHY_CTRL_HIB_EN | GPHY_CTRL_HIB_PULSE | GPHY_CTRL_SEL_ANA_RESET |
            GPHY_CTRL_PHY_PLL_ON);
-       DELAY(1000);
+       DELAY(2000);
        CSR_WRITE_2(sc, ALE_GPHY_CTRL,
            GPHY_CTRL_EXT_RESET | GPHY_CTRL_HIB_EN | GPHY_CTRL_HIB_PULSE |
            GPHY_CTRL_SEL_ANA_RESET | GPHY_CTRL_PHY_PLL_ON);
-       DELAY(1000);
+       DELAY(2000);
 
+#define        ATPHY_INT_CTRL          0x12
 #define        ATPHY_DBG_ADDR          0x1D
 #define        ATPHY_DBG_DATA          0x1E
 
@@ -374,9 +386,10 @@
        ale_miibus_writereg(sc->sc_dev, sc->ale_phyaddr,
            ATPHY_DBG_DATA, 0x2C46);
 
+       DELAY(1000);
+
 #undef ATPHY_DBG_ADDR
 #undef ATPHY_DBG_DATA
-       DELAY(1000);
 }
 
 void
@@ -389,7 +402,7 @@
        const char *intrstr;
        struct ifnet *ifp;
        struct mii_data * const mii = &sc->sc_miibus;
-       pcireg_t memtype;
+       pcireg_t memtype, pcireg, capoff;
        int mii_flags, error = 0;
        uint32_t rxf_len, txf_len;
        const char *chipname;
@@ -423,6 +436,26 @@
                return;
        }
 
+       pcireg = pci_conf_read(sc->sc_pct, sc->sc_pcitag,
+           PCI_COMMAND_STATUS_REG);
+       printf("%s: command = %08x\n", __func__, pcireg);
+       pcireg |= PCI_COMMAND_MEM_ENABLE | PCI_COMMAND_MASTER_ENABLE;
+       pci_conf_write(sc->sc_pct, sc->sc_pcitag, PCI_COMMAND_STATUS_REG, pcireg);
+
+#if 1
+       if (pci_get_capability(pa->pa_pc, pa->pa_tag, PCI_CAP_PWRMGMT, &capoff,
+           NULL) != 0) {
+               pcireg = pci_conf_read(pa->pa_pc, pa->pa_tag,
+                   PCI_COMMAND_STATUS_REG);
+               printf("%s: CSR was %#08x\n", __func__, pcireg);
+               pcireg = pci_conf_read(pa->pa_pc, pa->pa_tag,
+                   capoff + PCI_PMCSR);
+               printf("%s: PMCSR was %#08x\n", __func__, pcireg);
+               pci_conf_write(pa->pa_pc, pa->pa_tag, capoff + PCI_PMCSR, 0);
+               delay(1000);
+       }
+#endif
+
        if (pci_intr_map(pa, &ih) != 0) {
                aprint_error_dev(self, "could not map interrupt\n");
                goto fail;
@@ -446,11 +479,6 @@
        sc->ale_phyaddr = ALE_PHY_ADDR;
 
        /* Reset PHY. */
-       ale_phy_reset(sc);
-
-       /* Reset the ethernet controller. */
-       ale_reset(sc);
-



Home | Main Index | Thread Index | Old Index