Update FreeBSD network drivers with the 9.1 release

This commit is contained in:
Jérôme Duval
2013-01-08 22:45:30 +01:00
committed by Jerome Duval
parent 82ee340110
commit 648db7333e
179 changed files with 16481 additions and 6794 deletions
@@ -56,7 +56,7 @@
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: src/sys/dev/mii/bmtphy.c,v 1.12.10.8.2.1 2010/12/21 17:09:25 kensmith Exp $");
__FBSDID("$FreeBSD$");
/*
* Driver for the Broadcom BCM5201/BCM5202 "Mini-Theta" PHYs. This also
@@ -91,8 +91,7 @@ static device_method_t bmtphy_methods[] = {
DEVMETHOD(device_attach, bmtphy_attach),
DEVMETHOD(device_detach, mii_phy_detach),
DEVMETHOD(device_shutdown, bus_generic_shutdown),
{ 0, 0 }
DEVMETHOD_END
};
static devclass_t bmtphy_devclass;
@@ -28,7 +28,7 @@
*
* from NetBSD: bmtphyreg.h,v 1.1 2001/06/02 21:42:10 thorpej Exp
*
* $FreeBSD: src/sys/dev/mii/bmtphyreg.h,v 1.2.22.2.2.1 2010/12/21 17:09:25 kensmith Exp $
* $FreeBSD$
*/
#ifndef _DEV_MII_BMTPHYREG_H_
@@ -55,7 +55,7 @@
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: src/sys/dev/mii/ukphy.c,v 1.20.10.6.2.1 2010/12/21 17:09:25 kensmith Exp $");
__FBSDID("$FreeBSD$");
/*
* driver for generic unknown PHYs
@@ -86,7 +86,7 @@ static device_method_t ukphy_methods[] = {
DEVMETHOD(device_attach, ukphy_attach),
DEVMETHOD(device_detach, mii_phy_detach),
DEVMETHOD(device_shutdown, bus_generic_shutdown),
{ 0, 0 }
DEVMETHOD_END
};
static devclass_t ukphy_devclass;
@@ -31,7 +31,7 @@
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: src/sys/dev/mii/ukphy_subr.c,v 1.10.2.4.2.1 2010/12/21 17:09:25 kensmith Exp $");
__FBSDID("$FreeBSD$");
/*
* Subroutines shared by the ukphy driver and other PHY drivers.
@@ -31,7 +31,7 @@
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: src/sys/dev/xl/if_xl.c,v 1.8.2.7.2.1 2010/12/21 17:09:25 kensmith Exp $");
__FBSDID("$FreeBSD$");
/*
* 3Com 3c90x Etherlink XL PCI NIC driver
@@ -310,17 +310,13 @@ static device_method_t xl_methods[] = {
DEVMETHOD(device_suspend, xl_suspend),
DEVMETHOD(device_resume, xl_resume),
/* bus interface */
DEVMETHOD(bus_print_child, bus_generic_print_child),
DEVMETHOD(bus_driver_added, bus_generic_driver_added),
/* MII interface */
DEVMETHOD(miibus_readreg, xl_miibus_readreg),
DEVMETHOD(miibus_writereg, xl_miibus_writereg),
DEVMETHOD(miibus_statchg, xl_miibus_statchg),
DEVMETHOD(miibus_mediainit, xl_miibus_mediainit),
{ 0, 0 }
DEVMETHOD_END
};
static driver_t xl_driver = {
@@ -331,8 +327,9 @@ static driver_t xl_driver = {
static devclass_t xl_devclass;
DRIVER_MODULE(xl, pci, xl_driver, xl_devclass, 0, 0);
DRIVER_MODULE(miibus, xl, miibus_driver, miibus_devclass, 0, 0);
DRIVER_MODULE_ORDERED(xl, pci, xl_driver, xl_devclass, NULL, NULL,
SI_ORDER_ANY);
DRIVER_MODULE(miibus, xl, miibus_driver, miibus_devclass, NULL, NULL);
static void
xl_dma_map_addr(void *arg, bus_dma_segment_t *segs, int nseg, int error)
@@ -2185,12 +2182,9 @@ xl_intr(void *arg)
#endif
if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
break;
if (status & XL_STAT_UP_COMPLETE) {
int curpkts;
curpkts = ifp->if_ipackets;
xl_rxeof(sc);
if (curpkts == ifp->if_ipackets) {
if (status & XL_STAT_UP_COMPLETE) {
if (xl_rxeof(sc) == 0) {
while (xl_rx_resync(sc))
xl_rxeof(sc);
}
@@ -29,7 +29,7 @@
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
* $FreeBSD: src/sys/dev/xl/if_xlreg.h,v 1.1.2.2.2.1 2010/12/21 17:09:25 kensmith Exp $
* $FreeBSD$
*/
#define XL_EE_READ 0x0080 /* read, 5 bit address */
@@ -86,7 +86,7 @@ static device_method_t xlphy_methods[] = {
DEVMETHOD(device_attach, xlphy_attach),
DEVMETHOD(device_detach, mii_phy_detach),
DEVMETHOD(device_shutdown, bus_generic_shutdown),
{ 0, 0 }
DEVMETHOD_END
};
static devclass_t xlphy_devclass;
@@ -91,11 +91,11 @@ TUNABLE_INT("hw.ale.msix_disable", &msix_disable);
/*
* Devices supported by this driver.
*/
static struct ale_dev {
static const struct ale_dev {
uint16_t ale_vendorid;
uint16_t ale_deviceid;
const char *ale_name;
} ale_devs[] = {
} const ale_devs[] = {
{ VENDORID_ATHEROS, DEVICEID_ATHEROS_AR81XX,
"Atheros AR8121/AR8113/AR8114 PCIe Ethernet" },
};
@@ -115,7 +115,6 @@ static void ale_init_tx_ring(struct ale_softc *);
static void ale_int_task(void *, int);
static int ale_intr(void *);
static int ale_ioctl(struct ifnet *, u_long, caddr_t);
static void ale_link_task(void *, int);
static void ale_mac_config(struct ale_softc *);
static int ale_miibus_readreg(device_t, int, int);
static void ale_miibus_statchg(device_t);
@@ -164,7 +163,7 @@ static device_method_t ale_methods[] = {
DEVMETHOD(miibus_writereg, ale_miibus_writereg),
DEVMETHOD(miibus_statchg, ale_miibus_statchg),
{ NULL, NULL }
DEVMETHOD_END
};
static driver_t ale_driver = {
@@ -175,8 +174,8 @@ static driver_t ale_driver = {
static devclass_t ale_devclass;
DRIVER_MODULE(ale, pci, ale_driver, ale_devclass, 0, 0);
DRIVER_MODULE(miibus, ale, miibus_driver, miibus_devclass, 0, 0);
DRIVER_MODULE(ale, pci, ale_driver, ale_devclass, NULL, NULL);
DRIVER_MODULE(miibus, ale, miibus_driver, miibus_devclass, NULL, NULL);
static struct resource_spec ale_res_spec_mem[] = {
{ SYS_RES_MEMORY, PCIR_BAR(0), RF_ACTIVE },
@@ -253,10 +252,45 @@ static void
ale_miibus_statchg(device_t dev)
{
struct ale_softc *sc;
struct mii_data *mii;
struct ifnet *ifp;
uint32_t reg;
sc = device_get_softc(dev);
mii = device_get_softc(sc->ale_miibus);
ifp = sc->ale_ifp;
if (mii == NULL || ifp == NULL ||
(ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
return;
taskqueue_enqueue(taskqueue_swi, &sc->ale_link_task);
sc->ale_flags &= ~ALE_FLAG_LINK;
if ((mii->mii_media_status & (IFM_ACTIVE | IFM_AVALID)) ==
(IFM_ACTIVE | IFM_AVALID)) {
switch (IFM_SUBTYPE(mii->mii_media_active)) {
case IFM_10_T:
case IFM_100_TX:
sc->ale_flags |= ALE_FLAG_LINK;
break;
case IFM_1000_T:
if ((sc->ale_flags & ALE_FLAG_FASTETHER) == 0)
sc->ale_flags |= ALE_FLAG_LINK;
break;
default:
break;
}
}
/* Stop Rx/Tx MACs. */
ale_stop_mac(sc);
/* Program MACs with resolved speed/duplex/flow-control. */
if ((sc->ale_flags & ALE_FLAG_LINK) != 0) {
ale_mac_config(sc);
/* Reenable Tx/Rx MACs. */
reg = CSR_READ_4(sc, ALE_MAC_CFG);
reg |= MAC_CFG_TX_ENB | MAC_CFG_RX_ENB;
CSR_WRITE_4(sc, ALE_MAC_CFG, reg);
}
}
static void
@@ -267,12 +301,16 @@ ale_mediastatus(struct ifnet *ifp, struct ifmediareq *ifmr)
sc = ifp->if_softc;
ALE_LOCK(sc);
if ((ifp->if_flags & IFF_UP) == 0) {
ALE_UNLOCK(sc);
return;
}
mii = device_get_softc(sc->ale_miibus);
mii_pollstat(mii);
ALE_UNLOCK(sc);
ifmr->ifm_status = mii->mii_media_status;
ifmr->ifm_active = mii->mii_media_active;
ALE_UNLOCK(sc);
}
static int
@@ -297,7 +335,7 @@ ale_mediachange(struct ifnet *ifp)
static int
ale_probe(device_t dev)
{
struct ale_dev *sp;
const struct ale_dev *sp;
int i;
uint16_t vendor, devid;
@@ -414,7 +452,7 @@ ale_attach(device_t dev)
struct ale_softc *sc;
struct ifnet *ifp;
uint16_t burst;
int error, i, msic, msixc;
int error, i, msic, msixc, pmc;
uint32_t rxf_len, txf_len;
error = 0;
@@ -425,7 +463,6 @@ ale_attach(device_t dev)
MTX_DEF);
callout_init_mtx(&sc->ale_tick_ch, &sc->ale_mtx, 0);
TASK_INIT(&sc->ale_int_task, 0, ale_int_task, sc);
TASK_INIT(&sc->ale_link_task, 0, ale_link_task, sc);
/* Map the device. */
pci_enable_busmaster(dev);
@@ -589,18 +626,16 @@ ale_attach(device_t dev)
IFQ_SET_READY(&ifp->if_snd);
ifp->if_capabilities = IFCAP_RXCSUM | IFCAP_TXCSUM | IFCAP_TSO4;
ifp->if_hwassist = ALE_CSUM_FEATURES | CSUM_TSO;
#ifdef ENABLE_WOL
if (pci_find_cap(dev, PCIY_PMG, &pmc) == 0) {
sc->ale_flags |= ALE_FLAG_PMCAP;
ifp->if_capabilities |= IFCAP_WOL_MAGIC | IFCAP_WOL_MCAST;
}
#endif
ifp->if_capenable = ifp->if_capabilities;
/* Set up MII bus. */
error = mii_attach(dev, &sc->ale_miibus, ifp, ale_mediachange,
ale_mediastatus, BMSR_DEFCAPMASK, sc->ale_phyaddr, MII_OFFSET_ANY,
0);
MIIF_DOPAUSE);
if (error != 0) {
device_printf(dev, "attaching PHYs failed\n");
goto fail;
@@ -681,7 +716,6 @@ ale_detach(device_t dev)
ALE_UNLOCK(sc);
callout_drain(&sc->ale_tick_ch);
taskqueue_drain(sc->ale_tq, &sc->ale_int_task);
taskqueue_drain(taskqueue_swi, &sc->ale_link_task);
}
if (sc->ale_tq != NULL) {
@@ -1399,7 +1433,6 @@ ale_shutdown(device_t dev)
static void
ale_setlinkspeed(struct ale_softc *sc)
{
#ifdef ENABLE_WOL
struct mii_data *mii;
int aneg, i;
@@ -1458,13 +1491,11 @@ ale_setlinkspeed(struct ale_softc *sc)
mii->mii_media_status = IFM_AVALID | IFM_ACTIVE;
mii->mii_media_active = IFM_ETHER | IFM_100_TX | IFM_FDX;
ale_mac_config(sc);
#endif
}
static void
ale_setwol(struct ale_softc *sc)
{
#ifdef ENABLE_WOL
struct ifnet *ifp;
uint32_t reg, pmcs;
uint16_t pmstat;
@@ -1523,7 +1554,6 @@ ale_setwol(struct ale_softc *sc)
if ((ifp->if_capenable & IFCAP_WOL) != 0)
pmstat |= PCIM_PSTAT_PME | PCIM_PSTAT_PMEENABLE;
pci_write_config(sc->ale_dev, pmc + PCIR_POWER_STATUS, pmstat, 2);
#endif
}
static int
@@ -2017,14 +2047,12 @@ ale_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
ifp->if_hwassist &= ~CSUM_TSO;
}
#ifdef ENABLE_WOL
if ((mask & IFCAP_WOL_MCAST) != 0 &&
(ifp->if_capabilities & IFCAP_WOL_MCAST) != 0)
ifp->if_capenable ^= IFCAP_WOL_MCAST;
if ((mask & IFCAP_WOL_MAGIC) != 0 &&
(ifp->if_capabilities & IFCAP_WOL_MAGIC) != 0)
ifp->if_capenable ^= IFCAP_WOL_MAGIC;
#endif
if ((mask & IFCAP_VLAN_HWCSUM) != 0 &&
(ifp->if_capabilities & IFCAP_VLAN_HWCSUM) != 0)
ifp->if_capenable ^= IFCAP_VLAN_HWCSUM;
@@ -2073,67 +2101,14 @@ ale_mac_config(struct ale_softc *sc)
}
if ((IFM_OPTIONS(mii->mii_media_active) & IFM_FDX) != 0) {
reg |= MAC_CFG_FULL_DUPLEX;
#ifdef notyet
if ((IFM_OPTIONS(mii->mii_media_active) & IFM_ETH_TXPAUSE) != 0)
reg |= MAC_CFG_TX_FC;
if ((IFM_OPTIONS(mii->mii_media_active) & IFM_ETH_RXPAUSE) != 0)
reg |= MAC_CFG_RX_FC;
#endif
}
CSR_WRITE_4(sc, ALE_MAC_CFG, reg);
}
static void
ale_link_task(void *arg, int pending)
{
struct ale_softc *sc;
struct mii_data *mii;
struct ifnet *ifp;
uint32_t reg;
sc = (struct ale_softc *)arg;
ALE_LOCK(sc);
mii = device_get_softc(sc->ale_miibus);
ifp = sc->ale_ifp;
if (mii == NULL || ifp == NULL ||
(ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) {
ALE_UNLOCK(sc);
return;
}
sc->ale_flags &= ~ALE_FLAG_LINK;
if ((mii->mii_media_status & (IFM_ACTIVE | IFM_AVALID)) ==
(IFM_ACTIVE | IFM_AVALID)) {
switch (IFM_SUBTYPE(mii->mii_media_active)) {
case IFM_10_T:
case IFM_100_TX:
sc->ale_flags |= ALE_FLAG_LINK;
break;
case IFM_1000_T:
if ((sc->ale_flags & ALE_FLAG_FASTETHER) == 0)
sc->ale_flags |= ALE_FLAG_LINK;
break;
default:
break;
}
}
/* Stop Rx/Tx MACs. */
ale_stop_mac(sc);
/* Program MACs with resolved speed/duplex/flow-control. */
if ((sc->ale_flags & ALE_FLAG_LINK) != 0) {
ale_mac_config(sc);
/* Reenable Tx/Rx MACs. */
reg = CSR_READ_4(sc, ALE_MAC_CFG);
reg |= MAC_CFG_TX_ENB | MAC_CFG_RX_ENB;
CSR_WRITE_4(sc, ALE_MAC_CFG, reg);
}
ALE_UNLOCK(sc);
}
static void
ale_stats_clear(struct ale_softc *sc)
{
@@ -2884,14 +2859,14 @@ ale_init_locked(struct ale_softc *sc)
CSR_WRITE_4(sc, ALE_INTR_STATUS, 0xFFFFFFFF);
CSR_WRITE_4(sc, ALE_INTR_STATUS, 0);
ifp->if_drv_flags |= IFF_DRV_RUNNING;
ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
sc->ale_flags &= ~ALE_FLAG_LINK;
/* Switch to the current media. */
mii_mediachg(mii);
callout_reset(&sc->ale_tick_ch, hz, ale_tick, sc);
ifp->if_drv_flags |= IFF_DRV_RUNNING;
ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
}
static void
@@ -221,7 +221,6 @@ struct ale_softc {
int ale_pagesize;
struct task ale_int_task;
struct task ale_link_task;
struct taskqueue *ale_tq;
struct mtx ale_mtx;
};
@@ -16,13 +16,6 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the NetBSD
* Foundation, Inc. and its contributors.
* 4. Neither the name of The NetBSD Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
@@ -48,11 +41,6 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Manuel Bouyer.
* 4. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
@@ -67,7 +55,7 @@
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: src/sys/dev/mii/ukphy.c,v 1.20 2007/01/20 00:52:29 marius Exp $");
__FBSDID("$FreeBSD$");
/*
* driver for generic unknown PHYs
@@ -98,7 +86,7 @@ static device_method_t ukphy_methods[] = {
DEVMETHOD(device_attach, ukphy_attach),
DEVMETHOD(device_detach, mii_phy_detach),
DEVMETHOD(device_shutdown, bus_generic_shutdown),
{ 0, 0 }
DEVMETHOD_END
};
static devclass_t ukphy_devclass;
@@ -134,8 +122,6 @@ static int
ukphy_attach(device_t dev)
{
struct mii_softc *sc;
struct mii_attach_args *ma;
struct mii_data *mii;
sc = device_get_softc(dev);
@@ -148,29 +134,12 @@ ukphy_attach(device_t dev)
static int
ukphy_service(struct mii_softc *sc, struct mii_data *mii, int cmd)
{
struct ifmedia_entry *ife = mii->mii_media.ifm_cur;
int reg;
switch (cmd) {
case MII_POLLSTAT:
/*
* If we're not polling our PHY instance, just return.
*/
if (IFM_INST(ife->ifm_media) != sc->mii_inst)
return (0);
break;
case MII_MEDIACHG:
/*
* If the media indicates a different PHY instance,
* isolate ourselves.
*/
if (IFM_INST(ife->ifm_media) != sc->mii_inst) {
reg = PHY_READ(sc, MII_BMCR);
PHY_WRITE(sc, MII_BMCR, reg | BMCR_ISO);
return (0);
}
/*
* If the interface is not up, don't do anything.
*/
@@ -181,11 +150,6 @@ ukphy_service(struct mii_softc *sc, struct mii_data *mii, int cmd)
break;
case MII_TICK:
/*
* If we're not currently selected, just return.
*/
if (IFM_INST(ife->ifm_media) != sc->mii_inst)
return (0);
if (mii_phy_tick(sc) == EJUSTRETURN)
return (0);
break;
@@ -16,13 +16,6 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the NetBSD
* Foundation, Inc. and its contributors.
* 4. Neither the name of The NetBSD Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
@@ -38,7 +31,7 @@
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: src/sys/dev/mii/ukphy_subr.c,v 1.8.8.1 2006/07/19 04:40:26 yongari Exp $");
__FBSDID("$FreeBSD$");
/*
* Subroutines shared by the ukphy driver and other PHY drivers.
@@ -111,19 +104,26 @@ ukphy_status(struct mii_softc *phy)
mii->mii_media_active |= IFM_1000_T|IFM_FDX;
else if ((gtcr & GTCR_ADV_1000THDX) &&
(gtsr & GTSR_LP_1000THDX))
mii->mii_media_active |= IFM_1000_T;
else if (anlpar & ANLPAR_T4)
mii->mii_media_active |= IFM_100_T4;
mii->mii_media_active |= IFM_1000_T|IFM_HDX;
else if (anlpar & ANLPAR_TX_FD)
mii->mii_media_active |= IFM_100_TX|IFM_FDX;
else if (anlpar & ANLPAR_T4)
mii->mii_media_active |= IFM_100_T4|IFM_HDX;
else if (anlpar & ANLPAR_TX)
mii->mii_media_active |= IFM_100_TX;
mii->mii_media_active |= IFM_100_TX|IFM_HDX;
else if (anlpar & ANLPAR_10_FD)
mii->mii_media_active |= IFM_10_T|IFM_FDX;
else if (anlpar & ANLPAR_10)
mii->mii_media_active |= IFM_10_T;
mii->mii_media_active |= IFM_10_T|IFM_HDX;
else
mii->mii_media_active |= IFM_NONE;
if ((mii->mii_media_active & IFM_1000_T) != 0 &&
(gtsr & GTSR_MS_RES) != 0)
mii->mii_media_active |= IFM_ETH_MASTER;
if ((mii->mii_media_active & IFM_FDX) != 0)
mii->mii_media_active |= mii_phy_flowstatus(phy);
} else
mii->mii_media_active = ife->ifm_media;
}
@@ -349,9 +349,9 @@ alc_mediastatus(struct ifnet *ifp, struct ifmediareq *ifmr)
mii = device_get_softc(sc->alc_miibus);
mii_pollstat(mii);
ALC_UNLOCK(sc);
ifmr->ifm_status = mii->mii_media_status;
ifmr->ifm_active = mii->mii_media_active;
ALC_UNLOCK(sc);
}
static int
@@ -55,7 +55,7 @@
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: src/sys/dev/mii/ukphy.c,v 1.20.10.6.2.1 2010/12/21 17:09:25 kensmith Exp $");
__FBSDID("$FreeBSD$");
/*
* driver for generic unknown PHYs
@@ -86,7 +86,7 @@ static device_method_t ukphy_methods[] = {
DEVMETHOD(device_attach, ukphy_attach),
DEVMETHOD(device_detach, mii_phy_detach),
DEVMETHOD(device_shutdown, bus_generic_shutdown),
{ 0, 0 }
DEVMETHOD_END
};
static devclass_t ukphy_devclass;
@@ -31,7 +31,7 @@
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: src/sys/dev/mii/ukphy_subr.c,v 1.10.2.4.2.1 2010/12/21 17:09:25 kensmith Exp $");
__FBSDID("$FreeBSD$");
/*
* Subroutines shared by the ukphy driver and other PHY drivers.
@@ -282,9 +282,9 @@ age_mediastatus(struct ifnet *ifp, struct ifmediareq *ifmr)
mii = device_get_softc(sc->age_miibus);
mii_pollstat(mii);
AGE_UNLOCK(sc);
ifmr->ifm_status = mii->mii_media_status;
ifmr->ifm_active = mii->mii_media_active;
AGE_UNLOCK(sc);
}
/*
@@ -59,7 +59,7 @@ static device_method_t atphy_methods[] = {
DEVMETHOD(device_attach, atphy_attach),
DEVMETHOD(device_detach, mii_phy_detach),
DEVMETHOD(device_shutdown, bus_generic_shutdown),
{ NULL, NULL }
DEVMETHOD_END
};
static devclass_t atphy_devclass;
@@ -1385,12 +1385,13 @@ ae_pm_init(ae_softc_t *sc)
/*
* Configure PME.
*/
pci_find_cap(sc->dev, PCIY_PMG, &pmc);
if (pci_find_cap(sc->dev, PCIY_PMG, &pmc) == 0) {
pmstat = pci_read_config(sc->dev, pmc + PCIR_POWER_STATUS, 2);
pmstat &= ~(PCIM_PSTAT_PME | PCIM_PSTAT_PMEENABLE);
if ((ifp->if_capenable & IFCAP_WOL) != 0)
pmstat |= PCIM_PSTAT_PME | PCIM_PSTAT_PMEENABLE;
pci_write_config(sc->dev, pmc + PCIR_POWER_STATUS, pmstat, 2);
}
}
static int
@@ -1435,7 +1436,7 @@ ae_tx_avail_size(ae_softc_t *sc)
else
avail = sc->txd_ack - sc->txd_cur;
return (avail - 4); /* 4-byte header. */
return (avail);
}
static int
@@ -1452,7 +1453,7 @@ ae_encap(ae_softc_t *sc, struct mbuf **m_head)
len = m0->m_pkthdr.len;
if ((sc->flags & AE_FLAG_TXAVAIL) == 0 ||
ae_tx_avail_size(sc) < len) {
len + sizeof(ae_txd_t) + 3 > ae_tx_avail_size(sc)) {
#ifdef AE_DEBUG
if_printf(sc->ifp, "No free Tx available.\n");
#endif
@@ -1461,11 +1462,10 @@ ae_encap(ae_softc_t *sc, struct mbuf **m_head)
hdr = (ae_txd_t *)(sc->txd_base + sc->txd_cur);
bzero(hdr, sizeof(*hdr));
sc->txd_cur = (sc->txd_cur + 4) % AE_TXD_BUFSIZE_DEFAULT; /* Header
size. */
to_end = AE_TXD_BUFSIZE_DEFAULT - sc->txd_cur; /* Space available to
* the end of the ring
*/
/* Skip header size. */
sc->txd_cur = (sc->txd_cur + sizeof(ae_txd_t)) % AE_TXD_BUFSIZE_DEFAULT;
/* Space available to the end of the ring */
to_end = AE_TXD_BUFSIZE_DEFAULT - sc->txd_cur;
if (to_end >= len) {
m_copydata(m0, 0, len, (caddr_t)(sc->txd_base + sc->txd_cur));
} else {
@@ -1844,8 +1844,8 @@ ae_tx_intr(ae_softc_t *sc)
/*
* Move txd ack and align on 4-byte boundary.
*/
sc->txd_ack = ((sc->txd_ack + le16toh(txd->len) + 4 + 3) & ~3) %
AE_TXD_BUFSIZE_DEFAULT;
sc->txd_ack = ((sc->txd_ack + le16toh(txd->len) +
sizeof(ae_txs_t) + 3) & ~3) % AE_TXD_BUFSIZE_DEFAULT;
if ((flags & AE_TXS_SUCCESS) != 0)
ifp->if_opackets++;
@@ -55,7 +55,7 @@
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: src/sys/dev/mii/ukphy.c,v 1.20.10.6.2.1 2010/12/21 17:09:25 kensmith Exp $");
__FBSDID("$FreeBSD$");
/*
* driver for generic unknown PHYs
@@ -86,7 +86,7 @@ static device_method_t ukphy_methods[] = {
DEVMETHOD(device_attach, ukphy_attach),
DEVMETHOD(device_detach, mii_phy_detach),
DEVMETHOD(device_shutdown, bus_generic_shutdown),
{ 0, 0 }
DEVMETHOD_END
};
static devclass_t ukphy_devclass;
@@ -31,7 +31,7 @@
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: src/sys/dev/mii/ukphy_subr.c,v 1.10.2.4.2.1 2010/12/21 17:09:25 kensmith Exp $");
__FBSDID("$FreeBSD$");
/*
* Subroutines shared by the ukphy driver and other PHY drivers.
@@ -137,16 +137,12 @@ static device_method_t bfe_methods[] = {
DEVMETHOD(device_suspend, bfe_suspend),
DEVMETHOD(device_resume, bfe_resume),
/* bus interface */
DEVMETHOD(bus_print_child, bus_generic_print_child),
DEVMETHOD(bus_driver_added, bus_generic_driver_added),
/* MII interface */
DEVMETHOD(miibus_readreg, bfe_miibus_readreg),
DEVMETHOD(miibus_writereg, bfe_miibus_writereg),
DEVMETHOD(miibus_statchg, bfe_miibus_statchg),
{ 0, 0 }
DEVMETHOD_END
};
static driver_t bfe_driver = {
@@ -91,8 +91,7 @@ static device_method_t bmtphy_methods[] = {
DEVMETHOD(device_attach, bmtphy_attach),
DEVMETHOD(device_detach, mii_phy_detach),
DEVMETHOD(device_shutdown, bus_generic_shutdown),
{ 0, 0 }
DEVMETHOD_END
};
static devclass_t bmtphy_devclass;
@@ -576,7 +576,6 @@ default: DBPRINT(sc, BCE_INSANE_PHY, \
#define BCE_CHIP_NUM_5706 0x57060000
#define BCE_CHIP_NUM_5708 0x57080000
#define BCE_CHIP_NUM_5709 0x57090000
#define BCE_CHIP_NUM_5716 0x57160000
#define BCE_CHIP_REV(sc) (((sc)->bce_chipid) & 0x0000f000)
#define BCE_CHIP_REV_Ax 0x00000000
@@ -601,7 +600,6 @@ default: DBPRINT(sc, BCE_INSANE_PHY, \
#define BCE_CHIP_ID_5709_B1 0x57091010
#define BCE_CHIP_ID_5709_B2 0x57091020
#define BCE_CHIP_ID_5709_C0 0x57092000
#define BCE_CHIP_ID_5716_C0 0x57162000
#define BCE_CHIP_BOND_ID(sc) (((sc)->bce_chipid) & 0xf)
@@ -816,6 +814,23 @@ struct flash_spec {
#define BCE_DRV_PULSE_SEQ_MASK 0x00007fff
#define BCE_MB_ARGS_0 0x00000014
#define BCE_NETLINK_SPEED_10HALF (1<<0)
#define BCE_NETLINK_SPEED_10FULL (1<<1)
#define BCE_NETLINK_SPEED_100HALF (1<<2)
#define BCE_NETLINK_SPEED_100FULL (1<<3)
#define BCE_NETLINK_SPEED_1000HALF (1<<4)
#define BCE_NETLINK_SPEED_1000FULL (1<<5)
#define BCE_NETLINK_SPEED_2500HALF (1<<6)
#define BCE_NETLINK_SPEED_2500FULL (1<<7)
#define BCE_NETLINK_SPEED_10GHALF (1<<8)
#define BCE_NETLINK_SPEED_10GFULL (1<<9)
#define BCE_NETLINK_ANEG_ENB (1<<10)
#define BCE_NETLINK_PHY_APP_REMOTE (1<<11)
#define BCE_NETLINK_FC_PAUSE_SYM (1<<12)
#define BCE_NETLINK_FC_PAUSE_ASYM (1<<13)
#define BCE_NETLINK_ETH_AT_WIRESPEED (1<<14)
#define BCE_NETLINK_PHY_RESET (1<<15)
#define BCE_MB_ARGS_1 0x00000018
/* Indicate to the firmware not to go into the
@@ -1081,6 +1096,26 @@ struct flash_spec {
#define BCE_BC_STATE_BC_DBG_CMD_LOOP_CNT_MASK 0xffff
#define BCE_BC_STATE_BC_DBG_CMD_LOOP_INFINITE 0xffff
#define BCE_FW_EVT_CODE_MB 0x00000354
#define BCE_FW_EVT_CODE_SW_TIMER_EXPIRE_EVENT 0x00000000
#define BCE_FW_EVT_CODE_LINK_EVENT 0x00000001
#define BCE_DRV_ACK_CAP_MB 0x00000364
#define BCE_DRV_ACK_CAP_SIGNATURE_MAGIC 0x35450000
#define BCE_FW_CAP_MB 0x00000368
#define BCE_FW_CAP_SIGNATURE_MAGIC 0xaa550000
#define BCE_FW_ACK_SIGNATURE_MAGIC 0x52500000
#define BCE_FW_CAP_SIGNATURE_MAGIC_MASK 0xffff0000
#define BCE_FW_CAP_REMOTE_PHY_CAP 0x00000001
#define BCE_FW_CAP_REMOTE_PHY_PRESENT 0x00000002
#define BCE_FW_CAP_MFW_KEEP_VLAN 0x00000008
#define BCE_FW_CAP_BC_KEEP_VLAN 0x00000010
#define BCE_RPHY_SERDES_LINK 0x00000374
#define BCE_RPHY_COPPER_LINK 0x00000378
#define HOST_VIEW_SHMEM_BASE 0x167c00
/*
@@ -6456,6 +6491,8 @@ struct bce_softc
#define BCE_PHY_INT_MODE_AUTO_POLLING_FLAG 0x00000100
#define BCE_PHY_INT_MODE_LINK_READY_FLAG 0x00000200
#define BCE_PHY_IEEE_CLAUSE_45_FLAG 0x00000400
#define BCE_PHY_REMOTE_CAP_FLAG 0x00000800
#define BCE_PHY_REMOTE_PORT_FIBER_FLAG 0x00001000
/* Values that need to be shared with the PHY driver. */
u32 bce_shared_hw_cfg;
@@ -301,6 +301,7 @@ static const struct bge_revision {
{ BGE_CHIPID_BCM5717_A0, "BCM5717 A0" },
{ BGE_CHIPID_BCM5717_B0, "BCM5717 B0" },
{ BGE_CHIPID_BCM5719_A0, "BCM5719 A0" },
{ BGE_CHIPID_BCM5720_A0, "BCM5720 A0" },
{ BGE_CHIPID_BCM5755_A0, "BCM5755 A0" },
{ BGE_CHIPID_BCM5755_A1, "BCM5755 A1" },
{ BGE_CHIPID_BCM5755_A2, "BCM5755 A2" },
@@ -349,6 +350,7 @@ static const struct bge_revision const bge_majorrevs[] = {
{ BGE_ASICREV_BCM57780, "unknown BCM57780" },
{ BGE_ASICREV_BCM5717, "unknown BCM5717" },
{ BGE_ASICREV_BCM5719, "unknown BCM5719" },
{ BGE_ASICREV_BCM5720, "unknown BCM5720" },
{ 0, NULL }
};
@@ -378,6 +380,9 @@ static void bge_dma_free(struct bge_softc *);
static int bge_dma_ring_alloc(struct bge_softc *, bus_size_t, bus_size_t,
bus_dma_tag_t *, uint8_t **, bus_dmamap_t *, bus_addr_t *, const char *);
static void bge_devinfo(struct bge_softc *);
static int bge_mbox_reorder(struct bge_softc *);
static int bge_get_eaddr_fw(struct bge_softc *sc, uint8_t ether_addr[]);
static int bge_get_eaddr_mem(struct bge_softc *, uint8_t[]);
static int bge_get_eaddr_nvram(struct bge_softc *, uint8_t[]);
@@ -437,6 +442,7 @@ static int bge_init_tx_ring(struct bge_softc *);
static int bge_chipinit(struct bge_softc *);
static int bge_blockinit(struct bge_softc *);
static uint32_t bge_dma_swap_options(struct bge_softc *);
static int bge_has_eaddr(struct bge_softc *);
static uint32_t bge_readmem_ind(struct bge_softc *, int);
@@ -492,16 +498,12 @@ static device_method_t bge_methods[] = {
DEVMETHOD(device_suspend, bge_suspend),
DEVMETHOD(device_resume, bge_resume),
/* bus interface */
DEVMETHOD(bus_print_child, bus_generic_print_child),
DEVMETHOD(bus_driver_added, bus_generic_driver_added),
/* MII interface */
DEVMETHOD(miibus_readreg, bge_miibus_readreg),
DEVMETHOD(miibus_writereg, bge_miibus_writereg),
DEVMETHOD(miibus_statchg, bge_miibus_statchg),
{ 0, 0 }
DEVMETHOD_END
};
static driver_t bge_driver = {
@@ -642,6 +644,8 @@ bge_writembx(struct bge_softc *sc, int off, int val)
off += BGE_LPMBX_IRQ0_HI - BGE_MBX_IRQ0_HI;
CSR_WRITE_4(sc, off, val);
if ((sc->bge_flags & BGE_FLAG_MBOX_REORDER) != 0)
CSR_READ_4(sc, off);
}
/*
@@ -1315,15 +1319,17 @@ bge_sig_pre_reset(struct bge_softc *sc, int type)
* Some chips don't like this so only do this if ASF is enabled
*/
if (sc->bge_asf_mode)
bge_writemem_ind(sc, BGE_SOFTWARE_GENCOMM, BGE_MAGIC_NUMBER);
bge_writemem_ind(sc, BGE_SRAM_FW_MB, BGE_SRAM_FW_MB_MAGIC);
if (sc->bge_asf_mode & ASF_NEW_HANDSHAKE) {
switch (type) {
case BGE_RESET_START:
bge_writemem_ind(sc, BGE_SDI_STATUS, 0x1); /* START */
bge_writemem_ind(sc, BGE_SRAM_FW_DRV_STATE_MB,
BGE_FW_DRV_STATE_START);
break;
case BGE_RESET_STOP:
bge_writemem_ind(sc, BGE_SDI_STATUS, 0x2); /* UNLOAD */
bge_writemem_ind(sc, BGE_SRAM_FW_DRV_STATE_MB,
BGE_FW_DRV_STATE_UNLOAD);
break;
}
}
@@ -1336,11 +1342,13 @@ bge_sig_post_reset(struct bge_softc *sc, int type)
if (sc->bge_asf_mode & ASF_NEW_HANDSHAKE) {
switch (type) {
case BGE_RESET_START:
bge_writemem_ind(sc, BGE_SDI_STATUS, 0x80000001);
bge_writemem_ind(sc, BGE_SRAM_FW_DRV_STATE_MB,
BGE_FW_DRV_STATE_START_DONE);
/* START DONE */
break;
case BGE_RESET_STOP:
bge_writemem_ind(sc, BGE_SDI_STATUS, 0x80000002);
bge_writemem_ind(sc, BGE_SRAM_FW_DRV_STATE_MB,
BGE_FW_DRV_STATE_UNLOAD_DONE);
break;
}
}
@@ -1353,10 +1361,12 @@ bge_sig_legacy(struct bge_softc *sc, int type)
if (sc->bge_asf_mode) {
switch (type) {
case BGE_RESET_START:
bge_writemem_ind(sc, BGE_SDI_STATUS, 0x1); /* START */
bge_writemem_ind(sc, BGE_SRAM_FW_DRV_STATE_MB,
BGE_FW_DRV_STATE_START);
break;
case BGE_RESET_STOP:
bge_writemem_ind(sc, BGE_SDI_STATUS, 0x2); /* UNLOAD */
bge_writemem_ind(sc, BGE_SRAM_FW_DRV_STATE_MB,
BGE_FW_DRV_STATE_UNLOAD);
break;
}
}
@@ -1368,25 +1378,44 @@ bge_stop_fw(struct bge_softc *sc)
int i;
if (sc->bge_asf_mode) {
bge_writemem_ind(sc, BGE_SOFTWARE_GENCOMM_FW, BGE_FW_PAUSE);
CSR_WRITE_4(sc, BGE_CPU_EVENT,
CSR_READ_4(sc, BGE_CPU_EVENT) | (1 << 14));
bge_writemem_ind(sc, BGE_SRAM_FW_CMD_MB, BGE_FW_CMD_PAUSE);
CSR_WRITE_4(sc, BGE_RX_CPU_EVENT,
CSR_READ_4(sc, BGE_RX_CPU_EVENT) | BGE_RX_CPU_DRV_EVENT);
for (i = 0; i < 100; i++ ) {
if (!(CSR_READ_4(sc, BGE_CPU_EVENT) & (1 << 14)))
if (!(CSR_READ_4(sc, BGE_RX_CPU_EVENT) &
BGE_RX_CPU_DRV_EVENT))
break;
DELAY(10);
}
}
}
static uint32_t
bge_dma_swap_options(struct bge_softc *sc)
{
uint32_t dma_options;
dma_options = BGE_MODECTL_WORDSWAP_NONFRAME |
BGE_MODECTL_BYTESWAP_DATA | BGE_MODECTL_WORDSWAP_DATA;
#if BYTE_ORDER == BIG_ENDIAN
dma_options |= BGE_MODECTL_BYTESWAP_NONFRAME;
#endif
if ((sc)->bge_asicrev == BGE_ASICREV_BCM5720)
dma_options |= BGE_MODECTL_BYTESWAP_B2HRX_DATA |
BGE_MODECTL_WORDSWAP_B2HRX_DATA | BGE_MODECTL_B2HRX_ENABLE |
BGE_MODECTL_HTX2B_ENABLE;
return (dma_options);
}
/*
* Do endian, PCI and DMA initialization.
*/
static int
bge_chipinit(struct bge_softc *sc)
{
uint32_t dma_rw_ctl, misc_ctl;
uint32_t dma_rw_ctl, misc_ctl, mode_ctl;
uint16_t val;
int i;
@@ -1504,9 +1533,8 @@ bge_chipinit(struct bge_softc *sc)
/*
* Set up general mode register.
*/
CSR_WRITE_4(sc, BGE_MODE_CTL, BGE_DMA_SWAP_OPTIONS |
BGE_MODECTL_MAC_ATTN_INTR | BGE_MODECTL_HOST_SEND_BDS |
BGE_MODECTL_TX_NO_PHDR_CSUM);
mode_ctl = bge_dma_swap_options(sc) | BGE_MODECTL_MAC_ATTN_INTR |
BGE_MODECTL_HOST_SEND_BDS | BGE_MODECTL_TX_NO_PHDR_CSUM;
/*
* BCM5701 B5 have a bug causing data corruption when using
@@ -1516,13 +1544,15 @@ bge_chipinit(struct bge_softc *sc)
*/
if (sc->bge_asicrev == BGE_ASICREV_BCM5701 &&
sc->bge_chipid == BGE_CHIPID_BCM5701_B5)
BGE_SETBIT(sc, BGE_MODE_CTL, BGE_MODECTL_FORCE_PCI32);
mode_ctl |= BGE_MODECTL_FORCE_PCI32;
/*
* Tell the firmware the driver is running
*/
if (sc->bge_asf_mode & ASF_STACKUP)
BGE_SETBIT(sc, BGE_MODE_CTL, BGE_MODECTL_STACKUP);
mode_ctl |= BGE_MODECTL_STACKUP;
CSR_WRITE_4(sc, BGE_MODE_CTL, mode_ctl);
/*
* Disable memory write invalidate. Apparently it is not supported
@@ -1582,8 +1612,7 @@ bge_blockinit(struct bge_softc *sc)
}
/* Configure mbuf pool watermarks */
if (sc->bge_asicrev == BGE_ASICREV_BCM5717 ||
sc->bge_asicrev == BGE_ASICREV_BCM57765) {
if (BGE_IS_5717_PLUS(sc)) {
CSR_WRITE_4(sc, BGE_BMAN_MBUFPOOL_READDMA_LOWAT, 0x0);
if (sc->bge_ifp->if_mtu > ETHERMTU) {
CSR_WRITE_4(sc, BGE_BMAN_MBUFPOOL_MACRX_LOWAT, 0x7e);
@@ -1718,7 +1747,8 @@ bge_blockinit(struct bge_softc *sc)
BGE_RCB_MAXLEN_FLAGS(BGE_MAX_FRAMELEN, 0);
}
if (sc->bge_asicrev == BGE_ASICREV_BCM5717 ||
sc->bge_asicrev == BGE_ASICREV_BCM5719)
sc->bge_asicrev == BGE_ASICREV_BCM5719 ||
sc->bge_asicrev == BGE_ASICREV_BCM5720)
rcb->bge_nicaddr = BGE_STD_RX_RINGS_5717;
else
rcb->bge_nicaddr = BGE_STD_RX_RINGS;
@@ -1751,7 +1781,8 @@ bge_blockinit(struct bge_softc *sc)
rcb->bge_maxlen_flags = BGE_RCB_MAXLEN_FLAGS(0,
BGE_RCB_FLAG_USE_EXT_RX_BD | BGE_RCB_FLAG_RING_DISABLED);
if (sc->bge_asicrev == BGE_ASICREV_BCM5717 ||
sc->bge_asicrev == BGE_ASICREV_BCM5719)
sc->bge_asicrev == BGE_ASICREV_BCM5719 ||
sc->bge_asicrev == BGE_ASICREV_BCM5720)
rcb->bge_nicaddr = BGE_JUMBO_RX_RINGS_5717;
else
rcb->bge_nicaddr = BGE_JUMBO_RX_RINGS;
@@ -1840,7 +1871,8 @@ bge_blockinit(struct bge_softc *sc)
RCB_WRITE_4(sc, vrcb, bge_hostaddr.bge_addr_hi, taddr.bge_addr_hi);
RCB_WRITE_4(sc, vrcb, bge_hostaddr.bge_addr_lo, taddr.bge_addr_lo);
if (sc->bge_asicrev == BGE_ASICREV_BCM5717 ||
sc->bge_asicrev == BGE_ASICREV_BCM5719)
sc->bge_asicrev == BGE_ASICREV_BCM5719 ||
sc->bge_asicrev == BGE_ASICREV_BCM5720)
RCB_WRITE_4(sc, vrcb, bge_nicaddr, BGE_SEND_RING_5717);
else
RCB_WRITE_4(sc, vrcb, bge_nicaddr,
@@ -1854,7 +1886,8 @@ bge_blockinit(struct bge_softc *sc)
* return ring control blocks, located in NIC memory.
*/
if (sc->bge_asicrev == BGE_ASICREV_BCM5717 ||
sc->bge_asicrev == BGE_ASICREV_BCM5719) {
sc->bge_asicrev == BGE_ASICREV_BCM5719 ||
sc->bge_asicrev == BGE_ASICREV_BCM5720) {
/* Should be 17, use 16 until we get an SRAM map. */
limit = 16;
} else if (!BGE_IS_5705_PLUS(sc))
@@ -1898,7 +1931,11 @@ bge_blockinit(struct bge_softc *sc)
BGE_TX_BACKOFF_SEED_MASK);
/* Set inter-packet gap */
CSR_WRITE_4(sc, BGE_TX_LENGTHS, 0x2620);
val = 0x2620;
if (sc->bge_asicrev == BGE_ASICREV_BCM5720)
val |= CSR_READ_4(sc, BGE_TX_LENGTHS) &
(BGE_TXLEN_JMB_FRM_LEN_MSK | BGE_TXLEN_CNT_DN_VAL_MSK);
CSR_WRITE_4(sc, BGE_TX_LENGTHS, val);
/*
* Specify which ring to use for packets that don't match
@@ -2053,6 +2090,17 @@ bge_blockinit(struct bge_softc *sc)
sc->bge_asicrev == BGE_ASICREV_BCM57780)
val |= BGE_RDMAMODE_TSO6_ENABLE;
}
if (sc->bge_asicrev == BGE_ASICREV_BCM5720) {
val |= CSR_READ_4(sc, BGE_RDMA_MODE) &
BGE_RDMAMODE_H2BNC_VLAN_DET;
/*
* Allow multiple outstanding read requests from
* non-LSO read DMA engine.
*/
val &= ~BGE_RDMAMODE_MULT_DMA_RD_DIS;
}
if (sc->bge_asicrev == BGE_ASICREV_BCM5761 ||
sc->bge_asicrev == BGE_ASICREV_BCM5784 ||
sc->bge_asicrev == BGE_ASICREV_BCM5785 ||
@@ -2063,7 +2111,8 @@ bge_blockinit(struct bge_softc *sc)
* Adjust tx margin to prevent TX data corruption and
* fix internal FIFO overflow.
*/
if (sc->bge_asicrev == BGE_ASICREV_BCM5719) {
if (sc->bge_asicrev == BGE_ASICREV_BCM5719 ||
sc->bge_asicrev == BGE_ASICREV_BCM5720) {
dmactl &= ~(BGE_RDMA_RSRVCTRL_FIFO_LWM_MASK |
BGE_RDMA_RSRVCTRL_FIFO_HWM_MASK |
BGE_RDMA_RSRVCTRL_TXMRGN_MASK);
@@ -2085,6 +2134,15 @@ bge_blockinit(struct bge_softc *sc)
CSR_READ_4(sc, BGE_RDMA_LSO_CRPTEN_CTRL) |
BGE_RDMA_LSO_CRPTEN_CTRL_BLEN_BD_4K |
BGE_RDMA_LSO_CRPTEN_CTRL_BLEN_LSO_4K);
} else if (sc->bge_asicrev == BGE_ASICREV_BCM5720) {
/*
* Allow 4KB burst length reads for non-LSO frames.
* Enable 512B burst length reads for buffer descriptors.
*/
CSR_WRITE_4(sc, BGE_RDMA_LSO_CRPTEN_CTRL,
CSR_READ_4(sc, BGE_RDMA_LSO_CRPTEN_CTRL) |
BGE_RDMA_LSO_CRPTEN_CTRL_BLEN_BD_512 |
BGE_RDMA_LSO_CRPTEN_CTRL_BLEN_LSO_4K);
}
CSR_WRITE_4(sc, BGE_RDMA_MODE, val);
@@ -2239,6 +2297,7 @@ bge_probe(device_t dev)
case BCOM_DEVICEID_BCM5717:
case BCOM_DEVICEID_BCM5718:
case BCOM_DEVICEID_BCM5719:
case BCOM_DEVICEID_BCM5720:
id = pci_read_config(dev,
BGE_PCI_GEN2_PRODID_ASICREV, 4);
break;
@@ -2310,10 +2369,11 @@ bge_dma_free(struct bge_softc *sc)
if (sc->bge_cdata.bge_rx_mtag)
bus_dma_tag_destroy(sc->bge_cdata.bge_rx_mtag);
if (sc->bge_cdata.bge_mtag_jumbo)
bus_dma_tag_destroy(sc->bge_cdata.bge_mtag_jumbo);
if (sc->bge_cdata.bge_tx_mtag)
bus_dma_tag_destroy(sc->bge_cdata.bge_tx_mtag);
/* Destroy standard RX ring. */
if (sc->bge_cdata.bge_rx_std_ring_map)
bus_dmamap_unload(sc->bge_cdata.bge_rx_std_ring_tag,
@@ -2559,10 +2619,10 @@ bge_dma_alloc(struct bge_softc *sc)
* XXX
* watchdog timeout issue was observed on BCM5704 which
* lives behind PCI-X bridge(e.g AMD 8131 PCI-X bridge).
* Limiting DMA address space to 32bits seems to address
* it.
* Both limiting DMA address space to 32bits and flushing
* mailbox write seem to address the issue.
*/
if (sc->bge_flags & BGE_FLAG_PCIX)
if (sc->bge_pcixcap != 0)
lowaddr = BUS_SPACE_MAXADDR_32BIT;
}
error = bus_dma_tag_create(bus_get_dma_tag(sc->bge_dev),
@@ -2701,6 +2761,9 @@ bge_can_use_msi(struct bge_softc *sc)
return 0;
#endif
if (sc->bge_msi == 0)
return (0);
/* Disable MSI for polling(4). */
#ifdef DEVICE_POLLING
return (0);
@@ -2727,6 +2790,102 @@ bge_can_use_msi(struct bge_softc *sc)
return (can_use_msi);
}
static int
bge_mbox_reorder(struct bge_softc *sc)
{
#ifndef __HAIKU__
/* Lists of PCI bridges that are known to reorder mailbox writes. */
static const struct mbox_reorder {
const uint16_t vendor;
const uint16_t device;
const char *desc;
} const mbox_reorder_lists[] = {
{ 0x1022, 0x7450, "AMD-8131 PCI-X Bridge" },
};
devclass_t pci, pcib;
device_t bus, dev;
int i;
pci = devclass_find("pci");
pcib = devclass_find("pcib");
dev = sc->bge_dev;
bus = device_get_parent(dev);
for (;;) {
dev = device_get_parent(bus);
bus = device_get_parent(dev);
if (device_get_devclass(dev) != pcib)
break;
for (i = 0; i < nitems(mbox_reorder_lists); i++) {
if (pci_get_vendor(dev) ==
mbox_reorder_lists[i].vendor &&
pci_get_device(dev) ==
mbox_reorder_lists[i].device) {
device_printf(sc->bge_dev,
"enabling MBOX workaround for %s\n",
mbox_reorder_lists[i].desc);
return (1);
}
}
if (device_get_devclass(bus) != pci)
break;
}
#endif
return (0);
}
static void
bge_devinfo(struct bge_softc *sc)
{
uint32_t cfg, clk;
device_printf(sc->bge_dev,
"CHIP ID 0x%08x; ASIC REV 0x%02x; CHIP REV 0x%02x; ",
sc->bge_chipid, sc->bge_asicrev, sc->bge_chiprev);
if (sc->bge_flags & BGE_FLAG_PCIE)
printf("PCI-E\n");
else if (sc->bge_flags & BGE_FLAG_PCIX) {
printf("PCI-X ");
cfg = CSR_READ_4(sc, BGE_MISC_CFG) & BGE_MISCCFG_BOARD_ID_MASK;
if (cfg == BGE_MISCCFG_BOARD_ID_5704CIOBE)
clk = 133;
else {
clk = CSR_READ_4(sc, BGE_PCI_CLKCTL) & 0x1F;
switch (clk) {
case 0:
clk = 33;
break;
case 2:
clk = 50;
break;
case 4:
clk = 66;
break;
case 6:
clk = 100;
break;
case 7:
clk = 133;
break;
}
}
printf("%u MHz\n", clk);
} else {
if (sc->bge_pcixcap != 0)
printf("PCI on PCI-X ");
else
printf("PCI ");
cfg = pci_read_config(sc->bge_dev, BGE_PCI_PCISTATE, 4);
if (cfg & BGE_PCISTATE_PCI_BUSSPEED)
clk = 66;
else
clk = 33;
if (cfg & BGE_PCISTATE_32BIT_BUS)
printf("%u MHz; 32bit\n", clk);
else
printf("%u MHz; 64bit\n", clk);
}
}
static int
bge_attach(device_t dev)
{
@@ -2769,6 +2928,7 @@ bge_attach(device_t dev)
case BCOM_DEVICEID_BCM5717:
case BCOM_DEVICEID_BCM5718:
case BCOM_DEVICEID_BCM5719:
case BCOM_DEVICEID_BCM5720:
sc->bge_chipid = pci_read_config(dev,
BGE_PCI_GEN2_PRODID_ASICREV, 4);
break;
@@ -2800,12 +2960,14 @@ bge_attach(device_t dev)
* BCM5704 | 1 | X | 1 | X |
* BCM5717 | 1 | 8 | 2 | 9 |
* BCM5719 | 1 | 8 | 2 | 9 |
* BCM5720 | 1 | 8 | 2 | 9 |
*
* Other addresses may respond but they are not
* IEEE compliant PHYs and should be ignored.
*/
if (sc->bge_asicrev == BGE_ASICREV_BCM5717 ||
sc->bge_asicrev == BGE_ASICREV_BCM5719) {
sc->bge_asicrev == BGE_ASICREV_BCM5719 ||
sc->bge_asicrev == BGE_ASICREV_BCM5720) {
f = pci_get_function(dev);
if (sc->bge_chipid == BGE_CHIPID_BCM5717_A0) {
if (CSR_READ_4(sc, BGE_SGDIG_STS) &
@@ -2840,7 +3002,7 @@ bge_attach(device_t dev)
switch (sc->bge_asicrev) {
case BGE_ASICREV_BCM5717:
case BGE_ASICREV_BCM5719:
sc->bge_flags |= BGE_FLAG_SHORT_DMA_BUG;
case BGE_ASICREV_BCM5720:
case BGE_ASICREV_BCM57765:
sc->bge_flags |= BGE_FLAG_5717_PLUS | BGE_FLAG_5755_PLUS |
BGE_FLAG_575X_PLUS | BGE_FLAG_5705_PLUS | BGE_FLAG_JUMBO |
@@ -2875,14 +3037,15 @@ bge_attach(device_t dev)
case BGE_ASICREV_BCM5752:
case BGE_ASICREV_BCM5906:
sc->bge_flags |= BGE_FLAG_575X_PLUS;
if (sc->bge_asicrev == BGE_ASICREV_BCM5906)
sc->bge_flags |= BGE_FLAG_SHORT_DMA_BUG;
/* FALLTHROUGH */
case BGE_ASICREV_BCM5705:
sc->bge_flags |= BGE_FLAG_5705_PLUS;
break;
}
/* Add SYSCTLs, requires the chipset family to be set. */
bge_add_sysctls(sc);
/* Set various PHY bug flags. */
if (sc->bge_chipid == BGE_CHIPID_BCM5701_A0 ||
sc->bge_chipid == BGE_CHIPID_BCM5701_B0)
@@ -2898,6 +3061,7 @@ bge_attach(device_t dev)
sc->bge_asicrev != BGE_ASICREV_BCM5906 &&
sc->bge_asicrev != BGE_ASICREV_BCM5717 &&
sc->bge_asicrev != BGE_ASICREV_BCM5719 &&
sc->bge_asicrev != BGE_ASICREV_BCM5720 &&
sc->bge_asicrev != BGE_ASICREV_BCM5785 &&
sc->bge_asicrev != BGE_ASICREV_BCM57765 &&
sc->bge_asicrev != BGE_ASICREV_BCM57780) {
@@ -2930,17 +3094,28 @@ bge_attach(device_t dev)
sc->bge_mi_mode |= BGE_MIMODE_AUTOPOLL;
/*
* All controllers that are not 5755 or higher have 4GB
* boundary DMA bug.
* All Broadcom controllers have 4GB boundary DMA bug.
* Whenever an address crosses a multiple of the 4GB boundary
* (including 4GB, 8Gb, 12Gb, etc.) and makes the transition
* from 0xX_FFFF_FFFF to 0x(X+1)_0000_0000 an internal DMA
* state machine will lockup and cause the device to hang.
*/
if (BGE_IS_5755_PLUS(sc) == 0)
sc->bge_flags |= BGE_FLAG_4G_BNDRY_BUG;
misccfg = CSR_READ_4(sc, BGE_MISC_CFG) & BGE_MISCCFG_BOARD_ID;
/* BCM5755 or higher and BCM5906 have short DMA bug. */
if (BGE_IS_5755_PLUS(sc) || sc->bge_asicrev == BGE_ASICREV_BCM5906)
sc->bge_flags |= BGE_FLAG_SHORT_DMA_BUG;
/*
* BCM5719 cannot handle DMA requests for DMA segments that
* have larger than 4KB in size. However the maximum DMA
* segment size created in DMA tag is 4KB for TSO, so we
* wouldn't encounter the issue here.
*/
if (sc->bge_asicrev == BGE_ASICREV_BCM5719)
sc->bge_flags |= BGE_FLAG_4K_RDMA_BUG;
misccfg = CSR_READ_4(sc, BGE_MISC_CFG) & BGE_MISCCFG_BOARD_ID_MASK;
if (sc->bge_asicrev == BGE_ASICREV_BCM5705) {
if (misccfg == BGE_MISCCFG_BOARD_ID_5788 ||
misccfg == BGE_MISCCFG_BOARD_ID_5788M)
@@ -3007,7 +3182,8 @@ bge_attach(device_t dev)
*/
sc->bge_flags |= BGE_FLAG_PCIE;
sc->bge_expcap = reg;
if (sc->bge_asicrev == BGE_ASICREV_BCM5719)
if (sc->bge_asicrev == BGE_ASICREV_BCM5719 ||
sc->bge_asicrev == BGE_ASICREV_BCM5720)
pci_set_max_read_req(dev, 2048);
else if (pci_get_max_read_req(dev) != 4096)
pci_set_max_read_req(dev, 4096);
@@ -3030,6 +3206,16 @@ bge_attach(device_t dev)
*/
if (BGE_IS_5714_FAMILY(sc) && (sc->bge_flags & BGE_FLAG_PCIX))
sc->bge_flags |= BGE_FLAG_40BIT_BUG;
/*
* Some PCI-X bridges are known to trigger write reordering to
* the mailbox registers. Typical phenomena is watchdog timeouts
* caused by out-of-order TX completions. Enable workaround for
* PCI-X devices that live behind these bridges.
* Note, PCI-X controllers can run in PCI mode so we can't use
* BGE_FLAG_PCIX flag to detect PCI-X controllers.
*/
if (sc->bge_pcixcap != 0 && bge_mbox_reorder(sc) != 0)
sc->bge_flags |= BGE_FLAG_MBOX_REORDER;
/*
* Allocate the interrupt, using MSI if possible. These devices
* support 8 MSI messages, but only the first one is used in
@@ -3069,11 +3255,7 @@ bge_attach(device_t dev)
goto fail;
}
device_printf(dev,
"CHIP ID 0x%08x; ASIC REV 0x%02x; CHIP REV 0x%02x; %s\n",
sc->bge_chipid, sc->bge_asicrev, sc->bge_chiprev,
(sc->bge_flags & BGE_FLAG_PCIX) ? "PCI-X" :
((sc->bge_flags & BGE_FLAG_PCIE) ? "PCI-E" : "PCI"));
bge_devinfo(sc);
BGE_LOCK_INIT(sc, device_get_nameunit(dev));
@@ -3085,9 +3267,9 @@ bge_attach(device_t dev)
}
sc->bge_asf_mode = 0;
if (bge_allow_asf && (bge_readmem_ind(sc, BGE_SOFTWARE_GENCOMM_SIG)
== BGE_MAGIC_NUMBER)) {
if (bge_readmem_ind(sc, BGE_SOFTWARE_GENCOMM_NICCFG)
if (bge_allow_asf && (bge_readmem_ind(sc, BGE_SRAM_DATA_SIG) ==
BGE_SRAM_DATA_SIG_MAGIC)) {
if (bge_readmem_ind(sc, BGE_SRAM_DATA_CFG)
& BGE_HWCFG_ASF) {
sc->bge_asf_mode |= ASF_ENABLE;
sc->bge_asf_mode |= ASF_STACKUP;
@@ -3137,8 +3319,6 @@ bge_attach(device_t dev)
goto fail;
}
bge_add_sysctls(sc);
/* Set default tuneable values. */
sc->bge_stat_ticks = BGE_TICKS_PER_SEC;
sc->bge_rx_coal_ticks = 150;
@@ -3201,8 +3381,8 @@ bge_attach(device_t dev)
* by its PCI subsystem ID, as we do below for the SysKonnect
* SK-9D41.
*/
if (bge_readmem_ind(sc, BGE_SOFTWARE_GENCOMM_SIG) == BGE_MAGIC_NUMBER)
hwcfg = bge_readmem_ind(sc, BGE_SOFTWARE_GENCOMM_NICCFG);
if (bge_readmem_ind(sc, BGE_SRAM_DATA_SIG) == BGE_SRAM_DATA_SIG_MAGIC)
hwcfg = bge_readmem_ind(sc, BGE_SRAM_DATA_CFG);
else if ((sc->bge_flags & BGE_FLAG_EADDR) &&
(sc->bge_asicrev != BGE_ASICREV_BCM5906)) {
if (bge_read_eeprom(sc, (caddr_t)&hwcfg, BGE_EE_HWCFG_OFFSET,
@@ -3437,9 +3617,9 @@ bge_reset(struct bge_softc *sc)
/*
* Write the magic number to SRAM at offset 0xB50.
* When firmware finishes its initialization it will
* write ~BGE_MAGIC_NUMBER to the same location.
* write ~BGE_SRAM_FW_MB_MAGIC to the same location.
*/
bge_writemem_ind(sc, BGE_SOFTWARE_GENCOMM, BGE_MAGIC_NUMBER);
bge_writemem_ind(sc, BGE_SRAM_FW_MB, BGE_SRAM_FW_MB_MAGIC);
reset = BGE_MISCCFG_RESET_CORE_CLOCKS | BGE_32BITTIME_66MHZ;
@@ -3458,7 +3638,8 @@ bge_reset(struct bge_softc *sc)
* Set GPHY Power Down Override to leave GPHY
* powered up in D0 uninitialized.
*/
if (BGE_IS_5705_PLUS(sc))
if (BGE_IS_5705_PLUS(sc) &&
(sc->bge_flags & BGE_FLAG_CPMU_PRESENT) == 0)
reset |= BGE_MISCCFG_GPHY_PD_OVERRIDE;
/* Issue global reset */
@@ -3487,8 +3668,6 @@ bge_reset(struct bge_softc *sc)
/* Clear enable no snoop and disable relaxed ordering. */
devctl &= ~(PCIM_EXP_CTL_RELAXED_ORD_ENABLE |
PCIM_EXP_CTL_NOSNOOP_ENABLE);
/* Set PCIE max payload size to 128. */
devctl &= ~PCIM_EXP_CTL_MAX_PAYLOAD;
pci_write_config(dev, sc->bge_expcap + PCIR_EXPRESS_DEVICE_CTL,
devctl, 2);
/* Clear error status. */
@@ -3563,8 +3742,8 @@ bge_reset(struct bge_softc *sc)
*/
for (i = 0; i < BGE_TIMEOUT; i++) {
DELAY(10);
val = bge_readmem_ind(sc, BGE_SOFTWARE_GENCOMM);
if (val == ~BGE_MAGIC_NUMBER)
val = bge_readmem_ind(sc, BGE_SRAM_FW_MB);
if (val == ~BGE_SRAM_FW_MB_MAGIC)
break;
}
@@ -3592,8 +3771,7 @@ bge_reset(struct bge_softc *sc)
}
/* Fix up byte swapping. */
CSR_WRITE_4(sc, BGE_MODE_CTL, BGE_DMA_SWAP_OPTIONS |
BGE_MODECTL_BYTESWAP_DATA);
CSR_WRITE_4(sc, BGE_MODE_CTL, bge_dma_swap_options(sc));
/* Tell the ASF firmware we are up */
if (sc->bge_asf_mode & ASF_STACKUP)
@@ -3624,6 +3802,10 @@ bge_reset(struct bge_softc *sc)
}
DELAY(10000);
if (sc->bge_asicrev == BGE_ASICREV_BCM5720)
BGE_CLRBIT(sc, BGE_CPMU_CLCK_ORIDE,
CPMU_CLCK_ORIDE_MAC_ORIDE_EN);
return (0);
}
@@ -4103,12 +4285,14 @@ bge_asf_driver_up(struct bge_softc *sc)
sc->bge_asf_count --;
else {
sc->bge_asf_count = 2;
bge_writemem_ind(sc, BGE_SOFTWARE_GENCOMM_FW,
BGE_FW_DRV_ALIVE);
bge_writemem_ind(sc, BGE_SOFTWARE_GENNCOMM_FW_LEN, 4);
bge_writemem_ind(sc, BGE_SOFTWARE_GENNCOMM_FW_DATA, 3);
CSR_WRITE_4(sc, BGE_CPU_EVENT,
CSR_READ_4(sc, BGE_CPU_EVENT) | (1 << 14));
bge_writemem_ind(sc, BGE_SRAM_FW_CMD_MB,
BGE_FW_CMD_DRV_ALIVE);
bge_writemem_ind(sc, BGE_SRAM_FW_CMD_LEN_MB, 4);
bge_writemem_ind(sc, BGE_SRAM_FW_CMD_DATA_MB,
BGE_FW_HB_TIMEOUT_SEC);
CSR_WRITE_4(sc, BGE_RX_CPU_EVENT,
CSR_READ_4(sc, BGE_RX_CPU_EVENT) |
BGE_RX_CPU_DRV_EVENT);
}
}
}
@@ -4239,6 +4423,28 @@ bge_stats_update_regs(struct bge_softc *sc)
CSR_READ_4(sc, BGE_RXLP_LOCSTAT_DMA_HPWRQ_FULL);
stats->NoMoreRxBDs +=
CSR_READ_4(sc, BGE_RXLP_LOCSTAT_OUT_OF_BDS);
/*
* XXX
* Unlike other controllers, BGE_RXLP_LOCSTAT_IFIN_DROPS
* counter of BCM5717, BCM5718, BCM5719 A0 and BCM5720 A0
* includes number of unwanted multicast frames. This comes
* from silicon bug and known workaround to get rough(not
* exact) counter is to enable interrupt on MBUF low water
* attention. This can be accomplished by setting
* BGE_HCCMODE_ATTN bit of BGE_HCC_MODE,
* BGE_BMANMODE_LOMBUF_ATTN bit of BGE_BMAN_MODE and
* BGE_MODECTL_FLOWCTL_ATTN_INTR bit of BGE_MODE_CTL.
* However that change would generate more interrupts and
* there are still possibilities of losing multiple frames
* during BGE_MODECTL_FLOWCTL_ATTN_INTR interrupt handling.
* Given that the workaround still would not get correct
* counter I don't think it's worth to implement it. So
* ignore reading the counter on controllers that have the
* silicon bug.
*/
if (sc->bge_asicrev != BGE_ASICREV_BCM5717 &&
sc->bge_chipid != BGE_CHIPID_BCM5719_A0 &&
sc->bge_chipid != BGE_CHIPID_BCM5720_A0)
stats->InputDiscards +=
CSR_READ_4(sc, BGE_RXLP_LOCSTAT_IFIN_DROPS);
stats->InputErrors +=
@@ -4311,6 +4517,12 @@ bge_stats_update(struct bge_softc *sc)
ifp->if_collisions += (uint32_t)(cnt - sc->bge_tx_collisions);
sc->bge_tx_collisions = cnt;
cnt = READ_STAT(sc, stats, nicNoMoreRxBDs.bge_addr_lo);
ifp->if_ierrors += (uint32_t)(cnt - sc->bge_rx_nobds);
sc->bge_rx_nobds = cnt;
cnt = READ_STAT(sc, stats, ifInErrors.bge_addr_lo);
ifp->if_ierrors += (uint32_t)(cnt - sc->bge_rx_inerrs);
sc->bge_rx_inerrs = cnt;
cnt = READ_STAT(sc, stats, ifInDiscards.bge_addr_lo);
ifp->if_ierrors += (uint32_t)(cnt - sc->bge_rx_discards);
sc->bge_rx_discards = cnt;
@@ -4836,6 +5048,11 @@ bge_init_locked(struct bge_softc *sc)
mode = CSR_READ_4(sc, BGE_TX_MODE);
if (BGE_IS_5755_PLUS(sc) || sc->bge_asicrev == BGE_ASICREV_BCM5906)
mode |= BGE_TXMODE_MBUF_LOCKUP_FIX;
if (sc->bge_asicrev == BGE_ASICREV_BCM5720) {
mode &= ~(BGE_TXMODE_JMB_FRM_LEN | BGE_TXMODE_CNT_DN_MODE);
mode |= CSR_READ_4(sc, BGE_TX_MODE) &
(BGE_TXMODE_JMB_FRM_LEN | BGE_TXMODE_CNT_DN_MODE);
}
/* Turn on transmitter. */
CSR_WRITE_4(sc, BGE_TX_MODE, mode | BGE_TXMODE_ENABLE);
@@ -5536,6 +5753,12 @@ bge_add_sysctls(struct bge_softc *sc)
"Number of fragmented TX buffers of a frame allowed before "
"forced collapsing");
sc->bge_msi = 1;
snprintf(tn, sizeof(tn), "dev.bge.%d.msi", unit);
TUNABLE_INT_FETCH(tn, &sc->bge_msi);
SYSCTL_ADD_INT(ctx, children, OID_AUTO, "msi",
CTLFLAG_RD, &sc->bge_msi, 0, "Enable MSI");
/*
* It seems all Broadcom controllers have a bug that can generate UDP
* datagrams with checksum value 0 when TX UDP checksum offloading is
@@ -5809,8 +6032,7 @@ bge_sysctl_debug_info(SYSCTL_HANDLER_ARGS)
{
struct bge_softc *sc;
uint16_t *sbdata;
int error;
int result;
int error, result, sbsz;
int i, j;
result = -1;
@@ -5821,14 +6043,21 @@ bge_sysctl_debug_info(SYSCTL_HANDLER_ARGS)
if (result == 1) {
sc = (struct bge_softc *)arg1;
if (sc->bge_asicrev == BGE_ASICREV_BCM5700 &&
sc->bge_chipid != BGE_CHIPID_BCM5700_C0)
sbsz = BGE_STATUS_BLK_SZ;
else
sbsz = 32;
sbdata = (uint16_t *)sc->bge_ldata.bge_status_block;
printf("Status Block:\n");
for (i = 0x0; i < (BGE_STATUS_BLK_SZ / 4); ) {
BGE_LOCK(sc);
bus_dmamap_sync(sc->bge_cdata.bge_status_tag,
sc->bge_cdata.bge_status_map,
BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
for (i = 0x0; i < sbsz / sizeof(uint16_t); ) {
printf("%06x:", i);
for (j = 0; j < 8; j++) {
printf(" %04x", sbdata[i]);
i += 4;
}
for (j = 0; j < 8; j++)
printf(" %04x", sbdata[i++]);
printf("\n");
}
@@ -5841,8 +6070,11 @@ bge_sysctl_debug_info(SYSCTL_HANDLER_ARGS)
}
printf("\n");
}
BGE_UNLOCK(sc);
printf("Hardware Flags:\n");
if (BGE_IS_5717_PLUS(sc))
printf(" - 5717 Plus\n");
if (BGE_IS_5755_PLUS(sc))
printf(" - 5755 Plus\n");
if (BGE_IS_575X_PLUS(sc))
@@ -5932,11 +6164,11 @@ bge_get_eaddr_mem(struct bge_softc *sc, uint8_t ether_addr[])
{
uint32_t mac_addr;
mac_addr = bge_readmem_ind(sc, 0x0c14);
mac_addr = bge_readmem_ind(sc, BGE_SRAM_MAC_ADDR_HIGH_MB);
if ((mac_addr >> 16) == 0x484b) {
ether_addr[0] = (uint8_t)(mac_addr >> 8);
ether_addr[1] = (uint8_t)mac_addr;
mac_addr = bge_readmem_ind(sc, 0x0c18);
mac_addr = bge_readmem_ind(sc, BGE_SRAM_MAC_ADDR_LOW_MB);
ether_addr[2] = (uint8_t)(mac_addr >> 24);
ether_addr[3] = (uint8_t)(mac_addr >> 16);
ether_addr[4] = (uint8_t)(mac_addr >> 8);
@@ -71,12 +71,15 @@
#define BGE_STATS_BLOCK_END 0x00000AFF
#define BGE_STATUS_BLOCK 0x00000B00
#define BGE_STATUS_BLOCK_END 0x00000B4F
#define BGE_SOFTWARE_GENCOMM 0x00000B50
#define BGE_SOFTWARE_GENCOMM_SIG 0x00000B54
#define BGE_SOFTWARE_GENCOMM_NICCFG 0x00000B58
#define BGE_SOFTWARE_GENCOMM_FW 0x00000B78
#define BGE_SOFTWARE_GENNCOMM_FW_LEN 0x00000B7C
#define BGE_SOFTWARE_GENNCOMM_FW_DATA 0x00000B80
#define BGE_SRAM_FW_MB 0x00000B50
#define BGE_SRAM_DATA_SIG 0x00000B54
#define BGE_SRAM_DATA_CFG 0x00000B58
#define BGE_SRAM_FW_CMD_MB 0x00000B78
#define BGE_SRAM_FW_CMD_LEN_MB 0x00000B7C
#define BGE_SRAM_FW_CMD_DATA_MB 0x00000B80
#define BGE_SRAM_FW_DRV_STATE_MB 0x00000C04
#define BGE_SRAM_MAC_ADDR_HIGH_MB 0x00000C14
#define BGE_SRAM_MAC_ADDR_LOW_MB 0x00000C18
#define BGE_SOFTWARE_GENCOMM_END 0x00000FFF
#define BGE_UNMAPPED 0x00001000
#define BGE_UNMAPPED_END 0x00001FFF
@@ -87,8 +90,24 @@
#define BGE_SEND_RING_1_TO_4_END 0x00005FFF
/* Firmware interface */
#define BGE_FW_DRV_ALIVE 0x00000001
#define BGE_FW_PAUSE 0x00000002
#define BGE_SRAM_DATA_SIG_MAGIC 0x4B657654 /* 'KevT' */
#define BGE_FW_CMD_DRV_ALIVE 0x00000001
#define BGE_FW_CMD_PAUSE 0x00000002
#define BGE_FW_CMD_IPV4_ADDR_CHANGE 0x00000003
#define BGE_FW_CMD_IPV6_ADDR_CHANGE 0x00000004
#define BGE_FW_CMD_LINK_UPDATE 0x0000000C
#define BGE_FW_CMD_DRV_ALIVE2 0x0000000D
#define BGE_FW_CMD_DRV_ALIVE3 0x0000000E
#define BGE_FW_HB_TIMEOUT_SEC 3
#define BGE_FW_DRV_STATE_START 0x00000001
#define BGE_FW_DRV_STATE_START_DONE 0x80000001
#define BGE_FW_DRV_STATE_UNLOAD 0x00000002
#define BGE_FW_DRV_STATE_UNLOAD_DONE 0x80000002
#define BGE_FW_DRV_STATE_WOL 0x00000003
#define BGE_FW_DRV_STATE_SUSPEND 0x00000004
/* Mappings for internal memory configuration */
#define BGE_STD_RX_RINGS 0x00006000
@@ -239,15 +258,6 @@
#define BGE_PCIMISCCTL_ASICREV_SHIFT 16
#define BGE_HIF_SWAP_OPTIONS (BGE_PCIMISCCTL_ENDIAN_WORDSWAP)
#if BYTE_ORDER == LITTLE_ENDIAN
#define BGE_DMA_SWAP_OPTIONS \
BGE_MODECTL_WORDSWAP_NONFRAME| \
BGE_MODECTL_BYTESWAP_DATA|BGE_MODECTL_WORDSWAP_DATA
#else
#define BGE_DMA_SWAP_OPTIONS \
BGE_MODECTL_WORDSWAP_NONFRAME|BGE_MODECTL_BYTESWAP_NONFRAME| \
BGE_MODECTL_BYTESWAP_DATA|BGE_MODECTL_WORDSWAP_DATA
#endif
#define BGE_INIT \
(BGE_HIF_SWAP_OPTIONS|BGE_PCIMISCCTL_CLEAR_INTA| \
@@ -320,6 +330,7 @@
#define BGE_CHIPID_BCM5717_A0 0x05717000
#define BGE_CHIPID_BCM5717_B0 0x05717100
#define BGE_CHIPID_BCM5719_A0 0x05719000
#define BGE_CHIPID_BCM5720_A0 0x05720000
#define BGE_CHIPID_BCM57765_A0 0x57785000
#define BGE_CHIPID_BCM57765_B0 0x57785100
@@ -344,6 +355,7 @@
/* BGE_PCI_PRODID_ASICREV ASIC rev. identifiers. */
#define BGE_ASICREV_BCM5717 0x5717
#define BGE_ASICREV_BCM5719 0x5719
#define BGE_ASICREV_BCM5720 0x5720
#define BGE_ASICREV_BCM5761 0x5761
#define BGE_ASICREV_BCM5784 0x5784
#define BGE_ASICREV_BCM5785 0x5785
@@ -788,6 +800,8 @@
#define BGE_TXMODE_BIGBACKOFF_ENABLE 0x00000020
#define BGE_TXMODE_LONGPAUSE_ENABLE 0x00000040
#define BGE_TXMODE_MBUF_LOCKUP_FIX 0x00000100
#define BGE_TXMODE_JMB_FRM_LEN 0x00400000
#define BGE_TXMODE_CNT_DN_MODE 0x00800000
/* Transmit MAC status register */
#define BGE_TXSTAT_RX_XOFFED 0x00000001
@@ -801,6 +815,8 @@
#define BGE_TXLEN_SLOTTIME 0x000000FF
#define BGE_TXLEN_IPG 0x00000F00
#define BGE_TXLEN_CRS 0x00003000
#define BGE_TXLEN_JMB_FRM_LEN_MSK 0x00FF0000
#define BGE_TXLEN_CNT_DN_VAL_MSK 0xFF000000
/* Receive MAC mode register */
#define BGE_RXMODE_RESET 0x00000001
@@ -1258,6 +1274,7 @@
#define BGE_CPMU_LSPD_1000MB_CLK 0x360C
#define BGE_CPMU_LNK_AWARE_PWRMD 0x3610
#define BGE_CPMU_HST_ACC 0x361C
#define BGE_CPMU_CLCK_ORIDE 0x3624
#define BGE_CPMU_CLCK_STAT 0x3630
#define BGE_CPMU_MUTEX_REQ 0x365C
#define BGE_CPMU_MUTEX_GNT 0x3660
@@ -1285,6 +1302,9 @@
#define BGE_CPMU_HST_ACC_MACCLK_MASK 0x001F0000
#define BGE_CPMU_HST_ACC_MACCLK_6_25 0x00130000
/* Clock Speed Override Policy register */
#define CPMU_CLCK_ORIDE_MAC_ORIDE_EN 0x80000000
/* CPMU Clock Status register */
#define BGE_CPMU_CLCK_STAT_MAC_CLCK_MASK 0x001F0000
#define BGE_CPMU_CLCK_STAT_MAC_CLCK_62_5 0x00000000
@@ -1532,6 +1552,7 @@
#define BGE_RDMAMODE_MULT_DMA_RD_DIS 0x01000000
#define BGE_RDMAMODE_TSO4_ENABLE 0x08000000
#define BGE_RDMAMODE_TSO6_ENABLE 0x10000000
#define BGE_RDMAMODE_H2BNC_VLAN_DET 0x20000000
/* Read DMA status register */
#define BGE_RDMASTAT_PCI_TGT_ABRT_ATTN 0x00000004
@@ -1552,6 +1573,7 @@
#define BGE_RDMA_RSRVCTRL_FIFO_HWM_MASK 0x000FF000
#define BGE_RDMA_RSRVCTRL_TXMRGN_MASK 0xFFE00000
#define BGE_RDMA_LSO_CRPTEN_CTRL_BLEN_BD_512 0x00020000
#define BGE_RDMA_LSO_CRPTEN_CTRL_BLEN_BD_4K 0x00030000
#define BGE_RDMA_LSO_CRPTEN_CTRL_BLEN_LSO_4K 0x000C0000
@@ -1875,7 +1897,8 @@
#define BGE_MODE_CTL 0x6800
#define BGE_MISC_CFG 0x6804
#define BGE_MISC_LOCAL_CTL 0x6808
#define BGE_CPU_EVENT 0x6810
#define BGE_RX_CPU_EVENT 0x6810
#define BGE_TX_CPU_EVENT 0x6820
#define BGE_EE_ADDR 0x6838
#define BGE_EE_DATA 0x683C
#define BGE_EE_CTL 0x6840
@@ -1883,6 +1906,8 @@
#define BGE_EE_DELAY 0x6848
#define BGE_FASTBOOT_PC 0x6894
#define BGE_RX_CPU_DRV_EVENT 0x00004000
/*
* NVRAM Control registers
*/
@@ -1939,14 +1964,18 @@
#define BGE_MODECTL_WORDSWAP_NONFRAME 0x00000004
#define BGE_MODECTL_BYTESWAP_DATA 0x00000010
#define BGE_MODECTL_WORDSWAP_DATA 0x00000020
#define BGE_MODECTL_BYTESWAP_B2HRX_DATA 0x00000040
#define BGE_MODECTL_WORDSWAP_B2HRX_DATA 0x00000080
#define BGE_MODECTL_NO_FRAME_CRACKING 0x00000200
#define BGE_MODECTL_NO_RX_CRC 0x00000400
#define BGE_MODECTL_RX_BADFRAMES 0x00000800
#define BGE_MODECTL_NO_TX_INTR 0x00002000
#define BGE_MODECTL_NO_RX_INTR 0x00004000
#define BGE_MODECTL_FORCE_PCI32 0x00008000
#define BGE_MODECTL_B2HRX_ENABLE 0x00008000
#define BGE_MODECTL_STACKUP 0x00010000
#define BGE_MODECTL_HOST_SEND_BDS 0x00020000
#define BGE_MODECTL_HTX2B_ENABLE 0x00040000
#define BGE_MODECTL_TX_NO_PHDR_CSUM 0x00100000
#define BGE_MODECTL_RX_NO_PHDR_CSUM 0x00800000
#define BGE_MODECTL_TX_ATTN_INTR 0x01000000
@@ -1960,7 +1989,9 @@
/* Misc. config register */
#define BGE_MISCCFG_RESET_CORE_CLOCKS 0x00000001
#define BGE_MISCCFG_TIMER_PRESCALER 0x000000FE
#define BGE_MISCCFG_BOARD_ID 0x0001E000
#define BGE_MISCCFG_BOARD_ID_MASK 0x0001E000
#define BGE_MISCCFG_BOARD_ID_5704 0x00000000
#define BGE_MISCCFG_BOARD_ID_5704CIOBE 0x00004000
#define BGE_MISCCFG_BOARD_ID_5788 0x00010000
#define BGE_MISCCFG_BOARD_ID_5788M 0x00018000
#define BGE_MISCCFG_EPHY_IDDQ 0x00200000
@@ -2052,10 +2083,10 @@
* This magic number is written to the firmware mailbox at 0xb50
* before a software reset is issued. After the internal firmware
* has completed its initialization it will write the opposite of
* this value, ~BGE_MAGIC_NUMBER, to the same location, allowing the
* driver to synchronize with the firmware.
* this value, ~BGE_SRAM_FW_MB_MAGIC, to the same location,
* allowing the driver to synchronize with the firmware.
*/
#define BGE_MAGIC_NUMBER 0x4B657654
#define BGE_SRAM_FW_MB_MAGIC 0x4B657654
typedef struct {
uint32_t bge_addr_hi;
@@ -2276,7 +2307,8 @@ struct bge_status_block {
#define BCOM_DEVICEID_BCM5717 0x1655
#define BCOM_DEVICEID_BCM5718 0x1656
#define BCOM_DEVICEID_BCM5719 0x1657
#define BCOM_DEVICEID_BCM5720 0x1658
#define BCOM_DEVICEID_BCM5720_PP 0x1658 /* Not released to public. */
#define BCOM_DEVICEID_BCM5720 0x165F
#define BCOM_DEVICEID_BCM5721 0x1659
#define BCOM_DEVICEID_BCM5722 0x165A
#define BCOM_DEVICEID_BCM5723 0x165B
@@ -2797,6 +2829,8 @@ struct bge_softc {
#define BGE_FLAG_4G_BNDRY_BUG 0x02000000
#define BGE_FLAG_RX_ALIGNBUG 0x04000000
#define BGE_FLAG_SHORT_DMA_BUG 0x08000000
#define BGE_FLAG_4K_RDMA_BUG 0x10000000
#define BGE_FLAG_MBOX_REORDER 0x20000000
uint32_t bge_phy_flags;
#define BGE_PHY_NO_WIRESPEED 0x00000001
#define BGE_PHY_ADC_BUG 0x00000002
@@ -2833,9 +2867,12 @@ struct bge_softc {
int bge_timer;
int bge_forced_collapse;
int bge_forced_udpcsum;
int bge_msi;
int bge_csum_features;
struct callout bge_stat_ch;
uint32_t bge_rx_discards;
uint32_t bge_rx_inerrs;
uint32_t bge_rx_nobds;
uint32_t bge_tx_discards;
uint32_t bge_tx_collisions;
#ifdef DEVICE_POLLING
@@ -82,7 +82,7 @@ static device_method_t brgphy_methods[] = {
DEVMETHOD(device_attach, brgphy_attach),
DEVMETHOD(device_detach, mii_phy_detach),
DEVMETHOD(device_shutdown, bus_generic_shutdown),
{ 0, 0 }
DEVMETHOD_END
};
static devclass_t brgphy_devclass;
@@ -139,9 +139,14 @@ static const struct mii_phydesc brgphys[] = {
MII_PHY_DESC(BROADCOM2, BCM5754),
MII_PHY_DESC(BROADCOM2, BCM5761),
MII_PHY_DESC(BROADCOM2, BCM5784),
#ifdef notyet /* better handled by ukphy(4) until WARs are implemented */
MII_PHY_DESC(BROADCOM2, BCM5785),
#endif
MII_PHY_DESC(BROADCOM3, BCM5717C),
MII_PHY_DESC(BROADCOM3, BCM5719C),
MII_PHY_DESC(BROADCOM3, BCM5720C),
MII_PHY_DESC(BROADCOM3, BCM57765),
MII_PHY_DESC(BROADCOM3, BCM57780),
MII_PHY_DESC(xxBROADCOM_ALT1, BCM5906),
MII_PHY_END
};
@@ -221,7 +226,8 @@ brgphy_attach(device_t dev)
sc->mii_flags |= MIIF_HAVEFIBER;
}
break;
} break;
}
break;
case MII_OUI_BROADCOM2:
switch (sc->mii_mpd_model) {
case MII_MODEL_BROADCOM2_BCM5708S:
@@ -938,6 +944,7 @@ brgphy_reset(struct mii_softc *sc)
if (bge_sc->bge_phy_flags & BGE_PHY_JITTER_BUG)
brgphy_fixup_jitter_bug(sc);
if (bge_sc->bge_flags & BGE_FLAG_JUMBO)
brgphy_jumbo_settings(sc, ifp->if_mtu);
if ((bge_sc->bge_phy_flags & BGE_PHY_NO_WIRESPEED) == 0)
@@ -55,7 +55,7 @@
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: src/sys/dev/mii/ukphy.c,v 1.20.10.6.2.1 2010/12/21 17:09:25 kensmith Exp $");
__FBSDID("$FreeBSD$");
/*
* driver for generic unknown PHYs
@@ -86,7 +86,7 @@ static device_method_t ukphy_methods[] = {
DEVMETHOD(device_attach, ukphy_attach),
DEVMETHOD(device_detach, mii_phy_detach),
DEVMETHOD(device_shutdown, bus_generic_shutdown),
{ 0, 0 }
DEVMETHOD_END
};
static devclass_t ukphy_devclass;
@@ -31,7 +31,7 @@
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: src/sys/dev/mii/ukphy_subr.c,v 1.10.2.4.2.1 2010/12/21 17:09:25 kensmith Exp $");
__FBSDID("$FreeBSD$");
/*
* Subroutines shared by the ukphy driver and other PHY drivers.
@@ -95,7 +95,7 @@ static device_method_t dcphy_methods[] = {
DEVMETHOD(device_attach, dcphy_attach),
DEVMETHOD(device_detach, mii_phy_detach),
DEVMETHOD(device_shutdown, bus_generic_shutdown),
{ 0, 0 }
DEVMETHOD_END
};
static devclass_t dcphy_devclass;
@@ -294,7 +294,7 @@ static void
dcphy_status(struct mii_softc *sc)
{
struct mii_data *mii = sc->mii_pdata;
int reg, anlpar, tstat = 0;
int anlpar, tstat;
struct dc_softc *dc_sc;
dc_sc = mii->mii_ifp->if_softc;
@@ -305,13 +305,12 @@ dcphy_status(struct mii_softc *sc)
if ((mii->mii_ifp->if_flags & IFF_UP) == 0)
return;
reg = CSR_READ_4(dc_sc, DC_10BTSTAT);
if (!(reg & DC_TSTAT_LS10) || !(reg & DC_TSTAT_LS100))
tstat = CSR_READ_4(dc_sc, DC_10BTSTAT);
if (!(tstat & DC_TSTAT_LS10) || !(tstat & DC_TSTAT_LS100))
mii->mii_media_status |= IFM_ACTIVE;
if (CSR_READ_4(dc_sc, DC_10BTCTRL) & DC_TCTL_AUTONEGENBL) {
/* Erg, still trying, I guess... */
tstat = CSR_READ_4(dc_sc, DC_10BTSTAT);
if ((tstat & DC_TSTAT_ANEGSTAT) != DC_ASTAT_AUTONEGCMP) {
if ((DC_IS_MACRONIX(dc_sc) || DC_IS_PNICII(dc_sc)) &&
(tstat & DC_TSTAT_ANEGSTAT) == DC_ASTAT_DISABLE)
@@ -351,9 +350,9 @@ dcphy_status(struct mii_softc *sc)
* and hope that the user is clever enough to manually
* change the media settings if we're wrong.
*/
if (!(reg & DC_TSTAT_LS100))
if (!(tstat & DC_TSTAT_LS100))
mii->mii_media_active |= IFM_100_TX | IFM_HDX;
else if (!(reg & DC_TSTAT_LS10))
else if (!(tstat & DC_TSTAT_LS10))
mii->mii_media_active |= IFM_10_T | IFM_HDX;
else
mii->mii_media_active |= IFM_NONE;
@@ -31,7 +31,7 @@
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: src/sys/dev/dc/if_dc.c,v 1.201.2.3.2.1 2010/12/21 17:09:25 kensmith Exp $");
__FBSDID("$FreeBSD$");
/*
* DEC "tulip" clone ethernet driver. Supports the DEC/Intel 21143
@@ -225,6 +225,10 @@ static const struct dc_type const dc_devs[] = {
"Linksys PCMPC200 CardBus 10/100" },
{ DC_DEVID(DC_VENDORID_LINKSYS, DC_DEVICEID_PCMPC200_AB09), 0,
"Linksys PCMPC200 CardBus 10/100" },
{ DC_DEVID(DC_VENDORID_ULI, DC_DEVICEID_M5261), 0,
"ULi M5261 FastEthernet" },
{ DC_DEVID(DC_VENDORID_ULI, DC_DEVICEID_M5263), 0,
"ULi M5263 FastEthernet" },
{ 0, 0, NULL }
};
@@ -253,6 +257,7 @@ static void dc_stop(struct dc_softc *);
static void dc_watchdog(void *);
static int dc_shutdown(device_t);
static int dc_ifmedia_upd(struct ifnet *);
static int dc_ifmedia_upd_locked(struct dc_softc *);
static void dc_ifmedia_sts(struct ifnet *, struct ifmediareq *);
static int dc_dma_alloc(struct dc_softc *);
@@ -280,6 +285,7 @@ static uint32_t dc_mchash_be(const uint8_t *);
static void dc_setfilt_21143(struct dc_softc *);
static void dc_setfilt_asix(struct dc_softc *);
static void dc_setfilt_admtek(struct dc_softc *);
static void dc_setfilt_uli(struct dc_softc *);
static void dc_setfilt_xircom(struct dc_softc *);
static void dc_setfilt(struct dc_softc *);
@@ -331,17 +337,13 @@ static device_method_t dc_methods[] = {
DEVMETHOD(device_resume, dc_resume),
DEVMETHOD(device_shutdown, dc_shutdown),
/* bus interface */
DEVMETHOD(bus_print_child, bus_generic_print_child),
DEVMETHOD(bus_driver_added, bus_generic_driver_added),
/* MII interface */
DEVMETHOD(miibus_readreg, dc_miibus_readreg),
DEVMETHOD(miibus_writereg, dc_miibus_writereg),
DEVMETHOD(miibus_statchg, dc_miibus_statchg),
DEVMETHOD(miibus_mediainit, dc_miibus_mediainit),
{ 0, 0 }
DEVMETHOD_END
};
static driver_t dc_driver = {
@@ -352,8 +354,9 @@ static driver_t dc_driver = {
static devclass_t dc_devclass;
DRIVER_MODULE(dc, pci, dc_driver, dc_devclass, 0, 0);
DRIVER_MODULE(miibus, dc, miibus_driver, miibus_devclass, 0, 0);
DRIVER_MODULE_ORDERED(dc, pci, dc_driver, dc_devclass, NULL, NULL,
SI_ORDER_ANY);
DRIVER_MODULE(miibus, dc, miibus_driver, miibus_devclass, NULL, NULL);
#define DC_SETBIT(sc, reg, x) \
CSR_WRITE_4(sc, reg, CSR_READ_4(sc, reg) | (x))
@@ -700,6 +703,23 @@ dc_miibus_readreg(device_t dev, int phy, int reg)
return (0);
}
if (sc->dc_type == DC_TYPE_ULI_M5263) {
CSR_WRITE_4(sc, DC_ROM,
((phy << DC_ULI_PHY_ADDR_SHIFT) & DC_ULI_PHY_ADDR_MASK) |
((reg << DC_ULI_PHY_REG_SHIFT) & DC_ULI_PHY_REG_MASK) |
DC_ULI_PHY_OP_READ);
for (i = 0; i < DC_TIMEOUT; i++) {
DELAY(1);
rval = CSR_READ_4(sc, DC_ROM);
if ((rval & DC_ULI_PHY_OP_DONE) != 0) {
return (rval & DC_ULI_PHY_DATA_MASK);
}
}
if (i == DC_TIMEOUT)
device_printf(dev, "phy read timed out\n");
return (0);
}
if (DC_IS_COMET(sc)) {
switch (reg) {
case MII_BMCR:
@@ -765,6 +785,16 @@ dc_miibus_writereg(device_t dev, int phy, int reg, int data)
return (0);
}
if (sc->dc_type == DC_TYPE_ULI_M5263) {
CSR_WRITE_4(sc, DC_ROM,
((phy << DC_ULI_PHY_ADDR_SHIFT) & DC_ULI_PHY_ADDR_MASK) |
((reg << DC_ULI_PHY_REG_SHIFT) & DC_ULI_PHY_REG_MASK) |
((data << DC_ULI_PHY_DATA_SHIFT) & DC_ULI_PHY_DATA_MASK) |
DC_ULI_PHY_OP_WRITE);
DELAY(1);
return (0);
}
if (DC_IS_COMET(sc)) {
switch (reg) {
case MII_BMCR:
@@ -827,12 +857,11 @@ dc_miibus_statchg(device_t dev)
return;
ifm = &mii->mii_media;
if (DC_IS_DAVICOM(sc) &&
IFM_SUBTYPE(ifm->ifm_media) == IFM_HPNA_1) {
if (DC_IS_DAVICOM(sc) && IFM_SUBTYPE(ifm->ifm_media) == IFM_HPNA_1) {
dc_setcfg(sc, ifm->ifm_media);
sc->dc_if_media = ifm->ifm_media;
return;
}
} else if (!DC_IS_ADMTEK(sc))
dc_setcfg(sc, mii->mii_media_active);
sc->dc_link = 0;
if ((mii->mii_media_status & (IFM_ACTIVE | IFM_AVALID)) ==
@@ -842,17 +871,8 @@ dc_miibus_statchg(device_t dev)
case IFM_100_TX:
sc->dc_link = 1;
break;
default:
break;
}
}
if (sc->dc_link == 0)
return;
sc->dc_if_media = mii->mii_media_active;
if (DC_IS_ADMTEK(sc))
return;
dc_setcfg(sc, mii->mii_media_active);
}
/*
@@ -1147,6 +1167,97 @@ dc_setfilt_asix(struct dc_softc *sc)
CSR_WRITE_4(sc, DC_AX_FILTDATA, hashes[1]);
}
static void
dc_setfilt_uli(struct dc_softc *sc)
{
uint8_t eaddr[ETHER_ADDR_LEN];
struct ifnet *ifp;
struct ifmultiaddr *ifma;
struct dc_desc *sframe;
uint32_t filter, *sp;
uint8_t *ma;
int i, mcnt;
ifp = sc->dc_ifp;
i = sc->dc_cdata.dc_tx_prod;
DC_INC(sc->dc_cdata.dc_tx_prod, DC_TX_LIST_CNT);
sc->dc_cdata.dc_tx_cnt++;
sframe = &sc->dc_ldata.dc_tx_list[i];
sp = sc->dc_cdata.dc_sbuf;
bzero(sp, DC_SFRAME_LEN);
sframe->dc_data = htole32(DC_ADDR_LO(sc->dc_saddr));
sframe->dc_ctl = htole32(DC_SFRAME_LEN | DC_TXCTL_SETUP |
DC_TXCTL_TLINK | DC_FILTER_PERFECT | DC_TXCTL_FINT);
sc->dc_cdata.dc_tx_chain[i] = (struct mbuf *)sc->dc_cdata.dc_sbuf;
/* Set station address. */
bcopy(IF_LLADDR(sc->dc_ifp), eaddr, ETHER_ADDR_LEN);
*sp++ = DC_SP_MAC(eaddr[1] << 8 | eaddr[0]);
*sp++ = DC_SP_MAC(eaddr[3] << 8 | eaddr[2]);
*sp++ = DC_SP_MAC(eaddr[5] << 8 | eaddr[4]);
/* Set broadcast address. */
*sp++ = DC_SP_MAC(0xFFFF);
*sp++ = DC_SP_MAC(0xFFFF);
*sp++ = DC_SP_MAC(0xFFFF);
/* Extract current filter configuration. */
filter = CSR_READ_4(sc, DC_NETCFG);
filter &= ~(DC_NETCFG_RX_PROMISC | DC_NETCFG_RX_ALLMULTI);
/* Now build perfect filters. */
mcnt = 0;
if_maddr_rlock(ifp);
TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
if (ifma->ifma_addr->sa_family != AF_LINK)
continue;
if (mcnt >= DC_ULI_FILTER_NPERF) {
filter |= DC_NETCFG_RX_ALLMULTI;
break;
}
ma = LLADDR((struct sockaddr_dl *)ifma->ifma_addr);
*sp++ = DC_SP_MAC(ma[1] << 8 | ma[0]);
*sp++ = DC_SP_MAC(ma[3] << 8 | ma[2]);
*sp++ = DC_SP_MAC(ma[5] << 8 | ma[4]);
mcnt++;
}
if_maddr_runlock(ifp);
for (; mcnt < DC_ULI_FILTER_NPERF; mcnt++) {
*sp++ = DC_SP_MAC(0xFFFF);
*sp++ = DC_SP_MAC(0xFFFF);
*sp++ = DC_SP_MAC(0xFFFF);
}
if (filter & (DC_NETCFG_TX_ON | DC_NETCFG_RX_ON))
CSR_WRITE_4(sc, DC_NETCFG,
filter & ~(DC_NETCFG_TX_ON | DC_NETCFG_RX_ON));
if (ifp->if_flags & IFF_PROMISC)
filter |= DC_NETCFG_RX_PROMISC | DC_NETCFG_RX_ALLMULTI;
if (ifp->if_flags & IFF_ALLMULTI)
filter |= DC_NETCFG_RX_ALLMULTI;
CSR_WRITE_4(sc, DC_NETCFG,
filter & ~(DC_NETCFG_TX_ON | DC_NETCFG_RX_ON));
if (filter & (DC_NETCFG_TX_ON | DC_NETCFG_RX_ON))
CSR_WRITE_4(sc, DC_NETCFG, filter);
sframe->dc_status = htole32(DC_TXSTAT_OWN);
bus_dmamap_sync(sc->dc_tx_ltag, sc->dc_tx_lmap, BUS_DMASYNC_PREREAD |
BUS_DMASYNC_PREWRITE);
bus_dmamap_sync(sc->dc_stag, sc->dc_smap, BUS_DMASYNC_PREWRITE);
CSR_WRITE_4(sc, DC_TXSTART, 0xFFFFFFFF);
/*
* Wait some time...
*/
DELAY(1000);
sc->dc_wdog_timer = 5;
}
static void
dc_setfilt_xircom(struct dc_softc *sc)
{
@@ -1235,6 +1346,9 @@ dc_setfilt(struct dc_softc *sc)
if (DC_IS_ADMTEK(sc))
dc_setfilt_admtek(sc);
if (DC_IS_ULI(sc))
dc_setfilt_uli(sc);
if (DC_IS_XIRCOM(sc))
dc_setfilt_xircom(sc);
}
@@ -1403,7 +1517,7 @@ dc_reset(struct dc_softc *sc)
}
if (DC_IS_ASIX(sc) || DC_IS_ADMTEK(sc) || DC_IS_CONEXANT(sc) ||
DC_IS_XIRCOM(sc) || DC_IS_INTEL(sc)) {
DC_IS_XIRCOM(sc) || DC_IS_INTEL(sc) || DC_IS_ULI(sc)) {
DELAY(10000);
DC_CLRBIT(sc, DC_BUSCTL, DC_BUSCTL_RESET);
i = 0;
@@ -1615,7 +1729,7 @@ dc_read_srom(struct dc_softc *sc, int bits)
int size;
size = DC_ROM_SIZE(bits);
sc->dc_srom = malloc(size, M_DEVBUF, M_NOWAIT);
sc->dc_srom = malloc(size, M_DEVBUF, M_NOWAIT | M_ZERO);
if (sc->dc_srom == NULL) {
device_printf(sc->dc_dev, "Could not allocate SROM buffer\n");
return (ENOMEM);
@@ -1909,7 +2023,8 @@ dc_attach(device_t dev)
struct ifnet *ifp;
struct dc_mediainfo *m;
uint32_t reg, revision;
int error, mac_offset, phy, rid, tmp;
uint16_t *srom;
int error, mac_offset, n, phy, rid, tmp;
uint8_t *mac;
sc = device_get_softc(dev);
@@ -2089,6 +2204,21 @@ dc_attach(device_t dev)
if (error != 0)
goto fail;
break;
case DC_DEVID(DC_VENDORID_ULI, DC_DEVICEID_M5261):
case DC_DEVID(DC_VENDORID_ULI, DC_DEVICEID_M5263):
if (sc->dc_info->dc_devid ==
DC_DEVID(DC_VENDORID_ULI, DC_DEVICEID_M5261))
sc->dc_type = DC_TYPE_ULI_M5261;
else
sc->dc_type = DC_TYPE_ULI_M5263;
/* TX buffers should be aligned on 4 byte boundary. */
sc->dc_flags |= DC_TX_INTR_ALWAYS | DC_TX_COALESCE |
DC_TX_ALIGN;
sc->dc_pmode = DC_PMODE_MII;
error = dc_read_srom(sc, sc->dc_romwidth);
if (error != 0)
goto fail;
break;
default:
device_printf(dev, "unknown device: %x\n",
sc->dc_info->dc_devid);
@@ -2186,6 +2316,33 @@ dc_attach(device_t dev)
}
bcopy(mac, eaddr, ETHER_ADDR_LEN);
break;
case DC_TYPE_ULI_M5261:
case DC_TYPE_ULI_M5263:
srom = (uint16_t *)sc->dc_srom;
if (srom == NULL || *srom == 0xFFFF || *srom == 0) {
/*
* No valid SROM present, read station address
* from ID Table.
*/
device_printf(dev,
"Reading station address from ID Table.\n");
CSR_WRITE_4(sc, DC_BUSCTL, 0x10000);
CSR_WRITE_4(sc, DC_SIARESET, 0x01C0);
CSR_WRITE_4(sc, DC_10BTCTRL, 0x0000);
CSR_WRITE_4(sc, DC_10BTCTRL, 0x0010);
CSR_WRITE_4(sc, DC_10BTCTRL, 0x0000);
CSR_WRITE_4(sc, DC_SIARESET, 0x0000);
CSR_WRITE_4(sc, DC_SIARESET, 0x01B0);
mac = (uint8_t *)eaddr;
for (n = 0; n < ETHER_ADDR_LEN; n++)
mac[n] = (uint8_t)CSR_READ_4(sc, DC_10BTCTRL);
CSR_WRITE_4(sc, DC_SIARESET, 0x0000);
CSR_WRITE_4(sc, DC_BUSCTL, 0x0000);
DELAY(10);
} else
dc_read_eeprom(sc, (caddr_t)&eaddr, DC_EE_NODEADDR, 3,
0);
break;
default:
dc_read_eeprom(sc, (caddr_t)&eaddr, DC_EE_NODEADDR, 3, 0);
break;
@@ -2296,9 +2453,6 @@ dc_attach(device_t dev)
if (sc->dc_pmode != DC_PMODE_SIA)
sc->dc_pmode = DC_PMODE_SYM;
sc->dc_flags |= DC_21143_NWAY;
mii_attach(dev, &sc->dc_miibus, ifp, dc_ifmedia_upd,
dc_ifmedia_sts, BMSR_DEFCAPMASK, MII_PHY_ANY,
MII_OFFSET_ANY, 0);
/*
* For non-MII cards, we need to have the 21143
* drive the LEDs. Except there are some systems
@@ -2309,7 +2463,9 @@ dc_attach(device_t dev)
if (!(pci_get_subvendor(dev) == 0x1033 &&
pci_get_subdevice(dev) == 0x8028))
sc->dc_flags |= DC_TULIP_LEDS;
error = 0;
error = mii_attach(dev, &sc->dc_miibus, ifp, dc_ifmedia_upd,
dc_ifmedia_sts, BMSR_DEFCAPMASK, MII_PHY_ANY,
MII_OFFSET_ANY, 0);
}
if (error) {
@@ -2378,7 +2534,7 @@ dc_detach(device_t dev)
ifp = sc->dc_ifp;
#ifdef DEVICE_POLLING
if (ifp->if_capenable & IFCAP_POLLING)
if (ifp != NULL && ifp->if_capenable & IFCAP_POLLING)
ether_poll_deregister(ifp);
#endif
@@ -2402,7 +2558,7 @@ dc_detach(device_t dev)
if (sc->dc_res)
bus_release_resource(dev, DC_RES, DC_RID, sc->dc_res);
if (ifp)
if (ifp != NULL)
if_free(ifp);
dc_dma_free(sc);
@@ -2452,7 +2608,6 @@ dc_list_tx_init(struct dc_softc *sc)
return (0);
}
/*
* Initialize the RX descriptors and allocate mbufs for them. Note that
* we arrange the descriptors in a closed ring, so that the last descriptor
@@ -3462,7 +3617,7 @@ dc_init_locked(struct dc_softc *sc)
/*
* Set cache alignment and burst length.
*/
if (DC_IS_ASIX(sc) || DC_IS_DAVICOM(sc))
if (DC_IS_ASIX(sc) || DC_IS_DAVICOM(sc) || DC_IS_ULI(sc))
CSR_WRITE_4(sc, DC_BUSCTL, 0);
else
CSR_WRITE_4(sc, DC_BUSCTL, DC_BUSCTL_MRME | DC_BUSCTL_MRLE);
@@ -3575,6 +3730,11 @@ dc_init_locked(struct dc_softc *sc)
CSR_WRITE_4(sc, DC_IMR, DC_INTRS);
CSR_WRITE_4(sc, DC_ISR, 0xFFFFFFFF);
/* Initialize TX jabber and RX watchdog timer. */
if (DC_IS_ULI(sc))
CSR_WRITE_4(sc, DC_WATCHDOG, DC_WDOG_JABBERCLK |
DC_WDOG_HOSTUNJAB);
/* Enable transmitter. */
DC_SETBIT(sc, DC_NETCFG, DC_NETCFG_TX_ON);
@@ -3604,8 +3764,7 @@ dc_init_locked(struct dc_softc *sc)
ifp->if_drv_flags |= IFF_DRV_RUNNING;
ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
mii_mediachg(mii);
dc_setcfg(sc, sc->dc_if_media);
dc_ifmedia_upd_locked(sc);
/* Clear missed frames and overflow counter. */
CSR_READ_4(sc, DC_FRAMESDISCARDED);
@@ -3631,25 +3790,37 @@ static int
dc_ifmedia_upd(struct ifnet *ifp)
{
struct dc_softc *sc;
struct mii_data *mii;
struct ifmedia *ifm;
int error;
sc = ifp->if_softc;
mii = device_get_softc(sc->dc_miibus);
DC_LOCK(sc);
mii_mediachg(mii);
ifm = &mii->mii_media;
error = dc_ifmedia_upd_locked(sc);
DC_UNLOCK(sc);
return (error);
}
static int
dc_ifmedia_upd_locked(struct dc_softc *sc)
{
struct mii_data *mii;
struct ifmedia *ifm;
int error;
DC_LOCK_ASSERT(sc);
sc->dc_link = 0;
mii = device_get_softc(sc->dc_miibus);
error = mii_mediachg(mii);
if (error == 0) {
ifm = &mii->mii_media;
if (DC_IS_INTEL(sc))
dc_setcfg(sc, ifm->ifm_media);
else if (DC_IS_DAVICOM(sc) &&
IFM_SUBTYPE(ifm->ifm_media) == IFM_HPNA_1)
dc_setcfg(sc, ifm->ifm_media);
else
sc->dc_link = 0;
DC_UNLOCK(sc);
}
return (0);
return (error);
}
/*
@@ -29,7 +29,7 @@
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
* $FreeBSD: src/sys/dev/dc/if_dcreg.h,v 1.57.2.2.2.1 2010/12/21 17:09:25 kensmith Exp $
* $FreeBSD$
*/
/*
@@ -78,6 +78,8 @@
#define DC_TYPE_PNIC 0xA /* 82c168/82c169 PNIC I */
#define DC_TYPE_XIRCOM 0xB /* Xircom X3201 */
#define DC_TYPE_CONEXANT 0xC /* Conexant LANfinity RS7112 */
#define DC_TYPE_ULI_M5261 0xD /* ALi/ULi M5261 */
#define DC_TYPE_ULI_M5263 0xE /* ALi/ULi M5263 */
#define DC_IS_MACRONIX(x) \
(x->dc_type == DC_TYPE_98713 || \
@@ -88,6 +90,10 @@
(x->dc_type == DC_TYPE_AL981 || \
x->dc_type == DC_TYPE_AN983)
#define DC_IS_ULI(x) \
(x->dc_type == DC_TYPE_ULI_M5261 || \
x->dc_type == DC_TYPE_ULI_M5263)
#define DC_IS_INTEL(x) (x->dc_type == DC_TYPE_21143)
#define DC_IS_ASIX(x) (x->dc_type == DC_TYPE_ASIX)
#define DC_IS_COMET(x) (x->dc_type == DC_TYPE_AL981)
@@ -707,6 +713,23 @@ struct dc_type {
/* End of CONEXANT specific registers */
/*
* ULi M5263 specific registers.
*/
#define DC_ULI_FILTER_NPERF 14
#define DC_ULI_PHY_DATA_MASK 0x0000FFFF
#define DC_ULI_PHY_REG_MASK 0x001F0000
#define DC_ULI_PHY_ADDR_MASK 0x03E00000
#define DC_ULI_PHY_OP_WRITE 0x04000000
#define DC_ULI_PHY_OP_READ 0x08000000
#define DC_ULI_PHY_OP_DONE 0x10000000
#define DC_ULI_PHY_DATA_SHIFT 0
#define DC_ULI_PHY_REG_SHIFT 16
#define DC_ULI_PHY_ADDR_SHIFT 21
/* End of ULi M5263 specific registers */
struct dc_softc {
struct ifnet *dc_ifp; /* interface info */
@@ -737,7 +760,6 @@ struct dc_softc {
int dc_pnic_rx_bug_save;
unsigned char *dc_pnic_rx_buf;
int dc_if_flags;
int dc_if_media;
uint32_t dc_flags;
uint32_t dc_txthresh;
uint32_t dc_eaddr[2];
@@ -1014,6 +1036,17 @@ struct dc_softc {
#define DC_DEVICEID_PCMPC200_AB08 0xab08
#define DC_DEVICEID_PCMPC200_AB09 0xab09
/*
* ULi vendor ID.
*/
#define DC_VENDORID_ULI 0x10b9
/*
* ULi device IDs.
*/
#define DC_DEVICEID_M5261 0x5261
#define DC_DEVICEID_M5263 0x5263
#define DC_DEVID(vendor, device) ((device) << 16 | (vendor))
/*
@@ -74,7 +74,7 @@ static device_method_t pnphy_methods[] = {
DEVMETHOD(device_attach, pnphy_attach),
DEVMETHOD(device_detach, mii_phy_detach),
DEVMETHOD(device_shutdown, bus_generic_shutdown),
{ 0, 0 }
DEVMETHOD_END
};
static devclass_t pnphy_devclass;
@@ -1,6 +1,6 @@
/* $NetBSD: dc21040reg.h,v 1.15 1998/05/22 18:50:59 matt Exp $ */
/* $FreeBSD: src/sys/dev/de/dc21040reg.h,v 1.7.26.1.6.1 2010/12/21 17:09:25 kensmith Exp $ */
/* $FreeBSD$ */
/*-
* Copyright (c) 1994, 1995, 1996 Matt Thomas <matt@3am-software.com>
@@ -36,7 +36,7 @@
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: src/sys/dev/de/if_de.c,v 1.186.2.3.4.1 2010/12/21 17:09:25 kensmith Exp $");
__FBSDID("$FreeBSD$");
#define TULIP_HDR_DATA
@@ -4496,7 +4496,8 @@ tulip_busdma_allocring(device_t dev, tulip_softc_t * const sc, size_t count,
/* First, setup a tag. */
ri->ri_max = count;
size = count * sizeof(tulip_desc_t);
error = bus_dma_tag_create(NULL, 32, 0, BUS_SPACE_MAXADDR_32BIT,
error = bus_dma_tag_create(bus_get_dma_tag(dev),
32, 0, BUS_SPACE_MAXADDR_32BIT,
BUS_SPACE_MAXADDR, NULL, NULL, size, 1, size, 0, NULL, NULL,
&ri->ri_ring_tag);
if (error) {
@@ -4524,7 +4525,7 @@ tulip_busdma_allocring(device_t dev, tulip_softc_t * const sc, size_t count,
}
/* Allocate a tag for the data buffers. */
error = bus_dma_tag_create(NULL, align, 0,
error = bus_dma_tag_create(bus_get_dma_tag(dev), align, 0,
BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL,
MCLBYTES * nsegs, nsegs, MCLBYTES, 0, NULL, NULL, &ri->ri_data_tag);
if (error) {
@@ -4604,7 +4605,7 @@ tulip_busdma_init(device_t dev, tulip_softc_t * const sc)
/*
* Allocate a DMA tag, memory, and map for setup descriptor
*/
error = bus_dma_tag_create(NULL, 32, 0,
error = bus_dma_tag_create(bus_get_dma_tag(dev), 32, 0,
BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL,
sizeof(sc->tulip_setupdata), 1, sizeof(sc->tulip_setupdata), 0,
NULL, NULL, &sc->tulip_setup_tag);
@@ -1,6 +1,6 @@
/* $NetBSD: if_devar.h,v 1.32 1999/04/01 14:55:25 tsubai Exp $ */
/* $FreeBSD: src/sys/dev/de/if_devar.h,v 1.45.10.2.6.1 2010/12/21 17:09:25 kensmith Exp $ */
/* $FreeBSD$ */
/*-
* Copyright (c) 1994-1997 Matt Thomas (matt@3am-software.com)
@@ -53,7 +53,7 @@
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: src/sys/dev/mii/acphy.c,v 1.21.10.6.2.1 2010/12/21 17:09:25 kensmith Exp $");
__FBSDID("$FreeBSD$");
/*
* Driver for Altima AC101 10/100 PHY
@@ -87,7 +87,7 @@ static device_method_t acphy_methods[] = {
DEVMETHOD(device_attach, acphy_attach),
DEVMETHOD(device_detach, mii_phy_detach),
DEVMETHOD(device_shutdown, bus_generic_shutdown),
{ 0, 0 }
DEVMETHOD_END
};
static devclass_t acphy_devclass;
@@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD: src/sys/dev/mii/acphyreg.h,v 1.2.10.1.6.1 2010/12/21 17:09:25 kensmith Exp $
* $FreeBSD$
*/
#ifndef _DEV_MII_ACPHYREG_H_
@@ -31,7 +31,7 @@
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: src/sys/dev/mii/amphy.c,v 1.24.2.5.2.1 2010/12/21 17:09:25 kensmith Exp $");
__FBSDID("$FreeBSD$");
/*
* driver for AMD AM79c873 PHYs
@@ -66,7 +66,7 @@ static device_method_t amphy_methods[] = {
DEVMETHOD(device_attach, amphy_attach),
DEVMETHOD(device_detach, mii_phy_detach),
DEVMETHOD(device_shutdown, bus_generic_shutdown),
{ 0, 0 }
DEVMETHOD_END
};
static devclass_t amphy_devclass;
@@ -29,7 +29,7 @@
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
* $FreeBSD: src/sys/dev/mii/amphyreg.h,v 1.2.22.1.6.1 2010/12/21 17:09:25 kensmith Exp $
* $FreeBSD$
*/
#ifndef _DEV_MII_AMTPHYREG_H_
@@ -55,7 +55,7 @@
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: src/sys/dev/mii/ukphy.c,v 1.20.10.6.2.1 2010/12/21 17:09:25 kensmith Exp $");
__FBSDID("$FreeBSD$");
/*
* driver for generic unknown PHYs
@@ -86,7 +86,7 @@ static device_method_t ukphy_methods[] = {
DEVMETHOD(device_attach, ukphy_attach),
DEVMETHOD(device_detach, mii_phy_detach),
DEVMETHOD(device_shutdown, bus_generic_shutdown),
{ 0, 0 }
DEVMETHOD_END
};
static devclass_t ukphy_devclass;
@@ -31,7 +31,7 @@
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: src/sys/dev/mii/ukphy_subr.c,v 1.10.2.4.2.1 2010/12/21 17:09:25 kensmith Exp $");
__FBSDID("$FreeBSD$");
/*
* Subroutines shared by the ukphy driver and other PHY drivers.
@@ -28,7 +28,7 @@
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: src/sys/dev/fxp/if_fxp.c,v 1.295.2.14.2.1 2010/12/21 17:09:25 kensmith Exp $");
__FBSDID("$FreeBSD$");
/*
* Intel EtherExpress Pro/100B PCI Fast Ethernet driver
@@ -194,7 +194,7 @@ static const struct fxp_ident const fxp_ident_table[] = {
{ 0x1229, 0x08, 0, "Intel 82559 Pro/100 Ethernet" },
{ 0x1229, 0x09, 0, "Intel 82559ER Pro/100 Ethernet" },
{ 0x1229, 0x0c, 0, "Intel 82550 Pro/100 Ethernet" },
{ 0x1229, 0x0d, 0, "Intel 82550 Pro/100 Ethernet" },
{ 0x1229, 0x0d, 0, "Intel 82550C Pro/100 Ethernet" },
{ 0x1229, 0x0e, 0, "Intel 82550 Pro/100 Ethernet" },
{ 0x1229, 0x0f, 0, "Intel 82551 Pro/100 Ethernet" },
{ 0x1229, 0x10, 0, "Intel 82551 Pro/100 Ethernet" },
@@ -248,6 +248,7 @@ static uint16_t fxp_eeprom_getword(struct fxp_softc *sc, int offset,
static void fxp_eeprom_putword(struct fxp_softc *sc, int offset,
uint16_t data);
static void fxp_autosize_eeprom(struct fxp_softc *sc);
static void fxp_load_eeprom(struct fxp_softc *sc);
static void fxp_read_eeprom(struct fxp_softc *sc, u_short *data,
int offset, int words);
static void fxp_write_eeprom(struct fxp_softc *sc, u_short *data,
@@ -289,7 +290,7 @@ static device_method_t fxp_methods[] = {
DEVMETHOD(miibus_writereg, fxp_miibus_writereg),
DEVMETHOD(miibus_statchg, fxp_miibus_statchg),
{ 0, 0 }
DEVMETHOD_END
};
static driver_t fxp_driver = {
@@ -300,8 +301,9 @@ static driver_t fxp_driver = {
static devclass_t fxp_devclass;
DRIVER_MODULE(fxp, pci, fxp_driver, fxp_devclass, 0, 0);
DRIVER_MODULE(miibus, fxp, miibus_driver, miibus_devclass, 0, 0);
DRIVER_MODULE_ORDERED(fxp, pci, fxp_driver, fxp_devclass, NULL, NULL,
SI_ORDER_ANY);
DRIVER_MODULE(miibus, fxp, miibus_driver, miibus_devclass, NULL, NULL);
static struct resource_spec fxp_res_spec_mem[] = {
{ SYS_RES_MEMORY, FXP_PCI_MMBA, RF_ACTIVE },
@@ -426,7 +428,7 @@ fxp_attach(device_t dev)
struct fxp_rx *rxp;
struct ifnet *ifp;
uint32_t val;
uint16_t data, myea[ETHER_ADDR_LEN / 2];
uint16_t data;
u_char eaddr[ETHER_ADDR_LEN];
int error, flags, i, pmc, prefer_iomap;
@@ -498,6 +500,7 @@ fxp_attach(device_t dev)
* Find out how large of an SEEPROM we have.
*/
fxp_autosize_eeprom(sc);
fxp_load_eeprom(sc);
/*
* Find out the chip revision; lump all 82557 revs together.
@@ -507,7 +510,7 @@ fxp_attach(device_t dev)
/* Assume ICH controllers are 82559. */
sc->revision = FXP_REV_82559_A0;
} else {
fxp_read_eeprom(sc, &data, 5, 1);
data = sc->eeprom[FXP_EEPROM_MAP_CNTR];
if ((data >> 8) == 1)
sc->revision = FXP_REV_82557;
else
@@ -519,15 +522,27 @@ fxp_attach(device_t dev)
*/
if (sc->revision >= FXP_REV_82558_A4 &&
sc->revision != FXP_REV_82559S_A) {
fxp_read_eeprom(sc, &data, 10, 1);
data = sc->eeprom[FXP_EEPROM_MAP_ID];
if ((data & 0x20) != 0 &&
pci_find_cap(sc->dev, PCIY_PMG, &pmc) == 0)
sc->flags |= FXP_FLAG_WOLCAP;
}
if (sc->revision == FXP_REV_82550_C) {
/*
* 82550C with server extension requires microcode to
* receive fragmented UDP datagrams. However if the
* microcode is used for client-only featured 82550C
* it locks up controller.
*/
data = sc->eeprom[FXP_EEPROM_MAP_COMPAT];
if ((data & 0x0400) == 0)
sc->flags |= FXP_FLAG_NO_UCODE;
}
/* Receiver lock-up workaround detection. */
if (sc->revision < FXP_REV_82558_A4) {
fxp_read_eeprom(sc, &data, 3, 1);
data = sc->eeprom[FXP_EEPROM_MAP_COMPAT];
if ((data & 0x03) != 0x03) {
sc->flags |= FXP_FLAG_RXBUG;
device_printf(dev, "Enabling Rx lock-up workaround\n");
@@ -537,7 +552,7 @@ fxp_attach(device_t dev)
/*
* Determine whether we must use the 503 serial interface.
*/
fxp_read_eeprom(sc, &data, 6, 1);
data = sc->eeprom[FXP_EEPROM_MAP_PRI_PHY];
if (sc->revision == FXP_REV_82557 && (data & FXP_PHY_DEVICE_MASK) != 0
&& (data & FXP_PHY_SERIAL_ONLY))
sc->flags |= FXP_FLAG_SERIAL_MEDIA;
@@ -557,7 +572,7 @@ fxp_attach(device_t dev)
*/
if ((sc->ident->ich >= 2 && sc->ident->ich <= 3) ||
(sc->ident->ich == 0 && sc->revision >= FXP_REV_82559_A0)) {
fxp_read_eeprom(sc, &data, 10, 1);
data = sc->eeprom[FXP_EEPROM_MAP_ID];
if (data & 0x02) { /* STB enable */
uint16_t cksum;
int i;
@@ -565,27 +580,24 @@ fxp_attach(device_t dev)
device_printf(dev,
"Disabling dynamic standby mode in EEPROM\n");
data &= ~0x02;
fxp_write_eeprom(sc, &data, 10, 1);
sc->eeprom[FXP_EEPROM_MAP_ID] = data;
fxp_write_eeprom(sc, &data, FXP_EEPROM_MAP_ID, 1);
device_printf(dev, "New EEPROM ID: 0x%x\n", data);
cksum = 0;
for (i = 0; i < (1 << sc->eeprom_size) - 1; i++) {
fxp_read_eeprom(sc, &data, i, 1);
cksum += data;
}
for (i = 0; i < (1 << sc->eeprom_size) - 1; i++)
cksum += sc->eeprom[i];
i = (1 << sc->eeprom_size) - 1;
cksum = 0xBABA - cksum;
fxp_read_eeprom(sc, &data, i, 1);
fxp_write_eeprom(sc, &cksum, i, 1);
device_printf(dev,
"EEPROM checksum @ 0x%x: 0x%x -> 0x%x\n",
i, data, cksum);
#if 1
i, sc->eeprom[i], cksum);
sc->eeprom[i] = cksum;
/*
* If the user elects to continue, try the software
* workaround, as it is better than nothing.
*/
sc->flags |= FXP_FLAG_CU_RESUME_BUG;
#endif
}
}
@@ -681,7 +693,8 @@ fxp_attach(device_t dev)
goto fail;
}
error = bus_dmamap_load(sc->fxp_stag, sc->fxp_smap, sc->fxp_stats,
sizeof(struct fxp_stats), fxp_dma_map_addr, &sc->stats_addr, 0);
sizeof(struct fxp_stats), fxp_dma_map_addr, &sc->stats_addr,
BUS_DMA_NOWAIT);
if (error) {
device_printf(dev, "could not load the stats DMA buffer\n");
goto fail;
@@ -705,7 +718,7 @@ fxp_attach(device_t dev)
error = bus_dmamap_load(sc->cbl_tag, sc->cbl_map,
sc->fxp_desc.cbl_list, FXP_TXCB_SZ, fxp_dma_map_addr,
&sc->fxp_desc.cbl_addr, 0);
&sc->fxp_desc.cbl_addr, BUS_DMA_NOWAIT);
if (error) {
device_printf(dev, "could not load TxCB DMA buffer\n");
goto fail;
@@ -729,7 +742,8 @@ fxp_attach(device_t dev)
goto fail;
}
error = bus_dmamap_load(sc->mcs_tag, sc->mcs_map, sc->mcsp,
sizeof(struct fxp_cb_mcs), fxp_dma_map_addr, &sc->mcs_addr, 0);
sizeof(struct fxp_cb_mcs), fxp_dma_map_addr, &sc->mcs_addr,
BUS_DMA_NOWAIT);
if (error) {
device_printf(dev,
"can't load the multicast setup DMA buffer\n");
@@ -777,21 +791,20 @@ fxp_attach(device_t dev)
/*
* Read MAC address.
*/
fxp_read_eeprom(sc, myea, 0, 3);
eaddr[0] = myea[0] & 0xff;
eaddr[1] = myea[0] >> 8;
eaddr[2] = myea[1] & 0xff;
eaddr[3] = myea[1] >> 8;
eaddr[4] = myea[2] & 0xff;
eaddr[5] = myea[2] >> 8;
eaddr[0] = sc->eeprom[FXP_EEPROM_MAP_IA0] & 0xff;
eaddr[1] = sc->eeprom[FXP_EEPROM_MAP_IA0] >> 8;
eaddr[2] = sc->eeprom[FXP_EEPROM_MAP_IA1] & 0xff;
eaddr[3] = sc->eeprom[FXP_EEPROM_MAP_IA1] >> 8;
eaddr[4] = sc->eeprom[FXP_EEPROM_MAP_IA2] & 0xff;
eaddr[5] = sc->eeprom[FXP_EEPROM_MAP_IA2] >> 8;
if (bootverbose) {
device_printf(dev, "PCI IDs: %04x %04x %04x %04x %04x\n",
pci_get_vendor(dev), pci_get_device(dev),
pci_get_subvendor(dev), pci_get_subdevice(dev),
pci_get_revid(dev));
fxp_read_eeprom(sc, &data, 10, 1);
device_printf(dev, "Dynamic Standby mode is %s\n",
data & 0x02 ? "enabled" : "disabled");
sc->eeprom[FXP_EEPROM_MAP_ID] & 0x02 ? "enabled" :
"disabled");
}
/*
@@ -900,7 +913,7 @@ fxp_attach(device_t dev)
FXP_LOCK(sc);
/* Clear wakeup events. */
CSR_WRITE_1(sc, FXP_CSR_PMDR, CSR_READ_1(sc, FXP_CSR_PMDR));
fxp_init_body(sc, 1);
fxp_init_body(sc, 0);
fxp_stop(sc);
FXP_UNLOCK(sc);
}
@@ -1287,6 +1300,23 @@ fxp_write_eeprom(struct fxp_softc *sc, u_short *data, int offset, int words)
fxp_eeprom_putword(sc, offset + i, data[i]);
}
static void
fxp_load_eeprom(struct fxp_softc *sc)
{
int i;
uint16_t cksum;
fxp_read_eeprom(sc, sc->eeprom, 0, 1 << sc->eeprom_size);
cksum = 0;
for (i = 0; i < (1 << sc->eeprom_size) - 1; i++)
cksum += sc->eeprom[i];
cksum = 0xBABA - cksum;
if (cksum != sc->eeprom[(1 << sc->eeprom_size) - 1])
device_printf(sc->dev,
"EEPROM checksum mismatch! (0x%04x -> 0x%04x)\n",
cksum, sc->eeprom[(1 << sc->eeprom_size) - 1]);
}
/*
* Grab the softc lock and call the real fxp_start_body() routine
*/
@@ -1454,7 +1484,7 @@ fxp_encap(struct fxp_softc *sc, struct mbuf **m_head)
return (ENOBUFS);
}
tcp = (struct tcphdr *)(mtod(m, char *) + poff);
m = m_pullup(m, poff + sizeof(struct tcphdr) + tcp->th_off);
m = m_pullup(m, poff + (tcp->th_off << 2));
if (m == NULL) {
*m_head = NULL;
return (ENOBUFS);
@@ -2580,12 +2610,6 @@ fxp_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr)
mii_pollstat(mii);
ifmr->ifm_active = mii->mii_media_active;
ifmr->ifm_status = mii->mii_media_status;
if (IFM_SUBTYPE(ifmr->ifm_active) == IFM_10_T &&
sc->flags & FXP_FLAG_CU_RESUME_BUG)
sc->cu_resume_bug = 1;
else
sc->cu_resume_bug = 0;
FXP_UNLOCK(sc);
}
@@ -2778,6 +2802,11 @@ fxp_miibus_statchg(device_t dev)
(IFM_AVALID | IFM_ACTIVE))
return;
if (IFM_SUBTYPE(mii->mii_media_active) == IFM_10_T &&
sc->flags & FXP_FLAG_CU_RESUME_BUG)
sc->cu_resume_bug = 1;
else
sc->cu_resume_bug = 0;
/*
* Call fxp_init_body in order to adjust the flow control settings.
* Note that the 82557 doesn't support hardware flow control.
@@ -2808,7 +2837,7 @@ fxp_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
if (((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0) &&
((ifp->if_flags ^ sc->if_flags) &
(IFF_PROMISC | IFF_ALLMULTI | IFF_LINK0)) != 0)
fxp_init_body(sc, 1);
fxp_init_body(sc, 0);
else if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
fxp_init_body(sc, 1);
} else {
@@ -2914,7 +2943,7 @@ fxp_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
reinit++;
}
if (reinit > 0 && ifp->if_flags & IFF_UP)
fxp_init_body(sc, 1);
fxp_init_body(sc, 0);
FXP_UNLOCK(sc);
VLAN_CAPABILITIES(ifp);
break;
@@ -3012,10 +3041,8 @@ static uint32_t fxp_ucode_d101a[] = D101_A_RCVBUNDLE_UCODE;
static uint32_t fxp_ucode_d101b0[] = D101_B0_RCVBUNDLE_UCODE;
static uint32_t fxp_ucode_d101ma[] = D101M_B_RCVBUNDLE_UCODE;
static uint32_t fxp_ucode_d101s[] = D101S_RCVBUNDLE_UCODE;
#ifdef notyet
static uint32_t fxp_ucode_d102[] = D102_B_RCVBUNDLE_UCODE;
static uint32_t fxp_ucode_d102c[] = D102_C_RCVBUNDLE_UCODE;
#endif
static uint32_t fxp_ucode_d102e[] = D102_E_RCVBUNDLE_UCODE;
#define UCODE(x) x, sizeof(x)/sizeof(uint32_t)
@@ -3033,12 +3060,10 @@ static const struct ucode {
D101M_CPUSAVER_DWORD, D101M_CPUSAVER_BUNDLE_MAX_DWORD },
{ FXP_REV_82559S_A, UCODE(fxp_ucode_d101s),
D101S_CPUSAVER_DWORD, D101S_CPUSAVER_BUNDLE_MAX_DWORD },
#ifdef notyet
{ FXP_REV_82550, UCODE(fxp_ucode_d102),
D102_B_CPUSAVER_DWORD, D102_B_CPUSAVER_BUNDLE_MAX_DWORD },
{ FXP_REV_82550_C, UCODE(fxp_ucode_d102c),
D102_C_CPUSAVER_DWORD, D102_C_CPUSAVER_BUNDLE_MAX_DWORD },
#endif
{ FXP_REV_82551_F, UCODE(fxp_ucode_d102e),
D102_E_CPUSAVER_DWORD, D102_E_CPUSAVER_BUNDLE_MAX_DWORD },
{ FXP_REV_82551_10, UCODE(fxp_ucode_d102e),
@@ -3053,6 +3078,9 @@ fxp_load_ucode(struct fxp_softc *sc)
struct fxp_cb_ucode *cbp;
int i;
if (sc->flags & FXP_FLAG_NO_UCODE)
return;
for (uc = ucode_table; uc->ucode != NULL; uc++)
if (sc->revision == uc->revision)
break;
@@ -3085,6 +3113,7 @@ fxp_load_ucode(struct fxp_softc *sc)
sc->tunable_int_delay,
uc->bundle_max_offset == 0 ? 0 : sc->tunable_bundle_max);
sc->flags |= FXP_FLAG_UCODE;
bzero(cbp, FXP_TXCB_SZ);
}
#define FXP_SYSCTL_STAT_ADD(c, h, n, p, d) \
@@ -25,7 +25,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD: src/sys/dev/fxp/if_fxpreg.h,v 1.43.2.3.2.1 2010/12/21 17:09:25 kensmith Exp $
* $FreeBSD$
*/
#define FXP_VENDORID_INTEL 0x8086
@@ -447,6 +447,24 @@ struct fxp_stats {
#define FXP_EEPROM_OPC_WRITE 0x5
#define FXP_EEPROM_OPC_READ 0x6
/*
* EEPROM map
*/
#define FXP_EEPROM_MAP_IA0 0x00 /* Station address */
#define FXP_EEPROM_MAP_IA1 0x01
#define FXP_EEPROM_MAP_IA2 0x02
#define FXP_EEPROM_MAP_COMPAT 0x03 /* Compatibility */
#define FXP_EEPROM_MAP_CNTR 0x05 /* Controller/connector type */
#define FXP_EEPROM_MAP_PRI_PHY 0x06 /* Primary PHY record */
#define FXP_EEPROM_MAP_SEC_PHY 0x07 /* Secondary PHY record */
#define FXP_EEPROM_MAP_PWA0 0x08 /* Printed wire assembly num. */
#define FXP_EEPROM_MAP_PWA1 0x09 /* Printed wire assembly num. */
#define FXP_EEPROM_MAP_ID 0x0A /* EEPROM ID */
#define FXP_EEPROM_MAP_SUBSYS 0x0B /* Subsystem ID */
#define FXP_EEPROM_MAP_SUBVEN 0x0C /* Subsystem vendor ID */
#define FXP_EEPROM_MAP_CKSUM64 0x3F /* 64-word EEPROM checksum */
#define FXP_EEPROM_MAP_CKSUM256 0xFF /* 256-word EEPROM checksum */
/*
* Management Data Interface opcodes
*/
@@ -24,7 +24,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD: src/sys/dev/fxp/if_fxpvar.h,v 1.49.2.4.2.1 2010/12/21 17:09:25 kensmith Exp $
* $FreeBSD$
*/
/*
@@ -219,6 +219,7 @@ struct fxp_softc {
int if_flags;
uint8_t rfa_size;
uint32_t tx_cmd;
uint16_t eeprom[256];
};
#define FXP_FLAG_MWI_ENABLE 0x0001 /* MWI enable */
@@ -236,6 +237,7 @@ struct fxp_softc {
#define FXP_FLAG_WOLCAP 0x2000 /* WOL capability */
#define FXP_FLAG_WOL 0x4000 /* WOL active */
#define FXP_FLAG_RXBUG 0x8000 /* Rx lock-up bug */
#define FXP_FLAG_NO_UCODE 0x10000 /* ucode is not applicable */
/* Macros to ease CSR access. */
#define CSR_READ_1(sc, reg) bus_read_1(sc->fxp_res[0], reg)
@@ -29,7 +29,7 @@
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: src/sys/dev/mii/inphy.c,v 1.17.10.7.2.1 2010/12/21 17:09:25 kensmith Exp $");
__FBSDID("$FreeBSD$");
/*
* driver for Intel 82553 and 82555 PHYs
@@ -26,7 +26,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD: src/sys/dev/mii/inphyreg.h,v 1.1.38.1.6.1 2010/12/21 17:09:25 kensmith Exp $
* $FreeBSD$
*/
#ifndef _INPHYREG_H
@@ -29,7 +29,7 @@ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
* $FreeBSD: src/sys/dev/fxp/rcvbundl.h,v 1.3.22.1.6.1 2010/12/21 17:09:25 kensmith Exp $
* $FreeBSD$
*/
/*
rcvbundl.h
@@ -1,4 +1,4 @@
$FreeBSD: src/sys/dev/e1000/LICENSE,v 1.1.4.2.4.1 2010/12/21 17:09:25 kensmith Exp $
$FreeBSD$
Copyright (c) 2001-2010, Intel Corporation
All rights reserved.
@@ -1,4 +1,4 @@
$FreeBSD: src/sys/dev/e1000/README,v 1.1.4.1.6.1 2010/12/21 17:09:25 kensmith Exp $
$FreeBSD$
FreeBSD* Driver for Intel Network Connection
=============================================
@@ -354,6 +354,7 @@ Known Limitations
include:
Planex FXG-08TE
I-O Data ETG-SH8
Netgear GS105v3
The driver can be compiled with the following changes:
@@ -1,6 +1,6 @@
/******************************************************************************
Copyright (c) 2001-2010, Intel Corporation
Copyright (c) 2001-2011, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -30,7 +30,7 @@
POSSIBILITY OF SUCH DAMAGE.
******************************************************************************/
/*$FreeBSD: src/sys/dev/e1000/e1000_80003es2lan.c,v 1.3.2.2.4.1 2010/12/21 17:09:25 kensmith Exp $*/
/*$FreeBSD$*/
/*
* 80003ES2LAN Gigabit Ethernet Controller (Copper)
@@ -234,9 +234,8 @@ static s32 e1000_init_mac_params_80003es2lan(struct e1000_hw *hw)
/* FWSM register */
mac->has_fwsm = TRUE;
/* ARC supported; valid only if manageability features are enabled. */
mac->arc_subsystem_valid =
(E1000_READ_REG(hw, E1000_FWSM) & E1000_FWSM_MODE_MASK)
? TRUE : FALSE;
mac->arc_subsystem_valid = (E1000_READ_REG(hw, E1000_FWSM) &
E1000_FWSM_MODE_MASK) ? TRUE : FALSE;
/* Adaptive IFS not supported */
mac->adaptive_ifs = FALSE;
@@ -330,7 +329,7 @@ static void e1000_release_phy_80003es2lan(struct e1000_hw *hw)
}
/**
* e1000_acquire_mac_csr_80003es2lan - Acquire rights to access Kumeran register
* e1000_acquire_mac_csr_80003es2lan - Acquire right to access Kumeran register
* @hw: pointer to the HW structure
*
* Acquire the semaphore to access the Kumeran interface.
@@ -348,7 +347,7 @@ static s32 e1000_acquire_mac_csr_80003es2lan(struct e1000_hw *hw)
}
/**
* e1000_release_mac_csr_80003es2lan - Release rights to access Kumeran Register
* e1000_release_mac_csr_80003es2lan - Release right to access Kumeran Register
* @hw: pointer to the HW structure
*
* Release the semaphore used to access the Kumeran interface
@@ -729,8 +728,7 @@ static s32 e1000_phy_force_speed_duplex_80003es2lan(struct e1000_hw *hw)
usec_delay(1);
if (hw->phy.autoneg_wait_to_complete) {
DEBUGOUT("Waiting for forced speed/duplex link "
"on GG82563 phy.\n");
DEBUGOUT("Waiting for forced speed/duplex link on GG82563 phy.\n");
ret_val = e1000_phy_has_link_generic(hw, PHY_FORCE_LIMIT,
100000, &link);
@@ -754,7 +752,8 @@ static s32 e1000_phy_force_speed_duplex_80003es2lan(struct e1000_hw *hw)
goto out;
}
ret_val = hw->phy.ops.read_reg(hw, GG82563_PHY_MAC_SPEC_CTRL, &phy_data);
ret_val = hw->phy.ops.read_reg(hw, GG82563_PHY_MAC_SPEC_CTRL,
&phy_data);
if (ret_val)
goto out;
@@ -773,7 +772,8 @@ static s32 e1000_phy_force_speed_duplex_80003es2lan(struct e1000_hw *hw)
* duplex.
*/
phy_data |= GG82563_MSCR_ASSERT_CRS_ON_TX;
ret_val = hw->phy.ops.write_reg(hw, GG82563_PHY_MAC_SPEC_CTRL, phy_data);
ret_val = hw->phy.ops.write_reg(hw, GG82563_PHY_MAC_SPEC_CTRL,
phy_data);
out:
return ret_val;
@@ -833,8 +833,7 @@ static s32 e1000_get_link_up_info_80003es2lan(struct e1000_hw *hw, u16 *speed,
DEBUGFUNC("e1000_get_link_up_info_80003es2lan");
if (hw->phy.media_type == e1000_media_type_copper) {
ret_val = e1000_get_speed_and_duplex_copper_generic(hw,
speed,
ret_val = e1000_get_speed_and_duplex_copper_generic(hw, speed,
duplex);
hw->phy.ops.cfg_on_link_up(hw);
} else {
@@ -1056,11 +1055,7 @@ static s32 e1000_copper_link_setup_gg82563_80003es2lan(struct e1000_hw *hw)
DEBUGFUNC("e1000_copper_link_setup_gg82563_80003es2lan");
if (phy->reset_disable)
goto skip_reset;
ret_val = hw->phy.ops.read_reg(hw, GG82563_PHY_MAC_SPEC_CTRL,
&data);
ret_val = hw->phy.ops.read_reg(hw, GG82563_PHY_MAC_SPEC_CTRL, &data);
if (ret_val)
goto out;
@@ -1068,8 +1063,7 @@ static s32 e1000_copper_link_setup_gg82563_80003es2lan(struct e1000_hw *hw)
/* Use 25MHz for both link down and 1000Base-T for Tx clock. */
data |= GG82563_MSCR_TX_CLK_1000MBPS_25;
ret_val = hw->phy.ops.write_reg(hw, GG82563_PHY_MAC_SPEC_CTRL,
data);
ret_val = hw->phy.ops.write_reg(hw, GG82563_PHY_MAC_SPEC_CTRL, data);
if (ret_val)
goto out;
@@ -1122,7 +1116,6 @@ static s32 e1000_copper_link_setup_gg82563_80003es2lan(struct e1000_hw *hw)
goto out;
}
skip_reset:
/* Bypass Rx and Tx FIFO's */
ret_val = e1000_write_kmrn_reg_80003es2lan(hw,
E1000_KMRNCTRLSTA_OFFSET_FIFO_CTRL,
@@ -1132,14 +1125,12 @@ skip_reset:
goto out;
ret_val = e1000_read_kmrn_reg_80003es2lan(hw,
E1000_KMRNCTRLSTA_OFFSET_MAC2PHY_OPMODE,
&data);
E1000_KMRNCTRLSTA_OFFSET_MAC2PHY_OPMODE, &data);
if (ret_val)
goto out;
data |= E1000_KMRNCTRLSTA_OPMODE_E_IDLE;
ret_val = e1000_write_kmrn_reg_80003es2lan(hw,
E1000_KMRNCTRLSTA_OFFSET_MAC2PHY_OPMODE,
data);
E1000_KMRNCTRLSTA_OFFSET_MAC2PHY_OPMODE, data);
if (ret_val)
goto out;
@@ -1241,14 +1232,12 @@ static s32 e1000_setup_copper_link_80003es2lan(struct e1000_hw *hw)
if (ret_val)
goto out;
ret_val = e1000_read_kmrn_reg_80003es2lan(hw,
E1000_KMRNCTRLSTA_OFFSET_INB_CTRL,
&reg_data);
E1000_KMRNCTRLSTA_OFFSET_INB_CTRL, &reg_data);
if (ret_val)
goto out;
reg_data |= E1000_KMRNCTRLSTA_INB_CTRL_DIS_PADDING;
ret_val = e1000_write_kmrn_reg_80003es2lan(hw,
E1000_KMRNCTRLSTA_OFFSET_INB_CTRL,
reg_data);
E1000_KMRNCTRLSTA_OFFSET_INB_CTRL, reg_data);
if (ret_val)
goto out;
@@ -1279,8 +1268,7 @@ static s32 e1000_cfg_on_link_up_80003es2lan(struct e1000_hw *hw)
DEBUGFUNC("e1000_configure_on_link_up");
if (hw->phy.media_type == e1000_media_type_copper) {
ret_val = e1000_get_speed_and_duplex_copper_generic(hw,
&speed,
ret_val = e1000_get_speed_and_duplex_copper_generic(hw, &speed,
&duplex);
if (ret_val)
goto out;
@@ -1343,7 +1331,8 @@ static s32 e1000_cfg_kmrn_10_100_80003es2lan(struct e1000_hw *hw, u16 duplex)
else
reg_data &= ~GG82563_KMCR_PASS_FALSE_CARRIER;
ret_val = hw->phy.ops.write_reg(hw, GG82563_PHY_KMRN_MODE_CTRL, reg_data);
ret_val = hw->phy.ops.write_reg(hw, GG82563_PHY_KMRN_MODE_CTRL,
reg_data);
out:
return ret_val;
@@ -1367,8 +1356,7 @@ static s32 e1000_cfg_kmrn_1000_80003es2lan(struct e1000_hw *hw)
reg_data = E1000_KMRNCTRLSTA_HD_CTRL_1000_DEFAULT;
ret_val = e1000_write_kmrn_reg_80003es2lan(hw,
E1000_KMRNCTRLSTA_OFFSET_HD_CTRL,
reg_data);
E1000_KMRNCTRLSTA_OFFSET_HD_CTRL, reg_data);
if (ret_val)
goto out;
@@ -1392,7 +1380,8 @@ static s32 e1000_cfg_kmrn_1000_80003es2lan(struct e1000_hw *hw)
} while ((reg_data != reg_data2) && (i < GG82563_MAX_KMRN_RETRY));
reg_data &= ~GG82563_KMCR_PASS_FALSE_CARRIER;
ret_val = hw->phy.ops.write_reg(hw, GG82563_PHY_KMRN_MODE_CTRL, reg_data);
ret_val = hw->phy.ops.write_reg(hw, GG82563_PHY_KMRN_MODE_CTRL,
reg_data);
out:
return ret_val;
@@ -1423,6 +1412,7 @@ static s32 e1000_read_kmrn_reg_80003es2lan(struct e1000_hw *hw, u32 offset,
kmrnctrlsta = ((offset << E1000_KMRNCTRLSTA_OFFSET_SHIFT) &
E1000_KMRNCTRLSTA_OFFSET) | E1000_KMRNCTRLSTA_REN;
E1000_WRITE_REG(hw, E1000_KMRNCTRLSTA, kmrnctrlsta);
E1000_WRITE_FLUSH(hw);
usec_delay(2);
@@ -1460,6 +1450,7 @@ static s32 e1000_write_kmrn_reg_80003es2lan(struct e1000_hw *hw, u32 offset,
kmrnctrlsta = ((offset << E1000_KMRNCTRLSTA_OFFSET_SHIFT) &
E1000_KMRNCTRLSTA_OFFSET) | data;
E1000_WRITE_REG(hw, E1000_KMRNCTRLSTA, kmrnctrlsta);
E1000_WRITE_FLUSH(hw);
usec_delay(2);
@@ -1,6 +1,6 @@
/******************************************************************************
Copyright (c) 2001-2010, Intel Corporation
Copyright (c) 2001-2011, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -30,7 +30,7 @@
POSSIBILITY OF SUCH DAMAGE.
******************************************************************************/
/*$FreeBSD: src/sys/dev/e1000/e1000_80003es2lan.h,v 1.1.4.2.4.1 2010/12/21 17:09:25 kensmith Exp $*/
/*$FreeBSD$*/
#ifndef _E1000_80003ES2LAN_H_
#define _E1000_80003ES2LAN_H_
@@ -65,8 +65,7 @@
#define GG82563_PSCR_CROSSOVER_MODE_AUTO 0x0060 /* 11=Auto crossover */
/* PHY Specific Control Register 2 (Page 0, Register 26) */
#define GG82563_PSCR2_REVERSE_AUTO_NEG 0x2000
/* 1=Reverse Auto-Negotiation */
#define GG82563_PSCR2_REVERSE_AUTO_NEG 0x2000 /* 1=Reverse Auto-Nego */
/* MAC Specific Control Register (Page 2, Register 21) */
/* Tx clock speed for Link Down and 1000BASE-T for the following speeds */
@@ -95,8 +94,8 @@
#define GG82563_MAX_KMRN_RETRY 0x5
/* Power Management Control Register (Page 193, Register 20) */
/* 1=Enable SERDES Electrical Idle */
#define GG82563_PMCR_ENABLE_ELECTRICAL_IDLE 0x0001
/* 1=Enable SERDES Electrical Idle */
/* In-Band Control Register (Page 194, Register 18) */
#define GG82563_ICR_DIS_PADDING 0x0010 /* Disable Padding */
@@ -1,6 +1,6 @@
/******************************************************************************
Copyright (c) 2001-2010, Intel Corporation
Copyright (c) 2001-2011, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -30,7 +30,7 @@
POSSIBILITY OF SUCH DAMAGE.
******************************************************************************/
/*$FreeBSD: src/sys/dev/e1000/e1000_82540.c,v 1.4.2.2.4.1 2010/12/21 17:09:25 kensmith Exp $*/
/*$FreeBSD$*/
/*
* 82540EM Gigabit Ethernet Controller
@@ -427,11 +427,13 @@ static s32 e1000_setup_copper_link_82540(struct e1000_hw *hw)
if (hw->mac.type == e1000_82545_rev_3 ||
hw->mac.type == e1000_82546_rev_3) {
ret_val = hw->phy.ops.read_reg(hw, M88E1000_PHY_SPEC_CTRL, &data);
ret_val = hw->phy.ops.read_reg(hw, M88E1000_PHY_SPEC_CTRL,
&data);
if (ret_val)
goto out;
data |= 0x00000008;
ret_val = hw->phy.ops.write_reg(hw, M88E1000_PHY_SPEC_CTRL, data);
ret_val = hw->phy.ops.write_reg(hw, M88E1000_PHY_SPEC_CTRL,
data);
if (ret_val)
goto out;
}
@@ -508,8 +510,7 @@ static s32 e1000_adjust_serdes_amplitude_82540(struct e1000_hw *hw)
if (nvm_data != NVM_RESERVED_WORD) {
/* Adjust serdes output amplitude only. */
nvm_data &= NVM_SERDES_AMPLITUDE_MASK;
ret_val = hw->phy.ops.write_reg(hw,
M88E1000_PHY_EXT_CTRL,
ret_val = hw->phy.ops.write_reg(hw, M88E1000_PHY_EXT_CTRL,
nvm_data);
if (ret_val)
goto out;
@@ -535,8 +536,7 @@ static s32 e1000_set_vco_speed_82540(struct e1000_hw *hw)
/* Set PHY register 30, page 5, bit 8 to 0 */
ret_val = hw->phy.ops.read_reg(hw,
M88E1000_PHY_PAGE_SELECT,
ret_val = hw->phy.ops.read_reg(hw, M88E1000_PHY_PAGE_SELECT,
&default_page);
if (ret_val)
goto out;
@@ -587,7 +587,6 @@ out:
**/
static s32 e1000_set_phy_mode_82540(struct e1000_hw *hw)
{
struct e1000_phy_info *phy = &hw->phy;
s32 ret_val = E1000_SUCCESS;
u16 nvm_data;
@@ -609,15 +608,13 @@ static s32 e1000_set_phy_mode_82540(struct e1000_hw *hw)
ret_val = -E1000_ERR_PHY;
goto out;
}
ret_val = hw->phy.ops.write_reg(hw,
M88E1000_PHY_GEN_CONTROL,
ret_val = hw->phy.ops.write_reg(hw, M88E1000_PHY_GEN_CONTROL,
0x8104);
if (ret_val) {
ret_val = -E1000_ERR_PHY;
goto out;
}
phy->reset_disable = FALSE;
}
out:
@@ -1,6 +1,6 @@
/******************************************************************************
Copyright (c) 2001-2010, Intel Corporation
Copyright (c) 2001-2011, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -30,7 +30,7 @@
POSSIBILITY OF SUCH DAMAGE.
******************************************************************************/
/*$FreeBSD: src/sys/dev/e1000/e1000_82541.c,v 1.4.2.2.4.1 2010/12/21 17:09:25 kensmith Exp $*/
/*$FreeBSD$*/
/*
* 82541EI Gigabit Ethernet Controller
@@ -300,7 +300,7 @@ void e1000_init_function_pointers_82541(struct e1000_hw *hw)
**/
static s32 e1000_reset_hw_82541(struct e1000_hw *hw)
{
u32 ledctl, ctrl, manc;
u32 ledctl, ctrl, icr, manc;
DEBUGFUNC("e1000_reset_hw_82541");
@@ -364,7 +364,7 @@ static s32 e1000_reset_hw_82541(struct e1000_hw *hw)
E1000_WRITE_REG(hw, E1000_IMC, 0xFFFFFFFF);
/* Clear any pending interrupt events. */
E1000_READ_REG(hw, E1000_ICR);
icr = E1000_READ_REG(hw, E1000_ICR);
return E1000_SUCCESS;
}
@@ -549,8 +549,6 @@ static s32 e1000_setup_copper_link_82541(struct e1000_hw *hw)
ctrl &= ~(E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX);
E1000_WRITE_REG(hw, E1000_CTRL, ctrl);
hw->phy.reset_disable = FALSE;
/* Earlier revs of the IGP phy require us to force MDI. */
if (hw->mac.type == e1000_82541 || hw->mac.type == e1000_82547) {
dev_spec->dsp_config = e1000_dsp_config_disabled;
@@ -644,7 +642,7 @@ static s32 e1000_check_for_link_82541(struct e1000_hw *hw)
* of MAC speed/duplex configuration. So we only need to
* configure Collision Distance in the MAC.
*/
e1000_config_collision_dist_generic(hw);
mac->ops.config_collision_dist(hw);
/*
* Configure Flow Control now that Auto-Neg has completed.
@@ -30,7 +30,7 @@
POSSIBILITY OF SUCH DAMAGE.
******************************************************************************/
/*$FreeBSD: src/sys/dev/e1000/e1000_82541.h,v 1.1.4.1.6.1 2010/12/21 17:09:25 kensmith Exp $*/
/*$FreeBSD$*/
#ifndef _E1000_82541_H_
#define _E1000_82541_H_
@@ -30,7 +30,7 @@
POSSIBILITY OF SUCH DAMAGE.
******************************************************************************/
/*$FreeBSD: src/sys/dev/e1000/e1000_82542.c,v 1.3.2.2.4.1 2010/12/21 17:09:25 kensmith Exp $*/
/*$FreeBSD$*/
/*
* 82542 Gigabit Ethernet Controller
@@ -1,6 +1,6 @@
/******************************************************************************
Copyright (c) 2001-2010, Intel Corporation
Copyright (c) 2001-2011, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -30,7 +30,7 @@
POSSIBILITY OF SUCH DAMAGE.
******************************************************************************/
/*$FreeBSD: src/sys/dev/e1000/e1000_82543.c,v 1.2.2.2.4.1 2010/12/21 17:09:25 kensmith Exp $*/
/*$FreeBSD$*/
/*
* 82543GC Gigabit Ethernet Controller (Fiber)
@@ -901,7 +901,7 @@ static s32 e1000_phy_hw_reset_82543(struct e1000_hw *hw)
**/
static s32 e1000_reset_hw_82543(struct e1000_hw *hw)
{
u32 ctrl;
u32 ctrl, icr;
s32 ret_val = E1000_SUCCESS;
DEBUGFUNC("e1000_reset_hw_82543");
@@ -943,7 +943,7 @@ static s32 e1000_reset_hw_82543(struct e1000_hw *hw)
/* Masking off and clearing any pending interrupts */
E1000_WRITE_REG(hw, E1000_IMC, 0xffffffff);
E1000_READ_REG(hw, E1000_ICR);
icr = E1000_READ_REG(hw, E1000_ICR);
return ret_val;
}
@@ -1079,7 +1079,6 @@ static s32 e1000_setup_copper_link_82543(struct e1000_hw *hw)
ret_val = hw->phy.ops.reset(hw);
if (ret_val)
goto out;
hw->phy.reset_disable = FALSE;
} else {
ctrl &= ~(E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX);
E1000_WRITE_REG(hw, E1000_CTRL, ctrl);
@@ -1127,7 +1126,7 @@ static s32 e1000_setup_copper_link_82543(struct e1000_hw *hw)
DEBUGOUT("Valid link established!!!\n");
/* Config the MAC and PHY after link is up */
if (hw->mac.type == e1000_82544) {
e1000_config_collision_dist_generic(hw);
hw->mac.ops.config_collision_dist(hw);
} else {
ret_val = e1000_config_mac_to_phy_82543(hw);
if (ret_val)
@@ -1161,7 +1160,7 @@ static s32 e1000_setup_fiber_link_82543(struct e1000_hw *hw)
/* Take the link out of reset */
ctrl &= ~E1000_CTRL_LRST;
e1000_config_collision_dist_generic(hw);
hw->mac.ops.config_collision_dist(hw);
ret_val = e1000_commit_fc_settings_generic(hw);
if (ret_val)
@@ -1260,7 +1259,7 @@ static s32 e1000_check_for_copper_link_82543(struct e1000_hw *hw)
* settings.
*/
if (mac->type == e1000_82544)
e1000_config_collision_dist_generic(hw);
hw->mac.ops.config_collision_dist(hw);
else {
ret_val = e1000_config_mac_to_phy_82543(hw);
if (ret_val) {
@@ -1434,7 +1433,7 @@ static s32 e1000_config_mac_to_phy_82543(struct e1000_hw *hw)
if (phy_data & M88E1000_PSSR_DPLX)
ctrl |= E1000_CTRL_FD;
e1000_config_collision_dist_generic(hw);
hw->mac.ops.config_collision_dist(hw);
/*
* Set up speed in the Device Control register depending on
@@ -30,7 +30,7 @@
POSSIBILITY OF SUCH DAMAGE.
******************************************************************************/
/*$FreeBSD: src/sys/dev/e1000/e1000_82543.h,v 1.1.4.1.6.1 2010/12/21 17:09:25 kensmith Exp $*/
/*$FreeBSD$*/
#ifndef _E1000_82543_H_
#define _E1000_82543_H_
@@ -1,6 +1,6 @@
/******************************************************************************
Copyright (c) 2001-2010, Intel Corporation
Copyright (c) 2001-2011, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -30,7 +30,7 @@
POSSIBILITY OF SUCH DAMAGE.
******************************************************************************/
/*$FreeBSD: src/sys/dev/e1000/e1000_82571.c,v 1.4.2.3.2.1 2010/12/21 17:09:25 kensmith Exp $*/
/*$FreeBSD$*/
/*
* 82571EB Gigabit Ethernet Controller
@@ -363,8 +363,6 @@ static s32 e1000_init_mac_params_82571(struct e1000_hw *hw)
mac->ops.read_mac_addr = e1000_read_mac_addr_82571;
/* ID LED init */
mac->ops.id_led_init = e1000_id_led_init_generic;
/* blink LED */
mac->ops.blink_led = e1000_blink_led_generic;
/* setup LED */
mac->ops.setup_led = e1000_setup_led_generic;
/* cleanup LED */
@@ -380,6 +378,7 @@ static s32 e1000_init_mac_params_82571(struct e1000_hw *hw)
mac->ops.set_lan_id = e1000_set_lan_id_single_port;
mac->ops.check_mng_mode = e1000_check_mng_mode_generic;
mac->ops.led_on = e1000_led_on_generic;
mac->ops.blink_led = e1000_blink_led_generic;
/* FWSM register */
mac->has_fwsm = TRUE;
@@ -387,9 +386,8 @@ static s32 e1000_init_mac_params_82571(struct e1000_hw *hw)
* ARC supported; valid only if manageability features are
* enabled.
*/
mac->arc_subsystem_valid =
(E1000_READ_REG(hw, E1000_FWSM) & E1000_FWSM_MODE_MASK)
? TRUE : FALSE;
mac->arc_subsystem_valid = (E1000_READ_REG(hw, E1000_FWSM) &
E1000_FWSM_MODE_MASK) ? TRUE : FALSE;
break;
case e1000_82574:
case e1000_82583:
@@ -400,6 +398,7 @@ static s32 e1000_init_mac_params_82571(struct e1000_hw *hw)
default:
mac->ops.check_mng_mode = e1000_check_mng_mode_generic;
mac->ops.led_on = e1000_led_on_generic;
mac->ops.blink_led = e1000_blink_led_generic;
/* FWSM register */
mac->has_fwsm = TRUE;
@@ -420,8 +419,8 @@ static s32 e1000_init_mac_params_82571(struct e1000_hw *hw)
if (!(swsm2 & E1000_SWSM2_LOCK)) {
/* Only do this for the first interface on this card */
E1000_WRITE_REG(hw, E1000_SWSM2,
swsm2 | E1000_SWSM2_LOCK);
E1000_WRITE_REG(hw, E1000_SWSM2, swsm2 |
E1000_SWSM2_LOCK);
force_clear_smbi = TRUE;
} else
force_clear_smbi = FALSE;
@@ -1255,8 +1254,7 @@ static s32 e1000_init_hw_82571(struct e1000_hw *hw)
/* Set the transmit descriptor write-back policy */
reg_data = E1000_READ_REG(hw, E1000_TXDCTL(0));
reg_data = (reg_data & ~E1000_TXDCTL_WTHRESH) |
E1000_TXDCTL_FULL_TX_DESC_WB |
E1000_TXDCTL_COUNT_DESC;
E1000_TXDCTL_FULL_TX_DESC_WB | E1000_TXDCTL_COUNT_DESC;
E1000_WRITE_REG(hw, E1000_TXDCTL(0), reg_data);
/* ...for both queues. */
@@ -1320,6 +1318,10 @@ static void e1000_initialize_hw_bits_82571(struct e1000_hw *hw)
case e1000_82572:
reg |= (1 << 23) | (1 << 24) | (1 << 25) | (1 << 26);
break;
case e1000_82574:
case e1000_82583:
reg |= (1 << 26);
break;
default:
break;
}
@@ -1640,7 +1642,8 @@ static s32 e1000_setup_fiber_serdes_link_82571(struct e1000_hw *hw)
* mode. This prevents drivers from twiddling their thumbs
* if another tool failed to take it out of loopback mode.
*/
E1000_WRITE_REG(hw, E1000_SCTL, E1000_SCTL_DISABLE_SERDES_LOOPBACK);
E1000_WRITE_REG(hw, E1000_SCTL,
E1000_SCTL_DISABLE_SERDES_LOOPBACK);
break;
default:
break;
@@ -1664,7 +1667,7 @@ static s32 e1000_setup_fiber_serdes_link_82571(struct e1000_hw *hw)
*
* 1) down
* 2) autoneg_progress
* 3) autoneg_complete (the link sucessfully autonegotiated)
* 3) autoneg_complete (the link successfully autonegotiated)
* 4) forced_up (the link has been forced up, it did not autonegotiate)
*
**/
@@ -1777,8 +1780,8 @@ static s32 e1000_check_for_serdes_link_82571(struct e1000_hw *hw)
* up.
*/
E1000_WRITE_REG(hw, E1000_TXCW, mac->txcw);
E1000_WRITE_REG(hw, E1000_CTRL,
(ctrl & ~E1000_CTRL_SLU));
E1000_WRITE_REG(hw, E1000_CTRL, (ctrl &
~E1000_CTRL_SLU));
mac->serdes_link_state =
e1000_serdes_link_autoneg_progress;
mac->serdes_has_link = FALSE;
@@ -1904,7 +1907,7 @@ void e1000_set_laa_state_82571(struct e1000_hw *hw, bool state)
* incoming packets directed to this port are dropped.
* Eventually the LAA will be in RAR[0] and RAR[14].
*/
e1000_rar_set_generic(hw, hw->mac.addr,
hw->mac.ops.rar_set(hw, hw->mac.addr,
hw->mac.rar_entry_count - 1);
return;
}
@@ -30,7 +30,7 @@
POSSIBILITY OF SUCH DAMAGE.
******************************************************************************/
/*$FreeBSD: src/sys/dev/e1000/e1000_82571.h,v 1.1.4.2.2.1 2010/12/21 17:09:25 kensmith Exp $*/
/*$FreeBSD$*/
#ifndef _E1000_82571_H_
#define _E1000_82571_H_
File diff suppressed because it is too large Load Diff
@@ -1,6 +1,6 @@
/******************************************************************************
Copyright (c) 2001-2010, Intel Corporation
Copyright (c) 2001-2011, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -30,7 +30,7 @@
POSSIBILITY OF SUCH DAMAGE.
******************************************************************************/
/*$FreeBSD: src/sys/dev/e1000/e1000_82575.h,v 1.4.2.4.2.1 2010/12/21 17:09:25 kensmith Exp $*/
/*$FreeBSD$*/
#ifndef _E1000_82575_H_
#define _E1000_82575_H_
@@ -63,19 +63,19 @@ struct e1000_adv_data_desc {
union {
u32 data;
struct {
u32 datalen :16; /* Data buffer length */
u32 rsvd :4;
u32 dtyp :4; /* Descriptor type */
u32 dcmd :8; /* Descriptor command */
u32 datalen:16; /* Data buffer length */
u32 rsvd:4;
u32 dtyp:4; /* Descriptor type */
u32 dcmd:8; /* Descriptor command */
} config;
} lower;
union {
u32 data;
struct {
u32 status :4; /* Descriptor status */
u32 idx :4;
u32 popts :6; /* Packet Options */
u32 paylen :18; /* Payload length */
u32 status:4; /* Descriptor status */
u32 idx:4;
u32 popts:6; /* Packet Options */
u32 paylen:18; /* Payload length */
} options;
} upper;
};
@@ -100,23 +100,23 @@ struct e1000_adv_context_desc {
union {
u32 ip_config;
struct {
u32 iplen :9;
u32 maclen :7;
u32 vlan_tag :16;
u32 iplen:9;
u32 maclen:7;
u32 vlan_tag:16;
} fields;
} ip_setup;
u32 seq_num;
union {
u64 l4_config;
struct {
u32 mkrloc :9;
u32 tucmd :11;
u32 dtyp :4;
u32 adv :8;
u32 rsvd :4;
u32 idx :4;
u32 l4len :8;
u32 mss :16;
u32 mkrloc:9;
u32 tucmd:11;
u32 dtyp:4;
u32 adv:8;
u32 rsvd:4;
u32 idx:4;
u32 l4len:8;
u32 mss:16;
} fields;
} l4_setup;
};
@@ -151,7 +151,8 @@ struct e1000_adv_context_desc {
#define E1000_MRQC_ENABLE_RSS_8Q 0x00000002
#define E1000_VMRCTL_MIRROR_PORT_SHIFT 8
#define E1000_VMRCTL_MIRROR_DSTPORT_MASK (7 << E1000_VMRCTL_MIRROR_PORT_SHIFT)
#define E1000_VMRCTL_MIRROR_DSTPORT_MASK (7 << \
E1000_VMRCTL_MIRROR_PORT_SHIFT)
#define E1000_VMRCTL_POOL_MIRROR_ENABLE (1 << 0)
#define E1000_VMRCTL_UPLINK_MIRROR_ENABLE (1 << 1)
#define E1000_VMRCTL_DOWNLINK_MIRROR_ENABLE (1 << 2)
@@ -299,14 +300,15 @@ union e1000_adv_tx_desc {
#define E1000_ADVTXD_DCMD_DEXT 0x20000000 /* Descriptor extension (1=Adv) */
#define E1000_ADVTXD_DCMD_VLE 0x40000000 /* VLAN pkt enable */
#define E1000_ADVTXD_DCMD_TSE 0x80000000 /* TCP Seg enable */
#define E1000_ADVTXD_MAC_LINKSEC 0x00040000 /* Apply LinkSec on packet */
#define E1000_ADVTXD_MAC_TSTAMP 0x00080000 /* IEEE1588 Timestamp packet */
#define E1000_ADVTXD_STAT_SN_CRC 0x00000002 /* NXTSEQ/SEED present in WB */
#define E1000_ADVTXD_MAC_LINKSEC 0x00040000 /* Apply LinkSec on pkt */
#define E1000_ADVTXD_MAC_TSTAMP 0x00080000 /* IEEE1588 Timestamp pkt */
#define E1000_ADVTXD_STAT_SN_CRC 0x00000002 /* NXTSEQ/SEED prsnt in WB */
#define E1000_ADVTXD_IDX_SHIFT 4 /* Adv desc Index shift */
#define E1000_ADVTXD_POPTS_ISCO_1ST 0x00000000 /* 1st TSO of iSCSI PDU */
#define E1000_ADVTXD_POPTS_ISCO_MDL 0x00000800 /* Middle TSO of iSCSI PDU */
#define E1000_ADVTXD_POPTS_ISCO_LAST 0x00001000 /* Last TSO of iSCSI PDU */
#define E1000_ADVTXD_POPTS_ISCO_FULL 0x00001800 /* 1st&Last TSO-full iSCSI PDU*/
/* 1st & Last TSO-full iSCSI PDU*/
#define E1000_ADVTXD_POPTS_ISCO_FULL 0x00001800
#define E1000_ADVTXD_POPTS_IPSEC 0x00000400 /* IPSec offload request */
#define E1000_ADVTXD_PAYLEN_SHIFT 14 /* Adv desc PAYLEN shift */
@@ -328,7 +330,8 @@ struct e1000_adv_tx_context_desc {
#define E1000_ADVTXD_TUCMD_IPSEC_TYPE_ESP 0x00002000 /* IPSec Type ESP */
/* IPSec Encrypt Enable for ESP */
#define E1000_ADVTXD_TUCMD_IPSEC_ENCRYPT_EN 0x00004000
#define E1000_ADVTXD_TUCMD_MKRREQ 0x00002000 /* Req requires Markers and CRC */
/* Req requires Markers and CRC */
#define E1000_ADVTXD_TUCMD_MKRREQ 0x00002000
#define E1000_ADVTXD_L4LEN_SHIFT 8 /* Adv ctxt L4LEN shift */
#define E1000_ADVTXD_MSS_SHIFT 16 /* Adv ctxt MSS shift */
/* Adv ctxt IPSec SA IDX mask */
@@ -337,14 +340,14 @@ struct e1000_adv_tx_context_desc {
#define E1000_ADVTXD_IPSEC_ESP_LEN_MASK 0x000000FF
/* Additional Transmit Descriptor Control definitions */
#define E1000_TXDCTL_QUEUE_ENABLE 0x02000000 /* Enable specific Tx Queue */
#define E1000_TXDCTL_SWFLSH 0x04000000 /* Tx Desc. write-back flushing */
#define E1000_TXDCTL_QUEUE_ENABLE 0x02000000 /* Ena specific Tx Queue */
#define E1000_TXDCTL_SWFLSH 0x04000000 /* Tx Desc. wbk flushing */
/* Tx Queue Arbitration Priority 0=low, 1=high */
#define E1000_TXDCTL_PRIORITY 0x08000000
/* Additional Receive Descriptor Control definitions */
#define E1000_RXDCTL_QUEUE_ENABLE 0x02000000 /* Enable specific Rx Queue */
#define E1000_RXDCTL_SWFLSH 0x04000000 /* Rx Desc. write-back flushing */
#define E1000_RXDCTL_QUEUE_ENABLE 0x02000000 /* Ena specific Rx Queue */
#define E1000_RXDCTL_SWFLSH 0x04000000 /* Rx Desc. wbk flushing */
/* Direct Cache Access (DCA) definitions */
#define E1000_DCA_CTRL_DCA_ENABLE 0x00000000 /* DCA Enable */
@@ -355,8 +358,8 @@ struct e1000_adv_tx_context_desc {
#define E1000_DCA_RXCTRL_CPUID_MASK 0x0000001F /* Rx CPUID Mask */
#define E1000_DCA_RXCTRL_DESC_DCA_EN (1 << 5) /* DCA Rx Desc enable */
#define E1000_DCA_RXCTRL_HEAD_DCA_EN (1 << 6) /* DCA Rx Desc header enable */
#define E1000_DCA_RXCTRL_DATA_DCA_EN (1 << 7) /* DCA Rx Desc payload enable */
#define E1000_DCA_RXCTRL_HEAD_DCA_EN (1 << 6) /* DCA Rx Desc header ena */
#define E1000_DCA_RXCTRL_DATA_DCA_EN (1 << 7) /* DCA Rx Desc payload ena */
#define E1000_DCA_TXCTRL_CPUID_MASK 0x0000001F /* Tx CPUID Mask */
#define E1000_DCA_TXCTRL_DESC_DCA_EN (1 << 5) /* DCA Tx Desc enable */
@@ -396,10 +399,10 @@ struct e1000_adv_tx_context_desc {
#define E1000_FTQF_MASK_SOURCE_PORT_BP 0x80000000
#define E1000_NVM_APME_82575 0x0400
#define MAX_NUM_VFS 8
#define MAX_NUM_VFS 7
#define E1000_DTXSWC_MAC_SPOOF_MASK 0x000000FF /* Per VF MAC spoof control */
#define E1000_DTXSWC_VLAN_SPOOF_MASK 0x0000FF00 /* Per VF VLAN spoof control */
#define E1000_DTXSWC_MAC_SPOOF_MASK 0x000000FF /* Per VF MAC spoof cntrl */
#define E1000_DTXSWC_VLAN_SPOOF_MASK 0x0000FF00 /* Per VF VLAN spoof cntrl */
#define E1000_DTXSWC_LLE_MASK 0x00FF0000 /* Per VF Local LB enables */
#define E1000_DTXSWC_VLAN_SPOOF_SHIFT 8
#define E1000_DTXSWC_LLE_SHIFT 16
@@ -462,6 +465,8 @@ struct e1000_adv_tx_context_desc {
#define E1000_DTXCTL_MDP_EN 0x0020
#define E1000_DTXCTL_SPOOF_INT 0x0040
#define E1000_EEPROM_PCS_AUTONEG_DISABLE_BIT (1 << 14)
#define ALL_QUEUES 0xFFFF
/* Rx packet buffer size defines */
@@ -484,4 +489,23 @@ void e1000_rlpml_set_vf(struct e1000_hw *, u16);
s32 e1000_promisc_set_vf(struct e1000_hw *, enum e1000_promisc_type type);
u16 e1000_rxpbs_adjust_82580(u32 data);
s32 e1000_set_eee_i350(struct e1000_hw *);
/* I2C SDA and SCL timing parameters for standard mode */
#define E1000_I2C_T_HD_STA 4
#define E1000_I2C_T_LOW 5
#define E1000_I2C_T_HIGH 4
#define E1000_I2C_T_SU_STA 5
#define E1000_I2C_T_HD_DATA 5
#define E1000_I2C_T_SU_DATA 1
#define E1000_I2C_T_RISE 1
#define E1000_I2C_T_FALL 1
#define E1000_I2C_T_SU_STO 4
#define E1000_I2C_T_BUF 5
s32 e1000_set_i2c_bb(struct e1000_hw *hw);
s32 e1000_read_i2c_byte_generic(struct e1000_hw *hw, u8 byte_offset,
u8 dev_addr, u8 *data);
s32 e1000_write_i2c_byte_generic(struct e1000_hw *hw, u8 byte_offset,
u8 dev_addr, u8 data);
void e1000_i2c_bus_clear(struct e1000_hw *hw);
#endif /* _E1000_82575_H_ */
@@ -1,6 +1,6 @@
/******************************************************************************
Copyright (c) 2001-2010, Intel Corporation
Copyright (c) 2001-2012, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -30,7 +30,7 @@
POSSIBILITY OF SUCH DAMAGE.
******************************************************************************/
/*$FreeBSD: src/sys/dev/e1000/e1000_api.c,v 1.4.2.4.2.1 2010/12/21 17:09:25 kensmith Exp $*/
/*$FreeBSD$*/
#include "e1000_api.h"
@@ -277,7 +277,6 @@ s32 e1000_set_mac_type(struct e1000_hw *hw)
case E1000_DEV_ID_ICH10_D_BM_LM:
case E1000_DEV_ID_ICH10_D_BM_LF:
case E1000_DEV_ID_ICH10_D_BM_V:
case E1000_DEV_ID_ICH10_HANKSVILLE:
mac->type = e1000_ich10lan;
break;
case E1000_DEV_ID_PCH_D_HV_DM:
@@ -293,7 +292,6 @@ s32 e1000_set_mac_type(struct e1000_hw *hw)
case E1000_DEV_ID_82575EB_COPPER:
case E1000_DEV_ID_82575EB_FIBER_SERDES:
case E1000_DEV_ID_82575GB_QUAD_COPPER:
case E1000_DEV_ID_82575GB_QUAD_COPPER_PM:
mac->type = e1000_82575;
break;
case E1000_DEV_ID_82576:
@@ -322,8 +320,20 @@ s32 e1000_set_mac_type(struct e1000_hw *hw)
case E1000_DEV_ID_I350_FIBER:
case E1000_DEV_ID_I350_SERDES:
case E1000_DEV_ID_I350_SGMII:
case E1000_DEV_ID_I350_DA4:
mac->type = e1000_i350;
break;
case E1000_DEV_ID_I210_COPPER:
case E1000_DEV_ID_I210_COPPER_OEM1:
case E1000_DEV_ID_I210_COPPER_IT:
case E1000_DEV_ID_I210_FIBER:
case E1000_DEV_ID_I210_SERDES:
case E1000_DEV_ID_I210_SGMII:
mac->type = e1000_i210;
break;
case E1000_DEV_ID_I211_COPPER:
mac->type = e1000_i211;
break;
case E1000_DEV_ID_82576_VF:
mac->type = e1000_vfadapt;
break;
@@ -426,6 +436,10 @@ s32 e1000_setup_init_funcs(struct e1000_hw *hw, bool init_device)
case e1000_i350:
e1000_init_function_pointers_82575(hw);
break;
case e1000_i210:
case e1000_i211:
e1000_init_function_pointers_i210(hw);
break;
case e1000_vfadapt:
e1000_init_function_pointers_vf(hw);
break;
@@ -856,7 +870,7 @@ bool e1000_enable_tx_pkt_filtering(struct e1000_hw *hw)
* It also does alignment considerations to do the writes in most efficient
* way. Also fills up the sum of the buffer in *buffer parameter.
**/
s32 e1000_mng_host_if_write(struct e1000_hw * hw, u8 *buffer, u16 length,
s32 e1000_mng_host_if_write(struct e1000_hw *hw, u8 *buffer, u16 length,
u16 offset, u8 *sum)
{
if (hw->mac.ops.mng_host_if_write)
@@ -892,7 +906,7 @@ s32 e1000_mng_write_cmd_header(struct e1000_hw *hw,
* and also checks whether the previous command is completed. It busy waits
* in case of previous command is not completed.
**/
s32 e1000_mng_enable_host_if(struct e1000_hw * hw)
s32 e1000_mng_enable_host_if(struct e1000_hw *hw)
{
if (hw->mac.ops.mng_enable_host_if)
return hw->mac.ops.mng_enable_host_if(hw);
@@ -1,6 +1,6 @@
/******************************************************************************
Copyright (c) 2001-2010, Intel Corporation
Copyright (c) 2001-2012, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -30,7 +30,7 @@
POSSIBILITY OF SUCH DAMAGE.
******************************************************************************/
/*$FreeBSD: src/sys/dev/e1000/e1000_api.h,v 1.3.2.4.2.1 2010/12/21 17:09:25 kensmith Exp $*/
/*$FreeBSD$*/
#ifndef _E1000_API_H_
#define _E1000_API_H_
@@ -49,6 +49,7 @@ extern void e1000_rx_fifo_flush_82575(struct e1000_hw *hw);
extern void e1000_init_function_pointers_vf(struct e1000_hw *hw);
extern void e1000_power_up_fiber_serdes_link(struct e1000_hw *hw);
extern void e1000_shutdown_fiber_serdes_link(struct e1000_hw *hw);
extern void e1000_init_function_pointers_i210(struct e1000_hw *hw);
s32 e1000_set_mac_type(struct e1000_hw *hw);
s32 e1000_setup_init_funcs(struct e1000_hw *hw, bool init_device);
@@ -64,14 +65,13 @@ s32 e1000_check_for_link(struct e1000_hw *hw);
s32 e1000_reset_hw(struct e1000_hw *hw);
s32 e1000_init_hw(struct e1000_hw *hw);
s32 e1000_setup_link(struct e1000_hw *hw);
s32 e1000_get_speed_and_duplex(struct e1000_hw *hw, u16 *speed,
u16 *duplex);
s32 e1000_get_speed_and_duplex(struct e1000_hw *hw, u16 *speed, u16 *duplex);
s32 e1000_disable_pcie_master(struct e1000_hw *hw);
void e1000_config_collision_dist(struct e1000_hw *hw);
void e1000_rar_set(struct e1000_hw *hw, u8 *addr, u32 index);
u32 e1000_hash_mc_addr(struct e1000_hw *hw, u8 *mc_addr);
void e1000_update_mc_addr_list(struct e1000_hw *hw,
u8 *mc_addr_list, u32 mc_addr_count);
void e1000_update_mc_addr_list(struct e1000_hw *hw, u8 *mc_addr_list,
u32 mc_addr_count);
s32 e1000_setup_led(struct e1000_hw *hw);
s32 e1000_cleanup_led(struct e1000_hw *hw);
s32 e1000_check_reset_block(struct e1000_hw *hw);
@@ -85,8 +85,8 @@ s32 e1000_get_cable_length(struct e1000_hw *hw);
s32 e1000_validate_mdi_setting(struct e1000_hw *hw);
s32 e1000_read_phy_reg(struct e1000_hw *hw, u32 offset, u16 *data);
s32 e1000_write_phy_reg(struct e1000_hw *hw, u32 offset, u16 data);
s32 e1000_write_8bit_ctrl_reg(struct e1000_hw *hw, u32 reg,
u32 offset, u8 data);
s32 e1000_write_8bit_ctrl_reg(struct e1000_hw *hw, u32 reg, u32 offset,
u8 data);
s32 e1000_get_phy_info(struct e1000_hw *hw);
void e1000_release_phy(struct e1000_hw *hw);
s32 e1000_acquire_phy(struct e1000_hw *hw);
@@ -96,8 +96,7 @@ s32 e1000_phy_commit(struct e1000_hw *hw);
void e1000_power_up_phy(struct e1000_hw *hw);
void e1000_power_down_phy(struct e1000_hw *hw);
s32 e1000_read_mac_addr(struct e1000_hw *hw);
s32 e1000_read_pba_string(struct e1000_hw *hw, u8 *pba_num,
u32 pba_num_size);
s32 e1000_read_pba_string(struct e1000_hw *hw, u8 *pba_num, u32 pba_num_size);
s32 e1000_read_pba_length(struct e1000_hw *hw, u32 *pba_num_size);
void e1000_reload_nvm(struct e1000_hw *hw);
s32 e1000_update_nvm_checksum(struct e1000_hw *hw);
@@ -105,22 +104,22 @@ s32 e1000_validate_nvm_checksum(struct e1000_hw *hw);
s32 e1000_read_nvm(struct e1000_hw *hw, u16 offset, u16 words, u16 *data);
s32 e1000_read_kmrn_reg(struct e1000_hw *hw, u32 offset, u16 *data);
s32 e1000_write_kmrn_reg(struct e1000_hw *hw, u32 offset, u16 data);
s32 e1000_write_nvm(struct e1000_hw *hw, u16 offset, u16 words,
u16 *data);
s32 e1000_write_nvm(struct e1000_hw *hw, u16 offset, u16 words, u16 *data);
s32 e1000_wait_autoneg(struct e1000_hw *hw);
s32 e1000_set_d3_lplu_state(struct e1000_hw *hw, bool active);
s32 e1000_set_d0_lplu_state(struct e1000_hw *hw, bool active);
bool e1000_check_mng_mode(struct e1000_hw *hw);
bool e1000_enable_tx_pkt_filtering(struct e1000_hw *hw);
s32 e1000_mng_enable_host_if(struct e1000_hw *hw);
s32 e1000_mng_host_if_write(struct e1000_hw *hw,
u8 *buffer, u16 length, u16 offset, u8 *sum);
s32 e1000_mng_host_if_write(struct e1000_hw *hw, u8 *buffer, u16 length,
u16 offset, u8 *sum);
s32 e1000_mng_write_cmd_header(struct e1000_hw *hw,
struct e1000_host_mng_command_header *hdr);
s32 e1000_mng_write_dhcp_info(struct e1000_hw * hw,
u8 *buffer, u16 length);
s32 e1000_mng_write_dhcp_info(struct e1000_hw *hw, u8 *buffer, u16 length);
u32 e1000_translate_register_82542(u32 reg);
/*
* TBI_ACCEPT macro definition:
*
@@ -152,7 +151,8 @@ u32 e1000_translate_register_82542(u32 reg);
/* The carrier extension symbol, as received by the NIC. */
#define CARRIER_EXTENSION 0x0F
#define TBI_ACCEPT(a, status, errors, length, last_byte, min_frame_size, max_frame_size) \
#define TBI_ACCEPT(a, status, errors, length, last_byte, \
min_frame_size, max_frame_size) \
(e1000_tbi_sbp_enabled_82543(a) && \
(((errors) & E1000_RXD_ERR_FRAME_ERR_MASK) == E1000_RXD_ERR_CE) && \
((last_byte) == CARRIER_EXTENSION) && \
@@ -1,6 +1,6 @@
/******************************************************************************
Copyright (c) 2001-2010, Intel Corporation
Copyright (c) 2001-2012, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -30,7 +30,7 @@
POSSIBILITY OF SUCH DAMAGE.
******************************************************************************/
/*$FreeBSD: src/sys/dev/e1000/e1000_defines.h,v 1.4.2.3.2.1 2010/12/21 17:09:25 kensmith Exp $*/
/*$FreeBSD$*/
#ifndef _E1000_DEFINES_H_
#define _E1000_DEFINES_H_
@@ -79,18 +79,18 @@
#define E1000_WUFC_FLX6 0x00400000 /* Flexible Filter 6 Enable */
#define E1000_WUFC_FLX7 0x00800000 /* Flexible Filter 7 Enable */
#define E1000_WUFC_FW_RST 0x80000000 /* Wake on FW Reset Enable */
#define E1000_WUFC_ALL_FILTERS_PHY_4 0x0000F0FF /*Mask for all wakeup filters*/
#define E1000_WUFC_FLX_OFFSET_PHY 12 /* Offset to the Flexible Filters bits */
#define E1000_WUFC_FLX_FILTERS_PHY_4 0x0000F000 /*Mask for 4 flexible filters*/
#define E1000_WUFC_ALL_FILTERS_PHY_6 0x0000F6FF /*Mask for 6 wakeup filters */
#define E1000_WUFC_FLX_FILTERS_PHY_6 0x0000F600 /*Mask for 6 flexible filters*/
#define E1000_WUFC_ALL_FILTERS 0x000F00FF /* Mask for all wakeup filters */
#define E1000_WUFC_ALL_FILTERS_6 0x003F00FF /* Mask for all 6 wakeup filters*/
#define E1000_WUFC_ALL_FILTERS_8 0x00FF00FF /* Mask for all 8 wakeup filters*/
#define E1000_WUFC_FLX_OFFSET 16 /* Offset to the Flexible Filters bits */
#define E1000_WUFC_FLX_FILTERS 0x000F0000 /*Mask for the 4 flexible filters */
#define E1000_WUFC_FLX_FILTERS_6 0x003F0000 /* Mask for 6 flexible filters */
#define E1000_WUFC_FLX_FILTERS_8 0x00FF0000 /* Mask for 8 flexible filters */
#define E1000_WUFC_ALL_FILTERS_PHY_4 0x0000F0FF /* wakeup filters mask */
#define E1000_WUFC_FLX_OFFSET_PHY 12 /* Flexible Filters bits offset */
#define E1000_WUFC_FLX_FILTERS_PHY_4 0x0000F000 /* 4 flexible filters mask */
#define E1000_WUFC_ALL_FILTERS_PHY_6 0x0000F6FF /* 6 wakeup filters mask */
#define E1000_WUFC_FLX_FILTERS_PHY_6 0x0000F600 /* 6 flexible filters mask */
#define E1000_WUFC_ALL_FILTERS 0x000F00FF /* all wakeup filters mask */
#define E1000_WUFC_ALL_FILTERS_6 0x003F00FF /* Mask all 6 wu filters */
#define E1000_WUFC_ALL_FILTERS_8 0x00FF00FF /* Mask all 8 wu filters */
#define E1000_WUFC_FLX_OFFSET 16 /* Flexible Filters bits offset */
#define E1000_WUFC_FLX_FILTERS 0x000F0000 /* 4 flexible filters mask */
#define E1000_WUFC_FLX_FILTERS_6 0x003F0000 /* 6 flexible filters mask */
#define E1000_WUFC_FLX_FILTERS_8 0x00FF0000 /* 8 flexible filters mask */
/*
* For 82576 to utilize Extended filter masks in addition to
* existing (filter) masks
@@ -158,11 +158,11 @@
#define E1000_CTRL_EXT_GPI2_EN 0x00000004 /* Maps SDP6 to GPI2 */
#define E1000_CTRL_EXT_GPI3_EN 0x00000008 /* Maps SDP7 to GPI3 */
/* Reserved (bits 4,5) in >= 82575 */
#define E1000_CTRL_EXT_SDP4_DATA 0x00000010 /* Value of SW Definable Pin 4 */
#define E1000_CTRL_EXT_SDP5_DATA 0x00000020 /* Value of SW Definable Pin 5 */
#define E1000_CTRL_EXT_SDP4_DATA 0x00000010 /* SW Definable Pin 4 data */
#define E1000_CTRL_EXT_SDP5_DATA 0x00000020 /* SW Definable Pin 5 data */
#define E1000_CTRL_EXT_PHY_INT E1000_CTRL_EXT_SDP5_DATA
#define E1000_CTRL_EXT_SDP6_DATA 0x00000040 /* Value of SW Definable Pin 6 */
#define E1000_CTRL_EXT_SDP3_DATA 0x00000080 /* Value of SW Definable Pin 3 */
#define E1000_CTRL_EXT_SDP6_DATA 0x00000040 /* SW Definable Pin 6 data */
#define E1000_CTRL_EXT_SDP3_DATA 0x00000080 /* SW Definable Pin 3 data */
/* SDP 4/5 (bits 8,9) are reserved in >= 82575 */
#define E1000_CTRL_EXT_SDP4_DIR 0x00000100 /* Direction of SDP4 0=in 1=out */
#define E1000_CTRL_EXT_SDP5_DIR 0x00000200 /* Direction of SDP5 0=in 1=out */
@@ -175,8 +175,10 @@
#define E1000_CTRL_EXT_PFRSTD 0x00004000
#define E1000_CTRL_EXT_SPD_BYPS 0x00008000 /* Speed Select Bypass */
#define E1000_CTRL_EXT_RO_DIS 0x00020000 /* Relaxed Ordering disable */
#define E1000_CTRL_EXT_DMA_DYN_CLK_EN 0x00080000 /* DMA Dynamic Clock Gating */
#define E1000_CTRL_EXT_DMA_DYN_CLK_EN 0x00080000 /* DMA Dynamic Clk Gating */
#define E1000_CTRL_EXT_LINK_MODE_MASK 0x00C00000
/* Offset of the link mode field in Ctrl Ext register */
#define E1000_CTRL_EXT_LINK_MODE_OFFSET 22
#define E1000_CTRL_EXT_LINK_MODE_82580_MASK 0x01C00000 /*82580 bit 24:22*/
#define E1000_CTRL_EXT_LINK_MODE_1000BASE_KX 0x00400000
#define E1000_CTRL_EXT_LINK_MODE_GMII 0x00000000
@@ -193,13 +195,13 @@
#define E1000_CTRL_EXT_WR_WMARK_384 0x02000000
#define E1000_CTRL_EXT_WR_WMARK_448 0x03000000
#define E1000_CTRL_EXT_CANC 0x04000000 /* Int delay cancellation */
#define E1000_CTRL_EXT_DRV_LOAD 0x10000000 /* Driver loaded bit for FW */
#define E1000_CTRL_EXT_DRV_LOAD 0x10000000 /* Drv loaded bit for FW */
/* IAME enable bit (27) was removed in >= 82575 */
#define E1000_CTRL_EXT_IAME 0x08000000 /* Int acknowledge Auto-mask */
#define E1000_CRTL_EXT_PB_PAREN 0x01000000 /* packet buffer parity error
* detection enabled */
#define E1000_CTRL_EXT_DF_PAREN 0x02000000 /* descriptor FIFO parity
* error detection enable */
#define E1000_CTRL_EXT_IAME 0x08000000 /* Int ACK Auto-mask */
/* packet buffer parity error detection enabled */
#define E1000_CRTL_EXT_PB_PAREN 0x01000000
/* descriptor FIFO parity error detection enable */
#define E1000_CTRL_EXT_DF_PAREN 0x02000000
#define E1000_CTRL_EXT_GHOST_PAREN 0x40000000
#define E1000_CTRL_EXT_PBA_CLR 0x80000000 /* PBA Clear */
#define E1000_CTRL_EXT_LSECCK 0x00001000
@@ -214,6 +216,8 @@
#define E1000_I2CCMD_READY 0x20000000
#define E1000_I2CCMD_INTERRUPT_ENA 0x40000000
#define E1000_I2CCMD_ERROR 0x80000000
#define E1000_I2CCMD_SFP_DATA_ADDR(a) (0x0000 + (a))
#define E1000_I2CCMD_SFP_DIAG_ADDR(a) (0x0100 + (a))
#define E1000_MAX_SGMII_PHY_REG_ADDR 255
#define E1000_I2CCMD_PHY_TIMEOUT 200
#define E1000_IVAR_VALID 0x80
@@ -319,8 +323,8 @@
#define E1000_MANC_EN_MNG2HOST 0x00200000
/* Enable IP address filtering */
#define E1000_MANC_EN_IP_ADDR_FILTER 0x00400000
#define E1000_MANC_EN_XSUM_FILTER 0x00800000 /* Enable checksum filtering */
#define E1000_MANC_BR_EN 0x01000000 /* Enable broadcast filtering */
#define E1000_MANC_EN_XSUM_FILTER 0x00800000 /* Ena checksum filtering */
#define E1000_MANC_BR_EN 0x01000000 /* Ena broadcast filtering */
#define E1000_MANC_SMB_REQ 0x01000000 /* SMBus Request */
#define E1000_MANC_SMB_GNT 0x02000000 /* SMBus Grant */
#define E1000_MANC_SMB_CLK_IN 0x04000000 /* SMBus Clock In */
@@ -328,7 +332,7 @@
#define E1000_MANC_SMB_DATA_OUT 0x10000000 /* SMBus Data Out */
#define E1000_MANC_SMB_CLK_OUT 0x20000000 /* SMBus Clock Out */
#define E1000_MANC_MPROXYE 0x40000000 /* Mngment Proxy Enable */
#define E1000_MANC_EN_BMC2OS 0x10000000 /* OS2BMC is enabled or not */
#define E1000_MANC_EN_BMC2OS 0x10000000 /* OS2BMC is enabld or not */
#define E1000_MANC_SMB_DATA_OUT_SHIFT 28 /* SMBus Data Out Shift */
#define E1000_MANC_SMB_CLK_OUT_SHIFT 29 /* SMBus Clock Out Shift */
@@ -437,12 +441,12 @@
#define E1000_CTRL_FRCSPD 0x00000800 /* Force Speed */
#define E1000_CTRL_FRCDPX 0x00001000 /* Force Duplex */
#define E1000_CTRL_D_UD_EN 0x00002000 /* Dock/Undock enable */
#define E1000_CTRL_D_UD_POLARITY 0x00004000 /* Defined polarity of Dock/Undock
* indication in SDP[0] */
#define E1000_CTRL_FORCE_PHY_RESET 0x00008000 /* Reset both PHY ports, through
* PHYRST_N pin */
#define E1000_CTRL_EXT_LINK_EN 0x00010000 /* enable link status from external
* LINK_0 and LINK_1 pins */
/* Defined polarity of Dock/Undock indication in SDP[0] */
#define E1000_CTRL_D_UD_POLARITY 0x00004000
/* Reset both PHY ports, through PHYRST_N pin */
#define E1000_CTRL_FORCE_PHY_RESET 0x00008000
/* enable link status from external LINK_0 and LINK_1 pins */
#define E1000_CTRL_EXT_LINK_EN 0x00010000
#define E1000_CTRL_LANPHYPC_OVERRIDE 0x00010000 /* SW control of LANPHYPC */
#define E1000_CTRL_LANPHYPC_VALUE 0x00020000 /* SW value of LANPHYPC */
#define E1000_CTRL_SWDPIN0 0x00040000 /* SWDPIN 0 value */
@@ -510,7 +514,7 @@
#define E1000_PCS_LSTS_AN_ERROR_RWS 0x100000
/* Device Status */
#define E1000_STATUS_FD 0x00000001 /* Full duplex.0=half,1=full */
#define E1000_STATUS_FD 0x00000001 /* Duplex 0=half 1=full */
#define E1000_STATUS_LU 0x00000002 /* Link up.0=no,1=link */
#define E1000_STATUS_FUNC_MASK 0x0000000C /* PCI Function Mask */
#define E1000_STATUS_FUNC_SHIFT 2
@@ -522,33 +526,33 @@
#define E1000_STATUS_SPEED_10 0x00000000 /* Speed 10Mb/s */
#define E1000_STATUS_SPEED_100 0x00000040 /* Speed 100Mb/s */
#define E1000_STATUS_SPEED_1000 0x00000080 /* Speed 1000Mb/s */
#define E1000_STATUS_LAN_INIT_DONE 0x00000200 /* Lan Init Completion by NVM */
#define E1000_STATUS_LAN_INIT_DONE 0x00000200 /* Lan Init Compltn by NVM */
#define E1000_STATUS_ASDV 0x00000300 /* Auto speed detect value */
#define E1000_STATUS_PHYRA 0x00000400 /* PHY Reset Asserted */
#define E1000_STATUS_DOCK_CI 0x00000800 /* Change in Dock/Undock state.
* Clear on write '0'. */
/* Change in Dock/Undock state clear on write '0'. */
#define E1000_STATUS_DOCK_CI 0x00000800
#define E1000_STATUS_GIO_MASTER_ENABLE 0x00080000 /* Master request status */
#define E1000_STATUS_MTXCKOK 0x00000400 /* MTX clock running OK */
#define E1000_STATUS_PCI66 0x00000800 /* In 66Mhz slot */
#define E1000_STATUS_BUS64 0x00001000 /* In 64 bit slot */
#define E1000_STATUS_PCIX_MODE 0x00002000 /* PCI-X mode */
#define E1000_STATUS_PCIX_SPEED 0x0000C000 /* PCI-X bus speed */
#define E1000_STATUS_BMC_SKU_0 0x00100000 /* BMC USB redirect disabled */
#define E1000_STATUS_BMC_SKU_0 0x00100000 /* BMC USB redirect disbld */
#define E1000_STATUS_BMC_SKU_1 0x00200000 /* BMC SRAM disabled */
#define E1000_STATUS_BMC_SKU_2 0x00400000 /* BMC SDRAM disabled */
#define E1000_STATUS_BMC_CRYPTO 0x00800000 /* BMC crypto disabled */
#define E1000_STATUS_BMC_LITE 0x01000000 /* BMC external code execution
* disabled */
/* BMC external code execution disabled */
#define E1000_STATUS_BMC_LITE 0x01000000
#define E1000_STATUS_RGMII_ENABLE 0x02000000 /* RGMII disabled */
#define E1000_STATUS_FUSE_8 0x04000000
#define E1000_STATUS_FUSE_9 0x08000000
#define E1000_STATUS_SERDES0_DIS 0x10000000 /* SERDES disabled on port 0 */
#define E1000_STATUS_SERDES1_DIS 0x20000000 /* SERDES disabled on port 1 */
#define E1000_STATUS_SERDES0_DIS 0x10000000 /* SERDES disbld on port 0 */
#define E1000_STATUS_SERDES1_DIS 0x20000000 /* SERDES disbld on port 1 */
/* Constants used to interpret the masked PCI-X bus speed. */
#define E1000_STATUS_PCIX_SPEED_66 0x00000000 /* PCI-X bus speed 50-66 MHz */
#define E1000_STATUS_PCIX_SPEED_100 0x00004000 /* PCI-X bus speed 66-100 MHz */
#define E1000_STATUS_PCIX_SPEED_133 0x00008000 /*PCI-X bus speed 100-133 MHz*/
#define E1000_STATUS_PCIX_SPEED_66 0x00000000 /* PCI-X bus spd 50-66MHz */
#define E1000_STATUS_PCIX_SPEED_100 0x00004000 /* PCI-X bus spd 66-100MHz */
#define E1000_STATUS_PCIX_SPEED_133 0x00008000 /* PCI-X bus spd 100-133MHz*/
#define SPEED_10 10
#define SPEED_100 100
@@ -566,15 +570,16 @@
#define ADVERTISE_1000_FULL 0x0020
/* 1000/H is not supported, nor spec-compliant. */
#define E1000_ALL_SPEED_DUPLEX (ADVERTISE_10_HALF | ADVERTISE_10_FULL | \
ADVERTISE_100_HALF | ADVERTISE_100_FULL | \
ADVERTISE_1000_FULL)
#define E1000_ALL_NOT_GIG (ADVERTISE_10_HALF | ADVERTISE_10_FULL | \
ADVERTISE_100_HALF | ADVERTISE_100_FULL)
#define E1000_ALL_SPEED_DUPLEX ( \
ADVERTISE_10_HALF | ADVERTISE_10_FULL | ADVERTISE_100_HALF | \
ADVERTISE_100_FULL | ADVERTISE_1000_FULL)
#define E1000_ALL_NOT_GIG ( \
ADVERTISE_10_HALF | ADVERTISE_10_FULL | ADVERTISE_100_HALF | \
ADVERTISE_100_FULL)
#define E1000_ALL_100_SPEED (ADVERTISE_100_HALF | ADVERTISE_100_FULL)
#define E1000_ALL_10_SPEED (ADVERTISE_10_HALF | ADVERTISE_10_FULL)
#define E1000_ALL_FULL_DUPLEX (ADVERTISE_10_FULL | ADVERTISE_100_FULL | \
ADVERTISE_1000_FULL)
#define E1000_ALL_FULL_DUPLEX ( \
ADVERTISE_10_FULL | ADVERTISE_100_FULL | ADVERTISE_1000_FULL)
#define E1000_ALL_HALF_DUPLEX (ADVERTISE_10_HALF | ADVERTISE_100_HALF)
#define AUTONEG_ADVERTISE_SPEED_DEFAULT E1000_ALL_SPEED_DUPLEX
@@ -634,7 +639,7 @@
#define E1000_TXD_CMD_IC 0x04000000 /* Insert Checksum */
#define E1000_TXD_CMD_RS 0x08000000 /* Report Status */
#define E1000_TXD_CMD_RPS 0x10000000 /* Report Packet Sent */
#define E1000_TXD_CMD_DEXT 0x20000000 /* Descriptor extension (0 = legacy) */
#define E1000_TXD_CMD_DEXT 0x20000000 /* Desc extension (0 = legacy) */
#define E1000_TXD_CMD_VLE 0x40000000 /* Add VLAN tag */
#define E1000_TXD_CMD_IDE 0x80000000 /* Enable Tidv register */
#define E1000_TXD_STAT_DD 0x00000001 /* Descriptor Done */
@@ -765,6 +770,8 @@
#define E1000_PBA_48K 0x0030 /* 48KB */
#define E1000_PBA_64K 0x0040 /* 64KB */
#define E1000_PBA_RXA_MASK 0xFFFF;
#define E1000_PBS_16K E1000_PBA_16K
#define E1000_PBS_24K E1000_PBA_24K
@@ -803,8 +810,8 @@
#define E1000_ICR_MNG 0x00040000 /* Manageability event */
#define E1000_ICR_DOCK 0x00080000 /* Dock/Undock */
#define E1000_ICR_DRSTA 0x40000000 /* Device Reset Asserted */
#define E1000_ICR_INT_ASSERTED 0x80000000 /* If this bit asserted, the driver
* should claim the interrupt */
/* If this bit asserted, the driver should claim the interrupt */
#define E1000_ICR_INT_ASSERTED 0x80000000
#define E1000_ICR_RXD_FIFO_PAR0 0x00100000 /* Q0 Rx desc FIFO parity error */
#define E1000_ICR_TXD_FIFO_PAR0 0x00200000 /* Q0 Tx desc FIFO parity error */
#define E1000_ICR_HOST_ARB_PAR 0x00400000 /* host arb read buffer parity err */
@@ -812,10 +819,10 @@
#define E1000_ICR_RXD_FIFO_PAR1 0x01000000 /* Q1 Rx desc FIFO parity error */
#define E1000_ICR_TXD_FIFO_PAR1 0x02000000 /* Q1 Tx desc FIFO parity error */
#define E1000_ICR_ALL_PARITY 0x03F00000 /* all parity error bits */
#define E1000_ICR_DSW 0x00000020 /* FW changed the status of DISSW
* bit in the FWSM */
#define E1000_ICR_PHYINT 0x00001000 /* LAN connected device generates
* an interrupt */
/* FW changed the status of DISSW bit in the FWSM */
#define E1000_ICR_DSW 0x00000020
/* LAN connected device generates an interrupt */
#define E1000_ICR_PHYINT 0x00001000
#define E1000_ICR_DOUTSYNC 0x10000000 /* NIC DMA out of sync */
#define E1000_ICR_EPRST 0x00100000 /* ME hardware reset occurs */
#define E1000_ICR_RXQ0 0x00100000 /* Rx Queue 0 Interrupt */
@@ -827,6 +834,10 @@
#define E1000_ICR_THS 0x00800000 /* ICR.THS: Thermal Sensor Event*/
#define E1000_ICR_MDDET 0x10000000 /* Malicious Driver Detect */
#define E1000_ITR_MASK 0x000FFFFF /* ITR value bitfield */
#define E1000_ITR_MULT 256 /* ITR mulitplier in nsec */
/* PBA ECC Register */
#define E1000_PBA_ECC_COUNTER_MASK 0xFFF00000 /* ECC counter mask */
#define E1000_PBA_ECC_COUNTER_SHIFT 20 /* ECC counter shift value */
@@ -898,18 +909,18 @@
#define E1000_IMS_MNG E1000_ICR_MNG /* Manageability event */
#define E1000_IMS_DOCK E1000_ICR_DOCK /* Dock/Undock */
#define E1000_IMS_DRSTA E1000_ICR_DRSTA /* Device Reset Asserted */
#define E1000_IMS_RXD_FIFO_PAR0 E1000_ICR_RXD_FIFO_PAR0 /* Q0 Rx desc FIFO
* parity error */
#define E1000_IMS_TXD_FIFO_PAR0 E1000_ICR_TXD_FIFO_PAR0 /* Q0 Tx desc FIFO
* parity error */
#define E1000_IMS_HOST_ARB_PAR E1000_ICR_HOST_ARB_PAR /* host arb read buffer
* parity error */
#define E1000_IMS_PB_PAR E1000_ICR_PB_PAR /* packet buffer parity
* error */
#define E1000_IMS_RXD_FIFO_PAR1 E1000_ICR_RXD_FIFO_PAR1 /* Q1 Rx desc FIFO
* parity error */
#define E1000_IMS_TXD_FIFO_PAR1 E1000_ICR_TXD_FIFO_PAR1 /* Q1 Tx desc FIFO
* parity error */
/* Q0 Rx desc FIFO parity error */
#define E1000_IMS_RXD_FIFO_PAR0 E1000_ICR_RXD_FIFO_PAR0
/* Q0 Tx desc FIFO parity error */
#define E1000_IMS_TXD_FIFO_PAR0 E1000_ICR_TXD_FIFO_PAR0
/* host arb read buffer parity error */
#define E1000_IMS_HOST_ARB_PAR E1000_ICR_HOST_ARB_PAR
/* packet buffer parity error */
#define E1000_IMS_PB_PAR E1000_ICR_PB_PAR
/* Q1 Rx desc FIFO parity error */
#define E1000_IMS_RXD_FIFO_PAR1 E1000_ICR_RXD_FIFO_PAR1
/* Q1 Tx desc FIFO parity error */
#define E1000_IMS_TXD_FIFO_PAR1 E1000_ICR_TXD_FIFO_PAR1
#define E1000_IMS_DSW E1000_ICR_DSW
#define E1000_IMS_PHYINT E1000_ICR_PHYINT
#define E1000_IMS_DOUTSYNC E1000_ICR_DOUTSYNC /* NIC DMA out of sync */
@@ -955,18 +966,18 @@
#define E1000_ICS_MNG E1000_ICR_MNG /* Manageability event */
#define E1000_ICS_DOCK E1000_ICR_DOCK /* Dock/Undock */
#define E1000_ICS_DRSTA E1000_ICR_DRSTA /* Device Reset Aserted */
#define E1000_ICS_RXD_FIFO_PAR0 E1000_ICR_RXD_FIFO_PAR0 /* Q0 Rx desc FIFO
* parity error */
#define E1000_ICS_TXD_FIFO_PAR0 E1000_ICR_TXD_FIFO_PAR0 /* Q0 Tx desc FIFO
* parity error */
#define E1000_ICS_HOST_ARB_PAR E1000_ICR_HOST_ARB_PAR /* host arb read buffer
* parity error */
#define E1000_ICS_PB_PAR E1000_ICR_PB_PAR /* packet buffer parity
* error */
#define E1000_ICS_RXD_FIFO_PAR1 E1000_ICR_RXD_FIFO_PAR1 /* Q1 Rx desc FIFO
* parity error */
#define E1000_ICS_TXD_FIFO_PAR1 E1000_ICR_TXD_FIFO_PAR1 /* Q1 Tx desc FIFO
* parity error */
/* Q0 Rx desc FIFO parity error */
#define E1000_ICS_RXD_FIFO_PAR0 E1000_ICR_RXD_FIFO_PAR0
/* Q0 Tx desc FIFO parity error */
#define E1000_ICS_TXD_FIFO_PAR0 E1000_ICR_TXD_FIFO_PAR0
/* host arb read buffer parity error */
#define E1000_ICS_HOST_ARB_PAR E1000_ICR_HOST_ARB_PAR
/* packet buffer parity error */
#define E1000_ICS_PB_PAR E1000_ICR_PB_PAR
/* Q1 Rx desc FIFO parity error */
#define E1000_ICS_RXD_FIFO_PAR1 E1000_ICR_RXD_FIFO_PAR1
/* Q1 Tx desc FIFO parity error */
#define E1000_ICS_TXD_FIFO_PAR1 E1000_ICR_TXD_FIFO_PAR1
#define E1000_ICS_DSW E1000_ICR_DSW
#define E1000_ICS_DOUTSYNC E1000_ICR_DOUTSYNC /* NIC DMA out of sync */
#define E1000_ICS_PHYINT E1000_ICR_PHYINT
@@ -1043,6 +1054,8 @@
#define E1000_ERR_INVALID_ARGUMENT 16
#define E1000_ERR_NO_SPACE 17
#define E1000_ERR_NVM_PBA_SECTION 18
#define E1000_ERR_I2C 19
#define E1000_ERR_INVM_VALUE_NOT_FOUND 20
/* Loop limit on how long we wait for auto-negotiation to complete */
#define FIBER_LINK_UP_LIMIT 50
@@ -1145,16 +1158,16 @@
#define E1000_THSTAT_MID_EVENT 0x00200000 /* Mid thermal threshold */
#define E1000_THSTAT_HIGH_EVENT 0x00002000 /* High thermal threshold */
#define E1000_THSTAT_PWR_DOWN 0x00000001 /* Power Down Event */
#define E1000_THSTAT_LINK_THROTTLE 0x00000002 /* Link Speed Throttle Event */
#define E1000_THSTAT_LINK_THROTTLE 0x00000002 /* Link Spd Throttle Event */
/* Powerville EEE defines */
#define E1000_IPCNFG_EEE_1G_AN 0x00000008 /* IPCNFG EEE Enable 1G AN */
#define E1000_IPCNFG_EEE_100M_AN 0x00000004 /* IPCNFG EEE Enable 100M AN */
/* I350 EEE defines */
#define E1000_IPCNFG_EEE_1G_AN 0x00000008 /* IPCNFG EEE Ena 1G AN */
#define E1000_IPCNFG_EEE_100M_AN 0x00000004 /* IPCNFG EEE Ena 100M AN */
#define E1000_EEER_TX_LPI_EN 0x00010000 /* EEER Tx LPI Enable */
#define E1000_EEER_RX_LPI_EN 0x00020000 /* EEER Rx LPI Enable */
#define E1000_EEER_LPI_FC 0x00040000 /* EEER Enable on Flow Control*/
#define E1000_EEER_LPI_FC 0x00040000 /* EEER Ena on Flow Cntrl */
/* EEE status */
#define E1000_EEER_EEE_NEG 0x20000000 /* EEE capability negotiated */
#define E1000_EEER_EEE_NEG 0x20000000 /* EEE capability nego */
#define E1000_EEER_RX_LPI_STATUS 0x40000000 /* Rx in LPI state */
#define E1000_EEER_TX_LPI_STATUS 0x80000000 /* Tx in LPI state */
@@ -1177,6 +1190,16 @@
E1000_GCR_TXDSCW_NO_SNOOP | \
E1000_GCR_TXDSCR_NO_SNOOP)
/* mPHY address control and data registers */
#define E1000_MPHY_ADDR_CTL 0x0024 /* Address Control Reg */
#define E1000_MPHY_ADDR_CTL_OFFSET_MASK 0xFFFF0000
#define E1000_MPHY_DATA 0x0E10 /* Data Register */
/* AFE CSR Offset for PCS CLK */
#define E1000_MPHY_PCS_CLK_REG_OFFSET 0x0004
/* Override for near end digital loopback. */
#define E1000_MPHY_PCS_CLK_REG_DIGINELBEN 0x10
/* PHY Control Register */
#define MII_CR_SPEED_SELECT_MSB 0x0040 /* bits 6,13: 10=1000, 01=100, 00=10 */
#define MII_CR_COLL_TEST_ENABLE 0x0080 /* Collision test enable */
@@ -1223,34 +1246,34 @@
/* Link Partner Ability Register (Base Page) */
#define NWAY_LPAR_SELECTOR_FIELD 0x0000 /* LP protocol selector field */
#define NWAY_LPAR_10T_HD_CAPS 0x0020 /* LP is 10T Half Duplex Capable */
#define NWAY_LPAR_10T_FD_CAPS 0x0040 /* LP is 10T Full Duplex Capable */
#define NWAY_LPAR_100TX_HD_CAPS 0x0080 /* LP is 100TX Half Duplex Capable */
#define NWAY_LPAR_100TX_FD_CAPS 0x0100 /* LP is 100TX Full Duplex Capable */
#define NWAY_LPAR_10T_HD_CAPS 0x0020 /* LP 10T Half Dplx Capable */
#define NWAY_LPAR_10T_FD_CAPS 0x0040 /* LP 10T Full Dplx Capable */
#define NWAY_LPAR_100TX_HD_CAPS 0x0080 /* LP 100TX Half Dplx Capable */
#define NWAY_LPAR_100TX_FD_CAPS 0x0100 /* LP 100TX Full Dplx Capable */
#define NWAY_LPAR_100T4_CAPS 0x0200 /* LP is 100T4 Capable */
#define NWAY_LPAR_PAUSE 0x0400 /* LP Pause operation desired */
#define NWAY_LPAR_ASM_DIR 0x0800 /* LP Asymmetric Pause Direction bit */
#define NWAY_LPAR_REMOTE_FAULT 0x2000 /* LP has detected Remote Fault */
#define NWAY_LPAR_ACKNOWLEDGE 0x4000 /* LP has rx'd link code word */
#define NWAY_LPAR_ASM_DIR 0x0800 /* LP Asym Pause Direction bit */
#define NWAY_LPAR_REMOTE_FAULT 0x2000 /* LP detected Remote Fault */
#define NWAY_LPAR_ACKNOWLEDGE 0x4000 /* LP rx'd link code word */
#define NWAY_LPAR_NEXT_PAGE 0x8000 /* Next Page ability supported */
/* Autoneg Expansion Register */
#define NWAY_ER_LP_NWAY_CAPS 0x0001 /* LP has Auto Neg Capability */
#define NWAY_ER_PAGE_RXD 0x0002 /* LP is 10T Half Duplex Capable */
#define NWAY_ER_NEXT_PAGE_CAPS 0x0004 /* LP is 10T Full Duplex Capable */
#define NWAY_ER_LP_NEXT_PAGE_CAPS 0x0008 /* LP is 100TX Half Duplex Capable */
#define NWAY_ER_PAR_DETECT_FAULT 0x0010 /* LP is 100TX Full Duplex Capable */
#define NWAY_ER_PAGE_RXD 0x0002 /* LP 10T Half Dplx Capable */
#define NWAY_ER_NEXT_PAGE_CAPS 0x0004 /* LP 10T Full Dplx Capable */
#define NWAY_ER_LP_NEXT_PAGE_CAPS 0x0008 /* LP 100TX Half Dplx Capable */
#define NWAY_ER_PAR_DETECT_FAULT 0x0010 /* LP 100TX Full Dplx Capable */
/* 1000BASE-T Control Register */
#define CR_1000T_ASYM_PAUSE 0x0080 /* Advertise asymmetric pause bit */
#define CR_1000T_HD_CAPS 0x0100 /* Advertise 1000T HD capability */
#define CR_1000T_FD_CAPS 0x0200 /* Advertise 1000T FD capability */
#define CR_1000T_REPEATER_DTE 0x0400 /* 1=Repeater/switch device port */
/* 0=DTE device */
#define CR_1000T_MS_VALUE 0x0800 /* 1=Configure PHY as Master */
/* 0=Configure PHY as Slave */
#define CR_1000T_MS_ENABLE 0x1000 /* 1=Master/Slave manual config value */
/* 0=Automatic Master/Slave config */
/* 1=Repeater/switch device port 0=DTE device */
#define CR_1000T_REPEATER_DTE 0x0400
/* 1=Configure PHY as Master 0=Configure PHY as Slave */
#define CR_1000T_MS_VALUE 0x0800
/* 1=Master/Slave manual config value 0=Automatic Master/Slave config */
#define CR_1000T_MS_ENABLE 0x1000
#define CR_1000T_TEST_MODE_NORMAL 0x0000 /* Normal Operation */
#define CR_1000T_TEST_MODE_1 0x2000 /* Transmit Waveform test */
#define CR_1000T_TEST_MODE_2 0x4000 /* Master Transmit Jitter test */
@@ -1258,13 +1281,13 @@
#define CR_1000T_TEST_MODE_4 0x8000 /* Transmitter Distortion test */
/* 1000BASE-T Status Register */
#define SR_1000T_IDLE_ERROR_CNT 0x00FF /* Num idle errors since last read */
#define SR_1000T_ASYM_PAUSE_DIR 0x0100 /* LP asymmetric pause direction bit */
#define SR_1000T_IDLE_ERROR_CNT 0x00FF /* Num idle err since last rd */
#define SR_1000T_ASYM_PAUSE_DIR 0x0100 /* LP asym pause direction bit */
#define SR_1000T_LP_HD_CAPS 0x0400 /* LP is 1000T HD capable */
#define SR_1000T_LP_FD_CAPS 0x0800 /* LP is 1000T FD capable */
#define SR_1000T_REMOTE_RX_STATUS 0x1000 /* Remote receiver OK */
#define SR_1000T_LOCAL_RX_STATUS 0x2000 /* Local receiver OK */
#define SR_1000T_MS_CONFIG_RES 0x4000 /* 1=Local Tx is Master, 0=Slave */
#define SR_1000T_MS_CONFIG_RES 0x4000 /* 1=Local Tx Master, 0=Slave */
#define SR_1000T_MS_CONFIG_FAULT 0x8000 /* Master/Slave config fault */
#define SR_1000T_PHY_EXCESSIVE_IDLE_ERR_COUNT 5
@@ -1299,6 +1322,10 @@
#define E1000_EECD_GNT 0x00000080 /* NVM Access Grant */
#define E1000_EECD_PRES 0x00000100 /* NVM Present */
#define E1000_EECD_SIZE 0x00000200 /* NVM Size (0=64 word 1=256 word) */
#define E1000_EECD_BLOCKED 0x00008000 /* Bit banging access blocked flag */
#define E1000_EECD_ABORT 0x00010000 /* NVM operation aborted flag */
#define E1000_EECD_TIMEOUT 0x00020000 /* NVM read operation timeout flag */
#define E1000_EECD_ERROR_CLR 0x00040000 /* NVM error status clear bit */
/* NVM Addressing bits based on type 0=small, 1=large */
#define E1000_EECD_ADDR_BITS 0x00000400
#define E1000_EECD_TYPE 0x00002000 /* NVM Type (1-SPI, 0-Microwire) */
@@ -1312,11 +1339,21 @@
#define E1000_EECD_SELSHAD 0x00020000 /* Select Shadow RAM */
#define E1000_EECD_INITSRAM 0x00040000 /* Initialize Shadow RAM */
#define E1000_EECD_FLUPD 0x00080000 /* Update FLASH */
#define E1000_EECD_AUPDEN 0x00100000 /* Enable Autonomous FLASH update */
#define E1000_EECD_AUPDEN 0x00100000 /* Ena Auto FLASH update */
#define E1000_EECD_SHADV 0x00200000 /* Shadow RAM Data Valid */
#define E1000_EECD_SEC1VAL 0x00400000 /* Sector One Valid */
#define E1000_EECD_SECVAL_SHIFT 22
#define E1000_EECD_SEC1VAL_VALID_MASK (E1000_EECD_AUTO_RD | E1000_EECD_PRES)
#define E1000_EECD_FLUPD_I210 0x00800000 /* Update FLASH */
#define E1000_EECD_FLUDONE_I210 0x04000000 /* Update FLASH done */
#define E1000_EECD_FLASH_DETECTED_I210 0x00080000 /* FLASH detected */
#define E1000_FLUDONE_ATTEMPTS 20000
#define E1000_EERD_EEWR_MAX_COUNT 512 /* buffered EEPROM words rw */
#define E1000_I210_FIFO_SEL_RX 0x00
#define E1000_I210_FIFO_SEL_TX_QAV(_i) (0x02 + (_i))
#define E1000_I210_FIFO_SEL_TX_LEGACY E1000_I210_FIFO_SEL_TX_QAV(0)
#define E1000_I210_FIFO_SEL_BMC2OS_TX 0x06
#define E1000_I210_FIFO_SEL_BMC2OS_RX 0x01
#define E1000_NVM_SWDPIN0 0x0001 /* SWDPIN 0 NVM Value */
#define E1000_NVM_LED_LOGIC 0x0020 /* Led Logic Word */
@@ -1334,6 +1371,20 @@
#define NVM_VERSION 0x0005
#define NVM_SERDES_AMPLITUDE 0x0006 /* SERDES output amplitude */
#define NVM_PHY_CLASS_WORD 0x0007
#define NVM_ETRACK_WORD 0x0042
#define NVM_COMB_VER_OFF 0x0083
#define NVM_COMB_VER_PTR 0x003d
#define NVM_MAC_ADDR 0x0000
#define NVM_SUB_DEV_ID 0x000B
#define NVM_SUB_VEN_ID 0x000C
#define NVM_DEV_ID 0x000D
#define NVM_VEN_ID 0x000E
#define NVM_INIT_CTRL_2 0x000F
#define NVM_INIT_CTRL_4 0x0013
#define NVM_LED_1_CFG 0x001C
#define NVM_LED_0_2_CFG 0x001F
#define NVM_INIT_CONTROL1_REG 0x000A
#define NVM_INIT_CONTROL2_REG 0x000F
#define NVM_SWDEF_PINS_CTRL_PORT_1 0x0010
@@ -1353,11 +1404,16 @@
#define E1000_NVM_CFG_DONE_PORT_2 0x100000 /* ...for third port */
#define E1000_NVM_CFG_DONE_PORT_3 0x200000 /* ...for fourth port */
#define NVM_82580_LAN_FUNC_OFFSET(a) (a ? (0x40 + (0x40 * a)) : 0)
#define NVM_82580_LAN_FUNC_OFFSET(a) ((a) ? (0x40 + (0x40 * (a))) : 0)
/* Mask bits for fields in Word 0x24 of the NVM */
#define NVM_WORD24_COM_MDIO 0x0008 /* MDIO interface shared */
#define NVM_WORD24_EXT_MDIO 0x0004 /* MDIO accesses routed external */
#define NVM_WORD24_EXT_MDIO 0x0004 /* MDIO accesses routed extrnl */
/* Offset of Link Mode bits for 82575/82576 */
#define NVM_WORD24_LNK_MODE_OFFSET 8
/* Offset of Link Mode bits for 82580 up */
#define NVM_WORD24_82580_LNK_MODE_OFFSET 4
/* Mask bits for fields in Word 0x0f of the NVM */
#define NVM_WORD0F_PAUSE_MASK 0x3000
@@ -1493,20 +1549,21 @@
#define I82579_E_PHY_ID 0x01540090
#define I82580_I_PHY_ID 0x015403A0
#define I350_I_PHY_ID 0x015403B0
#define I210_I_PHY_ID 0x01410C00
#define IGP04E1000_E_PHY_ID 0x02A80391
#define M88_VENDOR 0x0141
/* M88E1000 Specific Registers */
#define M88E1000_PHY_SPEC_CTRL 0x10 /* PHY Specific Control Register */
#define M88E1000_PHY_SPEC_STATUS 0x11 /* PHY Specific Status Register */
#define M88E1000_INT_ENABLE 0x12 /* Interrupt Enable Register */
#define M88E1000_INT_STATUS 0x13 /* Interrupt Status Register */
#define M88E1000_EXT_PHY_SPEC_CTRL 0x14 /* Extended PHY Specific Control */
#define M88E1000_PHY_SPEC_CTRL 0x10 /* PHY Specific Control Reg */
#define M88E1000_PHY_SPEC_STATUS 0x11 /* PHY Specific Status Reg */
#define M88E1000_INT_ENABLE 0x12 /* Interrupt Enable Reg */
#define M88E1000_INT_STATUS 0x13 /* Interrupt Status Reg */
#define M88E1000_EXT_PHY_SPEC_CTRL 0x14 /* Extended PHY Specific Cntrl */
#define M88E1000_RX_ERR_CNTR 0x15 /* Receive Error Counter */
#define M88E1000_PHY_EXT_CTRL 0x1A /* PHY extend control register */
#define M88E1000_PHY_PAGE_SELECT 0x1D /* Reg 29 for page number setting */
#define M88E1000_PHY_GEN_CONTROL 0x1E /* Its meaning depends on reg 29 */
#define M88E1000_PHY_PAGE_SELECT 0x1D /* Reg 29 for pg number setting */
#define M88E1000_PHY_GEN_CONTROL 0x1E /* meaning depends on reg 29 */
#define M88E1000_PHY_VCO_REG_BIT8 0x100 /* Bits 8 & 11 are adjusted for */
#define M88E1000_PHY_VCO_REG_BIT11 0x800 /* improved BER performance */
@@ -1516,8 +1573,8 @@
#define M88E1000_PSCR_SQE_TEST 0x0004 /* 1=SQE Test enabled */
/* 1=CLK125 low, 0=CLK125 toggling */
#define M88E1000_PSCR_CLK125_DISABLE 0x0010
#define M88E1000_PSCR_MDI_MANUAL_MODE 0x0000 /* MDI Crossover Mode bits 6:5 */
/* Manual MDI configuration */
/* MDI Crossover Mode bits 6:5 Manual MDI configuration */
#define M88E1000_PSCR_MDI_MANUAL_MODE 0x0000
#define M88E1000_PSCR_MDIX_MANUAL_MODE 0x0020 /* Manual MDIX configuration */
/* 1000BASE-T: Auto crossover, 100BASE-TX/10BASE-T: MDI Mode */
#define M88E1000_PSCR_AUTO_X_1000T 0x0040
@@ -1654,68 +1711,47 @@
#define GG82563_MIN_ALT_REG 30
/* GG82563 Specific Registers */
#define GG82563_PHY_SPEC_CTRL \
GG82563_REG(0, 16) /* PHY Specific Control */
#define GG82563_PHY_SPEC_STATUS \
GG82563_REG(0, 17) /* PHY Specific Status */
#define GG82563_PHY_INT_ENABLE \
GG82563_REG(0, 18) /* Interrupt Enable */
#define GG82563_PHY_SPEC_STATUS_2 \
GG82563_REG(0, 19) /* PHY Specific Status 2 */
#define GG82563_PHY_RX_ERR_CNTR \
GG82563_REG(0, 21) /* Receive Error Counter */
#define GG82563_PHY_PAGE_SELECT \
GG82563_REG(0, 22) /* Page Select */
#define GG82563_PHY_SPEC_CTRL_2 \
GG82563_REG(0, 26) /* PHY Specific Control 2 */
#define GG82563_PHY_PAGE_SELECT_ALT \
GG82563_REG(0, 29) /* Alternate Page Select */
#define GG82563_PHY_TEST_CLK_CTRL \
GG82563_REG(0, 30) /* Test Clock Control (use reg. 29 to select) */
#define GG82563_PHY_SPEC_CTRL GG82563_REG(0, 16) /* PHY Spec Cntrl */
#define GG82563_PHY_SPEC_STATUS GG82563_REG(0, 17) /* PHY Spec Status */
#define GG82563_PHY_INT_ENABLE GG82563_REG(0, 18) /* Interrupt Ena */
#define GG82563_PHY_SPEC_STATUS_2 GG82563_REG(0, 19) /* PHY Spec Stat2 */
#define GG82563_PHY_RX_ERR_CNTR GG82563_REG(0, 21) /* Rx Err Counter */
#define GG82563_PHY_PAGE_SELECT GG82563_REG(0, 22) /* Page Select */
#define GG82563_PHY_SPEC_CTRL_2 GG82563_REG(0, 26) /* PHY Spec Cntrl2 */
#define GG82563_PHY_PAGE_SELECT_ALT GG82563_REG(0, 29) /* Alt Page Select */
/* Test Clock Control (use reg. 29 to select) */
#define GG82563_PHY_TEST_CLK_CTRL GG82563_REG(0, 30)
#define GG82563_PHY_MAC_SPEC_CTRL \
GG82563_REG(2, 21) /* MAC Specific Control Register */
#define GG82563_PHY_MAC_SPEC_CTRL_2 \
GG82563_REG(2, 26) /* MAC Specific Control 2 */
/* MAC Specific Control Register */
#define GG82563_PHY_MAC_SPEC_CTRL GG82563_REG(2, 21)
#define GG82563_PHY_MAC_SPEC_CTRL_2 GG82563_REG(2, 26) /* MAC Spec Ctrl 2 */
#define GG82563_PHY_DSP_DISTANCE \
GG82563_REG(5, 26) /* DSP Distance */
#define GG82563_PHY_DSP_DISTANCE GG82563_REG(5, 26) /* DSP Distance */
/* Page 193 - Port Control Registers */
#define GG82563_PHY_KMRN_MODE_CTRL \
GG82563_REG(193, 16) /* Kumeran Mode Control */
#define GG82563_PHY_PORT_RESET \
GG82563_REG(193, 17) /* Port Reset */
#define GG82563_PHY_REVISION_ID \
GG82563_REG(193, 18) /* Revision ID */
#define GG82563_PHY_DEVICE_ID \
GG82563_REG(193, 19) /* Device ID */
#define GG82563_PHY_PWR_MGMT_CTRL \
GG82563_REG(193, 20) /* Power Management Control */
#define GG82563_PHY_RATE_ADAPT_CTRL \
GG82563_REG(193, 25) /* Rate Adaptation Control */
/* Kumeran Mode Control */
#define GG82563_PHY_KMRN_MODE_CTRL GG82563_REG(193, 16)
#define GG82563_PHY_PORT_RESET GG82563_REG(193, 17) /* Port Reset */
#define GG82563_PHY_REVISION_ID GG82563_REG(193, 18) /* Revision ID */
#define GG82563_PHY_DEVICE_ID GG82563_REG(193, 19) /* Device ID */
#define GG82563_PHY_PWR_MGMT_CTRL GG82563_REG(193, 20) /* Pwr Mgt Ctrl */
/* Rate Adaptation Control */
#define GG82563_PHY_RATE_ADAPT_CTRL GG82563_REG(193, 25)
/* Page 194 - KMRN Registers */
#define GG82563_PHY_KMRN_FIFO_CTRL_STAT \
GG82563_REG(194, 16) /* FIFO's Control/Status */
#define GG82563_PHY_KMRN_CTRL \
GG82563_REG(194, 17) /* Control */
#define GG82563_PHY_INBAND_CTRL \
GG82563_REG(194, 18) /* Inband Control */
#define GG82563_PHY_KMRN_DIAGNOSTIC \
GG82563_REG(194, 19) /* Diagnostic */
#define GG82563_PHY_ACK_TIMEOUTS \
GG82563_REG(194, 20) /* Acknowledge Timeouts */
#define GG82563_PHY_ADV_ABILITY \
GG82563_REG(194, 21) /* Advertised Ability */
#define GG82563_PHY_LINK_PARTNER_ADV_ABILITY \
GG82563_REG(194, 23) /* Link Partner Advertised Ability */
#define GG82563_PHY_ADV_NEXT_PAGE \
GG82563_REG(194, 24) /* Advertised Next Page */
#define GG82563_PHY_LINK_PARTNER_ADV_NEXT_PAGE \
GG82563_REG(194, 25) /* Link Partner Advertised Next page */
#define GG82563_PHY_KMRN_MISC \
GG82563_REG(194, 26) /* Misc. */
/* FIFO's Control/Status */
#define GG82563_PHY_KMRN_FIFO_CTRL_STAT GG82563_REG(194, 16)
#define GG82563_PHY_KMRN_CTRL GG82563_REG(194, 17) /* Control */
#define GG82563_PHY_INBAND_CTRL GG82563_REG(194, 18) /* Inband Ctrl */
#define GG82563_PHY_KMRN_DIAGNOSTIC GG82563_REG(194, 19) /* Diagnostic */
#define GG82563_PHY_ACK_TIMEOUTS GG82563_REG(194, 20) /* Ack Timeouts */
#define GG82563_PHY_ADV_ABILITY GG82563_REG(194, 21) /* Adver Ability */
/* Link Partner Advertised Ability */
#define GG82563_PHY_LINK_PARTNER_ADV_ABILITY GG82563_REG(194, 23)
#define GG82563_PHY_ADV_NEXT_PAGE GG82563_REG(194, 24) /* Adver Next Pg */
/* Link Partner Advertised Next page */
#define GG82563_PHY_LINK_PARTNER_ADV_NEXT_PAGE GG82563_REG(194, 25)
#define GG82563_PHY_KMRN_MISC GG82563_REG(194, 26) /* Misc. */
/* MDI Control */
#define E1000_MDIC_DATA_MASK 0x0000FFFF
@@ -1767,55 +1803,88 @@
(E1000_RTTBCNRC_RF_DEC_MASK << E1000_RTTBCNRC_RF_INT_SHIFT)
/* DMA Coalescing register fields */
#define E1000_DMACR_DMACWT_MASK 0x00003FFF /* DMA Coalescing
* Watchdog Timer */
#define E1000_DMACR_DMACTHR_MASK 0x00FF0000 /* DMA Coalescing Rx
* Threshold */
/* DMA Coalescing Watchdog Timer */
#define E1000_DMACR_DMACWT_MASK 0x00003FFF
/* DMA Coalescing Rx Threshold */
#define E1000_DMACR_DMACTHR_MASK 0x00FF0000
#define E1000_DMACR_DMACTHR_SHIFT 16
#define E1000_DMACR_DMAC_LX_MASK 0x30000000 /* Lx when no PCIe
* transactions */
/* Lx when no PCIe transactions */
#define E1000_DMACR_DMAC_LX_MASK 0x30000000
#define E1000_DMACR_DMAC_LX_SHIFT 28
#define E1000_DMACR_DMAC_EN 0x80000000 /* Enable DMA Coalescing */
/* DMA Coalescing BMC-to-OS Watchdog Enable */
#define E1000_DMACR_DC_BMC2OSW_EN 0x00008000
#define E1000_DMCTXTH_DMCTTHR_MASK 0x00000FFF /* DMA Coalescing Transmit
* Threshold */
/* DMA Coalescing Transmit Threshold */
#define E1000_DMCTXTH_DMCTTHR_MASK 0x00000FFF
#define E1000_DMCTLX_TTLX_MASK 0x00000FFF /* Time to LX request */
#define E1000_DMCRTRH_UTRESH_MASK 0x0007FFFF /* Rx Traffic Rate
* Threshold */
#define E1000_DMCRTRH_LRPRCW 0x80000000 /* Rx packet rate in
* current window */
/* Rx Traffic Rate Threshold */
#define E1000_DMCRTRH_UTRESH_MASK 0x0007FFFF
/* Rx packet rate in current window */
#define E1000_DMCRTRH_LRPRCW 0x80000000
#define E1000_DMCCNT_CCOUNT_MASK 0x01FFFFFF /* DMA Coal Rx Traffic
* Current Cnt */
/* DMA Coal Rx Traffic Current Count */
#define E1000_DMCCNT_CCOUNT_MASK 0x01FFFFFF
#define E1000_FCRTC_RTH_COAL_MASK 0x0003FFF0 /* Flow ctrl Rx Threshold
* High val */
/* Flow ctrl Rx Threshold High val */
#define E1000_FCRTC_RTH_COAL_MASK 0x0003FFF0
#define E1000_FCRTC_RTH_COAL_SHIFT 4
#define E1000_PCIEMISC_LX_DECISION 0x00000080 /* Lx power decision based
on DMA coal */
/* Lx power decision based on DMA coal */
#define E1000_PCIEMISC_LX_DECISION 0x00000080
#define E1000_RXPBS_SIZE_I210_MASK 0x0000003F /* Rx packet buffer size */
#define E1000_TXPB0S_SIZE_I210_MASK 0x0000003F /* Tx packet buffer 0 size */
#define E1000_LTRC_EEEMS_EN 0x00000020 /* Enable EEE LTR max send */
/* Minimum time for 1000BASE-T where no data will be transmit following move out
* of EEE LPI Tx state
*/
#define E1000_TW_SYSTEM_1000_MASK 0x000000FF
/* Minimum time for 100BASE-T where no data will be transmit following move out
* of EEE LPI Tx state
*/
#define E1000_TW_SYSTEM_100_MASK 0x0000FF00
#define E1000_TW_SYSTEM_100_SHIFT 8
#define E1000_LTRMINV_LTRV_MASK 0x000003FF /* LTR minimum value */
#define E1000_LTRMAXV_LTRV_MASK 0x000003FF /* LTR maximum value */
#define E1000_LTRMINV_SCALE_MASK 0x00001C00 /* LTR minimum scale */
#define E1000_LTRMINV_SCALE_SHIFT 10
/* Reg val to set scale to 1024 nsec */
#define E1000_LTRMINV_SCALE_1024 2
/* Reg val to set scale to 32768 nsec */
#define E1000_LTRMINV_SCALE_32768 3
#define E1000_LTRMINV_LSNP_REQ 0x00008000 /* LTR Snoop Requirement */
#define E1000_LTRMAXV_SCALE_MASK 0x00001C00 /* LTR maximum scale */
#define E1000_LTRMAXV_SCALE_SHIFT 10
/* Reg val to set scale to 1024 nsec */
#define E1000_LTRMAXV_SCALE_1024 2
/* Reg val to set scale to 32768 nsec */
#define E1000_LTRMAXV_SCALE_32768 3
#define E1000_LTRMAXV_LSNP_REQ 0x00008000 /* LTR Snoop Requirement */
#define E1000_DOBFFCTL_OBFFTHR_MASK 0x000000FF /* OBFF threshold */
#define E1000_DOBFFCTL_EXIT_ACT_MASK 0x01000000 /* Exit active CB */
/* Proxy Filer Control */
#define E1000_PROXYFC_D0 0x00000001 /* Enable offload in D0 */
#define E1000_PROXYFC_EX 0x00000004 /* Directed exact proxy */
#define E1000_PROXYFC_MC 0x00000008 /* Directed Multicast
* Proxy */
#define E1000_PROXYFC_MC 0x00000008 /* Directed MC Proxy */
#define E1000_PROXYFC_BC 0x00000010 /* Broadcast Proxy Enable */
#define E1000_PROXYFC_ARP_DIRECTED 0x00000020 /* Directed ARP Proxy
* Enable */
#define E1000_PROXYFC_ARP_DIRECTED 0x00000020 /* Directed ARP Proxy Ena */
#define E1000_PROXYFC_IPV4 0x00000040 /* Directed IPv4 Enable */
#define E1000_PROXYFC_IPV6 0x00000080 /* Directed IPv6 Enable */
#define E1000_PROXYFC_NS 0x00000200 /* IPv4 Neighborhood
* Solicitation */
#define E1000_PROXYFC_ARP 0x00000800 /* ARP Request Proxy
* Enable */
#define E1000_PROXYFC_NS 0x00000200 /* IPv4 NBRHD Solicitation */
#define E1000_PROXYFC_ARP 0x00000800 /* ARP Request Proxy Ena */
/* Proxy Status */
#define E1000_PROXYS_CLEAR 0xFFFFFFFF /* Clear */
/* Firmware Status */
#define E1000_FWSTS_FWRI 0x80000000 /* Firmware Reset
* Indication */
#define E1000_FWSTS_FWRI 0x80000000 /* FW Reset Indication */
/* VF Control */
#define E1000_VTCTRL_RST 0x04000000 /* Reset VF */
#define E1000_STATUS_LAN_ID_MASK 0x00000000C /* Mask for Lan ID field */
/* Lan ID bit field offset in status register */
#define E1000_STATUS_LAN_ID_OFFSET 2
#define E1000_VFTA_ENTRIES 128
#endif /* _E1000_DEFINES_H_ */
@@ -1,6 +1,6 @@
/******************************************************************************
Copyright (c) 2001-2010, Intel Corporation
Copyright (c) 2001-2012, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -30,7 +30,7 @@
POSSIBILITY OF SUCH DAMAGE.
******************************************************************************/
/*$FreeBSD: src/sys/dev/e1000/e1000_hw.h,v 1.4.2.4.2.1 2010/12/21 17:09:25 kensmith Exp $*/
/*$FreeBSD$*/
#ifndef _E1000_HW_H_
#define _E1000_HW_H_
@@ -120,7 +120,6 @@ struct e1000_hw;
#define E1000_DEV_ID_ICH10_R_BM_LM 0x10CC
#define E1000_DEV_ID_ICH10_R_BM_LF 0x10CD
#define E1000_DEV_ID_ICH10_R_BM_V 0x10CE
#define E1000_DEV_ID_ICH10_HANKSVILLE 0xF0FE
#define E1000_DEV_ID_ICH10_D_BM_LM 0x10DE
#define E1000_DEV_ID_ICH10_D_BM_LF 0x10DF
#define E1000_DEV_ID_ICH10_D_BM_V 0x1525
@@ -144,7 +143,6 @@ struct e1000_hw;
#define E1000_DEV_ID_82575EB_COPPER 0x10A7
#define E1000_DEV_ID_82575EB_FIBER_SERDES 0x10A9
#define E1000_DEV_ID_82575GB_QUAD_COPPER 0x10D6
#define E1000_DEV_ID_82575GB_QUAD_COPPER_PM 0x10E2
#define E1000_DEV_ID_82580_COPPER 0x150E
#define E1000_DEV_ID_82580_FIBER 0x150F
#define E1000_DEV_ID_82580_SERDES 0x1510
@@ -155,6 +153,14 @@ struct e1000_hw;
#define E1000_DEV_ID_I350_FIBER 0x1522
#define E1000_DEV_ID_I350_SERDES 0x1523
#define E1000_DEV_ID_I350_SGMII 0x1524
#define E1000_DEV_ID_I350_DA4 0x1546
#define E1000_DEV_ID_I210_COPPER 0x1533
#define E1000_DEV_ID_I210_COPPER_OEM1 0x1534
#define E1000_DEV_ID_I210_COPPER_IT 0x1535
#define E1000_DEV_ID_I210_FIBER 0x1536
#define E1000_DEV_ID_I210_SERDES 0x1537
#define E1000_DEV_ID_I210_SGMII 0x1538
#define E1000_DEV_ID_I211_COPPER 0x1539
#define E1000_DEV_ID_DH89XXCC_SGMII 0x0438
#define E1000_DEV_ID_DH89XXCC_SERDES 0x043A
#define E1000_DEV_ID_DH89XXCC_BACKPLANE 0x043C
@@ -204,6 +210,8 @@ enum e1000_mac_type {
e1000_82576,
e1000_82580,
e1000_i350,
e1000_i210,
e1000_i211,
e1000_vfadapt,
e1000_vfadapt_i350,
e1000_num_macs /* List is 1-based, so subtract 1 for TRUE count. */
@@ -249,6 +257,7 @@ enum e1000_phy_type {
e1000_phy_82579,
e1000_phy_82580,
e1000_phy_vf,
e1000_phy_i210,
};
enum e1000_bus_type {
@@ -553,6 +562,10 @@ struct e1000_hw_stats {
u64 scvpc;
u64 hrmpc;
u64 doosync;
u64 o2bgptc;
u64 o2bspc;
u64 b2ospc;
u64 b2ogprc;
};
struct e1000_vf_stats {
@@ -671,8 +684,25 @@ struct e1000_mac_operations {
struct e1000_host_mng_command_header*);
s32 (*mng_enable_host_if)(struct e1000_hw *);
s32 (*wait_autoneg)(struct e1000_hw *);
s32 (*acquire_swfw_sync)(struct e1000_hw *, u16);
void (*release_swfw_sync)(struct e1000_hw *, u16);
};
/*
* When to use various PHY register access functions:
*
* Func Caller
* Function Does Does When to use
* ~~~~~~~~~~~~ ~~~~~ ~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* X_reg L,P,A n/a for simple PHY reg accesses
* X_reg_locked P,A L for multiple accesses of different regs
* on different pages
* X_reg_page A L,P for multiple accesses of different regs
* on the same page
*
* Where X=[read|write], L=locking, P=sets page, A=register access
*
*/
struct e1000_phy_operations {
s32 (*init_params)(struct e1000_hw *);
s32 (*acquire)(struct e1000_hw *);
@@ -684,16 +714,21 @@ struct e1000_phy_operations {
s32 (*get_cfg_done)(struct e1000_hw *hw);
s32 (*get_cable_length)(struct e1000_hw *);
s32 (*get_info)(struct e1000_hw *);
s32 (*set_page)(struct e1000_hw *, u16);
s32 (*read_reg)(struct e1000_hw *, u32, u16 *);
s32 (*read_reg_locked)(struct e1000_hw *, u32, u16 *);
s32 (*read_reg_page)(struct e1000_hw *, u32, u16 *);
void (*release)(struct e1000_hw *);
s32 (*reset)(struct e1000_hw *);
s32 (*set_d0_lplu_state)(struct e1000_hw *, bool);
s32 (*set_d3_lplu_state)(struct e1000_hw *, bool);
s32 (*write_reg)(struct e1000_hw *, u32, u16);
s32 (*write_reg_locked)(struct e1000_hw *, u32, u16);
s32 (*write_reg_page)(struct e1000_hw *, u32, u16);
void (*power_up)(struct e1000_hw *);
void (*power_down)(struct e1000_hw *);
s32 (*read_i2c_byte)(struct e1000_hw *, u8, u8, u8 *);
s32 (*write_i2c_byte)(struct e1000_hw *, u8, u8, u8);
};
struct e1000_nvm_operations {
@@ -781,7 +816,6 @@ struct e1000_phy_info {
bool disable_polarity_correction;
bool is_mdix;
bool polarity_correction;
bool reset_disable;
bool speed_downgraded;
bool autoneg_wait_to_complete;
};
@@ -896,6 +930,8 @@ struct e1000_dev_spec_82575 {
bool sgmii_active;
bool global_device_reset;
bool eee_disable;
bool module_plugged;
u32 mtu;
};
struct e1000_dev_spec_vf {
@@ -943,6 +979,7 @@ struct e1000_hw {
#include "e1000_80003es2lan.h"
#include "e1000_ich8lan.h"
#include "e1000_82575.h"
#include "e1000_i210.h"
/* These functions must be implemented by drivers */
void e1000_pci_clear_mwi(struct e1000_hw *hw);
@@ -0,0 +1,740 @@
/******************************************************************************
Copyright (c) 2001-2012, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of the Intel Corporation nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
******************************************************************************/
/*$FreeBSD$*/
#include "e1000_api.h"
static s32 e1000_acquire_nvm_i210(struct e1000_hw *hw);
static void e1000_release_nvm_i210(struct e1000_hw *hw);
static s32 e1000_get_hw_semaphore_i210(struct e1000_hw *hw);
static void e1000_put_hw_semaphore_i210(struct e1000_hw *hw);
static s32 e1000_write_nvm_srwr(struct e1000_hw *hw, u16 offset, u16 words,
u16 *data);
static s32 e1000_pool_flash_update_done_i210(struct e1000_hw *hw);
static s32 e1000_valid_led_default_i210(struct e1000_hw *hw, u16 *data);
static s32 e1000_read_nvm_i211(struct e1000_hw *hw, u16 offset, u16 words,
u16 *data);
/**
* e1000_acquire_nvm_i210 - Request for access to EEPROM
* @hw: pointer to the HW structure
*
* Acquire the necessary semaphores for exclusive access to the EEPROM.
* Set the EEPROM access request bit and wait for EEPROM access grant bit.
* Return successful if access grant bit set, else clear the request for
* EEPROM access and return -E1000_ERR_NVM (-1).
**/
static s32 e1000_acquire_nvm_i210(struct e1000_hw *hw)
{
s32 ret_val;
DEBUGFUNC("e1000_acquire_nvm_i210");
ret_val = e1000_acquire_swfw_sync_i210(hw, E1000_SWFW_EEP_SM);
return ret_val;
}
/**
* e1000_release_nvm_i210 - Release exclusive access to EEPROM
* @hw: pointer to the HW structure
*
* Stop any current commands to the EEPROM and clear the EEPROM request bit,
* then release the semaphores acquired.
**/
static void e1000_release_nvm_i210(struct e1000_hw *hw)
{
DEBUGFUNC("e1000_release_nvm_i210");
e1000_release_swfw_sync_i210(hw, E1000_SWFW_EEP_SM);
}
/**
* e1000_acquire_swfw_sync_i210 - Acquire SW/FW semaphore
* @hw: pointer to the HW structure
* @mask: specifies which semaphore to acquire
*
* Acquire the SW/FW semaphore to access the PHY or NVM. The mask
* will also specify which port we're acquiring the lock for.
**/
s32 e1000_acquire_swfw_sync_i210(struct e1000_hw *hw, u16 mask)
{
u32 swfw_sync;
u32 swmask = mask;
u32 fwmask = mask << 16;
s32 ret_val = E1000_SUCCESS;
s32 i = 0, timeout = 200; /* FIXME: find real value to use here */
DEBUGFUNC("e1000_acquire_swfw_sync_i210");
while (i < timeout) {
if (e1000_get_hw_semaphore_i210(hw)) {
ret_val = -E1000_ERR_SWFW_SYNC;
goto out;
}
swfw_sync = E1000_READ_REG(hw, E1000_SW_FW_SYNC);
if (!(swfw_sync & fwmask))
break;
/*
* Firmware currently using resource (fwmask)
*/
e1000_put_hw_semaphore_i210(hw);
msec_delay_irq(5);
i++;
}
if (i == timeout) {
DEBUGOUT("Driver can't access resource, SW_FW_SYNC timeout.\n");
ret_val = -E1000_ERR_SWFW_SYNC;
goto out;
}
swfw_sync |= swmask;
E1000_WRITE_REG(hw, E1000_SW_FW_SYNC, swfw_sync);
e1000_put_hw_semaphore_i210(hw);
out:
return ret_val;
}
/**
* e1000_release_swfw_sync_i210 - Release SW/FW semaphore
* @hw: pointer to the HW structure
* @mask: specifies which semaphore to acquire
*
* Release the SW/FW semaphore used to access the PHY or NVM. The mask
* will also specify which port we're releasing the lock for.
**/
void e1000_release_swfw_sync_i210(struct e1000_hw *hw, u16 mask)
{
u32 swfw_sync;
DEBUGFUNC("e1000_release_swfw_sync_i210");
while (e1000_get_hw_semaphore_i210(hw) != E1000_SUCCESS)
; /* Empty */
swfw_sync = E1000_READ_REG(hw, E1000_SW_FW_SYNC);
swfw_sync &= ~mask;
E1000_WRITE_REG(hw, E1000_SW_FW_SYNC, swfw_sync);
e1000_put_hw_semaphore_i210(hw);
}
/**
* e1000_get_hw_semaphore_i210 - Acquire hardware semaphore
* @hw: pointer to the HW structure
*
* Acquire the HW semaphore to access the PHY or NVM
**/
static s32 e1000_get_hw_semaphore_i210(struct e1000_hw *hw)
{
u32 swsm;
s32 ret_val = E1000_SUCCESS;
s32 timeout = hw->nvm.word_size + 1;
s32 i = 0;
DEBUGFUNC("e1000_get_hw_semaphore_i210");
/* Get the FW semaphore. */
for (i = 0; i < timeout; i++) {
swsm = E1000_READ_REG(hw, E1000_SWSM);
E1000_WRITE_REG(hw, E1000_SWSM, swsm | E1000_SWSM_SWESMBI);
/* Semaphore acquired if bit latched */
if (E1000_READ_REG(hw, E1000_SWSM) & E1000_SWSM_SWESMBI)
break;
usec_delay(50);
}
if (i == timeout) {
/* Release semaphores */
e1000_put_hw_semaphore_generic(hw);
DEBUGOUT("Driver can't access the NVM\n");
ret_val = -E1000_ERR_NVM;
goto out;
}
out:
return ret_val;
}
/**
* e1000_put_hw_semaphore_i210 - Release hardware semaphore
* @hw: pointer to the HW structure
*
* Release hardware semaphore used to access the PHY or NVM
**/
static void e1000_put_hw_semaphore_i210(struct e1000_hw *hw)
{
u32 swsm;
DEBUGFUNC("e1000_put_hw_semaphore_i210");
swsm = E1000_READ_REG(hw, E1000_SWSM);
swsm &= ~E1000_SWSM_SWESMBI;
E1000_WRITE_REG(hw, E1000_SWSM, swsm);
}
/**
* e1000_read_nvm_srrd_i210 - Reads Shadow Ram using EERD register
* @hw: pointer to the HW structure
* @offset: offset of word in the Shadow Ram to read
* @words: number of words to read
* @data: word read from the Shadow Ram
*
* Reads a 16 bit word from the Shadow Ram using the EERD register.
* Uses necessary synchronization semaphores.
**/
s32 e1000_read_nvm_srrd_i210(struct e1000_hw *hw, u16 offset, u16 words,
u16 *data)
{
s32 status = E1000_SUCCESS;
u16 i, count;
DEBUGFUNC("e1000_read_nvm_srrd_i210");
/* We cannot hold synchronization semaphores for too long,
* because of forceful takeover procedure. However it is more efficient
* to read in bursts than synchronizing access for each word. */
for (i = 0; i < words; i += E1000_EERD_EEWR_MAX_COUNT) {
count = (words - i) / E1000_EERD_EEWR_MAX_COUNT > 0 ?
E1000_EERD_EEWR_MAX_COUNT : (words - i);
if (hw->nvm.ops.acquire(hw) == E1000_SUCCESS) {
status = e1000_read_nvm_eerd(hw, offset, count,
data + i);
hw->nvm.ops.release(hw);
} else {
status = E1000_ERR_SWFW_SYNC;
}
if (status != E1000_SUCCESS)
break;
}
return status;
}
/**
* e1000_write_nvm_srwr_i210 - Write to Shadow RAM using EEWR
* @hw: pointer to the HW structure
* @offset: offset within the Shadow RAM to be written to
* @words: number of words to write
* @data: 16 bit word(s) to be written to the Shadow RAM
*
* Writes data to Shadow RAM at offset using EEWR register.
*
* If e1000_update_nvm_checksum is not called after this function , the
* data will not be committed to FLASH and also Shadow RAM will most likely
* contain an invalid checksum.
*
* If error code is returned, data and Shadow RAM may be inconsistent - buffer
* partially written.
**/
s32 e1000_write_nvm_srwr_i210(struct e1000_hw *hw, u16 offset, u16 words,
u16 *data)
{
s32 status = E1000_SUCCESS;
u16 i, count;
DEBUGFUNC("e1000_write_nvm_srwr_i210");
/* We cannot hold synchronization semaphores for too long,
* because of forceful takeover procedure. However it is more efficient
* to write in bursts than synchronizing access for each word. */
for (i = 0; i < words; i += E1000_EERD_EEWR_MAX_COUNT) {
count = (words - i) / E1000_EERD_EEWR_MAX_COUNT > 0 ?
E1000_EERD_EEWR_MAX_COUNT : (words - i);
if (hw->nvm.ops.acquire(hw) == E1000_SUCCESS) {
status = e1000_write_nvm_srwr(hw, offset, count,
data + i);
hw->nvm.ops.release(hw);
} else {
status = E1000_ERR_SWFW_SYNC;
}
if (status != E1000_SUCCESS)
break;
}
return status;
}
/**
* e1000_write_nvm_srwr - Write to Shadow Ram using EEWR
* @hw: pointer to the HW structure
* @offset: offset within the Shadow Ram to be written to
* @words: number of words to write
* @data: 16 bit word(s) to be written to the Shadow Ram
*
* Writes data to Shadow Ram at offset using EEWR register.
*
* If e1000_update_nvm_checksum is not called after this function , the
* Shadow Ram will most likely contain an invalid checksum.
**/
static s32 e1000_write_nvm_srwr(struct e1000_hw *hw, u16 offset, u16 words,
u16 *data)
{
struct e1000_nvm_info *nvm = &hw->nvm;
u32 i, k, eewr = 0;
u32 attempts = 100000;
s32 ret_val = E1000_SUCCESS;
DEBUGFUNC("e1000_write_nvm_srwr");
/*
* A check for invalid values: offset too large, too many words,
* too many words for the offset, and not enough words.
*/
if ((offset >= nvm->word_size) || (words > (nvm->word_size - offset)) ||
(words == 0)) {
DEBUGOUT("nvm parameter(s) out of bounds\n");
ret_val = -E1000_ERR_NVM;
goto out;
}
for (i = 0; i < words; i++) {
eewr = ((offset+i) << E1000_NVM_RW_ADDR_SHIFT) |
(data[i] << E1000_NVM_RW_REG_DATA) |
E1000_NVM_RW_REG_START;
E1000_WRITE_REG(hw, E1000_SRWR, eewr);
for (k = 0; k < attempts; k++) {
if (E1000_NVM_RW_REG_DONE &
E1000_READ_REG(hw, E1000_SRWR)) {
ret_val = E1000_SUCCESS;
break;
}
usec_delay(5);
}
if (ret_val != E1000_SUCCESS) {
DEBUGOUT("Shadow RAM write EEWR timed out\n");
break;
}
}
out:
return ret_val;
}
/**
* e1000_read_nvm_i211 - Read NVM wrapper function for I211
* @hw: pointer to the HW structure
* @address: the word address (aka eeprom offset) to read
* @data: pointer to the data read
*
* Wrapper function to return data formerly found in the NVM.
**/
static s32 e1000_read_nvm_i211(struct e1000_hw *hw, u16 offset, u16 words,
u16 *data)
{
s32 ret_val = E1000_SUCCESS;
DEBUGFUNC("e1000_read_nvm_i211");
/* Only the MAC addr is required to be present in the iNVM */
switch (offset) {
case NVM_MAC_ADDR:
ret_val = e1000_read_invm_i211(hw, (u8)offset, &data[0]);
ret_val |= e1000_read_invm_i211(hw, (u8)offset+1, &data[1]);
ret_val |= e1000_read_invm_i211(hw, (u8)offset+2, &data[2]);
if (ret_val != E1000_SUCCESS)
DEBUGOUT("MAC Addr not found in iNVM\n");
break;
case NVM_ID_LED_SETTINGS:
case NVM_INIT_CTRL_2:
case NVM_INIT_CTRL_4:
case NVM_LED_1_CFG:
case NVM_LED_0_2_CFG:
e1000_read_invm_i211(hw, (u8)offset, data);
break;
case NVM_COMPAT:
*data = ID_LED_DEFAULT_I210;
break;
case NVM_SUB_DEV_ID:
*data = hw->subsystem_device_id;
break;
case NVM_SUB_VEN_ID:
*data = hw->subsystem_vendor_id;
break;
case NVM_DEV_ID:
*data = hw->device_id;
break;
case NVM_VEN_ID:
*data = hw->vendor_id;
break;
default:
DEBUGOUT1("NVM word 0x%02x is not mapped.\n", offset);
*data = NVM_RESERVED_WORD;
break;
}
return ret_val;
}
/**
* e1000_read_invm_i211 - Reads OTP
* @hw: pointer to the HW structure
* @address: the word address (aka eeprom offset) to read
* @data: pointer to the data read
*
* Reads 16-bit words from the OTP. Return error when the word is not
* stored in OTP.
**/
s32 e1000_read_invm_i211(struct e1000_hw *hw, u8 address, u16 *data)
{
s32 status = -E1000_ERR_INVM_VALUE_NOT_FOUND;
u32 invm_dword;
u16 i;
u8 record_type, word_address;
DEBUGFUNC("e1000_read_invm_i211");
for (i = 0; i < E1000_INVM_SIZE; i++) {
invm_dword = E1000_READ_REG(hw, E1000_INVM_DATA_REG(i));
/* Get record type */
record_type = INVM_DWORD_TO_RECORD_TYPE(invm_dword);
if (record_type == E1000_INVM_UNINITIALIZED_STRUCTURE)
break;
if (record_type == E1000_INVM_CSR_AUTOLOAD_STRUCTURE)
i += E1000_INVM_CSR_AUTOLOAD_DATA_SIZE_IN_DWORDS;
if (record_type == E1000_INVM_RSA_KEY_SHA256_STRUCTURE)
i += E1000_INVM_RSA_KEY_SHA256_DATA_SIZE_IN_DWORDS;
if (record_type == E1000_INVM_WORD_AUTOLOAD_STRUCTURE) {
word_address = INVM_DWORD_TO_WORD_ADDRESS(invm_dword);
if (word_address == address) {
*data = INVM_DWORD_TO_WORD_DATA(invm_dword);
DEBUGOUT2("Read INVM Word 0x%02x = %x",
address, *data);
status = E1000_SUCCESS;
break;
}
}
}
if (status != E1000_SUCCESS)
DEBUGOUT1("Requested word 0x%02x not found in OTP\n", address);
return status;
}
/**
* e1000_validate_nvm_checksum_i210 - Validate EEPROM checksum
* @hw: pointer to the HW structure
*
* Calculates the EEPROM checksum by reading/adding each word of the EEPROM
* and then verifies that the sum of the EEPROM is equal to 0xBABA.
**/
s32 e1000_validate_nvm_checksum_i210(struct e1000_hw *hw)
{
s32 status = E1000_SUCCESS;
s32 (*read_op_ptr)(struct e1000_hw *, u16, u16, u16 *);
DEBUGFUNC("e1000_validate_nvm_checksum_i210");
if (hw->nvm.ops.acquire(hw) == E1000_SUCCESS) {
/*
* Replace the read function with semaphore grabbing with
* the one that skips this for a while.
* We have semaphore taken already here.
*/
read_op_ptr = hw->nvm.ops.read;
hw->nvm.ops.read = e1000_read_nvm_eerd;
status = e1000_validate_nvm_checksum_generic(hw);
/* Revert original read operation. */
hw->nvm.ops.read = read_op_ptr;
hw->nvm.ops.release(hw);
} else {
status = E1000_ERR_SWFW_SYNC;
}
return status;
}
/**
* e1000_update_nvm_checksum_i210 - Update EEPROM checksum
* @hw: pointer to the HW structure
*
* Updates the EEPROM checksum by reading/adding each word of the EEPROM
* up to the checksum. Then calculates the EEPROM checksum and writes the
* value to the EEPROM. Next commit EEPROM data onto the Flash.
**/
s32 e1000_update_nvm_checksum_i210(struct e1000_hw *hw)
{
s32 ret_val = E1000_SUCCESS;
u16 checksum = 0;
u16 i, nvm_data;
DEBUGFUNC("e1000_update_nvm_checksum_i210");
/*
* Read the first word from the EEPROM. If this times out or fails, do
* not continue or we could be in for a very long wait while every
* EEPROM read fails
*/
ret_val = e1000_read_nvm_eerd(hw, 0, 1, &nvm_data);
if (ret_val != E1000_SUCCESS) {
DEBUGOUT("EEPROM read failed\n");
goto out;
}
if (hw->nvm.ops.acquire(hw) == E1000_SUCCESS) {
/*
* Do not use hw->nvm.ops.write, hw->nvm.ops.read
* because we do not want to take the synchronization
* semaphores twice here.
*/
for (i = 0; i < NVM_CHECKSUM_REG; i++) {
ret_val = e1000_read_nvm_eerd(hw, i, 1, &nvm_data);
if (ret_val) {
hw->nvm.ops.release(hw);
DEBUGOUT("NVM Read Error while updating checksum.\n");
goto out;
}
checksum += nvm_data;
}
checksum = (u16) NVM_SUM - checksum;
ret_val = e1000_write_nvm_srwr(hw, NVM_CHECKSUM_REG, 1,
&checksum);
if (ret_val != E1000_SUCCESS) {
hw->nvm.ops.release(hw);
DEBUGOUT("NVM Write Error while updating checksum.\n");
goto out;
}
hw->nvm.ops.release(hw);
ret_val = e1000_update_flash_i210(hw);
} else {
ret_val = E1000_ERR_SWFW_SYNC;
}
out:
return ret_val;
}
/**
* e1000_get_flash_presence_i210 - Check if flash device is detected.
* @hw: pointer to the HW structure
*
**/
static bool e1000_get_flash_presence_i210(struct e1000_hw *hw)
{
u32 eec = 0;
bool ret_val = FALSE;
DEBUGFUNC("e1000_get_flash_presence_i210");
eec = E1000_READ_REG(hw, E1000_EECD);
if (eec & E1000_EECD_FLASH_DETECTED_I210)
ret_val = TRUE;
return ret_val;
}
/**
* e1000_update_flash_i210 - Commit EEPROM to the flash
* @hw: pointer to the HW structure
*
**/
s32 e1000_update_flash_i210(struct e1000_hw *hw)
{
s32 ret_val = E1000_SUCCESS;
u32 flup;
DEBUGFUNC("e1000_update_flash_i210");
ret_val = e1000_pool_flash_update_done_i210(hw);
if (ret_val == -E1000_ERR_NVM) {
DEBUGOUT("Flash update time out\n");
goto out;
}
flup = E1000_READ_REG(hw, E1000_EECD) | E1000_EECD_FLUPD_I210;
E1000_WRITE_REG(hw, E1000_EECD, flup);
ret_val = e1000_pool_flash_update_done_i210(hw);
if (ret_val == E1000_SUCCESS)
DEBUGOUT("Flash update complete\n");
else
DEBUGOUT("Flash update time out\n");
out:
return ret_val;
}
/**
* e1000_pool_flash_update_done_i210 - Pool FLUDONE status.
* @hw: pointer to the HW structure
*
**/
s32 e1000_pool_flash_update_done_i210(struct e1000_hw *hw)
{
s32 ret_val = -E1000_ERR_NVM;
u32 i, reg;
DEBUGFUNC("e1000_pool_flash_update_done_i210");
for (i = 0; i < E1000_FLUDONE_ATTEMPTS; i++) {
reg = E1000_READ_REG(hw, E1000_EECD);
if (reg & E1000_EECD_FLUDONE_I210) {
ret_val = E1000_SUCCESS;
break;
}
usec_delay(5);
}
return ret_val;
}
/**
* e1000_init_nvm_params_i210 - Initialize i210 NVM function pointers
* @hw: pointer to the HW structure
*
* Initialize the i210 NVM parameters and function pointers.
**/
static s32 e1000_init_nvm_params_i210(struct e1000_hw *hw)
{
s32 ret_val = E1000_SUCCESS;
struct e1000_nvm_info *nvm = &hw->nvm;
DEBUGFUNC("e1000_init_nvm_params_i210");
ret_val = e1000_init_nvm_params_82575(hw);
nvm->ops.acquire = e1000_acquire_nvm_i210;
nvm->ops.release = e1000_release_nvm_i210;
nvm->ops.read = e1000_read_nvm_srrd_i210;
nvm->ops.write = e1000_write_nvm_srwr_i210;
nvm->ops.valid_led_default = e1000_valid_led_default_i210;
nvm->ops.validate = e1000_validate_nvm_checksum_i210;
nvm->ops.update = e1000_update_nvm_checksum_i210;
return ret_val;
}
/**
* e1000_init_nvm_params_i211 - Initialize i211 NVM function pointers
* @hw: pointer to the HW structure
*
* Initialize the NVM parameters and function pointers for i211.
**/
static s32 e1000_init_nvm_params_i211(struct e1000_hw *hw)
{
struct e1000_nvm_info *nvm = &hw->nvm;
DEBUGFUNC("e1000_init_nvm_params_i211");
nvm->ops.acquire = e1000_acquire_nvm_i210;
nvm->ops.release = e1000_release_nvm_i210;
nvm->ops.read = e1000_read_nvm_i211;
nvm->ops.valid_led_default = e1000_valid_led_default_i210;
nvm->ops.write = e1000_null_write_nvm;
nvm->ops.validate = e1000_null_ops_generic;
nvm->ops.update = e1000_null_ops_generic;
return E1000_SUCCESS;
}
/**
* e1000_init_function_pointers_i210 - Init func ptrs.
* @hw: pointer to the HW structure
*
* Called to initialize all function pointers and parameters.
**/
void e1000_init_function_pointers_i210(struct e1000_hw *hw)
{
e1000_init_function_pointers_82575(hw);
switch (hw->mac.type) {
case e1000_i210:
if (e1000_get_flash_presence_i210(hw))
hw->nvm.ops.init_params = e1000_init_nvm_params_i210;
else
hw->nvm.ops.init_params = e1000_init_nvm_params_i211;
break;
case e1000_i211:
hw->nvm.ops.init_params = e1000_init_nvm_params_i211;
break;
default:
break;
}
return;
}
/**
* e1000_valid_led_default_i210 - Verify a valid default LED config
* @hw: pointer to the HW structure
* @data: pointer to the NVM (EEPROM)
*
* Read the EEPROM for the current default LED configuration. If the
* LED configuration is not valid, set to a valid LED configuration.
**/
static s32 e1000_valid_led_default_i210(struct e1000_hw *hw, u16 *data)
{
s32 ret_val;
DEBUGFUNC("e1000_valid_led_default_i210");
ret_val = hw->nvm.ops.read(hw, NVM_ID_LED_SETTINGS, 1, data);
if (ret_val) {
DEBUGOUT("NVM Read Error\n");
goto out;
}
if (*data == ID_LED_RESERVED_0000 || *data == ID_LED_RESERVED_FFFF) {
switch (hw->phy.media_type) {
case e1000_media_type_internal_serdes:
*data = ID_LED_DEFAULT_I210_SERDES;
break;
case e1000_media_type_copper:
default:
*data = ID_LED_DEFAULT_I210;
break;
}
}
out:
return ret_val;
}
@@ -0,0 +1,80 @@
/******************************************************************************
Copyright (c) 2001-2012, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of the Intel Corporation nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
******************************************************************************/
/*$FreeBSD$*/
#ifndef _E1000_I210_H_
#define _E1000_I210_H_
s32 e1000_update_flash_i210(struct e1000_hw *hw);
s32 e1000_update_nvm_checksum_i210(struct e1000_hw *hw);
s32 e1000_validate_nvm_checksum_i210(struct e1000_hw *hw);
s32 e1000_write_nvm_srwr_i210(struct e1000_hw *hw, u16 offset,
u16 words, u16 *data);
s32 e1000_read_nvm_srrd_i210(struct e1000_hw *hw, u16 offset,
u16 words, u16 *data);
s32 e1000_read_invm_i211(struct e1000_hw *hw, u8 address, u16 *data);
s32 e1000_check_for_copper_link_i210(struct e1000_hw *hw);
s32 e1000_set_ltr_i210(struct e1000_hw *hw, bool link);
s32 e1000_acquire_swfw_sync_i210(struct e1000_hw *hw, u16 mask);
void e1000_release_swfw_sync_i210(struct e1000_hw *hw, u16 mask);
#define E1000_STM_OPCODE 0xDB00
#define E1000_EEPROM_FLASH_SIZE_WORD 0x11
#define INVM_DWORD_TO_RECORD_TYPE(invm_dword) \
(u8)((invm_dword) & 0x7)
#define INVM_DWORD_TO_WORD_ADDRESS(invm_dword) \
(u8)(((invm_dword) & 0x0000FE00) >> 9)
#define INVM_DWORD_TO_WORD_DATA(invm_dword) \
(u16)(((invm_dword) & 0xFFFF0000) >> 16)
enum E1000_INVM_STRUCTURE_TYPE {
E1000_INVM_UNINITIALIZED_STRUCTURE = 0x00,
E1000_INVM_WORD_AUTOLOAD_STRUCTURE = 0x01,
E1000_INVM_CSR_AUTOLOAD_STRUCTURE = 0x02,
E1000_INVM_PHY_REGISTER_AUTOLOAD_STRUCTURE = 0x03,
E1000_INVM_RSA_KEY_SHA256_STRUCTURE = 0x04,
E1000_INVM_INVALIDATED_STRUCTURE = 0x0F,
};
#define E1000_INVM_RSA_KEY_SHA256_DATA_SIZE_IN_DWORDS 8
#define E1000_INVM_CSR_AUTOLOAD_DATA_SIZE_IN_DWORDS 1
#define ID_LED_DEFAULT_I210 ((ID_LED_OFF1_ON2 << 8) | \
(ID_LED_DEF1_DEF2 << 4) | \
(ID_LED_OFF1_OFF2))
#define ID_LED_DEFAULT_I210_SERDES ((ID_LED_DEF1_DEF2 << 8) | \
(ID_LED_DEF1_DEF2 << 4) | \
(ID_LED_DEF1_DEF2))
#endif
@@ -1,6 +1,6 @@
/******************************************************************************
Copyright (c) 2001-2010, Intel Corporation
Copyright (c) 2001-2011, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -30,7 +30,7 @@
POSSIBILITY OF SUCH DAMAGE.
******************************************************************************/
/*$FreeBSD: src/sys/dev/e1000/e1000_ich8lan.c,v 1.5.2.3.2.1 2010/12/21 17:09:25 kensmith Exp $*/
/*$FreeBSD$*/
/*
* 82562G 10/100 Network Connection
@@ -135,20 +135,23 @@ static s32 e1000_sw_lcd_config_ich8lan(struct e1000_hw *hw);
static s32 e1000_set_mdio_slow_mode_hv(struct e1000_hw *hw);
static s32 e1000_k1_workaround_lv(struct e1000_hw *hw);
static void e1000_gate_hw_phy_config_ich8lan(struct e1000_hw *hw, bool gate);
#if defined(NAHUM6_HW) && (defined(LTR_SUPPORT) || defined(OBFF_SUPPORT))
#endif /* NAHUM6_HW && (LTR_SUPPORT || OBFF_SUPPORT) */
/* ICH GbE Flash Hardware Sequencing Flash Status Register bit breakdown */
/* Offset 04h HSFSTS */
union ich8_hws_flash_status {
struct ich8_hsfsts {
u16 flcdone :1; /* bit 0 Flash Cycle Done */
u16 flcerr :1; /* bit 1 Flash Cycle Error */
u16 dael :1; /* bit 2 Direct Access error Log */
u16 berasesz :2; /* bit 4:3 Sector Erase Size */
u16 flcinprog :1; /* bit 5 flash cycle in Progress */
u16 reserved1 :2; /* bit 13:6 Reserved */
u16 reserved2 :6; /* bit 13:6 Reserved */
u16 fldesvalid :1; /* bit 14 Flash Descriptor Valid */
u16 flockdn :1; /* bit 15 Flash Config Lock-Down */
u16 flcdone:1; /* bit 0 Flash Cycle Done */
u16 flcerr:1; /* bit 1 Flash Cycle Error */
u16 dael:1; /* bit 2 Direct Access error Log */
u16 berasesz:2; /* bit 4:3 Sector Erase Size */
u16 flcinprog:1; /* bit 5 flash cycle in Progress */
u16 reserved1:2; /* bit 13:6 Reserved */
u16 reserved2:6; /* bit 13:6 Reserved */
u16 fldesvalid:1; /* bit 14 Flash Descriptor Valid */
u16 flockdn:1; /* bit 15 Flash Config Lock-Down */
} hsf_status;
u16 regval;
};
@@ -157,11 +160,11 @@ union ich8_hws_flash_status {
/* Offset 06h FLCTL */
union ich8_hws_flash_ctrl {
struct ich8_hsflctl {
u16 flcgo :1; /* 0 Flash Cycle Go */
u16 flcycle :2; /* 2:1 Flash Cycle */
u16 reserved :5; /* 7:3 Reserved */
u16 fldbcount :2; /* 9:8 Flash Data Byte Count */
u16 flockdn :6; /* 15:10 Reserved */
u16 flcgo:1; /* 0 Flash Cycle Go */
u16 flcycle:2; /* 2:1 Flash Cycle */
u16 reserved:5; /* 7:3 Reserved */
u16 fldbcount:2; /* 9:8 Flash Data Byte Count */
u16 flockdn:6; /* 15:10 Reserved */
} hsf_ctrl;
u16 regval;
};
@@ -169,14 +172,30 @@ union ich8_hws_flash_ctrl {
/* ICH Flash Region Access Permissions */
union ich8_hws_flash_regacc {
struct ich8_flracc {
u32 grra :8; /* 0:7 GbE region Read Access */
u32 grwa :8; /* 8:15 GbE region Write Access */
u32 gmrag :8; /* 23:16 GbE Master Read Access Grant */
u32 gmwag :8; /* 31:24 GbE Master Write Access Grant */
u32 grra:8; /* 0:7 GbE region Read Access */
u32 grwa:8; /* 8:15 GbE region Write Access */
u32 gmrag:8; /* 23:16 GbE Master Read Access Grant */
u32 gmwag:8; /* 31:24 GbE Master Write Access Grant */
} hsf_flregacc;
u16 regval;
};
static void e1000_toggle_lanphypc_value_ich8lan(struct e1000_hw *hw)
{
u32 ctrl;
DEBUGFUNC("e1000_toggle_lanphypc_value_ich8lan");
ctrl = E1000_READ_REG(hw, E1000_CTRL);
ctrl |= E1000_CTRL_LANPHYPC_OVERRIDE;
ctrl &= ~E1000_CTRL_LANPHYPC_VALUE;
E1000_WRITE_REG(hw, E1000_CTRL, ctrl);
E1000_WRITE_FLUSH(hw);
usec_delay(10);
ctrl &= ~E1000_CTRL_LANPHYPC_OVERRIDE;
E1000_WRITE_REG(hw, E1000_CTRL, ctrl);
}
/**
* e1000_init_phy_params_pchlan - Initialize PHY function pointers
* @hw: pointer to the HW structure
@@ -186,7 +205,6 @@ union ich8_hws_flash_regacc {
static s32 e1000_init_phy_params_pchlan(struct e1000_hw *hw)
{
struct e1000_phy_info *phy = &hw->phy;
u32 ctrl, fwsm;
s32 ret_val = E1000_SUCCESS;
DEBUGFUNC("e1000_init_phy_params_pchlan");
@@ -197,49 +215,45 @@ static s32 e1000_init_phy_params_pchlan(struct e1000_hw *hw)
phy->ops.acquire = e1000_acquire_swflag_ich8lan;
phy->ops.check_reset_block = e1000_check_reset_block_ich8lan;
phy->ops.get_cfg_done = e1000_get_cfg_done_ich8lan;
phy->ops.set_page = e1000_set_page_igp;
phy->ops.read_reg = e1000_read_phy_reg_hv;
phy->ops.read_reg_locked = e1000_read_phy_reg_hv_locked;
phy->ops.read_reg_page = e1000_read_phy_reg_page_hv;
phy->ops.release = e1000_release_swflag_ich8lan;
phy->ops.reset = e1000_phy_hw_reset_ich8lan;
phy->ops.set_d0_lplu_state = e1000_set_lplu_state_pchlan;
phy->ops.set_d3_lplu_state = e1000_set_lplu_state_pchlan;
phy->ops.write_reg = e1000_write_phy_reg_hv;
phy->ops.write_reg_locked = e1000_write_phy_reg_hv_locked;
phy->ops.write_reg_page = e1000_write_phy_reg_page_hv;
phy->ops.power_up = e1000_power_up_phy_copper;
phy->ops.power_down = e1000_power_down_phy_copper_ich8lan;
phy->autoneg_mask = AUTONEG_ADVERTISE_SPEED_DEFAULT;
if (!hw->phy.ops.check_reset_block(hw)) {
u32 fwsm = E1000_READ_REG(hw, E1000_FWSM);
/*
* The MAC-PHY interconnect may still be in SMBus mode
* after Sx->S0. If the manageability engine (ME) is
* disabled, then toggle the LANPHYPC Value bit to force
* the interconnect to PCIe mode.
* The MAC-PHY interconnect may still be in SMBus mode after
* Sx->S0. If resetting the PHY is not blocked, toggle the
* LANPHYPC Value bit to force the interconnect to PCIe mode.
*/
fwsm = E1000_READ_REG(hw, E1000_FWSM);
if (!(fwsm & E1000_ICH_FWSM_FW_VALID) &&
!(hw->phy.ops.check_reset_block(hw))) {
ctrl = E1000_READ_REG(hw, E1000_CTRL);
ctrl |= E1000_CTRL_LANPHYPC_OVERRIDE;
ctrl &= ~E1000_CTRL_LANPHYPC_VALUE;
E1000_WRITE_REG(hw, E1000_CTRL, ctrl);
usec_delay(10);
ctrl &= ~E1000_CTRL_LANPHYPC_OVERRIDE;
E1000_WRITE_REG(hw, E1000_CTRL, ctrl);
e1000_toggle_lanphypc_value_ich8lan(hw);
msec_delay(50);
/*
* Gate automatic PHY configuration by hardware on
* non-managed 82579
*/
if (hw->mac.type == e1000_pch2lan)
if ((hw->mac.type == e1000_pch2lan) &&
!(fwsm & E1000_ICH_FWSM_FW_VALID))
e1000_gate_hw_phy_config_ich8lan(hw, TRUE);
}
/*
* Reset the PHY before any acccess to it. Doing so, ensures that
* the PHY is in a known good state before we read/write PHY registers.
* The generic reset is sufficient here, because we haven't determined
* the PHY type yet.
* Reset the PHY before any access to it. Doing so, ensures
* that the PHY is in a known good state before we read/write
* PHY registers. The generic reset is sufficient here,
* because we haven't determined the PHY type yet.
*/
ret_val = e1000_phy_hw_reset_generic(hw);
if (ret_val)
@@ -251,6 +265,7 @@ static s32 e1000_init_phy_params_pchlan(struct e1000_hw *hw)
msec_delay(10);
e1000_gate_hw_phy_config_ich8lan(hw, FALSE);
}
}
phy->id = e1000_phy_unknown;
switch (hw->mac.type) {
@@ -477,7 +492,6 @@ out:
static s32 e1000_init_mac_params_ich8lan(struct e1000_hw *hw)
{
struct e1000_mac_info *mac = &hw->mac;
u16 pci_cfg;
DEBUGFUNC("e1000_init_mac_params_ich8lan");
@@ -549,9 +563,6 @@ static s32 e1000_init_mac_params_ich8lan(struct e1000_hw *hw)
e1000_update_mc_addr_list_pch2lan;
/* fall-through */
case e1000_pchlan:
/* save PCH revision_id */
e1000_read_pci_cfg(hw, 0x2, &pci_cfg);
hw->revision_id = (u8)(pci_cfg &= 0x000F);
/* check management mode */
mac->ops.check_mng_mode = e1000_check_mng_mode_pchlan;
/* ID LED init */
@@ -568,6 +579,11 @@ static s32 e1000_init_mac_params_ich8lan(struct e1000_hw *hw)
break;
}
#if defined(NAHUM6_HW) && (defined(LTR_SUPPORT) || defined(OBFF_SUPPORT))
if (mac->type == e1000_pch_lpt) {
}
#endif /* NAHUM6_HW && (LTR_SUPPORT || OBFF_SUPPORT) */
/* Enable PCS Lock-loss workaround for ICH8 */
if (mac->type == e1000_ich8lan)
e1000_set_kmrn_lock_loss_workaround_ich8lan(hw, TRUE);
@@ -589,6 +605,7 @@ static s32 e1000_init_mac_params_ich8lan(struct e1000_hw *hw)
**/
static s32 e1000_set_eee_pchlan(struct e1000_hw *hw)
{
struct e1000_dev_spec_ich8lan *dev_spec = &hw->dev_spec.ich8lan;
s32 ret_val = E1000_SUCCESS;
u16 phy_reg;
@@ -601,7 +618,7 @@ static s32 e1000_set_eee_pchlan(struct e1000_hw *hw)
if (ret_val)
goto out;
if (hw->dev_spec.ich8lan.eee_disable)
if (dev_spec->eee_disable)
phy_reg &= ~I82579_LPI_CTRL_ENABLE_MASK;
else
phy_reg |= I82579_LPI_CTRL_ENABLE_MASK;
@@ -624,6 +641,7 @@ static s32 e1000_check_for_copper_link_ich8lan(struct e1000_hw *hw)
struct e1000_mac_info *mac = &hw->mac;
s32 ret_val;
bool link;
u16 phy_reg;
DEBUGFUNC("e1000_check_for_copper_link_ich8lan");
@@ -653,21 +671,46 @@ static s32 e1000_check_for_copper_link_ich8lan(struct e1000_hw *hw)
goto out;
}
#if defined(NAHUM6_HW) && (defined(LTR_SUPPORT) || defined(OBFF_SUPPORT))
if (hw->mac.type == e1000_pch_lpt) {
}
#endif /* NAHUM6_HW && (LTR_SUPPORT || OBFF_SUPPORT) */
if (!link)
goto out; /* No link detected */
mac->get_link_status = FALSE;
switch (hw->mac.type) {
case e1000_pch2lan:
ret_val = e1000_k1_workaround_lv(hw);
if (ret_val)
goto out;
/* fall-thru */
case e1000_pchlan:
if (hw->phy.type == e1000_phy_82578) {
ret_val = e1000_link_stall_workaround_hv(hw);
if (ret_val)
goto out;
}
if (hw->mac.type == e1000_pch2lan) {
ret_val = e1000_k1_workaround_lv(hw);
if (ret_val)
goto out;
/*
* Workaround for PCHx parts in half-duplex:
* Set the number of preambles removed from the packet
* when it is passed from the PHY to the MAC to prevent
* the MAC from misinterpreting the packet type.
*/
hw->phy.ops.read_reg(hw, HV_KMRN_FIFO_CTRLSTA, &phy_reg);
phy_reg &= ~HV_KMRN_FIFO_CTRLSTA_PREAMBLE_MASK;
if ((E1000_READ_REG(hw, E1000_STATUS) & E1000_STATUS_FD) !=
E1000_STATUS_FD)
phy_reg |= (1 << HV_KMRN_FIFO_CTRLSTA_PREAMBLE_SHIFT);
hw->phy.ops.write_reg(hw, HV_KMRN_FIFO_CTRLSTA, phy_reg);
break;
default:
break;
}
/*
@@ -695,7 +738,7 @@ static s32 e1000_check_for_copper_link_ich8lan(struct e1000_hw *hw)
* of MAC speed/duplex configuration. So we only need to
* configure Collision Distance in the MAC.
*/
e1000_config_collision_dist_generic(hw);
hw->mac.ops.config_collision_dist(hw);
/*
* Configure Flow Control now that Auto-Neg has completed.
@@ -794,7 +837,7 @@ static s32 e1000_acquire_swflag_ich8lan(struct e1000_hw *hw)
}
if (!timeout) {
DEBUGOUT("SW/FW/HW has locked the resource for too long.\n");
DEBUGOUT("SW has already locked the resource.\n");
ret_val = -E1000_ERR_CONFIG;
goto out;
}
@@ -814,7 +857,8 @@ static s32 e1000_acquire_swflag_ich8lan(struct e1000_hw *hw)
}
if (!timeout) {
DEBUGOUT("Failed to acquire the semaphore.\n");
DEBUGOUT2("Failed to acquire the semaphore, FW or HW has it: FWSM=0x%8.8x EXTCNF_CTRL=0x%8.8x)\n",
E1000_READ_REG(hw, E1000_FWSM), extcnf_ctrl);
extcnf_ctrl &= ~E1000_EXTCNF_CTRL_SWFLAG;
E1000_WRITE_REG(hw, E1000_EXTCNF_CTRL, extcnf_ctrl);
ret_val = -E1000_ERR_CONFIG;
@@ -966,19 +1010,35 @@ static void e1000_update_mc_addr_list_pch2lan(struct e1000_hw *hw,
u8 *mc_addr_list,
u32 mc_addr_count)
{
u16 phy_reg = 0;
int i;
s32 ret_val;
DEBUGFUNC("e1000_update_mc_addr_list_pch2lan");
e1000_update_mc_addr_list_generic(hw, mc_addr_list, mc_addr_count);
ret_val = hw->phy.ops.acquire(hw);
if (ret_val)
return;
ret_val = e1000_enable_phy_wakeup_reg_access_bm(hw, &phy_reg);
if (ret_val)
goto release;
for (i = 0; i < hw->mac.mta_reg_count; i++) {
hw->phy.ops.write_reg(hw, BM_MTA(i),
(u16)(hw->mac.mta_shadow[i] & 0xFFFF));
hw->phy.ops.write_reg(hw, (BM_MTA(i) + 1),
hw->phy.ops.write_reg_page(hw, BM_MTA(i),
(u16)(hw->mac.mta_shadow[i] &
0xFFFF));
hw->phy.ops.write_reg_page(hw, (BM_MTA(i) + 1),
(u16)((hw->mac.mta_shadow[i] >> 16) &
0xFFFF));
}
e1000_disable_phy_wakeup_reg_access_bm(hw, &phy_reg);
release:
hw->phy.ops.release(hw);
}
/**
@@ -995,9 +1055,6 @@ static s32 e1000_check_reset_block_ich8lan(struct e1000_hw *hw)
DEBUGFUNC("e1000_check_reset_block_ich8lan");
if (hw->phy.reset_disable)
return E1000_BLK_PHY_RESET;
fwsm = E1000_READ_REG(hw, E1000_FWSM);
return (fwsm & E1000_ICH_FWSM_RSPCIPHY) ? E1000_SUCCESS
@@ -1259,8 +1316,7 @@ s32 e1000_configure_k1_ich8lan(struct e1000_hw *hw, bool k1_enable)
DEBUGFUNC("e1000_configure_k1_ich8lan");
ret_val = e1000_read_kmrn_reg_locked(hw,
E1000_KMRNCTRLSTA_K1_CONFIG,
ret_val = e1000_read_kmrn_reg_locked(hw, E1000_KMRNCTRLSTA_K1_CONFIG,
&kmrn_reg);
if (ret_val)
goto out;
@@ -1270,8 +1326,7 @@ s32 e1000_configure_k1_ich8lan(struct e1000_hw *hw, bool k1_enable)
else
kmrn_reg &= ~E1000_KMRNCTRLSTA_K1_ENABLE;
ret_val = e1000_write_kmrn_reg_locked(hw,
E1000_KMRNCTRLSTA_K1_CONFIG,
ret_val = e1000_write_kmrn_reg_locked(hw, E1000_KMRNCTRLSTA_K1_CONFIG,
kmrn_reg);
if (ret_val)
goto out;
@@ -1285,9 +1340,11 @@ s32 e1000_configure_k1_ich8lan(struct e1000_hw *hw, bool k1_enable)
E1000_WRITE_REG(hw, E1000_CTRL, reg);
E1000_WRITE_REG(hw, E1000_CTRL_EXT, ctrl_ext | E1000_CTRL_EXT_SPD_BYPS);
E1000_WRITE_FLUSH(hw);
usec_delay(20);
E1000_WRITE_REG(hw, E1000_CTRL, ctrl_reg);
E1000_WRITE_REG(hw, E1000_CTRL_EXT, ctrl_ext);
E1000_WRITE_FLUSH(hw);
usec_delay(20);
out:
@@ -1303,7 +1360,7 @@ out:
* collectively called OEM bits. The OEM Write Enable bit and SW Config bit
* in NVM determines whether HW should configure LPLU and Gbe Disable.
**/
s32 e1000_oem_bits_config_ich8lan(struct e1000_hw *hw, bool d0_state)
static s32 e1000_oem_bits_config_ich8lan(struct e1000_hw *hw, bool d0_state)
{
s32 ret_val = 0;
u32 mac_reg;
@@ -1342,16 +1399,20 @@ s32 e1000_oem_bits_config_ich8lan(struct e1000_hw *hw, bool d0_state)
if (mac_reg & E1000_PHY_CTRL_D0A_LPLU)
oem_reg |= HV_OEM_BITS_LPLU;
} else {
if (mac_reg & E1000_PHY_CTRL_NOND0A_GBE_DISABLE)
oem_reg |= HV_OEM_BITS_GBE_DIS;
if (mac_reg & E1000_PHY_CTRL_NOND0A_LPLU)
oem_reg |= HV_OEM_BITS_LPLU;
}
/* Restart auto-neg to activate the bits */
/* Set Restart auto-neg to activate the bits */
if (!hw->phy.ops.check_reset_block(hw))
oem_reg |= HV_OEM_BITS_RESTART_AN;
} else {
if (mac_reg & (E1000_PHY_CTRL_GBE_DISABLE |
E1000_PHY_CTRL_NOND0A_GBE_DISABLE))
oem_reg |= HV_OEM_BITS_GBE_DIS;
if (mac_reg & (E1000_PHY_CTRL_D0A_LPLU |
E1000_PHY_CTRL_NOND0A_LPLU))
oem_reg |= HV_OEM_BITS_LPLU;
}
ret_val = hw->phy.ops.write_reg_locked(hw, HV_OEM_BITS, oem_reg);
out:
@@ -1361,20 +1422,6 @@ out:
}
/**
* e1000_hv_phy_powerdown_workaround_ich8lan - Power down workaround on Sx
* @hw: pointer to the HW structure
**/
s32 e1000_hv_phy_powerdown_workaround_ich8lan(struct e1000_hw *hw)
{
DEBUGFUNC("e1000_hv_phy_powerdown_workaround_ich8lan");
if ((hw->phy.type != e1000_phy_82577) || (hw->revision_id > 2))
return E1000_SUCCESS;
return hw->phy.ops.write_reg(hw, PHY_REG(768, 25), 0x0444);
}
/**
* e1000_set_mdio_slow_mode_hv - Set slow MDIO access mode
* @hw: pointer to the HW structure
@@ -1418,32 +1465,6 @@ static s32 e1000_hv_phy_workarounds_ich8lan(struct e1000_hw *hw)
goto out;
}
/* Hanksville M Phy init for IEEE. */
if ((hw->revision_id == 2) &&
(hw->phy.type == e1000_phy_82577) &&
((hw->phy.revision == 2) || (hw->phy.revision == 3))) {
hw->phy.ops.write_reg(hw, 0x10, 0x8823);
hw->phy.ops.write_reg(hw, 0x11, 0x0018);
hw->phy.ops.write_reg(hw, 0x10, 0x8824);
hw->phy.ops.write_reg(hw, 0x11, 0x0016);
hw->phy.ops.write_reg(hw, 0x10, 0x8825);
hw->phy.ops.write_reg(hw, 0x11, 0x001A);
hw->phy.ops.write_reg(hw, 0x10, 0x888C);
hw->phy.ops.write_reg(hw, 0x11, 0x0007);
hw->phy.ops.write_reg(hw, 0x10, 0x888D);
hw->phy.ops.write_reg(hw, 0x11, 0x0007);
hw->phy.ops.write_reg(hw, 0x10, 0x888E);
hw->phy.ops.write_reg(hw, 0x11, 0x0007);
hw->phy.ops.write_reg(hw, 0x10, 0x8827);
hw->phy.ops.write_reg(hw, 0x11, 0x0001);
hw->phy.ops.write_reg(hw, 0x10, 0x8835);
hw->phy.ops.write_reg(hw, 0x11, 0x0001);
hw->phy.ops.write_reg(hw, 0x10, 0x8834);
hw->phy.ops.write_reg(hw, 0x11, 0x0001);
hw->phy.ops.write_reg(hw, 0x10, 0x8833);
hw->phy.ops.write_reg(hw, 0x11, 0x0002);
}
if (((hw->phy.type == e1000_phy_82577) &&
((hw->phy.revision == 1) || (hw->phy.revision == 2))) ||
((hw->phy.type == e1000_phy_82578) && (hw->phy.revision == 1))) {
@@ -1453,26 +1474,13 @@ static s32 e1000_hv_phy_workarounds_ich8lan(struct e1000_hw *hw)
goto out;
/* Preamble tuning for SSC */
ret_val = hw->phy.ops.write_reg(hw, PHY_REG(770, 16), 0xA204);
ret_val = hw->phy.ops.write_reg(hw, HV_KMRN_FIFO_CTRLSTA,
0xA204);
if (ret_val)
goto out;
}
if (hw->phy.type == e1000_phy_82578) {
if (hw->revision_id < 3) {
/* PHY config */
ret_val = hw->phy.ops.write_reg(hw, (1 << 6) | 0x29,
0x66C0);
if (ret_val)
goto out;
/* PHY config */
ret_val = hw->phy.ops.write_reg(hw, (1 << 6) | 0x1E,
0xFFFF);
if (ret_val)
goto out;
}
/*
* Return registers to default by doing a soft reset then
* writing 0x3140 to the control register.
@@ -1484,21 +1492,6 @@ static s32 e1000_hv_phy_workarounds_ich8lan(struct e1000_hw *hw)
}
}
if ((hw->revision_id == 2) &&
(hw->phy.type == e1000_phy_82577) &&
((hw->phy.revision == 2) || (hw->phy.revision == 3))) {
/*
* Workaround for OEM (GbE) not operating after reset -
* restart AN (twice)
*/
ret_val = hw->phy.ops.write_reg(hw, PHY_REG(768, 25), 0x0400);
if (ret_val)
goto out;
ret_val = hw->phy.ops.write_reg(hw, PHY_REG(768, 25), 0x0400);
if (ret_val)
goto out;
}
/* Select page 0 */
ret_val = hw->phy.ops.acquire(hw);
if (ret_val)
@@ -1522,11 +1515,10 @@ static s32 e1000_hv_phy_workarounds_ich8lan(struct e1000_hw *hw)
ret_val = hw->phy.ops.acquire(hw);
if (ret_val)
goto out;
ret_val = hw->phy.ops.read_reg_locked(hw, BM_PORT_GEN_CFG_REG,
&phy_data);
ret_val = hw->phy.ops.read_reg_locked(hw, BM_PORT_GEN_CFG, &phy_data);
if (ret_val)
goto release;
ret_val = hw->phy.ops.write_reg_locked(hw, BM_PORT_GEN_CFG_REG,
ret_val = hw->phy.ops.write_reg_locked(hw, BM_PORT_GEN_CFG,
phy_data & 0x00FF);
release:
hw->phy.ops.release(hw);
@@ -1541,19 +1533,38 @@ out:
void e1000_copy_rx_addrs_to_phy_ich8lan(struct e1000_hw *hw)
{
u32 mac_reg;
u16 i;
u16 i, phy_reg = 0;
s32 ret_val;
DEBUGFUNC("e1000_copy_rx_addrs_to_phy_ich8lan");
ret_val = hw->phy.ops.acquire(hw);
if (ret_val)
return;
ret_val = e1000_enable_phy_wakeup_reg_access_bm(hw, &phy_reg);
if (ret_val)
goto release;
/* Copy both RAL/H (rar_entry_count) and SHRAL/H (+4) to PHY */
for (i = 0; i < (hw->mac.rar_entry_count + 4); i++) {
mac_reg = E1000_READ_REG(hw, E1000_RAL(i));
hw->phy.ops.write_reg(hw, BM_RAR_L(i), (u16)(mac_reg & 0xFFFF));
hw->phy.ops.write_reg(hw, BM_RAR_M(i), (u16)((mac_reg >> 16) & 0xFFFF));
hw->phy.ops.write_reg_page(hw, BM_RAR_L(i),
(u16)(mac_reg & 0xFFFF));
hw->phy.ops.write_reg_page(hw, BM_RAR_M(i),
(u16)((mac_reg >> 16) & 0xFFFF));
mac_reg = E1000_READ_REG(hw, E1000_RAH(i));
hw->phy.ops.write_reg(hw, BM_RAR_H(i), (u16)(mac_reg & 0xFFFF));
hw->phy.ops.write_reg(hw, BM_RAR_CTRL(i), (u16)((mac_reg >> 16) & 0x8000));
hw->phy.ops.write_reg_page(hw, BM_RAR_H(i),
(u16)(mac_reg & 0xFFFF));
hw->phy.ops.write_reg_page(hw, BM_RAR_CTRL(i),
(u16)((mac_reg & E1000_RAH_AV)
>> 16));
}
e1000_disable_phy_wakeup_reg_access_bm(hw, &phy_reg);
release:
hw->phy.ops.release(hw);
}
static u32 e1000_calc_rx_da_crc(u8 mac[])
@@ -1594,7 +1605,8 @@ s32 e1000_lv_jumbo_workaround_ich8lan(struct e1000_hw *hw, bool enable)
/* disable Rx path while enabling/disabling workaround */
hw->phy.ops.read_reg(hw, PHY_REG(769, 20), &phy_reg);
ret_val = hw->phy.ops.write_reg(hw, PHY_REG(769, 20), phy_reg | (1 << 14));
ret_val = hw->phy.ops.write_reg(hw, PHY_REG(769, 20),
phy_reg | (1 << 14));
if (ret_val)
goto out;
@@ -1676,11 +1688,12 @@ s32 e1000_lv_jumbo_workaround_ich8lan(struct e1000_hw *hw, bool enable)
ret_val = hw->phy.ops.write_reg(hw, PHY_REG(776, 20), data);
if (ret_val)
goto out;
ret_val = hw->phy.ops.write_reg(hw, PHY_REG(776, 23), 0xFE00);
ret_val = hw->phy.ops.write_reg(hw, PHY_REG(776, 23), 0xF100);
if (ret_val)
goto out;
hw->phy.ops.read_reg(hw, HV_PM_CTRL, &data);
ret_val = hw->phy.ops.write_reg(hw, HV_PM_CTRL, data | (1 << 10));
ret_val = hw->phy.ops.write_reg(hw, HV_PM_CTRL, data |
(1 << 10));
if (ret_val)
goto out;
} else {
@@ -1737,13 +1750,15 @@ s32 e1000_lv_jumbo_workaround_ich8lan(struct e1000_hw *hw, bool enable)
if (ret_val)
goto out;
hw->phy.ops.read_reg(hw, HV_PM_CTRL, &data);
ret_val = hw->phy.ops.write_reg(hw, HV_PM_CTRL, data & ~(1 << 10));
ret_val = hw->phy.ops.write_reg(hw, HV_PM_CTRL, data &
~(1 << 10));
if (ret_val)
goto out;
}
/* re-enable Rx path after enabling/disabling workaround */
ret_val = hw->phy.ops.write_reg(hw, PHY_REG(769, 20), phy_reg & ~(1 << 14));
ret_val = hw->phy.ops.write_reg(hw, PHY_REG(769, 20), phy_reg &
~(1 << 14));
out:
return ret_val;
@@ -1765,6 +1780,28 @@ static s32 e1000_lv_phy_workarounds_ich8lan(struct e1000_hw *hw)
/* Set MDIO slow mode before any other MDIO access */
ret_val = e1000_set_mdio_slow_mode_hv(hw);
ret_val = hw->phy.ops.acquire(hw);
if (ret_val)
goto out;
ret_val = hw->phy.ops.write_reg_locked(hw, I82579_EMI_ADDR,
I82579_MSE_THRESHOLD);
if (ret_val)
goto release;
/* set MSE higher to enable link to stay up when noise is high */
ret_val = hw->phy.ops.write_reg_locked(hw, I82579_EMI_DATA,
0x0034);
if (ret_val)
goto release;
ret_val = hw->phy.ops.write_reg_locked(hw, I82579_EMI_ADDR,
I82579_MSE_LINK_DOWN);
if (ret_val)
goto release;
/* drop link after 5 times MSE threshold was reached */
ret_val = hw->phy.ops.write_reg_locked(hw, I82579_EMI_DATA,
0x0005);
release:
hw->phy.ops.release(hw);
out:
return ret_val;
}
@@ -1780,6 +1817,7 @@ static s32 e1000_k1_workaround_lv(struct e1000_hw *hw)
s32 ret_val = E1000_SUCCESS;
u16 status_reg = 0;
u32 mac_reg;
u16 phy_reg;
DEBUGFUNC("e1000_k1_workaround_lv");
@@ -1796,12 +1834,19 @@ static s32 e1000_k1_workaround_lv(struct e1000_hw *hw)
mac_reg = E1000_READ_REG(hw, E1000_FEXTNVM4);
mac_reg &= ~E1000_FEXTNVM4_BEACON_DURATION_MASK;
if (status_reg & HV_M_STATUS_SPEED_1000)
mac_reg |= E1000_FEXTNVM4_BEACON_DURATION_8USEC;
else
mac_reg |= E1000_FEXTNVM4_BEACON_DURATION_16USEC;
ret_val = hw->phy.ops.read_reg(hw, I82579_LPI_CTRL, &phy_reg);
if (ret_val)
goto out;
if (status_reg & HV_M_STATUS_SPEED_1000) {
mac_reg |= E1000_FEXTNVM4_BEACON_DURATION_8USEC;
phy_reg &= ~I82579_LPI_CTRL_FORCE_PLL_LOCK_COUNT;
} else {
mac_reg |= E1000_FEXTNVM4_BEACON_DURATION_16USEC;
phy_reg |= I82579_LPI_CTRL_FORCE_PLL_LOCK_COUNT;
}
E1000_WRITE_REG(hw, E1000_FEXTNVM4, mac_reg);
ret_val = hw->phy.ops.write_reg(hw, I82579_LPI_CTRL, phy_reg);
}
out:
@@ -1836,34 +1881,6 @@ static void e1000_gate_hw_phy_config_ich8lan(struct e1000_hw *hw, bool gate)
return;
}
/**
* e1000_hv_phy_tuning_workaround_ich8lan - This is a Phy tuning work around
* needed for Nahum3 + Hanksville testing, requested by HW team
**/
static s32 e1000_hv_phy_tuning_workaround_ich8lan(struct e1000_hw *hw)
{
s32 ret_val = E1000_SUCCESS;
DEBUGFUNC("e1000_hv_phy_tuning_workaround_ich8lan");
ret_val = hw->phy.ops.write_reg(hw, PHY_REG(769, 25), 0x4431);
if (ret_val)
goto out;
ret_val = hw->phy.ops.write_reg(hw, PHY_REG(770, 16), 0xA204);
if (ret_val)
goto out;
ret_val = hw->phy.ops.write_reg(hw, (1 << 6) | 0x29, 0x66C0);
if (ret_val)
goto out;
ret_val = hw->phy.ops.write_reg(hw, (1 << 6) | 0x1E, 0xFFFF);
out:
return ret_val;
}
/**
* e1000_lan_init_done_ich8lan - Check for PHY config completion
* @hw: pointer to the HW structure
@@ -1931,16 +1948,13 @@ static s32 e1000_post_phy_reset_ich8lan(struct e1000_hw *hw)
break;
}
if (hw->device_id == E1000_DEV_ID_ICH10_HANKSVILLE) {
ret_val = e1000_hv_phy_tuning_workaround_ich8lan(hw);
if (ret_val)
goto out;
/* Clear the host wakeup bit after lcd reset */
if (hw->mac.type >= e1000_pchlan) {
hw->phy.ops.read_reg(hw, BM_PORT_GEN_CFG, &reg);
reg &= ~BM_WUC_HOST_WU_BIT;
hw->phy.ops.write_reg(hw, BM_PORT_GEN_CFG, reg);
}
/* Dummy read to clear the phy wakeup bit after lcd reset */
if (hw->mac.type >= e1000_pchlan)
hw->phy.ops.read_reg(hw, BM_WUC, &reg);
/* Configure the LCD with the extended configuration region in NVM */
ret_val = e1000_sw_lcd_config_ich8lan(hw);
if (ret_val)
@@ -2031,7 +2045,9 @@ static s32 e1000_set_lplu_state_pchlan(struct e1000_hw *hw, bool active)
else
oem_reg &= ~HV_OEM_BITS_LPLU;
if (!hw->phy.ops.check_reset_block(hw))
oem_reg |= HV_OEM_BITS_RESTART_AN;
ret_val = hw->phy.ops.write_reg(hw, HV_OEM_BITS, oem_reg);
out:
@@ -2264,8 +2280,7 @@ static s32 e1000_valid_nvm_bank_detect_ich8lan(struct e1000_hw *hw, u32 *bank)
goto out;
}
DEBUGOUT("Unable to determine valid NVM bank via EEC - "
"reading flash signature\n");
DEBUGOUT("Unable to determine valid NVM bank via EEC - reading flash signature\n");
/* fall-thru */
default:
/* set bank to 0 in case flash read fails */
@@ -2343,8 +2358,7 @@ static s32 e1000_read_nvm_ich8lan(struct e1000_hw *hw, u16 offset, u16 words,
ret_val = E1000_SUCCESS;
for (i = 0; i < words; i++) {
if ((dev_spec->shadow_ram) &&
(dev_spec->shadow_ram[offset+i].modified)) {
if (dev_spec->shadow_ram[offset+i].modified) {
data[i] = dev_spec->shadow_ram[offset+i].value;
} else {
ret_val = e1000_read_flash_word_ich8lan(hw,
@@ -2383,8 +2397,7 @@ static s32 e1000_flash_cycle_init_ich8lan(struct e1000_hw *hw)
/* Check if the flash descriptor is valid */
if (hsfsts.hsf_status.fldesvalid == 0) {
DEBUGOUT("Flash descriptor invalid. "
"SW Sequencing must be used.");
DEBUGOUT("Flash descriptor invalid. SW Sequencing must be used.\n");
goto out;
}
@@ -2437,7 +2450,7 @@ static s32 e1000_flash_cycle_init_ich8lan(struct e1000_hw *hw)
E1000_WRITE_FLASH_REG16(hw, ICH_FLASH_HSFSTS,
hsfsts.regval);
} else {
DEBUGOUT("Flash controller busy, cannot get access");
DEBUGOUT("Flash controller busy, cannot get access\n");
}
}
@@ -2605,8 +2618,7 @@ static s32 e1000_read_flash_data_ich8lan(struct e1000_hw *hw, u32 offset,
/* Repeat for some time before giving up. */
continue;
} else if (hsfsts.hsf_status.flcdone == 0) {
DEBUGOUT("Timeout error - flash cycle "
"did not complete.");
DEBUGOUT("Timeout error - flash cycle did not complete.\n");
break;
}
}
@@ -2930,8 +2942,7 @@ static s32 e1000_write_flash_data_ich8lan(struct e1000_hw *hw, u32 offset,
/* Repeat for some time before giving up. */
continue;
if (hsfsts.hsf_status.flcdone == 0) {
DEBUGOUT("Timeout error - flash cycle "
"did not complete.");
DEBUGOUT("Timeout error - flash cycle did not complete.\n");
break;
}
} while (count++ < ICH_FLASH_CYCLE_REPEAT_COUNT);
@@ -3130,8 +3141,7 @@ static s32 e1000_valid_led_default_ich8lan(struct e1000_hw *hw, u16 *data)
goto out;
}
if (*data == ID_LED_RESERVED_0000 ||
*data == ID_LED_RESERVED_FFFF)
if (*data == ID_LED_RESERVED_0000 || *data == ID_LED_RESERVED_FFFF)
*data = ID_LED_DEFAULT_ICH8LAN;
out:
@@ -3218,7 +3228,7 @@ out:
* @hw: pointer to the HW structure
*
* ICH8 use the PCI Express bus, but does not contain a PCI Express Capability
* register, so the bus width is hard coded.
* register, so the the bus width is hard coded.
**/
static s32 e1000_get_bus_info_ich8lan(struct e1000_hw *hw)
{
@@ -3320,10 +3330,11 @@ static s32 e1000_reset_hw_ich8lan(struct e1000_hw *hw)
ret_val = e1000_acquire_swflag_ich8lan(hw);
DEBUGOUT("Issuing a global reset to ich8lan\n");
E1000_WRITE_REG(hw, E1000_CTRL, (ctrl | E1000_CTRL_RST));
/* cannot issue a flush here because it hangs the hardware */
msec_delay(20);
if (!ret_val)
e1000_release_swflag_ich8lan(hw);
E1000_MUTEX_UNLOCK(&hw->dev_spec.ich8lan.swflag_mutex);
if (ctrl & E1000_CTRL_PHY_RST) {
ret_val = hw->phy.ops.get_cfg_done(hw);
@@ -3393,11 +3404,13 @@ static s32 e1000_init_hw_ich8lan(struct e1000_hw *hw)
/*
* The 82578 Rx buffer will stall if wakeup is enabled in host and
* the ME. Reading the BM_WUC register will clear the host wakeup bit.
* the ME. Disable wakeup by clearing the host wakeup bit.
* Reset the phy after disabling host wakeup to reset the Rx buffer.
*/
if (hw->phy.type == e1000_phy_82578) {
hw->phy.ops.read_reg(hw, BM_WUC, &i);
hw->phy.ops.read_reg(hw, BM_PORT_GEN_CFG, &i);
i &= ~BM_WUC_HOST_WU_BIT;
hw->phy.ops.write_reg(hw, BM_PORT_GEN_CFG, i);
ret_val = e1000_phy_hw_reset_ich8lan(hw);
if (ret_val)
return ret_val;
@@ -3863,7 +3876,7 @@ out:
* LPLU, Gig disable, MDIC PHY reset):
* 1) Set Kumeran Near-end loopback
* 2) Clear Kumeran Near-end loopback
* Should only be called for ICH8[m] devices with IGP_3 Phy.
* Should only be called for ICH8[m] devices with any 1G Phy.
**/
void e1000_gig_downshift_workaround_ich8lan(struct e1000_hw *hw)
{
@@ -3873,7 +3886,7 @@ void e1000_gig_downshift_workaround_ich8lan(struct e1000_hw *hw)
DEBUGFUNC("e1000_gig_downshift_workaround_ich8lan");
if ((hw->mac.type != e1000_ich8lan) ||
(hw->phy.type != e1000_phy_igp_3))
(hw->phy.type == e1000_phy_ife))
goto out;
ret_val = e1000_read_kmrn_reg_generic(hw, E1000_KMRNCTRLSTA_DIAG_OFFSET,
@@ -3895,29 +3908,32 @@ out:
}
/**
* e1000_disable_gig_wol_ich8lan - disable gig during WoL
* e1000_suspend_workarounds_ich8lan - workarounds needed during S0->Sx
* @hw: pointer to the HW structure
*
* During S0 to Sx transition, it is possible the link remains at gig
* instead of negotiating to a lower speed. Before going to Sx, set
* 'LPLU Enabled' and 'Gig Disable' to force link speed negotiation
* to a lower speed.
*
* Should only be called for applicable parts.
* 'Gig Disable' to force link speed negotiation to a lower speed based on
* the LPLU setting in the NVM or custom setting. For PCH and newer parts,
* the OEM bits PHY register (LED, GbE disable and LPLU configurations) also
* needs to be written.
**/
void e1000_disable_gig_wol_ich8lan(struct e1000_hw *hw)
void e1000_suspend_workarounds_ich8lan(struct e1000_hw *hw)
{
u32 phy_ctrl;
s32 ret_val;
DEBUGFUNC("e1000_disable_gig_wol_ich8lan");
DEBUGFUNC("e1000_suspend_workarounds_ich8lan");
phy_ctrl = E1000_READ_REG(hw, E1000_PHY_CTRL);
phy_ctrl |= E1000_PHY_CTRL_D0A_LPLU | E1000_PHY_CTRL_GBE_DISABLE;
phy_ctrl |= E1000_PHY_CTRL_GBE_DISABLE;
E1000_WRITE_REG(hw, E1000_PHY_CTRL, phy_ctrl);
if (hw->mac.type == e1000_ich8lan)
e1000_gig_downshift_workaround_ich8lan(hw);
if (hw->mac.type >= e1000_pchlan) {
e1000_oem_bits_config_ich8lan(hw, FALSE);
e1000_phy_hw_reset_ich8lan(hw);
ret_val = hw->phy.ops.acquire(hw);
if (ret_val)
return;
@@ -3928,6 +3944,58 @@ void e1000_disable_gig_wol_ich8lan(struct e1000_hw *hw)
return;
}
/**
* e1000_resume_workarounds_pchlan - workarounds needed during Sx->S0
* @hw: pointer to the HW structure
*
* During Sx to S0 transitions on non-managed devices or managed devices
* on which PHY resets are not blocked, if the PHY registers cannot be
* accessed properly by the s/w toggle the LANPHYPC value to power cycle
* the PHY.
**/
void e1000_resume_workarounds_pchlan(struct e1000_hw *hw)
{
u16 phy_id1, phy_id2;
s32 ret_val;
DEBUGFUNC("e1000_resume_workarounds_pchlan");
if ((hw->mac.type != e1000_pch2lan) ||
hw->phy.ops.check_reset_block(hw))
return;
ret_val = hw->phy.ops.acquire(hw);
if (ret_val) {
DEBUGOUT("Failed to acquire PHY semaphore in resume\n");
return;
}
/* Test access to the PHY registers by reading the ID regs */
ret_val = hw->phy.ops.read_reg_locked(hw, PHY_ID1, &phy_id1);
if (ret_val)
goto release;
ret_val = hw->phy.ops.read_reg_locked(hw, PHY_ID2, &phy_id2);
if (ret_val)
goto release;
if (hw->phy.id == ((u32)(phy_id1 << 16) |
(u32)(phy_id2 & PHY_REVISION_MASK)))
goto release;
e1000_toggle_lanphypc_value_ich8lan(hw);
hw->phy.ops.release(hw);
msec_delay(50);
hw->phy.ops.reset(hw);
msec_delay(50);
return;
release:
hw->phy.ops.release(hw);
return;
}
/**
* e1000_cleanup_led_ich8lan - Restore the default LED operation
* @hw: pointer to the HW structure
@@ -4165,6 +4233,7 @@ static void e1000_power_down_phy_copper_ich8lan(struct e1000_hw *hw)
static void e1000_clear_hw_cntrs_ich8lan(struct e1000_hw *hw)
{
u16 phy_data;
s32 ret_val;
DEBUGFUNC("e1000_clear_hw_cntrs_ich8lan");
@@ -4188,20 +4257,29 @@ static void e1000_clear_hw_cntrs_ich8lan(struct e1000_hw *hw)
if ((hw->phy.type == e1000_phy_82578) ||
(hw->phy.type == e1000_phy_82579) ||
(hw->phy.type == e1000_phy_82577)) {
hw->phy.ops.read_reg(hw, HV_SCC_UPPER, &phy_data);
hw->phy.ops.read_reg(hw, HV_SCC_LOWER, &phy_data);
hw->phy.ops.read_reg(hw, HV_ECOL_UPPER, &phy_data);
hw->phy.ops.read_reg(hw, HV_ECOL_LOWER, &phy_data);
hw->phy.ops.read_reg(hw, HV_MCC_UPPER, &phy_data);
hw->phy.ops.read_reg(hw, HV_MCC_LOWER, &phy_data);
hw->phy.ops.read_reg(hw, HV_LATECOL_UPPER, &phy_data);
hw->phy.ops.read_reg(hw, HV_LATECOL_LOWER, &phy_data);
hw->phy.ops.read_reg(hw, HV_COLC_UPPER, &phy_data);
hw->phy.ops.read_reg(hw, HV_COLC_LOWER, &phy_data);
hw->phy.ops.read_reg(hw, HV_DC_UPPER, &phy_data);
hw->phy.ops.read_reg(hw, HV_DC_LOWER, &phy_data);
hw->phy.ops.read_reg(hw, HV_TNCRS_UPPER, &phy_data);
hw->phy.ops.read_reg(hw, HV_TNCRS_LOWER, &phy_data);
ret_val = hw->phy.ops.acquire(hw);
if (ret_val)
return;
ret_val = hw->phy.ops.set_page(hw,
HV_STATS_PAGE << IGP_PAGE_SHIFT);
if (ret_val)
goto release;
hw->phy.ops.read_reg_page(hw, HV_SCC_UPPER, &phy_data);
hw->phy.ops.read_reg_page(hw, HV_SCC_LOWER, &phy_data);
hw->phy.ops.read_reg_page(hw, HV_ECOL_UPPER, &phy_data);
hw->phy.ops.read_reg_page(hw, HV_ECOL_LOWER, &phy_data);
hw->phy.ops.read_reg_page(hw, HV_MCC_UPPER, &phy_data);
hw->phy.ops.read_reg_page(hw, HV_MCC_LOWER, &phy_data);
hw->phy.ops.read_reg_page(hw, HV_LATECOL_UPPER, &phy_data);
hw->phy.ops.read_reg_page(hw, HV_LATECOL_LOWER, &phy_data);
hw->phy.ops.read_reg_page(hw, HV_COLC_UPPER, &phy_data);
hw->phy.ops.read_reg_page(hw, HV_COLC_LOWER, &phy_data);
hw->phy.ops.read_reg_page(hw, HV_DC_UPPER, &phy_data);
hw->phy.ops.read_reg_page(hw, HV_DC_LOWER, &phy_data);
hw->phy.ops.read_reg_page(hw, HV_TNCRS_UPPER, &phy_data);
hw->phy.ops.read_reg_page(hw, HV_TNCRS_LOWER, &phy_data);
release:
hw->phy.ops.release(hw);
}
}
@@ -1,6 +1,6 @@
/******************************************************************************
Copyright (c) 2001-2010, Intel Corporation
Copyright (c) 2001-2011, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -30,7 +30,7 @@
POSSIBILITY OF SUCH DAMAGE.
******************************************************************************/
/*$FreeBSD: src/sys/dev/e1000/e1000_ich8lan.h,v 1.4.2.3.2.1 2010/12/21 17:09:25 kensmith Exp $*/
/*$FreeBSD$*/
#ifndef _E1000_ICH8LAN_H_
#define _E1000_ICH8LAN_H_
@@ -67,10 +67,13 @@
#define E1000_ICH_FWSM_DISSW 0x10000000 /* FW Disables SW Writes */
/* FW established a valid mode */
#define E1000_ICH_FWSM_FW_VALID 0x00008000
#define E1000_ICH_FWSM_PCIM2PCI 0x01000000 /* ME PCIm-to-PCI active */
#define E1000_ICH_FWSM_PCIM2PCI_COUNT 2000
#define E1000_ICH_MNG_IAMT_MODE 0x2
#define E1000_FWSM_PROXY_MODE 0x00000008 /* FW is in proxy mode */
#define E1000_FWSM_MEMC 0x00000010 /* ME Messaging capable */
/* Shared Receive Address Registers */
#define E1000_SHRAL(_i) (0x05438 + ((_i) * 8))
@@ -125,6 +128,7 @@
#define IGP3_PM_CTRL_FORCE_PWR_DOWN 0x0020
/* PHY Wakeup Registers and defines */
#define BM_PORT_GEN_CFG PHY_REG(BM_PORT_CTRL_PAGE, 17)
#define BM_RCTL PHY_REG(BM_WUC_PAGE, 0)
#define BM_WUC PHY_REG(BM_WUC_PAGE, 1)
#define BM_WUFC PHY_REG(BM_WUC_PAGE, 2)
@@ -155,23 +159,33 @@
#define HV_MUX_DATA_CTRL PHY_REG(776, 16)
#define HV_MUX_DATA_CTRL_GEN_TO_MAC 0x0400
#define HV_MUX_DATA_CTRL_FORCE_SPEED 0x0004
#define HV_SCC_UPPER PHY_REG(778, 16) /* Single Collision Count */
#define HV_SCC_LOWER PHY_REG(778, 17)
#define HV_ECOL_UPPER PHY_REG(778, 18) /* Excessive Collision Count */
#define HV_ECOL_LOWER PHY_REG(778, 19)
#define HV_MCC_UPPER PHY_REG(778, 20) /* Multiple Collision Count */
#define HV_MCC_LOWER PHY_REG(778, 21)
#define HV_LATECOL_UPPER PHY_REG(778, 23) /* Late Collision Count */
#define HV_LATECOL_LOWER PHY_REG(778, 24)
#define HV_COLC_UPPER PHY_REG(778, 25) /* Collision Count */
#define HV_COLC_LOWER PHY_REG(778, 26)
#define HV_DC_UPPER PHY_REG(778, 27) /* Defer Count */
#define HV_DC_LOWER PHY_REG(778, 28)
#define HV_TNCRS_UPPER PHY_REG(778, 29) /* Transmit with no CRS */
#define HV_TNCRS_LOWER PHY_REG(778, 30)
#define HV_STATS_PAGE 778
#define HV_SCC_UPPER PHY_REG(HV_STATS_PAGE, 16) /* Single Collision Count */
#define HV_SCC_LOWER PHY_REG(HV_STATS_PAGE, 17)
#define HV_ECOL_UPPER PHY_REG(HV_STATS_PAGE, 18) /* Excessive Coll. Count */
#define HV_ECOL_LOWER PHY_REG(HV_STATS_PAGE, 19)
#define HV_MCC_UPPER PHY_REG(HV_STATS_PAGE, 20) /* Multiple Coll. Count */
#define HV_MCC_LOWER PHY_REG(HV_STATS_PAGE, 21)
#define HV_LATECOL_UPPER PHY_REG(HV_STATS_PAGE, 23) /* Late Collision Count */
#define HV_LATECOL_LOWER PHY_REG(HV_STATS_PAGE, 24)
#define HV_COLC_UPPER PHY_REG(HV_STATS_PAGE, 25) /* Collision Count */
#define HV_COLC_LOWER PHY_REG(HV_STATS_PAGE, 26)
#define HV_DC_UPPER PHY_REG(HV_STATS_PAGE, 27) /* Defer Count */
#define HV_DC_LOWER PHY_REG(HV_STATS_PAGE, 28)
#define HV_TNCRS_UPPER PHY_REG(HV_STATS_PAGE, 29) /* Transmit with no CRS */
#define HV_TNCRS_LOWER PHY_REG(HV_STATS_PAGE, 30)
#define E1000_FCRTV_PCH 0x05F40 /* PCH Flow Control Refresh Timer Value */
/*
* For ICH, the name used for NVM word 17h is LED1 Config.
* For PCH, the word was re-named to OEM Config.
*/
#define E1000_NVM_LED1_CONFIG 0x17 /* NVM LED1/LPLU Config Word */
#define E1000_NVM_LED1_CONFIG_LPLU_NONDOA 0x0400 /* NVM LPLU in non-D0a Bit */
#define E1000_NVM_OEM_CONFIG E1000_NVM_LED1_CONFIG
#define E1000_NVM_OEM_CONFIG_LPLU_NONDOA E1000_NVM_LED1_CONFIG_LPLU_NONDOA
#define E1000_NVM_K1_CONFIG 0x1B /* NVM K1 Config Word */
#define E1000_NVM_K1_ENABLE 0x1 /* NVM Enable K1 bit */
@@ -192,25 +206,33 @@
#define HV_OEM_BITS_GBE_DIS 0x0040 /* Gigabit Disable */
#define HV_OEM_BITS_RESTART_AN 0x0400 /* Restart Auto-negotiation */
#define LCD_CFG_PHY_ADDR_BIT 0x0020 /* Phy address bit from LCD Config word */
#define LCD_CFG_PHY_ADDR_BIT 0x0020 /* Phy addr bit from LCD Config word */
/* KMRN Mode Control */
#define HV_KMRN_MODE_CTRL PHY_REG(769, 16)
#define HV_KMRN_MDIO_SLOW 0x0400
/* KMRN FIFO Control and Status */
#define HV_KMRN_FIFO_CTRLSTA PHY_REG(770, 16)
#define HV_KMRN_FIFO_CTRLSTA_PREAMBLE_MASK 0x7000
#define HV_KMRN_FIFO_CTRLSTA_PREAMBLE_SHIFT 12
/* PHY Power Management Control */
#define HV_PM_CTRL PHY_REG(770, 17)
#define SW_FLAG_TIMEOUT 1000 /* SW Semaphore flag timeout in milliseconds */
#define SW_FLAG_TIMEOUT 1000 /* SW Semaphore flag timeout in ms */
/* PHY Low Power Idle Control */
#define I82579_LPI_CTRL PHY_REG(772, 20)
#define I82579_LPI_CTRL_ENABLE_MASK 0x6000
#define I82579_LPI_CTRL_FORCE_PLL_LOCK_COUNT 0x80
/* EMI Registers */
#define I82579_EMI_ADDR 0x10
#define I82579_EMI_DATA 0x11
#define I82579_LPI_UPDATE_TIMER 0x4805 /* in 40ns units + 40 ns base value */
#define I82579_MSE_THRESHOLD 0x084F /* Mean Square Error Threshold */
#define I82579_MSE_LINK_DOWN 0x2411 /* MSE count before dropping link */
/*
* Additional interrupts need to be handled for ICH family:
@@ -242,10 +264,9 @@ void e1000_set_kmrn_lock_loss_workaround_ich8lan(struct e1000_hw *hw,
bool state);
void e1000_igp3_phy_powerdown_workaround_ich8lan(struct e1000_hw *hw);
void e1000_gig_downshift_workaround_ich8lan(struct e1000_hw *hw);
void e1000_disable_gig_wol_ich8lan(struct e1000_hw *hw);
void e1000_suspend_workarounds_ich8lan(struct e1000_hw *hw);
void e1000_resume_workarounds_pchlan(struct e1000_hw *hw);
s32 e1000_configure_k1_ich8lan(struct e1000_hw *hw, bool k1_enable);
s32 e1000_oem_bits_config_ich8lan(struct e1000_hw *hw, bool d0_config);
s32 e1000_hv_phy_powerdown_workaround_ich8lan(struct e1000_hw *hw);
void e1000_copy_rx_addrs_to_phy_ich8lan(struct e1000_hw *hw);
s32 e1000_lv_jumbo_workaround_ich8lan(struct e1000_hw *hw, bool enable);
#endif
File diff suppressed because it is too large Load Diff
@@ -1,6 +1,6 @@
/******************************************************************************
Copyright (c) 2001-2010, Intel Corporation
Copyright (c) 2001-2012, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -30,7 +30,7 @@
POSSIBILITY OF SUCH DAMAGE.
******************************************************************************/
/*$FreeBSD: src/sys/dev/e1000/e1000_mac.h,v 1.3.2.2.4.1 2010/12/21 17:09:25 kensmith Exp $*/
/*$FreeBSD$*/
#ifndef _E1000_MAC_H_
#define _E1000_MAC_H_
@@ -84,11 +84,9 @@ u32 e1000_hash_mc_addr_generic(struct e1000_hw *hw, u8 *mc_addr);
void e1000_clear_hw_cntrs_base_generic(struct e1000_hw *hw);
void e1000_clear_vfta_generic(struct e1000_hw *hw);
void e1000_config_collision_dist_generic(struct e1000_hw *hw);
void e1000_init_rx_addrs_generic(struct e1000_hw *hw, u16 rar_count);
void e1000_pcix_mmrbc_workaround_generic(struct e1000_hw *hw);
void e1000_put_hw_semaphore_generic(struct e1000_hw *hw);
void e1000_rar_set_generic(struct e1000_hw *hw, u8 *addr, u32 index);
s32 e1000_check_alt_mac_addr_generic(struct e1000_hw *hw);
void e1000_reset_adaptive_generic(struct e1000_hw *hw);
void e1000_set_pcie_no_snoop_generic(struct e1000_hw *hw, u32 no_snoop);
@@ -1,6 +1,6 @@
/******************************************************************************
Copyright (c) 2001-2010, Intel Corporation
Copyright (c) 2001-2012, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -30,7 +30,7 @@
POSSIBILITY OF SUCH DAMAGE.
******************************************************************************/
/*$FreeBSD: src/sys/dev/e1000/e1000_manage.c,v 1.2.2.2.4.1 2010/12/21 17:09:25 kensmith Exp $*/
/*$FreeBSD$*/
#include "e1000_api.h"
@@ -71,23 +71,20 @@ u8 e1000_calculate_checksum(u8 *buffer, u32 length)
s32 e1000_mng_enable_host_if_generic(struct e1000_hw *hw)
{
u32 hicr;
s32 ret_val = E1000_SUCCESS;
u8 i;
DEBUGFUNC("e1000_mng_enable_host_if_generic");
if (!(hw->mac.arc_subsystem_valid)) {
if (!hw->mac.arc_subsystem_valid) {
DEBUGOUT("ARC subsystem not valid.\n");
ret_val = -E1000_ERR_HOST_INTERFACE_COMMAND;
goto out;
return -E1000_ERR_HOST_INTERFACE_COMMAND;
}
/* Check that the host interface is enabled. */
hicr = E1000_READ_REG(hw, E1000_HICR);
if ((hicr & E1000_HICR_EN) == 0) {
if (!(hicr & E1000_HICR_EN)) {
DEBUGOUT("E1000_HOST_EN bit disabled.\n");
ret_val = -E1000_ERR_HOST_INTERFACE_COMMAND;
goto out;
return -E1000_ERR_HOST_INTERFACE_COMMAND;
}
/* check the previous command is completed */
for (i = 0; i < E1000_MNG_DHCP_COMMAND_TIMEOUT; i++) {
@@ -99,12 +96,10 @@ s32 e1000_mng_enable_host_if_generic(struct e1000_hw *hw)
if (i == E1000_MNG_DHCP_COMMAND_TIMEOUT) {
DEBUGOUT("Previous command timeout failed .\n");
ret_val = -E1000_ERR_HOST_INTERFACE_COMMAND;
goto out;
return -E1000_ERR_HOST_INTERFACE_COMMAND;
}
out:
return ret_val;
return E1000_SUCCESS;
}
/**
@@ -147,7 +142,7 @@ bool e1000_enable_tx_pkt_filtering_generic(struct e1000_hw *hw)
/* No manageability, no filtering */
if (!hw->mac.ops.check_mng_mode(hw)) {
hw->mac.tx_pkt_filtering = FALSE;
goto out;
return hw->mac.tx_pkt_filtering;
}
/*
@@ -157,7 +152,7 @@ bool e1000_enable_tx_pkt_filtering_generic(struct e1000_hw *hw)
ret_val = hw->mac.ops.mng_enable_host_if(hw);
if (ret_val != E1000_SUCCESS) {
hw->mac.tx_pkt_filtering = FALSE;
goto out;
return hw->mac.tx_pkt_filtering;
}
/* Read in the header. Length and offset are in dwords. */
@@ -177,66 +172,16 @@ bool e1000_enable_tx_pkt_filtering_generic(struct e1000_hw *hw)
*/
if ((hdr_csum != csum) || (hdr->signature != E1000_IAMT_SIGNATURE)) {
hw->mac.tx_pkt_filtering = TRUE;
goto out;
return hw->mac.tx_pkt_filtering;
}
/* Cookie area is valid, make the final check for filtering. */
if (!(hdr->status & E1000_MNG_DHCP_COOKIE_STATUS_PARSING)) {
if (!(hdr->status & E1000_MNG_DHCP_COOKIE_STATUS_PARSING))
hw->mac.tx_pkt_filtering = FALSE;
goto out;
}
out:
return hw->mac.tx_pkt_filtering;
}
/**
* e1000_mng_write_dhcp_info_generic - Writes DHCP info to host interface
* @hw: pointer to the HW structure
* @buffer: pointer to the host interface
* @length: size of the buffer
*
* Writes the DHCP information to the host interface.
**/
s32 e1000_mng_write_dhcp_info_generic(struct e1000_hw *hw, u8 *buffer,
u16 length)
{
struct e1000_host_mng_command_header hdr;
s32 ret_val;
u32 hicr;
DEBUGFUNC("e1000_mng_write_dhcp_info_generic");
hdr.command_id = E1000_MNG_DHCP_TX_PAYLOAD_CMD;
hdr.command_length = length;
hdr.reserved1 = 0;
hdr.reserved2 = 0;
hdr.checksum = 0;
/* Enable the host interface */
ret_val = hw->mac.ops.mng_enable_host_if(hw);
if (ret_val)
goto out;
/* Populate the host interface with the contents of "buffer". */
ret_val = hw->mac.ops.mng_host_if_write(hw, buffer, length,
sizeof(hdr), &(hdr.checksum));
if (ret_val)
goto out;
/* Write the manageability command header */
ret_val = hw->mac.ops.mng_write_cmd_header(hw, &hdr);
if (ret_val)
goto out;
/* Tell the ARC a new command is pending. */
hicr = E1000_READ_REG(hw, E1000_HICR);
E1000_WRITE_REG(hw, E1000_HICR, hicr | E1000_HICR_C);
out:
return ret_val;
}
/**
* e1000_mng_write_cmd_header_generic - Writes manageability command header
* @hw: pointer to the HW structure
@@ -284,17 +229,14 @@ s32 e1000_mng_host_if_write_generic(struct e1000_hw *hw, u8 *buffer,
u8 *tmp;
u8 *bufptr = buffer;
u32 data = 0;
s32 ret_val = E1000_SUCCESS;
u16 remaining, i, j, prev_bytes;
DEBUGFUNC("e1000_mng_host_if_write_generic");
/* sum = only sum of the data and it is not checksum */
if (length == 0 || offset + length > E1000_HI_MAX_MNG_DATA_LENGTH) {
ret_val = -E1000_ERR_PARAM;
goto out;
}
if (length == 0 || offset + length > E1000_HI_MAX_MNG_DATA_LENGTH)
return -E1000_ERR_PARAM;
tmp = (u8 *)&data;
prev_bytes = offset & 0x3;
@@ -339,11 +281,57 @@ s32 e1000_mng_host_if_write_generic(struct e1000_hw *hw, u8 *buffer,
*sum += *(tmp + j);
}
E1000_WRITE_REG_ARRAY_DWORD(hw, E1000_HOST_IF, offset + i, data);
E1000_WRITE_REG_ARRAY_DWORD(hw, E1000_HOST_IF, offset + i,
data);
}
out:
return E1000_SUCCESS;
}
/**
* e1000_mng_write_dhcp_info_generic - Writes DHCP info to host interface
* @hw: pointer to the HW structure
* @buffer: pointer to the host interface
* @length: size of the buffer
*
* Writes the DHCP information to the host interface.
**/
s32 e1000_mng_write_dhcp_info_generic(struct e1000_hw *hw, u8 *buffer,
u16 length)
{
struct e1000_host_mng_command_header hdr;
s32 ret_val;
u32 hicr;
DEBUGFUNC("e1000_mng_write_dhcp_info_generic");
hdr.command_id = E1000_MNG_DHCP_TX_PAYLOAD_CMD;
hdr.command_length = length;
hdr.reserved1 = 0;
hdr.reserved2 = 0;
hdr.checksum = 0;
/* Enable the host interface */
ret_val = hw->mac.ops.mng_enable_host_if(hw);
if (ret_val)
return ret_val;
/* Populate the host interface with the contents of "buffer". */
ret_val = hw->mac.ops.mng_host_if_write(hw, buffer, length,
sizeof(hdr), &(hdr.checksum));
if (ret_val)
return ret_val;
/* Write the manageability command header */
ret_val = hw->mac.ops.mng_write_cmd_header(hw, &hdr);
if (ret_val)
return ret_val;
/* Tell the ARC a new command is pending. */
hicr = E1000_READ_REG(hw, E1000_HICR);
E1000_WRITE_REG(hw, E1000_HICR, hicr | E1000_HICR_C);
return E1000_SUCCESS;
}
/**
@@ -357,17 +345,16 @@ bool e1000_enable_mng_pass_thru(struct e1000_hw *hw)
{
u32 manc;
u32 fwsm, factps;
bool ret_val = FALSE;
DEBUGFUNC("e1000_enable_mng_pass_thru");
if (!hw->mac.asf_firmware_present)
goto out;
return FALSE;
manc = E1000_READ_REG(hw, E1000_MANC);
if (!(manc & E1000_MANC_RCV_TCO_EN))
goto out;
return FALSE;
if (hw->mac.has_fwsm) {
fwsm = E1000_READ_REG(hw, E1000_FWSM);
@@ -375,10 +362,8 @@ bool e1000_enable_mng_pass_thru(struct e1000_hw *hw)
if (!(factps & E1000_FACTPS_MNGCG) &&
((fwsm & E1000_FWSM_MODE_MASK) ==
(e1000_mng_mode_pt << E1000_FWSM_MODE_SHIFT))) {
ret_val = TRUE;
goto out;
}
(e1000_mng_mode_pt << E1000_FWSM_MODE_SHIFT)))
return TRUE;
} else if ((hw->mac.type == e1000_82574) ||
(hw->mac.type == e1000_82583)) {
u16 data;
@@ -388,18 +373,14 @@ bool e1000_enable_mng_pass_thru(struct e1000_hw *hw)
if (!(factps & E1000_FACTPS_MNGCG) &&
((data & E1000_NVM_INIT_CTRL2_MNGM) ==
(e1000_mng_mode_pt << 13))) {
ret_val = TRUE;
goto out;
}
(e1000_mng_mode_pt << 13)))
return TRUE;
} else if ((manc & E1000_MANC_SMBUS_EN) &&
!(manc & E1000_MANC_ASF_EN)) {
ret_val = TRUE;
goto out;
return TRUE;
}
out:
return ret_val;
return FALSE;
}
/**
@@ -414,33 +395,30 @@ out:
s32 e1000_host_interface_command(struct e1000_hw *hw, u8 *buffer, u32 length)
{
u32 hicr, i;
s32 ret_val = E1000_SUCCESS;
DEBUGFUNC("e1000_host_interface_command");
if (!(hw->mac.arc_subsystem_valid)) {
DEBUGOUT("Hardware doesn't support host interface command.\n");
goto out;
return E1000_SUCCESS;
}
if (!hw->mac.asf_firmware_present) {
DEBUGOUT("Firmware is not present.\n");
goto out;
return E1000_SUCCESS;
}
if (length == 0 || length & 0x3 ||
length > E1000_HI_MAX_BLOCK_BYTE_LENGTH) {
DEBUGOUT("Buffer length failure.\n");
ret_val = -E1000_ERR_HOST_INTERFACE_COMMAND;
goto out;
return -E1000_ERR_HOST_INTERFACE_COMMAND;
}
/* Check that the host interface is enabled. */
hicr = E1000_READ_REG(hw, E1000_HICR);
if ((hicr & E1000_HICR_EN) == 0) {
if (!(hicr & E1000_HICR_EN)) {
DEBUGOUT("E1000_HOST_EN bit disabled.\n");
ret_val = -E1000_ERR_HOST_INTERFACE_COMMAND;
goto out;
return -E1000_ERR_HOST_INTERFACE_COMMAND;
}
/* Calculate length in DWORDs */
@@ -451,9 +429,7 @@ s32 e1000_host_interface_command(struct e1000_hw *hw, u8 *buffer, u32 length)
* into the ram area.
*/
for (i = 0; i < length; i++)
E1000_WRITE_REG_ARRAY_DWORD(hw,
E1000_HOST_IF,
i,
E1000_WRITE_REG_ARRAY_DWORD(hw, E1000_HOST_IF, i,
*((u32 *)buffer + i));
/* Setting this bit tells the ARC that a new command is pending. */
@@ -470,8 +446,7 @@ s32 e1000_host_interface_command(struct e1000_hw *hw, u8 *buffer, u32 length)
if (i == E1000_HI_COMMAND_TIMEOUT ||
(!(E1000_READ_REG(hw, E1000_HICR) & E1000_HICR_SV))) {
DEBUGOUT("Command has failed with no status valid.\n");
ret_val = -E1000_ERR_HOST_INTERFACE_COMMAND;
goto out;
return -E1000_ERR_HOST_INTERFACE_COMMAND;
}
for (i = 0; i < length; i++)
@@ -479,7 +454,126 @@ s32 e1000_host_interface_command(struct e1000_hw *hw, u8 *buffer, u32 length)
E1000_HOST_IF,
i);
out:
return ret_val;
return E1000_SUCCESS;
}
/**
* e1000_load_firmware - Writes proxy FW code buffer to host interface
* and execute.
* @hw: pointer to the HW structure
* @buffer: contains a firmware to write
* @length: the byte length of the buffer, must be multiple of 4 bytes
*
* Upon success returns E1000_SUCCESS, returns E1000_ERR_CONFIG if not enabled
* in HW else returns E1000_ERR_HOST_INTERFACE_COMMAND.
**/
s32 e1000_load_firmware(struct e1000_hw *hw, u8 *buffer, u32 length)
{
u32 hicr, hibba, fwsm, icr, i;
DEBUGFUNC("e1000_load_firmware");
if (hw->mac.type < e1000_i210) {
DEBUGOUT("Hardware doesn't support loading FW by the driver\n");
return -E1000_ERR_CONFIG;
}
/* Check that the host interface is enabled. */
hicr = E1000_READ_REG(hw, E1000_HICR);
if (!(hicr & E1000_HICR_EN)) {
DEBUGOUT("E1000_HOST_EN bit disabled.\n");
return -E1000_ERR_CONFIG;
}
if (!(hicr & E1000_HICR_MEMORY_BASE_EN)) {
DEBUGOUT("E1000_HICR_MEMORY_BASE_EN bit disabled.\n");
return -E1000_ERR_CONFIG;
}
if (length == 0 || length & 0x3 || length > E1000_HI_FW_MAX_LENGTH) {
DEBUGOUT("Buffer length failure.\n");
return -E1000_ERR_INVALID_ARGUMENT;
}
/* Clear notification from ROM-FW by reading ICR register */
icr = E1000_READ_REG(hw, E1000_ICR_V2);
/* Reset ROM-FW */
hicr = E1000_READ_REG(hw, E1000_HICR);
hicr |= E1000_HICR_FW_RESET_ENABLE;
E1000_WRITE_REG(hw, E1000_HICR, hicr);
hicr |= E1000_HICR_FW_RESET;
E1000_WRITE_REG(hw, E1000_HICR, hicr);
E1000_WRITE_FLUSH(hw);
/* Wait till MAC notifies about its readiness after ROM-FW reset */
for (i = 0; i < (E1000_HI_COMMAND_TIMEOUT * 2); i++) {
icr = E1000_READ_REG(hw, E1000_ICR_V2);
if (icr & E1000_ICR_MNG)
break;
msec_delay(1);
}
/* Check for timeout */
if (i == E1000_HI_COMMAND_TIMEOUT) {
DEBUGOUT("FW reset failed.\n");
return -E1000_ERR_HOST_INTERFACE_COMMAND;
}
/* Wait till MAC is ready to accept new FW code */
for (i = 0; i < E1000_HI_COMMAND_TIMEOUT; i++) {
fwsm = E1000_READ_REG(hw, E1000_FWSM);
if ((fwsm & E1000_FWSM_FW_VALID) &&
((fwsm & E1000_FWSM_MODE_MASK) >> E1000_FWSM_MODE_SHIFT ==
E1000_FWSM_HI_EN_ONLY_MODE))
break;
msec_delay(1);
}
/* Check for timeout */
if (i == E1000_HI_COMMAND_TIMEOUT) {
DEBUGOUT("FW reset failed.\n");
return -E1000_ERR_HOST_INTERFACE_COMMAND;
}
/* Calculate length in DWORDs */
length >>= 2;
/*
* The device driver writes the relevant FW code block
* into the ram area in DWORDs via 1kB ram addressing window.
*/
for (i = 0; i < length; i++) {
if (!(i % E1000_HI_FW_BLOCK_DWORD_LENGTH)) {
/* Point to correct 1kB ram window */
hibba = E1000_HI_FW_BASE_ADDRESS +
((E1000_HI_FW_BLOCK_DWORD_LENGTH << 2) *
(i / E1000_HI_FW_BLOCK_DWORD_LENGTH));
E1000_WRITE_REG(hw, E1000_HIBBA, hibba);
}
E1000_WRITE_REG_ARRAY_DWORD(hw, E1000_HOST_IF,
i % E1000_HI_FW_BLOCK_DWORD_LENGTH,
*((u32 *)buffer + i));
}
/* Setting this bit tells the ARC that a new FW is ready to execute. */
hicr = E1000_READ_REG(hw, E1000_HICR);
E1000_WRITE_REG(hw, E1000_HICR, hicr | E1000_HICR_C);
for (i = 0; i < E1000_HI_COMMAND_TIMEOUT; i++) {
hicr = E1000_READ_REG(hw, E1000_HICR);
if (!(hicr & E1000_HICR_C))
break;
msec_delay(1);
}
/* Check for successful FW start. */
if (i == E1000_HI_COMMAND_TIMEOUT) {
DEBUGOUT("New FW did not start within timeout period.\n");
return -E1000_ERR_HOST_INTERFACE_COMMAND;
}
return E1000_SUCCESS;
}
@@ -1,6 +1,6 @@
/******************************************************************************
Copyright (c) 2001-2010, Intel Corporation
Copyright (c) 2001-2012, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -30,7 +30,7 @@
POSSIBILITY OF SUCH DAMAGE.
******************************************************************************/
/*$FreeBSD: src/sys/dev/e1000/e1000_manage.h,v 1.1.4.1.6.1 2010/12/21 17:09:25 kensmith Exp $*/
/*$FreeBSD$*/
#ifndef _E1000_MANAGE_H_
#define _E1000_MANAGE_H_
@@ -47,6 +47,7 @@ s32 e1000_mng_write_dhcp_info_generic(struct e1000_hw *hw,
bool e1000_enable_mng_pass_thru(struct e1000_hw *hw);
u8 e1000_calculate_checksum(u8 *buffer, u32 length);
s32 e1000_host_interface_command(struct e1000_hw *hw, u8 *buffer, u32 length);
s32 e1000_load_firmware(struct e1000_hw *hw, u8 *buffer, u32 length);
enum e1000_mng_mode {
e1000_mng_mode_none = 0,
@@ -60,6 +61,8 @@ enum e1000_mng_mode {
#define E1000_FWSM_MODE_MASK 0xE
#define E1000_FWSM_MODE_SHIFT 1
#define E1000_FWSM_FW_VALID 0x00008000
#define E1000_FWSM_HI_EN_ONLY_MODE 0x4
#define E1000_MNG_IAMT_MODE 0x3
#define E1000_MNG_DHCP_COOKIE_LENGTH 0x10
@@ -75,8 +78,11 @@ enum e1000_mng_mode {
#define E1000_HI_MAX_BLOCK_BYTE_LENGTH 1792 /* Num of bytes in range */
#define E1000_HI_MAX_BLOCK_DWORD_LENGTH 448 /* Num of dwords in range */
#define E1000_HI_COMMAND_TIMEOUT 500 /* Process HI command limit */
#define E1000_HI_COMMAND_TIMEOUT 500 /* Process HI cmd limit */
#define E1000_HI_FW_BASE_ADDRESS 0x10000
#define E1000_HI_FW_MAX_LENGTH (64 * 1024) /* Num of bytes */
#define E1000_HI_FW_BLOCK_DWORD_LENGTH 256 /* Num of DWORDs per page */
#define E1000_HICR_MEMORY_BASE_EN 0x200 /* MB Enable bit - RO */
#define E1000_HICR_EN 0x01 /* Enable bit - RO */
/* Driver sets this bit when done to put command in RAM */
#define E1000_HICR_C 0x02
@@ -30,7 +30,7 @@
POSSIBILITY OF SUCH DAMAGE.
******************************************************************************/
/*$FreeBSD: src/sys/dev/e1000/e1000_mbx.c,v 1.1.2.2.2.1 2010/12/21 17:09:25 kensmith Exp $*/
/*$FreeBSD$*/
#include "e1000_mbx.h"
@@ -30,7 +30,7 @@
POSSIBILITY OF SUCH DAMAGE.
******************************************************************************/
/*$FreeBSD: src/sys/dev/e1000/e1000_mbx.h,v 1.1.2.2.2.1 2010/12/21 17:09:25 kensmith Exp $*/
/*$FreeBSD$*/
#ifndef _E1000_MBX_H_
#define _E1000_MBX_H_
@@ -1,6 +1,6 @@
/******************************************************************************
Copyright (c) 2001-2010, Intel Corporation
Copyright (c) 2001-2011, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -30,7 +30,7 @@
POSSIBILITY OF SUCH DAMAGE.
******************************************************************************/
/*$FreeBSD: src/sys/dev/e1000/e1000_nvm.c,v 1.3.2.2.2.1 2010/12/21 17:09:25 kensmith Exp $*/
/*$FreeBSD$*/
#include "e1000_api.h"
@@ -313,8 +313,7 @@ static void e1000_standby_nvm(struct e1000_hw *hw)
usec_delay(nvm->delay_usec);
e1000_lower_eec_clk(hw, &eecd);
} else
if (nvm->type == e1000_nvm_eeprom_spi) {
} else if (nvm->type == e1000_nvm_eeprom_spi) {
/* Toggle CS to flush commands */
eecd |= E1000_EECD_CS;
E1000_WRITE_REG(hw, E1000_EECD, eecd);
@@ -394,13 +393,13 @@ static s32 e1000_ready_nvm_eeprom(struct e1000_hw *hw)
/* Set CS */
eecd |= E1000_EECD_CS;
E1000_WRITE_REG(hw, E1000_EECD, eecd);
} else
if (nvm->type == e1000_nvm_eeprom_spi) {
} else if (nvm->type == e1000_nvm_eeprom_spi) {
u16 timeout = NVM_MAX_RETRY_SPI;
/* Clear SK and CS */
eecd &= ~(E1000_EECD_CS | E1000_EECD_SK);
E1000_WRITE_REG(hw, E1000_EECD, eecd);
E1000_WRITE_FLUSH(hw);
usec_delay(1);
/*
@@ -1,6 +1,6 @@
/******************************************************************************
Copyright (c) 2001-2010, Intel Corporation
Copyright (c) 2001-2011, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -30,7 +30,7 @@
POSSIBILITY OF SUCH DAMAGE.
******************************************************************************/
/*$FreeBSD: src/sys/dev/e1000/e1000_nvm.h,v 1.2.2.2.2.1 2010/12/21 17:09:25 kensmith Exp $*/
/*$FreeBSD$*/
#ifndef _E1000_NVM_H_
#define _E1000_NVM_H_
@@ -54,8 +54,6 @@ s32 e1000_read_nvm_eerd(struct e1000_hw *hw, u16 offset, u16 words,
u16 *data);
s32 e1000_valid_led_default_generic(struct e1000_hw *hw, u16 *data);
s32 e1000_validate_nvm_checksum_generic(struct e1000_hw *hw);
s32 e1000_write_nvm_eewr(struct e1000_hw *hw, u16 offset,
u16 words, u16 *data);
s32 e1000_write_nvm_microwire(struct e1000_hw *hw, u16 offset,
u16 words, u16 *data);
s32 e1000_write_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words,
@@ -30,7 +30,7 @@
POSSIBILITY OF SUCH DAMAGE.
******************************************************************************/
/*$FreeBSD: src/sys/dev/e1000/e1000_osdep.c,v 1.3.2.1.6.1 2010/12/21 17:09:25 kensmith Exp $*/
/*$FreeBSD$*/
#include "e1000_api.h"
@@ -30,7 +30,7 @@
POSSIBILITY OF SUCH DAMAGE.
******************************************************************************/
/*$FreeBSD: src/sys/dev/e1000/e1000_osdep.h,v 1.2.2.3.2.1 2010/12/21 17:09:25 kensmith Exp $*/
/*$FreeBSD$*/
#ifndef _FREEBSD_OS_H_
@@ -72,14 +72,11 @@
#define DEBUGOUT7(S,A,B,C,D,E,F,G) do {} while (0)
#define STATIC static
#ifndef __HAIKU__
#define FALSE 0
#define TRUE 1
#ifndef __bool_true_false_are_defined
#define false FALSE
#define TRUE 1
#define true TRUE
#else
#define FALSE 0
#define TRUE 1
#endif
#define CMD_MEM_WRT_INVALIDATE 0x0010 /* BIT_4 */
#define PCI_COMMAND_REGISTER PCIR_COMMAND
@@ -87,7 +84,8 @@
/* Mutex used in the shared code */
#define E1000_MUTEX struct mtx
#define E1000_MUTEX_INIT(mutex) mtx_init((mutex), #mutex, \
MTX_NETWORK_LOCK, MTX_DEF)
MTX_NETWORK_LOCK, \
MTX_DEF | MTX_DUPOK)
#define E1000_MUTEX_DESTROY(mutex) mtx_destroy(mutex)
#define E1000_MUTEX_LOCK(mutex) mtx_lock(mutex)
#define E1000_MUTEX_TRYLOCK(mutex) mtx_trylock(mutex)
@@ -101,7 +99,7 @@ typedef int64_t s64;
typedef int32_t s32;
typedef int16_t s16;
typedef int8_t s8;
#ifndef __HAIKU__
#ifndef __bool_true_false_are_defined
typedef boolean_t bool;
#endif
File diff suppressed because it is too large Load Diff
@@ -1,6 +1,6 @@
/******************************************************************************
Copyright (c) 2001-2010, Intel Corporation
Copyright (c) 2001-2012, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -30,7 +30,7 @@
POSSIBILITY OF SUCH DAMAGE.
******************************************************************************/
/*$FreeBSD: src/sys/dev/e1000/e1000_phy.h,v 1.4.2.3.2.1 2010/12/21 17:09:25 kensmith Exp $*/
/*$FreeBSD$*/
#ifndef _E1000_PHY_H_
#define _E1000_PHY_H_
@@ -40,6 +40,11 @@ s32 e1000_null_read_reg(struct e1000_hw *hw, u32 offset, u16 *data);
void e1000_null_phy_generic(struct e1000_hw *hw);
s32 e1000_null_lplu_state(struct e1000_hw *hw, bool active);
s32 e1000_null_write_reg(struct e1000_hw *hw, u32 offset, u16 data);
s32 e1000_null_set_page(struct e1000_hw *hw, u16 data);
s32 e1000_read_i2c_byte_null(struct e1000_hw *hw, u8 byte_offset,
u8 dev_addr, u8 *data);
s32 e1000_write_i2c_byte_null(struct e1000_hw *hw, u8 byte_offset,
u8 dev_addr, u8 data);
s32 e1000_check_downshift_generic(struct e1000_hw *hw);
s32 e1000_check_polarity_m88(struct e1000_hw *hw);
s32 e1000_check_polarity_igp(struct e1000_hw *hw);
@@ -67,6 +72,7 @@ s32 e1000_phy_hw_reset_generic(struct e1000_hw *hw);
s32 e1000_phy_reset_dsp_generic(struct e1000_hw *hw);
s32 e1000_read_kmrn_reg_generic(struct e1000_hw *hw, u32 offset, u16 *data);
s32 e1000_read_kmrn_reg_locked(struct e1000_hw *hw, u32 offset, u16 *data);
s32 e1000_set_page_igp(struct e1000_hw *hw, u16 page);
s32 e1000_read_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 *data);
s32 e1000_read_phy_reg_igp_locked(struct e1000_hw *hw, u32 offset, u16 *data);
s32 e1000_read_phy_reg_m88(struct e1000_hw *hw, u32 offset, u16 *data);
@@ -86,6 +92,8 @@ enum e1000_phy_type e1000_get_phy_type_from_id(u32 phy_id);
s32 e1000_determine_phy_address(struct e1000_hw *hw);
s32 e1000_write_phy_reg_bm(struct e1000_hw *hw, u32 offset, u16 data);
s32 e1000_read_phy_reg_bm(struct e1000_hw *hw, u32 offset, u16 *data);
s32 e1000_enable_phy_wakeup_reg_access_bm(struct e1000_hw *hw, u16 *phy_reg);
s32 e1000_disable_phy_wakeup_reg_access_bm(struct e1000_hw *hw, u16 *phy_reg);
s32 e1000_read_phy_reg_bm2(struct e1000_hw *hw, u32 offset, u16 *data);
s32 e1000_write_phy_reg_bm2(struct e1000_hw *hw, u32 offset, u16 data);
void e1000_power_up_phy_copper(struct e1000_hw *hw);
@@ -94,18 +102,24 @@ s32 e1000_read_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 *data);
s32 e1000_write_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 data);
s32 e1000_read_phy_reg_i2c(struct e1000_hw *hw, u32 offset, u16 *data);
s32 e1000_write_phy_reg_i2c(struct e1000_hw *hw, u32 offset, u16 data);
s32 e1000_read_sfp_data_byte(struct e1000_hw *hw, u16 offset, u8 *data);
s32 e1000_write_sfp_data_byte(struct e1000_hw *hw, u16 offset, u8 data);
s32 e1000_read_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 *data);
s32 e1000_read_phy_reg_hv_locked(struct e1000_hw *hw, u32 offset, u16 *data);
s32 e1000_read_phy_reg_page_hv(struct e1000_hw *hw, u32 offset, u16 *data);
s32 e1000_write_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 data);
s32 e1000_write_phy_reg_hv_locked(struct e1000_hw *hw, u32 offset, u16 data);
s32 e1000_write_phy_reg_page_hv(struct e1000_hw *hw, u32 offset, u16 data);
s32 e1000_link_stall_workaround_hv(struct e1000_hw *hw);
s32 e1000_copper_link_setup_82577(struct e1000_hw *hw);
s32 e1000_check_polarity_82577(struct e1000_hw *hw);
s32 e1000_get_phy_info_82577(struct e1000_hw *hw);
s32 e1000_phy_force_speed_duplex_82577(struct e1000_hw *hw);
s32 e1000_get_cable_length_82577(struct e1000_hw *hw);
s32 e1000_write_phy_reg_gs40g(struct e1000_hw *hw, u32 offset, u16 data);
s32 e1000_read_phy_reg_gs40g(struct e1000_hw *hw, u32 offset, u16 *data);
#define E1000_MAX_PHY_ADDR 4
#define E1000_MAX_PHY_ADDR 8
/* IGP01E1000 Specific Registers */
#define IGP01E1000_PHY_PORT_CONFIG 0x10 /* Port Config */
@@ -120,9 +134,19 @@ s32 e1000_get_cable_length_82577(struct e1000_hw *hw);
#define IGP_PAGE_SHIFT 5
#define PHY_REG_MASK 0x1F
/* GS40G - I210 PHY defines */
#define GS40G_PAGE_SELECT 0x16
#define GS40G_PAGE_SHIFT 16
#define GS40G_OFFSET_MASK 0xFFFF
#define GS40G_PAGE_2 0x20000
#define GS40G_MAC_REG2 0x15
#define GS40G_MAC_LB 0x4140
#define GS40G_MAC_SPEED_1G 0X0006
#define GS40G_COPPER_SPEC 0x0010
#define GS40G_CS_POWER_DOWN 0x0002
/* BM/HV Specific Registers */
#define BM_PORT_CTRL_PAGE 769
#define BM_PORT_GEN_CFG_REG PHY_REG(BM_PORT_CTRL_PAGE, 17)
#define BM_PCIE_PAGE 770
#define BM_WUC_PAGE 800
#define BM_WUC_ADDRESS_OPCODE 0x11
@@ -131,6 +155,7 @@ s32 e1000_get_cable_length_82577(struct e1000_hw *hw);
#define BM_WUC_ENABLE_REG 17
#define BM_WUC_ENABLE_BIT (1 << 2)
#define BM_WUC_HOST_WU_BIT (1 << 4)
#define BM_WUC_ME_WU_BIT (1 << 5)
#define PHY_UPPER_SHIFT 21
#define BM_PHY_REG(page, reg) \
@@ -166,8 +191,9 @@ s32 e1000_get_cable_length_82577(struct e1000_hw *hw);
#define I82577_PHY_STATUS2_SPEED_100MBPS 0x0100
/* I82577 PHY Control 2 */
#define I82577_PHY_CTRL2_AUTO_MDIX 0x0400
#define I82577_PHY_CTRL2_FORCE_MDI_MDIX 0x0200
#define I82577_PHY_CTRL2_MANUAL_MDIX 0x0200
#define I82577_PHY_CTRL2_AUTO_MDI_MDIX 0x0400
#define I82577_PHY_CTRL2_MDIX_CFG_MASK 0x0600
/* I82577 PHY Diagnostics Status */
#define I82577_DSTATUS_CABLE_LENGTH 0x03FC
@@ -270,6 +296,30 @@ s32 e1000_get_cable_length_82577(struct e1000_hw *hw);
/* IFE PHY MDIX Control */
#define IFE_PMC_MDIX_STATUS 0x0020 /* 1=MDI-X, 0=MDI */
#define IFE_PMC_FORCE_MDIX 0x0040 /* 1=force MDI-X, 0=force MDI */
#define IFE_PMC_AUTO_MDIX 0x0080 /* 1=enable auto MDI/MDI-X, 0=disable */
#define IFE_PMC_AUTO_MDIX 0x0080 /* 1=enable auto, 0=disable */
/* SFP modules ID memory locations */
#define E1000_SFF_IDENTIFIER_OFFSET 0x00
#define E1000_SFF_IDENTIFIER_SFF 0x02
#define E1000_SFF_IDENTIFIER_SFP 0x03
#define E1000_SFF_ETH_FLAGS_OFFSET 0x06
/* Flags for SFP modules compatible with ETH up to 1Gb */
struct sfp_e1000_flags {
u8 e1000_base_sx:1;
u8 e1000_base_lx:1;
u8 e1000_base_cx:1;
u8 e1000_base_t:1;
u8 e100_base_lx:1;
u8 e100_base_fx:1;
u8 e10_base_bx10:1;
u8 e10_base_px:1;
};
/* Vendor OUIs: format of OUI is 0x[byte0][byte1][byte2][00] */
#define E1000_SFF_VENDOR_OUI_TYCO 0x00407600
#define E1000_SFF_VENDOR_OUI_FTL 0x00906500
#define E1000_SFF_VENDOR_OUI_AVAGO 0x00176A00
#define E1000_SFF_VENDOR_OUI_INTEL 0x001B2100
#endif
@@ -1,6 +1,6 @@
/******************************************************************************
Copyright (c) 2001-2010, Intel Corporation
Copyright (c) 2001-2012, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -30,7 +30,7 @@
POSSIBILITY OF SUCH DAMAGE.
******************************************************************************/
/*$FreeBSD: src/sys/dev/e1000/e1000_regs.h,v 1.4.2.4.2.1 2010/12/21 17:09:25 kensmith Exp $*/
/*$FreeBSD$*/
#ifndef _E1000_REGS_H_
#define _E1000_REGS_H_
@@ -46,9 +46,12 @@
#define E1000_MDICNFG 0x00E04 /* MDI Config - RW */
#define E1000_REGISTER_SET_SIZE 0x20000 /* CSR Size */
#define E1000_EEPROM_INIT_CTRL_WORD_2 0x0F /* EEPROM Init Ctrl Word 2 */
#define E1000_EEPROM_PCIE_CTRL_WORD_2 0x28 /* EEPROM PCIe Ctrl Word 2 */
#define E1000_BARCTRL 0x5BBC /* BAR ctrl reg */
#define E1000_BARCTRL_FLSIZE 0x0700 /* BAR ctrl Flsize */
#define E1000_BARCTRL_CSRSIZE 0x2000 /* BAR ctrl CSR size */
#define E1000_I350_BARCTRL 0x5BFC /* BAR ctrl reg */
#define E1000_I350_DTXMXPKTSZ 0x355C /* Maximum sent packet size reg*/
#define E1000_SCTL 0x00024 /* SerDes Control - RW */
#define E1000_FCAL 0x00028 /* Flow Control Address Low - RW */
#define E1000_FCAH 0x0002C /* Flow Control Address High -RW */
@@ -104,16 +107,24 @@
#define E1000_FLOP 0x0103C /* FLASH Opcode Register */
#define E1000_I2CCMD 0x01028 /* SFPI2C Command Register - RW */
#define E1000_I2CPARAMS 0x0102C /* SFPI2C Parameters Register - RW */
#define E1000_I2CBB_EN 0x00000100 /* I2C - Bit Bang Enable */
#define E1000_I2C_CLK_OUT 0x00000200 /* I2C- Clock */
#define E1000_I2C_DATA_OUT 0x00000400 /* I2C- Data Out */
#define E1000_I2C_DATA_OE_N 0x00000800 /* I2C- Data Output Enable */
#define E1000_I2C_DATA_IN 0x00001000 /* I2C- Data In */
#define E1000_I2C_CLK_OE_N 0x00002000 /* I2C- Clock Output Enable */
#define E1000_I2C_CLK_IN 0x00004000 /* I2C- Clock In */
#define E1000_I2C_CLK_STRETCH_DIS 0x00008000 /* I2C- Dis Clk Stretching */
#define E1000_WDSTP 0x01040 /* Watchdog Setup - RW */
#define E1000_SWDSTS 0x01044 /* SW Device Status - RW */
#define E1000_FRTIMER 0x01048 /* Free Running Timer - RW */
#define E1000_TCPTIMER 0x0104C /* TCP Timer - RW */
#define E1000_VPDDIAG 0x01060 /* VPD Diagnostic - RO */
#define E1000_ICR_V2 0x01500 /* Interrupt Cause - new location - RC */
#define E1000_ICS_V2 0x01504 /* Interrupt Cause Set - new location - WO */
#define E1000_IMS_V2 0x01508 /* Interrupt Mask Set/Read - new location - RW */
#define E1000_IMC_V2 0x0150C /* Interrupt Mask Clear - new location - WO */
#define E1000_IAM_V2 0x01510 /* Interrupt Ack Auto Mask - new location - RW */
#define E1000_ICR_V2 0x01500 /* Intr Cause - new location - RC */
#define E1000_ICS_V2 0x01504 /* Intr Cause Set - new location - WO */
#define E1000_IMS_V2 0x01508 /* Intr Mask Set/Read - new location - RW */
#define E1000_IMC_V2 0x0150C /* Intr Mask Clear - new location - WO */
#define E1000_IAM_V2 0x01510 /* Intr Ack Auto Mask - new location - RW */
#define E1000_ERT 0x02008 /* Early Rx Threshold - RW */
#define E1000_FCRTL 0x02160 /* Flow Control Receive Threshold Low - RW */
#define E1000_FCRTH 0x02168 /* Flow Control Receive Threshold High - RW */
@@ -129,10 +140,66 @@
#define E1000_RDPUCTL 0x025DC /* DMA Rx Descriptor uC Control - RW */
#define E1000_PBDIAG 0x02458 /* Packet Buffer Diagnostic - RW */
#define E1000_RXPBS 0x02404 /* Rx Packet Buffer Size - RW */
#define E1000_IRPBS 0x02404 /* Same as RXPBS, renamed for newer adapters - RW */
#define E1000_IRPBS 0x02404 /* Same as RXPBS, renamed for newer Si - RW */
#define E1000_PBRWAC 0x024E8 /* Rx packet buffer wrap around counter - RO */
#define E1000_RDTR 0x02820 /* Rx Delay Timer - RW */
#define E1000_RADV 0x0282C /* Rx Interrupt Absolute Delay Timer - RW */
#define E1000_SRWR 0x12018 /* Shadow Ram Write Register - RW */
#define E1000_I210_FLMNGCTL 0x12038
#define E1000_I210_FLMNGDATA 0x1203C
#define E1000_I210_FLMNGCNT 0x12040
#define E1000_I210_FLSWCTL 0x12048
#define E1000_I210_FLSWDATA 0x1204C
#define E1000_I210_FLSWCNT 0x12050
#define E1000_I210_FLA 0x1201C
#define E1000_INVM_DATA_REG(_n) (0x12120 + 4*(_n))
#define E1000_INVM_SIZE 64 /* Number of INVM Data Registers */
/* QAV Tx mode control register */
#define E1000_I210_TQAVCTRL 0x3570
/* QAV Tx mode control register bitfields masks */
/* QAV enable */
#define E1000_TQAVCTRL_MODE (1 << 0)
/* Fetching arbitration type */
#define E1000_TQAVCTRL_FETCH_ARB (1 << 4)
/* Fetching timer enable */
#define E1000_TQAVCTRL_FETCH_TIMER_ENABLE (1 << 5)
/* Launch arbitration type */
#define E1000_TQAVCTRL_LAUNCH_ARB (1 << 8)
/* Launch timer enable */
#define E1000_TQAVCTRL_LAUNCH_TIMER_ENABLE (1 << 9)
/* SP waits for SR enable */
#define E1000_TQAVCTRL_SP_WAIT_SR (1 << 10)
/* Fetching timer correction */
#define E1000_TQAVCTRL_FETCH_TIMER_DELTA_OFFSET 16
#define E1000_TQAVCTRL_FETCH_TIMER_DELTA \
(0xFFFF << E1000_TQAVCTRL_FETCH_TIMER_DELTA_OFFSET)
/* High credit registers where _n can be 0 or 1. */
#define E1000_I210_TQAVHC(_n) (0x300C + 0x40 * (_n))
/* Queues fetch arbitration priority control register */
#define E1000_I210_TQAVARBCTRL 0x3574
/* Queues priority masks where _n and _p can be 0-3. */
#define E1000_TQAVARBCTRL_QUEUE_PRI(_n, _p) ((_p) << (2 * _n))
/* QAV Tx mode control registers where _n can be 0 or 1. */
#define E1000_I210_TQAVCC(_n) (0x3004 + 0x40 * (_n))
/* QAV Tx mode control register bitfields masks */
#define E1000_TQAVCC_IDLE_SLOPE 0xFFFF /* Idle slope */
#define E1000_TQAVCC_KEEP_CREDITS (1 << 30) /* Keep credits opt enable */
#define E1000_TQAVCC_QUEUE_MODE (1 << 31) /* SP vs. SR Tx mode */
/* Good transmitted packets counter registers */
#define E1000_PQGPTC(_n) (0x010014 + (0x100 * (_n)))
/* Queues packet buffer size masks where _n can be 0-3 and _s 0-63 [kB] */
#define E1000_I210_TXPBS_SIZE(_n, _s) ((_s) << (6 * _n))
/*
* Convenience macros
*
@@ -197,24 +264,26 @@
#define E1000_FFMT_REG(_i) (0x09000 + ((_i) * 8))
#define E1000_FFVT_REG(_i) (0x09800 + ((_i) * 8))
#define E1000_FFLT_REG(_i) (0x05F00 + ((_i) * 8))
#define E1000_PBSLAC 0x03100 /* Packet Buffer Slave Access Control */
#define E1000_PBSLAD(_n) (0x03110 + (0x4 * (_n))) /* Packet Buffer DWORD (_n) */
#define E1000_PBSLAC 0x03100 /* Pkt Buffer Slave Access Control */
#define E1000_PBSLAD(_n) (0x03110 + (0x4 * (_n))) /* Pkt Buffer DWORD */
#define E1000_TXPBS 0x03404 /* Tx Packet Buffer Size - RW */
#define E1000_ITPBS 0x03404 /* Same as TXPBS, renamed for newer adpaters - RW */
/* Same as TXPBS, renamed for newer Si - RW */
#define E1000_ITPBS 0x03404
#define E1000_TDFH 0x03410 /* Tx Data FIFO Head - RW */
#define E1000_TDFT 0x03418 /* Tx Data FIFO Tail - RW */
#define E1000_TDFHS 0x03420 /* Tx Data FIFO Head Saved - RW */
#define E1000_TDFTS 0x03428 /* Tx Data FIFO Tail Saved - RW */
#define E1000_TDFPC 0x03430 /* Tx Data FIFO Packet Count - RW */
#define E1000_TDPUMB 0x0357C /* DMA Tx Descriptor uC Mail Box - RW */
#define E1000_TDPUAD 0x03580 /* DMA Tx Descriptor uC Addr Command - RW */
#define E1000_TDPUWD 0x03584 /* DMA Tx Descriptor uC Data Write - RW */
#define E1000_TDPURD 0x03588 /* DMA Tx Descriptor uC Data Read - RW */
#define E1000_TDPUCTL 0x0358C /* DMA Tx Descriptor uC Control - RW */
#define E1000_TDPUMB 0x0357C /* DMA Tx Desc uC Mail Box - RW */
#define E1000_TDPUAD 0x03580 /* DMA Tx Desc uC Addr Command - RW */
#define E1000_TDPUWD 0x03584 /* DMA Tx Desc uC Data Write - RW */
#define E1000_TDPURD 0x03588 /* DMA Tx Desc uC Data Read - RW */
#define E1000_TDPUCTL 0x0358C /* DMA Tx Desc uC Control - RW */
#define E1000_DTXCTL 0x03590 /* DMA Tx Control - RW */
#define E1000_DTXTCPFLGL 0x0359C /* DMA Tx Control flag low - RW */
#define E1000_DTXTCPFLGH 0x035A0 /* DMA Tx Control flag high - RW */
#define E1000_DTXMXSZRQ 0x03540 /* DMA Tx Max Total Allow Size Requests - RW */
/* DMA Tx Max Total Allow Size Reqs - RW */
#define E1000_DTXMXSZRQ 0x03540
#define E1000_TIDV 0x03820 /* Tx Interrupt Delay Value - RW */
#define E1000_TADV 0x0382C /* Tx Interrupt Absolute Delay Val - RW */
#define E1000_TSPMT 0x03830 /* TCP Segmentation PAD & Min Threshold - RW */
@@ -307,55 +376,61 @@
#define E1000_PFVFGORLBC(_n) (0x010048 + (0x100 * (_n)))
#define E1000_PFVFGOTLBC(_n) (0x010050 + (0x100 * (_n)))
#define E1000_LSECTXUT 0x04300 /* LinkSec Tx Untagged Packet Count - OutPktsUntagged */
#define E1000_LSECTXPKTE 0x04304 /* LinkSec Encrypted Tx Packets Count - OutPktsEncrypted */
#define E1000_LSECTXPKTP 0x04308 /* LinkSec Protected Tx Packet Count - OutPktsProtected */
#define E1000_LSECTXOCTE 0x0430C /* LinkSec Encrypted Tx Octets Count - OutOctetsEncrypted */
#define E1000_LSECTXOCTP 0x04310 /* LinkSec Protected Tx Octets Count - OutOctetsProtected */
#define E1000_LSECRXUT 0x04314 /* LinkSec Untagged non-Strict Rx Packet Count - InPktsUntagged/InPktsNoTag */
#define E1000_LSECRXOCTD 0x0431C /* LinkSec Rx Octets Decrypted Count - InOctetsDecrypted */
#define E1000_LSECRXOCTV 0x04320 /* LinkSec Rx Octets Validated - InOctetsValidated */
#define E1000_LSECRXBAD 0x04324 /* LinkSec Rx Bad Tag - InPktsBadTag */
#define E1000_LSECRXNOSCI 0x04328 /* LinkSec Rx Packet No SCI Count - InPktsNoSci */
#define E1000_LSECRXUNSCI 0x0432C /* LinkSec Rx Packet Unknown SCI Count - InPktsUnknownSci */
#define E1000_LSECRXUNCH 0x04330 /* LinkSec Rx Unchecked Packets Count - InPktsUnchecked */
#define E1000_LSECRXDELAY 0x04340 /* LinkSec Rx Delayed Packet Count - InPktsDelayed */
#define E1000_LSECRXLATE 0x04350 /* LinkSec Rx Late Packets Count - InPktsLate */
#define E1000_LSECRXOK(_n) (0x04360 + (0x04 * (_n))) /* LinkSec Rx Packet OK Count - InPktsOk */
#define E1000_LSECRXINV(_n) (0x04380 + (0x04 * (_n))) /* LinkSec Rx Invalid Count - InPktsInvalid */
#define E1000_LSECRXNV(_n) (0x043A0 + (0x04 * (_n))) /* LinkSec Rx Not Valid Count - InPktsNotValid */
#define E1000_LSECRXUNSA 0x043C0 /* LinkSec Rx Unused SA Count - InPktsUnusedSa */
#define E1000_LSECRXNUSA 0x043D0 /* LinkSec Rx Not Using SA Count - InPktsNotUsingSa */
#define E1000_LSECTXCAP 0x0B000 /* LinkSec Tx Capabilities Register - RO */
#define E1000_LSECRXCAP 0x0B300 /* LinkSec Rx Capabilities Register - RO */
#define E1000_LSECTXCTRL 0x0B004 /* LinkSec Tx Control - RW */
#define E1000_LSECRXCTRL 0x0B304 /* LinkSec Rx Control - RW */
#define E1000_LSECTXSCL 0x0B008 /* LinkSec Tx SCI Low - RW */
#define E1000_LSECTXSCH 0x0B00C /* LinkSec Tx SCI High - RW */
#define E1000_LSECTXSA 0x0B010 /* LinkSec Tx SA0 - RW */
#define E1000_LSECTXPN0 0x0B018 /* LinkSec Tx SA PN 0 - RW */
#define E1000_LSECTXPN1 0x0B01C /* LinkSec Tx SA PN 1 - RW */
#define E1000_LSECRXSCL 0x0B3D0 /* LinkSec Rx SCI Low - RW */
#define E1000_LSECRXSCH 0x0B3E0 /* LinkSec Rx SCI High - RW */
#define E1000_LSECTXKEY0(_n) (0x0B020 + (0x04 * (_n))) /* LinkSec Tx 128-bit Key 0 - WO */
#define E1000_LSECTXKEY1(_n) (0x0B030 + (0x04 * (_n))) /* LinkSec Tx 128-bit Key 1 - WO */
#define E1000_LSECRXSA(_n) (0x0B310 + (0x04 * (_n))) /* LinkSec Rx SAs - RW */
#define E1000_LSECRXPN(_n) (0x0B330 + (0x04 * (_n))) /* LinkSec Rx SAs - RW */
/* LinkSec */
#define E1000_LSECTXUT 0x04300 /* Tx Untagged Pkt Cnt */
#define E1000_LSECTXPKTE 0x04304 /* Encrypted Tx Pkts Cnt */
#define E1000_LSECTXPKTP 0x04308 /* Protected Tx Pkt Cnt */
#define E1000_LSECTXOCTE 0x0430C /* Encrypted Tx Octets Cnt */
#define E1000_LSECTXOCTP 0x04310 /* Protected Tx Octets Cnt */
#define E1000_LSECRXUT 0x04314 /* Untagged non-Strict Rx Pkt Cnt */
#define E1000_LSECRXOCTD 0x0431C /* Rx Octets Decrypted Count */
#define E1000_LSECRXOCTV 0x04320 /* Rx Octets Validated */
#define E1000_LSECRXBAD 0x04324 /* Rx Bad Tag */
#define E1000_LSECRXNOSCI 0x04328 /* Rx Packet No SCI Count */
#define E1000_LSECRXUNSCI 0x0432C /* Rx Packet Unknown SCI Count */
#define E1000_LSECRXUNCH 0x04330 /* Rx Unchecked Packets Count */
#define E1000_LSECRXDELAY 0x04340 /* Rx Delayed Packet Count */
#define E1000_LSECRXLATE 0x04350 /* Rx Late Packets Count */
#define E1000_LSECRXOK(_n) (0x04360 + (0x04 * (_n))) /* Rx Pkt OK Cnt */
#define E1000_LSECRXINV(_n) (0x04380 + (0x04 * (_n))) /* Rx Invalid Cnt */
#define E1000_LSECRXNV(_n) (0x043A0 + (0x04 * (_n))) /* Rx Not Valid Cnt */
#define E1000_LSECRXUNSA 0x043C0 /* Rx Unused SA Count */
#define E1000_LSECRXNUSA 0x043D0 /* Rx Not Using SA Count */
#define E1000_LSECTXCAP 0x0B000 /* Tx Capabilities Register - RO */
#define E1000_LSECRXCAP 0x0B300 /* Rx Capabilities Register - RO */
#define E1000_LSECTXCTRL 0x0B004 /* Tx Control - RW */
#define E1000_LSECRXCTRL 0x0B304 /* Rx Control - RW */
#define E1000_LSECTXSCL 0x0B008 /* Tx SCI Low - RW */
#define E1000_LSECTXSCH 0x0B00C /* Tx SCI High - RW */
#define E1000_LSECTXSA 0x0B010 /* Tx SA0 - RW */
#define E1000_LSECTXPN0 0x0B018 /* Tx SA PN 0 - RW */
#define E1000_LSECTXPN1 0x0B01C /* Tx SA PN 1 - RW */
#define E1000_LSECRXSCL 0x0B3D0 /* Rx SCI Low - RW */
#define E1000_LSECRXSCH 0x0B3E0 /* Rx SCI High - RW */
/* LinkSec Tx 128-bit Key 0 - WO */
#define E1000_LSECTXKEY0(_n) (0x0B020 + (0x04 * (_n)))
/* LinkSec Tx 128-bit Key 1 - WO */
#define E1000_LSECTXKEY1(_n) (0x0B030 + (0x04 * (_n)))
#define E1000_LSECRXSA(_n) (0x0B310 + (0x04 * (_n))) /* Rx SAs - RW */
#define E1000_LSECRXPN(_n) (0x0B330 + (0x04 * (_n))) /* Rx SAs - RW */
/*
* LinkSec Rx Keys - where _n is the SA no. and _m the 4 dwords of the 128 bit
* key - RW.
*/
#define E1000_LSECRXKEY(_n, _m) (0x0B350 + (0x10 * (_n)) + (0x04 * (_m)))
#define E1000_SSVPC 0x041A0 /* Switch Security Violation Packet Count */
#define E1000_SSVPC 0x041A0 /* Switch Security Violation Pkt Cnt */
#define E1000_IPSCTRL 0xB430 /* IpSec Control Register */
#define E1000_IPSRXCMD 0x0B408 /* IPSec Rx Command Register - RW */
#define E1000_IPSRXIDX 0x0B400 /* IPSec Rx Index - RW */
#define E1000_IPSRXIPADDR(_n) (0x0B420+ (0x04 * (_n))) /* IPSec Rx IPv4/v6 Address - RW */
#define E1000_IPSRXKEY(_n) (0x0B410 + (0x04 * (_n))) /* IPSec Rx 128-bit Key - RW */
/* IPSec Rx IPv4/v6 Address - RW */
#define E1000_IPSRXIPADDR(_n) (0x0B420 + (0x04 * (_n)))
/* IPSec Rx 128-bit Key - RW */
#define E1000_IPSRXKEY(_n) (0x0B410 + (0x04 * (_n)))
#define E1000_IPSRXSALT 0x0B404 /* IPSec Rx Salt - RW */
#define E1000_IPSRXSPI 0x0B40C /* IPSec Rx SPI - RW */
#define E1000_IPSTXKEY(_n) (0x0B460 + (0x04 * (_n))) /* IPSec Tx 128-bit Key - RW */
/* IPSec Tx 128-bit Key - RW */
#define E1000_IPSTXKEY(_n) (0x0B460 + (0x04 * (_n)))
#define E1000_IPSTXSALT 0x0B454 /* IPSec Tx Salt - RW */
#define E1000_IPSTXIDX 0x0B450 /* IPSec Tx SA IDX - RW */
#define E1000_PCS_CFG0 0x04200 /* PCS Configuration 0 - RW */
@@ -378,16 +453,18 @@
#define E1000_PCS_ANADV 0x04218 /* AN advertisement - RW */
#define E1000_PCS_LPAB 0x0421C /* Link Partner Ability - RW */
#define E1000_PCS_NPTX 0x04220 /* AN Next Page Transmit - RW */
#define E1000_PCS_LPABNP 0x04224 /* Link Partner Ability Next Page - RW */
#define E1000_1GSTAT_RCV 0x04228 /* 1GSTAT Code Violation Packet Count - RW */
#define E1000_PCS_LPABNP 0x04224 /* Link Partner Ability Next Pg - RW */
#define E1000_1GSTAT_RCV 0x04228 /* 1GSTAT Code Violation Pkt Cnt - RW */
#define E1000_RXCSUM 0x05000 /* Rx Checksum Control - RW */
#define E1000_RLPML 0x05004 /* Rx Long Packet Max Length */
#define E1000_RFCTL 0x05008 /* Receive Filter Control*/
#define E1000_MTA 0x05200 /* Multicast Table Array - RW Array */
#define E1000_RA 0x05400 /* Receive Address - RW Array */
#define E1000_RA2 0x054E0 /* 2nd half of receive address array - RW Array */
#define E1000_RA2 0x054E0 /* 2nd half of Rx address array - RW Array */
#define E1000_VFTA 0x05600 /* VLAN Filter Table Array - RW Array */
#define E1000_VT_CTL 0x0581C /* VMDq Control - RW */
#define E1000_CIAA 0x05B88 /* Config Indirect Access Address - RW */
#define E1000_CIAD 0x05B8C /* Config Indirect Access Data - RW */
#define E1000_VFQA0 0x0B000 /* VLAN Filter Queue Array 0 - RW Array */
#define E1000_VFQA1 0x0B200 /* VLAN Filter Queue Array 1 - RW Array */
#define E1000_WUC 0x05800 /* Wakeup Control - RW */
@@ -404,15 +481,19 @@
#define E1000_HOST_IF 0x08800 /* Host Interface */
#define E1000_FFMT 0x09000 /* Flexible Filter Mask Table - RW Array */
#define E1000_FFVT 0x09800 /* Flexible Filter Value Table - RW Array */
#define E1000_FHFT(_n) (0x09000 + (_n * 0x100)) /* Flexible Host Filter Table */
#define E1000_FHFT_EXT(_n) (0x09A00 + (_n * 0x100)) /* Ext Flexible Host Filter Table */
#define E1000_HIBBA 0x8F40 /* Host Interface Buffer Base Address */
/* Flexible Host Filter Table */
#define E1000_FHFT(_n) (0x09000 + ((_n) * 0x100))
/* Ext Flexible Host Filter Table */
#define E1000_FHFT_EXT(_n) (0x09A00 + ((_n) * 0x100))
#define E1000_KMRNCTRLSTA 0x00034 /* MAC-PHY interface - RW */
#define E1000_MDPHYA 0x0003C /* PHY address - RW */
#define E1000_MANC2H 0x05860 /* Management Control To Host - RW */
#define E1000_MDEF(_n) (0x05890 + (4 * (_n))) /* Mngmt Decision Filters */
#define E1000_SW_FW_SYNC 0x05B5C /* Software-Firmware Synchronization - RW */
/* Management Decision Filters */
#define E1000_MDEF(_n) (0x05890 + (4 * (_n)))
#define E1000_SW_FW_SYNC 0x05B5C /* SW-FW Synchronization - RW */
#define E1000_CCMCTL 0x05B48 /* CCM Control Register */
#define E1000_GIOCTL 0x05B44 /* GIO Analog Control Register */
#define E1000_SCCTL 0x05B4C /* PCIc PLL Configuration Register */
@@ -425,7 +506,8 @@
#define E1000_FACTPS 0x05B30 /* Function Active and Power State to MNG */
#define E1000_SWSM 0x05B50 /* SW Semaphore */
#define E1000_FWSM 0x05B54 /* FW Semaphore */
#define E1000_SWSM2 0x05B58 /* Driver-only SW semaphore (not used by BOOT agents) */
/* Driver-only SW semaphore (not used by BOOT agents) */
#define E1000_SWSM2 0x05B58
#define E1000_DCA_ID 0x05B70 /* DCA Requester ID Information - RO */
#define E1000_DCA_CTRL 0x05B74 /* DCA Control - RW */
#define E1000_UFUSE 0x05B78 /* UFUSE - RO */
@@ -437,18 +519,17 @@
#define E1000_CPUVEC 0x02C10 /* CPU Vector Register - RW */
#define E1000_MRQC 0x05818 /* Multiple Receive Control - RW */
#define E1000_IMIR(_i) (0x05A80 + ((_i) * 4)) /* Immediate Interrupt */
#define E1000_IMIREXT(_i) (0x05AA0 + ((_i) * 4)) /* Immediate Interrupt Ext*/
#define E1000_IMIRVP 0x05AC0 /* Immediate Interrupt Rx VLAN Priority - RW */
#define E1000_MSIXBM(_i) (0x01600 + ((_i) * 4)) /* MSI-X Allocation Register
* (_i) - RW */
#define E1000_MSIXTADD(_i) (0x0C000 + ((_i) * 0x10)) /* MSI-X Table entry addr
* low reg - RW */
#define E1000_MSIXTUADD(_i) (0x0C004 + ((_i) * 0x10)) /* MSI-X Table entry addr
* upper reg - RW */
#define E1000_MSIXTMSG(_i) (0x0C008 + ((_i) * 0x10)) /* MSI-X Table entry
* message reg - RW */
#define E1000_MSIXVCTRL(_i) (0x0C00C + ((_i) * 0x10)) /* MSI-X Table entry
* vector ctrl reg - RW */
#define E1000_IMIREXT(_i) (0x05AA0 + ((_i) * 4)) /* Immediate INTR Ext*/
#define E1000_IMIRVP 0x05AC0 /* Immediate INT Rx VLAN Priority -RW */
#define E1000_MSIXBM(_i) (0x01600 + ((_i) * 4)) /* MSI-X Alloc Reg -RW */
/* MSI-X Table entry addr low reg - RW */
#define E1000_MSIXTADD(_i) (0x0C000 + ((_i) * 0x10))
/* MSI-X Table entry addr upper reg - RW */
#define E1000_MSIXTUADD(_i) (0x0C004 + ((_i) * 0x10))
/* MSI-X Table entry message reg - RW */
#define E1000_MSIXTMSG(_i) (0x0C008 + ((_i) * 0x10))
/* MSI-X Table entry vector ctrl reg - RW */
#define E1000_MSIXVCTRL(_i) (0x0C00C + ((_i) * 0x10))
#define E1000_MSIXPBA 0x0E000 /* MSI-X Pending bit array */
#define E1000_RETA(_i) (0x05C00 + ((_i) * 4)) /* Redirection Table - RW */
#define E1000_RSSRK(_i) (0x05C80 + ((_i) * 4)) /* RSS Random Key - RW */
@@ -482,11 +563,11 @@
#define E1000_VMBMEM(_n) (0x00800 + (64 * (_n)))
#define E1000_VFVMBMEM(_n) (0x00800 + (_n))
#define E1000_VMOLR(_n) (0x05AD0 + (4 * (_n)))
#define E1000_VLVF(_n) (0x05D00 + (4 * (_n))) /* VLAN Virtual Machine
* Filter - RW */
/* VLAN Virtual Machine Filter - RW */
#define E1000_VLVF(_n) (0x05D00 + (4 * (_n)))
#define E1000_VMVIR(_n) (0x03700 + (4 * (_n)))
#define E1000_DVMOLR(_n) (0x0C038 + (0x40 * (_n))) /* DMA VM offload */
/* Time Sync */
#define E1000_VTCTRL(_n) (0x10000 + (0x100 * (_n))) /* VT Control */
#define E1000_TSYNCRXCTL 0x0B620 /* Rx Time Sync Control register - RW */
#define E1000_TSYNCTXCTL 0x0B614 /* Tx Time Sync Control register - RW */
#define E1000_TSYNCRXCFG 0x05F50 /* Time Sync Rx Configuration - RW */
@@ -518,17 +599,28 @@
#define E1000_RTRPCS 0x2474 /* Rx packet plane control and status */
#define E1000_RTRUP2TC 0x05AC4 /* Rx User Priority to Traffic Class */
#define E1000_RTTUP2TC 0x0418 /* Transmit User Priority to Traffic Class */
#define E1000_RTTDTCRC(_n) (0x3610 + ((_n) * 4)) /* Tx Desc plane TC Rate-scheduler config */
#define E1000_RTTPTCRC(_n) (0x3480 + ((_n) * 4)) /* Tx Packet plane TC Rate-Scheduler Config */
#define E1000_RTRPTCRC(_n) (0x2480 + ((_n) * 4)) /* Rx Packet plane TC Rate-Scheduler Config */
#define E1000_RTTDTCRS(_n) (0x3630 + ((_n) * 4)) /* Tx Desc Plane TC Rate-Scheduler Status */
#define E1000_RTTDTCRM(_n) (0x3650 + ((_n) * 4)) /* Tx Desc Plane TC Rate-Scheduler MMW */
#define E1000_RTTPTCRS(_n) (0x34A0 + ((_n) * 4)) /* Tx Packet plane TC Rate-Scheduler Status */
#define E1000_RTTPTCRM(_n) (0x34C0 + ((_n) * 4)) /* Tx Packet plane TC Rate-scheduler MMW */
#define E1000_RTRPTCRS(_n) (0x24A0 + ((_n) * 4)) /* Rx Packet plane TC Rate-Scheduler Status */
#define E1000_RTRPTCRM(_n) (0x24C0 + ((_n) * 4)) /* Rx Packet plane TC Rate-Scheduler MMW */
#define E1000_RTTDVMRM(_n) (0x3670 + ((_n) * 4)) /* Tx Desc plane VM Rate-Scheduler MMW*/
#define E1000_RTTBCNRM(_n) (0x3690 + ((_n) * 4)) /* Tx BCN Rate-Scheduler MMW */
/* Tx Desc plane TC Rate-scheduler config */
#define E1000_RTTDTCRC(_n) (0x3610 + ((_n) * 4))
/* Tx Packet plane TC Rate-Scheduler Config */
#define E1000_RTTPTCRC(_n) (0x3480 + ((_n) * 4))
/* Rx Packet plane TC Rate-Scheduler Config */
#define E1000_RTRPTCRC(_n) (0x2480 + ((_n) * 4))
/* Tx Desc Plane TC Rate-Scheduler Status */
#define E1000_RTTDTCRS(_n) (0x3630 + ((_n) * 4))
/* Tx Desc Plane TC Rate-Scheduler MMW */
#define E1000_RTTDTCRM(_n) (0x3650 + ((_n) * 4))
/* Tx Packet plane TC Rate-Scheduler Status */
#define E1000_RTTPTCRS(_n) (0x34A0 + ((_n) * 4))
/* Tx Packet plane TC Rate-scheduler MMW */
#define E1000_RTTPTCRM(_n) (0x34C0 + ((_n) * 4))
/* Rx Packet plane TC Rate-Scheduler Status */
#define E1000_RTRPTCRS(_n) (0x24A0 + ((_n) * 4))
/* Rx Packet plane TC Rate-Scheduler MMW */
#define E1000_RTRPTCRM(_n) (0x24C0 + ((_n) * 4))
/* Tx Desc plane VM Rate-Scheduler MMW*/
#define E1000_RTTDVMRM(_n) (0x3670 + ((_n) * 4))
/* Tx BCN Rate-Scheduler MMW */
#define E1000_RTTBCNRM(_n) (0x3690 + ((_n) * 4))
#define E1000_RTTDQSEL 0x3604 /* Tx Desc Plane Queue Select */
#define E1000_RTTDVMRC 0x3608 /* Tx Desc Plane VM Rate-Scheduler Config */
#define E1000_RTTDVMRS 0x360C /* Tx Desc Plane VM Rate-Scheduler Status */
@@ -565,7 +657,7 @@
#define E1000_THHIGHTC 0x0810C /* High Threshold Control */
#define E1000_THSTAT 0x08110 /* Thermal Sensor Status */
/*Energy Efficient Ethernet "EEE" registers */
/* Energy Efficient Ethernet "EEE" registers */
#define E1000_IPCNFG 0x0E38 /* Internal PHY Configuration */
#define E1000_LTRC 0x01A0 /* Latency Tolerance Reporting Control */
#define E1000_EEER 0x0E30 /* Energy Efficient Ethernet "EEE"*/
@@ -579,4 +671,9 @@
#define E1000_O2BGPTC 0x08FE4 /* OS2BMC packets received by BMC */
#define E1000_O2BSPC 0x0415C /* OS2BMC packets transmitted by host */
#define E1000_LTRMINV 0x5BB0 /* LTR Minimum Value */
#define E1000_LTRMAXV 0x5BB4 /* LTR Maximum Value */
#define E1000_DOBFFCTL 0x3F24 /* DMA OBFF Control Register */
#endif
@@ -1,6 +1,6 @@
/******************************************************************************
Copyright (c) 2001-2010, Intel Corporation
Copyright (c) 2001-2011, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -30,7 +30,7 @@
POSSIBILITY OF SUCH DAMAGE.
******************************************************************************/
/*$FreeBSD: src/sys/dev/e1000/e1000_vf.c,v 1.1.2.2.2.1 2010/12/21 17:09:25 kensmith Exp $*/
/*$FreeBSD$*/
#include "e1000_api.h"
@@ -374,6 +374,17 @@ static u32 e1000_hash_mc_addr_vf(struct e1000_hw *hw, u8 *mc_addr)
return hash_value;
}
static void e1000_write_msg_read_ack(struct e1000_hw *hw,
u32 *msg, u16 size)
{
struct e1000_mbx_info *mbx = &hw->mbx;
u32 retmsg[E1000_VFMAILBOX_SIZE];
s32 retval = mbx->ops.write_posted(hw, msg, size, 0);
if (!retval)
mbx->ops.read_posted(hw, retmsg, E1000_VFMAILBOX_SIZE, 0);
}
/**
* e1000_update_mc_addr_list_vf - Update Multicast addresses
* @hw: pointer to the HW structure
@@ -386,7 +397,6 @@ static u32 e1000_hash_mc_addr_vf(struct e1000_hw *hw, u8 *mc_addr)
void e1000_update_mc_addr_list_vf(struct e1000_hw *hw,
u8 *mc_addr_list, u32 mc_addr_count)
{
struct e1000_mbx_info *mbx = &hw->mbx;
u32 msgbuf[E1000_VFMAILBOX_SIZE];
u16 *hash_list = (u16 *)&msgbuf[1];
u32 hash_value;
@@ -420,7 +430,7 @@ void e1000_update_mc_addr_list_vf(struct e1000_hw *hw,
mc_addr_list += ETH_ADDR_LEN;
}
mbx->ops.write_posted(hw, msgbuf, E1000_VFMAILBOX_SIZE, 0);
e1000_write_msg_read_ack(hw, msgbuf, E1000_VFMAILBOX_SIZE);
}
/**
@@ -431,7 +441,6 @@ void e1000_update_mc_addr_list_vf(struct e1000_hw *hw,
**/
void e1000_vfta_set_vf(struct e1000_hw *hw, u16 vid, bool set)
{
struct e1000_mbx_info *mbx = &hw->mbx;
u32 msgbuf[2];
msgbuf[0] = E1000_VF_SET_VLAN;
@@ -440,7 +449,7 @@ void e1000_vfta_set_vf(struct e1000_hw *hw, u16 vid, bool set)
if (set)
msgbuf[0] |= E1000_VF_SET_VLAN_ADD;
mbx->ops.write_posted(hw, msgbuf, 2, 0);
e1000_write_msg_read_ack(hw, msgbuf, 2);
}
/** e1000_rlpml_set_vf - Set the maximum receive packet length
@@ -449,13 +458,12 @@ void e1000_vfta_set_vf(struct e1000_hw *hw, u16 vid, bool set)
**/
void e1000_rlpml_set_vf(struct e1000_hw *hw, u16 max_size)
{
struct e1000_mbx_info *mbx = &hw->mbx;
u32 msgbuf[2];
msgbuf[0] = E1000_VF_SET_LPE;
msgbuf[1] = max_size;
mbx->ops.write_posted(hw, msgbuf, 2, 0);
e1000_write_msg_read_ack(hw, msgbuf, 2);
}
/**
@@ -30,7 +30,7 @@
POSSIBILITY OF SUCH DAMAGE.
******************************************************************************/
/*$FreeBSD: src/sys/dev/e1000/e1000_vf.h,v 1.1.2.2.2.1 2010/12/21 17:09:25 kensmith Exp $*/
/*$FreeBSD$*/
#ifndef _E1000_VF_H_
#define _E1000_VF_H_
File diff suppressed because it is too large Load Diff
@@ -30,7 +30,7 @@
POSSIBILITY OF SUCH DAMAGE.
******************************************************************************/
/*$FreeBSD: src/sys/dev/e1000/if_em.h,v 1.5.2.5.2.1 2010/12/21 17:09:25 kensmith Exp $*/
/*$FreeBSD$*/
#ifndef _EM_H_DEFINED_
@@ -212,7 +212,8 @@
#define EM_BAR_MEM_TYPE_64BIT 0x00000004
#define EM_MSIX_BAR 3 /* On 82575 */
#if !defined(SYSCTL_ADD_UQUAD)
/* More backward compatibility */
#if __FreeBSD_version < 900000
#define SYSCTL_ADD_UQUAD SYSCTL_ADD_QUAD
#endif
@@ -418,11 +419,11 @@ struct adapter {
u32 shadow_vfta[EM_VFTA_SIZE];
/* Info about the interface */
u8 link_active;
u16 link_active;
u16 fc;
u16 link_speed;
u16 link_duplex;
u32 smartspeed;
u32 fc_setting;
struct em_int_delay_info tx_int_delay;
struct em_int_delay_info tx_abs_int_delay;
File diff suppressed because it is too large Load Diff
@@ -30,7 +30,7 @@
POSSIBILITY OF SUCH DAMAGE.
******************************************************************************/
/*$FreeBSD: src/sys/dev/e1000/if_igb.h,v 1.4.2.6.2.1 2010/12/21 17:09:25 kensmith Exp $*/
/*$FreeBSD$*/
#ifndef _IGB_H_DEFINED_
#define _IGB_H_DEFINED_
@@ -52,7 +52,7 @@
#define IGB_MAX_TXD 4096
/*
* IGB_RXD: Maximum number of Transmit Descriptors
* IGB_RXD: Maximum number of Receive Descriptors
*
* This value is the number of receive descriptors allocated by the driver.
* Increasing this value allows the driver to buffer more incoming packets.
@@ -188,9 +188,13 @@
#define IGB_TX_BUFFER_SIZE ((uint32_t) 1514)
#define IGB_FC_PAUSE_TIME 0x0680
#define IGB_EEPROM_APME 0x400;
#define IGB_QUEUE_IDLE 0
#define IGB_QUEUE_WORKING 1
#define IGB_QUEUE_HUNG 2
/* Queue minimum free for use */
#define IGB_QUEUE_THRESHOLD (adapter->num_tx_desc / 8)
/* Queue bit defines */
#define IGB_QUEUE_IDLE 1
#define IGB_QUEUE_WORKING 2
#define IGB_QUEUE_HUNG 4
#define IGB_QUEUE_DEPLETED 8
/*
* TDBA/RDBA should be aligned on 16 byte boundary. But TDLEN/RDLEN should be
@@ -1,6 +1,6 @@
/******************************************************************************
Copyright (c) 2001-2010, Intel Corporation
Copyright (c) 2001-2011, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -30,11 +30,12 @@
POSSIBILITY OF SUCH DAMAGE.
******************************************************************************/
/*$FreeBSD: src/sys/dev/e1000/if_lem.c,v 1.3.2.10.2.1 2010/12/21 17:09:25 kensmith Exp $*/
/*$FreeBSD$*/
#ifdef HAVE_KERNEL_OPTION_HEADERS
#include "opt_device_polling.h"
#include "opt_inet.h"
#include "opt_inet6.h"
#endif
#include <sys/param.h>
@@ -74,11 +75,7 @@
#include <netinet/udp.h>
#include <machine/in_cksum.h>
#ifndef __HAIKU__
#include <dev/led/led.h>
#endif
#include <dev/pci/pcivar.h>
#include <dev/pci/pcireg.h>
@@ -88,7 +85,7 @@
/*********************************************************************
* Legacy Em Driver version:
*********************************************************************/
char lem_driver_version[] = "1.0.3";
char lem_driver_version[] = "1.0.4";
/*********************************************************************
* PCI Device ID Table
@@ -271,22 +268,12 @@ static device_method_t lem_methods[] = {
{0, 0}
};
#ifndef __HAIKU__
static driver_t lem_driver = {
"em", lem_methods, sizeof(struct adapter),
};
extern devclass_t em_devclass;
DRIVER_MODULE(lem, pci, lem_driver, em_devclass, 0, 0);
#else
static driver_t lem_driver = {
"lem", lem_methods, sizeof(struct adapter),
};
devclass_t lem_devclass;
DRIVER_MODULE(lem, pci, lem_driver, lem_devclass, 0, 0);
#endif
MODULE_DEPEND(lem, pci, 1, 1, 1);
MODULE_DEPEND(lem, ether, 1, 1, 1);
@@ -330,6 +317,10 @@ TUNABLE_INT("hw.em.fc_setting", &lem_fc_setting);
/* Global used in WOL setup with multiport cards */
static int global_quad_port_a = 0;
#ifdef DEV_NETMAP /* see ixgbe.c for details */
#include <dev/netmap/if_lem_netmap.h>
#endif /* DEV_NETMAP */
/*********************************************************************
* Device identification routine
*
@@ -400,6 +391,11 @@ lem_attach(device_t dev)
INIT_DEBUGOUT("lem_attach: begin");
if (resource_disabled("lem", device_get_unit(dev))) {
device_printf(dev, "Disabled by device hint\n");
return (ENXIO);
}
adapter = device_get_softc(dev);
adapter->dev = adapter->osdep.dev = dev;
EM_CORE_LOCK_INIT(adapter, device_get_nameunit(dev));
@@ -463,7 +459,7 @@ lem_attach(device_t dev)
/* Sysctl for setting the interface flow control */
lem_set_flow_cntrl(adapter, "flow_control",
"max number of rx packets to process",
"flow control setting",
&adapter->fc_setting, lem_fc_setting);
/*
@@ -657,11 +653,12 @@ lem_attach(device_t dev)
/* Tell the stack that the interface is not active */
adapter->ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
#ifndef __HAIKU__
adapter->led_dev = led_create(lem_led_func, adapter,
device_get_nameunit(dev));
#endif
#ifdef DEV_NETMAP
lem_netmap_attach(adapter);
#endif /* DEV_NETMAP */
INIT_DEBUGOUT("lem_attach: end");
return (0);
@@ -716,10 +713,8 @@ lem_detach(device_t dev)
ether_poll_deregister(ifp);
#endif
#ifndef __HAIKU__
if (adapter->led_dev != NULL)
led_destroy(adapter->led_dev);
#endif
EM_CORE_LOCK(adapter);
EM_TX_LOCK(adapter);
@@ -742,6 +737,9 @@ lem_detach(device_t dev)
callout_drain(&adapter->timer);
callout_drain(&adapter->tx_fifo_timer);
#ifdef DEV_NETMAP
netmap_detach(ifp);
#endif /* DEV_NETMAP */
lem_free_pci_resources(adapter);
bus_generic_detach(dev);
if_free(ifp);
@@ -899,9 +897,10 @@ lem_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
{
struct adapter *adapter = ifp->if_softc;
struct ifreq *ifr = (struct ifreq *)data;
#ifdef INET
#if defined(INET) || defined(INET6)
struct ifaddr *ifa = (struct ifaddr *)data;
#endif
bool avoid_reset = FALSE;
int error = 0;
if (adapter->in_detach)
@@ -910,23 +909,26 @@ lem_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
switch (command) {
case SIOCSIFADDR:
#ifdef INET
if (ifa->ifa_addr->sa_family == AF_INET) {
/*
* XXX
* Since resetting hardware takes a very long time
* and results in link renegotiation we only
* initialize the hardware only when it is absolutely
* required.
*/
ifp->if_flags |= IFF_UP;
if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
EM_CORE_LOCK(adapter);
lem_init_locked(adapter);
EM_CORE_UNLOCK(adapter);
}
arp_ifinit(ifp, ifa);
} else
if (ifa->ifa_addr->sa_family == AF_INET)
avoid_reset = TRUE;
#endif
#ifdef INET6
if (ifa->ifa_addr->sa_family == AF_INET6)
avoid_reset = TRUE;
#endif
/*
** Calling init results in link renegotiation,
** so we avoid doing it when possible.
*/
if (avoid_reset) {
ifp->if_flags |= IFF_UP;
if (!(ifp->if_drv_flags & IFF_DRV_RUNNING))
lem_init(adapter);
#ifdef INET
if (!(ifp->if_flags & IFF_NOARP))
arp_ifinit(ifp, ifa);
#endif
} else
error = ether_ioctl(ifp, command, data);
break;
case SIOCSIFMTU:
@@ -1225,9 +1227,6 @@ lem_init_locked(struct adapter *adapter)
/* AMT based hardware can now take control from firmware */
if (adapter->has_manage && adapter->has_amt)
lem_get_hw_control(adapter);
/* Don't reset the phy next time init gets called */
adapter->hw.phy.reset_disable = TRUE;
}
static void
@@ -1526,11 +1525,6 @@ lem_media_change(struct ifnet *ifp)
device_printf(adapter->dev, "Unsupported media type\n");
}
/* As the speed/duplex settings my have changed we need to
* reset the PHY.
*/
adapter->hw.phy.reset_disable = FALSE;
lem_init_locked(adapter);
EM_CORE_UNLOCK(adapter);
@@ -2360,7 +2354,6 @@ lem_setup_interface(device_t dev, struct adapter *adapter)
return (-1);
}
if_initname(ifp, device_get_name(dev), device_get_unit(dev));
ifp->if_mtu = ETHERMTU;
ifp->if_init = lem_init;
ifp->if_softc = adapter;
ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
@@ -2601,7 +2594,6 @@ lem_allocate_transmit_structures(struct adapter *adapter)
device_t dev = adapter->dev;
struct em_buffer *tx_buffer;
int error;
int i = 0;
/*
* Create DMA tags for tx descriptors
@@ -2631,7 +2623,7 @@ lem_allocate_transmit_structures(struct adapter *adapter)
}
/* Create the descriptor buffer dma maps */
for (i = 0; i < adapter->num_tx_desc; i++) {
for (int i = 0; i < adapter->num_tx_desc; i++) {
tx_buffer = &adapter->tx_buffer_area[i];
error = bus_dmamap_create(adapter->txtag, 0, &tx_buffer->map);
if (error != 0) {
@@ -2656,20 +2648,37 @@ static void
lem_setup_transmit_structures(struct adapter *adapter)
{
struct em_buffer *tx_buffer;
int i = 0;
#ifdef DEV_NETMAP
/* we are already locked */
struct netmap_adapter *na = NA(adapter->ifp);
struct netmap_slot *slot = netmap_reset(na, NR_TX, 0, 0);
#endif /* DEV_NETMAP */
/* Clear the old ring contents */
bzero(adapter->tx_desc_base,
(sizeof(struct e1000_tx_desc)) * adapter->num_tx_desc);
/* Free any existing TX buffers */
for (i = 0; i < adapter->num_tx_desc; i++, tx_buffer++) {
for (int i = 0; i < adapter->num_tx_desc; i++, tx_buffer++) {
tx_buffer = &adapter->tx_buffer_area[i];
bus_dmamap_sync(adapter->txtag, tx_buffer->map,
BUS_DMASYNC_POSTWRITE);
bus_dmamap_unload(adapter->txtag, tx_buffer->map);
m_freem(tx_buffer->m_head);
tx_buffer->m_head = NULL;
#ifdef DEV_NETMAP
if (slot) {
/* the i-th NIC entry goes to slot si */
int si = netmap_idx_n2k(&na->tx_rings[0], i);
uint64_t paddr;
void *addr;
addr = PNMB(slot + si, &paddr);
adapter->tx_desc_base[si].buffer_addr = htole64(paddr);
/* reload the map for netmap mode */
netmap_load_map(adapter->txtag, tx_buffer->map, addr);
}
#endif /* DEV_NETMAP */
tx_buffer->next_eop = -1;
}
@@ -2762,12 +2771,11 @@ static void
lem_free_transmit_structures(struct adapter *adapter)
{
struct em_buffer *tx_buffer;
int i = 0;
INIT_DEBUGOUT("free_transmit_structures: begin");
if (adapter->tx_buffer_area != NULL) {
for (i = 0; i < adapter->num_tx_desc; i++) {
for (int i = 0; i < adapter->num_tx_desc; i++) {
tx_buffer = &adapter->tx_buffer_area[i];
if (tx_buffer->m_head != NULL) {
bus_dmamap_sync(adapter->txtag, tx_buffer->map,
@@ -2794,13 +2802,10 @@ lem_free_transmit_structures(struct adapter *adapter)
bus_dma_tag_destroy(adapter->txtag);
adapter->txtag = NULL;
}
#ifndef __HAIKU__
#if __FreeBSD_version >= 800000
if (adapter->br != NULL)
buf_ring_free(adapter->br, M_DEVBUF);
#endif
#endif
}
/*********************************************************************
@@ -2975,6 +2980,12 @@ lem_txeof(struct adapter *adapter)
EM_TX_LOCK_ASSERT(adapter);
#ifdef DEV_NETMAP
if (ifp->if_capenable & IFCAP_NETMAP) {
selwakeuppri(&NA(ifp)->tx_rings[0].si, PI_NET);
return;
}
#endif /* DEV_NETMAP */
if (adapter->num_tx_desc_avail == adapter->num_tx_desc)
return;
@@ -3205,6 +3216,11 @@ lem_setup_receive_structures(struct adapter *adapter)
{
struct em_buffer *rx_buffer;
int i, error;
#ifdef DEV_NETMAP
/* we are already under lock */
struct netmap_adapter *na = NA(adapter->ifp);
struct netmap_slot *slot = netmap_reset(na, NR_RX, 0, 0);
#endif
/* Reset descriptor ring */
bzero(adapter->rx_desc_base,
@@ -3224,6 +3240,20 @@ lem_setup_receive_structures(struct adapter *adapter)
/* Allocate new ones. */
for (i = 0; i < adapter->num_rx_desc; i++) {
#ifdef DEV_NETMAP
if (slot) {
/* the i-th NIC entry goes to slot si */
int si = netmap_idx_n2k(&na->rx_rings[0], i);
uint64_t paddr;
void *addr;
addr = PNMB(slot + si, &paddr);
netmap_load_map(adapter->rxtag, rx_buffer->map, addr);
/* Update descriptor */
adapter->rx_desc_base[i].buffer_addr = htole64(paddr);
continue;
}
#endif /* DEV_NETMAP */
error = lem_get_buf(adapter, i);
if (error)
return (error);
@@ -3251,7 +3281,6 @@ lem_initialize_receive_unit(struct adapter *adapter)
struct ifnet *ifp = adapter->ifp;
u64 bus_addr;
u32 rctl, rxcsum;
int i = 0;
INIT_DEBUGOUT("lem_initialize_receive_unit: begin");
@@ -3277,7 +3306,7 @@ lem_initialize_receive_unit(struct adapter *adapter)
** using the EITR register (82574 only)
*/
if (adapter->msix)
for (i = 0; i < 4; i++)
for (int i = 0; i < 4; i++)
E1000_WRITE_REG(&adapter->hw,
E1000_EITR_82574(i), DEFAULT_ITR);
@@ -3349,6 +3378,18 @@ lem_initialize_receive_unit(struct adapter *adapter)
* Tail Descriptor Pointers
*/
E1000_WRITE_REG(&adapter->hw, E1000_RDH(0), 0);
#ifdef DEV_NETMAP
/* preserve buffers already made available to clients */
if (ifp->if_capenable & IFCAP_NETMAP) {
struct netmap_adapter *na = NA(adapter->ifp);
struct netmap_kring *kring = &na->rx_rings[0];
int t = na->num_rx_desc - 1 - kring->nr_hwavail;
if (t >= na->num_rx_desc)
t -= na->num_rx_desc;
E1000_WRITE_REG(&adapter->hw, E1000_RDT(0), t);
} else
#endif /* DEV_NETMAP */
E1000_WRITE_REG(&adapter->hw, E1000_RDT(0), adapter->num_rx_desc - 1);
return;
@@ -3419,7 +3460,7 @@ lem_free_receive_structures(struct adapter *adapter)
static bool
lem_rxeof(struct adapter *adapter, int count, int *done)
{
struct ifnet *ifp = adapter->ifp;
struct ifnet *ifp = adapter->ifp;;
struct mbuf *mp;
u8 status = 0, accept_frame = 0, eop = 0;
u16 len, desc_len, prev_len_adj;
@@ -3432,6 +3473,16 @@ lem_rxeof(struct adapter *adapter, int count, int *done)
bus_dmamap_sync(adapter->rxdma.dma_tag, adapter->rxdma.dma_map,
BUS_DMASYNC_POSTREAD);
#ifdef DEV_NETMAP
if (ifp->if_capenable & IFCAP_NETMAP) {
struct netmap_adapter *na = NA(ifp);
na->rx_rings[0].nr_kflags |= NKR_PENDINTR;
selwakeuppri(&na->rx_rings[0].si, PI_NET);
EM_RX_UNLOCK(adapter);
return (0);
}
#endif /* DEV_NETMAP */
if (!((current_desc->status) & E1000_RXD_STAT_DD)) {
if (done != NULL)
*done = rx_sent;
@@ -3535,8 +3586,7 @@ lem_rxeof(struct adapter *adapter, int count, int *done)
#endif
if (status & E1000_RXD_STAT_VP) {
adapter->fmp->m_pkthdr.ether_vtag =
(le16toh(current_desc->special) &
E1000_RXD_SPC_VLAN_MASK);
le16toh(current_desc->special);
adapter->fmp->m_flags |= M_VLANTAG;
}
#ifndef __NO_STRICT_ALIGNMENT
@@ -3744,7 +3794,6 @@ lem_setup_vlan_hw_support(struct adapter *adapter)
{
struct e1000_hw *hw = &adapter->hw;
u32 reg;
int i = 0;
/*
** We get here thru init_locked, meaning
@@ -3759,7 +3808,7 @@ lem_setup_vlan_hw_support(struct adapter *adapter)
** A soft reset zero's out the VFTA, so
** we need to repopulate it now.
*/
for (i = 0; i < EM_VFTA_SIZE; i++)
for (int i = 0; i < EM_VFTA_SIZE; i++)
if (adapter->shadow_vfta[i] != 0)
E1000_WRITE_REG_ARRAY(hw, E1000_VFTA,
i, adapter->shadow_vfta[i]);
@@ -4027,10 +4076,9 @@ lem_enable_phy_wakeup(struct adapter *adapter)
struct e1000_hw *hw = &adapter->hw;
u32 mreg, ret = 0;
u16 preg;
int i = 0;
/* copy MAC RARs to PHY RARs */
for (i = 0; i < adapter->hw.mac.rar_entry_count; i++) {
for (int i = 0; i < adapter->hw.mac.rar_entry_count; i++) {
mreg = E1000_READ_REG(hw, E1000_RAL(i));
e1000_write_phy_reg(hw, BM_RAR_L(i), (u16)(mreg & 0xFFFF));
e1000_write_phy_reg(hw, BM_RAR_M(i),
@@ -4042,7 +4090,7 @@ lem_enable_phy_wakeup(struct adapter *adapter)
}
/* copy MAC MTA to PHY MTA */
for (i = 0; i < adapter->hw.mac.mta_reg_count; i++) {
for (int i = 0; i < adapter->hw.mac.mta_reg_count; i++) {
mreg = E1000_READ_REG_ARRAY(hw, E1000_MTA, i);
e1000_write_phy_reg(hw, BM_MTA(i), (u16)(mreg & 0xFFFF));
e1000_write_phy_reg(hw, BM_MTA(i) + 1,
@@ -4277,11 +4325,8 @@ lem_sysctl_reg_handler(SYSCTL_HANDLER_ARGS)
struct adapter *adapter;
u_int val;
#ifndef __HAIKU__
adapter = oidp->oid_arg1;
val = E1000_READ_REG(&adapter->hw, oidp->oid_arg2);
#endif
return (sysctl_handle_int(oidp, &val, 0, req));
}
@@ -1,6 +1,6 @@
/******************************************************************************
Copyright (c) 2001-2010, Intel Corporation
Copyright (c) 2001-2011, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -30,7 +30,7 @@
POSSIBILITY OF SUCH DAMAGE.
******************************************************************************/
/*$FreeBSD: src/sys/dev/e1000/if_lem.h,v 1.2.2.5.2.1 2010/12/21 17:09:25 kensmith Exp $*/
/*$FreeBSD$*/
#ifndef _LEM_H_DEFINED_
@@ -217,7 +217,7 @@
#define EM_BAR_MEM_TYPE_64BIT 0x00000004
#define EM_MSIX_BAR 3 /* On 82575 */
#if !defined(SYSCTL_ADD_UQUAD)
#if __FreeBSD_version < 900000
#define SYSCTL_ADD_UQUAD SYSCTL_ADD_QUAD
#endif
@@ -26,7 +26,7 @@
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: src/sys/dev/jme/if_jme.c,v 1.11.2.8.2.1 2010/12/21 17:09:25 kensmith Exp $");
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
@@ -1661,7 +1661,7 @@ jme_resume(device_t dev)
sc = device_get_softc(dev);
JME_LOCK(sc);
if (pci_find_cap(sc->jme_dev, PCIY_PMG, &pmc) != 0) {
if (pci_find_cap(sc->jme_dev, PCIY_PMG, &pmc) == 0) {
pmstat = pci_read_config(sc->jme_dev,
pmc + PCIR_POWER_STATUS, 2);
/* Disable PME clear PME status. */
@@ -24,7 +24,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD: src/sys/dev/jme/if_jmereg.h,v 1.6.2.2.2.1 2010/12/21 17:09:25 kensmith Exp $
* $FreeBSD$
*/
#ifndef _IF_JMEREG_H
@@ -24,7 +24,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD: src/sys/dev/jme/if_jmevar.h,v 1.3.2.1.6.1 2010/12/21 17:09:25 kensmith Exp $
* $FreeBSD$
*/
#ifndef _IF_JMEVAR_H
@@ -26,7 +26,7 @@
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: src/sys/dev/mii/jmphy.c,v 1.1.6.5.2.1 2010/12/21 17:09:25 kensmith Exp $");
__FBSDID("$FreeBSD$");
/*
* Driver for the JMicron JMP211 10/100/1000, JMP202 10/100 PHY.
@@ -62,7 +62,7 @@ static device_method_t jmphy_methods[] = {
DEVMETHOD(device_attach, jmphy_attach),
DEVMETHOD(device_detach, mii_phy_detach),
DEVMETHOD(device_shutdown, bus_generic_shutdown),
{ NULL, NULL }
DEVMETHOD_END
};
static devclass_t jmphy_devclass;
@@ -24,7 +24,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD: src/sys/dev/mii/jmphyreg.h,v 1.1.6.1.6.1 2010/12/21 17:09:25 kensmith Exp $
* $FreeBSD$
*/
#ifndef _DEV_MII_JMPHYREG_H_
@@ -71,7 +71,7 @@ static device_method_t e1000phy_methods[] = {
DEVMETHOD(device_attach, e1000phy_attach),
DEVMETHOD(device_detach, mii_phy_detach),
DEVMETHOD(device_shutdown, bus_generic_shutdown),
{ 0, 0 }
DEVMETHOD_END
};
static devclass_t e1000phy_devclass;
@@ -55,7 +55,7 @@
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: src/sys/dev/mii/ukphy.c,v 1.20.10.6.2.1 2010/12/21 17:09:25 kensmith Exp $");
__FBSDID("$FreeBSD$");
/*
* driver for generic unknown PHYs
@@ -86,7 +86,7 @@ static device_method_t ukphy_methods[] = {
DEVMETHOD(device_attach, ukphy_attach),
DEVMETHOD(device_detach, mii_phy_detach),
DEVMETHOD(device_shutdown, bus_generic_shutdown),
{ 0, 0 }
DEVMETHOD_END
};
static devclass_t ukphy_devclass;
@@ -31,7 +31,7 @@
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: src/sys/dev/mii/ukphy_subr.c,v 1.10.2.4.2.1 2010/12/21 17:09:25 kensmith Exp $");
__FBSDID("$FreeBSD$");
/*
* Subroutines shared by the ukphy driver and other PHY drivers.
@@ -334,11 +334,7 @@ static device_method_t mskc_methods[] = {
DEVMETHOD(device_resume, mskc_resume),
DEVMETHOD(device_shutdown, mskc_shutdown),
/* bus interface */
DEVMETHOD(bus_print_child, bus_generic_print_child),
DEVMETHOD(bus_driver_added, bus_generic_driver_added),
{ NULL, NULL }
DEVMETHOD_END
};
static driver_t mskc_driver = {
@@ -356,16 +352,12 @@ static device_method_t msk_methods[] = {
DEVMETHOD(device_detach, msk_detach),
DEVMETHOD(device_shutdown, bus_generic_shutdown),
/* bus interface */
DEVMETHOD(bus_print_child, bus_generic_print_child),
DEVMETHOD(bus_driver_added, bus_generic_driver_added),
/* MII interface */
DEVMETHOD(miibus_readreg, msk_miibus_readreg),
DEVMETHOD(miibus_writereg, msk_miibus_writereg),
DEVMETHOD(miibus_statchg, msk_miibus_statchg),
{ NULL, NULL }
DEVMETHOD_END
};
static driver_t msk_driver = {
@@ -700,7 +692,7 @@ msk_init_rx_ring(struct msk_if_softc *sc_if)
{
struct msk_ring_data *rd;
struct msk_rxdesc *rxd;
int i, prod;
int i, nbuf, prod;
MSK_IF_LOCK_ASSERT(sc_if);
@@ -710,11 +702,18 @@ msk_init_rx_ring(struct msk_if_softc *sc_if)
rd = &sc_if->msk_rdata;
bzero(rd->msk_rx_ring, sizeof(struct msk_rx_desc) * MSK_RX_RING_CNT);
prod = sc_if->msk_cdata.msk_rx_prod;
i = 0;
for (i = prod = 0; i < MSK_RX_RING_CNT; i++) {
rxd = &sc_if->msk_cdata.msk_rxdesc[prod];
rxd->rx_m = NULL;
rxd->rx_le = &rd->msk_rx_ring[prod];
MSK_INC(prod, MSK_RX_RING_CNT);
}
nbuf = MSK_RX_BUF_CNT;
prod = 0;
/* Have controller know how to compute Rx checksum. */
if ((sc_if->msk_flags & MSK_FLAG_DESCV2) == 0 &&
(sc_if->msk_ifp->if_capenable & IFCAP_RXCSUM) != 0) {
#ifdef MSK_64BIT_DMA
rxd = &sc_if->msk_cdata.msk_rxdesc[prod];
rxd->rx_m = NULL;
rxd->rx_le = &rd->msk_rx_ring[prod];
@@ -723,15 +722,21 @@ msk_init_rx_ring(struct msk_if_softc *sc_if)
rxd->rx_le->msk_control = htole32(OP_TCPSTART | HW_OWNER);
MSK_INC(prod, MSK_RX_RING_CNT);
MSK_INC(sc_if->msk_cdata.msk_rx_cons, MSK_RX_RING_CNT);
i++;
}
for (; i < MSK_RX_RING_CNT; i++) {
#endif
rxd = &sc_if->msk_cdata.msk_rxdesc[prod];
rxd->rx_m = NULL;
rxd->rx_le = &rd->msk_rx_ring[prod];
rxd->rx_le->msk_addr = htole32(ETHER_HDR_LEN << 16 |
ETHER_HDR_LEN);
rxd->rx_le->msk_control = htole32(OP_TCPSTART | HW_OWNER);
MSK_INC(prod, MSK_RX_RING_CNT);
MSK_INC(sc_if->msk_cdata.msk_rx_cons, MSK_RX_RING_CNT);
nbuf--;
}
for (i = 0; i < nbuf; i++) {
if (msk_newbuf(sc_if, prod) != 0)
return (ENOBUFS);
MSK_INC(prod, MSK_RX_RING_CNT);
MSK_RX_INC(prod, MSK_RX_RING_CNT);
}
bus_dmamap_sync(sc_if->msk_cdata.msk_rx_ring_tag,
@@ -739,10 +744,11 @@ msk_init_rx_ring(struct msk_if_softc *sc_if)
BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
/* Update prefetch unit. */
sc_if->msk_cdata.msk_rx_prod = MSK_RX_RING_CNT - 1;
sc_if->msk_cdata.msk_rx_prod = prod;
CSR_WRITE_2(sc_if->msk_softc,
Y2_PREF_Q_ADDR(sc_if->msk_rxq, PREF_UNIT_PUT_IDX_REG),
sc_if->msk_cdata.msk_rx_prod);
(sc_if->msk_cdata.msk_rx_prod + MSK_RX_RING_CNT - 1) %
MSK_RX_RING_CNT);
if (msk_rx_fill(sc_if, 0) != 0)
return (ENOBUFS);
return (0);
@@ -753,7 +759,7 @@ msk_init_jumbo_rx_ring(struct msk_if_softc *sc_if)
{
struct msk_ring_data *rd;
struct msk_rxdesc *rxd;
int i, prod;
int i, nbuf, prod;
MSK_IF_LOCK_ASSERT(sc_if);
@@ -764,11 +770,18 @@ msk_init_jumbo_rx_ring(struct msk_if_softc *sc_if)
rd = &sc_if->msk_rdata;
bzero(rd->msk_jumbo_rx_ring,
sizeof(struct msk_rx_desc) * MSK_JUMBO_RX_RING_CNT);
prod = sc_if->msk_cdata.msk_rx_prod;
i = 0;
for (i = prod = 0; i < MSK_JUMBO_RX_RING_CNT; i++) {
rxd = &sc_if->msk_cdata.msk_jumbo_rxdesc[prod];
rxd->rx_m = NULL;
rxd->rx_le = &rd->msk_jumbo_rx_ring[prod];
MSK_INC(prod, MSK_JUMBO_RX_RING_CNT);
}
nbuf = MSK_RX_BUF_CNT;
prod = 0;
/* Have controller know how to compute Rx checksum. */
if ((sc_if->msk_flags & MSK_FLAG_DESCV2) == 0 &&
(sc_if->msk_ifp->if_capenable & IFCAP_RXCSUM) != 0) {
#ifdef MSK_64BIT_DMA
rxd = &sc_if->msk_cdata.msk_jumbo_rxdesc[prod];
rxd->rx_m = NULL;
rxd->rx_le = &rd->msk_jumbo_rx_ring[prod];
@@ -777,25 +790,33 @@ msk_init_jumbo_rx_ring(struct msk_if_softc *sc_if)
rxd->rx_le->msk_control = htole32(OP_TCPSTART | HW_OWNER);
MSK_INC(prod, MSK_JUMBO_RX_RING_CNT);
MSK_INC(sc_if->msk_cdata.msk_rx_cons, MSK_JUMBO_RX_RING_CNT);
i++;
}
for (; i < MSK_JUMBO_RX_RING_CNT; i++) {
#endif
rxd = &sc_if->msk_cdata.msk_jumbo_rxdesc[prod];
rxd->rx_m = NULL;
rxd->rx_le = &rd->msk_jumbo_rx_ring[prod];
rxd->rx_le->msk_addr = htole32(ETHER_HDR_LEN << 16 |
ETHER_HDR_LEN);
rxd->rx_le->msk_control = htole32(OP_TCPSTART | HW_OWNER);
MSK_INC(prod, MSK_JUMBO_RX_RING_CNT);
MSK_INC(sc_if->msk_cdata.msk_rx_cons, MSK_JUMBO_RX_RING_CNT);
nbuf--;
}
for (i = 0; i < nbuf; i++) {
if (msk_jumbo_newbuf(sc_if, prod) != 0)
return (ENOBUFS);
MSK_INC(prod, MSK_JUMBO_RX_RING_CNT);
MSK_RX_INC(prod, MSK_JUMBO_RX_RING_CNT);
}
bus_dmamap_sync(sc_if->msk_cdata.msk_jumbo_rx_ring_tag,
sc_if->msk_cdata.msk_jumbo_rx_ring_map,
BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
sc_if->msk_cdata.msk_rx_prod = MSK_JUMBO_RX_RING_CNT - 1;
/* Update prefetch unit. */
sc_if->msk_cdata.msk_rx_prod = prod;
CSR_WRITE_2(sc_if->msk_softc,
Y2_PREF_Q_ADDR(sc_if->msk_rxq, PREF_UNIT_PUT_IDX_REG),
sc_if->msk_cdata.msk_rx_prod);
(sc_if->msk_cdata.msk_rx_prod + MSK_JUMBO_RX_RING_CNT - 1) %
MSK_JUMBO_RX_RING_CNT);
if (msk_rx_fill(sc_if, 1) != 0)
return (ENOBUFS);
return (0);
@@ -813,6 +834,7 @@ msk_init_tx_ring(struct msk_if_softc *sc_if)
sc_if->msk_cdata.msk_tx_prod = 0;
sc_if->msk_cdata.msk_tx_cons = 0;
sc_if->msk_cdata.msk_tx_cnt = 0;
sc_if->msk_cdata.msk_tx_high_addr = 0;
rd = &sc_if->msk_rdata;
bzero(rd->msk_tx_ring, sizeof(struct msk_tx_desc) * MSK_TX_RING_CNT);
@@ -834,6 +856,12 @@ msk_discard_rxbuf(struct msk_if_softc *sc_if, int idx)
struct msk_rxdesc *rxd;
struct mbuf *m;
#ifdef MSK_64BIT_DMA
rxd = &sc_if->msk_cdata.msk_rxdesc[idx];
rx_le = rxd->rx_le;
rx_le->msk_control = htole32(OP_ADDR64 | HW_OWNER);
MSK_INC(idx, MSK_RX_RING_CNT);
#endif
rxd = &sc_if->msk_cdata.msk_rxdesc[idx];
m = rxd->rx_m;
rx_le = rxd->rx_le;
@@ -847,6 +875,12 @@ msk_discard_jumbo_rxbuf(struct msk_if_softc *sc_if, int idx)
struct msk_rxdesc *rxd;
struct mbuf *m;
#ifdef MSK_64BIT_DMA
rxd = &sc_if->msk_cdata.msk_jumbo_rxdesc[idx];
rx_le = rxd->rx_le;
rx_le->msk_control = htole32(OP_ADDR64 | HW_OWNER);
MSK_INC(idx, MSK_JUMBO_RX_RING_CNT);
#endif
rxd = &sc_if->msk_cdata.msk_jumbo_rxdesc[idx];
m = rxd->rx_m;
rx_le = rxd->rx_le;
@@ -884,10 +918,18 @@ msk_newbuf(struct msk_if_softc *sc_if, int idx)
KASSERT(nsegs == 1, ("%s: %d segments returned!", __func__, nsegs));
rxd = &sc_if->msk_cdata.msk_rxdesc[idx];
#ifdef MSK_64BIT_DMA
rx_le = rxd->rx_le;
rx_le->msk_addr = htole32(MSK_ADDR_HI(segs[0].ds_addr));
rx_le->msk_control = htole32(OP_ADDR64 | HW_OWNER);
MSK_INC(idx, MSK_RX_RING_CNT);
rxd = &sc_if->msk_cdata.msk_rxdesc[idx];
#endif
if (rxd->rx_m != NULL) {
bus_dmamap_sync(sc_if->msk_cdata.msk_rx_tag, rxd->rx_dmamap,
BUS_DMASYNC_POSTREAD);
bus_dmamap_unload(sc_if->msk_cdata.msk_rx_tag, rxd->rx_dmamap);
rxd->rx_m = NULL;
}
map = rxd->rx_dmamap;
rxd->rx_dmamap = sc_if->msk_cdata.msk_rx_sparemap;
@@ -937,11 +979,19 @@ msk_jumbo_newbuf(struct msk_if_softc *sc_if, int idx)
KASSERT(nsegs == 1, ("%s: %d segments returned!", __func__, nsegs));
rxd = &sc_if->msk_cdata.msk_jumbo_rxdesc[idx];
#ifdef MSK_64BIT_DMA
rx_le = rxd->rx_le;
rx_le->msk_addr = htole32(MSK_ADDR_HI(segs[0].ds_addr));
rx_le->msk_control = htole32(OP_ADDR64 | HW_OWNER);
MSK_INC(idx, MSK_JUMBO_RX_RING_CNT);
rxd = &sc_if->msk_cdata.msk_jumbo_rxdesc[idx];
#endif
if (rxd->rx_m != NULL) {
bus_dmamap_sync(sc_if->msk_cdata.msk_jumbo_rx_tag,
rxd->rx_dmamap, BUS_DMASYNC_POSTREAD);
bus_dmamap_unload(sc_if->msk_cdata.msk_jumbo_rx_tag,
rxd->rx_dmamap);
rxd->rx_m = NULL;
}
map = rxd->rx_dmamap;
rxd->rx_dmamap = sc_if->msk_cdata.msk_jumbo_rx_sparemap;
@@ -995,9 +1045,9 @@ msk_mediastatus(struct ifnet *ifp, struct ifmediareq *ifmr)
mii = device_get_softc(sc_if->msk_miibus);
mii_pollstat(mii);
MSK_IF_UNLOCK(sc_if);
ifmr->ifm_active = mii->mii_media_active;
ifmr->ifm_status = mii->mii_media_status;
MSK_IF_UNLOCK(sc_if);
}
static int
@@ -1472,7 +1522,7 @@ mskc_reset(struct msk_softc *sc)
/* Clear status list. */
bzero(sc->msk_stat_ring,
sizeof(struct msk_stat_desc) * MSK_STAT_RING_CNT);
sizeof(struct msk_stat_desc) * sc->msk_stat_count);
sc->msk_stat_cons = 0;
bus_dmamap_sync(sc->msk_stat_tag, sc->msk_stat_map,
BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
@@ -1483,7 +1533,7 @@ mskc_reset(struct msk_softc *sc)
CSR_WRITE_4(sc, STAT_LIST_ADDR_LO, MSK_ADDR_LO(addr));
CSR_WRITE_4(sc, STAT_LIST_ADDR_HI, MSK_ADDR_HI(addr));
/* Set the status list last index. */
CSR_WRITE_2(sc, STAT_LAST_IDX, MSK_STAT_RING_CNT - 1);
CSR_WRITE_2(sc, STAT_LAST_IDX, sc->msk_stat_count - 1);
if (sc->msk_hw_id == CHIP_ID_YUKON_EC &&
sc->msk_hw_rev == CHIP_REV_YU_EC_A1) {
/* WA for dev. #4.3 */
@@ -2083,17 +2133,33 @@ static int
msk_status_dma_alloc(struct msk_softc *sc)
{
struct msk_dmamap_arg ctx;
int error;
bus_size_t stat_sz;
int count, error;
/*
* It seems controller requires number of status LE entries
* is power of 2 and the maximum number of status LE entries
* is 4096. For dual-port controllers, the number of status
* LE entries should be large enough to hold both port's
* status updates.
*/
count = 3 * MSK_RX_RING_CNT + MSK_TX_RING_CNT;
#ifdef __HAIKU__
// TODO check this!
#define imin min
#endif
count = imin(4096, roundup2(count, 1024));
sc->msk_stat_count = count;
stat_sz = count * sizeof(struct msk_stat_desc);
error = bus_dma_tag_create(
bus_get_dma_tag(sc->msk_dev), /* parent */
MSK_STAT_ALIGN, 0, /* alignment, boundary */
BUS_SPACE_MAXADDR, /* lowaddr */
BUS_SPACE_MAXADDR, /* highaddr */
NULL, NULL, /* filter, filterarg */
MSK_STAT_RING_SZ, /* maxsize */
stat_sz, /* maxsize */
1, /* nsegments */
MSK_STAT_RING_SZ, /* maxsegsize */
stat_sz, /* maxsegsize */
0, /* flags */
NULL, NULL, /* lockfunc, lockarg */
&sc->msk_stat_tag);
@@ -2114,9 +2180,8 @@ msk_status_dma_alloc(struct msk_softc *sc)
}
ctx.msk_busaddr = 0;
error = bus_dmamap_load(sc->msk_stat_tag,
sc->msk_stat_map, sc->msk_stat_ring, MSK_STAT_RING_SZ,
msk_dmamap_cb, &ctx, 0);
error = bus_dmamap_load(sc->msk_stat_tag, sc->msk_stat_map,
sc->msk_stat_ring, stat_sz, msk_dmamap_cb, &ctx, BUS_DMA_NOWAIT);
if (error != 0) {
device_printf(sc->msk_dev,
"failed to load DMA'able memory for status ring\n");
@@ -2157,27 +2222,10 @@ msk_txrx_dma_alloc(struct msk_if_softc *sc_if)
int error, i;
/* Create parent DMA tag. */
/*
* XXX
* It seems that Yukon II supports full 64bits DMA operations. But
* it needs two descriptors(list elements) for 64bits DMA operations.
* Since we don't know what DMA address mappings(32bits or 64bits)
* would be used in advance for each mbufs, we limits its DMA space
* to be in range of 32bits address space. Otherwise, we should check
* what DMA address is used and chain another descriptor for the
* 64bits DMA operation. This also means descriptor ring size is
* variable. Limiting DMA address to be in 32bit address space greatly
* simplifies descriptor handling and possibly would increase
* performance a bit due to efficient handling of descriptors.
* Apart from harassing checksum offloading mechanisms, it seems
* it's really bad idea to use a separate descriptor for 64bit
* DMA operation to save small descriptor memory. Anyway, I've
* never seen these exotic scheme on ethernet interface hardware.
*/
error = bus_dma_tag_create(
bus_get_dma_tag(sc_if->msk_if_dev), /* parent */
1, 0, /* alignment, boundary */
BUS_SPACE_MAXADDR_32BIT, /* lowaddr */
BUS_SPACE_MAXADDR, /* lowaddr */
BUS_SPACE_MAXADDR, /* highaddr */
NULL, NULL, /* filter, filterarg */
BUS_SPACE_MAXSIZE_32BIT, /* maxsize */
@@ -2283,7 +2331,7 @@ msk_txrx_dma_alloc(struct msk_if_softc *sc_if)
ctx.msk_busaddr = 0;
error = bus_dmamap_load(sc_if->msk_cdata.msk_tx_ring_tag,
sc_if->msk_cdata.msk_tx_ring_map, sc_if->msk_rdata.msk_tx_ring,
MSK_TX_RING_SZ, msk_dmamap_cb, &ctx, 0);
MSK_TX_RING_SZ, msk_dmamap_cb, &ctx, BUS_DMA_NOWAIT);
if (error != 0) {
device_printf(sc_if->msk_if_dev,
"failed to load DMA'able memory for Tx ring\n");
@@ -2304,7 +2352,7 @@ msk_txrx_dma_alloc(struct msk_if_softc *sc_if)
ctx.msk_busaddr = 0;
error = bus_dmamap_load(sc_if->msk_cdata.msk_rx_ring_tag,
sc_if->msk_cdata.msk_rx_ring_map, sc_if->msk_rdata.msk_rx_ring,
MSK_RX_RING_SZ, msk_dmamap_cb, &ctx, 0);
MSK_RX_RING_SZ, msk_dmamap_cb, &ctx, BUS_DMA_NOWAIT);
if (error != 0) {
device_printf(sc_if->msk_if_dev,
"failed to load DMA'able memory for Rx ring\n");
@@ -2421,7 +2469,7 @@ msk_rx_dma_jalloc(struct msk_if_softc *sc_if)
error = bus_dmamap_load(sc_if->msk_cdata.msk_jumbo_rx_ring_tag,
sc_if->msk_cdata.msk_jumbo_rx_ring_map,
sc_if->msk_rdata.msk_jumbo_rx_ring, MSK_JUMBO_RX_RING_SZ,
msk_dmamap_cb, &ctx, 0);
msk_dmamap_cb, &ctx, BUS_DMA_NOWAIT);
if (error != 0) {
device_printf(sc_if->msk_if_dev,
"failed to load DMA'able memory for jumbo Rx ring\n");
@@ -2781,6 +2829,18 @@ msk_encap(struct msk_if_softc *sc_if, struct mbuf **m_head)
}
}
#ifdef MSK_64BIT_DMA
if (MSK_ADDR_HI(txsegs[0].ds_addr) !=
sc_if->msk_cdata.msk_tx_high_addr) {
sc_if->msk_cdata.msk_tx_high_addr =
MSK_ADDR_HI(txsegs[0].ds_addr);
tx_le = &sc_if->msk_rdata.msk_tx_ring[prod];
tx_le->msk_addr = htole32(MSK_ADDR_HI(txsegs[0].ds_addr));
tx_le->msk_control = htole32(OP_ADDR64 | HW_OWNER);
sc_if->msk_cdata.msk_tx_cnt++;
MSK_INC(prod, MSK_TX_RING_CNT);
}
#endif
si = prod;
tx_le = &sc_if->msk_rdata.msk_tx_ring[prod];
tx_le->msk_addr = htole32(MSK_ADDR_LO(txsegs[0].ds_addr));
@@ -2795,6 +2855,20 @@ msk_encap(struct msk_if_softc *sc_if, struct mbuf **m_head)
for (i = 1; i < nseg; i++) {
tx_le = &sc_if->msk_rdata.msk_tx_ring[prod];
#ifdef MSK_64BIT_DMA
if (MSK_ADDR_HI(txsegs[i].ds_addr) !=
sc_if->msk_cdata.msk_tx_high_addr) {
sc_if->msk_cdata.msk_tx_high_addr =
MSK_ADDR_HI(txsegs[i].ds_addr);
tx_le = &sc_if->msk_rdata.msk_tx_ring[prod];
tx_le->msk_addr =
htole32(MSK_ADDR_HI(txsegs[i].ds_addr));
tx_le->msk_control = htole32(OP_ADDR64 | HW_OWNER);
sc_if->msk_cdata.msk_tx_cnt++;
MSK_INC(prod, MSK_TX_RING_CNT);
tx_le = &sc_if->msk_rdata.msk_tx_ring[prod];
}
#endif
tx_le->msk_addr = htole32(MSK_ADDR_LO(txsegs[i].ds_addr));
tx_le->msk_control = htole32(txsegs[i].ds_len | control |
OP_BUFFER | HW_OWNER);
@@ -3147,7 +3221,12 @@ msk_rxeof(struct msk_if_softc *sc_if, uint32_t status, uint32_t control,
msk_discard_rxbuf(sc_if, cons);
break;
}
#ifdef MSK_64BIT_DMA
rxd = &sc_if->msk_cdata.msk_rxdesc[(cons + 1) %
MSK_RX_RING_CNT];
#else
rxd = &sc_if->msk_cdata.msk_rxdesc[cons];
#endif
m = rxd->rx_m;
if (msk_newbuf(sc_if, cons) != 0) {
ifp->if_iqdrops++;
@@ -3175,8 +3254,8 @@ msk_rxeof(struct msk_if_softc *sc_if, uint32_t status, uint32_t control,
MSK_IF_LOCK(sc_if);
} while (0);
MSK_INC(sc_if->msk_cdata.msk_rx_cons, MSK_RX_RING_CNT);
MSK_INC(sc_if->msk_cdata.msk_rx_prod, MSK_RX_RING_CNT);
MSK_RX_INC(sc_if->msk_cdata.msk_rx_cons, MSK_RX_RING_CNT);
MSK_RX_INC(sc_if->msk_cdata.msk_rx_prod, MSK_RX_RING_CNT);
}
static void
@@ -3207,7 +3286,12 @@ msk_jumbo_rxeof(struct msk_if_softc *sc_if, uint32_t status, uint32_t control,
msk_discard_jumbo_rxbuf(sc_if, cons);
break;
}
#ifdef MSK_64BIT_DMA
jrxd = &sc_if->msk_cdata.msk_jumbo_rxdesc[(cons + 1) %
MSK_JUMBO_RX_RING_CNT];
#else
jrxd = &sc_if->msk_cdata.msk_jumbo_rxdesc[cons];
#endif
m = jrxd->rx_m;
if (msk_jumbo_newbuf(sc_if, cons) != 0) {
ifp->if_iqdrops++;
@@ -3235,8 +3319,8 @@ msk_jumbo_rxeof(struct msk_if_softc *sc_if, uint32_t status, uint32_t control,
MSK_IF_LOCK(sc_if);
} while (0);
MSK_INC(sc_if->msk_cdata.msk_rx_cons, MSK_JUMBO_RX_RING_CNT);
MSK_INC(sc_if->msk_cdata.msk_rx_prod, MSK_JUMBO_RX_RING_CNT);
MSK_RX_INC(sc_if->msk_cdata.msk_rx_cons, MSK_JUMBO_RX_RING_CNT);
MSK_RX_INC(sc_if->msk_cdata.msk_rx_prod, MSK_JUMBO_RX_RING_CNT);
}
static void
@@ -3581,7 +3665,7 @@ msk_handle_events(struct msk_softc *sc)
control & STLE_OP_MASK);
break;
}
MSK_INC(cons, MSK_STAT_RING_CNT);
MSK_INC(cons, sc->msk_stat_count);
if (rxprog > sc->msk_process_limit)
break;
}
@@ -2315,35 +2315,48 @@ struct msk_stat_desc {
#define BMU_UDP_CHECK (0x57<<16) /* Descr with UDP ext (YUKON only) */
#define BMU_BBC 0xffff /* Bit 15.. 0: Buffer Byte Counter */
/*
* Controller requires an additional LE op code for 64bit DMA operation.
* Driver uses fixed number of RX buffers such that this limitation
* reduces number of available RX buffers with 64bit DMA so double
* number of RX buffers on platforms that support 64bit DMA. For TX
* side, controller requires an additional OP_ADDR64 op code if a TX
* buffer uses different high address value than previously used one.
* Driver monitors high DMA address change in TX and inserts an
* OP_ADDR64 op code if the high DMA address is changed. Driver
* allocates 50% more total TX buffers on platforms that support 64bit
* DMA.
*/
#if (BUS_SPACE_MAXADDR > 0xFFFFFFFF)
#define MSK_64BIT_DMA
#define MSK_TX_RING_CNT 384
#define MSK_RX_RING_CNT 512
#else
#undef MSK_64BIT_DMA
#define MSK_TX_RING_CNT 256
#define MSK_RX_RING_CNT 256
#endif
#define MSK_RX_BUF_ALIGN 8
#define MSK_JUMBO_RX_RING_CNT MSK_RX_RING_CNT
#define MSK_STAT_RING_CNT ((1 + 3) * (MSK_TX_RING_CNT + MSK_RX_RING_CNT))
#define MSK_MAXTXSEGS 32
#define MSK_TSO_MAXSGSIZE 4096
#define MSK_TSO_MAXSIZE (65535 + sizeof(struct ether_vlan_header))
/*
* It seems that the hardware requires extra decriptors(LEs) to offload
* TCP/UDP checksum, VLAN hardware tag inserstion and TSO.
* It seems that the hardware requires extra descriptors(LEs) to offload
* TCP/UDP checksum, VLAN hardware tag insertion and TSO.
*
* 1 descriptor for TCP/UDP checksum offload.
* 1 descriptor VLAN hardware tag insertion.
* 1 descriptor for TSO(TCP Segmentation Offload)
* 1 descriptor for 64bits DMA : Not applicatable due to the use of
* BUS_SPACE_MAXADDR_32BIT in parent DMA tag creation.
* 1 descriptor for each 64bits DMA transfers
*/
#ifdef MSK_64BIT_DMA
#define MSK_RESERVED_TX_DESC_CNT (MSK_MAXTXSEGS + 3)
#else
#define MSK_RESERVED_TX_DESC_CNT 3
#endif
/*
* Jumbo buffer stuff. Note that we must allocate more jumbo
* buffers than there are descriptors in the receive ring. This
* is because we don't know how long it will take for a packet
* to be released after we hand it off to the upper protocol
* layers. To be safe, we allocate 1.5 times the number of
* receive descriptors.
*/
#define MSK_JUMBO_FRAMELEN 9022
#define MSK_JUMBO_MTU (MSK_JUMBO_FRAMELEN-ETHER_HDR_LEN-ETHER_CRC_LEN)
#define MSK_MAX_FRAMELEN \
@@ -2380,6 +2393,7 @@ struct msk_chain_data {
bus_dmamap_t msk_jumbo_rx_sparemap;
uint16_t msk_tso_mtu;
uint32_t msk_last_csum;
uint32_t msk_tx_high_addr;
int msk_tx_prod;
int msk_tx_cons;
int msk_tx_cnt;
@@ -2411,10 +2425,17 @@ struct msk_ring_data {
(sizeof(struct msk_rx_desc) * MSK_RX_RING_CNT)
#define MSK_JUMBO_RX_RING_SZ \
(sizeof(struct msk_rx_desc) * MSK_JUMBO_RX_RING_CNT)
#define MSK_STAT_RING_SZ \
(sizeof(struct msk_stat_desc) * MSK_STAT_RING_CNT)
#define MSK_INC(x, y) (x) = (x + 1) % y
#ifdef MSK_64BIT_DMA
#define MSK_RX_INC(x, y) (x) = (x + 2) % y
#define MSK_RX_BUF_CNT (MSK_RX_RING_CNT / 2)
#define MSK_JUMBO_RX_BUF_CNT (MSK_JUMBO_RX_RING_CNT / 2)
#else
#define MSK_RX_INC(x, y) (x) = (x + 1) % y
#define MSK_RX_BUF_CNT MSK_RX_RING_CNT
#define MSK_JUMBO_RX_BUF_CNT MSK_JUMBO_RX_RING_CNT
#endif
#define MSK_PCI_BUS 0
#define MSK_PCIX_BUS 1
@@ -2519,6 +2540,7 @@ struct msk_softc {
int msk_int_holdoff;
int msk_process_limit;
int msk_stat_cons;
int msk_stat_count;
struct mtx msk_mtx;
#ifdef __HAIKU__
uint32_t haiku_interrupt_status;
@@ -67,7 +67,7 @@ static device_method_t ciphy_methods[] = {
DEVMETHOD(device_attach, ciphy_attach),
DEVMETHOD(device_detach, mii_phy_detach),
DEVMETHOD(device_shutdown, bus_generic_shutdown),
{ 0, 0 }
DEVMETHOD_END
};
static devclass_t ciphy_devclass;

Some files were not shown because too many files have changed in this diff Show More