Commit ec90970f authored by Julius Werner's avatar Julius Werner Committed by Ricardo Cañuelo Navarro
Browse files

r8152: Support partial reads for jumbo frame ethernet packets



The RealTek R8153 dongle will only send individual USB packets up to a
certain maximum packet size (not quite clear what this is, possibly
2KB). Usually this seems to be enough for our TFTP needs, but depending
on TFTP server configuration and network path MTU they may occasionally
get bigger. This patch makes sure the driver will not choke if it
receives a 9KB jumbo frame in small pieces.

BRANCH=None
BUG=b:159263757
TEST=ODM said this fixes their problem.
Signed-off-by: default avatarJulius Werner <jwerner@chromium.org>
Change-Id: I9c56de5c15ab6b2017a9a3ee8fa907f28737c0af
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/depthcharge/+/2261078

Reviewed-by: default avatarAaron Durbin <adurbin@google.com>
parent 2028bfc5
......@@ -18,6 +18,7 @@
#include "drivers/net/mii.h"
#include "drivers/net/r8152.h"
#include "drivers/net/usb_eth.h"
#include "net/net.h"
static R8152Dev r8152_dev;
......@@ -842,36 +843,43 @@ static int rtl8152_recv(NetDevice *net_dev, void *buf, uint16_t *len,
uint32_t rx_desc[6];
int32_t packet_len;
static int32_t buf_size = 0;
static uint8_t msg[RxUrbSize + sizeof(rx_desc)];
static int32_t offset;
static uint8_t msg[ETHERNET_MAX_FRAME_SIZE + sizeof(rx_desc)];
static int32_t offset, partial;
if (offset >= buf_size) {
if (partial || offset >= buf_size) {
offset = 0;
buf_size = usb_dev->controller->bulk(r8152_dev.bulk_in,
RxUrbSize, msg, 0);
sizeof(msg) - partial, msg + partial, 0);
if (buf_size < 0) {
printf("R8152: Bulk read error %#x\n", buf_size);
return 1;
}
buf_size += partial;
partial = 0;
}
if (!buf_size) {
*len = 0;
*len = 0;
if (buf_size < offset + sizeof(rx_desc))
return 0;
}
memcpy(&rx_desc, msg + offset, sizeof(rx_desc));
packet_len = le32toh(rx_desc[0]) & 0x7fff;
packet_len -= 4;
*len = packet_len;
if ((packet_len > maxlen) || (offset + packet_len > buf_size)) {
if (packet_len > maxlen ||
offset + sizeof(rx_desc) + packet_len > sizeof(msg)) {
buf_size = 0;
offset = 0;
printf("R8152: Packet is too large.\n");
return 1;
}
if (offset == 0 && packet_len > buf_size) {
partial = buf_size;
return 0;
}
*len = packet_len;
memcpy(buf, msg + offset + sizeof(rx_desc), packet_len);
offset += sizeof(rx_desc) + packet_len + 4;
offset = ALIGN_UP(offset, 8);
......
......@@ -18,6 +18,9 @@
#ifndef __NET_NET_H__
#define __NET_NET_H__
/* Common maximum supported jumbo frame size according to Wikipedia. */
#define ETHERNET_MAX_FRAME_SIZE 9216
typedef void (*NetCallback)(void);
void net_set_callback(NetCallback func);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment