diff --git a/src/add-ons/kernel/drivers/network/broadcom440x/dev/mii/Jamfile b/src/add-ons/kernel/drivers/network/broadcom440x/dev/mii/Jamfile index a27350562c..550825ec89 100644 --- a/src/add-ons/kernel/drivers/network/broadcom440x/dev/mii/Jamfile +++ b/src/add-ons/kernel/drivers/network/broadcom440x/dev/mii/Jamfile @@ -12,3 +12,6 @@ KernelStaticLibrary broadcom440x_mii.a bmtphy.c ; +ObjectHdrs [ FGristFiles bmtphy$(SUFOBJ) ] + : [ FDirName $(TARGET_COMMON_DEBUG_OBJECT_DIR) libs compat freebsd_network ] ; +Includes [ FGristFiles bmtphy.c ] : miidevs.h ; \ No newline at end of file diff --git a/src/add-ons/kernel/drivers/network/broadcom440x/dev/mii/miidevs.h b/src/add-ons/kernel/drivers/network/broadcom440x/dev/mii/miidevs.h deleted file mode 100644 index 4ab714b8db..0000000000 --- a/src/add-ons/kernel/drivers/network/broadcom440x/dev/mii/miidevs.h +++ /dev/null @@ -1,14 +0,0 @@ -#define MII_OUI_BROADCOM 0x001018 - -#define MII_MODEL_BROADCOM_BCM4401 0x0036 -#define MII_MODEL_BROADCOM_BCM5201 0x0021 -#define MII_MODEL_BROADCOM_BCM5221 0x001e -#define MII_MODEL_BROADCOM_3C905B 0x0012 -#define MII_MODEL_BROADCOM_3C905C 0x0017 - -#define MII_STR_BROADCOM_BCM4401 "BCM4401 10/100baseTX PHY" -#define MII_STR_BROADCOM_BCM5201 "BCM5201 10/100baseTX PHY" -#define MII_STR_BROADCOM_BCM5221 "BCM5221 10/100baseTX PHY" -#define MII_STR_BROADCOM_3C905B "3c905B 10/100 internal PHY" -#define MII_STR_BROADCOM_3C905C "3c905C 10/100 internal PHY" - 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 new file mode 100644 index 0000000000..774e220a7e --- /dev/null +++ b/src/add-ons/kernel/drivers/network/broadcom570x/dev/bce/if_bcereg.h @@ -0,0 +1,6694 @@ +/*- + * Copyright (c) 2006-2008 Broadcom Corporation + * David Christensen . 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 Broadcom Corporation nor the name of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written consent. + * + * 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: src/sys/dev/bce/if_bcereg.h,v 1.21 2008/08/27 18:47:24 davidch Exp $ + */ + +#ifndef _BCE_H_DEFINED +#define _BCE_H_DEFINED + +#ifdef HAVE_KERNEL_OPTION_HEADERS +#include "opt_device_polling.h" +#endif + +#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 "miidevs.h" +#include + +#include +#include + +#include "miibus_if.h" + +/****************************************************************************/ +/* Conversion to FreeBSD type definitions. */ +/****************************************************************************/ +#define u64 uint64_t +#define u32 uint32_t +#define u16 uint16_t +#define u8 uint8_t + +#if BYTE_ORDER == BIG_ENDIAN +#define __BIG_ENDIAN 1 +#undef __LITTLE_ENDIAN +#else +#undef __BIG_ENDIAN +#define __LITTLE_ENDIAN 1 +#endif + +#define BCE_DWORD_PRINTFB \ + "\020" \ + "\40b31" \ + "\37b30" \ + "\36b29" \ + "\35b28" \ + "\34b27" \ + "\33b26" \ + "\32b25" \ + "\31b24" \ + "\30b23" \ + "\27b22" \ + "\26b21" \ + "\25b20" \ + "\24b19" \ + "\23b18" \ + "\22b17" \ + "\21b16" \ + "\20b15" \ + "\17b14" \ + "\16b13" \ + "\15b12" \ + "\14b11" \ + "\13b10" \ + "\12b9" \ + "\11b8" \ + "\10b7" \ + "\07b6" \ + "\06b5" \ + "\05b4" \ + "\04b3" \ + "\03b2" \ + "\02b1" \ + "\01b0" + +/* MII Control Register 0x0 */ +#define BCE_BMCR_PRINTFB \ + "\020" \ + "\20Reset" \ + "\17Loopback" \ + "\16Spd0" \ + "\15AnegEna" \ + "\14PwrDn" \ + "\13Isolate" \ + "\12RstrtAneg" \ + "\11FD" \ + "\10CollTst" \ + "\07Spd1" \ + "\06Rsrvd" \ + "\05Rsrvd" \ + "\04Rsrvd" \ + "\03Rsrvd" \ + "\02Rsrvd" \ + "\01Rsrvd" + +/* MII Status Register 0x1 */ +#define BCE_BMSR_PRINTFB \ + "\020" \ + "\20Cap100T4" \ + "\17Cap100XFD" \ + "\16Cap100XHD" \ + "\15Cap10FD" \ + "\14Cap10HD" \ + "\13Cap100T2FD" \ + "\12Cap100T2HD" \ + "\11ExtStsPrsnt" \ + "\10Rsrvd" \ + "\07PrmblSupp" \ + "\06AnegCmpl" \ + "\05RemFaultDet" \ + "\04AnegCap" \ + "\03LnkUp" \ + "\02JabberDet" \ + "\01ExtCapSupp" + +/* MII Autoneg Advertisement Register 0x4 */ +#define BCE_ANAR_PRINTFB \ + "\020" \ + "\20AdvNxtPg" \ + "\17Rsrvd" \ + "\16AdvRemFault" \ + "\15Rsrvd" \ + "\14AdvAsymPause" \ + "\13AdvPause" \ + "\12Adv100T4" \ + "\11Adv100FD" \ + "\10Adv100HD" \ + "\07Adv10FD" \ + "\06Adv10HD" \ + "\05Rsrvd" \ + "\04Rsrvd" \ + "\03Rsrvd" \ + "\02Rsrvd" \ + "\01Adv802.3" + +/* MII Autoneg Link Partner Ability Register 0x5 */ +#define BCE_ANLPAR_PRINTFB \ + "\020" \ + "\20CapNxtPg" \ + "\17Ack" \ + "\16CapRemFault" \ + "\15Rsrvd" \ + "\14CapAsymPause" \ + "\13CapPause" \ + "\12Cap100T4" \ + "\11Cap100FD" \ + "\10Cap100HD" \ + "\07Cap10FD" \ + "\06Cap10HD" \ + "\05Rsrvd" \ + "\04Rsrvd" \ + "\03Rsrvd" \ + "\02Rsrvd" \ + "\01Cap802.3" + +/* 1000Base-T Control Register 0x09 */ +#define BCE_1000CTL_PRINTFB \ + "\020" \ + "\20Test3" \ + "\17Test2" \ + "\16Test1" \ + "\15MasterSlave" \ + "\14ForceMaster" \ + "\13SwitchDev" \ + "\12Adv1000TFD" \ + "\11Adv1000THD" \ + "\10Rsrvd" \ + "\07Rsrvd" \ + "\06Rsrvd" \ + "\05Rsrvd" \ + "\04Rsrvd" \ + "\03Rsrvd" \ + "\02Rsrvd" \ + "\01Rsrvd" + +/* MII 1000Base-T Status Register 0x0a */ +#define BCE_1000STS_PRINTFB \ + "\020" \ + "\20MstrSlvFault" \ + "\17Master" \ + "\16LclRcvrOk" \ + "\15RemRcvrOk" \ + "\14Cap1000FD" \ + "\13Cpa1000HD" \ + "\12Rsrvd" \ + "\11Rsrvd" + +/* MII Extended Status Register 0x0f */ +#define BCE_EXTSTS_PRINTFB \ + "\020" \ + "\20b15" \ + "\17b14" \ + "\16b13" \ + "\15b12" \ + "\14Rsrvd" \ + "\13Rsrvd" \ + "\12Rsrvd" \ + "\11Rsrvd" \ + "\10Rsrvd" \ + "\07Rsrvd" \ + "\06Rsrvd" \ + "\05Rsrvd" \ + "\04Rsrvd" \ + "\03Rsrvd" \ + "\02Rsrvd" \ + "\01Rsrvd" + +/* MII Autoneg Link Partner Ability Register 0x19 */ +#define BCE_AUXSTS_PRINTFB \ + "\020" \ + "\20AnegCmpl" \ + "\17AnegCmplAck" \ + "\16AnegAckDet" \ + "\15AnegAblDet" \ + "\14AnegNextPgWait" \ + "\13HCD" \ + "\12HCD" \ + "\11HCD" \ + "\10PrlDetFault" \ + "\07RemFault" \ + "\06PgRcvd" \ + "\05LnkPrtnrAnegAbl" \ + "\04LnkPrtnrNPAbl" \ + "\03LnkUp" \ + "\02EnaPauseRcv" \ + "\01EnaPausXmit" + +/* Remove before release. */ +/* #define BCE_DEBUG 1 */ +/* #define BCE_NVRAM_WRITE_SUPPORT */ + +/****************************************************************************/ +/* Debugging macros and definitions. */ +/****************************************************************************/ + +#define BCE_CP_LOAD 0x00000001 +#define BCE_CP_SEND 0x00000002 +#define BCE_CP_RECV 0x00000004 +#define BCE_CP_INTR 0x00000008 +#define BCE_CP_UNLOAD 0x00000010 +#define BCE_CP_RESET 0x00000020 +#define BCE_CP_PHY 0x00000040 +#define BCE_CP_NVRAM 0x00000080 +#define BCE_CP_FIRMWARE 0x00000100 +#define BCE_CP_CTX 0x00000200 +#define BCE_CP_REG 0x00000400 +#define BCE_CP_MISC 0x00400000 +#define BCE_CP_SPECIAL 0x00800000 +#define BCE_CP_ALL 0x00FFFFFF + +#define BCE_CP_MASK 0x00FFFFFF + +#define BCE_LEVEL_FATAL 0x00000000 +#define BCE_LEVEL_WARN 0x01000000 +#define BCE_LEVEL_INFO 0x02000000 +#define BCE_LEVEL_VERBOSE 0x03000000 +#define BCE_LEVEL_EXTREME 0x04000000 +#define BCE_LEVEL_INSANE 0x05000000 + +#define BCE_LEVEL_MASK 0xFF000000 + +#define BCE_WARN_LOAD (BCE_CP_LOAD | BCE_LEVEL_WARN) +#define BCE_INFO_LOAD (BCE_CP_LOAD | BCE_LEVEL_INFO) +#define BCE_VERBOSE_LOAD (BCE_CP_LOAD | BCE_LEVEL_VERBOSE) +#define BCE_EXTREME_LOAD (BCE_CP_LOAD | BCE_LEVEL_EXTREME) +#define BCE_INSANE_LOAD (BCE_CP_LOAD | BCE_LEVEL_INSANE) + +#define BCE_WARN_SEND (BCE_CP_SEND | BCE_LEVEL_WARN) +#define BCE_INFO_SEND (BCE_CP_SEND | BCE_LEVEL_INFO) +#define BCE_VERBOSE_SEND (BCE_CP_SEND | BCE_LEVEL_VERBOSE) +#define BCE_EXTREME_SEND (BCE_CP_SEND | BCE_LEVEL_EXTREME) +#define BCE_INSANE_SEND (BCE_CP_SEND | BCE_LEVEL_INSANE) + +#define BCE_WARN_RECV (BCE_CP_RECV | BCE_LEVEL_WARN) +#define BCE_INFO_RECV (BCE_CP_RECV | BCE_LEVEL_INFO) +#define BCE_VERBOSE_RECV (BCE_CP_RECV | BCE_LEVEL_VERBOSE) +#define BCE_EXTREME_RECV (BCE_CP_RECV | BCE_LEVEL_EXTREME) +#define BCE_INSANE_RECV (BCE_CP_RECV | BCE_LEVEL_INSANE) + +#define BCE_WARN_INTR (BCE_CP_INTR | BCE_LEVEL_WARN) +#define BCE_INFO_INTR (BCE_CP_INTR | BCE_LEVEL_INFO) +#define BCE_VERBOSE_INTR (BCE_CP_INTR | BCE_LEVEL_VERBOSE) +#define BCE_EXTREME_INTR (BCE_CP_INTR | BCE_LEVEL_EXTREME) +#define BCE_INSANE_INTR (BCE_CP_INTR | BCE_LEVEL_INSANE) + +#define BCE_WARN_UNLOAD (BCE_CP_UNLOAD | BCE_LEVEL_WARN) +#define BCE_INFO_UNLOAD (BCE_CP_UNLOAD | BCE_LEVEL_INFO) +#define BCE_VERBOSE_UNLOAD (BCE_CP_UNLOAD | BCE_LEVEL_VERBOSE) +#define BCE_EXTREME_UNLOAD (BCE_CP_UNLOAD | BCE_LEVEL_EXTREME) +#define BCE_INSANE_UNLOAD (BCE_CP_UNLOAD | BCE_LEVEL_INSANE) + +#define BCE_WARN_RESET (BCE_CP_RESET | BCE_LEVEL_WARN) +#define BCE_INFO_RESET (BCE_CP_RESET | BCE_LEVEL_INFO) +#define BCE_VERBOSE_RESET (BCE_CP_RESET | BCE_LEVEL_VERBOSE) +#define BCE_EXTREME_RESET (BCE_CP_RESET | BCE_LEVEL_EXTREME) +#define BCE_INSANE_RESET (BCE_CP_RESET | BCE_LEVEL_INSANE) + +#define BCE_WARN_PHY (BCE_CP_PHY | BCE_LEVEL_WARN) +#define BCE_INFO_PHY (BCE_CP_PHY | BCE_LEVEL_INFO) +#define BCE_VERBOSE_PHY (BCE_CP_PHY | BCE_LEVEL_VERBOSE) +#define BCE_EXTREME_PHY (BCE_CP_PHY | BCE_LEVEL_EXTREME) +#define BCE_INSANE_PHY (BCE_CP_PHY | BCE_LEVEL_INSANE) + +#define BCE_WARN_NVRAM (BCE_CP_NVRAM | BCE_LEVEL_WARN) +#define BCE_INFO_NVRAM (BCE_CP_NVRAM | BCE_LEVEL_INFO) +#define BCE_VERBOSE_NVRAM (BCE_CP_NVRAM | BCE_LEVEL_VERBOSE) +#define BCE_EXTREME_NVRAM (BCE_CP_NVRAM | BCE_LEVEL_EXTREME) +#define BCE_INSANE_NVRAM (BCE_CP_NVRAM | BCE_LEVEL_INSANE) + +#define BCE_WARN_FIRMWARE (BCE_CP_FIRMWARE | BCE_LEVEL_WARN) +#define BCE_INFO_FIRMWARE (BCE_CP_FIRMWARE | BCE_LEVEL_INFO) +#define BCE_VERBOSE_FIRMWARE (BCE_CP_FIRMWARE | BCE_LEVEL_VERBOSE) +#define BCE_EXTREME_FIRMWARE (BCE_CP_FIRMWARE | BCE_LEVEL_EXTREME) +#define BCE_INSANE_FIRMWARE (BCE_CP_FIRMWARE | BCE_LEVEL_INSANE) + +#define BCE_WARN_CTX (BCE_CP_CTX | BCE_LEVEL_WARN) +#define BCE_INFO_CTX (BCE_CP_CTX | BCE_LEVEL_INFO) +#define BCE_VERBOSE_CTX (BCE_CP_CTX | BCE_LEVEL_VERBOSE) +#define BCE_EXTREME_CTX (BCE_CP_CTX | BCE_LEVEL_EXTREME) +#define BCE_INSANE_CTX (BCE_CP_CTX | BCE_LEVEL_INSANE) + +#define BCE_WARN_REG (BCE_CP_REG | BCE_LEVEL_WARN) +#define BCE_INFO_REG (BCE_CP_REG | BCE_LEVEL_INFO) +#define BCE_VERBOSE_REG (BCE_CP_REG | BCE_LEVEL_VERBOSE) +#define BCE_EXTREME_REG (BCE_CP_REG | BCE_LEVEL_EXTREME) +#define BCE_INSANE_REG (BCE_CP_REG | BCE_LEVEL_INSANE) + +#define BCE_WARN_MISC (BCE_CP_MISC | BCE_LEVEL_WARN) +#define BCE_INFO_MISC (BCE_CP_MISC | BCE_LEVEL_INFO) +#define BCE_VERBOSE_MISC (BCE_CP_MISC | BCE_LEVEL_VERBOSE) +#define BCE_EXTREME_MISC (BCE_CP_MISC | BCE_LEVEL_EXTREME) +#define BCE_INSANE_MISC (BCE_CP_MISC | BCE_LEVEL_INSANE) + +#define BCE_WARN_SPECIAL (BCE_CP_SPECIAL | BCE_LEVEL_WARN) +#define BCE_INFO_SPECIAL (BCE_CP_SPECIAL | BCE_LEVEL_INFO) +#define BCE_VERBOSE_SPECIAL (BCE_CP_SPECIAL | BCE_LEVEL_VERBOSE) +#define BCE_EXTREME_SPECIAL (BCE_CP_SPECIAL | BCE_LEVEL_EXTREME) +#define BCE_INSANE_SPECIAL (BCE_CP_SPECIAL | BCE_LEVEL_INSANE) + +#define BCE_FATAL (BCE_CP_ALL | BCE_LEVEL_FATAL) +#define BCE_WARN (BCE_CP_ALL | BCE_LEVEL_WARN) +#define BCE_INFO (BCE_CP_ALL | BCE_LEVEL_INFO) +#define BCE_VERBOSE (BCE_CP_ALL | BCE_LEVEL_VERBOSE) +#define BCE_EXTREME (BCE_CP_ALL | BCE_LEVEL_EXTREME) +#define BCE_INSANE (BCE_CP_ALL | BCE_LEVEL_INSANE) + +#define BCE_CODE_PATH(cp) ((cp & BCE_CP_MASK) & bce_debug) +#define BCE_MSG_LEVEL(lv) ((lv & BCE_LEVEL_MASK) <= (bce_debug & BCE_LEVEL_MASK)) +#define BCE_LOG_MSG(m) (BCE_CODE_PATH(m) && BCE_MSG_LEVEL(m)) + +#ifdef BCE_DEBUG + +/* + * Calculate the time delta between two reads + * of the 25MHz free running clock. + */ +#define BCE_TIME_DELTA(start, end) (start > end ? (start - end) : \ + (~start + end + 1)) + +/* Print a message based on the logging level and code path. */ +#define DBPRINT(sc, level, format, args...) \ + if (BCE_LOG_MSG(level)) { \ + device_printf(sc->bce_dev, format, ## args); \ + } + +/* Runs a particular command when debugging is enabled. */ +#define DBRUN(args...) \ + do { \ + args; \ + } while (0) + +/* Runs a particular command based on the logging level and code path. */ +#define DBRUNMSG(msg, args...) \ + if (BCE_LOG_MSG(msg)) { \ + args; \ + } + +/* Runs a particular command based on the logging level. */ +#define DBRUNLV(level, args...) \ + if (BCE_MSG_LEVEL(level)) { \ + args; \ + } + +/* Runs a particular command based on the code path. */ +#define DBRUNCP(cp, args...) \ + if (BCE_CODE_PATH(cp)) { \ + args; \ + } + +/* Runs a particular command based on a condition. */ +#define DBRUNIF(cond, args...) \ + if (cond) { \ + args; \ + } + +/* Announces function entry. */ +#if 0 +#define DBENTER(cond) \ + u32 start_time = REG_RD(sc, BCE_TIMER_25MHZ_FREE_RUN); \ + u32 end_time; \ + DBPRINT(sc, (cond), "%s(enter)\n", __FUNCTION__); +#endif + +#define DBENTER(cond) \ + DBPRINT(sc, (cond), "%s(enter)\n", __FUNCTION__) + +/* Announces function exit. */ +#if 0 +#define DBEXIT(cond, val) \ + end_time = REG_RD(sc, BCE_TIMER_25MHZ_FREE_RUN); \ + val += (u64) BCE_TIME_DELTA(start_time, end_time); \ + DBPRINT(sc, (cond), "%s(exit)\n", __FUNCTION__); +#endif + +#define DBEXIT(cond) \ + DBPRINT(sc, (cond), "%s(exit)\n", __FUNCTION__) + +/* Temporarily override the debug level. */ +#define DBPUSH(cond) \ + u32 bce_debug_temp = bce_debug; \ + bce_debug |= cond; + +/* Restore the previously overriden debug level. */ +#define DBPOP() \ + bce_debug = bce_debug_temp; + +/* Needed for random() function which is only used in debugging. */ +#include + +/* Returns FALSE in "defects" per 2^31 - 1 calls, otherwise returns TRUE. */ +#define DB_RANDOMFALSE(defects) (random() > defects) +#define DB_OR_RANDOMFALSE(defects) || (random() > defects) +#define DB_AND_RANDOMFALSE(defects) && (random() > ddfects) + +/* Returns TRUE in "defects" per 2^31 - 1 calls, otherwise returns FALSE. */ +#define DB_RANDOMTRUE(defects) (random() < defects) +#define DB_OR_RANDOMTRUE(defects) || (random() < defects) +#define DB_AND_RANDOMTRUE(defects) && (random() < defects) + +#define DB_PRINT_PHY_REG(reg, val) \ + switch(reg) { \ + case 0x00: DBPRINT(sc, BCE_INSANE_PHY, \ + "%s(): phy = %d, reg = 0x%04X (BMCR ), val = 0x%b\n", \ + __FUNCTION__, phy, (u16) reg & 0xffff, (u16) val & 0xffff, \ + BCE_BMCR_PRINTFB); break; \ + case 0x01: DBPRINT(sc, BCE_INSANE_PHY, \ + "%s(): phy = %d, reg = 0x%04X (BMSR ), val = 0x%b\n", \ + __FUNCTION__, phy, (u16) reg & 0xffff, (u16) val & 0xffff, \ + BCE_BMSR_PRINTFB); break; \ + case 0x04: DBPRINT(sc, BCE_INSANE_PHY, \ + "%s(): phy = %d, reg = 0x%04X (ANAR ), val = 0x%b\n", \ + __FUNCTION__, phy, (u16) reg & 0xffff, (u16) val & 0xffff, \ + BCE_ANAR_PRINTFB); break; \ + case 0x05: DBPRINT(sc, BCE_INSANE_PHY, \ + "%s(): phy = %d, reg = 0x%04X (ANLPAR ), val = 0x%b\n", \ + __FUNCTION__, phy, (u16) reg & 0xffff, (u16) val & 0xffff, \ + BCE_ANLPAR_PRINTFB); break; \ + case 0x09: DBPRINT(sc, BCE_INSANE_PHY, \ + "%s(): phy = %d, reg = 0x%04X (1000CTL), val = 0x%b\n", \ + __FUNCTION__, phy, (u16) reg & 0xffff, (u16) val & 0xffff, \ + BCE_1000CTL_PRINTFB); break; \ + case 0x0a: DBPRINT(sc, BCE_INSANE_PHY, \ + "%s(): phy = %d, reg = 0x%04X (1000STS), val = 0x%b\n", \ + __FUNCTION__, phy, (u16) reg & 0xffff, (u16) val & 0xffff, \ + BCE_1000STS_PRINTFB); break; \ + case 0x0f: DBPRINT(sc, BCE_INSANE_PHY, \ + "%s(): phy = %d, reg = 0x%04X (EXTSTS ), val = 0x%b\n", \ + __FUNCTION__, phy, (u16) reg & 0xffff, (u16) val & 0xffff, \ + BCE_EXTSTS_PRINTFB); break; \ + case 0x19: DBPRINT(sc, BCE_INSANE_PHY, \ + "%s(): phy = %d, reg = 0x%04X (AUXSTS ), val = 0x%b\n", \ + __FUNCTION__, phy, (u16) reg & 0xffff, (u16) val & 0xffff, \ + BCE_AUXSTS_PRINTFB); break; \ + default: DBPRINT(sc, BCE_INSANE_PHY, \ + "%s(): phy = %d, reg = 0x%04X, val = 0x%04X\n", \ + __FUNCTION__, phy, (u16) reg & 0xffff, (u16) val & 0xffff); \ + } + +#else + +#define DBPRINT(level, format, args...) +#define DBRUN(args...) +#define DBRUNMSG(msg, args...) +#define DBRUNLV(level, args...) +#define DBRUNCP(cp, args...) +#define DBRUNIF(cond, args...) +#define DBENTER(cond) +#define DBEXIT(cond) +#define DBPUSH(cond) +#define DBPOP() +#define DB_RANDOMFALSE(defects) +#define DB_OR_RANDOMFALSE(percent) +#define DB_AND_RANDOMFALSE(percent) +#define DB_RANDOMTRUE(defects) +#define DB_OR_RANDOMTRUE(percent) +#define DB_AND_RANDOMTRUE(percent) +#define DB_PRINT_PHY_REG(reg, val) + +#endif /* BCE_DEBUG */ + +#if defined(__i386__) || defined(__amd64__) +#define mb() __asm volatile("mfence" ::: "memory") +#define wmb() __asm volatile("sfence" ::: "memory") +#define rmb() __asm volatile("lfence" ::: "memory") +#else +#define mb() +#define rmb() +#define wmb() +#endif + +/****************************************************************************/ +/* Device identification definitions. */ +/****************************************************************************/ +#define BRCM_VENDORID 0x14E4 +#define BRCM_DEVICEID_BCM5706 0x164A +#define BRCM_DEVICEID_BCM5706S 0x16AA +#define BRCM_DEVICEID_BCM5708 0x164C +#define BRCM_DEVICEID_BCM5708S 0x16AC +#define BRCM_DEVICEID_BCM5709 0x1639 +#define BRCM_DEVICEID_BCM5709S 0x163A +#define BRCM_DEVICEID_BCM5716 0x163B + +#define HP_VENDORID 0x103C + +#define PCI_ANY_ID (u_int16_t) (~0U) + +/* chip num:16-31, rev:12-15, metal:4-11, bond_id:0-3 */ + +#define BCE_CHIP_NUM(sc) (((sc)->bce_chipid) & 0xffff0000) +#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 +#define BCE_CHIP_REV_Bx 0x00001000 +#define BCE_CHIP_REV_Cx 0x00002000 + +#define BCE_CHIP_METAL(sc) (((sc)->bce_chipid) & 0x00000ff0) +#define BCE_CHIP_BOND(bp) (((sc)->bce_chipid) & 0x0000000f) + +#define BCE_CHIP_ID(sc) (((sc)->bce_chipid) & 0xfffffff0) +#define BCE_CHIP_ID_5706_A0 0x57060000 +#define BCE_CHIP_ID_5706_A1 0x57060010 +#define BCE_CHIP_ID_5706_A2 0x57060020 +#define BCE_CHIP_ID_5706_A3 0x57060030 +#define BCE_CHIP_ID_5708_A0 0x57080000 +#define BCE_CHIP_ID_5708_B0 0x57081000 +#define BCE_CHIP_ID_5708_B1 0x57081010 +#define BCE_CHIP_ID_5708_B2 0x57081020 +#define BCE_CHIP_ID_5709_A0 0x57090000 +#define BCE_CHIP_ID_5709_A1 0x57090010 +#define BCE_CHIP_ID_5709_B0 0x57091000 +#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) + +/* A serdes chip will have the first bit of the bond id set. */ +#define BCE_CHIP_BOND_ID_SERDES_BIT 0x01 + + +/* shorthand one */ +#define BCE_ASICREV(x) ((x) >> 28) +#define BCE_ASICREV_BCM5700 0x06 + +/* chip revisions */ +#define BCE_CHIPREV(x) ((x) >> 24) +#define BCE_CHIPREV_5700_AX 0x70 +#define BCE_CHIPREV_5700_BX 0x71 +#define BCE_CHIPREV_5700_CX 0x72 +#define BCE_CHIPREV_5701_AX 0x00 + +struct bce_type { + u_int16_t bce_vid; + u_int16_t bce_did; + u_int16_t bce_svid; + u_int16_t bce_sdid; + char *bce_name; +}; + +/****************************************************************************/ +/* Byte order conversions. */ +/****************************************************************************/ +#if __FreeBSD_version >= 500000 +#define bce_htobe16(x) htobe16(x) +#define bce_htobe32(x) htobe32(x) +#define bce_htobe64(x) htobe64(x) +#define bce_htole16(x) htole16(x) +#define bce_htole32(x) htole32(x) +#define bce_htole64(x) htole64(x) + +#define bce_be16toh(x) be16toh(x) +#define bce_be32toh(x) be32toh(x) +#define bce_be64toh(x) be64toh(x) +#define bce_le16toh(x) le16toh(x) +#define bce_le32toh(x) le32toh(x) +#define bce_le64toh(x) le64toh(x) +#else +#define bce_htobe16(x) (x) +#define bce_htobe32(x) (x) +#define bce_htobe64(x) (x) +#define bce_htole16(x) (x) +#define bce_htole32(x) (x) +#define bce_htole64(x) (x) + +#define bce_be16toh(x) (x) +#define bce_be32toh(x) (x) +#define bce_be64toh(x) (x) +#define bce_le16toh(x) (x) +#define bce_le32toh(x) (x) +#define bce_le64toh(x) (x) +#endif + + +/****************************************************************************/ +/* NVRAM Access */ +/****************************************************************************/ + +/* Buffered flash (Atmel: AT45DB011B) specific information */ +#define SEEPROM_PAGE_BITS 2 +#define SEEPROM_PHY_PAGE_SIZE (1 << SEEPROM_PAGE_BITS) +#define SEEPROM_BYTE_ADDR_MASK (SEEPROM_PHY_PAGE_SIZE-1) +#define SEEPROM_PAGE_SIZE 4 +#define SEEPROM_TOTAL_SIZE 65536 + +#define BUFFERED_FLASH_PAGE_BITS 9 +#define BUFFERED_FLASH_PHY_PAGE_SIZE (1 << BUFFERED_FLASH_PAGE_BITS) +#define BUFFERED_FLASH_BYTE_ADDR_MASK (BUFFERED_FLASH_PHY_PAGE_SIZE-1) +#define BUFFERED_FLASH_PAGE_SIZE 264 +#define BUFFERED_FLASH_TOTAL_SIZE 0x21000 + +#define SAIFUN_FLASH_PAGE_BITS 8 +#define SAIFUN_FLASH_PHY_PAGE_SIZE (1 << SAIFUN_FLASH_PAGE_BITS) +#define SAIFUN_FLASH_BYTE_ADDR_MASK (SAIFUN_FLASH_PHY_PAGE_SIZE-1) +#define SAIFUN_FLASH_PAGE_SIZE 256 +#define SAIFUN_FLASH_BASE_TOTAL_SIZE 65536 + +#define ST_MICRO_FLASH_PAGE_BITS 8 +#define ST_MICRO_FLASH_PHY_PAGE_SIZE (1 << ST_MICRO_FLASH_PAGE_BITS) +#define ST_MICRO_FLASH_BYTE_ADDR_MASK (ST_MICRO_FLASH_PHY_PAGE_SIZE-1) +#define ST_MICRO_FLASH_PAGE_SIZE 256 +#define ST_MICRO_FLASH_BASE_TOTAL_SIZE 65536 + +#define BCM5709_FLASH_PAGE_BITS 8 +#define BCM5709_FLASH_PHY_PAGE_SIZE (1 << BCM5709_FLASH_PAGE_BITS) +#define BCM5709_FLASH_BYTE_ADDR_MASK (BCM5709_FLASH_PHY_PAGE_SIZE-1) +#define BCM5709_FLASH_PAGE_SIZE 256 + +#define NVRAM_TIMEOUT_COUNT 30000 +#define BCE_FLASHDESC_MAX 64 + +#define FLASH_STRAP_MASK (BCE_NVM_CFG1_FLASH_MODE | \ + BCE_NVM_CFG1_BUFFER_MODE | \ + BCE_NVM_CFG1_PROTECT_MODE | \ + BCE_NVM_CFG1_FLASH_SIZE) + +#define FLASH_BACKUP_STRAP_MASK (0xf << 26) + +struct flash_spec { + u32 strapping; + u32 config1; + u32 config2; + u32 config3; + u32 write1; +#define BCE_NV_BUFFERED 0x00000001 +#define BCE_NV_TRANSLATE 0x00000002 +#define BCE_NV_WREN 0x00000004 + u32 flags; + u32 page_bits; + u32 page_size; + u32 addr_mask; + u32 total_size; + u8 *name; +}; + + +/****************************************************************************/ +/* Shared Memory layout */ +/* The BCE bootcode will initialize this data area with port configurtion */ +/* information which can be accessed by the driver. */ +/****************************************************************************/ + +/* + * This value (in milliseconds) determines the frequency of the driver + * issuing the PULSE message code. The firmware monitors this periodic + * pulse to determine when to switch to an OS-absent mode. + */ +#define DRV_PULSE_PERIOD_MS 250 + +/* + * This value (in milliseconds) determines how long the driver should + * wait for an acknowledgement from the firmware before timing out. Once + * the firmware has timed out, the driver will assume there is no firmware + * running and there won't be any firmware-driver synchronization during a + * driver reset. + */ +#define FW_ACK_TIME_OUT_MS 1000 + + +#define BCE_DRV_RESET_SIGNATURE 0x00000000 +#define BCE_DRV_RESET_SIGNATURE_MAGIC 0x4841564b /* HAVK */ + +#define BCE_DRV_MB 0x00000004 +#define BCE_DRV_MSG_CODE 0xff000000 +#define BCE_DRV_MSG_CODE_RESET 0x01000000 +#define BCE_DRV_MSG_CODE_UNLOAD 0x02000000 +#define BCE_DRV_MSG_CODE_SHUTDOWN 0x03000000 +#define BCE_DRV_MSG_CODE_SUSPEND_WOL 0x04000000 +#define BCE_DRV_MSG_CODE_FW_TIMEOUT 0x05000000 +#define BCE_DRV_MSG_CODE_PULSE 0x06000000 +#define BCE_DRV_MSG_CODE_DIAG 0x07000000 +#define BCE_DRV_MSG_CODE_SUSPEND_NO_WOL 0x09000000 +#define BCE_DRV_MSG_CODE_UNLOAD_LNK_DN 0x0b000000 +#define BCE_DRV_MSG_CODE_CMD_SET_LINK 0x10000000 + +#define BCE_DRV_MSG_DATA 0x00ff0000 +#define BCE_DRV_MSG_DATA_WAIT0 0x00010000 +#define BCE_DRV_MSG_DATA_WAIT1 0x00020000 +#define BCE_DRV_MSG_DATA_WAIT2 0x00030000 +#define BCE_DRV_MSG_DATA_WAIT3 0x00040000 + +#define BCE_DRV_MSG_SEQ 0x0000ffff + +#define BCE_FW_MB 0x00000008 +#define BCE_FW_MSG_ACK 0x0000ffff +#define BCE_FW_MSG_STATUS_MASK 0x00ff0000 +#define BCE_FW_MSG_STATUS_OK 0x00000000 +#define BCE_FW_MSG_STATUS_FAILURE 0x00ff0000 + +#define BCE_LINK_STATUS 0x0000000c +#define BCE_LINK_STATUS_INIT_VALUE 0xffffffff +#define BCE_LINK_STATUS_LINK_UP 0x1 +#define BCE_LINK_STATUS_LINK_DOWN 0x0 +#define BCE_LINK_STATUS_SPEED_MASK 0x1e +#define BCE_LINK_STATUS_AN_INCOMPLETE (0<<1) +#define BCE_LINK_STATUS_10HALF (1<<1) +#define BCE_LINK_STATUS_10FULL (2<<1) +#define BCE_LINK_STATUS_100HALF (3<<1) +#define BCE_LINK_STATUS_100BASE_T4 (4<<1) +#define BCE_LINK_STATUS_100FULL (5<<1) +#define BCE_LINK_STATUS_1000HALF (6<<1) +#define BCE_LINK_STATUS_1000FULL (7<<1) +#define BCE_LINK_STATUS_2500HALF (8<<1) +#define BCE_LINK_STATUS_2500FULL (9<<1) +#define BCE_LINK_STATUS_AN_ENABLED (1<<5) +#define BCE_LINK_STATUS_AN_COMPLETE (1<<6) +#define BCE_LINK_STATUS_PARALLEL_DET (1<<7) +#define BCE_LINK_STATUS_RESERVED (1<<8) +#define BCE_LINK_STATUS_PARTNER_AD_1000FULL (1<<9) +#define BCE_LINK_STATUS_PARTNER_AD_1000HALF (1<<10) +#define BCE_LINK_STATUS_PARTNER_AD_100BT4 (1<<11) +#define BCE_LINK_STATUS_PARTNER_AD_100FULL (1<<12) +#define BCE_LINK_STATUS_PARTNER_AD_100HALF (1<<13) +#define BCE_LINK_STATUS_PARTNER_AD_10FULL (1<<14) +#define BCE_LINK_STATUS_PARTNER_AD_10HALF (1<<15) +#define BCE_LINK_STATUS_TX_FC_ENABLED (1<<16) +#define BCE_LINK_STATUS_RX_FC_ENABLED (1<<17) +#define BCE_LINK_STATUS_PARTNER_SYM_PAUSE_CAP (1<<18) +#define BCE_LINK_STATUS_PARTNER_ASYM_PAUSE_CAP (1<<19) +#define BCE_LINK_STATUS_SERDES_LINK (1<<20) +#define BCE_LINK_STATUS_PARTNER_AD_2500FULL (1<<21) +#define BCE_LINK_STATUS_PARTNER_AD_2500HALF (1<<22) + +#define BCE_DRV_PULSE_MB 0x00000010 +#define BCE_DRV_PULSE_SEQ_MASK 0x00007fff + +#define BCE_MB_ARGS_0 0x00000014 +#define BCE_MB_ARGS_1 0x00000018 + +/* Indicate to the firmware not to go into the + * OS absent when it is not getting driver pulse. + * This is used for debugging. */ +#define BCE_DRV_MSG_DATA_PULSE_CODE_ALWAYS_ALIVE 0x00080000 + +#define BCE_DEV_INFO_SIGNATURE 0x00000020 +#define BCE_DEV_INFO_SIGNATURE_MAGIC 0x44564900 +#define BCE_DEV_INFO_SIGNATURE_MAGIC_MASK 0xffffff00 +#define BCE_DEV_INFO_FEATURE_CFG_VALID 0x01 +#define BCE_DEV_INFO_SECONDARY_PORT 0x80 +#define BCE_DEV_INFO_DRV_ALWAYS_ALIVE 0x40 + +#define BCE_SHARED_HW_CFG_PART_NUM 0x00000024 + +#define BCE_SHARED_HW_CFG_POWER_DISSIPATED 0x00000034 +#define BCE_SHARED_HW_CFG_POWER_STATE_D3_MASK 0xff000000 +#define BCE_SHARED_HW_CFG_POWER_STATE_D2_MASK 0xff0000 +#define BCE_SHARED_HW_CFG_POWER_STATE_D1_MASK 0xff00 +#define BCE_SHARED_HW_CFG_POWER_STATE_D0_MASK 0xff + +#define BCE_SHARED_HW_CFG_POWER_CONSUMED 0x00000038 +#define BCE_SHARED_HW_CFG_CONFIG 0x0000003c +#define BCE_SHARED_HW_CFG_DESIGN_NIC 0 +#define BCE_SHARED_HW_CFG_DESIGN_LOM 0x1 +#define BCE_SHARED_HW_CFG_PHY_COPPER 0 +#define BCE_SHARED_HW_CFG_PHY_FIBER 0x2 +#define BCE_SHARED_HW_CFG_PHY_2_5G 0x20 +#define BCE_SHARED_HW_CFG_PHY_BACKPLANE 0x40 +#define BCE_SHARED_HW_CFG_LED_MODE_SHIFT_BITS 8 +#define BCE_SHARED_HW_CFG_LED_MODE_MASK 0x300 +#define BCE_SHARED_HW_CFG_LED_MODE_MAC 0 +#define BCE_SHARED_HW_CFG_LED_MODE_GPHY1 0x100 +#define BCE_SHARED_HW_CFG_LED_MODE_GPHY2 0x200 + +#define BCE_SHARED_HW_CFG_CONFIG2 0x00000040 +#define BCE_SHARED_HW_CFG2_NVM_SIZE_MASK 0x00fff000 + +#define BCE_DEV_INFO_BC_REV 0x0000004c + +#define BCE_PORT_HW_CFG_MAC_UPPER 0x00000050 +#define BCE_PORT_HW_CFG_UPPERMAC_MASK 0xffff + +#define BCE_PORT_HW_CFG_MAC_LOWER 0x00000054 +#define BCE_PORT_HW_CFG_CONFIG 0x00000058 +#define BCE_PORT_HW_CFG_CFG_TXCTL3_MASK 0x0000ffff +#define BCE_PORT_HW_CFG_CFG_DFLT_LINK_MASK 0x001f0000 +#define BCE_PORT_HW_CFG_CFG_DFLT_LINK_AN 0x00000000 +#define BCE_PORT_HW_CFG_CFG_DFLT_LINK_1G 0x00030000 +#define BCE_PORT_HW_CFG_CFG_DFLT_LINK_2_5G 0x00040000 + +#define BCE_PORT_HW_CFG_IMD_MAC_A_UPPER 0x00000068 +#define BCE_PORT_HW_CFG_IMD_MAC_A_LOWER 0x0000006c +#define BCE_PORT_HW_CFG_IMD_MAC_B_UPPER 0x00000070 +#define BCE_PORT_HW_CFG_IMD_MAC_B_LOWER 0x00000074 +#define BCE_PORT_HW_CFG_ISCSI_MAC_UPPER 0x00000078 +#define BCE_PORT_HW_CFG_ISCSI_MAC_LOWER 0x0000007c + +#define BCE_DEV_INFO_PER_PORT_HW_CONFIG2 0x000000b4 + +#define BCE_DEV_INFO_FORMAT_REV 0x000000c4 +#define BCE_DEV_INFO_FORMAT_REV_MASK 0xff000000 +#define BCE_DEV_INFO_FORMAT_REV_ID ('A' << 24) + +#define BCE_SHARED_FEATURE 0x000000c8 +#define BCE_SHARED_FEATURE_MASK 0xffffffff + +#define BCE_PORT_FEATURE 0x000000d8 +#define BCE_PORT2_FEATURE 0x00000014c +#define BCE_PORT_FEATURE_WOL_ENABLED 0x01000000 +#define BCE_PORT_FEATURE_MBA_ENABLED 0x02000000 +#define BCE_PORT_FEATURE_ASF_ENABLED 0x04000000 +#define BCE_PORT_FEATURE_IMD_ENABLED 0x08000000 +#define BCE_PORT_FEATURE_BAR1_SIZE_MASK 0xf +#define BCE_PORT_FEATURE_BAR1_SIZE_DISABLED 0x0 +#define BCE_PORT_FEATURE_BAR1_SIZE_64K 0x1 +#define BCE_PORT_FEATURE_BAR1_SIZE_128K 0x2 +#define BCE_PORT_FEATURE_BAR1_SIZE_256K 0x3 +#define BCE_PORT_FEATURE_BAR1_SIZE_512K 0x4 +#define BCE_PORT_FEATURE_BAR1_SIZE_1M 0x5 +#define BCE_PORT_FEATURE_BAR1_SIZE_2M 0x6 +#define BCE_PORT_FEATURE_BAR1_SIZE_4M 0x7 +#define BCE_PORT_FEATURE_BAR1_SIZE_8M 0x8 +#define BCE_PORT_FEATURE_BAR1_SIZE_16M 0x9 +#define BCE_PORT_FEATURE_BAR1_SIZE_32M 0xa +#define BCE_PORT_FEATURE_BAR1_SIZE_64M 0xb +#define BCE_PORT_FEATURE_BAR1_SIZE_128M 0xc +#define BCE_PORT_FEATURE_BAR1_SIZE_256M 0xd +#define BCE_PORT_FEATURE_BAR1_SIZE_512M 0xe +#define BCE_PORT_FEATURE_BAR1_SIZE_1G 0xf + +#define BCE_PORT_FEATURE_WOL 0xdc +#define BCE_PORT2_FEATURE_WOL 0x150 +#define BCE_PORT_FEATURE_WOL_DEFAULT_SHIFT_BITS 4 +#define BCE_PORT_FEATURE_WOL_DEFAULT_MASK 0x30 +#define BCE_PORT_FEATURE_WOL_DEFAULT_DISABLE 0 +#define BCE_PORT_FEATURE_WOL_DEFAULT_MAGIC 0x10 +#define BCE_PORT_FEATURE_WOL_DEFAULT_ACPI 0x20 +#define BCE_PORT_FEATURE_WOL_DEFAULT_MAGIC_AND_ACPI 0x30 +#define BCE_PORT_FEATURE_WOL_LINK_SPEED_MASK 0xf +#define BCE_PORT_FEATURE_WOL_LINK_SPEED_AUTONEG 0 +#define BCE_PORT_FEATURE_WOL_LINK_SPEED_10HALF 1 +#define BCE_PORT_FEATURE_WOL_LINK_SPEED_10FULL 2 +#define BCE_PORT_FEATURE_WOL_LINK_SPEED_100HALF 3 +#define BCE_PORT_FEATURE_WOL_LINK_SPEED_100FULL 4 +#define BCE_PORT_FEATURE_WOL_LINK_SPEED_1000HALF 5 +#define BCE_PORT_FEATURE_WOL_LINK_SPEED_1000FULL 6 +#define BCE_PORT_FEATURE_WOL_AUTONEG_ADVERTISE_1000 0x40 +#define BCE_PORT_FEATURE_WOL_RESERVED_PAUSE_CAP 0x400 +#define BCE_PORT_FEATURE_WOL_RESERVED_ASYM_PAUSE_CAP 0x800 + +#define BCE_PORT_FEATURE_MBA 0xe0 +#define BCE_PORT2_FEATURE_MBA 0x154 +#define BCE_PORT_FEATURE_MBA_BOOT_AGENT_TYPE_SHIFT_BITS 0 +#define BCE_PORT_FEATURE_MBA_BOOT_AGENT_TYPE_MASK 0x3 +#define BCE_PORT_FEATURE_MBA_BOOT_AGENT_TYPE_PXE 0 +#define BCE_PORT_FEATURE_MBA_BOOT_AGENT_TYPE_RPL 1 +#define BCE_PORT_FEATURE_MBA_BOOT_AGENT_TYPE_BOOTP 2 +#define BCE_PORT_FEATURE_MBA_LINK_SPEED_SHIFT_BITS 2 +#define BCE_PORT_FEATURE_MBA_LINK_SPEED_MASK 0x3c +#define BCE_PORT_FEATURE_MBA_LINK_SPEED_AUTONEG 0 +#define BCE_PORT_FEATURE_MBA_LINK_SPEED_10HALF 0x4 +#define BCE_PORT_FEATURE_MBA_LINK_SPEED_10FULL 0x8 +#define BCE_PORT_FEATURE_MBA_LINK_SPEED_100HALF 0xc +#define BCE_PORT_FEATURE_MBA_LINK_SPEED_100FULL 0x10 +#define BCE_PORT_FEATURE_MBA_LINK_SPEED_1000HALF 0x14 +#define BCE_PORT_FEATURE_MBA_LINK_SPEED_1000FULL 0x18 +#define BCE_PORT_FEATURE_MBA_SETUP_PROMPT_ENABLE 0x40 +#define BCE_PORT_FEATURE_MBA_HOTKEY_CTRL_S 0 +#define BCE_PORT_FEATURE_MBA_HOTKEY_CTRL_B 0x80 +#define BCE_PORT_FEATURE_MBA_EXP_ROM_SIZE_SHIFT_BITS 8 +#define BCE_PORT_FEATURE_MBA_EXP_ROM_SIZE_MASK 0xff00 +#define BCE_PORT_FEATURE_MBA_EXP_ROM_SIZE_DISABLED 0 +#define BCE_PORT_FEATURE_MBA_EXP_ROM_SIZE_1K 0x100 +#define BCE_PORT_FEATURE_MBA_EXP_ROM_SIZE_2K 0x200 +#define BCE_PORT_FEATURE_MBA_EXP_ROM_SIZE_4K 0x300 +#define BCE_PORT_FEATURE_MBA_EXP_ROM_SIZE_8K 0x400 +#define BCE_PORT_FEATURE_MBA_EXP_ROM_SIZE_16K 0x500 +#define BCE_PORT_FEATURE_MBA_EXP_ROM_SIZE_32K 0x600 +#define BCE_PORT_FEATURE_MBA_EXP_ROM_SIZE_64K 0x700 +#define BCE_PORT_FEATURE_MBA_EXP_ROM_SIZE_128K 0x800 +#define BCE_PORT_FEATURE_MBA_EXP_ROM_SIZE_256K 0x900 +#define BCE_PORT_FEATURE_MBA_EXP_ROM_SIZE_512K 0xa00 +#define BCE_PORT_FEATURE_MBA_EXP_ROM_SIZE_1M 0xb00 +#define BCE_PORT_FEATURE_MBA_EXP_ROM_SIZE_2M 0xc00 +#define BCE_PORT_FEATURE_MBA_EXP_ROM_SIZE_4M 0xd00 +#define BCE_PORT_FEATURE_MBA_EXP_ROM_SIZE_8M 0xe00 +#define BCE_PORT_FEATURE_MBA_EXP_ROM_SIZE_16M 0xf00 +#define BCE_PORT_FEATURE_MBA_MSG_TIMEOUT_SHIFT_BITS 16 +#define BCE_PORT_FEATURE_MBA_MSG_TIMEOUT_MASK 0xf0000 +#define BCE_PORT_FEATURE_MBA_BIOS_BOOTSTRAP_SHIFT_BITS 20 +#define BCE_PORT_FEATURE_MBA_BIOS_BOOTSTRAP_MASK 0x300000 +#define BCE_PORT_FEATURE_MBA_BIOS_BOOTSTRAP_AUTO 0 +#define BCE_PORT_FEATURE_MBA_BIOS_BOOTSTRAP_BBS 0x100000 +#define BCE_PORT_FEATURE_MBA_BIOS_BOOTSTRAP_INT18H 0x200000 +#define BCE_PORT_FEATURE_MBA_BIOS_BOOTSTRAP_INT19H 0x300000 + +#define BCE_PORT_FEATURE_IMD 0xe4 +#define BCE_PORT2_FEATURE_IMD 0x158 +#define BCE_PORT_FEATURE_IMD_LINK_OVERRIDE_DEFAULT 0 +#define BCE_PORT_FEATURE_IMD_LINK_OVERRIDE_ENABLE 1 + +#define BCE_PORT_FEATURE_VLAN 0xe8 +#define BCE_PORT2_FEATURE_VLAN 0x15c +#define BCE_PORT_FEATURE_MBA_VLAN_TAG_MASK 0xffff +#define BCE_PORT_FEATURE_MBA_VLAN_ENABLE 0x10000 + +#define BCE_BC_STATE_RESET_TYPE 0x000001c0 +#define BCE_BC_STATE_RESET_TYPE_SIG 0x00005254 +#define BCE_BC_STATE_RESET_TYPE_SIG_MASK 0x0000ffff +#define BCE_BC_STATE_RESET_TYPE_NONE (BCE_BC_STATE_RESET_TYPE_SIG | \ + 0x00010000) +#define BCE_BC_STATE_RESET_TYPE_PCI (BCE_BC_STATE_RESET_TYPE_SIG | \ + 0x00020000) +#define BCE_BC_STATE_RESET_TYPE_VAUX (BCE_BC_STATE_RESET_TYPE_SIG | \ + 0x00030000) +#define BCE_BC_STATE_RESET_TYPE_DRV_MASK DRV_MSG_CODE +#define BCE_BC_STATE_RESET_TYPE_DRV_RESET (BCE_BC_STATE_RESET_TYPE_SIG | \ + DRV_MSG_CODE_RESET) +#define BCE_BC_STATE_RESET_TYPE_DRV_UNLOAD (BCE_BC_STATE_RESET_TYPE_SIG | \ + DRV_MSG_CODE_UNLOAD) +#define BCE_BC_STATE_RESET_TYPE_DRV_SHUTDOWN (BCE_BC_STATE_RESET_TYPE_SIG | \ + DRV_MSG_CODE_SHUTDOWN) +#define BCE_BC_STATE_RESET_TYPE_DRV_WOL (BCE_BC_STATE_RESET_TYPE_SIG | \ + DRV_MSG_CODE_WOL) +#define BCE_BC_STATE_RESET_TYPE_DRV_DIAG (BCE_BC_STATE_RESET_TYPE_SIG | \ + DRV_MSG_CODE_DIAG) +#define BCE_BC_STATE_RESET_TYPE_VALUE(msg) (BCE_BC_STATE_RESET_TYPE_SIG | \ + (msg)) + +#define BCE_BC_RESET_TYPE 0x000001c0 + +#define BCE_BC_STATE 0x000001c4 +#define BCE_BC_STATE_ERR_MASK 0x0000ff00 +#define BCE_BC_STATE_SIGN 0x42530000 +#define BCE_BC_STATE_SIGN_MASK 0xffff0000 +#define BCE_BC_STATE_BC1_START (BCE_BC_STATE_SIGN | 0x1) +#define BCE_BC_STATE_GET_NVM_CFG1 (BCE_BC_STATE_SIGN | 0x2) +#define BCE_BC_STATE_PROG_BAR (BCE_BC_STATE_SIGN | 0x3) +#define BCE_BC_STATE_INIT_VID (BCE_BC_STATE_SIGN | 0x4) +#define BCE_BC_STATE_GET_NVM_CFG2 (BCE_BC_STATE_SIGN | 0x5) +#define BCE_BC_STATE_APPLY_WKARND (BCE_BC_STATE_SIGN | 0x6) +#define BCE_BC_STATE_LOAD_BC2 (BCE_BC_STATE_SIGN | 0x7) +#define BCE_BC_STATE_GOING_BC2 (BCE_BC_STATE_SIGN | 0x8) +#define BCE_BC_STATE_GOING_DIAG (BCE_BC_STATE_SIGN | 0x9) +#define BCE_BC_STATE_RT_FINAL_INIT (BCE_BC_STATE_SIGN | 0x81) +#define BCE_BC_STATE_RT_WKARND (BCE_BC_STATE_SIGN | 0x82) +#define BCE_BC_STATE_RT_DRV_PULSE (BCE_BC_STATE_SIGN | 0x83) +#define BCE_BC_STATE_RT_FIOEVTS (BCE_BC_STATE_SIGN | 0x84) +#define BCE_BC_STATE_RT_DRV_CMD (BCE_BC_STATE_SIGN | 0x85) +#define BCE_BC_STATE_RT_LOW_POWER (BCE_BC_STATE_SIGN | 0x86) +#define BCE_BC_STATE_RT_SET_WOL (BCE_BC_STATE_SIGN | 0x87) +#define BCE_BC_STATE_RT_OTHER_FW (BCE_BC_STATE_SIGN | 0x88) +#define BCE_BC_STATE_RT_GOING_D3 (BCE_BC_STATE_SIGN | 0x89) +#define BCE_BC_STATE_ERR_BAD_VERSION (BCE_BC_STATE_SIGN | 0x0100) +#define BCE_BC_STATE_ERR_BAD_BC2_CRC (BCE_BC_STATE_SIGN | 0x0200) +#define BCE_BC_STATE_ERR_BC1_LOOP (BCE_BC_STATE_SIGN | 0x0300) +#define BCE_BC_STATE_ERR_UNKNOWN_CMD (BCE_BC_STATE_SIGN | 0x0400) +#define BCE_BC_STATE_ERR_DRV_DEAD (BCE_BC_STATE_SIGN | 0x0500) +#define BCE_BC_STATE_ERR_NO_RXP (BCE_BC_STATE_SIGN | 0x0600) +#define BCE_BC_STATE_ERR_TOO_MANY_RBUF (BCE_BC_STATE_SIGN | 0x0700) + +#define BCE_BC_CONDITION 0x000001c8 + +#define BCE_BC_STATE_DEBUG_CMD 0x1dc +#define BCE_BC_STATE_BC_DBG_CMD_SIGNATURE 0x42440000 +#define BCE_BC_STATE_BC_DBG_CMD_SIGNATURE_MASK 0xffff0000 +#define BCE_BC_STATE_BC_DBG_CMD_LOOP_CNT_MASK 0xffff +#define BCE_BC_STATE_BC_DBG_CMD_LOOP_INFINITE 0xffff + +#define HOST_VIEW_SHMEM_BASE 0x167c00 + +/* + * PCI registers defined in the PCI 2.2 spec. + */ +#define BCE_PCI_PCIX_CMD 0x42 + + +/****************************************************************************/ +/* Convenience definitions. */ +/****************************************************************************/ +#define BCE_PRINTF(fmt, args...) device_printf(sc->bce_dev, fmt, ##args) + +#define BCE_LOCK_INIT(_sc, _name) mtx_init(&(_sc)->bce_mtx, _name, MTX_NETWORK_LOCK, MTX_DEF) +#define BCE_LOCK(_sc) mtx_lock(&(_sc)->bce_mtx) +#define BCE_LOCK_ASSERT(_sc) mtx_assert(&(_sc)->bce_mtx, MA_OWNED) +#define BCE_UNLOCK(_sc) mtx_unlock(&(_sc)->bce_mtx) +#define BCE_LOCK_DESTROY(_sc) mtx_destroy(&(_sc)->bce_mtx) + +#ifdef BCE_DEBUG +#define REG_WR(sc, offset, val) bce_reg_wr(sc, offset, val) +#define REG_WR16(sc, offset, val) bce_reg_wr16(sc, offset, val) +#define REG_RD(sc, offset) bce_reg_rd(sc, offset) +#else +#define REG_WR(sc, offset, val) bus_space_write_4(sc->bce_btag, sc->bce_bhandle, offset, val) +#define REG_WR16(sc, offset, val) bus_space_write_2(sc->bce_btag, sc->bce_bhandle, offset, val) +#define REG_RD(sc, offset) bus_space_read_4(sc->bce_btag, sc->bce_bhandle, offset) +#endif + +#define REG_RD_IND(sc, offset) bce_reg_rd_ind(sc, offset) +#define REG_WR_IND(sc, offset, val) bce_reg_wr_ind(sc, offset, val) +#define CTX_WR(sc, cid_addr, offset, val) bce_ctx_wr(sc, cid_addr, offset, val) +#define CTX_RD(sc, cid_addr, offset) bce_ctx_rd(sc, cid_addr, offset) +#define BCE_SETBIT(sc, reg, x) REG_WR(sc, reg, (REG_RD(sc, reg) | (x))) +#define BCE_CLRBIT(sc, reg, x) REG_WR(sc, reg, (REG_RD(sc, reg) & ~(x))) +#define PCI_SETBIT(dev, reg, x, s) pci_write_config(dev, reg, (pci_read_config(dev, reg, s) | (x)), s) +#define PCI_CLRBIT(dev, reg, x, s) pci_write_config(dev, reg, (pci_read_config(dev, reg, s) & ~(x)), s) + +#define BCE_STATS(x) (u_long) stats->stat_ ## x ## _lo +#if (BUS_SPACE_MAXADDR > 0xFFFFFFFF) +#define BCE_ADDR_LO(y) ((u64) (y) & 0xFFFFFFFF) +#define BCE_ADDR_HI(y) ((u64) (y) >> 32) +#else +#define BCE_ADDR_LO(y) ((u32)y) +#define BCE_ADDR_HI(y) (0) +#endif + + +/****************************************************************************/ +/* Do not modify any of the following data structures, they are generated */ +/* from RTL code. */ +/* */ +/* Begin machine generated definitions. */ +/****************************************************************************/ + +/* + * tx_bd definition + */ +struct tx_bd { + u32 tx_bd_haddr_hi; + u32 tx_bd_haddr_lo; + u32 tx_bd_mss_nbytes; + u16 tx_bd_flags; + u16 tx_bd_vlan_tag; + #define TX_BD_FLAGS_CONN_FAULT (1<<0) + #define TX_BD_FLAGS_TCP_UDP_CKSUM (1<<1) + #define TX_BD_FLAGS_IP_CKSUM (1<<2) + #define TX_BD_FLAGS_VLAN_TAG (1<<3) + #define TX_BD_FLAGS_COAL_NOW (1<<4) + #define TX_BD_FLAGS_DONT_GEN_CRC (1<<5) + #define TX_BD_FLAGS_END (1<<6) + #define TX_BD_FLAGS_START (1<<7) + #define TX_BD_FLAGS_SW_OPTION_WORD (0x1f<<8) + #define TX_BD_FLAGS_SW_FLAGS (1<<13) + #define TX_BD_FLAGS_SW_SNAP (1<<14) + #define TX_BD_FLAGS_SW_LSO (1<<15) + +}; + + +/* + * rx_bd definition + */ +struct rx_bd { + u32 rx_bd_haddr_hi; + u32 rx_bd_haddr_lo; + u32 rx_bd_len; + u32 rx_bd_flags; + #define RX_BD_FLAGS_NOPUSH (1<<0) + #define RX_BD_FLAGS_DUMMY (1<<1) + #define RX_BD_FLAGS_END (1<<2) + #define RX_BD_FLAGS_START (1<<3) + +}; + + +/* + * status_block definition + */ +struct status_block { + u32 status_attn_bits; + #define STATUS_ATTN_BITS_LINK_STATE (1L<<0) + #define STATUS_ATTN_BITS_TX_SCHEDULER_ABORT (1L<<1) + #define STATUS_ATTN_BITS_TX_BD_READ_ABORT (1L<<2) + #define STATUS_ATTN_BITS_TX_BD_CACHE_ABORT (1L<<3) + #define STATUS_ATTN_BITS_TX_PROCESSOR_ABORT (1L<<4) + #define STATUS_ATTN_BITS_TX_DMA_ABORT (1L<<5) + #define STATUS_ATTN_BITS_TX_PATCHUP_ABORT (1L<<6) + #define STATUS_ATTN_BITS_TX_ASSEMBLER_ABORT (1L<<7) + #define STATUS_ATTN_BITS_RX_PARSER_MAC_ABORT (1L<<8) + #define STATUS_ATTN_BITS_RX_PARSER_CATCHUP_ABORT (1L<<9) + #define STATUS_ATTN_BITS_RX_MBUF_ABORT (1L<<10) + #define STATUS_ATTN_BITS_RX_LOOKUP_ABORT (1L<<11) + #define STATUS_ATTN_BITS_RX_PROCESSOR_ABORT (1L<<12) + #define STATUS_ATTN_BITS_RX_V2P_ABORT (1L<<13) + #define STATUS_ATTN_BITS_RX_BD_CACHE_ABORT (1L<<14) + #define STATUS_ATTN_BITS_RX_DMA_ABORT (1L<<15) + #define STATUS_ATTN_BITS_COMPLETION_ABORT (1L<<16) + #define STATUS_ATTN_BITS_HOST_COALESCE_ABORT (1L<<17) + #define STATUS_ATTN_BITS_MAILBOX_QUEUE_ABORT (1L<<18) + #define STATUS_ATTN_BITS_CONTEXT_ABORT (1L<<19) + #define STATUS_ATTN_BITS_CMD_SCHEDULER_ABORT (1L<<20) + #define STATUS_ATTN_BITS_CMD_PROCESSOR_ABORT (1L<<21) + #define STATUS_ATTN_BITS_MGMT_PROCESSOR_ABORT (1L<<22) + #define STATUS_ATTN_BITS_MAC_ABORT (1L<<23) + #define STATUS_ATTN_BITS_TIMER_ABORT (1L<<24) + #define STATUS_ATTN_BITS_DMAE_ABORT (1L<<25) + #define STATUS_ATTN_BITS_FLSH_ABORT (1L<<26) + #define STATUS_ATTN_BITS_GRC_ABORT (1L<<27) + #define STATUS_ATTN_BITS_PARITY_ERROR (1L<<31) + + u32 status_attn_bits_ack; +#if defined(__BIG_ENDIAN) + u16 status_tx_quick_consumer_index0; + u16 status_tx_quick_consumer_index1; + u16 status_tx_quick_consumer_index2; + u16 status_tx_quick_consumer_index3; + u16 status_rx_quick_consumer_index0; + u16 status_rx_quick_consumer_index1; + u16 status_rx_quick_consumer_index2; + u16 status_rx_quick_consumer_index3; + u16 status_rx_quick_consumer_index4; + u16 status_rx_quick_consumer_index5; + u16 status_rx_quick_consumer_index6; + u16 status_rx_quick_consumer_index7; + u16 status_rx_quick_consumer_index8; + u16 status_rx_quick_consumer_index9; + u16 status_rx_quick_consumer_index10; + u16 status_rx_quick_consumer_index11; + u16 status_rx_quick_consumer_index12; + u16 status_rx_quick_consumer_index13; + u16 status_rx_quick_consumer_index14; + u16 status_rx_quick_consumer_index15; + u16 status_completion_producer_index; + u16 status_cmd_consumer_index; + u16 status_idx; + u16 status_unused; +#elif defined(__LITTLE_ENDIAN) + u16 status_tx_quick_consumer_index1; + u16 status_tx_quick_consumer_index0; + u16 status_tx_quick_consumer_index3; + u16 status_tx_quick_consumer_index2; + u16 status_rx_quick_consumer_index1; + u16 status_rx_quick_consumer_index0; + u16 status_rx_quick_consumer_index3; + u16 status_rx_quick_consumer_index2; + u16 status_rx_quick_consumer_index5; + u16 status_rx_quick_consumer_index4; + u16 status_rx_quick_consumer_index7; + u16 status_rx_quick_consumer_index6; + u16 status_rx_quick_consumer_index9; + u16 status_rx_quick_consumer_index8; + u16 status_rx_quick_consumer_index11; + u16 status_rx_quick_consumer_index10; + u16 status_rx_quick_consumer_index13; + u16 status_rx_quick_consumer_index12; + u16 status_rx_quick_consumer_index15; + u16 status_rx_quick_consumer_index14; + u16 status_cmd_consumer_index; + u16 status_completion_producer_index; + u16 status_unused; + u16 status_idx; +#endif +}; + + +/* + * statistics_block definition + */ +struct statistics_block { + u32 stat_IfHCInOctets_hi; + u32 stat_IfHCInOctets_lo; + u32 stat_IfHCInBadOctets_hi; + u32 stat_IfHCInBadOctets_lo; + u32 stat_IfHCOutOctets_hi; + u32 stat_IfHCOutOctets_lo; + u32 stat_IfHCOutBadOctets_hi; + u32 stat_IfHCOutBadOctets_lo; + u32 stat_IfHCInUcastPkts_hi; + u32 stat_IfHCInUcastPkts_lo; + u32 stat_IfHCInMulticastPkts_hi; + u32 stat_IfHCInMulticastPkts_lo; + u32 stat_IfHCInBroadcastPkts_hi; + u32 stat_IfHCInBroadcastPkts_lo; + u32 stat_IfHCOutUcastPkts_hi; + u32 stat_IfHCOutUcastPkts_lo; + u32 stat_IfHCOutMulticastPkts_hi; + u32 stat_IfHCOutMulticastPkts_lo; + u32 stat_IfHCOutBroadcastPkts_hi; + u32 stat_IfHCOutBroadcastPkts_lo; + u32 stat_emac_tx_stat_dot3statsinternalmactransmiterrors; + u32 stat_Dot3StatsCarrierSenseErrors; + u32 stat_Dot3StatsFCSErrors; + u32 stat_Dot3StatsAlignmentErrors; + u32 stat_Dot3StatsSingleCollisionFrames; + u32 stat_Dot3StatsMultipleCollisionFrames; + u32 stat_Dot3StatsDeferredTransmissions; + u32 stat_Dot3StatsExcessiveCollisions; + u32 stat_Dot3StatsLateCollisions; + u32 stat_EtherStatsCollisions; + u32 stat_EtherStatsFragments; + u32 stat_EtherStatsJabbers; + u32 stat_EtherStatsUndersizePkts; + u32 stat_EtherStatsOverrsizePkts; + u32 stat_EtherStatsPktsRx64Octets; + u32 stat_EtherStatsPktsRx65Octetsto127Octets; + u32 stat_EtherStatsPktsRx128Octetsto255Octets; + u32 stat_EtherStatsPktsRx256Octetsto511Octets; + u32 stat_EtherStatsPktsRx512Octetsto1023Octets; + u32 stat_EtherStatsPktsRx1024Octetsto1522Octets; + u32 stat_EtherStatsPktsRx1523Octetsto9022Octets; + u32 stat_EtherStatsPktsTx64Octets; + u32 stat_EtherStatsPktsTx65Octetsto127Octets; + u32 stat_EtherStatsPktsTx128Octetsto255Octets; + u32 stat_EtherStatsPktsTx256Octetsto511Octets; + u32 stat_EtherStatsPktsTx512Octetsto1023Octets; + u32 stat_EtherStatsPktsTx1024Octetsto1522Octets; + u32 stat_EtherStatsPktsTx1523Octetsto9022Octets; + u32 stat_XonPauseFramesReceived; + u32 stat_XoffPauseFramesReceived; + u32 stat_OutXonSent; + u32 stat_OutXoffSent; + u32 stat_FlowControlDone; + u32 stat_MacControlFramesReceived; + u32 stat_XoffStateEntered; + u32 stat_IfInFramesL2FilterDiscards; + u32 stat_IfInRuleCheckerDiscards; + u32 stat_IfInFTQDiscards; + u32 stat_IfInMBUFDiscards; + u32 stat_IfInRuleCheckerP4Hit; + u32 stat_CatchupInRuleCheckerDiscards; + u32 stat_CatchupInFTQDiscards; + u32 stat_CatchupInMBUFDiscards; + u32 stat_CatchupInRuleCheckerP4Hit; + u32 stat_GenStat00; + u32 stat_GenStat01; + u32 stat_GenStat02; + u32 stat_GenStat03; + u32 stat_GenStat04; + u32 stat_GenStat05; + u32 stat_GenStat06; + u32 stat_GenStat07; + u32 stat_GenStat08; + u32 stat_GenStat09; + u32 stat_GenStat10; + u32 stat_GenStat11; + u32 stat_GenStat12; + u32 stat_GenStat13; + u32 stat_GenStat14; + u32 stat_GenStat15; +}; + + +/* + * l2_fhdr definition + */ +struct l2_fhdr { + u32 l2_fhdr_status; + #define L2_FHDR_STATUS_RULE_CLASS (0x7<<0) + #define L2_FHDR_STATUS_RULE_P2 (1<<3) + #define L2_FHDR_STATUS_RULE_P3 (1<<4) + #define L2_FHDR_STATUS_RULE_P4 (1<<5) + #define L2_FHDR_STATUS_L2_VLAN_TAG (1<<6) + #define L2_FHDR_STATUS_L2_LLC_SNAP (1<<7) + #define L2_FHDR_STATUS_RSS_HASH (1<<8) + #define L2_FHDR_STATUS_IP_DATAGRAM (1<<13) + #define L2_FHDR_STATUS_TCP_SEGMENT (1<<14) + #define L2_FHDR_STATUS_UDP_DATAGRAM (1<<15) + + #define L2_FHDR_STATUS_SPLIT (1<<16) + #define L2_FHDR_ERRORS_BAD_CRC (1<<17) + #define L2_FHDR_ERRORS_PHY_DECODE (1<<18) + #define L2_FHDR_ERRORS_ALIGNMENT (1<<19) + #define L2_FHDR_ERRORS_TOO_SHORT (1<<20) + #define L2_FHDR_ERRORS_GIANT_FRAME (1<<21) + #define L2_FHDR_ERRORS_TCP_XSUM (1<<28) + #define L2_FHDR_ERRORS_UDP_XSUM (1<<31) + + u32 l2_fhdr_hash; +#if defined(__BIG_ENDIAN) + u16 l2_fhdr_pkt_len; + u16 l2_fhdr_vlan_tag; + u16 l2_fhdr_ip_xsum; + u16 l2_fhdr_tcp_udp_xsum; +#elif defined(__LITTLE_ENDIAN) + u16 l2_fhdr_vlan_tag; + u16 l2_fhdr_pkt_len; + u16 l2_fhdr_tcp_udp_xsum; + u16 l2_fhdr_ip_xsum; +#endif +}; + +#define BCE_L2FHDR_PRINTFB \ + "\20" \ + "\40UDP_XSUM_ERR" \ + "\37b30" \ + "\36b29" \ + "\35TCP_XSUM_ERR" \ + "\34b27" \ + "\33b26" \ + "\32b25" \ + "\31b24" \ + "\30b23" \ + "\27b22" \ + "\26GIANT_ERR" \ + "\25SHORT_ERR" \ + "\24ALIGN_ERR" \ + "\23PHY_ERR" \ + "\22CRC_ERR" \ + "\21SPLIT" \ + "\20UDP" \ + "\17TCP" \ + "\16IP" \ + "\15b12" \ + "\14b11" \ + "\13b10" \ + "\12b09" \ + "\11RSS" \ + "\10SNAP" \ + "\07VLAN" \ + "\06P4" \ + "\05P3" \ + "\04P2" + + +/* + * l2_tx_context definition (5706 and 5708) + */ +#define BCE_L2CTX_TX_TYPE 0x00000000 +#define BCE_L2CTX_TX_TYPE_SIZE_L2 ((0xc0/0x20)<<16) +#define BCE_L2CTX_TX_TYPE_TYPE (0xf<<28) +#define BCE_L2CTX_TX_TYPE_TYPE_EMPTY (0<<28) +#define BCE_L2CTX_TX_TYPE_TYPE_L2 (1<<28) + +#define BCE_L2CTX_TX_HOST_BIDX 0x00000088 +#define BCE_L2CTX_TX_EST_NBD 0x00000088 +#define BCE_L2CTX_TX_CMD_TYPE 0x00000088 +#define BCE_L2CTX_TX_CMD_TYPE_TYPE (0xf<<24) +#define BCE_L2CTX_TX_CMD_TYPE_TYPE_L2 (0<<24) +#define BCE_L2CTX_TX_CMD_TYPE_TYPE_TCP (1<<24) + +#define BCE_L2CTX_TX_HOST_BSEQ 0x00000090 +#define BCE_L2CTX_TX_TSCH_BSEQ 0x00000094 +#define BCE_L2CTX_TX_TBDR_BSEQ 0x00000098 +#define BCE_L2CTX_TX_TBDR_BOFF 0x0000009c +#define BCE_L2CTX_TX_TBDR_BIDX 0x0000009c +#define BCE_L2CTX_TX_TBDR_BHADDR_HI 0x000000a0 +#define BCE_L2CTX_TX_TBDR_BHADDR_LO 0x000000a4 +#define BCE_L2CTX_TX_TXP_BOFF 0x000000a8 +#define BCE_L2CTX_TX_TXP_BIDX 0x000000a8 +#define BCE_L2CTX_TX_TXP_BSEQ 0x000000ac + +/* + * l2_tx_context definition (5709 and 5716) + */ +#define BCE_L2CTX_TX_TYPE_XI 0x00000080 +#define BCE_L2CTX_TX_TYPE_SIZE_L2_XI ((0xc0/0x20)<<16) +#define BCE_L2CTX_TX_TYPE_TYPE_XI (0xf<<28) +#define BCE_L2CTX_TX_TYPE_TYPE_EMPTY_XI (0<<28) +#define BCE_L2CTX_TX_TYPE_TYPE_L2_XI (1<<28) + +#define BCE_L2CTX_TX_CMD_TYPE_XI 0x00000240 +#define BCE_L2CTX_TX_CMD_TYPE_TYPE_XI (0xf<<24) +#define BCE_L2CTX_TX_CMD_TYPE_TYPE_L2_XI (0<<24) +#define BCE_L2CTX_TX_CMD_TYPE_TYPE_TCP_XI (1<<24) + +#define BCE_L2CTX_TX_HOST_BIDX_XI 0x00000240 +#define BCE_L2CTX_TX_HOST_BSEQ_XI 0x00000248 +#define BCE_L2CTX_TX_TBDR_BHADDR_HI_XI 0x00000258 +#define BCE_L2CTX_TX_TBDR_BHADDR_LO_XI 0x0000025c + + +/* + * l2_rx_context definition (5706, 5708, 5709, and 5716) + */ +#define BCE_L2CTX_RX_WATER_MARK 0x00000000 +#define BCE_L2CTX_RX_LO_WATER_MARK_SHIFT 0 +#define BCE_L2CTX_RX_LO_WATER_MARK_DEFAULT 32 +#define BCE_L2CTX_RX_LO_WATER_MARK_SCALE 4 +#define BCE_L2CTX_RX_LO_WATER_MARK_DIS 0 +#define BCE_L2CTX_RX_HI_WATER_MARK_SHIFT 4 +#define BCE_L2CTX_RX_HI_WATER_MARK_SCALE 16 +#define BCE_L2CTX_RX_WATER_MARKS_MSK 0x000000ff + +#define BCE_L2CTX_RX_BD_PRE_READ 0x00000000 +#define BCE_L2CTX_RX_BD_PRE_READ_SHIFT 8 + +#define BCE_L2CTX_RX_CTX_SIZE 0x00000000 +#define BCE_L2CTX_RX_CTX_SIZE_SHIFT 16 +#define BCE_L2CTX_RX_CTX_TYPE_SIZE_L2 ((0x20/20)<> BCM_PAGE_BITS) + +/* + * Page count must remain a power of 2 for all + * of the math to work correctly. + */ +#define TX_PAGES 2 +#define TOTAL_TX_BD_PER_PAGE (BCM_PAGE_SIZE / sizeof(struct tx_bd)) +#define USABLE_TX_BD_PER_PAGE (TOTAL_TX_BD_PER_PAGE - 1) +#define TOTAL_TX_BD (TOTAL_TX_BD_PER_PAGE * TX_PAGES) +#define USABLE_TX_BD (USABLE_TX_BD_PER_PAGE * TX_PAGES) +#define MAX_TX_BD (TOTAL_TX_BD - 1) + +#define NEXT_TX_BD(x) (((x) & USABLE_TX_BD_PER_PAGE) == \ + (USABLE_TX_BD_PER_PAGE - 1)) ? \ + (x) + 2 : (x) + 1 + +#define TX_CHAIN_IDX(x) ((x) & MAX_TX_BD) + +#define TX_PAGE(x) (((x) & ~USABLE_TX_BD_PER_PAGE) >> (BCM_PAGE_BITS - 4)) +#define TX_IDX(x) ((x) & USABLE_TX_BD_PER_PAGE) + +/* + * Page count must remain a power of 2 for all + * of the math to work correctly. + */ +#define RX_PAGES 2 +#define TOTAL_RX_BD_PER_PAGE (BCM_PAGE_SIZE / sizeof(struct rx_bd)) +#define USABLE_RX_BD_PER_PAGE (TOTAL_RX_BD_PER_PAGE - 1) +#define TOTAL_RX_BD (TOTAL_RX_BD_PER_PAGE * RX_PAGES) +#define USABLE_RX_BD (USABLE_RX_BD_PER_PAGE * RX_PAGES) +#define MAX_RX_BD (TOTAL_RX_BD - 1) + +#define NEXT_RX_BD(x) (((x) & USABLE_RX_BD_PER_PAGE) == \ + (USABLE_RX_BD_PER_PAGE - 1)) ? \ + (x) + 2 : (x) + 1 + +#define RX_CHAIN_IDX(x) ((x) & MAX_RX_BD) + +#define RX_PAGE(x) (((x) & ~USABLE_RX_BD_PER_PAGE) >> (BCM_PAGE_BITS - 4)) +#define RX_IDX(x) ((x) & USABLE_RX_BD_PER_PAGE) + +/* + * To accomodate jumbo frames, the page chain should + * be 4 times larger than the receive chain. + */ +#define PG_PAGES (RX_PAGES * 4) +#define TOTAL_PG_BD_PER_PAGE (BCM_PAGE_SIZE / sizeof(struct rx_bd)) +#define USABLE_PG_BD_PER_PAGE (TOTAL_PG_BD_PER_PAGE - 1) +#define TOTAL_PG_BD (TOTAL_PG_BD_PER_PAGE * PG_PAGES) +#define USABLE_PG_BD (USABLE_PG_BD_PER_PAGE * PG_PAGES) +#define MAX_PG_BD (TOTAL_PG_BD - 1) + +#define NEXT_PG_BD(x) (((x) & USABLE_PG_BD_PER_PAGE) == \ + (USABLE_PG_BD_PER_PAGE - 1)) ? \ + (x) + 2 : (x) + 1 + +#define PG_CHAIN_IDX(x) ((x) & MAX_PG_BD) + +#define PG_PAGE(x) (((x) & ~USABLE_PG_BD_PER_PAGE) >> (BCM_PAGE_BITS - 4)) +#define PG_IDX(x) ((x) & USABLE_PG_BD_PER_PAGE) + +/* Context size. */ +#define CTX_SHIFT 7 +#define CTX_SIZE (1 << CTX_SHIFT) +#define CTX_MASK (CTX_SIZE - 1) +#define GET_CID_ADDR(_cid) ((_cid) << CTX_SHIFT) +#define GET_CID(_cid_addr) ((_cid_addr) >> CTX_SHIFT) + +#define PHY_CTX_SHIFT 6 +#define PHY_CTX_SIZE (1 << PHY_CTX_SHIFT) +#define PHY_CTX_MASK (PHY_CTX_SIZE - 1) +#define GET_PCID_ADDR(_pcid) ((_pcid) << PHY_CTX_SHIFT) +#define GET_PCID(_pcid_addr) ((_pcid_addr) >> PHY_CTX_SHIFT) + +#define MB_KERNEL_CTX_SHIFT 8 +#define MB_KERNEL_CTX_SIZE (1 << MB_KERNEL_CTX_SHIFT) +#define MB_KERNEL_CTX_MASK (MB_KERNEL_CTX_SIZE - 1) +#define MB_GET_CID_ADDR(_cid) (0x10000 + ((_cid) << MB_KERNEL_CTX_SHIFT)) + +#define MAX_CID_CNT 0x4000 +#define MAX_CID_ADDR (GET_CID_ADDR(MAX_CID_CNT)) +#define INVALID_CID_ADDR 0xffffffff + +#define TX_CID 16 +#define RX_CID 0 + +/****************************************************************************/ +/* BCE Processor Firmwware Load Definitions */ +/****************************************************************************/ + +struct cpu_reg { + u32 mode; + u32 mode_value_halt; + u32 mode_value_sstep; + + u32 state; + u32 state_value_clear; + + u32 gpr0; + u32 evmask; + u32 pc; + u32 inst; + u32 bp; + + u32 spad_base; + + u32 mips_view_base; +}; + +struct fw_info { + u32 ver_major; + u32 ver_minor; + u32 ver_fix; + + u32 start_addr; + + /* Text section. */ + u32 text_addr; + u32 text_len; + u32 text_index; + u32 *text; + + /* Data section. */ + u32 data_addr; + u32 data_len; + u32 data_index; + u32 *data; + + /* SBSS section. */ + u32 sbss_addr; + u32 sbss_len; + u32 sbss_index; + u32 *sbss; + + /* BSS section. */ + u32 bss_addr; + u32 bss_len; + u32 bss_index; + u32 *bss; + + /* Read-only section. */ + u32 rodata_addr; + u32 rodata_len; + u32 rodata_index; + u32 *rodata; +}; + +#define RV2P_PROC1 0 +#define RV2P_PROC2 1 + +#define BCE_MIREG(x) ((x & 0x1F) << 16) +#define BCE_MIPHY(x) ((x & 0x1F) << 21) +#define BCE_PHY_TIMEOUT 50 + +#define BCE_NVRAM_SIZE 0x200 +#define BCE_NVRAM_MAGIC 0x669955aa +#define BCE_CRC32_RESIDUAL 0xdebb20e3 + +#define BCE_TX_TIMEOUT 5 + +#define BCE_MAX_SEGMENTS 32 +#define BCE_TSO_MAX_SIZE 65536 +#define BCE_TSO_MAX_SEG_SIZE 4096 + +#define BCE_DMA_ALIGN 8 +#define BCE_DMA_BOUNDARY 0 + +/* The BCM5708 has a problem with addresses greater that 40bits. */ +/* Handle the sizing issue in an architecture agnostic fashion. */ +#if (BUS_SPACE_MAXADDR < 0xFFFFFFFFFF) +#define BCE_BUS_SPACE_MAXADDR BUS_SPACE_MAXADDR +#else +#define BCE_BUS_SPACE_MAXADDR 0xFFFFFFFFFF +#endif + +/* + * XXX Checksum offload involving IP fragments seems to cause problems on + * transmit. Disable it for now, hopefully there will be a more elegant + * solution later. + */ +#ifdef BCE_IP_CSUM +#define BCE_IF_HWASSIST (CSUM_IP | CSUM_TCP | CSUM_UDP) +#else +#define BCE_IF_HWASSIST (CSUM_TCP | CSUM_UDP) +#endif + +#if __FreeBSD_version < 700000 +#define BCE_IF_CAPABILITIES (IFCAP_VLAN_MTU | IFCAP_VLAN_HWTAGGING | \ + IFCAP_HWCSUM | IFCAP_JUMBO_MTU) +#else +#define BCE_IF_CAPABILITIES (IFCAP_VLAN_MTU | IFCAP_VLAN_HWTAGGING | \ + IFCAP_HWCSUM | IFCAP_JUMBO_MTU | IFCAP_VLAN_HWCSUM) +#endif + +#define BCE_MIN_MTU 60 +#define BCE_MIN_ETHER_MTU 64 + +#define BCE_MAX_STD_MTU 1500 +#define BCE_MAX_STD_ETHER_MTU 1518 +#define BCE_MAX_STD_ETHER_MTU_VLAN 1522 + +#define BCE_MAX_JUMBO_MTU 9000 +#define BCE_MAX_JUMBO_ETHER_MTU 9018 +#define BCE_MAX_JUMBO_ETHER_MTU_VLAN 9022 + +// #define BCE_MAX_MTU ETHER_MAX_LEN_JUMBO + ETHER_VLAN_ENCAP_LEN /* 9022 */ + +/****************************************************************************/ +/* BCE Device State Data Structure */ +/****************************************************************************/ + +#define BCE_STATUS_BLK_SZ sizeof(struct status_block) +#define BCE_STATS_BLK_SZ sizeof(struct statistics_block) +#define BCE_TX_CHAIN_PAGE_SZ BCM_PAGE_SIZE +#define BCE_RX_CHAIN_PAGE_SZ BCM_PAGE_SIZE +#define BCE_PG_CHAIN_PAGE_SZ BCM_PAGE_SIZE + +struct bce_softc +{ + /* MUST start with ifnet pointer (see definition of miibus_statchg()) */ + struct ifnet *bce_ifp; /* Interface info */ + device_t bce_dev; /* Parent device handle */ + u_int8_t bce_unit; /* Interface number */ + struct resource *bce_res_mem; /* Device resource handle */ + struct ifmedia bce_ifmedia; /* TBI media info */ + bus_space_tag_t bce_btag; /* Device bus tag */ + bus_space_handle_t bce_bhandle; /* Device bus handle */ + vm_offset_t bce_vhandle; /* Device virtual memory handle */ + struct resource *bce_res_irq; /* IRQ Resource Handle */ + struct mtx bce_mtx; /* Mutex */ + + /* Interrupt handler. */ + driver_intr_t *bce_intr; + void *bce_intrhand; + int bce_irq_rid; + int bce_msi_count; + + /* ASIC Chip ID. */ + u32 bce_chipid; + + /* General controller flags. */ + u32 bce_flags; +#define BCE_PCIX_FLAG 0x00000001 +#define BCE_PCI_32BIT_FLAG 0x00000002 +#define BCE_ONE_TDMA_FLAG 0x00000004 /* Deprecated */ +#define BCE_NO_WOL_FLAG 0x00000008 +#define BCE_USING_DAC_FLAG 0x00000010 +#define BCE_USING_MSI_FLAG 0x00000020 +#define BCE_MFW_ENABLE_FLAG 0x00000040 +#define BCE_ONE_SHOT_MSI_FLAG 0x00000080 +#define BCE_USING_MSIX_FLAG 0x00000100 +#define BCE_PCIE_FLAG 0x00000200 + + /* Controller capability flags. */ + u32 bce_cap_flags; +#define BCE_MSI_CAPABLE_FLAG 0x00000001 +#define BCE_MSIX_CAPABLE_FLAG 0x00000002 +#define BCE_PCIE_CAPABLE_FLAG 0x00000004 +#define BCE_PCIX_CAPABLE_FLAG 0x00000008 + + /* PHY specific flags. */ + u32 bce_phy_flags; +#define BCE_PHY_SERDES_FLAG 0x00000001 +#define BCE_PHY_CRC_FIX_FLAG 0x00000002 +#define BCE_PHY_PARALLEL_DETECT_FLAG 0x00000004 +#define BCE_PHY_2_5G_CAPABLE_FLAG 0x00000008 +#define BCE_PHY_INT_MODE_MASK_FLAG 0x00000300 +#define BCE_PHY_INT_MODE_AUTO_POLLING_FLAG 0x00000100 +#define BCE_PHY_INT_MODE_LINK_READY_FLAG 0x00000200 + + /* Values that need to be shared with the PHY driver. */ + u32 bce_shared_hw_cfg; + u32 bce_port_hw_cfg; + + bus_addr_t max_bus_addr; + u16 bus_speed_mhz; /* PCI bus speed */ + u16 link_width; /* PCIe link width */ + u16 link_speed; /* PCIe link speed */ + struct flash_spec *bce_flash_info; /* Flash NVRAM settings */ + u32 bce_flash_size; /* Flash NVRAM size */ + u32 bce_shmem_base; /* Shared Memory base address */ + char * bce_name; /* Name string */ + + /* Tracks the version of bootcode firmware. */ + u32 bce_fw_ver; + + /* Tracks the state of the firmware. 0 = Running while any */ + /* other value indicates that the firmware is not responding. */ + u16 bce_fw_timed_out; + + /* An incrementing sequence used to coordinate messages passed */ + /* from the driver to the firmware. */ + u16 bce_fw_wr_seq; + + /* An incrementing sequence used to let the firmware know that */ + /* the driver is still operating. Without the pulse, management */ + /* firmware such as IPMI or UMP will operate in OS absent state. */ + u16 bce_fw_drv_pulse_wr_seq; + + /* Ethernet MAC address. */ + u_char eaddr[6]; + + /* These setting are used by the host coalescing (HC) block to */ + /* to control how often the status block, statistics block and */ + /* interrupts are generated. */ + u16 bce_tx_quick_cons_trip_int; + u16 bce_tx_quick_cons_trip; + u16 bce_rx_quick_cons_trip_int; + u16 bce_rx_quick_cons_trip; + u16 bce_comp_prod_trip_int; + u16 bce_comp_prod_trip; + u16 bce_tx_ticks_int; + u16 bce_tx_ticks; + u16 bce_rx_ticks_int; + u16 bce_rx_ticks; + u16 bce_com_ticks_int; + u16 bce_com_ticks; + u16 bce_cmd_ticks_int; + u16 bce_cmd_ticks; + u32 bce_stats_ticks; + + /* The address of the integrated PHY on the MII bus. */ + int bce_phy_addr; + + /* The device handle for the MII bus child device. */ + device_t bce_miibus; + + /* Driver maintained TX chain pointers and byte counter. */ + u16 rx_prod; + u16 rx_cons; + u32 rx_prod_bseq; /* Counts the bytes used. */ + u16 tx_prod; + u16 tx_cons; + u32 tx_prod_bseq; /* Counts the bytes used. */ + u16 pg_prod; + u16 pg_cons; + + int bce_link; + struct callout bce_tick_callout; + struct callout bce_pulse_callout; + + int watchdog_timer; /* ticks until chip reset */ + + /* Frame size and mbuf allocation size for RX frames. */ + u32 max_frame_size; + int rx_bd_mbuf_alloc_size; + int rx_bd_mbuf_data_len; + int rx_bd_mbuf_align_pad; + int pg_bd_mbuf_alloc_size; + + /* Receive mode settings (i.e promiscuous, multicast, etc.). */ + u32 rx_mode; + + /* Bus tag for the bce controller. */ + bus_dma_tag_t parent_tag; + + /* H/W maintained TX buffer descriptor chain structure. */ + bus_dma_tag_t tx_bd_chain_tag; + bus_dmamap_t tx_bd_chain_map[TX_PAGES]; + struct tx_bd *tx_bd_chain[TX_PAGES]; + bus_addr_t tx_bd_chain_paddr[TX_PAGES]; + + /* H/W maintained RX buffer descriptor chain structure. */ + bus_dma_tag_t rx_bd_chain_tag; + bus_dmamap_t rx_bd_chain_map[RX_PAGES]; + struct rx_bd *rx_bd_chain[RX_PAGES]; + bus_addr_t rx_bd_chain_paddr[RX_PAGES]; + + /* H/W maintained page buffer descriptor chain structure. */ + bus_dma_tag_t pg_bd_chain_tag; + bus_dmamap_t pg_bd_chain_map[PG_PAGES]; + struct rx_bd *pg_bd_chain[PG_PAGES]; + bus_addr_t pg_bd_chain_paddr[PG_PAGES]; + + /* H/W maintained status block. */ + bus_dma_tag_t status_tag; + bus_dmamap_t status_map; + struct status_block *status_block; /* Virtual address */ + bus_addr_t status_block_paddr; /* Physical address */ + + /* Driver maintained status block values. */ + u16 last_status_idx; + u16 hw_rx_cons; + u16 hw_tx_cons; + + /* H/W maintained statistics block. */ + bus_dma_tag_t stats_tag; + bus_dmamap_t stats_map; + struct statistics_block *stats_block; /* Virtual address */ + bus_addr_t stats_block_paddr; /* Physical address */ + + /* H/W maintained context block. */ + int ctx_pages; + bus_dma_tag_t ctx_tag; + /* DRC - Fix hard coded value. */ + bus_dmamap_t ctx_map[4]; + void *ctx_block[4]; /* Virtual address */ + bus_addr_t ctx_paddr[4]; /* Physical address */ + + /* Bus tag for RX/TX mbufs. */ + bus_dma_tag_t rx_mbuf_tag; + bus_dma_tag_t tx_mbuf_tag; + bus_dma_tag_t pg_mbuf_tag; + + /* S/W maintained mbuf TX chain structure. */ + bus_dmamap_t tx_mbuf_map[TOTAL_TX_BD]; + struct mbuf *tx_mbuf_ptr[TOTAL_TX_BD]; + + /* S/W maintained mbuf RX chain structure. */ + bus_dmamap_t rx_mbuf_map[TOTAL_RX_BD]; + struct mbuf *rx_mbuf_ptr[TOTAL_RX_BD]; + + /* S/W maintained mbuf page chain structure. */ + bus_dmamap_t pg_mbuf_map[TOTAL_PG_BD]; + struct mbuf *pg_mbuf_ptr[TOTAL_PG_BD]; + + /* Track the number of buffer descriptors in use. */ + u16 free_rx_bd; + u16 max_rx_bd; + u16 used_tx_bd; + u16 max_tx_bd; + u16 free_pg_bd; + u16 max_pg_bd; + + /* Provides access to hardware statistics through sysctl. */ + u64 stat_IfHCInOctets; + u64 stat_IfHCInBadOctets; + u64 stat_IfHCOutOctets; + u64 stat_IfHCOutBadOctets; + u64 stat_IfHCInUcastPkts; + u64 stat_IfHCInMulticastPkts; + u64 stat_IfHCInBroadcastPkts; + u64 stat_IfHCOutUcastPkts; + u64 stat_IfHCOutMulticastPkts; + u64 stat_IfHCOutBroadcastPkts; + + u32 stat_emac_tx_stat_dot3statsinternalmactransmiterrors; + u32 stat_Dot3StatsCarrierSenseErrors; + u32 stat_Dot3StatsFCSErrors; + u32 stat_Dot3StatsAlignmentErrors; + u32 stat_Dot3StatsSingleCollisionFrames; + u32 stat_Dot3StatsMultipleCollisionFrames; + u32 stat_Dot3StatsDeferredTransmissions; + u32 stat_Dot3StatsExcessiveCollisions; + u32 stat_Dot3StatsLateCollisions; + u32 stat_EtherStatsCollisions; + u32 stat_EtherStatsFragments; + u32 stat_EtherStatsJabbers; + u32 stat_EtherStatsUndersizePkts; + u32 stat_EtherStatsOverrsizePkts; + u32 stat_EtherStatsPktsRx64Octets; + u32 stat_EtherStatsPktsRx65Octetsto127Octets; + u32 stat_EtherStatsPktsRx128Octetsto255Octets; + u32 stat_EtherStatsPktsRx256Octetsto511Octets; + u32 stat_EtherStatsPktsRx512Octetsto1023Octets; + u32 stat_EtherStatsPktsRx1024Octetsto1522Octets; + u32 stat_EtherStatsPktsRx1523Octetsto9022Octets; + u32 stat_EtherStatsPktsTx64Octets; + u32 stat_EtherStatsPktsTx65Octetsto127Octets; + u32 stat_EtherStatsPktsTx128Octetsto255Octets; + u32 stat_EtherStatsPktsTx256Octetsto511Octets; + u32 stat_EtherStatsPktsTx512Octetsto1023Octets; + u32 stat_EtherStatsPktsTx1024Octetsto1522Octets; + u32 stat_EtherStatsPktsTx1523Octetsto9022Octets; + u32 stat_XonPauseFramesReceived; + u32 stat_XoffPauseFramesReceived; + u32 stat_OutXonSent; + u32 stat_OutXoffSent; + u32 stat_FlowControlDone; + u32 stat_MacControlFramesReceived; + u32 stat_XoffStateEntered; + u32 stat_IfInFramesL2FilterDiscards; + u32 stat_IfInRuleCheckerDiscards; + u32 stat_IfInFTQDiscards; + u32 stat_IfInMBUFDiscards; + u32 stat_IfInRuleCheckerP4Hit; + u32 stat_CatchupInRuleCheckerDiscards; + u32 stat_CatchupInFTQDiscards; + u32 stat_CatchupInMBUFDiscards; + u32 stat_CatchupInRuleCheckerP4Hit; + + /* Provides access to certain firmware statistics. */ + u32 com_no_buffers; + + /* Mbuf allocation failure counter. */ + u32 mbuf_alloc_failed; + + /* TX DMA mapping failure counter. */ + u32 tx_dma_map_failures; + + u32 hc_command; + +#ifdef BCE_DEBUG + /* Track the number of enqueued mbufs. */ + int debug_tx_mbuf_alloc; + int debug_rx_mbuf_alloc; + int debug_pg_mbuf_alloc; + + /* Track how many and what type of interrupts are generated. */ + u32 interrupts_generated; + u32 interrupts_handled; + u32 rx_interrupts; + u32 tx_interrupts; + + /* Track interrupt time (25MHz clock). */ + u64 rx_intr_time; + u64 tx_intr_time; + + u32 rx_low_watermark; /* Lowest number of rx_bd's free. */ + u32 rx_empty_count; /* Number of times the RX chain was empty. */ + + u32 pg_low_watermark; /* Lowest number of pages free. */ + u32 pg_empty_count; /* Number of times the page chain was empty. */ + + u32 tx_hi_watermark; /* Greatest number of tx_bd's used. */ + u32 tx_full_count; /* Number of times the TX chain was full. */ + + /* Simulated mbuf allocation failure counter. */ + u32 debug_mbuf_sim_alloc_failed; + + u32 l2fhdr_status_errors; + u32 unexpected_attentions; + u32 lost_status_block_updates; + + u32 requested_tso_frames; /* Number of TSO frames enqueued. */ +#endif +}; + +#endif /* #ifndef _BCE_H_DEFINED */ + diff --git a/src/add-ons/kernel/drivers/network/broadcom570x/dev/mii/Jamfile b/src/add-ons/kernel/drivers/network/broadcom570x/dev/mii/Jamfile index 22a640924d..e854cae01a 100644 --- a/src/add-ons/kernel/drivers/network/broadcom570x/dev/mii/Jamfile +++ b/src/add-ons/kernel/drivers/network/broadcom570x/dev/mii/Jamfile @@ -9,7 +9,11 @@ SubDirCcFlags [ FDefines _KERNEL=1 FBSD_DRIVER=1 ] ; KernelStaticLibrary broadcom570x_mii.a : + brgphy.c ukphy.c ukphy_subr.c ; +ObjectHdrs [ FGristFiles brgphy$(SUFOBJ) ] + : [ FDirName $(TARGET_COMMON_DEBUG_OBJECT_DIR) libs compat freebsd_network ] ; +Includes [ FGristFiles brgphy.c ] : miidevs.h ; 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 new file mode 100644 index 0000000000..9b38dc02db --- /dev/null +++ b/src/add-ons/kernel/drivers/network/broadcom570x/dev/mii/brgphy.c @@ -0,0 +1,1046 @@ +/*- + * Copyright (c) 2000 + * Bill Paul . 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. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Bill Paul. + * 4. Neither the name of the author nor the names of any co-contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY Bill Paul 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 Bill Paul OR THE VOICES IN HIS HEAD + * 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. + */ + +#include +__FBSDID("$FreeBSD: src/sys/dev/mii/brgphy.c,v 1.78 2008/08/12 00:57:39 yongari Exp $"); + +/* + * Driver for the Broadcom BCM54xx/57xx 1000baseTX PHY. + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include "miidevs.h" + +#include +#include +#include +#include +#include + +#include +#include + +#include "miibus_if.h" + +static int brgphy_probe(device_t); +static int brgphy_attach(device_t); + +struct brgphy_softc { + struct mii_softc mii_sc; + int mii_oui; + int mii_model; + int mii_rev; + int serdes_flags; /* Keeps track of the serdes type used */ +#define BRGPHY_5706S 0x0001 +#define BRGPHY_5708S 0x0002 + int bce_phy_flags; /* PHY flags transferred from the MAC driver */ +}; + +static device_method_t brgphy_methods[] = { + /* device interface */ + DEVMETHOD(device_probe, brgphy_probe), + DEVMETHOD(device_attach, brgphy_attach), + DEVMETHOD(device_detach, mii_phy_detach), + DEVMETHOD(device_shutdown, bus_generic_shutdown), + { 0, 0 } +}; + +static devclass_t brgphy_devclass; + +static driver_t brgphy_driver = { + "brgphy", + brgphy_methods, + sizeof(struct brgphy_softc) +}; + +DRIVER_MODULE(brgphy, miibus, brgphy_driver, brgphy_devclass, 0, 0); + +static int brgphy_service(struct mii_softc *, struct mii_data *, int); +static void brgphy_setmedia(struct mii_softc *, int, int); +static void brgphy_status(struct mii_softc *); +static void brgphy_mii_phy_auto(struct mii_softc *); +static void brgphy_reset(struct mii_softc *); +static void brgphy_enable_loopback(struct mii_softc *); +static void bcm5401_load_dspcode(struct mii_softc *); +static void bcm5411_load_dspcode(struct mii_softc *); +static void brgphy_fixup_5704_a0_bug(struct mii_softc *); +static void brgphy_fixup_adc_bug(struct mii_softc *); +static void brgphy_fixup_adjust_trim(struct mii_softc *); +static void brgphy_fixup_ber_bug(struct mii_softc *); +static void brgphy_fixup_crc_bug(struct mii_softc *); +static void brgphy_fixup_jitter_bug(struct mii_softc *); +static void brgphy_ethernet_wirespeed(struct mii_softc *); +static void brgphy_jumbo_settings(struct mii_softc *, u_long); + +static const struct mii_phydesc brgphys[] = { + MII_PHY_DESC(xxBROADCOM, BCM5400), + MII_PHY_DESC(xxBROADCOM, BCM5401), + MII_PHY_DESC(xxBROADCOM, BCM5411), + MII_PHY_DESC(xxBROADCOM, BCM5701), + MII_PHY_DESC(xxBROADCOM, BCM5703), + MII_PHY_DESC(xxBROADCOM, BCM5704), + MII_PHY_DESC(xxBROADCOM, BCM5705), + MII_PHY_DESC(xxBROADCOM, BCM5706), + MII_PHY_DESC(xxBROADCOM, BCM5714), + MII_PHY_DESC(xxBROADCOM, BCM5750), + MII_PHY_DESC(xxBROADCOM, BCM5752), + MII_PHY_DESC(xxBROADCOM, BCM5754), + MII_PHY_DESC(xxBROADCOM, BCM5780), + MII_PHY_DESC(xxBROADCOM, BCM5708C), + MII_PHY_DESC(xxBROADCOM_ALT1, BCM5755), + MII_PHY_DESC(xxBROADCOM_ALT1, BCM5787), + MII_PHY_DESC(xxBROADCOM_ALT1, BCM5708S), + MII_PHY_DESC(xxBROADCOM_ALT1, BCM5709CAX), + MII_PHY_DESC(xxBROADCOM_ALT1, BCM5722), + MII_PHY_DESC(xxBROADCOM_ALT1, BCM5709C), + MII_PHY_DESC(BROADCOM2, BCM5906), + MII_PHY_END +}; + + +/* Search for our PHY in the list of known PHYs */ +static int +brgphy_probe(device_t dev) +{ + return (mii_phy_dev_probe(dev, brgphys, BUS_PROBE_DEFAULT)); +} + +/* Attach the PHY to the MII bus */ +static int +brgphy_attach(device_t dev) +{ + struct brgphy_softc *bsc; + struct bge_softc *bge_sc = NULL; + struct bce_softc *bce_sc = NULL; + struct mii_softc *sc; + struct mii_attach_args *ma; + struct mii_data *mii; + struct ifnet *ifp; + int fast_ether; + + bsc = device_get_softc(dev); + sc = &bsc->mii_sc; + ma = device_get_ivars(dev); + sc->mii_dev = device_get_parent(dev); + mii = device_get_softc(sc->mii_dev); + LIST_INSERT_HEAD(&mii->mii_phys, sc, mii_list); + + /* Initialize mii_softc structure */ + sc->mii_inst = mii->mii_instance; + sc->mii_phy = ma->mii_phyno; + sc->mii_service = brgphy_service; + sc->mii_pdata = mii; + sc->mii_anegticks = MII_ANEGTICKS_GIGE; + sc->mii_flags |= MIIF_NOISOLATE | MIIF_NOLOOP; + mii->mii_instance++; + + /* Initialize brgphy_softc structure */ + bsc->mii_oui = MII_OUI(ma->mii_id1, ma->mii_id2); + bsc->mii_model = MII_MODEL(ma->mii_id2); + bsc->mii_rev = MII_REV(ma->mii_id2); + bsc->serdes_flags = 0; + + fast_ether = 0; + + if (bootverbose) + device_printf(dev, "OUI 0x%06x, model 0x%04x, rev. %d\n", + bsc->mii_oui, bsc->mii_model, bsc->mii_rev); + + /* Handle any special cases based on the PHY ID */ + switch (bsc->mii_oui) { + case MII_OUI_BROADCOM: + case MII_OUI_BROADCOM2: + break; + case MII_OUI_xxBROADCOM: + switch (bsc->mii_model) { + case MII_MODEL_xxBROADCOM_BCM5706: + /* + * The 5464 PHY used in the 5706 supports both copper + * and fiber interfaces over GMII. Need to check the + * shadow registers to see which mode is actually + * in effect, and therefore whether we have 5706C or + * 5706S. + */ + PHY_WRITE(sc, BRGPHY_MII_SHADOW_1C, + BRGPHY_SHADOW_1C_MODE_CTRL); + if (PHY_READ(sc, BRGPHY_MII_SHADOW_1C) & + BRGPHY_SHADOW_1C_ENA_1000X) { + bsc->serdes_flags |= BRGPHY_5706S; + sc->mii_flags |= MIIF_HAVEFIBER; + } + break; + } break; + case MII_OUI_xxBROADCOM_ALT1: + switch (bsc->mii_model) { + case MII_MODEL_xxBROADCOM_ALT1_BCM5708S: + bsc->serdes_flags |= BRGPHY_5708S; + sc->mii_flags |= MIIF_HAVEFIBER; + break; + } break; + default: + device_printf(dev, "Unrecognized OUI for PHY!\n"); + } + + ifp = sc->mii_pdata->mii_ifp; + + /* Find the MAC driver associated with this PHY. */ + if (strcmp(ifp->if_dname, "bge") == 0) { + bge_sc = ifp->if_softc; + } else if (strcmp(ifp->if_dname, "bce") == 0) { + bce_sc = ifp->if_softc; + } + + /* Todo: Need to add additional controllers such as 5906 & 5787F */ + /* The 590x chips are 10/100 only. */ + if (bge_sc && + pci_get_vendor(bge_sc->bge_dev) == BCOM_VENDORID && + (pci_get_device(bge_sc->bge_dev) == BCOM_DEVICEID_BCM5901 || + pci_get_device(bge_sc->bge_dev) == BCOM_DEVICEID_BCM5901A2 || + pci_get_device(bge_sc->bge_dev) == BCOM_DEVICEID_BCM5906 || + pci_get_device(bge_sc->bge_dev) == BCOM_DEVICEID_BCM5906M)) { + fast_ether = 1; + sc->mii_anegticks = MII_ANEGTICKS; + } + + brgphy_reset(sc); + + /* Read the PHY's capabilities. */ + sc->mii_capabilities = PHY_READ(sc, MII_BMSR) & ma->mii_capmask; + if (sc->mii_capabilities & BMSR_EXTSTAT) + sc->mii_extcapabilities = PHY_READ(sc, MII_EXTSR); + device_printf(dev, " "); + +#define ADD(m, c) ifmedia_add(&mii->mii_media, (m), (c), NULL) + + /* Create an instance of Ethernet media. */ + ADD(IFM_MAKEWORD(IFM_ETHER, IFM_NONE, 0, sc->mii_inst), BMCR_ISO); + + /* Add the supported media types */ + if ((sc->mii_flags & MIIF_HAVEFIBER) == 0) { + ADD(IFM_MAKEWORD(IFM_ETHER, IFM_10_T, 0, sc->mii_inst), + BRGPHY_S10); + printf("10baseT, "); + ADD(IFM_MAKEWORD(IFM_ETHER, IFM_10_T, IFM_FDX, sc->mii_inst), + BRGPHY_S10 | BRGPHY_BMCR_FDX); + printf("10baseT-FDX, "); + ADD(IFM_MAKEWORD(IFM_ETHER, IFM_100_TX, 0, sc->mii_inst), + BRGPHY_S100); + printf("100baseTX, "); + ADD(IFM_MAKEWORD(IFM_ETHER, IFM_100_TX, IFM_FDX, sc->mii_inst), + BRGPHY_S100 | BRGPHY_BMCR_FDX); + printf("100baseTX-FDX, "); + if (fast_ether == 0) { + ADD(IFM_MAKEWORD(IFM_ETHER, IFM_1000_T, 0, sc->mii_inst), + BRGPHY_S1000); + printf("1000baseT, "); + ADD(IFM_MAKEWORD(IFM_ETHER, IFM_1000_T, IFM_FDX, sc->mii_inst), + BRGPHY_S1000 | BRGPHY_BMCR_FDX); + printf("1000baseT-FDX, "); + } + } else { + ADD(IFM_MAKEWORD(IFM_ETHER, IFM_1000_SX, IFM_FDX, sc->mii_inst), + BRGPHY_S1000 | BRGPHY_BMCR_FDX); + printf("1000baseSX-FDX, "); + /* 2.5G support is a software enabled feature on the 5708S and 5709S. */ + if (bce_sc && (bce_sc->bce_phy_flags & BCE_PHY_2_5G_CAPABLE_FLAG)) { + ADD(IFM_MAKEWORD(IFM_ETHER, IFM_2500_SX, IFM_FDX, sc->mii_inst), 0); + printf("2500baseSX-FDX, "); + } + } + + ADD(IFM_MAKEWORD(IFM_ETHER, IFM_AUTO, 0, sc->mii_inst), 0); + printf("auto\n"); + +#undef ADD + MIIBUS_MEDIAINIT(sc->mii_dev); + return (0); +} + +static int +brgphy_service(struct mii_softc *sc, struct mii_data *mii, int cmd) +{ + struct brgphy_softc *bsc = (struct brgphy_softc *)sc; + struct ifmedia_entry *ife = mii->mii_media.ifm_cur; + int error = 0; + int val; + + switch (cmd) { + case MII_POLLSTAT: + /* If we're not polling our PHY instance, just return. */ + if (IFM_INST(ife->ifm_media) != sc->mii_inst) + goto brgphy_service_exit; + break; + case MII_MEDIACHG: + /* + * If the media indicates a different PHY instance, + * isolate ourselves. + */ + if (IFM_INST(ife->ifm_media) != sc->mii_inst) { + PHY_WRITE(sc, MII_BMCR, + PHY_READ(sc, MII_BMCR) | BMCR_ISO); + goto brgphy_service_exit; + } + + /* If the interface is not up, don't do anything. */ + if ((mii->mii_ifp->if_flags & IFF_UP) == 0) + break; + + /* Todo: Why is this here? Is it really needed? */ + brgphy_reset(sc); /* XXX hardware bug work-around */ + + switch (IFM_SUBTYPE(ife->ifm_media)) { + case IFM_AUTO: + brgphy_mii_phy_auto(sc); + break; + case IFM_2500_SX: + case IFM_1000_SX: + case IFM_1000_T: + case IFM_100_TX: + case IFM_10_T: + brgphy_setmedia(sc, ife->ifm_media, + mii->mii_ifp->if_flags & IFF_LINK0); + break; + default: + error = EINVAL; + goto brgphy_service_exit; + } + break; + case MII_TICK: + /* Bail if we're not currently selected. */ + if (IFM_INST(ife->ifm_media) != sc->mii_inst) + goto brgphy_service_exit; + + /* Bail if the interface isn't up. */ + if ((mii->mii_ifp->if_flags & IFF_UP) == 0) + goto brgphy_service_exit; + + + /* Bail if autoneg isn't in process. */ + if (IFM_SUBTYPE(ife->ifm_media) != IFM_AUTO) { + sc->mii_ticks = 0; + break; + } + + /* + * Check to see if we have link. If we do, we don't + * need to restart the autonegotiation process. + */ + val = PHY_READ(sc, MII_BMSR) | PHY_READ(sc, MII_BMSR); + if (val & BMSR_LINK) { + sc->mii_ticks = 0; /* Reset autoneg timer. */ + break; + } + + /* Announce link loss right after it happens. */ + if (sc->mii_ticks++ == 0) + break; + + /* Only retry autonegotiation every mii_anegticks seconds. */ + if (sc->mii_ticks <= sc->mii_anegticks) + break; + + + /* Retry autonegotiation */ + sc->mii_ticks = 0; + brgphy_mii_phy_auto(sc); + break; + } + + /* Update the media status. */ + brgphy_status(sc); + + /* + * Callback if something changed. Note that we need to poke + * the DSP on the Broadcom PHYs if the media changes. + */ + if (sc->mii_media_active != mii->mii_media_active || + sc->mii_media_status != mii->mii_media_status || + cmd == MII_MEDIACHG) { + switch (bsc->mii_oui) { + case MII_OUI_BROADCOM: + break; + case MII_OUI_xxBROADCOM: + switch (bsc->mii_model) { + case MII_MODEL_xxBROADCOM_BCM5400: + bcm5401_load_dspcode(sc); + break; + case MII_MODEL_xxBROADCOM_BCM5401: + if (bsc->mii_rev == 1 || bsc->mii_rev == 3) + bcm5401_load_dspcode(sc); + break; + case MII_MODEL_xxBROADCOM_BCM5411: + bcm5411_load_dspcode(sc); + break; + } + break; + case MII_OUI_xxBROADCOM_ALT1: + break; + } + } + mii_phy_update(sc, cmd); +brgphy_service_exit: + return (error); +} + + +/****************************************************************************/ +/* Sets the PHY link speed. */ +/* */ +/* Returns: */ +/* None */ +/****************************************************************************/ +static void +brgphy_setmedia(struct mii_softc *sc, int media, int master) +{ + struct brgphy_softc *bsc = (struct brgphy_softc *)sc; + int bmcr = 0, gig; + + /* Calculate the value for the BMCR register. */ + switch (IFM_SUBTYPE(media)) { + case IFM_2500_SX: + break; + case IFM_1000_SX: + case IFM_1000_T: + bmcr = BRGPHY_S1000; + break; + case IFM_100_TX: + bmcr = BRGPHY_S100; + break; + case IFM_10_T: + default: + bmcr = BRGPHY_S10; + break; + } + + /* Calculate duplex settings for 1000BasetT/1000BaseX. */ + if ((media & IFM_GMASK) == IFM_FDX) { + bmcr |= BRGPHY_BMCR_FDX; + gig = BRGPHY_1000CTL_AFD; + } else { + gig = BRGPHY_1000CTL_AHD; + } + + /* Force loopback to disconnect PHY for Ethernet medium. */ + brgphy_enable_loopback(sc); + + /* Disable 1000BaseT advertisements. */ + PHY_WRITE(sc, BRGPHY_MII_1000CTL, 0); + /* Disable 10/100 advertisements. */ + PHY_WRITE(sc, BRGPHY_MII_ANAR, BRGPHY_SEL_TYPE); + /* Write forced link speed. */ + PHY_WRITE(sc, BRGPHY_MII_BMCR, bmcr); + + /* If 10/100 only then configuration is complete. */ + if ((IFM_SUBTYPE(media) != IFM_1000_T) && (IFM_SUBTYPE(media) != IFM_1000_SX)) + goto brgphy_setmedia_exit; + + /* Set duplex speed advertisement for 1000BaseT/1000BaseX. */ + PHY_WRITE(sc, BRGPHY_MII_1000CTL, gig); + /* Restart auto-negotiation for 1000BaseT/1000BaseX. */ + PHY_WRITE(sc, BRGPHY_MII_BMCR, + bmcr | BRGPHY_BMCR_AUTOEN | BRGPHY_BMCR_STARTNEG); + + /* If not 5701 PHY then configuration is complete. */ + if (bsc->mii_model != MII_MODEL_xxBROADCOM_BCM5701) + goto brgphy_setmedia_exit; + + /* + * When setting the link manually, one side must be the master and + * the other the slave. However ifmedia doesn't give us a good way + * to specify this, so we fake it by using one of the LINK flags. + * If LINK0 is set, we program the PHY to be a master, otherwise + * it's a slave. + */ + if (master) { + PHY_WRITE(sc, BRGPHY_MII_1000CTL, + gig | BRGPHY_1000CTL_MSE | BRGPHY_1000CTL_MSC); + } else { + PHY_WRITE(sc, BRGPHY_MII_1000CTL, + gig | BRGPHY_1000CTL_MSE); + } + +brgphy_setmedia_exit: + return; +} + +/****************************************************************************/ +/* Set the media status based on the PHY settings. */ +/* IFM_FLAG0 = 0 (RX flow control disabled) | 1 (enabled) */ +/* IFM_FLAG1 = 0 (TX flow control disabled) | 1 (enabled) */ +/* */ +/* Returns: */ +/* None */ +/****************************************************************************/ +static void +brgphy_status(struct mii_softc *sc) +{ + struct brgphy_softc *bsc = (struct brgphy_softc *)sc; + struct mii_data *mii = sc->mii_pdata; + int aux, bmcr, bmsr, anar, anlpar, xstat, val; + + + mii->mii_media_status = IFM_AVALID; + mii->mii_media_active = IFM_ETHER; + + bmsr = PHY_READ(sc, BRGPHY_MII_BMSR) | PHY_READ(sc, BRGPHY_MII_BMSR); + bmcr = PHY_READ(sc, BRGPHY_MII_BMCR); + anar = PHY_READ(sc, BRGPHY_MII_ANAR); + anlpar = PHY_READ(sc, BRGPHY_MII_ANLPAR); + + /* Loopback is enabled. */ + if (bmcr & BRGPHY_BMCR_LOOP) { + + mii->mii_media_active |= IFM_LOOP; + } + + /* Autoneg is still in progress. */ + if ((bmcr & BRGPHY_BMCR_AUTOEN) && + (bmsr & BRGPHY_BMSR_ACOMP) == 0) { + /* Erg, still trying, I guess... */ + mii->mii_media_active |= IFM_NONE; + goto brgphy_status_exit; + } + + /* Autoneg is enabled and complete, link should be up. */ + if ((sc->mii_flags & MIIF_HAVEFIBER) == 0) { + aux = PHY_READ(sc, BRGPHY_MII_AUXSTS); + + /* If copper link is up, get the negotiated speed/duplex. */ + if (aux & BRGPHY_AUXSTS_LINK) { + mii->mii_media_status |= IFM_ACTIVE; + switch (aux & BRGPHY_AUXSTS_AN_RES) { + case BRGPHY_RES_1000FD: + mii->mii_media_active |= IFM_1000_T | IFM_FDX; break; + case BRGPHY_RES_1000HD: + mii->mii_media_active |= IFM_1000_T | IFM_HDX; break; + case BRGPHY_RES_100FD: + mii->mii_media_active |= IFM_100_TX | IFM_FDX; break; + case BRGPHY_RES_100T4: + mii->mii_media_active |= IFM_100_T4; break; + case BRGPHY_RES_100HD: + mii->mii_media_active |= IFM_100_TX | IFM_HDX; break; + case BRGPHY_RES_10FD: + mii->mii_media_active |= IFM_10_T | IFM_FDX; break; + case BRGPHY_RES_10HD: + mii->mii_media_active |= IFM_10_T | IFM_HDX; break; + default: + mii->mii_media_active |= IFM_NONE; break; + } + } + } else { + /* If serdes link is up, get the negotiated speed/duplex. */ + if (bmsr & BRGPHY_BMSR_LINK) { + mii->mii_media_status |= IFM_ACTIVE; + } + + /* Check the link speed/duplex based on the PHY type. */ + if (bsc->serdes_flags & BRGPHY_5706S) { + mii->mii_media_active |= IFM_1000_SX; + + /* If autoneg enabled, read negotiated duplex settings */ + if (bmcr & BRGPHY_BMCR_AUTOEN) { + val = PHY_READ(sc, BRGPHY_SERDES_ANAR) & PHY_READ(sc, BRGPHY_SERDES_ANLPAR); + if (val & BRGPHY_SERDES_ANAR_FDX) + mii->mii_media_active |= IFM_FDX; + else + mii->mii_media_active |= IFM_HDX; + } + + } else if (bsc->serdes_flags & BRGPHY_5708S) { + PHY_WRITE(sc, BRGPHY_5708S_BLOCK_ADDR, BRGPHY_5708S_DIG_PG0); + xstat = PHY_READ(sc, BRGPHY_5708S_PG0_1000X_STAT1); + + switch (xstat & BRGPHY_5708S_PG0_1000X_STAT1_SPEED_MASK) { + case BRGPHY_5708S_PG0_1000X_STAT1_SPEED_10: + mii->mii_media_active |= IFM_10_FL; break; + case BRGPHY_5708S_PG0_1000X_STAT1_SPEED_100: + mii->mii_media_active |= IFM_100_FX; break; + case BRGPHY_5708S_PG0_1000X_STAT1_SPEED_1G: + mii->mii_media_active |= IFM_1000_SX; break; + case BRGPHY_5708S_PG0_1000X_STAT1_SPEED_25G: + mii->mii_media_active |= IFM_2500_SX; break; + } + + if (xstat & BRGPHY_5708S_PG0_1000X_STAT1_FDX) + mii->mii_media_active |= IFM_FDX; + else + mii->mii_media_active |= IFM_HDX; + } + } + +#if 0 + /* Todo: Change bge/bce to use these settings. */ + + /* Fetch flow control settings from the PHY */ + if ((sc->mii_flags & MIIF_HAVEFIBER) == 0) { + /* Set FLAG0 is RX is enabled and FLAG1 if TX is enabled */ + if ((anar & BRGPHY_ANAR_PC) && (anlpar & BRGPHY_ANLPAR_PC)) { + mii->mii_media_active |= IFM_FLAG0 | IFM_FLAG1; + } else if (!(anar & BRGPHY_ANAR_PC) && (anlpar & BRGPHY_ANAR_ASP) && + (anlpar & BRPHY_ANLPAR_PC) && (anlpar & BRGPHY_ANLPAR_ASP)) { + mii->mii_media_active |= IFM_FLAG1; + } else if ((anar & BRGPHY_ANAR_PC) && (anar & BRGPHY_ANAR_ASP) && + !(anlpar & BRGPHY_ANLPAR_PC) && (anlpar & BRGPHY_ANLPAR_ASP)) { + mii->mii_media_active |= IFM_FLAG0; + } + } + + /* Todo: Add support for fiber settings too. */ +#endif + + +brgphy_status_exit: + return; +} + +static void +brgphy_mii_phy_auto(struct mii_softc *sc) +{ + struct brgphy_softc *bsc = (struct brgphy_softc *)sc; + int ktcr = 0; + + brgphy_reset(sc); + + /* Enable flow control in the advertisement register. */ + if ((sc->mii_flags & MIIF_HAVEFIBER) == 0) { + /* Pause capability advertisement (pause capable & asymmetric) */ + PHY_WRITE(sc, BRGPHY_MII_ANAR, + BMSR_MEDIA_TO_ANAR(sc->mii_capabilities) | ANAR_CSMA | + BRGPHY_ANAR_ASP | BRGPHY_ANAR_PC); + } else { + PHY_WRITE(sc, BRGPHY_SERDES_ANAR, BRGPHY_SERDES_ANAR_FDX | + BRGPHY_SERDES_ANAR_HDX | BRGPHY_SERDES_ANAR_BOTH_PAUSE); + } + + /* Enable speed in the 1000baseT control register */ + ktcr = BRGPHY_1000CTL_AFD | BRGPHY_1000CTL_AHD; + if (bsc->mii_model == MII_MODEL_xxBROADCOM_BCM5701) + ktcr |= BRGPHY_1000CTL_MSE | BRGPHY_1000CTL_MSC; + PHY_WRITE(sc, BRGPHY_MII_1000CTL, ktcr); + ktcr = PHY_READ(sc, BRGPHY_MII_1000CTL); + + /* Start autonegotiation */ + PHY_WRITE(sc, BRGPHY_MII_BMCR,BRGPHY_BMCR_AUTOEN | BRGPHY_BMCR_STARTNEG); + PHY_WRITE(sc, BRGPHY_MII_IMR, 0xFF00); + +} + + +/* Enable loopback to force the link down. */ +static void +brgphy_enable_loopback(struct mii_softc *sc) +{ + int i; + + PHY_WRITE(sc, BRGPHY_MII_BMCR, BRGPHY_BMCR_LOOP); + for (i = 0; i < 15000; i++) { + if (!(PHY_READ(sc, BRGPHY_MII_BMSR) & BRGPHY_BMSR_LINK)) + break; + DELAY(10); + } +} + +/* Turn off tap power management on 5401. */ +static void +bcm5401_load_dspcode(struct mii_softc *sc) +{ + static const struct { + int reg; + uint16_t val; + } dspcode[] = { + { BRGPHY_MII_AUXCTL, 0x0c20 }, + { BRGPHY_MII_DSP_ADDR_REG, 0x0012 }, + { BRGPHY_MII_DSP_RW_PORT, 0x1804 }, + { BRGPHY_MII_DSP_ADDR_REG, 0x0013 }, + { BRGPHY_MII_DSP_RW_PORT, 0x1204 }, + { BRGPHY_MII_DSP_ADDR_REG, 0x8006 }, + { BRGPHY_MII_DSP_RW_PORT, 0x0132 }, + { BRGPHY_MII_DSP_ADDR_REG, 0x8006 }, + { BRGPHY_MII_DSP_RW_PORT, 0x0232 }, + { BRGPHY_MII_DSP_ADDR_REG, 0x201f }, + { BRGPHY_MII_DSP_RW_PORT, 0x0a20 }, + { 0, 0 }, + }; + int i; + + for (i = 0; dspcode[i].reg != 0; i++) + PHY_WRITE(sc, dspcode[i].reg, dspcode[i].val); + DELAY(40); +} + +static void +bcm5411_load_dspcode(struct mii_softc *sc) +{ + static const struct { + int reg; + uint16_t val; + } dspcode[] = { + { 0x1c, 0x8c23 }, + { 0x1c, 0x8ca3 }, + { 0x1c, 0x8c23 }, + { 0, 0 }, + }; + int i; + + for (i = 0; dspcode[i].reg != 0; i++) + PHY_WRITE(sc, dspcode[i].reg, dspcode[i].val); +} + +static void +brgphy_fixup_5704_a0_bug(struct mii_softc *sc) +{ + static const struct { + int reg; + uint16_t val; + } dspcode[] = { + { 0x1c, 0x8d68 }, + { 0x1c, 0x8d68 }, + { 0, 0 }, + }; + int i; + + for (i = 0; dspcode[i].reg != 0; i++) + PHY_WRITE(sc, dspcode[i].reg, dspcode[i].val); +} + +static void +brgphy_fixup_adc_bug(struct mii_softc *sc) +{ + static const struct { + int reg; + uint16_t val; + } dspcode[] = { + { BRGPHY_MII_AUXCTL, 0x0c00 }, + { BRGPHY_MII_DSP_ADDR_REG, 0x201f }, + { BRGPHY_MII_DSP_RW_PORT, 0x2aaa }, + { 0, 0 }, + }; + int i; + + for (i = 0; dspcode[i].reg != 0; i++) + PHY_WRITE(sc, dspcode[i].reg, dspcode[i].val); +} + +static void +brgphy_fixup_adjust_trim(struct mii_softc *sc) +{ + static const struct { + int reg; + uint16_t val; + } dspcode[] = { + { BRGPHY_MII_AUXCTL, 0x0c00 }, + { BRGPHY_MII_DSP_ADDR_REG, 0x000a }, + { BRGPHY_MII_DSP_RW_PORT, 0x110b }, + { BRGPHY_MII_TEST1, 0x0014 }, + { BRGPHY_MII_AUXCTL, 0x0400 }, + { 0, 0 }, + }; + int i; + + for (i = 0; dspcode[i].reg != 0; i++) + PHY_WRITE(sc, dspcode[i].reg, dspcode[i].val); +} + +static void +brgphy_fixup_ber_bug(struct mii_softc *sc) +{ + static const struct { + int reg; + uint16_t val; + } dspcode[] = { + { BRGPHY_MII_AUXCTL, 0x0c00 }, + { BRGPHY_MII_DSP_ADDR_REG, 0x000a }, + { BRGPHY_MII_DSP_RW_PORT, 0x310b }, + { BRGPHY_MII_DSP_ADDR_REG, 0x201f }, + { BRGPHY_MII_DSP_RW_PORT, 0x9506 }, + { BRGPHY_MII_DSP_ADDR_REG, 0x401f }, + { BRGPHY_MII_DSP_RW_PORT, 0x14e2 }, + { BRGPHY_MII_AUXCTL, 0x0400 }, + { 0, 0 }, + }; + int i; + + for (i = 0; dspcode[i].reg != 0; i++) + PHY_WRITE(sc, dspcode[i].reg, dspcode[i].val); +} + +static void +brgphy_fixup_crc_bug(struct mii_softc *sc) +{ + static const struct { + int reg; + uint16_t val; + } dspcode[] = { + { BRGPHY_MII_DSP_RW_PORT, 0x0a75 }, + { 0x1c, 0x8c68 }, + { 0x1c, 0x8d68 }, + { 0x1c, 0x8c68 }, + { 0, 0 }, + }; + int i; + + for (i = 0; dspcode[i].reg != 0; i++) + PHY_WRITE(sc, dspcode[i].reg, dspcode[i].val); +} + +static void +brgphy_fixup_jitter_bug(struct mii_softc *sc) +{ + static const struct { + int reg; + uint16_t val; + } dspcode[] = { + { BRGPHY_MII_AUXCTL, 0x0c00 }, + { BRGPHY_MII_DSP_ADDR_REG, 0x000a }, + { BRGPHY_MII_DSP_RW_PORT, 0x010b }, + { BRGPHY_MII_AUXCTL, 0x0400 }, + { 0, 0 }, + }; + int i; + + for (i = 0; dspcode[i].reg != 0; i++) + PHY_WRITE(sc, dspcode[i].reg, dspcode[i].val); +} + + +static void +brgphy_fixup_disable_early_dac(struct mii_softc *sc) +{ + uint32_t val; + + PHY_WRITE(sc, BRGPHY_MII_DSP_ADDR_REG, 0x0f08); + val = PHY_READ(sc, BRGPHY_MII_DSP_RW_PORT); + val &= ~(1 << 8); + PHY_WRITE(sc, BRGPHY_MII_DSP_RW_PORT, val); + +} + + +static void +brgphy_ethernet_wirespeed(struct mii_softc *sc) +{ + uint32_t val; + + /* Enable Ethernet@WireSpeed. */ + PHY_WRITE(sc, BRGPHY_MII_AUXCTL, 0x7007); + val = PHY_READ(sc, BRGPHY_MII_AUXCTL); + PHY_WRITE(sc, BRGPHY_MII_AUXCTL, val | (1 << 15) | (1 << 4)); +} + + +static void +brgphy_jumbo_settings(struct mii_softc *sc, u_long mtu) +{ + struct brgphy_softc *bsc = (struct brgphy_softc *)sc; + uint32_t val; + + /* Set or clear jumbo frame settings in the PHY. */ + if (mtu > ETHER_MAX_LEN) { + if (bsc->mii_model == MII_MODEL_xxBROADCOM_BCM5401) { + /* BCM5401 PHY cannot read-modify-write. */ + PHY_WRITE(sc, BRGPHY_MII_AUXCTL, 0x4c20); + } else { + PHY_WRITE(sc, BRGPHY_MII_AUXCTL, 0x7); + val = PHY_READ(sc, BRGPHY_MII_AUXCTL); + PHY_WRITE(sc, BRGPHY_MII_AUXCTL, + val | BRGPHY_AUXCTL_LONG_PKT); + } + + val = PHY_READ(sc, BRGPHY_MII_PHY_EXTCTL); + PHY_WRITE(sc, BRGPHY_MII_PHY_EXTCTL, + val | BRGPHY_PHY_EXTCTL_HIGH_LA); + } else { + PHY_WRITE(sc, BRGPHY_MII_AUXCTL, 0x7); + val = PHY_READ(sc, BRGPHY_MII_AUXCTL); + PHY_WRITE(sc, BRGPHY_MII_AUXCTL, + val & ~(BRGPHY_AUXCTL_LONG_PKT | 0x7)); + + val = PHY_READ(sc, BRGPHY_MII_PHY_EXTCTL); + PHY_WRITE(sc, BRGPHY_MII_PHY_EXTCTL, + val & ~BRGPHY_PHY_EXTCTL_HIGH_LA); + } +} + +static void +brgphy_reset(struct mii_softc *sc) +{ + struct brgphy_softc *bsc = (struct brgphy_softc *)sc; + struct bge_softc *bge_sc = NULL; + struct bce_softc *bce_sc = NULL; + struct ifnet *ifp; + + /* Perform a standard PHY reset. */ + mii_phy_reset(sc); + + /* Handle any PHY specific procedures following the reset. */ + switch (bsc->mii_oui) { + case MII_OUI_BROADCOM: + break; + case MII_OUI_xxBROADCOM: + switch (bsc->mii_model) { + case MII_MODEL_xxBROADCOM_BCM5400: + bcm5401_load_dspcode(sc); + break; + case MII_MODEL_xxBROADCOM_BCM5401: + if (bsc->mii_rev == 1 || bsc->mii_rev == 3) + bcm5401_load_dspcode(sc); + break; + case MII_MODEL_xxBROADCOM_BCM5411: + bcm5411_load_dspcode(sc); + break; + } + break; + case MII_OUI_xxBROADCOM_ALT1: + break; + } + + ifp = sc->mii_pdata->mii_ifp; + + /* Find the driver associated with this PHY. */ + if (strcmp(ifp->if_dname, "bge") == 0) { + bge_sc = ifp->if_softc; + } else if (strcmp(ifp->if_dname, "bce") == 0) { + bce_sc = ifp->if_softc; + } + + /* Handle any bge (NetXtreme/NetLink) workarounds. */ + if (bge_sc) { + /* Fix up various bugs */ + if (bge_sc->bge_flags & BGE_FLAG_5704_A0_BUG) + brgphy_fixup_5704_a0_bug(sc); + if (bge_sc->bge_flags & BGE_FLAG_ADC_BUG) + brgphy_fixup_adc_bug(sc); + if (bge_sc->bge_flags & BGE_FLAG_ADJUST_TRIM) + brgphy_fixup_adjust_trim(sc); + if (bge_sc->bge_flags & BGE_FLAG_BER_BUG) + brgphy_fixup_ber_bug(sc); + if (bge_sc->bge_flags & BGE_FLAG_CRC_BUG) + brgphy_fixup_crc_bug(sc); + if (bge_sc->bge_flags & BGE_FLAG_JITTER_BUG) + brgphy_fixup_jitter_bug(sc); + + brgphy_jumbo_settings(sc, ifp->if_mtu); + + if (bge_sc->bge_flags & BGE_FLAG_WIRESPEED) + brgphy_ethernet_wirespeed(sc); + + /* Enable Link LED on Dell boxes */ + if (bge_sc->bge_flags & BGE_FLAG_NO_3LED) { + PHY_WRITE(sc, BRGPHY_MII_PHY_EXTCTL, + PHY_READ(sc, BRGPHY_MII_PHY_EXTCTL) & + ~BRGPHY_PHY_EXTCTL_3_LED); + } + + /* Adjust output voltage (From Linux driver) */ + if (bge_sc->bge_asicrev == BGE_ASICREV_BCM5906) + PHY_WRITE(sc, BRGPHY_MII_EPHY_PTEST, 0x12); + + /* Handle any bce (NetXtreme II) workarounds. */ + } else if (bce_sc) { + + if (BCE_CHIP_NUM(bce_sc) == BCE_CHIP_NUM_5708 && + (bce_sc->bce_phy_flags & BCE_PHY_SERDES_FLAG)) { + + /* Store autoneg capabilities/results in digital block (Page 0) */ + PHY_WRITE(sc, BRGPHY_5708S_BLOCK_ADDR, BRGPHY_5708S_DIG3_PG2); + PHY_WRITE(sc, BRGPHY_5708S_PG2_DIGCTL_3_0, + BRGPHY_5708S_PG2_DIGCTL_3_0_USE_IEEE); + PHY_WRITE(sc, BRGPHY_5708S_BLOCK_ADDR, BRGPHY_5708S_DIG_PG0); + + /* Enable fiber mode and autodetection */ + PHY_WRITE(sc, BRGPHY_5708S_PG0_1000X_CTL1, + PHY_READ(sc, BRGPHY_5708S_PG0_1000X_CTL1) | + BRGPHY_5708S_PG0_1000X_CTL1_AUTODET_EN | + BRGPHY_5708S_PG0_1000X_CTL1_FIBER_MODE); + + /* Enable parallel detection */ + PHY_WRITE(sc, BRGPHY_5708S_PG0_1000X_CTL2, + PHY_READ(sc, BRGPHY_5708S_PG0_1000X_CTL2) | + BRGPHY_5708S_PG0_1000X_CTL2_PAR_DET_EN); + + /* Advertise 2.5G support through next page during autoneg */ + if (bce_sc->bce_phy_flags & BCE_PHY_2_5G_CAPABLE_FLAG) + PHY_WRITE(sc, BRGPHY_5708S_ANEG_NXT_PG_XMIT1, + PHY_READ(sc, BRGPHY_5708S_ANEG_NXT_PG_XMIT1) | + BRGPHY_5708S_ANEG_NXT_PG_XMIT1_25G); + + /* Increase TX signal amplitude */ + if ((BCE_CHIP_ID(bce_sc) == BCE_CHIP_ID_5708_A0) || + (BCE_CHIP_ID(bce_sc) == BCE_CHIP_ID_5708_B0) || + (BCE_CHIP_ID(bce_sc) == BCE_CHIP_ID_5708_B1)) { + PHY_WRITE(sc, BRGPHY_5708S_BLOCK_ADDR, + BRGPHY_5708S_TX_MISC_PG5); + PHY_WRITE(sc, BRGPHY_5708S_PG5_TXACTL1, + PHY_READ(sc, BRGPHY_5708S_PG5_TXACTL1) & ~0x30); + PHY_WRITE(sc, BRGPHY_5708S_BLOCK_ADDR, + BRGPHY_5708S_DIG_PG0); + } + + /* Backplanes use special driver/pre-driver/pre-emphasis values. */ + if ((bce_sc->bce_shared_hw_cfg & BCE_SHARED_HW_CFG_PHY_BACKPLANE) && + (bce_sc->bce_port_hw_cfg & BCE_PORT_HW_CFG_CFG_TXCTL3_MASK)) { + PHY_WRITE(sc, BRGPHY_5708S_BLOCK_ADDR, + BRGPHY_5708S_TX_MISC_PG5); + PHY_WRITE(sc, BRGPHY_5708S_PG5_TXACTL3, + bce_sc->bce_port_hw_cfg & + BCE_PORT_HW_CFG_CFG_TXCTL3_MASK); + PHY_WRITE(sc, BRGPHY_5708S_BLOCK_ADDR, + BRGPHY_5708S_DIG_PG0); + } + } else if (BCE_CHIP_NUM(bce_sc) == BCE_CHIP_NUM_5709) { + if ((BCE_CHIP_REV(bce_sc) == BCE_CHIP_REV_Ax) || + (BCE_CHIP_REV(bce_sc) == BCE_CHIP_REV_Bx)) + brgphy_fixup_disable_early_dac(sc); + + brgphy_jumbo_settings(sc, ifp->if_mtu); + brgphy_ethernet_wirespeed(sc); + } else { + brgphy_fixup_ber_bug(sc); + brgphy_jumbo_settings(sc, ifp->if_mtu); + brgphy_ethernet_wirespeed(sc); + } + + } +} + diff --git a/src/add-ons/kernel/drivers/network/broadcom570x/dev/mii/miidevs.h b/src/add-ons/kernel/drivers/network/broadcom570x/dev/mii/miidevs.h deleted file mode 100644 index 9ee45234c2..0000000000 --- a/src/add-ons/kernel/drivers/network/broadcom570x/dev/mii/miidevs.h +++ /dev/null @@ -1,12 +0,0 @@ -#define MII_OUI_BROADCOM 0x001018 -#define MII_MODEL_BROADCOM_3C905B 0x0012 -#define MII_MODEL_BROADCOM_3C905C 0x0017 -#define MII_MODEL_BROADCOM_BCM5201 0x0021 -#define MII_MODEL_BROADCOM_BCM5221 0x001e -#define MII_MODEL_BROADCOM_BCM4401 0x0036 - -#define MII_STR_BROADCOM_3C905B "3C905B" -#define MII_STR_BROADCOM_3C905C "3C905C" -#define MII_STR_BROADCOM_BCM5201 "BCM5201" -#define MII_STR_BROADCOM_BCM5221 "BCM5221" -#define MII_STR_BROADCOM_BCM4401 "BCM4401"