125 lines
		
	
	
		
			3.8 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
		
		
			
		
	
	
			125 lines
		
	
	
		
			3.8 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
|   | diff --git a/ixgbe/ixgbe_main.c b/ixgbe/ixgbe_main.c | ||
|  | index 467948e..0aa1511 100644 | ||
|  | --- a/ixgbe/ixgbe_main.c | ||
|  | +++ b/ixgbe/ixgbe_main.c | ||
|  | @@ -204,6 +204,22 @@ static const struct ixgbe_reg_info ixgbe_reg_info_tbl[] = { | ||
|  |  	{} | ||
|  |  }; | ||
|  |   | ||
|  | +#if defined(CONFIG_NETMAP) || defined(CONFIG_NETMAP_MODULE) | ||
|  | +/* | ||
|  | + * The #ifdef DEV_NETMAP / #endif blocks in this file are meant to | ||
|  | + * be a reference on how to implement netmap support in a driver. | ||
|  | + * Additional comments are in ixgbe_netmap_linux.h . | ||
|  | + * | ||
|  | + * The code is originally developed on FreeBSD and in the interest | ||
|  | + * of maintainability we try to limit differences between the two systems. | ||
|  | + * | ||
|  | + * <ixgbe_netmap_linux.h> contains functions for netmap support | ||
|  | + * that extend the standard driver. | ||
|  | + * It also defines DEV_NETMAP so further conditional sections use | ||
|  | + * that instead of CONFIG_NETMAP | ||
|  | + */ | ||
|  | +#include <ixgbe_netmap_linux.h> | ||
|  | +#endif | ||
|  |   | ||
|  |  /* | ||
|  |   * ixgbe_regdump - register printout routine | ||
|  | @@ -749,6 +765,17 @@ static bool ixgbe_clean_tx_irq(struct ixgbe_q_vector *q_vector, | ||
|  |  	if (test_bit(__IXGBE_DOWN, &adapter->state)) | ||
|  |  		return true; | ||
|  |   | ||
|  | +#ifdef DEV_NETMAP | ||
|  | +	/* | ||
|  | +	 * In netmap mode, all the work is done in the context | ||
|  | +	 * of the client thread. Interrupt handlers only wake up | ||
|  | +	 * clients, which may be sleeping on individual rings | ||
|  | +	 * or on a global resource for all rings. | ||
|  | +	 */ | ||
|  | +	if (netmap_tx_irq(adapter->netdev, tx_ring->queue_index)) | ||
|  | +		return 1; /* seems to be ignored */ | ||
|  | +#endif /* DEV_NETMAP */ | ||
|  | + | ||
|  |  	tx_buffer = &tx_ring->tx_buffer_info[i]; | ||
|  |  	tx_desc = IXGBE_TX_DESC(tx_ring, i); | ||
|  |  	i -= tx_ring->count; | ||
|  | @@ -1629,6 +1656,15 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector, | ||
|  |  #endif /* IXGBE_FCOE */ | ||
|  |  	u16 cleaned_count = ixgbe_desc_unused(rx_ring); | ||
|  |   | ||
|  | +#ifdef DEV_NETMAP | ||
|  | +	/* | ||
|  | +	 * 	 Same as the txeof routine: only wakeup clients on intr. | ||
|  | +	 */ | ||
|  | +	int dummy; | ||
|  | +	if (netmap_rx_irq(rx_ring->netdev, rx_ring->queue_index, &dummy)) | ||
|  | +		return true; /* no more interrupts */ | ||
|  | +#endif /* DEV_NETMAP */ | ||
|  | + | ||
|  |  	do { | ||
|  |  		struct ixgbe_rx_buffer *rx_buffer; | ||
|  |  		union ixgbe_adv_rx_desc *rx_desc; | ||
|  | @@ -2683,6 +2719,9 @@ void ixgbe_configure_tx_ring(struct ixgbe_adapter *adapter, | ||
|  |  	} while (--wait_loop && !(txdctl & IXGBE_TXDCTL_ENABLE)); | ||
|  |  	if (!wait_loop) | ||
|  |  		e_err(drv, "Could not enable Tx Queue %d\n", reg_idx); | ||
|  | +#ifdef DEV_NETMAP | ||
|  | +	ixgbe_netmap_configure_tx_ring(adapter, reg_idx); | ||
|  | +#endif /* DEV_NETMAP */ | ||
|  |  } | ||
|  |   | ||
|  |  static void ixgbe_setup_mtqc(struct ixgbe_adapter *adapter) | ||
|  | @@ -3032,6 +3071,10 @@ void ixgbe_configure_rx_ring(struct ixgbe_adapter *adapter, | ||
|  |  	IXGBE_WRITE_REG(hw, IXGBE_RXDCTL(reg_idx), rxdctl); | ||
|  |   | ||
|  |  	ixgbe_rx_desc_queue_enable(adapter, ring); | ||
|  | +#ifdef DEV_NETMAP | ||
|  | +	if (ixgbe_netmap_configure_rx_ring(adapter, reg_idx)) | ||
|  | +		return; | ||
|  | +#endif /* DEV_NETMAP */ | ||
|  |  	ixgbe_alloc_rx_buffers(ring, ixgbe_desc_unused(ring)); | ||
|  |  } | ||
|  |   | ||
|  | @@ -3986,6 +4029,10 @@ static void ixgbe_up_complete(struct ixgbe_adapter *adapter) | ||
|  |  	/* enable transmits */ | ||
|  |  	netif_tx_start_all_queues(adapter->netdev); | ||
|  |   | ||
|  | +#ifdef DEV_NETMAP | ||
|  | +	netmap_enable_all_rings(adapter->netdev); | ||
|  | +#endif | ||
|  | + | ||
|  |  	/* bring the link up in the watchdog, this could race with our first | ||
|  |  	 * link up interrupt but shouldn't be a problem */ | ||
|  |  	adapter->flags |= IXGBE_FLAG_NEED_LINK_UPDATE; | ||
|  | @@ -4249,6 +4296,10 @@ void ixgbe_down(struct ixgbe_adapter *adapter) | ||
|  |   | ||
|  |  	ixgbe_napi_disable_all(adapter); | ||
|  |   | ||
|  | +#ifdef DEV_NETMAP | ||
|  | +	netmap_disable_all_rings(netdev); | ||
|  | +#endif | ||
|  | + | ||
|  |  	adapter->flags2 &= ~(IXGBE_FLAG2_FDIR_REQUIRES_REINIT | | ||
|  |  			     IXGBE_FLAG2_RESET_REQUESTED); | ||
|  |  	adapter->flags &= ~IXGBE_FLAG_NEED_LINK_UPDATE; | ||
|  | @@ -4764,6 +4815,7 @@ static int ixgbe_open(struct net_device *netdev) | ||
|  |   | ||
|  |  	ixgbe_up_complete(adapter); | ||
|  |   | ||
|  | + | ||
|  |  	return 0; | ||
|  |   | ||
|  |  err_req_irq: | ||
|  | @@ -7152,6 +7204,11 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev, | ||
|  |   | ||
|  |  	e_dev_info("%s\n", ixgbe_default_device_descr); | ||
|  |  	cards_found++; | ||
|  | + | ||
|  | +#ifdef DEV_NETMAP | ||
|  | +	ixgbe_netmap_attach(adapter); | ||
|  | +#endif /* DEV_NETMAP */ | ||
|  | + | ||
|  |  	return 0; | ||
|  |   | ||
|  |  err_register: |