1/* 2 * Ultra Wide Band 3 * Address management 4 * 5 * Copyright (C) 2005-2006 Intel Corporation 6 * Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com> 7 * 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. 11 * 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. 16 * 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 20 * 02110-1301, USA. 21 * 22 * 23 * FIXME: docs 24 */ 25 26#include <linux/slab.h> 27#include <linux/errno.h> 28#include <linux/module.h> 29#include <linux/device.h> 30#include <linux/random.h> 31#include <linux/etherdevice.h> 32 33#include "uwb-internal.h" 34 35 36/** Device Address Management command */ 37struct uwb_rc_cmd_dev_addr_mgmt { 38 struct uwb_rccb rccb; 39 u8 bmOperationType; 40 u8 baAddr[6]; 41} __attribute__((packed)); 42 43 44/** 45 * Low level command for setting/getting UWB radio's addresses 46 * 47 * @hwarc: HWA Radio Control interface instance 48 * @bmOperationType: 49 * Set/get, MAC/DEV (see WUSB1.0[8.6.2.2]) 50 * @baAddr: address buffer--assumed to have enough data to hold 51 * the address type requested. 52 * @reply: Pointer to reply buffer (can be stack allocated) 53 * @returns: 0 if ok, < 0 errno code on error. 54 * 55 * @cmd has to be allocated because USB cannot grok USB or vmalloc 56 * buffers depending on your combination of host architecture. 57 */ 58static 59int uwb_rc_dev_addr_mgmt(struct uwb_rc *rc, 60 u8 bmOperationType, const u8 *baAddr, 61 struct uwb_rc_evt_dev_addr_mgmt *reply) 62{ 63 int result; 64 struct uwb_rc_cmd_dev_addr_mgmt *cmd; 65 66 result = -ENOMEM; 67 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); 68 if (cmd == NULL) 69 goto error_kzalloc; 70 cmd->rccb.bCommandType = UWB_RC_CET_GENERAL; 71 cmd->rccb.wCommand = cpu_to_le16(UWB_RC_CMD_DEV_ADDR_MGMT); 72 cmd->bmOperationType = bmOperationType; 73 if (baAddr) { 74 size_t size = 0; 75 switch (bmOperationType >> 1) { 76 case 0: size = 2; break; 77 case 1: size = 6; break; 78 default: BUG(); 79 } 80 memcpy(cmd->baAddr, baAddr, size); 81 } 82 reply->rceb.bEventType = UWB_RC_CET_GENERAL; 83 reply->rceb.wEvent = UWB_RC_CMD_DEV_ADDR_MGMT; 84 result = uwb_rc_cmd(rc, "DEV-ADDR-MGMT", 85 &cmd->rccb, sizeof(*cmd), 86 &reply->rceb, sizeof(*reply)); 87 if (result < 0) 88 goto error_cmd; 89 if (result < sizeof(*reply)) { 90 dev_err(&rc->uwb_dev.dev, 91 "DEV-ADDR-MGMT: not enough data replied: " 92 "%d vs %zu bytes needed\n", result, sizeof(*reply)); 93 result = -ENOMSG; 94 } else if (reply->bResultCode != UWB_RC_RES_SUCCESS) { 95 dev_err(&rc->uwb_dev.dev, 96 "DEV-ADDR-MGMT: command execution failed: %s (%d)\n", 97 uwb_rc_strerror(reply->bResultCode), 98 reply->bResultCode); 99 result = -EIO; 100 } else 101 result = 0; 102error_cmd: 103 kfree(cmd); 104error_kzalloc: 105 return result; 106} 107 108 109/** 110 * Set the UWB RC MAC or device address. 111 * 112 * @rc: UWB Radio Controller 113 * @_addr: Pointer to address to write [assumed to be either a 114 * 'struct uwb_mac_addr *' or a 'struct uwb_dev_addr *']. 115 * @type: Type of address to set (UWB_ADDR_DEV or UWB_ADDR_MAC). 116 * @returns: 0 if ok, < 0 errno code on error. 117 * 118 * Some anal retentivity here: even if both 'struct 119 * uwb_{dev,mac}_addr' have the actual byte array in the same offset 120 * and I could just pass _addr to hwarc_cmd_dev_addr_mgmt(), I prefer 121 * to use some syntatic sugar in case someday we decide to change the 122 * format of the structs. The compiler will optimize it out anyway. 123 */ 124static int uwb_rc_addr_set(struct uwb_rc *rc, 125 const void *_addr, enum uwb_addr_type type) 126{ 127 int result; 128 u8 bmOperationType = 0x1; /* Set address */ 129 const struct uwb_dev_addr *dev_addr = _addr; 130 const struct uwb_mac_addr *mac_addr = _addr; 131 struct uwb_rc_evt_dev_addr_mgmt reply; 132 const u8 *baAddr; 133 134 result = -EINVAL; 135 switch (type) { 136 case UWB_ADDR_DEV: 137 baAddr = dev_addr->data; 138 break; 139 case UWB_ADDR_MAC: 140 baAddr = mac_addr->data; 141 bmOperationType |= 0x2; 142 break; 143 default: 144 return result; 145 } 146 return uwb_rc_dev_addr_mgmt(rc, bmOperationType, baAddr, &reply); 147} 148 149 150/** 151 * Get the UWB radio's MAC or device address. 152 * 153 * @rc: UWB Radio Controller 154 * @_addr: Where to write the address data [assumed to be either a 155 * 'struct uwb_mac_addr *' or a 'struct uwb_dev_addr *']. 156 * @type: Type of address to get (UWB_ADDR_DEV or UWB_ADDR_MAC). 157 * @returns: 0 if ok (and *_addr set), < 0 errno code on error. 158 * 159 * See comment in uwb_rc_addr_set() about anal retentivity in the 160 * type handling of the address variables. 161 */ 162static int uwb_rc_addr_get(struct uwb_rc *rc, 163 void *_addr, enum uwb_addr_type type) 164{ 165 int result; 166 u8 bmOperationType = 0x0; /* Get address */ 167 struct uwb_rc_evt_dev_addr_mgmt evt; 168 struct uwb_dev_addr *dev_addr = _addr; 169 struct uwb_mac_addr *mac_addr = _addr; 170 u8 *baAddr; 171 172 result = -EINVAL; 173 switch (type) { 174 case UWB_ADDR_DEV: 175 baAddr = dev_addr->data; 176 break; 177 case UWB_ADDR_MAC: 178 bmOperationType |= 0x2; 179 baAddr = mac_addr->data; 180 break; 181 default: 182 return result; 183 } 184 result = uwb_rc_dev_addr_mgmt(rc, bmOperationType, baAddr, &evt); 185 if (result == 0) 186 switch (type) { 187 case UWB_ADDR_DEV: 188 memcpy(&dev_addr->data, evt.baAddr, 189 sizeof(dev_addr->data)); 190 break; 191 case UWB_ADDR_MAC: 192 memcpy(&mac_addr->data, evt.baAddr, 193 sizeof(mac_addr->data)); 194 break; 195 default: /* shut gcc up */ 196 BUG(); 197 } 198 return result; 199} 200 201 202/** Get @rc's MAC address to @addr */ 203int uwb_rc_mac_addr_get(struct uwb_rc *rc, 204 struct uwb_mac_addr *addr) { 205 return uwb_rc_addr_get(rc, addr, UWB_ADDR_MAC); 206} 207EXPORT_SYMBOL_GPL(uwb_rc_mac_addr_get); 208 209 210/** Get @rc's device address to @addr */ 211int uwb_rc_dev_addr_get(struct uwb_rc *rc, 212 struct uwb_dev_addr *addr) { 213 return uwb_rc_addr_get(rc, addr, UWB_ADDR_DEV); 214} 215EXPORT_SYMBOL_GPL(uwb_rc_dev_addr_get); 216 217 218/** Set @rc's address to @addr */ 219int uwb_rc_mac_addr_set(struct uwb_rc *rc, 220 const struct uwb_mac_addr *addr) 221{ 222 int result = -EINVAL; 223 mutex_lock(&rc->uwb_dev.mutex); 224 result = uwb_rc_addr_set(rc, addr, UWB_ADDR_MAC); 225 mutex_unlock(&rc->uwb_dev.mutex); 226 return result; 227} 228 229 230/** Set @rc's address to @addr */ 231int uwb_rc_dev_addr_set(struct uwb_rc *rc, 232 const struct uwb_dev_addr *addr) 233{ 234 int result = -EINVAL; 235 mutex_lock(&rc->uwb_dev.mutex); 236 result = uwb_rc_addr_set(rc, addr, UWB_ADDR_DEV); 237 rc->uwb_dev.dev_addr = *addr; 238 mutex_unlock(&rc->uwb_dev.mutex); 239 return result; 240} 241 242/* Returns !0 if given address is already assigned to device. */ 243int __uwb_mac_addr_assigned_check(struct device *dev, void *_addr) 244{ 245 struct uwb_dev *uwb_dev = to_uwb_dev(dev); 246 struct uwb_mac_addr *addr = _addr; 247 248 if (!uwb_mac_addr_cmp(addr, &uwb_dev->mac_addr)) 249 return !0; 250 return 0; 251} 252 253/* Returns !0 if given address is already assigned to device. */ 254int __uwb_dev_addr_assigned_check(struct device *dev, void *_addr) 255{ 256 struct uwb_dev *uwb_dev = to_uwb_dev(dev); 257 struct uwb_dev_addr *addr = _addr; 258 if (!uwb_dev_addr_cmp(addr, &uwb_dev->dev_addr)) 259 return !0; 260 return 0; 261} 262 263/** 264 * uwb_dev_addr_assign - assigned a generated DevAddr to a radio controller 265 * @rc: the (local) radio controller device requiring a new DevAddr 266 * 267 * A new DevAddr is required when: 268 * - first setting up a radio controller 269 * - if the hardware reports a DevAddr conflict 270 * 271 * The DevAddr is randomly generated in the generated DevAddr range 272 * [0x100, 0xfeff]. The number of devices in a beacon group is limited 273 * by mMaxBPLength (96) so this address space will never be exhausted. 274 * 275 * [ECMA-368] 17.1.1, 17.16. 276 */ 277int uwb_rc_dev_addr_assign(struct uwb_rc *rc) 278{ 279 struct uwb_dev_addr new_addr; 280 281 do { 282 get_random_bytes(new_addr.data, sizeof(new_addr.data)); 283 } while (new_addr.data[0] == 0x00 || new_addr.data[0] == 0xff 284 || __uwb_dev_addr_assigned(rc, &new_addr)); 285 286 return uwb_rc_dev_addr_set(rc, &new_addr); 287} 288 289/** 290 * uwbd_evt_handle_rc_dev_addr_conflict - handle a DEV_ADDR_CONFLICT event 291 * @evt: the DEV_ADDR_CONFLICT notification from the radio controller 292 * 293 * A new (non-conflicting) DevAddr is assigned to the radio controller. 294 * 295 * [ECMA-368] 17.1.1.1. 296 */ 297int uwbd_evt_handle_rc_dev_addr_conflict(struct uwb_event *evt) 298{ 299 struct uwb_rc *rc = evt->rc; 300 301 return uwb_rc_dev_addr_assign(rc); 302} 303 304/* 305 * Print the 48-bit EUI MAC address of the radio controller when 306 * reading /sys/class/uwb_rc/XX/mac_address 307 */ 308static ssize_t uwb_rc_mac_addr_show(struct device *dev, 309 struct device_attribute *attr, char *buf) 310{ 311 struct uwb_dev *uwb_dev = to_uwb_dev(dev); 312 struct uwb_rc *rc = uwb_dev->rc; 313 struct uwb_mac_addr addr; 314 ssize_t result; 315 316 mutex_lock(&rc->uwb_dev.mutex); 317 result = uwb_rc_addr_get(rc, &addr, UWB_ADDR_MAC); 318 mutex_unlock(&rc->uwb_dev.mutex); 319 if (result >= 0) { 320 result = uwb_mac_addr_print(buf, UWB_ADDR_STRSIZE, &addr); 321 buf[result++] = '\n'; 322 } 323 return result; 324} 325 326/* 327 * Parse a 48 bit address written to /sys/class/uwb_rc/XX/mac_address 328 * and if correct, set it. 329 */ 330static ssize_t uwb_rc_mac_addr_store(struct device *dev, 331 struct device_attribute *attr, 332 const char *buf, size_t size) 333{ 334 struct uwb_dev *uwb_dev = to_uwb_dev(dev); 335 struct uwb_rc *rc = uwb_dev->rc; 336 struct uwb_mac_addr addr; 337 ssize_t result; 338 339 result = sscanf(buf, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx\n", 340 &addr.data[0], &addr.data[1], &addr.data[2], 341 &addr.data[3], &addr.data[4], &addr.data[5]); 342 if (result != 6) { 343 result = -EINVAL; 344 goto out; 345 } 346 if (is_multicast_ether_addr(addr.data)) { 347 dev_err(&rc->uwb_dev.dev, "refusing to set multicast " 348 "MAC address %s\n", buf); 349 result = -EINVAL; 350 goto out; 351 } 352 result = uwb_rc_mac_addr_set(rc, &addr); 353 if (result == 0) 354 rc->uwb_dev.mac_addr = addr; 355out: 356 return result < 0 ? result : size; 357} 358DEVICE_ATTR(mac_address, S_IRUGO | S_IWUSR, uwb_rc_mac_addr_show, uwb_rc_mac_addr_store); 359 360/** Print @addr to @buf, @return bytes written */ 361size_t __uwb_addr_print(char *buf, size_t buf_size, const unsigned char *addr, 362 int type) 363{ 364 size_t result; 365 if (type) 366 result = scnprintf(buf, buf_size, "%pM", addr); 367 else 368 result = scnprintf(buf, buf_size, "%02x:%02x", 369 addr[1], addr[0]); 370 return result; 371} 372EXPORT_SYMBOL_GPL(__uwb_addr_print); 373