mirror of
				https://github.com/AetherDroid/android_kernel_samsung_on5xelte.git
				synced 2025-10-31 16:18: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
				
			
		
							
								
								
									
										38
									
								
								drivers/net/ethernet/intel/igbvf/Makefile
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								drivers/net/ethernet/intel/igbvf/Makefile
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,38 @@ | |||
| ################################################################################
 | ||||
| #
 | ||||
| # Intel(R) 82576 Virtual Function Linux driver
 | ||||
| # Copyright(c) 2009 - 2012 Intel Corporation.
 | ||||
| #
 | ||||
| # This program is free software; you can redistribute it and/or modify it
 | ||||
| # under the terms and conditions of the GNU General Public License,
 | ||||
| # version 2, as published by the Free Software Foundation.
 | ||||
| #
 | ||||
| # This program is distributed in the hope it will be useful, but WITHOUT
 | ||||
| # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 | ||||
| # FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 | ||||
| # more details.
 | ||||
| #
 | ||||
| # You should have received a copy of the GNU General Public License along with
 | ||||
| # this program; if not, write to the Free Software Foundation, Inc.,
 | ||||
| # 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
 | ||||
| #
 | ||||
| # The full GNU General Public License is included in this distribution in
 | ||||
| # the file called "COPYING".
 | ||||
| #
 | ||||
| # Contact Information:
 | ||||
| # e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
 | ||||
| # Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
 | ||||
| #
 | ||||
| ################################################################################
 | ||||
| 
 | ||||
| #
 | ||||
| # Makefile for the Intel(R) 82576 VF ethernet driver
 | ||||
| #
 | ||||
| 
 | ||||
| obj-$(CONFIG_IGBVF) += igbvf.o | ||||
| 
 | ||||
| igbvf-objs := vf.o \
 | ||||
|               mbx.o \
 | ||||
|               ethtool.o \
 | ||||
|               netdev.o | ||||
| 
 | ||||
							
								
								
									
										122
									
								
								drivers/net/ethernet/intel/igbvf/defines.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										122
									
								
								drivers/net/ethernet/intel/igbvf/defines.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,122 @@ | |||
| /*******************************************************************************
 | ||||
| 
 | ||||
|   Intel(R) 82576 Virtual Function Linux driver | ||||
|   Copyright(c) 1999 - 2012 Intel Corporation. | ||||
| 
 | ||||
|   This program is free software; you can redistribute it and/or modify it | ||||
|   under the terms and conditions of the GNU General Public License, | ||||
|   version 2, as published by the Free Software Foundation. | ||||
| 
 | ||||
|   This program is distributed in the hope it will be useful, but WITHOUT | ||||
|   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||||
|   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for | ||||
|   more details. | ||||
| 
 | ||||
|   You should have received a copy of the GNU General Public License along with | ||||
|   this program; if not, write to the Free Software Foundation, Inc., | ||||
|   51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. | ||||
| 
 | ||||
|   The full GNU General Public License is included in this distribution in | ||||
|   the file called "COPYING". | ||||
| 
 | ||||
|   Contact Information: | ||||
|   e1000-devel Mailing List <e1000-devel@lists.sourceforge.net> | ||||
|   Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 | ||||
| 
 | ||||
| *******************************************************************************/ | ||||
| 
 | ||||
| #ifndef _E1000_DEFINES_H_ | ||||
| #define _E1000_DEFINES_H_ | ||||
| 
 | ||||
| /* Number of Transmit and Receive Descriptors must be a multiple of 8 */ | ||||
| #define REQ_TX_DESCRIPTOR_MULTIPLE  8 | ||||
| #define REQ_RX_DESCRIPTOR_MULTIPLE  8 | ||||
| 
 | ||||
| /* IVAR valid bit */ | ||||
| #define E1000_IVAR_VALID        0x80 | ||||
| 
 | ||||
| /* Receive Descriptor bit definitions */ | ||||
| #define E1000_RXD_STAT_DD       0x01    /* Descriptor Done */ | ||||
| #define E1000_RXD_STAT_EOP      0x02    /* End of Packet */ | ||||
| #define E1000_RXD_STAT_IXSM     0x04    /* Ignore checksum */ | ||||
| #define E1000_RXD_STAT_VP       0x08    /* IEEE VLAN Packet */ | ||||
| #define E1000_RXD_STAT_UDPCS    0x10    /* UDP xsum calculated */ | ||||
| #define E1000_RXD_STAT_TCPCS    0x20    /* TCP xsum calculated */ | ||||
| #define E1000_RXD_STAT_IPCS     0x40    /* IP xsum calculated */ | ||||
| #define E1000_RXD_ERR_SE        0x02    /* Symbol Error */ | ||||
| #define E1000_RXD_SPC_VLAN_MASK 0x0FFF  /* VLAN ID is in lower 12 bits */ | ||||
| 
 | ||||
| #define E1000_RXDEXT_STATERR_LB    0x00040000 | ||||
| #define E1000_RXDEXT_STATERR_CE    0x01000000 | ||||
| #define E1000_RXDEXT_STATERR_SE    0x02000000 | ||||
| #define E1000_RXDEXT_STATERR_SEQ   0x04000000 | ||||
| #define E1000_RXDEXT_STATERR_CXE   0x10000000 | ||||
| #define E1000_RXDEXT_STATERR_TCPE  0x20000000 | ||||
| #define E1000_RXDEXT_STATERR_IPE   0x40000000 | ||||
| #define E1000_RXDEXT_STATERR_RXE   0x80000000 | ||||
| 
 | ||||
| 
 | ||||
| /* Same mask, but for extended and packet split descriptors */ | ||||
| #define E1000_RXDEXT_ERR_FRAME_ERR_MASK ( \ | ||||
|     E1000_RXDEXT_STATERR_CE  |            \ | ||||
|     E1000_RXDEXT_STATERR_SE  |            \ | ||||
|     E1000_RXDEXT_STATERR_SEQ |            \ | ||||
|     E1000_RXDEXT_STATERR_CXE |            \ | ||||
|     E1000_RXDEXT_STATERR_RXE) | ||||
| 
 | ||||
| /* Device Control */ | ||||
| #define E1000_CTRL_RST      0x04000000  /* Global reset */ | ||||
| 
 | ||||
| /* Device Status */ | ||||
| #define E1000_STATUS_FD         0x00000001      /* Full duplex.0=half,1=full */ | ||||
| #define E1000_STATUS_LU         0x00000002      /* Link up.0=no,1=link */ | ||||
| #define E1000_STATUS_TXOFF      0x00000010      /* transmission paused */ | ||||
| #define E1000_STATUS_SPEED_10   0x00000000      /* Speed 10Mb/s */ | ||||
| #define E1000_STATUS_SPEED_100  0x00000040      /* Speed 100Mb/s */ | ||||
| #define E1000_STATUS_SPEED_1000 0x00000080      /* Speed 1000Mb/s */ | ||||
| 
 | ||||
| #define SPEED_10    10 | ||||
| #define SPEED_100   100 | ||||
| #define SPEED_1000  1000 | ||||
| #define HALF_DUPLEX 1 | ||||
| #define FULL_DUPLEX 2 | ||||
| 
 | ||||
| /* Transmit Descriptor bit definitions */ | ||||
| #define E1000_TXD_POPTS_IXSM 0x01       /* Insert IP checksum */ | ||||
| #define E1000_TXD_POPTS_TXSM 0x02       /* Insert TCP/UDP checksum */ | ||||
| #define E1000_TXD_CMD_DEXT   0x20000000 /* Descriptor extension (0 = legacy) */ | ||||
| #define E1000_TXD_STAT_DD    0x00000001 /* Descriptor Done */ | ||||
| 
 | ||||
| #define MAX_JUMBO_FRAME_SIZE    0x3F00 | ||||
| 
 | ||||
| /* 802.1q VLAN Packet Size */ | ||||
| #define VLAN_TAG_SIZE              4    /* 802.3ac tag (not DMA'd) */ | ||||
| 
 | ||||
| /* Error Codes */ | ||||
| #define E1000_SUCCESS      0 | ||||
| #define E1000_ERR_CONFIG   3 | ||||
| #define E1000_ERR_MAC_INIT 5 | ||||
| #define E1000_ERR_MBX      15 | ||||
| 
 | ||||
| /* SRRCTL bit definitions */ | ||||
| #define E1000_SRRCTL_BSIZEPKT_SHIFT                     10 /* Shift _right_ */ | ||||
| #define E1000_SRRCTL_BSIZEHDRSIZE_MASK                  0x00000F00 | ||||
| #define E1000_SRRCTL_BSIZEHDRSIZE_SHIFT                 2  /* Shift _left_ */ | ||||
| #define E1000_SRRCTL_DESCTYPE_ADV_ONEBUF                0x02000000 | ||||
| #define E1000_SRRCTL_DESCTYPE_HDR_SPLIT_ALWAYS          0x0A000000 | ||||
| #define E1000_SRRCTL_DESCTYPE_MASK                      0x0E000000 | ||||
| #define E1000_SRRCTL_DROP_EN                            0x80000000 | ||||
| 
 | ||||
| #define E1000_SRRCTL_BSIZEPKT_MASK      0x0000007F | ||||
| #define E1000_SRRCTL_BSIZEHDR_MASK      0x00003F00 | ||||
| 
 | ||||
| /* Additional Descriptor Control definitions */ | ||||
| #define E1000_TXDCTL_QUEUE_ENABLE  0x02000000 /* Enable specific Tx Queue */ | ||||
| #define E1000_RXDCTL_QUEUE_ENABLE  0x02000000 /* Enable specific Rx Queue */ | ||||
| 
 | ||||
| /* Direct Cache Access (DCA) definitions */ | ||||
| #define E1000_DCA_TXCTRL_TX_WB_RO_EN (1 << 11) /* Tx Desc writeback RO bit */ | ||||
| 
 | ||||
| #define E1000_VF_INIT_TIMEOUT 200 /* Number of retries to clear RSTI */ | ||||
| 
 | ||||
| #endif /* _E1000_DEFINES_H_ */ | ||||
							
								
								
									
										479
									
								
								drivers/net/ethernet/intel/igbvf/ethtool.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										479
									
								
								drivers/net/ethernet/intel/igbvf/ethtool.c
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,479 @@ | |||
| /*******************************************************************************
 | ||||
| 
 | ||||
|   Intel(R) 82576 Virtual Function Linux driver | ||||
|   Copyright(c) 2009 - 2012 Intel Corporation. | ||||
| 
 | ||||
|   This program is free software; you can redistribute it and/or modify it | ||||
|   under the terms and conditions of the GNU General Public License, | ||||
|   version 2, as published by the Free Software Foundation. | ||||
| 
 | ||||
|   This program is distributed in the hope it will be useful, but WITHOUT | ||||
|   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||||
|   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for | ||||
|   more details. | ||||
| 
 | ||||
|   You should have received a copy of the GNU General Public License along with | ||||
|   this program; if not, write to the Free Software Foundation, Inc., | ||||
|   51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. | ||||
| 
 | ||||
|   The full GNU General Public License is included in this distribution in | ||||
|   the file called "COPYING". | ||||
| 
 | ||||
|   Contact Information: | ||||
|   e1000-devel Mailing List <e1000-devel@lists.sourceforge.net> | ||||
|   Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 | ||||
| 
 | ||||
| *******************************************************************************/ | ||||
| 
 | ||||
| /* ethtool support for igbvf */ | ||||
| 
 | ||||
| #include <linux/netdevice.h> | ||||
| #include <linux/ethtool.h> | ||||
| #include <linux/pci.h> | ||||
| #include <linux/vmalloc.h> | ||||
| #include <linux/delay.h> | ||||
| 
 | ||||
| #include "igbvf.h" | ||||
| #include <linux/if_vlan.h> | ||||
| 
 | ||||
| 
 | ||||
| struct igbvf_stats { | ||||
| 	char stat_string[ETH_GSTRING_LEN]; | ||||
| 	int sizeof_stat; | ||||
| 	int stat_offset; | ||||
| 	int base_stat_offset; | ||||
| }; | ||||
| 
 | ||||
| #define IGBVF_STAT(current, base) \ | ||||
| 		sizeof(((struct igbvf_adapter *)0)->current), \ | ||||
| 		offsetof(struct igbvf_adapter, current), \ | ||||
| 		offsetof(struct igbvf_adapter, base) | ||||
| 
 | ||||
| static const struct igbvf_stats igbvf_gstrings_stats[] = { | ||||
| 	{ "rx_packets", IGBVF_STAT(stats.gprc, stats.base_gprc) }, | ||||
| 	{ "tx_packets", IGBVF_STAT(stats.gptc, stats.base_gptc) }, | ||||
| 	{ "rx_bytes", IGBVF_STAT(stats.gorc, stats.base_gorc) }, | ||||
| 	{ "tx_bytes", IGBVF_STAT(stats.gotc, stats.base_gotc) }, | ||||
| 	{ "multicast", IGBVF_STAT(stats.mprc, stats.base_mprc) }, | ||||
| 	{ "lbrx_bytes", IGBVF_STAT(stats.gorlbc, stats.base_gorlbc) }, | ||||
| 	{ "lbrx_packets", IGBVF_STAT(stats.gprlbc, stats.base_gprlbc) }, | ||||
| 	{ "tx_restart_queue", IGBVF_STAT(restart_queue, zero_base) }, | ||||
| 	{ "rx_long_byte_count", IGBVF_STAT(stats.gorc, stats.base_gorc) }, | ||||
| 	{ "rx_csum_offload_good", IGBVF_STAT(hw_csum_good, zero_base) }, | ||||
| 	{ "rx_csum_offload_errors", IGBVF_STAT(hw_csum_err, zero_base) }, | ||||
| 	{ "rx_header_split", IGBVF_STAT(rx_hdr_split, zero_base) }, | ||||
| 	{ "alloc_rx_buff_failed", IGBVF_STAT(alloc_rx_buff_failed, zero_base) }, | ||||
| }; | ||||
| 
 | ||||
| #define IGBVF_GLOBAL_STATS_LEN ARRAY_SIZE(igbvf_gstrings_stats) | ||||
| 
 | ||||
| static const char igbvf_gstrings_test[][ETH_GSTRING_LEN] = { | ||||
| 	"Link test   (on/offline)" | ||||
| }; | ||||
| 
 | ||||
| #define IGBVF_TEST_LEN ARRAY_SIZE(igbvf_gstrings_test) | ||||
| 
 | ||||
| static int igbvf_get_settings(struct net_device *netdev, | ||||
|                               struct ethtool_cmd *ecmd) | ||||
| { | ||||
| 	struct igbvf_adapter *adapter = netdev_priv(netdev); | ||||
| 	struct e1000_hw *hw = &adapter->hw; | ||||
| 	u32 status; | ||||
| 
 | ||||
| 	ecmd->supported   = SUPPORTED_1000baseT_Full; | ||||
| 
 | ||||
| 	ecmd->advertising = ADVERTISED_1000baseT_Full; | ||||
| 
 | ||||
| 	ecmd->port = -1; | ||||
| 	ecmd->transceiver = XCVR_DUMMY1; | ||||
| 
 | ||||
| 	status = er32(STATUS); | ||||
| 	if (status & E1000_STATUS_LU) { | ||||
| 		if (status & E1000_STATUS_SPEED_1000) | ||||
| 			ethtool_cmd_speed_set(ecmd, SPEED_1000); | ||||
| 		else if (status & E1000_STATUS_SPEED_100) | ||||
| 			ethtool_cmd_speed_set(ecmd, SPEED_100); | ||||
| 		else | ||||
| 			ethtool_cmd_speed_set(ecmd, SPEED_10); | ||||
| 
 | ||||
| 		if (status & E1000_STATUS_FD) | ||||
| 			ecmd->duplex = DUPLEX_FULL; | ||||
| 		else | ||||
| 			ecmd->duplex = DUPLEX_HALF; | ||||
| 	} else { | ||||
| 		ethtool_cmd_speed_set(ecmd, SPEED_UNKNOWN); | ||||
| 		ecmd->duplex = DUPLEX_UNKNOWN; | ||||
| 	} | ||||
| 
 | ||||
| 	ecmd->autoneg = AUTONEG_DISABLE; | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| static int igbvf_set_settings(struct net_device *netdev, | ||||
|                               struct ethtool_cmd *ecmd) | ||||
| { | ||||
| 	return -EOPNOTSUPP; | ||||
| } | ||||
| 
 | ||||
| static void igbvf_get_pauseparam(struct net_device *netdev, | ||||
|                                  struct ethtool_pauseparam *pause) | ||||
| { | ||||
| } | ||||
| 
 | ||||
| static int igbvf_set_pauseparam(struct net_device *netdev, | ||||
|                                 struct ethtool_pauseparam *pause) | ||||
| { | ||||
| 	return -EOPNOTSUPP; | ||||
| } | ||||
| 
 | ||||
| static u32 igbvf_get_msglevel(struct net_device *netdev) | ||||
| { | ||||
| 	struct igbvf_adapter *adapter = netdev_priv(netdev); | ||||
| 	return adapter->msg_enable; | ||||
| } | ||||
| 
 | ||||
| static void igbvf_set_msglevel(struct net_device *netdev, u32 data) | ||||
| { | ||||
| 	struct igbvf_adapter *adapter = netdev_priv(netdev); | ||||
| 	adapter->msg_enable = data; | ||||
| } | ||||
| 
 | ||||
| static int igbvf_get_regs_len(struct net_device *netdev) | ||||
| { | ||||
| #define IGBVF_REGS_LEN 8 | ||||
| 	return IGBVF_REGS_LEN * sizeof(u32); | ||||
| } | ||||
| 
 | ||||
| static void igbvf_get_regs(struct net_device *netdev, | ||||
|                            struct ethtool_regs *regs, void *p) | ||||
| { | ||||
| 	struct igbvf_adapter *adapter = netdev_priv(netdev); | ||||
| 	struct e1000_hw *hw = &adapter->hw; | ||||
| 	u32 *regs_buff = p; | ||||
| 
 | ||||
| 	memset(p, 0, IGBVF_REGS_LEN * sizeof(u32)); | ||||
| 
 | ||||
| 	regs->version = (1 << 24) | (adapter->pdev->revision << 16) | | ||||
| 			adapter->pdev->device; | ||||
| 
 | ||||
| 	regs_buff[0] = er32(CTRL); | ||||
| 	regs_buff[1] = er32(STATUS); | ||||
| 
 | ||||
| 	regs_buff[2] = er32(RDLEN(0)); | ||||
| 	regs_buff[3] = er32(RDH(0)); | ||||
| 	regs_buff[4] = er32(RDT(0)); | ||||
| 
 | ||||
| 	regs_buff[5] = er32(TDLEN(0)); | ||||
| 	regs_buff[6] = er32(TDH(0)); | ||||
| 	regs_buff[7] = er32(TDT(0)); | ||||
| } | ||||
| 
 | ||||
| static int igbvf_get_eeprom_len(struct net_device *netdev) | ||||
| { | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| static int igbvf_get_eeprom(struct net_device *netdev, | ||||
|                             struct ethtool_eeprom *eeprom, u8 *bytes) | ||||
| { | ||||
| 	return -EOPNOTSUPP; | ||||
| } | ||||
| 
 | ||||
| static int igbvf_set_eeprom(struct net_device *netdev, | ||||
|                             struct ethtool_eeprom *eeprom, u8 *bytes) | ||||
| { | ||||
| 	return -EOPNOTSUPP; | ||||
| } | ||||
| 
 | ||||
| static void igbvf_get_drvinfo(struct net_device *netdev, | ||||
|                               struct ethtool_drvinfo *drvinfo) | ||||
| { | ||||
| 	struct igbvf_adapter *adapter = netdev_priv(netdev); | ||||
| 
 | ||||
| 	strlcpy(drvinfo->driver,  igbvf_driver_name, sizeof(drvinfo->driver)); | ||||
| 	strlcpy(drvinfo->version, igbvf_driver_version, | ||||
| 		sizeof(drvinfo->version)); | ||||
| 	strlcpy(drvinfo->bus_info, pci_name(adapter->pdev), | ||||
| 		sizeof(drvinfo->bus_info)); | ||||
| 	drvinfo->regdump_len = igbvf_get_regs_len(netdev); | ||||
| 	drvinfo->eedump_len = igbvf_get_eeprom_len(netdev); | ||||
| } | ||||
| 
 | ||||
| static void igbvf_get_ringparam(struct net_device *netdev, | ||||
|                                 struct ethtool_ringparam *ring) | ||||
| { | ||||
| 	struct igbvf_adapter *adapter = netdev_priv(netdev); | ||||
| 	struct igbvf_ring *tx_ring = adapter->tx_ring; | ||||
| 	struct igbvf_ring *rx_ring = adapter->rx_ring; | ||||
| 
 | ||||
| 	ring->rx_max_pending = IGBVF_MAX_RXD; | ||||
| 	ring->tx_max_pending = IGBVF_MAX_TXD; | ||||
| 	ring->rx_pending = rx_ring->count; | ||||
| 	ring->tx_pending = tx_ring->count; | ||||
| } | ||||
| 
 | ||||
| static int igbvf_set_ringparam(struct net_device *netdev, | ||||
|                                struct ethtool_ringparam *ring) | ||||
| { | ||||
| 	struct igbvf_adapter *adapter = netdev_priv(netdev); | ||||
| 	struct igbvf_ring *temp_ring; | ||||
| 	int err = 0; | ||||
| 	u32 new_rx_count, new_tx_count; | ||||
| 
 | ||||
| 	if ((ring->rx_mini_pending) || (ring->rx_jumbo_pending)) | ||||
| 		return -EINVAL; | ||||
| 
 | ||||
| 	new_rx_count = max(ring->rx_pending, (u32)IGBVF_MIN_RXD); | ||||
| 	new_rx_count = min(new_rx_count, (u32)IGBVF_MAX_RXD); | ||||
| 	new_rx_count = ALIGN(new_rx_count, REQ_RX_DESCRIPTOR_MULTIPLE); | ||||
| 
 | ||||
| 	new_tx_count = max(ring->tx_pending, (u32)IGBVF_MIN_TXD); | ||||
| 	new_tx_count = min(new_tx_count, (u32)IGBVF_MAX_TXD); | ||||
| 	new_tx_count = ALIGN(new_tx_count, REQ_TX_DESCRIPTOR_MULTIPLE); | ||||
| 
 | ||||
| 	if ((new_tx_count == adapter->tx_ring->count) && | ||||
| 	    (new_rx_count == adapter->rx_ring->count)) { | ||||
| 		/* nothing to do */ | ||||
| 		return 0; | ||||
| 	} | ||||
| 
 | ||||
| 	while (test_and_set_bit(__IGBVF_RESETTING, &adapter->state)) | ||||
| 		msleep(1); | ||||
| 
 | ||||
| 	if (!netif_running(adapter->netdev)) { | ||||
| 		adapter->tx_ring->count = new_tx_count; | ||||
| 		adapter->rx_ring->count = new_rx_count; | ||||
| 		goto clear_reset; | ||||
| 	} | ||||
| 
 | ||||
| 	temp_ring = vmalloc(sizeof(struct igbvf_ring)); | ||||
| 	if (!temp_ring) { | ||||
| 		err = -ENOMEM; | ||||
| 		goto clear_reset; | ||||
| 	} | ||||
| 
 | ||||
| 	igbvf_down(adapter); | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * We can't just free everything and then setup again, | ||||
| 	 * because the ISRs in MSI-X mode get passed pointers | ||||
| 	 * to the tx and rx ring structs. | ||||
| 	 */ | ||||
| 	if (new_tx_count != adapter->tx_ring->count) { | ||||
| 		memcpy(temp_ring, adapter->tx_ring, sizeof(struct igbvf_ring)); | ||||
| 
 | ||||
| 		temp_ring->count = new_tx_count; | ||||
| 		err = igbvf_setup_tx_resources(adapter, temp_ring); | ||||
| 		if (err) | ||||
| 			goto err_setup; | ||||
| 
 | ||||
| 		igbvf_free_tx_resources(adapter->tx_ring); | ||||
| 
 | ||||
| 		memcpy(adapter->tx_ring, temp_ring, sizeof(struct igbvf_ring)); | ||||
| 	} | ||||
| 
 | ||||
| 	if (new_rx_count != adapter->rx_ring->count) { | ||||
| 		memcpy(temp_ring, adapter->rx_ring, sizeof(struct igbvf_ring)); | ||||
| 
 | ||||
| 		temp_ring->count = new_rx_count; | ||||
| 		err = igbvf_setup_rx_resources(adapter, temp_ring); | ||||
| 		if (err) | ||||
| 			goto err_setup; | ||||
| 
 | ||||
| 		igbvf_free_rx_resources(adapter->rx_ring); | ||||
| 
 | ||||
| 		memcpy(adapter->rx_ring, temp_ring,sizeof(struct igbvf_ring)); | ||||
| 	} | ||||
| err_setup: | ||||
| 	igbvf_up(adapter); | ||||
| 	vfree(temp_ring); | ||||
| clear_reset: | ||||
| 	clear_bit(__IGBVF_RESETTING, &adapter->state); | ||||
| 	return err; | ||||
| } | ||||
| 
 | ||||
| static int igbvf_link_test(struct igbvf_adapter *adapter, u64 *data) | ||||
| { | ||||
| 	struct e1000_hw *hw = &adapter->hw; | ||||
| 	*data = 0; | ||||
| 
 | ||||
| 	hw->mac.ops.check_for_link(hw); | ||||
| 
 | ||||
| 	if (!(er32(STATUS) & E1000_STATUS_LU)) | ||||
| 		*data = 1; | ||||
| 
 | ||||
| 	return *data; | ||||
| } | ||||
| 
 | ||||
| static void igbvf_diag_test(struct net_device *netdev, | ||||
|                             struct ethtool_test *eth_test, u64 *data) | ||||
| { | ||||
| 	struct igbvf_adapter *adapter = netdev_priv(netdev); | ||||
| 
 | ||||
| 	set_bit(__IGBVF_TESTING, &adapter->state); | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * Link test performed before hardware reset so autoneg doesn't | ||||
| 	 * interfere with test result | ||||
| 	 */ | ||||
| 	if (igbvf_link_test(adapter, &data[0])) | ||||
| 		eth_test->flags |= ETH_TEST_FL_FAILED; | ||||
| 
 | ||||
| 	clear_bit(__IGBVF_TESTING, &adapter->state); | ||||
| 	msleep_interruptible(4 * 1000); | ||||
| } | ||||
| 
 | ||||
| static void igbvf_get_wol(struct net_device *netdev, | ||||
|                           struct ethtool_wolinfo *wol) | ||||
| { | ||||
| 	wol->supported = 0; | ||||
| 	wol->wolopts = 0; | ||||
| } | ||||
| 
 | ||||
| static int igbvf_set_wol(struct net_device *netdev, | ||||
|                          struct ethtool_wolinfo *wol) | ||||
| { | ||||
| 	return -EOPNOTSUPP; | ||||
| } | ||||
| 
 | ||||
| static int igbvf_get_coalesce(struct net_device *netdev, | ||||
|                               struct ethtool_coalesce *ec) | ||||
| { | ||||
| 	struct igbvf_adapter *adapter = netdev_priv(netdev); | ||||
| 
 | ||||
| 	if (adapter->requested_itr <= 3) | ||||
| 		ec->rx_coalesce_usecs = adapter->requested_itr; | ||||
| 	else | ||||
| 		ec->rx_coalesce_usecs = adapter->current_itr >> 2; | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| static int igbvf_set_coalesce(struct net_device *netdev, | ||||
|                               struct ethtool_coalesce *ec) | ||||
| { | ||||
| 	struct igbvf_adapter *adapter = netdev_priv(netdev); | ||||
| 	struct e1000_hw *hw = &adapter->hw; | ||||
| 
 | ||||
| 	if ((ec->rx_coalesce_usecs >= IGBVF_MIN_ITR_USECS) && | ||||
| 	     (ec->rx_coalesce_usecs <= IGBVF_MAX_ITR_USECS)) { | ||||
| 		adapter->current_itr = ec->rx_coalesce_usecs << 2; | ||||
| 		adapter->requested_itr = 1000000000 / | ||||
| 					(adapter->current_itr * 256); | ||||
| 	} else if ((ec->rx_coalesce_usecs == 3) || | ||||
| 		   (ec->rx_coalesce_usecs == 2)) { | ||||
| 		adapter->current_itr = IGBVF_START_ITR; | ||||
| 		adapter->requested_itr = ec->rx_coalesce_usecs; | ||||
| 	} else if (ec->rx_coalesce_usecs == 0) { | ||||
| 		/*
 | ||||
| 		 * The user's desire is to turn off interrupt throttling | ||||
| 		 * altogether, but due to HW limitations, we can't do that. | ||||
| 		 * Instead we set a very small value in EITR, which would | ||||
| 		 * allow ~967k interrupts per second, but allow the adapter's | ||||
| 		 * internal clocking to still function properly. | ||||
| 		 */ | ||||
| 		adapter->current_itr = 4; | ||||
| 		adapter->requested_itr = 1000000000 / | ||||
| 					(adapter->current_itr * 256); | ||||
| 	} else | ||||
| 		return -EINVAL; | ||||
| 
 | ||||
| 	writel(adapter->current_itr, | ||||
| 	       hw->hw_addr + adapter->rx_ring->itr_register); | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| static int igbvf_nway_reset(struct net_device *netdev) | ||||
| { | ||||
| 	struct igbvf_adapter *adapter = netdev_priv(netdev); | ||||
| 	if (netif_running(netdev)) | ||||
| 		igbvf_reinit_locked(adapter); | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| static void igbvf_get_ethtool_stats(struct net_device *netdev, | ||||
|                                     struct ethtool_stats *stats, | ||||
|                                     u64 *data) | ||||
| { | ||||
| 	struct igbvf_adapter *adapter = netdev_priv(netdev); | ||||
| 	int i; | ||||
| 
 | ||||
| 	igbvf_update_stats(adapter); | ||||
| 	for (i = 0; i < IGBVF_GLOBAL_STATS_LEN; i++) { | ||||
| 		char *p = (char *)adapter + | ||||
| 		          igbvf_gstrings_stats[i].stat_offset; | ||||
| 		char *b = (char *)adapter + | ||||
| 		          igbvf_gstrings_stats[i].base_stat_offset; | ||||
| 		data[i] = ((igbvf_gstrings_stats[i].sizeof_stat == | ||||
| 		            sizeof(u64)) ? (*(u64 *)p - *(u64 *)b) : | ||||
| 		            (*(u32 *)p - *(u32 *)b)); | ||||
| 	} | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| static int igbvf_get_sset_count(struct net_device *dev, int stringset) | ||||
| { | ||||
| 	switch(stringset) { | ||||
| 	case ETH_SS_TEST: | ||||
| 		return IGBVF_TEST_LEN; | ||||
| 	case ETH_SS_STATS: | ||||
| 		return IGBVF_GLOBAL_STATS_LEN; | ||||
| 	default: | ||||
| 		return -EINVAL; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| static void igbvf_get_strings(struct net_device *netdev, u32 stringset, | ||||
|                               u8 *data) | ||||
| { | ||||
| 	u8 *p = data; | ||||
| 	int i; | ||||
| 
 | ||||
| 	switch (stringset) { | ||||
| 	case ETH_SS_TEST: | ||||
| 		memcpy(data, *igbvf_gstrings_test, sizeof(igbvf_gstrings_test)); | ||||
| 		break; | ||||
| 	case ETH_SS_STATS: | ||||
| 		for (i = 0; i < IGBVF_GLOBAL_STATS_LEN; i++) { | ||||
| 			memcpy(p, igbvf_gstrings_stats[i].stat_string, | ||||
| 			       ETH_GSTRING_LEN); | ||||
| 			p += ETH_GSTRING_LEN; | ||||
| 		} | ||||
| 		break; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| static const struct ethtool_ops igbvf_ethtool_ops = { | ||||
| 	.get_settings		= igbvf_get_settings, | ||||
| 	.set_settings		= igbvf_set_settings, | ||||
| 	.get_drvinfo		= igbvf_get_drvinfo, | ||||
| 	.get_regs_len		= igbvf_get_regs_len, | ||||
| 	.get_regs		= igbvf_get_regs, | ||||
| 	.get_wol		= igbvf_get_wol, | ||||
| 	.set_wol		= igbvf_set_wol, | ||||
| 	.get_msglevel		= igbvf_get_msglevel, | ||||
| 	.set_msglevel		= igbvf_set_msglevel, | ||||
| 	.nway_reset		= igbvf_nway_reset, | ||||
| 	.get_link		= ethtool_op_get_link, | ||||
| 	.get_eeprom_len		= igbvf_get_eeprom_len, | ||||
| 	.get_eeprom		= igbvf_get_eeprom, | ||||
| 	.set_eeprom		= igbvf_set_eeprom, | ||||
| 	.get_ringparam		= igbvf_get_ringparam, | ||||
| 	.set_ringparam		= igbvf_set_ringparam, | ||||
| 	.get_pauseparam		= igbvf_get_pauseparam, | ||||
| 	.set_pauseparam		= igbvf_set_pauseparam, | ||||
| 	.self_test		= igbvf_diag_test, | ||||
| 	.get_sset_count		= igbvf_get_sset_count, | ||||
| 	.get_strings		= igbvf_get_strings, | ||||
| 	.get_ethtool_stats	= igbvf_get_ethtool_stats, | ||||
| 	.get_coalesce		= igbvf_get_coalesce, | ||||
| 	.set_coalesce		= igbvf_set_coalesce, | ||||
| }; | ||||
| 
 | ||||
| void igbvf_set_ethtool_ops(struct net_device *netdev) | ||||
| { | ||||
| 	netdev->ethtool_ops = &igbvf_ethtool_ops; | ||||
| } | ||||
							
								
								
									
										329
									
								
								drivers/net/ethernet/intel/igbvf/igbvf.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										329
									
								
								drivers/net/ethernet/intel/igbvf/igbvf.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,329 @@ | |||
| /*******************************************************************************
 | ||||
| 
 | ||||
|   Intel(R) 82576 Virtual Function Linux driver | ||||
|   Copyright(c) 2009 - 2012 Intel Corporation. | ||||
| 
 | ||||
|   This program is free software; you can redistribute it and/or modify it | ||||
|   under the terms and conditions of the GNU General Public License, | ||||
|   version 2, as published by the Free Software Foundation. | ||||
| 
 | ||||
|   This program is distributed in the hope it will be useful, but WITHOUT | ||||
|   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||||
|   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for | ||||
|   more details. | ||||
| 
 | ||||
|   You should have received a copy of the GNU General Public License along with | ||||
|   this program; if not, write to the Free Software Foundation, Inc., | ||||
|   51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. | ||||
| 
 | ||||
|   The full GNU General Public License is included in this distribution in | ||||
|   the file called "COPYING". | ||||
| 
 | ||||
|   Contact Information: | ||||
|   e1000-devel Mailing List <e1000-devel@lists.sourceforge.net> | ||||
|   Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 | ||||
| 
 | ||||
| *******************************************************************************/ | ||||
| 
 | ||||
| /* Linux PRO/1000 Ethernet Driver main header file */ | ||||
| 
 | ||||
| #ifndef _IGBVF_H_ | ||||
| #define _IGBVF_H_ | ||||
| 
 | ||||
| #include <linux/types.h> | ||||
| #include <linux/timer.h> | ||||
| #include <linux/io.h> | ||||
| #include <linux/netdevice.h> | ||||
| #include <linux/if_vlan.h> | ||||
| 
 | ||||
| #include "vf.h" | ||||
| 
 | ||||
| /* Forward declarations */ | ||||
| struct igbvf_info; | ||||
| struct igbvf_adapter; | ||||
| 
 | ||||
| /* Interrupt defines */ | ||||
| #define IGBVF_START_ITR                    488 /* ~8000 ints/sec */ | ||||
| #define IGBVF_4K_ITR                       980 | ||||
| #define IGBVF_20K_ITR                      196 | ||||
| #define IGBVF_70K_ITR                       56 | ||||
| 
 | ||||
| enum latency_range { | ||||
| 	lowest_latency = 0, | ||||
| 	low_latency = 1, | ||||
| 	bulk_latency = 2, | ||||
| 	latency_invalid = 255 | ||||
| }; | ||||
| 
 | ||||
| 
 | ||||
| /* Interrupt modes, as used by the IntMode parameter */ | ||||
| #define IGBVF_INT_MODE_LEGACY           0 | ||||
| #define IGBVF_INT_MODE_MSI              1 | ||||
| #define IGBVF_INT_MODE_MSIX             2 | ||||
| 
 | ||||
| /* Tx/Rx descriptor defines */ | ||||
| #define IGBVF_DEFAULT_TXD               256 | ||||
| #define IGBVF_MAX_TXD                   4096 | ||||
| #define IGBVF_MIN_TXD                   80 | ||||
| 
 | ||||
| #define IGBVF_DEFAULT_RXD               256 | ||||
| #define IGBVF_MAX_RXD                   4096 | ||||
| #define IGBVF_MIN_RXD                   80 | ||||
| 
 | ||||
| #define IGBVF_MIN_ITR_USECS             10 /* 100000 irq/sec */ | ||||
| #define IGBVF_MAX_ITR_USECS             10000 /* 100    irq/sec */ | ||||
| 
 | ||||
| /* RX descriptor control thresholds.
 | ||||
|  * PTHRESH - MAC will consider prefetch if it has fewer than this number of | ||||
|  *           descriptors available in its onboard memory. | ||||
|  *           Setting this to 0 disables RX descriptor prefetch. | ||||
|  * HTHRESH - MAC will only prefetch if there are at least this many descriptors | ||||
|  *           available in host memory. | ||||
|  *           If PTHRESH is 0, this should also be 0. | ||||
|  * WTHRESH - RX descriptor writeback threshold - MAC will delay writing back | ||||
|  *           descriptors until either it has this many to write back, or the | ||||
|  *           ITR timer expires. | ||||
|  */ | ||||
| #define IGBVF_RX_PTHRESH                16 | ||||
| #define IGBVF_RX_HTHRESH                8 | ||||
| #define IGBVF_RX_WTHRESH                1 | ||||
| 
 | ||||
| /* this is the size past which hardware will drop packets when setting LPE=0 */ | ||||
| #define MAXIMUM_ETHERNET_VLAN_SIZE      1522 | ||||
| 
 | ||||
| #define IGBVF_FC_PAUSE_TIME             0x0680 /* 858 usec */ | ||||
| 
 | ||||
| /* How many Tx Descriptors do we need to call netif_wake_queue ? */ | ||||
| #define IGBVF_TX_QUEUE_WAKE             32 | ||||
| /* How many Rx Buffers do we bundle into one write to the hardware ? */ | ||||
| #define IGBVF_RX_BUFFER_WRITE           16 /* Must be power of 2 */ | ||||
| 
 | ||||
| #define AUTO_ALL_MODES                  0 | ||||
| #define IGBVF_EEPROM_APME               0x0400 | ||||
| 
 | ||||
| #define IGBVF_MNG_VLAN_NONE             (-1) | ||||
| 
 | ||||
| /* Number of packet split data buffers (not including the header buffer) */ | ||||
| #define PS_PAGE_BUFFERS                 (MAX_PS_BUFFERS - 1) | ||||
| 
 | ||||
| enum igbvf_boards { | ||||
| 	board_vf, | ||||
| 	board_i350_vf, | ||||
| }; | ||||
| 
 | ||||
| struct igbvf_queue_stats { | ||||
| 	u64 packets; | ||||
| 	u64 bytes; | ||||
| }; | ||||
| 
 | ||||
| /*
 | ||||
|  * wrappers around a pointer to a socket buffer, | ||||
|  * so a DMA handle can be stored along with the buffer | ||||
|  */ | ||||
| struct igbvf_buffer { | ||||
| 	dma_addr_t dma; | ||||
| 	struct sk_buff *skb; | ||||
| 	union { | ||||
| 		/* Tx */ | ||||
| 		struct { | ||||
| 			unsigned long time_stamp; | ||||
| 			union e1000_adv_tx_desc *next_to_watch; | ||||
| 			u16 length; | ||||
| 			u16 mapped_as_page; | ||||
| 		}; | ||||
| 		/* Rx */ | ||||
| 		struct { | ||||
| 			struct page *page; | ||||
| 			u64 page_dma; | ||||
| 			unsigned int page_offset; | ||||
| 		}; | ||||
| 	}; | ||||
| }; | ||||
| 
 | ||||
| union igbvf_desc { | ||||
| 	union e1000_adv_rx_desc rx_desc; | ||||
| 	union e1000_adv_tx_desc tx_desc; | ||||
| 	struct e1000_adv_tx_context_desc tx_context_desc; | ||||
| }; | ||||
| 
 | ||||
| struct igbvf_ring { | ||||
| 	struct igbvf_adapter *adapter;  /* backlink */ | ||||
| 	union igbvf_desc *desc;         /* pointer to ring memory  */ | ||||
| 	dma_addr_t dma;                 /* phys address of ring    */ | ||||
| 	unsigned int size;              /* length of ring in bytes */ | ||||
| 	unsigned int count;             /* number of desc. in ring */ | ||||
| 
 | ||||
| 	u16 next_to_use; | ||||
| 	u16 next_to_clean; | ||||
| 
 | ||||
| 	u16 head; | ||||
| 	u16 tail; | ||||
| 
 | ||||
| 	/* array of buffer information structs */ | ||||
| 	struct igbvf_buffer *buffer_info; | ||||
| 	struct napi_struct napi; | ||||
| 
 | ||||
| 	char name[IFNAMSIZ + 5]; | ||||
| 	u32 eims_value; | ||||
| 	u32 itr_val; | ||||
| 	enum latency_range itr_range; | ||||
| 	u16 itr_register; | ||||
| 	int set_itr; | ||||
| 
 | ||||
| 	struct sk_buff *rx_skb_top; | ||||
| 
 | ||||
| 	struct igbvf_queue_stats stats; | ||||
| }; | ||||
| 
 | ||||
| /* board specific private data structure */ | ||||
| struct igbvf_adapter { | ||||
| 	struct timer_list watchdog_timer; | ||||
| 	struct timer_list blink_timer; | ||||
| 
 | ||||
| 	struct work_struct reset_task; | ||||
| 	struct work_struct watchdog_task; | ||||
| 
 | ||||
| 	const struct igbvf_info *ei; | ||||
| 
 | ||||
| 	unsigned long active_vlans[BITS_TO_LONGS(VLAN_N_VID)]; | ||||
| 	u32 bd_number; | ||||
| 	u32 rx_buffer_len; | ||||
| 	u32 polling_interval; | ||||
| 	u16 mng_vlan_id; | ||||
| 	u16 link_speed; | ||||
| 	u16 link_duplex; | ||||
| 
 | ||||
| 	spinlock_t tx_queue_lock; /* prevent concurrent tail updates */ | ||||
| 
 | ||||
| 	/* track device up/down/testing state */ | ||||
| 	unsigned long state; | ||||
| 
 | ||||
| 	/* Interrupt Throttle Rate */ | ||||
| 	u32 requested_itr; /* ints/sec or adaptive */ | ||||
| 	u32 current_itr; /* Actual ITR register value, not ints/sec */ | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * Tx | ||||
| 	 */ | ||||
| 	struct igbvf_ring *tx_ring /* One per active queue */ | ||||
| 	____cacheline_aligned_in_smp; | ||||
| 
 | ||||
| 	unsigned int restart_queue; | ||||
| 	u32 txd_cmd; | ||||
| 
 | ||||
| 	u32 tx_int_delay; | ||||
| 	u32 tx_abs_int_delay; | ||||
| 
 | ||||
| 	unsigned int total_tx_bytes; | ||||
| 	unsigned int total_tx_packets; | ||||
| 	unsigned int total_rx_bytes; | ||||
| 	unsigned int total_rx_packets; | ||||
| 
 | ||||
| 	/* Tx stats */ | ||||
| 	u32 tx_timeout_count; | ||||
| 	u32 tx_fifo_head; | ||||
| 	u32 tx_head_addr; | ||||
| 	u32 tx_fifo_size; | ||||
| 	u32 tx_dma_failed; | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * Rx | ||||
| 	 */ | ||||
| 	struct igbvf_ring *rx_ring; | ||||
| 
 | ||||
| 	u32 rx_int_delay; | ||||
| 	u32 rx_abs_int_delay; | ||||
| 
 | ||||
| 	/* Rx stats */ | ||||
| 	u64 hw_csum_err; | ||||
| 	u64 hw_csum_good; | ||||
| 	u64 rx_hdr_split; | ||||
| 	u32 alloc_rx_buff_failed; | ||||
| 	u32 rx_dma_failed; | ||||
| 
 | ||||
| 	unsigned int rx_ps_hdr_size; | ||||
| 	u32 max_frame_size; | ||||
| 	u32 min_frame_size; | ||||
| 
 | ||||
| 	/* OS defined structs */ | ||||
| 	struct net_device *netdev; | ||||
| 	struct pci_dev *pdev; | ||||
| 	struct net_device_stats net_stats; | ||||
| 	spinlock_t stats_lock;      /* prevent concurrent stats updates */ | ||||
| 
 | ||||
| 	/* structs defined in e1000_hw.h */ | ||||
| 	struct e1000_hw hw; | ||||
| 
 | ||||
| 	/* The VF counters don't clear on read so we have to get a base
 | ||||
| 	 * count on driver start up and always subtract that base on | ||||
| 	 * on the first update, thus the flag.. | ||||
| 	 */ | ||||
| 	struct e1000_vf_stats stats; | ||||
| 	u64 zero_base; | ||||
| 
 | ||||
| 	struct igbvf_ring test_tx_ring; | ||||
| 	struct igbvf_ring test_rx_ring; | ||||
| 	u32 test_icr; | ||||
| 
 | ||||
| 	u32 msg_enable; | ||||
| 	struct msix_entry *msix_entries; | ||||
| 	int int_mode; | ||||
| 	u32 eims_enable_mask; | ||||
| 	u32 eims_other; | ||||
| 	u32 int_counter0; | ||||
| 	u32 int_counter1; | ||||
| 
 | ||||
| 	u32 eeprom_wol; | ||||
| 	u32 wol; | ||||
| 	u32 pba; | ||||
| 
 | ||||
| 	bool fc_autoneg; | ||||
| 
 | ||||
| 	unsigned long led_status; | ||||
| 
 | ||||
| 	unsigned int flags; | ||||
| 	unsigned long last_reset; | ||||
| }; | ||||
| 
 | ||||
| struct igbvf_info { | ||||
| 	enum e1000_mac_type     mac; | ||||
| 	unsigned int            flags; | ||||
| 	u32                     pba; | ||||
| 	void                    (*init_ops)(struct e1000_hw *); | ||||
| 	s32                     (*get_variants)(struct igbvf_adapter *); | ||||
| }; | ||||
| 
 | ||||
| /* hardware capability, feature, and workaround flags */ | ||||
| #define IGBVF_FLAG_RX_CSUM_DISABLED             (1 << 0) | ||||
| #define IGBVF_FLAG_RX_LB_VLAN_BSWAP		(1 << 1) | ||||
| #define IGBVF_RX_DESC_ADV(R, i)     \ | ||||
| 	(&((((R).desc))[i].rx_desc)) | ||||
| #define IGBVF_TX_DESC_ADV(R, i)     \ | ||||
| 	(&((((R).desc))[i].tx_desc)) | ||||
| #define IGBVF_TX_CTXTDESC_ADV(R, i) \ | ||||
| 	(&((((R).desc))[i].tx_context_desc)) | ||||
| 
 | ||||
| enum igbvf_state_t { | ||||
| 	__IGBVF_TESTING, | ||||
| 	__IGBVF_RESETTING, | ||||
| 	__IGBVF_DOWN | ||||
| }; | ||||
| 
 | ||||
| extern char igbvf_driver_name[]; | ||||
| extern const char igbvf_driver_version[]; | ||||
| 
 | ||||
| void igbvf_check_options(struct igbvf_adapter *); | ||||
| void igbvf_set_ethtool_ops(struct net_device *); | ||||
| 
 | ||||
| int igbvf_up(struct igbvf_adapter *); | ||||
| void igbvf_down(struct igbvf_adapter *); | ||||
| void igbvf_reinit_locked(struct igbvf_adapter *); | ||||
| int igbvf_setup_rx_resources(struct igbvf_adapter *, struct igbvf_ring *); | ||||
| int igbvf_setup_tx_resources(struct igbvf_adapter *, struct igbvf_ring *); | ||||
| void igbvf_free_rx_resources(struct igbvf_ring *); | ||||
| void igbvf_free_tx_resources(struct igbvf_ring *); | ||||
| void igbvf_update_stats(struct igbvf_adapter *); | ||||
| 
 | ||||
| extern unsigned int copybreak; | ||||
| 
 | ||||
| #endif /* _IGBVF_H_ */ | ||||
							
								
								
									
										350
									
								
								drivers/net/ethernet/intel/igbvf/mbx.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										350
									
								
								drivers/net/ethernet/intel/igbvf/mbx.c
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,350 @@ | |||
| /*******************************************************************************
 | ||||
| 
 | ||||
|   Intel(R) 82576 Virtual Function Linux driver | ||||
|   Copyright(c) 2009 - 2012 Intel Corporation. | ||||
| 
 | ||||
|   This program is free software; you can redistribute it and/or modify it | ||||
|   under the terms and conditions of the GNU General Public License, | ||||
|   version 2, as published by the Free Software Foundation. | ||||
| 
 | ||||
|   This program is distributed in the hope it will be useful, but WITHOUT | ||||
|   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||||
|   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for | ||||
|   more details. | ||||
| 
 | ||||
|   You should have received a copy of the GNU General Public License along with | ||||
|   this program; if not, write to the Free Software Foundation, Inc., | ||||
|   51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. | ||||
| 
 | ||||
|   The full GNU General Public License is included in this distribution in | ||||
|   the file called "COPYING". | ||||
| 
 | ||||
|   Contact Information: | ||||
|   e1000-devel Mailing List <e1000-devel@lists.sourceforge.net> | ||||
|   Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 | ||||
| 
 | ||||
| *******************************************************************************/ | ||||
| 
 | ||||
| #include "mbx.h" | ||||
| 
 | ||||
| /**
 | ||||
|  *  e1000_poll_for_msg - Wait for message notification | ||||
|  *  @hw: pointer to the HW structure | ||||
|  * | ||||
|  *  returns SUCCESS if it successfully received a message notification | ||||
|  **/ | ||||
| static s32 e1000_poll_for_msg(struct e1000_hw *hw) | ||||
| { | ||||
| 	struct e1000_mbx_info *mbx = &hw->mbx; | ||||
| 	int countdown = mbx->timeout; | ||||
| 
 | ||||
| 	if (!mbx->ops.check_for_msg) | ||||
| 		goto out; | ||||
| 
 | ||||
| 	while (countdown && mbx->ops.check_for_msg(hw)) { | ||||
| 		countdown--; | ||||
| 		udelay(mbx->usec_delay); | ||||
| 	} | ||||
| 
 | ||||
| 	/* if we failed, all future posted messages fail until reset */ | ||||
| 	if (!countdown) | ||||
| 		mbx->timeout = 0; | ||||
| out: | ||||
| 	return countdown ? E1000_SUCCESS : -E1000_ERR_MBX; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  *  e1000_poll_for_ack - Wait for message acknowledgement | ||||
|  *  @hw: pointer to the HW structure | ||||
|  * | ||||
|  *  returns SUCCESS if it successfully received a message acknowledgement | ||||
|  **/ | ||||
| static s32 e1000_poll_for_ack(struct e1000_hw *hw) | ||||
| { | ||||
| 	struct e1000_mbx_info *mbx = &hw->mbx; | ||||
| 	int countdown = mbx->timeout; | ||||
| 
 | ||||
| 	if (!mbx->ops.check_for_ack) | ||||
| 		goto out; | ||||
| 
 | ||||
| 	while (countdown && mbx->ops.check_for_ack(hw)) { | ||||
| 		countdown--; | ||||
| 		udelay(mbx->usec_delay); | ||||
| 	} | ||||
| 
 | ||||
| 	/* if we failed, all future posted messages fail until reset */ | ||||
| 	if (!countdown) | ||||
| 		mbx->timeout = 0; | ||||
| out: | ||||
| 	return countdown ? E1000_SUCCESS : -E1000_ERR_MBX; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  *  e1000_read_posted_mbx - Wait for message notification and receive message | ||||
|  *  @hw: pointer to the HW structure | ||||
|  *  @msg: The message buffer | ||||
|  *  @size: Length of buffer | ||||
|  * | ||||
|  *  returns SUCCESS if it successfully received a message notification and | ||||
|  *  copied it into the receive buffer. | ||||
|  **/ | ||||
| static s32 e1000_read_posted_mbx(struct e1000_hw *hw, u32 *msg, u16 size) | ||||
| { | ||||
| 	struct e1000_mbx_info *mbx = &hw->mbx; | ||||
| 	s32 ret_val = -E1000_ERR_MBX; | ||||
| 
 | ||||
| 	if (!mbx->ops.read) | ||||
| 		goto out; | ||||
| 
 | ||||
| 	ret_val = e1000_poll_for_msg(hw); | ||||
| 
 | ||||
| 	/* if ack received read message, otherwise we timed out */ | ||||
| 	if (!ret_val) | ||||
| 		ret_val = mbx->ops.read(hw, msg, size); | ||||
| out: | ||||
| 	return ret_val; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  *  e1000_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 | ||||
|  * | ||||
|  *  returns SUCCESS if it successfully copied message into the buffer and | ||||
|  *  received an ack to that message within delay * timeout period | ||||
|  **/ | ||||
| static s32 e1000_write_posted_mbx(struct e1000_hw *hw, u32 *msg, u16 size) | ||||
| { | ||||
| 	struct e1000_mbx_info *mbx = &hw->mbx; | ||||
| 	s32 ret_val = -E1000_ERR_MBX; | ||||
| 
 | ||||
| 	/* exit if we either can't write or there isn't a defined timeout */ | ||||
| 	if (!mbx->ops.write || !mbx->timeout) | ||||
| 		goto out; | ||||
| 
 | ||||
| 	/* send msg*/ | ||||
| 	ret_val = mbx->ops.write(hw, msg, size); | ||||
| 
 | ||||
| 	/* if msg sent wait until we receive an ack */ | ||||
| 	if (!ret_val) | ||||
| 		ret_val = e1000_poll_for_ack(hw); | ||||
| out: | ||||
| 	return ret_val; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  *  e1000_read_v2p_mailbox - read v2p mailbox | ||||
|  *  @hw: pointer to the HW structure | ||||
|  * | ||||
|  *  This function is used to read the v2p mailbox without losing the read to | ||||
|  *  clear status bits. | ||||
|  **/ | ||||
| static u32 e1000_read_v2p_mailbox(struct e1000_hw *hw) | ||||
| { | ||||
| 	u32 v2p_mailbox = er32(V2PMAILBOX(0)); | ||||
| 
 | ||||
| 	v2p_mailbox |= hw->dev_spec.vf.v2p_mailbox; | ||||
| 	hw->dev_spec.vf.v2p_mailbox |= v2p_mailbox & E1000_V2PMAILBOX_R2C_BITS; | ||||
| 
 | ||||
| 	return v2p_mailbox; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  *  e1000_check_for_bit_vf - Determine if a status bit was set | ||||
|  *  @hw: pointer to the HW structure | ||||
|  *  @mask: bitmask for bits to be tested and cleared | ||||
|  * | ||||
|  *  This function is used to check for the read to clear bits within | ||||
|  *  the V2P mailbox. | ||||
|  **/ | ||||
| static s32 e1000_check_for_bit_vf(struct e1000_hw *hw, u32 mask) | ||||
| { | ||||
| 	u32 v2p_mailbox = e1000_read_v2p_mailbox(hw); | ||||
| 	s32 ret_val = -E1000_ERR_MBX; | ||||
| 
 | ||||
| 	if (v2p_mailbox & mask) | ||||
| 		ret_val = E1000_SUCCESS; | ||||
| 
 | ||||
| 	hw->dev_spec.vf.v2p_mailbox &= ~mask; | ||||
| 
 | ||||
| 	return ret_val; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  *  e1000_check_for_msg_vf - checks to see if the PF has sent mail | ||||
|  *  @hw: pointer to the HW structure | ||||
|  * | ||||
|  *  returns SUCCESS if the PF has set the Status bit or else ERR_MBX | ||||
|  **/ | ||||
| static s32 e1000_check_for_msg_vf(struct e1000_hw *hw) | ||||
| { | ||||
| 	s32 ret_val = -E1000_ERR_MBX; | ||||
| 
 | ||||
| 	if (!e1000_check_for_bit_vf(hw, E1000_V2PMAILBOX_PFSTS)) { | ||||
| 		ret_val = E1000_SUCCESS; | ||||
| 		hw->mbx.stats.reqs++; | ||||
| 	} | ||||
| 
 | ||||
| 	return ret_val; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  *  e1000_check_for_ack_vf - checks to see if the PF has ACK'd | ||||
|  *  @hw: pointer to the HW structure | ||||
|  * | ||||
|  *  returns SUCCESS if the PF has set the ACK bit or else ERR_MBX | ||||
|  **/ | ||||
| static s32 e1000_check_for_ack_vf(struct e1000_hw *hw) | ||||
| { | ||||
| 	s32 ret_val = -E1000_ERR_MBX; | ||||
| 
 | ||||
| 	if (!e1000_check_for_bit_vf(hw, E1000_V2PMAILBOX_PFACK)) { | ||||
| 		ret_val = E1000_SUCCESS; | ||||
| 		hw->mbx.stats.acks++; | ||||
| 	} | ||||
| 
 | ||||
| 	return ret_val; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  *  e1000_check_for_rst_vf - checks to see if the PF has reset | ||||
|  *  @hw: pointer to the HW structure | ||||
|  * | ||||
|  *  returns true if the PF has set the reset done bit or else false | ||||
|  **/ | ||||
| static s32 e1000_check_for_rst_vf(struct e1000_hw *hw) | ||||
| { | ||||
| 	s32 ret_val = -E1000_ERR_MBX; | ||||
| 
 | ||||
| 	if (!e1000_check_for_bit_vf(hw, (E1000_V2PMAILBOX_RSTD | | ||||
| 	                                 E1000_V2PMAILBOX_RSTI))) { | ||||
| 		ret_val = E1000_SUCCESS; | ||||
| 		hw->mbx.stats.rsts++; | ||||
| 	} | ||||
| 
 | ||||
| 	return ret_val; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  *  e1000_obtain_mbx_lock_vf - obtain mailbox lock | ||||
|  *  @hw: pointer to the HW structure | ||||
|  * | ||||
|  *  return SUCCESS if we obtained the mailbox lock | ||||
|  **/ | ||||
| static s32 e1000_obtain_mbx_lock_vf(struct e1000_hw *hw) | ||||
| { | ||||
| 	s32 ret_val = -E1000_ERR_MBX; | ||||
| 
 | ||||
| 	/* Take ownership of the buffer */ | ||||
| 	ew32(V2PMAILBOX(0), E1000_V2PMAILBOX_VFU); | ||||
| 
 | ||||
| 	/* reserve mailbox for vf use */ | ||||
| 	if (e1000_read_v2p_mailbox(hw) & E1000_V2PMAILBOX_VFU) | ||||
| 		ret_val = E1000_SUCCESS; | ||||
| 
 | ||||
| 	return ret_val; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  *  e1000_write_mbx_vf - Write a message to the mailbox | ||||
|  *  @hw: pointer to the HW structure | ||||
|  *  @msg: The message buffer | ||||
|  *  @size: Length of buffer | ||||
|  * | ||||
|  *  returns SUCCESS if it successfully copied message into the buffer | ||||
|  **/ | ||||
| static s32 e1000_write_mbx_vf(struct e1000_hw *hw, u32 *msg, u16 size) | ||||
| { | ||||
| 	s32 err; | ||||
| 	u16 i; | ||||
| 
 | ||||
| 	/* lock the mailbox to prevent pf/vf race condition */ | ||||
| 	err = e1000_obtain_mbx_lock_vf(hw); | ||||
| 	if (err) | ||||
| 		goto out_no_write; | ||||
| 
 | ||||
| 	/* flush any ack or msg as we are going to overwrite mailbox */ | ||||
| 	e1000_check_for_ack_vf(hw); | ||||
| 	e1000_check_for_msg_vf(hw); | ||||
| 
 | ||||
| 	/* copy the caller specified message to the mailbox memory buffer */ | ||||
| 	for (i = 0; i < size; i++) | ||||
| 		array_ew32(VMBMEM(0), i, msg[i]); | ||||
| 
 | ||||
| 	/* update stats */ | ||||
| 	hw->mbx.stats.msgs_tx++; | ||||
| 
 | ||||
| 	/* Drop VFU and interrupt the PF to tell it a message has been sent */ | ||||
| 	ew32(V2PMAILBOX(0), E1000_V2PMAILBOX_REQ); | ||||
| 
 | ||||
| out_no_write: | ||||
| 	return err; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  *  e1000_read_mbx_vf - Reads a message from the inbox intended for vf | ||||
|  *  @hw: pointer to the HW structure | ||||
|  *  @msg: The message buffer | ||||
|  *  @size: Length of buffer | ||||
|  * | ||||
|  *  returns SUCCESS if it successfully read message from buffer | ||||
|  **/ | ||||
| static s32 e1000_read_mbx_vf(struct e1000_hw *hw, u32 *msg, u16 size) | ||||
| { | ||||
| 	s32 err; | ||||
| 	u16 i; | ||||
| 
 | ||||
| 	/* lock the mailbox to prevent pf/vf race condition */ | ||||
| 	err = e1000_obtain_mbx_lock_vf(hw); | ||||
| 	if (err) | ||||
| 		goto out_no_read; | ||||
| 
 | ||||
| 	/* copy the message from the mailbox memory buffer */ | ||||
| 	for (i = 0; i < size; i++) | ||||
| 		msg[i] = array_er32(VMBMEM(0), i); | ||||
| 
 | ||||
| 	/* Acknowledge receipt and release mailbox, then we're done */ | ||||
| 	ew32(V2PMAILBOX(0), E1000_V2PMAILBOX_ACK); | ||||
| 
 | ||||
| 	/* update stats */ | ||||
| 	hw->mbx.stats.msgs_rx++; | ||||
| 
 | ||||
| out_no_read: | ||||
| 	return err; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  *  e1000_init_mbx_params_vf - set initial values for vf mailbox | ||||
|  *  @hw: pointer to the HW structure | ||||
|  * | ||||
|  *  Initializes the hw->mbx struct to correct values for vf mailbox | ||||
|  */ | ||||
| s32 e1000_init_mbx_params_vf(struct e1000_hw *hw) | ||||
| { | ||||
| 	struct e1000_mbx_info *mbx = &hw->mbx; | ||||
| 
 | ||||
| 	/* start mailbox as timed out and let the reset_hw call set the timeout
 | ||||
| 	 * value to being communications */ | ||||
| 	mbx->timeout = 0; | ||||
| 	mbx->usec_delay = E1000_VF_MBX_INIT_DELAY; | ||||
| 
 | ||||
| 	mbx->size = E1000_VFMAILBOX_SIZE; | ||||
| 
 | ||||
| 	mbx->ops.read = e1000_read_mbx_vf; | ||||
| 	mbx->ops.write = e1000_write_mbx_vf; | ||||
| 	mbx->ops.read_posted = e1000_read_posted_mbx; | ||||
| 	mbx->ops.write_posted = e1000_write_posted_mbx; | ||||
| 	mbx->ops.check_for_msg = e1000_check_for_msg_vf; | ||||
| 	mbx->ops.check_for_ack = e1000_check_for_ack_vf; | ||||
| 	mbx->ops.check_for_rst = e1000_check_for_rst_vf; | ||||
| 
 | ||||
| 	mbx->stats.msgs_tx = 0; | ||||
| 	mbx->stats.msgs_rx = 0; | ||||
| 	mbx->stats.reqs = 0; | ||||
| 	mbx->stats.acks = 0; | ||||
| 	mbx->stats.rsts = 0; | ||||
| 
 | ||||
| 	return E1000_SUCCESS; | ||||
| } | ||||
| 
 | ||||
							
								
								
									
										75
									
								
								drivers/net/ethernet/intel/igbvf/mbx.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										75
									
								
								drivers/net/ethernet/intel/igbvf/mbx.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,75 @@ | |||
| /*******************************************************************************
 | ||||
| 
 | ||||
|   Intel(R) 82576 Virtual Function Linux driver | ||||
|   Copyright(c) 1999 - 2012 Intel Corporation. | ||||
| 
 | ||||
|   This program is free software; you can redistribute it and/or modify it | ||||
|   under the terms and conditions of the GNU General Public License, | ||||
|   version 2, as published by the Free Software Foundation. | ||||
| 
 | ||||
|   This program is distributed in the hope it will be useful, but WITHOUT | ||||
|   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||||
|   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for | ||||
|   more details. | ||||
| 
 | ||||
|   You should have received a copy of the GNU General Public License along with | ||||
|   this program; if not, write to the Free Software Foundation, Inc., | ||||
|   51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. | ||||
| 
 | ||||
|   The full GNU General Public License is included in this distribution in | ||||
|   the file called "COPYING". | ||||
| 
 | ||||
|   Contact Information: | ||||
|   e1000-devel Mailing List <e1000-devel@lists.sourceforge.net> | ||||
|   Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 | ||||
| 
 | ||||
| *******************************************************************************/ | ||||
| 
 | ||||
| #ifndef _E1000_MBX_H_ | ||||
| #define _E1000_MBX_H_ | ||||
| 
 | ||||
| #include "vf.h" | ||||
| 
 | ||||
| #define E1000_V2PMAILBOX_REQ   0x00000001 /* Request for PF Ready bit */ | ||||
| #define E1000_V2PMAILBOX_ACK   0x00000002 /* Ack PF message received */ | ||||
| #define E1000_V2PMAILBOX_VFU   0x00000004 /* VF owns the mailbox buffer */ | ||||
| #define E1000_V2PMAILBOX_PFU   0x00000008 /* PF owns the mailbox buffer */ | ||||
| #define E1000_V2PMAILBOX_PFSTS 0x00000010 /* PF wrote a message in the MB */ | ||||
| #define E1000_V2PMAILBOX_PFACK 0x00000020 /* PF ack the previous VF msg */ | ||||
| #define E1000_V2PMAILBOX_RSTI  0x00000040 /* PF has reset indication */ | ||||
| #define E1000_V2PMAILBOX_RSTD  0x00000080 /* PF has indicated reset done */ | ||||
| #define E1000_V2PMAILBOX_R2C_BITS 0x000000B0 /* All read to clear bits */ | ||||
| 
 | ||||
| #define E1000_VFMAILBOX_SIZE   16 /* 16 32 bit words - 64 bytes */ | ||||
| 
 | ||||
| /* If it's a E1000_VF_* msg then it originates in the VF and is sent to the
 | ||||
|  * PF.  The reverse is true if it is E1000_PF_*. | ||||
|  * Message ACK's are the value or'd with 0xF0000000 | ||||
|  */ | ||||
| #define E1000_VT_MSGTYPE_ACK      0x80000000  /* Messages below or'd with | ||||
|                                                * this are the ACK */ | ||||
| #define E1000_VT_MSGTYPE_NACK     0x40000000  /* Messages below or'd with | ||||
|                                                * this are the NACK */ | ||||
| #define E1000_VT_MSGTYPE_CTS      0x20000000  /* Indicates that VF is still | ||||
|                                                  clear to send requests */ | ||||
| 
 | ||||
| /* We have a total wait time of 1s for vf mailbox posted messages */ | ||||
| #define E1000_VF_MBX_INIT_TIMEOUT 2000 /* retry count for mailbox timeout */ | ||||
| #define E1000_VF_MBX_INIT_DELAY   500  /* usec delay between retries */ | ||||
| 
 | ||||
| #define E1000_VT_MSGINFO_SHIFT    16 | ||||
| /* bits 23:16 are used for exra info for certain messages */ | ||||
| #define E1000_VT_MSGINFO_MASK     (0xFF << E1000_VT_MSGINFO_SHIFT) | ||||
| 
 | ||||
| #define E1000_VF_RESET            0x01 /* VF requests reset */ | ||||
| #define E1000_VF_SET_MAC_ADDR     0x02 /* VF requests PF to set MAC addr */ | ||||
| #define E1000_VF_SET_MULTICAST    0x03 /* VF requests PF to set MC addr */ | ||||
| #define E1000_VF_SET_VLAN         0x04 /* VF requests PF to set VLAN */ | ||||
| #define E1000_VF_SET_LPE          0x05 /* VF requests PF to set VMOLR.LPE */ | ||||
| 
 | ||||
| #define E1000_PF_CONTROL_MSG      0x0100 /* PF control message */ | ||||
| 
 | ||||
| void e1000_init_mbx_ops_generic(struct e1000_hw *hw); | ||||
| s32 e1000_init_mbx_params_vf(struct e1000_hw *); | ||||
| 
 | ||||
| #endif /* _E1000_MBX_H_ */ | ||||
							
								
								
									
										2914
									
								
								drivers/net/ethernet/intel/igbvf/netdev.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										2914
									
								
								drivers/net/ethernet/intel/igbvf/netdev.c
									
										
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							
							
								
								
									
										108
									
								
								drivers/net/ethernet/intel/igbvf/regs.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										108
									
								
								drivers/net/ethernet/intel/igbvf/regs.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,108 @@ | |||
| /*******************************************************************************
 | ||||
| 
 | ||||
|   Intel(R) 82576 Virtual Function Linux driver | ||||
|   Copyright(c) 2009 - 2012 Intel Corporation. | ||||
| 
 | ||||
|   This program is free software; you can redistribute it and/or modify it | ||||
|   under the terms and conditions of the GNU General Public License, | ||||
|   version 2, as published by the Free Software Foundation. | ||||
| 
 | ||||
|   This program is distributed in the hope it will be useful, but WITHOUT | ||||
|   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||||
|   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for | ||||
|   more details. | ||||
| 
 | ||||
|   You should have received a copy of the GNU General Public License along with | ||||
|   this program; if not, write to the Free Software Foundation, Inc., | ||||
|   51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. | ||||
| 
 | ||||
|   The full GNU General Public License is included in this distribution in | ||||
|   the file called "COPYING". | ||||
| 
 | ||||
|   Contact Information: | ||||
|   e1000-devel Mailing List <e1000-devel@lists.sourceforge.net> | ||||
|   Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 | ||||
| 
 | ||||
| *******************************************************************************/ | ||||
| 
 | ||||
| #ifndef _E1000_REGS_H_ | ||||
| #define _E1000_REGS_H_ | ||||
| 
 | ||||
| #define E1000_CTRL      0x00000 /* Device Control - RW */ | ||||
| #define E1000_STATUS    0x00008 /* Device Status - RO */ | ||||
| #define E1000_ITR       0x000C4 /* Interrupt Throttling Rate - RW */ | ||||
| #define E1000_EICR      0x01580 /* Ext. Interrupt Cause Read - R/clr */ | ||||
| #define E1000_EITR(_n)  (0x01680 + (0x4 * (_n))) | ||||
| #define E1000_EICS      0x01520 /* Ext. Interrupt Cause Set - W0 */ | ||||
| #define E1000_EIMS      0x01524 /* Ext. Interrupt Mask Set/Read - RW */ | ||||
| #define E1000_EIMC      0x01528 /* Ext. Interrupt Mask Clear - WO */ | ||||
| #define E1000_EIAC      0x0152C /* Ext. Interrupt Auto Clear - RW */ | ||||
| #define E1000_EIAM      0x01530 /* Ext. Interrupt Ack Auto Clear Mask - RW */ | ||||
| #define E1000_IVAR0     0x01700 /* Interrupt Vector Allocation (array) - RW */ | ||||
| #define E1000_IVAR_MISC 0x01740 /* IVAR for "other" causes - RW */ | ||||
| /*
 | ||||
|  * Convenience macros | ||||
|  * | ||||
|  * Note: "_n" is the queue number of the register to be written to. | ||||
|  * | ||||
|  * Example usage: | ||||
|  * E1000_RDBAL_REG(current_rx_queue) | ||||
|  */ | ||||
| #define E1000_RDBAL(_n)      ((_n) < 4 ? (0x02800 + ((_n) * 0x100)) : \ | ||||
|                                          (0x0C000 + ((_n) * 0x40))) | ||||
| #define E1000_RDBAH(_n)      ((_n) < 4 ? (0x02804 + ((_n) * 0x100)) : \ | ||||
|                                          (0x0C004 + ((_n) * 0x40))) | ||||
| #define E1000_RDLEN(_n)      ((_n) < 4 ? (0x02808 + ((_n) * 0x100)) : \ | ||||
|                                          (0x0C008 + ((_n) * 0x40))) | ||||
| #define E1000_SRRCTL(_n)     ((_n) < 4 ? (0x0280C + ((_n) * 0x100)) : \ | ||||
|                                          (0x0C00C + ((_n) * 0x40))) | ||||
| #define E1000_RDH(_n)        ((_n) < 4 ? (0x02810 + ((_n) * 0x100)) : \ | ||||
|                                          (0x0C010 + ((_n) * 0x40))) | ||||
| #define E1000_RDT(_n)        ((_n) < 4 ? (0x02818 + ((_n) * 0x100)) : \ | ||||
|                                          (0x0C018 + ((_n) * 0x40))) | ||||
| #define E1000_RXDCTL(_n)     ((_n) < 4 ? (0x02828 + ((_n) * 0x100)) : \ | ||||
|                                          (0x0C028 + ((_n) * 0x40))) | ||||
| #define E1000_TDBAL(_n)      ((_n) < 4 ? (0x03800 + ((_n) * 0x100)) : \ | ||||
|                                          (0x0E000 + ((_n) * 0x40))) | ||||
| #define E1000_TDBAH(_n)      ((_n) < 4 ? (0x03804 + ((_n) * 0x100)) : \ | ||||
|                                          (0x0E004 + ((_n) * 0x40))) | ||||
| #define E1000_TDLEN(_n)      ((_n) < 4 ? (0x03808 + ((_n) * 0x100)) : \ | ||||
|                                          (0x0E008 + ((_n) * 0x40))) | ||||
| #define E1000_TDH(_n)        ((_n) < 4 ? (0x03810 + ((_n) * 0x100)) : \ | ||||
|                                          (0x0E010 + ((_n) * 0x40))) | ||||
| #define E1000_TDT(_n)        ((_n) < 4 ? (0x03818 + ((_n) * 0x100)) : \ | ||||
|                                          (0x0E018 + ((_n) * 0x40))) | ||||
| #define E1000_TXDCTL(_n)     ((_n) < 4 ? (0x03828 + ((_n) * 0x100)) : \ | ||||
|                                          (0x0E028 + ((_n) * 0x40))) | ||||
| #define E1000_DCA_TXCTRL(_n) (0x03814 + (_n << 8)) | ||||
| #define E1000_DCA_RXCTRL(_n) (0x02814 + (_n << 8)) | ||||
| #define E1000_RAL(_i)  (((_i) <= 15) ? (0x05400 + ((_i) * 8)) : \ | ||||
|                                        (0x054E0 + ((_i - 16) * 8))) | ||||
| #define E1000_RAH(_i)  (((_i) <= 15) ? (0x05404 + ((_i) * 8)) : \ | ||||
|                                        (0x054E4 + ((_i - 16) * 8))) | ||||
| 
 | ||||
| /* Statistics registers */ | ||||
| #define E1000_VFGPRC    0x00F10 | ||||
| #define E1000_VFGORC    0x00F18 | ||||
| #define E1000_VFMPRC    0x00F3C | ||||
| #define E1000_VFGPTC    0x00F14 | ||||
| #define E1000_VFGOTC    0x00F34 | ||||
| #define E1000_VFGOTLBC  0x00F50 | ||||
| #define E1000_VFGPTLBC  0x00F44 | ||||
| #define E1000_VFGORLBC  0x00F48 | ||||
| #define E1000_VFGPRLBC  0x00F40 | ||||
| 
 | ||||
| /* These act per VF so an array friendly macro is used */ | ||||
| #define E1000_V2PMAILBOX(_n)   (0x00C40 + (4 * (_n))) | ||||
| #define E1000_VMBMEM(_n)       (0x00800 + (64 * (_n))) | ||||
| 
 | ||||
| /* Define macros for handling registers */ | ||||
| #define er32(reg) readl(hw->hw_addr + E1000_##reg) | ||||
| #define ew32(reg, val) writel((val), hw->hw_addr +  E1000_##reg) | ||||
| #define array_er32(reg, offset) \ | ||||
| 	readl(hw->hw_addr + E1000_##reg + (offset << 2)) | ||||
| #define array_ew32(reg, offset, val) \ | ||||
| 	writel((val), hw->hw_addr +  E1000_##reg + (offset << 2)) | ||||
| #define e1e_flush() er32(STATUS) | ||||
| 
 | ||||
| #endif | ||||
							
								
								
									
										400
									
								
								drivers/net/ethernet/intel/igbvf/vf.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										400
									
								
								drivers/net/ethernet/intel/igbvf/vf.c
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,400 @@ | |||
| /*******************************************************************************
 | ||||
| 
 | ||||
|   Intel(R) 82576 Virtual Function Linux driver | ||||
|   Copyright(c) 2009 - 2012 Intel Corporation. | ||||
| 
 | ||||
|   This program is free software; you can redistribute it and/or modify it | ||||
|   under the terms and conditions of the GNU General Public License, | ||||
|   version 2, as published by the Free Software Foundation. | ||||
| 
 | ||||
|   This program is distributed in the hope it will be useful, but WITHOUT | ||||
|   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||||
|   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for | ||||
|   more details. | ||||
| 
 | ||||
|   You should have received a copy of the GNU General Public License along with | ||||
|   this program; if not, write to the Free Software Foundation, Inc., | ||||
|   51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. | ||||
| 
 | ||||
|   The full GNU General Public License is included in this distribution in | ||||
|   the file called "COPYING". | ||||
| 
 | ||||
|   Contact Information: | ||||
|   e1000-devel Mailing List <e1000-devel@lists.sourceforge.net> | ||||
|   Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 | ||||
| 
 | ||||
| *******************************************************************************/ | ||||
| 
 | ||||
| 
 | ||||
| #include "vf.h" | ||||
| 
 | ||||
| static s32 e1000_check_for_link_vf(struct e1000_hw *hw); | ||||
| static s32 e1000_get_link_up_info_vf(struct e1000_hw *hw, u16 *speed, | ||||
|                                      u16 *duplex); | ||||
| static s32 e1000_init_hw_vf(struct e1000_hw *hw); | ||||
| static s32 e1000_reset_hw_vf(struct e1000_hw *hw); | ||||
| 
 | ||||
| static void e1000_update_mc_addr_list_vf(struct e1000_hw *hw, u8 *, | ||||
|                                          u32, u32, u32); | ||||
| static void e1000_rar_set_vf(struct e1000_hw *, u8 *, u32); | ||||
| static s32 e1000_read_mac_addr_vf(struct e1000_hw *); | ||||
| static s32 e1000_set_vfta_vf(struct e1000_hw *, u16, bool); | ||||
| 
 | ||||
| /**
 | ||||
|  *  e1000_init_mac_params_vf - Inits MAC params | ||||
|  *  @hw: pointer to the HW structure | ||||
|  **/ | ||||
| static s32 e1000_init_mac_params_vf(struct e1000_hw *hw) | ||||
| { | ||||
| 	struct e1000_mac_info *mac = &hw->mac; | ||||
| 
 | ||||
| 	/* VF's have no MTA Registers - PF feature only */ | ||||
| 	mac->mta_reg_count = 128; | ||||
| 	/* VF's have no access to RAR entries  */ | ||||
| 	mac->rar_entry_count = 1; | ||||
| 
 | ||||
| 	/* Function pointers */ | ||||
| 	/* reset */ | ||||
| 	mac->ops.reset_hw = e1000_reset_hw_vf; | ||||
| 	/* hw initialization */ | ||||
| 	mac->ops.init_hw = e1000_init_hw_vf; | ||||
| 	/* check for link */ | ||||
| 	mac->ops.check_for_link = e1000_check_for_link_vf; | ||||
| 	/* link info */ | ||||
| 	mac->ops.get_link_up_info = e1000_get_link_up_info_vf; | ||||
| 	/* multicast address update */ | ||||
| 	mac->ops.update_mc_addr_list = e1000_update_mc_addr_list_vf; | ||||
| 	/* set mac address */ | ||||
| 	mac->ops.rar_set = e1000_rar_set_vf; | ||||
| 	/* read mac address */ | ||||
| 	mac->ops.read_mac_addr = e1000_read_mac_addr_vf; | ||||
| 	/* set vlan filter table array */ | ||||
| 	mac->ops.set_vfta = e1000_set_vfta_vf; | ||||
| 
 | ||||
| 	return E1000_SUCCESS; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  *  e1000_init_function_pointers_vf - Inits function pointers | ||||
|  *  @hw: pointer to the HW structure | ||||
|  **/ | ||||
| void e1000_init_function_pointers_vf(struct e1000_hw *hw) | ||||
| { | ||||
| 	hw->mac.ops.init_params = e1000_init_mac_params_vf; | ||||
| 	hw->mbx.ops.init_params = e1000_init_mbx_params_vf; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  *  e1000_get_link_up_info_vf - Gets link info. | ||||
|  *  @hw: pointer to the HW structure | ||||
|  *  @speed: pointer to 16 bit value to store link speed. | ||||
|  *  @duplex: pointer to 16 bit value to store duplex. | ||||
|  * | ||||
|  *  Since we cannot read the PHY and get accurate link info, we must rely upon | ||||
|  *  the status register's data which is often stale and inaccurate. | ||||
|  **/ | ||||
| static s32 e1000_get_link_up_info_vf(struct e1000_hw *hw, u16 *speed, | ||||
|                                      u16 *duplex) | ||||
| { | ||||
| 	s32 status; | ||||
| 
 | ||||
| 	status = er32(STATUS); | ||||
| 	if (status & E1000_STATUS_SPEED_1000) | ||||
| 		*speed = SPEED_1000; | ||||
| 	else if (status & E1000_STATUS_SPEED_100) | ||||
| 		*speed = SPEED_100; | ||||
| 	else | ||||
| 		*speed = SPEED_10; | ||||
| 
 | ||||
| 	if (status & E1000_STATUS_FD) | ||||
| 		*duplex = FULL_DUPLEX; | ||||
| 	else | ||||
| 		*duplex = HALF_DUPLEX; | ||||
| 
 | ||||
| 	return E1000_SUCCESS; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  *  e1000_reset_hw_vf - Resets the HW | ||||
|  *  @hw: pointer to the HW structure | ||||
|  * | ||||
|  *  VF's provide a function level reset. This is done using bit 26 of ctrl_reg. | ||||
|  *  This is all the reset we can perform on a VF. | ||||
|  **/ | ||||
| static s32 e1000_reset_hw_vf(struct e1000_hw *hw) | ||||
| { | ||||
| 	struct e1000_mbx_info *mbx = &hw->mbx; | ||||
| 	u32 timeout = E1000_VF_INIT_TIMEOUT; | ||||
| 	u32 ret_val = -E1000_ERR_MAC_INIT; | ||||
| 	u32 msgbuf[3]; | ||||
| 	u8 *addr = (u8 *)(&msgbuf[1]); | ||||
| 	u32 ctrl; | ||||
| 
 | ||||
| 	/* assert vf queue/interrupt reset */ | ||||
| 	ctrl = er32(CTRL); | ||||
| 	ew32(CTRL, ctrl | E1000_CTRL_RST); | ||||
| 
 | ||||
| 	/* we cannot initialize while the RSTI / RSTD bits are asserted */ | ||||
| 	while (!mbx->ops.check_for_rst(hw) && timeout) { | ||||
| 		timeout--; | ||||
| 		udelay(5); | ||||
| 	} | ||||
| 
 | ||||
| 	if (timeout) { | ||||
| 		/* mailbox timeout can now become active */ | ||||
| 		mbx->timeout = E1000_VF_MBX_INIT_TIMEOUT; | ||||
| 
 | ||||
| 		/* notify pf of vf reset completion */ | ||||
| 		msgbuf[0] = E1000_VF_RESET; | ||||
| 		mbx->ops.write_posted(hw, msgbuf, 1); | ||||
| 
 | ||||
| 		msleep(10); | ||||
| 
 | ||||
| 		/* set our "perm_addr" based on info provided by PF */ | ||||
| 		ret_val = mbx->ops.read_posted(hw, msgbuf, 3); | ||||
| 		if (!ret_val) { | ||||
| 			if (msgbuf[0] == (E1000_VF_RESET | E1000_VT_MSGTYPE_ACK)) | ||||
| 				memcpy(hw->mac.perm_addr, addr, ETH_ALEN); | ||||
| 			else | ||||
| 				ret_val = -E1000_ERR_MAC_INIT; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	return ret_val; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  *  e1000_init_hw_vf - Inits the HW | ||||
|  *  @hw: pointer to the HW structure | ||||
|  * | ||||
|  *  Not much to do here except clear the PF Reset indication if there is one. | ||||
|  **/ | ||||
| static s32 e1000_init_hw_vf(struct e1000_hw *hw) | ||||
| { | ||||
| 	/* attempt to set and restore our mac address */ | ||||
| 	e1000_rar_set_vf(hw, hw->mac.addr, 0); | ||||
| 
 | ||||
| 	return E1000_SUCCESS; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  *  e1000_hash_mc_addr_vf - Generate a multicast hash value | ||||
|  *  @hw: pointer to the HW structure | ||||
|  *  @mc_addr: pointer to a multicast address | ||||
|  * | ||||
|  *  Generates a multicast address hash value which is used to determine | ||||
|  *  the multicast filter table array address and new table value.  See | ||||
|  *  e1000_mta_set_generic() | ||||
|  **/ | ||||
| static u32 e1000_hash_mc_addr_vf(struct e1000_hw *hw, u8 *mc_addr) | ||||
| { | ||||
| 	u32 hash_value, hash_mask; | ||||
| 	u8 bit_shift = 0; | ||||
| 
 | ||||
| 	/* Register count multiplied by bits per register */ | ||||
| 	hash_mask = (hw->mac.mta_reg_count * 32) - 1; | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * The bit_shift is the number of left-shifts | ||||
| 	 * where 0xFF would still fall within the hash mask. | ||||
| 	 */ | ||||
| 	while (hash_mask >> bit_shift != 0xFF) | ||||
| 		bit_shift++; | ||||
| 
 | ||||
| 	hash_value = hash_mask & (((mc_addr[4] >> (8 - bit_shift)) | | ||||
| 	                          (((u16) mc_addr[5]) << bit_shift))); | ||||
| 
 | ||||
| 	return hash_value; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  *  e1000_update_mc_addr_list_vf - Update Multicast addresses | ||||
|  *  @hw: pointer to the HW structure | ||||
|  *  @mc_addr_list: array of multicast addresses to program | ||||
|  *  @mc_addr_count: number of multicast addresses to program | ||||
|  *  @rar_used_count: the first RAR register free to program | ||||
|  *  @rar_count: total number of supported Receive Address Registers | ||||
|  * | ||||
|  *  Updates the Receive Address Registers and Multicast Table Array. | ||||
|  *  The caller must have a packed mc_addr_list of multicast addresses. | ||||
|  *  The parameter rar_count will usually be hw->mac.rar_entry_count | ||||
|  *  unless there are workarounds that change this. | ||||
|  **/ | ||||
| static void e1000_update_mc_addr_list_vf(struct e1000_hw *hw, | ||||
|                                   u8 *mc_addr_list, u32 mc_addr_count, | ||||
|                                   u32 rar_used_count, u32 rar_count) | ||||
| { | ||||
| 	struct e1000_mbx_info *mbx = &hw->mbx; | ||||
| 	u32 msgbuf[E1000_VFMAILBOX_SIZE]; | ||||
| 	u16 *hash_list = (u16 *)&msgbuf[1]; | ||||
| 	u32 hash_value; | ||||
| 	u32 cnt, i; | ||||
| 
 | ||||
| 	/* Each entry in the list uses 1 16 bit word.  We have 30
 | ||||
| 	 * 16 bit words available in our HW msg buffer (minus 1 for the | ||||
| 	 * msg type).  That's 30 hash values if we pack 'em right.  If | ||||
| 	 * there are more than 30 MC addresses to add then punt the | ||||
| 	 * extras for now and then add code to handle more than 30 later. | ||||
| 	 * It would be unusual for a server to request that many multi-cast | ||||
| 	 * addresses except for in large enterprise network environments. | ||||
| 	 */ | ||||
| 
 | ||||
| 	cnt = (mc_addr_count > 30) ? 30 : mc_addr_count; | ||||
| 	msgbuf[0] = E1000_VF_SET_MULTICAST; | ||||
| 	msgbuf[0] |= cnt << E1000_VT_MSGINFO_SHIFT; | ||||
| 
 | ||||
| 	for (i = 0; i < cnt; i++) { | ||||
| 		hash_value = e1000_hash_mc_addr_vf(hw, mc_addr_list); | ||||
| 		hash_list[i] = hash_value & 0x0FFFF; | ||||
| 		mc_addr_list += ETH_ALEN; | ||||
| 	} | ||||
| 
 | ||||
| 	mbx->ops.write_posted(hw, msgbuf, E1000_VFMAILBOX_SIZE); | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  *  e1000_set_vfta_vf - Set/Unset vlan filter table address | ||||
|  *  @hw: pointer to the HW structure | ||||
|  *  @vid: determines the vfta register and bit to set/unset | ||||
|  *  @set: if true then set bit, else clear bit | ||||
|  **/ | ||||
| static s32 e1000_set_vfta_vf(struct e1000_hw *hw, u16 vid, bool set) | ||||
| { | ||||
| 	struct e1000_mbx_info *mbx = &hw->mbx; | ||||
| 	u32 msgbuf[2]; | ||||
| 	s32 err; | ||||
| 
 | ||||
| 	msgbuf[0] = E1000_VF_SET_VLAN; | ||||
| 	msgbuf[1] = vid; | ||||
| 	/* Setting the 8 bit field MSG INFO to true indicates "add" */ | ||||
| 	if (set) | ||||
| 		msgbuf[0] |= 1 << E1000_VT_MSGINFO_SHIFT; | ||||
| 
 | ||||
| 	mbx->ops.write_posted(hw, msgbuf, 2); | ||||
| 
 | ||||
| 	err = mbx->ops.read_posted(hw, msgbuf, 2); | ||||
| 
 | ||||
| 	msgbuf[0] &= ~E1000_VT_MSGTYPE_CTS; | ||||
| 
 | ||||
| 	/* if nacked the vlan was rejected */ | ||||
| 	if (!err && (msgbuf[0] == (E1000_VF_SET_VLAN | E1000_VT_MSGTYPE_NACK))) | ||||
| 		err = -E1000_ERR_MAC_INIT; | ||||
| 
 | ||||
| 	return err; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  *  e1000_rlpml_set_vf - Set the maximum receive packet length | ||||
|  *  @hw: pointer to the HW structure | ||||
|  *  @max_size: value to assign to max frame size | ||||
|  **/ | ||||
| void e1000_rlpml_set_vf(struct e1000_hw *hw, u16 max_size) | ||||
| { | ||||
| 	struct e1000_mbx_info *mbx = &hw->mbx; | ||||
| 	u32 msgbuf[2]; | ||||
| 
 | ||||
| 	msgbuf[0] = E1000_VF_SET_LPE; | ||||
| 	msgbuf[1] = max_size; | ||||
| 
 | ||||
| 	mbx->ops.write_posted(hw, msgbuf, 2); | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  *  e1000_rar_set_vf - set device MAC address | ||||
|  *  @hw: pointer to the HW structure | ||||
|  *  @addr: pointer to the receive address | ||||
|  *  @index: receive address array register | ||||
|  **/ | ||||
| static void e1000_rar_set_vf(struct e1000_hw *hw, u8 * addr, u32 index) | ||||
| { | ||||
| 	struct e1000_mbx_info *mbx = &hw->mbx; | ||||
| 	u32 msgbuf[3]; | ||||
| 	u8 *msg_addr = (u8 *)(&msgbuf[1]); | ||||
| 	s32 ret_val; | ||||
| 
 | ||||
| 	memset(msgbuf, 0, 12); | ||||
| 	msgbuf[0] = E1000_VF_SET_MAC_ADDR; | ||||
| 	memcpy(msg_addr, addr, ETH_ALEN); | ||||
| 	ret_val = mbx->ops.write_posted(hw, msgbuf, 3); | ||||
| 
 | ||||
| 	if (!ret_val) | ||||
| 		ret_val = mbx->ops.read_posted(hw, msgbuf, 3); | ||||
| 
 | ||||
| 	msgbuf[0] &= ~E1000_VT_MSGTYPE_CTS; | ||||
| 
 | ||||
| 	/* if nacked the address was rejected, use "perm_addr" */ | ||||
| 	if (!ret_val && | ||||
| 	    (msgbuf[0] == (E1000_VF_SET_MAC_ADDR | E1000_VT_MSGTYPE_NACK))) | ||||
| 		e1000_read_mac_addr_vf(hw); | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  *  e1000_read_mac_addr_vf - Read device MAC address | ||||
|  *  @hw: pointer to the HW structure | ||||
|  **/ | ||||
| static s32 e1000_read_mac_addr_vf(struct e1000_hw *hw) | ||||
| { | ||||
| 	memcpy(hw->mac.addr, hw->mac.perm_addr, ETH_ALEN); | ||||
| 
 | ||||
| 	return E1000_SUCCESS; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  *  e1000_check_for_link_vf - Check for link for a virtual interface | ||||
|  *  @hw: pointer to the HW structure | ||||
|  * | ||||
|  *  Checks to see if the underlying PF is still talking to the VF and | ||||
|  *  if it is then it reports the link state to the hardware, otherwise | ||||
|  *  it reports link down and returns an error. | ||||
|  **/ | ||||
| static s32 e1000_check_for_link_vf(struct e1000_hw *hw) | ||||
| { | ||||
| 	struct e1000_mbx_info *mbx = &hw->mbx; | ||||
| 	struct e1000_mac_info *mac = &hw->mac; | ||||
| 	s32 ret_val = E1000_SUCCESS; | ||||
| 	u32 in_msg = 0; | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * We only want to run this if there has been a rst asserted. | ||||
| 	 * in this case that could mean a link change, device reset, | ||||
| 	 * or a virtual function reset | ||||
| 	 */ | ||||
| 
 | ||||
| 	/* If we were hit with a reset or timeout drop the link */ | ||||
| 	if (!mbx->ops.check_for_rst(hw) || !mbx->timeout) | ||||
| 		mac->get_link_status = true; | ||||
| 
 | ||||
| 	if (!mac->get_link_status) | ||||
| 		goto out; | ||||
| 
 | ||||
| 	/* if link status is down no point in checking to see if pf is up */ | ||||
| 	if (!(er32(STATUS) & E1000_STATUS_LU)) | ||||
| 		goto out; | ||||
| 
 | ||||
| 	/* if the read failed it could just be a mailbox collision, best wait
 | ||||
| 	 * until we are called again and don't report an error */ | ||||
| 	if (mbx->ops.read(hw, &in_msg, 1)) | ||||
| 		goto out; | ||||
| 
 | ||||
| 	/* if incoming message isn't clear to send we are waiting on response */ | ||||
| 	if (!(in_msg & E1000_VT_MSGTYPE_CTS)) { | ||||
| 		/* message is not CTS and is NACK we must have lost CTS status */ | ||||
| 		if (in_msg & E1000_VT_MSGTYPE_NACK) | ||||
| 			ret_val = -E1000_ERR_MAC_INIT; | ||||
| 		goto out; | ||||
| 	} | ||||
| 
 | ||||
| 	/* the pf is talking, if we timed out in the past we reinit */ | ||||
| 	if (!mbx->timeout) { | ||||
| 		ret_val = -E1000_ERR_MAC_INIT; | ||||
| 		goto out; | ||||
| 	} | ||||
| 
 | ||||
| 	/* if we passed all the tests above then the link is up and we no
 | ||||
| 	 * longer need to check for link */ | ||||
| 	mac->get_link_status = false; | ||||
| 
 | ||||
| out: | ||||
| 	return ret_val; | ||||
| } | ||||
| 
 | ||||
							
								
								
									
										266
									
								
								drivers/net/ethernet/intel/igbvf/vf.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										266
									
								
								drivers/net/ethernet/intel/igbvf/vf.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,266 @@ | |||
| /*******************************************************************************
 | ||||
| 
 | ||||
|   Intel(R) 82576 Virtual Function Linux driver | ||||
|   Copyright(c) 2009 - 2012 Intel Corporation. | ||||
| 
 | ||||
|   This program is free software; you can redistribute it and/or modify it | ||||
|   under the terms and conditions of the GNU General Public License, | ||||
|   version 2, as published by the Free Software Foundation. | ||||
| 
 | ||||
|   This program is distributed in the hope it will be useful, but WITHOUT | ||||
|   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||||
|   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for | ||||
|   more details. | ||||
| 
 | ||||
|   You should have received a copy of the GNU General Public License along with | ||||
|   this program; if not, write to the Free Software Foundation, Inc., | ||||
|   51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. | ||||
| 
 | ||||
|   The full GNU General Public License is included in this distribution in | ||||
|   the file called "COPYING". | ||||
| 
 | ||||
|   Contact Information: | ||||
|   e1000-devel Mailing List <e1000-devel@lists.sourceforge.net> | ||||
|   Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 | ||||
| 
 | ||||
| *******************************************************************************/ | ||||
| 
 | ||||
| #ifndef _E1000_VF_H_ | ||||
| #define _E1000_VF_H_ | ||||
| 
 | ||||
| #include <linux/pci.h> | ||||
| #include <linux/delay.h> | ||||
| #include <linux/interrupt.h> | ||||
| #include <linux/if_ether.h> | ||||
| 
 | ||||
| #include "regs.h" | ||||
| #include "defines.h" | ||||
| 
 | ||||
| struct e1000_hw; | ||||
| 
 | ||||
| #define E1000_DEV_ID_82576_VF                 0x10CA | ||||
| #define E1000_DEV_ID_I350_VF                  0x1520 | ||||
| #define E1000_REVISION_0 0 | ||||
| #define E1000_REVISION_1 1 | ||||
| #define E1000_REVISION_2 2 | ||||
| #define E1000_REVISION_3 3 | ||||
| #define E1000_REVISION_4 4 | ||||
| 
 | ||||
| #define E1000_FUNC_0     0 | ||||
| #define E1000_FUNC_1     1 | ||||
| 
 | ||||
| /*
 | ||||
|  * Receive Address Register Count | ||||
|  * Number of high/low register pairs in the RAR.  The RAR (Receive Address | ||||
|  * Registers) holds the directed and multicast addresses that we monitor. | ||||
|  * These entries are also used for MAC-based filtering. | ||||
|  */ | ||||
| #define E1000_RAR_ENTRIES_VF      1 | ||||
| 
 | ||||
| /* Receive Descriptor - Advanced */ | ||||
| union e1000_adv_rx_desc { | ||||
| 	struct { | ||||
| 		u64 pkt_addr;             /* Packet buffer address */ | ||||
| 		u64 hdr_addr;             /* Header buffer address */ | ||||
| 	} read; | ||||
| 	struct { | ||||
| 		struct { | ||||
| 			union { | ||||
| 				u32 data; | ||||
| 				struct { | ||||
| 					u16 pkt_info; /* RSS/Packet type */ | ||||
| 					u16 hdr_info; /* Split Header,
 | ||||
| 					               * hdr buffer length */ | ||||
| 				} hs_rss; | ||||
| 			} lo_dword; | ||||
| 			union { | ||||
| 				u32 rss;          /* RSS Hash */ | ||||
| 				struct { | ||||
| 					u16 ip_id;    /* IP id */ | ||||
| 					u16 csum;     /* Packet Checksum */ | ||||
| 				} csum_ip; | ||||
| 			} hi_dword; | ||||
| 		} lower; | ||||
| 		struct { | ||||
| 			u32 status_error;     /* ext status/error */ | ||||
| 			u16 length;           /* Packet length */ | ||||
| 			u16 vlan;             /* VLAN tag */ | ||||
| 		} upper; | ||||
| 	} wb;  /* writeback */ | ||||
| }; | ||||
| 
 | ||||
| #define E1000_RXDADV_HDRBUFLEN_MASK      0x7FE0 | ||||
| #define E1000_RXDADV_HDRBUFLEN_SHIFT     5 | ||||
| 
 | ||||
| /* Transmit Descriptor - Advanced */ | ||||
| union e1000_adv_tx_desc { | ||||
| 	struct { | ||||
| 		u64 buffer_addr;    /* Address of descriptor's data buf */ | ||||
| 		u32 cmd_type_len; | ||||
| 		u32 olinfo_status; | ||||
| 	} read; | ||||
| 	struct { | ||||
| 		u64 rsvd;       /* Reserved */ | ||||
| 		u32 nxtseq_seed; | ||||
| 		u32 status; | ||||
| 	} wb; | ||||
| }; | ||||
| 
 | ||||
| /* Adv Transmit Descriptor Config Masks */ | ||||
| #define E1000_ADVTXD_DTYP_CTXT    0x00200000 /* Advanced Context Descriptor */ | ||||
| #define E1000_ADVTXD_DTYP_DATA    0x00300000 /* Advanced Data Descriptor */ | ||||
| #define E1000_ADVTXD_DCMD_EOP     0x01000000 /* End of Packet */ | ||||
| #define E1000_ADVTXD_DCMD_IFCS    0x02000000 /* Insert FCS (Ethernet CRC) */ | ||||
| #define E1000_ADVTXD_DCMD_RS      0x08000000 /* Report Status */ | ||||
| #define E1000_ADVTXD_DCMD_DEXT    0x20000000 /* Descriptor extension (1=Adv) */ | ||||
| #define E1000_ADVTXD_DCMD_VLE     0x40000000 /* VLAN pkt enable */ | ||||
| #define E1000_ADVTXD_DCMD_TSE     0x80000000 /* TCP Seg enable */ | ||||
| #define E1000_ADVTXD_PAYLEN_SHIFT    14 /* Adv desc PAYLEN shift */ | ||||
| 
 | ||||
| /* Context descriptors */ | ||||
| struct e1000_adv_tx_context_desc { | ||||
| 	u32 vlan_macip_lens; | ||||
| 	u32 seqnum_seed; | ||||
| 	u32 type_tucmd_mlhl; | ||||
| 	u32 mss_l4len_idx; | ||||
| }; | ||||
| 
 | ||||
| #define E1000_ADVTXD_MACLEN_SHIFT    9  /* Adv ctxt desc mac len shift */ | ||||
| #define E1000_ADVTXD_TUCMD_IPV4    0x00000400  /* IP Packet Type: 1=IPv4 */ | ||||
| #define E1000_ADVTXD_TUCMD_L4T_TCP 0x00000800  /* L4 Packet TYPE of TCP */ | ||||
| #define E1000_ADVTXD_L4LEN_SHIFT     8  /* Adv ctxt L4LEN shift */ | ||||
| #define E1000_ADVTXD_MSS_SHIFT      16  /* Adv ctxt MSS shift */ | ||||
| 
 | ||||
| enum e1000_mac_type { | ||||
| 	e1000_undefined = 0, | ||||
| 	e1000_vfadapt, | ||||
| 	e1000_vfadapt_i350, | ||||
| 	e1000_num_macs  /* List is 1-based, so subtract 1 for true count. */ | ||||
| }; | ||||
| 
 | ||||
| struct e1000_vf_stats { | ||||
| 	u64 base_gprc; | ||||
| 	u64 base_gptc; | ||||
| 	u64 base_gorc; | ||||
| 	u64 base_gotc; | ||||
| 	u64 base_mprc; | ||||
| 	u64 base_gotlbc; | ||||
| 	u64 base_gptlbc; | ||||
| 	u64 base_gorlbc; | ||||
| 	u64 base_gprlbc; | ||||
| 
 | ||||
| 	u32 last_gprc; | ||||
| 	u32 last_gptc; | ||||
| 	u32 last_gorc; | ||||
| 	u32 last_gotc; | ||||
| 	u32 last_mprc; | ||||
| 	u32 last_gotlbc; | ||||
| 	u32 last_gptlbc; | ||||
| 	u32 last_gorlbc; | ||||
| 	u32 last_gprlbc; | ||||
| 
 | ||||
| 	u64 gprc; | ||||
| 	u64 gptc; | ||||
| 	u64 gorc; | ||||
| 	u64 gotc; | ||||
| 	u64 mprc; | ||||
| 	u64 gotlbc; | ||||
| 	u64 gptlbc; | ||||
| 	u64 gorlbc; | ||||
| 	u64 gprlbc; | ||||
| }; | ||||
| 
 | ||||
| #include "mbx.h" | ||||
| 
 | ||||
| struct e1000_mac_operations { | ||||
| 	/* Function pointers for the MAC. */ | ||||
| 	s32  (*init_params)(struct e1000_hw *); | ||||
| 	s32  (*check_for_link)(struct e1000_hw *); | ||||
| 	void (*clear_vfta)(struct e1000_hw *); | ||||
| 	s32  (*get_bus_info)(struct e1000_hw *); | ||||
| 	s32  (*get_link_up_info)(struct e1000_hw *, u16 *, u16 *); | ||||
| 	void (*update_mc_addr_list)(struct e1000_hw *, u8 *, u32, u32, u32); | ||||
| 	s32  (*reset_hw)(struct e1000_hw *); | ||||
| 	s32  (*init_hw)(struct e1000_hw *); | ||||
| 	s32  (*setup_link)(struct e1000_hw *); | ||||
| 	void (*write_vfta)(struct e1000_hw *, u32, u32); | ||||
| 	void (*mta_set)(struct e1000_hw *, u32); | ||||
| 	void (*rar_set)(struct e1000_hw *, u8*, u32); | ||||
| 	s32  (*read_mac_addr)(struct e1000_hw *); | ||||
| 	s32  (*set_vfta)(struct e1000_hw *, u16, bool); | ||||
| }; | ||||
| 
 | ||||
| struct e1000_mac_info { | ||||
| 	struct e1000_mac_operations ops; | ||||
| 	u8 addr[6]; | ||||
| 	u8 perm_addr[6]; | ||||
| 
 | ||||
| 	enum e1000_mac_type type; | ||||
| 
 | ||||
| 	u16 mta_reg_count; | ||||
| 	u16 rar_entry_count; | ||||
| 
 | ||||
| 	bool get_link_status; | ||||
| }; | ||||
| 
 | ||||
| struct e1000_mbx_operations { | ||||
| 	s32 (*init_params)(struct e1000_hw *hw); | ||||
| 	s32 (*read)(struct e1000_hw *, u32 *, u16); | ||||
| 	s32 (*write)(struct e1000_hw *, u32 *, u16); | ||||
| 	s32 (*read_posted)(struct e1000_hw *, u32 *, u16); | ||||
| 	s32 (*write_posted)(struct e1000_hw *, u32 *, u16); | ||||
| 	s32 (*check_for_msg)(struct e1000_hw *); | ||||
| 	s32 (*check_for_ack)(struct e1000_hw *); | ||||
| 	s32 (*check_for_rst)(struct e1000_hw *); | ||||
| }; | ||||
| 
 | ||||
| struct e1000_mbx_stats { | ||||
| 	u32 msgs_tx; | ||||
| 	u32 msgs_rx; | ||||
| 
 | ||||
| 	u32 acks; | ||||
| 	u32 reqs; | ||||
| 	u32 rsts; | ||||
| }; | ||||
| 
 | ||||
| struct e1000_mbx_info { | ||||
| 	struct e1000_mbx_operations ops; | ||||
| 	struct e1000_mbx_stats stats; | ||||
| 	u32 timeout; | ||||
| 	u32 usec_delay; | ||||
| 	u16 size; | ||||
| }; | ||||
| 
 | ||||
| struct e1000_dev_spec_vf { | ||||
| 	u32 vf_number; | ||||
| 	u32 v2p_mailbox; | ||||
| }; | ||||
| 
 | ||||
| struct e1000_hw { | ||||
| 	void *back; | ||||
| 
 | ||||
| 	u8 __iomem *hw_addr; | ||||
| 	u8 __iomem *flash_address; | ||||
| 	unsigned long io_base; | ||||
| 
 | ||||
| 	struct e1000_mac_info  mac; | ||||
| 	struct e1000_mbx_info mbx; | ||||
| 
 | ||||
| 	union { | ||||
| 		struct e1000_dev_spec_vf vf; | ||||
| 	} dev_spec; | ||||
| 
 | ||||
| 	u16 device_id; | ||||
| 	u16 subsystem_vendor_id; | ||||
| 	u16 subsystem_device_id; | ||||
| 	u16 vendor_id; | ||||
| 
 | ||||
| 	u8  revision_id; | ||||
| }; | ||||
| 
 | ||||
| /* These functions must be implemented by drivers */ | ||||
| void e1000_rlpml_set_vf(struct e1000_hw *, u16); | ||||
| void e1000_init_function_pointers_vf(struct e1000_hw *hw); | ||||
| 
 | ||||
| 
 | ||||
| #endif /* _E1000_VF_H_ */ | ||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 awab228
						awab228