#ifndef _IF_HNVAR_H_
#define _IF_HNVAR_H_
#define HN_USE_TXDESC_BUFRING
#define HN_CHIM_SIZE (15 * 1024 * 1024)
#define HN_RXBUF_SIZE (31 * 1024 * 1024)
#define HN_RXBUF_SIZE_COMPAT (15 * 1024 * 1024)
#define HN_MTU_MAX (65535 - ETHER_ADDR_LEN)
#define HN_TXBR_SIZE (128 * PAGE_SIZE)
#define HN_RXBR_SIZE (128 * PAGE_SIZE)
#define HN_XACT_REQ_PGCNT 2
#define HN_XACT_RESP_PGCNT 2
#define HN_XACT_REQ_SIZE (HN_XACT_REQ_PGCNT * PAGE_SIZE)
#define HN_XACT_RESP_SIZE (HN_XACT_RESP_PGCNT * PAGE_SIZE)
#define HN_GPACNT_MAX 32
struct hn_txdesc;
#ifndef HN_USE_TXDESC_BUFRING
SLIST_HEAD(hn_txdesc_list, hn_txdesc);
#else
struct buf_ring;
#endif
struct hn_tx_ring;
#define HN_NVS_RSC_MAX 562
struct hn_rx_rsc {
const uint32_t *vlan_info;
const uint32_t *csum_info;
const uint32_t *hash_info;
const uint32_t *hash_value;
uint32_t cnt;
uint32_t pktlen;
uint8_t is_last;
const void *frag_data[HN_NVS_RSC_MAX];
uint32_t frag_len[HN_NVS_RSC_MAX];
};
struct hn_rx_ring {
if_t hn_ifp;
if_t hn_rxvf_ifp;
struct hn_tx_ring *hn_txr;
void *hn_pktbuf;
int hn_pktbuf_len;
int hn_rx_flags;
uint32_t hn_mbuf_hash;
uint8_t *hn_rxbuf;
int hn_rx_idx;
struct hn_rx_rsc rsc;
int hn_trust_hcsum;
struct lro_ctrl hn_lro;
u_long hn_csum_ip;
u_long hn_csum_tcp;
u_long hn_csum_udp;
u_long hn_csum_trusted;
u_long hn_lro_tried;
u_long hn_small_pkts;
u_long hn_pkts;
u_long hn_rss_pkts;
u_long hn_ack_failed;
u_long hn_rsc_pkts;
u_long hn_rsc_drop;
struct sysctl_oid *hn_rx_sysctl_tree;
void *hn_br;
struct vmbus_channel *hn_chan;
} __aligned(CACHE_LINE_SIZE);
#define HN_TRUST_HCSUM_IP 0x0001
#define HN_TRUST_HCSUM_TCP 0x0002
#define HN_TRUST_HCSUM_UDP 0x0004
#define HN_RX_FLAG_ATTACHED 0x0001
#define HN_RX_FLAG_BR_REF 0x0002
#define HN_RX_FLAG_XPNT_VF 0x0004
#define HN_RX_FLAG_UDP_HASH 0x0008
struct hn_tx_ring {
#ifndef HN_USE_TXDESC_BUFRING
struct mtx hn_txlist_spin;
struct hn_txdesc_list hn_txlist;
#else
struct buf_ring *hn_txdesc_br;
#endif
int hn_txdesc_cnt;
int hn_txdesc_avail;
u_short hn_has_txeof;
u_short hn_txdone_cnt;
int hn_sched_tx;
void (*hn_txeof)(struct hn_tx_ring *);
struct taskqueue *hn_tx_taskq;
struct task hn_tx_task;
struct task hn_txeof_task;
struct buf_ring *hn_mbuf_br;
int hn_oactive;
int hn_tx_idx;
int hn_tx_flags;
struct mtx hn_tx_lock;
struct hn_softc *hn_sc;
struct vmbus_channel *hn_chan;
int hn_direct_tx_size;
int hn_chim_size;
bus_dma_tag_t hn_tx_data_dtag;
uint64_t hn_csum_assist;
int hn_agg_szmax;
short hn_agg_pktmax;
short hn_agg_align;
struct hn_txdesc *hn_agg_txd;
int hn_agg_szleft;
short hn_agg_pktleft;
struct rndis_packet_msg *hn_agg_prevpkt;
int hn_stat_size;
short hn_stat_pkts;
short hn_stat_mcasts;
int (*hn_sendpkt)(struct hn_tx_ring *, struct hn_txdesc *);
int hn_suspended;
int hn_gpa_cnt;
struct vmbus_gpa hn_gpa[HN_GPACNT_MAX];
u_long hn_no_txdescs;
u_long hn_send_failed;
u_long hn_txdma_failed;
u_long hn_tx_collapsed;
u_long hn_tx_chimney_tried;
u_long hn_tx_chimney;
u_long hn_pkts;
u_long hn_sends;
u_long hn_flush_failed;
struct hn_txdesc *hn_txdesc;
bus_dma_tag_t hn_tx_rndis_dtag;
struct sysctl_oid *hn_tx_sysctl_tree;
} __aligned(CACHE_LINE_SIZE);
#define HN_TX_FLAG_ATTACHED 0x0001
#define HN_TX_FLAG_HASHVAL 0x0002
struct hn_softc {
if_t hn_ifp;
struct ifmedia hn_media;
device_t hn_dev;
int hn_if_flags;
struct sx hn_lock;
struct vmbus_channel *hn_prichan;
int hn_rx_ring_cnt;
int hn_rx_ring_inuse;
struct hn_rx_ring *hn_rx_ring;
struct rmlock hn_vf_lock;
if_t hn_vf_ifp;
uint32_t hn_xvf_flags;
int hn_tx_ring_cnt;
int hn_tx_ring_inuse;
struct hn_tx_ring *hn_tx_ring;
uint8_t *hn_chim;
u_long *hn_chim_bmap;
int hn_chim_bmap_cnt;
int hn_chim_cnt;
int hn_chim_szmax;
int hn_cpu;
struct taskqueue **hn_tx_taskqs;
struct sysctl_oid *hn_tx_sysctl_tree;
struct sysctl_oid *hn_rx_sysctl_tree;
struct vmbus_xact_ctx *hn_xact;
uint32_t hn_nvs_ver;
uint32_t hn_rx_filter;
int hn_agg_size;
int hn_agg_pkts;
struct taskqueue *hn_mgmt_taskq;
struct taskqueue *hn_mgmt_taskq0;
struct task hn_link_task;
struct task hn_netchg_init;
struct timeout_task hn_netchg_status;
uint32_t hn_link_flags;
uint32_t hn_caps;
uint32_t hn_flags;
u_int hn_pollhz;
void *hn_rxbuf;
uint32_t hn_rxbuf_gpadl;
uint32_t hn_chim_gpadl;
uint32_t hn_rndis_rid;
uint32_t hn_ndis_ver;
int hn_ndis_tso_szmax;
int hn_ndis_tso_sgmin;
uint32_t hn_rndis_agg_size;
uint32_t hn_rndis_agg_pkts;
uint32_t hn_rndis_agg_align;
int hn_rss_ind_size;
uint32_t hn_rss_hash;
uint32_t hn_rss_hcap;
struct ndis_rssprm_toeplitz hn_rss;
eventhandler_tag hn_ifaddr_evthand;
eventhandler_tag hn_ifnet_evthand;
eventhandler_tag hn_ifnet_atthand;
eventhandler_tag hn_ifnet_dethand;
eventhandler_tag hn_ifnet_lnkhand;
int hn_vf_rdytick;
struct taskqueue *hn_vf_taskq;
struct timeout_task hn_vf_init;
void (*hn_vf_input)
(if_t, struct mbuf *);
int hn_saved_caps;
u_int hn_saved_tsomax;
u_int hn_saved_tsosegcnt;
u_int hn_saved_tsosegsz;
u_int hn_saved_capenable;
u_int hn_saved_hwassist;
u_int hn_rsc_ctrl;
};
#define HN_FLAG_RXBUF_CONNECTED 0x0001
#define HN_FLAG_CHIM_CONNECTED 0x0002
#define HN_FLAG_HAS_RSSKEY 0x0004
#define HN_FLAG_HAS_RSSIND 0x0008
#define HN_FLAG_SYNTH_ATTACHED 0x0010
#define HN_FLAG_NO_SLEEPING 0x0020
#define HN_FLAG_RXBUF_REF 0x0040
#define HN_FLAG_CHIM_REF 0x0080
#define HN_FLAG_RXVF 0x0100
#define HN_FLAG_ERRORS (HN_FLAG_RXBUF_REF | HN_FLAG_CHIM_REF)
#define HN_XVFFLAG_ENABLED 0x0001
#define HN_XVFFLAG_ACCBPF 0x0002
#define HN_NO_SLEEPING(sc) \
do { \
(sc)->hn_flags |= HN_FLAG_NO_SLEEPING; \
} while (0)
#define HN_SLEEPING_OK(sc) \
do { \
(sc)->hn_flags &= ~HN_FLAG_NO_SLEEPING; \
} while (0)
#define HN_CAN_SLEEP(sc) \
(((sc)->hn_flags & HN_FLAG_NO_SLEEPING) == 0)
#define HN_CAP_VLAN 0x0001
#define HN_CAP_MTU 0x0002
#define HN_CAP_IPCS 0x0004
#define HN_CAP_TCP4CS 0x0008
#define HN_CAP_TCP6CS 0x0010
#define HN_CAP_UDP4CS 0x0020
#define HN_CAP_UDP6CS 0x0040
#define HN_CAP_TSO4 0x0080
#define HN_CAP_TSO6 0x0100
#define HN_CAP_HASHVAL 0x0200
#define HN_CAP_UDPHASH 0x0400
#define HN_CAP_BITS \
"\020\1VLAN\2MTU\3IPCS\4TCP4CS\5TCP6CS" \
"\6UDP4CS\7UDP6CS\10TSO4\11TSO6\12HASHVAL\13UDPHASH"
#define HN_LINK_FLAG_LINKUP 0x0001
#define HN_LINK_FLAG_NETCHG 0x0002
#endif