Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F135598360
D8089.id21219.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
7 KB
Referenced Files
None
Subscribers
None
D8089.id21219.diff
View Options
Index: head/sys/dev/hyperv/netvsc/hv_net_vsc.h
===================================================================
--- head/sys/dev/hyperv/netvsc/hv_net_vsc.h
+++ head/sys/dev/hyperv/netvsc/hv_net_vsc.h
@@ -244,6 +244,8 @@
uint32_t hn_rndis_rid;
uint32_t hn_ndis_ver;
+ int hn_ndis_tso_szmax;
+ int hn_ndis_tso_sgmin;
struct ndis_rssprm_toeplitz hn_rss;
};
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
@@ -230,7 +230,7 @@
"when csum info is missing (global setting)");
/* Limit TSO burst size */
-static int hn_tso_maxlen = 0;
+static int hn_tso_maxlen = IP_MAXPACKET;
SYSCTL_INT(_hw_hn, OID_AUTO, tso_maxlen, CTLFLAG_RDTUN,
&hn_tso_maxlen, 0, "TSO burst limit");
@@ -338,6 +338,7 @@
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 *);
@@ -520,7 +521,6 @@
uint32_t link_status;
struct ifnet *ifp = NULL;
int error, ring_cnt, tx_ring_cnt;
- int tso_maxlen;
sc->hn_dev = dev;
sc->hn_prichan = vmbus_get_channel(dev);
@@ -720,18 +720,16 @@
/* Enable all available capabilities by default. */
ifp->if_capenable = ifp->if_capabilities;
- tso_maxlen = hn_tso_maxlen;
- if (tso_maxlen <= 0 || tso_maxlen > IP_MAXPACKET)
- tso_maxlen = IP_MAXPACKET;
- ifp->if_hw_tsomaxsegcount = HN_TX_DATA_SEGCNT_MAX;
- ifp->if_hw_tsomaxsegsize = PAGE_SIZE;
- ifp->if_hw_tsomax = tso_maxlen -
- (ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN);
+ if (ifp->if_capabilities & (IFCAP_TSO6 | IFCAP_TSO4)) {
+ hn_set_tso_maxsize(sc, hn_tso_maxlen, ETHERMTU);
+ ifp->if_hw_tsomaxsegcount = HN_TX_DATA_SEGCNT_MAX;
+ ifp->if_hw_tsomaxsegsize = PAGE_SIZE;
+ }
ether_ifattach(ifp, eaddr);
- if (bootverbose) {
- if_printf(ifp, "TSO: %u/%u/%u\n", ifp->if_hw_tsomax,
+ if ((ifp->if_capabilities & (IFCAP_TSO6 | IFCAP_TSO4)) && bootverbose) {
+ if_printf(ifp, "TSO segcnt %u segsz %u\n",
ifp->if_hw_tsomaxsegcount, ifp->if_hw_tsomaxsegsize);
}
@@ -1672,6 +1670,7 @@
if (sc->hn_tx_ring[0].hn_chim_size > sc->hn_chim_szmax)
hn_set_chim_size(sc, sc->hn_chim_szmax);
+ hn_set_tso_maxsize(sc, hn_tso_maxlen, ifr->ifr_mtu);
/* All done! Resume now. */
if (ifp->if_drv_flags & IFF_DRV_RUNNING)
@@ -2919,6 +2918,34 @@
}
static void
+hn_set_tso_maxsize(struct hn_softc *sc, int tso_maxlen, int mtu)
+{
+ struct ifnet *ifp = sc->hn_ifp;
+ int tso_minlen;
+
+ if ((ifp->if_capabilities & (IFCAP_TSO4 | IFCAP_TSO6)) == 0)
+ return;
+
+ KASSERT(sc->hn_ndis_tso_sgmin >= 2,
+ ("invalid NDIS tso sgmin %d", sc->hn_ndis_tso_sgmin));
+ tso_minlen = sc->hn_ndis_tso_sgmin * mtu;
+
+ KASSERT(sc->hn_ndis_tso_szmax >= tso_minlen &&
+ sc->hn_ndis_tso_szmax <= IP_MAXPACKET,
+ ("invalid NDIS tso szmax %d", sc->hn_ndis_tso_szmax));
+
+ if (tso_maxlen < tso_minlen)
+ tso_maxlen = tso_minlen;
+ else if (tso_maxlen > IP_MAXPACKET)
+ tso_maxlen = IP_MAXPACKET;
+ if (tso_maxlen > sc->hn_ndis_tso_szmax)
+ tso_maxlen = sc->hn_ndis_tso_szmax;
+ ifp->if_hw_tsomax = tso_maxlen - (ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN);
+ if (bootverbose)
+ if_printf(ifp, "TSO size max %u\n", ifp->if_hw_tsomax);
+}
+
+static void
hn_fixup_tx_data(struct hn_softc *sc)
{
uint64_t csum_assist;
@@ -3424,7 +3451,7 @@
/*
* Attach RNDIS _after_ NVS is attached.
*/
- error = hn_rndis_attach(sc);
+ error = hn_rndis_attach(sc, mtu);
if (error)
return (error);
Index: head/sys/dev/hyperv/netvsc/hv_rndis_filter.c
===================================================================
--- head/sys/dev/hyperv/netvsc/hv_rndis_filter.c
+++ head/sys/dev/hyperv/netvsc/hv_rndis_filter.c
@@ -39,6 +39,8 @@
#include <net/if_var.h>
#include <net/ethernet.h>
#include <net/rndis.h>
+#include <netinet/in.h>
+#include <netinet/ip.h>
#include <sys/types.h>
#include <machine/atomic.h>
#include <sys/sema.h>
@@ -77,6 +79,8 @@
NDIS_TXCSUM_CAP_IP6EXT)
#define HN_NDIS_TXCSUM_CAP_UDP6 \
(NDIS_TXCSUM_CAP_UDP6 | NDIS_TXCSUM_CAP_IP6EXT)
+#define HN_NDIS_LSOV2_CAP_IP6 \
+ (NDIS_LSOV2_CAP_IP6EXT | NDIS_LSOV2_CAP_TCP6OPT)
/*
* Forward declarations
@@ -93,7 +97,7 @@
size_t min_odlen);
static int hn_rndis_set(struct hn_softc *sc, uint32_t oid, const void *data,
size_t dlen);
-static int hn_rndis_conf_offload(struct hn_softc *sc);
+static int hn_rndis_conf_offload(struct hn_softc *sc, int mtu);
static int hn_rndis_query_hwcaps(struct hn_softc *sc,
struct ndis_offload *caps);
@@ -830,13 +834,13 @@
}
static int
-hn_rndis_conf_offload(struct hn_softc *sc)
+hn_rndis_conf_offload(struct hn_softc *sc, int mtu)
{
struct ndis_offload hwcaps;
struct ndis_offload_params params;
uint32_t caps = 0;
size_t paramsz;
- int error;
+ int error, tso_maxsz, tso_minsg;
error = hn_rndis_query_hwcaps(sc, &hwcaps);
if (error) {
@@ -857,18 +861,58 @@
}
params.ndis_hdr.ndis_size = paramsz;
- /* TSO */
+ /*
+ * TSO4/TSO6 setup.
+ */
+ tso_maxsz = IP_MAXPACKET;
+ tso_minsg = 2;
if (hwcaps.ndis_lsov2.ndis_ip4_encap & NDIS_OFFLOAD_ENCAP_8023) {
caps |= HN_CAP_TSO4;
params.ndis_lsov2_ip4 = NDIS_OFFLOAD_LSOV2_ON;
- /* TODO: tso_max */
- }
- if (hwcaps.ndis_lsov2.ndis_ip6_encap & NDIS_OFFLOAD_ENCAP_8023) {
+
+ if (hwcaps.ndis_lsov2.ndis_ip4_maxsz < tso_maxsz)
+ tso_maxsz = hwcaps.ndis_lsov2.ndis_ip4_maxsz;
+ if (hwcaps.ndis_lsov2.ndis_ip4_minsg > tso_minsg)
+ tso_minsg = hwcaps.ndis_lsov2.ndis_ip4_minsg;
+ }
+ if ((hwcaps.ndis_lsov2.ndis_ip6_encap & NDIS_OFFLOAD_ENCAP_8023) &&
+ (hwcaps.ndis_lsov2.ndis_ip6_opts & HN_NDIS_LSOV2_CAP_IP6) ==
+ HN_NDIS_LSOV2_CAP_IP6) {
#ifdef notyet
caps |= HN_CAP_TSO6;
params.ndis_lsov2_ip6 = NDIS_OFFLOAD_LSOV2_ON;
+
+ if (hwcaps.ndis_lsov2.ndis_ip6_maxsz < tso_maxsz)
+ tso_maxsz = hwcaps.ndis_lsov2.ndis_ip6_maxsz;
+ if (hwcaps.ndis_lsov2.ndis_ip6_minsg > tso_minsg)
+ tso_minsg = hwcaps.ndis_lsov2.ndis_ip6_minsg;
#endif
- /* TODO: tso_max */
+ }
+ sc->hn_ndis_tso_szmax = 0;
+ sc->hn_ndis_tso_sgmin = 0;
+ if (caps & (HN_CAP_TSO4 | HN_CAP_TSO6)) {
+ KASSERT(tso_maxsz <= IP_MAXPACKET,
+ ("invalid NDIS TSO maxsz %d", tso_maxsz));
+ KASSERT(tso_minsg >= 2,
+ ("invalid NDIS TSO minsg %d", tso_minsg));
+ if (tso_maxsz < tso_minsg * mtu) {
+ if_printf(sc->hn_ifp, "invalid NDIS TSO config: "
+ "maxsz %d, minsg %d, mtu %d; "
+ "disable TSO4 and TSO6\n",
+ tso_maxsz, tso_minsg, mtu);
+ caps &= ~(HN_CAP_TSO4 | HN_CAP_TSO6);
+ params.ndis_lsov2_ip4 = NDIS_OFFLOAD_LSOV2_OFF;
+ params.ndis_lsov2_ip6 = NDIS_OFFLOAD_LSOV2_OFF;
+ } else {
+ sc->hn_ndis_tso_szmax = tso_maxsz;
+ sc->hn_ndis_tso_sgmin = tso_minsg;
+ if (bootverbose) {
+ if_printf(sc->hn_ifp, "NDIS TSO "
+ "szmax %d sgmin %d\n",
+ sc->hn_ndis_tso_szmax,
+ sc->hn_ndis_tso_sgmin);
+ }
+ }
}
/* IPv4 checksum */
@@ -1186,7 +1230,7 @@
}
int
-hn_rndis_attach(struct hn_softc *sc)
+hn_rndis_attach(struct hn_softc *sc, int mtu)
{
int error;
@@ -1201,7 +1245,7 @@
* Configure NDIS offload settings.
* XXX no offloading, if error happened?
*/
- hn_rndis_conf_offload(sc);
+ hn_rndis_conf_offload(sc, mtu);
return (0);
}
Index: head/sys/dev/hyperv/netvsc/if_hnvar.h
===================================================================
--- head/sys/dev/hyperv/netvsc/if_hnvar.h
+++ head/sys/dev/hyperv/netvsc/if_hnvar.h
@@ -117,7 +117,7 @@
uint32_t hn_chim_alloc(struct hn_softc *sc);
void hn_chim_free(struct hn_softc *sc, uint32_t chim_idx);
-int hn_rndis_attach(struct hn_softc *sc);
+int hn_rndis_attach(struct hn_softc *sc, int mtu);
void hn_rndis_detach(struct hn_softc *sc);
int hn_rndis_conf_rss(struct hn_softc *sc, uint16_t flags);
void *hn_rndis_pktinfo_append(struct rndis_packet_msg *,
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Wed, Nov 12, 4:31 AM (9 h, 55 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
25193639
Default Alt Text
D8089.id21219.diff (7 KB)
Attached To
Mode
D8089: hyperv/hn: Fix if_hw_tsomax setup.
Attached
Detach File
Event Timeline
Log In to Comment