/* ** Parse an integer ** decimal/hexa/octal/binary ** hexa is case insensitive */ t_bool ft_parsenumber(t_buff *buff, t_ulong *nb) { if (BIS(buff, '0')) { if (BIS(buff, 'x')) return (ft_parsebasei(buff, BASE_16, nb)); else if (BIS(buff, 'b')) return (ft_parsebase(buff, BASE_2, nb)); return (ft_parsebase(buff, BASE_8, nb)); } return (ft_parsebase(buff, BASE_10, nb)); }
/* * Bare-minimum autoneg protocol * * This code is only called when the link is up and we're receiving config * words, which implies that the link partner wants to autonegotiate * (otherwise, we wouldn't see configs and wouldn't reach this code). */ static void bge_autoneg_serdes(bge_t *bgep) { boolean_t ack; bgep->serdes_lpadv = bge_reg_get32(bgep, RX_1000BASEX_AUTONEG_REG); ack = BIS(bgep->serdes_lpadv, AUTONEG_CODE_ACKNOWLEDGE); if (!ack) { /* * Phase 1: after SerDes reset, we send a few zero configs * but then stop. Here the partner is sending configs, but * not ACKing ours; we assume that's 'cos we're not sending * any. So here we send ours, with ACK already set. */ bge_reg_put32(bgep, TX_1000BASEX_AUTONEG_REG, bgep->serdes_advert | AUTONEG_CODE_ACKNOWLEDGE); bge_reg_set32(bgep, ETHERNET_MAC_MODE_REG, ETHERNET_MODE_SEND_CFGS); } else { /* * Phase 2: partner has ACKed our configs, so now we can * stop sending; once our partner also stops sending, we * can resolve the Tx/Rx configs. */ bge_reg_clr32(bgep, ETHERNET_MAC_MODE_REG, ETHERNET_MODE_SEND_CFGS); } BGE_DEBUG(("bge_autoneg_serdes: Rx 0x%x %s Tx 0x%x", bgep->serdes_lpadv, ack ? "stop" : "send", bgep->serdes_advert)); }
/** * load BAM file header of file named filename * * @param filename BAM file name * @return header object from BAM file **/ static libmaus2::bambam::BamHeader::unique_ptr_type loadHeader(std::string const & filename) { libmaus2::aio::InputStream::unique_ptr_type Pistr(libmaus2::aio::InputStreamFactoryContainer::constructUnique(filename)); std::istream & CIS = *Pistr; libmaus2::lz::BgzfInflateStream BIS(CIS); libmaus2::bambam::BamHeader::unique_ptr_type Pheader(new libmaus2::bambam::BamHeader(BIS)); return UNIQUE_PTR_MOVE(Pheader); }
static boolean_t bge_check_copper(bge_t *bgep, boolean_t recheck) { uint32_t emac_status; uint16_t mii_status; uint16_t aux; uint_t mode; boolean_t linkup; /* * Step 10: read the status from the PHY (which is self-clearing * on read!); also read & clear the main (Ethernet) MAC status * (the relevant bits of this are write-one-to-clear). */ mii_status = bge_mii_get16(bgep, MII_STATUS); emac_status = bge_reg_get32(bgep, ETHERNET_MAC_STATUS_REG); bge_reg_put32(bgep, ETHERNET_MAC_STATUS_REG, emac_status); BGE_DEBUG(("bge_check_copper: link %d/%s, MII status 0x%x " "(was 0x%x), Ethernet MAC status 0x%x", bgep->link_state, UPORDOWN(bgep->param_link_up), mii_status, bgep->phy_gen_status, emac_status)); /* * If the PHY status hasn't changed since last we looked, and * we not forcing a recheck (i.e. the link state was already * known), there's nothing to do. */ if (mii_status == bgep->phy_gen_status && !recheck) return (B_FALSE); do { /* * Step 11: read AUX STATUS register to find speed/duplex */ aux = bge_mii_get16(bgep, MII_AUX_STATUS); BGE_CDB(bge_phydump, (bgep, mii_status, aux)); /* * We will only consider the link UP if all the readings * are consistent and give meaningful results ... */ mode = aux & MII_AUX_STATUS_MODE_MASK; mode >>= MII_AUX_STATUS_MODE_SHIFT; if (DEVICE_5906_SERIES_CHIPSETS(bgep)) { linkup = BIS(aux, MII_AUX_STATUS_LINKUP); linkup &= BIS(mii_status, MII_STATUS_LINKUP); } else { linkup = bge_copper_link_speed[mode] > 0; linkup &= bge_copper_link_duplex[mode] != LINK_DUPLEX_UNKNOWN; linkup &= BIS(aux, MII_AUX_STATUS_LINKUP); linkup &= BIS(mii_status, MII_STATUS_LINKUP); } BGE_DEBUG(("bge_check_copper: MII status 0x%x aux 0x%x " "=> mode %d (%s)", mii_status, aux, mode, UPORDOWN(linkup))); /* * Record current register values, then reread status * register & loop until it stabilises ... */ bgep->phy_aux_status = aux; bgep->phy_gen_status = mii_status; mii_status = bge_mii_get16(bgep, MII_STATUS); } while (mii_status != bgep->phy_gen_status); /* * Assume very little ... */ bgep->param_lp_autoneg = B_FALSE; bgep->param_lp_1000fdx = B_FALSE; bgep->param_lp_1000hdx = B_FALSE; bgep->param_lp_100fdx = B_FALSE; bgep->param_lp_100hdx = B_FALSE; bgep->param_lp_10fdx = B_FALSE; bgep->param_lp_10hdx = B_FALSE; bgep->param_lp_pause = B_FALSE; bgep->param_lp_asym_pause = B_FALSE; bgep->param_link_autoneg = B_FALSE; bgep->param_link_tx_pause = B_FALSE; if (bgep->param_adv_autoneg) bgep->param_link_rx_pause = B_FALSE; else bgep->param_link_rx_pause = bgep->param_adv_pause; /* * Discover all the link partner's abilities. * These are scattered through various registers ... */ if (BIS(aux, MII_AUX_STATUS_LP_ANEG_ABLE)) { bgep->param_lp_autoneg = B_TRUE; bgep->param_link_autoneg = B_TRUE; bgep->param_link_tx_pause = BIS(aux, MII_AUX_STATUS_TX_PAUSE); bgep->param_link_rx_pause = BIS(aux, MII_AUX_STATUS_RX_PAUSE); aux = bge_mii_get16(bgep, MII_MSSTATUS); bgep->param_lp_1000fdx = BIS(aux, MII_MSSTATUS_LP1000T_FD); bgep->param_lp_1000hdx = BIS(aux, MII_MSSTATUS_LP1000T); aux = bge_mii_get16(bgep, MII_AN_LPABLE); bgep->param_lp_100fdx = BIS(aux, MII_ABILITY_100BASE_TX_FD); bgep->param_lp_100hdx = BIS(aux, MII_ABILITY_100BASE_TX); bgep->param_lp_10fdx = BIS(aux, MII_ABILITY_10BASE_T_FD); bgep->param_lp_10hdx = BIS(aux, MII_ABILITY_10BASE_T); bgep->param_lp_pause = BIS(aux, MII_ABILITY_PAUSE); bgep->param_lp_asym_pause = BIS(aux, MII_ABILITY_ASMPAUSE); } /* * Step 12: update ndd-visible state parameters, BUT! * we don't transfer the new state to <link_state> just yet; * instead we mark the <link_state> as UNKNOWN, and our caller * will resolve it once the status has stopped changing and * been stable for several seconds. */ BGE_DEBUG(("bge_check_copper: link was %s speed %d duplex %d", UPORDOWN(bgep->param_link_up), bgep->param_link_speed, bgep->param_link_duplex)); if (!linkup) mode = MII_AUX_STATUS_MODE_NONE; bgep->param_link_up = linkup; bgep->link_state = LINK_STATE_UNKNOWN; if (DEVICE_5906_SERIES_CHIPSETS(bgep)) { if (bgep->phy_aux_status & MII_AUX_STATUS_NEG_ENABLED_5906) { bgep->param_link_speed = bge_copper_link_speed_5906[mode]; bgep->param_link_duplex = bge_copper_link_duplex_5906[mode]; } else { bgep->param_link_speed = (bgep->phy_aux_status & MII_AUX_STATUS_SPEED_IND_5906) ? 100 : 10; bgep->param_link_duplex = (bgep->phy_aux_status & MII_AUX_STATUS_DUPLEX_IND_5906) ? LINK_DUPLEX_FULL : LINK_DUPLEX_HALF; } } else { bgep->param_link_speed = bge_copper_link_speed[mode]; bgep->param_link_duplex = bge_copper_link_duplex[mode]; } BGE_DEBUG(("bge_check_copper: link now %s speed %d duplex %d", UPORDOWN(bgep->param_link_up), bgep->param_link_speed, bgep->param_link_duplex)); return (B_TRUE); }
static boolean_t bge_check_serdes(bge_t *bgep, boolean_t recheck) { uint32_t emac_status; uint32_t tx_status; uint32_t lpadv; boolean_t linkup; boolean_t linkup_old = bgep->param_link_up; for (;;) { /* * Step 10: BCM5714S, BCM5715S only * Don't call function bge_autoneg_serdes() as * RX_1000BASEX_AUTONEG_REG (0x0448) is not applicable * to BCM5705, BCM5788, BCM5721, BCM5751, BCM5752, * BCM5714, and BCM5715 devices. */ if (DEVICE_5714_SERIES_CHIPSETS(bgep)) { tx_status = bge_reg_get32(bgep, TRANSMIT_MAC_STATUS_REG); linkup = BIS(tx_status, TRANSMIT_STATUS_LINK_UP); emac_status = bge_reg_get32(bgep, ETHERNET_MAC_STATUS_REG); bgep->serdes_status = emac_status; if ((linkup && linkup_old) || (!linkup && !linkup_old)) { emac_status &= ~ETHERNET_STATUS_LINK_CHANGED; emac_status &= ~ETHERNET_STATUS_RECEIVING_CFG; break; } emac_status |= ETHERNET_STATUS_LINK_CHANGED; emac_status |= ETHERNET_STATUS_RECEIVING_CFG; if (linkup) linkup_old = B_TRUE; else linkup_old = B_FALSE; recheck = B_TRUE; } else { /* * Step 10: others * read & clear the main (Ethernet) MAC status * (the relevant bits of this are write-one-to-clear). */ emac_status = bge_reg_get32(bgep, ETHERNET_MAC_STATUS_REG); bge_reg_put32(bgep, ETHERNET_MAC_STATUS_REG, emac_status); BGE_DEBUG(("bge_check_serdes: link %d/%s, " "MAC status 0x%x (was 0x%x)", bgep->link_state, UPORDOWN(bgep->param_link_up), emac_status, bgep->serdes_status)); /* * We will only consider the link UP if all the readings * are consistent and give meaningful results ... */ bgep->serdes_status = emac_status; linkup = BIS(emac_status, ETHERNET_STATUS_SIGNAL_DETECT); linkup &= BIS(emac_status, ETHERNET_STATUS_PCS_SYNCHED); /* * Now some fiddling with the interpretation: * if there's been an error at the PCS level, treat * it as a link change (the h/w doesn't do this) * * if there's been a change, but it's only a PCS * sync change (not a config change), AND the link * already was & is still UP, then ignore the * change */ if (BIS(emac_status, ETHERNET_STATUS_PCS_ERROR)) emac_status |= ETHERNET_STATUS_LINK_CHANGED; else if (BIC(emac_status, ETHERNET_STATUS_CFG_CHANGED)) if (bgep->param_link_up && linkup) emac_status &= ~ETHERNET_STATUS_LINK_CHANGED; BGE_DEBUG(("bge_check_serdes: status 0x%x => 0x%x %s", bgep->serdes_status, emac_status, UPORDOWN(linkup))); /* * If we're receiving configs, run the autoneg protocol */ if (linkup && BIS(emac_status, ETHERNET_STATUS_RECEIVING_CFG)) bge_autoneg_serdes(bgep); /* * If the SerDes status hasn't changed, we're done ... */ if (BIC(emac_status, ETHERNET_STATUS_LINK_CHANGED)) break; /* * Go round again until we no longer see a change ... */ recheck = B_TRUE; } } /* * If we're not forcing a recheck (i.e. the link state was already * known), and we didn't see the hardware flag a change, there's * no more to do (and we tell the caller nothing happened). */ if (!recheck) return (B_FALSE); /* * Don't resolve autoneg until we're no longer receiving configs */ if (linkup && BIS(emac_status, ETHERNET_STATUS_RECEIVING_CFG)) return (B_FALSE); /* * Assume very little ... */ bgep->param_lp_autoneg = B_FALSE; bgep->param_lp_1000fdx = B_FALSE; bgep->param_lp_1000hdx = B_FALSE; bgep->param_lp_100fdx = B_FALSE; bgep->param_lp_100hdx = B_FALSE; bgep->param_lp_10fdx = B_FALSE; bgep->param_lp_10hdx = B_FALSE; bgep->param_lp_pause = B_FALSE; bgep->param_lp_asym_pause = B_FALSE; bgep->param_link_autoneg = B_FALSE; bgep->param_link_tx_pause = B_FALSE; if (bgep->param_adv_autoneg) bgep->param_link_rx_pause = B_FALSE; else bgep->param_link_rx_pause = bgep->param_adv_pause; /* * Discover all the link partner's abilities. */ lpadv = bgep->serdes_lpadv; if (lpadv != 0 && BIC(lpadv, AUTONEG_CODE_FAULT_MASK)) { /* * No fault, so derive partner's capabilities */ bgep->param_lp_autoneg = B_TRUE; bgep->param_lp_1000fdx = BIS(lpadv, AUTONEG_CODE_FULL_DUPLEX); bgep->param_lp_1000hdx = BIS(lpadv, AUTONEG_CODE_HALF_DUPLEX); bgep->param_lp_pause = BIS(lpadv, AUTONEG_CODE_PAUSE); bgep->param_lp_asym_pause = BIS(lpadv, AUTONEG_CODE_ASYM_PAUSE); /* * Pause direction resolution */ bgep->param_link_autoneg = B_TRUE; if (bgep->param_adv_pause && bgep->param_lp_pause) { bgep->param_link_tx_pause = B_TRUE; bgep->param_link_rx_pause = B_TRUE; } if (bgep->param_adv_asym_pause && bgep->param_lp_asym_pause) { if (bgep->param_adv_pause) bgep->param_link_rx_pause = B_TRUE; if (bgep->param_lp_pause) bgep->param_link_tx_pause = B_TRUE; } } /* * Step 12: update ndd-visible state parameters, BUT! * we don't transfer the new state to <link_state> just yet; * instead we mark the <link_state> as UNKNOWN, and our caller * will resolve it once the status has stopped changing and * been stable for several seconds. */ BGE_DEBUG(("bge_check_serdes: link was %s speed %d duplex %d", UPORDOWN(bgep->param_link_up), bgep->param_link_speed, bgep->param_link_duplex)); if (linkup) { bgep->param_link_up = B_TRUE; bgep->param_link_speed = 1000; if (bgep->param_adv_1000fdx) bgep->param_link_duplex = LINK_DUPLEX_FULL; else bgep->param_link_duplex = LINK_DUPLEX_HALF; if (bgep->param_lp_autoneg && !bgep->param_lp_1000fdx) bgep->param_link_duplex = LINK_DUPLEX_HALF; } else { bgep->param_link_up = B_FALSE; bgep->param_link_speed = 0; bgep->param_link_duplex = LINK_DUPLEX_UNKNOWN; } bgep->link_state = LINK_STATE_UNKNOWN; BGE_DEBUG(("bge_check_serdes: link now %s speed %d duplex %d", UPORDOWN(bgep->param_link_up), bgep->param_link_speed, bgep->param_link_duplex)); return (B_TRUE); }