summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/net/if_var.h11
-rw-r--r--sys/netinet/tcp_output.c12
2 files changed, 17 insertions, 6 deletions
diff --git a/sys/net/if_var.h b/sys/net/if_var.h
index 58391a1..1ff7a4b 100644
--- a/sys/net/if_var.h
+++ b/sys/net/if_var.h
@@ -236,11 +236,12 @@ struct ifnet {
* count limit does not apply. If all three fields are zero,
* there is no TSO limit.
*
- * NOTE: The TSO limits only apply to the data payload part of
- * a TCP/IP packet. That means there is no need to subtract
- * space for ethernet-, vlan-, IP- or TCP- headers from the
- * TSO limits unless the hardware driver in question requires
- * so.
+ * NOTE: The TSO limits should reflect the values used in the
+ * BUSDMA tag a network adapter is using to load a mbuf chain
+ * for transmission. The TCP/IP network stack will subtract
+ * space for all linklevel and protocol level headers and
+ * ensure that the full mbuf chain passed to the network
+ * adapter fits within the given limits.
*/
u_int if_hw_tsomax;
diff --git a/sys/netinet/tcp_output.c b/sys/netinet/tcp_output.c
index ba0ec40..f1196e1 100644
--- a/sys/netinet/tcp_output.c
+++ b/sys/netinet/tcp_output.c
@@ -807,7 +807,8 @@ send:
*/
if (if_hw_tsomax != 0) {
/* compute maximum TSO length */
- max_len = (if_hw_tsomax - hdrlen);
+ max_len = (if_hw_tsomax - hdrlen -
+ max_linkhdr);
if (max_len <= 0) {
len = 0;
} else if (len > max_len) {
@@ -822,6 +823,15 @@ send:
*/
if (if_hw_tsomaxsegcount != 0 &&
if_hw_tsomaxsegsize != 0) {
+ /*
+ * Subtract one segment for the LINK
+ * and TCP/IP headers mbuf that will
+ * be prepended to this mbuf chain
+ * after the code in this section
+ * limits the number of mbufs in the
+ * chain to if_hw_tsomaxsegcount.
+ */
+ if_hw_tsomaxsegcount -= 1;
max_len = 0;
mb = sbsndmbuf(&so->so_snd, off, &moff);
OpenPOWER on IntegriCloud