mirror of
https://github.com/torvalds/linux.git
synced 2026-07-27 17:47:41 +02:00
wifi: rtw89: usb: add serial_number and uuid sysfs attributes for 0x28de:0x2432
Expose the device's Serial Number (SN) and UUID from EFUSE via two read-only sysfs attributes, `serial_number` and `uuid`, on the ieee80211 phy device under the `rtw89_usb` attribute group. This hardware identification information is essential for user-space applications to uniquely identify, track, and manage specific Wi-Fi adapters. For example, in automated factory provisioning or device management systems, user-space tools rely on the EFUSE serial number and UUID to bind configurations to specific physical adapters. Currently, standard wireless APIs do not expose this low-level hardware information, making these sysfs nodes the only viable solution for user space to extract this data. The attributes are gated behind a new RTW89_QUIRK_HW_INFO_SYSFS quirk, enabled only for the VID 0x28de / PID 0x2432 device via the dev_id_quirks field in rtw89_driver_info. Example usage from user-space: $ cat /sys/class/ieee80211/phy0/rtw89_usb/serial_number 3642000123 $ cat /sys/class/ieee80211/phy0/rtw89_usb/uuid aaec2b7c-0a55-4727-8de0-b30febccbbaa Cc: Elliot Saba <sabae@valvesoftware.com> Cc: Charles Lohr <charlesl@valvesoftware.com> Signed-off-by: Johnson Tsai <wenjie.tsai@realtek.com> Signed-off-by: Ping-Ke Shih <pkshih@realtek.com> Link: https://patch.msgid.link/20260529075032.16807-3-pkshih@realtek.com
This commit is contained in:
parent
7554f6602a
commit
384cc80f30
24
Documentation/ABI/testing/sysfs-class-ieee80211-rtw89
Normal file
24
Documentation/ABI/testing/sysfs-class-ieee80211-rtw89
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
What: /sys/class/ieee80211/phyX/rtw89_usb/serial_number
|
||||
Date: May 2026
|
||||
Contact: Johnson Tsai <wenjie.tsai@realtek.com>, linux-wireless@vger.kernel.org
|
||||
Description: (Read) Serial number burned into EFUSE of the RTL8852CU-based
|
||||
USB Wi-Fi adapter. Only present on devices that set the
|
||||
RTW89_QUIRK_HW_INFO_SYSFS quirk (currently VID 0x28de /
|
||||
PID 0x2432).
|
||||
|
||||
Format: %10phN (5 raw bytes printed as 10 lowercase hex
|
||||
digits, no separators).
|
||||
|
||||
Example: 3642000123
|
||||
|
||||
What: /sys/class/ieee80211/phyX/rtw89_usb/uuid
|
||||
Date: May 2026
|
||||
Contact: Johnson Tsai <wenjie.tsai@realtek.com>, linux-wireless@vger.kernel.org
|
||||
Description: (Read) UUID burned into EFUSE of the RTL8852CU-based USB Wi-Fi
|
||||
adapter. Only present on devices that set the
|
||||
RTW89_QUIRK_HW_INFO_SYSFS quirk (currently VID 0x28de /
|
||||
PID 0x2432).
|
||||
|
||||
Format: %pUb (RFC 4122 UUID in lowercase with hyphens).
|
||||
|
||||
Example: aaec2b7c-0a55-4727-8de0-b30febccbbaa
|
||||
|
|
@ -3618,6 +3618,9 @@ struct rtw89_sta_link {
|
|||
u32 data_tx_cnt_lmt:6;
|
||||
};
|
||||
|
||||
#define RTW89_EFUSE_SN_LEN 5
|
||||
#define RTW89_EFUSE_UUID_LEN 16
|
||||
|
||||
struct rtw89_efuse {
|
||||
bool valid;
|
||||
bool power_k_valid;
|
||||
|
|
@ -3628,6 +3631,8 @@ struct rtw89_efuse {
|
|||
u8 adc_td;
|
||||
u8 bt_setting_2;
|
||||
u8 bt_setting_3;
|
||||
u8 sn[RTW89_EFUSE_SN_LEN];
|
||||
u8 uuid[RTW89_EFUSE_UUID_LEN];
|
||||
};
|
||||
|
||||
struct rtw89_phy_rate_pattern {
|
||||
|
|
@ -5376,6 +5381,7 @@ enum rtw89_quirks {
|
|||
RTW89_QUIRK_PCI_BER,
|
||||
RTW89_QUIRK_THERMAL_PROT_120C,
|
||||
RTW89_QUIRK_THERMAL_PROT_110C,
|
||||
RTW89_QUIRK_HW_INFO_SYSFS,
|
||||
|
||||
NUM_OF_RTW89_QUIRKS,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -621,6 +621,15 @@ static void rtw8852c_efuse_parsing_gain_offset(struct rtw89_dev *rtwdev,
|
|||
gain->offset_valid = valid;
|
||||
}
|
||||
|
||||
static void rtw8852c_efuse_copy_sn_uuid_usb(struct rtw89_dev *rtwdev,
|
||||
const struct rtw8852c_efuse *map)
|
||||
{
|
||||
struct rtw89_efuse *efuse = &rtwdev->efuse;
|
||||
|
||||
memcpy(efuse->sn, map->u.sn, sizeof(efuse->sn));
|
||||
memcpy(efuse->uuid, map->u.uuid, sizeof(efuse->uuid));
|
||||
}
|
||||
|
||||
static int rtw8852c_read_efuse(struct rtw89_dev *rtwdev, u8 *log_map,
|
||||
enum rtw89_efuse_block block)
|
||||
{
|
||||
|
|
@ -640,6 +649,7 @@ static int rtw8852c_read_efuse(struct rtw89_dev *rtwdev, u8 *log_map,
|
|||
break;
|
||||
case RTW89_HCI_TYPE_USB:
|
||||
ether_addr_copy(efuse->addr, map->u.mac_addr);
|
||||
rtw8852c_efuse_copy_sn_uuid_usb(rtwdev, map);
|
||||
break;
|
||||
default:
|
||||
return -ENOTSUPP;
|
||||
|
|
|
|||
|
|
@ -13,7 +13,11 @@
|
|||
struct rtw8852c_u_efuse {
|
||||
u8 rsvd[0x88];
|
||||
u8 mac_addr[ETH_ALEN];
|
||||
};
|
||||
u8 rsvd1[8];
|
||||
u8 sn[RTW89_EFUSE_SN_LEN];
|
||||
u8 rsvd2[29];
|
||||
u8 uuid[RTW89_EFUSE_UUID_LEN];
|
||||
} __packed;
|
||||
|
||||
struct rtw8852c_e_efuse {
|
||||
u8 mac_addr[ETH_ALEN];
|
||||
|
|
|
|||
|
|
@ -39,6 +39,16 @@ static const struct rtw89_driver_info rtw89_8852cu_info = {
|
|||
},
|
||||
};
|
||||
|
||||
static const struct rtw89_driver_info rtw89_8852cu_valve_info = {
|
||||
.chip = &rtw8852c_chip_info,
|
||||
.variant = NULL,
|
||||
.quirks = NULL,
|
||||
.dev_id_quirks = BIT(RTW89_QUIRK_HW_INFO_SYSFS),
|
||||
.bus = {
|
||||
.usb = &rtw8852c_usb_info,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct usb_device_id rtw_8852cu_id_table[] = {
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x0411, 0x03a6, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t)&rtw89_8852cu_info },
|
||||
|
|
@ -53,7 +63,7 @@ static const struct usb_device_id rtw_8852cu_id_table[] = {
|
|||
{ USB_DEVICE_AND_INTERFACE_INFO(0x0db0, 0x991d, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t)&rtw89_8852cu_info },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x28de, 0x2432, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t)&rtw89_8852cu_info },
|
||||
.driver_info = (kernel_ulong_t)&rtw89_8852cu_valve_info },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x2c7c, 0x8206, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t)&rtw89_8852cu_info },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x35b2, 0x0502, 0xff, 0xff, 0xff),
|
||||
|
|
|
|||
|
|
@ -1150,6 +1150,56 @@ static int rtw89_usb_switch_mode(struct rtw89_dev *rtwdev)
|
|||
return rtw89_usb_switch_mode_be(rtwdev);
|
||||
}
|
||||
|
||||
static ssize_t serial_number_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct wiphy *wiphy = container_of(dev, struct wiphy, dev);
|
||||
struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
|
||||
struct rtw89_dev *rtwdev = hw->priv;
|
||||
struct rtw89_efuse *efuse = &rtwdev->efuse;
|
||||
|
||||
return sysfs_emit(buf, "%*phN\n",
|
||||
(int)sizeof(efuse->sn), efuse->sn);
|
||||
}
|
||||
static DEVICE_ATTR_RO(serial_number);
|
||||
|
||||
static ssize_t uuid_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct wiphy *wiphy = container_of(dev, struct wiphy, dev);
|
||||
struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
|
||||
struct rtw89_dev *rtwdev = hw->priv;
|
||||
struct rtw89_efuse *efuse = &rtwdev->efuse;
|
||||
|
||||
return sysfs_emit(buf, "%pUb\n", efuse->uuid);
|
||||
}
|
||||
static DEVICE_ATTR_RO(uuid);
|
||||
|
||||
static struct attribute *rtw89_usb_attrs[] = {
|
||||
&dev_attr_serial_number.attr,
|
||||
&dev_attr_uuid.attr,
|
||||
NULL,
|
||||
};
|
||||
|
||||
static bool rtw89_usb_group_visible(struct kobject *kobj)
|
||||
{
|
||||
struct device *dev = kobj_to_dev(kobj);
|
||||
struct wiphy *wiphy = container_of(dev, struct wiphy, dev);
|
||||
struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
|
||||
struct rtw89_dev *rtwdev = hw->priv;
|
||||
|
||||
return test_bit(RTW89_QUIRK_HW_INFO_SYSFS, rtwdev->quirks);
|
||||
}
|
||||
|
||||
DEFINE_SIMPLE_SYSFS_GROUP_VISIBLE(rtw89_usb);
|
||||
|
||||
static const struct attribute_group rtw89_usb_group = {
|
||||
.name = "rtw89_usb",
|
||||
.attrs = rtw89_usb_attrs,
|
||||
.is_visible = SYSFS_GROUP_VISIBLE(rtw89_usb),
|
||||
};
|
||||
__ATTRIBUTE_GROUPS(rtw89_usb);
|
||||
|
||||
int rtw89_usb_probe(struct usb_interface *intf,
|
||||
const struct usb_device_id *id)
|
||||
{
|
||||
|
|
@ -1171,6 +1221,8 @@ int rtw89_usb_probe(struct usb_interface *intf,
|
|||
rtwusb->rtwdev = rtwdev;
|
||||
rtwusb->info = info->bus.usb;
|
||||
|
||||
rtwdev->hw->wiphy->dev.groups = rtw89_usb_groups;
|
||||
|
||||
rtwdev->hci.ops = &rtw89_usb_ops;
|
||||
rtwdev->hci.type = RTW89_HCI_TYPE_USB;
|
||||
rtwdev->hci.tx_rpt_enabled = true;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user