diff --git a/src/add-ons/kernel/drivers/network/3com/dev/mii/bmtphy.c b/src/add-ons/kernel/drivers/network/3com/dev/mii/bmtphy.c index ba4b509866e..81c2bd2ae1f 100644 --- a/src/add-ons/kernel/drivers/network/3com/dev/mii/bmtphy.c +++ b/src/add-ons/kernel/drivers/network/3com/dev/mii/bmtphy.c @@ -56,7 +56,7 @@ */ #include -__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; diff --git a/src/add-ons/kernel/drivers/network/3com/dev/mii/bmtphyreg.h b/src/add-ons/kernel/drivers/network/3com/dev/mii/bmtphyreg.h index 45ad8e75efa..6aa141deb4f 100644 --- a/src/add-ons/kernel/drivers/network/3com/dev/mii/bmtphyreg.h +++ b/src/add-ons/kernel/drivers/network/3com/dev/mii/bmtphyreg.h @@ -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_ diff --git a/src/add-ons/kernel/drivers/network/3com/dev/mii/ukphy.c b/src/add-ons/kernel/drivers/network/3com/dev/mii/ukphy.c index 4ecfce29d31..9d52eb580ca 100644 --- a/src/add-ons/kernel/drivers/network/3com/dev/mii/ukphy.c +++ b/src/add-ons/kernel/drivers/network/3com/dev/mii/ukphy.c @@ -55,7 +55,7 @@ */ #include -__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; diff --git a/src/add-ons/kernel/drivers/network/3com/dev/mii/ukphy_subr.c b/src/add-ons/kernel/drivers/network/3com/dev/mii/ukphy_subr.c index 73007e197b9..5f2f6341ba6 100644 --- a/src/add-ons/kernel/drivers/network/3com/dev/mii/ukphy_subr.c +++ b/src/add-ons/kernel/drivers/network/3com/dev/mii/ukphy_subr.c @@ -31,7 +31,7 @@ */ #include -__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. diff --git a/src/add-ons/kernel/drivers/network/3com/dev/xl/if_xl.c b/src/add-ons/kernel/drivers/network/3com/dev/xl/if_xl.c index 77b4c43220f..989c5a731ee 100644 --- a/src/add-ons/kernel/drivers/network/3com/dev/xl/if_xl.c +++ b/src/add-ons/kernel/drivers/network/3com/dev/xl/if_xl.c @@ -31,7 +31,7 @@ */ #include -__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); } @@ -2226,7 +2220,7 @@ xl_intr(void *arg) } if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd) && - ifp->if_drv_flags & IFF_DRV_RUNNING) { + ifp->if_drv_flags & IFF_DRV_RUNNING) { if (sc->xl_type == XL_TYPE_905B) xl_start_90xB_locked(ifp); else diff --git a/src/add-ons/kernel/drivers/network/3com/dev/xl/if_xlreg.h b/src/add-ons/kernel/drivers/network/3com/dev/xl/if_xlreg.h index cd1df201040..17457beefcb 100644 --- a/src/add-ons/kernel/drivers/network/3com/dev/xl/if_xlreg.h +++ b/src/add-ons/kernel/drivers/network/3com/dev/xl/if_xlreg.h @@ -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 */ diff --git a/src/add-ons/kernel/drivers/network/3com/dev/xl/xlphy.c b/src/add-ons/kernel/drivers/network/3com/dev/xl/xlphy.c index e5ac9fce4b2..2fe9e0d9058 100644 --- a/src/add-ons/kernel/drivers/network/3com/dev/xl/xlphy.c +++ b/src/add-ons/kernel/drivers/network/3com/dev/xl/xlphy.c @@ -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; diff --git a/src/add-ons/kernel/drivers/network/ar81xx/dev/ale/if_ale.c b/src/add-ons/kernel/drivers/network/ar81xx/dev/ale/if_ale.c index 9c3dfd99e18..78c0b4eeaa3 100644 --- a/src/add-ons/kernel/drivers/network/ar81xx/dev/ale/if_ale.c +++ b/src/add-ons/kernel/drivers/network/ar81xx/dev/ale/if_ale.c @@ -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; + + 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); - taskqueue_enqueue(taskqueue_swi, &sc->ale_link_task); + /* 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) { @@ -2821,7 +2796,7 @@ ale_init_locked(struct ale_softc *sc) ((rxf_lo << RX_FIFO_PAUSE_THRESH_LO_SHIFT) & RX_FIFO_PAUSE_THRESH_LO_MASK) | ((rxf_hi << RX_FIFO_PAUSE_THRESH_HI_SHIFT) & - RX_FIFO_PAUSE_THRESH_HI_MASK)); + RX_FIFO_PAUSE_THRESH_HI_MASK)); } /* Disable RSS. */ @@ -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 diff --git a/src/add-ons/kernel/drivers/network/ar81xx/dev/ale/if_alevar.h b/src/add-ons/kernel/drivers/network/ar81xx/dev/ale/if_alevar.h index dcf48d6aa19..abf2d2e39a7 100644 --- a/src/add-ons/kernel/drivers/network/ar81xx/dev/ale/if_alevar.h +++ b/src/add-ons/kernel/drivers/network/ar81xx/dev/ale/if_alevar.h @@ -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; }; diff --git a/src/add-ons/kernel/drivers/network/ar81xx/dev/mii/ukphy.c b/src/add-ons/kernel/drivers/network/ar81xx/dev/mii/ukphy.c index fc1cf4d2599..9d52eb580ca 100644 --- a/src/add-ons/kernel/drivers/network/ar81xx/dev/mii/ukphy.c +++ b/src/add-ons/kernel/drivers/network/ar81xx/dev/mii/ukphy.c @@ -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 -__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,11 +122,9 @@ 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); - + mii_phy_dev_attach(dev, MIIF_NOMANPAUSE, &ukphy_funcs, 1); mii_phy_setmedia(sc); @@ -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; diff --git a/src/add-ons/kernel/drivers/network/ar81xx/dev/mii/ukphy_subr.c b/src/add-ons/kernel/drivers/network/ar81xx/dev/mii/ukphy_subr.c index fb40b75c1d7..5f2f6341ba6 100644 --- a/src/add-ons/kernel/drivers/network/ar81xx/dev/mii/ukphy_subr.c +++ b/src/add-ons/kernel/drivers/network/ar81xx/dev/mii/ukphy_subr.c @@ -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 -__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; } diff --git a/src/add-ons/kernel/drivers/network/atheros813x/dev/alc/if_alc.c b/src/add-ons/kernel/drivers/network/atheros813x/dev/alc/if_alc.c index c13cb188dc1..c73075c6a8f 100644 --- a/src/add-ons/kernel/drivers/network/atheros813x/dev/alc/if_alc.c +++ b/src/add-ons/kernel/drivers/network/atheros813x/dev/alc/if_alc.c @@ -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 diff --git a/src/add-ons/kernel/drivers/network/atheros813x/dev/mii/ukphy.c b/src/add-ons/kernel/drivers/network/atheros813x/dev/mii/ukphy.c index 4ecfce29d31..9d52eb580ca 100644 --- a/src/add-ons/kernel/drivers/network/atheros813x/dev/mii/ukphy.c +++ b/src/add-ons/kernel/drivers/network/atheros813x/dev/mii/ukphy.c @@ -55,7 +55,7 @@ */ #include -__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; diff --git a/src/add-ons/kernel/drivers/network/atheros813x/dev/mii/ukphy_subr.c b/src/add-ons/kernel/drivers/network/atheros813x/dev/mii/ukphy_subr.c index 73007e197b9..5f2f6341ba6 100644 --- a/src/add-ons/kernel/drivers/network/atheros813x/dev/mii/ukphy_subr.c +++ b/src/add-ons/kernel/drivers/network/atheros813x/dev/mii/ukphy_subr.c @@ -31,7 +31,7 @@ */ #include -__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. diff --git a/src/add-ons/kernel/drivers/network/attansic_l1/dev/age/if_age.c b/src/add-ons/kernel/drivers/network/attansic_l1/dev/age/if_age.c index cecc339e2fe..f4287b0dd6b 100644 --- a/src/add-ons/kernel/drivers/network/attansic_l1/dev/age/if_age.c +++ b/src/add-ons/kernel/drivers/network/attansic_l1/dev/age/if_age.c @@ -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); } /* @@ -1405,7 +1405,7 @@ age_setwol(struct age_softc *sc) AGE_UNLOCK(sc); #ifdef __HAIKU__ DELAY(1); -#else +#else pause("agelnk", hz); #endif AGE_LOCK(sc); diff --git a/src/add-ons/kernel/drivers/network/attansic_l1/dev/mii/atphy.c b/src/add-ons/kernel/drivers/network/attansic_l1/dev/mii/atphy.c index b5cf14f44fa..cca8813a7cb 100644 --- a/src/add-ons/kernel/drivers/network/attansic_l1/dev/mii/atphy.c +++ b/src/add-ons/kernel/drivers/network/attansic_l1/dev/mii/atphy.c @@ -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; diff --git a/src/add-ons/kernel/drivers/network/attansic_l2/dev/ae/if_ae.c b/src/add-ons/kernel/drivers/network/attansic_l2/dev/ae/if_ae.c index 3ab598abc69..02a1e796f95 100644 --- a/src/add-ons/kernel/drivers/network/attansic_l2/dev/ae/if_ae.c +++ b/src/add-ons/kernel/drivers/network/attansic_l2/dev/ae/if_ae.c @@ -1385,12 +1385,13 @@ ae_pm_init(ae_softc_t *sc) /* * Configure PME. */ - pci_find_cap(sc->dev, PCIY_PMG, &pmc); - 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); + 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++; diff --git a/src/add-ons/kernel/drivers/network/attansic_l2/dev/mii/ukphy.c b/src/add-ons/kernel/drivers/network/attansic_l2/dev/mii/ukphy.c index 4ecfce29d31..9d52eb580ca 100644 --- a/src/add-ons/kernel/drivers/network/attansic_l2/dev/mii/ukphy.c +++ b/src/add-ons/kernel/drivers/network/attansic_l2/dev/mii/ukphy.c @@ -55,7 +55,7 @@ */ #include -__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; diff --git a/src/add-ons/kernel/drivers/network/attansic_l2/dev/mii/ukphy_subr.c b/src/add-ons/kernel/drivers/network/attansic_l2/dev/mii/ukphy_subr.c index 73007e197b9..5f2f6341ba6 100644 --- a/src/add-ons/kernel/drivers/network/attansic_l2/dev/mii/ukphy_subr.c +++ b/src/add-ons/kernel/drivers/network/attansic_l2/dev/mii/ukphy_subr.c @@ -31,7 +31,7 @@ */ #include -__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. diff --git a/src/add-ons/kernel/drivers/network/broadcom440x/dev/bfe/if_bfe.c b/src/add-ons/kernel/drivers/network/broadcom440x/dev/bfe/if_bfe.c index 7f970f4ac4c..6dd33cd5912 100644 --- a/src/add-ons/kernel/drivers/network/broadcom440x/dev/bfe/if_bfe.c +++ b/src/add-ons/kernel/drivers/network/broadcom440x/dev/bfe/if_bfe.c @@ -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 = { diff --git a/src/add-ons/kernel/drivers/network/broadcom440x/dev/mii/bmtphy.c b/src/add-ons/kernel/drivers/network/broadcom440x/dev/mii/bmtphy.c index 3f91a61cae3..9af56e92dad 100644 --- a/src/add-ons/kernel/drivers/network/broadcom440x/dev/mii/bmtphy.c +++ b/src/add-ons/kernel/drivers/network/broadcom440x/dev/mii/bmtphy.c @@ -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; diff --git a/src/add-ons/kernel/drivers/network/broadcom570x/dev/bce/if_bcereg.h b/src/add-ons/kernel/drivers/network/broadcom570x/dev/bce/if_bcereg.h index f4215db49be..be206081a29 100644 --- a/src/add-ons/kernel/drivers/network/broadcom570x/dev/bce/if_bcereg.h +++ b/src/add-ons/kernel/drivers/network/broadcom570x/dev/bce/if_bcereg.h @@ -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; diff --git a/src/add-ons/kernel/drivers/network/broadcom570x/dev/bge/if_bge.c b/src/add-ons/kernel/drivers/network/broadcom570x/dev/bge/if_bge.c index d4567743fda..d635000c523 100644 --- a/src/add-ons/kernel/drivers/network/broadcom570x/dev/bge/if_bge.c +++ b/src/add-ons/kernel/drivers/network/broadcom570x/dev/bge/if_bge.c @@ -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; + sc->bge_flags |= BGE_FLAG_4G_BNDRY_BUG; + + /* 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; - misccfg = CSR_READ_4(sc, BGE_MISC_CFG) & BGE_MISCCFG_BOARD_ID; + /* + * 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) @@ -2997,9 +3172,9 @@ bge_attach(device_t dev) sc->bge_flags |= BGE_FLAG_TSO; } - /* + /* * Check if this is a PCI-X or PCI Express device. - */ + */ if (pci_find_cap(dev, PCIY_EXPRESS, ®) == 0) { /* * Found a PCI Express capabilities register, this @@ -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); } @@ -4007,7 +4189,7 @@ bge_intr_task(void *arg, int pending) if (ifp->if_drv_flags & IFF_DRV_RUNNING) { /* Check TX ring producer/consumer. */ bge_txeof(sc, tx_cons); - if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) + if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) bge_start_locked(ifp); } BGE_UNLOCK(sc); @@ -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); } } } @@ -4124,7 +4308,7 @@ bge_tick(void *xsc) /* Synchronize with possible callout reset/stop. */ if (callout_pending(&sc->bge_stat_ch) || !callout_active(&sc->bge_stat_ch)) - return; + return; if (BGE_IS_5705_PLUS(sc)) bge_stats_update_regs(sc); @@ -4239,8 +4423,30 @@ 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); - stats->InputDiscards += - CSR_READ_4(sc, BGE_RXLP_LOCSTAT_IFIN_DROPS); + /* + * 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 += CSR_READ_4(sc, BGE_RXLP_LOCSTAT_IFIN_ERRORS); stats->RecvThresholdHit += @@ -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); @@ -5048,7 +5265,7 @@ bge_ioctl(struct ifnet *ifp, u_long command, caddr_t data) break; } } else if (ifr->ifr_mtu < ETHERMIN || ifr->ifr_mtu > ETHERMTU) { - error = EINVAL; + error = EINVAL; break; } BGE_LOCK(sc); @@ -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); diff --git a/src/add-ons/kernel/drivers/network/broadcom570x/dev/bge/if_bgereg.h b/src/add-ons/kernel/drivers/network/broadcom570x/dev/bge/if_bgereg.h index 889efcec435..4413775d56f 100644 --- a/src/add-ons/kernel/drivers/network/broadcom570x/dev/bge/if_bgereg.h +++ b/src/add-ons/kernel/drivers/network/broadcom570x/dev/bge/if_bgereg.h @@ -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 diff --git a/src/add-ons/kernel/drivers/network/broadcom570x/dev/mii/brgphy.c b/src/add-ons/kernel/drivers/network/broadcom570x/dev/mii/brgphy.c index 88090b7607a..57646e56bda 100644 --- a/src/add-ons/kernel/drivers/network/broadcom570x/dev/mii/brgphy.c +++ b/src/add-ons/kernel/drivers/network/broadcom570x/dev/mii/brgphy.c @@ -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,7 +944,8 @@ brgphy_reset(struct mii_softc *sc) if (bge_sc->bge_phy_flags & BGE_PHY_JITTER_BUG) brgphy_fixup_jitter_bug(sc); - brgphy_jumbo_settings(sc, ifp->if_mtu); + 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) brgphy_ethernet_wirespeed(sc); diff --git a/src/add-ons/kernel/drivers/network/broadcom570x/dev/mii/ukphy.c b/src/add-ons/kernel/drivers/network/broadcom570x/dev/mii/ukphy.c index 4ecfce29d31..9d52eb580ca 100644 --- a/src/add-ons/kernel/drivers/network/broadcom570x/dev/mii/ukphy.c +++ b/src/add-ons/kernel/drivers/network/broadcom570x/dev/mii/ukphy.c @@ -55,7 +55,7 @@ */ #include -__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; diff --git a/src/add-ons/kernel/drivers/network/broadcom570x/dev/mii/ukphy_subr.c b/src/add-ons/kernel/drivers/network/broadcom570x/dev/mii/ukphy_subr.c index 73007e197b9..5f2f6341ba6 100644 --- a/src/add-ons/kernel/drivers/network/broadcom570x/dev/mii/ukphy_subr.c +++ b/src/add-ons/kernel/drivers/network/broadcom570x/dev/mii/ukphy_subr.c @@ -31,7 +31,7 @@ */ #include -__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. diff --git a/src/add-ons/kernel/drivers/network/dec21xxx/dev/dc/dcphy.c b/src/add-ons/kernel/drivers/network/dec21xxx/dev/dc/dcphy.c index 5c60ad55f54..a05f2ed4f33 100644 --- a/src/add-ons/kernel/drivers/network/dec21xxx/dev/dc/dcphy.c +++ b/src/add-ons/kernel/drivers/network/dec21xxx/dev/dc/dcphy.c @@ -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; diff --git a/src/add-ons/kernel/drivers/network/dec21xxx/dev/dc/if_dc.c b/src/add-ons/kernel/drivers/network/dec21xxx/dev/dc/if_dc.c index 4945a0e10cf..41d9ea30792 100644 --- a/src/add-ons/kernel/drivers/network/dec21xxx/dev/dc/if_dc.c +++ b/src/add-ons/kernel/drivers/network/dec21xxx/dev/dc/if_dc.c @@ -31,7 +31,7 @@ */ #include -__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; - - 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; + error = dc_ifmedia_upd_locked(sc); DC_UNLOCK(sc); + return (error); +} - return (0); +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); + } + + return (error); } /* diff --git a/src/add-ons/kernel/drivers/network/dec21xxx/dev/dc/if_dcreg.h b/src/add-ons/kernel/drivers/network/dec21xxx/dev/dc/if_dcreg.h index 0b6afd00bda..e290881fa01 100644 --- a/src/add-ons/kernel/drivers/network/dec21xxx/dev/dc/if_dcreg.h +++ b/src/add-ons/kernel/drivers/network/dec21xxx/dev/dc/if_dcreg.h @@ -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)) /* diff --git a/src/add-ons/kernel/drivers/network/dec21xxx/dev/dc/pnphy.c b/src/add-ons/kernel/drivers/network/dec21xxx/dev/dc/pnphy.c index 6546acdd712..98e721da2cb 100644 --- a/src/add-ons/kernel/drivers/network/dec21xxx/dev/dc/pnphy.c +++ b/src/add-ons/kernel/drivers/network/dec21xxx/dev/dc/pnphy.c @@ -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; diff --git a/src/add-ons/kernel/drivers/network/dec21xxx/dev/de/dc21040reg.h b/src/add-ons/kernel/drivers/network/dec21xxx/dev/de/dc21040reg.h index 9f733f766d3..c0ff1916578 100644 --- a/src/add-ons/kernel/drivers/network/dec21xxx/dev/de/dc21040reg.h +++ b/src/add-ons/kernel/drivers/network/dec21xxx/dev/de/dc21040reg.h @@ -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 diff --git a/src/add-ons/kernel/drivers/network/dec21xxx/dev/de/if_de.c b/src/add-ons/kernel/drivers/network/dec21xxx/dev/de/if_de.c index cd3da4c7b3a..9848c9d3536 100644 --- a/src/add-ons/kernel/drivers/network/dec21xxx/dev/de/if_de.c +++ b/src/add-ons/kernel/drivers/network/dec21xxx/dev/de/if_de.c @@ -36,7 +36,7 @@ */ #include -__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); @@ -4710,7 +4711,7 @@ tulip_pci_probe(device_t dev) else name = "Digital 21140 Fast Ethernet"; break; -#ifndef __HAIKU__ +#ifndef __HAIKU__ /* * The card with the same id is supported by if_dc - screen it to * prevent duplicated dev entries. @@ -4721,7 +4722,7 @@ tulip_pci_probe(device_t dev) else name = "Digital 21142 Fast Ethernet"; break; -#endif +#endif } if (name) { device_set_desc(dev, name); diff --git a/src/add-ons/kernel/drivers/network/dec21xxx/dev/de/if_devar.h b/src/add-ons/kernel/drivers/network/dec21xxx/dev/de/if_devar.h index 12880953ed6..8776be01c25 100644 --- a/src/add-ons/kernel/drivers/network/dec21xxx/dev/de/if_devar.h +++ b/src/add-ons/kernel/drivers/network/dec21xxx/dev/de/if_devar.h @@ -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) diff --git a/src/add-ons/kernel/drivers/network/dec21xxx/dev/mii/acphy.c b/src/add-ons/kernel/drivers/network/dec21xxx/dev/mii/acphy.c index df948e6cff9..c61c05bf437 100644 --- a/src/add-ons/kernel/drivers/network/dec21xxx/dev/mii/acphy.c +++ b/src/add-ons/kernel/drivers/network/dec21xxx/dev/mii/acphy.c @@ -53,7 +53,7 @@ */ #include -__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; diff --git a/src/add-ons/kernel/drivers/network/dec21xxx/dev/mii/acphyreg.h b/src/add-ons/kernel/drivers/network/dec21xxx/dev/mii/acphyreg.h index 664671aa2ee..dc34010e0d3 100644 --- a/src/add-ons/kernel/drivers/network/dec21xxx/dev/mii/acphyreg.h +++ b/src/add-ons/kernel/drivers/network/dec21xxx/dev/mii/acphyreg.h @@ -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_ diff --git a/src/add-ons/kernel/drivers/network/dec21xxx/dev/mii/amphy.c b/src/add-ons/kernel/drivers/network/dec21xxx/dev/mii/amphy.c index 10f247bd726..bd90ccf6508 100644 --- a/src/add-ons/kernel/drivers/network/dec21xxx/dev/mii/amphy.c +++ b/src/add-ons/kernel/drivers/network/dec21xxx/dev/mii/amphy.c @@ -31,7 +31,7 @@ */ #include -__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; diff --git a/src/add-ons/kernel/drivers/network/dec21xxx/dev/mii/amphyreg.h b/src/add-ons/kernel/drivers/network/dec21xxx/dev/mii/amphyreg.h index 6aa82e39341..6cdbc95647b 100644 --- a/src/add-ons/kernel/drivers/network/dec21xxx/dev/mii/amphyreg.h +++ b/src/add-ons/kernel/drivers/network/dec21xxx/dev/mii/amphyreg.h @@ -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_ diff --git a/src/add-ons/kernel/drivers/network/dec21xxx/dev/mii/ukphy.c b/src/add-ons/kernel/drivers/network/dec21xxx/dev/mii/ukphy.c index 4ecfce29d31..9d52eb580ca 100644 --- a/src/add-ons/kernel/drivers/network/dec21xxx/dev/mii/ukphy.c +++ b/src/add-ons/kernel/drivers/network/dec21xxx/dev/mii/ukphy.c @@ -55,7 +55,7 @@ */ #include -__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; diff --git a/src/add-ons/kernel/drivers/network/dec21xxx/dev/mii/ukphy_subr.c b/src/add-ons/kernel/drivers/network/dec21xxx/dev/mii/ukphy_subr.c index 73007e197b9..5f2f6341ba6 100644 --- a/src/add-ons/kernel/drivers/network/dec21xxx/dev/mii/ukphy_subr.c +++ b/src/add-ons/kernel/drivers/network/dec21xxx/dev/mii/ukphy_subr.c @@ -31,7 +31,7 @@ */ #include -__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. diff --git a/src/add-ons/kernel/drivers/network/ipro100/dev/fxp/if_fxp.c b/src/add-ons/kernel/drivers/network/ipro100/dev/fxp/if_fxp.c index c0c839dd403..bcbfe1bddb8 100644 --- a/src/add-ons/kernel/drivers/network/ipro100/dev/fxp/if_fxp.c +++ b/src/add-ons/kernel/drivers/network/ipro100/dev/fxp/if_fxp.c @@ -28,7 +28,7 @@ */ #include -__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" }, @@ -236,11 +236,11 @@ static int fxp_ioctl(struct ifnet *ifp, u_long command, caddr_t data); static void fxp_watchdog(struct fxp_softc *sc); static void fxp_add_rfabuf(struct fxp_softc *sc, - struct fxp_rx *rxp); + struct fxp_rx *rxp); static void fxp_discard_rfabuf(struct fxp_softc *sc, - struct fxp_rx *rxp); + struct fxp_rx *rxp); static int fxp_new_rfabuf(struct fxp_softc *sc, - struct fxp_rx *rxp); + struct fxp_rx *rxp); static int fxp_mc_addrs(struct fxp_softc *sc); static void fxp_mc_setup(struct fxp_softc *sc); static uint16_t fxp_eeprom_getword(struct fxp_softc *sc, int offset, @@ -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, @@ -272,7 +273,7 @@ static int sysctl_hw_fxp_int_delay(SYSCTL_HANDLER_ARGS); static void fxp_scb_wait(struct fxp_softc *sc); static void fxp_scb_cmd(struct fxp_softc *sc, int cmd); static void fxp_dma_wait(struct fxp_softc *sc, - volatile uint16_t *status, bus_dma_tag_t dmat, + volatile uint16_t *status, bus_dma_tag_t dmat, bus_dmamap_t map); static device_method_t fxp_methods[] = { @@ -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); @@ -1541,7 +1571,7 @@ fxp_encap(struct fxp_softc *sc, struct mbuf **m_head) } *m_head = m; error = bus_dmamap_load_mbuf_sg(sc->fxp_txmtag, txp->tx_map, - *m_head, segs, &nseg, 0); + *m_head, segs, &nseg, 0); if (error != 0) { m_freem(*m_head); *m_head = NULL; @@ -2048,7 +2078,7 @@ fxp_update_stats(struct fxp_softc *sc) */ sc->rx_idle_secs++; } - ifp->if_ierrors += + ifp->if_ierrors += le32toh(sp->rx_crc_errors) + le32toh(sp->rx_alignment_errors) + le32toh(sp->rx_rnr_errors) + @@ -2175,7 +2205,7 @@ fxp_stop(struct fxp_softc *sc) txp = sc->fxp_desc.tx_list; if (txp != NULL) { for (i = 0; i < FXP_NTXCB; i++) { - if (txp[i].tx_mbuf != NULL) { + if (txp[i].tx_mbuf != NULL) { bus_dmamap_sync(sc->fxp_txmtag, txp[i].tx_map, BUS_DMASYNC_POSTWRITE); bus_dmamap_unload(sc->fxp_txmtag, @@ -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) \ diff --git a/src/add-ons/kernel/drivers/network/ipro100/dev/fxp/if_fxpreg.h b/src/add-ons/kernel/drivers/network/ipro100/dev/fxp/if_fxpreg.h index e2b1e3f4983..cc764b54b2d 100644 --- a/src/add-ons/kernel/drivers/network/ipro100/dev/fxp/if_fxpreg.h +++ b/src/add-ons/kernel/drivers/network/ipro100/dev/fxp/if_fxpreg.h @@ -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 */ diff --git a/src/add-ons/kernel/drivers/network/ipro100/dev/fxp/if_fxpvar.h b/src/add-ons/kernel/drivers/network/ipro100/dev/fxp/if_fxpvar.h index 3d6ba30aad7..253c4ff1ec5 100644 --- a/src/add-ons/kernel/drivers/network/ipro100/dev/fxp/if_fxpvar.h +++ b/src/add-ons/kernel/drivers/network/ipro100/dev/fxp/if_fxpvar.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/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) diff --git a/src/add-ons/kernel/drivers/network/ipro100/dev/fxp/inphy.c b/src/add-ons/kernel/drivers/network/ipro100/dev/fxp/inphy.c index b9e40a103ef..587f3fd6255 100644 --- a/src/add-ons/kernel/drivers/network/ipro100/dev/fxp/inphy.c +++ b/src/add-ons/kernel/drivers/network/ipro100/dev/fxp/inphy.c @@ -29,7 +29,7 @@ */ #include -__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 diff --git a/src/add-ons/kernel/drivers/network/ipro100/dev/fxp/inphyreg.h b/src/add-ons/kernel/drivers/network/ipro100/dev/fxp/inphyreg.h index 33d9ad874eb..42c683dbf18 100644 --- a/src/add-ons/kernel/drivers/network/ipro100/dev/fxp/inphyreg.h +++ b/src/add-ons/kernel/drivers/network/ipro100/dev/fxp/inphyreg.h @@ -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 diff --git a/src/add-ons/kernel/drivers/network/ipro100/dev/fxp/rcvbundl.h b/src/add-ons/kernel/drivers/network/ipro100/dev/fxp/rcvbundl.h index 39e70e96e20..2510f420b6f 100644 --- a/src/add-ons/kernel/drivers/network/ipro100/dev/fxp/rcvbundl.h +++ b/src/add-ons/kernel/drivers/network/ipro100/dev/fxp/rcvbundl.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 diff --git a/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/LICENSE b/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/LICENSE index 3417b58c52e..f70a7cbd4a1 100644 --- a/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/LICENSE +++ b/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/LICENSE @@ -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. diff --git a/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/README b/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/README index 6eb6512f559..88879e1840f 100644 --- a/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/README +++ b/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/README @@ -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: diff --git a/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_80003es2lan.c b/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_80003es2lan.c index 335f075420f..bdbb31cfdbb 100644 --- a/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_80003es2lan.c +++ b/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_80003es2lan.c @@ -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) @@ -47,18 +47,18 @@ static void e1000_release_phy_80003es2lan(struct e1000_hw *hw); static s32 e1000_acquire_nvm_80003es2lan(struct e1000_hw *hw); static void e1000_release_nvm_80003es2lan(struct e1000_hw *hw); static s32 e1000_read_phy_reg_gg82563_80003es2lan(struct e1000_hw *hw, - u32 offset, - u16 *data); + u32 offset, + u16 *data); static s32 e1000_write_phy_reg_gg82563_80003es2lan(struct e1000_hw *hw, - u32 offset, - u16 data); + u32 offset, + u16 data); static s32 e1000_write_nvm_80003es2lan(struct e1000_hw *hw, u16 offset, - u16 words, u16 *data); + u16 words, u16 *data); static s32 e1000_get_cfg_done_80003es2lan(struct e1000_hw *hw); static s32 e1000_phy_force_speed_duplex_80003es2lan(struct e1000_hw *hw); static s32 e1000_get_cable_length_80003es2lan(struct e1000_hw *hw); static s32 e1000_get_link_up_info_80003es2lan(struct e1000_hw *hw, u16 *speed, - u16 *duplex); + u16 *duplex); static s32 e1000_reset_hw_80003es2lan(struct e1000_hw *hw); static s32 e1000_init_hw_80003es2lan(struct e1000_hw *hw); static s32 e1000_setup_copper_link_80003es2lan(struct e1000_hw *hw); @@ -68,9 +68,9 @@ static s32 e1000_cfg_kmrn_10_100_80003es2lan(struct e1000_hw *hw, u16 duplex); static s32 e1000_cfg_kmrn_1000_80003es2lan(struct e1000_hw *hw); static s32 e1000_cfg_on_link_up_80003es2lan(struct e1000_hw *hw); static s32 e1000_read_kmrn_reg_80003es2lan(struct e1000_hw *hw, u32 offset, - u16 *data); + u16 *data); static s32 e1000_write_kmrn_reg_80003es2lan(struct e1000_hw *hw, u32 offset, - u16 data); + u16 data); static s32 e1000_copper_link_setup_gg82563_80003es2lan(struct e1000_hw *hw); static void e1000_initialize_hw_bits_80003es2lan(struct e1000_hw *hw); static void e1000_release_swfw_sync_80003es2lan(struct e1000_hw *hw, u16 mask); @@ -85,8 +85,8 @@ static void e1000_power_down_phy_copper_80003es2lan(struct e1000_hw *hw); static const u16 e1000_gg82563_cable_length_table[] = { 0, 60, 115, 150, 150, 60, 115, 150, 180, 180, 0xFF }; #define GG82563_CABLE_LENGTH_TABLE_SIZE \ - (sizeof(e1000_gg82563_cable_length_table) / \ - sizeof(e1000_gg82563_cable_length_table[0])) + (sizeof(e1000_gg82563_cable_length_table) / \ + sizeof(e1000_gg82563_cable_length_table[0])) /** * e1000_init_phy_params_80003es2lan - Init ESB2 PHY func ptrs. @@ -100,34 +100,34 @@ static s32 e1000_init_phy_params_80003es2lan(struct e1000_hw *hw) DEBUGFUNC("e1000_init_phy_params_80003es2lan"); if (hw->phy.media_type != e1000_media_type_copper) { - phy->type = e1000_phy_none; + phy->type = e1000_phy_none; goto out; } else { phy->ops.power_up = e1000_power_up_phy_copper; phy->ops.power_down = e1000_power_down_phy_copper_80003es2lan; } - phy->addr = 1; - phy->autoneg_mask = AUTONEG_ADVERTISE_SPEED_DEFAULT; - phy->reset_delay_us = 100; - phy->type = e1000_phy_gg82563; - - phy->ops.acquire = e1000_acquire_phy_80003es2lan; - phy->ops.check_polarity = e1000_check_polarity_m88; - phy->ops.check_reset_block = e1000_check_reset_block_generic; - phy->ops.commit = e1000_phy_sw_reset_generic; - phy->ops.get_cfg_done = e1000_get_cfg_done_80003es2lan; - phy->ops.get_info = e1000_get_phy_info_m88; - phy->ops.release = e1000_release_phy_80003es2lan; - phy->ops.reset = e1000_phy_hw_reset_generic; - phy->ops.set_d3_lplu_state = e1000_set_d3_lplu_state_generic; + phy->addr = 1; + phy->autoneg_mask = AUTONEG_ADVERTISE_SPEED_DEFAULT; + phy->reset_delay_us = 100; + phy->type = e1000_phy_gg82563; + + phy->ops.acquire = e1000_acquire_phy_80003es2lan; + phy->ops.check_polarity = e1000_check_polarity_m88; + phy->ops.check_reset_block = e1000_check_reset_block_generic; + phy->ops.commit = e1000_phy_sw_reset_generic; + phy->ops.get_cfg_done = e1000_get_cfg_done_80003es2lan; + phy->ops.get_info = e1000_get_phy_info_m88; + phy->ops.release = e1000_release_phy_80003es2lan; + phy->ops.reset = e1000_phy_hw_reset_generic; + phy->ops.set_d3_lplu_state = e1000_set_d3_lplu_state_generic; phy->ops.force_speed_duplex = e1000_phy_force_speed_duplex_80003es2lan; - phy->ops.get_cable_length = e1000_get_cable_length_80003es2lan; - phy->ops.read_reg = e1000_read_phy_reg_gg82563_80003es2lan; - phy->ops.write_reg = e1000_write_phy_reg_gg82563_80003es2lan; + phy->ops.get_cable_length = e1000_get_cable_length_80003es2lan; + phy->ops.read_reg = e1000_read_phy_reg_gg82563_80003es2lan; + phy->ops.write_reg = e1000_write_phy_reg_gg82563_80003es2lan; - phy->ops.cfg_on_link_up = e1000_cfg_on_link_up_80003es2lan; + phy->ops.cfg_on_link_up = e1000_cfg_on_link_up_80003es2lan; /* This can only be done after all function pointers are setup. */ ret_val = e1000_get_phy_id(hw); @@ -154,19 +154,19 @@ static s32 e1000_init_nvm_params_80003es2lan(struct e1000_hw *hw) DEBUGFUNC("e1000_init_nvm_params_80003es2lan"); - nvm->opcode_bits = 8; - nvm->delay_usec = 1; + nvm->opcode_bits = 8; + nvm->delay_usec = 1; switch (nvm->override) { case e1000_nvm_override_spi_large: - nvm->page_size = 32; + nvm->page_size = 32; nvm->address_bits = 16; break; case e1000_nvm_override_spi_small: - nvm->page_size = 8; + nvm->page_size = 8; nvm->address_bits = 8; break; default: - nvm->page_size = eecd & E1000_EECD_ADDR_BITS ? 32 : 8; + nvm->page_size = eecd & E1000_EECD_ADDR_BITS ? 32 : 8; nvm->address_bits = eecd & E1000_EECD_ADDR_BITS ? 16 : 8; break; } @@ -174,7 +174,7 @@ static s32 e1000_init_nvm_params_80003es2lan(struct e1000_hw *hw) nvm->type = e1000_nvm_eeprom_spi; size = (u16)((eecd & E1000_EECD_SIZE_EX_MASK) >> - E1000_EECD_SIZE_EX_SHIFT); + E1000_EECD_SIZE_EX_SHIFT); /* * Added to a constant, "size" becomes the left-shift value @@ -185,16 +185,16 @@ static s32 e1000_init_nvm_params_80003es2lan(struct e1000_hw *hw) /* EEPROM access above 16k is unsupported */ if (size > 14) size = 14; - nvm->word_size = 1 << size; + nvm->word_size = 1 << size; /* Function Pointers */ - nvm->ops.acquire = e1000_acquire_nvm_80003es2lan; - nvm->ops.read = e1000_read_nvm_eerd; - nvm->ops.release = e1000_release_nvm_80003es2lan; - nvm->ops.update = e1000_update_nvm_checksum_generic; + nvm->ops.acquire = e1000_acquire_nvm_80003es2lan; + nvm->ops.read = e1000_read_nvm_eerd; + nvm->ops.release = e1000_release_nvm_80003es2lan; + nvm->ops.update = e1000_update_nvm_checksum_generic; nvm->ops.valid_led_default = e1000_valid_led_default_generic; - nvm->ops.validate = e1000_validate_nvm_checksum_generic; - nvm->ops.write = e1000_write_nvm_80003es2lan; + nvm->ops.validate = e1000_validate_nvm_checksum_generic; + nvm->ops.write = e1000_write_nvm_80003es2lan; return E1000_SUCCESS; } @@ -215,13 +215,13 @@ static s32 e1000_init_mac_params_80003es2lan(struct e1000_hw *hw) hw->phy.media_type = e1000_media_type_internal_serdes; mac->ops.check_for_link = e1000_check_for_serdes_link_generic; mac->ops.setup_physical_interface = - e1000_setup_fiber_serdes_link_generic; + e1000_setup_fiber_serdes_link_generic; break; default: hw->phy.media_type = e1000_media_type_copper; mac->ops.check_for_link = e1000_check_for_copper_link_generic; mac->ops.setup_physical_interface = - e1000_setup_copper_link_80003es2lan; + e1000_setup_copper_link_80003es2lan; break; } @@ -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 @@ -488,7 +487,7 @@ static void e1000_release_swfw_sync_80003es2lan(struct e1000_hw *hw, u16 mask) * Read the GG82563 PHY register. **/ static s32 e1000_read_phy_reg_gg82563_80003es2lan(struct e1000_hw *hw, - u32 offset, u16 *data) + u32 offset, u16 *data) { s32 ret_val; u32 page_select; @@ -538,14 +537,14 @@ static s32 e1000_read_phy_reg_gg82563_80003es2lan(struct e1000_hw *hw, usec_delay(200); ret_val = e1000_read_phy_reg_mdic(hw, - MAX_PHY_REG_ADDRESS & offset, - data); + MAX_PHY_REG_ADDRESS & offset, + data); usec_delay(200); } else { ret_val = e1000_read_phy_reg_mdic(hw, - MAX_PHY_REG_ADDRESS & offset, - data); + MAX_PHY_REG_ADDRESS & offset, + data); } e1000_release_phy_80003es2lan(hw); @@ -563,7 +562,7 @@ static s32 e1000_read_phy_reg_gg82563_80003es2lan(struct e1000_hw *hw, * Write to the GG82563 PHY register. **/ static s32 e1000_write_phy_reg_gg82563_80003es2lan(struct e1000_hw *hw, - u32 offset, u16 data) + u32 offset, u16 data) { s32 ret_val; u32 page_select; @@ -613,14 +612,14 @@ static s32 e1000_write_phy_reg_gg82563_80003es2lan(struct e1000_hw *hw, usec_delay(200); ret_val = e1000_write_phy_reg_mdic(hw, - MAX_PHY_REG_ADDRESS & offset, - data); + MAX_PHY_REG_ADDRESS & offset, + data); usec_delay(200); } else { ret_val = e1000_write_phy_reg_mdic(hw, - MAX_PHY_REG_ADDRESS & offset, - data); + MAX_PHY_REG_ADDRESS & offset, + data); } e1000_release_phy_80003es2lan(hw); @@ -639,7 +638,7 @@ static s32 e1000_write_phy_reg_gg82563_80003es2lan(struct e1000_hw *hw, * Write "words" of data to the ESB2 NVM. **/ static s32 e1000_write_nvm_80003es2lan(struct e1000_hw *hw, u16 offset, - u16 words, u16 *data) + u16 words, u16 *data) { DEBUGFUNC("e1000_write_nvm_80003es2lan"); @@ -729,11 +728,10 @@ 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); + 100000, &link); if (ret_val) goto out; @@ -749,12 +747,13 @@ static s32 e1000_phy_force_speed_duplex_80003es2lan(struct e1000_hw *hw) /* Try once more */ ret_val = e1000_phy_has_link_generic(hw, PHY_FORCE_LIMIT, - 100000, &link); + 100000, &link); if (ret_val) 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; @@ -826,21 +826,20 @@ static s32 e1000_get_cable_length_80003es2lan(struct e1000_hw *hw) * Retrieve the current speed and duplex configuration. **/ static s32 e1000_get_link_up_info_80003es2lan(struct e1000_hw *hw, u16 *speed, - u16 *duplex) + u16 *duplex) { s32 ret_val; 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, - duplex); + ret_val = e1000_get_speed_and_duplex_copper_generic(hw, speed, + duplex); hw->phy.ops.cfg_on_link_up(hw); } else { ret_val = e1000_get_speed_and_duplex_fiber_serdes_generic(hw, - speed, - duplex); + speed, + duplex); } return ret_val; @@ -939,21 +938,21 @@ static s32 e1000_init_hw_80003es2lan(struct e1000_hw *hw) /* Disable IBIST slave mode (far-end loopback) */ e1000_read_kmrn_reg_80003es2lan(hw, E1000_KMRNCTRLSTA_INBAND_PARAM, - &kum_reg_data); + &kum_reg_data); kum_reg_data |= E1000_KMRNCTRLSTA_IBIST_DISABLE; e1000_write_kmrn_reg_80003es2lan(hw, E1000_KMRNCTRLSTA_INBAND_PARAM, - kum_reg_data); + kum_reg_data); /* 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. */ reg_data = E1000_READ_REG(hw, E1000_TXDCTL(1)); 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(1), reg_data); /* Enable retransmit on late collisions */ @@ -981,9 +980,9 @@ static s32 e1000_init_hw_80003es2lan(struct e1000_hw *hw) hw->dev_spec._80003es2lan.mdic_wa_enable = TRUE; ret_val = e1000_read_kmrn_reg_80003es2lan(hw, - E1000_KMRNCTRLSTA_OFFSET >> - E1000_KMRNCTRLSTA_OFFSET_SHIFT, - &i); + E1000_KMRNCTRLSTA_OFFSET >> + E1000_KMRNCTRLSTA_OFFSET_SHIFT, + &i); if (!ret_val) { if ((i & E1000_KMRNCTRLSTA_OPMODE_MASK) == E1000_KMRNCTRLSTA_OPMODE_INBAND_MDIO) @@ -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 @@ static s32 e1000_copper_link_setup_gg82563_80003es2lan(struct e1000_hw *hw) 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; @@ -1169,18 +1160,18 @@ static s32 e1000_copper_link_setup_gg82563_80003es2lan(struct e1000_hw *hw) /* Enable Electrical Idle on the PHY */ data |= GG82563_PMCR_ENABLE_ELECTRICAL_IDLE; ret_val = hw->phy.ops.write_reg(hw, GG82563_PHY_PWR_MGMT_CTRL, - data); + data); if (ret_val) goto out; ret_val = hw->phy.ops.read_reg(hw, GG82563_PHY_KMRN_MODE_CTRL, - &data); + &data); if (ret_val) goto out; data &= ~GG82563_KMCR_PASS_FALSE_CARRIER; ret_val = hw->phy.ops.write_reg(hw, GG82563_PHY_KMRN_MODE_CTRL, - data); + data); if (ret_val) goto out; } @@ -1228,27 +1219,25 @@ static s32 e1000_setup_copper_link_80003es2lan(struct e1000_hw *hw) * polling the phy; this fixes erroneous timeouts at 10Mbps. */ ret_val = e1000_write_kmrn_reg_80003es2lan(hw, GG82563_REG(0x34, 4), - 0xFFFF); + 0xFFFF); if (ret_val) goto out; ret_val = e1000_read_kmrn_reg_80003es2lan(hw, GG82563_REG(0x34, 9), - ®_data); + ®_data); if (ret_val) goto out; reg_data |= 0x3F; ret_val = e1000_write_kmrn_reg_80003es2lan(hw, GG82563_REG(0x34, 9), - reg_data); + reg_data); if (ret_val) goto out; ret_val = e1000_read_kmrn_reg_80003es2lan(hw, - E1000_KMRNCTRLSTA_OFFSET_INB_CTRL, - ®_data); + E1000_KMRNCTRLSTA_OFFSET_INB_CTRL, ®_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,9 +1268,8 @@ 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, - &duplex); + ret_val = e1000_get_speed_and_duplex_copper_generic(hw, &speed, + &duplex); if (ret_val) goto out; @@ -1314,8 +1302,8 @@ static s32 e1000_cfg_kmrn_10_100_80003es2lan(struct e1000_hw *hw, u16 duplex) reg_data = E1000_KMRNCTRLSTA_HD_CTRL_10_100_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; @@ -1327,12 +1315,12 @@ static s32 e1000_cfg_kmrn_10_100_80003es2lan(struct e1000_hw *hw, u16 duplex) do { ret_val = hw->phy.ops.read_reg(hw, GG82563_PHY_KMRN_MODE_CTRL, - ®_data); + ®_data); if (ret_val) goto out; ret_val = hw->phy.ops.read_reg(hw, GG82563_PHY_KMRN_MODE_CTRL, - ®_data2); + ®_data2); if (ret_val) goto out; i++; @@ -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; @@ -1380,19 +1368,20 @@ static s32 e1000_cfg_kmrn_1000_80003es2lan(struct e1000_hw *hw) do { ret_val = hw->phy.ops.read_reg(hw, GG82563_PHY_KMRN_MODE_CTRL, - ®_data); + ®_data); if (ret_val) goto out; ret_val = hw->phy.ops.read_reg(hw, GG82563_PHY_KMRN_MODE_CTRL, - ®_data2); + ®_data2); if (ret_val) goto out; i++; } 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; @@ -1409,7 +1398,7 @@ static s32 e1000_cfg_kmrn_1000_80003es2lan(struct e1000_hw *hw) * Release the semaphore before exiting. **/ static s32 e1000_read_kmrn_reg_80003es2lan(struct e1000_hw *hw, u32 offset, - u16 *data) + u16 *data) { u32 kmrnctrlsta; s32 ret_val = E1000_SUCCESS; @@ -1421,8 +1410,9 @@ static s32 e1000_read_kmrn_reg_80003es2lan(struct e1000_hw *hw, u32 offset, goto out; kmrnctrlsta = ((offset << E1000_KMRNCTRLSTA_OFFSET_SHIFT) & - E1000_KMRNCTRLSTA_OFFSET) | E1000_KMRNCTRLSTA_REN; + E1000_KMRNCTRLSTA_OFFSET) | E1000_KMRNCTRLSTA_REN; E1000_WRITE_REG(hw, E1000_KMRNCTRLSTA, kmrnctrlsta); + E1000_WRITE_FLUSH(hw); usec_delay(2); @@ -1446,7 +1436,7 @@ static s32 e1000_read_kmrn_reg_80003es2lan(struct e1000_hw *hw, u32 offset, * before exiting. **/ static s32 e1000_write_kmrn_reg_80003es2lan(struct e1000_hw *hw, u32 offset, - u16 data) + u16 data) { u32 kmrnctrlsta; s32 ret_val = E1000_SUCCESS; @@ -1458,8 +1448,9 @@ static s32 e1000_write_kmrn_reg_80003es2lan(struct e1000_hw *hw, u32 offset, goto out; kmrnctrlsta = ((offset << E1000_KMRNCTRLSTA_OFFSET_SHIFT) & - E1000_KMRNCTRLSTA_OFFSET) | data; + E1000_KMRNCTRLSTA_OFFSET) | data; E1000_WRITE_REG(hw, E1000_KMRNCTRLSTA, kmrnctrlsta); + E1000_WRITE_FLUSH(hw); usec_delay(2); diff --git a/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_80003es2lan.h b/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_80003es2lan.h index b685f37dcca..157468e485d 100644 --- a/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_80003es2lan.h +++ b/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_80003es2lan.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,53 +30,52 @@ 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_ -#define E1000_KMRNCTRLSTA_OFFSET_FIFO_CTRL 0x00 -#define E1000_KMRNCTRLSTA_OFFSET_INB_CTRL 0x02 -#define E1000_KMRNCTRLSTA_OFFSET_HD_CTRL 0x10 -#define E1000_KMRNCTRLSTA_OFFSET_MAC2PHY_OPMODE 0x1F +#define E1000_KMRNCTRLSTA_OFFSET_FIFO_CTRL 0x00 +#define E1000_KMRNCTRLSTA_OFFSET_INB_CTRL 0x02 +#define E1000_KMRNCTRLSTA_OFFSET_HD_CTRL 0x10 +#define E1000_KMRNCTRLSTA_OFFSET_MAC2PHY_OPMODE 0x1F -#define E1000_KMRNCTRLSTA_FIFO_CTRL_RX_BYPASS 0x0008 -#define E1000_KMRNCTRLSTA_FIFO_CTRL_TX_BYPASS 0x0800 -#define E1000_KMRNCTRLSTA_INB_CTRL_DIS_PADDING 0x0010 +#define E1000_KMRNCTRLSTA_FIFO_CTRL_RX_BYPASS 0x0008 +#define E1000_KMRNCTRLSTA_FIFO_CTRL_TX_BYPASS 0x0800 +#define E1000_KMRNCTRLSTA_INB_CTRL_DIS_PADDING 0x0010 #define E1000_KMRNCTRLSTA_HD_CTRL_10_100_DEFAULT 0x0004 -#define E1000_KMRNCTRLSTA_HD_CTRL_1000_DEFAULT 0x0000 -#define E1000_KMRNCTRLSTA_OPMODE_E_IDLE 0x2000 +#define E1000_KMRNCTRLSTA_HD_CTRL_1000_DEFAULT 0x0000 +#define E1000_KMRNCTRLSTA_OPMODE_E_IDLE 0x2000 -#define E1000_KMRNCTRLSTA_OPMODE_MASK 0x000C -#define E1000_KMRNCTRLSTA_OPMODE_INBAND_MDIO 0x0004 +#define E1000_KMRNCTRLSTA_OPMODE_MASK 0x000C +#define E1000_KMRNCTRLSTA_OPMODE_INBAND_MDIO 0x0004 #define E1000_TCTL_EXT_GCEX_MASK 0x000FFC00 /* Gigabit Carry Extend Padding */ -#define DEFAULT_TCTL_EXT_GCEX_80003ES2LAN 0x00010000 +#define DEFAULT_TCTL_EXT_GCEX_80003ES2LAN 0x00010000 -#define DEFAULT_TIPG_IPGT_1000_80003ES2LAN 0x8 -#define DEFAULT_TIPG_IPGT_10_100_80003ES2LAN 0x9 +#define DEFAULT_TIPG_IPGT_1000_80003ES2LAN 0x8 +#define DEFAULT_TIPG_IPGT_10_100_80003ES2LAN 0x9 /* GG82563 PHY Specific Status Register (Page 0, Register 16 */ -#define GG82563_PSCR_POLARITY_REVERSAL_DISABLE 0x0002 /* 1=Reversal Disabled */ -#define GG82563_PSCR_CROSSOVER_MODE_MASK 0x0060 -#define GG82563_PSCR_CROSSOVER_MODE_MDI 0x0000 /* 00=Manual MDI */ -#define GG82563_PSCR_CROSSOVER_MODE_MDIX 0x0020 /* 01=Manual MDIX */ -#define GG82563_PSCR_CROSSOVER_MODE_AUTO 0x0060 /* 11=Auto crossover */ +#define GG82563_PSCR_POLARITY_REVERSAL_DISABLE 0x0002 /* 1=Reversal Disabled */ +#define GG82563_PSCR_CROSSOVER_MODE_MASK 0x0060 +#define GG82563_PSCR_CROSSOVER_MODE_MDI 0x0000 /* 00=Manual MDI */ +#define GG82563_PSCR_CROSSOVER_MODE_MDIX 0x0020 /* 01=Manual MDIX */ +#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 */ -#define GG82563_MSCR_TX_CLK_MASK 0x0007 -#define GG82563_MSCR_TX_CLK_10MBPS_2_5 0x0004 -#define GG82563_MSCR_TX_CLK_100MBPS_25 0x0005 -#define GG82563_MSCR_TX_CLK_1000MBPS_2_5 0x0006 -#define GG82563_MSCR_TX_CLK_1000MBPS_25 0x0007 +#define GG82563_MSCR_TX_CLK_MASK 0x0007 +#define GG82563_MSCR_TX_CLK_10MBPS_2_5 0x0004 +#define GG82563_MSCR_TX_CLK_100MBPS_25 0x0005 +#define GG82563_MSCR_TX_CLK_1000MBPS_2_5 0x0006 +#define GG82563_MSCR_TX_CLK_1000MBPS_25 0x0007 -#define GG82563_MSCR_ASSERT_CRS_ON_TX 0x0010 /* 1=Assert */ +#define GG82563_MSCR_ASSERT_CRS_ON_TX 0x0010 /* 1=Assert */ /* DSP Distance Register (Page 5, Register 26) */ /* @@ -86,19 +85,19 @@ * 3 = 110-140M * 4 = >140M */ -#define GG82563_DSPD_CABLE_LENGTH 0x0007 +#define GG82563_DSPD_CABLE_LENGTH 0x0007 /* Kumeran Mode Control Register (Page 193, Register 16) */ -#define GG82563_KMCR_PASS_FALSE_CARRIER 0x0800 +#define GG82563_KMCR_PASS_FALSE_CARRIER 0x0800 /* Max number of times Kumeran read/write should be validated */ -#define GG82563_MAX_KMRN_RETRY 0x5 +#define GG82563_MAX_KMRN_RETRY 0x5 /* Power Management Control Register (Page 193, Register 20) */ -#define GG82563_PMCR_ENABLE_ELECTRICAL_IDLE 0x0001 - /* 1=Enable SERDES Electrical Idle */ +/* 1=Enable SERDES Electrical Idle */ +#define GG82563_PMCR_ENABLE_ELECTRICAL_IDLE 0x0001 /* In-Band Control Register (Page 194, Register 18) */ -#define GG82563_ICR_DIS_PADDING 0x0010 /* Disable Padding */ +#define GG82563_ICR_DIS_PADDING 0x0010 /* Disable Padding */ #endif diff --git a/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_82540.c b/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_82540.c index 33383df0fe0..141b92e208f 100644 --- a/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_82540.c +++ b/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_82540.c @@ -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 @@ -68,23 +68,23 @@ static s32 e1000_init_phy_params_82540(struct e1000_hw *hw) struct e1000_phy_info *phy = &hw->phy; s32 ret_val = E1000_SUCCESS; - phy->addr = 1; - phy->autoneg_mask = AUTONEG_ADVERTISE_SPEED_DEFAULT; - phy->reset_delay_us = 10000; - phy->type = e1000_phy_m88; + phy->addr = 1; + phy->autoneg_mask = AUTONEG_ADVERTISE_SPEED_DEFAULT; + phy->reset_delay_us = 10000; + phy->type = e1000_phy_m88; /* Function Pointers */ - phy->ops.check_polarity = e1000_check_polarity_m88; - phy->ops.commit = e1000_phy_sw_reset_generic; - phy->ops.force_speed_duplex = e1000_phy_force_speed_duplex_m88; - phy->ops.get_cable_length = e1000_get_cable_length_m88; - phy->ops.get_cfg_done = e1000_get_cfg_done_generic; - phy->ops.read_reg = e1000_read_phy_reg_m88; - phy->ops.reset = e1000_phy_hw_reset_generic; - phy->ops.write_reg = e1000_write_phy_reg_m88; - phy->ops.get_info = e1000_get_phy_info_m88; - phy->ops.power_up = e1000_power_up_phy_copper; - phy->ops.power_down = e1000_power_down_phy_copper_82540; + phy->ops.check_polarity = e1000_check_polarity_m88; + phy->ops.commit = e1000_phy_sw_reset_generic; + phy->ops.force_speed_duplex = e1000_phy_force_speed_duplex_m88; + phy->ops.get_cable_length = e1000_get_cable_length_m88; + phy->ops.get_cfg_done = e1000_get_cfg_done_generic; + phy->ops.read_reg = e1000_read_phy_reg_m88; + phy->ops.reset = e1000_phy_hw_reset_generic; + phy->ops.write_reg = e1000_write_phy_reg_m88; + phy->ops.get_info = e1000_get_phy_info_m88; + phy->ops.power_up = e1000_power_up_phy_copper; + phy->ops.power_down = e1000_power_down_phy_copper_82540; ret_val = e1000_get_phy_id(hw); if (ret_val) @@ -121,32 +121,32 @@ static s32 e1000_init_nvm_params_82540(struct e1000_hw *hw) DEBUGFUNC("e1000_init_nvm_params_82540"); - nvm->type = e1000_nvm_eeprom_microwire; - nvm->delay_usec = 50; - nvm->opcode_bits = 3; + nvm->type = e1000_nvm_eeprom_microwire; + nvm->delay_usec = 50; + nvm->opcode_bits = 3; switch (nvm->override) { case e1000_nvm_override_microwire_large: - nvm->address_bits = 8; - nvm->word_size = 256; + nvm->address_bits = 8; + nvm->word_size = 256; break; case e1000_nvm_override_microwire_small: - nvm->address_bits = 6; - nvm->word_size = 64; + nvm->address_bits = 6; + nvm->word_size = 64; break; default: - nvm->address_bits = eecd & E1000_EECD_SIZE ? 8 : 6; - nvm->word_size = eecd & E1000_EECD_SIZE ? 256 : 64; + nvm->address_bits = eecd & E1000_EECD_SIZE ? 8 : 6; + nvm->word_size = eecd & E1000_EECD_SIZE ? 256 : 64; break; } /* Function Pointers */ - nvm->ops.acquire = e1000_acquire_nvm_generic; - nvm->ops.read = e1000_read_nvm_microwire; - nvm->ops.release = e1000_release_nvm_generic; - nvm->ops.update = e1000_update_nvm_checksum_generic; - nvm->ops.valid_led_default = e1000_valid_led_default_generic; - nvm->ops.validate = e1000_validate_nvm_checksum_generic; - nvm->ops.write = e1000_write_nvm_microwire; + nvm->ops.acquire = e1000_acquire_nvm_generic; + nvm->ops.read = e1000_read_nvm_microwire; + nvm->ops.release = e1000_release_nvm_generic; + nvm->ops.update = e1000_update_nvm_checksum_generic; + nvm->ops.valid_led_default = e1000_valid_led_default_generic; + nvm->ops.validate = e1000_validate_nvm_checksum_generic; + nvm->ops.write = e1000_write_nvm_microwire; return E1000_SUCCESS; } @@ -198,9 +198,9 @@ static s32 e1000_init_mac_params_82540(struct e1000_hw *hw) mac->ops.setup_link = e1000_setup_link_generic; /* physical interface setup */ mac->ops.setup_physical_interface = - (hw->phy.media_type == e1000_media_type_copper) - ? e1000_setup_copper_link_82540 - : e1000_setup_fiber_serdes_link_82540; + (hw->phy.media_type == e1000_media_type_copper) + ? e1000_setup_copper_link_82540 + : e1000_setup_fiber_serdes_link_82540; /* check for link */ switch (hw->phy.media_type) { case e1000_media_type_copper: @@ -219,9 +219,9 @@ static s32 e1000_init_mac_params_82540(struct e1000_hw *hw) } /* link info */ mac->ops.get_link_up_info = - (hw->phy.media_type == e1000_media_type_copper) - ? e1000_get_speed_and_duplex_copper_generic - : e1000_get_speed_and_duplex_fiber_serdes_generic; + (hw->phy.media_type == e1000_media_type_copper) + ? e1000_get_speed_and_duplex_copper_generic + : e1000_get_speed_and_duplex_fiber_serdes_generic; /* multicast address update */ mac->ops.update_mc_addr_list = e1000_update_mc_addr_list_generic; /* writing VFTA */ @@ -374,7 +374,7 @@ static s32 e1000_init_hw_82540(struct e1000_hw *hw) txdctl = E1000_READ_REG(hw, E1000_TXDCTL(0)); txdctl = (txdctl & ~E1000_TXDCTL_WTHRESH) | - E1000_TXDCTL_FULL_TX_DESC_WB; + E1000_TXDCTL_FULL_TX_DESC_WB; E1000_WRITE_REG(hw, E1000_TXDCTL(0), txdctl); /* @@ -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,9 +510,8 @@ 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, - nvm_data); + ret_val = hw->phy.ops.write_reg(hw, M88E1000_PHY_EXT_CTRL, + nvm_data); if (ret_val) goto out; } @@ -535,9 +536,8 @@ 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, - &default_page); + ret_val = hw->phy.ops.read_reg(hw, M88E1000_PHY_PAGE_SELECT, + &default_page); if (ret_val) goto out; @@ -570,7 +570,7 @@ static s32 e1000_set_vco_speed_82540(struct e1000_hw *hw) goto out; ret_val = hw->phy.ops.write_reg(hw, M88E1000_PHY_PAGE_SELECT, - default_page); + default_page); out: return ret_val; @@ -587,7 +587,6 @@ static s32 e1000_set_vco_speed_82540(struct e1000_hw *hw) **/ 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; @@ -604,20 +603,18 @@ static s32 e1000_set_phy_mode_82540(struct e1000_hw *hw) if ((nvm_data != NVM_RESERVED_WORD) && (nvm_data & NVM_PHY_CLASS_A)) { ret_val = hw->phy.ops.write_reg(hw, M88E1000_PHY_PAGE_SELECT, - 0x000B); + 0x000B); if (ret_val) { ret_val = -E1000_ERR_PHY; goto out; } - ret_val = hw->phy.ops.write_reg(hw, - M88E1000_PHY_GEN_CONTROL, - 0x8104); + 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: diff --git a/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_82541.c b/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_82541.c index 6e0bdd9f566..781aa931fb2 100644 --- a/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_82541.c +++ b/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_82541.c @@ -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; } @@ -390,7 +390,7 @@ static s32 e1000_init_hw_82541(struct e1000_hw *hw) DEBUGOUT("Error initializing identification LED\n"); /* This is not fatal and we should not stop init due to this */ } - + /* Storing the Speed Power Down value for later use */ ret_val = hw->phy.ops.read_reg(hw, IGP01E1000_GMII_FIFO, @@ -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. diff --git a/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_82541.h b/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_82541.h index 477707e5159..3b6b9612ee8 100644 --- a/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_82541.h +++ b/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_82541.h @@ -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_ diff --git a/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_82542.c b/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_82542.c index b4159833f7f..c0b4e88be98 100644 --- a/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_82542.c +++ b/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_82542.c @@ -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 diff --git a/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_82543.c b/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_82543.c index 89ebf512b88..1c01658cfc9 100644 --- a/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_82543.c +++ b/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_82543.c @@ -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 diff --git a/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_82543.h b/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_82543.h index 5388c8beaa3..60e5c15dda6 100644 --- a/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_82543.h +++ b/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_82543.h @@ -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_ diff --git a/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_82571.c b/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_82571.c index 7bcedc26837..30015c1eaa4 100644 --- a/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_82571.c +++ b/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_82571.c @@ -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 @@ -57,12 +57,12 @@ static s32 e1000_init_mac_params_82571(struct e1000_hw *hw); static s32 e1000_acquire_nvm_82571(struct e1000_hw *hw); static void e1000_release_nvm_82571(struct e1000_hw *hw); static s32 e1000_write_nvm_82571(struct e1000_hw *hw, u16 offset, - u16 words, u16 *data); + u16 words, u16 *data); static s32 e1000_update_nvm_checksum_82571(struct e1000_hw *hw); static s32 e1000_validate_nvm_checksum_82571(struct e1000_hw *hw); static s32 e1000_get_cfg_done_82571(struct e1000_hw *hw); static s32 e1000_set_d0_lplu_state_82571(struct e1000_hw *hw, - bool active); + bool active); static s32 e1000_reset_hw_82571(struct e1000_hw *hw); static s32 e1000_init_hw_82571(struct e1000_hw *hw); static void e1000_clear_vfta_82571(struct e1000_hw *hw); @@ -83,12 +83,12 @@ static void e1000_put_hw_semaphore_82573(struct e1000_hw *hw); static s32 e1000_get_hw_semaphore_82574(struct e1000_hw *hw); static void e1000_put_hw_semaphore_82574(struct e1000_hw *hw); static s32 e1000_set_d0_lplu_state_82574(struct e1000_hw *hw, - bool active); + bool active); static s32 e1000_set_d3_lplu_state_82574(struct e1000_hw *hw, - bool active); + bool active); static void e1000_initialize_hw_bits_82571(struct e1000_hw *hw); static s32 e1000_write_nvm_eewr_82571(struct e1000_hw *hw, u16 offset, - u16 words, u16 *data); + u16 words, u16 *data); static s32 e1000_read_mac_addr_82571(struct e1000_hw *hw); static void e1000_power_down_phy_copper_82571(struct e1000_hw *hw); @@ -108,61 +108,61 @@ static s32 e1000_init_phy_params_82571(struct e1000_hw *hw) goto out; } - phy->addr = 1; - phy->autoneg_mask = AUTONEG_ADVERTISE_SPEED_DEFAULT; - phy->reset_delay_us = 100; + phy->addr = 1; + phy->autoneg_mask = AUTONEG_ADVERTISE_SPEED_DEFAULT; + phy->reset_delay_us = 100; - phy->ops.check_reset_block = e1000_check_reset_block_generic; - phy->ops.reset = e1000_phy_hw_reset_generic; - phy->ops.set_d0_lplu_state = e1000_set_d0_lplu_state_82571; - phy->ops.set_d3_lplu_state = e1000_set_d3_lplu_state_generic; - phy->ops.power_up = e1000_power_up_phy_copper; - phy->ops.power_down = e1000_power_down_phy_copper_82571; + phy->ops.check_reset_block = e1000_check_reset_block_generic; + phy->ops.reset = e1000_phy_hw_reset_generic; + phy->ops.set_d0_lplu_state = e1000_set_d0_lplu_state_82571; + phy->ops.set_d3_lplu_state = e1000_set_d3_lplu_state_generic; + phy->ops.power_up = e1000_power_up_phy_copper; + phy->ops.power_down = e1000_power_down_phy_copper_82571; switch (hw->mac.type) { case e1000_82571: case e1000_82572: - phy->type = e1000_phy_igp_2; - phy->ops.get_cfg_done = e1000_get_cfg_done_82571; - phy->ops.get_info = e1000_get_phy_info_igp; - phy->ops.check_polarity = e1000_check_polarity_igp; + phy->type = e1000_phy_igp_2; + phy->ops.get_cfg_done = e1000_get_cfg_done_82571; + phy->ops.get_info = e1000_get_phy_info_igp; + phy->ops.check_polarity = e1000_check_polarity_igp; phy->ops.force_speed_duplex = e1000_phy_force_speed_duplex_igp; - phy->ops.get_cable_length = e1000_get_cable_length_igp_2; - phy->ops.read_reg = e1000_read_phy_reg_igp; - phy->ops.write_reg = e1000_write_phy_reg_igp; - phy->ops.acquire = e1000_get_hw_semaphore_82571; - phy->ops.release = e1000_put_hw_semaphore_82571; + phy->ops.get_cable_length = e1000_get_cable_length_igp_2; + phy->ops.read_reg = e1000_read_phy_reg_igp; + phy->ops.write_reg = e1000_write_phy_reg_igp; + phy->ops.acquire = e1000_get_hw_semaphore_82571; + phy->ops.release = e1000_put_hw_semaphore_82571; break; case e1000_82573: - phy->type = e1000_phy_m88; - phy->ops.get_cfg_done = e1000_get_cfg_done_generic; - phy->ops.get_info = e1000_get_phy_info_m88; - phy->ops.check_polarity = e1000_check_polarity_m88; - phy->ops.commit = e1000_phy_sw_reset_generic; + phy->type = e1000_phy_m88; + phy->ops.get_cfg_done = e1000_get_cfg_done_generic; + phy->ops.get_info = e1000_get_phy_info_m88; + phy->ops.check_polarity = e1000_check_polarity_m88; + phy->ops.commit = e1000_phy_sw_reset_generic; phy->ops.force_speed_duplex = e1000_phy_force_speed_duplex_m88; - phy->ops.get_cable_length = e1000_get_cable_length_m88; - phy->ops.read_reg = e1000_read_phy_reg_m88; - phy->ops.write_reg = e1000_write_phy_reg_m88; - phy->ops.acquire = e1000_get_hw_semaphore_82571; - phy->ops.release = e1000_put_hw_semaphore_82571; + phy->ops.get_cable_length = e1000_get_cable_length_m88; + phy->ops.read_reg = e1000_read_phy_reg_m88; + phy->ops.write_reg = e1000_write_phy_reg_m88; + phy->ops.acquire = e1000_get_hw_semaphore_82571; + phy->ops.release = e1000_put_hw_semaphore_82571; break; case e1000_82574: case e1000_82583: E1000_MUTEX_INIT(&hw->dev_spec._82571.swflag_mutex); - phy->type = e1000_phy_bm; - phy->ops.get_cfg_done = e1000_get_cfg_done_generic; - phy->ops.get_info = e1000_get_phy_info_m88; - phy->ops.check_polarity = e1000_check_polarity_m88; - phy->ops.commit = e1000_phy_sw_reset_generic; + phy->type = e1000_phy_bm; + phy->ops.get_cfg_done = e1000_get_cfg_done_generic; + phy->ops.get_info = e1000_get_phy_info_m88; + phy->ops.check_polarity = e1000_check_polarity_m88; + phy->ops.commit = e1000_phy_sw_reset_generic; phy->ops.force_speed_duplex = e1000_phy_force_speed_duplex_m88; - phy->ops.get_cable_length = e1000_get_cable_length_m88; - phy->ops.read_reg = e1000_read_phy_reg_bm2; - phy->ops.write_reg = e1000_write_phy_reg_bm2; - phy->ops.acquire = e1000_get_hw_semaphore_82574; - phy->ops.release = e1000_put_hw_semaphore_82574; - phy->ops.set_d0_lplu_state = e1000_set_d0_lplu_state_82574; - phy->ops.set_d3_lplu_state = e1000_set_d3_lplu_state_82574; + phy->ops.get_cable_length = e1000_get_cable_length_m88; + phy->ops.read_reg = e1000_read_phy_reg_bm2; + phy->ops.write_reg = e1000_write_phy_reg_bm2; + phy->ops.acquire = e1000_get_hw_semaphore_82574; + phy->ops.release = e1000_put_hw_semaphore_82574; + phy->ops.set_d0_lplu_state = e1000_set_d0_lplu_state_82574; + phy->ops.set_d3_lplu_state = e1000_set_d3_lplu_state_82574; break; default: ret_val = -E1000_ERR_PHY; @@ -253,7 +253,7 @@ static s32 e1000_init_nvm_params_82571(struct e1000_hw *hw) default: nvm->type = e1000_nvm_eeprom_spi; size = (u16)((eecd & E1000_EECD_SIZE_EX_MASK) >> - E1000_EECD_SIZE_EX_SHIFT); + E1000_EECD_SIZE_EX_SHIFT); /* * Added to a constant, "size" becomes the left-shift value * for setting word_size. @@ -263,7 +263,7 @@ static s32 e1000_init_nvm_params_82571(struct e1000_hw *hw) /* EEPROM access above 16k is unsupported */ if (size > 14) size = 14; - nvm->word_size = 1 << size; + nvm->word_size = 1 << size; break; } @@ -279,11 +279,11 @@ static s32 e1000_init_nvm_params_82571(struct e1000_hw *hw) nvm->ops.release = e1000_release_nvm_82571; break; } - nvm->ops.read = e1000_read_nvm_eerd; - nvm->ops.update = e1000_update_nvm_checksum_82571; - nvm->ops.validate = e1000_validate_nvm_checksum_82571; + nvm->ops.read = e1000_read_nvm_eerd; + nvm->ops.update = e1000_update_nvm_checksum_82571; + nvm->ops.validate = e1000_validate_nvm_checksum_82571; nvm->ops.valid_led_default = e1000_valid_led_default_82571; - nvm->ops.write = e1000_write_nvm_82571; + nvm->ops.write = e1000_write_nvm_82571; return E1000_SUCCESS; } @@ -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; @@ -746,8 +745,8 @@ static s32 e1000_set_d3_lplu_state_82574(struct e1000_hw *hw, bool active) if (!active) { data &= ~E1000_PHY_CTRL_NOND0A_LPLU; } else if ((hw->phy.autoneg_advertised == E1000_ALL_SPEED_DUPLEX) || - (hw->phy.autoneg_advertised == E1000_ALL_NOT_GIG) || - (hw->phy.autoneg_advertised == E1000_ALL_10_SPEED)) { + (hw->phy.autoneg_advertised == E1000_ALL_NOT_GIG) || + (hw->phy.autoneg_advertised == E1000_ALL_10_SPEED)) { data |= E1000_PHY_CTRL_NOND0A_LPLU; } @@ -816,7 +815,7 @@ static void e1000_release_nvm_82571(struct e1000_hw *hw) * EEPROM will most likely contain an invalid checksum. **/ static s32 e1000_write_nvm_82571(struct e1000_hw *hw, u16 offset, u16 words, - u16 *data) + u16 *data) { s32 ret_val = E1000_SUCCESS; @@ -941,7 +940,7 @@ static s32 e1000_validate_nvm_checksum_82571(struct e1000_hw *hw) * EEPROM will most likely contain an invalid checksum. **/ static s32 e1000_write_nvm_eewr_82571(struct e1000_hw *hw, u16 offset, - u16 words, u16 *data) + u16 words, u16 *data) { struct e1000_nvm_info *nvm = &hw->nvm; u32 i, eewr = 0; @@ -1039,22 +1038,22 @@ static s32 e1000_set_d0_lplu_state_82571(struct e1000_hw *hw, bool active) if (active) { data |= IGP02E1000_PM_D0_LPLU; ret_val = phy->ops.write_reg(hw, IGP02E1000_PHY_POWER_MGMT, - data); + data); if (ret_val) goto out; /* When LPLU is enabled, we should disable SmartSpeed */ ret_val = phy->ops.read_reg(hw, IGP01E1000_PHY_PORT_CONFIG, - &data); + &data); data &= ~IGP01E1000_PSCFR_SMART_SPEED; ret_val = phy->ops.write_reg(hw, IGP01E1000_PHY_PORT_CONFIG, - data); + data); if (ret_val) goto out; } else { data &= ~IGP02E1000_PM_D0_LPLU; ret_val = phy->ops.write_reg(hw, IGP02E1000_PHY_POWER_MGMT, - data); + data); /* * LPLU and SmartSpeed are mutually exclusive. LPLU is used * during Dx states where the power conservation is most @@ -1063,28 +1062,28 @@ static s32 e1000_set_d0_lplu_state_82571(struct e1000_hw *hw, bool active) */ if (phy->smart_speed == e1000_smart_speed_on) { ret_val = phy->ops.read_reg(hw, - IGP01E1000_PHY_PORT_CONFIG, - &data); + IGP01E1000_PHY_PORT_CONFIG, + &data); if (ret_val) goto out; data |= IGP01E1000_PSCFR_SMART_SPEED; ret_val = phy->ops.write_reg(hw, - IGP01E1000_PHY_PORT_CONFIG, - data); + IGP01E1000_PHY_PORT_CONFIG, + data); if (ret_val) goto out; } else if (phy->smart_speed == e1000_smart_speed_off) { ret_val = phy->ops.read_reg(hw, - IGP01E1000_PHY_PORT_CONFIG, - &data); + IGP01E1000_PHY_PORT_CONFIG, + &data); if (ret_val) goto out; data &= ~IGP01E1000_PSCFR_SMART_SPEED; ret_val = phy->ops.write_reg(hw, - IGP01E1000_PHY_PORT_CONFIG, - data); + IGP01E1000_PHY_PORT_CONFIG, + data); if (ret_val) goto out; } @@ -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. */ @@ -1273,8 +1271,8 @@ static s32 e1000_init_hw_82571(struct e1000_hw *hw) default: reg_data = E1000_READ_REG(hw, E1000_TXDCTL(1)); 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(1), reg_data); break; } @@ -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; } @@ -1527,12 +1529,12 @@ bool e1000_check_phy_82574(struct e1000_hw *hw) * read the Base1000T status register If both are max then PHY is hung. */ ret_val = hw->phy.ops.read_reg(hw, E1000_RECEIVE_ERROR_COUNTER, - &receive_errors); + &receive_errors); if (ret_val) goto out; if (receive_errors == E1000_RECEIVE_ERROR_MAX) { ret_val = hw->phy.ops.read_reg(hw, E1000_BASE1000T_STATUS, - &status_1kbt); + &status_1kbt); if (ret_val) goto out; if ((status_1kbt & E1000_IDLE_ERROR_COUNT_MASK) == @@ -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) * **/ @@ -1763,7 +1766,7 @@ static s32 e1000_check_for_serdes_link_82571(struct e1000_hw *hw) break; } mac->serdes_link_state = - e1000_serdes_link_forced_up; + e1000_serdes_link_forced_up; mac->serdes_has_link = TRUE; DEBUGOUT("AN_PROG -> FORCED_UP\n"); } @@ -1777,10 +1780,10 @@ 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; + e1000_serdes_link_autoneg_progress; mac->serdes_has_link = FALSE; DEBUGOUT("DOWN -> AN_PROG\n"); break; @@ -1804,7 +1807,7 @@ static s32 e1000_check_for_serdes_link_82571(struct e1000_hw *hw) (rxcw & E1000_RXCW_C))) { mac->serdes_has_link = FALSE; mac->serdes_link_state = - e1000_serdes_link_down; + e1000_serdes_link_down; DEBUGOUT("ANYSTATE -> DOWN\n"); break; } @@ -1815,7 +1818,7 @@ static s32 e1000_check_for_serdes_link_82571(struct e1000_hw *hw) txcw |= E1000_TXCW_ANE; E1000_WRITE_REG(hw, E1000_TXCW, txcw); mac->serdes_link_state = - e1000_serdes_link_autoneg_progress; + e1000_serdes_link_autoneg_progress; mac->serdes_has_link = FALSE; DEBUGOUT("ANYSTATE -> AN_PROG\n"); } @@ -1904,8 +1907,8 @@ 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.rar_entry_count - 1); + hw->mac.ops.rar_set(hw, hw->mac.addr, + hw->mac.rar_entry_count - 1); return; } diff --git a/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_82571.h b/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_82571.h index c7ec58bdd3f..c76f16fe179 100644 --- a/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_82571.h +++ b/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_82571.h @@ -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_ diff --git a/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_82575.c b/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_82575.c index 5a6840176ca..a04e3fad22f 100644 --- a/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_82575.c +++ b/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_82575.c @@ -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_82575.c,v 1.4.2.3.2.1 2010/12/21 17:09:25 kensmith Exp $*/ +/*$FreeBSD$*/ /* * 82575EB Gigabit Network Connection @@ -38,9 +38,12 @@ * 82575GB Gigabit Network Connection * 82576 Gigabit Network Connection * 82576 Quad Port Gigabit Mezzanine Adapter + * 82580 Gigabit Network Connection + * I350 Gigabit Network Connection */ #include "e1000_api.h" +#include "e1000_i210.h" static s32 e1000_init_phy_params_82575(struct e1000_hw *hw); static s32 e1000_init_mac_params_82575(struct e1000_hw *hw); @@ -51,32 +54,34 @@ static void e1000_release_nvm_82575(struct e1000_hw *hw); static s32 e1000_check_for_link_82575(struct e1000_hw *hw); static s32 e1000_get_cfg_done_82575(struct e1000_hw *hw); static s32 e1000_get_link_up_info_82575(struct e1000_hw *hw, u16 *speed, - u16 *duplex); + u16 *duplex); static s32 e1000_init_hw_82575(struct e1000_hw *hw); static s32 e1000_phy_hw_reset_sgmii_82575(struct e1000_hw *hw); static s32 e1000_read_phy_reg_sgmii_82575(struct e1000_hw *hw, u32 offset, - u16 *data); + u16 *data); static s32 e1000_reset_hw_82575(struct e1000_hw *hw); static s32 e1000_reset_hw_82580(struct e1000_hw *hw); static s32 e1000_read_phy_reg_82580(struct e1000_hw *hw, - u32 offset, u16 *data); + u32 offset, u16 *data); static s32 e1000_write_phy_reg_82580(struct e1000_hw *hw, - u32 offset, u16 data); + u32 offset, u16 data); static s32 e1000_set_d0_lplu_state_82580(struct e1000_hw *hw, - bool active); + bool active); static s32 e1000_set_d3_lplu_state_82580(struct e1000_hw *hw, - bool active); + bool active); static s32 e1000_set_d0_lplu_state_82575(struct e1000_hw *hw, - bool active); + bool active); static s32 e1000_setup_copper_link_82575(struct e1000_hw *hw); static s32 e1000_setup_serdes_link_82575(struct e1000_hw *hw); +static s32 e1000_get_media_type_82575(struct e1000_hw *hw); +static s32 e1000_set_sfp_media_type_82575(struct e1000_hw *hw); static s32 e1000_valid_led_default_82575(struct e1000_hw *hw, u16 *data); static s32 e1000_write_phy_reg_sgmii_82575(struct e1000_hw *hw, - u32 offset, u16 data); + u32 offset, u16 data); static void e1000_clear_hw_cntrs_82575(struct e1000_hw *hw); static s32 e1000_acquire_swfw_sync_82575(struct e1000_hw *hw, u16 mask); static s32 e1000_get_pcs_speed_and_duplex_82575(struct e1000_hw *hw, - u16 *speed, u16 *duplex); + u16 *speed, u16 *duplex); static s32 e1000_get_phy_id_82575(struct e1000_hw *hw); static void e1000_release_swfw_sync_82575(struct e1000_hw *hw, u16 mask); static bool e1000_sgmii_active_82575(struct e1000_hw *hw); @@ -91,15 +96,28 @@ static s32 e1000_reset_mdicnfg_82580(struct e1000_hw *hw); static s32 e1000_validate_nvm_checksum_82580(struct e1000_hw *hw); static s32 e1000_update_nvm_checksum_82580(struct e1000_hw *hw); static s32 e1000_update_nvm_checksum_with_offset(struct e1000_hw *hw, - u16 offset); + u16 offset); static s32 e1000_validate_nvm_checksum_with_offset(struct e1000_hw *hw, - u16 offset); + u16 offset); static s32 e1000_validate_nvm_checksum_i350(struct e1000_hw *hw); static s32 e1000_update_nvm_checksum_i350(struct e1000_hw *hw); - -static const u16 e1000_82580_rxpbs_table[] = - { 36, 72, 144, 1, 2, 4, 8, 16, - 35, 70, 140 }; +static void e1000_write_vfta_i350(struct e1000_hw *hw, u32 offset, u32 value); +static void e1000_clear_vfta_i350(struct e1000_hw *hw); + +static void e1000_i2c_start(struct e1000_hw *hw); +static void e1000_i2c_stop(struct e1000_hw *hw); +static s32 e1000_clock_in_i2c_byte(struct e1000_hw *hw, u8 *data); +static s32 e1000_clock_out_i2c_byte(struct e1000_hw *hw, u8 data); +static s32 e1000_get_i2c_ack(struct e1000_hw *hw); +static s32 e1000_clock_in_i2c_bit(struct e1000_hw *hw, bool *data); +static s32 e1000_clock_out_i2c_bit(struct e1000_hw *hw, bool data); +static void e1000_raise_i2c_clk(struct e1000_hw *hw, u32 *i2cctl); +static void e1000_lower_i2c_clk(struct e1000_hw *hw, u32 *i2cctl); +static s32 e1000_set_i2c_data(struct e1000_hw *hw, u32 *i2cctl, bool data); +static bool e1000_get_i2c_data(u32 *i2cctl); + +static const u16 e1000_82580_rxpbs_table[] = { + 36, 72, 144, 1, 2, 4, 8, 16, 35, 70, 140 }; #define E1000_82580_RXPBS_TABLE_SIZE \ (sizeof(e1000_82580_rxpbs_table)/sizeof(u16)) @@ -147,6 +165,9 @@ static s32 e1000_init_phy_params_82575(struct e1000_hw *hw) DEBUGFUNC("e1000_init_phy_params_82575"); + phy->ops.read_i2c_byte = e1000_read_i2c_byte_generic; + phy->ops.write_i2c_byte = e1000_write_i2c_byte_generic; + if (hw->phy.media_type != e1000_media_type_copper) { phy->type = e1000_phy_none; goto out; @@ -155,22 +176,22 @@ static s32 e1000_init_phy_params_82575(struct e1000_hw *hw) phy->ops.power_up = e1000_power_up_phy_copper; phy->ops.power_down = e1000_power_down_phy_copper_82575; - phy->autoneg_mask = AUTONEG_ADVERTISE_SPEED_DEFAULT; - phy->reset_delay_us = 100; + phy->autoneg_mask = AUTONEG_ADVERTISE_SPEED_DEFAULT; + phy->reset_delay_us = 100; - phy->ops.acquire = e1000_acquire_phy_82575; - phy->ops.check_reset_block = e1000_check_reset_block_generic; - phy->ops.commit = e1000_phy_sw_reset_generic; - phy->ops.get_cfg_done = e1000_get_cfg_done_82575; - phy->ops.release = e1000_release_phy_82575; + phy->ops.acquire = e1000_acquire_phy_82575; + phy->ops.check_reset_block = e1000_check_reset_block_generic; + phy->ops.commit = e1000_phy_sw_reset_generic; + phy->ops.get_cfg_done = e1000_get_cfg_done_82575; + phy->ops.release = e1000_release_phy_82575; ctrl_ext = E1000_READ_REG(hw, E1000_CTRL_EXT); if (e1000_sgmii_active_82575(hw)) { - phy->ops.reset = e1000_phy_hw_reset_sgmii_82575; + phy->ops.reset = e1000_phy_hw_reset_sgmii_82575; ctrl_ext |= E1000_CTRL_I2C_ENA; } else { - phy->ops.reset = e1000_phy_hw_reset_generic; + phy->ops.reset = e1000_phy_hw_reset_generic; ctrl_ext &= ~E1000_CTRL_I2C_ENA; } @@ -178,14 +199,24 @@ static s32 e1000_init_phy_params_82575(struct e1000_hw *hw) e1000_reset_mdicnfg_82580(hw); if (e1000_sgmii_active_82575(hw) && !e1000_sgmii_uses_mdio_82575(hw)) { - phy->ops.read_reg = e1000_read_phy_reg_sgmii_82575; - phy->ops.write_reg = e1000_write_phy_reg_sgmii_82575; - } else if (hw->mac.type >= e1000_82580) { - phy->ops.read_reg = e1000_read_phy_reg_82580; - phy->ops.write_reg = e1000_write_phy_reg_82580; + phy->ops.read_reg = e1000_read_phy_reg_sgmii_82575; + phy->ops.write_reg = e1000_write_phy_reg_sgmii_82575; } else { - phy->ops.read_reg = e1000_read_phy_reg_igp; - phy->ops.write_reg = e1000_write_phy_reg_igp; + switch (hw->mac.type) { + case e1000_82580: + case e1000_i350: + phy->ops.read_reg = e1000_read_phy_reg_82580; + phy->ops.write_reg = e1000_write_phy_reg_82580; + break; + case e1000_i210: + case e1000_i211: + phy->ops.read_reg = e1000_read_phy_reg_gs40g; + phy->ops.write_reg = e1000_write_phy_reg_gs40g; + break; + default: + phy->ops.read_reg = e1000_read_phy_reg_igp; + phy->ops.write_reg = e1000_write_phy_reg_igp; + } } /* Set phy->phy_addr and phy->id. */ @@ -197,36 +228,47 @@ static s32 e1000_init_phy_params_82575(struct e1000_hw *hw) case M88E1112_E_PHY_ID: case M88E1340M_E_PHY_ID: case M88E1111_I_PHY_ID: - phy->type = e1000_phy_m88; - phy->ops.check_polarity = e1000_check_polarity_m88; - phy->ops.get_info = e1000_get_phy_info_m88; + phy->type = e1000_phy_m88; + phy->ops.check_polarity = e1000_check_polarity_m88; + phy->ops.get_info = e1000_get_phy_info_m88; if (phy->id == I347AT4_E_PHY_ID || phy->id == M88E1112_E_PHY_ID || phy->id == M88E1340M_E_PHY_ID) - phy->ops.get_cable_length = e1000_get_cable_length_m88_gen2; + phy->ops.get_cable_length = + e1000_get_cable_length_m88_gen2; else phy->ops.get_cable_length = e1000_get_cable_length_m88; phy->ops.force_speed_duplex = e1000_phy_force_speed_duplex_m88; break; case IGP03E1000_E_PHY_ID: case IGP04E1000_E_PHY_ID: - phy->type = e1000_phy_igp_3; - phy->ops.check_polarity = e1000_check_polarity_igp; - phy->ops.get_info = e1000_get_phy_info_igp; - phy->ops.get_cable_length = e1000_get_cable_length_igp_2; + phy->type = e1000_phy_igp_3; + phy->ops.check_polarity = e1000_check_polarity_igp; + phy->ops.get_info = e1000_get_phy_info_igp; + phy->ops.get_cable_length = e1000_get_cable_length_igp_2; phy->ops.force_speed_duplex = e1000_phy_force_speed_duplex_igp; - phy->ops.set_d0_lplu_state = e1000_set_d0_lplu_state_82575; - phy->ops.set_d3_lplu_state = e1000_set_d3_lplu_state_generic; + phy->ops.set_d0_lplu_state = e1000_set_d0_lplu_state_82575; + phy->ops.set_d3_lplu_state = e1000_set_d3_lplu_state_generic; break; case I82580_I_PHY_ID: case I350_I_PHY_ID: - phy->type = e1000_phy_82580; - phy->ops.check_polarity = e1000_check_polarity_82577; - phy->ops.force_speed_duplex = e1000_phy_force_speed_duplex_82577; - phy->ops.get_cable_length = e1000_get_cable_length_82577; - phy->ops.get_info = e1000_get_phy_info_82577; - phy->ops.set_d0_lplu_state = e1000_set_d0_lplu_state_82580; - phy->ops.set_d3_lplu_state = e1000_set_d3_lplu_state_82580; + phy->type = e1000_phy_82580; + phy->ops.check_polarity = e1000_check_polarity_82577; + phy->ops.force_speed_duplex = + e1000_phy_force_speed_duplex_82577; + phy->ops.get_cable_length = e1000_get_cable_length_82577; + phy->ops.get_info = e1000_get_phy_info_82577; + phy->ops.set_d0_lplu_state = e1000_set_d0_lplu_state_82580; + phy->ops.set_d3_lplu_state = e1000_set_d3_lplu_state_82580; + break; + case I210_I_PHY_ID: + phy->type = e1000_phy_i210; + phy->ops.check_polarity = e1000_check_polarity_m88; + phy->ops.get_info = e1000_get_phy_info_m88; + phy->ops.get_cable_length = e1000_get_cable_length_m88_gen2; + phy->ops.set_d0_lplu_state = e1000_set_d0_lplu_state_82580; + phy->ops.set_d3_lplu_state = e1000_set_d3_lplu_state_82580; + phy->ops.force_speed_duplex = e1000_phy_force_speed_duplex_m88; break; default: ret_val = -E1000_ERR_PHY; @@ -250,50 +292,60 @@ s32 e1000_init_nvm_params_82575(struct e1000_hw *hw) DEBUGFUNC("e1000_init_nvm_params_82575"); size = (u16)((eecd & E1000_EECD_SIZE_EX_MASK) >> - E1000_EECD_SIZE_EX_SHIFT); + E1000_EECD_SIZE_EX_SHIFT); /* * Added to a constant, "size" becomes the left-shift value * for setting word_size. */ size += NVM_WORD_SIZE_BASE_SHIFT; - nvm->word_size = 1 << size; - nvm->opcode_bits = 8; - nvm->delay_usec = 1; - switch (nvm->override) { - case e1000_nvm_override_spi_large: - nvm->page_size = 32; - nvm->address_bits = 16; - break; - case e1000_nvm_override_spi_small: - nvm->page_size = 8; - nvm->address_bits = 8; - break; - default: - nvm->page_size = eecd & E1000_EECD_ADDR_BITS ? 32 : 8; - nvm->address_bits = eecd & E1000_EECD_ADDR_BITS ? 16 : 8; - break; - } - - nvm->type = e1000_nvm_eeprom_spi; + /* Just in case size is out of range, cap it to the largest + * EEPROM size supported + */ + if (size > 15) + size = 15; - if (nvm->word_size == (1 << 15)) - nvm->page_size = 128; + nvm->word_size = 1 << size; + if (hw->mac.type < e1000_i210) { + nvm->opcode_bits = 8; + nvm->delay_usec = 1; + + switch (nvm->override) { + case e1000_nvm_override_spi_large: + nvm->page_size = 32; + nvm->address_bits = 16; + break; + case e1000_nvm_override_spi_small: + nvm->page_size = 8; + nvm->address_bits = 8; + break; + default: + nvm->page_size = eecd & E1000_EECD_ADDR_BITS ? 32 : 8; + nvm->address_bits = eecd & E1000_EECD_ADDR_BITS ? + 16 : 8; + break; + } + if (nvm->word_size == (1 << 15)) + nvm->page_size = 128; + nvm->type = e1000_nvm_eeprom_spi; + } else { + nvm->type = e1000_nvm_flash_hw; + } /* Function Pointers */ - nvm->ops.acquire = e1000_acquire_nvm_82575; - nvm->ops.release = e1000_release_nvm_82575; + nvm->ops.acquire = e1000_acquire_nvm_82575; + nvm->ops.release = e1000_release_nvm_82575; if (nvm->word_size < (1 << 15)) - nvm->ops.read = e1000_read_nvm_eerd; + nvm->ops.read = e1000_read_nvm_eerd; else - nvm->ops.read = e1000_read_nvm_spi; + nvm->ops.read = e1000_read_nvm_spi; - nvm->ops.write = e1000_write_nvm_spi; - nvm->ops.validate = e1000_validate_nvm_checksum_generic; - nvm->ops.update = e1000_update_nvm_checksum_generic; - nvm->ops.valid_led_default = e1000_valid_led_default_82575; + nvm->ops.write = e1000_write_nvm_spi; + nvm->ops.validate = e1000_validate_nvm_checksum_generic; + nvm->ops.update = e1000_update_nvm_checksum_generic; + nvm->ops.valid_led_default = e1000_valid_led_default_82575; - /* override genric family function pointers for specific descendants */ + /* override generic family function pointers for specific descendants */ switch (hw->mac.type) { case e1000_82580: nvm->ops.validate = e1000_validate_nvm_checksum_82580; @@ -318,34 +370,11 @@ static s32 e1000_init_mac_params_82575(struct e1000_hw *hw) { struct e1000_mac_info *mac = &hw->mac; struct e1000_dev_spec_82575 *dev_spec = &hw->dev_spec._82575; - u32 ctrl_ext = 0; DEBUGFUNC("e1000_init_mac_params_82575"); - /* Set media type */ - /* - * The 82575 uses bits 22:23 for link mode. The mode can be changed - * based on the EEPROM. We cannot rely upon device ID. There - * is no distinguishable difference between fiber and internal - * SerDes mode on the 82575. There can be an external PHY attached - * on the SGMII interface. For this, we'll set sgmii_active to TRUE. - */ - hw->phy.media_type = e1000_media_type_copper; - dev_spec->sgmii_active = FALSE; - - ctrl_ext = E1000_READ_REG(hw, E1000_CTRL_EXT); - switch (ctrl_ext & E1000_CTRL_EXT_LINK_MODE_MASK) { - case E1000_CTRL_EXT_LINK_MODE_SGMII: - dev_spec->sgmii_active = TRUE; - break; - case E1000_CTRL_EXT_LINK_MODE_1000BASE_KX: - case E1000_CTRL_EXT_LINK_MODE_PCIE_SERDES: - hw->phy.media_type = e1000_media_type_internal_serdes; - break; - default: - break; - } - + /* Derives media type */ + e1000_get_media_type_82575(hw); /* Set mta register count */ mac->mta_reg_count = 128; /* Set uta register count */ @@ -368,8 +397,7 @@ static s32 e1000_init_mac_params_82575(struct e1000_hw *hw) 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; + !!(E1000_READ_REG(hw, E1000_FWSM) & E1000_FWSM_MODE_MASK); /* Function pointers */ @@ -386,27 +414,31 @@ static s32 e1000_init_mac_params_82575(struct e1000_hw *hw) mac->ops.setup_link = e1000_setup_link_generic; /* physical interface link setup */ mac->ops.setup_physical_interface = - (hw->phy.media_type == e1000_media_type_copper) - ? e1000_setup_copper_link_82575 - : e1000_setup_serdes_link_82575; + (hw->phy.media_type == e1000_media_type_copper) + ? e1000_setup_copper_link_82575 : e1000_setup_serdes_link_82575; /* physical interface shutdown */ mac->ops.shutdown_serdes = e1000_shutdown_serdes_link_82575; /* physical interface power up */ mac->ops.power_up_serdes = e1000_power_up_serdes_link_82575; /* check for link */ mac->ops.check_for_link = e1000_check_for_link_82575; - /* receive address register setting */ - mac->ops.rar_set = e1000_rar_set_generic; /* read mac address */ mac->ops.read_mac_addr = e1000_read_mac_addr_82575; /* configure collision distance */ mac->ops.config_collision_dist = e1000_config_collision_dist_82575; /* multicast address update */ mac->ops.update_mc_addr_list = e1000_update_mc_addr_list_generic; - /* writing VFTA */ - mac->ops.write_vfta = e1000_write_vfta_generic; - /* clearing VFTA */ - mac->ops.clear_vfta = e1000_clear_vfta_generic; + if (hw->mac.type == e1000_i350) { + /* writing VFTA */ + mac->ops.write_vfta = e1000_write_vfta_i350; + /* clearing VFTA */ + mac->ops.clear_vfta = e1000_clear_vfta_i350; + } else { + /* writing VFTA */ + mac->ops.write_vfta = e1000_write_vfta_generic; + /* clearing VFTA */ + mac->ops.clear_vfta = e1000_clear_vfta_generic; + } /* ID LED init */ mac->ops.id_led_init = e1000_id_led_init_generic; /* blink LED */ @@ -422,6 +454,13 @@ static s32 e1000_init_mac_params_82575(struct e1000_hw *hw) mac->ops.clear_hw_cntrs = e1000_clear_hw_cntrs_82575; /* link info */ mac->ops.get_link_up_info = e1000_get_link_up_info_82575; + /* acquire SW_FW sync */ + mac->ops.acquire_swfw_sync = e1000_acquire_swfw_sync_82575; + mac->ops.release_swfw_sync = e1000_release_swfw_sync_82575; + if (mac->type >= e1000_i210) { + mac->ops.acquire_swfw_sync = e1000_acquire_swfw_sync_i210; + mac->ops.release_swfw_sync = e1000_release_swfw_sync_i210; + } /* set lan id for port to determine which phy lock to use */ hw->mac.ops.set_lan_id(hw); @@ -464,7 +503,7 @@ static s32 e1000_acquire_phy_82575(struct e1000_hw *hw) else if (hw->bus.func == E1000_FUNC_3) mask = E1000_SWFW_PHY3_SM; - return e1000_acquire_swfw_sync_82575(hw, mask); + return hw->mac.ops.acquire_swfw_sync(hw, mask); } /** @@ -486,7 +525,7 @@ static void e1000_release_phy_82575(struct e1000_hw *hw) else if (hw->bus.func == E1000_FUNC_3) mask = E1000_SWFW_PHY3_SM; - e1000_release_swfw_sync_82575(hw, mask); + hw->mac.ops.release_swfw_sync(hw, mask); } /** @@ -499,7 +538,7 @@ static void e1000_release_phy_82575(struct e1000_hw *hw) * interface and stores the retrieved information in data. **/ static s32 e1000_read_phy_reg_sgmii_82575(struct e1000_hw *hw, u32 offset, - u16 *data) + u16 *data) { s32 ret_val = -E1000_ERR_PARAM; @@ -532,7 +571,7 @@ static s32 e1000_read_phy_reg_sgmii_82575(struct e1000_hw *hw, u32 offset, * media independent interface. **/ static s32 e1000_write_phy_reg_sgmii_82575(struct e1000_hw *hw, u32 offset, - u16 data) + u16 data) { s32 ret_val = -E1000_ERR_PARAM; @@ -611,7 +650,7 @@ static s32 e1000_get_phy_id_82575(struct e1000_hw *hw) /* Power on sgmii phy if it is disabled */ ctrl_ext = E1000_READ_REG(hw, E1000_CTRL_EXT); E1000_WRITE_REG(hw, E1000_CTRL_EXT, - ctrl_ext & ~E1000_CTRL_EXT_SDP3_DATA); + ctrl_ext & ~E1000_CTRL_EXT_SDP3_DATA); E1000_WRITE_FLUSH(hw); msec_delay(300); @@ -623,8 +662,7 @@ static s32 e1000_get_phy_id_82575(struct e1000_hw *hw) ret_val = e1000_read_phy_reg_sgmii_82575(hw, PHY_ID1, &phy_id); if (ret_val == E1000_SUCCESS) { DEBUGOUT2("Vendor ID 0x%08X read at address %u\n", - phy_id, - phy->addr); + phy_id, phy->addr); /* * At the time of this writing, The M88 part is * the only supported SGMII PHY product. @@ -633,7 +671,7 @@ static s32 e1000_get_phy_id_82575(struct e1000_hw *hw) break; } else { DEBUGOUT1("PHY address %u was unreadable\n", - phy->addr); + phy->addr); } } @@ -719,22 +757,22 @@ static s32 e1000_set_d0_lplu_state_82575(struct e1000_hw *hw, bool active) if (active) { data |= IGP02E1000_PM_D0_LPLU; ret_val = phy->ops.write_reg(hw, IGP02E1000_PHY_POWER_MGMT, - data); + data); if (ret_val) goto out; /* When LPLU is enabled, we should disable SmartSpeed */ ret_val = phy->ops.read_reg(hw, IGP01E1000_PHY_PORT_CONFIG, - &data); + &data); data &= ~IGP01E1000_PSCFR_SMART_SPEED; ret_val = phy->ops.write_reg(hw, IGP01E1000_PHY_PORT_CONFIG, - data); + data); if (ret_val) goto out; } else { data &= ~IGP02E1000_PM_D0_LPLU; ret_val = phy->ops.write_reg(hw, IGP02E1000_PHY_POWER_MGMT, - data); + data); /* * LPLU and SmartSpeed are mutually exclusive. LPLU is used * during Dx states where the power conservation is most @@ -743,28 +781,28 @@ static s32 e1000_set_d0_lplu_state_82575(struct e1000_hw *hw, bool active) */ if (phy->smart_speed == e1000_smart_speed_on) { ret_val = phy->ops.read_reg(hw, - IGP01E1000_PHY_PORT_CONFIG, - &data); + IGP01E1000_PHY_PORT_CONFIG, + &data); if (ret_val) goto out; data |= IGP01E1000_PSCFR_SMART_SPEED; ret_val = phy->ops.write_reg(hw, - IGP01E1000_PHY_PORT_CONFIG, - data); + IGP01E1000_PHY_PORT_CONFIG, + data); if (ret_val) goto out; } else if (phy->smart_speed == e1000_smart_speed_off) { ret_val = phy->ops.read_reg(hw, - IGP01E1000_PHY_PORT_CONFIG, - &data); + IGP01E1000_PHY_PORT_CONFIG, + &data); if (ret_val) goto out; data &= ~IGP01E1000_PSCFR_SMART_SPEED; ret_val = phy->ops.write_reg(hw, - IGP01E1000_PHY_PORT_CONFIG, - data); + IGP01E1000_PHY_PORT_CONFIG, + data); if (ret_val) goto out; } @@ -791,7 +829,7 @@ static s32 e1000_set_d0_lplu_state_82580(struct e1000_hw *hw, bool active) { struct e1000_phy_info *phy = &hw->phy; s32 ret_val = E1000_SUCCESS; - u16 data; + u32 data; DEBUGFUNC("e1000_set_d0_lplu_state_82580"); @@ -811,11 +849,10 @@ static s32 e1000_set_d0_lplu_state_82580(struct e1000_hw *hw, bool active) * important. During driver activity we should enable * SmartSpeed, so performance is maintained. */ - if (phy->smart_speed == e1000_smart_speed_on) { + if (phy->smart_speed == e1000_smart_speed_on) data |= E1000_82580_PM_SPD; - } else if (phy->smart_speed == e1000_smart_speed_off) { + else if (phy->smart_speed == e1000_smart_speed_off) data &= ~E1000_82580_PM_SPD; - } } E1000_WRITE_REG(hw, E1000_82580_PHY_POWER_MGMT, data); @@ -840,7 +877,7 @@ s32 e1000_set_d3_lplu_state_82580(struct e1000_hw *hw, bool active) { struct e1000_phy_info *phy = &hw->phy; s32 ret_val = E1000_SUCCESS; - u16 data; + u32 data; DEBUGFUNC("e1000_set_d3_lplu_state_82580"); @@ -854,14 +891,13 @@ s32 e1000_set_d3_lplu_state_82580(struct e1000_hw *hw, bool active) * important. During driver activity we should enable * SmartSpeed, so performance is maintained. */ - if (phy->smart_speed == e1000_smart_speed_on) { + if (phy->smart_speed == e1000_smart_speed_on) data |= E1000_82580_PM_SPD; - } else if (phy->smart_speed == e1000_smart_speed_off) { + else if (phy->smart_speed == e1000_smart_speed_off) data &= ~E1000_82580_PM_SPD; - } } else if ((phy->autoneg_advertised == E1000_ALL_SPEED_DUPLEX) || - (phy->autoneg_advertised == E1000_ALL_NOT_GIG) || - (phy->autoneg_advertised == E1000_ALL_10_SPEED)) { + (phy->autoneg_advertised == E1000_ALL_NOT_GIG) || + (phy->autoneg_advertised == E1000_ALL_10_SPEED)) { data |= E1000_82580_PM_D3_LPLU; /* When LPLU is enabled, we should disable SmartSpeed */ data &= ~E1000_82580_PM_SPD; @@ -889,6 +925,32 @@ static s32 e1000_acquire_nvm_82575(struct e1000_hw *hw) ret_val = e1000_acquire_swfw_sync_82575(hw, E1000_SWFW_EEP_SM); if (ret_val) goto out; + + /* + * Check if there is some access + * error this access may hook on + */ + if (hw->mac.type == e1000_i350) { + u32 eecd = E1000_READ_REG(hw, E1000_EECD); + if (eecd & (E1000_EECD_BLOCKED | E1000_EECD_ABORT | + E1000_EECD_TIMEOUT)) { + /* Clear all access error flags */ + E1000_WRITE_REG(hw, E1000_EECD, eecd | + E1000_EECD_ERROR_CLR); + DEBUGOUT("Nvm bit banging access error detected and cleared.\n"); + } + } + if (hw->mac.type == e1000_82580) { + u32 eecd = E1000_READ_REG(hw, E1000_EECD); + if (eecd & E1000_EECD_BLOCKED) { + /* Clear access error flag */ + E1000_WRITE_REG(hw, E1000_EECD, eecd | + E1000_EECD_BLOCKED); + DEBUGOUT("Nvm bit banging access error detected and cleared.\n"); + } + } + + ret_val = e1000_acquire_nvm_generic(hw); if (ret_val) e1000_release_swfw_sync_82575(hw, E1000_SWFW_EEP_SM); @@ -908,6 +970,8 @@ static void e1000_release_nvm_82575(struct e1000_hw *hw) { DEBUGFUNC("e1000_release_nvm_82575"); + e1000_release_nvm_generic(hw); + e1000_release_swfw_sync_82575(hw, E1000_SWFW_EEP_SM); } @@ -977,8 +1041,8 @@ static void e1000_release_swfw_sync_82575(struct e1000_hw *hw, u16 mask) DEBUGFUNC("e1000_release_swfw_sync_82575"); - while (e1000_get_hw_semaphore_generic(hw) != E1000_SUCCESS); - /* Empty */ + while (e1000_get_hw_semaphore_generic(hw) != E1000_SUCCESS) + ; /* Empty */ swfw_sync = E1000_READ_REG(hw, E1000_SW_FW_SYNC); swfw_sync &= ~mask; @@ -1021,7 +1085,7 @@ static s32 e1000_get_cfg_done_82575(struct e1000_hw *hw) DEBUGOUT("MNG configuration cycle has not completed.\n"); /* If EEPROM is not marked present, init the PHY manually */ - if (((E1000_READ_REG(hw, E1000_EECD) & E1000_EECD_PRES) == 0) && + if (!(E1000_READ_REG(hw, E1000_EECD) & E1000_EECD_PRES) && (hw->phy.type == e1000_phy_igp_3)) e1000_phy_init_script_igp3(hw); @@ -1039,7 +1103,7 @@ static s32 e1000_get_cfg_done_82575(struct e1000_hw *hw) * Otherwise, use the generic function to get the link speed and duplex info. **/ static s32 e1000_get_link_up_info_82575(struct e1000_hw *hw, u16 *speed, - u16 *duplex) + u16 *duplex) { s32 ret_val; @@ -1047,10 +1111,10 @@ static s32 e1000_get_link_up_info_82575(struct e1000_hw *hw, u16 *speed, if (hw->phy.media_type != e1000_media_type_copper) ret_val = e1000_get_pcs_speed_and_duplex_82575(hw, speed, - duplex); + duplex); else ret_val = e1000_get_speed_and_duplex_copper_generic(hw, speed, - duplex); + duplex); return ret_val; } @@ -1071,13 +1135,14 @@ static s32 e1000_check_for_link_82575(struct e1000_hw *hw) if (hw->phy.media_type != e1000_media_type_copper) { ret_val = e1000_get_pcs_speed_and_duplex_82575(hw, &speed, - &duplex); + &duplex); /* * Use this flag to determine if link needs to be checked or * not. If we have link clear the flag so that we do not * continue to check for link. */ hw->mac.get_link_status = !hw->mac.serdes_has_link; + } else { ret_val = e1000_check_for_copper_link_generic(hw); } @@ -1124,18 +1189,13 @@ static void e1000_power_up_serdes_link_82575(struct e1000_hw *hw) * duplex, then store the values in the pointers provided. **/ static s32 e1000_get_pcs_speed_and_duplex_82575(struct e1000_hw *hw, - u16 *speed, u16 *duplex) + u16 *speed, u16 *duplex) { struct e1000_mac_info *mac = &hw->mac; u32 pcs; DEBUGFUNC("e1000_get_pcs_speed_and_duplex_82575"); - /* Set up defaults for the return values of this function */ - mac->serdes_has_link = FALSE; - *speed = 0; - *duplex = 0; - /* * Read the PCS Status register for link state. For non-copper mode, * the status register is not accurate. The PCS status register is @@ -1144,28 +1204,28 @@ static s32 e1000_get_pcs_speed_and_duplex_82575(struct e1000_hw *hw, pcs = E1000_READ_REG(hw, E1000_PCS_LSTAT); /* - * The link up bit determines when link is up on autoneg. The sync ok - * gets set once both sides sync up and agree upon link. Stable link - * can be determined by checking for both link up and link sync ok + * The link up bit determines when link is up on autoneg. */ - if ((pcs & E1000_PCS_LSTS_LINK_OK) && (pcs & E1000_PCS_LSTS_SYNK_OK)) { + if (pcs & E1000_PCS_LSTS_LINK_OK) { mac->serdes_has_link = TRUE; /* Detect and store PCS speed */ - if (pcs & E1000_PCS_LSTS_SPEED_1000) { + if (pcs & E1000_PCS_LSTS_SPEED_1000) *speed = SPEED_1000; - } else if (pcs & E1000_PCS_LSTS_SPEED_100) { + else if (pcs & E1000_PCS_LSTS_SPEED_100) *speed = SPEED_100; - } else { + else *speed = SPEED_10; - } /* Detect and store PCS duplex */ - if (pcs & E1000_PCS_LSTS_DUPLEX_FULL) { + if (pcs & E1000_PCS_LSTS_DUPLEX_FULL) *duplex = FULL_DUPLEX; - } else { + else *duplex = HALF_DUPLEX; - } + } else { + mac->serdes_has_link = FALSE; + *speed = 0; + *duplex = 0; } return E1000_SUCCESS; @@ -1225,15 +1285,13 @@ static s32 e1000_reset_hw_82575(struct e1000_hw *hw) * on the last TLP read/write transaction when MAC is reset. */ ret_val = e1000_disable_pcie_master_generic(hw); - if (ret_val) { + if (ret_val) DEBUGOUT("PCI-E Master disable polling has failed.\n"); - } /* set the completion timeout for interface */ ret_val = e1000_set_pcie_completion_timeout(hw); - if (ret_val) { + if (ret_val) DEBUGOUT("PCI-E Set completion timeout has failed.\n"); - } DEBUGOUT("Masking off all interrupts\n"); E1000_WRITE_REG(hw, E1000_IMC, 0xffffffff); @@ -1260,7 +1318,7 @@ static s32 e1000_reset_hw_82575(struct e1000_hw *hw) } /* If EEPROM is not present, run manual init scripts */ - if ((E1000_READ_REG(hw, E1000_EECD) & E1000_EECD_PRES) == 0) + if (!(E1000_READ_REG(hw, E1000_EECD) & E1000_EECD_PRES)) e1000_reset_init_script_82575(hw); /* Clear any pending interrupt events. */ @@ -1314,6 +1372,9 @@ static s32 e1000_init_hw_82575(struct e1000_hw *hw) /* Setup link and flow control */ ret_val = mac->ops.setup_link(hw); + /* Set the default MTU size */ + hw->dev_spec._82575.mtu = 1500; + /* * Clear all of the statistics registers (clear on read). It is * important that we do this after we have tried to establish link @@ -1349,7 +1410,7 @@ static s32 e1000_setup_copper_link_82575(struct e1000_hw *hw) if (ret_val) goto out; - if (e1000_sgmii_active_82575(hw) && !hw->phy.reset_disable) { + if (e1000_sgmii_active_82575(hw)) { /* allow time for SFP cage time to power up phy */ msec_delay(300); @@ -1360,6 +1421,7 @@ static s32 e1000_setup_copper_link_82575(struct e1000_hw *hw) } } switch (hw->phy.type) { + case e1000_phy_i210: case e1000_phy_m88: if (hw->phy.id == I347AT4_E_PHY_ID || hw->phy.id == M88E1112_E_PHY_ID || @@ -1400,12 +1462,14 @@ static s32 e1000_setup_serdes_link_82575(struct e1000_hw *hw) { u32 ctrl_ext, ctrl_reg, reg; bool pcs_autoneg; + s32 ret_val = E1000_SUCCESS; + u16 data; DEBUGFUNC("e1000_setup_serdes_link_82575"); if ((hw->phy.media_type != e1000_media_type_internal_serdes) && !e1000_sgmii_active_82575(hw)) - return E1000_SUCCESS; + return ret_val; /* * On the 82575, SerDes loopback mode persists until it is @@ -1444,13 +1508,25 @@ static s32 e1000_setup_serdes_link_82575(struct e1000_hw *hw) pcs_autoneg = FALSE; /* fall through to default case */ default: + if (hw->mac.type == e1000_82575 || + hw->mac.type == e1000_82576) { + ret_val = hw->nvm.ops.read(hw, NVM_COMPAT, 1, &data); + if (ret_val) { + DEBUGOUT("NVM Read Error\n"); + return ret_val; + } + + if (data & E1000_EEPROM_PCS_AUTONEG_DISABLE_BIT) + pcs_autoneg = FALSE; + } + /* * non-SGMII modes only supports a speed of 1000/Full for the * link so it is best to just force the MAC and let the pcs * link either autoneg or be forced to 1000/Full */ ctrl_reg |= E1000_CTRL_SPD_1000 | E1000_CTRL_FRCSPD | - E1000_CTRL_FD | E1000_CTRL_FRCDPX; + E1000_CTRL_FD | E1000_CTRL_FRCDPX; /* set speed of 1000/Full if speed/duplex is forced */ reg |= E1000_PCS_LCTL_FSV_1000 | E1000_PCS_LCTL_FDV_FULL; @@ -1466,7 +1542,7 @@ static s32 e1000_setup_serdes_link_82575(struct e1000_hw *hw) * However, both are supported by the hardware and some drivers/tools. */ reg &= ~(E1000_PCS_LCTL_AN_ENABLE | E1000_PCS_LCTL_FLV_LINK_UP | - E1000_PCS_LCTL_FSD | E1000_PCS_LCTL_FORCE_LINK); + E1000_PCS_LCTL_FSD | E1000_PCS_LCTL_FORCE_LINK); /* * We force flow control to prevent the CTRL register values from being @@ -1481,7 +1557,7 @@ static s32 e1000_setup_serdes_link_82575(struct e1000_hw *hw) DEBUGOUT1("Configuring Autoneg:PCS_LCTL=0x%08X\n", reg); } else { /* Set PCS register for forced link */ - reg |= E1000_PCS_LCTL_FSD; /* Force Speed */ + reg |= E1000_PCS_LCTL_FSD; /* Force Speed */ DEBUGOUT1("Configuring Forced Link:PCS_LCTL=0x%08X\n", reg); } @@ -1490,7 +1566,213 @@ static s32 e1000_setup_serdes_link_82575(struct e1000_hw *hw) if (!e1000_sgmii_active_82575(hw)) e1000_force_mac_fc_generic(hw); - return E1000_SUCCESS; + return ret_val; +} + +/** + * e1000_get_media_type_82575 - derives current media type. + * @hw: pointer to the HW structure + * + * The media type is chosen reflecting few settings. + * The following are taken into account: + * - link mode set in the current port Init Control Word #3 + * - current link mode settings in CSR register + * - MDIO vs. I2C PHY control interface chosen + * - SFP module media type + **/ +static s32 e1000_get_media_type_82575(struct e1000_hw *hw) +{ + u32 lan_id = 0; + s32 ret_val = E1000_ERR_CONFIG; + struct e1000_dev_spec_82575 *dev_spec = &hw->dev_spec._82575; + u32 ctrl_ext = 0; + u32 current_link_mode = 0; + u16 init_ctrl_wd_3 = 0; + u8 init_ctrl_wd_3_offset = 0; + u8 init_ctrl_wd_3_bit_offset = 0; + + /* Set internal phy as default */ + dev_spec->sgmii_active = FALSE; + dev_spec->module_plugged = FALSE; + + /* + * Check if NVM access method is attached already. + * If it is then Init Control Word #3 is considered + * otherwise runtime CSR register content is taken. + */ + + /* Get CSR setting */ + ctrl_ext = E1000_READ_REG(hw, E1000_CTRL_EXT); + + /* Get link mode setting */ + if ((hw->nvm.ops.read) && (hw->nvm.ops.read != e1000_null_read_nvm)) { + /* Take link mode from EEPROM */ + + /* + * Get LAN port ID to derive its + * adequate Init Control Word #3 + */ + lan_id = ((E1000_READ_REG(hw, E1000_STATUS) & + E1000_STATUS_LAN_ID_MASK) >> E1000_STATUS_LAN_ID_OFFSET); + /* + * Derive Init Control Word #3 offset + * and mask to pick up link mode setting. + */ + if (hw->mac.type < e1000_82580) { + init_ctrl_wd_3_offset = lan_id ? + NVM_INIT_CONTROL3_PORT_A : NVM_INIT_CONTROL3_PORT_B; + init_ctrl_wd_3_bit_offset = NVM_WORD24_LNK_MODE_OFFSET; + } else { + init_ctrl_wd_3_offset = + NVM_82580_LAN_FUNC_OFFSET(lan_id) + + NVM_INIT_CONTROL3_PORT_A; + init_ctrl_wd_3_bit_offset = + NVM_WORD24_82580_LNK_MODE_OFFSET; + } + /* Read Init Control Word #3*/ + hw->nvm.ops.read(hw, init_ctrl_wd_3_offset, 1, &init_ctrl_wd_3); + + /* + * Align link mode bits to + * their CTRL_EXT location. + */ + current_link_mode = init_ctrl_wd_3; + current_link_mode <<= (E1000_CTRL_EXT_LINK_MODE_OFFSET - + init_ctrl_wd_3_bit_offset); + current_link_mode &= E1000_CTRL_EXT_LINK_MODE_MASK; + + /* + * Switch to CSR for all but internal PHY. + */ + if (current_link_mode != E1000_CTRL_EXT_LINK_MODE_GMII) + /* Take link mode from CSR */ + current_link_mode = ctrl_ext & + E1000_CTRL_EXT_LINK_MODE_MASK; + } else { + /* Take link mode from CSR */ + current_link_mode = ctrl_ext & E1000_CTRL_EXT_LINK_MODE_MASK; + } + + switch (current_link_mode) { + + case E1000_CTRL_EXT_LINK_MODE_1000BASE_KX: + hw->phy.media_type = e1000_media_type_internal_serdes; + current_link_mode = E1000_CTRL_EXT_LINK_MODE_1000BASE_KX; + break; + case E1000_CTRL_EXT_LINK_MODE_GMII: + hw->phy.media_type = e1000_media_type_copper; + current_link_mode = E1000_CTRL_EXT_LINK_MODE_GMII; + break; + case E1000_CTRL_EXT_LINK_MODE_SGMII: + case E1000_CTRL_EXT_LINK_MODE_PCIE_SERDES: + /* Get phy control interface type set (MDIO vs. I2C)*/ + if (e1000_sgmii_uses_mdio_82575(hw)) { + hw->phy.media_type = e1000_media_type_copper; + dev_spec->sgmii_active = TRUE; + current_link_mode = E1000_CTRL_EXT_LINK_MODE_SGMII; + } else { + ret_val = e1000_set_sfp_media_type_82575(hw); + if (ret_val != E1000_SUCCESS) + goto out; + if (hw->phy.media_type == + e1000_media_type_internal_serdes) { + current_link_mode = + E1000_CTRL_EXT_LINK_MODE_PCIE_SERDES; + } else if (hw->phy.media_type == + e1000_media_type_copper) { + current_link_mode = + E1000_CTRL_EXT_LINK_MODE_SGMII; + } + } + break; + default: + DEBUGOUT("Link mode mask doesn't fit bit field size\n"); + goto out; + } + /* + * Do not change current link mode setting + * if media type is fibre or has not been + * recognized. + */ + if ((hw->phy.media_type != e1000_media_type_unknown) && + (hw->phy.media_type != e1000_media_type_fiber)) { + /* Update link mode */ + ctrl_ext &= ~E1000_CTRL_EXT_LINK_MODE_MASK; + E1000_WRITE_REG(hw, E1000_CTRL_EXT, ctrl_ext | + current_link_mode); + } + + ret_val = E1000_SUCCESS; +out: + /* + * If media type was not identified then return media type + * defined by the CTRL_EXT settings. + */ + if (hw->phy.media_type == e1000_media_type_unknown) { + if (current_link_mode == E1000_CTRL_EXT_LINK_MODE_SGMII) + hw->phy.media_type = e1000_media_type_copper; + else + hw->phy.media_type = e1000_media_type_internal_serdes; + } + + return ret_val; +} + +/** + * e1000_set_sfp_media_type_82575 - derives SFP module media type. + * @hw: pointer to the HW structure + * + * The media type is chosen based on SFP module. + * compatibility flags retrieved from SFP ID EEPROM. + **/ +static s32 e1000_set_sfp_media_type_82575(struct e1000_hw *hw) +{ + s32 ret_val = E1000_ERR_CONFIG; + u32 ctrl_ext = 0; + struct e1000_dev_spec_82575 *dev_spec = &hw->dev_spec._82575; + struct sfp_e1000_flags eth_flags = {0}; + u8 tranceiver_type = 0; + + /* Turn I2C interface ON */ + ctrl_ext = E1000_READ_REG(hw, E1000_CTRL_EXT); + E1000_WRITE_REG(hw, E1000_CTRL_EXT, ctrl_ext | E1000_CTRL_I2C_ENA); + + /* Read SFP module data */ + ret_val = e1000_read_sfp_data_byte(hw, + E1000_I2CCMD_SFP_DATA_ADDR(E1000_SFF_IDENTIFIER_OFFSET), + &tranceiver_type); + if (ret_val != E1000_SUCCESS) + goto out; + ret_val = e1000_read_sfp_data_byte(hw, + E1000_I2CCMD_SFP_DATA_ADDR(E1000_SFF_ETH_FLAGS_OFFSET), + (u8 *)ð_flags); + if (ret_val != E1000_SUCCESS) + goto out; + /* + * Check if there is some SFP + * module plugged and powered + */ + if ((tranceiver_type == E1000_SFF_IDENTIFIER_SFP) || + (tranceiver_type == E1000_SFF_IDENTIFIER_SFF)) { + dev_spec->module_plugged = TRUE; + if (eth_flags.e1000_base_lx || eth_flags.e1000_base_sx) { + hw->phy.media_type = e1000_media_type_internal_serdes; + } else if (eth_flags.e1000_base_t) { + dev_spec->sgmii_active = TRUE; + hw->phy.media_type = e1000_media_type_copper; + } else { + hw->phy.media_type = e1000_media_type_unknown; + DEBUGOUT("PHY module has not been recognized\n"); + goto out; + } + } else { + hw->phy.media_type = e1000_media_type_unknown; + } + ret_val = E1000_SUCCESS; +out: + /* Restore I2C interface setting */ + E1000_WRITE_REG(hw, E1000_CTRL_EXT, ctrl_ext); + return ret_val; } /** @@ -1514,7 +1796,7 @@ static s32 e1000_valid_led_default_82575(struct e1000_hw *hw, u16 *data) } if (*data == ID_LED_RESERVED_0000 || *data == ID_LED_RESERVED_FFFF) { - switch(hw->phy.media_type) { + switch (hw->phy.media_type) { case e1000_media_type_internal_serdes: *data = ID_LED_DEFAULT_82575_SERDES; break; @@ -1549,7 +1831,7 @@ static bool e1000_sgmii_active_82575(struct e1000_hw *hw) * Inits recommended HW defaults after a reset when there is no EEPROM * detected. This is only for the 82575. **/ -static s32 e1000_reset_init_script_82575(struct e1000_hw* hw) +static s32 e1000_reset_init_script_82575(struct e1000_hw *hw) { DEBUGFUNC("e1000_reset_init_script_82575"); @@ -1736,7 +2018,7 @@ void e1000_rx_fifo_flush_82575(struct e1000_hw *hw) for (i = 0; i < 4; i++) { rxdctl[i] = E1000_READ_REG(hw, E1000_RXDCTL(i)); E1000_WRITE_REG(hw, E1000_RXDCTL(i), - rxdctl[i] & ~E1000_RXDCTL_QUEUE_ENABLE); + rxdctl[i] & ~E1000_RXDCTL_QUEUE_ENABLE); } /* Poll all queues to verify they have shut down */ for (ms_wait = 0; ms_wait < 10; ms_wait++) { @@ -1822,14 +2104,14 @@ static s32 e1000_set_pcie_completion_timeout(struct e1000_hw *hw) * 16ms to 55ms */ ret_val = e1000_read_pcie_cap_reg(hw, PCIE_DEVICE_CONTROL2, - &pcie_devctl2); + &pcie_devctl2); if (ret_val) goto out; pcie_devctl2 |= PCIE_DEVICE_CONTROL2_16ms; ret_val = e1000_write_pcie_cap_reg(hw, PCIE_DEVICE_CONTROL2, - &pcie_devctl2); + &pcie_devctl2); out: /* disable completion timeout resend */ gcr &= ~E1000_GCR_CMPL_TMOUT_RESEND; @@ -1852,20 +2134,35 @@ void e1000_vmdq_set_anti_spoofing_pf(struct e1000_hw *hw, bool enable, int pf) switch (hw->mac.type) { case e1000_82576: - case e1000_i350: dtxswc = E1000_READ_REG(hw, E1000_DTXSWC); if (enable) { dtxswc |= (E1000_DTXSWC_MAC_SPOOF_MASK | E1000_DTXSWC_VLAN_SPOOF_MASK); /* The PF can spoof - it has to in order to * support emulation mode NICs */ - dtxswc ^= (1 << pf | 1 << (pf + MAX_NUM_VFS)); + dtxswc ^= (1 << pf | 1 << (pf + + E1000_DTXSWC_VLAN_SPOOF_SHIFT)); } else { dtxswc &= ~(E1000_DTXSWC_MAC_SPOOF_MASK | E1000_DTXSWC_VLAN_SPOOF_MASK); } E1000_WRITE_REG(hw, E1000_DTXSWC, dtxswc); break; + case e1000_i350: + dtxswc = E1000_READ_REG(hw, E1000_TXSWC); + if (enable) { + dtxswc |= (E1000_DTXSWC_MAC_SPOOF_MASK | + E1000_DTXSWC_VLAN_SPOOF_MASK); + /* The PF can spoof - it has to in order to + * support emulation mode NICs + */ + dtxswc ^= (1 << pf | 1 << (pf + + E1000_DTXSWC_VLAN_SPOOF_SHIFT)); + } else { + dtxswc &= ~(E1000_DTXSWC_MAC_SPOOF_MASK | + E1000_DTXSWC_VLAN_SPOOF_MASK); + } + E1000_WRITE_REG(hw, E1000_TXSWC, dtxswc); default: break; } @@ -2001,8 +2298,8 @@ static s32 e1000_reset_mdicnfg_82580(struct e1000_hw *hw) goto out; ret_val = hw->nvm.ops.read(hw, NVM_INIT_CONTROL3_PORT_A + - NVM_82580_LAN_FUNC_OFFSET(hw->bus.func), 1, - &nvm_data); + NVM_82580_LAN_FUNC_OFFSET(hw->bus.func), 1, + &nvm_data); if (ret_val) { DEBUGOUT("NVM Read Error\n"); goto out; @@ -2057,17 +2354,18 @@ static s32 e1000_reset_hw_82580(struct e1000_hw *hw) msec_delay(10); /* Determine whether or not a global dev reset is requested */ - if (global_device_reset && - e1000_acquire_swfw_sync_82575(hw, swmbsw_mask)) + if (global_device_reset && hw->mac.ops.acquire_swfw_sync(hw, + swmbsw_mask)) global_device_reset = FALSE; - if (global_device_reset && - !(E1000_READ_REG(hw, E1000_STATUS) & E1000_STAT_DEV_RST_SET)) + if (global_device_reset && !(E1000_READ_REG(hw, E1000_STATUS) & + E1000_STAT_DEV_RST_SET)) ctrl |= E1000_CTRL_DEV_RST; else ctrl |= E1000_CTRL_RST; E1000_WRITE_REG(hw, E1000_CTRL, ctrl); + E1000_WRITE_FLUSH(hw); /* Add delay to insure DEV_RST has time to complete */ if (global_device_reset) @@ -2084,7 +2382,7 @@ static s32 e1000_reset_hw_82580(struct e1000_hw *hw) } /* If EEPROM is not present, run manual init scripts */ - if ((E1000_READ_REG(hw, E1000_EECD) & E1000_EECD_PRES) == 0) + if (!(E1000_READ_REG(hw, E1000_EECD) & E1000_EECD_PRES)) e1000_reset_init_script_82575(hw); /* clear global device reset status bit */ @@ -2103,7 +2401,7 @@ static s32 e1000_reset_hw_82580(struct e1000_hw *hw) /* Release semaphore */ if (global_device_reset) - e1000_release_swfw_sync_82575(hw, swmbsw_mask); + hw->mac.ops.release_swfw_sync(hw, swmbsw_mask); return ret_val; } @@ -2192,7 +2490,7 @@ s32 e1000_update_nvm_checksum_with_offset(struct e1000_hw *hw, u16 offset) } checksum = (u16) NVM_SUM - checksum; ret_val = hw->nvm.ops.write(hw, (NVM_CHECKSUM_REG + offset), 1, - &checksum); + &checksum); if (ret_val) DEBUGOUT("NVM Write Error while updating checksum.\n"); @@ -2232,7 +2530,7 @@ static s32 e1000_validate_nvm_checksum_82580(struct e1000_hw *hw) for (j = 0; j < eeprom_regions_count; j++) { nvm_offset = NVM_82580_LAN_FUNC_OFFSET(j); ret_val = e1000_validate_nvm_checksum_with_offset(hw, - nvm_offset); + nvm_offset); if (ret_val != E1000_SUCCESS) goto out; } @@ -2259,19 +2557,17 @@ static s32 e1000_update_nvm_checksum_82580(struct e1000_hw *hw) ret_val = hw->nvm.ops.read(hw, NVM_COMPATIBILITY_REG_3, 1, &nvm_data); if (ret_val) { - DEBUGOUT("NVM Read Error while updating checksum" - " compatibility bit.\n"); + DEBUGOUT("NVM Read Error while updating checksum compatibility bit.\n"); goto out; } - if ((nvm_data & NVM_COMPATIBILITY_BIT_MASK) == 0) { + if (!(nvm_data & NVM_COMPATIBILITY_BIT_MASK)) { /* set compatibility bit to validate checksums appropriately */ nvm_data = nvm_data | NVM_COMPATIBILITY_BIT_MASK; ret_val = hw->nvm.ops.write(hw, NVM_COMPATIBILITY_REG_3, 1, - &nvm_data); + &nvm_data); if (ret_val) { - DEBUGOUT("NVM Write Error while updating checksum" - " compatibility bit.\n"); + DEBUGOUT("NVM Write Error while updating checksum compatibility bit.\n"); goto out; } } @@ -2279,9 +2575,8 @@ static s32 e1000_update_nvm_checksum_82580(struct e1000_hw *hw) for (j = 0; j < 4; j++) { nvm_offset = NVM_82580_LAN_FUNC_OFFSET(j); ret_val = e1000_update_nvm_checksum_with_offset(hw, nvm_offset); - if (ret_val) { + if (ret_val) goto out; - } } out: @@ -2307,7 +2602,7 @@ static s32 e1000_validate_nvm_checksum_i350(struct e1000_hw *hw) for (j = 0; j < 4; j++) { nvm_offset = NVM_82580_LAN_FUNC_OFFSET(j); ret_val = e1000_validate_nvm_checksum_with_offset(hw, - nvm_offset); + nvm_offset); if (ret_val != E1000_SUCCESS) goto out; } @@ -2353,37 +2648,630 @@ static s32 e1000_update_nvm_checksum_i350(struct e1000_hw *hw) s32 e1000_set_eee_i350(struct e1000_hw *hw) { s32 ret_val = E1000_SUCCESS; - u32 ipcnfg, eeer, ctrl_ext; + u32 ipcnfg, eeer; DEBUGFUNC("e1000_set_eee_i350"); - ctrl_ext = E1000_READ_REG(hw, E1000_CTRL_EXT); - if ((hw->mac.type != e1000_i350) || - (ctrl_ext & E1000_CTRL_EXT_LINK_MODE_MASK)) + if ((hw->mac.type < e1000_i350) || + (hw->phy.media_type != e1000_media_type_copper)) goto out; ipcnfg = E1000_READ_REG(hw, E1000_IPCNFG); eeer = E1000_READ_REG(hw, E1000_EEER); /* enable or disable per user setting */ if (!(hw->dev_spec._82575.eee_disable)) { - ipcnfg |= (E1000_IPCNFG_EEE_1G_AN | - E1000_IPCNFG_EEE_100M_AN); - eeer |= (E1000_EEER_TX_LPI_EN | - E1000_EEER_RX_LPI_EN | - E1000_EEER_LPI_FC); + ipcnfg |= (E1000_IPCNFG_EEE_1G_AN | E1000_IPCNFG_EEE_100M_AN); + eeer |= (E1000_EEER_TX_LPI_EN | E1000_EEER_RX_LPI_EN | + E1000_EEER_LPI_FC); } else { - ipcnfg &= ~(E1000_IPCNFG_EEE_1G_AN | - E1000_IPCNFG_EEE_100M_AN); - eeer &= ~(E1000_EEER_TX_LPI_EN | - E1000_EEER_RX_LPI_EN | - E1000_EEER_LPI_FC); + ipcnfg &= ~(E1000_IPCNFG_EEE_1G_AN | E1000_IPCNFG_EEE_100M_AN); + eeer &= ~(E1000_EEER_TX_LPI_EN | E1000_EEER_RX_LPI_EN | + E1000_EEER_LPI_FC); } E1000_WRITE_REG(hw, E1000_IPCNFG, ipcnfg); E1000_WRITE_REG(hw, E1000_EEER, eeer); - E1000_READ_REG(hw, E1000_IPCNFG); - E1000_READ_REG(hw, E1000_EEER); + E1000_READ_REG(hw, E1000_IPCNFG); + E1000_READ_REG(hw, E1000_EEER); out: return ret_val; } + +/* Due to a hw errata, if the host tries to configure the VFTA register + * while performing queries from the BMC or DMA, then the VFTA in some + * cases won't be written. + */ + +/** + * e1000_clear_vfta_i350 - Clear VLAN filter table + * @hw: pointer to the HW structure + * + * Clears the register array which contains the VLAN filter table by + * setting all the values to 0. + **/ +void e1000_clear_vfta_i350(struct e1000_hw *hw) +{ + u32 offset; + int i; + + DEBUGFUNC("e1000_clear_vfta_350"); + + for (offset = 0; offset < E1000_VLAN_FILTER_TBL_SIZE; offset++) { + for (i = 0; i < 10; i++) + E1000_WRITE_REG_ARRAY(hw, E1000_VFTA, offset, 0); + + E1000_WRITE_FLUSH(hw); + } +} + +/** + * e1000_write_vfta_i350 - Write value to VLAN filter table + * @hw: pointer to the HW structure + * @offset: register offset in VLAN filter table + * @value: register value written to VLAN filter table + * + * Writes value at the given offset in the register array which stores + * the VLAN filter table. + **/ +void e1000_write_vfta_i350(struct e1000_hw *hw, u32 offset, u32 value) +{ + int i; + + DEBUGFUNC("e1000_write_vfta_350"); + + for (i = 0; i < 10; i++) + E1000_WRITE_REG_ARRAY(hw, E1000_VFTA, offset, value); + + E1000_WRITE_FLUSH(hw); +} + + +/** + * e1000_set_i2c_bb - Enable I2C bit-bang + * @hw: pointer to the HW structure + * + * Enable I2C bit-bang interface + * + **/ +s32 e1000_set_i2c_bb(struct e1000_hw *hw) +{ + s32 ret_val = E1000_SUCCESS; + u32 ctrl_ext, i2cparams; + + DEBUGFUNC("e1000_set_i2c_bb"); + + ctrl_ext = E1000_READ_REG(hw, E1000_CTRL_EXT); + ctrl_ext |= E1000_CTRL_I2C_ENA; + E1000_WRITE_REG(hw, E1000_CTRL_EXT, ctrl_ext); + E1000_WRITE_FLUSH(hw); + + i2cparams = E1000_READ_REG(hw, E1000_I2CPARAMS); + i2cparams |= E1000_I2CBB_EN; + i2cparams |= E1000_I2C_DATA_OE_N; + i2cparams |= E1000_I2C_CLK_OE_N; + E1000_WRITE_REG(hw, E1000_I2CPARAMS, i2cparams); + E1000_WRITE_FLUSH(hw); + + return ret_val; +} + +/** + * e1000_read_i2c_byte_generic - Reads 8 bit word over I2C + * @hw: pointer to hardware structure + * @byte_offset: byte offset to read + * @dev_addr: device address + * @data: value read + * + * Performs byte read operation over I2C interface at + * a specified device address. + **/ +s32 e1000_read_i2c_byte_generic(struct e1000_hw *hw, u8 byte_offset, + u8 dev_addr, u8 *data) +{ + s32 status = E1000_SUCCESS; + u32 max_retry = 10; + u32 retry = 1; + u16 swfw_mask = 0; + + bool nack = TRUE; + + DEBUGFUNC("e1000_read_i2c_byte_generic"); + + swfw_mask = E1000_SWFW_PHY0_SM; + + do { + if (hw->mac.ops.acquire_swfw_sync(hw, swfw_mask) + != E1000_SUCCESS) { + status = E1000_ERR_SWFW_SYNC; + goto read_byte_out; + } + + e1000_i2c_start(hw); + + /* Device Address and write indication */ + status = e1000_clock_out_i2c_byte(hw, dev_addr); + if (status != E1000_SUCCESS) + goto fail; + + status = e1000_get_i2c_ack(hw); + if (status != E1000_SUCCESS) + goto fail; + + status = e1000_clock_out_i2c_byte(hw, byte_offset); + if (status != E1000_SUCCESS) + goto fail; + + status = e1000_get_i2c_ack(hw); + if (status != E1000_SUCCESS) + goto fail; + + e1000_i2c_start(hw); + + /* Device Address and read indication */ + status = e1000_clock_out_i2c_byte(hw, (dev_addr | 0x1)); + if (status != E1000_SUCCESS) + goto fail; + + status = e1000_get_i2c_ack(hw); + if (status != E1000_SUCCESS) + goto fail; + + status = e1000_clock_in_i2c_byte(hw, data); + if (status != E1000_SUCCESS) + goto fail; + + status = e1000_clock_out_i2c_bit(hw, nack); + if (status != E1000_SUCCESS) + goto fail; + + e1000_i2c_stop(hw); + break; + +fail: + hw->mac.ops.release_swfw_sync(hw, swfw_mask); + msec_delay(100); + e1000_i2c_bus_clear(hw); + retry++; + if (retry < max_retry) + DEBUGOUT("I2C byte read error - Retrying.\n"); + else + DEBUGOUT("I2C byte read error.\n"); + + } while (retry < max_retry); + + hw->mac.ops.release_swfw_sync(hw, swfw_mask); + +read_byte_out: + + return status; +} + +/** + * e1000_write_i2c_byte_generic - Writes 8 bit word over I2C + * @hw: pointer to hardware structure + * @byte_offset: byte offset to write + * @dev_addr: device address + * @data: value to write + * + * Performs byte write operation over I2C interface at + * a specified device address. + **/ +s32 e1000_write_i2c_byte_generic(struct e1000_hw *hw, u8 byte_offset, + u8 dev_addr, u8 data) +{ + s32 status = E1000_SUCCESS; + u32 max_retry = 1; + u32 retry = 0; + u16 swfw_mask = 0; + + DEBUGFUNC("e1000_write_i2c_byte_generic"); + + swfw_mask = E1000_SWFW_PHY0_SM; + + if (hw->mac.ops.acquire_swfw_sync(hw, swfw_mask) != E1000_SUCCESS) { + status = E1000_ERR_SWFW_SYNC; + goto write_byte_out; + } + + do { + e1000_i2c_start(hw); + + status = e1000_clock_out_i2c_byte(hw, dev_addr); + if (status != E1000_SUCCESS) + goto fail; + + status = e1000_get_i2c_ack(hw); + if (status != E1000_SUCCESS) + goto fail; + + status = e1000_clock_out_i2c_byte(hw, byte_offset); + if (status != E1000_SUCCESS) + goto fail; + + status = e1000_get_i2c_ack(hw); + if (status != E1000_SUCCESS) + goto fail; + + status = e1000_clock_out_i2c_byte(hw, data); + if (status != E1000_SUCCESS) + goto fail; + + status = e1000_get_i2c_ack(hw); + if (status != E1000_SUCCESS) + goto fail; + + e1000_i2c_stop(hw); + break; + +fail: + e1000_i2c_bus_clear(hw); + retry++; + if (retry < max_retry) + DEBUGOUT("I2C byte write error - Retrying.\n"); + else + DEBUGOUT("I2C byte write error.\n"); + } while (retry < max_retry); + + hw->mac.ops.release_swfw_sync(hw, swfw_mask); + +write_byte_out: + + return status; +} + +/** + * e1000_i2c_start - Sets I2C start condition + * @hw: pointer to hardware structure + * + * Sets I2C start condition (High -> Low on SDA while SCL is High) + **/ +static void e1000_i2c_start(struct e1000_hw *hw) +{ + u32 i2cctl = E1000_READ_REG(hw, E1000_I2CPARAMS); + + DEBUGFUNC("e1000_i2c_start"); + + /* Start condition must begin with data and clock high */ + e1000_set_i2c_data(hw, &i2cctl, 1); + e1000_raise_i2c_clk(hw, &i2cctl); + + /* Setup time for start condition (4.7us) */ + usec_delay(E1000_I2C_T_SU_STA); + + e1000_set_i2c_data(hw, &i2cctl, 0); + + /* Hold time for start condition (4us) */ + usec_delay(E1000_I2C_T_HD_STA); + + e1000_lower_i2c_clk(hw, &i2cctl); + + /* Minimum low period of clock is 4.7 us */ + usec_delay(E1000_I2C_T_LOW); + +} + +/** + * e1000_i2c_stop - Sets I2C stop condition + * @hw: pointer to hardware structure + * + * Sets I2C stop condition (Low -> High on SDA while SCL is High) + **/ +static void e1000_i2c_stop(struct e1000_hw *hw) +{ + u32 i2cctl = E1000_READ_REG(hw, E1000_I2CPARAMS); + + DEBUGFUNC("e1000_i2c_stop"); + + /* Stop condition must begin with data low and clock high */ + e1000_set_i2c_data(hw, &i2cctl, 0); + e1000_raise_i2c_clk(hw, &i2cctl); + + /* Setup time for stop condition (4us) */ + usec_delay(E1000_I2C_T_SU_STO); + + e1000_set_i2c_data(hw, &i2cctl, 1); + + /* bus free time between stop and start (4.7us)*/ + usec_delay(E1000_I2C_T_BUF); +} + +/** + * e1000_clock_in_i2c_byte - Clocks in one byte via I2C + * @hw: pointer to hardware structure + * @data: data byte to clock in + * + * Clocks in one byte data via I2C data/clock + **/ +static s32 e1000_clock_in_i2c_byte(struct e1000_hw *hw, u8 *data) +{ + s32 i; + bool bit = 0; + + DEBUGFUNC("e1000_clock_in_i2c_byte"); + + *data = 0; + for (i = 7; i >= 0; i--) { + e1000_clock_in_i2c_bit(hw, &bit); + *data |= bit << i; + } + + return E1000_SUCCESS; +} + +/** + * e1000_clock_out_i2c_byte - Clocks out one byte via I2C + * @hw: pointer to hardware structure + * @data: data byte clocked out + * + * Clocks out one byte data via I2C data/clock + **/ +static s32 e1000_clock_out_i2c_byte(struct e1000_hw *hw, u8 data) +{ + s32 status = E1000_SUCCESS; + s32 i; + u32 i2cctl; + bool bit = 0; + + DEBUGFUNC("e1000_clock_out_i2c_byte"); + + for (i = 7; i >= 0; i--) { + bit = (data >> i) & 0x1; + status = e1000_clock_out_i2c_bit(hw, bit); + + if (status != E1000_SUCCESS) + break; + } + + /* Release SDA line (set high) */ + i2cctl = E1000_READ_REG(hw, E1000_I2CPARAMS); + + i2cctl |= E1000_I2C_DATA_OE_N; + E1000_WRITE_REG(hw, E1000_I2CPARAMS, i2cctl); + E1000_WRITE_FLUSH(hw); + + return status; +} + +/** + * e1000_get_i2c_ack - Polls for I2C ACK + * @hw: pointer to hardware structure + * + * Clocks in/out one bit via I2C data/clock + **/ +static s32 e1000_get_i2c_ack(struct e1000_hw *hw) +{ + s32 status = E1000_SUCCESS; + u32 i = 0; + u32 i2cctl = E1000_READ_REG(hw, E1000_I2CPARAMS); + u32 timeout = 10; + bool ack = TRUE; + + DEBUGFUNC("e1000_get_i2c_ack"); + + e1000_raise_i2c_clk(hw, &i2cctl); + + /* Minimum high period of clock is 4us */ + usec_delay(E1000_I2C_T_HIGH); + + /* Wait until SCL returns high */ + for (i = 0; i < timeout; i++) { + usec_delay(1); + i2cctl = E1000_READ_REG(hw, E1000_I2CPARAMS); + if (i2cctl & E1000_I2C_CLK_IN) + break; + } + if (!(i2cctl & E1000_I2C_CLK_IN)) + return E1000_ERR_I2C; + + ack = e1000_get_i2c_data(&i2cctl); + if (ack) { + DEBUGOUT("I2C ack was not received.\n"); + status = E1000_ERR_I2C; + } + + e1000_lower_i2c_clk(hw, &i2cctl); + + /* Minimum low period of clock is 4.7 us */ + usec_delay(E1000_I2C_T_LOW); + + return status; +} + +/** + * e1000_clock_in_i2c_bit - Clocks in one bit via I2C data/clock + * @hw: pointer to hardware structure + * @data: read data value + * + * Clocks in one bit via I2C data/clock + **/ +static s32 e1000_clock_in_i2c_bit(struct e1000_hw *hw, bool *data) +{ + u32 i2cctl = E1000_READ_REG(hw, E1000_I2CPARAMS); + + DEBUGFUNC("e1000_clock_in_i2c_bit"); + + e1000_raise_i2c_clk(hw, &i2cctl); + + /* Minimum high period of clock is 4us */ + usec_delay(E1000_I2C_T_HIGH); + + i2cctl = E1000_READ_REG(hw, E1000_I2CPARAMS); + *data = e1000_get_i2c_data(&i2cctl); + + e1000_lower_i2c_clk(hw, &i2cctl); + + /* Minimum low period of clock is 4.7 us */ + usec_delay(E1000_I2C_T_LOW); + + return E1000_SUCCESS; +} + +/** + * e1000_clock_out_i2c_bit - Clocks in/out one bit via I2C data/clock + * @hw: pointer to hardware structure + * @data: data value to write + * + * Clocks out one bit via I2C data/clock + **/ +static s32 e1000_clock_out_i2c_bit(struct e1000_hw *hw, bool data) +{ + s32 status; + u32 i2cctl = E1000_READ_REG(hw, E1000_I2CPARAMS); + + DEBUGFUNC("e1000_clock_out_i2c_bit"); + + status = e1000_set_i2c_data(hw, &i2cctl, data); + if (status == E1000_SUCCESS) { + e1000_raise_i2c_clk(hw, &i2cctl); + + /* Minimum high period of clock is 4us */ + usec_delay(E1000_I2C_T_HIGH); + + e1000_lower_i2c_clk(hw, &i2cctl); + + /* Minimum low period of clock is 4.7 us. + * This also takes care of the data hold time. + */ + usec_delay(E1000_I2C_T_LOW); + } else { + status = E1000_ERR_I2C; + DEBUGOUT1("I2C data was not set to %X\n", data); + } + + return status; +} +/** + * e1000_raise_i2c_clk - Raises the I2C SCL clock + * @hw: pointer to hardware structure + * @i2cctl: Current value of I2CCTL register + * + * Raises the I2C clock line '0'->'1' + **/ +static void e1000_raise_i2c_clk(struct e1000_hw *hw, u32 *i2cctl) +{ + DEBUGFUNC("e1000_raise_i2c_clk"); + + *i2cctl |= E1000_I2C_CLK_OUT; + *i2cctl &= ~E1000_I2C_CLK_OE_N; + E1000_WRITE_REG(hw, E1000_I2CPARAMS, *i2cctl); + E1000_WRITE_FLUSH(hw); + + /* SCL rise time (1000ns) */ + usec_delay(E1000_I2C_T_RISE); +} + +/** + * e1000_lower_i2c_clk - Lowers the I2C SCL clock + * @hw: pointer to hardware structure + * @i2cctl: Current value of I2CCTL register + * + * Lowers the I2C clock line '1'->'0' + **/ +static void e1000_lower_i2c_clk(struct e1000_hw *hw, u32 *i2cctl) +{ + + DEBUGFUNC("e1000_lower_i2c_clk"); + + *i2cctl &= ~E1000_I2C_CLK_OUT; + *i2cctl &= ~E1000_I2C_CLK_OE_N; + E1000_WRITE_REG(hw, E1000_I2CPARAMS, *i2cctl); + E1000_WRITE_FLUSH(hw); + + /* SCL fall time (300ns) */ + usec_delay(E1000_I2C_T_FALL); +} + +/** + * e1000_set_i2c_data - Sets the I2C data bit + * @hw: pointer to hardware structure + * @i2cctl: Current value of I2CCTL register + * @data: I2C data value (0 or 1) to set + * + * Sets the I2C data bit + **/ +static s32 e1000_set_i2c_data(struct e1000_hw *hw, u32 *i2cctl, bool data) +{ + s32 status = E1000_SUCCESS; + + DEBUGFUNC("e1000_set_i2c_data"); + + if (data) + *i2cctl |= E1000_I2C_DATA_OUT; + else + *i2cctl &= ~E1000_I2C_DATA_OUT; + + *i2cctl &= ~E1000_I2C_DATA_OE_N; + *i2cctl |= E1000_I2C_CLK_OE_N; + E1000_WRITE_REG(hw, E1000_I2CPARAMS, *i2cctl); + E1000_WRITE_FLUSH(hw); + + /* Data rise/fall (1000ns/300ns) and set-up time (250ns) */ + usec_delay(E1000_I2C_T_RISE + E1000_I2C_T_FALL + E1000_I2C_T_SU_DATA); + + *i2cctl = E1000_READ_REG(hw, E1000_I2CPARAMS); + if (data != e1000_get_i2c_data(i2cctl)) { + status = E1000_ERR_I2C; + DEBUGOUT1("Error - I2C data was not set to %X.\n", data); + } + + return status; +} + +/** + * e1000_get_i2c_data - Reads the I2C SDA data bit + * @hw: pointer to hardware structure + * @i2cctl: Current value of I2CCTL register + * + * Returns the I2C data bit value + **/ +static bool e1000_get_i2c_data(u32 *i2cctl) +{ + bool data; + + DEBUGFUNC("e1000_get_i2c_data"); + + if (*i2cctl & E1000_I2C_DATA_IN) + data = 1; + else + data = 0; + + return data; +} + +/** + * e1000_i2c_bus_clear - Clears the I2C bus + * @hw: pointer to hardware structure + * + * Clears the I2C bus by sending nine clock pulses. + * Used when data line is stuck low. + **/ +void e1000_i2c_bus_clear(struct e1000_hw *hw) +{ + u32 i2cctl = E1000_READ_REG(hw, E1000_I2CPARAMS); + u32 i; + + DEBUGFUNC("e1000_i2c_bus_clear"); + + e1000_i2c_start(hw); + + e1000_set_i2c_data(hw, &i2cctl, 1); + + for (i = 0; i < 9; i++) { + e1000_raise_i2c_clk(hw, &i2cctl); + + /* Min high period of clock is 4us */ + usec_delay(E1000_I2C_T_HIGH); + + e1000_lower_i2c_clk(hw, &i2cctl); + + /* Min low period of clock is 4.7us*/ + usec_delay(E1000_I2C_T_LOW); + } + + e1000_i2c_start(hw); + + /* Put the i2c bus back to default state */ + e1000_i2c_stop(hw); +} + diff --git a/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_82575.h b/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_82575.h index baef9d0c680..4b2b245f3de 100644 --- a/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_82575.h +++ b/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_82575.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,15 +30,15 @@ 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_ -#define ID_LED_DEFAULT_82575_SERDES ((ID_LED_DEF1_DEF2 << 12) | \ - (ID_LED_DEF1_DEF2 << 8) | \ - (ID_LED_DEF1_DEF2 << 4) | \ - (ID_LED_OFF1_ON2)) +#define ID_LED_DEFAULT_82575_SERDES ((ID_LED_DEF1_DEF2 << 12) | \ + (ID_LED_DEF1_DEF2 << 8) | \ + (ID_LED_DEF1_DEF2 << 4) | \ + (ID_LED_OFF1_ON2)) /* * Receive Address Register Count * Number of high/low register pairs in the RAR. The RAR (Receive Address @@ -49,13 +49,13 @@ * For 82576, there are an additional set of RARs that begin at an offset * separate from the first set of RARs. */ -#define E1000_RAR_ENTRIES_82575 16 -#define E1000_RAR_ENTRIES_82576 24 -#define E1000_RAR_ENTRIES_82580 24 -#define E1000_RAR_ENTRIES_I350 32 -#define E1000_SW_SYNCH_MB 0x00000100 -#define E1000_STAT_DEV_RST_SET 0x00100000 -#define E1000_CTRL_DEV_RST 0x20000000 +#define E1000_RAR_ENTRIES_82575 16 +#define E1000_RAR_ENTRIES_82576 24 +#define E1000_RAR_ENTRIES_82580 24 +#define E1000_RAR_ENTRIES_I350 32 +#define E1000_SW_SYNCH_MB 0x00000100 +#define E1000_STAT_DEV_RST_SET 0x00100000 +#define E1000_CTRL_DEV_RST 0x20000000 #ifdef E1000_BIT_FIELDS struct e1000_adv_data_desc { @@ -63,137 +63,138 @@ 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; }; -#define E1000_TXD_DTYP_ADV_C 0x2 /* Advanced Context Descriptor */ -#define E1000_TXD_DTYP_ADV_D 0x3 /* Advanced Data Descriptor */ -#define E1000_ADV_TXD_CMD_DEXT 0x20 /* Descriptor extension (0 = legacy) */ -#define E1000_ADV_TUCMD_IPV4 0x2 /* IP Packet Type: 1=IPv4 */ -#define E1000_ADV_TUCMD_IPV6 0x0 /* IP Packet Type: 0=IPv6 */ -#define E1000_ADV_TUCMD_L4T_UDP 0x0 /* L4 Packet TYPE of UDP */ -#define E1000_ADV_TUCMD_L4T_TCP 0x4 /* L4 Packet TYPE of TCP */ -#define E1000_ADV_TUCMD_MKRREQ 0x10 /* Indicates markers are required */ -#define E1000_ADV_DCMD_EOP 0x1 /* End of Packet */ -#define E1000_ADV_DCMD_IFCS 0x2 /* Insert FCS (Ethernet CRC) */ -#define E1000_ADV_DCMD_RS 0x8 /* Report Status */ -#define E1000_ADV_DCMD_VLE 0x40 /* Add VLAN tag */ -#define E1000_ADV_DCMD_TSE 0x80 /* TCP Seg enable */ +#define E1000_TXD_DTYP_ADV_C 0x2 /* Advanced Context Descriptor */ +#define E1000_TXD_DTYP_ADV_D 0x3 /* Advanced Data Descriptor */ +#define E1000_ADV_TXD_CMD_DEXT 0x20 /* Descriptor extension (0 = legacy) */ +#define E1000_ADV_TUCMD_IPV4 0x2 /* IP Packet Type: 1=IPv4 */ +#define E1000_ADV_TUCMD_IPV6 0x0 /* IP Packet Type: 0=IPv6 */ +#define E1000_ADV_TUCMD_L4T_UDP 0x0 /* L4 Packet TYPE of UDP */ +#define E1000_ADV_TUCMD_L4T_TCP 0x4 /* L4 Packet TYPE of TCP */ +#define E1000_ADV_TUCMD_MKRREQ 0x10 /* Indicates markers are required */ +#define E1000_ADV_DCMD_EOP 0x1 /* End of Packet */ +#define E1000_ADV_DCMD_IFCS 0x2 /* Insert FCS (Ethernet CRC) */ +#define E1000_ADV_DCMD_RS 0x8 /* Report Status */ +#define E1000_ADV_DCMD_VLE 0x40 /* Add VLAN tag */ +#define E1000_ADV_DCMD_TSE 0x80 /* TCP Seg enable */ /* Extended Device Control */ -#define E1000_CTRL_EXT_NSICR 0x00000001 /* Disable Intr Clear all on read */ +#define E1000_CTRL_EXT_NSICR 0x00000001 /* Disable Intr Clear all on read */ 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; }; #endif /* SRRCTL bit definitions */ -#define E1000_SRRCTL_BSIZEPKT_SHIFT 10 /* Shift _right_ */ -#define E1000_SRRCTL_BSIZEHDRSIZE_MASK 0x00000F00 -#define E1000_SRRCTL_BSIZEHDRSIZE_SHIFT 2 /* Shift _left_ */ -#define E1000_SRRCTL_DESCTYPE_LEGACY 0x00000000 -#define E1000_SRRCTL_DESCTYPE_ADV_ONEBUF 0x02000000 -#define E1000_SRRCTL_DESCTYPE_HDR_SPLIT 0x04000000 -#define E1000_SRRCTL_DESCTYPE_HDR_SPLIT_ALWAYS 0x0A000000 -#define E1000_SRRCTL_DESCTYPE_HDR_REPLICATION 0x06000000 +#define E1000_SRRCTL_BSIZEPKT_SHIFT 10 /* Shift _right_ */ +#define E1000_SRRCTL_BSIZEHDRSIZE_MASK 0x00000F00 +#define E1000_SRRCTL_BSIZEHDRSIZE_SHIFT 2 /* Shift _left_ */ +#define E1000_SRRCTL_DESCTYPE_LEGACY 0x00000000 +#define E1000_SRRCTL_DESCTYPE_ADV_ONEBUF 0x02000000 +#define E1000_SRRCTL_DESCTYPE_HDR_SPLIT 0x04000000 +#define E1000_SRRCTL_DESCTYPE_HDR_SPLIT_ALWAYS 0x0A000000 +#define E1000_SRRCTL_DESCTYPE_HDR_REPLICATION 0x06000000 #define E1000_SRRCTL_DESCTYPE_HDR_REPLICATION_LARGE_PKT 0x08000000 -#define E1000_SRRCTL_DESCTYPE_MASK 0x0E000000 -#define E1000_SRRCTL_TIMESTAMP 0x40000000 -#define E1000_SRRCTL_DROP_EN 0x80000000 - -#define E1000_SRRCTL_BSIZEPKT_MASK 0x0000007F -#define E1000_SRRCTL_BSIZEHDR_MASK 0x00003F00 - -#define E1000_TX_HEAD_WB_ENABLE 0x1 -#define E1000_TX_SEQNUM_WB_ENABLE 0x2 - -#define E1000_MRQC_ENABLE_RSS_4Q 0x00000002 -#define E1000_MRQC_ENABLE_VMDQ 0x00000003 -#define E1000_MRQC_ENABLE_VMDQ_RSS_2Q 0x00000005 -#define E1000_MRQC_RSS_FIELD_IPV4_UDP 0x00400000 -#define E1000_MRQC_RSS_FIELD_IPV6_UDP 0x00800000 -#define E1000_MRQC_RSS_FIELD_IPV6_UDP_EX 0x01000000 -#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_POOL_MIRROR_ENABLE (1 << 0) -#define E1000_VMRCTL_UPLINK_MIRROR_ENABLE (1 << 1) -#define E1000_VMRCTL_DOWNLINK_MIRROR_ENABLE (1 << 2) +#define E1000_SRRCTL_DESCTYPE_MASK 0x0E000000 +#define E1000_SRRCTL_TIMESTAMP 0x40000000 +#define E1000_SRRCTL_DROP_EN 0x80000000 + +#define E1000_SRRCTL_BSIZEPKT_MASK 0x0000007F +#define E1000_SRRCTL_BSIZEHDR_MASK 0x00003F00 + +#define E1000_TX_HEAD_WB_ENABLE 0x1 +#define E1000_TX_SEQNUM_WB_ENABLE 0x2 + +#define E1000_MRQC_ENABLE_RSS_4Q 0x00000002 +#define E1000_MRQC_ENABLE_VMDQ 0x00000003 +#define E1000_MRQC_ENABLE_VMDQ_RSS_2Q 0x00000005 +#define E1000_MRQC_RSS_FIELD_IPV4_UDP 0x00400000 +#define E1000_MRQC_RSS_FIELD_IPV6_UDP 0x00800000 +#define E1000_MRQC_RSS_FIELD_IPV6_UDP_EX 0x01000000 +#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_POOL_MIRROR_ENABLE (1 << 0) +#define E1000_VMRCTL_UPLINK_MIRROR_ENABLE (1 << 1) +#define E1000_VMRCTL_DOWNLINK_MIRROR_ENABLE (1 << 2) #define E1000_EICR_TX_QUEUE ( \ - E1000_EICR_TX_QUEUE0 | \ - E1000_EICR_TX_QUEUE1 | \ - E1000_EICR_TX_QUEUE2 | \ - E1000_EICR_TX_QUEUE3) + E1000_EICR_TX_QUEUE0 | \ + E1000_EICR_TX_QUEUE1 | \ + E1000_EICR_TX_QUEUE2 | \ + E1000_EICR_TX_QUEUE3) #define E1000_EICR_RX_QUEUE ( \ - E1000_EICR_RX_QUEUE0 | \ - E1000_EICR_RX_QUEUE1 | \ - E1000_EICR_RX_QUEUE2 | \ - E1000_EICR_RX_QUEUE3) + E1000_EICR_RX_QUEUE0 | \ + E1000_EICR_RX_QUEUE1 | \ + E1000_EICR_RX_QUEUE2 | \ + E1000_EICR_RX_QUEUE3) -#define E1000_EIMS_RX_QUEUE E1000_EICR_RX_QUEUE -#define E1000_EIMS_TX_QUEUE E1000_EICR_TX_QUEUE +#define E1000_EIMS_RX_QUEUE E1000_EICR_RX_QUEUE +#define E1000_EIMS_TX_QUEUE E1000_EICR_TX_QUEUE #define EIMS_ENABLE_MASK ( \ - E1000_EIMS_RX_QUEUE | \ - E1000_EIMS_TX_QUEUE | \ - E1000_EIMS_TCP_TIMER | \ - E1000_EIMS_OTHER) + E1000_EIMS_RX_QUEUE | \ + E1000_EIMS_TX_QUEUE | \ + E1000_EIMS_TCP_TIMER | \ + E1000_EIMS_OTHER) /* Immediate Interrupt Rx (A.K.A. Low Latency Interrupt) */ -#define E1000_IMIR_PORT_IM_EN 0x00010000 /* TCP port enable */ -#define E1000_IMIR_PORT_BP 0x00020000 /* TCP port check bypass */ -#define E1000_IMIREXT_SIZE_BP 0x00001000 /* Packet size bypass */ -#define E1000_IMIREXT_CTRL_URG 0x00002000 /* Check URG bit in header */ -#define E1000_IMIREXT_CTRL_ACK 0x00004000 /* Check ACK bit in header */ -#define E1000_IMIREXT_CTRL_PSH 0x00008000 /* Check PSH bit in header */ -#define E1000_IMIREXT_CTRL_RST 0x00010000 /* Check RST bit in header */ -#define E1000_IMIREXT_CTRL_SYN 0x00020000 /* Check SYN bit in header */ -#define E1000_IMIREXT_CTRL_FIN 0x00040000 /* Check FIN bit in header */ -#define E1000_IMIREXT_CTRL_BP 0x00080000 /* Bypass check of ctrl bits */ +#define E1000_IMIR_PORT_IM_EN 0x00010000 /* TCP port enable */ +#define E1000_IMIR_PORT_BP 0x00020000 /* TCP port check bypass */ +#define E1000_IMIREXT_SIZE_BP 0x00001000 /* Packet size bypass */ +#define E1000_IMIREXT_CTRL_URG 0x00002000 /* Check URG bit in header */ +#define E1000_IMIREXT_CTRL_ACK 0x00004000 /* Check ACK bit in header */ +#define E1000_IMIREXT_CTRL_PSH 0x00008000 /* Check PSH bit in header */ +#define E1000_IMIREXT_CTRL_RST 0x00010000 /* Check RST bit in header */ +#define E1000_IMIREXT_CTRL_SYN 0x00020000 /* Check SYN bit in header */ +#define E1000_IMIREXT_CTRL_FIN 0x00040000 /* Check FIN bit in header */ +#define E1000_IMIREXT_CTRL_BP 0x00080000 /* Bypass check of ctrl bits */ /* Receive Descriptor - Advanced */ union e1000_adv_rx_desc { struct { - __le64 pkt_addr; /* Packet buffer address */ - __le64 hdr_addr; /* Header buffer address */ + __le64 pkt_addr; /* Packet buffer address */ + __le64 hdr_addr; /* Header buffer address */ } read; struct { struct { @@ -206,74 +207,74 @@ union e1000_adv_rx_desc { } hs_rss; } lo_dword; union { - __le32 rss; /* RSS Hash */ + __le32 rss; /* RSS Hash */ struct { - __le16 ip_id; /* IP id */ - __le16 csum; /* Packet Checksum */ + __le16 ip_id; /* IP id */ + __le16 csum; /* Packet Checksum */ } csum_ip; } hi_dword; } lower; struct { - __le32 status_error; /* ext status/error */ - __le16 length; /* Packet length */ - __le16 vlan; /* VLAN tag */ + __le32 status_error; /* ext status/error */ + __le16 length; /* Packet length */ + __le16 vlan; /* VLAN tag */ } upper; } wb; /* writeback */ }; -#define E1000_RXDADV_RSSTYPE_MASK 0x0000000F -#define E1000_RXDADV_RSSTYPE_SHIFT 12 -#define E1000_RXDADV_HDRBUFLEN_MASK 0x7FE0 -#define E1000_RXDADV_HDRBUFLEN_SHIFT 5 -#define E1000_RXDADV_SPLITHEADER_EN 0x00001000 -#define E1000_RXDADV_SPH 0x8000 -#define E1000_RXDADV_STAT_TS 0x10000 /* Pkt was time stamped */ -#define E1000_RXDADV_STAT_TSIP 0x08000 /* timestamp in packet */ -#define E1000_RXDADV_ERR_HBO 0x00800000 +#define E1000_RXDADV_RSSTYPE_MASK 0x0000000F +#define E1000_RXDADV_RSSTYPE_SHIFT 12 +#define E1000_RXDADV_HDRBUFLEN_MASK 0x7FE0 +#define E1000_RXDADV_HDRBUFLEN_SHIFT 5 +#define E1000_RXDADV_SPLITHEADER_EN 0x00001000 +#define E1000_RXDADV_SPH 0x8000 +#define E1000_RXDADV_STAT_TS 0x10000 /* Pkt was time stamped */ +#define E1000_RXDADV_STAT_TSIP 0x08000 /* timestamp in packet */ +#define E1000_RXDADV_ERR_HBO 0x00800000 /* RSS Hash results */ -#define E1000_RXDADV_RSSTYPE_NONE 0x00000000 -#define E1000_RXDADV_RSSTYPE_IPV4_TCP 0x00000001 -#define E1000_RXDADV_RSSTYPE_IPV4 0x00000002 -#define E1000_RXDADV_RSSTYPE_IPV6_TCP 0x00000003 -#define E1000_RXDADV_RSSTYPE_IPV6_EX 0x00000004 -#define E1000_RXDADV_RSSTYPE_IPV6 0x00000005 +#define E1000_RXDADV_RSSTYPE_NONE 0x00000000 +#define E1000_RXDADV_RSSTYPE_IPV4_TCP 0x00000001 +#define E1000_RXDADV_RSSTYPE_IPV4 0x00000002 +#define E1000_RXDADV_RSSTYPE_IPV6_TCP 0x00000003 +#define E1000_RXDADV_RSSTYPE_IPV6_EX 0x00000004 +#define E1000_RXDADV_RSSTYPE_IPV6 0x00000005 #define E1000_RXDADV_RSSTYPE_IPV6_TCP_EX 0x00000006 -#define E1000_RXDADV_RSSTYPE_IPV4_UDP 0x00000007 -#define E1000_RXDADV_RSSTYPE_IPV6_UDP 0x00000008 +#define E1000_RXDADV_RSSTYPE_IPV4_UDP 0x00000007 +#define E1000_RXDADV_RSSTYPE_IPV6_UDP 0x00000008 #define E1000_RXDADV_RSSTYPE_IPV6_UDP_EX 0x00000009 /* RSS Packet Types as indicated in the receive descriptor */ -#define E1000_RXDADV_PKTTYPE_NONE 0x00000000 -#define E1000_RXDADV_PKTTYPE_IPV4 0x00000010 /* IPV4 hdr present */ -#define E1000_RXDADV_PKTTYPE_IPV4_EX 0x00000020 /* IPV4 hdr + extensions */ -#define E1000_RXDADV_PKTTYPE_IPV6 0x00000040 /* IPV6 hdr present */ -#define E1000_RXDADV_PKTTYPE_IPV6_EX 0x00000080 /* IPV6 hdr + extensions */ -#define E1000_RXDADV_PKTTYPE_TCP 0x00000100 /* TCP hdr present */ -#define E1000_RXDADV_PKTTYPE_UDP 0x00000200 /* UDP hdr present */ -#define E1000_RXDADV_PKTTYPE_SCTP 0x00000400 /* SCTP hdr present */ -#define E1000_RXDADV_PKTTYPE_NFS 0x00000800 /* NFS hdr present */ - -#define E1000_RXDADV_PKTTYPE_IPSEC_ESP 0x00001000 /* IPSec ESP */ -#define E1000_RXDADV_PKTTYPE_IPSEC_AH 0x00002000 /* IPSec AH */ -#define E1000_RXDADV_PKTTYPE_LINKSEC 0x00004000 /* LinkSec Encap */ -#define E1000_RXDADV_PKTTYPE_ETQF 0x00008000 /* PKTTYPE is ETQF index */ -#define E1000_RXDADV_PKTTYPE_ETQF_MASK 0x00000070 /* ETQF has 8 indices */ -#define E1000_RXDADV_PKTTYPE_ETQF_SHIFT 4 /* Right-shift 4 bits */ +#define E1000_RXDADV_PKTTYPE_NONE 0x00000000 +#define E1000_RXDADV_PKTTYPE_IPV4 0x00000010 /* IPV4 hdr present */ +#define E1000_RXDADV_PKTTYPE_IPV4_EX 0x00000020 /* IPV4 hdr + extensions */ +#define E1000_RXDADV_PKTTYPE_IPV6 0x00000040 /* IPV6 hdr present */ +#define E1000_RXDADV_PKTTYPE_IPV6_EX 0x00000080 /* IPV6 hdr + extensions */ +#define E1000_RXDADV_PKTTYPE_TCP 0x00000100 /* TCP hdr present */ +#define E1000_RXDADV_PKTTYPE_UDP 0x00000200 /* UDP hdr present */ +#define E1000_RXDADV_PKTTYPE_SCTP 0x00000400 /* SCTP hdr present */ +#define E1000_RXDADV_PKTTYPE_NFS 0x00000800 /* NFS hdr present */ + +#define E1000_RXDADV_PKTTYPE_IPSEC_ESP 0x00001000 /* IPSec ESP */ +#define E1000_RXDADV_PKTTYPE_IPSEC_AH 0x00002000 /* IPSec AH */ +#define E1000_RXDADV_PKTTYPE_LINKSEC 0x00004000 /* LinkSec Encap */ +#define E1000_RXDADV_PKTTYPE_ETQF 0x00008000 /* PKTTYPE is ETQF index */ +#define E1000_RXDADV_PKTTYPE_ETQF_MASK 0x00000070 /* ETQF has 8 indices */ +#define E1000_RXDADV_PKTTYPE_ETQF_SHIFT 4 /* Right-shift 4 bits */ /* LinkSec results */ /* Security Processing bit Indication */ -#define E1000_RXDADV_LNKSEC_STATUS_SECP 0x00020000 -#define E1000_RXDADV_LNKSEC_ERROR_BIT_MASK 0x18000000 -#define E1000_RXDADV_LNKSEC_ERROR_NO_SA_MATCH 0x08000000 -#define E1000_RXDADV_LNKSEC_ERROR_REPLAY_ERROR 0x10000000 -#define E1000_RXDADV_LNKSEC_ERROR_BAD_SIG 0x18000000 - -#define E1000_RXDADV_IPSEC_STATUS_SECP 0x00020000 -#define E1000_RXDADV_IPSEC_ERROR_BIT_MASK 0x18000000 -#define E1000_RXDADV_IPSEC_ERROR_INVALID_PROTOCOL 0x08000000 -#define E1000_RXDADV_IPSEC_ERROR_INVALID_LENGTH 0x10000000 -#define E1000_RXDADV_IPSEC_ERROR_AUTHENTICATION_FAILED 0x18000000 +#define E1000_RXDADV_LNKSEC_STATUS_SECP 0x00020000 +#define E1000_RXDADV_LNKSEC_ERROR_BIT_MASK 0x18000000 +#define E1000_RXDADV_LNKSEC_ERROR_NO_SA_MATCH 0x08000000 +#define E1000_RXDADV_LNKSEC_ERROR_REPLAY_ERROR 0x10000000 +#define E1000_RXDADV_LNKSEC_ERROR_BAD_SIG 0x18000000 + +#define E1000_RXDADV_IPSEC_STATUS_SECP 0x00020000 +#define E1000_RXDADV_IPSEC_ERROR_BIT_MASK 0x18000000 +#define E1000_RXDADV_IPSEC_ERROR_INVALID_PROTOCOL 0x08000000 +#define E1000_RXDADV_IPSEC_ERROR_INVALID_LENGTH 0x10000000 +#define E1000_RXDADV_IPSEC_ERROR_AUTHENTICATION_FAILED 0x18000000 /* Transmit Descriptor - Advanced */ union e1000_adv_tx_desc { @@ -290,25 +291,26 @@ union e1000_adv_tx_desc { }; /* Adv Transmit Descriptor Config Masks */ -#define E1000_ADVTXD_DTYP_CTXT 0x00200000 /* Advanced Context Descriptor */ -#define E1000_ADVTXD_DTYP_DATA 0x00300000 /* Advanced Data Descriptor */ -#define E1000_ADVTXD_DCMD_EOP 0x01000000 /* End of Packet */ -#define E1000_ADVTXD_DCMD_IFCS 0x02000000 /* Insert FCS (Ethernet CRC) */ -#define E1000_ADVTXD_DCMD_RS 0x08000000 /* Report Status */ -#define E1000_ADVTXD_DCMD_DDTYP_ISCSI 0x10000000 /* DDP hdr type or iSCSI */ -#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_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*/ -#define E1000_ADVTXD_POPTS_IPSEC 0x00000400 /* IPSec offload request */ -#define E1000_ADVTXD_PAYLEN_SHIFT 14 /* Adv desc PAYLEN shift */ +#define E1000_ADVTXD_DTYP_CTXT 0x00200000 /* Advanced Context Descriptor */ +#define E1000_ADVTXD_DTYP_DATA 0x00300000 /* Advanced Data Descriptor */ +#define E1000_ADVTXD_DCMD_EOP 0x01000000 /* End of Packet */ +#define E1000_ADVTXD_DCMD_IFCS 0x02000000 /* Insert FCS (Ethernet CRC) */ +#define E1000_ADVTXD_DCMD_RS 0x08000000 /* Report Status */ +#define E1000_ADVTXD_DCMD_DDTYP_ISCSI 0x10000000 /* DDP hdr type or iSCSI */ +#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 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 */ +/* 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 */ /* Context descriptors */ struct e1000_adv_tx_context_desc { @@ -318,65 +320,66 @@ struct e1000_adv_tx_context_desc { __le32 mss_l4len_idx; }; -#define E1000_ADVTXD_MACLEN_SHIFT 9 /* Adv ctxt desc mac len shift */ -#define E1000_ADVTXD_VLAN_SHIFT 16 /* Adv ctxt vlan tag shift */ -#define E1000_ADVTXD_TUCMD_IPV4 0x00000400 /* IP Packet Type: 1=IPv4 */ -#define E1000_ADVTXD_TUCMD_IPV6 0x00000000 /* IP Packet Type: 0=IPv6 */ -#define E1000_ADVTXD_TUCMD_L4T_UDP 0x00000000 /* L4 Packet TYPE of UDP */ -#define E1000_ADVTXD_TUCMD_L4T_TCP 0x00000800 /* L4 Packet TYPE of TCP */ -#define E1000_ADVTXD_TUCMD_L4T_SCTP 0x00001000 /* L4 Packet TYPE of SCTP */ -#define E1000_ADVTXD_TUCMD_IPSEC_TYPE_ESP 0x00002000 /* IPSec Type ESP */ +#define E1000_ADVTXD_MACLEN_SHIFT 9 /* Adv ctxt desc mac len shift */ +#define E1000_ADVTXD_VLAN_SHIFT 16 /* Adv ctxt vlan tag shift */ +#define E1000_ADVTXD_TUCMD_IPV4 0x00000400 /* IP Packet Type: 1=IPv4 */ +#define E1000_ADVTXD_TUCMD_IPV6 0x00000000 /* IP Packet Type: 0=IPv6 */ +#define E1000_ADVTXD_TUCMD_L4T_UDP 0x00000000 /* L4 Packet TYPE of UDP */ +#define E1000_ADVTXD_TUCMD_L4T_TCP 0x00000800 /* L4 Packet TYPE of TCP */ +#define E1000_ADVTXD_TUCMD_L4T_SCTP 0x00001000 /* L4 Packet TYPE of SCTP */ +#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 */ -#define E1000_ADVTXD_L4LEN_SHIFT 8 /* Adv ctxt L4LEN shift */ -#define E1000_ADVTXD_MSS_SHIFT 16 /* Adv ctxt MSS shift */ +#define E1000_ADVTXD_TUCMD_IPSEC_ENCRYPT_EN 0x00004000 +/* 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 */ -#define E1000_ADVTXD_IPSEC_SA_INDEX_MASK 0x000000FF +#define E1000_ADVTXD_IPSEC_SA_INDEX_MASK 0x000000FF /* Adv ctxt IPSec ESP len mask */ -#define E1000_ADVTXD_IPSEC_ESP_LEN_MASK 0x000000FF +#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 +#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 */ -#define E1000_DCA_CTRL_DCA_DISABLE 0x00000001 /* DCA Disable */ +#define E1000_DCA_CTRL_DCA_ENABLE 0x00000000 /* DCA Enable */ +#define E1000_DCA_CTRL_DCA_DISABLE 0x00000001 /* DCA Disable */ -#define E1000_DCA_CTRL_DCA_MODE_CB1 0x00 /* DCA Mode CB1 */ -#define E1000_DCA_CTRL_DCA_MODE_CB2 0x02 /* DCA Mode CB2 */ +#define E1000_DCA_CTRL_DCA_MODE_CB1 0x00 /* DCA Mode CB1 */ +#define E1000_DCA_CTRL_DCA_MODE_CB2 0x02 /* DCA Mode CB2 */ -#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_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 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 */ -#define E1000_DCA_TXCTRL_TX_WB_RO_EN (1 << 11) /* Tx Desc writeback RO bit */ +#define E1000_DCA_TXCTRL_CPUID_MASK 0x0000001F /* Tx CPUID Mask */ +#define E1000_DCA_TXCTRL_DESC_DCA_EN (1 << 5) /* DCA Tx Desc enable */ +#define E1000_DCA_TXCTRL_TX_WB_RO_EN (1 << 11) /* Tx Desc writeback RO bit */ -#define E1000_DCA_TXCTRL_CPUID_MASK_82576 0xFF000000 /* Tx CPUID Mask */ -#define E1000_DCA_RXCTRL_CPUID_MASK_82576 0xFF000000 /* Rx CPUID Mask */ -#define E1000_DCA_TXCTRL_CPUID_SHIFT_82576 24 /* Tx CPUID */ -#define E1000_DCA_RXCTRL_CPUID_SHIFT_82576 24 /* Rx CPUID */ +#define E1000_DCA_TXCTRL_CPUID_MASK_82576 0xFF000000 /* Tx CPUID Mask */ +#define E1000_DCA_RXCTRL_CPUID_MASK_82576 0xFF000000 /* Rx CPUID Mask */ +#define E1000_DCA_TXCTRL_CPUID_SHIFT_82576 24 /* Tx CPUID */ +#define E1000_DCA_RXCTRL_CPUID_SHIFT_82576 24 /* Rx CPUID */ /* Additional interrupt register bit definitions */ -#define E1000_ICR_LSECPNS 0x00000020 /* PN threshold - server */ -#define E1000_IMS_LSECPNS E1000_ICR_LSECPNS /* PN threshold - server */ -#define E1000_ICS_LSECPNS E1000_ICR_LSECPNS /* PN threshold - server */ +#define E1000_ICR_LSECPNS 0x00000020 /* PN threshold - server */ +#define E1000_IMS_LSECPNS E1000_ICR_LSECPNS /* PN threshold - server */ +#define E1000_ICS_LSECPNS E1000_ICR_LSECPNS /* PN threshold - server */ /* ETQF register bit definitions */ -#define E1000_ETQF_FILTER_ENABLE (1 << 26) -#define E1000_ETQF_IMM_INT (1 << 29) -#define E1000_ETQF_1588 (1 << 30) -#define E1000_ETQF_QUEUE_ENABLE (1 << 31) +#define E1000_ETQF_FILTER_ENABLE (1 << 26) +#define E1000_ETQF_IMM_INT (1 << 29) +#define E1000_ETQF_1588 (1 << 30) +#define E1000_ETQF_QUEUE_ENABLE (1 << 31) /* * ETQF filter list: one static filter per filter consumer. This is * to avoid filter collisions later. Add new filters @@ -385,87 +388,89 @@ struct e1000_adv_tx_context_desc { * Current filters: * EAPOL 802.1x (0x888e): Filter 0 */ -#define E1000_ETQF_FILTER_EAPOL 0 - -#define E1000_FTQF_VF_BP 0x00008000 -#define E1000_FTQF_1588_TIME_STAMP 0x08000000 -#define E1000_FTQF_MASK 0xF0000000 -#define E1000_FTQF_MASK_PROTO_BP 0x10000000 -#define E1000_FTQF_MASK_SOURCE_ADDR_BP 0x20000000 -#define E1000_FTQF_MASK_DEST_ADDR_BP 0x40000000 -#define E1000_FTQF_MASK_SOURCE_PORT_BP 0x80000000 - -#define E1000_NVM_APME_82575 0x0400 -#define MAX_NUM_VFS 8 - -#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_LLE_MASK 0x00FF0000 /* Per VF Local LB enables */ -#define E1000_DTXSWC_VLAN_SPOOF_SHIFT 8 -#define E1000_DTXSWC_LLE_SHIFT 16 -#define E1000_DTXSWC_VMDQ_LOOPBACK_EN (1 << 31) /* global VF LB enable */ +#define E1000_ETQF_FILTER_EAPOL 0 + +#define E1000_FTQF_VF_BP 0x00008000 +#define E1000_FTQF_1588_TIME_STAMP 0x08000000 +#define E1000_FTQF_MASK 0xF0000000 +#define E1000_FTQF_MASK_PROTO_BP 0x10000000 +#define E1000_FTQF_MASK_SOURCE_ADDR_BP 0x20000000 +#define E1000_FTQF_MASK_DEST_ADDR_BP 0x40000000 +#define E1000_FTQF_MASK_SOURCE_PORT_BP 0x80000000 + +#define E1000_NVM_APME_82575 0x0400 +#define MAX_NUM_VFS 7 + +#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 +#define E1000_DTXSWC_VMDQ_LOOPBACK_EN (1 << 31) /* global VF LB enable */ /* Easy defines for setting default pool, would normally be left a zero */ -#define E1000_VT_CTL_DEFAULT_POOL_SHIFT 7 -#define E1000_VT_CTL_DEFAULT_POOL_MASK (0x7 << E1000_VT_CTL_DEFAULT_POOL_SHIFT) +#define E1000_VT_CTL_DEFAULT_POOL_SHIFT 7 +#define E1000_VT_CTL_DEFAULT_POOL_MASK (0x7 << E1000_VT_CTL_DEFAULT_POOL_SHIFT) /* Other useful VMD_CTL register defines */ -#define E1000_VT_CTL_IGNORE_MAC (1 << 28) -#define E1000_VT_CTL_DISABLE_DEF_POOL (1 << 29) -#define E1000_VT_CTL_VM_REPL_EN (1 << 30) +#define E1000_VT_CTL_IGNORE_MAC (1 << 28) +#define E1000_VT_CTL_DISABLE_DEF_POOL (1 << 29) +#define E1000_VT_CTL_VM_REPL_EN (1 << 30) /* Per VM Offload register setup */ -#define E1000_VMOLR_RLPML_MASK 0x00003FFF /* Long Packet Maximum Length mask */ -#define E1000_VMOLR_LPE 0x00010000 /* Accept Long packet */ -#define E1000_VMOLR_RSSE 0x00020000 /* Enable RSS */ -#define E1000_VMOLR_AUPE 0x01000000 /* Accept untagged packets */ -#define E1000_VMOLR_ROMPE 0x02000000 /* Accept overflow multicast */ -#define E1000_VMOLR_ROPE 0x04000000 /* Accept overflow unicast */ -#define E1000_VMOLR_BAM 0x08000000 /* Accept Broadcast packets */ -#define E1000_VMOLR_MPME 0x10000000 /* Multicast promiscuous mode */ -#define E1000_VMOLR_STRVLAN 0x40000000 /* Vlan stripping enable */ -#define E1000_VMOLR_STRCRC 0x80000000 /* CRC stripping enable */ - -#define E1000_VMOLR_VPE 0x00800000 /* VLAN promiscuous enable */ -#define E1000_VMOLR_UPE 0x20000000 /* Unicast promisuous enable */ -#define E1000_DVMOLR_HIDVLAN 0x20000000 /* Vlan hiding enable */ -#define E1000_DVMOLR_STRVLAN 0x40000000 /* Vlan stripping enable */ -#define E1000_DVMOLR_STRCRC 0x80000000 /* CRC stripping enable */ - -#define E1000_PBRWAC_WALPB 0x00000007 /* Wrap around event on LAN Rx PB */ -#define E1000_PBRWAC_PBE 0x00000008 /* Rx packet buffer empty */ - -#define E1000_VLVF_ARRAY_SIZE 32 -#define E1000_VLVF_VLANID_MASK 0x00000FFF -#define E1000_VLVF_POOLSEL_SHIFT 12 -#define E1000_VLVF_POOLSEL_MASK (0xFF << E1000_VLVF_POOLSEL_SHIFT) -#define E1000_VLVF_LVLAN 0x00100000 -#define E1000_VLVF_VLANID_ENABLE 0x80000000 - -#define E1000_VMVIR_VLANA_DEFAULT 0x40000000 /* Always use default VLAN */ -#define E1000_VMVIR_VLANA_NEVER 0x80000000 /* Never insert VLAN tag */ - -#define E1000_VF_INIT_TIMEOUT 200 /* Number of retries to clear RSTI */ - -#define E1000_IOVCTL 0x05BBC -#define E1000_IOVCTL_REUSE_VFQ 0x00000001 - -#define E1000_RPLOLR_STRVLAN 0x40000000 -#define E1000_RPLOLR_STRCRC 0x80000000 - -#define E1000_TCTL_EXT_COLD 0x000FFC00 -#define E1000_TCTL_EXT_COLD_SHIFT 10 - -#define E1000_DTXCTL_8023LL 0x0004 -#define E1000_DTXCTL_VLAN_ADDED 0x0008 -#define E1000_DTXCTL_OOS_ENABLE 0x0010 -#define E1000_DTXCTL_MDP_EN 0x0020 -#define E1000_DTXCTL_SPOOF_INT 0x0040 - -#define ALL_QUEUES 0xFFFF +#define E1000_VMOLR_RLPML_MASK 0x00003FFF /* Long Packet Maximum Length mask */ +#define E1000_VMOLR_LPE 0x00010000 /* Accept Long packet */ +#define E1000_VMOLR_RSSE 0x00020000 /* Enable RSS */ +#define E1000_VMOLR_AUPE 0x01000000 /* Accept untagged packets */ +#define E1000_VMOLR_ROMPE 0x02000000 /* Accept overflow multicast */ +#define E1000_VMOLR_ROPE 0x04000000 /* Accept overflow unicast */ +#define E1000_VMOLR_BAM 0x08000000 /* Accept Broadcast packets */ +#define E1000_VMOLR_MPME 0x10000000 /* Multicast promiscuous mode */ +#define E1000_VMOLR_STRVLAN 0x40000000 /* Vlan stripping enable */ +#define E1000_VMOLR_STRCRC 0x80000000 /* CRC stripping enable */ + +#define E1000_VMOLR_VPE 0x00800000 /* VLAN promiscuous enable */ +#define E1000_VMOLR_UPE 0x20000000 /* Unicast promisuous enable */ +#define E1000_DVMOLR_HIDVLAN 0x20000000 /* Vlan hiding enable */ +#define E1000_DVMOLR_STRVLAN 0x40000000 /* Vlan stripping enable */ +#define E1000_DVMOLR_STRCRC 0x80000000 /* CRC stripping enable */ + +#define E1000_PBRWAC_WALPB 0x00000007 /* Wrap around event on LAN Rx PB */ +#define E1000_PBRWAC_PBE 0x00000008 /* Rx packet buffer empty */ + +#define E1000_VLVF_ARRAY_SIZE 32 +#define E1000_VLVF_VLANID_MASK 0x00000FFF +#define E1000_VLVF_POOLSEL_SHIFT 12 +#define E1000_VLVF_POOLSEL_MASK (0xFF << E1000_VLVF_POOLSEL_SHIFT) +#define E1000_VLVF_LVLAN 0x00100000 +#define E1000_VLVF_VLANID_ENABLE 0x80000000 + +#define E1000_VMVIR_VLANA_DEFAULT 0x40000000 /* Always use default VLAN */ +#define E1000_VMVIR_VLANA_NEVER 0x80000000 /* Never insert VLAN tag */ + +#define E1000_VF_INIT_TIMEOUT 200 /* Number of retries to clear RSTI */ + +#define E1000_IOVCTL 0x05BBC +#define E1000_IOVCTL_REUSE_VFQ 0x00000001 + +#define E1000_RPLOLR_STRVLAN 0x40000000 +#define E1000_RPLOLR_STRCRC 0x80000000 + +#define E1000_TCTL_EXT_COLD 0x000FFC00 +#define E1000_TCTL_EXT_COLD_SHIFT 10 + +#define E1000_DTXCTL_8023LL 0x0004 +#define E1000_DTXCTL_VLAN_ADDED 0x0008 +#define E1000_DTXCTL_OOS_ENABLE 0x0010 +#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 */ -#define E1000_RXPBS_SIZE_MASK_82576 0x0000007F +#define E1000_RXPBS_SIZE_MASK_82576 0x0000007F void e1000_vmdq_set_loopback_pf(struct e1000_hw *hw, bool enable); void e1000_vmdq_set_anti_spoofing_pf(struct e1000_hw *hw, bool enable, int pf); void e1000_vmdq_set_replication_pf(struct e1000_hw *hw, bool enable); @@ -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_ */ diff --git a/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_api.c b/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_api.c index 1b7835b8902..4b2a43d7286 100644 --- a/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_api.c +++ b/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_api.c @@ -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; @@ -343,10 +353,10 @@ s32 e1000_set_mac_type(struct e1000_hw *hw) * e1000_setup_init_funcs - Initializes function pointers * @hw: pointer to the HW structure * @init_device: TRUE will initialize the rest of the function pointers - * getting the device ready for use. FALSE will only set - * MAC type and the function pointers for the other init - * functions. Passing FALSE will not generate any hardware - * reads or writes. + * getting the device ready for use. FALSE will only set + * MAC type and the function pointers for the other init + * functions. Passing FALSE will not generate any hardware + * reads or writes. * * This function must be called by a driver in order to use the rest * of the 'shared' code files. Called by drivers only. @@ -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; @@ -518,11 +532,11 @@ void e1000_write_vfta(struct e1000_hw *hw, u32 offset, u32 value) * The caller must have a packed mc_addr_list of multicast addresses. **/ void e1000_update_mc_addr_list(struct e1000_hw *hw, u8 *mc_addr_list, - u32 mc_addr_count) + u32 mc_addr_count) { if (hw->mac.ops.update_mc_addr_list) hw->mac.ops.update_mc_addr_list(hw, mc_addr_list, - mc_addr_count); + mc_addr_count); } /** @@ -856,12 +870,12 @@ 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, - u16 offset, u8 *sum) +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) return hw->mac.ops.mng_host_if_write(hw, buffer, length, - offset, sum); + offset, sum); return E1000_NOT_IMPLEMENTED; } @@ -874,7 +888,7 @@ s32 e1000_mng_host_if_write(struct e1000_hw * hw, u8 *buffer, u16 length, * Writes the command header after does the checksum calculation. **/ s32 e1000_mng_write_cmd_header(struct e1000_hw *hw, - struct e1000_host_mng_command_header *hdr) + struct e1000_host_mng_command_header *hdr) { if (hw->mac.ops.mng_write_cmd_header) return hw->mac.ops.mng_write_cmd_header(hw, hdr); @@ -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); @@ -1277,7 +1291,7 @@ s32 e1000_write_nvm(struct e1000_hw *hw, u16 offset, u16 words, u16 *data) * This is a function pointer entry point called by drivers. **/ s32 e1000_write_8bit_ctrl_reg(struct e1000_hw *hw, u32 reg, u32 offset, - u8 data) + u8 data) { return e1000_write_8bit_ctrl_reg_generic(hw, reg, offset, data); } diff --git a/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_api.h b/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_api.h index 86d45736203..4c061c0958b 100644 --- a/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_api.h +++ b/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_api.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,97 +30,96 @@ 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_ #include "e1000_hw.h" -extern void e1000_init_function_pointers_82542(struct e1000_hw *hw); -extern void e1000_init_function_pointers_82543(struct e1000_hw *hw); -extern void e1000_init_function_pointers_82540(struct e1000_hw *hw); -extern void e1000_init_function_pointers_82571(struct e1000_hw *hw); -extern void e1000_init_function_pointers_82541(struct e1000_hw *hw); -extern void e1000_init_function_pointers_80003es2lan(struct e1000_hw *hw); -extern void e1000_init_function_pointers_ich8lan(struct e1000_hw *hw); -extern void e1000_init_function_pointers_82575(struct e1000_hw *hw); -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_82542(struct e1000_hw *hw); +extern void e1000_init_function_pointers_82543(struct e1000_hw *hw); +extern void e1000_init_function_pointers_82540(struct e1000_hw *hw); +extern void e1000_init_function_pointers_82571(struct e1000_hw *hw); +extern void e1000_init_function_pointers_82541(struct e1000_hw *hw); +extern void e1000_init_function_pointers_80003es2lan(struct e1000_hw *hw); +extern void e1000_init_function_pointers_ich8lan(struct e1000_hw *hw); +extern void e1000_init_function_pointers_82575(struct e1000_hw *hw); +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); -s32 e1000_init_mac_params(struct e1000_hw *hw); -s32 e1000_init_nvm_params(struct e1000_hw *hw); -s32 e1000_init_phy_params(struct e1000_hw *hw); -s32 e1000_init_mbx_params(struct e1000_hw *hw); -s32 e1000_get_bus_info(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); +s32 e1000_init_mac_params(struct e1000_hw *hw); +s32 e1000_init_nvm_params(struct e1000_hw *hw); +s32 e1000_init_phy_params(struct e1000_hw *hw); +s32 e1000_init_mbx_params(struct e1000_hw *hw); +s32 e1000_get_bus_info(struct e1000_hw *hw); void e1000_clear_vfta(struct e1000_hw *hw); void e1000_write_vfta(struct e1000_hw *hw, u32 offset, u32 value); -s32 e1000_force_mac_fc(struct e1000_hw *hw); -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_disable_pcie_master(struct e1000_hw *hw); +s32 e1000_force_mac_fc(struct e1000_hw *hw); +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_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); -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); -s32 e1000_blink_led(struct e1000_hw *hw); -s32 e1000_led_on(struct e1000_hw *hw); -s32 e1000_led_off(struct e1000_hw *hw); +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); +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); +s32 e1000_blink_led(struct e1000_hw *hw); +s32 e1000_led_on(struct e1000_hw *hw); +s32 e1000_led_off(struct e1000_hw *hw); s32 e1000_id_led_init(struct e1000_hw *hw); void e1000_reset_adaptive(struct e1000_hw *hw); void e1000_update_adaptive(struct e1000_hw *hw); -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_get_phy_info(struct e1000_hw *hw); +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_get_phy_info(struct e1000_hw *hw); void e1000_release_phy(struct e1000_hw *hw); -s32 e1000_acquire_phy(struct e1000_hw *hw); -s32 e1000_cfg_on_link_up(struct e1000_hw *hw); -s32 e1000_phy_hw_reset(struct e1000_hw *hw); -s32 e1000_phy_commit(struct e1000_hw *hw); +s32 e1000_acquire_phy(struct e1000_hw *hw); +s32 e1000_cfg_on_link_up(struct e1000_hw *hw); +s32 e1000_phy_hw_reset(struct e1000_hw *hw); +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_length(struct e1000_hw *hw, u32 *pba_num_size); +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_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); -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_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); +s32 e1000_update_nvm_checksum(struct e1000_hw *hw); +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_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_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_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_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); u32 e1000_translate_register_82542(u32 reg); + + /* * TBI_ACCEPT macro definition: * @@ -152,14 +151,15 @@ 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) \ - (e1000_tbi_sbp_enabled_82543(a) && \ - (((errors) & E1000_RXD_ERR_FRAME_ERR_MASK) == E1000_RXD_ERR_CE) && \ - ((last_byte) == CARRIER_EXTENSION) && \ - (((status) & E1000_RXD_STAT_VP) ? \ - (((length) > (min_frame_size - VLAN_TAG_SIZE)) && \ - ((length) <= (max_frame_size + 1))) : \ - (((length) > min_frame_size) && \ - ((length) <= (max_frame_size + VLAN_TAG_SIZE + 1))))) +#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) && \ + (((status) & E1000_RXD_STAT_VP) ? \ + (((length) > (min_frame_size - VLAN_TAG_SIZE)) && \ + ((length) <= (max_frame_size + 1))) : \ + (((length) > min_frame_size) && \ + ((length) <= (max_frame_size + VLAN_TAG_SIZE + 1))))) #endif diff --git a/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_defines.h b/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_defines.h index 90fb9f1ab65..a4a0ed05004 100644 --- a/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_defines.h +++ b/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/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_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_ @@ -41,815 +41,826 @@ /* Definitions for power management and wakeup registers */ /* Wake Up Control */ -#define E1000_WUC_APME 0x00000001 /* APM Enable */ -#define E1000_WUC_PME_EN 0x00000002 /* PME Enable */ -#define E1000_WUC_PME_STATUS 0x00000004 /* PME Status */ -#define E1000_WUC_APMPME 0x00000008 /* Assert PME on APM Wakeup */ -#define E1000_WUC_LSCWE 0x00000010 /* Link Status wake up enable */ -#define E1000_WUC_PPROXYE 0x00000010 /* Protocol Proxy Enable */ -#define E1000_WUC_LSCWO 0x00000020 /* Link Status wake up override */ -#define E1000_WUC_SPM 0x80000000 /* Enable SPM */ -#define E1000_WUC_PHY_WAKE 0x00000100 /* if PHY supports wakeup */ -#define E1000_WUC_FLX6_PHY 0x4000 /* Flexible Filter 6 Enable */ -#define E1000_WUC_FLX7_PHY 0x8000 /* Flexible Filter 7 Enable */ +#define E1000_WUC_APME 0x00000001 /* APM Enable */ +#define E1000_WUC_PME_EN 0x00000002 /* PME Enable */ +#define E1000_WUC_PME_STATUS 0x00000004 /* PME Status */ +#define E1000_WUC_APMPME 0x00000008 /* Assert PME on APM Wakeup */ +#define E1000_WUC_LSCWE 0x00000010 /* Link Status wake up enable */ +#define E1000_WUC_PPROXYE 0x00000010 /* Protocol Proxy Enable */ +#define E1000_WUC_LSCWO 0x00000020 /* Link Status wake up override */ +#define E1000_WUC_SPM 0x80000000 /* Enable SPM */ +#define E1000_WUC_PHY_WAKE 0x00000100 /* if PHY supports wakeup */ +#define E1000_WUC_FLX6_PHY 0x4000 /* Flexible Filter 6 Enable */ +#define E1000_WUC_FLX7_PHY 0x8000 /* Flexible Filter 7 Enable */ /* Wake Up Filter Control */ -#define E1000_WUFC_LNKC 0x00000001 /* Link Status Change Wakeup Enable */ -#define E1000_WUFC_MAG 0x00000002 /* Magic Packet Wakeup Enable */ -#define E1000_WUFC_EX 0x00000004 /* Directed Exact Wakeup Enable */ -#define E1000_WUFC_MC 0x00000008 /* Directed Multicast Wakeup Enable */ -#define E1000_WUFC_BC 0x00000010 /* Broadcast Wakeup Enable */ -#define E1000_WUFC_ARP 0x00000020 /* ARP Request Packet Wakeup Enable */ -#define E1000_WUFC_IPV4 0x00000040 /* Directed IPv4 Packet Wakeup Enable */ -#define E1000_WUFC_IPV6 0x00000080 /* Directed IPv6 Packet Wakeup Enable */ +#define E1000_WUFC_LNKC 0x00000001 /* Link Status Change Wakeup Enable */ +#define E1000_WUFC_MAG 0x00000002 /* Magic Packet Wakeup Enable */ +#define E1000_WUFC_EX 0x00000004 /* Directed Exact Wakeup Enable */ +#define E1000_WUFC_MC 0x00000008 /* Directed Multicast Wakeup Enable */ +#define E1000_WUFC_BC 0x00000010 /* Broadcast Wakeup Enable */ +#define E1000_WUFC_ARP 0x00000020 /* ARP Request Packet Wakeup Enable */ +#define E1000_WUFC_IPV4 0x00000040 /* Directed IPv4 Packet Wakeup Enable */ +#define E1000_WUFC_IPV6 0x00000080 /* Directed IPv6 Packet Wakeup Enable */ #define E1000_WUFC_IGNORE_TCO_PHY 0x00000800 /* Ignore WakeOn TCO packets */ -#define E1000_WUFC_FLX0_PHY 0x00001000 /* Flexible Filter 0 Enable */ -#define E1000_WUFC_FLX1_PHY 0x00002000 /* Flexible Filter 1 Enable */ -#define E1000_WUFC_FLX2_PHY 0x00004000 /* Flexible Filter 2 Enable */ -#define E1000_WUFC_FLX3_PHY 0x00008000 /* Flexible Filter 3 Enable */ -#define E1000_WUFC_FLX4_PHY 0x00000200 /* Flexible Filter 4 Enable */ -#define E1000_WUFC_FLX5_PHY 0x00000400 /* Flexible Filter 5 Enable */ -#define E1000_WUFC_IGNORE_TCO 0x00008000 /* Ignore WakeOn TCO packets */ -#define E1000_WUFC_FLX0 0x00010000 /* Flexible Filter 0 Enable */ -#define E1000_WUFC_FLX1 0x00020000 /* Flexible Filter 1 Enable */ -#define E1000_WUFC_FLX2 0x00040000 /* Flexible Filter 2 Enable */ -#define E1000_WUFC_FLX3 0x00080000 /* Flexible Filter 3 Enable */ -#define E1000_WUFC_FLX4 0x00100000 /* Flexible Filter 4 Enable */ -#define E1000_WUFC_FLX5 0x00200000 /* Flexible Filter 5 Enable */ -#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_FLX0_PHY 0x00001000 /* Flexible Filter 0 Enable */ +#define E1000_WUFC_FLX1_PHY 0x00002000 /* Flexible Filter 1 Enable */ +#define E1000_WUFC_FLX2_PHY 0x00004000 /* Flexible Filter 2 Enable */ +#define E1000_WUFC_FLX3_PHY 0x00008000 /* Flexible Filter 3 Enable */ +#define E1000_WUFC_FLX4_PHY 0x00000200 /* Flexible Filter 4 Enable */ +#define E1000_WUFC_FLX5_PHY 0x00000400 /* Flexible Filter 5 Enable */ +#define E1000_WUFC_IGNORE_TCO 0x00008000 /* Ignore WakeOn TCO packets */ +#define E1000_WUFC_FLX0 0x00010000 /* Flexible Filter 0 Enable */ +#define E1000_WUFC_FLX1 0x00020000 /* Flexible Filter 1 Enable */ +#define E1000_WUFC_FLX2 0x00040000 /* Flexible Filter 2 Enable */ +#define E1000_WUFC_FLX3 0x00080000 /* Flexible Filter 3 Enable */ +#define E1000_WUFC_FLX4 0x00100000 /* Flexible Filter 4 Enable */ +#define E1000_WUFC_FLX5 0x00200000 /* Flexible Filter 5 Enable */ +#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 /* 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 */ -#define E1000_WUFC_EXT_FLX_FILTERS 0x00300000 /* Ext. FLX filter mask */ +#define E1000_WUFC_EXT_FLX_FILTERS 0x00300000 /* Ext. FLX filter mask */ /* Wake Up Status */ -#define E1000_WUS_LNKC E1000_WUFC_LNKC -#define E1000_WUS_MAG E1000_WUFC_MAG -#define E1000_WUS_EX E1000_WUFC_EX -#define E1000_WUS_MC E1000_WUFC_MC -#define E1000_WUS_BC E1000_WUFC_BC -#define E1000_WUS_ARP E1000_WUFC_ARP -#define E1000_WUS_IPV4 E1000_WUFC_IPV4 -#define E1000_WUS_IPV6 E1000_WUFC_IPV6 -#define E1000_WUS_FLX0_PHY E1000_WUFC_FLX0_PHY -#define E1000_WUS_FLX1_PHY E1000_WUFC_FLX1_PHY -#define E1000_WUS_FLX2_PHY E1000_WUFC_FLX2_PHY -#define E1000_WUS_FLX3_PHY E1000_WUFC_FLX3_PHY -#define E1000_WUS_FLX_FILTERS_PHY_4 E1000_WUFC_FLX_FILTERS_PHY_4 -#define E1000_WUS_FLX0 E1000_WUFC_FLX0 -#define E1000_WUS_FLX1 E1000_WUFC_FLX1 -#define E1000_WUS_FLX2 E1000_WUFC_FLX2 -#define E1000_WUS_FLX3 E1000_WUFC_FLX3 -#define E1000_WUS_FLX4 E1000_WUFC_FLX4 -#define E1000_WUS_FLX5 E1000_WUFC_FLX5 -#define E1000_WUS_FLX6 E1000_WUFC_FLX6 -#define E1000_WUS_FLX7 E1000_WUFC_FLX7 -#define E1000_WUS_FLX4_PHY E1000_WUFC_FLX4_PHY -#define E1000_WUS_FLX5_PHY E1000_WUFC_FLX5_PHY -#define E1000_WUS_FLX6_PHY 0x0400 -#define E1000_WUS_FLX7_PHY 0x0800 -#define E1000_WUS_FLX_FILTERS E1000_WUFC_FLX_FILTERS -#define E1000_WUS_FLX_FILTERS_6 E1000_WUFC_FLX_FILTERS_6 -#define E1000_WUS_FLX_FILTERS_8 E1000_WUFC_FLX_FILTERS_8 -#define E1000_WUS_FLX_FILTERS_PHY_6 E1000_WUFC_FLX_FILTERS_PHY_6 +#define E1000_WUS_LNKC E1000_WUFC_LNKC +#define E1000_WUS_MAG E1000_WUFC_MAG +#define E1000_WUS_EX E1000_WUFC_EX +#define E1000_WUS_MC E1000_WUFC_MC +#define E1000_WUS_BC E1000_WUFC_BC +#define E1000_WUS_ARP E1000_WUFC_ARP +#define E1000_WUS_IPV4 E1000_WUFC_IPV4 +#define E1000_WUS_IPV6 E1000_WUFC_IPV6 +#define E1000_WUS_FLX0_PHY E1000_WUFC_FLX0_PHY +#define E1000_WUS_FLX1_PHY E1000_WUFC_FLX1_PHY +#define E1000_WUS_FLX2_PHY E1000_WUFC_FLX2_PHY +#define E1000_WUS_FLX3_PHY E1000_WUFC_FLX3_PHY +#define E1000_WUS_FLX_FILTERS_PHY_4 E1000_WUFC_FLX_FILTERS_PHY_4 +#define E1000_WUS_FLX0 E1000_WUFC_FLX0 +#define E1000_WUS_FLX1 E1000_WUFC_FLX1 +#define E1000_WUS_FLX2 E1000_WUFC_FLX2 +#define E1000_WUS_FLX3 E1000_WUFC_FLX3 +#define E1000_WUS_FLX4 E1000_WUFC_FLX4 +#define E1000_WUS_FLX5 E1000_WUFC_FLX5 +#define E1000_WUS_FLX6 E1000_WUFC_FLX6 +#define E1000_WUS_FLX7 E1000_WUFC_FLX7 +#define E1000_WUS_FLX4_PHY E1000_WUFC_FLX4_PHY +#define E1000_WUS_FLX5_PHY E1000_WUFC_FLX5_PHY +#define E1000_WUS_FLX6_PHY 0x0400 +#define E1000_WUS_FLX7_PHY 0x0800 +#define E1000_WUS_FLX_FILTERS E1000_WUFC_FLX_FILTERS +#define E1000_WUS_FLX_FILTERS_6 E1000_WUFC_FLX_FILTERS_6 +#define E1000_WUS_FLX_FILTERS_8 E1000_WUFC_FLX_FILTERS_8 +#define E1000_WUS_FLX_FILTERS_PHY_6 E1000_WUFC_FLX_FILTERS_PHY_6 /* Wake Up Packet Length */ -#define E1000_WUPL_LENGTH_MASK 0x0FFF /* Only the lower 12 bits are valid */ +#define E1000_WUPL_LENGTH_MASK 0x0FFF /* Only the lower 12 bits are valid */ /* Four Flexible Filters are supported */ -#define E1000_FLEXIBLE_FILTER_COUNT_MAX 4 +#define E1000_FLEXIBLE_FILTER_COUNT_MAX 4 /* Six Flexible Filters are supported */ -#define E1000_FLEXIBLE_FILTER_COUNT_MAX_6 6 +#define E1000_FLEXIBLE_FILTER_COUNT_MAX_6 6 /* Eight Flexible Filters are supported */ -#define E1000_FLEXIBLE_FILTER_COUNT_MAX_8 8 +#define E1000_FLEXIBLE_FILTER_COUNT_MAX_8 8 /* Two Extended Flexible Filters are supported (82576) */ -#define E1000_EXT_FLEXIBLE_FILTER_COUNT_MAX 2 -#define E1000_FHFT_LENGTH_OFFSET 0xFC /* Length byte in FHFT */ -#define E1000_FHFT_LENGTH_MASK 0x0FF /* Length in lower byte */ +#define E1000_EXT_FLEXIBLE_FILTER_COUNT_MAX 2 +#define E1000_FHFT_LENGTH_OFFSET 0xFC /* Length byte in FHFT */ +#define E1000_FHFT_LENGTH_MASK 0x0FF /* Length in lower byte */ /* Each Flexible Filter is at most 128 (0x80) bytes in length */ -#define E1000_FLEXIBLE_FILTER_SIZE_MAX 128 +#define E1000_FLEXIBLE_FILTER_SIZE_MAX 128 -#define E1000_FFLT_SIZE E1000_FLEXIBLE_FILTER_COUNT_MAX -#define E1000_FFLT_SIZE_6 E1000_FLEXIBLE_FILTER_COUNT_MAX_6 -#define E1000_FFLT_SIZE_8 E1000_FLEXIBLE_FILTER_COUNT_MAX_8 -#define E1000_FFMT_SIZE E1000_FLEXIBLE_FILTER_SIZE_MAX -#define E1000_FFVT_SIZE E1000_FLEXIBLE_FILTER_SIZE_MAX +#define E1000_FFLT_SIZE E1000_FLEXIBLE_FILTER_COUNT_MAX +#define E1000_FFLT_SIZE_6 E1000_FLEXIBLE_FILTER_COUNT_MAX_6 +#define E1000_FFLT_SIZE_8 E1000_FLEXIBLE_FILTER_COUNT_MAX_8 +#define E1000_FFMT_SIZE E1000_FLEXIBLE_FILTER_SIZE_MAX +#define E1000_FFVT_SIZE E1000_FLEXIBLE_FILTER_SIZE_MAX /* Extended Device Control */ -#define E1000_CTRL_EXT_GPI0_EN 0x00000001 /* Maps SDP4 to GPI0 */ -#define E1000_CTRL_EXT_GPI1_EN 0x00000002 /* Maps SDP5 to GPI1 */ -#define E1000_CTRL_EXT_PHYINT_EN E1000_CTRL_EXT_GPI1_EN -#define E1000_CTRL_EXT_GPI2_EN 0x00000004 /* Maps SDP6 to GPI2 */ -#define E1000_CTRL_EXT_GPI3_EN 0x00000008 /* Maps SDP7 to GPI3 */ +#define E1000_CTRL_EXT_GPI0_EN 0x00000001 /* Maps SDP4 to GPI0 */ +#define E1000_CTRL_EXT_GPI1_EN 0x00000002 /* Maps SDP5 to GPI1 */ +#define E1000_CTRL_EXT_PHYINT_EN E1000_CTRL_EXT_GPI1_EN +#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_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_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 /* 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 */ -#define E1000_CTRL_EXT_SDP6_DIR 0x00000400 /* Direction of SDP6 0=in 1=out */ -#define E1000_CTRL_EXT_SDP3_DIR 0x00000800 /* Direction of SDP3 0=in 1=out */ -#define E1000_CTRL_EXT_ASDCHK 0x00001000 /* Initiate an ASD sequence */ -#define E1000_CTRL_EXT_EE_RST 0x00002000 /* Reinitialize from EEPROM */ -#define E1000_CTRL_EXT_IPS 0x00004000 /* Invert Power State */ +#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 */ +#define E1000_CTRL_EXT_SDP6_DIR 0x00000400 /* Direction of SDP6 0=in 1=out */ +#define E1000_CTRL_EXT_SDP3_DIR 0x00000800 /* Direction of SDP3 0=in 1=out */ +#define E1000_CTRL_EXT_ASDCHK 0x00001000 /* Initiate an ASD sequence */ +#define E1000_CTRL_EXT_EE_RST 0x00002000 /* Reinitialize from EEPROM */ +#define E1000_CTRL_EXT_IPS 0x00004000 /* Invert Power State */ /* Physical Func Reset Done Indication */ -#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_LINK_MODE_MASK 0x00C00000 -#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 -#define E1000_CTRL_EXT_LINK_MODE_TBI 0x00C00000 -#define E1000_CTRL_EXT_LINK_MODE_KMRN 0x00000000 -#define E1000_CTRL_EXT_LINK_MODE_PCIE_SERDES 0x00C00000 -#define E1000_CTRL_EXT_LINK_MODE_PCIX_SERDES 0x00800000 -#define E1000_CTRL_EXT_LINK_MODE_SGMII 0x00800000 -#define E1000_CTRL_EXT_EIAME 0x01000000 -#define E1000_CTRL_EXT_IRCA 0x00000001 -#define E1000_CTRL_EXT_WR_WMARK_MASK 0x03000000 -#define E1000_CTRL_EXT_WR_WMARK_256 0x00000000 -#define E1000_CTRL_EXT_WR_WMARK_320 0x01000000 -#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_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 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 +#define E1000_CTRL_EXT_LINK_MODE_TBI 0x00C00000 +#define E1000_CTRL_EXT_LINK_MODE_KMRN 0x00000000 +#define E1000_CTRL_EXT_LINK_MODE_PCIE_SERDES 0x00C00000 +#define E1000_CTRL_EXT_LINK_MODE_PCIX_SERDES 0x00800000 +#define E1000_CTRL_EXT_LINK_MODE_SGMII 0x00800000 +#define E1000_CTRL_EXT_EIAME 0x01000000 +#define E1000_CTRL_EXT_IRCA 0x00000001 +#define E1000_CTRL_EXT_WR_WMARK_MASK 0x03000000 +#define E1000_CTRL_EXT_WR_WMARK_256 0x00000000 +#define E1000_CTRL_EXT_WR_WMARK_320 0x01000000 +#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 /* 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_GHOST_PAREN 0x40000000 -#define E1000_CTRL_EXT_PBA_CLR 0x80000000 /* PBA Clear */ -#define E1000_CTRL_EXT_LSECCK 0x00001000 -#define E1000_CTRL_EXT_PHYPDEN 0x00100000 -#define E1000_I2CCMD_REG_ADDR_SHIFT 16 -#define E1000_I2CCMD_REG_ADDR 0x00FF0000 -#define E1000_I2CCMD_PHY_ADDR_SHIFT 24 -#define E1000_I2CCMD_PHY_ADDR 0x07000000 -#define E1000_I2CCMD_OPCODE_READ 0x08000000 -#define E1000_I2CCMD_OPCODE_WRITE 0x00000000 -#define E1000_I2CCMD_RESET 0x10000000 -#define E1000_I2CCMD_READY 0x20000000 -#define E1000_I2CCMD_INTERRUPT_ENA 0x40000000 -#define E1000_I2CCMD_ERROR 0x80000000 -#define E1000_MAX_SGMII_PHY_REG_ADDR 255 -#define E1000_I2CCMD_PHY_TIMEOUT 200 -#define E1000_IVAR_VALID 0x80 -#define E1000_GPIE_NSICR 0x00000001 -#define E1000_GPIE_MSIX_MODE 0x00000010 -#define E1000_GPIE_EIAME 0x40000000 -#define E1000_GPIE_PBA 0x80000000 +#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 +#define E1000_CTRL_EXT_PHYPDEN 0x00100000 +#define E1000_I2CCMD_REG_ADDR_SHIFT 16 +#define E1000_I2CCMD_REG_ADDR 0x00FF0000 +#define E1000_I2CCMD_PHY_ADDR_SHIFT 24 +#define E1000_I2CCMD_PHY_ADDR 0x07000000 +#define E1000_I2CCMD_OPCODE_READ 0x08000000 +#define E1000_I2CCMD_OPCODE_WRITE 0x00000000 +#define E1000_I2CCMD_RESET 0x10000000 +#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 +#define E1000_GPIE_NSICR 0x00000001 +#define E1000_GPIE_MSIX_MODE 0x00000010 +#define E1000_GPIE_EIAME 0x40000000 +#define E1000_GPIE_PBA 0x80000000 /* Receive Descriptor bit definitions */ -#define E1000_RXD_STAT_DD 0x01 /* Descriptor Done */ -#define E1000_RXD_STAT_EOP 0x02 /* End of Packet */ -#define E1000_RXD_STAT_IXSM 0x04 /* Ignore checksum */ -#define E1000_RXD_STAT_VP 0x08 /* IEEE VLAN Packet */ -#define E1000_RXD_STAT_UDPCS 0x10 /* UDP xsum calculated */ -#define E1000_RXD_STAT_TCPCS 0x20 /* TCP xsum calculated */ -#define E1000_RXD_STAT_IPCS 0x40 /* IP xsum calculated */ -#define E1000_RXD_STAT_PIF 0x80 /* passed in-exact filter */ -#define E1000_RXD_STAT_CRCV 0x100 /* Speculative CRC Valid */ -#define E1000_RXD_STAT_IPIDV 0x200 /* IP identification valid */ -#define E1000_RXD_STAT_UDPV 0x400 /* Valid UDP checksum */ -#define E1000_RXD_STAT_DYNINT 0x800 /* Pkt caused INT via DYNINT */ -#define E1000_RXD_STAT_ACK 0x8000 /* ACK Packet indication */ -#define E1000_RXD_ERR_CE 0x01 /* CRC Error */ -#define E1000_RXD_ERR_SE 0x02 /* Symbol Error */ -#define E1000_RXD_ERR_SEQ 0x04 /* Sequence Error */ -#define E1000_RXD_ERR_CXE 0x10 /* Carrier Extension Error */ -#define E1000_RXD_ERR_TCPE 0x20 /* TCP/UDP Checksum Error */ -#define E1000_RXD_ERR_IPE 0x40 /* IP Checksum Error */ -#define E1000_RXD_ERR_RXE 0x80 /* Rx Data Error */ -#define E1000_RXD_SPC_VLAN_MASK 0x0FFF /* VLAN ID is in lower 12 bits */ -#define E1000_RXD_SPC_PRI_MASK 0xE000 /* Priority is in upper 3 bits */ -#define E1000_RXD_SPC_PRI_SHIFT 13 -#define E1000_RXD_SPC_CFI_MASK 0x1000 /* CFI is bit 12 */ -#define E1000_RXD_SPC_CFI_SHIFT 12 - -#define E1000_RXDEXT_STATERR_LB 0x00040000 -#define E1000_RXDEXT_STATERR_CE 0x01000000 -#define E1000_RXDEXT_STATERR_SE 0x02000000 -#define E1000_RXDEXT_STATERR_SEQ 0x04000000 -#define E1000_RXDEXT_STATERR_CXE 0x10000000 -#define E1000_RXDEXT_STATERR_TCPE 0x20000000 -#define E1000_RXDEXT_STATERR_IPE 0x40000000 -#define E1000_RXDEXT_STATERR_RXE 0x80000000 - -#define E1000_RXDEXT_LSECH 0x01000000 -#define E1000_RXDEXT_LSECE_MASK 0x60000000 -#define E1000_RXDEXT_LSECE_NO_ERROR 0x00000000 -#define E1000_RXDEXT_LSECE_NO_SA_MATCH 0x20000000 -#define E1000_RXDEXT_LSECE_REPLAY_DETECT 0x40000000 -#define E1000_RXDEXT_LSECE_BAD_SIG 0x60000000 +#define E1000_RXD_STAT_DD 0x01 /* Descriptor Done */ +#define E1000_RXD_STAT_EOP 0x02 /* End of Packet */ +#define E1000_RXD_STAT_IXSM 0x04 /* Ignore checksum */ +#define E1000_RXD_STAT_VP 0x08 /* IEEE VLAN Packet */ +#define E1000_RXD_STAT_UDPCS 0x10 /* UDP xsum calculated */ +#define E1000_RXD_STAT_TCPCS 0x20 /* TCP xsum calculated */ +#define E1000_RXD_STAT_IPCS 0x40 /* IP xsum calculated */ +#define E1000_RXD_STAT_PIF 0x80 /* passed in-exact filter */ +#define E1000_RXD_STAT_CRCV 0x100 /* Speculative CRC Valid */ +#define E1000_RXD_STAT_IPIDV 0x200 /* IP identification valid */ +#define E1000_RXD_STAT_UDPV 0x400 /* Valid UDP checksum */ +#define E1000_RXD_STAT_DYNINT 0x800 /* Pkt caused INT via DYNINT */ +#define E1000_RXD_STAT_ACK 0x8000 /* ACK Packet indication */ +#define E1000_RXD_ERR_CE 0x01 /* CRC Error */ +#define E1000_RXD_ERR_SE 0x02 /* Symbol Error */ +#define E1000_RXD_ERR_SEQ 0x04 /* Sequence Error */ +#define E1000_RXD_ERR_CXE 0x10 /* Carrier Extension Error */ +#define E1000_RXD_ERR_TCPE 0x20 /* TCP/UDP Checksum Error */ +#define E1000_RXD_ERR_IPE 0x40 /* IP Checksum Error */ +#define E1000_RXD_ERR_RXE 0x80 /* Rx Data Error */ +#define E1000_RXD_SPC_VLAN_MASK 0x0FFF /* VLAN ID is in lower 12 bits */ +#define E1000_RXD_SPC_PRI_MASK 0xE000 /* Priority is in upper 3 bits */ +#define E1000_RXD_SPC_PRI_SHIFT 13 +#define E1000_RXD_SPC_CFI_MASK 0x1000 /* CFI is bit 12 */ +#define E1000_RXD_SPC_CFI_SHIFT 12 + +#define E1000_RXDEXT_STATERR_LB 0x00040000 +#define E1000_RXDEXT_STATERR_CE 0x01000000 +#define E1000_RXDEXT_STATERR_SE 0x02000000 +#define E1000_RXDEXT_STATERR_SEQ 0x04000000 +#define E1000_RXDEXT_STATERR_CXE 0x10000000 +#define E1000_RXDEXT_STATERR_TCPE 0x20000000 +#define E1000_RXDEXT_STATERR_IPE 0x40000000 +#define E1000_RXDEXT_STATERR_RXE 0x80000000 + +#define E1000_RXDEXT_LSECH 0x01000000 +#define E1000_RXDEXT_LSECE_MASK 0x60000000 +#define E1000_RXDEXT_LSECE_NO_ERROR 0x00000000 +#define E1000_RXDEXT_LSECE_NO_SA_MATCH 0x20000000 +#define E1000_RXDEXT_LSECE_REPLAY_DETECT 0x40000000 +#define E1000_RXDEXT_LSECE_BAD_SIG 0x60000000 /* mask to determine if packets should be dropped due to frame errors */ #define E1000_RXD_ERR_FRAME_ERR_MASK ( \ - E1000_RXD_ERR_CE | \ - E1000_RXD_ERR_SE | \ - E1000_RXD_ERR_SEQ | \ - E1000_RXD_ERR_CXE | \ - E1000_RXD_ERR_RXE) + E1000_RXD_ERR_CE | \ + E1000_RXD_ERR_SE | \ + E1000_RXD_ERR_SEQ | \ + E1000_RXD_ERR_CXE | \ + E1000_RXD_ERR_RXE) /* Same mask, but for extended and packet split descriptors */ #define E1000_RXDEXT_ERR_FRAME_ERR_MASK ( \ - E1000_RXDEXT_STATERR_CE | \ - E1000_RXDEXT_STATERR_SE | \ - E1000_RXDEXT_STATERR_SEQ | \ - E1000_RXDEXT_STATERR_CXE | \ - E1000_RXDEXT_STATERR_RXE) - -#define E1000_MRQC_ENABLE_MASK 0x00000007 -#define E1000_MRQC_ENABLE_RSS_2Q 0x00000001 -#define E1000_MRQC_ENABLE_RSS_INT 0x00000004 -#define E1000_MRQC_RSS_FIELD_MASK 0xFFFF0000 -#define E1000_MRQC_RSS_FIELD_IPV4_TCP 0x00010000 -#define E1000_MRQC_RSS_FIELD_IPV4 0x00020000 -#define E1000_MRQC_RSS_FIELD_IPV6_TCP_EX 0x00040000 -#define E1000_MRQC_RSS_FIELD_IPV6_EX 0x00080000 -#define E1000_MRQC_RSS_FIELD_IPV6 0x00100000 -#define E1000_MRQC_RSS_FIELD_IPV6_TCP 0x00200000 - -#define E1000_RXDPS_HDRSTAT_HDRSP 0x00008000 -#define E1000_RXDPS_HDRSTAT_HDRLEN_MASK 0x000003FF + E1000_RXDEXT_STATERR_CE | \ + E1000_RXDEXT_STATERR_SE | \ + E1000_RXDEXT_STATERR_SEQ | \ + E1000_RXDEXT_STATERR_CXE | \ + E1000_RXDEXT_STATERR_RXE) + +#define E1000_MRQC_ENABLE_MASK 0x00000007 +#define E1000_MRQC_ENABLE_RSS_2Q 0x00000001 +#define E1000_MRQC_ENABLE_RSS_INT 0x00000004 +#define E1000_MRQC_RSS_FIELD_MASK 0xFFFF0000 +#define E1000_MRQC_RSS_FIELD_IPV4_TCP 0x00010000 +#define E1000_MRQC_RSS_FIELD_IPV4 0x00020000 +#define E1000_MRQC_RSS_FIELD_IPV6_TCP_EX 0x00040000 +#define E1000_MRQC_RSS_FIELD_IPV6_EX 0x00080000 +#define E1000_MRQC_RSS_FIELD_IPV6 0x00100000 +#define E1000_MRQC_RSS_FIELD_IPV6_TCP 0x00200000 + +#define E1000_RXDPS_HDRSTAT_HDRSP 0x00008000 +#define E1000_RXDPS_HDRSTAT_HDRLEN_MASK 0x000003FF /* Management Control */ -#define E1000_MANC_SMBUS_EN 0x00000001 /* SMBus Enabled - RO */ -#define E1000_MANC_ASF_EN 0x00000002 /* ASF Enabled - RO */ -#define E1000_MANC_R_ON_FORCE 0x00000004 /* Reset on Force TCO - RO */ -#define E1000_MANC_RMCP_EN 0x00000100 /* Enable RCMP 026Fh Filtering */ -#define E1000_MANC_0298_EN 0x00000200 /* Enable RCMP 0298h Filtering */ -#define E1000_MANC_IPV4_EN 0x00000400 /* Enable IPv4 */ -#define E1000_MANC_IPV6_EN 0x00000800 /* Enable IPv6 */ -#define E1000_MANC_SNAP_EN 0x00001000 /* Accept LLC/SNAP */ -#define E1000_MANC_ARP_EN 0x00002000 /* Enable ARP Request Filtering */ +#define E1000_MANC_SMBUS_EN 0x00000001 /* SMBus Enabled - RO */ +#define E1000_MANC_ASF_EN 0x00000002 /* ASF Enabled - RO */ +#define E1000_MANC_R_ON_FORCE 0x00000004 /* Reset on Force TCO - RO */ +#define E1000_MANC_RMCP_EN 0x00000100 /* Enable RCMP 026Fh Filtering */ +#define E1000_MANC_0298_EN 0x00000200 /* Enable RCMP 0298h Filtering */ +#define E1000_MANC_IPV4_EN 0x00000400 /* Enable IPv4 */ +#define E1000_MANC_IPV6_EN 0x00000800 /* Enable IPv6 */ +#define E1000_MANC_SNAP_EN 0x00001000 /* Accept LLC/SNAP */ +#define E1000_MANC_ARP_EN 0x00002000 /* Enable ARP Request Filtering */ /* Enable Neighbor Discovery Filtering */ -#define E1000_MANC_NEIGHBOR_EN 0x00004000 -#define E1000_MANC_ARP_RES_EN 0x00008000 /* Enable ARP response Filtering */ -#define E1000_MANC_TCO_RESET 0x00010000 /* TCO Reset Occurred */ -#define E1000_MANC_RCV_TCO_EN 0x00020000 /* Receive TCO Packets Enabled */ +#define E1000_MANC_NEIGHBOR_EN 0x00004000 +#define E1000_MANC_ARP_RES_EN 0x00008000 /* Enable ARP response Filtering */ +#define E1000_MANC_TCO_RESET 0x00010000 /* TCO Reset Occurred */ +#define E1000_MANC_RCV_TCO_EN 0x00020000 /* Receive TCO Packets Enabled */ #define E1000_MANC_REPORT_STATUS 0x00040000 /* Status Reporting Enabled */ -#define E1000_MANC_RCV_ALL 0x00080000 /* Receive All Enabled */ -#define E1000_MANC_BLK_PHY_RST_ON_IDE 0x00040000 /* Block phy resets */ +#define E1000_MANC_RCV_ALL 0x00080000 /* Receive All Enabled */ +#define E1000_MANC_BLK_PHY_RST_ON_IDE 0x00040000 /* Block phy resets */ /* Enable MAC address filtering */ -#define E1000_MANC_EN_MAC_ADDR_FILTER 0x00100000 +#define E1000_MANC_EN_MAC_ADDR_FILTER 0x00100000 /* Enable MNG packets to host memory */ -#define E1000_MANC_EN_MNG2HOST 0x00200000 +#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_SMB_REQ 0x01000000 /* SMBus Request */ -#define E1000_MANC_SMB_GNT 0x02000000 /* SMBus Grant */ -#define E1000_MANC_SMB_CLK_IN 0x04000000 /* SMBus Clock In */ -#define E1000_MANC_SMB_DATA_IN 0x08000000 /* SMBus Data In */ -#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_SMB_DATA_OUT_SHIFT 28 /* SMBus Data Out Shift */ -#define E1000_MANC_SMB_CLK_OUT_SHIFT 29 /* SMBus Clock Out Shift */ - -#define E1000_MANC2H_PORT_623 0x00000020 /* Port 0x26f */ -#define E1000_MANC2H_PORT_664 0x00000040 /* Port 0x298 */ -#define E1000_MDEF_PORT_623 0x00000800 /* Port 0x26f */ -#define E1000_MDEF_PORT_664 0x00000400 /* Port 0x298 */ +#define E1000_MANC_EN_IP_ADDR_FILTER 0x00400000 +#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 */ +#define E1000_MANC_SMB_DATA_IN 0x08000000 /* SMBus Data In */ +#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 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 */ + +#define E1000_MANC2H_PORT_623 0x00000020 /* Port 0x26f */ +#define E1000_MANC2H_PORT_664 0x00000040 /* Port 0x298 */ +#define E1000_MDEF_PORT_623 0x00000800 /* Port 0x26f */ +#define E1000_MDEF_PORT_664 0x00000400 /* Port 0x298 */ /* Receive Control */ -#define E1000_RCTL_RST 0x00000001 /* Software reset */ -#define E1000_RCTL_EN 0x00000002 /* enable */ -#define E1000_RCTL_SBP 0x00000004 /* store bad packet */ -#define E1000_RCTL_UPE 0x00000008 /* unicast promisc enable */ -#define E1000_RCTL_MPE 0x00000010 /* multicast promisc enable */ -#define E1000_RCTL_LPE 0x00000020 /* long packet enable */ -#define E1000_RCTL_LBM_NO 0x00000000 /* no loopback mode */ -#define E1000_RCTL_LBM_MAC 0x00000040 /* MAC loopback mode */ -#define E1000_RCTL_LBM_SLP 0x00000080 /* serial link loopback mode */ -#define E1000_RCTL_LBM_TCVR 0x000000C0 /* tcvr loopback mode */ -#define E1000_RCTL_DTYP_MASK 0x00000C00 /* Descriptor type mask */ -#define E1000_RCTL_DTYP_PS 0x00000400 /* Packet Split descriptor */ -#define E1000_RCTL_RDMTS_HALF 0x00000000 /* Rx desc min thresh size */ -#define E1000_RCTL_RDMTS_QUAT 0x00000100 /* Rx desc min thresh size */ -#define E1000_RCTL_RDMTS_EIGTH 0x00000200 /* Rx desc min thresh size */ -#define E1000_RCTL_MO_SHIFT 12 /* multicast offset shift */ -#define E1000_RCTL_MO_0 0x00000000 /* multicast offset 11:0 */ -#define E1000_RCTL_MO_1 0x00001000 /* multicast offset 12:1 */ -#define E1000_RCTL_MO_2 0x00002000 /* multicast offset 13:2 */ -#define E1000_RCTL_MO_3 0x00003000 /* multicast offset 15:4 */ -#define E1000_RCTL_MDR 0x00004000 /* multicast desc ring 0 */ -#define E1000_RCTL_BAM 0x00008000 /* broadcast enable */ +#define E1000_RCTL_RST 0x00000001 /* Software reset */ +#define E1000_RCTL_EN 0x00000002 /* enable */ +#define E1000_RCTL_SBP 0x00000004 /* store bad packet */ +#define E1000_RCTL_UPE 0x00000008 /* unicast promisc enable */ +#define E1000_RCTL_MPE 0x00000010 /* multicast promisc enable */ +#define E1000_RCTL_LPE 0x00000020 /* long packet enable */ +#define E1000_RCTL_LBM_NO 0x00000000 /* no loopback mode */ +#define E1000_RCTL_LBM_MAC 0x00000040 /* MAC loopback mode */ +#define E1000_RCTL_LBM_SLP 0x00000080 /* serial link loopback mode */ +#define E1000_RCTL_LBM_TCVR 0x000000C0 /* tcvr loopback mode */ +#define E1000_RCTL_DTYP_MASK 0x00000C00 /* Descriptor type mask */ +#define E1000_RCTL_DTYP_PS 0x00000400 /* Packet Split descriptor */ +#define E1000_RCTL_RDMTS_HALF 0x00000000 /* Rx desc min thresh size */ +#define E1000_RCTL_RDMTS_QUAT 0x00000100 /* Rx desc min thresh size */ +#define E1000_RCTL_RDMTS_EIGTH 0x00000200 /* Rx desc min thresh size */ +#define E1000_RCTL_MO_SHIFT 12 /* multicast offset shift */ +#define E1000_RCTL_MO_0 0x00000000 /* multicast offset 11:0 */ +#define E1000_RCTL_MO_1 0x00001000 /* multicast offset 12:1 */ +#define E1000_RCTL_MO_2 0x00002000 /* multicast offset 13:2 */ +#define E1000_RCTL_MO_3 0x00003000 /* multicast offset 15:4 */ +#define E1000_RCTL_MDR 0x00004000 /* multicast desc ring 0 */ +#define E1000_RCTL_BAM 0x00008000 /* broadcast enable */ /* these buffer sizes are valid if E1000_RCTL_BSEX is 0 */ -#define E1000_RCTL_SZ_2048 0x00000000 /* Rx buffer size 2048 */ -#define E1000_RCTL_SZ_1024 0x00010000 /* Rx buffer size 1024 */ -#define E1000_RCTL_SZ_512 0x00020000 /* Rx buffer size 512 */ -#define E1000_RCTL_SZ_256 0x00030000 /* Rx buffer size 256 */ +#define E1000_RCTL_SZ_2048 0x00000000 /* Rx buffer size 2048 */ +#define E1000_RCTL_SZ_1024 0x00010000 /* Rx buffer size 1024 */ +#define E1000_RCTL_SZ_512 0x00020000 /* Rx buffer size 512 */ +#define E1000_RCTL_SZ_256 0x00030000 /* Rx buffer size 256 */ /* these buffer sizes are valid if E1000_RCTL_BSEX is 1 */ -#define E1000_RCTL_SZ_16384 0x00010000 /* Rx buffer size 16384 */ -#define E1000_RCTL_SZ_8192 0x00020000 /* Rx buffer size 8192 */ -#define E1000_RCTL_SZ_4096 0x00030000 /* Rx buffer size 4096 */ -#define E1000_RCTL_VFE 0x00040000 /* vlan filter enable */ -#define E1000_RCTL_CFIEN 0x00080000 /* canonical form enable */ -#define E1000_RCTL_CFI 0x00100000 /* canonical form indicator */ -#define E1000_RCTL_DPF 0x00400000 /* discard pause frames */ -#define E1000_RCTL_PMCF 0x00800000 /* pass MAC control frames */ -#define E1000_RCTL_BSEX 0x02000000 /* Buffer size extension */ -#define E1000_RCTL_SECRC 0x04000000 /* Strip Ethernet CRC */ -#define E1000_RCTL_FLXBUF_MASK 0x78000000 /* Flexible buffer size */ -#define E1000_RCTL_FLXBUF_SHIFT 27 /* Flexible buffer shift */ +#define E1000_RCTL_SZ_16384 0x00010000 /* Rx buffer size 16384 */ +#define E1000_RCTL_SZ_8192 0x00020000 /* Rx buffer size 8192 */ +#define E1000_RCTL_SZ_4096 0x00030000 /* Rx buffer size 4096 */ +#define E1000_RCTL_VFE 0x00040000 /* vlan filter enable */ +#define E1000_RCTL_CFIEN 0x00080000 /* canonical form enable */ +#define E1000_RCTL_CFI 0x00100000 /* canonical form indicator */ +#define E1000_RCTL_DPF 0x00400000 /* discard pause frames */ +#define E1000_RCTL_PMCF 0x00800000 /* pass MAC control frames */ +#define E1000_RCTL_BSEX 0x02000000 /* Buffer size extension */ +#define E1000_RCTL_SECRC 0x04000000 /* Strip Ethernet CRC */ +#define E1000_RCTL_FLXBUF_MASK 0x78000000 /* Flexible buffer size */ +#define E1000_RCTL_FLXBUF_SHIFT 27 /* Flexible buffer shift */ /* * Use byte values for the following shift parameters * Usage: * psrctl |= (((ROUNDUP(value0, 128) >> E1000_PSRCTL_BSIZE0_SHIFT) & - * E1000_PSRCTL_BSIZE0_MASK) | - * ((ROUNDUP(value1, 1024) >> E1000_PSRCTL_BSIZE1_SHIFT) & - * E1000_PSRCTL_BSIZE1_MASK) | - * ((ROUNDUP(value2, 1024) << E1000_PSRCTL_BSIZE2_SHIFT) & - * E1000_PSRCTL_BSIZE2_MASK) | - * ((ROUNDUP(value3, 1024) << E1000_PSRCTL_BSIZE3_SHIFT) |; - * E1000_PSRCTL_BSIZE3_MASK)) + * E1000_PSRCTL_BSIZE0_MASK) | + * ((ROUNDUP(value1, 1024) >> E1000_PSRCTL_BSIZE1_SHIFT) & + * E1000_PSRCTL_BSIZE1_MASK) | + * ((ROUNDUP(value2, 1024) << E1000_PSRCTL_BSIZE2_SHIFT) & + * E1000_PSRCTL_BSIZE2_MASK) | + * ((ROUNDUP(value3, 1024) << E1000_PSRCTL_BSIZE3_SHIFT) |; + * E1000_PSRCTL_BSIZE3_MASK)) * where value0 = [128..16256], default=256 * value1 = [1024..64512], default=4096 * value2 = [0..64512], default=4096 * value3 = [0..64512], default=0 */ -#define E1000_PSRCTL_BSIZE0_MASK 0x0000007F -#define E1000_PSRCTL_BSIZE1_MASK 0x00003F00 -#define E1000_PSRCTL_BSIZE2_MASK 0x003F0000 -#define E1000_PSRCTL_BSIZE3_MASK 0x3F000000 +#define E1000_PSRCTL_BSIZE0_MASK 0x0000007F +#define E1000_PSRCTL_BSIZE1_MASK 0x00003F00 +#define E1000_PSRCTL_BSIZE2_MASK 0x003F0000 +#define E1000_PSRCTL_BSIZE3_MASK 0x3F000000 -#define E1000_PSRCTL_BSIZE0_SHIFT 7 /* Shift _right_ 7 */ -#define E1000_PSRCTL_BSIZE1_SHIFT 2 /* Shift _right_ 2 */ -#define E1000_PSRCTL_BSIZE2_SHIFT 6 /* Shift _left_ 6 */ -#define E1000_PSRCTL_BSIZE3_SHIFT 14 /* Shift _left_ 14 */ +#define E1000_PSRCTL_BSIZE0_SHIFT 7 /* Shift _right_ 7 */ +#define E1000_PSRCTL_BSIZE1_SHIFT 2 /* Shift _right_ 2 */ +#define E1000_PSRCTL_BSIZE2_SHIFT 6 /* Shift _left_ 6 */ +#define E1000_PSRCTL_BSIZE3_SHIFT 14 /* Shift _left_ 14 */ /* SWFW_SYNC Definitions */ -#define E1000_SWFW_EEP_SM 0x01 -#define E1000_SWFW_PHY0_SM 0x02 -#define E1000_SWFW_PHY1_SM 0x04 -#define E1000_SWFW_CSR_SM 0x08 -#define E1000_SWFW_PHY2_SM 0x20 -#define E1000_SWFW_PHY3_SM 0x40 -#define E1000_SWFW_SW_MNG_SM 0x400 +#define E1000_SWFW_EEP_SM 0x01 +#define E1000_SWFW_PHY0_SM 0x02 +#define E1000_SWFW_PHY1_SM 0x04 +#define E1000_SWFW_CSR_SM 0x08 +#define E1000_SWFW_PHY2_SM 0x20 +#define E1000_SWFW_PHY3_SM 0x40 +#define E1000_SWFW_SW_MNG_SM 0x400 /* FACTPS Definitions */ -#define E1000_FACTPS_LFS 0x40000000 /* LAN Function Select */ +#define E1000_FACTPS_LFS 0x40000000 /* LAN Function Select */ /* Device Control */ -#define E1000_CTRL_FD 0x00000001 /* Full duplex.0=half; 1=full */ -#define E1000_CTRL_BEM 0x00000002 /* Endian Mode.0=little,1=big */ -#define E1000_CTRL_PRIOR 0x00000004 /* Priority on PCI. 0=rx,1=fair */ +#define E1000_CTRL_FD 0x00000001 /* Full duplex.0=half; 1=full */ +#define E1000_CTRL_BEM 0x00000002 /* Endian Mode.0=little,1=big */ +#define E1000_CTRL_PRIOR 0x00000004 /* Priority on PCI. 0=rx,1=fair */ #define E1000_CTRL_GIO_MASTER_DISABLE 0x00000004 /*Blocks new Master reqs */ -#define E1000_CTRL_LRST 0x00000008 /* Link reset. 0=normal,1=reset */ -#define E1000_CTRL_TME 0x00000010 /* Test mode. 0=normal,1=test */ -#define E1000_CTRL_SLE 0x00000020 /* Serial Link on 0=dis,1=en */ -#define E1000_CTRL_ASDE 0x00000020 /* Auto-speed detect enable */ -#define E1000_CTRL_SLU 0x00000040 /* Set link up (Force Link) */ -#define E1000_CTRL_ILOS 0x00000080 /* Invert Loss-Of Signal */ -#define E1000_CTRL_SPD_SEL 0x00000300 /* Speed Select Mask */ -#define E1000_CTRL_SPD_10 0x00000000 /* Force 10Mb */ -#define E1000_CTRL_SPD_100 0x00000100 /* Force 100Mb */ -#define E1000_CTRL_SPD_1000 0x00000200 /* Force 1Gb */ -#define E1000_CTRL_BEM32 0x00000400 /* Big Endian 32 mode */ -#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 */ -#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 */ -#define E1000_CTRL_SWDPIN1 0x00080000 /* SWDPIN 1 value */ -#define E1000_CTRL_SWDPIN2 0x00100000 /* SWDPIN 2 value */ -#define E1000_CTRL_ADVD3WUC 0x00100000 /* D3 WUC */ -#define E1000_CTRL_SWDPIN3 0x00200000 /* SWDPIN 3 value */ -#define E1000_CTRL_SWDPIO0 0x00400000 /* SWDPIN 0 Input or output */ -#define E1000_CTRL_SWDPIO1 0x00800000 /* SWDPIN 1 input or output */ -#define E1000_CTRL_SWDPIO2 0x01000000 /* SWDPIN 2 input or output */ -#define E1000_CTRL_SWDPIO3 0x02000000 /* SWDPIN 3 input or output */ -#define E1000_CTRL_RST 0x04000000 /* Global reset */ -#define E1000_CTRL_RFCE 0x08000000 /* Receive Flow Control enable */ -#define E1000_CTRL_TFCE 0x10000000 /* Transmit flow control enable */ -#define E1000_CTRL_RTE 0x20000000 /* Routing tag enable */ -#define E1000_CTRL_VME 0x40000000 /* IEEE VLAN mode enable */ -#define E1000_CTRL_PHY_RST 0x80000000 /* PHY Reset */ -#define E1000_CTRL_SW2FW_INT 0x02000000 /* Initiate an interrupt to ME */ -#define E1000_CTRL_I2C_ENA 0x02000000 /* I2C enable */ +#define E1000_CTRL_LRST 0x00000008 /* Link reset. 0=normal,1=reset */ +#define E1000_CTRL_TME 0x00000010 /* Test mode. 0=normal,1=test */ +#define E1000_CTRL_SLE 0x00000020 /* Serial Link on 0=dis,1=en */ +#define E1000_CTRL_ASDE 0x00000020 /* Auto-speed detect enable */ +#define E1000_CTRL_SLU 0x00000040 /* Set link up (Force Link) */ +#define E1000_CTRL_ILOS 0x00000080 /* Invert Loss-Of Signal */ +#define E1000_CTRL_SPD_SEL 0x00000300 /* Speed Select Mask */ +#define E1000_CTRL_SPD_10 0x00000000 /* Force 10Mb */ +#define E1000_CTRL_SPD_100 0x00000100 /* Force 100Mb */ +#define E1000_CTRL_SPD_1000 0x00000200 /* Force 1Gb */ +#define E1000_CTRL_BEM32 0x00000400 /* Big Endian 32 mode */ +#define E1000_CTRL_FRCSPD 0x00000800 /* Force Speed */ +#define E1000_CTRL_FRCDPX 0x00001000 /* Force Duplex */ +#define E1000_CTRL_D_UD_EN 0x00002000 /* Dock/Undock enable */ +/* 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 */ +#define E1000_CTRL_SWDPIN1 0x00080000 /* SWDPIN 1 value */ +#define E1000_CTRL_SWDPIN2 0x00100000 /* SWDPIN 2 value */ +#define E1000_CTRL_ADVD3WUC 0x00100000 /* D3 WUC */ +#define E1000_CTRL_SWDPIN3 0x00200000 /* SWDPIN 3 value */ +#define E1000_CTRL_SWDPIO0 0x00400000 /* SWDPIN 0 Input or output */ +#define E1000_CTRL_SWDPIO1 0x00800000 /* SWDPIN 1 input or output */ +#define E1000_CTRL_SWDPIO2 0x01000000 /* SWDPIN 2 input or output */ +#define E1000_CTRL_SWDPIO3 0x02000000 /* SWDPIN 3 input or output */ +#define E1000_CTRL_RST 0x04000000 /* Global reset */ +#define E1000_CTRL_RFCE 0x08000000 /* Receive Flow Control enable */ +#define E1000_CTRL_TFCE 0x10000000 /* Transmit flow control enable */ +#define E1000_CTRL_RTE 0x20000000 /* Routing tag enable */ +#define E1000_CTRL_VME 0x40000000 /* IEEE VLAN mode enable */ +#define E1000_CTRL_PHY_RST 0x80000000 /* PHY Reset */ +#define E1000_CTRL_SW2FW_INT 0x02000000 /* Initiate an interrupt to ME */ +#define E1000_CTRL_I2C_ENA 0x02000000 /* I2C enable */ /* * Bit definitions for the Management Data IO (MDIO) and Management Data * Clock (MDC) pins in the Device Control Register. */ -#define E1000_CTRL_PHY_RESET_DIR E1000_CTRL_SWDPIO0 -#define E1000_CTRL_PHY_RESET E1000_CTRL_SWDPIN0 -#define E1000_CTRL_MDIO_DIR E1000_CTRL_SWDPIO2 -#define E1000_CTRL_MDIO E1000_CTRL_SWDPIN2 -#define E1000_CTRL_MDC_DIR E1000_CTRL_SWDPIO3 -#define E1000_CTRL_MDC E1000_CTRL_SWDPIN3 -#define E1000_CTRL_PHY_RESET_DIR4 E1000_CTRL_EXT_SDP4_DIR -#define E1000_CTRL_PHY_RESET4 E1000_CTRL_EXT_SDP4_DATA - -#define E1000_CONNSW_ENRGSRC 0x4 -#define E1000_PCS_CFG_PCS_EN 8 -#define E1000_PCS_LCTL_FLV_LINK_UP 1 -#define E1000_PCS_LCTL_FSV_10 0 -#define E1000_PCS_LCTL_FSV_100 2 -#define E1000_PCS_LCTL_FSV_1000 4 -#define E1000_PCS_LCTL_FDV_FULL 8 -#define E1000_PCS_LCTL_FSD 0x10 -#define E1000_PCS_LCTL_FORCE_LINK 0x20 -#define E1000_PCS_LCTL_LOW_LINK_LATCH 0x40 -#define E1000_PCS_LCTL_FORCE_FCTRL 0x80 -#define E1000_PCS_LCTL_AN_ENABLE 0x10000 -#define E1000_PCS_LCTL_AN_RESTART 0x20000 -#define E1000_PCS_LCTL_AN_TIMEOUT 0x40000 -#define E1000_PCS_LCTL_AN_SGMII_BYPASS 0x80000 -#define E1000_PCS_LCTL_AN_SGMII_TRIGGER 0x100000 -#define E1000_PCS_LCTL_FAST_LINK_TIMER 0x1000000 -#define E1000_PCS_LCTL_LINK_OK_FIX 0x2000000 -#define E1000_PCS_LCTL_CRS_ON_NI 0x4000000 -#define E1000_ENABLE_SERDES_LOOPBACK 0x0410 - -#define E1000_PCS_LSTS_LINK_OK 1 -#define E1000_PCS_LSTS_SPEED_10 0 -#define E1000_PCS_LSTS_SPEED_100 2 -#define E1000_PCS_LSTS_SPEED_1000 4 -#define E1000_PCS_LSTS_DUPLEX_FULL 8 -#define E1000_PCS_LSTS_SYNK_OK 0x10 -#define E1000_PCS_LSTS_AN_COMPLETE 0x10000 -#define E1000_PCS_LSTS_AN_PAGE_RX 0x20000 -#define E1000_PCS_LSTS_AN_TIMED_OUT 0x40000 -#define E1000_PCS_LSTS_AN_REMOTE_FAULT 0x80000 -#define E1000_PCS_LSTS_AN_ERROR_RWS 0x100000 +#define E1000_CTRL_PHY_RESET_DIR E1000_CTRL_SWDPIO0 +#define E1000_CTRL_PHY_RESET E1000_CTRL_SWDPIN0 +#define E1000_CTRL_MDIO_DIR E1000_CTRL_SWDPIO2 +#define E1000_CTRL_MDIO E1000_CTRL_SWDPIN2 +#define E1000_CTRL_MDC_DIR E1000_CTRL_SWDPIO3 +#define E1000_CTRL_MDC E1000_CTRL_SWDPIN3 +#define E1000_CTRL_PHY_RESET_DIR4 E1000_CTRL_EXT_SDP4_DIR +#define E1000_CTRL_PHY_RESET4 E1000_CTRL_EXT_SDP4_DATA + +#define E1000_CONNSW_ENRGSRC 0x4 +#define E1000_PCS_CFG_PCS_EN 8 +#define E1000_PCS_LCTL_FLV_LINK_UP 1 +#define E1000_PCS_LCTL_FSV_10 0 +#define E1000_PCS_LCTL_FSV_100 2 +#define E1000_PCS_LCTL_FSV_1000 4 +#define E1000_PCS_LCTL_FDV_FULL 8 +#define E1000_PCS_LCTL_FSD 0x10 +#define E1000_PCS_LCTL_FORCE_LINK 0x20 +#define E1000_PCS_LCTL_LOW_LINK_LATCH 0x40 +#define E1000_PCS_LCTL_FORCE_FCTRL 0x80 +#define E1000_PCS_LCTL_AN_ENABLE 0x10000 +#define E1000_PCS_LCTL_AN_RESTART 0x20000 +#define E1000_PCS_LCTL_AN_TIMEOUT 0x40000 +#define E1000_PCS_LCTL_AN_SGMII_BYPASS 0x80000 +#define E1000_PCS_LCTL_AN_SGMII_TRIGGER 0x100000 +#define E1000_PCS_LCTL_FAST_LINK_TIMER 0x1000000 +#define E1000_PCS_LCTL_LINK_OK_FIX 0x2000000 +#define E1000_PCS_LCTL_CRS_ON_NI 0x4000000 +#define E1000_ENABLE_SERDES_LOOPBACK 0x0410 + +#define E1000_PCS_LSTS_LINK_OK 1 +#define E1000_PCS_LSTS_SPEED_10 0 +#define E1000_PCS_LSTS_SPEED_100 2 +#define E1000_PCS_LSTS_SPEED_1000 4 +#define E1000_PCS_LSTS_DUPLEX_FULL 8 +#define E1000_PCS_LSTS_SYNK_OK 0x10 +#define E1000_PCS_LSTS_AN_COMPLETE 0x10000 +#define E1000_PCS_LSTS_AN_PAGE_RX 0x20000 +#define E1000_PCS_LSTS_AN_TIMED_OUT 0x40000 +#define E1000_PCS_LSTS_AN_REMOTE_FAULT 0x80000 +#define E1000_PCS_LSTS_AN_ERROR_RWS 0x100000 /* Device Status */ -#define E1000_STATUS_FD 0x00000001 /* Full 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 -#define E1000_STATUS_FUNC_0 0x00000000 /* Function 0 */ -#define E1000_STATUS_FUNC_1 0x00000004 /* Function 1 */ -#define E1000_STATUS_TXOFF 0x00000010 /* transmission paused */ -#define E1000_STATUS_TBIMODE 0x00000020 /* TBI mode */ -#define E1000_STATUS_SPEED_MASK 0x000000C0 -#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_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'. */ -#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_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 */ -#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_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 +#define E1000_STATUS_FUNC_0 0x00000000 /* Function 0 */ +#define E1000_STATUS_FUNC_1 0x00000004 /* Function 1 */ +#define E1000_STATUS_TXOFF 0x00000010 /* transmission paused */ +#define E1000_STATUS_TBIMODE 0x00000020 /* TBI mode */ +#define E1000_STATUS_SPEED_MASK 0x000000C0 +#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 Compltn by NVM */ +#define E1000_STATUS_ASDV 0x00000300 /* Auto speed detect value */ +#define E1000_STATUS_PHYRA 0x00000400 /* PHY Reset Asserted */ +/* 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 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 */ +/* 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 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 -#define SPEED_1000 1000 -#define HALF_DUPLEX 1 -#define FULL_DUPLEX 2 +#define SPEED_10 10 +#define SPEED_100 100 +#define SPEED_1000 1000 +#define HALF_DUPLEX 1 +#define FULL_DUPLEX 2 -#define PHY_FORCE_TIME 20 +#define PHY_FORCE_TIME 20 -#define ADVERTISE_10_HALF 0x0001 -#define ADVERTISE_10_FULL 0x0002 -#define ADVERTISE_100_HALF 0x0004 -#define ADVERTISE_100_FULL 0x0008 -#define ADVERTISE_1000_HALF 0x0010 /* Not used, just FYI */ -#define ADVERTISE_1000_FULL 0x0020 +#define ADVERTISE_10_HALF 0x0001 +#define ADVERTISE_10_FULL 0x0002 +#define ADVERTISE_100_HALF 0x0004 +#define ADVERTISE_100_FULL 0x0008 +#define ADVERTISE_1000_HALF 0x0010 /* Not used, just FYI */ +#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_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_HALF_DUPLEX (ADVERTISE_10_HALF | ADVERTISE_100_HALF) - -#define AUTONEG_ADVERTISE_SPEED_DEFAULT E1000_ALL_SPEED_DUPLEX +#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_HALF_DUPLEX (ADVERTISE_10_HALF | ADVERTISE_100_HALF) + +#define AUTONEG_ADVERTISE_SPEED_DEFAULT E1000_ALL_SPEED_DUPLEX /* LED Control */ -#define E1000_PHY_LED0_MODE_MASK 0x00000007 -#define E1000_PHY_LED0_IVRT 0x00000008 -#define E1000_PHY_LED0_BLINK 0x00000010 -#define E1000_PHY_LED0_MASK 0x0000001F - -#define E1000_LEDCTL_LED0_MODE_MASK 0x0000000F -#define E1000_LEDCTL_LED0_MODE_SHIFT 0 -#define E1000_LEDCTL_LED0_BLINK_RATE 0x00000020 -#define E1000_LEDCTL_LED0_IVRT 0x00000040 -#define E1000_LEDCTL_LED0_BLINK 0x00000080 -#define E1000_LEDCTL_LED1_MODE_MASK 0x00000F00 -#define E1000_LEDCTL_LED1_MODE_SHIFT 8 -#define E1000_LEDCTL_LED1_BLINK_RATE 0x00002000 -#define E1000_LEDCTL_LED1_IVRT 0x00004000 -#define E1000_LEDCTL_LED1_BLINK 0x00008000 -#define E1000_LEDCTL_LED2_MODE_MASK 0x000F0000 -#define E1000_LEDCTL_LED2_MODE_SHIFT 16 -#define E1000_LEDCTL_LED2_BLINK_RATE 0x00200000 -#define E1000_LEDCTL_LED2_IVRT 0x00400000 -#define E1000_LEDCTL_LED2_BLINK 0x00800000 -#define E1000_LEDCTL_LED3_MODE_MASK 0x0F000000 -#define E1000_LEDCTL_LED3_MODE_SHIFT 24 -#define E1000_LEDCTL_LED3_BLINK_RATE 0x20000000 -#define E1000_LEDCTL_LED3_IVRT 0x40000000 -#define E1000_LEDCTL_LED3_BLINK 0x80000000 - -#define E1000_LEDCTL_MODE_LINK_10_1000 0x0 -#define E1000_LEDCTL_MODE_LINK_100_1000 0x1 -#define E1000_LEDCTL_MODE_LINK_UP 0x2 -#define E1000_LEDCTL_MODE_ACTIVITY 0x3 -#define E1000_LEDCTL_MODE_LINK_ACTIVITY 0x4 -#define E1000_LEDCTL_MODE_LINK_10 0x5 -#define E1000_LEDCTL_MODE_LINK_100 0x6 -#define E1000_LEDCTL_MODE_LINK_1000 0x7 -#define E1000_LEDCTL_MODE_PCIX_MODE 0x8 -#define E1000_LEDCTL_MODE_FULL_DUPLEX 0x9 -#define E1000_LEDCTL_MODE_COLLISION 0xA -#define E1000_LEDCTL_MODE_BUS_SPEED 0xB -#define E1000_LEDCTL_MODE_BUS_SIZE 0xC -#define E1000_LEDCTL_MODE_PAUSED 0xD -#define E1000_LEDCTL_MODE_LED_ON 0xE -#define E1000_LEDCTL_MODE_LED_OFF 0xF +#define E1000_PHY_LED0_MODE_MASK 0x00000007 +#define E1000_PHY_LED0_IVRT 0x00000008 +#define E1000_PHY_LED0_BLINK 0x00000010 +#define E1000_PHY_LED0_MASK 0x0000001F + +#define E1000_LEDCTL_LED0_MODE_MASK 0x0000000F +#define E1000_LEDCTL_LED0_MODE_SHIFT 0 +#define E1000_LEDCTL_LED0_BLINK_RATE 0x00000020 +#define E1000_LEDCTL_LED0_IVRT 0x00000040 +#define E1000_LEDCTL_LED0_BLINK 0x00000080 +#define E1000_LEDCTL_LED1_MODE_MASK 0x00000F00 +#define E1000_LEDCTL_LED1_MODE_SHIFT 8 +#define E1000_LEDCTL_LED1_BLINK_RATE 0x00002000 +#define E1000_LEDCTL_LED1_IVRT 0x00004000 +#define E1000_LEDCTL_LED1_BLINK 0x00008000 +#define E1000_LEDCTL_LED2_MODE_MASK 0x000F0000 +#define E1000_LEDCTL_LED2_MODE_SHIFT 16 +#define E1000_LEDCTL_LED2_BLINK_RATE 0x00200000 +#define E1000_LEDCTL_LED2_IVRT 0x00400000 +#define E1000_LEDCTL_LED2_BLINK 0x00800000 +#define E1000_LEDCTL_LED3_MODE_MASK 0x0F000000 +#define E1000_LEDCTL_LED3_MODE_SHIFT 24 +#define E1000_LEDCTL_LED3_BLINK_RATE 0x20000000 +#define E1000_LEDCTL_LED3_IVRT 0x40000000 +#define E1000_LEDCTL_LED3_BLINK 0x80000000 + +#define E1000_LEDCTL_MODE_LINK_10_1000 0x0 +#define E1000_LEDCTL_MODE_LINK_100_1000 0x1 +#define E1000_LEDCTL_MODE_LINK_UP 0x2 +#define E1000_LEDCTL_MODE_ACTIVITY 0x3 +#define E1000_LEDCTL_MODE_LINK_ACTIVITY 0x4 +#define E1000_LEDCTL_MODE_LINK_10 0x5 +#define E1000_LEDCTL_MODE_LINK_100 0x6 +#define E1000_LEDCTL_MODE_LINK_1000 0x7 +#define E1000_LEDCTL_MODE_PCIX_MODE 0x8 +#define E1000_LEDCTL_MODE_FULL_DUPLEX 0x9 +#define E1000_LEDCTL_MODE_COLLISION 0xA +#define E1000_LEDCTL_MODE_BUS_SPEED 0xB +#define E1000_LEDCTL_MODE_BUS_SIZE 0xC +#define E1000_LEDCTL_MODE_PAUSED 0xD +#define E1000_LEDCTL_MODE_LED_ON 0xE +#define E1000_LEDCTL_MODE_LED_OFF 0xF /* Transmit Descriptor bit definitions */ -#define E1000_TXD_DTYP_D 0x00100000 /* Data Descriptor */ -#define E1000_TXD_DTYP_C 0x00000000 /* Context Descriptor */ -#define E1000_TXD_POPTS_SHIFT 8 /* POPTS shift */ -#define E1000_TXD_POPTS_IXSM 0x01 /* Insert IP checksum */ -#define E1000_TXD_POPTS_TXSM 0x02 /* Insert TCP/UDP checksum */ -#define E1000_TXD_CMD_EOP 0x01000000 /* End of Packet */ -#define E1000_TXD_CMD_IFCS 0x02000000 /* Insert FCS (Ethernet CRC) */ -#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_VLE 0x40000000 /* Add VLAN tag */ -#define E1000_TXD_CMD_IDE 0x80000000 /* Enable Tidv register */ -#define E1000_TXD_STAT_DD 0x00000001 /* Descriptor Done */ -#define E1000_TXD_STAT_EC 0x00000002 /* Excess Collisions */ -#define E1000_TXD_STAT_LC 0x00000004 /* Late Collisions */ -#define E1000_TXD_STAT_TU 0x00000008 /* Transmit underrun */ -#define E1000_TXD_CMD_TCP 0x01000000 /* TCP packet */ -#define E1000_TXD_CMD_IP 0x02000000 /* IP packet */ -#define E1000_TXD_CMD_TSE 0x04000000 /* TCP Seg enable */ -#define E1000_TXD_STAT_TC 0x00000004 /* Tx Underrun */ +#define E1000_TXD_DTYP_D 0x00100000 /* Data Descriptor */ +#define E1000_TXD_DTYP_C 0x00000000 /* Context Descriptor */ +#define E1000_TXD_POPTS_SHIFT 8 /* POPTS shift */ +#define E1000_TXD_POPTS_IXSM 0x01 /* Insert IP checksum */ +#define E1000_TXD_POPTS_TXSM 0x02 /* Insert TCP/UDP checksum */ +#define E1000_TXD_CMD_EOP 0x01000000 /* End of Packet */ +#define E1000_TXD_CMD_IFCS 0x02000000 /* Insert FCS (Ethernet CRC) */ +#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 /* 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 */ +#define E1000_TXD_STAT_EC 0x00000002 /* Excess Collisions */ +#define E1000_TXD_STAT_LC 0x00000004 /* Late Collisions */ +#define E1000_TXD_STAT_TU 0x00000008 /* Transmit underrun */ +#define E1000_TXD_CMD_TCP 0x01000000 /* TCP packet */ +#define E1000_TXD_CMD_IP 0x02000000 /* IP packet */ +#define E1000_TXD_CMD_TSE 0x04000000 /* TCP Seg enable */ +#define E1000_TXD_STAT_TC 0x00000004 /* Tx Underrun */ /* Extended desc bits for Linksec and timesync */ -#define E1000_TXD_CMD_LINKSEC 0x10000000 /* Apply LinkSec on packet */ -#define E1000_TXD_EXTCMD_TSTAMP 0x00000010 /* IEEE1588 Timestamp packet */ +#define E1000_TXD_CMD_LINKSEC 0x10000000 /* Apply LinkSec on packet */ +#define E1000_TXD_EXTCMD_TSTAMP 0x00000010 /* IEEE1588 Timestamp packet */ /* Transmit Control */ -#define E1000_TCTL_RST 0x00000001 /* software reset */ -#define E1000_TCTL_EN 0x00000002 /* enable Tx */ -#define E1000_TCTL_BCE 0x00000004 /* busy check enable */ -#define E1000_TCTL_PSP 0x00000008 /* pad short packets */ -#define E1000_TCTL_CT 0x00000ff0 /* collision threshold */ -#define E1000_TCTL_COLD 0x003ff000 /* collision distance */ -#define E1000_TCTL_SWXOFF 0x00400000 /* SW Xoff transmission */ -#define E1000_TCTL_PBE 0x00800000 /* Packet Burst Enable */ -#define E1000_TCTL_RTLC 0x01000000 /* Re-transmit on late collision */ -#define E1000_TCTL_NRTU 0x02000000 /* No Re-transmit on underrun */ -#define E1000_TCTL_MULR 0x10000000 /* Multiple request support */ +#define E1000_TCTL_RST 0x00000001 /* software reset */ +#define E1000_TCTL_EN 0x00000002 /* enable Tx */ +#define E1000_TCTL_BCE 0x00000004 /* busy check enable */ +#define E1000_TCTL_PSP 0x00000008 /* pad short packets */ +#define E1000_TCTL_CT 0x00000ff0 /* collision threshold */ +#define E1000_TCTL_COLD 0x003ff000 /* collision distance */ +#define E1000_TCTL_SWXOFF 0x00400000 /* SW Xoff transmission */ +#define E1000_TCTL_PBE 0x00800000 /* Packet Burst Enable */ +#define E1000_TCTL_RTLC 0x01000000 /* Re-transmit on late collision */ +#define E1000_TCTL_NRTU 0x02000000 /* No Re-transmit on underrun */ +#define E1000_TCTL_MULR 0x10000000 /* Multiple request support */ /* Transmit Arbitration Count */ -#define E1000_TARC0_ENABLE 0x00000400 /* Enable Tx Queue 0 */ +#define E1000_TARC0_ENABLE 0x00000400 /* Enable Tx Queue 0 */ /* SerDes Control */ -#define E1000_SCTL_DISABLE_SERDES_LOOPBACK 0x0400 +#define E1000_SCTL_DISABLE_SERDES_LOOPBACK 0x0400 /* Receive Checksum Control */ -#define E1000_RXCSUM_PCSS_MASK 0x000000FF /* Packet Checksum Start */ -#define E1000_RXCSUM_IPOFL 0x00000100 /* IPv4 checksum offload */ -#define E1000_RXCSUM_TUOFL 0x00000200 /* TCP / UDP checksum offload */ -#define E1000_RXCSUM_IPV6OFL 0x00000400 /* IPv6 checksum offload */ -#define E1000_RXCSUM_CRCOFL 0x00000800 /* CRC32 offload enable */ -#define E1000_RXCSUM_IPPCSE 0x00001000 /* IP payload checksum enable */ -#define E1000_RXCSUM_PCSD 0x00002000 /* packet checksum disabled */ +#define E1000_RXCSUM_PCSS_MASK 0x000000FF /* Packet Checksum Start */ +#define E1000_RXCSUM_IPOFL 0x00000100 /* IPv4 checksum offload */ +#define E1000_RXCSUM_TUOFL 0x00000200 /* TCP / UDP checksum offload */ +#define E1000_RXCSUM_IPV6OFL 0x00000400 /* IPv6 checksum offload */ +#define E1000_RXCSUM_CRCOFL 0x00000800 /* CRC32 offload enable */ +#define E1000_RXCSUM_IPPCSE 0x00001000 /* IP payload checksum enable */ +#define E1000_RXCSUM_PCSD 0x00002000 /* packet checksum disabled */ /* Header split receive */ -#define E1000_RFCTL_ISCSI_DIS 0x00000001 -#define E1000_RFCTL_ISCSI_DWC_MASK 0x0000003E -#define E1000_RFCTL_ISCSI_DWC_SHIFT 1 -#define E1000_RFCTL_NFSW_DIS 0x00000040 -#define E1000_RFCTL_NFSR_DIS 0x00000080 -#define E1000_RFCTL_NFS_VER_MASK 0x00000300 -#define E1000_RFCTL_NFS_VER_SHIFT 8 -#define E1000_RFCTL_IPV6_DIS 0x00000400 -#define E1000_RFCTL_IPV6_XSUM_DIS 0x00000800 -#define E1000_RFCTL_ACK_DIS 0x00001000 -#define E1000_RFCTL_ACKD_DIS 0x00002000 -#define E1000_RFCTL_IPFRSP_DIS 0x00004000 -#define E1000_RFCTL_EXTEN 0x00008000 -#define E1000_RFCTL_IPV6_EX_DIS 0x00010000 -#define E1000_RFCTL_NEW_IPV6_EXT_DIS 0x00020000 -#define E1000_RFCTL_LEF 0x00040000 +#define E1000_RFCTL_ISCSI_DIS 0x00000001 +#define E1000_RFCTL_ISCSI_DWC_MASK 0x0000003E +#define E1000_RFCTL_ISCSI_DWC_SHIFT 1 +#define E1000_RFCTL_NFSW_DIS 0x00000040 +#define E1000_RFCTL_NFSR_DIS 0x00000080 +#define E1000_RFCTL_NFS_VER_MASK 0x00000300 +#define E1000_RFCTL_NFS_VER_SHIFT 8 +#define E1000_RFCTL_IPV6_DIS 0x00000400 +#define E1000_RFCTL_IPV6_XSUM_DIS 0x00000800 +#define E1000_RFCTL_ACK_DIS 0x00001000 +#define E1000_RFCTL_ACKD_DIS 0x00002000 +#define E1000_RFCTL_IPFRSP_DIS 0x00004000 +#define E1000_RFCTL_EXTEN 0x00008000 +#define E1000_RFCTL_IPV6_EX_DIS 0x00010000 +#define E1000_RFCTL_NEW_IPV6_EXT_DIS 0x00020000 +#define E1000_RFCTL_LEF 0x00040000 /* Collision related configuration parameters */ -#define E1000_COLLISION_THRESHOLD 15 -#define E1000_CT_SHIFT 4 -#define E1000_COLLISION_DISTANCE 63 -#define E1000_COLD_SHIFT 12 +#define E1000_COLLISION_THRESHOLD 15 +#define E1000_CT_SHIFT 4 +#define E1000_COLLISION_DISTANCE 63 +#define E1000_COLD_SHIFT 12 /* Default values for the transmit IPG register */ -#define DEFAULT_82542_TIPG_IPGT 10 -#define DEFAULT_82543_TIPG_IPGT_FIBER 9 -#define DEFAULT_82543_TIPG_IPGT_COPPER 8 +#define DEFAULT_82542_TIPG_IPGT 10 +#define DEFAULT_82543_TIPG_IPGT_FIBER 9 +#define DEFAULT_82543_TIPG_IPGT_COPPER 8 -#define E1000_TIPG_IPGT_MASK 0x000003FF -#define E1000_TIPG_IPGR1_MASK 0x000FFC00 -#define E1000_TIPG_IPGR2_MASK 0x3FF00000 +#define E1000_TIPG_IPGT_MASK 0x000003FF +#define E1000_TIPG_IPGR1_MASK 0x000FFC00 +#define E1000_TIPG_IPGR2_MASK 0x3FF00000 -#define DEFAULT_82542_TIPG_IPGR1 2 -#define DEFAULT_82543_TIPG_IPGR1 8 -#define E1000_TIPG_IPGR1_SHIFT 10 +#define DEFAULT_82542_TIPG_IPGR1 2 +#define DEFAULT_82543_TIPG_IPGR1 8 +#define E1000_TIPG_IPGR1_SHIFT 10 -#define DEFAULT_82542_TIPG_IPGR2 10 -#define DEFAULT_82543_TIPG_IPGR2 6 -#define DEFAULT_80003ES2LAN_TIPG_IPGR2 7 -#define E1000_TIPG_IPGR2_SHIFT 20 +#define DEFAULT_82542_TIPG_IPGR2 10 +#define DEFAULT_82543_TIPG_IPGR2 6 +#define DEFAULT_80003ES2LAN_TIPG_IPGR2 7 +#define E1000_TIPG_IPGR2_SHIFT 20 /* Ethertype field values */ -#define ETHERNET_IEEE_VLAN_TYPE 0x8100 /* 802.3ac packet */ +#define ETHERNET_IEEE_VLAN_TYPE 0x8100 /* 802.3ac packet */ -#define ETHERNET_FCS_SIZE 4 -#define MAX_JUMBO_FRAME_SIZE 0x3F00 +#define ETHERNET_FCS_SIZE 4 +#define MAX_JUMBO_FRAME_SIZE 0x3F00 /* Extended Configuration Control and Size */ -#define E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP 0x00000020 -#define E1000_EXTCNF_CTRL_LCD_WRITE_ENABLE 0x00000001 -#define E1000_EXTCNF_CTRL_OEM_WRITE_ENABLE 0x00000008 -#define E1000_EXTCNF_CTRL_SWFLAG 0x00000020 -#define E1000_EXTCNF_CTRL_GATE_PHY_CFG 0x00000080 -#define E1000_EXTCNF_SIZE_EXT_PCIE_LENGTH_MASK 0x00FF0000 -#define E1000_EXTCNF_SIZE_EXT_PCIE_LENGTH_SHIFT 16 -#define E1000_EXTCNF_CTRL_EXT_CNF_POINTER_MASK 0x0FFF0000 -#define E1000_EXTCNF_CTRL_EXT_CNF_POINTER_SHIFT 16 - -#define E1000_PHY_CTRL_SPD_EN 0x00000001 -#define E1000_PHY_CTRL_D0A_LPLU 0x00000002 -#define E1000_PHY_CTRL_NOND0A_LPLU 0x00000004 -#define E1000_PHY_CTRL_NOND0A_GBE_DISABLE 0x00000008 -#define E1000_PHY_CTRL_GBE_DISABLE 0x00000040 - -#define E1000_KABGTXD_BGSQLBIAS 0x00050000 +#define E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP 0x00000020 +#define E1000_EXTCNF_CTRL_LCD_WRITE_ENABLE 0x00000001 +#define E1000_EXTCNF_CTRL_OEM_WRITE_ENABLE 0x00000008 +#define E1000_EXTCNF_CTRL_SWFLAG 0x00000020 +#define E1000_EXTCNF_CTRL_GATE_PHY_CFG 0x00000080 +#define E1000_EXTCNF_SIZE_EXT_PCIE_LENGTH_MASK 0x00FF0000 +#define E1000_EXTCNF_SIZE_EXT_PCIE_LENGTH_SHIFT 16 +#define E1000_EXTCNF_CTRL_EXT_CNF_POINTER_MASK 0x0FFF0000 +#define E1000_EXTCNF_CTRL_EXT_CNF_POINTER_SHIFT 16 + +#define E1000_PHY_CTRL_SPD_EN 0x00000001 +#define E1000_PHY_CTRL_D0A_LPLU 0x00000002 +#define E1000_PHY_CTRL_NOND0A_LPLU 0x00000004 +#define E1000_PHY_CTRL_NOND0A_GBE_DISABLE 0x00000008 +#define E1000_PHY_CTRL_GBE_DISABLE 0x00000040 + +#define E1000_KABGTXD_BGSQLBIAS 0x00050000 /* PBA constants */ -#define E1000_PBA_6K 0x0006 /* 6KB */ -#define E1000_PBA_8K 0x0008 /* 8KB */ -#define E1000_PBA_10K 0x000A /* 10KB */ -#define E1000_PBA_12K 0x000C /* 12KB */ -#define E1000_PBA_14K 0x000E /* 14KB */ -#define E1000_PBA_16K 0x0010 /* 16KB */ -#define E1000_PBA_18K 0x0012 -#define E1000_PBA_20K 0x0014 -#define E1000_PBA_22K 0x0016 -#define E1000_PBA_24K 0x0018 -#define E1000_PBA_26K 0x001A -#define E1000_PBA_30K 0x001E -#define E1000_PBA_32K 0x0020 -#define E1000_PBA_34K 0x0022 -#define E1000_PBA_35K 0x0023 -#define E1000_PBA_38K 0x0026 -#define E1000_PBA_40K 0x0028 -#define E1000_PBA_48K 0x0030 /* 48KB */ -#define E1000_PBA_64K 0x0040 /* 64KB */ - -#define E1000_PBS_16K E1000_PBA_16K -#define E1000_PBS_24K E1000_PBA_24K - -#define IFS_MAX 80 -#define IFS_MIN 40 -#define IFS_RATIO 4 -#define IFS_STEP 10 -#define MIN_NUM_XMITS 1000 +#define E1000_PBA_6K 0x0006 /* 6KB */ +#define E1000_PBA_8K 0x0008 /* 8KB */ +#define E1000_PBA_10K 0x000A /* 10KB */ +#define E1000_PBA_12K 0x000C /* 12KB */ +#define E1000_PBA_14K 0x000E /* 14KB */ +#define E1000_PBA_16K 0x0010 /* 16KB */ +#define E1000_PBA_18K 0x0012 +#define E1000_PBA_20K 0x0014 +#define E1000_PBA_22K 0x0016 +#define E1000_PBA_24K 0x0018 +#define E1000_PBA_26K 0x001A +#define E1000_PBA_30K 0x001E +#define E1000_PBA_32K 0x0020 +#define E1000_PBA_34K 0x0022 +#define E1000_PBA_35K 0x0023 +#define E1000_PBA_38K 0x0026 +#define E1000_PBA_40K 0x0028 +#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 + +#define IFS_MAX 80 +#define IFS_MIN 40 +#define IFS_RATIO 4 +#define IFS_STEP 10 +#define MIN_NUM_XMITS 1000 /* SW Semaphore Register */ -#define E1000_SWSM_SMBI 0x00000001 /* Driver Semaphore bit */ -#define E1000_SWSM_SWESMBI 0x00000002 /* FW Semaphore bit */ -#define E1000_SWSM_WMNG 0x00000004 /* Wake MNG Clock */ -#define E1000_SWSM_DRV_LOAD 0x00000008 /* Driver Loaded Bit */ +#define E1000_SWSM_SMBI 0x00000001 /* Driver Semaphore bit */ +#define E1000_SWSM_SWESMBI 0x00000002 /* FW Semaphore bit */ +#define E1000_SWSM_WMNG 0x00000004 /* Wake MNG Clock */ +#define E1000_SWSM_DRV_LOAD 0x00000008 /* Driver Loaded Bit */ -#define E1000_SWSM2_LOCK 0x00000002 /* Secondary driver semaphore bit */ +#define E1000_SWSM2_LOCK 0x00000002 /* Secondary driver semaphore bit */ /* Interrupt Cause Read */ -#define E1000_ICR_TXDW 0x00000001 /* Transmit desc written back */ -#define E1000_ICR_TXQE 0x00000002 /* Transmit Queue empty */ -#define E1000_ICR_LSC 0x00000004 /* Link Status Change */ -#define E1000_ICR_RXSEQ 0x00000008 /* Rx sequence error */ -#define E1000_ICR_RXDMT0 0x00000010 /* Rx desc min. threshold (0) */ -#define E1000_ICR_RXO 0x00000040 /* Rx overrun */ -#define E1000_ICR_RXT0 0x00000080 /* Rx timer intr (ring 0) */ -#define E1000_ICR_VMMB 0x00000100 /* VM MB event */ -#define E1000_ICR_MDAC 0x00000200 /* MDIO access complete */ -#define E1000_ICR_RXCFG 0x00000400 /* Rx /c/ ordered set */ -#define E1000_ICR_GPI_EN0 0x00000800 /* GP Int 0 */ -#define E1000_ICR_GPI_EN1 0x00001000 /* GP Int 1 */ -#define E1000_ICR_GPI_EN2 0x00002000 /* GP Int 2 */ -#define E1000_ICR_GPI_EN3 0x00004000 /* GP Int 3 */ -#define E1000_ICR_TXD_LOW 0x00008000 -#define E1000_ICR_SRPD 0x00010000 -#define E1000_ICR_ACK 0x00020000 /* Receive Ack frame */ -#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 */ -#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 */ -#define E1000_ICR_PB_PAR 0x00800000 /* packet buffer parity error */ -#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 */ -#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 */ -#define E1000_ICR_RXQ1 0x00200000 /* Rx Queue 1 Interrupt */ -#define E1000_ICR_TXQ0 0x00400000 /* Tx Queue 0 Interrupt */ -#define E1000_ICR_TXQ1 0x00800000 /* Tx Queue 1 Interrupt */ -#define E1000_ICR_OTHER 0x01000000 /* Other Interrupts */ -#define E1000_ICR_FER 0x00400000 /* Fatal Error */ - -#define E1000_ICR_THS 0x00800000 /* ICR.THS: Thermal Sensor Event*/ -#define E1000_ICR_MDDET 0x10000000 /* Malicious Driver Detect */ +#define E1000_ICR_TXDW 0x00000001 /* Transmit desc written back */ +#define E1000_ICR_TXQE 0x00000002 /* Transmit Queue empty */ +#define E1000_ICR_LSC 0x00000004 /* Link Status Change */ +#define E1000_ICR_RXSEQ 0x00000008 /* Rx sequence error */ +#define E1000_ICR_RXDMT0 0x00000010 /* Rx desc min. threshold (0) */ +#define E1000_ICR_RXO 0x00000040 /* Rx overrun */ +#define E1000_ICR_RXT0 0x00000080 /* Rx timer intr (ring 0) */ +#define E1000_ICR_VMMB 0x00000100 /* VM MB event */ +#define E1000_ICR_MDAC 0x00000200 /* MDIO access complete */ +#define E1000_ICR_RXCFG 0x00000400 /* Rx /c/ ordered set */ +#define E1000_ICR_GPI_EN0 0x00000800 /* GP Int 0 */ +#define E1000_ICR_GPI_EN1 0x00001000 /* GP Int 1 */ +#define E1000_ICR_GPI_EN2 0x00002000 /* GP Int 2 */ +#define E1000_ICR_GPI_EN3 0x00004000 /* GP Int 3 */ +#define E1000_ICR_TXD_LOW 0x00008000 +#define E1000_ICR_SRPD 0x00010000 +#define E1000_ICR_ACK 0x00020000 /* Receive Ack frame */ +#define E1000_ICR_MNG 0x00040000 /* Manageability event */ +#define E1000_ICR_DOCK 0x00080000 /* Dock/Undock */ +#define E1000_ICR_DRSTA 0x40000000 /* Device Reset Asserted */ +/* 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 */ +#define E1000_ICR_PB_PAR 0x00800000 /* packet buffer parity error */ +#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 */ +/* 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 */ +#define E1000_ICR_RXQ1 0x00200000 /* Rx Queue 1 Interrupt */ +#define E1000_ICR_TXQ0 0x00400000 /* Tx Queue 0 Interrupt */ +#define E1000_ICR_TXQ1 0x00800000 /* Tx Queue 1 Interrupt */ +#define E1000_ICR_OTHER 0x01000000 /* Other Interrupts */ +#define E1000_ICR_FER 0x00400000 /* Fatal Error */ + +#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 */ -#define E1000_PBA_ECC_CORR_EN 0x00000001 /* Enable ECC error correction */ -#define E1000_PBA_ECC_STAT_CLR 0x00000002 /* Clear ECC error counter */ -#define E1000_PBA_ECC_INT_EN 0x00000004 /* Enable ICR bit 5 on ECC error */ +#define E1000_PBA_ECC_COUNTER_MASK 0xFFF00000 /* ECC counter mask */ +#define E1000_PBA_ECC_COUNTER_SHIFT 20 /* ECC counter shift value */ +#define E1000_PBA_ECC_CORR_EN 0x00000001 /* Enable ECC error correction */ +#define E1000_PBA_ECC_STAT_CLR 0x00000002 /* Clear ECC error counter */ +#define E1000_PBA_ECC_INT_EN 0x00000004 /* Enable ICR bit 5 on ECC error */ /* Extended Interrupt Cause Read */ -#define E1000_EICR_RX_QUEUE0 0x00000001 /* Rx Queue 0 Interrupt */ -#define E1000_EICR_RX_QUEUE1 0x00000002 /* Rx Queue 1 Interrupt */ -#define E1000_EICR_RX_QUEUE2 0x00000004 /* Rx Queue 2 Interrupt */ -#define E1000_EICR_RX_QUEUE3 0x00000008 /* Rx Queue 3 Interrupt */ -#define E1000_EICR_TX_QUEUE0 0x00000100 /* Tx Queue 0 Interrupt */ -#define E1000_EICR_TX_QUEUE1 0x00000200 /* Tx Queue 1 Interrupt */ -#define E1000_EICR_TX_QUEUE2 0x00000400 /* Tx Queue 2 Interrupt */ -#define E1000_EICR_TX_QUEUE3 0x00000800 /* Tx Queue 3 Interrupt */ -#define E1000_EICR_TCP_TIMER 0x40000000 /* TCP Timer */ -#define E1000_EICR_OTHER 0x80000000 /* Interrupt Cause Active */ +#define E1000_EICR_RX_QUEUE0 0x00000001 /* Rx Queue 0 Interrupt */ +#define E1000_EICR_RX_QUEUE1 0x00000002 /* Rx Queue 1 Interrupt */ +#define E1000_EICR_RX_QUEUE2 0x00000004 /* Rx Queue 2 Interrupt */ +#define E1000_EICR_RX_QUEUE3 0x00000008 /* Rx Queue 3 Interrupt */ +#define E1000_EICR_TX_QUEUE0 0x00000100 /* Tx Queue 0 Interrupt */ +#define E1000_EICR_TX_QUEUE1 0x00000200 /* Tx Queue 1 Interrupt */ +#define E1000_EICR_TX_QUEUE2 0x00000400 /* Tx Queue 2 Interrupt */ +#define E1000_EICR_TX_QUEUE3 0x00000800 /* Tx Queue 3 Interrupt */ +#define E1000_EICR_TCP_TIMER 0x40000000 /* TCP Timer */ +#define E1000_EICR_OTHER 0x80000000 /* Interrupt Cause Active */ /* TCP Timer */ -#define E1000_TCPTIMER_KS 0x00000100 /* KickStart */ -#define E1000_TCPTIMER_COUNT_ENABLE 0x00000200 /* Count Enable */ -#define E1000_TCPTIMER_COUNT_FINISH 0x00000400 /* Count finish */ -#define E1000_TCPTIMER_LOOP 0x00000800 /* Loop */ +#define E1000_TCPTIMER_KS 0x00000100 /* KickStart */ +#define E1000_TCPTIMER_COUNT_ENABLE 0x00000200 /* Count Enable */ +#define E1000_TCPTIMER_COUNT_FINISH 0x00000400 /* Count finish */ +#define E1000_TCPTIMER_LOOP 0x00000800 /* Loop */ /* * This defines the bits that are set in the Interrupt Mask @@ -858,8 +869,8 @@ * o RXSEQ = Receive Sequence Error */ #define POLL_IMS_ENABLE_MASK ( \ - E1000_IMS_RXDMT0 | \ - E1000_IMS_RXSEQ) + E1000_IMS_RXDMT0 | \ + E1000_IMS_RXSEQ) /* * This defines the bits that are set in the Interrupt Mask @@ -871,142 +882,142 @@ * o LSC = Link Status Change */ #define IMS_ENABLE_MASK ( \ - E1000_IMS_RXT0 | \ - E1000_IMS_TXDW | \ - E1000_IMS_RXDMT0 | \ - E1000_IMS_RXSEQ | \ - E1000_IMS_LSC) + E1000_IMS_RXT0 | \ + E1000_IMS_TXDW | \ + E1000_IMS_RXDMT0 | \ + E1000_IMS_RXSEQ | \ + E1000_IMS_LSC) /* Interrupt Mask Set */ -#define E1000_IMS_TXDW E1000_ICR_TXDW /* Tx desc written back */ -#define E1000_IMS_TXQE E1000_ICR_TXQE /* Transmit Queue empty */ -#define E1000_IMS_LSC E1000_ICR_LSC /* Link Status Change */ -#define E1000_IMS_VMMB E1000_ICR_VMMB /* Mail box activity */ -#define E1000_IMS_RXSEQ E1000_ICR_RXSEQ /* Rx sequence error */ -#define E1000_IMS_RXDMT0 E1000_ICR_RXDMT0 /* Rx desc min. threshold */ -#define E1000_IMS_RXO E1000_ICR_RXO /* Rx overrun */ -#define E1000_IMS_RXT0 E1000_ICR_RXT0 /* Rx timer intr */ -#define E1000_IMS_MDAC E1000_ICR_MDAC /* MDIO access complete */ -#define E1000_IMS_RXCFG E1000_ICR_RXCFG /* Rx /c/ ordered set */ -#define E1000_IMS_GPI_EN0 E1000_ICR_GPI_EN0 /* GP Int 0 */ -#define E1000_IMS_GPI_EN1 E1000_ICR_GPI_EN1 /* GP Int 1 */ -#define E1000_IMS_GPI_EN2 E1000_ICR_GPI_EN2 /* GP Int 2 */ -#define E1000_IMS_GPI_EN3 E1000_ICR_GPI_EN3 /* GP Int 3 */ -#define E1000_IMS_TXD_LOW E1000_ICR_TXD_LOW -#define E1000_IMS_SRPD E1000_ICR_SRPD -#define E1000_IMS_ACK E1000_ICR_ACK /* Receive Ack frame */ -#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 */ -#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 */ -#define E1000_IMS_EPRST E1000_ICR_EPRST -#define E1000_IMS_RXQ0 E1000_ICR_RXQ0 /* Rx Queue 0 Interrupt */ -#define E1000_IMS_RXQ1 E1000_ICR_RXQ1 /* Rx Queue 1 Interrupt */ -#define E1000_IMS_TXQ0 E1000_ICR_TXQ0 /* Tx Queue 0 Interrupt */ -#define E1000_IMS_TXQ1 E1000_ICR_TXQ1 /* Tx Queue 1 Interrupt */ -#define E1000_IMS_OTHER E1000_ICR_OTHER /* Other Interrupts */ -#define E1000_IMS_FER E1000_ICR_FER /* Fatal Error */ - -#define E1000_IMS_THS E1000_ICR_THS /* ICR.TS: Thermal Sensor Event*/ -#define E1000_IMS_MDDET E1000_ICR_MDDET /* Malicious Driver Detect */ +#define E1000_IMS_TXDW E1000_ICR_TXDW /* Tx desc written back */ +#define E1000_IMS_TXQE E1000_ICR_TXQE /* Transmit Queue empty */ +#define E1000_IMS_LSC E1000_ICR_LSC /* Link Status Change */ +#define E1000_IMS_VMMB E1000_ICR_VMMB /* Mail box activity */ +#define E1000_IMS_RXSEQ E1000_ICR_RXSEQ /* Rx sequence error */ +#define E1000_IMS_RXDMT0 E1000_ICR_RXDMT0 /* Rx desc min. threshold */ +#define E1000_IMS_RXO E1000_ICR_RXO /* Rx overrun */ +#define E1000_IMS_RXT0 E1000_ICR_RXT0 /* Rx timer intr */ +#define E1000_IMS_MDAC E1000_ICR_MDAC /* MDIO access complete */ +#define E1000_IMS_RXCFG E1000_ICR_RXCFG /* Rx /c/ ordered set */ +#define E1000_IMS_GPI_EN0 E1000_ICR_GPI_EN0 /* GP Int 0 */ +#define E1000_IMS_GPI_EN1 E1000_ICR_GPI_EN1 /* GP Int 1 */ +#define E1000_IMS_GPI_EN2 E1000_ICR_GPI_EN2 /* GP Int 2 */ +#define E1000_IMS_GPI_EN3 E1000_ICR_GPI_EN3 /* GP Int 3 */ +#define E1000_IMS_TXD_LOW E1000_ICR_TXD_LOW +#define E1000_IMS_SRPD E1000_ICR_SRPD +#define E1000_IMS_ACK E1000_ICR_ACK /* Receive Ack frame */ +#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 */ +/* 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 */ +#define E1000_IMS_EPRST E1000_ICR_EPRST +#define E1000_IMS_RXQ0 E1000_ICR_RXQ0 /* Rx Queue 0 Interrupt */ +#define E1000_IMS_RXQ1 E1000_ICR_RXQ1 /* Rx Queue 1 Interrupt */ +#define E1000_IMS_TXQ0 E1000_ICR_TXQ0 /* Tx Queue 0 Interrupt */ +#define E1000_IMS_TXQ1 E1000_ICR_TXQ1 /* Tx Queue 1 Interrupt */ +#define E1000_IMS_OTHER E1000_ICR_OTHER /* Other Interrupts */ +#define E1000_IMS_FER E1000_ICR_FER /* Fatal Error */ + +#define E1000_IMS_THS E1000_ICR_THS /* ICR.TS: Thermal Sensor Event*/ +#define E1000_IMS_MDDET E1000_ICR_MDDET /* Malicious Driver Detect */ /* Extended Interrupt Mask Set */ -#define E1000_EIMS_RX_QUEUE0 E1000_EICR_RX_QUEUE0 /* Rx Queue 0 Interrupt */ -#define E1000_EIMS_RX_QUEUE1 E1000_EICR_RX_QUEUE1 /* Rx Queue 1 Interrupt */ -#define E1000_EIMS_RX_QUEUE2 E1000_EICR_RX_QUEUE2 /* Rx Queue 2 Interrupt */ -#define E1000_EIMS_RX_QUEUE3 E1000_EICR_RX_QUEUE3 /* Rx Queue 3 Interrupt */ -#define E1000_EIMS_TX_QUEUE0 E1000_EICR_TX_QUEUE0 /* Tx Queue 0 Interrupt */ -#define E1000_EIMS_TX_QUEUE1 E1000_EICR_TX_QUEUE1 /* Tx Queue 1 Interrupt */ -#define E1000_EIMS_TX_QUEUE2 E1000_EICR_TX_QUEUE2 /* Tx Queue 2 Interrupt */ -#define E1000_EIMS_TX_QUEUE3 E1000_EICR_TX_QUEUE3 /* Tx Queue 3 Interrupt */ -#define E1000_EIMS_TCP_TIMER E1000_EICR_TCP_TIMER /* TCP Timer */ -#define E1000_EIMS_OTHER E1000_EICR_OTHER /* Interrupt Cause Active */ +#define E1000_EIMS_RX_QUEUE0 E1000_EICR_RX_QUEUE0 /* Rx Queue 0 Interrupt */ +#define E1000_EIMS_RX_QUEUE1 E1000_EICR_RX_QUEUE1 /* Rx Queue 1 Interrupt */ +#define E1000_EIMS_RX_QUEUE2 E1000_EICR_RX_QUEUE2 /* Rx Queue 2 Interrupt */ +#define E1000_EIMS_RX_QUEUE3 E1000_EICR_RX_QUEUE3 /* Rx Queue 3 Interrupt */ +#define E1000_EIMS_TX_QUEUE0 E1000_EICR_TX_QUEUE0 /* Tx Queue 0 Interrupt */ +#define E1000_EIMS_TX_QUEUE1 E1000_EICR_TX_QUEUE1 /* Tx Queue 1 Interrupt */ +#define E1000_EIMS_TX_QUEUE2 E1000_EICR_TX_QUEUE2 /* Tx Queue 2 Interrupt */ +#define E1000_EIMS_TX_QUEUE3 E1000_EICR_TX_QUEUE3 /* Tx Queue 3 Interrupt */ +#define E1000_EIMS_TCP_TIMER E1000_EICR_TCP_TIMER /* TCP Timer */ +#define E1000_EIMS_OTHER E1000_EICR_OTHER /* Interrupt Cause Active */ /* Interrupt Cause Set */ -#define E1000_ICS_TXDW E1000_ICR_TXDW /* Tx desc written back */ -#define E1000_ICS_TXQE E1000_ICR_TXQE /* Transmit Queue empty */ -#define E1000_ICS_LSC E1000_ICR_LSC /* Link Status Change */ -#define E1000_ICS_RXSEQ E1000_ICR_RXSEQ /* Rx sequence error */ -#define E1000_ICS_RXDMT0 E1000_ICR_RXDMT0 /* Rx desc min. threshold */ -#define E1000_ICS_RXO E1000_ICR_RXO /* Rx overrun */ -#define E1000_ICS_RXT0 E1000_ICR_RXT0 /* Rx timer intr */ -#define E1000_ICS_MDAC E1000_ICR_MDAC /* MDIO access complete */ -#define E1000_ICS_RXCFG E1000_ICR_RXCFG /* Rx /c/ ordered set */ -#define E1000_ICS_GPI_EN0 E1000_ICR_GPI_EN0 /* GP Int 0 */ -#define E1000_ICS_GPI_EN1 E1000_ICR_GPI_EN1 /* GP Int 1 */ -#define E1000_ICS_GPI_EN2 E1000_ICR_GPI_EN2 /* GP Int 2 */ -#define E1000_ICS_GPI_EN3 E1000_ICR_GPI_EN3 /* GP Int 3 */ -#define E1000_ICS_TXD_LOW E1000_ICR_TXD_LOW -#define E1000_ICS_SRPD E1000_ICR_SRPD -#define E1000_ICS_ACK E1000_ICR_ACK /* Receive Ack frame */ -#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 */ -#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 -#define E1000_ICS_EPRST E1000_ICR_EPRST +#define E1000_ICS_TXDW E1000_ICR_TXDW /* Tx desc written back */ +#define E1000_ICS_TXQE E1000_ICR_TXQE /* Transmit Queue empty */ +#define E1000_ICS_LSC E1000_ICR_LSC /* Link Status Change */ +#define E1000_ICS_RXSEQ E1000_ICR_RXSEQ /* Rx sequence error */ +#define E1000_ICS_RXDMT0 E1000_ICR_RXDMT0 /* Rx desc min. threshold */ +#define E1000_ICS_RXO E1000_ICR_RXO /* Rx overrun */ +#define E1000_ICS_RXT0 E1000_ICR_RXT0 /* Rx timer intr */ +#define E1000_ICS_MDAC E1000_ICR_MDAC /* MDIO access complete */ +#define E1000_ICS_RXCFG E1000_ICR_RXCFG /* Rx /c/ ordered set */ +#define E1000_ICS_GPI_EN0 E1000_ICR_GPI_EN0 /* GP Int 0 */ +#define E1000_ICS_GPI_EN1 E1000_ICR_GPI_EN1 /* GP Int 1 */ +#define E1000_ICS_GPI_EN2 E1000_ICR_GPI_EN2 /* GP Int 2 */ +#define E1000_ICS_GPI_EN3 E1000_ICR_GPI_EN3 /* GP Int 3 */ +#define E1000_ICS_TXD_LOW E1000_ICR_TXD_LOW +#define E1000_ICS_SRPD E1000_ICR_SRPD +#define E1000_ICS_ACK E1000_ICR_ACK /* Receive Ack frame */ +#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 */ +/* 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 +#define E1000_ICS_EPRST E1000_ICR_EPRST /* Extended Interrupt Cause Set */ -#define E1000_EICS_RX_QUEUE0 E1000_EICR_RX_QUEUE0 /* Rx Queue 0 Interrupt */ -#define E1000_EICS_RX_QUEUE1 E1000_EICR_RX_QUEUE1 /* Rx Queue 1 Interrupt */ -#define E1000_EICS_RX_QUEUE2 E1000_EICR_RX_QUEUE2 /* Rx Queue 2 Interrupt */ -#define E1000_EICS_RX_QUEUE3 E1000_EICR_RX_QUEUE3 /* Rx Queue 3 Interrupt */ -#define E1000_EICS_TX_QUEUE0 E1000_EICR_TX_QUEUE0 /* Tx Queue 0 Interrupt */ -#define E1000_EICS_TX_QUEUE1 E1000_EICR_TX_QUEUE1 /* Tx Queue 1 Interrupt */ -#define E1000_EICS_TX_QUEUE2 E1000_EICR_TX_QUEUE2 /* Tx Queue 2 Interrupt */ -#define E1000_EICS_TX_QUEUE3 E1000_EICR_TX_QUEUE3 /* Tx Queue 3 Interrupt */ -#define E1000_EICS_TCP_TIMER E1000_EICR_TCP_TIMER /* TCP Timer */ -#define E1000_EICS_OTHER E1000_EICR_OTHER /* Interrupt Cause Active */ - -#define E1000_EITR_ITR_INT_MASK 0x0000FFFF +#define E1000_EICS_RX_QUEUE0 E1000_EICR_RX_QUEUE0 /* Rx Queue 0 Interrupt */ +#define E1000_EICS_RX_QUEUE1 E1000_EICR_RX_QUEUE1 /* Rx Queue 1 Interrupt */ +#define E1000_EICS_RX_QUEUE2 E1000_EICR_RX_QUEUE2 /* Rx Queue 2 Interrupt */ +#define E1000_EICS_RX_QUEUE3 E1000_EICR_RX_QUEUE3 /* Rx Queue 3 Interrupt */ +#define E1000_EICS_TX_QUEUE0 E1000_EICR_TX_QUEUE0 /* Tx Queue 0 Interrupt */ +#define E1000_EICS_TX_QUEUE1 E1000_EICR_TX_QUEUE1 /* Tx Queue 1 Interrupt */ +#define E1000_EICS_TX_QUEUE2 E1000_EICR_TX_QUEUE2 /* Tx Queue 2 Interrupt */ +#define E1000_EICS_TX_QUEUE3 E1000_EICR_TX_QUEUE3 /* Tx Queue 3 Interrupt */ +#define E1000_EICS_TCP_TIMER E1000_EICR_TCP_TIMER /* TCP Timer */ +#define E1000_EICS_OTHER E1000_EICR_OTHER /* Interrupt Cause Active */ + +#define E1000_EITR_ITR_INT_MASK 0x0000FFFF /* E1000_EITR_CNT_IGNR is only for 82576 and newer */ -#define E1000_EITR_CNT_IGNR 0x80000000 /* Don't reset counters on write */ +#define E1000_EITR_CNT_IGNR 0x80000000 /* Don't reset counters on write */ /* Transmit Descriptor Control */ -#define E1000_TXDCTL_PTHRESH 0x0000003F /* TXDCTL Prefetch Threshold */ -#define E1000_TXDCTL_HTHRESH 0x00003F00 /* TXDCTL Host Threshold */ -#define E1000_TXDCTL_WTHRESH 0x003F0000 /* TXDCTL Writeback Threshold */ -#define E1000_TXDCTL_GRAN 0x01000000 /* TXDCTL Granularity */ -#define E1000_TXDCTL_LWTHRESH 0xFE000000 /* TXDCTL Low Threshold */ -#define E1000_TXDCTL_FULL_TX_DESC_WB 0x01010000 /* GRAN=1, WTHRESH=1 */ +#define E1000_TXDCTL_PTHRESH 0x0000003F /* TXDCTL Prefetch Threshold */ +#define E1000_TXDCTL_HTHRESH 0x00003F00 /* TXDCTL Host Threshold */ +#define E1000_TXDCTL_WTHRESH 0x003F0000 /* TXDCTL Writeback Threshold */ +#define E1000_TXDCTL_GRAN 0x01000000 /* TXDCTL Granularity */ +#define E1000_TXDCTL_LWTHRESH 0xFE000000 /* TXDCTL Low Threshold */ +#define E1000_TXDCTL_FULL_TX_DESC_WB 0x01010000 /* GRAN=1, WTHRESH=1 */ #define E1000_TXDCTL_MAX_TX_DESC_PREFETCH 0x0100001F /* GRAN=1, PTHRESH=31 */ /* Enable the counting of descriptors still to be processed. */ -#define E1000_TXDCTL_COUNT_DESC 0x00400000 +#define E1000_TXDCTL_COUNT_DESC 0x00400000 /* Flow Control Constants */ -#define FLOW_CONTROL_ADDRESS_LOW 0x00C28001 -#define FLOW_CONTROL_ADDRESS_HIGH 0x00000100 -#define FLOW_CONTROL_TYPE 0x8808 +#define FLOW_CONTROL_ADDRESS_LOW 0x00C28001 +#define FLOW_CONTROL_ADDRESS_HIGH 0x00000100 +#define FLOW_CONTROL_TYPE 0x8808 /* 802.1q VLAN Packet Size */ -#define VLAN_TAG_SIZE 4 /* 802.3ac tag (not DMA'd) */ -#define E1000_VLAN_FILTER_TBL_SIZE 128 /* VLAN Filter Table (4096 bits) */ +#define VLAN_TAG_SIZE 4 /* 802.3ac tag (not DMA'd) */ +#define E1000_VLAN_FILTER_TBL_SIZE 128 /* VLAN Filter Table (4096 bits) */ /* Receive Address */ /* @@ -1016,529 +1027,575 @@ * (RAR[15]) for our directed address used by controllers with * manageability enabled, allowing us room for 15 multicast addresses. */ -#define E1000_RAR_ENTRIES 15 -#define E1000_RAH_AV 0x80000000 /* Receive descriptor valid */ -#define E1000_RAL_MAC_ADDR_LEN 4 -#define E1000_RAH_MAC_ADDR_LEN 2 -#define E1000_RAH_QUEUE_MASK_82575 0x000C0000 -#define E1000_RAH_POOL_MASK 0x03FC0000 -#define E1000_RAH_POOL_SHIFT 18 -#define E1000_RAH_POOL_1 0x00040000 +#define E1000_RAR_ENTRIES 15 +#define E1000_RAH_AV 0x80000000 /* Receive descriptor valid */ +#define E1000_RAL_MAC_ADDR_LEN 4 +#define E1000_RAH_MAC_ADDR_LEN 2 +#define E1000_RAH_QUEUE_MASK_82575 0x000C0000 +#define E1000_RAH_POOL_MASK 0x03FC0000 +#define E1000_RAH_POOL_SHIFT 18 +#define E1000_RAH_POOL_1 0x00040000 /* Error Codes */ -#define E1000_SUCCESS 0 -#define E1000_ERR_NVM 1 -#define E1000_ERR_PHY 2 -#define E1000_ERR_CONFIG 3 -#define E1000_ERR_PARAM 4 -#define E1000_ERR_MAC_INIT 5 -#define E1000_ERR_PHY_TYPE 6 -#define E1000_ERR_RESET 9 -#define E1000_ERR_MASTER_REQUESTS_PENDING 10 -#define E1000_ERR_HOST_INTERFACE_COMMAND 11 -#define E1000_BLK_PHY_RESET 12 -#define E1000_ERR_SWFW_SYNC 13 -#define E1000_NOT_IMPLEMENTED 14 -#define E1000_ERR_MBX 15 -#define E1000_ERR_INVALID_ARGUMENT 16 -#define E1000_ERR_NO_SPACE 17 -#define E1000_ERR_NVM_PBA_SECTION 18 +#define E1000_SUCCESS 0 +#define E1000_ERR_NVM 1 +#define E1000_ERR_PHY 2 +#define E1000_ERR_CONFIG 3 +#define E1000_ERR_PARAM 4 +#define E1000_ERR_MAC_INIT 5 +#define E1000_ERR_PHY_TYPE 6 +#define E1000_ERR_RESET 9 +#define E1000_ERR_MASTER_REQUESTS_PENDING 10 +#define E1000_ERR_HOST_INTERFACE_COMMAND 11 +#define E1000_BLK_PHY_RESET 12 +#define E1000_ERR_SWFW_SYNC 13 +#define E1000_NOT_IMPLEMENTED 14 +#define E1000_ERR_MBX 15 +#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 -#define COPPER_LINK_UP_LIMIT 10 -#define PHY_AUTO_NEG_LIMIT 45 -#define PHY_FORCE_LIMIT 20 +#define FIBER_LINK_UP_LIMIT 50 +#define COPPER_LINK_UP_LIMIT 10 +#define PHY_AUTO_NEG_LIMIT 45 +#define PHY_FORCE_LIMIT 20 /* Number of 100 microseconds we wait for PCI Express master disable */ -#define MASTER_DISABLE_TIMEOUT 800 +#define MASTER_DISABLE_TIMEOUT 800 /* Number of milliseconds we wait for PHY configuration done after MAC reset */ -#define PHY_CFG_TIMEOUT 100 +#define PHY_CFG_TIMEOUT 100 /* Number of 2 milliseconds we wait for acquiring MDIO ownership. */ -#define MDIO_OWNERSHIP_TIMEOUT 10 +#define MDIO_OWNERSHIP_TIMEOUT 10 /* Number of milliseconds for NVM auto read done after MAC reset. */ -#define AUTO_READ_DONE_TIMEOUT 10 +#define AUTO_READ_DONE_TIMEOUT 10 /* Flow Control */ -#define E1000_FCRTH_RTH 0x0000FFF8 /* Mask Bits[15:3] for RTH */ -#define E1000_FCRTH_XFCE 0x80000000 /* External Flow Control Enable */ -#define E1000_FCRTL_RTL 0x0000FFF8 /* Mask Bits[15:3] for RTL */ -#define E1000_FCRTL_XONE 0x80000000 /* Enable XON frame transmission */ +#define E1000_FCRTH_RTH 0x0000FFF8 /* Mask Bits[15:3] for RTH */ +#define E1000_FCRTH_XFCE 0x80000000 /* External Flow Control Enable */ +#define E1000_FCRTL_RTL 0x0000FFF8 /* Mask Bits[15:3] for RTL */ +#define E1000_FCRTL_XONE 0x80000000 /* Enable XON frame transmission */ /* Transmit Configuration Word */ -#define E1000_TXCW_FD 0x00000020 /* TXCW full duplex */ -#define E1000_TXCW_HD 0x00000040 /* TXCW half duplex */ -#define E1000_TXCW_PAUSE 0x00000080 /* TXCW sym pause request */ -#define E1000_TXCW_ASM_DIR 0x00000100 /* TXCW astm pause direction */ -#define E1000_TXCW_PAUSE_MASK 0x00000180 /* TXCW pause request mask */ -#define E1000_TXCW_RF 0x00003000 /* TXCW remote fault */ -#define E1000_TXCW_NP 0x00008000 /* TXCW next page */ -#define E1000_TXCW_CW 0x0000ffff /* TxConfigWord mask */ -#define E1000_TXCW_TXC 0x40000000 /* Transmit Config control */ -#define E1000_TXCW_ANE 0x80000000 /* Auto-neg enable */ +#define E1000_TXCW_FD 0x00000020 /* TXCW full duplex */ +#define E1000_TXCW_HD 0x00000040 /* TXCW half duplex */ +#define E1000_TXCW_PAUSE 0x00000080 /* TXCW sym pause request */ +#define E1000_TXCW_ASM_DIR 0x00000100 /* TXCW astm pause direction */ +#define E1000_TXCW_PAUSE_MASK 0x00000180 /* TXCW pause request mask */ +#define E1000_TXCW_RF 0x00003000 /* TXCW remote fault */ +#define E1000_TXCW_NP 0x00008000 /* TXCW next page */ +#define E1000_TXCW_CW 0x0000ffff /* TxConfigWord mask */ +#define E1000_TXCW_TXC 0x40000000 /* Transmit Config control */ +#define E1000_TXCW_ANE 0x80000000 /* Auto-neg enable */ /* Receive Configuration Word */ -#define E1000_RXCW_CW 0x0000ffff /* RxConfigWord mask */ -#define E1000_RXCW_NC 0x04000000 /* Receive config no carrier */ -#define E1000_RXCW_IV 0x08000000 /* Receive config invalid */ -#define E1000_RXCW_CC 0x10000000 /* Receive config change */ -#define E1000_RXCW_C 0x20000000 /* Receive config */ -#define E1000_RXCW_SYNCH 0x40000000 /* Receive config synch */ -#define E1000_RXCW_ANC 0x80000000 /* Auto-neg complete */ - -#define E1000_TSYNCTXCTL_VALID 0x00000001 /* Tx timestamp valid */ -#define E1000_TSYNCTXCTL_ENABLED 0x00000010 /* enable Tx timestamping */ - -#define E1000_TSYNCRXCTL_VALID 0x00000001 /* Rx timestamp valid */ -#define E1000_TSYNCRXCTL_TYPE_MASK 0x0000000E /* Rx type mask */ -#define E1000_TSYNCRXCTL_TYPE_L2_V2 0x00 -#define E1000_TSYNCRXCTL_TYPE_L4_V1 0x02 -#define E1000_TSYNCRXCTL_TYPE_L2_L4_V2 0x04 -#define E1000_TSYNCRXCTL_TYPE_ALL 0x08 -#define E1000_TSYNCRXCTL_TYPE_EVENT_V2 0x0A -#define E1000_TSYNCRXCTL_ENABLED 0x00000010 /* enable Rx timestamping */ - -#define E1000_TSYNCRXCFG_PTP_V1_CTRLT_MASK 0x000000FF -#define E1000_TSYNCRXCFG_PTP_V1_SYNC_MESSAGE 0x00 -#define E1000_TSYNCRXCFG_PTP_V1_DELAY_REQ_MESSAGE 0x01 -#define E1000_TSYNCRXCFG_PTP_V1_FOLLOWUP_MESSAGE 0x02 -#define E1000_TSYNCRXCFG_PTP_V1_DELAY_RESP_MESSAGE 0x03 -#define E1000_TSYNCRXCFG_PTP_V1_MANAGEMENT_MESSAGE 0x04 - -#define E1000_TSYNCRXCFG_PTP_V2_MSGID_MASK 0x00000F00 -#define E1000_TSYNCRXCFG_PTP_V2_SYNC_MESSAGE 0x0000 -#define E1000_TSYNCRXCFG_PTP_V2_DELAY_REQ_MESSAGE 0x0100 -#define E1000_TSYNCRXCFG_PTP_V2_PATH_DELAY_REQ_MESSAGE 0x0200 -#define E1000_TSYNCRXCFG_PTP_V2_PATH_DELAY_RESP_MESSAGE 0x0300 -#define E1000_TSYNCRXCFG_PTP_V2_FOLLOWUP_MESSAGE 0x0800 -#define E1000_TSYNCRXCFG_PTP_V2_DELAY_RESP_MESSAGE 0x0900 -#define E1000_TSYNCRXCFG_PTP_V2_PATH_DELAY_FOLLOWUP_MESSAGE 0x0A00 -#define E1000_TSYNCRXCFG_PTP_V2_ANNOUNCE_MESSAGE 0x0B00 -#define E1000_TSYNCRXCFG_PTP_V2_SIGNALLING_MESSAGE 0x0C00 -#define E1000_TSYNCRXCFG_PTP_V2_MANAGEMENT_MESSAGE 0x0D00 - -#define E1000_TIMINCA_16NS_SHIFT 24 +#define E1000_RXCW_CW 0x0000ffff /* RxConfigWord mask */ +#define E1000_RXCW_NC 0x04000000 /* Receive config no carrier */ +#define E1000_RXCW_IV 0x08000000 /* Receive config invalid */ +#define E1000_RXCW_CC 0x10000000 /* Receive config change */ +#define E1000_RXCW_C 0x20000000 /* Receive config */ +#define E1000_RXCW_SYNCH 0x40000000 /* Receive config synch */ +#define E1000_RXCW_ANC 0x80000000 /* Auto-neg complete */ + +#define E1000_TSYNCTXCTL_VALID 0x00000001 /* Tx timestamp valid */ +#define E1000_TSYNCTXCTL_ENABLED 0x00000010 /* enable Tx timestamping */ + +#define E1000_TSYNCRXCTL_VALID 0x00000001 /* Rx timestamp valid */ +#define E1000_TSYNCRXCTL_TYPE_MASK 0x0000000E /* Rx type mask */ +#define E1000_TSYNCRXCTL_TYPE_L2_V2 0x00 +#define E1000_TSYNCRXCTL_TYPE_L4_V1 0x02 +#define E1000_TSYNCRXCTL_TYPE_L2_L4_V2 0x04 +#define E1000_TSYNCRXCTL_TYPE_ALL 0x08 +#define E1000_TSYNCRXCTL_TYPE_EVENT_V2 0x0A +#define E1000_TSYNCRXCTL_ENABLED 0x00000010 /* enable Rx timestamping */ + +#define E1000_TSYNCRXCFG_PTP_V1_CTRLT_MASK 0x000000FF +#define E1000_TSYNCRXCFG_PTP_V1_SYNC_MESSAGE 0x00 +#define E1000_TSYNCRXCFG_PTP_V1_DELAY_REQ_MESSAGE 0x01 +#define E1000_TSYNCRXCFG_PTP_V1_FOLLOWUP_MESSAGE 0x02 +#define E1000_TSYNCRXCFG_PTP_V1_DELAY_RESP_MESSAGE 0x03 +#define E1000_TSYNCRXCFG_PTP_V1_MANAGEMENT_MESSAGE 0x04 + +#define E1000_TSYNCRXCFG_PTP_V2_MSGID_MASK 0x00000F00 +#define E1000_TSYNCRXCFG_PTP_V2_SYNC_MESSAGE 0x0000 +#define E1000_TSYNCRXCFG_PTP_V2_DELAY_REQ_MESSAGE 0x0100 +#define E1000_TSYNCRXCFG_PTP_V2_PATH_DELAY_REQ_MESSAGE 0x0200 +#define E1000_TSYNCRXCFG_PTP_V2_PATH_DELAY_RESP_MESSAGE 0x0300 +#define E1000_TSYNCRXCFG_PTP_V2_FOLLOWUP_MESSAGE 0x0800 +#define E1000_TSYNCRXCFG_PTP_V2_DELAY_RESP_MESSAGE 0x0900 +#define E1000_TSYNCRXCFG_PTP_V2_PATH_DELAY_FOLLOWUP_MESSAGE 0x0A00 +#define E1000_TSYNCRXCFG_PTP_V2_ANNOUNCE_MESSAGE 0x0B00 +#define E1000_TSYNCRXCFG_PTP_V2_SIGNALLING_MESSAGE 0x0C00 +#define E1000_TSYNCRXCFG_PTP_V2_MANAGEMENT_MESSAGE 0x0D00 + +#define E1000_TIMINCA_16NS_SHIFT 24 /* TUPLE Filtering Configuration */ -#define E1000_TTQF_DISABLE_MASK 0xF0008000 /* TTQF Disable Mask */ -#define E1000_TTQF_QUEUE_ENABLE 0x100 /* TTQF Queue Enable Bit */ -#define E1000_TTQF_PROTOCOL_MASK 0xFF /* TTQF Protocol Mask */ +#define E1000_TTQF_DISABLE_MASK 0xF0008000 /* TTQF Disable Mask */ +#define E1000_TTQF_QUEUE_ENABLE 0x100 /* TTQF Queue Enable Bit */ +#define E1000_TTQF_PROTOCOL_MASK 0xFF /* TTQF Protocol Mask */ /* TTQF TCP Bit, shift with E1000_TTQF_PROTOCOL SHIFT */ -#define E1000_TTQF_PROTOCOL_TCP 0x0 +#define E1000_TTQF_PROTOCOL_TCP 0x0 /* TTQF UDP Bit, shift with E1000_TTQF_PROTOCOL_SHIFT */ -#define E1000_TTQF_PROTOCOL_UDP 0x1 +#define E1000_TTQF_PROTOCOL_UDP 0x1 /* TTQF SCTP Bit, shift with E1000_TTQF_PROTOCOL_SHIFT */ -#define E1000_TTQF_PROTOCOL_SCTP 0x2 -#define E1000_TTQF_PROTOCOL_SHIFT 5 /* TTQF Protocol Shift */ -#define E1000_TTQF_QUEUE_SHIFT 16 /* TTQF Queue Shfit */ -#define E1000_TTQF_RX_QUEUE_MASK 0x70000 /* TTQF Queue Mask */ -#define E1000_TTQF_MASK_ENABLE 0x10000000 /* TTQF Mask Enable Bit */ -#define E1000_IMIR_CLEAR_MASK 0xF001FFFF /* IMIR Reg Clear Mask */ -#define E1000_IMIR_PORT_BYPASS 0x20000 /* IMIR Port Bypass Bit */ -#define E1000_IMIR_PRIORITY_SHIFT 29 /* IMIR Priority Shift */ -#define E1000_IMIREXT_CLEAR_MASK 0x7FFFF /* IMIREXT Reg Clear Mask */ - -#define E1000_MDICNFG_EXT_MDIO 0x80000000 /* MDI ext/int destination */ -#define E1000_MDICNFG_COM_MDIO 0x40000000 /* MDI shared w/ lan 0 */ -#define E1000_MDICNFG_PHY_MASK 0x03E00000 -#define E1000_MDICNFG_PHY_SHIFT 21 - -#define E1000_THSTAT_LOW_EVENT 0x20000000 /* Low thermal threshold */ -#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 */ - -/* 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 */ -#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_TTQF_PROTOCOL_SCTP 0x2 +#define E1000_TTQF_PROTOCOL_SHIFT 5 /* TTQF Protocol Shift */ +#define E1000_TTQF_QUEUE_SHIFT 16 /* TTQF Queue Shfit */ +#define E1000_TTQF_RX_QUEUE_MASK 0x70000 /* TTQF Queue Mask */ +#define E1000_TTQF_MASK_ENABLE 0x10000000 /* TTQF Mask Enable Bit */ +#define E1000_IMIR_CLEAR_MASK 0xF001FFFF /* IMIR Reg Clear Mask */ +#define E1000_IMIR_PORT_BYPASS 0x20000 /* IMIR Port Bypass Bit */ +#define E1000_IMIR_PRIORITY_SHIFT 29 /* IMIR Priority Shift */ +#define E1000_IMIREXT_CLEAR_MASK 0x7FFFF /* IMIREXT Reg Clear Mask */ + +#define E1000_MDICNFG_EXT_MDIO 0x80000000 /* MDI ext/int destination */ +#define E1000_MDICNFG_COM_MDIO 0x40000000 /* MDI shared w/ lan 0 */ +#define E1000_MDICNFG_PHY_MASK 0x03E00000 +#define E1000_MDICNFG_PHY_SHIFT 21 + +#define E1000_THSTAT_LOW_EVENT 0x20000000 /* Low thermal threshold */ +#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 Spd Throttle Event */ + +/* 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 Ena on Flow Cntrl */ /* EEE status */ -#define E1000_EEER_EEE_NEG 0x20000000 /* EEE capability negotiated */ -#define E1000_EEER_RX_LPI_STATUS 0x40000000 /* Rx in LPI state */ -#define E1000_EEER_TX_LPI_STATUS 0x80000000 /* Tx in LPI state */ +#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 */ /* PCI Express Control */ -#define E1000_GCR_RXD_NO_SNOOP 0x00000001 -#define E1000_GCR_RXDSCW_NO_SNOOP 0x00000002 -#define E1000_GCR_RXDSCR_NO_SNOOP 0x00000004 -#define E1000_GCR_TXD_NO_SNOOP 0x00000008 -#define E1000_GCR_TXDSCW_NO_SNOOP 0x00000010 -#define E1000_GCR_TXDSCR_NO_SNOOP 0x00000020 -#define E1000_GCR_CMPL_TMOUT_MASK 0x0000F000 -#define E1000_GCR_CMPL_TMOUT_10ms 0x00001000 -#define E1000_GCR_CMPL_TMOUT_RESEND 0x00010000 -#define E1000_GCR_CAP_VER2 0x00040000 - -#define PCIE_NO_SNOOP_ALL (E1000_GCR_RXD_NO_SNOOP | \ - E1000_GCR_RXDSCW_NO_SNOOP | \ - E1000_GCR_RXDSCR_NO_SNOOP | \ - E1000_GCR_TXD_NO_SNOOP | \ - E1000_GCR_TXDSCW_NO_SNOOP | \ - E1000_GCR_TXDSCR_NO_SNOOP) +#define E1000_GCR_RXD_NO_SNOOP 0x00000001 +#define E1000_GCR_RXDSCW_NO_SNOOP 0x00000002 +#define E1000_GCR_RXDSCR_NO_SNOOP 0x00000004 +#define E1000_GCR_TXD_NO_SNOOP 0x00000008 +#define E1000_GCR_TXDSCW_NO_SNOOP 0x00000010 +#define E1000_GCR_TXDSCR_NO_SNOOP 0x00000020 +#define E1000_GCR_CMPL_TMOUT_MASK 0x0000F000 +#define E1000_GCR_CMPL_TMOUT_10ms 0x00001000 +#define E1000_GCR_CMPL_TMOUT_RESEND 0x00010000 +#define E1000_GCR_CAP_VER2 0x00040000 + +#define PCIE_NO_SNOOP_ALL (E1000_GCR_RXD_NO_SNOOP | \ + E1000_GCR_RXDSCW_NO_SNOOP | \ + E1000_GCR_RXDSCR_NO_SNOOP | \ + E1000_GCR_TXD_NO_SNOOP | \ + 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 */ -#define MII_CR_FULL_DUPLEX 0x0100 /* FDX =1, half duplex =0 */ -#define MII_CR_RESTART_AUTO_NEG 0x0200 /* Restart auto negotiation */ -#define MII_CR_ISOLATE 0x0400 /* Isolate PHY from MII */ -#define MII_CR_POWER_DOWN 0x0800 /* Power down */ -#define MII_CR_AUTO_NEG_EN 0x1000 /* Auto Neg Enable */ -#define MII_CR_SPEED_SELECT_LSB 0x2000 /* bits 6,13: 10=1000, 01=100, 00=10 */ -#define MII_CR_LOOPBACK 0x4000 /* 0 = normal, 1 = loopback */ -#define MII_CR_RESET 0x8000 /* 0 = normal, 1 = PHY reset */ -#define MII_CR_SPEED_1000 0x0040 -#define MII_CR_SPEED_100 0x2000 -#define MII_CR_SPEED_10 0x0000 +#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 */ +#define MII_CR_FULL_DUPLEX 0x0100 /* FDX =1, half duplex =0 */ +#define MII_CR_RESTART_AUTO_NEG 0x0200 /* Restart auto negotiation */ +#define MII_CR_ISOLATE 0x0400 /* Isolate PHY from MII */ +#define MII_CR_POWER_DOWN 0x0800 /* Power down */ +#define MII_CR_AUTO_NEG_EN 0x1000 /* Auto Neg Enable */ +#define MII_CR_SPEED_SELECT_LSB 0x2000 /* bits 6,13: 10=1000, 01=100, 00=10 */ +#define MII_CR_LOOPBACK 0x4000 /* 0 = normal, 1 = loopback */ +#define MII_CR_RESET 0x8000 /* 0 = normal, 1 = PHY reset */ +#define MII_CR_SPEED_1000 0x0040 +#define MII_CR_SPEED_100 0x2000 +#define MII_CR_SPEED_10 0x0000 /* PHY Status Register */ -#define MII_SR_EXTENDED_CAPS 0x0001 /* Extended register capabilities */ -#define MII_SR_JABBER_DETECT 0x0002 /* Jabber Detected */ -#define MII_SR_LINK_STATUS 0x0004 /* Link Status 1 = link */ -#define MII_SR_AUTONEG_CAPS 0x0008 /* Auto Neg Capable */ -#define MII_SR_REMOTE_FAULT 0x0010 /* Remote Fault Detect */ -#define MII_SR_AUTONEG_COMPLETE 0x0020 /* Auto Neg Complete */ +#define MII_SR_EXTENDED_CAPS 0x0001 /* Extended register capabilities */ +#define MII_SR_JABBER_DETECT 0x0002 /* Jabber Detected */ +#define MII_SR_LINK_STATUS 0x0004 /* Link Status 1 = link */ +#define MII_SR_AUTONEG_CAPS 0x0008 /* Auto Neg Capable */ +#define MII_SR_REMOTE_FAULT 0x0010 /* Remote Fault Detect */ +#define MII_SR_AUTONEG_COMPLETE 0x0020 /* Auto Neg Complete */ #define MII_SR_PREAMBLE_SUPPRESS 0x0040 /* Preamble may be suppressed */ -#define MII_SR_EXTENDED_STATUS 0x0100 /* Ext. status info in Reg 0x0F */ -#define MII_SR_100T2_HD_CAPS 0x0200 /* 100T2 Half Duplex Capable */ -#define MII_SR_100T2_FD_CAPS 0x0400 /* 100T2 Full Duplex Capable */ -#define MII_SR_10T_HD_CAPS 0x0800 /* 10T Half Duplex Capable */ -#define MII_SR_10T_FD_CAPS 0x1000 /* 10T Full Duplex Capable */ -#define MII_SR_100X_HD_CAPS 0x2000 /* 100X Half Duplex Capable */ -#define MII_SR_100X_FD_CAPS 0x4000 /* 100X Full Duplex Capable */ -#define MII_SR_100T4_CAPS 0x8000 /* 100T4 Capable */ +#define MII_SR_EXTENDED_STATUS 0x0100 /* Ext. status info in Reg 0x0F */ +#define MII_SR_100T2_HD_CAPS 0x0200 /* 100T2 Half Duplex Capable */ +#define MII_SR_100T2_FD_CAPS 0x0400 /* 100T2 Full Duplex Capable */ +#define MII_SR_10T_HD_CAPS 0x0800 /* 10T Half Duplex Capable */ +#define MII_SR_10T_FD_CAPS 0x1000 /* 10T Full Duplex Capable */ +#define MII_SR_100X_HD_CAPS 0x2000 /* 100X Half Duplex Capable */ +#define MII_SR_100X_FD_CAPS 0x4000 /* 100X Full Duplex Capable */ +#define MII_SR_100T4_CAPS 0x8000 /* 100T4 Capable */ /* Autoneg Advertisement Register */ -#define NWAY_AR_SELECTOR_FIELD 0x0001 /* indicates IEEE 802.3 CSMA/CD */ -#define NWAY_AR_10T_HD_CAPS 0x0020 /* 10T Half Duplex Capable */ -#define NWAY_AR_10T_FD_CAPS 0x0040 /* 10T Full Duplex Capable */ -#define NWAY_AR_100TX_HD_CAPS 0x0080 /* 100TX Half Duplex Capable */ -#define NWAY_AR_100TX_FD_CAPS 0x0100 /* 100TX Full Duplex Capable */ -#define NWAY_AR_100T4_CAPS 0x0200 /* 100T4 Capable */ -#define NWAY_AR_PAUSE 0x0400 /* Pause operation desired */ -#define NWAY_AR_ASM_DIR 0x0800 /* Asymmetric Pause Direction bit */ -#define NWAY_AR_REMOTE_FAULT 0x2000 /* Remote Fault detected */ -#define NWAY_AR_NEXT_PAGE 0x8000 /* Next Page ability supported */ +#define NWAY_AR_SELECTOR_FIELD 0x0001 /* indicates IEEE 802.3 CSMA/CD */ +#define NWAY_AR_10T_HD_CAPS 0x0020 /* 10T Half Duplex Capable */ +#define NWAY_AR_10T_FD_CAPS 0x0040 /* 10T Full Duplex Capable */ +#define NWAY_AR_100TX_HD_CAPS 0x0080 /* 100TX Half Duplex Capable */ +#define NWAY_AR_100TX_FD_CAPS 0x0100 /* 100TX Full Duplex Capable */ +#define NWAY_AR_100T4_CAPS 0x0200 /* 100T4 Capable */ +#define NWAY_AR_PAUSE 0x0400 /* Pause operation desired */ +#define NWAY_AR_ASM_DIR 0x0800 /* Asymmetric Pause Direction bit */ +#define NWAY_AR_REMOTE_FAULT 0x2000 /* Remote Fault detected */ +#define NWAY_AR_NEXT_PAGE 0x8000 /* Next Page ability supported */ /* 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_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_NEXT_PAGE 0x8000 /* Next Page ability supported */ +#define NWAY_LPAR_SELECTOR_FIELD 0x0000 /* LP protocol selector field */ +#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 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_LP_NWAY_CAPS 0x0001 /* LP has Auto Neg Capability */ +#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 */ +#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 */ +/* 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 */ -#define CR_1000T_TEST_MODE_3 0x6000 /* Slave Transmit Jitter test */ -#define CR_1000T_TEST_MODE_4 0x8000 /* Transmitter Distortion test */ +#define CR_1000T_TEST_MODE_1 0x2000 /* Transmit Waveform test */ +#define CR_1000T_TEST_MODE_2 0x4000 /* Master Transmit Jitter test */ +#define CR_1000T_TEST_MODE_3 0x6000 /* Slave Transmit Jitter test */ +#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_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_FAULT 0x8000 /* Master/Slave config fault */ +#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 Master, 0=Slave */ +#define SR_1000T_MS_CONFIG_FAULT 0x8000 /* Master/Slave config fault */ -#define SR_1000T_PHY_EXCESSIVE_IDLE_ERR_COUNT 5 +#define SR_1000T_PHY_EXCESSIVE_IDLE_ERR_COUNT 5 /* PHY 1000 MII Register/Bit Definitions */ /* PHY Registers defined by IEEE */ -#define PHY_CONTROL 0x00 /* Control Register */ -#define PHY_STATUS 0x01 /* Status Register */ -#define PHY_ID1 0x02 /* Phy Id Reg (word 1) */ -#define PHY_ID2 0x03 /* Phy Id Reg (word 2) */ -#define PHY_AUTONEG_ADV 0x04 /* Autoneg Advertisement */ -#define PHY_LP_ABILITY 0x05 /* Link Partner Ability (Base Page) */ -#define PHY_AUTONEG_EXP 0x06 /* Autoneg Expansion Reg */ -#define PHY_NEXT_PAGE_TX 0x07 /* Next Page Tx */ -#define PHY_LP_NEXT_PAGE 0x08 /* Link Partner Next Page */ -#define PHY_1000T_CTRL 0x09 /* 1000Base-T Control Reg */ -#define PHY_1000T_STATUS 0x0A /* 1000Base-T Status Reg */ -#define PHY_EXT_STATUS 0x0F /* Extended Status Reg */ - -#define PHY_CONTROL_LB 0x4000 /* PHY Loopback bit */ +#define PHY_CONTROL 0x00 /* Control Register */ +#define PHY_STATUS 0x01 /* Status Register */ +#define PHY_ID1 0x02 /* Phy Id Reg (word 1) */ +#define PHY_ID2 0x03 /* Phy Id Reg (word 2) */ +#define PHY_AUTONEG_ADV 0x04 /* Autoneg Advertisement */ +#define PHY_LP_ABILITY 0x05 /* Link Partner Ability (Base Page) */ +#define PHY_AUTONEG_EXP 0x06 /* Autoneg Expansion Reg */ +#define PHY_NEXT_PAGE_TX 0x07 /* Next Page Tx */ +#define PHY_LP_NEXT_PAGE 0x08 /* Link Partner Next Page */ +#define PHY_1000T_CTRL 0x09 /* 1000Base-T Control Reg */ +#define PHY_1000T_STATUS 0x0A /* 1000Base-T Status Reg */ +#define PHY_EXT_STATUS 0x0F /* Extended Status Reg */ + +#define PHY_CONTROL_LB 0x4000 /* PHY Loopback bit */ /* NVM Control */ -#define E1000_EECD_SK 0x00000001 /* NVM Clock */ -#define E1000_EECD_CS 0x00000002 /* NVM Chip Select */ -#define E1000_EECD_DI 0x00000004 /* NVM Data In */ -#define E1000_EECD_DO 0x00000008 /* NVM Data Out */ -#define E1000_EECD_FWE_MASK 0x00000030 -#define E1000_EECD_FWE_DIS 0x00000010 /* Disable FLASH writes */ -#define E1000_EECD_FWE_EN 0x00000020 /* Enable FLASH writes */ -#define E1000_EECD_FWE_SHIFT 4 -#define E1000_EECD_REQ 0x00000040 /* NVM Access Request */ -#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_SK 0x00000001 /* NVM Clock */ +#define E1000_EECD_CS 0x00000002 /* NVM Chip Select */ +#define E1000_EECD_DI 0x00000004 /* NVM Data In */ +#define E1000_EECD_DO 0x00000008 /* NVM Data Out */ +#define E1000_EECD_FWE_MASK 0x00000030 +#define E1000_EECD_FWE_DIS 0x00000010 /* Disable FLASH writes */ +#define E1000_EECD_FWE_EN 0x00000020 /* Enable FLASH writes */ +#define E1000_EECD_FWE_SHIFT 4 +#define E1000_EECD_REQ 0x00000040 /* NVM Access Request */ +#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) */ +#define E1000_EECD_ADDR_BITS 0x00000400 +#define E1000_EECD_TYPE 0x00002000 /* NVM Type (1-SPI, 0-Microwire) */ #ifndef E1000_NVM_GRANT_ATTEMPTS -#define E1000_NVM_GRANT_ATTEMPTS 1000 /* NVM # attempts to gain grant */ +#define E1000_NVM_GRANT_ATTEMPTS 1000 /* NVM # attempts to gain grant */ #endif -#define E1000_EECD_AUTO_RD 0x00000200 /* NVM Auto Read done */ -#define E1000_EECD_SIZE_EX_MASK 0x00007800 /* NVM Size */ -#define E1000_EECD_SIZE_EX_SHIFT 11 -#define E1000_EECD_NVADDS 0x00018000 /* NVM Address Size */ -#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_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_NVM_SWDPIN0 0x0001 /* SWDPIN 0 NVM Value */ -#define E1000_NVM_LED_LOGIC 0x0020 /* Led Logic Word */ -#define E1000_NVM_RW_REG_DATA 16 /* Offset to data in NVM read/write regs */ -#define E1000_NVM_RW_REG_DONE 2 /* Offset to READ/WRITE done bit */ -#define E1000_NVM_RW_REG_START 1 /* Start operation */ -#define E1000_NVM_RW_ADDR_SHIFT 2 /* Shift to the address bits */ -#define E1000_NVM_POLL_WRITE 1 /* Flag for polling for write complete */ -#define E1000_NVM_POLL_READ 0 /* Flag for polling for read complete */ -#define E1000_FLASH_UPDATES 2000 +#define E1000_EECD_AUTO_RD 0x00000200 /* NVM Auto Read done */ +#define E1000_EECD_SIZE_EX_MASK 0x00007800 /* NVM Size */ +#define E1000_EECD_SIZE_EX_SHIFT 11 +#define E1000_EECD_NVADDS 0x00018000 /* NVM Address Size */ +#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 /* 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 */ +#define E1000_NVM_RW_REG_DATA 16 /* Offset to data in NVM read/write regs */ +#define E1000_NVM_RW_REG_DONE 2 /* Offset to READ/WRITE done bit */ +#define E1000_NVM_RW_REG_START 1 /* Start operation */ +#define E1000_NVM_RW_ADDR_SHIFT 2 /* Shift to the address bits */ +#define E1000_NVM_POLL_WRITE 1 /* Flag for polling for write complete */ +#define E1000_NVM_POLL_READ 0 /* Flag for polling for read complete */ +#define E1000_FLASH_UPDATES 2000 /* NVM Word Offsets */ -#define NVM_COMPAT 0x0003 -#define NVM_ID_LED_SETTINGS 0x0004 -#define NVM_VERSION 0x0005 -#define NVM_SERDES_AMPLITUDE 0x0006 /* SERDES output amplitude */ -#define NVM_PHY_CLASS_WORD 0x0007 -#define NVM_INIT_CONTROL1_REG 0x000A -#define NVM_INIT_CONTROL2_REG 0x000F -#define NVM_SWDEF_PINS_CTRL_PORT_1 0x0010 -#define NVM_INIT_CONTROL3_PORT_B 0x0014 -#define NVM_INIT_3GIO_3 0x001A -#define NVM_SWDEF_PINS_CTRL_PORT_0 0x0020 -#define NVM_INIT_CONTROL3_PORT_A 0x0024 -#define NVM_CFG 0x0012 -#define NVM_FLASH_VERSION 0x0032 -#define NVM_ALT_MAC_ADDR_PTR 0x0037 -#define NVM_CHECKSUM_REG 0x003F -#define NVM_COMPATIBILITY_REG_3 0x0003 -#define NVM_COMPATIBILITY_BIT_MASK 0x8000 - -#define E1000_NVM_CFG_DONE_PORT_0 0x040000 /* MNG config cycle done */ -#define E1000_NVM_CFG_DONE_PORT_1 0x080000 /* ...for second port */ -#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_COMPAT 0x0003 +#define NVM_ID_LED_SETTINGS 0x0004 +#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 +#define NVM_INIT_CONTROL3_PORT_B 0x0014 +#define NVM_INIT_3GIO_3 0x001A +#define NVM_SWDEF_PINS_CTRL_PORT_0 0x0020 +#define NVM_INIT_CONTROL3_PORT_A 0x0024 +#define NVM_CFG 0x0012 +#define NVM_FLASH_VERSION 0x0032 +#define NVM_ALT_MAC_ADDR_PTR 0x0037 +#define NVM_CHECKSUM_REG 0x003F +#define NVM_COMPATIBILITY_REG_3 0x0003 +#define NVM_COMPATIBILITY_BIT_MASK 0x8000 + +#define E1000_NVM_CFG_DONE_PORT_0 0x040000 /* MNG config cycle done */ +#define E1000_NVM_CFG_DONE_PORT_1 0x080000 /* ...for second port */ +#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) /* 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_COM_MDIO 0x0008 /* MDIO interface shared */ +#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 -#define NVM_WORD0F_PAUSE 0x1000 -#define NVM_WORD0F_ASM_DIR 0x2000 -#define NVM_WORD0F_ANE 0x0800 -#define NVM_WORD0F_SWPDIO_EXT_MASK 0x00F0 -#define NVM_WORD0F_LPLU 0x0001 +#define NVM_WORD0F_PAUSE_MASK 0x3000 +#define NVM_WORD0F_PAUSE 0x1000 +#define NVM_WORD0F_ASM_DIR 0x2000 +#define NVM_WORD0F_ANE 0x0800 +#define NVM_WORD0F_SWPDIO_EXT_MASK 0x00F0 +#define NVM_WORD0F_LPLU 0x0001 /* Mask bits for fields in Word 0x1a of the NVM */ -#define NVM_WORD1A_ASPM_MASK 0x000C +#define NVM_WORD1A_ASPM_MASK 0x000C /* Mask bits for fields in Word 0x03 of the EEPROM */ -#define NVM_COMPAT_LOM 0x0800 +#define NVM_COMPAT_LOM 0x0800 /* length of string needed to store PBA number */ -#define E1000_PBANUM_LENGTH 11 +#define E1000_PBANUM_LENGTH 11 /* For checksumming, the sum of all words in the NVM should equal 0xBABA. */ -#define NVM_SUM 0xBABA - -#define NVM_MAC_ADDR_OFFSET 0 -#define NVM_PBA_OFFSET_0 8 -#define NVM_PBA_OFFSET_1 9 -#define NVM_PBA_PTR_GUARD 0xFAFA -#define NVM_RESERVED_WORD 0xFFFF -#define NVM_PHY_CLASS_A 0x8000 -#define NVM_SERDES_AMPLITUDE_MASK 0x000F -#define NVM_SIZE_MASK 0x1C00 -#define NVM_SIZE_SHIFT 10 -#define NVM_WORD_SIZE_BASE_SHIFT 6 -#define NVM_SWDPIO_EXT_SHIFT 4 +#define NVM_SUM 0xBABA + +#define NVM_MAC_ADDR_OFFSET 0 +#define NVM_PBA_OFFSET_0 8 +#define NVM_PBA_OFFSET_1 9 +#define NVM_PBA_PTR_GUARD 0xFAFA +#define NVM_RESERVED_WORD 0xFFFF +#define NVM_PHY_CLASS_A 0x8000 +#define NVM_SERDES_AMPLITUDE_MASK 0x000F +#define NVM_SIZE_MASK 0x1C00 +#define NVM_SIZE_SHIFT 10 +#define NVM_WORD_SIZE_BASE_SHIFT 6 +#define NVM_SWDPIO_EXT_SHIFT 4 /* NVM Commands - Microwire */ -#define NVM_READ_OPCODE_MICROWIRE 0x6 /* NVM read opcode */ -#define NVM_WRITE_OPCODE_MICROWIRE 0x5 /* NVM write opcode */ -#define NVM_ERASE_OPCODE_MICROWIRE 0x7 /* NVM erase opcode */ -#define NVM_EWEN_OPCODE_MICROWIRE 0x13 /* NVM erase/write enable */ -#define NVM_EWDS_OPCODE_MICROWIRE 0x10 /* NVM erase/write disable */ +#define NVM_READ_OPCODE_MICROWIRE 0x6 /* NVM read opcode */ +#define NVM_WRITE_OPCODE_MICROWIRE 0x5 /* NVM write opcode */ +#define NVM_ERASE_OPCODE_MICROWIRE 0x7 /* NVM erase opcode */ +#define NVM_EWEN_OPCODE_MICROWIRE 0x13 /* NVM erase/write enable */ +#define NVM_EWDS_OPCODE_MICROWIRE 0x10 /* NVM erase/write disable */ /* NVM Commands - SPI */ -#define NVM_MAX_RETRY_SPI 5000 /* Max wait of 5ms, for RDY signal */ -#define NVM_READ_OPCODE_SPI 0x03 /* NVM read opcode */ -#define NVM_WRITE_OPCODE_SPI 0x02 /* NVM write opcode */ -#define NVM_A8_OPCODE_SPI 0x08 /* opcode bit-3 = address bit-8 */ -#define NVM_WREN_OPCODE_SPI 0x06 /* NVM set Write Enable latch */ -#define NVM_WRDI_OPCODE_SPI 0x04 /* NVM reset Write Enable latch */ -#define NVM_RDSR_OPCODE_SPI 0x05 /* NVM read Status register */ -#define NVM_WRSR_OPCODE_SPI 0x01 /* NVM write Status register */ +#define NVM_MAX_RETRY_SPI 5000 /* Max wait of 5ms, for RDY signal */ +#define NVM_READ_OPCODE_SPI 0x03 /* NVM read opcode */ +#define NVM_WRITE_OPCODE_SPI 0x02 /* NVM write opcode */ +#define NVM_A8_OPCODE_SPI 0x08 /* opcode bit-3 = address bit-8 */ +#define NVM_WREN_OPCODE_SPI 0x06 /* NVM set Write Enable latch */ +#define NVM_WRDI_OPCODE_SPI 0x04 /* NVM reset Write Enable latch */ +#define NVM_RDSR_OPCODE_SPI 0x05 /* NVM read Status register */ +#define NVM_WRSR_OPCODE_SPI 0x01 /* NVM write Status register */ /* SPI NVM Status Register */ -#define NVM_STATUS_RDY_SPI 0x01 -#define NVM_STATUS_WEN_SPI 0x02 -#define NVM_STATUS_BP0_SPI 0x04 -#define NVM_STATUS_BP1_SPI 0x08 -#define NVM_STATUS_WPEN_SPI 0x80 +#define NVM_STATUS_RDY_SPI 0x01 +#define NVM_STATUS_WEN_SPI 0x02 +#define NVM_STATUS_BP0_SPI 0x04 +#define NVM_STATUS_BP1_SPI 0x08 +#define NVM_STATUS_WPEN_SPI 0x80 /* Word definitions for ID LED Settings */ -#define ID_LED_RESERVED_0000 0x0000 -#define ID_LED_RESERVED_FFFF 0xFFFF -#define ID_LED_DEFAULT ((ID_LED_OFF1_ON2 << 12) | \ - (ID_LED_OFF1_OFF2 << 8) | \ - (ID_LED_DEF1_DEF2 << 4) | \ - (ID_LED_DEF1_DEF2)) -#define ID_LED_DEF1_DEF2 0x1 -#define ID_LED_DEF1_ON2 0x2 -#define ID_LED_DEF1_OFF2 0x3 -#define ID_LED_ON1_DEF2 0x4 -#define ID_LED_ON1_ON2 0x5 -#define ID_LED_ON1_OFF2 0x6 -#define ID_LED_OFF1_DEF2 0x7 -#define ID_LED_OFF1_ON2 0x8 -#define ID_LED_OFF1_OFF2 0x9 - -#define IGP_ACTIVITY_LED_MASK 0xFFFFF0FF -#define IGP_ACTIVITY_LED_ENABLE 0x0300 -#define IGP_LED3_MODE 0x07000000 +#define ID_LED_RESERVED_0000 0x0000 +#define ID_LED_RESERVED_FFFF 0xFFFF +#define ID_LED_DEFAULT ((ID_LED_OFF1_ON2 << 12) | \ + (ID_LED_OFF1_OFF2 << 8) | \ + (ID_LED_DEF1_DEF2 << 4) | \ + (ID_LED_DEF1_DEF2)) +#define ID_LED_DEF1_DEF2 0x1 +#define ID_LED_DEF1_ON2 0x2 +#define ID_LED_DEF1_OFF2 0x3 +#define ID_LED_ON1_DEF2 0x4 +#define ID_LED_ON1_ON2 0x5 +#define ID_LED_ON1_OFF2 0x6 +#define ID_LED_OFF1_DEF2 0x7 +#define ID_LED_OFF1_ON2 0x8 +#define ID_LED_OFF1_OFF2 0x9 + +#define IGP_ACTIVITY_LED_MASK 0xFFFFF0FF +#define IGP_ACTIVITY_LED_ENABLE 0x0300 +#define IGP_LED3_MODE 0x07000000 /* PCI/PCI-X/PCI-EX Config space */ -#define PCIX_COMMAND_REGISTER 0xE6 -#define PCIX_STATUS_REGISTER_LO 0xE8 -#define PCIX_STATUS_REGISTER_HI 0xEA -#define PCI_HEADER_TYPE_REGISTER 0x0E -#define PCIE_LINK_STATUS 0x12 -#define PCIE_DEVICE_CONTROL2 0x28 - -#define PCIX_COMMAND_MMRBC_MASK 0x000C -#define PCIX_COMMAND_MMRBC_SHIFT 0x2 -#define PCIX_STATUS_HI_MMRBC_MASK 0x0060 -#define PCIX_STATUS_HI_MMRBC_SHIFT 0x5 -#define PCIX_STATUS_HI_MMRBC_4K 0x3 -#define PCIX_STATUS_HI_MMRBC_2K 0x2 -#define PCIX_STATUS_LO_FUNC_MASK 0x7 -#define PCI_HEADER_TYPE_MULTIFUNC 0x80 -#define PCIE_LINK_WIDTH_MASK 0x3F0 -#define PCIE_LINK_WIDTH_SHIFT 4 -#define PCIE_LINK_SPEED_MASK 0x0F -#define PCIE_LINK_SPEED_2500 0x01 -#define PCIE_LINK_SPEED_5000 0x02 -#define PCIE_DEVICE_CONTROL2_16ms 0x0005 +#define PCIX_COMMAND_REGISTER 0xE6 +#define PCIX_STATUS_REGISTER_LO 0xE8 +#define PCIX_STATUS_REGISTER_HI 0xEA +#define PCI_HEADER_TYPE_REGISTER 0x0E +#define PCIE_LINK_STATUS 0x12 +#define PCIE_DEVICE_CONTROL2 0x28 + +#define PCIX_COMMAND_MMRBC_MASK 0x000C +#define PCIX_COMMAND_MMRBC_SHIFT 0x2 +#define PCIX_STATUS_HI_MMRBC_MASK 0x0060 +#define PCIX_STATUS_HI_MMRBC_SHIFT 0x5 +#define PCIX_STATUS_HI_MMRBC_4K 0x3 +#define PCIX_STATUS_HI_MMRBC_2K 0x2 +#define PCIX_STATUS_LO_FUNC_MASK 0x7 +#define PCI_HEADER_TYPE_MULTIFUNC 0x80 +#define PCIE_LINK_WIDTH_MASK 0x3F0 +#define PCIE_LINK_WIDTH_SHIFT 4 +#define PCIE_LINK_SPEED_MASK 0x0F +#define PCIE_LINK_SPEED_2500 0x01 +#define PCIE_LINK_SPEED_5000 0x02 +#define PCIE_DEVICE_CONTROL2_16ms 0x0005 #ifndef ETH_ADDR_LEN -#define ETH_ADDR_LEN 6 +#define ETH_ADDR_LEN 6 #endif -#define PHY_REVISION_MASK 0xFFFFFFF0 -#define MAX_PHY_REG_ADDRESS 0x1F /* 5 bit address bus (0-0x1F) */ -#define MAX_PHY_MULTI_PAGE_REG 0xF +#define PHY_REVISION_MASK 0xFFFFFFF0 +#define MAX_PHY_REG_ADDRESS 0x1F /* 5 bit address bus (0-0x1F) */ +#define MAX_PHY_MULTI_PAGE_REG 0xF /* Bit definitions for valid PHY IDs. */ /* * I = Integrated * E = External */ -#define M88E1000_E_PHY_ID 0x01410C50 -#define M88E1000_I_PHY_ID 0x01410C30 -#define M88E1011_I_PHY_ID 0x01410C20 -#define IGP01E1000_I_PHY_ID 0x02A80380 -#define M88E1011_I_REV_4 0x04 -#define M88E1111_I_PHY_ID 0x01410CC0 -#define M88E1112_E_PHY_ID 0x01410C90 -#define I347AT4_E_PHY_ID 0x01410DC0 -#define M88E1340M_E_PHY_ID 0x01410DF0 -#define GG82563_E_PHY_ID 0x01410CA0 -#define IGP03E1000_E_PHY_ID 0x02A80390 -#define IFE_E_PHY_ID 0x02A80330 -#define IFE_PLUS_E_PHY_ID 0x02A80320 -#define IFE_C_E_PHY_ID 0x02A80310 -#define BME1000_E_PHY_ID 0x01410CB0 -#define BME1000_E_PHY_ID_R2 0x01410CB1 -#define I82577_E_PHY_ID 0x01540050 -#define I82578_E_PHY_ID 0x004DD040 -#define I82579_E_PHY_ID 0x01540090 -#define I82580_I_PHY_ID 0x015403A0 -#define I350_I_PHY_ID 0x015403B0 -#define IGP04E1000_E_PHY_ID 0x02A80391 -#define M88_VENDOR 0x0141 +#define M88E1000_E_PHY_ID 0x01410C50 +#define M88E1000_I_PHY_ID 0x01410C30 +#define M88E1011_I_PHY_ID 0x01410C20 +#define IGP01E1000_I_PHY_ID 0x02A80380 +#define M88E1011_I_REV_4 0x04 +#define M88E1111_I_PHY_ID 0x01410CC0 +#define M88E1112_E_PHY_ID 0x01410C90 +#define I347AT4_E_PHY_ID 0x01410DC0 +#define M88E1340M_E_PHY_ID 0x01410DF0 +#define GG82563_E_PHY_ID 0x01410CA0 +#define IGP03E1000_E_PHY_ID 0x02A80390 +#define IFE_E_PHY_ID 0x02A80330 +#define IFE_PLUS_E_PHY_ID 0x02A80320 +#define IFE_C_E_PHY_ID 0x02A80310 +#define BME1000_E_PHY_ID 0x01410CB0 +#define BME1000_E_PHY_ID_R2 0x01410CB1 +#define I82577_E_PHY_ID 0x01540050 +#define I82578_E_PHY_ID 0x004DD040 +#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_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_VCO_REG_BIT8 0x100 /* Bits 8 & 11 are adjusted for */ -#define M88E1000_PHY_VCO_REG_BIT11 0x800 /* improved BER performance */ +#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 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 */ /* M88E1000 PHY Specific Control Register */ -#define M88E1000_PSCR_JABBER_DISABLE 0x0001 /* 1=Jabber Function disabled */ -#define M88E1000_PSCR_POLARITY_REVERSAL 0x0002 /* 1=Polarity Reverse enabled */ -#define M88E1000_PSCR_SQE_TEST 0x0004 /* 1=SQE Test enabled */ +#define M88E1000_PSCR_JABBER_DISABLE 0x0001 /* 1=Jabber Function disabled */ +#define M88E1000_PSCR_POLARITY_REVERSAL 0x0002 /* 1=Polarity Reverse enabled */ +#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 */ -#define M88E1000_PSCR_MDIX_MANUAL_MODE 0x0020 /* Manual MDIX configuration */ +#define M88E1000_PSCR_CLK125_DISABLE 0x0010 +/* 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 +#define M88E1000_PSCR_AUTO_X_1000T 0x0040 /* Auto crossover enabled all speeds */ -#define M88E1000_PSCR_AUTO_X_MODE 0x0060 +#define M88E1000_PSCR_AUTO_X_MODE 0x0060 /* * 1=Enable Extended 10BASE-T distance (Lower 10BASE-T Rx Threshold * 0=Normal 10BASE-T Rx Threshold */ -#define M88E1000_PSCR_EN_10BT_EXT_DIST 0x0080 +#define M88E1000_PSCR_EN_10BT_EXT_DIST 0x0080 /* 1=5-bit interface in 100BASE-TX, 0=MII interface in 100BASE-TX */ -#define M88E1000_PSCR_MII_5BIT_ENABLE 0x0100 -#define M88E1000_PSCR_SCRAMBLER_DISABLE 0x0200 /* 1=Scrambler disable */ -#define M88E1000_PSCR_FORCE_LINK_GOOD 0x0400 /* 1=Force link good */ -#define M88E1000_PSCR_ASSERT_CRS_ON_TX 0x0800 /* 1=Assert CRS on Tx */ +#define M88E1000_PSCR_MII_5BIT_ENABLE 0x0100 +#define M88E1000_PSCR_SCRAMBLER_DISABLE 0x0200 /* 1=Scrambler disable */ +#define M88E1000_PSCR_FORCE_LINK_GOOD 0x0400 /* 1=Force link good */ +#define M88E1000_PSCR_ASSERT_CRS_ON_TX 0x0800 /* 1=Assert CRS on Tx */ /* M88E1000 PHY Specific Status Register */ -#define M88E1000_PSSR_JABBER 0x0001 /* 1=Jabber */ -#define M88E1000_PSSR_REV_POLARITY 0x0002 /* 1=Polarity reversed */ -#define M88E1000_PSSR_DOWNSHIFT 0x0020 /* 1=Downshifted */ -#define M88E1000_PSSR_MDIX 0x0040 /* 1=MDIX; 0=MDI */ +#define M88E1000_PSSR_JABBER 0x0001 /* 1=Jabber */ +#define M88E1000_PSSR_REV_POLARITY 0x0002 /* 1=Polarity reversed */ +#define M88E1000_PSSR_DOWNSHIFT 0x0020 /* 1=Downshifted */ +#define M88E1000_PSSR_MDIX 0x0040 /* 1=MDIX; 0=MDI */ /* * 0 = <50M * 1 = 50-80M @@ -1546,62 +1603,62 @@ * 3 = 110-140M * 4 = >140M */ -#define M88E1000_PSSR_CABLE_LENGTH 0x0380 -#define M88E1000_PSSR_LINK 0x0400 /* 1=Link up, 0=Link down */ -#define M88E1000_PSSR_SPD_DPLX_RESOLVED 0x0800 /* 1=Speed & Duplex resolved */ -#define M88E1000_PSSR_PAGE_RCVD 0x1000 /* 1=Page received */ -#define M88E1000_PSSR_DPLX 0x2000 /* 1=Duplex 0=Half Duplex */ -#define M88E1000_PSSR_SPEED 0xC000 /* Speed, bits 14:15 */ -#define M88E1000_PSSR_10MBS 0x0000 /* 00=10Mbs */ -#define M88E1000_PSSR_100MBS 0x4000 /* 01=100Mbs */ -#define M88E1000_PSSR_1000MBS 0x8000 /* 10=1000Mbs */ - -#define M88E1000_PSSR_CABLE_LENGTH_SHIFT 7 +#define M88E1000_PSSR_CABLE_LENGTH 0x0380 +#define M88E1000_PSSR_LINK 0x0400 /* 1=Link up, 0=Link down */ +#define M88E1000_PSSR_SPD_DPLX_RESOLVED 0x0800 /* 1=Speed & Duplex resolved */ +#define M88E1000_PSSR_PAGE_RCVD 0x1000 /* 1=Page received */ +#define M88E1000_PSSR_DPLX 0x2000 /* 1=Duplex 0=Half Duplex */ +#define M88E1000_PSSR_SPEED 0xC000 /* Speed, bits 14:15 */ +#define M88E1000_PSSR_10MBS 0x0000 /* 00=10Mbs */ +#define M88E1000_PSSR_100MBS 0x4000 /* 01=100Mbs */ +#define M88E1000_PSSR_1000MBS 0x8000 /* 10=1000Mbs */ + +#define M88E1000_PSSR_CABLE_LENGTH_SHIFT 7 /* M88E1000 Extended PHY Specific Control Register */ -#define M88E1000_EPSCR_FIBER_LOOPBACK 0x4000 /* 1=Fiber loopback */ +#define M88E1000_EPSCR_FIBER_LOOPBACK 0x4000 /* 1=Fiber loopback */ /* * 1 = Lost lock detect enabled. * Will assert lost lock and bring * link down if idle not seen * within 1ms in 1000BASE-T */ -#define M88E1000_EPSCR_DOWN_NO_IDLE 0x8000 +#define M88E1000_EPSCR_DOWN_NO_IDLE 0x8000 /* * Number of times we will attempt to autonegotiate before downshifting if we * are the master */ -#define M88E1000_EPSCR_MASTER_DOWNSHIFT_MASK 0x0C00 -#define M88E1000_EPSCR_MASTER_DOWNSHIFT_1X 0x0000 -#define M88E1000_EPSCR_MASTER_DOWNSHIFT_2X 0x0400 -#define M88E1000_EPSCR_MASTER_DOWNSHIFT_3X 0x0800 -#define M88E1000_EPSCR_MASTER_DOWNSHIFT_4X 0x0C00 +#define M88E1000_EPSCR_MASTER_DOWNSHIFT_MASK 0x0C00 +#define M88E1000_EPSCR_MASTER_DOWNSHIFT_1X 0x0000 +#define M88E1000_EPSCR_MASTER_DOWNSHIFT_2X 0x0400 +#define M88E1000_EPSCR_MASTER_DOWNSHIFT_3X 0x0800 +#define M88E1000_EPSCR_MASTER_DOWNSHIFT_4X 0x0C00 /* * Number of times we will attempt to autonegotiate before downshifting if we * are the slave */ -#define M88E1000_EPSCR_SLAVE_DOWNSHIFT_MASK 0x0300 -#define M88E1000_EPSCR_SLAVE_DOWNSHIFT_DIS 0x0000 -#define M88E1000_EPSCR_SLAVE_DOWNSHIFT_1X 0x0100 -#define M88E1000_EPSCR_SLAVE_DOWNSHIFT_2X 0x0200 -#define M88E1000_EPSCR_SLAVE_DOWNSHIFT_3X 0x0300 -#define M88E1000_EPSCR_TX_CLK_2_5 0x0060 /* 2.5 MHz TX_CLK */ -#define M88E1000_EPSCR_TX_CLK_25 0x0070 /* 25 MHz TX_CLK */ -#define M88E1000_EPSCR_TX_CLK_0 0x0000 /* NO TX_CLK */ +#define M88E1000_EPSCR_SLAVE_DOWNSHIFT_MASK 0x0300 +#define M88E1000_EPSCR_SLAVE_DOWNSHIFT_DIS 0x0000 +#define M88E1000_EPSCR_SLAVE_DOWNSHIFT_1X 0x0100 +#define M88E1000_EPSCR_SLAVE_DOWNSHIFT_2X 0x0200 +#define M88E1000_EPSCR_SLAVE_DOWNSHIFT_3X 0x0300 +#define M88E1000_EPSCR_TX_CLK_2_5 0x0060 /* 2.5 MHz TX_CLK */ +#define M88E1000_EPSCR_TX_CLK_25 0x0070 /* 25 MHz TX_CLK */ +#define M88E1000_EPSCR_TX_CLK_0 0x0000 /* NO TX_CLK */ /* M88E1111 Specific Registers */ -#define M88E1111_PHY_PAGE_SELECT1 0x16 /* for registers 0-28 */ -#define M88E1111_PHY_PAGE_SELECT2 0x1D /* for registers 30-31 */ +#define M88E1111_PHY_PAGE_SELECT1 0x16 /* for registers 0-28 */ +#define M88E1111_PHY_PAGE_SELECT2 0x1D /* for registers 30-31 */ /* M88E1111 page select register mask */ -#define M88E1111_PHY_PAGE_SELECT_MASK1 0xFF -#define M88E1111_PHY_PAGE_SELECT_MASK2 0x3F +#define M88E1111_PHY_PAGE_SELECT_MASK1 0xFF +#define M88E1111_PHY_PAGE_SELECT_MASK2 0x3F /* Intel I347AT4 Registers */ -#define I347AT4_PCDL 0x10 /* PHY Cable Diagnostics Length */ -#define I347AT4_PCDC 0x15 /* PHY Cable Diagnostics Control */ -#define I347AT4_PAGE_SELECT 0x16 +#define I347AT4_PCDL 0x10 /* PHY Cable Diagnostics Length */ +#define I347AT4_PCDC 0x15 /* PHY Cable Diagnostics Control */ +#define I347AT4_PAGE_SELECT 0x16 /* I347AT4 Extended PHY Specific Control Register */ @@ -1609,213 +1666,225 @@ * Number of times we will attempt to autonegotiate before downshifting if we * are the master */ -#define I347AT4_PSCR_DOWNSHIFT_ENABLE 0x0800 -#define I347AT4_PSCR_DOWNSHIFT_MASK 0x7000 -#define I347AT4_PSCR_DOWNSHIFT_1X 0x0000 -#define I347AT4_PSCR_DOWNSHIFT_2X 0x1000 -#define I347AT4_PSCR_DOWNSHIFT_3X 0x2000 -#define I347AT4_PSCR_DOWNSHIFT_4X 0x3000 -#define I347AT4_PSCR_DOWNSHIFT_5X 0x4000 -#define I347AT4_PSCR_DOWNSHIFT_6X 0x5000 -#define I347AT4_PSCR_DOWNSHIFT_7X 0x6000 -#define I347AT4_PSCR_DOWNSHIFT_8X 0x7000 +#define I347AT4_PSCR_DOWNSHIFT_ENABLE 0x0800 +#define I347AT4_PSCR_DOWNSHIFT_MASK 0x7000 +#define I347AT4_PSCR_DOWNSHIFT_1X 0x0000 +#define I347AT4_PSCR_DOWNSHIFT_2X 0x1000 +#define I347AT4_PSCR_DOWNSHIFT_3X 0x2000 +#define I347AT4_PSCR_DOWNSHIFT_4X 0x3000 +#define I347AT4_PSCR_DOWNSHIFT_5X 0x4000 +#define I347AT4_PSCR_DOWNSHIFT_6X 0x5000 +#define I347AT4_PSCR_DOWNSHIFT_7X 0x6000 +#define I347AT4_PSCR_DOWNSHIFT_8X 0x7000 /* I347AT4 PHY Cable Diagnostics Control */ -#define I347AT4_PCDC_CABLE_LENGTH_UNIT 0x0400 /* 0=cm 1=meters */ +#define I347AT4_PCDC_CABLE_LENGTH_UNIT 0x0400 /* 0=cm 1=meters */ /* M88E1112 only registers */ -#define M88E1112_VCT_DSP_DISTANCE 0x001A +#define M88E1112_VCT_DSP_DISTANCE 0x001A /* M88EC018 Rev 2 specific DownShift settings */ -#define M88EC018_EPSCR_DOWNSHIFT_COUNTER_MASK 0x0E00 -#define M88EC018_EPSCR_DOWNSHIFT_COUNTER_1X 0x0000 -#define M88EC018_EPSCR_DOWNSHIFT_COUNTER_2X 0x0200 -#define M88EC018_EPSCR_DOWNSHIFT_COUNTER_3X 0x0400 -#define M88EC018_EPSCR_DOWNSHIFT_COUNTER_4X 0x0600 -#define M88EC018_EPSCR_DOWNSHIFT_COUNTER_5X 0x0800 -#define M88EC018_EPSCR_DOWNSHIFT_COUNTER_6X 0x0A00 -#define M88EC018_EPSCR_DOWNSHIFT_COUNTER_7X 0x0C00 -#define M88EC018_EPSCR_DOWNSHIFT_COUNTER_8X 0x0E00 - -#define I82578_EPSCR_DOWNSHIFT_ENABLE 0x0020 -#define I82578_EPSCR_DOWNSHIFT_COUNTER_MASK 0x001C +#define M88EC018_EPSCR_DOWNSHIFT_COUNTER_MASK 0x0E00 +#define M88EC018_EPSCR_DOWNSHIFT_COUNTER_1X 0x0000 +#define M88EC018_EPSCR_DOWNSHIFT_COUNTER_2X 0x0200 +#define M88EC018_EPSCR_DOWNSHIFT_COUNTER_3X 0x0400 +#define M88EC018_EPSCR_DOWNSHIFT_COUNTER_4X 0x0600 +#define M88EC018_EPSCR_DOWNSHIFT_COUNTER_5X 0x0800 +#define M88EC018_EPSCR_DOWNSHIFT_COUNTER_6X 0x0A00 +#define M88EC018_EPSCR_DOWNSHIFT_COUNTER_7X 0x0C00 +#define M88EC018_EPSCR_DOWNSHIFT_COUNTER_8X 0x0E00 + +#define I82578_EPSCR_DOWNSHIFT_ENABLE 0x0020 +#define I82578_EPSCR_DOWNSHIFT_COUNTER_MASK 0x001C /* BME1000 PHY Specific Control Register */ -#define BME1000_PSCR_ENABLE_DOWNSHIFT 0x0800 /* 1 = enable downshift */ +#define BME1000_PSCR_ENABLE_DOWNSHIFT 0x0800 /* 1 = enable downshift */ /* * Bits... * 15-5: page * 4-0: register offset */ -#define GG82563_PAGE_SHIFT 5 -#define GG82563_REG(page, reg) \ - (((page) << GG82563_PAGE_SHIFT) | ((reg) & MAX_PHY_REG_ADDRESS)) -#define GG82563_MIN_ALT_REG 30 +#define GG82563_PAGE_SHIFT 5 +#define GG82563_REG(page, reg) \ + (((page) << GG82563_PAGE_SHIFT) | ((reg) & MAX_PHY_REG_ADDRESS)) +#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_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 */ - -#define GG82563_PHY_DSP_DISTANCE \ - GG82563_REG(5, 26) /* DSP Distance */ +#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) + +/* 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 */ /* 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 -#define E1000_MDIC_REG_MASK 0x001F0000 -#define E1000_MDIC_REG_SHIFT 16 -#define E1000_MDIC_PHY_MASK 0x03E00000 -#define E1000_MDIC_PHY_SHIFT 21 -#define E1000_MDIC_OP_WRITE 0x04000000 -#define E1000_MDIC_OP_READ 0x08000000 -#define E1000_MDIC_READY 0x10000000 -#define E1000_MDIC_INT_EN 0x20000000 -#define E1000_MDIC_ERROR 0x40000000 -#define E1000_MDIC_DEST 0x80000000 +#define E1000_MDIC_DATA_MASK 0x0000FFFF +#define E1000_MDIC_REG_MASK 0x001F0000 +#define E1000_MDIC_REG_SHIFT 16 +#define E1000_MDIC_PHY_MASK 0x03E00000 +#define E1000_MDIC_PHY_SHIFT 21 +#define E1000_MDIC_OP_WRITE 0x04000000 +#define E1000_MDIC_OP_READ 0x08000000 +#define E1000_MDIC_READY 0x10000000 +#define E1000_MDIC_INT_EN 0x20000000 +#define E1000_MDIC_ERROR 0x40000000 +#define E1000_MDIC_DEST 0x80000000 /* SerDes Control */ -#define E1000_GEN_CTL_READY 0x80000000 -#define E1000_GEN_CTL_ADDRESS_SHIFT 8 -#define E1000_GEN_POLL_TIMEOUT 640 +#define E1000_GEN_CTL_READY 0x80000000 +#define E1000_GEN_CTL_ADDRESS_SHIFT 8 +#define E1000_GEN_POLL_TIMEOUT 640 /* LinkSec register fields */ -#define E1000_LSECTXCAP_SUM_MASK 0x00FF0000 -#define E1000_LSECTXCAP_SUM_SHIFT 16 -#define E1000_LSECRXCAP_SUM_MASK 0x00FF0000 -#define E1000_LSECRXCAP_SUM_SHIFT 16 - -#define E1000_LSECTXCTRL_EN_MASK 0x00000003 -#define E1000_LSECTXCTRL_DISABLE 0x0 -#define E1000_LSECTXCTRL_AUTH 0x1 -#define E1000_LSECTXCTRL_AUTH_ENCRYPT 0x2 -#define E1000_LSECTXCTRL_AISCI 0x00000020 -#define E1000_LSECTXCTRL_PNTHRSH_MASK 0xFFFFFF00 -#define E1000_LSECTXCTRL_RSV_MASK 0x000000D8 - -#define E1000_LSECRXCTRL_EN_MASK 0x0000000C -#define E1000_LSECRXCTRL_EN_SHIFT 2 -#define E1000_LSECRXCTRL_DISABLE 0x0 -#define E1000_LSECRXCTRL_CHECK 0x1 -#define E1000_LSECRXCTRL_STRICT 0x2 -#define E1000_LSECRXCTRL_DROP 0x3 -#define E1000_LSECRXCTRL_PLSH 0x00000040 -#define E1000_LSECRXCTRL_RP 0x00000080 -#define E1000_LSECRXCTRL_RSV_MASK 0xFFFFFF33 +#define E1000_LSECTXCAP_SUM_MASK 0x00FF0000 +#define E1000_LSECTXCAP_SUM_SHIFT 16 +#define E1000_LSECRXCAP_SUM_MASK 0x00FF0000 +#define E1000_LSECRXCAP_SUM_SHIFT 16 + +#define E1000_LSECTXCTRL_EN_MASK 0x00000003 +#define E1000_LSECTXCTRL_DISABLE 0x0 +#define E1000_LSECTXCTRL_AUTH 0x1 +#define E1000_LSECTXCTRL_AUTH_ENCRYPT 0x2 +#define E1000_LSECTXCTRL_AISCI 0x00000020 +#define E1000_LSECTXCTRL_PNTHRSH_MASK 0xFFFFFF00 +#define E1000_LSECTXCTRL_RSV_MASK 0x000000D8 + +#define E1000_LSECRXCTRL_EN_MASK 0x0000000C +#define E1000_LSECRXCTRL_EN_SHIFT 2 +#define E1000_LSECRXCTRL_DISABLE 0x0 +#define E1000_LSECRXCTRL_CHECK 0x1 +#define E1000_LSECRXCTRL_STRICT 0x2 +#define E1000_LSECRXCTRL_DROP 0x3 +#define E1000_LSECRXCTRL_PLSH 0x00000040 +#define E1000_LSECRXCTRL_RP 0x00000080 +#define E1000_LSECRXCTRL_RSV_MASK 0xFFFFFF33 /* Tx Rate-Scheduler Config fields */ #define E1000_RTTBCNRC_RS_ENA 0x80000000 #define E1000_RTTBCNRC_RF_DEC_MASK 0x00003FFF -#define E1000_RTTBCNRC_RF_INT_SHIFT 14 +#define E1000_RTTBCNRC_RF_INT_SHIFT 14 #define E1000_RTTBCNRC_RF_INT_MASK \ (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 */ -#define E1000_DMACR_DMACTHR_SHIFT 16 -#define E1000_DMACR_DMAC_LX_MASK 0x30000000 /* Lx when no PCIe - * transactions */ -#define E1000_DMACR_DMAC_LX_SHIFT 28 -#define E1000_DMACR_DMAC_EN 0x80000000 /* Enable DMA Coalescing */ - -#define E1000_DMCTXTH_DMCTTHR_MASK 0x00000FFF /* DMA Coalescing Transmit - * Threshold */ - -#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 */ - -#define E1000_DMCCNT_CCOUNT_MASK 0x01FFFFFF /* DMA Coal Rx Traffic - * Current Cnt */ - -#define E1000_FCRTC_RTH_COAL_MASK 0x0003FFF0 /* Flow ctrl Rx Threshold - * High val */ -#define E1000_FCRTC_RTH_COAL_SHIFT 4 -#define E1000_PCIEMISC_LX_DECISION 0x00000080 /* Lx power decision based - on DMA coal */ +/* 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 +/* 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 + +/* DMA Coalescing Transmit Threshold */ +#define E1000_DMCTXTH_DMCTTHR_MASK 0x00000FFF + +#define E1000_DMCTLX_TTLX_MASK 0x00000FFF /* Time to LX request */ + +/* Rx Traffic Rate Threshold */ +#define E1000_DMCRTRH_UTRESH_MASK 0x0007FFFF +/* Rx packet rate in current window */ +#define E1000_DMCRTRH_LRPRCW 0x80000000 + +/* DMA Coal Rx Traffic Current Count */ +#define E1000_DMCCNT_CCOUNT_MASK 0x01FFFFFF + +/* Flow ctrl Rx Threshold High val */ +#define E1000_FCRTC_RTH_COAL_MASK 0x0003FFF0 +#define E1000_FCRTC_RTH_COAL_SHIFT 4 +/* 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_BC 0x00000010 /* Broadcast Proxy Enable */ -#define E1000_PROXYFC_ARP_DIRECTED 0x00000020 /* Directed ARP Proxy - * Enable */ -#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_D0 0x00000001 /* Enable offload in D0 */ +#define E1000_PROXYFC_EX 0x00000004 /* Directed exact 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 Ena */ +#define E1000_PROXYFC_IPV4 0x00000040 /* Directed IPv4 Enable */ +#define E1000_PROXYFC_IPV6 0x00000080 /* Directed IPv6 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 */ +#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_ */ diff --git a/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_hw.h b/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_hw.h index 0e6bf1a51fe..50a5ce2c28d 100644 --- a/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_hw.h +++ b/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_hw.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_ @@ -41,139 +41,145 @@ struct e1000_hw; -#define E1000_DEV_ID_82542 0x1000 -#define E1000_DEV_ID_82543GC_FIBER 0x1001 -#define E1000_DEV_ID_82543GC_COPPER 0x1004 -#define E1000_DEV_ID_82544EI_COPPER 0x1008 -#define E1000_DEV_ID_82544EI_FIBER 0x1009 -#define E1000_DEV_ID_82544GC_COPPER 0x100C -#define E1000_DEV_ID_82544GC_LOM 0x100D -#define E1000_DEV_ID_82540EM 0x100E -#define E1000_DEV_ID_82540EM_LOM 0x1015 -#define E1000_DEV_ID_82540EP_LOM 0x1016 -#define E1000_DEV_ID_82540EP 0x1017 -#define E1000_DEV_ID_82540EP_LP 0x101E -#define E1000_DEV_ID_82545EM_COPPER 0x100F -#define E1000_DEV_ID_82545EM_FIBER 0x1011 -#define E1000_DEV_ID_82545GM_COPPER 0x1026 -#define E1000_DEV_ID_82545GM_FIBER 0x1027 -#define E1000_DEV_ID_82545GM_SERDES 0x1028 -#define E1000_DEV_ID_82546EB_COPPER 0x1010 -#define E1000_DEV_ID_82546EB_FIBER 0x1012 -#define E1000_DEV_ID_82546EB_QUAD_COPPER 0x101D -#define E1000_DEV_ID_82546GB_COPPER 0x1079 -#define E1000_DEV_ID_82546GB_FIBER 0x107A -#define E1000_DEV_ID_82546GB_SERDES 0x107B -#define E1000_DEV_ID_82546GB_PCIE 0x108A -#define E1000_DEV_ID_82546GB_QUAD_COPPER 0x1099 -#define E1000_DEV_ID_82546GB_QUAD_COPPER_KSP3 0x10B5 -#define E1000_DEV_ID_82541EI 0x1013 -#define E1000_DEV_ID_82541EI_MOBILE 0x1018 -#define E1000_DEV_ID_82541ER_LOM 0x1014 -#define E1000_DEV_ID_82541ER 0x1078 -#define E1000_DEV_ID_82541GI 0x1076 -#define E1000_DEV_ID_82541GI_LF 0x107C -#define E1000_DEV_ID_82541GI_MOBILE 0x1077 -#define E1000_DEV_ID_82547EI 0x1019 -#define E1000_DEV_ID_82547EI_MOBILE 0x101A -#define E1000_DEV_ID_82547GI 0x1075 -#define E1000_DEV_ID_82571EB_COPPER 0x105E -#define E1000_DEV_ID_82571EB_FIBER 0x105F -#define E1000_DEV_ID_82571EB_SERDES 0x1060 -#define E1000_DEV_ID_82571EB_SERDES_DUAL 0x10D9 -#define E1000_DEV_ID_82571EB_SERDES_QUAD 0x10DA -#define E1000_DEV_ID_82571EB_QUAD_COPPER 0x10A4 -#define E1000_DEV_ID_82571PT_QUAD_COPPER 0x10D5 -#define E1000_DEV_ID_82571EB_QUAD_FIBER 0x10A5 -#define E1000_DEV_ID_82571EB_QUAD_COPPER_LP 0x10BC -#define E1000_DEV_ID_82572EI_COPPER 0x107D -#define E1000_DEV_ID_82572EI_FIBER 0x107E -#define E1000_DEV_ID_82572EI_SERDES 0x107F -#define E1000_DEV_ID_82572EI 0x10B9 -#define E1000_DEV_ID_82573E 0x108B -#define E1000_DEV_ID_82573E_IAMT 0x108C -#define E1000_DEV_ID_82573L 0x109A -#define E1000_DEV_ID_82574L 0x10D3 -#define E1000_DEV_ID_82574LA 0x10F6 -#define E1000_DEV_ID_82583V 0x150C -#define E1000_DEV_ID_80003ES2LAN_COPPER_DPT 0x1096 -#define E1000_DEV_ID_80003ES2LAN_SERDES_DPT 0x1098 -#define E1000_DEV_ID_80003ES2LAN_COPPER_SPT 0x10BA -#define E1000_DEV_ID_80003ES2LAN_SERDES_SPT 0x10BB -#define E1000_DEV_ID_ICH8_82567V_3 0x1501 -#define E1000_DEV_ID_ICH8_IGP_M_AMT 0x1049 -#define E1000_DEV_ID_ICH8_IGP_AMT 0x104A -#define E1000_DEV_ID_ICH8_IGP_C 0x104B -#define E1000_DEV_ID_ICH8_IFE 0x104C -#define E1000_DEV_ID_ICH8_IFE_GT 0x10C4 -#define E1000_DEV_ID_ICH8_IFE_G 0x10C5 -#define E1000_DEV_ID_ICH8_IGP_M 0x104D -#define E1000_DEV_ID_ICH9_IGP_M 0x10BF -#define E1000_DEV_ID_ICH9_IGP_M_AMT 0x10F5 -#define E1000_DEV_ID_ICH9_IGP_M_V 0x10CB -#define E1000_DEV_ID_ICH9_IGP_AMT 0x10BD -#define E1000_DEV_ID_ICH9_BM 0x10E5 -#define E1000_DEV_ID_ICH9_IGP_C 0x294C -#define E1000_DEV_ID_ICH9_IFE 0x10C0 -#define E1000_DEV_ID_ICH9_IFE_GT 0x10C3 -#define E1000_DEV_ID_ICH9_IFE_G 0x10C2 -#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 - -#define E1000_DEV_ID_PCH_M_HV_LM 0x10EA -#define E1000_DEV_ID_PCH_M_HV_LC 0x10EB -#define E1000_DEV_ID_PCH_D_HV_DM 0x10EF -#define E1000_DEV_ID_PCH_D_HV_DC 0x10F0 -#define E1000_DEV_ID_PCH2_LV_LM 0x1502 -#define E1000_DEV_ID_PCH2_LV_V 0x1503 -#define E1000_DEV_ID_82576 0x10C9 -#define E1000_DEV_ID_82576_FIBER 0x10E6 -#define E1000_DEV_ID_82576_SERDES 0x10E7 -#define E1000_DEV_ID_82576_QUAD_COPPER 0x10E8 -#define E1000_DEV_ID_82576_QUAD_COPPER_ET2 0x1526 -#define E1000_DEV_ID_82576_NS 0x150A -#define E1000_DEV_ID_82576_NS_SERDES 0x1518 -#define E1000_DEV_ID_82576_SERDES_QUAD 0x150D -#define E1000_DEV_ID_82576_VF 0x10CA -#define E1000_DEV_ID_I350_VF 0x1520 -#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 -#define E1000_DEV_ID_82580_SGMII 0x1511 -#define E1000_DEV_ID_82580_COPPER_DUAL 0x1516 -#define E1000_DEV_ID_82580_QUAD_FIBER 0x1527 -#define E1000_DEV_ID_I350_COPPER 0x1521 -#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_DH89XXCC_SGMII 0x0438 -#define E1000_DEV_ID_DH89XXCC_SERDES 0x043A -#define E1000_DEV_ID_DH89XXCC_BACKPLANE 0x043C -#define E1000_DEV_ID_DH89XXCC_SFP 0x0440 -#define E1000_REVISION_0 0 -#define E1000_REVISION_1 1 -#define E1000_REVISION_2 2 -#define E1000_REVISION_3 3 -#define E1000_REVISION_4 4 - -#define E1000_FUNC_0 0 -#define E1000_FUNC_1 1 -#define E1000_FUNC_2 2 -#define E1000_FUNC_3 3 - -#define E1000_ALT_MAC_ADDRESS_OFFSET_LAN0 0 -#define E1000_ALT_MAC_ADDRESS_OFFSET_LAN1 3 -#define E1000_ALT_MAC_ADDRESS_OFFSET_LAN2 6 -#define E1000_ALT_MAC_ADDRESS_OFFSET_LAN3 9 +#define E1000_DEV_ID_82542 0x1000 +#define E1000_DEV_ID_82543GC_FIBER 0x1001 +#define E1000_DEV_ID_82543GC_COPPER 0x1004 +#define E1000_DEV_ID_82544EI_COPPER 0x1008 +#define E1000_DEV_ID_82544EI_FIBER 0x1009 +#define E1000_DEV_ID_82544GC_COPPER 0x100C +#define E1000_DEV_ID_82544GC_LOM 0x100D +#define E1000_DEV_ID_82540EM 0x100E +#define E1000_DEV_ID_82540EM_LOM 0x1015 +#define E1000_DEV_ID_82540EP_LOM 0x1016 +#define E1000_DEV_ID_82540EP 0x1017 +#define E1000_DEV_ID_82540EP_LP 0x101E +#define E1000_DEV_ID_82545EM_COPPER 0x100F +#define E1000_DEV_ID_82545EM_FIBER 0x1011 +#define E1000_DEV_ID_82545GM_COPPER 0x1026 +#define E1000_DEV_ID_82545GM_FIBER 0x1027 +#define E1000_DEV_ID_82545GM_SERDES 0x1028 +#define E1000_DEV_ID_82546EB_COPPER 0x1010 +#define E1000_DEV_ID_82546EB_FIBER 0x1012 +#define E1000_DEV_ID_82546EB_QUAD_COPPER 0x101D +#define E1000_DEV_ID_82546GB_COPPER 0x1079 +#define E1000_DEV_ID_82546GB_FIBER 0x107A +#define E1000_DEV_ID_82546GB_SERDES 0x107B +#define E1000_DEV_ID_82546GB_PCIE 0x108A +#define E1000_DEV_ID_82546GB_QUAD_COPPER 0x1099 +#define E1000_DEV_ID_82546GB_QUAD_COPPER_KSP3 0x10B5 +#define E1000_DEV_ID_82541EI 0x1013 +#define E1000_DEV_ID_82541EI_MOBILE 0x1018 +#define E1000_DEV_ID_82541ER_LOM 0x1014 +#define E1000_DEV_ID_82541ER 0x1078 +#define E1000_DEV_ID_82541GI 0x1076 +#define E1000_DEV_ID_82541GI_LF 0x107C +#define E1000_DEV_ID_82541GI_MOBILE 0x1077 +#define E1000_DEV_ID_82547EI 0x1019 +#define E1000_DEV_ID_82547EI_MOBILE 0x101A +#define E1000_DEV_ID_82547GI 0x1075 +#define E1000_DEV_ID_82571EB_COPPER 0x105E +#define E1000_DEV_ID_82571EB_FIBER 0x105F +#define E1000_DEV_ID_82571EB_SERDES 0x1060 +#define E1000_DEV_ID_82571EB_SERDES_DUAL 0x10D9 +#define E1000_DEV_ID_82571EB_SERDES_QUAD 0x10DA +#define E1000_DEV_ID_82571EB_QUAD_COPPER 0x10A4 +#define E1000_DEV_ID_82571PT_QUAD_COPPER 0x10D5 +#define E1000_DEV_ID_82571EB_QUAD_FIBER 0x10A5 +#define E1000_DEV_ID_82571EB_QUAD_COPPER_LP 0x10BC +#define E1000_DEV_ID_82572EI_COPPER 0x107D +#define E1000_DEV_ID_82572EI_FIBER 0x107E +#define E1000_DEV_ID_82572EI_SERDES 0x107F +#define E1000_DEV_ID_82572EI 0x10B9 +#define E1000_DEV_ID_82573E 0x108B +#define E1000_DEV_ID_82573E_IAMT 0x108C +#define E1000_DEV_ID_82573L 0x109A +#define E1000_DEV_ID_82574L 0x10D3 +#define E1000_DEV_ID_82574LA 0x10F6 +#define E1000_DEV_ID_82583V 0x150C +#define E1000_DEV_ID_80003ES2LAN_COPPER_DPT 0x1096 +#define E1000_DEV_ID_80003ES2LAN_SERDES_DPT 0x1098 +#define E1000_DEV_ID_80003ES2LAN_COPPER_SPT 0x10BA +#define E1000_DEV_ID_80003ES2LAN_SERDES_SPT 0x10BB +#define E1000_DEV_ID_ICH8_82567V_3 0x1501 +#define E1000_DEV_ID_ICH8_IGP_M_AMT 0x1049 +#define E1000_DEV_ID_ICH8_IGP_AMT 0x104A +#define E1000_DEV_ID_ICH8_IGP_C 0x104B +#define E1000_DEV_ID_ICH8_IFE 0x104C +#define E1000_DEV_ID_ICH8_IFE_GT 0x10C4 +#define E1000_DEV_ID_ICH8_IFE_G 0x10C5 +#define E1000_DEV_ID_ICH8_IGP_M 0x104D +#define E1000_DEV_ID_ICH9_IGP_M 0x10BF +#define E1000_DEV_ID_ICH9_IGP_M_AMT 0x10F5 +#define E1000_DEV_ID_ICH9_IGP_M_V 0x10CB +#define E1000_DEV_ID_ICH9_IGP_AMT 0x10BD +#define E1000_DEV_ID_ICH9_BM 0x10E5 +#define E1000_DEV_ID_ICH9_IGP_C 0x294C +#define E1000_DEV_ID_ICH9_IFE 0x10C0 +#define E1000_DEV_ID_ICH9_IFE_GT 0x10C3 +#define E1000_DEV_ID_ICH9_IFE_G 0x10C2 +#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_D_BM_LM 0x10DE +#define E1000_DEV_ID_ICH10_D_BM_LF 0x10DF +#define E1000_DEV_ID_ICH10_D_BM_V 0x1525 + +#define E1000_DEV_ID_PCH_M_HV_LM 0x10EA +#define E1000_DEV_ID_PCH_M_HV_LC 0x10EB +#define E1000_DEV_ID_PCH_D_HV_DM 0x10EF +#define E1000_DEV_ID_PCH_D_HV_DC 0x10F0 +#define E1000_DEV_ID_PCH2_LV_LM 0x1502 +#define E1000_DEV_ID_PCH2_LV_V 0x1503 +#define E1000_DEV_ID_82576 0x10C9 +#define E1000_DEV_ID_82576_FIBER 0x10E6 +#define E1000_DEV_ID_82576_SERDES 0x10E7 +#define E1000_DEV_ID_82576_QUAD_COPPER 0x10E8 +#define E1000_DEV_ID_82576_QUAD_COPPER_ET2 0x1526 +#define E1000_DEV_ID_82576_NS 0x150A +#define E1000_DEV_ID_82576_NS_SERDES 0x1518 +#define E1000_DEV_ID_82576_SERDES_QUAD 0x150D +#define E1000_DEV_ID_82576_VF 0x10CA +#define E1000_DEV_ID_I350_VF 0x1520 +#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_82580_COPPER 0x150E +#define E1000_DEV_ID_82580_FIBER 0x150F +#define E1000_DEV_ID_82580_SERDES 0x1510 +#define E1000_DEV_ID_82580_SGMII 0x1511 +#define E1000_DEV_ID_82580_COPPER_DUAL 0x1516 +#define E1000_DEV_ID_82580_QUAD_FIBER 0x1527 +#define E1000_DEV_ID_I350_COPPER 0x1521 +#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 +#define E1000_DEV_ID_DH89XXCC_SFP 0x0440 +#define E1000_REVISION_0 0 +#define E1000_REVISION_1 1 +#define E1000_REVISION_2 2 +#define E1000_REVISION_3 3 +#define E1000_REVISION_4 4 + +#define E1000_FUNC_0 0 +#define E1000_FUNC_1 1 +#define E1000_FUNC_2 2 +#define E1000_FUNC_3 3 + +#define E1000_ALT_MAC_ADDRESS_OFFSET_LAN0 0 +#define E1000_ALT_MAC_ADDRESS_OFFSET_LAN1 3 +#define E1000_ALT_MAC_ADDRESS_OFFSET_LAN2 6 +#define E1000_ALT_MAC_ADDRESS_OFFSET_LAN3 9 enum e1000_mac_type { e1000_undefined = 0, @@ -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 { @@ -342,9 +351,9 @@ enum e1000_serdes_link_state { struct e1000_rx_desc { __le64 buffer_addr; /* Address of the descriptor's data buffer */ __le16 length; /* Length of data DMAed into data buffer */ - __le16 csum; /* Packet checksum */ - u8 status; /* Descriptor status */ - u8 errors; /* Descriptor Errors */ + __le16 csum; /* Packet checksum */ + u8 status; /* Descriptor status */ + u8 errors; /* Descriptor Errors */ __le16 special; }; @@ -356,9 +365,9 @@ union e1000_rx_desc_extended { } read; struct { struct { - __le32 mrq; /* Multiple Rx Queues */ + __le32 mrq; /* Multiple Rx Queues */ union { - __le32 rss; /* RSS Hash */ + __le32 rss; /* RSS Hash */ struct { __le16 ip_id; /* IP id */ __le16 csum; /* Packet Checksum */ @@ -368,7 +377,7 @@ union e1000_rx_desc_extended { struct { __le32 status_error; /* ext status/error */ __le16 length; - __le16 vlan; /* VLAN tag */ + __le16 vlan; /* VLAN tag */ } upper; } wb; /* writeback */ }; @@ -382,9 +391,9 @@ union e1000_rx_desc_packet_split { } read; struct { struct { - __le32 mrq; /* Multiple Rx Queues */ + __le32 mrq; /* Multiple Rx Queues */ union { - __le32 rss; /* RSS Hash */ + __le32 rss; /* RSS Hash */ struct { __le16 ip_id; /* IP id */ __le16 csum; /* Packet Checksum */ @@ -393,8 +402,8 @@ union e1000_rx_desc_packet_split { } lower; struct { __le32 status_error; /* ext status/error */ - __le16 length0; /* length of buffer 0 */ - __le16 vlan; /* VLAN tag */ + __le16 length0; /* length of buffer 0 */ + __le16 vlan; /* VLAN tag */ } middle; struct { __le16 header_status; @@ -410,16 +419,16 @@ struct e1000_tx_desc { union { __le32 data; struct { - __le16 length; /* Data buffer length */ - u8 cso; /* Checksum offset */ - u8 cmd; /* Descriptor control */ + __le16 length; /* Data buffer length */ + u8 cso; /* Checksum offset */ + u8 cmd; /* Descriptor control */ } flags; } lower; union { __le32 data; struct { - u8 status; /* Descriptor status */ - u8 css; /* Checksum start */ + u8 status; /* Descriptor status */ + u8 css; /* Checksum start */ __le16 special; } fields; } upper; @@ -430,37 +439,37 @@ struct e1000_context_desc { union { __le32 ip_config; struct { - u8 ipcss; /* IP checksum start */ - u8 ipcso; /* IP checksum offset */ - __le16 ipcse; /* IP checksum end */ + u8 ipcss; /* IP checksum start */ + u8 ipcso; /* IP checksum offset */ + __le16 ipcse; /* IP checksum end */ } ip_fields; } lower_setup; union { __le32 tcp_config; struct { - u8 tucss; /* TCP checksum start */ - u8 tucso; /* TCP checksum offset */ - __le16 tucse; /* TCP checksum end */ + u8 tucss; /* TCP checksum start */ + u8 tucso; /* TCP checksum offset */ + __le16 tucse; /* TCP checksum end */ } tcp_fields; } upper_setup; __le32 cmd_and_length; union { __le32 data; struct { - u8 status; /* Descriptor status */ - u8 hdr_len; /* Header length */ - __le16 mss; /* Maximum segment size */ + u8 status; /* Descriptor status */ + u8 hdr_len; /* Header length */ + __le16 mss; /* Maximum segment size */ } fields; } tcp_seg_setup; }; /* Offload data descriptor */ struct e1000_data_desc { - __le64 buffer_addr; /* Address of the descriptor's buffer address */ + __le64 buffer_addr; /* Address of the descriptor's buffer address */ union { __le32 data; struct { - __le16 length; /* Data buffer length */ + __le16 length; /* Data buffer length */ u8 typ_len_ext; u8 cmd; } flags; @@ -468,8 +477,8 @@ struct e1000_data_desc { union { __le32 data; struct { - u8 status; /* Descriptor status */ - u8 popts; /* Packet Options */ + u8 status; /* Descriptor status */ + u8 popts; /* Packet Options */ __le16 special; } fields; } upper; @@ -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 { @@ -611,7 +624,7 @@ struct e1000_host_command_header { u8 checksum; }; -#define E1000_HI_MAX_DATA_LENGTH 252 +#define E1000_HI_MAX_DATA_LENGTH 252 struct e1000_host_command_info { struct e1000_host_command_header command_header; u8 command_data[E1000_HI_MAX_DATA_LENGTH]; @@ -626,7 +639,7 @@ struct e1000_host_mng_command_header { u16 command_length; }; -#define E1000_HI_MAX_MNG_DATA_LENGTH 0x6F8 +#define E1000_HI_MAX_MNG_DATA_LENGTH 0x6F8 struct e1000_host_mng_command_info { struct e1000_host_mng_command_header command_header; u8 command_data[E1000_HI_MAX_MNG_DATA_LENGTH]; @@ -668,11 +681,28 @@ struct e1000_mac_operations { s32 (*validate_mdi_setting)(struct e1000_hw *); s32 (*mng_host_if_write)(struct e1000_hw *, u8*, u16, u16, u8*); s32 (*mng_write_cmd_header)(struct e1000_hw *hw, - struct e1000_host_mng_command_header*); + 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; }; @@ -811,14 +845,14 @@ struct e1000_bus_info { }; struct e1000_fc_info { - u32 high_water; /* Flow control high-water mark */ - u32 low_water; /* Flow control low-water mark */ - u16 pause_time; /* Flow control pause timer */ - u16 refresh_time; /* Flow control refresh timer */ - bool send_xon; /* Flow control send XON */ - bool strict_ieee; /* Strict IEEE mode */ - enum e1000_fc_mode current_mode; /* FC mode in effect */ - enum e1000_fc_mode requested_mode; /* FC mode requested by caller */ + u32 high_water; /* Flow control high-water mark */ + u32 low_water; /* Flow control low-water mark */ + u16 pause_time; /* Flow control pause timer */ + u16 refresh_time; /* Flow control refresh timer */ + bool send_xon; /* Flow control send XON */ + bool strict_ieee; /* Strict IEEE mode */ + enum e1000_fc_mode current_mode; /* FC mode in effect */ + enum e1000_fc_mode requested_mode; /* FC mode requested by caller */ }; struct e1000_mbx_operations { @@ -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); diff --git a/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_i210.c b/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_i210.c new file mode 100644 index 00000000000..f8e8bad0d84 --- /dev/null +++ b/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_i210.c @@ -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; +} diff --git a/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_i210.h b/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_i210.h new file mode 100644 index 00000000000..a0cd93576d5 --- /dev/null +++ b/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_i210.h @@ -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 diff --git a/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_ich8lan.c b/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_ich8lan.c index cff4f192d7b..98aefc4fc0b 100644 --- a/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_ich8lan.c +++ b/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_ich8lan.c @@ -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 @@ -76,23 +76,23 @@ static bool e1000_check_mng_mode_ich8lan(struct e1000_hw *hw); static bool e1000_check_mng_mode_pchlan(struct e1000_hw *hw); static void e1000_rar_set_pch2lan(struct e1000_hw *hw, u8 *addr, u32 index); static void e1000_update_mc_addr_list_pch2lan(struct e1000_hw *hw, - u8 *mc_addr_list, - u32 mc_addr_count); + u8 *mc_addr_list, + u32 mc_addr_count); static s32 e1000_check_reset_block_ich8lan(struct e1000_hw *hw); static s32 e1000_phy_hw_reset_ich8lan(struct e1000_hw *hw); static s32 e1000_set_lplu_state_pchlan(struct e1000_hw *hw, bool active); static s32 e1000_set_d0_lplu_state_ich8lan(struct e1000_hw *hw, - bool active); + bool active); static s32 e1000_set_d3_lplu_state_ich8lan(struct e1000_hw *hw, - bool active); + bool active); static s32 e1000_read_nvm_ich8lan(struct e1000_hw *hw, u16 offset, - u16 words, u16 *data); + u16 words, u16 *data); static s32 e1000_write_nvm_ich8lan(struct e1000_hw *hw, u16 offset, - u16 words, u16 *data); + u16 words, u16 *data); static s32 e1000_validate_nvm_checksum_ich8lan(struct e1000_hw *hw); static s32 e1000_update_nvm_checksum_ich8lan(struct e1000_hw *hw); static s32 e1000_valid_led_default_ich8lan(struct e1000_hw *hw, - u16 *data); + u16 *data); static s32 e1000_id_led_init_pchlan(struct e1000_hw *hw); static s32 e1000_get_bus_info_ich8lan(struct e1000_hw *hw); static s32 e1000_reset_hw_ich8lan(struct e1000_hw *hw); @@ -100,7 +100,7 @@ static s32 e1000_init_hw_ich8lan(struct e1000_hw *hw); static s32 e1000_setup_link_ich8lan(struct e1000_hw *hw); static s32 e1000_setup_copper_link_ich8lan(struct e1000_hw *hw); static s32 e1000_get_link_up_info_ich8lan(struct e1000_hw *hw, - u16 *speed, u16 *duplex); + u16 *speed, u16 *duplex); static s32 e1000_cleanup_led_ich8lan(struct e1000_hw *hw); static s32 e1000_led_on_ich8lan(struct e1000_hw *hw); static s32 e1000_led_off_ich8lan(struct e1000_hw *hw); @@ -116,17 +116,17 @@ static s32 e1000_flash_cycle_init_ich8lan(struct e1000_hw *hw); static void e1000_initialize_hw_bits_ich8lan(struct e1000_hw *hw); static s32 e1000_kmrn_lock_loss_workaround_ich8lan(struct e1000_hw *hw); static s32 e1000_read_flash_byte_ich8lan(struct e1000_hw *hw, - u32 offset, u8 *data); + u32 offset, u8 *data); static s32 e1000_read_flash_data_ich8lan(struct e1000_hw *hw, u32 offset, - u8 size, u16 *data); + u8 size, u16 *data); static s32 e1000_read_flash_word_ich8lan(struct e1000_hw *hw, - u32 offset, u16 *data); + u32 offset, u16 *data); static s32 e1000_retry_write_flash_byte_ich8lan(struct e1000_hw *hw, - u32 offset, u8 byte); + u32 offset, u8 byte); static s32 e1000_write_flash_byte_ich8lan(struct e1000_hw *hw, - u32 offset, u8 data); + u32 offset, u8 data); static s32 e1000_write_flash_data_ich8lan(struct e1000_hw *hw, u32 offset, - u8 size, u16 data); + u8 size, u16 data); static s32 e1000_get_cfg_done_ich8lan(struct e1000_hw *hw); static void e1000_power_down_phy_copper_ich8lan(struct e1000_hw *hw); static s32 e1000_check_for_copper_link_ich8lan(struct e1000_hw *hw); @@ -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,70 +205,66 @@ 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"); - phy->addr = 1; - phy->reset_delay_us = 100; - - 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.read_reg = e1000_read_phy_reg_hv; - phy->ops.read_reg_locked = e1000_read_phy_reg_hv_locked; - 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.power_up = e1000_power_up_phy_copper; - phy->ops.power_down = e1000_power_down_phy_copper_ich8lan; - phy->autoneg_mask = AUTONEG_ADVERTISE_SPEED_DEFAULT; + phy->addr = 1; + phy->reset_delay_us = 100; + + 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; - /* - * 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. - */ - 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); + 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 resetting the PHY is not blocked, toggle the + * LANPHYPC Value bit to force the interconnect to PCIe mode. + */ + 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. - */ - ret_val = e1000_phy_hw_reset_generic(hw); - if (ret_val) - goto out; + /* + * 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) + goto out; - /* Ungate automatic PHY configuration on non-managed 82579 */ - if ((hw->mac.type == e1000_pch2lan) && - !(fwsm & E1000_ICH_FWSM_FW_VALID)) { - msec_delay(10); - e1000_gate_hw_phy_config_ich8lan(hw, FALSE); + /* Ungate automatic PHY configuration on non-managed 82579 */ + if ((hw->mac.type == e1000_pch2lan) && + !(fwsm & E1000_ICH_FWSM_FW_VALID)) { + msec_delay(10); + e1000_gate_hw_phy_config_ich8lan(hw, FALSE); + } } phy->id = e1000_phy_unknown; @@ -315,21 +330,21 @@ static s32 e1000_init_phy_params_ich8lan(struct e1000_hw *hw) DEBUGFUNC("e1000_init_phy_params_ich8lan"); - phy->addr = 1; - phy->reset_delay_us = 100; - - phy->ops.acquire = e1000_acquire_swflag_ich8lan; - phy->ops.check_reset_block = e1000_check_reset_block_ich8lan; - phy->ops.get_cable_length = e1000_get_cable_length_igp_2; - phy->ops.get_cfg_done = e1000_get_cfg_done_ich8lan; - phy->ops.read_reg = e1000_read_phy_reg_igp; - phy->ops.release = e1000_release_swflag_ich8lan; - phy->ops.reset = e1000_phy_hw_reset_ich8lan; - phy->ops.set_d0_lplu_state = e1000_set_d0_lplu_state_ich8lan; - phy->ops.set_d3_lplu_state = e1000_set_d3_lplu_state_ich8lan; - phy->ops.write_reg = e1000_write_phy_reg_igp; - phy->ops.power_up = e1000_power_up_phy_copper; - phy->ops.power_down = e1000_power_down_phy_copper_ich8lan; + phy->addr = 1; + phy->reset_delay_us = 100; + + phy->ops.acquire = e1000_acquire_swflag_ich8lan; + phy->ops.check_reset_block = e1000_check_reset_block_ich8lan; + phy->ops.get_cable_length = e1000_get_cable_length_igp_2; + phy->ops.get_cfg_done = e1000_get_cfg_done_ich8lan; + phy->ops.read_reg = e1000_read_phy_reg_igp; + phy->ops.release = e1000_release_swflag_ich8lan; + phy->ops.reset = e1000_phy_hw_reset_ich8lan; + phy->ops.set_d0_lplu_state = e1000_set_d0_lplu_state_ich8lan; + phy->ops.set_d3_lplu_state = e1000_set_d3_lplu_state_ich8lan; + phy->ops.write_reg = e1000_write_phy_reg_igp; + phy->ops.power_up = e1000_power_up_phy_copper; + phy->ops.power_down = e1000_power_down_phy_copper_ich8lan; /* * We may need to do this twice - once for IGP and if that fails, @@ -438,7 +453,7 @@ static s32 e1000_init_nvm_params_ich8lan(struct e1000_hw *hw) * size represents two separate NVM banks. */ nvm->flash_bank_size = (sector_end_addr - sector_base_addr) - << FLASH_SECTOR_ADDR_SHIFT; + << FLASH_SECTOR_ADDR_SHIFT; nvm->flash_bank_size /= 2; /* Adjust to word count */ nvm->flash_bank_size /= sizeof(u16); @@ -455,13 +470,13 @@ static s32 e1000_init_nvm_params_ich8lan(struct e1000_hw *hw) E1000_MUTEX_INIT(&dev_spec->swflag_mutex); /* Function Pointers */ - nvm->ops.acquire = e1000_acquire_nvm_ich8lan; - nvm->ops.release = e1000_release_nvm_ich8lan; - nvm->ops.read = e1000_read_nvm_ich8lan; - nvm->ops.update = e1000_update_nvm_checksum_ich8lan; + nvm->ops.acquire = e1000_acquire_nvm_ich8lan; + nvm->ops.release = e1000_release_nvm_ich8lan; + nvm->ops.read = e1000_read_nvm_ich8lan; + nvm->ops.update = e1000_update_nvm_checksum_ich8lan; nvm->ops.valid_led_default = e1000_valid_led_default_ich8lan; - nvm->ops.validate = e1000_validate_nvm_checksum_ich8lan; - nvm->ops.write = e1000_write_nvm_ich8lan; + nvm->ops.validate = e1000_validate_nvm_checksum_ich8lan; + nvm->ops.write = e1000_write_nvm_ich8lan; out: return ret_val; @@ -477,7 +492,6 @@ static s32 e1000_init_nvm_params_ich8lan(struct e1000_hw *hw) 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; - 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) { + 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; + } + + /* + * 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; @@ -918,8 +962,8 @@ static void e1000_rar_set_pch2lan(struct e1000_hw *hw, u8 *addr, u32 index) * from network order (big endian) to little endian */ rar_low = ((u32) addr[0] | - ((u32) addr[1] << 8) | - ((u32) addr[2] << 16) | ((u32) addr[3] << 24)); + ((u32) addr[1] << 8) | + ((u32) addr[2] << 16) | ((u32) addr[3] << 24)); rar_high = ((u32) addr[4] | ((u32) addr[5] << 8)); @@ -963,22 +1007,38 @@ static void e1000_rar_set_pch2lan(struct e1000_hw *hw, u8 *addr, u32 index) * The caller must have a packed mc_addr_list of multicast addresses. **/ static void e1000_update_mc_addr_list_pch2lan(struct e1000_hw *hw, - u8 *mc_addr_list, - u32 mc_addr_count) + 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), - (u16)((hw->mac.mta_shadow[i] >> 16) & - 0xFFFF)); + 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,13 +1055,10 @@ 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 - : E1000_BLK_PHY_RESET; + : E1000_BLK_PHY_RESET; } /** @@ -1187,46 +1244,46 @@ static s32 e1000_k1_gig_workaround_hv(struct e1000_hw *hw, bool link) if (link) { if (hw->phy.type == e1000_phy_82578) { ret_val = hw->phy.ops.read_reg_locked(hw, BM_CS_STATUS, - &status_reg); + &status_reg); if (ret_val) goto release; status_reg &= BM_CS_STATUS_LINK_UP | - BM_CS_STATUS_RESOLVED | - BM_CS_STATUS_SPEED_MASK; + BM_CS_STATUS_RESOLVED | + BM_CS_STATUS_SPEED_MASK; if (status_reg == (BM_CS_STATUS_LINK_UP | - BM_CS_STATUS_RESOLVED | - BM_CS_STATUS_SPEED_1000)) + BM_CS_STATUS_RESOLVED | + BM_CS_STATUS_SPEED_1000)) k1_enable = FALSE; } if (hw->phy.type == e1000_phy_82577) { ret_val = hw->phy.ops.read_reg_locked(hw, HV_M_STATUS, - &status_reg); + &status_reg); if (ret_val) goto release; status_reg &= HV_M_STATUS_LINK_UP | - HV_M_STATUS_AUTONEG_COMPLETE | - HV_M_STATUS_SPEED_MASK; + HV_M_STATUS_AUTONEG_COMPLETE | + HV_M_STATUS_SPEED_MASK; if (status_reg == (HV_M_STATUS_LINK_UP | - HV_M_STATUS_AUTONEG_COMPLETE | - HV_M_STATUS_SPEED_1000)) + HV_M_STATUS_AUTONEG_COMPLETE | + HV_M_STATUS_SPEED_1000)) k1_enable = FALSE; } /* Link stall fix for link up */ ret_val = hw->phy.ops.write_reg_locked(hw, PHY_REG(770, 19), - 0x0100); + 0x0100); if (ret_val) goto release; } else { /* Link stall fix for link down */ ret_val = hw->phy.ops.write_reg_locked(hw, PHY_REG(770, 19), - 0x4100); + 0x4100); if (ret_val) goto release; } @@ -1259,9 +1316,8 @@ 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, - &kmrn_reg); + ret_val = e1000_read_kmrn_reg_locked(hw, E1000_KMRNCTRLSTA_K1_CONFIG, + &kmrn_reg); if (ret_val) goto out; @@ -1270,9 +1326,8 @@ 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, - kmrn_reg); + 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 @@ s32 e1000_configure_k1_ich8lan(struct e1000_hw *hw, bool k1_enable) * 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; + + /* 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_NOND0A_GBE_DISABLE) + 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_NOND0A_LPLU) + if (mac_reg & (E1000_PHY_CTRL_D0A_LPLU | + E1000_PHY_CTRL_NOND0A_LPLU)) oem_reg |= HV_OEM_BITS_LPLU; } - /* Restart auto-neg to activate the bits */ - if (!hw->phy.ops.check_reset_block(hw)) - oem_reg |= HV_OEM_BITS_RESTART_AN; + ret_val = hw->phy.ops.write_reg_locked(hw, HV_OEM_BITS, oem_reg); out: @@ -1361,20 +1422,6 @@ s32 e1000_oem_bits_config_ich8lan(struct e1000_hw *hw, bool d0_state) } -/** - * 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. @@ -1480,25 +1488,10 @@ static s32 e1000_hv_phy_workarounds_ich8lan(struct e1000_hw *hw) if (hw->phy.revision < 2) { e1000_phy_sw_reset_generic(hw); ret_val = hw->phy.ops.write_reg(hw, PHY_CONTROL, - 0x3140); + 0x3140); } } - 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,12 +1515,11 @@ 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, - phy_data & 0x00FF); + ret_val = hw->phy.ops.write_reg_locked(hw, BM_PORT_GEN_CFG, + phy_data & 0x00FF); release: hw->phy.ops.release(hw); out: @@ -1541,19 +1533,38 @@ static s32 e1000_hv_phy_workarounds_ich8lan(struct e1000_hw *hw) 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) + 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; - else + 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 &= ~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, ®); - /* 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; - oem_reg |= HV_OEM_BITS_RESTART_AN; + 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: @@ -2081,12 +2097,12 @@ static s32 e1000_set_d0_lplu_state_ich8lan(struct e1000_hw *hw, bool active) /* When LPLU is enabled, we should disable SmartSpeed */ ret_val = phy->ops.read_reg(hw, - IGP01E1000_PHY_PORT_CONFIG, - &data); + IGP01E1000_PHY_PORT_CONFIG, + &data); data &= ~IGP01E1000_PSCFR_SMART_SPEED; ret_val = phy->ops.write_reg(hw, - IGP01E1000_PHY_PORT_CONFIG, - data); + IGP01E1000_PHY_PORT_CONFIG, + data); if (ret_val) goto out; } else { @@ -2104,28 +2120,28 @@ static s32 e1000_set_d0_lplu_state_ich8lan(struct e1000_hw *hw, bool active) */ if (phy->smart_speed == e1000_smart_speed_on) { ret_val = phy->ops.read_reg(hw, - IGP01E1000_PHY_PORT_CONFIG, - &data); + IGP01E1000_PHY_PORT_CONFIG, + &data); if (ret_val) goto out; data |= IGP01E1000_PSCFR_SMART_SPEED; ret_val = phy->ops.write_reg(hw, - IGP01E1000_PHY_PORT_CONFIG, - data); + IGP01E1000_PHY_PORT_CONFIG, + data); if (ret_val) goto out; } else if (phy->smart_speed == e1000_smart_speed_off) { ret_val = phy->ops.read_reg(hw, - IGP01E1000_PHY_PORT_CONFIG, - &data); + IGP01E1000_PHY_PORT_CONFIG, + &data); if (ret_val) goto out; data &= ~IGP01E1000_PSCFR_SMART_SPEED; ret_val = phy->ops.write_reg(hw, - IGP01E1000_PHY_PORT_CONFIG, - data); + IGP01E1000_PHY_PORT_CONFIG, + data); if (ret_val) goto out; } @@ -2174,34 +2190,34 @@ static s32 e1000_set_d3_lplu_state_ich8lan(struct e1000_hw *hw, bool active) */ if (phy->smart_speed == e1000_smart_speed_on) { ret_val = phy->ops.read_reg(hw, - IGP01E1000_PHY_PORT_CONFIG, - &data); + IGP01E1000_PHY_PORT_CONFIG, + &data); if (ret_val) goto out; data |= IGP01E1000_PSCFR_SMART_SPEED; ret_val = phy->ops.write_reg(hw, - IGP01E1000_PHY_PORT_CONFIG, - data); + IGP01E1000_PHY_PORT_CONFIG, + data); if (ret_val) goto out; } else if (phy->smart_speed == e1000_smart_speed_off) { ret_val = phy->ops.read_reg(hw, - IGP01E1000_PHY_PORT_CONFIG, - &data); + IGP01E1000_PHY_PORT_CONFIG, + &data); if (ret_val) goto out; data &= ~IGP01E1000_PSCFR_SMART_SPEED; ret_val = phy->ops.write_reg(hw, - IGP01E1000_PHY_PORT_CONFIG, - data); + IGP01E1000_PHY_PORT_CONFIG, + data); if (ret_val) goto out; } } else if ((phy->autoneg_advertised == E1000_ALL_SPEED_DUPLEX) || - (phy->autoneg_advertised == E1000_ALL_NOT_GIG) || - (phy->autoneg_advertised == E1000_ALL_10_SPEED)) { + (phy->autoneg_advertised == E1000_ALL_NOT_GIG) || + (phy->autoneg_advertised == E1000_ALL_10_SPEED)) { phy_ctrl |= E1000_PHY_CTRL_NOND0A_LPLU; E1000_WRITE_REG(hw, E1000_PHY_CTRL, phy_ctrl); @@ -2217,15 +2233,15 @@ static s32 e1000_set_d3_lplu_state_ich8lan(struct e1000_hw *hw, bool active) /* When LPLU is enabled, we should disable SmartSpeed */ ret_val = phy->ops.read_reg(hw, - IGP01E1000_PHY_PORT_CONFIG, - &data); + IGP01E1000_PHY_PORT_CONFIG, + &data); if (ret_val) goto out; data &= ~IGP01E1000_PSCFR_SMART_SPEED; ret_val = phy->ops.write_reg(hw, - IGP01E1000_PHY_PORT_CONFIG, - data); + IGP01E1000_PHY_PORT_CONFIG, + data); } 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 */ @@ -2273,7 +2288,7 @@ static s32 e1000_valid_nvm_bank_detect_ich8lan(struct e1000_hw *hw, u32 *bank) /* Check bank 0 */ ret_val = e1000_read_flash_byte_ich8lan(hw, act_offset, - &sig_byte); + &sig_byte); if (ret_val) goto out; if ((sig_byte & E1000_ICH_NVM_VALID_SIG_MASK) == @@ -2284,8 +2299,8 @@ static s32 e1000_valid_nvm_bank_detect_ich8lan(struct e1000_hw *hw, u32 *bank) /* Check bank 1 */ ret_val = e1000_read_flash_byte_ich8lan(hw, act_offset + - bank1_offset, - &sig_byte); + bank1_offset, + &sig_byte); if (ret_val) goto out; if ((sig_byte & E1000_ICH_NVM_VALID_SIG_MASK) == @@ -2312,7 +2327,7 @@ static s32 e1000_valid_nvm_bank_detect_ich8lan(struct e1000_hw *hw, u32 *bank) * Reads a word(s) from the NVM using the flash access registers. **/ static s32 e1000_read_nvm_ich8lan(struct e1000_hw *hw, u16 offset, u16 words, - u16 *data) + u16 *data) { struct e1000_nvm_info *nvm = &hw->nvm; struct e1000_dev_spec_ich8lan *dev_spec = &hw->dev_spec.ich8lan; @@ -2343,13 +2358,12 @@ 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, - act_offset + i, - &word); + act_offset + i, + &word); if (ret_val) break; data[i] = word; @@ -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; } @@ -2421,7 +2434,7 @@ static s32 e1000_flash_cycle_init_ich8lan(struct e1000_hw *hw) */ for (i = 0; i < ICH_FLASH_READ_COMMAND_TIMEOUT; i++) { hsfsts.regval = E1000_READ_FLASH_REG16(hw, - ICH_FLASH_HSFSTS); + ICH_FLASH_HSFSTS); if (hsfsts.hsf_status.flcinprog == 0) { ret_val = E1000_SUCCESS; break; @@ -2435,9 +2448,9 @@ static s32 e1000_flash_cycle_init_ich8lan(struct e1000_hw *hw) */ hsfsts.hsf_status.flcdone = 1; E1000_WRITE_FLASH_REG16(hw, ICH_FLASH_HSFSTS, - hsfsts.regval); + hsfsts.regval); } else { - DEBUGOUT("Flash controller busy, cannot get access"); + DEBUGOUT("Flash controller busy, cannot get access\n"); } } @@ -2490,7 +2503,7 @@ static s32 e1000_flash_cycle_ich8lan(struct e1000_hw *hw, u32 timeout) * to bytes before read. **/ static s32 e1000_read_flash_word_ich8lan(struct e1000_hw *hw, u32 offset, - u16 *data) + u16 *data) { s32 ret_val; @@ -2519,7 +2532,7 @@ static s32 e1000_read_flash_word_ich8lan(struct e1000_hw *hw, u32 offset, * Reads a single byte from the NVM using the flash access registers. **/ static s32 e1000_read_flash_byte_ich8lan(struct e1000_hw *hw, u32 offset, - u8 *data) + u8 *data) { s32 ret_val = E1000_SUCCESS; u16 word = 0; @@ -2544,7 +2557,7 @@ static s32 e1000_read_flash_byte_ich8lan(struct e1000_hw *hw, u32 offset, * Reads a byte or word from the NVM using the flash access registers. **/ static s32 e1000_read_flash_data_ich8lan(struct e1000_hw *hw, u32 offset, - u8 size, u16 *data) + u8 size, u16 *data) { union ich8_hws_flash_status hsfsts; union ich8_hws_flash_ctrl hsflctl; @@ -2559,7 +2572,7 @@ static s32 e1000_read_flash_data_ich8lan(struct e1000_hw *hw, u32 offset, goto out; flash_linear_addr = (ICH_FLASH_LINEAR_ADDR_MASK & offset) + - hw->nvm.flash_base_addr; + hw->nvm.flash_base_addr; do { usec_delay(1); @@ -2577,7 +2590,7 @@ static s32 e1000_read_flash_data_ich8lan(struct e1000_hw *hw, u32 offset, E1000_WRITE_FLASH_REG(hw, ICH_FLASH_FADDR, flash_linear_addr); ret_val = e1000_flash_cycle_ich8lan(hw, - ICH_FLASH_READ_COMMAND_TIMEOUT); + ICH_FLASH_READ_COMMAND_TIMEOUT); /* * Check if FCERR is set to 1, if set to 1, clear it @@ -2600,13 +2613,12 @@ static s32 e1000_read_flash_data_ich8lan(struct e1000_hw *hw, u32 offset, * ICH_FLASH_CYCLE_REPEAT_COUNT times. */ hsfsts.regval = E1000_READ_FLASH_REG16(hw, - ICH_FLASH_HSFSTS); + ICH_FLASH_HSFSTS); if (hsfsts.hsf_status.flcerr == 1) { /* 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; } } @@ -2626,7 +2638,7 @@ static s32 e1000_read_flash_data_ich8lan(struct e1000_hw *hw, u32 offset, * Writes a byte or word to the NVM using the flash access registers. **/ static s32 e1000_write_nvm_ich8lan(struct e1000_hw *hw, u16 offset, u16 words, - u16 *data) + u16 *data) { struct e1000_nvm_info *nvm = &hw->nvm; struct e1000_dev_spec_ich8lan *dev_spec = &hw->dev_spec.ich8lan; @@ -2720,8 +2732,8 @@ static s32 e1000_update_nvm_checksum_ich8lan(struct e1000_hw *hw) data = dev_spec->shadow_ram[i].value; } else { ret_val = e1000_read_flash_word_ich8lan(hw, i + - old_bank_offset, - &data); + old_bank_offset, + &data); if (ret_val) break; } @@ -2743,15 +2755,15 @@ static s32 e1000_update_nvm_checksum_ich8lan(struct e1000_hw *hw) usec_delay(100); /* Write the bytes to the new bank. */ ret_val = e1000_retry_write_flash_byte_ich8lan(hw, - act_offset, - (u8)data); + act_offset, + (u8)data); if (ret_val) break; usec_delay(100); ret_val = e1000_retry_write_flash_byte_ich8lan(hw, - act_offset + 1, - (u8)(data >> 8)); + act_offset + 1, + (u8)(data >> 8)); if (ret_val) break; } @@ -2778,8 +2790,8 @@ static s32 e1000_update_nvm_checksum_ich8lan(struct e1000_hw *hw) data &= 0xBFFF; ret_val = e1000_retry_write_flash_byte_ich8lan(hw, - act_offset * 2 + 1, - (u8)(data >> 8)); + act_offset * 2 + 1, + (u8)(data >> 8)); if (ret_val) goto release; @@ -2870,7 +2882,7 @@ static s32 e1000_validate_nvm_checksum_ich8lan(struct e1000_hw *hw) * Writes one/two bytes to the NVM using the flash access registers. **/ static s32 e1000_write_flash_data_ich8lan(struct e1000_hw *hw, u32 offset, - u8 size, u16 data) + u8 size, u16 data) { union ich8_hws_flash_status hsfsts; union ich8_hws_flash_ctrl hsflctl; @@ -2886,7 +2898,7 @@ static s32 e1000_write_flash_data_ich8lan(struct e1000_hw *hw, u32 offset, goto out; flash_linear_addr = (ICH_FLASH_LINEAR_ADDR_MASK & offset) + - hw->nvm.flash_base_addr; + hw->nvm.flash_base_addr; do { usec_delay(1); @@ -2915,7 +2927,7 @@ static s32 e1000_write_flash_data_ich8lan(struct e1000_hw *hw, u32 offset, * and try the whole sequence a few more times else done */ ret_val = e1000_flash_cycle_ich8lan(hw, - ICH_FLASH_WRITE_COMMAND_TIMEOUT); + ICH_FLASH_WRITE_COMMAND_TIMEOUT); if (ret_val == E1000_SUCCESS) 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); @@ -2949,7 +2960,7 @@ static s32 e1000_write_flash_data_ich8lan(struct e1000_hw *hw, u32 offset, * Writes a single byte to the NVM using the flash access registers. **/ static s32 e1000_write_flash_byte_ich8lan(struct e1000_hw *hw, u32 offset, - u8 data) + u8 data) { u16 word = (u16)data; @@ -2968,7 +2979,7 @@ static s32 e1000_write_flash_byte_ich8lan(struct e1000_hw *hw, u32 offset, * Goes through a retry algorithm before giving up. **/ static s32 e1000_retry_write_flash_byte_ich8lan(struct e1000_hw *hw, - u32 offset, u8 byte) + u32 offset, u8 byte) { s32 ret_val; u16 program_retries; @@ -3071,10 +3082,10 @@ static s32 e1000_erase_flash_bank_ich8lan(struct e1000_hw *hw, u32 bank) * Cycle field in hw flash control */ hsflctl.regval = E1000_READ_FLASH_REG16(hw, - ICH_FLASH_HSFCTL); + ICH_FLASH_HSFCTL); hsflctl.hsf_ctrl.flcycle = ICH_CYCLE_ERASE; E1000_WRITE_FLASH_REG16(hw, ICH_FLASH_HSFCTL, - hsflctl.regval); + hsflctl.regval); /* * Write the last 24 bits of an index within the @@ -3083,10 +3094,10 @@ static s32 e1000_erase_flash_bank_ich8lan(struct e1000_hw *hw, u32 bank) */ flash_linear_addr += (j * sector_size); E1000_WRITE_FLASH_REG(hw, ICH_FLASH_FADDR, - flash_linear_addr); + flash_linear_addr); ret_val = e1000_flash_cycle_ich8lan(hw, - ICH_FLASH_ERASE_COMMAND_TIMEOUT); + ICH_FLASH_ERASE_COMMAND_TIMEOUT); if (ret_val == E1000_SUCCESS) break; @@ -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 @@ static s32 e1000_id_led_init_pchlan(struct e1000_hw *hw) * @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; @@ -3411,13 +3424,13 @@ static s32 e1000_init_hw_ich8lan(struct e1000_hw *hw) txdctl = (txdctl & ~E1000_TXDCTL_WTHRESH) | E1000_TXDCTL_FULL_TX_DESC_WB; txdctl = (txdctl & ~E1000_TXDCTL_PTHRESH) | - E1000_TXDCTL_MAX_TX_DESC_PREFETCH; + E1000_TXDCTL_MAX_TX_DESC_PREFETCH; E1000_WRITE_REG(hw, E1000_TXDCTL(0), txdctl); txdctl = E1000_READ_REG(hw, E1000_TXDCTL(1)); txdctl = (txdctl & ~E1000_TXDCTL_WTHRESH) | E1000_TXDCTL_FULL_TX_DESC_WB; txdctl = (txdctl & ~E1000_TXDCTL_PTHRESH) | - E1000_TXDCTL_MAX_TX_DESC_PREFETCH; + E1000_TXDCTL_MAX_TX_DESC_PREFETCH; E1000_WRITE_REG(hw, E1000_TXDCTL(1), txdctl); /* @@ -3557,8 +3570,8 @@ static s32 e1000_setup_link_ich8lan(struct e1000_hw *hw) E1000_WRITE_REG(hw, E1000_FCRTV_PCH, hw->fc.refresh_time); ret_val = hw->phy.ops.write_reg(hw, - PHY_REG(BM_PORT_CTRL_PAGE, 27), - hw->fc.pause_time); + PHY_REG(BM_PORT_CTRL_PAGE, 27), + hw->fc.pause_time); if (ret_val) goto out; } @@ -3596,18 +3609,18 @@ static s32 e1000_setup_copper_link_ich8lan(struct e1000_hw *hw) * this fixes erroneous timeouts at 10Mbps. */ ret_val = e1000_write_kmrn_reg_generic(hw, E1000_KMRNCTRLSTA_TIMEOUTS, - 0xFFFF); + 0xFFFF); if (ret_val) goto out; ret_val = e1000_read_kmrn_reg_generic(hw, - E1000_KMRNCTRLSTA_INBAND_PARAM, - ®_data); + E1000_KMRNCTRLSTA_INBAND_PARAM, + ®_data); if (ret_val) goto out; reg_data |= 0x3F; ret_val = e1000_write_kmrn_reg_generic(hw, - E1000_KMRNCTRLSTA_INBAND_PARAM, - reg_data); + E1000_KMRNCTRLSTA_INBAND_PARAM, + reg_data); if (ret_val) goto out; @@ -3631,7 +3644,7 @@ static s32 e1000_setup_copper_link_ich8lan(struct e1000_hw *hw) break; case e1000_phy_ife: ret_val = hw->phy.ops.read_reg(hw, IFE_PHY_MDIX_CONTROL, - ®_data); + ®_data); if (ret_val) goto out; @@ -3650,7 +3663,7 @@ static s32 e1000_setup_copper_link_ich8lan(struct e1000_hw *hw) break; } ret_val = hw->phy.ops.write_reg(hw, IFE_PHY_MDIX_CONTROL, - reg_data); + reg_data); if (ret_val) goto out; break; @@ -3674,7 +3687,7 @@ static s32 e1000_setup_copper_link_ich8lan(struct e1000_hw *hw) * gigabit speeds. **/ static s32 e1000_get_link_up_info_ich8lan(struct e1000_hw *hw, u16 *speed, - u16 *duplex) + u16 *duplex) { s32 ret_val; @@ -3756,7 +3769,7 @@ static s32 e1000_kmrn_lock_loss_workaround_ich8lan(struct e1000_hw *hw) /* Disable GigE link negotiation */ phy_ctrl = E1000_READ_REG(hw, E1000_PHY_CTRL); phy_ctrl |= (E1000_PHY_CTRL_GBE_DISABLE | - E1000_PHY_CTRL_NOND0A_GBE_DISABLE); + E1000_PHY_CTRL_NOND0A_GBE_DISABLE); E1000_WRITE_REG(hw, E1000_PHY_CTRL, phy_ctrl); /* @@ -3781,7 +3794,7 @@ static s32 e1000_kmrn_lock_loss_workaround_ich8lan(struct e1000_hw *hw) * /disabled - FALSE). **/ void e1000_set_kmrn_lock_loss_workaround_ich8lan(struct e1000_hw *hw, - bool state) + bool state) { struct e1000_dev_spec_ich8lan *dev_spec = &hw->dev_spec.ich8lan; @@ -3823,7 +3836,7 @@ void e1000_igp3_phy_powerdown_workaround_ich8lan(struct e1000_hw *hw) /* Disable link */ reg = E1000_READ_REG(hw, E1000_PHY_CTRL); reg |= (E1000_PHY_CTRL_GBE_DISABLE | - E1000_PHY_CTRL_NOND0A_GBE_DISABLE); + E1000_PHY_CTRL_NOND0A_GBE_DISABLE); E1000_WRITE_REG(hw, E1000_PHY_CTRL, reg); /* @@ -3837,7 +3850,7 @@ void e1000_igp3_phy_powerdown_workaround_ich8lan(struct e1000_hw *hw) hw->phy.ops.read_reg(hw, IGP3_VR_CTRL, &data); data &= ~IGP3_VR_CTRL_DEV_POWERDOWN_MODE_MASK; hw->phy.ops.write_reg(hw, IGP3_VR_CTRL, - data | IGP3_VR_CTRL_MODE_SHUTDOWN); + data | IGP3_VR_CTRL_MODE_SHUTDOWN); /* Read it back and test */ hw->phy.ops.read_reg(hw, IGP3_VR_CTRL, &data); @@ -3863,7 +3876,7 @@ void e1000_igp3_phy_powerdown_workaround_ich8lan(struct e1000_hw *hw) * 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,51 +3886,54 @@ 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, - ®_data); + ®_data); if (ret_val) goto out; reg_data |= E1000_KMRNCTRLSTA_DIAG_NELPBK; ret_val = e1000_write_kmrn_reg_generic(hw, - E1000_KMRNCTRLSTA_DIAG_OFFSET, - reg_data); + E1000_KMRNCTRLSTA_DIAG_OFFSET, + reg_data); if (ret_val) goto out; reg_data &= ~E1000_KMRNCTRLSTA_DIAG_NELPBK; ret_val = e1000_write_kmrn_reg_generic(hw, - E1000_KMRNCTRLSTA_DIAG_OFFSET, - reg_data); + E1000_KMRNCTRLSTA_DIAG_OFFSET, + reg_data); out: return; } /** - * 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 @@ -3940,7 +4008,7 @@ static s32 e1000_cleanup_led_ich8lan(struct e1000_hw *hw) if (hw->phy.type == e1000_phy_ife) return hw->phy.ops.write_reg(hw, IFE_PHY_SPECIAL_CONTROL_LED, - 0); + 0); E1000_WRITE_REG(hw, E1000_LEDCTL, hw->mac.ledctl_default); return E1000_SUCCESS; @@ -3958,7 +4026,7 @@ static s32 e1000_led_on_ich8lan(struct e1000_hw *hw) if (hw->phy.type == e1000_phy_ife) return hw->phy.ops.write_reg(hw, IFE_PHY_SPECIAL_CONTROL_LED, - (IFE_PSCL_PROBE_MODE | IFE_PSCL_PROBE_LEDS_ON)); + (IFE_PSCL_PROBE_MODE | IFE_PSCL_PROBE_LEDS_ON)); E1000_WRITE_REG(hw, E1000_LEDCTL, hw->mac.ledctl_mode2); return E1000_SUCCESS; @@ -3976,7 +4044,7 @@ static s32 e1000_led_off_ich8lan(struct e1000_hw *hw) if (hw->phy.type == e1000_phy_ife) return hw->phy.ops.write_reg(hw, IFE_PHY_SPECIAL_CONTROL_LED, - (IFE_PSCL_PROBE_MODE | IFE_PSCL_PROBE_LEDS_OFF)); + (IFE_PSCL_PROBE_MODE | IFE_PSCL_PROBE_LEDS_OFF)); E1000_WRITE_REG(hw, E1000_LEDCTL, hw->mac.ledctl_mode1); return E1000_SUCCESS; @@ -3993,7 +4061,7 @@ static s32 e1000_setup_led_pchlan(struct e1000_hw *hw) DEBUGFUNC("e1000_setup_led_pchlan"); return hw->phy.ops.write_reg(hw, HV_LED_CONFIG, - (u16)hw->mac.ledctl_mode1); + (u16)hw->mac.ledctl_mode1); } /** @@ -4007,7 +4075,7 @@ static s32 e1000_cleanup_led_pchlan(struct e1000_hw *hw) DEBUGFUNC("e1000_cleanup_led_pchlan"); return hw->phy.ops.write_reg(hw, HV_LED_CONFIG, - (u16)hw->mac.ledctl_default); + (u16)hw->mac.ledctl_default); } /** @@ -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); } } diff --git a/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_ich8lan.h b/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_ich8lan.h index 26dbaffba0a..2eccb30046d 100644 --- a/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_ich8lan.h +++ b/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_ich8lan.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,187 +30,209 @@ 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_ -#define ICH_FLASH_GFPREG 0x0000 -#define ICH_FLASH_HSFSTS 0x0004 -#define ICH_FLASH_HSFCTL 0x0006 -#define ICH_FLASH_FADDR 0x0008 -#define ICH_FLASH_FDATA0 0x0010 +#define ICH_FLASH_GFPREG 0x0000 +#define ICH_FLASH_HSFSTS 0x0004 +#define ICH_FLASH_HSFCTL 0x0006 +#define ICH_FLASH_FADDR 0x0008 +#define ICH_FLASH_FDATA0 0x0010 /* Requires up to 10 seconds when MNG might be accessing part. */ -#define ICH_FLASH_READ_COMMAND_TIMEOUT 10000000 -#define ICH_FLASH_WRITE_COMMAND_TIMEOUT 10000000 -#define ICH_FLASH_ERASE_COMMAND_TIMEOUT 10000000 -#define ICH_FLASH_LINEAR_ADDR_MASK 0x00FFFFFF -#define ICH_FLASH_CYCLE_REPEAT_COUNT 10 +#define ICH_FLASH_READ_COMMAND_TIMEOUT 10000000 +#define ICH_FLASH_WRITE_COMMAND_TIMEOUT 10000000 +#define ICH_FLASH_ERASE_COMMAND_TIMEOUT 10000000 +#define ICH_FLASH_LINEAR_ADDR_MASK 0x00FFFFFF +#define ICH_FLASH_CYCLE_REPEAT_COUNT 10 -#define ICH_CYCLE_READ 0 -#define ICH_CYCLE_WRITE 2 -#define ICH_CYCLE_ERASE 3 +#define ICH_CYCLE_READ 0 +#define ICH_CYCLE_WRITE 2 +#define ICH_CYCLE_ERASE 3 -#define FLASH_GFPREG_BASE_MASK 0x1FFF -#define FLASH_SECTOR_ADDR_SHIFT 12 +#define FLASH_GFPREG_BASE_MASK 0x1FFF +#define FLASH_SECTOR_ADDR_SHIFT 12 -#define ICH_FLASH_SEG_SIZE_256 256 -#define ICH_FLASH_SEG_SIZE_4K 4096 -#define ICH_FLASH_SEG_SIZE_8K 8192 -#define ICH_FLASH_SEG_SIZE_64K 65536 -#define ICH_FLASH_SECTOR_SIZE 4096 +#define ICH_FLASH_SEG_SIZE_256 256 +#define ICH_FLASH_SEG_SIZE_4K 4096 +#define ICH_FLASH_SEG_SIZE_8K 8192 +#define ICH_FLASH_SEG_SIZE_64K 65536 +#define ICH_FLASH_SECTOR_SIZE 4096 -#define ICH_FLASH_REG_MAPSIZE 0x00A0 +#define ICH_FLASH_REG_MAPSIZE 0x00A0 -#define E1000_ICH_FWSM_RSPCIPHY 0x00000040 /* Reset PHY on PCI Reset */ -#define E1000_ICH_FWSM_DISSW 0x10000000 /* FW Disables SW Writes */ +#define E1000_ICH_FWSM_RSPCIPHY 0x00000040 /* Reset PHY on PCI Reset */ +#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_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_ICH_MNG_IAMT_MODE 0x2 -#define E1000_FWSM_PROXY_MODE 0x00000008 /* FW is in proxy mode */ +#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)) -#define E1000_SHRAH(_i) (0x0543C + ((_i) * 8)) -#define E1000_SHRAH_AV 0x80000000 /* Addr Valid bit */ -#define E1000_SHRAH_MAV 0x40000000 /* Multicast Addr Valid bit */ - -#define E1000_H2ME 0x05B50 /* Host to ME */ -#define E1000_H2ME_LSECREQ 0x00000001 /* Linksec Request */ -#define E1000_H2ME_LSECA 0x00000002 /* Linksec Active */ -#define E1000_H2ME_LSECSF 0x00000004 /* Linksec Failed */ -#define E1000_H2ME_LSECD 0x00000008 /* Linksec Disabled */ -#define E1000_H2ME_SLCAPD 0x00000010 /* Start LCAPD */ -#define E1000_H2ME_IPV4_ARP_EN 0x00000020 /* Arp Offload enable bit */ -#define E1000_H2ME_IPV6_NS_EN 0x00000040 /* NS Offload enable bit */ - -#define ID_LED_DEFAULT_ICH8LAN ((ID_LED_DEF1_DEF2 << 12) | \ - (ID_LED_OFF1_OFF2 << 8) | \ - (ID_LED_OFF1_ON2 << 4) | \ - (ID_LED_DEF1_DEF2)) - -#define E1000_ICH_NVM_SIG_WORD 0x13 -#define E1000_ICH_NVM_SIG_MASK 0xC000 -#define E1000_ICH_NVM_VALID_SIG_MASK 0xC0 -#define E1000_ICH_NVM_SIG_VALUE 0x80 - -#define E1000_ICH8_LAN_INIT_TIMEOUT 1500 - -#define E1000_FEXTNVM_SW_CONFIG 1 -#define E1000_FEXTNVM_SW_CONFIG_ICH8M (1 << 27) /* Bit redefined for ICH8M */ - -#define E1000_FEXTNVM4_BEACON_DURATION_MASK 0x7 -#define E1000_FEXTNVM4_BEACON_DURATION_8USEC 0x7 -#define E1000_FEXTNVM4_BEACON_DURATION_16USEC 0x3 - -#define PCIE_ICH8_SNOOP_ALL PCIE_NO_SNOOP_ALL - -#define E1000_ICH_RAR_ENTRIES 7 -#define E1000_PCH2_RAR_ENTRIES 5 /* RAR[0], SHRA[0-3] */ - -#define PHY_PAGE_SHIFT 5 -#define PHY_REG(page, reg) (((page) << PHY_PAGE_SHIFT) | \ - ((reg) & MAX_PHY_REG_ADDRESS)) -#define IGP3_KMRN_DIAG PHY_REG(770, 19) /* KMRN Diagnostic */ -#define IGP3_VR_CTRL PHY_REG(776, 18) /* Voltage Regulator Control */ -#define IGP3_CAPABILITY PHY_REG(776, 19) /* Capability */ -#define IGP3_PM_CTRL PHY_REG(769, 20) /* Power Management Control */ - -#define IGP3_KMRN_DIAG_PCS_LOCK_LOSS 0x0002 -#define IGP3_VR_CTRL_DEV_POWERDOWN_MODE_MASK 0x0300 -#define IGP3_VR_CTRL_MODE_SHUTDOWN 0x0200 -#define IGP3_PM_CTRL_FORCE_PWR_DOWN 0x0020 +#define E1000_SHRAL(_i) (0x05438 + ((_i) * 8)) +#define E1000_SHRAH(_i) (0x0543C + ((_i) * 8)) +#define E1000_SHRAH_AV 0x80000000 /* Addr Valid bit */ +#define E1000_SHRAH_MAV 0x40000000 /* Multicast Addr Valid bit */ + +#define E1000_H2ME 0x05B50 /* Host to ME */ +#define E1000_H2ME_LSECREQ 0x00000001 /* Linksec Request */ +#define E1000_H2ME_LSECA 0x00000002 /* Linksec Active */ +#define E1000_H2ME_LSECSF 0x00000004 /* Linksec Failed */ +#define E1000_H2ME_LSECD 0x00000008 /* Linksec Disabled */ +#define E1000_H2ME_SLCAPD 0x00000010 /* Start LCAPD */ +#define E1000_H2ME_IPV4_ARP_EN 0x00000020 /* Arp Offload enable bit */ +#define E1000_H2ME_IPV6_NS_EN 0x00000040 /* NS Offload enable bit */ + +#define ID_LED_DEFAULT_ICH8LAN ((ID_LED_DEF1_DEF2 << 12) | \ + (ID_LED_OFF1_OFF2 << 8) | \ + (ID_LED_OFF1_ON2 << 4) | \ + (ID_LED_DEF1_DEF2)) + +#define E1000_ICH_NVM_SIG_WORD 0x13 +#define E1000_ICH_NVM_SIG_MASK 0xC000 +#define E1000_ICH_NVM_VALID_SIG_MASK 0xC0 +#define E1000_ICH_NVM_SIG_VALUE 0x80 + +#define E1000_ICH8_LAN_INIT_TIMEOUT 1500 + +#define E1000_FEXTNVM_SW_CONFIG 1 +#define E1000_FEXTNVM_SW_CONFIG_ICH8M (1 << 27) /* Bit redefined for ICH8M */ + +#define E1000_FEXTNVM4_BEACON_DURATION_MASK 0x7 +#define E1000_FEXTNVM4_BEACON_DURATION_8USEC 0x7 +#define E1000_FEXTNVM4_BEACON_DURATION_16USEC 0x3 + +#define PCIE_ICH8_SNOOP_ALL PCIE_NO_SNOOP_ALL + +#define E1000_ICH_RAR_ENTRIES 7 +#define E1000_PCH2_RAR_ENTRIES 5 /* RAR[0], SHRA[0-3] */ + +#define PHY_PAGE_SHIFT 5 +#define PHY_REG(page, reg) (((page) << PHY_PAGE_SHIFT) | \ + ((reg) & MAX_PHY_REG_ADDRESS)) +#define IGP3_KMRN_DIAG PHY_REG(770, 19) /* KMRN Diagnostic */ +#define IGP3_VR_CTRL PHY_REG(776, 18) /* Voltage Regulator Control */ +#define IGP3_CAPABILITY PHY_REG(776, 19) /* Capability */ +#define IGP3_PM_CTRL PHY_REG(769, 20) /* Power Management Control */ + +#define IGP3_KMRN_DIAG_PCS_LOCK_LOSS 0x0002 +#define IGP3_VR_CTRL_DEV_POWERDOWN_MODE_MASK 0x0300 +#define IGP3_VR_CTRL_MODE_SHUTDOWN 0x0200 +#define IGP3_PM_CTRL_FORCE_PWR_DOWN 0x0020 /* PHY Wakeup Registers and defines */ -#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) -#define BM_WUS PHY_REG(BM_WUC_PAGE, 3) -#define BM_RAR_L(_i) (BM_PHY_REG(BM_WUC_PAGE, 16 + ((_i) << 2))) -#define BM_RAR_M(_i) (BM_PHY_REG(BM_WUC_PAGE, 17 + ((_i) << 2))) -#define BM_RAR_H(_i) (BM_PHY_REG(BM_WUC_PAGE, 18 + ((_i) << 2))) -#define BM_RAR_CTRL(_i) (BM_PHY_REG(BM_WUC_PAGE, 19 + ((_i) << 2))) -#define BM_MTA(_i) (BM_PHY_REG(BM_WUC_PAGE, 128 + ((_i) << 1))) -#define BM_IPAV (BM_PHY_REG(BM_WUC_PAGE, 64)) -#define BM_IP4AT_L(_i) (BM_PHY_REG(BM_WUC_PAGE, 82 + ((_i) * 2))) -#define BM_IP4AT_H(_i) (BM_PHY_REG(BM_WUC_PAGE, 83 + ((_i) * 2))) - -#define BM_SHRAL_LOWER(_i) (BM_PHY_REG(BM_WUC_PAGE, 44 + ((_i) * 4))) -#define BM_SHRAL_UPPER(_i) (BM_PHY_REG(BM_WUC_PAGE, 45 + ((_i) * 4))) -#define BM_SHRAH_LOWER(_i) (BM_PHY_REG(BM_WUC_PAGE, 46 + ((_i) * 4))) -#define BM_SHRAH_UPPER(_i) (BM_PHY_REG(BM_WUC_PAGE, 47 + ((_i) * 4))) - -#define BM_RCTL_UPE 0x0001 /* Unicast Promiscuous Mode */ -#define BM_RCTL_MPE 0x0002 /* Multicast Promiscuous Mode */ -#define BM_RCTL_MO_SHIFT 3 /* Multicast Offset Shift */ -#define BM_RCTL_MO_MASK (3 << 3) /* Multicast Offset Mask */ -#define BM_RCTL_BAM 0x0020 /* Broadcast Accept Mode */ -#define BM_RCTL_PMCF 0x0040 /* Pass MAC Control Frames */ -#define BM_RCTL_RFCE 0x0080 /* Rx Flow Control Enable */ - -#define HV_LED_CONFIG PHY_REG(768, 30) /* LED Configuration */ -#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 E1000_FCRTV_PCH 0x05F40 /* PCH Flow Control Refresh Timer Value */ - -#define E1000_NVM_K1_CONFIG 0x1B /* NVM K1 Config Word */ -#define E1000_NVM_K1_ENABLE 0x1 /* NVM Enable K1 bit */ +#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) +#define BM_WUS PHY_REG(BM_WUC_PAGE, 3) +#define BM_RAR_L(_i) (BM_PHY_REG(BM_WUC_PAGE, 16 + ((_i) << 2))) +#define BM_RAR_M(_i) (BM_PHY_REG(BM_WUC_PAGE, 17 + ((_i) << 2))) +#define BM_RAR_H(_i) (BM_PHY_REG(BM_WUC_PAGE, 18 + ((_i) << 2))) +#define BM_RAR_CTRL(_i) (BM_PHY_REG(BM_WUC_PAGE, 19 + ((_i) << 2))) +#define BM_MTA(_i) (BM_PHY_REG(BM_WUC_PAGE, 128 + ((_i) << 1))) +#define BM_IPAV (BM_PHY_REG(BM_WUC_PAGE, 64)) +#define BM_IP4AT_L(_i) (BM_PHY_REG(BM_WUC_PAGE, 82 + ((_i) * 2))) +#define BM_IP4AT_H(_i) (BM_PHY_REG(BM_WUC_PAGE, 83 + ((_i) * 2))) + +#define BM_SHRAL_LOWER(_i) (BM_PHY_REG(BM_WUC_PAGE, 44 + ((_i) * 4))) +#define BM_SHRAL_UPPER(_i) (BM_PHY_REG(BM_WUC_PAGE, 45 + ((_i) * 4))) +#define BM_SHRAH_LOWER(_i) (BM_PHY_REG(BM_WUC_PAGE, 46 + ((_i) * 4))) +#define BM_SHRAH_UPPER(_i) (BM_PHY_REG(BM_WUC_PAGE, 47 + ((_i) * 4))) + +#define BM_RCTL_UPE 0x0001 /* Unicast Promiscuous Mode */ +#define BM_RCTL_MPE 0x0002 /* Multicast Promiscuous Mode */ +#define BM_RCTL_MO_SHIFT 3 /* Multicast Offset Shift */ +#define BM_RCTL_MO_MASK (3 << 3) /* Multicast Offset Mask */ +#define BM_RCTL_BAM 0x0020 /* Broadcast Accept Mode */ +#define BM_RCTL_PMCF 0x0040 /* Pass MAC Control Frames */ +#define BM_RCTL_RFCE 0x0080 /* Rx Flow Control Enable */ + +#define HV_LED_CONFIG PHY_REG(768, 30) /* LED Configuration */ +#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_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 */ /* SMBus Address Phy Register */ -#define HV_SMB_ADDR PHY_REG(768, 26) -#define HV_SMB_ADDR_MASK 0x007F -#define HV_SMB_ADDR_PEC_EN 0x0200 -#define HV_SMB_ADDR_VALID 0x0080 +#define HV_SMB_ADDR PHY_REG(768, 26) +#define HV_SMB_ADDR_MASK 0x007F +#define HV_SMB_ADDR_PEC_EN 0x0200 +#define HV_SMB_ADDR_VALID 0x0080 /* Strapping Option Register - RO */ -#define E1000_STRAP 0x0000C -#define E1000_STRAP_SMBUS_ADDRESS_MASK 0x00FE0000 -#define E1000_STRAP_SMBUS_ADDRESS_SHIFT 17 +#define E1000_STRAP 0x0000C +#define E1000_STRAP_SMBUS_ADDRESS_MASK 0x00FE0000 +#define E1000_STRAP_SMBUS_ADDRESS_SHIFT 17 /* OEM Bits Phy Register */ -#define HV_OEM_BITS PHY_REG(768, 25) -#define HV_OEM_BITS_LPLU 0x0004 /* Low Power Link Up */ -#define HV_OEM_BITS_GBE_DIS 0x0040 /* Gigabit Disable */ -#define HV_OEM_BITS_RESTART_AN 0x0400 /* Restart Auto-negotiation */ +#define HV_OEM_BITS PHY_REG(768, 25) +#define HV_OEM_BITS_LPLU 0x0004 /* Low Power Link Up */ +#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 +#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 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 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_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: @@ -219,33 +241,32 @@ * EPRST = Manageability reset event */ #define IMS_ICH_ENABLE_MASK (\ - E1000_IMS_DSW | \ - E1000_IMS_PHYINT | \ - E1000_IMS_EPRST) + E1000_IMS_DSW | \ + E1000_IMS_PHYINT | \ + E1000_IMS_EPRST) /* Additional interrupt register bit definitions */ -#define E1000_ICR_LSECPNC 0x00004000 /* PN threshold - client */ -#define E1000_IMS_LSECPNC E1000_ICR_LSECPNC /* PN threshold - client */ -#define E1000_ICS_LSECPNC E1000_ICR_LSECPNC /* PN threshold - client */ +#define E1000_ICR_LSECPNC 0x00004000 /* PN threshold - client */ +#define E1000_IMS_LSECPNC E1000_ICR_LSECPNC /* PN threshold - client */ +#define E1000_ICS_LSECPNC E1000_ICR_LSECPNC /* PN threshold - client */ /* Security Processing bit Indication */ -#define E1000_RXDEXT_LINKSEC_STATUS_LSECH 0x01000000 -#define E1000_RXDEXT_LINKSEC_ERROR_BIT_MASK 0x60000000 -#define E1000_RXDEXT_LINKSEC_ERROR_NO_SA_MATCH 0x20000000 -#define E1000_RXDEXT_LINKSEC_ERROR_REPLAY_ERROR 0x40000000 -#define E1000_RXDEXT_LINKSEC_ERROR_BAD_SIG 0x60000000 +#define E1000_RXDEXT_LINKSEC_STATUS_LSECH 0x01000000 +#define E1000_RXDEXT_LINKSEC_ERROR_BIT_MASK 0x60000000 +#define E1000_RXDEXT_LINKSEC_ERROR_NO_SA_MATCH 0x20000000 +#define E1000_RXDEXT_LINKSEC_ERROR_REPLAY_ERROR 0x40000000 +#define E1000_RXDEXT_LINKSEC_ERROR_BAD_SIG 0x60000000 /* Receive Address Initial CRC Calculation */ -#define E1000_PCH_RAICC(_n) (0x05F50 + ((_n) * 4)) +#define E1000_PCH_RAICC(_n) (0x05F50 + ((_n) * 4)) void e1000_set_kmrn_lock_loss_workaround_ich8lan(struct e1000_hw *hw, - bool state); + 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 diff --git a/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_mac.c b/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_mac.c index a68aba78756..95d6873b13f 100644 --- a/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_mac.c +++ b/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_mac.c @@ -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,12 +30,14 @@ POSSIBILITY OF SUCH DAMAGE. ******************************************************************************/ -/*$FreeBSD: src/sys/dev/e1000/e1000_mac.c,v 1.4.2.3.2.1 2010/12/21 17:09:25 kensmith Exp $*/ +/*$FreeBSD$*/ #include "e1000_api.h" static s32 e1000_validate_mdi_setting_generic(struct e1000_hw *hw); static void e1000_set_lan_id_multi_port_pcie(struct e1000_hw *hw); +static void e1000_config_collision_dist_generic(struct e1000_hw *hw); +static void e1000_rar_set_generic(struct e1000_hw *hw, u8 *addr, u32 index); /** * e1000_init_mac_ops_generic - Initialize MAC function pointers @@ -177,8 +179,8 @@ s32 e1000_get_bus_info_pci_generic(struct e1000_hw *hw) /* Bus speed */ if (bus->type == e1000_bus_type_pci) { bus->speed = (status & E1000_STATUS_PCI66) - ? e1000_bus_speed_66 - : e1000_bus_speed_33; + ? e1000_bus_speed_66 + : e1000_bus_speed_33; } else { switch (status & E1000_STATUS_PCIX_SPEED) { case E1000_STATUS_PCIX_SPEED_66: @@ -198,8 +200,8 @@ s32 e1000_get_bus_info_pci_generic(struct e1000_hw *hw) /* Bus width */ bus->width = (status & E1000_STATUS_BUS64) - ? e1000_bus_width_64 - : e1000_bus_width_32; + ? e1000_bus_width_64 + : e1000_bus_width_32; /* Which PCI(-X) function? */ mac->ops.set_lan_id(hw); @@ -226,9 +228,8 @@ s32 e1000_get_bus_info_pcie_generic(struct e1000_hw *hw) bus->type = e1000_bus_type_pci_express; - ret_val = e1000_read_pcie_cap_reg(hw, - PCIE_LINK_STATUS, - &pcie_link_status); + ret_val = e1000_read_pcie_cap_reg(hw, PCIE_LINK_STATUS, + &pcie_link_status); if (ret_val) { bus->width = e1000_bus_width_unknown; bus->speed = e1000_bus_speed_unknown; @@ -246,8 +247,7 @@ s32 e1000_get_bus_info_pcie_generic(struct e1000_hw *hw) } bus->width = (enum e1000_bus_width)((pcie_link_status & - PCIE_LINK_WIDTH_MASK) >> - PCIE_LINK_WIDTH_SHIFT); + PCIE_LINK_WIDTH_MASK) >> PCIE_LINK_WIDTH_SHIFT); } mac->ops.set_lan_id(hw); @@ -292,7 +292,7 @@ void e1000_set_lan_id_multi_port_pci(struct e1000_hw *hw) if (pci_header_type & PCI_HEADER_TYPE_MULTIFUNC) { status = E1000_READ_REG(hw, E1000_STATUS); bus->func = (status & E1000_STATUS_FUNC_MASK) - >> E1000_STATUS_FUNC_SHIFT; + >> E1000_STATUS_FUNC_SHIFT; } else { bus->func = 0; } @@ -352,7 +352,7 @@ void e1000_write_vfta_generic(struct e1000_hw *hw, u32 offset, u32 value) * @hw: pointer to the HW structure * @rar_count: receive address registers * - * Setups the receive address registers by setting the base receive address + * Setup the receive address registers by setting the base receive address * register to the devices MAC address and clearing all the other receive * address registers to 0. **/ @@ -397,25 +397,30 @@ s32 e1000_check_alt_mac_addr_generic(struct e1000_hw *hw) ret_val = hw->nvm.ops.read(hw, NVM_COMPAT, 1, &nvm_data); if (ret_val) - goto out; + return ret_val; - /* Check for LOM (vs. NIC) or one of two valid mezzanine cards */ - if (!((nvm_data & NVM_COMPAT_LOM) || - (hw->device_id == E1000_DEV_ID_82571EB_SERDES_DUAL) || - (hw->device_id == E1000_DEV_ID_82571EB_SERDES_QUAD))) - goto out; + /* not supported on older hardware or 82573 */ + if ((hw->mac.type < e1000_82571) || (hw->mac.type == e1000_82573)) + return E1000_SUCCESS; + + /* + * Alternate MAC address is handled by the option ROM for 82580 + * and newer. SW support not required. + */ + if (hw->mac.type >= e1000_82580) + return E1000_SUCCESS; ret_val = hw->nvm.ops.read(hw, NVM_ALT_MAC_ADDR_PTR, 1, - &nvm_alt_mac_addr_offset); + &nvm_alt_mac_addr_offset); if (ret_val) { DEBUGOUT("NVM Read Error\n"); - goto out; + return ret_val; } - if (nvm_alt_mac_addr_offset == 0xFFFF) { + if ((nvm_alt_mac_addr_offset == 0xFFFF) || + (nvm_alt_mac_addr_offset == 0x0000)) /* There is no Alternate MAC Address */ - goto out; - } + return E1000_SUCCESS; if (hw->bus.func == E1000_FUNC_1) nvm_alt_mac_addr_offset += E1000_ALT_MAC_ADDRESS_OFFSET_LAN1; @@ -429,7 +434,7 @@ s32 e1000_check_alt_mac_addr_generic(struct e1000_hw *hw) ret_val = hw->nvm.ops.read(hw, offset, 1, &nvm_data); if (ret_val) { DEBUGOUT("NVM Read Error\n"); - goto out; + return ret_val; } alt_mac_addr[i] = (u8)(nvm_data & 0xFF); @@ -439,7 +444,7 @@ s32 e1000_check_alt_mac_addr_generic(struct e1000_hw *hw) /* if multicast bit is set, the alternate address will not be used */ if (alt_mac_addr[0] & 0x01) { DEBUGOUT("Ignoring Alternate Mac Address with MC bit set\n"); - goto out; + return E1000_SUCCESS; } /* @@ -449,8 +454,7 @@ s32 e1000_check_alt_mac_addr_generic(struct e1000_hw *hw) */ hw->mac.ops.rar_set(hw, alt_mac_addr, 0); -out: - return ret_val; + return E1000_SUCCESS; } /** @@ -462,7 +466,7 @@ s32 e1000_check_alt_mac_addr_generic(struct e1000_hw *hw) * Sets the receive address array register at index to the address passed * in by addr. **/ -void e1000_rar_set_generic(struct e1000_hw *hw, u8 *addr, u32 index) +static void e1000_rar_set_generic(struct e1000_hw *hw, u8 *addr, u32 index) { u32 rar_low, rar_high; @@ -472,9 +476,8 @@ void e1000_rar_set_generic(struct e1000_hw *hw, u8 *addr, u32 index) * HW expects these in little endian so we reverse the byte order * from network order (big endian) to little endian */ - rar_low = ((u32) addr[0] | - ((u32) addr[1] << 8) | - ((u32) addr[2] << 16) | ((u32) addr[3] << 24)); + rar_low = ((u32) addr[0] | ((u32) addr[1] << 8) | + ((u32) addr[2] << 16) | ((u32) addr[3] << 24)); rar_high = ((u32) addr[4] | ((u32) addr[5] << 8)); @@ -493,43 +496,6 @@ void e1000_rar_set_generic(struct e1000_hw *hw, u8 *addr, u32 index) E1000_WRITE_FLUSH(hw); } -/** - * e1000_update_mc_addr_list_generic - Update Multicast addresses - * @hw: pointer to the HW structure - * @mc_addr_list: array of multicast addresses to program - * @mc_addr_count: number of multicast addresses to program - * - * Updates entire Multicast Table Array. - * The caller must have a packed mc_addr_list of multicast addresses. - **/ -void e1000_update_mc_addr_list_generic(struct e1000_hw *hw, - u8 *mc_addr_list, u32 mc_addr_count) -{ - u32 hash_value, hash_bit, hash_reg; - int i; - - DEBUGFUNC("e1000_update_mc_addr_list_generic"); - - /* clear mta_shadow */ - memset(&hw->mac.mta_shadow, 0, sizeof(hw->mac.mta_shadow)); - - /* update mta_shadow from mc_addr_list */ - for (i = 0; (u32) i < mc_addr_count; i++) { - hash_value = e1000_hash_mc_addr_generic(hw, mc_addr_list); - - hash_reg = (hash_value >> 5) & (hw->mac.mta_reg_count - 1); - hash_bit = hash_value & 0x1F; - - hw->mac.mta_shadow[hash_reg] |= (1 << hash_bit); - mc_addr_list += (ETH_ADDR_LEN); - } - - /* replace the entire MTA table */ - for (i = hw->mac.mta_reg_count - 1; i >= 0; i--) - E1000_WRITE_REG_ARRAY(hw, E1000_MTA, i, hw->mac.mta_shadow[i]); - E1000_WRITE_FLUSH(hw); -} - /** * e1000_hash_mc_addr_generic - Generate a multicast hash value * @hw: pointer to the HW structure @@ -574,7 +540,7 @@ u32 e1000_hash_mc_addr_generic(struct e1000_hw *hw, u8 *mc_addr) * values resulting from each mc_filter_type... * [0] [1] [2] [3] [4] [5] * 01 AA 00 12 34 56 - * LSB MSB + * LSB MSB * * case 0: hash_value = ((0x34 >> 4) | (0x56 << 4)) & 0xFFF = 0x563 * case 1: hash_value = ((0x34 >> 3) | (0x56 << 5)) & 0xFFF = 0xAC6 @@ -597,11 +563,48 @@ u32 e1000_hash_mc_addr_generic(struct e1000_hw *hw, u8 *mc_addr) } hash_value = hash_mask & (((mc_addr[4] >> (8 - bit_shift)) | - (((u16) mc_addr[5]) << bit_shift))); + (((u16) mc_addr[5]) << bit_shift))); return hash_value; } +/** + * e1000_update_mc_addr_list_generic - Update Multicast addresses + * @hw: pointer to the HW structure + * @mc_addr_list: array of multicast addresses to program + * @mc_addr_count: number of multicast addresses to program + * + * Updates entire Multicast Table Array. + * The caller must have a packed mc_addr_list of multicast addresses. + **/ +void e1000_update_mc_addr_list_generic(struct e1000_hw *hw, + u8 *mc_addr_list, u32 mc_addr_count) +{ + u32 hash_value, hash_bit, hash_reg; + int i; + + DEBUGFUNC("e1000_update_mc_addr_list_generic"); + + /* clear mta_shadow */ + memset(&hw->mac.mta_shadow, 0, sizeof(hw->mac.mta_shadow)); + + /* update mta_shadow from mc_addr_list */ + for (i = 0; (u32) i < mc_addr_count; i++) { + hash_value = e1000_hash_mc_addr_generic(hw, mc_addr_list); + + hash_reg = (hash_value >> 5) & (hw->mac.mta_reg_count - 1); + hash_bit = hash_value & 0x1F; + + hw->mac.mta_shadow[hash_reg] |= (1 << hash_bit); + mc_addr_list += (ETH_ADDR_LEN); + } + + /* replace the entire MTA table */ + for (i = hw->mac.mta_reg_count - 1; i >= 0; i--) + E1000_WRITE_REG_ARRAY(hw, E1000_MTA, i, hw->mac.mta_shadow[i]); + E1000_WRITE_FLUSH(hw); +} + /** * e1000_pcix_mmrbc_workaround_generic - Fix incorrect MMRBC value * @hw: pointer to the HW structure @@ -627,9 +630,9 @@ void e1000_pcix_mmrbc_workaround_generic(struct e1000_hw *hw) e1000_read_pci_cfg(hw, PCIX_COMMAND_REGISTER, &pcix_cmd); e1000_read_pci_cfg(hw, PCIX_STATUS_REGISTER_HI, &pcix_stat_hi_word); cmd_mmrbc = (pcix_cmd & PCIX_COMMAND_MMRBC_MASK) >> - PCIX_COMMAND_MMRBC_SHIFT; + PCIX_COMMAND_MMRBC_SHIFT; stat_mmrbc = (pcix_stat_hi_word & PCIX_STATUS_HI_MMRBC_MASK) >> - PCIX_STATUS_HI_MMRBC_SHIFT; + PCIX_STATUS_HI_MMRBC_SHIFT; if (stat_mmrbc == PCIX_STATUS_HI_MMRBC_4K) stat_mmrbc = PCIX_STATUS_HI_MMRBC_2K; if (cmd_mmrbc > stat_mmrbc) { @@ -710,10 +713,8 @@ s32 e1000_check_for_copper_link_generic(struct e1000_hw *hw) * get_link_status flag is set upon receiving a Link Status * Change or Rx Sequence Error interrupt. */ - if (!mac->get_link_status) { - ret_val = E1000_SUCCESS; - goto out; - } + if (!mac->get_link_status) + return E1000_SUCCESS; /* * First we want to see if the MII Status Register reports @@ -722,10 +723,10 @@ s32 e1000_check_for_copper_link_generic(struct e1000_hw *hw) */ ret_val = e1000_phy_has_link_generic(hw, 1, 0, &link); if (ret_val) - goto out; + return ret_val; if (!link) - goto out; /* No link detected */ + return E1000_SUCCESS; /* No link detected */ mac->get_link_status = FALSE; @@ -739,10 +740,8 @@ s32 e1000_check_for_copper_link_generic(struct e1000_hw *hw) * If we are forcing speed/duplex, then we simply return since * we have already determined whether we have link or not. */ - if (!mac->autoneg) { - ret_val = -E1000_ERR_CONFIG; - goto out; - } + if (!mac->autoneg) + return -E1000_ERR_CONFIG; /* * Auto-Neg is enabled. Auto Speed Detection takes care @@ -761,7 +760,6 @@ s32 e1000_check_for_copper_link_generic(struct e1000_hw *hw) if (ret_val) DEBUGOUT("Error configuring flow control\n"); -out: return ret_val; } @@ -778,7 +776,7 @@ s32 e1000_check_for_fiber_link_generic(struct e1000_hw *hw) u32 rxcw; u32 ctrl; u32 status; - s32 ret_val = E1000_SUCCESS; + s32 ret_val; DEBUGFUNC("e1000_check_for_fiber_link_generic"); @@ -795,11 +793,11 @@ s32 e1000_check_for_fiber_link_generic(struct e1000_hw *hw) * was just plugged in. The autoneg_failed flag does this. */ /* (ctrl & E1000_CTRL_SWDPIN1) == 1 == have signal */ - if ((ctrl & E1000_CTRL_SWDPIN1) && (!(status & E1000_STATUS_LU)) && - (!(rxcw & E1000_RXCW_C))) { - if (mac->autoneg_failed == 0) { - mac->autoneg_failed = 1; - goto out; + if ((ctrl & E1000_CTRL_SWDPIN1) && !(status & E1000_STATUS_LU) && + !(rxcw & E1000_RXCW_C)) { + if (!mac->autoneg_failed) { + mac->autoneg_failed = TRUE; + return E1000_SUCCESS; } DEBUGOUT("NOT Rx'ing /C/, disable AutoNeg and force link.\n"); @@ -815,7 +813,7 @@ s32 e1000_check_for_fiber_link_generic(struct e1000_hw *hw) ret_val = e1000_config_fc_after_link_up_generic(hw); if (ret_val) { DEBUGOUT("Error configuring flow control\n"); - goto out; + return ret_val; } } else if ((ctrl & E1000_CTRL_SLU) && (rxcw & E1000_RXCW_C)) { /* @@ -831,8 +829,7 @@ s32 e1000_check_for_fiber_link_generic(struct e1000_hw *hw) mac->serdes_has_link = TRUE; } -out: - return ret_val; + return E1000_SUCCESS; } /** @@ -848,7 +845,7 @@ s32 e1000_check_for_serdes_link_generic(struct e1000_hw *hw) u32 rxcw; u32 ctrl; u32 status; - s32 ret_val = E1000_SUCCESS; + s32 ret_val; DEBUGFUNC("e1000_check_for_serdes_link_generic"); @@ -864,10 +861,10 @@ s32 e1000_check_for_serdes_link_generic(struct e1000_hw *hw) * time to complete. */ /* (ctrl & E1000_CTRL_SWDPIN1) == 1 == have signal */ - if ((!(status & E1000_STATUS_LU)) && (!(rxcw & E1000_RXCW_C))) { - if (mac->autoneg_failed == 0) { - mac->autoneg_failed = 1; - goto out; + if (!(status & E1000_STATUS_LU) && !(rxcw & E1000_RXCW_C)) { + if (!mac->autoneg_failed) { + mac->autoneg_failed = TRUE; + return E1000_SUCCESS; } DEBUGOUT("NOT Rx'ing /C/, disable AutoNeg and force link.\n"); @@ -883,7 +880,7 @@ s32 e1000_check_for_serdes_link_generic(struct e1000_hw *hw) ret_val = e1000_config_fc_after_link_up_generic(hw); if (ret_val) { DEBUGOUT("Error configuring flow control\n"); - goto out; + return ret_val; } } else if ((ctrl & E1000_CTRL_SLU) && (rxcw & E1000_RXCW_C)) { /* @@ -926,12 +923,10 @@ s32 e1000_check_for_serdes_link_generic(struct e1000_hw *hw) if (rxcw & E1000_RXCW_SYNCH) { if (!(rxcw & E1000_RXCW_IV)) { mac->serdes_has_link = TRUE; - DEBUGOUT("SERDES: Link up - autoneg " - "completed sucessfully.\n"); + DEBUGOUT("SERDES: Link up - autoneg completed successfully.\n"); } else { mac->serdes_has_link = FALSE; - DEBUGOUT("SERDES: Link down - invalid" - "codewords detected in autoneg.\n"); + DEBUGOUT("SERDES: Link down - invalid codewords detected in autoneg.\n"); } } else { mac->serdes_has_link = FALSE; @@ -943,8 +938,48 @@ s32 e1000_check_for_serdes_link_generic(struct e1000_hw *hw) } } -out: - return ret_val; + return E1000_SUCCESS; +} + +/** + * e1000_set_default_fc_generic - Set flow control default values + * @hw: pointer to the HW structure + * + * Read the EEPROM for the default values for flow control and store the + * values. + **/ +s32 e1000_set_default_fc_generic(struct e1000_hw *hw) +{ + s32 ret_val; + u16 nvm_data; + + DEBUGFUNC("e1000_set_default_fc_generic"); + + /* + * Read and store word 0x0F of the EEPROM. This word contains bits + * that determine the hardware's default PAUSE (flow control) mode, + * a bit that determines whether the HW defaults to enabling or + * disabling auto-negotiation, and the direction of the + * SW defined pins. If there is no SW over-ride of the flow + * control setting, then the variable hw->fc will + * be initialized based on a value in the EEPROM. + */ + ret_val = hw->nvm.ops.read(hw, NVM_INIT_CONTROL2_REG, 1, &nvm_data); + + if (ret_val) { + DEBUGOUT("NVM Read Error\n"); + return ret_val; + } + + if (!(nvm_data & NVM_WORD0F_PAUSE_MASK)) + hw->fc.requested_mode = e1000_fc_none; + else if ((nvm_data & NVM_WORD0F_PAUSE_MASK) == + NVM_WORD0F_ASM_DIR) + hw->fc.requested_mode = e1000_fc_tx_pause; + else + hw->fc.requested_mode = e1000_fc_full; + + return E1000_SUCCESS; } /** @@ -959,7 +994,7 @@ s32 e1000_check_for_serdes_link_generic(struct e1000_hw *hw) **/ s32 e1000_setup_link_generic(struct e1000_hw *hw) { - s32 ret_val = E1000_SUCCESS; + s32 ret_val; DEBUGFUNC("e1000_setup_link_generic"); @@ -967,8 +1002,8 @@ s32 e1000_setup_link_generic(struct e1000_hw *hw) * In the case of the phy reset being blocked, we already have a link. * We do not need to set it up again. */ - if (e1000_check_reset_block(hw)) - goto out; + if (hw->phy.ops.check_reset_block && hw->phy.ops.check_reset_block(hw)) + return E1000_SUCCESS; /* * If requested flow control is set to default, set flow control @@ -977,7 +1012,7 @@ s32 e1000_setup_link_generic(struct e1000_hw *hw) if (hw->fc.requested_mode == e1000_fc_default) { ret_val = e1000_set_default_fc_generic(hw); if (ret_val) - goto out; + return ret_val; } /* @@ -992,7 +1027,7 @@ s32 e1000_setup_link_generic(struct e1000_hw *hw) /* Call the necessary media_type subroutine to configure the link. */ ret_val = hw->mac.ops.setup_physical_interface(hw); if (ret_val) - goto out; + return ret_val; /* * Initialize the flow control address, type, and PAUSE timer @@ -1007,87 +1042,80 @@ s32 e1000_setup_link_generic(struct e1000_hw *hw) E1000_WRITE_REG(hw, E1000_FCTTV, hw->fc.pause_time); - ret_val = e1000_set_fc_watermarks_generic(hw); - -out: - return ret_val; + return e1000_set_fc_watermarks_generic(hw); } /** - * e1000_setup_fiber_serdes_link_generic - Setup link for fiber/serdes + * e1000_commit_fc_settings_generic - Configure flow control * @hw: pointer to the HW structure * - * Configures collision distance and flow control for fiber and serdes - * links. Upon successful setup, poll for link. + * Write the flow control settings to the Transmit Config Word Register (TXCW) + * base on the flow control settings in e1000_mac_info. **/ -s32 e1000_setup_fiber_serdes_link_generic(struct e1000_hw *hw) +s32 e1000_commit_fc_settings_generic(struct e1000_hw *hw) { struct e1000_mac_info *mac = &hw->mac; - u32 ctrl; - s32 ret_val = E1000_SUCCESS; - - DEBUGFUNC("e1000_setup_fiber_serdes_link_generic"); - - ctrl = E1000_READ_REG(hw, E1000_CTRL); - - /* Take the link out of reset */ - ctrl &= ~E1000_CTRL_LRST; - - mac->ops.config_collision_dist(hw); - - ret_val = e1000_commit_fc_settings_generic(hw); - if (ret_val) - goto out; - - /* - * Since auto-negotiation is enabled, take the link out of reset (the - * link will be in reset, because we previously reset the chip). This - * will restart auto-negotiation. If auto-negotiation is successful - * then the link-up status bit will be set and the flow control enable - * bits (RFCE and TFCE) will be set according to their negotiated value. - */ - DEBUGOUT("Auto-negotiation enabled\n"); + u32 txcw; - E1000_WRITE_REG(hw, E1000_CTRL, ctrl); - E1000_WRITE_FLUSH(hw); - msec_delay(1); + DEBUGFUNC("e1000_commit_fc_settings_generic"); /* - * For these adapters, the SW definable pin 1 is set when the optics - * detect a signal. If we have a signal, then poll for a "Link-Up" - * indication. + * Check for a software override of the flow control settings, and + * setup the device accordingly. If auto-negotiation is enabled, then + * software will have to set the "PAUSE" bits to the correct value in + * the Transmit Config Word Register (TXCW) and re-start auto- + * negotiation. However, if auto-negotiation is disabled, then + * software will have to manually configure the two flow control enable + * bits in the CTRL register. + * + * The possible values of the "fc" parameter are: + * 0: Flow control is completely disabled + * 1: Rx flow control is enabled (we can receive pause frames, + * but not send pause frames). + * 2: Tx flow control is enabled (we can send pause frames but we + * do not support receiving pause frames). + * 3: Both Rx and Tx flow control (symmetric) are enabled. */ - if (hw->phy.media_type == e1000_media_type_internal_serdes || - (E1000_READ_REG(hw, E1000_CTRL) & E1000_CTRL_SWDPIN1)) { - ret_val = e1000_poll_fiber_serdes_link_generic(hw); - } else { - DEBUGOUT("No signal detected\n"); + switch (hw->fc.current_mode) { + case e1000_fc_none: + /* Flow control completely disabled by a software over-ride. */ + txcw = (E1000_TXCW_ANE | E1000_TXCW_FD); + break; + case e1000_fc_rx_pause: + /* + * Rx Flow control is enabled and Tx Flow control is disabled + * by a software over-ride. Since there really isn't a way to + * advertise that we are capable of Rx Pause ONLY, we will + * advertise that we support both symmetric and asymmetric Rx + * PAUSE. Later, we will disable the adapter's ability to send + * PAUSE frames. + */ + txcw = (E1000_TXCW_ANE | E1000_TXCW_FD | E1000_TXCW_PAUSE_MASK); + break; + case e1000_fc_tx_pause: + /* + * Tx Flow control is enabled, and Rx Flow control is disabled, + * by a software over-ride. + */ + txcw = (E1000_TXCW_ANE | E1000_TXCW_FD | E1000_TXCW_ASM_DIR); + break; + case e1000_fc_full: + /* + * Flow control (both Rx and Tx) is enabled by a software + * over-ride. + */ + txcw = (E1000_TXCW_ANE | E1000_TXCW_FD | E1000_TXCW_PAUSE_MASK); + break; + default: + DEBUGOUT("Flow control param set incorrectly\n"); + return -E1000_ERR_CONFIG; + break; } -out: - return ret_val; -} - -/** - * e1000_config_collision_dist_generic - Configure collision distance - * @hw: pointer to the HW structure - * - * Configures the collision distance to the default value and is used - * during link setup. - **/ -void e1000_config_collision_dist_generic(struct e1000_hw *hw) -{ - u32 tctl; - - DEBUGFUNC("e1000_config_collision_dist_generic"); - - tctl = E1000_READ_REG(hw, E1000_TCTL); - - tctl &= ~E1000_TCTL_COLD; - tctl |= E1000_COLLISION_DISTANCE << E1000_COLD_SHIFT; + E1000_WRITE_REG(hw, E1000_TXCW, txcw); + mac->txcw = txcw; - E1000_WRITE_REG(hw, E1000_TCTL, tctl); - E1000_WRITE_FLUSH(hw); + return E1000_SUCCESS; } /** @@ -1101,7 +1129,7 @@ s32 e1000_poll_fiber_serdes_link_generic(struct e1000_hw *hw) { struct e1000_mac_info *mac = &hw->mac; u32 i, status; - s32 ret_val = E1000_SUCCESS; + s32 ret_val; DEBUGFUNC("e1000_poll_fiber_serdes_link_generic"); @@ -1120,7 +1148,7 @@ s32 e1000_poll_fiber_serdes_link_generic(struct e1000_hw *hw) } if (i == FIBER_LINK_UP_LIMIT) { DEBUGOUT("Never got a valid link from auto-neg!!!\n"); - mac->autoneg_failed = 1; + mac->autoneg_failed = TRUE; /* * AutoNeg failed to achieve a link, so we'll call * mac->check_for_link. This routine will force the @@ -1130,94 +1158,92 @@ s32 e1000_poll_fiber_serdes_link_generic(struct e1000_hw *hw) ret_val = mac->ops.check_for_link(hw); if (ret_val) { DEBUGOUT("Error while checking for link\n"); - goto out; + return ret_val; } - mac->autoneg_failed = 0; + mac->autoneg_failed = FALSE; } else { - mac->autoneg_failed = 0; + mac->autoneg_failed = FALSE; DEBUGOUT("Valid Link Found\n"); } -out: - return ret_val; + return E1000_SUCCESS; } /** - * e1000_commit_fc_settings_generic - Configure flow control + * e1000_setup_fiber_serdes_link_generic - Setup link for fiber/serdes * @hw: pointer to the HW structure * - * Write the flow control settings to the Transmit Config Word Register (TXCW) - * base on the flow control settings in e1000_mac_info. + * Configures collision distance and flow control for fiber and serdes + * links. Upon successful setup, poll for link. **/ -s32 e1000_commit_fc_settings_generic(struct e1000_hw *hw) +s32 e1000_setup_fiber_serdes_link_generic(struct e1000_hw *hw) { - struct e1000_mac_info *mac = &hw->mac; - u32 txcw; - s32 ret_val = E1000_SUCCESS; + u32 ctrl; + s32 ret_val; - DEBUGFUNC("e1000_commit_fc_settings_generic"); + DEBUGFUNC("e1000_setup_fiber_serdes_link_generic"); + + ctrl = E1000_READ_REG(hw, E1000_CTRL); + + /* Take the link out of reset */ + ctrl &= ~E1000_CTRL_LRST; + + hw->mac.ops.config_collision_dist(hw); + + ret_val = e1000_commit_fc_settings_generic(hw); + if (ret_val) + return ret_val; /* - * Check for a software override of the flow control settings, and - * setup the device accordingly. If auto-negotiation is enabled, then - * software will have to set the "PAUSE" bits to the correct value in - * the Transmit Config Word Register (TXCW) and re-start auto- - * negotiation. However, if auto-negotiation is disabled, then - * software will have to manually configure the two flow control enable - * bits in the CTRL register. - * - * The possible values of the "fc" parameter are: - * 0: Flow control is completely disabled - * 1: Rx flow control is enabled (we can receive pause frames, - * but not send pause frames). - * 2: Tx flow control is enabled (we can send pause frames but we - * do not support receiving pause frames). - * 3: Both Rx and Tx flow control (symmetric) are enabled. + * Since auto-negotiation is enabled, take the link out of reset (the + * link will be in reset, because we previously reset the chip). This + * will restart auto-negotiation. If auto-negotiation is successful + * then the link-up status bit will be set and the flow control enable + * bits (RFCE and TFCE) will be set according to their negotiated value. */ - switch (hw->fc.current_mode) { - case e1000_fc_none: - /* Flow control completely disabled by a software over-ride. */ - txcw = (E1000_TXCW_ANE | E1000_TXCW_FD); - break; - case e1000_fc_rx_pause: - /* - * Rx Flow control is enabled and Tx Flow control is disabled - * by a software over-ride. Since there really isn't a way to - * advertise that we are capable of Rx Pause ONLY, we will - * advertise that we support both symmetric and asymmetric Rx - * PAUSE. Later, we will disable the adapter's ability to send - * PAUSE frames. - */ - txcw = (E1000_TXCW_ANE | E1000_TXCW_FD | E1000_TXCW_PAUSE_MASK); - break; - case e1000_fc_tx_pause: - /* - * Tx Flow control is enabled, and Rx Flow control is disabled, - * by a software over-ride. - */ - txcw = (E1000_TXCW_ANE | E1000_TXCW_FD | E1000_TXCW_ASM_DIR); - break; - case e1000_fc_full: - /* - * Flow control (both Rx and Tx) is enabled by a software - * over-ride. - */ - txcw = (E1000_TXCW_ANE | E1000_TXCW_FD | E1000_TXCW_PAUSE_MASK); - break; - default: - DEBUGOUT("Flow control param set incorrectly\n"); - ret_val = -E1000_ERR_CONFIG; - goto out; - break; - } + DEBUGOUT("Auto-negotiation enabled\n"); - E1000_WRITE_REG(hw, E1000_TXCW, txcw); - mac->txcw = txcw; + E1000_WRITE_REG(hw, E1000_CTRL, ctrl); + E1000_WRITE_FLUSH(hw); + msec_delay(1); + + /* + * For these adapters, the SW definable pin 1 is set when the optics + * detect a signal. If we have a signal, then poll for a "Link-Up" + * indication. + */ + if (hw->phy.media_type == e1000_media_type_internal_serdes || + (E1000_READ_REG(hw, E1000_CTRL) & E1000_CTRL_SWDPIN1)) { + ret_val = e1000_poll_fiber_serdes_link_generic(hw); + } else { + DEBUGOUT("No signal detected\n"); + } -out: return ret_val; } +/** + * e1000_config_collision_dist_generic - Configure collision distance + * @hw: pointer to the HW structure + * + * Configures the collision distance to the default value and is used + * during link setup. + **/ +static void e1000_config_collision_dist_generic(struct e1000_hw *hw) +{ + u32 tctl; + + DEBUGFUNC("e1000_config_collision_dist_generic"); + + tctl = E1000_READ_REG(hw, E1000_TCTL); + + tctl &= ~E1000_TCTL_COLD; + tctl |= E1000_COLLISION_DISTANCE << E1000_COLD_SHIFT; + + E1000_WRITE_REG(hw, E1000_TCTL, tctl); + E1000_WRITE_FLUSH(hw); +} + /** * e1000_set_fc_watermarks_generic - Set flow control high/low watermarks * @hw: pointer to the HW structure @@ -1257,48 +1283,6 @@ s32 e1000_set_fc_watermarks_generic(struct e1000_hw *hw) return E1000_SUCCESS; } -/** - * e1000_set_default_fc_generic - Set flow control default values - * @hw: pointer to the HW structure - * - * Read the EEPROM for the default values for flow control and store the - * values. - **/ -s32 e1000_set_default_fc_generic(struct e1000_hw *hw) -{ - s32 ret_val = E1000_SUCCESS; - u16 nvm_data; - - DEBUGFUNC("e1000_set_default_fc_generic"); - - /* - * Read and store word 0x0F of the EEPROM. This word contains bits - * that determine the hardware's default PAUSE (flow control) mode, - * a bit that determines whether the HW defaults to enabling or - * disabling auto-negotiation, and the direction of the - * SW defined pins. If there is no SW over-ride of the flow - * control setting, then the variable hw->fc will - * be initialized based on a value in the EEPROM. - */ - ret_val = hw->nvm.ops.read(hw, NVM_INIT_CONTROL2_REG, 1, &nvm_data); - - if (ret_val) { - DEBUGOUT("NVM Read Error\n"); - goto out; - } - - if ((nvm_data & NVM_WORD0F_PAUSE_MASK) == 0) - hw->fc.requested_mode = e1000_fc_none; - else if ((nvm_data & NVM_WORD0F_PAUSE_MASK) == - NVM_WORD0F_ASM_DIR) - hw->fc.requested_mode = e1000_fc_tx_pause; - else - hw->fc.requested_mode = e1000_fc_full; - -out: - return ret_val; -} - /** * e1000_force_mac_fc_generic - Force the MAC's flow control settings * @hw: pointer to the HW structure @@ -1312,7 +1296,6 @@ s32 e1000_set_default_fc_generic(struct e1000_hw *hw) s32 e1000_force_mac_fc_generic(struct e1000_hw *hw) { u32 ctrl; - s32 ret_val = E1000_SUCCESS; DEBUGFUNC("e1000_force_mac_fc_generic"); @@ -1355,14 +1338,12 @@ s32 e1000_force_mac_fc_generic(struct e1000_hw *hw) break; default: DEBUGOUT("Flow control param set incorrectly\n"); - ret_val = -E1000_ERR_CONFIG; - goto out; + return -E1000_ERR_CONFIG; } E1000_WRITE_REG(hw, E1000_CTRL, ctrl); -out: - return ret_val; + return E1000_SUCCESS; } /** @@ -1400,7 +1381,7 @@ s32 e1000_config_fc_after_link_up_generic(struct e1000_hw *hw) if (ret_val) { DEBUGOUT("Error forcing flow control settings\n"); - goto out; + return ret_val; } /* @@ -1417,15 +1398,14 @@ s32 e1000_config_fc_after_link_up_generic(struct e1000_hw *hw) */ ret_val = hw->phy.ops.read_reg(hw, PHY_STATUS, &mii_status_reg); if (ret_val) - goto out; + return ret_val; ret_val = hw->phy.ops.read_reg(hw, PHY_STATUS, &mii_status_reg); if (ret_val) - goto out; + return ret_val; if (!(mii_status_reg & MII_SR_AUTONEG_COMPLETE)) { - DEBUGOUT("Copper PHY and Auto Neg " - "has not completed.\n"); - goto out; + DEBUGOUT("Copper PHY and Auto Neg has not completed.\n"); + return ret_val; } /* @@ -1436,13 +1416,13 @@ s32 e1000_config_fc_after_link_up_generic(struct e1000_hw *hw) * flow control was negotiated. */ ret_val = hw->phy.ops.read_reg(hw, PHY_AUTONEG_ADV, - &mii_nway_adv_reg); + &mii_nway_adv_reg); if (ret_val) - goto out; + return ret_val; ret_val = hw->phy.ops.read_reg(hw, PHY_LP_ABILITY, - &mii_nway_lp_ability_reg); + &mii_nway_lp_ability_reg); if (ret_val) - goto out; + return ret_val; /* * Two bits in the Auto Negotiation Advertisement Register @@ -1485,15 +1465,14 @@ s32 e1000_config_fc_after_link_up_generic(struct e1000_hw *hw) * of pause frames. In this case, we had to advertise * FULL flow control because we could not advertise Rx * ONLY. Hence, we must now check to see if we need to - * turn OFF the TRANSMISSION of PAUSE frames. + * turn OFF the TRANSMISSION of PAUSE frames. */ if (hw->fc.requested_mode == e1000_fc_full) { hw->fc.current_mode = e1000_fc_full; - DEBUGOUT("Flow Control = FULL.\r\n"); + DEBUGOUT("Flow Control = FULL.\n"); } else { hw->fc.current_mode = e1000_fc_rx_pause; - DEBUGOUT("Flow Control = " - "Rx PAUSE frames only.\r\n"); + DEBUGOUT("Flow Control = Rx PAUSE frames only.\n"); } } /* @@ -1505,11 +1484,11 @@ s32 e1000_config_fc_after_link_up_generic(struct e1000_hw *hw) * 0 | 1 | 1 | 1 | e1000_fc_tx_pause */ else if (!(mii_nway_adv_reg & NWAY_AR_PAUSE) && - (mii_nway_adv_reg & NWAY_AR_ASM_DIR) && - (mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE) && - (mii_nway_lp_ability_reg & NWAY_LPAR_ASM_DIR)) { + (mii_nway_adv_reg & NWAY_AR_ASM_DIR) && + (mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE) && + (mii_nway_lp_ability_reg & NWAY_LPAR_ASM_DIR)) { hw->fc.current_mode = e1000_fc_tx_pause; - DEBUGOUT("Flow Control = Tx PAUSE frames only.\r\n"); + DEBUGOUT("Flow Control = Tx PAUSE frames only.\n"); } /* * For transmitting PAUSE frames ONLY. @@ -1520,18 +1499,18 @@ s32 e1000_config_fc_after_link_up_generic(struct e1000_hw *hw) * 1 | 1 | 0 | 1 | e1000_fc_rx_pause */ else if ((mii_nway_adv_reg & NWAY_AR_PAUSE) && - (mii_nway_adv_reg & NWAY_AR_ASM_DIR) && - !(mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE) && - (mii_nway_lp_ability_reg & NWAY_LPAR_ASM_DIR)) { + (mii_nway_adv_reg & NWAY_AR_ASM_DIR) && + !(mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE) && + (mii_nway_lp_ability_reg & NWAY_LPAR_ASM_DIR)) { hw->fc.current_mode = e1000_fc_rx_pause; - DEBUGOUT("Flow Control = Rx PAUSE frames only.\r\n"); + DEBUGOUT("Flow Control = Rx PAUSE frames only.\n"); } else { /* * Per the IEEE spec, at this point flow control * should be disabled. */ hw->fc.current_mode = e1000_fc_none; - DEBUGOUT("Flow Control = NONE.\r\n"); + DEBUGOUT("Flow Control = NONE.\n"); } /* @@ -1542,7 +1521,7 @@ s32 e1000_config_fc_after_link_up_generic(struct e1000_hw *hw) ret_val = mac->ops.get_link_up_info(hw, &speed, &duplex); if (ret_val) { DEBUGOUT("Error getting link speed and duplex\n"); - goto out; + return ret_val; } if (duplex == HALF_DUPLEX) @@ -1555,12 +1534,11 @@ s32 e1000_config_fc_after_link_up_generic(struct e1000_hw *hw) ret_val = e1000_force_mac_fc_generic(hw); if (ret_val) { DEBUGOUT("Error forcing flow control settings\n"); - goto out; + return ret_val; } } -out: - return ret_val; + return E1000_SUCCESS; } /** @@ -1573,7 +1551,7 @@ s32 e1000_config_fc_after_link_up_generic(struct e1000_hw *hw) * speed and duplex for copper connections. **/ s32 e1000_get_speed_and_duplex_copper_generic(struct e1000_hw *hw, u16 *speed, - u16 *duplex) + u16 *duplex) { u32 status; @@ -1612,7 +1590,7 @@ s32 e1000_get_speed_and_duplex_copper_generic(struct e1000_hw *hw, u16 *speed, * for fiber/serdes links. **/ s32 e1000_get_speed_and_duplex_fiber_serdes_generic(struct e1000_hw *hw, - u16 *speed, u16 *duplex) + u16 *speed, u16 *duplex) { DEBUGFUNC("e1000_get_speed_and_duplex_fiber_serdes_generic"); @@ -1631,7 +1609,6 @@ s32 e1000_get_speed_and_duplex_fiber_serdes_generic(struct e1000_hw *hw, s32 e1000_get_hw_semaphore_generic(struct e1000_hw *hw) { u32 swsm; - s32 ret_val = E1000_SUCCESS; s32 timeout = hw->nvm.word_size + 1; s32 i = 0; @@ -1649,8 +1626,7 @@ s32 e1000_get_hw_semaphore_generic(struct e1000_hw *hw) if (i == timeout) { DEBUGOUT("Driver can't access device - SMBI bit is set.\n"); - ret_val = -E1000_ERR_NVM; - goto out; + return -E1000_ERR_NVM; } /* Get the FW semaphore. */ @@ -1669,12 +1645,10 @@ s32 e1000_get_hw_semaphore_generic(struct e1000_hw *hw) /* Release semaphores */ e1000_put_hw_semaphore_generic(hw); DEBUGOUT("Driver can't access the NVM\n"); - ret_val = -E1000_ERR_NVM; - goto out; + return -E1000_ERR_NVM; } -out: - return ret_val; + return E1000_SUCCESS; } /** @@ -1705,7 +1679,6 @@ void e1000_put_hw_semaphore_generic(struct e1000_hw *hw) s32 e1000_get_auto_rd_done_generic(struct e1000_hw *hw) { s32 i = 0; - s32 ret_val = E1000_SUCCESS; DEBUGFUNC("e1000_get_auto_rd_done_generic"); @@ -1718,12 +1691,10 @@ s32 e1000_get_auto_rd_done_generic(struct e1000_hw *hw) if (i == AUTO_READ_DONE_TIMEOUT) { DEBUGOUT("Auto read by HW from NVM has not completed.\n"); - ret_val = -E1000_ERR_RESET; - goto out; + return -E1000_ERR_RESET; } -out: - return ret_val; + return E1000_SUCCESS; } /** @@ -1743,14 +1714,13 @@ s32 e1000_valid_led_default_generic(struct e1000_hw *hw, u16 *data) ret_val = hw->nvm.ops.read(hw, NVM_ID_LED_SETTINGS, 1, data); if (ret_val) { DEBUGOUT("NVM Read Error\n"); - goto out; + return ret_val; } if (*data == ID_LED_RESERVED_0000 || *data == ID_LED_RESERVED_FFFF) *data = ID_LED_DEFAULT; -out: - return ret_val; + return E1000_SUCCESS; } /** @@ -1772,7 +1742,7 @@ s32 e1000_id_led_init_generic(struct e1000_hw *hw) ret_val = hw->nvm.ops.valid_led_default(hw, &data); if (ret_val) - goto out; + return ret_val; mac->ledctl_default = E1000_READ_REG(hw, E1000_LEDCTL); mac->ledctl_mode1 = mac->ledctl_default; @@ -1816,8 +1786,7 @@ s32 e1000_id_led_init_generic(struct e1000_hw *hw) } } -out: - return ret_val; + return E1000_SUCCESS; } /** @@ -1830,31 +1799,26 @@ s32 e1000_id_led_init_generic(struct e1000_hw *hw) s32 e1000_setup_led_generic(struct e1000_hw *hw) { u32 ledctl; - s32 ret_val = E1000_SUCCESS; DEBUGFUNC("e1000_setup_led_generic"); - if (hw->mac.ops.setup_led != e1000_setup_led_generic) { - ret_val = -E1000_ERR_CONFIG; - goto out; - } + if (hw->mac.ops.setup_led != e1000_setup_led_generic) + return -E1000_ERR_CONFIG; if (hw->phy.media_type == e1000_media_type_fiber) { ledctl = E1000_READ_REG(hw, E1000_LEDCTL); hw->mac.ledctl_default = ledctl; /* Turn off LED0 */ - ledctl &= ~(E1000_LEDCTL_LED0_IVRT | - E1000_LEDCTL_LED0_BLINK | - E1000_LEDCTL_LED0_MODE_MASK); + ledctl &= ~(E1000_LEDCTL_LED0_IVRT | E1000_LEDCTL_LED0_BLINK | + E1000_LEDCTL_LED0_MODE_MASK); ledctl |= (E1000_LEDCTL_MODE_LED_OFF << - E1000_LEDCTL_LED0_MODE_SHIFT); + E1000_LEDCTL_LED0_MODE_SHIFT); E1000_WRITE_REG(hw, E1000_LEDCTL, ledctl); } else if (hw->phy.media_type == e1000_media_type_copper) { E1000_WRITE_REG(hw, E1000_LEDCTL, hw->mac.ledctl_mode1); } -out: - return ret_val; + return E1000_SUCCESS; } /** @@ -1899,7 +1863,7 @@ s32 e1000_blink_led_generic(struct e1000_hw *hw) if (((hw->mac.ledctl_mode2 >> (i * 8)) & 0xFF) == E1000_LEDCTL_MODE_LED_ON) ledctl_blink |= (E1000_LEDCTL_LED0_BLINK << - (i * 8)); + (i * 8)); } E1000_WRITE_REG(hw, E1000_LEDCTL, ledctl_blink); @@ -1979,7 +1943,7 @@ void e1000_set_pcie_no_snoop_generic(struct e1000_hw *hw, u32 no_snoop) DEBUGFUNC("e1000_set_pcie_no_snoop_generic"); if (hw->bus.type != e1000_bus_type_pci_express) - goto out; + return; if (no_snoop) { gcr = E1000_READ_REG(hw, E1000_GCR); @@ -1987,8 +1951,6 @@ void e1000_set_pcie_no_snoop_generic(struct e1000_hw *hw, u32 no_snoop) gcr |= no_snoop; E1000_WRITE_REG(hw, E1000_GCR, gcr); } -out: - return; } /** @@ -2006,12 +1968,11 @@ s32 e1000_disable_pcie_master_generic(struct e1000_hw *hw) { u32 ctrl; s32 timeout = MASTER_DISABLE_TIMEOUT; - s32 ret_val = E1000_SUCCESS; DEBUGFUNC("e1000_disable_pcie_master_generic"); if (hw->bus.type != e1000_bus_type_pci_express) - goto out; + return E1000_SUCCESS; ctrl = E1000_READ_REG(hw, E1000_CTRL); ctrl |= E1000_CTRL_GIO_MASTER_DISABLE; @@ -2027,11 +1988,10 @@ s32 e1000_disable_pcie_master_generic(struct e1000_hw *hw) if (!timeout) { DEBUGOUT("Master requests are pending.\n"); - ret_val = -E1000_ERR_MASTER_REQUESTS_PENDING; + return -E1000_ERR_MASTER_REQUESTS_PENDING; } -out: - return ret_val; + return E1000_SUCCESS; } /** @@ -2048,7 +2008,7 @@ void e1000_reset_adaptive_generic(struct e1000_hw *hw) if (!mac->adaptive_ifs) { DEBUGOUT("Not in Adaptive IFS mode!\n"); - goto out; + return; } mac->current_ifs_val = 0; @@ -2059,8 +2019,6 @@ void e1000_reset_adaptive_generic(struct e1000_hw *hw) mac->in_ifs_mode = FALSE; E1000_WRITE_REG(hw, E1000_AIT, 0); -out: - return; } /** @@ -2078,7 +2036,7 @@ void e1000_update_adaptive_generic(struct e1000_hw *hw) if (!mac->adaptive_ifs) { DEBUGOUT("Not in Adaptive IFS mode!\n"); - goto out; + return; } if ((mac->collision_delta * mac->ifs_ratio) > mac->tx_packet_delta) { @@ -2090,7 +2048,8 @@ void e1000_update_adaptive_generic(struct e1000_hw *hw) else mac->current_ifs_val += mac->ifs_step_size; - E1000_WRITE_REG(hw, E1000_AIT, mac->current_ifs_val); + E1000_WRITE_REG(hw, E1000_AIT, + mac->current_ifs_val); } } } else { @@ -2101,8 +2060,6 @@ void e1000_update_adaptive_generic(struct e1000_hw *hw) E1000_WRITE_REG(hw, E1000_AIT, 0); } } -out: - return; } /** @@ -2114,19 +2071,15 @@ void e1000_update_adaptive_generic(struct e1000_hw *hw) **/ static s32 e1000_validate_mdi_setting_generic(struct e1000_hw *hw) { - s32 ret_val = E1000_SUCCESS; - DEBUGFUNC("e1000_validate_mdi_setting_generic"); if (!hw->mac.autoneg && (hw->phy.mdix == 0 || hw->phy.mdix == 3)) { DEBUGOUT("Invalid MDI setting detected\n"); hw->phy.mdix = 1; - ret_val = -E1000_ERR_CONFIG; - goto out; + return -E1000_ERR_CONFIG; } -out: - return ret_val; + return E1000_SUCCESS; } /** @@ -2141,10 +2094,9 @@ static s32 e1000_validate_mdi_setting_generic(struct e1000_hw *hw) * completion. **/ s32 e1000_write_8bit_ctrl_reg_generic(struct e1000_hw *hw, u32 reg, - u32 offset, u8 data) + u32 offset, u8 data) { u32 i, regvalue = 0; - s32 ret_val = E1000_SUCCESS; DEBUGFUNC("e1000_write_8bit_ctrl_reg_generic"); @@ -2161,10 +2113,8 @@ s32 e1000_write_8bit_ctrl_reg_generic(struct e1000_hw *hw, u32 reg, } if (!(regvalue & E1000_GEN_CTL_READY)) { DEBUGOUT1("Reg %08x did not indicate ready\n", reg); - ret_val = -E1000_ERR_PHY; - goto out; + return -E1000_ERR_PHY; } -out: - return ret_val; + return E1000_SUCCESS; } diff --git a/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_mac.h b/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_mac.h index aab796b7687..c18a7ec1293 100644 --- a/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_mac.h +++ b/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_mac.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_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_ @@ -64,31 +64,29 @@ void e1000_set_lan_id_single_port(struct e1000_hw *hw); void e1000_set_lan_id_multi_port_pci(struct e1000_hw *hw); s32 e1000_get_hw_semaphore_generic(struct e1000_hw *hw); s32 e1000_get_speed_and_duplex_copper_generic(struct e1000_hw *hw, u16 *speed, - u16 *duplex); + u16 *duplex); s32 e1000_get_speed_and_duplex_fiber_serdes_generic(struct e1000_hw *hw, - u16 *speed, u16 *duplex); + u16 *speed, u16 *duplex); s32 e1000_id_led_init_generic(struct e1000_hw *hw); s32 e1000_led_on_generic(struct e1000_hw *hw); s32 e1000_led_off_generic(struct e1000_hw *hw); void e1000_update_mc_addr_list_generic(struct e1000_hw *hw, - u8 *mc_addr_list, u32 mc_addr_count); + u8 *mc_addr_list, u32 mc_addr_count); s32 e1000_set_default_fc_generic(struct e1000_hw *hw); s32 e1000_set_fc_watermarks_generic(struct e1000_hw *hw); s32 e1000_setup_fiber_serdes_link_generic(struct e1000_hw *hw); s32 e1000_setup_led_generic(struct e1000_hw *hw); s32 e1000_setup_link_generic(struct e1000_hw *hw); s32 e1000_write_8bit_ctrl_reg_generic(struct e1000_hw *hw, u32 reg, - u32 offset, u8 data); + u32 offset, u8 data); 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); diff --git a/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_manage.c b/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_manage.c index b8180b3795e..f11b18d20e0 100644 --- a/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_manage.c +++ b/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_manage.c @@ -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; } /** @@ -122,7 +117,7 @@ bool e1000_check_mng_mode_generic(struct e1000_hw *hw) return (fwsm & E1000_FWSM_MODE_MASK) == - (E1000_MNG_IAMT_MODE << E1000_FWSM_MODE_SHIFT); + (E1000_MNG_IAMT_MODE << E1000_FWSM_MODE_SHIFT); } /** @@ -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. */ @@ -165,11 +160,11 @@ bool e1000_enable_tx_pkt_filtering_generic(struct e1000_hw *hw) offset = E1000_MNG_DHCP_COOKIE_OFFSET >> 2; for (i = 0; i < len; i++) *(buffer + i) = E1000_READ_REG_ARRAY_DWORD(hw, E1000_HOST_IF, - offset + i); + offset + i); hdr_csum = hdr->checksum; hdr->checksum = 0; csum = e1000_calculate_checksum((u8 *)hdr, - E1000_MNG_DHCP_COOKIE_LENGTH); + E1000_MNG_DHCP_COOKIE_LENGTH); /* * If either the checksums or signature don't match, then * the cookie area isn't considered valid, in which case we @@ -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 @@ -245,7 +190,7 @@ s32 e1000_mng_write_dhcp_info_generic(struct e1000_hw *hw, u8 *buffer, * Writes the command header after does the checksum calculation. **/ s32 e1000_mng_write_cmd_header_generic(struct e1000_hw *hw, - struct e1000_host_mng_command_header *hdr) + struct e1000_host_mng_command_header *hdr) { u16 i, length = sizeof(struct e1000_host_mng_command_header); @@ -259,7 +204,7 @@ s32 e1000_mng_write_cmd_header_generic(struct e1000_hw *hw, /* Write the relevant command block into the ram area. */ for (i = 0; i < length; i++) { E1000_WRITE_REG_ARRAY_DWORD(hw, E1000_HOST_IF, i, - *((u32 *) hdr + i)); + *((u32 *) hdr + i)); E1000_WRITE_FLUSH(hw); } @@ -279,22 +224,19 @@ s32 e1000_mng_write_cmd_header_generic(struct e1000_hw *hw, * way. Also fills up the sum of the buffer in *buffer parameter. **/ s32 e1000_mng_host_if_write_generic(struct e1000_hw *hw, u8 *buffer, - u16 length, u16 offset, u8 *sum) + u16 length, u16 offset, u8 *sum) { 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; @@ -328,7 +270,7 @@ s32 e1000_mng_host_if_write_generic(struct e1000_hw *hw, u8 *buffer, } E1000_WRITE_REG_ARRAY_DWORD(hw, E1000_HOST_IF, offset + i, - data); + data); } if (remaining) { for (j = 0; j < sizeof(u32); j++) { @@ -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 ret_val; + 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; + !(manc & E1000_MANC_ASF_EN)) { + return TRUE; } -out: - return ret_val; + return FALSE; } /** @@ -414,33 +395,30 @@ bool e1000_enable_mng_pass_thru(struct e1000_hw *hw) 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,10 +429,8 @@ 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, - *((u32 *)buffer + 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. */ E1000_WRITE_REG(hw, E1000_HICR, hicr | E1000_HICR_C); @@ -470,16 +446,134 @@ 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++) *((u32 *)buffer + i) = E1000_READ_REG_ARRAY_DWORD(hw, - E1000_HOST_IF, - i); + E1000_HOST_IF, + i); + + 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)); + } -out: - return ret_val; + /* 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; } + diff --git a/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_manage.h b/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_manage.h index 8e0d386255b..51f176719cb 100644 --- a/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_manage.h +++ b/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_manage.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_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_ @@ -39,14 +39,15 @@ bool e1000_check_mng_mode_generic(struct e1000_hw *hw); bool e1000_enable_tx_pkt_filtering_generic(struct e1000_hw *hw); s32 e1000_mng_enable_host_if_generic(struct e1000_hw *hw); s32 e1000_mng_host_if_write_generic(struct e1000_hw *hw, u8 *buffer, - u16 length, u16 offset, u8 *sum); + u16 length, u16 offset, u8 *sum); s32 e1000_mng_write_cmd_header_generic(struct e1000_hw *hw, - struct e1000_host_mng_command_header *hdr); + struct e1000_host_mng_command_header *hdr); s32 e1000_mng_write_dhcp_info_generic(struct e1000_hw *hw, - u8 *buffer, u16 length); + u8 *buffer, u16 length); 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, @@ -56,35 +57,40 @@ enum e1000_mng_mode { e1000_mng_mode_host_if_only }; -#define E1000_FACTPS_MNGCG 0x20000000 +#define E1000_FACTPS_MNGCG 0x20000000 -#define E1000_FWSM_MODE_MASK 0xE -#define E1000_FWSM_MODE_SHIFT 1 +#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 -#define E1000_MNG_DHCP_COOKIE_OFFSET 0x6F0 -#define E1000_MNG_DHCP_COMMAND_TIMEOUT 10 -#define E1000_MNG_DHCP_TX_PAYLOAD_CMD 64 -#define E1000_MNG_DHCP_COOKIE_STATUS_PARSING 0x1 -#define E1000_MNG_DHCP_COOKIE_STATUS_VLAN 0x2 +#define E1000_MNG_IAMT_MODE 0x3 +#define E1000_MNG_DHCP_COOKIE_LENGTH 0x10 +#define E1000_MNG_DHCP_COOKIE_OFFSET 0x6F0 +#define E1000_MNG_DHCP_COMMAND_TIMEOUT 10 +#define E1000_MNG_DHCP_TX_PAYLOAD_CMD 64 +#define E1000_MNG_DHCP_COOKIE_STATUS_PARSING 0x1 +#define E1000_MNG_DHCP_COOKIE_STATUS_VLAN 0x2 -#define E1000_VFTA_ENTRY_SHIFT 5 -#define E1000_VFTA_ENTRY_MASK 0x7F -#define E1000_VFTA_ENTRY_BIT_SHIFT_MASK 0x1F +#define E1000_VFTA_ENTRY_SHIFT 5 +#define E1000_VFTA_ENTRY_MASK 0x7F +#define E1000_VFTA_ENTRY_BIT_SHIFT_MASK 0x1F -#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_HICR_EN 0x01 /* Enable bit - RO */ +#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 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 -#define E1000_HICR_SV 0x04 /* Status Validity */ -#define E1000_HICR_FW_RESET_ENABLE 0x40 -#define E1000_HICR_FW_RESET 0x80 +#define E1000_HICR_C 0x02 +#define E1000_HICR_SV 0x04 /* Status Validity */ +#define E1000_HICR_FW_RESET_ENABLE 0x40 +#define E1000_HICR_FW_RESET 0x80 /* Intel(R) Active Management Technology signature */ -#define E1000_IAMT_SIGNATURE 0x544D4149 +#define E1000_IAMT_SIGNATURE 0x544D4149 #endif diff --git a/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_mbx.c b/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_mbx.c index 3f023bb1b98..14af886738f 100644 --- a/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_mbx.c +++ b/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_mbx.c @@ -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" diff --git a/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_mbx.h b/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_mbx.h index 7a451d6c979..206f00c5fad 100644 --- a/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_mbx.h +++ b/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/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_ diff --git a/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_nvm.c b/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_nvm.c index dc16977d849..d8df089efec 100644 --- a/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_nvm.c +++ b/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_nvm.c @@ -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); /* @@ -411,7 +410,7 @@ static s32 e1000_ready_nvm_eeprom(struct e1000_hw *hw) */ while (timeout) { e1000_shift_out_eec_bits(hw, NVM_RDSR_OPCODE_SPI, - hw->nvm.opcode_bits); + hw->nvm.opcode_bits); spi_stat_reg = (u8)e1000_shift_in_eec_bits(hw, 8); if (!(spi_stat_reg & NVM_STATUS_RDY_SPI)) break; @@ -506,7 +505,7 @@ s32 e1000_read_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data) * Reads a 16 bit word from the EEPROM. **/ s32 e1000_read_nvm_microwire(struct e1000_hw *hw, u16 offset, u16 words, - u16 *data) + u16 *data) { struct e1000_nvm_info *nvm = &hw->nvm; u32 i = 0; @@ -593,7 +592,7 @@ s32 e1000_read_nvm_eerd(struct e1000_hw *hw, u16 offset, u16 words, u16 *data) break; data[i] = (E1000_READ_REG(hw, E1000_EERD) >> - E1000_NVM_RW_REG_DATA); + E1000_NVM_RW_REG_DATA); } out: @@ -646,7 +645,7 @@ s32 e1000_write_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data) /* Send the WRITE ENABLE command (8 bit opcode) */ e1000_shift_out_eec_bits(hw, NVM_WREN_OPCODE_SPI, - nvm->opcode_bits); + nvm->opcode_bits); e1000_standby_nvm(hw); @@ -660,7 +659,7 @@ s32 e1000_write_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data) /* Send the Write command (8-bit opcode + addr) */ e1000_shift_out_eec_bits(hw, write_opcode, nvm->opcode_bits); e1000_shift_out_eec_bits(hw, (u16)((offset + widx) * 2), - nvm->address_bits); + nvm->address_bits); /* Loop to allow for up to whole page write of eeprom */ while (widx < words) { @@ -697,7 +696,7 @@ s32 e1000_write_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data) * EEPROM will most likely contain an invalid checksum. **/ s32 e1000_write_nvm_microwire(struct e1000_hw *hw, u16 offset, u16 words, - u16 *data) + u16 *data) { struct e1000_nvm_info *nvm = &hw->nvm; s32 ret_val; @@ -727,7 +726,7 @@ s32 e1000_write_nvm_microwire(struct e1000_hw *hw, u16 offset, u16 words, goto release; e1000_shift_out_eec_bits(hw, NVM_EWEN_OPCODE_MICROWIRE, - (u16)(nvm->opcode_bits + 2)); + (u16)(nvm->opcode_bits + 2)); e1000_shift_out_eec_bits(hw, 0, (u16)(nvm->address_bits - 2)); @@ -735,10 +734,10 @@ s32 e1000_write_nvm_microwire(struct e1000_hw *hw, u16 offset, u16 words, while (words_written < words) { e1000_shift_out_eec_bits(hw, NVM_WRITE_OPCODE_MICROWIRE, - nvm->opcode_bits); + nvm->opcode_bits); e1000_shift_out_eec_bits(hw, (u16)(offset + words_written), - nvm->address_bits); + nvm->address_bits); e1000_shift_out_eec_bits(hw, data[words_written], 16); @@ -763,7 +762,7 @@ s32 e1000_write_nvm_microwire(struct e1000_hw *hw, u16 offset, u16 words, } e1000_shift_out_eec_bits(hw, NVM_EWDS_OPCODE_MICROWIRE, - (u16)(nvm->opcode_bits + 2)); + (u16)(nvm->opcode_bits + 2)); e1000_shift_out_eec_bits(hw, 0, (u16)(nvm->address_bits - 2)); @@ -784,7 +783,7 @@ s32 e1000_write_nvm_microwire(struct e1000_hw *hw, u16 offset, u16 words, * the value in pba_num. **/ s32 e1000_read_pba_string_generic(struct e1000_hw *hw, u8 *pba_num, - u32 pba_num_size) + u32 pba_num_size) { s32 ret_val; u16 nvm_data; diff --git a/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_nvm.h b/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_nvm.h index b6d5ce7c691..ed23eb3e37a 100644 --- a/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_nvm.h +++ b/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_nvm.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.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_ @@ -45,25 +45,23 @@ s32 e1000_acquire_nvm_generic(struct e1000_hw *hw); s32 e1000_poll_eerd_eewr_done(struct e1000_hw *hw, int ee_reg); s32 e1000_read_mac_addr_generic(struct e1000_hw *hw); s32 e1000_read_pba_string_generic(struct e1000_hw *hw, u8 *pba_num, - u32 pba_num_size); + u32 pba_num_size); s32 e1000_read_pba_length_generic(struct e1000_hw *hw, u32 *pba_num_size); s32 e1000_read_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data); s32 e1000_read_nvm_microwire(struct e1000_hw *hw, u16 offset, - u16 words, u16 *data); + u16 words, u16 *data); s32 e1000_read_nvm_eerd(struct e1000_hw *hw, u16 offset, u16 words, - u16 *data); + 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); + u16 words, u16 *data); s32 e1000_write_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, - u16 *data); + u16 *data); s32 e1000_update_nvm_checksum_generic(struct e1000_hw *hw); void e1000_stop_nvm(struct e1000_hw *hw); void e1000_release_nvm_generic(struct e1000_hw *hw); -#define E1000_STM_OPCODE 0xDB00 +#define E1000_STM_OPCODE 0xDB00 #endif diff --git a/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_osdep.c b/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_osdep.c index 327cd31c4b8..75a7b79a4c4 100644 --- a/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_osdep.c +++ b/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_osdep.c @@ -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" diff --git a/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_osdep.h b/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_osdep.h index b6d0a463c70..e6d131a52e2 100644 --- a/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_osdep.h +++ b/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_osdep.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 false FALSE #define TRUE 1 +#ifndef __bool_true_false_are_defined +#define false FALSE #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 diff --git a/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_phy.c b/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_phy.c index 04971e53d46..fd253ba92f9 100644 --- a/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_phy.c +++ b/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_phy.c @@ -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,23 +30,23 @@ POSSIBILITY OF SUCH DAMAGE. ******************************************************************************/ -/*$FreeBSD: src/sys/dev/e1000/e1000_phy.c,v 1.4.2.3.2.1 2010/12/21 17:09:25 kensmith Exp $*/ +/*$FreeBSD$*/ #include "e1000_api.h" static u32 e1000_get_phy_addr_for_bm_page(u32 page, u32 reg); static s32 e1000_access_phy_wakeup_reg_bm(struct e1000_hw *hw, u32 offset, - u16 *data, bool read); + u16 *data, bool read, bool page_set); static u32 e1000_get_phy_addr_for_hv_page(u32 page); static s32 e1000_access_phy_debug_regs_hv(struct e1000_hw *hw, u32 offset, - u16 *data, bool read); + u16 *data, bool read); /* Cable length tables */ static const u16 e1000_m88_cable_length_table[] = { 0, 50, 80, 110, 140, 140, E1000_CABLE_LENGTH_UNDEFINED }; #define M88E1000_CABLE_LENGTH_TABLE_SIZE \ - (sizeof(e1000_m88_cable_length_table) / \ - sizeof(e1000_m88_cable_length_table[0])) + (sizeof(e1000_m88_cable_length_table) / \ + sizeof(e1000_m88_cable_length_table[0])) static const u16 e1000_igp_2_cable_length_table[] = { 0, 0, 0, 0, 0, 0, 0, 0, 3, 5, 8, 11, 13, 16, 18, 21, 0, 0, 0, 3, @@ -58,8 +58,8 @@ static const u16 e1000_igp_2_cable_length_table[] = { 100, 105, 109, 113, 116, 119, 122, 124, 104, 109, 114, 118, 121, 124}; #define IGP02E1000_CABLE_LENGTH_TABLE_SIZE \ - (sizeof(e1000_igp_2_cable_length_table) / \ - sizeof(e1000_igp_2_cable_length_table[0])) + (sizeof(e1000_igp_2_cable_length_table) / \ + sizeof(e1000_igp_2_cable_length_table[0])) /** * e1000_init_phy_ops_generic - Initialize PHY function pointers @@ -82,19 +82,34 @@ void e1000_init_phy_ops_generic(struct e1000_hw *hw) phy->ops.get_cfg_done = e1000_null_ops_generic; phy->ops.get_cable_length = e1000_null_ops_generic; phy->ops.get_info = e1000_null_ops_generic; + phy->ops.set_page = e1000_null_set_page; phy->ops.read_reg = e1000_null_read_reg; phy->ops.read_reg_locked = e1000_null_read_reg; + phy->ops.read_reg_page = e1000_null_read_reg; phy->ops.release = e1000_null_phy_generic; phy->ops.reset = e1000_null_ops_generic; phy->ops.set_d0_lplu_state = e1000_null_lplu_state; phy->ops.set_d3_lplu_state = e1000_null_lplu_state; phy->ops.write_reg = e1000_null_write_reg; phy->ops.write_reg_locked = e1000_null_write_reg; + phy->ops.write_reg_page = e1000_null_write_reg; phy->ops.power_up = e1000_null_phy_generic; phy->ops.power_down = e1000_null_phy_generic; + phy->ops.read_i2c_byte = e1000_read_i2c_byte_null; + phy->ops.write_i2c_byte = e1000_write_i2c_byte_null; phy->ops.cfg_on_link_up = e1000_null_ops_generic; } +/** + * e1000_null_set_page - No-op function, return 0 + * @hw: pointer to the HW structure + **/ +s32 e1000_null_set_page(struct e1000_hw *hw, u16 data) +{ + DEBUGFUNC("e1000_null_set_page"); + return E1000_SUCCESS; +} + /** * e1000_null_read_reg - No-op function, return 0 * @hw: pointer to the HW structure @@ -135,6 +150,36 @@ s32 e1000_null_write_reg(struct e1000_hw *hw, u32 offset, u16 data) return E1000_SUCCESS; } +/** + * e1000_read_i2c_byte_null - No-op function, return 0 + * @hw: pointer to hardware structure + * @byte_offset: byte offset to write + * @dev_addr: device address + * @data: data value read + * + **/ +s32 e1000_read_i2c_byte_null(struct e1000_hw *hw, u8 byte_offset, + u8 dev_addr, u8 *data) +{ + DEBUGFUNC("e1000_read_i2c_byte_null"); + return E1000_SUCCESS; +} + +/** + * e1000_write_i2c_byte_null - No-op function, return 0 + * @hw: pointer to hardware structure + * @byte_offset: byte offset to write + * @dev_addr: device address + * @data: data value to write + * + **/ +s32 e1000_write_i2c_byte_null(struct e1000_hw *hw, u8 byte_offset, + u8 dev_addr, u8 data) +{ + DEBUGFUNC("e1000_write_i2c_byte_null"); + return E1000_SUCCESS; +} + /** * e1000_check_reset_block_generic - Check if PHY reset is blocked * @hw: pointer to the HW structure @@ -171,30 +216,30 @@ s32 e1000_get_phy_id(struct e1000_hw *hw) DEBUGFUNC("e1000_get_phy_id"); - if (!(phy->ops.read_reg)) - goto out; + if (!phy->ops.read_reg) + return E1000_SUCCESS; while (retry_count < 2) { ret_val = phy->ops.read_reg(hw, PHY_ID1, &phy_id); if (ret_val) - goto out; + return ret_val; phy->id = (u32)(phy_id << 16); usec_delay(20); ret_val = phy->ops.read_reg(hw, PHY_ID2, &phy_id); if (ret_val) - goto out; + return ret_val; phy->id |= (u32)(phy_id & PHY_REVISION_MASK); phy->revision = (u32)(phy_id & ~PHY_REVISION_MASK); if (phy->id != 0 && phy->id != PHY_REVISION_MASK) - goto out; + return E1000_SUCCESS; retry_count++; } -out: - return ret_val; + + return E1000_SUCCESS; } /** @@ -205,21 +250,18 @@ s32 e1000_get_phy_id(struct e1000_hw *hw) **/ s32 e1000_phy_reset_dsp_generic(struct e1000_hw *hw) { - s32 ret_val = E1000_SUCCESS; + s32 ret_val; DEBUGFUNC("e1000_phy_reset_dsp_generic"); - if (!(hw->phy.ops.write_reg)) - goto out; + if (!hw->phy.ops.write_reg) + return E1000_SUCCESS; ret_val = hw->phy.ops.write_reg(hw, M88E1000_PHY_GEN_CONTROL, 0xC1); if (ret_val) - goto out; - - ret_val = hw->phy.ops.write_reg(hw, M88E1000_PHY_GEN_CONTROL, 0); + return ret_val; -out: - return ret_val; + return hw->phy.ops.write_reg(hw, M88E1000_PHY_GEN_CONTROL, 0); } /** @@ -235,7 +277,6 @@ s32 e1000_read_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 *data) { struct e1000_phy_info *phy = &hw->phy; u32 i, mdic = 0; - s32 ret_val = E1000_SUCCESS; DEBUGFUNC("e1000_read_phy_reg_mdic"); @@ -250,8 +291,8 @@ s32 e1000_read_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 *data) * PHY to retrieve the desired data. */ mdic = ((offset << E1000_MDIC_REG_SHIFT) | - (phy->addr << E1000_MDIC_PHY_SHIFT) | - (E1000_MDIC_OP_READ)); + (phy->addr << E1000_MDIC_PHY_SHIFT) | + (E1000_MDIC_OP_READ)); E1000_WRITE_REG(hw, E1000_MDIC, mdic); @@ -268,13 +309,11 @@ s32 e1000_read_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 *data) } if (!(mdic & E1000_MDIC_READY)) { DEBUGOUT("MDI Read did not complete\n"); - ret_val = -E1000_ERR_PHY; - goto out; + return -E1000_ERR_PHY; } if (mdic & E1000_MDIC_ERROR) { DEBUGOUT("MDI Error\n"); - ret_val = -E1000_ERR_PHY; - goto out; + return -E1000_ERR_PHY; } *data = (u16) mdic; @@ -285,8 +324,7 @@ s32 e1000_read_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 *data) if (hw->mac.type == e1000_pch2lan) usec_delay(100); -out: - return ret_val; + return E1000_SUCCESS; } /** @@ -301,7 +339,6 @@ s32 e1000_write_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 data) { struct e1000_phy_info *phy = &hw->phy; u32 i, mdic = 0; - s32 ret_val = E1000_SUCCESS; DEBUGFUNC("e1000_write_phy_reg_mdic"); @@ -316,9 +353,9 @@ s32 e1000_write_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 data) * PHY to retrieve the desired data. */ mdic = (((u32)data) | - (offset << E1000_MDIC_REG_SHIFT) | - (phy->addr << E1000_MDIC_PHY_SHIFT) | - (E1000_MDIC_OP_WRITE)); + (offset << E1000_MDIC_REG_SHIFT) | + (phy->addr << E1000_MDIC_PHY_SHIFT) | + (E1000_MDIC_OP_WRITE)); E1000_WRITE_REG(hw, E1000_MDIC, mdic); @@ -335,13 +372,11 @@ s32 e1000_write_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 data) } if (!(mdic & E1000_MDIC_READY)) { DEBUGOUT("MDI Write did not complete\n"); - ret_val = -E1000_ERR_PHY; - goto out; + return -E1000_ERR_PHY; } if (mdic & E1000_MDIC_ERROR) { DEBUGOUT("MDI Error\n"); - ret_val = -E1000_ERR_PHY; - goto out; + return -E1000_ERR_PHY; } /* @@ -351,8 +386,7 @@ s32 e1000_write_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 data) if (hw->mac.type == e1000_pch2lan) usec_delay(100); -out: - return ret_val; + return E1000_SUCCESS; } /** @@ -377,8 +411,8 @@ s32 e1000_read_phy_reg_i2c(struct e1000_hw *hw, u32 offset, u16 *data) * PHY to retrieve the desired data. */ i2ccmd = ((offset << E1000_I2CCMD_REG_ADDR_SHIFT) | - (phy->addr << E1000_I2CCMD_PHY_ADDR_SHIFT) | - (E1000_I2CCMD_OPCODE_READ)); + (phy->addr << E1000_I2CCMD_PHY_ADDR_SHIFT) | + (E1000_I2CCMD_OPCODE_READ)); E1000_WRITE_REG(hw, E1000_I2CCMD, i2ccmd); @@ -420,6 +454,13 @@ s32 e1000_write_phy_reg_i2c(struct e1000_hw *hw, u32 offset, u16 data) DEBUGFUNC("e1000_write_phy_reg_i2c"); + /* Prevent overwritting SFP I2C EEPROM which is at A0 address.*/ + if ((hw->phy.addr == 0) || (hw->phy.addr > 7)) { + DEBUGOUT1("PHY I2C Address %d is out of range.\n", + hw->phy.addr); + return -E1000_ERR_CONFIG; + } + /* Swap the data bytes for the I2C interface */ phy_data_swapped = ((data >> 8) & 0x00FF) | ((data << 8) & 0xFF00); @@ -429,9 +470,9 @@ s32 e1000_write_phy_reg_i2c(struct e1000_hw *hw, u32 offset, u16 data) * PHY to retrieve the desired data. */ i2ccmd = ((offset << E1000_I2CCMD_REG_ADDR_SHIFT) | - (phy->addr << E1000_I2CCMD_PHY_ADDR_SHIFT) | - E1000_I2CCMD_OPCODE_WRITE | - phy_data_swapped); + (phy->addr << E1000_I2CCMD_PHY_ADDR_SHIFT) | + E1000_I2CCMD_OPCODE_WRITE | + phy_data_swapped); E1000_WRITE_REG(hw, E1000_I2CCMD, i2ccmd); @@ -454,6 +495,139 @@ s32 e1000_write_phy_reg_i2c(struct e1000_hw *hw, u32 offset, u16 data) return E1000_SUCCESS; } +/** + * e1000_read_sfp_data_byte - Reads SFP module data. + * @hw: pointer to the HW structure + * @offset: byte location offset to be read + * @data: read data buffer pointer + * + * Reads one byte from SFP module data stored + * in SFP resided EEPROM memory or SFP diagnostic area. + * Function should be called with + * E1000_I2CCMD_SFP_DATA_ADDR() for SFP module database access + * E1000_I2CCMD_SFP_DIAG_ADDR() for SFP diagnostics parameters + * access + **/ +s32 e1000_read_sfp_data_byte(struct e1000_hw *hw, u16 offset, u8 *data) +{ + u32 i = 0; + u32 i2ccmd = 0; + u32 data_local = 0; + + DEBUGFUNC("e1000_read_sfp_data_byte"); + + if (offset > E1000_I2CCMD_SFP_DIAG_ADDR(255)) { + DEBUGOUT("I2CCMD command address exceeds upper limit\n"); + return -E1000_ERR_PHY; + } + + /* + * Set up Op-code, EEPROM Address,in the I2CCMD + * register. The MAC will take care of interfacing with the + * EEPROM to retrieve the desired data. + */ + i2ccmd = ((offset << E1000_I2CCMD_REG_ADDR_SHIFT) | + E1000_I2CCMD_OPCODE_READ); + + E1000_WRITE_REG(hw, E1000_I2CCMD, i2ccmd); + + /* Poll the ready bit to see if the I2C read completed */ + for (i = 0; i < E1000_I2CCMD_PHY_TIMEOUT; i++) { + usec_delay(50); + data_local = E1000_READ_REG(hw, E1000_I2CCMD); + if (data_local & E1000_I2CCMD_READY) + break; + } + if (!(data_local & E1000_I2CCMD_READY)) { + DEBUGOUT("I2CCMD Read did not complete\n"); + return -E1000_ERR_PHY; + } + if (data_local & E1000_I2CCMD_ERROR) { + DEBUGOUT("I2CCMD Error bit set\n"); + return -E1000_ERR_PHY; + } + *data = (u8) data_local & 0xFF; + + return E1000_SUCCESS; +} + +/** + * e1000_write_sfp_data_byte - Writes SFP module data. + * @hw: pointer to the HW structure + * @offset: byte location offset to write to + * @data: data to write + * + * Writes one byte to SFP module data stored + * in SFP resided EEPROM memory or SFP diagnostic area. + * Function should be called with + * E1000_I2CCMD_SFP_DATA_ADDR() for SFP module database access + * E1000_I2CCMD_SFP_DIAG_ADDR() for SFP diagnostics parameters + * access + **/ +s32 e1000_write_sfp_data_byte(struct e1000_hw *hw, u16 offset, u8 data) +{ + u32 i = 0; + u32 i2ccmd = 0; + u32 data_local = 0; + + DEBUGFUNC("e1000_write_sfp_data_byte"); + + if (offset > E1000_I2CCMD_SFP_DIAG_ADDR(255)) { + DEBUGOUT("I2CCMD command address exceeds upper limit\n"); + return -E1000_ERR_PHY; + } + /* + * The programming interface is 16 bits wide + * so we need to read the whole word first + * then update appropriate byte lane and write + * the updated word back. + */ + /* + * Set up Op-code, EEPROM Address,in the I2CCMD + * register. The MAC will take care of interfacing + * with an EEPROM to write the data given. + */ + i2ccmd = ((offset << E1000_I2CCMD_REG_ADDR_SHIFT) | + E1000_I2CCMD_OPCODE_READ); + /* Set a command to read single word */ + E1000_WRITE_REG(hw, E1000_I2CCMD, i2ccmd); + for (i = 0; i < E1000_I2CCMD_PHY_TIMEOUT; i++) { + usec_delay(50); + /* + * Poll the ready bit to see if lastly + * launched I2C operation completed + */ + i2ccmd = E1000_READ_REG(hw, E1000_I2CCMD); + if (i2ccmd & E1000_I2CCMD_READY) { + /* Check if this is READ or WRITE phase */ + if ((i2ccmd & E1000_I2CCMD_OPCODE_READ) == + E1000_I2CCMD_OPCODE_READ) { + /* + * Write the selected byte + * lane and update whole word + */ + data_local = i2ccmd & 0xFF00; + data_local |= data; + i2ccmd = ((offset << + E1000_I2CCMD_REG_ADDR_SHIFT) | + E1000_I2CCMD_OPCODE_WRITE | data_local); + E1000_WRITE_REG(hw, E1000_I2CCMD, i2ccmd); + } else { + break; + } + } + } + if (!(i2ccmd & E1000_I2CCMD_READY)) { + DEBUGOUT("I2CCMD Write did not complete\n"); + return -E1000_ERR_PHY; + } + if (i2ccmd & E1000_I2CCMD_ERROR) { + DEBUGOUT("I2CCMD Error bit set\n"); + return -E1000_ERR_PHY; + } + return E1000_SUCCESS; +} + /** * e1000_read_phy_reg_m88 - Read m88 PHY register * @hw: pointer to the HW structure @@ -466,23 +640,22 @@ s32 e1000_write_phy_reg_i2c(struct e1000_hw *hw, u32 offset, u16 data) **/ s32 e1000_read_phy_reg_m88(struct e1000_hw *hw, u32 offset, u16 *data) { - s32 ret_val = E1000_SUCCESS; + s32 ret_val; DEBUGFUNC("e1000_read_phy_reg_m88"); - if (!(hw->phy.ops.acquire)) - goto out; + if (!hw->phy.ops.acquire) + return E1000_SUCCESS; ret_val = hw->phy.ops.acquire(hw); if (ret_val) - goto out; + return ret_val; ret_val = e1000_read_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset, - data); + data); hw->phy.ops.release(hw); -out: return ret_val; } @@ -497,26 +670,45 @@ s32 e1000_read_phy_reg_m88(struct e1000_hw *hw, u32 offset, u16 *data) **/ s32 e1000_write_phy_reg_m88(struct e1000_hw *hw, u32 offset, u16 data) { - s32 ret_val = E1000_SUCCESS; + s32 ret_val; DEBUGFUNC("e1000_write_phy_reg_m88"); - if (!(hw->phy.ops.acquire)) - goto out; + if (!hw->phy.ops.acquire) + return E1000_SUCCESS; ret_val = hw->phy.ops.acquire(hw); if (ret_val) - goto out; + return ret_val; ret_val = e1000_write_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset, - data); + data); hw->phy.ops.release(hw); -out: return ret_val; } +/** + * e1000_set_page_igp - Set page as on IGP-like PHY(s) + * @hw: pointer to the HW structure + * @page: page to set (shifted left when necessary) + * + * Sets PHY page required for PHY register access. Assumes semaphore is + * already acquired. Note, this function sets phy.addr to 1 so the caller + * must set it appropriately (if necessary) after this function returns. + **/ +s32 e1000_set_page_igp(struct e1000_hw *hw, u16 page) +{ + DEBUGFUNC("e1000_set_page_igp"); + + DEBUGOUT1("Setting page 0x%x\n", page); + + hw->phy.addr = 1; + + return e1000_write_phy_reg_mdic(hw, IGP01E1000_PHY_PAGE_SELECT, page); +} + /** * __e1000_read_phy_reg_igp - Read igp PHY register * @hw: pointer to the HW structure @@ -529,36 +721,32 @@ s32 e1000_write_phy_reg_m88(struct e1000_hw *hw, u32 offset, u16 data) * semaphores before exiting. **/ static s32 __e1000_read_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 *data, - bool locked) + bool locked) { s32 ret_val = E1000_SUCCESS; DEBUGFUNC("__e1000_read_phy_reg_igp"); if (!locked) { - if (!(hw->phy.ops.acquire)) - goto out; + if (!hw->phy.ops.acquire) + return E1000_SUCCESS; ret_val = hw->phy.ops.acquire(hw); if (ret_val) - goto out; + return ret_val; } - if (offset > MAX_PHY_MULTI_PAGE_REG) { + if (offset > MAX_PHY_MULTI_PAGE_REG) ret_val = e1000_write_phy_reg_mdic(hw, - IGP01E1000_PHY_PAGE_SELECT, - (u16)offset); - if (ret_val) - goto release; - } - - ret_val = e1000_read_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset, - data); - -release: + IGP01E1000_PHY_PAGE_SELECT, + (u16)offset); + if (!ret_val) + ret_val = e1000_read_phy_reg_mdic(hw, + MAX_PHY_REG_ADDRESS & offset, + data); if (!locked) hw->phy.ops.release(hw); -out: + return ret_val; } @@ -602,37 +790,32 @@ s32 e1000_read_phy_reg_igp_locked(struct e1000_hw *hw, u32 offset, u16 *data) * at the offset. Release any acquired semaphores before exiting. **/ static s32 __e1000_write_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 data, - bool locked) + bool locked) { s32 ret_val = E1000_SUCCESS; DEBUGFUNC("e1000_write_phy_reg_igp"); if (!locked) { - if (!(hw->phy.ops.acquire)) - goto out; + if (!hw->phy.ops.acquire) + return E1000_SUCCESS; ret_val = hw->phy.ops.acquire(hw); if (ret_val) - goto out; + return ret_val; } - if (offset > MAX_PHY_MULTI_PAGE_REG) { + if (offset > MAX_PHY_MULTI_PAGE_REG) ret_val = e1000_write_phy_reg_mdic(hw, - IGP01E1000_PHY_PAGE_SELECT, - (u16)offset); - if (ret_val) - goto release; - } - - ret_val = e1000_write_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset, - data); - -release: + IGP01E1000_PHY_PAGE_SELECT, + (u16)offset); + if (!ret_val) + ret_val = e1000_write_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & + offset, + data); if (!locked) hw->phy.ops.release(hw); -out: return ret_val; } @@ -676,25 +859,27 @@ s32 e1000_write_phy_reg_igp_locked(struct e1000_hw *hw, u32 offset, u16 data) * Release any acquired semaphores before exiting. **/ static s32 __e1000_read_kmrn_reg(struct e1000_hw *hw, u32 offset, u16 *data, - bool locked) + bool locked) { u32 kmrnctrlsta; - s32 ret_val = E1000_SUCCESS; DEBUGFUNC("__e1000_read_kmrn_reg"); if (!locked) { - if (!(hw->phy.ops.acquire)) - goto out; + s32 ret_val = E1000_SUCCESS; + + if (!hw->phy.ops.acquire) + return E1000_SUCCESS; ret_val = hw->phy.ops.acquire(hw); if (ret_val) - goto out; + return ret_val; } kmrnctrlsta = ((offset << E1000_KMRNCTRLSTA_OFFSET_SHIFT) & - E1000_KMRNCTRLSTA_OFFSET) | E1000_KMRNCTRLSTA_REN; + E1000_KMRNCTRLSTA_OFFSET) | E1000_KMRNCTRLSTA_REN; E1000_WRITE_REG(hw, E1000_KMRNCTRLSTA, kmrnctrlsta); + E1000_WRITE_FLUSH(hw); usec_delay(2); @@ -704,8 +889,7 @@ static s32 __e1000_read_kmrn_reg(struct e1000_hw *hw, u32 offset, u16 *data, if (!locked) hw->phy.ops.release(hw); -out: - return ret_val; + return E1000_SUCCESS; } /** @@ -750,33 +934,34 @@ s32 e1000_read_kmrn_reg_locked(struct e1000_hw *hw, u32 offset, u16 *data) * before exiting. **/ static s32 __e1000_write_kmrn_reg(struct e1000_hw *hw, u32 offset, u16 data, - bool locked) + bool locked) { u32 kmrnctrlsta; - s32 ret_val = E1000_SUCCESS; DEBUGFUNC("e1000_write_kmrn_reg_generic"); if (!locked) { - if (!(hw->phy.ops.acquire)) - goto out; + s32 ret_val = E1000_SUCCESS; + + if (!hw->phy.ops.acquire) + return E1000_SUCCESS; ret_val = hw->phy.ops.acquire(hw); if (ret_val) - goto out; + return ret_val; } kmrnctrlsta = ((offset << E1000_KMRNCTRLSTA_OFFSET_SHIFT) & - E1000_KMRNCTRLSTA_OFFSET) | data; + E1000_KMRNCTRLSTA_OFFSET) | data; E1000_WRITE_REG(hw, E1000_KMRNCTRLSTA, kmrnctrlsta); + E1000_WRITE_FLUSH(hw); usec_delay(2); if (!locked) hw->phy.ops.release(hw); -out: - return ret_val; + return E1000_SUCCESS; } /** @@ -807,6 +992,46 @@ s32 e1000_write_kmrn_reg_locked(struct e1000_hw *hw, u32 offset, u16 data) return __e1000_write_kmrn_reg(hw, offset, data, TRUE); } +/** + * e1000_set_master_slave_mode - Setup PHY for Master/slave mode + * @hw: pointer to the HW structure + * + * Sets up Master/slave mode + **/ +static s32 e1000_set_master_slave_mode(struct e1000_hw *hw) +{ + s32 ret_val; + u16 phy_data; + + /* Resolve Master/Slave mode */ + ret_val = hw->phy.ops.read_reg(hw, PHY_1000T_CTRL, &phy_data); + if (ret_val) + return ret_val; + + /* load defaults for future use */ + hw->phy.original_ms_type = (phy_data & CR_1000T_MS_ENABLE) ? + ((phy_data & CR_1000T_MS_VALUE) ? + e1000_ms_force_master : + e1000_ms_force_slave) : e1000_ms_auto; + + switch (hw->phy.ms_type) { + case e1000_ms_force_master: + phy_data |= (CR_1000T_MS_ENABLE | CR_1000T_MS_VALUE); + break; + case e1000_ms_force_slave: + phy_data |= CR_1000T_MS_ENABLE; + phy_data &= ~(CR_1000T_MS_VALUE); + break; + case e1000_ms_auto: + phy_data &= ~CR_1000T_MS_ENABLE; + /* fall-through */ + default: + break; + } + + return hw->phy.ops.write_reg(hw, PHY_1000T_CTRL, phy_data); +} + /** * e1000_copper_link_setup_82577 - Setup 82577 PHY for copper link * @hw: pointer to the HW structure @@ -820,23 +1045,18 @@ s32 e1000_copper_link_setup_82577(struct e1000_hw *hw) DEBUGFUNC("e1000_copper_link_setup_82577"); - if (hw->phy.reset_disable) { - ret_val = E1000_SUCCESS; - goto out; - } - if (hw->phy.type == e1000_phy_82580) { ret_val = hw->phy.ops.reset(hw); if (ret_val) { DEBUGOUT("Error resetting the PHY.\n"); - goto out; + return ret_val; } } /* Enable CRS on Tx. This must be set for half-duplex operation. */ ret_val = hw->phy.ops.read_reg(hw, I82577_CFG_REG, &phy_data); if (ret_val) - goto out; + return ret_val; phy_data |= I82577_CFG_ASSERT_CRS_ON_TX; @@ -844,9 +1064,36 @@ s32 e1000_copper_link_setup_82577(struct e1000_hw *hw) phy_data |= I82577_CFG_ENABLE_DOWNSHIFT; ret_val = hw->phy.ops.write_reg(hw, I82577_CFG_REG, phy_data); + if (ret_val) + return ret_val; -out: - return ret_val; + /* Set MDI/MDIX mode */ + ret_val = hw->phy.ops.read_reg(hw, I82577_PHY_CTRL_2, &phy_data); + if (ret_val) + return ret_val; + phy_data &= ~I82577_PHY_CTRL2_MDIX_CFG_MASK; + /* + * Options: + * 0 - Auto (default) + * 1 - MDI mode + * 2 - MDI-X mode + */ + switch (hw->phy.mdix) { + case 1: + break; + case 2: + phy_data |= I82577_PHY_CTRL2_MANUAL_MDIX; + break; + case 0: + default: + phy_data |= I82577_PHY_CTRL2_AUTO_MDI_MDIX; + break; + } + ret_val = hw->phy.ops.write_reg(hw, I82577_PHY_CTRL_2, phy_data); + if (ret_val) + return ret_val; + + return e1000_set_master_slave_mode(hw); } /** @@ -864,15 +1111,11 @@ s32 e1000_copper_link_setup_m88(struct e1000_hw *hw) DEBUGFUNC("e1000_copper_link_setup_m88"); - if (phy->reset_disable) { - ret_val = E1000_SUCCESS; - goto out; - } /* Enable CRS on Tx. This must be set for half-duplex operation. */ ret_val = phy->ops.read_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data); if (ret_val) - goto out; + return ret_val; /* For BM PHY this bit is downshift enable */ if (phy->type != e1000_phy_bm) @@ -912,16 +1155,32 @@ s32 e1000_copper_link_setup_m88(struct e1000_hw *hw) * 1 - Enabled */ phy_data &= ~M88E1000_PSCR_POLARITY_REVERSAL; - if (phy->disable_polarity_correction == 1) + if (phy->disable_polarity_correction) phy_data |= M88E1000_PSCR_POLARITY_REVERSAL; /* Enable downshift on BM (disabled by default) */ - if (phy->type == e1000_phy_bm) + if (phy->type == e1000_phy_bm) { + /* For 82574/82583, first disable then enable downshift */ + if (phy->id == BME1000_E_PHY_ID_R2) { + phy_data &= ~BME1000_PSCR_ENABLE_DOWNSHIFT; + ret_val = phy->ops.write_reg(hw, M88E1000_PHY_SPEC_CTRL, + phy_data); + if (ret_val) + return ret_val; + /* Commit the changes. */ + ret_val = phy->ops.commit(hw); + if (ret_val) { + DEBUGOUT("Error committing the PHY changes\n"); + return ret_val; + } + } + phy_data |= BME1000_PSCR_ENABLE_DOWNSHIFT; + } ret_val = phy->ops.write_reg(hw, M88E1000_PHY_SPEC_CTRL, phy_data); if (ret_val) - goto out; + return ret_val; if ((phy->type == e1000_phy_m88) && (phy->revision < E1000_REVISION_4) && @@ -931,9 +1190,9 @@ s32 e1000_copper_link_setup_m88(struct e1000_hw *hw) * to 25MHz clock. */ ret_val = phy->ops.read_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL, - &phy_data); + &phy_data); if (ret_val) - goto out; + return ret_val; phy_data |= M88E1000_EPSCR_TX_CLK_25; @@ -945,52 +1204,57 @@ s32 e1000_copper_link_setup_m88(struct e1000_hw *hw) } else { /* Configure Master and Slave downshift values */ phy_data &= ~(M88E1000_EPSCR_MASTER_DOWNSHIFT_MASK | - M88E1000_EPSCR_SLAVE_DOWNSHIFT_MASK); + M88E1000_EPSCR_SLAVE_DOWNSHIFT_MASK); phy_data |= (M88E1000_EPSCR_MASTER_DOWNSHIFT_1X | - M88E1000_EPSCR_SLAVE_DOWNSHIFT_1X); + M88E1000_EPSCR_SLAVE_DOWNSHIFT_1X); } ret_val = phy->ops.write_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL, - phy_data); + phy_data); if (ret_val) - goto out; + return ret_val; } if ((phy->type == e1000_phy_bm) && (phy->id == BME1000_E_PHY_ID_R2)) { /* Set PHY page 0, register 29 to 0x0003 */ ret_val = phy->ops.write_reg(hw, 29, 0x0003); if (ret_val) - goto out; + return ret_val; /* Set PHY page 0, register 30 to 0x0000 */ ret_val = phy->ops.write_reg(hw, 30, 0x0000); if (ret_val) - goto out; + return ret_val; } /* Commit the changes. */ ret_val = phy->ops.commit(hw); if (ret_val) { DEBUGOUT("Error committing the PHY changes\n"); - goto out; + return ret_val; } if (phy->type == e1000_phy_82578) { ret_val = phy->ops.read_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL, - &phy_data); + &phy_data); if (ret_val) - goto out; + return ret_val; /* 82578 PHY - set the downshift count to 1x. */ phy_data |= I82578_EPSCR_DOWNSHIFT_ENABLE; phy_data &= ~I82578_EPSCR_DOWNSHIFT_COUNTER_MASK; ret_val = phy->ops.write_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL, - phy_data); + phy_data); if (ret_val) - goto out; + return ret_val; } -out: - return ret_val; + if (phy->type == e1000_phy_i210) { + ret_val = e1000_set_master_slave_mode(hw); + if (ret_val) + return ret_val; + } + + return E1000_SUCCESS; } /** @@ -1008,15 +1272,11 @@ s32 e1000_copper_link_setup_m88_gen2(struct e1000_hw *hw) DEBUGFUNC("e1000_copper_link_setup_m88_gen2"); - if (phy->reset_disable) { - ret_val = E1000_SUCCESS; - goto out; - } /* Enable CRS on Tx. This must be set for half-duplex operation. */ ret_val = phy->ops.read_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data); if (ret_val) - goto out; + return ret_val; /* * Options: @@ -1055,7 +1315,7 @@ s32 e1000_copper_link_setup_m88_gen2(struct e1000_hw *hw) * 1 - Enabled */ phy_data &= ~M88E1000_PSCR_POLARITY_REVERSAL; - if (phy->disable_polarity_correction == 1) + if (phy->disable_polarity_correction) phy_data |= M88E1000_PSCR_POLARITY_REVERSAL; /* Enable downshift and setting it to X6 */ @@ -1065,17 +1325,16 @@ s32 e1000_copper_link_setup_m88_gen2(struct e1000_hw *hw) ret_val = phy->ops.write_reg(hw, M88E1000_PHY_SPEC_CTRL, phy_data); if (ret_val) - goto out; + return ret_val; /* Commit the changes. */ ret_val = phy->ops.commit(hw); if (ret_val) { DEBUGOUT("Error committing the PHY changes\n"); - goto out; + return ret_val; } -out: - return ret_val; + return E1000_SUCCESS; } /** @@ -1093,15 +1352,11 @@ s32 e1000_copper_link_setup_igp(struct e1000_hw *hw) DEBUGFUNC("e1000_copper_link_setup_igp"); - if (phy->reset_disable) { - ret_val = E1000_SUCCESS; - goto out; - } ret_val = hw->phy.ops.reset(hw); if (ret_val) { DEBUGOUT("Error resetting the PHY.\n"); - goto out; + return ret_val; } /* @@ -1119,7 +1374,7 @@ s32 e1000_copper_link_setup_igp(struct e1000_hw *hw) ret_val = hw->phy.ops.set_d3_lplu_state(hw, FALSE); if (ret_val) { DEBUGOUT("Error Disabling LPLU D3\n"); - goto out; + return ret_val; } } @@ -1128,13 +1383,13 @@ s32 e1000_copper_link_setup_igp(struct e1000_hw *hw) ret_val = hw->phy.ops.set_d0_lplu_state(hw, FALSE); if (ret_val) { DEBUGOUT("Error Disabling LPLU D0\n"); - goto out; + return ret_val; } } /* Configure mdi-mdix settings */ ret_val = phy->ops.read_reg(hw, IGP01E1000_PHY_PORT_CTRL, &data); if (ret_val) - goto out; + return ret_val; data &= ~IGP01E1000_PSCR_AUTO_MDIX; @@ -1152,7 +1407,7 @@ s32 e1000_copper_link_setup_igp(struct e1000_hw *hw) } ret_val = phy->ops.write_reg(hw, IGP01E1000_PHY_PORT_CTRL, data); if (ret_val) - goto out; + return ret_val; /* set auto-master slave resolution settings */ if (hw->mac.autoneg) { @@ -1164,129 +1419,32 @@ s32 e1000_copper_link_setup_igp(struct e1000_hw *hw) if (phy->autoneg_advertised == ADVERTISE_1000_FULL) { /* Disable SmartSpeed */ ret_val = phy->ops.read_reg(hw, - IGP01E1000_PHY_PORT_CONFIG, - &data); + IGP01E1000_PHY_PORT_CONFIG, + &data); if (ret_val) - goto out; + return ret_val; data &= ~IGP01E1000_PSCFR_SMART_SPEED; ret_val = phy->ops.write_reg(hw, - IGP01E1000_PHY_PORT_CONFIG, - data); + IGP01E1000_PHY_PORT_CONFIG, + data); if (ret_val) - goto out; - - /* Set auto Master/Slave resolution process */ - ret_val = phy->ops.read_reg(hw, PHY_1000T_CTRL, &data); - if (ret_val) - goto out; - - data &= ~CR_1000T_MS_ENABLE; - ret_val = phy->ops.write_reg(hw, PHY_1000T_CTRL, data); - if (ret_val) - goto out; - } - - ret_val = phy->ops.read_reg(hw, PHY_1000T_CTRL, &data); - if (ret_val) - goto out; - - /* load defaults for future use */ - phy->original_ms_type = (data & CR_1000T_MS_ENABLE) ? - ((data & CR_1000T_MS_VALUE) ? - e1000_ms_force_master : - e1000_ms_force_slave) : - e1000_ms_auto; - - switch (phy->ms_type) { - case e1000_ms_force_master: - data |= (CR_1000T_MS_ENABLE | CR_1000T_MS_VALUE); - break; - case e1000_ms_force_slave: - data |= CR_1000T_MS_ENABLE; - data &= ~(CR_1000T_MS_VALUE); - break; - case e1000_ms_auto: - data &= ~CR_1000T_MS_ENABLE; - default: - break; - } - ret_val = phy->ops.write_reg(hw, PHY_1000T_CTRL, data); - if (ret_val) - goto out; - } - -out: - return ret_val; -} - -/** - * e1000_copper_link_autoneg - Setup/Enable autoneg for copper link - * @hw: pointer to the HW structure - * - * Performs initial bounds checking on autoneg advertisement parameter, then - * configure to advertise the full capability. Setup the PHY to autoneg - * and restart the negotiation process between the link partner. If - * autoneg_wait_to_complete, then wait for autoneg to complete before exiting. - **/ -s32 e1000_copper_link_autoneg(struct e1000_hw *hw) -{ - struct e1000_phy_info *phy = &hw->phy; - s32 ret_val; - u16 phy_ctrl; - - DEBUGFUNC("e1000_copper_link_autoneg"); - - /* - * Perform some bounds checking on the autoneg advertisement - * parameter. - */ - phy->autoneg_advertised &= phy->autoneg_mask; - - /* - * If autoneg_advertised is zero, we assume it was not defaulted - * by the calling code so we set to advertise full capability. - */ - if (phy->autoneg_advertised == 0) - phy->autoneg_advertised = phy->autoneg_mask; - - DEBUGOUT("Reconfiguring auto-neg advertisement params\n"); - ret_val = e1000_phy_setup_autoneg(hw); - if (ret_val) { - DEBUGOUT("Error Setting up Auto-Negotiation\n"); - goto out; - } - DEBUGOUT("Restarting Auto-Neg\n"); - - /* - * Restart auto-negotiation by setting the Auto Neg Enable bit and - * the Auto Neg Restart bit in the PHY control register. - */ - ret_val = phy->ops.read_reg(hw, PHY_CONTROL, &phy_ctrl); - if (ret_val) - goto out; + return ret_val; - phy_ctrl |= (MII_CR_AUTO_NEG_EN | MII_CR_RESTART_AUTO_NEG); - ret_val = phy->ops.write_reg(hw, PHY_CONTROL, phy_ctrl); - if (ret_val) - goto out; - - /* - * Does the user want to wait for Auto-Neg to complete here, or - * check at a later time (for example, callback routine). - */ - if (phy->autoneg_wait_to_complete) { - ret_val = hw->mac.ops.wait_autoneg(hw); - if (ret_val) { - DEBUGOUT("Error while waiting for " - "autoneg to complete\n"); - goto out; + /* Set auto Master/Slave resolution process */ + ret_val = phy->ops.read_reg(hw, PHY_1000T_CTRL, &data); + if (ret_val) + return ret_val; + + data &= ~CR_1000T_MS_ENABLE; + ret_val = phy->ops.write_reg(hw, PHY_1000T_CTRL, data); + if (ret_val) + return ret_val; } - } - hw->mac.get_link_status = TRUE; + ret_val = e1000_set_master_slave_mode(hw); + } -out: return ret_val; } @@ -1313,14 +1471,14 @@ s32 e1000_phy_setup_autoneg(struct e1000_hw *hw) /* Read the MII Auto-Neg Advertisement Register (Address 4). */ ret_val = phy->ops.read_reg(hw, PHY_AUTONEG_ADV, &mii_autoneg_adv_reg); if (ret_val) - goto out; + return ret_val; if (phy->autoneg_mask & ADVERTISE_1000_FULL) { /* Read the MII 1000Base-T Control Register (Address 9). */ ret_val = phy->ops.read_reg(hw, PHY_1000T_CTRL, - &mii_1000t_ctrl_reg); + &mii_1000t_ctrl_reg); if (ret_val) - goto out; + return ret_val; } /* @@ -1337,9 +1495,9 @@ s32 e1000_phy_setup_autoneg(struct e1000_hw *hw) * the 1000Base-T Control Register (Address 9). */ mii_autoneg_adv_reg &= ~(NWAY_AR_100TX_FD_CAPS | - NWAY_AR_100TX_HD_CAPS | - NWAY_AR_10T_FD_CAPS | - NWAY_AR_10T_HD_CAPS); + NWAY_AR_100TX_HD_CAPS | + NWAY_AR_10T_FD_CAPS | + NWAY_AR_10T_HD_CAPS); mii_1000t_ctrl_reg &= ~(CR_1000T_HD_CAPS | CR_1000T_FD_CAPS); DEBUGOUT1("autoneg_advertised %x\n", phy->autoneg_advertised); @@ -1434,25 +1592,87 @@ s32 e1000_phy_setup_autoneg(struct e1000_hw *hw) break; default: DEBUGOUT("Flow control param set incorrectly\n"); - ret_val = -E1000_ERR_CONFIG; - goto out; + return -E1000_ERR_CONFIG; } ret_val = phy->ops.write_reg(hw, PHY_AUTONEG_ADV, mii_autoneg_adv_reg); if (ret_val) - goto out; + return ret_val; DEBUGOUT1("Auto-Neg Advertising %x\n", mii_autoneg_adv_reg); - if (phy->autoneg_mask & ADVERTISE_1000_FULL) { - ret_val = phy->ops.write_reg(hw, - PHY_1000T_CTRL, - mii_1000t_ctrl_reg); - if (ret_val) - goto out; + if (phy->autoneg_mask & ADVERTISE_1000_FULL) + ret_val = phy->ops.write_reg(hw, PHY_1000T_CTRL, + mii_1000t_ctrl_reg); + + return ret_val; +} + +/** + * e1000_copper_link_autoneg - Setup/Enable autoneg for copper link + * @hw: pointer to the HW structure + * + * Performs initial bounds checking on autoneg advertisement parameter, then + * configure to advertise the full capability. Setup the PHY to autoneg + * and restart the negotiation process between the link partner. If + * autoneg_wait_to_complete, then wait for autoneg to complete before exiting. + **/ +s32 e1000_copper_link_autoneg(struct e1000_hw *hw) +{ + struct e1000_phy_info *phy = &hw->phy; + s32 ret_val; + u16 phy_ctrl; + + DEBUGFUNC("e1000_copper_link_autoneg"); + + /* + * Perform some bounds checking on the autoneg advertisement + * parameter. + */ + phy->autoneg_advertised &= phy->autoneg_mask; + + /* + * If autoneg_advertised is zero, we assume it was not defaulted + * by the calling code so we set to advertise full capability. + */ + if (!phy->autoneg_advertised) + phy->autoneg_advertised = phy->autoneg_mask; + + DEBUGOUT("Reconfiguring auto-neg advertisement params\n"); + ret_val = e1000_phy_setup_autoneg(hw); + if (ret_val) { + DEBUGOUT("Error Setting up Auto-Negotiation\n"); + return ret_val; } + DEBUGOUT("Restarting Auto-Neg\n"); + + /* + * Restart auto-negotiation by setting the Auto Neg Enable bit and + * the Auto Neg Restart bit in the PHY control register. + */ + ret_val = phy->ops.read_reg(hw, PHY_CONTROL, &phy_ctrl); + if (ret_val) + return ret_val; + + phy_ctrl |= (MII_CR_AUTO_NEG_EN | MII_CR_RESTART_AUTO_NEG); + ret_val = phy->ops.write_reg(hw, PHY_CONTROL, phy_ctrl); + if (ret_val) + return ret_val; + + /* + * Does the user want to wait for Auto-Neg to complete here, or + * check at a later time (for example, callback routine). + */ + if (phy->autoneg_wait_to_complete) { + ret_val = hw->mac.ops.wait_autoneg(hw); + if (ret_val) { + DEBUGOUT("Error while waiting for autoneg to complete\n"); + return ret_val; + } + } + + hw->mac.get_link_status = TRUE; -out: return ret_val; } @@ -1479,7 +1699,7 @@ s32 e1000_setup_copper_link_generic(struct e1000_hw *hw) */ ret_val = e1000_copper_link_autoneg(hw); if (ret_val) - goto out; + return ret_val; } else { /* * PHY will be set to 10H, 10F, 100H or 100F @@ -1489,7 +1709,7 @@ s32 e1000_setup_copper_link_generic(struct e1000_hw *hw) ret_val = hw->phy.ops.force_speed_duplex(hw); if (ret_val) { DEBUGOUT("Error Forcing Speed and Duplex\n"); - goto out; + return ret_val; } } @@ -1497,22 +1717,19 @@ s32 e1000_setup_copper_link_generic(struct e1000_hw *hw) * Check link status. Wait up to 100 microseconds for link to become * valid. */ - ret_val = e1000_phy_has_link_generic(hw, - COPPER_LINK_UP_LIMIT, - 10, - &link); + ret_val = e1000_phy_has_link_generic(hw, COPPER_LINK_UP_LIMIT, 10, + &link); if (ret_val) - goto out; + return ret_val; if (link) { DEBUGOUT("Valid link established!!!\n"); - e1000_config_collision_dist_generic(hw); + hw->mac.ops.config_collision_dist(hw); ret_val = e1000_config_fc_after_link_up_generic(hw); } else { DEBUGOUT("Unable to establish link!!!\n"); } -out: return ret_val; } @@ -1535,13 +1752,13 @@ s32 e1000_phy_force_speed_duplex_igp(struct e1000_hw *hw) ret_val = phy->ops.read_reg(hw, PHY_CONTROL, &phy_data); if (ret_val) - goto out; + return ret_val; e1000_phy_force_speed_duplex_setup(hw, &phy_data); ret_val = phy->ops.write_reg(hw, PHY_CONTROL, phy_data); if (ret_val) - goto out; + return ret_val; /* * Clear Auto-Crossover to force MDI manually. IGP requires MDI @@ -1549,14 +1766,14 @@ s32 e1000_phy_force_speed_duplex_igp(struct e1000_hw *hw) */ ret_val = phy->ops.read_reg(hw, IGP01E1000_PHY_PORT_CTRL, &phy_data); if (ret_val) - goto out; + return ret_val; phy_data &= ~IGP01E1000_PSCR_AUTO_MDIX; phy_data &= ~IGP01E1000_PSCR_FORCE_MDI_MDIX; ret_val = phy->ops.write_reg(hw, IGP01E1000_PHY_PORT_CTRL, phy_data); if (ret_val) - goto out; + return ret_val; DEBUGOUT1("IGP PSCR: %X\n", phy_data); @@ -1565,26 +1782,19 @@ s32 e1000_phy_force_speed_duplex_igp(struct e1000_hw *hw) if (phy->autoneg_wait_to_complete) { DEBUGOUT("Waiting for forced speed/duplex link on IGP phy.\n"); - ret_val = e1000_phy_has_link_generic(hw, - PHY_FORCE_LIMIT, - 100000, - &link); + ret_val = e1000_phy_has_link_generic(hw, PHY_FORCE_LIMIT, + 100000, &link); if (ret_val) - goto out; + return ret_val; if (!link) DEBUGOUT("Link taking longer than expected.\n"); /* Try once more */ - ret_val = e1000_phy_has_link_generic(hw, - PHY_FORCE_LIMIT, - 100000, - &link); - if (ret_val) - goto out; + ret_val = e1000_phy_has_link_generic(hw, PHY_FORCE_LIMIT, + 100000, &link); } -out: return ret_val; } @@ -1613,43 +1823,55 @@ s32 e1000_phy_force_speed_duplex_m88(struct e1000_hw *hw) */ ret_val = phy->ops.read_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data); if (ret_val) - goto out; + return ret_val; phy_data &= ~M88E1000_PSCR_AUTO_X_MODE; ret_val = phy->ops.write_reg(hw, M88E1000_PHY_SPEC_CTRL, phy_data); if (ret_val) - goto out; + return ret_val; DEBUGOUT1("M88E1000 PSCR: %X\n", phy_data); ret_val = phy->ops.read_reg(hw, PHY_CONTROL, &phy_data); if (ret_val) - goto out; + return ret_val; e1000_phy_force_speed_duplex_setup(hw, &phy_data); ret_val = phy->ops.write_reg(hw, PHY_CONTROL, phy_data); if (ret_val) - goto out; + return ret_val; /* Reset the phy to commit changes. */ ret_val = hw->phy.ops.commit(hw); if (ret_val) - goto out; + return ret_val; if (phy->autoneg_wait_to_complete) { DEBUGOUT("Waiting for forced speed/duplex link on M88 phy.\n"); ret_val = e1000_phy_has_link_generic(hw, PHY_FORCE_LIMIT, - 100000, &link); + 100000, &link); if (ret_val) - goto out; + return ret_val; if (!link) { - if (hw->phy.type != e1000_phy_m88 || - hw->phy.id == I347AT4_E_PHY_ID || - hw->phy.id == M88E1340M_E_PHY_ID || - hw->phy.id == M88E1112_E_PHY_ID) { + bool reset_dsp = TRUE; + + switch (hw->phy.id) { + case I347AT4_E_PHY_ID: + case M88E1340M_E_PHY_ID: + case M88E1112_E_PHY_ID: + case I210_I_PHY_ID: + reset_dsp = FALSE; + break; + default: + if (hw->phy.type != e1000_phy_m88) + reset_dsp = FALSE; + break; + } + + if (!reset_dsp) { DEBUGOUT("Link taking longer than expected.\n"); } else { /* @@ -1660,29 +1882,32 @@ s32 e1000_phy_force_speed_duplex_m88(struct e1000_hw *hw) M88E1000_PHY_PAGE_SELECT, 0x001d); if (ret_val) - goto out; + return ret_val; ret_val = e1000_phy_reset_dsp_generic(hw); if (ret_val) - goto out; + return ret_val; } } /* Try once more */ ret_val = e1000_phy_has_link_generic(hw, PHY_FORCE_LIMIT, - 100000, &link); + 100000, &link); if (ret_val) - goto out; + return ret_val; } - if (hw->phy.type != e1000_phy_m88 || - hw->phy.id == I347AT4_E_PHY_ID || - hw->phy.id == M88E1340M_E_PHY_ID || - hw->phy.id == M88E1112_E_PHY_ID) - goto out; + if (hw->phy.type != e1000_phy_m88) + return E1000_SUCCESS; + if (hw->phy.id == I347AT4_E_PHY_ID || + hw->phy.id == M88E1340M_E_PHY_ID || + hw->phy.id == M88E1112_E_PHY_ID) + return E1000_SUCCESS; + if (hw->phy.id == I210_I_PHY_ID) + return E1000_SUCCESS; ret_val = phy->ops.read_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL, &phy_data); if (ret_val) - goto out; + return ret_val; /* * Resetting the phy means we need to re-force TX_CLK in the @@ -1692,7 +1917,7 @@ s32 e1000_phy_force_speed_duplex_m88(struct e1000_hw *hw) phy_data |= M88E1000_EPSCR_TX_CLK_25; ret_val = phy->ops.write_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL, phy_data); if (ret_val) - goto out; + return ret_val; /* * In addition, we must re-enable CRS on Tx for both half and full @@ -1700,12 +1925,11 @@ s32 e1000_phy_force_speed_duplex_m88(struct e1000_hw *hw) */ ret_val = phy->ops.read_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data); if (ret_val) - goto out; + return ret_val; phy_data |= M88E1000_PSCR_ASSERT_CRS_ON_TX; ret_val = phy->ops.write_reg(hw, M88E1000_PHY_SPEC_CTRL, phy_data); -out: return ret_val; } @@ -1728,25 +1952,25 @@ s32 e1000_phy_force_speed_duplex_ife(struct e1000_hw *hw) ret_val = phy->ops.read_reg(hw, PHY_CONTROL, &data); if (ret_val) - goto out; + return ret_val; e1000_phy_force_speed_duplex_setup(hw, &data); ret_val = phy->ops.write_reg(hw, PHY_CONTROL, data); if (ret_val) - goto out; + return ret_val; /* Disable MDI-X support for 10/100 */ ret_val = phy->ops.read_reg(hw, IFE_PHY_MDIX_CONTROL, &data); if (ret_val) - goto out; + return ret_val; data &= ~IFE_PMC_AUTO_MDIX; data &= ~IFE_PMC_FORCE_MDIX; ret_val = phy->ops.write_reg(hw, IFE_PHY_MDIX_CONTROL, data); if (ret_val) - goto out; + return ret_val; DEBUGOUT1("IFE PMC: %X\n", data); @@ -1755,27 +1979,22 @@ s32 e1000_phy_force_speed_duplex_ife(struct e1000_hw *hw) if (phy->autoneg_wait_to_complete) { DEBUGOUT("Waiting for forced speed/duplex link on IFE phy.\n"); - ret_val = e1000_phy_has_link_generic(hw, - PHY_FORCE_LIMIT, - 100000, - &link); + ret_val = e1000_phy_has_link_generic(hw, PHY_FORCE_LIMIT, + 100000, &link); if (ret_val) - goto out; + return ret_val; if (!link) DEBUGOUT("Link taking longer than expected.\n"); /* Try once more */ - ret_val = e1000_phy_has_link_generic(hw, - PHY_FORCE_LIMIT, - 100000, - &link); + ret_val = e1000_phy_has_link_generic(hw, PHY_FORCE_LIMIT, + 100000, &link); if (ret_val) - goto out; + return ret_val; } -out: - return ret_val; + return E1000_SUCCESS; } /** @@ -1835,7 +2054,7 @@ void e1000_phy_force_speed_duplex_setup(struct e1000_hw *hw, u16 *phy_ctrl) DEBUGOUT("Forcing 10mb\n"); } - e1000_config_collision_dist_generic(hw); + hw->mac.ops.config_collision_dist(hw); E1000_WRITE_REG(hw, E1000_CTRL, ctrl); } @@ -1857,24 +2076,24 @@ void e1000_phy_force_speed_duplex_setup(struct e1000_hw *hw, u16 *phy_ctrl) s32 e1000_set_d3_lplu_state_generic(struct e1000_hw *hw, bool active) { struct e1000_phy_info *phy = &hw->phy; - s32 ret_val = E1000_SUCCESS; + s32 ret_val; u16 data; DEBUGFUNC("e1000_set_d3_lplu_state_generic"); - if (!(hw->phy.ops.read_reg)) - goto out; + if (!hw->phy.ops.read_reg) + return E1000_SUCCESS; ret_val = phy->ops.read_reg(hw, IGP02E1000_PHY_POWER_MGMT, &data); if (ret_val) - goto out; + return ret_val; if (!active) { data &= ~IGP02E1000_PM_D3_LPLU; ret_val = phy->ops.write_reg(hw, IGP02E1000_PHY_POWER_MGMT, - data); + data); if (ret_val) - goto out; + return ret_val; /* * LPLU and SmartSpeed are mutually exclusive. LPLU is used * during Dx states where the power conservation is most @@ -1883,52 +2102,51 @@ s32 e1000_set_d3_lplu_state_generic(struct e1000_hw *hw, bool active) */ if (phy->smart_speed == e1000_smart_speed_on) { ret_val = phy->ops.read_reg(hw, - IGP01E1000_PHY_PORT_CONFIG, - &data); + IGP01E1000_PHY_PORT_CONFIG, + &data); if (ret_val) - goto out; + return ret_val; data |= IGP01E1000_PSCFR_SMART_SPEED; ret_val = phy->ops.write_reg(hw, - IGP01E1000_PHY_PORT_CONFIG, - data); + IGP01E1000_PHY_PORT_CONFIG, + data); if (ret_val) - goto out; + return ret_val; } else if (phy->smart_speed == e1000_smart_speed_off) { ret_val = phy->ops.read_reg(hw, - IGP01E1000_PHY_PORT_CONFIG, - &data); + IGP01E1000_PHY_PORT_CONFIG, + &data); if (ret_val) - goto out; + return ret_val; data &= ~IGP01E1000_PSCFR_SMART_SPEED; ret_val = phy->ops.write_reg(hw, - IGP01E1000_PHY_PORT_CONFIG, - data); + IGP01E1000_PHY_PORT_CONFIG, + data); if (ret_val) - goto out; + return ret_val; } } else if ((phy->autoneg_advertised == E1000_ALL_SPEED_DUPLEX) || - (phy->autoneg_advertised == E1000_ALL_NOT_GIG) || - (phy->autoneg_advertised == E1000_ALL_10_SPEED)) { + (phy->autoneg_advertised == E1000_ALL_NOT_GIG) || + (phy->autoneg_advertised == E1000_ALL_10_SPEED)) { data |= IGP02E1000_PM_D3_LPLU; ret_val = phy->ops.write_reg(hw, IGP02E1000_PHY_POWER_MGMT, - data); + data); if (ret_val) - goto out; + return ret_val; /* When LPLU is enabled, we should disable SmartSpeed */ ret_val = phy->ops.read_reg(hw, IGP01E1000_PHY_PORT_CONFIG, - &data); + &data); if (ret_val) - goto out; + return ret_val; data &= ~IGP01E1000_PSCFR_SMART_SPEED; ret_val = phy->ops.write_reg(hw, IGP01E1000_PHY_PORT_CONFIG, - data); + data); } -out: return ret_val; } @@ -1949,32 +2167,31 @@ s32 e1000_check_downshift_generic(struct e1000_hw *hw) DEBUGFUNC("e1000_check_downshift_generic"); switch (phy->type) { + case e1000_phy_i210: case e1000_phy_m88: case e1000_phy_gg82563: case e1000_phy_bm: case e1000_phy_82578: - offset = M88E1000_PHY_SPEC_STATUS; - mask = M88E1000_PSSR_DOWNSHIFT; + offset = M88E1000_PHY_SPEC_STATUS; + mask = M88E1000_PSSR_DOWNSHIFT; break; case e1000_phy_igp: case e1000_phy_igp_2: case e1000_phy_igp_3: - offset = IGP01E1000_PHY_LINK_HEALTH; - mask = IGP01E1000_PLHR_SS_DOWNGRADE; + offset = IGP01E1000_PHY_LINK_HEALTH; + mask = IGP01E1000_PLHR_SS_DOWNGRADE; break; default: /* speed downshift not supported */ phy->speed_downgraded = FALSE; - ret_val = E1000_SUCCESS; - goto out; + return E1000_SUCCESS; } ret_val = phy->ops.read_reg(hw, offset, &phy_data); if (!ret_val) - phy->speed_downgraded = (phy_data & mask) ? TRUE : FALSE; + phy->speed_downgraded = !!(phy_data & mask); -out: return ret_val; } @@ -1998,8 +2215,8 @@ s32 e1000_check_polarity_m88(struct e1000_hw *hw) if (!ret_val) phy->cable_polarity = (data & M88E1000_PSSR_REV_POLARITY) - ? e1000_rev_polarity_reversed - : e1000_rev_polarity_normal; + ? e1000_rev_polarity_reversed + : e1000_rev_polarity_normal; return ret_val; } @@ -2027,29 +2244,28 @@ s32 e1000_check_polarity_igp(struct e1000_hw *hw) */ ret_val = phy->ops.read_reg(hw, IGP01E1000_PHY_PORT_STATUS, &data); if (ret_val) - goto out; + return ret_val; if ((data & IGP01E1000_PSSR_SPEED_MASK) == IGP01E1000_PSSR_SPEED_1000MBPS) { - offset = IGP01E1000_PHY_PCS_INIT_REG; - mask = IGP01E1000_PHY_POLARITY_MASK; + offset = IGP01E1000_PHY_PCS_INIT_REG; + mask = IGP01E1000_PHY_POLARITY_MASK; } else { /* * This really only applies to 10Mbps since * there is no polarity for 100Mbps (always 0). */ - offset = IGP01E1000_PHY_PORT_STATUS; - mask = IGP01E1000_PSSR_POLARITY_REVERSED; + offset = IGP01E1000_PHY_PORT_STATUS; + mask = IGP01E1000_PSSR_POLARITY_REVERSED; } ret_val = phy->ops.read_reg(hw, offset, &data); if (!ret_val) phy->cable_polarity = (data & mask) - ? e1000_rev_polarity_reversed - : e1000_rev_polarity_normal; + ? e1000_rev_polarity_reversed + : e1000_rev_polarity_normal; -out: return ret_val; } @@ -2082,8 +2298,8 @@ s32 e1000_check_polarity_ife(struct e1000_hw *hw) if (!ret_val) phy->cable_polarity = (phy_data & mask) - ? e1000_rev_polarity_reversed - : e1000_rev_polarity_normal; + ? e1000_rev_polarity_reversed + : e1000_rev_polarity_normal; return ret_val; } @@ -2102,7 +2318,7 @@ s32 e1000_wait_autoneg_generic(struct e1000_hw *hw) DEBUGFUNC("e1000_wait_autoneg_generic"); - if (!(hw->phy.ops.read_reg)) + if (!hw->phy.ops.read_reg) return E1000_SUCCESS; /* Break after autoneg completes or PHY_AUTO_NEG_LIMIT expires. */ @@ -2135,14 +2351,14 @@ s32 e1000_wait_autoneg_generic(struct e1000_hw *hw) * Polls the PHY status register for link, 'iterations' number of times. **/ s32 e1000_phy_has_link_generic(struct e1000_hw *hw, u32 iterations, - u32 usec_interval, bool *success) + u32 usec_interval, bool *success) { s32 ret_val = E1000_SUCCESS; u16 i, phy_status; DEBUGFUNC("e1000_phy_has_link_generic"); - if (!(hw->phy.ops.read_reg)) + if (!hw->phy.ops.read_reg) return E1000_SUCCESS; for (i = 0; i < iterations; i++) { @@ -2170,7 +2386,7 @@ s32 e1000_phy_has_link_generic(struct e1000_hw *hw, u32 iterations, usec_delay(usec_interval); } - *success = (i < iterations) ? TRUE : FALSE; + *success = (i < iterations); return ret_val; } @@ -2200,22 +2416,20 @@ s32 e1000_get_cable_length_m88(struct e1000_hw *hw) ret_val = phy->ops.read_reg(hw, M88E1000_PHY_SPEC_STATUS, &phy_data); if (ret_val) - goto out; + return ret_val; index = (phy_data & M88E1000_PSSR_CABLE_LENGTH) >> - M88E1000_PSSR_CABLE_LENGTH_SHIFT; - if (index >= M88E1000_CABLE_LENGTH_TABLE_SIZE - 1) { - ret_val = -E1000_ERR_PHY; - goto out; - } + M88E1000_PSSR_CABLE_LENGTH_SHIFT; + + if (index >= M88E1000_CABLE_LENGTH_TABLE_SIZE - 1) + return -E1000_ERR_PHY; phy->min_cable_length = e1000_m88_cable_length_table[index]; phy->max_cable_length = e1000_m88_cable_length_table[index + 1]; phy->cable_length = (phy->min_cable_length + phy->max_cable_length) / 2; -out: - return ret_val; + return E1000_SUCCESS; } s32 e1000_get_cable_length_m88_gen2(struct e1000_hw *hw) @@ -2227,64 +2441,85 @@ s32 e1000_get_cable_length_m88_gen2(struct e1000_hw *hw) DEBUGFUNC("e1000_get_cable_length_m88_gen2"); switch (hw->phy.id) { + case I210_I_PHY_ID: + /* Get cable length from PHY Cable Diagnostics Control Reg */ + ret_val = phy->ops.read_reg(hw, (0x7 << GS40G_PAGE_SHIFT) + + (I347AT4_PCDL + phy->addr), + &phy_data); + if (ret_val) + return ret_val; + + /* Check if the unit of cable length is meters or cm */ + ret_val = phy->ops.read_reg(hw, (0x7 << GS40G_PAGE_SHIFT) + + I347AT4_PCDC, &phy_data2); + if (ret_val) + return ret_val; + + is_cm = !(phy_data2 & I347AT4_PCDC_CABLE_LENGTH_UNIT); + + /* Populate the phy structure with cable length in meters */ + phy->min_cable_length = phy_data / (is_cm ? 100 : 1); + phy->max_cable_length = phy_data / (is_cm ? 100 : 1); + phy->cable_length = phy_data / (is_cm ? 100 : 1); + break; case M88E1340M_E_PHY_ID: case I347AT4_E_PHY_ID: /* Remember the original page select and set it to 7 */ ret_val = phy->ops.read_reg(hw, I347AT4_PAGE_SELECT, &default_page); if (ret_val) - goto out; + return ret_val; ret_val = phy->ops.write_reg(hw, I347AT4_PAGE_SELECT, 0x07); if (ret_val) - goto out; + return ret_val; /* Get cable length from PHY Cable Diagnostics Control Reg */ ret_val = phy->ops.read_reg(hw, (I347AT4_PCDL + phy->addr), &phy_data); if (ret_val) - goto out; + return ret_val; /* Check if the unit of cable length is meters or cm */ ret_val = phy->ops.read_reg(hw, I347AT4_PCDC, &phy_data2); if (ret_val) - goto out; + return ret_val; - is_cm = !(phy_data & I347AT4_PCDC_CABLE_LENGTH_UNIT); + is_cm = !(phy_data2 & I347AT4_PCDC_CABLE_LENGTH_UNIT); /* Populate the phy structure with cable length in meters */ phy->min_cable_length = phy_data / (is_cm ? 100 : 1); phy->max_cable_length = phy_data / (is_cm ? 100 : 1); phy->cable_length = phy_data / (is_cm ? 100 : 1); - /* Reset the page selec to its original value */ + /* Reset the page select to its original value */ ret_val = phy->ops.write_reg(hw, I347AT4_PAGE_SELECT, default_page); if (ret_val) - goto out; + return ret_val; break; + case M88E1112_E_PHY_ID: /* Remember the original page select and set it to 5 */ ret_val = phy->ops.read_reg(hw, I347AT4_PAGE_SELECT, &default_page); if (ret_val) - goto out; + return ret_val; ret_val = phy->ops.write_reg(hw, I347AT4_PAGE_SELECT, 0x05); if (ret_val) - goto out; + return ret_val; ret_val = phy->ops.read_reg(hw, M88E1112_VCT_DSP_DISTANCE, &phy_data); if (ret_val) - goto out; + return ret_val; index = (phy_data & M88E1000_PSSR_CABLE_LENGTH) >> M88E1000_PSSR_CABLE_LENGTH_SHIFT; - if (index >= M88E1000_CABLE_LENGTH_TABLE_SIZE - 1) { - ret_val = -E1000_ERR_PHY; - goto out; - } + + if (index >= M88E1000_CABLE_LENGTH_TABLE_SIZE - 1) + return -E1000_ERR_PHY; phy->min_cable_length = e1000_m88_cable_length_table[index]; phy->max_cable_length = e1000_m88_cable_length_table[index + 1]; @@ -2296,15 +2531,13 @@ s32 e1000_get_cable_length_m88_gen2(struct e1000_hw *hw) ret_val = phy->ops.write_reg(hw, I347AT4_PAGE_SELECT, default_page); if (ret_val) - goto out; + return ret_val; break; default: - ret_val = -E1000_ERR_PHY; - goto out; + return -E1000_ERR_PHY; } -out: return ret_val; } @@ -2322,15 +2555,15 @@ s32 e1000_get_cable_length_m88_gen2(struct e1000_hw *hw) s32 e1000_get_cable_length_igp_2(struct e1000_hw *hw) { struct e1000_phy_info *phy = &hw->phy; - s32 ret_val = E1000_SUCCESS; + s32 ret_val; u16 phy_data, i, agc_value = 0; u16 cur_agc_index, max_agc_index = 0; u16 min_agc_index = IGP02E1000_CABLE_LENGTH_TABLE_SIZE - 1; static const u16 agc_reg_array[IGP02E1000_PHY_CHANNEL_NUM] = { - IGP02E1000_PHY_AGC_A, - IGP02E1000_PHY_AGC_B, - IGP02E1000_PHY_AGC_C, - IGP02E1000_PHY_AGC_D + IGP02E1000_PHY_AGC_A, + IGP02E1000_PHY_AGC_B, + IGP02E1000_PHY_AGC_C, + IGP02E1000_PHY_AGC_D }; DEBUGFUNC("e1000_get_cable_length_igp_2"); @@ -2339,7 +2572,7 @@ s32 e1000_get_cable_length_igp_2(struct e1000_hw *hw) for (i = 0; i < IGP02E1000_PHY_CHANNEL_NUM; i++) { ret_val = phy->ops.read_reg(hw, agc_reg_array[i], &phy_data); if (ret_val) - goto out; + return ret_val; /* * Getting bits 15:9, which represent the combination of @@ -2348,14 +2581,12 @@ s32 e1000_get_cable_length_igp_2(struct e1000_hw *hw) * approximate cable length. */ cur_agc_index = (phy_data >> IGP02E1000_AGC_LENGTH_SHIFT) & - IGP02E1000_AGC_LENGTH_MASK; + IGP02E1000_AGC_LENGTH_MASK; /* Array index bound check. */ if ((cur_agc_index >= IGP02E1000_CABLE_LENGTH_TABLE_SIZE) || - (cur_agc_index == 0)) { - ret_val = -E1000_ERR_PHY; - goto out; - } + (cur_agc_index == 0)) + return -E1000_ERR_PHY; /* Remove min & max AGC values from calculation. */ if (e1000_igp_2_cable_length_table[min_agc_index] > @@ -2369,18 +2600,17 @@ s32 e1000_get_cable_length_igp_2(struct e1000_hw *hw) } agc_value -= (e1000_igp_2_cable_length_table[min_agc_index] + - e1000_igp_2_cable_length_table[max_agc_index]); + e1000_igp_2_cable_length_table[max_agc_index]); agc_value /= (IGP02E1000_PHY_CHANNEL_NUM - 2); /* Calculate cable length with the error range of +/- 10 meters. */ phy->min_cable_length = ((agc_value - IGP02E1000_AGC_RANGE) > 0) ? - (agc_value - IGP02E1000_AGC_RANGE) : 0; + (agc_value - IGP02E1000_AGC_RANGE) : 0; phy->max_cable_length = agc_value + IGP02E1000_AGC_RANGE; phy->cable_length = (phy->min_cable_length + phy->max_cable_length) / 2; -out: - return ret_val; + return E1000_SUCCESS; } /** @@ -2404,53 +2634,51 @@ s32 e1000_get_phy_info_m88(struct e1000_hw *hw) if (phy->media_type != e1000_media_type_copper) { DEBUGOUT("Phy info is only valid for copper media\n"); - ret_val = -E1000_ERR_CONFIG; - goto out; + return -E1000_ERR_CONFIG; } ret_val = e1000_phy_has_link_generic(hw, 1, 0, &link); if (ret_val) - goto out; + return ret_val; if (!link) { DEBUGOUT("Phy info is only valid if link is up\n"); - ret_val = -E1000_ERR_CONFIG; - goto out; + return -E1000_ERR_CONFIG; } ret_val = phy->ops.read_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data); if (ret_val) - goto out; + return ret_val; - phy->polarity_correction = (phy_data & M88E1000_PSCR_POLARITY_REVERSAL) - ? TRUE : FALSE; + phy->polarity_correction = !!(phy_data & + M88E1000_PSCR_POLARITY_REVERSAL); ret_val = e1000_check_polarity_m88(hw); if (ret_val) - goto out; + return ret_val; ret_val = phy->ops.read_reg(hw, M88E1000_PHY_SPEC_STATUS, &phy_data); if (ret_val) - goto out; + return ret_val; - phy->is_mdix = (phy_data & M88E1000_PSSR_MDIX) ? TRUE : FALSE; + phy->is_mdix = !!(phy_data & M88E1000_PSSR_MDIX); if ((phy_data & M88E1000_PSSR_SPEED) == M88E1000_PSSR_1000MBS) { ret_val = hw->phy.ops.get_cable_length(hw); if (ret_val) - goto out; + return ret_val; ret_val = phy->ops.read_reg(hw, PHY_1000T_STATUS, &phy_data); if (ret_val) - goto out; + return ret_val; phy->local_rx = (phy_data & SR_1000T_LOCAL_RX_STATUS) - ? e1000_1000t_rx_status_ok - : e1000_1000t_rx_status_not_ok; + ? e1000_1000t_rx_status_ok + : e1000_1000t_rx_status_not_ok; phy->remote_rx = (phy_data & SR_1000T_REMOTE_RX_STATUS) - ? e1000_1000t_rx_status_ok - : e1000_1000t_rx_status_not_ok; + ? e1000_1000t_rx_status_ok + : e1000_1000t_rx_status_not_ok; } else { /* Set values to "undefined" */ phy->cable_length = E1000_CABLE_LENGTH_UNDEFINED; @@ -2458,7 +2686,6 @@ s32 e1000_get_phy_info_m88(struct e1000_hw *hw) phy->remote_rx = e1000_1000t_rx_status_undefined; } -out: return ret_val; } @@ -2482,50 +2709,48 @@ s32 e1000_get_phy_info_igp(struct e1000_hw *hw) ret_val = e1000_phy_has_link_generic(hw, 1, 0, &link); if (ret_val) - goto out; + return ret_val; if (!link) { DEBUGOUT("Phy info is only valid if link is up\n"); - ret_val = -E1000_ERR_CONFIG; - goto out; + return -E1000_ERR_CONFIG; } phy->polarity_correction = TRUE; ret_val = e1000_check_polarity_igp(hw); if (ret_val) - goto out; + return ret_val; ret_val = phy->ops.read_reg(hw, IGP01E1000_PHY_PORT_STATUS, &data); if (ret_val) - goto out; + return ret_val; - phy->is_mdix = (data & IGP01E1000_PSSR_MDIX) ? TRUE : FALSE; + phy->is_mdix = !!(data & IGP01E1000_PSSR_MDIX); if ((data & IGP01E1000_PSSR_SPEED_MASK) == IGP01E1000_PSSR_SPEED_1000MBPS) { ret_val = phy->ops.get_cable_length(hw); if (ret_val) - goto out; + return ret_val; ret_val = phy->ops.read_reg(hw, PHY_1000T_STATUS, &data); if (ret_val) - goto out; + return ret_val; phy->local_rx = (data & SR_1000T_LOCAL_RX_STATUS) - ? e1000_1000t_rx_status_ok - : e1000_1000t_rx_status_not_ok; + ? e1000_1000t_rx_status_ok + : e1000_1000t_rx_status_not_ok; phy->remote_rx = (data & SR_1000T_REMOTE_RX_STATUS) - ? e1000_1000t_rx_status_ok - : e1000_1000t_rx_status_not_ok; + ? e1000_1000t_rx_status_ok + : e1000_1000t_rx_status_not_ok; } else { phy->cable_length = E1000_CABLE_LENGTH_UNDEFINED; phy->local_rx = e1000_1000t_rx_status_undefined; phy->remote_rx = e1000_1000t_rx_status_undefined; } -out: return ret_val; } @@ -2546,44 +2771,41 @@ s32 e1000_get_phy_info_ife(struct e1000_hw *hw) ret_val = e1000_phy_has_link_generic(hw, 1, 0, &link); if (ret_val) - goto out; + return ret_val; if (!link) { DEBUGOUT("Phy info is only valid if link is up\n"); - ret_val = -E1000_ERR_CONFIG; - goto out; + return -E1000_ERR_CONFIG; } ret_val = phy->ops.read_reg(hw, IFE_PHY_SPECIAL_CONTROL, &data); if (ret_val) - goto out; - phy->polarity_correction = (data & IFE_PSC_AUTO_POLARITY_DISABLE) - ? FALSE : TRUE; + return ret_val; + phy->polarity_correction = !(data & IFE_PSC_AUTO_POLARITY_DISABLE); if (phy->polarity_correction) { ret_val = e1000_check_polarity_ife(hw); if (ret_val) - goto out; + return ret_val; } else { /* Polarity is forced */ phy->cable_polarity = (data & IFE_PSC_FORCE_POLARITY) - ? e1000_rev_polarity_reversed - : e1000_rev_polarity_normal; + ? e1000_rev_polarity_reversed + : e1000_rev_polarity_normal; } ret_val = phy->ops.read_reg(hw, IFE_PHY_MDIX_CONTROL, &data); if (ret_val) - goto out; + return ret_val; - phy->is_mdix = (data & IFE_PMC_MDIX_STATUS) ? TRUE : FALSE; + phy->is_mdix = !!(data & IFE_PMC_MDIX_STATUS); /* The following parameters are undefined for 10/100 operation. */ phy->cable_length = E1000_CABLE_LENGTH_UNDEFINED; phy->local_rx = e1000_1000t_rx_status_undefined; phy->remote_rx = e1000_1000t_rx_status_undefined; -out: - return ret_val; + return E1000_SUCCESS; } /** @@ -2595,26 +2817,25 @@ s32 e1000_get_phy_info_ife(struct e1000_hw *hw) **/ s32 e1000_phy_sw_reset_generic(struct e1000_hw *hw) { - s32 ret_val = E1000_SUCCESS; + s32 ret_val; u16 phy_ctrl; DEBUGFUNC("e1000_phy_sw_reset_generic"); - if (!(hw->phy.ops.read_reg)) - goto out; + if (!hw->phy.ops.read_reg) + return E1000_SUCCESS; ret_val = hw->phy.ops.read_reg(hw, PHY_CONTROL, &phy_ctrl); if (ret_val) - goto out; + return ret_val; phy_ctrl |= MII_CR_RESET; ret_val = hw->phy.ops.write_reg(hw, PHY_CONTROL, phy_ctrl); if (ret_val) - goto out; + return ret_val; usec_delay(1); -out: return ret_val; } @@ -2630,20 +2851,20 @@ s32 e1000_phy_sw_reset_generic(struct e1000_hw *hw) s32 e1000_phy_hw_reset_generic(struct e1000_hw *hw) { struct e1000_phy_info *phy = &hw->phy; - s32 ret_val = E1000_SUCCESS; + s32 ret_val; u32 ctrl; DEBUGFUNC("e1000_phy_hw_reset_generic"); - ret_val = phy->ops.check_reset_block(hw); - if (ret_val) { - ret_val = E1000_SUCCESS; - goto out; + if (phy->ops.check_reset_block) { + ret_val = phy->ops.check_reset_block(hw); + if (ret_val) + return E1000_SUCCESS; } ret_val = phy->ops.acquire(hw); if (ret_val) - goto out; + return ret_val; ctrl = E1000_READ_REG(hw, E1000_CTRL); E1000_WRITE_REG(hw, E1000_CTRL, ctrl | E1000_CTRL_PHY_RST); @@ -2658,10 +2879,7 @@ s32 e1000_phy_hw_reset_generic(struct e1000_hw *hw) phy->ops.release(hw); - ret_val = phy->ops.get_cfg_done(hw); - -out: - return ret_val; + return phy->ops.get_cfg_done(hw); } /** @@ -2815,6 +3033,9 @@ enum e1000_phy_type e1000_get_phy_type_from_id(u32 phy_id) case I82580_I_PHY_ID: phy_type = e1000_phy_82580; break; + case I210_I_PHY_ID: + phy_type = e1000_phy_i210; + break; default: phy_type = e1000_phy_unknown; break; @@ -2832,7 +3053,6 @@ enum e1000_phy_type e1000_get_phy_type_from_id(u32 phy_id) **/ s32 e1000_determine_phy_address(struct e1000_hw *hw) { - s32 ret_val = -E1000_ERR_PHY_TYPE; u32 phy_addr = 0; u32 i; enum e1000_phy_type phy_type = e1000_phy_unknown; @@ -2851,17 +3071,15 @@ s32 e1000_determine_phy_address(struct e1000_hw *hw) * If phy_type is valid, break - we found our * PHY address */ - if (phy_type != e1000_phy_unknown) { - ret_val = E1000_SUCCESS; - goto out; - } + if (phy_type != e1000_phy_unknown) + return E1000_SUCCESS; + msec_delay(1); i++; } while (i < 10); } -out: - return ret_val; + return -E1000_ERR_PHY_TYPE; } /** @@ -2903,8 +3121,8 @@ s32 e1000_write_phy_reg_bm(struct e1000_hw *hw, u32 offset, u16 data) /* Page 800 works differently than the rest so it has its own func */ if (page == BM_WUC_PAGE) { ret_val = e1000_access_phy_wakeup_reg_bm(hw, offset, &data, - FALSE); - goto out; + FALSE, FALSE); + goto release; } hw->phy.addr = e1000_get_phy_addr_for_bm_page(page, offset); @@ -2927,15 +3145,15 @@ s32 e1000_write_phy_reg_bm(struct e1000_hw *hw, u32 offset, u16 data) /* Page is shifted left, PHY expects (page x 32) */ ret_val = e1000_write_phy_reg_mdic(hw, page_select, - (page << page_shift)); + (page << page_shift)); if (ret_val) - goto out; + goto release; } ret_val = e1000_write_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset, - data); + data); -out: +release: hw->phy.ops.release(hw); return ret_val; } @@ -2964,8 +3182,8 @@ s32 e1000_read_phy_reg_bm(struct e1000_hw *hw, u32 offset, u16 *data) /* Page 800 works differently than the rest so it has its own func */ if (page == BM_WUC_PAGE) { ret_val = e1000_access_phy_wakeup_reg_bm(hw, offset, data, - TRUE); - goto out; + TRUE, FALSE); + goto release; } hw->phy.addr = e1000_get_phy_addr_for_bm_page(page, offset); @@ -2988,14 +3206,14 @@ s32 e1000_read_phy_reg_bm(struct e1000_hw *hw, u32 offset, u16 *data) /* Page is shifted left, PHY expects (page x 32) */ ret_val = e1000_write_phy_reg_mdic(hw, page_select, - (page << page_shift)); + (page << page_shift)); if (ret_val) - goto out; + goto release; } ret_val = e1000_read_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset, - data); -out: + data); +release: hw->phy.ops.release(hw); return ret_val; } @@ -3015,7 +3233,7 @@ s32 e1000_read_phy_reg_bm2(struct e1000_hw *hw, u32 offset, u16 *data) s32 ret_val; u16 page = (u16)(offset >> IGP_PAGE_SHIFT); - DEBUGFUNC("e1000_write_phy_reg_bm2"); + DEBUGFUNC("e1000_read_phy_reg_bm2"); ret_val = hw->phy.ops.acquire(hw); if (ret_val) @@ -3024,8 +3242,8 @@ s32 e1000_read_phy_reg_bm2(struct e1000_hw *hw, u32 offset, u16 *data) /* Page 800 works differently than the rest so it has its own func */ if (page == BM_WUC_PAGE) { ret_val = e1000_access_phy_wakeup_reg_bm(hw, offset, data, - TRUE); - goto out; + TRUE, FALSE); + goto release; } hw->phy.addr = 1; @@ -3034,15 +3252,15 @@ s32 e1000_read_phy_reg_bm2(struct e1000_hw *hw, u32 offset, u16 *data) /* Page is shifted left, PHY expects (page x 32) */ ret_val = e1000_write_phy_reg_mdic(hw, BM_PHY_PAGE_SELECT, - page); + page); if (ret_val) - goto out; + goto release; } ret_val = e1000_read_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset, - data); -out: + data); +release: hw->phy.ops.release(hw); return ret_val; } @@ -3070,8 +3288,8 @@ s32 e1000_write_phy_reg_bm2(struct e1000_hw *hw, u32 offset, u16 data) /* Page 800 works differently than the rest so it has its own func */ if (page == BM_WUC_PAGE) { ret_val = e1000_access_phy_wakeup_reg_bm(hw, offset, &data, - FALSE); - goto out; + FALSE, FALSE); + goto release; } hw->phy.addr = 1; @@ -3079,41 +3297,140 @@ s32 e1000_write_phy_reg_bm2(struct e1000_hw *hw, u32 offset, u16 data) if (offset > MAX_PHY_MULTI_PAGE_REG) { /* Page is shifted left, PHY expects (page x 32) */ ret_val = e1000_write_phy_reg_mdic(hw, BM_PHY_PAGE_SELECT, - page); + page); if (ret_val) - goto out; + goto release; } ret_val = e1000_write_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset, - data); + data); -out: +release: hw->phy.ops.release(hw); return ret_val; } /** - * e1000_access_phy_wakeup_reg_bm - Read BM PHY wakeup register + * e1000_enable_phy_wakeup_reg_access_bm - enable access to BM wakeup registers + * @hw: pointer to the HW structure + * @phy_reg: pointer to store original contents of BM_WUC_ENABLE_REG + * + * Assumes semaphore already acquired and phy_reg points to a valid memory + * address to store contents of the BM_WUC_ENABLE_REG register. + **/ +s32 e1000_enable_phy_wakeup_reg_access_bm(struct e1000_hw *hw, u16 *phy_reg) +{ + s32 ret_val; + u16 temp; + + DEBUGFUNC("e1000_enable_phy_wakeup_reg_access_bm"); + + if (!phy_reg) + return -E1000_ERR_PARAM; + + /* All page select, port ctrl and wakeup registers use phy address 1 */ + hw->phy.addr = 1; + + /* Select Port Control Registers page */ + ret_val = e1000_set_page_igp(hw, (BM_PORT_CTRL_PAGE << IGP_PAGE_SHIFT)); + if (ret_val) { + DEBUGOUT("Could not set Port Control page\n"); + return ret_val; + } + + ret_val = e1000_read_phy_reg_mdic(hw, BM_WUC_ENABLE_REG, phy_reg); + if (ret_val) { + DEBUGOUT2("Could not read PHY register %d.%d\n", + BM_PORT_CTRL_PAGE, BM_WUC_ENABLE_REG); + return ret_val; + } + + /* + * Enable both PHY wakeup mode and Wakeup register page writes. + * Prevent a power state change by disabling ME and Host PHY wakeup. + */ + temp = *phy_reg; + temp |= BM_WUC_ENABLE_BIT; + temp &= ~(BM_WUC_ME_WU_BIT | BM_WUC_HOST_WU_BIT); + + ret_val = e1000_write_phy_reg_mdic(hw, BM_WUC_ENABLE_REG, temp); + if (ret_val) { + DEBUGOUT2("Could not write PHY register %d.%d\n", + BM_PORT_CTRL_PAGE, BM_WUC_ENABLE_REG); + return ret_val; + } + + /* + * Select Host Wakeup Registers page - caller now able to write + * registers on the Wakeup registers page + */ + return e1000_set_page_igp(hw, (BM_WUC_PAGE << IGP_PAGE_SHIFT)); +} + +/** + * e1000_disable_phy_wakeup_reg_access_bm - disable access to BM wakeup regs + * @hw: pointer to the HW structure + * @phy_reg: pointer to original contents of BM_WUC_ENABLE_REG + * + * Restore BM_WUC_ENABLE_REG to its original value. + * + * Assumes semaphore already acquired and *phy_reg is the contents of the + * BM_WUC_ENABLE_REG before register(s) on BM_WUC_PAGE were accessed by + * caller. + **/ +s32 e1000_disable_phy_wakeup_reg_access_bm(struct e1000_hw *hw, u16 *phy_reg) +{ + s32 ret_val = E1000_SUCCESS; + + DEBUGFUNC("e1000_disable_phy_wakeup_reg_access_bm"); + + if (!phy_reg) + return -E1000_ERR_PARAM; + + /* Select Port Control Registers page */ + ret_val = e1000_set_page_igp(hw, (BM_PORT_CTRL_PAGE << IGP_PAGE_SHIFT)); + if (ret_val) { + DEBUGOUT("Could not set Port Control page\n"); + return ret_val; + } + + /* Restore 769.17 to its original value */ + ret_val = e1000_write_phy_reg_mdic(hw, BM_WUC_ENABLE_REG, *phy_reg); + if (ret_val) + DEBUGOUT2("Could not restore PHY register %d.%d\n", + BM_PORT_CTRL_PAGE, BM_WUC_ENABLE_REG); + + return ret_val; +} + +/** + * e1000_access_phy_wakeup_reg_bm - Read/write BM PHY wakeup register * @hw: pointer to the HW structure * @offset: register offset to be read or written * @data: pointer to the data to read or write * @read: determines if operation is read or write + * @page_set: BM_WUC_PAGE already set and access enabled * - * Acquires semaphore, if necessary, then reads the PHY register at offset - * and storing the retrieved information in data. Release any acquired - * semaphores before exiting. Note that procedure to read the wakeup - * registers are different. It works as such: - * 1) Set page 769, register 17, bit 2 = 1 + * Read the PHY register at offset and store the retrieved information in + * data, or write data to PHY register at offset. Note the procedure to + * access the PHY wakeup registers is different than reading the other PHY + * registers. It works as such: + * 1) Set 769.17.2 (page 769, register 17, bit 2) = 1 * 2) Set page to 800 for host (801 if we were manageability) * 3) Write the address using the address opcode (0x11) * 4) Read or write the data using the data opcode (0x12) - * 5) Restore 769_17.2 to its original value + * 5) Restore 769.17.2 to its original value * - * Assumes semaphore already acquired. + * Steps 1 and 2 are done by e1000_enable_phy_wakeup_reg_access_bm() and + * step 5 is done by e1000_disable_phy_wakeup_reg_access_bm(). + * + * Assumes semaphore is already acquired. When page_set==TRUE, assumes + * the PHY page is set to BM_WUC_PAGE (i.e. a function in the call stack + * is responsible for calls to e1000_[enable|disable]_phy_wakeup_reg_bm()). **/ static s32 e1000_access_phy_wakeup_reg_bm(struct e1000_hw *hw, u32 offset, - u16 *data, bool read) + u16 *data, bool read, bool page_set) { s32 ret_val; u16 reg = BM_PHY_REG_NUM(offset); @@ -3121,81 +3438,48 @@ static s32 e1000_access_phy_wakeup_reg_bm(struct e1000_hw *hw, u32 offset, DEBUGFUNC("e1000_access_phy_wakeup_reg_bm"); - /* Gig must be disabled for MDIO accesses to page 800 */ + /* Gig must be disabled for MDIO accesses to Host Wakeup reg page */ if ((hw->mac.type == e1000_pchlan) && (!(E1000_READ_REG(hw, E1000_PHY_CTRL) & E1000_PHY_CTRL_GBE_DISABLE))) - DEBUGOUT("Attempting to access page 800 while gig enabled.\n"); - - /* All operations in this function are phy address 1 */ - hw->phy.addr = 1; - - /* Set page 769 */ - e1000_write_phy_reg_mdic(hw, IGP01E1000_PHY_PAGE_SELECT, - (BM_WUC_ENABLE_PAGE << IGP_PAGE_SHIFT)); - - ret_val = e1000_read_phy_reg_mdic(hw, BM_WUC_ENABLE_REG, &phy_reg); - if (ret_val) { - DEBUGOUT("Could not read PHY page 769\n"); - goto out; - } - - /* First clear bit 4 to avoid a power state change */ - phy_reg &= ~(BM_WUC_HOST_WU_BIT); - ret_val = e1000_write_phy_reg_mdic(hw, BM_WUC_ENABLE_REG, phy_reg); - if (ret_val) { - DEBUGOUT("Could not clear PHY page 769 bit 4\n"); - goto out; - } + DEBUGOUT1("Attempting to access page %d while gig enabled.\n", + page); - /* Write bit 2 = 1, and clear bit 4 to 769_17 */ - ret_val = e1000_write_phy_reg_mdic(hw, BM_WUC_ENABLE_REG, - phy_reg | BM_WUC_ENABLE_BIT); - if (ret_val) { - DEBUGOUT("Could not write PHY page 769 bit 2\n"); - goto out; + if (!page_set) { + /* Enable access to PHY wakeup registers */ + ret_val = e1000_enable_phy_wakeup_reg_access_bm(hw, &phy_reg); + if (ret_val) { + DEBUGOUT("Could not enable PHY wakeup reg access\n"); + return ret_val; + } } - /* Select page 800 */ - ret_val = e1000_write_phy_reg_mdic(hw, IGP01E1000_PHY_PAGE_SELECT, - (BM_WUC_PAGE << IGP_PAGE_SHIFT)); + DEBUGOUT2("Accessing PHY page %d reg 0x%x\n", page, reg); - /* Write the page 800 offset value using opcode 0x11 */ + /* Write the Wakeup register page offset value using opcode 0x11 */ ret_val = e1000_write_phy_reg_mdic(hw, BM_WUC_ADDRESS_OPCODE, reg); if (ret_val) { - DEBUGOUT("Could not write address opcode to page 800\n"); - goto out; + DEBUGOUT1("Could not write address opcode to page %d\n", page); + return ret_val; } if (read) { - /* Read the page 800 value using opcode 0x12 */ + /* Read the Wakeup register page value using opcode 0x12 */ ret_val = e1000_read_phy_reg_mdic(hw, BM_WUC_DATA_OPCODE, - data); + data); } else { - /* Write the page 800 value using opcode 0x12 */ + /* Write the Wakeup register page value using opcode 0x12 */ ret_val = e1000_write_phy_reg_mdic(hw, BM_WUC_DATA_OPCODE, - *data); + *data); } if (ret_val) { - DEBUGOUT("Could not access data value from page 800\n"); - goto out; + DEBUGOUT2("Could not access PHY reg %d.%d\n", page, reg); + return ret_val; } - /* - * Restore 769_17.2 to its original value - * Set page 769 - */ - e1000_write_phy_reg_mdic(hw, IGP01E1000_PHY_PAGE_SELECT, - (BM_WUC_ENABLE_PAGE << IGP_PAGE_SHIFT)); - - /* Clear 769_17.2 */ - ret_val = e1000_write_phy_reg_mdic(hw, BM_WUC_ENABLE_REG, phy_reg); - if (ret_val) { - DEBUGOUT("Could not clear PHY page 769 bit 2\n"); - goto out; - } + if (!page_set) + ret_val = e1000_disable_phy_wakeup_reg_access_bm(hw, &phy_reg); -out: return ret_val; } @@ -3210,10 +3494,16 @@ static s32 e1000_access_phy_wakeup_reg_bm(struct e1000_hw *hw, u32 offset, void e1000_power_up_phy_copper(struct e1000_hw *hw) { u16 mii_reg = 0; + u16 power_reg = 0; /* The PHY will retain its settings across a power down/up cycle */ hw->phy.ops.read_reg(hw, PHY_CONTROL, &mii_reg); mii_reg &= ~MII_CR_POWER_DOWN; + if (hw->phy.type == e1000_phy_i210) { + hw->phy.ops.read_reg(hw, GS40G_COPPER_SPEC, &power_reg); + power_reg &= ~GS40G_CS_POWER_DOWN; + hw->phy.ops.write_reg(hw, GS40G_COPPER_SPEC, power_reg); + } hw->phy.ops.write_reg(hw, PHY_CONTROL, mii_reg); } @@ -3228,10 +3518,17 @@ void e1000_power_up_phy_copper(struct e1000_hw *hw) void e1000_power_down_phy_copper(struct e1000_hw *hw) { u16 mii_reg = 0; + u16 power_reg = 0; /* The PHY will retain its settings across a power down/up cycle */ hw->phy.ops.read_reg(hw, PHY_CONTROL, &mii_reg); mii_reg |= MII_CR_POWER_DOWN; + /* i210 Phy requires an additional bit for power up/down */ + if (hw->phy.type == e1000_phy_i210) { + hw->phy.ops.read_reg(hw, GS40G_COPPER_SPEC, &power_reg); + power_reg |= GS40G_CS_POWER_DOWN; + hw->phy.ops.write_reg(hw, GS40G_COPPER_SPEC, power_reg); + } hw->phy.ops.write_reg(hw, PHY_CONTROL, mii_reg); msec_delay(1); } @@ -3248,11 +3545,12 @@ void e1000_power_down_phy_copper(struct e1000_hw *hw) * semaphore before exiting. **/ static s32 __e1000_read_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 *data, - bool locked) + bool locked, bool page_set) { s32 ret_val; u16 page = BM_PHY_REG_PAGE(offset); u16 reg = BM_PHY_REG_NUM(offset); + u32 phy_addr = hw->phy.addr = e1000_get_phy_addr_for_hv_page(page); DEBUGFUNC("__e1000_read_phy_reg_hv"); @@ -3264,39 +3562,38 @@ static s32 __e1000_read_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 *data, /* Page 800 works differently than the rest so it has its own func */ if (page == BM_WUC_PAGE) { - ret_val = e1000_access_phy_wakeup_reg_bm(hw, offset, - data, TRUE); + ret_val = e1000_access_phy_wakeup_reg_bm(hw, offset, data, + TRUE, page_set); goto out; } if (page > 0 && page < HV_INTC_FC_PAGE_START) { ret_val = e1000_access_phy_debug_regs_hv(hw, offset, - data, TRUE); + data, TRUE); goto out; } - hw->phy.addr = e1000_get_phy_addr_for_hv_page(page); - - if (page == HV_INTC_FC_PAGE_START) - page = 0; + if (!page_set) { + if (page == HV_INTC_FC_PAGE_START) + page = 0; - if (reg > MAX_PHY_MULTI_PAGE_REG) { - u32 phy_addr = hw->phy.addr; + if (reg > MAX_PHY_MULTI_PAGE_REG) { + /* Page is shifted left, PHY expects (page x 32) */ + ret_val = e1000_set_page_igp(hw, + (page << IGP_PAGE_SHIFT)); - hw->phy.addr = 1; - - /* Page is shifted left, PHY expects (page x 32) */ - ret_val = e1000_write_phy_reg_mdic(hw, - IGP01E1000_PHY_PAGE_SELECT, - (page << IGP_PAGE_SHIFT)); - hw->phy.addr = phy_addr; + hw->phy.addr = phy_addr; - if (ret_val) - goto out; + if (ret_val) + goto out; + } } + DEBUGOUT3("reading PHY page %d (or 0x%x shifted) reg 0x%x\n", page, + page << IGP_PAGE_SHIFT, reg); + ret_val = e1000_read_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & reg, - data); + data); out: if (!locked) hw->phy.ops.release(hw); @@ -3316,7 +3613,7 @@ static s32 __e1000_read_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 *data, **/ s32 e1000_read_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 *data) { - return __e1000_read_phy_reg_hv(hw, offset, data, FALSE); + return __e1000_read_phy_reg_hv(hw, offset, data, FALSE, FALSE); } /** @@ -3330,7 +3627,21 @@ 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) { - return __e1000_read_phy_reg_hv(hw, offset, data, TRUE); + return __e1000_read_phy_reg_hv(hw, offset, data, TRUE, FALSE); +} + +/** + * e1000_read_phy_reg_page_hv - Read HV PHY register + * @hw: pointer to the HW structure + * @offset: register offset to write to + * @data: data to write at register offset + * + * Reads the PHY register at offset and stores the retrieved information + * in data. Assumes semaphore already acquired and page already set. + **/ +s32 e1000_read_phy_reg_page_hv(struct e1000_hw *hw, u32 offset, u16 *data) +{ + return __e1000_read_phy_reg_hv(hw, offset, data, TRUE, true); } /** @@ -3344,11 +3655,12 @@ s32 e1000_read_phy_reg_hv_locked(struct e1000_hw *hw, u32 offset, u16 *data) * at the offset. Release any acquired semaphores before exiting. **/ static s32 __e1000_write_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 data, - bool locked) + bool locked, bool page_set) { s32 ret_val; u16 page = BM_PHY_REG_PAGE(offset); u16 reg = BM_PHY_REG_NUM(offset); + u32 phy_addr = hw->phy.addr = e1000_get_phy_addr_for_hv_page(page); DEBUGFUNC("__e1000_write_phy_reg_hv"); @@ -3360,55 +3672,55 @@ static s32 __e1000_write_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 data, /* Page 800 works differently than the rest so it has its own func */ if (page == BM_WUC_PAGE) { - ret_val = e1000_access_phy_wakeup_reg_bm(hw, offset, - &data, FALSE); + ret_val = e1000_access_phy_wakeup_reg_bm(hw, offset, &data, + FALSE, page_set); goto out; } if (page > 0 && page < HV_INTC_FC_PAGE_START) { ret_val = e1000_access_phy_debug_regs_hv(hw, offset, - &data, FALSE); + &data, FALSE); goto out; } - hw->phy.addr = e1000_get_phy_addr_for_hv_page(page); - - if (page == HV_INTC_FC_PAGE_START) - page = 0; - - /* - * Workaround MDIO accesses being disabled after entering IEEE Power - * Down (whenever bit 11 of the PHY Control register is set) - */ - if ((hw->phy.type == e1000_phy_82578) && - (hw->phy.revision >= 1) && - (hw->phy.addr == 2) && - ((MAX_PHY_REG_ADDRESS & reg) == 0) && - (data & (1 << 11))) { - u16 data2 = 0x7EFF; - ret_val = e1000_access_phy_debug_regs_hv(hw, (1 << 6) | 0x3, - &data2, FALSE); - if (ret_val) - goto out; - } + if (!page_set) { + if (page == HV_INTC_FC_PAGE_START) + page = 0; - if (reg > MAX_PHY_MULTI_PAGE_REG) { - u32 phy_addr = hw->phy.addr; + /* + * Workaround MDIO accesses being disabled after entering IEEE + * Power Down (when bit 11 of the PHY Control register is set) + */ + if ((hw->phy.type == e1000_phy_82578) && + (hw->phy.revision >= 1) && + (hw->phy.addr == 2) && + !(MAX_PHY_REG_ADDRESS & reg) && + (data & (1 << 11))) { + u16 data2 = 0x7EFF; + ret_val = e1000_access_phy_debug_regs_hv(hw, + (1 << 6) | 0x3, + &data2, FALSE); + if (ret_val) + goto out; + } - hw->phy.addr = 1; + if (reg > MAX_PHY_MULTI_PAGE_REG) { + /* Page is shifted left, PHY expects (page x 32) */ + ret_val = e1000_set_page_igp(hw, + (page << IGP_PAGE_SHIFT)); - /* Page is shifted left, PHY expects (page x 32) */ - ret_val = e1000_write_phy_reg_mdic(hw, - IGP01E1000_PHY_PAGE_SELECT, - (page << IGP_PAGE_SHIFT)); - hw->phy.addr = phy_addr; + hw->phy.addr = phy_addr; - if (ret_val) - goto out; + if (ret_val) + goto out; + } } + DEBUGOUT3("writing PHY page %d (or 0x%x shifted) reg 0x%x\n", page, + page << IGP_PAGE_SHIFT, reg); + ret_val = e1000_write_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & reg, - data); + data); out: if (!locked) @@ -3428,7 +3740,7 @@ static s32 __e1000_write_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 data, **/ s32 e1000_write_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 data) { - return __e1000_write_phy_reg_hv(hw, offset, data, FALSE); + return __e1000_write_phy_reg_hv(hw, offset, data, FALSE, FALSE); } /** @@ -3442,7 +3754,21 @@ 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) { - return __e1000_write_phy_reg_hv(hw, offset, data, TRUE); + return __e1000_write_phy_reg_hv(hw, offset, data, TRUE, FALSE); +} + +/** + * e1000_write_phy_reg_page_hv - Write HV PHY register + * @hw: pointer to the HW structure + * @offset: register offset to write to + * @data: data to write at register offset + * + * Writes the data to PHY register at the offset. Assumes semaphore + * already acquired and page already set. + **/ +s32 e1000_write_phy_reg_page_hv(struct e1000_hw *hw, u32 offset, u16 data) +{ + return __e1000_write_phy_reg_hv(hw, offset, data, TRUE, true); } /** @@ -3464,14 +3790,15 @@ static u32 e1000_get_phy_addr_for_hv_page(u32 page) * @hw: pointer to the HW structure * @offset: register offset to be read or written * @data: pointer to the data to be read or written - * @read: determines if operation is read or written + * @read: determines if operation is read or write * * Reads the PHY register at offset and stores the retreived information * in data. Assumes semaphore already acquired. Note that the procedure - * to read these regs uses the address port and data port to read/write. + * to access these regs uses the address port and data port to read/write. + * These accesses done with PHY address 2 and without using pages. **/ static s32 e1000_access_phy_debug_regs_hv(struct e1000_hw *hw, u32 offset, - u16 *data, bool read) + u16 *data, bool read) { s32 ret_val; u32 addr_reg = 0; @@ -3481,7 +3808,7 @@ static s32 e1000_access_phy_debug_regs_hv(struct e1000_hw *hw, u32 offset, /* This takes care of the difference with desktop vs mobile phy */ addr_reg = (hw->phy.type == e1000_phy_82578) ? - I82578_ADDR_REG : I82577_ADDR_REG; + I82578_ADDR_REG : I82577_ADDR_REG; data_reg = addr_reg + 1; /* All operations in this function are phy address 2 */ @@ -3490,8 +3817,8 @@ static s32 e1000_access_phy_debug_regs_hv(struct e1000_hw *hw, u32 offset, /* masking with 0x3F to remove the page from offset */ ret_val = e1000_write_phy_reg_mdic(hw, addr_reg, (u16)offset & 0x3F); if (ret_val) { - DEBUGOUT("Could not write PHY the HV address register\n"); - goto out; + DEBUGOUT("Could not write the Address Offset port register\n"); + return ret_val; } /* Read or write the data value next */ @@ -3500,12 +3827,9 @@ static s32 e1000_access_phy_debug_regs_hv(struct e1000_hw *hw, u32 offset, else ret_val = e1000_write_phy_reg_mdic(hw, data_reg, *data); - if (ret_val) { - DEBUGOUT("Could not read data value from HV data register\n"); - goto out; - } + if (ret_val) + DEBUGOUT("Could not access the Data port register\n"); -out: return ret_val; } @@ -3528,41 +3852,36 @@ s32 e1000_link_stall_workaround_hv(struct e1000_hw *hw) DEBUGFUNC("e1000_link_stall_workaround_hv"); if (hw->phy.type != e1000_phy_82578) - goto out; + return E1000_SUCCESS; /* Do not apply workaround if in PHY loopback bit 14 set */ hw->phy.ops.read_reg(hw, PHY_CONTROL, &data); if (data & PHY_CONTROL_LB) - goto out; + return E1000_SUCCESS; /* check if link is up and at 1Gbps */ ret_val = hw->phy.ops.read_reg(hw, BM_CS_STATUS, &data); if (ret_val) - goto out; + return ret_val; - data &= BM_CS_STATUS_LINK_UP | - BM_CS_STATUS_RESOLVED | - BM_CS_STATUS_SPEED_MASK; + data &= BM_CS_STATUS_LINK_UP | BM_CS_STATUS_RESOLVED | + BM_CS_STATUS_SPEED_MASK; - if (data != (BM_CS_STATUS_LINK_UP | - BM_CS_STATUS_RESOLVED | - BM_CS_STATUS_SPEED_1000)) - goto out; + if (data != (BM_CS_STATUS_LINK_UP | BM_CS_STATUS_RESOLVED | + BM_CS_STATUS_SPEED_1000)) + return E1000_SUCCESS; msec_delay(200); /* flush the packets in the fifo buffer */ ret_val = hw->phy.ops.write_reg(hw, HV_MUX_DATA_CTRL, - HV_MUX_DATA_CTRL_GEN_TO_MAC | - HV_MUX_DATA_CTRL_FORCE_SPEED); + HV_MUX_DATA_CTRL_GEN_TO_MAC | + HV_MUX_DATA_CTRL_FORCE_SPEED); if (ret_val) - goto out; - - ret_val = hw->phy.ops.write_reg(hw, HV_MUX_DATA_CTRL, - HV_MUX_DATA_CTRL_GEN_TO_MAC); + return ret_val; -out: - return ret_val; + return hw->phy.ops.write_reg(hw, HV_MUX_DATA_CTRL, + HV_MUX_DATA_CTRL_GEN_TO_MAC); } /** @@ -3585,8 +3904,8 @@ s32 e1000_check_polarity_82577(struct e1000_hw *hw) if (!ret_val) phy->cable_polarity = (data & I82577_PHY_STATUS2_REV_POLARITY) - ? e1000_rev_polarity_reversed - : e1000_rev_polarity_normal; + ? e1000_rev_polarity_reversed + : e1000_rev_polarity_normal; return ret_val; } @@ -3608,39 +3927,32 @@ s32 e1000_phy_force_speed_duplex_82577(struct e1000_hw *hw) ret_val = phy->ops.read_reg(hw, PHY_CONTROL, &phy_data); if (ret_val) - goto out; + return ret_val; e1000_phy_force_speed_duplex_setup(hw, &phy_data); ret_val = phy->ops.write_reg(hw, PHY_CONTROL, phy_data); if (ret_val) - goto out; + return ret_val; usec_delay(1); if (phy->autoneg_wait_to_complete) { DEBUGOUT("Waiting for forced speed/duplex link on 82577 phy\n"); - ret_val = e1000_phy_has_link_generic(hw, - PHY_FORCE_LIMIT, - 100000, - &link); + ret_val = e1000_phy_has_link_generic(hw, PHY_FORCE_LIMIT, + 100000, &link); if (ret_val) - goto out; + return ret_val; if (!link) DEBUGOUT("Link taking longer than expected.\n"); /* Try once more */ - ret_val = e1000_phy_has_link_generic(hw, - PHY_FORCE_LIMIT, - 100000, - &link); - if (ret_val) - goto out; + ret_val = e1000_phy_has_link_generic(hw, PHY_FORCE_LIMIT, + 100000, &link); } -out: return ret_val; } @@ -3664,51 +3976,49 @@ s32 e1000_get_phy_info_82577(struct e1000_hw *hw) ret_val = e1000_phy_has_link_generic(hw, 1, 0, &link); if (ret_val) - goto out; + return ret_val; if (!link) { DEBUGOUT("Phy info is only valid if link is up\n"); - ret_val = -E1000_ERR_CONFIG; - goto out; + return -E1000_ERR_CONFIG; } phy->polarity_correction = TRUE; ret_val = e1000_check_polarity_82577(hw); if (ret_val) - goto out; + return ret_val; ret_val = phy->ops.read_reg(hw, I82577_PHY_STATUS_2, &data); if (ret_val) - goto out; + return ret_val; - phy->is_mdix = (data & I82577_PHY_STATUS2_MDIX) ? TRUE : FALSE; + phy->is_mdix = !!(data & I82577_PHY_STATUS2_MDIX); if ((data & I82577_PHY_STATUS2_SPEED_MASK) == I82577_PHY_STATUS2_SPEED_1000MBPS) { ret_val = hw->phy.ops.get_cable_length(hw); if (ret_val) - goto out; + return ret_val; ret_val = phy->ops.read_reg(hw, PHY_1000T_STATUS, &data); if (ret_val) - goto out; + return ret_val; phy->local_rx = (data & SR_1000T_LOCAL_RX_STATUS) - ? e1000_1000t_rx_status_ok - : e1000_1000t_rx_status_not_ok; + ? e1000_1000t_rx_status_ok + : e1000_1000t_rx_status_not_ok; phy->remote_rx = (data & SR_1000T_REMOTE_RX_STATUS) - ? e1000_1000t_rx_status_ok - : e1000_1000t_rx_status_not_ok; + ? e1000_1000t_rx_status_ok + : e1000_1000t_rx_status_not_ok; } else { phy->cable_length = E1000_CABLE_LENGTH_UNDEFINED; phy->local_rx = e1000_1000t_rx_status_undefined; phy->remote_rx = e1000_1000t_rx_status_undefined; } -out: - return ret_val; + return E1000_SUCCESS; } /** @@ -3728,16 +4038,78 @@ s32 e1000_get_cable_length_82577(struct e1000_hw *hw) ret_val = phy->ops.read_reg(hw, I82577_PHY_DIAG_STATUS, &phy_data); if (ret_val) - goto out; + return ret_val; length = (phy_data & I82577_DSTATUS_CABLE_LENGTH) >> - I82577_DSTATUS_CABLE_LENGTH_SHIFT; + I82577_DSTATUS_CABLE_LENGTH_SHIFT; if (length == E1000_CABLE_LENGTH_UNDEFINED) ret_val = -E1000_ERR_PHY; phy->cable_length = length; -out: + return E1000_SUCCESS; +} + +/** + * e1000_write_phy_reg_gs40g - Write GS40G PHY register + * @hw: pointer to the HW structure + * @offset: register offset to write to + * @data: data to write at register offset + * + * Acquires semaphore, if necessary, then writes the data to PHY register + * at the offset. Release any acquired semaphores before exiting. + **/ +s32 e1000_write_phy_reg_gs40g(struct e1000_hw *hw, u32 offset, u16 data) +{ + s32 ret_val; + u16 page = offset >> GS40G_PAGE_SHIFT; + + DEBUGFUNC("e1000_write_phy_reg_gs40g"); + + offset = offset & GS40G_OFFSET_MASK; + ret_val = hw->phy.ops.acquire(hw); + if (ret_val) + return ret_val; + + ret_val = e1000_write_phy_reg_mdic(hw, GS40G_PAGE_SELECT, page); + if (ret_val) + goto release; + ret_val = e1000_write_phy_reg_mdic(hw, offset, data); + +release: + hw->phy.ops.release(hw); + return ret_val; +} + +/** + * e1000_read_phy_reg_gs40g - Read GS40G PHY register + * @hw: pointer to the HW structure + * @offset: lower half is register offset to read to + * upper half is page to use. + * @data: data to read at register offset + * + * Acquires semaphore, if necessary, then reads the data in the PHY register + * at the offset. Release any acquired semaphores before exiting. + **/ +s32 e1000_read_phy_reg_gs40g(struct e1000_hw *hw, u32 offset, u16 *data) +{ + s32 ret_val; + u16 page = offset >> GS40G_PAGE_SHIFT; + + DEBUGFUNC("e1000_read_phy_reg_gs40g"); + + offset = offset & GS40G_OFFSET_MASK; + ret_val = hw->phy.ops.acquire(hw); + if (ret_val) + return ret_val; + + ret_val = e1000_write_phy_reg_mdic(hw, GS40G_PAGE_SELECT, page); + if (ret_val) + goto release; + ret_val = e1000_read_phy_reg_mdic(hw, offset, data); + +release: + hw->phy.ops.release(hw); return ret_val; } diff --git a/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_phy.h b/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_phy.h index 24ba69b938b..edcbcabe446 100644 --- a/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_phy.h +++ b/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_phy.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_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); @@ -80,12 +86,14 @@ s32 e1000_write_phy_reg_igp_locked(struct e1000_hw *hw, u32 offset, u16 data); s32 e1000_write_phy_reg_m88(struct e1000_hw *hw, u32 offset, u16 data); s32 e1000_phy_reset_dsp(struct e1000_hw *hw); s32 e1000_phy_has_link_generic(struct e1000_hw *hw, u32 iterations, - u32 usec_interval, bool *success); + u32 usec_interval, bool *success); s32 e1000_phy_init_script_igp3(struct e1000_hw *hw); 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,45 +102,62 @@ 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 */ -#define IGP01E1000_PHY_PORT_STATUS 0x11 /* Status */ -#define IGP01E1000_PHY_PORT_CTRL 0x12 /* Control */ -#define IGP01E1000_PHY_LINK_HEALTH 0x13 /* PHY Link Health */ -#define IGP01E1000_GMII_FIFO 0x14 /* GMII FIFO */ -#define IGP01E1000_PHY_CHANNEL_QUALITY 0x15 /* PHY Channel Quality */ -#define IGP02E1000_PHY_POWER_MGMT 0x19 /* Power Management */ -#define IGP01E1000_PHY_PAGE_SELECT 0x1F /* Page Select */ -#define BM_PHY_PAGE_SELECT 22 /* Page Select for BM */ -#define IGP_PAGE_SHIFT 5 -#define PHY_REG_MASK 0x1F +#define IGP01E1000_PHY_PORT_CONFIG 0x10 /* Port Config */ +#define IGP01E1000_PHY_PORT_STATUS 0x11 /* Status */ +#define IGP01E1000_PHY_PORT_CTRL 0x12 /* Control */ +#define IGP01E1000_PHY_LINK_HEALTH 0x13 /* PHY Link Health */ +#define IGP01E1000_GMII_FIFO 0x14 /* GMII FIFO */ +#define IGP01E1000_PHY_CHANNEL_QUALITY 0x15 /* PHY Channel Quality */ +#define IGP02E1000_PHY_POWER_MGMT 0x19 /* Power Management */ +#define IGP01E1000_PHY_PAGE_SELECT 0x1F /* Page Select */ +#define BM_PHY_PAGE_SELECT 22 /* Page Select for BM */ +#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 -#define BM_WUC_DATA_OPCODE 0x12 -#define BM_WUC_ENABLE_PAGE BM_PORT_CTRL_PAGE -#define BM_WUC_ENABLE_REG 17 -#define BM_WUC_ENABLE_BIT (1 << 2) -#define BM_WUC_HOST_WU_BIT (1 << 4) - -#define PHY_UPPER_SHIFT 21 +#define BM_PORT_CTRL_PAGE 769 +#define BM_PCIE_PAGE 770 +#define BM_WUC_PAGE 800 +#define BM_WUC_ADDRESS_OPCODE 0x11 +#define BM_WUC_DATA_OPCODE 0x12 +#define BM_WUC_ENABLE_PAGE BM_PORT_CTRL_PAGE +#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) \ (((reg) & MAX_PHY_REG_ADDRESS) |\ (((page) & 0xFFFF) << PHY_PAGE_SHIFT) |\ @@ -144,132 +169,157 @@ s32 e1000_get_cable_length_82577(struct e1000_hw *hw); (((offset) >> (PHY_UPPER_SHIFT - PHY_PAGE_SHIFT)) &\ ~MAX_PHY_REG_ADDRESS))) -#define HV_INTC_FC_PAGE_START 768 -#define I82578_ADDR_REG 29 -#define I82577_ADDR_REG 16 -#define I82577_CFG_REG 22 -#define I82577_CFG_ASSERT_CRS_ON_TX (1 << 15) -#define I82577_CFG_ENABLE_DOWNSHIFT (3 << 10) /* auto downshift 100/10 */ -#define I82577_CTRL_REG 23 +#define HV_INTC_FC_PAGE_START 768 +#define I82578_ADDR_REG 29 +#define I82577_ADDR_REG 16 +#define I82577_CFG_REG 22 +#define I82577_CFG_ASSERT_CRS_ON_TX (1 << 15) +#define I82577_CFG_ENABLE_DOWNSHIFT (3 << 10) /* auto downshift 100/10 */ +#define I82577_CTRL_REG 23 /* 82577 specific PHY registers */ -#define I82577_PHY_CTRL_2 18 -#define I82577_PHY_LBK_CTRL 19 -#define I82577_PHY_STATUS_2 26 -#define I82577_PHY_DIAG_STATUS 31 +#define I82577_PHY_CTRL_2 18 +#define I82577_PHY_LBK_CTRL 19 +#define I82577_PHY_STATUS_2 26 +#define I82577_PHY_DIAG_STATUS 31 /* I82577 PHY Status 2 */ -#define I82577_PHY_STATUS2_REV_POLARITY 0x0400 -#define I82577_PHY_STATUS2_MDIX 0x0800 -#define I82577_PHY_STATUS2_SPEED_MASK 0x0300 -#define I82577_PHY_STATUS2_SPEED_1000MBPS 0x0200 -#define I82577_PHY_STATUS2_SPEED_100MBPS 0x0100 +#define I82577_PHY_STATUS2_REV_POLARITY 0x0400 +#define I82577_PHY_STATUS2_MDIX 0x0800 +#define I82577_PHY_STATUS2_SPEED_MASK 0x0300 +#define I82577_PHY_STATUS2_SPEED_1000MBPS 0x0200 +#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 -#define I82577_DSTATUS_CABLE_LENGTH_SHIFT 2 +#define I82577_DSTATUS_CABLE_LENGTH 0x03FC +#define I82577_DSTATUS_CABLE_LENGTH_SHIFT 2 /* 82580 PHY Power Management */ -#define E1000_82580_PHY_POWER_MGMT 0xE14 -#define E1000_82580_PM_SPD 0x0001 /* Smart Power Down */ -#define E1000_82580_PM_D0_LPLU 0x0002 /* For D0a states */ -#define E1000_82580_PM_D3_LPLU 0x0004 /* For all other states */ +#define E1000_82580_PHY_POWER_MGMT 0xE14 +#define E1000_82580_PM_SPD 0x0001 /* Smart Power Down */ +#define E1000_82580_PM_D0_LPLU 0x0002 /* For D0a states */ +#define E1000_82580_PM_D3_LPLU 0x0004 /* For all other states */ /* BM PHY Copper Specific Control 1 */ -#define BM_CS_CTRL1 16 -#define BM_CS_CTRL1_ENERGY_DETECT 0x0300 /* Enable Energy Detect */ +#define BM_CS_CTRL1 16 +#define BM_CS_CTRL1_ENERGY_DETECT 0x0300 /* Enable Energy Detect */ /* BM PHY Copper Specific Status */ -#define BM_CS_STATUS 17 -#define BM_CS_STATUS_ENERGY_DETECT 0x0010 /* Energy Detect Status */ -#define BM_CS_STATUS_LINK_UP 0x0400 -#define BM_CS_STATUS_RESOLVED 0x0800 -#define BM_CS_STATUS_SPEED_MASK 0xC000 -#define BM_CS_STATUS_SPEED_1000 0x8000 +#define BM_CS_STATUS 17 +#define BM_CS_STATUS_ENERGY_DETECT 0x0010 /* Energy Detect Status */ +#define BM_CS_STATUS_LINK_UP 0x0400 +#define BM_CS_STATUS_RESOLVED 0x0800 +#define BM_CS_STATUS_SPEED_MASK 0xC000 +#define BM_CS_STATUS_SPEED_1000 0x8000 /* 82577 Mobile Phy Status Register */ -#define HV_M_STATUS 26 -#define HV_M_STATUS_AUTONEG_COMPLETE 0x1000 -#define HV_M_STATUS_SPEED_MASK 0x0300 -#define HV_M_STATUS_SPEED_1000 0x0200 -#define HV_M_STATUS_LINK_UP 0x0040 +#define HV_M_STATUS 26 +#define HV_M_STATUS_AUTONEG_COMPLETE 0x1000 +#define HV_M_STATUS_SPEED_MASK 0x0300 +#define HV_M_STATUS_SPEED_1000 0x0200 +#define HV_M_STATUS_LINK_UP 0x0040 -#define IGP01E1000_PHY_PCS_INIT_REG 0x00B4 -#define IGP01E1000_PHY_POLARITY_MASK 0x0078 +#define IGP01E1000_PHY_PCS_INIT_REG 0x00B4 +#define IGP01E1000_PHY_POLARITY_MASK 0x0078 -#define IGP01E1000_PSCR_AUTO_MDIX 0x1000 -#define IGP01E1000_PSCR_FORCE_MDI_MDIX 0x2000 /* 0=MDI, 1=MDIX */ +#define IGP01E1000_PSCR_AUTO_MDIX 0x1000 +#define IGP01E1000_PSCR_FORCE_MDI_MDIX 0x2000 /* 0=MDI, 1=MDIX */ -#define IGP01E1000_PSCFR_SMART_SPEED 0x0080 +#define IGP01E1000_PSCFR_SMART_SPEED 0x0080 /* Enable flexible speed on link-up */ -#define IGP01E1000_GMII_FLEX_SPD 0x0010 -#define IGP01E1000_GMII_SPD 0x0020 /* Enable SPD */ - -#define IGP02E1000_PM_SPD 0x0001 /* Smart Power Down */ -#define IGP02E1000_PM_D0_LPLU 0x0002 /* For D0a states */ -#define IGP02E1000_PM_D3_LPLU 0x0004 /* For all other states */ - -#define IGP01E1000_PLHR_SS_DOWNGRADE 0x8000 - -#define IGP01E1000_PSSR_POLARITY_REVERSED 0x0002 -#define IGP01E1000_PSSR_MDIX 0x0800 -#define IGP01E1000_PSSR_SPEED_MASK 0xC000 -#define IGP01E1000_PSSR_SPEED_1000MBPS 0xC000 - -#define IGP02E1000_PHY_CHANNEL_NUM 4 -#define IGP02E1000_PHY_AGC_A 0x11B1 -#define IGP02E1000_PHY_AGC_B 0x12B1 -#define IGP02E1000_PHY_AGC_C 0x14B1 -#define IGP02E1000_PHY_AGC_D 0x18B1 - -#define IGP02E1000_AGC_LENGTH_SHIFT 9 /* Course - 15:13, Fine - 12:9 */ -#define IGP02E1000_AGC_LENGTH_MASK 0x7F -#define IGP02E1000_AGC_RANGE 15 - -#define IGP03E1000_PHY_MISC_CTRL 0x1B -#define IGP03E1000_PHY_MISC_DUPLEX_MANUAL_SET 0x1000 /* Manually Set Duplex */ - -#define E1000_CABLE_LENGTH_UNDEFINED 0xFF - -#define E1000_KMRNCTRLSTA_OFFSET 0x001F0000 -#define E1000_KMRNCTRLSTA_OFFSET_SHIFT 16 -#define E1000_KMRNCTRLSTA_REN 0x00200000 -#define E1000_KMRNCTRLSTA_CTRL_OFFSET 0x1 /* Kumeran Control */ -#define E1000_KMRNCTRLSTA_DIAG_OFFSET 0x3 /* Kumeran Diagnostic */ -#define E1000_KMRNCTRLSTA_TIMEOUTS 0x4 /* Kumeran Timeouts */ -#define E1000_KMRNCTRLSTA_INBAND_PARAM 0x9 /* Kumeran InBand Parameters */ -#define E1000_KMRNCTRLSTA_IBIST_DISABLE 0x0200 /* Kumeran IBIST Disable */ -#define E1000_KMRNCTRLSTA_DIAG_NELPBK 0x1000 /* Nearend Loopback mode */ -#define E1000_KMRNCTRLSTA_K1_CONFIG 0x7 -#define E1000_KMRNCTRLSTA_K1_ENABLE 0x0002 -#define E1000_KMRNCTRLSTA_HD_CTRL 0x10 /* Kumeran HD Control */ - -#define IFE_PHY_EXTENDED_STATUS_CONTROL 0x10 -#define IFE_PHY_SPECIAL_CONTROL 0x11 /* 100BaseTx PHY Special Control */ -#define IFE_PHY_SPECIAL_CONTROL_LED 0x1B /* PHY Special and LED Control */ -#define IFE_PHY_MDIX_CONTROL 0x1C /* MDI/MDI-X Control */ +#define IGP01E1000_GMII_FLEX_SPD 0x0010 +#define IGP01E1000_GMII_SPD 0x0020 /* Enable SPD */ + +#define IGP02E1000_PM_SPD 0x0001 /* Smart Power Down */ +#define IGP02E1000_PM_D0_LPLU 0x0002 /* For D0a states */ +#define IGP02E1000_PM_D3_LPLU 0x0004 /* For all other states */ + +#define IGP01E1000_PLHR_SS_DOWNGRADE 0x8000 + +#define IGP01E1000_PSSR_POLARITY_REVERSED 0x0002 +#define IGP01E1000_PSSR_MDIX 0x0800 +#define IGP01E1000_PSSR_SPEED_MASK 0xC000 +#define IGP01E1000_PSSR_SPEED_1000MBPS 0xC000 + +#define IGP02E1000_PHY_CHANNEL_NUM 4 +#define IGP02E1000_PHY_AGC_A 0x11B1 +#define IGP02E1000_PHY_AGC_B 0x12B1 +#define IGP02E1000_PHY_AGC_C 0x14B1 +#define IGP02E1000_PHY_AGC_D 0x18B1 + +#define IGP02E1000_AGC_LENGTH_SHIFT 9 /* Course - 15:13, Fine - 12:9 */ +#define IGP02E1000_AGC_LENGTH_MASK 0x7F +#define IGP02E1000_AGC_RANGE 15 + +#define IGP03E1000_PHY_MISC_CTRL 0x1B +#define IGP03E1000_PHY_MISC_DUPLEX_MANUAL_SET 0x1000 /* Manually Set Duplex */ + +#define E1000_CABLE_LENGTH_UNDEFINED 0xFF + +#define E1000_KMRNCTRLSTA_OFFSET 0x001F0000 +#define E1000_KMRNCTRLSTA_OFFSET_SHIFT 16 +#define E1000_KMRNCTRLSTA_REN 0x00200000 +#define E1000_KMRNCTRLSTA_CTRL_OFFSET 0x1 /* Kumeran Control */ +#define E1000_KMRNCTRLSTA_DIAG_OFFSET 0x3 /* Kumeran Diagnostic */ +#define E1000_KMRNCTRLSTA_TIMEOUTS 0x4 /* Kumeran Timeouts */ +#define E1000_KMRNCTRLSTA_INBAND_PARAM 0x9 /* Kumeran InBand Parameters */ +#define E1000_KMRNCTRLSTA_IBIST_DISABLE 0x0200 /* Kumeran IBIST Disable */ +#define E1000_KMRNCTRLSTA_DIAG_NELPBK 0x1000 /* Nearend Loopback mode */ +#define E1000_KMRNCTRLSTA_K1_CONFIG 0x7 +#define E1000_KMRNCTRLSTA_K1_ENABLE 0x0002 +#define E1000_KMRNCTRLSTA_HD_CTRL 0x10 /* Kumeran HD Control */ + +#define IFE_PHY_EXTENDED_STATUS_CONTROL 0x10 +#define IFE_PHY_SPECIAL_CONTROL 0x11 /* 100BaseTx PHY Special Control */ +#define IFE_PHY_SPECIAL_CONTROL_LED 0x1B /* PHY Special and LED Control */ +#define IFE_PHY_MDIX_CONTROL 0x1C /* MDI/MDI-X Control */ /* IFE PHY Extended Status Control */ -#define IFE_PESC_POLARITY_REVERSED 0x0100 +#define IFE_PESC_POLARITY_REVERSED 0x0100 /* IFE PHY Special Control */ -#define IFE_PSC_AUTO_POLARITY_DISABLE 0x0010 -#define IFE_PSC_FORCE_POLARITY 0x0020 -#define IFE_PSC_DISABLE_DYNAMIC_POWER_DOWN 0x0100 +#define IFE_PSC_AUTO_POLARITY_DISABLE 0x0010 +#define IFE_PSC_FORCE_POLARITY 0x0020 +#define IFE_PSC_DISABLE_DYNAMIC_POWER_DOWN 0x0100 /* IFE PHY Special Control and LED Control */ -#define IFE_PSCL_PROBE_MODE 0x0020 -#define IFE_PSCL_PROBE_LEDS_OFF 0x0006 /* Force LEDs 0 and 2 off */ -#define IFE_PSCL_PROBE_LEDS_ON 0x0007 /* Force LEDs 0 and 2 on */ +#define IFE_PSCL_PROBE_MODE 0x0020 +#define IFE_PSCL_PROBE_LEDS_OFF 0x0006 /* Force LEDs 0 and 2 off */ +#define IFE_PSCL_PROBE_LEDS_ON 0x0007 /* Force LEDs 0 and 2 on */ /* 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_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, 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 diff --git a/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_regs.h b/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_regs.h index 892d1cccea1..8c4e4afd13b 100644 --- a/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_regs.h +++ b/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_regs.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,109 +30,176 @@ 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_ -#define E1000_CTRL 0x00000 /* Device Control - RW */ -#define E1000_CTRL_DUP 0x00004 /* Device Control Duplicate (Shadow) - RW */ -#define E1000_STATUS 0x00008 /* Device Status - RO */ -#define E1000_EECD 0x00010 /* EEPROM/Flash Control - RW */ -#define E1000_EERD 0x00014 /* EEPROM Read - RW */ -#define E1000_CTRL_EXT 0x00018 /* Extended Device Control - RW */ -#define E1000_FLA 0x0001C /* Flash Access - RW */ -#define E1000_MDIC 0x00020 /* MDI Control - RW */ -#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_BARCTRL 0x5BBC /* BAR ctrl reg */ -#define E1000_BARCTRL_FLSIZE 0x0700 /* BAR ctrl Flsize */ -#define E1000_BARCTRL_CSRSIZE 0x2000 /* BAR ctrl CSR size */ -#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 */ -#define E1000_FEXT 0x0002C /* Future Extended - RW */ -#define E1000_FEXTNVM4 0x00024 /* Future Extended NVM 4 - RW */ -#define E1000_FEXTNVM 0x00028 /* Future Extended NVM - RW */ -#define E1000_FCT 0x00030 /* Flow Control Type - RW */ -#define E1000_CONNSW 0x00034 /* Copper/Fiber switch control - RW */ -#define E1000_VET 0x00038 /* VLAN Ether Type - RW */ -#define E1000_ICR 0x000C0 /* Interrupt Cause Read - R/clr */ -#define E1000_ITR 0x000C4 /* Interrupt Throttling Rate - RW */ -#define E1000_ICS 0x000C8 /* Interrupt Cause Set - WO */ -#define E1000_IMS 0x000D0 /* Interrupt Mask Set - RW */ -#define E1000_IMC 0x000D8 /* Interrupt Mask Clear - WO */ -#define E1000_IAM 0x000E0 /* Interrupt Acknowledge Auto Mask */ -#define E1000_IVAR 0x000E4 /* Interrupt Vector Allocation Register - RW */ -#define E1000_SVCR 0x000F0 -#define E1000_SVT 0x000F4 -#define E1000_RCTL 0x00100 /* Rx Control - RW */ -#define E1000_FCTTV 0x00170 /* Flow Control Transmit Timer Value - RW */ -#define E1000_TXCW 0x00178 /* Tx Configuration Word - RW */ -#define E1000_RXCW 0x00180 /* Rx Configuration Word - RO */ -#define E1000_PBA_ECC 0x01100 /* PBA ECC Register */ -#define E1000_EICR 0x01580 /* Ext. Interrupt Cause Read - R/clr */ -#define E1000_EITR(_n) (0x01680 + (0x4 * (_n))) -#define E1000_EICS 0x01520 /* Ext. Interrupt Cause Set - W0 */ -#define E1000_EIMS 0x01524 /* Ext. Interrupt Mask Set/Read - RW */ -#define E1000_EIMC 0x01528 /* Ext. Interrupt Mask Clear - WO */ -#define E1000_EIAC 0x0152C /* Ext. Interrupt Auto Clear - RW */ -#define E1000_EIAM 0x01530 /* Ext. Interrupt Ack Auto Clear Mask - RW */ -#define E1000_GPIE 0x01514 /* General Purpose Interrupt Enable - RW */ -#define E1000_IVAR0 0x01700 /* Interrupt Vector Allocation (array) - RW */ -#define E1000_IVAR_MISC 0x01740 /* IVAR for "other" causes - RW */ -#define E1000_TCTL 0x00400 /* Tx Control - RW */ -#define E1000_TCTL_EXT 0x00404 /* Extended Tx Control - RW */ -#define E1000_TIPG 0x00410 /* Tx Inter-packet gap -RW */ -#define E1000_TBT 0x00448 /* Tx Burst Timer - RW */ -#define E1000_AIT 0x00458 /* Adaptive Interframe Spacing Throttle - RW */ -#define E1000_LEDCTL 0x00E00 /* LED Control - RW */ -#define E1000_EXTCNF_CTRL 0x00F00 /* Extended Configuration Control */ -#define E1000_EXTCNF_SIZE 0x00F08 /* Extended Configuration Size */ -#define E1000_PHY_CTRL 0x00F10 /* PHY Control Register in CSR */ -#define E1000_POEMB E1000_PHY_CTRL /* PHY OEM Bits */ -#define E1000_PBA 0x01000 /* Packet Buffer Allocation - RW */ -#define E1000_PBS 0x01008 /* Packet Buffer Size */ -#define E1000_EEMNGCTL 0x01010 /* MNG EEprom Control */ -#define E1000_EEARBC 0x01024 /* EEPROM Auto Read Bus Control */ -#define E1000_FLASHT 0x01028 /* FLASH Timer Register */ -#define E1000_EEWR 0x0102C /* EEPROM Write Register - RW */ -#define E1000_FLSWCTL 0x01030 /* FLASH control register */ -#define E1000_FLSWDATA 0x01034 /* FLASH data register */ -#define E1000_FLSWCNT 0x01038 /* FLASH Access Counter */ -#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_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_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 */ -#define E1000_PSRCTL 0x02170 /* Packet Split Receive Control - RW */ -#define E1000_RDFPCQ(_n) (0x02430 + (0x4 * (_n))) -#define E1000_PBRTH 0x02458 /* PB Rx Arbitration Threshold - RW */ -#define E1000_FCRTV 0x02460 /* Flow Control Refresh Timer Value - RW */ +#define E1000_CTRL 0x00000 /* Device Control - RW */ +#define E1000_CTRL_DUP 0x00004 /* Device Control Duplicate (Shadow) - RW */ +#define E1000_STATUS 0x00008 /* Device Status - RO */ +#define E1000_EECD 0x00010 /* EEPROM/Flash Control - RW */ +#define E1000_EERD 0x00014 /* EEPROM Read - RW */ +#define E1000_CTRL_EXT 0x00018 /* Extended Device Control - RW */ +#define E1000_FLA 0x0001C /* Flash Access - RW */ +#define E1000_MDIC 0x00020 /* MDI Control - RW */ +#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 */ +#define E1000_FEXT 0x0002C /* Future Extended - RW */ +#define E1000_FEXTNVM4 0x00024 /* Future Extended NVM 4 - RW */ +#define E1000_FEXTNVM 0x00028 /* Future Extended NVM - RW */ +#define E1000_FCT 0x00030 /* Flow Control Type - RW */ +#define E1000_CONNSW 0x00034 /* Copper/Fiber switch control - RW */ +#define E1000_VET 0x00038 /* VLAN Ether Type - RW */ +#define E1000_ICR 0x000C0 /* Interrupt Cause Read - R/clr */ +#define E1000_ITR 0x000C4 /* Interrupt Throttling Rate - RW */ +#define E1000_ICS 0x000C8 /* Interrupt Cause Set - WO */ +#define E1000_IMS 0x000D0 /* Interrupt Mask Set - RW */ +#define E1000_IMC 0x000D8 /* Interrupt Mask Clear - WO */ +#define E1000_IAM 0x000E0 /* Interrupt Acknowledge Auto Mask */ +#define E1000_IVAR 0x000E4 /* Interrupt Vector Allocation Register - RW */ +#define E1000_SVCR 0x000F0 +#define E1000_SVT 0x000F4 +#define E1000_RCTL 0x00100 /* Rx Control - RW */ +#define E1000_FCTTV 0x00170 /* Flow Control Transmit Timer Value - RW */ +#define E1000_TXCW 0x00178 /* Tx Configuration Word - RW */ +#define E1000_RXCW 0x00180 /* Rx Configuration Word - RO */ +#define E1000_PBA_ECC 0x01100 /* PBA ECC Register */ +#define E1000_EICR 0x01580 /* Ext. Interrupt Cause Read - R/clr */ +#define E1000_EITR(_n) (0x01680 + (0x4 * (_n))) +#define E1000_EICS 0x01520 /* Ext. Interrupt Cause Set - W0 */ +#define E1000_EIMS 0x01524 /* Ext. Interrupt Mask Set/Read - RW */ +#define E1000_EIMC 0x01528 /* Ext. Interrupt Mask Clear - WO */ +#define E1000_EIAC 0x0152C /* Ext. Interrupt Auto Clear - RW */ +#define E1000_EIAM 0x01530 /* Ext. Interrupt Ack Auto Clear Mask - RW */ +#define E1000_GPIE 0x01514 /* General Purpose Interrupt Enable - RW */ +#define E1000_IVAR0 0x01700 /* Interrupt Vector Allocation (array) - RW */ +#define E1000_IVAR_MISC 0x01740 /* IVAR for "other" causes - RW */ +#define E1000_TCTL 0x00400 /* Tx Control - RW */ +#define E1000_TCTL_EXT 0x00404 /* Extended Tx Control - RW */ +#define E1000_TIPG 0x00410 /* Tx Inter-packet gap -RW */ +#define E1000_TBT 0x00448 /* Tx Burst Timer - RW */ +#define E1000_AIT 0x00458 /* Adaptive Interframe Spacing Throttle - RW */ +#define E1000_LEDCTL 0x00E00 /* LED Control - RW */ +#define E1000_EXTCNF_CTRL 0x00F00 /* Extended Configuration Control */ +#define E1000_EXTCNF_SIZE 0x00F08 /* Extended Configuration Size */ +#define E1000_PHY_CTRL 0x00F10 /* PHY Control Register in CSR */ +#define E1000_POEMB E1000_PHY_CTRL /* PHY OEM Bits */ +#define E1000_PBA 0x01000 /* Packet Buffer Allocation - RW */ +#define E1000_PBS 0x01008 /* Packet Buffer Size */ +#define E1000_EEMNGCTL 0x01010 /* MNG EEprom Control */ +#define E1000_EEARBC 0x01024 /* EEPROM Auto Read Bus Control */ +#define E1000_FLASHT 0x01028 /* FLASH Timer Register */ +#define E1000_EEWR 0x0102C /* EEPROM Write Register - RW */ +#define E1000_FLSWCTL 0x01030 /* FLASH control register */ +#define E1000_FLSWDATA 0x01034 /* FLASH data register */ +#define E1000_FLSWCNT 0x01038 /* FLASH Access Counter */ +#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 /* 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 */ +#define E1000_PSRCTL 0x02170 /* Packet Split Receive Control - RW */ +#define E1000_RDFPCQ(_n) (0x02430 + (0x4 * (_n))) +#define E1000_PBRTH 0x02458 /* PB Rx Arbitration Threshold - RW */ +#define E1000_FCRTV 0x02460 /* Flow Control Refresh Timer Value - RW */ /* Split and Replication Rx Control - RW */ -#define E1000_RDPUMB 0x025CC /* DMA Rx Descriptor uC Mailbox - RW */ -#define E1000_RDPUAD 0x025D0 /* DMA Rx Descriptor uC Addr Command - RW */ -#define E1000_RDPUWD 0x025D4 /* DMA Rx Descriptor uC Data Write - RW */ -#define E1000_RDPURD 0x025D8 /* DMA Rx Descriptor uC Data Read - RW */ -#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_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_RDPUMB 0x025CC /* DMA Rx Descriptor uC Mailbox - RW */ +#define E1000_RDPUAD 0x025D0 /* DMA Rx Descriptor uC Addr Command - RW */ +#define E1000_RDPUWD 0x025D4 /* DMA Rx Descriptor uC Data Write - RW */ +#define E1000_RDPURD 0x025D8 /* DMA Rx Descriptor uC Data Read - RW */ +#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 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 * @@ -141,442 +208,472 @@ * Example usage: * E1000_RDBAL_REG(current_rx_queue) */ -#define E1000_RDBAL(_n) ((_n) < 4 ? (0x02800 + ((_n) * 0x100)) : \ - (0x0C000 + ((_n) * 0x40))) -#define E1000_RDBAH(_n) ((_n) < 4 ? (0x02804 + ((_n) * 0x100)) : \ - (0x0C004 + ((_n) * 0x40))) -#define E1000_RDLEN(_n) ((_n) < 4 ? (0x02808 + ((_n) * 0x100)) : \ - (0x0C008 + ((_n) * 0x40))) -#define E1000_SRRCTL(_n) ((_n) < 4 ? (0x0280C + ((_n) * 0x100)) : \ - (0x0C00C + ((_n) * 0x40))) -#define E1000_RDH(_n) ((_n) < 4 ? (0x02810 + ((_n) * 0x100)) : \ - (0x0C010 + ((_n) * 0x40))) -#define E1000_RXCTL(_n) ((_n) < 4 ? (0x02814 + ((_n) * 0x100)) : \ - (0x0C014 + ((_n) * 0x40))) -#define E1000_DCA_RXCTRL(_n) E1000_RXCTL(_n) -#define E1000_RDT(_n) ((_n) < 4 ? (0x02818 + ((_n) * 0x100)) : \ - (0x0C018 + ((_n) * 0x40))) -#define E1000_RXDCTL(_n) ((_n) < 4 ? (0x02828 + ((_n) * 0x100)) : \ - (0x0C028 + ((_n) * 0x40))) -#define E1000_RQDPC(_n) ((_n) < 4 ? (0x02830 + ((_n) * 0x100)) : \ - (0x0C030 + ((_n) * 0x40))) -#define E1000_TDBAL(_n) ((_n) < 4 ? (0x03800 + ((_n) * 0x100)) : \ - (0x0E000 + ((_n) * 0x40))) -#define E1000_TDBAH(_n) ((_n) < 4 ? (0x03804 + ((_n) * 0x100)) : \ - (0x0E004 + ((_n) * 0x40))) -#define E1000_TDLEN(_n) ((_n) < 4 ? (0x03808 + ((_n) * 0x100)) : \ - (0x0E008 + ((_n) * 0x40))) -#define E1000_TDH(_n) ((_n) < 4 ? (0x03810 + ((_n) * 0x100)) : \ - (0x0E010 + ((_n) * 0x40))) -#define E1000_TXCTL(_n) ((_n) < 4 ? (0x03814 + ((_n) * 0x100)) : \ - (0x0E014 + ((_n) * 0x40))) +#define E1000_RDBAL(_n) ((_n) < 4 ? (0x02800 + ((_n) * 0x100)) : \ + (0x0C000 + ((_n) * 0x40))) +#define E1000_RDBAH(_n) ((_n) < 4 ? (0x02804 + ((_n) * 0x100)) : \ + (0x0C004 + ((_n) * 0x40))) +#define E1000_RDLEN(_n) ((_n) < 4 ? (0x02808 + ((_n) * 0x100)) : \ + (0x0C008 + ((_n) * 0x40))) +#define E1000_SRRCTL(_n) ((_n) < 4 ? (0x0280C + ((_n) * 0x100)) : \ + (0x0C00C + ((_n) * 0x40))) +#define E1000_RDH(_n) ((_n) < 4 ? (0x02810 + ((_n) * 0x100)) : \ + (0x0C010 + ((_n) * 0x40))) +#define E1000_RXCTL(_n) ((_n) < 4 ? (0x02814 + ((_n) * 0x100)) : \ + (0x0C014 + ((_n) * 0x40))) +#define E1000_DCA_RXCTRL(_n) E1000_RXCTL(_n) +#define E1000_RDT(_n) ((_n) < 4 ? (0x02818 + ((_n) * 0x100)) : \ + (0x0C018 + ((_n) * 0x40))) +#define E1000_RXDCTL(_n) ((_n) < 4 ? (0x02828 + ((_n) * 0x100)) : \ + (0x0C028 + ((_n) * 0x40))) +#define E1000_RQDPC(_n) ((_n) < 4 ? (0x02830 + ((_n) * 0x100)) : \ + (0x0C030 + ((_n) * 0x40))) +#define E1000_TDBAL(_n) ((_n) < 4 ? (0x03800 + ((_n) * 0x100)) : \ + (0x0E000 + ((_n) * 0x40))) +#define E1000_TDBAH(_n) ((_n) < 4 ? (0x03804 + ((_n) * 0x100)) : \ + (0x0E004 + ((_n) * 0x40))) +#define E1000_TDLEN(_n) ((_n) < 4 ? (0x03808 + ((_n) * 0x100)) : \ + (0x0E008 + ((_n) * 0x40))) +#define E1000_TDH(_n) ((_n) < 4 ? (0x03810 + ((_n) * 0x100)) : \ + (0x0E010 + ((_n) * 0x40))) +#define E1000_TXCTL(_n) ((_n) < 4 ? (0x03814 + ((_n) * 0x100)) : \ + (0x0E014 + ((_n) * 0x40))) #define E1000_DCA_TXCTRL(_n) E1000_TXCTL(_n) -#define E1000_TDT(_n) ((_n) < 4 ? (0x03818 + ((_n) * 0x100)) : \ - (0x0E018 + ((_n) * 0x40))) -#define E1000_TXDCTL(_n) ((_n) < 4 ? (0x03828 + ((_n) * 0x100)) : \ - (0x0E028 + ((_n) * 0x40))) -#define E1000_TDWBAL(_n) ((_n) < 4 ? (0x03838 + ((_n) * 0x100)) : \ - (0x0E038 + ((_n) * 0x40))) -#define E1000_TDWBAH(_n) ((_n) < 4 ? (0x0383C + ((_n) * 0x100)) : \ - (0x0E03C + ((_n) * 0x40))) -#define E1000_TARC(_n) (0x03840 + ((_n) * 0x100)) -#define E1000_RSRPD 0x02C00 /* Rx Small Packet Detect - RW */ -#define E1000_RAID 0x02C08 /* Receive Ack Interrupt Delay - RW */ -#define E1000_TXDMAC 0x03000 /* Tx DMA Control - RW */ -#define E1000_KABGTXD 0x03004 /* AFE Band Gap Transmit Ref Data */ -#define E1000_PSRTYPE(_i) (0x05480 + ((_i) * 4)) -#define E1000_RAL(_i) (((_i) <= 15) ? (0x05400 + ((_i) * 8)) : \ - (0x054E0 + ((_i - 16) * 8))) -#define E1000_RAH(_i) (((_i) <= 15) ? (0x05404 + ((_i) * 8)) : \ - (0x054E4 + ((_i - 16) * 8))) -#define E1000_SHRAL(_i) (0x05438 + ((_i) * 8)) -#define E1000_SHRAH(_i) (0x0543C + ((_i) * 8)) -#define E1000_IP4AT_REG(_i) (0x05840 + ((_i) * 8)) -#define E1000_IP6AT_REG(_i) (0x05880 + ((_i) * 4)) -#define E1000_WUPM_REG(_i) (0x05A00 + ((_i) * 4)) -#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_TXPBS 0x03404 /* Tx Packet Buffer Size - RW */ -#define E1000_ITPBS 0x03404 /* Same as TXPBS, renamed for newer adpaters - RW */ -#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_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 */ -#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 */ -#define E1000_CRCERRS 0x04000 /* CRC Error Count - R/clr */ -#define E1000_ALGNERRC 0x04004 /* Alignment Error Count - R/clr */ -#define E1000_SYMERRS 0x04008 /* Symbol Error Count - R/clr */ -#define E1000_RXERRC 0x0400C /* Receive Error Count - R/clr */ -#define E1000_MPC 0x04010 /* Missed Packet Count - R/clr */ -#define E1000_SCC 0x04014 /* Single Collision Count - R/clr */ -#define E1000_ECOL 0x04018 /* Excessive Collision Count - R/clr */ -#define E1000_MCC 0x0401C /* Multiple Collision Count - R/clr */ -#define E1000_LATECOL 0x04020 /* Late Collision Count - R/clr */ -#define E1000_COLC 0x04028 /* Collision Count - R/clr */ -#define E1000_DC 0x04030 /* Defer Count - R/clr */ -#define E1000_TNCRS 0x04034 /* Tx-No CRS - R/clr */ -#define E1000_SEC 0x04038 /* Sequence Error Count - R/clr */ -#define E1000_CEXTERR 0x0403C /* Carrier Extension Error Count - R/clr */ -#define E1000_RLEC 0x04040 /* Receive Length Error Count - R/clr */ -#define E1000_XONRXC 0x04048 /* XON Rx Count - R/clr */ -#define E1000_XONTXC 0x0404C /* XON Tx Count - R/clr */ -#define E1000_XOFFRXC 0x04050 /* XOFF Rx Count - R/clr */ -#define E1000_XOFFTXC 0x04054 /* XOFF Tx Count - R/clr */ -#define E1000_FCRUC 0x04058 /* Flow Control Rx Unsupported Count- R/clr */ -#define E1000_PRC64 0x0405C /* Packets Rx (64 bytes) - R/clr */ -#define E1000_PRC127 0x04060 /* Packets Rx (65-127 bytes) - R/clr */ -#define E1000_PRC255 0x04064 /* Packets Rx (128-255 bytes) - R/clr */ -#define E1000_PRC511 0x04068 /* Packets Rx (255-511 bytes) - R/clr */ -#define E1000_PRC1023 0x0406C /* Packets Rx (512-1023 bytes) - R/clr */ -#define E1000_PRC1522 0x04070 /* Packets Rx (1024-1522 bytes) - R/clr */ -#define E1000_GPRC 0x04074 /* Good Packets Rx Count - R/clr */ -#define E1000_BPRC 0x04078 /* Broadcast Packets Rx Count - R/clr */ -#define E1000_MPRC 0x0407C /* Multicast Packets Rx Count - R/clr */ -#define E1000_GPTC 0x04080 /* Good Packets Tx Count - R/clr */ -#define E1000_GORCL 0x04088 /* Good Octets Rx Count Low - R/clr */ -#define E1000_GORCH 0x0408C /* Good Octets Rx Count High - R/clr */ -#define E1000_GOTCL 0x04090 /* Good Octets Tx Count Low - R/clr */ -#define E1000_GOTCH 0x04094 /* Good Octets Tx Count High - R/clr */ -#define E1000_RNBC 0x040A0 /* Rx No Buffers Count - R/clr */ -#define E1000_RUC 0x040A4 /* Rx Undersize Count - R/clr */ -#define E1000_RFC 0x040A8 /* Rx Fragment Count - R/clr */ -#define E1000_ROC 0x040AC /* Rx Oversize Count - R/clr */ -#define E1000_RJC 0x040B0 /* Rx Jabber Count - R/clr */ -#define E1000_MGTPRC 0x040B4 /* Management Packets Rx Count - R/clr */ -#define E1000_MGTPDC 0x040B8 /* Management Packets Dropped Count - R/clr */ -#define E1000_MGTPTC 0x040BC /* Management Packets Tx Count - R/clr */ -#define E1000_TORL 0x040C0 /* Total Octets Rx Low - R/clr */ -#define E1000_TORH 0x040C4 /* Total Octets Rx High - R/clr */ -#define E1000_TOTL 0x040C8 /* Total Octets Tx Low - R/clr */ -#define E1000_TOTH 0x040CC /* Total Octets Tx High - R/clr */ -#define E1000_TPR 0x040D0 /* Total Packets Rx - R/clr */ -#define E1000_TPT 0x040D4 /* Total Packets Tx - R/clr */ -#define E1000_PTC64 0x040D8 /* Packets Tx (64 bytes) - R/clr */ -#define E1000_PTC127 0x040DC /* Packets Tx (65-127 bytes) - R/clr */ -#define E1000_PTC255 0x040E0 /* Packets Tx (128-255 bytes) - R/clr */ -#define E1000_PTC511 0x040E4 /* Packets Tx (256-511 bytes) - R/clr */ -#define E1000_PTC1023 0x040E8 /* Packets Tx (512-1023 bytes) - R/clr */ -#define E1000_PTC1522 0x040EC /* Packets Tx (1024-1522 Bytes) - R/clr */ -#define E1000_MPTC 0x040F0 /* Multicast Packets Tx Count - R/clr */ -#define E1000_BPTC 0x040F4 /* Broadcast Packets Tx Count - R/clr */ -#define E1000_TSCTC 0x040F8 /* TCP Segmentation Context Tx - R/clr */ -#define E1000_TSCTFC 0x040FC /* TCP Segmentation Context Tx Fail - R/clr */ -#define E1000_IAC 0x04100 /* Interrupt Assertion Count */ -#define E1000_ICRXPTC 0x04104 /* Interrupt Cause Rx Pkt Timer Expire Count */ -#define E1000_ICRXATC 0x04108 /* Interrupt Cause Rx Abs Timer Expire Count */ -#define E1000_ICTXPTC 0x0410C /* Interrupt Cause Tx Pkt Timer Expire Count */ -#define E1000_ICTXATC 0x04110 /* Interrupt Cause Tx Abs Timer Expire Count */ -#define E1000_ICTXQEC 0x04118 /* Interrupt Cause Tx Queue Empty Count */ -#define E1000_ICTXQMTC 0x0411C /* Interrupt Cause Tx Queue Min Thresh Count */ -#define E1000_ICRXDMTC 0x04120 /* Interrupt Cause Rx Desc Min Thresh Count */ -#define E1000_ICRXOC 0x04124 /* Interrupt Cause Receiver Overrun Count */ -#define E1000_CRC_OFFSET 0x05F50 /* CRC Offset register */ +#define E1000_TDT(_n) ((_n) < 4 ? (0x03818 + ((_n) * 0x100)) : \ + (0x0E018 + ((_n) * 0x40))) +#define E1000_TXDCTL(_n) ((_n) < 4 ? (0x03828 + ((_n) * 0x100)) : \ + (0x0E028 + ((_n) * 0x40))) +#define E1000_TDWBAL(_n) ((_n) < 4 ? (0x03838 + ((_n) * 0x100)) : \ + (0x0E038 + ((_n) * 0x40))) +#define E1000_TDWBAH(_n) ((_n) < 4 ? (0x0383C + ((_n) * 0x100)) : \ + (0x0E03C + ((_n) * 0x40))) +#define E1000_TARC(_n) (0x03840 + ((_n) * 0x100)) +#define E1000_RSRPD 0x02C00 /* Rx Small Packet Detect - RW */ +#define E1000_RAID 0x02C08 /* Receive Ack Interrupt Delay - RW */ +#define E1000_TXDMAC 0x03000 /* Tx DMA Control - RW */ +#define E1000_KABGTXD 0x03004 /* AFE Band Gap Transmit Ref Data */ +#define E1000_PSRTYPE(_i) (0x05480 + ((_i) * 4)) +#define E1000_RAL(_i) (((_i) <= 15) ? (0x05400 + ((_i) * 8)) : \ + (0x054E0 + ((_i - 16) * 8))) +#define E1000_RAH(_i) (((_i) <= 15) ? (0x05404 + ((_i) * 8)) : \ + (0x054E4 + ((_i - 16) * 8))) +#define E1000_SHRAL(_i) (0x05438 + ((_i) * 8)) +#define E1000_SHRAH(_i) (0x0543C + ((_i) * 8)) +#define E1000_IP4AT_REG(_i) (0x05840 + ((_i) * 8)) +#define E1000_IP6AT_REG(_i) (0x05880 + ((_i) * 4)) +#define E1000_WUPM_REG(_i) (0x05A00 + ((_i) * 4)) +#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 /* Pkt Buffer Slave Access Control */ +#define E1000_PBSLAD(_n) (0x03110 + (0x4 * (_n))) /* Pkt Buffer DWORD */ +#define E1000_TXPBS 0x03404 /* Tx Packet Buffer Size - 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 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 */ +/* 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 */ +#define E1000_CRCERRS 0x04000 /* CRC Error Count - R/clr */ +#define E1000_ALGNERRC 0x04004 /* Alignment Error Count - R/clr */ +#define E1000_SYMERRS 0x04008 /* Symbol Error Count - R/clr */ +#define E1000_RXERRC 0x0400C /* Receive Error Count - R/clr */ +#define E1000_MPC 0x04010 /* Missed Packet Count - R/clr */ +#define E1000_SCC 0x04014 /* Single Collision Count - R/clr */ +#define E1000_ECOL 0x04018 /* Excessive Collision Count - R/clr */ +#define E1000_MCC 0x0401C /* Multiple Collision Count - R/clr */ +#define E1000_LATECOL 0x04020 /* Late Collision Count - R/clr */ +#define E1000_COLC 0x04028 /* Collision Count - R/clr */ +#define E1000_DC 0x04030 /* Defer Count - R/clr */ +#define E1000_TNCRS 0x04034 /* Tx-No CRS - R/clr */ +#define E1000_SEC 0x04038 /* Sequence Error Count - R/clr */ +#define E1000_CEXTERR 0x0403C /* Carrier Extension Error Count - R/clr */ +#define E1000_RLEC 0x04040 /* Receive Length Error Count - R/clr */ +#define E1000_XONRXC 0x04048 /* XON Rx Count - R/clr */ +#define E1000_XONTXC 0x0404C /* XON Tx Count - R/clr */ +#define E1000_XOFFRXC 0x04050 /* XOFF Rx Count - R/clr */ +#define E1000_XOFFTXC 0x04054 /* XOFF Tx Count - R/clr */ +#define E1000_FCRUC 0x04058 /* Flow Control Rx Unsupported Count- R/clr */ +#define E1000_PRC64 0x0405C /* Packets Rx (64 bytes) - R/clr */ +#define E1000_PRC127 0x04060 /* Packets Rx (65-127 bytes) - R/clr */ +#define E1000_PRC255 0x04064 /* Packets Rx (128-255 bytes) - R/clr */ +#define E1000_PRC511 0x04068 /* Packets Rx (255-511 bytes) - R/clr */ +#define E1000_PRC1023 0x0406C /* Packets Rx (512-1023 bytes) - R/clr */ +#define E1000_PRC1522 0x04070 /* Packets Rx (1024-1522 bytes) - R/clr */ +#define E1000_GPRC 0x04074 /* Good Packets Rx Count - R/clr */ +#define E1000_BPRC 0x04078 /* Broadcast Packets Rx Count - R/clr */ +#define E1000_MPRC 0x0407C /* Multicast Packets Rx Count - R/clr */ +#define E1000_GPTC 0x04080 /* Good Packets Tx Count - R/clr */ +#define E1000_GORCL 0x04088 /* Good Octets Rx Count Low - R/clr */ +#define E1000_GORCH 0x0408C /* Good Octets Rx Count High - R/clr */ +#define E1000_GOTCL 0x04090 /* Good Octets Tx Count Low - R/clr */ +#define E1000_GOTCH 0x04094 /* Good Octets Tx Count High - R/clr */ +#define E1000_RNBC 0x040A0 /* Rx No Buffers Count - R/clr */ +#define E1000_RUC 0x040A4 /* Rx Undersize Count - R/clr */ +#define E1000_RFC 0x040A8 /* Rx Fragment Count - R/clr */ +#define E1000_ROC 0x040AC /* Rx Oversize Count - R/clr */ +#define E1000_RJC 0x040B0 /* Rx Jabber Count - R/clr */ +#define E1000_MGTPRC 0x040B4 /* Management Packets Rx Count - R/clr */ +#define E1000_MGTPDC 0x040B8 /* Management Packets Dropped Count - R/clr */ +#define E1000_MGTPTC 0x040BC /* Management Packets Tx Count - R/clr */ +#define E1000_TORL 0x040C0 /* Total Octets Rx Low - R/clr */ +#define E1000_TORH 0x040C4 /* Total Octets Rx High - R/clr */ +#define E1000_TOTL 0x040C8 /* Total Octets Tx Low - R/clr */ +#define E1000_TOTH 0x040CC /* Total Octets Tx High - R/clr */ +#define E1000_TPR 0x040D0 /* Total Packets Rx - R/clr */ +#define E1000_TPT 0x040D4 /* Total Packets Tx - R/clr */ +#define E1000_PTC64 0x040D8 /* Packets Tx (64 bytes) - R/clr */ +#define E1000_PTC127 0x040DC /* Packets Tx (65-127 bytes) - R/clr */ +#define E1000_PTC255 0x040E0 /* Packets Tx (128-255 bytes) - R/clr */ +#define E1000_PTC511 0x040E4 /* Packets Tx (256-511 bytes) - R/clr */ +#define E1000_PTC1023 0x040E8 /* Packets Tx (512-1023 bytes) - R/clr */ +#define E1000_PTC1522 0x040EC /* Packets Tx (1024-1522 Bytes) - R/clr */ +#define E1000_MPTC 0x040F0 /* Multicast Packets Tx Count - R/clr */ +#define E1000_BPTC 0x040F4 /* Broadcast Packets Tx Count - R/clr */ +#define E1000_TSCTC 0x040F8 /* TCP Segmentation Context Tx - R/clr */ +#define E1000_TSCTFC 0x040FC /* TCP Segmentation Context Tx Fail - R/clr */ +#define E1000_IAC 0x04100 /* Interrupt Assertion Count */ +#define E1000_ICRXPTC 0x04104 /* Interrupt Cause Rx Pkt Timer Expire Count */ +#define E1000_ICRXATC 0x04108 /* Interrupt Cause Rx Abs Timer Expire Count */ +#define E1000_ICTXPTC 0x0410C /* Interrupt Cause Tx Pkt Timer Expire Count */ +#define E1000_ICTXATC 0x04110 /* Interrupt Cause Tx Abs Timer Expire Count */ +#define E1000_ICTXQEC 0x04118 /* Interrupt Cause Tx Queue Empty Count */ +#define E1000_ICTXQMTC 0x0411C /* Interrupt Cause Tx Queue Min Thresh Count */ +#define E1000_ICRXDMTC 0x04120 /* Interrupt Cause Rx Desc Min Thresh Count */ +#define E1000_ICRXOC 0x04124 /* Interrupt Cause Receiver Overrun Count */ +#define E1000_CRC_OFFSET 0x05F50 /* CRC Offset register */ -#define E1000_VFGPRC 0x00F10 -#define E1000_VFGORC 0x00F18 -#define E1000_VFMPRC 0x00F3C -#define E1000_VFGPTC 0x00F14 -#define E1000_VFGOTC 0x00F34 -#define E1000_VFGOTLBC 0x00F50 -#define E1000_VFGPTLBC 0x00F44 -#define E1000_VFGORLBC 0x00F48 -#define E1000_VFGPRLBC 0x00F40 +#define E1000_VFGPRC 0x00F10 +#define E1000_VFGORC 0x00F18 +#define E1000_VFMPRC 0x00F3C +#define E1000_VFGPTC 0x00F14 +#define E1000_VFGOTC 0x00F34 +#define E1000_VFGOTLBC 0x00F50 +#define E1000_VFGPTLBC 0x00F44 +#define E1000_VFGORLBC 0x00F48 +#define E1000_VFGPRLBC 0x00F40 /* Virtualization statistical counters */ -#define E1000_PFVFGPRC(_n) (0x010010 + (0x100 * (_n))) -#define E1000_PFVFGPTC(_n) (0x010014 + (0x100 * (_n))) -#define E1000_PFVFGORC(_n) (0x010018 + (0x100 * (_n))) -#define E1000_PFVFGOTC(_n) (0x010034 + (0x100 * (_n))) -#define E1000_PFVFMPRC(_n) (0x010038 + (0x100 * (_n))) -#define E1000_PFVFGPRLBC(_n) (0x010040 + (0x100 * (_n))) -#define E1000_PFVFGPTLBC(_n) (0x010044 + (0x100 * (_n))) -#define E1000_PFVFGORLBC(_n) (0x010048 + (0x100 * (_n))) -#define E1000_PFVFGOTLBC(_n) (0x010050 + (0x100 * (_n))) +#define E1000_PFVFGPRC(_n) (0x010010 + (0x100 * (_n))) +#define E1000_PFVFGPTC(_n) (0x010014 + (0x100 * (_n))) +#define E1000_PFVFGORC(_n) (0x010018 + (0x100 * (_n))) +#define E1000_PFVFGOTC(_n) (0x010034 + (0x100 * (_n))) +#define E1000_PFVFMPRC(_n) (0x010038 + (0x100 * (_n))) +#define E1000_PFVFGPRLBC(_n) (0x010040 + (0x100 * (_n))) +#define E1000_PFVFGPTLBC(_n) (0x010044 + (0x100 * (_n))) +#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_LSECRXKEY(_n, _m) (0x0B350 + (0x10 * (_n)) + (0x04 * (_m))) -#define E1000_SSVPC 0x041A0 /* Switch Security Violation Packet Count */ -#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 */ -#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 */ -#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 */ -#define E1000_PCS_LCTL 0x04208 /* PCS Link Control - RW */ -#define E1000_PCS_LSTAT 0x0420C /* PCS Link Status - RO */ -#define E1000_CBTMPC 0x0402C /* Circuit Breaker Tx Packet Count */ -#define E1000_HTDPMC 0x0403C /* Host Transmit Discarded Packets */ -#define E1000_CBRDPC 0x04044 /* Circuit Breaker Rx Dropped Count */ -#define E1000_CBRMPC 0x040FC /* Circuit Breaker Rx Packet Count */ -#define E1000_RPTHC 0x04104 /* Rx Packets To Host */ -#define E1000_HGPTC 0x04118 /* Host Good Packets Tx Count */ -#define E1000_HTCBDPC 0x04124 /* Host Tx Circuit Breaker Dropped Count */ -#define E1000_HGORCL 0x04128 /* Host Good Octets Received Count Low */ -#define E1000_HGORCH 0x0412C /* Host Good Octets Received Count High */ -#define E1000_HGOTCL 0x04130 /* Host Good Octets Transmit Count Low */ -#define E1000_HGOTCH 0x04134 /* Host Good Octets Transmit Count High */ -#define E1000_LENERRS 0x04138 /* Length Errors Count */ -#define E1000_SCVPC 0x04228 /* SerDes/SGMII Code Violation Pkt Count */ -#define E1000_HRMPC 0x0A018 /* Header Redirection Missed Packet Count */ -#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_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_VFTA 0x05600 /* VLAN Filter Table Array - RW Array */ -#define E1000_VT_CTL 0x0581C /* VMDq Control - 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 */ -#define E1000_WUFC 0x05808 /* Wakeup Filter Control - RW */ -#define E1000_WUS 0x05810 /* Wakeup Status - RO */ -#define E1000_MANC 0x05820 /* Management Control - RW */ -#define E1000_IPAV 0x05838 /* IP Address Valid - RW */ -#define E1000_IP4AT 0x05840 /* IPv4 Address Table - RW Array */ -#define E1000_IP6AT 0x05880 /* IPv6 Address Table - RW Array */ -#define E1000_WUPL 0x05900 /* Wakeup Packet Length - RW */ -#define E1000_WUPM 0x05A00 /* Wakeup Packet Memory - RO A */ -#define E1000_PBACL 0x05B68 /* MSIx PBA Clear - Read/Write 1's to clear */ -#define E1000_FFLT 0x05F00 /* Flexible Filter Length Table - RW Array */ -#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_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 */ +/* 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 */ +/* 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 */ +#define E1000_PCS_LCTL 0x04208 /* PCS Link Control - RW */ +#define E1000_PCS_LSTAT 0x0420C /* PCS Link Status - RO */ +#define E1000_CBTMPC 0x0402C /* Circuit Breaker Tx Packet Count */ +#define E1000_HTDPMC 0x0403C /* Host Transmit Discarded Packets */ +#define E1000_CBRDPC 0x04044 /* Circuit Breaker Rx Dropped Count */ +#define E1000_CBRMPC 0x040FC /* Circuit Breaker Rx Packet Count */ +#define E1000_RPTHC 0x04104 /* Rx Packets To Host */ +#define E1000_HGPTC 0x04118 /* Host Good Packets Tx Count */ +#define E1000_HTCBDPC 0x04124 /* Host Tx Circuit Breaker Dropped Count */ +#define E1000_HGORCL 0x04128 /* Host Good Octets Received Count Low */ +#define E1000_HGORCH 0x0412C /* Host Good Octets Received Count High */ +#define E1000_HGOTCL 0x04130 /* Host Good Octets Transmit Count Low */ +#define E1000_HGOTCH 0x04134 /* Host Good Octets Transmit Count High */ +#define E1000_LENERRS 0x04138 /* Length Errors Count */ +#define E1000_SCVPC 0x04228 /* SerDes/SGMII Code Violation Pkt Count */ +#define E1000_HRMPC 0x0A018 /* Header Redirection Missed Packet Count */ +#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 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 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 */ +#define E1000_WUFC 0x05808 /* Wakeup Filter Control - RW */ +#define E1000_WUS 0x05810 /* Wakeup Status - RO */ +#define E1000_MANC 0x05820 /* Management Control - RW */ +#define E1000_IPAV 0x05838 /* IP Address Valid - RW */ +#define E1000_IP4AT 0x05840 /* IPv4 Address Table - RW Array */ +#define E1000_IP6AT 0x05880 /* IPv6 Address Table - RW Array */ +#define E1000_WUPL 0x05900 /* Wakeup Packet Length - RW */ +#define E1000_WUPM 0x05A00 /* Wakeup Packet Memory - RO A */ +#define E1000_PBACL 0x05B68 /* MSIx PBA Clear - Read/Write 1's to clear */ +#define E1000_FFLT 0x05F00 /* Flexible Filter Length Table - RW Array */ +#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_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 */ -#define E1000_CCMCTL 0x05B48 /* CCM Control Register */ -#define E1000_GIOCTL 0x05B44 /* GIO Analog Control Register */ -#define E1000_SCCTL 0x05B4C /* PCIc PLL Configuration Register */ -#define E1000_GCR 0x05B00 /* PCI-Ex Control */ -#define E1000_GCR2 0x05B64 /* PCI-Ex Control #2 */ -#define E1000_GSCL_1 0x05B10 /* PCI-Ex Statistic Control #1 */ -#define E1000_GSCL_2 0x05B14 /* PCI-Ex Statistic Control #2 */ -#define E1000_GSCL_3 0x05B18 /* PCI-Ex Statistic Control #3 */ -#define E1000_GSCL_4 0x05B1C /* PCI-Ex Statistic Control #4 */ -#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) */ -#define E1000_DCA_ID 0x05B70 /* DCA Requester ID Information - RO */ -#define E1000_DCA_CTRL 0x05B74 /* DCA Control - RW */ -#define E1000_UFUSE 0x05B78 /* UFUSE - RO */ -#define E1000_FFLT_DBG 0x05F04 /* Debug Register */ -#define E1000_HICR 0x08F00 /* Host Interface Control */ -#define E1000_FWSTS 0x08F0C /* FW Status */ +#define E1000_KMRNCTRLSTA 0x00034 /* MAC-PHY interface - RW */ +#define E1000_MDPHYA 0x0003C /* PHY address - RW */ +#define E1000_MANC2H 0x05860 /* Management Control To Host - 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 */ +#define E1000_GCR 0x05B00 /* PCI-Ex Control */ +#define E1000_GCR2 0x05B64 /* PCI-Ex Control #2 */ +#define E1000_GSCL_1 0x05B10 /* PCI-Ex Statistic Control #1 */ +#define E1000_GSCL_2 0x05B14 /* PCI-Ex Statistic Control #2 */ +#define E1000_GSCL_3 0x05B18 /* PCI-Ex Statistic Control #3 */ +#define E1000_GSCL_4 0x05B1C /* PCI-Ex Statistic Control #4 */ +#define E1000_FACTPS 0x05B30 /* Function Active and Power State to MNG */ +#define E1000_SWSM 0x05B50 /* SW Semaphore */ +#define E1000_FWSM 0x05B54 /* FW Semaphore */ +/* 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 */ +#define E1000_FFLT_DBG 0x05F04 /* Debug Register */ +#define E1000_HICR 0x08F00 /* Host Interface Control */ +#define E1000_FWSTS 0x08F0C /* FW Status */ /* RSS registers */ -#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_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 */ -#define E1000_RSSIM 0x05864 /* RSS Interrupt Mask */ -#define E1000_RSSIR 0x05868 /* RSS Interrupt Request */ +#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 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 */ +#define E1000_RSSIM 0x05864 /* RSS Interrupt Mask */ +#define E1000_RSSIR 0x05868 /* RSS Interrupt Request */ /* VT Registers */ -#define E1000_SWPBS 0x03004 /* Switch Packet Buffer Size - RW */ -#define E1000_MBVFICR 0x00C80 /* Mailbox VF Cause - RWC */ -#define E1000_MBVFIMR 0x00C84 /* Mailbox VF int Mask - RW */ -#define E1000_VFLRE 0x00C88 /* VF Register Events - RWC */ -#define E1000_VFRE 0x00C8C /* VF Receive Enables */ -#define E1000_VFTE 0x00C90 /* VF Transmit Enables */ -#define E1000_QDE 0x02408 /* Queue Drop Enable - RW */ -#define E1000_DTXSWC 0x03500 /* DMA Tx Switch Control - RW */ -#define E1000_WVBR 0x03554 /* VM Wrong Behavior - RWS */ -#define E1000_RPLOLR 0x05AF0 /* Replication Offload - RW */ -#define E1000_UTA 0x0A000 /* Unicast Table Array - RW */ -#define E1000_IOVTCL 0x05BBC /* IOV Control Register */ -#define E1000_VMRCTL 0X05D80 /* Virtual Mirror Rule Control */ -#define E1000_VMRVLAN 0x05D90 /* Virtual Mirror Rule VLAN */ -#define E1000_VMRVM 0x05DA0 /* Virtual Mirror Rule VM */ -#define E1000_MDFB 0x03558 /* Malicious Driver free block */ -#define E1000_LVMMC 0x03548 /* Last VM Misbehavior cause */ -#define E1000_TXSWC 0x05ACC /* Tx Switch Control */ -#define E1000_SCCRL 0x05DB0 /* Storm Control Control */ -#define E1000_BSCTRH 0x05DB8 /* Broadcast Storm Control Threshold */ -#define E1000_MSCTRH 0x05DBC /* Multicast Storm Control Threshold */ +#define E1000_SWPBS 0x03004 /* Switch Packet Buffer Size - RW */ +#define E1000_MBVFICR 0x00C80 /* Mailbox VF Cause - RWC */ +#define E1000_MBVFIMR 0x00C84 /* Mailbox VF int Mask - RW */ +#define E1000_VFLRE 0x00C88 /* VF Register Events - RWC */ +#define E1000_VFRE 0x00C8C /* VF Receive Enables */ +#define E1000_VFTE 0x00C90 /* VF Transmit Enables */ +#define E1000_QDE 0x02408 /* Queue Drop Enable - RW */ +#define E1000_DTXSWC 0x03500 /* DMA Tx Switch Control - RW */ +#define E1000_WVBR 0x03554 /* VM Wrong Behavior - RWS */ +#define E1000_RPLOLR 0x05AF0 /* Replication Offload - RW */ +#define E1000_UTA 0x0A000 /* Unicast Table Array - RW */ +#define E1000_IOVTCL 0x05BBC /* IOV Control Register */ +#define E1000_VMRCTL 0X05D80 /* Virtual Mirror Rule Control */ +#define E1000_VMRVLAN 0x05D90 /* Virtual Mirror Rule VLAN */ +#define E1000_VMRVM 0x05DA0 /* Virtual Mirror Rule VM */ +#define E1000_MDFB 0x03558 /* Malicious Driver free block */ +#define E1000_LVMMC 0x03548 /* Last VM Misbehavior cause */ +#define E1000_TXSWC 0x05ACC /* Tx Switch Control */ +#define E1000_SCCRL 0x05DB0 /* Storm Control Control */ +#define E1000_BSCTRH 0x05DB8 /* Broadcast Storm Control Threshold */ +#define E1000_MSCTRH 0x05DBC /* Multicast Storm Control Threshold */ /* These act per VF so an array friendly macro is used */ -#define E1000_V2PMAILBOX(_n) (0x00C40 + (4 * (_n))) -#define E1000_P2VMAILBOX(_n) (0x00C00 + (4 * (_n))) -#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 */ -#define E1000_VMVIR(_n) (0x03700 + (4 * (_n))) -#define E1000_DVMOLR(_n) (0x0C038 + (0x40 * (_n))) /* DMA VM offload */ -/* Time Sync */ -#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 */ -#define E1000_RXSTMPL 0x0B624 /* Rx timestamp Low - RO */ -#define E1000_RXSTMPH 0x0B628 /* Rx timestamp High - RO */ -#define E1000_RXSATRL 0x0B62C /* Rx timestamp attribute low - RO */ -#define E1000_RXSATRH 0x0B630 /* Rx timestamp attribute high - RO */ -#define E1000_TXSTMPL 0x0B618 /* Tx timestamp value Low - RO */ -#define E1000_TXSTMPH 0x0B61C /* Tx timestamp value High - RO */ -#define E1000_SYSTIML 0x0B600 /* System time register Low - RO */ -#define E1000_SYSTIMH 0x0B604 /* System time register High - RO */ -#define E1000_TIMINCA 0x0B608 /* Increment attributes register - RW */ -#define E1000_TSAUXC 0x0B640 /* Timesync Auxiliary Control register */ -#define E1000_SYSTIMR 0x0B6F8 /* System time register Residue */ -#define E1000_RXMTRL 0x0B634 /* Time sync Rx EtherType and Msg Type - RW */ -#define E1000_RXUDP 0x0B638 /* Time Sync Rx UDP Port - RW */ +#define E1000_V2PMAILBOX(_n) (0x00C40 + (4 * (_n))) +#define E1000_P2VMAILBOX(_n) (0x00C00 + (4 * (_n))) +#define E1000_VMBMEM(_n) (0x00800 + (64 * (_n))) +#define E1000_VFVMBMEM(_n) (0x00800 + (_n)) +#define E1000_VMOLR(_n) (0x05AD0 + (4 * (_n))) +/* 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 */ +#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 */ +#define E1000_RXSTMPL 0x0B624 /* Rx timestamp Low - RO */ +#define E1000_RXSTMPH 0x0B628 /* Rx timestamp High - RO */ +#define E1000_RXSATRL 0x0B62C /* Rx timestamp attribute low - RO */ +#define E1000_RXSATRH 0x0B630 /* Rx timestamp attribute high - RO */ +#define E1000_TXSTMPL 0x0B618 /* Tx timestamp value Low - RO */ +#define E1000_TXSTMPH 0x0B61C /* Tx timestamp value High - RO */ +#define E1000_SYSTIML 0x0B600 /* System time register Low - RO */ +#define E1000_SYSTIMH 0x0B604 /* System time register High - RO */ +#define E1000_TIMINCA 0x0B608 /* Increment attributes register - RW */ +#define E1000_TSAUXC 0x0B640 /* Timesync Auxiliary Control register */ +#define E1000_SYSTIMR 0x0B6F8 /* System time register Residue */ +#define E1000_RXMTRL 0x0B634 /* Time sync Rx EtherType and Msg Type - RW */ +#define E1000_RXUDP 0x0B638 /* Time Sync Rx UDP Port - RW */ /* Filtering Registers */ -#define E1000_SAQF(_n) (0x05980 + (4 * (_n))) /* Source Address Queue Fltr */ -#define E1000_DAQF(_n) (0x059A0 + (4 * (_n))) /* Dest Address Queue Fltr */ -#define E1000_SPQF(_n) (0x059C0 + (4 * (_n))) /* Source Port Queue Fltr */ -#define E1000_FTQF(_n) (0x059E0 + (4 * (_n))) /* 5-tuple Queue Fltr */ -#define E1000_TTQF(_n) (0x059E0 + (4 * (_n))) /* 2-tuple Queue Fltr */ -#define E1000_SYNQF(_n) (0x055FC + (4 * (_n))) /* SYN Packet Queue Fltr */ -#define E1000_ETQF(_n) (0x05CB0 + (4 * (_n))) /* EType Queue Fltr */ +#define E1000_SAQF(_n) (0x05980 + (4 * (_n))) /* Source Address Queue Fltr */ +#define E1000_DAQF(_n) (0x059A0 + (4 * (_n))) /* Dest Address Queue Fltr */ +#define E1000_SPQF(_n) (0x059C0 + (4 * (_n))) /* Source Port Queue Fltr */ +#define E1000_FTQF(_n) (0x059E0 + (4 * (_n))) /* 5-tuple Queue Fltr */ +#define E1000_TTQF(_n) (0x059E0 + (4 * (_n))) /* 2-tuple Queue Fltr */ +#define E1000_SYNQF(_n) (0x055FC + (4 * (_n))) /* SYN Packet Queue Fltr */ +#define E1000_ETQF(_n) (0x05CB0 + (4 * (_n))) /* EType Queue Fltr */ -#define E1000_RTTDCS 0x3600 /* Reedtown Tx Desc plane control and status */ -#define E1000_RTTPCS 0x3474 /* Reedtown Tx Packet Plane control and status */ -#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 */ -#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 */ -#define E1000_RTTBCNRC 0x36B0 /* Tx BCN Rate-Scheduler Config */ -#define E1000_RTTBCNRS 0x36B4 /* Tx BCN Rate-Scheduler Status */ -#define E1000_RTTBCNCR 0xB200 /* Tx BCN Control Register */ -#define E1000_RTTBCNTG 0x35A4 /* Tx BCN Tagging */ -#define E1000_RTTBCNCP 0xB208 /* Tx BCN Congestion point */ -#define E1000_RTRBCNCR 0xB20C /* Rx BCN Control Register */ -#define E1000_RTTBCNRD 0x36B8 /* Tx BCN Rate Drift */ -#define E1000_PFCTOP 0x1080 /* Priority Flow Control Type and Opcode */ -#define E1000_RTTBCNIDX 0xB204 /* Tx BCN Congestion Point */ -#define E1000_RTTBCNACH 0x0B214 /* Tx BCN Control High */ -#define E1000_RTTBCNACL 0x0B210 /* Tx BCN Control Low */ +#define E1000_RTTDCS 0x3600 /* Reedtown Tx Desc plane control and status */ +#define E1000_RTTPCS 0x3474 /* Reedtown Tx Packet Plane control and status */ +#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 */ +/* 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 */ +#define E1000_RTTBCNRC 0x36B0 /* Tx BCN Rate-Scheduler Config */ +#define E1000_RTTBCNRS 0x36B4 /* Tx BCN Rate-Scheduler Status */ +#define E1000_RTTBCNCR 0xB200 /* Tx BCN Control Register */ +#define E1000_RTTBCNTG 0x35A4 /* Tx BCN Tagging */ +#define E1000_RTTBCNCP 0xB208 /* Tx BCN Congestion point */ +#define E1000_RTRBCNCR 0xB20C /* Rx BCN Control Register */ +#define E1000_RTTBCNRD 0x36B8 /* Tx BCN Rate Drift */ +#define E1000_PFCTOP 0x1080 /* Priority Flow Control Type and Opcode */ +#define E1000_RTTBCNIDX 0xB204 /* Tx BCN Congestion Point */ +#define E1000_RTTBCNACH 0x0B214 /* Tx BCN Control High */ +#define E1000_RTTBCNACL 0x0B210 /* Tx BCN Control Low */ /* DMA Coalescing registers */ -#define E1000_DMACR 0x02508 /* Control Register */ -#define E1000_DMCTXTH 0x03550 /* Transmit Threshold */ -#define E1000_DMCTLX 0x02514 /* Time to Lx Request */ -#define E1000_DMCRTRH 0x05DD0 /* Receive Packet Rate Threshold */ -#define E1000_DMCCNT 0x05DD4 /* Current Rx Count */ -#define E1000_FCRTC 0x02170 /* Flow Control Rx high watermark */ -#define E1000_PCIEMISC 0x05BB8 /* PCIE misc config register */ +#define E1000_DMACR 0x02508 /* Control Register */ +#define E1000_DMCTXTH 0x03550 /* Transmit Threshold */ +#define E1000_DMCTLX 0x02514 /* Time to Lx Request */ +#define E1000_DMCRTRH 0x05DD0 /* Receive Packet Rate Threshold */ +#define E1000_DMCCNT 0x05DD4 /* Current Rx Count */ +#define E1000_FCRTC 0x02170 /* Flow Control Rx high watermark */ +#define E1000_PCIEMISC 0x05BB8 /* PCIE misc config register */ /* PCIe Parity Status Register */ -#define E1000_PCIEERRSTS 0x05BA8 +#define E1000_PCIEERRSTS 0x05BA8 -#define E1000_PROXYS 0x5F64 /* Proxying Status */ -#define E1000_PROXYFC 0x5F60 /* Proxying Filter Control */ +#define E1000_PROXYS 0x5F64 /* Proxying Status */ +#define E1000_PROXYFC 0x5F60 /* Proxying Filter Control */ /* Thermal sensor configuration and status registers */ -#define E1000_THMJT 0x08100 /* Junction Temperature */ -#define E1000_THLOWTC 0x08104 /* Low Threshold Control */ -#define E1000_THMIDTC 0x08108 /* Mid Threshold Control */ -#define E1000_THHIGHTC 0x0810C /* High Threshold Control */ -#define E1000_THSTAT 0x08110 /* Thermal Sensor Status */ +#define E1000_THMJT 0x08100 /* Junction Temperature */ +#define E1000_THLOWTC 0x08104 /* Low Threshold Control */ +#define E1000_THMIDTC 0x08108 /* Mid Threshold Control */ +#define E1000_THHIGHTC 0x0810C /* High Threshold Control */ +#define E1000_THSTAT 0x08110 /* Thermal Sensor Status */ -/*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"*/ -#define E1000_EEE_SU 0x0E34 /* EEE Setup */ -#define E1000_TLPIC 0x4148 /* EEE Tx LPI Count - TLPIC */ -#define E1000_RLPIC 0x414C /* EEE Rx LPI Count - RLPIC */ +/* 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"*/ +#define E1000_EEE_SU 0x0E34 /* EEE Setup */ +#define E1000_TLPIC 0x4148 /* EEE Tx LPI Count - TLPIC */ +#define E1000_RLPIC 0x414C /* EEE Rx LPI Count - RLPIC */ /* OS2BMC Registers */ -#define E1000_B2OSPC 0x08FE0 /* BMC2OS packets sent by BMC */ -#define E1000_B2OGPRC 0x04158 /* BMC2OS packets received by host */ -#define E1000_O2BGPTC 0x08FE4 /* OS2BMC packets received by BMC */ -#define E1000_O2BSPC 0x0415C /* OS2BMC packets transmitted by host */ +#define E1000_B2OSPC 0x08FE0 /* BMC2OS packets sent by BMC */ +#define E1000_B2OGPRC 0x04158 /* BMC2OS packets received by host */ +#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 diff --git a/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_vf.c b/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_vf.c index be93eecc62a..d1286ad2a5f 100644 --- a/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_vf.c +++ b/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_vf.c @@ -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,27 +30,27 @@ 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" -static s32 e1000_init_phy_params_vf(struct e1000_hw *hw); -static s32 e1000_init_nvm_params_vf(struct e1000_hw *hw); -static void e1000_release_vf(struct e1000_hw *hw); -static s32 e1000_acquire_vf(struct e1000_hw *hw); -static s32 e1000_setup_link_vf(struct e1000_hw *hw); -static s32 e1000_get_bus_info_pcie_vf(struct e1000_hw *hw); -static s32 e1000_init_mac_params_vf(struct e1000_hw *hw); -static s32 e1000_check_for_link_vf(struct e1000_hw *hw); -static s32 e1000_get_link_up_info_vf(struct e1000_hw *hw, u16 *speed, - u16 *duplex); -static s32 e1000_init_hw_vf(struct e1000_hw *hw); -static s32 e1000_reset_hw_vf(struct e1000_hw *hw); -static void e1000_update_mc_addr_list_vf(struct e1000_hw *hw, u8 *, u32); -static void e1000_rar_set_vf(struct e1000_hw *, u8 *, u32); -static s32 e1000_read_mac_addr_vf(struct e1000_hw *); +static s32 e1000_init_phy_params_vf(struct e1000_hw *hw); +static s32 e1000_init_nvm_params_vf(struct e1000_hw *hw); +static void e1000_release_vf(struct e1000_hw *hw); +static s32 e1000_acquire_vf(struct e1000_hw *hw); +static s32 e1000_setup_link_vf(struct e1000_hw *hw); +static s32 e1000_get_bus_info_pcie_vf(struct e1000_hw *hw); +static s32 e1000_init_mac_params_vf(struct e1000_hw *hw); +static s32 e1000_check_for_link_vf(struct e1000_hw *hw); +static s32 e1000_get_link_up_info_vf(struct e1000_hw *hw, u16 *speed, + u16 *duplex); +static s32 e1000_init_hw_vf(struct e1000_hw *hw); +static s32 e1000_reset_hw_vf(struct e1000_hw *hw); +static void e1000_update_mc_addr_list_vf(struct e1000_hw *hw, u8 *, u32); +static void e1000_rar_set_vf(struct e1000_hw *, u8 *, u32); +static s32 e1000_read_mac_addr_vf(struct e1000_hw *); /** * e1000_init_phy_params_vf - Inits PHY params @@ -219,7 +219,7 @@ static s32 e1000_get_bus_info_pcie_vf(struct e1000_hw *hw) * the status register's data which is often stale and inaccurate. **/ static s32 e1000_get_link_up_info_vf(struct e1000_hw *hw, u16 *speed, - u16 *duplex) + u16 *duplex) { s32 status; @@ -288,7 +288,7 @@ static s32 e1000_reset_hw_vf(struct e1000_hw *hw) ret_val = mbx->ops.read_posted(hw, msgbuf, 3, 0); if (!ret_val) { if (msgbuf[0] == (E1000_VF_RESET | - E1000_VT_MSGTYPE_ACK)) + E1000_VT_MSGTYPE_ACK)) memcpy(hw->mac.perm_addr, addr, 6); else ret_val = -E1000_ERR_MAC_INIT; @@ -369,11 +369,22 @@ static u32 e1000_hash_mc_addr_vf(struct e1000_hw *hw, u8 *mc_addr) bit_shift++; hash_value = hash_mask & (((mc_addr[4] >> (8 - bit_shift)) | - (((u16) mc_addr[5]) << bit_shift))); + (((u16) mc_addr[5]) << bit_shift))); 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 @@ -384,9 +395,8 @@ static u32 e1000_hash_mc_addr_vf(struct e1000_hw *hw, u8 *mc_addr) * The caller must have a packed mc_addr_list of multicast addresses. **/ void e1000_update_mc_addr_list_vf(struct e1000_hw *hw, - u8 *mc_addr_list, u32 mc_addr_count) + 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); } /** diff --git a/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_vf.h b/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_vf.h index 591c09c8483..0ee73aec628 100644 --- a/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_vf.h +++ b/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_vf.h @@ -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_ diff --git a/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/if_em.c b/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/if_em.c index 625022c7c5f..856aac7da50 100644 --- a/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/if_em.c +++ b/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/if_em.c @@ -30,22 +30,19 @@ POSSIBILITY OF SUCH DAMAGE. ******************************************************************************/ -/*$FreeBSD: src/sys/dev/e1000/if_em.c,v 1.21.2.18.2.3 2011/01/25 23:20:22 jfv Exp $*/ +/*$FreeBSD$*/ #ifdef HAVE_KERNEL_OPTION_HEADERS #include "opt_device_polling.h" #include "opt_inet.h" +#include "opt_inet6.h" #endif #include #include - -#ifndef __HAIKU__ #if __FreeBSD_version >= 800000 #include #endif -#endif - #include #include #include @@ -81,11 +78,7 @@ #include #include - -#ifndef __HAIKU__ #include -#endif - #include #include @@ -101,7 +94,7 @@ int em_display_debug_stats = 0; /********************************************************************* * Driver version: *********************************************************************/ -char em_driver_version[] = "7.2.3"; +char em_driver_version[] = "7.3.2"; /********************************************************************* * PCI Device ID Table @@ -200,13 +193,14 @@ static int em_detach(device_t); static int em_shutdown(device_t); static int em_suspend(device_t); static int em_resume(device_t); -static void em_start(struct ifnet *); -static void em_start_locked(struct ifnet *, struct tx_ring *); #ifdef EM_MULTIQUEUE static int em_mq_start(struct ifnet *, struct mbuf *); static int em_mq_start_locked(struct ifnet *, struct tx_ring *, struct mbuf *); static void em_qflush(struct ifnet *); +#else +static void em_start(struct ifnet *); +static void em_start_locked(struct ifnet *, struct tx_ring *); #endif static int em_ioctl(struct ifnet *, u_long, caddr_t); static void em_init(void *); @@ -241,7 +235,7 @@ static void em_enable_intr(struct adapter *); static void em_disable_intr(struct adapter *); static void em_update_stats_counters(struct adapter *); static void em_add_hw_stats(struct adapter *adapter); -static bool em_txeof(struct tx_ring *); +static void em_txeof(struct tx_ring *); static bool em_rxeof(struct rx_ring *, int, int *); #ifndef __NO_STRICT_ALIGNMENT static int em_fixup_rx(struct rx_ring *); @@ -294,6 +288,8 @@ static void em_handle_link(void *context, int pending); static void em_set_sysctl_value(struct adapter *, const char *, const char *, int *, int); +static int em_set_flowcntl(SYSCTL_HANDLER_ARGS); +static int em_sysctl_eee(SYSCTL_HANDLER_ARGS); static __inline void em_rx_discard(struct rx_ring *, int); @@ -338,7 +334,7 @@ MODULE_DEPEND(em, ether, 1, 1, 1); #define CSUM_TSO 0 #endif -SYSCTL_NODE(_hw, OID_AUTO, em, CTLFLAG_RD, 0, "EM driver parameters"); +static SYSCTL_NODE(_hw, OID_AUTO, em, CTLFLAG_RD, 0, "EM driver parameters"); static int em_tx_int_delay_dflt = EM_TICKS_TO_USECS(EM_TIDV); static int em_rx_int_delay_dflt = EM_TICKS_TO_USECS(EM_RDTR); @@ -390,16 +386,11 @@ static int em_rx_process_limit = 100; TUNABLE_INT("hw.em.rx_process_limit", &em_rx_process_limit); SYSCTL_INT(_hw_em, OID_AUTO, rx_process_limit, CTLFLAG_RDTUN, &em_rx_process_limit, 0, - "Maximum number of received packets to process at a time, -1 means unlimited"); - -/* Flow control setting - default to FULL */ -static int em_fc_setting = e1000_fc_full; -TUNABLE_INT("hw.em.fc_setting", &em_fc_setting); -SYSCTL_INT(_hw_em, OID_AUTO, fc_setting, CTLFLAG_RDTUN, &em_fc_setting, 0, - "Flow control"); + "Maximum number of received packets to process " + "at a time, -1 means unlimited"); /* Energy efficient ethernet - default to OFF */ -static int eee_setting = 0; +static int eee_setting = 1; TUNABLE_INT("hw.em.eee_setting", &eee_setting); SYSCTL_INT(_hw_em, OID_AUTO, eee_setting, CTLFLAG_RDTUN, &eee_setting, 0, "Enable Energy Efficient Ethernet"); @@ -407,6 +398,10 @@ SYSCTL_INT(_hw_em, OID_AUTO, eee_setting, CTLFLAG_RDTUN, &eee_setting, 0, /* Global used in WOL setup with multiport cards */ static int global_quad_port_a = 0; +#ifdef DEV_NETMAP /* see ixgbe.c for details */ +#include +#endif /* DEV_NETMAP */ + /********************************************************************* * Device identification routine * @@ -477,6 +472,11 @@ em_attach(device_t dev) INIT_DEBUGOUT("em_attach: begin"); + if (resource_disabled("em", 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; hw = &adapter->hw; @@ -493,6 +493,11 @@ em_attach(device_t dev) OID_AUTO, "debug", CTLTYPE_INT|CTLFLAG_RW, adapter, 0, em_sysctl_debug_info, "I", "Debug Information"); + SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev), + SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), + OID_AUTO, "fc", CTLTYPE_INT|CTLFLAG_RW, adapter, 0, + em_set_flowcntl, "I", "Flow Control"); + callout_init_mtx(&adapter->timer, &adapter->core_mtx, 0); /* Determine hardware and mac info */ @@ -564,11 +569,6 @@ em_attach(device_t dev) "max number of rx packets to process", &adapter->rx_process_limit, em_rx_process_limit); - /* Sysctl for setting the interface flow control */ - em_set_sysctl_value(adapter, "flow_control", - "configure flow control", - &adapter->fc_setting, em_fc_setting); - /* * Validate number of transmit and receive descriptors. It * must not exceed hardware maximum, and must be multiple @@ -637,9 +637,12 @@ em_attach(device_t dev) " due to SOL/IDER session.\n"); /* Sysctl for setting Energy Efficient Ethernet */ - em_set_sysctl_value(adapter, "eee_control", - "enable Energy Efficient Ethernet", - &hw->dev_spec.ich8lan.eee_disable, eee_setting); + hw->dev_spec.ich8lan.eee_disable = eee_setting; + SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev), + SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), + OID_AUTO, "eee_control", CTLTYPE_INT|CTLFLAG_RW, + adapter, 0, em_sysctl_eee, "I", + "Disable Energy Efficient Ethernet"); /* ** Start from a known state, this is @@ -718,12 +721,14 @@ em_attach(device_t dev) em_get_hw_control(adapter); /* Tell the stack that the interface is not active */ - adapter->ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); + adapter->ifp->if_drv_flags &= ~IFF_DRV_RUNNING; + adapter->ifp->if_drv_flags |= IFF_DRV_OACTIVE; -#ifndef __HAIKU__ adapter->led_dev = led_create(em_led_func, adapter, device_get_nameunit(dev)); -#endif +#ifdef DEV_NETMAP + em_netmap_attach(adapter); +#endif /* DEV_NETMAP */ INIT_DEBUGOUT("em_attach: end"); @@ -772,10 +777,8 @@ em_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); adapter->in_detach = 1; @@ -797,6 +800,10 @@ em_detach(device_t dev) ether_ifdetach(adapter->ifp); callout_drain(&adapter->timer); +#ifdef DEV_NETMAP + netmap_detach(ifp); +#endif /* DEV_NETMAP */ + em_free_pci_resources(adapter); bus_generic_detach(dev); if_free(ifp); @@ -845,29 +852,44 @@ static int em_resume(device_t dev) { struct adapter *adapter = device_get_softc(dev); + struct tx_ring *txr = adapter->tx_rings; struct ifnet *ifp = adapter->ifp; EM_CORE_LOCK(adapter); + if (adapter->hw.mac.type == e1000_pch2lan) + e1000_resume_workarounds_pchlan(&adapter->hw); em_init_locked(adapter); em_init_manageability(adapter); + + if ((ifp->if_flags & IFF_UP) && + (ifp->if_drv_flags & IFF_DRV_RUNNING) && adapter->link_active) { + for (int i = 0; i < adapter->num_queues; i++, txr++) { + EM_TX_LOCK(txr); +#ifdef EM_MULTIQUEUE + if (!drbr_empty(ifp, txr->br)) + em_mq_start_locked(ifp, txr, NULL); +#else + if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) + em_start_locked(ifp, txr); +#endif + EM_TX_UNLOCK(txr); + } + } EM_CORE_UNLOCK(adapter); - em_start(ifp); return bus_generic_resume(dev); } +#ifdef EM_MULTIQUEUE /********************************************************************* - * Transmit entry point + * Multiqueue Transmit routines * - * em_start is called by the stack to initiate a transmit. - * The driver will remain in this routine as long as there are - * packets to transmit and transmit resources are available. - * In case resources are not available stack is notified and - * the packet is requeued. + * em_mq_start is called by the stack to initiate a transmit. + * however, if busy the driver can queue the request rather + * than do an immediate send. It is this that is an advantage + * in this driver, rather than also having multiple tx queues. **********************************************************************/ - -#ifdef EM_MULTIQUEUE static int em_mq_start_locked(struct ifnet *ifp, struct tx_ring *txr, struct mbuf *m) { @@ -882,10 +904,6 @@ em_mq_start_locked(struct ifnet *ifp, struct tx_ring *txr, struct mbuf *m) return (err); } - /* Call cleanup if number of TX descriptors low */ - if (txr->tx_avail <= EM_TX_CLEANUP_THRESHOLD) - em_txeof(txr); - enq = 0; if (m == NULL) { next = drbr_dequeue(ifp, txr->br); @@ -908,10 +926,6 @@ em_mq_start_locked(struct ifnet *ifp, struct tx_ring *txr, struct mbuf *m) ETHER_BPF_MTAP(ifp, next); if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) break; - if (txr->tx_avail < EM_MAX_SCATTER) { - ifp->if_drv_flags |= IFF_DRV_OACTIVE; - break; - } next = drbr_dequeue(ifp, txr->br); } @@ -920,6 +934,11 @@ em_mq_start_locked(struct ifnet *ifp, struct tx_ring *txr, struct mbuf *m) txr->queue_status = EM_QUEUE_WORKING; txr->watchdog_time = ticks; } + + if (txr->tx_avail < EM_MAX_SCATTER) + em_txeof(txr); + if (txr->tx_avail < EM_MAX_SCATTER) + ifp->if_drv_flags |= IFF_DRV_OACTIVE; return (err); } @@ -960,8 +979,7 @@ em_qflush(struct ifnet *ifp) } if_qflush(ifp); } - -#endif /* EM_MULTIQUEUE */ +#else /* !EM_MULTIQUEUE */ static void em_start_locked(struct ifnet *ifp, struct tx_ring *txr) @@ -996,7 +1014,6 @@ em_start_locked(struct ifnet *ifp, struct tx_ring *txr) if (em_xmit(txr, &m_head)) { if (m_head == NULL) break; - ifp->if_drv_flags |= IFF_DRV_OACTIVE; IFQ_DRV_PREPEND(&ifp->if_snd, m_head); break; } @@ -1025,6 +1042,7 @@ em_start(struct ifnet *ifp) } return; } +#endif /* EM_MULTIQUEUE */ /********************************************************************* * Ioctl entry point @@ -1039,11 +1057,12 @@ static int em_ioctl(struct ifnet *ifp, u_long command, caddr_t data) { struct adapter *adapter = ifp->if_softc; - struct ifreq *ifr = (struct ifreq *)data; -#ifdef INET - struct ifaddr *ifa = (struct ifaddr *)data; + struct ifreq *ifr = (struct ifreq *)data; +#if defined(INET) || defined(INET6) + struct ifaddr *ifa = (struct ifaddr *)data; #endif - int error = 0; + bool avoid_reset = FALSE; + int error = 0; if (adapter->in_detach) return (error); @@ -1051,23 +1070,26 @@ em_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. - */ + 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)) { - EM_CORE_LOCK(adapter); - em_init_locked(adapter); - EM_CORE_UNLOCK(adapter); - } - arp_ifinit(ifp, ifa); - } else + if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) + em_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: @@ -1084,6 +1106,7 @@ em_ioctl(struct ifnet *ifp, u_long command, caddr_t data) case e1000_ich10lan: case e1000_pch2lan: case e1000_82574: + case e1000_82583: case e1000_80003es2lan: /* 9K Jumbo Frame size */ max_frame_size = 9234; break; @@ -1091,7 +1114,6 @@ em_ioctl(struct ifnet *ifp, u_long command, caddr_t data) max_frame_size = 4096; break; /* Adapters that do not support jumbo frames */ - case e1000_82583: case e1000_ich8lan: max_frame_size = ETHER_MAX_LEN; break; @@ -1146,11 +1168,6 @@ em_ioctl(struct ifnet *ifp, u_long command, caddr_t data) } break; case SIOCSIFMEDIA: - /* - ** As the speed/duplex settings are being - ** changed, we need to reset the PHY. - */ - adapter->hw.phy.reset_disable = FALSE; /* Check SOL/IDER usage */ EM_CORE_LOCK(adapter); if (e1000_check_reset_block(&adapter->hw)) { @@ -1209,6 +1226,10 @@ em_ioctl(struct ifnet *ifp, u_long command, caddr_t data) ifp->if_capenable ^= IFCAP_VLAN_HWFILTER; reinit = 1; } + if (mask & IFCAP_VLAN_HWTSO) { + ifp->if_capenable ^= IFCAP_VLAN_HWTSO; + reinit = 1; + } if ((mask & IFCAP_WOL) && (ifp->if_capabilities & IFCAP_WOL) != 0) { if (mask & IFCAP_WOL_MCAST) @@ -1247,7 +1268,6 @@ em_init_locked(struct adapter *adapter) { struct ifnet *ifp = adapter->ifp; device_t dev = adapter->dev; - u32 pba; INIT_DEBUGOUT("em_init: begin"); @@ -1256,46 +1276,6 @@ em_init_locked(struct adapter *adapter) em_disable_intr(adapter); callout_stop(&adapter->timer); - /* - * Packet Buffer Allocation (PBA) - * Writing PBA sets the receive portion of the buffer - * the remainder is used for the transmit buffer. - */ - switch (adapter->hw.mac.type) { - /* Total Packet Buffer on these is 48K */ - case e1000_82571: - case e1000_82572: - case e1000_80003es2lan: - pba = E1000_PBA_32K; /* 32K for Rx, 16K for Tx */ - break; - case e1000_82573: /* 82573: Total Packet Buffer is 32K */ - pba = E1000_PBA_12K; /* 12K for Rx, 20K for Tx */ - break; - case e1000_82574: - case e1000_82583: - pba = E1000_PBA_20K; /* 20K for Rx, 20K for Tx */ - break; - case e1000_ich8lan: - pba = E1000_PBA_8K; - break; - case e1000_ich9lan: - case e1000_ich10lan: - pba = E1000_PBA_10K; - break; - case e1000_pchlan: - case e1000_pch2lan: - pba = E1000_PBA_26K; - break; - default: - if (adapter->max_frame_size > 8192) - pba = E1000_PBA_40K; /* 40K for Rx, 24K for Tx */ - else - pba = E1000_PBA_48K; /* 48K for Rx, 16K for Tx */ - } - - INIT_DEBUGOUT1("em_init: pba=%dK",pba); - E1000_WRITE_REG(&adapter->hw, E1000_PBA, pba); - /* Get the latest mac address, User can use a LAA */ bcopy(IF_LLADDR(adapter->ifp), adapter->hw.mac.addr, ETHER_ADDR_LEN); @@ -1374,6 +1354,7 @@ em_init_locked(struct adapter *adapter) /* Don't lose promiscuous settings */ em_set_promisc(adapter); + /* Set the interface as ACTIVE */ ifp->if_drv_flags |= IFF_DRV_RUNNING; ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; @@ -1404,9 +1385,6 @@ em_init_locked(struct adapter *adapter) /* AMT based hardware can now take control from firmware */ if (adapter->has_manage && adapter->has_amt) em_get_hw_control(adapter); - - /* Don't reset the phy next time init gets called */ - adapter->hw.phy.reset_disable = TRUE; } static void @@ -1461,7 +1439,8 @@ em_poll(struct ifnet *ifp, enum poll_cmd cmd, int count) if (!drbr_empty(ifp, txr->br)) em_mq_start_locked(ifp, txr, NULL); #else - em_start_locked(ifp, txr); + if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) + em_start_locked(ifp, txr); #endif EM_TX_UNLOCK(txr); @@ -1534,10 +1513,11 @@ em_handle_que(void *context, int pending) if (!drbr_empty(ifp, txr->br)) em_mq_start_locked(ifp, txr, NULL); #else - em_start_locked(ifp, txr); + if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) + em_start_locked(ifp, txr); #endif EM_TX_UNLOCK(txr); - if (more || (ifp->if_drv_flags & IFF_DRV_OACTIVE)) { + if (more) { taskqueue_enqueue(adapter->tq, &adapter->que_task); return; } @@ -1558,17 +1538,21 @@ em_msix_tx(void *arg) { struct tx_ring *txr = arg; struct adapter *adapter = txr->adapter; - bool more; + struct ifnet *ifp = adapter->ifp; ++txr->tx_irq; EM_TX_LOCK(txr); - more = em_txeof(txr); + em_txeof(txr); +#ifdef EM_MULTIQUEUE + if (!drbr_empty(ifp, txr->br)) + em_mq_start_locked(ifp, txr, NULL); +#else + if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) + em_start_locked(ifp, txr); +#endif + /* Reenable this interrupt */ + E1000_WRITE_REG(&adapter->hw, E1000_IMS, txr->ims); EM_TX_UNLOCK(txr); - if (more) - taskqueue_enqueue(txr->tq, &txr->tx_task); - else - /* Reenable this interrupt */ - E1000_WRITE_REG(&adapter->hw, E1000_IMS, txr->ims); return; } @@ -1646,7 +1630,8 @@ em_handle_tx(void *context, int pending) if (!drbr_empty(ifp, txr->br)) em_mq_start_locked(ifp, txr, NULL); #else - em_start_locked(ifp, txr); + if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) + em_start_locked(ifp, txr); #endif E1000_WRITE_REG(&adapter->hw, E1000_IMS, txr->ims); EM_TX_UNLOCK(txr); @@ -1656,6 +1641,7 @@ static void em_handle_link(void *context, int pending) { struct adapter *adapter = context; + struct tx_ring *txr = adapter->tx_rings; struct ifnet *ifp = adapter->ifp; if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) @@ -1667,6 +1653,19 @@ em_handle_link(void *context, int pending) callout_reset(&adapter->timer, hz, em_local_timer, adapter); E1000_WRITE_REG(&adapter->hw, E1000_IMS, EM_MSIX_LINK | E1000_IMS_LSC); + if (adapter->link_active) { + for (int i = 0; i < adapter->num_queues; i++, txr++) { + EM_TX_LOCK(txr); +#ifdef EM_MULTIQUEUE + if (!drbr_empty(ifp, txr->br)) + em_mq_start_locked(ifp, txr, NULL); +#else + if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) + em_start_locked(ifp, txr); +#endif + EM_TX_UNLOCK(txr); + } + } EM_CORE_UNLOCK(adapter); } @@ -1996,6 +1995,14 @@ em_xmit(struct tx_ring *txr, struct mbuf **m_headp) em_transmit_checksum_setup(txr, m_head, ip_off, ip, &txd_upper, &txd_lower); + if (m_head->m_flags & M_VLANTAG) { + /* Set the vlan id. */ + txd_upper |= + (htole16(m_head->m_pkthdr.ether_vtag) << 16); + /* Tell hardware to add tag */ + txd_lower |= htole32(E1000_TXD_CMD_VLE); + } + i = txr->next_avail_desc; /* Set up our transmit descriptors */ @@ -2053,15 +2060,13 @@ em_xmit(struct tx_ring *txr, struct mbuf **m_headp) if (tso_desc) /* TSO used an extra for sentinel */ txr->tx_avail -= txd_used; - if (m_head->m_flags & M_VLANTAG) { - /* Set the vlan id. */ - ctxd->upper.fields.special = - htole16(m_head->m_pkthdr.ether_vtag); - /* Tell hardware to add tag */ - ctxd->lower.data |= htole32(E1000_TXD_CMD_VLE); - } - tx_buffer->m_head = m_head; + /* + ** Here we swap the map so the last descriptor, + ** which gets the completion interrupt has the + ** real map, and the first descriptor gets the + ** unused map from this descriptor. + */ tx_buffer_mapped->map = tx_buffer->map; tx_buffer->map = map; bus_dmamap_sync(txr->txtag, map, BUS_DMASYNC_PREWRITE); @@ -2214,7 +2219,6 @@ em_local_timer(void *arg) struct tx_ring *txr = adapter->tx_rings; struct rx_ring *rxr = adapter->rx_rings; u32 trigger; - int i = 0; EM_CORE_LOCK_ASSERT(adapter); @@ -2232,22 +2236,21 @@ em_local_timer(void *arg) else trigger = E1000_ICS_RXDMT0; - /* - ** Don't do TX watchdog check if we've been paused - */ - if (adapter->pause_frames) { - adapter->pause_frames = 0; - goto out; - } /* ** Check on the state of the TX queue(s), this ** can be done without the lock because its RO ** and the HUNG state will be static if set. */ - for (i = 0; i < adapter->num_queues; i++, txr++) - if (txr->queue_status == EM_QUEUE_HUNG) + for (int i = 0; i < adapter->num_queues; i++, txr++) { + if ((txr->queue_status == EM_QUEUE_HUNG) && + (adapter->pause_frames == 0)) goto hung; -out: + /* Schedule a TX tasklet if needed */ + if (txr->tx_avail <= EM_MAX_SCATTER) + taskqueue_enqueue(txr->tq, &txr->tx_task); + } + + adapter->pause_frames = 0; callout_reset(&adapter->timer, hz, em_local_timer, adapter); #ifndef DEVICE_POLLING /* Trigger an RX interrupt to guarantee mbuf refresh */ @@ -2266,6 +2269,7 @@ em_local_timer(void *arg) txr->me, txr->tx_avail, txr->next_to_clean); ifp->if_drv_flags &= ~IFF_DRV_RUNNING; adapter->watchdog_events++; + adapter->pause_frames = 0; em_init_locked(adapter); } @@ -2328,14 +2332,13 @@ em_update_link_status(struct adapter *adapter) ifp->if_baudrate = adapter->link_speed * 1000000; if_link_state_change(ifp, LINK_STATE_UP); } else if (!link_check && (adapter->link_active == 1)) { - int i = 0; ifp->if_baudrate = adapter->link_speed = 0; adapter->link_duplex = 0; if (bootverbose) device_printf(dev, "Link is Down\n"); adapter->link_active = 0; /* Link down, disable watchdog */ - for (i = 0; i < adapter->num_queues; i++, txr++) + for (int i = 0; i < adapter->num_queues; i++, txr++) txr->queue_status = EM_QUEUE_IDLE; if_link_state_change(ifp, LINK_STATE_DOWN); } @@ -2356,7 +2359,6 @@ em_stop(void *arg) struct adapter *adapter = arg; struct ifnet *ifp = adapter->ifp; struct tx_ring *txr = adapter->tx_rings; - int i = 0; EM_CORE_LOCK_ASSERT(adapter); @@ -2366,10 +2368,11 @@ em_stop(void *arg) callout_stop(&adapter->timer); /* Tell the stack that the interface is no longer active */ - ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); + ifp->if_drv_flags &= ~IFF_DRV_RUNNING; + ifp->if_drv_flags |= IFF_DRV_OACTIVE; /* Unarm watchdog timer. */ - for (i = 0; i < adapter->num_queues; i++, txr++) { + for (int i = 0; i < adapter->num_queues; i++, txr++) { EM_TX_LOCK(txr); txr->queue_status = EM_QUEUE_IDLE; EM_TX_UNLOCK(txr); @@ -2462,6 +2465,7 @@ int em_allocate_legacy(struct adapter *adapter) { device_t dev = adapter->dev; + struct tx_ring *txr = adapter->tx_rings; int error, rid = 0; /* Manually turn off all interrupts */ @@ -2483,11 +2487,17 @@ em_allocate_legacy(struct adapter *adapter) * deferred processing contexts. */ TASK_INIT(&adapter->que_task, 0, em_handle_que, adapter); - TASK_INIT(&adapter->link_task, 0, em_handle_link, adapter); adapter->tq = taskqueue_create_fast("em_taskq", M_NOWAIT, taskqueue_thread_enqueue, &adapter->tq); - taskqueue_start_threads(&adapter->tq, 1, PI_NET, "%s taskq", + taskqueue_start_threads(&adapter->tq, 1, PI_NET, "%s que", + device_get_nameunit(adapter->dev)); + /* Use a TX only tasklet for local timer */ + TASK_INIT(&txr->tx_task, 0, em_handle_tx, txr); + txr->tq = taskqueue_create_fast("em_txq", M_NOWAIT, + taskqueue_thread_enqueue, &txr->tq); + taskqueue_start_threads(&txr->tq, 1, PI_NET, "%s txq", device_get_nameunit(adapter->dev)); + TASK_INIT(&adapter->link_task, 0, em_handle_link, adapter); if ((error = bus_setup_intr(dev, adapter->res, INTR_TYPE_NET, em_irq_fast, NULL, adapter, &adapter->tag)) != 0) { device_printf(dev, "Failed to register fast interrupt " @@ -2504,7 +2514,8 @@ em_allocate_legacy(struct adapter *adapter) * * Setup the MSIX Interrupt handlers * This is not really Multiqueue, rather - * its just multiple interrupt vectors. + * its just seperate interrupt vectors + * for TX, RX, and Link. * **********************************************************************/ int @@ -2513,14 +2524,14 @@ em_allocate_msix(struct adapter *adapter) device_t dev = adapter->dev; struct tx_ring *txr = adapter->tx_rings; struct rx_ring *rxr = adapter->rx_rings; - int error, rid, vector = 0, i = 0; + int error, rid, vector = 0; /* Make sure all interrupts are disabled */ E1000_WRITE_REG(&adapter->hw, E1000_IMC, 0xffffffff); /* First set up ring resources */ - for (i = 0; i < adapter->num_queues; i++, txr++, rxr++) { + for (int i = 0; i < adapter->num_queues; i++, txr++, rxr++) { /* RX ring */ rid = vector + 1; @@ -2628,13 +2639,12 @@ em_free_pci_resources(struct adapter *adapter) struct tx_ring *txr; struct rx_ring *rxr; int rid; - int i = 0; /* ** Release all the queue interrupt resources: */ - for (i = 0; i < adapter->num_queues; i++) { + for (int i = 0; i < adapter->num_queues; i++) { txr = &adapter->tx_rings[i]; rxr = &adapter->rx_rings[i]; /* an early abort? */ @@ -2697,7 +2707,6 @@ em_setup_msix(struct adapter *adapter) device_t dev = adapter->dev; int val = 0; - /* ** Setup MSI/X for Hartwell: tests have shown ** use of two queues to be unstable, and to @@ -2717,16 +2726,18 @@ em_setup_msix(struct adapter *adapter) goto msi; } val = pci_msix_count(dev); - if (val < 3) { + /* We only need 3 vectors */ + if (val > 3) + val = 3; + if ((val != 3) && (val != 5)) { bus_release_resource(dev, SYS_RES_MEMORY, PCIR_BAR(EM_MSIX_BAR), adapter->msix_mem); adapter->msix_mem = NULL; device_printf(adapter->dev, - "MSIX: insufficient vectors, using MSI\n"); + "MSIX: incorrect vectors, using MSI\n"); goto msi; } - val = 3; - adapter->num_queues = 1; + if (pci_alloc_msix(dev, &val) == 0) { device_printf(adapter->dev, "Using MSIX interrupts " @@ -2761,6 +2772,7 @@ em_reset(struct adapter *adapter) struct ifnet *ifp = adapter->ifp; struct e1000_hw *hw = &adapter->hw; u16 rx_buffer_size; + u32 pba; INIT_DEBUGOUT("em_reset: begin"); @@ -2775,6 +2787,48 @@ em_reset(struct adapter *adapter) e1000_write_phy_reg(hw, IGP02E1000_PHY_POWER_MGMT, phy_tmp); } + /* + * Packet Buffer Allocation (PBA) + * Writing PBA sets the receive portion of the buffer + * the remainder is used for the transmit buffer. + */ + switch (hw->mac.type) { + /* Total Packet Buffer on these is 48K */ + case e1000_82571: + case e1000_82572: + case e1000_80003es2lan: + pba = E1000_PBA_32K; /* 32K for Rx, 16K for Tx */ + break; + case e1000_82573: /* 82573: Total Packet Buffer is 32K */ + pba = E1000_PBA_12K; /* 12K for Rx, 20K for Tx */ + break; + case e1000_82574: + case e1000_82583: + pba = E1000_PBA_20K; /* 20K for Rx, 20K for Tx */ + break; + case e1000_ich8lan: + pba = E1000_PBA_8K; + break; + case e1000_ich9lan: + case e1000_ich10lan: + /* Boost Receive side for jumbo frames */ + if (adapter->max_frame_size > 4096) + pba = E1000_PBA_14K; + else + pba = E1000_PBA_10K; + break; + case e1000_pchlan: + case e1000_pch2lan: + pba = E1000_PBA_26K; + break; + default: + if (adapter->max_frame_size > 8192) + pba = E1000_PBA_40K; /* 40K for Rx, 24K for Tx */ + else + pba = E1000_PBA_48K; /* 48K for Rx, 16K for Tx */ + } + E1000_WRITE_REG(&adapter->hw, E1000_PBA, pba); + /* * These parameters control the automatic generation (Tx) and * response (Rx) to Ethernet PAUSE frames. @@ -2790,11 +2844,15 @@ em_reset(struct adapter *adapter) * - The pause time is fairly large at 1000 x 512ns = 512 usec. */ rx_buffer_size = ((E1000_READ_REG(hw, E1000_PBA) & 0xffff) << 10 ); - hw->fc.high_water = rx_buffer_size - roundup2(adapter->max_frame_size, 1024); hw->fc.low_water = hw->fc.high_water - 1500; + if (adapter->fc) /* locally set flow control value? */ + hw->fc.requested_mode = adapter->fc; + else + hw->fc.requested_mode = e1000_fc_full; + if (hw->mac.type == e1000_80003es2lan) hw->fc.pause_time = 0xFFFF; else @@ -2802,15 +2860,22 @@ em_reset(struct adapter *adapter) hw->fc.send_xon = TRUE; - /* Set Flow control, use the tunable location if sane */ - hw->fc.requested_mode = adapter->fc_setting; - - /* Workaround: no TX flow ctrl for PCH */ - if (hw->mac.type == e1000_pchlan) + /* Device specific overrides/settings */ + switch (hw->mac.type) { + case e1000_pchlan: + /* Workaround: no TX flow ctrl for PCH */ hw->fc.requested_mode = e1000_fc_rx_pause; - - /* Override - settings for PCH2LAN, ya its magic :) */ - if (hw->mac.type == e1000_pch2lan) { + hw->fc.pause_time = 0xFFFF; /* override */ + if (ifp->if_mtu > ETHERMTU) { + hw->fc.high_water = 0x3500; + hw->fc.low_water = 0x1500; + } else { + hw->fc.high_water = 0x5000; + hw->fc.low_water = 0x3000; + } + hw->fc.refresh_time = 0x1000; + break; + case e1000_pch2lan: hw->fc.high_water = 0x5C20; hw->fc.low_water = 0x5048; hw->fc.pause_time = 0x0650; @@ -2820,13 +2885,26 @@ em_reset(struct adapter *adapter) E1000_WRITE_REG(hw, E1000_PBA, 12); else E1000_WRITE_REG(hw, E1000_PBA, 26); + break; + case e1000_ich9lan: + case e1000_ich10lan: + if (ifp->if_mtu > ETHERMTU) { + hw->fc.high_water = 0x2800; + hw->fc.low_water = hw->fc.high_water - 8; + break; + } + /* else fall thru */ + default: + if (hw->mac.type == e1000_80003es2lan) + hw->fc.pause_time = 0xFFFF; + break; } /* Issue a global reset */ e1000_reset_hw(hw); E1000_WRITE_REG(hw, E1000_WUC, 0); em_disable_aspm(adapter); - + /* and a re-init */ if (e1000_init_hw(hw) < 0) { device_printf(dev, "Hardware Initialization Failed\n"); return; @@ -2856,43 +2934,40 @@ em_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 = em_init; ifp->if_softc = adapter; ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; ifp->if_ioctl = em_ioctl; +#ifdef EM_MULTIQUEUE + /* Multiqueue stack interface */ + ifp->if_transmit = em_mq_start; + ifp->if_qflush = em_qflush; +#else ifp->if_start = em_start; IFQ_SET_MAXLEN(&ifp->if_snd, adapter->num_tx_desc - 1); ifp->if_snd.ifq_drv_maxlen = adapter->num_tx_desc - 1; IFQ_SET_READY(&ifp->if_snd); +#endif ether_ifattach(ifp, adapter->hw.mac.addr); ifp->if_capabilities = ifp->if_capenable = 0; -#ifdef EM_MULTIQUEUE - /* Multiqueue tx functions */ - ifp->if_transmit = em_mq_start; - ifp->if_qflush = em_qflush; -#endif ifp->if_capabilities |= IFCAP_HWCSUM | IFCAP_VLAN_HWCSUM; - ifp->if_capenable |= IFCAP_HWCSUM | IFCAP_VLAN_HWCSUM; - - /* Enable TSO by default, can disable with ifconfig */ ifp->if_capabilities |= IFCAP_TSO4; - ifp->if_capenable |= IFCAP_TSO4; - /* * Tell the upper layer(s) we * support full VLAN capability */ ifp->if_data.ifi_hdrlen = sizeof(struct ether_vlan_header); - ifp->if_capabilities |= IFCAP_VLAN_HWTAGGING | IFCAP_VLAN_MTU; - ifp->if_capenable |= IFCAP_VLAN_HWTAGGING | IFCAP_VLAN_MTU; + ifp->if_capabilities |= IFCAP_VLAN_HWTAGGING + | IFCAP_VLAN_HWTSO + | IFCAP_VLAN_MTU; + ifp->if_capenable = ifp->if_capabilities; /* - ** Dont turn this on by default, if vlans are + ** Don't turn this on by default, if vlans are ** created on another pseudo device (eg. lagg) ** then vlan events are not passed thru, breaking ** operation, but with HW FILTER off it works. If @@ -3045,7 +3120,6 @@ em_allocate_queues(struct adapter *adapter) struct rx_ring *rxr = NULL; int rsize, tsize, error = E1000_SUCCESS; int txconf = 0, rxconf = 0; - int i = 0; /* Allocate the TX ring struct memory */ @@ -3073,7 +3147,7 @@ em_allocate_queues(struct adapter *adapter) * possibility that things fail midcourse and we need to * undo memory gracefully */ - for (i = 0; i < adapter->num_queues; i++, txconf++) { + for (int i = 0; i < adapter->num_queues; i++, txconf++) { /* Set up some basics */ txr = &adapter->tx_rings[i]; txr->adapter = adapter; @@ -3100,15 +3174,11 @@ em_allocate_queues(struct adapter *adapter) error = ENOMEM; goto err_tx_desc; } - -#ifndef __HAIKU__ #if __FreeBSD_version >= 800000 /* Allocate a buf ring */ txr->br = buf_ring_alloc(4096, M_DEVBUF, M_WAITOK, &txr->tx_mtx); #endif -#endif - } /* @@ -3116,7 +3186,7 @@ em_allocate_queues(struct adapter *adapter) */ rsize = roundup2(adapter->num_rx_desc * sizeof(struct e1000_rx_desc), EM_DBA_ALIGN); - for (i = 0; i < adapter->num_queues; i++, rxconf++) { + for (int i = 0; i < adapter->num_queues; i++, rxconf++) { rxr = &adapter->rx_rings[i]; rxr->adapter = adapter; rxr->me = i; @@ -3155,13 +3225,9 @@ em_allocate_queues(struct adapter *adapter) em_dma_free(adapter, &txr->txdma); free(adapter->rx_rings, M_DEVBUF); rx_fail: - -#ifndef __HAIKU__ #if __FreeBSD_version >= 800000 buf_ring_free(txr->br, M_DEVBUF); #endif -#endif - free(adapter->tx_rings, M_DEVBUF); fail: return (error); @@ -3238,9 +3304,17 @@ em_setup_transmit_ring(struct tx_ring *txr) struct adapter *adapter = txr->adapter; struct em_buffer *txbuf; int i; +#ifdef DEV_NETMAP + struct netmap_adapter *na = NA(adapter->ifp); + struct netmap_slot *slot; +#endif /* DEV_NETMAP */ /* Clear the old descriptor contents */ EM_TX_LOCK(txr); +#ifdef DEV_NETMAP + slot = netmap_reset(na, NR_TX, txr->me, 0); +#endif /* DEV_NETMAP */ + bzero((void *)txr->tx_base, (sizeof(struct e1000_tx_desc)) * adapter->num_tx_desc); /* Reset indices */ @@ -3257,6 +3331,19 @@ em_setup_transmit_ring(struct tx_ring *txr) m_freem(txbuf->m_head); txbuf->m_head = NULL; } +#ifdef DEV_NETMAP + if (slot) { + int si = netmap_idx_n2k(&na->tx_rings[txr->me], i); + uint64_t paddr; + void *addr; + + addr = PNMB(slot + si, &paddr); + txr->tx_base[i].buffer_addr = htole64(paddr); + /* reload the map for netmap mode */ + netmap_load_map(txr->txtag, txbuf->map, addr); + } +#endif /* DEV_NETMAP */ + /* clear the watch index */ txbuf->next_eop = -1; } @@ -3286,9 +3373,8 @@ static void em_setup_transmit_structures(struct adapter *adapter) { struct tx_ring *txr = adapter->tx_rings; - int i = 0; - for (i = 0; i < adapter->num_queues; i++, txr++) + for (int i = 0; i < adapter->num_queues; i++, txr++) em_setup_transmit_ring(txr); return; @@ -3305,11 +3391,10 @@ em_initialize_transmit_unit(struct adapter *adapter) struct tx_ring *txr = adapter->tx_rings; struct e1000_hw *hw = &adapter->hw; u32 tctl, tarc, tipg = 0; - int i = 0; INIT_DEBUGOUT("em_initialize_transmit_unit: begin"); - for (i = 0; i < adapter->num_queues; i++, txr++) { + for (int i = 0; i < adapter->num_queues; i++, txr++) { u64 bus_addr = txr->txdma.dma_paddr; /* Base and Len of TX Ring */ E1000_WRITE_REG(hw, E1000_TDLEN(i), @@ -3331,11 +3416,6 @@ em_initialize_transmit_unit(struct adapter *adapter) /* Set the default values for the Tx Inter Packet Gap timer */ switch (adapter->hw.mac.type) { - case e1000_82542: - tipg = DEFAULT_82542_TIPG_IPGT; - tipg |= DEFAULT_82542_TIPG_IPGR1 << E1000_TIPG_IPGR1_SHIFT; - tipg |= DEFAULT_82542_TIPG_IPGR2 << E1000_TIPG_IPGR2_SHIFT; - break; case e1000_80003es2lan: tipg = DEFAULT_82543_TIPG_IPGR1; tipg |= DEFAULT_80003ES2LAN_TIPG_IPGR2 << @@ -3401,9 +3481,8 @@ static void em_free_transmit_structures(struct adapter *adapter) { struct tx_ring *txr = adapter->tx_rings; - int i = 0; - for (i = 0; i < adapter->num_queues; i++, txr++) { + for (int i = 0; i < adapter->num_queues; i++, txr++) { EM_TX_LOCK(txr); em_free_transmit_buffers(txr); em_dma_free(adapter, &txr->txdma); @@ -3424,14 +3503,13 @@ em_free_transmit_buffers(struct tx_ring *txr) { struct adapter *adapter = txr->adapter; struct em_buffer *txbuf; - int i = 0; INIT_DEBUGOUT("free_transmit_ring: begin"); if (txr->tx_buffers == NULL) return; - for (i = 0; i < adapter->num_tx_desc; i++) { + for (int i = 0; i < adapter->num_tx_desc; i++) { txbuf = &txr->tx_buffers[i]; if (txbuf->m_head != NULL) { bus_dmamap_sync(txr->txtag, txbuf->map, @@ -3453,14 +3531,10 @@ em_free_transmit_buffers(struct tx_ring *txr) txbuf->map = NULL; } } - -#ifndef __HAIKU__ #if __FreeBSD_version >= 800000 if (txr->br != NULL) buf_ring_free(txr->br, M_DEVBUF); #endif -#endif - if (txr->tx_buffers != NULL) { free(txr->tx_buffers, M_DEVBUF); txr->tx_buffers = NULL; @@ -3705,7 +3779,7 @@ em_tso_setup(struct tx_ring *txr, struct mbuf *mp, int ip_off, * tx_buffer is put back on the free queue. * **********************************************************************/ -static bool +static void em_txeof(struct tx_ring *txr) { struct adapter *adapter = txr->adapter; @@ -3715,11 +3789,24 @@ em_txeof(struct tx_ring *txr) struct ifnet *ifp = adapter->ifp; EM_TX_LOCK_ASSERT(txr); +#ifdef DEV_NETMAP + if (ifp->if_capenable & IFCAP_NETMAP) { + struct netmap_adapter *na = NA(ifp); + + selwakeuppri(&na->tx_rings[txr->me].si, PI_NET); + EM_TX_UNLOCK(txr); + EM_CORE_LOCK(adapter); + selwakeuppri(&na->tx_si, PI_NET); + EM_CORE_UNLOCK(adapter); + EM_TX_LOCK(txr); + return; + } +#endif /* DEV_NETMAP */ /* No work, make sure watchdog is off */ if (txr->tx_avail == adapter->num_tx_desc) { txr->queue_status = EM_QUEUE_IDLE; - return (FALSE); + return; } processed = 0; @@ -3798,17 +3885,17 @@ em_txeof(struct tx_ring *txr) /* * If we have a minimum free, clear IFF_DRV_OACTIVE * to tell the stack that it is OK to send packets. + * Notice that all writes of OACTIVE happen under the + * TX lock which, with a single queue, guarantees + * sanity. */ - if (txr->tx_avail > EM_MAX_SCATTER) - ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; + if (txr->tx_avail >= EM_MAX_SCATTER) + ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; /* Disable watchdog if all clean */ if (txr->tx_avail == adapter->num_tx_desc) { txr->queue_status = EM_QUEUE_IDLE; - return (FALSE); } - - return (TRUE); } @@ -3906,7 +3993,6 @@ em_allocate_receive_buffers(struct rx_ring *rxr) device_t dev = adapter->dev; struct em_buffer *rxbuf; int error; - int i = 0; rxr->rx_buffers = malloc(sizeof(struct em_buffer) * adapter->num_rx_desc, M_DEVBUF, M_NOWAIT | M_ZERO); @@ -3934,7 +4020,7 @@ em_allocate_receive_buffers(struct rx_ring *rxr) } rxbuf = rxr->rx_buffers; - for (i = 0; i < adapter->num_rx_desc; i++, rxbuf++) { + for (int i = 0; i < adapter->num_rx_desc; i++, rxbuf++) { rxbuf = &rxr->rx_buffers[i]; error = bus_dmamap_create(rxr->rxtag, BUS_DMA_NOWAIT, &rxbuf->map); @@ -3964,26 +4050,52 @@ em_setup_receive_ring(struct rx_ring *rxr) struct adapter *adapter = rxr->adapter; struct em_buffer *rxbuf; bus_dma_segment_t seg[1]; - int i, j, nsegs, error = 0; + int rsize, nsegs, error = 0; +#ifdef DEV_NETMAP + struct netmap_adapter *na = NA(adapter->ifp); + struct netmap_slot *slot; +#endif /* Clear the ring contents */ EM_RX_LOCK(rxr); + rsize = roundup2(adapter->num_rx_desc * + sizeof(struct e1000_rx_desc), EM_DBA_ALIGN); + bzero((void *)rxr->rx_base, rsize); +#ifdef DEV_NETMAP + slot = netmap_reset(na, NR_RX, 0, 0); +#endif - /* Invalidate all descriptors */ - for (i = 0; i < adapter->num_rx_desc; i++) { - struct e1000_rx_desc* cur; - cur = &rxr->rx_base[i]; - cur->status = 0; + /* + ** Free current RX buffer structs and their mbufs + */ + for (int i = 0; i < adapter->num_rx_desc; i++) { + rxbuf = &rxr->rx_buffers[i]; + if (rxbuf->m_head != NULL) { + bus_dmamap_sync(rxr->rxtag, rxbuf->map, + BUS_DMASYNC_POSTREAD); + bus_dmamap_unload(rxr->rxtag, rxbuf->map); + m_freem(rxbuf->m_head); + rxbuf->m_head = NULL; /* mark as freed */ + } } /* Now replenish the mbufs */ - i = j = rxr->next_to_refresh; - if (++j == adapter->num_rx_desc) - j = 0; - - while (j != rxr->next_to_check) { - rxbuf = &rxr->rx_buffers[i]; + for (int j = 0; j != adapter->num_rx_desc; ++j) { + rxbuf = &rxr->rx_buffers[j]; +#ifdef DEV_NETMAP + if (slot) { + int si = netmap_idx_n2k(&na->rx_rings[rxr->me], j); + uint64_t paddr; + void *addr; + + addr = PNMB(slot + si, &paddr); + netmap_load_map(rxr->rxtag, rxbuf->map, addr); + /* Update descriptor */ + rxr->rx_base[j].buffer_addr = htole64(paddr); + continue; + } +#endif /* DEV_NETMAP */ rxbuf->m_head = m_getjcl(M_DONTWAIT, MT_DATA, M_PKTHDR, adapter->rx_mbuf_sz); if (rxbuf->m_head == NULL) { @@ -4007,16 +4119,14 @@ em_setup_receive_ring(struct rx_ring *rxr) rxbuf->map, BUS_DMASYNC_PREREAD); /* Update descriptor */ - rxr->rx_base[i].buffer_addr = htole64(seg[0].ds_addr); - i = j; - if (++j == adapter->num_rx_desc) - j = 0; + rxr->rx_base[j].buffer_addr = htole64(seg[0].ds_addr); } - -fail: - rxr->next_to_refresh = i; + rxr->next_to_check = 0; + rxr->next_to_refresh = 0; bus_dmamap_sync(rxr->rxdma.dma_tag, rxr->rxdma.dma_map, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); + +fail: EM_RX_UNLOCK(rxr); return (error); } @@ -4030,7 +4140,7 @@ static int em_setup_receive_structures(struct adapter *adapter) { struct rx_ring *rxr = adapter->rx_rings; - int q, i, n; + int q; for (q = 0; q < adapter->num_queues; q++, rxr++) if (em_setup_receive_ring(rxr)) @@ -4043,10 +4153,9 @@ em_setup_receive_structures(struct adapter *adapter) * the rings that completed, the failing case will have * cleaned up for itself. 'q' failed, so its the terminus. */ - for (i = 0, n = 0; i < q; ++i) { + for (int i = 0; i < q; ++i) { rxr = &adapter->rx_rings[i]; - n = rxr->next_to_check; - while(n != rxr->next_to_refresh) { + for (int n = 0; n < adapter->num_rx_desc; n++) { struct em_buffer *rxbuf; rxbuf = &rxr->rx_buffers[n]; if (rxbuf->m_head != NULL) { @@ -4056,8 +4165,6 @@ em_setup_receive_structures(struct adapter *adapter) m_freem(rxbuf->m_head); rxbuf->m_head = NULL; } - if (++n == adapter->num_rx_desc) - n = 0; } rxr->next_to_check = 0; rxr->next_to_refresh = 0; @@ -4075,9 +4182,8 @@ static void em_free_receive_structures(struct adapter *adapter) { struct rx_ring *rxr = adapter->rx_rings; - int i = 0; - for (i = 0; i < adapter->num_queues; i++, rxr++) { + for (int i = 0; i < adapter->num_queues; i++, rxr++) { em_free_receive_buffers(rxr); /* Free the ring memory as well */ em_dma_free(adapter, &rxr->rxdma); @@ -4098,13 +4204,11 @@ em_free_receive_buffers(struct rx_ring *rxr) { struct adapter *adapter = rxr->adapter; struct em_buffer *rxbuf = NULL; - int i = 0; INIT_DEBUGOUT("free_receive_buffers: begin"); if (rxr->rx_buffers != NULL) { - int i = rxr->next_to_check; - while(i != rxr->next_to_refresh) { + for (int i = 0; i < adapter->num_rx_desc; i++) { rxbuf = &rxr->rx_buffers[i]; if (rxbuf->map != NULL) { bus_dmamap_sync(rxr->rxtag, rxbuf->map, @@ -4116,8 +4220,6 @@ em_free_receive_buffers(struct rx_ring *rxr) m_freem(rxbuf->m_head); rxbuf->m_head = NULL; } - if (++i == adapter->num_rx_desc) - i = 0; } free(rxr->rx_buffers, M_DEVBUF); rxr->rx_buffers = NULL; @@ -4150,7 +4252,6 @@ em_initialize_receive_unit(struct adapter *adapter) struct e1000_hw *hw = &adapter->hw; u64 bus_addr; u32 rctl, rxcsum; - int i = 0; INIT_DEBUGOUT("em_initialize_receive_units: begin"); @@ -4159,7 +4260,9 @@ em_initialize_receive_unit(struct adapter *adapter) * up the descriptor ring */ rctl = E1000_READ_REG(hw, E1000_RCTL); - E1000_WRITE_REG(hw, E1000_RCTL, rctl & ~E1000_RCTL_EN); + /* Do not disable if ever enabled on this hardware */ + if ((hw->mac.type != e1000_82574) && (hw->mac.type != e1000_82583)) + E1000_WRITE_REG(hw, E1000_RCTL, rctl & ~E1000_RCTL_EN); E1000_WRITE_REG(&adapter->hw, E1000_RADV, adapter->rx_abs_int_delay.value); @@ -4173,14 +4276,13 @@ em_initialize_receive_unit(struct adapter *adapter) ** When using MSIX interrupts we need to throttle ** using the EITR register (82574 only) */ - if (hw->mac.type == e1000_82574) - for (i = 0; i < 4; i++) + if (hw->mac.type == e1000_82574) { + for (int i = 0; i < 4; i++) E1000_WRITE_REG(hw, E1000_EITR_82574(i), DEFAULT_ITR); - - /* Disable accelerated ackknowledge */ - if (adapter->hw.mac.type == e1000_82574) + /* Disable accelerated acknowledge */ E1000_WRITE_REG(hw, E1000_RFCTL, E1000_RFCTL_ACK_DIS); + } if (ifp->if_capenable & IFCAP_RXCSUM) { rxcsum = E1000_READ_REG(hw, E1000_RXCSUM); @@ -4198,7 +4300,7 @@ em_initialize_receive_unit(struct adapter *adapter) if (hw->mac.type == e1000_82573) E1000_WRITE_REG(hw, E1000_RDTR, 0x20); - for (i = 0; i < adapter->num_queues; i++, rxr++) { + for (int i = 0; i < adapter->num_queues; i++, rxr++) { /* Setup the Base and Length of the Rx Descriptor Ring */ bus_addr = rxr->rxdma.dma_paddr; E1000_WRITE_REG(hw, E1000_RDLEN(i), @@ -4206,18 +4308,32 @@ em_initialize_receive_unit(struct adapter *adapter) E1000_WRITE_REG(hw, E1000_RDBAH(i), (u32)(bus_addr >> 32)); E1000_WRITE_REG(hw, E1000_RDBAL(i), (u32)bus_addr); /* Setup the Head and Tail Descriptor Pointers */ - E1000_WRITE_REG(hw, E1000_RDH(i), rxr->next_to_check); - E1000_WRITE_REG(hw, E1000_RDT(i), rxr->next_to_refresh); + E1000_WRITE_REG(hw, E1000_RDH(i), 0); +#ifdef DEV_NETMAP + /* + * an init() while a netmap client is active must + * preserve the rx buffers passed to userspace. + * In this driver it means we adjust RDT to + * something different from na->num_rx_desc - 1. + */ + if (ifp->if_capenable & IFCAP_NETMAP) { + struct netmap_adapter *na = NA(adapter->ifp); + struct netmap_kring *kring = &na->rx_rings[i]; + int t = na->num_rx_desc - 1 - kring->nr_hwavail; + + E1000_WRITE_REG(hw, E1000_RDT(i), t); + } else +#endif /* DEV_NETMAP */ + E1000_WRITE_REG(hw, E1000_RDT(i), adapter->num_rx_desc - 1); } - /* Set early receive threshold on appropriate hw */ + /* Set PTHRESH for improved jumbo performance */ if (((adapter->hw.mac.type == e1000_ich9lan) || (adapter->hw.mac.type == e1000_pch2lan) || (adapter->hw.mac.type == e1000_ich10lan)) && (ifp->if_mtu > ETHERMTU)) { u32 rxdctl = E1000_READ_REG(hw, E1000_RXDCTL(0)); E1000_WRITE_REG(hw, E1000_RXDCTL(0), rxdctl | 3); - E1000_WRITE_REG(hw, E1000_ERT, 0x100 | (1 << 13)); } if (adapter->hw.mac.type == e1000_pch2lan) { @@ -4284,6 +4400,20 @@ em_rxeof(struct rx_ring *rxr, int count, int *done) EM_RX_LOCK(rxr); +#ifdef DEV_NETMAP + if (ifp->if_capenable & IFCAP_NETMAP) { + struct netmap_adapter *na = NA(ifp); + + na->rx_rings[rxr->me].nr_kflags |= NKR_PENDINTR; + selwakeuppri(&na->rx_rings[rxr->me].si, PI_NET); + EM_RX_UNLOCK(rxr); + EM_CORE_LOCK(adapter); + selwakeuppri(&na->rx_si, PI_NET); + EM_CORE_UNLOCK(adapter); + return (0); + } +#endif /* DEV_NETMAP */ + for (i = rxr->next_to_check, processed = 0; count != 0;) { if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) @@ -4347,14 +4477,9 @@ em_rxeof(struct rx_ring *rxr, int count, int *done) #endif if (status & E1000_RXD_STAT_VP) { sendmp->m_pkthdr.ether_vtag = - (le16toh(cur->special) & - E1000_RXD_SPC_VLAN_MASK); + le16toh(cur->special); sendmp->m_flags |= M_VLANTAG; } -#ifdef EM_MULTIQUEUE - sendmp->m_pkthdr.flowid = rxr->msix; - sendmp->m_flags |= M_FLOWID; -#endif #ifndef __NO_STRICT_ALIGNMENT skip: #endif @@ -4568,7 +4693,6 @@ em_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 @@ -4583,7 +4707,7 @@ em_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]); @@ -4830,7 +4954,7 @@ em_enable_wakeup(device_t dev) (adapter->hw.mac.type == e1000_pchlan) || (adapter->hw.mac.type == e1000_ich9lan) || (adapter->hw.mac.type == e1000_ich10lan)) - e1000_disable_gig_wol_ich8lan(&adapter->hw); + e1000_suspend_workarounds_ich8lan(&adapter->hw); /* Keep the laser running on Fiber adapters */ if (adapter->hw.phy.media_type == e1000_media_type_fiber || @@ -4887,13 +5011,12 @@ em_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 */ e1000_copy_rx_addrs_to_phy_ich8lan(hw); /* 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, @@ -5121,11 +5244,8 @@ em_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)); } @@ -5147,7 +5267,6 @@ em_add_hw_stats(struct adapter *adapter) struct sysctl_oid *stat_node, *queue_node, *int_node; struct sysctl_oid_list *stat_list, *queue_list, *int_list; - int i = 0; #define QUEUE_NAME_LEN 32 char namebuf[QUEUE_NAME_LEN]; @@ -5190,7 +5309,7 @@ em_add_hw_stats(struct adapter *adapter) CTLFLAG_RD, &adapter->hw.fc.low_water, 0, "Flow Control Low Watermark"); - for (i = 0; i < adapter->num_queues; i++, rxr++, txr++) { + for (int i = 0; i < adapter->num_queues; i++, rxr++, txr++) { snprintf(namebuf, QUEUE_NAME_LEN, "queue%d", i); queue_node = SYSCTL_ADD_NODE(ctx, child, OID_AUTO, namebuf, CTLFLAG_RD, NULL, "Queue Name"); @@ -5432,7 +5551,7 @@ em_add_hw_stats(struct adapter *adapter) static int em_sysctl_nvm_info(SYSCTL_HANDLER_ARGS) { - struct adapter *adapter; + struct adapter *adapter = (struct adapter *)arg1; int error; int result; @@ -5447,10 +5566,8 @@ em_sysctl_nvm_info(SYSCTL_HANDLER_ARGS) * first 32 16-bit words of the EEPROM to * the screen. */ - if (result == 1) { - adapter = (struct adapter *)arg1; + if (result == 1) em_print_nvm_info(adapter); - } return (error); } @@ -5540,6 +5657,70 @@ em_set_sysctl_value(struct adapter *adapter, const char *name, OID_AUTO, name, CTLTYPE_INT|CTLFLAG_RW, limit, value, description); } + +/* +** Set flow control using sysctl: +** Flow control values: +** 0 - off +** 1 - rx pause +** 2 - tx pause +** 3 - full +*/ +static int +em_set_flowcntl(SYSCTL_HANDLER_ARGS) +{ + int error; + static int input = 3; /* default is full */ + struct adapter *adapter = (struct adapter *) arg1; + + error = sysctl_handle_int(oidp, &input, 0, req); + + if ((error) || (req->newptr == NULL)) + return (error); + + if (input == adapter->fc) /* no change? */ + return (error); + + switch (input) { + case e1000_fc_rx_pause: + case e1000_fc_tx_pause: + case e1000_fc_full: + case e1000_fc_none: + adapter->hw.fc.requested_mode = input; + adapter->fc = input; + break; + default: + /* Do nothing */ + return (error); + } + + adapter->hw.fc.current_mode = adapter->hw.fc.requested_mode; + e1000_force_mac_fc(&adapter->hw); + return (error); +} + +/* +** Manage Energy Efficient Ethernet: +** Control values: +** 0/1 - enabled/disabled +*/ +static int +em_sysctl_eee(SYSCTL_HANDLER_ARGS) +{ + struct adapter *adapter = (struct adapter *) arg1; + int error, value; + + value = adapter->hw.dev_spec.ich8lan.eee_disable; + error = sysctl_handle_int(oidp, &value, 0, req); + if (error || req->newptr == NULL) + return (error); + EM_CORE_LOCK(adapter); + adapter->hw.dev_spec.ich8lan.eee_disable = (value != 0); + em_init_locked(adapter); + EM_CORE_UNLOCK(adapter); + return (0); +} + static int em_sysctl_debug_info(SYSCTL_HANDLER_ARGS) { @@ -5576,10 +5757,11 @@ em_print_debug_info(struct adapter *adapter) printf("Interface is RUNNING "); else printf("Interface is NOT RUNNING\n"); + if (adapter->ifp->if_drv_flags & IFF_DRV_OACTIVE) - printf("and ACTIVE\n"); - else printf("and INACTIVE\n"); + else + printf("and ACTIVE\n"); device_printf(dev, "hw tdh = %d, hw tdt = %d\n", E1000_READ_REG(&adapter->hw, E1000_TDH(0)), diff --git a/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/if_em.h b/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/if_em.h index 6b959af966b..f1afbadb32d 100644 --- a/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/if_em.h +++ b/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/if_em.h @@ -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; diff --git a/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/if_igb.c b/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/if_igb.c index 1c49a091cf8..26d09035862 100644 --- a/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/if_igb.c +++ b/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/if_igb.c @@ -1,6 +1,6 @@ /****************************************************************************** - Copyright (c) 2001-2011, 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/if_igb.c,v 1.21.2.18.2.1 2010/12/21 17:09:25 kensmith Exp $*/ +/*$FreeBSD$*/ #ifdef HAVE_KERNEL_OPTION_HEADERS @@ -100,7 +100,7 @@ int igb_display_debug_stats = 0; /********************************************************************* * Driver version: *********************************************************************/ -char igb_driver_version[] = "version - 2.2.5"; +char igb_driver_version[] = "version - 2.3.4"; /********************************************************************* @@ -150,6 +150,14 @@ static igb_vendor_info_t igb_vendor_info_array[] = { 0x8086, E1000_DEV_ID_I350_SERDES, PCI_ANY_ID, PCI_ANY_ID, 0}, { 0x8086, E1000_DEV_ID_I350_SGMII, PCI_ANY_ID, PCI_ANY_ID, 0}, { 0x8086, E1000_DEV_ID_I350_VF, PCI_ANY_ID, PCI_ANY_ID, 0}, + { 0x8086, E1000_DEV_ID_I210_COPPER, PCI_ANY_ID, PCI_ANY_ID, 0}, + { 0x8086, E1000_DEV_ID_I210_COPPER_IT, PCI_ANY_ID, PCI_ANY_ID, 0}, + { 0x8086, E1000_DEV_ID_I210_COPPER_OEM1, + PCI_ANY_ID, PCI_ANY_ID, 0}, + { 0x8086, E1000_DEV_ID_I210_FIBER, PCI_ANY_ID, PCI_ANY_ID, 0}, + { 0x8086, E1000_DEV_ID_I210_SERDES, PCI_ANY_ID, PCI_ANY_ID, 0}, + { 0x8086, E1000_DEV_ID_I210_SGMII, PCI_ANY_ID, PCI_ANY_ID, 0}, + { 0x8086, E1000_DEV_ID_I211_COPPER, PCI_ANY_ID, PCI_ANY_ID, 0}, /* required last entry */ { 0, 0, 0, 0, 0} }; @@ -225,8 +233,9 @@ static __inline void igb_rx_input(struct rx_ring *, static bool igb_rxeof(struct igb_queue *, int, int *); static void igb_rx_checksum(u32, struct mbuf *, u32); -static int igb_tx_ctx_setup(struct tx_ring *, struct mbuf *); -static bool igb_tso_setup(struct tx_ring *, struct mbuf *, u32 *); +static bool igb_tx_ctx_setup(struct tx_ring *, struct mbuf *); +static bool igb_tso_setup(struct tx_ring *, struct mbuf *, int, + struct ip *, struct tcphdr *); static void igb_set_promisc(struct adapter *); static void igb_disable_promisc(struct adapter *); static void igb_set_multi(struct adapter *); @@ -262,11 +271,13 @@ static void igb_msix_que(void *); static void igb_msix_link(void *); static void igb_handle_que(void *context, int pending); static void igb_handle_link(void *context, int pending); +static void igb_handle_link_locked(struct adapter *); static void igb_set_sysctl_value(struct adapter *, const char *, const char *, int *, int); static int igb_set_flowcntl(SYSCTL_HANDLER_ARGS); static int igb_sysctl_dmac(SYSCTL_HANDLER_ARGS); +static int igb_sysctl_eee(SYSCTL_HANDLER_ARGS); #ifdef DEVICE_POLLING static poll_handler_t igb_poll; @@ -300,7 +311,7 @@ MODULE_DEPEND(igb, ether, 1, 1, 1); * Tunable default values. *********************************************************************/ -SYSCTL_NODE(_hw, OID_AUTO, igb, CTLFLAG_RD, 0, "IGB driver parameters"); +static SYSCTL_NODE(_hw, OID_AUTO, igb, CTLFLAG_RD, 0, "IGB driver parameters"); /* Descriptor defaults */ static int igb_rxd = IGB_DEFAULT_RXD; @@ -348,7 +359,7 @@ SYSCTL_INT(_hw_igb, OID_AUTO, max_interrupt_rate, CTLFLAG_RDTUN, ** into the header and thus use no cluster. Its ** a very workload dependent type feature. */ -static bool igb_header_split = FALSE; +static int igb_header_split = FALSE; TUNABLE_INT("hw.igb.hdr_split", &igb_header_split); SYSCTL_INT(_hw_igb, OID_AUTO, header_split, CTLFLAG_RDTUN, &igb_header_split, 0, "Enable receive mbuf header split"); @@ -362,6 +373,13 @@ TUNABLE_INT("hw.igb.num_queues", &igb_num_queues); SYSCTL_INT(_hw_igb, OID_AUTO, num_queues, CTLFLAG_RDTUN, &igb_num_queues, 0, "Number of queues to configure, 0 indicates autoconfigure"); +/* +** Global variable to store last used CPU when binding queues +** to CPUs in igb_allocate_msix. Starts at CPU_FIRST and increments when a +** queue is bound to a cpu. +*/ +static int igb_last_bind_cpu = -1; + /* How many packets rxeof tries to clean at a time */ static int igb_rx_process_limit = 100; TUNABLE_INT("hw.igb.rx_process_limit", &igb_rx_process_limit); @@ -369,6 +387,9 @@ SYSCTL_INT(_hw_igb, OID_AUTO, rx_process_limit, CTLFLAG_RDTUN, &igb_rx_process_limit, 0, "Maximum number of received packets to process at a time, -1 means unlimited"); +#ifdef DEV_NETMAP /* see ixgbe.c for details */ +#include +#endif /* DEV_NETMAP */ /********************************************************************* * Device identification routine * @@ -566,11 +587,13 @@ igb_attach(device_t dev) SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, "dmac", CTLTYPE_INT|CTLFLAG_RW, adapter, 0, igb_sysctl_dmac, "I", "DMA Coalesce"); - igb_set_sysctl_value(adapter, "eee_disabled", - "enable Energy Efficient Ethernet", - &adapter->hw.dev_spec._82575.eee_disable, - TRUE); - e1000_set_eee_i350(&adapter->hw); + SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev), + SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), + OID_AUTO, "eee_disabled", CTLTYPE_INT|CTLFLAG_RW, + adapter, 0, igb_sysctl_eee, "I", + "Disable Energy Efficient Ethernet"); + if (adapter->hw.phy.media_type == e1000_media_type_copper) + e1000_set_eee_i350(&adapter->hw); } /* @@ -581,7 +604,9 @@ igb_attach(device_t dev) e1000_reset_hw(&adapter->hw); /* Make sure we have a good EEPROM before we read from it */ - if (e1000_validate_nvm_checksum(&adapter->hw) < 0) { + if (((adapter->hw.mac.type != e1000_i210) && + (adapter->hw.mac.type != e1000_i211)) && + (e1000_validate_nvm_checksum(&adapter->hw) < 0)) { /* ** Some PCI-E parts fail the first check due to ** the link being in sleep state, call it again, @@ -611,16 +636,6 @@ igb_attach(device_t dev) goto err_late; } - /* - ** Configure Interrupts - */ - if ((adapter->msix > 1) && (igb_enable_msix)) - error = igb_allocate_msix(adapter); - else /* MSI or Legacy */ - error = igb_allocate_legacy(adapter); - if (error) - goto err_late; - /* Setup OS specific network interface */ if (igb_setup_interface(dev, adapter) != 0) goto err_late; @@ -659,11 +674,25 @@ igb_attach(device_t dev) igb_add_hw_stats(adapter); /* Tell the stack that the interface is not active */ - adapter->ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); + adapter->ifp->if_drv_flags &= ~IFF_DRV_RUNNING; + adapter->ifp->if_drv_flags |= IFF_DRV_OACTIVE; adapter->led_dev = led_create(igb_led_func, adapter, device_get_nameunit(dev)); + /* + ** Configure Interrupts + */ + if ((adapter->msix > 1) && (igb_enable_msix)) + error = igb_allocate_msix(adapter); + else /* MSI or Legacy */ + error = igb_allocate_legacy(adapter); + if (error) + goto err_late; + +#ifdef DEV_NETMAP + igb_netmap_attach(adapter); +#endif /* DEV_NETMAP */ INIT_DEBUGOUT("igb_attach: end"); return (0); @@ -673,10 +702,10 @@ igb_attach(device_t dev) igb_free_transmit_structures(adapter); igb_free_receive_structures(adapter); igb_release_hw_control(adapter); - if (adapter->ifp != NULL) - if_free(adapter->ifp); err_pci: igb_free_pci_resources(adapter); + if (adapter->ifp != NULL) + if_free(adapter->ifp); free(adapter->mta, M_DEVBUF); IGB_CORE_LOCK_DESTROY(adapter); @@ -742,6 +771,9 @@ igb_detach(device_t dev) callout_drain(&adapter->timer); +#ifdef DEV_NETMAP + netmap_detach(adapter->ifp); +#endif /* DEV_NETMAP */ igb_free_pci_resources(adapter); bus_generic_detach(dev); if_free(ifp); @@ -798,29 +830,29 @@ static int igb_resume(device_t dev) { struct adapter *adapter = device_get_softc(dev); + struct tx_ring *txr = adapter->tx_rings; struct ifnet *ifp = adapter->ifp; -#if __FreeBSD_version >= 800000 - struct tx_ring *txr = adapter->tx_rings; -#endif IGB_CORE_LOCK(adapter); igb_init_locked(adapter); igb_init_manageability(adapter); if ((ifp->if_flags & IFF_UP) && - (ifp->if_drv_flags & IFF_DRV_RUNNING)) { -#if __FreeBSD_version < 800000 - igb_start(ifp); -#else + (ifp->if_drv_flags & IFF_DRV_RUNNING) && adapter->link_active) { for (int i = 0; i < adapter->num_queues; i++, txr++) { IGB_TX_LOCK(txr); - if (!drbr_empty(ifp, txr->br)) +#if __FreeBSD_version >= 800000 + /* Process the stack queue only if not depleted */ + if (((txr->queue_status & IGB_QUEUE_DEPLETED) == 0) && + !drbr_empty(ifp, txr->br)) igb_mq_start_locked(ifp, txr, NULL); +#else + if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) + igb_start_locked(txr, ifp); +#endif IGB_TX_UNLOCK(txr); } -#endif } - IGB_CORE_UNLOCK(adapter); return bus_generic_resume(dev); @@ -828,6 +860,7 @@ igb_resume(device_t dev) #if __FreeBSD_version < 800000 + /********************************************************************* * Transmit entry point * @@ -858,7 +891,7 @@ igb_start_locked(struct tx_ring *txr, struct ifnet *ifp) while (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) { if (txr->tx_avail <= IGB_MAX_SCATTER) { - ifp->if_drv_flags |= IFF_DRV_OACTIVE; + txr->queue_status |= IGB_QUEUE_DEPLETED; break; } IFQ_DRV_DEQUEUE(&ifp->if_snd, m_head); @@ -869,10 +902,10 @@ igb_start_locked(struct tx_ring *txr, struct ifnet *ifp) * NULL on failure. In that event, we can't requeue. */ if (igb_xmit(txr, &m_head)) { - if (m_head == NULL) - break; - ifp->if_drv_flags |= IFF_DRV_OACTIVE; - IFQ_DRV_PREPEND(&ifp->if_snd, m_head); + if (m_head != NULL) + IFQ_DRV_PREPEND(&ifp->if_snd, m_head); + if (txr->tx_avail <= IGB_MAX_SCATTER) + txr->queue_status |= IGB_QUEUE_DEPLETED; break; } @@ -881,7 +914,7 @@ igb_start_locked(struct tx_ring *txr, struct ifnet *ifp) /* Set watchdog on */ txr->watchdog_time = ticks; - txr->queue_status = IGB_QUEUE_WORKING; + txr->queue_status |= IGB_QUEUE_WORKING; } } @@ -905,6 +938,7 @@ igb_start(struct ifnet *ifp) } #else /* __FreeBSD_version >= 800000 */ + /* ** Multiqueue Transmit driver ** @@ -915,16 +949,18 @@ igb_mq_start(struct ifnet *ifp, struct mbuf *m) struct adapter *adapter = ifp->if_softc; struct igb_queue *que; struct tx_ring *txr; - int i = 0, err = 0; + int i, err = 0; /* Which queue to use */ if ((m->m_flags & M_FLOWID) != 0) i = m->m_pkthdr.flowid % adapter->num_queues; + else + i = curcpu % adapter->num_queues; txr = &adapter->tx_rings[i]; que = &adapter->queues[i]; - - if (IGB_TX_TRYLOCK(txr)) { + if (((txr->queue_status & IGB_QUEUE_DEPLETED) == 0) && + IGB_TX_TRYLOCK(txr)) { err = igb_mq_start_locked(ifp, txr, m); IGB_TX_UNLOCK(txr); } else { @@ -944,8 +980,9 @@ igb_mq_start_locked(struct ifnet *ifp, struct tx_ring *txr, struct mbuf *m) IGB_TX_LOCK_ASSERT(txr); - if ((ifp->if_drv_flags & (IFF_DRV_RUNNING | IFF_DRV_OACTIVE)) != - IFF_DRV_RUNNING || adapter->link_active == 0) { + if (((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) || + (txr->queue_status == IGB_QUEUE_DEPLETED) || + adapter->link_active == 0) { if (m != NULL) err = drbr_enqueue(ifp, txr->br, m); return (err); @@ -973,19 +1010,17 @@ igb_mq_start_locked(struct ifnet *ifp, struct tx_ring *txr, struct mbuf *m) ETHER_BPF_MTAP(ifp, next); if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) break; - if (txr->tx_avail <= IGB_TX_CLEANUP_THRESHOLD) - igb_txeof(txr); - if (txr->tx_avail <= IGB_MAX_SCATTER) { - ifp->if_drv_flags |= IFF_DRV_OACTIVE; - break; - } next = drbr_dequeue(ifp, txr->br); } if (enq > 0) { /* Set the watchdog */ - txr->queue_status = IGB_QUEUE_WORKING; + txr->queue_status |= IGB_QUEUE_WORKING; txr->watchdog_time = ticks; } + if (txr->tx_avail <= IGB_TX_CLEANUP_THRESHOLD) + igb_txeof(txr); + if (txr->tx_avail <= IGB_MAX_SCATTER) + txr->queue_status |= IGB_QUEUE_DEPLETED; return (err); } @@ -1023,7 +1058,7 @@ igb_qflush(struct ifnet *ifp) } if_qflush(ifp); } -#endif /* __FreeBSD_version < 800000 */ +#endif /* __FreeBSD_version >= 800000 */ /********************************************************************* * Ioctl entry point @@ -1129,11 +1164,6 @@ igb_ioctl(struct ifnet *ifp, u_long command, caddr_t data) } break; case SIOCSIFMEDIA: - /* - ** As the speed/duplex settings are being - ** changed, we need toreset the PHY. - */ - adapter->hw.phy.reset_disable = FALSE; /* Check SOL/IDER usage */ IGB_CORE_LOCK(adapter); if (e1000_check_reset_block(&adapter->hw)) { @@ -1324,10 +1354,8 @@ igb_init_locked(struct adapter *adapter) } /* Set Energy Efficient Ethernet */ - e1000_set_eee_i350(&adapter->hw); - - /* Don't reset the phy next time init gets called */ - adapter->hw.phy.reset_disable = TRUE; + if (adapter->hw.phy.media_type == e1000_media_type_copper) + e1000_set_eee_i350(&adapter->hw); } static void @@ -1352,19 +1380,22 @@ igb_handle_que(void *context, int pending) if (ifp->if_drv_flags & IFF_DRV_RUNNING) { bool more; - more = igb_rxeof(que, -1, NULL); + more = igb_rxeof(que, adapter->rx_process_limit, NULL); IGB_TX_LOCK(txr); - if (igb_txeof(txr)) - more = TRUE; + igb_txeof(txr); #if __FreeBSD_version >= 800000 - if (!drbr_empty(ifp, txr->br)) + /* Process the stack queue only if not depleted */ + if (((txr->queue_status & IGB_QUEUE_DEPLETED) == 0) && + !drbr_empty(ifp, txr->br)) igb_mq_start_locked(ifp, txr, NULL); #else - igb_start_locked(txr, ifp); + if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) + igb_start_locked(txr, ifp); #endif IGB_TX_UNLOCK(txr); - if (more || (ifp->if_drv_flags & IFF_DRV_OACTIVE)) { + /* Do we need another? */ + if (more) { taskqueue_enqueue(que->tq, &que->que_task); return; } @@ -1387,8 +1418,35 @@ igb_handle_link(void *context, int pending) { struct adapter *adapter = context; + IGB_CORE_LOCK(adapter); + igb_handle_link_locked(adapter); + IGB_CORE_UNLOCK(adapter); +} + +static void +igb_handle_link_locked(struct adapter *adapter) +{ + struct tx_ring *txr = adapter->tx_rings; + struct ifnet *ifp = adapter->ifp; + + IGB_CORE_LOCK_ASSERT(adapter); adapter->hw.mac.get_link_status = 1; igb_update_link_status(adapter); + if ((ifp->if_drv_flags & IFF_DRV_RUNNING) && adapter->link_active) { + for (int i = 0; i < adapter->num_queues; i++, txr++) { + IGB_TX_LOCK(txr); +#if __FreeBSD_version >= 800000 + /* Process the stack queue only if not depleted */ + if (((txr->queue_status & IGB_QUEUE_DEPLETED) == 0) && + !drbr_empty(ifp, txr->br)) + igb_mq_start_locked(ifp, txr, NULL); +#else + if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) + igb_start_locked(txr, ifp); +#endif + IGB_TX_UNLOCK(txr); + } + } } /********************************************************************* @@ -1468,7 +1526,7 @@ igb_poll(struct ifnet *ifp, enum poll_cmd cmd, int count) reg_icr = E1000_READ_REG(&adapter->hw, E1000_ICR); /* Link status change */ if (reg_icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC)) - igb_handle_link(adapter, 0); + igb_handle_link_locked(adapter); if (reg_icr & E1000_ICR_RXO) adapter->rx_overruns++; @@ -1485,7 +1543,8 @@ igb_poll(struct ifnet *ifp, enum poll_cmd cmd, int count) if (!drbr_empty(ifp, txr->br)) igb_mq_start_locked(ifp, txr, NULL); #else - igb_start_locked(txr, ifp); + if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) + igb_start_locked(txr, ifp); #endif IGB_TX_UNLOCK(txr); return POLL_RETURN_COUNT(rx_done); @@ -1494,7 +1553,7 @@ igb_poll(struct ifnet *ifp, enum poll_cmd cmd, int count) /********************************************************************* * - * MSIX TX Interrupt Service routine + * MSIX Que Interrupt Service routine * **********************************************************************/ static void @@ -1502,16 +1561,26 @@ igb_msix_que(void *arg) { struct igb_queue *que = arg; struct adapter *adapter = que->adapter; + struct ifnet *ifp = adapter->ifp; struct tx_ring *txr = que->txr; struct rx_ring *rxr = que->rxr; u32 newitr = 0; - bool more_tx, more_rx; + bool more_rx; E1000_WRITE_REG(&adapter->hw, E1000_EIMC, que->eims); ++que->irqs; IGB_TX_LOCK(txr); - more_tx = igb_txeof(txr); + igb_txeof(txr); +#if __FreeBSD_version >= 800000 + /* Process the stack queue only if not depleted */ + if (((txr->queue_status & IGB_QUEUE_DEPLETED) == 0) && + !drbr_empty(ifp, txr->br)) + igb_mq_start_locked(ifp, txr, NULL); +#else + if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) + igb_start_locked(txr, ifp); +#endif IGB_TX_UNLOCK(txr); more_rx = igb_rxeof(que, adapter->rx_process_limit, NULL); @@ -1569,8 +1638,7 @@ igb_msix_que(void *arg) no_calc: /* Schedule a clean task if needed*/ - if (more_tx || more_rx || - (adapter->ifp->if_drv_flags & IFF_DRV_OACTIVE)) + if (more_rx) taskqueue_enqueue(que->tq, &que->que_task); else /* Reenable this interrupt */ @@ -1718,10 +1786,8 @@ igb_media_change(struct ifnet *ifp) /********************************************************************* * * This routine maps the mbufs to Advanced TX descriptors. - * used by the 82575 adapter. * **********************************************************************/ - static int igb_xmit(struct tx_ring *txr, struct mbuf **m_headp) { @@ -1730,22 +1796,123 @@ igb_xmit(struct tx_ring *txr, struct mbuf **m_headp) bus_dmamap_t map; struct igb_tx_buffer *tx_buffer, *tx_buffer_mapped; union e1000_adv_tx_desc *txd = NULL; - struct mbuf *m_head; - u32 olinfo_status = 0, cmd_type_len = 0; - int nsegs, i, j, error, first, last = 0; - u32 hdrlen = 0; - - m_head = *m_headp; - + struct mbuf *m_head = *m_headp; + struct ether_vlan_header *eh = NULL; + struct ip *ip = NULL; + struct tcphdr *th = NULL; + u32 hdrlen, cmd_type_len, olinfo_status = 0; + int ehdrlen, poff; + int nsegs, i, first, last = 0; + int error, do_tso, remap = 1; /* Set basic descriptor constants */ - cmd_type_len |= E1000_ADVTXD_DTYP_DATA; + cmd_type_len = E1000_ADVTXD_DTYP_DATA; cmd_type_len |= E1000_ADVTXD_DCMD_IFCS | E1000_ADVTXD_DCMD_DEXT; if (m_head->m_flags & M_VLANTAG) cmd_type_len |= E1000_ADVTXD_DCMD_VLE; +retry: + m_head = *m_headp; + do_tso = ((m_head->m_pkthdr.csum_flags & CSUM_TSO) != 0); + hdrlen = ehdrlen = poff = 0; + /* - * Map the packet for DMA. + * Intel recommends entire IP/TCP header length reside in a single + * buffer. If multiple descriptors are used to describe the IP and + * TCP header, each descriptor should describe one or more + * complete headers; descriptors referencing only parts of headers + * are not supported. If all layer headers are not coalesced into + * a single buffer, each buffer should not cross a 4KB boundary, + * or be larger than the maximum read request size. + * Controller also requires modifing IP/TCP header to make TSO work + * so we firstly get a writable mbuf chain then coalesce ethernet/ + * IP/TCP header into a single buffer to meet the requirement of + * controller. This also simplifies IP/TCP/UDP checksum offloading + * which also has similiar restrictions. + */ + if (do_tso || m_head->m_pkthdr.csum_flags & CSUM_OFFLOAD) { + if (do_tso || (m_head->m_next != NULL && + m_head->m_pkthdr.csum_flags & CSUM_OFFLOAD)) { + if (M_WRITABLE(*m_headp) == 0) { + m_head = m_dup(*m_headp, M_DONTWAIT); + m_freem(*m_headp); + if (m_head == NULL) { + *m_headp = NULL; + return (ENOBUFS); + } + *m_headp = m_head; + } + } + /* + * Assume IPv4, we don't have TSO/checksum offload support + * for IPv6 yet. + */ + ehdrlen = sizeof(struct ether_header); + m_head = m_pullup(m_head, ehdrlen); + if (m_head == NULL) { + *m_headp = NULL; + return (ENOBUFS); + } + eh = mtod(m_head, struct ether_vlan_header *); + if (eh->evl_encap_proto == htons(ETHERTYPE_VLAN)) { + ehdrlen = sizeof(struct ether_vlan_header); + m_head = m_pullup(m_head, ehdrlen); + if (m_head == NULL) { + *m_headp = NULL; + return (ENOBUFS); + } + } + m_head = m_pullup(m_head, ehdrlen + sizeof(struct ip)); + if (m_head == NULL) { + *m_headp = NULL; + return (ENOBUFS); + } + ip = (struct ip *)(mtod(m_head, char *) + ehdrlen); + poff = ehdrlen + (ip->ip_hl << 2); + if (do_tso) { + m_head = m_pullup(m_head, poff + sizeof(struct tcphdr)); + if (m_head == NULL) { + *m_headp = NULL; + return (ENOBUFS); + } + /* + * The pseudo TCP checksum does not include TCP payload + * length so driver should recompute the checksum here + * what hardware expect to see. This is adherence of + * Microsoft's Large Send specification. + */ + th = (struct tcphdr *)(mtod(m_head, char *) + poff); + th->th_sum = in_pseudo(ip->ip_src.s_addr, + ip->ip_dst.s_addr, htons(IPPROTO_TCP)); + /* Keep track of the full header length */ + hdrlen = poff + (th->th_off << 2); + } else if (m_head->m_pkthdr.csum_flags & CSUM_TCP) { + m_head = m_pullup(m_head, poff + sizeof(struct tcphdr)); + if (m_head == NULL) { + *m_headp = NULL; + return (ENOBUFS); + } + th = (struct tcphdr *)(mtod(m_head, char *) + poff); + m_head = m_pullup(m_head, poff + (th->th_off << 2)); + if (m_head == NULL) { + *m_headp = NULL; + return (ENOBUFS); + } + ip = (struct ip *)(mtod(m_head, char *) + ehdrlen); + th = (struct tcphdr *)(mtod(m_head, char *) + poff); + } else if (m_head->m_pkthdr.csum_flags & CSUM_UDP) { + m_head = m_pullup(m_head, poff + sizeof(struct udphdr)); + if (m_head == NULL) { + *m_headp = NULL; + return (ENOBUFS); + } + ip = (struct ip *)(mtod(m_head, char *) + ehdrlen); + } + *m_headp = m_head; + } + + /* + * Map the packet for DMA * * Capture the first descriptor index, * this descriptor will have the index @@ -1760,7 +1927,16 @@ igb_xmit(struct tx_ring *txr, struct mbuf **m_headp) error = bus_dmamap_load_mbuf_sg(txr->txtag, map, *m_headp, segs, &nsegs, BUS_DMA_NOWAIT); - if (error == EFBIG) { + /* + * There are two types of errors we can (try) to handle: + * - EFBIG means the mbuf chain was too long and bus_dma ran + * out of segments. Defragment the mbuf chain and try again. + * - ENOMEM means bus_dma could not obtain enough bounce buffers + * at this point in time. Defer sending and try again later. + * All other errors, in particular EINVAL, are fatal and prevent the + * mbuf chain from ever going through. Drop it and report error. + */ + if (error == EFBIG && remap) { struct mbuf *m; m = m_defrag(*m_headp, M_DONTWAIT); @@ -1772,19 +1948,9 @@ igb_xmit(struct tx_ring *txr, struct mbuf **m_headp) } *m_headp = m; - /* Try it again */ - error = bus_dmamap_load_mbuf_sg(txr->txtag, map, - *m_headp, segs, &nsegs, BUS_DMA_NOWAIT); - - if (error == ENOMEM) { - adapter->no_tx_dma_setup++; - return (error); - } else if (error != 0) { - adapter->no_tx_dma_setup++; - m_freem(*m_headp); - *m_headp = NULL; - return (error); - } + /* Try it again, but only once */ + remap = 0; + goto retry; } else if (error == ENOMEM) { adapter->no_tx_dma_setup++; return (error); @@ -1795,29 +1961,35 @@ igb_xmit(struct tx_ring *txr, struct mbuf **m_headp) return (error); } - /* Check again to be sure we have enough descriptors */ - if (nsegs > (txr->tx_avail - 2)) { + /* + ** Make sure we don't overrun the ring, + ** we need nsegs descriptors and one for + ** the context descriptor used for the + ** offloads. + */ + if ((nsegs + 1) > (txr->tx_avail - 2)) { txr->no_desc_avail++; bus_dmamap_unload(txr->txtag, map); return (ENOBUFS); } m_head = *m_headp; - /* - * Set up the context descriptor: - * used when any hardware offload is done. - * This includes CSUM, VLAN, and TSO. It - * will use the first descriptor. + /* Do hardware assists: + * Set up the context descriptor, used + * when any hardware offload is done. + * This includes CSUM, VLAN, and TSO. + * It will use the first descriptor. */ - if (m_head->m_pkthdr.csum_flags & CSUM_TSO) { - if (igb_tso_setup(txr, m_head, &hdrlen)) { + + if (m_head->m_pkthdr.csum_flags & CSUM_TSO) { + if (igb_tso_setup(txr, m_head, ehdrlen, ip, th)) { cmd_type_len |= E1000_ADVTXD_DCMD_TSE; olinfo_status |= E1000_TXD_POPTS_IXSM << 8; olinfo_status |= E1000_TXD_POPTS_TXSM << 8; } else - return (ENXIO); + return (ENXIO); } else if (igb_tx_ctx_setup(txr, m_head)) - olinfo_status |= E1000_TXD_POPTS_TXSM << 8; + olinfo_status |= E1000_TXD_POPTS_TXSM << 8; /* Calculate payload length */ olinfo_status |= ((m_head->m_pkthdr.len - hdrlen) @@ -1829,7 +2001,7 @@ igb_xmit(struct tx_ring *txr, struct mbuf **m_headp) /* Set up our transmit descriptors */ i = txr->next_avail_desc; - for (j = 0; j < nsegs; j++) { + for (int j = 0; j < nsegs; j++) { bus_size_t seg_len; bus_addr_t seg_addr; @@ -1850,8 +2022,14 @@ igb_xmit(struct tx_ring *txr, struct mbuf **m_headp) txr->next_avail_desc = i; txr->tx_avail -= nsegs; - tx_buffer->m_head = m_head; + + /* + ** Here we swap the map so the last descriptor, + ** which gets the completion interrupt has the + ** real map, and the first descriptor gets the + ** unused map from this descriptor. + */ tx_buffer_mapped->map = tx_buffer->map; tx_buffer->map = map; bus_dmamap_sync(txr->txtag, map, BUS_DMASYNC_PREWRITE); @@ -1869,6 +2047,7 @@ igb_xmit(struct tx_ring *txr, struct mbuf **m_headp) */ tx_buffer = &txr->tx_buffers[first]; tx_buffer->next_eop = last; + /* Update the watchdog time early and often */ txr->watchdog_time = ticks; /* @@ -1881,9 +2060,7 @@ igb_xmit(struct tx_ring *txr, struct mbuf **m_headp) ++txr->tx_packets; return (0); - } - static void igb_set_promisc(struct adapter *adapter) { @@ -1990,7 +2167,10 @@ igb_local_timer(void *arg) { struct adapter *adapter = arg; device_t dev = adapter->dev; + struct ifnet *ifp = adapter->ifp; struct tx_ring *txr = adapter->tx_rings; + struct igb_queue *que = adapter->queues; + int hung = 0, busy = 0; IGB_CORE_LOCK_ASSERT(adapter); @@ -1998,22 +2178,29 @@ igb_local_timer(void *arg) igb_update_link_status(adapter); igb_update_stats_counters(adapter); - /* - ** If flow control has paused us since last checking - ** it invalidates the watchdog timing, so dont run it. - */ - if (adapter->pause_frames) { - adapter->pause_frames = 0; - goto out; - } - /* - ** Watchdog: check for time since any descriptor was cleaned + ** Check the TX queues status + ** - central locked handling of OACTIVE + ** - watchdog only if all queues show hung */ - for (int i = 0; i < adapter->num_queues; i++, txr++) - if (txr->queue_status == IGB_QUEUE_HUNG) - goto timeout; -out: + for (int i = 0; i < adapter->num_queues; i++, que++, txr++) { + if ((txr->queue_status & IGB_QUEUE_HUNG) && + (adapter->pause_frames == 0)) + ++hung; + if (txr->queue_status & IGB_QUEUE_DEPLETED) + ++busy; + if ((txr->queue_status & IGB_QUEUE_IDLE) == 0) + taskqueue_enqueue(que->tq, &que->que_task); + } + if (hung == adapter->num_queues) + goto timeout; + if (busy == adapter->num_queues) + ifp->if_drv_flags |= IFF_DRV_OACTIVE; + else if ((ifp->if_drv_flags & IFF_DRV_OACTIVE) && + (busy < adapter->num_queues)) + ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; + + adapter->pause_frames = 0; callout_reset(&adapter->timer, hz, igb_local_timer, adapter); #ifndef DEVICE_POLLING /* Schedule all queue interrupts - deadlock protection */ @@ -2106,7 +2293,7 @@ igb_update_link_status(struct adapter *adapter) adapter->link_active = 0; /* This can sleep */ if_link_state_change(ifp, LINK_STATE_DOWN); - /* Turn off watchdogs */ + /* Reset queue state */ for (int i = 0; i < adapter->num_queues; i++, txr++) txr->queue_status = IGB_QUEUE_IDLE; } @@ -2135,9 +2322,10 @@ igb_stop(void *arg) callout_stop(&adapter->timer); /* Tell the stack that the interface is no longer active */ - ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); + ifp->if_drv_flags &= ~IFF_DRV_RUNNING; + ifp->if_drv_flags |= IFF_DRV_OACTIVE; - /* Unarm watchdog timer. */ + /* Disarm watchdog timer. */ for (int i = 0; i < adapter->num_queues; i++, txr++) { IGB_TX_LOCK(txr); txr->queue_status = IGB_QUEUE_IDLE; @@ -2292,6 +2480,9 @@ igb_allocate_msix(struct adapter *adapter) struct igb_queue *que = adapter->queues; int error, rid, vector = 0; + /* Be sure to start with all interrupts disabled */ + E1000_WRITE_REG(&adapter->hw, E1000_IMC, ~0); + E1000_WRITE_FLUSH(&adapter->hw); for (int i = 0; i < adapter->num_queues; i++, vector++, que++) { rid = vector +1; @@ -2323,8 +2514,16 @@ igb_allocate_msix(struct adapter *adapter) ** Bind the msix vector, and thus the ** rings to the corresponding cpu. */ - if (adapter->num_queues > 1) - bus_bind_intr(dev, que->res, i); + if (adapter->num_queues > 1) { + if (igb_last_bind_cpu < 0) + igb_last_bind_cpu = CPU_FIRST(); + bus_bind_intr(dev, que->res, igb_last_bind_cpu); + device_printf(dev, + "Bound queue %d to cpu %d\n", + i,igb_last_bind_cpu); + igb_last_bind_cpu = CPU_NEXT(igb_last_bind_cpu); + igb_last_bind_cpu = igb_last_bind_cpu % mp_ncpus; + } #if __FreeBSD_version >= 800000 TASK_INIT(&que->txr->txq_task, 0, igb_deferred_mq_start, que->txr); @@ -2379,6 +2578,8 @@ igb_configure_queues(struct adapter *adapter) switch (adapter->hw.mac.type) { case e1000_82580: case e1000_i350: + case e1000_i210: + case e1000_i211: case e1000_vfadapt: case e1000_vfadapt_i350: /* RX entries */ @@ -2577,7 +2778,7 @@ static int igb_setup_msix(struct adapter *adapter) { device_t dev = adapter->dev; - int rid, want, queues, msgs; + int rid, want, queues, msgs, maxqueues; /* tuneable override */ if (igb_enable_msix == 0) @@ -2608,16 +2809,29 @@ igb_setup_msix(struct adapter *adapter) /* Manual override */ if (igb_num_queues != 0) queues = igb_num_queues; - if (queues > 8) /* max queues */ - queues = 8; - /* Can have max of 4 queues on 82575 */ - if ((adapter->hw.mac.type == e1000_82575) && (queues > 4)) - queues = 4; - - /* Limit the VF devices to one queue */ - if (adapter->vf_ifp) - queues = 1; + /* Sanity check based on HW */ + switch (adapter->hw.mac.type) { + case e1000_82575: + maxqueues = 4; + break; + case e1000_82576: + case e1000_82580: + case e1000_i350: + maxqueues = 8; + break; + case e1000_i210: + maxqueues = 4; + break; + case e1000_i211: + maxqueues = 2; + break; + default: /* VF interfaces */ + maxqueues = 1; + break; + } + if (queues > maxqueues) + queues = maxqueues; /* ** One vector (RX/TX pair) per queue @@ -2631,7 +2845,7 @@ igb_setup_msix(struct adapter *adapter) "MSIX Configuration Problem, " "%d vectors configured, but %d queues wanted!\n", msgs, want); - return (ENXIO); + return (0); } if ((msgs) && pci_alloc_msix(dev, &msgs) == 0) { device_printf(adapter->dev, @@ -2641,9 +2855,11 @@ igb_setup_msix(struct adapter *adapter) } msi: msgs = pci_msi_count(dev); - if (msgs == 1 && pci_alloc_msi(dev, &msgs) == 0) - device_printf(adapter->dev,"Using MSI interrupt\n"); - return (msgs); + if (msgs == 1 && pci_alloc_msi(dev, &msgs) == 0) { + device_printf(adapter->dev," Using MSI interrupt\n"); + return (msgs); + } + return (0); } /********************************************************************* @@ -2686,7 +2902,9 @@ igb_reset(struct adapter *adapter) pba = E1000_READ_REG(hw, E1000_RXPBS); pba = e1000_rxpbs_adjust_82580(pba); break; - pba = E1000_PBA_35K; + case e1000_i210: + case e1000_i211: + pba = E1000_PBA_34K; default: break; } @@ -2741,12 +2959,10 @@ igb_reset(struct adapter *adapter) fc->pause_time = IGB_FC_PAUSE_TIME; fc->send_xon = TRUE; - if (fc->requested_mode) - fc->current_mode = fc->requested_mode; + if (adapter->fc) + fc->requested_mode = adapter->fc; else - fc->current_mode = e1000_fc_full; - - adapter->fc = fc->current_mode; + fc->requested_mode = e1000_fc_default; /* Issue a global reset */ e1000_reset_hw(hw); @@ -2756,7 +2972,9 @@ igb_reset(struct adapter *adapter) device_printf(dev, "Hardware Initialization Failed\n"); /* Setup DMA Coalescing */ - if (hw->mac.type == e1000_i350) { + if ((hw->mac.type > e1000_82580) && + (hw->mac.type != e1000_i211)) { + u32 dmac; u32 reg = ~E1000_DMACR_DMAC_EN; if (adapter->dmac == 0) { /* Disabling it */ @@ -2764,26 +2982,36 @@ igb_reset(struct adapter *adapter) goto reset_out; } - hwm = (pba - 4) << 10; - reg = (((pba-6) << E1000_DMACR_DMACTHR_SHIFT) - & E1000_DMACR_DMACTHR_MASK); + /* Set starting thresholds */ + E1000_WRITE_REG(hw, E1000_DMCTXTH, 0); + E1000_WRITE_REG(hw, E1000_DMCRTRH, 0); + hwm = 64 * pba - adapter->max_frame_size / 16; + if (hwm < 64 * (pba - 6)) + hwm = 64 * (pba - 6); + reg = E1000_READ_REG(hw, E1000_FCRTC); + reg &= ~E1000_FCRTC_RTH_COAL_MASK; + reg |= ((hwm << E1000_FCRTC_RTH_COAL_SHIFT) + & E1000_FCRTC_RTH_COAL_MASK); + E1000_WRITE_REG(hw, E1000_FCRTC, reg); + + + dmac = pba - adapter->max_frame_size / 512; + if (dmac < pba - 10) + dmac = pba - 10; + reg = E1000_READ_REG(hw, E1000_DMACR); + reg &= ~E1000_DMACR_DMACTHR_MASK; + reg = ((dmac << E1000_DMACR_DMACTHR_SHIFT) + & E1000_DMACR_DMACTHR_MASK); /* transition to L0x or L1 if available..*/ reg |= (E1000_DMACR_DMAC_EN | E1000_DMACR_DMAC_LX_MASK); - /* timer = value in adapter->dmac in 32usec intervals */ reg |= (adapter->dmac >> 5); E1000_WRITE_REG(hw, E1000_DMACR, reg); - /* No lower threshold */ - E1000_WRITE_REG(hw, E1000_DMCRTRH, 0); - - /* set hwm to PBA - 2 * max frame size */ - E1000_WRITE_REG(hw, E1000_FCRTC, hwm); - /* Set the interval before transition */ reg = E1000_READ_REG(hw, E1000_DMCTLX); - reg |= 0x800000FF; /* 255 usec */ + reg |= 0x80000004; E1000_WRITE_REG(hw, E1000_DMCTLX, reg); /* free space in tx packet buffer to wake from DMA coal */ @@ -2792,9 +3020,15 @@ igb_reset(struct adapter *adapter) /* make low power state decision controlled by DMA coal */ reg = E1000_READ_REG(hw, E1000_PCIEMISC); - E1000_WRITE_REG(hw, E1000_PCIEMISC, - reg | E1000_PCIEMISC_LX_DECISION); + reg &= ~E1000_PCIEMISC_LX_DECISION; + E1000_WRITE_REG(hw, E1000_PCIEMISC, reg); device_printf(dev, "DMA Coalescing enabled\n"); + + } else if (hw->mac.type == e1000_82580) { + u32 reg = E1000_READ_REG(hw, E1000_PCIEMISC); + E1000_WRITE_REG(hw, E1000_DMACR, 0); + E1000_WRITE_REG(hw, E1000_PCIEMISC, + reg & ~E1000_PCIEMISC_LX_DECISION); } reset_out: @@ -2822,7 +3056,6 @@ igb_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 = igb_init; ifp->if_softc = adapter; ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; @@ -2832,10 +3065,10 @@ igb_setup_interface(device_t dev, struct adapter *adapter) ifp->if_qflush = igb_qflush; #else ifp->if_start = igb_start; -#endif IFQ_SET_MAXLEN(&ifp->if_snd, adapter->num_tx_desc - 1); ifp->if_snd.ifq_drv_maxlen = adapter->num_tx_desc - 1; IFQ_SET_READY(&ifp->if_snd); +#endif ether_ifattach(ifp, adapter->hw.mac.addr); @@ -3212,9 +3445,16 @@ igb_setup_transmit_ring(struct tx_ring *txr) struct adapter *adapter = txr->adapter; struct igb_tx_buffer *txbuf; int i; +#ifdef DEV_NETMAP + struct netmap_adapter *na = NA(adapter->ifp); + struct netmap_slot *slot; +#endif /* DEV_NETMAP */ /* Clear the old descriptor contents */ IGB_TX_LOCK(txr); +#ifdef DEV_NETMAP + slot = netmap_reset(na, NR_TX, txr->me, 0); +#endif /* DEV_NETMAP */ bzero((void *)txr->tx_base, (sizeof(union e1000_adv_tx_desc)) * adapter->num_tx_desc); /* Reset indices */ @@ -3231,6 +3471,13 @@ igb_setup_transmit_ring(struct tx_ring *txr) m_freem(txbuf->m_head); txbuf->m_head = NULL; } +#ifdef DEV_NETMAP + if (slot) { + int si = netmap_idx_n2k(&na->tx_rings[txr->me], i); + /* no need to set the address */ + netmap_load_map(txr->txtag, txbuf->map, NMB(slot + si)); + } +#endif /* DEV_NETMAP */ /* clear the watch index */ txbuf->next_eop = -1; } @@ -3396,8 +3643,9 @@ igb_free_transmit_buffers(struct tx_ring *txr) * Setup work for hardware segmentation offload (TSO) * **********************************************************************/ -static boolean_t -igb_tso_setup(struct tx_ring *txr, struct mbuf *mp, u32 *hdrlen) +static bool +igb_tso_setup(struct tx_ring *txr, struct mbuf *mp, int ehdrlen, + struct ip *ip, struct tcphdr *th) { struct adapter *adapter = txr->adapter; struct e1000_adv_tx_context_desc *TXD; @@ -3405,45 +3653,15 @@ igb_tso_setup(struct tx_ring *txr, struct mbuf *mp, u32 *hdrlen) u32 vlan_macip_lens = 0, type_tucmd_mlhl = 0; u32 mss_l4len_idx = 0; u16 vtag = 0; - int ctxd, ehdrlen, ip_hlen, tcp_hlen; - struct ether_vlan_header *eh; - struct ip *ip; - struct tcphdr *th; - + int ctxd, ip_hlen, tcp_hlen; - /* - * Determine where frame payload starts. - * Jump over vlan headers if already present - */ - eh = mtod(mp, struct ether_vlan_header *); - if (eh->evl_encap_proto == htons(ETHERTYPE_VLAN)) - ehdrlen = ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN; - else - ehdrlen = ETHER_HDR_LEN; - - /* Ensure we have at least the IP+TCP header in the first mbuf. */ - if (mp->m_len < ehdrlen + sizeof(struct ip) + sizeof(struct tcphdr)) - return FALSE; - - /* Only supports IPV4 for now */ ctxd = txr->next_avail_desc; tx_buffer = &txr->tx_buffers[ctxd]; TXD = (struct e1000_adv_tx_context_desc *) &txr->tx_base[ctxd]; - ip = (struct ip *)(mp->m_data + ehdrlen); - if (ip->ip_p != IPPROTO_TCP) - return FALSE; /* 0 */ ip->ip_sum = 0; ip_hlen = ip->ip_hl << 2; - th = (struct tcphdr *)((caddr_t)ip + ip_hlen); - th->th_sum = in_pseudo(ip->ip_src.s_addr, - ip->ip_dst.s_addr, htons(IPPROTO_TCP)); tcp_hlen = th->th_off << 2; - /* - * Calculate header length, this is used - * in the transmit desc in igb_xmit - */ - *hdrlen = ehdrlen + ip_hlen + tcp_hlen; /* VLAN MACLEN IPLEN */ if (mp->m_flags & M_VLANTAG) { @@ -3626,6 +3844,19 @@ igb_txeof(struct tx_ring *txr) IGB_TX_LOCK_ASSERT(txr); +#ifdef DEV_NETMAP + if (ifp->if_capenable & IFCAP_NETMAP) { + struct netmap_adapter *na = NA(ifp); + + selwakeuppri(&na->tx_rings[txr->me].si, PI_NET); + IGB_TX_UNLOCK(txr); + IGB_CORE_LOCK(adapter); + selwakeuppri(&na->tx_si, PI_NET); + IGB_CORE_UNLOCK(adapter); + IGB_TX_LOCK(txr); + return FALSE; + } +#endif /* DEV_NETMAP */ if (txr->tx_avail == adapter->num_tx_desc) { txr->queue_status = IGB_QUEUE_IDLE; return FALSE; @@ -3705,20 +3936,20 @@ igb_txeof(struct tx_ring *txr) ** for too long indicates a hang. */ if ((!processed) && ((ticks - txr->watchdog_time) > IGB_WATCHDOG)) - txr->queue_status = IGB_QUEUE_HUNG; - + txr->queue_status |= IGB_QUEUE_HUNG; /* - * If we have a minimum free, clear IFF_DRV_OACTIVE - * to tell the stack that it is OK to send packets. + * If we have a minimum free, + * clear depleted state bit */ - if (txr->tx_avail > IGB_TX_CLEANUP_THRESHOLD) { - ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; - /* All clean, turn off the watchdog */ - if (txr->tx_avail == adapter->num_tx_desc) { - txr->queue_status = IGB_QUEUE_IDLE; - return (FALSE); - } + if (txr->tx_avail >= IGB_QUEUE_THRESHOLD) + txr->queue_status &= ~IGB_QUEUE_DEPLETED; + + /* All clean, turn off the watchdog */ + if (txr->tx_avail == adapter->num_tx_desc) { + txr->queue_status = IGB_QUEUE_IDLE; + return (FALSE); } + return (TRUE); } @@ -3949,6 +4180,10 @@ igb_setup_receive_ring(struct rx_ring *rxr) bus_dma_segment_t pseg[1], hseg[1]; struct lro_ctrl *lro = &rxr->lro; int rsize, nsegs, error = 0; +#ifdef DEV_NETMAP + struct netmap_adapter *na = NA(rxr->adapter->ifp); + struct netmap_slot *slot; +#endif /* DEV_NETMAP */ adapter = rxr->adapter; dev = adapter->dev; @@ -3956,6 +4191,9 @@ igb_setup_receive_ring(struct rx_ring *rxr) /* Clear the ring contents */ IGB_RX_LOCK(rxr); +#ifdef DEV_NETMAP + slot = netmap_reset(na, NR_RX, rxr->me, 0); +#endif /* DEV_NETMAP */ rsize = roundup2(adapter->num_rx_desc * sizeof(union e1000_adv_rx_desc), IGB_DBA_ALIGN); bzero((void *)rxr->rx_base, rsize); @@ -3974,6 +4212,20 @@ igb_setup_receive_ring(struct rx_ring *rxr) struct mbuf *mh, *mp; rxbuf = &rxr->rx_buffers[j]; +#ifdef DEV_NETMAP + if (slot) { + /* slot sj is mapped to the i-th NIC-ring entry */ + int sj = netmap_idx_n2k(&na->rx_rings[rxr->me], j); + uint64_t paddr; + void *addr; + + addr = PNMB(slot + sj, &paddr); + netmap_load_map(rxr->ptag, rxbuf->pmap, addr); + /* Update descriptor */ + rxr->rx_base[j].read.pkt_addr = htole64(paddr); + continue; + } +#endif /* DEV_NETMAP */ if (rxr->hdr_split == FALSE) goto skip_head; @@ -4258,6 +4510,26 @@ igb_initialize_receive_units(struct adapter *adapter) for (int i = 0; i < adapter->num_queues; i++) { rxr = &adapter->rx_rings[i]; E1000_WRITE_REG(hw, E1000_RDH(i), rxr->next_to_check); +#ifdef DEV_NETMAP + /* + * an init() while a netmap client is active must + * preserve the rx buffers passed to userspace. + * In this driver it means we adjust RDT to + * somthing different from next_to_refresh + * (which is not used in netmap mode). + */ + if (ifp->if_capenable & IFCAP_NETMAP) { + struct netmap_adapter *na = NA(adapter->ifp); + struct netmap_kring *kring = &na->rx_rings[i]; + int t = rxr->next_to_refresh - kring->nr_hwavail; + + if (t >= adapter->num_rx_desc) + t -= adapter->num_rx_desc; + else if (t < 0) + t += adapter->num_rx_desc; + E1000_WRITE_REG(hw, E1000_RDT(i), t); + } else +#endif /* DEV_NETMAP */ E1000_WRITE_REG(hw, E1000_RDT(i), rxr->next_to_refresh); } return; @@ -4436,6 +4708,20 @@ igb_rxeof(struct igb_queue *que, int count, int *done) bus_dmamap_sync(rxr->rxdma.dma_tag, rxr->rxdma.dma_map, BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); +#ifdef DEV_NETMAP + if (ifp->if_capenable & IFCAP_NETMAP) { + struct netmap_adapter *na = NA(ifp); + + na->rx_rings[rxr->me].nr_kflags |= NKR_PENDINTR; + selwakeuppri(&na->rx_rings[rxr->me].si, PI_NET); + IGB_RX_UNLOCK(rxr); + IGB_CORE_LOCK(adapter); + selwakeuppri(&na->rx_si, PI_NET); + IGB_CORE_UNLOCK(adapter); + return (0); + } +#endif /* DEV_NETMAP */ + /* Main clean loop */ for (i = rxr->next_to_check; count != 0;) { struct mbuf *sendmp, *mh, *mp; @@ -4762,8 +5048,8 @@ igb_setup_vlan_hw_support(struct adapter *adapter) e1000_vfta_set_vf(hw, adapter->shadow_vfta[i], TRUE); else - E1000_WRITE_REG_ARRAY(hw, E1000_VFTA, - i, adapter->shadow_vfta[i]); + e1000_write_vfta(hw, + i, adapter->shadow_vfta[i]); } } @@ -5629,23 +5915,26 @@ igb_set_sysctl_value(struct adapter *adapter, const char *name, static int igb_set_flowcntl(SYSCTL_HANDLER_ARGS) { - int error; - struct adapter *adapter = (struct adapter *) arg1; + int error; + static int input = 3; /* default is full */ + struct adapter *adapter = (struct adapter *) arg1; - error = sysctl_handle_int(oidp, &adapter->fc, 0, req); + error = sysctl_handle_int(oidp, &input, 0, req); if ((error) || (req->newptr == NULL)) return (error); - switch (adapter->fc) { + switch (input) { case e1000_fc_rx_pause: case e1000_fc_tx_pause: case e1000_fc_full: - adapter->hw.fc.requested_mode = adapter->fc; - break; case e1000_fc_none: + adapter->hw.fc.requested_mode = input; + adapter->fc = input; + break; default: - adapter->hw.fc.requested_mode = e1000_fc_none; + /* Do nothing */ + return (error); } adapter->hw.fc.current_mode = adapter->hw.fc.requested_mode; @@ -5701,3 +5990,25 @@ igb_sysctl_dmac(SYSCTL_HANDLER_ARGS) igb_init(adapter); return (error); } + +/* +** Manage Energy Efficient Ethernet: +** Control values: +** 0/1 - enabled/disabled +*/ +static int +igb_sysctl_eee(SYSCTL_HANDLER_ARGS) +{ + struct adapter *adapter = (struct adapter *) arg1; + int error, value; + + value = adapter->hw.dev_spec._82575.eee_disable; + error = sysctl_handle_int(oidp, &value, 0, req); + if (error || req->newptr == NULL) + return (error); + IGB_CORE_LOCK(adapter); + adapter->hw.dev_spec._82575.eee_disable = (value != 0); + igb_init_locked(adapter); + IGB_CORE_UNLOCK(adapter); + return (0); +} diff --git a/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/if_igb.h b/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/if_igb.h index 7d7e21a6c00..2be0b08736b 100644 --- a/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/if_igb.h +++ b/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/if_igb.h @@ -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 diff --git a/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/if_lem.c b/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/if_lem.c index 7056a0d53bd..b5bca6a8e4f 100644 --- a/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/if_lem.c +++ b/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/if_lem.c @@ -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 @@ -74,11 +75,7 @@ #include #include - -#ifndef __HAIKU__ #include -#endif - #include #include @@ -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 +#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); @@ -898,11 +896,12 @@ static int 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 - struct ifaddr *ifa = (struct ifaddr *)data; + struct ifreq *ifr = (struct ifreq *)data; +#if defined(INET) || defined(INET6) + struct ifaddr *ifa = (struct ifaddr *)data; #endif - int error = 0; + bool avoid_reset = FALSE; + int error = 0; if (adapter->in_detach) return (error); @@ -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. - */ + 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)) { - EM_CORE_LOCK(adapter); - lem_init_locked(adapter); - EM_CORE_UNLOCK(adapter); - } - arp_ifinit(ifp, ifa); - } else + 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)); } diff --git a/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/if_lem.h b/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/if_lem.h index 316aae7b262..c1973e55be6 100644 --- a/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/if_lem.h +++ b/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/if_lem.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/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 diff --git a/src/add-ons/kernel/drivers/network/jmicron2x0/dev/jme/if_jme.c b/src/add-ons/kernel/drivers/network/jmicron2x0/dev/jme/if_jme.c index 3a4fbb0fbff..7f0f9174f8a 100644 --- a/src/add-ons/kernel/drivers/network/jmicron2x0/dev/jme/if_jme.c +++ b/src/add-ons/kernel/drivers/network/jmicron2x0/dev/jme/if_jme.c @@ -26,7 +26,7 @@ */ #include -__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 #include @@ -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. */ diff --git a/src/add-ons/kernel/drivers/network/jmicron2x0/dev/jme/if_jmereg.h b/src/add-ons/kernel/drivers/network/jmicron2x0/dev/jme/if_jmereg.h index 375f5c4c5a7..f7dfb129e83 100644 --- a/src/add-ons/kernel/drivers/network/jmicron2x0/dev/jme/if_jmereg.h +++ b/src/add-ons/kernel/drivers/network/jmicron2x0/dev/jme/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_jmereg.h,v 1.6.2.2.2.1 2010/12/21 17:09:25 kensmith Exp $ + * $FreeBSD$ */ #ifndef _IF_JMEREG_H diff --git a/src/add-ons/kernel/drivers/network/jmicron2x0/dev/jme/if_jmevar.h b/src/add-ons/kernel/drivers/network/jmicron2x0/dev/jme/if_jmevar.h index 2e83a7055bf..eb4eddc8030 100644 --- a/src/add-ons/kernel/drivers/network/jmicron2x0/dev/jme/if_jmevar.h +++ b/src/add-ons/kernel/drivers/network/jmicron2x0/dev/jme/if_jmevar.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 diff --git a/src/add-ons/kernel/drivers/network/jmicron2x0/dev/mii/jmphy.c b/src/add-ons/kernel/drivers/network/jmicron2x0/dev/mii/jmphy.c index 12ef39ddcad..14fdf7e787c 100644 --- a/src/add-ons/kernel/drivers/network/jmicron2x0/dev/mii/jmphy.c +++ b/src/add-ons/kernel/drivers/network/jmicron2x0/dev/mii/jmphy.c @@ -26,7 +26,7 @@ */ #include -__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; diff --git a/src/add-ons/kernel/drivers/network/jmicron2x0/dev/mii/jmphyreg.h b/src/add-ons/kernel/drivers/network/jmicron2x0/dev/mii/jmphyreg.h index a676d3b4aea..ec668ad1cc9 100644 --- a/src/add-ons/kernel/drivers/network/jmicron2x0/dev/mii/jmphyreg.h +++ b/src/add-ons/kernel/drivers/network/jmicron2x0/dev/mii/jmphyreg.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/mii/jmphyreg.h,v 1.1.6.1.6.1 2010/12/21 17:09:25 kensmith Exp $ + * $FreeBSD$ */ #ifndef _DEV_MII_JMPHYREG_H_ diff --git a/src/add-ons/kernel/drivers/network/marvell_yukon/dev/mii/e1000phy.c b/src/add-ons/kernel/drivers/network/marvell_yukon/dev/mii/e1000phy.c index e657592b6d1..91ae44d2e97 100644 --- a/src/add-ons/kernel/drivers/network/marvell_yukon/dev/mii/e1000phy.c +++ b/src/add-ons/kernel/drivers/network/marvell_yukon/dev/mii/e1000phy.c @@ -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; diff --git a/src/add-ons/kernel/drivers/network/marvell_yukon/dev/mii/ukphy.c b/src/add-ons/kernel/drivers/network/marvell_yukon/dev/mii/ukphy.c index 4ecfce29d31..9d52eb580ca 100644 --- a/src/add-ons/kernel/drivers/network/marvell_yukon/dev/mii/ukphy.c +++ b/src/add-ons/kernel/drivers/network/marvell_yukon/dev/mii/ukphy.c @@ -55,7 +55,7 @@ */ #include -__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; diff --git a/src/add-ons/kernel/drivers/network/marvell_yukon/dev/mii/ukphy_subr.c b/src/add-ons/kernel/drivers/network/marvell_yukon/dev/mii/ukphy_subr.c index 73007e197b9..5f2f6341ba6 100644 --- a/src/add-ons/kernel/drivers/network/marvell_yukon/dev/mii/ukphy_subr.c +++ b/src/add-ons/kernel/drivers/network/marvell_yukon/dev/mii/ukphy_subr.c @@ -31,7 +31,7 @@ */ #include -__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. diff --git a/src/add-ons/kernel/drivers/network/marvell_yukon/dev/msk/if_msk.c b/src/add-ons/kernel/drivers/network/marvell_yukon/dev/msk/if_msk.c index 377a1589b2c..a6754561424 100644 --- a/src/add-ons/kernel/drivers/network/marvell_yukon/dev/msk/if_msk.c +++ b/src/add-ons/kernel/drivers/network/marvell_yukon/dev/msk/if_msk.c @@ -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; } diff --git a/src/add-ons/kernel/drivers/network/marvell_yukon/dev/msk/if_mskreg.h b/src/add-ons/kernel/drivers/network/marvell_yukon/dev/msk/if_mskreg.h index 75ef99ba9d4..3037797bb13 100644 --- a/src/add-ons/kernel/drivers/network/marvell_yukon/dev/msk/if_mskreg.h +++ b/src/add-ons/kernel/drivers/network/marvell_yukon/dev/msk/if_mskreg.h @@ -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; diff --git a/src/add-ons/kernel/drivers/network/nforce/dev/mii/ciphy.c b/src/add-ons/kernel/drivers/network/nforce/dev/mii/ciphy.c index 2133c76ca05..87d0d814e91 100644 --- a/src/add-ons/kernel/drivers/network/nforce/dev/mii/ciphy.c +++ b/src/add-ons/kernel/drivers/network/nforce/dev/mii/ciphy.c @@ -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; diff --git a/src/add-ons/kernel/drivers/network/nforce/dev/mii/ukphy.c b/src/add-ons/kernel/drivers/network/nforce/dev/mii/ukphy.c index 4ecfce29d31..9d52eb580ca 100644 --- a/src/add-ons/kernel/drivers/network/nforce/dev/mii/ukphy.c +++ b/src/add-ons/kernel/drivers/network/nforce/dev/mii/ukphy.c @@ -55,7 +55,7 @@ */ #include -__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; diff --git a/src/add-ons/kernel/drivers/network/nforce/dev/mii/ukphy_subr.c b/src/add-ons/kernel/drivers/network/nforce/dev/mii/ukphy_subr.c index 73007e197b9..5f2f6341ba6 100644 --- a/src/add-ons/kernel/drivers/network/nforce/dev/mii/ukphy_subr.c +++ b/src/add-ons/kernel/drivers/network/nforce/dev/mii/ukphy_subr.c @@ -31,7 +31,7 @@ */ #include -__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. diff --git a/src/add-ons/kernel/drivers/network/nforce/dev/nfe/if_nfe.c b/src/add-ons/kernel/drivers/network/nforce/dev/nfe/if_nfe.c index 28a3c0149f2..f4c5bed4192 100644 --- a/src/add-ons/kernel/drivers/network/nforce/dev/nfe/if_nfe.c +++ b/src/add-ons/kernel/drivers/network/nforce/dev/nfe/if_nfe.c @@ -165,16 +165,12 @@ static device_method_t nfe_methods[] = { DEVMETHOD(device_resume, nfe_resume), DEVMETHOD(device_shutdown, nfe_shutdown), - /* bus interface */ - DEVMETHOD(bus_print_child, bus_generic_print_child), - DEVMETHOD(bus_driver_added, bus_generic_driver_added), - /* MII interface */ DEVMETHOD(miibus_readreg, nfe_miibus_readreg), DEVMETHOD(miibus_writereg, nfe_miibus_writereg), DEVMETHOD(miibus_statchg, nfe_miibus_statchg), - { NULL, NULL } + DEVMETHOD_END }; static driver_t nfe_driver = { @@ -2952,10 +2948,10 @@ nfe_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr) NFE_LOCK(sc); mii = device_get_softc(sc->nfe_miibus); mii_pollstat(mii); - NFE_UNLOCK(sc); ifmr->ifm_active = mii->mii_media_active; ifmr->ifm_status = mii->mii_media_status; + NFE_UNLOCK(sc); } diff --git a/src/add-ons/kernel/drivers/network/pcnet/dev/le/am7990.c b/src/add-ons/kernel/drivers/network/pcnet/dev/le/am7990.c index a3fe239889a..56a07d5330d 100644 --- a/src/add-ons/kernel/drivers/network/pcnet/dev/le/am7990.c +++ b/src/add-ons/kernel/drivers/network/pcnet/dev/le/am7990.c @@ -72,7 +72,7 @@ */ #include -__FBSDID("$FreeBSD: src/sys/dev/le/am7990.c,v 1.1.2.3 2006/06/18 15:43:18 marius Exp $"); +__FBSDID("$FreeBSD$"); #include #include @@ -385,7 +385,7 @@ am7990_tint(struct lance_softc *sc) sc->sc_first_td = bix; - ifp->if_timer = sc->sc_no_td > 0 ? 5 : 0; + sc->sc_wdog_timer = sc->sc_no_td > 0 ? 5 : 0; } /* @@ -421,10 +421,9 @@ am7990_intr(void *arg) * Clear interrupt source flags and turn off interrupts. If we * don't clear these flags before processing their sources we * could completely miss some interrupt events as the NIC can - * change these flags while we're in this handler. We turn off - * interrupts so we don't get another RX interrupt while still - * processing the previous one in ifp->if_input() with the - * driver lock dropped. + * change these flags while we're in this handler. We toggle + * the interrupt enable bit in order to keep receiving them + * (some chips work without this, some don't). */ (*sc->sc_wrcsr)(sc, LE_CSR0, isr & ~(LE_C0_INEA | LE_C0_TDMD | LE_C0_STOP | LE_C0_STRT | LE_C0_INIT)); @@ -575,7 +574,7 @@ am7990_start_locked(struct lance_softc *sc) sc->sc_last_td = bix; if (enq > 0) - ifp->if_timer = 5; + sc->sc_wdog_timer = 5; } #ifdef LEDEBUG diff --git a/src/add-ons/kernel/drivers/network/pcnet/dev/le/am79900.c b/src/add-ons/kernel/drivers/network/pcnet/dev/le/am79900.c index 4c0ff2fdc62..a86590ba5fc 100644 --- a/src/add-ons/kernel/drivers/network/pcnet/dev/le/am79900.c +++ b/src/add-ons/kernel/drivers/network/pcnet/dev/le/am79900.c @@ -110,7 +110,7 @@ */ #include -__FBSDID("$FreeBSD: src/sys/dev/le/am79900.c,v 1.1.2.3 2006/06/18 15:43:18 marius Exp $"); +__FBSDID("$FreeBSD$"); #include #include @@ -172,8 +172,6 @@ am79900_config(struct am79900_softc *sc, const char* name, int unit) if (mem > sc->lsc.sc_memsize) panic("%s: memsize", __func__); - sc->lsc.sc_flags |= LE_DEBUG; - lance_attach(&sc->lsc); return (0); @@ -425,7 +423,7 @@ am79900_tint(struct lance_softc *sc) sc->sc_first_td = bix; - ifp->if_timer = sc->sc_no_td > 0 ? 5 : 0; + sc->sc_wdog_timer = sc->sc_no_td > 0 ? 5 : 0; } /* @@ -447,9 +445,9 @@ am79900_intr(void *arg) return; } -#if 0 +#ifndef __HAIKU__ isr = (*sc->sc_rdcsr)(sc, LE_CSR0); -#endif +#else { HAIKU_INTR_REGISTER_STATE; HAIKU_INTR_REGISTER_ENTER(); @@ -457,7 +455,7 @@ am79900_intr(void *arg) sc->sc_lastisr = 0; HAIKU_INTR_REGISTER_LEAVE(); } - +#endif #if defined(LEDEBUG) && LEDEBUG > 1 if (sc->sc_flags & LE_DEBUG) if_printf(ifp, "%s: entering with isr=%04x\n", __func__, isr); @@ -471,10 +469,9 @@ am79900_intr(void *arg) * Clear interrupt source flags and turn off interrupts. If we * don't clear these flags before processing their sources we * could completely miss some interrupt events as the NIC can - * change these flags while we're in this handler. We turn off - * interrupts so we don't get another RX interrupt while still - * processing the previous one in ifp->if_input() with the - * driver lock dropped. + * change these flags while we're in this handler. We toggle + * the interrupt enable bit in order to keep receiving them + * (some chips work without this, some don't). */ (*sc->sc_wrcsr)(sc, LE_CSR0, isr & ~(LE_C0_INEA | LE_C0_TDMD | LE_C0_STOP | LE_C0_STRT | LE_C0_INIT)); @@ -626,7 +623,7 @@ am79900_start_locked(struct lance_softc *sc) sc->sc_last_td = bix; if (enq > 0) - ifp->if_timer = 5; + sc->sc_wdog_timer = 5; } #ifdef LEDEBUG diff --git a/src/add-ons/kernel/drivers/network/pcnet/dev/le/am79900reg.h b/src/add-ons/kernel/drivers/network/pcnet/dev/le/am79900reg.h index 0212bbd6dd7..33610645d39 100644 --- a/src/add-ons/kernel/drivers/network/pcnet/dev/le/am79900reg.h +++ b/src/add-ons/kernel/drivers/network/pcnet/dev/le/am79900reg.h @@ -70,7 +70,7 @@ * @(#)if_lereg.h 8.1 (Berkeley) 6/10/93 */ -/* $FreeBSD: src/sys/dev/le/am79900reg.h,v 1.1.2.1 2006/02/13 11:30:40 marius Exp $ */ +/* $FreeBSD$ */ #ifndef _DEV_LE_AM79900REG_H_ #define _DEV_LE_AM79900REG_H_ diff --git a/src/add-ons/kernel/drivers/network/pcnet/dev/le/am79900var.h b/src/add-ons/kernel/drivers/network/pcnet/dev/le/am79900var.h index 39e6acb0b2e..79ab3309e13 100644 --- a/src/add-ons/kernel/drivers/network/pcnet/dev/le/am79900var.h +++ b/src/add-ons/kernel/drivers/network/pcnet/dev/le/am79900var.h @@ -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 @@ -37,7 +30,7 @@ * POSSIBILITY OF SUCH DAMAGE. */ -/* $FreeBSD: src/sys/dev/le/am79900var.h,v 1.1.2.1 2006/02/13 11:30:40 marius Exp $ */ +/* $FreeBSD$ */ #ifndef _DEV_LE_AM79900VAR_H_ #define _DEV_LE_AM79900VAR_H_ diff --git a/src/add-ons/kernel/drivers/network/pcnet/dev/le/am7990reg.h b/src/add-ons/kernel/drivers/network/pcnet/dev/le/am7990reg.h index 60af47c6144..d3f8e0d3d9f 100644 --- a/src/add-ons/kernel/drivers/network/pcnet/dev/le/am7990reg.h +++ b/src/add-ons/kernel/drivers/network/pcnet/dev/le/am7990reg.h @@ -70,7 +70,7 @@ * @(#)if_lereg.h 8.1 (Berkeley) 6/10/93 */ -/* $FreeBSD: src/sys/dev/le/am7990reg.h,v 1.1.2.1 2006/02/13 11:30:40 marius Exp $ */ +/* $FreeBSD$ */ #ifndef _DEV_LE_AM7990REG_H_ #define _DEV_LE_AM7990REG_H_ diff --git a/src/add-ons/kernel/drivers/network/pcnet/dev/le/am7990var.h b/src/add-ons/kernel/drivers/network/pcnet/dev/le/am7990var.h index 014c0316281..24cbfe05aff 100644 --- a/src/add-ons/kernel/drivers/network/pcnet/dev/le/am7990var.h +++ b/src/add-ons/kernel/drivers/network/pcnet/dev/le/am7990var.h @@ -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 @@ -37,7 +30,7 @@ * POSSIBILITY OF SUCH DAMAGE. */ -/* $FreeBSD: src/sys/dev/le/am7990var.h,v 1.1.2.1 2006/02/13 11:30:40 marius Exp $ */ +/* $FreeBSD$ */ #ifndef _DEV_LE_AM7990VAR_H_ #define _DEV_LE_AM7990VAR_H_ diff --git a/src/add-ons/kernel/drivers/network/pcnet/dev/le/if_le_ledma.c b/src/add-ons/kernel/drivers/network/pcnet/dev/le/if_le_ledma.c index e7cbc9a6f15..7b09366ec7e 100644 --- a/src/add-ons/kernel/drivers/network/pcnet/dev/le/if_le_ledma.c +++ b/src/add-ons/kernel/drivers/network/pcnet/dev/le/if_le_ledma.c @@ -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 -__FBSDID("$FreeBSD: src/sys/dev/le/if_le_ledma.c,v 1.1.2.2 2006/06/18 15:43:18 marius Exp $"); +__FBSDID("$FreeBSD$"); #include #include @@ -78,12 +71,8 @@ __FBSDID("$FreeBSD: src/sys/dev/le/if_le_ledma.c,v 1.1.2.2 2006/06/18 15:43:18 m struct le_dma_softc { struct am7990_softc sc_am7990; /* glue to MI code */ - int sc_rrid; struct resource *sc_rres; - bus_space_tag_t sc_regt; - bus_space_handle_t sc_regh; - int sc_irid; struct resource *sc_ires; void *sc_ih; @@ -92,7 +81,6 @@ struct le_dma_softc { bus_addr_t sc_laddr; /* LANCE DMA address */ struct lsi64854_softc *sc_dma; /* pointer to DMA engine */ - int sc_dodrain; }; static device_probe_t le_dma_probe; @@ -116,6 +104,7 @@ static device_method_t le_dma_methods[] = { DEFINE_CLASS_0(le, le_dma_driver, le_dma_methods, sizeof(struct le_dma_softc)); DRIVER_MODULE(le, dma, le_dma_driver, le_devclass, 0, 0); +MODULE_DEPEND(le, dma, 1, 1, 1); MODULE_DEPEND(le, ether, 1, 1, 1); /* @@ -143,10 +132,9 @@ le_dma_wrcsr(struct lance_softc *sc, uint16_t port, uint16_t val) { struct le_dma_softc *lesc = (struct le_dma_softc *)sc; - bus_space_write_2(lesc->sc_regt, lesc->sc_regh, LEREG1_RAP, port); - bus_space_barrier(lesc->sc_regt, lesc->sc_regh, LEREG1_RAP, 2, - BUS_SPACE_BARRIER_WRITE); - bus_space_write_2(lesc->sc_regt, lesc->sc_regh, LEREG1_RDP, val); + bus_write_2(lesc->sc_rres, LEREG1_RAP, port); + bus_barrier(lesc->sc_rres, LEREG1_RAP, 2, BUS_SPACE_BARRIER_WRITE); + bus_write_2(lesc->sc_rres, LEREG1_RDP, val); } static uint16_t @@ -154,10 +142,9 @@ le_dma_rdcsr(struct lance_softc *sc, uint16_t port) { struct le_dma_softc *lesc = (struct le_dma_softc *)sc; - bus_space_write_2(lesc->sc_regt, lesc->sc_regh, LEREG1_RAP, port); - bus_space_barrier(lesc->sc_regt, lesc->sc_regh, LEREG1_RAP, 2, - BUS_SPACE_BARRIER_WRITE); - return (bus_space_read_2(lesc->sc_regt, lesc->sc_regh, LEREG1_RDP)); + bus_write_2(lesc->sc_rres, LEREG1_RAP, port); + bus_barrier(lesc->sc_rres, LEREG1_RAP, 2, BUS_SPACE_BARRIER_WRITE); + return (bus_read_2(lesc->sc_rres, LEREG1_RDP)); } static void @@ -239,7 +226,7 @@ le_dma_hwreset(struct lance_softc *sc) DMA_RESET(dma); /* Write bits 24-31 of Lance address. */ - bus_space_write_4(dma->sc_regt, dma->sc_regh, L64854_REG_ENBAR, + bus_write_4(dma->sc_res, L64854_REG_ENBAR, lesc->sc_laddr & 0xff000000); DMA_ENINTR(dma); @@ -260,46 +247,7 @@ le_dma_hwintr(struct lance_softc *sc) struct le_dma_softc *lesc = (struct le_dma_softc *)sc; struct lsi64854_softc *dma = lesc->sc_dma; -#if 0 return (DMA_INTR(dma)); -#else - /* - * Inlined version of lsi64854_enet_intr() from rev. 1.8 of - * sys/sparc64/sbus/lsi64854.c in order to not break the API - * of the LSI64854 driver in RELENG_6. - */ - uint32_t csr; - int i, rv; - - csr = L64854_GCSR(dma); - - /* If the DMA logic shows an interrupt, claim it */ - rv = ((csr & E_INT_PEND) != 0) ? 1 : 0; - - if (csr & (E_ERR_PEND|E_SLAVE_ERR)) { - device_printf(dma->sc_dev, "error: csr=%b\n", csr, - EDMACSR_BITS); - csr &= ~L64854_EN_DMA; /* Stop DMA */ - /* Invalidate the queue; SLAVE_ERR bit is write-to-clear */ - csr |= E_INVALIDATE|E_SLAVE_ERR; - L64854_SCSR(dma, csr); - /* Will be drained with the LE_C0_IDON interrupt. */ - lesc->sc_dodrain = 1; - return (-1); - } - - /* XXX - is this necessary with E_DSBL_WR_INVAL on? */ - if (lesc->sc_dodrain) { - i = 10; - csr |= E_DRAIN; - L64854_SCSR(dma, csr); - while (i-- > 0 && (L64854_GCSR(dma) & E_DRAINING)) - DELAY(1); - lesc->sc_dodrain = 0; - } - - return (rv); -#endif } static void @@ -359,7 +307,7 @@ le_dma_attach(device_t dev) struct le_dma_softc *lesc; struct lsi64854_softc *dma; struct lance_softc *sc; - int error; + int error, i; lesc = device_get_softc(dev); sc = &lesc->sc_am7990.lsc; @@ -374,25 +322,30 @@ le_dma_attach(device_t dev) lesc->sc_dma = dma; lesc->sc_dma->sc_client = lesc; - lesc->sc_rrid = 0; + i = 0; lesc->sc_rres = bus_alloc_resource_any(dev, SYS_RES_MEMORY, - &lesc->sc_rrid, RF_ACTIVE); + &i, RF_ACTIVE); if (lesc->sc_rres == NULL) { device_printf(dev, "cannot allocate registers\n"); error = ENXIO; goto fail_mtx; } - lesc->sc_regt = rman_get_bustag(lesc->sc_rres); - lesc->sc_regh = rman_get_bushandle(lesc->sc_rres); - lesc->sc_irid = 0; + i = 0; if ((lesc->sc_ires = bus_alloc_resource_any(dev, SYS_RES_IRQ, - &lesc->sc_irid, RF_SHAREABLE | RF_ACTIVE)) == NULL) { + &i, RF_SHAREABLE | RF_ACTIVE)) == NULL) { device_printf(dev, "cannot allocate interrupt\n"); error = ENXIO; goto fail_rres; } + /* Attach the DMA engine. */ + error = lsi64854_attach(dma); + if (error != 0) { + device_printf(dev, "lsi64854_attach failed\n"); + goto fail_ires; + } + sc->sc_memsize = LEDMA_MEMSIZE; error = bus_dma_tag_create( dma->sc_parent_dmat, /* parent */ @@ -404,12 +357,12 @@ le_dma_attach(device_t dev) sc->sc_memsize, /* maxsize */ 1, /* nsegments */ sc->sc_memsize, /* maxsegsize */ - BUS_DMA_WAITOK, /* flags */ + 0, /* flags */ NULL, NULL, /* lockfunc, lockarg */ &lesc->sc_dmat); if (error != 0) { device_printf(dev, "cannot allocate buffer DMA tag\n"); - goto fail_ires; + goto fail_lsi; } error = bus_dmamem_alloc(lesc->sc_dmat, (void **)&sc->sc_mem, @@ -423,7 +376,7 @@ le_dma_attach(device_t dev) error = bus_dmamap_load(lesc->sc_dmat, lesc->sc_dmam, sc->sc_mem, sc->sc_memsize, le_dma_dma_callback, lesc, 0); if (error != 0 || lesc->sc_laddr == 0) { - device_printf(dev, "cannot load DMA buffer map\n"); + device_printf(dev, "cannot load DMA buffer map\n"); goto fail_dmem; } @@ -459,7 +412,7 @@ le_dma_attach(device_t dev) } error = bus_setup_intr(dev, lesc->sc_ires, INTR_TYPE_NET | INTR_MPSAFE, - am7990_intr, sc, &lesc->sc_ih); + NULL, am7990_intr, sc, &lesc->sc_ih); if (error != 0) { device_printf(dev, "cannot set up interrupt\n"); goto fail_am7990; @@ -475,10 +428,14 @@ le_dma_attach(device_t dev) bus_dmamem_free(lesc->sc_dmat, sc->sc_mem, lesc->sc_dmam); fail_dtag: bus_dma_tag_destroy(lesc->sc_dmat); + fail_lsi: + lsi64854_detach(dma); fail_ires: - bus_release_resource(dev, SYS_RES_IRQ, lesc->sc_irid, lesc->sc_ires); + bus_release_resource(dev, SYS_RES_IRQ, rman_get_rid(lesc->sc_ires), + lesc->sc_ires); fail_rres: - bus_release_resource(dev, SYS_RES_MEMORY, lesc->sc_rrid, lesc->sc_rres); + bus_release_resource(dev, SYS_RES_MEMORY, rman_get_rid(lesc->sc_rres), + lesc->sc_rres); fail_mtx: LE_LOCK_DESTROY(sc); return (error); @@ -489,6 +446,7 @@ le_dma_detach(device_t dev) { struct le_dma_softc *lesc; struct lance_softc *sc; + int error; lesc = device_get_softc(dev); sc = &lesc->sc_am7990.lsc; @@ -498,8 +456,13 @@ le_dma_detach(device_t dev) bus_dmamap_unload(lesc->sc_dmat, lesc->sc_dmam); bus_dmamem_free(lesc->sc_dmat, sc->sc_mem, lesc->sc_dmam); bus_dma_tag_destroy(lesc->sc_dmat); - bus_release_resource(dev, SYS_RES_IRQ, lesc->sc_irid, lesc->sc_ires); - bus_release_resource(dev, SYS_RES_MEMORY, lesc->sc_rrid, lesc->sc_rres); + error = lsi64854_detach(lesc->sc_dma); + if (error != 0) + return (error); + bus_release_resource(dev, SYS_RES_IRQ, rman_get_rid(lesc->sc_ires), + lesc->sc_ires); + bus_release_resource(dev, SYS_RES_MEMORY, rman_get_rid(lesc->sc_rres), + lesc->sc_rres); LE_LOCK_DESTROY(sc); return (0); diff --git a/src/add-ons/kernel/drivers/network/pcnet/dev/le/if_le_pci.c b/src/add-ons/kernel/drivers/network/pcnet/dev/le/if_le_pci.c index 672e12a6013..b989fe00655 100644 --- a/src/add-ons/kernel/drivers/network/pcnet/dev/le/if_le_pci.c +++ b/src/add-ons/kernel/drivers/network/pcnet/dev/le/if_le_pci.c @@ -72,7 +72,7 @@ */ #include -__FBSDID("$FreeBSD: src/sys/dev/le/if_le_pci.c,v 1.1.2.2 2006/06/18 15:43:18 marius Exp $"); +__FBSDID("$FreeBSD$"); #include #include @@ -111,12 +111,8 @@ __FBSDID("$FreeBSD: src/sys/dev/le/if_le_pci.c,v 1.1.2.2 2006/06/18 15:43:18 mar struct le_pci_softc { struct am79900_softc sc_am79900; /* glue to MI code */ - int sc_rrid; struct resource *sc_rres; - bus_space_tag_t sc_regt; - bus_space_handle_t sc_regh; - int sc_irid; struct resource *sc_ires; void *sc_ih; @@ -174,10 +170,9 @@ le_pci_wrbcr(struct lance_softc *sc, uint16_t port, uint16_t val) { struct le_pci_softc *lesc = (struct le_pci_softc *)sc; - bus_space_write_2(lesc->sc_regt, lesc->sc_regh, PCNET_PCI_RAP, port); - bus_space_barrier(lesc->sc_regt, lesc->sc_regh, PCNET_PCI_RAP, 2, - BUS_SPACE_BARRIER_WRITE); - bus_space_write_2(lesc->sc_regt, lesc->sc_regh, PCNET_PCI_BDP, val); + bus_write_2(lesc->sc_rres, PCNET_PCI_RAP, port); + bus_barrier(lesc->sc_rres, PCNET_PCI_RAP, 2, BUS_SPACE_BARRIER_WRITE); + bus_write_2(lesc->sc_rres, PCNET_PCI_BDP, val); } static uint16_t @@ -185,45 +180,51 @@ le_pci_rdbcr(struct lance_softc *sc, uint16_t port) { struct le_pci_softc *lesc = (struct le_pci_softc *)sc; - bus_space_write_2(lesc->sc_regt, lesc->sc_regh, PCNET_PCI_RAP, port); - bus_space_barrier(lesc->sc_regt, lesc->sc_regh, PCNET_PCI_RAP, 2, - BUS_SPACE_BARRIER_WRITE); - return (bus_space_read_2(lesc->sc_regt, lesc->sc_regh, PCNET_PCI_BDP)); + bus_write_2(lesc->sc_rres, PCNET_PCI_RAP, port); + bus_barrier(lesc->sc_rres, PCNET_PCI_RAP, 2, BUS_SPACE_BARRIER_WRITE); + return (bus_read_2(lesc->sc_rres, PCNET_PCI_BDP)); } static void le_pci_wrcsr(struct lance_softc *sc, uint16_t port, uint16_t val) { struct le_pci_softc *lesc = (struct le_pci_softc *)sc; - HAIKU_INTR_REGISTER_STATE; +#ifdef __HAIKU__ + HAIKU_INTR_REGISTER_STATE; if (port == LE_CSR0) HAIKU_INTR_REGISTER_ENTER(); - bus_space_write_2(lesc->sc_regt, lesc->sc_regh, PCNET_PCI_RAP, port); - bus_space_barrier(lesc->sc_regt, lesc->sc_regh, PCNET_PCI_RAP, 2, - BUS_SPACE_BARRIER_WRITE); - bus_space_write_2(lesc->sc_regt, lesc->sc_regh, PCNET_PCI_RDP, val); +#endif + bus_write_2(lesc->sc_rres, PCNET_PCI_RAP, port); + bus_barrier(lesc->sc_rres, PCNET_PCI_RAP, 2, BUS_SPACE_BARRIER_WRITE); + bus_write_2(lesc->sc_rres, PCNET_PCI_RDP, val); +#ifdef __HAIKU__ if (port == LE_CSR0) HAIKU_INTR_REGISTER_LEAVE(); +#endif } static uint16_t le_pci_rdcsr(struct lance_softc *sc, uint16_t port) { struct le_pci_softc *lesc = (struct le_pci_softc *)sc; + +#ifdef __HAIKU__ HAIKU_INTR_REGISTER_STATE; uint16_t value; - if (port == LE_CSR0) HAIKU_INTR_REGISTER_ENTER(); - bus_space_write_2(lesc->sc_regt, lesc->sc_regh, PCNET_PCI_RAP, port); - bus_space_barrier(lesc->sc_regt, lesc->sc_regh, PCNET_PCI_RAP, 2, - BUS_SPACE_BARRIER_WRITE); - value = bus_space_read_2(lesc->sc_regt, lesc->sc_regh, PCNET_PCI_RDP); +#endif + bus_write_2(lesc->sc_rres, PCNET_PCI_RAP, port); + bus_barrier(lesc->sc_rres, PCNET_PCI_RAP, 2, BUS_SPACE_BARRIER_WRITE); +#ifndef __HAIKU__ + return (bus_read_2(lesc->sc_rres, PCNET_PCI_RDP)); +#else + value = bus_read_2(lesc->sc_rres, PCNET_PCI_RDP); if (port == LE_CSR0) HAIKU_INTR_REGISTER_LEAVE(); - return value; +#endif } static int @@ -309,11 +310,11 @@ le_pci_probe(device_t dev) switch (pci_get_device(dev)) { case AMD_PCNET_PCI: device_set_desc(dev, "AMD PCnet-PCI"); - /* Let lnc(4) and pcn(4) win. */ + /* Let pcn(4) win. */ return (BUS_PROBE_LOW_PRIORITY); case AMD_PCNET_HOME: device_set_desc(dev, "AMD PCnet-Home"); - /* Let lnc(4) and pcn(4) win. */ + /* Let pcn(4) win. */ return (BUS_PROBE_LOW_PRIORITY); default: return (ENXIO); @@ -333,29 +334,26 @@ le_pci_attach(device_t dev) LE_LOCK_INIT(sc, device_get_nameunit(dev)); pci_enable_busmaster(dev); - pci_enable_io(dev, PCIM_CMD_PORTEN); - lesc->sc_rrid = PCIR_BAR(0); + i = PCIR_BAR(0); lesc->sc_rres = bus_alloc_resource_any(dev, SYS_RES_IOPORT, - &lesc->sc_rrid, RF_ACTIVE); + &i, RF_ACTIVE); if (lesc->sc_rres == NULL) { device_printf(dev, "cannot allocate registers\n"); error = ENXIO; goto fail_mtx; } - lesc->sc_regt = rman_get_bustag(lesc->sc_rres); - lesc->sc_regh = rman_get_bushandle(lesc->sc_rres); - lesc->sc_irid = 0; + i = 0; if ((lesc->sc_ires = bus_alloc_resource_any(dev, SYS_RES_IRQ, - &lesc->sc_irid, RF_SHAREABLE | RF_ACTIVE)) == NULL) { + &i, RF_SHAREABLE | RF_ACTIVE)) == NULL) { device_printf(dev, "cannot allocate interrupt\n"); error = ENXIO; goto fail_rres; } error = bus_dma_tag_create( - NULL, /* parent */ + bus_get_dma_tag(dev), /* parent */ 1, 0, /* alignment, boundary */ BUS_SPACE_MAXADDR_32BIT, /* lowaddr */ BUS_SPACE_MAXADDR, /* highaddr */ @@ -363,7 +361,7 @@ le_pci_attach(device_t dev) BUS_SPACE_MAXSIZE_32BIT, /* maxsize */ 0, /* nsegments */ BUS_SPACE_MAXSIZE_32BIT, /* maxsegsize */ - BUS_DMA_WAITOK, /* flags */ + 0, /* flags */ NULL, NULL, /* lockfunc, lockarg */ &lesc->sc_pdmat); if (error != 0) { @@ -386,7 +384,7 @@ le_pci_attach(device_t dev) sc->sc_memsize, /* maxsize */ 1, /* nsegments */ sc->sc_memsize, /* maxsegsize */ - BUS_DMA_WAITOK, /* flags */ + 0, /* flags */ NULL, NULL, /* lockfunc, lockarg */ &lesc->sc_dmat); if (error != 0) { @@ -405,7 +403,7 @@ le_pci_attach(device_t dev) error = bus_dmamap_load(lesc->sc_dmat, lesc->sc_dmam, sc->sc_mem, sc->sc_memsize, le_pci_dma_callback, sc, 0); if (error != 0 || sc->sc_addr == 0) { - device_printf(dev, "cannot load DMA buffer map\n"); + device_printf(dev, "cannot load DMA buffer map\n"); goto fail_dmem; } @@ -430,9 +428,8 @@ le_pci_attach(device_t dev) /* * Extract the physical MAC address from the ROM. */ - for (i = 0; i < sizeof(sc->sc_enaddr); i++) - sc->sc_enaddr[i] = - bus_space_read_1(lesc->sc_regt, lesc->sc_regh, i); + bus_read_region_1(lesc->sc_rres, 0, sc->sc_enaddr, + sizeof(sc->sc_enaddr)); sc->sc_copytodesc = lance_copytobuf_contig; sc->sc_copyfromdesc = lance_copyfrombuf_contig; @@ -474,9 +471,11 @@ le_pci_attach(device_t dev) fail_pdtag: bus_dma_tag_destroy(lesc->sc_pdmat); fail_ires: - bus_release_resource(dev, SYS_RES_IRQ, lesc->sc_irid, lesc->sc_ires); + bus_release_resource(dev, SYS_RES_IRQ, + rman_get_rid(lesc->sc_ires), lesc->sc_ires); fail_rres: - bus_release_resource(dev, SYS_RES_IOPORT, lesc->sc_rrid, lesc->sc_rres); + bus_release_resource(dev, SYS_RES_IOPORT, + rman_get_rid(lesc->sc_rres), lesc->sc_rres); fail_mtx: LE_LOCK_DESTROY(sc); return (error); @@ -497,8 +496,10 @@ le_pci_detach(device_t dev) bus_dmamem_free(lesc->sc_dmat, sc->sc_mem, lesc->sc_dmam); bus_dma_tag_destroy(lesc->sc_dmat); bus_dma_tag_destroy(lesc->sc_pdmat); - bus_release_resource(dev, SYS_RES_IRQ, lesc->sc_irid, lesc->sc_ires); - bus_release_resource(dev, SYS_RES_IOPORT, lesc->sc_rrid, lesc->sc_rres); + bus_release_resource(dev, SYS_RES_IRQ, + rman_get_rid(lesc->sc_ires), lesc->sc_ires); + bus_release_resource(dev, SYS_RES_IOPORT, + rman_get_rid(lesc->sc_rres), lesc->sc_rres); LE_LOCK_DESTROY(sc); return (0); diff --git a/src/add-ons/kernel/drivers/network/pcnet/dev/le/lance.c b/src/add-ons/kernel/drivers/network/pcnet/dev/le/lance.c index 285196bfe0c..8700aa2cd43 100644 --- a/src/add-ons/kernel/drivers/network/pcnet/dev/le/lance.c +++ b/src/add-ons/kernel/drivers/network/pcnet/dev/le/lance.c @@ -72,12 +72,13 @@ */ #include -__FBSDID("$FreeBSD: src/sys/dev/le/lance.c,v 1.1.2.2 2006/06/18 15:43:18 marius Exp $"); +__FBSDID("$FreeBSD$"); #include #include #include #include +#include #include #include #include @@ -101,7 +102,7 @@ devclass_t le_devclass; static void lance_start(struct ifnet *); static void lance_stop(struct lance_softc *); static void lance_init(void *); -static void lance_watchdog(struct ifnet *); +static void lance_watchdog(void *s); static int lance_mediachange(struct ifnet *); static void lance_mediastatus(struct ifnet *, struct ifmediareq *); static int lance_ioctl(struct ifnet *, u_long, caddr_t); @@ -119,20 +120,21 @@ lance_config(struct lance_softc *sc, const char* name, int unit) if (ifp == NULL) return (ENOSPC); + callout_init_mtx(&sc->sc_wdog_ch, &sc->sc_mtx, 0); + /* Initialize ifnet structure. */ ifp->if_softc = sc; if_initname(ifp, name, unit); ifp->if_start = lance_start; ifp->if_ioctl = lance_ioctl; - ifp->if_watchdog = lance_watchdog; ifp->if_init = lance_init; ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; #ifdef LANCE_REVC_BUG ifp->if_flags &= ~IFF_MULTICAST; #endif ifp->if_baudrate = IF_Mbps(10); - IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN); - ifp->if_snd.ifq_drv_maxlen = IFQ_MAXLEN; + IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen); + ifp->if_snd.ifq_drv_maxlen = ifqmaxlen; IFQ_SET_READY(&ifp->if_snd); /* Initialize ifmedia structures. */ @@ -213,6 +215,7 @@ lance_detach(struct lance_softc *sc) LE_LOCK(sc); lance_stop(sc); LE_UNLOCK(sc); + callout_drain(&sc->sc_wdog_ch); ether_ifdetach(ifp); if_free(ifp); } @@ -257,7 +260,8 @@ lance_stop(struct lance_softc *sc) * Mark the interface down and cancel the watchdog timer. */ ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); - ifp->if_timer = 0; + callout_stop(&sc->sc_wdog_ch); + sc->sc_wdog_timer = 0; (*sc->sc_wrcsr)(sc, LE_CSR0, LE_C0_STOP); } @@ -295,6 +299,10 @@ lance_init_locked(struct lance_softc *sc) /* Set the correct byte swapping mode, etc. */ (*sc->sc_wrcsr)(sc, LE_CSR3, sc->sc_conf3); + /* Set the current media. This may require the chip to be stopped. */ + if (sc->sc_mediachange) + (void)(*sc->sc_mediachange)(sc); + /* * Update our private copy of the Ethernet address. * We NEED the copy so we can ensure its alignment! @@ -318,16 +326,13 @@ lance_init_locked(struct lance_softc *sc) if ((*sc->sc_rdcsr)(sc, LE_CSR0) & LE_C0_IDON) break; - /* Set the current media. */ - if (sc->sc_mediachange) - (void)(*sc->sc_mediachange)(sc); - if ((*sc->sc_rdcsr)(sc, LE_CSR0) & LE_C0_IDON) { /* Start the LANCE. */ (*sc->sc_wrcsr)(sc, LE_CSR0, LE_C0_INEA | LE_C0_STRT); ifp->if_drv_flags |= IFF_DRV_RUNNING; ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; - ifp->if_timer = 0; + sc->sc_wdog_timer = 0; + callout_reset(&sc->sc_wdog_ch, hz, lance_watchdog, sc); (*sc->sc_start_locked)(sc); } else if_printf(ifp, "controller failed to initialize\n"); @@ -434,28 +439,42 @@ lance_get(struct lance_softc *sc, int boff, int totlen) } static void -lance_watchdog(struct ifnet *ifp) +lance_watchdog(void *xsc) { - struct lance_softc *sc = ifp->if_softc; + struct lance_softc *sc = (struct lance_softc *)xsc; + struct ifnet *ifp = sc->sc_ifp; + + LE_LOCK_ASSERT(sc, MA_OWNED); + + if (sc->sc_wdog_timer == 0 || --sc->sc_wdog_timer != 0) { + callout_reset(&sc->sc_wdog_ch, hz, lance_watchdog, sc); + return; + } - LE_LOCK(sc); if_printf(ifp, "device timeout\n"); ++ifp->if_oerrors; lance_init_locked(sc); - LE_UNLOCK(sc); } static int lance_mediachange(struct ifnet *ifp) { struct lance_softc *sc = ifp->if_softc; - int error; if (sc->sc_mediachange) { + /* + * For setting the port in LE_CSR15 the PCnet chips must + * be powered down or stopped and unlike documented may + * not take effect without an initialization. So don't + * invoke (*sc_mediachange) directly here but go through + * lance_init_locked(). + */ LE_LOCK(sc); - error = (*sc->sc_mediachange)(sc); + lance_stop(sc); + lance_init_locked(sc); + if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) + (*sc->sc_start_locked)(sc); LE_UNLOCK(sc); - return (error); } return (0); } @@ -586,7 +605,7 @@ lance_setladrf(struct lance_softc *sc, uint16_t *af) } af[0] = af[1] = af[2] = af[3] = 0x0000; - IF_ADDR_LOCK(ifp); + if_maddr_rlock(ifp); TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { if (ifma->ifma_addr->sa_family != AF_LINK) continue; @@ -600,7 +619,7 @@ lance_setladrf(struct lance_softc *sc, uint16_t *af) /* Set the corresponding bit in the filter. */ af[crc >> 4] |= LE_HTOLE16(1 << (crc & 0xf)); } - IF_ADDR_UNLOCK(ifp); + if_maddr_runlock(ifp); } /* diff --git a/src/add-ons/kernel/drivers/network/pcnet/dev/le/lancereg.h b/src/add-ons/kernel/drivers/network/pcnet/dev/le/lancereg.h index e5165e96311..3e0ce060dcf 100644 --- a/src/add-ons/kernel/drivers/network/pcnet/dev/le/lancereg.h +++ b/src/add-ons/kernel/drivers/network/pcnet/dev/le/lancereg.h @@ -120,7 +120,7 @@ * valid on the LANCE. */ -/* $FreeBSD: src/sys/dev/le/lancereg.h,v 1.1.2.2 2006/06/18 15:43:18 marius Exp $ */ +/* $FreeBSD$ */ #ifndef _DEV_LE_LANCEREG_H_ #define _DEV_LE_LANCEREG_H_ diff --git a/src/add-ons/kernel/drivers/network/pcnet/dev/le/lancevar.h b/src/add-ons/kernel/drivers/network/pcnet/dev/le/lancevar.h index c7fb69976e7..1491ea762a2 100644 --- a/src/add-ons/kernel/drivers/network/pcnet/dev/le/lancevar.h +++ b/src/add-ons/kernel/drivers/network/pcnet/dev/le/lancevar.h @@ -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 @@ -37,7 +30,7 @@ * POSSIBILITY OF SUCH DAMAGE. */ -/* $FreeBSD: src/sys/dev/le/lancevar.h,v 1.1.2.2 2006/06/18 15:43:18 marius Exp $ */ +/* $FreeBSD$ */ #ifndef _DEV_LE_LANCEVAR_H_ #define _DEV_LE_LANCEVAR_H_ @@ -48,6 +41,8 @@ struct lance_softc { struct ifnet *sc_ifp; struct ifmedia sc_media; struct mtx sc_mtx; + struct callout sc_wdog_ch; + int sc_wdog_timer; /* * Memory functions: @@ -120,7 +115,9 @@ struct lance_softc { #define LE_DEBUG (1 << 3) #define LE_PROMISC (1 << 4) +#ifdef __HAIKU__ uint16_t sc_lastisr; +#endif }; #define LE_LOCK_INIT(_sc, _name) \ diff --git a/src/add-ons/kernel/drivers/network/rtl8139/pci/if_rl.c b/src/add-ons/kernel/drivers/network/rtl8139/pci/if_rl.c index ab60d68229e..8cd6a91bc33 100644 --- a/src/add-ons/kernel/drivers/network/rtl8139/pci/if_rl.c +++ b/src/add-ons/kernel/drivers/network/rtl8139/pci/if_rl.c @@ -31,7 +31,7 @@ */ #include -__FBSDID("$FreeBSD: src/sys/pci/if_rl.c,v 1.189.2.8.2.1 2010/12/21 17:09:25 kensmith Exp $"); +__FBSDID("$FreeBSD$"); /* * RealTek 8129/8139 PCI NIC driver @@ -239,16 +239,12 @@ static device_method_t rl_methods[] = { DEVMETHOD(device_resume, rl_resume), DEVMETHOD(device_shutdown, rl_shutdown), - /* bus interface */ - DEVMETHOD(bus_print_child, bus_generic_print_child), - DEVMETHOD(bus_driver_added, bus_generic_driver_added), - /* MII interface */ DEVMETHOD(miibus_readreg, rl_miibus_readreg), DEVMETHOD(miibus_writereg, rl_miibus_writereg), DEVMETHOD(miibus_statchg, rl_miibus_statchg), - { 0, 0 } + DEVMETHOD_END }; static driver_t rl_driver = { @@ -721,6 +717,13 @@ rl_attach(device_t dev) goto fail; } + sc->rl_cfg0 = RL_8139_CFG0; + sc->rl_cfg1 = RL_8139_CFG1; + sc->rl_cfg2 = 0; + sc->rl_cfg3 = RL_8139_CFG3; + sc->rl_cfg4 = RL_8139_CFG4; + sc->rl_cfg5 = RL_8139_CFG5; + /* * Reset the adapter. Only take the lock here as it's needed in * order to call rl_reset(). @@ -822,6 +825,7 @@ rl_attach(device_t dev) } } ifp->if_capenable = ifp->if_capabilities; + ifp->if_capenable &= ~(IFCAP_WOL_UCAST | IFCAP_WOL_MCAST); #ifdef DEVICE_POLLING ifp->if_capabilities |= IFCAP_POLLING; #endif @@ -1758,7 +1762,7 @@ rl_init_locked(struct rl_softc *sc) sc->rl_flags &= ~RL_FLAG_LINK; mii_mediachg(mii); - CSR_WRITE_1(sc, RL_CFG1, RL_CFG1_DRVLOAD|RL_CFG1_FULLDUPLEX); + CSR_WRITE_1(sc, sc->rl_cfg1, RL_CFG1_DRVLOAD|RL_CFG1_FULLDUPLEX); ifp->if_drv_flags |= IFF_DRV_RUNNING; ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; @@ -1797,9 +1801,9 @@ rl_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr) RL_LOCK(sc); mii_pollstat(mii); - RL_UNLOCK(sc); ifmr->ifm_active = mii->mii_media_active; ifmr->ifm_status = mii->mii_media_status; + RL_UNLOCK(sc); } static int @@ -2059,22 +2063,19 @@ rl_setwol(struct rl_softc *sc) CSR_WRITE_1(sc, RL_EECMD, RL_EE_MODE); /* Enable PME. */ - v = CSR_READ_1(sc, RL_CFG1); + v = CSR_READ_1(sc, sc->rl_cfg1); v &= ~RL_CFG1_PME; if ((ifp->if_capenable & IFCAP_WOL) != 0) v |= RL_CFG1_PME; - CSR_WRITE_1(sc, RL_CFG1, v); + CSR_WRITE_1(sc, sc->rl_cfg1, v); - v = CSR_READ_1(sc, RL_CFG3); + v = CSR_READ_1(sc, sc->rl_cfg3); v &= ~(RL_CFG3_WOL_LINK | RL_CFG3_WOL_MAGIC); if ((ifp->if_capenable & IFCAP_WOL_MAGIC) != 0) v |= RL_CFG3_WOL_MAGIC; - CSR_WRITE_1(sc, RL_CFG3, v); + CSR_WRITE_1(sc, sc->rl_cfg3, v); - /* Config register write done. */ - CSR_WRITE_1(sc, RL_EECMD, RL_EEMODE_OFF); - - v = CSR_READ_1(sc, RL_CFG5); + v = CSR_READ_1(sc, sc->rl_cfg5); v &= ~(RL_CFG5_WOL_BCAST | RL_CFG5_WOL_MCAST | RL_CFG5_WOL_UCAST); v &= ~RL_CFG5_WOL_LANWAKE; if ((ifp->if_capenable & IFCAP_WOL_UCAST) != 0) @@ -2083,7 +2084,11 @@ rl_setwol(struct rl_softc *sc) v |= RL_CFG5_WOL_MCAST | RL_CFG5_WOL_BCAST; if ((ifp->if_capenable & IFCAP_WOL) != 0) v |= RL_CFG5_WOL_LANWAKE; - CSR_WRITE_1(sc, RL_CFG5, v); + CSR_WRITE_1(sc, sc->rl_cfg5, v); + + /* Config register write done. */ + CSR_WRITE_1(sc, RL_EECMD, RL_EEMODE_OFF); + /* Request PME if WOL is requested. */ pmstat = pci_read_config(sc->rl_dev, pmc + PCIR_POWER_STATUS, 2); pmstat &= ~(PCIM_PSTAT_PME | PCIM_PSTAT_PMEENABLE); @@ -2105,15 +2110,15 @@ rl_clrwol(struct rl_softc *sc) /* Enable config register write. */ CSR_WRITE_1(sc, RL_EECMD, RL_EE_MODE); - v = CSR_READ_1(sc, RL_CFG3); + v = CSR_READ_1(sc, sc->rl_cfg3); v &= ~(RL_CFG3_WOL_LINK | RL_CFG3_WOL_MAGIC); - CSR_WRITE_1(sc, RL_CFG3, v); + CSR_WRITE_1(sc, sc->rl_cfg3, v); /* Config register write done. */ CSR_WRITE_1(sc, RL_EECMD, RL_EEMODE_OFF); - v = CSR_READ_1(sc, RL_CFG5); + v = CSR_READ_1(sc, sc->rl_cfg5); v &= ~(RL_CFG5_WOL_BCAST | RL_CFG5_WOL_MCAST | RL_CFG5_WOL_UCAST); v &= ~RL_CFG5_WOL_LANWAKE; - CSR_WRITE_1(sc, RL_CFG5, v); + CSR_WRITE_1(sc, sc->rl_cfg5, v); } diff --git a/src/add-ons/kernel/drivers/network/rtl8139/pci/if_rlreg.h b/src/add-ons/kernel/drivers/network/rtl8139/pci/if_rlreg.h index d8732c1b0ed..7822ce3654b 100644 --- a/src/add-ons/kernel/drivers/network/rtl8139/pci/if_rlreg.h +++ b/src/add-ons/kernel/drivers/network/rtl8139/pci/if_rlreg.h @@ -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/pci/if_rlreg.h,v 1.97.2.8.2.1 2010/12/21 17:09:25 kensmith Exp $ + * $FreeBSD$ */ /* @@ -74,6 +74,14 @@ #define RL_TIMERCNT 0x0048 /* timer count register */ #define RL_MISSEDPKT 0x004C /* missed packet counter */ #define RL_EECMD 0x0050 /* EEPROM command register */ + +/* RTL8139/RTL8139C+ only */ +#define RL_8139_CFG0 0x0051 /* config register #0 */ +#define RL_8139_CFG1 0x0052 /* config register #1 */ +#define RL_8139_CFG3 0x0059 /* config register #3 */ +#define RL_8139_CFG4 0x005A /* config register #4 */ +#define RL_8139_CFG5 0x00D8 /* config register #5 */ + #define RL_CFG0 0x0051 /* config register #0 */ #define RL_CFG1 0x0052 /* config register #1 */ #define RL_CFG2 0x0053 /* config register #2 */ @@ -143,6 +151,7 @@ */ #define RL_TXCFG_CLRABRT 0x00000001 /* retransmit aborted pkt */ #define RL_TXCFG_MAXDMA 0x00000700 /* max DMA burst size */ +#define RL_TXCFG_QUEUE_EMPTY 0x00000800 /* 8168E-VL or higher */ #define RL_TXCFG_CRCAPPEND 0x00010000 /* CRC append (0 = yes) */ #define RL_TXCFG_LOOPBKTST 0x00060000 /* loopback test */ #define RL_TXCFG_IFG2 0x00080000 /* 8169 only */ @@ -178,6 +187,10 @@ #define RL_HWREV_8168C_SPIN2 0x3C400000 #define RL_HWREV_8168CP 0x3C800000 #define RL_HWREV_8105E 0x40800000 +#define RL_HWREV_8105E_SPIN1 0x40C00000 +#define RL_HWREV_8402 0x44000000 +#define RL_HWREV_8168F 0x48000000 +#define RL_HWREV_8411 0x48800000 #define RL_HWREV_8139 0x60000000 #define RL_HWREV_8139A 0x70000000 #define RL_HWREV_8139AG 0x70800000 @@ -866,7 +879,14 @@ struct rl_softc { const struct rl_hwrev *rl_hwrev; int rl_eecmd_read; int rl_eewidth; + int rl_expcap; int rl_txthresh; + bus_size_t rl_cfg0; + bus_size_t rl_cfg1; + bus_size_t rl_cfg2; + bus_size_t rl_cfg3; + bus_size_t rl_cfg4; + bus_size_t rl_cfg5; struct rl_chain_data rl_cdata; struct rl_list_data rl_ldata; struct callout rl_stat_callout; @@ -892,22 +912,25 @@ struct rl_softc { int rl_int_rx_act; int rl_int_rx_mod; uint32_t rl_flags; -#define RL_FLAG_MSI 0x0001 -#define RL_FLAG_AUTOPAD 0x0002 -#define RL_FLAG_PHYWAKE_PM 0x0004 -#define RL_FLAG_PHYWAKE 0x0008 -#define RL_FLAG_JUMBOV2 0x0010 -#define RL_FLAG_PAR 0x0020 -#define RL_FLAG_DESCV2 0x0040 -#define RL_FLAG_MACSTAT 0x0080 -#define RL_FLAG_FASTETHER 0x0100 -#define RL_FLAG_CMDSTOP 0x0200 -#define RL_FLAG_MACRESET 0x0400 -#define RL_FLAG_MSIX 0x0800 -#define RL_FLAG_WOLRXENB 0x1000 -#define RL_FLAG_MACSLEEP 0x2000 -#define RL_FLAG_PCIE 0x4000 -#define RL_FLAG_LINK 0x8000 +#define RL_FLAG_MSI 0x00000001 +#define RL_FLAG_AUTOPAD 0x00000002 +#define RL_FLAG_PHYWAKE_PM 0x00000004 +#define RL_FLAG_PHYWAKE 0x00000008 +#define RL_FLAG_JUMBOV2 0x00000010 +#define RL_FLAG_PAR 0x00000020 +#define RL_FLAG_DESCV2 0x00000040 +#define RL_FLAG_MACSTAT 0x00000080 +#define RL_FLAG_FASTETHER 0x00000100 +#define RL_FLAG_CMDSTOP 0x00000200 +#define RL_FLAG_MACRESET 0x00000400 +#define RL_FLAG_MSIX 0x00000800 +#define RL_FLAG_WOLRXENB 0x00001000 +#define RL_FLAG_MACSLEEP 0x00002000 +#define RL_FLAG_WAIT_TXPOLL 0x00004000 +#define RL_FLAG_CMDSTOP_WAIT_TXQ 0x00008000 +#define RL_FLAG_WOL_MANLINK 0x00010000 +#define RL_FLAG_PCIE 0x40000000 +#define RL_FLAG_LINK 0x80000000 }; #define RL_LOCK(_sc) mtx_lock(&(_sc)->rl_mtx) diff --git a/src/add-ons/kernel/drivers/network/rtl81xx/dev/mii/rgephy.c b/src/add-ons/kernel/drivers/network/rtl81xx/dev/mii/rgephy.c index 6d54542723a..aadc6fd9676 100644 --- a/src/add-ons/kernel/drivers/network/rtl81xx/dev/mii/rgephy.c +++ b/src/add-ons/kernel/drivers/network/rtl81xx/dev/mii/rgephy.c @@ -68,7 +68,7 @@ static device_method_t rgephy_methods[] = { DEVMETHOD(device_attach, rgephy_attach), DEVMETHOD(device_detach, mii_phy_detach), DEVMETHOD(device_shutdown, bus_generic_shutdown), - { 0, 0 } + DEVMETHOD_END }; static devclass_t rgephy_devclass; @@ -110,10 +110,15 @@ static int rgephy_attach(device_t dev) { struct mii_softc *sc; + struct mii_attach_args *ma; + u_int flags; sc = device_get_softc(dev); - - mii_phy_dev_attach(dev, 0, &rgephy_funcs, 0); + ma = device_get_ivars(dev); + flags = 0; + if (strcmp(ma->mii_data->mii_ifp->if_dname, "re") == 0) + flags |= MIIF_PHYPRIV0; + mii_phy_dev_attach(dev, flags, &rgephy_funcs, 0); /* RTL8169S do not report auto-sense; add manually. */ sc->mii_capabilities = (PHY_READ(sc, MII_BMSR) | BMSR_ANEG) & @@ -243,7 +248,8 @@ rgephy_service(struct mii_softc *sc, struct mii_data *mii, int cmd) * Check to see if we have link. If we do, we don't * need to restart the autonegotiation process. */ - if (sc->mii_mpd_rev >= 2) { + if ((sc->mii_flags & MIIF_PHYPRIV0) == 0 && + sc->mii_mpd_rev >= 2) { /* RTL8211B(L) */ reg = PHY_READ(sc, RGEPHY_MII_SSR); if (reg & RGEPHY_SSR_LINK) { @@ -298,7 +304,7 @@ rgephy_status(struct mii_softc *sc) mii->mii_media_status = IFM_AVALID; mii->mii_media_active = IFM_ETHER; - if (sc->mii_mpd_rev >= 2) { + if ((sc->mii_flags & MIIF_PHYPRIV0) == 0 && sc->mii_mpd_rev >= 2) { ssr = PHY_READ(sc, RGEPHY_MII_SSR); if (ssr & RGEPHY_SSR_LINK) mii->mii_media_status |= IFM_ACTIVE; @@ -328,7 +334,7 @@ rgephy_status(struct mii_softc *sc) } } - if (sc->mii_mpd_rev >= 2) { + if ((sc->mii_flags & MIIF_PHYPRIV0) == 0 && sc->mii_mpd_rev >= 2) { ssr = PHY_READ(sc, RGEPHY_MII_SSR); switch (ssr & RGEPHY_SSR_SPD_MASK) { case RGEPHY_SSR_S1000: @@ -484,7 +490,7 @@ rgephy_reset(struct mii_softc *sc) { uint16_t ssr; - if (sc->mii_mpd_rev == 3) { + if ((sc->mii_flags & MIIF_PHYPRIV0) == 0 && sc->mii_mpd_rev == 3) { /* RTL8211C(L) */ ssr = PHY_READ(sc, RGEPHY_MII_SSR); if ((ssr & RGEPHY_SSR_ALDPS) != 0) { diff --git a/src/add-ons/kernel/drivers/network/rtl81xx/dev/re/if_re.c b/src/add-ons/kernel/drivers/network/rtl81xx/dev/re/if_re.c index 3c45cc97d9c..a056ea77056 100644 --- a/src/add-ons/kernel/drivers/network/rtl81xx/dev/re/if_re.c +++ b/src/add-ons/kernel/drivers/network/rtl81xx/dev/re/if_re.c @@ -171,7 +171,7 @@ TUNABLE_INT("hw.re.prefer_iomap", &prefer_iomap); /* * Various supported device vendors/types and their names. */ -static struct rl_type re_devs[] = { +static const struct rl_type const re_devs[] = { { DLINK_VENDORID, DLINK_DEVICEID_528T, 0, "D-Link DGE-528(T) Gigabit Ethernet Adapter" }, { DLINK_VENDORID, DLINK_DEVICEID_530T_REVC, 0, @@ -181,7 +181,7 @@ static struct rl_type re_devs[] = { { RT_VENDORID, RT_DEVICEID_8101E, 0, "RealTek 810xE PCIe 10/100baseTX" }, { RT_VENDORID, RT_DEVICEID_8168, 0, - "RealTek 8168/8111 B/C/CP/D/DP/E PCIe Gigabit Ethernet" }, + "RealTek 8168/8111 B/C/CP/D/DP/E/F PCIe Gigabit Ethernet" }, { RT_VENDORID, RT_DEVICEID_8169, 0, "RealTek 8169/8169S/8169SB(L)/8110S/8110SB(L) Gigabit Ethernet" }, { RT_VENDORID, RT_DEVICEID_8169SC, 0, @@ -194,8 +194,8 @@ static struct rl_type re_devs[] = { "US Robotics 997902 (RTL8169S) Gigabit Ethernet" } }; -static struct rl_hwrev re_hwrevs[] = { - { RL_HWREV_8139, RL_8139, "", RL_MTU }, +static const struct rl_hwrev const re_hwrevs[] = { + { RL_HWREV_8139, RL_8139, "", RL_MTU }, { RL_HWREV_8139A, RL_8139, "A", RL_MTU }, { RL_HWREV_8139AG, RL_8139, "A-G", RL_MTU }, { RL_HWREV_8139B, RL_8139, "B", RL_MTU }, @@ -220,7 +220,9 @@ static struct rl_hwrev re_hwrevs[] = { { RL_HWREV_8102EL_SPIN1, RL_8169, "8102EL", RL_MTU }, { RL_HWREV_8103E, RL_8169, "8103E", RL_MTU }, { RL_HWREV_8401E, RL_8169, "8401E", RL_MTU }, + { RL_HWREV_8402, RL_8169, "8402", RL_MTU }, { RL_HWREV_8105E, RL_8169, "8105E", RL_MTU }, + { RL_HWREV_8105E_SPIN1, RL_8169, "8105E", RL_MTU }, { RL_HWREV_8168B_SPIN2, RL_8169, "8168", RL_JUMBO_MTU }, { RL_HWREV_8168B_SPIN3, RL_8169, "8168", RL_JUMBO_MTU }, { RL_HWREV_8168C, RL_8169, "8168C/8111C", RL_JUMBO_MTU_6K }, @@ -230,6 +232,8 @@ static struct rl_hwrev re_hwrevs[] = { { RL_HWREV_8168DP, RL_8169, "8168DP/8111DP", RL_JUMBO_MTU_9K }, { RL_HWREV_8168E, RL_8169, "8168E/8111E", RL_JUMBO_MTU_9K}, { RL_HWREV_8168E_VL, RL_8169, "8168E/8111E-VL", RL_JUMBO_MTU_6K}, + { RL_HWREV_8168F, RL_8169, "8168F/8111F", RL_JUMBO_MTU_9K}, + { RL_HWREV_8411, RL_8169, "8411", RL_JUMBO_MTU_9K}, { 0, 0, NULL, 0 } }; @@ -290,6 +294,11 @@ static void re_set_rxmode (struct rl_softc *); static void re_reset (struct rl_softc *); static void re_setwol (struct rl_softc *); static void re_clrwol (struct rl_softc *); +static void re_set_linkspeed (struct rl_softc *); + +#ifdef DEV_NETMAP /* see ixgbe.c for details */ +#include +#endif /* !DEV_NETMAP */ #ifdef RE_DIAG static int re_diag (struct rl_softc *); @@ -309,16 +318,12 @@ static device_method_t re_methods[] = { DEVMETHOD(device_resume, re_resume), DEVMETHOD(device_shutdown, re_shutdown), - /* bus interface */ - DEVMETHOD(bus_print_child, bus_generic_print_child), - DEVMETHOD(bus_driver_added, bus_generic_driver_added), - /* MII interface */ DEVMETHOD(miibus_readreg, re_miibus_readreg), DEVMETHOD(miibus_writereg, re_miibus_writereg), DEVMETHOD(miibus_statchg, re_miibus_statchg), - { 0, 0 } + DEVMETHOD_END }; static driver_t re_driver = { @@ -868,7 +873,7 @@ re_diag(struct rl_softc *sc) device_printf(sc->rl_dev, "expected TX data: %6D/%6D/0x%x\n", dst, ":", src, ":", ETHERTYPE_IP); device_printf(sc->rl_dev, "received RX data: %6D/%6D/0x%x\n", - eh->ether_dhost, ":", eh->ether_shost, ":", + eh->ether_dhost, ":", eh->ether_shost, ":", ntohs(eh->ether_type)); device_printf(sc->rl_dev, "You may have a defective 32-bit " "NIC plugged into a 64-bit PCI slot.\n"); @@ -903,7 +908,7 @@ re_diag(struct rl_softc *sc) static int re_probe(device_t dev) { - struct rl_type *t; + const struct rl_type *t; uint16_t devid, vendor; uint16_t revid, sdevid; int i; @@ -1183,7 +1188,8 @@ re_attach(device_t dev) u_int16_t as[ETHER_ADDR_LEN / 2]; struct rl_softc *sc; struct ifnet *ifp; - struct rl_hwrev *hw_rev; + const struct rl_hwrev *hw_rev; + u_int32_t cap, ctl; int hwrev; u_int16_t devid, re_did = 0; int error = 0, i, phy, rid; @@ -1239,8 +1245,10 @@ re_attach(device_t dev) msic = pci_msi_count(dev); msixc = pci_msix_count(dev); - if (pci_find_cap(dev, PCIY_EXPRESS, ®) == 0) + if (pci_find_cap(dev, PCIY_EXPRESS, ®) == 0) { sc->rl_flags |= RL_FLAG_PCIE; + sc->rl_expcap = reg; + } if (bootverbose) { device_printf(dev, "MSI count : %d\n", msic); device_printf(dev, "MSI-X count : %d\n", msixc); @@ -1332,6 +1340,23 @@ re_attach(device_t dev) CSR_WRITE_1(sc, RL_EECMD, RL_EEMODE_OFF); } + /* Disable ASPM L0S/L1. */ + if (sc->rl_expcap != 0) { + cap = pci_read_config(dev, sc->rl_expcap + + PCIR_EXPRESS_LINK_CAP, 2); + if ((cap & PCIM_LINK_CAP_ASPM) != 0) { + ctl = pci_read_config(dev, sc->rl_expcap + + PCIR_EXPRESS_LINK_CTL, 2); + if ((ctl & 0x0003) != 0) { + ctl &= ~0x0003; + pci_write_config(dev, sc->rl_expcap + + PCIR_EXPRESS_LINK_CTL, ctl, 2); + device_printf(dev, "ASPM disabled\n"); + } + } else + device_printf(dev, "no ASPM capability\n"); + } + hw_rev = re_hwrevs; hwrev = CSR_READ_4(sc, RL_TXCFG); switch (hwrev & 0x70000000) { @@ -1382,10 +1407,17 @@ re_attach(device_t dev) break; case RL_HWREV_8401E: case RL_HWREV_8105E: + case RL_HWREV_8105E_SPIN1: sc->rl_flags |= RL_FLAG_PHYWAKE | RL_FLAG_PHYWAKE_PM | RL_FLAG_PAR | RL_FLAG_DESCV2 | RL_FLAG_MACSTAT | RL_FLAG_FASTETHER | RL_FLAG_CMDSTOP | RL_FLAG_AUTOPAD; break; + case RL_HWREV_8402: + sc->rl_flags |= RL_FLAG_PHYWAKE | RL_FLAG_PHYWAKE_PM | + RL_FLAG_PAR | RL_FLAG_DESCV2 | RL_FLAG_MACSTAT | + RL_FLAG_FASTETHER | RL_FLAG_CMDSTOP | RL_FLAG_AUTOPAD | + RL_FLAG_CMDSTOP_WAIT_TXQ; + break; case RL_HWREV_8168B_SPIN1: case RL_HWREV_8168B_SPIN2: sc->rl_flags |= RL_FLAG_WOLRXENB; @@ -1401,21 +1433,34 @@ re_attach(device_t dev) sc->rl_flags |= RL_FLAG_MACSLEEP; /* FALLTHROUGH */ case RL_HWREV_8168CP: + sc->rl_flags |= RL_FLAG_PHYWAKE | RL_FLAG_PAR | + RL_FLAG_DESCV2 | RL_FLAG_MACSTAT | RL_FLAG_CMDSTOP | + RL_FLAG_AUTOPAD | RL_FLAG_JUMBOV2 | RL_FLAG_WOL_MANLINK; + break; case RL_HWREV_8168D: + sc->rl_flags |= RL_FLAG_PHYWAKE | RL_FLAG_PHYWAKE_PM | + RL_FLAG_PAR | RL_FLAG_DESCV2 | RL_FLAG_MACSTAT | + RL_FLAG_CMDSTOP | RL_FLAG_AUTOPAD | RL_FLAG_JUMBOV2 | + RL_FLAG_WOL_MANLINK; + break; case RL_HWREV_8168DP: sc->rl_flags |= RL_FLAG_PHYWAKE | RL_FLAG_PAR | - RL_FLAG_DESCV2 | RL_FLAG_MACSTAT | RL_FLAG_CMDSTOP | - RL_FLAG_AUTOPAD | RL_FLAG_JUMBOV2; + RL_FLAG_DESCV2 | RL_FLAG_MACSTAT | RL_FLAG_AUTOPAD | + RL_FLAG_JUMBOV2 | RL_FLAG_WAIT_TXPOLL | RL_FLAG_WOL_MANLINK; break; case RL_HWREV_8168E: sc->rl_flags |= RL_FLAG_PHYWAKE | RL_FLAG_PHYWAKE_PM | RL_FLAG_PAR | RL_FLAG_DESCV2 | RL_FLAG_MACSTAT | - RL_FLAG_CMDSTOP | RL_FLAG_AUTOPAD | RL_FLAG_JUMBOV2; + RL_FLAG_CMDSTOP | RL_FLAG_AUTOPAD | RL_FLAG_JUMBOV2 | + RL_FLAG_WOL_MANLINK; break; case RL_HWREV_8168E_VL: + case RL_HWREV_8168F: + case RL_HWREV_8411: sc->rl_flags |= RL_FLAG_PHYWAKE | RL_FLAG_PAR | RL_FLAG_DESCV2 | RL_FLAG_MACSTAT | RL_FLAG_CMDSTOP | - RL_FLAG_AUTOPAD | RL_FLAG_JUMBOV2; + RL_FLAG_AUTOPAD | RL_FLAG_JUMBOV2 | + RL_FLAG_CMDSTOP_WAIT_TXQ | RL_FLAG_WOL_MANLINK; break; case RL_HWREV_8169_8110SB: case RL_HWREV_8169_8110SBL: @@ -1432,6 +1477,22 @@ re_attach(device_t dev) break; } + if (sc->rl_hwrev->rl_rev == RL_HWREV_8139CPLUS) { + sc->rl_cfg0 = RL_8139_CFG0; + sc->rl_cfg1 = RL_8139_CFG1; + sc->rl_cfg2 = 0; + sc->rl_cfg3 = RL_8139_CFG3; + sc->rl_cfg4 = RL_8139_CFG4; + sc->rl_cfg5 = RL_8139_CFG5; + } else { + sc->rl_cfg0 = RL_CFG0; + sc->rl_cfg1 = RL_CFG1; + sc->rl_cfg2 = RL_CFG2; + sc->rl_cfg3 = RL_CFG3; + sc->rl_cfg4 = RL_CFG4; + sc->rl_cfg5 = RL_CFG5; + } + /* Reset the adapter. */ RL_LOCK(sc); re_reset(sc); @@ -1439,12 +1500,12 @@ re_attach(device_t dev) /* Enable PME. */ CSR_WRITE_1(sc, RL_EECMD, RL_EE_MODE); - cfg = CSR_READ_1(sc, RL_CFG1); + cfg = CSR_READ_1(sc, sc->rl_cfg1); cfg |= RL_CFG1_PME; - CSR_WRITE_1(sc, RL_CFG1, cfg); - cfg = CSR_READ_1(sc, RL_CFG5); + CSR_WRITE_1(sc, sc->rl_cfg1, cfg); + cfg = CSR_READ_1(sc, sc->rl_cfg5); cfg &= RL_CFG5_PME_STS; - CSR_WRITE_1(sc, RL_CFG5, cfg); + CSR_WRITE_1(sc, sc->rl_cfg5, cfg); CSR_WRITE_1(sc, RL_EECMD, RL_EEMODE_OFF); if ((sc->rl_flags & RL_FLAG_PAR) != 0) { @@ -1466,7 +1527,7 @@ re_attach(device_t dev) re_read_eeprom(sc, (caddr_t)as, RL_EE_EADDR, 3); for (i = 0; i < ETHER_ADDR_LEN / 2; i++) as[i] = le16toh(as[i]); - bcopy(as, eaddr, sizeof(eaddr)); + bcopy(as, eaddr, ETHER_ADDR_LEN); } if (sc->rl_type == RL_8169) { @@ -1516,19 +1577,6 @@ re_attach(device_t dev) re_gmii_writereg(dev, 1, 0x0e, 0); } -#define RE_PHYAD_INTERNAL 0 - - /* Do MII setup. */ - phy = RE_PHYAD_INTERNAL; - if (sc->rl_type == RL_8169) - phy = 1; - error = mii_attach(dev, &sc->rl_miibus, ifp, re_ifmedia_upd, - re_ifmedia_sts, BMSR_DEFCAPMASK, phy, MII_OFFSET_ANY, MIIF_DOPAUSE); - if (error != 0) { - device_printf(dev, "attaching PHYs failed\n"); - goto fail; - } - ifp->if_softc = sc; if_initname(ifp, device_get_name(dev), device_get_unit(dev)); ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; @@ -1553,6 +1601,19 @@ re_attach(device_t dev) TASK_INIT(&sc->rl_inttask, 0, re_int_task, sc); +#define RE_PHYAD_INTERNAL 0 + + /* Do MII setup. */ + phy = RE_PHYAD_INTERNAL; + if (sc->rl_type == RL_8169) + phy = 1; + error = mii_attach(dev, &sc->rl_miibus, ifp, re_ifmedia_upd, + re_ifmedia_sts, BMSR_DEFCAPMASK, phy, MII_OFFSET_ANY, MIIF_DOPAUSE); + if (error != 0) { + device_printf(dev, "attaching PHYs failed\n"); + goto fail; + } + /* * Call MI attach routine. */ @@ -1566,6 +1627,7 @@ re_attach(device_t dev) if (pci_find_cap(sc->rl_dev, PCIY_PMG, ®) == 0) ifp->if_capabilities |= IFCAP_WOL; ifp->if_capenable = ifp->if_capabilities; + ifp->if_capenable &= ~(IFCAP_WOL_UCAST | IFCAP_WOL_MCAST); /* * Don't enable TSO by default. It is known to generate * corrupted TCP segments(bad TCP options) under certain @@ -1583,6 +1645,9 @@ re_attach(device_t dev) */ ifp->if_data.ifi_hdrlen = sizeof(struct ether_vlan_header); +#ifdef DEV_NETMAP + re_netmap_attach(sc); +#endif /* DEV_NETMAP */ #ifdef RE_DIAG /* * Perform hardware diagnostic on the original RTL8169. @@ -1778,6 +1843,9 @@ re_detach(device_t dev) bus_dma_tag_destroy(sc->rl_ldata.rl_stag); } +#ifdef DEV_NETMAP + netmap_detach(ifp); +#endif /* DEV_NETMAP */ if (sc->rl_parent_tag) bus_dma_tag_destroy(sc->rl_parent_tag); @@ -1952,6 +2020,9 @@ re_tx_list_init(struct rl_softc *sc) sc->rl_ldata.rl_tx_desc_cnt * sizeof(struct rl_desc)); for (i = 0; i < sc->rl_ldata.rl_tx_desc_cnt; i++) sc->rl_ldata.rl_tx_desc[i].tx_m = NULL; +#ifdef DEV_NETMAP + re_netmap_tx_init(sc); +#endif /* DEV_NETMAP */ /* Set EOR. */ desc = &sc->rl_ldata.rl_tx_list[sc->rl_ldata.rl_tx_desc_cnt - 1]; desc->rl_cmdstat |= htole32(RL_TDESC_CMD_EOR); @@ -1979,6 +2050,9 @@ re_rx_list_init(struct rl_softc *sc) if ((error = re_newbuf(sc, i)) != 0) return (error); } +#ifdef DEV_NETMAP + re_netmap_rx_init(sc); +#endif /* DEV_NETMAP */ /* Flush the RX descriptors */ @@ -2035,6 +2109,13 @@ re_rxeof(struct rl_softc *sc, int *rx_npktsp) RL_LOCK_ASSERT(sc); ifp = sc->rl_ifp; +#ifdef DEV_NETMAP + if (ifp->if_capenable & IFCAP_NETMAP) { + NA(ifp)->rx_rings->nr_kflags |= NKR_PENDINTR; + selwakeuppri(&NA(ifp)->rx_rings->si, PI_NET); + return 0; + } +#endif /* DEV_NETMAP */ if (ifp->if_mtu > RL_MTU && (sc->rl_flags & RL_FLAG_JUMBOV2) != 0) jumbo = 1; else @@ -2276,6 +2357,12 @@ re_txeof(struct rl_softc *sc) return; ifp = sc->rl_ifp; +#ifdef DEV_NETMAP + if (ifp->if_capenable & IFCAP_NETMAP) { + selwakeuppri(&NA(ifp)->tx_rings[0].si, PI_NET); + return; + } +#endif /* DEV_NETMAP */ /* Invalidate the TX descriptor list */ bus_dmamap_sync(sc->rl_ldata.rl_tx_list_tag, sc->rl_ldata.rl_tx_list_map, @@ -2794,6 +2881,21 @@ re_start_locked(struct ifnet *ifp) sc = ifp->if_softc; +#ifdef DEV_NETMAP + /* XXX is this necessary ? */ + if (ifp->if_capenable & IFCAP_NETMAP) { + struct netmap_kring *kring = &NA(ifp)->tx_rings[0]; + if (sc->rl_ldata.rl_tx_prodidx != kring->nr_hwcur) { + /* kick the tx unit */ + CSR_WRITE_1(sc, sc->rl_txstart, RL_TXSTART_START); +#ifdef RE_TX_MODERATION + CSR_WRITE_4(sc, RL_TIMERCNT, 1); +#endif + sc->rl_watchdog_timer = 5; + } + return; + } +#endif /* DEV_NETMAP */ if ((ifp->if_drv_flags & (IFF_DRV_RUNNING | IFF_DRV_OACTIVE)) != IFF_DRV_RUNNING || (sc->rl_flags & RL_FLAG_LINK) == 0) return; @@ -2866,32 +2968,32 @@ re_set_jumbo(struct rl_softc *sc, int jumbo) CSR_WRITE_1(sc, RL_EECMD, RL_EEMODE_WRITECFG); if (jumbo != 0) { - CSR_WRITE_1(sc, RL_CFG3, CSR_READ_1(sc, RL_CFG3) | + CSR_WRITE_1(sc, sc->rl_cfg3, CSR_READ_1(sc, sc->rl_cfg3) | RL_CFG3_JUMBO_EN0); switch (sc->rl_hwrev->rl_rev) { case RL_HWREV_8168DP: break; case RL_HWREV_8168E: - CSR_WRITE_1(sc, RL_CFG4, CSR_READ_1(sc, RL_CFG4) | - 0x01); + CSR_WRITE_1(sc, sc->rl_cfg4, + CSR_READ_1(sc, sc->rl_cfg4) | 0x01); break; default: - CSR_WRITE_1(sc, RL_CFG4, CSR_READ_1(sc, RL_CFG4) | - RL_CFG4_JUMBO_EN1); + CSR_WRITE_1(sc, sc->rl_cfg4, + CSR_READ_1(sc, sc->rl_cfg4) | RL_CFG4_JUMBO_EN1); } } else { - CSR_WRITE_1(sc, RL_CFG3, CSR_READ_1(sc, RL_CFG3) & + CSR_WRITE_1(sc, sc->rl_cfg3, CSR_READ_1(sc, sc->rl_cfg3) & ~RL_CFG3_JUMBO_EN0); switch (sc->rl_hwrev->rl_rev) { case RL_HWREV_8168DP: break; case RL_HWREV_8168E: - CSR_WRITE_1(sc, RL_CFG4, CSR_READ_1(sc, RL_CFG4) & - ~0x01); + CSR_WRITE_1(sc, sc->rl_cfg4, + CSR_READ_1(sc, sc->rl_cfg4) & ~0x01); break; default: - CSR_WRITE_1(sc, RL_CFG4, CSR_READ_1(sc, RL_CFG4) & - ~RL_CFG4_JUMBO_EN1); + CSR_WRITE_1(sc, sc->rl_cfg4, + CSR_READ_1(sc, sc->rl_cfg4) & ~RL_CFG4_JUMBO_EN1); } } CSR_WRITE_1(sc, RL_EECMD, RL_EEMODE_OFF); @@ -3004,7 +3106,7 @@ re_init_locked(struct rl_softc *sc) if (sc->rl_hwrev->rl_rev == RL_HWREV_8169_8110SC || sc->rl_hwrev->rl_rev == RL_HWREV_8169_8110SCE) { reg = 0x000fff00; - if ((CSR_READ_1(sc, RL_CFG2) & RL_CFG2_PCI66MHZ) != 0) + if ((CSR_READ_1(sc, sc->rl_cfg2) & RL_CFG2_PCI66MHZ) != 0) reg |= 0x000000ff; if (sc->rl_hwrev->rl_rev == RL_HWREV_8169_8110SCE) reg |= 0x00f00000; @@ -3169,14 +3271,15 @@ re_init_locked(struct rl_softc *sc) if (sc->rl_testmode) return; - mii_mediachg(mii); - - CSR_WRITE_1(sc, RL_CFG1, CSR_READ_1(sc, RL_CFG1) | RL_CFG1_DRVLOAD); + CSR_WRITE_1(sc, sc->rl_cfg1, CSR_READ_1(sc, sc->rl_cfg1) | + RL_CFG1_DRVLOAD); ifp->if_drv_flags |= IFF_DRV_RUNNING; ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; sc->rl_flags &= ~RL_FLAG_LINK; + mii_mediachg(mii); + sc->rl_watchdog_timer = 0; callout_reset(&sc->rl_stat_callout, hz, re_tick, sc); } @@ -3214,9 +3317,9 @@ re_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr) RL_LOCK(sc); mii_pollstat(mii); - RL_UNLOCK(sc); ifmr->ifm_active = mii->mii_media_active; ifmr->ifm_status = mii->mii_media_status; + RL_UNLOCK(sc); } static int @@ -3308,6 +3411,7 @@ re_ioctl(struct ifnet *ifp, u_long command, caddr_t data) } } #endif /* DEVICE_POLLING */ + RL_LOCK(sc); if ((mask & IFCAP_TXCSUM) != 0 && (ifp->if_capabilities & IFCAP_TXCSUM) != 0) { ifp->if_capenable ^= IFCAP_TXCSUM; @@ -3328,7 +3432,7 @@ re_ioctl(struct ifnet *ifp, u_long command, caddr_t data) reinit = 1; } if ((mask & IFCAP_TSO4) != 0 && - (ifp->if_capabilities & IFCAP_TSO) != 0) { + (ifp->if_capabilities & IFCAP_TSO4) != 0) { ifp->if_capenable ^= IFCAP_TSO4; if ((IFCAP_TSO4 & ifp->if_capenable) != 0) ifp->if_hwassist |= CSUM_TSO; @@ -3366,8 +3470,9 @@ re_ioctl(struct ifnet *ifp, u_long command, caddr_t data) } if (reinit && ifp->if_drv_flags & IFF_DRV_RUNNING) { ifp->if_drv_flags &= ~IFF_DRV_RUNNING; - re_init(sc); + re_init_locked(sc); } + RL_UNLOCK(sc); VLAN_CAPABILITIES(ifp); } break; @@ -3429,10 +3534,42 @@ re_stop(struct rl_softc *sc) callout_stop(&sc->rl_stat_callout); ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); - if ((sc->rl_flags & RL_FLAG_CMDSTOP) != 0) + /* + * Disable accepting frames to put RX MAC into idle state. + * Otherwise it's possible to get frames while stop command + * execution is in progress and controller can DMA the frame + * to already freed RX buffer during that period. + */ + CSR_WRITE_4(sc, RL_RXCFG, CSR_READ_4(sc, RL_RXCFG) & + ~(RL_RXCFG_RX_ALLPHYS | RL_RXCFG_RX_INDIV | RL_RXCFG_RX_MULTI | + RL_RXCFG_RX_BROAD)); + + if ((sc->rl_flags & RL_FLAG_WAIT_TXPOLL) != 0) { + for (i = RL_TIMEOUT; i > 0; i--) { + if ((CSR_READ_1(sc, sc->rl_txstart) & + RL_TXSTART_START) == 0) + break; + DELAY(20); + } + if (i == 0) + device_printf(sc->rl_dev, + "stopping TX poll timed out!\n"); + CSR_WRITE_1(sc, RL_COMMAND, 0x00); + } else if ((sc->rl_flags & RL_FLAG_CMDSTOP) != 0) { CSR_WRITE_1(sc, RL_COMMAND, RL_CMD_STOPREQ | RL_CMD_TX_ENB | RL_CMD_RX_ENB); - else + if ((sc->rl_flags & RL_FLAG_CMDSTOP_WAIT_TXQ) != 0) { + for (i = RL_TIMEOUT; i > 0; i--) { + if ((CSR_READ_4(sc, RL_TXCFG) & + RL_TXCFG_QUEUE_EMPTY) != 0) + break; + DELAY(100); + } + if (i == 0) + device_printf(sc->rl_dev, + "stopping TXQ timed out!\n"); + } + } else CSR_WRITE_1(sc, RL_COMMAND, 0x00); DELAY(1000); CSR_WRITE_2(sc, RL_IMR, 0x0000); @@ -3444,7 +3581,6 @@ re_stop(struct rl_softc *sc) } /* Free the TX list buffers. */ - for (i = 0; i < sc->rl_ldata.rl_tx_desc_cnt; i++) { txd = &sc->rl_ldata.rl_tx_desc[i]; if (txd->tx_m != NULL) { @@ -3458,11 +3594,10 @@ re_stop(struct rl_softc *sc) } /* Free the RX list buffers. */ - for (i = 0; i < sc->rl_ldata.rl_rx_desc_cnt; i++) { rxd = &sc->rl_ldata.rl_rx_desc[i]; if (rxd->rx_m != NULL) { - bus_dmamap_sync(sc->rl_ldata.rl_tx_mtag, + bus_dmamap_sync(sc->rl_ldata.rl_rx_mtag, rxd->rx_dmamap, BUS_DMASYNC_POSTREAD); bus_dmamap_unload(sc->rl_ldata.rl_rx_mtag, rxd->rx_dmamap); @@ -3470,6 +3605,20 @@ re_stop(struct rl_softc *sc) rxd->rx_m = NULL; } } + + if ((sc->rl_flags & RL_FLAG_JUMBOV2) != 0) { + for (i = 0; i < sc->rl_ldata.rl_rx_desc_cnt; i++) { + rxd = &sc->rl_ldata.rl_jrx_desc[i]; + if (rxd->rx_m != NULL) { + bus_dmamap_sync(sc->rl_ldata.rl_jrx_mtag, + rxd->rx_dmamap, BUS_DMASYNC_POSTREAD); + bus_dmamap_unload(sc->rl_ldata.rl_jrx_mtag, + rxd->rx_dmamap); + m_freem(rxd->rx_m); + rxd->rx_m = NULL; + } + } + } } /* @@ -3557,6 +3706,74 @@ re_shutdown(device_t dev) return (0); } +static void +re_set_linkspeed(struct rl_softc *sc) +{ + struct mii_softc *miisc; + struct mii_data *mii; + int aneg, i, phyno; + + RL_LOCK_ASSERT(sc); + + mii = device_get_softc(sc->rl_miibus); + mii_pollstat(mii); + aneg = 0; + 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: + return; + case IFM_1000_T: + aneg++; + break; + default: + break; + } + } + miisc = LIST_FIRST(&mii->mii_phys); + phyno = miisc->mii_phy; + LIST_FOREACH(miisc, &mii->mii_phys, mii_list) + PHY_RESET(miisc); + re_miibus_writereg(sc->rl_dev, phyno, MII_100T2CR, 0); + re_miibus_writereg(sc->rl_dev, phyno, + MII_ANAR, ANAR_TX_FD | ANAR_TX | ANAR_10_FD | ANAR_10 | ANAR_CSMA); + re_miibus_writereg(sc->rl_dev, phyno, + MII_BMCR, BMCR_AUTOEN | BMCR_STARTNEG); + DELAY(1000); + if (aneg != 0) { + /* + * Poll link state until re(4) get a 10/100Mbps link. + */ + for (i = 0; i < MII_ANEGTICKS_GIGE; i++) { + mii_pollstat(mii); + 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: + return; + default: + break; + } + } + RL_UNLOCK(sc); + pause("relnk", hz); + RL_LOCK(sc); + } + if (i == MII_ANEGTICKS_GIGE) + device_printf(sc->rl_dev, + "establishing a link failed, WOL may not work!"); + } + /* + * No link, force MAC to have 100Mbps, full-duplex link. + * MAC does not require reprogramming on resolved speed/duplex, + * so this is just for completeness. + */ + mii->mii_media_status = IFM_AVALID | IFM_ACTIVE; + mii->mii_media_active = IFM_ETHER | IFM_100_TX | IFM_FDX; +} + static void re_setwol(struct rl_softc *sc) { @@ -3577,40 +3794,44 @@ re_setwol(struct rl_softc *sc) CSR_WRITE_1(sc, RL_GPIO, CSR_READ_1(sc, RL_GPIO) & ~0x01); } - if ((ifp->if_capenable & IFCAP_WOL) != 0 && - (sc->rl_flags & RL_FLAG_WOLRXENB) != 0) - CSR_WRITE_1(sc, RL_COMMAND, RL_CMD_RX_ENB); + if ((ifp->if_capenable & IFCAP_WOL) != 0) { + re_set_rxmode(sc); + if ((sc->rl_flags & RL_FLAG_WOL_MANLINK) != 0) + re_set_linkspeed(sc); + if ((sc->rl_flags & RL_FLAG_WOLRXENB) != 0) + CSR_WRITE_1(sc, RL_COMMAND, RL_CMD_RX_ENB); + } /* Enable config register write. */ CSR_WRITE_1(sc, RL_EECMD, RL_EE_MODE); /* Enable PME. */ - v = CSR_READ_1(sc, RL_CFG1); + v = CSR_READ_1(sc, sc->rl_cfg1); v &= ~RL_CFG1_PME; if ((ifp->if_capenable & IFCAP_WOL) != 0) v |= RL_CFG1_PME; - CSR_WRITE_1(sc, RL_CFG1, v); + CSR_WRITE_1(sc, sc->rl_cfg1, v); - v = CSR_READ_1(sc, RL_CFG3); + v = CSR_READ_1(sc, sc->rl_cfg3); v &= ~(RL_CFG3_WOL_LINK | RL_CFG3_WOL_MAGIC); if ((ifp->if_capenable & IFCAP_WOL_MAGIC) != 0) v |= RL_CFG3_WOL_MAGIC; - CSR_WRITE_1(sc, RL_CFG3, v); + CSR_WRITE_1(sc, sc->rl_cfg3, v); - /* Config register write done. */ - CSR_WRITE_1(sc, RL_EECMD, RL_EEMODE_OFF); - - v = CSR_READ_1(sc, RL_CFG5); - v &= ~(RL_CFG5_WOL_BCAST | RL_CFG5_WOL_MCAST | RL_CFG5_WOL_UCAST); - v &= ~RL_CFG5_WOL_LANWAKE; + v = CSR_READ_1(sc, sc->rl_cfg5); + v &= ~(RL_CFG5_WOL_BCAST | RL_CFG5_WOL_MCAST | RL_CFG5_WOL_UCAST | + RL_CFG5_WOL_LANWAKE); if ((ifp->if_capenable & IFCAP_WOL_UCAST) != 0) v |= RL_CFG5_WOL_UCAST; if ((ifp->if_capenable & IFCAP_WOL_MCAST) != 0) v |= RL_CFG5_WOL_MCAST | RL_CFG5_WOL_BCAST; if ((ifp->if_capenable & IFCAP_WOL) != 0) v |= RL_CFG5_WOL_LANWAKE; - CSR_WRITE_1(sc, RL_CFG5, v); + CSR_WRITE_1(sc, sc->rl_cfg5, v); + + /* Config register write done. */ + CSR_WRITE_1(sc, RL_EECMD, RL_EEMODE_OFF); - if ((ifp->if_capenable & IFCAP_WOL) != 0 && + if ((ifp->if_capenable & IFCAP_WOL) == 0 && (sc->rl_flags & RL_FLAG_PHYWAKE_PM) != 0) CSR_WRITE_1(sc, RL_PMCH, CSR_READ_1(sc, RL_PMCH) & ~0x80); /* @@ -3641,17 +3862,17 @@ re_clrwol(struct rl_softc *sc) /* Enable config register write. */ CSR_WRITE_1(sc, RL_EECMD, RL_EE_MODE); - v = CSR_READ_1(sc, RL_CFG3); + v = CSR_READ_1(sc, sc->rl_cfg3); v &= ~(RL_CFG3_WOL_LINK | RL_CFG3_WOL_MAGIC); - CSR_WRITE_1(sc, RL_CFG3, v); + CSR_WRITE_1(sc, sc->rl_cfg3, v); /* Config register write done. */ CSR_WRITE_1(sc, RL_EECMD, RL_EEMODE_OFF); - v = CSR_READ_1(sc, RL_CFG5); + v = CSR_READ_1(sc, sc->rl_cfg5); v &= ~(RL_CFG5_WOL_BCAST | RL_CFG5_WOL_MCAST | RL_CFG5_WOL_UCAST); v &= ~RL_CFG5_WOL_LANWAKE; - CSR_WRITE_1(sc, RL_CFG5, v); + CSR_WRITE_1(sc, sc->rl_cfg5, v); } static void diff --git a/src/add-ons/kernel/drivers/network/rtl81xx/pci/if_rlreg.h b/src/add-ons/kernel/drivers/network/rtl81xx/pci/if_rlreg.h index 6e7c0c1d543..7822ce3654b 100644 --- a/src/add-ons/kernel/drivers/network/rtl81xx/pci/if_rlreg.h +++ b/src/add-ons/kernel/drivers/network/rtl81xx/pci/if_rlreg.h @@ -74,6 +74,14 @@ #define RL_TIMERCNT 0x0048 /* timer count register */ #define RL_MISSEDPKT 0x004C /* missed packet counter */ #define RL_EECMD 0x0050 /* EEPROM command register */ + +/* RTL8139/RTL8139C+ only */ +#define RL_8139_CFG0 0x0051 /* config register #0 */ +#define RL_8139_CFG1 0x0052 /* config register #1 */ +#define RL_8139_CFG3 0x0059 /* config register #3 */ +#define RL_8139_CFG4 0x005A /* config register #4 */ +#define RL_8139_CFG5 0x00D8 /* config register #5 */ + #define RL_CFG0 0x0051 /* config register #0 */ #define RL_CFG1 0x0052 /* config register #1 */ #define RL_CFG2 0x0053 /* config register #2 */ @@ -143,6 +151,7 @@ */ #define RL_TXCFG_CLRABRT 0x00000001 /* retransmit aborted pkt */ #define RL_TXCFG_MAXDMA 0x00000700 /* max DMA burst size */ +#define RL_TXCFG_QUEUE_EMPTY 0x00000800 /* 8168E-VL or higher */ #define RL_TXCFG_CRCAPPEND 0x00010000 /* CRC append (0 = yes) */ #define RL_TXCFG_LOOPBKTST 0x00060000 /* loopback test */ #define RL_TXCFG_IFG2 0x00080000 /* 8169 only */ @@ -178,6 +187,10 @@ #define RL_HWREV_8168C_SPIN2 0x3C400000 #define RL_HWREV_8168CP 0x3C800000 #define RL_HWREV_8105E 0x40800000 +#define RL_HWREV_8105E_SPIN1 0x40C00000 +#define RL_HWREV_8402 0x44000000 +#define RL_HWREV_8168F 0x48000000 +#define RL_HWREV_8411 0x48800000 #define RL_HWREV_8139 0x60000000 #define RL_HWREV_8139A 0x70000000 #define RL_HWREV_8139AG 0x70800000 @@ -866,7 +879,14 @@ struct rl_softc { const struct rl_hwrev *rl_hwrev; int rl_eecmd_read; int rl_eewidth; + int rl_expcap; int rl_txthresh; + bus_size_t rl_cfg0; + bus_size_t rl_cfg1; + bus_size_t rl_cfg2; + bus_size_t rl_cfg3; + bus_size_t rl_cfg4; + bus_size_t rl_cfg5; struct rl_chain_data rl_cdata; struct rl_list_data rl_ldata; struct callout rl_stat_callout; @@ -892,22 +912,25 @@ struct rl_softc { int rl_int_rx_act; int rl_int_rx_mod; uint32_t rl_flags; -#define RL_FLAG_MSI 0x0001 -#define RL_FLAG_AUTOPAD 0x0002 -#define RL_FLAG_PHYWAKE_PM 0x0004 -#define RL_FLAG_PHYWAKE 0x0008 -#define RL_FLAG_JUMBOV2 0x0010 -#define RL_FLAG_PAR 0x0020 -#define RL_FLAG_DESCV2 0x0040 -#define RL_FLAG_MACSTAT 0x0080 -#define RL_FLAG_FASTETHER 0x0100 -#define RL_FLAG_CMDSTOP 0x0200 -#define RL_FLAG_MACRESET 0x0400 -#define RL_FLAG_MSIX 0x0800 -#define RL_FLAG_WOLRXENB 0x1000 -#define RL_FLAG_MACSLEEP 0x2000 -#define RL_FLAG_PCIE 0x4000 -#define RL_FLAG_LINK 0x8000 +#define RL_FLAG_MSI 0x00000001 +#define RL_FLAG_AUTOPAD 0x00000002 +#define RL_FLAG_PHYWAKE_PM 0x00000004 +#define RL_FLAG_PHYWAKE 0x00000008 +#define RL_FLAG_JUMBOV2 0x00000010 +#define RL_FLAG_PAR 0x00000020 +#define RL_FLAG_DESCV2 0x00000040 +#define RL_FLAG_MACSTAT 0x00000080 +#define RL_FLAG_FASTETHER 0x00000100 +#define RL_FLAG_CMDSTOP 0x00000200 +#define RL_FLAG_MACRESET 0x00000400 +#define RL_FLAG_MSIX 0x00000800 +#define RL_FLAG_WOLRXENB 0x00001000 +#define RL_FLAG_MACSLEEP 0x00002000 +#define RL_FLAG_WAIT_TXPOLL 0x00004000 +#define RL_FLAG_CMDSTOP_WAIT_TXQ 0x00008000 +#define RL_FLAG_WOL_MANLINK 0x00010000 +#define RL_FLAG_PCIE 0x40000000 +#define RL_FLAG_LINK 0x80000000 }; #define RL_LOCK(_sc) mtx_lock(&(_sc)->rl_mtx) diff --git a/src/add-ons/kernel/drivers/network/syskonnect/dev/mii/e1000phy.c b/src/add-ons/kernel/drivers/network/syskonnect/dev/mii/e1000phy.c index 8818ee43ee7..91ae44d2e97 100644 --- a/src/add-ons/kernel/drivers/network/syskonnect/dev/mii/e1000phy.c +++ b/src/add-ons/kernel/drivers/network/syskonnect/dev/mii/e1000phy.c @@ -30,7 +30,7 @@ */ #include -__FBSDID("$FreeBSD: src/sys/dev/mii/e1000phy.c,v 1.18 2006/12/11 11:09:48 yongari Exp $"); +__FBSDID("$FreeBSD$"); /* * driver for the Marvell 88E1000 series external 1000/100/10-BT PHY. @@ -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; diff --git a/src/add-ons/kernel/drivers/network/syskonnect/dev/mii/e1000phyreg.h b/src/add-ons/kernel/drivers/network/syskonnect/dev/mii/e1000phyreg.h index 08f9e5f1d41..e5d5cf961a2 100644 --- a/src/add-ons/kernel/drivers/network/syskonnect/dev/mii/e1000phyreg.h +++ b/src/add-ons/kernel/drivers/network/syskonnect/dev/mii/e1000phyreg.h @@ -1,4 +1,4 @@ -/* $FreeBSD: src/sys/dev/mii/e1000phyreg.h,v 1.4 2006/12/11 10:43:32 yongari Exp $ */ +/* $FreeBSD$ */ /*- * Principal Author: Parag Patel * Copyright (c) 2001 diff --git a/src/add-ons/kernel/drivers/network/syskonnect/dev/mii/ukphy.c b/src/add-ons/kernel/drivers/network/syskonnect/dev/mii/ukphy.c index 4ecfce29d31..9d52eb580ca 100644 --- a/src/add-ons/kernel/drivers/network/syskonnect/dev/mii/ukphy.c +++ b/src/add-ons/kernel/drivers/network/syskonnect/dev/mii/ukphy.c @@ -55,7 +55,7 @@ */ #include -__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; diff --git a/src/add-ons/kernel/drivers/network/syskonnect/dev/mii/ukphy_subr.c b/src/add-ons/kernel/drivers/network/syskonnect/dev/mii/ukphy_subr.c index 73007e197b9..5f2f6341ba6 100644 --- a/src/add-ons/kernel/drivers/network/syskonnect/dev/mii/ukphy_subr.c +++ b/src/add-ons/kernel/drivers/network/syskonnect/dev/mii/ukphy_subr.c @@ -31,7 +31,7 @@ */ #include -__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. diff --git a/src/add-ons/kernel/drivers/network/syskonnect/dev/mii/xmphy.c b/src/add-ons/kernel/drivers/network/syskonnect/dev/mii/xmphy.c index 886bb7e8735..328d34ad9a5 100644 --- a/src/add-ons/kernel/drivers/network/syskonnect/dev/mii/xmphy.c +++ b/src/add-ons/kernel/drivers/network/syskonnect/dev/mii/xmphy.c @@ -31,7 +31,7 @@ */ #include -__FBSDID("$FreeBSD: src/sys/dev/mii/xmphy.c,v 1.21 2006/12/02 19:36:25 marius Exp $"); +__FBSDID("$FreeBSD$"); /* * driver for the XaQti XMAC II's internal PHY. This is sort of @@ -66,7 +66,7 @@ static device_method_t xmphy_methods[] = { DEVMETHOD(device_attach, xmphy_attach), DEVMETHOD(device_detach, mii_phy_detach), DEVMETHOD(device_shutdown, bus_generic_shutdown), - { 0, 0 } + DEVMETHOD_END }; static devclass_t xmphy_devclass; diff --git a/src/add-ons/kernel/drivers/network/syskonnect/dev/mii/xmphyreg.h b/src/add-ons/kernel/drivers/network/syskonnect/dev/mii/xmphyreg.h index ad1e6fc4b77..92b9f78b461 100644 --- a/src/add-ons/kernel/drivers/network/syskonnect/dev/mii/xmphyreg.h +++ b/src/add-ons/kernel/drivers/network/syskonnect/dev/mii/xmphyreg.h @@ -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/xmphyreg.h,v 1.4 2005/01/06 01:42:56 imp Exp $ + * $FreeBSD$ */ #ifndef _DEV_MII_XMPHYREG_H_ diff --git a/src/add-ons/kernel/drivers/network/syskonnect/dev/sk/if_sk.c b/src/add-ons/kernel/drivers/network/syskonnect/dev/sk/if_sk.c index a0afc0ff588..4b244659280 100644 --- a/src/add-ons/kernel/drivers/network/syskonnect/dev/sk/if_sk.c +++ b/src/add-ons/kernel/drivers/network/syskonnect/dev/sk/if_sk.c @@ -48,7 +48,7 @@ */ #include -__FBSDID("$FreeBSD: src/sys/dev/sk/if_sk.c,v 1.138 2007/11/22 02:44:59 yongari Exp $"); +__FBSDID("$FreeBSD$"); /* * SysKonnect SK-NET gigabit ethernet driver for FreeBSD. Supports @@ -140,7 +140,7 @@ MODULE_DEPEND(sk, miibus, 1, 1, 1); #ifndef lint static const char rcsid[] = - "$FreeBSD: src/sys/dev/sk/if_sk.c,v 1.138 2007/11/22 02:44:59 yongari Exp $"; + "$FreeBSD$"; #endif static struct sk_type sk_devs[] = { @@ -234,10 +234,10 @@ static int sk_init_rx_ring(struct sk_if_softc *); static int sk_init_jumbo_rx_ring(struct sk_if_softc *); static void sk_init_tx_ring(struct sk_if_softc *); static u_int32_t sk_win_read_4(struct sk_softc *, int); -u_int16_t sk_win_read_2(struct sk_softc *, int); +static u_int16_t sk_win_read_2(struct sk_softc *, int); static u_int8_t sk_win_read_1(struct sk_softc *, int); static void sk_win_write_4(struct sk_softc *, int, u_int32_t); -void sk_win_write_2(struct sk_softc *, int, u_int32_t); +static void sk_win_write_2(struct sk_softc *, int, u_int32_t); static void sk_win_write_1(struct sk_softc *, int, u_int32_t); static int sk_miibus_readreg(device_t, int, int); @@ -300,11 +300,7 @@ static device_method_t skc_methods[] = { DEVMETHOD(device_resume, skc_resume), DEVMETHOD(device_shutdown, skc_shutdown), - /* bus interface */ - DEVMETHOD(bus_print_child, bus_generic_print_child), - DEVMETHOD(bus_driver_added, bus_generic_driver_added), - - { 0, 0 } + DEVMETHOD_END }; static driver_t skc_driver = { @@ -322,16 +318,12 @@ static device_method_t sk_methods[] = { DEVMETHOD(device_detach, sk_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, sk_miibus_readreg), DEVMETHOD(miibus_writereg, sk_miibus_writereg), DEVMETHOD(miibus_statchg, sk_miibus_statchg), - { 0, 0 } + DEVMETHOD_END }; static driver_t sk_driver = { @@ -389,7 +381,7 @@ sk_win_read_4(sc, reg) #endif } -u_int16_t +static u_int16_t sk_win_read_2(sc, reg) struct sk_softc *sc; int reg; @@ -430,7 +422,7 @@ sk_win_write_4(sc, reg, val) return; } -void +static void sk_win_write_2(sc, reg, val) struct sk_softc *sc; int reg; @@ -1213,7 +1205,6 @@ skc_probe(dev) { struct sk_type *t = sk_devs; - while(t->sk_name != NULL) { if ((pci_get_vendor(dev) == t->sk_vid) && (pci_get_device(dev) == t->sk_did)) { @@ -1819,7 +1810,8 @@ skc_attach(dev) goto fail; } - error = bus_setup_intr(dev, sc->sk_res[1], INTR_TYPE_NET|INTR_MPSAFE/*|INTR_FAST*/, + /* Hook interrupt last to avoid having to lock softc */ + error = bus_setup_intr(dev, sc->sk_res[1], INTR_TYPE_NET|INTR_MPSAFE, NULL, sk_intr, sc, &sc->sk_intrhand); if (error) { @@ -3127,9 +3119,7 @@ sk_intr(xsc) #ifndef __HAIKU__ status = CSR_READ_4(sc, SK_ISSR); if (status == 0 || status == 0xffffffff || sc->sk_suspended) - { goto done_locked; - } #endif sc_if0 = sc->sk_if[SK_PORT_A]; @@ -3148,9 +3138,7 @@ sk_intr(xsc) while (true) { if (status == 0 || status == 0xffffffff || sc->sk_suspended) - { goto done_locked; - } #endif /* Handle receive interrupts first. */ @@ -3206,8 +3194,8 @@ sk_intr(xsc) sc_if1->sk_phytype == SK_PHYTYPE_BCOM) sk_intr_bcom(sc_if1); } -#ifdef __HAIKU__ status = CSR_READ_4(sc, SK_ISSR); +#ifdef __HAIKU__ if (((status & sc->sk_intrmask) == 0) || status == 0xffffffff || sc->sk_suspended) { break; diff --git a/src/add-ons/kernel/drivers/network/syskonnect/dev/sk/if_skreg.h b/src/add-ons/kernel/drivers/network/syskonnect/dev/sk/if_skreg.h index b518baaede6..d164ffcdc00 100644 --- a/src/add-ons/kernel/drivers/network/syskonnect/dev/sk/if_skreg.h +++ b/src/add-ons/kernel/drivers/network/syskonnect/dev/sk/if_skreg.h @@ -1,6 +1,6 @@ /* $OpenBSD: if_skreg.h,v 1.10 2003/08/12 05:23:06 nate Exp $ */ -/*-f +/*- * Copyright (c) 1997, 1998, 1999, 2000 * Bill Paul . All rights reserved. * @@ -31,7 +31,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/sk/if_skreg.h,v 1.41 2007/04/02 04:43:41 yongari Exp $ + * $FreeBSD$ */ /*- @@ -379,8 +379,8 @@ #define SK_IMCTL_STOP 0x02 #define SK_IMCTL_START 0x04 -#define SK_IMTIMER_TICKS_GENESIS 177 /* FBSD ticks are 1/100, Haiku 3? secs 53 */ -#define SK_IMTIMER_TICKS_YUKON 260 /* FBSD ticks are 1/100, Haiku 3? secs 78 */ +#define SK_IMTIMER_TICKS_GENESIS 53 +#define SK_IMTIMER_TICKS_YUKON 78 #define SK_IM_USECS(x, t) ((x) * (t)) #define SK_IM_MIN 10 diff --git a/src/add-ons/kernel/drivers/network/syskonnect/dev/sk/xmaciireg.h b/src/add-ons/kernel/drivers/network/syskonnect/dev/sk/xmaciireg.h index 85a59980bc4..604073b72a3 100644 --- a/src/add-ons/kernel/drivers/network/syskonnect/dev/sk/xmaciireg.h +++ b/src/add-ons/kernel/drivers/network/syskonnect/dev/sk/xmaciireg.h @@ -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/sk/xmaciireg.h,v 1.5 2006/04/27 05:59:09 yongari Exp $ + * $FreeBSD$ */ /* diff --git a/src/add-ons/kernel/drivers/network/syskonnect/dev/sk/yukonreg.h b/src/add-ons/kernel/drivers/network/syskonnect/dev/sk/yukonreg.h index c66487472e1..efe71a0d346 100644 --- a/src/add-ons/kernel/drivers/network/syskonnect/dev/sk/yukonreg.h +++ b/src/add-ons/kernel/drivers/network/syskonnect/dev/sk/yukonreg.h @@ -14,7 +14,7 @@ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * - * $FreeBSD: src/sys/dev/sk/yukonreg.h,v 1.3 2006/04/27 05:59:09 yongari Exp $ + * $FreeBSD$ */ /* General Purpose Status Register (GPSR) */ diff --git a/src/add-ons/kernel/drivers/network/via_rhine/dev/mii/ciphy.c b/src/add-ons/kernel/drivers/network/via_rhine/dev/mii/ciphy.c index 2133c76ca05..87d0d814e91 100644 --- a/src/add-ons/kernel/drivers/network/via_rhine/dev/mii/ciphy.c +++ b/src/add-ons/kernel/drivers/network/via_rhine/dev/mii/ciphy.c @@ -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; diff --git a/src/add-ons/kernel/drivers/network/via_rhine/dev/mii/ukphy.c b/src/add-ons/kernel/drivers/network/via_rhine/dev/mii/ukphy.c index 4ecfce29d31..9d52eb580ca 100644 --- a/src/add-ons/kernel/drivers/network/via_rhine/dev/mii/ukphy.c +++ b/src/add-ons/kernel/drivers/network/via_rhine/dev/mii/ukphy.c @@ -55,7 +55,7 @@ */ #include -__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; diff --git a/src/add-ons/kernel/drivers/network/via_rhine/dev/mii/ukphy_subr.c b/src/add-ons/kernel/drivers/network/via_rhine/dev/mii/ukphy_subr.c index 73007e197b9..5f2f6341ba6 100644 --- a/src/add-ons/kernel/drivers/network/via_rhine/dev/mii/ukphy_subr.c +++ b/src/add-ons/kernel/drivers/network/via_rhine/dev/mii/ukphy_subr.c @@ -31,7 +31,7 @@ */ #include -__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. diff --git a/src/add-ons/kernel/drivers/network/via_rhine/dev/vr/if_vr.c b/src/add-ons/kernel/drivers/network/via_rhine/dev/vr/if_vr.c index ed1c351587a..737084972ab 100644 --- a/src/add-ons/kernel/drivers/network/via_rhine/dev/vr/if_vr.c +++ b/src/add-ons/kernel/drivers/network/via_rhine/dev/vr/if_vr.c @@ -114,12 +114,12 @@ MODULE_DEPEND(vr, miibus, 1, 1, 1); #define VR_Q_CSUM (1<<1) #define VR_Q_CAM (1<<2) -static struct vr_type { +static const struct vr_type { u_int16_t vr_vid; u_int16_t vr_did; int vr_quirks; - char *vr_name; -} vr_devs[] = { + const char *vr_name; +} const vr_devs[] = { { VIA_VENDORID, VIA_DEVICEID_RHINE, VR_Q_NEEDALIGN, "VIA VT3043 Rhine I 10/100BaseTX" }, @@ -195,11 +195,11 @@ static void vr_setwol(struct vr_softc *); static void vr_clrwol(struct vr_softc *); static int vr_sysctl_stats(SYSCTL_HANDLER_ARGS); -static struct vr_tx_threshold_table { +static const struct vr_tx_threshold_table { int tx_cfg; int bcr_cfg; int value; -} vr_tx_threshold_tables[] = { +} const vr_tx_threshold_tables[] = { { VR_TXTHRESH_64BYTES, VR_BCR1_TXTHRESH64BYTES, 64 }, { VR_TXTHRESH_128BYTES, VR_BCR1_TXTHRESH128BYTES, 128 }, { VR_TXTHRESH_256BYTES, VR_BCR1_TXTHRESH256BYTES, 256 }, @@ -217,16 +217,12 @@ static device_method_t vr_methods[] = { DEVMETHOD(device_suspend, vr_suspend), DEVMETHOD(device_resume, vr_resume), - /* bus interface */ - DEVMETHOD(bus_print_child, bus_generic_print_child), - DEVMETHOD(bus_driver_added, bus_generic_driver_added), - /* MII interface */ DEVMETHOD(miibus_readreg, vr_miibus_readreg), DEVMETHOD(miibus_writereg, vr_miibus_writereg), DEVMETHOD(miibus_statchg, vr_miibus_statchg), - { NULL, NULL } + DEVMETHOD_END }; static driver_t vr_driver = { @@ -334,20 +330,20 @@ vr_miibus_statchg(device_t dev) (ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) return; - sc->vr_link = 0; + sc->vr_flags &= ~(VR_F_LINK | VR_F_TXPAUSE); 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->vr_link = 1; + sc->vr_flags |= VR_F_LINK; break; default: break; } } - if (sc->vr_link != 0) { + if ((sc->vr_flags & VR_F_LINK) != 0) { cr0 = CSR_READ_1(sc, VR_CR0); cr1 = CSR_READ_1(sc, VR_CR1); mfdx = (cr1 & VR_CR1_FULLDUPLEX) != 0; @@ -371,7 +367,6 @@ vr_miibus_statchg(device_t dev) CSR_WRITE_1(sc, VR_CR1, cr1); } fc = 0; -#ifdef notyet /* Configure flow-control. */ if (sc->vr_revid >= REV_ID_VT6105_A0) { fc = CSR_READ_1(sc, VR_FLOWCR1); @@ -380,8 +375,10 @@ vr_miibus_statchg(device_t dev) IFM_ETH_RXPAUSE) != 0) fc |= VR_FLOWCR1_RXPAUSE; if ((IFM_OPTIONS(mii->mii_media_active) & - IFM_ETH_TXPAUSE) != 0) + IFM_ETH_TXPAUSE) != 0) { fc |= VR_FLOWCR1_TXPAUSE; + sc->vr_flags |= VR_F_TXPAUSE; + } CSR_WRITE_1(sc, VR_FLOWCR1, fc); } else if (sc->vr_revid >= REV_ID_VT6102_A) { /* No Tx puase capability available for Rhine II. */ @@ -392,7 +389,6 @@ vr_miibus_statchg(device_t dev) fc |= VR_MISCCR0_RXPAUSE; CSR_WRITE_1(sc, VR_MISC_CR0, fc); } -#endif vr_rx_start(sc); vr_tx_start(sc); } else { @@ -582,10 +578,10 @@ vr_reset(const struct vr_softc *sc) * Probe for a VIA Rhine chip. Check the PCI vendor and device * IDs against our list and return a match or NULL */ -static struct vr_type * +static const struct vr_type * vr_match(device_t dev) { - struct vr_type *t = vr_devs; + const struct vr_type *t = vr_devs; for (t = vr_devs; t->vr_name != NULL; t++) if ((pci_get_vendor(dev) == t->vr_vid) && @@ -601,7 +597,7 @@ vr_match(device_t dev) static int vr_probe(device_t dev) { - struct vr_type *t; + const struct vr_type *t; t = vr_match(dev); if (t != NULL) { @@ -620,7 +616,7 @@ vr_attach(device_t dev) { struct vr_softc *sc; struct ifnet *ifp; - struct vr_type *t; + const struct vr_type *t; uint8_t eaddr[ETHER_ADDR_LEN]; int error, rid; int i, phy, pmc; @@ -795,7 +791,8 @@ vr_attach(device_t dev) else phy = CSR_READ_1(sc, VR_PHYADDR) & VR_PHYADDR_MASK; error = mii_attach(dev, &sc->vr_miibus, ifp, vr_ifmedia_upd, - vr_ifmedia_sts, BMSR_DEFCAPMASK, phy, MII_OFFSET_ANY, 0); + vr_ifmedia_sts, BMSR_DEFCAPMASK, phy, MII_OFFSET_ANY, + sc->vr_revid >= REV_ID_VT6102_A ? MIIF_DOPAUSE : 0); if (error != 0) { device_printf(dev, "attaching PHYs failed\n"); goto fail; @@ -850,7 +847,7 @@ vr_detach(device_t dev) /* These should only be active if attach succeeded. */ if (device_is_attached(dev)) { VR_LOCK(sc); - sc->vr_detach = 1; + sc->vr_flags |= VR_F_DETACHED; vr_stop(sc); VR_UNLOCK(sc); callout_drain(&sc->vr_stat_callout); @@ -1425,6 +1422,17 @@ vr_rxeof(struct vr_softc *sc) } if (prog > 0) { + /* + * Let controller know how many number of RX buffers + * are posted but avoid expensive register access if + * TX pause capability was not negotiated with link + * partner. + */ + if ((sc->vr_flags & VR_F_TXPAUSE) != 0) { + if (prog >= VR_RX_RING_CNT) + prog = VR_RX_RING_CNT - 1; + CSR_WRITE_1(sc, VR_FLOWCR0, prog); + } sc->vr_cdata.vr_rx_cons = cons; bus_dmamap_sync(sc->vr_cdata.vr_rx_ring_tag, sc->vr_cdata.vr_rx_ring_map, @@ -1571,7 +1579,7 @@ vr_tick(void *xsc) mii = device_get_softc(sc->vr_miibus); mii_tick(mii); - if (sc->vr_link == 0) + if ((sc->vr_flags & VR_F_LINK) == 0) vr_miibus_statchg(sc->vr_dev); vr_watchdog(sc); callout_reset(&sc->vr_stat_callout, hz, vr_tick, sc); @@ -1681,7 +1689,7 @@ vr_intr(void *arg) VR_LOCK(sc); - if (sc->vr_suspended != 0) + if ((sc->vr_flags & VR_F_SUSPENDED) != 0) goto done_locked; status = CSR_READ_2(sc, VR_ISR); @@ -1962,7 +1970,7 @@ vr_start_locked(struct ifnet *ifp) VR_LOCK_ASSERT(sc); if ((ifp->if_drv_flags & (IFF_DRV_RUNNING | IFF_DRV_OACTIVE)) != - IFF_DRV_RUNNING || sc->vr_link == 0) + IFF_DRV_RUNNING || (sc->vr_flags & VR_F_LINK) == 0) return; for (enq = 0; !IFQ_DRV_IS_EMPTY(&ifp->if_snd) && @@ -2100,14 +2108,32 @@ vr_init_locked(struct vr_softc *sc) /* Set flow-control parameters for Rhine III. */ if (sc->vr_revid >= REV_ID_VT6105_A0) { - /* Rx buffer count available for incoming packet. */ - CSR_WRITE_1(sc, VR_FLOWCR0, VR_RX_RING_CNT); /* - * Tx pause low threshold : 16 free receive buffers - * Tx pause XON high threshold : 48 free receive buffers + * Configure Rx buffer count available for incoming + * packet. + * Even though data sheet says almost nothing about + * this register, this register should be updated + * whenever driver adds new RX buffers to controller. + * Otherwise, XON frame is not sent to link partner + * even if controller has enough RX buffers and you + * would be isolated from network. + * The controller is not smart enough to know number + * of available RX buffers so driver have to let + * controller know how many RX buffers are posted. + * In other words, this register works like a residue + * counter for RX buffers and should be initialized + * to the number of total RX buffers - 1 before + * enabling RX MAC. Note, this register is 8bits so + * it effectively limits the maximum number of RX + * buffer to be configured by controller is 255. + */ + CSR_WRITE_1(sc, VR_FLOWCR0, VR_RX_RING_CNT - 1); + /* + * Tx pause low threshold : 8 free receive buffers + * Tx pause XON high threshold : 24 free receive buffers */ CSR_WRITE_1(sc, VR_FLOWCR1, - VR_FLOWCR1_TXLO16 | VR_FLOWCR1_TXHI48 | VR_FLOWCR1_XONXOFF); + VR_FLOWCR1_TXLO8 | VR_FLOWCR1_TXHI24 | VR_FLOWCR1_XONXOFF); /* Set Tx pause timer. */ CSR_WRITE_2(sc, VR_PAUSETIMER, 0xffff); } @@ -2132,12 +2158,12 @@ vr_init_locked(struct vr_softc *sc) if (sc->vr_revid > REV_ID_VT6102_A) CSR_WRITE_2(sc, VR_MII_IMR, 0); - sc->vr_link = 0; - mii_mediachg(mii); - ifp->if_drv_flags |= IFF_DRV_RUNNING; ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; + sc->vr_flags &= ~(VR_F_LINK | VR_F_TXPAUSE); + mii_mediachg(mii); + callout_reset(&sc->vr_stat_callout, hz, vr_tick, sc); } @@ -2157,6 +2183,7 @@ vr_ifmedia_upd(struct ifnet *ifp) mii = device_get_softc(sc->vr_miibus); LIST_FOREACH(miisc, &mii->mii_phys, mii_list) PHY_RESET(miisc); + sc->vr_flags &= ~(VR_F_LINK | VR_F_TXPAUSE); error = mii_mediachg(mii); VR_UNLOCK(sc); @@ -2180,9 +2207,9 @@ vr_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr) return; } mii_pollstat(mii); - VR_UNLOCK(sc); ifmr->ifm_active = mii->mii_media_active; ifmr->ifm_status = mii->mii_media_status; + VR_UNLOCK(sc); } static int @@ -2206,7 +2233,7 @@ vr_ioctl(struct ifnet *ifp, u_long command, caddr_t data) (IFF_PROMISC | IFF_ALLMULTI)) vr_set_filter(sc); } else { - if (sc->vr_detach == 0) + if ((sc->vr_flags & VR_F_DETACHED) == 0) vr_init_locked(sc); } } else { @@ -2294,7 +2321,7 @@ vr_watchdog(struct vr_softc *sc) if (sc->vr_cdata.vr_tx_cnt == 0) return; - if (sc->vr_link == 0) { + if ((sc->vr_flags & VR_F_LINK) == 0) { if (bootverbose) if_printf(sc->vr_ifp, "watchdog timeout " "(missed link)\n"); @@ -2472,7 +2499,7 @@ vr_suspend(device_t dev) VR_LOCK(sc); vr_stop(sc); vr_setwol(sc); - sc->vr_suspended = 1; + sc->vr_flags |= VR_F_SUSPENDED; VR_UNLOCK(sc); return (0); @@ -2493,7 +2520,7 @@ vr_resume(device_t dev) if (ifp->if_flags & IFF_UP) vr_init_locked(sc); - sc->vr_suspended = 0; + sc->vr_flags &= ~VR_F_SUSPENDED; VR_UNLOCK(sc); return (0); diff --git a/src/add-ons/kernel/drivers/network/via_rhine/dev/vr/if_vrreg.h b/src/add-ons/kernel/drivers/network/via_rhine/dev/vr/if_vrreg.h index 5e2b6b84032..2445babd7a7 100644 --- a/src/add-ons/kernel/drivers/network/via_rhine/dev/vr/if_vrreg.h +++ b/src/add-ons/kernel/drivers/network/via_rhine/dev/vr/if_vrreg.h @@ -720,20 +720,21 @@ struct vr_softc { void *vr_intrhand; device_t vr_miibus; uint8_t vr_revid; /* Rhine chip revision */ - uint8_t vr_flags; /* See VR_F_* below */ -#define VR_F_RESTART 0x01 /* Restart unit on next tick */ + int vr_flags; /* See VR_F_* below */ +#define VR_F_RESTART 0x0001 /* Restart unit on next tick */ +#define VR_F_TXPAUSE 0x0010 +#define VR_F_SUSPENDED 0x2000 +#define VR_F_DETACHED 0x4000 +#define VR_F_LINK 0x8000 int vr_if_flags; struct vr_chain_data vr_cdata; struct vr_ring_data vr_rdata; struct vr_statistics vr_stat; struct callout vr_stat_callout; struct mtx vr_mtx; - int vr_suspended; /* if 1, sleeping/detaching */ int vr_quirks; - int vr_link; int vr_watchdog_timer; int vr_txthresh; - int vr_detach; #ifdef DEVICE_POLLING int rxcycles; #endif diff --git a/src/add-ons/kernel/drivers/network/vt612x/dev/mii/ciphy.c b/src/add-ons/kernel/drivers/network/vt612x/dev/mii/ciphy.c index 2133c76ca05..87d0d814e91 100644 --- a/src/add-ons/kernel/drivers/network/vt612x/dev/mii/ciphy.c +++ b/src/add-ons/kernel/drivers/network/vt612x/dev/mii/ciphy.c @@ -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; diff --git a/src/add-ons/kernel/drivers/network/vt612x/dev/mii/ukphy.c b/src/add-ons/kernel/drivers/network/vt612x/dev/mii/ukphy.c index 4ecfce29d31..9d52eb580ca 100644 --- a/src/add-ons/kernel/drivers/network/vt612x/dev/mii/ukphy.c +++ b/src/add-ons/kernel/drivers/network/vt612x/dev/mii/ukphy.c @@ -55,7 +55,7 @@ */ #include -__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; diff --git a/src/add-ons/kernel/drivers/network/vt612x/dev/mii/ukphy_subr.c b/src/add-ons/kernel/drivers/network/vt612x/dev/mii/ukphy_subr.c index 73007e197b9..5f2f6341ba6 100644 --- a/src/add-ons/kernel/drivers/network/vt612x/dev/mii/ukphy_subr.c +++ b/src/add-ons/kernel/drivers/network/vt612x/dev/mii/ukphy_subr.c @@ -31,7 +31,7 @@ */ #include -__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. diff --git a/src/add-ons/kernel/drivers/network/vt612x/dev/vge/if_vge.c b/src/add-ons/kernel/drivers/network/vt612x/dev/vge/if_vge.c index 3ffee38a6e4..a49af277f53 100644 --- a/src/add-ons/kernel/drivers/network/vt612x/dev/vge/if_vge.c +++ b/src/add-ons/kernel/drivers/network/vt612x/dev/vge/if_vge.c @@ -31,7 +31,7 @@ */ #include -__FBSDID("$FreeBSD: src/sys/dev/vge/if_vge.c,v 1.37.2.12.2.1 2010/12/21 17:09:25 kensmith Exp $"); +__FBSDID("$FreeBSD$"); /* * VIA Networking Technologies VT612x PCI gigabit ethernet NIC driver. @@ -173,6 +173,7 @@ static __inline void static void vge_freebufs(struct vge_softc *); static void vge_ifmedia_sts(struct ifnet *, struct ifmediareq *); static int vge_ifmedia_upd(struct ifnet *); +static int vge_ifmedia_upd_locked(struct vge_softc *); static void vge_init(void *); static void vge_init_locked(struct vge_softc *); static void vge_intr(void *); @@ -180,7 +181,6 @@ static void vge_intr_holdoff(struct vge_softc *); static int vge_ioctl(struct ifnet *, u_long, caddr_t); static void vge_link_statchg(void *); static int vge_miibus_readreg(device_t, int, int); -static void vge_miibus_statchg(device_t); static int vge_miibus_writereg(device_t, int, int, int); static void vge_miipoll_start(struct vge_softc *); static void vge_miipoll_stop(struct vge_softc *); @@ -190,6 +190,7 @@ static void vge_reset(struct vge_softc *); static int vge_rx_list_init(struct vge_softc *); static int vge_rxeof(struct vge_softc *, int); static void vge_rxfilter(struct vge_softc *); +static void vge_setmedia(struct vge_softc *); static void vge_setvlan(struct vge_softc *); static void vge_setwol(struct vge_softc *); static void vge_start(struct ifnet *); @@ -211,16 +212,11 @@ static device_method_t vge_methods[] = { DEVMETHOD(device_resume, vge_resume), DEVMETHOD(device_shutdown, vge_shutdown), - /* bus interface */ - DEVMETHOD(bus_print_child, bus_generic_print_child), - DEVMETHOD(bus_driver_added, bus_generic_driver_added), - /* MII interface */ DEVMETHOD(miibus_readreg, vge_miibus_readreg), DEVMETHOD(miibus_writereg, vge_miibus_writereg), - DEVMETHOD(miibus_statchg, vge_miibus_statchg), - { 0, 0 } + DEVMETHOD_END }; static driver_t vge_driver = { @@ -1099,10 +1095,11 @@ vge_attach(device_t dev) goto fail; } + vge_miipoll_start(sc); /* Do MII setup */ error = mii_attach(dev, &sc->vge_miibus, ifp, vge_ifmedia_upd, vge_ifmedia_sts, BMSR_DEFCAPMASK, sc->vge_phyaddr, MII_OFFSET_ANY, - 0); + MIIF_DOPAUSE); if (error != 0) { device_printf(dev, "attaching PHYs failed\n"); goto fail; @@ -1660,30 +1657,41 @@ vge_link_statchg(void *xsc) { struct vge_softc *sc; struct ifnet *ifp; - struct mii_data *mii; + uint8_t physts; sc = xsc; ifp = sc->vge_ifp; VGE_LOCK_ASSERT(sc); - mii = device_get_softc(sc->vge_miibus); - mii_pollstat(mii); - if ((sc->vge_flags & VGE_FLAG_LINK) != 0) { - if (!(mii->mii_media_status & IFM_ACTIVE)) { + physts = CSR_READ_1(sc, VGE_PHYSTS0); + if ((physts & VGE_PHYSTS_RESETSTS) == 0) { + if ((physts & VGE_PHYSTS_LINK) == 0) { sc->vge_flags &= ~VGE_FLAG_LINK; if_link_state_change(sc->vge_ifp, LINK_STATE_DOWN); - } - } else { - if (mii->mii_media_status & IFM_ACTIVE && - IFM_SUBTYPE(mii->mii_media_active) != IFM_NONE) { + } else { sc->vge_flags |= VGE_FLAG_LINK; if_link_state_change(sc->vge_ifp, LINK_STATE_UP); + CSR_WRITE_1(sc, VGE_CRC2, VGE_CR2_FDX_TXFLOWCTL_ENABLE | + VGE_CR2_FDX_RXFLOWCTL_ENABLE); + if ((physts & VGE_PHYSTS_FDX) != 0) { + if ((physts & VGE_PHYSTS_TXFLOWCAP) != 0) + CSR_WRITE_1(sc, VGE_CRS2, + VGE_CR2_FDX_TXFLOWCTL_ENABLE); + if ((physts & VGE_PHYSTS_RXFLOWCAP) != 0) + CSR_WRITE_1(sc, VGE_CRS2, + VGE_CR2_FDX_RXFLOWCTL_ENABLE); + } if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) vge_start_locked(ifp); } } + /* + * Restart MII auto-polling because link state change interrupt + * will disable it. + */ + vge_miipoll_start(sc); } #ifdef DEVICE_POLLING @@ -2028,6 +2036,7 @@ vge_init_locked(struct vge_softc *sc) */ vge_stop(sc); vge_reset(sc); + vge_miipoll_start(sc); /* * Initialize the RX and TX descriptors and mbufs. @@ -2099,9 +2108,16 @@ vge_init_locked(struct vge_softc *sc) vge_rxfilter(sc); vge_setvlan(sc); - /* Enable flow control */ - - CSR_WRITE_1(sc, VGE_CRS2, 0x8B); + /* Initialize pause timer. */ + CSR_WRITE_2(sc, VGE_TX_PAUSE_TIMER, 0xFFFF); + /* + * Initialize flow control parameters. + * TX XON high threshold : 48 + * TX pause low threshold : 24 + * Disable hald-duplex flow control + */ + CSR_WRITE_1(sc, VGE_CRC2, 0xFF); + CSR_WRITE_1(sc, VGE_CRS2, VGE_CR2_XON_ENABLE | 0x0B); /* Enable jumbo frame reception (if desired) */ @@ -2129,7 +2145,7 @@ vge_init_locked(struct vge_softc *sc) CSR_WRITE_1(sc, VGE_CRS3, VGE_CR3_INT_GMSK); sc->vge_flags &= ~VGE_FLAG_LINK; - mii_mediachg(mii); + vge_ifmedia_upd_locked(sc); ifp->if_drv_flags |= IFF_DRV_RUNNING; ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; @@ -2143,14 +2159,28 @@ static int vge_ifmedia_upd(struct ifnet *ifp) { struct vge_softc *sc; - struct mii_data *mii; int error; sc = ifp->if_softc; VGE_LOCK(sc); + error = vge_ifmedia_upd_locked(sc); + VGE_UNLOCK(sc); + + return (error); +} + +static int +vge_ifmedia_upd_locked(struct vge_softc *sc) +{ + struct mii_data *mii; + struct mii_softc *miisc; + int error; + mii = device_get_softc(sc->vge_miibus); + LIST_FOREACH(miisc, &mii->mii_phys, mii_list) + PHY_RESET(miisc); + vge_setmedia(sc); error = mii_mediachg(mii); - VGE_UNLOCK(sc); return (error); } @@ -2173,19 +2203,17 @@ vge_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr) return; } mii_pollstat(mii); - VGE_UNLOCK(sc); ifmr->ifm_active = mii->mii_media_active; ifmr->ifm_status = mii->mii_media_status; + VGE_UNLOCK(sc); } static void -vge_miibus_statchg(device_t dev) +vge_setmedia(struct vge_softc *sc) { - struct vge_softc *sc; struct mii_data *mii; struct ifmedia_entry *ife; - sc = device_get_softc(dev); mii = device_get_softc(sc->vge_miibus); ife = mii->mii_media.ifm_cur; @@ -2219,7 +2247,7 @@ vge_miibus_statchg(device_t dev) } break; default: - device_printf(dev, "unknown media type: %x\n", + device_printf(sc->vge_dev, "unknown media type: %x\n", IFM_SUBTYPE(ife->ifm_media)); break; } @@ -2772,6 +2800,9 @@ vge_setlinkspeed(struct vge_softc *sc) break; } } + /* Clear forced MAC speed/duplex configuration. */ + CSR_CLRBIT_1(sc, VGE_DIAGCTL, VGE_DIAGCTL_MACFORCE); + CSR_CLRBIT_1(sc, VGE_DIAGCTL, VGE_DIAGCTL_FDXFORCE); vge_miibus_writereg(sc->vge_dev, sc->vge_phyaddr, MII_100T2CR, 0); vge_miibus_writereg(sc->vge_dev, sc->vge_phyaddr, MII_ANAR, ANAR_TX_FD | ANAR_TX | ANAR_10_FD | ANAR_10 | ANAR_CSMA); diff --git a/src/add-ons/kernel/drivers/network/vt612x/dev/vge/if_vgereg.h b/src/add-ons/kernel/drivers/network/vt612x/dev/vge/if_vgereg.h index a21f11e563e..c8b3f1bb459 100644 --- a/src/add-ons/kernel/drivers/network/vt612x/dev/vge/if_vgereg.h +++ b/src/add-ons/kernel/drivers/network/vt612x/dev/vge/if_vgereg.h @@ -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/vge/if_vgereg.h,v 1.2.22.6.4.1 2010/12/21 17:09:25 kensmith Exp $ + * $FreeBSD$ */ /* diff --git a/src/add-ons/kernel/drivers/network/vt612x/dev/vge/if_vgevar.h b/src/add-ons/kernel/drivers/network/vt612x/dev/vge/if_vgevar.h index d73370b50a6..ca899cc5fc0 100644 --- a/src/add-ons/kernel/drivers/network/vt612x/dev/vge/if_vgevar.h +++ b/src/add-ons/kernel/drivers/network/vt612x/dev/vge/if_vgevar.h @@ -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/vge/if_vgevar.h,v 1.4.22.9.4.1 2010/12/21 17:09:25 kensmith Exp $ + * $FreeBSD$ */ #define VGE_JUMBO_MTU 9000 diff --git a/src/add-ons/kernel/drivers/network/wlan/aironetwifi/dev/an/if_an.c b/src/add-ons/kernel/drivers/network/wlan/aironetwifi/dev/an/if_an.c index 0898961e955..ef729932d2e 100644 --- a/src/add-ons/kernel/drivers/network/wlan/aironetwifi/dev/an/if_an.c +++ b/src/add-ons/kernel/drivers/network/wlan/aironetwifi/dev/an/if_an.c @@ -796,7 +796,7 @@ an_attach(struct an_softc *sc, int flags) ADD(IFM_AUTO, IFM_IEEE80211_ADHOC); for (i = 0; i < nrate; i++) { r = sc->an_caps.an_rates[i]; - mword = ieee80211_rate2media(NULL, r, IEEE80211_T_DS); + mword = ieee80211_rate2media(NULL, r, IEEE80211_MODE_AUTO); if (mword == 0) continue; printf("%s%d%sMbps", (i != 0 ? " " : ""), @@ -3298,7 +3298,7 @@ an_media_status(struct ifnet *ifp, struct ifmediareq *imr) if (sc->an_config.an_opmode == AN_OPMODE_IBSS_ADHOC) imr->ifm_active |= IFM_IEEE80211_ADHOC; imr->ifm_active |= ieee80211_rate2media(NULL, - status.an_current_tx_rate, IEEE80211_T_DS); + status.an_current_tx_rate, IEEE80211_MODE_AUTO); imr->ifm_status = IFM_AVALID; if (status.an_opmode & AN_STATUS_OPMODE_ASSOCIATED) imr->ifm_status |= IFM_ACTIVE; diff --git a/src/add-ons/kernel/drivers/network/wlan/aironetwifi/dev/an/if_an_pci.c b/src/add-ons/kernel/drivers/network/wlan/aironetwifi/dev/an/if_an_pci.c index 2d0d2b5a667..fe3467d83e0 100644 --- a/src/add-ons/kernel/drivers/network/wlan/aironetwifi/dev/an/if_an_pci.c +++ b/src/add-ons/kernel/drivers/network/wlan/aironetwifi/dev/an/if_an_pci.c @@ -195,7 +195,7 @@ an_attach_pci(dev) } /* Allocate DMA region */ - error = bus_dma_tag_create(NULL, /* parent */ + error = bus_dma_tag_create(bus_get_dma_tag(dev),/* parent */ 1, 0, /* alignment, bounds */ BUS_SPACE_MAXADDR_32BIT, /* lowaddr */ BUS_SPACE_MAXADDR, /* highaddr */ diff --git a/src/add-ons/kernel/drivers/network/wlan/atheroswifi/dev/ath/ath_dfs/null/dfs_null.c b/src/add-ons/kernel/drivers/network/wlan/atheroswifi/dev/ath/ath_dfs/null/dfs_null.c index a3bae914585..75574b4e4ac 100644 --- a/src/add-ons/kernel/drivers/network/wlan/atheroswifi/dev/ath/ath_dfs/null/dfs_null.c +++ b/src/add-ons/kernel/drivers/network/wlan/atheroswifi/dev/ath/ath_dfs/null/dfs_null.c @@ -128,7 +128,7 @@ ath_dfs_process_radar_event(struct ath_softc *sc, } /* - * Determine whether the the DFS check task needs to be queued. + * Determine whether the DFS check task needs to be queued. * * This is called in the RX task when the current batch of packets * have been received. It will return whether there are any radar diff --git a/src/add-ons/kernel/drivers/network/wlan/atheroswifi/dev/ath/ath_hal/ar5210/ar5210reg.h b/src/add-ons/kernel/drivers/network/wlan/atheroswifi/dev/ath/ath_hal/ar5210/ar5210reg.h index 894d9bbd854..738210743f2 100644 --- a/src/add-ons/kernel/drivers/network/wlan/atheroswifi/dev/ath/ath_hal/ar5210/ar5210reg.h +++ b/src/add-ons/kernel/drivers/network/wlan/atheroswifi/dev/ath/ath_hal/ar5210/ar5210reg.h @@ -245,9 +245,20 @@ #define AR_SCR_SLDUR 0x0000ffff /* sleep duration */ #define AR_SCR_SLE 0x00030000 /* sleep enable */ #define AR_SCR_SLE_S 16 -#define AR_SCR_SLE_WAKE 0x00000000 /* force wake */ -#define AR_SCR_SLE_SLP 0x00010000 /* force sleep */ -#define AR_SCR_SLE_ALLOW 0x00020000 /* allow to control sleep */ +/* + * The previous values for the following three defines were: + * + * AR_SCR_SLE_WAKE 0x00000000 + * AR_SCR_SLE_SLP 0x00010000 + * AR_SCR_SLE_ALLOW 0x00020000 + * + * However, these have been pre-shifted with AR_SCR_SLE_S. The + * OS_REG_READ() macro would attempt to shift them again, effectively + * shifting out any of the set bits completely. + */ +#define AR_SCR_SLE_WAKE 0 /* force wake */ +#define AR_SCR_SLE_SLP 1 /* force sleep */ +#define AR_SCR_SLE_ALLOW 2 /* allow to control sleep */ #define AR_SCR_BITS "\20\20SLE_SLP\21SLE_ALLOW" #define AR_INTPEND_IP 0x00000001 /* interrupt pending */ diff --git a/src/add-ons/kernel/drivers/network/wlan/atheroswifi/dev/ath/ath_hal/ar5211/ar5211reg.h b/src/add-ons/kernel/drivers/network/wlan/atheroswifi/dev/ath/ath_hal/ar5211/ar5211reg.h index 647f20db455..93d4fc5d9b8 100644 --- a/src/add-ons/kernel/drivers/network/wlan/atheroswifi/dev/ath/ath_hal/ar5211/ar5211reg.h +++ b/src/add-ons/kernel/drivers/network/wlan/atheroswifi/dev/ath/ath_hal/ar5211/ar5211reg.h @@ -618,9 +618,20 @@ #define AR_SCR_SLDUR_S 0 #define AR_SCR_SLE 0x00030000 /* sleep enable mask */ #define AR_SCR_SLE_S 16 /* sleep enable bits shift */ -#define AR_SCR_SLE_WAKE 0x00000000 /* force wake */ -#define AR_SCR_SLE_SLP 0x00010000 /* force sleep */ -#define AR_SCR_SLE_NORM 0x00020000 /* sleep logic normal operation */ +/* + * The previous values for the following three defines were: + * + * AR_SCR_SLE_WAKE 0x00000000 + * AR_SCR_SLE_SLP 0x00010000 + * AR_SCR_SLE_NORM 0x00020000 + * + * However, these have been pre-shifted with AR_SCR_SLE_S. The + * OS_REG_READ() macro would attempt to shift them again, effectively + * shifting out any of the set bits completely. + */ +#define AR_SCR_SLE_WAKE 0 /* force wake */ +#define AR_SCR_SLE_SLP 1 /* force sleep */ +#define AR_SCR_SLE_NORM 2 /* sleep logic normal operation */ #define AR_SCR_SLE_UNITS 0x00000008 /* SCR units/TU */ #define AR_SCR_BITS "\20\20SLE_SLP\21SLE" diff --git a/src/add-ons/kernel/drivers/network/wlan/atheroswifi/dev/ath/ath_hal/ar5212/ar5212_misc.c b/src/add-ons/kernel/drivers/network/wlan/atheroswifi/dev/ath/ath_hal/ar5212/ar5212_misc.c index 5bcde762a5d..e1eab2c6cce 100644 --- a/src/add-ons/kernel/drivers/network/wlan/atheroswifi/dev/ath/ath_hal/ar5212/ar5212_misc.c +++ b/src/add-ons/kernel/drivers/network/wlan/atheroswifi/dev/ath/ath_hal/ar5212/ar5212_misc.c @@ -573,7 +573,7 @@ ar5212SetDecompMask(struct ath_hal *ah, uint16_t keyidx, int en) struct ath_hal_5212 *ahp = AH5212(ah); if (keyidx >= HAL_DECOMP_MASK_SIZE) - return HAL_EINVAL; + return AH_FALSE; OS_REG_WRITE(ah, AR_DCM_A, keyidx); OS_REG_WRITE(ah, AR_DCM_D, en ? AR_DCM_D_EN : 0); ahp->ah_decompMask[keyidx] = en; diff --git a/src/add-ons/kernel/drivers/network/wlan/atheroswifi/dev/ath/ath_hal/ar5416/ar5416_misc.c b/src/add-ons/kernel/drivers/network/wlan/atheroswifi/dev/ath/ath_hal/ar5416/ar5416_misc.c index 7e61c84930d..68c41174366 100644 --- a/src/add-ons/kernel/drivers/network/wlan/atheroswifi/dev/ath/ath_hal/ar5416/ar5416_misc.c +++ b/src/add-ons/kernel/drivers/network/wlan/atheroswifi/dev/ath/ath_hal/ar5416/ar5416_misc.c @@ -155,7 +155,7 @@ ar5416SetAntennaSwitch(struct ath_hal *ah, HAL_ANT_SETTING settings) HAL_BOOL ar5416SetDecompMask(struct ath_hal *ah, uint16_t keyidx, int en) { - return HAL_OK; + return AH_TRUE; } /* Setup coverage class */ diff --git a/src/add-ons/kernel/drivers/network/wlan/atheroswifi/dev/ath/if_ath.c b/src/add-ons/kernel/drivers/network/wlan/atheroswifi/dev/ath/if_ath.c index 6ba6b1ae061..de6e49eaaed 100644 --- a/src/add-ons/kernel/drivers/network/wlan/atheroswifi/dev/ath/if_ath.c +++ b/src/add-ons/kernel/drivers/network/wlan/atheroswifi/dev/ath/if_ath.c @@ -119,9 +119,9 @@ __FBSDID("$FreeBSD$"); CTASSERT(ATH_BCBUF <= 8); static struct ieee80211vap *ath_vap_create(struct ieee80211com *, - const char name[IFNAMSIZ], int unit, int opmode, - int flags, const uint8_t bssid[IEEE80211_ADDR_LEN], - const uint8_t mac[IEEE80211_ADDR_LEN]); + const char [IFNAMSIZ], int, enum ieee80211_opmode, int, + const uint8_t [IEEE80211_ADDR_LEN], + const uint8_t [IEEE80211_ADDR_LEN]); static void ath_vap_delete(struct ieee80211vap *); static void ath_init(void *); static void ath_stop_locked(struct ifnet *); @@ -849,16 +849,17 @@ assign_bslot(struct ath_softc *sc) } static struct ieee80211vap * -ath_vap_create(struct ieee80211com *ic, - const char name[IFNAMSIZ], int unit, int opmode, int flags, - const uint8_t bssid[IEEE80211_ADDR_LEN], - const uint8_t mac0[IEEE80211_ADDR_LEN]) +ath_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit, + enum ieee80211_opmode opmode, int flags, + const uint8_t bssid[IEEE80211_ADDR_LEN], + const uint8_t mac0[IEEE80211_ADDR_LEN]) { struct ath_softc *sc = ic->ic_ifp->if_softc; struct ath_vap *avp; struct ieee80211vap *vap; uint8_t mac[IEEE80211_ADDR_LEN]; - int ic_opmode, needbeacon, error; + int needbeacon, error; + enum ieee80211_opmode ic_opmode; avp = (struct ath_vap *) malloc(sizeof(struct ath_vap), M_80211_VAP, M_WAITOK | M_ZERO); diff --git a/src/add-ons/kernel/drivers/network/wlan/atheroswifi/dev/ath/if_ath_sysctl.c b/src/add-ons/kernel/drivers/network/wlan/atheroswifi/dev/ath/if_ath_sysctl.c index ea6f949bdbe..4c60275bb0e 100644 --- a/src/add-ons/kernel/drivers/network/wlan/atheroswifi/dev/ath/if_ath_sysctl.c +++ b/src/add-ons/kernel/drivers/network/wlan/atheroswifi/dev/ath/if_ath_sysctl.c @@ -756,7 +756,7 @@ ath_sysctl_hal_attach(struct ath_softc *sc) sc->sc_ah->ah_config.ah_ar5416_biasadj = 0; SYSCTL_ADD_INT(ctx, child, OID_AUTO, "ar5416_biasadj", CTLFLAG_RW, &sc->sc_ah->ah_config.ah_ar5416_biasadj, 0, - "Enable 2ghz AR5416 direction sensitivity bias adjust"); + "Enable 2GHz AR5416 direction sensitivity bias adjust"); sc->sc_ah->ah_config.ah_dma_beacon_response_time = 2; SYSCTL_ADD_INT(ctx, child, OID_AUTO, "dma_brt", CTLFLAG_RW, diff --git a/src/add-ons/kernel/drivers/network/wlan/broadcom43xx/dev/bwi/bwiphy.c b/src/add-ons/kernel/drivers/network/wlan/broadcom43xx/dev/bwi/bwiphy.c index c41c0f85487..d817d260344 100644 --- a/src/add-ons/kernel/drivers/network/wlan/broadcom43xx/dev/bwi/bwiphy.c +++ b/src/add-ons/kernel/drivers/network/wlan/broadcom43xx/dev/bwi/bwiphy.c @@ -796,7 +796,7 @@ bwi_phy_config_11g(struct bwi_mac *mac) bwi_tbl_write_2(mac, BWI_PHYTBL_RSSI + i, i); /* Fill noise table */ - for (i = 0; i < sizeof(bwi_phy_noise_11g); ++i) { + for (i = 0; i < N(bwi_phy_noise_11g); ++i) { bwi_tbl_write_2(mac, BWI_PHYTBL_NOISE + i, bwi_phy_noise_11g[i]); } diff --git a/src/add-ons/kernel/drivers/network/wlan/broadcom43xx/dev/bwi/if_bwi.c b/src/add-ons/kernel/drivers/network/wlan/broadcom43xx/dev/bwi/if_bwi.c index f789ca0ba50..3e0f294e986 100644 --- a/src/add-ons/kernel/drivers/network/wlan/broadcom43xx/dev/bwi/if_bwi.c +++ b/src/add-ons/kernel/drivers/network/wlan/broadcom43xx/dev/bwi/if_bwi.c @@ -1,13 +1,13 @@ /* * Copyright (c) 2007 The DragonFly Project. All rights reserved. - * + * * This code is derived from software contributed to The DragonFly Project * by Sepherosa Ziehau - * + * * 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 @@ -17,7 +17,7 @@ * 3. Neither the name of The DragonFly Project 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 @@ -30,7 +30,7 @@ * 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. - * + * * $DragonFly: src/sys/dev/netif/bwi/if_bwi.c,v 1.19 2008/02/15 11:15:38 sephe Exp $ */ @@ -52,7 +52,7 @@ __FBSDID("$FreeBSD$"); #include #include #include - + #include #include #include @@ -70,7 +70,7 @@ __FBSDID("$FreeBSD$"); #include #ifdef INET -#include +#include #include #endif @@ -96,9 +96,9 @@ struct bwi_myaddr_bssid { } __packed; static struct ieee80211vap *bwi_vap_create(struct ieee80211com *, - const char [IFNAMSIZ], int, int, int, - const uint8_t [IEEE80211_ADDR_LEN], - const uint8_t [IEEE80211_ADDR_LEN]); + const char [IFNAMSIZ], int, enum ieee80211_opmode, int, + const uint8_t [IEEE80211_ADDR_LEN], + const uint8_t [IEEE80211_ADDR_LEN]); static void bwi_vap_delete(struct ieee80211vap *); static void bwi_init(void *); static int bwi_ioctl(struct ifnet *, u_long, caddr_t); @@ -118,8 +118,7 @@ static void bwi_calibrate(void *); static int bwi_calc_rssi(struct bwi_softc *, const struct bwi_rxbuf_hdr *); static int bwi_calc_noise(struct bwi_softc *); -static __inline uint8_t bwi_ofdm_plcp2rate(const uint32_t *); -static __inline uint8_t bwi_ds_plcp2rate(const struct ieee80211_ds_plcp_hdr *); +static __inline uint8_t bwi_plcp2rate(uint32_t, enum ieee80211_phytype); static void bwi_rx_radiotap(struct bwi_softc *, struct mbuf *, struct bwi_rxbuf_hdr *, const void *, int, int, int); @@ -221,7 +220,7 @@ static const struct { } bwi_bbpid_map[] = { { 0x4301, 0x4301, 0x4301 }, { 0x4305, 0x4307, 0x4307 }, - { 0x4403, 0x4403, 0x4402 }, + { 0x4402, 0x4403, 0x4402 }, { 0x4610, 0x4615, 0x4610 }, { 0x4710, 0x4715, 0x4710 }, { 0x4720, 0x4725, 0x4309 } @@ -592,10 +591,10 @@ bwi_detach(struct bwi_softc *sc) } static struct ieee80211vap * -bwi_vap_create(struct ieee80211com *ic, - const char name[IFNAMSIZ], int unit, int opmode, int flags, - const uint8_t bssid[IEEE80211_ADDR_LEN], - const uint8_t mac[IEEE80211_ADDR_LEN]) +bwi_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit, + enum ieee80211_opmode opmode, int flags, + const uint8_t bssid[IEEE80211_ADDR_LEN], + const uint8_t mac[IEEE80211_ADDR_LEN]) { struct bwi_vap *bvp; struct ieee80211vap *vap; @@ -1805,7 +1804,7 @@ bwi_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) * the same AP, this will reinialize things * correctly... */ - if (ic->ic_opmode == IEEE80211_M_STA && + if (ic->ic_opmode == IEEE80211_M_STA && !(sc->sc_flags & BWI_F_STOP)) bwi_set_bssid(sc, bwi_zero_addr); } @@ -2635,7 +2634,7 @@ bwi_rxeof(struct bwi_softc *sc, int end_idx) struct ieee80211_frame_min *wh; struct ieee80211_node *ni; struct mbuf *m; - const void *plcp; + uint32_t plcp; uint16_t flags2; int buflen, wh_ofs, hdr_extra, rssi, noise, type, rate; @@ -2665,7 +2664,7 @@ bwi_rxeof(struct bwi_softc *sc, int end_idx) goto next; } - plcp = ((const uint8_t *)(hdr + 1) + hdr_extra); + bcopy((uint8_t *)(hdr + 1) + hdr_extra, &plcp, sizeof(plcp)); rssi = bwi_calc_rssi(sc, hdr); noise = bwi_calc_noise(sc); @@ -2674,13 +2673,13 @@ bwi_rxeof(struct bwi_softc *sc, int end_idx) m_adj(m, sizeof(*hdr) + wh_ofs); if (htole16(hdr->rxh_flags1) & BWI_RXH_F1_OFDM) - rate = bwi_ofdm_plcp2rate(plcp); + rate = bwi_plcp2rate(plcp, IEEE80211_T_OFDM); else - rate = bwi_ds_plcp2rate(plcp); + rate = bwi_plcp2rate(plcp, IEEE80211_T_CCK); /* RX radio tap */ if (ieee80211_radiotap_active(ic)) - bwi_rx_radiotap(sc, m, hdr, plcp, rate, rssi, noise); + bwi_rx_radiotap(sc, m, hdr, &plcp, rate, rssi, noise); m_adj(m, -IEEE80211_CRC_LEN); @@ -3808,20 +3807,10 @@ bwi_calc_noise(struct bwi_softc *sc) } static __inline uint8_t -bwi_ofdm_plcp2rate(const uint32_t *plcp0) -{ - uint32_t plcp; - uint8_t plcp_rate; - - plcp = le32toh(*plcp0); - plcp_rate = __SHIFTOUT(plcp, IEEE80211_OFDM_PLCP_RATE_MASK); - return ieee80211_plcp2rate(plcp_rate, IEEE80211_T_OFDM); -} - -static __inline uint8_t -bwi_ds_plcp2rate(const struct ieee80211_ds_plcp_hdr *hdr) +bwi_plcp2rate(const uint32_t plcp0, enum ieee80211_phytype type) { - return ieee80211_plcp2rate(hdr->i_signal, IEEE80211_T_DS); + uint32_t plcp = le32toh(plcp0) & IEEE80211_OFDM_PLCP_RATE_MASK; + return (ieee80211_plcp2rate(plcp, type)); } static void diff --git a/src/add-ons/kernel/drivers/network/wlan/broadcom43xx/dev/bwi/if_bwivar.h b/src/add-ons/kernel/drivers/network/wlan/broadcom43xx/dev/bwi/if_bwivar.h index bb35623a15e..7a8a59bdf36 100644 --- a/src/add-ons/kernel/drivers/network/wlan/broadcom43xx/dev/bwi/if_bwivar.h +++ b/src/add-ons/kernel/drivers/network/wlan/broadcom43xx/dev/bwi/if_bwivar.h @@ -1,13 +1,13 @@ /* * Copyright (c) 2007 The DragonFly Project. All rights reserved. - * + * * This code is derived from software contributed to The DragonFly Project * by Sepherosa Ziehau - * + * * 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 @@ -17,7 +17,7 @@ * 3. Neither the name of The DragonFly Project 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 @@ -30,7 +30,7 @@ * 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. - * + * * $DragonFly: src/sys/dev/netif/bwi/if_bwivar.h,v 1.14 2008/02/15 11:15:38 sephe Exp $ * $FreeBSD$ */ diff --git a/src/add-ons/kernel/drivers/network/wlan/iprowifi2100/dev/ipw/if_ipw.c b/src/add-ons/kernel/drivers/network/wlan/iprowifi2100/dev/ipw/if_ipw.c index 0a576ab0648..24f0a1f36ef 100644 --- a/src/add-ons/kernel/drivers/network/wlan/iprowifi2100/dev/ipw/if_ipw.c +++ b/src/add-ons/kernel/drivers/network/wlan/iprowifi2100/dev/ipw/if_ipw.c @@ -108,9 +108,9 @@ static const struct ipw_ident ipw_ident_table[] = { }; static struct ieee80211vap *ipw_vap_create(struct ieee80211com *, - const char name[IFNAMSIZ], int unit, int opmode, int flags, - const uint8_t bssid[IEEE80211_ADDR_LEN], - const uint8_t mac[IEEE80211_ADDR_LEN]); + const char [IFNAMSIZ], int, enum ieee80211_opmode, int, + const uint8_t [IEEE80211_ADDR_LEN], + const uint8_t [IEEE80211_ADDR_LEN]); static void ipw_vap_delete(struct ieee80211vap *); static int ipw_dma_alloc(struct ipw_softc *); static void ipw_release(struct ipw_softc *); @@ -428,10 +428,10 @@ ipw_detach(device_t dev) } static struct ieee80211vap * -ipw_vap_create(struct ieee80211com *ic, - const char name[IFNAMSIZ], int unit, int opmode, int flags, - const uint8_t bssid[IEEE80211_ADDR_LEN], - const uint8_t mac[IEEE80211_ADDR_LEN]) +ipw_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit, + enum ieee80211_opmode opmode, int flags, + const uint8_t bssid[IEEE80211_ADDR_LEN], + const uint8_t mac[IEEE80211_ADDR_LEN]) { struct ifnet *ifp = ic->ic_ifp; struct ipw_softc *sc = ifp->if_softc; @@ -527,10 +527,22 @@ ipw_dma_alloc(struct ipw_softc *sc) bus_addr_t physaddr; int error, i; + /* + * Allocate parent DMA tag for subsequent allocations. + */ + error = bus_dma_tag_create(bus_get_dma_tag(sc->sc_dev), 1, 0, + BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL, + BUS_SPACE_MAXSIZE_32BIT, BUS_SPACE_UNRESTRICTED, + BUS_SPACE_MAXSIZE_32BIT, 0, NULL, NULL, &sc->parent_dmat); + if (error != 0) { + device_printf(sc->sc_dev, "could not create parent DMA tag\n"); + goto fail; + } + /* * Allocate and map tx ring. */ - error = bus_dma_tag_create(NULL, 4, 0, BUS_SPACE_MAXADDR_32BIT, + error = bus_dma_tag_create(sc->parent_dmat, 4, 0, BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL, IPW_TBD_SZ, 1, IPW_TBD_SZ, 0, NULL, NULL, &sc->tbd_dmat); if (error != 0) { @@ -556,7 +568,7 @@ ipw_dma_alloc(struct ipw_softc *sc) /* * Allocate and map rx ring. */ - error = bus_dma_tag_create(NULL, 4, 0, BUS_SPACE_MAXADDR_32BIT, + error = bus_dma_tag_create(sc->parent_dmat, 4, 0, BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL, IPW_RBD_SZ, 1, IPW_RBD_SZ, 0, NULL, NULL, &sc->rbd_dmat); if (error != 0) { @@ -582,7 +594,7 @@ ipw_dma_alloc(struct ipw_softc *sc) /* * Allocate and map status ring. */ - error = bus_dma_tag_create(NULL, 4, 0, BUS_SPACE_MAXADDR_32BIT, + error = bus_dma_tag_create(sc->parent_dmat, 4, 0, BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL, IPW_STATUS_SZ, 1, IPW_STATUS_SZ, 0, NULL, NULL, &sc->status_dmat); if (error != 0) { @@ -611,7 +623,7 @@ ipw_dma_alloc(struct ipw_softc *sc) /* * Allocate command DMA map. */ - error = bus_dma_tag_create(NULL, 1, 0, BUS_SPACE_MAXADDR_32BIT, + error = bus_dma_tag_create(sc->parent_dmat, 1, 0, BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL, sizeof (struct ipw_cmd), 1, sizeof (struct ipw_cmd), 0, NULL, NULL, &sc->cmd_dmat); if (error != 0) { @@ -629,7 +641,7 @@ ipw_dma_alloc(struct ipw_softc *sc) /* * Allocate headers DMA maps. */ - error = bus_dma_tag_create(NULL, 1, 0, BUS_SPACE_MAXADDR_32BIT, + error = bus_dma_tag_create(sc->parent_dmat, 1, 0, BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL, sizeof (struct ipw_hdr), 1, sizeof (struct ipw_hdr), 0, NULL, NULL, &sc->hdr_dmat); if (error != 0) { @@ -652,7 +664,7 @@ ipw_dma_alloc(struct ipw_softc *sc) /* * Allocate tx buffers DMA maps. */ - error = bus_dma_tag_create(NULL, 1, 0, BUS_SPACE_MAXADDR_32BIT, + error = bus_dma_tag_create(sc->parent_dmat, 1, 0, BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL, MCLBYTES, IPW_MAX_NSEG, MCLBYTES, 0, NULL, NULL, &sc->txbuf_dmat); if (error != 0) { @@ -684,7 +696,7 @@ ipw_dma_alloc(struct ipw_softc *sc) /* * Pre-allocate rx buffers and DMA maps. */ - error = bus_dma_tag_create(NULL, 1, 0, BUS_SPACE_MAXADDR_32BIT, + error = bus_dma_tag_create(sc->parent_dmat, 1, 0, BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL, MCLBYTES, 1, MCLBYTES, 0, NULL, NULL, &sc->rxbuf_dmat); if (error != 0) { @@ -741,6 +753,10 @@ ipw_release(struct ipw_softc *sc) struct ipw_soft_buf *sbuf; int i; + if (sc->parent_dmat != NULL) { + bus_dma_tag_destroy(sc->parent_dmat); + } + if (sc->tbd_dmat != NULL) { if (sc->stbd_list != NULL) { bus_dmamap_unload(sc->tbd_dmat, sc->tbd_map); @@ -819,9 +835,9 @@ static int ipw_suspend(device_t dev) { struct ipw_softc *sc = device_get_softc(dev); + struct ieee80211com *ic = sc->sc_ifp->if_l2com; - ipw_stop(sc); - + ieee80211_suspend_all(ic); return 0; } @@ -829,13 +845,11 @@ static int ipw_resume(device_t dev) { struct ipw_softc *sc = device_get_softc(dev); - struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = sc->sc_ifp->if_l2com; pci_write_config(dev, 0x41, 0, 1); - if (ifp->if_flags & IFF_UP) - ipw_init(sc); - + ieee80211_resume_all(ic); return 0; } diff --git a/src/add-ons/kernel/drivers/network/wlan/iprowifi2100/dev/ipw/if_ipwvar.h b/src/add-ons/kernel/drivers/network/wlan/iprowifi2100/dev/ipw/if_ipwvar.h index 6be3cbc1be4..ea4f2180182 100644 --- a/src/add-ons/kernel/drivers/network/wlan/iprowifi2100/dev/ipw/if_ipwvar.h +++ b/src/add-ons/kernel/drivers/network/wlan/iprowifi2100/dev/ipw/if_ipwvar.h @@ -117,6 +117,7 @@ struct ipw_softc { int sc_tx_timer; int sc_scan_timer; + bus_dma_tag_t parent_dmat; bus_dma_tag_t tbd_dmat; bus_dma_tag_t rbd_dmat; bus_dma_tag_t status_dmat; diff --git a/src/add-ons/kernel/drivers/network/wlan/iprowifi2200/dev/iwi/if_iwi.c b/src/add-ons/kernel/drivers/network/wlan/iprowifi2200/dev/iwi/if_iwi.c index a826750c2d2..33463749367 100644 --- a/src/add-ons/kernel/drivers/network/wlan/iprowifi2200/dev/iwi/if_iwi.c +++ b/src/add-ons/kernel/drivers/network/wlan/iprowifi2200/dev/iwi/if_iwi.c @@ -129,7 +129,7 @@ static const struct iwi_ident iwi_ident_table[] = { }; static struct ieee80211vap *iwi_vap_create(struct ieee80211com *, - const char name[IFNAMSIZ], int unit, int opmode, int flags, + const char name[IFNAMSIZ], int unit, enum ieee80211_opmode opmode, int flags, const uint8_t bssid[IEEE80211_ADDR_LEN], const uint8_t mac[IEEE80211_ADDR_LEN]); static void iwi_vap_delete(struct ieee80211vap *); @@ -496,7 +496,7 @@ iwi_detach(device_t dev) static struct ieee80211vap * iwi_vap_create(struct ieee80211com *ic, - const char name[IFNAMSIZ], int unit, int opmode, int flags, + const char name[IFNAMSIZ], int unit, enum ieee80211_opmode opmode, int flags, const uint8_t bssid[IEEE80211_ADDR_LEN], const uint8_t mac[IEEE80211_ADDR_LEN]) { diff --git a/src/add-ons/kernel/drivers/network/wlan/iprowifi3945/dev/wpi/if_wpi.c b/src/add-ons/kernel/drivers/network/wlan/iprowifi3945/dev/wpi/if_wpi.c index 62f44d1362b..d35ab79086a 100644 --- a/src/add-ons/kernel/drivers/network/wlan/iprowifi3945/dev/wpi/if_wpi.c +++ b/src/add-ons/kernel/drivers/network/wlan/iprowifi3945/dev/wpi/if_wpi.c @@ -157,9 +157,9 @@ static const struct wpi_ident wpi_ident_table[] = { }; static struct ieee80211vap *wpi_vap_create(struct ieee80211com *, - const char name[IFNAMSIZ], int unit, int opmode, - int flags, const uint8_t bssid[IEEE80211_ADDR_LEN], - const uint8_t mac[IEEE80211_ADDR_LEN]); + const char [IFNAMSIZ], int, enum ieee80211_opmode, int, + const uint8_t [IEEE80211_ADDR_LEN], + const uint8_t [IEEE80211_ADDR_LEN]); static void wpi_vap_delete(struct ieee80211vap *); static int wpi_dma_contig_alloc(struct wpi_softc *, struct wpi_dma_info *, void **, bus_size_t, bus_size_t, int); @@ -760,10 +760,10 @@ wpi_detach(device_t dev) } static struct ieee80211vap * -wpi_vap_create(struct ieee80211com *ic, - const char name[IFNAMSIZ], int unit, int opmode, int flags, - const uint8_t bssid[IEEE80211_ADDR_LEN], - const uint8_t mac[IEEE80211_ADDR_LEN]) +wpi_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit, + enum ieee80211_opmode opmode, int flags, + const uint8_t bssid[IEEE80211_ADDR_LEN], + const uint8_t mac[IEEE80211_ADDR_LEN]) { struct wpi_vap *wvp; struct ieee80211vap *vap; @@ -1218,8 +1218,9 @@ static int wpi_suspend(device_t dev) { struct wpi_softc *sc = device_get_softc(dev); + struct ieee80211com *ic = sc->sc_ifp->if_l2com; - wpi_stop(sc); + ieee80211_suspend_all(ic); return 0; } @@ -1227,15 +1228,11 @@ static int wpi_resume(device_t dev) { struct wpi_softc *sc = device_get_softc(dev); - struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = sc->sc_ifp->if_l2com; pci_write_config(dev, 0x41, 0, 1); - if (ifp->if_flags & IFF_UP) { - wpi_init(ifp->if_softc); - if (ifp->if_drv_flags & IFF_DRV_RUNNING) - wpi_start(ifp); - } + ieee80211_resume_all(ic); return 0; } diff --git a/src/add-ons/kernel/drivers/network/wlan/iprowifi4965/dev/iwn/if_iwn.c b/src/add-ons/kernel/drivers/network/wlan/iprowifi4965/dev/iwn/if_iwn.c index 6c95ec05120..4ae41916176 100644 --- a/src/add-ons/kernel/drivers/network/wlan/iprowifi4965/dev/iwn/if_iwn.c +++ b/src/add-ons/kernel/drivers/network/wlan/iprowifi4965/dev/iwn/if_iwn.c @@ -79,34 +79,38 @@ struct iwn_ident { }; static const struct iwn_ident iwn_ident_table[] = { - { 0x8086, 0x0082, "Intel(R) Centrino(R) Advanced-N 6205" }, - { 0x8086, 0x0083, "Intel(R) Centrino(R) Wireless-N 1000" }, - { 0x8086, 0x0084, "Intel(R) Centrino(R) Wireless-N 1000" }, - { 0x8086, 0x0085, "Intel(R) Centrino(R) Advanced-N 6205" }, - { 0x8086, 0x0087, "Intel(R) Centrino(R) Advanced-N + WiMAX 6250" }, - { 0x8086, 0x0089, "Intel(R) Centrino(R) Advanced-N + WiMAX 6250" }, - { 0x8086, 0x008a, "Intel(R) Centrino(R) Wireless-N 1030" }, - { 0x8086, 0x008b, "Intel(R) Centrino(R) Wireless-N 1030" }, - { 0x8086, 0x0090, "Intel(R) Centrino(R) Advanced-N 6230" }, - { 0x8086, 0x0091, "Intel(R) Centrino(R) Advanced-N 6230" }, - { 0x8086, 0x088e, "Intel(R) Centrino(R) Advanced-N 6235" }, - { 0x8086, 0x0896, "Intel(R) Centrino(R) Wireless-N 130" }, - { 0x8086, 0x4229, "Intel(R) Wireless WiFi Link 4965" }, - { 0x8086, 0x422b, "Intel(R) Centrino(R) Ultimate-N 6300" }, - { 0x8086, 0x422c, "Intel(R) Centrino(R) Advanced-N 6200" }, - { 0x8086, 0x422d, "Intel(R) Wireless WiFi Link 4965" }, - { 0x8086, 0x4230, "Intel(R) Wireless WiFi Link 4965" }, - { 0x8086, 0x4232, "Intel(R) WiFi Link 5100" }, - { 0x8086, 0x4233, "Intel(R) Wireless WiFi Link 4965" }, - { 0x8086, 0x4235, "Intel(R) Ultimate N WiFi Link 5300" }, - { 0x8086, 0x4236, "Intel(R) Ultimate N WiFi Link 5300" }, - { 0x8086, 0x4237, "Intel(R) WiFi Link 5100" }, - { 0x8086, 0x4238, "Intel(R) Centrino(R) Ultimate-N 6300" }, - { 0x8086, 0x4239, "Intel(R) Centrino(R) Advanced-N 6200" }, - { 0x8086, 0x423a, "Intel(R) WiMAX/WiFi Link 5350" }, - { 0x8086, 0x423b, "Intel(R) WiMAX/WiFi Link 5350" }, - { 0x8086, 0x423c, "Intel(R) WiMAX/WiFi Link 5150" }, - { 0x8086, 0x423d, "Intel(R) WiMAX/WiFi Link 5150" }, + { 0x8086, 0x0082, "Intel Centrino Advanced-N 6205" }, + { 0x8086, 0x0083, "Intel Centrino Wireless-N 1000" }, + { 0x8086, 0x0084, "Intel Centrino Wireless-N 1000" }, + { 0x8086, 0x0085, "Intel Centrino Advanced-N 6205" }, + { 0x8086, 0x0087, "Intel Centrino Advanced-N + WiMAX 6250" }, + { 0x8086, 0x0089, "Intel Centrino Advanced-N + WiMAX 6250" }, + { 0x8086, 0x008a, "Intel Centrino Wireless-N 1030" }, + { 0x8086, 0x008b, "Intel Centrino Wireless-N 1030" }, + { 0x8086, 0x0090, "Intel Centrino Advanced-N 6230" }, + { 0x8086, 0x0091, "Intel Centrino Advanced-N 6230" }, + { 0x8086, 0x0885, "Intel Centrino Wireless-N + WiMAX 6150" }, + { 0x8086, 0x0886, "Intel Centrino Wireless-N + WiMAX 6150" }, + { 0x8086, 0x0896, "Intel Centrino Wireless-N 130" }, + { 0x8086, 0x0887, "Intel Centrino Wireless-N 130" }, + { 0x8086, 0x08ae, "Intel Centrino Wireless-N 100" }, + { 0x8086, 0x08af, "Intel Centrino Wireless-N 100" }, + { 0x8086, 0x4229, "Intel Wireless WiFi Link 4965" }, + { 0x8086, 0x422b, "Intel Centrino Ultimate-N 6300" }, + { 0x8086, 0x422c, "Intel Centrino Advanced-N 6200" }, + { 0x8086, 0x422d, "Intel Wireless WiFi Link 4965" }, + { 0x8086, 0x4230, "Intel Wireless WiFi Link 4965" }, + { 0x8086, 0x4232, "Intel WiFi Link 5100" }, + { 0x8086, 0x4233, "Intel Wireless WiFi Link 4965" }, + { 0x8086, 0x4235, "Intel Ultimate N WiFi Link 5300" }, + { 0x8086, 0x4236, "Intel Ultimate N WiFi Link 5300" }, + { 0x8086, 0x4237, "Intel WiFi Link 5100" }, + { 0x8086, 0x4238, "Intel Centrino Ultimate-N 6300" }, + { 0x8086, 0x4239, "Intel Centrino Advanced-N 6200" }, + { 0x8086, 0x423a, "Intel WiMAX/WiFi Link 5350" }, + { 0x8086, 0x423b, "Intel WiMAX/WiFi Link 5350" }, + { 0x8086, 0x423c, "Intel WiMAX/WiFi Link 5150" }, + { 0x8086, 0x423d, "Intel WiMAX/WiFi Link 5150" }, { 0, 0, NULL } }; @@ -117,9 +121,9 @@ static int iwn5000_attach(struct iwn_softc *, uint16_t); static void iwn_radiotap_attach(struct iwn_softc *); static void iwn_sysctlattach(struct iwn_softc *); static struct ieee80211vap *iwn_vap_create(struct ieee80211com *, - const char name[IFNAMSIZ], int unit, int opmode, - int flags, const uint8_t bssid[IEEE80211_ADDR_LEN], - const uint8_t mac[IEEE80211_ADDR_LEN]); + const char [IFNAMSIZ], int, enum ieee80211_opmode, int, + const uint8_t [IEEE80211_ADDR_LEN], + const uint8_t [IEEE80211_ADDR_LEN]); static void iwn_vap_delete(struct ieee80211vap *); static int iwn_detach(device_t); static int iwn_shutdown(device_t); @@ -846,8 +850,8 @@ iwn_sysctlattach(struct iwn_softc *sc) } static struct ieee80211vap * -iwn_vap_create(struct ieee80211com *ic, - const char name[IFNAMSIZ], int unit, int opmode, int flags, +iwn_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit, + enum ieee80211_opmode opmode, int flags, const uint8_t bssid[IEEE80211_ADDR_LEN], const uint8_t mac[IEEE80211_ADDR_LEN]) { @@ -946,13 +950,9 @@ static int iwn_suspend(device_t dev) { struct iwn_softc *sc = device_get_softc(dev); - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; - struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); + struct ieee80211com *ic = sc->sc_ifp->if_l2com; - iwn_stop(sc); - if (vap != NULL) - ieee80211_stop(vap); + ieee80211_suspend_all(ic); return 0; } @@ -960,20 +960,12 @@ static int iwn_resume(device_t dev) { struct iwn_softc *sc = device_get_softc(dev); - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; - struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); + struct ieee80211com *ic = sc->sc_ifp->if_l2com; /* Clear device-specific "PCI retry timeout" register (41h). */ pci_write_config(dev, 0x41, 0, 1); - if (ifp->if_flags & IFF_UP) { - iwn_init(sc); - if (vap != NULL) - ieee80211_init(vap); - if (ifp->if_drv_flags & IFF_DRV_RUNNING) - iwn_start(ifp); - } + ieee80211_resume_all(ic); return 0; } @@ -2013,8 +2005,6 @@ iwn_setregdomain(struct ieee80211com *ic, struct ieee80211_regdomain *rd, return 0; } -#define nitems(_a) (sizeof((_a)) / sizeof((_a)[0])) - static void iwn_read_eeprom_enhinfo(struct iwn_softc *sc) { @@ -2129,7 +2119,7 @@ iwn_newassoc(struct ieee80211_node *ni, int isnew) plcp |= IWN_RFLAG_SGI; } else if (ni->ni_htcap & IEEE80211_HTCAP_SHORTGI20) plcp |= IWN_RFLAG_SGI; - if (i > 7) + if (RV(ni->ni_htrates.rs_rates[i]) > 7) plcp |= IWN_RFLAG_ANT(txant1 | txant2); else plcp |= IWN_RFLAG_ANT(txant1); @@ -2442,23 +2432,66 @@ static void iwn_rx_compressed_ba(struct iwn_softc *sc, struct iwn_rx_desc *desc, struct iwn_rx_data *data) { + struct iwn_ops *ops = &sc->ops; struct ifnet *ifp = sc->sc_ifp; struct iwn_node *wn; struct ieee80211_node *ni; struct iwn_compressed_ba *ba = (struct iwn_compressed_ba *)(desc + 1); struct iwn_tx_ring *txq; + struct iwn_tx_data *txdata; struct ieee80211_tx_ampdu *tap; + struct mbuf *m; uint64_t bitmap; + uint16_t ssn; uint8_t tid; - int ackfailcnt = 0, i, shift; + int ackfailcnt = 0, i, lastidx, qid, *res, shift; bus_dmamap_sync(sc->rxq.data_dmat, data->map, BUS_DMASYNC_POSTREAD); - txq = &sc->txq[le16toh(ba->qid)]; - tap = sc->qid2tap[le16toh(ba->qid)]; + qid = le16toh(ba->qid); + txq = &sc->txq[ba->qid]; + tap = sc->qid2tap[ba->qid]; tid = WME_AC_TO_TID(tap->txa_ac); - ni = tap->txa_ni; - wn = (void *)ni; + wn = (void *)tap->txa_ni; + + res = NULL; + ssn = 0; + if (!IEEE80211_AMPDU_RUNNING(tap)) { + res = tap->txa_private; + ssn = tap->txa_start & 0xfff; + } + + for (lastidx = le16toh(ba->ssn) & 0xff; txq->read != lastidx;) { + txdata = &txq->data[txq->read]; + + /* Unmap and free mbuf. */ + bus_dmamap_sync(txq->data_dmat, txdata->map, + BUS_DMASYNC_POSTWRITE); + bus_dmamap_unload(txq->data_dmat, txdata->map); + m = txdata->m, txdata->m = NULL; + ni = txdata->ni, txdata->ni = NULL; + + KASSERT(ni != NULL, ("no node")); + KASSERT(m != NULL, ("no mbuf")); + + if (m->m_flags & M_TXCB) + ieee80211_process_callback(ni, m, 1); + + m_freem(m); + ieee80211_free_node(ni); + + txq->queued--; + txq->read = (txq->read + 1) % IWN_TX_RING_COUNT; + } + + if (txq->queued == 0 && res != NULL) { + iwn_nic_lock(sc); + ops->ampdu_tx_stop(sc, qid, tid, ssn); + iwn_nic_unlock(sc); + sc->qid2tap[qid] = NULL; + free(res, M_DEVBUF); + return; + } if (wn->agg[tid].bitmap == 0) return; @@ -2470,6 +2503,7 @@ iwn_rx_compressed_ba(struct iwn_softc *sc, struct iwn_rx_desc *desc, if (wn->agg[tid].nframes > (64 - shift)) return; + ni = tap->txa_ni; bitmap = (le64toh(ba->bitmap) >> shift) & wn->agg[tid].bitmap; for (i = 0; bitmap; i++) { if ((bitmap & 1) == 0) { @@ -2769,19 +2803,20 @@ static void iwn_ampdu_tx_done(struct iwn_softc *sc, int qid, int idx, int nframes, void *stat) { + struct iwn_ops *ops = &sc->ops; struct ifnet *ifp = sc->sc_ifp; struct iwn_tx_ring *ring = &sc->txq[qid]; struct iwn_tx_data *data; struct mbuf *m; struct iwn_node *wn; struct ieee80211_node *ni; - struct ieee80211vap *vap; struct ieee80211_tx_ampdu *tap; uint64_t bitmap; uint32_t *status = stat; uint16_t *aggstatus = stat; + uint16_t ssn; uint8_t tid; - int bit, i, lastidx, seqno, shift, start; + int bit, i, lastidx, *res, seqno, shift, start; #ifdef NOT_YET if (nframes == 1) { @@ -2820,19 +2855,26 @@ iwn_ampdu_tx_done(struct iwn_softc *sc, int qid, int idx, int nframes, wn->agg[tid].startidx = start; wn->agg[tid].nframes = nframes; + res = NULL; + ssn = 0; + if (!IEEE80211_AMPDU_RUNNING(tap)) { + res = tap->txa_private; + ssn = tap->txa_start & 0xfff; + } + seqno = le32toh(*(status + nframes)) & 0xfff; for (lastidx = (seqno & 0xff); ring->read != lastidx;) { data = &ring->data[ring->read]; - KASSERT(data->ni != NULL, ("no node")); - /* Unmap and free mbuf. */ bus_dmamap_sync(ring->data_dmat, data->map, BUS_DMASYNC_POSTWRITE); bus_dmamap_unload(ring->data_dmat, data->map); m = data->m, data->m = NULL; ni = data->ni, data->ni = NULL; - vap = ni->ni_vap; + + KASSERT(ni != NULL, ("no node")); + KASSERT(m != NULL, ("no mbuf")); if (m->m_flags & M_TXCB) ieee80211_process_callback(ni, m, 1); @@ -2844,6 +2886,15 @@ iwn_ampdu_tx_done(struct iwn_softc *sc, int qid, int idx, int nframes, ring->read = (ring->read + 1) % IWN_TX_RING_COUNT; } + if (ring->queued == 0 && res != NULL) { + iwn_nic_lock(sc); + ops->ampdu_tx_stop(sc, qid, tid, ssn); + iwn_nic_unlock(sc); + sc->qid2tap[qid] = NULL; + free(res, M_DEVBUF); + return; + } + sc->sc_tx_timer = 0; if (ring->queued < IWN_TX_RING_LOMARK) { sc->qfullmsk &= ~(1 << ring->qid); @@ -3322,18 +3373,20 @@ iwn_tx_data(struct iwn_softc *sc, struct mbuf *m, struct ieee80211_node *ni) tid = 0; } ac = M_WME_GETAC(m); - - if (IEEE80211_QOS_HAS_SEQ(wh) && - IEEE80211_AMPDU_RUNNING(&ni->ni_tx_ampdu[ac])) { + if (m->m_flags & M_AMPDU_MPDU) { struct ieee80211_tx_ampdu *tap = &ni->ni_tx_ampdu[ac]; - ring = &sc->txq[*(int *)tap->txa_private]; + if (!IEEE80211_AMPDU_RUNNING(tap)) { + m_freem(m); + return EINVAL; + } + + ac = *(int *)tap->txa_private; *(uint16_t *)wh->i_seq = htole16(ni->ni_txseqs[tid] << IEEE80211_SEQ_SEQ_SHIFT); ni->ni_txseqs[tid]++; - } else { - ring = &sc->txq[ac]; } + ring = &sc->txq[ac]; desc = &ring->desc[ring->cur]; data = &ring->data[ring->cur]; @@ -5647,6 +5700,8 @@ iwn_ampdu_tx_start(struct ieee80211com *ic, struct ieee80211_node *ni, if ((error = iwn_nic_lock(sc)) != 0) return 0; qid = *(int *)tap->txa_private; + DPRINTF(sc, IWN_DEBUG_XMIT, "%s: ra=%d tid=%d ssn=%d qid=%d\n", + __func__, wn->id, tid, tap->txa_start, qid); ops->ampdu_tx_start(sc, ni, qid, tid, tap->txa_start & 0xfff); iwn_nic_unlock(sc); @@ -5662,10 +5717,14 @@ iwn_ampdu_tx_stop(struct ieee80211_node *ni, struct ieee80211_tx_ampdu *tap) uint8_t tid = WME_AC_TO_TID(tap->txa_ac); int qid; + sc->sc_addba_stop(ni, tap); + if (tap->txa_private == NULL) return; qid = *(int *)tap->txa_private; + if (sc->txq[qid].queued != 0) + return; if (iwn_nic_lock(sc) != 0) return; ops->ampdu_tx_stop(sc, qid, tid, tap->txa_start & 0xfff); @@ -5673,7 +5732,6 @@ iwn_ampdu_tx_stop(struct ieee80211_node *ni, struct ieee80211_tx_ampdu *tap) sc->qid2tap[qid] = NULL; free(tap->txa_private, M_DEVBUF); tap->txa_private = NULL; - sc->sc_addba_stop(ni, tap); } static void diff --git a/src/add-ons/kernel/drivers/network/wlan/marvell88w8335/dev/malo/if_malo.c b/src/add-ons/kernel/drivers/network/wlan/marvell88w8335/dev/malo/if_malo.c index ae6ef882652..dbb4f385bea 100644 --- a/src/add-ons/kernel/drivers/network/wlan/marvell88w8335/dev/malo/if_malo.c +++ b/src/add-ons/kernel/drivers/network/wlan/marvell88w8335/dev/malo/if_malo.c @@ -125,10 +125,10 @@ enum { MALLOC_DEFINE(M_MALODEV, "malodev", "malo driver dma buffers"); -static struct ieee80211vap *malo_vap_create(struct ieee80211com *ic, - const char name[IFNAMSIZ], int unit, int opmode, int flags, - const uint8_t bssid[IEEE80211_ADDR_LEN], - const uint8_t mac[IEEE80211_ADDR_LEN]); +static struct ieee80211vap *malo_vap_create(struct ieee80211com *, + const char [IFNAMSIZ], int, enum ieee80211_opmode, int, + const uint8_t [IEEE80211_ADDR_LEN], + const uint8_t [IEEE80211_ADDR_LEN]); static void malo_vap_delete(struct ieee80211vap *); static int malo_dma_setup(struct malo_softc *); static int malo_setup_hwdma(struct malo_softc *); @@ -344,10 +344,10 @@ malo_attach(uint16_t devid, struct malo_softc *sc) } static struct ieee80211vap * -malo_vap_create(struct ieee80211com *ic, - const char name[IFNAMSIZ], int unit, int opmode, int flags, - const uint8_t bssid[IEEE80211_ADDR_LEN], - const uint8_t mac[IEEE80211_ADDR_LEN]) +malo_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit, + enum ieee80211_opmode opmode, int flags, + const uint8_t bssid[IEEE80211_ADDR_LEN], + const uint8_t mac[IEEE80211_ADDR_LEN]) { struct ifnet *ifp = ic->ic_ifp; struct malo_vap *mvp; diff --git a/src/add-ons/kernel/drivers/network/wlan/marvell88w8363/dev/mwl/if_mwl.c b/src/add-ons/kernel/drivers/network/wlan/marvell88w8363/dev/mwl/if_mwl.c index 0d47661c4e3..f42a45d3a2a 100644 --- a/src/add-ons/kernel/drivers/network/wlan/marvell88w8363/dev/mwl/if_mwl.c +++ b/src/add-ons/kernel/drivers/network/wlan/marvell88w8363/dev/mwl/if_mwl.c @@ -83,9 +83,9 @@ __FBSDID("$FreeBSD$"); #define SM(v,x) (((v) << x##_S) & x) static struct ieee80211vap *mwl_vap_create(struct ieee80211com *, - const char name[IFNAMSIZ], int unit, int opmode, - int flags, const uint8_t bssid[IEEE80211_ADDR_LEN], - const uint8_t mac[IEEE80211_ADDR_LEN]); + const char [IFNAMSIZ], int, enum ieee80211_opmode, int, + const uint8_t [IEEE80211_ADDR_LEN], + const uint8_t [IEEE80211_ADDR_LEN]); static void mwl_vap_delete(struct ieee80211vap *); static int mwl_setupdma(struct mwl_softc *); static int mwl_hal_reset(struct mwl_softc *sc); @@ -601,10 +601,10 @@ reclaim_address(struct mwl_softc *sc, uint8_t mac[IEEE80211_ADDR_LEN]) } static struct ieee80211vap * -mwl_vap_create(struct ieee80211com *ic, - const char name[IFNAMSIZ], int unit, int opmode, int flags, - const uint8_t bssid[IEEE80211_ADDR_LEN], - const uint8_t mac0[IEEE80211_ADDR_LEN]) +mwl_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit, + enum ieee80211_opmode opmode, int flags, + const uint8_t bssid[IEEE80211_ADDR_LEN], + const uint8_t mac0[IEEE80211_ADDR_LEN]) { struct ifnet *ifp = ic->ic_ifp; struct mwl_softc *sc = ifp->if_softc; diff --git a/src/add-ons/kernel/drivers/network/wlan/marvell88w8363/dev/mwl/mwlhal.c b/src/add-ons/kernel/drivers/network/wlan/marvell88w8363/dev/mwl/mwlhal.c index 18992c2f68a..3b8f27e2d31 100644 --- a/src/add-ons/kernel/drivers/network/wlan/marvell88w8363/dev/mwl/mwlhal.c +++ b/src/add-ons/kernel/drivers/network/wlan/marvell88w8363/dev/mwl/mwlhal.c @@ -1451,20 +1451,15 @@ mwl_hal_bastream_alloc(struct mwl_hal_vap *vap, int ba_policy, } sp = &mh->mh_streams[s]; mh->mh_bastreams &= ~(1<public.data[0] = a1; - sp->public.data[1] = a2; - IEEE80211_ADDR_COPY(sp->macaddr, Macaddr); - sp->tid = Tid; - sp->paraminfo = ParamInfo; - sp->setup = 0; - sp->ba_policy = ba_policy; - MWL_HAL_UNLOCK(mh); - return &sp->public; - } else { - MWL_HAL_UNLOCK(mh); - return NULL; - } + sp->public.data[0] = a1; + sp->public.data[1] = a2; + IEEE80211_ADDR_COPY(sp->macaddr, Macaddr); + sp->tid = Tid; + sp->paraminfo = ParamInfo; + sp->setup = 0; + sp->ba_policy = ba_policy; + MWL_HAL_UNLOCK(mh); + return sp != NULL ? &sp->public : NULL; } const MWL_HAL_BASTREAM * diff --git a/src/add-ons/kernel/drivers/network/wlan/ralinkwifi/Jamfile b/src/add-ons/kernel/drivers/network/wlan/ralinkwifi/Jamfile index a6be2bb1727..f519213d82e 100644 --- a/src/add-ons/kernel/drivers/network/wlan/ralinkwifi/Jamfile +++ b/src/add-ons/kernel/drivers/network/wlan/ralinkwifi/Jamfile @@ -19,6 +19,7 @@ KernelAddon ralinkwifi : if_ral_pci.c rt2560.c rt2661.c + rt2860.c glue.c : libfreebsd_wlan.a diff --git a/src/add-ons/kernel/drivers/network/wlan/ralinkwifi/dev/ral/if_ral_pci.c b/src/add-ons/kernel/drivers/network/wlan/ralinkwifi/dev/ral/if_ral_pci.c index 68b662261f8..cd892b50d93 100644 --- a/src/add-ons/kernel/drivers/network/wlan/ralinkwifi/dev/ral/if_ral_pci.c +++ b/src/add-ons/kernel/drivers/network/wlan/ralinkwifi/dev/ral/if_ral_pci.c @@ -57,6 +57,7 @@ __FBSDID("$FreeBSD$"); #include #include +#include MODULE_DEPEND(ral, pci, 1, 1, 1); MODULE_DEPEND(ral, firmware, 1, 1, 1); @@ -70,11 +71,37 @@ struct ral_pci_ident { }; static const struct ral_pci_ident ral_pci_ids[] = { + { 0x1432, 0x7708, "Edimax RT2860" }, + { 0x1432, 0x7711, "Edimax RT3591" }, + { 0x1432, 0x7722, "Edimax RT3591" }, + { 0x1432, 0x7727, "Edimax RT2860" }, + { 0x1432, 0x7728, "Edimax RT2860" }, + { 0x1432, 0x7738, "Edimax RT2860" }, + { 0x1432, 0x7748, "Edimax RT2860" }, + { 0x1432, 0x7758, "Edimax RT2860" }, + { 0x1432, 0x7768, "Edimax RT2860" }, + { 0x1462, 0x891a, "MSI RT3090" }, { 0x1814, 0x0201, "Ralink Technology RT2560" }, { 0x1814, 0x0301, "Ralink Technology RT2561S" }, { 0x1814, 0x0302, "Ralink Technology RT2561" }, { 0x1814, 0x0401, "Ralink Technology RT2661" }, - + { 0x1814, 0x0601, "Ralink Technology RT2860" }, + { 0x1814, 0x0681, "Ralink Technology RT2890" }, + { 0x1814, 0x0701, "Ralink Technology RT2760" }, + { 0x1814, 0x0781, "Ralink Technology RT2790" }, + { 0x1814, 0x3060, "Ralink Technology RT3060" }, + { 0x1814, 0x3062, "Ralink Technology RT3062" }, + { 0x1814, 0x3090, "Ralink Technology RT3090" }, + { 0x1814, 0x3091, "Ralink Technology RT3091" }, + { 0x1814, 0x3092, "Ralink Technology RT3092" }, + { 0x1814, 0x3390, "Ralink Technology RT3390" }, + { 0x1814, 0x3562, "Ralink Technology RT3562" }, + { 0x1814, 0x3592, "Ralink Technology RT3592" }, + { 0x1814, 0x3593, "Ralink Technology RT3593" }, + { 0x1814, 0x5390, "Ralink Technology RT5390" }, + { 0x1814, 0x539a, "Ralink Technology RT5390" }, + { 0x1814, 0x539f, "Ralink Technology RT5390" }, + { 0x1a3b, 0x1059, "AWT RT2890" }, { 0, 0, NULL } }; @@ -101,12 +128,20 @@ static struct ral_opns { rt2661_suspend, rt2661_resume, rt2661_intr +}, ral_rt2860_opns = { + rt2860_attach, + rt2860_detach, + rt2860_shutdown, + rt2860_suspend, + rt2860_resume, + rt2860_intr }; struct ral_pci_softc { union { struct rt2560_softc sc_rt2560; struct rt2661_softc sc_rt2661; + struct rt2860_softc sc_rt2860; } u; struct ral_opns *sc_opns; @@ -180,8 +215,19 @@ ral_pci_attach(device_t dev) /* enable bus-mastering */ pci_enable_busmaster(dev); - psc->sc_opns = (pci_get_device(dev) == 0x0201) ? &ral_rt2560_opns : - &ral_rt2661_opns; + switch (pci_get_device(dev)) { + case 0x0201: + psc->sc_opns = &ral_rt2560_opns; + break; + case 0x0301: + case 0x0302: + case 0x0401: + psc->sc_opns = &ral_rt2661_opns; + break; + default: + psc->sc_opns = &ral_rt2860_opns; + break; + } psc->mem_rid = RAL_PCI_BAR0; psc->mem = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &psc->mem_rid, diff --git a/src/add-ons/kernel/drivers/network/wlan/ralinkwifi/dev/ral/rt2560.c b/src/add-ons/kernel/drivers/network/wlan/ralinkwifi/dev/ral/rt2560.c index 33667becf53..815794cae66 100644 --- a/src/add-ons/kernel/drivers/network/wlan/ralinkwifi/dev/ral/rt2560.c +++ b/src/add-ons/kernel/drivers/network/wlan/ralinkwifi/dev/ral/rt2560.c @@ -85,9 +85,9 @@ __FBSDID("$FreeBSD$"); #endif static struct ieee80211vap *rt2560_vap_create(struct ieee80211com *, - const char name[IFNAMSIZ], int unit, int opmode, - int flags, const uint8_t bssid[IEEE80211_ADDR_LEN], - const uint8_t mac[IEEE80211_ADDR_LEN]); + const char [IFNAMSIZ], int, enum ieee80211_opmode, + int, const uint8_t [IEEE80211_ADDR_LEN], + const uint8_t [IEEE80211_ADDR_LEN]); static void rt2560_vap_delete(struct ieee80211vap *); static void rt2560_dma_map_addr(void *, bus_dma_segment_t *, int, int); @@ -373,10 +373,10 @@ rt2560_detach(void *xsc) } static struct ieee80211vap * -rt2560_vap_create(struct ieee80211com *ic, - const char name[IFNAMSIZ], int unit, int opmode, int flags, - const uint8_t bssid[IEEE80211_ADDR_LEN], - const uint8_t mac[IEEE80211_ADDR_LEN]) +rt2560_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit, + enum ieee80211_opmode opmode, int flags, + const uint8_t bssid[IEEE80211_ADDR_LEN], + const uint8_t mac[IEEE80211_ADDR_LEN]) { struct ifnet *ifp = ic->ic_ifp; struct rt2560_vap *rvp; diff --git a/src/add-ons/kernel/drivers/network/wlan/ralinkwifi/dev/ral/rt2661.c b/src/add-ons/kernel/drivers/network/wlan/ralinkwifi/dev/ral/rt2661.c index 0adc8990d48..63ab1d1c701 100644 --- a/src/add-ons/kernel/drivers/network/wlan/ralinkwifi/dev/ral/rt2661.c +++ b/src/add-ons/kernel/drivers/network/wlan/ralinkwifi/dev/ral/rt2661.c @@ -82,9 +82,9 @@ __FBSDID("$FreeBSD$"); #endif static struct ieee80211vap *rt2661_vap_create(struct ieee80211com *, - const char name[IFNAMSIZ], int unit, int opmode, - int flags, const uint8_t bssid[IEEE80211_ADDR_LEN], - const uint8_t mac[IEEE80211_ADDR_LEN]); + const char [IFNAMSIZ], int, enum ieee80211_opmode, + int, const uint8_t [IEEE80211_ADDR_LEN], + const uint8_t [IEEE80211_ADDR_LEN]); static void rt2661_vap_delete(struct ieee80211vap *); static void rt2661_dma_map_addr(void *, bus_dma_segment_t *, int, int); @@ -368,10 +368,10 @@ rt2661_detach(void *xsc) } static struct ieee80211vap * -rt2661_vap_create(struct ieee80211com *ic, - const char name[IFNAMSIZ], int unit, int opmode, int flags, - const uint8_t bssid[IEEE80211_ADDR_LEN], - const uint8_t mac[IEEE80211_ADDR_LEN]) +rt2661_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit, + enum ieee80211_opmode opmode, int flags, + const uint8_t bssid[IEEE80211_ADDR_LEN], + const uint8_t mac[IEEE80211_ADDR_LEN]) { struct ifnet *ifp = ic->ic_ifp; struct rt2661_vap *rvp; diff --git a/src/add-ons/kernel/drivers/network/wlan/ralinkwifi/dev/ral/rt2860.c b/src/add-ons/kernel/drivers/network/wlan/ralinkwifi/dev/ral/rt2860.c new file mode 100644 index 00000000000..4a5aa259c0e --- /dev/null +++ b/src/add-ons/kernel/drivers/network/wlan/ralinkwifi/dev/ral/rt2860.c @@ -0,0 +1,4103 @@ +/*- + * Copyright (c) 2007-2010 Damien Bergamini + * Copyright (c) 2012 Bernhard Schmidt + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * $OpenBSD: rt2860.c,v 1.65 2010/10/23 14:24:54 damien Exp $ + */ + +#include +__FBSDID("$FreeBSD$"); + +/*- + * Ralink Technology RT2860/RT3090/RT3390/RT3562 chipset driver + * http://www.ralinktech.com/ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include + +#define RAL_DEBUG +#ifdef RAL_DEBUG +#define DPRINTF(x) do { if (sc->sc_debug > 0) printf x; } while (0) +#define DPRINTFN(n, x) do { if (sc->sc_debug >= (n)) printf x; } while (0) +#else +#define DPRINTF(x) +#define DPRINTFN(n, x) +#endif + +static struct ieee80211vap *rt2860_vap_create(struct ieee80211com *, + const char [IFNAMSIZ], int, enum ieee80211_opmode, + int, const uint8_t [IEEE80211_ADDR_LEN], + const uint8_t [IEEE80211_ADDR_LEN]); +static void rt2860_vap_delete(struct ieee80211vap *); +static void rt2860_dma_map_addr(void *, bus_dma_segment_t *, int, int); +static int rt2860_alloc_tx_ring(struct rt2860_softc *, + struct rt2860_tx_ring *); +static void rt2860_reset_tx_ring(struct rt2860_softc *, + struct rt2860_tx_ring *); +static void rt2860_free_tx_ring(struct rt2860_softc *, + struct rt2860_tx_ring *); +static int rt2860_alloc_tx_pool(struct rt2860_softc *); +static void rt2860_free_tx_pool(struct rt2860_softc *); +static int rt2860_alloc_rx_ring(struct rt2860_softc *, + struct rt2860_rx_ring *); +static void rt2860_reset_rx_ring(struct rt2860_softc *, + struct rt2860_rx_ring *); +static void rt2860_free_rx_ring(struct rt2860_softc *, + struct rt2860_rx_ring *); +static void rt2860_updatestats(struct rt2860_softc *); +static void rt2860_newassoc(struct ieee80211_node *, int); +static void rt2860_node_free(struct ieee80211_node *); +#ifdef IEEE80211_HT +static int rt2860_ampdu_rx_start(struct ieee80211com *, + struct ieee80211_node *, uint8_t); +static void rt2860_ampdu_rx_stop(struct ieee80211com *, + struct ieee80211_node *, uint8_t); +#endif +static int rt2860_newstate(struct ieee80211vap *, enum ieee80211_state, + int); +static uint16_t rt3090_efuse_read_2(struct rt2860_softc *, uint16_t); +static uint16_t rt2860_eeprom_read_2(struct rt2860_softc *, uint16_t); +static void rt2860_intr_coherent(struct rt2860_softc *); +static void rt2860_drain_stats_fifo(struct rt2860_softc *); +static void rt2860_tx_intr(struct rt2860_softc *, int); +static void rt2860_rx_intr(struct rt2860_softc *); +static void rt2860_tbtt_intr(struct rt2860_softc *); +static void rt2860_gp_intr(struct rt2860_softc *); +static int rt2860_tx(struct rt2860_softc *, struct mbuf *, + struct ieee80211_node *); +static int rt2860_raw_xmit(struct ieee80211_node *, struct mbuf *, + const struct ieee80211_bpf_params *); +static int rt2860_tx_raw(struct rt2860_softc *, struct mbuf *, + struct ieee80211_node *, + const struct ieee80211_bpf_params *params); +static void rt2860_start(struct ifnet *); +static void rt2860_start_locked(struct ifnet *); +static void rt2860_watchdog(void *); +static int rt2860_ioctl(struct ifnet *, u_long, caddr_t); +static void rt2860_mcu_bbp_write(struct rt2860_softc *, uint8_t, uint8_t); +static uint8_t rt2860_mcu_bbp_read(struct rt2860_softc *, uint8_t); +static void rt2860_rf_write(struct rt2860_softc *, uint8_t, uint32_t); +static uint8_t rt3090_rf_read(struct rt2860_softc *, uint8_t); +static void rt3090_rf_write(struct rt2860_softc *, uint8_t, uint8_t); +static int rt2860_mcu_cmd(struct rt2860_softc *, uint8_t, uint16_t, int); +static void rt2860_enable_mrr(struct rt2860_softc *); +static void rt2860_set_txpreamble(struct rt2860_softc *); +static void rt2860_set_basicrates(struct rt2860_softc *, + const struct ieee80211_rateset *); +static void rt2860_scan_start(struct ieee80211com *); +static void rt2860_scan_end(struct ieee80211com *); +static void rt2860_set_channel(struct ieee80211com *); +static void rt2860_select_chan_group(struct rt2860_softc *, int); +static void rt2860_set_chan(struct rt2860_softc *, u_int); +static void rt3090_set_chan(struct rt2860_softc *, u_int); +static int rt3090_rf_init(struct rt2860_softc *); +static void rt3090_rf_wakeup(struct rt2860_softc *); +static int rt3090_filter_calib(struct rt2860_softc *, uint8_t, uint8_t, + uint8_t *); +static void rt3090_rf_setup(struct rt2860_softc *); +static void rt2860_set_leds(struct rt2860_softc *, uint16_t); +static void rt2860_set_gp_timer(struct rt2860_softc *, int); +static void rt2860_set_bssid(struct rt2860_softc *, const uint8_t *); +static void rt2860_set_macaddr(struct rt2860_softc *, const uint8_t *); +static void rt2860_update_promisc(struct ifnet *); +static void rt2860_updateslot(struct ifnet *); +static void rt2860_updateprot(struct ifnet *); +static int rt2860_updateedca(struct ieee80211com *); +#ifdef HW_CRYPTO +static int rt2860_set_key(struct ieee80211com *, struct ieee80211_node *, + struct ieee80211_key *); +static void rt2860_delete_key(struct ieee80211com *, + struct ieee80211_node *, struct ieee80211_key *); +#endif +static int8_t rt2860_rssi2dbm(struct rt2860_softc *, uint8_t, uint8_t); +static const char *rt2860_get_rf(uint8_t); +static int rt2860_read_eeprom(struct rt2860_softc *, + uint8_t macaddr[IEEE80211_ADDR_LEN]); +static int rt2860_bbp_init(struct rt2860_softc *); +static int rt2860_txrx_enable(struct rt2860_softc *); +static void rt2860_init(void *); +static void rt2860_init_locked(struct rt2860_softc *); +static void rt2860_stop(void *); +static void rt2860_stop_locked(struct rt2860_softc *); +static int rt2860_load_microcode(struct rt2860_softc *); +#ifdef NOT_YET +static void rt2860_calib(struct rt2860_softc *); +#endif +static void rt3090_set_rx_antenna(struct rt2860_softc *, int); +static void rt2860_switch_chan(struct rt2860_softc *, + struct ieee80211_channel *); +static int rt2860_setup_beacon(struct rt2860_softc *, + struct ieee80211vap *); +static void rt2860_enable_tsf_sync(struct rt2860_softc *); + +static const struct { + uint32_t reg; + uint32_t val; +} rt2860_def_mac[] = { + RT2860_DEF_MAC +}; + +static const struct { + uint8_t reg; + uint8_t val; +} rt2860_def_bbp[] = { + RT2860_DEF_BBP +}; + +static const struct rfprog { + uint8_t chan; + uint32_t r1, r2, r3, r4; +} rt2860_rf2850[] = { + RT2860_RF2850 +}; + +struct { + uint8_t n, r, k; +} rt3090_freqs[] = { + RT3070_RF3052 +}; + +static const struct { + uint8_t reg; + uint8_t val; +} rt3090_def_rf[] = { + RT3070_DEF_RF +}; + +int +rt2860_attach(device_t dev, int id) +{ + struct rt2860_softc *sc = device_get_softc(dev); + struct ieee80211com *ic; + struct ifnet *ifp; + uint32_t tmp; + int error, ntries, qid; + uint8_t bands; + uint8_t macaddr[IEEE80211_ADDR_LEN]; + + sc->sc_dev = dev; + sc->sc_debug = 0; + + ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211); + if (ifp == NULL) { + device_printf(sc->sc_dev, "can not if_alloc()\n"); + return ENOMEM; + } + ic = ifp->if_l2com; + + mtx_init(&sc->sc_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK, + MTX_DEF | MTX_RECURSE); + + callout_init_mtx(&sc->watchdog_ch, &sc->sc_mtx, 0); + + /* wait for NIC to initialize */ + for (ntries = 0; ntries < 100; ntries++) { + tmp = RAL_READ(sc, RT2860_ASIC_VER_ID); + if (tmp != 0 && tmp != 0xffffffff) + break; + DELAY(10); + } + if (ntries == 100) { + device_printf(sc->sc_dev, + "timeout waiting for NIC to initialize\n"); + error = EIO; + goto fail1; + } + sc->mac_ver = tmp >> 16; + sc->mac_rev = tmp & 0xffff; + + if (sc->mac_ver != 0x2860 && + (id == 0x0681 || id == 0x0781 || id == 0x1059)) + sc->sc_flags |= RT2860_ADVANCED_PS; + + /* retrieve RF rev. no and various other things from EEPROM */ + rt2860_read_eeprom(sc, macaddr); + if (bootverbose) { + device_printf(sc->sc_dev, "MAC/BBP RT%X (rev 0x%04X), " + "RF %s (MIMO %dT%dR), address %6D\n", + sc->mac_ver, sc->mac_rev, rt2860_get_rf(sc->rf_rev), + sc->ntxchains, sc->nrxchains, macaddr, ":"); + } + + /* + * Allocate Tx (4 EDCAs + HCCA + Mgt) and Rx rings. + */ + for (qid = 0; qid < 6; qid++) { + if ((error = rt2860_alloc_tx_ring(sc, &sc->txq[qid])) != 0) { + device_printf(sc->sc_dev, + "could not allocate Tx ring %d\n", qid); + goto fail2; + } + } + + if ((error = rt2860_alloc_rx_ring(sc, &sc->rxq)) != 0) { + device_printf(sc->sc_dev, "could not allocate Rx ring\n"); + goto fail2; + } + + if ((error = rt2860_alloc_tx_pool(sc)) != 0) { + device_printf(sc->sc_dev, "could not allocate Tx pool\n"); + goto fail3; + } + + /* mgmt ring is broken on RT2860C, use EDCA AC VO ring instead */ + sc->mgtqid = (sc->mac_ver == 0x2860 && sc->mac_rev == 0x0100) ? + WME_AC_VO : 5; + + ifp->if_softc = sc; + if_initname(ifp, device_get_name(dev), device_get_unit(dev)); + ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; + ifp->if_init = rt2860_init; + ifp->if_ioctl = rt2860_ioctl; + ifp->if_start = rt2860_start; + IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen); + ifp->if_snd.ifq_drv_maxlen = ifqmaxlen; + IFQ_SET_READY(&ifp->if_snd); + + ic->ic_ifp = ifp; + ic->ic_opmode = IEEE80211_M_STA; + ic->ic_phytype = IEEE80211_T_OFDM; /* not only, but not used */ + + /* set device capabilities */ + ic->ic_caps = + IEEE80211_C_STA /* station mode */ + | IEEE80211_C_IBSS /* ibss, nee adhoc, mode */ + | IEEE80211_C_HOSTAP /* hostap mode */ + | IEEE80211_C_MONITOR /* monitor mode */ + | IEEE80211_C_AHDEMO /* adhoc demo mode */ + | IEEE80211_C_WDS /* 4-address traffic works */ + | IEEE80211_C_MBSS /* mesh point link mode */ + | IEEE80211_C_SHPREAMBLE /* short preamble supported */ + | IEEE80211_C_SHSLOT /* short slot time supported */ + | IEEE80211_C_WPA /* capable of WPA1+WPA2 */ +#if 0 + | IEEE80211_C_BGSCAN /* capable of bg scanning */ +#endif + | IEEE80211_C_WME /* 802.11e */ + ; + + bands = 0; + setbit(&bands, IEEE80211_MODE_11B); + setbit(&bands, IEEE80211_MODE_11G); + if (sc->rf_rev == RT2860_RF_2750 || sc->rf_rev == RT2860_RF_2850) + setbit(&bands, IEEE80211_MODE_11A); + ieee80211_init_channels(ic, NULL, &bands); + + ieee80211_ifattach(ic, macaddr); + + ic->ic_wme.wme_update = rt2860_updateedca; + ic->ic_scan_start = rt2860_scan_start; + ic->ic_scan_end = rt2860_scan_end; + ic->ic_set_channel = rt2860_set_channel; + ic->ic_updateslot = rt2860_updateslot; + ic->ic_update_promisc = rt2860_update_promisc; + ic->ic_raw_xmit = rt2860_raw_xmit; + sc->sc_node_free = ic->ic_node_free; + ic->ic_node_free = rt2860_node_free; + ic->ic_newassoc = rt2860_newassoc; + + ic->ic_vap_create = rt2860_vap_create; + ic->ic_vap_delete = rt2860_vap_delete; + + ieee80211_radiotap_attach(ic, + &sc->sc_txtap.wt_ihdr, sizeof(sc->sc_txtap), + RT2860_TX_RADIOTAP_PRESENT, + &sc->sc_rxtap.wr_ihdr, sizeof(sc->sc_rxtap), + RT2860_RX_RADIOTAP_PRESENT); + +#ifdef RAL_DEBUG + SYSCTL_ADD_INT(device_get_sysctl_ctx(dev), + SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, + "debug", CTLFLAG_RW, &sc->sc_debug, 0, "debug msgs"); +#endif + if (bootverbose) + ieee80211_announce(ic); + + return 0; + +fail3: rt2860_free_rx_ring(sc, &sc->rxq); +fail2: while (--qid >= 0) + rt2860_free_tx_ring(sc, &sc->txq[qid]); +fail1: mtx_destroy(&sc->sc_mtx); + if_free(ifp); + return error; +} + +int +rt2860_detach(void *xsc) +{ + struct rt2860_softc *sc = xsc; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; + int qid; + + RAL_LOCK(sc); + rt2860_stop_locked(sc); + RAL_UNLOCK(sc); + + ieee80211_ifdetach(ic); + + for (qid = 0; qid < 6; qid++) + rt2860_free_tx_ring(sc, &sc->txq[qid]); + rt2860_free_rx_ring(sc, &sc->rxq); + rt2860_free_tx_pool(sc); + + if_free(ifp); + + mtx_destroy(&sc->sc_mtx); + + return 0; +} + +void +rt2860_shutdown(void *xsc) +{ + struct rt2860_softc *sc = xsc; + + rt2860_stop(sc); +} + +void +rt2860_suspend(void *xsc) +{ + struct rt2860_softc *sc = xsc; + + rt2860_stop(sc); +} + +void +rt2860_resume(void *xsc) +{ + struct rt2860_softc *sc = xsc; + struct ifnet *ifp = sc->sc_ifp; + + if (ifp->if_flags & IFF_UP) + rt2860_init(sc); +} + +static struct ieee80211vap * +rt2860_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit, + enum ieee80211_opmode opmode, int flags, + const uint8_t bssid[IEEE80211_ADDR_LEN], + const uint8_t mac[IEEE80211_ADDR_LEN]) +{ + struct ifnet *ifp = ic->ic_ifp; + struct rt2860_vap *rvp; + struct ieee80211vap *vap; + + switch (opmode) { + case IEEE80211_M_STA: + case IEEE80211_M_IBSS: + case IEEE80211_M_AHDEMO: + case IEEE80211_M_MONITOR: + case IEEE80211_M_HOSTAP: + case IEEE80211_M_MBSS: + /* XXXRP: TBD */ + if (!TAILQ_EMPTY(&ic->ic_vaps)) { + if_printf(ifp, "only 1 vap supported\n"); + return NULL; + } + if (opmode == IEEE80211_M_STA) + flags |= IEEE80211_CLONE_NOBEACONS; + break; + case IEEE80211_M_WDS: + if (TAILQ_EMPTY(&ic->ic_vaps) || + ic->ic_opmode != IEEE80211_M_HOSTAP) { + if_printf(ifp, "wds only supported in ap mode\n"); + return NULL; + } + /* + * Silently remove any request for a unique + * bssid; WDS vap's always share the local + * mac address. + */ + flags &= ~IEEE80211_CLONE_BSSID; + break; + default: + if_printf(ifp, "unknown opmode %d\n", opmode); + return NULL; + } + rvp = malloc(sizeof(struct rt2860_vap), M_80211_VAP, M_NOWAIT | M_ZERO); + if (rvp == NULL) + return NULL; + vap = &rvp->ral_vap; + ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid, mac); + + /* override state transition machine */ + rvp->ral_newstate = vap->iv_newstate; + vap->iv_newstate = rt2860_newstate; +#if 0 + vap->iv_update_beacon = rt2860_beacon_update; +#endif + + /* HW supports up to 255 STAs (0-254) in HostAP and IBSS modes */ + vap->iv_max_aid = min(IEEE80211_AID_MAX, RT2860_WCID_MAX); + + ieee80211_ratectl_init(vap); + /* complete setup */ + ieee80211_vap_attach(vap, ieee80211_media_change, ieee80211_media_status); + if (TAILQ_FIRST(&ic->ic_vaps) == vap) + ic->ic_opmode = opmode; + return vap; +} + +static void +rt2860_vap_delete(struct ieee80211vap *vap) +{ + struct rt2860_vap *rvp = RT2860_VAP(vap); + + ieee80211_ratectl_deinit(vap); + ieee80211_vap_detach(vap); + free(rvp, M_80211_VAP); +} + +static void +rt2860_dma_map_addr(void *arg, bus_dma_segment_t *segs, int nseg, int error) +{ + if (error != 0) + return; + + KASSERT(nseg == 1, ("too many DMA segments, %d should be 1", nseg)); + + *(bus_addr_t *)arg = segs[0].ds_addr; +} + + +static int +rt2860_alloc_tx_ring(struct rt2860_softc *sc, struct rt2860_tx_ring *ring) +{ + int size, error; + + size = RT2860_TX_RING_COUNT * sizeof (struct rt2860_txd); + + error = bus_dma_tag_create(bus_get_dma_tag(sc->sc_dev), 16, 0, + BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL, + size, 1, size, 0, NULL, NULL, &ring->desc_dmat); + if (error != 0) { + device_printf(sc->sc_dev, "could not create desc DMA map\n"); + goto fail; + } + + error = bus_dmamem_alloc(ring->desc_dmat, (void **)&ring->txd, + BUS_DMA_NOWAIT | BUS_DMA_ZERO, &ring->desc_map); + if (error != 0) { + device_printf(sc->sc_dev, "could not allocate DMA memory\n"); + goto fail; + } + + error = bus_dmamap_load(ring->desc_dmat, ring->desc_map, ring->txd, + size, rt2860_dma_map_addr, &ring->paddr, 0); + if (error != 0) { + device_printf(sc->sc_dev, "could not load desc DMA map\n"); + goto fail; + } + + bus_dmamap_sync(ring->desc_dmat, ring->desc_map, BUS_DMASYNC_PREWRITE); + + return 0; + +fail: rt2860_free_tx_ring(sc, ring); + return error; +} + +void +rt2860_reset_tx_ring(struct rt2860_softc *sc, struct rt2860_tx_ring *ring) +{ + struct rt2860_tx_data *data; + int i; + + for (i = 0; i < RT2860_TX_RING_COUNT; i++) { + if ((data = ring->data[i]) == NULL) + continue; /* nothing mapped in this slot */ + + if (data->m != NULL) { + bus_dmamap_sync(sc->txwi_dmat, data->map, + BUS_DMASYNC_POSTWRITE); + bus_dmamap_unload(sc->txwi_dmat, data->map); + m_freem(data->m); + data->m = NULL; + } + if (data->ni != NULL) { + ieee80211_free_node(data->ni); + data->ni = NULL; + } + + SLIST_INSERT_HEAD(&sc->data_pool, data, next); + ring->data[i] = NULL; + } + + ring->queued = 0; + ring->cur = ring->next = 0; +} + +void +rt2860_free_tx_ring(struct rt2860_softc *sc, struct rt2860_tx_ring *ring) +{ + struct rt2860_tx_data *data; + int i; + + if (ring->txd != NULL) { + bus_dmamap_sync(ring->desc_dmat, ring->desc_map, + BUS_DMASYNC_POSTWRITE); + bus_dmamap_unload(ring->desc_dmat, ring->desc_map); + bus_dmamem_free(ring->desc_dmat, ring->txd, ring->desc_map); + } + if (ring->desc_dmat != NULL) + bus_dma_tag_destroy(ring->desc_dmat); + + for (i = 0; i < RT2860_TX_RING_COUNT; i++) { + if ((data = ring->data[i]) == NULL) + continue; /* nothing mapped in this slot */ + + if (data->m != NULL) { + bus_dmamap_sync(sc->txwi_dmat, data->map, + BUS_DMASYNC_POSTWRITE); + bus_dmamap_unload(sc->txwi_dmat, data->map); + m_freem(data->m); + } + if (data->ni != NULL) + ieee80211_free_node(data->ni); + + SLIST_INSERT_HEAD(&sc->data_pool, data, next); + } +} + +/* + * Allocate a pool of TX Wireless Information blocks. + */ +int +rt2860_alloc_tx_pool(struct rt2860_softc *sc) +{ + caddr_t vaddr; + bus_addr_t paddr; + int i, size, error; + + size = RT2860_TX_POOL_COUNT * RT2860_TXWI_DMASZ; + + /* init data_pool early in case of failure.. */ + SLIST_INIT(&sc->data_pool); + + error = bus_dma_tag_create(bus_get_dma_tag(sc->sc_dev), 1, 0, + BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL, + size, 1, size, 0, NULL, NULL, &sc->txwi_dmat); + if (error != 0) { + device_printf(sc->sc_dev, "could not create txwi DMA tag\n"); + goto fail; + } + + error = bus_dmamem_alloc(sc->txwi_dmat, (void **)&sc->txwi_vaddr, + BUS_DMA_NOWAIT | BUS_DMA_ZERO, &sc->txwi_map); + if (error != 0) { + device_printf(sc->sc_dev, "could not allocate DMA memory\n"); + goto fail; + } + + error = bus_dmamap_load(sc->txwi_dmat, sc->txwi_map, + sc->txwi_vaddr, size, rt2860_dma_map_addr, &paddr, 0); + if (error != 0) { + device_printf(sc->sc_dev, "could not load txwi DMA map\n"); + goto fail; + } + + bus_dmamap_sync(sc->txwi_dmat, sc->txwi_map, BUS_DMASYNC_PREWRITE); + + vaddr = sc->txwi_vaddr; + for (i = 0; i < RT2860_TX_POOL_COUNT; i++) { + struct rt2860_tx_data *data = &sc->data[i]; + + error = bus_dmamap_create(sc->txwi_dmat, 0, &data->map); + if (error != 0) { + device_printf(sc->sc_dev, "could not create DMA map\n"); + goto fail; + } + data->txwi = (struct rt2860_txwi *)vaddr; + data->paddr = paddr; + vaddr += RT2860_TXWI_DMASZ; + paddr += RT2860_TXWI_DMASZ; + + SLIST_INSERT_HEAD(&sc->data_pool, data, next); + } + + return 0; + +fail: rt2860_free_tx_pool(sc); + return error; +} + +void +rt2860_free_tx_pool(struct rt2860_softc *sc) +{ + if (sc->txwi_vaddr != NULL) { + bus_dmamap_sync(sc->txwi_dmat, sc->txwi_map, + BUS_DMASYNC_POSTWRITE); + bus_dmamap_unload(sc->txwi_dmat, sc->txwi_map); + bus_dmamem_free(sc->txwi_dmat, sc->txwi_vaddr, sc->txwi_map); + } + if (sc->txwi_dmat != NULL) + bus_dma_tag_destroy(sc->txwi_dmat); + + while (!SLIST_EMPTY(&sc->data_pool)) { + struct rt2860_tx_data *data; + data = SLIST_FIRST(&sc->data_pool); + bus_dmamap_destroy(sc->txwi_dmat, data->map); + SLIST_REMOVE_HEAD(&sc->data_pool, next); + } +} + +int +rt2860_alloc_rx_ring(struct rt2860_softc *sc, struct rt2860_rx_ring *ring) +{ + bus_addr_t physaddr; + int i, size, error; + + size = RT2860_RX_RING_COUNT * sizeof (struct rt2860_rxd); + + error = bus_dma_tag_create(bus_get_dma_tag(sc->sc_dev), 16, 0, + BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL, + size, 1, size, 0, NULL, NULL, &ring->desc_dmat); + if (error != 0) { + device_printf(sc->sc_dev, "could not create desc DMA tag\n"); + goto fail; + } + + error = bus_dmamem_alloc(ring->desc_dmat, (void **)&ring->rxd, + BUS_DMA_NOWAIT | BUS_DMA_ZERO, &ring->desc_map); + if (error != 0) { + device_printf(sc->sc_dev, "could not allocate DMA memory\n"); + goto fail; + } + + error = bus_dmamap_load(ring->desc_dmat, ring->desc_map, ring->rxd, + size, rt2860_dma_map_addr, &ring->paddr, 0); + if (error != 0) { + device_printf(sc->sc_dev, "could not load desc DMA map\n"); + goto fail; + } + + error = bus_dma_tag_create(bus_get_dma_tag(sc->sc_dev), 1, 0, + BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL, MCLBYTES, + 1, MCLBYTES, 0, NULL, NULL, &ring->data_dmat); + if (error != 0) { + device_printf(sc->sc_dev, "could not create data DMA tag\n"); + goto fail; + } + + for (i = 0; i < RT2860_RX_RING_COUNT; i++) { + struct rt2860_rx_data *data = &ring->data[i]; + struct rt2860_rxd *rxd = &ring->rxd[i]; + + error = bus_dmamap_create(ring->data_dmat, 0, &data->map); + if (error != 0) { + device_printf(sc->sc_dev, "could not create DMA map\n"); + goto fail; + } + + data->m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR); + if (data->m == NULL) { + device_printf(sc->sc_dev, + "could not allocate rx mbuf\n"); + error = ENOMEM; + goto fail; + } + + error = bus_dmamap_load(ring->data_dmat, data->map, + mtod(data->m, void *), MCLBYTES, rt2860_dma_map_addr, + &physaddr, 0); + if (error != 0) { + device_printf(sc->sc_dev, + "could not load rx buf DMA map"); + goto fail; + } + + rxd->sdp0 = htole32(physaddr); + rxd->sdl0 = htole16(MCLBYTES); + } + + bus_dmamap_sync(ring->desc_dmat, ring->desc_map, BUS_DMASYNC_PREWRITE); + + return 0; + +fail: rt2860_free_rx_ring(sc, ring); + return error; +} + +void +rt2860_reset_rx_ring(struct rt2860_softc *sc, struct rt2860_rx_ring *ring) +{ + int i; + + for (i = 0; i < RT2860_RX_RING_COUNT; i++) + ring->rxd[i].sdl0 &= ~htole16(RT2860_RX_DDONE); + + bus_dmamap_sync(ring->desc_dmat, ring->desc_map, BUS_DMASYNC_PREWRITE); + + ring->cur = 0; +} + +void +rt2860_free_rx_ring(struct rt2860_softc *sc, struct rt2860_rx_ring *ring) +{ + int i; + + if (ring->rxd != NULL) { + bus_dmamap_sync(ring->desc_dmat, ring->desc_map, + BUS_DMASYNC_POSTWRITE); + bus_dmamap_unload(ring->desc_dmat, ring->desc_map); + bus_dmamem_free(ring->desc_dmat, ring->rxd, ring->desc_map); + } + if (ring->desc_dmat != NULL) + bus_dma_tag_destroy(ring->desc_dmat); + + for (i = 0; i < RT2860_RX_RING_COUNT; i++) { + struct rt2860_rx_data *data = &ring->data[i]; + + if (data->m != NULL) { + bus_dmamap_sync(ring->data_dmat, data->map, + BUS_DMASYNC_POSTREAD); + bus_dmamap_unload(ring->data_dmat, data->map); + m_freem(data->m); + } + if (data->map != NULL) + bus_dmamap_destroy(ring->data_dmat, data->map); + } + if (ring->data_dmat != NULL) + bus_dma_tag_destroy(ring->data_dmat); +} + +static void +rt2860_updatestats(struct rt2860_softc *sc) +{ + struct ieee80211com *ic = sc->sc_ifp->if_l2com; + + /* + * In IBSS or HostAP modes (when the hardware sends beacons), the + * MAC can run into a livelock and start sending CTS-to-self frames + * like crazy if protection is enabled. Fortunately, we can detect + * when such a situation occurs and reset the MAC. + */ + if (ic->ic_curmode != IEEE80211_M_STA) { + /* check if we're in a livelock situation.. */ + uint32_t tmp = RAL_READ(sc, RT2860_DEBUG); + if ((tmp & (1 << 29)) && (tmp & (1 << 7 | 1 << 5))) { + /* ..and reset MAC/BBP for a while.. */ + DPRINTF(("CTS-to-self livelock detected\n")); + RAL_WRITE(sc, RT2860_MAC_SYS_CTRL, RT2860_MAC_SRST); + RAL_BARRIER_WRITE(sc); + DELAY(1); + RAL_WRITE(sc, RT2860_MAC_SYS_CTRL, + RT2860_MAC_RX_EN | RT2860_MAC_TX_EN); + } + } +} + +static void +rt2860_newassoc(struct ieee80211_node *ni, int isnew) +{ + struct ieee80211com *ic = ni->ni_ic; + struct rt2860_softc *sc = ic->ic_ifp->if_softc; + uint8_t wcid; + + wcid = IEEE80211_AID(ni->ni_associd); + if (isnew && ni->ni_associd != 0) { + sc->wcid2ni[wcid] = ni; + + /* init WCID table entry */ + RAL_WRITE_REGION_1(sc, RT2860_WCID_ENTRY(wcid), + ni->ni_macaddr, IEEE80211_ADDR_LEN); + } + DPRINTF(("new assoc isnew=%d addr=%s WCID=%d\n", + isnew, ether_sprintf(ni->ni_macaddr), wcid)); +} + +static void +rt2860_node_free(struct ieee80211_node *ni) +{ + struct ieee80211com *ic = ni->ni_ic; + struct rt2860_softc *sc = ic->ic_ifp->if_softc; + uint8_t wcid; + + if (ni->ni_associd != 0) { + wcid = IEEE80211_AID(ni->ni_associd); + + /* clear Rx WCID search table entry */ + RAL_SET_REGION_4(sc, RT2860_WCID_ENTRY(wcid), 0, 2); + } + sc->sc_node_free(ni); +} + +#ifdef IEEE80211_HT +static int +rt2860_ampdu_rx_start(struct ieee80211com *ic, struct ieee80211_node *ni, + uint8_t tid) +{ + struct rt2860_softc *sc = ic->ic_softc; + uint8_t wcid = ((struct rt2860_node *)ni)->wcid; + uint32_t tmp; + + /* update BA session mask */ + tmp = RAL_READ(sc, RT2860_WCID_ENTRY(wcid) + 4); + tmp |= (1 << tid) << 16; + RAL_WRITE(sc, RT2860_WCID_ENTRY(wcid) + 4, tmp); + return 0; +} + +static void +rt2860_ampdu_rx_stop(struct ieee80211com *ic, struct ieee80211_node *ni, + uint8_t tid) +{ + struct rt2860_softc *sc = ic->ic_softc; + uint8_t wcid = ((struct rt2860_node *)ni)->wcid; + uint32_t tmp; + + /* update BA session mask */ + tmp = RAL_READ(sc, RT2860_WCID_ENTRY(wcid) + 4); + tmp &= ~((1 << tid) << 16); + RAL_WRITE(sc, RT2860_WCID_ENTRY(wcid) + 4, tmp); +} +#endif + +int +rt2860_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) +{ + struct rt2860_vap *rvp = RT2860_VAP(vap); + struct ieee80211com *ic = vap->iv_ic; + struct rt2860_softc *sc = ic->ic_ifp->if_softc; + uint32_t tmp; + int error; + + if (vap->iv_state == IEEE80211_S_RUN) { + /* turn link LED off */ + rt2860_set_leds(sc, RT2860_LED_RADIO); + } + + if (nstate == IEEE80211_S_INIT && vap->iv_state == IEEE80211_S_RUN) { + /* abort TSF synchronization */ + tmp = RAL_READ(sc, RT2860_BCN_TIME_CFG); + RAL_WRITE(sc, RT2860_BCN_TIME_CFG, + tmp & ~(RT2860_BCN_TX_EN | RT2860_TSF_TIMER_EN | + RT2860_TBTT_TIMER_EN)); + } + + rt2860_set_gp_timer(sc, 0); + + error = rvp->ral_newstate(vap, nstate, arg); + if (error != 0) + return (error); + + if (nstate == IEEE80211_S_RUN) { + struct ieee80211_node *ni = vap->iv_bss; + + if (ic->ic_opmode != IEEE80211_M_MONITOR) { + rt2860_enable_mrr(sc); + rt2860_set_txpreamble(sc); + rt2860_set_basicrates(sc, &ni->ni_rates); + rt2860_set_bssid(sc, ni->ni_bssid); + } + + if (vap->iv_opmode == IEEE80211_M_HOSTAP || + vap->iv_opmode == IEEE80211_M_IBSS || + vap->iv_opmode == IEEE80211_M_MBSS) { + error = rt2860_setup_beacon(sc, vap); + if (error != 0) + return error; + } + + if (ic->ic_opmode != IEEE80211_M_MONITOR) { + rt2860_enable_tsf_sync(sc); + rt2860_set_gp_timer(sc, 500); + } + + /* turn link LED on */ + rt2860_set_leds(sc, RT2860_LED_RADIO | + (IEEE80211_IS_CHAN_2GHZ(ni->ni_chan) ? + RT2860_LED_LINK_2GHZ : RT2860_LED_LINK_5GHZ)); + } + return error; +} + +/* Read 16-bit from eFUSE ROM (>=RT3071 only.) */ +static uint16_t +rt3090_efuse_read_2(struct rt2860_softc *sc, uint16_t addr) +{ + uint32_t tmp; + uint16_t reg; + int ntries; + + addr *= 2; + /*- + * Read one 16-byte block into registers EFUSE_DATA[0-3]: + * DATA0: F E D C + * DATA1: B A 9 8 + * DATA2: 7 6 5 4 + * DATA3: 3 2 1 0 + */ + tmp = RAL_READ(sc, RT3070_EFUSE_CTRL); + tmp &= ~(RT3070_EFSROM_MODE_MASK | RT3070_EFSROM_AIN_MASK); + tmp |= (addr & ~0xf) << RT3070_EFSROM_AIN_SHIFT | RT3070_EFSROM_KICK; + RAL_WRITE(sc, RT3070_EFUSE_CTRL, tmp); + for (ntries = 0; ntries < 500; ntries++) { + tmp = RAL_READ(sc, RT3070_EFUSE_CTRL); + if (!(tmp & RT3070_EFSROM_KICK)) + break; + DELAY(2); + } + if (ntries == 500) + return 0xffff; + + if ((tmp & RT3070_EFUSE_AOUT_MASK) == RT3070_EFUSE_AOUT_MASK) + return 0xffff; /* address not found */ + + /* determine to which 32-bit register our 16-bit word belongs */ + reg = RT3070_EFUSE_DATA3 - (addr & 0xc); + tmp = RAL_READ(sc, reg); + + return (addr & 2) ? tmp >> 16 : tmp & 0xffff; +} + +/* + * Read 16 bits at address 'addr' from the serial EEPROM (either 93C46, + * 93C66 or 93C86). + */ +static uint16_t +rt2860_eeprom_read_2(struct rt2860_softc *sc, uint16_t addr) +{ + uint32_t tmp; + uint16_t val; + int n; + + /* clock C once before the first command */ + RT2860_EEPROM_CTL(sc, 0); + + RT2860_EEPROM_CTL(sc, RT2860_S); + RT2860_EEPROM_CTL(sc, RT2860_S | RT2860_C); + RT2860_EEPROM_CTL(sc, RT2860_S); + + /* write start bit (1) */ + RT2860_EEPROM_CTL(sc, RT2860_S | RT2860_D); + RT2860_EEPROM_CTL(sc, RT2860_S | RT2860_D | RT2860_C); + + /* write READ opcode (10) */ + RT2860_EEPROM_CTL(sc, RT2860_S | RT2860_D); + RT2860_EEPROM_CTL(sc, RT2860_S | RT2860_D | RT2860_C); + RT2860_EEPROM_CTL(sc, RT2860_S); + RT2860_EEPROM_CTL(sc, RT2860_S | RT2860_C); + + /* write address (A5-A0 or A7-A0) */ + n = ((RAL_READ(sc, RT2860_PCI_EECTRL) & 0x30) == 0) ? 5 : 7; + for (; n >= 0; n--) { + RT2860_EEPROM_CTL(sc, RT2860_S | + (((addr >> n) & 1) << RT2860_SHIFT_D)); + RT2860_EEPROM_CTL(sc, RT2860_S | + (((addr >> n) & 1) << RT2860_SHIFT_D) | RT2860_C); + } + + RT2860_EEPROM_CTL(sc, RT2860_S); + + /* read data Q15-Q0 */ + val = 0; + for (n = 15; n >= 0; n--) { + RT2860_EEPROM_CTL(sc, RT2860_S | RT2860_C); + tmp = RAL_READ(sc, RT2860_PCI_EECTRL); + val |= ((tmp & RT2860_Q) >> RT2860_SHIFT_Q) << n; + RT2860_EEPROM_CTL(sc, RT2860_S); + } + + RT2860_EEPROM_CTL(sc, 0); + + /* clear Chip Select and clock C */ + RT2860_EEPROM_CTL(sc, RT2860_S); + RT2860_EEPROM_CTL(sc, 0); + RT2860_EEPROM_CTL(sc, RT2860_C); + + return val; +} + +static __inline uint16_t +rt2860_srom_read(struct rt2860_softc *sc, uint8_t addr) +{ + /* either eFUSE ROM or EEPROM */ + return sc->sc_srom_read(sc, addr); +} + +static void +rt2860_intr_coherent(struct rt2860_softc *sc) +{ + uint32_t tmp; + + /* DMA finds data coherent event when checking the DDONE bit */ + + DPRINTF(("Tx/Rx Coherent interrupt\n")); + + /* restart DMA engine */ + tmp = RAL_READ(sc, RT2860_WPDMA_GLO_CFG); + tmp &= ~(RT2860_TX_WB_DDONE | RT2860_RX_DMA_EN | RT2860_TX_DMA_EN); + RAL_WRITE(sc, RT2860_WPDMA_GLO_CFG, tmp); + + (void)rt2860_txrx_enable(sc); +} + +static void +rt2860_drain_stats_fifo(struct rt2860_softc *sc) +{ + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211_node *ni; + uint32_t stat; + int retrycnt; + uint8_t wcid, mcs, pid; + + /* drain Tx status FIFO (maxsize = 16) */ + while ((stat = RAL_READ(sc, RT2860_TX_STAT_FIFO)) & RT2860_TXQ_VLD) { + DPRINTFN(4, ("tx stat 0x%08x\n", stat)); + + wcid = (stat >> RT2860_TXQ_WCID_SHIFT) & 0xff; + ni = sc->wcid2ni[wcid]; + + /* if no ACK was requested, no feedback is available */ + if (!(stat & RT2860_TXQ_ACKREQ) || wcid == 0xff || ni == NULL) + continue; + + /* update per-STA AMRR stats */ + if (stat & RT2860_TXQ_OK) { + /* + * Check if there were retries, ie if the Tx success + * rate is different from the requested rate. Note + * that it works only because we do not allow rate + * fallback from OFDM to CCK. + */ + mcs = (stat >> RT2860_TXQ_MCS_SHIFT) & 0x7f; + pid = (stat >> RT2860_TXQ_PID_SHIFT) & 0xf; + if (mcs + 1 != pid) + retrycnt = 1; + else + retrycnt = 0; + ieee80211_ratectl_tx_complete(ni->ni_vap, ni, + IEEE80211_RATECTL_TX_SUCCESS, &retrycnt, NULL); + } else { + ieee80211_ratectl_tx_complete(ni->ni_vap, ni, + IEEE80211_RATECTL_TX_FAILURE, &retrycnt, NULL); + ifp->if_oerrors++; + } + } +} + +static void +rt2860_tx_intr(struct rt2860_softc *sc, int qid) +{ + struct ifnet *ifp = sc->sc_ifp; + struct rt2860_tx_ring *ring = &sc->txq[qid]; + uint32_t hw; + + rt2860_drain_stats_fifo(sc); + + hw = RAL_READ(sc, RT2860_TX_DTX_IDX(qid)); + while (ring->next != hw) { + struct rt2860_tx_data *data = ring->data[ring->next]; + + if (data != NULL) { + bus_dmamap_sync(sc->txwi_dmat, data->map, + BUS_DMASYNC_POSTWRITE); + bus_dmamap_unload(sc->txwi_dmat, data->map); + if (data->m->m_flags & M_TXCB) { + ieee80211_process_callback(data->ni, data->m, + 0); + } + m_freem(data->m); + ieee80211_free_node(data->ni); + data->m = NULL; + data->ni = NULL; + + SLIST_INSERT_HEAD(&sc->data_pool, data, next); + ring->data[ring->next] = NULL; + + ifp->if_opackets++; + } + ring->queued--; + ring->next = (ring->next + 1) % RT2860_TX_RING_COUNT; + } + + sc->sc_tx_timer = 0; + if (ring->queued < RT2860_TX_RING_COUNT) + sc->qfullmsk &= ~(1 << qid); + ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; + rt2860_start_locked(ifp); +} + +/* + * Return the Rx chain with the highest RSSI for a given frame. + */ +static __inline uint8_t +rt2860_maxrssi_chain(struct rt2860_softc *sc, const struct rt2860_rxwi *rxwi) +{ + uint8_t rxchain = 0; + + if (sc->nrxchains > 1) { + if (rxwi->rssi[1] > rxwi->rssi[rxchain]) + rxchain = 1; + if (sc->nrxchains > 2) + if (rxwi->rssi[2] > rxwi->rssi[rxchain]) + rxchain = 2; + } + return rxchain; +} + +static void +rt2860_rx_intr(struct rt2860_softc *sc) +{ + struct rt2860_rx_radiotap_header *tap; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211_frame *wh; + struct ieee80211_node *ni; + struct mbuf *m, *m1; + bus_addr_t physaddr; + uint32_t hw; + uint16_t phy; + uint8_t ant; + int8_t rssi, nf; + int error; + + hw = RAL_READ(sc, RT2860_FS_DRX_IDX) & 0xfff; + while (sc->rxq.cur != hw) { + struct rt2860_rx_data *data = &sc->rxq.data[sc->rxq.cur]; + struct rt2860_rxd *rxd = &sc->rxq.rxd[sc->rxq.cur]; + struct rt2860_rxwi *rxwi; + + bus_dmamap_sync(sc->rxq.desc_dmat, sc->rxq.desc_map, + BUS_DMASYNC_POSTREAD); + + if (__predict_false(!(rxd->sdl0 & htole16(RT2860_RX_DDONE)))) { + DPRINTF(("RXD DDONE bit not set!\n")); + break; /* should not happen */ + } + + if (__predict_false(rxd->flags & + htole32(RT2860_RX_CRCERR | RT2860_RX_ICVERR))) { + ifp->if_ierrors++; + goto skip; + } + +#ifdef HW_CRYPTO + if (__predict_false(rxd->flags & htole32(RT2860_RX_MICERR))) { + /* report MIC failures to net80211 for TKIP */ + ic->ic_stats.is_rx_locmicfail++; + ieee80211_michael_mic_failure(ic, 0/* XXX */); + ifp->if_ierrors++; + goto skip; + } +#endif + + m1 = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR); + if (__predict_false(m1 == NULL)) { + ifp->if_ierrors++; + goto skip; + } + + bus_dmamap_sync(sc->rxq.data_dmat, data->map, + BUS_DMASYNC_POSTREAD); + bus_dmamap_unload(sc->rxq.data_dmat, data->map); + + error = bus_dmamap_load(sc->rxq.data_dmat, data->map, + mtod(m1, void *), MCLBYTES, rt2860_dma_map_addr, + &physaddr, 0); + if (__predict_false(error != 0)) { + m_freem(m1); + + /* try to reload the old mbuf */ + error = bus_dmamap_load(sc->rxq.data_dmat, data->map, + mtod(data->m, void *), MCLBYTES, + rt2860_dma_map_addr, &physaddr, 0); + if (__predict_false(error != 0)) { + panic("%s: could not load old rx mbuf", + device_get_name(sc->sc_dev)); + } + /* physical address may have changed */ + rxd->sdp0 = htole32(physaddr); + ifp->if_ierrors++; + goto skip; + } + + /* + * New mbuf successfully loaded, update Rx ring and continue + * processing. + */ + m = data->m; + data->m = m1; + rxd->sdp0 = htole32(physaddr); + + rxwi = mtod(m, struct rt2860_rxwi *); + + /* finalize mbuf */ + m->m_pkthdr.rcvif = ifp; + m->m_data = (caddr_t)(rxwi + 1); + m->m_pkthdr.len = m->m_len = le16toh(rxwi->len) & 0xfff; + + wh = mtod(m, struct ieee80211_frame *); +#ifdef HW_CRYPTO + if (wh->i_fc[1] & IEEE80211_FC1_WEP) { + /* frame is decrypted by hardware */ + wh->i_fc[1] &= ~IEEE80211_FC1_WEP; + } +#endif + + /* HW may insert 2 padding bytes after 802.11 header */ + if (rxd->flags & htole32(RT2860_RX_L2PAD)) { + u_int hdrlen = ieee80211_hdrsize(wh); + ovbcopy(wh, (caddr_t)wh + 2, hdrlen); + m->m_data += 2; + wh = mtod(m, struct ieee80211_frame *); + } + + ant = rt2860_maxrssi_chain(sc, rxwi); + rssi = rt2860_rssi2dbm(sc, rxwi->rssi[ant], ant); + nf = RT2860_NOISE_FLOOR; + + if (ieee80211_radiotap_active(ic)) { + tap = &sc->sc_rxtap; + tap->wr_flags = 0; + tap->wr_antenna = ant; + tap->wr_antsignal = nf + rssi; + tap->wr_antnoise = nf; + /* in case it can't be found below */ + tap->wr_rate = 2; + phy = le16toh(rxwi->phy); + switch (phy & RT2860_PHY_MODE) { + case RT2860_PHY_CCK: + switch ((phy & RT2860_PHY_MCS) & ~RT2860_PHY_SHPRE) { + case 0: tap->wr_rate = 2; break; + case 1: tap->wr_rate = 4; break; + case 2: tap->wr_rate = 11; break; + case 3: tap->wr_rate = 22; break; + } + if (phy & RT2860_PHY_SHPRE) + tap->wr_flags |= IEEE80211_RADIOTAP_F_SHORTPRE; + break; + case RT2860_PHY_OFDM: + switch (phy & RT2860_PHY_MCS) { + case 0: tap->wr_rate = 12; break; + case 1: tap->wr_rate = 18; break; + case 2: tap->wr_rate = 24; break; + case 3: tap->wr_rate = 36; break; + case 4: tap->wr_rate = 48; break; + case 5: tap->wr_rate = 72; break; + case 6: tap->wr_rate = 96; break; + case 7: tap->wr_rate = 108; break; + } + break; + } + } + + RAL_UNLOCK(sc); + wh = mtod(m, struct ieee80211_frame *); + + /* send the frame to the 802.11 layer */ + ni = ieee80211_find_rxnode(ic, + (struct ieee80211_frame_min *)wh); + if (ni != NULL) { + (void)ieee80211_input(ni, m, rssi - nf, nf); + ieee80211_free_node(ni); + } else + (void)ieee80211_input_all(ic, m, rssi - nf, nf); + + RAL_LOCK(sc); + +skip: rxd->sdl0 &= ~htole16(RT2860_RX_DDONE); + + bus_dmamap_sync(sc->rxq.desc_dmat, sc->rxq.desc_map, + BUS_DMASYNC_PREWRITE); + + sc->rxq.cur = (sc->rxq.cur + 1) % RT2860_RX_RING_COUNT; + } + + /* tell HW what we have processed */ + RAL_WRITE(sc, RT2860_RX_CALC_IDX, + (sc->rxq.cur - 1) % RT2860_RX_RING_COUNT); +} + +static void +rt2860_tbtt_intr(struct rt2860_softc *sc) +{ +#if 0 + struct ieee80211com *ic = &sc->sc_ic; + +#ifndef IEEE80211_STA_ONLY + if (ic->ic_opmode == IEEE80211_M_HOSTAP) { + /* one less beacon until next DTIM */ + if (ic->ic_dtim_count == 0) + ic->ic_dtim_count = ic->ic_dtim_period - 1; + else + ic->ic_dtim_count--; + + /* update dynamic parts of beacon */ + rt2860_setup_beacon(sc); + + /* flush buffered multicast frames */ + if (ic->ic_dtim_count == 0) + ieee80211_notify_dtim(ic); + } +#endif + /* check if protection mode has changed */ + if ((sc->sc_ic_flags ^ ic->ic_flags) & IEEE80211_F_USEPROT) { + rt2860_updateprot(ic); + sc->sc_ic_flags = ic->ic_flags; + } +#endif +} + +static void +rt2860_gp_intr(struct rt2860_softc *sc) +{ + struct ieee80211com *ic = sc->sc_ifp->if_l2com; + struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); + + DPRINTFN(2, ("GP timeout state=%d\n", vap->iv_state)); + + if (vap->iv_state == IEEE80211_S_RUN) + rt2860_updatestats(sc); +} + +void +rt2860_intr(void *arg) +{ + struct rt2860_softc *sc = arg; + uint32_t r; + + RAL_LOCK(sc); + + r = RAL_READ(sc, RT2860_INT_STATUS); + if (__predict_false(r == 0xffffffff)) { + RAL_UNLOCK(sc); + return; /* device likely went away */ + } + if (r == 0) { + RAL_UNLOCK(sc); + return; /* not for us */ + } + + /* acknowledge interrupts */ + RAL_WRITE(sc, RT2860_INT_STATUS, r); + + if (r & RT2860_TX_RX_COHERENT) + rt2860_intr_coherent(sc); + + if (r & RT2860_MAC_INT_2) /* TX status */ + rt2860_drain_stats_fifo(sc); + + if (r & RT2860_TX_DONE_INT5) + rt2860_tx_intr(sc, 5); + + if (r & RT2860_RX_DONE_INT) + rt2860_rx_intr(sc); + + if (r & RT2860_TX_DONE_INT4) + rt2860_tx_intr(sc, 4); + + if (r & RT2860_TX_DONE_INT3) + rt2860_tx_intr(sc, 3); + + if (r & RT2860_TX_DONE_INT2) + rt2860_tx_intr(sc, 2); + + if (r & RT2860_TX_DONE_INT1) + rt2860_tx_intr(sc, 1); + + if (r & RT2860_TX_DONE_INT0) + rt2860_tx_intr(sc, 0); + + if (r & RT2860_MAC_INT_0) /* TBTT */ + rt2860_tbtt_intr(sc); + + if (r & RT2860_MAC_INT_3) /* Auto wakeup */ + /* TBD wakeup */; + + if (r & RT2860_MAC_INT_4) /* GP timer */ + rt2860_gp_intr(sc); + + RAL_UNLOCK(sc); +} + +static int +rt2860_tx(struct rt2860_softc *sc, struct mbuf *m, struct ieee80211_node *ni) +{ + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211vap *vap = ni->ni_vap; + struct rt2860_tx_ring *ring; + struct rt2860_tx_data *data; + struct rt2860_txd *txd; + struct rt2860_txwi *txwi; + struct ieee80211_frame *wh; + const struct ieee80211_txparam *tp; + struct ieee80211_key *k; + struct mbuf *m1; + bus_dma_segment_t segs[RT2860_MAX_SCATTER]; + bus_dma_segment_t *seg; + u_int hdrlen; + uint16_t qos, dur; + uint8_t type, qsel, mcs, pid, tid, qid; + int i, nsegs, ntxds, pad, rate, ridx, error; + + /* the data pool contains at least one element, pick the first */ + data = SLIST_FIRST(&sc->data_pool); + + wh = mtod(m, struct ieee80211_frame *); + + if (wh->i_fc[1] & IEEE80211_FC1_WEP) { + k = ieee80211_crypto_encap(ni, m); + if (k == NULL) { + m_freem(m); + return ENOBUFS; + } + + /* packet header may have moved, reset our local pointer */ + wh = mtod(m, struct ieee80211_frame *); + } + + hdrlen = ieee80211_anyhdrsize(wh); + type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK; + + tp = &vap->iv_txparms[ieee80211_chan2mode(ni->ni_chan)]; + if (IEEE80211_IS_MULTICAST(wh->i_addr1)) { + rate = tp->mcastrate; + } else if (m->m_flags & M_EAPOL) { + rate = tp->mgmtrate; + } else if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE) { + rate = tp->ucastrate; + } else { + (void) ieee80211_ratectl_rate(ni, NULL, 0); + rate = ni->ni_txrate; + } + rate &= IEEE80211_RATE_VAL; + + qid = M_WME_GETAC(m); + if (IEEE80211_QOS_HAS_SEQ(wh)) { + qos = ((const struct ieee80211_qosframe *)wh)->i_qos[0]; + tid = qos & IEEE80211_QOS_TID; + } else { + qos = 0; + tid = 0; + } + ring = &sc->txq[qid]; + ridx = ic->ic_rt->rateCodeToIndex[rate]; + + /* get MCS code from rate index */ + mcs = rt2860_rates[ridx].mcs; + + /* setup TX Wireless Information */ + txwi = data->txwi; + txwi->flags = 0; + /* let HW generate seq numbers for non-QoS frames */ + txwi->xflags = qos ? 0 : RT2860_TX_NSEQ; + if (type == IEEE80211_FC0_TYPE_DATA) + txwi->wcid = IEEE80211_AID(ni->ni_associd); + else + txwi->wcid = 0xff; + txwi->len = htole16(m->m_pkthdr.len); + if (rt2860_rates[ridx].phy == IEEE80211_T_DS) { + txwi->phy = htole16(RT2860_PHY_CCK); + if (ridx != RT2860_RIDX_CCK1 && + (ic->ic_flags & IEEE80211_F_SHPREAMBLE)) + mcs |= RT2860_PHY_SHPRE; + } else + txwi->phy = htole16(RT2860_PHY_OFDM); + txwi->phy |= htole16(mcs); + + /* + * We store the MCS code into the driver-private PacketID field. + * The PacketID is latched into TX_STAT_FIFO when Tx completes so + * that we know at which initial rate the frame was transmitted. + * We add 1 to the MCS code because setting the PacketID field to + * 0 means that we don't want feedback in TX_STAT_FIFO. + */ + pid = (mcs + 1) & 0xf; + txwi->len |= htole16(pid << RT2860_TX_PID_SHIFT); + + /* check if RTS/CTS or CTS-to-self protection is required */ + if (!IEEE80211_IS_MULTICAST(wh->i_addr1) && + (m->m_pkthdr.len + IEEE80211_CRC_LEN > vap->iv_rtsthreshold || + ((ic->ic_flags & IEEE80211_F_USEPROT) && + rt2860_rates[ridx].phy == IEEE80211_T_OFDM))) + txwi->txop = RT2860_TX_TXOP_HT; + else + txwi->txop = RT2860_TX_TXOP_BACKOFF; + + if (!IEEE80211_IS_MULTICAST(wh->i_addr1) && + (!qos || (qos & IEEE80211_QOS_ACKPOLICY) != + IEEE80211_QOS_ACKPOLICY_NOACK)) { + txwi->xflags |= RT2860_TX_ACK; + + if (ic->ic_flags & IEEE80211_F_SHPREAMBLE) + dur = rt2860_rates[ridx].sp_ack_dur; + else + dur = rt2860_rates[ridx].lp_ack_dur; + *(uint16_t *)wh->i_dur = htole16(dur); + } + /* ask MAC to insert timestamp into probe responses */ + if ((wh->i_fc[0] & + (IEEE80211_FC0_TYPE_MASK | IEEE80211_FC0_SUBTYPE_MASK)) == + (IEEE80211_FC0_TYPE_MGT | IEEE80211_FC0_SUBTYPE_PROBE_RESP)) + /* NOTE: beacons do not pass through tx_data() */ + txwi->flags |= RT2860_TX_TS; + + if (ieee80211_radiotap_active_vap(vap)) { + struct rt2860_tx_radiotap_header *tap = &sc->sc_txtap; + + tap->wt_flags = 0; + tap->wt_rate = rate; + if (mcs & RT2860_PHY_SHPRE) + tap->wt_flags |= IEEE80211_RADIOTAP_F_SHORTPRE; + + ieee80211_radiotap_tx(vap, m); + } + + pad = (hdrlen + 3) & ~3; + + /* copy and trim 802.11 header */ + memcpy(txwi + 1, wh, hdrlen); + m_adj(m, hdrlen); + + error = bus_dmamap_load_mbuf_sg(sc->txwi_dmat, data->map, m, segs, + &nsegs, 0); + if (__predict_false(error != 0 && error != EFBIG)) { + device_printf(sc->sc_dev, "can't map mbuf (error %d)\n", + error); + m_freem(m); + return error; + } + if (__predict_true(error == 0)) { + /* determine how many TXDs are required */ + ntxds = 1 + (nsegs / 2); + + if (ring->queued + ntxds >= RT2860_TX_RING_COUNT) { + /* not enough free TXDs, force mbuf defrag */ + bus_dmamap_unload(sc->txwi_dmat, data->map); + error = EFBIG; + } + } + if (__predict_false(error != 0)) { + m1 = m_defrag(m, M_DONTWAIT); + if (m1 == NULL) { + device_printf(sc->sc_dev, + "could not defragment mbuf\n"); + m_freem(m); + return ENOBUFS; + } + m = m1; + + error = bus_dmamap_load_mbuf_sg(sc->txwi_dmat, data->map, m, + segs, &nsegs, 0); + if (__predict_false(error != 0)) { + device_printf(sc->sc_dev, "can't map mbuf (error %d)\n", + error); + m_freem(m); + return error; + } + + /* determine how many TXDs are now required */ + ntxds = 1 + (nsegs / 2); + + if (ring->queued + ntxds >= RT2860_TX_RING_COUNT) { + /* this is a hopeless case, drop the mbuf! */ + bus_dmamap_unload(sc->txwi_dmat, data->map); + m_freem(m); + return ENOBUFS; + } + } + + qsel = (qid < WME_NUM_AC) ? RT2860_TX_QSEL_EDCA : RT2860_TX_QSEL_MGMT; + + /* first segment is TXWI + 802.11 header */ + txd = &ring->txd[ring->cur]; + txd->sdp0 = htole32(data->paddr); + txd->sdl0 = htole16(sizeof (struct rt2860_txwi) + pad); + txd->flags = qsel; + + /* setup payload segments */ + seg = &segs[0]; + for (i = nsegs; i >= 2; i -= 2) { + txd->sdp1 = htole32(seg->ds_addr); + txd->sdl1 = htole16(seg->ds_len); + seg++; + ring->cur = (ring->cur + 1) % RT2860_TX_RING_COUNT; + /* grab a new Tx descriptor */ + txd = &ring->txd[ring->cur]; + txd->sdp0 = htole32(seg->ds_addr); + txd->sdl0 = htole16(seg->ds_len); + txd->flags = qsel; + seg++; + } + /* finalize last segment */ + if (i > 0) { + txd->sdp1 = htole32(seg->ds_addr); + txd->sdl1 = htole16(seg->ds_len | RT2860_TX_LS1); + } else { + txd->sdl0 |= htole16(RT2860_TX_LS0); + txd->sdl1 = 0; + } + + /* remove from the free pool and link it into the SW Tx slot */ + SLIST_REMOVE_HEAD(&sc->data_pool, next); + data->m = m; + data->ni = ni; + ring->data[ring->cur] = data; + + bus_dmamap_sync(sc->txwi_dmat, sc->txwi_map, BUS_DMASYNC_PREWRITE); + bus_dmamap_sync(sc->txwi_dmat, data->map, BUS_DMASYNC_PREWRITE); + bus_dmamap_sync(ring->desc_dmat, ring->desc_map, BUS_DMASYNC_PREWRITE); + + DPRINTFN(4, ("sending frame qid=%d wcid=%d nsegs=%d ridx=%d\n", + qid, txwi->wcid, nsegs, ridx)); + + ring->cur = (ring->cur + 1) % RT2860_TX_RING_COUNT; + ring->queued += ntxds; + if (ring->queued >= RT2860_TX_RING_COUNT) + sc->qfullmsk |= 1 << qid; + + /* kick Tx */ + RAL_WRITE(sc, RT2860_TX_CTX_IDX(qid), ring->cur); + + return 0; +} + +static int +rt2860_raw_xmit(struct ieee80211_node *ni, struct mbuf *m, + const struct ieee80211_bpf_params *params) +{ + struct ieee80211com *ic = ni->ni_ic; + struct ifnet *ifp = ic->ic_ifp; + struct rt2860_softc *sc = ifp->if_softc; + int error; + + RAL_LOCK(sc); + + /* prevent management frames from being sent if we're not ready */ + if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) { + RAL_UNLOCK(sc); + m_freem(m); + ieee80211_free_node(ni); + return ENETDOWN; + } + if (params == NULL) { + /* + * Legacy path; interpret frame contents to decide + * precisely how to send the frame. + */ + error = rt2860_tx(sc, m, ni); + } else { + /* + * Caller supplied explicit parameters to use in + * sending the frame. + */ + error = rt2860_tx_raw(sc, m, ni, params); + } + if (error != 0) { + /* NB: m is reclaimed on tx failure */ + ieee80211_free_node(ni); + ifp->if_oerrors++; + } + sc->sc_tx_timer = 5; + RAL_UNLOCK(sc); + return error; +} + +static int +rt2860_tx_raw(struct rt2860_softc *sc, struct mbuf *m, + struct ieee80211_node *ni, const struct ieee80211_bpf_params *params) +{ + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211vap *vap = ni->ni_vap; + struct rt2860_tx_ring *ring; + struct rt2860_tx_data *data; + struct rt2860_txd *txd; + struct rt2860_txwi *txwi; + struct ieee80211_frame *wh; + struct mbuf *m1; + bus_dma_segment_t segs[RT2860_MAX_SCATTER]; + bus_dma_segment_t *seg; + u_int hdrlen; + uint16_t dur; + uint8_t type, qsel, mcs, pid, tid, qid; + int i, nsegs, ntxds, pad, rate, ridx, error; + + /* the data pool contains at least one element, pick the first */ + data = SLIST_FIRST(&sc->data_pool); + + wh = mtod(m, struct ieee80211_frame *); + hdrlen = ieee80211_hdrsize(wh); + type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK; + + /* Choose a TX rate index. */ + rate = params->ibp_rate0; + ridx = ic->ic_rt->rateCodeToIndex[rate]; + if (ridx == (uint8_t)-1) { + /* XXX fall back to mcast/mgmt rate? */ + m_freem(m); + return EINVAL; + } + + qid = params->ibp_pri & 3; + tid = 0; + ring = &sc->txq[qid]; + + /* get MCS code from rate index */ + mcs = rt2860_rates[ridx].mcs; + + /* setup TX Wireless Information */ + txwi = data->txwi; + txwi->flags = 0; + /* let HW generate seq numbers for non-QoS frames */ + txwi->xflags = params->ibp_pri & 3 ? 0 : RT2860_TX_NSEQ; + txwi->wcid = 0xff; + txwi->len = htole16(m->m_pkthdr.len); + if (rt2860_rates[ridx].phy == IEEE80211_T_DS) { + txwi->phy = htole16(RT2860_PHY_CCK); + if (ridx != RT2860_RIDX_CCK1 && + (ic->ic_flags & IEEE80211_F_SHPREAMBLE)) + mcs |= RT2860_PHY_SHPRE; + } else + txwi->phy = htole16(RT2860_PHY_OFDM); + txwi->phy |= htole16(mcs); + + /* + * We store the MCS code into the driver-private PacketID field. + * The PacketID is latched into TX_STAT_FIFO when Tx completes so + * that we know at which initial rate the frame was transmitted. + * We add 1 to the MCS code because setting the PacketID field to + * 0 means that we don't want feedback in TX_STAT_FIFO. + */ + pid = (mcs + 1) & 0xf; + txwi->len |= htole16(pid << RT2860_TX_PID_SHIFT); + + /* check if RTS/CTS or CTS-to-self protection is required */ + if (params->ibp_flags & IEEE80211_BPF_RTS || + params->ibp_flags & IEEE80211_BPF_CTS) + txwi->txop = RT2860_TX_TXOP_HT; + else + txwi->txop = RT2860_TX_TXOP_BACKOFF; + if ((params->ibp_flags & IEEE80211_BPF_NOACK) == 0) { + txwi->xflags |= RT2860_TX_ACK; + + if (ic->ic_flags & IEEE80211_F_SHPREAMBLE) + dur = rt2860_rates[ridx].sp_ack_dur; + else + dur = rt2860_rates[ridx].lp_ack_dur; + *(uint16_t *)wh->i_dur = htole16(dur); + } + /* ask MAC to insert timestamp into probe responses */ + if ((wh->i_fc[0] & + (IEEE80211_FC0_TYPE_MASK | IEEE80211_FC0_SUBTYPE_MASK)) == + (IEEE80211_FC0_TYPE_MGT | IEEE80211_FC0_SUBTYPE_PROBE_RESP)) + /* NOTE: beacons do not pass through tx_data() */ + txwi->flags |= RT2860_TX_TS; + + if (ieee80211_radiotap_active_vap(vap)) { + struct rt2860_tx_radiotap_header *tap = &sc->sc_txtap; + + tap->wt_flags = 0; + tap->wt_rate = rate; + if (mcs & RT2860_PHY_SHPRE) + tap->wt_flags |= IEEE80211_RADIOTAP_F_SHORTPRE; + + ieee80211_radiotap_tx(vap, m); + } + + pad = (hdrlen + 3) & ~3; + + /* copy and trim 802.11 header */ + memcpy(txwi + 1, wh, hdrlen); + m_adj(m, hdrlen); + + error = bus_dmamap_load_mbuf_sg(sc->txwi_dmat, data->map, m, segs, + &nsegs, 0); + if (__predict_false(error != 0 && error != EFBIG)) { + device_printf(sc->sc_dev, "can't map mbuf (error %d)\n", + error); + m_freem(m); + return error; + } + if (__predict_true(error == 0)) { + /* determine how many TXDs are required */ + ntxds = 1 + (nsegs / 2); + + if (ring->queued + ntxds >= RT2860_TX_RING_COUNT) { + /* not enough free TXDs, force mbuf defrag */ + bus_dmamap_unload(sc->txwi_dmat, data->map); + error = EFBIG; + } + } + if (__predict_false(error != 0)) { + m1 = m_defrag(m, M_DONTWAIT); + if (m1 == NULL) { + device_printf(sc->sc_dev, + "could not defragment mbuf\n"); + m_freem(m); + return ENOBUFS; + } + m = m1; + + error = bus_dmamap_load_mbuf_sg(sc->txwi_dmat, data->map, m, + segs, &nsegs, 0); + if (__predict_false(error != 0)) { + device_printf(sc->sc_dev, "can't map mbuf (error %d)\n", + error); + m_freem(m); + return error; + } + + /* determine how many TXDs are now required */ + ntxds = 1 + (nsegs / 2); + + if (ring->queued + ntxds >= RT2860_TX_RING_COUNT) { + /* this is a hopeless case, drop the mbuf! */ + bus_dmamap_unload(sc->txwi_dmat, data->map); + m_freem(m); + return ENOBUFS; + } + } + + qsel = (qid < WME_NUM_AC) ? RT2860_TX_QSEL_EDCA : RT2860_TX_QSEL_MGMT; + + /* first segment is TXWI + 802.11 header */ + txd = &ring->txd[ring->cur]; + txd->sdp0 = htole32(data->paddr); + txd->sdl0 = htole16(sizeof (struct rt2860_txwi) + pad); + txd->flags = qsel; + + /* setup payload segments */ + seg = &segs[0]; + for (i = nsegs; i >= 2; i -= 2) { + txd->sdp1 = htole32(seg->ds_addr); + txd->sdl1 = htole16(seg->ds_len); + seg++; + ring->cur = (ring->cur + 1) % RT2860_TX_RING_COUNT; + /* grab a new Tx descriptor */ + txd = &ring->txd[ring->cur]; + txd->sdp0 = htole32(seg->ds_addr); + txd->sdl0 = htole16(seg->ds_len); + txd->flags = qsel; + seg++; + } + /* finalize last segment */ + if (i > 0) { + txd->sdp1 = htole32(seg->ds_addr); + txd->sdl1 = htole16(seg->ds_len | RT2860_TX_LS1); + } else { + txd->sdl0 |= htole16(RT2860_TX_LS0); + txd->sdl1 = 0; + } + + /* remove from the free pool and link it into the SW Tx slot */ + SLIST_REMOVE_HEAD(&sc->data_pool, next); + data->m = m; + data->ni = ni; + ring->data[ring->cur] = data; + + bus_dmamap_sync(sc->txwi_dmat, sc->txwi_map, BUS_DMASYNC_PREWRITE); + bus_dmamap_sync(sc->txwi_dmat, data->map, BUS_DMASYNC_PREWRITE); + bus_dmamap_sync(ring->desc_dmat, ring->desc_map, BUS_DMASYNC_PREWRITE); + + DPRINTFN(4, ("sending frame qid=%d wcid=%d nsegs=%d ridx=%d\n", + qid, txwi->wcid, nsegs, ridx)); + + ring->cur = (ring->cur + 1) % RT2860_TX_RING_COUNT; + ring->queued += ntxds; + if (ring->queued >= RT2860_TX_RING_COUNT) + sc->qfullmsk |= 1 << qid; + + /* kick Tx */ + RAL_WRITE(sc, RT2860_TX_CTX_IDX(qid), ring->cur); + + return 0; +} + +static void +rt2860_start(struct ifnet *ifp) +{ + struct rt2860_softc *sc = ifp->if_softc; + + RAL_LOCK(sc); + rt2860_start_locked(ifp); + RAL_UNLOCK(sc); +} + +static void +rt2860_start_locked(struct ifnet *ifp) +{ + struct rt2860_softc *sc = ifp->if_softc; + struct ieee80211_node *ni; + struct mbuf *m; + + RAL_LOCK_ASSERT(sc); + + if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0 || + (ifp->if_drv_flags & IFF_DRV_OACTIVE)) + return; + + for (;;) { + if (SLIST_EMPTY(&sc->data_pool) || sc->qfullmsk != 0) { + ifp->if_drv_flags |= IFF_DRV_OACTIVE; + break; + } + IFQ_DRV_DEQUEUE(&ifp->if_snd, m); + if (m == NULL) + break; + ni = (struct ieee80211_node *)m->m_pkthdr.rcvif; + if (rt2860_tx(sc, m, ni) != 0) { + ieee80211_free_node(ni); + ifp->if_oerrors++; + continue; + } + sc->sc_tx_timer = 5; + } +} + +static void +rt2860_watchdog(void *arg) +{ + struct rt2860_softc *sc = arg; + struct ifnet *ifp = sc->sc_ifp; + + RAL_LOCK_ASSERT(sc); + + KASSERT(ifp->if_drv_flags & IFF_DRV_RUNNING, ("not running")); + + if (sc->sc_invalid) /* card ejected */ + return; + + if (sc->sc_tx_timer > 0 && --sc->sc_tx_timer == 0) { + if_printf(ifp, "device timeout\n"); + rt2860_stop_locked(sc); + rt2860_init_locked(sc); + ifp->if_oerrors++; + return; + } + callout_reset(&sc->watchdog_ch, hz, rt2860_watchdog, sc); +} + +static int +rt2860_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) +{ + struct rt2860_softc *sc = ifp->if_softc; + struct ieee80211com *ic = ifp->if_l2com; + struct ifreq *ifr = (struct ifreq *)data; + int error = 0, startall = 0; + + switch (cmd) { + case SIOCSIFFLAGS: + RAL_LOCK(sc); + if (ifp->if_flags & IFF_UP) { + if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) { + rt2860_init_locked(sc); + startall = 1; + } else + rt2860_update_promisc(ifp); + } else { + if (ifp->if_drv_flags & IFF_DRV_RUNNING) + rt2860_stop_locked(sc); + } + RAL_UNLOCK(sc); + if (startall) + ieee80211_start_all(ic); + break; + case SIOCGIFMEDIA: + error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd); + break; + case SIOCSIFADDR: + error = ether_ioctl(ifp, cmd, data); + break; + default: + error = EINVAL; + break; + } + return error; +} + +/* + * Reading and writing from/to the BBP is different from RT2560 and RT2661. + * We access the BBP through the 8051 microcontroller unit which means that + * the microcode must be loaded first. + */ +void +rt2860_mcu_bbp_write(struct rt2860_softc *sc, uint8_t reg, uint8_t val) +{ + int ntries; + + for (ntries = 0; ntries < 100; ntries++) { + if (!(RAL_READ(sc, RT2860_H2M_BBPAGENT) & RT2860_BBP_CSR_KICK)) + break; + DELAY(1); + } + if (ntries == 100) { + device_printf(sc->sc_dev, + "could not write to BBP through MCU\n"); + return; + } + + RAL_WRITE(sc, RT2860_H2M_BBPAGENT, RT2860_BBP_RW_PARALLEL | + RT2860_BBP_CSR_KICK | reg << 8 | val); + RAL_BARRIER_WRITE(sc); + + rt2860_mcu_cmd(sc, RT2860_MCU_CMD_BBP, 0, 0); + DELAY(1000); +} + +uint8_t +rt2860_mcu_bbp_read(struct rt2860_softc *sc, uint8_t reg) +{ + uint32_t val; + int ntries; + + for (ntries = 0; ntries < 100; ntries++) { + if (!(RAL_READ(sc, RT2860_H2M_BBPAGENT) & RT2860_BBP_CSR_KICK)) + break; + DELAY(1); + } + if (ntries == 100) { + device_printf(sc->sc_dev, + "could not read from BBP through MCU\n"); + return 0; + } + + RAL_WRITE(sc, RT2860_H2M_BBPAGENT, RT2860_BBP_RW_PARALLEL | + RT2860_BBP_CSR_KICK | RT2860_BBP_CSR_READ | reg << 8); + RAL_BARRIER_WRITE(sc); + + rt2860_mcu_cmd(sc, RT2860_MCU_CMD_BBP, 0, 0); + DELAY(1000); + + for (ntries = 0; ntries < 100; ntries++) { + val = RAL_READ(sc, RT2860_H2M_BBPAGENT); + if (!(val & RT2860_BBP_CSR_KICK)) + return val & 0xff; + DELAY(1); + } + device_printf(sc->sc_dev, "could not read from BBP through MCU\n"); + + return 0; +} + +/* + * Write to one of the 4 programmable 24-bit RF registers. + */ +static void +rt2860_rf_write(struct rt2860_softc *sc, uint8_t reg, uint32_t val) +{ + uint32_t tmp; + int ntries; + + for (ntries = 0; ntries < 100; ntries++) { + if (!(RAL_READ(sc, RT2860_RF_CSR_CFG0) & RT2860_RF_REG_CTRL)) + break; + DELAY(1); + } + if (ntries == 100) { + device_printf(sc->sc_dev, "could not write to RF\n"); + return; + } + + /* RF registers are 24-bit on the RT2860 */ + tmp = RT2860_RF_REG_CTRL | 24 << RT2860_RF_REG_WIDTH_SHIFT | + (val & 0x3fffff) << 2 | (reg & 3); + RAL_WRITE(sc, RT2860_RF_CSR_CFG0, tmp); +} + +static uint8_t +rt3090_rf_read(struct rt2860_softc *sc, uint8_t reg) +{ + uint32_t tmp; + int ntries; + + for (ntries = 0; ntries < 100; ntries++) { + if (!(RAL_READ(sc, RT3070_RF_CSR_CFG) & RT3070_RF_KICK)) + break; + DELAY(1); + } + if (ntries == 100) { + device_printf(sc->sc_dev, "could not read RF register\n"); + return 0xff; + } + tmp = RT3070_RF_KICK | reg << 8; + RAL_WRITE(sc, RT3070_RF_CSR_CFG, tmp); + + for (ntries = 0; ntries < 100; ntries++) { + tmp = RAL_READ(sc, RT3070_RF_CSR_CFG); + if (!(tmp & RT3070_RF_KICK)) + break; + DELAY(1); + } + if (ntries == 100) { + device_printf(sc->sc_dev, "could not read RF register\n"); + return 0xff; + } + return tmp & 0xff; +} + +void +rt3090_rf_write(struct rt2860_softc *sc, uint8_t reg, uint8_t val) +{ + uint32_t tmp; + int ntries; + + for (ntries = 0; ntries < 10; ntries++) { + if (!(RAL_READ(sc, RT3070_RF_CSR_CFG) & RT3070_RF_KICK)) + break; + DELAY(10); + } + if (ntries == 10) { + device_printf(sc->sc_dev, "could not write to RF\n"); + return; + } + + tmp = RT3070_RF_WRITE | RT3070_RF_KICK | reg << 8 | val; + RAL_WRITE(sc, RT3070_RF_CSR_CFG, tmp); +} + +/* + * Send a command to the 8051 microcontroller unit. + */ +int +rt2860_mcu_cmd(struct rt2860_softc *sc, uint8_t cmd, uint16_t arg, int wait) +{ + int slot, ntries; + uint32_t tmp; + uint8_t cid; + + for (ntries = 0; ntries < 100; ntries++) { + if (!(RAL_READ(sc, RT2860_H2M_MAILBOX) & RT2860_H2M_BUSY)) + break; + DELAY(2); + } + if (ntries == 100) + return EIO; + + cid = wait ? cmd : RT2860_TOKEN_NO_INTR; + RAL_WRITE(sc, RT2860_H2M_MAILBOX, RT2860_H2M_BUSY | cid << 16 | arg); + RAL_BARRIER_WRITE(sc); + RAL_WRITE(sc, RT2860_HOST_CMD, cmd); + + if (!wait) + return 0; + /* wait for the command to complete */ + for (ntries = 0; ntries < 200; ntries++) { + tmp = RAL_READ(sc, RT2860_H2M_MAILBOX_CID); + /* find the command slot */ + for (slot = 0; slot < 4; slot++, tmp >>= 8) + if ((tmp & 0xff) == cid) + break; + if (slot < 4) + break; + DELAY(100); + } + if (ntries == 200) { + /* clear command and status */ + RAL_WRITE(sc, RT2860_H2M_MAILBOX_STATUS, 0xffffffff); + RAL_WRITE(sc, RT2860_H2M_MAILBOX_CID, 0xffffffff); + return ETIMEDOUT; + } + /* get command status (1 means success) */ + tmp = RAL_READ(sc, RT2860_H2M_MAILBOX_STATUS); + tmp = (tmp >> (slot * 8)) & 0xff; + DPRINTF(("MCU command=0x%02x slot=%d status=0x%02x\n", + cmd, slot, tmp)); + /* clear command and status */ + RAL_WRITE(sc, RT2860_H2M_MAILBOX_STATUS, 0xffffffff); + RAL_WRITE(sc, RT2860_H2M_MAILBOX_CID, 0xffffffff); + return (tmp == 1) ? 0 : EIO; +} + +static void +rt2860_enable_mrr(struct rt2860_softc *sc) +{ +#define CCK(mcs) (mcs) +#define OFDM(mcs) (1 << 3 | (mcs)) + RAL_WRITE(sc, RT2860_LG_FBK_CFG0, + OFDM(6) << 28 | /* 54->48 */ + OFDM(5) << 24 | /* 48->36 */ + OFDM(4) << 20 | /* 36->24 */ + OFDM(3) << 16 | /* 24->18 */ + OFDM(2) << 12 | /* 18->12 */ + OFDM(1) << 8 | /* 12-> 9 */ + OFDM(0) << 4 | /* 9-> 6 */ + OFDM(0)); /* 6-> 6 */ + + RAL_WRITE(sc, RT2860_LG_FBK_CFG1, + CCK(2) << 12 | /* 11->5.5 */ + CCK(1) << 8 | /* 5.5-> 2 */ + CCK(0) << 4 | /* 2-> 1 */ + CCK(0)); /* 1-> 1 */ +#undef OFDM +#undef CCK +} + +static void +rt2860_set_txpreamble(struct rt2860_softc *sc) +{ + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; + uint32_t tmp; + + tmp = RAL_READ(sc, RT2860_AUTO_RSP_CFG); + tmp &= ~RT2860_CCK_SHORT_EN; + if (ic->ic_flags & IEEE80211_F_SHPREAMBLE) + tmp |= RT2860_CCK_SHORT_EN; + RAL_WRITE(sc, RT2860_AUTO_RSP_CFG, tmp); +} + +void +rt2860_set_basicrates(struct rt2860_softc *sc, + const struct ieee80211_rateset *rs) +{ +#define RV(r) ((r) & IEEE80211_RATE_VAL) + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; + uint32_t mask = 0; + uint8_t rate; + int i; + + for (i = 0; i < rs->rs_nrates; i++) { + rate = rs->rs_rates[i]; + + if (!(rate & IEEE80211_RATE_BASIC)) + continue; + + mask |= 1 << ic->ic_rt->rateCodeToIndex[RV(rate)]; + } + + RAL_WRITE(sc, RT2860_LEGACY_BASIC_RATE, mask); +#undef RV +} + +static void +rt2860_scan_start(struct ieee80211com *ic) +{ + struct ifnet *ifp = ic->ic_ifp; + struct rt2860_softc *sc = ifp->if_softc; + uint32_t tmp; + + tmp = RAL_READ(sc, RT2860_BCN_TIME_CFG); + RAL_WRITE(sc, RT2860_BCN_TIME_CFG, + tmp & ~(RT2860_BCN_TX_EN | RT2860_TSF_TIMER_EN | + RT2860_TBTT_TIMER_EN)); + rt2860_set_gp_timer(sc, 0); +} + +static void +rt2860_scan_end(struct ieee80211com *ic) +{ + struct ifnet *ifp = ic->ic_ifp; + struct rt2860_softc *sc = ifp->if_softc; + struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); + + if (vap->iv_state == IEEE80211_S_RUN) { + rt2860_enable_tsf_sync(sc); + rt2860_set_gp_timer(sc, 500); + } +} + +static void +rt2860_set_channel(struct ieee80211com *ic) +{ + struct ifnet *ifp = ic->ic_ifp; + struct rt2860_softc *sc = ifp->if_softc; + + RAL_LOCK(sc); + rt2860_switch_chan(sc, ic->ic_curchan); + RAL_UNLOCK(sc); +} + +static void +rt2860_select_chan_group(struct rt2860_softc *sc, int group) +{ + uint32_t tmp; + uint8_t agc; + + rt2860_mcu_bbp_write(sc, 62, 0x37 - sc->lna[group]); + rt2860_mcu_bbp_write(sc, 63, 0x37 - sc->lna[group]); + rt2860_mcu_bbp_write(sc, 64, 0x37 - sc->lna[group]); + rt2860_mcu_bbp_write(sc, 86, 0x00); + + if (group == 0) { + if (sc->ext_2ghz_lna) { + rt2860_mcu_bbp_write(sc, 82, 0x62); + rt2860_mcu_bbp_write(sc, 75, 0x46); + } else { + rt2860_mcu_bbp_write(sc, 82, 0x84); + rt2860_mcu_bbp_write(sc, 75, 0x50); + } + } else { + if (sc->ext_5ghz_lna) { + rt2860_mcu_bbp_write(sc, 82, 0xf2); + rt2860_mcu_bbp_write(sc, 75, 0x46); + } else { + rt2860_mcu_bbp_write(sc, 82, 0xf2); + rt2860_mcu_bbp_write(sc, 75, 0x50); + } + } + + tmp = RAL_READ(sc, RT2860_TX_BAND_CFG); + tmp &= ~(RT2860_5G_BAND_SEL_N | RT2860_5G_BAND_SEL_P); + tmp |= (group == 0) ? RT2860_5G_BAND_SEL_N : RT2860_5G_BAND_SEL_P; + RAL_WRITE(sc, RT2860_TX_BAND_CFG, tmp); + + /* enable appropriate Power Amplifiers and Low Noise Amplifiers */ + tmp = RT2860_RFTR_EN | RT2860_TRSW_EN | RT2860_LNA_PE0_EN; + if (sc->nrxchains > 1) + tmp |= RT2860_LNA_PE1_EN; + if (sc->mac_ver == 0x3593 && sc->nrxchains > 2) + tmp |= RT3593_LNA_PE2_EN; + if (group == 0) { /* 2GHz */ + tmp |= RT2860_PA_PE_G0_EN; + if (sc->ntxchains > 1) + tmp |= RT2860_PA_PE_G1_EN; + if (sc->mac_ver == 0x3593 && sc->ntxchains > 2) + tmp |= RT3593_PA_PE_G2_EN; + } else { /* 5GHz */ + tmp |= RT2860_PA_PE_A0_EN; + if (sc->ntxchains > 1) + tmp |= RT2860_PA_PE_A1_EN; + if (sc->mac_ver == 0x3593 && sc->ntxchains > 2) + tmp |= RT3593_PA_PE_A2_EN; + } + RAL_WRITE(sc, RT2860_TX_PIN_CFG, tmp); + + if (sc->mac_ver == 0x3593) { + tmp = RAL_READ(sc, RT2860_GPIO_CTRL); + if (sc->sc_flags & RT2860_PCIE) { + tmp &= ~0x01010000; + if (group == 0) + tmp |= 0x00010000; + } else { + tmp &= ~0x00008080; + if (group == 0) + tmp |= 0x00000080; + } + tmp = (tmp & ~0x00001000) | 0x00000010; + RAL_WRITE(sc, RT2860_GPIO_CTRL, tmp); + } + + /* set initial AGC value */ + if (group == 0) { /* 2GHz band */ + if (sc->mac_ver >= 0x3071) + agc = 0x1c + sc->lna[0] * 2; + else + agc = 0x2e + sc->lna[0]; + } else { /* 5GHz band */ + agc = 0x32 + (sc->lna[group] * 5) / 3; + } + rt2860_mcu_bbp_write(sc, 66, agc); + + DELAY(1000); +} + +static void +rt2860_set_chan(struct rt2860_softc *sc, u_int chan) +{ + const struct rfprog *rfprog = rt2860_rf2850; + uint32_t r2, r3, r4; + int8_t txpow1, txpow2; + u_int i; + + /* find the settings for this channel (we know it exists) */ + for (i = 0; rfprog[i].chan != chan; i++); + + r2 = rfprog[i].r2; + if (sc->ntxchains == 1) + r2 |= 1 << 12; /* 1T: disable Tx chain 2 */ + if (sc->nrxchains == 1) + r2 |= 1 << 15 | 1 << 4; /* 1R: disable Rx chains 2 & 3 */ + else if (sc->nrxchains == 2) + r2 |= 1 << 4; /* 2R: disable Rx chain 3 */ + + /* use Tx power values from EEPROM */ + txpow1 = sc->txpow1[i]; + txpow2 = sc->txpow2[i]; + if (chan > 14) { + if (txpow1 >= 0) + txpow1 = txpow1 << 1 | 1; + else + txpow1 = (7 + txpow1) << 1; + if (txpow2 >= 0) + txpow2 = txpow2 << 1 | 1; + else + txpow2 = (7 + txpow2) << 1; + } + r3 = rfprog[i].r3 | txpow1 << 7; + r4 = rfprog[i].r4 | sc->freq << 13 | txpow2 << 4; + + rt2860_rf_write(sc, RT2860_RF1, rfprog[i].r1); + rt2860_rf_write(sc, RT2860_RF2, r2); + rt2860_rf_write(sc, RT2860_RF3, r3); + rt2860_rf_write(sc, RT2860_RF4, r4); + + DELAY(200); + + rt2860_rf_write(sc, RT2860_RF1, rfprog[i].r1); + rt2860_rf_write(sc, RT2860_RF2, r2); + rt2860_rf_write(sc, RT2860_RF3, r3 | 1); + rt2860_rf_write(sc, RT2860_RF4, r4); + + DELAY(200); + + rt2860_rf_write(sc, RT2860_RF1, rfprog[i].r1); + rt2860_rf_write(sc, RT2860_RF2, r2); + rt2860_rf_write(sc, RT2860_RF3, r3); + rt2860_rf_write(sc, RT2860_RF4, r4); +} + +static void +rt3090_set_chan(struct rt2860_softc *sc, u_int chan) +{ + int8_t txpow1, txpow2; + uint8_t rf; + int i; + + /* RT3090 is 2GHz only */ + KASSERT(chan >= 1 && chan <= 14, ("chan %d not support", chan)); + + /* find the settings for this channel (we know it exists) */ + for (i = 0; rt2860_rf2850[i].chan != chan; i++); + + /* use Tx power values from EEPROM */ + txpow1 = sc->txpow1[i]; + txpow2 = sc->txpow2[i]; + + rt3090_rf_write(sc, 2, rt3090_freqs[i].n); + rf = rt3090_rf_read(sc, 3); + rf = (rf & ~0x0f) | rt3090_freqs[i].k; + rt3090_rf_write(sc, 3, rf); + rf = rt3090_rf_read(sc, 6); + rf = (rf & ~0x03) | rt3090_freqs[i].r; + rt3090_rf_write(sc, 6, rf); + + /* set Tx0 power */ + rf = rt3090_rf_read(sc, 12); + rf = (rf & ~0x1f) | txpow1; + rt3090_rf_write(sc, 12, rf); + + /* set Tx1 power */ + rf = rt3090_rf_read(sc, 13); + rf = (rf & ~0x1f) | txpow2; + rt3090_rf_write(sc, 13, rf); + + rf = rt3090_rf_read(sc, 1); + rf &= ~0xfc; + if (sc->ntxchains == 1) + rf |= RT3070_TX1_PD | RT3070_TX2_PD; + else if (sc->ntxchains == 2) + rf |= RT3070_TX2_PD; + if (sc->nrxchains == 1) + rf |= RT3070_RX1_PD | RT3070_RX2_PD; + else if (sc->nrxchains == 2) + rf |= RT3070_RX2_PD; + rt3090_rf_write(sc, 1, rf); + + /* set RF offset */ + rf = rt3090_rf_read(sc, 23); + rf = (rf & ~0x7f) | sc->freq; + rt3090_rf_write(sc, 23, rf); + + /* program RF filter */ + rf = rt3090_rf_read(sc, 24); /* Tx */ + rf = (rf & ~0x3f) | sc->rf24_20mhz; + rt3090_rf_write(sc, 24, rf); + rf = rt3090_rf_read(sc, 31); /* Rx */ + rf = (rf & ~0x3f) | sc->rf24_20mhz; + rt3090_rf_write(sc, 31, rf); + + /* enable RF tuning */ + rf = rt3090_rf_read(sc, 7); + rt3090_rf_write(sc, 7, rf | RT3070_TUNE); +} + +static int +rt3090_rf_init(struct rt2860_softc *sc) +{ +#define N(a) (sizeof (a) / sizeof ((a)[0])) + uint32_t tmp; + uint8_t rf, bbp; + int i; + + rf = rt3090_rf_read(sc, 30); + /* toggle RF R30 bit 7 */ + rt3090_rf_write(sc, 30, rf | 0x80); + DELAY(1000); + rt3090_rf_write(sc, 30, rf & ~0x80); + + tmp = RAL_READ(sc, RT3070_LDO_CFG0); + tmp &= ~0x1f000000; + if (sc->patch_dac && sc->mac_rev < 0x0211) + tmp |= 0x0d000000; /* 1.35V */ + else + tmp |= 0x01000000; /* 1.2V */ + RAL_WRITE(sc, RT3070_LDO_CFG0, tmp); + + /* patch LNA_PE_G1 */ + tmp = RAL_READ(sc, RT3070_GPIO_SWITCH); + RAL_WRITE(sc, RT3070_GPIO_SWITCH, tmp & ~0x20); + + /* initialize RF registers to default value */ + for (i = 0; i < N(rt3090_def_rf); i++) { + rt3090_rf_write(sc, rt3090_def_rf[i].reg, + rt3090_def_rf[i].val); + } + + /* select 20MHz bandwidth */ + rt3090_rf_write(sc, 31, 0x14); + + rf = rt3090_rf_read(sc, 6); + rt3090_rf_write(sc, 6, rf | 0x40); + + if (sc->mac_ver != 0x3593) { + /* calibrate filter for 20MHz bandwidth */ + sc->rf24_20mhz = 0x1f; /* default value */ + rt3090_filter_calib(sc, 0x07, 0x16, &sc->rf24_20mhz); + + /* select 40MHz bandwidth */ + bbp = rt2860_mcu_bbp_read(sc, 4); + rt2860_mcu_bbp_write(sc, 4, (bbp & ~0x08) | 0x10); + rf = rt3090_rf_read(sc, 31); + rt3090_rf_write(sc, 31, rf | 0x20); + + /* calibrate filter for 40MHz bandwidth */ + sc->rf24_40mhz = 0x2f; /* default value */ + rt3090_filter_calib(sc, 0x27, 0x19, &sc->rf24_40mhz); + + /* go back to 20MHz bandwidth */ + bbp = rt2860_mcu_bbp_read(sc, 4); + rt2860_mcu_bbp_write(sc, 4, bbp & ~0x18); + } + if (sc->mac_rev < 0x0211) + rt3090_rf_write(sc, 27, 0x03); + + tmp = RAL_READ(sc, RT3070_OPT_14); + RAL_WRITE(sc, RT3070_OPT_14, tmp | 1); + + if (sc->rf_rev == RT3070_RF_3020) + rt3090_set_rx_antenna(sc, 0); + + bbp = rt2860_mcu_bbp_read(sc, 138); + if (sc->mac_ver == 0x3593) { + if (sc->ntxchains == 1) + bbp |= 0x60; /* turn off DAC1 and DAC2 */ + else if (sc->ntxchains == 2) + bbp |= 0x40; /* turn off DAC2 */ + if (sc->nrxchains == 1) + bbp &= ~0x06; /* turn off ADC1 and ADC2 */ + else if (sc->nrxchains == 2) + bbp &= ~0x04; /* turn off ADC2 */ + } else { + if (sc->ntxchains == 1) + bbp |= 0x20; /* turn off DAC1 */ + if (sc->nrxchains == 1) + bbp &= ~0x02; /* turn off ADC1 */ + } + rt2860_mcu_bbp_write(sc, 138, bbp); + + rf = rt3090_rf_read(sc, 1); + rf &= ~(RT3070_RX0_PD | RT3070_TX0_PD); + rf |= RT3070_RF_BLOCK | RT3070_RX1_PD | RT3070_TX1_PD; + rt3090_rf_write(sc, 1, rf); + + rf = rt3090_rf_read(sc, 15); + rt3090_rf_write(sc, 15, rf & ~RT3070_TX_LO2); + + rf = rt3090_rf_read(sc, 17); + rf &= ~RT3070_TX_LO1; + if (sc->mac_rev >= 0x0211 && !sc->ext_2ghz_lna) + rf |= 0x20; /* fix for long range Rx issue */ + if (sc->txmixgain_2ghz >= 2) + rf = (rf & ~0x7) | sc->txmixgain_2ghz; + rt3090_rf_write(sc, 17, rf); + + rf = rt3090_rf_read(sc, 20); + rt3090_rf_write(sc, 20, rf & ~RT3070_RX_LO1); + + rf = rt3090_rf_read(sc, 21); + rt3090_rf_write(sc, 21, rf & ~RT3070_RX_LO2); + + return 0; +#undef N +} + +void +rt3090_rf_wakeup(struct rt2860_softc *sc) +{ + uint32_t tmp; + uint8_t rf; + + if (sc->mac_ver == 0x3593) { + /* enable VCO */ + rf = rt3090_rf_read(sc, 1); + rt3090_rf_write(sc, 1, rf | RT3593_VCO); + + /* initiate VCO calibration */ + rf = rt3090_rf_read(sc, 3); + rt3090_rf_write(sc, 3, rf | RT3593_VCOCAL); + + /* enable VCO bias current control */ + rf = rt3090_rf_read(sc, 6); + rt3090_rf_write(sc, 6, rf | RT3593_VCO_IC); + + /* initiate res calibration */ + rf = rt3090_rf_read(sc, 2); + rt3090_rf_write(sc, 2, rf | RT3593_RESCAL); + + /* set reference current control to 0.33 mA */ + rf = rt3090_rf_read(sc, 22); + rf &= ~RT3593_CP_IC_MASK; + rf |= 1 << RT3593_CP_IC_SHIFT; + rt3090_rf_write(sc, 22, rf); + + /* enable RX CTB */ + rf = rt3090_rf_read(sc, 46); + rt3090_rf_write(sc, 46, rf | RT3593_RX_CTB); + + rf = rt3090_rf_read(sc, 20); + rf &= ~(RT3593_LDO_RF_VC_MASK | RT3593_LDO_PLL_VC_MASK); + rt3090_rf_write(sc, 20, rf); + } else { + /* enable RF block */ + rf = rt3090_rf_read(sc, 1); + rt3090_rf_write(sc, 1, rf | RT3070_RF_BLOCK); + + /* enable VCO bias current control */ + rf = rt3090_rf_read(sc, 7); + rt3090_rf_write(sc, 7, rf | 0x30); + + rf = rt3090_rf_read(sc, 9); + rt3090_rf_write(sc, 9, rf | 0x0e); + + /* enable RX CTB */ + rf = rt3090_rf_read(sc, 21); + rt3090_rf_write(sc, 21, rf | RT3070_RX_CTB); + + /* fix Tx to Rx IQ glitch by raising RF voltage */ + rf = rt3090_rf_read(sc, 27); + rf &= ~0x77; + if (sc->mac_rev < 0x0211) + rf |= 0x03; + rt3090_rf_write(sc, 27, rf); + } + if (sc->patch_dac && sc->mac_rev < 0x0211) { + tmp = RAL_READ(sc, RT3070_LDO_CFG0); + tmp = (tmp & ~0x1f000000) | 0x0d000000; + RAL_WRITE(sc, RT3070_LDO_CFG0, tmp); + } +} + +int +rt3090_filter_calib(struct rt2860_softc *sc, uint8_t init, uint8_t target, + uint8_t *val) +{ + uint8_t rf22, rf24; + uint8_t bbp55_pb, bbp55_sb, delta; + int ntries; + + /* program filter */ + rf24 = rt3090_rf_read(sc, 24); + rf24 = (rf24 & 0xc0) | init; /* initial filter value */ + rt3090_rf_write(sc, 24, rf24); + + /* enable baseband loopback mode */ + rf22 = rt3090_rf_read(sc, 22); + rt3090_rf_write(sc, 22, rf22 | RT3070_BB_LOOPBACK); + + /* set power and frequency of passband test tone */ + rt2860_mcu_bbp_write(sc, 24, 0x00); + for (ntries = 0; ntries < 100; ntries++) { + /* transmit test tone */ + rt2860_mcu_bbp_write(sc, 25, 0x90); + DELAY(1000); + /* read received power */ + bbp55_pb = rt2860_mcu_bbp_read(sc, 55); + if (bbp55_pb != 0) + break; + } + if (ntries == 100) + return ETIMEDOUT; + + /* set power and frequency of stopband test tone */ + rt2860_mcu_bbp_write(sc, 24, 0x06); + for (ntries = 0; ntries < 100; ntries++) { + /* transmit test tone */ + rt2860_mcu_bbp_write(sc, 25, 0x90); + DELAY(1000); + /* read received power */ + bbp55_sb = rt2860_mcu_bbp_read(sc, 55); + + delta = bbp55_pb - bbp55_sb; + if (delta > target) + break; + + /* reprogram filter */ + rf24++; + rt3090_rf_write(sc, 24, rf24); + } + if (ntries < 100) { + if (rf24 != init) + rf24--; /* backtrack */ + *val = rf24; + rt3090_rf_write(sc, 24, rf24); + } + + /* restore initial state */ + rt2860_mcu_bbp_write(sc, 24, 0x00); + + /* disable baseband loopback mode */ + rf22 = rt3090_rf_read(sc, 22); + rt3090_rf_write(sc, 22, rf22 & ~RT3070_BB_LOOPBACK); + + return 0; +} + +static void +rt3090_rf_setup(struct rt2860_softc *sc) +{ + uint8_t bbp; + int i; + + if (sc->mac_rev >= 0x0211) { + /* enable DC filter */ + rt2860_mcu_bbp_write(sc, 103, 0xc0); + + /* improve power consumption */ + bbp = rt2860_mcu_bbp_read(sc, 31); + rt2860_mcu_bbp_write(sc, 31, bbp & ~0x03); + } + + RAL_WRITE(sc, RT2860_TX_SW_CFG1, 0); + if (sc->mac_rev < 0x0211) { + RAL_WRITE(sc, RT2860_TX_SW_CFG2, + sc->patch_dac ? 0x2c : 0x0f); + } else + RAL_WRITE(sc, RT2860_TX_SW_CFG2, 0); + + /* initialize RF registers from ROM */ + for (i = 0; i < 10; i++) { + if (sc->rf[i].reg == 0 || sc->rf[i].reg == 0xff) + continue; + rt3090_rf_write(sc, sc->rf[i].reg, sc->rf[i].val); + } +} + +static void +rt2860_set_leds(struct rt2860_softc *sc, uint16_t which) +{ + rt2860_mcu_cmd(sc, RT2860_MCU_CMD_LEDS, + which | (sc->leds & 0x7f), 0); +} + +/* + * Hardware has a general-purpose programmable timer interrupt that can + * periodically raise MAC_INT_4. + */ +static void +rt2860_set_gp_timer(struct rt2860_softc *sc, int ms) +{ + uint32_t tmp; + + /* disable GP timer before reprogramming it */ + tmp = RAL_READ(sc, RT2860_INT_TIMER_EN); + RAL_WRITE(sc, RT2860_INT_TIMER_EN, tmp & ~RT2860_GP_TIMER_EN); + + if (ms == 0) + return; + + tmp = RAL_READ(sc, RT2860_INT_TIMER_CFG); + ms *= 16; /* Unit: 64us */ + tmp = (tmp & 0xffff) | ms << RT2860_GP_TIMER_SHIFT; + RAL_WRITE(sc, RT2860_INT_TIMER_CFG, tmp); + + /* enable GP timer */ + tmp = RAL_READ(sc, RT2860_INT_TIMER_EN); + RAL_WRITE(sc, RT2860_INT_TIMER_EN, tmp | RT2860_GP_TIMER_EN); +} + +static void +rt2860_set_bssid(struct rt2860_softc *sc, const uint8_t *bssid) +{ + RAL_WRITE(sc, RT2860_MAC_BSSID_DW0, + bssid[0] | bssid[1] << 8 | bssid[2] << 16 | bssid[3] << 24); + RAL_WRITE(sc, RT2860_MAC_BSSID_DW1, + bssid[4] | bssid[5] << 8); +} + +static void +rt2860_set_macaddr(struct rt2860_softc *sc, const uint8_t *addr) +{ + RAL_WRITE(sc, RT2860_MAC_ADDR_DW0, + addr[0] | addr[1] << 8 | addr[2] << 16 | addr[3] << 24); + RAL_WRITE(sc, RT2860_MAC_ADDR_DW1, + addr[4] | addr[5] << 8 | 0xff << 16); +} + +static void +rt2860_updateslot(struct ifnet *ifp) +{ + struct rt2860_softc *sc = ifp->if_softc; + struct ieee80211com *ic = ifp->if_l2com; + uint32_t tmp; + + tmp = RAL_READ(sc, RT2860_BKOFF_SLOT_CFG); + tmp &= ~0xff; + tmp |= (ic->ic_flags & IEEE80211_F_SHSLOT) ? 9 : 20; + RAL_WRITE(sc, RT2860_BKOFF_SLOT_CFG, tmp); +} + +static void +rt2860_updateprot(struct ifnet *ifp) +{ + struct rt2860_softc *sc = ifp->if_softc; + struct ieee80211com *ic = ifp->if_l2com; + uint32_t tmp; + + tmp = RT2860_RTSTH_EN | RT2860_PROT_NAV_SHORT | RT2860_TXOP_ALLOW_ALL; + /* setup protection frame rate (MCS code) */ + tmp |= IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan) ? + rt2860_rates[RT2860_RIDX_OFDM6].mcs : + rt2860_rates[RT2860_RIDX_CCK11].mcs; + + /* CCK frames don't require protection */ + RAL_WRITE(sc, RT2860_CCK_PROT_CFG, tmp); + + if (ic->ic_flags & IEEE80211_F_USEPROT) { + if (ic->ic_protmode == IEEE80211_PROT_RTSCTS) + tmp |= RT2860_PROT_CTRL_RTS_CTS; + else if (ic->ic_protmode == IEEE80211_PROT_CTSONLY) + tmp |= RT2860_PROT_CTRL_CTS; + } + RAL_WRITE(sc, RT2860_OFDM_PROT_CFG, tmp); +} + +static void +rt2860_update_promisc(struct ifnet *ifp) +{ + struct rt2860_softc *sc = ifp->if_softc; + uint32_t tmp; + + tmp = RAL_READ(sc, RT2860_RX_FILTR_CFG); + tmp &= ~RT2860_DROP_NOT_MYBSS; + if (!(ifp->if_flags & IFF_PROMISC)) + tmp |= RT2860_DROP_NOT_MYBSS; + RAL_WRITE(sc, RT2860_RX_FILTR_CFG, tmp); +} + +static int +rt2860_updateedca(struct ieee80211com *ic) +{ + struct rt2860_softc *sc = ic->ic_ifp->if_softc; + const struct wmeParams *wmep; + int aci; + + wmep = ic->ic_wme.wme_chanParams.cap_wmeParams; + + /* update MAC TX configuration registers */ + for (aci = 0; aci < WME_NUM_AC; aci++) { + RAL_WRITE(sc, RT2860_EDCA_AC_CFG(aci), + wmep[aci].wmep_logcwmax << 16 | + wmep[aci].wmep_logcwmin << 12 | + wmep[aci].wmep_aifsn << 8 | + wmep[aci].wmep_txopLimit); + } + + /* update SCH/DMA registers too */ + RAL_WRITE(sc, RT2860_WMM_AIFSN_CFG, + wmep[WME_AC_VO].wmep_aifsn << 12 | + wmep[WME_AC_VI].wmep_aifsn << 8 | + wmep[WME_AC_BK].wmep_aifsn << 4 | + wmep[WME_AC_BE].wmep_aifsn); + RAL_WRITE(sc, RT2860_WMM_CWMIN_CFG, + wmep[WME_AC_VO].wmep_logcwmin << 12 | + wmep[WME_AC_VI].wmep_logcwmin << 8 | + wmep[WME_AC_BK].wmep_logcwmin << 4 | + wmep[WME_AC_BE].wmep_logcwmin); + RAL_WRITE(sc, RT2860_WMM_CWMAX_CFG, + wmep[WME_AC_VO].wmep_logcwmax << 12 | + wmep[WME_AC_VI].wmep_logcwmax << 8 | + wmep[WME_AC_BK].wmep_logcwmax << 4 | + wmep[WME_AC_BE].wmep_logcwmax); + RAL_WRITE(sc, RT2860_WMM_TXOP0_CFG, + wmep[WME_AC_BK].wmep_txopLimit << 16 | + wmep[WME_AC_BE].wmep_txopLimit); + RAL_WRITE(sc, RT2860_WMM_TXOP1_CFG, + wmep[WME_AC_VO].wmep_txopLimit << 16 | + wmep[WME_AC_VI].wmep_txopLimit); + + return 0; +} + +#ifdef HW_CRYPTO +static int +rt2860_set_key(struct ieee80211com *ic, struct ieee80211_node *ni, + struct ieee80211_key *k) +{ + struct rt2860_softc *sc = ic->ic_softc; + bus_size_t base; + uint32_t attr; + uint8_t mode, wcid, iv[8]; + + /* defer setting of WEP keys until interface is brought up */ + if ((ic->ic_if.if_flags & (IFF_UP | IFF_RUNNING)) != + (IFF_UP | IFF_RUNNING)) + return 0; + + /* map net80211 cipher to RT2860 security mode */ + switch (k->k_cipher) { + case IEEE80211_CIPHER_WEP40: + mode = RT2860_MODE_WEP40; + break; + case IEEE80211_CIPHER_WEP104: + mode = RT2860_MODE_WEP104; + break; + case IEEE80211_CIPHER_TKIP: + mode = RT2860_MODE_TKIP; + break; + case IEEE80211_CIPHER_CCMP: + mode = RT2860_MODE_AES_CCMP; + break; + default: + return EINVAL; + } + + if (k->k_flags & IEEE80211_KEY_GROUP) { + wcid = 0; /* NB: update WCID0 for group keys */ + base = RT2860_SKEY(0, k->k_id); + } else { + wcid = ((struct rt2860_node *)ni)->wcid; + base = RT2860_PKEY(wcid); + } + + if (k->k_cipher == IEEE80211_CIPHER_TKIP) { + RAL_WRITE_REGION_1(sc, base, k->k_key, 16); +#ifndef IEEE80211_STA_ONLY + if (ic->ic_opmode == IEEE80211_M_HOSTAP) { + RAL_WRITE_REGION_1(sc, base + 16, &k->k_key[16], 8); + RAL_WRITE_REGION_1(sc, base + 24, &k->k_key[24], 8); + } else +#endif + { + RAL_WRITE_REGION_1(sc, base + 16, &k->k_key[24], 8); + RAL_WRITE_REGION_1(sc, base + 24, &k->k_key[16], 8); + } + } else + RAL_WRITE_REGION_1(sc, base, k->k_key, k->k_len); + + if (!(k->k_flags & IEEE80211_KEY_GROUP) || + (k->k_flags & IEEE80211_KEY_TX)) { + /* set initial packet number in IV+EIV */ + if (k->k_cipher == IEEE80211_CIPHER_WEP40 || + k->k_cipher == IEEE80211_CIPHER_WEP104) { + uint32_t val = arc4random(); + /* skip weak IVs from Fluhrer/Mantin/Shamir */ + if (val >= 0x03ff00 && (val & 0xf8ff00) == 0x00ff00) + val += 0x000100; + iv[0] = val; + iv[1] = val >> 8; + iv[2] = val >> 16; + iv[3] = k->k_id << 6; + iv[4] = iv[5] = iv[6] = iv[7] = 0; + } else { + if (k->k_cipher == IEEE80211_CIPHER_TKIP) { + iv[0] = k->k_tsc >> 8; + iv[1] = (iv[0] | 0x20) & 0x7f; + iv[2] = k->k_tsc; + } else /* CCMP */ { + iv[0] = k->k_tsc; + iv[1] = k->k_tsc >> 8; + iv[2] = 0; + } + iv[3] = k->k_id << 6 | IEEE80211_WEP_EXTIV; + iv[4] = k->k_tsc >> 16; + iv[5] = k->k_tsc >> 24; + iv[6] = k->k_tsc >> 32; + iv[7] = k->k_tsc >> 40; + } + RAL_WRITE_REGION_1(sc, RT2860_IVEIV(wcid), iv, 8); + } + + if (k->k_flags & IEEE80211_KEY_GROUP) { + /* install group key */ + attr = RAL_READ(sc, RT2860_SKEY_MODE_0_7); + attr &= ~(0xf << (k->k_id * 4)); + attr |= mode << (k->k_id * 4); + RAL_WRITE(sc, RT2860_SKEY_MODE_0_7, attr); + } else { + /* install pairwise key */ + attr = RAL_READ(sc, RT2860_WCID_ATTR(wcid)); + attr = (attr & ~0xf) | (mode << 1) | RT2860_RX_PKEY_EN; + RAL_WRITE(sc, RT2860_WCID_ATTR(wcid), attr); + } + return 0; +} + +static void +rt2860_delete_key(struct ieee80211com *ic, struct ieee80211_node *ni, + struct ieee80211_key *k) +{ + struct rt2860_softc *sc = ic->ic_softc; + uint32_t attr; + uint8_t wcid; + + if (k->k_flags & IEEE80211_KEY_GROUP) { + /* remove group key */ + attr = RAL_READ(sc, RT2860_SKEY_MODE_0_7); + attr &= ~(0xf << (k->k_id * 4)); + RAL_WRITE(sc, RT2860_SKEY_MODE_0_7, attr); + + } else { + /* remove pairwise key */ + wcid = ((struct rt2860_node *)ni)->wcid; + attr = RAL_READ(sc, RT2860_WCID_ATTR(wcid)); + attr &= ~0xf; + RAL_WRITE(sc, RT2860_WCID_ATTR(wcid), attr); + } +} +#endif + +static int8_t +rt2860_rssi2dbm(struct rt2860_softc *sc, uint8_t rssi, uint8_t rxchain) +{ + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211_channel *c = ic->ic_curchan; + int delta; + + if (IEEE80211_IS_CHAN_5GHZ(c)) { + u_int chan = ieee80211_chan2ieee(ic, c); + delta = sc->rssi_5ghz[rxchain]; + + /* determine channel group */ + if (chan <= 64) + delta -= sc->lna[1]; + else if (chan <= 128) + delta -= sc->lna[2]; + else + delta -= sc->lna[3]; + } else + delta = sc->rssi_2ghz[rxchain] - sc->lna[0]; + + return -12 - delta - rssi; +} + +/* + * Add `delta' (signed) to each 4-bit sub-word of a 32-bit word. + * Used to adjust per-rate Tx power registers. + */ +static __inline uint32_t +b4inc(uint32_t b32, int8_t delta) +{ + int8_t i, b4; + + for (i = 0; i < 8; i++) { + b4 = b32 & 0xf; + b4 += delta; + if (b4 < 0) + b4 = 0; + else if (b4 > 0xf) + b4 = 0xf; + b32 = b32 >> 4 | b4 << 28; + } + return b32; +} + +static const char * +rt2860_get_rf(uint8_t rev) +{ + switch (rev) { + case RT2860_RF_2820: return "RT2820"; + case RT2860_RF_2850: return "RT2850"; + case RT2860_RF_2720: return "RT2720"; + case RT2860_RF_2750: return "RT2750"; + case RT3070_RF_3020: return "RT3020"; + case RT3070_RF_2020: return "RT2020"; + case RT3070_RF_3021: return "RT3021"; + case RT3070_RF_3022: return "RT3022"; + case RT3070_RF_3052: return "RT3052"; + case RT3070_RF_3320: return "RT3320"; + case RT3070_RF_3053: return "RT3053"; + default: return "unknown"; + } +} + +static int +rt2860_read_eeprom(struct rt2860_softc *sc, uint8_t macaddr[IEEE80211_ADDR_LEN]) +{ + int8_t delta_2ghz, delta_5ghz; + uint32_t tmp; + uint16_t val; + int ridx, ant, i; + + /* check whether the ROM is eFUSE ROM or EEPROM */ + sc->sc_srom_read = rt2860_eeprom_read_2; + if (sc->mac_ver >= 0x3071) { + tmp = RAL_READ(sc, RT3070_EFUSE_CTRL); + DPRINTF(("EFUSE_CTRL=0x%08x\n", tmp)); + if (tmp & RT3070_SEL_EFUSE) + sc->sc_srom_read = rt3090_efuse_read_2; + } + + /* read EEPROM version */ + val = rt2860_srom_read(sc, RT2860_EEPROM_VERSION); + DPRINTF(("EEPROM rev=%d, FAE=%d\n", val & 0xff, val >> 8)); + + /* read MAC address */ + val = rt2860_srom_read(sc, RT2860_EEPROM_MAC01); + macaddr[0] = val & 0xff; + macaddr[1] = val >> 8; + val = rt2860_srom_read(sc, RT2860_EEPROM_MAC23); + macaddr[2] = val & 0xff; + macaddr[3] = val >> 8; + val = rt2860_srom_read(sc, RT2860_EEPROM_MAC45); + macaddr[4] = val & 0xff; + macaddr[5] = val >> 8; + + /* read country code */ + val = rt2860_srom_read(sc, RT2860_EEPROM_COUNTRY); + DPRINTF(("EEPROM region code=0x%04x\n", val)); + + /* read vendor BBP settings */ + for (i = 0; i < 8; i++) { + val = rt2860_srom_read(sc, RT2860_EEPROM_BBP_BASE + i); + sc->bbp[i].val = val & 0xff; + sc->bbp[i].reg = val >> 8; + DPRINTF(("BBP%d=0x%02x\n", sc->bbp[i].reg, sc->bbp[i].val)); + } + if (sc->mac_ver >= 0x3071) { + /* read vendor RF settings */ + for (i = 0; i < 10; i++) { + val = rt2860_srom_read(sc, RT3071_EEPROM_RF_BASE + i); + sc->rf[i].val = val & 0xff; + sc->rf[i].reg = val >> 8; + DPRINTF(("RF%d=0x%02x\n", sc->rf[i].reg, + sc->rf[i].val)); + } + } + + /* read RF frequency offset from EEPROM */ + val = rt2860_srom_read(sc, RT2860_EEPROM_FREQ_LEDS); + sc->freq = ((val & 0xff) != 0xff) ? val & 0xff : 0; + DPRINTF(("EEPROM freq offset %d\n", sc->freq & 0xff)); + if ((val >> 8) != 0xff) { + /* read LEDs operating mode */ + sc->leds = val >> 8; + sc->led[0] = rt2860_srom_read(sc, RT2860_EEPROM_LED1); + sc->led[1] = rt2860_srom_read(sc, RT2860_EEPROM_LED2); + sc->led[2] = rt2860_srom_read(sc, RT2860_EEPROM_LED3); + } else { + /* broken EEPROM, use default settings */ + sc->leds = 0x01; + sc->led[0] = 0x5555; + sc->led[1] = 0x2221; + sc->led[2] = 0xa9f8; + } + DPRINTF(("EEPROM LED mode=0x%02x, LEDs=0x%04x/0x%04x/0x%04x\n", + sc->leds, sc->led[0], sc->led[1], sc->led[2])); + + /* read RF information */ + val = rt2860_srom_read(sc, RT2860_EEPROM_ANTENNA); + if (val == 0xffff) { + DPRINTF(("invalid EEPROM antenna info, using default\n")); + if (sc->mac_ver == 0x3593) { + /* default to RF3053 3T3R */ + sc->rf_rev = RT3070_RF_3053; + sc->ntxchains = 3; + sc->nrxchains = 3; + } else if (sc->mac_ver >= 0x3071) { + /* default to RF3020 1T1R */ + sc->rf_rev = RT3070_RF_3020; + sc->ntxchains = 1; + sc->nrxchains = 1; + } else { + /* default to RF2820 1T2R */ + sc->rf_rev = RT2860_RF_2820; + sc->ntxchains = 1; + sc->nrxchains = 2; + } + } else { + sc->rf_rev = (val >> 8) & 0xf; + sc->ntxchains = (val >> 4) & 0xf; + sc->nrxchains = val & 0xf; + } + DPRINTF(("EEPROM RF rev=0x%02x chains=%dT%dR\n", + sc->rf_rev, sc->ntxchains, sc->nrxchains)); + + /* check if RF supports automatic Tx access gain control */ + val = rt2860_srom_read(sc, RT2860_EEPROM_CONFIG); + DPRINTF(("EEPROM CFG 0x%04x\n", val)); + /* check if driver should patch the DAC issue */ + if ((val >> 8) != 0xff) + sc->patch_dac = (val >> 15) & 1; + if ((val & 0xff) != 0xff) { + sc->ext_5ghz_lna = (val >> 3) & 1; + sc->ext_2ghz_lna = (val >> 2) & 1; + /* check if RF supports automatic Tx access gain control */ + sc->calib_2ghz = sc->calib_5ghz = 0; /* XXX (val >> 1) & 1 */; + /* check if we have a hardware radio switch */ + sc->rfswitch = val & 1; + } + if (sc->sc_flags & RT2860_ADVANCED_PS) { + /* read PCIe power save level */ + val = rt2860_srom_read(sc, RT2860_EEPROM_PCIE_PSLEVEL); + if ((val & 0xff) != 0xff) { + sc->pslevel = val & 0x3; + val = rt2860_srom_read(sc, RT2860_EEPROM_REV); + if ((val & 0xff80) != 0x9280) + sc->pslevel = MIN(sc->pslevel, 1); + DPRINTF(("EEPROM PCIe PS Level=%d\n", sc->pslevel)); + } + } + + /* read power settings for 2GHz channels */ + for (i = 0; i < 14; i += 2) { + val = rt2860_srom_read(sc, + RT2860_EEPROM_PWR2GHZ_BASE1 + i / 2); + sc->txpow1[i + 0] = (int8_t)(val & 0xff); + sc->txpow1[i + 1] = (int8_t)(val >> 8); + + val = rt2860_srom_read(sc, + RT2860_EEPROM_PWR2GHZ_BASE2 + i / 2); + sc->txpow2[i + 0] = (int8_t)(val & 0xff); + sc->txpow2[i + 1] = (int8_t)(val >> 8); + } + /* fix broken Tx power entries */ + for (i = 0; i < 14; i++) { + if (sc->txpow1[i] < 0 || sc->txpow1[i] > 31) + sc->txpow1[i] = 5; + if (sc->txpow2[i] < 0 || sc->txpow2[i] > 31) + sc->txpow2[i] = 5; + DPRINTF(("chan %d: power1=%d, power2=%d\n", + rt2860_rf2850[i].chan, sc->txpow1[i], sc->txpow2[i])); + } + /* read power settings for 5GHz channels */ + for (i = 0; i < 40; i += 2) { + val = rt2860_srom_read(sc, + RT2860_EEPROM_PWR5GHZ_BASE1 + i / 2); + sc->txpow1[i + 14] = (int8_t)(val & 0xff); + sc->txpow1[i + 15] = (int8_t)(val >> 8); + + val = rt2860_srom_read(sc, + RT2860_EEPROM_PWR5GHZ_BASE2 + i / 2); + sc->txpow2[i + 14] = (int8_t)(val & 0xff); + sc->txpow2[i + 15] = (int8_t)(val >> 8); + } + /* fix broken Tx power entries */ + for (i = 0; i < 40; i++) { + if (sc->txpow1[14 + i] < -7 || sc->txpow1[14 + i] > 15) + sc->txpow1[14 + i] = 5; + if (sc->txpow2[14 + i] < -7 || sc->txpow2[14 + i] > 15) + sc->txpow2[14 + i] = 5; + DPRINTF(("chan %d: power1=%d, power2=%d\n", + rt2860_rf2850[14 + i].chan, sc->txpow1[14 + i], + sc->txpow2[14 + i])); + } + + /* read Tx power compensation for each Tx rate */ + val = rt2860_srom_read(sc, RT2860_EEPROM_DELTAPWR); + delta_2ghz = delta_5ghz = 0; + if ((val & 0xff) != 0xff && (val & 0x80)) { + delta_2ghz = val & 0xf; + if (!(val & 0x40)) /* negative number */ + delta_2ghz = -delta_2ghz; + } + val >>= 8; + if ((val & 0xff) != 0xff && (val & 0x80)) { + delta_5ghz = val & 0xf; + if (!(val & 0x40)) /* negative number */ + delta_5ghz = -delta_5ghz; + } + DPRINTF(("power compensation=%d (2GHz), %d (5GHz)\n", + delta_2ghz, delta_5ghz)); + + for (ridx = 0; ridx < 5; ridx++) { + uint32_t reg; + + val = rt2860_srom_read(sc, RT2860_EEPROM_RPWR + ridx * 2); + reg = val; + val = rt2860_srom_read(sc, RT2860_EEPROM_RPWR + ridx * 2 + 1); + reg |= (uint32_t)val << 16; + + sc->txpow20mhz[ridx] = reg; + sc->txpow40mhz_2ghz[ridx] = b4inc(reg, delta_2ghz); + sc->txpow40mhz_5ghz[ridx] = b4inc(reg, delta_5ghz); + + DPRINTF(("ridx %d: power 20MHz=0x%08x, 40MHz/2GHz=0x%08x, " + "40MHz/5GHz=0x%08x\n", ridx, sc->txpow20mhz[ridx], + sc->txpow40mhz_2ghz[ridx], sc->txpow40mhz_5ghz[ridx])); + } + + /* read factory-calibrated samples for temperature compensation */ + val = rt2860_srom_read(sc, RT2860_EEPROM_TSSI1_2GHZ); + sc->tssi_2ghz[0] = val & 0xff; /* [-4] */ + sc->tssi_2ghz[1] = val >> 8; /* [-3] */ + val = rt2860_srom_read(sc, RT2860_EEPROM_TSSI2_2GHZ); + sc->tssi_2ghz[2] = val & 0xff; /* [-2] */ + sc->tssi_2ghz[3] = val >> 8; /* [-1] */ + val = rt2860_srom_read(sc, RT2860_EEPROM_TSSI3_2GHZ); + sc->tssi_2ghz[4] = val & 0xff; /* [+0] */ + sc->tssi_2ghz[5] = val >> 8; /* [+1] */ + val = rt2860_srom_read(sc, RT2860_EEPROM_TSSI4_2GHZ); + sc->tssi_2ghz[6] = val & 0xff; /* [+2] */ + sc->tssi_2ghz[7] = val >> 8; /* [+3] */ + val = rt2860_srom_read(sc, RT2860_EEPROM_TSSI5_2GHZ); + sc->tssi_2ghz[8] = val & 0xff; /* [+4] */ + sc->step_2ghz = val >> 8; + DPRINTF(("TSSI 2GHz: 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x " + "0x%02x 0x%02x step=%d\n", sc->tssi_2ghz[0], sc->tssi_2ghz[1], + sc->tssi_2ghz[2], sc->tssi_2ghz[3], sc->tssi_2ghz[4], + sc->tssi_2ghz[5], sc->tssi_2ghz[6], sc->tssi_2ghz[7], + sc->tssi_2ghz[8], sc->step_2ghz)); + /* check that ref value is correct, otherwise disable calibration */ + if (sc->tssi_2ghz[4] == 0xff) + sc->calib_2ghz = 0; + + val = rt2860_srom_read(sc, RT2860_EEPROM_TSSI1_5GHZ); + sc->tssi_5ghz[0] = val & 0xff; /* [-4] */ + sc->tssi_5ghz[1] = val >> 8; /* [-3] */ + val = rt2860_srom_read(sc, RT2860_EEPROM_TSSI2_5GHZ); + sc->tssi_5ghz[2] = val & 0xff; /* [-2] */ + sc->tssi_5ghz[3] = val >> 8; /* [-1] */ + val = rt2860_srom_read(sc, RT2860_EEPROM_TSSI3_5GHZ); + sc->tssi_5ghz[4] = val & 0xff; /* [+0] */ + sc->tssi_5ghz[5] = val >> 8; /* [+1] */ + val = rt2860_srom_read(sc, RT2860_EEPROM_TSSI4_5GHZ); + sc->tssi_5ghz[6] = val & 0xff; /* [+2] */ + sc->tssi_5ghz[7] = val >> 8; /* [+3] */ + val = rt2860_srom_read(sc, RT2860_EEPROM_TSSI5_5GHZ); + sc->tssi_5ghz[8] = val & 0xff; /* [+4] */ + sc->step_5ghz = val >> 8; + DPRINTF(("TSSI 5GHz: 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x " + "0x%02x 0x%02x step=%d\n", sc->tssi_5ghz[0], sc->tssi_5ghz[1], + sc->tssi_5ghz[2], sc->tssi_5ghz[3], sc->tssi_5ghz[4], + sc->tssi_5ghz[5], sc->tssi_5ghz[6], sc->tssi_5ghz[7], + sc->tssi_5ghz[8], sc->step_5ghz)); + /* check that ref value is correct, otherwise disable calibration */ + if (sc->tssi_5ghz[4] == 0xff) + sc->calib_5ghz = 0; + + /* read RSSI offsets and LNA gains from EEPROM */ + val = rt2860_srom_read(sc, RT2860_EEPROM_RSSI1_2GHZ); + sc->rssi_2ghz[0] = val & 0xff; /* Ant A */ + sc->rssi_2ghz[1] = val >> 8; /* Ant B */ + val = rt2860_srom_read(sc, RT2860_EEPROM_RSSI2_2GHZ); + if (sc->mac_ver >= 0x3071) { + /* + * On RT3090 chips (limited to 2 Rx chains), this ROM + * field contains the Tx mixer gain for the 2GHz band. + */ + if ((val & 0xff) != 0xff) + sc->txmixgain_2ghz = val & 0x7; + DPRINTF(("tx mixer gain=%u (2GHz)\n", sc->txmixgain_2ghz)); + } else + sc->rssi_2ghz[2] = val & 0xff; /* Ant C */ + sc->lna[2] = val >> 8; /* channel group 2 */ + + val = rt2860_srom_read(sc, RT2860_EEPROM_RSSI1_5GHZ); + sc->rssi_5ghz[0] = val & 0xff; /* Ant A */ + sc->rssi_5ghz[1] = val >> 8; /* Ant B */ + val = rt2860_srom_read(sc, RT2860_EEPROM_RSSI2_5GHZ); + sc->rssi_5ghz[2] = val & 0xff; /* Ant C */ + sc->lna[3] = val >> 8; /* channel group 3 */ + + val = rt2860_srom_read(sc, RT2860_EEPROM_LNA); + if (sc->mac_ver >= 0x3071) + sc->lna[0] = RT3090_DEF_LNA; + else /* channel group 0 */ + sc->lna[0] = val & 0xff; + sc->lna[1] = val >> 8; /* channel group 1 */ + + /* fix broken 5GHz LNA entries */ + if (sc->lna[2] == 0 || sc->lna[2] == 0xff) { + DPRINTF(("invalid LNA for channel group %d\n", 2)); + sc->lna[2] = sc->lna[1]; + } + if (sc->lna[3] == 0 || sc->lna[3] == 0xff) { + DPRINTF(("invalid LNA for channel group %d\n", 3)); + sc->lna[3] = sc->lna[1]; + } + + /* fix broken RSSI offset entries */ + for (ant = 0; ant < 3; ant++) { + if (sc->rssi_2ghz[ant] < -10 || sc->rssi_2ghz[ant] > 10) { + DPRINTF(("invalid RSSI%d offset: %d (2GHz)\n", + ant + 1, sc->rssi_2ghz[ant])); + sc->rssi_2ghz[ant] = 0; + } + if (sc->rssi_5ghz[ant] < -10 || sc->rssi_5ghz[ant] > 10) { + DPRINTF(("invalid RSSI%d offset: %d (5GHz)\n", + ant + 1, sc->rssi_5ghz[ant])); + sc->rssi_5ghz[ant] = 0; + } + } + + return 0; +} + +int +rt2860_bbp_init(struct rt2860_softc *sc) +{ +#define N(a) (sizeof (a) / sizeof ((a)[0])) + int i, ntries; + + /* wait for BBP to wake up */ + for (ntries = 0; ntries < 20; ntries++) { + uint8_t bbp0 = rt2860_mcu_bbp_read(sc, 0); + if (bbp0 != 0 && bbp0 != 0xff) + break; + } + if (ntries == 20) { + device_printf(sc->sc_dev, + "timeout waiting for BBP to wake up\n"); + return ETIMEDOUT; + } + + /* initialize BBP registers to default values */ + for (i = 0; i < N(rt2860_def_bbp); i++) { + rt2860_mcu_bbp_write(sc, rt2860_def_bbp[i].reg, + rt2860_def_bbp[i].val); + } + + /* fix BBP84 for RT2860E */ + if (sc->mac_ver == 0x2860 && sc->mac_rev != 0x0101) + rt2860_mcu_bbp_write(sc, 84, 0x19); + + if (sc->mac_ver >= 0x3071) { + rt2860_mcu_bbp_write(sc, 79, 0x13); + rt2860_mcu_bbp_write(sc, 80, 0x05); + rt2860_mcu_bbp_write(sc, 81, 0x33); + } else if (sc->mac_ver == 0x2860 && sc->mac_rev == 0x0100) { + rt2860_mcu_bbp_write(sc, 69, 0x16); + rt2860_mcu_bbp_write(sc, 73, 0x12); + } + + return 0; +#undef N +} + +static int +rt2860_txrx_enable(struct rt2860_softc *sc) +{ + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; + uint32_t tmp; + int ntries; + + /* enable Tx/Rx DMA engine */ + RAL_WRITE(sc, RT2860_MAC_SYS_CTRL, RT2860_MAC_TX_EN); + RAL_BARRIER_READ_WRITE(sc); + for (ntries = 0; ntries < 200; ntries++) { + tmp = RAL_READ(sc, RT2860_WPDMA_GLO_CFG); + if ((tmp & (RT2860_TX_DMA_BUSY | RT2860_RX_DMA_BUSY)) == 0) + break; + DELAY(1000); + } + if (ntries == 200) { + device_printf(sc->sc_dev, "timeout waiting for DMA engine\n"); + return ETIMEDOUT; + } + + DELAY(50); + + tmp |= RT2860_RX_DMA_EN | RT2860_TX_DMA_EN | + RT2860_WPDMA_BT_SIZE64 << RT2860_WPDMA_BT_SIZE_SHIFT; + RAL_WRITE(sc, RT2860_WPDMA_GLO_CFG, tmp); + + /* set Rx filter */ + tmp = RT2860_DROP_CRC_ERR | RT2860_DROP_PHY_ERR; + if (ic->ic_opmode != IEEE80211_M_MONITOR) { + tmp |= RT2860_DROP_UC_NOME | RT2860_DROP_DUPL | + RT2860_DROP_CTS | RT2860_DROP_BA | RT2860_DROP_ACK | + RT2860_DROP_VER_ERR | RT2860_DROP_CTRL_RSV | + RT2860_DROP_CFACK | RT2860_DROP_CFEND; + if (ic->ic_opmode == IEEE80211_M_STA) + tmp |= RT2860_DROP_RTS | RT2860_DROP_PSPOLL; + } + RAL_WRITE(sc, RT2860_RX_FILTR_CFG, tmp); + + RAL_WRITE(sc, RT2860_MAC_SYS_CTRL, + RT2860_MAC_RX_EN | RT2860_MAC_TX_EN); + + return 0; +} + +static void +rt2860_init(void *arg) +{ + struct rt2860_softc *sc = arg; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; + + RAL_LOCK(sc); + rt2860_init_locked(sc); + RAL_UNLOCK(sc); + + if (ifp->if_drv_flags & IFF_DRV_RUNNING) + ieee80211_start_all(ic); +} + +static void +rt2860_init_locked(struct rt2860_softc *sc) +{ +#define N(a) (sizeof (a) / sizeof ((a)[0])) + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; + uint32_t tmp; + uint8_t bbp1, bbp3; + int i, qid, ridx, ntries, error; + + RAL_LOCK_ASSERT(sc); + + if (sc->rfswitch) { + /* hardware has a radio switch on GPIO pin 2 */ + if (!(RAL_READ(sc, RT2860_GPIO_CTRL) & (1 << 2))) { + device_printf(sc->sc_dev, + "radio is disabled by hardware switch\n"); +#ifdef notyet + rt2860_stop_locked(sc); + return; +#endif + } + } + RAL_WRITE(sc, RT2860_PWR_PIN_CFG, RT2860_IO_RA_PE); + + /* disable DMA */ + tmp = RAL_READ(sc, RT2860_WPDMA_GLO_CFG); + tmp &= 0xff0; + RAL_WRITE(sc, RT2860_WPDMA_GLO_CFG, tmp); + + /* PBF hardware reset */ + RAL_WRITE(sc, RT2860_SYS_CTRL, 0xe1f); + RAL_BARRIER_WRITE(sc); + RAL_WRITE(sc, RT2860_SYS_CTRL, 0xe00); + + if ((error = rt2860_load_microcode(sc)) != 0) { + device_printf(sc->sc_dev, "could not load 8051 microcode\n"); + rt2860_stop_locked(sc); + return; + } + + rt2860_set_macaddr(sc, IF_LLADDR(ifp)); + + /* init Tx power for all Tx rates (from EEPROM) */ + for (ridx = 0; ridx < 5; ridx++) { + if (sc->txpow20mhz[ridx] == 0xffffffff) + continue; + RAL_WRITE(sc, RT2860_TX_PWR_CFG(ridx), sc->txpow20mhz[ridx]); + } + + for (ntries = 0; ntries < 100; ntries++) { + tmp = RAL_READ(sc, RT2860_WPDMA_GLO_CFG); + if ((tmp & (RT2860_TX_DMA_BUSY | RT2860_RX_DMA_BUSY)) == 0) + break; + DELAY(1000); + } + if (ntries == 100) { + device_printf(sc->sc_dev, "timeout waiting for DMA engine\n"); + rt2860_stop_locked(sc); + return; + } + tmp &= 0xff0; + RAL_WRITE(sc, RT2860_WPDMA_GLO_CFG, tmp); + + /* reset Rx ring and all 6 Tx rings */ + RAL_WRITE(sc, RT2860_WPDMA_RST_IDX, 0x1003f); + + /* PBF hardware reset */ + RAL_WRITE(sc, RT2860_SYS_CTRL, 0xe1f); + RAL_BARRIER_WRITE(sc); + RAL_WRITE(sc, RT2860_SYS_CTRL, 0xe00); + + RAL_WRITE(sc, RT2860_PWR_PIN_CFG, RT2860_IO_RA_PE | RT2860_IO_RF_PE); + + RAL_WRITE(sc, RT2860_MAC_SYS_CTRL, RT2860_BBP_HRST | RT2860_MAC_SRST); + RAL_BARRIER_WRITE(sc); + RAL_WRITE(sc, RT2860_MAC_SYS_CTRL, 0); + + for (i = 0; i < N(rt2860_def_mac); i++) + RAL_WRITE(sc, rt2860_def_mac[i].reg, rt2860_def_mac[i].val); + if (sc->mac_ver >= 0x3071) { + /* set delay of PA_PE assertion to 1us (unit of 0.25us) */ + RAL_WRITE(sc, RT2860_TX_SW_CFG0, + 4 << RT2860_DLY_PAPE_EN_SHIFT); + } + + if (!(RAL_READ(sc, RT2860_PCI_CFG) & RT2860_PCI_CFG_PCI)) { + sc->sc_flags |= RT2860_PCIE; + /* PCIe has different clock cycle count than PCI */ + tmp = RAL_READ(sc, RT2860_US_CYC_CNT); + tmp = (tmp & ~0xff) | 0x7d; + RAL_WRITE(sc, RT2860_US_CYC_CNT, tmp); + } + + /* wait while MAC is busy */ + for (ntries = 0; ntries < 100; ntries++) { + if (!(RAL_READ(sc, RT2860_MAC_STATUS_REG) & + (RT2860_RX_STATUS_BUSY | RT2860_TX_STATUS_BUSY))) + break; + DELAY(1000); + } + if (ntries == 100) { + device_printf(sc->sc_dev, "timeout waiting for MAC\n"); + rt2860_stop_locked(sc); + return; + } + + /* clear Host to MCU mailbox */ + RAL_WRITE(sc, RT2860_H2M_BBPAGENT, 0); + RAL_WRITE(sc, RT2860_H2M_MAILBOX, 0); + + rt2860_mcu_cmd(sc, RT2860_MCU_CMD_RFRESET, 0, 0); + DELAY(1000); + + if ((error = rt2860_bbp_init(sc)) != 0) { + rt2860_stop_locked(sc); + return; + } + + /* clear RX WCID search table */ + RAL_SET_REGION_4(sc, RT2860_WCID_ENTRY(0), 0, 512); + /* clear pairwise key table */ + RAL_SET_REGION_4(sc, RT2860_PKEY(0), 0, 2048); + /* clear IV/EIV table */ + RAL_SET_REGION_4(sc, RT2860_IVEIV(0), 0, 512); + /* clear WCID attribute table */ + RAL_SET_REGION_4(sc, RT2860_WCID_ATTR(0), 0, 256); + /* clear shared key table */ + RAL_SET_REGION_4(sc, RT2860_SKEY(0, 0), 0, 8 * 32); + /* clear shared key mode */ + RAL_SET_REGION_4(sc, RT2860_SKEY_MODE_0_7, 0, 4); + + /* init Tx rings (4 EDCAs + HCCA + Mgt) */ + for (qid = 0; qid < 6; qid++) { + RAL_WRITE(sc, RT2860_TX_BASE_PTR(qid), sc->txq[qid].paddr); + RAL_WRITE(sc, RT2860_TX_MAX_CNT(qid), RT2860_TX_RING_COUNT); + RAL_WRITE(sc, RT2860_TX_CTX_IDX(qid), 0); + } + + /* init Rx ring */ + RAL_WRITE(sc, RT2860_RX_BASE_PTR, sc->rxq.paddr); + RAL_WRITE(sc, RT2860_RX_MAX_CNT, RT2860_RX_RING_COUNT); + RAL_WRITE(sc, RT2860_RX_CALC_IDX, RT2860_RX_RING_COUNT - 1); + + /* setup maximum buffer sizes */ + RAL_WRITE(sc, RT2860_MAX_LEN_CFG, 1 << 12 | + (MCLBYTES - sizeof (struct rt2860_rxwi) - 2)); + + for (ntries = 0; ntries < 100; ntries++) { + tmp = RAL_READ(sc, RT2860_WPDMA_GLO_CFG); + if ((tmp & (RT2860_TX_DMA_BUSY | RT2860_RX_DMA_BUSY)) == 0) + break; + DELAY(1000); + } + if (ntries == 100) { + device_printf(sc->sc_dev, "timeout waiting for DMA engine\n"); + rt2860_stop_locked(sc); + return; + } + tmp &= 0xff0; + RAL_WRITE(sc, RT2860_WPDMA_GLO_CFG, tmp); + + /* disable interrupts mitigation */ + RAL_WRITE(sc, RT2860_DELAY_INT_CFG, 0); + + /* write vendor-specific BBP values (from EEPROM) */ + for (i = 0; i < 8; i++) { + if (sc->bbp[i].reg == 0 || sc->bbp[i].reg == 0xff) + continue; + rt2860_mcu_bbp_write(sc, sc->bbp[i].reg, sc->bbp[i].val); + } + + /* select Main antenna for 1T1R devices */ + if (sc->rf_rev == RT3070_RF_2020 || + sc->rf_rev == RT3070_RF_3020 || + sc->rf_rev == RT3070_RF_3320) + rt3090_set_rx_antenna(sc, 0); + + /* send LEDs operating mode to microcontroller */ + rt2860_mcu_cmd(sc, RT2860_MCU_CMD_LED1, sc->led[0], 0); + rt2860_mcu_cmd(sc, RT2860_MCU_CMD_LED2, sc->led[1], 0); + rt2860_mcu_cmd(sc, RT2860_MCU_CMD_LED3, sc->led[2], 0); + + if (sc->mac_ver >= 0x3071) + rt3090_rf_init(sc); + + rt2860_mcu_cmd(sc, RT2860_MCU_CMD_SLEEP, 0x02ff, 1); + rt2860_mcu_cmd(sc, RT2860_MCU_CMD_WAKEUP, 0, 1); + + if (sc->mac_ver >= 0x3071) + rt3090_rf_wakeup(sc); + + /* disable non-existing Rx chains */ + bbp3 = rt2860_mcu_bbp_read(sc, 3); + bbp3 &= ~(1 << 3 | 1 << 4); + if (sc->nrxchains == 2) + bbp3 |= 1 << 3; + else if (sc->nrxchains == 3) + bbp3 |= 1 << 4; + rt2860_mcu_bbp_write(sc, 3, bbp3); + + /* disable non-existing Tx chains */ + bbp1 = rt2860_mcu_bbp_read(sc, 1); + if (sc->ntxchains == 1) + bbp1 = (bbp1 & ~(1 << 3 | 1 << 4)); + else if (sc->mac_ver == 0x3593 && sc->ntxchains == 2) + bbp1 = (bbp1 & ~(1 << 4)) | 1 << 3; + else if (sc->mac_ver == 0x3593 && sc->ntxchains == 3) + bbp1 = (bbp1 & ~(1 << 3)) | 1 << 4; + rt2860_mcu_bbp_write(sc, 1, bbp1); + + if (sc->mac_ver >= 0x3071) + rt3090_rf_setup(sc); + + /* select default channel */ + rt2860_switch_chan(sc, ic->ic_curchan); + + /* reset RF from MCU */ + rt2860_mcu_cmd(sc, RT2860_MCU_CMD_RFRESET, 0, 0); + + /* set RTS threshold */ + tmp = RAL_READ(sc, RT2860_TX_RTS_CFG); + tmp &= ~0xffff00; + tmp |= IEEE80211_RTS_DEFAULT << 8; + RAL_WRITE(sc, RT2860_TX_RTS_CFG, tmp); + + /* setup initial protection mode */ + rt2860_updateprot(ifp); + + /* turn radio LED on */ + rt2860_set_leds(sc, RT2860_LED_RADIO); + + /* enable Tx/Rx DMA engine */ + if ((error = rt2860_txrx_enable(sc)) != 0) { + rt2860_stop_locked(sc); + return; + } + + /* clear pending interrupts */ + RAL_WRITE(sc, RT2860_INT_STATUS, 0xffffffff); + /* enable interrupts */ + RAL_WRITE(sc, RT2860_INT_MASK, 0x3fffc); + + if (sc->sc_flags & RT2860_ADVANCED_PS) + rt2860_mcu_cmd(sc, RT2860_MCU_CMD_PSLEVEL, sc->pslevel, 0); + + ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; + ifp->if_drv_flags |= IFF_DRV_RUNNING; + + callout_reset(&sc->watchdog_ch, hz, rt2860_watchdog, sc); +#undef N +} + +static void +rt2860_stop(void *arg) +{ + struct rt2860_softc *sc = arg; + + RAL_LOCK(sc); + rt2860_stop_locked(sc); + RAL_UNLOCK(sc); +} + +static void +rt2860_stop_locked(struct rt2860_softc *sc) +{ + struct ifnet *ifp = sc->sc_ifp; + uint32_t tmp; + int qid; + + if (ifp->if_drv_flags & IFF_DRV_RUNNING) + rt2860_set_leds(sc, 0); /* turn all LEDs off */ + + callout_stop(&sc->watchdog_ch); + sc->sc_tx_timer = 0; + ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); + + /* disable interrupts */ + RAL_WRITE(sc, RT2860_INT_MASK, 0); + + /* disable GP timer */ + rt2860_set_gp_timer(sc, 0); + + /* disable Rx */ + tmp = RAL_READ(sc, RT2860_MAC_SYS_CTRL); + tmp &= ~(RT2860_MAC_RX_EN | RT2860_MAC_TX_EN); + RAL_WRITE(sc, RT2860_MAC_SYS_CTRL, tmp); + + /* reset adapter */ + RAL_WRITE(sc, RT2860_MAC_SYS_CTRL, RT2860_BBP_HRST | RT2860_MAC_SRST); + RAL_BARRIER_WRITE(sc); + RAL_WRITE(sc, RT2860_MAC_SYS_CTRL, 0); + + /* reset Tx and Rx rings (and reclaim TXWIs) */ + sc->qfullmsk = 0; + for (qid = 0; qid < 6; qid++) + rt2860_reset_tx_ring(sc, &sc->txq[qid]); + rt2860_reset_rx_ring(sc, &sc->rxq); +} + +int +rt2860_load_microcode(struct rt2860_softc *sc) +{ + const struct firmware *fp; + int ntries, error; + + RAL_LOCK_ASSERT(sc); + + RAL_UNLOCK(sc); + fp = firmware_get("rt2860fw"); + RAL_LOCK(sc); + if (fp == NULL) { + device_printf(sc->sc_dev, + "unable to receive rt2860fw firmware image\n"); + return EINVAL; + } + + /* set "host program ram write selection" bit */ + RAL_WRITE(sc, RT2860_SYS_CTRL, RT2860_HST_PM_SEL); + /* write microcode image */ + RAL_WRITE_REGION_1(sc, RT2860_FW_BASE, fp->data, fp->datasize); + /* kick microcontroller unit */ + RAL_WRITE(sc, RT2860_SYS_CTRL, 0); + RAL_BARRIER_WRITE(sc); + RAL_WRITE(sc, RT2860_SYS_CTRL, RT2860_MCU_RESET); + + RAL_WRITE(sc, RT2860_H2M_BBPAGENT, 0); + RAL_WRITE(sc, RT2860_H2M_MAILBOX, 0); + + /* wait until microcontroller is ready */ + RAL_BARRIER_READ_WRITE(sc); + for (ntries = 0; ntries < 1000; ntries++) { + if (RAL_READ(sc, RT2860_SYS_CTRL) & RT2860_MCU_READY) + break; + DELAY(1000); + } + if (ntries == 1000) { + device_printf(sc->sc_dev, + "timeout waiting for MCU to initialize\n"); + error = ETIMEDOUT; + } else + error = 0; + + firmware_put(fp, FIRMWARE_UNLOAD); + return error; +} + +/* + * This function is called periodically to adjust Tx power based on + * temperature variation. + */ +#ifdef NOT_YET +static void +rt2860_calib(struct rt2860_softc *sc) +{ + struct ieee80211com *ic = &sc->sc_ic; + const uint8_t *tssi; + uint8_t step, bbp49; + int8_t ridx, d; + + /* read current temperature */ + bbp49 = rt2860_mcu_bbp_read(sc, 49); + + if (IEEE80211_IS_CHAN_2GHZ(ic->ic_bss->ni_chan)) { + tssi = &sc->tssi_2ghz[4]; + step = sc->step_2ghz; + } else { + tssi = &sc->tssi_5ghz[4]; + step = sc->step_5ghz; + } + + if (bbp49 < tssi[0]) { /* lower than reference */ + /* use higher Tx power than default */ + for (d = 0; d > -4 && bbp49 <= tssi[d - 1]; d--); + } else if (bbp49 > tssi[0]) { /* greater than reference */ + /* use lower Tx power than default */ + for (d = 0; d < +4 && bbp49 >= tssi[d + 1]; d++); + } else { + /* use default Tx power */ + d = 0; + } + d *= step; + + DPRINTF(("BBP49=0x%02x, adjusting Tx power by %d\n", bbp49, d)); + + /* write adjusted Tx power values for each Tx rate */ + for (ridx = 0; ridx < 5; ridx++) { + if (sc->txpow20mhz[ridx] == 0xffffffff) + continue; + RAL_WRITE(sc, RT2860_TX_PWR_CFG(ridx), + b4inc(sc->txpow20mhz[ridx], d)); + } +} +#endif + +static void +rt3090_set_rx_antenna(struct rt2860_softc *sc, int aux) +{ + uint32_t tmp; + + if (aux) { + tmp = RAL_READ(sc, RT2860_PCI_EECTRL); + RAL_WRITE(sc, RT2860_PCI_EECTRL, tmp & ~RT2860_C); + tmp = RAL_READ(sc, RT2860_GPIO_CTRL); + RAL_WRITE(sc, RT2860_GPIO_CTRL, (tmp & ~0x0808) | 0x08); + } else { + tmp = RAL_READ(sc, RT2860_PCI_EECTRL); + RAL_WRITE(sc, RT2860_PCI_EECTRL, tmp | RT2860_C); + tmp = RAL_READ(sc, RT2860_GPIO_CTRL); + RAL_WRITE(sc, RT2860_GPIO_CTRL, tmp & ~0x0808); + } +} + +static void +rt2860_switch_chan(struct rt2860_softc *sc, struct ieee80211_channel *c) +{ + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; + u_int chan, group; + + chan = ieee80211_chan2ieee(ic, c); + if (chan == 0 || chan == IEEE80211_CHAN_ANY) + return; + + if (sc->mac_ver >= 0x3071) + rt3090_set_chan(sc, chan); + else + rt2860_set_chan(sc, chan); + + /* determine channel group */ + if (chan <= 14) + group = 0; + else if (chan <= 64) + group = 1; + else if (chan <= 128) + group = 2; + else + group = 3; + + /* XXX necessary only when group has changed! */ + rt2860_select_chan_group(sc, group); + + DELAY(1000); +} + +static int +rt2860_setup_beacon(struct rt2860_softc *sc, struct ieee80211vap *vap) +{ + struct ieee80211com *ic = vap->iv_ic; + struct ieee80211_beacon_offsets bo; + struct rt2860_txwi txwi; + struct mbuf *m; + int ridx; + + if ((m = ieee80211_beacon_alloc(vap->iv_bss, &bo)) == NULL) + return ENOBUFS; + + memset(&txwi, 0, sizeof txwi); + txwi.wcid = 0xff; + txwi.len = htole16(m->m_pkthdr.len); + /* send beacons at the lowest available rate */ + ridx = IEEE80211_IS_CHAN_5GHZ(ic->ic_bsschan) ? + RT2860_RIDX_OFDM6 : RT2860_RIDX_CCK1; + txwi.phy = htole16(rt2860_rates[ridx].mcs); + if (rt2860_rates[ridx].phy == IEEE80211_T_OFDM) + txwi.phy |= htole16(RT2860_PHY_OFDM); + txwi.txop = RT2860_TX_TXOP_HT; + txwi.flags = RT2860_TX_TS; + txwi.xflags = RT2860_TX_NSEQ; + + RAL_WRITE_REGION_1(sc, RT2860_BCN_BASE(0), + (uint8_t *)&txwi, sizeof txwi); + RAL_WRITE_REGION_1(sc, RT2860_BCN_BASE(0) + sizeof txwi, + mtod(m, uint8_t *), m->m_pkthdr.len); + + m_freem(m); + + return 0; +} + +static void +rt2860_enable_tsf_sync(struct rt2860_softc *sc) +{ + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); + uint32_t tmp; + + tmp = RAL_READ(sc, RT2860_BCN_TIME_CFG); + + tmp &= ~0x1fffff; + tmp |= vap->iv_bss->ni_intval * 16; + tmp |= RT2860_TSF_TIMER_EN | RT2860_TBTT_TIMER_EN; + if (vap->iv_opmode == IEEE80211_M_STA) { + /* + * Local TSF is always updated with remote TSF on beacon + * reception. + */ + tmp |= 1 << RT2860_TSF_SYNC_MODE_SHIFT; + } + else if (vap->iv_opmode == IEEE80211_M_IBSS || + vap->iv_opmode == IEEE80211_M_MBSS) { + tmp |= RT2860_BCN_TX_EN; + /* + * Local TSF is updated with remote TSF on beacon reception + * only if the remote TSF is greater than local TSF. + */ + tmp |= 2 << RT2860_TSF_SYNC_MODE_SHIFT; + } else if (vap->iv_opmode == IEEE80211_M_HOSTAP) { + tmp |= RT2860_BCN_TX_EN; + /* SYNC with nobody */ + tmp |= 3 << RT2860_TSF_SYNC_MODE_SHIFT; + } + + RAL_WRITE(sc, RT2860_BCN_TIME_CFG, tmp); +} diff --git a/src/add-ons/kernel/drivers/network/wlan/ralinkwifi/dev/ral/rt2860reg.h b/src/add-ons/kernel/drivers/network/wlan/ralinkwifi/dev/ral/rt2860reg.h new file mode 100644 index 00000000000..06c275d47f0 --- /dev/null +++ b/src/add-ons/kernel/drivers/network/wlan/ralinkwifi/dev/ral/rt2860reg.h @@ -0,0 +1,1255 @@ +/*- + * Copyright (c) 2007 Damien Bergamini + * Copyright (c) 2012 Bernhard Schmidt + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * $OpenBSD: rt2860reg.h,v 1.30 2010/05/10 18:17:10 damien Exp $ + * $FreeBSD$ + */ + +#define RT2860_NOISE_FLOOR -95 + +/* PCI registers */ +#define RT2860_PCI_CFG 0x0000 +#define RT2860_PCI_EECTRL 0x0004 +#define RT2860_PCI_MCUCTRL 0x0008 +#define RT2860_PCI_SYSCTRL 0x000c +#define RT2860_PCIE_JTAG 0x0010 + +#define RT3090_AUX_CTRL 0x010c + +#define RT3070_OPT_14 0x0114 + +/* SCH/DMA registers */ +#define RT2860_INT_STATUS 0x0200 +#define RT2860_INT_MASK 0x0204 +#define RT2860_WPDMA_GLO_CFG 0x0208 +#define RT2860_WPDMA_RST_IDX 0x020c +#define RT2860_DELAY_INT_CFG 0x0210 +#define RT2860_WMM_AIFSN_CFG 0x0214 +#define RT2860_WMM_CWMIN_CFG 0x0218 +#define RT2860_WMM_CWMAX_CFG 0x021c +#define RT2860_WMM_TXOP0_CFG 0x0220 +#define RT2860_WMM_TXOP1_CFG 0x0224 +#define RT2860_GPIO_CTRL 0x0228 +#define RT2860_MCU_CMD_REG 0x022c +#define RT2860_TX_BASE_PTR(qid) (0x0230 + (qid) * 16) +#define RT2860_TX_MAX_CNT(qid) (0x0234 + (qid) * 16) +#define RT2860_TX_CTX_IDX(qid) (0x0238 + (qid) * 16) +#define RT2860_TX_DTX_IDX(qid) (0x023c + (qid) * 16) +#define RT2860_RX_BASE_PTR 0x0290 +#define RT2860_RX_MAX_CNT 0x0294 +#define RT2860_RX_CALC_IDX 0x0298 +#define RT2860_FS_DRX_IDX 0x029c +#define RT2860_USB_DMA_CFG 0x02a0 /* RT2870 only */ +#define RT2860_US_CYC_CNT 0x02a4 + +/* PBF registers */ +#define RT2860_SYS_CTRL 0x0400 +#define RT2860_HOST_CMD 0x0404 +#define RT2860_PBF_CFG 0x0408 +#define RT2860_MAX_PCNT 0x040c +#define RT2860_BUF_CTRL 0x0410 +#define RT2860_MCU_INT_STA 0x0414 +#define RT2860_MCU_INT_ENA 0x0418 +#define RT2860_TXQ_IO(qid) (0x041c + (qid) * 4) +#define RT2860_RX0Q_IO 0x0424 +#define RT2860_BCN_OFFSET0 0x042c +#define RT2860_BCN_OFFSET1 0x0430 +#define RT2860_TXRXQ_STA 0x0434 +#define RT2860_TXRXQ_PCNT 0x0438 +#define RT2860_PBF_DBG 0x043c +#define RT2860_CAP_CTRL 0x0440 + +/* RT3070 registers */ +#define RT3070_RF_CSR_CFG 0x0500 +#define RT3070_EFUSE_CTRL 0x0580 +#define RT3070_EFUSE_DATA0 0x0590 +#define RT3070_EFUSE_DATA1 0x0594 +#define RT3070_EFUSE_DATA2 0x0598 +#define RT3070_EFUSE_DATA3 0x059c +#define RT3090_OSC_CTRL 0x05a4 +#define RT3070_LDO_CFG0 0x05d4 +#define RT3070_GPIO_SWITCH 0x05dc + +/* MAC registers */ +#define RT2860_ASIC_VER_ID 0x1000 +#define RT2860_MAC_SYS_CTRL 0x1004 +#define RT2860_MAC_ADDR_DW0 0x1008 +#define RT2860_MAC_ADDR_DW1 0x100c +#define RT2860_MAC_BSSID_DW0 0x1010 +#define RT2860_MAC_BSSID_DW1 0x1014 +#define RT2860_MAX_LEN_CFG 0x1018 +#define RT2860_BBP_CSR_CFG 0x101c +#define RT2860_RF_CSR_CFG0 0x1020 +#define RT2860_RF_CSR_CFG1 0x1024 +#define RT2860_RF_CSR_CFG2 0x1028 +#define RT2860_LED_CFG 0x102c + +/* undocumented registers */ +#define RT2860_DEBUG 0x10f4 + +/* MAC Timing control registers */ +#define RT2860_XIFS_TIME_CFG 0x1100 +#define RT2860_BKOFF_SLOT_CFG 0x1104 +#define RT2860_NAV_TIME_CFG 0x1108 +#define RT2860_CH_TIME_CFG 0x110c +#define RT2860_PBF_LIFE_TIMER 0x1110 +#define RT2860_BCN_TIME_CFG 0x1114 +#define RT2860_TBTT_SYNC_CFG 0x1118 +#define RT2860_TSF_TIMER_DW0 0x111c +#define RT2860_TSF_TIMER_DW1 0x1120 +#define RT2860_TBTT_TIMER 0x1124 +#define RT2860_INT_TIMER_CFG 0x1128 +#define RT2860_INT_TIMER_EN 0x112c +#define RT2860_CH_IDLE_TIME 0x1130 + +/* MAC Power Save configuration registers */ +#define RT2860_MAC_STATUS_REG 0x1200 +#define RT2860_PWR_PIN_CFG 0x1204 +#define RT2860_AUTO_WAKEUP_CFG 0x1208 + +/* MAC TX configuration registers */ +#define RT2860_EDCA_AC_CFG(aci) (0x1300 + (aci) * 4) +#define RT2860_EDCA_TID_AC_MAP 0x1310 +#define RT2860_TX_PWR_CFG(ridx) (0x1314 + (ridx) * 4) +#define RT2860_TX_PIN_CFG 0x1328 +#define RT2860_TX_BAND_CFG 0x132c +#define RT2860_TX_SW_CFG0 0x1330 +#define RT2860_TX_SW_CFG1 0x1334 +#define RT2860_TX_SW_CFG2 0x1338 +#define RT2860_TXOP_THRES_CFG 0x133c +#define RT2860_TXOP_CTRL_CFG 0x1340 +#define RT2860_TX_RTS_CFG 0x1344 +#define RT2860_TX_TIMEOUT_CFG 0x1348 +#define RT2860_TX_RTY_CFG 0x134c +#define RT2860_TX_LINK_CFG 0x1350 +#define RT2860_HT_FBK_CFG0 0x1354 +#define RT2860_HT_FBK_CFG1 0x1358 +#define RT2860_LG_FBK_CFG0 0x135c +#define RT2860_LG_FBK_CFG1 0x1360 +#define RT2860_CCK_PROT_CFG 0x1364 +#define RT2860_OFDM_PROT_CFG 0x1368 +#define RT2860_MM20_PROT_CFG 0x136c +#define RT2860_MM40_PROT_CFG 0x1370 +#define RT2860_GF20_PROT_CFG 0x1374 +#define RT2860_GF40_PROT_CFG 0x1378 +#define RT2860_EXP_CTS_TIME 0x137c +#define RT2860_EXP_ACK_TIME 0x1380 + +/* MAC RX configuration registers */ +#define RT2860_RX_FILTR_CFG 0x1400 +#define RT2860_AUTO_RSP_CFG 0x1404 +#define RT2860_LEGACY_BASIC_RATE 0x1408 +#define RT2860_HT_BASIC_RATE 0x140c +#define RT2860_HT_CTRL_CFG 0x1410 +#define RT2860_SIFS_COST_CFG 0x1414 +#define RT2860_RX_PARSER_CFG 0x1418 + +/* MAC Security configuration registers */ +#define RT2860_TX_SEC_CNT0 0x1500 +#define RT2860_RX_SEC_CNT0 0x1504 +#define RT2860_CCMP_FC_MUTE 0x1508 + +/* MAC HCCA/PSMP configuration registers */ +#define RT2860_TXOP_HLDR_ADDR0 0x1600 +#define RT2860_TXOP_HLDR_ADDR1 0x1604 +#define RT2860_TXOP_HLDR_ET 0x1608 +#define RT2860_QOS_CFPOLL_RA_DW0 0x160c +#define RT2860_QOS_CFPOLL_A1_DW1 0x1610 +#define RT2860_QOS_CFPOLL_QC 0x1614 + +/* MAC Statistics Counters */ +#define RT2860_RX_STA_CNT0 0x1700 +#define RT2860_RX_STA_CNT1 0x1704 +#define RT2860_RX_STA_CNT2 0x1708 +#define RT2860_TX_STA_CNT0 0x170c +#define RT2860_TX_STA_CNT1 0x1710 +#define RT2860_TX_STA_CNT2 0x1714 +#define RT2860_TX_STAT_FIFO 0x1718 + +/* RX WCID search table */ +#define RT2860_WCID_ENTRY(wcid) (0x1800 + (wcid) * 8) + +#define RT2860_FW_BASE 0x2000 +#define RT2870_FW_BASE 0x3000 + +/* Pair-wise key table */ +#define RT2860_PKEY(wcid) (0x4000 + (wcid) * 32) + +/* IV/EIV table */ +#define RT2860_IVEIV(wcid) (0x6000 + (wcid) * 8) + +/* WCID attribute table */ +#define RT2860_WCID_ATTR(wcid) (0x6800 + (wcid) * 4) + +/* Shared Key Table */ +#define RT2860_SKEY(vap, kidx) (0x6c00 + (vap) * 128 + (kidx) * 32) + +/* Shared Key Mode */ +#define RT2860_SKEY_MODE_0_7 0x7000 +#define RT2860_SKEY_MODE_8_15 0x7004 +#define RT2860_SKEY_MODE_16_23 0x7008 +#define RT2860_SKEY_MODE_24_31 0x700c + +/* Shared Memory between MCU and host */ +#define RT2860_H2M_MAILBOX 0x7010 +#define RT2860_H2M_MAILBOX_CID 0x7014 +#define RT2860_H2M_MAILBOX_STATUS 0x701c +#define RT2860_H2M_BBPAGENT 0x7028 +#define RT2860_BCN_BASE(vap) (0x7800 + (vap) * 512) + + +/* possible flags for RT2860_PCI_CFG */ +#define RT2860_PCI_CFG_USB (1 << 17) +#define RT2860_PCI_CFG_PCI (1 << 16) + +/* possible flags for register RT2860_PCI_EECTRL */ +#define RT2860_C (1 << 0) +#define RT2860_S (1 << 1) +#define RT2860_D (1 << 2) +#define RT2860_SHIFT_D 2 +#define RT2860_Q (1 << 3) +#define RT2860_SHIFT_Q 3 + +/* possible flags for registers INT_STATUS/INT_MASK */ +#define RT2860_TX_COHERENT (1 << 17) +#define RT2860_RX_COHERENT (1 << 16) +#define RT2860_MAC_INT_4 (1 << 15) +#define RT2860_MAC_INT_3 (1 << 14) +#define RT2860_MAC_INT_2 (1 << 13) +#define RT2860_MAC_INT_1 (1 << 12) +#define RT2860_MAC_INT_0 (1 << 11) +#define RT2860_TX_RX_COHERENT (1 << 10) +#define RT2860_MCU_CMD_INT (1 << 9) +#define RT2860_TX_DONE_INT5 (1 << 8) +#define RT2860_TX_DONE_INT4 (1 << 7) +#define RT2860_TX_DONE_INT3 (1 << 6) +#define RT2860_TX_DONE_INT2 (1 << 5) +#define RT2860_TX_DONE_INT1 (1 << 4) +#define RT2860_TX_DONE_INT0 (1 << 3) +#define RT2860_RX_DONE_INT (1 << 2) +#define RT2860_TX_DLY_INT (1 << 1) +#define RT2860_RX_DLY_INT (1 << 0) + +/* possible flags for register WPDMA_GLO_CFG */ +#define RT2860_HDR_SEG_LEN_SHIFT 8 +#define RT2860_BIG_ENDIAN (1 << 7) +#define RT2860_TX_WB_DDONE (1 << 6) +#define RT2860_WPDMA_BT_SIZE_SHIFT 4 +#define RT2860_WPDMA_BT_SIZE16 0 +#define RT2860_WPDMA_BT_SIZE32 1 +#define RT2860_WPDMA_BT_SIZE64 2 +#define RT2860_WPDMA_BT_SIZE128 3 +#define RT2860_RX_DMA_BUSY (1 << 3) +#define RT2860_RX_DMA_EN (1 << 2) +#define RT2860_TX_DMA_BUSY (1 << 1) +#define RT2860_TX_DMA_EN (1 << 0) + +/* possible flags for register DELAY_INT_CFG */ +#define RT2860_TXDLY_INT_EN (1 << 31) +#define RT2860_TXMAX_PINT_SHIFT 24 +#define RT2860_TXMAX_PTIME_SHIFT 16 +#define RT2860_RXDLY_INT_EN (1 << 15) +#define RT2860_RXMAX_PINT_SHIFT 8 +#define RT2860_RXMAX_PTIME_SHIFT 0 + +/* possible flags for register GPIO_CTRL */ +#define RT2860_GPIO_D_SHIFT 8 +#define RT2860_GPIO_O_SHIFT 0 + +/* possible flags for register USB_DMA_CFG */ +#define RT2860_USB_TX_BUSY (1 << 31) +#define RT2860_USB_RX_BUSY (1 << 30) +#define RT2860_USB_EPOUT_VLD_SHIFT 24 +#define RT2860_USB_TX_EN (1 << 23) +#define RT2860_USB_RX_EN (1 << 22) +#define RT2860_USB_RX_AGG_EN (1 << 21) +#define RT2860_USB_TXOP_HALT (1 << 20) +#define RT2860_USB_TX_CLEAR (1 << 19) +#define RT2860_USB_PHY_WD_EN (1 << 16) +#define RT2860_USB_PHY_MAN_RST (1 << 15) +#define RT2860_USB_RX_AGG_LMT(x) ((x) << 8) /* in unit of 1KB */ +#define RT2860_USB_RX_AGG_TO(x) ((x) & 0xff) /* in unit of 33ns */ + +/* possible flags for register US_CYC_CNT */ +#define RT2860_TEST_EN (1 << 24) +#define RT2860_TEST_SEL_SHIFT 16 +#define RT2860_BT_MODE_EN (1 << 8) +#define RT2860_US_CYC_CNT_SHIFT 0 + +/* possible flags for register SYS_CTRL */ +#define RT2860_HST_PM_SEL (1 << 16) +#define RT2860_CAP_MODE (1 << 14) +#define RT2860_PME_OEN (1 << 13) +#define RT2860_CLKSELECT (1 << 12) +#define RT2860_PBF_CLK_EN (1 << 11) +#define RT2860_MAC_CLK_EN (1 << 10) +#define RT2860_DMA_CLK_EN (1 << 9) +#define RT2860_MCU_READY (1 << 7) +#define RT2860_ASY_RESET (1 << 4) +#define RT2860_PBF_RESET (1 << 3) +#define RT2860_MAC_RESET (1 << 2) +#define RT2860_DMA_RESET (1 << 1) +#define RT2860_MCU_RESET (1 << 0) + +/* possible values for register HOST_CMD */ +#define RT2860_MCU_CMD_SLEEP 0x30 +#define RT2860_MCU_CMD_WAKEUP 0x31 +#define RT2860_MCU_CMD_LEDS 0x50 +#define RT2860_MCU_CMD_LED_RSSI 0x51 +#define RT2860_MCU_CMD_LED1 0x52 +#define RT2860_MCU_CMD_LED2 0x53 +#define RT2860_MCU_CMD_LED3 0x54 +#define RT2860_MCU_CMD_RFRESET 0x72 +#define RT2860_MCU_CMD_ANTSEL 0x73 +#define RT2860_MCU_CMD_BBP 0x80 +#define RT2860_MCU_CMD_PSLEVEL 0x83 + +/* possible flags for register PBF_CFG */ +#define RT2860_TX1Q_NUM_SHIFT 21 +#define RT2860_TX2Q_NUM_SHIFT 16 +#define RT2860_NULL0_MODE (1 << 15) +#define RT2860_NULL1_MODE (1 << 14) +#define RT2860_RX_DROP_MODE (1 << 13) +#define RT2860_TX0Q_MANUAL (1 << 12) +#define RT2860_TX1Q_MANUAL (1 << 11) +#define RT2860_TX2Q_MANUAL (1 << 10) +#define RT2860_RX0Q_MANUAL (1 << 9) +#define RT2860_HCCA_EN (1 << 8) +#define RT2860_TX0Q_EN (1 << 4) +#define RT2860_TX1Q_EN (1 << 3) +#define RT2860_TX2Q_EN (1 << 2) +#define RT2860_RX0Q_EN (1 << 1) + +/* possible flags for register BUF_CTRL */ +#define RT2860_WRITE_TXQ(qid) (1 << (11 - (qid))) +#define RT2860_NULL0_KICK (1 << 7) +#define RT2860_NULL1_KICK (1 << 6) +#define RT2860_BUF_RESET (1 << 5) +#define RT2860_READ_TXQ(qid) (1 << (3 - (qid)) +#define RT2860_READ_RX0Q (1 << 0) + +/* possible flags for registers MCU_INT_STA/MCU_INT_ENA */ +#define RT2860_MCU_MAC_INT_8 (1 << 24) +#define RT2860_MCU_MAC_INT_7 (1 << 23) +#define RT2860_MCU_MAC_INT_6 (1 << 22) +#define RT2860_MCU_MAC_INT_4 (1 << 20) +#define RT2860_MCU_MAC_INT_3 (1 << 19) +#define RT2860_MCU_MAC_INT_2 (1 << 18) +#define RT2860_MCU_MAC_INT_1 (1 << 17) +#define RT2860_MCU_MAC_INT_0 (1 << 16) +#define RT2860_DTX0_INT (1 << 11) +#define RT2860_DTX1_INT (1 << 10) +#define RT2860_DTX2_INT (1 << 9) +#define RT2860_DRX0_INT (1 << 8) +#define RT2860_HCMD_INT (1 << 7) +#define RT2860_N0TX_INT (1 << 6) +#define RT2860_N1TX_INT (1 << 5) +#define RT2860_BCNTX_INT (1 << 4) +#define RT2860_MTX0_INT (1 << 3) +#define RT2860_MTX1_INT (1 << 2) +#define RT2860_MTX2_INT (1 << 1) +#define RT2860_MRX0_INT (1 << 0) + +/* possible flags for register TXRXQ_PCNT */ +#define RT2860_RX0Q_PCNT_MASK 0xff000000 +#define RT2860_TX2Q_PCNT_MASK 0x00ff0000 +#define RT2860_TX1Q_PCNT_MASK 0x0000ff00 +#define RT2860_TX0Q_PCNT_MASK 0x000000ff + +/* possible flags for register CAP_CTRL */ +#define RT2860_CAP_ADC_FEQ (1 << 31) +#define RT2860_CAP_START (1 << 30) +#define RT2860_MAN_TRIG (1 << 29) +#define RT2860_TRIG_OFFSET_SHIFT 16 +#define RT2860_START_ADDR_SHIFT 0 + +/* possible flags for register RF_CSR_CFG */ +#define RT3070_RF_KICK (1 << 17) +#define RT3070_RF_WRITE (1 << 16) + +/* possible flags for register EFUSE_CTRL */ +#define RT3070_SEL_EFUSE (1 << 31) +#define RT3070_EFSROM_KICK (1 << 30) +#define RT3070_EFSROM_AIN_MASK 0x03ff0000 +#define RT3070_EFSROM_AIN_SHIFT 16 +#define RT3070_EFSROM_MODE_MASK 0x000000c0 +#define RT3070_EFUSE_AOUT_MASK 0x0000003f + +/* possible flags for register MAC_SYS_CTRL */ +#define RT2860_RX_TS_EN (1 << 7) +#define RT2860_WLAN_HALT_EN (1 << 6) +#define RT2860_PBF_LOOP_EN (1 << 5) +#define RT2860_CONT_TX_TEST (1 << 4) +#define RT2860_MAC_RX_EN (1 << 3) +#define RT2860_MAC_TX_EN (1 << 2) +#define RT2860_BBP_HRST (1 << 1) +#define RT2860_MAC_SRST (1 << 0) + +/* possible flags for register MAC_BSSID_DW1 */ +#define RT2860_MULTI_BCN_NUM_SHIFT 18 +#define RT2860_MULTI_BSSID_MODE_SHIFT 16 + +/* possible flags for register MAX_LEN_CFG */ +#define RT2860_MIN_MPDU_LEN_SHIFT 16 +#define RT2860_MAX_PSDU_LEN_SHIFT 12 +#define RT2860_MAX_PSDU_LEN8K 0 +#define RT2860_MAX_PSDU_LEN16K 1 +#define RT2860_MAX_PSDU_LEN32K 2 +#define RT2860_MAX_PSDU_LEN64K 3 +#define RT2860_MAX_MPDU_LEN_SHIFT 0 + +/* possible flags for registers BBP_CSR_CFG/H2M_BBPAGENT */ +#define RT2860_BBP_RW_PARALLEL (1 << 19) +#define RT2860_BBP_PAR_DUR_112_5 (1 << 18) +#define RT2860_BBP_CSR_KICK (1 << 17) +#define RT2860_BBP_CSR_READ (1 << 16) +#define RT2860_BBP_ADDR_SHIFT 8 +#define RT2860_BBP_DATA_SHIFT 0 + +/* possible flags for register RF_CSR_CFG0 */ +#define RT2860_RF_REG_CTRL (1 << 31) +#define RT2860_RF_LE_SEL1 (1 << 30) +#define RT2860_RF_LE_STBY (1 << 29) +#define RT2860_RF_REG_WIDTH_SHIFT 24 +#define RT2860_RF_REG_0_SHIFT 0 + +/* possible flags for register RF_CSR_CFG1 */ +#define RT2860_RF_DUR_5 (1 << 24) +#define RT2860_RF_REG_1_SHIFT 0 + +/* possible flags for register LED_CFG */ +#define RT2860_LED_POL (1 << 30) +#define RT2860_Y_LED_MODE_SHIFT 28 +#define RT2860_G_LED_MODE_SHIFT 26 +#define RT2860_R_LED_MODE_SHIFT 24 +#define RT2860_LED_MODE_OFF 0 +#define RT2860_LED_MODE_BLINK_TX 1 +#define RT2860_LED_MODE_SLOW_BLINK 2 +#define RT2860_LED_MODE_ON 3 +#define RT2860_SLOW_BLK_TIME_SHIFT 16 +#define RT2860_LED_OFF_TIME_SHIFT 8 +#define RT2860_LED_ON_TIME_SHIFT 0 + +/* possible flags for register XIFS_TIME_CFG */ +#define RT2860_BB_RXEND_EN (1 << 29) +#define RT2860_EIFS_TIME_SHIFT 20 +#define RT2860_OFDM_XIFS_TIME_SHIFT 16 +#define RT2860_OFDM_SIFS_TIME_SHIFT 8 +#define RT2860_CCK_SIFS_TIME_SHIFT 0 + +/* possible flags for register BKOFF_SLOT_CFG */ +#define RT2860_CC_DELAY_TIME_SHIFT 8 +#define RT2860_SLOT_TIME 0 + +/* possible flags for register NAV_TIME_CFG */ +#define RT2860_NAV_UPD (1 << 31) +#define RT2860_NAV_UPD_VAL_SHIFT 16 +#define RT2860_NAV_CLR_EN (1 << 15) +#define RT2860_NAV_TIMER_SHIFT 0 + +/* possible flags for register CH_TIME_CFG */ +#define RT2860_EIFS_AS_CH_BUSY (1 << 4) +#define RT2860_NAV_AS_CH_BUSY (1 << 3) +#define RT2860_RX_AS_CH_BUSY (1 << 2) +#define RT2860_TX_AS_CH_BUSY (1 << 1) +#define RT2860_CH_STA_TIMER_EN (1 << 0) + +/* possible values for register BCN_TIME_CFG */ +#define RT2860_TSF_INS_COMP_SHIFT 24 +#define RT2860_BCN_TX_EN (1 << 20) +#define RT2860_TBTT_TIMER_EN (1 << 19) +#define RT2860_TSF_SYNC_MODE_SHIFT 17 +#define RT2860_TSF_SYNC_MODE_DIS 0 +#define RT2860_TSF_SYNC_MODE_STA 1 +#define RT2860_TSF_SYNC_MODE_IBSS 2 +#define RT2860_TSF_SYNC_MODE_HOSTAP 3 +#define RT2860_TSF_TIMER_EN (1 << 16) +#define RT2860_BCN_INTVAL_SHIFT 0 + +/* possible flags for register TBTT_SYNC_CFG */ +#define RT2860_BCN_CWMIN_SHIFT 20 +#define RT2860_BCN_AIFSN_SHIFT 16 +#define RT2860_BCN_EXP_WIN_SHIFT 8 +#define RT2860_TBTT_ADJUST_SHIFT 0 + +/* possible flags for register INT_TIMER_CFG */ +#define RT2860_GP_TIMER_SHIFT 16 +#define RT2860_PRE_TBTT_TIMER_SHIFT 0 + +/* possible flags for register INT_TIMER_EN */ +#define RT2860_GP_TIMER_EN (1 << 1) +#define RT2860_PRE_TBTT_INT_EN (1 << 0) + +/* possible flags for register MAC_STATUS_REG */ +#define RT2860_RX_STATUS_BUSY (1 << 1) +#define RT2860_TX_STATUS_BUSY (1 << 0) + +/* possible flags for register PWR_PIN_CFG */ +#define RT2860_IO_ADDA_PD (1 << 3) +#define RT2860_IO_PLL_PD (1 << 2) +#define RT2860_IO_RA_PE (1 << 1) +#define RT2860_IO_RF_PE (1 << 0) + +/* possible flags for register AUTO_WAKEUP_CFG */ +#define RT2860_AUTO_WAKEUP_EN (1 << 15) +#define RT2860_SLEEP_TBTT_NUM_SHIFT 8 +#define RT2860_WAKEUP_LEAD_TIME_SHIFT 0 + +/* possible flags for register TX_PIN_CFG */ +#define RT3593_LNA_PE_G2_POL (1 << 31) +#define RT3593_LNA_PE_A2_POL (1 << 30) +#define RT3593_LNA_PE_G2_EN (1 << 29) +#define RT3593_LNA_PE_A2_EN (1 << 28) +#define RT3593_LNA_PE2_EN (RT3593_LNA_PE_A2_EN | RT3593_LNA_PE_G2_EN) +#define RT3593_PA_PE_G2_POL (1 << 27) +#define RT3593_PA_PE_A2_POL (1 << 26) +#define RT3593_PA_PE_G2_EN (1 << 25) +#define RT3593_PA_PE_A2_EN (1 << 24) +#define RT2860_TRSW_POL (1 << 19) +#define RT2860_TRSW_EN (1 << 18) +#define RT2860_RFTR_POL (1 << 17) +#define RT2860_RFTR_EN (1 << 16) +#define RT2860_LNA_PE_G1_POL (1 << 15) +#define RT2860_LNA_PE_A1_POL (1 << 14) +#define RT2860_LNA_PE_G0_POL (1 << 13) +#define RT2860_LNA_PE_A0_POL (1 << 12) +#define RT2860_LNA_PE_G1_EN (1 << 11) +#define RT2860_LNA_PE_A1_EN (1 << 10) +#define RT2860_LNA_PE1_EN (RT2860_LNA_PE_A1_EN | RT2860_LNA_PE_G1_EN) +#define RT2860_LNA_PE_G0_EN (1 << 9) +#define RT2860_LNA_PE_A0_EN (1 << 8) +#define RT2860_LNA_PE0_EN (RT2860_LNA_PE_A0_EN | RT2860_LNA_PE_G0_EN) +#define RT2860_PA_PE_G1_POL (1 << 7) +#define RT2860_PA_PE_A1_POL (1 << 6) +#define RT2860_PA_PE_G0_POL (1 << 5) +#define RT2860_PA_PE_A0_POL (1 << 4) +#define RT2860_PA_PE_G1_EN (1 << 3) +#define RT2860_PA_PE_A1_EN (1 << 2) +#define RT2860_PA_PE_G0_EN (1 << 1) +#define RT2860_PA_PE_A0_EN (1 << 0) + +/* possible flags for register TX_BAND_CFG */ +#define RT2860_5G_BAND_SEL_N (1 << 2) +#define RT2860_5G_BAND_SEL_P (1 << 1) +#define RT2860_TX_BAND_SEL (1 << 0) + +/* possible flags for register TX_SW_CFG0 */ +#define RT2860_DLY_RFTR_EN_SHIFT 24 +#define RT2860_DLY_TRSW_EN_SHIFT 16 +#define RT2860_DLY_PAPE_EN_SHIFT 8 +#define RT2860_DLY_TXPE_EN_SHIFT 0 + +/* possible flags for register TX_SW_CFG1 */ +#define RT2860_DLY_RFTR_DIS_SHIFT 16 +#define RT2860_DLY_TRSW_DIS_SHIFT 8 +#define RT2860_DLY_PAPE_DIS SHIFT 0 + +/* possible flags for register TX_SW_CFG2 */ +#define RT2860_DLY_LNA_EN_SHIFT 24 +#define RT2860_DLY_LNA_DIS_SHIFT 16 +#define RT2860_DLY_DAC_EN_SHIFT 8 +#define RT2860_DLY_DAC_DIS_SHIFT 0 + +/* possible flags for register TXOP_THRES_CFG */ +#define RT2860_TXOP_REM_THRES_SHIFT 24 +#define RT2860_CF_END_THRES_SHIFT 16 +#define RT2860_RDG_IN_THRES 8 +#define RT2860_RDG_OUT_THRES 0 + +/* possible flags for register TXOP_CTRL_CFG */ +#define RT2860_EXT_CW_MIN_SHIFT 16 +#define RT2860_EXT_CCA_DLY_SHIFT 8 +#define RT2860_EXT_CCA_EN (1 << 7) +#define RT2860_LSIG_TXOP_EN (1 << 6) +#define RT2860_TXOP_TRUN_EN_MIMOPS (1 << 4) +#define RT2860_TXOP_TRUN_EN_TXOP (1 << 3) +#define RT2860_TXOP_TRUN_EN_RATE (1 << 2) +#define RT2860_TXOP_TRUN_EN_AC (1 << 1) +#define RT2860_TXOP_TRUN_EN_TIMEOUT (1 << 0) + +/* possible flags for register TX_RTS_CFG */ +#define RT2860_RTS_FBK_EN (1 << 24) +#define RT2860_RTS_THRES_SHIFT 8 +#define RT2860_RTS_RTY_LIMIT_SHIFT 0 + +/* possible flags for register TX_TIMEOUT_CFG */ +#define RT2860_TXOP_TIMEOUT_SHIFT 16 +#define RT2860_RX_ACK_TIMEOUT_SHIFT 8 +#define RT2860_MPDU_LIFE_TIME_SHIFT 4 + +/* possible flags for register TX_RTY_CFG */ +#define RT2860_TX_AUTOFB_EN (1 << 30) +#define RT2860_AGG_RTY_MODE_TIMER (1 << 29) +#define RT2860_NAG_RTY_MODE_TIMER (1 << 28) +#define RT2860_LONG_RTY_THRES_SHIFT 16 +#define RT2860_LONG_RTY_LIMIT_SHIFT 8 +#define RT2860_SHORT_RTY_LIMIT_SHIFT 0 + +/* possible flags for register TX_LINK_CFG */ +#define RT2860_REMOTE_MFS_SHIFT 24 +#define RT2860_REMOTE_MFB_SHIFT 16 +#define RT2860_TX_CFACK_EN (1 << 12) +#define RT2860_TX_RDG_EN (1 << 11) +#define RT2860_TX_MRQ_EN (1 << 10) +#define RT2860_REMOTE_UMFS_EN (1 << 9) +#define RT2860_TX_MFB_EN (1 << 8) +#define RT2860_REMOTE_MFB_LT_SHIFT 0 + +/* possible flags for registers *_PROT_CFG */ +#define RT2860_RTSTH_EN (1 << 26) +#define RT2860_TXOP_ALLOW_GF40 (1 << 25) +#define RT2860_TXOP_ALLOW_GF20 (1 << 24) +#define RT2860_TXOP_ALLOW_MM40 (1 << 23) +#define RT2860_TXOP_ALLOW_MM20 (1 << 22) +#define RT2860_TXOP_ALLOW_OFDM (1 << 21) +#define RT2860_TXOP_ALLOW_CCK (1 << 20) +#define RT2860_TXOP_ALLOW_ALL (0x3f << 20) +#define RT2860_PROT_NAV_SHORT (1 << 18) +#define RT2860_PROT_NAV_LONG (2 << 18) +#define RT2860_PROT_CTRL_RTS_CTS (1 << 16) +#define RT2860_PROT_CTRL_CTS (2 << 16) + +/* possible flags for registers EXP_{CTS,ACK}_TIME */ +#define RT2860_EXP_OFDM_TIME_SHIFT 16 +#define RT2860_EXP_CCK_TIME_SHIFT 0 + +/* possible flags for register RX_FILTR_CFG */ +#define RT2860_DROP_CTRL_RSV (1 << 16) +#define RT2860_DROP_BAR (1 << 15) +#define RT2860_DROP_BA (1 << 14) +#define RT2860_DROP_PSPOLL (1 << 13) +#define RT2860_DROP_RTS (1 << 12) +#define RT2860_DROP_CTS (1 << 11) +#define RT2860_DROP_ACK (1 << 10) +#define RT2860_DROP_CFEND (1 << 9) +#define RT2860_DROP_CFACK (1 << 8) +#define RT2860_DROP_DUPL (1 << 7) +#define RT2860_DROP_BC (1 << 6) +#define RT2860_DROP_MC (1 << 5) +#define RT2860_DROP_VER_ERR (1 << 4) +#define RT2860_DROP_NOT_MYBSS (1 << 3) +#define RT2860_DROP_UC_NOME (1 << 2) +#define RT2860_DROP_PHY_ERR (1 << 1) +#define RT2860_DROP_CRC_ERR (1 << 0) + +/* possible flags for register AUTO_RSP_CFG */ +#define RT2860_CTRL_PWR_BIT (1 << 7) +#define RT2860_BAC_ACK_POLICY (1 << 6) +#define RT2860_CCK_SHORT_EN (1 << 4) +#define RT2860_CTS_40M_REF_EN (1 << 3) +#define RT2860_CTS_40M_MODE_EN (1 << 2) +#define RT2860_BAC_ACKPOLICY_EN (1 << 1) +#define RT2860_AUTO_RSP_EN (1 << 0) + +/* possible flags for register SIFS_COST_CFG */ +#define RT2860_OFDM_SIFS_COST_SHIFT 8 +#define RT2860_CCK_SIFS_COST_SHIFT 0 + +/* possible flags for register TXOP_HLDR_ET */ +#define RT2860_TXOP_ETM1_EN (1 << 25) +#define RT2860_TXOP_ETM0_EN (1 << 24) +#define RT2860_TXOP_ETM_THRES_SHIFT 16 +#define RT2860_TXOP_ETO_EN (1 << 8) +#define RT2860_TXOP_ETO_THRES_SHIFT 1 +#define RT2860_PER_RX_RST_EN (1 << 0) + +/* possible flags for register TX_STAT_FIFO */ +#define RT2860_TXQ_MCS_SHIFT 16 +#define RT2860_TXQ_WCID_SHIFT 8 +#define RT2860_TXQ_ACKREQ (1 << 7) +#define RT2860_TXQ_AGG (1 << 6) +#define RT2860_TXQ_OK (1 << 5) +#define RT2860_TXQ_PID_SHIFT 1 +#define RT2860_TXQ_VLD (1 << 0) + +/* possible flags for register WCID_ATTR */ +#define RT2860_MODE_NOSEC 0 +#define RT2860_MODE_WEP40 1 +#define RT2860_MODE_WEP104 2 +#define RT2860_MODE_TKIP 3 +#define RT2860_MODE_AES_CCMP 4 +#define RT2860_MODE_CKIP40 5 +#define RT2860_MODE_CKIP104 6 +#define RT2860_MODE_CKIP128 7 +#define RT2860_RX_PKEY_EN (1 << 0) + +/* possible flags for register H2M_MAILBOX */ +#define RT2860_H2M_BUSY (1 << 24) +#define RT2860_TOKEN_NO_INTR 0xff + + +/* possible flags for MCU command RT2860_MCU_CMD_LEDS */ +#define RT2860_LED_RADIO (1 << 13) +#define RT2860_LED_LINK_2GHZ (1 << 14) +#define RT2860_LED_LINK_5GHZ (1 << 15) + + +/* possible flags for RT3020 RF register 1 */ +#define RT3070_RF_BLOCK (1 << 0) +#define RT3070_RX0_PD (1 << 2) +#define RT3070_TX0_PD (1 << 3) +#define RT3070_RX1_PD (1 << 4) +#define RT3070_TX1_PD (1 << 5) +#define RT3070_RX2_PD (1 << 6) +#define RT3070_TX2_PD (1 << 7) + +/* possible flags for RT3020 RF register 7 */ +#define RT3070_TUNE (1 << 0) + +/* possible flags for RT3020 RF register 15 */ +#define RT3070_TX_LO2 (1 << 3) + +/* possible flags for RT3020 RF register 17 */ +#define RT3070_TX_LO1 (1 << 3) + +/* possible flags for RT3020 RF register 20 */ +#define RT3070_RX_LO1 (1 << 3) + +/* possible flags for RT3020 RF register 21 */ +#define RT3070_RX_LO2 (1 << 3) +#define RT3070_RX_CTB (1 << 7) + +/* possible flags for RT3020 RF register 22 */ +#define RT3070_BB_LOOPBACK (1 << 0) + +/* possible flags for RT3053 RF register 1 */ +#define RT3593_VCO (1 << 0) + +/* possible flags for RT3053 RF register 2 */ +#define RT3593_RESCAL (1 << 7) + +/* possible flags for RT3053 RF register 3 */ +#define RT3593_VCOCAL (1 << 7) + +/* possible flags for RT3053 RF register 6 */ +#define RT3593_VCO_IC (1 << 6) + +/* possible flags for RT3053 RF register 20 */ +#define RT3593_LDO_PLL_VC_MASK 0x0e +#define RT3593_LDO_RF_VC_MASK 0xe0 + +/* possible flags for RT3053 RF register 22 */ +#define RT3593_CP_IC_MASK 0xe0 +#define RT3593_CP_IC_SHIFT 5 + +/* possible flags for RT3053 RF register 46 */ +#define RT3593_RX_CTB (1 << 5) + +#define RT3090_DEF_LNA 10 + +/* RT2860 TX descriptor */ +struct rt2860_txd { + uint32_t sdp0; /* Segment Data Pointer 0 */ + uint16_t sdl1; /* Segment Data Length 1 */ +#define RT2860_TX_BURST (1 << 15) +#define RT2860_TX_LS1 (1 << 14) /* SDP1 is the last segment */ + + uint16_t sdl0; /* Segment Data Length 0 */ +#define RT2860_TX_DDONE (1 << 15) +#define RT2860_TX_LS0 (1 << 14) /* SDP0 is the last segment */ + + uint32_t sdp1; /* Segment Data Pointer 1 */ + uint8_t reserved[3]; + uint8_t flags; +#define RT2860_TX_QSEL_SHIFT 1 +#define RT2860_TX_QSEL_MGMT (0 << 1) +#define RT2860_TX_QSEL_HCCA (1 << 1) +#define RT2860_TX_QSEL_EDCA (2 << 1) +#define RT2860_TX_WIV (1 << 0) +} __packed; + +/* RT2870 TX descriptor */ +struct rt2870_txd { + uint16_t len; + uint8_t pad; + uint8_t flags; +} __packed; + +/* TX Wireless Information */ +struct rt2860_txwi { + uint8_t flags; +#define RT2860_TX_MPDU_DSITY_SHIFT 5 +#define RT2860_TX_AMPDU (1 << 4) +#define RT2860_TX_TS (1 << 3) +#define RT2860_TX_CFACK (1 << 2) +#define RT2860_TX_MMPS (1 << 1) +#define RT2860_TX_FRAG (1 << 0) + + uint8_t txop; +#define RT2860_TX_TXOP_HT 0 +#define RT2860_TX_TXOP_PIFS 1 +#define RT2860_TX_TXOP_SIFS 2 +#define RT2860_TX_TXOP_BACKOFF 3 + + uint16_t phy; +#define RT2860_PHY_MODE 0xc000 +#define RT2860_PHY_CCK (0 << 14) +#define RT2860_PHY_OFDM (1 << 14) +#define RT2860_PHY_HT (2 << 14) +#define RT2860_PHY_HT_GF (3 << 14) +#define RT2860_PHY_SGI (1 << 8) +#define RT2860_PHY_BW40 (1 << 7) +#define RT2860_PHY_MCS 0x7f +#define RT2860_PHY_SHPRE (1 << 3) + + uint8_t xflags; +#define RT2860_TX_BAWINSIZE_SHIFT 2 +#define RT2860_TX_NSEQ (1 << 1) +#define RT2860_TX_ACK (1 << 0) + + uint8_t wcid; /* Wireless Client ID */ + uint16_t len; +#define RT2860_TX_PID_SHIFT 12 + + uint32_t iv; + uint32_t eiv; +} __packed; + +/* RT2860 RX descriptor */ +struct rt2860_rxd { + uint32_t sdp0; + uint16_t sdl1; /* unused */ + uint16_t sdl0; +#define RT2860_RX_DDONE (1 << 15) +#define RT2860_RX_LS0 (1 << 14) + + uint32_t sdp1; /* unused */ + uint32_t flags; +#define RT2860_RX_DEC (1 << 16) +#define RT2860_RX_AMPDU (1 << 15) +#define RT2860_RX_L2PAD (1 << 14) +#define RT2860_RX_RSSI (1 << 13) +#define RT2860_RX_HTC (1 << 12) +#define RT2860_RX_AMSDU (1 << 11) +#define RT2860_RX_MICERR (1 << 10) +#define RT2860_RX_ICVERR (1 << 9) +#define RT2860_RX_CRCERR (1 << 8) +#define RT2860_RX_MYBSS (1 << 7) +#define RT2860_RX_BC (1 << 6) +#define RT2860_RX_MC (1 << 5) +#define RT2860_RX_UC2ME (1 << 4) +#define RT2860_RX_FRAG (1 << 3) +#define RT2860_RX_NULL (1 << 2) +#define RT2860_RX_DATA (1 << 1) +#define RT2860_RX_BA (1 << 0) +} __packed; + +/* RT2870 RX descriptor */ +struct rt2870_rxd { + /* single 32-bit field */ + uint32_t flags; +} __packed; + +/* RX Wireless Information */ +struct rt2860_rxwi { + uint8_t wcid; + uint8_t keyidx; +#define RT2860_RX_UDF_SHIFT 5 +#define RT2860_RX_BSS_IDX_SHIFT 2 + + uint16_t len; +#define RT2860_RX_TID_SHIFT 12 + + uint16_t seq; + uint16_t phy; + uint8_t rssi[3]; + uint8_t reserved1; + uint8_t snr[2]; + uint16_t reserved2; +} __packed; + + +/* first DMA segment contains TXWI + 802.11 header + 32-bit padding */ +#define RT2860_TXWI_DMASZ \ + (sizeof (struct rt2860_txwi) + \ + sizeof (struct ieee80211_frame) + 6 + \ + sizeof (uint16_t)) + +#define RT2860_RF1 0 +#define RT2860_RF2 2 +#define RT2860_RF3 1 +#define RT2860_RF4 3 + +#define RT2860_RF_2820 1 /* 2T3R */ +#define RT2860_RF_2850 2 /* dual-band 2T3R */ +#define RT2860_RF_2720 3 /* 1T2R */ +#define RT2860_RF_2750 4 /* dual-band 1T2R */ +#define RT3070_RF_3020 5 /* 1T1R */ +#define RT3070_RF_2020 6 /* b/g */ +#define RT3070_RF_3021 7 /* 1T2R */ +#define RT3070_RF_3022 8 /* 2T2R */ +#define RT3070_RF_3052 9 /* dual-band 2T2R */ +#define RT3070_RF_3320 11 /* 1T1R */ +#define RT3070_RF_3053 13 /* dual-band 3T3R */ + +/* USB commands for RT2870 only */ +#define RT2870_RESET 1 +#define RT2870_WRITE_2 2 +#define RT2870_WRITE_REGION_1 6 +#define RT2870_READ_REGION_1 7 +#define RT2870_EEPROM_READ 9 + +#define RT2860_EEPROM_DELAY 1 /* minimum hold time (microsecond) */ + +#define RT2860_EEPROM_VERSION 0x01 +#define RT2860_EEPROM_MAC01 0x02 +#define RT2860_EEPROM_MAC23 0x03 +#define RT2860_EEPROM_MAC45 0x04 +#define RT2860_EEPROM_PCIE_PSLEVEL 0x11 +#define RT2860_EEPROM_REV 0x12 +#define RT2860_EEPROM_ANTENNA 0x1a +#define RT2860_EEPROM_CONFIG 0x1b +#define RT2860_EEPROM_COUNTRY 0x1c +#define RT2860_EEPROM_FREQ_LEDS 0x1d +#define RT2860_EEPROM_LED1 0x1e +#define RT2860_EEPROM_LED2 0x1f +#define RT2860_EEPROM_LED3 0x20 +#define RT2860_EEPROM_LNA 0x22 +#define RT2860_EEPROM_RSSI1_2GHZ 0x23 +#define RT2860_EEPROM_RSSI2_2GHZ 0x24 +#define RT2860_EEPROM_RSSI1_5GHZ 0x25 +#define RT2860_EEPROM_RSSI2_5GHZ 0x26 +#define RT2860_EEPROM_DELTAPWR 0x28 +#define RT2860_EEPROM_PWR2GHZ_BASE1 0x29 +#define RT2860_EEPROM_PWR2GHZ_BASE2 0x30 +#define RT2860_EEPROM_TSSI1_2GHZ 0x37 +#define RT2860_EEPROM_TSSI2_2GHZ 0x38 +#define RT2860_EEPROM_TSSI3_2GHZ 0x39 +#define RT2860_EEPROM_TSSI4_2GHZ 0x3a +#define RT2860_EEPROM_TSSI5_2GHZ 0x3b +#define RT2860_EEPROM_PWR5GHZ_BASE1 0x3c +#define RT2860_EEPROM_PWR5GHZ_BASE2 0x53 +#define RT2860_EEPROM_TSSI1_5GHZ 0x6a +#define RT2860_EEPROM_TSSI2_5GHZ 0x6b +#define RT2860_EEPROM_TSSI3_5GHZ 0x6c +#define RT2860_EEPROM_TSSI4_5GHZ 0x6d +#define RT2860_EEPROM_TSSI5_5GHZ 0x6e +#define RT2860_EEPROM_RPWR 0x6f +#define RT2860_EEPROM_BBP_BASE 0x78 +#define RT3071_EEPROM_RF_BASE 0x82 + +#define RT2860_RIDX_CCK1 0 +#define RT2860_RIDX_CCK11 3 +#define RT2860_RIDX_OFDM6 4 +#define RT2860_RIDX_MAX 11 +static const struct rt2860_rate { + uint8_t rate; + uint8_t mcs; + enum ieee80211_phytype phy; + uint8_t ctl_ridx; + uint16_t sp_ack_dur; + uint16_t lp_ack_dur; +} rt2860_rates[] = { + { 2, 0, IEEE80211_T_DS, 0, 314, 314 }, + { 4, 1, IEEE80211_T_DS, 1, 258, 162 }, + { 11, 2, IEEE80211_T_DS, 2, 223, 127 }, + { 22, 3, IEEE80211_T_DS, 3, 213, 117 }, + { 12, 0, IEEE80211_T_OFDM, 4, 60, 60 }, + { 18, 1, IEEE80211_T_OFDM, 4, 52, 52 }, + { 24, 2, IEEE80211_T_OFDM, 6, 48, 48 }, + { 36, 3, IEEE80211_T_OFDM, 6, 44, 44 }, + { 48, 4, IEEE80211_T_OFDM, 8, 44, 44 }, + { 72, 5, IEEE80211_T_OFDM, 8, 40, 40 }, + { 96, 6, IEEE80211_T_OFDM, 8, 40, 40 }, + { 108, 7, IEEE80211_T_OFDM, 8, 40, 40 } +}; + +/* + * Control and status registers access macros. + */ +#define RAL_READ(sc, reg) \ + bus_space_read_4((sc)->sc_st, (sc)->sc_sh, (reg)) + +#define RAL_WRITE(sc, reg, val) \ + bus_space_write_4((sc)->sc_st, (sc)->sc_sh, (reg), (val)) + +#define RAL_BARRIER_WRITE(sc) \ + bus_space_barrier((sc)->sc_st, (sc)->sc_sh, 0, 0x1800, \ + BUS_SPACE_BARRIER_WRITE) + +#define RAL_BARRIER_READ_WRITE(sc) \ + bus_space_barrier((sc)->sc_st, (sc)->sc_sh, 0, 0x1800, \ + BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE) + +#define RAL_WRITE_REGION_1(sc, offset, datap, count) \ + bus_space_write_region_1((sc)->sc_st, (sc)->sc_sh, (offset), \ + (datap), (count)) + +#define RAL_SET_REGION_4(sc, offset, val, count) \ + bus_space_set_region_4((sc)->sc_st, (sc)->sc_sh, (offset), \ + (val), (count)) + +/* + * EEPROM access macro. + */ +#define RT2860_EEPROM_CTL(sc, val) do { \ + RAL_WRITE((sc), RT2860_PCI_EECTRL, (val)); \ + RAL_BARRIER_READ_WRITE((sc)); \ + DELAY(RT2860_EEPROM_DELAY); \ +} while (/* CONSTCOND */0) + +/* + * Default values for MAC registers; values taken from the reference driver. + */ +#define RT2860_DEF_MAC \ + { RT2860_BCN_OFFSET0, 0xf8f0e8e0 }, \ + { RT2860_LEGACY_BASIC_RATE, 0x0000013f }, \ + { RT2860_HT_BASIC_RATE, 0x00008003 }, \ + { RT2860_MAC_SYS_CTRL, 0x00000000 }, \ + { RT2860_BKOFF_SLOT_CFG, 0x00000209 }, \ + { RT2860_TX_SW_CFG0, 0x00000000 }, \ + { RT2860_TX_SW_CFG1, 0x00080606 }, \ + { RT2860_TX_LINK_CFG, 0x00001020 }, \ + { RT2860_TX_TIMEOUT_CFG, 0x000a2090 }, \ + { RT2860_LED_CFG, 0x7f031e46 }, \ + { RT2860_WMM_AIFSN_CFG, 0x00002273 }, \ + { RT2860_WMM_CWMIN_CFG, 0x00002344 }, \ + { RT2860_WMM_CWMAX_CFG, 0x000034aa }, \ + { RT2860_MAX_PCNT, 0x1f3fbf9f }, \ + { RT2860_TX_RTY_CFG, 0x47d01f0f }, \ + { RT2860_AUTO_RSP_CFG, 0x00000013 }, \ + { RT2860_CCK_PROT_CFG, 0x05740003 }, \ + { RT2860_OFDM_PROT_CFG, 0x05740003 }, \ + { RT2860_GF20_PROT_CFG, 0x01744004 }, \ + { RT2860_GF40_PROT_CFG, 0x03f44084 }, \ + { RT2860_MM20_PROT_CFG, 0x01744004 }, \ + { RT2860_MM40_PROT_CFG, 0x03f54084 }, \ + { RT2860_TXOP_CTRL_CFG, 0x0000583f }, \ + { RT2860_TXOP_HLDR_ET, 0x00000002 }, \ + { RT2860_TX_RTS_CFG, 0x00092b20 }, \ + { RT2860_EXP_ACK_TIME, 0x002400ca }, \ + { RT2860_XIFS_TIME_CFG, 0x33a41010 }, \ + { RT2860_PWR_PIN_CFG, 0x00000003 } + +/* XXX only a few registers differ from above, try to merge? */ +#define RT2870_DEF_MAC \ + { RT2860_BCN_OFFSET0, 0xf8f0e8e0 }, \ + { RT2860_LEGACY_BASIC_RATE, 0x0000013f }, \ + { RT2860_HT_BASIC_RATE, 0x00008003 }, \ + { RT2860_MAC_SYS_CTRL, 0x00000000 }, \ + { RT2860_BKOFF_SLOT_CFG, 0x00000209 }, \ + { RT2860_TX_SW_CFG0, 0x00000000 }, \ + { RT2860_TX_SW_CFG1, 0x00080606 }, \ + { RT2860_TX_LINK_CFG, 0x00001020 }, \ + { RT2860_TX_TIMEOUT_CFG, 0x000a2090 }, \ + { RT2860_LED_CFG, 0x7f031e46 }, \ + { RT2860_WMM_AIFSN_CFG, 0x00002273 }, \ + { RT2860_WMM_CWMIN_CFG, 0x00002344 }, \ + { RT2860_WMM_CWMAX_CFG, 0x000034aa }, \ + { RT2860_MAX_PCNT, 0x1f3fbf9f }, \ + { RT2860_TX_RTY_CFG, 0x47d01f0f }, \ + { RT2860_AUTO_RSP_CFG, 0x00000013 }, \ + { RT2860_CCK_PROT_CFG, 0x05740003 }, \ + { RT2860_OFDM_PROT_CFG, 0x05740003 }, \ + { RT2860_PBF_CFG, 0x00f40006 }, \ + { RT2860_WPDMA_GLO_CFG, 0x00000030 }, \ + { RT2860_GF20_PROT_CFG, 0x01744004 }, \ + { RT2860_GF40_PROT_CFG, 0x03f44084 }, \ + { RT2860_MM20_PROT_CFG, 0x01744004 }, \ + { RT2860_MM40_PROT_CFG, 0x03f44084 }, \ + { RT2860_TXOP_CTRL_CFG, 0x0000583f }, \ + { RT2860_TXOP_HLDR_ET, 0x00000002 }, \ + { RT2860_TX_RTS_CFG, 0x00092b20 }, \ + { RT2860_EXP_ACK_TIME, 0x002400ca }, \ + { RT2860_XIFS_TIME_CFG, 0x33a41010 }, \ + { RT2860_PWR_PIN_CFG, 0x00000003 } + +/* + * Default values for BBP registers; values taken from the reference driver. + */ +#define RT2860_DEF_BBP \ + { 65, 0x2c }, \ + { 66, 0x38 }, \ + { 69, 0x12 }, \ + { 70, 0x0a }, \ + { 73, 0x10 }, \ + { 81, 0x37 }, \ + { 82, 0x62 }, \ + { 83, 0x6a }, \ + { 84, 0x99 }, \ + { 86, 0x00 }, \ + { 91, 0x04 }, \ + { 92, 0x00 }, \ + { 103, 0x00 }, \ + { 105, 0x05 }, \ + { 106, 0x35 } + +/* + * Default settings for RF registers; values derived from the reference driver. + */ +#define RT2860_RF2850 \ + { 1, 0x100bb3, 0x1301e1, 0x05a014, 0x001402 }, \ + { 2, 0x100bb3, 0x1301e1, 0x05a014, 0x001407 }, \ + { 3, 0x100bb3, 0x1301e2, 0x05a014, 0x001402 }, \ + { 4, 0x100bb3, 0x1301e2, 0x05a014, 0x001407 }, \ + { 5, 0x100bb3, 0x1301e3, 0x05a014, 0x001402 }, \ + { 6, 0x100bb3, 0x1301e3, 0x05a014, 0x001407 }, \ + { 7, 0x100bb3, 0x1301e4, 0x05a014, 0x001402 }, \ + { 8, 0x100bb3, 0x1301e4, 0x05a014, 0x001407 }, \ + { 9, 0x100bb3, 0x1301e5, 0x05a014, 0x001402 }, \ + { 10, 0x100bb3, 0x1301e5, 0x05a014, 0x001407 }, \ + { 11, 0x100bb3, 0x1301e6, 0x05a014, 0x001402 }, \ + { 12, 0x100bb3, 0x1301e6, 0x05a014, 0x001407 }, \ + { 13, 0x100bb3, 0x1301e7, 0x05a014, 0x001402 }, \ + { 14, 0x100bb3, 0x1301e8, 0x05a014, 0x001404 }, \ + { 36, 0x100bb3, 0x130266, 0x056014, 0x001408 }, \ + { 38, 0x100bb3, 0x130267, 0x056014, 0x001404 }, \ + { 40, 0x100bb2, 0x1301a0, 0x056014, 0x001400 }, \ + { 44, 0x100bb2, 0x1301a0, 0x056014, 0x001408 }, \ + { 46, 0x100bb2, 0x1301a1, 0x056014, 0x001402 }, \ + { 48, 0x100bb2, 0x1301a1, 0x056014, 0x001406 }, \ + { 52, 0x100bb2, 0x1301a2, 0x056014, 0x001404 }, \ + { 54, 0x100bb2, 0x1301a2, 0x056014, 0x001408 }, \ + { 56, 0x100bb2, 0x1301a3, 0x056014, 0x001402 }, \ + { 60, 0x100bb2, 0x1301a4, 0x056014, 0x001400 }, \ + { 62, 0x100bb2, 0x1301a4, 0x056014, 0x001404 }, \ + { 64, 0x100bb2, 0x1301a4, 0x056014, 0x001408 }, \ + { 100, 0x100bb2, 0x1301ac, 0x05e014, 0x001400 }, \ + { 102, 0x100bb2, 0x1701ac, 0x15e014, 0x001404 }, \ + { 104, 0x100bb2, 0x1701ac, 0x15e014, 0x001408 }, \ + { 108, 0x100bb3, 0x17028c, 0x15e014, 0x001404 }, \ + { 110, 0x100bb3, 0x13028d, 0x05e014, 0x001400 }, \ + { 112, 0x100bb3, 0x13028d, 0x05e014, 0x001406 }, \ + { 116, 0x100bb3, 0x13028e, 0x05e014, 0x001408 }, \ + { 118, 0x100bb3, 0x13028f, 0x05e014, 0x001404 }, \ + { 120, 0x100bb1, 0x1300e0, 0x05e014, 0x001400 }, \ + { 124, 0x100bb1, 0x1300e0, 0x05e014, 0x001404 }, \ + { 126, 0x100bb1, 0x1300e0, 0x05e014, 0x001406 }, \ + { 128, 0x100bb1, 0x1300e0, 0x05e014, 0x001408 }, \ + { 132, 0x100bb1, 0x1300e1, 0x05e014, 0x001402 }, \ + { 134, 0x100bb1, 0x1300e1, 0x05e014, 0x001404 }, \ + { 136, 0x100bb1, 0x1300e1, 0x05e014, 0x001406 }, \ + { 140, 0x100bb1, 0x1300e2, 0x05e014, 0x001400 }, \ + { 149, 0x100bb1, 0x1300e2, 0x05e014, 0x001409 }, \ + { 151, 0x100bb1, 0x1300e3, 0x05e014, 0x001401 }, \ + { 153, 0x100bb1, 0x1300e3, 0x05e014, 0x001403 }, \ + { 157, 0x100bb1, 0x1300e3, 0x05e014, 0x001407 }, \ + { 159, 0x100bb1, 0x1300e3, 0x05e014, 0x001409 }, \ + { 161, 0x100bb1, 0x1300e4, 0x05e014, 0x001401 }, \ + { 165, 0x100bb1, 0x1300e4, 0x05e014, 0x001405 }, \ + { 167, 0x100bb1, 0x1300f4, 0x05e014, 0x001407 }, \ + { 169, 0x100bb1, 0x1300f4, 0x05e014, 0x001409 }, \ + { 171, 0x100bb1, 0x1300f5, 0x05e014, 0x001401 }, \ + { 173, 0x100bb1, 0x1300f5, 0x05e014, 0x001403 } + +#define RT3070_RF3052 \ + { 0xf1, 2, 2 }, \ + { 0xf1, 2, 7 }, \ + { 0xf2, 2, 2 }, \ + { 0xf2, 2, 7 }, \ + { 0xf3, 2, 2 }, \ + { 0xf3, 2, 7 }, \ + { 0xf4, 2, 2 }, \ + { 0xf4, 2, 7 }, \ + { 0xf5, 2, 2 }, \ + { 0xf5, 2, 7 }, \ + { 0xf6, 2, 2 }, \ + { 0xf6, 2, 7 }, \ + { 0xf7, 2, 2 }, \ + { 0xf8, 2, 4 }, \ + { 0x56, 0, 4 }, \ + { 0x56, 0, 6 }, \ + { 0x56, 0, 8 }, \ + { 0x57, 0, 0 }, \ + { 0x57, 0, 2 }, \ + { 0x57, 0, 4 }, \ + { 0x57, 0, 8 }, \ + { 0x57, 0, 10 }, \ + { 0x58, 0, 0 }, \ + { 0x58, 0, 4 }, \ + { 0x58, 0, 6 }, \ + { 0x58, 0, 8 }, \ + { 0x5b, 0, 8 }, \ + { 0x5b, 0, 10 }, \ + { 0x5c, 0, 0 }, \ + { 0x5c, 0, 4 }, \ + { 0x5c, 0, 6 }, \ + { 0x5c, 0, 8 }, \ + { 0x5d, 0, 0 }, \ + { 0x5d, 0, 2 }, \ + { 0x5d, 0, 4 }, \ + { 0x5d, 0, 8 }, \ + { 0x5d, 0, 10 }, \ + { 0x5e, 0, 0 }, \ + { 0x5e, 0, 4 }, \ + { 0x5e, 0, 6 }, \ + { 0x5e, 0, 8 }, \ + { 0x5f, 0, 0 }, \ + { 0x5f, 0, 9 }, \ + { 0x5f, 0, 11 }, \ + { 0x60, 0, 1 }, \ + { 0x60, 0, 5 }, \ + { 0x60, 0, 7 }, \ + { 0x60, 0, 9 }, \ + { 0x61, 0, 1 }, \ + { 0x61, 0, 3 }, \ + { 0x61, 0, 5 }, \ + { 0x61, 0, 7 }, \ + { 0x61, 0, 9 } + +#define RT3070_DEF_RF \ + { 4, 0x40 }, \ + { 5, 0x03 }, \ + { 6, 0x02 }, \ + { 7, 0x70 }, \ + { 9, 0x0f }, \ + { 10, 0x41 }, \ + { 11, 0x21 }, \ + { 12, 0x7b }, \ + { 14, 0x90 }, \ + { 15, 0x58 }, \ + { 16, 0xb3 }, \ + { 17, 0x92 }, \ + { 18, 0x2c }, \ + { 19, 0x02 }, \ + { 20, 0xba }, \ + { 21, 0xdb }, \ + { 24, 0x16 }, \ + { 25, 0x01 }, \ + { 29, 0x1f } + +#define RT3572_DEF_RF \ + { 0, 0x70 }, \ + { 1, 0x81 }, \ + { 2, 0xf1 }, \ + { 3, 0x02 }, \ + { 4, 0x4c }, \ + { 5, 0x05 }, \ + { 6, 0x4a }, \ + { 7, 0xd8 }, \ + { 9, 0xc3 }, \ + { 10, 0xf1 }, \ + { 11, 0xb9 }, \ + { 12, 0x70 }, \ + { 13, 0x65 }, \ + { 14, 0xa0 }, \ + { 15, 0x53 }, \ + { 16, 0x4c }, \ + { 17, 0x23 }, \ + { 18, 0xac }, \ + { 19, 0x93 }, \ + { 20, 0xb3 }, \ + { 21, 0xd0 }, \ + { 22, 0x00 }, \ + { 23, 0x3c }, \ + { 24, 0x16 }, \ + { 25, 0x15 }, \ + { 26, 0x85 }, \ + { 27, 0x00 }, \ + { 28, 0x00 }, \ + { 29, 0x9b }, \ + { 30, 0x09 }, \ + { 31, 0x10 } diff --git a/src/add-ons/kernel/drivers/network/wlan/ralinkwifi/dev/ral/rt2860var.h b/src/add-ons/kernel/drivers/network/wlan/ralinkwifi/dev/ral/rt2860var.h new file mode 100644 index 00000000000..28a3d59b826 --- /dev/null +++ b/src/add-ons/kernel/drivers/network/wlan/ralinkwifi/dev/ral/rt2860var.h @@ -0,0 +1,210 @@ +/*- + * Copyright (c) 2007 Damien Bergamini + * Copyright (c) 2012 Bernhard Schmidt + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * $OpenBSD: rt2860var.h,v 1.20 2010/09/07 16:21:42 deraadt Exp $ + * $FreeBSD$ + */ + +#define RT2860_TX_RING_COUNT 64 +#define RT2860_RX_RING_COUNT 128 +#define RT2860_TX_POOL_COUNT (RT2860_TX_RING_COUNT * 2) + +#define RT2860_MAX_SCATTER ((RT2860_TX_RING_COUNT * 2) - 1) + +/* HW supports up to 255 STAs */ +#define RT2860_WCID_MAX 254 +#define RT2860_AID2WCID(aid) ((aid) & 0xff) + +struct rt2860_rx_radiotap_header { + struct ieee80211_radiotap_header wr_ihdr; + uint64_t wr_tsf; + uint8_t wr_flags; + uint8_t wr_rate; + uint16_t wr_chan_freq; + uint16_t wr_chan_flags; + uint8_t wr_antenna; + int8_t wr_antsignal; + int8_t wr_antnoise; +} __packed; + +#define RT2860_RX_RADIOTAP_PRESENT \ + ((1 << IEEE80211_RADIOTAP_TSFT) | \ + (1 << IEEE80211_RADIOTAP_FLAGS) | \ + (1 << IEEE80211_RADIOTAP_RATE) | \ + (1 << IEEE80211_RADIOTAP_CHANNEL) | \ + (1 << IEEE80211_RADIOTAP_ANTENNA) | \ + (1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL) | \ + (1 << IEEE80211_RADIOTAP_DBM_ANTNOISE)) + +struct rt2860_tx_radiotap_header { + struct ieee80211_radiotap_header wt_ihdr; + uint8_t wt_flags; + uint8_t wt_rate; + uint16_t wt_chan_freq; + uint16_t wt_chan_flags; +} __packed; + +#define RT2860_TX_RADIOTAP_PRESENT \ + ((1 << IEEE80211_RADIOTAP_FLAGS) | \ + (1 << IEEE80211_RADIOTAP_RATE) | \ + (1 << IEEE80211_RADIOTAP_CHANNEL)) + +struct rt2860_tx_data { + struct rt2860_txwi *txwi; + struct mbuf *m; + struct ieee80211_node *ni; + bus_dmamap_t map; + bus_addr_t paddr; + SLIST_ENTRY(rt2860_tx_data) next; +}; + +struct rt2860_tx_ring { + struct rt2860_txd *txd; + bus_addr_t paddr; + bus_dma_tag_t desc_dmat; + bus_dmamap_t desc_map; + bus_dma_segment_t seg; + struct rt2860_tx_data *data[RT2860_TX_RING_COUNT]; + int cur; + int next; + int queued; +}; + +struct rt2860_rx_data { + struct mbuf *m; + bus_dmamap_t map; +}; + +struct rt2860_rx_ring { + struct rt2860_rxd *rxd; + bus_addr_t paddr; + bus_dma_tag_t desc_dmat; + bus_dmamap_t desc_map; + bus_dma_tag_t data_dmat; + bus_dma_segment_t seg; + unsigned int cur; /* must be unsigned */ + struct rt2860_rx_data data[RT2860_RX_RING_COUNT]; +}; + +struct rt2860_node { + struct ieee80211_node ni; + uint8_t wcid; + uint8_t ridx[IEEE80211_RATE_MAXSIZE]; + uint8_t ctl_ridx[IEEE80211_RATE_MAXSIZE]; +}; + +struct rt2860_vap { + struct ieee80211vap ral_vap; + + int (*ral_newstate)(struct ieee80211vap *, + enum ieee80211_state, int); +}; +#define RT2860_VAP(vap) ((struct rt2860_vap *)(vap)) + +struct rt2860_softc { + struct ifnet *sc_ifp; + device_t sc_dev; + bus_space_tag_t sc_st; + bus_space_handle_t sc_sh; + + struct mtx sc_mtx; + + struct callout watchdog_ch; + + int sc_invalid; + int sc_debug; +/* + * The same in both up to here + * ------------------------------------------------ + */ + + uint16_t (*sc_srom_read)(struct rt2860_softc *, + uint16_t); + void (*sc_node_free)(struct ieee80211_node *); + + int sc_flags; +#define RT2860_ENABLED (1 << 0) +#define RT2860_ADVANCED_PS (1 << 1) +#define RT2860_PCIE (1 << 2) + + struct ieee80211_node *wcid2ni[RT2860_WCID_MAX]; + + struct rt2860_tx_ring txq[6]; + struct rt2860_rx_ring rxq; + + SLIST_HEAD(, rt2860_tx_data) data_pool; + struct rt2860_tx_data data[RT2860_TX_POOL_COUNT]; + bus_dma_tag_t txwi_dmat; + bus_dmamap_t txwi_map; + bus_dma_segment_t txwi_seg; + caddr_t txwi_vaddr; + + int sc_tx_timer; + int mgtqid; + uint8_t qfullmsk; + + uint16_t mac_ver; + uint16_t mac_rev; + uint8_t rf_rev; + uint8_t freq; + uint8_t ntxchains; + uint8_t nrxchains; + uint8_t pslevel; + int8_t txpow1[54]; + int8_t txpow2[54]; + int8_t rssi_2ghz[3]; + int8_t rssi_5ghz[3]; + uint8_t lna[4]; + uint8_t rf24_20mhz; + uint8_t rf24_40mhz; + uint8_t patch_dac; + uint8_t rfswitch; + uint8_t ext_2ghz_lna; + uint8_t ext_5ghz_lna; + uint8_t calib_2ghz; + uint8_t calib_5ghz; + uint8_t txmixgain_2ghz; + uint8_t txmixgain_5ghz; + uint8_t tssi_2ghz[9]; + uint8_t tssi_5ghz[9]; + uint8_t step_2ghz; + uint8_t step_5ghz; + struct { + uint8_t reg; + uint8_t val; + } bbp[8], rf[10]; + uint8_t leds; + uint16_t led[3]; + uint32_t txpow20mhz[5]; + uint32_t txpow40mhz_2ghz[5]; + uint32_t txpow40mhz_5ghz[5]; + + struct rt2860_rx_radiotap_header sc_rxtap; + int sc_rxtap_len; + struct rt2860_tx_radiotap_header sc_txtap; + int sc_txtap_len; +}; + +int rt2860_attach(device_t, int); +int rt2860_detach(void *); +void rt2860_shutdown(void *); +void rt2860_suspend(void *); +void rt2860_resume(void *); +void rt2860_intr(void *); + +#define RAL_LOCK(sc) mtx_lock(&(sc)->sc_mtx) +#define RAL_LOCK_ASSERT(sc) mtx_assert(&(sc)->sc_mtx, MA_OWNED) +#define RAL_UNLOCK(sc) mtx_unlock(&(sc)->sc_mtx) diff --git a/src/add-ons/kernel/drivers/network/wlan/wavelanwifi/dev/wi/if_wi.c b/src/add-ons/kernel/drivers/network/wlan/wavelanwifi/dev/wi/if_wi.c index e46b74866be..70574ff5d04 100644 --- a/src/add-ons/kernel/drivers/network/wlan/wavelanwifi/dev/wi/if_wi.c +++ b/src/add-ons/kernel/drivers/network/wlan/wavelanwifi/dev/wi/if_wi.c @@ -108,10 +108,10 @@ __FBSDID("$FreeBSD$"); #include #include -static struct ieee80211vap *wi_vap_create(struct ieee80211com *ic, - const char name[IFNAMSIZ], int unit, int opmode, int flags, - const uint8_t bssid[IEEE80211_ADDR_LEN], - const uint8_t mac[IEEE80211_ADDR_LEN]); +static struct ieee80211vap *wi_vap_create(struct ieee80211com *, + const char [IFNAMSIZ], int, enum ieee80211_opmode, int, + const uint8_t [IEEE80211_ADDR_LEN], + const uint8_t [IEEE80211_ADDR_LEN]); static void wi_vap_delete(struct ieee80211vap *vap); static void wi_stop_locked(struct wi_softc *sc, int disable); static void wi_start_locked(struct ifnet *); @@ -506,10 +506,10 @@ wi_detach(device_t dev) } static struct ieee80211vap * -wi_vap_create(struct ieee80211com *ic, - const char name[IFNAMSIZ], int unit, int opmode, int flags, - const uint8_t bssid[IEEE80211_ADDR_LEN], - const uint8_t mac[IEEE80211_ADDR_LEN]) +wi_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit, + enum ieee80211_opmode opmode, int flags, + const uint8_t bssid[IEEE80211_ADDR_LEN], + const uint8_t mac[IEEE80211_ADDR_LEN]) { struct wi_softc *sc = ic->ic_ifp->if_softc; struct wi_vap *wvp; diff --git a/src/libs/compat/freebsd_network/bus.cpp b/src/libs/compat/freebsd_network/bus.cpp index bc89fe8900e..22aed56b3c7 100644 --- a/src/libs/compat/freebsd_network/bus.cpp +++ b/src/libs/compat/freebsd_network/bus.cpp @@ -256,6 +256,13 @@ rman_get_bustag(struct resource *res) } +int +rman_get_rid(struct resource *res) +{ + return 0; +} + + // #pragma mark - Interrupt handling diff --git a/src/libs/compat/freebsd_network/compat.c b/src/libs/compat/freebsd_network/compat.c index f17eb593195..33957800b1a 100644 --- a/src/libs/compat/freebsd_network/compat.c +++ b/src/libs/compat/freebsd_network/compat.c @@ -175,6 +175,14 @@ device_get_parent(device_t dev) } +devclass_t +device_get_devclass(device_t dev) +{ + // TODO find out what to do + return 0; +} + + int device_get_children(device_t dev, device_t **devlistp, int *devcountp) { @@ -641,3 +649,4 @@ pmap_kextract(vm_offset_t virtualAddress) return (vm_paddr_t)entry.address; } + diff --git a/src/libs/compat/freebsd_network/compat/dev/mii/miidevs b/src/libs/compat/freebsd_network/compat/dev/mii/miidevs index 1b98542fdcf..5629290c961 100644 --- a/src/libs/compat/freebsd_network/compat/dev/mii/miidevs +++ b/src/libs/compat/freebsd_network/compat/dev/mii/miidevs @@ -1,5 +1,5 @@ $FreeBSD$ -/*$NetBSD: miidevs,v 1.99 2011/01/26 18:39:04 bouyer Exp $*/ +/*$NetBSD: miidevs,v 1.105 2011/11/25 23:28:14 jakllsch Exp $*/ /*- * Copyright (c) 1998, 1999 The NetBSD Foundation, Inc. @@ -146,6 +146,7 @@ model xxBROADCOM BCM5214 0x0028 BCM5214 Quad 10/100 media interface model xxBROADCOM BCM5221 0x001e BCM5221 10/100 media interface model xxBROADCOM BCM5222 0x0032 BCM5222 Dual 10/100 media interface model xxBROADCOM BCM4401 0x0036 BCM4401 10/100 media interface +model xxBROADCOM BCM5365 0x0037 BCM5365 10/100 5-port PHY switch model BROADCOM BCM5400 0x0004 BCM5400 1000BASE-T media interface model BROADCOM BCM5401 0x0005 BCM5401 1000BASE-T media interface model BROADCOM BCM5411 0x0007 BCM5411 1000BASE-T media interface @@ -164,21 +165,25 @@ model BROADCOM BCM54K2 0x002e BCM54K2 1000BASE-T media interface model BROADCOM BCM5714 0x0034 BCM5714 1000BASE-T media interface model BROADCOM BCM5780 0x0035 BCM5780 1000BASE-T media interface model BROADCOM BCM5708C 0x0036 BCM5708C 1000BASE-T media interface +model BROADCOM2 BCM5325 0x0003 BCM5325 10/100 5-port PHY switch model BROADCOM2 BCM5906 0x0004 BCM5906 10/100baseTX media interface model BROADCOM2 BCM5481 0x000a BCM5481 1000BASE-T media interface model BROADCOM2 BCM5482 0x000b BCM5482 1000BASE-T media interface model BROADCOM2 BCM5755 0x000c BCM5755 1000BASE-T media interface model BROADCOM2 BCM5754 0x000e BCM5754/5787 1000BASE-T media interface model BROADCOM2 BCM5708S 0x0015 BCM5708S 1000/2500baseSX PHY +model BROADCOM2 BCM5785 0x0016 BCM5785 1000BASE-T media interface model BROADCOM2 BCM5709CAX 0x002c BCM5709CAX 10/100/1000baseT PHY model BROADCOM2 BCM5722 0x002d BCM5722 1000BASE-T media interface model BROADCOM2 BCM5784 0x003a BCM5784 10/100/1000baseT PHY model BROADCOM2 BCM5709C 0x003c BCM5709 10/100/1000baseT PHY model BROADCOM2 BCM5761 0x003d BCM5761 10/100/1000baseT PHY model BROADCOM2 BCM5709S 0x003f BCM5709S 1000/2500baseSX PHY +model BROADCOM3 BCM57780 0x0019 BCM57780 1000BASE-T media interface model BROADCOM3 BCM5717C 0x0020 BCM5717C 1000BASE-T media interface model BROADCOM3 BCM5719C 0x0022 BCM5719C 1000BASE-T media interface model BROADCOM3 BCM57765 0x0024 BCM57765 1000BASE-T media interface +model BROADCOM3 BCM5720C 0x0036 BCM5720C 1000BASE-T media interface model xxBROADCOM_ALT1 BCM5906 0x0004 BCM5906 10/100baseTX media interface /* Cicada Semiconductor PHYs (now owned by Vitesse?) */ @@ -217,6 +222,10 @@ model yyINTEL I82562ET 0x0033 i82562ET 10/100 media interface model yyINTEL I82553 0x0035 i82553 10/100 media interface model yyINTEL I82566 0x0039 i82566 10/100/1000 media interface model INTEL I82577 0x0005 i82577 10/100/1000 media interface +model INTEL I82579 0x0009 i82579 10/100/1000 media interface +model xxMARVELL I82563 0x000a i82563 10/100/1000 media interface + +model yyINTEL IGP01E1000 0x0038 Intel IGP01E1000 Gigabit PHY /* Jato Technologies PHYs */ model xxJATO BASEX 0x0000 Jato 1000baseX media interface @@ -245,18 +254,24 @@ model xxMARVELL E3082 0x0008 Marvell 88E3082 10/100 Fast Ethernet PHY model xxMARVELL E1112 0x0009 Marvell 88E1112 Gigabit PHY model xxMARVELL E1149 0x000b Marvell 88E1149 Gigabit PHY model xxMARVELL E1111 0x000c Marvell 88E1111 Gigabit PHY +model xxMARVELL E1145 0x000d Marvell 88E1145 Quad Gigabit PHY model xxMARVELL E1116 0x0021 Marvell 88E1116 Gigabit PHY model xxMARVELL E1116R 0x0024 Marvell 88E1116R Gigabit PHY model xxMARVELL E1118 0x0022 Marvell 88E1118 Gigabit PHY model xxMARVELL E1149R 0x0025 Marvell 88E1149R Quad Gigabit PHY model xxMARVELL E3016 0x0026 Marvell 88E3016 10/100 Fast Ethernet PHY model xxMARVELL PHYG65G 0x0027 Marvell PHYG65G Gigabit PHY +model xxMARVELL E1116R_29 0x0029 Marvell 88E1116R Gigabit PHY model MARVELL E1000 0x0005 Marvell 88E1000 Gigabit PHY model MARVELL E1011 0x0002 Marvell 88E1011 Gigabit PHY model MARVELL E1000_3 0x0003 Marvell 88E1000 Gigabit PHY model MARVELL E1000_5 0x0005 Marvell 88E1000 Gigabit PHY model MARVELL E1111 0x000c Marvell 88E1111 Gigabit PHY +/* Myson Technology PHYs */ +model xxMYSON MTD972 0x0000 MTD972 10/100 media interface +model MYSON MTD803 0x0000 MTD803 3-in-1 media interface + /* National Semiconductor PHYs */ model xxNATSEMI DP83840 0x0000 DP83840 10/100 media interface model xxNATSEMI DP83843 0x0001 DP83843 10/100 media interface @@ -265,6 +280,7 @@ model xxNATSEMI DP83847 0x0003 DP83847 10/100 media interface model xxNATSEMI DP83891 0x0005 DP83891 1000BASE-T media interface model xxNATSEMI DP83861 0x0006 DP83861 1000BASE-T media interface model xxNATSEMI DP83865 0x0007 DP83865 1000BASE-T media interface +model xxNATSEMI DP83849 0x000a DP83849 10/100 media interface /* PMC Sierra PHYs */ model xxPMCSIERRA PM8351 0x0000 PM8351 OctalPHY Gigabit interface diff --git a/src/libs/compat/freebsd_network/compat/machine/bus.h b/src/libs/compat/freebsd_network/compat/machine/bus.h index 717f895fed8..648d718b659 100644 --- a/src/libs/compat/freebsd_network/compat/machine/bus.h +++ b/src/libs/compat/freebsd_network/compat/machine/bus.h @@ -115,6 +115,9 @@ #include +struct resource; + + // TODO: x86 specific! #define I386_BUS_SPACE_IO 0 #define I386_BUS_SPACE_MEM 1 @@ -215,6 +218,22 @@ bus_space_write_region_1(bus_space_tag_t tag, bus_space_handle_t bsh, } +static inline void +bus_space_set_region_4(bus_space_tag_t tag, bus_space_handle_t bsh, + bus_size_t offset, u_int32_t value, size_t count) +{ + /* TODO implement */ +} + + +static inline void +bus_read_region_1(struct resource *res, bus_size_t offset, + const u_int8_t *addr, size_t count) +{ + /* TODO implement */ +} + + static inline void bus_space_barrier(bus_space_tag_t tag, bus_space_handle_t handle, bus_size_t offset, bus_size_t len, int flags) diff --git a/src/libs/compat/freebsd_network/compat/sys/bus.h b/src/libs/compat/freebsd_network/compat/sys/bus.h index a7d1add66a3..2299ef2e6c6 100644 --- a/src/libs/compat/freebsd_network/compat/sys/bus.h +++ b/src/libs/compat/freebsd_network/compat/sys/bus.h @@ -115,6 +115,7 @@ void device_set_desc_copy(device_t dev, const char *desc); const char *device_get_desc(device_t dev); device_t device_get_parent(device_t dev); u_int32_t device_get_flags(device_t dev); +devclass_t device_get_devclass(device_t dev); int device_get_children(device_t dev, device_t **devlistp, int *devcountp); void device_set_ivars(device_t dev, void *); diff --git a/src/libs/compat/freebsd_network/compat/sys/haiku-module.h b/src/libs/compat/freebsd_network/compat/sys/haiku-module.h index ec2d98fd1a2..26e07bb3dee 100644 --- a/src/libs/compat/freebsd_network/compat/sys/haiku-module.h +++ b/src/libs/compat/freebsd_network/compat/sys/haiku-module.h @@ -36,6 +36,7 @@ struct device_method { typedef struct device_method device_method_t; #define DEVMETHOD(name, func) { #name, (device_method_signature_t)&func } +#define DEVMETHOD_END { 0, 0 } typedef struct { const char *name; @@ -255,5 +256,9 @@ extern const char* __haiku_firmware_name_map[][2]; driver_t *DRIVER_MODULE_NAME(name, busname) = &(driver); \ devclass_t *__class_ ## name ## _ ## busname ## _ ## devclass = &(devclass) +#define DRIVER_MODULE_ORDERED(name, busname, driver, devclass, evh, arg, order) \ + DRIVER_MODULE(name, busname, driver, devclass, evh, arg) + +#define nitems(_a) (sizeof((_a)) / sizeof((_a)[0])) #endif /* _FBSD_COMPAT_SYS_HAIKU_MODULE_H_ */ diff --git a/src/libs/compat/freebsd_network/compat/sys/mutex.h b/src/libs/compat/freebsd_network/compat/sys/mutex.h index 444aea6e93b..18b2838557e 100644 --- a/src/libs/compat/freebsd_network/compat/sys/mutex.h +++ b/src/libs/compat/freebsd_network/compat/sys/mutex.h @@ -25,6 +25,9 @@ #define MTX_DEF 0x0000 #define MTX_RECURSE 0x0004 +#define MTX_QUIET 0x40000 +#define MTX_DUPOK 0x400000 + #define MTX_NETWORK_LOCK "network driver" diff --git a/src/libs/compat/freebsd_network/compat/sys/rman.h b/src/libs/compat/freebsd_network/compat/sys/rman.h index a537e2b1546..c3911d974f2 100644 --- a/src/libs/compat/freebsd_network/compat/sys/rman.h +++ b/src/libs/compat/freebsd_network/compat/sys/rman.h @@ -59,6 +59,7 @@ struct resource { bus_space_handle_t rman_get_bushandle(struct resource *); bus_space_tag_t rman_get_bustag(struct resource *); +int rman_get_rid(struct resource *); static inline u_long diff --git a/src/libs/compat/freebsd_network/compat/sys/sysctl.h b/src/libs/compat/freebsd_network/compat/sys/sysctl.h index a1519bda8df..0f324a296a9 100644 --- a/src/libs/compat/freebsd_network/compat/sys/sysctl.h +++ b/src/libs/compat/freebsd_network/compat/sys/sysctl.h @@ -157,6 +157,7 @@ SYSCTL_CHILDREN(void *ptr) #define SYSCTL_NODE(...) #define SYSCTL_INT(...) +#define SYSCTL_UINT(...) #define SYSCTL_PROC(...) #endif diff --git a/src/libs/compat/freebsd_network/shared.h b/src/libs/compat/freebsd_network/shared.h index a1ffb40a962..51cbba8a1c1 100644 --- a/src/libs/compat/freebsd_network/shared.h +++ b/src/libs/compat/freebsd_network/shared.h @@ -21,7 +21,7 @@ struct device { driver_t *driver; struct list children; - int32 flags; + uint32 flags; char device_name[128]; int unit; diff --git a/src/libs/compat/freebsd_wlan/net80211/ieee80211_var.h b/src/libs/compat/freebsd_wlan/net80211/ieee80211_var.h index 93db5b313ed..de24cbd4ccb 100644 --- a/src/libs/compat/freebsd_wlan/net80211/ieee80211_var.h +++ b/src/libs/compat/freebsd_wlan/net80211/ieee80211_var.h @@ -232,7 +232,7 @@ struct ieee80211com { /* virtual ap create/delete */ struct ieee80211vap* (*ic_vap_create)(struct ieee80211com *, const char name[IFNAMSIZ], int unit, - int opmode, int flags, + enum ieee80211_opmode opmode, int flags, const uint8_t bssid[IEEE80211_ADDR_LEN], const uint8_t macaddr[IEEE80211_ADDR_LEN]); void (*ic_vap_delete)(struct ieee80211vap *);