text: /*
   * Copyright (c) 2001-2013, Intel Corporation 
   * All rights reserved.
   *
   * Redistribution and use in source and binary forms, with or without 
   * modification, are permitted provided that the following conditions are met:
   *
   *  1. Redistributions of source code must retain the above copyright notice, 
   *     this list of conditions and the following disclaimer.
   *
   *  2. Redistributions in binary form must reproduce the above copyright 
   *     notice, this list of conditions and the following disclaimer in the 
   *     documentation and/or other materials provided with the distribution.
   *
   *  3. Neither the name of the Intel Corporation nor the names of its 
   *     contributors may be used to endorse or promote products derived from 
   *     this software without specific prior written permission.
   *
   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
   * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 
   * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 
   * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
   * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
   * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
   * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   * POSSIBILITY OF SUCH DAMAGE.
   */
  
  #ifndef _IF_IX_H_
  #define _IF_IX_H_
  
  /* Tunables */
  
  /*
   * MSI-X count
   */
  #define IX_MAX_MSIX		64
  #define IX_MAX_MSIX_82598	16
  
  /*
   * RX ring count
   */
  #define IX_MAX_RXRING		16
  #define IX_MAX_RXRING_X550	64
  #define IX_MIN_RXRING_RSS	2
  
  /*
   * TX ring count
   */
  #define IX_MAX_TXRING		16
  #define IX_MAX_TXRING_82598	32
  #define IX_MAX_TXRING_82599	64
  #define IX_MAX_TXRING_X540	64
  #define IX_MAX_TXRING_X550	64
  
  /*
   * Default number of segments received before writing to RX related registers
   */
  #define IX_DEF_RXWREG_NSEGS	32
  
  /*
   * Default number of segments sent before writing to TX related registers
   */
  #define IX_DEF_TXWREG_NSEGS	8
  
  /*
   * TxDescriptors Valid Range: 64-4096 Default Value: 256 This value is the
   * number of transmit descriptors allocated by the driver. Increasing this
   * value allows the driver to queue more transmits. Each descriptor is 16
   * bytes. Performance tests have show the 2K value to be optimal for top
   * performance.
   */
  #define IX_DEF_TXD		1024
  #define IX_PERF_TXD		2048
  #define IX_MAX_TXD		4096
  #define IX_MIN_TXD		64
  
  /*
   * RxDescriptors Valid Range: 64-4096 Default Value: 256 This value is the
   * number of receive descriptors allocated for each RX queue. Increasing this
   * value allows the driver to buffer more incoming packets. Each descriptor
   * is 16 bytes.  A receive buffer is also allocated for each descriptor. 
   * 
   * Note: with 8 rings and a dual port card, it is possible to bump up 
   *	against the system mbuf pool limit, you can tune nmbclusters
   *	to adjust for this.
   */
  #define IX_DEF_RXD		1024
  #define IX_PERF_RXD		2048
  #define IX_MAX_RXD		4096
  #define IX_MIN_RXD		64
  
  /* Alignment for rings */
  #define IX_DBA_ALIGN		128
  
  #define IX_MAX_FRAME_SIZE	9728
  #define IX_MTU_HDR		(ETHER_HDR_LEN + ETHER_CRC_LEN + EVL_ENCAPLEN)
  #define IX_MAX_MTU		(IX_MAX_FRAME_SIZE - IX_MTU_HDR)
  
  
  /* Flow control constants */
  #define IX_FC_PAUSE		0xFFFF
  #define IX_FC_HI		0x20000
  #define IX_FC_LO		0x10000
  
  /*
   * RSS related registers
   */
  #define IX_NRSSRK		10
  #define IX_RSSRK_SIZE		4
  #define IX_RSSRK_VAL(key, i)	(key[(i) * IX_RSSRK_SIZE] | \
  				 key[(i) * IX_RSSRK_SIZE + 1] << 8 | \
  				 key[(i) * IX_RSSRK_SIZE + 2] << 16 | \
  				 key[(i) * IX_RSSRK_SIZE + 3] << 24)
  #define IX_NRETA		32
  #define IX_NRETA_X550		128
  #define IX_NRETA_MAX		128
  #define IX_RETA_SIZE		4
  
  #define IX_RDRTABLE_SIZE	(IX_NRETA_MAX * IX_RETA_SIZE)
  
  /*
   * EITR
   */
  #define IX_EITR_INTVL_MASK_82598 0xffff
  #define IX_EITR_INTVL_MASK	0x0fff
  #define IX_EITR_INTVL_RSVD_MASK	0x0007
  #define IX_EITR_INTVL_MIN	IXGBE_MIN_EITR
  #define IX_EITR_INTVL_MAX	IXGBE_MAX_EITR
  
  /*
   * Used for optimizing small rx mbufs.  Effort is made to keep the copy
   * small and aligned for the CPU L1 cache.
   * 
   * MHLEN is typically 168 bytes, giving us 8-byte alignment.  Getting
   * 32 byte alignment needed for the fast bcopy results in 8 bytes being
   * wasted.  Getting 64 byte alignment, which _should_ be ideal for
   * modern Intel CPUs, results in 40 bytes wasted and a significant drop
   * in observed efficiency of the optimization, 97.9% -> 81.8%.
   */
  #define IX_RX_COPY_LEN		160
  #define IX_RX_COPY_ALIGN	(MHLEN - IX_RX_COPY_LEN)
  
  #define IX_MAX_MCASTADDR	128
  
  #define IX_MSIX_BAR_82598	3
  #define IX_MSIX_BAR_82599	4
  
  #define IX_TSO_SIZE		(IP_MAXPACKET + \
  				 sizeof(struct ether_vlan_header))
  
  /*
   * MUST be less than 38.  Though 82598 does not have this limit,
   * we don't want long TX chain.  33 should be large enough even
   * for 64K TSO (32 x 2K mbuf cluster and 1 x mbuf header).
   *
   * Reference:
   * - 82599 datasheet 7.2.1.1
   * - X540 datasheet 7.2.1.1
   */
  #define IX_MAX_SCATTER		33
  #define IX_TX_RESERVED		3	/* 1 for TX ctx, 2 reserved */
  
  /* MSI and legacy interrupt */
  #define IX_TX_INTR_VEC		0
  #define IX_TX_INTR_MASK		(1 << IX_TX_INTR_VEC)
  #define IX_RX0_INTR_VEC		1
  #define IX_RX0_INTR_MASK	(1 << IX_RX0_INTR_VEC)
  #define IX_RX1_INTR_VEC		2
  #define IX_RX1_INTR_MASK	(1 << IX_RX1_INTR_VEC)
  
  #define IX_INTR_RATE		8000
  #define IX_MSIX_RX_RATE		8000
  #define IX_MSIX_TX_RATE		6000
  
  /* IOCTL define to gather SFP+ Diagnostic data */
  #define SIOCGI2C		SIOCGIFGENERIC
  
  /* TX checksum offload */
  #define CSUM_OFFLOAD		(CSUM_IP|CSUM_TCP|CSUM_UDP)
  
  #define IX_EICR_STATUS		(IXGBE_EICR_LSC | IXGBE_EICR_ECC | \
  				 IXGBE_EICR_GPI_SDP1 | IXGBE_EICR_GPI_SDP2 | \
  				 IXGBE_EICR_TS)
  
  /* This is used to get SFP+ module data */
  struct ix_i2c_req {
  	uint8_t		dev_addr;
  	uint8_t		offset;
  	uint8_t		len;
  	uint8_t		data[8];
  };
  
  struct ix_mc_addr {
  	uint8_t		addr[IXGBE_ETH_LENGTH_OF_ADDRESS];
  	uint32_t	vmdq;
  };
  
  struct ix_tx_buf {
  	struct mbuf	*m_head;
  	bus_dmamap_t	map;
  };
  
  struct ix_rx_buf {
  	struct mbuf	*m_head;
  	struct mbuf	*fmp;
  	struct mbuf	*lmp;
  	bus_dmamap_t	map;
  	bus_addr_t	paddr;
  	u_int		flags;
  #define IX_RX_COPY	0x1
  };
  
  struct ix_softc;
  
  struct ix_tx_ring {
  	struct lwkt_serialize	tx_serialize;
  	struct ifaltq_subque	*tx_ifsq;
  	struct ix_softc		*tx_sc;
  	volatile uint32_t	*tx_hdr;
  	union ixgbe_adv_tx_desc	*tx_base;
  	struct ix_tx_buf	*tx_buf;
  	bus_dma_tag_t		tx_tag;
  	int8_t			tx_running;
  #define IX_TX_RUNNING		100
  #define IX_TX_RUNNING_DEC	25
  	uint8_t			tx_flags;
  #define IX_TXFLAG_ENABLED	0x1
  	uint16_t		tx_nmbuf;
  	uint32_t		tx_idx;
  	uint16_t		tx_avail;
  	uint16_t		tx_next_avail;
  	uint16_t		tx_next_clean;
  	uint16_t		tx_ndesc;
  	uint16_t		tx_wreg_nsegs;
  	uint16_t		tx_intr_nsegs;
  	uint16_t		tx_nsegs;
  	int16_t			tx_intr_vec;
  	int			tx_intr_cpuid;
  	uint32_t		tx_eims;
  	uint32_t		tx_eims_val;
  	struct ifsubq_watchdog	tx_watchdog;
  	struct callout		tx_gc_timer;
  
  	u_long			tx_gc;
  
  	bus_dma_tag_t		tx_base_dtag;
  	bus_dmamap_t		tx_base_map;
  	bus_addr_t		tx_base_paddr;
  
  	bus_dma_tag_t		tx_hdr_dtag;
  	bus_dmamap_t		tx_hdr_map;
  	bus_addr_t		tx_hdr_paddr;
  } __cachealign;
  
  struct ix_rx_ring {
  	struct lwkt_serialize	rx_serialize;
  	struct ix_softc		*rx_sc;
  	union ixgbe_adv_rx_desc	*rx_base;
  	struct ix_rx_buf	*rx_buf;
  	bus_dma_tag_t		rx_tag;
  	bus_dmamap_t		rx_sparemap;
  	uint32_t		rx_idx;
  	uint16_t		rx_flags;
  #define IX_RXRING_FLAG_LRO	0x01
  #define IX_RXRING_FLAG_DISC	0x02
  	uint16_t 		rx_next_check;
  	uint16_t		rx_ndesc;
  	uint16_t		rx_mbuf_sz;
  	uint16_t		rx_wreg_nsegs;
  	int16_t			rx_intr_vec;
  	uint32_t		rx_eims;
  	uint32_t		rx_eims_val;
  	struct ix_tx_ring	*rx_txr;	/* piggybacked TX ring */
  
  #ifdef IX_RSS_DEBUG
  	u_long			rx_pkts;
  #endif
  
  	bus_dma_tag_t		rx_base_dtag;
  	bus_dmamap_t		rx_base_map;
  	bus_addr_t		rx_base_paddr;
  } __cachealign;
  
  struct ix_intr_data {
  	struct lwkt_serialize	*intr_serialize;
  	driver_intr_t		*intr_func;
  	void			*intr_hand;
  	struct resource		*intr_res;
  	void			*intr_funcarg;
  	int			intr_rid;
  	int			intr_cpuid;
  	int			intr_rate;
  	int			intr_use;
  #define IX_INTR_USE_RXTX	0
  #define IX_INTR_USE_STATUS	1
  #define IX_INTR_USE_RX		2
  #define IX_INTR_USE_TX		3
  	const char		*intr_desc;
  	char			intr_desc0[64];
  };
  
  struct ix_softc {
  	struct arpcom		arpcom;
  
  	struct ixgbe_hw		hw;
  	struct ixgbe_osdep	osdep;
  
  	struct lwkt_serialize	main_serialize;
  	uint32_t		intr_mask;
  
  	boolean_t		link_active;
  
  	int			rx_ring_inuse;
  	int			tx_ring_inuse;
  
  	struct ix_rx_ring	*rx_rings;
  	struct ix_tx_ring	*tx_rings;
  
  	struct callout		timer;
  	int			timer_cpuid;
  
  	int			ifm_media;	/* IFM_ */
  	uint32_t		link_speed;
  	bool			link_up;
  	boolean_t		sfp_probe;	/* pluggable optics */
  	uint32_t		phy_layer;
  
  	uint16_t		caps;		/* IX_CAP_ */
  #define IX_CAP_DETECT_FANFAIL	0x0001
  #define IX_CAP_TEMP_SENSOR	0x0002
  #define IX_CAP_EEE		0x0004
  #define IX_CAP_LEGACY_INTR	0x0008
  #define IX_CAP_FW_RECOVERY	0x0010
  
  	uint16_t		flags;		/* IX_FLAG_ */
  #define IX_FLAG_FW_RECOVERY	0x0001
  
  	struct callout		fw_timer;
  
  	struct ixgbe_hw_stats 	stats;
  
  	int			rx_ring_cnt;
  	int			rx_ring_msix;
  
  	int			tx_ring_cnt;
  	int			tx_ring_msix;
  
  	int			intr_type;
  	int			intr_cnt;
  	struct ix_intr_data	*intr_data;
  
  	device_t		dev;
  	bus_dma_tag_t		parent_tag;
  	struct ifmedia		media;
  
  	struct resource		*mem_res;
  	int			mem_rid;
  
  	struct resource 	*msix_mem_res;
  	int			msix_mem_rid;
  
  	int			nserialize;
  	struct lwkt_serialize	**serializes;
  
  	struct ix_mc_addr	*mta;		/* Multicast array memory */
  
  	int			if_flags;
  	int			advspeed;	/* advertised link speeds */
  	uint32_t		wufc;		/* power management */
  	uint16_t		dmac;		/* DMA coalescing */
  	uint16_t		max_frame_size;
  	int16_t			sts_msix_vec;	/* status MSI-X vector */
  
  	struct if_ringmap	*tx_rmap;
  	struct if_ringmap	*tx_rmap_intr;
  	struct if_ringmap	*rx_rmap;
  	struct if_ringmap	*rx_rmap_intr;
  
  	int			rdr_table[IX_RDRTABLE_SIZE];
  
  	struct task		wdog_task;
  	int			direct_input;
  #ifdef IX_RSS_DEBUG
  	int			rss_debug;
  #endif
  };
  
  #define IX_ENABLE_HWRSS(sc)	((sc)->rx_ring_cnt > 1)
  #define IX_ENABLE_HWTSS(sc)	((sc)->tx_ring_cnt > 1)
  
  #endif /* _IF_IX_H_ */
  