1 /* 2 * Copyright (C) 2008 Michael Brown <mbrown (at) fensystems.co.uk>. 3 * 4 * This program is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU General Public License as 6 * published by the Free Software Foundation; either version 2 of the 7 * License, or any later version. 8 * 9 * This program is distributed in the hope that it will be useful, but 10 * WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 * General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with this program; if not, write to the Free Software 16 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 17 */ 18 19 FILE_LICENCE ( GPL2_OR_LATER ); 20 21 #include <string.h> 22 #include <errno.h> 23 #include <byteswap.h> 24 #include <gpxe/dhcp.h> 25 #include <gpxe/settings.h> 26 #include <gpxe/device.h> 27 #include <gpxe/netdevice.h> 28 29 /** @file 30 * 31 * Network device configuration settings 32 * 33 */ 34 35 /** Network device named settings */ 36 struct setting mac_setting __setting = { 37 .name = "mac", 38 .description = "MAC address", 39 .type = &setting_type_hex, 40 }; 41 struct setting busid_setting __setting = { 42 .name = "busid", 43 .description = "Bus ID", 44 .type = &setting_type_hex, 45 }; 46 47 /** 48 * Store value of network device setting 49 * 50 * @v settings Settings block 51 * @v setting Setting to store 52 * @v data Setting data, or NULL to clear setting 53 * @v len Length of setting data 54 * @ret rc Return status code 55 */ 56 static int netdev_store ( struct settings *settings, struct setting *setting, 57 const void *data, size_t len ) { 58 struct net_device *netdev = container_of ( settings, struct net_device, 59 settings.settings ); 60 61 if ( setting_cmp ( setting, &mac_setting ) == 0 ) { 62 if ( len != netdev->ll_protocol->ll_addr_len ) 63 return -EINVAL; 64 memcpy ( netdev->ll_addr, data, len ); 65 return 0; 66 } 67 68 return generic_settings_store ( settings, setting, data, len ); 69 } 70 71 /** 72 * Fetch value of network device setting 73 * 74 * @v settings Settings block 75 * @v setting Setting to fetch 76 * @v data Setting data, or NULL to clear setting 77 * @v len Length of setting data 78 * @ret rc Return status code 79 */ 80 static int netdev_fetch ( struct settings *settings, struct setting *setting, 81 void *data, size_t len ) { 82 struct net_device *netdev = container_of ( settings, struct net_device, 83 settings.settings ); 84 struct device_description *desc = &netdev->dev->desc; 85 struct dhcp_netdev_desc dhcp_desc; 86 87 if ( setting_cmp ( setting, &mac_setting ) == 0 ) { 88 if ( len > netdev->ll_protocol->ll_addr_len ) 89 len = netdev->ll_protocol->ll_addr_len; 90 memcpy ( data, netdev->ll_addr, len ); 91 return netdev->ll_protocol->ll_addr_len; 92 } 93 if ( setting_cmp ( setting, &busid_setting ) == 0 ) { 94 dhcp_desc.type = desc->bus_type; 95 dhcp_desc.vendor = htons ( desc->vendor ); 96 dhcp_desc.device = htons ( desc->device ); 97 if ( len > sizeof ( dhcp_desc ) ) 98 len = sizeof ( dhcp_desc ); 99 memcpy ( data, &dhcp_desc, len ); 100 return sizeof ( dhcp_desc ); 101 } 102 103 return generic_settings_fetch ( settings, setting, data, len ); 104 } 105 106 /** 107 * Clear network device settings 108 * 109 * @v settings Settings block 110 */ 111 static void netdev_clear ( struct settings *settings ) { 112 generic_settings_clear ( settings ); 113 } 114 115 /** Network device configuration settings operations */ 116 struct settings_operations netdev_settings_operations = { 117 .store = netdev_store, 118 .fetch = netdev_fetch, 119 .clear = netdev_clear, 120 }; 121