1 // SPDX-License-Identifier: GPL-2.0-only
6 * Copyright (C) 2005-2006 Intel Corporation
7 * Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com>
12 #include <linux/slab.h>
13 #include <linux/errno.h>
14 #include <linux/module.h>
15 #include <linux/device.h>
16 #include <linux/random.h>
17 #include <linux/etherdevice.h>
19 #include "uwb-internal.h"
22 /** Device Address Management command */
23 struct uwb_rc_cmd_dev_addr_mgmt
{
27 } __attribute__((packed
));
31 * Low level command for setting/getting UWB radio's addresses
33 * @hwarc: HWA Radio Control interface instance
35 * Set/get, MAC/DEV (see WUSB1.0[8.6.2.2])
36 * @baAddr: address buffer--assumed to have enough data to hold
37 * the address type requested.
38 * @reply: Pointer to reply buffer (can be stack allocated)
39 * @returns: 0 if ok, < 0 errno code on error.
41 * @cmd has to be allocated because USB cannot grok USB or vmalloc
42 * buffers depending on your combination of host architecture.
45 int uwb_rc_dev_addr_mgmt(struct uwb_rc
*rc
,
46 u8 bmOperationType
, const u8
*baAddr
,
47 struct uwb_rc_evt_dev_addr_mgmt
*reply
)
50 struct uwb_rc_cmd_dev_addr_mgmt
*cmd
;
53 cmd
= kzalloc(sizeof(*cmd
), GFP_KERNEL
);
56 cmd
->rccb
.bCommandType
= UWB_RC_CET_GENERAL
;
57 cmd
->rccb
.wCommand
= cpu_to_le16(UWB_RC_CMD_DEV_ADDR_MGMT
);
58 cmd
->bmOperationType
= bmOperationType
;
61 switch (bmOperationType
>> 1) {
62 case 0: size
= 2; break;
63 case 1: size
= 6; break;
66 memcpy(cmd
->baAddr
, baAddr
, size
);
68 reply
->rceb
.bEventType
= UWB_RC_CET_GENERAL
;
69 reply
->rceb
.wEvent
= UWB_RC_CMD_DEV_ADDR_MGMT
;
70 result
= uwb_rc_cmd(rc
, "DEV-ADDR-MGMT",
71 &cmd
->rccb
, sizeof(*cmd
),
72 &reply
->rceb
, sizeof(*reply
));
75 if (result
< sizeof(*reply
)) {
76 dev_err(&rc
->uwb_dev
.dev
,
77 "DEV-ADDR-MGMT: not enough data replied: "
78 "%d vs %zu bytes needed\n", result
, sizeof(*reply
));
80 } else if (reply
->bResultCode
!= UWB_RC_RES_SUCCESS
) {
81 dev_err(&rc
->uwb_dev
.dev
,
82 "DEV-ADDR-MGMT: command execution failed: %s (%d)\n",
83 uwb_rc_strerror(reply
->bResultCode
),
96 * Set the UWB RC MAC or device address.
98 * @rc: UWB Radio Controller
99 * @_addr: Pointer to address to write [assumed to be either a
100 * 'struct uwb_mac_addr *' or a 'struct uwb_dev_addr *'].
101 * @type: Type of address to set (UWB_ADDR_DEV or UWB_ADDR_MAC).
102 * @returns: 0 if ok, < 0 errno code on error.
104 * Some anal retentivity here: even if both 'struct
105 * uwb_{dev,mac}_addr' have the actual byte array in the same offset
106 * and I could just pass _addr to hwarc_cmd_dev_addr_mgmt(), I prefer
107 * to use some syntatic sugar in case someday we decide to change the
108 * format of the structs. The compiler will optimize it out anyway.
110 static int uwb_rc_addr_set(struct uwb_rc
*rc
,
111 const void *_addr
, enum uwb_addr_type type
)
114 u8 bmOperationType
= 0x1; /* Set address */
115 const struct uwb_dev_addr
*dev_addr
= _addr
;
116 const struct uwb_mac_addr
*mac_addr
= _addr
;
117 struct uwb_rc_evt_dev_addr_mgmt reply
;
123 baAddr
= dev_addr
->data
;
126 baAddr
= mac_addr
->data
;
127 bmOperationType
|= 0x2;
132 return uwb_rc_dev_addr_mgmt(rc
, bmOperationType
, baAddr
, &reply
);
137 * Get the UWB radio's MAC or device address.
139 * @rc: UWB Radio Controller
140 * @_addr: Where to write the address data [assumed to be either a
141 * 'struct uwb_mac_addr *' or a 'struct uwb_dev_addr *'].
142 * @type: Type of address to get (UWB_ADDR_DEV or UWB_ADDR_MAC).
143 * @returns: 0 if ok (and *_addr set), < 0 errno code on error.
145 * See comment in uwb_rc_addr_set() about anal retentivity in the
146 * type handling of the address variables.
148 static int uwb_rc_addr_get(struct uwb_rc
*rc
,
149 void *_addr
, enum uwb_addr_type type
)
152 u8 bmOperationType
= 0x0; /* Get address */
153 struct uwb_rc_evt_dev_addr_mgmt evt
;
154 struct uwb_dev_addr
*dev_addr
= _addr
;
155 struct uwb_mac_addr
*mac_addr
= _addr
;
161 baAddr
= dev_addr
->data
;
164 bmOperationType
|= 0x2;
165 baAddr
= mac_addr
->data
;
170 result
= uwb_rc_dev_addr_mgmt(rc
, bmOperationType
, baAddr
, &evt
);
174 memcpy(&dev_addr
->data
, evt
.baAddr
,
175 sizeof(dev_addr
->data
));
178 memcpy(&mac_addr
->data
, evt
.baAddr
,
179 sizeof(mac_addr
->data
));
181 default: /* shut gcc up */
188 /** Get @rc's MAC address to @addr */
189 int uwb_rc_mac_addr_get(struct uwb_rc
*rc
,
190 struct uwb_mac_addr
*addr
) {
191 return uwb_rc_addr_get(rc
, addr
, UWB_ADDR_MAC
);
193 EXPORT_SYMBOL_GPL(uwb_rc_mac_addr_get
);
196 /** Get @rc's device address to @addr */
197 int uwb_rc_dev_addr_get(struct uwb_rc
*rc
,
198 struct uwb_dev_addr
*addr
) {
199 return uwb_rc_addr_get(rc
, addr
, UWB_ADDR_DEV
);
201 EXPORT_SYMBOL_GPL(uwb_rc_dev_addr_get
);
204 /** Set @rc's address to @addr */
205 int uwb_rc_mac_addr_set(struct uwb_rc
*rc
,
206 const struct uwb_mac_addr
*addr
)
208 int result
= -EINVAL
;
209 mutex_lock(&rc
->uwb_dev
.mutex
);
210 result
= uwb_rc_addr_set(rc
, addr
, UWB_ADDR_MAC
);
211 mutex_unlock(&rc
->uwb_dev
.mutex
);
216 /** Set @rc's address to @addr */
217 int uwb_rc_dev_addr_set(struct uwb_rc
*rc
,
218 const struct uwb_dev_addr
*addr
)
220 int result
= -EINVAL
;
221 mutex_lock(&rc
->uwb_dev
.mutex
);
222 result
= uwb_rc_addr_set(rc
, addr
, UWB_ADDR_DEV
);
223 rc
->uwb_dev
.dev_addr
= *addr
;
224 mutex_unlock(&rc
->uwb_dev
.mutex
);
228 /* Returns !0 if given address is already assigned to device. */
229 int __uwb_mac_addr_assigned_check(struct device
*dev
, void *_addr
)
231 struct uwb_dev
*uwb_dev
= to_uwb_dev(dev
);
232 struct uwb_mac_addr
*addr
= _addr
;
234 if (!uwb_mac_addr_cmp(addr
, &uwb_dev
->mac_addr
))
239 /* Returns !0 if given address is already assigned to device. */
240 int __uwb_dev_addr_assigned_check(struct device
*dev
, void *_addr
)
242 struct uwb_dev
*uwb_dev
= to_uwb_dev(dev
);
243 struct uwb_dev_addr
*addr
= _addr
;
244 if (!uwb_dev_addr_cmp(addr
, &uwb_dev
->dev_addr
))
250 * uwb_dev_addr_assign - assigned a generated DevAddr to a radio controller
251 * @rc: the (local) radio controller device requiring a new DevAddr
253 * A new DevAddr is required when:
254 * - first setting up a radio controller
255 * - if the hardware reports a DevAddr conflict
257 * The DevAddr is randomly generated in the generated DevAddr range
258 * [0x100, 0xfeff]. The number of devices in a beacon group is limited
259 * by mMaxBPLength (96) so this address space will never be exhausted.
261 * [ECMA-368] 17.1.1, 17.16.
263 int uwb_rc_dev_addr_assign(struct uwb_rc
*rc
)
265 struct uwb_dev_addr new_addr
;
268 get_random_bytes(new_addr
.data
, sizeof(new_addr
.data
));
269 } while (new_addr
.data
[0] == 0x00 || new_addr
.data
[0] == 0xff
270 || __uwb_dev_addr_assigned(rc
, &new_addr
));
272 return uwb_rc_dev_addr_set(rc
, &new_addr
);
276 * uwbd_evt_handle_rc_dev_addr_conflict - handle a DEV_ADDR_CONFLICT event
277 * @evt: the DEV_ADDR_CONFLICT notification from the radio controller
279 * A new (non-conflicting) DevAddr is assigned to the radio controller.
281 * [ECMA-368] 17.1.1.1.
283 int uwbd_evt_handle_rc_dev_addr_conflict(struct uwb_event
*evt
)
285 struct uwb_rc
*rc
= evt
->rc
;
287 return uwb_rc_dev_addr_assign(rc
);
291 * Print the 48-bit EUI MAC address of the radio controller when
292 * reading /sys/class/uwb_rc/XX/mac_address
294 static ssize_t
uwb_rc_mac_addr_show(struct device
*dev
,
295 struct device_attribute
*attr
, char *buf
)
297 struct uwb_dev
*uwb_dev
= to_uwb_dev(dev
);
298 struct uwb_rc
*rc
= uwb_dev
->rc
;
299 struct uwb_mac_addr addr
;
302 mutex_lock(&rc
->uwb_dev
.mutex
);
303 result
= uwb_rc_addr_get(rc
, &addr
, UWB_ADDR_MAC
);
304 mutex_unlock(&rc
->uwb_dev
.mutex
);
306 result
= uwb_mac_addr_print(buf
, UWB_ADDR_STRSIZE
, &addr
);
307 buf
[result
++] = '\n';
313 * Parse a 48 bit address written to /sys/class/uwb_rc/XX/mac_address
314 * and if correct, set it.
316 static ssize_t
uwb_rc_mac_addr_store(struct device
*dev
,
317 struct device_attribute
*attr
,
318 const char *buf
, size_t size
)
320 struct uwb_dev
*uwb_dev
= to_uwb_dev(dev
);
321 struct uwb_rc
*rc
= uwb_dev
->rc
;
322 struct uwb_mac_addr addr
;
325 if (!mac_pton(buf
, addr
.data
))
327 if (is_multicast_ether_addr(addr
.data
)) {
328 dev_err(&rc
->uwb_dev
.dev
, "refusing to set multicast "
329 "MAC address %s\n", buf
);
332 result
= uwb_rc_mac_addr_set(rc
, &addr
);
334 rc
->uwb_dev
.mac_addr
= addr
;
336 return result
< 0 ? result
: size
;
338 DEVICE_ATTR(mac_address
, S_IRUGO
| S_IWUSR
, uwb_rc_mac_addr_show
, uwb_rc_mac_addr_store
);
340 /** Print @addr to @buf, @return bytes written */
341 size_t __uwb_addr_print(char *buf
, size_t buf_size
, const unsigned char *addr
,
346 result
= scnprintf(buf
, buf_size
, "%pM", addr
);
348 result
= scnprintf(buf
, buf_size
, "%02x:%02x",
352 EXPORT_SYMBOL_GPL(__uwb_addr_print
);