platform/x86: thinkpad_acpi: sysfs interface to auxmac
Newer Thinkpads have a feature called MAC Address Pass-through. This patch provides a sysfs interface that userspace can use to get this auxiliary mac address. Signed-off-by: Fernando Eckhardt Valle <fevalle@ipt.br> Reviewed-by: Hans de Goede <hdegoede@redhat.com> Link: https://lore.kernel.org/r/20230926202144.5906-1-fevalle@ipt.br Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com> Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
This commit is contained in:
parent
9cf63f3a33
commit
18801efed7
@ -53,6 +53,7 @@ detailed description):
|
||||
- Lap mode sensor
|
||||
- Setting keyboard language
|
||||
- WWAN Antenna type
|
||||
- Auxmac
|
||||
|
||||
A compatibility table by model and feature is maintained on the web
|
||||
site, http://ibm-acpi.sf.net/. I appreciate any success or failure
|
||||
@ -1511,6 +1512,25 @@ Currently 2 antenna types are supported as mentioned below:
|
||||
The property is read-only. If the platform doesn't have support the sysfs
|
||||
class is not created.
|
||||
|
||||
Auxmac
|
||||
------
|
||||
|
||||
sysfs: auxmac
|
||||
|
||||
Some newer Thinkpads have a feature called MAC Address Pass-through. This
|
||||
feature is implemented by the system firmware to provide a system unique MAC,
|
||||
that can override a dock or USB ethernet dongle MAC, when connected to a
|
||||
network. This property enables user-space to easily determine the MAC address
|
||||
if the feature is enabled.
|
||||
|
||||
The values of this auxiliary MAC are:
|
||||
|
||||
cat /sys/devices/platform/thinkpad_acpi/auxmac
|
||||
|
||||
If the feature is disabled, the value will be 'disabled'.
|
||||
|
||||
This property is read-only.
|
||||
|
||||
Adaptive keyboard
|
||||
-----------------
|
||||
|
||||
|
@ -10785,6 +10785,89 @@ static struct ibm_struct dprc_driver_data = {
|
||||
.name = "dprc",
|
||||
};
|
||||
|
||||
/*
|
||||
* Auxmac
|
||||
*
|
||||
* This auxiliary mac address is enabled in the bios through the
|
||||
* MAC Address Pass-through feature. In most cases, there are three
|
||||
* possibilities: Internal Mac, Second Mac, and disabled.
|
||||
*
|
||||
*/
|
||||
|
||||
#define AUXMAC_LEN 12
|
||||
#define AUXMAC_START 9
|
||||
#define AUXMAC_STRLEN 22
|
||||
#define AUXMAC_BEGIN_MARKER 8
|
||||
#define AUXMAC_END_MARKER 21
|
||||
|
||||
static char auxmac[AUXMAC_LEN + 1];
|
||||
|
||||
static int auxmac_init(struct ibm_init_struct *iibm)
|
||||
{
|
||||
acpi_status status;
|
||||
struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
|
||||
union acpi_object *obj;
|
||||
|
||||
status = acpi_evaluate_object(NULL, "\\MACA", NULL, &buffer);
|
||||
|
||||
if (ACPI_FAILURE(status))
|
||||
return -ENODEV;
|
||||
|
||||
obj = buffer.pointer;
|
||||
|
||||
if (obj->type != ACPI_TYPE_STRING || obj->string.length != AUXMAC_STRLEN) {
|
||||
pr_info("Invalid buffer for MAC address pass-through.\n");
|
||||
goto auxmacinvalid;
|
||||
}
|
||||
|
||||
if (obj->string.pointer[AUXMAC_BEGIN_MARKER] != '#' ||
|
||||
obj->string.pointer[AUXMAC_END_MARKER] != '#') {
|
||||
pr_info("Invalid header for MAC address pass-through.\n");
|
||||
goto auxmacinvalid;
|
||||
}
|
||||
|
||||
if (strncmp(obj->string.pointer + AUXMAC_START, "XXXXXXXXXXXX", AUXMAC_LEN) != 0)
|
||||
strscpy(auxmac, obj->string.pointer + AUXMAC_START, sizeof(auxmac));
|
||||
else
|
||||
strscpy(auxmac, "disabled", sizeof(auxmac));
|
||||
|
||||
free:
|
||||
kfree(obj);
|
||||
return 0;
|
||||
|
||||
auxmacinvalid:
|
||||
strscpy(auxmac, "unavailable", sizeof(auxmac));
|
||||
goto free;
|
||||
}
|
||||
|
||||
static struct ibm_struct auxmac_data = {
|
||||
.name = "auxmac",
|
||||
};
|
||||
|
||||
static ssize_t auxmac_show(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
return sysfs_emit(buf, "%s\n", auxmac);
|
||||
}
|
||||
static DEVICE_ATTR_RO(auxmac);
|
||||
|
||||
static umode_t auxmac_attr_is_visible(struct kobject *kobj,
|
||||
struct attribute *attr, int n)
|
||||
{
|
||||
return auxmac[0] == 0 ? 0 : attr->mode;
|
||||
}
|
||||
|
||||
static struct attribute *auxmac_attributes[] = {
|
||||
&dev_attr_auxmac.attr,
|
||||
NULL
|
||||
};
|
||||
|
||||
static const struct attribute_group auxmac_attr_group = {
|
||||
.is_visible = auxmac_attr_is_visible,
|
||||
.attrs = auxmac_attributes,
|
||||
};
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
static struct attribute *tpacpi_driver_attributes[] = {
|
||||
@ -10843,6 +10926,7 @@ static const struct attribute_group *tpacpi_groups[] = {
|
||||
&proxsensor_attr_group,
|
||||
&kbdlang_attr_group,
|
||||
&dprc_attr_group,
|
||||
&auxmac_attr_group,
|
||||
NULL,
|
||||
};
|
||||
|
||||
@ -11414,6 +11498,10 @@ static struct ibm_init_struct ibms_init[] __initdata = {
|
||||
.init = tpacpi_dprc_init,
|
||||
.data = &dprc_driver_data,
|
||||
},
|
||||
{
|
||||
.init = auxmac_init,
|
||||
.data = &auxmac_data,
|
||||
},
|
||||
};
|
||||
|
||||
static int __init set_ibm_param(const char *val, const struct kernel_param *kp)
|
||||
|
Loading…
x
Reference in New Issue
Block a user