mirror of
				https://github.com/AetherDroid/android_kernel_samsung_on5xelte.git
				synced 2025-10-31 08:08:51 +01:00 
			
		
		
		
	Fixed MTP to work with TWRP
This commit is contained in:
		
						commit
						f6dfaef42e
					
				
					 50820 changed files with 20846062 additions and 0 deletions
				
			
		
							
								
								
									
										44
									
								
								drivers/net/ethernet/intel/ixgbe/Makefile
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								drivers/net/ethernet/intel/ixgbe/Makefile
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,44 @@ | |||
| ################################################################################
 | ||||
| #
 | ||||
| # Intel 10 Gigabit PCI Express Linux driver
 | ||||
| # Copyright(c) 1999 - 2013 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:
 | ||||
| # Linux NICS <linux.nics@intel.com>
 | ||||
| # e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
 | ||||
| # Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
 | ||||
| #
 | ||||
| ################################################################################
 | ||||
| 
 | ||||
| #
 | ||||
| # Makefile for the Intel(R) 10GbE PCI Express ethernet driver
 | ||||
| #
 | ||||
| 
 | ||||
| obj-$(CONFIG_IXGBE) += ixgbe.o | ||||
| 
 | ||||
| ixgbe-objs := ixgbe_main.o ixgbe_common.o ixgbe_ethtool.o \
 | ||||
|               ixgbe_82599.o ixgbe_82598.o ixgbe_phy.o ixgbe_sriov.o \
 | ||||
|               ixgbe_mbx.o ixgbe_x540.o ixgbe_lib.o ixgbe_ptp.o | ||||
| 
 | ||||
| ixgbe-$(CONFIG_IXGBE_DCB) +=  ixgbe_dcb.o ixgbe_dcb_82598.o \
 | ||||
|                               ixgbe_dcb_82599.o ixgbe_dcb_nl.o | ||||
| 
 | ||||
| ixgbe-$(CONFIG_IXGBE_HWMON) += ixgbe_sysfs.o | ||||
| ixgbe-$(CONFIG_DEBUG_FS) += ixgbe_debugfs.o | ||||
| ixgbe-$(CONFIG_FCOE:m=y) += ixgbe_fcoe.o | ||||
							
								
								
									
										940
									
								
								drivers/net/ethernet/intel/ixgbe/ixgbe.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										940
									
								
								drivers/net/ethernet/intel/ixgbe/ixgbe.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,940 @@ | |||
| /*******************************************************************************
 | ||||
| 
 | ||||
|   Intel 10 Gigabit PCI Express Linux driver | ||||
|   Copyright(c) 1999 - 2013 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: | ||||
|   Linux NICS <linux.nics@intel.com> | ||||
|   e1000-devel Mailing List <e1000-devel@lists.sourceforge.net> | ||||
|   Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 | ||||
| 
 | ||||
| *******************************************************************************/ | ||||
| 
 | ||||
| #ifndef _IXGBE_H_ | ||||
| #define _IXGBE_H_ | ||||
| 
 | ||||
| #include <linux/bitops.h> | ||||
| #include <linux/types.h> | ||||
| #include <linux/pci.h> | ||||
| #include <linux/netdevice.h> | ||||
| #include <linux/cpumask.h> | ||||
| #include <linux/aer.h> | ||||
| #include <linux/if_vlan.h> | ||||
| #include <linux/jiffies.h> | ||||
| 
 | ||||
| #include <linux/clocksource.h> | ||||
| #include <linux/net_tstamp.h> | ||||
| #include <linux/ptp_clock_kernel.h> | ||||
| 
 | ||||
| #include "ixgbe_type.h" | ||||
| #include "ixgbe_common.h" | ||||
| #include "ixgbe_dcb.h" | ||||
| #if defined(CONFIG_FCOE) || defined(CONFIG_FCOE_MODULE) | ||||
| #define IXGBE_FCOE | ||||
| #include "ixgbe_fcoe.h" | ||||
| #endif /* CONFIG_FCOE or CONFIG_FCOE_MODULE */ | ||||
| #ifdef CONFIG_IXGBE_DCA | ||||
| #include <linux/dca.h> | ||||
| #endif | ||||
| 
 | ||||
| #include <net/busy_poll.h> | ||||
| 
 | ||||
| #ifdef CONFIG_NET_RX_BUSY_POLL | ||||
| #define BP_EXTENDED_STATS | ||||
| #endif | ||||
| /* common prefix used by pr_<> macros */ | ||||
| #undef pr_fmt | ||||
| #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||||
| 
 | ||||
| /* TX/RX descriptor defines */ | ||||
| #define IXGBE_DEFAULT_TXD		    512 | ||||
| #define IXGBE_DEFAULT_TX_WORK		    256 | ||||
| #define IXGBE_MAX_TXD			   4096 | ||||
| #define IXGBE_MIN_TXD			     64 | ||||
| 
 | ||||
| #if (PAGE_SIZE < 8192) | ||||
| #define IXGBE_DEFAULT_RXD		    512 | ||||
| #else | ||||
| #define IXGBE_DEFAULT_RXD		    128 | ||||
| #endif | ||||
| #define IXGBE_MAX_RXD			   4096 | ||||
| #define IXGBE_MIN_RXD			     64 | ||||
| 
 | ||||
| /* flow control */ | ||||
| #define IXGBE_MIN_FCRTL			   0x40 | ||||
| #define IXGBE_MAX_FCRTL			0x7FF80 | ||||
| #define IXGBE_MIN_FCRTH			  0x600 | ||||
| #define IXGBE_MAX_FCRTH			0x7FFF0 | ||||
| #define IXGBE_DEFAULT_FCPAUSE		 0xFFFF | ||||
| #define IXGBE_MIN_FCPAUSE		      0 | ||||
| #define IXGBE_MAX_FCPAUSE		 0xFFFF | ||||
| 
 | ||||
| /* Supported Rx Buffer Sizes */ | ||||
| #define IXGBE_RXBUFFER_256    256  /* Used for skb receive header */ | ||||
| #define IXGBE_RXBUFFER_2K    2048 | ||||
| #define IXGBE_RXBUFFER_3K    3072 | ||||
| #define IXGBE_RXBUFFER_4K    4096 | ||||
| #define IXGBE_MAX_RXBUFFER  16384  /* largest size for a single descriptor */ | ||||
| 
 | ||||
| /*
 | ||||
|  * NOTE: netdev_alloc_skb reserves up to 64 bytes, NET_IP_ALIGN means we | ||||
|  * reserve 64 more, and skb_shared_info adds an additional 320 bytes more, | ||||
|  * this adds up to 448 bytes of extra data. | ||||
|  * | ||||
|  * Since netdev_alloc_skb now allocates a page fragment we can use a value | ||||
|  * of 256 and the resultant skb will have a truesize of 960 or less. | ||||
|  */ | ||||
| #define IXGBE_RX_HDR_SIZE IXGBE_RXBUFFER_256 | ||||
| 
 | ||||
| /* How many Rx Buffers do we bundle into one write to the hardware ? */ | ||||
| #define IXGBE_RX_BUFFER_WRITE	16	/* Must be power of 2 */ | ||||
| 
 | ||||
| enum ixgbe_tx_flags { | ||||
| 	/* cmd_type flags */ | ||||
| 	IXGBE_TX_FLAGS_HW_VLAN	= 0x01, | ||||
| 	IXGBE_TX_FLAGS_TSO	= 0x02, | ||||
| 	IXGBE_TX_FLAGS_TSTAMP	= 0x04, | ||||
| 
 | ||||
| 	/* olinfo flags */ | ||||
| 	IXGBE_TX_FLAGS_CC	= 0x08, | ||||
| 	IXGBE_TX_FLAGS_IPV4	= 0x10, | ||||
| 	IXGBE_TX_FLAGS_CSUM	= 0x20, | ||||
| 
 | ||||
| 	/* software defined flags */ | ||||
| 	IXGBE_TX_FLAGS_SW_VLAN	= 0x40, | ||||
| 	IXGBE_TX_FLAGS_FCOE	= 0x80, | ||||
| }; | ||||
| 
 | ||||
| /* VLAN info */ | ||||
| #define IXGBE_TX_FLAGS_VLAN_MASK	0xffff0000 | ||||
| #define IXGBE_TX_FLAGS_VLAN_PRIO_MASK	0xe0000000 | ||||
| #define IXGBE_TX_FLAGS_VLAN_PRIO_SHIFT  29 | ||||
| #define IXGBE_TX_FLAGS_VLAN_SHIFT	16 | ||||
| 
 | ||||
| #define IXGBE_MAX_VF_MC_ENTRIES         30 | ||||
| #define IXGBE_MAX_VF_FUNCTIONS          64 | ||||
| #define IXGBE_MAX_VFTA_ENTRIES          128 | ||||
| #define MAX_EMULATION_MAC_ADDRS         16 | ||||
| #define IXGBE_MAX_PF_MACVLANS           15 | ||||
| #define VMDQ_P(p)   ((p) + adapter->ring_feature[RING_F_VMDQ].offset) | ||||
| #define IXGBE_82599_VF_DEVICE_ID        0x10ED | ||||
| #define IXGBE_X540_VF_DEVICE_ID         0x1515 | ||||
| 
 | ||||
| struct vf_data_storage { | ||||
| 	unsigned char vf_mac_addresses[ETH_ALEN]; | ||||
| 	u16 vf_mc_hashes[IXGBE_MAX_VF_MC_ENTRIES]; | ||||
| 	u16 num_vf_mc_hashes; | ||||
| 	u16 default_vf_vlan_id; | ||||
| 	u16 vlans_enabled; | ||||
| 	bool clear_to_send; | ||||
| 	bool pf_set_mac; | ||||
| 	u16 pf_vlan; /* When set, guest VLAN config not allowed. */ | ||||
| 	u16 pf_qos; | ||||
| 	u16 tx_rate; | ||||
| 	u16 vlan_count; | ||||
| 	u8 spoofchk_enabled; | ||||
| 	unsigned int vf_api; | ||||
| }; | ||||
| 
 | ||||
| struct vf_macvlans { | ||||
| 	struct list_head l; | ||||
| 	int vf; | ||||
| 	bool free; | ||||
| 	bool is_macvlan; | ||||
| 	u8 vf_macvlan[ETH_ALEN]; | ||||
| }; | ||||
| 
 | ||||
| #define IXGBE_MAX_TXD_PWR	14 | ||||
| #define IXGBE_MAX_DATA_PER_TXD	(1 << IXGBE_MAX_TXD_PWR) | ||||
| 
 | ||||
| /* Tx Descriptors needed, worst case */ | ||||
| #define TXD_USE_COUNT(S) DIV_ROUND_UP((S), IXGBE_MAX_DATA_PER_TXD) | ||||
| #define DESC_NEEDED (MAX_SKB_FRAGS + 4) | ||||
| 
 | ||||
| /* wrapper around a pointer to a socket buffer,
 | ||||
|  * so a DMA handle can be stored along with the buffer */ | ||||
| struct ixgbe_tx_buffer { | ||||
| 	union ixgbe_adv_tx_desc *next_to_watch; | ||||
| 	unsigned long time_stamp; | ||||
| 	struct sk_buff *skb; | ||||
| 	unsigned int bytecount; | ||||
| 	unsigned short gso_segs; | ||||
| 	__be16 protocol; | ||||
| 	DEFINE_DMA_UNMAP_ADDR(dma); | ||||
| 	DEFINE_DMA_UNMAP_LEN(len); | ||||
| 	u32 tx_flags; | ||||
| }; | ||||
| 
 | ||||
| struct ixgbe_rx_buffer { | ||||
| 	struct sk_buff *skb; | ||||
| 	dma_addr_t dma; | ||||
| 	struct page *page; | ||||
| 	unsigned int page_offset; | ||||
| }; | ||||
| 
 | ||||
| struct ixgbe_queue_stats { | ||||
| 	u64 packets; | ||||
| 	u64 bytes; | ||||
| #ifdef BP_EXTENDED_STATS | ||||
| 	u64 yields; | ||||
| 	u64 misses; | ||||
| 	u64 cleaned; | ||||
| #endif  /* BP_EXTENDED_STATS */ | ||||
| }; | ||||
| 
 | ||||
| struct ixgbe_tx_queue_stats { | ||||
| 	u64 restart_queue; | ||||
| 	u64 tx_busy; | ||||
| 	u64 tx_done_old; | ||||
| }; | ||||
| 
 | ||||
| struct ixgbe_rx_queue_stats { | ||||
| 	u64 rsc_count; | ||||
| 	u64 rsc_flush; | ||||
| 	u64 non_eop_descs; | ||||
| 	u64 alloc_rx_page_failed; | ||||
| 	u64 alloc_rx_buff_failed; | ||||
| 	u64 csum_err; | ||||
| }; | ||||
| 
 | ||||
| enum ixgbe_ring_state_t { | ||||
| 	__IXGBE_TX_FDIR_INIT_DONE, | ||||
| 	__IXGBE_TX_XPS_INIT_DONE, | ||||
| 	__IXGBE_TX_DETECT_HANG, | ||||
| 	__IXGBE_HANG_CHECK_ARMED, | ||||
| 	__IXGBE_RX_RSC_ENABLED, | ||||
| 	__IXGBE_RX_CSUM_UDP_ZERO_ERR, | ||||
| 	__IXGBE_RX_FCOE, | ||||
| }; | ||||
| 
 | ||||
| struct ixgbe_fwd_adapter { | ||||
| 	unsigned long active_vlans[BITS_TO_LONGS(VLAN_N_VID)]; | ||||
| 	struct net_device *netdev; | ||||
| 	struct ixgbe_adapter *real_adapter; | ||||
| 	unsigned int tx_base_queue; | ||||
| 	unsigned int rx_base_queue; | ||||
| 	int pool; | ||||
| }; | ||||
| 
 | ||||
| #define check_for_tx_hang(ring) \ | ||||
| 	test_bit(__IXGBE_TX_DETECT_HANG, &(ring)->state) | ||||
| #define set_check_for_tx_hang(ring) \ | ||||
| 	set_bit(__IXGBE_TX_DETECT_HANG, &(ring)->state) | ||||
| #define clear_check_for_tx_hang(ring) \ | ||||
| 	clear_bit(__IXGBE_TX_DETECT_HANG, &(ring)->state) | ||||
| #define ring_is_rsc_enabled(ring) \ | ||||
| 	test_bit(__IXGBE_RX_RSC_ENABLED, &(ring)->state) | ||||
| #define set_ring_rsc_enabled(ring) \ | ||||
| 	set_bit(__IXGBE_RX_RSC_ENABLED, &(ring)->state) | ||||
| #define clear_ring_rsc_enabled(ring) \ | ||||
| 	clear_bit(__IXGBE_RX_RSC_ENABLED, &(ring)->state) | ||||
| struct ixgbe_ring { | ||||
| 	struct ixgbe_ring *next;	/* pointer to next ring in q_vector */ | ||||
| 	struct ixgbe_q_vector *q_vector; /* backpointer to host q_vector */ | ||||
| 	struct net_device *netdev;	/* netdev ring belongs to */ | ||||
| 	struct device *dev;		/* device for DMA mapping */ | ||||
| 	struct ixgbe_fwd_adapter *l2_accel_priv; | ||||
| 	void *desc;			/* descriptor ring memory */ | ||||
| 	union { | ||||
| 		struct ixgbe_tx_buffer *tx_buffer_info; | ||||
| 		struct ixgbe_rx_buffer *rx_buffer_info; | ||||
| 	}; | ||||
| 	unsigned long state; | ||||
| 	u8 __iomem *tail; | ||||
| 	dma_addr_t dma;			/* phys. address of descriptor ring */ | ||||
| 	unsigned int size;		/* length in bytes */ | ||||
| 
 | ||||
| 	u16 count;			/* amount of descriptors */ | ||||
| 
 | ||||
| 	u8 queue_index; /* needed for multiqueue queue management */ | ||||
| 	u8 reg_idx;			/* holds the special value that gets
 | ||||
| 					 * the hardware register offset | ||||
| 					 * associated with this ring, which is | ||||
| 					 * different for DCB and RSS modes | ||||
| 					 */ | ||||
| 	u16 next_to_use; | ||||
| 	u16 next_to_clean; | ||||
| 
 | ||||
| 	union { | ||||
| 		u16 next_to_alloc; | ||||
| 		struct { | ||||
| 			u8 atr_sample_rate; | ||||
| 			u8 atr_count; | ||||
| 		}; | ||||
| 	}; | ||||
| 
 | ||||
| 	u8 dcb_tc; | ||||
| 	struct ixgbe_queue_stats stats; | ||||
| 	struct u64_stats_sync syncp; | ||||
| 	union { | ||||
| 		struct ixgbe_tx_queue_stats tx_stats; | ||||
| 		struct ixgbe_rx_queue_stats rx_stats; | ||||
| 	}; | ||||
| } ____cacheline_internodealigned_in_smp; | ||||
| 
 | ||||
| enum ixgbe_ring_f_enum { | ||||
| 	RING_F_NONE = 0, | ||||
| 	RING_F_VMDQ,  /* SR-IOV uses the same ring feature */ | ||||
| 	RING_F_RSS, | ||||
| 	RING_F_FDIR, | ||||
| #ifdef IXGBE_FCOE | ||||
| 	RING_F_FCOE, | ||||
| #endif /* IXGBE_FCOE */ | ||||
| 
 | ||||
| 	RING_F_ARRAY_SIZE      /* must be last in enum set */ | ||||
| }; | ||||
| 
 | ||||
| #define IXGBE_MAX_RSS_INDICES  16 | ||||
| #define IXGBE_MAX_VMDQ_INDICES 64 | ||||
| #define IXGBE_MAX_FDIR_INDICES 63	/* based on q_vector limit */ | ||||
| #define IXGBE_MAX_FCOE_INDICES  8 | ||||
| #define MAX_RX_QUEUES (IXGBE_MAX_FDIR_INDICES + 1) | ||||
| #define MAX_TX_QUEUES (IXGBE_MAX_FDIR_INDICES + 1) | ||||
| #define IXGBE_MAX_L2A_QUEUES 4 | ||||
| #define IXGBE_BAD_L2A_QUEUE 3 | ||||
| #define IXGBE_MAX_MACVLANS	31 | ||||
| #define IXGBE_MAX_DCBMACVLANS	8 | ||||
| 
 | ||||
| struct ixgbe_ring_feature { | ||||
| 	u16 limit;	/* upper limit on feature indices */ | ||||
| 	u16 indices;	/* current value of indices */ | ||||
| 	u16 mask;	/* Mask used for feature to ring mapping */ | ||||
| 	u16 offset;	/* offset to start of feature */ | ||||
| } ____cacheline_internodealigned_in_smp; | ||||
| 
 | ||||
| #define IXGBE_82599_VMDQ_8Q_MASK 0x78 | ||||
| #define IXGBE_82599_VMDQ_4Q_MASK 0x7C | ||||
| #define IXGBE_82599_VMDQ_2Q_MASK 0x7E | ||||
| 
 | ||||
| /*
 | ||||
|  * FCoE requires that all Rx buffers be over 2200 bytes in length.  Since | ||||
|  * this is twice the size of a half page we need to double the page order | ||||
|  * for FCoE enabled Rx queues. | ||||
|  */ | ||||
| static inline unsigned int ixgbe_rx_bufsz(struct ixgbe_ring *ring) | ||||
| { | ||||
| #ifdef IXGBE_FCOE | ||||
| 	if (test_bit(__IXGBE_RX_FCOE, &ring->state)) | ||||
| 		return (PAGE_SIZE < 8192) ? IXGBE_RXBUFFER_4K : | ||||
| 					    IXGBE_RXBUFFER_3K; | ||||
| #endif | ||||
| 	return IXGBE_RXBUFFER_2K; | ||||
| } | ||||
| 
 | ||||
| static inline unsigned int ixgbe_rx_pg_order(struct ixgbe_ring *ring) | ||||
| { | ||||
| #ifdef IXGBE_FCOE | ||||
| 	if (test_bit(__IXGBE_RX_FCOE, &ring->state)) | ||||
| 		return (PAGE_SIZE < 8192) ? 1 : 0; | ||||
| #endif | ||||
| 	return 0; | ||||
| } | ||||
| #define ixgbe_rx_pg_size(_ring) (PAGE_SIZE << ixgbe_rx_pg_order(_ring)) | ||||
| 
 | ||||
| struct ixgbe_ring_container { | ||||
| 	struct ixgbe_ring *ring;	/* pointer to linked list of rings */ | ||||
| 	unsigned int total_bytes;	/* total bytes processed this int */ | ||||
| 	unsigned int total_packets;	/* total packets processed this int */ | ||||
| 	u16 work_limit;			/* total work allowed per interrupt */ | ||||
| 	u8 count;			/* total number of rings in vector */ | ||||
| 	u8 itr;				/* current ITR setting for ring */ | ||||
| }; | ||||
| 
 | ||||
| /* iterator for handling rings in ring container */ | ||||
| #define ixgbe_for_each_ring(pos, head) \ | ||||
| 	for (pos = (head).ring; pos != NULL; pos = pos->next) | ||||
| 
 | ||||
| #define MAX_RX_PACKET_BUFFERS ((adapter->flags & IXGBE_FLAG_DCB_ENABLED) \ | ||||
| 			      ? 8 : 1) | ||||
| #define MAX_TX_PACKET_BUFFERS MAX_RX_PACKET_BUFFERS | ||||
| 
 | ||||
| /* MAX_Q_VECTORS of these are allocated,
 | ||||
|  * but we only use one per queue-specific vector. | ||||
|  */ | ||||
| struct ixgbe_q_vector { | ||||
| 	struct ixgbe_adapter *adapter; | ||||
| #ifdef CONFIG_IXGBE_DCA | ||||
| 	int cpu;	    /* CPU for DCA */ | ||||
| #endif | ||||
| 	u16 v_idx;		/* index of q_vector within array, also used for
 | ||||
| 				 * finding the bit in EICR and friends that | ||||
| 				 * represents the vector for this ring */ | ||||
| 	u16 itr;		/* Interrupt throttle rate written to EITR */ | ||||
| 	struct ixgbe_ring_container rx, tx; | ||||
| 
 | ||||
| 	struct napi_struct napi; | ||||
| 	cpumask_t affinity_mask; | ||||
| 	int numa_node; | ||||
| 	struct rcu_head rcu;	/* to avoid race with update stats on free */ | ||||
| 	char name[IFNAMSIZ + 9]; | ||||
| 
 | ||||
| #ifdef CONFIG_NET_RX_BUSY_POLL | ||||
| 	atomic_t state; | ||||
| #endif  /* CONFIG_NET_RX_BUSY_POLL */ | ||||
| 
 | ||||
| 	/* for dynamic allocation of rings associated with this q_vector */ | ||||
| 	struct ixgbe_ring ring[0] ____cacheline_internodealigned_in_smp; | ||||
| }; | ||||
| 
 | ||||
| #ifdef CONFIG_NET_RX_BUSY_POLL | ||||
| enum ixgbe_qv_state_t { | ||||
| 	IXGBE_QV_STATE_IDLE = 0, | ||||
| 	IXGBE_QV_STATE_NAPI, | ||||
| 	IXGBE_QV_STATE_POLL, | ||||
| 	IXGBE_QV_STATE_DISABLE | ||||
| }; | ||||
| 
 | ||||
| static inline void ixgbe_qv_init_lock(struct ixgbe_q_vector *q_vector) | ||||
| { | ||||
| 	/* reset state to idle */ | ||||
| 	atomic_set(&q_vector->state, IXGBE_QV_STATE_IDLE); | ||||
| } | ||||
| 
 | ||||
| /* called from the device poll routine to get ownership of a q_vector */ | ||||
| static inline bool ixgbe_qv_lock_napi(struct ixgbe_q_vector *q_vector) | ||||
| { | ||||
| 	int rc = atomic_cmpxchg(&q_vector->state, IXGBE_QV_STATE_IDLE, | ||||
| 				IXGBE_QV_STATE_NAPI); | ||||
| #ifdef BP_EXTENDED_STATS | ||||
| 	if (rc != IXGBE_QV_STATE_IDLE) | ||||
| 		q_vector->tx.ring->stats.yields++; | ||||
| #endif | ||||
| 
 | ||||
| 	return rc == IXGBE_QV_STATE_IDLE; | ||||
| } | ||||
| 
 | ||||
| /* returns true is someone tried to get the qv while napi had it */ | ||||
| static inline void ixgbe_qv_unlock_napi(struct ixgbe_q_vector *q_vector) | ||||
| { | ||||
| 	WARN_ON(atomic_read(&q_vector->state) != IXGBE_QV_STATE_NAPI); | ||||
| 
 | ||||
| 	/* flush any outstanding Rx frames */ | ||||
| 	if (q_vector->napi.gro_list) | ||||
| 		napi_gro_flush(&q_vector->napi, false); | ||||
| 
 | ||||
| 	/* reset state to idle */ | ||||
| 	atomic_set(&q_vector->state, IXGBE_QV_STATE_IDLE); | ||||
| } | ||||
| 
 | ||||
| /* called from ixgbe_low_latency_poll() */ | ||||
| static inline bool ixgbe_qv_lock_poll(struct ixgbe_q_vector *q_vector) | ||||
| { | ||||
| 	int rc = atomic_cmpxchg(&q_vector->state, IXGBE_QV_STATE_IDLE, | ||||
| 				IXGBE_QV_STATE_POLL); | ||||
| #ifdef BP_EXTENDED_STATS | ||||
| 	if (rc != IXGBE_QV_STATE_IDLE) | ||||
| 		q_vector->tx.ring->stats.yields++; | ||||
| #endif | ||||
| 	return rc == IXGBE_QV_STATE_IDLE; | ||||
| } | ||||
| 
 | ||||
| /* returns true if someone tried to get the qv while it was locked */ | ||||
| static inline void ixgbe_qv_unlock_poll(struct ixgbe_q_vector *q_vector) | ||||
| { | ||||
| 	WARN_ON(atomic_read(&q_vector->state) != IXGBE_QV_STATE_POLL); | ||||
| 
 | ||||
| 	/* reset state to idle */ | ||||
| 	atomic_set(&q_vector->state, IXGBE_QV_STATE_IDLE); | ||||
| } | ||||
| 
 | ||||
| /* true if a socket is polling, even if it did not get the lock */ | ||||
| static inline bool ixgbe_qv_busy_polling(struct ixgbe_q_vector *q_vector) | ||||
| { | ||||
| 	return atomic_read(&q_vector->state) == IXGBE_QV_STATE_POLL; | ||||
| } | ||||
| 
 | ||||
| /* false if QV is currently owned */ | ||||
| static inline bool ixgbe_qv_disable(struct ixgbe_q_vector *q_vector) | ||||
| { | ||||
| 	int rc = atomic_cmpxchg(&q_vector->state, IXGBE_QV_STATE_IDLE, | ||||
| 				IXGBE_QV_STATE_DISABLE); | ||||
| 
 | ||||
| 	return rc == IXGBE_QV_STATE_IDLE; | ||||
| } | ||||
| 
 | ||||
| #else /* CONFIG_NET_RX_BUSY_POLL */ | ||||
| static inline void ixgbe_qv_init_lock(struct ixgbe_q_vector *q_vector) | ||||
| { | ||||
| } | ||||
| 
 | ||||
| static inline bool ixgbe_qv_lock_napi(struct ixgbe_q_vector *q_vector) | ||||
| { | ||||
| 	return true; | ||||
| } | ||||
| 
 | ||||
| static inline bool ixgbe_qv_unlock_napi(struct ixgbe_q_vector *q_vector) | ||||
| { | ||||
| 	return false; | ||||
| } | ||||
| 
 | ||||
| static inline bool ixgbe_qv_lock_poll(struct ixgbe_q_vector *q_vector) | ||||
| { | ||||
| 	return false; | ||||
| } | ||||
| 
 | ||||
| static inline bool ixgbe_qv_unlock_poll(struct ixgbe_q_vector *q_vector) | ||||
| { | ||||
| 	return false; | ||||
| } | ||||
| 
 | ||||
| static inline bool ixgbe_qv_busy_polling(struct ixgbe_q_vector *q_vector) | ||||
| { | ||||
| 	return false; | ||||
| } | ||||
| 
 | ||||
| static inline bool ixgbe_qv_disable(struct ixgbe_q_vector *q_vector) | ||||
| { | ||||
| 	return true; | ||||
| } | ||||
| 
 | ||||
| #endif /* CONFIG_NET_RX_BUSY_POLL */ | ||||
| 
 | ||||
| #ifdef CONFIG_IXGBE_HWMON | ||||
| 
 | ||||
| #define IXGBE_HWMON_TYPE_LOC		0 | ||||
| #define IXGBE_HWMON_TYPE_TEMP		1 | ||||
| #define IXGBE_HWMON_TYPE_CAUTION	2 | ||||
| #define IXGBE_HWMON_TYPE_MAX		3 | ||||
| 
 | ||||
| struct hwmon_attr { | ||||
| 	struct device_attribute dev_attr; | ||||
| 	struct ixgbe_hw *hw; | ||||
| 	struct ixgbe_thermal_diode_data *sensor; | ||||
| 	char name[12]; | ||||
| }; | ||||
| 
 | ||||
| struct hwmon_buff { | ||||
| 	struct attribute_group group; | ||||
| 	const struct attribute_group *groups[2]; | ||||
| 	struct attribute *attrs[IXGBE_MAX_SENSORS * 4 + 1]; | ||||
| 	struct hwmon_attr hwmon_list[IXGBE_MAX_SENSORS * 4]; | ||||
| 	unsigned int n_hwmon; | ||||
| }; | ||||
| #endif /* CONFIG_IXGBE_HWMON */ | ||||
| 
 | ||||
| /*
 | ||||
|  * microsecond values for various ITR rates shifted by 2 to fit itr register | ||||
|  * with the first 3 bits reserved 0 | ||||
|  */ | ||||
| #define IXGBE_MIN_RSC_ITR	24 | ||||
| #define IXGBE_100K_ITR		40 | ||||
| #define IXGBE_20K_ITR		200 | ||||
| #define IXGBE_10K_ITR		400 | ||||
| #define IXGBE_8K_ITR		500 | ||||
| 
 | ||||
| /* ixgbe_test_staterr - tests bits in Rx descriptor status and error fields */ | ||||
| static inline __le32 ixgbe_test_staterr(union ixgbe_adv_rx_desc *rx_desc, | ||||
| 					const u32 stat_err_bits) | ||||
| { | ||||
| 	return rx_desc->wb.upper.status_error & cpu_to_le32(stat_err_bits); | ||||
| } | ||||
| 
 | ||||
| static inline u16 ixgbe_desc_unused(struct ixgbe_ring *ring) | ||||
| { | ||||
| 	u16 ntc = ring->next_to_clean; | ||||
| 	u16 ntu = ring->next_to_use; | ||||
| 
 | ||||
| 	return ((ntc > ntu) ? 0 : ring->count) + ntc - ntu - 1; | ||||
| } | ||||
| 
 | ||||
| static inline void ixgbe_write_tail(struct ixgbe_ring *ring, u32 value) | ||||
| { | ||||
| 	writel(value, ring->tail); | ||||
| } | ||||
| 
 | ||||
| #define IXGBE_RX_DESC(R, i)	    \ | ||||
| 	(&(((union ixgbe_adv_rx_desc *)((R)->desc))[i])) | ||||
| #define IXGBE_TX_DESC(R, i)	    \ | ||||
| 	(&(((union ixgbe_adv_tx_desc *)((R)->desc))[i])) | ||||
| #define IXGBE_TX_CTXTDESC(R, i)	    \ | ||||
| 	(&(((struct ixgbe_adv_tx_context_desc *)((R)->desc))[i])) | ||||
| 
 | ||||
| #define IXGBE_MAX_JUMBO_FRAME_SIZE	9728 /* Maximum Supported Size 9.5KB */ | ||||
| #ifdef IXGBE_FCOE | ||||
| /* Use 3K as the baby jumbo frame size for FCoE */ | ||||
| #define IXGBE_FCOE_JUMBO_FRAME_SIZE       3072 | ||||
| #endif /* IXGBE_FCOE */ | ||||
| 
 | ||||
| #define OTHER_VECTOR 1 | ||||
| #define NON_Q_VECTORS (OTHER_VECTOR) | ||||
| 
 | ||||
| #define MAX_MSIX_VECTORS_82599 64 | ||||
| #define MAX_Q_VECTORS_82599 64 | ||||
| #define MAX_MSIX_VECTORS_82598 18 | ||||
| #define MAX_Q_VECTORS_82598 16 | ||||
| 
 | ||||
| struct ixgbe_mac_addr { | ||||
| 	u8 addr[ETH_ALEN]; | ||||
| 	u16 queue; | ||||
| 	u16 state; /* bitmask */ | ||||
| }; | ||||
| #define IXGBE_MAC_STATE_DEFAULT		0x1 | ||||
| #define IXGBE_MAC_STATE_MODIFIED	0x2 | ||||
| #define IXGBE_MAC_STATE_IN_USE		0x4 | ||||
| 
 | ||||
| #define MAX_Q_VECTORS MAX_Q_VECTORS_82599 | ||||
| #define MAX_MSIX_COUNT MAX_MSIX_VECTORS_82599 | ||||
| 
 | ||||
| #define MIN_MSIX_Q_VECTORS 1 | ||||
| #define MIN_MSIX_COUNT (MIN_MSIX_Q_VECTORS + NON_Q_VECTORS) | ||||
| 
 | ||||
| /* default to trying for four seconds */ | ||||
| #define IXGBE_TRY_LINK_TIMEOUT (4 * HZ) | ||||
| 
 | ||||
| /* board specific private data structure */ | ||||
| struct ixgbe_adapter { | ||||
| 	unsigned long active_vlans[BITS_TO_LONGS(VLAN_N_VID)]; | ||||
| 	/* OS defined structs */ | ||||
| 	struct net_device *netdev; | ||||
| 	struct pci_dev *pdev; | ||||
| 
 | ||||
| 	unsigned long state; | ||||
| 
 | ||||
| 	/* Some features need tri-state capability,
 | ||||
| 	 * thus the additional *_CAPABLE flags. | ||||
| 	 */ | ||||
| 	u32 flags; | ||||
| #define IXGBE_FLAG_MSI_ENABLED                  (u32)(1 << 1) | ||||
| #define IXGBE_FLAG_MSIX_ENABLED                 (u32)(1 << 3) | ||||
| #define IXGBE_FLAG_RX_1BUF_CAPABLE              (u32)(1 << 4) | ||||
| #define IXGBE_FLAG_RX_PS_CAPABLE                (u32)(1 << 5) | ||||
| #define IXGBE_FLAG_RX_PS_ENABLED                (u32)(1 << 6) | ||||
| #define IXGBE_FLAG_IN_NETPOLL                   (u32)(1 << 7) | ||||
| #define IXGBE_FLAG_DCA_ENABLED                  (u32)(1 << 8) | ||||
| #define IXGBE_FLAG_DCA_CAPABLE                  (u32)(1 << 9) | ||||
| #define IXGBE_FLAG_IMIR_ENABLED                 (u32)(1 << 10) | ||||
| #define IXGBE_FLAG_MQ_CAPABLE                   (u32)(1 << 11) | ||||
| #define IXGBE_FLAG_DCB_ENABLED                  (u32)(1 << 12) | ||||
| #define IXGBE_FLAG_VMDQ_CAPABLE                 (u32)(1 << 13) | ||||
| #define IXGBE_FLAG_VMDQ_ENABLED                 (u32)(1 << 14) | ||||
| #define IXGBE_FLAG_FAN_FAIL_CAPABLE             (u32)(1 << 15) | ||||
| #define IXGBE_FLAG_NEED_LINK_UPDATE             (u32)(1 << 16) | ||||
| #define IXGBE_FLAG_NEED_LINK_CONFIG             (u32)(1 << 17) | ||||
| #define IXGBE_FLAG_FDIR_HASH_CAPABLE            (u32)(1 << 18) | ||||
| #define IXGBE_FLAG_FDIR_PERFECT_CAPABLE         (u32)(1 << 19) | ||||
| #define IXGBE_FLAG_FCOE_CAPABLE                 (u32)(1 << 20) | ||||
| #define IXGBE_FLAG_FCOE_ENABLED                 (u32)(1 << 21) | ||||
| #define IXGBE_FLAG_SRIOV_CAPABLE                (u32)(1 << 22) | ||||
| #define IXGBE_FLAG_SRIOV_ENABLED                (u32)(1 << 23) | ||||
| 
 | ||||
| 	u32 flags2; | ||||
| #define IXGBE_FLAG2_RSC_CAPABLE                 (u32)(1 << 0) | ||||
| #define IXGBE_FLAG2_RSC_ENABLED                 (u32)(1 << 1) | ||||
| #define IXGBE_FLAG2_TEMP_SENSOR_CAPABLE         (u32)(1 << 2) | ||||
| #define IXGBE_FLAG2_TEMP_SENSOR_EVENT           (u32)(1 << 3) | ||||
| #define IXGBE_FLAG2_SEARCH_FOR_SFP              (u32)(1 << 4) | ||||
| #define IXGBE_FLAG2_SFP_NEEDS_RESET             (u32)(1 << 5) | ||||
| #define IXGBE_FLAG2_RESET_REQUESTED             (u32)(1 << 6) | ||||
| #define IXGBE_FLAG2_FDIR_REQUIRES_REINIT        (u32)(1 << 7) | ||||
| #define IXGBE_FLAG2_RSS_FIELD_IPV4_UDP		(u32)(1 << 8) | ||||
| #define IXGBE_FLAG2_RSS_FIELD_IPV6_UDP		(u32)(1 << 9) | ||||
| #define IXGBE_FLAG2_PTP_PPS_ENABLED		(u32)(1 << 10) | ||||
| #define IXGBE_FLAG2_BRIDGE_MODE_VEB		(u32)(1 << 11) | ||||
| 
 | ||||
| 	/* Tx fast path data */ | ||||
| 	int num_tx_queues; | ||||
| 	u16 tx_itr_setting; | ||||
| 	u16 tx_work_limit; | ||||
| 
 | ||||
| 	/* Rx fast path data */ | ||||
| 	int num_rx_queues; | ||||
| 	u16 rx_itr_setting; | ||||
| 
 | ||||
| 	/* TX */ | ||||
| 	struct ixgbe_ring *tx_ring[MAX_TX_QUEUES] ____cacheline_aligned_in_smp; | ||||
| 
 | ||||
| 	u64 restart_queue; | ||||
| 	u64 lsc_int; | ||||
| 	u32 tx_timeout_count; | ||||
| 
 | ||||
| 	/* RX */ | ||||
| 	struct ixgbe_ring *rx_ring[MAX_RX_QUEUES]; | ||||
| 	int num_rx_pools;		/* == num_rx_queues in 82598 */ | ||||
| 	int num_rx_queues_per_pool;	/* 1 if 82598, can be many if 82599 */ | ||||
| 	u64 hw_csum_rx_error; | ||||
| 	u64 hw_rx_no_dma_resources; | ||||
| 	u64 rsc_total_count; | ||||
| 	u64 rsc_total_flush; | ||||
| 	u64 non_eop_descs; | ||||
| 	u32 alloc_rx_page_failed; | ||||
| 	u32 alloc_rx_buff_failed; | ||||
| 
 | ||||
| 	struct ixgbe_q_vector *q_vector[MAX_Q_VECTORS]; | ||||
| 
 | ||||
| 	/* DCB parameters */ | ||||
| 	struct ieee_pfc *ixgbe_ieee_pfc; | ||||
| 	struct ieee_ets *ixgbe_ieee_ets; | ||||
| 	struct ixgbe_dcb_config dcb_cfg; | ||||
| 	struct ixgbe_dcb_config temp_dcb_cfg; | ||||
| 	u8 dcb_set_bitmap; | ||||
| 	u8 dcbx_cap; | ||||
| 	enum ixgbe_fc_mode last_lfc_mode; | ||||
| 
 | ||||
| 	int num_q_vectors;	/* current number of q_vectors for device */ | ||||
| 	int max_q_vectors;	/* true count of q_vectors for device */ | ||||
| 	struct ixgbe_ring_feature ring_feature[RING_F_ARRAY_SIZE]; | ||||
| 	struct msix_entry *msix_entries; | ||||
| 
 | ||||
| 	u32 test_icr; | ||||
| 	struct ixgbe_ring test_tx_ring; | ||||
| 	struct ixgbe_ring test_rx_ring; | ||||
| 
 | ||||
| 	/* structs defined in ixgbe_hw.h */ | ||||
| 	struct ixgbe_hw hw; | ||||
| 	u16 msg_enable; | ||||
| 	struct ixgbe_hw_stats stats; | ||||
| 
 | ||||
| 	u64 tx_busy; | ||||
| 	unsigned int tx_ring_count; | ||||
| 	unsigned int rx_ring_count; | ||||
| 
 | ||||
| 	u32 link_speed; | ||||
| 	bool link_up; | ||||
| 	unsigned long link_check_timeout; | ||||
| 
 | ||||
| 	struct timer_list service_timer; | ||||
| 	struct work_struct service_task; | ||||
| 
 | ||||
| 	struct hlist_head fdir_filter_list; | ||||
| 	unsigned long fdir_overflow; /* number of times ATR was backed off */ | ||||
| 	union ixgbe_atr_input fdir_mask; | ||||
| 	int fdir_filter_count; | ||||
| 	u32 fdir_pballoc; | ||||
| 	u32 atr_sample_rate; | ||||
| 	spinlock_t fdir_perfect_lock; | ||||
| 
 | ||||
| #ifdef IXGBE_FCOE | ||||
| 	struct ixgbe_fcoe fcoe; | ||||
| #endif /* IXGBE_FCOE */ | ||||
| 	u8 __iomem *io_addr; /* Mainly for iounmap use */ | ||||
| 	u32 wol; | ||||
| 
 | ||||
| 	u16 eeprom_verh; | ||||
| 	u16 eeprom_verl; | ||||
| 	u16 eeprom_cap; | ||||
| 
 | ||||
| 	u32 interrupt_event; | ||||
| 	u32 led_reg; | ||||
| 
 | ||||
| 	struct ptp_clock *ptp_clock; | ||||
| 	struct ptp_clock_info ptp_caps; | ||||
| 	struct work_struct ptp_tx_work; | ||||
| 	struct sk_buff *ptp_tx_skb; | ||||
| 	struct hwtstamp_config tstamp_config; | ||||
| 	unsigned long ptp_tx_start; | ||||
| 	unsigned long last_overflow_check; | ||||
| 	unsigned long last_rx_ptp_check; | ||||
| 	unsigned long last_rx_timestamp; | ||||
| 	spinlock_t tmreg_lock; | ||||
| 	struct cyclecounter cc; | ||||
| 	struct timecounter tc; | ||||
| 	u32 base_incval; | ||||
| 
 | ||||
| 	/* SR-IOV */ | ||||
| 	DECLARE_BITMAP(active_vfs, IXGBE_MAX_VF_FUNCTIONS); | ||||
| 	unsigned int num_vfs; | ||||
| 	struct vf_data_storage *vfinfo; | ||||
| 	int vf_rate_link_speed; | ||||
| 	struct vf_macvlans vf_mvs; | ||||
| 	struct vf_macvlans *mv_list; | ||||
| 
 | ||||
| 	u32 timer_event_accumulator; | ||||
| 	u32 vferr_refcount; | ||||
| 	struct ixgbe_mac_addr *mac_table; | ||||
| 	struct kobject *info_kobj; | ||||
| #ifdef CONFIG_IXGBE_HWMON | ||||
| 	struct hwmon_buff *ixgbe_hwmon_buff; | ||||
| #endif /* CONFIG_IXGBE_HWMON */ | ||||
| #ifdef CONFIG_DEBUG_FS | ||||
| 	struct dentry *ixgbe_dbg_adapter; | ||||
| #endif /*CONFIG_DEBUG_FS*/ | ||||
| 
 | ||||
| 	u8 default_up; | ||||
| 	unsigned long fwd_bitmask; /* Bitmask indicating in use pools */ | ||||
| }; | ||||
| 
 | ||||
| struct ixgbe_fdir_filter { | ||||
| 	struct hlist_node fdir_node; | ||||
| 	union ixgbe_atr_input filter; | ||||
| 	u16 sw_idx; | ||||
| 	u16 action; | ||||
| }; | ||||
| 
 | ||||
| enum ixgbe_state_t { | ||||
| 	__IXGBE_TESTING, | ||||
| 	__IXGBE_RESETTING, | ||||
| 	__IXGBE_DOWN, | ||||
| 	__IXGBE_DISABLED, | ||||
| 	__IXGBE_REMOVING, | ||||
| 	__IXGBE_SERVICE_SCHED, | ||||
| 	__IXGBE_SERVICE_INITED, | ||||
| 	__IXGBE_IN_SFP_INIT, | ||||
| 	__IXGBE_PTP_RUNNING, | ||||
| 	__IXGBE_PTP_TX_IN_PROGRESS, | ||||
| }; | ||||
| 
 | ||||
| struct ixgbe_cb { | ||||
| 	union {				/* Union defining head/tail partner */ | ||||
| 		struct sk_buff *head; | ||||
| 		struct sk_buff *tail; | ||||
| 	}; | ||||
| 	dma_addr_t dma; | ||||
| 	u16 append_cnt; | ||||
| 	bool page_released; | ||||
| }; | ||||
| #define IXGBE_CB(skb) ((struct ixgbe_cb *)(skb)->cb) | ||||
| 
 | ||||
| enum ixgbe_boards { | ||||
| 	board_82598, | ||||
| 	board_82599, | ||||
| 	board_X540, | ||||
| }; | ||||
| 
 | ||||
| extern struct ixgbe_info ixgbe_82598_info; | ||||
| extern struct ixgbe_info ixgbe_82599_info; | ||||
| extern struct ixgbe_info ixgbe_X540_info; | ||||
| #ifdef CONFIG_IXGBE_DCB | ||||
| extern const struct dcbnl_rtnl_ops dcbnl_ops; | ||||
| #endif | ||||
| 
 | ||||
| extern char ixgbe_driver_name[]; | ||||
| extern const char ixgbe_driver_version[]; | ||||
| #ifdef IXGBE_FCOE | ||||
| extern char ixgbe_default_device_descr[]; | ||||
| #endif /* IXGBE_FCOE */ | ||||
| 
 | ||||
| void ixgbe_up(struct ixgbe_adapter *adapter); | ||||
| void ixgbe_down(struct ixgbe_adapter *adapter); | ||||
| void ixgbe_reinit_locked(struct ixgbe_adapter *adapter); | ||||
| void ixgbe_reset(struct ixgbe_adapter *adapter); | ||||
| void ixgbe_set_ethtool_ops(struct net_device *netdev); | ||||
| int ixgbe_setup_rx_resources(struct ixgbe_ring *); | ||||
| int ixgbe_setup_tx_resources(struct ixgbe_ring *); | ||||
| void ixgbe_free_rx_resources(struct ixgbe_ring *); | ||||
| void ixgbe_free_tx_resources(struct ixgbe_ring *); | ||||
| void ixgbe_configure_rx_ring(struct ixgbe_adapter *, struct ixgbe_ring *); | ||||
| void ixgbe_configure_tx_ring(struct ixgbe_adapter *, struct ixgbe_ring *); | ||||
| void ixgbe_disable_rx_queue(struct ixgbe_adapter *adapter, struct ixgbe_ring *); | ||||
| void ixgbe_update_stats(struct ixgbe_adapter *adapter); | ||||
| int ixgbe_init_interrupt_scheme(struct ixgbe_adapter *adapter); | ||||
| int ixgbe_wol_supported(struct ixgbe_adapter *adapter, u16 device_id, | ||||
| 			       u16 subdevice_id); | ||||
| #ifdef CONFIG_PCI_IOV | ||||
| void ixgbe_full_sync_mac_table(struct ixgbe_adapter *adapter); | ||||
| #endif | ||||
| int ixgbe_add_mac_filter(struct ixgbe_adapter *adapter, | ||||
| 			 u8 *addr, u16 queue); | ||||
| int ixgbe_del_mac_filter(struct ixgbe_adapter *adapter, | ||||
| 			 u8 *addr, u16 queue); | ||||
| void ixgbe_clear_interrupt_scheme(struct ixgbe_adapter *adapter); | ||||
| netdev_tx_t ixgbe_xmit_frame_ring(struct sk_buff *, struct ixgbe_adapter *, | ||||
| 				  struct ixgbe_ring *); | ||||
| void ixgbe_unmap_and_free_tx_resource(struct ixgbe_ring *, | ||||
| 				      struct ixgbe_tx_buffer *); | ||||
| void ixgbe_alloc_rx_buffers(struct ixgbe_ring *, u16); | ||||
| void ixgbe_write_eitr(struct ixgbe_q_vector *); | ||||
| int ixgbe_poll(struct napi_struct *napi, int budget); | ||||
| int ethtool_ioctl(struct ifreq *ifr); | ||||
| s32 ixgbe_reinit_fdir_tables_82599(struct ixgbe_hw *hw); | ||||
| s32 ixgbe_init_fdir_signature_82599(struct ixgbe_hw *hw, u32 fdirctrl); | ||||
| s32 ixgbe_init_fdir_perfect_82599(struct ixgbe_hw *hw, u32 fdirctrl); | ||||
| s32 ixgbe_fdir_add_signature_filter_82599(struct ixgbe_hw *hw, | ||||
| 					  union ixgbe_atr_hash_dword input, | ||||
| 					  union ixgbe_atr_hash_dword common, | ||||
| 					  u8 queue); | ||||
| s32 ixgbe_fdir_set_input_mask_82599(struct ixgbe_hw *hw, | ||||
| 				    union ixgbe_atr_input *input_mask); | ||||
| s32 ixgbe_fdir_write_perfect_filter_82599(struct ixgbe_hw *hw, | ||||
| 					  union ixgbe_atr_input *input, | ||||
| 					  u16 soft_id, u8 queue); | ||||
| s32 ixgbe_fdir_erase_perfect_filter_82599(struct ixgbe_hw *hw, | ||||
| 					  union ixgbe_atr_input *input, | ||||
| 					  u16 soft_id); | ||||
| void ixgbe_atr_compute_perfect_hash_82599(union ixgbe_atr_input *input, | ||||
| 					  union ixgbe_atr_input *mask); | ||||
| void ixgbe_set_rx_mode(struct net_device *netdev); | ||||
| #ifdef CONFIG_IXGBE_DCB | ||||
| void ixgbe_set_rx_drop_en(struct ixgbe_adapter *adapter); | ||||
| #endif | ||||
| int ixgbe_setup_tc(struct net_device *dev, u8 tc); | ||||
| void ixgbe_tx_ctxtdesc(struct ixgbe_ring *, u32, u32, u32, u32); | ||||
| void ixgbe_do_reset(struct net_device *netdev); | ||||
| #ifdef CONFIG_IXGBE_HWMON | ||||
| void ixgbe_sysfs_exit(struct ixgbe_adapter *adapter); | ||||
| int ixgbe_sysfs_init(struct ixgbe_adapter *adapter); | ||||
| #endif /* CONFIG_IXGBE_HWMON */ | ||||
| #ifdef IXGBE_FCOE | ||||
| void ixgbe_configure_fcoe(struct ixgbe_adapter *adapter); | ||||
| int ixgbe_fso(struct ixgbe_ring *tx_ring, struct ixgbe_tx_buffer *first, | ||||
| 	      u8 *hdr_len); | ||||
| int ixgbe_fcoe_ddp(struct ixgbe_adapter *adapter, | ||||
| 		   union ixgbe_adv_rx_desc *rx_desc, struct sk_buff *skb); | ||||
| int ixgbe_fcoe_ddp_get(struct net_device *netdev, u16 xid, | ||||
| 		       struct scatterlist *sgl, unsigned int sgc); | ||||
| int ixgbe_fcoe_ddp_target(struct net_device *netdev, u16 xid, | ||||
| 			  struct scatterlist *sgl, unsigned int sgc); | ||||
| int ixgbe_fcoe_ddp_put(struct net_device *netdev, u16 xid); | ||||
| int ixgbe_setup_fcoe_ddp_resources(struct ixgbe_adapter *adapter); | ||||
| void ixgbe_free_fcoe_ddp_resources(struct ixgbe_adapter *adapter); | ||||
| int ixgbe_fcoe_enable(struct net_device *netdev); | ||||
| int ixgbe_fcoe_disable(struct net_device *netdev); | ||||
| #ifdef CONFIG_IXGBE_DCB | ||||
| u8 ixgbe_fcoe_getapp(struct ixgbe_adapter *adapter); | ||||
| u8 ixgbe_fcoe_setapp(struct ixgbe_adapter *adapter, u8 up); | ||||
| #endif /* CONFIG_IXGBE_DCB */ | ||||
| int ixgbe_fcoe_get_wwn(struct net_device *netdev, u64 *wwn, int type); | ||||
| int ixgbe_fcoe_get_hbainfo(struct net_device *netdev, | ||||
| 			   struct netdev_fcoe_hbainfo *info); | ||||
| u8 ixgbe_fcoe_get_tc(struct ixgbe_adapter *adapter); | ||||
| #endif /* IXGBE_FCOE */ | ||||
| #ifdef CONFIG_DEBUG_FS | ||||
| void ixgbe_dbg_adapter_init(struct ixgbe_adapter *adapter); | ||||
| void ixgbe_dbg_adapter_exit(struct ixgbe_adapter *adapter); | ||||
| void ixgbe_dbg_init(void); | ||||
| void ixgbe_dbg_exit(void); | ||||
| #else | ||||
| static inline void ixgbe_dbg_adapter_init(struct ixgbe_adapter *adapter) {} | ||||
| static inline void ixgbe_dbg_adapter_exit(struct ixgbe_adapter *adapter) {} | ||||
| static inline void ixgbe_dbg_init(void) {} | ||||
| static inline void ixgbe_dbg_exit(void) {} | ||||
| #endif /* CONFIG_DEBUG_FS */ | ||||
| static inline struct netdev_queue *txring_txq(const struct ixgbe_ring *ring) | ||||
| { | ||||
| 	return netdev_get_tx_queue(ring->netdev, ring->queue_index); | ||||
| } | ||||
| 
 | ||||
| void ixgbe_ptp_init(struct ixgbe_adapter *adapter); | ||||
| void ixgbe_ptp_suspend(struct ixgbe_adapter *adapter); | ||||
| void ixgbe_ptp_stop(struct ixgbe_adapter *adapter); | ||||
| void ixgbe_ptp_overflow_check(struct ixgbe_adapter *adapter); | ||||
| void ixgbe_ptp_rx_hang(struct ixgbe_adapter *adapter); | ||||
| void ixgbe_ptp_rx_hwtstamp(struct ixgbe_adapter *adapter, struct sk_buff *skb); | ||||
| int ixgbe_ptp_set_ts_config(struct ixgbe_adapter *adapter, struct ifreq *ifr); | ||||
| int ixgbe_ptp_get_ts_config(struct ixgbe_adapter *adapter, struct ifreq *ifr); | ||||
| void ixgbe_ptp_start_cyclecounter(struct ixgbe_adapter *adapter); | ||||
| void ixgbe_ptp_reset(struct ixgbe_adapter *adapter); | ||||
| void ixgbe_ptp_check_pps_event(struct ixgbe_adapter *adapter, u32 eicr); | ||||
| #ifdef CONFIG_PCI_IOV | ||||
| void ixgbe_sriov_reinit(struct ixgbe_adapter *adapter); | ||||
| #endif | ||||
| 
 | ||||
| netdev_tx_t ixgbe_xmit_frame_ring(struct sk_buff *skb, | ||||
| 				  struct ixgbe_adapter *adapter, | ||||
| 				  struct ixgbe_ring *tx_ring); | ||||
| #endif /* _IXGBE_H_ */ | ||||
							
								
								
									
										1231
									
								
								drivers/net/ethernet/intel/ixgbe/ixgbe_82598.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										1231
									
								
								drivers/net/ethernet/intel/ixgbe/ixgbe_82598.c
									
										
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							
							
								
								
									
										2376
									
								
								drivers/net/ethernet/intel/ixgbe/ixgbe_82599.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										2376
									
								
								drivers/net/ethernet/intel/ixgbe/ixgbe_82599.c
									
										
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							
							
								
								
									
										3779
									
								
								drivers/net/ethernet/intel/ixgbe/ixgbe_common.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										3779
									
								
								drivers/net/ethernet/intel/ixgbe/ixgbe_common.c
									
										
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							
							
								
								
									
										206
									
								
								drivers/net/ethernet/intel/ixgbe/ixgbe_common.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										206
									
								
								drivers/net/ethernet/intel/ixgbe/ixgbe_common.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,206 @@ | |||
| /*******************************************************************************
 | ||||
| 
 | ||||
|   Intel 10 Gigabit PCI Express Linux driver | ||||
|   Copyright(c) 1999 - 2014 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: | ||||
|   Linux NICS <linux.nics@intel.com> | ||||
|   e1000-devel Mailing List <e1000-devel@lists.sourceforge.net> | ||||
|   Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 | ||||
| 
 | ||||
| *******************************************************************************/ | ||||
| 
 | ||||
| #ifndef _IXGBE_COMMON_H_ | ||||
| #define _IXGBE_COMMON_H_ | ||||
| 
 | ||||
| #include "ixgbe_type.h" | ||||
| #include "ixgbe.h" | ||||
| 
 | ||||
| u16 ixgbe_get_pcie_msix_count_generic(struct ixgbe_hw *hw); | ||||
| s32 ixgbe_init_ops_generic(struct ixgbe_hw *hw); | ||||
| s32 ixgbe_init_hw_generic(struct ixgbe_hw *hw); | ||||
| s32 ixgbe_start_hw_generic(struct ixgbe_hw *hw); | ||||
| s32 ixgbe_start_hw_gen2(struct ixgbe_hw *hw); | ||||
| s32 ixgbe_clear_hw_cntrs_generic(struct ixgbe_hw *hw); | ||||
| s32 ixgbe_read_pba_string_generic(struct ixgbe_hw *hw, u8 *pba_num, | ||||
| 				  u32 pba_num_size); | ||||
| s32 ixgbe_get_mac_addr_generic(struct ixgbe_hw *hw, u8 *mac_addr); | ||||
| enum ixgbe_bus_width ixgbe_convert_bus_width(u16 link_status); | ||||
| enum ixgbe_bus_speed ixgbe_convert_bus_speed(u16 link_status); | ||||
| s32 ixgbe_get_bus_info_generic(struct ixgbe_hw *hw); | ||||
| void ixgbe_set_lan_id_multi_port_pcie(struct ixgbe_hw *hw); | ||||
| s32 ixgbe_stop_adapter_generic(struct ixgbe_hw *hw); | ||||
| 
 | ||||
| s32 ixgbe_led_on_generic(struct ixgbe_hw *hw, u32 index); | ||||
| s32 ixgbe_led_off_generic(struct ixgbe_hw *hw, u32 index); | ||||
| 
 | ||||
| s32 ixgbe_init_eeprom_params_generic(struct ixgbe_hw *hw); | ||||
| s32 ixgbe_write_eeprom_generic(struct ixgbe_hw *hw, u16 offset, u16 data); | ||||
| s32 ixgbe_write_eeprom_buffer_bit_bang_generic(struct ixgbe_hw *hw, u16 offset, | ||||
| 					       u16 words, u16 *data); | ||||
| s32 ixgbe_read_eerd_generic(struct ixgbe_hw *hw, u16 offset, u16 *data); | ||||
| s32 ixgbe_read_eerd_buffer_generic(struct ixgbe_hw *hw, u16 offset, | ||||
| 				   u16 words, u16 *data); | ||||
| s32 ixgbe_write_eewr_generic(struct ixgbe_hw *hw, u16 offset, u16 data); | ||||
| s32 ixgbe_write_eewr_buffer_generic(struct ixgbe_hw *hw, u16 offset, | ||||
| 				    u16 words, u16 *data); | ||||
| s32 ixgbe_read_eeprom_bit_bang_generic(struct ixgbe_hw *hw, u16 offset, | ||||
| 				       u16 *data); | ||||
| s32 ixgbe_read_eeprom_buffer_bit_bang_generic(struct ixgbe_hw *hw, u16 offset, | ||||
| 					      u16 words, u16 *data); | ||||
| u16 ixgbe_calc_eeprom_checksum_generic(struct ixgbe_hw *hw); | ||||
| s32 ixgbe_validate_eeprom_checksum_generic(struct ixgbe_hw *hw, | ||||
| 					   u16 *checksum_val); | ||||
| s32 ixgbe_update_eeprom_checksum_generic(struct ixgbe_hw *hw); | ||||
| 
 | ||||
| s32 ixgbe_set_rar_generic(struct ixgbe_hw *hw, u32 index, u8 *addr, u32 vmdq, | ||||
| 			  u32 enable_addr); | ||||
| s32 ixgbe_clear_rar_generic(struct ixgbe_hw *hw, u32 index); | ||||
| s32 ixgbe_init_rx_addrs_generic(struct ixgbe_hw *hw); | ||||
| s32 ixgbe_update_mc_addr_list_generic(struct ixgbe_hw *hw, | ||||
| 				      struct net_device *netdev); | ||||
| s32 ixgbe_enable_mc_generic(struct ixgbe_hw *hw); | ||||
| s32 ixgbe_disable_mc_generic(struct ixgbe_hw *hw); | ||||
| s32 ixgbe_disable_rx_buff_generic(struct ixgbe_hw *hw); | ||||
| s32 ixgbe_enable_rx_buff_generic(struct ixgbe_hw *hw); | ||||
| s32 ixgbe_enable_rx_dma_generic(struct ixgbe_hw *hw, u32 regval); | ||||
| s32 ixgbe_fc_enable_generic(struct ixgbe_hw *hw); | ||||
| bool ixgbe_device_supports_autoneg_fc(struct ixgbe_hw *hw); | ||||
| void ixgbe_fc_autoneg(struct ixgbe_hw *hw); | ||||
| 
 | ||||
| s32 ixgbe_acquire_swfw_sync(struct ixgbe_hw *hw, u16 mask); | ||||
| void ixgbe_release_swfw_sync(struct ixgbe_hw *hw, u16 mask); | ||||
| s32 ixgbe_get_san_mac_addr_generic(struct ixgbe_hw *hw, u8 *san_mac_addr); | ||||
| s32 ixgbe_set_vmdq_generic(struct ixgbe_hw *hw, u32 rar, u32 vmdq); | ||||
| s32 ixgbe_set_vmdq_san_mac_generic(struct ixgbe_hw *hw, u32 vmdq); | ||||
| s32 ixgbe_clear_vmdq_generic(struct ixgbe_hw *hw, u32 rar, u32 vmdq); | ||||
| s32 ixgbe_init_uta_tables_generic(struct ixgbe_hw *hw); | ||||
| s32 ixgbe_set_vfta_generic(struct ixgbe_hw *hw, u32 vlan, | ||||
| 			   u32 vind, bool vlan_on); | ||||
| s32 ixgbe_clear_vfta_generic(struct ixgbe_hw *hw); | ||||
| s32 ixgbe_check_mac_link_generic(struct ixgbe_hw *hw, | ||||
| 				 ixgbe_link_speed *speed, | ||||
| 				 bool *link_up, bool link_up_wait_to_complete); | ||||
| s32 ixgbe_get_wwn_prefix_generic(struct ixgbe_hw *hw, u16 *wwnn_prefix, | ||||
| 				 u16 *wwpn_prefix); | ||||
| 
 | ||||
| s32 prot_autoc_read_generic(struct ixgbe_hw *hw, bool *, u32 *reg_val); | ||||
| s32 prot_autoc_write_generic(struct ixgbe_hw *hw, u32 reg_val, bool locked); | ||||
| 
 | ||||
| s32 ixgbe_blink_led_start_generic(struct ixgbe_hw *hw, u32 index); | ||||
| s32 ixgbe_blink_led_stop_generic(struct ixgbe_hw *hw, u32 index); | ||||
| void ixgbe_set_mac_anti_spoofing(struct ixgbe_hw *hw, bool enable, int pf); | ||||
| void ixgbe_set_vlan_anti_spoofing(struct ixgbe_hw *hw, bool enable, int vf); | ||||
| s32 ixgbe_get_device_caps_generic(struct ixgbe_hw *hw, u16 *device_caps); | ||||
| s32 ixgbe_set_fw_drv_ver_generic(struct ixgbe_hw *hw, u8 maj, u8 min, | ||||
| 				 u8 build, u8 ver); | ||||
| void ixgbe_clear_tx_pending(struct ixgbe_hw *hw); | ||||
| bool ixgbe_mng_enabled(struct ixgbe_hw *hw); | ||||
| 
 | ||||
| void ixgbe_set_rxpba_generic(struct ixgbe_hw *hw, int num_pb, | ||||
| 			     u32 headroom, int strategy); | ||||
| 
 | ||||
| #define IXGBE_I2C_THERMAL_SENSOR_ADDR	0xF8 | ||||
| #define IXGBE_EMC_INTERNAL_DATA		0x00 | ||||
| #define IXGBE_EMC_INTERNAL_THERM_LIMIT	0x20 | ||||
| #define IXGBE_EMC_DIODE1_DATA		0x01 | ||||
| #define IXGBE_EMC_DIODE1_THERM_LIMIT	0x19 | ||||
| #define IXGBE_EMC_DIODE2_DATA		0x23 | ||||
| #define IXGBE_EMC_DIODE2_THERM_LIMIT	0x1A | ||||
| #define IXGBE_EMC_DIODE3_DATA		0x2A | ||||
| #define IXGBE_EMC_DIODE3_THERM_LIMIT	0x30 | ||||
| 
 | ||||
| s32 ixgbe_get_thermal_sensor_data_generic(struct ixgbe_hw *hw); | ||||
| s32 ixgbe_init_thermal_sensor_thresh_generic(struct ixgbe_hw *hw); | ||||
| 
 | ||||
| #define IXGBE_FAILED_READ_REG 0xffffffffU | ||||
| #define IXGBE_FAILED_READ_CFG_DWORD 0xffffffffU | ||||
| #define IXGBE_FAILED_READ_CFG_WORD 0xffffU | ||||
| 
 | ||||
| u16 ixgbe_read_pci_cfg_word(struct ixgbe_hw *hw, u32 reg); | ||||
| void ixgbe_write_pci_cfg_word(struct ixgbe_hw *hw, u32 reg, u16 value); | ||||
| 
 | ||||
| static inline bool ixgbe_removed(void __iomem *addr) | ||||
| { | ||||
| 	return unlikely(!addr); | ||||
| } | ||||
| 
 | ||||
| static inline void ixgbe_write_reg(struct ixgbe_hw *hw, u32 reg, u32 value) | ||||
| { | ||||
| 	u8 __iomem *reg_addr = ACCESS_ONCE(hw->hw_addr); | ||||
| 
 | ||||
| 	if (ixgbe_removed(reg_addr)) | ||||
| 		return; | ||||
| 	writel(value, reg_addr + reg); | ||||
| } | ||||
| #define IXGBE_WRITE_REG(a, reg, value) ixgbe_write_reg((a), (reg), (value)) | ||||
| 
 | ||||
| #ifndef writeq | ||||
| #define writeq writeq | ||||
| static inline void writeq(u64 val, void __iomem *addr) | ||||
| { | ||||
| 	writel((u32)val, addr); | ||||
| 	writel((u32)(val >> 32), addr + 4); | ||||
| } | ||||
| #endif | ||||
| 
 | ||||
| static inline void ixgbe_write_reg64(struct ixgbe_hw *hw, u32 reg, u64 value) | ||||
| { | ||||
| 	u8 __iomem *reg_addr = ACCESS_ONCE(hw->hw_addr); | ||||
| 
 | ||||
| 	if (ixgbe_removed(reg_addr)) | ||||
| 		return; | ||||
| 	writeq(value, reg_addr + reg); | ||||
| } | ||||
| #define IXGBE_WRITE_REG64(a, reg, value) ixgbe_write_reg64((a), (reg), (value)) | ||||
| 
 | ||||
| u32 ixgbe_read_reg(struct ixgbe_hw *hw, u32 reg); | ||||
| #define IXGBE_READ_REG(a, reg) ixgbe_read_reg((a), (reg)) | ||||
| 
 | ||||
| #define IXGBE_WRITE_REG_ARRAY(a, reg, offset, value) \ | ||||
| 		ixgbe_write_reg((a), (reg) + ((offset) << 2), (value)) | ||||
| 
 | ||||
| #define IXGBE_READ_REG_ARRAY(a, reg, offset) \ | ||||
| 		ixgbe_read_reg((a), (reg) + ((offset) << 2)) | ||||
| 
 | ||||
| #define IXGBE_WRITE_FLUSH(a) ixgbe_read_reg((a), IXGBE_STATUS) | ||||
| 
 | ||||
| #define ixgbe_hw_to_netdev(hw) (((struct ixgbe_adapter *)(hw)->back)->netdev) | ||||
| 
 | ||||
| #define hw_dbg(hw, format, arg...) \ | ||||
| 	netdev_dbg(ixgbe_hw_to_netdev(hw), format, ## arg) | ||||
| #define hw_err(hw, format, arg...) \ | ||||
| 	netdev_err(ixgbe_hw_to_netdev(hw), format, ## arg) | ||||
| #define e_dev_info(format, arg...) \ | ||||
| 	dev_info(&adapter->pdev->dev, format, ## arg) | ||||
| #define e_dev_warn(format, arg...) \ | ||||
| 	dev_warn(&adapter->pdev->dev, format, ## arg) | ||||
| #define e_dev_err(format, arg...) \ | ||||
| 	dev_err(&adapter->pdev->dev, format, ## arg) | ||||
| #define e_dev_notice(format, arg...) \ | ||||
| 	dev_notice(&adapter->pdev->dev, format, ## arg) | ||||
| #define e_info(msglvl, format, arg...) \ | ||||
| 	netif_info(adapter, msglvl, adapter->netdev, format, ## arg) | ||||
| #define e_err(msglvl, format, arg...) \ | ||||
| 	netif_err(adapter, msglvl, adapter->netdev, format, ## arg) | ||||
| #define e_warn(msglvl, format, arg...) \ | ||||
| 	netif_warn(adapter, msglvl, adapter->netdev, format, ## arg) | ||||
| #define e_crit(msglvl, format, arg...) \ | ||||
| 	netif_crit(adapter, msglvl, adapter->netdev, format, ## arg) | ||||
| #endif /* IXGBE_COMMON */ | ||||
							
								
								
									
										393
									
								
								drivers/net/ethernet/intel/ixgbe/ixgbe_dcb.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										393
									
								
								drivers/net/ethernet/intel/ixgbe/ixgbe_dcb.c
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,393 @@ | |||
| /*******************************************************************************
 | ||||
| 
 | ||||
|   Intel 10 Gigabit PCI Express Linux driver | ||||
|   Copyright(c) 1999 - 2014 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: | ||||
|   Linux NICS <linux.nics@intel.com> | ||||
|   e1000-devel Mailing List <e1000-devel@lists.sourceforge.net> | ||||
|   Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 | ||||
| 
 | ||||
| *******************************************************************************/ | ||||
| 
 | ||||
| 
 | ||||
| #include "ixgbe.h" | ||||
| #include "ixgbe_type.h" | ||||
| #include "ixgbe_dcb.h" | ||||
| #include "ixgbe_dcb_82598.h" | ||||
| #include "ixgbe_dcb_82599.h" | ||||
| 
 | ||||
| /**
 | ||||
|  * ixgbe_ieee_credits - This calculates the ieee traffic class | ||||
|  * credits from the configured bandwidth percentages. Credits | ||||
|  * are the smallest unit programmable into the underlying | ||||
|  * hardware. The IEEE 802.1Qaz specification do not use bandwidth | ||||
|  * groups so this is much simplified from the CEE case. | ||||
|  */ | ||||
| static s32 ixgbe_ieee_credits(__u8 *bw, __u16 *refill, | ||||
| 			      __u16 *max, int max_frame) | ||||
| { | ||||
| 	int min_percent = 100; | ||||
| 	int min_credit, multiplier; | ||||
| 	int i; | ||||
| 
 | ||||
| 	min_credit = ((max_frame / 2) + DCB_CREDIT_QUANTUM - 1) / | ||||
| 			DCB_CREDIT_QUANTUM; | ||||
| 
 | ||||
| 	for (i = 0; i < MAX_TRAFFIC_CLASS; i++) { | ||||
| 		if (bw[i] < min_percent && bw[i]) | ||||
| 			min_percent = bw[i]; | ||||
| 	} | ||||
| 
 | ||||
| 	multiplier = (min_credit / min_percent) + 1; | ||||
| 
 | ||||
| 	/* Find out the hw credits for each TC */ | ||||
| 	for (i = 0; i < MAX_TRAFFIC_CLASS; i++) { | ||||
| 		int val = min(bw[i] * multiplier, MAX_CREDIT_REFILL); | ||||
| 
 | ||||
| 		if (val < min_credit) | ||||
| 			val = min_credit; | ||||
| 		refill[i] = val; | ||||
| 
 | ||||
| 		max[i] = bw[i] ? (bw[i] * MAX_CREDIT)/100 : min_credit; | ||||
| 	} | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  * ixgbe_dcb_calculate_tc_credits - Calculates traffic class credits | ||||
|  * @ixgbe_dcb_config: Struct containing DCB settings. | ||||
|  * @direction: Configuring either Tx or Rx. | ||||
|  * | ||||
|  * This function calculates the credits allocated to each traffic class. | ||||
|  * It should be called only after the rules are checked by | ||||
|  * ixgbe_dcb_check_config(). | ||||
|  */ | ||||
| s32 ixgbe_dcb_calculate_tc_credits(struct ixgbe_hw *hw, | ||||
| 				   struct ixgbe_dcb_config *dcb_config, | ||||
| 				   int max_frame, u8 direction) | ||||
| { | ||||
| 	struct tc_bw_alloc *p; | ||||
| 	int min_credit; | ||||
| 	int min_multiplier; | ||||
| 	int min_percent = 100; | ||||
| 	/* Initialization values default for Tx settings */ | ||||
| 	u32 credit_refill       = 0; | ||||
| 	u32 credit_max          = 0; | ||||
| 	u16 link_percentage     = 0; | ||||
| 	u8  bw_percent          = 0; | ||||
| 	u8  i; | ||||
| 
 | ||||
| 	if (!dcb_config) | ||||
| 		return DCB_ERR_CONFIG; | ||||
| 
 | ||||
| 	min_credit = ((max_frame / 2) + DCB_CREDIT_QUANTUM - 1) / | ||||
| 			DCB_CREDIT_QUANTUM; | ||||
| 
 | ||||
| 	/* Find smallest link percentage */ | ||||
| 	for (i = 0; i < MAX_TRAFFIC_CLASS; i++) { | ||||
| 		p = &dcb_config->tc_config[i].path[direction]; | ||||
| 		bw_percent = dcb_config->bw_percentage[direction][p->bwg_id]; | ||||
| 		link_percentage = p->bwg_percent; | ||||
| 
 | ||||
| 		link_percentage = (link_percentage * bw_percent) / 100; | ||||
| 
 | ||||
| 		if (link_percentage && link_percentage < min_percent) | ||||
| 			min_percent = link_percentage; | ||||
| 	} | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * The ratio between traffic classes will control the bandwidth | ||||
| 	 * percentages seen on the wire. To calculate this ratio we use | ||||
| 	 * a multiplier. It is required that the refill credits must be | ||||
| 	 * larger than the max frame size so here we find the smallest | ||||
| 	 * multiplier that will allow all bandwidth percentages to be | ||||
| 	 * greater than the max frame size. | ||||
| 	 */ | ||||
| 	min_multiplier = (min_credit / min_percent) + 1; | ||||
| 
 | ||||
| 	/* Find out the link percentage for each TC first */ | ||||
| 	for (i = 0; i < MAX_TRAFFIC_CLASS; i++) { | ||||
| 		p = &dcb_config->tc_config[i].path[direction]; | ||||
| 		bw_percent = dcb_config->bw_percentage[direction][p->bwg_id]; | ||||
| 
 | ||||
| 		link_percentage = p->bwg_percent; | ||||
| 		/* Must be careful of integer division for very small nums */ | ||||
| 		link_percentage = (link_percentage * bw_percent) / 100; | ||||
| 		if (p->bwg_percent > 0 && link_percentage == 0) | ||||
| 			link_percentage = 1; | ||||
| 
 | ||||
| 		/* Save link_percentage for reference */ | ||||
| 		p->link_percent = (u8)link_percentage; | ||||
| 
 | ||||
| 		/* Calculate credit refill ratio using multiplier */ | ||||
| 		credit_refill = min(link_percentage * min_multiplier, | ||||
| 				    MAX_CREDIT_REFILL); | ||||
| 		p->data_credits_refill = (u16)credit_refill; | ||||
| 
 | ||||
| 		/* Calculate maximum credit for the TC */ | ||||
| 		credit_max = (link_percentage * MAX_CREDIT) / 100; | ||||
| 
 | ||||
| 		/*
 | ||||
| 		 * Adjustment based on rule checking, if the percentage | ||||
| 		 * of a TC is too small, the maximum credit may not be | ||||
| 		 * enough to send out a jumbo frame in data plane arbitration. | ||||
| 		 */ | ||||
| 		if (credit_max && (credit_max < min_credit)) | ||||
| 			credit_max = min_credit; | ||||
| 
 | ||||
| 		if (direction == DCB_TX_CONFIG) { | ||||
| 			/*
 | ||||
| 			 * Adjustment based on rule checking, if the | ||||
| 			 * percentage of a TC is too small, the maximum | ||||
| 			 * credit may not be enough to send out a TSO | ||||
| 			 * packet in descriptor plane arbitration. | ||||
| 			 */ | ||||
| 			if ((hw->mac.type == ixgbe_mac_82598EB) && | ||||
| 			    credit_max && | ||||
| 			    (credit_max < MINIMUM_CREDIT_FOR_TSO)) | ||||
| 				credit_max = MINIMUM_CREDIT_FOR_TSO; | ||||
| 
 | ||||
| 			dcb_config->tc_config[i].desc_credits_max = | ||||
| 				(u16)credit_max; | ||||
| 		} | ||||
| 
 | ||||
| 		p->data_credits_max = (u16)credit_max; | ||||
| 	} | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| void ixgbe_dcb_unpack_pfc(struct ixgbe_dcb_config *cfg, u8 *pfc_en) | ||||
| { | ||||
| 	struct tc_configuration *tc_config = &cfg->tc_config[0]; | ||||
| 	int tc; | ||||
| 
 | ||||
| 	for (*pfc_en = 0, tc = 0; tc < MAX_TRAFFIC_CLASS; tc++) { | ||||
| 		if (tc_config[tc].dcb_pfc != pfc_disabled) | ||||
| 			*pfc_en |= 1 << tc; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| void ixgbe_dcb_unpack_refill(struct ixgbe_dcb_config *cfg, int direction, | ||||
| 			     u16 *refill) | ||||
| { | ||||
| 	struct tc_configuration *tc_config = &cfg->tc_config[0]; | ||||
| 	int tc; | ||||
| 
 | ||||
| 	for (tc = 0; tc < MAX_TRAFFIC_CLASS; tc++) | ||||
| 		refill[tc] = tc_config[tc].path[direction].data_credits_refill; | ||||
| } | ||||
| 
 | ||||
| void ixgbe_dcb_unpack_max(struct ixgbe_dcb_config *cfg, u16 *max) | ||||
| { | ||||
| 	struct tc_configuration *tc_config = &cfg->tc_config[0]; | ||||
| 	int tc; | ||||
| 
 | ||||
| 	for (tc = 0; tc < MAX_TRAFFIC_CLASS; tc++) | ||||
| 		max[tc] = tc_config[tc].desc_credits_max; | ||||
| } | ||||
| 
 | ||||
| void ixgbe_dcb_unpack_bwgid(struct ixgbe_dcb_config *cfg, int direction, | ||||
| 			    u8 *bwgid) | ||||
| { | ||||
| 	struct tc_configuration *tc_config = &cfg->tc_config[0]; | ||||
| 	int tc; | ||||
| 
 | ||||
| 	for (tc = 0; tc < MAX_TRAFFIC_CLASS; tc++) | ||||
| 		bwgid[tc] = tc_config[tc].path[direction].bwg_id; | ||||
| } | ||||
| 
 | ||||
| void ixgbe_dcb_unpack_prio(struct ixgbe_dcb_config *cfg, int direction, | ||||
| 			    u8 *ptype) | ||||
| { | ||||
| 	struct tc_configuration *tc_config = &cfg->tc_config[0]; | ||||
| 	int tc; | ||||
| 
 | ||||
| 	for (tc = 0; tc < MAX_TRAFFIC_CLASS; tc++) | ||||
| 		ptype[tc] = tc_config[tc].path[direction].prio_type; | ||||
| } | ||||
| 
 | ||||
| u8 ixgbe_dcb_get_tc_from_up(struct ixgbe_dcb_config *cfg, int direction, u8 up) | ||||
| { | ||||
| 	struct tc_configuration *tc_config = &cfg->tc_config[0]; | ||||
| 	u8 prio_mask = 1 << up; | ||||
| 	u8 tc = cfg->num_tcs.pg_tcs; | ||||
| 
 | ||||
| 	/* If tc is 0 then DCB is likely not enabled or supported */ | ||||
| 	if (!tc) | ||||
| 		return 0; | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * Test from maximum TC to 1 and report the first match we find.  If | ||||
| 	 * we find no match we can assume that the TC is 0 since the TC must | ||||
| 	 * be set for all user priorities | ||||
| 	 */ | ||||
| 	for (tc--; tc; tc--) { | ||||
| 		if (prio_mask & tc_config[tc].path[direction].up_to_tc_bitmap) | ||||
| 			break; | ||||
| 	} | ||||
| 
 | ||||
| 	return tc; | ||||
| } | ||||
| 
 | ||||
| void ixgbe_dcb_unpack_map(struct ixgbe_dcb_config *cfg, int direction, u8 *map) | ||||
| { | ||||
| 	u8 up; | ||||
| 
 | ||||
| 	for (up = 0; up < MAX_USER_PRIORITY; up++) | ||||
| 		map[up] = ixgbe_dcb_get_tc_from_up(cfg, direction, up); | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  * ixgbe_dcb_hw_config - Config and enable DCB | ||||
|  * @hw: pointer to hardware structure | ||||
|  * @dcb_config: pointer to ixgbe_dcb_config structure | ||||
|  * | ||||
|  * Configure dcb settings and enable dcb mode. | ||||
|  */ | ||||
| s32 ixgbe_dcb_hw_config(struct ixgbe_hw *hw, | ||||
| 			struct ixgbe_dcb_config *dcb_config) | ||||
| { | ||||
| 	u8 pfc_en; | ||||
| 	u8 ptype[MAX_TRAFFIC_CLASS]; | ||||
| 	u8 bwgid[MAX_TRAFFIC_CLASS]; | ||||
| 	u8 prio_tc[MAX_TRAFFIC_CLASS]; | ||||
| 	u16 refill[MAX_TRAFFIC_CLASS]; | ||||
| 	u16 max[MAX_TRAFFIC_CLASS]; | ||||
| 
 | ||||
| 	/* Unpack CEE standard containers */ | ||||
| 	ixgbe_dcb_unpack_pfc(dcb_config, &pfc_en); | ||||
| 	ixgbe_dcb_unpack_refill(dcb_config, DCB_TX_CONFIG, refill); | ||||
| 	ixgbe_dcb_unpack_max(dcb_config, max); | ||||
| 	ixgbe_dcb_unpack_bwgid(dcb_config, DCB_TX_CONFIG, bwgid); | ||||
| 	ixgbe_dcb_unpack_prio(dcb_config, DCB_TX_CONFIG, ptype); | ||||
| 	ixgbe_dcb_unpack_map(dcb_config, DCB_TX_CONFIG, prio_tc); | ||||
| 
 | ||||
| 	switch (hw->mac.type) { | ||||
| 	case ixgbe_mac_82598EB: | ||||
| 		return ixgbe_dcb_hw_config_82598(hw, pfc_en, refill, max, | ||||
| 						 bwgid, ptype); | ||||
| 	case ixgbe_mac_82599EB: | ||||
| 	case ixgbe_mac_X540: | ||||
| 		return ixgbe_dcb_hw_config_82599(hw, pfc_en, refill, max, | ||||
| 						 bwgid, ptype, prio_tc); | ||||
| 	default: | ||||
| 		break; | ||||
| 	} | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| /* Helper routines to abstract HW specifics from DCB netlink ops */ | ||||
| s32 ixgbe_dcb_hw_pfc_config(struct ixgbe_hw *hw, u8 pfc_en, u8 *prio_tc) | ||||
| { | ||||
| 	switch (hw->mac.type) { | ||||
| 	case ixgbe_mac_82598EB: | ||||
| 		return ixgbe_dcb_config_pfc_82598(hw, pfc_en); | ||||
| 	case ixgbe_mac_82599EB: | ||||
| 	case ixgbe_mac_X540: | ||||
| 		return ixgbe_dcb_config_pfc_82599(hw, pfc_en, prio_tc); | ||||
| 	default: | ||||
| 		break; | ||||
| 	} | ||||
| 	return -EINVAL; | ||||
| } | ||||
| 
 | ||||
| s32 ixgbe_dcb_hw_ets(struct ixgbe_hw *hw, struct ieee_ets *ets, int max_frame) | ||||
| { | ||||
| 	__u16 refill[IEEE_8021QAZ_MAX_TCS], max[IEEE_8021QAZ_MAX_TCS]; | ||||
| 	__u8 prio_type[IEEE_8021QAZ_MAX_TCS]; | ||||
| 	int i; | ||||
| 
 | ||||
| 	/* naively give each TC a bwg to map onto CEE hardware */ | ||||
| 	__u8 bwg_id[IEEE_8021QAZ_MAX_TCS] = {0, 1, 2, 3, 4, 5, 6, 7}; | ||||
| 
 | ||||
| 	/* Map TSA onto CEE prio type */ | ||||
| 	for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) { | ||||
| 		switch (ets->tc_tsa[i]) { | ||||
| 		case IEEE_8021QAZ_TSA_STRICT: | ||||
| 			prio_type[i] = 2; | ||||
| 			break; | ||||
| 		case IEEE_8021QAZ_TSA_ETS: | ||||
| 			prio_type[i] = 0; | ||||
| 			break; | ||||
| 		default: | ||||
| 			/* Hardware only supports priority strict or
 | ||||
| 			 * ETS transmission selection algorithms if | ||||
| 			 * we receive some other value from dcbnl | ||||
| 			 * throw an error | ||||
| 			 */ | ||||
| 			return -EINVAL; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	ixgbe_ieee_credits(ets->tc_tx_bw, refill, max, max_frame); | ||||
| 	return ixgbe_dcb_hw_ets_config(hw, refill, max, | ||||
| 				       bwg_id, prio_type, ets->prio_tc); | ||||
| } | ||||
| 
 | ||||
| s32 ixgbe_dcb_hw_ets_config(struct ixgbe_hw *hw, | ||||
| 			    u16 *refill, u16 *max, u8 *bwg_id, | ||||
| 			    u8 *prio_type, u8 *prio_tc) | ||||
| { | ||||
| 	switch (hw->mac.type) { | ||||
| 	case ixgbe_mac_82598EB: | ||||
| 		ixgbe_dcb_config_rx_arbiter_82598(hw, refill, max, | ||||
| 							prio_type); | ||||
| 		ixgbe_dcb_config_tx_desc_arbiter_82598(hw, refill, max, | ||||
| 							     bwg_id, prio_type); | ||||
| 		ixgbe_dcb_config_tx_data_arbiter_82598(hw, refill, max, | ||||
| 							     bwg_id, prio_type); | ||||
| 		break; | ||||
| 	case ixgbe_mac_82599EB: | ||||
| 	case ixgbe_mac_X540: | ||||
| 		ixgbe_dcb_config_rx_arbiter_82599(hw, refill, max, | ||||
| 						  bwg_id, prio_type, prio_tc); | ||||
| 		ixgbe_dcb_config_tx_desc_arbiter_82599(hw, refill, max, | ||||
| 						       bwg_id, prio_type); | ||||
| 		ixgbe_dcb_config_tx_data_arbiter_82599(hw, refill, max, bwg_id, | ||||
| 						       prio_type, prio_tc); | ||||
| 		break; | ||||
| 	default: | ||||
| 		break; | ||||
| 	} | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| static void ixgbe_dcb_read_rtrup2tc_82599(struct ixgbe_hw *hw, u8 *map) | ||||
| { | ||||
| 	u32 reg, i; | ||||
| 
 | ||||
| 	reg = IXGBE_READ_REG(hw, IXGBE_RTRUP2TC); | ||||
| 	for (i = 0; i < MAX_USER_PRIORITY; i++) | ||||
| 		map[i] = IXGBE_RTRUP2TC_UP_MASK & | ||||
| 			(reg >> (i * IXGBE_RTRUP2TC_UP_SHIFT)); | ||||
| } | ||||
| 
 | ||||
| void ixgbe_dcb_read_rtrup2tc(struct ixgbe_hw *hw, u8 *map) | ||||
| { | ||||
| 	switch (hw->mac.type) { | ||||
| 	case ixgbe_mac_82599EB: | ||||
| 	case ixgbe_mac_X540: | ||||
| 		ixgbe_dcb_read_rtrup2tc_82599(hw, map); | ||||
| 		break; | ||||
| 	default: | ||||
| 		break; | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										171
									
								
								drivers/net/ethernet/intel/ixgbe/ixgbe_dcb.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										171
									
								
								drivers/net/ethernet/intel/ixgbe/ixgbe_dcb.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,171 @@ | |||
| /*******************************************************************************
 | ||||
| 
 | ||||
|   Intel 10 Gigabit PCI Express Linux driver | ||||
|   Copyright(c) 1999 - 2013 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: | ||||
|   Linux NICS <linux.nics@intel.com> | ||||
|   e1000-devel Mailing List <e1000-devel@lists.sourceforge.net> | ||||
|   Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 | ||||
| 
 | ||||
| *******************************************************************************/ | ||||
| 
 | ||||
| #ifndef _DCB_CONFIG_H_ | ||||
| #define _DCB_CONFIG_H_ | ||||
| 
 | ||||
| #include <linux/dcbnl.h> | ||||
| #include "ixgbe_type.h" | ||||
| 
 | ||||
| /* DCB data structures */ | ||||
| 
 | ||||
| #define IXGBE_MAX_PACKET_BUFFERS 8 | ||||
| #define MAX_USER_PRIORITY        8 | ||||
| #define MAX_BW_GROUP             8 | ||||
| #define BW_PERCENT               100 | ||||
| 
 | ||||
| #define DCB_TX_CONFIG            0 | ||||
| #define DCB_RX_CONFIG            1 | ||||
| 
 | ||||
| /* DCB error Codes */ | ||||
| #define DCB_SUCCESS              0 | ||||
| #define DCB_ERR_CONFIG           -1 | ||||
| #define DCB_ERR_PARAM            -2 | ||||
| 
 | ||||
| /* Transmit and receive Errors */ | ||||
| /* Error in bandwidth group allocation */ | ||||
| #define DCB_ERR_BW_GROUP        -3 | ||||
| /* Error in traffic class bandwidth allocation */ | ||||
| #define DCB_ERR_TC_BW           -4 | ||||
| /* Traffic class has both link strict and group strict enabled */ | ||||
| #define DCB_ERR_LS_GS           -5 | ||||
| /* Link strict traffic class has non zero bandwidth */ | ||||
| #define DCB_ERR_LS_BW_NONZERO   -6 | ||||
| /* Link strict bandwidth group has non zero bandwidth */ | ||||
| #define DCB_ERR_LS_BWG_NONZERO  -7 | ||||
| /*  Traffic class has zero bandwidth */ | ||||
| #define DCB_ERR_TC_BW_ZERO      -8 | ||||
| 
 | ||||
| #define DCB_NOT_IMPLEMENTED      0x7FFFFFFF | ||||
| 
 | ||||
| struct dcb_pfc_tc_debug { | ||||
| 	u8  tc; | ||||
| 	u8  pause_status; | ||||
| 	u64 pause_quanta; | ||||
| }; | ||||
| 
 | ||||
| enum strict_prio_type { | ||||
| 	prio_none = 0, | ||||
| 	prio_group, | ||||
| 	prio_link | ||||
| }; | ||||
| 
 | ||||
| /* DCB capability definitions */ | ||||
| #define IXGBE_DCB_PG_SUPPORT        0x00000001 | ||||
| #define IXGBE_DCB_PFC_SUPPORT       0x00000002 | ||||
| #define IXGBE_DCB_BCN_SUPPORT       0x00000004 | ||||
| #define IXGBE_DCB_UP2TC_SUPPORT     0x00000008 | ||||
| #define IXGBE_DCB_GSP_SUPPORT       0x00000010 | ||||
| 
 | ||||
| #define IXGBE_DCB_8_TC_SUPPORT      0x80 | ||||
| 
 | ||||
| struct dcb_support { | ||||
| 	/* DCB capabilities */ | ||||
| 	u32 capabilities; | ||||
| 
 | ||||
| 	/* Each bit represents a number of TCs configurable in the hw.
 | ||||
| 	 * If 8 traffic classes can be configured, the value is 0x80. | ||||
| 	 */ | ||||
| 	u8  traffic_classes; | ||||
| 	u8  pfc_traffic_classes; | ||||
| }; | ||||
| 
 | ||||
| /* Traffic class bandwidth allocation per direction */ | ||||
| struct tc_bw_alloc { | ||||
| 	u8 bwg_id;		  /* Bandwidth Group (BWG) ID */ | ||||
| 	u8 bwg_percent;		  /* % of BWG's bandwidth */ | ||||
| 	u8 link_percent;	  /* % of link bandwidth */ | ||||
| 	u8 up_to_tc_bitmap;	  /* User Priority to Traffic Class mapping */ | ||||
| 	u16 data_credits_refill;  /* Credit refill amount in 64B granularity */ | ||||
| 	u16 data_credits_max;	  /* Max credits for a configured packet buffer
 | ||||
| 				   * in 64B granularity.*/ | ||||
| 	enum strict_prio_type prio_type; /* Link or Group Strict Priority */ | ||||
| }; | ||||
| 
 | ||||
| enum dcb_pfc_type { | ||||
| 	pfc_disabled = 0, | ||||
| 	pfc_enabled_full, | ||||
| 	pfc_enabled_tx, | ||||
| 	pfc_enabled_rx | ||||
| }; | ||||
| 
 | ||||
| /* Traffic class configuration */ | ||||
| struct tc_configuration { | ||||
| 	struct tc_bw_alloc path[2]; /* One each for Tx/Rx */ | ||||
| 	enum dcb_pfc_type  dcb_pfc; /* Class based flow control setting */ | ||||
| 
 | ||||
| 	u16 desc_credits_max; /* For Tx Descriptor arbitration */ | ||||
| 	u8 tc; /* Traffic class (TC) */ | ||||
| }; | ||||
| 
 | ||||
| struct dcb_num_tcs { | ||||
| 	u8 pg_tcs; | ||||
| 	u8 pfc_tcs; | ||||
| }; | ||||
| 
 | ||||
| struct ixgbe_dcb_config { | ||||
| 	struct dcb_support support; | ||||
| 	struct dcb_num_tcs num_tcs; | ||||
| 	struct tc_configuration tc_config[MAX_TRAFFIC_CLASS]; | ||||
| 	u8     bw_percentage[2][MAX_BW_GROUP]; /* One each for Tx/Rx */ | ||||
| 	bool   pfc_mode_enable; | ||||
| 
 | ||||
| 	u32  dcb_cfg_version; /* Not used...OS-specific? */ | ||||
| 	u32  link_speed; /* For bandwidth allocation validation purpose */ | ||||
| }; | ||||
| 
 | ||||
| /* DCB driver APIs */ | ||||
| void ixgbe_dcb_unpack_pfc(struct ixgbe_dcb_config *cfg, u8 *pfc_en); | ||||
| void ixgbe_dcb_unpack_refill(struct ixgbe_dcb_config *, int, u16 *); | ||||
| void ixgbe_dcb_unpack_max(struct ixgbe_dcb_config *, u16 *); | ||||
| void ixgbe_dcb_unpack_bwgid(struct ixgbe_dcb_config *, int, u8 *); | ||||
| void ixgbe_dcb_unpack_prio(struct ixgbe_dcb_config *, int, u8 *); | ||||
| void ixgbe_dcb_unpack_map(struct ixgbe_dcb_config *, int, u8 *); | ||||
| u8 ixgbe_dcb_get_tc_from_up(struct ixgbe_dcb_config *, int, u8); | ||||
| 
 | ||||
| /* DCB credits calculation */ | ||||
| s32 ixgbe_dcb_calculate_tc_credits(struct ixgbe_hw *, | ||||
| 				   struct ixgbe_dcb_config *, int, u8); | ||||
| 
 | ||||
| /* DCB hw initialization */ | ||||
| s32 ixgbe_dcb_hw_ets(struct ixgbe_hw *hw, struct ieee_ets *ets, int max); | ||||
| s32 ixgbe_dcb_hw_ets_config(struct ixgbe_hw *hw, u16 *refill, u16 *max, | ||||
| 			    u8 *bwg_id, u8 *prio_type, u8 *tc_prio); | ||||
| s32 ixgbe_dcb_hw_pfc_config(struct ixgbe_hw *hw, u8 pfc_en, u8 *tc_prio); | ||||
| s32 ixgbe_dcb_hw_config(struct ixgbe_hw *, struct ixgbe_dcb_config *); | ||||
| 
 | ||||
| void ixgbe_dcb_read_rtrup2tc(struct ixgbe_hw *hw, u8 *map); | ||||
| 
 | ||||
| /* DCB definitions for credit calculation */ | ||||
| #define DCB_CREDIT_QUANTUM	64   /* DCB Quantum */ | ||||
| #define MAX_CREDIT_REFILL       511  /* 0x1FF * 64B = 32704B */ | ||||
| #define DCB_MAX_TSO_SIZE        (32*1024) /* MAX TSO packet size supported in DCB mode */ | ||||
| #define MINIMUM_CREDIT_FOR_TSO  (DCB_MAX_TSO_SIZE/64 + 1) /* 513 for 32KB TSO packet */ | ||||
| #define MAX_CREDIT              4095 /* Maximum credit supported: 256KB * 1204 / 64B */ | ||||
| 
 | ||||
| #endif /* _DCB_CONFIG_H */ | ||||
							
								
								
									
										288
									
								
								drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_82598.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										288
									
								
								drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_82598.c
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,288 @@ | |||
| /*******************************************************************************
 | ||||
| 
 | ||||
|   Intel 10 Gigabit PCI Express Linux driver | ||||
|   Copyright(c) 1999 - 2013 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: | ||||
|   Linux NICS <linux.nics@intel.com> | ||||
|   e1000-devel Mailing List <e1000-devel@lists.sourceforge.net> | ||||
|   Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 | ||||
| 
 | ||||
| *******************************************************************************/ | ||||
| 
 | ||||
| #include "ixgbe.h" | ||||
| #include "ixgbe_type.h" | ||||
| #include "ixgbe_dcb.h" | ||||
| #include "ixgbe_dcb_82598.h" | ||||
| 
 | ||||
| /**
 | ||||
|  * ixgbe_dcb_config_rx_arbiter_82598 - Config Rx data arbiter | ||||
|  * @hw: pointer to hardware structure | ||||
|  * @dcb_config: pointer to ixgbe_dcb_config structure | ||||
|  * | ||||
|  * Configure Rx Data Arbiter and credits for each traffic class. | ||||
|  */ | ||||
| s32 ixgbe_dcb_config_rx_arbiter_82598(struct ixgbe_hw *hw, | ||||
| 					u16 *refill, | ||||
| 					u16 *max, | ||||
| 					u8 *prio_type) | ||||
| { | ||||
| 	u32    reg           = 0; | ||||
| 	u32    credit_refill = 0; | ||||
| 	u32    credit_max    = 0; | ||||
| 	u8     i             = 0; | ||||
| 
 | ||||
| 	reg = IXGBE_READ_REG(hw, IXGBE_RUPPBMR) | IXGBE_RUPPBMR_MQA; | ||||
| 	IXGBE_WRITE_REG(hw, IXGBE_RUPPBMR, reg); | ||||
| 
 | ||||
| 	reg = IXGBE_READ_REG(hw, IXGBE_RMCS); | ||||
| 	/* Enable Arbiter */ | ||||
| 	reg &= ~IXGBE_RMCS_ARBDIS; | ||||
| 	/* Enable Receive Recycle within the BWG */ | ||||
| 	reg |= IXGBE_RMCS_RRM; | ||||
| 	/* Enable Deficit Fixed Priority arbitration*/ | ||||
| 	reg |= IXGBE_RMCS_DFP; | ||||
| 
 | ||||
| 	IXGBE_WRITE_REG(hw, IXGBE_RMCS, reg); | ||||
| 
 | ||||
| 	/* Configure traffic class credits and priority */ | ||||
| 	for (i = 0; i < MAX_TRAFFIC_CLASS; i++) { | ||||
| 		credit_refill = refill[i]; | ||||
| 		credit_max    = max[i]; | ||||
| 
 | ||||
| 		reg = credit_refill | (credit_max << IXGBE_RT2CR_MCL_SHIFT); | ||||
| 
 | ||||
| 		if (prio_type[i] == prio_link) | ||||
| 			reg |= IXGBE_RT2CR_LSP; | ||||
| 
 | ||||
| 		IXGBE_WRITE_REG(hw, IXGBE_RT2CR(i), reg); | ||||
| 	} | ||||
| 
 | ||||
| 	reg = IXGBE_READ_REG(hw, IXGBE_RDRXCTL); | ||||
| 	reg |= IXGBE_RDRXCTL_RDMTS_1_2; | ||||
| 	reg |= IXGBE_RDRXCTL_MPBEN; | ||||
| 	reg |= IXGBE_RDRXCTL_MCEN; | ||||
| 	IXGBE_WRITE_REG(hw, IXGBE_RDRXCTL, reg); | ||||
| 
 | ||||
| 	reg = IXGBE_READ_REG(hw, IXGBE_RXCTRL); | ||||
| 	/* Make sure there is enough descriptors before arbitration */ | ||||
| 	reg &= ~IXGBE_RXCTRL_DMBYPS; | ||||
| 	IXGBE_WRITE_REG(hw, IXGBE_RXCTRL, reg); | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  * ixgbe_dcb_config_tx_desc_arbiter_82598 - Config Tx Desc. arbiter | ||||
|  * @hw: pointer to hardware structure | ||||
|  * @dcb_config: pointer to ixgbe_dcb_config structure | ||||
|  * | ||||
|  * Configure Tx Descriptor Arbiter and credits for each traffic class. | ||||
|  */ | ||||
| s32 ixgbe_dcb_config_tx_desc_arbiter_82598(struct ixgbe_hw *hw, | ||||
| 						u16 *refill, | ||||
| 						u16 *max, | ||||
| 						u8 *bwg_id, | ||||
| 						u8 *prio_type) | ||||
| { | ||||
| 	u32    reg, max_credits; | ||||
| 	u8     i; | ||||
| 
 | ||||
| 	reg = IXGBE_READ_REG(hw, IXGBE_DPMCS); | ||||
| 
 | ||||
| 	/* Enable arbiter */ | ||||
| 	reg &= ~IXGBE_DPMCS_ARBDIS; | ||||
| 	reg |= IXGBE_DPMCS_TSOEF; | ||||
| 
 | ||||
| 	/* Configure Max TSO packet size 34KB including payload and headers */ | ||||
| 	reg |= (0x4 << IXGBE_DPMCS_MTSOS_SHIFT); | ||||
| 
 | ||||
| 	IXGBE_WRITE_REG(hw, IXGBE_DPMCS, reg); | ||||
| 
 | ||||
| 	/* Configure traffic class credits and priority */ | ||||
| 	for (i = 0; i < MAX_TRAFFIC_CLASS; i++) { | ||||
| 		max_credits = max[i]; | ||||
| 		reg = max_credits << IXGBE_TDTQ2TCCR_MCL_SHIFT; | ||||
| 		reg |= refill[i]; | ||||
| 		reg |= (u32)(bwg_id[i]) << IXGBE_TDTQ2TCCR_BWG_SHIFT; | ||||
| 
 | ||||
| 		if (prio_type[i] == prio_group) | ||||
| 			reg |= IXGBE_TDTQ2TCCR_GSP; | ||||
| 
 | ||||
| 		if (prio_type[i] == prio_link) | ||||
| 			reg |= IXGBE_TDTQ2TCCR_LSP; | ||||
| 
 | ||||
| 		IXGBE_WRITE_REG(hw, IXGBE_TDTQ2TCCR(i), reg); | ||||
| 	} | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  * ixgbe_dcb_config_tx_data_arbiter_82598 - Config Tx data arbiter | ||||
|  * @hw: pointer to hardware structure | ||||
|  * @dcb_config: pointer to ixgbe_dcb_config structure | ||||
|  * | ||||
|  * Configure Tx Data Arbiter and credits for each traffic class. | ||||
|  */ | ||||
| s32 ixgbe_dcb_config_tx_data_arbiter_82598(struct ixgbe_hw *hw, | ||||
| 						u16 *refill, | ||||
| 						u16 *max, | ||||
| 						u8 *bwg_id, | ||||
| 						u8 *prio_type) | ||||
| { | ||||
| 	u32 reg; | ||||
| 	u8 i; | ||||
| 
 | ||||
| 	reg = IXGBE_READ_REG(hw, IXGBE_PDPMCS); | ||||
| 	/* Enable Data Plane Arbiter */ | ||||
| 	reg &= ~IXGBE_PDPMCS_ARBDIS; | ||||
| 	/* Enable DFP and Transmit Recycle Mode */ | ||||
| 	reg |= (IXGBE_PDPMCS_TPPAC | IXGBE_PDPMCS_TRM); | ||||
| 
 | ||||
| 	IXGBE_WRITE_REG(hw, IXGBE_PDPMCS, reg); | ||||
| 
 | ||||
| 	/* Configure traffic class credits and priority */ | ||||
| 	for (i = 0; i < MAX_TRAFFIC_CLASS; i++) { | ||||
| 		reg = refill[i]; | ||||
| 		reg |= (u32)(max[i]) << IXGBE_TDPT2TCCR_MCL_SHIFT; | ||||
| 		reg |= (u32)(bwg_id[i]) << IXGBE_TDPT2TCCR_BWG_SHIFT; | ||||
| 
 | ||||
| 		if (prio_type[i] == prio_group) | ||||
| 			reg |= IXGBE_TDPT2TCCR_GSP; | ||||
| 
 | ||||
| 		if (prio_type[i] == prio_link) | ||||
| 			reg |= IXGBE_TDPT2TCCR_LSP; | ||||
| 
 | ||||
| 		IXGBE_WRITE_REG(hw, IXGBE_TDPT2TCCR(i), reg); | ||||
| 	} | ||||
| 
 | ||||
| 	/* Enable Tx packet buffer division */ | ||||
| 	reg = IXGBE_READ_REG(hw, IXGBE_DTXCTL); | ||||
| 	reg |= IXGBE_DTXCTL_ENDBUBD; | ||||
| 	IXGBE_WRITE_REG(hw, IXGBE_DTXCTL, reg); | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  * ixgbe_dcb_config_pfc_82598 - Config priority flow control | ||||
|  * @hw: pointer to hardware structure | ||||
|  * @dcb_config: pointer to ixgbe_dcb_config structure | ||||
|  * | ||||
|  * Configure Priority Flow Control for each traffic class. | ||||
|  */ | ||||
| s32 ixgbe_dcb_config_pfc_82598(struct ixgbe_hw *hw, u8 pfc_en) | ||||
| { | ||||
| 	u32 fcrtl, reg; | ||||
| 	u8  i; | ||||
| 
 | ||||
| 	/* Enable Transmit Priority Flow Control */ | ||||
| 	reg = IXGBE_READ_REG(hw, IXGBE_RMCS); | ||||
| 	reg &= ~IXGBE_RMCS_TFCE_802_3X; | ||||
| 	reg |= IXGBE_RMCS_TFCE_PRIORITY; | ||||
| 	IXGBE_WRITE_REG(hw, IXGBE_RMCS, reg); | ||||
| 
 | ||||
| 	/* Enable Receive Priority Flow Control */ | ||||
| 	reg = IXGBE_READ_REG(hw, IXGBE_FCTRL); | ||||
| 	reg &= ~(IXGBE_FCTRL_RPFCE | IXGBE_FCTRL_RFCE); | ||||
| 
 | ||||
| 	if (pfc_en) | ||||
| 		reg |= IXGBE_FCTRL_RPFCE; | ||||
| 
 | ||||
| 	IXGBE_WRITE_REG(hw, IXGBE_FCTRL, reg); | ||||
| 
 | ||||
| 	/* Configure PFC Tx thresholds per TC */ | ||||
| 	for (i = 0; i < MAX_TRAFFIC_CLASS; i++) { | ||||
| 		if (!(pfc_en & (1 << i))) { | ||||
| 			IXGBE_WRITE_REG(hw, IXGBE_FCRTL(i), 0); | ||||
| 			IXGBE_WRITE_REG(hw, IXGBE_FCRTH(i), 0); | ||||
| 			continue; | ||||
| 		} | ||||
| 
 | ||||
| 		fcrtl = (hw->fc.low_water[i] << 10) | IXGBE_FCRTL_XONE; | ||||
| 		reg = (hw->fc.high_water[i] << 10) | IXGBE_FCRTH_FCEN; | ||||
| 		IXGBE_WRITE_REG(hw, IXGBE_FCRTL(i), fcrtl); | ||||
| 		IXGBE_WRITE_REG(hw, IXGBE_FCRTH(i), reg); | ||||
| 	} | ||||
| 
 | ||||
| 	/* Configure pause time */ | ||||
| 	reg = hw->fc.pause_time * 0x00010001; | ||||
| 	for (i = 0; i < (MAX_TRAFFIC_CLASS / 2); i++) | ||||
| 		IXGBE_WRITE_REG(hw, IXGBE_FCTTV(i), reg); | ||||
| 
 | ||||
| 	/* Configure flow control refresh threshold value */ | ||||
| 	IXGBE_WRITE_REG(hw, IXGBE_FCRTV, hw->fc.pause_time / 2); | ||||
| 
 | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  * ixgbe_dcb_config_tc_stats_82598 - Configure traffic class statistics | ||||
|  * @hw: pointer to hardware structure | ||||
|  * | ||||
|  * Configure queue statistics registers, all queues belonging to same traffic | ||||
|  * class uses a single set of queue statistics counters. | ||||
|  */ | ||||
| static s32 ixgbe_dcb_config_tc_stats_82598(struct ixgbe_hw *hw) | ||||
| { | ||||
| 	u32 reg = 0; | ||||
| 	u8  i   = 0; | ||||
| 	u8  j   = 0; | ||||
| 
 | ||||
| 	/* Receive Queues stats setting -  8 queues per statistics reg */ | ||||
| 	for (i = 0, j = 0; i < 15 && j < 8; i = i + 2, j++) { | ||||
| 		reg = IXGBE_READ_REG(hw, IXGBE_RQSMR(i)); | ||||
| 		reg |= ((0x1010101) * j); | ||||
| 		IXGBE_WRITE_REG(hw, IXGBE_RQSMR(i), reg); | ||||
| 		reg = IXGBE_READ_REG(hw, IXGBE_RQSMR(i + 1)); | ||||
| 		reg |= ((0x1010101) * j); | ||||
| 		IXGBE_WRITE_REG(hw, IXGBE_RQSMR(i + 1), reg); | ||||
| 	} | ||||
| 	/* Transmit Queues stats setting -  4 queues per statistics reg */ | ||||
| 	for (i = 0; i < 8; i++) { | ||||
| 		reg = IXGBE_READ_REG(hw, IXGBE_TQSMR(i)); | ||||
| 		reg |= ((0x1010101) * i); | ||||
| 		IXGBE_WRITE_REG(hw, IXGBE_TQSMR(i), reg); | ||||
| 	} | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  * ixgbe_dcb_hw_config_82598 - Config and enable DCB | ||||
|  * @hw: pointer to hardware structure | ||||
|  * @dcb_config: pointer to ixgbe_dcb_config structure | ||||
|  * | ||||
|  * Configure dcb settings and enable dcb mode. | ||||
|  */ | ||||
| s32 ixgbe_dcb_hw_config_82598(struct ixgbe_hw *hw, u8 pfc_en, u16 *refill, | ||||
| 			      u16 *max, u8 *bwg_id, u8 *prio_type) | ||||
| { | ||||
| 	ixgbe_dcb_config_rx_arbiter_82598(hw, refill, max, prio_type); | ||||
| 	ixgbe_dcb_config_tx_desc_arbiter_82598(hw, refill, max, | ||||
| 					       bwg_id, prio_type); | ||||
| 	ixgbe_dcb_config_tx_data_arbiter_82598(hw, refill, max, | ||||
| 					       bwg_id, prio_type); | ||||
| 	ixgbe_dcb_config_pfc_82598(hw, pfc_en); | ||||
| 	ixgbe_dcb_config_tc_stats_82598(hw); | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
							
								
								
									
										97
									
								
								drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_82598.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										97
									
								
								drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_82598.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,97 @@ | |||
| /*******************************************************************************
 | ||||
| 
 | ||||
|   Intel 10 Gigabit PCI Express Linux driver | ||||
|   Copyright(c) 1999 - 2013 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: | ||||
|   Linux NICS <linux.nics@intel.com> | ||||
|   e1000-devel Mailing List <e1000-devel@lists.sourceforge.net> | ||||
|   Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 | ||||
| 
 | ||||
| *******************************************************************************/ | ||||
| 
 | ||||
| #ifndef _DCB_82598_CONFIG_H_ | ||||
| #define _DCB_82598_CONFIG_H_ | ||||
| 
 | ||||
| /* DCB register definitions */ | ||||
| 
 | ||||
| #define IXGBE_DPMCS_MTSOS_SHIFT 16 | ||||
| #define IXGBE_DPMCS_TDPAC       0x00000001 /* 0 Round Robin, 1 DFP - Deficit Fixed Priority */ | ||||
| #define IXGBE_DPMCS_TRM         0x00000010 /* Transmit Recycle Mode */ | ||||
| #define IXGBE_DPMCS_ARBDIS      0x00000040 /* DCB arbiter disable */ | ||||
| #define IXGBE_DPMCS_TSOEF       0x00080000 /* TSO Expand Factor: 0=x4, 1=x2 */ | ||||
| 
 | ||||
| #define IXGBE_RUPPBMR_MQA       0x80000000 /* Enable UP to queue mapping */ | ||||
| 
 | ||||
| #define IXGBE_RT2CR_MCL_SHIFT   12 /* Offset to Max Credit Limit setting */ | ||||
| #define IXGBE_RT2CR_LSP         0x80000000 /* LSP enable bit */ | ||||
| 
 | ||||
| #define IXGBE_RDRXCTL_MPBEN     0x00000010 /* DMA config for multiple packet buffers enable */ | ||||
| #define IXGBE_RDRXCTL_MCEN      0x00000040 /* DMA config for multiple cores (RSS) enable */ | ||||
| 
 | ||||
| #define IXGBE_TDTQ2TCCR_MCL_SHIFT   12 | ||||
| #define IXGBE_TDTQ2TCCR_BWG_SHIFT   9 | ||||
| #define IXGBE_TDTQ2TCCR_GSP     0x40000000 | ||||
| #define IXGBE_TDTQ2TCCR_LSP     0x80000000 | ||||
| 
 | ||||
| #define IXGBE_TDPT2TCCR_MCL_SHIFT   12 | ||||
| #define IXGBE_TDPT2TCCR_BWG_SHIFT   9 | ||||
| #define IXGBE_TDPT2TCCR_GSP     0x40000000 | ||||
| #define IXGBE_TDPT2TCCR_LSP     0x80000000 | ||||
| 
 | ||||
| #define IXGBE_PDPMCS_TPPAC      0x00000020 /* 0 Round Robin, 1 for DFP - Deficit Fixed Priority */ | ||||
| #define IXGBE_PDPMCS_ARBDIS     0x00000040 /* Arbiter disable */ | ||||
| #define IXGBE_PDPMCS_TRM        0x00000100 /* Transmit Recycle Mode enable */ | ||||
| 
 | ||||
| #define IXGBE_DTXCTL_ENDBUBD    0x00000004 /* Enable DBU buffer division */ | ||||
| 
 | ||||
| #define IXGBE_TXPBSIZE_40KB     0x0000A000 /* 40KB Packet Buffer */ | ||||
| #define IXGBE_RXPBSIZE_48KB     0x0000C000 /* 48KB Packet Buffer */ | ||||
| #define IXGBE_RXPBSIZE_64KB     0x00010000 /* 64KB Packet Buffer */ | ||||
| #define IXGBE_RXPBSIZE_80KB     0x00014000 /* 80KB Packet Buffer */ | ||||
| 
 | ||||
| #define IXGBE_RDRXCTL_RDMTS_1_2 0x00000000 | ||||
| 
 | ||||
| /* DCB hardware-specific driver APIs */ | ||||
| 
 | ||||
| /* DCB PFC functions */ | ||||
| s32 ixgbe_dcb_config_pfc_82598(struct ixgbe_hw *, u8 pfc_en); | ||||
| 
 | ||||
| /* DCB hw initialization */ | ||||
| s32 ixgbe_dcb_config_rx_arbiter_82598(struct ixgbe_hw *hw, | ||||
| 					u16 *refill, | ||||
| 					u16 *max, | ||||
| 					u8 *prio_type); | ||||
| 
 | ||||
| s32 ixgbe_dcb_config_tx_desc_arbiter_82598(struct ixgbe_hw *hw, | ||||
| 						u16 *refill, | ||||
| 						u16 *max, | ||||
| 						u8 *bwg_id, | ||||
| 						u8 *prio_type); | ||||
| 
 | ||||
| s32 ixgbe_dcb_config_tx_data_arbiter_82598(struct ixgbe_hw *hw, | ||||
| 						u16 *refill, | ||||
| 						u16 *max, | ||||
| 						u8 *bwg_id, | ||||
| 						u8 *prio_type); | ||||
| 
 | ||||
| s32 ixgbe_dcb_hw_config_82598(struct ixgbe_hw *hw, u8 pfc_en, u16 *refill, | ||||
| 			      u16 *max, u8 *bwg_id, u8 *prio_type); | ||||
| 
 | ||||
| #endif /* _DCB_82598_CONFIG_H */ | ||||
							
								
								
									
										363
									
								
								drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_82599.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										363
									
								
								drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_82599.c
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,363 @@ | |||
| /*******************************************************************************
 | ||||
| 
 | ||||
|   Intel 10 Gigabit PCI Express Linux driver | ||||
|   Copyright(c) 1999 - 2013 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: | ||||
|   Linux NICS <linux.nics@intel.com> | ||||
|   e1000-devel Mailing List <e1000-devel@lists.sourceforge.net> | ||||
|   Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 | ||||
| 
 | ||||
| *******************************************************************************/ | ||||
| 
 | ||||
| #include "ixgbe.h" | ||||
| #include "ixgbe_type.h" | ||||
| #include "ixgbe_dcb.h" | ||||
| #include "ixgbe_dcb_82599.h" | ||||
| 
 | ||||
| /**
 | ||||
|  * ixgbe_dcb_config_rx_arbiter_82599 - Config Rx Data arbiter | ||||
|  * @hw: pointer to hardware structure | ||||
|  * @refill: refill credits index by traffic class | ||||
|  * @max: max credits index by traffic class | ||||
|  * @bwg_id: bandwidth grouping indexed by traffic class | ||||
|  * @prio_type: priority type indexed by traffic class | ||||
|  * | ||||
|  * Configure Rx Packet Arbiter and credits for each traffic class. | ||||
|  */ | ||||
| s32 ixgbe_dcb_config_rx_arbiter_82599(struct ixgbe_hw *hw, | ||||
| 				      u16 *refill, | ||||
| 				      u16 *max, | ||||
| 				      u8 *bwg_id, | ||||
| 				      u8 *prio_type, | ||||
| 				      u8 *prio_tc) | ||||
| { | ||||
| 	u32    reg           = 0; | ||||
| 	u32    credit_refill = 0; | ||||
| 	u32    credit_max    = 0; | ||||
| 	u8     i             = 0; | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * Disable the arbiter before changing parameters | ||||
| 	 * (always enable recycle mode; WSP) | ||||
| 	 */ | ||||
| 	reg = IXGBE_RTRPCS_RRM | IXGBE_RTRPCS_RAC | IXGBE_RTRPCS_ARBDIS; | ||||
| 	IXGBE_WRITE_REG(hw, IXGBE_RTRPCS, reg); | ||||
| 
 | ||||
| 	/* Map all traffic classes to their UP */ | ||||
| 	reg = 0; | ||||
| 	for (i = 0; i < MAX_USER_PRIORITY; i++) | ||||
| 		reg |= (prio_tc[i] << (i * IXGBE_RTRUP2TC_UP_SHIFT)); | ||||
| 	IXGBE_WRITE_REG(hw, IXGBE_RTRUP2TC, reg); | ||||
| 
 | ||||
| 	/* Configure traffic class credits and priority */ | ||||
| 	for (i = 0; i < MAX_TRAFFIC_CLASS; i++) { | ||||
| 		credit_refill = refill[i]; | ||||
| 		credit_max    = max[i]; | ||||
| 		reg = credit_refill | (credit_max << IXGBE_RTRPT4C_MCL_SHIFT); | ||||
| 
 | ||||
| 		reg |= (u32)(bwg_id[i]) << IXGBE_RTRPT4C_BWG_SHIFT; | ||||
| 
 | ||||
| 		if (prio_type[i] == prio_link) | ||||
| 			reg |= IXGBE_RTRPT4C_LSP; | ||||
| 
 | ||||
| 		IXGBE_WRITE_REG(hw, IXGBE_RTRPT4C(i), reg); | ||||
| 	} | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * Configure Rx packet plane (recycle mode; WSP) and | ||||
| 	 * enable arbiter | ||||
| 	 */ | ||||
| 	reg = IXGBE_RTRPCS_RRM | IXGBE_RTRPCS_RAC; | ||||
| 	IXGBE_WRITE_REG(hw, IXGBE_RTRPCS, reg); | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  * ixgbe_dcb_config_tx_desc_arbiter_82599 - Config Tx Desc. arbiter | ||||
|  * @hw: pointer to hardware structure | ||||
|  * @refill: refill credits index by traffic class | ||||
|  * @max: max credits index by traffic class | ||||
|  * @bwg_id: bandwidth grouping indexed by traffic class | ||||
|  * @prio_type: priority type indexed by traffic class | ||||
|  * | ||||
|  * Configure Tx Descriptor Arbiter and credits for each traffic class. | ||||
|  */ | ||||
| s32 ixgbe_dcb_config_tx_desc_arbiter_82599(struct ixgbe_hw *hw, | ||||
| 					   u16 *refill, | ||||
| 					   u16 *max, | ||||
| 					   u8 *bwg_id, | ||||
| 					   u8 *prio_type) | ||||
| { | ||||
| 	u32    reg, max_credits; | ||||
| 	u8     i; | ||||
| 
 | ||||
| 	/* Clear the per-Tx queue credits; we use per-TC instead */ | ||||
| 	for (i = 0; i < 128; i++) { | ||||
| 		IXGBE_WRITE_REG(hw, IXGBE_RTTDQSEL, i); | ||||
| 		IXGBE_WRITE_REG(hw, IXGBE_RTTDT1C, 0); | ||||
| 	} | ||||
| 
 | ||||
| 	/* Configure traffic class credits and priority */ | ||||
| 	for (i = 0; i < MAX_TRAFFIC_CLASS; i++) { | ||||
| 		max_credits = max[i]; | ||||
| 		reg = max_credits << IXGBE_RTTDT2C_MCL_SHIFT; | ||||
| 		reg |= refill[i]; | ||||
| 		reg |= (u32)(bwg_id[i]) << IXGBE_RTTDT2C_BWG_SHIFT; | ||||
| 
 | ||||
| 		if (prio_type[i] == prio_group) | ||||
| 			reg |= IXGBE_RTTDT2C_GSP; | ||||
| 
 | ||||
| 		if (prio_type[i] == prio_link) | ||||
| 			reg |= IXGBE_RTTDT2C_LSP; | ||||
| 
 | ||||
| 		IXGBE_WRITE_REG(hw, IXGBE_RTTDT2C(i), reg); | ||||
| 	} | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * Configure Tx descriptor plane (recycle mode; WSP) and | ||||
| 	 * enable arbiter | ||||
| 	 */ | ||||
| 	reg = IXGBE_RTTDCS_TDPAC | IXGBE_RTTDCS_TDRM; | ||||
| 	IXGBE_WRITE_REG(hw, IXGBE_RTTDCS, reg); | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  * ixgbe_dcb_config_tx_data_arbiter_82599 - Config Tx Data arbiter | ||||
|  * @hw: pointer to hardware structure | ||||
|  * @refill: refill credits index by traffic class | ||||
|  * @max: max credits index by traffic class | ||||
|  * @bwg_id: bandwidth grouping indexed by traffic class | ||||
|  * @prio_type: priority type indexed by traffic class | ||||
|  * | ||||
|  * Configure Tx Packet Arbiter and credits for each traffic class. | ||||
|  */ | ||||
| s32 ixgbe_dcb_config_tx_data_arbiter_82599(struct ixgbe_hw *hw, | ||||
| 					   u16 *refill, | ||||
| 					   u16 *max, | ||||
| 					   u8 *bwg_id, | ||||
| 					   u8 *prio_type, | ||||
| 					   u8 *prio_tc) | ||||
| { | ||||
| 	u32 reg; | ||||
| 	u8 i; | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * Disable the arbiter before changing parameters | ||||
| 	 * (always enable recycle mode; SP; arb delay) | ||||
| 	 */ | ||||
| 	reg = IXGBE_RTTPCS_TPPAC | IXGBE_RTTPCS_TPRM | | ||||
| 	      (IXGBE_RTTPCS_ARBD_DCB << IXGBE_RTTPCS_ARBD_SHIFT) | | ||||
| 	      IXGBE_RTTPCS_ARBDIS; | ||||
| 	IXGBE_WRITE_REG(hw, IXGBE_RTTPCS, reg); | ||||
| 
 | ||||
| 	/* Map all traffic classes to their UP */ | ||||
| 	reg = 0; | ||||
| 	for (i = 0; i < MAX_USER_PRIORITY; i++) | ||||
| 		reg |= (prio_tc[i] << (i * IXGBE_RTTUP2TC_UP_SHIFT)); | ||||
| 	IXGBE_WRITE_REG(hw, IXGBE_RTTUP2TC, reg); | ||||
| 
 | ||||
| 	/* Configure traffic class credits and priority */ | ||||
| 	for (i = 0; i < MAX_TRAFFIC_CLASS; i++) { | ||||
| 		reg = refill[i]; | ||||
| 		reg |= (u32)(max[i]) << IXGBE_RTTPT2C_MCL_SHIFT; | ||||
| 		reg |= (u32)(bwg_id[i]) << IXGBE_RTTPT2C_BWG_SHIFT; | ||||
| 
 | ||||
| 		if (prio_type[i] == prio_group) | ||||
| 			reg |= IXGBE_RTTPT2C_GSP; | ||||
| 
 | ||||
| 		if (prio_type[i] == prio_link) | ||||
| 			reg |= IXGBE_RTTPT2C_LSP; | ||||
| 
 | ||||
| 		IXGBE_WRITE_REG(hw, IXGBE_RTTPT2C(i), reg); | ||||
| 	} | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * Configure Tx packet plane (recycle mode; SP; arb delay) and | ||||
| 	 * enable arbiter | ||||
| 	 */ | ||||
| 	reg = IXGBE_RTTPCS_TPPAC | IXGBE_RTTPCS_TPRM | | ||||
| 	      (IXGBE_RTTPCS_ARBD_DCB << IXGBE_RTTPCS_ARBD_SHIFT); | ||||
| 	IXGBE_WRITE_REG(hw, IXGBE_RTTPCS, reg); | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  * ixgbe_dcb_config_pfc_82599 - Configure priority flow control | ||||
|  * @hw: pointer to hardware structure | ||||
|  * @pfc_en: enabled pfc bitmask | ||||
|  * @prio_tc: priority to tc assignments indexed by priority | ||||
|  * | ||||
|  * Configure Priority Flow Control (PFC) for each traffic class. | ||||
|  */ | ||||
| s32 ixgbe_dcb_config_pfc_82599(struct ixgbe_hw *hw, u8 pfc_en, u8 *prio_tc) | ||||
| { | ||||
| 	u32 i, j, fcrtl, reg; | ||||
| 	u8 max_tc = 0; | ||||
| 
 | ||||
| 	/* Enable Transmit Priority Flow Control */ | ||||
| 	IXGBE_WRITE_REG(hw, IXGBE_FCCFG, IXGBE_FCCFG_TFCE_PRIORITY); | ||||
| 
 | ||||
| 	/* Enable Receive Priority Flow Control */ | ||||
| 	reg = IXGBE_READ_REG(hw, IXGBE_MFLCN); | ||||
| 	reg |= IXGBE_MFLCN_DPF; | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * X540 supports per TC Rx priority flow control.  So | ||||
| 	 * clear all TCs and only enable those that should be | ||||
| 	 * enabled. | ||||
| 	 */ | ||||
| 	reg &= ~(IXGBE_MFLCN_RPFCE_MASK | IXGBE_MFLCN_RFCE); | ||||
| 
 | ||||
| 	if (hw->mac.type == ixgbe_mac_X540) | ||||
| 		reg |= pfc_en << IXGBE_MFLCN_RPFCE_SHIFT; | ||||
| 
 | ||||
| 	if (pfc_en) | ||||
| 		reg |= IXGBE_MFLCN_RPFCE; | ||||
| 
 | ||||
| 	IXGBE_WRITE_REG(hw, IXGBE_MFLCN, reg); | ||||
| 
 | ||||
| 	for (i = 0; i < MAX_USER_PRIORITY; i++) { | ||||
| 		if (prio_tc[i] > max_tc) | ||||
| 			max_tc = prio_tc[i]; | ||||
| 	} | ||||
| 
 | ||||
| 
 | ||||
| 	/* Configure PFC Tx thresholds per TC */ | ||||
| 	for (i = 0; i <= max_tc; i++) { | ||||
| 		int enabled = 0; | ||||
| 
 | ||||
| 		for (j = 0; j < MAX_USER_PRIORITY; j++) { | ||||
| 			if ((prio_tc[j] == i) && (pfc_en & (1 << j))) { | ||||
| 				enabled = 1; | ||||
| 				break; | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		if (enabled) { | ||||
| 			reg = (hw->fc.high_water[i] << 10) | IXGBE_FCRTH_FCEN; | ||||
| 			fcrtl = (hw->fc.low_water[i] << 10) | IXGBE_FCRTL_XONE; | ||||
| 			IXGBE_WRITE_REG(hw, IXGBE_FCRTL_82599(i), fcrtl); | ||||
| 		} else { | ||||
| 			reg = IXGBE_READ_REG(hw, IXGBE_RXPBSIZE(i)) - 32; | ||||
| 			IXGBE_WRITE_REG(hw, IXGBE_FCRTL_82599(i), 0); | ||||
| 		} | ||||
| 
 | ||||
| 		IXGBE_WRITE_REG(hw, IXGBE_FCRTH_82599(i), reg); | ||||
| 	} | ||||
| 
 | ||||
| 	for (; i < MAX_TRAFFIC_CLASS; i++) { | ||||
| 		IXGBE_WRITE_REG(hw, IXGBE_FCRTL_82599(i), 0); | ||||
| 		IXGBE_WRITE_REG(hw, IXGBE_FCRTH_82599(i), 0); | ||||
| 	} | ||||
| 
 | ||||
| 	/* Configure pause time (2 TCs per register) */ | ||||
| 	reg = hw->fc.pause_time * 0x00010001; | ||||
| 	for (i = 0; i < (MAX_TRAFFIC_CLASS / 2); i++) | ||||
| 		IXGBE_WRITE_REG(hw, IXGBE_FCTTV(i), reg); | ||||
| 
 | ||||
| 	/* Configure flow control refresh threshold value */ | ||||
| 	IXGBE_WRITE_REG(hw, IXGBE_FCRTV, hw->fc.pause_time / 2); | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  * ixgbe_dcb_config_tc_stats_82599 - Config traffic class statistics | ||||
|  * @hw: pointer to hardware structure | ||||
|  * | ||||
|  * Configure queue statistics registers, all queues belonging to same traffic | ||||
|  * class uses a single set of queue statistics counters. | ||||
|  */ | ||||
| static s32 ixgbe_dcb_config_tc_stats_82599(struct ixgbe_hw *hw) | ||||
| { | ||||
| 	u32 reg = 0; | ||||
| 	u8  i   = 0; | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * Receive Queues stats setting | ||||
| 	 * 32 RQSMR registers, each configuring 4 queues. | ||||
| 	 * Set all 16 queues of each TC to the same stat | ||||
| 	 * with TC 'n' going to stat 'n'. | ||||
| 	 */ | ||||
| 	for (i = 0; i < 32; i++) { | ||||
| 		reg = 0x01010101 * (i / 4); | ||||
| 		IXGBE_WRITE_REG(hw, IXGBE_RQSMR(i), reg); | ||||
| 	} | ||||
| 	/*
 | ||||
| 	 * Transmit Queues stats setting | ||||
| 	 * 32 TQSM registers, each controlling 4 queues. | ||||
| 	 * Set all queues of each TC to the same stat | ||||
| 	 * with TC 'n' going to stat 'n'. | ||||
| 	 * Tx queues are allocated non-uniformly to TCs: | ||||
| 	 * 32, 32, 16, 16, 8, 8, 8, 8. | ||||
| 	 */ | ||||
| 	for (i = 0; i < 32; i++) { | ||||
| 		if (i < 8) | ||||
| 			reg = 0x00000000; | ||||
| 		else if (i < 16) | ||||
| 			reg = 0x01010101; | ||||
| 		else if (i < 20) | ||||
| 			reg = 0x02020202; | ||||
| 		else if (i < 24) | ||||
| 			reg = 0x03030303; | ||||
| 		else if (i < 26) | ||||
| 			reg = 0x04040404; | ||||
| 		else if (i < 28) | ||||
| 			reg = 0x05050505; | ||||
| 		else if (i < 30) | ||||
| 			reg = 0x06060606; | ||||
| 		else | ||||
| 			reg = 0x07070707; | ||||
| 		IXGBE_WRITE_REG(hw, IXGBE_TQSM(i), reg); | ||||
| 	} | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  * ixgbe_dcb_hw_config_82599 - Configure and enable DCB | ||||
|  * @hw: pointer to hardware structure | ||||
|  * @refill: refill credits index by traffic class | ||||
|  * @max: max credits index by traffic class | ||||
|  * @bwg_id: bandwidth grouping indexed by traffic class | ||||
|  * @prio_type: priority type indexed by traffic class | ||||
|  * @pfc_en: enabled pfc bitmask | ||||
|  * | ||||
|  * Configure dcb settings and enable dcb mode. | ||||
|  */ | ||||
| s32 ixgbe_dcb_hw_config_82599(struct ixgbe_hw *hw, u8 pfc_en, u16 *refill, | ||||
| 			      u16 *max, u8 *bwg_id, u8 *prio_type, u8 *prio_tc) | ||||
| { | ||||
| 	ixgbe_dcb_config_rx_arbiter_82599(hw, refill, max, bwg_id, | ||||
| 					  prio_type, prio_tc); | ||||
| 	ixgbe_dcb_config_tx_desc_arbiter_82599(hw, refill, max, | ||||
| 					       bwg_id, prio_type); | ||||
| 	ixgbe_dcb_config_tx_data_arbiter_82599(hw, refill, max, | ||||
| 					       bwg_id, prio_type, prio_tc); | ||||
| 	ixgbe_dcb_config_pfc_82599(hw, pfc_en, prio_tc); | ||||
| 	ixgbe_dcb_config_tc_stats_82599(hw); | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
							
								
								
									
										125
									
								
								drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_82599.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										125
									
								
								drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_82599.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,125 @@ | |||
| /*******************************************************************************
 | ||||
| 
 | ||||
|   Intel 10 Gigabit PCI Express Linux driver | ||||
|   Copyright(c) 1999 - 2013 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: | ||||
|   Linux NICS <linux.nics@intel.com> | ||||
|   e1000-devel Mailing List <e1000-devel@lists.sourceforge.net> | ||||
|   Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 | ||||
| 
 | ||||
| *******************************************************************************/ | ||||
| 
 | ||||
| #ifndef _DCB_82599_CONFIG_H_ | ||||
| #define _DCB_82599_CONFIG_H_ | ||||
| 
 | ||||
| /* DCB register definitions */ | ||||
| #define IXGBE_RTTDCS_TDPAC      0x00000001 /* 0 Round Robin, | ||||
| 					    * 1 WSP - Weighted Strict Priority | ||||
| 					    */ | ||||
| #define IXGBE_RTTDCS_VMPAC      0x00000002 /* 0 Round Robin, | ||||
| 					    * 1 WRR - Weighted Round Robin | ||||
| 					    */ | ||||
| #define IXGBE_RTTDCS_TDRM       0x00000010 /* Transmit Recycle Mode */ | ||||
| #define IXGBE_RTTDCS_ARBDIS     0x00000040 /* DCB arbiter disable */ | ||||
| #define IXGBE_RTTDCS_BDPM       0x00400000 /* Bypass Data Pipe - must clear! */ | ||||
| #define IXGBE_RTTDCS_BPBFSM     0x00800000 /* Bypass PB Free Space - must | ||||
| 					     * clear! | ||||
| 					     */ | ||||
| #define IXGBE_RTTDCS_SPEED_CHG  0x80000000 /* Link speed change */ | ||||
| 
 | ||||
| /* Receive UP2TC mapping */ | ||||
| #define IXGBE_RTRUP2TC_UP_SHIFT 3 | ||||
| #define IXGBE_RTRUP2TC_UP_MASK	7 | ||||
| /* Transmit UP2TC mapping */ | ||||
| #define IXGBE_RTTUP2TC_UP_SHIFT 3 | ||||
| 
 | ||||
| #define IXGBE_RTRPT4C_MCL_SHIFT 12 /* Offset to Max Credit Limit setting */ | ||||
| #define IXGBE_RTRPT4C_BWG_SHIFT 9  /* Offset to BWG index */ | ||||
| #define IXGBE_RTRPT4C_GSP       0x40000000 /* GSP enable bit */ | ||||
| #define IXGBE_RTRPT4C_LSP       0x80000000 /* LSP enable bit */ | ||||
| 
 | ||||
| #define IXGBE_RDRXCTL_MPBEN     0x00000010 /* DMA config for multiple packet | ||||
| 					    * buffers enable | ||||
| 					    */ | ||||
| #define IXGBE_RDRXCTL_MCEN      0x00000040 /* DMA config for multiple cores | ||||
| 					    * (RSS) enable | ||||
| 					    */ | ||||
| 
 | ||||
| /* RTRPCS Bit Masks */ | ||||
| #define IXGBE_RTRPCS_RRM        0x00000002 /* Receive Recycle Mode enable */ | ||||
| /* Receive Arbitration Control: 0 Round Robin, 1 DFP */ | ||||
| #define IXGBE_RTRPCS_RAC        0x00000004 | ||||
| #define IXGBE_RTRPCS_ARBDIS     0x00000040 /* Arbitration disable bit */ | ||||
| 
 | ||||
| /* RTTDT2C Bit Masks */ | ||||
| #define IXGBE_RTTDT2C_MCL_SHIFT 12 | ||||
| #define IXGBE_RTTDT2C_BWG_SHIFT 9 | ||||
| #define IXGBE_RTTDT2C_GSP       0x40000000 | ||||
| #define IXGBE_RTTDT2C_LSP       0x80000000 | ||||
| 
 | ||||
| #define IXGBE_RTTPT2C_MCL_SHIFT 12 | ||||
| #define IXGBE_RTTPT2C_BWG_SHIFT 9 | ||||
| #define IXGBE_RTTPT2C_GSP       0x40000000 | ||||
| #define IXGBE_RTTPT2C_LSP       0x80000000 | ||||
| 
 | ||||
| /* RTTPCS Bit Masks */ | ||||
| #define IXGBE_RTTPCS_TPPAC      0x00000020 /* 0 Round Robin, | ||||
| 					    * 1 SP - Strict Priority | ||||
| 					    */ | ||||
| #define IXGBE_RTTPCS_ARBDIS     0x00000040 /* Arbiter disable */ | ||||
| #define IXGBE_RTTPCS_TPRM       0x00000100 /* Transmit Recycle Mode enable */ | ||||
| #define IXGBE_RTTPCS_ARBD_SHIFT 22 | ||||
| #define IXGBE_RTTPCS_ARBD_DCB   0x4        /* Arbitration delay in DCB mode */ | ||||
| 
 | ||||
| /* SECTXMINIFG DCB */ | ||||
| #define IXGBE_SECTX_DCB		0x00001F00 /* DCB TX Buffer IFG */ | ||||
| 
 | ||||
| 
 | ||||
| /* DCB hardware-specific driver APIs */ | ||||
| 
 | ||||
| /* DCB PFC functions */ | ||||
| s32 ixgbe_dcb_config_pfc_82599(struct ixgbe_hw *hw, u8 pfc_en, u8 *prio_tc); | ||||
| 
 | ||||
| /* DCB hw initialization */ | ||||
| s32 ixgbe_dcb_config_rx_arbiter_82599(struct ixgbe_hw *hw, | ||||
| 					u16 *refill, | ||||
| 					u16 *max, | ||||
| 					u8 *bwg_id, | ||||
| 					u8 *prio_type, | ||||
| 					u8 *prio_tc); | ||||
| 
 | ||||
| s32 ixgbe_dcb_config_tx_desc_arbiter_82599(struct ixgbe_hw *hw, | ||||
| 						u16 *refill, | ||||
| 						u16 *max, | ||||
| 						u8 *bwg_id, | ||||
| 						u8 *prio_type); | ||||
| 
 | ||||
| s32 ixgbe_dcb_config_tx_data_arbiter_82599(struct ixgbe_hw *hw, | ||||
| 						u16 *refill, | ||||
| 						u16 *max, | ||||
| 						u8 *bwg_id, | ||||
| 						u8 *prio_type, | ||||
| 						u8 *prio_tc); | ||||
| 
 | ||||
| s32 ixgbe_dcb_hw_config_82599(struct ixgbe_hw *hw, u8 pfc_en, u16 *refill, | ||||
| 			      u16 *max, u8 *bwg_id, u8 *prio_type, | ||||
| 			      u8 *prio_tc); | ||||
| 
 | ||||
| #endif /* _DCB_82599_CONFIG_H */ | ||||
							
								
								
									
										808
									
								
								drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_nl.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										808
									
								
								drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_nl.c
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,808 @@ | |||
| /*******************************************************************************
 | ||||
| 
 | ||||
|   Intel 10 Gigabit PCI Express Linux driver | ||||
|   Copyright(c) 1999 - 2014 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: | ||||
|   Linux NICS <linux.nics@intel.com> | ||||
|   e1000-devel Mailing List <e1000-devel@lists.sourceforge.net> | ||||
|   Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 | ||||
| 
 | ||||
| *******************************************************************************/ | ||||
| 
 | ||||
| #include "ixgbe.h" | ||||
| #include <linux/dcbnl.h> | ||||
| #include "ixgbe_dcb_82598.h" | ||||
| #include "ixgbe_dcb_82599.h" | ||||
| #include "ixgbe_sriov.h" | ||||
| 
 | ||||
| /* Callbacks for DCB netlink in the kernel */ | ||||
| #define BIT_DCB_MODE	0x01 | ||||
| #define BIT_PFC		0x02 | ||||
| #define BIT_PG_RX	0x04 | ||||
| #define BIT_PG_TX	0x08 | ||||
| #define BIT_APP_UPCHG	0x10 | ||||
| #define BIT_LINKSPEED   0x80 | ||||
| 
 | ||||
| /* Responses for the DCB_C_SET_ALL command */ | ||||
| #define DCB_HW_CHG_RST  0  /* DCB configuration changed with reset */ | ||||
| #define DCB_NO_HW_CHG   1  /* DCB configuration did not change */ | ||||
| #define DCB_HW_CHG      2  /* DCB configuration changed, no reset */ | ||||
| 
 | ||||
| static int ixgbe_copy_dcb_cfg(struct ixgbe_adapter *adapter, int tc_max) | ||||
| { | ||||
| 	struct ixgbe_dcb_config *scfg = &adapter->temp_dcb_cfg; | ||||
| 	struct ixgbe_dcb_config *dcfg = &adapter->dcb_cfg; | ||||
| 	struct tc_configuration *src = NULL; | ||||
| 	struct tc_configuration *dst = NULL; | ||||
| 	int i, j; | ||||
| 	int tx = DCB_TX_CONFIG; | ||||
| 	int rx = DCB_RX_CONFIG; | ||||
| 	int changes = 0; | ||||
| #ifdef IXGBE_FCOE | ||||
| 	struct dcb_app app = { | ||||
| 			      .selector = DCB_APP_IDTYPE_ETHTYPE, | ||||
| 			      .protocol = ETH_P_FCOE, | ||||
| 			     }; | ||||
| 	u8 up = dcb_getapp(adapter->netdev, &app); | ||||
| 
 | ||||
| 	if (up && !(up & (1 << adapter->fcoe.up))) | ||||
| 		changes |= BIT_APP_UPCHG; | ||||
| #endif | ||||
| 
 | ||||
| 	for (i = DCB_PG_ATTR_TC_0; i < tc_max + DCB_PG_ATTR_TC_0; i++) { | ||||
| 		src = &scfg->tc_config[i - DCB_PG_ATTR_TC_0]; | ||||
| 		dst = &dcfg->tc_config[i - DCB_PG_ATTR_TC_0]; | ||||
| 
 | ||||
| 		if (dst->path[tx].prio_type != src->path[tx].prio_type) { | ||||
| 			dst->path[tx].prio_type = src->path[tx].prio_type; | ||||
| 			changes |= BIT_PG_TX; | ||||
| 		} | ||||
| 
 | ||||
| 		if (dst->path[tx].bwg_id != src->path[tx].bwg_id) { | ||||
| 			dst->path[tx].bwg_id = src->path[tx].bwg_id; | ||||
| 			changes |= BIT_PG_TX; | ||||
| 		} | ||||
| 
 | ||||
| 		if (dst->path[tx].bwg_percent != src->path[tx].bwg_percent) { | ||||
| 			dst->path[tx].bwg_percent = src->path[tx].bwg_percent; | ||||
| 			changes |= BIT_PG_TX; | ||||
| 		} | ||||
| 
 | ||||
| 		if (dst->path[tx].up_to_tc_bitmap != | ||||
| 				src->path[tx].up_to_tc_bitmap) { | ||||
| 			dst->path[tx].up_to_tc_bitmap = | ||||
| 				src->path[tx].up_to_tc_bitmap; | ||||
| 			changes |= (BIT_PG_TX | BIT_PFC | BIT_APP_UPCHG); | ||||
| 		} | ||||
| 
 | ||||
| 		if (dst->path[rx].prio_type != src->path[rx].prio_type) { | ||||
| 			dst->path[rx].prio_type = src->path[rx].prio_type; | ||||
| 			changes |= BIT_PG_RX; | ||||
| 		} | ||||
| 
 | ||||
| 		if (dst->path[rx].bwg_id != src->path[rx].bwg_id) { | ||||
| 			dst->path[rx].bwg_id = src->path[rx].bwg_id; | ||||
| 			changes |= BIT_PG_RX; | ||||
| 		} | ||||
| 
 | ||||
| 		if (dst->path[rx].bwg_percent != src->path[rx].bwg_percent) { | ||||
| 			dst->path[rx].bwg_percent = src->path[rx].bwg_percent; | ||||
| 			changes |= BIT_PG_RX; | ||||
| 		} | ||||
| 
 | ||||
| 		if (dst->path[rx].up_to_tc_bitmap != | ||||
| 				src->path[rx].up_to_tc_bitmap) { | ||||
| 			dst->path[rx].up_to_tc_bitmap = | ||||
| 				src->path[rx].up_to_tc_bitmap; | ||||
| 			changes |= (BIT_PG_RX | BIT_PFC | BIT_APP_UPCHG); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	for (i = DCB_PG_ATTR_BW_ID_0; i < DCB_PG_ATTR_BW_ID_MAX; i++) { | ||||
| 		j = i - DCB_PG_ATTR_BW_ID_0; | ||||
| 		if (dcfg->bw_percentage[tx][j] != scfg->bw_percentage[tx][j]) { | ||||
| 			dcfg->bw_percentage[tx][j] = scfg->bw_percentage[tx][j]; | ||||
| 			changes |= BIT_PG_TX; | ||||
| 		} | ||||
| 		if (dcfg->bw_percentage[rx][j] != scfg->bw_percentage[rx][j]) { | ||||
| 			dcfg->bw_percentage[rx][j] = scfg->bw_percentage[rx][j]; | ||||
| 			changes |= BIT_PG_RX; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	for (i = DCB_PFC_UP_ATTR_0; i < DCB_PFC_UP_ATTR_MAX; i++) { | ||||
| 		j = i - DCB_PFC_UP_ATTR_0; | ||||
| 		if (dcfg->tc_config[j].dcb_pfc != scfg->tc_config[j].dcb_pfc) { | ||||
| 			dcfg->tc_config[j].dcb_pfc = scfg->tc_config[j].dcb_pfc; | ||||
| 			changes |= BIT_PFC; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	if (dcfg->pfc_mode_enable != scfg->pfc_mode_enable) { | ||||
| 		dcfg->pfc_mode_enable = scfg->pfc_mode_enable; | ||||
| 		changes |= BIT_PFC; | ||||
| 	} | ||||
| 
 | ||||
| 	return changes; | ||||
| } | ||||
| 
 | ||||
| static u8 ixgbe_dcbnl_get_state(struct net_device *netdev) | ||||
| { | ||||
| 	struct ixgbe_adapter *adapter = netdev_priv(netdev); | ||||
| 
 | ||||
| 	return !!(adapter->flags & IXGBE_FLAG_DCB_ENABLED); | ||||
| } | ||||
| 
 | ||||
| static u8 ixgbe_dcbnl_set_state(struct net_device *netdev, u8 state) | ||||
| { | ||||
| 	struct ixgbe_adapter *adapter = netdev_priv(netdev); | ||||
| 
 | ||||
| 	/* Fail command if not in CEE mode */ | ||||
| 	if (!(adapter->dcbx_cap & DCB_CAP_DCBX_VER_CEE)) | ||||
| 		return 1; | ||||
| 
 | ||||
| 	/* verify there is something to do, if not then exit */ | ||||
| 	if (!state == !(adapter->flags & IXGBE_FLAG_DCB_ENABLED)) | ||||
| 		return 0; | ||||
| 
 | ||||
| 	return !!ixgbe_setup_tc(netdev, | ||||
| 				state ? adapter->dcb_cfg.num_tcs.pg_tcs : 0); | ||||
| } | ||||
| 
 | ||||
| static void ixgbe_dcbnl_get_perm_hw_addr(struct net_device *netdev, | ||||
| 					 u8 *perm_addr) | ||||
| { | ||||
| 	struct ixgbe_adapter *adapter = netdev_priv(netdev); | ||||
| 	int i, j; | ||||
| 
 | ||||
| 	memset(perm_addr, 0xff, MAX_ADDR_LEN); | ||||
| 
 | ||||
| 	for (i = 0; i < netdev->addr_len; i++) | ||||
| 		perm_addr[i] = adapter->hw.mac.perm_addr[i]; | ||||
| 
 | ||||
| 	switch (adapter->hw.mac.type) { | ||||
| 	case ixgbe_mac_82599EB: | ||||
| 	case ixgbe_mac_X540: | ||||
| 		for (j = 0; j < netdev->addr_len; j++, i++) | ||||
| 			perm_addr[i] = adapter->hw.mac.san_addr[j]; | ||||
| 		break; | ||||
| 	default: | ||||
| 		break; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| static void ixgbe_dcbnl_set_pg_tc_cfg_tx(struct net_device *netdev, int tc, | ||||
| 					 u8 prio, u8 bwg_id, u8 bw_pct, | ||||
| 					 u8 up_map) | ||||
| { | ||||
| 	struct ixgbe_adapter *adapter = netdev_priv(netdev); | ||||
| 
 | ||||
| 	if (prio != DCB_ATTR_VALUE_UNDEFINED) | ||||
| 		adapter->temp_dcb_cfg.tc_config[tc].path[0].prio_type = prio; | ||||
| 	if (bwg_id != DCB_ATTR_VALUE_UNDEFINED) | ||||
| 		adapter->temp_dcb_cfg.tc_config[tc].path[0].bwg_id = bwg_id; | ||||
| 	if (bw_pct != DCB_ATTR_VALUE_UNDEFINED) | ||||
| 		adapter->temp_dcb_cfg.tc_config[tc].path[0].bwg_percent = | ||||
| 			bw_pct; | ||||
| 	if (up_map != DCB_ATTR_VALUE_UNDEFINED) | ||||
| 		adapter->temp_dcb_cfg.tc_config[tc].path[0].up_to_tc_bitmap = | ||||
| 			up_map; | ||||
| } | ||||
| 
 | ||||
| static void ixgbe_dcbnl_set_pg_bwg_cfg_tx(struct net_device *netdev, int bwg_id, | ||||
| 					  u8 bw_pct) | ||||
| { | ||||
| 	struct ixgbe_adapter *adapter = netdev_priv(netdev); | ||||
| 
 | ||||
| 	adapter->temp_dcb_cfg.bw_percentage[0][bwg_id] = bw_pct; | ||||
| } | ||||
| 
 | ||||
| static void ixgbe_dcbnl_set_pg_tc_cfg_rx(struct net_device *netdev, int tc, | ||||
| 					 u8 prio, u8 bwg_id, u8 bw_pct, | ||||
| 					 u8 up_map) | ||||
| { | ||||
| 	struct ixgbe_adapter *adapter = netdev_priv(netdev); | ||||
| 
 | ||||
| 	if (prio != DCB_ATTR_VALUE_UNDEFINED) | ||||
| 		adapter->temp_dcb_cfg.tc_config[tc].path[1].prio_type = prio; | ||||
| 	if (bwg_id != DCB_ATTR_VALUE_UNDEFINED) | ||||
| 		adapter->temp_dcb_cfg.tc_config[tc].path[1].bwg_id = bwg_id; | ||||
| 	if (bw_pct != DCB_ATTR_VALUE_UNDEFINED) | ||||
| 		adapter->temp_dcb_cfg.tc_config[tc].path[1].bwg_percent = | ||||
| 			bw_pct; | ||||
| 	if (up_map != DCB_ATTR_VALUE_UNDEFINED) | ||||
| 		adapter->temp_dcb_cfg.tc_config[tc].path[1].up_to_tc_bitmap = | ||||
| 			up_map; | ||||
| } | ||||
| 
 | ||||
| static void ixgbe_dcbnl_set_pg_bwg_cfg_rx(struct net_device *netdev, int bwg_id, | ||||
| 					  u8 bw_pct) | ||||
| { | ||||
| 	struct ixgbe_adapter *adapter = netdev_priv(netdev); | ||||
| 
 | ||||
| 	adapter->temp_dcb_cfg.bw_percentage[1][bwg_id] = bw_pct; | ||||
| } | ||||
| 
 | ||||
| static void ixgbe_dcbnl_get_pg_tc_cfg_tx(struct net_device *netdev, int tc, | ||||
| 					 u8 *prio, u8 *bwg_id, u8 *bw_pct, | ||||
| 					 u8 *up_map) | ||||
| { | ||||
| 	struct ixgbe_adapter *adapter = netdev_priv(netdev); | ||||
| 
 | ||||
| 	*prio = adapter->dcb_cfg.tc_config[tc].path[0].prio_type; | ||||
| 	*bwg_id = adapter->dcb_cfg.tc_config[tc].path[0].bwg_id; | ||||
| 	*bw_pct = adapter->dcb_cfg.tc_config[tc].path[0].bwg_percent; | ||||
| 	*up_map = adapter->dcb_cfg.tc_config[tc].path[0].up_to_tc_bitmap; | ||||
| } | ||||
| 
 | ||||
| static void ixgbe_dcbnl_get_pg_bwg_cfg_tx(struct net_device *netdev, int bwg_id, | ||||
| 					  u8 *bw_pct) | ||||
| { | ||||
| 	struct ixgbe_adapter *adapter = netdev_priv(netdev); | ||||
| 
 | ||||
| 	*bw_pct = adapter->dcb_cfg.bw_percentage[0][bwg_id]; | ||||
| } | ||||
| 
 | ||||
| static void ixgbe_dcbnl_get_pg_tc_cfg_rx(struct net_device *netdev, int tc, | ||||
| 					 u8 *prio, u8 *bwg_id, u8 *bw_pct, | ||||
| 					 u8 *up_map) | ||||
| { | ||||
| 	struct ixgbe_adapter *adapter = netdev_priv(netdev); | ||||
| 
 | ||||
| 	*prio = adapter->dcb_cfg.tc_config[tc].path[1].prio_type; | ||||
| 	*bwg_id = adapter->dcb_cfg.tc_config[tc].path[1].bwg_id; | ||||
| 	*bw_pct = adapter->dcb_cfg.tc_config[tc].path[1].bwg_percent; | ||||
| 	*up_map = adapter->dcb_cfg.tc_config[tc].path[1].up_to_tc_bitmap; | ||||
| } | ||||
| 
 | ||||
| static void ixgbe_dcbnl_get_pg_bwg_cfg_rx(struct net_device *netdev, int bwg_id, | ||||
| 					  u8 *bw_pct) | ||||
| { | ||||
| 	struct ixgbe_adapter *adapter = netdev_priv(netdev); | ||||
| 
 | ||||
| 	*bw_pct = adapter->dcb_cfg.bw_percentage[1][bwg_id]; | ||||
| } | ||||
| 
 | ||||
| static void ixgbe_dcbnl_set_pfc_cfg(struct net_device *netdev, int priority, | ||||
| 				    u8 setting) | ||||
| { | ||||
| 	struct ixgbe_adapter *adapter = netdev_priv(netdev); | ||||
| 
 | ||||
| 	adapter->temp_dcb_cfg.tc_config[priority].dcb_pfc = setting; | ||||
| 	if (adapter->temp_dcb_cfg.tc_config[priority].dcb_pfc != | ||||
| 	    adapter->dcb_cfg.tc_config[priority].dcb_pfc) | ||||
| 		adapter->temp_dcb_cfg.pfc_mode_enable = true; | ||||
| } | ||||
| 
 | ||||
| static void ixgbe_dcbnl_get_pfc_cfg(struct net_device *netdev, int priority, | ||||
| 				    u8 *setting) | ||||
| { | ||||
| 	struct ixgbe_adapter *adapter = netdev_priv(netdev); | ||||
| 
 | ||||
| 	*setting = adapter->dcb_cfg.tc_config[priority].dcb_pfc; | ||||
| } | ||||
| 
 | ||||
| static void ixgbe_dcbnl_devreset(struct net_device *dev) | ||||
| { | ||||
| 	struct ixgbe_adapter *adapter = netdev_priv(dev); | ||||
| 
 | ||||
| 	while (test_and_set_bit(__IXGBE_RESETTING, &adapter->state)) | ||||
| 		usleep_range(1000, 2000); | ||||
| 
 | ||||
| 	if (netif_running(dev)) | ||||
| 		dev->netdev_ops->ndo_stop(dev); | ||||
| 
 | ||||
| 	ixgbe_clear_interrupt_scheme(adapter); | ||||
| 	ixgbe_init_interrupt_scheme(adapter); | ||||
| 
 | ||||
| 	if (netif_running(dev)) | ||||
| 		dev->netdev_ops->ndo_open(dev); | ||||
| 
 | ||||
| 	clear_bit(__IXGBE_RESETTING, &adapter->state); | ||||
| } | ||||
| 
 | ||||
| static u8 ixgbe_dcbnl_set_all(struct net_device *netdev) | ||||
| { | ||||
| 	struct ixgbe_adapter *adapter = netdev_priv(netdev); | ||||
| 	struct ixgbe_dcb_config *dcb_cfg = &adapter->dcb_cfg; | ||||
| 	struct ixgbe_hw *hw = &adapter->hw; | ||||
| 	int ret = DCB_NO_HW_CHG; | ||||
| 	int i; | ||||
| 
 | ||||
| 	/* Fail command if not in CEE mode */ | ||||
| 	if (!(adapter->dcbx_cap & DCB_CAP_DCBX_VER_CEE)) | ||||
| 		return DCB_NO_HW_CHG; | ||||
| 
 | ||||
| 	adapter->dcb_set_bitmap |= ixgbe_copy_dcb_cfg(adapter, | ||||
| 						      MAX_TRAFFIC_CLASS); | ||||
| 	if (!adapter->dcb_set_bitmap) | ||||
| 		return DCB_NO_HW_CHG; | ||||
| 
 | ||||
| 	if (adapter->dcb_set_bitmap & (BIT_PG_TX|BIT_PG_RX)) { | ||||
| 		u16 refill[MAX_TRAFFIC_CLASS], max[MAX_TRAFFIC_CLASS]; | ||||
| 		u8 bwg_id[MAX_TRAFFIC_CLASS], prio_type[MAX_TRAFFIC_CLASS]; | ||||
| 		/* Priority to TC mapping in CEE case default to 1:1 */ | ||||
| 		u8 prio_tc[MAX_USER_PRIORITY]; | ||||
| 		int max_frame = adapter->netdev->mtu + ETH_HLEN + ETH_FCS_LEN; | ||||
| 
 | ||||
| #ifdef IXGBE_FCOE | ||||
| 		if (adapter->netdev->features & NETIF_F_FCOE_MTU) | ||||
| 			max_frame = max(max_frame, IXGBE_FCOE_JUMBO_FRAME_SIZE); | ||||
| #endif | ||||
| 
 | ||||
| 		ixgbe_dcb_calculate_tc_credits(hw, dcb_cfg, max_frame, | ||||
| 					       DCB_TX_CONFIG); | ||||
| 		ixgbe_dcb_calculate_tc_credits(hw, dcb_cfg, max_frame, | ||||
| 					       DCB_RX_CONFIG); | ||||
| 
 | ||||
| 		ixgbe_dcb_unpack_refill(dcb_cfg, DCB_TX_CONFIG, refill); | ||||
| 		ixgbe_dcb_unpack_max(dcb_cfg, max); | ||||
| 		ixgbe_dcb_unpack_bwgid(dcb_cfg, DCB_TX_CONFIG, bwg_id); | ||||
| 		ixgbe_dcb_unpack_prio(dcb_cfg, DCB_TX_CONFIG, prio_type); | ||||
| 		ixgbe_dcb_unpack_map(dcb_cfg, DCB_TX_CONFIG, prio_tc); | ||||
| 
 | ||||
| 		ixgbe_dcb_hw_ets_config(hw, refill, max, bwg_id, | ||||
| 					prio_type, prio_tc); | ||||
| 
 | ||||
| 		for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) | ||||
| 			netdev_set_prio_tc_map(netdev, i, prio_tc[i]); | ||||
| 
 | ||||
| 		ret = DCB_HW_CHG_RST; | ||||
| 	} | ||||
| 
 | ||||
| 	if (adapter->dcb_set_bitmap & BIT_PFC) { | ||||
| 		if (dcb_cfg->pfc_mode_enable) { | ||||
| 			u8 pfc_en; | ||||
| 			u8 prio_tc[MAX_USER_PRIORITY]; | ||||
| 
 | ||||
| 			ixgbe_dcb_unpack_map(dcb_cfg, DCB_TX_CONFIG, prio_tc); | ||||
| 			ixgbe_dcb_unpack_pfc(dcb_cfg, &pfc_en); | ||||
| 			ixgbe_dcb_hw_pfc_config(hw, pfc_en, prio_tc); | ||||
| 		} else { | ||||
| 			hw->mac.ops.fc_enable(hw); | ||||
| 		} | ||||
| 
 | ||||
| 		ixgbe_set_rx_drop_en(adapter); | ||||
| 
 | ||||
| 		ret = DCB_HW_CHG; | ||||
| 	} | ||||
| 
 | ||||
| #ifdef IXGBE_FCOE | ||||
| 	/* Reprogam FCoE hardware offloads when the traffic class
 | ||||
| 	 * FCoE is using changes. This happens if the APP info | ||||
| 	 * changes or the up2tc mapping is updated. | ||||
| 	 */ | ||||
| 	if (adapter->dcb_set_bitmap & BIT_APP_UPCHG) { | ||||
| 		struct dcb_app app = { | ||||
| 				      .selector = DCB_APP_IDTYPE_ETHTYPE, | ||||
| 				      .protocol = ETH_P_FCOE, | ||||
| 				     }; | ||||
| 		u8 up = dcb_getapp(netdev, &app); | ||||
| 
 | ||||
| 		adapter->fcoe.up = ffs(up) - 1; | ||||
| 		ixgbe_dcbnl_devreset(netdev); | ||||
| 		ret = DCB_HW_CHG_RST; | ||||
| 	} | ||||
| #endif | ||||
| 
 | ||||
| 	adapter->dcb_set_bitmap = 0x00; | ||||
| 	return ret; | ||||
| } | ||||
| 
 | ||||
| static u8 ixgbe_dcbnl_getcap(struct net_device *netdev, int capid, u8 *cap) | ||||
| { | ||||
| 	struct ixgbe_adapter *adapter = netdev_priv(netdev); | ||||
| 
 | ||||
| 	switch (capid) { | ||||
| 	case DCB_CAP_ATTR_PG: | ||||
| 		*cap = true; | ||||
| 		break; | ||||
| 	case DCB_CAP_ATTR_PFC: | ||||
| 		*cap = true; | ||||
| 		break; | ||||
| 	case DCB_CAP_ATTR_UP2TC: | ||||
| 		*cap = false; | ||||
| 		break; | ||||
| 	case DCB_CAP_ATTR_PG_TCS: | ||||
| 		*cap = 0x80; | ||||
| 		break; | ||||
| 	case DCB_CAP_ATTR_PFC_TCS: | ||||
| 		*cap = 0x80; | ||||
| 		break; | ||||
| 	case DCB_CAP_ATTR_GSP: | ||||
| 		*cap = true; | ||||
| 		break; | ||||
| 	case DCB_CAP_ATTR_BCN: | ||||
| 		*cap = false; | ||||
| 		break; | ||||
| 	case DCB_CAP_ATTR_DCBX: | ||||
| 		*cap = adapter->dcbx_cap; | ||||
| 		break; | ||||
| 	default: | ||||
| 		*cap = false; | ||||
| 		break; | ||||
| 	} | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| static int ixgbe_dcbnl_getnumtcs(struct net_device *netdev, int tcid, u8 *num) | ||||
| { | ||||
| 	struct ixgbe_adapter *adapter = netdev_priv(netdev); | ||||
| 
 | ||||
| 	if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) { | ||||
| 		switch (tcid) { | ||||
| 		case DCB_NUMTCS_ATTR_PG: | ||||
| 			*num = adapter->dcb_cfg.num_tcs.pg_tcs; | ||||
| 			break; | ||||
| 		case DCB_NUMTCS_ATTR_PFC: | ||||
| 			*num = adapter->dcb_cfg.num_tcs.pfc_tcs; | ||||
| 			break; | ||||
| 		default: | ||||
| 			return -EINVAL; | ||||
| 		} | ||||
| 	} else { | ||||
| 		return -EINVAL; | ||||
| 	} | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| static int ixgbe_dcbnl_setnumtcs(struct net_device *netdev, int tcid, u8 num) | ||||
| { | ||||
| 	return -EINVAL; | ||||
| } | ||||
| 
 | ||||
| static u8 ixgbe_dcbnl_getpfcstate(struct net_device *netdev) | ||||
| { | ||||
| 	struct ixgbe_adapter *adapter = netdev_priv(netdev); | ||||
| 
 | ||||
| 	return adapter->dcb_cfg.pfc_mode_enable; | ||||
| } | ||||
| 
 | ||||
| static void ixgbe_dcbnl_setpfcstate(struct net_device *netdev, u8 state) | ||||
| { | ||||
| 	struct ixgbe_adapter *adapter = netdev_priv(netdev); | ||||
| 
 | ||||
| 	adapter->temp_dcb_cfg.pfc_mode_enable = state; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  * ixgbe_dcbnl_getapp - retrieve the DCBX application user priority | ||||
|  * @netdev : the corresponding netdev | ||||
|  * @idtype : identifies the id as ether type or TCP/UDP port number | ||||
|  * @id: id is either ether type or TCP/UDP port number | ||||
|  * | ||||
|  * Returns : on success, returns a non-zero 802.1p user priority bitmap | ||||
|  * otherwise returns -EINVAL as the invalid user priority bitmap to indicate an | ||||
|  * error. | ||||
|  */ | ||||
| static int ixgbe_dcbnl_getapp(struct net_device *netdev, u8 idtype, u16 id) | ||||
| { | ||||
| 	struct ixgbe_adapter *adapter = netdev_priv(netdev); | ||||
| 	struct dcb_app app = { | ||||
| 				.selector = idtype, | ||||
| 				.protocol = id, | ||||
| 			     }; | ||||
| 
 | ||||
| 	if (!(adapter->dcbx_cap & DCB_CAP_DCBX_VER_CEE)) | ||||
| 		return -EINVAL; | ||||
| 
 | ||||
| 	return dcb_getapp(netdev, &app); | ||||
| } | ||||
| 
 | ||||
| static int ixgbe_dcbnl_ieee_getets(struct net_device *dev, | ||||
| 				   struct ieee_ets *ets) | ||||
| { | ||||
| 	struct ixgbe_adapter *adapter = netdev_priv(dev); | ||||
| 	struct ieee_ets *my_ets = adapter->ixgbe_ieee_ets; | ||||
| 
 | ||||
| 	ets->ets_cap = adapter->dcb_cfg.num_tcs.pg_tcs; | ||||
| 
 | ||||
| 	/* No IEEE PFC settings available */ | ||||
| 	if (!my_ets) | ||||
| 		return 0; | ||||
| 
 | ||||
| 	ets->cbs = my_ets->cbs; | ||||
| 	memcpy(ets->tc_tx_bw, my_ets->tc_tx_bw, sizeof(ets->tc_tx_bw)); | ||||
| 	memcpy(ets->tc_rx_bw, my_ets->tc_rx_bw, sizeof(ets->tc_rx_bw)); | ||||
| 	memcpy(ets->tc_tsa, my_ets->tc_tsa, sizeof(ets->tc_tsa)); | ||||
| 	memcpy(ets->prio_tc, my_ets->prio_tc, sizeof(ets->prio_tc)); | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| static int ixgbe_dcbnl_ieee_setets(struct net_device *dev, | ||||
| 				   struct ieee_ets *ets) | ||||
| { | ||||
| 	struct ixgbe_adapter *adapter = netdev_priv(dev); | ||||
| 	int max_frame = dev->mtu + ETH_HLEN + ETH_FCS_LEN; | ||||
| 	int i, err; | ||||
| 	__u8 max_tc = 0; | ||||
| 	__u8 map_chg = 0; | ||||
| 
 | ||||
| 	if (!(adapter->dcbx_cap & DCB_CAP_DCBX_VER_IEEE)) | ||||
| 		return -EINVAL; | ||||
| 
 | ||||
| 	if (!adapter->ixgbe_ieee_ets) { | ||||
| 		adapter->ixgbe_ieee_ets = kmalloc(sizeof(struct ieee_ets), | ||||
| 						  GFP_KERNEL); | ||||
| 		if (!adapter->ixgbe_ieee_ets) | ||||
| 			return -ENOMEM; | ||||
| 
 | ||||
| 		/* initialize UP2TC mappings to invalid value */ | ||||
| 		for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) | ||||
| 			adapter->ixgbe_ieee_ets->prio_tc[i] = | ||||
| 				IEEE_8021QAZ_MAX_TCS; | ||||
| 		/* if possible update UP2TC mappings from HW */ | ||||
| 		ixgbe_dcb_read_rtrup2tc(&adapter->hw, | ||||
| 					adapter->ixgbe_ieee_ets->prio_tc); | ||||
| 	} | ||||
| 
 | ||||
| 	for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) { | ||||
| 		if (ets->prio_tc[i] > max_tc) | ||||
| 			max_tc = ets->prio_tc[i]; | ||||
| 		if (ets->prio_tc[i] != adapter->ixgbe_ieee_ets->prio_tc[i]) | ||||
| 			map_chg = 1; | ||||
| 	} | ||||
| 
 | ||||
| 	memcpy(adapter->ixgbe_ieee_ets, ets, sizeof(*adapter->ixgbe_ieee_ets)); | ||||
| 
 | ||||
| 	if (max_tc) | ||||
| 		max_tc++; | ||||
| 
 | ||||
| 	if (max_tc > adapter->dcb_cfg.num_tcs.pg_tcs) | ||||
| 		return -EINVAL; | ||||
| 
 | ||||
| 	if (max_tc != netdev_get_num_tc(dev)) { | ||||
| 		err = ixgbe_setup_tc(dev, max_tc); | ||||
| 		if (err) | ||||
| 			return err; | ||||
| 	} else if (map_chg) { | ||||
| 		ixgbe_dcbnl_devreset(dev); | ||||
| 	} | ||||
| 
 | ||||
| 	return ixgbe_dcb_hw_ets(&adapter->hw, ets, max_frame); | ||||
| } | ||||
| 
 | ||||
| static int ixgbe_dcbnl_ieee_getpfc(struct net_device *dev, | ||||
| 				   struct ieee_pfc *pfc) | ||||
| { | ||||
| 	struct ixgbe_adapter *adapter = netdev_priv(dev); | ||||
| 	struct ieee_pfc *my_pfc = adapter->ixgbe_ieee_pfc; | ||||
| 	int i; | ||||
| 
 | ||||
| 	pfc->pfc_cap = adapter->dcb_cfg.num_tcs.pfc_tcs; | ||||
| 
 | ||||
| 	/* No IEEE PFC settings available */ | ||||
| 	if (!my_pfc) | ||||
| 		return 0; | ||||
| 
 | ||||
| 	pfc->pfc_en = my_pfc->pfc_en; | ||||
| 	pfc->mbc = my_pfc->mbc; | ||||
| 	pfc->delay = my_pfc->delay; | ||||
| 
 | ||||
| 	for (i = 0; i < MAX_TRAFFIC_CLASS; i++) { | ||||
| 		pfc->requests[i] = adapter->stats.pxoffrxc[i]; | ||||
| 		pfc->indications[i] = adapter->stats.pxofftxc[i]; | ||||
| 	} | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| static int ixgbe_dcbnl_ieee_setpfc(struct net_device *dev, | ||||
| 				   struct ieee_pfc *pfc) | ||||
| { | ||||
| 	struct ixgbe_adapter *adapter = netdev_priv(dev); | ||||
| 	struct ixgbe_hw *hw = &adapter->hw; | ||||
| 	u8 *prio_tc; | ||||
| 	int err; | ||||
| 
 | ||||
| 	if (!(adapter->dcbx_cap & DCB_CAP_DCBX_VER_IEEE)) | ||||
| 		return -EINVAL; | ||||
| 
 | ||||
| 	if (!adapter->ixgbe_ieee_pfc) { | ||||
| 		adapter->ixgbe_ieee_pfc = kmalloc(sizeof(struct ieee_pfc), | ||||
| 						  GFP_KERNEL); | ||||
| 		if (!adapter->ixgbe_ieee_pfc) | ||||
| 			return -ENOMEM; | ||||
| 	} | ||||
| 
 | ||||
| 	prio_tc = adapter->ixgbe_ieee_ets->prio_tc; | ||||
| 	memcpy(adapter->ixgbe_ieee_pfc, pfc, sizeof(*adapter->ixgbe_ieee_pfc)); | ||||
| 
 | ||||
| 	/* Enable link flow control parameters if PFC is disabled */ | ||||
| 	if (pfc->pfc_en) | ||||
| 		err = ixgbe_dcb_hw_pfc_config(hw, pfc->pfc_en, prio_tc); | ||||
| 	else | ||||
| 		err = hw->mac.ops.fc_enable(hw); | ||||
| 
 | ||||
| 	ixgbe_set_rx_drop_en(adapter); | ||||
| 
 | ||||
| 	return err; | ||||
| } | ||||
| 
 | ||||
| static int ixgbe_dcbnl_ieee_setapp(struct net_device *dev, | ||||
| 				   struct dcb_app *app) | ||||
| { | ||||
| 	struct ixgbe_adapter *adapter = netdev_priv(dev); | ||||
| 	int err; | ||||
| 
 | ||||
| 	if (!(adapter->dcbx_cap & DCB_CAP_DCBX_VER_IEEE)) | ||||
| 		return -EINVAL; | ||||
| 
 | ||||
| 	err = dcb_ieee_setapp(dev, app); | ||||
| 	if (err) | ||||
| 		return err; | ||||
| 
 | ||||
| #ifdef IXGBE_FCOE | ||||
| 	if (app->selector == IEEE_8021QAZ_APP_SEL_ETHERTYPE && | ||||
| 	    app->protocol == ETH_P_FCOE) { | ||||
| 		u8 app_mask = dcb_ieee_getapp_mask(dev, app); | ||||
| 
 | ||||
| 		if (app_mask & (1 << adapter->fcoe.up)) | ||||
| 			return 0; | ||||
| 
 | ||||
| 		adapter->fcoe.up = app->priority; | ||||
| 		ixgbe_dcbnl_devreset(dev); | ||||
| 	} | ||||
| #endif | ||||
| 
 | ||||
| 	/* VF devices should use default UP when available */ | ||||
| 	if (app->selector == IEEE_8021QAZ_APP_SEL_ETHERTYPE && | ||||
| 	    app->protocol == 0) { | ||||
| 		int vf; | ||||
| 
 | ||||
| 		adapter->default_up = app->priority; | ||||
| 
 | ||||
| 		for (vf = 0; vf < adapter->num_vfs; vf++) { | ||||
| 			struct vf_data_storage *vfinfo = &adapter->vfinfo[vf]; | ||||
| 
 | ||||
| 			if (!vfinfo->pf_qos) | ||||
| 				ixgbe_set_vmvir(adapter, vfinfo->pf_vlan, | ||||
| 						app->priority, vf); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| static int ixgbe_dcbnl_ieee_delapp(struct net_device *dev, | ||||
| 				   struct dcb_app *app) | ||||
| { | ||||
| 	struct ixgbe_adapter *adapter = netdev_priv(dev); | ||||
| 	int err; | ||||
| 
 | ||||
| 	if (!(adapter->dcbx_cap & DCB_CAP_DCBX_VER_IEEE)) | ||||
| 		return -EINVAL; | ||||
| 
 | ||||
| 	err = dcb_ieee_delapp(dev, app); | ||||
| 
 | ||||
| #ifdef IXGBE_FCOE | ||||
| 	if (!err && app->selector == IEEE_8021QAZ_APP_SEL_ETHERTYPE && | ||||
| 	    app->protocol == ETH_P_FCOE) { | ||||
| 		u8 app_mask = dcb_ieee_getapp_mask(dev, app); | ||||
| 
 | ||||
| 		if (app_mask & (1 << adapter->fcoe.up)) | ||||
| 			return 0; | ||||
| 
 | ||||
| 		adapter->fcoe.up = app_mask ? | ||||
| 				   ffs(app_mask) - 1 : IXGBE_FCOE_DEFTC; | ||||
| 		ixgbe_dcbnl_devreset(dev); | ||||
| 	} | ||||
| #endif | ||||
| 	/* IF default priority is being removed clear VF default UP */ | ||||
| 	if (app->selector == IEEE_8021QAZ_APP_SEL_ETHERTYPE && | ||||
| 	    app->protocol == 0 && adapter->default_up == app->priority) { | ||||
| 		int vf; | ||||
| 		long unsigned int app_mask = dcb_ieee_getapp_mask(dev, app); | ||||
| 		int qos = app_mask ? find_first_bit(&app_mask, 8) : 0; | ||||
| 
 | ||||
| 		adapter->default_up = qos; | ||||
| 
 | ||||
| 		for (vf = 0; vf < adapter->num_vfs; vf++) { | ||||
| 			struct vf_data_storage *vfinfo = &adapter->vfinfo[vf]; | ||||
| 
 | ||||
| 			if (!vfinfo->pf_qos) | ||||
| 				ixgbe_set_vmvir(adapter, vfinfo->pf_vlan, | ||||
| 						qos, vf); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	return err; | ||||
| } | ||||
| 
 | ||||
| static u8 ixgbe_dcbnl_getdcbx(struct net_device *dev) | ||||
| { | ||||
| 	struct ixgbe_adapter *adapter = netdev_priv(dev); | ||||
| 	return adapter->dcbx_cap; | ||||
| } | ||||
| 
 | ||||
| static u8 ixgbe_dcbnl_setdcbx(struct net_device *dev, u8 mode) | ||||
| { | ||||
| 	struct ixgbe_adapter *adapter = netdev_priv(dev); | ||||
| 	struct ieee_ets ets = {0}; | ||||
| 	struct ieee_pfc pfc = {0}; | ||||
| 	int err = 0; | ||||
| 
 | ||||
| 	/* no support for LLD_MANAGED modes or CEE+IEEE */ | ||||
| 	if ((mode & DCB_CAP_DCBX_LLD_MANAGED) || | ||||
| 	    ((mode & DCB_CAP_DCBX_VER_IEEE) && (mode & DCB_CAP_DCBX_VER_CEE)) || | ||||
| 	    !(mode & DCB_CAP_DCBX_HOST)) | ||||
| 		return 1; | ||||
| 
 | ||||
| 	if (mode == adapter->dcbx_cap) | ||||
| 		return 0; | ||||
| 
 | ||||
| 	adapter->dcbx_cap = mode; | ||||
| 
 | ||||
| 	/* ETS and PFC defaults */ | ||||
| 	ets.ets_cap = 8; | ||||
| 	pfc.pfc_cap = 8; | ||||
| 
 | ||||
| 	if (mode & DCB_CAP_DCBX_VER_IEEE) { | ||||
| 		ixgbe_dcbnl_ieee_setets(dev, &ets); | ||||
| 		ixgbe_dcbnl_ieee_setpfc(dev, &pfc); | ||||
| 	} else if (mode & DCB_CAP_DCBX_VER_CEE) { | ||||
| 		u8 mask = BIT_PFC | BIT_PG_TX | BIT_PG_RX | BIT_APP_UPCHG; | ||||
| 
 | ||||
| 		adapter->dcb_set_bitmap |= mask; | ||||
| 		ixgbe_dcbnl_set_all(dev); | ||||
| 	} else { | ||||
| 		/* Drop into single TC mode strict priority as this
 | ||||
| 		 * indicates CEE and IEEE versions are disabled | ||||
| 		 */ | ||||
| 		ixgbe_dcbnl_ieee_setets(dev, &ets); | ||||
| 		ixgbe_dcbnl_ieee_setpfc(dev, &pfc); | ||||
| 		err = ixgbe_setup_tc(dev, 0); | ||||
| 	} | ||||
| 
 | ||||
| 	return err ? 1 : 0; | ||||
| } | ||||
| 
 | ||||
| const struct dcbnl_rtnl_ops dcbnl_ops = { | ||||
| 	.ieee_getets	= ixgbe_dcbnl_ieee_getets, | ||||
| 	.ieee_setets	= ixgbe_dcbnl_ieee_setets, | ||||
| 	.ieee_getpfc	= ixgbe_dcbnl_ieee_getpfc, | ||||
| 	.ieee_setpfc	= ixgbe_dcbnl_ieee_setpfc, | ||||
| 	.ieee_setapp	= ixgbe_dcbnl_ieee_setapp, | ||||
| 	.ieee_delapp	= ixgbe_dcbnl_ieee_delapp, | ||||
| 	.getstate	= ixgbe_dcbnl_get_state, | ||||
| 	.setstate	= ixgbe_dcbnl_set_state, | ||||
| 	.getpermhwaddr	= ixgbe_dcbnl_get_perm_hw_addr, | ||||
| 	.setpgtccfgtx	= ixgbe_dcbnl_set_pg_tc_cfg_tx, | ||||
| 	.setpgbwgcfgtx	= ixgbe_dcbnl_set_pg_bwg_cfg_tx, | ||||
| 	.setpgtccfgrx	= ixgbe_dcbnl_set_pg_tc_cfg_rx, | ||||
| 	.setpgbwgcfgrx	= ixgbe_dcbnl_set_pg_bwg_cfg_rx, | ||||
| 	.getpgtccfgtx	= ixgbe_dcbnl_get_pg_tc_cfg_tx, | ||||
| 	.getpgbwgcfgtx	= ixgbe_dcbnl_get_pg_bwg_cfg_tx, | ||||
| 	.getpgtccfgrx	= ixgbe_dcbnl_get_pg_tc_cfg_rx, | ||||
| 	.getpgbwgcfgrx	= ixgbe_dcbnl_get_pg_bwg_cfg_rx, | ||||
| 	.setpfccfg	= ixgbe_dcbnl_set_pfc_cfg, | ||||
| 	.getpfccfg	= ixgbe_dcbnl_get_pfc_cfg, | ||||
| 	.setall		= ixgbe_dcbnl_set_all, | ||||
| 	.getcap		= ixgbe_dcbnl_getcap, | ||||
| 	.getnumtcs	= ixgbe_dcbnl_getnumtcs, | ||||
| 	.setnumtcs	= ixgbe_dcbnl_setnumtcs, | ||||
| 	.getpfcstate	= ixgbe_dcbnl_getpfcstate, | ||||
| 	.setpfcstate	= ixgbe_dcbnl_setpfcstate, | ||||
| 	.getapp		= ixgbe_dcbnl_getapp, | ||||
| 	.getdcbx	= ixgbe_dcbnl_getdcbx, | ||||
| 	.setdcbx	= ixgbe_dcbnl_setdcbx, | ||||
| }; | ||||
							
								
								
									
										276
									
								
								drivers/net/ethernet/intel/ixgbe/ixgbe_debugfs.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										276
									
								
								drivers/net/ethernet/intel/ixgbe/ixgbe_debugfs.c
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,276 @@ | |||
| /*******************************************************************************
 | ||||
| 
 | ||||
|   Intel 10 Gigabit PCI Express Linux driver | ||||
|   Copyright(c) 1999 - 2013 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: | ||||
|   Linux NICS <linux.nics@intel.com> | ||||
|   e1000-devel Mailing List <e1000-devel@lists.sourceforge.net> | ||||
|   Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 | ||||
| 
 | ||||
| *******************************************************************************/ | ||||
| #include <linux/debugfs.h> | ||||
| #include <linux/module.h> | ||||
| 
 | ||||
| #include "ixgbe.h" | ||||
| 
 | ||||
| static struct dentry *ixgbe_dbg_root; | ||||
| 
 | ||||
| static char ixgbe_dbg_reg_ops_buf[256] = ""; | ||||
| 
 | ||||
| /**
 | ||||
|  * ixgbe_dbg_reg_ops_read - read for reg_ops datum | ||||
|  * @filp: the opened file | ||||
|  * @buffer: where to write the data for the user to read | ||||
|  * @count: the size of the user's buffer | ||||
|  * @ppos: file position offset | ||||
|  **/ | ||||
| static ssize_t ixgbe_dbg_reg_ops_read(struct file *filp, char __user *buffer, | ||||
| 				    size_t count, loff_t *ppos) | ||||
| { | ||||
| 	struct ixgbe_adapter *adapter = filp->private_data; | ||||
| 	char *buf; | ||||
| 	int len; | ||||
| 
 | ||||
| 	/* don't allow partial reads */ | ||||
| 	if (*ppos != 0) | ||||
| 		return 0; | ||||
| 
 | ||||
| 	buf = kasprintf(GFP_KERNEL, "%s: %s\n", | ||||
| 			adapter->netdev->name, | ||||
| 			ixgbe_dbg_reg_ops_buf); | ||||
| 	if (!buf) | ||||
| 		return -ENOMEM; | ||||
| 
 | ||||
| 	if (count < strlen(buf)) { | ||||
| 		kfree(buf); | ||||
| 		return -ENOSPC; | ||||
| 	} | ||||
| 
 | ||||
| 	len = simple_read_from_buffer(buffer, count, ppos, buf, strlen(buf)); | ||||
| 
 | ||||
| 	kfree(buf); | ||||
| 	return len; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  * ixgbe_dbg_reg_ops_write - write into reg_ops datum | ||||
|  * @filp: the opened file | ||||
|  * @buffer: where to find the user's data | ||||
|  * @count: the length of the user's data | ||||
|  * @ppos: file position offset | ||||
|  **/ | ||||
| static ssize_t ixgbe_dbg_reg_ops_write(struct file *filp, | ||||
| 				     const char __user *buffer, | ||||
| 				     size_t count, loff_t *ppos) | ||||
| { | ||||
| 	struct ixgbe_adapter *adapter = filp->private_data; | ||||
| 	int len; | ||||
| 
 | ||||
| 	/* don't allow partial writes */ | ||||
| 	if (*ppos != 0) | ||||
| 		return 0; | ||||
| 	if (count >= sizeof(ixgbe_dbg_reg_ops_buf)) | ||||
| 		return -ENOSPC; | ||||
| 
 | ||||
| 	len = simple_write_to_buffer(ixgbe_dbg_reg_ops_buf, | ||||
| 				     sizeof(ixgbe_dbg_reg_ops_buf)-1, | ||||
| 				     ppos, | ||||
| 				     buffer, | ||||
| 				     count); | ||||
| 	if (len < 0) | ||||
| 		return len; | ||||
| 
 | ||||
| 	ixgbe_dbg_reg_ops_buf[len] = '\0'; | ||||
| 
 | ||||
| 	if (strncmp(ixgbe_dbg_reg_ops_buf, "write", 5) == 0) { | ||||
| 		u32 reg, value; | ||||
| 		int cnt; | ||||
| 		cnt = sscanf(&ixgbe_dbg_reg_ops_buf[5], "%x %x", ®, &value); | ||||
| 		if (cnt == 2) { | ||||
| 			IXGBE_WRITE_REG(&adapter->hw, reg, value); | ||||
| 			value = IXGBE_READ_REG(&adapter->hw, reg); | ||||
| 			e_dev_info("write: 0x%08x = 0x%08x\n", reg, value); | ||||
| 		} else { | ||||
| 			e_dev_info("write <reg> <value>\n"); | ||||
| 		} | ||||
| 	} else if (strncmp(ixgbe_dbg_reg_ops_buf, "read", 4) == 0) { | ||||
| 		u32 reg, value; | ||||
| 		int cnt; | ||||
| 		cnt = sscanf(&ixgbe_dbg_reg_ops_buf[4], "%x", ®); | ||||
| 		if (cnt == 1) { | ||||
| 			value = IXGBE_READ_REG(&adapter->hw, reg); | ||||
| 			e_dev_info("read 0x%08x = 0x%08x\n", reg, value); | ||||
| 		} else { | ||||
| 			e_dev_info("read <reg>\n"); | ||||
| 		} | ||||
| 	} else { | ||||
| 		e_dev_info("Unknown command %s\n", ixgbe_dbg_reg_ops_buf); | ||||
| 		e_dev_info("Available commands:\n"); | ||||
| 		e_dev_info("   read <reg>\n"); | ||||
| 		e_dev_info("   write <reg> <value>\n"); | ||||
| 	} | ||||
| 	return count; | ||||
| } | ||||
| 
 | ||||
| static const struct file_operations ixgbe_dbg_reg_ops_fops = { | ||||
| 	.owner = THIS_MODULE, | ||||
| 	.open = simple_open, | ||||
| 	.read =  ixgbe_dbg_reg_ops_read, | ||||
| 	.write = ixgbe_dbg_reg_ops_write, | ||||
| }; | ||||
| 
 | ||||
| static char ixgbe_dbg_netdev_ops_buf[256] = ""; | ||||
| 
 | ||||
| /**
 | ||||
|  * ixgbe_dbg_netdev_ops_read - read for netdev_ops datum | ||||
|  * @filp: the opened file | ||||
|  * @buffer: where to write the data for the user to read | ||||
|  * @count: the size of the user's buffer | ||||
|  * @ppos: file position offset | ||||
|  **/ | ||||
| static ssize_t ixgbe_dbg_netdev_ops_read(struct file *filp, | ||||
| 					 char __user *buffer, | ||||
| 					 size_t count, loff_t *ppos) | ||||
| { | ||||
| 	struct ixgbe_adapter *adapter = filp->private_data; | ||||
| 	char *buf; | ||||
| 	int len; | ||||
| 
 | ||||
| 	/* don't allow partial reads */ | ||||
| 	if (*ppos != 0) | ||||
| 		return 0; | ||||
| 
 | ||||
| 	buf = kasprintf(GFP_KERNEL, "%s: %s\n", | ||||
| 			adapter->netdev->name, | ||||
| 			ixgbe_dbg_netdev_ops_buf); | ||||
| 	if (!buf) | ||||
| 		return -ENOMEM; | ||||
| 
 | ||||
| 	if (count < strlen(buf)) { | ||||
| 		kfree(buf); | ||||
| 		return -ENOSPC; | ||||
| 	} | ||||
| 
 | ||||
| 	len = simple_read_from_buffer(buffer, count, ppos, buf, strlen(buf)); | ||||
| 
 | ||||
| 	kfree(buf); | ||||
| 	return len; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  * ixgbe_dbg_netdev_ops_write - write into netdev_ops datum | ||||
|  * @filp: the opened file | ||||
|  * @buffer: where to find the user's data | ||||
|  * @count: the length of the user's data | ||||
|  * @ppos: file position offset | ||||
|  **/ | ||||
| static ssize_t ixgbe_dbg_netdev_ops_write(struct file *filp, | ||||
| 					  const char __user *buffer, | ||||
| 					  size_t count, loff_t *ppos) | ||||
| { | ||||
| 	struct ixgbe_adapter *adapter = filp->private_data; | ||||
| 	int len; | ||||
| 
 | ||||
| 	/* don't allow partial writes */ | ||||
| 	if (*ppos != 0) | ||||
| 		return 0; | ||||
| 	if (count >= sizeof(ixgbe_dbg_netdev_ops_buf)) | ||||
| 		return -ENOSPC; | ||||
| 
 | ||||
| 	len = simple_write_to_buffer(ixgbe_dbg_netdev_ops_buf, | ||||
| 				     sizeof(ixgbe_dbg_netdev_ops_buf)-1, | ||||
| 				     ppos, | ||||
| 				     buffer, | ||||
| 				     count); | ||||
| 	if (len < 0) | ||||
| 		return len; | ||||
| 
 | ||||
| 	ixgbe_dbg_netdev_ops_buf[len] = '\0'; | ||||
| 
 | ||||
| 	if (strncmp(ixgbe_dbg_netdev_ops_buf, "tx_timeout", 10) == 0) { | ||||
| 		adapter->netdev->netdev_ops->ndo_tx_timeout(adapter->netdev); | ||||
| 		e_dev_info("tx_timeout called\n"); | ||||
| 	} else { | ||||
| 		e_dev_info("Unknown command: %s\n", ixgbe_dbg_netdev_ops_buf); | ||||
| 		e_dev_info("Available commands:\n"); | ||||
| 		e_dev_info("    tx_timeout\n"); | ||||
| 	} | ||||
| 	return count; | ||||
| } | ||||
| 
 | ||||
| static const struct file_operations ixgbe_dbg_netdev_ops_fops = { | ||||
| 	.owner = THIS_MODULE, | ||||
| 	.open = simple_open, | ||||
| 	.read = ixgbe_dbg_netdev_ops_read, | ||||
| 	.write = ixgbe_dbg_netdev_ops_write, | ||||
| }; | ||||
| 
 | ||||
| /**
 | ||||
|  * ixgbe_dbg_adapter_init - setup the debugfs directory for the adapter | ||||
|  * @adapter: the adapter that is starting up | ||||
|  **/ | ||||
| void ixgbe_dbg_adapter_init(struct ixgbe_adapter *adapter) | ||||
| { | ||||
| 	const char *name = pci_name(adapter->pdev); | ||||
| 	struct dentry *pfile; | ||||
| 	adapter->ixgbe_dbg_adapter = debugfs_create_dir(name, ixgbe_dbg_root); | ||||
| 	if (adapter->ixgbe_dbg_adapter) { | ||||
| 		pfile = debugfs_create_file("reg_ops", 0600, | ||||
| 					    adapter->ixgbe_dbg_adapter, adapter, | ||||
| 					    &ixgbe_dbg_reg_ops_fops); | ||||
| 		if (!pfile) | ||||
| 			e_dev_err("debugfs reg_ops for %s failed\n", name); | ||||
| 		pfile = debugfs_create_file("netdev_ops", 0600, | ||||
| 					    adapter->ixgbe_dbg_adapter, adapter, | ||||
| 					    &ixgbe_dbg_netdev_ops_fops); | ||||
| 		if (!pfile) | ||||
| 			e_dev_err("debugfs netdev_ops for %s failed\n", name); | ||||
| 	} else { | ||||
| 		e_dev_err("debugfs entry for %s failed\n", name); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  * ixgbe_dbg_adapter_exit - clear out the adapter's debugfs entries | ||||
|  * @pf: the pf that is stopping | ||||
|  **/ | ||||
| void ixgbe_dbg_adapter_exit(struct ixgbe_adapter *adapter) | ||||
| { | ||||
| 	debugfs_remove_recursive(adapter->ixgbe_dbg_adapter); | ||||
| 	adapter->ixgbe_dbg_adapter = NULL; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  * ixgbe_dbg_init - start up debugfs for the driver | ||||
|  **/ | ||||
| void ixgbe_dbg_init(void) | ||||
| { | ||||
| 	ixgbe_dbg_root = debugfs_create_dir(ixgbe_driver_name, NULL); | ||||
| 	if (ixgbe_dbg_root == NULL) | ||||
| 		pr_err("init of debugfs failed\n"); | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  * ixgbe_dbg_exit - clean out the driver's debugfs entries | ||||
|  **/ | ||||
| void ixgbe_dbg_exit(void) | ||||
| { | ||||
| 	debugfs_remove_recursive(ixgbe_dbg_root); | ||||
| } | ||||
							
								
								
									
										3094
									
								
								drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										3094
									
								
								drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c
									
										
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							
							
								
								
									
										1005
									
								
								drivers/net/ethernet/intel/ixgbe/ixgbe_fcoe.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										1005
									
								
								drivers/net/ethernet/intel/ixgbe/ixgbe_fcoe.c
									
										
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							
							
								
								
									
										87
									
								
								drivers/net/ethernet/intel/ixgbe/ixgbe_fcoe.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										87
									
								
								drivers/net/ethernet/intel/ixgbe/ixgbe_fcoe.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,87 @@ | |||
| /*******************************************************************************
 | ||||
| 
 | ||||
|   Intel 10 Gigabit PCI Express Linux driver | ||||
|   Copyright(c) 1999 - 2013 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: | ||||
|   Linux NICS <linux.nics@intel.com> | ||||
|   e1000-devel Mailing List <e1000-devel@lists.sourceforge.net> | ||||
|   Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 | ||||
| 
 | ||||
| *******************************************************************************/ | ||||
| 
 | ||||
| #ifndef _IXGBE_FCOE_H | ||||
| #define _IXGBE_FCOE_H | ||||
| 
 | ||||
| #include <scsi/fc/fc_fs.h> | ||||
| #include <scsi/fc/fc_fcoe.h> | ||||
| 
 | ||||
| /* shift bits within STAT fo FCSTAT */ | ||||
| #define IXGBE_RXDADV_FCSTAT_SHIFT	4 | ||||
| 
 | ||||
| /* ddp user buffer */ | ||||
| #define IXGBE_BUFFCNT_MAX	256	/* 8 bits bufcnt */ | ||||
| #define IXGBE_FCPTR_ALIGN	16 | ||||
| #define IXGBE_FCPTR_MAX	(IXGBE_BUFFCNT_MAX * sizeof(dma_addr_t)) | ||||
| #define IXGBE_FCBUFF_4KB	0x0 | ||||
| #define IXGBE_FCBUFF_8KB	0x1 | ||||
| #define IXGBE_FCBUFF_16KB	0x2 | ||||
| #define IXGBE_FCBUFF_64KB	0x3 | ||||
| #define IXGBE_FCBUFF_MAX	65536	/* 64KB max */ | ||||
| #define IXGBE_FCBUFF_MIN	4096	/* 4KB min */ | ||||
| #define IXGBE_FCOE_DDP_MAX	512	/* 9 bits xid */ | ||||
| 
 | ||||
| /* Default traffic class to use for FCoE */ | ||||
| #define IXGBE_FCOE_DEFTC	3 | ||||
| 
 | ||||
| /* fcerr */ | ||||
| #define IXGBE_FCERR_BADCRC       0x00100000 | ||||
| 
 | ||||
| /* FCoE DDP for target mode */ | ||||
| #define __IXGBE_FCOE_TARGET	1 | ||||
| 
 | ||||
| struct ixgbe_fcoe_ddp { | ||||
| 	int len; | ||||
| 	u32 err; | ||||
| 	unsigned int sgc; | ||||
| 	struct scatterlist *sgl; | ||||
| 	dma_addr_t udp; | ||||
| 	u64 *udl; | ||||
| 	struct dma_pool *pool; | ||||
| }; | ||||
| 
 | ||||
| /* per cpu variables */ | ||||
| struct ixgbe_fcoe_ddp_pool { | ||||
| 	struct dma_pool *pool; | ||||
| 	u64 noddp; | ||||
| 	u64 noddp_ext_buff; | ||||
| }; | ||||
| 
 | ||||
| struct ixgbe_fcoe { | ||||
| 	struct ixgbe_fcoe_ddp_pool __percpu *ddp_pool; | ||||
| 	atomic_t refcnt; | ||||
| 	spinlock_t lock; | ||||
| 	struct ixgbe_fcoe_ddp ddp[IXGBE_FCOE_DDP_MAX]; | ||||
| 	void *extra_ddp_buffer; | ||||
| 	dma_addr_t extra_ddp_buffer_dma; | ||||
| 	unsigned long mode; | ||||
| 	u8 up; | ||||
| }; | ||||
| 
 | ||||
| #endif /* _IXGBE_FCOE_H */ | ||||
							
								
								
									
										1219
									
								
								drivers/net/ethernet/intel/ixgbe/ixgbe_lib.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										1219
									
								
								drivers/net/ethernet/intel/ixgbe/ixgbe_lib.c
									
										
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							
							
								
								
									
										8737
									
								
								drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										8737
									
								
								drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
									
										
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							
							
								
								
									
										454
									
								
								drivers/net/ethernet/intel/ixgbe/ixgbe_mbx.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										454
									
								
								drivers/net/ethernet/intel/ixgbe/ixgbe_mbx.c
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,454 @@ | |||
| /*******************************************************************************
 | ||||
| 
 | ||||
|   Intel 10 Gigabit PCI Express Linux driver | ||||
|   Copyright(c) 1999 - 2014 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: | ||||
|   Linux NICS <linux.nics@intel.com> | ||||
|   e1000-devel Mailing List <e1000-devel@lists.sourceforge.net> | ||||
|   Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 | ||||
| 
 | ||||
| *******************************************************************************/ | ||||
| 
 | ||||
| #include <linux/pci.h> | ||||
| #include <linux/delay.h> | ||||
| #include "ixgbe.h" | ||||
| #include "ixgbe_mbx.h" | ||||
| 
 | ||||
| /**
 | ||||
|  *  ixgbe_read_mbx - Reads a message from the mailbox | ||||
|  *  @hw: pointer to the HW structure | ||||
|  *  @msg: The message buffer | ||||
|  *  @size: Length of buffer | ||||
|  *  @mbx_id: id of mailbox to read | ||||
|  * | ||||
|  *  returns SUCCESS if it successfully read message from buffer | ||||
|  **/ | ||||
| s32 ixgbe_read_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size, u16 mbx_id) | ||||
| { | ||||
| 	struct ixgbe_mbx_info *mbx = &hw->mbx; | ||||
| 
 | ||||
| 	/* limit read to size of mailbox */ | ||||
| 	if (size > mbx->size) | ||||
| 		size = mbx->size; | ||||
| 
 | ||||
| 	if (!mbx->ops.read) | ||||
| 		return IXGBE_ERR_MBX; | ||||
| 
 | ||||
| 	return mbx->ops.read(hw, msg, size, mbx_id); | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  *  ixgbe_write_mbx - Write a message to the mailbox | ||||
|  *  @hw: pointer to the HW structure | ||||
|  *  @msg: The message buffer | ||||
|  *  @size: Length of buffer | ||||
|  *  @mbx_id: id of mailbox to write | ||||
|  * | ||||
|  *  returns SUCCESS if it successfully copied message into the buffer | ||||
|  **/ | ||||
| s32 ixgbe_write_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size, u16 mbx_id) | ||||
| { | ||||
| 	struct ixgbe_mbx_info *mbx = &hw->mbx; | ||||
| 
 | ||||
| 	if (size > mbx->size) | ||||
| 		return IXGBE_ERR_MBX; | ||||
| 
 | ||||
| 	if (!mbx->ops.write) | ||||
| 		return IXGBE_ERR_MBX; | ||||
| 
 | ||||
| 	return mbx->ops.write(hw, msg, size, mbx_id); | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  *  ixgbe_check_for_msg - checks to see if someone sent us mail | ||||
|  *  @hw: pointer to the HW structure | ||||
|  *  @mbx_id: id of mailbox to check | ||||
|  * | ||||
|  *  returns SUCCESS if the Status bit was found or else ERR_MBX | ||||
|  **/ | ||||
| s32 ixgbe_check_for_msg(struct ixgbe_hw *hw, u16 mbx_id) | ||||
| { | ||||
| 	struct ixgbe_mbx_info *mbx = &hw->mbx; | ||||
| 
 | ||||
| 	if (!mbx->ops.check_for_msg) | ||||
| 		return IXGBE_ERR_MBX; | ||||
| 
 | ||||
| 	return mbx->ops.check_for_msg(hw, mbx_id); | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  *  ixgbe_check_for_ack - checks to see if someone sent us ACK | ||||
|  *  @hw: pointer to the HW structure | ||||
|  *  @mbx_id: id of mailbox to check | ||||
|  * | ||||
|  *  returns SUCCESS if the Status bit was found or else ERR_MBX | ||||
|  **/ | ||||
| s32 ixgbe_check_for_ack(struct ixgbe_hw *hw, u16 mbx_id) | ||||
| { | ||||
| 	struct ixgbe_mbx_info *mbx = &hw->mbx; | ||||
| 
 | ||||
| 	if (!mbx->ops.check_for_ack) | ||||
| 		return IXGBE_ERR_MBX; | ||||
| 
 | ||||
| 	return mbx->ops.check_for_ack(hw, mbx_id); | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  *  ixgbe_check_for_rst - checks to see if other side has reset | ||||
|  *  @hw: pointer to the HW structure | ||||
|  *  @mbx_id: id of mailbox to check | ||||
|  * | ||||
|  *  returns SUCCESS if the Status bit was found or else ERR_MBX | ||||
|  **/ | ||||
| s32 ixgbe_check_for_rst(struct ixgbe_hw *hw, u16 mbx_id) | ||||
| { | ||||
| 	struct ixgbe_mbx_info *mbx = &hw->mbx; | ||||
| 
 | ||||
| 	if (!mbx->ops.check_for_rst) | ||||
| 		return IXGBE_ERR_MBX; | ||||
| 
 | ||||
| 	return mbx->ops.check_for_rst(hw, mbx_id); | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  *  ixgbe_poll_for_msg - Wait for message notification | ||||
|  *  @hw: pointer to the HW structure | ||||
|  *  @mbx_id: id of mailbox to write | ||||
|  * | ||||
|  *  returns SUCCESS if it successfully received a message notification | ||||
|  **/ | ||||
| static s32 ixgbe_poll_for_msg(struct ixgbe_hw *hw, u16 mbx_id) | ||||
| { | ||||
| 	struct ixgbe_mbx_info *mbx = &hw->mbx; | ||||
| 	int countdown = mbx->timeout; | ||||
| 
 | ||||
| 	if (!countdown || !mbx->ops.check_for_msg) | ||||
| 		return IXGBE_ERR_MBX; | ||||
| 
 | ||||
| 	while (mbx->ops.check_for_msg(hw, mbx_id)) { | ||||
| 		countdown--; | ||||
| 		if (!countdown) | ||||
| 			return IXGBE_ERR_MBX; | ||||
| 		udelay(mbx->usec_delay); | ||||
| 	} | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  *  ixgbe_poll_for_ack - Wait for message acknowledgement | ||||
|  *  @hw: pointer to the HW structure | ||||
|  *  @mbx_id: id of mailbox to write | ||||
|  * | ||||
|  *  returns SUCCESS if it successfully received a message acknowledgement | ||||
|  **/ | ||||
| static s32 ixgbe_poll_for_ack(struct ixgbe_hw *hw, u16 mbx_id) | ||||
| { | ||||
| 	struct ixgbe_mbx_info *mbx = &hw->mbx; | ||||
| 	int countdown = mbx->timeout; | ||||
| 
 | ||||
| 	if (!countdown || !mbx->ops.check_for_ack) | ||||
| 		return IXGBE_ERR_MBX; | ||||
| 
 | ||||
| 	while (mbx->ops.check_for_ack(hw, mbx_id)) { | ||||
| 		countdown--; | ||||
| 		if (!countdown) | ||||
| 			return IXGBE_ERR_MBX; | ||||
| 		udelay(mbx->usec_delay); | ||||
| 	} | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  *  ixgbe_read_posted_mbx - Wait for message notification and receive message | ||||
|  *  @hw: pointer to the HW structure | ||||
|  *  @msg: The message buffer | ||||
|  *  @size: Length of buffer | ||||
|  *  @mbx_id: id of mailbox to write | ||||
|  * | ||||
|  *  returns SUCCESS if it successfully received a message notification and | ||||
|  *  copied it into the receive buffer. | ||||
|  **/ | ||||
| static s32 ixgbe_read_posted_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size, | ||||
| 				 u16 mbx_id) | ||||
| { | ||||
| 	struct ixgbe_mbx_info *mbx = &hw->mbx; | ||||
| 	s32 ret_val; | ||||
| 
 | ||||
| 	if (!mbx->ops.read) | ||||
| 		return IXGBE_ERR_MBX; | ||||
| 
 | ||||
| 	ret_val = ixgbe_poll_for_msg(hw, mbx_id); | ||||
| 	if (ret_val) | ||||
| 		return ret_val; | ||||
| 
 | ||||
| 	/* if ack received read message */ | ||||
| 	return mbx->ops.read(hw, msg, size, mbx_id); | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  *  ixgbe_write_posted_mbx - Write a message to the mailbox, wait for ack | ||||
|  *  @hw: pointer to the HW structure | ||||
|  *  @msg: The message buffer | ||||
|  *  @size: Length of buffer | ||||
|  *  @mbx_id: id of mailbox to write | ||||
|  * | ||||
|  *  returns SUCCESS if it successfully copied message into the buffer and | ||||
|  *  received an ack to that message within delay * timeout period | ||||
|  **/ | ||||
| static s32 ixgbe_write_posted_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size, | ||||
| 			   u16 mbx_id) | ||||
| { | ||||
| 	struct ixgbe_mbx_info *mbx = &hw->mbx; | ||||
| 	s32 ret_val; | ||||
| 
 | ||||
| 	/* exit if either we can't write or there isn't a defined timeout */ | ||||
| 	if (!mbx->ops.write || !mbx->timeout) | ||||
| 		return IXGBE_ERR_MBX; | ||||
| 
 | ||||
| 	/* send msg */ | ||||
| 	ret_val = mbx->ops.write(hw, msg, size, mbx_id); | ||||
| 	if (ret_val) | ||||
| 		return ret_val; | ||||
| 
 | ||||
| 	/* if msg sent wait until we receive an ack */ | ||||
| 	return ixgbe_poll_for_ack(hw, mbx_id); | ||||
| } | ||||
| 
 | ||||
| static s32 ixgbe_check_for_bit_pf(struct ixgbe_hw *hw, u32 mask, s32 index) | ||||
| { | ||||
| 	u32 mbvficr = IXGBE_READ_REG(hw, IXGBE_MBVFICR(index)); | ||||
| 
 | ||||
| 	if (mbvficr & mask) { | ||||
| 		IXGBE_WRITE_REG(hw, IXGBE_MBVFICR(index), mask); | ||||
| 		return 0; | ||||
| 	} | ||||
| 
 | ||||
| 	return IXGBE_ERR_MBX; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  *  ixgbe_check_for_msg_pf - checks to see if the VF has sent mail | ||||
|  *  @hw: pointer to the HW structure | ||||
|  *  @vf_number: the VF index | ||||
|  * | ||||
|  *  returns SUCCESS if the VF has set the Status bit or else ERR_MBX | ||||
|  **/ | ||||
| static s32 ixgbe_check_for_msg_pf(struct ixgbe_hw *hw, u16 vf_number) | ||||
| { | ||||
| 	s32 index = IXGBE_MBVFICR_INDEX(vf_number); | ||||
| 	u32 vf_bit = vf_number % 16; | ||||
| 
 | ||||
| 	if (!ixgbe_check_for_bit_pf(hw, IXGBE_MBVFICR_VFREQ_VF1 << vf_bit, | ||||
| 				    index)) { | ||||
| 		hw->mbx.stats.reqs++; | ||||
| 		return 0; | ||||
| 	} | ||||
| 
 | ||||
| 	return IXGBE_ERR_MBX; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  *  ixgbe_check_for_ack_pf - checks to see if the VF has ACKed | ||||
|  *  @hw: pointer to the HW structure | ||||
|  *  @vf_number: the VF index | ||||
|  * | ||||
|  *  returns SUCCESS if the VF has set the Status bit or else ERR_MBX | ||||
|  **/ | ||||
| static s32 ixgbe_check_for_ack_pf(struct ixgbe_hw *hw, u16 vf_number) | ||||
| { | ||||
| 	s32 index = IXGBE_MBVFICR_INDEX(vf_number); | ||||
| 	u32 vf_bit = vf_number % 16; | ||||
| 
 | ||||
| 	if (!ixgbe_check_for_bit_pf(hw, IXGBE_MBVFICR_VFACK_VF1 << vf_bit, | ||||
| 				    index)) { | ||||
| 		hw->mbx.stats.acks++; | ||||
| 		return 0; | ||||
| 	} | ||||
| 
 | ||||
| 	return IXGBE_ERR_MBX; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  *  ixgbe_check_for_rst_pf - checks to see if the VF has reset | ||||
|  *  @hw: pointer to the HW structure | ||||
|  *  @vf_number: the VF index | ||||
|  * | ||||
|  *  returns SUCCESS if the VF has set the Status bit or else ERR_MBX | ||||
|  **/ | ||||
| static s32 ixgbe_check_for_rst_pf(struct ixgbe_hw *hw, u16 vf_number) | ||||
| { | ||||
| 	u32 reg_offset = (vf_number < 32) ? 0 : 1; | ||||
| 	u32 vf_shift = vf_number % 32; | ||||
| 	u32 vflre = 0; | ||||
| 
 | ||||
| 	switch (hw->mac.type) { | ||||
| 	case ixgbe_mac_82599EB: | ||||
| 		vflre = IXGBE_READ_REG(hw, IXGBE_VFLRE(reg_offset)); | ||||
| 		break; | ||||
| 	case ixgbe_mac_X540: | ||||
| 		vflre = IXGBE_READ_REG(hw, IXGBE_VFLREC(reg_offset)); | ||||
| 		break; | ||||
| 	default: | ||||
| 		break; | ||||
| 	} | ||||
| 
 | ||||
| 	if (vflre & (1 << vf_shift)) { | ||||
| 		IXGBE_WRITE_REG(hw, IXGBE_VFLREC(reg_offset), (1 << vf_shift)); | ||||
| 		hw->mbx.stats.rsts++; | ||||
| 		return 0; | ||||
| 	} | ||||
| 
 | ||||
| 	return IXGBE_ERR_MBX; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  *  ixgbe_obtain_mbx_lock_pf - obtain mailbox lock | ||||
|  *  @hw: pointer to the HW structure | ||||
|  *  @vf_number: the VF index | ||||
|  * | ||||
|  *  return SUCCESS if we obtained the mailbox lock | ||||
|  **/ | ||||
| static s32 ixgbe_obtain_mbx_lock_pf(struct ixgbe_hw *hw, u16 vf_number) | ||||
| { | ||||
| 	u32 p2v_mailbox; | ||||
| 
 | ||||
| 	/* Take ownership of the buffer */ | ||||
| 	IXGBE_WRITE_REG(hw, IXGBE_PFMAILBOX(vf_number), IXGBE_PFMAILBOX_PFU); | ||||
| 
 | ||||
| 	/* reserve mailbox for vf use */ | ||||
| 	p2v_mailbox = IXGBE_READ_REG(hw, IXGBE_PFMAILBOX(vf_number)); | ||||
| 	if (p2v_mailbox & IXGBE_PFMAILBOX_PFU) | ||||
| 		return 0; | ||||
| 
 | ||||
| 	return IXGBE_ERR_MBX; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  *  ixgbe_write_mbx_pf - Places a message in the mailbox | ||||
|  *  @hw: pointer to the HW structure | ||||
|  *  @msg: The message buffer | ||||
|  *  @size: Length of buffer | ||||
|  *  @vf_number: the VF index | ||||
|  * | ||||
|  *  returns SUCCESS if it successfully copied message into the buffer | ||||
|  **/ | ||||
| static s32 ixgbe_write_mbx_pf(struct ixgbe_hw *hw, u32 *msg, u16 size, | ||||
| 			      u16 vf_number) | ||||
| { | ||||
| 	s32 ret_val; | ||||
| 	u16 i; | ||||
| 
 | ||||
| 	/* lock the mailbox to prevent pf/vf race condition */ | ||||
| 	ret_val = ixgbe_obtain_mbx_lock_pf(hw, vf_number); | ||||
| 	if (ret_val) | ||||
| 		return ret_val; | ||||
| 
 | ||||
| 	/* flush msg and acks as we are overwriting the message buffer */ | ||||
| 	ixgbe_check_for_msg_pf(hw, vf_number); | ||||
| 	ixgbe_check_for_ack_pf(hw, vf_number); | ||||
| 
 | ||||
| 	/* copy the caller specified message to the mailbox memory buffer */ | ||||
| 	for (i = 0; i < size; i++) | ||||
| 		IXGBE_WRITE_REG_ARRAY(hw, IXGBE_PFMBMEM(vf_number), i, msg[i]); | ||||
| 
 | ||||
| 	/* Interrupt VF to tell it a message has been sent and release buffer*/ | ||||
| 	IXGBE_WRITE_REG(hw, IXGBE_PFMAILBOX(vf_number), IXGBE_PFMAILBOX_STS); | ||||
| 
 | ||||
| 	/* update stats */ | ||||
| 	hw->mbx.stats.msgs_tx++; | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  *  ixgbe_read_mbx_pf - Read a message from the mailbox | ||||
|  *  @hw: pointer to the HW structure | ||||
|  *  @msg: The message buffer | ||||
|  *  @size: Length of buffer | ||||
|  *  @vf_number: the VF index | ||||
|  * | ||||
|  *  This function copies a message from the mailbox buffer to the caller's | ||||
|  *  memory buffer.  The presumption is that the caller knows that there was | ||||
|  *  a message due to a VF request so no polling for message is needed. | ||||
|  **/ | ||||
| static s32 ixgbe_read_mbx_pf(struct ixgbe_hw *hw, u32 *msg, u16 size, | ||||
| 			     u16 vf_number) | ||||
| { | ||||
| 	s32 ret_val; | ||||
| 	u16 i; | ||||
| 
 | ||||
| 	/* lock the mailbox to prevent pf/vf race condition */ | ||||
| 	ret_val = ixgbe_obtain_mbx_lock_pf(hw, vf_number); | ||||
| 	if (ret_val) | ||||
| 		return ret_val; | ||||
| 
 | ||||
| 	/* copy the message to the mailbox memory buffer */ | ||||
| 	for (i = 0; i < size; i++) | ||||
| 		msg[i] = IXGBE_READ_REG_ARRAY(hw, IXGBE_PFMBMEM(vf_number), i); | ||||
| 
 | ||||
| 	/* Acknowledge the message and release buffer */ | ||||
| 	IXGBE_WRITE_REG(hw, IXGBE_PFMAILBOX(vf_number), IXGBE_PFMAILBOX_ACK); | ||||
| 
 | ||||
| 	/* update stats */ | ||||
| 	hw->mbx.stats.msgs_rx++; | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| #ifdef CONFIG_PCI_IOV | ||||
| /**
 | ||||
|  *  ixgbe_init_mbx_params_pf - set initial values for pf mailbox | ||||
|  *  @hw: pointer to the HW structure | ||||
|  * | ||||
|  *  Initializes the hw->mbx struct to correct values for pf mailbox | ||||
|  */ | ||||
| void ixgbe_init_mbx_params_pf(struct ixgbe_hw *hw) | ||||
| { | ||||
| 	struct ixgbe_mbx_info *mbx = &hw->mbx; | ||||
| 
 | ||||
| 	if (hw->mac.type != ixgbe_mac_82599EB && | ||||
| 	    hw->mac.type != ixgbe_mac_X540) | ||||
| 		return; | ||||
| 
 | ||||
| 	mbx->timeout = 0; | ||||
| 	mbx->usec_delay = 0; | ||||
| 
 | ||||
| 	mbx->stats.msgs_tx = 0; | ||||
| 	mbx->stats.msgs_rx = 0; | ||||
| 	mbx->stats.reqs = 0; | ||||
| 	mbx->stats.acks = 0; | ||||
| 	mbx->stats.rsts = 0; | ||||
| 
 | ||||
| 	mbx->size = IXGBE_VFMAILBOX_SIZE; | ||||
| } | ||||
| #endif /* CONFIG_PCI_IOV */ | ||||
| 
 | ||||
| struct ixgbe_mbx_operations mbx_ops_generic = { | ||||
| 	.read                   = ixgbe_read_mbx_pf, | ||||
| 	.write                  = ixgbe_write_mbx_pf, | ||||
| 	.read_posted            = ixgbe_read_posted_mbx, | ||||
| 	.write_posted           = ixgbe_write_posted_mbx, | ||||
| 	.check_for_msg          = ixgbe_check_for_msg_pf, | ||||
| 	.check_for_ack          = ixgbe_check_for_ack_pf, | ||||
| 	.check_for_rst          = ixgbe_check_for_rst_pf, | ||||
| }; | ||||
| 
 | ||||
							
								
								
									
										121
									
								
								drivers/net/ethernet/intel/ixgbe/ixgbe_mbx.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										121
									
								
								drivers/net/ethernet/intel/ixgbe/ixgbe_mbx.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,121 @@ | |||
| /*******************************************************************************
 | ||||
| 
 | ||||
|   Intel 10 Gigabit PCI Express Linux driver | ||||
|   Copyright(c) 1999 - 2013 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: | ||||
|   Linux NICS <linux.nics@intel.com> | ||||
|   e1000-devel Mailing List <e1000-devel@lists.sourceforge.net> | ||||
|   Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 | ||||
| 
 | ||||
| *******************************************************************************/ | ||||
| 
 | ||||
| #ifndef _IXGBE_MBX_H_ | ||||
| #define _IXGBE_MBX_H_ | ||||
| 
 | ||||
| #include "ixgbe_type.h" | ||||
| 
 | ||||
| #define IXGBE_VFMAILBOX_SIZE        16 /* 16 32 bit words - 64 bytes */ | ||||
| #define IXGBE_ERR_MBX               -100 | ||||
| 
 | ||||
| #define IXGBE_VFMAILBOX             0x002FC | ||||
| #define IXGBE_VFMBMEM               0x00200 | ||||
| 
 | ||||
| #define IXGBE_PFMAILBOX_STS   0x00000001 /* Initiate message send to VF */ | ||||
| #define IXGBE_PFMAILBOX_ACK   0x00000002 /* Ack message recv'd from VF */ | ||||
| #define IXGBE_PFMAILBOX_VFU   0x00000004 /* VF owns the mailbox buffer */ | ||||
| #define IXGBE_PFMAILBOX_PFU   0x00000008 /* PF owns the mailbox buffer */ | ||||
| #define IXGBE_PFMAILBOX_RVFU  0x00000010 /* Reset VFU - used when VF stuck */ | ||||
| 
 | ||||
| #define IXGBE_MBVFICR_VFREQ_MASK 0x0000FFFF /* bits for VF messages */ | ||||
| #define IXGBE_MBVFICR_VFREQ_VF1  0x00000001 /* bit for VF 1 message */ | ||||
| #define IXGBE_MBVFICR_VFACK_MASK 0xFFFF0000 /* bits for VF acks */ | ||||
| #define IXGBE_MBVFICR_VFACK_VF1  0x00010000 /* bit for VF 1 ack */ | ||||
| 
 | ||||
| 
 | ||||
| /* If it's a IXGBE_VF_* msg then it originates in the VF and is sent to the
 | ||||
|  * PF.  The reverse is true if it is IXGBE_PF_*. | ||||
|  * Message ACK's are the value or'd with 0xF0000000 | ||||
|  */ | ||||
| #define IXGBE_VT_MSGTYPE_ACK      0x80000000  /* Messages below or'd with | ||||
| 					       * this are the ACK */ | ||||
| #define IXGBE_VT_MSGTYPE_NACK     0x40000000  /* Messages below or'd with | ||||
| 					       * this are the NACK */ | ||||
| #define IXGBE_VT_MSGTYPE_CTS      0x20000000  /* Indicates that VF is still | ||||
| 						 clear to send requests */ | ||||
| #define IXGBE_VT_MSGINFO_SHIFT    16 | ||||
| /* bits 23:16 are used for exra info for certain messages */ | ||||
| #define IXGBE_VT_MSGINFO_MASK     (0xFF << IXGBE_VT_MSGINFO_SHIFT) | ||||
| 
 | ||||
| /* definitions to support mailbox API version negotiation */ | ||||
| 
 | ||||
| /*
 | ||||
|  * Each element denotes a version of the API; existing numbers may not | ||||
|  * change; any additions must go at the end | ||||
|  */ | ||||
| enum ixgbe_pfvf_api_rev { | ||||
| 	ixgbe_mbox_api_10,	/* API version 1.0, linux/freebsd VF driver */ | ||||
| 	ixgbe_mbox_api_20,	/* API version 2.0, solaris Phase1 VF driver */ | ||||
| 	ixgbe_mbox_api_11,	/* API version 1.1, linux/freebsd VF driver */ | ||||
| 	/* This value should always be last */ | ||||
| 	ixgbe_mbox_api_unknown,	/* indicates that API version is not known */ | ||||
| }; | ||||
| 
 | ||||
| /* mailbox API, legacy requests */ | ||||
| #define IXGBE_VF_RESET            0x01 /* VF requests reset */ | ||||
| #define IXGBE_VF_SET_MAC_ADDR     0x02 /* VF requests PF to set MAC addr */ | ||||
| #define IXGBE_VF_SET_MULTICAST    0x03 /* VF requests PF to set MC addr */ | ||||
| #define IXGBE_VF_SET_VLAN         0x04 /* VF requests PF to set VLAN */ | ||||
| 
 | ||||
| /* mailbox API, version 1.0 VF requests */ | ||||
| #define IXGBE_VF_SET_LPE	0x05 /* VF requests PF to set VMOLR.LPE */ | ||||
| #define IXGBE_VF_SET_MACVLAN	0x06 /* VF requests PF for unicast filter */ | ||||
| #define IXGBE_VF_API_NEGOTIATE	0x08 /* negotiate API version */ | ||||
| 
 | ||||
| /* mailbox API, version 1.1 VF requests */ | ||||
| #define IXGBE_VF_GET_QUEUES	0x09 /* get queue configuration */ | ||||
| 
 | ||||
| /* GET_QUEUES return data indices within the mailbox */ | ||||
| #define IXGBE_VF_TX_QUEUES	1	/* number of Tx queues supported */ | ||||
| #define IXGBE_VF_RX_QUEUES	2	/* number of Rx queues supported */ | ||||
| #define IXGBE_VF_TRANS_VLAN	3	/* Indication of port vlan */ | ||||
| #define IXGBE_VF_DEF_QUEUE	4	/* Default queue offset */ | ||||
| 
 | ||||
| /* length of permanent address message returned from PF */ | ||||
| #define IXGBE_VF_PERMADDR_MSG_LEN 4 | ||||
| /* word in permanent address message with the current multicast type */ | ||||
| #define IXGBE_VF_MC_TYPE_WORD     3 | ||||
| 
 | ||||
| #define IXGBE_PF_CONTROL_MSG      0x0100 /* PF control message */ | ||||
| 
 | ||||
| #define IXGBE_VF_MBX_INIT_TIMEOUT 2000 /* number of retries on mailbox */ | ||||
| #define IXGBE_VF_MBX_INIT_DELAY   500  /* microseconds between retries */ | ||||
| 
 | ||||
| s32 ixgbe_read_mbx(struct ixgbe_hw *, u32 *, u16, u16); | ||||
| s32 ixgbe_write_mbx(struct ixgbe_hw *, u32 *, u16, u16); | ||||
| s32 ixgbe_check_for_msg(struct ixgbe_hw *, u16); | ||||
| s32 ixgbe_check_for_ack(struct ixgbe_hw *, u16); | ||||
| s32 ixgbe_check_for_rst(struct ixgbe_hw *, u16); | ||||
| #ifdef CONFIG_PCI_IOV | ||||
| void ixgbe_init_mbx_params_pf(struct ixgbe_hw *); | ||||
| #endif /* CONFIG_PCI_IOV */ | ||||
| 
 | ||||
| extern struct ixgbe_mbx_operations mbx_ops_generic; | ||||
| 
 | ||||
| #endif /* _IXGBE_MBX_H_ */ | ||||
							
								
								
									
										1956
									
								
								drivers/net/ethernet/intel/ixgbe/ixgbe_phy.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										1956
									
								
								drivers/net/ethernet/intel/ixgbe/ixgbe_phy.c
									
										
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							
							
								
								
									
										160
									
								
								drivers/net/ethernet/intel/ixgbe/ixgbe_phy.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										160
									
								
								drivers/net/ethernet/intel/ixgbe/ixgbe_phy.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,160 @@ | |||
| /*******************************************************************************
 | ||||
| 
 | ||||
|   Intel 10 Gigabit PCI Express Linux driver | ||||
|   Copyright(c) 1999 - 2014 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: | ||||
|   Linux NICS <linux.nics@intel.com> | ||||
|   e1000-devel Mailing List <e1000-devel@lists.sourceforge.net> | ||||
|   Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 | ||||
| 
 | ||||
| *******************************************************************************/ | ||||
| 
 | ||||
| #ifndef _IXGBE_PHY_H_ | ||||
| #define _IXGBE_PHY_H_ | ||||
| 
 | ||||
| #include "ixgbe_type.h" | ||||
| #define IXGBE_I2C_EEPROM_DEV_ADDR    0xA0 | ||||
| #define IXGBE_I2C_EEPROM_DEV_ADDR2   0xA2 | ||||
| 
 | ||||
| /* EEPROM byte offsets */ | ||||
| #define IXGBE_SFF_IDENTIFIER		0x0 | ||||
| #define IXGBE_SFF_IDENTIFIER_SFP	0x3 | ||||
| #define IXGBE_SFF_VENDOR_OUI_BYTE0	0x25 | ||||
| #define IXGBE_SFF_VENDOR_OUI_BYTE1	0x26 | ||||
| #define IXGBE_SFF_VENDOR_OUI_BYTE2	0x27 | ||||
| #define IXGBE_SFF_1GBE_COMP_CODES	0x6 | ||||
| #define IXGBE_SFF_10GBE_COMP_CODES	0x3 | ||||
| #define IXGBE_SFF_CABLE_TECHNOLOGY	0x8 | ||||
| #define IXGBE_SFF_CABLE_SPEC_COMP	0x3C | ||||
| #define IXGBE_SFF_SFF_8472_SWAP		0x5C | ||||
| #define IXGBE_SFF_SFF_8472_COMP		0x5E | ||||
| #define IXGBE_SFF_SFF_8472_OSCB		0x6E | ||||
| #define IXGBE_SFF_SFF_8472_ESCB		0x76 | ||||
| #define IXGBE_SFF_IDENTIFIER_QSFP_PLUS	0xD | ||||
| #define IXGBE_SFF_QSFP_VENDOR_OUI_BYTE0	0xA5 | ||||
| #define IXGBE_SFF_QSFP_VENDOR_OUI_BYTE1	0xA6 | ||||
| #define IXGBE_SFF_QSFP_VENDOR_OUI_BYTE2	0xA7 | ||||
| #define IXGBE_SFF_QSFP_CONNECTOR	0x82 | ||||
| #define IXGBE_SFF_QSFP_10GBE_COMP	0x83 | ||||
| #define IXGBE_SFF_QSFP_1GBE_COMP	0x86 | ||||
| #define IXGBE_SFF_QSFP_CABLE_LENGTH	0x92 | ||||
| #define IXGBE_SFF_QSFP_DEVICE_TECH	0x93 | ||||
| 
 | ||||
| /* Bitmasks */ | ||||
| #define IXGBE_SFF_DA_PASSIVE_CABLE		0x4 | ||||
| #define IXGBE_SFF_DA_ACTIVE_CABLE		0x8 | ||||
| #define IXGBE_SFF_DA_SPEC_ACTIVE_LIMITING	0x4 | ||||
| #define IXGBE_SFF_1GBASESX_CAPABLE		0x1 | ||||
| #define IXGBE_SFF_1GBASELX_CAPABLE		0x2 | ||||
| #define IXGBE_SFF_1GBASET_CAPABLE		0x8 | ||||
| #define IXGBE_SFF_10GBASESR_CAPABLE		0x10 | ||||
| #define IXGBE_SFF_10GBASELR_CAPABLE		0x20 | ||||
| #define IXGBE_SFF_ADDRESSING_MODE		0x4 | ||||
| #define IXGBE_SFF_QSFP_DA_ACTIVE_CABLE		0x1 | ||||
| #define IXGBE_SFF_QSFP_DA_PASSIVE_CABLE		0x8 | ||||
| #define IXGBE_SFF_QSFP_CONNECTOR_NOT_SEPARABLE	0x23 | ||||
| #define IXGBE_SFF_QSFP_TRANSMITER_850NM_VCSEL	0x0 | ||||
| #define IXGBE_I2C_EEPROM_READ_MASK		0x100 | ||||
| #define IXGBE_I2C_EEPROM_STATUS_MASK		0x3 | ||||
| #define IXGBE_I2C_EEPROM_STATUS_NO_OPERATION	0x0 | ||||
| #define IXGBE_I2C_EEPROM_STATUS_PASS		0x1 | ||||
| #define IXGBE_I2C_EEPROM_STATUS_FAIL		0x2 | ||||
| #define IXGBE_I2C_EEPROM_STATUS_IN_PROGRESS	0x3 | ||||
| /* Flow control defines */ | ||||
| #define IXGBE_TAF_SYM_PAUSE                  0x400 | ||||
| #define IXGBE_TAF_ASM_PAUSE                  0x800 | ||||
| 
 | ||||
| /* Bit-shift macros */ | ||||
| #define IXGBE_SFF_VENDOR_OUI_BYTE0_SHIFT    24 | ||||
| #define IXGBE_SFF_VENDOR_OUI_BYTE1_SHIFT    16 | ||||
| #define IXGBE_SFF_VENDOR_OUI_BYTE2_SHIFT    8 | ||||
| 
 | ||||
| /* Vendor OUIs: format of OUI is 0x[byte0][byte1][byte2][00] */ | ||||
| #define IXGBE_SFF_VENDOR_OUI_TYCO     0x00407600 | ||||
| #define IXGBE_SFF_VENDOR_OUI_FTL      0x00906500 | ||||
| #define IXGBE_SFF_VENDOR_OUI_AVAGO    0x00176A00 | ||||
| #define IXGBE_SFF_VENDOR_OUI_INTEL    0x001B2100 | ||||
| 
 | ||||
| /* I2C SDA and SCL timing parameters for standard mode */ | ||||
| #define IXGBE_I2C_T_HD_STA  4 | ||||
| #define IXGBE_I2C_T_LOW     5 | ||||
| #define IXGBE_I2C_T_HIGH    4 | ||||
| #define IXGBE_I2C_T_SU_STA  5 | ||||
| #define IXGBE_I2C_T_HD_DATA 5 | ||||
| #define IXGBE_I2C_T_SU_DATA 1 | ||||
| #define IXGBE_I2C_T_RISE    1 | ||||
| #define IXGBE_I2C_T_FALL    1 | ||||
| #define IXGBE_I2C_T_SU_STO  4 | ||||
| #define IXGBE_I2C_T_BUF     5 | ||||
| 
 | ||||
| #define IXGBE_TN_LASI_STATUS_REG        0x9005 | ||||
| #define IXGBE_TN_LASI_STATUS_TEMP_ALARM 0x0008 | ||||
| 
 | ||||
| /* SFP+ SFF-8472 Compliance code */ | ||||
| #define IXGBE_SFF_SFF_8472_UNSUP      0x00 | ||||
| 
 | ||||
| s32 ixgbe_init_phy_ops_generic(struct ixgbe_hw *hw); | ||||
| s32 ixgbe_identify_phy_generic(struct ixgbe_hw *hw); | ||||
| s32 ixgbe_reset_phy_generic(struct ixgbe_hw *hw); | ||||
| s32 ixgbe_read_phy_reg_generic(struct ixgbe_hw *hw, u32 reg_addr, | ||||
| 			       u32 device_type, u16 *phy_data); | ||||
| s32 ixgbe_write_phy_reg_generic(struct ixgbe_hw *hw, u32 reg_addr, | ||||
| 				u32 device_type, u16 phy_data); | ||||
| s32 ixgbe_read_phy_reg_mdi(struct ixgbe_hw *hw, u32 reg_addr, | ||||
| 			   u32 device_type, u16 *phy_data); | ||||
| s32 ixgbe_write_phy_reg_mdi(struct ixgbe_hw *hw, u32 reg_addr, | ||||
| 			    u32 device_type, u16 phy_data); | ||||
| s32 ixgbe_setup_phy_link_generic(struct ixgbe_hw *hw); | ||||
| s32 ixgbe_setup_phy_link_speed_generic(struct ixgbe_hw *hw, | ||||
| 				       ixgbe_link_speed speed, | ||||
| 				       bool autoneg_wait_to_complete); | ||||
| s32 ixgbe_get_copper_link_capabilities_generic(struct ixgbe_hw *hw, | ||||
| 					       ixgbe_link_speed *speed, | ||||
| 					       bool *autoneg); | ||||
| bool ixgbe_check_reset_blocked(struct ixgbe_hw *hw); | ||||
| 
 | ||||
| /* PHY specific */ | ||||
| s32 ixgbe_check_phy_link_tnx(struct ixgbe_hw *hw, | ||||
| 			     ixgbe_link_speed *speed, | ||||
| 			     bool *link_up); | ||||
| s32 ixgbe_setup_phy_link_tnx(struct ixgbe_hw *hw); | ||||
| s32 ixgbe_get_phy_firmware_version_tnx(struct ixgbe_hw *hw, | ||||
| 				       u16 *firmware_version); | ||||
| s32 ixgbe_get_phy_firmware_version_generic(struct ixgbe_hw *hw, | ||||
| 					   u16 *firmware_version); | ||||
| 
 | ||||
| s32 ixgbe_reset_phy_nl(struct ixgbe_hw *hw); | ||||
| s32 ixgbe_identify_module_generic(struct ixgbe_hw *hw); | ||||
| s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw); | ||||
| s32 ixgbe_get_sfp_init_sequence_offsets(struct ixgbe_hw *hw, | ||||
| 					u16 *list_offset, | ||||
| 					u16 *data_offset); | ||||
| s32 ixgbe_tn_check_overtemp(struct ixgbe_hw *hw); | ||||
| s32 ixgbe_read_i2c_byte_generic(struct ixgbe_hw *hw, u8 byte_offset, | ||||
| 				u8 dev_addr, u8 *data); | ||||
| s32 ixgbe_write_i2c_byte_generic(struct ixgbe_hw *hw, u8 byte_offset, | ||||
| 				 u8 dev_addr, u8 data); | ||||
| s32 ixgbe_read_i2c_eeprom_generic(struct ixgbe_hw *hw, u8 byte_offset, | ||||
| 				  u8 *eeprom_data); | ||||
| s32 ixgbe_read_i2c_sff8472_generic(struct ixgbe_hw *hw, u8 byte_offset, | ||||
| 				   u8 *sff8472_data); | ||||
| s32 ixgbe_write_i2c_eeprom_generic(struct ixgbe_hw *hw, u8 byte_offset, | ||||
| 				   u8 eeprom_data); | ||||
| #endif /* _IXGBE_PHY_H_ */ | ||||
							
								
								
									
										1009
									
								
								drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										1009
									
								
								drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c
									
										
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							
							
								
								
									
										1299
									
								
								drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										1299
									
								
								drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c
									
										
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							
							
								
								
									
										69
									
								
								drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										69
									
								
								drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,69 @@ | |||
| /*******************************************************************************
 | ||||
| 
 | ||||
|   Intel 10 Gigabit PCI Express Linux driver | ||||
|   Copyright(c) 1999 - 2013 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: | ||||
|   Linux NICS <linux.nics@intel.com> | ||||
|   e1000-devel Mailing List <e1000-devel@lists.sourceforge.net> | ||||
|   Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 | ||||
| 
 | ||||
| *******************************************************************************/ | ||||
| 
 | ||||
| #ifndef _IXGBE_SRIOV_H_ | ||||
| #define _IXGBE_SRIOV_H_ | ||||
| 
 | ||||
| /*  ixgbe driver limit the max number of VFs could be enabled to
 | ||||
|  *  63 (IXGBE_MAX_VF_FUNCTIONS - 1) | ||||
|  */ | ||||
| #define IXGBE_MAX_VFS_DRV_LIMIT  (IXGBE_MAX_VF_FUNCTIONS - 1) | ||||
| 
 | ||||
| #ifdef CONFIG_PCI_IOV | ||||
| void ixgbe_restore_vf_multicasts(struct ixgbe_adapter *adapter); | ||||
| #endif | ||||
| void ixgbe_msg_task(struct ixgbe_adapter *adapter); | ||||
| int ixgbe_vf_configuration(struct pci_dev *pdev, unsigned int event_mask); | ||||
| void ixgbe_disable_tx_rx(struct ixgbe_adapter *adapter); | ||||
| void ixgbe_ping_all_vfs(struct ixgbe_adapter *adapter); | ||||
| int ixgbe_ndo_set_vf_mac(struct net_device *netdev, int queue, u8 *mac); | ||||
| int ixgbe_ndo_set_vf_vlan(struct net_device *netdev, int queue, u16 vlan, | ||||
| 			   u8 qos); | ||||
| int ixgbe_ndo_set_vf_bw(struct net_device *netdev, int vf, int min_tx_rate, | ||||
| 			int max_tx_rate); | ||||
| int ixgbe_ndo_set_vf_spoofchk(struct net_device *netdev, int vf, bool setting); | ||||
| int ixgbe_ndo_get_vf_config(struct net_device *netdev, | ||||
| 			    int vf, struct ifla_vf_info *ivi); | ||||
| void ixgbe_check_vf_rate_limit(struct ixgbe_adapter *adapter); | ||||
| int ixgbe_disable_sriov(struct ixgbe_adapter *adapter); | ||||
| #ifdef CONFIG_PCI_IOV | ||||
| void ixgbe_enable_sriov(struct ixgbe_adapter *adapter); | ||||
| #endif | ||||
| int ixgbe_pci_sriov_configure(struct pci_dev *dev, int num_vfs); | ||||
| 
 | ||||
| static inline void ixgbe_set_vmvir(struct ixgbe_adapter *adapter, | ||||
| 				   u16 vid, u16 qos, u32 vf) | ||||
| { | ||||
| 	struct ixgbe_hw *hw = &adapter->hw; | ||||
| 	u32 vmvir = vid | (qos << VLAN_PRIO_SHIFT) | IXGBE_VMVIR_VLANA_DEFAULT; | ||||
| 
 | ||||
| 	IXGBE_WRITE_REG(hw, IXGBE_VMVIR(vf), vmvir); | ||||
| } | ||||
| 
 | ||||
| #endif /* _IXGBE_SRIOV_H_ */ | ||||
| 
 | ||||
							
								
								
									
										230
									
								
								drivers/net/ethernet/intel/ixgbe/ixgbe_sysfs.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										230
									
								
								drivers/net/ethernet/intel/ixgbe/ixgbe_sysfs.c
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,230 @@ | |||
| /*******************************************************************************
 | ||||
| 
 | ||||
|   Intel 10 Gigabit PCI Express Linux driver | ||||
|   Copyright(c) 1999 - 2013 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: | ||||
|   Linux NICS <linux.nics@intel.com> | ||||
|   e1000-devel Mailing List <e1000-devel@lists.sourceforge.net> | ||||
|   Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 | ||||
| 
 | ||||
| *******************************************************************************/ | ||||
| 
 | ||||
| #include "ixgbe.h" | ||||
| #include "ixgbe_common.h" | ||||
| #include "ixgbe_type.h" | ||||
| 
 | ||||
| #include <linux/module.h> | ||||
| #include <linux/types.h> | ||||
| #include <linux/sysfs.h> | ||||
| #include <linux/kobject.h> | ||||
| #include <linux/device.h> | ||||
| #include <linux/netdevice.h> | ||||
| #include <linux/hwmon.h> | ||||
| 
 | ||||
| /* hwmon callback functions */ | ||||
| static ssize_t ixgbe_hwmon_show_location(struct device *dev, | ||||
| 					 struct device_attribute *attr, | ||||
| 					 char *buf) | ||||
| { | ||||
| 	struct hwmon_attr *ixgbe_attr = container_of(attr, struct hwmon_attr, | ||||
| 						     dev_attr); | ||||
| 	return sprintf(buf, "loc%u\n", | ||||
| 		       ixgbe_attr->sensor->location); | ||||
| } | ||||
| 
 | ||||
| static ssize_t ixgbe_hwmon_show_temp(struct device *dev, | ||||
| 				     struct device_attribute *attr, | ||||
| 				     char *buf) | ||||
| { | ||||
| 	struct hwmon_attr *ixgbe_attr = container_of(attr, struct hwmon_attr, | ||||
| 						     dev_attr); | ||||
| 	unsigned int value; | ||||
| 
 | ||||
| 	/* reset the temp field */ | ||||
| 	ixgbe_attr->hw->mac.ops.get_thermal_sensor_data(ixgbe_attr->hw); | ||||
| 
 | ||||
| 	value = ixgbe_attr->sensor->temp; | ||||
| 
 | ||||
| 	/* display millidegree */ | ||||
| 	value *= 1000; | ||||
| 
 | ||||
| 	return sprintf(buf, "%u\n", value); | ||||
| } | ||||
| 
 | ||||
| static ssize_t ixgbe_hwmon_show_cautionthresh(struct device *dev, | ||||
| 				     struct device_attribute *attr, | ||||
| 				     char *buf) | ||||
| { | ||||
| 	struct hwmon_attr *ixgbe_attr = container_of(attr, struct hwmon_attr, | ||||
| 						     dev_attr); | ||||
| 	unsigned int value = ixgbe_attr->sensor->caution_thresh; | ||||
| 
 | ||||
| 	/* display millidegree */ | ||||
| 	value *= 1000; | ||||
| 
 | ||||
| 	return sprintf(buf, "%u\n", value); | ||||
| } | ||||
| 
 | ||||
| static ssize_t ixgbe_hwmon_show_maxopthresh(struct device *dev, | ||||
| 				     struct device_attribute *attr, | ||||
| 				     char *buf) | ||||
| { | ||||
| 	struct hwmon_attr *ixgbe_attr = container_of(attr, struct hwmon_attr, | ||||
| 						     dev_attr); | ||||
| 	unsigned int value = ixgbe_attr->sensor->max_op_thresh; | ||||
| 
 | ||||
| 	/* display millidegree */ | ||||
| 	value *= 1000; | ||||
| 
 | ||||
| 	return sprintf(buf, "%u\n", value); | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  * ixgbe_add_hwmon_attr - Create hwmon attr table for a hwmon sysfs file. | ||||
|  * @adapter: pointer to the adapter structure | ||||
|  * @offset: offset in the eeprom sensor data table | ||||
|  * @type: type of sensor data to display | ||||
|  * | ||||
|  * For each file we want in hwmon's sysfs interface we need a device_attribute | ||||
|  * This is included in our hwmon_attr struct that contains the references to | ||||
|  * the data structures we need to get the data to display. | ||||
|  */ | ||||
| static int ixgbe_add_hwmon_attr(struct ixgbe_adapter *adapter, | ||||
| 				unsigned int offset, int type) { | ||||
| 	int rc; | ||||
| 	unsigned int n_attr; | ||||
| 	struct hwmon_attr *ixgbe_attr; | ||||
| 
 | ||||
| 	n_attr = adapter->ixgbe_hwmon_buff->n_hwmon; | ||||
| 	ixgbe_attr = &adapter->ixgbe_hwmon_buff->hwmon_list[n_attr]; | ||||
| 
 | ||||
| 	switch (type) { | ||||
| 	case IXGBE_HWMON_TYPE_LOC: | ||||
| 		ixgbe_attr->dev_attr.show = ixgbe_hwmon_show_location; | ||||
| 		snprintf(ixgbe_attr->name, sizeof(ixgbe_attr->name), | ||||
| 			 "temp%u_label", offset + 1); | ||||
| 		break; | ||||
| 	case IXGBE_HWMON_TYPE_TEMP: | ||||
| 		ixgbe_attr->dev_attr.show = ixgbe_hwmon_show_temp; | ||||
| 		snprintf(ixgbe_attr->name, sizeof(ixgbe_attr->name), | ||||
| 			 "temp%u_input", offset + 1); | ||||
| 		break; | ||||
| 	case IXGBE_HWMON_TYPE_CAUTION: | ||||
| 		ixgbe_attr->dev_attr.show = ixgbe_hwmon_show_cautionthresh; | ||||
| 		snprintf(ixgbe_attr->name, sizeof(ixgbe_attr->name), | ||||
| 			 "temp%u_max", offset + 1); | ||||
| 		break; | ||||
| 	case IXGBE_HWMON_TYPE_MAX: | ||||
| 		ixgbe_attr->dev_attr.show = ixgbe_hwmon_show_maxopthresh; | ||||
| 		snprintf(ixgbe_attr->name, sizeof(ixgbe_attr->name), | ||||
| 			 "temp%u_crit", offset + 1); | ||||
| 		break; | ||||
| 	default: | ||||
| 		rc = -EPERM; | ||||
| 		return rc; | ||||
| 	} | ||||
| 
 | ||||
| 	/* These always the same regardless of type */ | ||||
| 	ixgbe_attr->sensor = | ||||
| 		&adapter->hw.mac.thermal_sensor_data.sensor[offset]; | ||||
| 	ixgbe_attr->hw = &adapter->hw; | ||||
| 	ixgbe_attr->dev_attr.store = NULL; | ||||
| 	ixgbe_attr->dev_attr.attr.mode = S_IRUGO; | ||||
| 	ixgbe_attr->dev_attr.attr.name = ixgbe_attr->name; | ||||
| 	sysfs_attr_init(&ixgbe_attr->dev_attr.attr); | ||||
| 
 | ||||
| 	adapter->ixgbe_hwmon_buff->attrs[n_attr] = &ixgbe_attr->dev_attr.attr; | ||||
| 
 | ||||
| 	++adapter->ixgbe_hwmon_buff->n_hwmon; | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| static void ixgbe_sysfs_del_adapter(struct ixgbe_adapter *adapter) | ||||
| { | ||||
| } | ||||
| 
 | ||||
| /* called from ixgbe_main.c */ | ||||
| void ixgbe_sysfs_exit(struct ixgbe_adapter *adapter) | ||||
| { | ||||
| 	ixgbe_sysfs_del_adapter(adapter); | ||||
| } | ||||
| 
 | ||||
| /* called from ixgbe_main.c */ | ||||
| int ixgbe_sysfs_init(struct ixgbe_adapter *adapter) | ||||
| { | ||||
| 	struct hwmon_buff *ixgbe_hwmon; | ||||
| 	struct device *hwmon_dev; | ||||
| 	unsigned int i; | ||||
| 	int rc = 0; | ||||
| 
 | ||||
| 	/* If this method isn't defined we don't support thermals */ | ||||
| 	if (adapter->hw.mac.ops.init_thermal_sensor_thresh == NULL) { | ||||
| 		goto exit; | ||||
| 	} | ||||
| 
 | ||||
| 	/* Don't create thermal hwmon interface if no sensors present */ | ||||
| 	if (adapter->hw.mac.ops.init_thermal_sensor_thresh(&adapter->hw)) | ||||
| 		goto exit; | ||||
| 
 | ||||
| 	ixgbe_hwmon = devm_kzalloc(&adapter->pdev->dev, sizeof(*ixgbe_hwmon), | ||||
| 				   GFP_KERNEL); | ||||
| 	if (ixgbe_hwmon == NULL) { | ||||
| 		rc = -ENOMEM; | ||||
| 		goto exit; | ||||
| 	} | ||||
| 	adapter->ixgbe_hwmon_buff = ixgbe_hwmon; | ||||
| 
 | ||||
| 	for (i = 0; i < IXGBE_MAX_SENSORS; i++) { | ||||
| 		/*
 | ||||
| 		 * Only create hwmon sysfs entries for sensors that have | ||||
| 		 * meaningful data for. | ||||
| 		 */ | ||||
| 		if (adapter->hw.mac.thermal_sensor_data.sensor[i].location == 0) | ||||
| 			continue; | ||||
| 
 | ||||
| 		/* Bail if any hwmon attr struct fails to initialize */ | ||||
| 		rc = ixgbe_add_hwmon_attr(adapter, i, IXGBE_HWMON_TYPE_CAUTION); | ||||
| 		if (rc) | ||||
| 			goto exit; | ||||
| 		rc = ixgbe_add_hwmon_attr(adapter, i, IXGBE_HWMON_TYPE_LOC); | ||||
| 		if (rc) | ||||
| 			goto exit; | ||||
| 		rc = ixgbe_add_hwmon_attr(adapter, i, IXGBE_HWMON_TYPE_TEMP); | ||||
| 		if (rc) | ||||
| 			goto exit; | ||||
| 		rc = ixgbe_add_hwmon_attr(adapter, i, IXGBE_HWMON_TYPE_MAX); | ||||
| 		if (rc) | ||||
| 			goto exit; | ||||
| 	} | ||||
| 
 | ||||
| 	ixgbe_hwmon->groups[0] = &ixgbe_hwmon->group; | ||||
| 	ixgbe_hwmon->group.attrs = ixgbe_hwmon->attrs; | ||||
| 
 | ||||
| 	hwmon_dev = devm_hwmon_device_register_with_groups(&adapter->pdev->dev, | ||||
| 							   "ixgbe", | ||||
| 							   ixgbe_hwmon, | ||||
| 							   ixgbe_hwmon->groups); | ||||
| 	if (IS_ERR(hwmon_dev)) | ||||
| 		rc = PTR_ERR(hwmon_dev); | ||||
| exit: | ||||
| 	return rc; | ||||
| } | ||||
| 
 | ||||
							
								
								
									
										3089
									
								
								drivers/net/ethernet/intel/ixgbe/ixgbe_type.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										3089
									
								
								drivers/net/ethernet/intel/ixgbe/ixgbe_type.h
									
										
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							
							
								
								
									
										845
									
								
								drivers/net/ethernet/intel/ixgbe/ixgbe_x540.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										845
									
								
								drivers/net/ethernet/intel/ixgbe/ixgbe_x540.c
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,845 @@ | |||
| /*******************************************************************************
 | ||||
| 
 | ||||
|   Intel 10 Gigabit PCI Express Linux driver | ||||
|   Copyright(c) 1999 - 2014 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: | ||||
|   Linux NICS <linux.nics@intel.com> | ||||
|   e1000-devel Mailing List <e1000-devel@lists.sourceforge.net> | ||||
|   Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 | ||||
| 
 | ||||
| *******************************************************************************/ | ||||
| 
 | ||||
| #include <linux/pci.h> | ||||
| #include <linux/delay.h> | ||||
| #include <linux/sched.h> | ||||
| 
 | ||||
| #include "ixgbe.h" | ||||
| #include "ixgbe_phy.h" | ||||
| 
 | ||||
| #define IXGBE_X540_MAX_TX_QUEUES	128 | ||||
| #define IXGBE_X540_MAX_RX_QUEUES	128 | ||||
| #define IXGBE_X540_RAR_ENTRIES		128 | ||||
| #define IXGBE_X540_MC_TBL_SIZE		128 | ||||
| #define IXGBE_X540_VFT_TBL_SIZE		128 | ||||
| #define IXGBE_X540_RX_PB_SIZE		384 | ||||
| 
 | ||||
| static s32 ixgbe_update_flash_X540(struct ixgbe_hw *hw); | ||||
| static s32 ixgbe_poll_flash_update_done_X540(struct ixgbe_hw *hw); | ||||
| static s32 ixgbe_acquire_swfw_sync_X540(struct ixgbe_hw *hw, u16 mask); | ||||
| static void ixgbe_release_swfw_sync_X540(struct ixgbe_hw *hw, u16 mask); | ||||
| static s32 ixgbe_get_swfw_sync_semaphore(struct ixgbe_hw *hw); | ||||
| static void ixgbe_release_swfw_sync_semaphore(struct ixgbe_hw *hw); | ||||
| 
 | ||||
| static enum ixgbe_media_type ixgbe_get_media_type_X540(struct ixgbe_hw *hw) | ||||
| { | ||||
| 	return ixgbe_media_type_copper; | ||||
| } | ||||
| 
 | ||||
| static s32 ixgbe_get_invariants_X540(struct ixgbe_hw *hw) | ||||
| { | ||||
| 	struct ixgbe_mac_info *mac = &hw->mac; | ||||
| 
 | ||||
| 	/* Call PHY identify routine to get the phy type */ | ||||
| 	ixgbe_identify_phy_generic(hw); | ||||
| 
 | ||||
| 	mac->mcft_size = IXGBE_X540_MC_TBL_SIZE; | ||||
| 	mac->vft_size = IXGBE_X540_VFT_TBL_SIZE; | ||||
| 	mac->num_rar_entries = IXGBE_X540_RAR_ENTRIES; | ||||
| 	mac->rx_pb_size = IXGBE_X540_RX_PB_SIZE; | ||||
| 	mac->max_rx_queues = IXGBE_X540_MAX_RX_QUEUES; | ||||
| 	mac->max_tx_queues = IXGBE_X540_MAX_TX_QUEUES; | ||||
| 	mac->max_msix_vectors = ixgbe_get_pcie_msix_count_generic(hw); | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  *  ixgbe_setup_mac_link_X540 - Set the auto advertised capabilitires | ||||
|  *  @hw: pointer to hardware structure | ||||
|  *  @speed: new link speed | ||||
|  *  @autoneg_wait_to_complete: true when waiting for completion is needed | ||||
|  **/ | ||||
| static s32 ixgbe_setup_mac_link_X540(struct ixgbe_hw *hw, | ||||
| 				     ixgbe_link_speed speed, | ||||
| 				     bool autoneg_wait_to_complete) | ||||
| { | ||||
| 	return hw->phy.ops.setup_link_speed(hw, speed, | ||||
| 					    autoneg_wait_to_complete); | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  *  ixgbe_reset_hw_X540 - Perform hardware reset | ||||
|  *  @hw: pointer to hardware structure | ||||
|  * | ||||
|  *  Resets the hardware by resetting the transmit and receive units, masks | ||||
|  *  and clears all interrupts, perform a PHY reset, and perform a link (MAC) | ||||
|  *  reset. | ||||
|  **/ | ||||
| static s32 ixgbe_reset_hw_X540(struct ixgbe_hw *hw) | ||||
| { | ||||
| 	s32 status; | ||||
| 	u32 ctrl, i; | ||||
| 
 | ||||
| 	/* Call adapter stop to disable tx/rx and clear interrupts */ | ||||
| 	status = hw->mac.ops.stop_adapter(hw); | ||||
| 	if (status) | ||||
| 		return status; | ||||
| 
 | ||||
| 	/* flush pending Tx transactions */ | ||||
| 	ixgbe_clear_tx_pending(hw); | ||||
| 
 | ||||
| mac_reset_top: | ||||
| 	ctrl = IXGBE_CTRL_RST; | ||||
| 	ctrl |= IXGBE_READ_REG(hw, IXGBE_CTRL); | ||||
| 	IXGBE_WRITE_REG(hw, IXGBE_CTRL, ctrl); | ||||
| 	IXGBE_WRITE_FLUSH(hw); | ||||
| 
 | ||||
| 	/* Poll for reset bit to self-clear indicating reset is complete */ | ||||
| 	for (i = 0; i < 10; i++) { | ||||
| 		udelay(1); | ||||
| 		ctrl = IXGBE_READ_REG(hw, IXGBE_CTRL); | ||||
| 		if (!(ctrl & IXGBE_CTRL_RST_MASK)) | ||||
| 			break; | ||||
| 	} | ||||
| 
 | ||||
| 	if (ctrl & IXGBE_CTRL_RST_MASK) { | ||||
| 		status = IXGBE_ERR_RESET_FAILED; | ||||
| 		hw_dbg(hw, "Reset polling failed to complete.\n"); | ||||
| 	} | ||||
| 	msleep(100); | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * Double resets are required for recovery from certain error | ||||
| 	 * conditions.  Between resets, it is necessary to stall to allow time | ||||
| 	 * for any pending HW events to complete. | ||||
| 	 */ | ||||
| 	if (hw->mac.flags & IXGBE_FLAGS_DOUBLE_RESET_REQUIRED) { | ||||
| 		hw->mac.flags &= ~IXGBE_FLAGS_DOUBLE_RESET_REQUIRED; | ||||
| 		goto mac_reset_top; | ||||
| 	} | ||||
| 
 | ||||
| 	/* Set the Rx packet buffer size. */ | ||||
| 	IXGBE_WRITE_REG(hw, IXGBE_RXPBSIZE(0), 384 << IXGBE_RXPBSIZE_SHIFT); | ||||
| 
 | ||||
| 	/* Store the permanent mac address */ | ||||
| 	hw->mac.ops.get_mac_addr(hw, hw->mac.perm_addr); | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * Store MAC address from RAR0, clear receive address registers, and | ||||
| 	 * clear the multicast table.  Also reset num_rar_entries to 128, | ||||
| 	 * since we modify this value when programming the SAN MAC address. | ||||
| 	 */ | ||||
| 	hw->mac.num_rar_entries = IXGBE_X540_MAX_TX_QUEUES; | ||||
| 	hw->mac.ops.init_rx_addrs(hw); | ||||
| 
 | ||||
| 	/* Store the permanent SAN mac address */ | ||||
| 	hw->mac.ops.get_san_mac_addr(hw, hw->mac.san_addr); | ||||
| 
 | ||||
| 	/* Add the SAN MAC address to the RAR only if it's a valid address */ | ||||
| 	if (is_valid_ether_addr(hw->mac.san_addr)) { | ||||
| 		hw->mac.ops.set_rar(hw, hw->mac.num_rar_entries - 1, | ||||
| 				    hw->mac.san_addr, 0, IXGBE_RAH_AV); | ||||
| 
 | ||||
| 		/* Save the SAN MAC RAR index */ | ||||
| 		hw->mac.san_mac_rar_index = hw->mac.num_rar_entries - 1; | ||||
| 
 | ||||
| 		/* Reserve the last RAR for the SAN MAC address */ | ||||
| 		hw->mac.num_rar_entries--; | ||||
| 	} | ||||
| 
 | ||||
| 	/* Store the alternative WWNN/WWPN prefix */ | ||||
| 	hw->mac.ops.get_wwn_prefix(hw, &hw->mac.wwnn_prefix, | ||||
| 				   &hw->mac.wwpn_prefix); | ||||
| 
 | ||||
| 	return status; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  *  ixgbe_start_hw_X540 - Prepare hardware for Tx/Rx | ||||
|  *  @hw: pointer to hardware structure | ||||
|  * | ||||
|  *  Starts the hardware using the generic start_hw function | ||||
|  *  and the generation start_hw function. | ||||
|  *  Then performs revision-specific operations, if any. | ||||
|  **/ | ||||
| static s32 ixgbe_start_hw_X540(struct ixgbe_hw *hw) | ||||
| { | ||||
| 	s32 ret_val; | ||||
| 
 | ||||
| 	ret_val = ixgbe_start_hw_generic(hw); | ||||
| 	if (ret_val) | ||||
| 		return ret_val; | ||||
| 
 | ||||
| 	return ixgbe_start_hw_gen2(hw); | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  *  ixgbe_init_eeprom_params_X540 - Initialize EEPROM params | ||||
|  *  @hw: pointer to hardware structure | ||||
|  * | ||||
|  *  Initializes the EEPROM parameters ixgbe_eeprom_info within the | ||||
|  *  ixgbe_hw struct in order to set up EEPROM access. | ||||
|  **/ | ||||
| static s32 ixgbe_init_eeprom_params_X540(struct ixgbe_hw *hw) | ||||
| { | ||||
| 	struct ixgbe_eeprom_info *eeprom = &hw->eeprom; | ||||
| 	u32 eec; | ||||
| 	u16 eeprom_size; | ||||
| 
 | ||||
| 	if (eeprom->type == ixgbe_eeprom_uninitialized) { | ||||
| 		eeprom->semaphore_delay = 10; | ||||
| 		eeprom->type = ixgbe_flash; | ||||
| 
 | ||||
| 		eec = IXGBE_READ_REG(hw, IXGBE_EEC); | ||||
| 		eeprom_size = (u16)((eec & IXGBE_EEC_SIZE) >> | ||||
| 				    IXGBE_EEC_SIZE_SHIFT); | ||||
| 		eeprom->word_size = 1 << (eeprom_size + | ||||
| 					  IXGBE_EEPROM_WORD_SIZE_SHIFT); | ||||
| 
 | ||||
| 		hw_dbg(hw, "Eeprom params: type = %d, size = %d\n", | ||||
| 		       eeprom->type, eeprom->word_size); | ||||
| 	} | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  *  ixgbe_read_eerd_X540- Read EEPROM word using EERD | ||||
|  *  @hw: pointer to hardware structure | ||||
|  *  @offset: offset of  word in the EEPROM to read | ||||
|  *  @data: word read from the EEPROM | ||||
|  * | ||||
|  *  Reads a 16 bit word from the EEPROM using the EERD register. | ||||
|  **/ | ||||
| static s32 ixgbe_read_eerd_X540(struct ixgbe_hw *hw, u16 offset, u16 *data) | ||||
| { | ||||
| 	s32 status; | ||||
| 
 | ||||
| 	if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM)) | ||||
| 		return IXGBE_ERR_SWFW_SYNC; | ||||
| 
 | ||||
| 	status = ixgbe_read_eerd_generic(hw, offset, data); | ||||
| 
 | ||||
| 	hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM); | ||||
| 	return status; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  *  ixgbe_read_eerd_buffer_X540 - Read EEPROM word(s) using EERD | ||||
|  *  @hw: pointer to hardware structure | ||||
|  *  @offset: offset of  word in the EEPROM to read | ||||
|  *  @words: number of words | ||||
|  *  @data: word(s) read from the EEPROM | ||||
|  * | ||||
|  *  Reads a 16 bit word(s) from the EEPROM using the EERD register. | ||||
|  **/ | ||||
| static s32 ixgbe_read_eerd_buffer_X540(struct ixgbe_hw *hw, | ||||
| 				       u16 offset, u16 words, u16 *data) | ||||
| { | ||||
| 	s32 status; | ||||
| 
 | ||||
| 	if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM)) | ||||
| 		return IXGBE_ERR_SWFW_SYNC; | ||||
| 
 | ||||
| 	status = ixgbe_read_eerd_buffer_generic(hw, offset, words, data); | ||||
| 
 | ||||
| 	hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM); | ||||
| 	return status; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  *  ixgbe_write_eewr_X540 - Write EEPROM word using EEWR | ||||
|  *  @hw: pointer to hardware structure | ||||
|  *  @offset: offset of  word in the EEPROM to write | ||||
|  *  @data: word write to the EEPROM | ||||
|  * | ||||
|  *  Write a 16 bit word to the EEPROM using the EEWR register. | ||||
|  **/ | ||||
| static s32 ixgbe_write_eewr_X540(struct ixgbe_hw *hw, u16 offset, u16 data) | ||||
| { | ||||
| 	s32 status; | ||||
| 
 | ||||
| 	if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM)) | ||||
| 		return IXGBE_ERR_SWFW_SYNC; | ||||
| 
 | ||||
| 	status = ixgbe_write_eewr_generic(hw, offset, data); | ||||
| 
 | ||||
| 	hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM); | ||||
| 	return status; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  *  ixgbe_write_eewr_buffer_X540 - Write EEPROM word(s) using EEWR | ||||
|  *  @hw: pointer to hardware structure | ||||
|  *  @offset: offset of  word in the EEPROM to write | ||||
|  *  @words: number of words | ||||
|  *  @data: word(s) write to the EEPROM | ||||
|  * | ||||
|  *  Write a 16 bit word(s) to the EEPROM using the EEWR register. | ||||
|  **/ | ||||
| static s32 ixgbe_write_eewr_buffer_X540(struct ixgbe_hw *hw, | ||||
| 					u16 offset, u16 words, u16 *data) | ||||
| { | ||||
| 	s32 status; | ||||
| 
 | ||||
| 	if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM)) | ||||
| 		return IXGBE_ERR_SWFW_SYNC; | ||||
| 
 | ||||
| 	status = ixgbe_write_eewr_buffer_generic(hw, offset, words, data); | ||||
| 
 | ||||
| 	hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM); | ||||
| 	return status; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  *  ixgbe_calc_eeprom_checksum_X540 - Calculates and returns the checksum | ||||
|  * | ||||
|  *  This function does not use synchronization for EERD and EEWR. It can | ||||
|  *  be used internally by function which utilize ixgbe_acquire_swfw_sync_X540. | ||||
|  * | ||||
|  *  @hw: pointer to hardware structure | ||||
|  **/ | ||||
| static u16 ixgbe_calc_eeprom_checksum_X540(struct ixgbe_hw *hw) | ||||
| { | ||||
| 	u16 i; | ||||
| 	u16 j; | ||||
| 	u16 checksum = 0; | ||||
| 	u16 length = 0; | ||||
| 	u16 pointer = 0; | ||||
| 	u16 word = 0; | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * Do not use hw->eeprom.ops.read because we do not want to take | ||||
| 	 * the synchronization semaphores here. Instead use | ||||
| 	 * ixgbe_read_eerd_generic | ||||
| 	 */ | ||||
| 
 | ||||
| 	/* Include 0x0-0x3F in the checksum */ | ||||
| 	for (i = 0; i < IXGBE_EEPROM_CHECKSUM; i++) { | ||||
| 		if (ixgbe_read_eerd_generic(hw, i, &word) != 0) { | ||||
| 			hw_dbg(hw, "EEPROM read failed\n"); | ||||
| 			break; | ||||
| 		} | ||||
| 		checksum += word; | ||||
| 	} | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * Include all data from pointers 0x3, 0x6-0xE.  This excludes the | ||||
| 	 * FW, PHY module, and PCIe Expansion/Option ROM pointers. | ||||
| 	 */ | ||||
| 	for (i = IXGBE_PCIE_ANALOG_PTR; i < IXGBE_FW_PTR; i++) { | ||||
| 		if (i == IXGBE_PHY_PTR || i == IXGBE_OPTION_ROM_PTR) | ||||
| 			continue; | ||||
| 
 | ||||
| 		if (ixgbe_read_eerd_generic(hw, i, &pointer) != 0) { | ||||
| 			hw_dbg(hw, "EEPROM read failed\n"); | ||||
| 			break; | ||||
| 		} | ||||
| 
 | ||||
| 		/* Skip pointer section if the pointer is invalid. */ | ||||
| 		if (pointer == 0xFFFF || pointer == 0 || | ||||
| 		    pointer >= hw->eeprom.word_size) | ||||
| 			continue; | ||||
| 
 | ||||
| 		if (ixgbe_read_eerd_generic(hw, pointer, &length) != 0) { | ||||
| 			hw_dbg(hw, "EEPROM read failed\n"); | ||||
| 			break; | ||||
| 		} | ||||
| 
 | ||||
| 		/* Skip pointer section if length is invalid. */ | ||||
| 		if (length == 0xFFFF || length == 0 || | ||||
| 		    (pointer + length) >= hw->eeprom.word_size) | ||||
| 			continue; | ||||
| 
 | ||||
| 		for (j = pointer+1; j <= pointer+length; j++) { | ||||
| 			if (ixgbe_read_eerd_generic(hw, j, &word) != 0) { | ||||
| 				hw_dbg(hw, "EEPROM read failed\n"); | ||||
| 				break; | ||||
| 			} | ||||
| 			checksum += word; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	checksum = (u16)IXGBE_EEPROM_SUM - checksum; | ||||
| 
 | ||||
| 	return checksum; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  *  ixgbe_validate_eeprom_checksum_X540 - Validate EEPROM checksum | ||||
|  *  @hw: pointer to hardware structure | ||||
|  *  @checksum_val: calculated checksum | ||||
|  * | ||||
|  *  Performs checksum calculation and validates the EEPROM checksum.  If the | ||||
|  *  caller does not need checksum_val, the value can be NULL. | ||||
|  **/ | ||||
| static s32 ixgbe_validate_eeprom_checksum_X540(struct ixgbe_hw *hw, | ||||
| 					       u16 *checksum_val) | ||||
| { | ||||
| 	s32 status; | ||||
| 	u16 checksum; | ||||
| 	u16 read_checksum = 0; | ||||
| 
 | ||||
| 	/* Read the first word from the EEPROM. If this times out or fails, do
 | ||||
| 	 * not continue or we could be in for a very long wait while every | ||||
| 	 * EEPROM read fails | ||||
| 	 */ | ||||
| 	status = hw->eeprom.ops.read(hw, 0, &checksum); | ||||
| 	if (status) { | ||||
| 		hw_dbg(hw, "EEPROM read failed\n"); | ||||
| 		return status; | ||||
| 	} | ||||
| 
 | ||||
| 	if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM)) | ||||
| 		return IXGBE_ERR_SWFW_SYNC; | ||||
| 
 | ||||
| 	checksum = hw->eeprom.ops.calc_checksum(hw); | ||||
| 
 | ||||
| 	/* Do not use hw->eeprom.ops.read because we do not want to take
 | ||||
| 	 * the synchronization semaphores twice here. | ||||
| 	 */ | ||||
| 	status = ixgbe_read_eerd_generic(hw, IXGBE_EEPROM_CHECKSUM, | ||||
| 					 &read_checksum); | ||||
| 
 | ||||
| 	hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM); | ||||
| 
 | ||||
| 	/* If the user cares, return the calculated checksum */ | ||||
| 	if (checksum_val) | ||||
| 		*checksum_val = checksum; | ||||
| 
 | ||||
| 	/* Verify read and calculated checksums are the same */ | ||||
| 	if (read_checksum != checksum) | ||||
| 		return IXGBE_ERR_EEPROM_CHECKSUM; | ||||
| 
 | ||||
| 	return status; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  * ixgbe_update_eeprom_checksum_X540 - Updates the EEPROM checksum and flash | ||||
|  * @hw: pointer to hardware structure | ||||
|  * | ||||
|  * After writing EEPROM to shadow RAM using EEWR register, software calculates | ||||
|  * checksum and updates the EEPROM and instructs the hardware to update | ||||
|  * the flash. | ||||
|  **/ | ||||
| static s32 ixgbe_update_eeprom_checksum_X540(struct ixgbe_hw *hw) | ||||
| { | ||||
| 	s32 status; | ||||
| 	u16 checksum; | ||||
| 
 | ||||
| 	/* Read the first word from the EEPROM. If this times out or fails, do
 | ||||
| 	 * not continue or we could be in for a very long wait while every | ||||
| 	 * EEPROM read fails | ||||
| 	 */ | ||||
| 	status = hw->eeprom.ops.read(hw, 0, &checksum); | ||||
| 	if (status) { | ||||
| 		hw_dbg(hw, "EEPROM read failed\n"); | ||||
| 		return status; | ||||
| 	} | ||||
| 
 | ||||
| 	if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM)) | ||||
| 		return  IXGBE_ERR_SWFW_SYNC; | ||||
| 
 | ||||
| 	checksum = hw->eeprom.ops.calc_checksum(hw); | ||||
| 
 | ||||
| 	/* Do not use hw->eeprom.ops.write because we do not want to
 | ||||
| 	 * take the synchronization semaphores twice here. | ||||
| 	 */ | ||||
| 	status = ixgbe_write_eewr_generic(hw, IXGBE_EEPROM_CHECKSUM, checksum); | ||||
| 	if (!status) | ||||
| 		status = ixgbe_update_flash_X540(hw); | ||||
| 
 | ||||
| 	hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM); | ||||
| 	return status; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  * ixgbe_update_flash_X540 - Instruct HW to copy EEPROM to Flash device | ||||
|  * @hw: pointer to hardware structure | ||||
|  * | ||||
|  * Set FLUP (bit 23) of the EEC register to instruct Hardware to copy | ||||
|  * EEPROM from shadow RAM to the flash device. | ||||
|  **/ | ||||
| static s32 ixgbe_update_flash_X540(struct ixgbe_hw *hw) | ||||
| { | ||||
| 	u32 flup; | ||||
| 	s32 status; | ||||
| 
 | ||||
| 	status = ixgbe_poll_flash_update_done_X540(hw); | ||||
| 	if (status == IXGBE_ERR_EEPROM) { | ||||
| 		hw_dbg(hw, "Flash update time out\n"); | ||||
| 		return status; | ||||
| 	} | ||||
| 
 | ||||
| 	flup = IXGBE_READ_REG(hw, IXGBE_EEC) | IXGBE_EEC_FLUP; | ||||
| 	IXGBE_WRITE_REG(hw, IXGBE_EEC, flup); | ||||
| 
 | ||||
| 	status = ixgbe_poll_flash_update_done_X540(hw); | ||||
| 	if (status == 0) | ||||
| 		hw_dbg(hw, "Flash update complete\n"); | ||||
| 	else | ||||
| 		hw_dbg(hw, "Flash update time out\n"); | ||||
| 
 | ||||
| 	if (hw->revision_id == 0) { | ||||
| 		flup = IXGBE_READ_REG(hw, IXGBE_EEC); | ||||
| 
 | ||||
| 		if (flup & IXGBE_EEC_SEC1VAL) { | ||||
| 			flup |= IXGBE_EEC_FLUP; | ||||
| 			IXGBE_WRITE_REG(hw, IXGBE_EEC, flup); | ||||
| 		} | ||||
| 
 | ||||
| 		status = ixgbe_poll_flash_update_done_X540(hw); | ||||
| 		if (status == 0) | ||||
| 			hw_dbg(hw, "Flash update complete\n"); | ||||
| 		else | ||||
| 			hw_dbg(hw, "Flash update time out\n"); | ||||
| 	} | ||||
| 
 | ||||
| 	return status; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  * ixgbe_poll_flash_update_done_X540 - Poll flash update status | ||||
|  * @hw: pointer to hardware structure | ||||
|  * | ||||
|  * Polls the FLUDONE (bit 26) of the EEC Register to determine when the | ||||
|  * flash update is done. | ||||
|  **/ | ||||
| static s32 ixgbe_poll_flash_update_done_X540(struct ixgbe_hw *hw) | ||||
| { | ||||
| 	u32 i; | ||||
| 	u32 reg; | ||||
| 
 | ||||
| 	for (i = 0; i < IXGBE_FLUDONE_ATTEMPTS; i++) { | ||||
| 		reg = IXGBE_READ_REG(hw, IXGBE_EEC); | ||||
| 		if (reg & IXGBE_EEC_FLUDONE) | ||||
| 			return 0; | ||||
| 		udelay(5); | ||||
| 	} | ||||
| 	return IXGBE_ERR_EEPROM; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  * ixgbe_acquire_swfw_sync_X540 - Acquire SWFW semaphore | ||||
|  * @hw: pointer to hardware structure | ||||
|  * @mask: Mask to specify which semaphore to acquire | ||||
|  * | ||||
|  * Acquires the SWFW semaphore thought the SW_FW_SYNC register for | ||||
|  * the specified function (CSR, PHY0, PHY1, NVM, Flash) | ||||
|  **/ | ||||
| static s32 ixgbe_acquire_swfw_sync_X540(struct ixgbe_hw *hw, u16 mask) | ||||
| { | ||||
| 	u32 swfw_sync; | ||||
| 	u32 swmask = mask; | ||||
| 	u32 fwmask = mask << 5; | ||||
| 	u32 hwmask = 0; | ||||
| 	u32 timeout = 200; | ||||
| 	u32 i; | ||||
| 
 | ||||
| 	if (swmask == IXGBE_GSSR_EEP_SM) | ||||
| 		hwmask = IXGBE_GSSR_FLASH_SM; | ||||
| 
 | ||||
| 	for (i = 0; i < timeout; i++) { | ||||
| 		/*
 | ||||
| 		 * SW NVM semaphore bit is used for access to all | ||||
| 		 * SW_FW_SYNC bits (not just NVM) | ||||
| 		 */ | ||||
| 		if (ixgbe_get_swfw_sync_semaphore(hw)) | ||||
| 			return IXGBE_ERR_SWFW_SYNC; | ||||
| 
 | ||||
| 		swfw_sync = IXGBE_READ_REG(hw, IXGBE_SWFW_SYNC); | ||||
| 		if (!(swfw_sync & (fwmask | swmask | hwmask))) { | ||||
| 			swfw_sync |= swmask; | ||||
| 			IXGBE_WRITE_REG(hw, IXGBE_SWFW_SYNC, swfw_sync); | ||||
| 			ixgbe_release_swfw_sync_semaphore(hw); | ||||
| 			break; | ||||
| 		} else { | ||||
| 			/*
 | ||||
| 			 * Firmware currently using resource (fwmask), | ||||
| 			 * hardware currently using resource (hwmask), | ||||
| 			 * or other software thread currently using | ||||
| 			 * resource (swmask) | ||||
| 			 */ | ||||
| 			ixgbe_release_swfw_sync_semaphore(hw); | ||||
| 			usleep_range(5000, 10000); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * If the resource is not released by the FW/HW the SW can assume that | ||||
| 	 * the FW/HW malfunctions. In that case the SW should sets the | ||||
| 	 * SW bit(s) of the requested resource(s) while ignoring the | ||||
| 	 * corresponding FW/HW bits in the SW_FW_SYNC register. | ||||
| 	 */ | ||||
| 	if (i >= timeout) { | ||||
| 		swfw_sync = IXGBE_READ_REG(hw, IXGBE_SWFW_SYNC); | ||||
| 		if (swfw_sync & (fwmask | hwmask)) { | ||||
| 			if (ixgbe_get_swfw_sync_semaphore(hw)) | ||||
| 				return IXGBE_ERR_SWFW_SYNC; | ||||
| 
 | ||||
| 			swfw_sync |= swmask; | ||||
| 			IXGBE_WRITE_REG(hw, IXGBE_SWFW_SYNC, swfw_sync); | ||||
| 			ixgbe_release_swfw_sync_semaphore(hw); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	usleep_range(5000, 10000); | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  * ixgbe_release_swfw_sync_X540 - Release SWFW semaphore | ||||
|  * @hw: pointer to hardware structure | ||||
|  * @mask: Mask to specify which semaphore to release | ||||
|  * | ||||
|  * Releases the SWFW semaphore through the SW_FW_SYNC register | ||||
|  * for the specified function (CSR, PHY0, PHY1, EVM, Flash) | ||||
|  **/ | ||||
| static void ixgbe_release_swfw_sync_X540(struct ixgbe_hw *hw, u16 mask) | ||||
| { | ||||
| 	u32 swfw_sync; | ||||
| 	u32 swmask = mask; | ||||
| 
 | ||||
| 	ixgbe_get_swfw_sync_semaphore(hw); | ||||
| 
 | ||||
| 	swfw_sync = IXGBE_READ_REG(hw, IXGBE_SWFW_SYNC); | ||||
| 	swfw_sync &= ~swmask; | ||||
| 	IXGBE_WRITE_REG(hw, IXGBE_SWFW_SYNC, swfw_sync); | ||||
| 
 | ||||
| 	ixgbe_release_swfw_sync_semaphore(hw); | ||||
| 	usleep_range(5000, 10000); | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  * ixgbe_get_swfw_sync_semaphore - Get hardware semaphore | ||||
|  * @hw: pointer to hardware structure | ||||
|  * | ||||
|  * Sets the hardware semaphores so SW/FW can gain control of shared resources | ||||
|  */ | ||||
| static s32 ixgbe_get_swfw_sync_semaphore(struct ixgbe_hw *hw) | ||||
| { | ||||
| 	u32 timeout = 2000; | ||||
| 	u32 i; | ||||
| 	u32 swsm; | ||||
| 
 | ||||
| 	/* Get SMBI software semaphore between device drivers first */ | ||||
| 	for (i = 0; i < timeout; i++) { | ||||
| 		/* If the SMBI bit is 0 when we read it, then the bit will be
 | ||||
| 		 * set and we have the semaphore | ||||
| 		 */ | ||||
| 		swsm = IXGBE_READ_REG(hw, IXGBE_SWSM); | ||||
| 		if (!(swsm & IXGBE_SWSM_SMBI)) | ||||
| 			break; | ||||
| 		usleep_range(50, 100); | ||||
| 	} | ||||
| 
 | ||||
| 	if (i == timeout) { | ||||
| 		hw_dbg(hw, | ||||
| 		       "Software semaphore SMBI between device drivers not granted.\n"); | ||||
| 		return IXGBE_ERR_EEPROM; | ||||
| 	} | ||||
| 
 | ||||
| 	/* Now get the semaphore between SW/FW through the REGSMP bit */ | ||||
| 	for (i = 0; i < timeout; i++) { | ||||
| 		swsm = IXGBE_READ_REG(hw, IXGBE_SWFW_SYNC); | ||||
| 		if (!(swsm & IXGBE_SWFW_REGSMP)) | ||||
| 			return 0; | ||||
| 
 | ||||
| 		usleep_range(50, 100); | ||||
| 	} | ||||
| 
 | ||||
| 	return IXGBE_ERR_EEPROM; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  * ixgbe_release_nvm_semaphore - Release hardware semaphore | ||||
|  * @hw: pointer to hardware structure | ||||
|  * | ||||
|  * This function clears hardware semaphore bits. | ||||
|  **/ | ||||
| static void ixgbe_release_swfw_sync_semaphore(struct ixgbe_hw *hw) | ||||
| { | ||||
| 	 u32 swsm; | ||||
| 
 | ||||
| 	/* Release both semaphores by writing 0 to the bits REGSMP and SMBI */ | ||||
| 
 | ||||
| 	swsm = IXGBE_READ_REG(hw, IXGBE_SWSM); | ||||
| 	swsm &= ~IXGBE_SWSM_SMBI; | ||||
| 	IXGBE_WRITE_REG(hw, IXGBE_SWSM, swsm); | ||||
| 
 | ||||
| 	swsm = IXGBE_READ_REG(hw, IXGBE_SWFW_SYNC); | ||||
| 	swsm &= ~IXGBE_SWFW_REGSMP; | ||||
| 	IXGBE_WRITE_REG(hw, IXGBE_SWFW_SYNC, swsm); | ||||
| 
 | ||||
| 	IXGBE_WRITE_FLUSH(hw); | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  * ixgbe_blink_led_start_X540 - Blink LED based on index. | ||||
|  * @hw: pointer to hardware structure | ||||
|  * @index: led number to blink | ||||
|  * | ||||
|  * Devices that implement the version 2 interface: | ||||
|  *   X540 | ||||
|  **/ | ||||
| static s32 ixgbe_blink_led_start_X540(struct ixgbe_hw *hw, u32 index) | ||||
| { | ||||
| 	u32 macc_reg; | ||||
| 	u32 ledctl_reg; | ||||
| 	ixgbe_link_speed speed; | ||||
| 	bool link_up; | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * Link should be up in order for the blink bit in the LED control | ||||
| 	 * register to work. Force link and speed in the MAC if link is down. | ||||
| 	 * This will be reversed when we stop the blinking. | ||||
| 	 */ | ||||
| 	hw->mac.ops.check_link(hw, &speed, &link_up, false); | ||||
| 	if (!link_up) { | ||||
| 		macc_reg = IXGBE_READ_REG(hw, IXGBE_MACC); | ||||
| 		macc_reg |= IXGBE_MACC_FLU | IXGBE_MACC_FSV_10G | IXGBE_MACC_FS; | ||||
| 		IXGBE_WRITE_REG(hw, IXGBE_MACC, macc_reg); | ||||
| 	} | ||||
| 	/* Set the LED to LINK_UP + BLINK. */ | ||||
| 	ledctl_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL); | ||||
| 	ledctl_reg &= ~IXGBE_LED_MODE_MASK(index); | ||||
| 	ledctl_reg |= IXGBE_LED_BLINK(index); | ||||
| 	IXGBE_WRITE_REG(hw, IXGBE_LEDCTL, ledctl_reg); | ||||
| 	IXGBE_WRITE_FLUSH(hw); | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  * ixgbe_blink_led_stop_X540 - Stop blinking LED based on index. | ||||
|  * @hw: pointer to hardware structure | ||||
|  * @index: led number to stop blinking | ||||
|  * | ||||
|  * Devices that implement the version 2 interface: | ||||
|  *   X540 | ||||
|  **/ | ||||
| static s32 ixgbe_blink_led_stop_X540(struct ixgbe_hw *hw, u32 index) | ||||
| { | ||||
| 	u32 macc_reg; | ||||
| 	u32 ledctl_reg; | ||||
| 
 | ||||
| 	/* Restore the LED to its default value. */ | ||||
| 	ledctl_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL); | ||||
| 	ledctl_reg &= ~IXGBE_LED_MODE_MASK(index); | ||||
| 	ledctl_reg |= IXGBE_LED_LINK_ACTIVE << IXGBE_LED_MODE_SHIFT(index); | ||||
| 	ledctl_reg &= ~IXGBE_LED_BLINK(index); | ||||
| 	IXGBE_WRITE_REG(hw, IXGBE_LEDCTL, ledctl_reg); | ||||
| 
 | ||||
| 	/* Unforce link and speed in the MAC. */ | ||||
| 	macc_reg = IXGBE_READ_REG(hw, IXGBE_MACC); | ||||
| 	macc_reg &= ~(IXGBE_MACC_FLU | IXGBE_MACC_FSV_10G | IXGBE_MACC_FS); | ||||
| 	IXGBE_WRITE_REG(hw, IXGBE_MACC, macc_reg); | ||||
| 	IXGBE_WRITE_FLUSH(hw); | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| static struct ixgbe_mac_operations mac_ops_X540 = { | ||||
| 	.init_hw                = &ixgbe_init_hw_generic, | ||||
| 	.reset_hw               = &ixgbe_reset_hw_X540, | ||||
| 	.start_hw               = &ixgbe_start_hw_X540, | ||||
| 	.clear_hw_cntrs         = &ixgbe_clear_hw_cntrs_generic, | ||||
| 	.get_media_type         = &ixgbe_get_media_type_X540, | ||||
| 	.enable_rx_dma          = &ixgbe_enable_rx_dma_generic, | ||||
| 	.get_mac_addr           = &ixgbe_get_mac_addr_generic, | ||||
| 	.get_san_mac_addr       = &ixgbe_get_san_mac_addr_generic, | ||||
| 	.get_device_caps        = &ixgbe_get_device_caps_generic, | ||||
| 	.get_wwn_prefix         = &ixgbe_get_wwn_prefix_generic, | ||||
| 	.stop_adapter           = &ixgbe_stop_adapter_generic, | ||||
| 	.get_bus_info           = &ixgbe_get_bus_info_generic, | ||||
| 	.set_lan_id             = &ixgbe_set_lan_id_multi_port_pcie, | ||||
| 	.read_analog_reg8       = NULL, | ||||
| 	.write_analog_reg8      = NULL, | ||||
| 	.setup_link             = &ixgbe_setup_mac_link_X540, | ||||
| 	.set_rxpba		= &ixgbe_set_rxpba_generic, | ||||
| 	.check_link             = &ixgbe_check_mac_link_generic, | ||||
| 	.get_link_capabilities  = &ixgbe_get_copper_link_capabilities_generic, | ||||
| 	.led_on                 = &ixgbe_led_on_generic, | ||||
| 	.led_off                = &ixgbe_led_off_generic, | ||||
| 	.blink_led_start        = &ixgbe_blink_led_start_X540, | ||||
| 	.blink_led_stop         = &ixgbe_blink_led_stop_X540, | ||||
| 	.set_rar                = &ixgbe_set_rar_generic, | ||||
| 	.clear_rar              = &ixgbe_clear_rar_generic, | ||||
| 	.set_vmdq               = &ixgbe_set_vmdq_generic, | ||||
| 	.set_vmdq_san_mac	= &ixgbe_set_vmdq_san_mac_generic, | ||||
| 	.clear_vmdq             = &ixgbe_clear_vmdq_generic, | ||||
| 	.init_rx_addrs          = &ixgbe_init_rx_addrs_generic, | ||||
| 	.update_mc_addr_list    = &ixgbe_update_mc_addr_list_generic, | ||||
| 	.enable_mc              = &ixgbe_enable_mc_generic, | ||||
| 	.disable_mc             = &ixgbe_disable_mc_generic, | ||||
| 	.clear_vfta             = &ixgbe_clear_vfta_generic, | ||||
| 	.set_vfta               = &ixgbe_set_vfta_generic, | ||||
| 	.fc_enable              = &ixgbe_fc_enable_generic, | ||||
| 	.set_fw_drv_ver         = &ixgbe_set_fw_drv_ver_generic, | ||||
| 	.init_uta_tables        = &ixgbe_init_uta_tables_generic, | ||||
| 	.setup_sfp              = NULL, | ||||
| 	.set_mac_anti_spoofing  = &ixgbe_set_mac_anti_spoofing, | ||||
| 	.set_vlan_anti_spoofing = &ixgbe_set_vlan_anti_spoofing, | ||||
| 	.acquire_swfw_sync      = &ixgbe_acquire_swfw_sync_X540, | ||||
| 	.release_swfw_sync      = &ixgbe_release_swfw_sync_X540, | ||||
| 	.disable_rx_buff	= &ixgbe_disable_rx_buff_generic, | ||||
| 	.enable_rx_buff		= &ixgbe_enable_rx_buff_generic, | ||||
| 	.get_thermal_sensor_data = NULL, | ||||
| 	.init_thermal_sensor_thresh = NULL, | ||||
| 	.prot_autoc_read	= &prot_autoc_read_generic, | ||||
| 	.prot_autoc_write	= &prot_autoc_write_generic, | ||||
| }; | ||||
| 
 | ||||
| static struct ixgbe_eeprom_operations eeprom_ops_X540 = { | ||||
| 	.init_params            = &ixgbe_init_eeprom_params_X540, | ||||
| 	.read                   = &ixgbe_read_eerd_X540, | ||||
| 	.read_buffer		= &ixgbe_read_eerd_buffer_X540, | ||||
| 	.write                  = &ixgbe_write_eewr_X540, | ||||
| 	.write_buffer		= &ixgbe_write_eewr_buffer_X540, | ||||
| 	.calc_checksum		= &ixgbe_calc_eeprom_checksum_X540, | ||||
| 	.validate_checksum      = &ixgbe_validate_eeprom_checksum_X540, | ||||
| 	.update_checksum        = &ixgbe_update_eeprom_checksum_X540, | ||||
| }; | ||||
| 
 | ||||
| static struct ixgbe_phy_operations phy_ops_X540 = { | ||||
| 	.identify               = &ixgbe_identify_phy_generic, | ||||
| 	.identify_sfp           = &ixgbe_identify_sfp_module_generic, | ||||
| 	.init			= NULL, | ||||
| 	.reset                  = NULL, | ||||
| 	.read_reg               = &ixgbe_read_phy_reg_generic, | ||||
| 	.write_reg              = &ixgbe_write_phy_reg_generic, | ||||
| 	.setup_link             = &ixgbe_setup_phy_link_generic, | ||||
| 	.setup_link_speed       = &ixgbe_setup_phy_link_speed_generic, | ||||
| 	.read_i2c_byte          = &ixgbe_read_i2c_byte_generic, | ||||
| 	.write_i2c_byte         = &ixgbe_write_i2c_byte_generic, | ||||
| 	.read_i2c_sff8472	= &ixgbe_read_i2c_sff8472_generic, | ||||
| 	.read_i2c_eeprom        = &ixgbe_read_i2c_eeprom_generic, | ||||
| 	.write_i2c_eeprom       = &ixgbe_write_i2c_eeprom_generic, | ||||
| 	.check_overtemp         = &ixgbe_tn_check_overtemp, | ||||
| 	.get_firmware_version   = &ixgbe_get_phy_firmware_version_generic, | ||||
| }; | ||||
| 
 | ||||
| struct ixgbe_info ixgbe_X540_info = { | ||||
| 	.mac                    = ixgbe_mac_X540, | ||||
| 	.get_invariants         = &ixgbe_get_invariants_X540, | ||||
| 	.mac_ops                = &mac_ops_X540, | ||||
| 	.eeprom_ops             = &eeprom_ops_X540, | ||||
| 	.phy_ops                = &phy_ops_X540, | ||||
| 	.mbx_ops                = &mbx_ops_generic, | ||||
| }; | ||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 awab228
						awab228