FreeBSD/sys/dev/ixgbe/if_ixv.c
/*********************************************************************
 *  Device initialization routine
 *
 *  The attach entry point is called when the driver is being loaded.
 *  This routine identifies the type of hardware, allocates all resources
 *  and initializes the hardware.
 *
 *  return 0 on success, positive on failure
 *********************************************************************/
Device initialization routine
The attach entry point is called when the driver is being loaded.
This routine identifies the type of hardware, allocates all resources
and initializes the hardware.

return 0 on success, positive on failure
Device initialization routine The attach entry point is called when the driver is being loaded . This routine identifies the type of hardware allocates all resources and initializes the hardware . return 0 on success positive on failure
static int
ixv_attach(device_t dev)
{
	struct adapter *adapter;
	struct ixgbe_hw *hw;
	int             error = 0;
	INIT_DEBUGOUT("ixv_attach: begin");
	adapter = device_get_softc(dev);
	adapter->dev = dev;
	hw = &adapter->hw;
#ifdef DEV_NETMAP
	adapter->init_locked = ixv_init_locked;
	adapter->stop_locked = ixv_stop;
#endif
	IXGBE_CORE_LOCK_INIT(adapter, device_get_nameunit(dev));
	SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
			SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
			OID_AUTO, "debug", CTLTYPE_INT | CTLFLAG_RW,
			adapter, 0, ixv_sysctl_debug, "I", "Debug Info");
	SYSCTL_ADD_INT(device_get_sysctl_ctx(dev),
			SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
			OID_AUTO, "enable_aim", CTLFLAG_RW,
			&ixv_enable_aim, 1, "Interrupt Moderation");
	callout_init_mtx(&adapter->timer, &adapter->core_mtx, 0);
	ixv_identify_hardware(adapter);
	if (ixv_allocate_pci_resources(adapter)) {
		device_printf(dev, "ixv_allocate_pci_resources() failed!\n");
		error = ENXIO;
		goto err_out;
	}
	ixv_set_sysctl_value(adapter, "rx_processing_limit",
	    "max number of rx packets to process",
	    &adapter->rx_process_limit, ixv_rx_process_limit);
	ixv_set_sysctl_value(adapter, "tx_processing_limit",
	    "max number of tx packets to process",
	    &adapter->tx_process_limit, ixv_tx_process_limit);
	if (((ixv_txd * sizeof(union ixgbe_adv_tx_desc)) % DBA_ALIGN) != 0 ||
	    ixv_txd < MIN_TXD || ixv_txd > MAX_TXD) {
		device_printf(dev, "TXD config issue, using default!\n");
		adapter->num_tx_desc = DEFAULT_TXD;
	} else
		adapter->num_tx_desc = ixv_txd;
	if (((ixv_rxd * sizeof(union ixgbe_adv_rx_desc)) % DBA_ALIGN) != 0 ||
	    ixv_rxd < MIN_RXD || ixv_rxd > MAX_RXD) {
		device_printf(dev, "RXD config issue, using default!\n");
		adapter->num_rx_desc = DEFAULT_RXD;
	} else
		adapter->num_rx_desc = ixv_rxd;
	if (ixgbe_allocate_queues(adapter)) {
		device_printf(dev, "ixgbe_allocate_queues() failed!\n");
		error = ENOMEM;
		goto err_out;
	}
	error = ixgbe_init_shared_code(hw);
	if (error) {
		device_printf(dev, "ixgbe_init_shared_code() failed!\n");
		error = EIO;
		goto err_late;
	}
	ixgbe_init_mbx_params_vf(hw);
	error = ixgbe_reset_hw(hw);
	if (error == IXGBE_ERR_RESET_FAILED)
		device_printf(dev, "ixgbe_reset_hw() failure: Reset Failed!\n");
	else if (error)
		device_printf(dev, "ixgbe_reset_hw() failed with error %d\n", error);
	if (error) {
		error = EIO;
		goto err_late;
	}
	error = ixgbevf_negotiate_api_version(hw, ixgbe_mbox_api_11);
	if (error) {
		device_printf(dev, "MBX API 1.1 negotiation failed! Error %d\n", error);
		error = EIO;
		goto err_late;
	}
	error = ixgbe_init_hw(hw);
	if (error) {
		device_printf(dev, "ixgbe_init_hw() failed!\n");
		error = EIO;
		goto err_late;
	}
	error = ixv_allocate_msix(adapter); 
	if (error) {
		device_printf(dev, "ixv_allocate_msix() failed!\n");
		goto err_late;
	}
	if (!ixv_check_ether_addr(hw->mac.addr)) {
		u8 addr[ETHER_ADDR_LEN];
		arc4rand(&addr, sizeof(addr), 0);
		addr[0] &= 0xFE;
		addr[0] |= 0x02;
		bcopy(addr, hw->mac.addr, sizeof(addr));
	}
	ixv_setup_interface(dev, adapter);
	ixv_save_stats(adapter);
	ixv_init_stats(adapter);
	ixv_add_stats_sysctls(adapter);
	adapter->vlan_attach = EVENTHANDLER_REGISTER(vlan_config,
	    ixv_register_vlan, adapter, EVENTHANDLER_PRI_FIRST);
	adapter->vlan_detach = EVENTHANDLER_REGISTER(vlan_unconfig,
	    ixv_unregister_vlan, adapter, EVENTHANDLER_PRI_FIRST);
#ifdef DEV_NETMAP
	ixgbe_netmap_attach(adapter);
#endif 
	INIT_DEBUGOUT("ixv_attach: end");
	return (0);
err_late:
	ixgbe_free_transmit_structures(adapter);
	ixgbe_free_receive_structures(adapter);
err_out:
	ixv_free_pci_resources(adapter);
	return (error);
}
static int ixv_attach ( device_t dev ) { struct adapter * adapter ; struct ixgbe_hw * hw ; int error = 0 ; INIT_DEBUGOUT ( " " ) ; adapter = device_get_softc ( dev ) ; adapter -> dev = dev ; hw = & adapter -> hw ; #ifdef DEV_NETMAP adapter -> init_locked = ixv_init_locked ; adapter -> stop_locked = ixv_stop ; #endif IXGBE_CORE_LOCK_INIT ( adapter , device_get_nameunit ( dev ) ) ; SYSCTL_ADD_PROC ( device_get_sysctl_ctx ( dev ) , SYSCTL_CHILDREN ( device_get_sysctl_tree ( dev ) ) , OID_AUTO , " " , CTLTYPE_INT | CTLFLAG_RW , adapter , 0 , ixv_sysctl_debug , " " , " " ) ; SYSCTL_ADD_INT ( device_get_sysctl_ctx ( dev ) , SYSCTL_CHILDREN ( device_get_sysctl_tree ( dev ) ) , OID_AUTO , " " , CTLFLAG_RW , & ixv_enable_aim , 1 , " " ) ; callout_init_mtx ( & adapter -> timer , & adapter -> core_mtx , 0 ) ; ixv_identify_hardware ( adapter ) ; if ( ixv_allocate_pci_resources ( adapter ) ) { device_printf ( dev , " \n " ) ; error = ENXIO ; goto err_out ; } ixv_set_sysctl_value ( adapter , " " , " " , & adapter -> rx_process_limit , ixv_rx_process_limit ) ; ixv_set_sysctl_value ( adapter , " " , " " , & adapter -> tx_process_limit , ixv_tx_process_limit ) ; if ( ( ( ixv_txd * sizeof ( union ixgbe_adv_tx_desc ) ) % DBA_ALIGN ) != 0 || ixv_txd < MIN_TXD || ixv_txd > MAX_TXD ) { device_printf ( dev , " \n " ) ; adapter -> num_tx_desc = DEFAULT_TXD ; } else adapter -> num_tx_desc = ixv_txd ; if ( ( ( ixv_rxd * sizeof ( union ixgbe_adv_rx_desc ) ) % DBA_ALIGN ) != 0 || ixv_rxd < MIN_RXD || ixv_rxd > MAX_RXD ) { device_printf ( dev , " \n " ) ; adapter -> num_rx_desc = DEFAULT_RXD ; } else adapter -> num_rx_desc = ixv_rxd ; if ( ixgbe_allocate_queues ( adapter ) ) { device_printf ( dev , " \n " ) ; error = ENOMEM ; goto err_out ; } error = ixgbe_init_shared_code ( hw ) ; if ( error ) { device_printf ( dev , " \n " ) ; error = EIO ; goto err_late ; } ixgbe_init_mbx_params_vf ( hw ) ; error = ixgbe_reset_hw ( hw ) ; if ( error == IXGBE_ERR_RESET_FAILED ) device_printf ( dev , " \n " ) ; else if ( error ) device_printf ( dev , " \n " , error ) ; if ( error ) { error = EIO ; goto err_late ; } error = ixgbevf_negotiate_api_version ( hw , ixgbe_mbox_api_11 ) ; if ( error ) { device_printf ( dev , " \n " , error ) ; error = EIO ; goto err_late ; } error = ixgbe_init_hw ( hw ) ; if ( error ) { device_printf ( dev , " \n " ) ; error = EIO ; goto err_late ; } error = ixv_allocate_msix ( adapter ) ; if ( error ) { device_printf ( dev , " \n " ) ; goto err_late ; } if ( ! ixv_check_ether_addr ( hw -> mac . addr ) ) { u8 addr [ ETHER_ADDR_LEN ] ; arc4rand ( & addr , sizeof ( addr ) , 0 ) ; addr [ 0 ] &= 0xFE ; addr [ 0 ] |= 0x02 ; bcopy ( addr , hw -> mac . addr , sizeof ( addr ) ) ; } ixv_setup_interface ( dev , adapter ) ; ixv_save_stats ( adapter ) ; ixv_init_stats ( adapter ) ; ixv_add_stats_sysctls ( adapter ) ; adapter -> vlan_attach = EVENTHANDLER_REGISTER ( vlan_config , ixv_register_vlan , adapter , EVENTHANDLER_PRI_FIRST ) ; adapter -> vlan_detach = EVENTHANDLER_REGISTER ( vlan_unconfig , ixv_unregister_vlan , adapter , EVENTHANDLER_PRI_FIRST ) ; #ifdef DEV_NETMAP ixgbe_netmap_attach ( adapter ) ; #endif INIT_DEBUGOUT ( " " ) ; return ( 0 ) ; err_late : ixgbe_free_transmit_structures ( adapter ) ; ixgbe_free_receive_structures ( adapter ) ; err_out : ixv_free_pci_resources ( adapter ) ; return ( error ) ; }
Device initialization routine
  The attach entry point is called when the driver is being loaded.
Device initialization routine The attach entry point is called when the driver is being loaded .
/* Allocate, clear, and link in our adapter structure */ /* Core Lock Init*/ /* SYSCTL APIs */ /* Set up the timer callout */ /* Determine hardware revision */ /* Do base PCI setup - map BAR0 */ /* Sysctls for limiting the amount of work done in the taskqueues */ /* Do descriptor calc and sanity checks */ /* Allocate our TX/RX Queues */ /*
	** Initialize the shared code: its
	** at this point the mac type is set.
	*/ /* Setup the mailbox */ /* Reset mbox api to 1.0 */ /* Negotiate mailbox API version */ /* If no mac address was assigned, make a random one */ /* Setup OS specific network interface */ /* Do the stats setup */ /* Register for VLAN events */ /* DEV_NETMAP */