summaryrefslogtreecommitdiffstats
path: root/src/net/netdev_settings.c
diff options
context:
space:
mode:
authorMichael Brown2013-05-16 16:32:17 +0200
committerMichael Brown2013-05-16 16:32:17 +0200
commit08bf79582a281d303842ee11951033d2c532f1f3 (patch)
treec3c2f3fdfd5bcd1e5d85d9b755a2b6e7a0e0112e /src/net/netdev_settings.c
parent[build] Add efidrv.cab target for UEFI Secure Boot signing (diff)
downloadipxe-08bf79582a281d303842ee11951033d2c532f1f3.tar.gz
ipxe-08bf79582a281d303842ee11951033d2c532f1f3.tar.xz
ipxe-08bf79582a281d303842ee11951033d2c532f1f3.zip
[netdevice] Add "chip" setting
Suggested-by: Robin Smidsrød <robin@smidsrod.no> Signed-off-by: Michael Brown <mcb30@ipxe.org>
Diffstat (limited to 'src/net/netdev_settings.c')
-rw-r--r--src/net/netdev_settings.c157
1 files changed, 131 insertions, 26 deletions
diff --git a/src/net/netdev_settings.c b/src/net/netdev_settings.c
index 8758e980..8f66c553 100644
--- a/src/net/netdev_settings.c
+++ b/src/net/netdev_settings.c
@@ -45,6 +45,113 @@ struct setting busid_setting __setting ( SETTING_NETDEV ) = {
.description = "Bus ID",
.type = &setting_type_hex,
};
+struct setting chip_setting __setting ( SETTING_NETDEV ) = {
+ .name = "chip",
+ .description = "Chip",
+ .type = &setting_type_string,
+};
+
+/**
+ * Store MAC address setting
+ *
+ * @v netdev Network device
+ * @v data Setting data, or NULL to clear setting
+ * @v len Length of setting data
+ * @ret rc Return status code
+ */
+static int netdev_store_mac ( struct net_device *netdev,
+ const void *data, size_t len ) {
+
+ if ( len != netdev->ll_protocol->ll_addr_len )
+ return -EINVAL;
+ memcpy ( netdev->ll_addr, data, len );
+ return 0;
+}
+
+/**
+ * Fetch MAC address setting
+ *
+ * @v netdev Network device
+ * @v data Buffer to fill with setting data
+ * @v len Length of buffer
+ * @ret len Length of setting data, or negative error
+ */
+static int netdev_fetch_mac ( struct net_device *netdev, void *data,
+ size_t len ) {
+
+ if ( len > netdev->ll_protocol->ll_addr_len )
+ len = netdev->ll_protocol->ll_addr_len;
+ memcpy ( data, netdev->ll_addr, len );
+ return netdev->ll_protocol->ll_addr_len;
+}
+
+/**
+ * Fetch bus ID setting
+ *
+ * @v netdev Network device
+ * @v data Buffer to fill with setting data
+ * @v len Length of buffer
+ * @ret len Length of setting data, or negative error
+ */
+static int netdev_fetch_busid ( struct net_device *netdev, void *data,
+ size_t len ) {
+ struct device_description *desc = &netdev->dev->desc;
+ struct dhcp_netdev_desc dhcp_desc;
+
+ dhcp_desc.type = desc->bus_type;
+ dhcp_desc.vendor = htons ( desc->vendor );
+ dhcp_desc.device = htons ( desc->device );
+ if ( len > sizeof ( dhcp_desc ) )
+ len = sizeof ( dhcp_desc );
+ memcpy ( data, &dhcp_desc, len );
+ return sizeof ( dhcp_desc );
+}
+
+/**
+ * Fetch chip setting
+ *
+ * @v netdev Network device
+ * @v data Buffer to fill with setting data
+ * @v len Length of buffer
+ * @ret len Length of setting data, or negative error
+ */
+static int netdev_fetch_chip ( struct net_device *netdev, void *data,
+ size_t len ) {
+ const char *chip = netdev->dev->driver_name;
+
+ strncpy ( data, chip, len );
+ return strlen ( chip );
+}
+
+/** A network device setting operation */
+struct netdev_setting_operation {
+ /** Setting */
+ struct setting *setting;
+ /** Store setting (or NULL if not supported)
+ *
+ * @v netdev Network device
+ * @v data Setting data, or NULL to clear setting
+ * @v len Length of setting data
+ * @ret rc Return status code
+ */
+ int ( * store ) ( struct net_device *netdev, const void *data,
+ size_t len );
+ /** Fetch setting
+ *
+ * @v netdev Network device
+ * @v data Buffer to fill with setting data
+ * @v len Length of buffer
+ * @ret len Length of setting data, or negative error
+ */
+ int ( * fetch ) ( struct net_device *netdev, void *data, size_t len );
+};
+
+/** Network device settings */
+static struct netdev_setting_operation netdev_setting_operations[] = {
+ { &mac_setting, netdev_store_mac, netdev_fetch_mac },
+ { &busid_setting, NULL, netdev_fetch_busid },
+ { &chip_setting, NULL, netdev_fetch_chip },
+};
/**
* Store value of network device setting
@@ -59,15 +166,21 @@ static int netdev_store ( struct settings *settings, struct setting *setting,
const void *data, size_t len ) {
struct net_device *netdev = container_of ( settings, struct net_device,
settings.settings );
+ struct netdev_setting_operation *op;
+ unsigned int i;
- if ( setting_cmp ( setting, &mac_setting ) == 0 ) {
- if ( len != netdev->ll_protocol->ll_addr_len )
- return -EINVAL;
- memcpy ( netdev->ll_addr, data, len );
- return 0;
+ /* Handle network device-specific settings */
+ for ( i = 0 ; i < ( sizeof ( netdev_setting_operations ) /
+ sizeof ( netdev_setting_operations[0] ) ) ; i++ ) {
+ op = &netdev_setting_operations[i];
+ if ( setting_cmp ( setting, op->setting ) == 0 ) {
+ if ( op->store ) {
+ return op->store ( netdev, data, len );
+ } else {
+ return -ENOTSUP;
+ }
+ }
}
- if ( setting_cmp ( setting, &busid_setting ) == 0 )
- return -ENOTSUP;
return generic_settings_store ( settings, setting, data, len );
}
@@ -77,31 +190,23 @@ static int netdev_store ( struct settings *settings, struct setting *setting,
*
* @v settings Settings block
* @v setting Setting to fetch
- * @v data Setting data, or NULL to clear setting
- * @v len Length of setting data
- * @ret rc Return status code
+ * @v data Buffer to fill with setting data
+ * @v len Length of buffer
+ * @ret len Length of setting data, or negative error
*/
static int netdev_fetch ( struct settings *settings, struct setting *setting,
void *data, size_t len ) {
struct net_device *netdev = container_of ( settings, struct net_device,
settings.settings );
- struct device_description *desc = &netdev->dev->desc;
- struct dhcp_netdev_desc dhcp_desc;
+ struct netdev_setting_operation *op;
+ unsigned int i;
- if ( setting_cmp ( setting, &mac_setting ) == 0 ) {
- if ( len > netdev->ll_protocol->ll_addr_len )
- len = netdev->ll_protocol->ll_addr_len;
- memcpy ( data, netdev->ll_addr, len );
- return netdev->ll_protocol->ll_addr_len;
- }
- if ( setting_cmp ( setting, &busid_setting ) == 0 ) {
- dhcp_desc.type = desc->bus_type;
- dhcp_desc.vendor = htons ( desc->vendor );
- dhcp_desc.device = htons ( desc->device );
- if ( len > sizeof ( dhcp_desc ) )
- len = sizeof ( dhcp_desc );
- memcpy ( data, &dhcp_desc, len );
- return sizeof ( dhcp_desc );
+ /* Handle network device-specific settings */
+ for ( i = 0 ; i < ( sizeof ( netdev_setting_operations ) /
+ sizeof ( netdev_setting_operations[0] ) ) ; i++ ) {
+ op = &netdev_setting_operations[i];
+ if ( setting_cmp ( setting, op->setting ) == 0 )
+ return op->fetch ( netdev, data, len );
}
return generic_settings_fetch ( settings, setting, data, len );