]> git.ipfire.org Git - thirdparty/ipxe.git/commitdiff
[netdevice] Add "chip" setting
authorMichael Brown <mcb30@ipxe.org>
Thu, 16 May 2013 14:32:17 +0000 (15:32 +0100)
committerMichael Brown <mcb30@ipxe.org>
Thu, 16 May 2013 14:32:17 +0000 (15:32 +0100)
Suggested-by: Robin Smidsrød <robin@smidsrod.no>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
src/net/netdev_settings.c

index 8758e9800cb958aa214b5e79016e9eef1ec8cbfa..8f66c5538d42dcf95e70a841c53b84a55cd6641a 100644 (file)
@@ -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 );