Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 30 Aug 2010 21:15:40 +0000 (UTC)
From:      Pyun YongHyeon <yongari@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-8@freebsd.org
Subject:   svn commit: r212021 - stable/8/sys/dev/alc
Message-ID:  <201008302115.o7ULFeCf007673@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: yongari
Date: Mon Aug 30 21:15:40 2010
New Revision: 212021
URL: http://svn.freebsd.org/changeset/base/212021

Log:
  MFC r211105:
    Add support for Atheros AR8151/AR8152 PCIe gigabit/fast ethernet
    controller. These controllers are known as L1D(AR8151) and
    L2CB/B2(AR8152). This change adds supports for the following
    controllers.
     o AR8151 v1.0(L1D) gigabit ethernet controller
     o AR8151 v2.0(L1D) gigabit ethernet controller
     o AR8152 v1.1(L2CB) fast ethernet controller
     o AR8152 v2.0(L2CB2) fast ethernet controller
    These controllers have the same feature of AR8131/AR8132 and
    support improved power saving control. The user visible change at
    this moment is reduced jumbo frame size from 9KB to 6KB. Many
    thanks to Atheros for continuing to support FreeBSD.
  
    HW donated by:	Atheros Communications, Inc.

Modified:
  stable/8/sys/dev/alc/if_alc.c
  stable/8/sys/dev/alc/if_alcreg.h
  stable/8/sys/dev/alc/if_alcvar.h
Directory Properties:
  stable/8/sys/   (props changed)
  stable/8/sys/amd64/include/xen/   (props changed)
  stable/8/sys/cddl/contrib/opensolaris/   (props changed)
  stable/8/sys/contrib/dev/acpica/   (props changed)
  stable/8/sys/contrib/pf/   (props changed)
  stable/8/sys/dev/xen/xenpci/   (props changed)

Modified: stable/8/sys/dev/alc/if_alc.c
==============================================================================
--- stable/8/sys/dev/alc/if_alc.c	Mon Aug 30 21:13:08 2010	(r212020)
+++ stable/8/sys/dev/alc/if_alc.c	Mon Aug 30 21:15:40 2010	(r212021)
@@ -25,7 +25,7 @@
  * SUCH DAMAGE.
  */
 
-/* Driver for Atheros AR8131/AR8132 PCIe Ethernet. */
+/* Driver for Atheros AR813x/AR815x PCIe Ethernet. */
 
 #include <sys/cdefs.h>
 __FBSDID("$FreeBSD$");
@@ -98,18 +98,23 @@ TUNABLE_INT("hw.alc.msix_disable", &msix
 /*
  * Devices supported by this driver.
  */
-static struct alc_dev {
-	uint16_t	alc_vendorid;
-	uint16_t	alc_deviceid;
-	const char	*alc_name;
-} alc_devs[] = {
-	{ VENDORID_ATHEROS, DEVICEID_ATHEROS_AR8131,
+static struct alc_ident alc_ident_table[] = {
+	{ VENDORID_ATHEROS, DEVICEID_ATHEROS_AR8131, 9 * 1024,
 		"Atheros AR8131 PCIe Gigabit Ethernet" },
-	{ VENDORID_ATHEROS, DEVICEID_ATHEROS_AR8132,
-		"Atheros AR8132 PCIe Fast Ethernet" }
+	{ VENDORID_ATHEROS, DEVICEID_ATHEROS_AR8132, 9 * 1024,
+		"Atheros AR8132 PCIe Fast Ethernet" },
+	{ VENDORID_ATHEROS, DEVICEID_ATHEROS_AR8151, 6 * 1024,
+		"Atheros AR8151 v1.0 PCIe Gigabit Ethernet" },
+	{ VENDORID_ATHEROS, DEVICEID_ATHEROS_AR8151_V2, 6 * 1024,
+		"Atheros AR8151 v2.0 PCIe Gigabit Ethernet" },
+	{ VENDORID_ATHEROS, DEVICEID_ATHEROS_AR8152_B, 6 * 1024,
+		"Atheros AR8152 v1.1 PCIe Fast Ethernet" },
+	{ VENDORID_ATHEROS, DEVICEID_ATHEROS_AR8152_B2, 6 * 1024,
+		"Atheros AR8152 v2.0 PCIe Fast Ethernet" },
+	{ 0, 0, 0, NULL}
 };
 
-static void	alc_aspm(struct alc_softc *);
+static void	alc_aspm(struct alc_softc *, int);
 static int	alc_attach(device_t);
 static int	alc_check_boundary(struct alc_softc *);
 static int	alc_detach(device_t);
@@ -118,6 +123,8 @@ static int	alc_dma_alloc(struct alc_soft
 static void	alc_dma_free(struct alc_softc *);
 static void	alc_dmamap_cb(void *, bus_dma_segment_t *, int, int);
 static int	alc_encap(struct alc_softc *, struct mbuf **);
+static struct alc_ident *
+		alc_find_ident(device_t);
 #ifndef __NO_STRICT_ALIGNMENT
 static struct mbuf *
 		alc_fixup_rx(struct ifnet *, struct mbuf *);
@@ -331,7 +338,7 @@ alc_miibus_statchg(device_t dev)
 		reg |= MAC_CFG_TX_ENB | MAC_CFG_RX_ENB;
 		CSR_WRITE_4(sc, ALC_MAC_CFG, reg);
 	}
-	alc_aspm(sc);
+	alc_aspm(sc, IFM_SUBTYPE(mii->mii_media_active));
 }
 
 static void
@@ -375,23 +382,31 @@ alc_mediachange(struct ifnet *ifp)
 	return (error);
 }
 
-static int
-alc_probe(device_t dev)
+static struct alc_ident *
+alc_find_ident(device_t dev)
 {
-	struct alc_dev *sp;
-	int i;
+	struct alc_ident *ident;
 	uint16_t vendor, devid;
 
 	vendor = pci_get_vendor(dev);
 	devid = pci_get_device(dev);
-	sp = alc_devs;
-	for (i = 0; i < sizeof(alc_devs) / sizeof(alc_devs[0]); i++) {
-		if (vendor == sp->alc_vendorid &&
-		    devid == sp->alc_deviceid) {
-			device_set_desc(dev, sp->alc_name);
-			return (BUS_PROBE_DEFAULT);
-		}
-		sp++;
+	for (ident = alc_ident_table; ident->name != NULL; ident++) {
+		if (vendor == ident->vendorid && devid == ident->deviceid)
+			return (ident);
+	}
+
+	return (NULL);
+}
+
+static int
+alc_probe(device_t dev)
+{
+	struct alc_ident *ident;
+
+	ident = alc_find_ident(dev);
+	if (ident != NULL) {
+		device_set_desc(dev, ident->name);
+		return (BUS_PROBE_DEFAULT);
 	}
 
 	return (ENXIO);
@@ -401,20 +416,53 @@ static void
 alc_get_macaddr(struct alc_softc *sc)
 {
 	uint32_t ea[2], opt;
-	int i;
+	uint16_t val;
+	int eeprom, i;
 
+	eeprom = 0;
 	opt = CSR_READ_4(sc, ALC_OPT_CFG);
-	if ((CSR_READ_4(sc, ALC_TWSI_DEBUG) & TWSI_DEBUG_DEV_EXIST) != 0) {
+	if ((CSR_READ_4(sc, ALC_MASTER_CFG) & MASTER_OTP_SEL) != 0 &&
+	    (CSR_READ_4(sc, ALC_TWSI_DEBUG) & TWSI_DEBUG_DEV_EXIST) != 0) {
 		/*
 		 * EEPROM found, let TWSI reload EEPROM configuration.
 		 * This will set ethernet address of controller.
 		 */
-		if ((opt & OPT_CFG_CLK_ENB) == 0) {
-			opt |= OPT_CFG_CLK_ENB;
-			CSR_WRITE_4(sc, ALC_OPT_CFG, opt);
-			CSR_READ_4(sc, ALC_OPT_CFG);
-			DELAY(1000);
+		eeprom++;
+		switch (sc->alc_ident->deviceid) {
+		case DEVICEID_ATHEROS_AR8131:
+		case DEVICEID_ATHEROS_AR8132:
+			if ((opt & OPT_CFG_CLK_ENB) == 0) {
+				opt |= OPT_CFG_CLK_ENB;
+				CSR_WRITE_4(sc, ALC_OPT_CFG, opt);
+				CSR_READ_4(sc, ALC_OPT_CFG);
+				DELAY(1000);
+			}
+			break;
+		case DEVICEID_ATHEROS_AR8151:
+		case DEVICEID_ATHEROS_AR8151_V2:
+		case DEVICEID_ATHEROS_AR8152_B:
+		case DEVICEID_ATHEROS_AR8152_B2:
+			alc_miibus_writereg(sc->alc_dev, sc->alc_phyaddr,
+			    ALC_MII_DBG_ADDR, 0x00);
+			val = alc_miibus_readreg(sc->alc_dev, sc->alc_phyaddr,
+			    ALC_MII_DBG_DATA);
+			alc_miibus_writereg(sc->alc_dev, sc->alc_phyaddr,
+			    ALC_MII_DBG_DATA, val & 0xFF7F);
+			alc_miibus_writereg(sc->alc_dev, sc->alc_phyaddr,
+			    ALC_MII_DBG_ADDR, 0x3B);
+			val = alc_miibus_readreg(sc->alc_dev, sc->alc_phyaddr,
+			    ALC_MII_DBG_DATA);
+			alc_miibus_writereg(sc->alc_dev, sc->alc_phyaddr,
+			    ALC_MII_DBG_DATA, val | 0x0008);
+			DELAY(20);
+			break;
 		}
+
+		CSR_WRITE_4(sc, ALC_LTSSM_ID_CFG,
+		    CSR_READ_4(sc, ALC_LTSSM_ID_CFG) & ~LTSSM_ID_WRO_ENB);
+		CSR_WRITE_4(sc, ALC_WOL_CFG, 0);
+		CSR_READ_4(sc, ALC_WOL_CFG);
+
 		CSR_WRITE_4(sc, ALC_TWSI_CFG, CSR_READ_4(sc, ALC_TWSI_CFG) |
 		    TWSI_CFG_SW_LD_START);
 		for (i = 100; i > 0; i--) {
@@ -430,11 +478,36 @@ alc_get_macaddr(struct alc_softc *sc)
 		if (bootverbose)
 			device_printf(sc->alc_dev, "EEPROM not found!\n");
 	}
-	if ((opt & OPT_CFG_CLK_ENB) != 0) {
-		opt &= ~OPT_CFG_CLK_ENB;
-		CSR_WRITE_4(sc, ALC_OPT_CFG, opt);
-		CSR_READ_4(sc, ALC_OPT_CFG);
-		DELAY(1000);
+	if (eeprom != 0) {
+		switch (sc->alc_ident->deviceid) {
+		case DEVICEID_ATHEROS_AR8131:
+		case DEVICEID_ATHEROS_AR8132:
+			if ((opt & OPT_CFG_CLK_ENB) != 0) {
+				opt &= ~OPT_CFG_CLK_ENB;
+				CSR_WRITE_4(sc, ALC_OPT_CFG, opt);
+				CSR_READ_4(sc, ALC_OPT_CFG);
+				DELAY(1000);
+			}
+			break;
+		case DEVICEID_ATHEROS_AR8151:
+		case DEVICEID_ATHEROS_AR8151_V2:
+		case DEVICEID_ATHEROS_AR8152_B:
+		case DEVICEID_ATHEROS_AR8152_B2:
+			alc_miibus_writereg(sc->alc_dev, sc->alc_phyaddr,
+			    ALC_MII_DBG_ADDR, 0x00);
+			val = alc_miibus_readreg(sc->alc_dev, sc->alc_phyaddr,
+			    ALC_MII_DBG_DATA);
+			alc_miibus_writereg(sc->alc_dev, sc->alc_phyaddr,
+			    ALC_MII_DBG_DATA, val | 0x0080);
+			alc_miibus_writereg(sc->alc_dev, sc->alc_phyaddr,
+			    ALC_MII_DBG_ADDR, 0x3B);
+			val = alc_miibus_readreg(sc->alc_dev, sc->alc_phyaddr,
+			    ALC_MII_DBG_DATA);
+			alc_miibus_writereg(sc->alc_dev, sc->alc_phyaddr,
+			    ALC_MII_DBG_DATA, val & 0xFFF7);
+			DELAY(20);
+			break;
+		}
 	}
 
 	ea[0] = CSR_READ_4(sc, ALC_PAR0);
@@ -479,6 +552,43 @@ alc_phy_reset(struct alc_softc *sc)
 	CSR_READ_2(sc, ALC_GPHY_CFG);
 	DELAY(10 * 1000);
 
+	/* DSP fixup, Vendor magic. */
+	if (sc->alc_ident->deviceid == DEVICEID_ATHEROS_AR8152_B) {
+		alc_miibus_writereg(sc->alc_dev, sc->alc_phyaddr,
+		    ALC_MII_DBG_ADDR, 0x000A);
+		data = alc_miibus_readreg(sc->alc_dev, sc->alc_phyaddr,
+		    ALC_MII_DBG_DATA);
+		alc_miibus_writereg(sc->alc_dev, sc->alc_phyaddr,
+		    ALC_MII_DBG_DATA, data & 0xDFFF);
+	}
+	if (sc->alc_ident->deviceid == DEVICEID_ATHEROS_AR8151 ||
+	    sc->alc_ident->deviceid == DEVICEID_ATHEROS_AR8151_V2 ||
+	    sc->alc_ident->deviceid == DEVICEID_ATHEROS_AR8152_B ||
+	    sc->alc_ident->deviceid == DEVICEID_ATHEROS_AR8152_B2) {
+		alc_miibus_writereg(sc->alc_dev, sc->alc_phyaddr,
+		    ALC_MII_DBG_ADDR, 0x003B);
+		data = alc_miibus_readreg(sc->alc_dev, sc->alc_phyaddr,
+		    ALC_MII_DBG_DATA);
+		alc_miibus_writereg(sc->alc_dev, sc->alc_phyaddr,
+		    ALC_MII_DBG_DATA, data & 0xFFF7);
+		DELAY(20 * 1000);
+	}
+	if (sc->alc_ident->deviceid == DEVICEID_ATHEROS_AR8151) {
+		alc_miibus_writereg(sc->alc_dev, sc->alc_phyaddr,
+		    ALC_MII_DBG_ADDR, 0x0029);
+		alc_miibus_writereg(sc->alc_dev, sc->alc_phyaddr,
+		    ALC_MII_DBG_DATA, 0x929D);
+	}
+	if (sc->alc_ident->deviceid == DEVICEID_ATHEROS_AR8131 ||
+	    sc->alc_ident->deviceid == DEVICEID_ATHEROS_AR8132 ||
+	    sc->alc_ident->deviceid == DEVICEID_ATHEROS_AR8151_V2 ||
+	    sc->alc_ident->deviceid == DEVICEID_ATHEROS_AR8152_B2) {
+		alc_miibus_writereg(sc->alc_dev, sc->alc_phyaddr,
+		    ALC_MII_DBG_ADDR, 0x0029);
+		alc_miibus_writereg(sc->alc_dev, sc->alc_phyaddr,
+		    ALC_MII_DBG_DATA, 0xB6DD);
+	}
+
 	/* Load DSP codes, vendor magic. */
 	data = ANA_LOOP_SEL_10BT | ANA_EN_MASK_TB | ANA_EN_10BT_IDLE |
 	    ((1 << ANA_INTERVAL_SEL_TIMER_SHIFT) & ANA_INTERVAL_SEL_TIMER_MASK);
@@ -528,36 +638,117 @@ static void
 alc_phy_down(struct alc_softc *sc)
 {
 
-	/* Force PHY down. */
-	CSR_WRITE_2(sc, ALC_GPHY_CFG,
-	    GPHY_CFG_EXT_RESET | GPHY_CFG_HIB_EN | GPHY_CFG_HIB_PULSE |
-	    GPHY_CFG_SEL_ANA_RESET | GPHY_CFG_PHY_IDDQ | GPHY_CFG_PWDOWN_HW);
-	DELAY(1000);
+	switch (sc->alc_ident->deviceid) {
+	case DEVICEID_ATHEROS_AR8151:
+	case DEVICEID_ATHEROS_AR8151_V2:
+		/*
+		 * GPHY power down caused more problems on AR8151 v2.0.
+		 * When driver is reloaded after GPHY power down,
+		 * accesses to PHY/MAC registers hung the system. Only
+		 * cold boot recovered from it.  I'm not sure whether
+		 * AR8151 v1.0 also requires this one though.  I don't
+		 * have AR8151 v1.0 controller in hand.
+		 * The only option left is to isolate the PHY and
+		 * initiates power down the PHY which in turn saves
+		 * more power when driver is unloaded.
+		 */
+		alc_miibus_writereg(sc->alc_dev, sc->alc_phyaddr,
+		    MII_BMCR, BMCR_ISO | BMCR_PDOWN);
+		break;
+	default:
+		/* Force PHY down. */
+		CSR_WRITE_2(sc, ALC_GPHY_CFG,
+		    GPHY_CFG_EXT_RESET | GPHY_CFG_HIB_EN | GPHY_CFG_HIB_PULSE |
+		    GPHY_CFG_SEL_ANA_RESET | GPHY_CFG_PHY_IDDQ |
+		    GPHY_CFG_PWDOWN_HW);
+		DELAY(1000);
+		break;
+	}
 }
 
 static void
-alc_aspm(struct alc_softc *sc)
+alc_aspm(struct alc_softc *sc, int media)
 {
 	uint32_t pmcfg;
+	uint16_t linkcfg;
 
 	ALC_LOCK_ASSERT(sc);
 
 	pmcfg = CSR_READ_4(sc, ALC_PM_CFG);
+	if ((sc->alc_flags & (ALC_FLAG_APS | ALC_FLAG_PCIE)) ==
+	    (ALC_FLAG_APS | ALC_FLAG_PCIE))
+		linkcfg = CSR_READ_2(sc, sc->alc_expcap +
+		    PCIR_EXPRESS_LINK_CTL);
+	else
+		linkcfg = 0;
 	pmcfg &= ~PM_CFG_SERDES_PD_EX_L1;
-	pmcfg |= PM_CFG_SERDES_BUDS_RX_L1_ENB;
-	pmcfg |= PM_CFG_SERDES_L1_ENB;
-	pmcfg &= ~PM_CFG_L1_ENTRY_TIMER_MASK;
+	pmcfg &= ~(PM_CFG_L1_ENTRY_TIMER_MASK | PM_CFG_LCKDET_TIMER_MASK);
 	pmcfg |= PM_CFG_MAC_ASPM_CHK;
+	pmcfg |= PM_CFG_SERDES_ENB | PM_CFG_RBER_ENB;
+	pmcfg &= ~(PM_CFG_ASPM_L1_ENB | PM_CFG_ASPM_L0S_ENB);
+
+	if ((sc->alc_flags & ALC_FLAG_APS) != 0) {
+		/* Disable extended sync except AR8152 B v1.0 */
+		linkcfg &= ~0x80;
+		if (sc->alc_ident->deviceid == DEVICEID_ATHEROS_AR8152_B &&
+		    sc->alc_rev == ATHEROS_AR8152_B_V10)
+			linkcfg |= 0x80;
+		CSR_WRITE_2(sc, sc->alc_expcap + PCIR_EXPRESS_LINK_CTL,
+		    linkcfg);
+		pmcfg &= ~(PM_CFG_EN_BUFS_RX_L0S | PM_CFG_SA_DLY_ENB |
+		    PM_CFG_HOTRST);
+		pmcfg |= (PM_CFG_L1_ENTRY_TIMER_DEFAULT <<
+		    PM_CFG_L1_ENTRY_TIMER_SHIFT);
+		pmcfg &= ~PM_CFG_PM_REQ_TIMER_MASK;
+		pmcfg |= (PM_CFG_PM_REQ_TIMER_DEFAULT <<
+		    PM_CFG_PM_REQ_TIMER_SHIFT);
+		pmcfg |= PM_CFG_SERDES_PD_EX_L1 | PM_CFG_PCIE_RECV;
+	}
+
 	if ((sc->alc_flags & ALC_FLAG_LINK) != 0) {
-		pmcfg |= PM_CFG_SERDES_PLL_L1_ENB;
-		pmcfg &= ~PM_CFG_CLK_SWH_L1;
-		pmcfg &= ~PM_CFG_ASPM_L1_ENB;
-		pmcfg &= ~PM_CFG_ASPM_L0S_ENB;
+		if ((sc->alc_flags & ALC_FLAG_L0S) != 0)
+			pmcfg |= PM_CFG_ASPM_L0S_ENB;
+		if ((sc->alc_flags & ALC_FLAG_L1S) != 0)
+			pmcfg |= PM_CFG_ASPM_L1_ENB;
+		if ((sc->alc_flags & ALC_FLAG_APS) != 0) {
+			if (sc->alc_ident->deviceid ==
+			    DEVICEID_ATHEROS_AR8152_B)
+				pmcfg &= ~PM_CFG_ASPM_L0S_ENB;
+			pmcfg &= ~(PM_CFG_SERDES_L1_ENB |
+			    PM_CFG_SERDES_PLL_L1_ENB |
+			    PM_CFG_SERDES_BUDS_RX_L1_ENB);
+			pmcfg |= PM_CFG_CLK_SWH_L1;
+			if (media == IFM_100_TX || media == IFM_1000_T) {
+				pmcfg &= ~PM_CFG_L1_ENTRY_TIMER_MASK;
+				switch (sc->alc_ident->deviceid) {
+				case DEVICEID_ATHEROS_AR8152_B:
+					pmcfg |= (7 <<
+					    PM_CFG_L1_ENTRY_TIMER_SHIFT);
+					break;
+				case DEVICEID_ATHEROS_AR8152_B2:
+				case DEVICEID_ATHEROS_AR8151_V2:
+					pmcfg |= (4 <<
+					    PM_CFG_L1_ENTRY_TIMER_SHIFT);
+					break;
+				default:
+					pmcfg |= (15 <<
+					    PM_CFG_L1_ENTRY_TIMER_SHIFT);
+					break;
+				}
+			}
+		} else {
+			pmcfg |= PM_CFG_SERDES_L1_ENB |
+			    PM_CFG_SERDES_PLL_L1_ENB |
+			    PM_CFG_SERDES_BUDS_RX_L1_ENB;
+			pmcfg &= ~(PM_CFG_CLK_SWH_L1 |
+			    PM_CFG_ASPM_L1_ENB | PM_CFG_ASPM_L0S_ENB);
+		}
 	} else {
-		pmcfg &= ~PM_CFG_SERDES_PLL_L1_ENB;
+		pmcfg &= ~(PM_CFG_SERDES_BUDS_RX_L1_ENB | PM_CFG_SERDES_L1_ENB |
+		    PM_CFG_SERDES_PLL_L1_ENB);
 		pmcfg |= PM_CFG_CLK_SWH_L1;
-		pmcfg &= ~PM_CFG_ASPM_L1_ENB;
-		pmcfg &= ~PM_CFG_ASPM_L0S_ENB;
+		if ((sc->alc_flags & ALC_FLAG_L1S) != 0)
+			pmcfg |= PM_CFG_ASPM_L1_ENB;
 	}
 	CSR_WRITE_4(sc, ALC_PM_CFG, pmcfg);
 }
@@ -567,7 +758,7 @@ alc_attach(device_t dev)
 {
 	struct alc_softc *sc;
 	struct ifnet *ifp;
-	char *aspm_state[] = { "L0s/L1", "L0s", "L1", "L0s/l1" };
+	char *aspm_state[] = { "L0s/L1", "L0s", "L1", "L0s/L1" };
 	uint16_t burst;
 	int base, error, i, msic, msixc, state;
 	uint32_t cap, ctl, val;
@@ -580,6 +771,7 @@ alc_attach(device_t dev)
 	    MTX_DEF);
 	callout_init_mtx(&sc->alc_tick_ch, &sc->alc_mtx, 0);
 	TASK_INIT(&sc->alc_int_task, 0, alc_int_task, sc);
+	sc->alc_ident = alc_find_ident(dev);
 
 	/* Map the device. */
 	pci_enable_busmaster(dev);
@@ -619,6 +811,20 @@ alc_attach(device_t dev)
 		val = CSR_READ_4(sc, ALC_PEX_UNC_ERR_SEV);
 		val &= ~(PEX_UNC_ERR_SEV_DLP | PEX_UNC_ERR_SEV_FCP);
 		CSR_WRITE_4(sc, ALC_PEX_UNC_ERR_SEV, val);
+		CSR_WRITE_4(sc, ALC_LTSSM_ID_CFG,
+		    CSR_READ_4(sc, ALC_LTSSM_ID_CFG) & ~LTSSM_ID_WRO_ENB);
+		CSR_WRITE_4(sc, ALC_PCIE_PHYMISC,
+		    CSR_READ_4(sc, ALC_PCIE_PHYMISC) |
+		    PCIE_PHYMISC_FORCE_RCV_DET);
+		if (sc->alc_ident->deviceid == DEVICEID_ATHEROS_AR8152_B &&
+		    sc->alc_rev == ATHEROS_AR8152_B_V10) {
+			val = CSR_READ_4(sc, ALC_PCIE_PHYMISC2);
+			val &= ~(PCIE_PHYMISC2_SERDES_CDR_MASK |
+			    PCIE_PHYMISC2_SERDES_TH_MASK);
+			val |= 3 << PCIE_PHYMISC2_SERDES_CDR_SHIFT;
+			val |= 3 << PCIE_PHYMISC2_SERDES_TH_SHIFT;
+			CSR_WRITE_4(sc, ALC_PCIE_PHYMISC2, val);
+		}
 		/* Disable ASPM L0S and L1. */
 		cap = CSR_READ_2(sc, base + PCIR_EXPRESS_LINK_CAP);
 		if ((cap & PCIM_LINK_CAP_ASPM) != 0) {
@@ -629,12 +835,19 @@ alc_attach(device_t dev)
 				device_printf(dev, "RCB %u bytes\n",
 				    sc->alc_rcb == DMA_CFG_RCB_64 ? 64 : 128);
 			state = ctl & 0x03;
+			if (state & 0x01)
+				sc->alc_flags |= ALC_FLAG_L0S;
+			if (state & 0x02)
+				sc->alc_flags |= ALC_FLAG_L1S;
 			if (bootverbose)
 				device_printf(sc->alc_dev, "ASPM %s %s\n",
 				    aspm_state[state],
 				    state == 0 ? "disabled" : "enabled");
-			if (state != 0)
-				alc_disable_l0s_l1(sc);
+			alc_disable_l0s_l1(sc);
+		} else {
+			if (bootverbose)
+				device_printf(sc->alc_dev,
+				    "no ASPM support\n");
 		}
 	}
 
@@ -651,12 +864,25 @@ alc_attach(device_t dev)
 	 * used in AR8132 can't establish gigabit link even if it
 	 * shows the same PHY model/revision number of AR8131.
 	 */
-	if (pci_get_device(dev) == DEVICEID_ATHEROS_AR8132)
-		sc->alc_flags |= ALC_FLAG_FASTETHER | ALC_FLAG_JUMBO;
-	else
-		sc->alc_flags |= ALC_FLAG_JUMBO | ALC_FLAG_ASPM_MON;
+	switch (sc->alc_ident->deviceid) {
+	case DEVICEID_ATHEROS_AR8152_B:
+	case DEVICEID_ATHEROS_AR8152_B2:
+		sc->alc_flags |= ALC_FLAG_APS;
+		/* FALLTHROUGH */
+	case DEVICEID_ATHEROS_AR8132:
+		sc->alc_flags |= ALC_FLAG_FASTETHER;
+		break;
+	case DEVICEID_ATHEROS_AR8151:
+	case DEVICEID_ATHEROS_AR8151_V2:
+		sc->alc_flags |= ALC_FLAG_APS;
+		/* FALLTHROUGH */
+	default:
+		break;
+	}
+	sc->alc_flags |= ALC_FLAG_ASPM_MON | ALC_FLAG_JUMBO;
+
 	/*
-	 * It seems that AR8131/AR8132 has silicon bug for SMB. In
+	 * It seems that AR813x/AR815x has silicon bug for SMB. In
 	 * addition, Atheros said that enabling SMB wouldn't improve
 	 * performance. However I think it's bad to access lots of
 	 * registers to extract MAC statistics.
@@ -1369,7 +1595,7 @@ again:
 
 	/*
 	 * Create Tx buffer parent tag.
-	 * AR8131/AR8132 allows 64bit DMA addressing of Tx/Rx buffers
+	 * AR813x/AR815x allows 64bit DMA addressing of Tx/Rx buffers
 	 * so it needs separate parent DMA tag as parent DMA address
 	 * space could be restricted to be within 32bit address space
 	 * by 4GB boundary crossing.
@@ -1806,7 +2032,7 @@ alc_encap(struct alc_softc *sc, struct m
 	poff = 0;
 	if ((m->m_pkthdr.csum_flags & (ALC_CSUM_FEATURES | CSUM_TSO)) != 0) {
 		/*
-		 * AR8131/AR8132 requires offset of TCP/UDP header in its
+		 * AR813x/AR815x requires offset of TCP/UDP header in its
 		 * Tx descriptor to perform Tx checksum offloading. TSO
 		 * also requires TCP header offset and modification of
 		 * IP/TCP header. This kind of operation takes many CPU
@@ -1826,12 +2052,14 @@ alc_encap(struct alc_softc *sc, struct m
 			*m_head = m;
 		}
 
-		m = m_pullup(m, sizeof(struct ether_header) + sizeof(struct ip));
+		m = m_pullup(m, sizeof(struct ether_header) +
+		    sizeof(struct ip));
 		if (m == NULL) {
 			*m_head = NULL;
 			return (ENOBUFS);
 		}
-		ip = (struct ip *)(mtod(m, char *) + sizeof(struct ether_header));
+		ip = (struct ip *)(mtod(m, char *) +
+		    sizeof(struct ether_header));
 		poff = sizeof(struct ether_header) + (ip->ip_hl << 2);
 		if ((m->m_pkthdr.csum_flags & CSUM_TSO) != 0) {
 			m = m_pullup(m, poff + sizeof(struct tcphdr));
@@ -1922,7 +2150,7 @@ alc_encap(struct alc_softc *sc, struct m
 		cflags |= (poff << TD_TCPHDR_OFFSET_SHIFT) &
 		    TD_TCPHDR_OFFSET_MASK;
 		/*
-		 * AR8131/AR8132 requires the first buffer should
+		 * AR813x/AR815x requires the first buffer should
 		 * only hold IP/TCP header data. Payload should
 		 * be handled in other descriptors.
 		 */
@@ -2103,14 +2331,16 @@ alc_ioctl(struct ifnet *ifp, u_long cmd,
 	error = 0;
 	switch (cmd) {
 	case SIOCSIFMTU:
-		if (ifr->ifr_mtu < ETHERMIN || ifr->ifr_mtu > ALC_JUMBO_MTU ||
+		if (ifr->ifr_mtu < ETHERMIN ||
+		    ifr->ifr_mtu > (sc->alc_ident->max_framelen -
+		    sizeof(struct ether_vlan_header) - ETHER_CRC_LEN) ||
 		    ((sc->alc_flags & ALC_FLAG_JUMBO) == 0 &&
 		    ifr->ifr_mtu > ETHERMTU))
 			error = EINVAL;
 		else if (ifp->if_mtu != ifr->ifr_mtu) {
 			ALC_LOCK(sc);
 			ifp->if_mtu = ifr->ifr_mtu;
-			/* AR8131/AR8132 has 13 bits MSS field. */
+			/* AR813x/AR815x has 13 bits MSS field. */
 			if (ifp->if_mtu > ALC_TSO_MTU &&
 			    (ifp->if_capenable & IFCAP_TSO4) != 0) {
 				ifp->if_capenable &= ~IFCAP_TSO4;
@@ -2161,7 +2391,7 @@ alc_ioctl(struct ifnet *ifp, u_long cmd,
 		    (ifp->if_capabilities & IFCAP_TSO4) != 0) {
 			ifp->if_capenable ^= IFCAP_TSO4;
 			if ((ifp->if_capenable & IFCAP_TSO4) != 0) {
-				/* AR8131/AR8132 has 13 bits MSS field. */
+				/* AR813x/AR815x has 13 bits MSS field. */
 				if (ifp->if_mtu > ALC_TSO_MTU) {
 					ifp->if_capenable &= ~IFCAP_TSO4;
 					ifp->if_hwassist &= ~CSUM_TSO;
@@ -2213,6 +2443,10 @@ alc_mac_config(struct alc_softc *sc)
 	reg = CSR_READ_4(sc, ALC_MAC_CFG);
 	reg &= ~(MAC_CFG_FULL_DUPLEX | MAC_CFG_TX_FC | MAC_CFG_RX_FC |
 	    MAC_CFG_SPEED_MASK);
+	if (sc->alc_ident->deviceid == DEVICEID_ATHEROS_AR8151 ||
+	    sc->alc_ident->deviceid == DEVICEID_ATHEROS_AR8151_V2 ||
+	    sc->alc_ident->deviceid == DEVICEID_ATHEROS_AR8152_B2)
+		reg |= MAC_CFG_HASH_ALG_CRC32 | MAC_CFG_SPEED_MODE_SW;
 	/* Reprogram MAC with resolved speed/duplex. */
 	switch (IFM_SUBTYPE(mii->mii_media_active)) {
 	case IFM_10_T:
@@ -2834,7 +3068,9 @@ alc_reset(struct alc_softc *sc)
 	uint32_t reg;
 	int i;
 
-	CSR_WRITE_4(sc, ALC_MASTER_CFG, MASTER_RESET);
+	reg = CSR_READ_4(sc, ALC_MASTER_CFG) & 0xFFFF;
+	reg |= MASTER_OOB_DIS_OFF | MASTER_RESET;
+	CSR_WRITE_4(sc, ALC_MASTER_CFG, reg);
 	for (i = ALC_RESET_TIMEOUT; i > 0; i--) {
 		DELAY(10);
 		if ((CSR_READ_4(sc, ALC_MASTER_CFG) & MASTER_RESET) == 0)
@@ -2965,6 +3201,18 @@ alc_init_locked(struct alc_softc *sc)
 	CSR_WRITE_4(sc, ALC_SMB_BASE_ADDR_HI, ALC_ADDR_HI(paddr));
 	CSR_WRITE_4(sc, ALC_SMB_BASE_ADDR_LO, ALC_ADDR_LO(paddr));
 
+	if (sc->alc_ident->deviceid == DEVICEID_ATHEROS_AR8152_B) {
+		/* Reconfigure SRAM - Vendor magic. */
+		CSR_WRITE_4(sc, ALC_SRAM_RX_FIFO_LEN, 0x000002A0);
+		CSR_WRITE_4(sc, ALC_SRAM_TX_FIFO_LEN, 0x00000100);
+		CSR_WRITE_4(sc, ALC_SRAM_RX_FIFO_ADDR, 0x029F0000);
+		CSR_WRITE_4(sc, ALC_SRAM_RD0_ADDR, 0x02BF02A0);
+		CSR_WRITE_4(sc, ALC_SRAM_TX_FIFO_ADDR, 0x03BF02C0);
+		CSR_WRITE_4(sc, ALC_SRAM_TD_ADDR, 0x03DF03C0);
+		CSR_WRITE_4(sc, ALC_TXF_WATER_MARK, 0x00000000);
+		CSR_WRITE_4(sc, ALC_RD_DMA_CFG, 0x00000000);
+	}
+
 	/* Tell hardware that we're ready to load DMA blocks. */
 	CSR_WRITE_4(sc, ALC_DMA_BLOCK, DMA_BLOCK_LOAD);
 
@@ -2972,14 +3220,11 @@ alc_init_locked(struct alc_softc *sc)
 	reg = ALC_USECS(sc->alc_int_rx_mod) << IM_TIMER_RX_SHIFT;
 	reg |= ALC_USECS(sc->alc_int_tx_mod) << IM_TIMER_TX_SHIFT;
 	CSR_WRITE_4(sc, ALC_IM_TIMER, reg);
-	reg = CSR_READ_4(sc, ALC_MASTER_CFG);
-	reg &= ~(MASTER_CHIP_REV_MASK | MASTER_CHIP_ID_MASK);
 	/*
 	 * We don't want to automatic interrupt clear as task queue
 	 * for the interrupt should know interrupt status.
 	 */
-	reg &= ~MASTER_INTR_RD_CLR;
-	reg &= ~(MASTER_IM_RX_TIMER_ENB | MASTER_IM_TX_TIMER_ENB);
+	reg = MASTER_SA_TIMER_ENB;
 	if (ALC_USECS(sc->alc_int_rx_mod) != 0)
 		reg |= MASTER_IM_RX_TIMER_ENB;
 	if (ALC_USECS(sc->alc_int_tx_mod) != 0)
@@ -3020,7 +3265,7 @@ alc_init_locked(struct alc_softc *sc)
 	 * Be conservative in what you do, be liberal in what you
 	 * accept from others - RFC 793.
 	 */
-	CSR_WRITE_4(sc, ALC_FRAME_SIZE, ALC_JUMBO_FRAMELEN);
+	CSR_WRITE_4(sc, ALC_FRAME_SIZE, sc->alc_ident->max_framelen);
 
 	/* Disable header split(?) */
 	CSR_WRITE_4(sc, ALC_HDS_CFG, 0);
@@ -3047,11 +3292,14 @@ alc_init_locked(struct alc_softc *sc)
 	 * TSO/checksum offloading.
 	 */
 	CSR_WRITE_4(sc, ALC_TSO_OFFLOAD_THRESH,
-	    (ALC_JUMBO_FRAMELEN >> TSO_OFFLOAD_THRESH_UNIT_SHIFT) &
+	    (sc->alc_ident->max_framelen >> TSO_OFFLOAD_THRESH_UNIT_SHIFT) &
 	    TSO_OFFLOAD_THRESH_MASK);
 	/* Configure TxQ. */
 	reg = (alc_dma_burst[sc->alc_dma_rd_burst] <<
 	    TXQ_CFG_TX_FIFO_BURST_SHIFT) & TXQ_CFG_TX_FIFO_BURST_MASK;
+	if (sc->alc_ident->deviceid == DEVICEID_ATHEROS_AR8152_B ||
+	    sc->alc_ident->deviceid == DEVICEID_ATHEROS_AR8152_B2)
+		reg >>= 1;
 	reg |= (TXQ_CFG_TD_BURST_DEFAULT << TXQ_CFG_TD_BURST_SHIFT) &
 	    TXQ_CFG_TD_BURST_MASK;
 	CSR_WRITE_4(sc, ALC_TXQ_CFG, reg | TXQ_CFG_ENHANCED_MODE);
@@ -3068,14 +3316,23 @@ alc_init_locked(struct alc_softc *sc)
 	 * XON  : 80% of Rx FIFO
 	 * XOFF : 30% of Rx FIFO
 	 */
-	reg = CSR_READ_4(sc, ALC_SRAM_RX_FIFO_LEN);
-	rxf_hi = (reg * 8) / 10;
-	rxf_lo = (reg * 3)/ 10;
-	CSR_WRITE_4(sc, ALC_RX_FIFO_PAUSE_THRESH,
-	    ((rxf_lo << RX_FIFO_PAUSE_THRESH_LO_SHIFT) &
-	    RX_FIFO_PAUSE_THRESH_LO_MASK) |
-	    ((rxf_hi << RX_FIFO_PAUSE_THRESH_HI_SHIFT) &
-	     RX_FIFO_PAUSE_THRESH_HI_MASK));
+	if (sc->alc_ident->deviceid == DEVICEID_ATHEROS_AR8131 ||
+	    sc->alc_ident->deviceid == DEVICEID_ATHEROS_AR8132) {
+		reg = CSR_READ_4(sc, ALC_SRAM_RX_FIFO_LEN);
+		rxf_hi = (reg * 8) / 10;
+		rxf_lo = (reg * 3) / 10;
+		CSR_WRITE_4(sc, ALC_RX_FIFO_PAUSE_THRESH,
+		    ((rxf_lo << RX_FIFO_PAUSE_THRESH_LO_SHIFT) &
+		     RX_FIFO_PAUSE_THRESH_LO_MASK) |
+		    ((rxf_hi << RX_FIFO_PAUSE_THRESH_HI_SHIFT) &
+		     RX_FIFO_PAUSE_THRESH_HI_MASK));
+	}
+
+	if (sc->alc_ident->deviceid == DEVICEID_ATHEROS_AR8152_B ||
+	    sc->alc_ident->deviceid == DEVICEID_ATHEROS_AR8151_V2)
+		CSR_WRITE_4(sc, ALC_SERDES_LOCK,
+		    CSR_READ_4(sc, ALC_SERDES_LOCK) | SERDES_MAC_CLK_SLOWDOWN |
+		    SERDES_PHY_CLK_SLOWDOWN);
 
 	/* Disable RSS until I understand L1C/L2C's RSS logic. */
 	CSR_WRITE_4(sc, ALC_RSS_IDT_TABLE0, 0);
@@ -3086,15 +3343,9 @@ alc_init_locked(struct alc_softc *sc)
 	    RXQ_CFG_RD_BURST_MASK;
 	reg |= RXQ_CFG_RSS_MODE_DIS;
 	if ((sc->alc_flags & ALC_FLAG_ASPM_MON) != 0)
-		reg |= RXQ_CFG_ASPM_THROUGHPUT_LIMIT_100M;
+		reg |= RXQ_CFG_ASPM_THROUGHPUT_LIMIT_1M;
 	CSR_WRITE_4(sc, ALC_RXQ_CFG, reg);
 
-	/* Configure Rx DMAW request thresold. */
-	CSR_WRITE_4(sc, ALC_RD_DMA_CFG,
-	    ((RD_DMA_CFG_THRESH_DEFAULT << RD_DMA_CFG_THRESH_SHIFT) &
-	    RD_DMA_CFG_THRESH_MASK) |
-	    ((ALC_RD_DMA_CFG_USECS(0) << RD_DMA_CFG_TIMER_SHIFT) &
-	    RD_DMA_CFG_TIMER_MASK));
 	/* Configure DMA parameters. */
 	reg = DMA_CFG_OUT_ORDER | DMA_CFG_RD_REQ_PRI;
 	reg |= sc->alc_rcb;
@@ -3120,7 +3371,7 @@ alc_init_locked(struct alc_softc *sc)
 	 *  - Enable CRC generation.
 	 *  Actual reconfiguration of MAC for resolved speed/duplex
 	 *  is followed after detection of link establishment.
-	 *  AR8131/AR8132 always does checksum computation regardless
+	 *  AR813x/AR815x always does checksum computation regardless
 	 *  of MAC_CFG_RXCSUM_ENB bit. Also the controller is known to
 	 *  have bug in protocol field in Rx return structure so
 	 *  these controllers can't handle fragmented frames. Disable
@@ -3130,6 +3381,10 @@ alc_init_locked(struct alc_softc *sc)
 	reg = MAC_CFG_TX_CRC_ENB | MAC_CFG_TX_AUTO_PAD | MAC_CFG_FULL_DUPLEX |
 	    ((MAC_CFG_PREAMBLE_DEFAULT << MAC_CFG_PREAMBLE_SHIFT) &
 	    MAC_CFG_PREAMBLE_MASK);
+	if (sc->alc_ident->deviceid == DEVICEID_ATHEROS_AR8151 ||
+	    sc->alc_ident->deviceid == DEVICEID_ATHEROS_AR8151_V2 ||
+	    sc->alc_ident->deviceid == DEVICEID_ATHEROS_AR8152_B2)
+		reg |= MAC_CFG_HASH_ALG_CRC32 | MAC_CFG_SPEED_MODE_SW;
 	if ((sc->alc_flags & ALC_FLAG_FASTETHER) != 0)
 		reg |= MAC_CFG_SPEED_10_100;
 	else

Modified: stable/8/sys/dev/alc/if_alcreg.h
==============================================================================
--- stable/8/sys/dev/alc/if_alcreg.h	Mon Aug 30 21:13:08 2010	(r212020)
+++ stable/8/sys/dev/alc/if_alcreg.h	Mon Aug 30 21:15:40 2010	(r212021)
@@ -36,10 +36,17 @@
 #define	VENDORID_ATHEROS		0x1969
 
 /*
- * Atheros AR8131/AR8132 device ID
+ * Atheros AR813x/AR815x device ID
  */
 #define	DEVICEID_ATHEROS_AR8131		0x1063	/* L1C */
 #define	DEVICEID_ATHEROS_AR8132		0x1062	/* L2C */
+#define	DEVICEID_ATHEROS_AR8151		0x1073	/* L1D V1.0 */
+#define	DEVICEID_ATHEROS_AR8151_V2	0x1083	/* L1D V2.0 */
+#define	DEVICEID_ATHEROS_AR8152_B	0x2060	/* L2C V1.1 */
+#define	DEVICEID_ATHEROS_AR8152_B2	0x2062	/* L2C V2.0 */
+
+#define	ATHEROS_AR8152_B_V10		0xC0
+#define	ATHEROS_AR8152_B_V11		0xC1
 
 /* 0x0000 - 0x02FF : PCIe configuration space */
 
@@ -64,6 +71,12 @@
 #define	ALC_PCIE_PHYMISC		0x1000
 #define	PCIE_PHYMISC_FORCE_RCV_DET	0x00000004
 
+#define	ALC_PCIE_PHYMISC2		0x1004
+#define	PCIE_PHYMISC2_SERDES_CDR_MASK	0x00030000
+#define	PCIE_PHYMISC2_SERDES_TH_MASK	0x000C0000
+#define	PCIE_PHYMISC2_SERDES_CDR_SHIFT	16
+#define	PCIE_PHYMISC2_SERDES_TH_SHIFT	18
+
 #define	ALC_TWSI_DEBUG			0x1108
 #define	TWSI_DEBUG_DEV_EXIST		0x20000000
 
@@ -97,6 +110,8 @@
 #define	PM_CFG_L1_ENTRY_TIMER_MASK	0x000F0000
 #define	PM_CFG_PM_REQ_TIMER_MASK	0x00F00000
 #define	PM_CFG_LCKDET_TIMER_MASK	0x3F000000
+#define	PM_CFG_EN_BUFS_RX_L0S		0x10000000
+#define	PM_CFG_SA_DLY_ENB		0x20000000
 #define	PM_CFG_MAC_ASPM_CHK		0x40000000
 #define	PM_CFG_HOTRST			0x80000000
 #define	PM_CFG_L0S_ENTRY_TIMER_SHIFT	8
@@ -104,10 +119,19 @@
 #define	PM_CFG_PM_REQ_TIMER_SHIFT	20
 #define	PM_CFG_LCKDET_TIMER_SHIFT	24
 
+#define	PM_CFG_L0S_ENTRY_TIMER_DEFAULT	6
+#define	PM_CFG_L1_ENTRY_TIMER_DEFAULT	12
+#define	PM_CFG_PM_REQ_TIMER_DEFAULT	1
+
+#define	ALC_LTSSM_ID_CFG		0x12FC
+#define	LTSSM_ID_WRO_ENB		0x00001000
+
 #define	ALC_MASTER_CFG			0x1400
 #define	MASTER_RESET			0x00000001
 #define	MASTER_TEST_MODE_MASK		0x0000000C
 #define	MASTER_BERT_START		0x00000010
+#define	MASTER_OOB_DIS_OFF		0x00000040
+#define	MASTER_SA_TIMER_ENB		0x00000080
 #define	MASTER_MTIMER_ENB		0x00000100
 #define	MASTER_MANUAL_INTR_ENB		0x00000200
 #define	MASTER_IM_TX_TIMER_ENB		0x00000400
@@ -122,7 +146,7 @@
 #define	MASTER_CHIP_REV_SHIFT		16
 #define	MASTER_CHIP_ID_SHIFT		24
 
-/* Number of ticks per usec for AR8131/AR8132. */
+/* Number of ticks per usec for AR813x/AR815x. */
 #define	ALC_TICK_USECS			2
 #define	ALC_USECS(x)			((x) / ALC_TICK_USECS)
 
@@ -220,6 +244,8 @@
 #define	ALC_SERDES_LOCK			0x1424
 #define	SERDES_LOCK_DET			0x00000001
 #define	SERDES_LOCK_DET_ENB		0x00000002
+#define	SERDES_MAC_CLK_SLOWDOWN		0x00020000
+#define	SERDES_PHY_CLK_SLOWDOWN		0x00040000
 
 #define	ALC_MAC_CFG			0x1480
 #define	MAC_CFG_TX_ENB			0x00000001
@@ -249,6 +275,8 @@
 #define	MAC_CFG_BCAST			0x04000000
 #define	MAC_CFG_DBG			0x08000000
 #define	MAC_CFG_SINGLE_PAUSE_ENB	0x10000000
+#define	MAC_CFG_HASH_ALG_CRC32		0x20000000
+#define	MAC_CFG_SPEED_MODE_SW		0x40000000
 #define	MAC_CFG_PREAMBLE_SHIFT		10
 #define	MAC_CFG_PREAMBLE_DEFAULT	7
 
@@ -691,7 +719,7 @@
 #define	HDS_CFG_BACKFILLSIZE_SHIFT	8
 #define	HDS_CFG_MAX_HDRSIZE_SHIFT	20
 
-/* AR8131/AR8132 registers for MAC statistics */
+/* AR813x/AR815x registers for MAC statistics */
 #define	ALC_RX_MIB_BASE			0x1700
 
 #define	ALC_TX_MIB_BASE			0x1760

Modified: stable/8/sys/dev/alc/if_alcvar.h
==============================================================================
--- stable/8/sys/dev/alc/if_alcvar.h	Mon Aug 30 21:13:08 2010	(r212020)
+++ stable/8/sys/dev/alc/if_alcvar.h	Mon Aug 30 21:15:40 2010	(r212021)
@@ -68,13 +68,8 @@
 #define	ALC_PROC_MAX		(ALC_RX_RING_CNT - 1)
 #define	ALC_PROC_DEFAULT	(ALC_RX_RING_CNT / 4)
 
-#define	ALC_JUMBO_FRAMELEN	(9 * 1024)
-#define	ALC_JUMBO_MTU		\
-	(ALC_JUMBO_FRAMELEN - sizeof(struct ether_vlan_header) - ETHER_CRC_LEN)
-#define	ALC_MAX_FRAMELEN	(ETHER_MAX_LEN + ETHER_VLAN_ENCAP_LEN)
-
 /*
- * The number of bits reserved for MSS in AR8121/AR8132 controllers
+ * The number of bits reserved for MSS in AR813x/AR815x controllers
  * are 13 bits. This limits the maximum interface MTU size in TSO
  * case(8191 + sizeof(struct ip) + sizeof(struct tcphdr)) as upper
  * stack should not generate TCP segments with MSS greater than the
@@ -192,6 +187,13 @@ struct alc_hw_stats {
 	uint64_t tx_mcast_bytes;
 };
 
+struct alc_ident {
+	uint16_t	vendorid;
+	uint16_t	deviceid;
+	uint32_t	max_framelen;
+	const char	*name;
+};
+
 /*
  * Software state per device.
  */
@@ -204,6 +206,7 @@ struct alc_softc {
 	struct resource		*alc_irq[ALC_MSI_MESSAGES];
 	struct resource_spec	*alc_irq_spec;
 	void			*alc_intrhand[ALC_MSI_MESSAGES];
+	struct alc_ident	*alc_ident;
 	int			alc_rev;
 	int			alc_chip_rev;
 	int			alc_phyaddr;
@@ -224,6 +227,9 @@ struct alc_softc {
 #define	ALC_FLAG_ASPM_MON	0x0080
 #define	ALC_FLAG_CMB_BUG	0x0100
 #define	ALC_FLAG_SMB_BUG	0x0200
+#define	ALC_FLAG_L0S		0x0400
+#define	ALC_FLAG_L1S		0x0800
+#define	ALC_FLAG_APS		0x1000
 #define	ALC_FLAG_DETACH		0x4000
 #define	ALC_FLAG_LINK		0x8000
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201008302115.o7ULFeCf007673>