Deleted Added
full compact
if_bge.c (152953) if_bge.c (153234)
1/*-
2 * Copyright (c) 2001 Wind River Systems
3 * Copyright (c) 1997, 1998, 1999, 2001
4 * Bill Paul <wpaul@windriver.com>. All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:

--- 18 unchanged lines hidden (view full) ---

27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
31 * THE POSSIBILITY OF SUCH DAMAGE.
32 */
33
34#include <sys/cdefs.h>
1/*-
2 * Copyright (c) 2001 Wind River Systems
3 * Copyright (c) 1997, 1998, 1999, 2001
4 * Bill Paul <wpaul@windriver.com>. All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:

--- 18 unchanged lines hidden (view full) ---

27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
31 * THE POSSIBILITY OF SUCH DAMAGE.
32 */
33
34#include <sys/cdefs.h>
35__FBSDID("$FreeBSD: head/sys/dev/bge/if_bge.c 152953 2005-11-30 12:37:07Z glebius $");
35__FBSDID("$FreeBSD: head/sys/dev/bge/if_bge.c 153234 2005-12-08 13:31:52Z oleg $");
36
37/*
38 * Broadcom BCM570x family gigabit ethernet driver for FreeBSD.
39 *
40 * The Broadcom BCM5700 is based on technology originally developed by
41 * Alteon Networks as part of the Tigon I and Tigon II gigabit ethernet
42 * MAC chips. The BCM5700, sometimes refered to as the Tigon III, has
43 * two on-board MIPS R4000 CPUs and can have as much as 16MB of external

--- 230 unchanged lines hidden (view full) ---

274#ifdef DEVICE_POLLING
275static void bge_poll (struct ifnet *ifp, enum poll_cmd cmd,
276 int count);
277static void bge_poll_locked (struct ifnet *ifp, enum poll_cmd cmd,
278 int count);
279#endif
280
281static void bge_reset (struct bge_softc *);
36
37/*
38 * Broadcom BCM570x family gigabit ethernet driver for FreeBSD.
39 *
40 * The Broadcom BCM5700 is based on technology originally developed by
41 * Alteon Networks as part of the Tigon I and Tigon II gigabit ethernet
42 * MAC chips. The BCM5700, sometimes refered to as the Tigon III, has
43 * two on-board MIPS R4000 CPUs and can have as much as 16MB of external

--- 230 unchanged lines hidden (view full) ---

274#ifdef DEVICE_POLLING
275static void bge_poll (struct ifnet *ifp, enum poll_cmd cmd,
276 int count);
277static void bge_poll_locked (struct ifnet *ifp, enum poll_cmd cmd,
278 int count);
279#endif
280
281static void bge_reset (struct bge_softc *);
282static void bge_link_upd (struct bge_softc *);
282
283static device_method_t bge_methods[] = {
284 /* Device interface */
285 DEVMETHOD(device_probe, bge_probe),
286 DEVMETHOD(device_attach, bge_attach),
287 DEVMETHOD(device_detach, bge_detach),
288 DEVMETHOD(device_shutdown, bge_shutdown),
289 DEVMETHOD(device_suspend, bge_suspend),

--- 2669 unchanged lines hidden (view full) ---

2959
2960 sc->rxcycles = count;
2961 bge_rxeof(sc);
2962 bge_txeof(sc);
2963 if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd))
2964 bge_start_locked(ifp);
2965
2966 if (cmd == POLL_AND_CHECK_STATUS) {
283
284static device_method_t bge_methods[] = {
285 /* Device interface */
286 DEVMETHOD(device_probe, bge_probe),
287 DEVMETHOD(device_attach, bge_attach),
288 DEVMETHOD(device_detach, bge_detach),
289 DEVMETHOD(device_shutdown, bge_shutdown),
290 DEVMETHOD(device_suspend, bge_suspend),

--- 2669 unchanged lines hidden (view full) ---

2960
2961 sc->rxcycles = count;
2962 bge_rxeof(sc);
2963 bge_txeof(sc);
2964 if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd))
2965 bge_start_locked(ifp);
2966
2967 if (cmd == POLL_AND_CHECK_STATUS) {
2967 u_int32_t status;
2968 uint32_t statusword;
2968
2969
2969 status = CSR_READ_4(sc, BGE_MAC_STS);
2970 if (status)
2971 CSR_WRITE_4(sc, BGE_MAC_STS, status);
2970 bus_dmamap_sync(sc->bge_cdata.bge_status_tag,
2971 sc->bge_cdata.bge_status_map, BUS_DMASYNC_POSTWRITE);
2972
2973 statusword = atomic_readandclear_32(&sc->bge_ldata.bge_status_block->bge_status);
2974
2975 if (sc->bge_asicrev == BGE_ASICREV_BCM5700 ||
2976 statusword & BGE_STATFLAG_LINKSTATE_CHANGED)
2977 bge_link_upd(sc);
2978
2979 bus_dmamap_sync(sc->bge_cdata.bge_status_tag,
2980 sc->bge_cdata.bge_status_map, BUS_DMASYNC_PREWRITE);
2972 }
2973}
2974#endif /* DEVICE_POLLING */
2975
2976static void
2977bge_intr(xsc)
2978 void *xsc;
2979{
2980 struct bge_softc *sc;
2981 struct ifnet *ifp;
2981 }
2982}
2983#endif /* DEVICE_POLLING */
2984
2985static void
2986bge_intr(xsc)
2987 void *xsc;
2988{
2989 struct bge_softc *sc;
2990 struct ifnet *ifp;
2982 u_int32_t statusword;
2983 u_int32_t status, mimode;
2991 uint32_t statusword;
2984
2985 sc = xsc;
2992
2993 sc = xsc;
2986 ifp = sc->bge_ifp;
2987
2988 BGE_LOCK(sc);
2989
2994
2995 BGE_LOCK(sc);
2996
2997 ifp = sc->bge_ifp;
2998
2990#ifdef DEVICE_POLLING
2991 if (ifp->if_capenable & IFCAP_POLLING) {
2992 BGE_UNLOCK(sc);
2993 return;
2994 }
2995#endif
2996
2997 bus_dmamap_sync(sc->bge_cdata.bge_status_tag,

--- 6 unchanged lines hidden (view full) ---

3004 /* Avoid this for now -- checking this register is expensive. */
3005 /* Make sure this is really our interrupt. */
3006 if (!(CSR_READ_4(sc, BGE_MISC_LOCAL_CTL) & BGE_MLC_INTR_STATE))
3007 return;
3008#endif
3009 /* Ack interrupt and stop others from occuring. */
3010 CSR_WRITE_4(sc, BGE_MBX_IRQ0_LO, 1);
3011
2999#ifdef DEVICE_POLLING
3000 if (ifp->if_capenable & IFCAP_POLLING) {
3001 BGE_UNLOCK(sc);
3002 return;
3003 }
3004#endif
3005
3006 bus_dmamap_sync(sc->bge_cdata.bge_status_tag,

--- 6 unchanged lines hidden (view full) ---

3013 /* Avoid this for now -- checking this register is expensive. */
3014 /* Make sure this is really our interrupt. */
3015 if (!(CSR_READ_4(sc, BGE_MISC_LOCAL_CTL) & BGE_MLC_INTR_STATE))
3016 return;
3017#endif
3018 /* Ack interrupt and stop others from occuring. */
3019 CSR_WRITE_4(sc, BGE_MBX_IRQ0_LO, 1);
3020
3012 /*
3013 * Process link state changes.
3014 * Grrr. The link status word in the status block does
3015 * not work correctly on the BCM5700 rev AX and BX chips,
3016 * according to all available information. Hence, we have
3017 * to enable MII interrupts in order to properly obtain
3018 * async link changes. Unfortunately, this also means that
3019 * we have to read the MAC status register to detect link
3020 * changes, thereby adding an additional register access to
3021 * the interrupt handler.
3022 */
3021 if (sc->bge_asicrev == BGE_ASICREV_BCM5700 ||
3022 statusword & BGE_STATFLAG_LINKSTATE_CHANGED)
3023 bge_link_upd(sc);
3023
3024
3024 if (sc->bge_asicrev == BGE_ASICREV_BCM5700) {
3025
3026 status = CSR_READ_4(sc, BGE_MAC_STS);
3027 if (status & BGE_MACSTAT_MI_INTERRUPT) {
3028 sc->bge_link = 0;
3029 callout_stop(&sc->bge_stat_ch);
3030 bge_tick_locked(sc);
3031 /* Clear the interrupt */
3032 CSR_WRITE_4(sc, BGE_MAC_EVT_ENB,
3033 BGE_EVTENB_MI_INTERRUPT);
3034 bge_miibus_readreg(sc->bge_dev, 1, BRGPHY_MII_ISR);
3035 bge_miibus_writereg(sc->bge_dev, 1, BRGPHY_MII_IMR,
3036 BRGPHY_INTRS);
3037 }
3038 } else {
3039 if (statusword & BGE_STATFLAG_LINKSTATE_CHANGED) {
3040 /*
3041 * Sometimes PCS encoding errors are detected in
3042 * TBI mode (on fiber NICs), and for some reason
3043 * the chip will signal them as link changes.
3044 * If we get a link change event, but the 'PCS
3045 * encoding error' bit in the MAC status register
3046 * is set, don't bother doing a link check.
3047 * This avoids spurious "gigabit link up" messages
3048 * that sometimes appear on fiber NICs during
3049 * periods of heavy traffic. (There should be no
3050 * effect on copper NICs.)
3051 *
3052 * If we do have a copper NIC (bge_tbi == 0) then
3053 * check that the AUTOPOLL bit is set before
3054 * processing the event as a real link change.
3055 * Turning AUTOPOLL on and off in the MII read/write
3056 * functions will often trigger a link status
3057 * interrupt for no reason.
3058 */
3059 status = CSR_READ_4(sc, BGE_MAC_STS);
3060 mimode = CSR_READ_4(sc, BGE_MI_MODE);
3061 if (!(status & (BGE_MACSTAT_PORT_DECODE_ERROR|
3062 BGE_MACSTAT_MI_COMPLETE)) && (!sc->bge_tbi &&
3063 (mimode & BGE_MIMODE_AUTOPOLL))) {
3064 sc->bge_link = 0;
3065 callout_stop(&sc->bge_stat_ch);
3066 bge_tick_locked(sc);
3067 }
3068 /* Clear the interrupt */
3069 CSR_WRITE_4(sc, BGE_MAC_STS, BGE_MACSTAT_SYNC_CHANGED|
3070 BGE_MACSTAT_CFG_CHANGED|BGE_MACSTAT_MI_COMPLETE|
3071 BGE_MACSTAT_LINK_CHANGED);
3072
3073 /* Force flush the status block cached by PCI bridge */
3074 CSR_READ_4(sc, BGE_MBX_IRQ0_LO);
3075 }
3076 }
3077
3078 if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
3079 /* Check RX return ring producer/consumer */
3080 bge_rxeof(sc);
3081
3082 /* Check TX ring producer/consumer */
3083 bge_txeof(sc);
3084 }
3085

--- 14 unchanged lines hidden (view full) ---

3100 return;
3101}
3102
3103static void
3104bge_tick_locked(sc)
3105 struct bge_softc *sc;
3106{
3107 struct mii_data *mii = NULL;
3025 if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
3026 /* Check RX return ring producer/consumer */
3027 bge_rxeof(sc);
3028
3029 /* Check TX ring producer/consumer */
3030 bge_txeof(sc);
3031 }
3032

--- 14 unchanged lines hidden (view full) ---

3047 return;
3048}
3049
3050static void
3051bge_tick_locked(sc)
3052 struct bge_softc *sc;
3053{
3054 struct mii_data *mii = NULL;
3108 struct ifmedia *ifm = NULL;
3109 struct ifnet *ifp;
3110
3055 struct ifnet *ifp;
3056
3111 ifp = sc->bge_ifp;
3112
3113 BGE_LOCK_ASSERT(sc);
3114
3057 BGE_LOCK_ASSERT(sc);
3058
3059 ifp = sc->bge_ifp;
3060
3115 if (sc->bge_asicrev == BGE_ASICREV_BCM5705 ||
3116 sc->bge_asicrev == BGE_ASICREV_BCM5750)
3117 bge_stats_update_regs(sc);
3118 else
3119 bge_stats_update(sc);
3061 if (sc->bge_asicrev == BGE_ASICREV_BCM5705 ||
3062 sc->bge_asicrev == BGE_ASICREV_BCM5750)
3063 bge_stats_update_regs(sc);
3064 else
3065 bge_stats_update(sc);
3120 callout_reset(&sc->bge_stat_ch, hz, bge_tick, sc);
3121 if (sc->bge_link)
3122 return;
3123
3124 if (sc->bge_tbi) {
3066
3067 if (sc->bge_tbi) {
3125 ifm = &sc->bge_ifmedia;
3126 if (CSR_READ_4(sc, BGE_MAC_STS) &
3127 BGE_MACSTAT_TBI_PCS_SYNCHED) {
3068 if (!sc->bge_link) {
3069 if (CSR_READ_4(sc, BGE_MAC_STS) &
3070 BGE_MACSTAT_TBI_PCS_SYNCHED) {
3071 sc->bge_link++;
3072 if (sc->bge_asicrev == BGE_ASICREV_BCM5704)
3073 BGE_CLRBIT(sc, BGE_MAC_MODE,
3074 BGE_MACMODE_TBI_SEND_CFGS);
3075 CSR_WRITE_4(sc, BGE_MAC_STS, 0xFFFFFFFF);
3076 if (bootverbose)
3077 printf("bge%d: gigabit link up\n",
3078 sc->bge_unit);
3079 if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd))
3080 bge_start_locked(ifp);
3081 }
3082 }
3083 }
3084 else {
3085 mii = device_get_softc(sc->bge_miibus);
3086 mii_tick(mii);
3087
3088 if (!sc->bge_link && mii->mii_media_status & IFM_ACTIVE &&
3089 IFM_SUBTYPE(mii->mii_media_active) != IFM_NONE) {
3128 sc->bge_link++;
3090 sc->bge_link++;
3129 if (sc->bge_asicrev == BGE_ASICREV_BCM5704)
3130 BGE_CLRBIT(sc, BGE_MAC_MODE,
3131 BGE_MACMODE_TBI_SEND_CFGS);
3132 CSR_WRITE_4(sc, BGE_MAC_STS, 0xFFFFFFFF);
3133 if (bootverbose)
3134 printf("bge%d: gigabit link up\n",
3135 sc->bge_unit);
3091 if ((IFM_SUBTYPE(mii->mii_media_active) == IFM_1000_T ||
3092 IFM_SUBTYPE(mii->mii_media_active) == IFM_1000_SX)&&
3093 bootverbose)
3094 printf("bge%d: gigabit link up\n", sc->bge_unit);
3136 if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd))
3137 bge_start_locked(ifp);
3138 }
3095 if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd))
3096 bge_start_locked(ifp);
3097 }
3139 return;
3140 }
3141
3098 }
3099
3142 mii = device_get_softc(sc->bge_miibus);
3143 mii_tick(mii);
3144
3145 if (!sc->bge_link && mii->mii_media_status & IFM_ACTIVE &&
3146 IFM_SUBTYPE(mii->mii_media_active) != IFM_NONE) {
3147 sc->bge_link++;
3148 if ((IFM_SUBTYPE(mii->mii_media_active) == IFM_1000_T ||
3149 IFM_SUBTYPE(mii->mii_media_active) == IFM_1000_SX) &&
3150 bootverbose)
3151 printf("bge%d: gigabit link up\n", sc->bge_unit);
3152 if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd))
3153 bge_start_locked(ifp);
3154 }
3155
3156 return;
3100 callout_reset(&sc->bge_stat_ch, hz, bge_tick, sc);
3157}
3158
3159static void
3160bge_tick(xsc)
3161 void *xsc;
3162{
3163 struct bge_softc *sc;
3164

--- 145 unchanged lines hidden (view full) ---

3310{
3311 struct bge_softc *sc;
3312 struct mbuf *m_head = NULL;
3313 u_int32_t prodidx = 0;
3314 int count = 0;
3315
3316 sc = ifp->if_softc;
3317
3101}
3102
3103static void
3104bge_tick(xsc)
3105 void *xsc;
3106{
3107 struct bge_softc *sc;
3108

--- 145 unchanged lines hidden (view full) ---

3254{
3255 struct bge_softc *sc;
3256 struct mbuf *m_head = NULL;
3257 u_int32_t prodidx = 0;
3258 int count = 0;
3259
3260 sc = ifp->if_softc;
3261
3318 if (!sc->bge_link && IFQ_DRV_IS_EMPTY(&ifp->if_snd))
3262 if (!sc->bge_link || IFQ_DRV_IS_EMPTY(&ifp->if_snd))
3319 return;
3320
3321 prodidx = CSR_READ_4(sc, BGE_MBX_TX_HOST_PROD0_LO);
3322
3323 while(sc->bge_cdata.bge_tx_chain[prodidx] == NULL) {
3324 IFQ_DRV_DEQUEUE(&ifp->if_snd, m_head);
3325 if (m_head == NULL)
3326 break;

--- 610 unchanged lines hidden (view full) ---

3937 bge_init_locked(sc);
3938 if (ifp->if_drv_flags & IFF_DRV_RUNNING)
3939 bge_start_locked(ifp);
3940 }
3941 BGE_UNLOCK(sc);
3942
3943 return (0);
3944}
3263 return;
3264
3265 prodidx = CSR_READ_4(sc, BGE_MBX_TX_HOST_PROD0_LO);
3266
3267 while(sc->bge_cdata.bge_tx_chain[prodidx] == NULL) {
3268 IFQ_DRV_DEQUEUE(&ifp->if_snd, m_head);
3269 if (m_head == NULL)
3270 break;

--- 610 unchanged lines hidden (view full) ---

3881 bge_init_locked(sc);
3882 if (ifp->if_drv_flags & IFF_DRV_RUNNING)
3883 bge_start_locked(ifp);
3884 }
3885 BGE_UNLOCK(sc);
3886
3887 return (0);
3888}
3889
3890static void
3891bge_link_upd(sc)
3892 struct bge_softc *sc;
3893{
3894 uint32_t status;
3895
3896 BGE_LOCK_ASSERT(sc);
3897 /*
3898 * Process link state changes.
3899 * Grrr. The link status word in the status block does
3900 * not work correctly on the BCM5700 rev AX and BX chips,
3901 * according to all available information. Hence, we have
3902 * to enable MII interrupts in order to properly obtain
3903 * async link changes. Unfortunately, this also means that
3904 * we have to read the MAC status register to detect link
3905 * changes, thereby adding an additional register access to
3906 * the interrupt handler.
3907 */
3908
3909 if (sc->bge_asicrev == BGE_ASICREV_BCM5700) {
3910 status = CSR_READ_4(sc, BGE_MAC_STS);
3911 if (status & BGE_MACSTAT_MI_INTERRUPT) {
3912 sc->bge_link = 0;
3913 callout_stop(&sc->bge_stat_ch);
3914 bge_tick_locked(sc);
3915 /* Clear the interrupt */
3916 CSR_WRITE_4(sc, BGE_MAC_EVT_ENB,
3917 BGE_EVTENB_MI_INTERRUPT);
3918 bge_miibus_readreg(sc->bge_dev, 1, BRGPHY_MII_ISR);
3919 bge_miibus_writereg(sc->bge_dev, 1, BRGPHY_MII_IMR,
3920 BRGPHY_INTRS);
3921 }
3922 return;
3923 }
3924
3925 /*
3926 * Sometimes PCS encoding errors are detected in
3927 * TBI mode (on fiber NICs), and for some reason
3928 * the chip will signal them as link changes.
3929 * If we get a link change event, but the 'PCS
3930 * encoding error' bit in the MAC status register
3931 * is set, don't bother doing a link check.
3932 * This avoids spurious "gigabit link up" messages
3933 * that sometimes appear on fiber NICs during
3934 * periods of heavy traffic. (There should be no
3935 * effect on copper NICs.)
3936 */
3937 if (sc->bge_tbi) status = CSR_READ_4(sc, BGE_MAC_STS);
3938
3939 if (!sc->bge_tbi || !(status & (BGE_MACSTAT_PORT_DECODE_ERROR |
3940 BGE_MACSTAT_MI_COMPLETE))) {
3941 sc->bge_link = 0;
3942 callout_stop(&sc->bge_stat_ch);
3943 bge_tick_locked(sc);
3944 }
3945
3946 /* Clear the interrupt */
3947 CSR_WRITE_4(sc, BGE_MAC_STS, BGE_MACSTAT_SYNC_CHANGED|
3948 BGE_MACSTAT_CFG_CHANGED|BGE_MACSTAT_MI_COMPLETE|
3949 BGE_MACSTAT_LINK_CHANGED);
3950
3951 /* Force flush the status block cached by PCI bridge */
3952 CSR_READ_4(sc, BGE_MBX_IRQ0_LO);
3953}
3954