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

📄 netdev.c

📁 DELL755 Intel 网卡驱动
💻 C
📖 第 1 页 / 共 5 页
字号:
	rx_ring->next_to_clean = 0;	rx_ring->next_to_use = 0;	writel(0, adapter->hw.hw_addr + rx_ring->head);	writel(0, adapter->hw.hw_addr + rx_ring->tail);}/** * e1000_free_rx_resources - Free Rx Resources * @adapter: board private structure * * Free all receive software resources **/void e1000_free_rx_resources(struct e1000_adapter *adapter){	struct pci_dev *pdev = adapter->pdev;	struct e1000_ring *rx_ring = adapter->rx_ring;	int i;	e1000_clean_rx_ring(adapter);	for (i = 0; i < rx_ring->count; i++) {		kfree(rx_ring->buffer_info[i].ps_pages);	}	vfree(rx_ring->buffer_info);	rx_ring->buffer_info = NULL;	dma_free_coherent(&pdev->dev, rx_ring->size, rx_ring->desc,			  rx_ring->dma);	rx_ring->desc = NULL;}/** * e1000_update_itr - update the dynamic ITR value based on statistics * @adapter: pointer to adapter * @itr_setting: current adapter->itr * @packets: the number of packets during this measurement interval * @bytes: the number of bytes during this measurement interval * *      Stores a new ITR value based on packets and byte *      counts during the last interrupt.  The advantage of per interrupt *      computation is faster updates and more accurate ITR for the current *      traffic pattern.  Constants in this function were computed *      based on theoretical maximum wire speed and thresholds were set based *      on testing data as well as attempting to minimize response time *      while increasing bulk throughput.  This functionality is controlled *      by the InterruptThrottleRate module parameter. **/static unsigned int e1000_update_itr(struct e1000_adapter *adapter,				     u16 itr_setting, int packets,				     int bytes){	unsigned int retval = itr_setting;	if (packets == 0)		goto update_itr_done;	switch (itr_setting) {	case lowest_latency:		/* handle TSO and jumbo frames */		if (bytes/packets > 8000)			retval = bulk_latency;		else if ((packets < 5) && (bytes > 512)) {			retval = low_latency;		}		break;	case low_latency:  /* 50 usec aka 20000 ints/s */		if (bytes > 10000) {			/* this if handles the TSO accounting */			if (bytes/packets > 8000) {				retval = bulk_latency;			} else if ((packets < 10) || ((bytes/packets) > 1200)) {				retval = bulk_latency;			} else if ((packets > 35)) {				retval = lowest_latency;			}		} else if (bytes/packets > 2000) {			retval = bulk_latency;		} else if (packets <= 2 && bytes < 512) {			retval = lowest_latency;		}		break;	case bulk_latency: /* 250 usec aka 4000 ints/s */		if (bytes > 25000) {			if (packets > 35) {				retval = low_latency;			}		} else if (bytes < 6000) {			retval = low_latency;		}		break;	}update_itr_done:	return retval;}static void e1000_set_itr(struct e1000_adapter *adapter){	struct e1000_hw *hw = &adapter->hw;	u16 current_itr;	u32 new_itr = adapter->itr;	/* for non-gigabit speeds, just fix the interrupt rate at 4000 */	if (adapter->link_speed != SPEED_1000) {		current_itr = 0;		new_itr = 4000;		goto set_itr_now;	}	adapter->tx_itr = e1000_update_itr(adapter,				    adapter->tx_itr,				    adapter->total_tx_packets,				    adapter->total_tx_bytes);	/* conservative mode (itr 3) eliminates the lowest_latency setting */	if (adapter->itr_setting == 3 && adapter->tx_itr == lowest_latency)		adapter->tx_itr = low_latency;	adapter->rx_itr = e1000_update_itr(adapter,				    adapter->rx_itr,				    adapter->total_rx_packets,				    adapter->total_rx_bytes);	/* conservative mode (itr 3) eliminates the lowest_latency setting */	if (adapter->itr_setting == 3 && adapter->rx_itr == lowest_latency)		adapter->rx_itr = low_latency;	current_itr = max(adapter->rx_itr, adapter->tx_itr);	switch (current_itr) {	/* counts and packets in update_itr are dependent on these numbers */	case lowest_latency:		new_itr = 70000;		break;	case low_latency:		new_itr = 20000; /* aka hwitr = ~200 */		break;	case bulk_latency:		new_itr = 4000;		break;	default:		break;	}set_itr_now:	if (new_itr != adapter->itr) {		/*		 * this attempts to bias the interrupt rate towards Bulk		 * by adding intermediate steps when interrupt rate is		 * increasing		 */		new_itr = new_itr > adapter->itr ?			     min(adapter->itr + (new_itr >> 2), new_itr) :			     new_itr;		adapter->itr = new_itr;#ifdef CONFIG_E1000E_MSIX		adapter->rx_ring->itr_val = new_itr;		if (adapter->msix_entries)			adapter->rx_ring->set_itr = 1;		else#endif			ew32(ITR, 1000000000 / (new_itr * 256));	}}/** * e1000_clean_tx_irq - Reclaim resources after transmit completes * @adapter: board private structure * * the return value indicates if there is more work to do (later) **/static bool e1000_clean_tx_irq(struct e1000_adapter *adapter){	struct net_device *netdev = adapter->netdev;	struct e1000_hw *hw = &adapter->hw;	struct e1000_ring *tx_ring = adapter->tx_ring;	struct e1000_tx_desc *tx_desc, *eop_desc;	struct e1000_buffer *buffer_info;	unsigned int i, eop;	bool cleaned = 0, retval = 1;	unsigned int total_tx_bytes = 0, total_tx_packets = 0;	i = tx_ring->next_to_clean;	eop = tx_ring->buffer_info[i].next_to_watch;	eop_desc = E1000_TX_DESC(*tx_ring, eop);	while (eop_desc->upper.data & cpu_to_le32(E1000_TXD_STAT_DD)) {		for (cleaned = 0; !cleaned; ) {			tx_desc = E1000_TX_DESC(*tx_ring, i);			buffer_info = &tx_ring->buffer_info[i];			cleaned = (i == eop);			if (cleaned) {				struct sk_buff *skb = buffer_info->skb;#ifdef NETIF_F_TSO				unsigned int segs, bytecount;				segs = skb_shinfo(skb)->gso_segs ?: 1;				/* multiply data chunks by size of headers */				bytecount = ((segs - 1) * skb_headlen(skb)) +					    skb->len;				total_tx_packets += segs;				total_tx_bytes += bytecount;#else				total_tx_packets++;				total_tx_bytes += skb->len;#endif			}			e1000_put_txbuf(adapter, buffer_info);			tx_desc->upper.data = 0;			i++;			if (i == tx_ring->count)				i = 0;#ifdef CONFIG_E1000E_NAPI			if (total_tx_packets >= tx_ring->count) {				retval = 0;				goto done_cleaning;			}#endif		}		eop = tx_ring->buffer_info[i].next_to_watch;		eop_desc = E1000_TX_DESC(*tx_ring, eop);	}#ifdef CONFIG_E1000E_NAPIdone_cleaning:#endif	tx_ring->next_to_clean = i;#define TX_WAKE_THRESHOLD 32	if (cleaned && netif_carrier_ok(netdev) &&	    e1000_desc_unused(tx_ring) >= TX_WAKE_THRESHOLD) {		/*		 * Make sure that anybody stopping the queue after this		 * sees the new next_to_clean.		 */		smp_mb();		if (netif_queue_stopped(netdev) &&		    !(test_bit(__E1000_DOWN, &adapter->state))) {			netif_wake_queue(netdev);			++adapter->restart_queue;		}	}	if (adapter->detect_tx_hung) {		/*		 * Detect a transmit hang in hardware, this serializes the		 * check with the clearing of time_stamp and movement of i		 */		adapter->detect_tx_hung = 0;		if (tx_ring->buffer_info[eop].dma &&		    time_after(jiffies, tx_ring->buffer_info[eop].time_stamp			       + (adapter->tx_timeout_factor * HZ))		    && !(er32(STATUS) & E1000_STATUS_TXOFF)) {			e1000_print_tx_hang(adapter);			netif_stop_queue(netdev);		}	}	adapter->total_tx_bytes += total_tx_bytes;	adapter->total_tx_packets += total_tx_packets;	adapter->net_stats.tx_bytes += total_tx_bytes;	adapter->net_stats.tx_packets += total_tx_packets;	return retval;}/** * e1000_intr_msi - Interrupt Handler * @irq: interrupt number * @data: pointer to a network interface device structure **/static irqreturn_t e1000_intr_msi(int irq, void *data){	struct net_device *netdev = data;	struct e1000_adapter *adapter = netdev_priv(netdev);	struct e1000_hw *hw = &adapter->hw;#ifndef CONFIG_E1000E_NAPI	int i;#endif	/* read ICR disables interrupts using IAM */	u32 icr = er32(ICR);	if (icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC)) {		hw->mac.get_link_status = 1;		/*		 * ICH8 workaround-- Call gig speed drop workaround on cable		 * disconnect (LSC) before accessing any PHY registers		 */		if ((adapter->flags & FLAG_LSC_GIG_SPEED_DROP) &&		    (!(er32(STATUS) & E1000_STATUS_LU)))			e1000_gig_downshift_workaround_ich8lan(hw);		/*		 * 80003ES2LAN workaround-- For packet buffer work-around on		 * link down event; disable receives here in the ISR and reset		 * adapter in watchdog		 */		if (netif_carrier_ok(netdev) &&		    adapter->flags & FLAG_RX_NEEDS_RESTART) {			/* disable receives */			u32 rctl = er32(RCTL);			ew32(RCTL, rctl & ~E1000_RCTL_EN);			adapter->flags |= FLAG_RX_RESTART_NOW;		}		/* guard against interrupt when we're going down */		if (!test_bit(__E1000_DOWN, &adapter->state))			mod_timer(&adapter->watchdog_timer, jiffies + 1);	}#ifdef CONFIG_E1000E_NAPI	if (netif_rx_schedule_prep(netdev, &adapter->napi)) {		adapter->total_tx_bytes = 0;		adapter->total_tx_packets = 0;		adapter->total_rx_bytes = 0;		adapter->total_rx_packets = 0;		__netif_rx_schedule(netdev, &adapter->napi);	}#else	adapter->total_tx_bytes = 0;	adapter->total_rx_bytes = 0;	adapter->total_tx_packets = 0;	adapter->total_rx_packets = 0;	for (i = 0; i < E1000_MAX_INTR; i++) {		int rx_cleaned = adapter->clean_rx(adapter);		int tx_cleaned_complete = e1000_clean_tx_irq(adapter);		if (!rx_cleaned && tx_cleaned_complete)			break;	}	if (likely(adapter->itr_setting & 3))		e1000_set_itr(adapter);#endif /* CONFIG_E1000E_NAPI */	return IRQ_HANDLED;}/** * e1000_intr - Interrupt Handler * @irq: interrupt number * @data: pointer to a network interface device structure **/static irqreturn_t e1000_intr(int irq, void *data){	struct net_device *netdev = data;	struct e1000_adapter *adapter = netdev_priv(netdev);	struct e1000_hw *hw = &adapter->hw;#ifndef CONFIG_E1000E_NAPI	int i;	int rx_cleaned, tx_cleaned_complete;#endif	u32 rctl, icr = er32(ICR);	if (!icr)		return IRQ_NONE;  /* Not our interrupt */#ifdef CONFIG_E1000E_NAPI	/*	 * IMS will not auto-mask if INT_ASSERTED is not set, and if it is	 * not set, then the adapter didn't send an interrupt	 */	if (!(icr & E1000_ICR_INT_ASSERTED))		return IRQ_NONE;#endif /* CONFIG_E1000E_NAPI */	if (icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC)) {		hw->mac.get_link_status = 1;		/*		 * ICH8 workaround-- Call gig speed drop workaround on cable		 * disconnect (LSC) before accessing any PHY registers		 */		if ((adapter->flags & FLAG_LSC_GIG_SPEED_DROP) &&		    (!(er32(STATUS) & E1000_STATUS_LU)))			e1000_gig_downshift_workaround_ich8lan(hw);		/*		 * 80003ES2LAN workaround--		 * For packet buffer work-around on link down event;		 * disable receives here in the ISR and		 * reset adapter in watchdog		 */		if (netif_carrier_ok(netdev) &&		    (adapter->flags & FLAG_RX_NEEDS_RESTART)) {			/* disable receives */			rctl = er32(RCTL);			ew32(RCTL, rctl & ~E1000_RCTL_EN);			adapter->flags |= FLAG_RX_RESTART_NOW;		}		/* guard against interrupt when we're going down */		if (!test_bit(__E1000_DOWN, &adapter->state))			mod_timer(&adapter->watchdog_timer, jiffies + 1);	}#ifdef CONFIG_E1000E_NAPI	if (netif_rx_schedule_prep(netdev, &adapter->napi)) {		adapter->total_tx_bytes = 0;		adapter->total_tx_packets = 0;		adapter->total_rx_bytes = 0;		adapter->total_rx_packets = 0;		__netif_rx_schedule(netdev, &adapter->napi);	}#else	adapter->total_tx_bytes = 0;	adapter->total_rx_bytes = 0;	adapter->total_tx_packets = 0;	adapter->total_rx_packets = 0;	for (i = 0; i < E1000_MAX_INTR; i++) {		rx_cleaned = adapter->clean_rx(adapter);		tx_cleaned_complete = e1000_clean_tx_irq(adapter);		if (!rx_cleaned && tx_cleaned_complete)			break;	}	if (likely(adapter->itr_setting & 3))		e1000_set_itr(adapter);#endif /* CONFIG_E1000E_NAPI */	return IRQ_HANDLED;}#ifdef CONFIG_E1000E_MSIXstatic irqreturn_t e1000_msix_other(int irq, void *data){	struct net_device *netdev = data;	struct e1000_adapter *adapter = netdev_priv(netdev);	struct e1000_hw *hw = &adapter->hw;	u32 icr = er32(ICR);	if (!(icr & E1000_ICR_INT_ASSERTED))	{		ew32(IMS, E1000_IMS_OTHER);		return IRQ_NONE;	}	if (icr & adapter->eiac_mask)		ew32(ICS, (icr & adapter->eiac_mask));	if (icr & E1000_ICR_OTHER) {		if (!(icr & E1000_ICR_LSC))			goto no_link_interrupt;		hw->mac.get_link_status = 1;		/* guard against interrupt when we're going down */		if (!test_bit(__E1000_DOWN, &adapter->state))			mod_timer(&adapter->watchdog_timer, jiffies + 1);	}no_link_interrupt:	ew32(IMS, E1000_IMS_LSC | E1000_IMS_OTHER);	return IRQ_HANDLED;}#ifdef CONFIG_E1000E_SEPARATE_TX_HANDLERstatic irqreturn_t e1000_intr_msix_tx(int irq, void *data){	struct net_device *netdev = data;	struct e1000_adapter *adapter = netdev_priv(netdev);	struct e1000_hw *hw = &adapter->hw;	struct e1000_ring *tx_ring = adapter->tx_ring;	adapter->total_tx_bytes = 0;	adapter->total_tx_packets = 0;	if (!e1000_clean_tx_irq(adapter))		/* Ring was not completely cleaned, so fire another interrupt */		ew32(ICS, tx_ring->ims_val);	return IRQ_HANDLED;}#endif  /* CONFIG_E1000E_SEPARATE_TX_HANDLER */static irqreturn_t e1000_intr_msix_rx(int irq, void *data){	struct net_device *netdev = data;	struct e1000_adapter *adapter = netdev_priv(netdev);#ifndef CONFIG_E1000E_NAPI	int i;

⌨️ 快捷键说明

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