瀏覽代碼

[netdevice] Add the concept of a network upper-layer driver

Add the concept of a network upper-layer driver, which can create
arbitrary devices on top of network devices.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown 15 年之前
父節點
當前提交
ca4df90a63
共有 2 個檔案被更改,包括 114 行新增35 行删除
  1. 39
    21
      src/include/ipxe/netdevice.h
  2. 75
    14
      src/net/netdevice.c

+ 39
- 21
src/include/ipxe/netdevice.h 查看文件

344
 /** Declare a network-layer protocol */
344
 /** Declare a network-layer protocol */
345
 #define __net_protocol __table_entry ( NET_PROTOCOLS, 01 )
345
 #define __net_protocol __table_entry ( NET_PROTOCOLS, 01 )
346
 
346
 
347
+/** A network upper-layer driver */
348
+struct net_driver {
349
+	/** Name */
350
+	const char *name;
351
+	/** Probe device
352
+	 *
353
+	 * @v netdev		Network device
354
+	 * @ret rc		Return status code
355
+	 */
356
+	int ( * probe ) ( struct net_device *netdev );
357
+	/** Notify of device or link state change
358
+	 *
359
+	 * @v netdev		Network device
360
+	 */
361
+	void ( * notify ) ( struct net_device *netdev );
362
+	/** Remove device
363
+	 *
364
+	 * @v netdev		Network device
365
+	 */
366
+	void ( * remove ) ( struct net_device *netdev );
367
+};
368
+
369
+/** Network driver table */
370
+#define NET_DRIVERS __table ( struct net_driver, "net_drivers" )
371
+
372
+/** Declare a network driver */
373
+#define __net_driver __table_entry ( NET_DRIVERS, 01 )
374
+
347
 extern struct list_head net_devices;
375
 extern struct list_head net_devices;
348
 extern struct net_device_operations null_netdev_operations;
376
 extern struct net_device_operations null_netdev_operations;
349
 extern struct settings_operations netdev_settings_operations;
377
 extern struct settings_operations netdev_settings_operations;
451
 	netdev->settings.settings.op = &netdev_settings_operations;
479
 	netdev->settings.settings.op = &netdev_settings_operations;
452
 }
480
 }
453
 
481
 
454
-/**
455
- * Mark network device as having link up
456
- *
457
- * @v netdev		Network device
458
- */
459
-static inline __attribute__ (( always_inline )) void
460
-netdev_link_up ( struct net_device *netdev ) {
461
-	netdev->link_rc = 0;
462
-}
463
-
464
-/**
465
- * Mark network device as having link down due to a specific error
466
- *
467
- * @v netdev		Network device
468
- * @v rc		Link status code
469
- */
470
-static inline __attribute__ (( always_inline )) void
471
-netdev_link_err ( struct net_device *netdev, int rc ) {
472
-	netdev->link_rc = rc;
473
-}
474
-
475
 /**
482
 /**
476
  * Check link state of network device
483
  * Check link state of network device
477
  *
484
  *
505
 	return ( netdev->state & NETDEV_IRQ_ENABLED );
512
 	return ( netdev->state & NETDEV_IRQ_ENABLED );
506
 }
513
 }
507
 
514
 
515
+extern void netdev_link_err ( struct net_device *netdev, int rc );
508
 extern void netdev_link_down ( struct net_device *netdev );
516
 extern void netdev_link_down ( struct net_device *netdev );
509
 extern int netdev_tx ( struct net_device *netdev, struct io_buffer *iobuf );
517
 extern int netdev_tx ( struct net_device *netdev, struct io_buffer *iobuf );
510
 extern void netdev_tx_complete_err ( struct net_device *netdev,
518
 extern void netdev_tx_complete_err ( struct net_device *netdev,
554
 	netdev_tx_complete_next_err ( netdev, 0 );
562
 	netdev_tx_complete_next_err ( netdev, 0 );
555
 }
563
 }
556
 
564
 
565
+/**
566
+ * Mark network device as having link up
567
+ *
568
+ * @v netdev		Network device
569
+ */
570
+static inline __attribute__ (( always_inline )) void
571
+netdev_link_up ( struct net_device *netdev ) {
572
+	netdev_link_err ( netdev, 0 );
573
+}
574
+
557
 #endif /* _IPXE_NETDEVICE_H */
575
 #endif /* _IPXE_NETDEVICE_H */

+ 75
- 14
src/net/netdevice.c 查看文件

56
 	__einfo_errortab ( EINFO_EUNKNOWN_LINK_STATUS ),
56
 	__einfo_errortab ( EINFO_EUNKNOWN_LINK_STATUS ),
57
 };
57
 };
58
 
58
 
59
+/**
60
+ * Notify drivers of network device or link state change
61
+ *
62
+ * @v netdev		Network device
63
+ */
64
+static void netdev_notify ( struct net_device *netdev ) {
65
+	struct net_driver *driver;
66
+
67
+	for_each_table_entry ( driver, NET_DRIVERS )
68
+		driver->notify ( netdev );
69
+}
70
+
71
+/**
72
+ * Mark network device as having a specific link state
73
+ *
74
+ * @v netdev		Network device
75
+ * @v rc		Link status code
76
+ */
77
+void netdev_link_err ( struct net_device *netdev, int rc ) {
78
+
79
+	/* Record link state */
80
+	netdev->link_rc = rc;
81
+	if ( netdev->link_rc == 0 ) {
82
+		DBGC ( netdev, "NETDEV %p link is up\n", netdev );
83
+	} else {
84
+		DBGC ( netdev, "NETDEV %p link is down: %s\n",
85
+		       netdev, strerror ( netdev->link_rc ) );
86
+	}
87
+
88
+	/* Notify drivers of link state change */
89
+	netdev_notify ( netdev );
90
+}
91
+
59
 /**
92
 /**
60
  * Mark network device as having link down
93
  * Mark network device as having link down
61
  *
94
  *
68
 	 */
101
 	 */
69
 	if ( ( netdev->link_rc == 0 ) ||
102
 	if ( ( netdev->link_rc == 0 ) ||
70
 	     ( netdev->link_rc == -EUNKNOWN_LINK_STATUS ) ) {
103
 	     ( netdev->link_rc == -EUNKNOWN_LINK_STATUS ) ) {
71
-		netdev->link_rc = -ENOTCONN;
104
+		netdev_link_err ( netdev, -ENOTCONN );
72
 	}
105
 	}
73
 }
106
 }
74
 
107
 
367
  */
400
  */
368
 int register_netdev ( struct net_device *netdev ) {
401
 int register_netdev ( struct net_device *netdev ) {
369
 	static unsigned int ifindex = 0;
402
 	static unsigned int ifindex = 0;
403
+	struct net_driver *driver;
370
 	int rc;
404
 	int rc;
371
 
405
 
372
 	/* Create device name */
406
 	/* Create device name */
376
 	/* Set initial link-layer address */
410
 	/* Set initial link-layer address */
377
 	netdev->ll_protocol->init_addr ( netdev->hw_addr, netdev->ll_addr );
411
 	netdev->ll_protocol->init_addr ( netdev->hw_addr, netdev->ll_addr );
378
 
412
 
413
+	/* Add to device list */
414
+	netdev_get ( netdev );
415
+	list_add_tail ( &netdev->list, &net_devices );
416
+	DBGC ( netdev, "NETDEV %p registered as %s (phys %s hwaddr %s)\n",
417
+	       netdev, netdev->name, netdev->dev->name,
418
+	       netdev_addr ( netdev ) );
419
+
379
 	/* Register per-netdev configuration settings */
420
 	/* Register per-netdev configuration settings */
380
 	if ( ( rc = register_settings ( netdev_settings ( netdev ),
421
 	if ( ( rc = register_settings ( netdev_settings ( netdev ),
381
 					NULL ) ) != 0 ) {
422
 					NULL ) ) != 0 ) {
382
 		DBGC ( netdev, "NETDEV %p could not register settings: %s\n",
423
 		DBGC ( netdev, "NETDEV %p could not register settings: %s\n",
383
 		       netdev, strerror ( rc ) );
424
 		       netdev, strerror ( rc ) );
384
-		return rc;
425
+		goto err_register_settings;
385
 	}
426
 	}
386
 
427
 
387
-	/* Add to device list */
388
-	netdev_get ( netdev );
389
-	list_add_tail ( &netdev->list, &net_devices );
390
-	DBGC ( netdev, "NETDEV %p registered as %s (phys %s hwaddr %s)\n",
391
-	       netdev, netdev->name, netdev->dev->name,
392
-	       netdev_addr ( netdev ) );
428
+	/* Probe device */
429
+	for_each_table_entry ( driver, NET_DRIVERS ) {
430
+		if ( ( rc = driver->probe ( netdev ) ) != 0 ) {
431
+			DBGC ( netdev, "NETDEV %p could not add %s device: "
432
+			       "%s\n", netdev, driver->name, strerror ( rc ) );
433
+			goto err_probe;
434
+		}
435
+	}
393
 
436
 
394
 	return 0;
437
 	return 0;
438
+
439
+ err_probe:
440
+	for_each_table_entry_continue_reverse ( driver, NET_DRIVERS )
441
+		driver->remove ( netdev );
442
+	unregister_settings ( netdev_settings ( netdev ) );
443
+ err_register_settings:
444
+	return rc;
395
 }
445
 }
396
 
446
 
397
 /**
447
 /**
419
 	/* Add to head of open devices list */
469
 	/* Add to head of open devices list */
420
 	list_add ( &netdev->open_list, &open_net_devices );
470
 	list_add ( &netdev->open_list, &open_net_devices );
421
 
471
 
472
+	/* Notify drivers of device state change */
473
+	netdev_notify ( netdev );
474
+
422
 	return 0;
475
 	return 0;
423
 }
476
 }
424
 
477
 
435
 
488
 
436
 	DBGC ( netdev, "NETDEV %p closing\n", netdev );
489
 	DBGC ( netdev, "NETDEV %p closing\n", netdev );
437
 
490
 
491
+	/* Remove from open devices list */
492
+	list_del ( &netdev->open_list );
493
+
494
+	/* Mark as closed */
495
+	netdev->state &= ~NETDEV_OPEN;
496
+
497
+	/* Notify drivers of device state change */
498
+	netdev_notify ( netdev );
499
+
438
 	/* Close the device */
500
 	/* Close the device */
439
 	netdev->op->close ( netdev );
501
 	netdev->op->close ( netdev );
440
 
502
 
441
 	/* Flush TX and RX queues */
503
 	/* Flush TX and RX queues */
442
 	netdev_tx_flush ( netdev );
504
 	netdev_tx_flush ( netdev );
443
 	netdev_rx_flush ( netdev );
505
 	netdev_rx_flush ( netdev );
444
-
445
-	/* Mark as closed */
446
-	netdev->state &= ~NETDEV_OPEN;
447
-
448
-	/* Remove from open devices list */
449
-	list_del ( &netdev->open_list );
450
 }
506
 }
451
 
507
 
452
 /**
508
 /**
457
  * Removes the network device from the list of network devices.
513
  * Removes the network device from the list of network devices.
458
  */
514
  */
459
 void unregister_netdev ( struct net_device *netdev ) {
515
 void unregister_netdev ( struct net_device *netdev ) {
516
+	struct net_driver *driver;
460
 
517
 
461
 	/* Ensure device is closed */
518
 	/* Ensure device is closed */
462
 	netdev_close ( netdev );
519
 	netdev_close ( netdev );
463
 
520
 
521
+	/* Remove device */
522
+	for_each_table_entry_reverse ( driver, NET_DRIVERS )
523
+		driver->remove ( netdev );
524
+
464
 	/* Unregister per-netdev configuration settings */
525
 	/* Unregister per-netdev configuration settings */
465
 	unregister_settings ( netdev_settings ( netdev ) );
526
 	unregister_settings ( netdev_settings ( netdev ) );
466
 
527
 

Loading…
取消
儲存