summaryrefslogtreecommitdiffstats
path: root/src/net
diff options
context:
space:
mode:
Diffstat (limited to 'src/net')
-rw-r--r--src/net/netdevice.c9
-rw-r--r--src/net/tcp.c12
2 files changed, 17 insertions, 4 deletions
diff --git a/src/net/netdevice.c b/src/net/netdevice.c
index 2733d237d..c5085918f 100644
--- a/src/net/netdevice.c
+++ b/src/net/netdevice.c
@@ -398,8 +398,13 @@ static void net_step ( struct process *process ) {
/* Poll for new packets */
netdev_poll ( netdev, -1U );
- /* Process received packets */
- while ( ( pkb = netdev_rx_dequeue ( netdev ) ) ) {
+ /* Process at most one received packet. Give priority
+ * to getting packets out of the NIC over processing
+ * the received packets, because we advertise a window
+ * that assumes that we can receive packets from the
+ * NIC faster than they arrive.
+ */
+ if ( ( pkb = netdev_rx_dequeue ( netdev ) ) ) {
DBGC ( netdev, "NETDEV %p processing %p\n",
netdev, pkb );
netdev->ll_protocol->rx ( pkb, netdev );
diff --git a/src/net/tcp.c b/src/net/tcp.c
index af5f2b064..2311881bf 100644
--- a/src/net/tcp.c
+++ b/src/net/tcp.c
@@ -6,6 +6,7 @@
#include <timer.h>
#include <vsprintf.h>
#include <gpxe/pkbuff.h>
+#include <gpxe/malloc.h>
#include <gpxe/retry.h>
#include <gpxe/tcpip.h>
#include <gpxe/tcp.h>
@@ -265,6 +266,7 @@ static int tcp_senddata_conn ( struct tcp_connection *conn, int force_send ) {
unsigned int flags;
size_t len;
size_t seq_len;
+ size_t window;
int rc;
/* Allocate space to the TX buffer */
@@ -322,6 +324,12 @@ static int tcp_senddata_conn ( struct tcp_connection *conn, int force_send ) {
if ( seq_len )
start_timer ( &conn->timer );
+ /* Estimate window size */
+ window = freemem;
+ if ( window > TCP_MAX_WINDOW_SIZE )
+ window = TCP_MAX_WINDOW_SIZE;
+ window &= ~0x03; /* Keep everything dword-aligned */
+
/* Fill up the TCP header */
payload = pkb->data;
if ( flags & TCP_SYN ) {
@@ -338,7 +346,7 @@ static int tcp_senddata_conn ( struct tcp_connection *conn, int force_send ) {
tcphdr->ack = htonl ( conn->rcv_ack );
tcphdr->hlen = ( ( payload - pkb->data ) << 2 );
tcphdr->flags = flags;
- tcphdr->win = htons ( TCP_WINDOW_SIZE );
+ tcphdr->win = htons ( window );
tcphdr->csum = tcpip_chksum ( pkb->data, pkb_len ( pkb ) );
/* Dump header */
@@ -492,7 +500,7 @@ static int tcp_send_reset ( struct tcp_connection *conn,
tcphdr->ack = in_tcphdr->seq;
tcphdr->hlen = ( ( sizeof ( *tcphdr ) / 4 ) << 4 );
tcphdr->flags = ( TCP_RST | TCP_ACK );
- tcphdr->win = htons ( TCP_WINDOW_SIZE );
+ tcphdr->win = htons ( TCP_MAX_WINDOW_SIZE );
tcphdr->csum = tcpip_chksum ( pkb->data, pkb_len ( pkb ) );
/* Dump header */