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/ixgbevf/Makefile
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								drivers/net/ethernet/intel/ixgbevf/Makefile
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,38 @@ | |||
| ################################################################################
 | ||||
| #
 | ||||
| # Intel 82599 Virtual Function 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
 | ||||
| #
 | ||||
| ################################################################################
 | ||||
| 
 | ||||
| #
 | ||||
| # Makefile for the Intel(R) 82599 VF ethernet driver
 | ||||
| #
 | ||||
| 
 | ||||
| obj-$(CONFIG_IXGBEVF) += ixgbevf.o | ||||
| 
 | ||||
| ixgbevf-objs := vf.o \
 | ||||
|                 mbx.o \
 | ||||
|                 ethtool.o \
 | ||||
|                 ixgbevf_main.o | ||||
| 
 | ||||
							
								
								
									
										298
									
								
								drivers/net/ethernet/intel/ixgbevf/defines.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										298
									
								
								drivers/net/ethernet/intel/ixgbevf/defines.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,298 @@ | |||
| /*******************************************************************************
 | ||||
| 
 | ||||
|   Intel 82599 Virtual Function 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 _IXGBEVF_DEFINES_H_ | ||||
| #define _IXGBEVF_DEFINES_H_ | ||||
| 
 | ||||
| /* Device IDs */ | ||||
| #define IXGBE_DEV_ID_82599_VF           0x10ED | ||||
| #define IXGBE_DEV_ID_X540_VF            0x1515 | ||||
| 
 | ||||
| #define IXGBE_VF_IRQ_CLEAR_MASK         7 | ||||
| #define IXGBE_VF_MAX_TX_QUEUES          8 | ||||
| #define IXGBE_VF_MAX_RX_QUEUES          8 | ||||
| 
 | ||||
| /* DCB define */ | ||||
| #define IXGBE_VF_MAX_TRAFFIC_CLASS	8 | ||||
| 
 | ||||
| /* Link speed */ | ||||
| typedef u32 ixgbe_link_speed; | ||||
| #define IXGBE_LINK_SPEED_1GB_FULL       0x0020 | ||||
| #define IXGBE_LINK_SPEED_10GB_FULL      0x0080 | ||||
| #define IXGBE_LINK_SPEED_100_FULL	0x0008 | ||||
| 
 | ||||
| #define IXGBE_CTRL_RST              0x04000000 /* Reset (SW) */ | ||||
| #define IXGBE_RXDCTL_ENABLE         0x02000000 /* Enable specific Rx Queue */ | ||||
| #define IXGBE_TXDCTL_ENABLE         0x02000000 /* Enable specific Tx Queue */ | ||||
| #define IXGBE_LINKS_UP              0x40000000 | ||||
| #define IXGBE_LINKS_SPEED_82599     0x30000000 | ||||
| #define IXGBE_LINKS_SPEED_10G_82599 0x30000000 | ||||
| #define IXGBE_LINKS_SPEED_1G_82599  0x20000000 | ||||
| #define IXGBE_LINKS_SPEED_100_82599 0x10000000 | ||||
| 
 | ||||
| /* Number of Transmit and Receive Descriptors must be a multiple of 8 */ | ||||
| #define IXGBE_REQ_TX_DESCRIPTOR_MULTIPLE  8 | ||||
| #define IXGBE_REQ_RX_DESCRIPTOR_MULTIPLE  8 | ||||
| #define IXGBE_REQ_TX_BUFFER_GRANULARITY   1024 | ||||
| 
 | ||||
| /* Interrupt Vector Allocation Registers */ | ||||
| #define IXGBE_IVAR_ALLOC_VAL    0x80 /* Interrupt Allocation valid */ | ||||
| 
 | ||||
| #define IXGBE_VF_INIT_TIMEOUT   200 /* Number of retries to clear RSTI */ | ||||
| 
 | ||||
| /* Receive Config masks */ | ||||
| #define IXGBE_RXCTRL_RXEN       0x00000001  /* Enable Receiver */ | ||||
| #define IXGBE_RXCTRL_DMBYPS     0x00000002  /* Descriptor Monitor Bypass */ | ||||
| #define IXGBE_RXDCTL_ENABLE     0x02000000  /* Enable specific Rx Queue */ | ||||
| #define IXGBE_RXDCTL_VME        0x40000000  /* VLAN mode enable */ | ||||
| #define IXGBE_RXDCTL_RLPMLMASK  0x00003FFF  /* Only supported on the X540 */ | ||||
| #define IXGBE_RXDCTL_RLPML_EN   0x00008000 | ||||
| 
 | ||||
| /* DCA Control */ | ||||
| #define IXGBE_DCA_TXCTRL_TX_WB_RO_EN (1 << 11) /* Tx Desc writeback RO bit */ | ||||
| 
 | ||||
| /* PSRTYPE bit definitions */ | ||||
| #define IXGBE_PSRTYPE_TCPHDR    0x00000010 | ||||
| #define IXGBE_PSRTYPE_UDPHDR    0x00000020 | ||||
| #define IXGBE_PSRTYPE_IPV4HDR   0x00000100 | ||||
| #define IXGBE_PSRTYPE_IPV6HDR   0x00000200 | ||||
| #define IXGBE_PSRTYPE_L2HDR     0x00001000 | ||||
| 
 | ||||
| /* SRRCTL bit definitions */ | ||||
| #define IXGBE_SRRCTL_BSIZEPKT_SHIFT     10     /* so many KBs */ | ||||
| #define IXGBE_SRRCTL_RDMTS_SHIFT        22 | ||||
| #define IXGBE_SRRCTL_RDMTS_MASK         0x01C00000 | ||||
| #define IXGBE_SRRCTL_DROP_EN            0x10000000 | ||||
| #define IXGBE_SRRCTL_BSIZEPKT_MASK      0x0000007F | ||||
| #define IXGBE_SRRCTL_BSIZEHDR_MASK      0x00003F00 | ||||
| #define IXGBE_SRRCTL_DESCTYPE_LEGACY    0x00000000 | ||||
| #define IXGBE_SRRCTL_DESCTYPE_ADV_ONEBUF 0x02000000 | ||||
| #define IXGBE_SRRCTL_DESCTYPE_HDR_SPLIT  0x04000000 | ||||
| #define IXGBE_SRRCTL_DESCTYPE_HDR_REPLICATION_LARGE_PKT 0x08000000 | ||||
| #define IXGBE_SRRCTL_DESCTYPE_HDR_SPLIT_ALWAYS 0x0A000000 | ||||
| #define IXGBE_SRRCTL_DESCTYPE_MASK      0x0E000000 | ||||
| 
 | ||||
| /* Receive Descriptor bit definitions */ | ||||
| #define IXGBE_RXD_STAT_DD         0x01    /* Descriptor Done */ | ||||
| #define IXGBE_RXD_STAT_EOP        0x02    /* End of Packet */ | ||||
| #define IXGBE_RXD_STAT_FLM        0x04    /* FDir Match */ | ||||
| #define IXGBE_RXD_STAT_VP         0x08    /* IEEE VLAN Packet */ | ||||
| #define IXGBE_RXDADV_NEXTP_MASK   0x000FFFF0 /* Next Descriptor Index */ | ||||
| #define IXGBE_RXDADV_NEXTP_SHIFT  0x00000004 | ||||
| #define IXGBE_RXD_STAT_UDPCS      0x10    /* UDP xsum calculated */ | ||||
| #define IXGBE_RXD_STAT_L4CS       0x20    /* L4 xsum calculated */ | ||||
| #define IXGBE_RXD_STAT_IPCS       0x40    /* IP xsum calculated */ | ||||
| #define IXGBE_RXD_STAT_PIF        0x80    /* passed in-exact filter */ | ||||
| #define IXGBE_RXD_STAT_CRCV       0x100   /* Speculative CRC Valid */ | ||||
| #define IXGBE_RXD_STAT_VEXT       0x200   /* 1st VLAN found */ | ||||
| #define IXGBE_RXD_STAT_UDPV       0x400   /* Valid UDP checksum */ | ||||
| #define IXGBE_RXD_STAT_DYNINT     0x800   /* Pkt caused INT via DYNINT */ | ||||
| #define IXGBE_RXD_STAT_TS         0x10000 /* Time Stamp */ | ||||
| #define IXGBE_RXD_STAT_SECP       0x20000 /* Security Processing */ | ||||
| #define IXGBE_RXD_STAT_LB         0x40000 /* Loopback Status */ | ||||
| #define IXGBE_RXD_STAT_ACK        0x8000  /* ACK Packet indication */ | ||||
| #define IXGBE_RXD_ERR_CE          0x01    /* CRC Error */ | ||||
| #define IXGBE_RXD_ERR_LE          0x02    /* Length Error */ | ||||
| #define IXGBE_RXD_ERR_PE          0x08    /* Packet Error */ | ||||
| #define IXGBE_RXD_ERR_OSE         0x10    /* Oversize Error */ | ||||
| #define IXGBE_RXD_ERR_USE         0x20    /* Undersize Error */ | ||||
| #define IXGBE_RXD_ERR_TCPE        0x40    /* TCP/UDP Checksum Error */ | ||||
| #define IXGBE_RXD_ERR_IPE         0x80    /* IP Checksum Error */ | ||||
| #define IXGBE_RXDADV_ERR_MASK     0xFFF00000 /* RDESC.ERRORS mask */ | ||||
| #define IXGBE_RXDADV_ERR_SHIFT    20         /* RDESC.ERRORS shift */ | ||||
| #define IXGBE_RXDADV_ERR_HBO      0x00800000 /*Header Buffer Overflow */ | ||||
| #define IXGBE_RXDADV_ERR_CE       0x01000000 /* CRC Error */ | ||||
| #define IXGBE_RXDADV_ERR_LE       0x02000000 /* Length Error */ | ||||
| #define IXGBE_RXDADV_ERR_PE       0x08000000 /* Packet Error */ | ||||
| #define IXGBE_RXDADV_ERR_OSE      0x10000000 /* Oversize Error */ | ||||
| #define IXGBE_RXDADV_ERR_USE      0x20000000 /* Undersize Error */ | ||||
| #define IXGBE_RXDADV_ERR_TCPE     0x40000000 /* TCP/UDP Checksum Error */ | ||||
| #define IXGBE_RXDADV_ERR_IPE      0x80000000 /* IP Checksum Error */ | ||||
| #define IXGBE_RXD_VLAN_ID_MASK    0x0FFF  /* VLAN ID is in lower 12 bits */ | ||||
| #define IXGBE_RXD_PRI_MASK        0xE000  /* Priority is in upper 3 bits */ | ||||
| #define IXGBE_RXD_PRI_SHIFT       13 | ||||
| #define IXGBE_RXD_CFI_MASK        0x1000  /* CFI is bit 12 */ | ||||
| #define IXGBE_RXD_CFI_SHIFT       12 | ||||
| 
 | ||||
| #define IXGBE_RXDADV_STAT_DD            IXGBE_RXD_STAT_DD  /* Done */ | ||||
| #define IXGBE_RXDADV_STAT_EOP           IXGBE_RXD_STAT_EOP /* End of Packet */ | ||||
| #define IXGBE_RXDADV_STAT_FLM           IXGBE_RXD_STAT_FLM /* FDir Match */ | ||||
| #define IXGBE_RXDADV_STAT_VP            IXGBE_RXD_STAT_VP  /* IEEE VLAN Pkt */ | ||||
| #define IXGBE_RXDADV_STAT_MASK          0x000FFFFF /* Stat/NEXTP: bit 0-19 */ | ||||
| #define IXGBE_RXDADV_STAT_FCEOFS        0x00000040 /* FCoE EOF/SOF Stat */ | ||||
| #define IXGBE_RXDADV_STAT_FCSTAT        0x00000030 /* FCoE Pkt Stat */ | ||||
| #define IXGBE_RXDADV_STAT_FCSTAT_NOMTCH 0x00000000 /* 00: No Ctxt Match */ | ||||
| #define IXGBE_RXDADV_STAT_FCSTAT_NODDP  0x00000010 /* 01: Ctxt w/o DDP */ | ||||
| #define IXGBE_RXDADV_STAT_FCSTAT_FCPRSP 0x00000020 /* 10: Recv. FCP_RSP */ | ||||
| #define IXGBE_RXDADV_STAT_FCSTAT_DDP    0x00000030 /* 11: Ctxt w/ DDP */ | ||||
| 
 | ||||
| #define IXGBE_RXDADV_RSSTYPE_MASK       0x0000000F | ||||
| #define IXGBE_RXDADV_PKTTYPE_MASK       0x0000FFF0 | ||||
| #define IXGBE_RXDADV_PKTTYPE_MASK_EX    0x0001FFF0 | ||||
| #define IXGBE_RXDADV_HDRBUFLEN_MASK     0x00007FE0 | ||||
| #define IXGBE_RXDADV_RSCCNT_MASK        0x001E0000 | ||||
| #define IXGBE_RXDADV_RSCCNT_SHIFT       17 | ||||
| #define IXGBE_RXDADV_HDRBUFLEN_SHIFT    5 | ||||
| #define IXGBE_RXDADV_SPLITHEADER_EN     0x00001000 | ||||
| #define IXGBE_RXDADV_SPH                0x8000 | ||||
| 
 | ||||
| #define IXGBE_RXD_ERR_FRAME_ERR_MASK ( \ | ||||
| 				      IXGBE_RXD_ERR_CE |  \ | ||||
| 				      IXGBE_RXD_ERR_LE |  \ | ||||
| 				      IXGBE_RXD_ERR_PE |  \ | ||||
| 				      IXGBE_RXD_ERR_OSE | \ | ||||
| 				      IXGBE_RXD_ERR_USE) | ||||
| 
 | ||||
| #define IXGBE_RXDADV_ERR_FRAME_ERR_MASK ( \ | ||||
| 					 IXGBE_RXDADV_ERR_CE |  \ | ||||
| 					 IXGBE_RXDADV_ERR_LE |  \ | ||||
| 					 IXGBE_RXDADV_ERR_PE |  \ | ||||
| 					 IXGBE_RXDADV_ERR_OSE | \ | ||||
| 					 IXGBE_RXDADV_ERR_USE) | ||||
| 
 | ||||
| #define IXGBE_TXD_POPTS_IXSM 0x01       /* Insert IP checksum */ | ||||
| #define IXGBE_TXD_POPTS_TXSM 0x02       /* Insert TCP/UDP checksum */ | ||||
| #define IXGBE_TXD_CMD_EOP    0x01000000 /* End of Packet */ | ||||
| #define IXGBE_TXD_CMD_IFCS   0x02000000 /* Insert FCS (Ethernet CRC) */ | ||||
| #define IXGBE_TXD_CMD_IC     0x04000000 /* Insert Checksum */ | ||||
| #define IXGBE_TXD_CMD_RS     0x08000000 /* Report Status */ | ||||
| #define IXGBE_TXD_CMD_DEXT   0x20000000 /* Descriptor extension (0 = legacy) */ | ||||
| #define IXGBE_TXD_CMD_VLE    0x40000000 /* Add VLAN tag */ | ||||
| #define IXGBE_TXD_STAT_DD    0x00000001 /* Descriptor Done */ | ||||
| #define IXGBE_TXD_CMD	     (IXGBE_TXD_CMD_EOP | IXGBE_TXD_CMD_RS) | ||||
| 
 | ||||
| /* Transmit Descriptor - Advanced */ | ||||
| union ixgbe_adv_tx_desc { | ||||
| 	struct { | ||||
| 		__le64 buffer_addr;      /* Address of descriptor's data buf */ | ||||
| 		__le32 cmd_type_len; | ||||
| 		__le32 olinfo_status; | ||||
| 	} read; | ||||
| 	struct { | ||||
| 		__le64 rsvd;       /* Reserved */ | ||||
| 		__le32 nxtseq_seed; | ||||
| 		__le32 status; | ||||
| 	} wb; | ||||
| }; | ||||
| 
 | ||||
| /* Receive Descriptor - Advanced */ | ||||
| union ixgbe_adv_rx_desc { | ||||
| 	struct { | ||||
| 		__le64 pkt_addr; /* Packet buffer address */ | ||||
| 		__le64 hdr_addr; /* Header buffer address */ | ||||
| 	} read; | ||||
| 	struct { | ||||
| 		struct { | ||||
| 			union { | ||||
| 				__le32 data; | ||||
| 				struct { | ||||
| 					__le16 pkt_info; /* RSS, Pkt type */ | ||||
| 					__le16 hdr_info; /* Splithdr, hdrlen */ | ||||
| 				} hs_rss; | ||||
| 			} lo_dword; | ||||
| 			union { | ||||
| 				__le32 rss; /* RSS Hash */ | ||||
| 				struct { | ||||
| 					__le16 ip_id; /* IP id */ | ||||
| 					__le16 csum; /* Packet Checksum */ | ||||
| 				} csum_ip; | ||||
| 			} hi_dword; | ||||
| 		} lower; | ||||
| 		struct { | ||||
| 			__le32 status_error; /* ext status/error */ | ||||
| 			__le16 length; /* Packet length */ | ||||
| 			__le16 vlan; /* VLAN tag */ | ||||
| 		} upper; | ||||
| 	} wb;  /* writeback */ | ||||
| }; | ||||
| 
 | ||||
| /* Context descriptors */ | ||||
| struct ixgbe_adv_tx_context_desc { | ||||
| 	__le32 vlan_macip_lens; | ||||
| 	__le32 seqnum_seed; | ||||
| 	__le32 type_tucmd_mlhl; | ||||
| 	__le32 mss_l4len_idx; | ||||
| }; | ||||
| 
 | ||||
| /* Adv Transmit Descriptor Config Masks */ | ||||
| #define IXGBE_ADVTXD_DTYP_MASK  0x00F00000 /* DTYP mask */ | ||||
| #define IXGBE_ADVTXD_DTYP_CTXT  0x00200000 /* Advanced Context Desc */ | ||||
| #define IXGBE_ADVTXD_DTYP_DATA  0x00300000 /* Advanced Data Descriptor */ | ||||
| #define IXGBE_ADVTXD_DCMD_EOP   IXGBE_TXD_CMD_EOP  /* End of Packet */ | ||||
| #define IXGBE_ADVTXD_DCMD_IFCS  IXGBE_TXD_CMD_IFCS /* Insert FCS */ | ||||
| #define IXGBE_ADVTXD_DCMD_RS    IXGBE_TXD_CMD_RS   /* Report Status */ | ||||
| #define IXGBE_ADVTXD_DCMD_DEXT  IXGBE_TXD_CMD_DEXT /* Desc ext (1=Adv) */ | ||||
| #define IXGBE_ADVTXD_DCMD_VLE   IXGBE_TXD_CMD_VLE  /* VLAN pkt enable */ | ||||
| #define IXGBE_ADVTXD_DCMD_TSE   0x80000000 /* TCP Seg enable */ | ||||
| #define IXGBE_ADVTXD_STAT_DD    IXGBE_TXD_STAT_DD  /* Descriptor Done */ | ||||
| #define IXGBE_ADVTXD_TUCMD_IPV4      0x00000400  /* IP Packet Type: 1=IPv4 */ | ||||
| #define IXGBE_ADVTXD_TUCMD_IPV6      0x00000000  /* IP Packet Type: 0=IPv6 */ | ||||
| #define IXGBE_ADVTXD_TUCMD_L4T_UDP   0x00000000  /* L4 Packet TYPE of UDP */ | ||||
| #define IXGBE_ADVTXD_TUCMD_L4T_TCP   0x00000800  /* L4 Packet TYPE of TCP */ | ||||
| #define IXGBE_ADVTXD_TUCMD_L4T_SCTP  0x00001000  /* L4 Packet TYPE of SCTP */ | ||||
| #define IXGBE_ADVTXD_IDX_SHIFT  4 /* Adv desc Index shift */ | ||||
| #define IXGBE_ADVTXD_CC		0x00000080 /* Check Context */ | ||||
| #define IXGBE_ADVTXD_POPTS_SHIFT      8  /* Adv desc POPTS shift */ | ||||
| #define IXGBE_ADVTXD_POPTS_IXSM (IXGBE_TXD_POPTS_IXSM << \ | ||||
| 				 IXGBE_ADVTXD_POPTS_SHIFT) | ||||
| #define IXGBE_ADVTXD_POPTS_TXSM (IXGBE_TXD_POPTS_TXSM << \ | ||||
| 				 IXGBE_ADVTXD_POPTS_SHIFT) | ||||
| #define IXGBE_ADVTXD_PAYLEN_SHIFT    14 /* Adv desc PAYLEN shift */ | ||||
| #define IXGBE_ADVTXD_MACLEN_SHIFT    9  /* Adv ctxt desc mac len shift */ | ||||
| #define IXGBE_ADVTXD_VLAN_SHIFT      16  /* Adv ctxt vlan tag shift */ | ||||
| #define IXGBE_ADVTXD_L4LEN_SHIFT     8  /* Adv ctxt L4LEN shift */ | ||||
| #define IXGBE_ADVTXD_MSS_SHIFT       16  /* Adv ctxt MSS shift */ | ||||
| 
 | ||||
| /* Interrupt register bitmasks */ | ||||
| 
 | ||||
| #define IXGBE_EITR_CNT_WDIS     0x80000000 | ||||
| #define IXGBE_MAX_EITR		0x00000FF8 | ||||
| #define IXGBE_MIN_EITR		8 | ||||
| 
 | ||||
| /* Error Codes */ | ||||
| #define IXGBE_ERR_INVALID_MAC_ADDR              -1 | ||||
| #define IXGBE_ERR_RESET_FAILED                  -2 | ||||
| #define IXGBE_ERR_INVALID_ARGUMENT              -3 | ||||
| 
 | ||||
| /* Transmit Config masks */ | ||||
| #define IXGBE_TXDCTL_ENABLE		0x02000000 /* Ena specific Tx Queue */ | ||||
| #define IXGBE_TXDCTL_SWFLSH		0x04000000 /* Tx Desc. wr-bk flushing */ | ||||
| #define IXGBE_TXDCTL_WTHRESH_SHIFT	16	   /* shift to WTHRESH bits */ | ||||
| 
 | ||||
| #define IXGBE_DCA_RXCTRL_DESC_DCA_EN	(1 << 5)  /* Rx Desc enable */ | ||||
| #define IXGBE_DCA_RXCTRL_HEAD_DCA_EN	(1 << 6)  /* Rx Desc header ena */ | ||||
| #define IXGBE_DCA_RXCTRL_DATA_DCA_EN	(1 << 7)  /* Rx Desc payload ena */ | ||||
| #define IXGBE_DCA_RXCTRL_DESC_RRO_EN	(1 << 9)  /* Rx rd Desc Relax Order */ | ||||
| #define IXGBE_DCA_RXCTRL_DATA_WRO_EN	(1 << 13) /* Rx wr data Relax Order */ | ||||
| #define IXGBE_DCA_RXCTRL_HEAD_WRO_EN	(1 << 15) /* Rx wr header RO */ | ||||
| 
 | ||||
| #define IXGBE_DCA_TXCTRL_DESC_DCA_EN	(1 << 5)  /* DCA Tx Desc enable */ | ||||
| #define IXGBE_DCA_TXCTRL_DESC_RRO_EN	(1 << 9)  /* Tx rd Desc Relax Order */ | ||||
| #define IXGBE_DCA_TXCTRL_DESC_WRO_EN	(1 << 11) /* Tx Desc writeback RO bit */ | ||||
| #define IXGBE_DCA_TXCTRL_DATA_RRO_EN	(1 << 13) /* Tx rd data Relax Order */ | ||||
| 
 | ||||
| #endif /* _IXGBEVF_DEFINES_H_ */ | ||||
							
								
								
									
										817
									
								
								drivers/net/ethernet/intel/ixgbevf/ethtool.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										817
									
								
								drivers/net/ethernet/intel/ixgbevf/ethtool.c
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,817 @@ | |||
| /*******************************************************************************
 | ||||
| 
 | ||||
|   Intel 82599 Virtual Function 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: | ||||
|   e1000-devel Mailing List <e1000-devel@lists.sourceforge.net> | ||||
|   Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 | ||||
| 
 | ||||
| *******************************************************************************/ | ||||
| 
 | ||||
| /* ethtool support for ixgbevf */ | ||||
| 
 | ||||
| #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||||
| 
 | ||||
| #include <linux/types.h> | ||||
| #include <linux/module.h> | ||||
| #include <linux/slab.h> | ||||
| #include <linux/pci.h> | ||||
| #include <linux/netdevice.h> | ||||
| #include <linux/ethtool.h> | ||||
| #include <linux/vmalloc.h> | ||||
| #include <linux/if_vlan.h> | ||||
| #include <linux/uaccess.h> | ||||
| 
 | ||||
| #include "ixgbevf.h" | ||||
| 
 | ||||
| #define IXGBE_ALL_RAR_ENTRIES 16 | ||||
| 
 | ||||
| struct ixgbe_stats { | ||||
| 	char stat_string[ETH_GSTRING_LEN]; | ||||
| 	struct { | ||||
| 		int sizeof_stat; | ||||
| 		int stat_offset; | ||||
| 		int base_stat_offset; | ||||
| 		int saved_reset_offset; | ||||
| 	}; | ||||
| }; | ||||
| 
 | ||||
| #define IXGBEVF_STAT(m, b, r) { \ | ||||
| 	.sizeof_stat = FIELD_SIZEOF(struct ixgbevf_adapter, m), \ | ||||
| 	.stat_offset = offsetof(struct ixgbevf_adapter, m), \ | ||||
| 	.base_stat_offset = offsetof(struct ixgbevf_adapter, b), \ | ||||
| 	.saved_reset_offset = offsetof(struct ixgbevf_adapter, r) \ | ||||
| } | ||||
| 
 | ||||
| #define IXGBEVF_ZSTAT(m) { \ | ||||
| 	.sizeof_stat = FIELD_SIZEOF(struct ixgbevf_adapter, m), \ | ||||
| 	.stat_offset = offsetof(struct ixgbevf_adapter, m), \ | ||||
| 	.base_stat_offset = -1, \ | ||||
| 	.saved_reset_offset = -1 \ | ||||
| } | ||||
| 
 | ||||
| static const struct ixgbe_stats ixgbe_gstrings_stats[] = { | ||||
| 	{"rx_packets", IXGBEVF_STAT(stats.vfgprc, stats.base_vfgprc, | ||||
| 				    stats.saved_reset_vfgprc)}, | ||||
| 	{"tx_packets", IXGBEVF_STAT(stats.vfgptc, stats.base_vfgptc, | ||||
| 				    stats.saved_reset_vfgptc)}, | ||||
| 	{"rx_bytes", IXGBEVF_STAT(stats.vfgorc, stats.base_vfgorc, | ||||
| 				  stats.saved_reset_vfgorc)}, | ||||
| 	{"tx_bytes", IXGBEVF_STAT(stats.vfgotc, stats.base_vfgotc, | ||||
| 				  stats.saved_reset_vfgotc)}, | ||||
| 	{"tx_busy", IXGBEVF_ZSTAT(tx_busy)}, | ||||
| 	{"tx_restart_queue", IXGBEVF_ZSTAT(restart_queue)}, | ||||
| 	{"tx_timeout_count", IXGBEVF_ZSTAT(tx_timeout_count)}, | ||||
| 	{"multicast", IXGBEVF_STAT(stats.vfmprc, stats.base_vfmprc, | ||||
| 				   stats.saved_reset_vfmprc)}, | ||||
| 	{"rx_csum_offload_errors", IXGBEVF_ZSTAT(hw_csum_rx_error)}, | ||||
| #ifdef BP_EXTENDED_STATS | ||||
| 	{"rx_bp_poll_yield", IXGBEVF_ZSTAT(bp_rx_yields)}, | ||||
| 	{"rx_bp_cleaned", IXGBEVF_ZSTAT(bp_rx_cleaned)}, | ||||
| 	{"rx_bp_misses", IXGBEVF_ZSTAT(bp_rx_missed)}, | ||||
| 	{"tx_bp_napi_yield", IXGBEVF_ZSTAT(bp_tx_yields)}, | ||||
| 	{"tx_bp_cleaned", IXGBEVF_ZSTAT(bp_tx_cleaned)}, | ||||
| 	{"tx_bp_misses", IXGBEVF_ZSTAT(bp_tx_missed)}, | ||||
| #endif | ||||
| }; | ||||
| 
 | ||||
| #define IXGBE_QUEUE_STATS_LEN 0 | ||||
| #define IXGBE_GLOBAL_STATS_LEN	ARRAY_SIZE(ixgbe_gstrings_stats) | ||||
| 
 | ||||
| #define IXGBEVF_STATS_LEN (IXGBE_GLOBAL_STATS_LEN + IXGBE_QUEUE_STATS_LEN) | ||||
| static const char ixgbe_gstrings_test[][ETH_GSTRING_LEN] = { | ||||
| 	"Register test  (offline)", | ||||
| 	"Link test   (on/offline)" | ||||
| }; | ||||
| #define IXGBE_TEST_LEN (sizeof(ixgbe_gstrings_test) / ETH_GSTRING_LEN) | ||||
| 
 | ||||
| static int ixgbevf_get_settings(struct net_device *netdev, | ||||
| 				struct ethtool_cmd *ecmd) | ||||
| { | ||||
| 	struct ixgbevf_adapter *adapter = netdev_priv(netdev); | ||||
| 	struct ixgbe_hw *hw = &adapter->hw; | ||||
| 	u32 link_speed = 0; | ||||
| 	bool link_up; | ||||
| 
 | ||||
| 	ecmd->supported = SUPPORTED_10000baseT_Full; | ||||
| 	ecmd->autoneg = AUTONEG_DISABLE; | ||||
| 	ecmd->transceiver = XCVR_DUMMY1; | ||||
| 	ecmd->port = -1; | ||||
| 
 | ||||
| 	hw->mac.get_link_status = 1; | ||||
| 	hw->mac.ops.check_link(hw, &link_speed, &link_up, false); | ||||
| 
 | ||||
| 	if (link_up) { | ||||
| 		__u32 speed = SPEED_10000; | ||||
| 		switch (link_speed) { | ||||
| 		case IXGBE_LINK_SPEED_10GB_FULL: | ||||
| 			speed = SPEED_10000; | ||||
| 			break; | ||||
| 		case IXGBE_LINK_SPEED_1GB_FULL: | ||||
| 			speed = SPEED_1000; | ||||
| 			break; | ||||
| 		case IXGBE_LINK_SPEED_100_FULL: | ||||
| 			speed = SPEED_100; | ||||
| 			break; | ||||
| 		} | ||||
| 
 | ||||
| 		ethtool_cmd_speed_set(ecmd, speed); | ||||
| 		ecmd->duplex = DUPLEX_FULL; | ||||
| 	} else { | ||||
| 		ethtool_cmd_speed_set(ecmd, SPEED_UNKNOWN); | ||||
| 		ecmd->duplex = DUPLEX_UNKNOWN; | ||||
| 	} | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| static u32 ixgbevf_get_msglevel(struct net_device *netdev) | ||||
| { | ||||
| 	struct ixgbevf_adapter *adapter = netdev_priv(netdev); | ||||
| 	return adapter->msg_enable; | ||||
| } | ||||
| 
 | ||||
| static void ixgbevf_set_msglevel(struct net_device *netdev, u32 data) | ||||
| { | ||||
| 	struct ixgbevf_adapter *adapter = netdev_priv(netdev); | ||||
| 	adapter->msg_enable = data; | ||||
| } | ||||
| 
 | ||||
| #define IXGBE_GET_STAT(_A_, _R_) (_A_->stats._R_) | ||||
| 
 | ||||
| static int ixgbevf_get_regs_len(struct net_device *netdev) | ||||
| { | ||||
| #define IXGBE_REGS_LEN 45 | ||||
| 	return IXGBE_REGS_LEN * sizeof(u32); | ||||
| } | ||||
| 
 | ||||
| static void ixgbevf_get_regs(struct net_device *netdev, | ||||
| 			     struct ethtool_regs *regs, | ||||
| 			     void *p) | ||||
| { | ||||
| 	struct ixgbevf_adapter *adapter = netdev_priv(netdev); | ||||
| 	struct ixgbe_hw *hw = &adapter->hw; | ||||
| 	u32 *regs_buff = p; | ||||
| 	u32 regs_len = ixgbevf_get_regs_len(netdev); | ||||
| 	u8 i; | ||||
| 
 | ||||
| 	memset(p, 0, regs_len); | ||||
| 
 | ||||
| 	regs->version = (1 << 24) | hw->revision_id << 16 | hw->device_id; | ||||
| 
 | ||||
| 	/* General Registers */ | ||||
| 	regs_buff[0] = IXGBE_READ_REG(hw, IXGBE_VFCTRL); | ||||
| 	regs_buff[1] = IXGBE_READ_REG(hw, IXGBE_VFSTATUS); | ||||
| 	regs_buff[2] = IXGBE_READ_REG(hw, IXGBE_VFLINKS); | ||||
| 	regs_buff[3] = IXGBE_READ_REG(hw, IXGBE_VFRXMEMWRAP); | ||||
| 	regs_buff[4] = IXGBE_READ_REG(hw, IXGBE_VFFRTIMER); | ||||
| 
 | ||||
| 	/* Interrupt */ | ||||
| 	/* don't read EICR because it can clear interrupt causes, instead
 | ||||
| 	 * read EICS which is a shadow but doesn't clear EICR */ | ||||
| 	regs_buff[5] = IXGBE_READ_REG(hw, IXGBE_VTEICS); | ||||
| 	regs_buff[6] = IXGBE_READ_REG(hw, IXGBE_VTEICS); | ||||
| 	regs_buff[7] = IXGBE_READ_REG(hw, IXGBE_VTEIMS); | ||||
| 	regs_buff[8] = IXGBE_READ_REG(hw, IXGBE_VTEIMC); | ||||
| 	regs_buff[9] = IXGBE_READ_REG(hw, IXGBE_VTEIAC); | ||||
| 	regs_buff[10] = IXGBE_READ_REG(hw, IXGBE_VTEIAM); | ||||
| 	regs_buff[11] = IXGBE_READ_REG(hw, IXGBE_VTEITR(0)); | ||||
| 	regs_buff[12] = IXGBE_READ_REG(hw, IXGBE_VTIVAR(0)); | ||||
| 	regs_buff[13] = IXGBE_READ_REG(hw, IXGBE_VTIVAR_MISC); | ||||
| 
 | ||||
| 	/* Receive DMA */ | ||||
| 	for (i = 0; i < 2; i++) | ||||
| 		regs_buff[14 + i] = IXGBE_READ_REG(hw, IXGBE_VFRDBAL(i)); | ||||
| 	for (i = 0; i < 2; i++) | ||||
| 		regs_buff[16 + i] = IXGBE_READ_REG(hw, IXGBE_VFRDBAH(i)); | ||||
| 	for (i = 0; i < 2; i++) | ||||
| 		regs_buff[18 + i] = IXGBE_READ_REG(hw, IXGBE_VFRDLEN(i)); | ||||
| 	for (i = 0; i < 2; i++) | ||||
| 		regs_buff[20 + i] = IXGBE_READ_REG(hw, IXGBE_VFRDH(i)); | ||||
| 	for (i = 0; i < 2; i++) | ||||
| 		regs_buff[22 + i] = IXGBE_READ_REG(hw, IXGBE_VFRDT(i)); | ||||
| 	for (i = 0; i < 2; i++) | ||||
| 		regs_buff[24 + i] = IXGBE_READ_REG(hw, IXGBE_VFRXDCTL(i)); | ||||
| 	for (i = 0; i < 2; i++) | ||||
| 		regs_buff[26 + i] = IXGBE_READ_REG(hw, IXGBE_VFSRRCTL(i)); | ||||
| 
 | ||||
| 	/* Receive */ | ||||
| 	regs_buff[28] = IXGBE_READ_REG(hw, IXGBE_VFPSRTYPE); | ||||
| 
 | ||||
| 	/* Transmit */ | ||||
| 	for (i = 0; i < 2; i++) | ||||
| 		regs_buff[29 + i] = IXGBE_READ_REG(hw, IXGBE_VFTDBAL(i)); | ||||
| 	for (i = 0; i < 2; i++) | ||||
| 		regs_buff[31 + i] = IXGBE_READ_REG(hw, IXGBE_VFTDBAH(i)); | ||||
| 	for (i = 0; i < 2; i++) | ||||
| 		regs_buff[33 + i] = IXGBE_READ_REG(hw, IXGBE_VFTDLEN(i)); | ||||
| 	for (i = 0; i < 2; i++) | ||||
| 		regs_buff[35 + i] = IXGBE_READ_REG(hw, IXGBE_VFTDH(i)); | ||||
| 	for (i = 0; i < 2; i++) | ||||
| 		regs_buff[37 + i] = IXGBE_READ_REG(hw, IXGBE_VFTDT(i)); | ||||
| 	for (i = 0; i < 2; i++) | ||||
| 		regs_buff[39 + i] = IXGBE_READ_REG(hw, IXGBE_VFTXDCTL(i)); | ||||
| 	for (i = 0; i < 2; i++) | ||||
| 		regs_buff[41 + i] = IXGBE_READ_REG(hw, IXGBE_VFTDWBAL(i)); | ||||
| 	for (i = 0; i < 2; i++) | ||||
| 		regs_buff[43 + i] = IXGBE_READ_REG(hw, IXGBE_VFTDWBAH(i)); | ||||
| } | ||||
| 
 | ||||
| static void ixgbevf_get_drvinfo(struct net_device *netdev, | ||||
| 				struct ethtool_drvinfo *drvinfo) | ||||
| { | ||||
| 	struct ixgbevf_adapter *adapter = netdev_priv(netdev); | ||||
| 
 | ||||
| 	strlcpy(drvinfo->driver, ixgbevf_driver_name, sizeof(drvinfo->driver)); | ||||
| 	strlcpy(drvinfo->version, ixgbevf_driver_version, | ||||
| 		sizeof(drvinfo->version)); | ||||
| 	strlcpy(drvinfo->bus_info, pci_name(adapter->pdev), | ||||
| 		sizeof(drvinfo->bus_info)); | ||||
| } | ||||
| 
 | ||||
| static void ixgbevf_get_ringparam(struct net_device *netdev, | ||||
| 				  struct ethtool_ringparam *ring) | ||||
| { | ||||
| 	struct ixgbevf_adapter *adapter = netdev_priv(netdev); | ||||
| 
 | ||||
| 	ring->rx_max_pending = IXGBEVF_MAX_RXD; | ||||
| 	ring->tx_max_pending = IXGBEVF_MAX_TXD; | ||||
| 	ring->rx_pending = adapter->rx_ring_count; | ||||
| 	ring->tx_pending = adapter->tx_ring_count; | ||||
| } | ||||
| 
 | ||||
| static int ixgbevf_set_ringparam(struct net_device *netdev, | ||||
| 				 struct ethtool_ringparam *ring) | ||||
| { | ||||
| 	struct ixgbevf_adapter *adapter = netdev_priv(netdev); | ||||
| 	struct ixgbevf_ring *tx_ring = NULL, *rx_ring = NULL; | ||||
| 	u32 new_rx_count, new_tx_count; | ||||
| 	int i, err = 0; | ||||
| 
 | ||||
| 	if ((ring->rx_mini_pending) || (ring->rx_jumbo_pending)) | ||||
| 		return -EINVAL; | ||||
| 
 | ||||
| 	new_tx_count = max_t(u32, ring->tx_pending, IXGBEVF_MIN_TXD); | ||||
| 	new_tx_count = min_t(u32, new_tx_count, IXGBEVF_MAX_TXD); | ||||
| 	new_tx_count = ALIGN(new_tx_count, IXGBE_REQ_TX_DESCRIPTOR_MULTIPLE); | ||||
| 
 | ||||
| 	new_rx_count = max_t(u32, ring->rx_pending, IXGBEVF_MIN_RXD); | ||||
| 	new_rx_count = min_t(u32, new_rx_count, IXGBEVF_MAX_RXD); | ||||
| 	new_rx_count = ALIGN(new_rx_count, IXGBE_REQ_RX_DESCRIPTOR_MULTIPLE); | ||||
| 
 | ||||
| 	/* if nothing to do return success */ | ||||
| 	if ((new_tx_count == adapter->tx_ring_count) && | ||||
| 	    (new_rx_count == adapter->rx_ring_count)) | ||||
| 		return 0; | ||||
| 
 | ||||
| 	while (test_and_set_bit(__IXGBEVF_RESETTING, &adapter->state)) | ||||
| 		usleep_range(1000, 2000); | ||||
| 
 | ||||
| 	if (!netif_running(adapter->netdev)) { | ||||
| 		for (i = 0; i < adapter->num_tx_queues; i++) | ||||
| 			adapter->tx_ring[i]->count = new_tx_count; | ||||
| 		for (i = 0; i < adapter->num_rx_queues; i++) | ||||
| 			adapter->rx_ring[i]->count = new_rx_count; | ||||
| 		adapter->tx_ring_count = new_tx_count; | ||||
| 		adapter->rx_ring_count = new_rx_count; | ||||
| 		goto clear_reset; | ||||
| 	} | ||||
| 
 | ||||
| 	if (new_tx_count != adapter->tx_ring_count) { | ||||
| 		tx_ring = vmalloc(adapter->num_tx_queues * sizeof(*tx_ring)); | ||||
| 		if (!tx_ring) { | ||||
| 			err = -ENOMEM; | ||||
| 			goto clear_reset; | ||||
| 		} | ||||
| 
 | ||||
| 		for (i = 0; i < adapter->num_tx_queues; i++) { | ||||
| 			/* clone ring and setup updated count */ | ||||
| 			tx_ring[i] = *adapter->tx_ring[i]; | ||||
| 			tx_ring[i].count = new_tx_count; | ||||
| 			err = ixgbevf_setup_tx_resources(&tx_ring[i]); | ||||
| 			if (err) { | ||||
| 				while (i) { | ||||
| 					i--; | ||||
| 					ixgbevf_free_tx_resources(&tx_ring[i]); | ||||
| 				} | ||||
| 
 | ||||
| 				vfree(tx_ring); | ||||
| 				tx_ring = NULL; | ||||
| 
 | ||||
| 				goto clear_reset; | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	if (new_rx_count != adapter->rx_ring_count) { | ||||
| 		rx_ring = vmalloc(adapter->num_rx_queues * sizeof(*rx_ring)); | ||||
| 		if (!rx_ring) { | ||||
| 			err = -ENOMEM; | ||||
| 			goto clear_reset; | ||||
| 		} | ||||
| 
 | ||||
| 		for (i = 0; i < adapter->num_rx_queues; i++) { | ||||
| 			/* clone ring and setup updated count */ | ||||
| 			rx_ring[i] = *adapter->rx_ring[i]; | ||||
| 			rx_ring[i].count = new_rx_count; | ||||
| 			err = ixgbevf_setup_rx_resources(&rx_ring[i]); | ||||
| 			if (err) { | ||||
| 				while (i) { | ||||
| 					i--; | ||||
| 					ixgbevf_free_rx_resources(&rx_ring[i]); | ||||
| 				} | ||||
| 
 | ||||
| 				vfree(rx_ring); | ||||
| 				rx_ring = NULL; | ||||
| 
 | ||||
| 				goto clear_reset; | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	/* bring interface down to prepare for update */ | ||||
| 	ixgbevf_down(adapter); | ||||
| 
 | ||||
| 	/* Tx */ | ||||
| 	if (tx_ring) { | ||||
| 		for (i = 0; i < adapter->num_tx_queues; i++) { | ||||
| 			ixgbevf_free_tx_resources(adapter->tx_ring[i]); | ||||
| 			*adapter->tx_ring[i] = tx_ring[i]; | ||||
| 		} | ||||
| 		adapter->tx_ring_count = new_tx_count; | ||||
| 
 | ||||
| 		vfree(tx_ring); | ||||
| 		tx_ring = NULL; | ||||
| 	} | ||||
| 
 | ||||
| 	/* Rx */ | ||||
| 	if (rx_ring) { | ||||
| 		for (i = 0; i < adapter->num_rx_queues; i++) { | ||||
| 			ixgbevf_free_rx_resources(adapter->rx_ring[i]); | ||||
| 			*adapter->rx_ring[i] = rx_ring[i]; | ||||
| 		} | ||||
| 		adapter->rx_ring_count = new_rx_count; | ||||
| 
 | ||||
| 		vfree(rx_ring); | ||||
| 		rx_ring = NULL; | ||||
| 	} | ||||
| 
 | ||||
| 	/* restore interface using new values */ | ||||
| 	ixgbevf_up(adapter); | ||||
| 
 | ||||
| clear_reset: | ||||
| 	/* free Tx resources if Rx error is encountered */ | ||||
| 	if (tx_ring) { | ||||
| 		for (i = 0; i < adapter->num_tx_queues; i++) | ||||
| 			ixgbevf_free_tx_resources(&tx_ring[i]); | ||||
| 		vfree(tx_ring); | ||||
| 	} | ||||
| 
 | ||||
| 	clear_bit(__IXGBEVF_RESETTING, &adapter->state); | ||||
| 	return err; | ||||
| } | ||||
| 
 | ||||
| static int ixgbevf_get_sset_count(struct net_device *dev, int stringset) | ||||
| { | ||||
|        switch (stringset) { | ||||
|        case ETH_SS_TEST: | ||||
| 	       return IXGBE_TEST_LEN; | ||||
|        case ETH_SS_STATS: | ||||
| 	       return IXGBE_GLOBAL_STATS_LEN; | ||||
|        default: | ||||
| 	       return -EINVAL; | ||||
|        } | ||||
| } | ||||
| 
 | ||||
| static void ixgbevf_get_ethtool_stats(struct net_device *netdev, | ||||
| 				      struct ethtool_stats *stats, u64 *data) | ||||
| { | ||||
| 	struct ixgbevf_adapter *adapter = netdev_priv(netdev); | ||||
| 	char *base = (char *) adapter; | ||||
| 	int i; | ||||
| #ifdef BP_EXTENDED_STATS | ||||
| 	u64 rx_yields = 0, rx_cleaned = 0, rx_missed = 0, | ||||
| 	    tx_yields = 0, tx_cleaned = 0, tx_missed = 0; | ||||
| 
 | ||||
| 	for (i = 0; i < adapter->num_rx_queues; i++) { | ||||
| 		rx_yields += adapter->rx_ring[i]->stats.yields; | ||||
| 		rx_cleaned += adapter->rx_ring[i]->stats.cleaned; | ||||
| 		rx_yields += adapter->rx_ring[i]->stats.yields; | ||||
| 	} | ||||
| 
 | ||||
| 	for (i = 0; i < adapter->num_tx_queues; i++) { | ||||
| 		tx_yields += adapter->tx_ring[i]->stats.yields; | ||||
| 		tx_cleaned += adapter->tx_ring[i]->stats.cleaned; | ||||
| 		tx_yields += adapter->tx_ring[i]->stats.yields; | ||||
| 	} | ||||
| 
 | ||||
| 	adapter->bp_rx_yields = rx_yields; | ||||
| 	adapter->bp_rx_cleaned = rx_cleaned; | ||||
| 	adapter->bp_rx_missed = rx_missed; | ||||
| 
 | ||||
| 	adapter->bp_tx_yields = tx_yields; | ||||
| 	adapter->bp_tx_cleaned = tx_cleaned; | ||||
| 	adapter->bp_tx_missed = tx_missed; | ||||
| #endif | ||||
| 
 | ||||
| 	ixgbevf_update_stats(adapter); | ||||
| 	for (i = 0; i < IXGBE_GLOBAL_STATS_LEN; i++) { | ||||
| 		char *p = base + ixgbe_gstrings_stats[i].stat_offset; | ||||
| 		char *b = base + ixgbe_gstrings_stats[i].base_stat_offset; | ||||
| 		char *r = base + ixgbe_gstrings_stats[i].saved_reset_offset; | ||||
| 
 | ||||
| 		if (ixgbe_gstrings_stats[i].sizeof_stat == sizeof(u64)) { | ||||
| 			if (ixgbe_gstrings_stats[i].base_stat_offset >= 0) | ||||
| 				data[i] = *(u64 *)p - *(u64 *)b + *(u64 *)r; | ||||
| 			else | ||||
| 				data[i] = *(u64 *)p; | ||||
| 		} else { | ||||
| 			if (ixgbe_gstrings_stats[i].base_stat_offset >= 0) | ||||
| 				data[i] = *(u32 *)p - *(u32 *)b + *(u32 *)r; | ||||
| 			else | ||||
| 				data[i] = *(u32 *)p; | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| static void ixgbevf_get_strings(struct net_device *netdev, u32 stringset, | ||||
| 				u8 *data) | ||||
| { | ||||
| 	char *p = (char *)data; | ||||
| 	int i; | ||||
| 
 | ||||
| 	switch (stringset) { | ||||
| 	case ETH_SS_TEST: | ||||
| 		memcpy(data, *ixgbe_gstrings_test, | ||||
| 		       IXGBE_TEST_LEN * ETH_GSTRING_LEN); | ||||
| 		break; | ||||
| 	case ETH_SS_STATS: | ||||
| 		for (i = 0; i < IXGBE_GLOBAL_STATS_LEN; i++) { | ||||
| 			memcpy(p, ixgbe_gstrings_stats[i].stat_string, | ||||
| 			       ETH_GSTRING_LEN); | ||||
| 			p += ETH_GSTRING_LEN; | ||||
| 		} | ||||
| 		break; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| static int ixgbevf_link_test(struct ixgbevf_adapter *adapter, u64 *data) | ||||
| { | ||||
| 	struct ixgbe_hw *hw = &adapter->hw; | ||||
| 	bool link_up; | ||||
| 	u32 link_speed = 0; | ||||
| 	*data = 0; | ||||
| 
 | ||||
| 	hw->mac.ops.check_link(hw, &link_speed, &link_up, true); | ||||
| 	if (!link_up) | ||||
| 		*data = 1; | ||||
| 
 | ||||
| 	return *data; | ||||
| } | ||||
| 
 | ||||
| /* ethtool register test data */ | ||||
| struct ixgbevf_reg_test { | ||||
| 	u16 reg; | ||||
| 	u8  array_len; | ||||
| 	u8  test_type; | ||||
| 	u32 mask; | ||||
| 	u32 write; | ||||
| }; | ||||
| 
 | ||||
| /* In the hardware, registers are laid out either singly, in arrays
 | ||||
|  * spaced 0x40 bytes apart, or in contiguous tables.  We assume | ||||
|  * most tests take place on arrays or single registers (handled | ||||
|  * as a single-element array) and special-case the tables. | ||||
|  * Table tests are always pattern tests. | ||||
|  * | ||||
|  * We also make provision for some required setup steps by specifying | ||||
|  * registers to be written without any read-back testing. | ||||
|  */ | ||||
| 
 | ||||
| #define PATTERN_TEST	1 | ||||
| #define SET_READ_TEST	2 | ||||
| #define WRITE_NO_TEST	3 | ||||
| #define TABLE32_TEST	4 | ||||
| #define TABLE64_TEST_LO	5 | ||||
| #define TABLE64_TEST_HI	6 | ||||
| 
 | ||||
| /* default VF register test */ | ||||
| static const struct ixgbevf_reg_test reg_test_vf[] = { | ||||
| 	{ IXGBE_VFRDBAL(0), 2, PATTERN_TEST, 0xFFFFFF80, 0xFFFFFF80 }, | ||||
| 	{ IXGBE_VFRDBAH(0), 2, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF }, | ||||
| 	{ IXGBE_VFRDLEN(0), 2, PATTERN_TEST, 0x000FFF80, 0x000FFFFF }, | ||||
| 	{ IXGBE_VFRXDCTL(0), 2, WRITE_NO_TEST, 0, IXGBE_RXDCTL_ENABLE }, | ||||
| 	{ IXGBE_VFRDT(0), 2, PATTERN_TEST, 0x0000FFFF, 0x0000FFFF }, | ||||
| 	{ IXGBE_VFRXDCTL(0), 2, WRITE_NO_TEST, 0, 0 }, | ||||
| 	{ IXGBE_VFTDBAL(0), 2, PATTERN_TEST, 0xFFFFFF80, 0xFFFFFFFF }, | ||||
| 	{ IXGBE_VFTDBAH(0), 2, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF }, | ||||
| 	{ IXGBE_VFTDLEN(0), 2, PATTERN_TEST, 0x000FFF80, 0x000FFF80 }, | ||||
| 	{ .reg = 0 } | ||||
| }; | ||||
| 
 | ||||
| static const u32 register_test_patterns[] = { | ||||
| 	0x5A5A5A5A, 0xA5A5A5A5, 0x00000000, 0xFFFFFFFF | ||||
| }; | ||||
| 
 | ||||
| static bool reg_pattern_test(struct ixgbevf_adapter *adapter, u64 *data, | ||||
| 			     int reg, u32 mask, u32 write) | ||||
| { | ||||
| 	u32 pat, val, before; | ||||
| 
 | ||||
| 	if (IXGBE_REMOVED(adapter->hw.hw_addr)) { | ||||
| 		*data = 1; | ||||
| 		return true; | ||||
| 	} | ||||
| 	for (pat = 0; pat < ARRAY_SIZE(register_test_patterns); pat++) { | ||||
| 		before = ixgbevf_read_reg(&adapter->hw, reg); | ||||
| 		ixgbe_write_reg(&adapter->hw, reg, | ||||
| 				register_test_patterns[pat] & write); | ||||
| 		val = ixgbevf_read_reg(&adapter->hw, reg); | ||||
| 		if (val != (register_test_patterns[pat] & write & mask)) { | ||||
| 			hw_dbg(&adapter->hw, | ||||
| 			       "pattern test reg %04X failed: got 0x%08X expected 0x%08X\n", | ||||
| 			       reg, val, | ||||
| 			       register_test_patterns[pat] & write & mask); | ||||
| 			*data = reg; | ||||
| 			ixgbe_write_reg(&adapter->hw, reg, before); | ||||
| 			return true; | ||||
| 		} | ||||
| 		ixgbe_write_reg(&adapter->hw, reg, before); | ||||
| 	} | ||||
| 	return false; | ||||
| } | ||||
| 
 | ||||
| static bool reg_set_and_check(struct ixgbevf_adapter *adapter, u64 *data, | ||||
| 			      int reg, u32 mask, u32 write) | ||||
| { | ||||
| 	u32 val, before; | ||||
| 
 | ||||
| 	if (IXGBE_REMOVED(adapter->hw.hw_addr)) { | ||||
| 		*data = 1; | ||||
| 		return true; | ||||
| 	} | ||||
| 	before = ixgbevf_read_reg(&adapter->hw, reg); | ||||
| 	ixgbe_write_reg(&adapter->hw, reg, write & mask); | ||||
| 	val = ixgbevf_read_reg(&adapter->hw, reg); | ||||
| 	if ((write & mask) != (val & mask)) { | ||||
| 		pr_err("set/check reg %04X test failed: got 0x%08X expected 0x%08X\n", | ||||
| 		       reg, (val & mask), write & mask); | ||||
| 		*data = reg; | ||||
| 		ixgbe_write_reg(&adapter->hw, reg, before); | ||||
| 		return true; | ||||
| 	} | ||||
| 	ixgbe_write_reg(&adapter->hw, reg, before); | ||||
| 	return false; | ||||
| } | ||||
| 
 | ||||
| static int ixgbevf_reg_test(struct ixgbevf_adapter *adapter, u64 *data) | ||||
| { | ||||
| 	const struct ixgbevf_reg_test *test; | ||||
| 	u32 i; | ||||
| 
 | ||||
| 	if (IXGBE_REMOVED(adapter->hw.hw_addr)) { | ||||
| 		dev_err(&adapter->pdev->dev, | ||||
| 			"Adapter removed - register test blocked\n"); | ||||
| 		*data = 1; | ||||
| 		return 1; | ||||
| 	} | ||||
| 	test = reg_test_vf; | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * Perform the register test, looping through the test table | ||||
| 	 * until we either fail or reach the null entry. | ||||
| 	 */ | ||||
| 	while (test->reg) { | ||||
| 		for (i = 0; i < test->array_len; i++) { | ||||
| 			bool b = false; | ||||
| 
 | ||||
| 			switch (test->test_type) { | ||||
| 			case PATTERN_TEST: | ||||
| 				b = reg_pattern_test(adapter, data, | ||||
| 						     test->reg + (i * 0x40), | ||||
| 						     test->mask, | ||||
| 						     test->write); | ||||
| 				break; | ||||
| 			case SET_READ_TEST: | ||||
| 				b = reg_set_and_check(adapter, data, | ||||
| 						      test->reg + (i * 0x40), | ||||
| 						      test->mask, | ||||
| 						      test->write); | ||||
| 				break; | ||||
| 			case WRITE_NO_TEST: | ||||
| 				ixgbe_write_reg(&adapter->hw, | ||||
| 						  test->reg + (i * 0x40), | ||||
| 						  test->write); | ||||
| 				break; | ||||
| 			case TABLE32_TEST: | ||||
| 				b = reg_pattern_test(adapter, data, | ||||
| 						     test->reg + (i * 4), | ||||
| 						     test->mask, | ||||
| 						     test->write); | ||||
| 				break; | ||||
| 			case TABLE64_TEST_LO: | ||||
| 				b = reg_pattern_test(adapter, data, | ||||
| 						     test->reg + (i * 8), | ||||
| 						     test->mask, | ||||
| 						     test->write); | ||||
| 				break; | ||||
| 			case TABLE64_TEST_HI: | ||||
| 				b = reg_pattern_test(adapter, data, | ||||
| 						     test->reg + 4 + (i * 8), | ||||
| 						     test->mask, | ||||
| 						     test->write); | ||||
| 				break; | ||||
| 			} | ||||
| 			if (b) | ||||
| 				return 1; | ||||
| 		} | ||||
| 		test++; | ||||
| 	} | ||||
| 
 | ||||
| 	*data = 0; | ||||
| 	return *data; | ||||
| } | ||||
| 
 | ||||
| static void ixgbevf_diag_test(struct net_device *netdev, | ||||
| 			      struct ethtool_test *eth_test, u64 *data) | ||||
| { | ||||
| 	struct ixgbevf_adapter *adapter = netdev_priv(netdev); | ||||
| 	bool if_running = netif_running(netdev); | ||||
| 
 | ||||
| 	if (IXGBE_REMOVED(adapter->hw.hw_addr)) { | ||||
| 		dev_err(&adapter->pdev->dev, | ||||
| 			"Adapter removed - test blocked\n"); | ||||
| 		data[0] = 1; | ||||
| 		data[1] = 1; | ||||
| 		eth_test->flags |= ETH_TEST_FL_FAILED; | ||||
| 		return; | ||||
| 	} | ||||
| 	set_bit(__IXGBEVF_TESTING, &adapter->state); | ||||
| 	if (eth_test->flags == ETH_TEST_FL_OFFLINE) { | ||||
| 		/* Offline tests */ | ||||
| 
 | ||||
| 		hw_dbg(&adapter->hw, "offline testing starting\n"); | ||||
| 
 | ||||
| 		/* Link test performed before hardware reset so autoneg doesn't
 | ||||
| 		 * interfere with test result */ | ||||
| 		if (ixgbevf_link_test(adapter, &data[1])) | ||||
| 			eth_test->flags |= ETH_TEST_FL_FAILED; | ||||
| 
 | ||||
| 		if (if_running) | ||||
| 			/* indicate we're in test mode */ | ||||
| 			dev_close(netdev); | ||||
| 		else | ||||
| 			ixgbevf_reset(adapter); | ||||
| 
 | ||||
| 		hw_dbg(&adapter->hw, "register testing starting\n"); | ||||
| 		if (ixgbevf_reg_test(adapter, &data[0])) | ||||
| 			eth_test->flags |= ETH_TEST_FL_FAILED; | ||||
| 
 | ||||
| 		ixgbevf_reset(adapter); | ||||
| 
 | ||||
| 		clear_bit(__IXGBEVF_TESTING, &adapter->state); | ||||
| 		if (if_running) | ||||
| 			dev_open(netdev); | ||||
| 	} else { | ||||
| 		hw_dbg(&adapter->hw, "online testing starting\n"); | ||||
| 		/* Online tests */ | ||||
| 		if (ixgbevf_link_test(adapter, &data[1])) | ||||
| 			eth_test->flags |= ETH_TEST_FL_FAILED; | ||||
| 
 | ||||
| 		/* Online tests aren't run; pass by default */ | ||||
| 		data[0] = 0; | ||||
| 
 | ||||
| 		clear_bit(__IXGBEVF_TESTING, &adapter->state); | ||||
| 	} | ||||
| 	msleep_interruptible(4 * 1000); | ||||
| } | ||||
| 
 | ||||
| static int ixgbevf_nway_reset(struct net_device *netdev) | ||||
| { | ||||
| 	struct ixgbevf_adapter *adapter = netdev_priv(netdev); | ||||
| 
 | ||||
| 	if (netif_running(netdev)) | ||||
| 		ixgbevf_reinit_locked(adapter); | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| static int ixgbevf_get_coalesce(struct net_device *netdev, | ||||
| 				struct ethtool_coalesce *ec) | ||||
| { | ||||
| 	struct ixgbevf_adapter *adapter = netdev_priv(netdev); | ||||
| 
 | ||||
| 	/* only valid if in constant ITR mode */ | ||||
| 	if (adapter->rx_itr_setting <= 1) | ||||
| 		ec->rx_coalesce_usecs = adapter->rx_itr_setting; | ||||
| 	else | ||||
| 		ec->rx_coalesce_usecs = adapter->rx_itr_setting >> 2; | ||||
| 
 | ||||
| 	/* if in mixed tx/rx queues per vector mode, report only rx settings */ | ||||
| 	if (adapter->q_vector[0]->tx.count && adapter->q_vector[0]->rx.count) | ||||
| 		return 0; | ||||
| 
 | ||||
| 	/* only valid if in constant ITR mode */ | ||||
| 	if (adapter->tx_itr_setting <= 1) | ||||
| 		ec->tx_coalesce_usecs = adapter->tx_itr_setting; | ||||
| 	else | ||||
| 		ec->tx_coalesce_usecs = adapter->tx_itr_setting >> 2; | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| static int ixgbevf_set_coalesce(struct net_device *netdev, | ||||
| 				struct ethtool_coalesce *ec) | ||||
| { | ||||
| 	struct ixgbevf_adapter *adapter = netdev_priv(netdev); | ||||
| 	struct ixgbevf_q_vector *q_vector; | ||||
| 	int num_vectors, i; | ||||
| 	u16 tx_itr_param, rx_itr_param; | ||||
| 
 | ||||
| 	/* don't accept tx specific changes if we've got mixed RxTx vectors */ | ||||
| 	if (adapter->q_vector[0]->tx.count && adapter->q_vector[0]->rx.count | ||||
| 	    && ec->tx_coalesce_usecs) | ||||
| 		return -EINVAL; | ||||
| 
 | ||||
| 
 | ||||
| 	if ((ec->rx_coalesce_usecs > (IXGBE_MAX_EITR >> 2)) || | ||||
| 	    (ec->tx_coalesce_usecs > (IXGBE_MAX_EITR >> 2))) | ||||
| 		return -EINVAL; | ||||
| 
 | ||||
| 	if (ec->rx_coalesce_usecs > 1) | ||||
| 		adapter->rx_itr_setting = ec->rx_coalesce_usecs << 2; | ||||
| 	else | ||||
| 		adapter->rx_itr_setting = ec->rx_coalesce_usecs; | ||||
| 
 | ||||
| 	if (adapter->rx_itr_setting == 1) | ||||
| 		rx_itr_param = IXGBE_20K_ITR; | ||||
| 	else | ||||
| 		rx_itr_param = adapter->rx_itr_setting; | ||||
| 
 | ||||
| 
 | ||||
| 	if (ec->tx_coalesce_usecs > 1) | ||||
| 		adapter->tx_itr_setting = ec->tx_coalesce_usecs << 2; | ||||
| 	else | ||||
| 		adapter->tx_itr_setting = ec->tx_coalesce_usecs; | ||||
| 
 | ||||
| 	if (adapter->tx_itr_setting == 1) | ||||
| 		tx_itr_param = IXGBE_10K_ITR; | ||||
| 	else | ||||
| 		tx_itr_param = adapter->tx_itr_setting; | ||||
| 
 | ||||
| 	num_vectors = adapter->num_msix_vectors - NON_Q_VECTORS; | ||||
| 
 | ||||
| 	for (i = 0; i < num_vectors; i++) { | ||||
| 		q_vector = adapter->q_vector[i]; | ||||
| 		if (q_vector->tx.count && !q_vector->rx.count) | ||||
| 			/* tx only */ | ||||
| 			q_vector->itr = tx_itr_param; | ||||
| 		else | ||||
| 			/* rx only or mixed */ | ||||
| 			q_vector->itr = rx_itr_param; | ||||
| 		ixgbevf_write_eitr(q_vector); | ||||
| 	} | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| static const struct ethtool_ops ixgbevf_ethtool_ops = { | ||||
| 	.get_settings           = ixgbevf_get_settings, | ||||
| 	.get_drvinfo            = ixgbevf_get_drvinfo, | ||||
| 	.get_regs_len           = ixgbevf_get_regs_len, | ||||
| 	.get_regs               = ixgbevf_get_regs, | ||||
| 	.nway_reset             = ixgbevf_nway_reset, | ||||
| 	.get_link               = ethtool_op_get_link, | ||||
| 	.get_ringparam          = ixgbevf_get_ringparam, | ||||
| 	.set_ringparam          = ixgbevf_set_ringparam, | ||||
| 	.get_msglevel           = ixgbevf_get_msglevel, | ||||
| 	.set_msglevel           = ixgbevf_set_msglevel, | ||||
| 	.self_test              = ixgbevf_diag_test, | ||||
| 	.get_sset_count         = ixgbevf_get_sset_count, | ||||
| 	.get_strings            = ixgbevf_get_strings, | ||||
| 	.get_ethtool_stats      = ixgbevf_get_ethtool_stats, | ||||
| 	.get_coalesce           = ixgbevf_get_coalesce, | ||||
| 	.set_coalesce           = ixgbevf_set_coalesce, | ||||
| }; | ||||
| 
 | ||||
| void ixgbevf_set_ethtool_ops(struct net_device *netdev) | ||||
| { | ||||
| 	netdev->ethtool_ops = &ixgbevf_ethtool_ops; | ||||
| } | ||||
							
								
								
									
										469
									
								
								drivers/net/ethernet/intel/ixgbevf/ixgbevf.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										469
									
								
								drivers/net/ethernet/intel/ixgbevf/ixgbevf.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,469 @@ | |||
| /*******************************************************************************
 | ||||
| 
 | ||||
|   Intel 82599 Virtual Function 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: | ||||
|   e1000-devel Mailing List <e1000-devel@lists.sourceforge.net> | ||||
|   Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 | ||||
| 
 | ||||
| *******************************************************************************/ | ||||
| 
 | ||||
| #ifndef _IXGBEVF_H_ | ||||
| #define _IXGBEVF_H_ | ||||
| 
 | ||||
| #include <linux/types.h> | ||||
| #include <linux/bitops.h> | ||||
| #include <linux/timer.h> | ||||
| #include <linux/io.h> | ||||
| #include <linux/netdevice.h> | ||||
| #include <linux/if_vlan.h> | ||||
| #include <linux/u64_stats_sync.h> | ||||
| 
 | ||||
| #include "vf.h" | ||||
| 
 | ||||
| #ifdef CONFIG_NET_RX_BUSY_POLL | ||||
| #include <net/busy_poll.h> | ||||
| #define BP_EXTENDED_STATS | ||||
| #endif | ||||
| 
 | ||||
| /* wrapper around a pointer to a socket buffer,
 | ||||
|  * so a DMA handle can be stored along with the buffer */ | ||||
| struct ixgbevf_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 ixgbevf_rx_buffer { | ||||
| 	struct sk_buff *skb; | ||||
| 	dma_addr_t dma; | ||||
| }; | ||||
| 
 | ||||
| struct ixgbevf_stats { | ||||
| 	u64 packets; | ||||
| 	u64 bytes; | ||||
| #ifdef BP_EXTENDED_STATS | ||||
| 	u64 yields; | ||||
| 	u64 misses; | ||||
| 	u64 cleaned; | ||||
| #endif | ||||
| }; | ||||
| 
 | ||||
| struct ixgbevf_tx_queue_stats { | ||||
| 	u64 restart_queue; | ||||
| 	u64 tx_busy; | ||||
| 	u64 tx_done_old; | ||||
| }; | ||||
| 
 | ||||
| struct ixgbevf_rx_queue_stats { | ||||
| 	u64 non_eop_descs; | ||||
| 	u64 alloc_rx_page_failed; | ||||
| 	u64 alloc_rx_buff_failed; | ||||
| 	u64 csum_err; | ||||
| }; | ||||
| 
 | ||||
| struct ixgbevf_ring { | ||||
| 	struct ixgbevf_ring *next; | ||||
| 	struct net_device *netdev; | ||||
| 	struct device *dev; | ||||
| 	void *desc;			/* descriptor ring memory */ | ||||
| 	dma_addr_t dma;			/* phys. address of descriptor ring */ | ||||
| 	unsigned int size;		/* length in bytes */ | ||||
| 	unsigned int count;		/* amount of descriptors */ | ||||
| 	unsigned int next_to_use; | ||||
| 	unsigned int next_to_clean; | ||||
| 
 | ||||
| 	union { | ||||
| 		struct ixgbevf_tx_buffer *tx_buffer_info; | ||||
| 		struct ixgbevf_rx_buffer *rx_buffer_info; | ||||
| 	}; | ||||
| 
 | ||||
| 	struct ixgbevf_stats stats; | ||||
| 	struct u64_stats_sync syncp; | ||||
| 	union { | ||||
| 		struct ixgbevf_tx_queue_stats tx_stats; | ||||
| 		struct ixgbevf_rx_queue_stats rx_stats; | ||||
| 	}; | ||||
| 
 | ||||
| 	u64 hw_csum_rx_error; | ||||
| 	u8 __iomem *tail; | ||||
| 
 | ||||
| 	u16 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 rx_buf_len; | ||||
| 	int queue_index; /* needed for multiqueue queue management */ | ||||
| }; | ||||
| 
 | ||||
| /* How many Rx Buffers do we bundle into one write to the hardware ? */ | ||||
| #define IXGBEVF_RX_BUFFER_WRITE	16	/* Must be power of 2 */ | ||||
| 
 | ||||
| #define MAX_RX_QUEUES IXGBE_VF_MAX_RX_QUEUES | ||||
| #define MAX_TX_QUEUES IXGBE_VF_MAX_TX_QUEUES | ||||
| 
 | ||||
| #define IXGBEVF_DEFAULT_TXD   1024 | ||||
| #define IXGBEVF_DEFAULT_RXD   512 | ||||
| #define IXGBEVF_MAX_TXD       4096 | ||||
| #define IXGBEVF_MIN_TXD       64 | ||||
| #define IXGBEVF_MAX_RXD       4096 | ||||
| #define IXGBEVF_MIN_RXD       64 | ||||
| 
 | ||||
| /* Supported Rx Buffer Sizes */ | ||||
| #define IXGBEVF_RXBUFFER_256   256    /* Used for packet split */ | ||||
| #define IXGBEVF_RXBUFFER_2K    2048 | ||||
| #define IXGBEVF_RXBUFFER_4K    4096 | ||||
| #define IXGBEVF_RXBUFFER_8K    8192 | ||||
| #define IXGBEVF_RXBUFFER_10K   10240 | ||||
| 
 | ||||
| #define IXGBEVF_RX_HDR_SIZE IXGBEVF_RXBUFFER_256 | ||||
| 
 | ||||
| #define MAXIMUM_ETHERNET_VLAN_SIZE (VLAN_ETH_FRAME_LEN + ETH_FCS_LEN) | ||||
| 
 | ||||
| #define IXGBE_TX_FLAGS_CSUM		(u32)(1) | ||||
| #define IXGBE_TX_FLAGS_VLAN		(u32)(1 << 1) | ||||
| #define IXGBE_TX_FLAGS_TSO		(u32)(1 << 2) | ||||
| #define IXGBE_TX_FLAGS_IPV4		(u32)(1 << 3) | ||||
| #define IXGBE_TX_FLAGS_VLAN_MASK	0xffff0000 | ||||
| #define IXGBE_TX_FLAGS_VLAN_PRIO_MASK	0x0000e000 | ||||
| #define IXGBE_TX_FLAGS_VLAN_SHIFT	16 | ||||
| 
 | ||||
| struct ixgbevf_ring_container { | ||||
| 	struct ixgbevf_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 */ | ||||
| 	u8 count;			/* total number of rings in vector */ | ||||
| 	u8 itr;				/* current ITR setting for ring */ | ||||
| }; | ||||
| 
 | ||||
| /* iterator for handling rings in ring container */ | ||||
| #define ixgbevf_for_each_ring(pos, head) \ | ||||
| 	for (pos = (head).ring; pos != NULL; pos = pos->next) | ||||
| 
 | ||||
| /* MAX_MSIX_Q_VECTORS of these are allocated,
 | ||||
|  * but we only use one per queue-specific vector. | ||||
|  */ | ||||
| struct ixgbevf_q_vector { | ||||
| 	struct ixgbevf_adapter *adapter; | ||||
| 	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 napi_struct napi; | ||||
| 	struct ixgbevf_ring_container rx, tx; | ||||
| 	char name[IFNAMSIZ + 9]; | ||||
| #ifdef CONFIG_NET_RX_BUSY_POLL | ||||
| 	unsigned int state; | ||||
| #define IXGBEVF_QV_STATE_IDLE		0 | ||||
| #define IXGBEVF_QV_STATE_NAPI		1    /* NAPI owns this QV */ | ||||
| #define IXGBEVF_QV_STATE_POLL		2    /* poll owns this QV */ | ||||
| #define IXGBEVF_QV_STATE_DISABLED	4    /* QV is disabled */ | ||||
| #define IXGBEVF_QV_OWNED (IXGBEVF_QV_STATE_NAPI | IXGBEVF_QV_STATE_POLL) | ||||
| #define IXGBEVF_QV_LOCKED (IXGBEVF_QV_OWNED | IXGBEVF_QV_STATE_DISABLED) | ||||
| #define IXGBEVF_QV_STATE_NAPI_YIELD	8    /* NAPI yielded this QV */ | ||||
| #define IXGBEVF_QV_STATE_POLL_YIELD	16   /* poll yielded this QV */ | ||||
| #define IXGBEVF_QV_YIELD (IXGBEVF_QV_STATE_NAPI_YIELD | IXGBEVF_QV_STATE_POLL_YIELD) | ||||
| #define IXGBEVF_QV_USER_PEND (IXGBEVF_QV_STATE_POLL | IXGBEVF_QV_STATE_POLL_YIELD) | ||||
| 	spinlock_t lock; | ||||
| #endif /* CONFIG_NET_RX_BUSY_POLL */ | ||||
| }; | ||||
| #ifdef CONFIG_NET_RX_BUSY_POLL | ||||
| static inline void ixgbevf_qv_init_lock(struct ixgbevf_q_vector *q_vector) | ||||
| { | ||||
| 
 | ||||
| 	spin_lock_init(&q_vector->lock); | ||||
| 	q_vector->state = IXGBEVF_QV_STATE_IDLE; | ||||
| } | ||||
| 
 | ||||
| /* called from the device poll routine to get ownership of a q_vector */ | ||||
| static inline bool ixgbevf_qv_lock_napi(struct ixgbevf_q_vector *q_vector) | ||||
| { | ||||
| 	int rc = true; | ||||
| 	spin_lock_bh(&q_vector->lock); | ||||
| 	if (q_vector->state & IXGBEVF_QV_LOCKED) { | ||||
| 		WARN_ON(q_vector->state & IXGBEVF_QV_STATE_NAPI); | ||||
| 		q_vector->state |= IXGBEVF_QV_STATE_NAPI_YIELD; | ||||
| 		rc = false; | ||||
| #ifdef BP_EXTENDED_STATS | ||||
| 		q_vector->tx.ring->stats.yields++; | ||||
| #endif | ||||
| 	} else { | ||||
| 		/* we don't care if someone yielded */ | ||||
| 		q_vector->state = IXGBEVF_QV_STATE_NAPI; | ||||
| 	} | ||||
| 	spin_unlock_bh(&q_vector->lock); | ||||
| 	return rc; | ||||
| } | ||||
| 
 | ||||
| /* returns true is someone tried to get the qv while napi had it */ | ||||
| static inline bool ixgbevf_qv_unlock_napi(struct ixgbevf_q_vector *q_vector) | ||||
| { | ||||
| 	int rc = false; | ||||
| 	spin_lock_bh(&q_vector->lock); | ||||
| 	WARN_ON(q_vector->state & (IXGBEVF_QV_STATE_POLL | | ||||
| 				   IXGBEVF_QV_STATE_NAPI_YIELD)); | ||||
| 
 | ||||
| 	if (q_vector->state & IXGBEVF_QV_STATE_POLL_YIELD) | ||||
| 		rc = true; | ||||
| 	/* reset state to idle, unless QV is disabled */ | ||||
| 	q_vector->state &= IXGBEVF_QV_STATE_DISABLED; | ||||
| 	spin_unlock_bh(&q_vector->lock); | ||||
| 	return rc; | ||||
| } | ||||
| 
 | ||||
| /* called from ixgbevf_low_latency_poll() */ | ||||
| static inline bool ixgbevf_qv_lock_poll(struct ixgbevf_q_vector *q_vector) | ||||
| { | ||||
| 	int rc = true; | ||||
| 	spin_lock_bh(&q_vector->lock); | ||||
| 	if ((q_vector->state & IXGBEVF_QV_LOCKED)) { | ||||
| 		q_vector->state |= IXGBEVF_QV_STATE_POLL_YIELD; | ||||
| 		rc = false; | ||||
| #ifdef BP_EXTENDED_STATS | ||||
| 		q_vector->rx.ring->stats.yields++; | ||||
| #endif | ||||
| 	} else { | ||||
| 		/* preserve yield marks */ | ||||
| 		q_vector->state |= IXGBEVF_QV_STATE_POLL; | ||||
| 	} | ||||
| 	spin_unlock_bh(&q_vector->lock); | ||||
| 	return rc; | ||||
| } | ||||
| 
 | ||||
| /* returns true if someone tried to get the qv while it was locked */ | ||||
| static inline bool ixgbevf_qv_unlock_poll(struct ixgbevf_q_vector *q_vector) | ||||
| { | ||||
| 	int rc = false; | ||||
| 	spin_lock_bh(&q_vector->lock); | ||||
| 	WARN_ON(q_vector->state & (IXGBEVF_QV_STATE_NAPI)); | ||||
| 
 | ||||
| 	if (q_vector->state & IXGBEVF_QV_STATE_POLL_YIELD) | ||||
| 		rc = true; | ||||
| 	/* reset state to idle, unless QV is disabled */ | ||||
| 	q_vector->state &= IXGBEVF_QV_STATE_DISABLED; | ||||
| 	spin_unlock_bh(&q_vector->lock); | ||||
| 	return rc; | ||||
| } | ||||
| 
 | ||||
| /* true if a socket is polling, even if it did not get the lock */ | ||||
| static inline bool ixgbevf_qv_busy_polling(struct ixgbevf_q_vector *q_vector) | ||||
| { | ||||
| 	WARN_ON(!(q_vector->state & IXGBEVF_QV_OWNED)); | ||||
| 	return q_vector->state & IXGBEVF_QV_USER_PEND; | ||||
| } | ||||
| 
 | ||||
| /* false if QV is currently owned */ | ||||
| static inline bool ixgbevf_qv_disable(struct ixgbevf_q_vector *q_vector) | ||||
| { | ||||
| 	int rc = true; | ||||
| 	spin_lock_bh(&q_vector->lock); | ||||
| 	if (q_vector->state & IXGBEVF_QV_OWNED) | ||||
| 		rc = false; | ||||
| 	q_vector->state |= IXGBEVF_QV_STATE_DISABLED; | ||||
| 	spin_unlock_bh(&q_vector->lock); | ||||
| 	return rc; | ||||
| } | ||||
| 
 | ||||
| #endif /* CONFIG_NET_RX_BUSY_POLL */ | ||||
| 
 | ||||
| /*
 | ||||
|  * 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 | ||||
| 
 | ||||
| /* Helper macros to switch between ints/sec and what the register uses.
 | ||||
|  * And yes, it's the same math going both ways.  The lowest value | ||||
|  * supported by all of the ixgbe hardware is 8. | ||||
|  */ | ||||
| #define EITR_INTS_PER_SEC_TO_REG(_eitr) \ | ||||
| 	((_eitr) ? (1000000000 / ((_eitr) * 256)) : 8) | ||||
| #define EITR_REG_TO_INTS_PER_SEC EITR_INTS_PER_SEC_TO_REG | ||||
| 
 | ||||
| static inline u16 ixgbevf_desc_unused(struct ixgbevf_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 ixgbevf_write_tail(struct ixgbevf_ring *ring, u32 value) | ||||
| { | ||||
| 	writel(value, ring->tail); | ||||
| } | ||||
| 
 | ||||
| #define IXGBEVF_RX_DESC(R, i)	    \ | ||||
| 	(&(((union ixgbe_adv_rx_desc *)((R)->desc))[i])) | ||||
| #define IXGBEVF_TX_DESC(R, i)	    \ | ||||
| 	(&(((union ixgbe_adv_tx_desc *)((R)->desc))[i])) | ||||
| #define IXGBEVF_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 */ | ||||
| 
 | ||||
| #define OTHER_VECTOR 1 | ||||
| #define NON_Q_VECTORS (OTHER_VECTOR) | ||||
| 
 | ||||
| #define MAX_MSIX_Q_VECTORS 2 | ||||
| 
 | ||||
| #define MIN_MSIX_Q_VECTORS 1 | ||||
| #define MIN_MSIX_COUNT (MIN_MSIX_Q_VECTORS + NON_Q_VECTORS) | ||||
| 
 | ||||
| /* board specific private data structure */ | ||||
| struct ixgbevf_adapter { | ||||
| 	struct timer_list watchdog_timer; | ||||
| 	unsigned long active_vlans[BITS_TO_LONGS(VLAN_N_VID)]; | ||||
| 	struct work_struct reset_task; | ||||
| 	struct ixgbevf_q_vector *q_vector[MAX_MSIX_Q_VECTORS]; | ||||
| 
 | ||||
| 	/* Interrupt Throttle Rate */ | ||||
| 	u16 rx_itr_setting; | ||||
| 	u16 tx_itr_setting; | ||||
| 
 | ||||
| 	/* interrupt masks */ | ||||
| 	u32 eims_enable_mask; | ||||
| 	u32 eims_other; | ||||
| 
 | ||||
| 	/* TX */ | ||||
| 	int num_tx_queues; | ||||
| 	struct ixgbevf_ring *tx_ring[MAX_TX_QUEUES]; /* One per active queue */ | ||||
| 	u64 restart_queue; | ||||
| 	u32 tx_timeout_count; | ||||
| 
 | ||||
| 	/* RX */ | ||||
| 	int num_rx_queues; | ||||
| 	struct ixgbevf_ring *rx_ring[MAX_TX_QUEUES]; /* One per active queue */ | ||||
| 	u64 hw_csum_rx_error; | ||||
| 	u64 hw_rx_no_dma_resources; | ||||
| 	u64 non_eop_descs; | ||||
| 	int num_msix_vectors; | ||||
| 	u32 alloc_rx_page_failed; | ||||
| 	u32 alloc_rx_buff_failed; | ||||
| 
 | ||||
| 	/* Some features need tri-state capability,
 | ||||
| 	 * thus the additional *_CAPABLE flags. | ||||
| 	 */ | ||||
| 	u32 flags; | ||||
| #define IXGBE_FLAG_IN_WATCHDOG_TASK             (u32)(1) | ||||
| #define IXGBE_FLAG_IN_NETPOLL                   (u32)(1 << 1) | ||||
| #define IXGBEVF_FLAG_QUEUE_RESET_REQUESTED	(u32)(1 << 2) | ||||
| 
 | ||||
| 	struct msix_entry *msix_entries; | ||||
| 
 | ||||
| 	/* OS defined structs */ | ||||
| 	struct net_device *netdev; | ||||
| 	struct pci_dev *pdev; | ||||
| 
 | ||||
| 	/* structs defined in ixgbe_vf.h */ | ||||
| 	struct ixgbe_hw hw; | ||||
| 	u16 msg_enable; | ||||
| 	/* Interrupt Throttle Rate */ | ||||
| 	u32 eitr_param; | ||||
| 
 | ||||
| 	struct ixgbevf_hw_stats stats; | ||||
| 
 | ||||
| 	unsigned long state; | ||||
| 	u64 tx_busy; | ||||
| 	unsigned int tx_ring_count; | ||||
| 	unsigned int rx_ring_count; | ||||
| 
 | ||||
| #ifdef BP_EXTENDED_STATS | ||||
| 	u64 bp_rx_yields; | ||||
| 	u64 bp_rx_cleaned; | ||||
| 	u64 bp_rx_missed; | ||||
| 
 | ||||
| 	u64 bp_tx_yields; | ||||
| 	u64 bp_tx_cleaned; | ||||
| 	u64 bp_tx_missed; | ||||
| #endif | ||||
| 
 | ||||
| 	u8 __iomem *io_addr; /* Mainly for iounmap use */ | ||||
| 	u32 link_speed; | ||||
| 	bool link_up; | ||||
| 
 | ||||
| 	spinlock_t mbx_lock; | ||||
| 
 | ||||
| 	struct work_struct watchdog_task; | ||||
| }; | ||||
| 
 | ||||
| enum ixbgevf_state_t { | ||||
| 	__IXGBEVF_TESTING, | ||||
| 	__IXGBEVF_RESETTING, | ||||
| 	__IXGBEVF_DOWN, | ||||
| 	__IXGBEVF_DISABLED, | ||||
| 	__IXGBEVF_REMOVING, | ||||
| 	__IXGBEVF_WORK_INIT, | ||||
| }; | ||||
| 
 | ||||
| struct ixgbevf_cb { | ||||
| 	struct sk_buff *prev; | ||||
| }; | ||||
| #define IXGBE_CB(skb) ((struct ixgbevf_cb *)(skb)->cb) | ||||
| 
 | ||||
| enum ixgbevf_boards { | ||||
| 	board_82599_vf, | ||||
| 	board_X540_vf, | ||||
| }; | ||||
| 
 | ||||
| extern const struct ixgbevf_info ixgbevf_82599_vf_info; | ||||
| extern const struct ixgbevf_info ixgbevf_X540_vf_info; | ||||
| extern const struct ixgbe_mbx_operations ixgbevf_mbx_ops; | ||||
| 
 | ||||
| /* needed by ethtool.c */ | ||||
| extern const char ixgbevf_driver_name[]; | ||||
| extern const char ixgbevf_driver_version[]; | ||||
| 
 | ||||
| void ixgbevf_up(struct ixgbevf_adapter *adapter); | ||||
| void ixgbevf_down(struct ixgbevf_adapter *adapter); | ||||
| void ixgbevf_reinit_locked(struct ixgbevf_adapter *adapter); | ||||
| void ixgbevf_reset(struct ixgbevf_adapter *adapter); | ||||
| void ixgbevf_set_ethtool_ops(struct net_device *netdev); | ||||
| int ixgbevf_setup_rx_resources(struct ixgbevf_ring *); | ||||
| int ixgbevf_setup_tx_resources(struct ixgbevf_ring *); | ||||
| void ixgbevf_free_rx_resources(struct ixgbevf_ring *); | ||||
| void ixgbevf_free_tx_resources(struct ixgbevf_ring *); | ||||
| void ixgbevf_update_stats(struct ixgbevf_adapter *adapter); | ||||
| int ethtool_ioctl(struct ifreq *ifr); | ||||
| 
 | ||||
| extern void ixgbevf_write_eitr(struct ixgbevf_q_vector *q_vector); | ||||
| 
 | ||||
| void ixgbe_napi_add_all(struct ixgbevf_adapter *adapter); | ||||
| void ixgbe_napi_del_all(struct ixgbevf_adapter *adapter); | ||||
| 
 | ||||
| #ifdef DEBUG | ||||
| char *ixgbevf_get_hw_dev_name(struct ixgbe_hw *hw); | ||||
| #define hw_dbg(hw, format, arg...) \ | ||||
| 	printk(KERN_DEBUG "%s: " format, ixgbevf_get_hw_dev_name(hw), ##arg) | ||||
| #else | ||||
| #define hw_dbg(hw, format, arg...) do {} while (0) | ||||
| #endif | ||||
| 
 | ||||
| #endif /* _IXGBEVF_H_ */ | ||||
							
								
								
									
										3805
									
								
								drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										3805
									
								
								drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
									
										
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							
							
								
								
									
										349
									
								
								drivers/net/ethernet/intel/ixgbevf/mbx.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										349
									
								
								drivers/net/ethernet/intel/ixgbevf/mbx.c
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,349 @@ | |||
| /*******************************************************************************
 | ||||
| 
 | ||||
|   Intel 82599 Virtual Function 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 | ||||
| 
 | ||||
| *******************************************************************************/ | ||||
| 
 | ||||
| #include "mbx.h" | ||||
| #include "ixgbevf.h" | ||||
| 
 | ||||
| /**
 | ||||
|  *  ixgbevf_poll_for_msg - Wait for message notification | ||||
|  *  @hw: pointer to the HW structure | ||||
|  * | ||||
|  *  returns 0 if it successfully received a message notification | ||||
|  **/ | ||||
| static s32 ixgbevf_poll_for_msg(struct ixgbe_hw *hw) | ||||
| { | ||||
| 	struct ixgbe_mbx_info *mbx = &hw->mbx; | ||||
| 	int countdown = mbx->timeout; | ||||
| 
 | ||||
| 	while (countdown && mbx->ops.check_for_msg(hw)) { | ||||
| 		countdown--; | ||||
| 		udelay(mbx->udelay); | ||||
| 	} | ||||
| 
 | ||||
| 	/* if we failed, all future posted messages fail until reset */ | ||||
| 	if (!countdown) | ||||
| 		mbx->timeout = 0; | ||||
| 
 | ||||
| 	return countdown ? 0 : IXGBE_ERR_MBX; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  *  ixgbevf_poll_for_ack - Wait for message acknowledgement | ||||
|  *  @hw: pointer to the HW structure | ||||
|  * | ||||
|  *  returns 0 if it successfully received a message acknowledgement | ||||
|  **/ | ||||
| static s32 ixgbevf_poll_for_ack(struct ixgbe_hw *hw) | ||||
| { | ||||
| 	struct ixgbe_mbx_info *mbx = &hw->mbx; | ||||
| 	int countdown = mbx->timeout; | ||||
| 
 | ||||
| 	while (countdown && mbx->ops.check_for_ack(hw)) { | ||||
| 		countdown--; | ||||
| 		udelay(mbx->udelay); | ||||
| 	} | ||||
| 
 | ||||
| 	/* if we failed, all future posted messages fail until reset */ | ||||
| 	if (!countdown) | ||||
| 		mbx->timeout = 0; | ||||
| 
 | ||||
| 	return countdown ? 0 : IXGBE_ERR_MBX; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  *  ixgbevf_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 0 if it successfully received a message notification and | ||||
|  *  copied it into the receive buffer. | ||||
|  **/ | ||||
| static s32 ixgbevf_read_posted_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size) | ||||
| { | ||||
| 	struct ixgbe_mbx_info *mbx = &hw->mbx; | ||||
| 	s32 ret_val = -IXGBE_ERR_MBX; | ||||
| 
 | ||||
| 	if (!mbx->ops.read) | ||||
| 		goto out; | ||||
| 
 | ||||
| 	ret_val = ixgbevf_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; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  *  ixgbevf_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 0 if it successfully copied message into the buffer and | ||||
|  *  received an ack to that message within delay * timeout period | ||||
|  **/ | ||||
| static s32 ixgbevf_write_posted_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size) | ||||
| { | ||||
| 	struct ixgbe_mbx_info *mbx = &hw->mbx; | ||||
| 	s32 ret_val = -IXGBE_ERR_MBX; | ||||
| 
 | ||||
| 	/* exit if either we 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 = ixgbevf_poll_for_ack(hw); | ||||
| out: | ||||
| 	return ret_val; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  *  ixgbevf_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 ixgbevf_read_v2p_mailbox(struct ixgbe_hw *hw) | ||||
| { | ||||
| 	u32 v2p_mailbox = IXGBE_READ_REG(hw, IXGBE_VFMAILBOX); | ||||
| 
 | ||||
| 	v2p_mailbox |= hw->mbx.v2p_mailbox; | ||||
| 	hw->mbx.v2p_mailbox |= v2p_mailbox & IXGBE_VFMAILBOX_R2C_BITS; | ||||
| 
 | ||||
| 	return v2p_mailbox; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  *  ixgbevf_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 ixgbevf_check_for_bit_vf(struct ixgbe_hw *hw, u32 mask) | ||||
| { | ||||
| 	u32 v2p_mailbox = ixgbevf_read_v2p_mailbox(hw); | ||||
| 	s32 ret_val = IXGBE_ERR_MBX; | ||||
| 
 | ||||
| 	if (v2p_mailbox & mask) | ||||
| 		ret_val = 0; | ||||
| 
 | ||||
| 	hw->mbx.v2p_mailbox &= ~mask; | ||||
| 
 | ||||
| 	return ret_val; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  *  ixgbevf_check_for_msg_vf - checks to see if the PF has sent mail | ||||
|  *  @hw: pointer to the HW structure | ||||
|  * | ||||
|  *  returns 0 if the PF has set the Status bit or else ERR_MBX | ||||
|  **/ | ||||
| static s32 ixgbevf_check_for_msg_vf(struct ixgbe_hw *hw) | ||||
| { | ||||
| 	s32 ret_val = IXGBE_ERR_MBX; | ||||
| 
 | ||||
| 	if (!ixgbevf_check_for_bit_vf(hw, IXGBE_VFMAILBOX_PFSTS)) { | ||||
| 		ret_val = 0; | ||||
| 		hw->mbx.stats.reqs++; | ||||
| 	} | ||||
| 
 | ||||
| 	return ret_val; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  *  ixgbevf_check_for_ack_vf - checks to see if the PF has ACK'd | ||||
|  *  @hw: pointer to the HW structure | ||||
|  * | ||||
|  *  returns 0 if the PF has set the ACK bit or else ERR_MBX | ||||
|  **/ | ||||
| static s32 ixgbevf_check_for_ack_vf(struct ixgbe_hw *hw) | ||||
| { | ||||
| 	s32 ret_val = IXGBE_ERR_MBX; | ||||
| 
 | ||||
| 	if (!ixgbevf_check_for_bit_vf(hw, IXGBE_VFMAILBOX_PFACK)) { | ||||
| 		ret_val = 0; | ||||
| 		hw->mbx.stats.acks++; | ||||
| 	} | ||||
| 
 | ||||
| 	return ret_val; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  *  ixgbevf_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 ixgbevf_check_for_rst_vf(struct ixgbe_hw *hw) | ||||
| { | ||||
| 	s32 ret_val = IXGBE_ERR_MBX; | ||||
| 
 | ||||
| 	if (!ixgbevf_check_for_bit_vf(hw, (IXGBE_VFMAILBOX_RSTD | | ||||
| 					 IXGBE_VFMAILBOX_RSTI))) { | ||||
| 		ret_val = 0; | ||||
| 		hw->mbx.stats.rsts++; | ||||
| 	} | ||||
| 
 | ||||
| 	return ret_val; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  *  ixgbevf_obtain_mbx_lock_vf - obtain mailbox lock | ||||
|  *  @hw: pointer to the HW structure | ||||
|  * | ||||
|  *  return 0 if we obtained the mailbox lock | ||||
|  **/ | ||||
| static s32 ixgbevf_obtain_mbx_lock_vf(struct ixgbe_hw *hw) | ||||
| { | ||||
| 	s32 ret_val = IXGBE_ERR_MBX; | ||||
| 
 | ||||
| 	/* Take ownership of the buffer */ | ||||
| 	IXGBE_WRITE_REG(hw, IXGBE_VFMAILBOX, IXGBE_VFMAILBOX_VFU); | ||||
| 
 | ||||
| 	/* reserve mailbox for vf use */ | ||||
| 	if (ixgbevf_read_v2p_mailbox(hw) & IXGBE_VFMAILBOX_VFU) | ||||
| 		ret_val = 0; | ||||
| 
 | ||||
| 	return ret_val; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  *  ixgbevf_write_mbx_vf - Write a message to the mailbox | ||||
|  *  @hw: pointer to the HW structure | ||||
|  *  @msg: The message buffer | ||||
|  *  @size: Length of buffer | ||||
|  * | ||||
|  *  returns 0 if it successfully copied message into the buffer | ||||
|  **/ | ||||
| static s32 ixgbevf_write_mbx_vf(struct ixgbe_hw *hw, u32 *msg, u16 size) | ||||
| { | ||||
| 	s32 ret_val; | ||||
| 	u16 i; | ||||
| 
 | ||||
| 
 | ||||
| 	/* lock the mailbox to prevent pf/vf race condition */ | ||||
| 	ret_val = ixgbevf_obtain_mbx_lock_vf(hw); | ||||
| 	if (ret_val) | ||||
| 		goto out_no_write; | ||||
| 
 | ||||
| 	/* flush msg and acks as we are overwriting the message buffer */ | ||||
| 	ixgbevf_check_for_msg_vf(hw); | ||||
| 	ixgbevf_check_for_ack_vf(hw); | ||||
| 
 | ||||
| 	/* copy the caller specified message to the mailbox memory buffer */ | ||||
| 	for (i = 0; i < size; i++) | ||||
| 		IXGBE_WRITE_REG_ARRAY(hw, IXGBE_VFMBMEM, i, msg[i]); | ||||
| 
 | ||||
| 	/* update stats */ | ||||
| 	hw->mbx.stats.msgs_tx++; | ||||
| 
 | ||||
| 	/* Drop VFU and interrupt the PF to tell it a message has been sent */ | ||||
| 	IXGBE_WRITE_REG(hw, IXGBE_VFMAILBOX, IXGBE_VFMAILBOX_REQ); | ||||
| 
 | ||||
| out_no_write: | ||||
| 	return ret_val; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  *  ixgbevf_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 0 if it successfully read message from buffer | ||||
|  **/ | ||||
| static s32 ixgbevf_read_mbx_vf(struct ixgbe_hw *hw, u32 *msg, u16 size) | ||||
| { | ||||
| 	s32 ret_val = 0; | ||||
| 	u16 i; | ||||
| 
 | ||||
| 	/* lock the mailbox to prevent pf/vf race condition */ | ||||
| 	ret_val = ixgbevf_obtain_mbx_lock_vf(hw); | ||||
| 	if (ret_val) | ||||
| 		goto out_no_read; | ||||
| 
 | ||||
| 	/* copy the message from the mailbox memory buffer */ | ||||
| 	for (i = 0; i < size; i++) | ||||
| 		msg[i] = IXGBE_READ_REG_ARRAY(hw, IXGBE_VFMBMEM, i); | ||||
| 
 | ||||
| 	/* Acknowledge receipt and release mailbox, then we're done */ | ||||
| 	IXGBE_WRITE_REG(hw, IXGBE_VFMAILBOX, IXGBE_VFMAILBOX_ACK); | ||||
| 
 | ||||
| 	/* update stats */ | ||||
| 	hw->mbx.stats.msgs_rx++; | ||||
| 
 | ||||
| out_no_read: | ||||
| 	return ret_val; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  *  ixgbevf_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 | ||||
|  */ | ||||
| static s32 ixgbevf_init_mbx_params_vf(struct ixgbe_hw *hw) | ||||
| { | ||||
| 	struct ixgbe_mbx_info *mbx = &hw->mbx; | ||||
| 
 | ||||
| 	/* start mailbox as timed out and let the reset_hw call set the timeout
 | ||||
| 	 * value to begin communications */ | ||||
| 	mbx->timeout = 0; | ||||
| 	mbx->udelay = IXGBE_VF_MBX_INIT_DELAY; | ||||
| 
 | ||||
| 	mbx->size = IXGBE_VFMAILBOX_SIZE; | ||||
| 
 | ||||
| 	mbx->stats.msgs_tx = 0; | ||||
| 	mbx->stats.msgs_rx = 0; | ||||
| 	mbx->stats.reqs = 0; | ||||
| 	mbx->stats.acks = 0; | ||||
| 	mbx->stats.rsts = 0; | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| const struct ixgbe_mbx_operations ixgbevf_mbx_ops = { | ||||
| 	.init_params   = ixgbevf_init_mbx_params_vf, | ||||
| 	.read          = ixgbevf_read_mbx_vf, | ||||
| 	.write         = ixgbevf_write_mbx_vf, | ||||
| 	.read_posted   = ixgbevf_read_posted_mbx, | ||||
| 	.write_posted  = ixgbevf_write_posted_mbx, | ||||
| 	.check_for_msg = ixgbevf_check_for_msg_vf, | ||||
| 	.check_for_ack = ixgbevf_check_for_ack_vf, | ||||
| 	.check_for_rst = ixgbevf_check_for_rst_vf, | ||||
| }; | ||||
| 
 | ||||
							
								
								
									
										126
									
								
								drivers/net/ethernet/intel/ixgbevf/mbx.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										126
									
								
								drivers/net/ethernet/intel/ixgbevf/mbx.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,126 @@ | |||
| /*******************************************************************************
 | ||||
| 
 | ||||
|   Intel 82599 Virtual Function 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 _IXGBE_MBX_H_ | ||||
| #define _IXGBE_MBX_H_ | ||||
| 
 | ||||
| #include "vf.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 mailbox register bits */ | ||||
| #define IXGBE_VFMAILBOX_REQ      0x00000001 /* Request for PF Ready bit */ | ||||
| #define IXGBE_VFMAILBOX_ACK      0x00000002 /* Ack PF message received */ | ||||
| #define IXGBE_VFMAILBOX_VFU      0x00000004 /* VF owns the mailbox buffer */ | ||||
| #define IXGBE_VFMAILBOX_PFU      0x00000008 /* PF owns the mailbox buffer */ | ||||
| #define IXGBE_VFMAILBOX_PFSTS    0x00000010 /* PF wrote a message in the MB */ | ||||
| #define IXGBE_VFMAILBOX_PFACK    0x00000020 /* PF ack the previous VF msg */ | ||||
| #define IXGBE_VFMAILBOX_RSTI     0x00000040 /* PF has reset indication */ | ||||
| #define IXGBE_VFMAILBOX_RSTD     0x00000080 /* PF has indicated reset done */ | ||||
| #define IXGBE_VFMAILBOX_R2C_BITS 0x000000B0 /* All read to clear bits */ | ||||
| 
 | ||||
| #define IXGBE_PFMAILBOX(x)          (0x04B00 + (4 * (x))) | ||||
| #define IXGBE_PFMBMEM(vfn)          (0x13000 + (64 * (vfn))) | ||||
| 
 | ||||
| #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_QUEUE	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 */ | ||||
| 
 | ||||
| /* forward declaration of the HW struct */ | ||||
| struct ixgbe_hw; | ||||
| 
 | ||||
| #endif /* _IXGBE_MBX_H_ */ | ||||
							
								
								
									
										75
									
								
								drivers/net/ethernet/intel/ixgbevf/regs.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										75
									
								
								drivers/net/ethernet/intel/ixgbevf/regs.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,75 @@ | |||
| /*******************************************************************************
 | ||||
| 
 | ||||
|   Intel 82599 Virtual Function 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: | ||||
|   e1000-devel Mailing List <e1000-devel@lists.sourceforge.net> | ||||
|   Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 | ||||
| 
 | ||||
| *******************************************************************************/ | ||||
| 
 | ||||
| #ifndef _IXGBEVF_REGS_H_ | ||||
| #define _IXGBEVF_REGS_H_ | ||||
| 
 | ||||
| #define IXGBE_VFCTRL           0x00000 | ||||
| #define IXGBE_VFSTATUS         0x00008 | ||||
| #define IXGBE_VFLINKS          0x00010 | ||||
| #define IXGBE_VFFRTIMER        0x00048 | ||||
| #define IXGBE_VFRXMEMWRAP      0x03190 | ||||
| #define IXGBE_VTEICR           0x00100 | ||||
| #define IXGBE_VTEICS           0x00104 | ||||
| #define IXGBE_VTEIMS           0x00108 | ||||
| #define IXGBE_VTEIMC           0x0010C | ||||
| #define IXGBE_VTEIAC           0x00110 | ||||
| #define IXGBE_VTEIAM           0x00114 | ||||
| #define IXGBE_VTEITR(x)        (0x00820 + (4 * (x))) | ||||
| #define IXGBE_VTIVAR(x)        (0x00120 + (4 * (x))) | ||||
| #define IXGBE_VTIVAR_MISC      0x00140 | ||||
| #define IXGBE_VTRSCINT(x)      (0x00180 + (4 * (x))) | ||||
| #define IXGBE_VFRDBAL(x)       (0x01000 + (0x40 * (x))) | ||||
| #define IXGBE_VFRDBAH(x)       (0x01004 + (0x40 * (x))) | ||||
| #define IXGBE_VFRDLEN(x)       (0x01008 + (0x40 * (x))) | ||||
| #define IXGBE_VFRDH(x)         (0x01010 + (0x40 * (x))) | ||||
| #define IXGBE_VFRDT(x)         (0x01018 + (0x40 * (x))) | ||||
| #define IXGBE_VFRXDCTL(x)      (0x01028 + (0x40 * (x))) | ||||
| #define IXGBE_VFSRRCTL(x)      (0x01014 + (0x40 * (x))) | ||||
| #define IXGBE_VFRSCCTL(x)      (0x0102C + (0x40 * (x))) | ||||
| #define IXGBE_VFPSRTYPE        0x00300 | ||||
| #define IXGBE_VFTDBAL(x)       (0x02000 + (0x40 * (x))) | ||||
| #define IXGBE_VFTDBAH(x)       (0x02004 + (0x40 * (x))) | ||||
| #define IXGBE_VFTDLEN(x)       (0x02008 + (0x40 * (x))) | ||||
| #define IXGBE_VFTDH(x)         (0x02010 + (0x40 * (x))) | ||||
| #define IXGBE_VFTDT(x)         (0x02018 + (0x40 * (x))) | ||||
| #define IXGBE_VFTXDCTL(x)      (0x02028 + (0x40 * (x))) | ||||
| #define IXGBE_VFTDWBAL(x)      (0x02038 + (0x40 * (x))) | ||||
| #define IXGBE_VFTDWBAH(x)      (0x0203C + (0x40 * (x))) | ||||
| #define IXGBE_VFDCA_RXCTRL(x)  (0x0100C + (0x40 * (x))) | ||||
| #define IXGBE_VFDCA_TXCTRL(x)  (0x0200c + (0x40 * (x))) | ||||
| #define IXGBE_VFGPRC           0x0101C | ||||
| #define IXGBE_VFGPTC           0x0201C | ||||
| #define IXGBE_VFGORC_LSB       0x01020 | ||||
| #define IXGBE_VFGORC_MSB       0x01024 | ||||
| #define IXGBE_VFGOTC_LSB       0x02020 | ||||
| #define IXGBE_VFGOTC_MSB       0x02024 | ||||
| #define IXGBE_VFMPRC           0x01034 | ||||
| 
 | ||||
| #define IXGBE_WRITE_FLUSH(a) (IXGBE_READ_REG(a, IXGBE_VFSTATUS)) | ||||
| 
 | ||||
| #endif /* _IXGBEVF_REGS_H_ */ | ||||
							
								
								
									
										619
									
								
								drivers/net/ethernet/intel/ixgbevf/vf.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										619
									
								
								drivers/net/ethernet/intel/ixgbevf/vf.c
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,619 @@ | |||
| /*******************************************************************************
 | ||||
| 
 | ||||
|   Intel 82599 Virtual Function 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 | ||||
| 
 | ||||
| *******************************************************************************/ | ||||
| 
 | ||||
| #include "vf.h" | ||||
| #include "ixgbevf.h" | ||||
| 
 | ||||
| /**
 | ||||
|  *  ixgbevf_start_hw_vf - Prepare hardware for Tx/Rx | ||||
|  *  @hw: pointer to hardware structure | ||||
|  * | ||||
|  *  Starts the hardware by filling the bus info structure and media type, clears | ||||
|  *  all on chip counters, initializes receive address registers, multicast | ||||
|  *  table, VLAN filter table, calls routine to set up link and flow control | ||||
|  *  settings, and leaves transmit and receive units disabled and uninitialized | ||||
|  **/ | ||||
| static s32 ixgbevf_start_hw_vf(struct ixgbe_hw *hw) | ||||
| { | ||||
| 	/* Clear adapter stopped flag */ | ||||
| 	hw->adapter_stopped = false; | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  *  ixgbevf_init_hw_vf - virtual function hardware initialization | ||||
|  *  @hw: pointer to hardware structure | ||||
|  * | ||||
|  *  Initialize the hardware by resetting the hardware and then starting | ||||
|  *  the hardware | ||||
|  **/ | ||||
| static s32 ixgbevf_init_hw_vf(struct ixgbe_hw *hw) | ||||
| { | ||||
| 	s32 status = hw->mac.ops.start_hw(hw); | ||||
| 
 | ||||
| 	hw->mac.ops.get_mac_addr(hw, hw->mac.addr); | ||||
| 
 | ||||
| 	return status; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  *  ixgbevf_reset_hw_vf - Performs hardware reset | ||||
|  *  @hw: pointer to hardware structure | ||||
|  * | ||||
|  *  Resets the hardware by reseting the transmit and receive units, masks and | ||||
|  *  clears all interrupts. | ||||
|  **/ | ||||
| static s32 ixgbevf_reset_hw_vf(struct ixgbe_hw *hw) | ||||
| { | ||||
| 	struct ixgbe_mbx_info *mbx = &hw->mbx; | ||||
| 	u32 timeout = IXGBE_VF_INIT_TIMEOUT; | ||||
| 	s32 ret_val = IXGBE_ERR_INVALID_MAC_ADDR; | ||||
| 	u32 msgbuf[IXGBE_VF_PERMADDR_MSG_LEN]; | ||||
| 	u8 *addr = (u8 *)(&msgbuf[1]); | ||||
| 
 | ||||
| 	/* Call adapter stop to disable tx/rx and clear interrupts */ | ||||
| 	hw->mac.ops.stop_adapter(hw); | ||||
| 
 | ||||
| 	/* reset the api version */ | ||||
| 	hw->api_version = ixgbe_mbox_api_10; | ||||
| 
 | ||||
| 	IXGBE_WRITE_REG(hw, IXGBE_VFCTRL, IXGBE_CTRL_RST); | ||||
| 	IXGBE_WRITE_FLUSH(hw); | ||||
| 
 | ||||
| 	/* we cannot reset while the RSTI / RSTD bits are asserted */ | ||||
| 	while (!mbx->ops.check_for_rst(hw) && timeout) { | ||||
| 		timeout--; | ||||
| 		udelay(5); | ||||
| 	} | ||||
| 
 | ||||
| 	if (!timeout) | ||||
| 		return IXGBE_ERR_RESET_FAILED; | ||||
| 
 | ||||
| 	/* mailbox timeout can now become active */ | ||||
| 	mbx->timeout = IXGBE_VF_MBX_INIT_TIMEOUT; | ||||
| 
 | ||||
| 	msgbuf[0] = IXGBE_VF_RESET; | ||||
| 	mbx->ops.write_posted(hw, msgbuf, 1); | ||||
| 
 | ||||
| 	mdelay(10); | ||||
| 
 | ||||
| 	/* set our "perm_addr" based on info provided by PF */ | ||||
| 	/* also set up the mc_filter_type which is piggy backed
 | ||||
| 	 * on the mac address in word 3 */ | ||||
| 	ret_val = mbx->ops.read_posted(hw, msgbuf, IXGBE_VF_PERMADDR_MSG_LEN); | ||||
| 	if (ret_val) | ||||
| 		return ret_val; | ||||
| 
 | ||||
| 	/* New versions of the PF may NACK the reset return message
 | ||||
| 	 * to indicate that no MAC address has yet been assigned for | ||||
| 	 * the VF. | ||||
| 	 */ | ||||
| 	if (msgbuf[0] != (IXGBE_VF_RESET | IXGBE_VT_MSGTYPE_ACK) && | ||||
| 	    msgbuf[0] != (IXGBE_VF_RESET | IXGBE_VT_MSGTYPE_NACK)) | ||||
| 		return IXGBE_ERR_INVALID_MAC_ADDR; | ||||
| 
 | ||||
| 	memcpy(hw->mac.perm_addr, addr, ETH_ALEN); | ||||
| 	hw->mac.mc_filter_type = msgbuf[IXGBE_VF_MC_TYPE_WORD]; | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  *  ixgbevf_stop_hw_vf - Generic stop Tx/Rx units | ||||
|  *  @hw: pointer to hardware structure | ||||
|  * | ||||
|  *  Sets the adapter_stopped flag within ixgbe_hw struct. Clears interrupts, | ||||
|  *  disables transmit and receive units. The adapter_stopped flag is used by | ||||
|  *  the shared code and drivers to determine if the adapter is in a stopped | ||||
|  *  state and should not touch the hardware. | ||||
|  **/ | ||||
| static s32 ixgbevf_stop_hw_vf(struct ixgbe_hw *hw) | ||||
| { | ||||
| 	u32 number_of_queues; | ||||
| 	u32 reg_val; | ||||
| 	u16 i; | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * Set the adapter_stopped flag so other driver functions stop touching | ||||
| 	 * the hardware | ||||
| 	 */ | ||||
| 	hw->adapter_stopped = true; | ||||
| 
 | ||||
| 	/* Disable the receive unit by stopped each queue */ | ||||
| 	number_of_queues = hw->mac.max_rx_queues; | ||||
| 	for (i = 0; i < number_of_queues; i++) { | ||||
| 		reg_val = IXGBE_READ_REG(hw, IXGBE_VFRXDCTL(i)); | ||||
| 		if (reg_val & IXGBE_RXDCTL_ENABLE) { | ||||
| 			reg_val &= ~IXGBE_RXDCTL_ENABLE; | ||||
| 			IXGBE_WRITE_REG(hw, IXGBE_VFRXDCTL(i), reg_val); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	IXGBE_WRITE_FLUSH(hw); | ||||
| 
 | ||||
| 	/* Clear interrupt mask to stop from interrupts being generated */ | ||||
| 	IXGBE_WRITE_REG(hw, IXGBE_VTEIMC, IXGBE_VF_IRQ_CLEAR_MASK); | ||||
| 
 | ||||
| 	/* Clear any pending interrupts */ | ||||
| 	IXGBE_READ_REG(hw, IXGBE_VTEICR); | ||||
| 
 | ||||
| 	/* Disable the transmit unit.  Each queue must be disabled. */ | ||||
| 	number_of_queues = hw->mac.max_tx_queues; | ||||
| 	for (i = 0; i < number_of_queues; i++) { | ||||
| 		reg_val = IXGBE_READ_REG(hw, IXGBE_VFTXDCTL(i)); | ||||
| 		if (reg_val & IXGBE_TXDCTL_ENABLE) { | ||||
| 			reg_val &= ~IXGBE_TXDCTL_ENABLE; | ||||
| 			IXGBE_WRITE_REG(hw, IXGBE_VFTXDCTL(i), reg_val); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  *  ixgbevf_mta_vector - Determines bit-vector in multicast table to set | ||||
|  *  @hw: pointer to hardware structure | ||||
|  *  @mc_addr: the multicast address | ||||
|  * | ||||
|  *  Extracts the 12 bits, from a multicast address, to determine which | ||||
|  *  bit-vector to set in the multicast table. The hardware uses 12 bits, from | ||||
|  *  incoming rx multicast addresses, to determine the bit-vector to check in | ||||
|  *  the MTA. Which of the 4 combination, of 12-bits, the hardware uses is set | ||||
|  *  by the MO field of the MCSTCTRL. The MO field is set during initialization | ||||
|  *  to mc_filter_type. | ||||
|  **/ | ||||
| static s32 ixgbevf_mta_vector(struct ixgbe_hw *hw, u8 *mc_addr) | ||||
| { | ||||
| 	u32 vector = 0; | ||||
| 
 | ||||
| 	switch (hw->mac.mc_filter_type) { | ||||
| 	case 0:   /* use bits [47:36] of the address */ | ||||
| 		vector = ((mc_addr[4] >> 4) | (((u16)mc_addr[5]) << 4)); | ||||
| 		break; | ||||
| 	case 1:   /* use bits [46:35] of the address */ | ||||
| 		vector = ((mc_addr[4] >> 3) | (((u16)mc_addr[5]) << 5)); | ||||
| 		break; | ||||
| 	case 2:   /* use bits [45:34] of the address */ | ||||
| 		vector = ((mc_addr[4] >> 2) | (((u16)mc_addr[5]) << 6)); | ||||
| 		break; | ||||
| 	case 3:   /* use bits [43:32] of the address */ | ||||
| 		vector = ((mc_addr[4]) | (((u16)mc_addr[5]) << 8)); | ||||
| 		break; | ||||
| 	default:  /* Invalid mc_filter_type */ | ||||
| 		break; | ||||
| 	} | ||||
| 
 | ||||
| 	/* vector can only be 12-bits or boundary will be exceeded */ | ||||
| 	vector &= 0xFFF; | ||||
| 	return vector; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  *  ixgbevf_get_mac_addr_vf - Read device MAC address | ||||
|  *  @hw: pointer to the HW structure | ||||
|  *  @mac_addr: pointer to storage for retrieved MAC address | ||||
|  **/ | ||||
| static s32 ixgbevf_get_mac_addr_vf(struct ixgbe_hw *hw, u8 *mac_addr) | ||||
| { | ||||
| 	memcpy(mac_addr, hw->mac.perm_addr, ETH_ALEN); | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| static s32 ixgbevf_set_uc_addr_vf(struct ixgbe_hw *hw, u32 index, u8 *addr) | ||||
| { | ||||
| 	struct ixgbe_mbx_info *mbx = &hw->mbx; | ||||
| 	u32 msgbuf[3]; | ||||
| 	u8 *msg_addr = (u8 *)(&msgbuf[1]); | ||||
| 	s32 ret_val; | ||||
| 
 | ||||
| 	memset(msgbuf, 0, sizeof(msgbuf)); | ||||
| 	/*
 | ||||
| 	 * If index is one then this is the start of a new list and needs | ||||
| 	 * indication to the PF so it can do it's own list management. | ||||
| 	 * If it is zero then that tells the PF to just clear all of | ||||
| 	 * this VF's macvlans and there is no new list. | ||||
| 	 */ | ||||
| 	msgbuf[0] |= index << IXGBE_VT_MSGINFO_SHIFT; | ||||
| 	msgbuf[0] |= IXGBE_VF_SET_MACVLAN; | ||||
| 	if (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] &= ~IXGBE_VT_MSGTYPE_CTS; | ||||
| 
 | ||||
| 	if (!ret_val) | ||||
| 		if (msgbuf[0] == | ||||
| 		    (IXGBE_VF_SET_MACVLAN | IXGBE_VT_MSGTYPE_NACK)) | ||||
| 			ret_val = -ENOMEM; | ||||
| 
 | ||||
| 	return ret_val; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  *  ixgbevf_set_rar_vf - set device MAC address | ||||
|  *  @hw: pointer to hardware structure | ||||
|  *  @index: Receive address register to write | ||||
|  *  @addr: Address to put into receive address register | ||||
|  *  @vmdq: Unused in this implementation | ||||
|  **/ | ||||
| static s32 ixgbevf_set_rar_vf(struct ixgbe_hw *hw, u32 index, u8 *addr, | ||||
| 			      u32 vmdq) | ||||
| { | ||||
| 	struct ixgbe_mbx_info *mbx = &hw->mbx; | ||||
| 	u32 msgbuf[3]; | ||||
| 	u8 *msg_addr = (u8 *)(&msgbuf[1]); | ||||
| 	s32 ret_val; | ||||
| 
 | ||||
| 	memset(msgbuf, 0, sizeof(msgbuf)); | ||||
| 	msgbuf[0] = IXGBE_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] &= ~IXGBE_VT_MSGTYPE_CTS; | ||||
| 
 | ||||
| 	/* if nacked the address was rejected, use "perm_addr" */ | ||||
| 	if (!ret_val && | ||||
| 	    (msgbuf[0] == (IXGBE_VF_SET_MAC_ADDR | IXGBE_VT_MSGTYPE_NACK))) | ||||
| 		ixgbevf_get_mac_addr_vf(hw, hw->mac.addr); | ||||
| 
 | ||||
| 	return ret_val; | ||||
| } | ||||
| 
 | ||||
| static void ixgbevf_write_msg_read_ack(struct ixgbe_hw *hw, | ||||
| 					u32 *msg, u16 size) | ||||
| { | ||||
| 	struct ixgbe_mbx_info *mbx = &hw->mbx; | ||||
| 	u32 retmsg[IXGBE_VFMAILBOX_SIZE]; | ||||
| 	s32 retval = mbx->ops.write_posted(hw, msg, size); | ||||
| 
 | ||||
| 	if (!retval) | ||||
| 		mbx->ops.read_posted(hw, retmsg, size); | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  *  ixgbevf_update_mc_addr_list_vf - Update Multicast addresses | ||||
|  *  @hw: pointer to the HW structure | ||||
|  *  @netdev: pointer to net device structure | ||||
|  * | ||||
|  *  Updates the Multicast Table Array. | ||||
|  **/ | ||||
| static s32 ixgbevf_update_mc_addr_list_vf(struct ixgbe_hw *hw, | ||||
| 					  struct net_device *netdev) | ||||
| { | ||||
| 	struct netdev_hw_addr *ha; | ||||
| 	u32 msgbuf[IXGBE_VFMAILBOX_SIZE]; | ||||
| 	u16 *vector_list = (u16 *)&msgbuf[1]; | ||||
| 	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 = netdev_mc_count(netdev); | ||||
| 	if (cnt > 30) | ||||
| 		cnt = 30; | ||||
| 	msgbuf[0] = IXGBE_VF_SET_MULTICAST; | ||||
| 	msgbuf[0] |= cnt << IXGBE_VT_MSGINFO_SHIFT; | ||||
| 
 | ||||
| 	i = 0; | ||||
| 	netdev_for_each_mc_addr(ha, netdev) { | ||||
| 		if (i == cnt) | ||||
| 			break; | ||||
| 		if (is_link_local_ether_addr(ha->addr)) | ||||
| 			continue; | ||||
| 
 | ||||
| 		vector_list[i++] = ixgbevf_mta_vector(hw, ha->addr); | ||||
| 	} | ||||
| 
 | ||||
| 	ixgbevf_write_msg_read_ack(hw, msgbuf, IXGBE_VFMAILBOX_SIZE); | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  *  ixgbevf_set_vfta_vf - Set/Unset vlan filter table address | ||||
|  *  @hw: pointer to the HW structure | ||||
|  *  @vlan: 12 bit VLAN ID | ||||
|  *  @vind: unused by VF drivers | ||||
|  *  @vlan_on: if true then set bit, else clear bit | ||||
|  **/ | ||||
| static s32 ixgbevf_set_vfta_vf(struct ixgbe_hw *hw, u32 vlan, u32 vind, | ||||
| 			       bool vlan_on) | ||||
| { | ||||
| 	struct ixgbe_mbx_info *mbx = &hw->mbx; | ||||
| 	u32 msgbuf[2]; | ||||
| 	s32 err; | ||||
| 
 | ||||
| 	msgbuf[0] = IXGBE_VF_SET_VLAN; | ||||
| 	msgbuf[1] = vlan; | ||||
| 	/* Setting the 8 bit field MSG INFO to TRUE indicates "add" */ | ||||
| 	msgbuf[0] |= vlan_on << IXGBE_VT_MSGINFO_SHIFT; | ||||
| 
 | ||||
| 	err = mbx->ops.write_posted(hw, msgbuf, 2); | ||||
| 	if (err) | ||||
| 		goto mbx_err; | ||||
| 
 | ||||
| 	err = mbx->ops.read_posted(hw, msgbuf, 2); | ||||
| 	if (err) | ||||
| 		goto mbx_err; | ||||
| 
 | ||||
| 	/* remove extra bits from the message */ | ||||
| 	msgbuf[0] &= ~IXGBE_VT_MSGTYPE_CTS; | ||||
| 	msgbuf[0] &= ~(0xFF << IXGBE_VT_MSGINFO_SHIFT); | ||||
| 
 | ||||
| 	if (msgbuf[0] != (IXGBE_VF_SET_VLAN | IXGBE_VT_MSGTYPE_ACK)) | ||||
| 		err = IXGBE_ERR_INVALID_ARGUMENT; | ||||
| 
 | ||||
| mbx_err: | ||||
| 	return err; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  *  ixgbevf_setup_mac_link_vf - Setup MAC link settings | ||||
|  *  @hw: pointer to hardware structure | ||||
|  *  @speed: Unused in this implementation | ||||
|  *  @autoneg: Unused in this implementation | ||||
|  *  @autoneg_wait_to_complete: Unused in this implementation | ||||
|  * | ||||
|  *  Do nothing and return success.  VF drivers are not allowed to change | ||||
|  *  global settings.  Maintained for driver compatibility. | ||||
|  **/ | ||||
| static s32 ixgbevf_setup_mac_link_vf(struct ixgbe_hw *hw, | ||||
| 				     ixgbe_link_speed speed, bool autoneg, | ||||
| 				     bool autoneg_wait_to_complete) | ||||
| { | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  *  ixgbevf_check_mac_link_vf - Get link/speed status | ||||
|  *  @hw: pointer to hardware structure | ||||
|  *  @speed: pointer to link speed | ||||
|  *  @link_up: true is link is up, false otherwise | ||||
|  *  @autoneg_wait_to_complete: true when waiting for completion is needed | ||||
|  * | ||||
|  *  Reads the links register to determine if link is up and the current speed | ||||
|  **/ | ||||
| static s32 ixgbevf_check_mac_link_vf(struct ixgbe_hw *hw, | ||||
| 				     ixgbe_link_speed *speed, | ||||
| 				     bool *link_up, | ||||
| 				     bool autoneg_wait_to_complete) | ||||
| { | ||||
| 	struct ixgbe_mbx_info *mbx = &hw->mbx; | ||||
| 	struct ixgbe_mac_info *mac = &hw->mac; | ||||
| 	s32 ret_val = 0; | ||||
| 	u32 links_reg; | ||||
| 	u32 in_msg = 0; | ||||
| 
 | ||||
| 	/* If we were hit with a reset 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 */ | ||||
| 	links_reg = IXGBE_READ_REG(hw, IXGBE_VFLINKS); | ||||
| 	if (!(links_reg & IXGBE_LINKS_UP)) | ||||
| 		goto out; | ||||
| 
 | ||||
| 	/* for SFP+ modules and DA cables on 82599 it can take up to 500usecs
 | ||||
| 	 * before the link status is correct | ||||
| 	 */ | ||||
| 	if (mac->type == ixgbe_mac_82599_vf) { | ||||
| 		int i; | ||||
| 
 | ||||
| 		for (i = 0; i < 5; i++) { | ||||
| 			udelay(100); | ||||
| 			links_reg = IXGBE_READ_REG(hw, IXGBE_VFLINKS); | ||||
| 
 | ||||
| 			if (!(links_reg & IXGBE_LINKS_UP)) | ||||
| 				goto out; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	switch (links_reg & IXGBE_LINKS_SPEED_82599) { | ||||
| 	case IXGBE_LINKS_SPEED_10G_82599: | ||||
| 		*speed = IXGBE_LINK_SPEED_10GB_FULL; | ||||
| 		break; | ||||
| 	case IXGBE_LINKS_SPEED_1G_82599: | ||||
| 		*speed = IXGBE_LINK_SPEED_1GB_FULL; | ||||
| 		break; | ||||
| 	case IXGBE_LINKS_SPEED_100_82599: | ||||
| 		*speed = IXGBE_LINK_SPEED_100_FULL; | ||||
| 		break; | ||||
| 	} | ||||
| 
 | ||||
| 	/* 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 (!(in_msg & IXGBE_VT_MSGTYPE_CTS)) { | ||||
| 		/* msg is not CTS and is NACK we must have lost CTS status */ | ||||
| 		if (in_msg & IXGBE_VT_MSGTYPE_NACK) | ||||
| 			ret_val = -1; | ||||
| 		goto out; | ||||
| 	} | ||||
| 
 | ||||
| 	/* the pf is talking, if we timed out in the past we reinit */ | ||||
| 	if (!mbx->timeout) { | ||||
| 		ret_val = -1; | ||||
| 		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: | ||||
| 	*link_up = !mac->get_link_status; | ||||
| 	return ret_val; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  *  ixgbevf_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 ixgbevf_rlpml_set_vf(struct ixgbe_hw *hw, u16 max_size) | ||||
| { | ||||
| 	u32 msgbuf[2]; | ||||
| 
 | ||||
| 	msgbuf[0] = IXGBE_VF_SET_LPE; | ||||
| 	msgbuf[1] = max_size; | ||||
| 	ixgbevf_write_msg_read_ack(hw, msgbuf, 2); | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  *  ixgbevf_negotiate_api_version - Negotiate supported API version | ||||
|  *  @hw: pointer to the HW structure | ||||
|  *  @api: integer containing requested API version | ||||
|  **/ | ||||
| int ixgbevf_negotiate_api_version(struct ixgbe_hw *hw, int api) | ||||
| { | ||||
| 	int err; | ||||
| 	u32 msg[3]; | ||||
| 
 | ||||
| 	/* Negotiate the mailbox API version */ | ||||
| 	msg[0] = IXGBE_VF_API_NEGOTIATE; | ||||
| 	msg[1] = api; | ||||
| 	msg[2] = 0; | ||||
| 	err = hw->mbx.ops.write_posted(hw, msg, 3); | ||||
| 
 | ||||
| 	if (!err) | ||||
| 		err = hw->mbx.ops.read_posted(hw, msg, 3); | ||||
| 
 | ||||
| 	if (!err) { | ||||
| 		msg[0] &= ~IXGBE_VT_MSGTYPE_CTS; | ||||
| 
 | ||||
| 		/* Store value and return 0 on success */ | ||||
| 		if (msg[0] == (IXGBE_VF_API_NEGOTIATE | IXGBE_VT_MSGTYPE_ACK)) { | ||||
| 			hw->api_version = api; | ||||
| 			return 0; | ||||
| 		} | ||||
| 
 | ||||
| 		err = IXGBE_ERR_INVALID_ARGUMENT; | ||||
| 	} | ||||
| 
 | ||||
| 	return err; | ||||
| } | ||||
| 
 | ||||
| int ixgbevf_get_queues(struct ixgbe_hw *hw, unsigned int *num_tcs, | ||||
| 		       unsigned int *default_tc) | ||||
| { | ||||
| 	int err; | ||||
| 	u32 msg[5]; | ||||
| 
 | ||||
| 	/* do nothing if API doesn't support ixgbevf_get_queues */ | ||||
| 	switch (hw->api_version) { | ||||
| 	case ixgbe_mbox_api_11: | ||||
| 		break; | ||||
| 	default: | ||||
| 		return 0; | ||||
| 	} | ||||
| 
 | ||||
| 	/* Fetch queue configuration from the PF */ | ||||
| 	msg[0] = IXGBE_VF_GET_QUEUE; | ||||
| 	msg[1] = msg[2] = msg[3] = msg[4] = 0; | ||||
| 	err = hw->mbx.ops.write_posted(hw, msg, 5); | ||||
| 
 | ||||
| 	if (!err) | ||||
| 		err = hw->mbx.ops.read_posted(hw, msg, 5); | ||||
| 
 | ||||
| 	if (!err) { | ||||
| 		msg[0] &= ~IXGBE_VT_MSGTYPE_CTS; | ||||
| 
 | ||||
| 		/*
 | ||||
| 		 * if we we didn't get an ACK there must have been | ||||
| 		 * some sort of mailbox error so we should treat it | ||||
| 		 * as such | ||||
| 		 */ | ||||
| 		if (msg[0] != (IXGBE_VF_GET_QUEUE | IXGBE_VT_MSGTYPE_ACK)) | ||||
| 			return IXGBE_ERR_MBX; | ||||
| 
 | ||||
| 		/* record and validate values from message */ | ||||
| 		hw->mac.max_tx_queues = msg[IXGBE_VF_TX_QUEUES]; | ||||
| 		if (hw->mac.max_tx_queues == 0 || | ||||
| 		    hw->mac.max_tx_queues > IXGBE_VF_MAX_TX_QUEUES) | ||||
| 			hw->mac.max_tx_queues = IXGBE_VF_MAX_TX_QUEUES; | ||||
| 
 | ||||
| 		hw->mac.max_rx_queues = msg[IXGBE_VF_RX_QUEUES]; | ||||
| 		if (hw->mac.max_rx_queues == 0 || | ||||
| 		    hw->mac.max_rx_queues > IXGBE_VF_MAX_RX_QUEUES) | ||||
| 			hw->mac.max_rx_queues = IXGBE_VF_MAX_RX_QUEUES; | ||||
| 
 | ||||
| 		*num_tcs = msg[IXGBE_VF_TRANS_VLAN]; | ||||
| 		/* in case of unknown state assume we cannot tag frames */ | ||||
| 		if (*num_tcs > hw->mac.max_rx_queues) | ||||
| 			*num_tcs = 1; | ||||
| 
 | ||||
| 		*default_tc = msg[IXGBE_VF_DEF_QUEUE]; | ||||
| 		/* default to queue 0 on out-of-bounds queue number */ | ||||
| 		if (*default_tc >= hw->mac.max_tx_queues) | ||||
| 			*default_tc = 0; | ||||
| 	} | ||||
| 
 | ||||
| 	return err; | ||||
| } | ||||
| 
 | ||||
| static const struct ixgbe_mac_operations ixgbevf_mac_ops = { | ||||
| 	.init_hw             = ixgbevf_init_hw_vf, | ||||
| 	.reset_hw            = ixgbevf_reset_hw_vf, | ||||
| 	.start_hw            = ixgbevf_start_hw_vf, | ||||
| 	.get_mac_addr        = ixgbevf_get_mac_addr_vf, | ||||
| 	.stop_adapter        = ixgbevf_stop_hw_vf, | ||||
| 	.setup_link          = ixgbevf_setup_mac_link_vf, | ||||
| 	.check_link          = ixgbevf_check_mac_link_vf, | ||||
| 	.set_rar             = ixgbevf_set_rar_vf, | ||||
| 	.update_mc_addr_list = ixgbevf_update_mc_addr_list_vf, | ||||
| 	.set_uc_addr         = ixgbevf_set_uc_addr_vf, | ||||
| 	.set_vfta            = ixgbevf_set_vfta_vf, | ||||
| }; | ||||
| 
 | ||||
| const struct ixgbevf_info ixgbevf_82599_vf_info = { | ||||
| 	.mac = ixgbe_mac_82599_vf, | ||||
| 	.mac_ops = &ixgbevf_mac_ops, | ||||
| }; | ||||
| 
 | ||||
| const struct ixgbevf_info ixgbevf_X540_vf_info = { | ||||
| 	.mac = ixgbe_mac_X540_vf, | ||||
| 	.mac_ops = &ixgbevf_mac_ops, | ||||
| }; | ||||
							
								
								
									
										210
									
								
								drivers/net/ethernet/intel/ixgbevf/vf.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										210
									
								
								drivers/net/ethernet/intel/ixgbevf/vf.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,210 @@ | |||
| /*******************************************************************************
 | ||||
| 
 | ||||
|   Intel 82599 Virtual Function 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: | ||||
|   e1000-devel Mailing List <e1000-devel@lists.sourceforge.net> | ||||
|   Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 | ||||
| 
 | ||||
| *******************************************************************************/ | ||||
| 
 | ||||
| #ifndef __IXGBE_VF_H__ | ||||
| #define __IXGBE_VF_H__ | ||||
| 
 | ||||
| #include <linux/pci.h> | ||||
| #include <linux/delay.h> | ||||
| #include <linux/interrupt.h> | ||||
| #include <linux/if_ether.h> | ||||
| #include <linux/netdevice.h> | ||||
| 
 | ||||
| #include "defines.h" | ||||
| #include "regs.h" | ||||
| #include "mbx.h" | ||||
| 
 | ||||
| struct ixgbe_hw; | ||||
| 
 | ||||
| /* iterator type for walking multicast address lists */ | ||||
| typedef u8* (*ixgbe_mc_addr_itr) (struct ixgbe_hw *hw, u8 **mc_addr_ptr, | ||||
| 				  u32 *vmdq); | ||||
| struct ixgbe_mac_operations { | ||||
| 	s32 (*init_hw)(struct ixgbe_hw *); | ||||
| 	s32 (*reset_hw)(struct ixgbe_hw *); | ||||
| 	s32 (*start_hw)(struct ixgbe_hw *); | ||||
| 	s32 (*clear_hw_cntrs)(struct ixgbe_hw *); | ||||
| 	enum ixgbe_media_type (*get_media_type)(struct ixgbe_hw *); | ||||
| 	s32 (*get_mac_addr)(struct ixgbe_hw *, u8 *); | ||||
| 	s32 (*stop_adapter)(struct ixgbe_hw *); | ||||
| 	s32 (*get_bus_info)(struct ixgbe_hw *); | ||||
| 
 | ||||
| 	/* Link */ | ||||
| 	s32 (*setup_link)(struct ixgbe_hw *, ixgbe_link_speed, bool, bool); | ||||
| 	s32 (*check_link)(struct ixgbe_hw *, ixgbe_link_speed *, bool *, bool); | ||||
| 	s32 (*get_link_capabilities)(struct ixgbe_hw *, ixgbe_link_speed *, | ||||
| 				     bool *); | ||||
| 
 | ||||
| 	/* RAR, Multicast, VLAN */ | ||||
| 	s32 (*set_rar)(struct ixgbe_hw *, u32, u8 *, u32); | ||||
| 	s32 (*set_uc_addr)(struct ixgbe_hw *, u32, u8 *); | ||||
| 	s32 (*init_rx_addrs)(struct ixgbe_hw *); | ||||
| 	s32 (*update_mc_addr_list)(struct ixgbe_hw *, struct net_device *); | ||||
| 	s32 (*enable_mc)(struct ixgbe_hw *); | ||||
| 	s32 (*disable_mc)(struct ixgbe_hw *); | ||||
| 	s32 (*clear_vfta)(struct ixgbe_hw *); | ||||
| 	s32 (*set_vfta)(struct ixgbe_hw *, u32, u32, bool); | ||||
| }; | ||||
| 
 | ||||
| enum ixgbe_mac_type { | ||||
| 	ixgbe_mac_unknown = 0, | ||||
| 	ixgbe_mac_82599_vf, | ||||
| 	ixgbe_mac_X540_vf, | ||||
| 	ixgbe_num_macs | ||||
| }; | ||||
| 
 | ||||
| struct ixgbe_mac_info { | ||||
| 	struct ixgbe_mac_operations ops; | ||||
| 	u8 addr[6]; | ||||
| 	u8 perm_addr[6]; | ||||
| 
 | ||||
| 	enum ixgbe_mac_type type; | ||||
| 
 | ||||
| 	s32  mc_filter_type; | ||||
| 
 | ||||
| 	bool get_link_status; | ||||
| 	u32  max_tx_queues; | ||||
| 	u32  max_rx_queues; | ||||
| 	u32  max_msix_vectors; | ||||
| }; | ||||
| 
 | ||||
| struct ixgbe_mbx_operations { | ||||
| 	s32 (*init_params)(struct ixgbe_hw *hw); | ||||
| 	s32 (*read)(struct ixgbe_hw *, u32 *, u16); | ||||
| 	s32 (*write)(struct ixgbe_hw *, u32 *, u16); | ||||
| 	s32 (*read_posted)(struct ixgbe_hw *, u32 *, u16); | ||||
| 	s32 (*write_posted)(struct ixgbe_hw *, u32 *, u16); | ||||
| 	s32 (*check_for_msg)(struct ixgbe_hw *); | ||||
| 	s32 (*check_for_ack)(struct ixgbe_hw *); | ||||
| 	s32 (*check_for_rst)(struct ixgbe_hw *); | ||||
| }; | ||||
| 
 | ||||
| struct ixgbe_mbx_stats { | ||||
| 	u32 msgs_tx; | ||||
| 	u32 msgs_rx; | ||||
| 
 | ||||
| 	u32 acks; | ||||
| 	u32 reqs; | ||||
| 	u32 rsts; | ||||
| }; | ||||
| 
 | ||||
| struct ixgbe_mbx_info { | ||||
| 	struct ixgbe_mbx_operations ops; | ||||
| 	struct ixgbe_mbx_stats stats; | ||||
| 	u32 timeout; | ||||
| 	u32 udelay; | ||||
| 	u32 v2p_mailbox; | ||||
| 	u16 size; | ||||
| }; | ||||
| 
 | ||||
| struct ixgbe_hw { | ||||
| 	void *back; | ||||
| 
 | ||||
| 	u8 __iomem *hw_addr; | ||||
| 
 | ||||
| 	struct ixgbe_mac_info mac; | ||||
| 	struct ixgbe_mbx_info mbx; | ||||
| 
 | ||||
| 	u16 device_id; | ||||
| 	u16 subsystem_vendor_id; | ||||
| 	u16 subsystem_device_id; | ||||
| 	u16 vendor_id; | ||||
| 
 | ||||
| 	u8  revision_id; | ||||
| 	bool adapter_stopped; | ||||
| 
 | ||||
| 	int api_version; | ||||
| }; | ||||
| 
 | ||||
| struct ixgbevf_hw_stats { | ||||
| 	u64 base_vfgprc; | ||||
| 	u64 base_vfgptc; | ||||
| 	u64 base_vfgorc; | ||||
| 	u64 base_vfgotc; | ||||
| 	u64 base_vfmprc; | ||||
| 
 | ||||
| 	u64 last_vfgprc; | ||||
| 	u64 last_vfgptc; | ||||
| 	u64 last_vfgorc; | ||||
| 	u64 last_vfgotc; | ||||
| 	u64 last_vfmprc; | ||||
| 
 | ||||
| 	u64 vfgprc; | ||||
| 	u64 vfgptc; | ||||
| 	u64 vfgorc; | ||||
| 	u64 vfgotc; | ||||
| 	u64 vfmprc; | ||||
| 
 | ||||
| 	u64 saved_reset_vfgprc; | ||||
| 	u64 saved_reset_vfgptc; | ||||
| 	u64 saved_reset_vfgorc; | ||||
| 	u64 saved_reset_vfgotc; | ||||
| 	u64 saved_reset_vfmprc; | ||||
| }; | ||||
| 
 | ||||
| struct ixgbevf_info { | ||||
| 	enum ixgbe_mac_type		mac; | ||||
| 	const struct ixgbe_mac_operations *mac_ops; | ||||
| }; | ||||
| 
 | ||||
| #define IXGBE_FAILED_READ_REG 0xffffffffU | ||||
| 
 | ||||
| #define IXGBE_REMOVED(a) unlikely(!(a)) | ||||
| 
 | ||||
| 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(h, r, v) ixgbe_write_reg(h, r, v) | ||||
| 
 | ||||
| u32 ixgbevf_read_reg(struct ixgbe_hw *hw, u32 reg); | ||||
| #define IXGBE_READ_REG(h, r) ixgbevf_read_reg(h, r) | ||||
| 
 | ||||
| static inline void ixgbe_write_reg_array(struct ixgbe_hw *hw, u32 reg, | ||||
| 					  u32 offset, u32 value) | ||||
| { | ||||
| 	ixgbe_write_reg(hw, reg + (offset << 2), value); | ||||
| } | ||||
| #define IXGBE_WRITE_REG_ARRAY(h, r, o, v) ixgbe_write_reg_array(h, r, o, v) | ||||
| 
 | ||||
| static inline u32 ixgbe_read_reg_array(struct ixgbe_hw *hw, u32 reg, | ||||
| 					u32 offset) | ||||
| { | ||||
| 	return ixgbevf_read_reg(hw, reg + (offset << 2)); | ||||
| } | ||||
| #define IXGBE_READ_REG_ARRAY(h, r, o) ixgbe_read_reg_array(h, r, o) | ||||
| 
 | ||||
| void ixgbevf_rlpml_set_vf(struct ixgbe_hw *hw, u16 max_size); | ||||
| int ixgbevf_negotiate_api_version(struct ixgbe_hw *hw, int api); | ||||
| int ixgbevf_get_queues(struct ixgbe_hw *hw, unsigned int *num_tcs, | ||||
| 		       unsigned int *default_tc); | ||||
| #endif /* __IXGBE_VF_H__ */ | ||||
| 
 | ||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 awab228
						awab228