mirror of https://github.com/ipxe/ipxe.git
[netdevice] Add "chip" setting
Suggested-by: Robin Smidsrød <robin@smidsrod.no> Signed-off-by: Michael Brown <mcb30@ipxe.org>pull/13/head
parent
dbea47ce7d
commit
08bf79582a
|
@ -45,6 +45,113 @@ struct setting busid_setting __setting ( SETTING_NETDEV ) = {
|
||||||
.description = "Bus ID",
|
.description = "Bus ID",
|
||||||
.type = &setting_type_hex,
|
.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
|
* 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 ) {
|
const void *data, size_t len ) {
|
||||||
struct net_device *netdev = container_of ( settings, struct net_device,
|
struct net_device *netdev = container_of ( settings, struct net_device,
|
||||||
settings.settings );
|
settings.settings );
|
||||||
|
struct netdev_setting_operation *op;
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
if ( setting_cmp ( setting, &mac_setting ) == 0 ) {
|
/* Handle network device-specific settings */
|
||||||
if ( len != netdev->ll_protocol->ll_addr_len )
|
for ( i = 0 ; i < ( sizeof ( netdev_setting_operations ) /
|
||||||
return -EINVAL;
|
sizeof ( netdev_setting_operations[0] ) ) ; i++ ) {
|
||||||
memcpy ( netdev->ll_addr, data, len );
|
op = &netdev_setting_operations[i];
|
||||||
return 0;
|
if ( setting_cmp ( setting, op->setting ) == 0 ) {
|
||||||
}
|
if ( op->store ) {
|
||||||
if ( setting_cmp ( setting, &busid_setting ) == 0 )
|
return op->store ( netdev, data, len );
|
||||||
|
} else {
|
||||||
return -ENOTSUP;
|
return -ENOTSUP;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return generic_settings_store ( settings, setting, data, len );
|
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 settings Settings block
|
||||||
* @v setting Setting to fetch
|
* @v setting Setting to fetch
|
||||||
* @v data Setting data, or NULL to clear setting
|
* @v data Buffer to fill with setting data
|
||||||
* @v len Length of setting data
|
* @v len Length of buffer
|
||||||
* @ret rc Return status code
|
* @ret len Length of setting data, or negative error
|
||||||
*/
|
*/
|
||||||
static int netdev_fetch ( struct settings *settings, struct setting *setting,
|
static int netdev_fetch ( struct settings *settings, struct setting *setting,
|
||||||
void *data, size_t len ) {
|
void *data, size_t len ) {
|
||||||
struct net_device *netdev = container_of ( settings, struct net_device,
|
struct net_device *netdev = container_of ( settings, struct net_device,
|
||||||
settings.settings );
|
settings.settings );
|
||||||
struct device_description *desc = &netdev->dev->desc;
|
struct netdev_setting_operation *op;
|
||||||
struct dhcp_netdev_desc dhcp_desc;
|
unsigned int i;
|
||||||
|
|
||||||
if ( setting_cmp ( setting, &mac_setting ) == 0 ) {
|
/* Handle network device-specific settings */
|
||||||
if ( len > netdev->ll_protocol->ll_addr_len )
|
for ( i = 0 ; i < ( sizeof ( netdev_setting_operations ) /
|
||||||
len = netdev->ll_protocol->ll_addr_len;
|
sizeof ( netdev_setting_operations[0] ) ) ; i++ ) {
|
||||||
memcpy ( data, netdev->ll_addr, len );
|
op = &netdev_setting_operations[i];
|
||||||
return netdev->ll_protocol->ll_addr_len;
|
if ( setting_cmp ( setting, op->setting ) == 0 )
|
||||||
}
|
return op->fetch ( netdev, data, 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 );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return generic_settings_fetch ( settings, setting, data, len );
|
return generic_settings_fetch ( settings, setting, data, len );
|
||||||
|
|
Loading…
Reference in New Issue