5 * Copyright (C) 2005-2006 Intel Corporation
6 * Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com>
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License version
10 * 2 as published by the Free Software Foundation.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
26 #include <linux/errno.h>
27 #include <linux/module.h>
28 #include <linux/device.h>
29 #include <linux/random.h>
30 #include <linux/etherdevice.h>
32 #include "uwb-internal.h"
35 /** Device Address Management command */
36 struct uwb_rc_cmd_dev_addr_mgmt
{
40 } __attribute__((packed
));
44 * Low level command for setting/getting UWB radio's addresses
46 * @hwarc: HWA Radio Control interface instance
48 * Set/get, MAC/DEV (see WUSB1.0[8.6.2.2])
49 * @baAddr: address buffer--assumed to have enough data to hold
50 * the address type requested.
51 * @reply: Pointer to reply buffer (can be stack allocated)
52 * @returns: 0 if ok, < 0 errno code on error.
54 * @cmd has to be allocated because USB cannot grok USB or vmalloc
55 * buffers depending on your combination of host architecture.
58 int uwb_rc_dev_addr_mgmt(struct uwb_rc
*rc
,
59 u8 bmOperationType
, const u8
*baAddr
,
60 struct uwb_rc_evt_dev_addr_mgmt
*reply
)
63 struct uwb_rc_cmd_dev_addr_mgmt
*cmd
;
66 cmd
= kzalloc(sizeof(*cmd
), GFP_KERNEL
);
69 cmd
->rccb
.bCommandType
= UWB_RC_CET_GENERAL
;
70 cmd
->rccb
.wCommand
= cpu_to_le16(UWB_RC_CMD_DEV_ADDR_MGMT
);
71 cmd
->bmOperationType
= bmOperationType
;
74 switch (bmOperationType
>> 1) {
75 case 0: size
= 2; break;
76 case 1: size
= 6; break;
79 memcpy(cmd
->baAddr
, baAddr
, size
);
81 reply
->rceb
.bEventType
= UWB_RC_CET_GENERAL
;
82 reply
->rceb
.wEvent
= UWB_RC_CMD_DEV_ADDR_MGMT
;
83 result
= uwb_rc_cmd(rc
, "DEV-ADDR-MGMT",
84 &cmd
->rccb
, sizeof(*cmd
),
85 &reply
->rceb
, sizeof(*reply
));
88 if (result
< sizeof(*reply
)) {
89 dev_err(&rc
->uwb_dev
.dev
,
90 "DEV-ADDR-MGMT: not enough data replied: "
91 "%d vs %zu bytes needed\n", result
, sizeof(*reply
));
93 } else if (reply
->bResultCode
!= UWB_RC_RES_SUCCESS
) {
94 dev_err(&rc
->uwb_dev
.dev
,
95 "DEV-ADDR-MGMT: command execution failed: %s (%d)\n",
96 uwb_rc_strerror(reply
->bResultCode
),
109 * Set the UWB RC MAC or device address.
111 * @rc: UWB Radio Controller
112 * @_addr: Pointer to address to write [assumed to be either a
113 * 'struct uwb_mac_addr *' or a 'struct uwb_dev_addr *'].
114 * @type: Type of address to set (UWB_ADDR_DEV or UWB_ADDR_MAC).
115 * @returns: 0 if ok, < 0 errno code on error.
117 * Some anal retentivity here: even if both 'struct
118 * uwb_{dev,mac}_addr' have the actual byte array in the same offset
119 * and I could just pass _addr to hwarc_cmd_dev_addr_mgmt(), I prefer
120 * to use some syntatic sugar in case someday we decide to change the
121 * format of the structs. The compiler will optimize it out anyway.
123 static int uwb_rc_addr_set(struct uwb_rc
*rc
,
124 const void *_addr
, enum uwb_addr_type type
)
127 u8 bmOperationType
= 0x1; /* Set address */
128 const struct uwb_dev_addr
*dev_addr
= _addr
;
129 const struct uwb_mac_addr
*mac_addr
= _addr
;
130 struct uwb_rc_evt_dev_addr_mgmt reply
;
136 baAddr
= dev_addr
->data
;
139 baAddr
= mac_addr
->data
;
140 bmOperationType
|= 0x2;
145 return uwb_rc_dev_addr_mgmt(rc
, bmOperationType
, baAddr
, &reply
);
150 * Get the UWB radio's MAC or device address.
152 * @rc: UWB Radio Controller
153 * @_addr: Where to write the address data [assumed to be either a
154 * 'struct uwb_mac_addr *' or a 'struct uwb_dev_addr *'].
155 * @type: Type of address to get (UWB_ADDR_DEV or UWB_ADDR_MAC).
156 * @returns: 0 if ok (and *_addr set), < 0 errno code on error.
158 * See comment in uwb_rc_addr_set() about anal retentivity in the
159 * type handling of the address variables.
161 static int uwb_rc_addr_get(struct uwb_rc
*rc
,
162 void *_addr
, enum uwb_addr_type type
)
165 u8 bmOperationType
= 0x0; /* Get address */
166 struct uwb_rc_evt_dev_addr_mgmt evt
;
167 struct uwb_dev_addr
*dev_addr
= _addr
;
168 struct uwb_mac_addr
*mac_addr
= _addr
;
174 baAddr
= dev_addr
->data
;
177 bmOperationType
|= 0x2;
178 baAddr
= mac_addr
->data
;
183 result
= uwb_rc_dev_addr_mgmt(rc
, bmOperationType
, baAddr
, &evt
);
187 memcpy(&dev_addr
->data
, evt
.baAddr
,
188 sizeof(dev_addr
->data
));
191 memcpy(&mac_addr
->data
, evt
.baAddr
,
192 sizeof(mac_addr
->data
));
194 default: /* shut gcc up */
201 /** Get @rc's MAC address to @addr */
202 int uwb_rc_mac_addr_get(struct uwb_rc
*rc
,
203 struct uwb_mac_addr
*addr
) {
204 return uwb_rc_addr_get(rc
, addr
, UWB_ADDR_MAC
);
206 EXPORT_SYMBOL_GPL(uwb_rc_mac_addr_get
);
209 /** Get @rc's device address to @addr */
210 int uwb_rc_dev_addr_get(struct uwb_rc
*rc
,
211 struct uwb_dev_addr
*addr
) {
212 return uwb_rc_addr_get(rc
, addr
, UWB_ADDR_DEV
);
214 EXPORT_SYMBOL_GPL(uwb_rc_dev_addr_get
);
217 /** Set @rc's address to @addr */
218 int uwb_rc_mac_addr_set(struct uwb_rc
*rc
,
219 const struct uwb_mac_addr
*addr
)
221 int result
= -EINVAL
;
222 mutex_lock(&rc
->uwb_dev
.mutex
);
223 result
= uwb_rc_addr_set(rc
, addr
, UWB_ADDR_MAC
);
224 mutex_unlock(&rc
->uwb_dev
.mutex
);
229 /** Set @rc's address to @addr */
230 int uwb_rc_dev_addr_set(struct uwb_rc
*rc
,
231 const struct uwb_dev_addr
*addr
)
233 int result
= -EINVAL
;
234 mutex_lock(&rc
->uwb_dev
.mutex
);
235 result
= uwb_rc_addr_set(rc
, addr
, UWB_ADDR_DEV
);
236 rc
->uwb_dev
.dev_addr
= *addr
;
237 mutex_unlock(&rc
->uwb_dev
.mutex
);
241 /* Returns !0 if given address is already assigned to device. */
242 int __uwb_mac_addr_assigned_check(struct device
*dev
, void *_addr
)
244 struct uwb_dev
*uwb_dev
= to_uwb_dev(dev
);
245 struct uwb_mac_addr
*addr
= _addr
;
247 if (!uwb_mac_addr_cmp(addr
, &uwb_dev
->mac_addr
))
252 /* Returns !0 if given address is already assigned to device. */
253 int __uwb_dev_addr_assigned_check(struct device
*dev
, void *_addr
)
255 struct uwb_dev
*uwb_dev
= to_uwb_dev(dev
);
256 struct uwb_dev_addr
*addr
= _addr
;
257 if (!uwb_dev_addr_cmp(addr
, &uwb_dev
->dev_addr
))
263 * uwb_dev_addr_assign - assigned a generated DevAddr to a radio controller
264 * @rc: the (local) radio controller device requiring a new DevAddr
266 * A new DevAddr is required when:
267 * - first setting up a radio controller
268 * - if the hardware reports a DevAddr conflict
270 * The DevAddr is randomly generated in the generated DevAddr range
271 * [0x100, 0xfeff]. The number of devices in a beacon group is limited
272 * by mMaxBPLength (96) so this address space will never be exhausted.
274 * [ECMA-368] 17.1.1, 17.16.
276 int uwb_rc_dev_addr_assign(struct uwb_rc
*rc
)
278 struct uwb_dev_addr new_addr
;
281 get_random_bytes(new_addr
.data
, sizeof(new_addr
.data
));
282 } while (new_addr
.data
[0] == 0x00 || new_addr
.data
[0] == 0xff
283 || __uwb_dev_addr_assigned(rc
, &new_addr
));
285 return uwb_rc_dev_addr_set(rc
, &new_addr
);
289 * uwbd_evt_handle_rc_dev_addr_conflict - handle a DEV_ADDR_CONFLICT event
290 * @evt: the DEV_ADDR_CONFLICT notification from the radio controller
292 * A new (non-conflicting) DevAddr is assigned to the radio controller.
294 * [ECMA-368] 17.1.1.1.
296 int uwbd_evt_handle_rc_dev_addr_conflict(struct uwb_event
*evt
)
298 struct uwb_rc
*rc
= evt
->rc
;
300 return uwb_rc_dev_addr_assign(rc
);
304 * Print the 48-bit EUI MAC address of the radio controller when
305 * reading /sys/class/uwb_rc/XX/mac_address
307 static ssize_t
uwb_rc_mac_addr_show(struct device
*dev
,
308 struct device_attribute
*attr
, char *buf
)
310 struct uwb_dev
*uwb_dev
= to_uwb_dev(dev
);
311 struct uwb_rc
*rc
= uwb_dev
->rc
;
312 struct uwb_mac_addr addr
;
315 mutex_lock(&rc
->uwb_dev
.mutex
);
316 result
= uwb_rc_addr_get(rc
, &addr
, UWB_ADDR_MAC
);
317 mutex_unlock(&rc
->uwb_dev
.mutex
);
319 result
= uwb_mac_addr_print(buf
, UWB_ADDR_STRSIZE
, &addr
);
320 buf
[result
++] = '\n';
326 * Parse a 48 bit address written to /sys/class/uwb_rc/XX/mac_address
327 * and if correct, set it.
329 static ssize_t
uwb_rc_mac_addr_store(struct device
*dev
,
330 struct device_attribute
*attr
,
331 const char *buf
, size_t size
)
333 struct uwb_dev
*uwb_dev
= to_uwb_dev(dev
);
334 struct uwb_rc
*rc
= uwb_dev
->rc
;
335 struct uwb_mac_addr addr
;
338 result
= sscanf(buf
, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx\n",
339 &addr
.data
[0], &addr
.data
[1], &addr
.data
[2],
340 &addr
.data
[3], &addr
.data
[4], &addr
.data
[5]);
345 if (is_multicast_ether_addr(addr
.data
)) {
346 dev_err(&rc
->uwb_dev
.dev
, "refusing to set multicast "
347 "MAC address %s\n", buf
);
351 result
= uwb_rc_mac_addr_set(rc
, &addr
);
353 rc
->uwb_dev
.mac_addr
= addr
;
355 return result
< 0 ? result
: size
;
357 DEVICE_ATTR(mac_address
, S_IRUGO
| S_IWUSR
, uwb_rc_mac_addr_show
, uwb_rc_mac_addr_store
);
359 /** Print @addr to @buf, @return bytes written */
360 size_t __uwb_addr_print(char *buf
, size_t buf_size
, const unsigned char *addr
,
365 result
= scnprintf(buf
, buf_size
,
366 "%02x:%02x:%02x:%02x:%02x:%02x",
367 addr
[0], addr
[1], addr
[2],
368 addr
[3], addr
[4], addr
[5]);
370 result
= scnprintf(buf
, buf_size
, "%02x:%02x",
374 EXPORT_SYMBOL_GPL(__uwb_addr_print
);