FreeBSD/sys/dev/bxe/bxe.c
/* report link status to OS, should be called under phy_lock */
report link status to OS, should be called under phy_lock
report link status to OS should be called under phy_lock
static void
bxe_link_report_locked(struct bxe_softc *sc)
{
    struct bxe_link_report_data cur_data;
    if (IS_PF(sc) && !CHIP_IS_E1(sc)) {
        bxe_read_mf_cfg(sc);
    }
    bxe_fill_report_data(sc, &cur_data);
    if (!memcmp(&cur_data, &sc->last_reported_link, sizeof(cur_data)) ||
        (bxe_test_bit(BXE_LINK_REPORT_LINK_DOWN,
                      &sc->last_reported_link.link_report_flags) &&
         bxe_test_bit(BXE_LINK_REPORT_LINK_DOWN,
                      &cur_data.link_report_flags))) {
        return;
    }
    sc->link_cnt++;
    memcpy(&sc->last_reported_link, &cur_data, sizeof(cur_data));
    if (bxe_test_bit(BXE_LINK_REPORT_LINK_DOWN,
                     &cur_data.link_report_flags)) {
        if_link_state_change(sc->ifp, LINK_STATE_DOWN);
        BLOGI(sc, "NIC Link is Down\n");
    } else {
        const char *duplex;
        const char *flow;
        if (bxe_test_and_clear_bit(BXE_LINK_REPORT_FULL_DUPLEX,
                                   &cur_data.link_report_flags)) {
            duplex = "full";
        } else {
            duplex = "half";
        }
        if (cur_data.link_report_flags) {
            if (bxe_test_bit(BXE_LINK_REPORT_RX_FC_ON,
                             &cur_data.link_report_flags) &&
                bxe_test_bit(BXE_LINK_REPORT_TX_FC_ON,
                             &cur_data.link_report_flags)) {
                flow = "ON - receive & transmit";
            } else if (bxe_test_bit(BXE_LINK_REPORT_RX_FC_ON,
                                    &cur_data.link_report_flags) &&
                       !bxe_test_bit(BXE_LINK_REPORT_TX_FC_ON,
                                     &cur_data.link_report_flags)) {
                flow = "ON - receive";
            } else if (!bxe_test_bit(BXE_LINK_REPORT_RX_FC_ON,
                                     &cur_data.link_report_flags) &&
                       bxe_test_bit(BXE_LINK_REPORT_TX_FC_ON,
                                    &cur_data.link_report_flags)) {
                flow = "ON - transmit";
            } else {
                flow = "none"; 
            }
        } else {
            flow = "none";
        }
        if_link_state_change(sc->ifp, LINK_STATE_UP);
        BLOGI(sc, "NIC Link is Up, %d Mbps %s duplex, Flow control: %s\n",
              cur_data.line_speed, duplex, flow);
    }
}
static void bxe_link_report_locked ( struct bxe_softc * sc ) { struct bxe_link_report_data cur_data ; if ( IS_PF ( sc ) && ! CHIP_IS_E1 ( sc ) ) { bxe_read_mf_cfg ( sc ) ; } bxe_fill_report_data ( sc , & cur_data ) ; if ( ! memcmp ( & cur_data , & sc -> last_reported_link , sizeof ( cur_data ) ) || ( bxe_test_bit ( BXE_LINK_REPORT_LINK_DOWN , & sc -> last_reported_link . link_report_flags ) && bxe_test_bit ( BXE_LINK_REPORT_LINK_DOWN , & cur_data . link_report_flags ) ) ) { return ; } sc -> link_cnt ++ ; memcpy ( & sc -> last_reported_link , & cur_data , sizeof ( cur_data ) ) ; if ( bxe_test_bit ( BXE_LINK_REPORT_LINK_DOWN , & cur_data . link_report_flags ) ) { if_link_state_change ( sc -> ifp , LINK_STATE_DOWN ) ; BLOGI ( sc , " \n " ) ; } else { const char * duplex ; const char * flow ; if ( bxe_test_and_clear_bit ( BXE_LINK_REPORT_FULL_DUPLEX , & cur_data . link_report_flags ) ) { duplex = " " ; } else { duplex = " " ; } if ( cur_data . link_report_flags ) { if ( bxe_test_bit ( BXE_LINK_REPORT_RX_FC_ON , & cur_data . link_report_flags ) && bxe_test_bit ( BXE_LINK_REPORT_TX_FC_ON , & cur_data . link_report_flags ) ) { flow = " " ; } else if ( bxe_test_bit ( BXE_LINK_REPORT_RX_FC_ON , & cur_data . link_report_flags ) && ! bxe_test_bit ( BXE_LINK_REPORT_TX_FC_ON , & cur_data . link_report_flags ) ) { flow = " " ; } else if ( ! bxe_test_bit ( BXE_LINK_REPORT_RX_FC_ON , & cur_data . link_report_flags ) && bxe_test_bit ( BXE_LINK_REPORT_TX_FC_ON , & cur_data . link_report_flags ) ) { flow = " " ; } else { flow = " " ; } } else { flow = " " ; } if_link_state_change ( sc -> ifp , LINK_STATE_UP ) ; BLOGI ( sc , " \n " , cur_data . line_speed , duplex , flow ) ; } }
report link status to OS, should be called under phy_lock
report link status to OS should be called under phy_lock
/* reread mf_cfg */ /* Read the current link report info */ /* Don't report link down or exactly the same link status twice */ /* report new link params and remember the state for the next time */ /*
         * Handle the FC at the end so that only these flags would be
         * possibly set. This way we may easily check if there is no FC
         * enabled.
         */ /* possible? */