summaryrefslogtreecommitdiffstats
path: root/src/drivers/net/smsc95xx.c
diff options
context:
space:
mode:
authorMichael Brown2016-01-19 01:04:33 +0100
committerMichael Brown2016-01-19 01:23:06 +0100
commit207edc46158a91128c28de43c47cb4c1ac98e207 (patch)
tree4b6c10883cdf9724b615f27794b0a2858d6de7cd /src/drivers/net/smsc95xx.c
parent[usb] Allow USB endpoints to specify a reserved header length for refills (diff)
downloadipxe-207edc46158a91128c28de43c47cb4c1ac98e207.tar.gz
ipxe-207edc46158a91128c28de43c47cb4c1ac98e207.tar.xz
ipxe-207edc46158a91128c28de43c47cb4c1ac98e207.zip
[smsc95xx] Reserve headroom in received packets
Some protocols (such as ARP) may modify the received packet and re-use the same I/O buffer for transmission of a reply. The SMSC95XX transmit header is larger than the receive header: the re-used I/O buffer therefore does not have sufficient headroom for the transmit header, and the ARP reply will therefore fail to be transmitted. This is essentially the same problem as in commit 2e72d10 ("[ncm] Reserve headroom in received packets"). Fix by reserving sufficient space at the start of each received packet to allow for the difference between the lengths of the transmit and receive headers. This problem is not caught by the current driver development test suite (documented at http://ipxe.org/dev/driver), since even the large file transfer tests tend to completely sufficiently quickly that there is no need for the server to ever send an ARP request. The failure shows up only when using a very slow protocol such as RFC7440-enhanced TFTP (as used by Windows Deployment Services). Signed-off-by: Michael Brown <mcb30@ipxe.org>
Diffstat (limited to 'src/drivers/net/smsc95xx.c')
-rw-r--r--src/drivers/net/smsc95xx.c6
1 files changed, 4 insertions, 2 deletions
diff --git a/src/drivers/net/smsc95xx.c b/src/drivers/net/smsc95xx.c
index 1e237d01..3d9c0f1a 100644
--- a/src/drivers/net/smsc95xx.c
+++ b/src/drivers/net/smsc95xx.c
@@ -1142,8 +1142,10 @@ static int smsc95xx_probe ( struct usb_function *func,
&smsc95xx_in_operations, &smsc95xx_out_operations );
usb_refill_init ( &smsc95xx->usbnet.intr, 0, 0,
SMSC95XX_INTR_MAX_FILL );
- usb_refill_init ( &smsc95xx->usbnet.in, 0, SMSC95XX_IN_MTU,
- SMSC95XX_IN_MAX_FILL );
+ usb_refill_init ( &smsc95xx->usbnet.in,
+ ( sizeof ( struct smsc95xx_tx_header ) -
+ sizeof ( struct smsc95xx_rx_header ) ),
+ SMSC95XX_IN_MTU, SMSC95XX_IN_MAX_FILL );
mii_init ( &smsc95xx->mii, &smsc95xx_mii_operations );
DBGC ( smsc95xx, "SMSC95XX %p on %s\n", smsc95xx, func->name );