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