2991 lines · 77.5 KB · C
RawDownload
// SPDX-License-Identifier: GPL-2.0/* Copyright(c) 2009 - 2018 Intel Corporation. */ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt #include <linux/bitfield.h>#include <linux/delay.h>#include <linux/ethtool.h>#include <linux/if_vlan.h>#include <linux/init.h>#include <linux/ipv6.h>#include <linux/mii.h>#include <linux/module.h>#include <linux/netdevice.h>#include <linux/pagemap.h>#include <linux/pci.h>#include <linux/prefetch.h>#include <linux/sctp.h>#include <linux/slab.h>#include <linux/tcp.h>#include <linux/types.h>#include <linux/vmalloc.h>#include <net/checksum.h>#include <net/ip6_checksum.h>#include "igbvf.h" char igbvf_driver_name[] = "igbvf";static const char igbvf_driver_string[] =		  "Intel(R) Gigabit Virtual Function Network Driver";static const char igbvf_copyright[] =		  "Copyright (c) 2009 - 2012 Intel Corporation."; #define DEFAULT_MSG_ENABLE (NETIF_MSG_DRV|NETIF_MSG_PROBE|NETIF_MSG_LINK)static int debug = -1;module_param(debug, int, 0);MODULE_PARM_DESC(debug, "Debug level (0=none,...,16=all)"); 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 * @ring: address of receive ring structure **/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 * @netdev: pointer to netdev struct * @skb: skb to indicate to stack * @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, __le16 vlan){	u16 vid; 	if (status & E1000_RXD_STAT_VP) {		if ((adapter->flags & IGBVF_FLAG_RX_LB_VLAN_BSWAP) &&		    (status & E1000_RXDEXT_STATERR_LB))			vid = be16_to_cpu((__force __be16)vlan) & E1000_RXD_SPC_VLAN_MASK;		else			vid = le16_to_cpu(vlan) & E1000_RXD_SPC_VLAN_MASK;		if (test_bit(vid, adapter->active_vlans))			__vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), vid);	} 	napi_gro_receive(&adapter->rx_ring->napi, 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 (dma_mapping_error(&pdev->dev,					      buffer_info->page_dma)) {				__free_page(buffer_info->page);				buffer_info->page = NULL;				dev_err(&pdev->dev, "RX DMA map failed\n");				break;			}		} 		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);			if (dma_mapping_error(&pdev->dev, buffer_info->dma)) {				dev_kfree_skb(buffer_info->skb);				buffer_info->skb = NULL;				dev_err(&pdev->dev, "RX DMA map failed\n");				goto no_buffers;			}		}		/* 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 * @work_done: output parameter used to indicate completed work * @work_to_do: input parameter setting limit of work * * 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_get_bits(rx_desc->wb.lower.lo_dword.hs_rss.hdr_info,				     E1000_RXDADV_HDRBUFLEN_MASK);		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);			buffer_info->dma = 0;			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 += PAGE_SIZE / 2;		}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;	netdev->stats.rx_bytes += total_bytes;	netdev->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 * @tx_ring: ring being initialized * * 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 * @rx_ring: ring being initialized * * 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;

Lines 1–500 of 2991.

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t