⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ixgbe_main.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
	napi_disable(&adapter->napi);	atomic_set(&adapter->irq_sem, 0);	ixgbe_irq_disable(adapter);	del_timer_sync(&adapter->watchdog_timer);	netif_carrier_off(netdev);	netif_stop_queue(netdev);	ixgbe_reset(adapter);	ixgbe_clean_all_tx_rings(adapter);	ixgbe_clean_all_rx_rings(adapter);}static int ixgbe_suspend(struct pci_dev *pdev, pm_message_t state){	struct net_device *netdev = pci_get_drvdata(pdev);	struct ixgbe_adapter *adapter = netdev_priv(netdev);#ifdef CONFIG_PM	int retval = 0;#endif	netif_device_detach(netdev);	if (netif_running(netdev)) {		ixgbe_down(adapter);		ixgbe_free_irq(adapter);	}#ifdef CONFIG_PM	retval = pci_save_state(pdev);	if (retval)		return retval;#endif	pci_enable_wake(pdev, PCI_D3hot, 0);	pci_enable_wake(pdev, PCI_D3cold, 0);	pci_disable_device(pdev);	pci_set_power_state(pdev, pci_choose_state(pdev, state));	return 0;}static void ixgbe_shutdown(struct pci_dev *pdev){	ixgbe_suspend(pdev, PMSG_SUSPEND);}/** * ixgbe_clean - NAPI Rx polling callback * @adapter: board private structure **/static int ixgbe_clean(struct napi_struct *napi, int budget){	struct ixgbe_adapter *adapter = container_of(napi,					struct ixgbe_adapter, napi);	struct net_device *netdev = adapter->netdev;	int tx_cleaned = 0, work_done = 0;	/* In non-MSIX case, there is no multi-Tx/Rx queue */	tx_cleaned = ixgbe_clean_tx_irq(adapter, adapter->tx_ring);	ixgbe_clean_rx_irq(adapter, &adapter->rx_ring[0], &work_done,			   budget);	if (tx_cleaned)		work_done = budget;	/* If budget not fully consumed, exit the polling mode */	if (work_done < budget) {		netif_rx_complete(netdev, napi);		ixgbe_irq_enable(adapter);	}	return work_done;}/** * ixgbe_tx_timeout - Respond to a Tx Hang * @netdev: network interface device structure **/static void ixgbe_tx_timeout(struct net_device *netdev){	struct ixgbe_adapter *adapter = netdev_priv(netdev);	/* Do the reset outside of interrupt context */	schedule_work(&adapter->reset_task);}static void ixgbe_reset_task(struct work_struct *work){	struct ixgbe_adapter *adapter;	adapter = container_of(work, struct ixgbe_adapter, reset_task);	adapter->tx_timeout_count++;	ixgbe_down(adapter);	ixgbe_up(adapter);}/** * ixgbe_alloc_queues - Allocate memory for all rings * @adapter: board private structure to initialize * * We allocate one ring per queue at run-time since we don't know the * number of queues at compile-time.  The polling_netdev array is * intended for Multiqueue, but should work fine with a single queue. **/static int __devinit ixgbe_alloc_queues(struct ixgbe_adapter *adapter){	int i;	adapter->tx_ring = kcalloc(adapter->num_tx_queues,				   sizeof(struct ixgbe_ring), GFP_KERNEL);	if (!adapter->tx_ring)		return -ENOMEM;	for (i = 0; i < adapter->num_tx_queues; i++)		adapter->tx_ring[i].count = IXGBE_DEFAULT_TXD;	adapter->rx_ring = kcalloc(adapter->num_rx_queues,				   sizeof(struct ixgbe_ring), GFP_KERNEL);	if (!adapter->rx_ring) {		kfree(adapter->tx_ring);		return -ENOMEM;	}	for (i = 0; i < adapter->num_rx_queues; i++) {		adapter->rx_ring[i].adapter = adapter;		adapter->rx_ring[i].itr_register = IXGBE_EITR(i);		adapter->rx_ring[i].count = IXGBE_DEFAULT_RXD;	}	return 0;}/** * ixgbe_sw_init - Initialize general software structures (struct ixgbe_adapter) * @adapter: board private structure to initialize * * ixgbe_sw_init initializes the Adapter private data structure. * Fields are initialized based on PCI device information and * OS network device settings (MTU size). **/static int __devinit ixgbe_sw_init(struct ixgbe_adapter *adapter){	struct ixgbe_hw *hw = &adapter->hw;	struct pci_dev *pdev = adapter->pdev;	/* default flow control settings */	hw->fc.original_type = ixgbe_fc_full;	hw->fc.type = ixgbe_fc_full;	hw->mac.link_mode_select = IXGBE_AUTOC_LMS_10G_LINK_NO_AN;	if (hw->mac.ops.reset(hw)) {		dev_err(&pdev->dev, "HW Init failed\n");		return -EIO;	}	if (hw->phy.ops.setup_speed(hw, IXGBE_LINK_SPEED_10GB_FULL, true,				   false)) {		dev_err(&pdev->dev, "Link Speed setup failed\n");		return -EIO;	}	/* initialize eeprom parameters */	if (ixgbe_init_eeprom(hw)) {		dev_err(&pdev->dev, "EEPROM initialization failed\n");		return -EIO;	}	/* Set the default values */	adapter->num_rx_queues = IXGBE_DEFAULT_RXQ;	adapter->num_tx_queues = 1;	adapter->flags |= IXGBE_FLAG_RX_CSUM_ENABLED;	if (ixgbe_alloc_queues(adapter)) {		dev_err(&pdev->dev, "Unable to allocate memory for queues\n");		return -ENOMEM;	}	atomic_set(&adapter->irq_sem, 1);	set_bit(__IXGBE_DOWN, &adapter->state);	return 0;}/** * ixgbe_setup_tx_resources - allocate Tx resources (Descriptors) * @adapter: board private structure * @txdr:    tx descriptor ring (for a specific queue) to setup * * Return 0 on success, negative on failure **/int ixgbe_setup_tx_resources(struct ixgbe_adapter *adapter,			     struct ixgbe_ring *txdr){	struct pci_dev *pdev = adapter->pdev;	int size;	size = sizeof(struct ixgbe_tx_buffer) * txdr->count;	txdr->tx_buffer_info = vmalloc(size);	if (!txdr->tx_buffer_info) {		DPRINTK(PROBE, ERR,		"Unable to allocate memory for the transmit descriptor ring\n");		return -ENOMEM;	}	memset(txdr->tx_buffer_info, 0, size);	/* round up to nearest 4K */	txdr->size = txdr->count * sizeof(union ixgbe_adv_tx_desc);	txdr->size = ALIGN(txdr->size, 4096);	txdr->desc = pci_alloc_consistent(pdev, txdr->size, &txdr->dma);	if (!txdr->desc) {		vfree(txdr->tx_buffer_info);		DPRINTK(PROBE, ERR,			"Memory allocation failed for the tx desc ring\n");		return -ENOMEM;	}	txdr->adapter = adapter;	txdr->next_to_use = 0;	txdr->next_to_clean = 0;	txdr->work_limit = txdr->count;	spin_lock_init(&txdr->tx_lock);	return 0;}/** * ixgbe_setup_rx_resources - allocate Rx resources (Descriptors) * @adapter: board private structure * @rxdr:    rx descriptor ring (for a specific queue) to setup * * Returns 0 on success, negative on failure **/int ixgbe_setup_rx_resources(struct ixgbe_adapter *adapter,			     struct ixgbe_ring *rxdr){	struct pci_dev *pdev = adapter->pdev;	int size, desc_len;	size = sizeof(struct ixgbe_rx_buffer) * rxdr->count;	rxdr->rx_buffer_info = vmalloc(size);	if (!rxdr->rx_buffer_info) {		DPRINTK(PROBE, ERR,			"vmalloc allocation failed for the rx desc ring\n");		return -ENOMEM;	}	memset(rxdr->rx_buffer_info, 0, size);	desc_len = sizeof(union ixgbe_adv_rx_desc);	/* Round up to nearest 4K */	rxdr->size = rxdr->count * desc_len;	rxdr->size = ALIGN(rxdr->size, 4096);	rxdr->desc = pci_alloc_consistent(pdev, rxdr->size, &rxdr->dma);	if (!rxdr->desc) {		DPRINTK(PROBE, ERR,			"Memory allocation failed for the rx desc ring\n");		vfree(rxdr->rx_buffer_info);		return -ENOMEM;	}	rxdr->next_to_clean = 0;	rxdr->next_to_use = 0;	rxdr->adapter = adapter;	return 0;}/** * ixgbe_free_tx_resources - Free Tx Resources per Queue * @adapter: board private structure * @tx_ring: Tx descriptor ring for a specific queue * * Free all transmit software resources **/static void ixgbe_free_tx_resources(struct ixgbe_adapter *adapter,				    struct ixgbe_ring *tx_ring){	struct pci_dev *pdev = adapter->pdev;	ixgbe_clean_tx_ring(adapter, tx_ring);	vfree(tx_ring->tx_buffer_info);	tx_ring->tx_buffer_info = NULL;	pci_free_consistent(pdev, tx_ring->size, tx_ring->desc, tx_ring->dma);	tx_ring->desc = NULL;}/** * ixgbe_free_all_tx_resources - Free Tx Resources for All Queues * @adapter: board private structure * * Free all transmit software resources **/static void ixgbe_free_all_tx_resources(struct ixgbe_adapter *adapter){	int i;	for (i = 0; i < adapter->num_tx_queues; i++)		ixgbe_free_tx_resources(adapter, &adapter->tx_ring[i]);}/** * ixgbe_free_rx_resources - Free Rx Resources * @adapter: board private structure * @rx_ring: ring to clean the resources from * * Free all receive software resources **/static void ixgbe_free_rx_resources(struct ixgbe_adapter *adapter,				    struct ixgbe_ring *rx_ring){	struct pci_dev *pdev = adapter->pdev;	ixgbe_clean_rx_ring(adapter, rx_ring);	vfree(rx_ring->rx_buffer_info);	rx_ring->rx_buffer_info = NULL;	pci_free_consistent(pdev, rx_ring->size, rx_ring->desc, rx_ring->dma);	rx_ring->desc = NULL;}/** * ixgbe_free_all_rx_resources - Free Rx Resources for All Queues * @adapter: board private structure * * Free all receive software resources **/static void ixgbe_free_all_rx_resources(struct ixgbe_adapter *adapter){	int i;	for (i = 0; i < adapter->num_rx_queues; i++)		ixgbe_free_rx_resources(adapter, &adapter->rx_ring[i]);}/** * ixgbe_setup_all_tx_resources - wrapper to allocate Tx resources *				  (Descriptors) for all queues * @adapter: board private structure * * If this function returns with an error, then it's possible one or * more of the rings is populated (while the rest are not).  It is the * callers duty to clean those orphaned rings. * * Return 0 on success, negative on failure **/static int ixgbe_setup_all_tx_resources(struct ixgbe_adapter *adapter){	int i, err = 0;	for (i = 0; i < adapter->num_tx_queues; i++) {		err = ixgbe_setup_tx_resources(adapter, &adapter->tx_ring[i]);		if (err) {			DPRINTK(PROBE, ERR,				"Allocation for Tx Queue %u failed\n", i);			break;		}	}	return err;}/** * ixgbe_setup_all_rx_resources - wrapper to allocate Rx resources *				  (Descriptors) for all queues * @adapter: board private structure * * If this function returns with an error, then it's possible one or * more of the rings is populated (while the rest are not).  It is the * callers duty to clean those orphaned rings. * * Return 0 on success, negative on failure **/static int ixgbe_setup_all_rx_resources(struct ixgbe_adapter *adapter){	int i, err = 0;	for (i = 0; i < adapter->num_rx_queues; i++) {		err = ixgbe_setup_rx_resources(adapter, &adapter->rx_ring[i]);		if (err) {			DPRINTK(PROBE, ERR,				"Allocation for Rx Queue %u failed\n", i);			break;		}	}	return err;}/** * ixgbe_change_mtu - Change the Maximum Transfer Unit * @netdev: network interface device structure * @new_mtu: new value for maximum frame size * * Returns 0 on success, negative on failure **/static int ixgbe_change_mtu(struct net_device *netdev, int new_mtu){	struct ixgbe_adapter *adapter = netdev_priv(netdev);	int max_frame = new_mtu + ETH_HLEN + ETH_FCS_LEN;	if ((max_frame < (ETH_ZLEN + ETH_FCS_LEN)) ||	    (max_frame > IXGBE_MAX_JUMBO_FRAME_SIZE))		return -EINVAL;	netdev->mtu = new_mtu;	if (netif_running(netdev)) {		ixgbe_down(adapter);		ixgbe_up(adapter);	}	return 0;}/** * ixgbe_open - Called when a network interface is made active * @netdev: network interface device structure * * Returns 0 on success, negative value on failure * * The open entry point is called when a network interface is made * active by the system (IFF_UP).  At this point all resources needed * for transmit and receive operations are allocated, the interrupt * handler is registered with the OS, the watchdog timer is started, * and the stack is notified that the interface is ready. **/static int ixgbe_open(struct net_device *netdev){	struct ixgbe_adapter *adapter = netdev_priv(netdev);	int err;	u32 ctrl_ext;	u32 num_rx_queues = adapter->num_rx_queues;	/* Let firmware know the driver has taken over */	ctrl_ext = IXGBE_READ_REG(&adapter->hw, IXGBE_CTRL_EXT);	IXGBE_WRITE_REG(&adapter->hw, IXGBE_CTRL_EXT,			ctrl_ext | IXGBE_CTRL_EXT_DRV_LOAD);try_intr_reinit:	/* allocate transmit descriptors */	err = ixgbe_setup_all_tx_resources(adapter);	if (err)		goto err_setup_tx;	if (!(adapter->flags & IXGBE_FLAG_MSIX_ENABLED)) {		num_rx_queues = 1;		adapter->num_rx_queues = num_rx_queues;	}	/* allocate receive descriptors */	err = ixgbe_setup_all_rx_resources(adapter);	if (err)		goto err_setup_rx;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -