hyperv/hn: Cosmetic cleanup; no functional changes.

MFC after:	1 week
Sponsored by:	Microsoft
Differential Revision:	https://reviews.freebsd.org/D8389
This commit is contained in:
Sepherosa Ziehau 2016-11-01 04:44:11 +00:00
parent d9fea9f287
commit ba015837bf
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=308162

View File

@ -59,62 +59,41 @@ __FBSDID("$FreeBSD$");
#include "opt_inet.h"
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/sockio.h>
#include <sys/limits.h>
#include <sys/mbuf.h>
#include <sys/malloc.h>
#include <sys/module.h>
#include <sys/bus.h>
#include <sys/kernel.h>
#include <sys/socket.h>
#include <sys/limits.h>
#include <sys/malloc.h>
#include <sys/mbuf.h>
#include <sys/module.h>
#include <sys/queue.h>
#include <sys/lock.h>
#include <sys/sx.h>
#include <sys/smp.h>
#include <sys/socket.h>
#include <sys/sockio.h>
#include <sys/sx.h>
#include <sys/sysctl.h>
#include <sys/buf_ring.h>
#include <sys/systm.h>
#include <sys/taskqueue.h>
#include <sys/buf_ring.h>
#include <machine/atomic.h>
#include <machine/in_cksum.h>
#include <net/if.h>
#include <net/if_arp.h>
#include <net/ethernet.h>
#include <net/if_dl.h>
#include <net/if_media.h>
#include <net/rndis.h>
#include <net/bpf.h>
#include <net/if_var.h>
#include <net/ethernet.h>
#include <net/if.h>
#include <net/if_media.h>
#include <net/if_types.h>
#include <net/if_vlan_var.h>
#include <net/if_var.h>
#include <net/rndis.h>
#include <netinet/in_systm.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/if_ether.h>
#include <netinet/ip6.h>
#include <netinet/tcp.h>
#include <netinet/tcp_lro.h>
#include <netinet/udp.h>
#include <netinet/ip6.h>
#include <vm/vm.h>
#include <vm/vm_param.h>
#include <vm/vm_kern.h>
#include <vm/pmap.h>
#include <machine/bus.h>
#include <machine/resource.h>
#include <machine/frame.h>
#include <sys/bus.h>
#include <sys/rman.h>
#include <sys/mutex.h>
#include <sys/errno.h>
#include <sys/types.h>
#include <machine/atomic.h>
#include <machine/intr_machdep.h>
#include <machine/in_cksum.h>
#include <dev/hyperv/include/hyperv.h>
#include <dev/hyperv/include/hyperv_busdma.h>
@ -129,24 +108,11 @@ __FBSDID("$FreeBSD$");
#include "vmbus_if.h"
/* Short for Hyper-V network interface */
#define NETVSC_DEVNAME "hn"
/*
* It looks like offset 0 of buf is reserved to hold the softc pointer.
* The sc pointer evidently not needed, and is not presently populated.
* The packet offset is where the netvsc_packet starts in the buffer.
*/
#define HV_NV_SC_PTR_OFFSET_IN_BUF 0
#define HV_NV_PACKET_OFFSET_IN_BUF 16
#define HN_RING_CNT_DEF_MAX 8
/* YYY should get it from the underlying channel */
#define HN_TX_DESC_CNT 512
#define HN_LROENT_CNT_DEF 128
#define HN_RING_CNT_DEF_MAX 8
#define HN_RNDIS_PKT_LEN \
(sizeof(struct rndis_packet_msg) + \
HN_RNDIS_PKTINFO_SIZE(HN_NDIS_HASH_VALUE_SIZE) + \
@ -166,50 +132,9 @@ __FBSDID("$FreeBSD$");
#define HN_EARLY_TXEOF_THRESH 8
#define HN_RXINFO_VLAN 0x0001
#define HN_RXINFO_CSUM 0x0002
#define HN_RXINFO_HASHINF 0x0004
#define HN_RXINFO_HASHVAL 0x0008
#define HN_RXINFO_ALL \
(HN_RXINFO_VLAN | \
HN_RXINFO_CSUM | \
HN_RXINFO_HASHINF | \
HN_RXINFO_HASHVAL)
#define HN_PKTBUF_LEN_DEF (16 * 1024)
struct hn_txdesc {
#ifndef HN_USE_TXDESC_BUFRING
SLIST_ENTRY(hn_txdesc) link;
#endif
struct mbuf *m;
struct hn_tx_ring *txr;
int refs;
uint32_t flags; /* HN_TXD_FLAG_ */
struct hn_nvs_sendctx send_ctx;
uint32_t chim_index;
int chim_size;
bus_dmamap_t data_dmap;
bus_addr_t rndis_pkt_paddr;
struct rndis_packet_msg *rndis_pkt;
bus_dmamap_t rndis_pkt_dmap;
};
#define HN_TXD_FLAG_ONLIST 0x1
#define HN_TXD_FLAG_DMAMAP 0x2
#define HN_NDIS_VLAN_INFO_INVALID 0xffffffff
#define HN_NDIS_RXCSUM_INFO_INVALID 0
#define HN_NDIS_HASH_INFO_INVALID 0
struct hn_rxinfo {
uint32_t vlan_info;
uint32_t csum_info;
uint32_t hash_info;
uint32_t hash_value;
};
#define HN_LROENT_CNT_DEF 128
#define HN_LRO_LENLIM_MULTIRX_DEF (12 * ETHERMTU)
#define HN_LRO_LENLIM_DEF (25 * ETHERMTU)
@ -220,8 +145,8 @@ struct hn_rxinfo {
#define HN_LOCK_INIT(sc) \
sx_init(&(sc)->hn_lock, device_get_nameunit((sc)->hn_dev))
#define HN_LOCK_ASSERT(sc) sx_assert(&(sc)->hn_lock, SA_XLOCKED)
#define HN_LOCK_DESTROY(sc) sx_destroy(&(sc)->hn_lock)
#define HN_LOCK_ASSERT(sc) sx_assert(&(sc)->hn_lock, SA_XLOCKED)
#define HN_LOCK(sc) sx_xlock(&(sc)->hn_lock)
#define HN_UNLOCK(sc) sx_xunlock(&(sc)->hn_lock)
@ -232,199 +157,276 @@ struct hn_rxinfo {
#define HN_CSUM_IP6_HWASSIST(sc) \
((sc)->hn_tx_ring[0].hn_csum_assist & HN_CSUM_IP6_MASK)
/*
* Globals
*/
struct hn_txdesc {
#ifndef HN_USE_TXDESC_BUFRING
SLIST_ENTRY(hn_txdesc) link;
#endif
struct mbuf *m;
struct hn_tx_ring *txr;
int refs;
uint32_t flags; /* HN_TXD_FLAG_ */
struct hn_nvs_sendctx send_ctx;
uint32_t chim_index;
int chim_size;
bus_dmamap_t data_dmap;
bus_addr_t rndis_pkt_paddr;
struct rndis_packet_msg *rndis_pkt;
bus_dmamap_t rndis_pkt_dmap;
};
#define HN_TXD_FLAG_ONLIST 0x0001
#define HN_TXD_FLAG_DMAMAP 0x0002
struct hn_rxinfo {
uint32_t vlan_info;
uint32_t csum_info;
uint32_t hash_info;
uint32_t hash_value;
};
#define HN_RXINFO_VLAN 0x0001
#define HN_RXINFO_CSUM 0x0002
#define HN_RXINFO_HASHINF 0x0004
#define HN_RXINFO_HASHVAL 0x0008
#define HN_RXINFO_ALL \
(HN_RXINFO_VLAN | \
HN_RXINFO_CSUM | \
HN_RXINFO_HASHINF | \
HN_RXINFO_HASHVAL)
#define HN_NDIS_VLAN_INFO_INVALID 0xffffffff
#define HN_NDIS_RXCSUM_INFO_INVALID 0
#define HN_NDIS_HASH_INFO_INVALID 0
static int hn_probe(device_t);
static int hn_attach(device_t);
static int hn_detach(device_t);
static int hn_shutdown(device_t);
static void hn_chan_callback(struct vmbus_channel *,
void *);
static void hn_init(void *);
static int hn_ioctl(struct ifnet *, u_long, caddr_t);
static void hn_start(struct ifnet *);
static int hn_transmit(struct ifnet *, struct mbuf *);
static void hn_xmit_qflush(struct ifnet *);
static int hn_ifmedia_upd(struct ifnet *);
static void hn_ifmedia_sts(struct ifnet *,
struct ifmediareq *);
static int hn_rndis_rxinfo(const void *, int,
struct hn_rxinfo *);
static void hn_rndis_rx_data(struct hn_rx_ring *,
const void *, int);
static void hn_rndis_rx_status(struct hn_softc *,
const void *, int);
static void hn_nvs_handle_notify(struct hn_softc *,
const struct vmbus_chanpkt_hdr *);
static void hn_nvs_handle_comp(struct hn_softc *,
struct vmbus_channel *,
const struct vmbus_chanpkt_hdr *);
static void hn_nvs_handle_rxbuf(struct hn_rx_ring *,
struct vmbus_channel *,
const struct vmbus_chanpkt_hdr *);
static void hn_nvs_ack_rxbuf(struct hn_rx_ring *,
struct vmbus_channel *, uint64_t);
#if __FreeBSD_version >= 1100099
static int hn_lro_lenlim_sysctl(SYSCTL_HANDLER_ARGS);
static int hn_lro_ackcnt_sysctl(SYSCTL_HANDLER_ARGS);
#endif
static int hn_trust_hcsum_sysctl(SYSCTL_HANDLER_ARGS);
static int hn_chim_size_sysctl(SYSCTL_HANDLER_ARGS);
#if __FreeBSD_version < 1100095
static int hn_rx_stat_int_sysctl(SYSCTL_HANDLER_ARGS);
#else
static int hn_rx_stat_u64_sysctl(SYSCTL_HANDLER_ARGS);
#endif
static int hn_rx_stat_ulong_sysctl(SYSCTL_HANDLER_ARGS);
static int hn_tx_stat_ulong_sysctl(SYSCTL_HANDLER_ARGS);
static int hn_tx_conf_int_sysctl(SYSCTL_HANDLER_ARGS);
static int hn_ndis_version_sysctl(SYSCTL_HANDLER_ARGS);
static int hn_caps_sysctl(SYSCTL_HANDLER_ARGS);
static int hn_hwassist_sysctl(SYSCTL_HANDLER_ARGS);
static int hn_rxfilter_sysctl(SYSCTL_HANDLER_ARGS);
static int hn_rss_key_sysctl(SYSCTL_HANDLER_ARGS);
static int hn_rss_ind_sysctl(SYSCTL_HANDLER_ARGS);
static int hn_rss_hash_sysctl(SYSCTL_HANDLER_ARGS);
static void hn_stop(struct hn_softc *);
static void hn_init_locked(struct hn_softc *);
static int hn_chan_attach(struct hn_softc *,
struct vmbus_channel *);
static void hn_chan_detach(struct hn_softc *,
struct vmbus_channel *);
static int hn_attach_subchans(struct hn_softc *);
static void hn_detach_allchans(struct hn_softc *);
static void hn_chan_rollup(struct hn_rx_ring *,
struct hn_tx_ring *);
static void hn_set_ring_inuse(struct hn_softc *, int);
static int hn_synth_attach(struct hn_softc *, int);
static void hn_synth_detach(struct hn_softc *);
static int hn_synth_alloc_subchans(struct hn_softc *,
int *);
static void hn_suspend(struct hn_softc *);
static void hn_suspend_data(struct hn_softc *);
static void hn_suspend_mgmt(struct hn_softc *);
static void hn_resume(struct hn_softc *);
static void hn_resume_data(struct hn_softc *);
static void hn_resume_mgmt(struct hn_softc *);
static void hn_suspend_mgmt_taskfunc(void *, int);
static void hn_chan_drain(struct vmbus_channel *);
static void hn_update_link_status(struct hn_softc *);
static void hn_change_network(struct hn_softc *);
static void hn_link_taskfunc(void *, int);
static void hn_netchg_init_taskfunc(void *, int);
static void hn_netchg_status_taskfunc(void *, int);
static void hn_link_status(struct hn_softc *);
static int hn_create_rx_data(struct hn_softc *, int);
static void hn_destroy_rx_data(struct hn_softc *);
static int hn_check_iplen(const struct mbuf *, int);
static int hn_set_rxfilter(struct hn_softc *);
static int hn_rss_reconfig(struct hn_softc *);
static void hn_rss_ind_fixup(struct hn_softc *, int);
static int hn_rxpkt(struct hn_rx_ring *, const void *,
int, const struct hn_rxinfo *);
static int hn_tx_ring_create(struct hn_softc *, int);
static void hn_tx_ring_destroy(struct hn_tx_ring *);
static int hn_create_tx_data(struct hn_softc *, int);
static void hn_fixup_tx_data(struct hn_softc *);
static void hn_destroy_tx_data(struct hn_softc *);
static void hn_txdesc_dmamap_destroy(struct hn_txdesc *);
static int hn_encap(struct hn_tx_ring *,
struct hn_txdesc *, struct mbuf **);
static int hn_txpkt(struct ifnet *, struct hn_tx_ring *,
struct hn_txdesc *);
static void hn_set_chim_size(struct hn_softc *, int);
static void hn_set_tso_maxsize(struct hn_softc *, int, int);
static bool hn_tx_ring_pending(struct hn_tx_ring *);
static void hn_tx_ring_qflush(struct hn_tx_ring *);
static void hn_resume_tx(struct hn_softc *, int);
static int hn_get_txswq_depth(const struct hn_tx_ring *);
static void hn_txpkt_done(struct hn_nvs_sendctx *,
struct hn_softc *, struct vmbus_channel *,
const void *, int);
static int hn_txpkt_sglist(struct hn_tx_ring *,
struct hn_txdesc *);
static int hn_txpkt_chim(struct hn_tx_ring *,
struct hn_txdesc *);
static int hn_xmit(struct hn_tx_ring *, int);
static void hn_xmit_taskfunc(void *, int);
static void hn_xmit_txeof(struct hn_tx_ring *);
static void hn_xmit_txeof_taskfunc(void *, int);
static int hn_start_locked(struct hn_tx_ring *, int);
static void hn_start_taskfunc(void *, int);
static void hn_start_txeof(struct hn_tx_ring *);
static void hn_start_txeof_taskfunc(void *, int);
SYSCTL_NODE(_hw, OID_AUTO, hn, CTLFLAG_RD | CTLFLAG_MPSAFE, NULL,
"Hyper-V network interface");
/* Trust tcp segements verification on host side. */
static int hn_trust_hosttcp = 1;
static int hn_trust_hosttcp = 1;
SYSCTL_INT(_hw_hn, OID_AUTO, trust_hosttcp, CTLFLAG_RDTUN,
&hn_trust_hosttcp, 0,
"Trust tcp segement verification on host side, "
"when csum info is missing (global setting)");
/* Trust udp datagrams verification on host side. */
static int hn_trust_hostudp = 1;
static int hn_trust_hostudp = 1;
SYSCTL_INT(_hw_hn, OID_AUTO, trust_hostudp, CTLFLAG_RDTUN,
&hn_trust_hostudp, 0,
"Trust udp datagram verification on host side, "
"when csum info is missing (global setting)");
/* Trust ip packets verification on host side. */
static int hn_trust_hostip = 1;
static int hn_trust_hostip = 1;
SYSCTL_INT(_hw_hn, OID_AUTO, trust_hostip, CTLFLAG_RDTUN,
&hn_trust_hostip, 0,
"Trust ip packet verification on host side, "
"when csum info is missing (global setting)");
/* Limit TSO burst size */
static int hn_tso_maxlen = IP_MAXPACKET;
static int hn_tso_maxlen = IP_MAXPACKET;
SYSCTL_INT(_hw_hn, OID_AUTO, tso_maxlen, CTLFLAG_RDTUN,
&hn_tso_maxlen, 0, "TSO burst limit");
/* Limit chimney send size */
static int hn_tx_chimney_size = 0;
static int hn_tx_chimney_size = 0;
SYSCTL_INT(_hw_hn, OID_AUTO, tx_chimney_size, CTLFLAG_RDTUN,
&hn_tx_chimney_size, 0, "Chimney send packet size limit");
/* Limit the size of packet for direct transmission */
static int hn_direct_tx_size = HN_DIRECT_TX_SIZE_DEF;
static int hn_direct_tx_size = HN_DIRECT_TX_SIZE_DEF;
SYSCTL_INT(_hw_hn, OID_AUTO, direct_tx_size, CTLFLAG_RDTUN,
&hn_direct_tx_size, 0, "Size of the packet for direct transmission");
/* # of LRO entries per RX ring */
#if defined(INET) || defined(INET6)
#if __FreeBSD_version >= 1100095
static int hn_lro_entry_count = HN_LROENT_CNT_DEF;
static int hn_lro_entry_count = HN_LROENT_CNT_DEF;
SYSCTL_INT(_hw_hn, OID_AUTO, lro_entry_count, CTLFLAG_RDTUN,
&hn_lro_entry_count, 0, "LRO entry count");
#endif
#endif
static int hn_share_tx_taskq = 0;
/* Use shared TX taskqueue */
static int hn_share_tx_taskq = 0;
SYSCTL_INT(_hw_hn, OID_AUTO, share_tx_taskq, CTLFLAG_RDTUN,
&hn_share_tx_taskq, 0, "Enable shared TX taskqueue");
static struct taskqueue *hn_tx_taskq;
#ifndef HN_USE_TXDESC_BUFRING
static int hn_use_txdesc_bufring = 0;
static int hn_use_txdesc_bufring = 0;
#else
static int hn_use_txdesc_bufring = 1;
static int hn_use_txdesc_bufring = 1;
#endif
SYSCTL_INT(_hw_hn, OID_AUTO, use_txdesc_bufring, CTLFLAG_RD,
&hn_use_txdesc_bufring, 0, "Use buf_ring for TX descriptors");
static int hn_bind_tx_taskq = -1;
/* Bind TX taskqueue to the target CPU */
static int hn_bind_tx_taskq = -1;
SYSCTL_INT(_hw_hn, OID_AUTO, bind_tx_taskq, CTLFLAG_RDTUN,
&hn_bind_tx_taskq, 0, "Bind TX taskqueue to the specified cpu");
static int hn_use_if_start = 0;
/* Use ifnet.if_start instead of ifnet.if_transmit */
static int hn_use_if_start = 0;
SYSCTL_INT(_hw_hn, OID_AUTO, use_if_start, CTLFLAG_RDTUN,
&hn_use_if_start, 0, "Use if_start TX method");
static int hn_chan_cnt = 0;
/* # of channels to use */
static int hn_chan_cnt = 0;
SYSCTL_INT(_hw_hn, OID_AUTO, chan_cnt, CTLFLAG_RDTUN,
&hn_chan_cnt, 0,
"# of channels to use; each channel has one RX ring and one TX ring");
static int hn_tx_ring_cnt = 0;
/* # of transmit rings to use */
static int hn_tx_ring_cnt = 0;
SYSCTL_INT(_hw_hn, OID_AUTO, tx_ring_cnt, CTLFLAG_RDTUN,
&hn_tx_ring_cnt, 0, "# of TX rings to use");
static int hn_tx_swq_depth = 0;
/* Software TX ring deptch */
static int hn_tx_swq_depth = 0;
SYSCTL_INT(_hw_hn, OID_AUTO, tx_swq_depth, CTLFLAG_RDTUN,
&hn_tx_swq_depth, 0, "Depth of IFQ or BUFRING");
/* Enable sorted LRO, and the depth of the per-channel mbuf queue */
#if __FreeBSD_version >= 1100095
static u_int hn_lro_mbufq_depth = 0;
static u_int hn_lro_mbufq_depth = 0;
SYSCTL_UINT(_hw_hn, OID_AUTO, lro_mbufq_depth, CTLFLAG_RDTUN,
&hn_lro_mbufq_depth, 0, "Depth of LRO mbuf queue");
#endif
static u_int hn_cpu_index;
static u_int hn_cpu_index; /* next CPU for channel */
static struct taskqueue *hn_tx_taskq; /* shared TX taskqueue */
/*
* Forward declarations
*/
static void hn_stop(struct hn_softc *sc);
static void hn_init_locked(struct hn_softc *sc);
static void hn_init(void *xsc);
static int hn_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data);
static int hn_start_locked(struct hn_tx_ring *txr, int len);
static void hn_start(struct ifnet *ifp);
static void hn_start_txeof(struct hn_tx_ring *);
static int hn_ifmedia_upd(struct ifnet *ifp);
static void hn_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr);
#if __FreeBSD_version >= 1100099
static int hn_lro_lenlim_sysctl(SYSCTL_HANDLER_ARGS);
static int hn_lro_ackcnt_sysctl(SYSCTL_HANDLER_ARGS);
#endif
static int hn_trust_hcsum_sysctl(SYSCTL_HANDLER_ARGS);
static int hn_chim_size_sysctl(SYSCTL_HANDLER_ARGS);
#if __FreeBSD_version < 1100095
static int hn_rx_stat_int_sysctl(SYSCTL_HANDLER_ARGS);
#else
static int hn_rx_stat_u64_sysctl(SYSCTL_HANDLER_ARGS);
#endif
static int hn_rx_stat_ulong_sysctl(SYSCTL_HANDLER_ARGS);
static int hn_tx_stat_ulong_sysctl(SYSCTL_HANDLER_ARGS);
static int hn_tx_conf_int_sysctl(SYSCTL_HANDLER_ARGS);
static int hn_ndis_version_sysctl(SYSCTL_HANDLER_ARGS);
static int hn_caps_sysctl(SYSCTL_HANDLER_ARGS);
static int hn_hwassist_sysctl(SYSCTL_HANDLER_ARGS);
static int hn_rxfilter_sysctl(SYSCTL_HANDLER_ARGS);
static int hn_rss_key_sysctl(SYSCTL_HANDLER_ARGS);
static int hn_rss_ind_sysctl(SYSCTL_HANDLER_ARGS);
static int hn_rss_hash_sysctl(SYSCTL_HANDLER_ARGS);
static int hn_check_iplen(const struct mbuf *, int);
static int hn_create_tx_ring(struct hn_softc *, int);
static void hn_destroy_tx_ring(struct hn_tx_ring *);
static int hn_create_tx_data(struct hn_softc *, int);
static void hn_fixup_tx_data(struct hn_softc *);
static void hn_destroy_tx_data(struct hn_softc *);
static void hn_start_taskfunc(void *, int);
static void hn_start_txeof_taskfunc(void *, int);
static void hn_link_taskfunc(void *, int);
static void hn_netchg_init_taskfunc(void *, int);
static void hn_netchg_status_taskfunc(void *, int);
static void hn_suspend_mgmt_taskfunc(void *, int);
static int hn_encap(struct hn_tx_ring *, struct hn_txdesc *, struct mbuf **);
static int hn_create_rx_data(struct hn_softc *sc, int);
static void hn_destroy_rx_data(struct hn_softc *sc);
static void hn_set_chim_size(struct hn_softc *, int);
static void hn_set_tso_maxsize(struct hn_softc *, int, int);
static int hn_chan_attach(struct hn_softc *, struct vmbus_channel *);
static void hn_chan_detach(struct hn_softc *, struct vmbus_channel *);
static int hn_attach_subchans(struct hn_softc *);
static void hn_detach_allchans(struct hn_softc *);
static void hn_chan_callback(struct vmbus_channel *chan, void *xrxr);
static void hn_chan_rollup(struct hn_rx_ring *, struct hn_tx_ring *);
static void hn_set_ring_inuse(struct hn_softc *, int);
static int hn_synth_attach(struct hn_softc *, int);
static void hn_synth_detach(struct hn_softc *);
static bool hn_tx_ring_pending(struct hn_tx_ring *);
static void hn_suspend(struct hn_softc *);
static void hn_suspend_data(struct hn_softc *);
static void hn_suspend_mgmt(struct hn_softc *);
static void hn_resume(struct hn_softc *);
static void hn_resume_data(struct hn_softc *);
static void hn_resume_mgmt(struct hn_softc *);
static void hn_rx_drain(struct vmbus_channel *);
static void hn_tx_resume(struct hn_softc *, int);
static void hn_tx_ring_qflush(struct hn_tx_ring *);
static int netvsc_detach(device_t dev);
static void hn_link_status(struct hn_softc *);
static int hn_sendpkt_rndis_sglist(struct hn_tx_ring *, struct hn_txdesc *);
static int hn_sendpkt_rndis_chim(struct hn_tx_ring *, struct hn_txdesc *);
static int hn_set_rxfilter(struct hn_softc *);
static void hn_link_status_update(struct hn_softc *);
static void hn_network_change(struct hn_softc *);
static int hn_rndis_rxinfo(const void *, int, struct hn_rxinfo *);
static void hn_rndis_rx_data(struct hn_rx_ring *, const void *, int);
static void hn_rndis_rx_status(struct hn_softc *, const void *, int);
static void hn_nvs_handle_notify(struct hn_softc *sc,
const struct vmbus_chanpkt_hdr *pkt);
static void hn_nvs_handle_comp(struct hn_softc *sc, struct vmbus_channel *chan,
const struct vmbus_chanpkt_hdr *pkt);
static void hn_nvs_handle_rxbuf(struct hn_rx_ring *rxr,
struct vmbus_channel *chan,
const struct vmbus_chanpkt_hdr *pkthdr);
static void hn_nvs_ack_rxbuf(struct hn_rx_ring *, struct vmbus_channel *,
uint64_t);
static int hn_transmit(struct ifnet *, struct mbuf *);
static void hn_xmit_qflush(struct ifnet *);
static int hn_xmit(struct hn_tx_ring *, int);
static void hn_xmit_txeof(struct hn_tx_ring *);
static void hn_xmit_taskfunc(void *, int);
static void hn_xmit_txeof_taskfunc(void *, int);
static const uint8_t hn_rss_key_default[NDIS_HASH_KEYSIZE_TOEPLITZ] = {
static const uint8_t
hn_rss_key_default[NDIS_HASH_KEYSIZE_TOEPLITZ] = {
0x6d, 0x5a, 0x56, 0xda, 0x25, 0x5b, 0x0e, 0xc2,
0x41, 0x67, 0x25, 0x3d, 0x43, 0xa3, 0x8f, 0xb0,
0xd0, 0xca, 0x2b, 0xcb, 0xae, 0x7b, 0x30, 0xb4,
@ -432,6 +434,27 @@ static const uint8_t hn_rss_key_default[NDIS_HASH_KEYSIZE_TOEPLITZ] = {
0x6a, 0x42, 0xb7, 0x3b, 0xbe, 0xac, 0x01, 0xfa
};
static device_method_t hn_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, hn_probe),
DEVMETHOD(device_attach, hn_attach),
DEVMETHOD(device_detach, hn_detach),
DEVMETHOD(device_shutdown, hn_shutdown),
DEVMETHOD_END
};
static driver_t hn_driver = {
"hn",
hn_methods,
sizeof(struct hn_softc)
};
static devclass_t hn_devclass;
DRIVER_MODULE(hn, vmbus, hn_driver, hn_devclass, 0, 0);
MODULE_VERSION(hn, 1);
MODULE_DEPEND(hn, vmbus, 1, 1, 1);
#if __FreeBSD_version >= 1100099
static void
hn_set_lro_lenlim(struct hn_softc *sc, int lenlim)
@ -444,7 +467,7 @@ hn_set_lro_lenlim(struct hn_softc *sc, int lenlim)
#endif
static int
hn_sendpkt_rndis_sglist(struct hn_tx_ring *txr, struct hn_txdesc *txd)
hn_txpkt_sglist(struct hn_tx_ring *txr, struct hn_txdesc *txd)
{
KASSERT(txd->chim_index == HN_NVS_CHIM_IDX_INVALID &&
@ -454,7 +477,7 @@ hn_sendpkt_rndis_sglist(struct hn_tx_ring *txr, struct hn_txdesc *txd)
}
static int
hn_sendpkt_rndis_chim(struct hn_tx_ring *txr, struct hn_txdesc *txd)
hn_txpkt_chim(struct hn_tx_ring *txr, struct hn_txdesc *txd)
{
struct hn_nvs_rndis rndis;
@ -653,13 +676,10 @@ static const struct hyperv_guid g_net_vsc_device_type = {
0x91, 0x3F, 0xF2, 0xD2, 0xF9, 0x65, 0xED, 0x0E}
};
/*
* Standard probe entry point.
*
*/
static int
netvsc_probe(device_t dev)
hn_probe(device_t dev)
{
if (VMBUS_PROBE_GUID(device_get_parent(dev), dev,
&g_net_vsc_device_type) == 0) {
device_set_desc(dev, "Hyper-V Network Interface");
@ -668,14 +688,8 @@ netvsc_probe(device_t dev)
return ENXIO;
}
/*
* Standard attach entry point.
*
* Called when the driver is loaded. It allocates needed resources,
* and initializes the "hardware" and software.
*/
static int
netvsc_attach(device_t dev)
hn_attach(device_t dev)
{
struct hn_softc *sc = device_get_softc(dev);
struct sysctl_oid_list *child;
@ -917,18 +931,18 @@ netvsc_attach(device_t dev)
* Kick off link status check.
*/
sc->hn_mgmt_taskq = sc->hn_mgmt_taskq0;
hn_link_status_update(sc);
hn_update_link_status(sc);
return (0);
failed:
if (sc->hn_flags & HN_FLAG_SYNTH_ATTACHED)
hn_synth_detach(sc);
netvsc_detach(dev);
hn_detach(dev);
return (error);
}
static int
netvsc_detach(device_t dev)
hn_detach(device_t dev)
{
struct hn_softc *sc = device_get_softc(dev);
struct ifnet *ifp = sc->hn_ifp;
@ -967,12 +981,10 @@ netvsc_detach(device_t dev)
return (0);
}
/*
* Standard shutdown entry point
*/
static int
netvsc_shutdown(device_t dev)
hn_shutdown(device_t dev)
{
return (0);
}
@ -1037,7 +1049,7 @@ hn_netchg_status_taskfunc(void *xsc, int pending __unused)
}
static void
hn_link_status_update(struct hn_softc *sc)
hn_update_link_status(struct hn_softc *sc)
{
if (sc->hn_mgmt_taskq != NULL)
@ -1045,7 +1057,7 @@ hn_link_status_update(struct hn_softc *sc)
}
static void
hn_network_change(struct hn_softc *sc)
hn_change_network(struct hn_softc *sc)
{
if (sc->hn_mgmt_taskq != NULL)
@ -1197,7 +1209,7 @@ hn_txeof(struct hn_tx_ring *txr)
}
static void
hn_tx_done(struct hn_nvs_sendctx *sndc, struct hn_softc *sc,
hn_txpkt_done(struct hn_nvs_sendctx *sndc, struct hn_softc *sc,
struct vmbus_channel *chan, const void *data __unused, int dlen __unused)
{
struct hn_txdesc *txd = sndc->hn_cbarg;
@ -1420,7 +1432,7 @@ hn_encap(struct hn_tx_ring *txr, struct hn_txdesc *txd, struct mbuf **m_head0)
txd->chim_size = pkt->rm_len;
txr->hn_gpa_cnt = 0;
txr->hn_tx_chimney++;
txr->hn_sendpkt = hn_sendpkt_rndis_chim;
txr->hn_sendpkt = hn_txpkt_chim;
goto done;
}
}
@ -1467,12 +1479,12 @@ hn_encap(struct hn_tx_ring *txr, struct hn_txdesc *txd, struct mbuf **m_head0)
txd->chim_index = HN_NVS_CHIM_IDX_INVALID;
txd->chim_size = 0;
txr->hn_sendpkt = hn_sendpkt_rndis_sglist;
txr->hn_sendpkt = hn_txpkt_sglist;
done:
txd->m = m_head;
/* Set the completion routine */
hn_nvs_sendctx_init(&txd->send_ctx, hn_tx_done, txd);
hn_nvs_sendctx_init(&txd->send_ctx, hn_txpkt_done, txd);
return 0;
}
@ -1483,7 +1495,7 @@ hn_encap(struct hn_tx_ring *txr, struct hn_txdesc *txd, struct mbuf **m_head0)
* associated w/ the txd will _not_ be freed.
*/
static int
hn_send_pkt(struct ifnet *ifp, struct hn_tx_ring *txr, struct hn_txdesc *txd)
hn_txpkt(struct ifnet *ifp, struct hn_tx_ring *txr, struct hn_txdesc *txd)
{
int error, send_failed = 0;
@ -1599,7 +1611,7 @@ hn_start_locked(struct hn_tx_ring *txr, int len)
continue;
}
error = hn_send_pkt(ifp, txr, txd);
error = hn_txpkt(ifp, txr, txd);
if (__predict_false(error)) {
/* txd is freed, but m_head is not */
IFQ_DRV_PREPEND(&ifp->if_snd, m_head);
@ -2114,9 +2126,6 @@ hn_stop(struct hn_softc *sc)
sc->hn_tx_ring[i].hn_oactive = 0;
}
/*
* FreeBSD transmit entry point
*/
static void
hn_start(struct ifnet *ifp)
{
@ -2195,7 +2204,7 @@ hn_init_locked(struct hn_softc *sc)
sc->hn_tx_ring[i].hn_oactive = 0;
/* Clear TX 'suspended' bit. */
hn_tx_resume(sc, sc->hn_tx_ring_inuse);
hn_resume_tx(sc, sc->hn_tx_ring_inuse);
/* Everything is ready; unleash! */
atomic_set_int(&ifp->if_drv_flags, IFF_DRV_RUNNING);
@ -2211,20 +2220,6 @@ hn_init(void *xsc)
HN_UNLOCK(sc);
}
#ifdef LATER
/*
*
*/
static void
hn_watchdog(struct ifnet *ifp)
{
if_printf(ifp, "watchdog timeout -- resetting\n");
hn_init(ifp->if_softc); /* XXX */
if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
}
#endif
#if __FreeBSD_version >= 1100099
static int
@ -2906,7 +2901,7 @@ hn_destroy_rx_data(struct hn_softc *sc)
}
static int
hn_create_tx_ring(struct hn_softc *sc, int id)
hn_tx_ring_create(struct hn_softc *sc, int id)
{
struct hn_tx_ring *txr = &sc->hn_tx_ring[id];
device_t dev = sc->hn_dev;
@ -3103,7 +3098,7 @@ hn_txdesc_dmamap_destroy(struct hn_txdesc *txd)
}
static void
hn_destroy_tx_ring(struct hn_tx_ring *txr)
hn_tx_ring_destroy(struct hn_tx_ring *txr)
{
struct hn_txdesc *txd;
@ -3179,7 +3174,7 @@ hn_create_tx_data(struct hn_softc *sc, int ring_cnt)
for (i = 0; i < sc->hn_tx_ring_cnt; ++i) {
int error;
error = hn_create_tx_ring(sc, i);
error = hn_tx_ring_create(sc, i);
if (error)
return error;
}
@ -3325,7 +3320,7 @@ hn_destroy_tx_data(struct hn_softc *sc)
return;
for (i = 0; i < sc->hn_tx_ring_cnt; ++i)
hn_destroy_tx_ring(&sc->hn_tx_ring[i]);
hn_tx_ring_destroy(&sc->hn_tx_ring[i]);
free(sc->hn_tx_ring, M_DEVBUF);
sc->hn_tx_ring = NULL;
@ -3401,7 +3396,7 @@ hn_xmit(struct hn_tx_ring *txr, int len)
continue;
}
error = hn_send_pkt(ifp, txr, txd);
error = hn_txpkt(ifp, txr, txd);
if (__predict_false(error)) {
/* txd is freed, but m_head is not */
drbr_putback(ifp, txr->hn_mbuf_br, m_head);
@ -3924,7 +3919,7 @@ hn_set_ring_inuse(struct hn_softc *sc, int ring_cnt)
}
static void
hn_rx_drain(struct vmbus_channel *chan)
hn_chan_drain(struct vmbus_channel *chan)
{
while (!vmbus_chan_rx_empty(chan) || !vmbus_chan_tx_empty(chan))
@ -3979,9 +3974,9 @@ hn_suspend_data(struct hn_softc *sc)
if (subch != NULL) {
for (i = 0; i < nsubch; ++i)
hn_rx_drain(subch[i]);
hn_chan_drain(subch[i]);
}
hn_rx_drain(sc->hn_prichan);
hn_chan_drain(sc->hn_prichan);
if (subch != NULL)
vmbus_subchan_rel(subch, nsubch);
@ -4026,7 +4021,7 @@ hn_suspend(struct hn_softc *sc)
}
static void
hn_tx_resume(struct hn_softc *sc, int tx_ring_cnt)
hn_resume_tx(struct hn_softc *sc, int tx_ring_cnt)
{
int i;
@ -4059,7 +4054,7 @@ hn_resume_data(struct hn_softc *sc)
* since hn_tx_ring_inuse can be changed after
* hn_suspend_data().
*/
hn_tx_resume(sc, sc->hn_tx_ring_cnt);
hn_resume_tx(sc, sc->hn_tx_ring_cnt);
if (!hn_use_if_start) {
/*
@ -4097,9 +4092,9 @@ hn_resume_mgmt(struct hn_softc *sc)
* detection.
*/
if (sc->hn_link_flags & HN_LINK_FLAG_NETCHG)
hn_network_change(sc);
hn_change_network(sc);
else
hn_link_status_update(sc);
hn_update_link_status(sc);
}
static void
@ -4126,7 +4121,7 @@ hn_rndis_rx_status(struct hn_softc *sc, const void *data, int dlen)
switch (msg->rm_status) {
case RNDIS_STATUS_MEDIA_CONNECT:
case RNDIS_STATUS_MEDIA_DISCONNECT:
hn_link_status_update(sc);
hn_update_link_status(sc);
break;
case RNDIS_STATUS_TASK_OFFLOAD_CURRENT_CONFIG:
@ -4146,7 +4141,7 @@ hn_rndis_rx_status(struct hn_softc *sc, const void *data, int dlen)
if_printf(sc->hn_ifp, "network changed, change %u\n",
change);
}
hn_network_change(sc);
hn_change_network(sc);
break;
default:
@ -4661,25 +4656,3 @@ hn_tx_taskq_destroy(void *arg __unused)
}
SYSUNINIT(hn_txtq_destroy, SI_SUB_DRIVERS, SI_ORDER_SECOND,
hn_tx_taskq_destroy, NULL);
static device_method_t netvsc_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, netvsc_probe),
DEVMETHOD(device_attach, netvsc_attach),
DEVMETHOD(device_detach, netvsc_detach),
DEVMETHOD(device_shutdown, netvsc_shutdown),
{ 0, 0 }
};
static driver_t netvsc_driver = {
NETVSC_DEVNAME,
netvsc_methods,
sizeof(struct hn_softc)
};
static devclass_t netvsc_devclass;
DRIVER_MODULE(hn, vmbus, netvsc_driver, netvsc_devclass, 0, 0);
MODULE_VERSION(hn, 1);
MODULE_DEPEND(hn, vmbus, 1, 1, 1);