This source file includes following definitions.
- uwb_rc_dev_addr_mgmt
- uwb_rc_addr_set
- uwb_rc_addr_get
- uwb_rc_mac_addr_get
- uwb_rc_dev_addr_get
- uwb_rc_mac_addr_set
- uwb_rc_dev_addr_set
- __uwb_mac_addr_assigned_check
- __uwb_dev_addr_assigned_check
- uwb_rc_dev_addr_assign
- uwbd_evt_handle_rc_dev_addr_conflict
- uwb_rc_mac_addr_show
- uwb_rc_mac_addr_store
- __uwb_addr_print
   1 
   2 
   3 
   4 
   5 
   6 
   7 
   8 
   9 
  10 
  11 
  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>
  18 
  19 #include "uwb-internal.h"
  20 
  21 
  22 
  23 struct uwb_rc_cmd_dev_addr_mgmt {
  24         struct uwb_rccb rccb;
  25         u8 bmOperationType;
  26         u8 baAddr[6];
  27 } __attribute__((packed));
  28 
  29 
  30 
  31 
  32 
  33 
  34 
  35 
  36 
  37 
  38 
  39 
  40 
  41 
  42 
  43 
  44 static
  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)
  48 {
  49         int result;
  50         struct uwb_rc_cmd_dev_addr_mgmt *cmd;
  51 
  52         result = -ENOMEM;
  53         cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
  54         if (cmd == NULL)
  55                 goto error_kzalloc;
  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;
  59         if (baAddr) {
  60                 size_t size = 0;
  61                 switch (bmOperationType >> 1) {
  62                 case 0: size = 2; break;
  63                 case 1: size = 6; break;
  64                 default: BUG();
  65                 }
  66                 memcpy(cmd->baAddr, baAddr, size);
  67         }
  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));
  73         if (result < 0)
  74                 goto error_cmd;
  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));
  79                 result = -ENOMSG;
  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),
  84                         reply->bResultCode);
  85                 result = -EIO;
  86         } else
  87                 result = 0;
  88 error_cmd:
  89         kfree(cmd);
  90 error_kzalloc:
  91         return result;
  92 }
  93 
  94 
  95 
  96 
  97 
  98 
  99 
 100 
 101 
 102 
 103 
 104 
 105 
 106 
 107 
 108 
 109 
 110 static int uwb_rc_addr_set(struct uwb_rc *rc,
 111                     const void *_addr, enum uwb_addr_type type)
 112 {
 113         int result;
 114         u8 bmOperationType = 0x1;               
 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;
 118         const u8 *baAddr;
 119 
 120         result = -EINVAL;
 121         switch (type) {
 122         case UWB_ADDR_DEV:
 123                 baAddr = dev_addr->data;
 124                 break;
 125         case UWB_ADDR_MAC:
 126                 baAddr = mac_addr->data;
 127                 bmOperationType |= 0x2;
 128                 break;
 129         default:
 130                 return result;
 131         }
 132         return uwb_rc_dev_addr_mgmt(rc, bmOperationType, baAddr, &reply);
 133 }
 134 
 135 
 136 
 137 
 138 
 139 
 140 
 141 
 142 
 143 
 144 
 145 
 146 
 147 
 148 static int uwb_rc_addr_get(struct uwb_rc *rc,
 149                     void *_addr, enum uwb_addr_type type)
 150 {
 151         int result;
 152         u8 bmOperationType = 0x0;               
 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;
 156         u8 *baAddr;
 157 
 158         result = -EINVAL;
 159         switch (type) {
 160         case UWB_ADDR_DEV:
 161                 baAddr = dev_addr->data;
 162                 break;
 163         case UWB_ADDR_MAC:
 164                 bmOperationType |= 0x2;
 165                 baAddr = mac_addr->data;
 166                 break;
 167         default:
 168                 return result;
 169         }
 170         result = uwb_rc_dev_addr_mgmt(rc, bmOperationType, baAddr, &evt);
 171         if (result == 0)
 172                 switch (type) {
 173                 case UWB_ADDR_DEV:
 174                         memcpy(&dev_addr->data, evt.baAddr,
 175                                sizeof(dev_addr->data));
 176                         break;
 177                 case UWB_ADDR_MAC:
 178                         memcpy(&mac_addr->data, evt.baAddr,
 179                                sizeof(mac_addr->data));
 180                         break;
 181                 default:                
 182                         BUG();
 183                 }
 184         return result;
 185 }
 186 
 187 
 188 
 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);
 192 }
 193 EXPORT_SYMBOL_GPL(uwb_rc_mac_addr_get);
 194 
 195 
 196 
 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);
 200 }
 201 EXPORT_SYMBOL_GPL(uwb_rc_dev_addr_get);
 202 
 203 
 204 
 205 int uwb_rc_mac_addr_set(struct uwb_rc *rc,
 206                         const struct uwb_mac_addr *addr)
 207 {
 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);
 212         return result;
 213 }
 214 
 215 
 216 
 217 int uwb_rc_dev_addr_set(struct uwb_rc *rc,
 218                         const struct uwb_dev_addr *addr)
 219 {
 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);
 225         return result;
 226 }
 227 
 228 
 229 int __uwb_mac_addr_assigned_check(struct device *dev, void *_addr)
 230 {
 231         struct uwb_dev *uwb_dev = to_uwb_dev(dev);
 232         struct uwb_mac_addr *addr = _addr;
 233 
 234         if (!uwb_mac_addr_cmp(addr, &uwb_dev->mac_addr))
 235                 return !0;
 236         return 0;
 237 }
 238 
 239 
 240 int __uwb_dev_addr_assigned_check(struct device *dev, void *_addr)
 241 {
 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))
 245                 return !0;
 246         return 0;
 247 }
 248 
 249 
 250 
 251 
 252 
 253 
 254 
 255 
 256 
 257 
 258 
 259 
 260 
 261 
 262 
 263 int uwb_rc_dev_addr_assign(struct uwb_rc *rc)
 264 {
 265         struct uwb_dev_addr new_addr;
 266 
 267         do {
 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));
 271 
 272         return uwb_rc_dev_addr_set(rc, &new_addr);
 273 }
 274 
 275 
 276 
 277 
 278 
 279 
 280 
 281 
 282 
 283 int uwbd_evt_handle_rc_dev_addr_conflict(struct uwb_event *evt)
 284 {
 285         struct uwb_rc *rc = evt->rc;
 286 
 287         return uwb_rc_dev_addr_assign(rc);
 288 }
 289 
 290 
 291 
 292 
 293 
 294 static ssize_t uwb_rc_mac_addr_show(struct device *dev,
 295                                     struct device_attribute *attr, char *buf)
 296 {
 297         struct uwb_dev *uwb_dev = to_uwb_dev(dev);
 298         struct uwb_rc *rc = uwb_dev->rc;
 299         struct uwb_mac_addr addr;
 300         ssize_t result;
 301 
 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);
 305         if (result >= 0) {
 306                 result = uwb_mac_addr_print(buf, UWB_ADDR_STRSIZE, &addr);
 307                 buf[result++] = '\n';
 308         }
 309         return result;
 310 }
 311 
 312 
 313 
 314 
 315 
 316 static ssize_t uwb_rc_mac_addr_store(struct device *dev,
 317                                      struct device_attribute *attr,
 318                                      const char *buf, size_t size)
 319 {
 320         struct uwb_dev *uwb_dev = to_uwb_dev(dev);
 321         struct uwb_rc *rc = uwb_dev->rc;
 322         struct uwb_mac_addr addr;
 323         ssize_t result;
 324 
 325         if (!mac_pton(buf, addr.data))
 326                 return -EINVAL;
 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);
 330                 return -EINVAL;
 331         }
 332         result = uwb_rc_mac_addr_set(rc, &addr);
 333         if (result == 0)
 334                 rc->uwb_dev.mac_addr = addr;
 335 
 336         return result < 0 ? result : size;
 337 }
 338 DEVICE_ATTR(mac_address, S_IRUGO | S_IWUSR, uwb_rc_mac_addr_show, uwb_rc_mac_addr_store);
 339 
 340 
 341 size_t __uwb_addr_print(char *buf, size_t buf_size, const unsigned char *addr,
 342                         int type)
 343 {
 344         size_t result;
 345         if (type)
 346                 result = scnprintf(buf, buf_size, "%pM", addr);
 347         else
 348                 result = scnprintf(buf, buf_size, "%02x:%02x",
 349                                   addr[1], addr[0]);
 350         return result;
 351 }
 352 EXPORT_SYMBOL_GPL(__uwb_addr_print);