aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoe Hershberger <joe.hershberger@ni.com>2015-04-03 20:09:46 -0500
committerSimon Glass <sjg@chromium.org>2015-04-18 11:11:18 -0600
commit63c9729a1306ee3fed54923f53b20ce769884a81 (patch)
tree3aaf0e23d5620892ed37593aca29d7a77fbf6699
parent5bc48308960b8d28d9d7653efbb91c1be390c916 (diff)
downloadu-boot-63c9729a1306ee3fed54923f53b20ce769884a81.zip
u-boot-63c9729a1306ee3fed54923f53b20ce769884a81.tar.gz
u-boot-63c9729a1306ee3fed54923f53b20ce769884a81.tar.bz2
dm: eth: Provide a way for drivers to manage packet buffers
Some drivers need a chance to manage their receive buffers after the packet has been handled by the network stack. Add an operation that will allow the driver to be called in that case. Reported-by: Simon Glass <sjg@chromium.org> Signed-off-by: Joe Hershberger <joe.hershberger@ni.com> Acked-by: Simon Glass <sjg@chromium.org> Tested-by: Simon Glass <sjg@chromium.org> Tested-on: pcduino3
-rw-r--r--include/net.h8
-rw-r--r--net/eth.c4
2 files changed, 10 insertions, 2 deletions
diff --git a/include/net.h b/include/net.h
index e7f28d7..35602cd 100644
--- a/include/net.h
+++ b/include/net.h
@@ -97,7 +97,12 @@ struct eth_pdata {
* send: Send the bytes passed in "packet" as a packet on the wire
* recv: Check if the hardware received a packet. If so, set the pointer to the
* packet buffer in the packetp parameter. If not, return an error or 0 to
- * indicate that the hardware receive FIFO is empty
+ * indicate that the hardware receive FIFO is empty. If 0 is returned, the
+ * network stack will not process the empty packet, but free_pkt() will be
+ * called if supplied
+ * free_pkt: Give the driver an opportunity to manage its packet buffer memory
+ * when the network stack is finished processing it. This will only be
+ * called when no error was returned from recv - optional
* stop: Stop the hardware from looking for packets - may be called even if
* state == PASSIVE
* mcast: Join or leave a multicast group (for TFTP) - optional
@@ -113,6 +118,7 @@ struct eth_ops {
int (*start)(struct udevice *dev);
int (*send)(struct udevice *dev, void *packet, int length);
int (*recv)(struct udevice *dev, uchar **packetp);
+ int (*free_pkt)(struct udevice *dev, uchar *packet, int length);
void (*stop)(struct udevice *dev);
#ifdef CONFIG_MCAST_TFTP
int (*mcast)(struct udevice *dev, const u8 *enetaddr, int join);
diff --git a/net/eth.c b/net/eth.c
index 13b7723..05411f1 100644
--- a/net/eth.c
+++ b/net/eth.c
@@ -344,7 +344,9 @@ int eth_rx(void)
ret = eth_get_ops(current)->recv(current, &packet);
if (ret > 0)
net_process_received_packet(packet, ret);
- else
+ if (ret >= 0 && eth_get_ops(current)->free_pkt)
+ eth_get_ops(current)->free_pkt(current, packet, ret);
+ if (ret <= 0)
break;
}
if (ret == -EAGAIN)