summaryrefslogtreecommitdiffstats
path: root/src/net/netdevice.c
diff options
context:
space:
mode:
authorMichael Brown2011-06-28 11:19:23 +0200
committerMichael Brown2011-06-28 11:19:23 +0200
commitd6115c91cfa4e3de72b87d3035b418d13b81e197 (patch)
treea92c30e2786877dbae437eb4009c7421a6cea77d /src/net/netdevice.c
parent[build] Allow APPEND lines in ipxe.iso to function as expected (diff)
downloadipxe-d6115c91cfa4e3de72b87d3035b418d13b81e197.tar.gz
ipxe-d6115c91cfa4e3de72b87d3035b418d13b81e197.tar.xz
ipxe-d6115c91cfa4e3de72b87d3035b418d13b81e197.zip
[netdevice] Allow non-completion TX errors to be recorded
Allow TX errors to be recorded against a network device even when the packet didn't make it as far as netdev_tx(). Inspired-by: Dominik Russenberger <dominik.russenberger@terreactive.ch> Signed-off-by: Michael Brown <mcb30@ipxe.org>
Diffstat (limited to 'src/net/netdevice.c')
-rw-r--r--src/net/netdevice.c32
1 files changed, 25 insertions, 7 deletions
diff --git a/src/net/netdevice.c b/src/net/netdevice.c
index 9a8a3aaf..54b41b3f 100644
--- a/src/net/netdevice.c
+++ b/src/net/netdevice.c
@@ -194,16 +194,17 @@ int netdev_tx ( struct net_device *netdev, struct io_buffer *iobuf ) {
}
/**
- * Complete network transmission
+ * Discard transmitted packet
*
* @v netdev Network device
- * @v iobuf I/O buffer
+ * @v iobuf I/O buffer, or NULL
* @v rc Packet status code
*
- * The packet must currently be in the network device's TX queue.
+ * The packet is discarded and a TX error is recorded. This function
+ * takes ownership of the I/O buffer.
*/
-void netdev_tx_complete_err ( struct net_device *netdev,
- struct io_buffer *iobuf, int rc ) {
+void netdev_tx_err ( struct net_device *netdev,
+ struct io_buffer *iobuf, int rc ) {
/* Update statistics counter */
netdev_record_stat ( &netdev->tx_stats, rc );
@@ -215,12 +216,28 @@ void netdev_tx_complete_err ( struct net_device *netdev,
netdev->name, iobuf, strerror ( rc ) );
}
+ /* Discard packet */
+ free_iob ( iobuf );
+}
+
+/**
+ * Complete network transmission
+ *
+ * @v netdev Network device
+ * @v iobuf I/O buffer
+ * @v rc Packet status code
+ *
+ * The packet must currently be in the network device's TX queue.
+ */
+void netdev_tx_complete_err ( struct net_device *netdev,
+ struct io_buffer *iobuf, int rc ) {
+
/* Catch data corruption as early as possible */
list_check_contains ( iobuf, &netdev->tx_queue, list );
/* Dequeue and free I/O buffer */
list_del ( &iobuf->list );
- free_iob ( iobuf );
+ netdev_tx_err ( netdev, iobuf, rc );
}
/**
@@ -644,7 +661,8 @@ int net_tx ( struct io_buffer *iobuf, struct net_device *netdev,
/* Add link-layer header */
if ( ( rc = ll_protocol->push ( netdev, iobuf, ll_dest, ll_source,
net_protocol->net_proto ) ) != 0 ) {
- free_iob ( iobuf );
+ /* Record error for diagnosis */
+ netdev_tx_err ( netdev, iobuf, rc );
return rc;
}