Browse Source

[netdevice] Add mechanism for reporting detailed link status codes

Expand the NETDEV_LINK_UP bit into a link_rc status code field,
allowing specific reasons for link failure to be reported via
"ifstat".

Originally-authored-by: Joshua Oreman <oremanj@rwcr.net>
tags/v0.9.8
Michael Brown 15 years ago
parent
commit
a310d00d37
4 changed files with 48 additions and 8 deletions
  1. 1
    0
      src/hci/strerror.c
  2. 13
    8
      src/include/gpxe/netdevice.h
  3. 30
    0
      src/net/netdevice.c
  4. 4
    0
      src/usr/ifmgmt.c

+ 1
- 0
src/hci/strerror.c View File

115
 	{ ENOEXEC, "Not an executable image" },
115
 	{ ENOEXEC, "Not an executable image" },
116
 	{ ENOMEM, "Out of memory" },
116
 	{ ENOMEM, "Out of memory" },
117
 	{ ENOSPC, "No space left on device" },
117
 	{ ENOSPC, "No space left on device" },
118
+	{ ENOTCONN, "Not connected" },
118
 	{ ENOTSUP, "Not supported" },
119
 	{ ENOTSUP, "Not supported" },
119
 	{ EPERM, "Operation not permitted" },
120
 	{ EPERM, "Operation not permitted" },
120
 	{ ERANGE, "Out of range" },
121
 	{ ERANGE, "Out of range" },

+ 13
- 8
src/include/gpxe/netdevice.h View File

267
 	 * This is the bitwise-OR of zero or more NETDEV_XXX constants.
267
 	 * This is the bitwise-OR of zero or more NETDEV_XXX constants.
268
 	 */
268
 	 */
269
 	unsigned int state;
269
 	unsigned int state;
270
+	/** Link status code
271
+	 *
272
+	 * Zero indicates that the link is up; any other value
273
+	 * indicates the error preventing link-up.
274
+	 */
275
+	int link_rc;
270
 	/** Maximum packet length
276
 	/** Maximum packet length
271
 	 *
277
 	 *
272
 	 * This length includes any link-layer headers.
278
 	 * This length includes any link-layer headers.
291
 /** Network device is open */
297
 /** Network device is open */
292
 #define NETDEV_OPEN 0x0001
298
 #define NETDEV_OPEN 0x0001
293
 
299
 
294
-/** Network device has link */
295
-#define NETDEV_LINK_UP 0x0002
296
-
297
 /** Link-layer protocol table */
300
 /** Link-layer protocol table */
298
 #define LL_PROTOCOLS __table ( struct ll_protocol, "ll_protocols" )
301
 #define LL_PROTOCOLS __table ( struct ll_protocol, "ll_protocols" )
299
 
302
 
420
  */
423
  */
421
 static inline __attribute__ (( always_inline )) void
424
 static inline __attribute__ (( always_inline )) void
422
 netdev_link_up ( struct net_device *netdev ) {
425
 netdev_link_up ( struct net_device *netdev ) {
423
-	netdev->state |= NETDEV_LINK_UP;
426
+	netdev->link_rc = 0;
424
 }
427
 }
425
 
428
 
426
 /**
429
 /**
427
- * Mark network device as having link down
430
+ * Mark network device as having link down due to a specific error
428
  *
431
  *
429
  * @v netdev		Network device
432
  * @v netdev		Network device
433
+ * @v rc		Link status code
430
  */
434
  */
431
 static inline __attribute__ (( always_inline )) void
435
 static inline __attribute__ (( always_inline )) void
432
-netdev_link_down ( struct net_device *netdev ) {
433
-	netdev->state &= ~NETDEV_LINK_UP;
436
+netdev_link_err ( struct net_device *netdev, int rc ) {
437
+	netdev->link_rc = rc;
434
 }
438
 }
435
 
439
 
436
 /**
440
 /**
441
  */
445
  */
442
 static inline __attribute__ (( always_inline )) int
446
 static inline __attribute__ (( always_inline )) int
443
 netdev_link_ok ( struct net_device *netdev ) {
447
 netdev_link_ok ( struct net_device *netdev ) {
444
-	return ( netdev->state & NETDEV_LINK_UP );
448
+	return ( netdev->link_rc == 0 );
445
 }
449
 }
446
 
450
 
451
+extern void netdev_link_down ( struct net_device *netdev );
447
 extern int netdev_tx ( struct net_device *netdev, struct io_buffer *iobuf );
452
 extern int netdev_tx ( struct net_device *netdev, struct io_buffer *iobuf );
448
 extern void netdev_tx_complete_err ( struct net_device *netdev,
453
 extern void netdev_tx_complete_err ( struct net_device *netdev,
449
 				 struct io_buffer *iobuf, int rc );
454
 				 struct io_buffer *iobuf, int rc );

+ 30
- 0
src/net/netdevice.c View File

30
 #include <gpxe/process.h>
30
 #include <gpxe/process.h>
31
 #include <gpxe/init.h>
31
 #include <gpxe/init.h>
32
 #include <gpxe/device.h>
32
 #include <gpxe/device.h>
33
+#include <gpxe/errortab.h>
33
 #include <gpxe/netdevice.h>
34
 #include <gpxe/netdevice.h>
34
 
35
 
35
 /** @file
36
 /** @file
44
 /** List of open network devices, in reverse order of opening */
45
 /** List of open network devices, in reverse order of opening */
45
 struct list_head open_net_devices = LIST_HEAD_INIT ( open_net_devices );
46
 struct list_head open_net_devices = LIST_HEAD_INIT ( open_net_devices );
46
 
47
 
48
+/** Default link status code */
49
+#define EUNKNOWN_LINK_STATUS EINPROGRESS
50
+
51
+/** Human-readable message for the default link status */
52
+struct errortab netdev_errors[] __errortab = {
53
+	{ EUNKNOWN_LINK_STATUS, "Unknown" },
54
+};
55
+
56
+/**
57
+ * Mark network device as having link down
58
+ *
59
+ * @v netdev		Network device
60
+ */
61
+void netdev_link_down ( struct net_device *netdev ) {
62
+
63
+	switch ( netdev->link_rc ) {
64
+	case 0:
65
+	case -EUNKNOWN_LINK_STATUS:
66
+		netdev->link_rc = -ENOTCONN;
67
+		break;
68
+	default:
69
+		/* Avoid clobbering a more detailed link status code,
70
+		 * if one is already set.
71
+		 */
72
+		break;
73
+	}
74
+}
75
+
47
 /**
76
 /**
48
  * Record network device statistic
77
  * Record network device statistic
49
  *
78
  *
302
 	netdev = zalloc ( total_len );
331
 	netdev = zalloc ( total_len );
303
 	if ( netdev ) {
332
 	if ( netdev ) {
304
 		netdev->refcnt.free = free_netdev;
333
 		netdev->refcnt.free = free_netdev;
334
+		netdev->link_rc = -EUNKNOWN_LINK_STATUS;
305
 		INIT_LIST_HEAD ( &netdev->tx_queue );
335
 		INIT_LIST_HEAD ( &netdev->tx_queue );
306
 		INIT_LIST_HEAD ( &netdev->rx_queue );
336
 		INIT_LIST_HEAD ( &netdev->rx_queue );
307
 		netdev_settings_init ( netdev );
337
 		netdev_settings_init ( netdev );

+ 4
- 0
src/usr/ifmgmt.c View File

94
 		 ( netdev_link_ok ( netdev ) ? "up" : "down" ),
94
 		 ( netdev_link_ok ( netdev ) ? "up" : "down" ),
95
 		 netdev->tx_stats.good, netdev->tx_stats.bad,
95
 		 netdev->tx_stats.good, netdev->tx_stats.bad,
96
 		 netdev->rx_stats.good, netdev->rx_stats.bad );
96
 		 netdev->rx_stats.good, netdev->rx_stats.bad );
97
+	if ( ! netdev_link_ok ( netdev ) ) {
98
+		printf ( "  [Link status: %s]\n",
99
+			 strerror ( netdev->link_rc ) );
100
+	}
97
 	ifstat_errors ( &netdev->tx_stats, "TXE" );
101
 	ifstat_errors ( &netdev->tx_stats, "TXE" );
98
 	ifstat_errors ( &netdev->rx_stats, "RXE" );
102
 	ifstat_errors ( &netdev->rx_stats, "RXE" );
99
 }
103
 }

Loading…
Cancel
Save