summaryrefslogtreecommitdiffstats
path: root/sys/net
diff options
context:
space:
mode:
authorhselasky <hselasky@FreeBSD.org>2014-09-13 20:52:01 +0000
committerhselasky <hselasky@FreeBSD.org>2014-09-13 20:52:01 +0000
commit727760a4e452031c6ff1856c341de106c671838e (patch)
treef2a711c563349212d5fa8c8a4d2f0a78d82ace1e /sys/net
parentd999791b48275bcd322e001fb9096478bb0f0045 (diff)
downloadFreeBSD-src-727760a4e452031c6ff1856c341de106c671838e.zip
FreeBSD-src-727760a4e452031c6ff1856c341de106c671838e.tar.gz
Revert r271504. A new patch to solve this issue will be made.
Suggested by: adrian @
Diffstat (limited to 'sys/net')
-rw-r--r--sys/net/if.c60
-rw-r--r--sys/net/if_lagg.c13
-rw-r--r--sys/net/if_var.h44
-rw-r--r--sys/net/if_vlan.c4
4 files changed, 23 insertions, 98 deletions
diff --git a/sys/net/if.c b/sys/net/if.c
index 5e9b776..017af33 100644
--- a/sys/net/if.c
+++ b/sys/net/if.c
@@ -423,52 +423,6 @@ if_grow(void)
}
/*
- * Compute the least common value of two "if_hw_tsomax" values:
- */
-u_int
-if_hw_tsomax_common(u_int a, u_int b)
-{
- u_int a_bytes = IF_HW_TSOMAX_GET_BYTES(a);
- u_int a_frag_count = IF_HW_TSOMAX_GET_FRAG_COUNT(a);
- u_int a_frag_size = IF_HW_TSOMAX_GET_FRAG_SIZE(a);
- u_int b_bytes = IF_HW_TSOMAX_GET_BYTES(b);
- u_int b_frag_count = IF_HW_TSOMAX_GET_FRAG_COUNT(b);
- u_int b_frag_size = IF_HW_TSOMAX_GET_FRAG_SIZE(b);
-
- return (IF_HW_TSOMAX_BUILD_VALUE(min(a_bytes, b_bytes),
- min(a_frag_count, b_frag_count),
- min(a_frag_size, b_frag_size)));
-}
-
-/*
- * Range check the "if_hw_tsomax" value:
- */
-u_int
-if_hw_tsomax_range_check(u_int a)
-{
- u_int a_bytes = IF_HW_TSOMAX_GET_BYTES(a);
- u_int a_frag_count = IF_HW_TSOMAX_GET_FRAG_COUNT(a);
- u_int a_frag_size = IF_HW_TSOMAX_GET_FRAG_SIZE(a);
-
- /* round down to nearest 4 bytes */
- a_bytes &= 0xFFFC;
-
- /* use default, if zero */
- if (a_bytes == 0)
- a_bytes = IF_HW_TSOMAX_DEFAULT_BYTES;
-
- /* use default, if zero */
- if (a_frag_count == 0)
- a_frag_count = IF_HW_TSOMAX_DEFAULT_FRAG_COUNT;
-
- /* use default, if zero */
- if (a_frag_size == 0)
- a_frag_size = IF_HW_TSOMAX_DEFAULT_FRAG_SIZE;
-
- return (IF_HW_TSOMAX_BUILD_VALUE(a_bytes, a_frag_count, a_frag_size));
-}
-
-/*
* Allocate a struct ifnet and an index for an interface. A layer 2
* common structure will also be allocated if an allocation routine is
* registered for the passed type.
@@ -491,7 +445,6 @@ if_alloc(u_char type)
ifp->if_index = idx;
ifp->if_type = type;
ifp->if_alloctype = type;
- ifp->if_hw_tsomax = IF_HW_TSOMAX_DEFAULT_VALUE();
if (if_com_alloc[type] != NULL) {
ifp->if_l2com = if_com_alloc[type](type, ifp);
if (ifp->if_l2com == NULL) {
@@ -704,9 +657,16 @@ if_attach_internal(struct ifnet *ifp, int vmove)
TAILQ_INSERT_HEAD(&ifp->if_addrhead, ifa, ifa_link);
/* Reliably crash if used uninitialized. */
ifp->if_broadcastaddr = NULL;
- /* range check TSO value */
- ifp->if_hw_tsomax =
- if_hw_tsomax_range_check(ifp->if_hw_tsomax);
+
+#if defined(INET) || defined(INET6)
+ /* Initialize to max value. */
+ if (ifp->if_hw_tsomax == 0)
+ ifp->if_hw_tsomax = min(IP_MAXPACKET, 32 * MCLBYTES -
+ (ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN));
+ KASSERT(ifp->if_hw_tsomax <= IP_MAXPACKET &&
+ ifp->if_hw_tsomax >= IP_MAXPACKET / 8,
+ ("%s: tsomax outside of range", __func__));
+#endif
}
#ifdef VIMAGE
else {
diff --git a/sys/net/if_lagg.c b/sys/net/if_lagg.c
index e7cfb3c..8d53526 100644
--- a/sys/net/if_lagg.c
+++ b/sys/net/if_lagg.c
@@ -445,7 +445,11 @@ lagg_capabilities(struct lagg_softc *sc)
struct lagg_port *lp;
int cap = ~0, ena = ~0;
u_long hwa = ~0UL;
- u_int hw_tsomax = IF_HW_TSOMAX_DEFAULT_VALUE();
+#if defined(INET) || defined(INET6)
+ u_int hw_tsomax = IP_MAXPACKET; /* Initialize to the maximum value. */
+#else
+ u_int hw_tsomax = ~0; /* if_hw_tsomax is only for INET/INET6, but.. */
+#endif
LAGG_WLOCK_ASSERT(sc);
@@ -454,9 +458,10 @@ lagg_capabilities(struct lagg_softc *sc)
cap &= lp->lp_ifp->if_capabilities;
ena &= lp->lp_ifp->if_capenable;
hwa &= lp->lp_ifp->if_hwassist;
- /* Set to the common value of the lagg ports. */
- hw_tsomax = if_hw_tsomax_common(hw_tsomax,
- lp->lp_ifp->if_hw_tsomax);
+ /* Set to the minimum value of the lagg ports. */
+ if (lp->lp_ifp->if_hw_tsomax < hw_tsomax &&
+ lp->lp_ifp->if_hw_tsomax > 0)
+ hw_tsomax = lp->lp_ifp->if_hw_tsomax;
}
cap = (cap == ~0 ? 0 : cap);
ena = (ena == ~0 ? 0 : ena);
diff --git a/sys/net/if_var.h b/sys/net/if_var.h
index af83713..09f41b8 100644
--- a/sys/net/if_var.h
+++ b/sys/net/if_var.h
@@ -120,43 +120,6 @@ typedef int (*if_transmit_fn_t)(if_t, struct mbuf *);
typedef uint64_t (*if_get_counter_t)(if_t, ifnet_counter);
/*
- * Macros defining how to decode the "if_hw_tsomax" field:
- */
-#define IF_HW_TSOMAX_GET_BYTES(x) \
- ((uint16_t)(x)) /* 32..65535 */
-
-#define IF_HW_TSOMAX_GET_FRAG_COUNT(x) \
- ((uint8_t)((x) >> 16)) /* 1..255 */
-
-#define IF_HW_TSOMAX_GET_FRAG_SIZE(x) \
- ((uint8_t)((x) >> 24)) /* 12..16 */
-
-/*
- * The following macro defines how to build the "if_hw_tsomax"
- * field. The "bytes" field has unit 1 bytes and declares the maximum
- * number of bytes which can be transferred by a single transmit
- * offload, TSO, job. The "bytes" field is rounded down to the neares
- * 4 bytes to avoid having the hardware do unaligned memory
- * accesses. The "frag_count" field has unit 1 fragment and declares
- * the maximum number of fragments a TSO job can contain. The
- * "frag_size" field has unit logarithm in base 2 of the actual value
- * in bytes and declares the maximum size of a fragment.
- */
-#define IF_HW_TSOMAX_BUILD_VALUE(bytes, frag_count, frag_size) \
- (((bytes) & 0xFFFC) | (((frag_count) & 0xFF) << 16) | \
- (((frag_size) & 0xFF) << 24))
-
-#define IF_HW_TSOMAX_DEFAULT_BYTES (65536 - 4)
-#define IF_HW_TSOMAX_DEFAULT_FRAG_COUNT 255
-#define IF_HW_TSOMAX_DEFAULT_FRAG_SIZE 16
-
-#define IF_HW_TSOMAX_DEFAULT_VALUE() \
- IF_HW_TSOMAX_BUILD_VALUE( \
- IF_HW_TSOMAX_DEFAULT_BYTES, \
- IF_HW_TSOMAX_DEFAULT_FRAG_COUNT, \
- IF_HW_TSOMAX_DEFAULT_FRAG_SIZE)
-
-/*
* Structure defining a network interface.
*
* Size ILP32: 592 (approx)
@@ -259,7 +222,8 @@ struct ifnet {
if_get_counter_t if_get_counter; /* get counter values */
/* Stuff that's only temporary and doesn't belong here. */
- u_int if_hw_tsomax; /* TSO burst length limits.
+ u_int if_hw_tsomax; /* tso burst length limit, the minimum
+ * is (IP_MAXPACKET / 8).
* XXXAO: Have to find a better place
* for it eventually. */
/*
@@ -644,10 +608,6 @@ void if_setioctlfn(if_t ifp, int (*)(if_t, u_long, caddr_t));
void if_setstartfn(if_t ifp, void (*)(if_t));
void if_settransmitfn(if_t ifp, if_transmit_fn_t);
void if_setqflushfn(if_t ifp, if_qflush_fn_t);
-
-/* "if_hw_tsomax" related functions */
-u_int if_hw_tsomax_common(u_int, u_int);
-u_int if_hw_tsomax_range_check(u_int);
/* Revisit the below. These are inline functions originally */
int drbr_inuse_drv(if_t ifp, struct buf_ring *br);
diff --git a/sys/net/if_vlan.c b/sys/net/if_vlan.c
index b7ccb61..5a5e712 100644
--- a/sys/net/if_vlan.c
+++ b/sys/net/if_vlan.c
@@ -1557,8 +1557,8 @@ vlan_capabilities(struct ifvlan *ifv)
* propagate the hardware-assisted flag. TSO on VLANs
* does not necessarily require hardware VLAN tagging.
*/
- ifp->if_hw_tsomax = if_hw_tsomax_common(ifp->if_hw_tsomax,
- p->if_hw_tsomax);
+ if (p->if_hw_tsomax > 0)
+ ifp->if_hw_tsomax = p->if_hw_tsomax;
if (p->if_capabilities & IFCAP_VLAN_HWTSO)
ifp->if_capabilities |= p->if_capabilities & IFCAP_TSO;
if (p->if_capenable & IFCAP_VLAN_HWTSO) {
OpenPOWER on IntegriCloud