FreeBSD/sys/dev/bxe/bxe.c
/*
 * Device attach function.
 *
 * Allocates device resources, performs secondary chip identification, and
 * initializes driver instance variables. This function is called from driver
 * load after a successful probe.
 *
 * Returns:
 *   0 = Success, >0 = Failure
 */
Device attach function.
Allocates device resources, performs secondary chip identification, and
initializes driver instance variables. This function is called from driver
load after a successful probe.

0 = Success, >0 = Failure
Device attach function . Allocates device resources performs secondary chip identification and initializes driver instance variables . This function is called from driver load after a successful probe . 0 = Success > 0 = Failure
static int
bxe_attach(device_t dev)
{
    struct bxe_softc *sc;
    sc = device_get_softc(dev);
    BLOGD(sc, DBG_LOAD, "Starting attach...\n");
    sc->state = BXE_STATE_CLOSED;
    sc->dev  = dev;
    sc->unit = device_get_unit(dev);
    BLOGD(sc, DBG_LOAD, "softc = %p\n", sc);
    sc->pcie_bus    = pci_get_bus(dev);
    sc->pcie_device = pci_get_slot(dev);
    sc->pcie_func   = pci_get_function(dev);
    pci_enable_busmaster(dev);
    if (bxe_allocate_bars(sc) != 0) {
        return (ENXIO);
    }
    bxe_init_mutexes(sc);
    callout_init(&sc->periodic_callout, 0);
    sc->chip_tq_flags = CHIP_TQ_NONE;
    snprintf(sc->chip_tq_name, sizeof(sc->chip_tq_name),
             "bxe%d_chip_tq", sc->unit);
    TASK_INIT(&sc->chip_tq_task, 0, bxe_handle_chip_tq, sc);
    sc->chip_tq = taskqueue_create(sc->chip_tq_name, M_NOWAIT,
                                   taskqueue_thread_enqueue,
                                   &sc->chip_tq);
    taskqueue_start_threads(&sc->chip_tq, 1, PWAIT, 
                            "%s", sc->chip_tq_name);
    if (bxe_get_device_info(sc) != 0) {
        BLOGE(sc, "getting device info\n");
        bxe_deallocate_bars(sc);
        pci_disable_busmaster(dev);
        return (ENXIO);
    }
    bxe_get_params(sc);
    sc->mtu = ETHERMTU;
    bxe_set_modes_bitmap(sc);
    bxe_get_phy_info(sc);
    if (bxe_init_ifnet(sc) != 0) {
        bxe_release_mutexes(sc);
        bxe_deallocate_bars(sc);
        pci_disable_busmaster(dev);
        return (ENXIO);
    }
    if (bxe_add_cdev(sc) != 0) {
        if (sc->ifp != NULL) {
            ether_ifdetach(sc->ifp);
        }
        ifmedia_removeall(&sc->ifmedia);
        bxe_release_mutexes(sc);
        bxe_deallocate_bars(sc);
        pci_disable_busmaster(dev);
        return (ENXIO);
    }
    if (bxe_interrupt_alloc(sc) != 0) {
        bxe_del_cdev(sc);
        if (sc->ifp != NULL) {
            ether_ifdetach(sc->ifp);
        }
        ifmedia_removeall(&sc->ifmedia);
        bxe_release_mutexes(sc);
        bxe_deallocate_bars(sc);
        pci_disable_busmaster(dev);
        return (ENXIO);
    }
    bxe_init_fp_mutexs(sc);
    if (bxe_alloc_buf_rings(sc) != 0) {
	bxe_free_buf_rings(sc);
        bxe_interrupt_free(sc);
        bxe_del_cdev(sc);
        if (sc->ifp != NULL) {
            ether_ifdetach(sc->ifp);
        }
        ifmedia_removeall(&sc->ifmedia);
        bxe_release_mutexes(sc);
        bxe_deallocate_bars(sc);
        pci_disable_busmaster(dev);
        return (ENXIO);
    }
    if (bxe_alloc_ilt_mem(sc) != 0) {
	bxe_free_buf_rings(sc);
        bxe_interrupt_free(sc);
        bxe_del_cdev(sc);
        if (sc->ifp != NULL) {
            ether_ifdetach(sc->ifp);
        }
        ifmedia_removeall(&sc->ifmedia);
        bxe_release_mutexes(sc);
        bxe_deallocate_bars(sc);
        pci_disable_busmaster(dev);
        return (ENXIO);
    }
    if (bxe_alloc_hsi_mem(sc) != 0) {
        bxe_free_ilt_mem(sc);
	bxe_free_buf_rings(sc);
        bxe_interrupt_free(sc);
        bxe_del_cdev(sc);
        if (sc->ifp != NULL) {
            ether_ifdetach(sc->ifp);
        }
        ifmedia_removeall(&sc->ifmedia);
        bxe_release_mutexes(sc);
        bxe_deallocate_bars(sc);
        pci_disable_busmaster(dev);
        return (ENXIO);
    }
    if (IS_PF(sc) && !BXE_NOMCP(sc)) {
        sc->fw_seq =
            (SHMEM_RD(sc, func_mb[SC_FW_MB_IDX(sc)].drv_mb_header) &
             DRV_MSG_SEQ_NUMBER_MASK);
        BLOGD(sc, DBG_LOAD, "prev unload fw_seq 0x%04x\n", sc->fw_seq);
        bxe_prev_unload(sc);
    }
#if 1
    bxe_dcbx_set_state(sc, FALSE, BXE_DCBX_ENABLED_OFF);
#else
    if (SHMEM2_HAS(sc, dcbx_lldp_params_offset) &&
        SHMEM2_HAS(sc, dcbx_lldp_dcbx_stat_offset) &&
        SHMEM2_RD(sc, dcbx_lldp_params_offset) &&
        SHMEM2_RD(sc, dcbx_lldp_dcbx_stat_offset)) {
        bxe_dcbx_set_state(sc, TRUE, BXE_DCBX_ENABLED_ON_NEG_ON);
        bxe_dcbx_init_params(sc);
    } else {
        bxe_dcbx_set_state(sc, FALSE, BXE_DCBX_ENABLED_OFF);
    }
#endif
    sc->qm_cid_count = bxe_set_qm_cid_count(sc);
    BLOGD(sc, DBG_LOAD, "qm_cid_count=%d\n", sc->qm_cid_count);
    sc->max_cos = 1;
    bxe_init_multi_cos(sc);
    bxe_add_sysctls(sc);
    return (0);
}
static int bxe_attach ( device_t dev ) { struct bxe_softc * sc ; sc = device_get_softc ( dev ) ; BLOGD ( sc , DBG_LOAD , " \n " ) ; sc -> state = BXE_STATE_CLOSED ; sc -> dev = dev ; sc -> unit = device_get_unit ( dev ) ; BLOGD ( sc , DBG_LOAD , " \n " , sc ) ; sc -> pcie_bus = pci_get_bus ( dev ) ; sc -> pcie_device = pci_get_slot ( dev ) ; sc -> pcie_func = pci_get_function ( dev ) ; pci_enable_busmaster ( dev ) ; if ( bxe_allocate_bars ( sc ) != 0 ) { return ( ENXIO ) ; } bxe_init_mutexes ( sc ) ; callout_init ( & sc -> periodic_callout , 0 ) ; sc -> chip_tq_flags = CHIP_TQ_NONE ; snprintf ( sc -> chip_tq_name , sizeof ( sc -> chip_tq_name ) , " " , sc -> unit ) ; TASK_INIT ( & sc -> chip_tq_task , 0 , bxe_handle_chip_tq , sc ) ; sc -> chip_tq = taskqueue_create ( sc -> chip_tq_name , M_NOWAIT , taskqueue_thread_enqueue , & sc -> chip_tq ) ; taskqueue_start_threads ( & sc -> chip_tq , 1 , PWAIT , " " , sc -> chip_tq_name ) ; if ( bxe_get_device_info ( sc ) != 0 ) { BLOGE ( sc , " \n " ) ; bxe_deallocate_bars ( sc ) ; pci_disable_busmaster ( dev ) ; return ( ENXIO ) ; } bxe_get_params ( sc ) ; sc -> mtu = ETHERMTU ; bxe_set_modes_bitmap ( sc ) ; bxe_get_phy_info ( sc ) ; if ( bxe_init_ifnet ( sc ) != 0 ) { bxe_release_mutexes ( sc ) ; bxe_deallocate_bars ( sc ) ; pci_disable_busmaster ( dev ) ; return ( ENXIO ) ; } if ( bxe_add_cdev ( sc ) != 0 ) { if ( sc -> ifp != NULL ) { ether_ifdetach ( sc -> ifp ) ; } ifmedia_removeall ( & sc -> ifmedia ) ; bxe_release_mutexes ( sc ) ; bxe_deallocate_bars ( sc ) ; pci_disable_busmaster ( dev ) ; return ( ENXIO ) ; } if ( bxe_interrupt_alloc ( sc ) != 0 ) { bxe_del_cdev ( sc ) ; if ( sc -> ifp != NULL ) { ether_ifdetach ( sc -> ifp ) ; } ifmedia_removeall ( & sc -> ifmedia ) ; bxe_release_mutexes ( sc ) ; bxe_deallocate_bars ( sc ) ; pci_disable_busmaster ( dev ) ; return ( ENXIO ) ; } bxe_init_fp_mutexs ( sc ) ; if ( bxe_alloc_buf_rings ( sc ) != 0 ) { bxe_free_buf_rings ( sc ) ; bxe_interrupt_free ( sc ) ; bxe_del_cdev ( sc ) ; if ( sc -> ifp != NULL ) { ether_ifdetach ( sc -> ifp ) ; } ifmedia_removeall ( & sc -> ifmedia ) ; bxe_release_mutexes ( sc ) ; bxe_deallocate_bars ( sc ) ; pci_disable_busmaster ( dev ) ; return ( ENXIO ) ; } if ( bxe_alloc_ilt_mem ( sc ) != 0 ) { bxe_free_buf_rings ( sc ) ; bxe_interrupt_free ( sc ) ; bxe_del_cdev ( sc ) ; if ( sc -> ifp != NULL ) { ether_ifdetach ( sc -> ifp ) ; } ifmedia_removeall ( & sc -> ifmedia ) ; bxe_release_mutexes ( sc ) ; bxe_deallocate_bars ( sc ) ; pci_disable_busmaster ( dev ) ; return ( ENXIO ) ; } if ( bxe_alloc_hsi_mem ( sc ) != 0 ) { bxe_free_ilt_mem ( sc ) ; bxe_free_buf_rings ( sc ) ; bxe_interrupt_free ( sc ) ; bxe_del_cdev ( sc ) ; if ( sc -> ifp != NULL ) { ether_ifdetach ( sc -> ifp ) ; } ifmedia_removeall ( & sc -> ifmedia ) ; bxe_release_mutexes ( sc ) ; bxe_deallocate_bars ( sc ) ; pci_disable_busmaster ( dev ) ; return ( ENXIO ) ; } if ( IS_PF ( sc ) && ! BXE_NOMCP ( sc ) ) { sc -> fw_seq = ( SHMEM_RD ( sc , func_mb [ SC_FW_MB_IDX ( sc ) ] . drv_mb_header ) & DRV_MSG_SEQ_NUMBER_MASK ) ; BLOGD ( sc , DBG_LOAD , " \n " , sc -> fw_seq ) ; bxe_prev_unload ( sc ) ; } #if 1 bxe_dcbx_set_state ( sc , FALSE , BXE_DCBX_ENABLED_OFF ) ; #else if ( SHMEM2_HAS ( sc , dcbx_lldp_params_offset ) && SHMEM2_HAS ( sc , dcbx_lldp_dcbx_stat_offset ) && SHMEM2_RD ( sc , dcbx_lldp_params_offset ) && SHMEM2_RD ( sc , dcbx_lldp_dcbx_stat_offset ) ) { bxe_dcbx_set_state ( sc , TRUE , BXE_DCBX_ENABLED_ON_NEG_ON ) ; bxe_dcbx_init_params ( sc ) ; } else { bxe_dcbx_set_state ( sc , FALSE , BXE_DCBX_ENABLED_OFF ) ; } #endif sc -> qm_cid_count = bxe_set_qm_cid_count ( sc ) ; BLOGD ( sc , DBG_LOAD , " \n " , sc -> qm_cid_count ) ; sc -> max_cos = 1 ; bxe_init_multi_cos ( sc ) ; bxe_add_sysctls ( sc ) ; return ( 0 ) ; }
Device attach function.
Device attach function .
/* enable bus master capability */ /* get the BARs */ /* initialize the mutexes */ /* prepare the periodic callout */ /* prepare the chip taskqueue */ /* lower priority */ /* get device info and set params */ /* get final misc params */ /* set the default MTU (changed via ifconfig) */ /* XXX
     * If in AFEX mode and the function is configured for FCoE
     * then bail... no L2 allowed.
     */ /* get phy settings from shmem and 'and' against admin settings */ /* initialize the FreeBSD ifnet interface */ /* allocate device interrupts */ /* allocate ilt */ /* allocate the host hardware/software hsi structures */ /* need to reset chip if UNDI was active */ /* init fw_seq */ /* XXX */ /* calculate qm_cid_count */