Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F156927052
D8389.id.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
28 KB
Referenced Files
None
Subscribers
None
D8389.id.diff
View Options
Index: head/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c
===================================================================
--- head/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c
+++ head/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c
@@ -59,62 +59,41 @@
#include "opt_inet.h"
#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/sockio.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
#include <sys/limits.h>
-#include <sys/mbuf.h>
#include <sys/malloc.h>
+#include <sys/mbuf.h>
#include <sys/module.h>
-#include <sys/kernel.h>
-#include <sys/socket.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 <net/if.h>
-#include <net/if_arp.h>
+#include <machine/atomic.h>
+#include <machine/in_cksum.h>
+
+#include <net/bpf.h>
#include <net/ethernet.h>
-#include <net/if_dl.h>
+#include <net/if.h>
#include <net/if_media.h>
-#include <net/rndis.h>
-#include <net/bpf.h>
-
-#include <net/if_var.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 @@
#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 @@
#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 @@
#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 @@
#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;
-
-/*
- * 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 u_int hn_cpu_index; /* next CPU for channel */
+static struct taskqueue *hn_tx_taskq; /* shared TX taskqueue */
-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 @@
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 @@
#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 @@
}
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 @@
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 @@
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 @@
* 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 @@
return (0);
}
-/*
- * Standard shutdown entry point
- */
static int
-netvsc_shutdown(device_t dev)
+hn_shutdown(device_t dev)
{
+
return (0);
}
@@ -1037,7 +1049,7 @@
}
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 @@
}
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 @@
}
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 @@
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 @@
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 @@
* 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 @@
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 @@
sc->hn_tx_ring[i].hn_oactive = 0;
}
-/*
- * FreeBSD transmit entry point
- */
static void
hn_start(struct ifnet *ifp)
{
@@ -2195,7 +2204,7 @@
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_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 @@
}
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 @@
}
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 @@
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 @@
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 @@
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 @@
}
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 @@
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 @@
}
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 @@
* 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 @@
* 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 @@
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 @@
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 @@
}
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);
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Mon, May 18, 10:14 AM (14 h, 39 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
33243680
Default Alt Text
D8389.id.diff (28 KB)
Attached To
Mode
D8389: Cosmetic cleanup; no functional changes.
Attached
Detach File
Event Timeline
Log In to Comment