2873 lines · 76.4 KB · C
RawDownload
/*******************************************************************************   Intel(R) 82576 Virtual Function Linux driver  Copyright(c) 2009 - 2010 Intel Corporation.   This program is free software; you can redistribute it and/or modify it  under the terms and conditions of the GNU General Public License,  version 2, as published by the Free Software Foundation.   This program is distributed in the hope it will be useful, but WITHOUT  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for  more details.   You should have received a copy of the GNU General Public License along with  this program; if not, write to the Free Software Foundation, Inc.,  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.   The full GNU General Public License is included in this distribution in  the file called "COPYING".   Contact Information:  e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>  Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 *******************************************************************************/ #include <linux/module.h>#include <linux/types.h>#include <linux/init.h>#include <linux/pci.h>#include <linux/vmalloc.h>#include <linux/pagemap.h>#include <linux/delay.h>#include <linux/netdevice.h>#include <linux/tcp.h>#include <linux/ipv6.h>#include <linux/slab.h>#include <net/checksum.h>#include <net/ip6_checksum.h>#include <linux/mii.h>#include <linux/ethtool.h>#include <linux/if_vlan.h>#include <linux/prefetch.h> #include "igbvf.h" #define DRV_VERSION "1.0.8-k0"char igbvf_driver_name[] = "igbvf";const char igbvf_driver_version[] = DRV_VERSION;static const char igbvf_driver_string[] =				"Intel(R) Virtual Function Network Driver";static const char igbvf_copyright[] =				"Copyright (c) 2009 - 2010 Intel Corporation."; static int igbvf_poll(struct napi_struct *napi, int budget);static void igbvf_reset(struct igbvf_adapter *);static void igbvf_set_interrupt_capability(struct igbvf_adapter *);static void igbvf_reset_interrupt_capability(struct igbvf_adapter *); static struct igbvf_info igbvf_vf_info = {	.mac                    = e1000_vfadapt,	.flags                  = 0,	.pba                    = 10,	.init_ops               = e1000_init_function_pointers_vf,}; static struct igbvf_info igbvf_i350_vf_info = {	.mac			= e1000_vfadapt_i350,	.flags			= 0,	.pba			= 10,	.init_ops		= e1000_init_function_pointers_vf,}; static const struct igbvf_info *igbvf_info_tbl[] = {	[board_vf]              = &igbvf_vf_info,	[board_i350_vf]		= &igbvf_i350_vf_info,}; /** * igbvf_desc_unused - calculate if we have unused descriptors **/static int igbvf_desc_unused(struct igbvf_ring *ring){	if (ring->next_to_clean > ring->next_to_use)		return ring->next_to_clean - ring->next_to_use - 1; 	return ring->count + ring->next_to_clean - ring->next_to_use - 1;} /** * igbvf_receive_skb - helper function to handle Rx indications * @adapter: board private structure * @status: descriptor status field as written by hardware * @vlan: descriptor vlan field as written by hardware (no le/be conversion) * @skb: pointer to sk_buff to be indicated to stack **/static void igbvf_receive_skb(struct igbvf_adapter *adapter,                              struct net_device *netdev,                              struct sk_buff *skb,                              u32 status, u16 vlan){	if (adapter->vlgrp && (status & E1000_RXD_STAT_VP))		vlan_hwaccel_receive_skb(skb, adapter->vlgrp,		                         le16_to_cpu(vlan) &		                         E1000_RXD_SPC_VLAN_MASK);	else		netif_receive_skb(skb);} static inline void igbvf_rx_checksum_adv(struct igbvf_adapter *adapter,                                         u32 status_err, struct sk_buff *skb){	skb_checksum_none_assert(skb); 	/* Ignore Checksum bit is set or checksum is disabled through ethtool */	if ((status_err & E1000_RXD_STAT_IXSM) ||	    (adapter->flags & IGBVF_FLAG_RX_CSUM_DISABLED))		return; 	/* TCP/UDP checksum error bit is set */	if (status_err &	    (E1000_RXDEXT_STATERR_TCPE | E1000_RXDEXT_STATERR_IPE)) {		/* let the stack verify checksum errors */		adapter->hw_csum_err++;		return;	} 	/* It must be a TCP or UDP packet with a valid checksum */	if (status_err & (E1000_RXD_STAT_TCPCS | E1000_RXD_STAT_UDPCS))		skb->ip_summed = CHECKSUM_UNNECESSARY; 	adapter->hw_csum_good++;} /** * igbvf_alloc_rx_buffers - Replace used receive buffers; packet split * @rx_ring: address of ring structure to repopulate * @cleaned_count: number of buffers to repopulate **/static void igbvf_alloc_rx_buffers(struct igbvf_ring *rx_ring,                                   int cleaned_count){	struct igbvf_adapter *adapter = rx_ring->adapter;	struct net_device *netdev = adapter->netdev;	struct pci_dev *pdev = adapter->pdev;	union e1000_adv_rx_desc *rx_desc;	struct igbvf_buffer *buffer_info;	struct sk_buff *skb;	unsigned int i;	int bufsz; 	i = rx_ring->next_to_use;	buffer_info = &rx_ring->buffer_info[i]; 	if (adapter->rx_ps_hdr_size)		bufsz = adapter->rx_ps_hdr_size;	else		bufsz = adapter->rx_buffer_len; 	while (cleaned_count--) {		rx_desc = IGBVF_RX_DESC_ADV(*rx_ring, i); 		if (adapter->rx_ps_hdr_size && !buffer_info->page_dma) {			if (!buffer_info->page) {				buffer_info->page = alloc_page(GFP_ATOMIC);				if (!buffer_info->page) {					adapter->alloc_rx_buff_failed++;					goto no_buffers;				}				buffer_info->page_offset = 0;			} else {				buffer_info->page_offset ^= PAGE_SIZE / 2;			}			buffer_info->page_dma =				dma_map_page(&pdev->dev, buffer_info->page,				             buffer_info->page_offset,				             PAGE_SIZE / 2,					     DMA_FROM_DEVICE);		} 		if (!buffer_info->skb) {			skb = netdev_alloc_skb_ip_align(netdev, bufsz);			if (!skb) {				adapter->alloc_rx_buff_failed++;				goto no_buffers;			} 			buffer_info->skb = skb;			buffer_info->dma = dma_map_single(&pdev->dev, skb->data,			                                  bufsz,							  DMA_FROM_DEVICE);		}		/* Refresh the desc even if buffer_addrs didn't change because		 * each write-back erases this info. */		if (adapter->rx_ps_hdr_size) {			rx_desc->read.pkt_addr =			     cpu_to_le64(buffer_info->page_dma);			rx_desc->read.hdr_addr = cpu_to_le64(buffer_info->dma);		} else {			rx_desc->read.pkt_addr =			     cpu_to_le64(buffer_info->dma);			rx_desc->read.hdr_addr = 0;		} 		i++;		if (i == rx_ring->count)			i = 0;		buffer_info = &rx_ring->buffer_info[i];	} no_buffers:	if (rx_ring->next_to_use != i) {		rx_ring->next_to_use = i;		if (i == 0)			i = (rx_ring->count - 1);		else			i--; 		/* Force memory writes to complete before letting h/w		 * know there are new descriptors to fetch.  (Only		 * applicable for weak-ordered memory model archs,		 * such as IA-64). */		wmb();		writel(i, adapter->hw.hw_addr + rx_ring->tail);	}} /** * igbvf_clean_rx_irq - Send received data up the network stack; legacy * @adapter: board private structure * * the return value indicates whether actual cleaning was done, there * is no guarantee that everything was cleaned **/static bool igbvf_clean_rx_irq(struct igbvf_adapter *adapter,                               int *work_done, int work_to_do){	struct igbvf_ring *rx_ring = adapter->rx_ring;	struct net_device *netdev = adapter->netdev;	struct pci_dev *pdev = adapter->pdev;	union e1000_adv_rx_desc *rx_desc, *next_rxd;	struct igbvf_buffer *buffer_info, *next_buffer;	struct sk_buff *skb;	bool cleaned = false;	int cleaned_count = 0;	unsigned int total_bytes = 0, total_packets = 0;	unsigned int i;	u32 length, hlen, staterr; 	i = rx_ring->next_to_clean;	rx_desc = IGBVF_RX_DESC_ADV(*rx_ring, i);	staterr = le32_to_cpu(rx_desc->wb.upper.status_error); 	while (staterr & E1000_RXD_STAT_DD) {		if (*work_done >= work_to_do)			break;		(*work_done)++;		rmb(); /* read descriptor and rx_buffer_info after status DD */ 		buffer_info = &rx_ring->buffer_info[i]; 		/* HW will not DMA in data larger than the given buffer, even		 * if it parses the (NFS, of course) header to be larger.  In		 * that case, it fills the header buffer and spills the rest		 * into the page.		 */		hlen = (le16_to_cpu(rx_desc->wb.lower.lo_dword.hs_rss.hdr_info) &		  E1000_RXDADV_HDRBUFLEN_MASK) >> E1000_RXDADV_HDRBUFLEN_SHIFT;		if (hlen > adapter->rx_ps_hdr_size)			hlen = adapter->rx_ps_hdr_size; 		length = le16_to_cpu(rx_desc->wb.upper.length);		cleaned = true;		cleaned_count++; 		skb = buffer_info->skb;		prefetch(skb->data - NET_IP_ALIGN);		buffer_info->skb = NULL;		if (!adapter->rx_ps_hdr_size) {			dma_unmap_single(&pdev->dev, buffer_info->dma,			                 adapter->rx_buffer_len,					 DMA_FROM_DEVICE);			buffer_info->dma = 0;			skb_put(skb, length);			goto send_up;		} 		if (!skb_shinfo(skb)->nr_frags) {			dma_unmap_single(&pdev->dev, buffer_info->dma,			                 adapter->rx_ps_hdr_size,					 DMA_FROM_DEVICE);			skb_put(skb, hlen);		} 		if (length) {			dma_unmap_page(&pdev->dev, buffer_info->page_dma,			               PAGE_SIZE / 2,				       DMA_FROM_DEVICE);			buffer_info->page_dma = 0; 			skb_fill_page_desc(skb, skb_shinfo(skb)->nr_frags,			                   buffer_info->page,			                   buffer_info->page_offset,			                   length); 			if ((adapter->rx_buffer_len > (PAGE_SIZE / 2)) ||			    (page_count(buffer_info->page) != 1))				buffer_info->page = NULL;			else				get_page(buffer_info->page); 			skb->len += length;			skb->data_len += length;			skb->truesize += length;		}send_up:		i++;		if (i == rx_ring->count)			i = 0;		next_rxd = IGBVF_RX_DESC_ADV(*rx_ring, i);		prefetch(next_rxd);		next_buffer = &rx_ring->buffer_info[i]; 		if (!(staterr & E1000_RXD_STAT_EOP)) {			buffer_info->skb = next_buffer->skb;			buffer_info->dma = next_buffer->dma;			next_buffer->skb = skb;			next_buffer->dma = 0;			goto next_desc;		} 		if (staterr & E1000_RXDEXT_ERR_FRAME_ERR_MASK) {			dev_kfree_skb_irq(skb);			goto next_desc;		} 		total_bytes += skb->len;		total_packets++; 		igbvf_rx_checksum_adv(adapter, staterr, skb); 		skb->protocol = eth_type_trans(skb, netdev); 		igbvf_receive_skb(adapter, netdev, skb, staterr,		                  rx_desc->wb.upper.vlan); next_desc:		rx_desc->wb.upper.status_error = 0; 		/* return some buffers to hardware, one at a time is too slow */		if (cleaned_count >= IGBVF_RX_BUFFER_WRITE) {			igbvf_alloc_rx_buffers(rx_ring, cleaned_count);			cleaned_count = 0;		} 		/* use prefetched values */		rx_desc = next_rxd;		buffer_info = next_buffer; 		staterr = le32_to_cpu(rx_desc->wb.upper.status_error);	} 	rx_ring->next_to_clean = i;	cleaned_count = igbvf_desc_unused(rx_ring); 	if (cleaned_count)		igbvf_alloc_rx_buffers(rx_ring, cleaned_count); 	adapter->total_rx_packets += total_packets;	adapter->total_rx_bytes += total_bytes;	adapter->net_stats.rx_bytes += total_bytes;	adapter->net_stats.rx_packets += total_packets;	return cleaned;} static void igbvf_put_txbuf(struct igbvf_adapter *adapter,                            struct igbvf_buffer *buffer_info){	if (buffer_info->dma) {		if (buffer_info->mapped_as_page)			dma_unmap_page(&adapter->pdev->dev,				       buffer_info->dma,				       buffer_info->length,				       DMA_TO_DEVICE);		else			dma_unmap_single(&adapter->pdev->dev,					 buffer_info->dma,					 buffer_info->length,					 DMA_TO_DEVICE);		buffer_info->dma = 0;	}	if (buffer_info->skb) {		dev_kfree_skb_any(buffer_info->skb);		buffer_info->skb = NULL;	}	buffer_info->time_stamp = 0;} /** * igbvf_setup_tx_resources - allocate Tx resources (Descriptors) * @adapter: board private structure * * Return 0 on success, negative on failure **/int igbvf_setup_tx_resources(struct igbvf_adapter *adapter,                             struct igbvf_ring *tx_ring){	struct pci_dev *pdev = adapter->pdev;	int size; 	size = sizeof(struct igbvf_buffer) * tx_ring->count;	tx_ring->buffer_info = vzalloc(size);	if (!tx_ring->buffer_info)		goto err; 	/* round up to nearest 4K */	tx_ring->size = tx_ring->count * sizeof(union e1000_adv_tx_desc);	tx_ring->size = ALIGN(tx_ring->size, 4096); 	tx_ring->desc = dma_alloc_coherent(&pdev->dev, tx_ring->size,					   &tx_ring->dma, GFP_KERNEL); 	if (!tx_ring->desc)		goto err; 	tx_ring->adapter = adapter;	tx_ring->next_to_use = 0;	tx_ring->next_to_clean = 0; 	return 0;err:	vfree(tx_ring->buffer_info);	dev_err(&adapter->pdev->dev,	        "Unable to allocate memory for the transmit descriptor ring\n");	return -ENOMEM;} /** * igbvf_setup_rx_resources - allocate Rx resources (Descriptors) * @adapter: board private structure * * Returns 0 on success, negative on failure **/int igbvf_setup_rx_resources(struct igbvf_adapter *adapter,			     struct igbvf_ring *rx_ring){	struct pci_dev *pdev = adapter->pdev;	int size, desc_len; 	size = sizeof(struct igbvf_buffer) * rx_ring->count;	rx_ring->buffer_info = vzalloc(size);	if (!rx_ring->buffer_info)		goto err; 	desc_len = sizeof(union e1000_adv_rx_desc); 	/* Round up to nearest 4K */	rx_ring->size = rx_ring->count * desc_len;	rx_ring->size = ALIGN(rx_ring->size, 4096); 	rx_ring->desc = dma_alloc_coherent(&pdev->dev, rx_ring->size,					   &rx_ring->dma, GFP_KERNEL); 	if (!rx_ring->desc)		goto err; 	rx_ring->next_to_clean = 0;	rx_ring->next_to_use = 0; 	rx_ring->adapter = adapter; 	return 0; err:	vfree(rx_ring->buffer_info);	rx_ring->buffer_info = NULL;	dev_err(&adapter->pdev->dev,	        "Unable to allocate memory for the receive descriptor ring\n");	return -ENOMEM;} /** * igbvf_clean_tx_ring - Free Tx Buffers * @tx_ring: ring to be cleaned **/static void igbvf_clean_tx_ring(struct igbvf_ring *tx_ring){	struct igbvf_adapter *adapter = tx_ring->adapter;	struct igbvf_buffer *buffer_info;	unsigned long size;	unsigned int i; 	if (!tx_ring->buffer_info)		return; 	/* Free all the Tx ring sk_buffs */	for (i = 0; i < tx_ring->count; i++) {		buffer_info = &tx_ring->buffer_info[i];		igbvf_put_txbuf(adapter, buffer_info);

Lines 1–500 of 2873.