#ifndef _IXGBE_H_
#define _IXGBE_H_
#include <sys/param.h>
#include <sys/reboot.h>
#include <sys/systm.h>
#include <sys/pcq.h>
#include <sys/mbuf.h>
#include <sys/protosw.h>
#include <sys/socket.h>
#include <sys/malloc.h>
#include <sys/kernel.h>
#include <sys/module.h>
#include <sys/sockio.h>
#include <sys/percpu.h>
#include <net/if.h>
#include <net/if_arp.h>
#include <net/bpf.h>
#include <net/if_ether.h>
#include <net/if_dl.h>
#include <net/if_media.h>
#include <net/if_types.h>
#include <net/if_vlanvar.h>
#include <netinet/in_systm.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/ip6.h>
#include <netinet/tcp.h>
#include <netinet/udp.h>
#include <sys/bus.h>
#include <dev/pci/pcivar.h>
#include <dev/pci/pcireg.h>
#include <sys/proc.h>
#include <sys/sysctl.h>
#include <sys/endian.h>
#include <sys/workqueue.h>
#include <sys/cpu.h>
#include <sys/interrupt.h>
#include <sys/bitops.h>
#include "ixgbe_netbsd.h"
#include "ixgbe_api.h"
#include "ixgbe_common.h"
#include "ixgbe_vf.h"
#include "ixgbe_features.h"
#define DEFAULT_TXD 2048
#define MAX_TXD 4096
#define MIN_TXD 64
#define DEFAULT_RXD 2048
#define MAX_RXD 4096
#define MIN_RXD 64
#define DBA_ALIGN 128
#define IXGBE_WATCHDOG (10 * hz)
#define IXGBE_TX_CLEANUP_THRESHOLD(_a) ((_a)->num_tx_desc / 8)
#define IXGBE_TX_OP_THRESHOLD(_a) ((_a)->num_tx_desc / 32)
#define IXGBE_MAX_FRAME_SIZE 9728
#define IXGBE_MTU_HDR (ETHER_HDR_LEN + ETHER_CRC_LEN)
#define IXGBE_MTU_HDR_VLAN (ETHER_HDR_LEN + ETHER_CRC_LEN + \
ETHER_VLAN_ENCAP_LEN)
#define IXGBE_MAX_MTU (IXGBE_MAX_FRAME_SIZE - IXGBE_MTU_HDR)
#define IXGBE_MAX_MTU_VLAN (IXGBE_MAX_FRAME_SIZE - IXGBE_MTU_HDR_VLAN)
#define IXGBE_FC_PAUSE 0xFFFF
#define IXGBE_RX_COPY_LEN_MAX (MHLEN - ETHER_ALIGN)
#define IXGBE_TX_WTHRESH 5
#define IXGBE_82599_SCATTER_MAX (40 - IXGBE_TX_WTHRESH - 2)
#define IXGBE_SCATTER_DEFAULT 33
#define DEBUG_INIT 0
#define DEBUG_IOCTL 0
#define DEBUG_HW 0
#define INIT_DEBUGOUT(S) if (DEBUG_INIT) printf(S "\n")
#define INIT_DEBUGOUT1(S, A) if (DEBUG_INIT) printf(S "\n", A)
#define INIT_DEBUGOUT2(S, A, B) if (DEBUG_INIT) printf(S "\n", A, B)
#define IOCTL_DEBUGOUT(S) if (DEBUG_IOCTL) printf(S "\n")
#define IOCTL_DEBUGOUT1(S, A) if (DEBUG_IOCTL) printf(S "\n", A)
#define IOCTL_DEBUGOUT2(S, A, B) if (DEBUG_IOCTL) printf(S "\n", A, B)
#define HW_DEBUGOUT(S) if (DEBUG_HW) printf(S "\n")
#define HW_DEBUGOUT1(S, A) if (DEBUG_HW) printf(S "\n", A)
#define HW_DEBUGOUT2(S, A, B) if (DEBUG_HW) printf(S "\n", A, B)
#define MAX_NUM_MULTICAST_ADDRESSES 128
#define MSIX_82598_BAR 3
#define MSIX_82599_BAR 4
#define IXGBE_TSO_SIZE 262140
#define IXGBE_RX_HDR 128
#define IXGBE_VFTA_SIZE 128
#define IXGBE_BR_SIZE 2048
#define IXGBE_QUEUE_MIN_FREE 32
#define IXGBE_MAX_TX_BUSY 10
#define IXGBE_QUEUE_HUNG 0x80000000
#define IXGBE_EITR_DEFAULT 128
#define SIOCGI2C SIOCGIFGENERIC
#define M_CSUM_OFFLOAD \
(M_CSUM_IPv4|M_CSUM_UDPv4|M_CSUM_TCPv4|M_CSUM_UDPv6|M_CSUM_TCPv6)
#ifndef pci_find_cap
#define pci_find_cap pci_find_extcap
#endif
#ifndef DEVMETHOD_END
#define DEVMETHOD_END { NULL, NULL }
#endif
#define IXGBE_LOW_LATENCY 128
#define IXGBE_AVE_LATENCY 400
#define IXGBE_BULK_LATENCY 1200
#define IXGBE_LINK_ITR_QUANTA 0x1FF
#define IXGBE_LINK_ITR ((IXGBE_LINK_ITR_QUANTA << 3) & \
IXGBE_EITR_ITR_INT_MASK)
typedef struct _ixgbe_vendor_info_t {
unsigned int vendor_id;
unsigned int device_id;
unsigned int subvendor_id;
unsigned int subdevice_id;
unsigned int index;
} ixgbe_vendor_info_t;
struct ixgbe_i2c_req {
u8 dev_addr;
u8 offset;
u8 len;
u8 data[8];
};
struct ixgbe_bp_data {
u32 low;
u32 high;
u32 log;
};
struct ixgbe_tx_buf {
union ixgbe_adv_tx_desc *eop;
struct mbuf *m_head;
bus_dmamap_t map;
};
struct ixgbe_rx_buf {
struct mbuf *buf;
struct mbuf *fmp;
bus_dmamap_t pmap;
u_int flags;
#define IXGBE_RX_COPY 0x01
uint64_t addr;
};
struct ixgbe_dma_alloc {
bus_addr_t dma_paddr;
void *dma_vaddr;
ixgbe_dma_tag_t *dma_tag;
bus_dmamap_t dma_map;
bus_dma_segment_t dma_seg;
bus_size_t dma_size;
};
struct ixgbe_mc_addr {
u8 addr[IXGBE_ETH_LENGTH_OF_ADDRESS];
u32 vmdq;
};
struct ix_queue {
struct ixgbe_softc *sc;
u32 msix;
u32 eitr_setting;
u8 me;
struct resource *res;
int busy;
struct tx_ring *txr;
struct rx_ring *rxr;
struct work wq_cookie;
void *que_si;
struct evcnt irqs;
struct evcnt handleq;
struct evcnt req;
char namebuf[32];
char evnamebuf[32];
kmutex_t dc_mtx;
int disabled_count;
bool txrx_use_workqueue;
};
struct tx_ring {
struct ixgbe_softc *sc;
kmutex_t tx_mtx;
u8 me;
u32 tail;
int busy;
union ixgbe_adv_tx_desc *tx_base;
struct ixgbe_tx_buf *tx_buffers;
struct ixgbe_dma_alloc txdma;
volatile u16 tx_avail;
u16 next_avail_desc;
u16 next_to_clean;
u16 num_desc;
ixgbe_dma_tag_t *txtag;
#if 0
char mtx_name[16];
#endif
pcq_t *txr_interq;
struct work wq_cookie;
void *txr_si;
bool txr_no_space;
#ifdef IXGBE_FDIR
u16 atr_sample;
u16 atr_count;
#endif
u64 bytes;
u64 packets;
struct evcnt total_packets;
struct evcnt pcq_drops;
struct evcnt no_desc_avail;
struct evcnt tso_tx;
u64 q_efbig_tx_dma_setup;
u64 q_mbuf_defrag_failed;
u64 q_efbig2_tx_dma_setup;
u64 q_einval_tx_dma_setup;
u64 q_other_tx_dma_setup;
u64 q_eagain_tx_dma_setup;
u64 q_enomem_tx_dma_setup;
u64 q_tso_err;
};
struct rx_ring {
struct ixgbe_softc *sc;
kmutex_t rx_mtx;
u8 me;
u32 tail;
union ixgbe_adv_rx_desc *rx_base;
struct ixgbe_dma_alloc rxdma;
#ifdef LRO
struct lro_ctrl lro;
bool lro_enabled;
#endif
#ifdef RSC
bool hw_rsc;
#endif
bool vtag_strip;
bool discard_multidesc;
u16 next_to_refresh;
u16 next_to_check;
u16 num_desc;
u16 mbuf_sz;
#if 0
char mtx_name[16];
#endif
struct ixgbe_rx_buf *rx_buffers;
ixgbe_dma_tag_t *ptag;
u64 bytes;
u64 packets;
struct evcnt rx_copies;
struct evcnt rx_packets;
struct evcnt rx_bytes;
struct evcnt rx_discarded;
struct evcnt no_mbuf;
#ifdef RSC
u64 rsc_num;
#endif
};
struct ixgbe_vf {
u_int pool;
u_int rar_index;
u_int max_frame_size;
uint32_t flags;
uint8_t ether_addr[ETHER_ADDR_LEN];
uint16_t mc_hash[IXGBE_MAX_VF_MC];
uint16_t num_mc_hashes;
uint16_t default_vlan;
uint16_t vlan_tag;
uint16_t api_ver;
};
struct ixgbe_tc {
char evnamebuf[32];
};
struct ixgbe_softc {
struct ixgbe_hw hw;
struct ixgbe_osdep osdep;
device_t dev;
struct ifnet *ifp;
struct if_percpuq *ipq;
struct resource *pci_mem;
struct ifmedia media;
callout_t timer;
struct workqueue *timer_wq;
struct work timer_wc;
u_int timer_pending;
u_short if_flags;
int ec_capenable;
kmutex_t core_mtx;
unsigned int num_queues;
u32 shadow_vfta[IXGBE_VFTA_SIZE];
int advertise;
bool enable_aim;
int max_interrupt_rate;
int link_active;
u16 max_frame_size;
u16 num_segs;
u32 link_speed;
bool link_up;
bool link_enabled;
u32 vector;
u16 dmac;
u32 phy_layer;
bool wol_support;
u32 wufc;
u32 rx_mbuf_sz;
bool schedule_wqs_ok;
int fdir_reinit;
struct workqueue *admin_wq;
struct work admin_wc;
u_int admin_pending;
volatile u32 task_requests;
kmutex_t admin_mtx;
bool txrx_use_workqueue;
struct workqueue *que_wq;
struct workqueue *txr_wq;
percpu_t *txr_wq_enqueued;
struct ix_queue *queues;
struct tx_ring *tx_rings;
u32 num_tx_desc;
u32 tx_process_limit;
struct rx_ring *rx_rings;
u64 active_queues;
u32 num_rx_desc;
u32 rx_process_limit;
u32 rx_copy_len;
struct ixgbe_mc_addr *mta;
int iov_mode;
int num_vfs;
int pool;
struct ixgbe_vf *vfs;
struct ixgbe_bp_data bypass;
void (*init_locked)(struct ixgbe_softc *);
void (*stop_locked)(void *);
u_int recovery_mode;
callout_t recovery_mode_timer;
struct workqueue *recovery_mode_timer_wq;
struct work recovery_mode_timer_wc;
u_int recovery_mode_timer_pending;
struct evcnt efbig_tx_dma_setup;
struct evcnt mbuf_defrag_failed;
struct evcnt efbig2_tx_dma_setup;
struct evcnt einval_tx_dma_setup;
struct evcnt other_tx_dma_setup;
struct evcnt eagain_tx_dma_setup;
struct evcnt enomem_tx_dma_setup;
struct evcnt tso_err;
struct evcnt watchdog_events;
struct evcnt admin_irqev;
struct evcnt link_workev;
struct evcnt mod_workev;
struct evcnt msf_workev;
struct evcnt phy_workev;
union {
struct ixgbe_hw_stats pf;
struct ixgbevf_hw_stats vf;
} stats;
#if __FreeBSD_version >= 1100036
u64 ipackets;
u64 ierrors;
u64 opackets;
u64 oerrors;
u64 ibytes;
u64 obytes;
u64 imcasts;
u64 omcasts;
u64 iqdrops;
u64 noproto;
#endif
u32 feat_cap;
u32 feat_en;
struct ixgbe_tc tcs[IXGBE_DCB_MAX_TRAFFIC_CLASS];
struct sysctllog *sysctllog;
const struct sysctlnode *sysctltop;
struct timeval lasterr_time;
};
#define ETHERTYPE_IEEE1588 0x88F7
#define PICOSECS_PER_TICK 20833
#define TSYNC_UDP_PORT 319
#define IXGBE_ADVTXD_TSTAMP 0x00080000
#define IXGBE_CORE_LOCK_INIT(_sc, _name) \
mutex_init(&(_sc)->core_mtx, MUTEX_DEFAULT, IPL_SOFTNET)
#define IXGBE_CORE_LOCK_DESTROY(_sc) mutex_destroy(&(_sc)->core_mtx)
#define IXGBE_TX_LOCK_DESTROY(_sc) mutex_destroy(&(_sc)->tx_mtx)
#define IXGBE_RX_LOCK_DESTROY(_sc) mutex_destroy(&(_sc)->rx_mtx)
#define IXGBE_CORE_LOCK(_sc) mutex_enter(&(_sc)->core_mtx)
#define IXGBE_TX_LOCK(_sc) mutex_enter(&(_sc)->tx_mtx)
#define IXGBE_TX_TRYLOCK(_sc) mutex_tryenter(&(_sc)->tx_mtx)
#define IXGBE_RX_LOCK(_sc) mutex_enter(&(_sc)->rx_mtx)
#define IXGBE_CORE_UNLOCK(_sc) mutex_exit(&(_sc)->core_mtx)
#define IXGBE_TX_UNLOCK(_sc) mutex_exit(&(_sc)->tx_mtx)
#define IXGBE_RX_UNLOCK(_sc) mutex_exit(&(_sc)->rx_mtx)
#define IXGBE_CORE_LOCK_ASSERT(_sc) KASSERT(mutex_owned(&(_sc)->core_mtx))
#define IXGBE_TX_LOCK_ASSERT(_sc) KASSERT(mutex_owned(&(_sc)->tx_mtx))
#define IXGBE_PHY_CURRENT_TEMP 0xC820
#define IXGBE_PHY_OVERTEMP_STATUS 0xC830
#define IXGBE_SYSCTL_DESC_ADV_SPEED \
"\nControl advertised link speed using these flags:\n" \
"\t0x1 - advertise 100M\n" \
"\t0x2 - advertise 1G\n" \
"\t0x4 - advertise 10G\n" \
"\t0x8 - advertise 10M\n" \
"\t0x10 - advertise 2.5G\n" \
"\t0x20 - advertise 5G\n\n" \
"\t5G, 2.5G, 100M and 10M are only supported on certain adapters."
#define IXGBE_SYSCTL_DESC_SET_FC \
"\nSet flow control mode using these values:\n" \
"\t0 - off\n" \
"\t1 - rx pause\n" \
"\t2 - tx pause\n" \
"\t3 - tx and rx pause"
static __inline u16
ixgbe_rx_unrefreshed(struct rx_ring *rxr)
{
if (rxr->next_to_check > rxr->next_to_refresh)
return (rxr->next_to_check - rxr->next_to_refresh - 1);
else
return ((rxr->num_desc + rxr->next_to_check) -
rxr->next_to_refresh - 1);
}
static __inline int
ixgbe_legacy_ring_empty(struct ifnet *ifp, pcq_t *dummy)
{
UNREFERENCED_1PARAMETER(dummy);
return IFQ_IS_EMPTY(&ifp->if_snd);
}
static __inline int
ixgbe_mq_ring_empty(struct ifnet *dummy, pcq_t *interq)
{
UNREFERENCED_1PARAMETER(dummy);
return (pcq_peek(interq) == NULL);
}
static __inline bool
ixv_check_ether_addr(u8 *addr)
{
bool status = TRUE;
if ((addr[0] == 0 && addr[1]== 0 && addr[2] == 0 &&
addr[3] == 0 && addr[4]== 0 && addr[5] == 0))
status = FALSE;
return (status);
}
static inline bool
ixgbe_fw_recovery_mode_swflag(struct ixgbe_softc *sc)
{
return (sc->feat_en & IXGBE_FEATURE_RECOVERY_MODE) &&
atomic_load_acq_uint(&sc->recovery_mode);
}
void ixgbe_legacy_start(struct ifnet *);
int ixgbe_legacy_start_locked(struct ifnet *, struct tx_ring *);
int ixgbe_mq_start(struct ifnet *, struct mbuf *);
int ixgbe_mq_start_locked(struct ifnet *, struct tx_ring *);
void ixgbe_deferred_mq_start(void *);
void ixgbe_deferred_mq_start_work(struct work *, void *);
void ixgbe_drain_all(struct ixgbe_softc *);
int ixgbe_allocate_queues(struct ixgbe_softc *);
void ixgbe_free_queues(struct ixgbe_softc *);
int ixgbe_setup_transmit_structures(struct ixgbe_softc *);
void ixgbe_free_transmit_structures(struct ixgbe_softc *);
int ixgbe_setup_receive_structures(struct ixgbe_softc *);
void ixgbe_free_receive_structures(struct ixgbe_softc *);
bool ixgbe_txeof(struct tx_ring *);
bool ixgbe_rxeof(struct ix_queue *);
#define IXGBE_REQUEST_TASK_MOD 0x01
#define IXGBE_REQUEST_TASK_MOD_WOI 0x02
#define IXGBE_REQUEST_TASK_MSF 0x04
#define IXGBE_REQUEST_TASK_MSF_WOI 0x08
#define IXGBE_REQUEST_TASK_MBX 0x10
#define IXGBE_REQUEST_TASK_FDIR 0x20
#define IXGBE_REQUEST_TASK_PHY 0x40
#define IXGBE_REQUEST_TASK_LSC 0x80
const struct sysctlnode *ixgbe_sysctl_instance(struct ixgbe_softc *);
#include "ixgbe_bypass.h"
#include "ixgbe_fdir.h"
#include "ixgbe_rss.h"
#include "ixgbe_netmap.h"
#endif