Ticket #1590: against-28608.diff

File against-28608.diff, 9.4 KB (added by Adek336, 15 years ago)

BCM5906M works well with this patch

  • build/jam/HaikuImage

     
    142142    $(X86_ONLY)via_rhine wb840 $(X86_ONLY)ipro100 $(X86_ONLY)nforce
    143143    #vlance
    144144    $(X86_ONLY)marvell_yukon $(X86_ONLY)syskonnect usb_ecm
    145     $(GPL_ONLY)bcm570x
     145    broadcom570x
    146146;
    147147#BEOS_ADD_ONS_DRIVERS_ACPI = $(X86_ONLY)acpi_button ;
    148148BEOS_ADD_ONS_BUS_MANAGERS = pci $(X86_ONLY)ps2 $(X86_ONLY)isa ide scsi
  • src/add-ons/kernel/drivers/network/broadcom570x/dev/bge/if_bgereg.h

     
    25782578#ifdef DEVICE_POLLING
    25792579    int         rxcycles;
    25802580#endif /* DEVICE_POLLING */
     2581    u_int32_t       bge_intr_status;
     2582    int         bge_transmitting;
    25812583};
    25822584
    25832585#define BGE_LOCK_INIT(_sc, _name) \
  • src/add-ons/kernel/drivers/network/broadcom570x/dev/bge/if_bge.c

     
    398398static void bge_sig_legacy(struct bge_softc *, int);
    399399static void bge_sig_pre_reset(struct bge_softc *, int);
    400400static int bge_reset(struct bge_softc *);
    401 static void bge_link_upd(struct bge_softc *);
     401/*static*/ void bge_link_upd(struct bge_softc *);
    402402
    403403/*
    404404 * The BGE_REGISTER_DEBUG option is only for low-level debugging.  It may
     
    23612361
    23622362    sc = device_get_softc(dev);
    23632363    sc->bge_dev = dev;
     2364    sc->bge_transmitting = 0;
    23642365
    23652366    /*
    23662367     * Map control/status registers.
     
    30263027        sc->bge_ldata.bge_status_block->bge_idx[0].bge_rx_prod_idx)
    30273028        return;
    30283029
     3030    dprintf("bge_rxeof\n");
     3031
    30293032    ifp = sc->bge_ifp;
    30303033
    30313034    bus_dmamap_sync(sc->bge_cdata.bge_rx_return_ring_tag,
     
    31943197        sc->bge_ldata.bge_status_block->bge_idx[0].bge_tx_cons_idx)
    31953198        return;
    31963199
     3200    dprintf("bge_txeof\n");
     3201
    31973202    ifp = sc->bge_ifp;
    31983203
    31993204    bus_dmamap_sync(sc->bge_cdata.bge_tx_ring_tag,
     
    32813286
    32823287    sc = xsc;
    32833288
     3289    dprintf("bge_intr, sc->bge_intr_status=0x%x\n", sc->bge_intr_status);
     3290
    32843291    BGE_LOCK(sc);
    32853292
    32863293    ifp = sc->bge_ifp;
     
    33123319     * the status check).  So toggling would probably be a pessimization
    33133320     * even with MSI.  It would only be needed for using a task queue.
    33143321     */
     3322#ifndef __HAIKU__
    33153323    bge_writembx(sc, BGE_MBX_IRQ0_LO, 0);
     3324#endif
    33163325
    33173326    /*
    33183327     * Do the mandatory PCI flush as well as get the link status.
    33193328     */
    3320     statusword = CSR_READ_4(sc, BGE_MAC_STS) & BGE_MACSTAT_LINK_CHANGED;
     3329#ifdef __HAIKU__
     3330        /* Get the statusword as saved in __haiku_disable_interrupts
     3331         * and clear the saved value */
     3332        statusword = atomic_and((int32 *)&sc->bge_intr_status, 0) & BGE_MACSTAT_LINK_CHANGED;
     3333#else
     3334        statusword = CSR_READ_4(sc, BGE_MAC_STS) & BGE_MACSTAT_LINK_CHANGED;
     3335#endif
    33213336
    33223337    /* Make sure the descriptor ring indexes are coherent. */
    33233338    bus_dmamap_sync(sc->bge_cdata.bge_status_tag,
     
    33253340    bus_dmamap_sync(sc->bge_cdata.bge_status_tag,
    33263341        sc->bge_cdata.bge_status_map, BUS_DMASYNC_PREREAD);
    33273342
    3328     if ((sc->bge_asicrev == BGE_ASICREV_BCM5700 &&
    3329         sc->bge_chipid != BGE_CHIPID_BCM5700_B2) ||
    3330         statusword || sc->bge_link_evt)
    3331         bge_link_upd(sc);
     3343        /* TODO: bge_link_upd is probably not correct with interrupt changes
     3344         * May need to also use the saved statusword... */
     3345//FIXME: moved to glue.c, probably safe to remove
     3346    //if ((sc->bge_asicrev == BGE_ASICREV_BCM5700 &&
     3347    //    sc->bge_chipid != BGE_CHIPID_BCM5700_B2) ||
     3348    //    statusword || sc->bge_link_evt)
     3349    //  bge_link_upd(sc);
    33323350
    33333351    if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
    33343352        /* Check RX return ring producer/consumer. */
     
    36343652
    36353653    sc = ifp->if_softc;
    36363654
    3637     if (!sc->bge_link || IFQ_DRV_IS_EMPTY(&ifp->if_snd))
     3655//FIXME: sc->bge_link isn't being properly set in bge_link_upd
     3656    //if (!sc->bge_link || IFQ_DRV_IS_EMPTY(&ifp->if_snd))
     3657    if (IFQ_DRV_IS_EMPTY(&ifp->if_snd))
    36383658        return;
    36393659
    36403660    prodidx = sc->bge_tx_prodidx;
     
    36963716        /* No packets were dequeued. */
    36973717        return;
    36983718
     3719    sc -> bge_transmitting = 1;
    36993720    /* Transmit. */
    37003721    bge_writembx(sc, BGE_MBX_TX_HOST_PROD0_LO, prodidx);
    37013722    /* 5700 b2 errata */
     
    42534275         */
    42544276        if (mii != NULL) {
    42554277            ifm = mii->mii_media.ifm_cur;
     4278            if (ifm == NULL)
     4279            {
     4280                panic("bge_stop: ifm == NULL");
     4281                return ;
     4282            }
    42564283            mtmp = ifm->ifm_media;
    42574284            ifm->ifm_media = IFM_ETHER | IFM_NONE;
    42584285            mii_mediachg(mii);
     
    43204347    return (0);
    43214348}
    43224349
    4323 static void
     4350/*static*/ void
    43244351bge_link_upd(struct bge_softc *sc)
    43254352{
    43264353    struct mii_data *mii;
     
    44024429         * in status word always set. Workaround this bug by reading
    44034430         * PHY link status directly.
    44044431         */
     4432#define lnDbg do {printf("%s: %s: %d\n", __FILE__,__func__, __LINE__); } while(0)
     4433        lnDbg;
     4434        printf("bge: bge\n");
    44054435        link = (CSR_READ_4(sc, BGE_MI_STS) & BGE_MISTS_LINK) ? 1 : 0;
    44064436
    44074437        if (link != sc->bge_link ||
    44084438            sc->bge_asicrev == BGE_ASICREV_BCM5700) {
     4439        lnDbg;
    44094440            mii = device_get_softc(sc->bge_miibus);
    44104441            mii_pollstat(mii);
    44114442            if (!sc->bge_link &&
    44124443                mii->mii_media_status & IFM_ACTIVE &&
    44134444                IFM_SUBTYPE(mii->mii_media_active) != IFM_NONE) {
     4445        lnDbg;
    44144446                sc->bge_link++;
    44154447                if (bootverbose)
    44164448                    if_printf(sc->bge_ifp, "link UP\n");
     
    44334465    CSR_WRITE_4(sc, BGE_MAC_STS, BGE_MACSTAT_SYNC_CHANGED |
    44344466        BGE_MACSTAT_CFG_CHANGED | BGE_MACSTAT_MI_COMPLETE |
    44354467        BGE_MACSTAT_LINK_CHANGED);
     4468
     4469    dprintf("bge_link_upd, sc->bge_link=0x%x\n", sc->bge_link);
    44364470}
    44374471
    44384472#define BGE_SYSCTL_STAT(sc, ctx, desc, parent, node, oid) \
  • src/add-ons/kernel/drivers/network/broadcom570x/dev/bge/glue.c

     
    2828    return __haiku_probe_miibus(dev, drivers);
    2929}
    3030
     31int
     32__haiku_disable_interrupts(device_t dev)
     33{
     34        struct bge_softc *sc = device_get_softc(dev);
     35 
     36        // Obtain the status and return 0 if the bge did not set the intr
     37        u_int32_t status = CSR_READ_4(sc, BGE_MAC_STS);
     38    // status & 0x1000 for media change, sc->transmitting if sending a packet
     39    // use BGE_PCI_PCISTATE to check interrupt source like in the Linux driver
     40    if ( ((status & 0x1000)==0)&&(sc->bge_transmitting==0) && ((pci_read_config(sc->bge_dev, BGE_PCI_PCISTATE,4) & BGE_PCISTATE_INTR_STATE) != 0)) {
     41                return 0;
     42        }
     43    sc->bge_transmitting=0;
     44 
     45        // Clear the interrupt, the bge intr handler will take care of it
     46        BGE_SETBIT(sc, BGE_PCI_MISC_CTL, BGE_PCIMISCCTL_MASK_PCI_INTR);
     47        bge_writembx(sc, BGE_MBX_IRQ0_LO, 1);
     48 
     49        // save the status for the interrupt handler
     50        atomic_or((int32 *)&sc->bge_intr_status, status);
     51// ***
     52    if ((sc->bge_asicrev == BGE_ASICREV_BCM5700 &&
     53        sc->bge_chipid != BGE_CHIPID_BCM5700_B2) ||
     54        (status&0x1000) || sc->bge_link_evt)
     55        bge_link_upd(sc);
     56// ***
     57        return 1;
     58}
     59//int
     60//__haiku_disable_interrupts(device_t dev)
     61//{
     62//  struct bge_softc *sc = device_get_softc(dev);
     63//
     64//  uint32 statusword = CSR_READ_4(sc, BGE_MAC_STS) & BGE_MACSTAT_LINK_CHANGED;
     65//
     66//  if ((sc->bge_ifp->if_drv_flags & IFF_DRV_RUNNING) == 0 && !statusword
     67//      && (pci_read_config(sc->bge_dev, BGE_PCI_PCISTATE,4) & BGE_PCISTATE_INTR_STATE))
     68//      return 0;
     69//
     70//  BGE_SETBIT(sc, BGE_PCI_MISC_CTL, BGE_PCIMISCCTL_MASK_PCI_INTR);
     71//  bge_writembx(sc, BGE_MBX_IRQ0_LO, 1);
     72//
     73//  return 1;
     74//}
     75 
    3176
    3277// copied from if_bge.c
    3378static void
     
    3984    CSR_WRITE_4(sc, off, val);
    4085}
    4186
    42 
    43 int
    44 __haiku_disable_interrupts(device_t dev)
     87void
     88__haiku_reenable_interrupts(device_t dev)
    4589{
    46     struct bge_softc *sc = device_get_softc(dev);
     90        struct bge_softc *sc = device_get_softc(dev);
     91        BGE_SETBIT(sc, BGE_PCI_MISC_CTL, BGE_PCIMISCCTL_CLEAR_INTA);
     92        BGE_CLRBIT(sc, BGE_PCI_MISC_CTL, BGE_PCIMISCCTL_MASK_PCI_INTR);
     93        bge_writembx(sc, BGE_MBX_IRQ0_LO, 0);
     94}
    4795
    48     uint32 statusword = CSR_READ_4(sc, BGE_MAC_STS) & BGE_MACSTAT_LINK_CHANGED;
    49 
    50     if ((sc->bge_ifp->if_drv_flags & IFF_DRV_RUNNING) == 0 && !statusword
    51         && (pci_read_config(sc->bge_dev, BGE_PCI_PCISTATE,4) & BGE_PCISTATE_INTR_STATE))
    52         return 0;
    53 
    54     BGE_SETBIT(sc, BGE_PCI_MISC_CTL, BGE_PCIMISCCTL_MASK_PCI_INTR);
    55     bge_writembx(sc, BGE_MBX_IRQ0_LO, 1);
    56 
    57     return 1;
    58 }
    59 
    60 
    61 void
    62 __haiku_reenable_interrupts(device_t dev)
    63 {
    64     struct bge_softc *sc = device_get_softc(dev);
    65     BGE_SETBIT(sc, BGE_PCI_MISC_CTL, BGE_PCIMISCCTL_CLEAR_INTA);
    66     BGE_CLRBIT(sc, BGE_PCI_MISC_CTL, BGE_PCIMISCCTL_MASK_PCI_INTR);
    67     bge_writembx(sc, BGE_MBX_IRQ0_LO, 0);
    68 }
  • src/libs/compat/freebsd_network/fbsd_mii_physubr.c

     
    510510    }
    511511
    512512    if (sc->mii_capabilities & BMSR_ANEG) {
    513         ADD(IFM_MAKEWORD(IFM_ETHER, IFM_AUTO, 0, sc->mii_inst),
    514             MII_NMEDIA);    /* intentionally invalid index */
     513        dprintf("don't know how to handle sc->mii_capabilities & BMSR_ANEG\n");
     514        //ADD(IFM_MAKEWORD(IFM_ETHER, IFM_AUTO, 0, sc->mii_inst),
     515            //MII_NMEDIA);  /* intentionally invalid index */
    515516        PRINT("auto");
    516517    }
    517518#undef ADD