]> git.ipfire.org Git - thirdparty/ipxe.git/commitdiff
[netdevice] Allow non-completion TX errors to be recorded
authorMichael Brown <mcb30@ipxe.org>
Tue, 28 Jun 2011 09:19:23 +0000 (10:19 +0100)
committerMichael Brown <mcb30@ipxe.org>
Tue, 28 Jun 2011 09:19:23 +0000 (10:19 +0100)
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>
src/include/ipxe/netdevice.h
src/net/netdevice.c

index e49191f4ae214268cb59246e2b1365d3c9f4e142..64285984eab4154170526b21e7cb7c1503ef2c81 100644 (file)
@@ -586,6 +586,8 @@ netdev_rx_frozen ( struct net_device *netdev ) {
 extern void netdev_link_err ( struct net_device *netdev, int rc );
 extern void netdev_link_down ( struct net_device *netdev );
 extern int netdev_tx ( struct net_device *netdev, struct io_buffer *iobuf );
+extern void netdev_tx_err ( struct net_device *netdev,
+                           struct io_buffer *iobuf, int rc );
 extern void netdev_tx_complete_err ( struct net_device *netdev,
                                 struct io_buffer *iobuf, int rc );
 extern void netdev_tx_complete_next_err ( struct net_device *netdev, int rc );
index 9a8a3aaf6a376f3a4de7c20e2a765e96af8891c0..54b41b3f16b90b68a34353613a657dcda40f478d 100644 (file)
@@ -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;
        }