/* * XXX: Poll a particular ring. The implementation is incomplete. * Once the ring interrupts are disabled, we need to do bge_recyle() * for the ring as well and re enable the ring interrupt automatically * if the poll doesn't find any packets in the ring. We need to * have MSI-X interrupts support for this. * * The basic poll policy is that rings that are dealing with explicit * flows (like TCP or some service) and are marked as such should * have their own MSI-X interrupt per ring. bge_intr() should leave * that interrupt disabled after an upcall. The ring is in poll mode. * When a poll thread comes down and finds nothing, the MSI-X interrupt * is automatically enabled. Squeue needs to deal with the race of * a new interrupt firing and reaching before poll thread returns. */ mblk_t * bge_poll_ring(void *arg, int bytes_to_pickup) { recv_ring_t *rrp = arg; bge_t *bgep = rrp->bgep; bge_rbd_t *hw_rbd_p; uint64_t slot; mblk_t *head; mblk_t **tail; mblk_t *mp; size_t sz = 0; mutex_enter(rrp->rx_lock); /* * Sync (all) the receive ring descriptors * before accepting the packets they describe */ DMA_SYNC(rrp->desc, DDI_DMA_SYNC_FORKERNEL); if (*rrp->prod_index_p >= rrp->desc.nslots) { bgep->bge_chip_state = BGE_CHIP_ERROR; bge_fm_ereport(bgep, DDI_FM_DEVICE_INVAL_STATE); mutex_exit(rrp->rx_lock); return (NULL); } if (bge_check_dma_handle(bgep, rrp->desc.dma_hdl) != DDI_FM_OK) { rrp->rx_next = *rrp->prod_index_p; bge_mbx_put(bgep, rrp->chip_mbx_reg, rrp->rx_next); bgep->bge_dma_error = B_TRUE; bgep->bge_chip_state = BGE_CHIP_ERROR; mutex_exit(rrp->rx_lock); return (NULL); } hw_rbd_p = DMA_VPTR(rrp->desc); head = NULL; tail = &head; slot = rrp->rx_next; /* Note: volatile */ while ((slot != *rrp->prod_index_p) && (sz <= bytes_to_pickup)) { if ((mp = bge_receive_packet(bgep, &hw_rbd_p[slot], rrp)) != NULL) { *tail = mp; sz += msgdsize(mp); tail = &mp->b_next; } rrp->rx_next = slot = NEXT(slot, rrp->desc.nslots); } bge_mbx_put(bgep, rrp->chip_mbx_reg, rrp->rx_next); if (bge_check_acc_handle(bgep, bgep->io_handle) != DDI_FM_OK) bgep->bge_chip_state = BGE_CHIP_ERROR; mutex_exit(rrp->rx_lock); return (head); }
/* * Reset the physical layer */ void bge_phys_reset(bge_t *bgep) { BGE_TRACE(("bge_phys_reset($%p)", (void *)bgep)); mutex_enter(bgep->genlock); if ((*bgep->physops->phys_restart)(bgep, B_FALSE) != DDI_SUCCESS) ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_UNAFFECTED); if (bge_check_acc_handle(bgep, bgep->io_handle) != DDI_FM_OK) ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_UNAFFECTED); mutex_exit(bgep->genlock); }
static mblk_t * bge_receive_ring(bge_t *bgep, recv_ring_t *rrp) { bge_rbd_t *hw_rbd_p; uint64_t slot; mblk_t *head; mblk_t **tail; mblk_t *mp; int recv_cnt = 0; ASSERT(mutex_owned(rrp->rx_lock)); /* * Sync (all) the receive ring descriptors * before accepting the packets they describe */ DMA_SYNC(rrp->desc, DDI_DMA_SYNC_FORKERNEL); if (*rrp->prod_index_p >= rrp->desc.nslots) { bgep->bge_chip_state = BGE_CHIP_ERROR; bge_fm_ereport(bgep, DDI_FM_DEVICE_INVAL_STATE); return (NULL); } if (bge_check_dma_handle(bgep, rrp->desc.dma_hdl) != DDI_FM_OK) { rrp->rx_next = *rrp->prod_index_p; bge_mbx_put(bgep, rrp->chip_mbx_reg, rrp->rx_next); bgep->bge_dma_error = B_TRUE; bgep->bge_chip_state = BGE_CHIP_ERROR; return (NULL); } hw_rbd_p = DMA_VPTR(rrp->desc); head = NULL; tail = &head; slot = rrp->rx_next; while ((slot != *rrp->prod_index_p) && /* Note: volatile */ (recv_cnt < BGE_MAXPKT_RCVED)) { if ((mp = bge_receive_packet(bgep, &hw_rbd_p[slot], rrp)) != NULL) { *tail = mp; tail = &mp->b_next; recv_cnt++; } rrp->rx_next = slot = NEXT(slot, rrp->desc.nslots); } bge_mbx_put(bgep, rrp->chip_mbx_reg, rrp->rx_next); if (bge_check_acc_handle(bgep, bgep->io_handle) != DDI_FM_OK) bgep->bge_chip_state = BGE_CHIP_ERROR; return (head); }
/* * Here we have to determine which media we're using (copper or serdes). * Once that's done, we can initialise the physical layer appropriately. */ int bge_phys_init(bge_t *bgep) { BGE_TRACE(("bge_phys_init($%p)", (void *)bgep)); mutex_enter(bgep->genlock); /* * Probe for the (internal) PHY. If it's not there, we'll assume * that this is a 5703/4S, with a SerDes interface rather than * a PHY. BCM5714S/BCM5715S are not supported.It are based on * BCM800x PHY. */ bgep->phy_mii_addr = 1; if (DEVICE_5717_SERIES_CHIPSETS(bgep)) { int regval = bge_reg_get32(bgep, CPMU_STATUS_REG); if (regval & CPMU_STATUS_FUN_NUM) bgep->phy_mii_addr += 1; regval = bge_reg_get32(bgep, SGMII_STATUS_REG); if (regval & MEDIA_SELECTION_MODE) bgep->phy_mii_addr += 7; } if (bge_phy_probe(bgep)) { bgep->chipid.flags &= ~CHIP_FLAG_SERDES; bgep->physops = &copper_ops; } else { bgep->chipid.flags |= CHIP_FLAG_SERDES; bgep->physops = &serdes_ops; } if ((*bgep->physops->phys_restart)(bgep, B_FALSE) != DDI_SUCCESS) { mutex_exit(bgep->genlock); return (EIO); } if (bge_check_acc_handle(bgep, bgep->io_handle) != DDI_FM_OK) { mutex_exit(bgep->genlock); return (EIO); } mutex_exit(bgep->genlock); return (0); }
int bge_m_stat(void *arg, uint_t stat, uint64_t *val) { bge_t *bgep = arg; bge_statistics_t *bstp; bge_statistics_reg_t *pstats; if (bgep->bge_chip_state != BGE_CHIP_RUNNING) { return (EINVAL); } if (bgep->chipid.statistic_type == BGE_STAT_BLK) bstp = DMA_VPTR(bgep->statistics); else { pstats = bgep->pstats; pstats->ifHCOutOctets += bge_reg_get32(bgep, STAT_IFHCOUT_OCTETS_REG); pstats->etherStatsCollisions += bge_reg_get32(bgep, STAT_ETHER_COLLIS_REG); pstats->outXonSent += bge_reg_get32(bgep, STAT_OUTXON_SENT_REG); pstats->outXoffSent += bge_reg_get32(bgep, STAT_OUTXOFF_SENT_REG); pstats->dot3StatsInternalMacTransmitErrors += bge_reg_get32(bgep, STAT_DOT3_INTMACTX_ERR_REG); pstats->dot3StatsSingleCollisionFrames += bge_reg_get32(bgep, STAT_DOT3_SCOLLI_FRAME_REG); pstats->dot3StatsMultipleCollisionFrames += bge_reg_get32(bgep, STAT_DOT3_MCOLLI_FRAME_REG); pstats->dot3StatsDeferredTransmissions += bge_reg_get32(bgep, STAT_DOT3_DEFERED_TX_REG); pstats->dot3StatsExcessiveCollisions += bge_reg_get32(bgep, STAT_DOT3_EXCE_COLLI_REG); pstats->dot3StatsLateCollisions += bge_reg_get32(bgep, STAT_DOT3_LATE_COLLI_REG); pstats->ifHCOutUcastPkts += bge_reg_get32(bgep, STAT_IFHCOUT_UPKGS_REG); pstats->ifHCOutMulticastPkts += bge_reg_get32(bgep, STAT_IFHCOUT_MPKGS_REG); pstats->ifHCOutBroadcastPkts += bge_reg_get32(bgep, STAT_IFHCOUT_BPKGS_REG); pstats->ifHCInOctets += bge_reg_get32(bgep, STAT_IFHCIN_OCTETS_REG); pstats->etherStatsFragments += bge_reg_get32(bgep, STAT_ETHER_FRAGMENT_REG); pstats->ifHCInUcastPkts += bge_reg_get32(bgep, STAT_IFHCIN_UPKGS_REG); pstats->ifHCInMulticastPkts += bge_reg_get32(bgep, STAT_IFHCIN_MPKGS_REG); pstats->ifHCInBroadcastPkts += bge_reg_get32(bgep, STAT_IFHCIN_BPKGS_REG); pstats->dot3StatsFCSErrors += bge_reg_get32(bgep, STAT_DOT3_FCS_ERR_REG); pstats->dot3StatsAlignmentErrors += bge_reg_get32(bgep, STAT_DOT3_ALIGN_ERR_REG); pstats->xonPauseFramesReceived += bge_reg_get32(bgep, STAT_XON_PAUSE_RX_REG); pstats->xoffPauseFramesReceived += bge_reg_get32(bgep, STAT_XOFF_PAUSE_RX_REG); pstats->macControlFramesReceived += bge_reg_get32(bgep, STAT_MAC_CTRL_RX_REG); pstats->xoffStateEntered += bge_reg_get32(bgep, STAT_XOFF_STATE_ENTER_REG); pstats->dot3StatsFrameTooLongs += bge_reg_get32(bgep, STAT_DOT3_FRAME_TOOLONG_REG); pstats->etherStatsJabbers += bge_reg_get32(bgep, STAT_ETHER_JABBERS_REG); pstats->etherStatsUndersizePkts += bge_reg_get32(bgep, STAT_ETHER_UNDERSIZE_REG); mutex_enter(bgep->genlock); if (bge_check_acc_handle(bgep, bgep->io_handle) != DDI_FM_OK) { ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_UNAFFECTED); } mutex_exit(bgep->genlock); } switch (stat) { case MAC_STAT_IFSPEED: *val = (bgep->link_state != LINK_STATE_UNKNOWN) ? (bgep->param_link_speed * 1000000ull) : 0; break; case MAC_STAT_MULTIRCV: if (bgep->chipid.statistic_type == BGE_STAT_BLK) *val = bstp->s.ifHCInMulticastPkts; else *val = pstats->ifHCInMulticastPkts; break; case MAC_STAT_BRDCSTRCV: if (bgep->chipid.statistic_type == BGE_STAT_BLK) *val = bstp->s.ifHCInBroadcastPkts; else *val = pstats->ifHCInBroadcastPkts; break; case MAC_STAT_MULTIXMT: if (bgep->chipid.statistic_type == BGE_STAT_BLK) *val = bstp->s.ifHCOutMulticastPkts; else *val = pstats->ifHCOutMulticastPkts; break; case MAC_STAT_BRDCSTXMT: if (bgep->chipid.statistic_type == BGE_STAT_BLK) *val = bstp->s.ifHCOutBroadcastPkts; else *val = pstats->ifHCOutBroadcastPkts; break; case MAC_STAT_NORCVBUF: if (bgep->chipid.statistic_type == BGE_STAT_BLK) *val = bstp->s.ifInDiscards; else *val = 0; break; case MAC_STAT_IERRORS: if (bgep->chipid.statistic_type == BGE_STAT_BLK) { *val = bstp->s.dot3StatsFCSErrors + bstp->s.dot3StatsAlignmentErrors + bstp->s.dot3StatsFrameTooLongs + bstp->s.etherStatsUndersizePkts + bstp->s.etherStatsJabbers; } else { *val = pstats->dot3StatsFCSErrors + pstats->dot3StatsAlignmentErrors + pstats->dot3StatsFrameTooLongs + pstats->etherStatsUndersizePkts + pstats->etherStatsJabbers; } break; case MAC_STAT_NOXMTBUF: if (bgep->chipid.statistic_type == BGE_STAT_BLK) *val = bstp->s.ifOutDiscards; else *val = 0; break; case MAC_STAT_OERRORS: if (bgep->chipid.statistic_type == BGE_STAT_BLK) *val = bstp->s.ifOutDiscards; else *val = 0; break; case MAC_STAT_COLLISIONS: if (bgep->chipid.statistic_type == BGE_STAT_BLK) *val = bstp->s.etherStatsCollisions; else *val = pstats->etherStatsCollisions; break; case MAC_STAT_RBYTES: if (bgep->chipid.statistic_type == BGE_STAT_BLK) *val = bstp->s.ifHCInOctets; else *val = pstats->ifHCInOctets; break; case MAC_STAT_IPACKETS: if (bgep->chipid.statistic_type == BGE_STAT_BLK) *val = bstp->s.ifHCInUcastPkts + bstp->s.ifHCInMulticastPkts + bstp->s.ifHCInBroadcastPkts; else *val = pstats->ifHCInUcastPkts + pstats->ifHCInMulticastPkts + pstats->ifHCInBroadcastPkts; break; case MAC_STAT_OBYTES: if (bgep->chipid.statistic_type == BGE_STAT_BLK) *val = bstp->s.ifHCOutOctets; else *val = pstats->ifHCOutOctets; break; case MAC_STAT_OPACKETS: if (bgep->chipid.statistic_type == BGE_STAT_BLK) *val = bstp->s.ifHCOutUcastPkts + bstp->s.ifHCOutMulticastPkts + bstp->s.ifHCOutBroadcastPkts; else *val = pstats->ifHCOutUcastPkts + pstats->ifHCOutMulticastPkts + pstats->ifHCOutBroadcastPkts; break; case ETHER_STAT_ALIGN_ERRORS: if (bgep->chipid.statistic_type == BGE_STAT_BLK) *val = bstp->s.dot3StatsAlignmentErrors; else *val = pstats->dot3StatsAlignmentErrors; break; case ETHER_STAT_FCS_ERRORS: if (bgep->chipid.statistic_type == BGE_STAT_BLK) *val = bstp->s.dot3StatsFCSErrors; else *val = pstats->dot3StatsFCSErrors; break; case ETHER_STAT_FIRST_COLLISIONS: if (bgep->chipid.statistic_type == BGE_STAT_BLK) *val = bstp->s.dot3StatsSingleCollisionFrames; else *val = pstats->dot3StatsSingleCollisionFrames; break; case ETHER_STAT_MULTI_COLLISIONS: if (bgep->chipid.statistic_type == BGE_STAT_BLK) *val = bstp->s.dot3StatsMultipleCollisionFrames; else *val = pstats->dot3StatsMultipleCollisionFrames; break; case ETHER_STAT_DEFER_XMTS: if (bgep->chipid.statistic_type == BGE_STAT_BLK) *val = bstp->s.dot3StatsDeferredTransmissions; else *val = pstats->dot3StatsDeferredTransmissions; break; case ETHER_STAT_TX_LATE_COLLISIONS: if (bgep->chipid.statistic_type == BGE_STAT_BLK) *val = bstp->s.dot3StatsLateCollisions; else *val = pstats->dot3StatsLateCollisions; break; case ETHER_STAT_EX_COLLISIONS: if (bgep->chipid.statistic_type == BGE_STAT_BLK) *val = bstp->s.dot3StatsExcessiveCollisions; else *val = pstats->dot3StatsExcessiveCollisions; break; case ETHER_STAT_MACXMT_ERRORS: if (bgep->chipid.statistic_type == BGE_STAT_BLK) *val = bstp->s.dot3StatsInternalMacTransmitErrors; else *val = bgep->pstats->dot3StatsInternalMacTransmitErrors; break; case ETHER_STAT_CARRIER_ERRORS: if (bgep->chipid.statistic_type == BGE_STAT_BLK) *val = bstp->s.dot3StatsCarrierSenseErrors; else *val = 0; break; case ETHER_STAT_TOOLONG_ERRORS: if (bgep->chipid.statistic_type == BGE_STAT_BLK) *val = bstp->s.dot3StatsFrameTooLongs; else *val = pstats->dot3StatsFrameTooLongs; break; #if (MAC_VERSION > 1) case ETHER_STAT_TOOSHORT_ERRORS: if (bgep->chipid.statistic_type == BGE_STAT_BLK) *val = bstp->s.etherStatsUndersizePkts; else *val = pstats->etherStatsUndersizePkts; break; #endif case ETHER_STAT_XCVR_ADDR: *val = bgep->phy_mii_addr; break; case ETHER_STAT_XCVR_ID: mutex_enter(bgep->genlock); *val = bge_mii_get16(bgep, MII_PHYIDH); *val <<= 16; *val |= bge_mii_get16(bgep, MII_PHYIDL); if (bge_check_acc_handle(bgep, bgep->io_handle) != DDI_FM_OK) { ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_UNAFFECTED); } mutex_exit(bgep->genlock); break; case ETHER_STAT_XCVR_INUSE: if (bgep->chipid.flags & CHIP_FLAG_SERDES) *val = XCVR_1000X; else *val = XCVR_1000T; break; case ETHER_STAT_CAP_1000FDX: *val = 1; break; case ETHER_STAT_CAP_1000HDX: *val = 1; break; case ETHER_STAT_CAP_100FDX: if (bgep->chipid.flags & CHIP_FLAG_SERDES) *val = 0; else *val = 1; break; case ETHER_STAT_CAP_100HDX: if (bgep->chipid.flags & CHIP_FLAG_SERDES) *val = 0; else *val = 1; break; case ETHER_STAT_CAP_10FDX: if (bgep->chipid.flags & CHIP_FLAG_SERDES) *val = 0; else *val = 1; break; case ETHER_STAT_CAP_10HDX: if (bgep->chipid.flags & CHIP_FLAG_SERDES) *val = 0; else *val = 1; break; case ETHER_STAT_CAP_ASMPAUSE: *val = 1; break; case ETHER_STAT_CAP_PAUSE: *val = 1; break; case ETHER_STAT_CAP_AUTONEG: *val = 1; break; #if (MAC_VERSION > 1) case ETHER_STAT_CAP_REMFAULT: *val = 1; break; #endif case ETHER_STAT_ADV_CAP_1000FDX: *val = bgep->param_adv_1000fdx; break; case ETHER_STAT_ADV_CAP_1000HDX: *val = bgep->param_adv_1000hdx; break; case ETHER_STAT_ADV_CAP_100FDX: *val = bgep->param_adv_100fdx; break; case ETHER_STAT_ADV_CAP_100HDX: *val = bgep->param_adv_100hdx; break; case ETHER_STAT_ADV_CAP_10FDX: *val = bgep->param_adv_10fdx; break; case ETHER_STAT_ADV_CAP_10HDX: *val = bgep->param_adv_10hdx; break; case ETHER_STAT_ADV_CAP_ASMPAUSE: *val = bgep->param_adv_asym_pause; break; case ETHER_STAT_ADV_CAP_PAUSE: *val = bgep->param_adv_pause; break; case ETHER_STAT_ADV_CAP_AUTONEG: *val = bgep->param_adv_autoneg; break; #if (MAC_VERSION > 1) case ETHER_STAT_ADV_REMFAULT: if (bgep->chipid.flags & CHIP_FLAG_SERDES) *val = 0; else { mutex_enter(bgep->genlock); *val = bge_mii_get16(bgep, MII_AN_ADVERT) & MII_AN_ADVERT_REMFAULT ? 1 : 0; if (bge_check_acc_handle(bgep, bgep->io_handle) != DDI_FM_OK) { ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_UNAFFECTED); } mutex_exit(bgep->genlock); } break; #endif case ETHER_STAT_LP_CAP_1000FDX: *val = bgep->param_lp_1000fdx; break; case ETHER_STAT_LP_CAP_1000HDX: *val = bgep->param_lp_1000hdx; break; case ETHER_STAT_LP_CAP_100FDX: *val = bgep->param_lp_100fdx; break; case ETHER_STAT_LP_CAP_100HDX: *val = bgep->param_lp_100hdx; break; case ETHER_STAT_LP_CAP_10FDX: *val = bgep->param_lp_10fdx; break; case ETHER_STAT_LP_CAP_10HDX: *val = bgep->param_lp_10hdx; break; case ETHER_STAT_LP_CAP_ASMPAUSE: *val = bgep->param_lp_asym_pause; break; case ETHER_STAT_LP_CAP_PAUSE: *val = bgep->param_lp_pause; break; case ETHER_STAT_LP_CAP_AUTONEG: *val = bgep->param_lp_autoneg; break; #if (MAC_VERSION > 1) case ETHER_STAT_LP_REMFAULT: if (bgep->chipid.flags & CHIP_FLAG_SERDES) *val = 0; else { mutex_enter(bgep->genlock); *val = bge_mii_get16(bgep, MII_AN_LPABLE) & MII_AN_ADVERT_REMFAULT ? 1 : 0; if (bge_check_acc_handle(bgep, bgep->io_handle) != DDI_FM_OK) { ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_UNAFFECTED); } mutex_exit(bgep->genlock); } break; #endif case ETHER_STAT_LINK_ASMPAUSE: *val = bgep->param_adv_asym_pause && bgep->param_lp_asym_pause && bgep->param_adv_pause != bgep->param_lp_pause; break; case ETHER_STAT_LINK_PAUSE: *val = bgep->param_link_rx_pause; break; case ETHER_STAT_LINK_AUTONEG: *val = bgep->param_link_autoneg; break; case ETHER_STAT_LINK_DUPLEX: *val = (bgep->link_state != LINK_STATE_UNKNOWN) ? bgep->param_link_duplex : LINK_DUPLEX_UNKNOWN; break; default: return (ENOTSUP); } return (0); }
static int bge_phydata_update(kstat_t *ksp, int flag) { bge_t *bgep; kstat_named_t *knp; const bge_ksindex_t *ksip; if (flag != KSTAT_READ) return (EACCES); bgep = ksp->ks_private; if (bgep->bge_chip_state == BGE_CHIP_FAULT) return (EIO); knp = ksp->ks_data; /* * Read the PHY registers & update the kstats ... * * We need to hold the mutex while performing MII reads, but * we don't want to hold it across the entire sequence of reads. * So we grab and release it on each iteration, 'cos it doesn't * really matter if the kstats are less than 100% consistent ... */ for (ksip = bge_phydata; ksip->name != NULL; ++knp, ++ksip) { mutex_enter(bgep->genlock); switch (ksip->index) { case MII_STATUS: knp->value.ui64 = bgep->phy_gen_status; break; case MII_PHYIDH: knp->value.ui64 = bge_mii_get16(bgep, MII_PHYIDH); knp->value.ui64 <<= 16; knp->value.ui64 |= bge_mii_get16(bgep, MII_PHYIDL); break; case EEE_MODE_REG: knp->value.ui64 = 0; if (bgep->link_state == LINK_STATE_UP) { knp->value.ui64 = (bge_reg_get32(bgep, EEE_MODE_REG) & 0x80) ? 1 : 0; } break; default: knp->value.ui64 = bge_mii_get16(bgep, ksip->index); break; } if (bge_check_acc_handle(bgep, bgep->io_handle) != DDI_FM_OK) { ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_DEGRADED); mutex_exit(bgep->genlock); return (EIO); } mutex_exit(bgep->genlock); } return (0); }
static int bge_driverinfo_update(kstat_t *ksp, int flag) { bge_t *bgep; kstat_named_t *knp; ddi_acc_handle_t handle; if (flag != KSTAT_READ) return (EACCES); bgep = ksp->ks_private; if (bgep->bge_chip_state == BGE_CHIP_FAULT) return (EIO); knp = ksp->ks_data; (knp++)->value.ui64 = bgep->rx_buff[0].cookie.dmac_laddress; (knp++)->value.ui64 = bgep->tx_buff[0].cookie.dmac_laddress; (knp++)->value.ui64 = bgep->rx_desc[0].cookie.dmac_laddress; (knp++)->value.ui64 = bgep->tx_desc.cookie.dmac_laddress; (knp++)->value.ui64 = bgep->send[0].tx_free; (knp++)->value.ui64 = bgep->send[0].tx_array; (knp++)->value.ui64 = bgep->send[0].tc_next; (knp++)->value.ui64 = bgep->send[0].tx_next; (knp++)->value.ui64 = bgep->send[0].txfill_next; (knp++)->value.ui64 = bgep->send[0].txpkt_next; (knp++)->value.ui64 = bgep->send[0].txbuf_pop_queue->count + bgep->send[0].txbuf_push_queue->count; (knp++)->value.ui64 = bgep->send[0].tx_flow; (knp++)->value.ui64 = bgep->tx_resched_needed; (knp++)->value.ui64 = bgep->tx_resched; (knp++)->value.ui64 = bgep->send[0].tx_nobuf; (knp++)->value.ui64 = bgep->send[0].tx_nobd; (knp++)->value.ui64 = bgep->send[0].tx_block; (knp++)->value.ui64 = bgep->send[0].tx_alloc_fail; (knp++)->value.ui64 = bgep->watchdog; (knp++)->value.ui64 = bgep->chip_resets; (knp++)->value.ui64 = bgep->missed_dmas; (knp++)->value.ui64 = bgep->missed_updates; /* * Hold the mutex while accessing the chip registers * just in case the factotum is trying to reset it! */ handle = bgep->cfg_handle; mutex_enter(bgep->genlock); (knp++)->value.ui64 = pci_config_get32(handle, PCI_CONF_BGE_MHCR); (knp++)->value.ui64 = pci_config_get32(handle, PCI_CONF_BGE_PDRWCR); (knp++)->value.ui64 = pci_config_get32(handle, PCI_CONF_BGE_PCISTATE); if (bge_check_acc_handle(bgep, bgep->cfg_handle) != DDI_FM_OK) { ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_DEGRADED); mutex_exit(bgep->genlock); return (EIO); } (knp++)->value.ui64 = bge_reg_get32(bgep, BUFFER_MANAGER_STATUS_REG); (knp++)->value.ui64 = bge_reg_get32(bgep, RCV_INITIATOR_STATUS_REG); if (bge_check_acc_handle(bgep, bgep->io_handle) != DDI_FM_OK) { ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_DEGRADED); mutex_exit(bgep->genlock); return (EIO); } mutex_exit(bgep->genlock); return (0); }