1 2 3#include <linux/wlp.h> 4#include <linux/slab.h> 5 6#include "wlp-internal.h" 7 8static 9const char *__wlp_assoc_frame[] = { 10 [WLP_ASSOC_D1] = "WLP_ASSOC_D1", 11 [WLP_ASSOC_D2] = "WLP_ASSOC_D2", 12 [WLP_ASSOC_M1] = "WLP_ASSOC_M1", 13 [WLP_ASSOC_M2] = "WLP_ASSOC_M2", 14 [WLP_ASSOC_M3] = "WLP_ASSOC_M3", 15 [WLP_ASSOC_M4] = "WLP_ASSOC_M4", 16 [WLP_ASSOC_M5] = "WLP_ASSOC_M5", 17 [WLP_ASSOC_M6] = "WLP_ASSOC_M6", 18 [WLP_ASSOC_M7] = "WLP_ASSOC_M7", 19 [WLP_ASSOC_M8] = "WLP_ASSOC_M8", 20 [WLP_ASSOC_F0] = "WLP_ASSOC_F0", 21 [WLP_ASSOC_E1] = "WLP_ASSOC_E1", 22 [WLP_ASSOC_E2] = "WLP_ASSOC_E2", 23 [WLP_ASSOC_C1] = "WLP_ASSOC_C1", 24 [WLP_ASSOC_C2] = "WLP_ASSOC_C2", 25 [WLP_ASSOC_C3] = "WLP_ASSOC_C3", 26 [WLP_ASSOC_C4] = "WLP_ASSOC_C4", 27}; 28 29static const char *wlp_assoc_frame_str(unsigned id) 30{ 31 if (id >= ARRAY_SIZE(__wlp_assoc_frame)) 32 return "unknown association frame"; 33 return __wlp_assoc_frame[id]; 34} 35 36static const char *__wlp_assc_error[] = { 37 "none", 38 "Authenticator Failure", 39 "Rogue activity suspected", 40 "Device busy", 41 "Setup Locked", 42 "Registrar not ready", 43 "Invalid WSS selection", 44 "Message timeout", 45 "Enrollment session timeout", 46 "Device password invalid", 47 "Unsupported version", 48 "Internal error", 49 "Undefined error", 50 "Numeric comparison failure", 51 "Waiting for user input", 52}; 53 54static const char *wlp_assc_error_str(unsigned id) 55{ 56 if (id >= ARRAY_SIZE(__wlp_assc_error)) 57 return "unknown WLP association error"; 58 return __wlp_assc_error[id]; 59} 60 61static inline void wlp_set_attr_hdr(struct wlp_attr_hdr *hdr, unsigned type, 62 size_t len) 63{ 64 hdr->type = cpu_to_le16(type); 65 hdr->length = cpu_to_le16(len); 66} 67 68/* 69 * Populate fields of a constant sized attribute 70 * 71 * @returns: total size of attribute including size of new value 72 * 73 * We have two instances of this function (wlp_pset and wlp_set): one takes 74 * the value as a parameter, the other takes a pointer to the value as 75 * parameter. They thus only differ in how the value is assigned to the 76 * attribute. 77 * 78 * We use sizeof(*attr) - sizeof(struct wlp_attr_hdr) instead of 79 * sizeof(type) to be able to use this same code for the structures that 80 * contain 8bit enum values and be able to deal with pointer types. 81 */ 82#define wlp_set(type, type_code, name) \ 83static size_t wlp_set_##name(struct wlp_attr_##name *attr, type value) \ 84{ \ 85 wlp_set_attr_hdr(&attr->hdr, type_code, \ 86 sizeof(*attr) - sizeof(struct wlp_attr_hdr)); \ 87 attr->name = value; \ 88 return sizeof(*attr); \ 89} 90 91#define wlp_pset(type, type_code, name) \ 92static size_t wlp_set_##name(struct wlp_attr_##name *attr, type value) \ 93{ \ 94 wlp_set_attr_hdr(&attr->hdr, type_code, \ 95 sizeof(*attr) - sizeof(struct wlp_attr_hdr)); \ 96 attr->name = *value; \ 97 return sizeof(*attr); \ 98} 99 100/** 101 * Populate fields of a variable attribute 102 * 103 * @returns: total size of attribute including size of new value 104 * 105 * Provided with a pointer to the memory area reserved for the 106 * attribute structure, the field is populated with the value. The 107 * reserved memory has to contain enough space for the value. 108 */ 109#define wlp_vset(type, type_code, name) \ 110static size_t wlp_set_##name(struct wlp_attr_##name *attr, type value, \ 111 size_t len) \ 112{ \ 113 wlp_set_attr_hdr(&attr->hdr, type_code, len); \ 114 memcpy(attr->name, value, len); \ 115 return sizeof(*attr) + len; \ 116} 117 118wlp_vset(char *, WLP_ATTR_DEV_NAME, dev_name) 119wlp_vset(char *, WLP_ATTR_MANUF, manufacturer) 120wlp_set(enum wlp_assoc_type, WLP_ATTR_MSG_TYPE, msg_type) 121wlp_vset(char *, WLP_ATTR_MODEL_NAME, model_name) 122wlp_vset(char *, WLP_ATTR_MODEL_NR, model_nr) 123wlp_vset(char *, WLP_ATTR_SERIAL, serial) 124wlp_vset(char *, WLP_ATTR_WSS_NAME, wss_name) 125wlp_pset(struct wlp_uuid *, WLP_ATTR_UUID_E, uuid_e) 126wlp_pset(struct wlp_uuid *, WLP_ATTR_UUID_R, uuid_r) 127wlp_pset(struct wlp_uuid *, WLP_ATTR_WSSID, wssid) 128wlp_pset(struct wlp_dev_type *, WLP_ATTR_PRI_DEV_TYPE, prim_dev_type) 129/*wlp_pset(struct wlp_dev_type *, WLP_ATTR_SEC_DEV_TYPE, sec_dev_type)*/ 130wlp_set(u8, WLP_ATTR_WLP_VER, version) 131wlp_set(enum wlp_assc_error, WLP_ATTR_WLP_ASSC_ERR, wlp_assc_err) 132wlp_set(enum wlp_wss_sel_mthd, WLP_ATTR_WSS_SEL_MTHD, wss_sel_mthd) 133wlp_set(u8, WLP_ATTR_ACC_ENRL, accept_enrl) 134wlp_set(u8, WLP_ATTR_WSS_SEC_STAT, wss_sec_status) 135wlp_pset(struct uwb_mac_addr *, WLP_ATTR_WSS_BCAST, wss_bcast) 136wlp_pset(struct wlp_nonce *, WLP_ATTR_ENRL_NONCE, enonce) 137wlp_pset(struct wlp_nonce *, WLP_ATTR_REG_NONCE, rnonce) 138wlp_set(u8, WLP_ATTR_WSS_TAG, wss_tag) 139wlp_pset(struct uwb_mac_addr *, WLP_ATTR_WSS_VIRT, wss_virt) 140 141/** 142 * Fill in the WSS information attributes 143 * 144 * We currently only support one WSS, and this is assumed in this function 145 * that can populate only one WSS information attribute. 146 */ 147static size_t wlp_set_wss_info(struct wlp_attr_wss_info *attr, 148 struct wlp_wss *wss) 149{ 150 size_t datalen; 151 void *ptr = attr->wss_info; 152 size_t used = sizeof(*attr); 153 154 datalen = sizeof(struct wlp_wss_info) + strlen(wss->name); 155 wlp_set_attr_hdr(&attr->hdr, WLP_ATTR_WSS_INFO, datalen); 156 used = wlp_set_wssid(ptr, &wss->wssid); 157 used += wlp_set_wss_name(ptr + used, wss->name, strlen(wss->name)); 158 used += wlp_set_accept_enrl(ptr + used, wss->accept_enroll); 159 used += wlp_set_wss_sec_status(ptr + used, wss->secure_status); 160 used += wlp_set_wss_bcast(ptr + used, &wss->bcast); 161 return sizeof(*attr) + used; 162} 163 164/** 165 * Verify attribute header 166 * 167 * @hdr: Pointer to attribute header that will be verified. 168 * @type: Expected attribute type. 169 * @len: Expected length of attribute value (excluding header). 170 * 171 * Most attribute values have a known length even when they do have a 172 * length field. This knowledge can be used via this function to verify 173 * that the length field matches the expected value. 174 */ 175static int wlp_check_attr_hdr(struct wlp *wlp, struct wlp_attr_hdr *hdr, 176 enum wlp_attr_type type, unsigned len) 177{ 178 struct device *dev = &wlp->rc->uwb_dev.dev; 179 180 if (le16_to_cpu(hdr->type) != type) { 181 dev_err(dev, "WLP: unexpected header type. Expected " 182 "%u, got %u.\n", type, le16_to_cpu(hdr->type)); 183 return -EINVAL; 184 } 185 if (le16_to_cpu(hdr->length) != len) { 186 dev_err(dev, "WLP: unexpected length in header. Expected " 187 "%u, got %u.\n", len, le16_to_cpu(hdr->length)); 188 return -EINVAL; 189 } 190 return 0; 191} 192 193/** 194 * Check if header of WSS information attribute valid 195 * 196 * @returns: length of WSS attributes (value of length attribute field) if 197 * valid WSS information attribute found 198 * -ENODATA if no WSS information attribute found 199 * -EIO other error occured 200 * 201 * The WSS information attribute is optional. The function will be provided 202 * with a pointer to data that could _potentially_ be a WSS information 203 * attribute. If a valid WSS information attribute is found it will return 204 * 0, if no WSS information attribute is found it will return -ENODATA, and 205 * another error will be returned if it is a WSS information attribute, but 206 * some parsing failure occured. 207 */ 208static int wlp_check_wss_info_attr_hdr(struct wlp *wlp, 209 struct wlp_attr_hdr *hdr, size_t buflen) 210{ 211 struct device *dev = &wlp->rc->uwb_dev.dev; 212 size_t len; 213 int result = 0; 214 215 if (buflen < sizeof(*hdr)) { 216 dev_err(dev, "WLP: Not enough space in buffer to parse" 217 " WSS information attribute header.\n"); 218 result = -EIO; 219 goto out; 220 } 221 if (le16_to_cpu(hdr->type) != WLP_ATTR_WSS_INFO) { 222 /* WSS information is optional */ 223 result = -ENODATA; 224 goto out; 225 } 226 len = le16_to_cpu(hdr->length); 227 if (buflen < sizeof(*hdr) + len) { 228 dev_err(dev, "WLP: Not enough space in buffer to parse " 229 "variable data. Got %d, expected %d.\n", 230 (int)buflen, (int)(sizeof(*hdr) + len)); 231 result = -EIO; 232 goto out; 233 } 234 result = len; 235out: 236 return result; 237} 238 239 240static ssize_t wlp_get_attribute(struct wlp *wlp, u16 type_code, 241 struct wlp_attr_hdr *attr_hdr, void *value, ssize_t value_len, 242 ssize_t buflen) 243{ 244 struct device *dev = &wlp->rc->uwb_dev.dev; 245 ssize_t attr_len = sizeof(*attr_hdr) + value_len; 246 if (buflen < 0) 247 return -EINVAL; 248 if (buflen < attr_len) { 249 dev_err(dev, "WLP: Not enough space in buffer to parse" 250 " attribute field. Need %d, received %zu\n", 251 (int)attr_len, buflen); 252 return -EIO; 253 } 254 if (wlp_check_attr_hdr(wlp, attr_hdr, type_code, value_len) < 0) { 255 dev_err(dev, "WLP: Header verification failed. \n"); 256 return -EINVAL; 257 } 258 memcpy(value, (void *)attr_hdr + sizeof(*attr_hdr), value_len); 259 return attr_len; 260} 261 262static ssize_t wlp_vget_attribute(struct wlp *wlp, u16 type_code, 263 struct wlp_attr_hdr *attr_hdr, void *value, ssize_t max_value_len, 264 ssize_t buflen) 265{ 266 struct device *dev = &wlp->rc->uwb_dev.dev; 267 size_t len; 268 if (buflen < 0) 269 return -EINVAL; 270 if (buflen < sizeof(*attr_hdr)) { 271 dev_err(dev, "WLP: Not enough space in buffer to parse" 272 " header.\n"); 273 return -EIO; 274 } 275 if (le16_to_cpu(attr_hdr->type) != type_code) { 276 dev_err(dev, "WLP: Unexpected attribute type. Got %u, " 277 "expected %u.\n", le16_to_cpu(attr_hdr->type), 278 type_code); 279 return -EINVAL; 280 } 281 len = le16_to_cpu(attr_hdr->length); 282 if (len > max_value_len) { 283 dev_err(dev, "WLP: Attribute larger than maximum " 284 "allowed. Received %zu, max is %d.\n", len, 285 (int)max_value_len); 286 return -EFBIG; 287 } 288 if (buflen < sizeof(*attr_hdr) + len) { 289 dev_err(dev, "WLP: Not enough space in buffer to parse " 290 "variable data.\n"); 291 return -EIO; 292 } 293 memcpy(value, (void *)attr_hdr + sizeof(*attr_hdr), len); 294 return sizeof(*attr_hdr) + len; 295} 296 297/** 298 * Get value of attribute from fixed size attribute field. 299 * 300 * @attr: Pointer to attribute field. 301 * @value: Pointer to variable in which attribute value will be placed. 302 * @buflen: Size of buffer in which attribute field (including header) 303 * can be found. 304 * @returns: Amount of given buffer consumed by parsing for this attribute. 305 * 306 * The size and type of the value is known by the type of the attribute. 307 */ 308#define wlp_get(type, type_code, name) \ 309ssize_t wlp_get_##name(struct wlp *wlp, struct wlp_attr_##name *attr, \ 310 type *value, ssize_t buflen) \ 311{ \ 312 return wlp_get_attribute(wlp, (type_code), &attr->hdr, \ 313 value, sizeof(*value), buflen); \ 314} 315 316#define wlp_get_sparse(type, type_code, name) \ 317 static wlp_get(type, type_code, name) 318 319/** 320 * Get value of attribute from variable sized attribute field. 321 * 322 * @max: The maximum size of this attribute. This value is dictated by 323 * the maximum value from the WLP specification. 324 * 325 * @attr: Pointer to attribute field. 326 * @value: Pointer to variable that will contain the value. The memory 327 * must already have been allocated for this value. 328 * @buflen: Size of buffer in which attribute field (including header) 329 * can be found. 330 * @returns: Amount of given bufferconsumed by parsing for this attribute. 331 */ 332#define wlp_vget(type_val, type_code, name, max) \ 333static ssize_t wlp_get_##name(struct wlp *wlp, \ 334 struct wlp_attr_##name *attr, \ 335 type_val *value, ssize_t buflen) \ 336{ \ 337 return wlp_vget_attribute(wlp, (type_code), &attr->hdr, \ 338 value, (max), buflen); \ 339} 340 341wlp_get(u8, WLP_ATTR_WLP_VER, version) 342wlp_get_sparse(enum wlp_wss_sel_mthd, WLP_ATTR_WSS_SEL_MTHD, wss_sel_mthd) 343wlp_get_sparse(struct wlp_dev_type, WLP_ATTR_PRI_DEV_TYPE, prim_dev_type) 344wlp_get_sparse(enum wlp_assc_error, WLP_ATTR_WLP_ASSC_ERR, wlp_assc_err) 345wlp_get_sparse(struct wlp_uuid, WLP_ATTR_UUID_E, uuid_e) 346wlp_get_sparse(struct wlp_uuid, WLP_ATTR_UUID_R, uuid_r) 347wlp_get(struct wlp_uuid, WLP_ATTR_WSSID, wssid) 348wlp_get_sparse(u8, WLP_ATTR_ACC_ENRL, accept_enrl) 349wlp_get_sparse(u8, WLP_ATTR_WSS_SEC_STAT, wss_sec_status) 350wlp_get_sparse(struct uwb_mac_addr, WLP_ATTR_WSS_BCAST, wss_bcast) 351wlp_get_sparse(u8, WLP_ATTR_WSS_TAG, wss_tag) 352wlp_get_sparse(struct uwb_mac_addr, WLP_ATTR_WSS_VIRT, wss_virt) 353wlp_get_sparse(struct wlp_nonce, WLP_ATTR_ENRL_NONCE, enonce) 354wlp_get_sparse(struct wlp_nonce, WLP_ATTR_REG_NONCE, rnonce) 355 356/* The buffers for the device info attributes can be found in the 357 * wlp_device_info struct. These buffers contain one byte more than the 358 * max allowed by the spec - this is done to be able to add the 359 * terminating \0 for user display. This terminating byte is not required 360 * in the actual attribute field (because it has a length field) so the 361 * maximum allowed for this value is one less than its size in the 362 * structure. 363 */ 364wlp_vget(char, WLP_ATTR_WSS_NAME, wss_name, 365 FIELD_SIZEOF(struct wlp_wss, name) - 1) 366wlp_vget(char, WLP_ATTR_DEV_NAME, dev_name, 367 FIELD_SIZEOF(struct wlp_device_info, name) - 1) 368wlp_vget(char, WLP_ATTR_MANUF, manufacturer, 369 FIELD_SIZEOF(struct wlp_device_info, manufacturer) - 1) 370wlp_vget(char, WLP_ATTR_MODEL_NAME, model_name, 371 FIELD_SIZEOF(struct wlp_device_info, model_name) - 1) 372wlp_vget(char, WLP_ATTR_MODEL_NR, model_nr, 373 FIELD_SIZEOF(struct wlp_device_info, model_nr) - 1) 374wlp_vget(char, WLP_ATTR_SERIAL, serial, 375 FIELD_SIZEOF(struct wlp_device_info, serial) - 1) 376 377/** 378 * Retrieve WSS Name, Accept enroll, Secure status, Broadcast from WSS info 379 * 380 * @attr: pointer to WSS name attribute in WSS information attribute field 381 * @info: structure that will be populated with data from WSS information 382 * field (WSS name, Accept enroll, secure status, broadcast address) 383 * @buflen: size of buffer 384 * 385 * Although the WSSID attribute forms part of the WSS info attribute it is 386 * retrieved separately and stored in a different location. 387 */ 388static ssize_t wlp_get_wss_info_attrs(struct wlp *wlp, 389 struct wlp_attr_hdr *attr, 390 struct wlp_wss_tmp_info *info, 391 ssize_t buflen) 392{ 393 struct device *dev = &wlp->rc->uwb_dev.dev; 394 void *ptr = attr; 395 size_t used = 0; 396 ssize_t result = -EINVAL; 397 398 result = wlp_get_wss_name(wlp, ptr, info->name, buflen); 399 if (result < 0) { 400 dev_err(dev, "WLP: unable to obtain WSS name from " 401 "WSS info in D2 message.\n"); 402 goto error_parse; 403 } 404 used += result; 405 406 result = wlp_get_accept_enrl(wlp, ptr + used, &info->accept_enroll, 407 buflen - used); 408 if (result < 0) { 409 dev_err(dev, "WLP: unable to obtain accepting " 410 "enrollment from WSS info in D2 message.\n"); 411 goto error_parse; 412 } 413 if (info->accept_enroll != 0 && info->accept_enroll != 1) { 414 dev_err(dev, "WLP: invalid value for accepting " 415 "enrollment in D2 message.\n"); 416 result = -EINVAL; 417 goto error_parse; 418 } 419 used += result; 420 421 result = wlp_get_wss_sec_status(wlp, ptr + used, &info->sec_status, 422 buflen - used); 423 if (result < 0) { 424 dev_err(dev, "WLP: unable to obtain secure " 425 "status from WSS info in D2 message.\n"); 426 goto error_parse; 427 } 428 if (info->sec_status != 0 && info->sec_status != 1) { 429 dev_err(dev, "WLP: invalid value for secure " 430 "status in D2 message.\n"); 431 result = -EINVAL; 432 goto error_parse; 433 } 434 used += result; 435 436 result = wlp_get_wss_bcast(wlp, ptr + used, &info->bcast, 437 buflen - used); 438 if (result < 0) { 439 dev_err(dev, "WLP: unable to obtain broadcast " 440 "address from WSS info in D2 message.\n"); 441 goto error_parse; 442 } 443 used += result; 444 result = used; 445error_parse: 446 return result; 447} 448 449/** 450 * Create a new WSSID entry for the neighbor, allocate temporary storage 451 * 452 * Each neighbor can have many WSS active. We maintain a list of WSSIDs 453 * advertised by neighbor. During discovery we also cache information about 454 * these WSS in temporary storage. 455 * 456 * The temporary storage will be removed after it has been used (eg. 457 * displayed to user), the wssid element will be removed from the list when 458 * the neighbor is rediscovered or when it disappears. 459 */ 460static struct wlp_wssid_e *wlp_create_wssid_e(struct wlp *wlp, 461 struct wlp_neighbor_e *neighbor) 462{ 463 struct device *dev = &wlp->rc->uwb_dev.dev; 464 struct wlp_wssid_e *wssid_e; 465 466 wssid_e = kzalloc(sizeof(*wssid_e), GFP_KERNEL); 467 if (wssid_e == NULL) { 468 dev_err(dev, "WLP: unable to allocate memory " 469 "for WSS information.\n"); 470 goto error_alloc; 471 } 472 wssid_e->info = kzalloc(sizeof(struct wlp_wss_tmp_info), GFP_KERNEL); 473 if (wssid_e->info == NULL) { 474 dev_err(dev, "WLP: unable to allocate memory " 475 "for temporary WSS information.\n"); 476 kfree(wssid_e); 477 wssid_e = NULL; 478 goto error_alloc; 479 } 480 list_add(&wssid_e->node, &neighbor->wssid); 481error_alloc: 482 return wssid_e; 483} 484 485/** 486 * Parse WSS information attribute 487 * 488 * @attr: pointer to WSS information attribute header 489 * @buflen: size of buffer in which WSS information attribute appears 490 * @wssid: will place wssid from WSS info attribute in this location 491 * @wss_info: will place other information from WSS information attribute 492 * in this location 493 * 494 * memory for @wssid and @wss_info must be allocated when calling this 495 */ 496static ssize_t wlp_get_wss_info(struct wlp *wlp, struct wlp_attr_wss_info *attr, 497 size_t buflen, struct wlp_uuid *wssid, 498 struct wlp_wss_tmp_info *wss_info) 499{ 500 struct device *dev = &wlp->rc->uwb_dev.dev; 501 ssize_t result; 502 size_t len; 503 size_t used = 0; 504 void *ptr; 505 506 result = wlp_check_wss_info_attr_hdr(wlp, (struct wlp_attr_hdr *)attr, 507 buflen); 508 if (result < 0) 509 goto out; 510 len = result; 511 used = sizeof(*attr); 512 ptr = attr; 513 514 result = wlp_get_wssid(wlp, ptr + used, wssid, buflen - used); 515 if (result < 0) { 516 dev_err(dev, "WLP: unable to obtain WSSID from WSS info.\n"); 517 goto out; 518 } 519 used += result; 520 result = wlp_get_wss_info_attrs(wlp, ptr + used, wss_info, 521 buflen - used); 522 if (result < 0) { 523 dev_err(dev, "WLP: unable to obtain WSS information " 524 "from WSS information attributes. \n"); 525 goto out; 526 } 527 used += result; 528 if (len + sizeof(*attr) != used) { 529 dev_err(dev, "WLP: Amount of data parsed does not " 530 "match length field. Parsed %zu, length " 531 "field %zu. \n", used, len); 532 result = -EINVAL; 533 goto out; 534 } 535 result = used; 536out: 537 return result; 538} 539 540/** 541 * Retrieve WSS info from association frame 542 * 543 * @attr: pointer to WSS information attribute 544 * @neighbor: ptr to neighbor being discovered, NULL if enrollment in 545 * progress 546 * @wss: ptr to WSS being enrolled in, NULL if discovery in progress 547 * @buflen: size of buffer in which WSS information appears 548 * 549 * The WSS information attribute appears in the D2 association message. 550 * This message is used in two ways: to discover all neighbors or to enroll 551 * into a WSS activated by a neighbor. During discovery we only want to 552 * store the WSS info in a cache, to be deleted right after it has been 553 * used (eg. displayed to the user). During enrollment we store the WSS 554 * information for the lifetime of enrollment. 555 * 556 * During discovery we are interested in all WSS information, during 557 * enrollment we are only interested in the WSS being enrolled in. Even so, 558 * when in enrollment we keep parsing the message after finding the WSS of 559 * interest, this simplifies the calling routine in that it can be sure 560 * that all WSS information attributes have been parsed out of the message. 561 * 562 * Association frame is process with nbmutex held. The list access is safe. 563 */ 564static ssize_t wlp_get_all_wss_info(struct wlp *wlp, 565 struct wlp_attr_wss_info *attr, 566 struct wlp_neighbor_e *neighbor, 567 struct wlp_wss *wss, ssize_t buflen) 568{ 569 struct device *dev = &wlp->rc->uwb_dev.dev; 570 size_t used = 0; 571 ssize_t result = -EINVAL; 572 struct wlp_attr_wss_info *cur; 573 struct wlp_uuid wssid; 574 struct wlp_wss_tmp_info wss_info; 575 unsigned enroll; /* 0 - discovery to cache, 1 - enrollment */ 576 struct wlp_wssid_e *wssid_e; 577 char buf[WLP_WSS_UUID_STRSIZE]; 578 579 if (buflen < 0) 580 goto out; 581 582 if (neighbor != NULL && wss == NULL) 583 enroll = 0; /* discovery */ 584 else if (wss != NULL && neighbor == NULL) 585 enroll = 1; /* enrollment */ 586 else 587 goto out; 588 589 cur = attr; 590 while (buflen - used > 0) { 591 memset(&wss_info, 0, sizeof(wss_info)); 592 cur = (void *)cur + used; 593 result = wlp_get_wss_info(wlp, cur, buflen - used, &wssid, 594 &wss_info); 595 if (result == -ENODATA) { 596 result = used; 597 goto out; 598 } else if (result < 0) { 599 dev_err(dev, "WLP: Unable to parse WSS information " 600 "from WSS information attribute. \n"); 601 result = -EINVAL; 602 goto error_parse; 603 } 604 if (enroll && !memcmp(&wssid, &wss->wssid, sizeof(wssid))) { 605 if (wss_info.accept_enroll != 1) { 606 dev_err(dev, "WLP: Requested WSS does " 607 "not accept enrollment.\n"); 608 result = -EINVAL; 609 goto out; 610 } 611 memcpy(wss->name, wss_info.name, sizeof(wss->name)); 612 wss->bcast = wss_info.bcast; 613 wss->secure_status = wss_info.sec_status; 614 wss->accept_enroll = wss_info.accept_enroll; 615 wss->state = WLP_WSS_STATE_PART_ENROLLED; 616 wlp_wss_uuid_print(buf, sizeof(buf), &wssid); 617 dev_dbg(dev, "WLP: Found WSS %s. Enrolling.\n", buf); 618 } else { 619 wssid_e = wlp_create_wssid_e(wlp, neighbor); 620 if (wssid_e == NULL) { 621 dev_err(dev, "WLP: Cannot create new WSSID " 622 "entry for neighbor %02x:%02x.\n", 623 neighbor->uwb_dev->dev_addr.data[1], 624 neighbor->uwb_dev->dev_addr.data[0]); 625 result = -ENOMEM; 626 goto out; 627 } 628 wssid_e->wssid = wssid; 629 *wssid_e->info = wss_info; 630 } 631 used += result; 632 } 633 result = used; 634error_parse: 635 if (result < 0 && !enroll) /* this was a discovery */ 636 wlp_remove_neighbor_tmp_info(neighbor); 637out: 638 return result; 639 640} 641 642/** 643 * Parse WSS information attributes into cache for discovery 644 * 645 * @attr: the first WSS information attribute in message 646 * @neighbor: the neighbor whose cache will be populated 647 * @buflen: size of the input buffer 648 */ 649static ssize_t wlp_get_wss_info_to_cache(struct wlp *wlp, 650 struct wlp_attr_wss_info *attr, 651 struct wlp_neighbor_e *neighbor, 652 ssize_t buflen) 653{ 654 return wlp_get_all_wss_info(wlp, attr, neighbor, NULL, buflen); 655} 656 657/** 658 * Parse WSS information attributes into WSS struct for enrollment 659 * 660 * @attr: the first WSS information attribute in message 661 * @wss: the WSS that will be enrolled 662 * @buflen: size of the input buffer 663 */ 664static ssize_t wlp_get_wss_info_to_enroll(struct wlp *wlp, 665 struct wlp_attr_wss_info *attr, 666 struct wlp_wss *wss, ssize_t buflen) 667{ 668 return wlp_get_all_wss_info(wlp, attr, NULL, wss, buflen); 669} 670 671/** 672 * Construct a D1 association frame 673 * 674 * We use the radio control functions to determine the values of the device 675 * properties. These are of variable length and the total space needed is 676 * tallied first before we start constructing the message. The radio 677 * control functions return strings that are terminated with \0. This 678 * character should not be included in the message (there is a length field 679 * accompanying it in the attribute). 680 */ 681static int wlp_build_assoc_d1(struct wlp *wlp, struct wlp_wss *wss, 682 struct sk_buff **skb) 683{ 684 685 struct device *dev = &wlp->rc->uwb_dev.dev; 686 int result = 0; 687 struct wlp_device_info *info; 688 size_t used = 0; 689 struct wlp_frame_assoc *_d1; 690 struct sk_buff *_skb; 691 void *d1_itr; 692 693 if (wlp->dev_info == NULL) { 694 result = __wlp_setup_device_info(wlp); 695 if (result < 0) { 696 dev_err(dev, "WLP: Unable to setup device " 697 "information for D1 message.\n"); 698 goto error; 699 } 700 } 701 info = wlp->dev_info; 702 _skb = dev_alloc_skb(sizeof(*_d1) 703 + sizeof(struct wlp_attr_uuid_e) 704 + sizeof(struct wlp_attr_wss_sel_mthd) 705 + sizeof(struct wlp_attr_dev_name) 706 + strlen(info->name) 707 + sizeof(struct wlp_attr_manufacturer) 708 + strlen(info->manufacturer) 709 + sizeof(struct wlp_attr_model_name) 710 + strlen(info->model_name) 711 + sizeof(struct wlp_attr_model_nr) 712 + strlen(info->model_nr) 713 + sizeof(struct wlp_attr_serial) 714 + strlen(info->serial) 715 + sizeof(struct wlp_attr_prim_dev_type) 716 + sizeof(struct wlp_attr_wlp_assc_err)); 717 if (_skb == NULL) { 718 dev_err(dev, "WLP: Cannot allocate memory for association " 719 "message.\n"); 720 result = -ENOMEM; 721 goto error; 722 } 723 _d1 = (void *) _skb->data; 724 _d1->hdr.mux_hdr = cpu_to_le16(WLP_PROTOCOL_ID); 725 _d1->hdr.type = WLP_FRAME_ASSOCIATION; 726 _d1->type = WLP_ASSOC_D1; 727 728 wlp_set_version(&_d1->version, WLP_VERSION); 729 wlp_set_msg_type(&_d1->msg_type, WLP_ASSOC_D1); 730 d1_itr = _d1->attr; 731 used = wlp_set_uuid_e(d1_itr, &wlp->uuid); 732 used += wlp_set_wss_sel_mthd(d1_itr + used, WLP_WSS_REG_SELECT); 733 used += wlp_set_dev_name(d1_itr + used, info->name, 734 strlen(info->name)); 735 used += wlp_set_manufacturer(d1_itr + used, info->manufacturer, 736 strlen(info->manufacturer)); 737 used += wlp_set_model_name(d1_itr + used, info->model_name, 738 strlen(info->model_name)); 739 used += wlp_set_model_nr(d1_itr + used, info->model_nr, 740 strlen(info->model_nr)); 741 used += wlp_set_serial(d1_itr + used, info->serial, 742 strlen(info->serial)); 743 used += wlp_set_prim_dev_type(d1_itr + used, &info->prim_dev_type); 744 used += wlp_set_wlp_assc_err(d1_itr + used, WLP_ASSOC_ERROR_NONE); 745 skb_put(_skb, sizeof(*_d1) + used); 746 *skb = _skb; 747error: 748 return result; 749} 750 751/** 752 * Construct a D2 association frame 753 * 754 * We use the radio control functions to determine the values of the device 755 * properties. These are of variable length and the total space needed is 756 * tallied first before we start constructing the message. The radio 757 * control functions return strings that are terminated with \0. This 758 * character should not be included in the message (there is a length field 759 * accompanying it in the attribute). 760 */ 761static 762int wlp_build_assoc_d2(struct wlp *wlp, struct wlp_wss *wss, 763 struct sk_buff **skb, struct wlp_uuid *uuid_e) 764{ 765 766 struct device *dev = &wlp->rc->uwb_dev.dev; 767 int result = 0; 768 struct wlp_device_info *info; 769 size_t used = 0; 770 struct wlp_frame_assoc *_d2; 771 struct sk_buff *_skb; 772 void *d2_itr; 773 size_t mem_needed; 774 775 if (wlp->dev_info == NULL) { 776 result = __wlp_setup_device_info(wlp); 777 if (result < 0) { 778 dev_err(dev, "WLP: Unable to setup device " 779 "information for D2 message.\n"); 780 goto error; 781 } 782 } 783 info = wlp->dev_info; 784 mem_needed = sizeof(*_d2) 785 + sizeof(struct wlp_attr_uuid_e) 786 + sizeof(struct wlp_attr_uuid_r) 787 + sizeof(struct wlp_attr_dev_name) 788 + strlen(info->name) 789 + sizeof(struct wlp_attr_manufacturer) 790 + strlen(info->manufacturer) 791 + sizeof(struct wlp_attr_model_name) 792 + strlen(info->model_name) 793 + sizeof(struct wlp_attr_model_nr) 794 + strlen(info->model_nr) 795 + sizeof(struct wlp_attr_serial) 796 + strlen(info->serial) 797 + sizeof(struct wlp_attr_prim_dev_type) 798 + sizeof(struct wlp_attr_wlp_assc_err); 799 if (wlp->wss.state >= WLP_WSS_STATE_ACTIVE) 800 mem_needed += sizeof(struct wlp_attr_wss_info) 801 + sizeof(struct wlp_wss_info) 802 + strlen(wlp->wss.name); 803 _skb = dev_alloc_skb(mem_needed); 804 if (_skb == NULL) { 805 dev_err(dev, "WLP: Cannot allocate memory for association " 806 "message.\n"); 807 result = -ENOMEM; 808 goto error; 809 } 810 _d2 = (void *) _skb->data; 811 _d2->hdr.mux_hdr = cpu_to_le16(WLP_PROTOCOL_ID); 812 _d2->hdr.type = WLP_FRAME_ASSOCIATION; 813 _d2->type = WLP_ASSOC_D2; 814 815 wlp_set_version(&_d2->version, WLP_VERSION); 816 wlp_set_msg_type(&_d2->msg_type, WLP_ASSOC_D2); 817 d2_itr = _d2->attr; 818 used = wlp_set_uuid_e(d2_itr, uuid_e); 819 used += wlp_set_uuid_r(d2_itr + used, &wlp->uuid); 820 if (wlp->wss.state >= WLP_WSS_STATE_ACTIVE) 821 used += wlp_set_wss_info(d2_itr + used, &wlp->wss); 822 used += wlp_set_dev_name(d2_itr + used, info->name, 823 strlen(info->name)); 824 used += wlp_set_manufacturer(d2_itr + used, info->manufacturer, 825 strlen(info->manufacturer)); 826 used += wlp_set_model_name(d2_itr + used, info->model_name, 827 strlen(info->model_name)); 828 used += wlp_set_model_nr(d2_itr + used, info->model_nr, 829 strlen(info->model_nr)); 830 used += wlp_set_serial(d2_itr + used, info->serial, 831 strlen(info->serial)); 832 used += wlp_set_prim_dev_type(d2_itr + used, &info->prim_dev_type); 833 used += wlp_set_wlp_assc_err(d2_itr + used, WLP_ASSOC_ERROR_NONE); 834 skb_put(_skb, sizeof(*_d2) + used); 835 *skb = _skb; 836error: 837 return result; 838} 839 840/** 841 * Allocate memory for and populate fields of F0 association frame 842 * 843 * Currently (while focusing on unsecure enrollment) we ignore the 844 * nonce's that could be placed in the message. Only the error field is 845 * populated by the value provided by the caller. 846 */ 847static 848int wlp_build_assoc_f0(struct wlp *wlp, struct sk_buff **skb, 849 enum wlp_assc_error error) 850{ 851 struct device *dev = &wlp->rc->uwb_dev.dev; 852 int result = -ENOMEM; 853 struct { 854 struct wlp_frame_assoc f0_hdr; 855 struct wlp_attr_enonce enonce; 856 struct wlp_attr_rnonce rnonce; 857 struct wlp_attr_wlp_assc_err assc_err; 858 } *f0; 859 struct sk_buff *_skb; 860 struct wlp_nonce tmp; 861 862 _skb = dev_alloc_skb(sizeof(*f0)); 863 if (_skb == NULL) { 864 dev_err(dev, "WLP: Unable to allocate memory for F0 " 865 "association frame. \n"); 866 goto error_alloc; 867 } 868 f0 = (void *) _skb->data; 869 f0->f0_hdr.hdr.mux_hdr = cpu_to_le16(WLP_PROTOCOL_ID); 870 f0->f0_hdr.hdr.type = WLP_FRAME_ASSOCIATION; 871 f0->f0_hdr.type = WLP_ASSOC_F0; 872 wlp_set_version(&f0->f0_hdr.version, WLP_VERSION); 873 wlp_set_msg_type(&f0->f0_hdr.msg_type, WLP_ASSOC_F0); 874 memset(&tmp, 0, sizeof(tmp)); 875 wlp_set_enonce(&f0->enonce, &tmp); 876 wlp_set_rnonce(&f0->rnonce, &tmp); 877 wlp_set_wlp_assc_err(&f0->assc_err, error); 878 skb_put(_skb, sizeof(*f0)); 879 *skb = _skb; 880 result = 0; 881error_alloc: 882 return result; 883} 884 885/** 886 * Parse F0 frame 887 * 888 * We just retrieve the values and print it as an error to the user. 889 * Calling function already knows an error occured (F0 indicates error), so 890 * we just parse the content as debug for higher layers. 891 */ 892int wlp_parse_f0(struct wlp *wlp, struct sk_buff *skb) 893{ 894 struct device *dev = &wlp->rc->uwb_dev.dev; 895 struct wlp_frame_assoc *f0 = (void *) skb->data; 896 void *ptr = skb->data; 897 size_t len = skb->len; 898 size_t used; 899 ssize_t result; 900 struct wlp_nonce enonce, rnonce; 901 enum wlp_assc_error assc_err; 902 char enonce_buf[WLP_WSS_NONCE_STRSIZE]; 903 char rnonce_buf[WLP_WSS_NONCE_STRSIZE]; 904 905 used = sizeof(*f0); 906 result = wlp_get_enonce(wlp, ptr + used, &enonce, len - used); 907 if (result < 0) { 908 dev_err(dev, "WLP: unable to obtain Enrollee nonce " 909 "attribute from F0 message.\n"); 910 goto error_parse; 911 } 912 used += result; 913 result = wlp_get_rnonce(wlp, ptr + used, &rnonce, len - used); 914 if (result < 0) { 915 dev_err(dev, "WLP: unable to obtain Registrar nonce " 916 "attribute from F0 message.\n"); 917 goto error_parse; 918 } 919 used += result; 920 result = wlp_get_wlp_assc_err(wlp, ptr + used, &assc_err, len - used); 921 if (result < 0) { 922 dev_err(dev, "WLP: unable to obtain WLP Association error " 923 "attribute from F0 message.\n"); 924 goto error_parse; 925 } 926 wlp_wss_nonce_print(enonce_buf, sizeof(enonce_buf), &enonce); 927 wlp_wss_nonce_print(rnonce_buf, sizeof(rnonce_buf), &rnonce); 928 dev_err(dev, "WLP: Received F0 error frame from neighbor. Enrollee " 929 "nonce: %s, Registrar nonce: %s, WLP Association error: %s.\n", 930 enonce_buf, rnonce_buf, wlp_assc_error_str(assc_err)); 931 result = 0; 932error_parse: 933 return result; 934} 935 936/** 937 * Retrieve variable device information from association message 938 * 939 * The device information parsed is not required in any message. This 940 * routine will thus not fail if an attribute is not present. 941 * The attributes are expected in a certain order, even if all are not 942 * present. The "attribute type" value is used to ensure the attributes 943 * are parsed in the correct order. 944 * 945 * If an error is encountered during parsing the function will return an 946 * error code, when this happens the given device_info structure may be 947 * partially filled. 948 */ 949static 950int wlp_get_variable_info(struct wlp *wlp, void *data, 951 struct wlp_device_info *dev_info, ssize_t len) 952{ 953 struct device *dev = &wlp->rc->uwb_dev.dev; 954 size_t used = 0; 955 struct wlp_attr_hdr *hdr; 956 ssize_t result = 0; 957 unsigned last = 0; 958 959 while (len - used > 0) { 960 if (len - used < sizeof(*hdr)) { 961 dev_err(dev, "WLP: Partial data in frame, cannot " 962 "parse. \n"); 963 goto error_parse; 964 } 965 hdr = data + used; 966 switch (le16_to_cpu(hdr->type)) { 967 case WLP_ATTR_MANUF: 968 if (last >= WLP_ATTR_MANUF) { 969 dev_err(dev, "WLP: Incorrect order of " 970 "attribute values in D1 msg.\n"); 971 goto error_parse; 972 } 973 result = wlp_get_manufacturer(wlp, data + used, 974 dev_info->manufacturer, 975 len - used); 976 if (result < 0) { 977 dev_err(dev, "WLP: Unable to obtain " 978 "Manufacturer attribute from D1 " 979 "message.\n"); 980 goto error_parse; 981 } 982 last = WLP_ATTR_MANUF; 983 used += result; 984 break; 985 case WLP_ATTR_MODEL_NAME: 986 if (last >= WLP_ATTR_MODEL_NAME) { 987 dev_err(dev, "WLP: Incorrect order of " 988 "attribute values in D1 msg.\n"); 989 goto error_parse; 990 } 991 result = wlp_get_model_name(wlp, data + used, 992 dev_info->model_name, 993 len - used); 994 if (result < 0) { 995 dev_err(dev, "WLP: Unable to obtain Model " 996 "name attribute from D1 message.\n"); 997 goto error_parse; 998 } 999 last = WLP_ATTR_MODEL_NAME; 1000 used += result; 1001 break; 1002 case WLP_ATTR_MODEL_NR: 1003 if (last >= WLP_ATTR_MODEL_NR) { 1004 dev_err(dev, "WLP: Incorrect order of " 1005 "attribute values in D1 msg.\n"); 1006 goto error_parse; 1007 } 1008 result = wlp_get_model_nr(wlp, data + used, 1009 dev_info->model_nr, 1010 len - used); 1011 if (result < 0) { 1012 dev_err(dev, "WLP: Unable to obtain Model " 1013 "number attribute from D1 message.\n"); 1014 goto error_parse; 1015 } 1016 last = WLP_ATTR_MODEL_NR; 1017 used += result; 1018 break; 1019 case WLP_ATTR_SERIAL: 1020 if (last >= WLP_ATTR_SERIAL) { 1021 dev_err(dev, "WLP: Incorrect order of " 1022 "attribute values in D1 msg.\n"); 1023 goto error_parse; 1024 } 1025 result = wlp_get_serial(wlp, data + used, 1026 dev_info->serial, len - used); 1027 if (result < 0) { 1028 dev_err(dev, "WLP: Unable to obtain Serial " 1029 "number attribute from D1 message.\n"); 1030 goto error_parse; 1031 } 1032 last = WLP_ATTR_SERIAL; 1033 used += result; 1034 break; 1035 case WLP_ATTR_PRI_DEV_TYPE: 1036 if (last >= WLP_ATTR_PRI_DEV_TYPE) { 1037 dev_err(dev, "WLP: Incorrect order of " 1038 "attribute values in D1 msg.\n"); 1039 goto error_parse; 1040 } 1041 result = wlp_get_prim_dev_type(wlp, data + used, 1042 &dev_info->prim_dev_type, 1043 len - used); 1044 if (result < 0) { 1045 dev_err(dev, "WLP: Unable to obtain Primary " 1046 "device type attribute from D1 " 1047 "message.\n"); 1048 goto error_parse; 1049 } 1050 dev_info->prim_dev_type.category = 1051 le16_to_cpu(dev_info->prim_dev_type.category); 1052 dev_info->prim_dev_type.subID = 1053 le16_to_cpu(dev_info->prim_dev_type.subID); 1054 last = WLP_ATTR_PRI_DEV_TYPE; 1055 used += result; 1056 break; 1057 default: 1058 /* This is not variable device information. */ 1059 goto out; 1060 break; 1061 } 1062 } 1063out: 1064 return used; 1065error_parse: 1066 return -EINVAL; 1067} 1068 1069/** 1070 * Parse incoming D1 frame, populate attribute values 1071 * 1072 * Caller provides pointers to memory already allocated for attributes 1073 * expected in the D1 frame. These variables will be populated. 1074 */ 1075static 1076int wlp_parse_d1_frame(struct wlp *wlp, struct sk_buff *skb, 1077 struct wlp_uuid *uuid_e, 1078 enum wlp_wss_sel_mthd *sel_mthd, 1079 struct wlp_device_info *dev_info, 1080 enum wlp_assc_error *assc_err) 1081{ 1082 struct device *dev = &wlp->rc->uwb_dev.dev; 1083 struct wlp_frame_assoc *d1 = (void *) skb->data; 1084 void *ptr = skb->data; 1085 size_t len = skb->len; 1086 size_t used; 1087 ssize_t result; 1088 1089 used = sizeof(*d1); 1090 result = wlp_get_uuid_e(wlp, ptr + used, uuid_e, len - used); 1091 if (result < 0) { 1092 dev_err(dev, "WLP: unable to obtain UUID-E attribute from D1 " 1093 "message.\n"); 1094 goto error_parse; 1095 } 1096 used += result; 1097 result = wlp_get_wss_sel_mthd(wlp, ptr + used, sel_mthd, len - used); 1098 if (result < 0) { 1099 dev_err(dev, "WLP: unable to obtain WSS selection method " 1100 "from D1 message.\n"); 1101 goto error_parse; 1102 } 1103 used += result; 1104 result = wlp_get_dev_name(wlp, ptr + used, dev_info->name, 1105 len - used); 1106 if (result < 0) { 1107 dev_err(dev, "WLP: unable to obtain Device Name from D1 " 1108 "message.\n"); 1109 goto error_parse; 1110 } 1111 used += result; 1112 result = wlp_get_variable_info(wlp, ptr + used, dev_info, len - used); 1113 if (result < 0) { 1114 dev_err(dev, "WLP: unable to obtain Device Information from " 1115 "D1 message.\n"); 1116 goto error_parse; 1117 } 1118 used += result; 1119 result = wlp_get_wlp_assc_err(wlp, ptr + used, assc_err, len - used); 1120 if (result < 0) { 1121 dev_err(dev, "WLP: unable to obtain WLP Association Error " 1122 "Information from D1 message.\n"); 1123 goto error_parse; 1124 } 1125 result = 0; 1126error_parse: 1127 return result; 1128} 1129/** 1130 * Handle incoming D1 frame 1131 * 1132 * The frame has already been verified to contain an Association header with 1133 * the correct version number. Parse the incoming frame, construct and send 1134 * a D2 frame in response. 1135 * 1136 * It is not clear what to do with most fields in the incoming D1 frame. We 1137 * retrieve and discard the information here for now. 1138 */ 1139void wlp_handle_d1_frame(struct work_struct *ws) 1140{ 1141 struct wlp_assoc_frame_ctx *frame_ctx = container_of(ws, 1142 struct wlp_assoc_frame_ctx, 1143 ws); 1144 struct wlp *wlp = frame_ctx->wlp; 1145 struct wlp_wss *wss = &wlp->wss; 1146 struct sk_buff *skb = frame_ctx->skb; 1147 struct uwb_dev_addr *src = &frame_ctx->src; 1148 int result; 1149 struct device *dev = &wlp->rc->uwb_dev.dev; 1150 struct wlp_uuid uuid_e; 1151 enum wlp_wss_sel_mthd sel_mthd = 0; 1152 struct wlp_device_info dev_info; 1153 enum wlp_assc_error assc_err; 1154 struct sk_buff *resp = NULL; 1155 1156 /* Parse D1 frame */ 1157 mutex_lock(&wss->mutex); 1158 mutex_lock(&wlp->mutex); /* to access wlp->uuid */ 1159 memset(&dev_info, 0, sizeof(dev_info)); 1160 result = wlp_parse_d1_frame(wlp, skb, &uuid_e, &sel_mthd, &dev_info, 1161 &assc_err); 1162 if (result < 0) { 1163 dev_err(dev, "WLP: Unable to parse incoming D1 frame.\n"); 1164 kfree_skb(skb); 1165 goto out; 1166 } 1167 1168 kfree_skb(skb); 1169 if (!wlp_uuid_is_set(&wlp->uuid)) { 1170 dev_err(dev, "WLP: UUID is not set. Set via sysfs to " 1171 "proceed. Respong to D1 message with error F0.\n"); 1172 result = wlp_build_assoc_f0(wlp, &resp, 1173 WLP_ASSOC_ERROR_NOT_READY); 1174 if (result < 0) { 1175 dev_err(dev, "WLP: Unable to construct F0 message.\n"); 1176 goto out; 1177 } 1178 } else { 1179 /* Construct D2 frame */ 1180 result = wlp_build_assoc_d2(wlp, wss, &resp, &uuid_e); 1181 if (result < 0) { 1182 dev_err(dev, "WLP: Unable to construct D2 message.\n"); 1183 goto out; 1184 } 1185 } 1186 /* Send D2 frame */ 1187 BUG_ON(wlp->xmit_frame == NULL); 1188 result = wlp->xmit_frame(wlp, resp, src); 1189 if (result < 0) { 1190 dev_err(dev, "WLP: Unable to transmit D2 association " 1191 "message: %d\n", result); 1192 if (result == -ENXIO) 1193 dev_err(dev, "WLP: Is network interface up? \n"); 1194 /* We could try again ... */ 1195 dev_kfree_skb_any(resp); /* we need to free if tx fails */ 1196 } 1197out: 1198 kfree(frame_ctx); 1199 mutex_unlock(&wlp->mutex); 1200 mutex_unlock(&wss->mutex); 1201} 1202 1203/** 1204 * Parse incoming D2 frame, create and populate temporary cache 1205 * 1206 * @skb: socket buffer in which D2 frame can be found 1207 * @neighbor: the neighbor that sent the D2 frame 1208 * 1209 * Will allocate memory for temporary storage of information learned during 1210 * discovery. 1211 */ 1212int wlp_parse_d2_frame_to_cache(struct wlp *wlp, struct sk_buff *skb, 1213 struct wlp_neighbor_e *neighbor) 1214{ 1215 struct device *dev = &wlp->rc->uwb_dev.dev; 1216 struct wlp_frame_assoc *d2 = (void *) skb->data; 1217 void *ptr = skb->data; 1218 size_t len = skb->len; 1219 size_t used; 1220 ssize_t result; 1221 struct wlp_uuid uuid_e; 1222 struct wlp_device_info *nb_info; 1223 enum wlp_assc_error assc_err; 1224 1225 used = sizeof(*d2); 1226 result = wlp_get_uuid_e(wlp, ptr + used, &uuid_e, len - used); 1227 if (result < 0) { 1228 dev_err(dev, "WLP: unable to obtain UUID-E attribute from D2 " 1229 "message.\n"); 1230 goto error_parse; 1231 } 1232 if (memcmp(&uuid_e, &wlp->uuid, sizeof(uuid_e))) { 1233 dev_err(dev, "WLP: UUID-E in incoming D2 does not match " 1234 "local UUID sent in D1. \n"); 1235 goto error_parse; 1236 } 1237 used += result; 1238 result = wlp_get_uuid_r(wlp, ptr + used, &neighbor->uuid, len - used); 1239 if (result < 0) { 1240 dev_err(dev, "WLP: unable to obtain UUID-R attribute from D2 " 1241 "message.\n"); 1242 goto error_parse; 1243 } 1244 used += result; 1245 result = wlp_get_wss_info_to_cache(wlp, ptr + used, neighbor, 1246 len - used); 1247 if (result < 0) { 1248 dev_err(dev, "WLP: unable to obtain WSS information " 1249 "from D2 message.\n"); 1250 goto error_parse; 1251 } 1252 used += result; 1253 neighbor->info = kzalloc(sizeof(struct wlp_device_info), GFP_KERNEL); 1254 if (neighbor->info == NULL) { 1255 dev_err(dev, "WLP: cannot allocate memory to store device " 1256 "info.\n"); 1257 result = -ENOMEM; 1258 goto error_parse; 1259 } 1260 nb_info = neighbor->info; 1261 result = wlp_get_dev_name(wlp, ptr + used, nb_info->name, 1262 len - used); 1263 if (result < 0) { 1264 dev_err(dev, "WLP: unable to obtain Device Name from D2 " 1265 "message.\n"); 1266 goto error_parse; 1267 } 1268 used += result; 1269 result = wlp_get_variable_info(wlp, ptr + used, nb_info, len - used); 1270 if (result < 0) { 1271 dev_err(dev, "WLP: unable to obtain Device Information from " 1272 "D2 message.\n"); 1273 goto error_parse; 1274 } 1275 used += result; 1276 result = wlp_get_wlp_assc_err(wlp, ptr + used, &assc_err, len - used); 1277 if (result < 0) { 1278 dev_err(dev, "WLP: unable to obtain WLP Association Error " 1279 "Information from D2 message.\n"); 1280 goto error_parse; 1281 } 1282 if (assc_err != WLP_ASSOC_ERROR_NONE) { 1283 dev_err(dev, "WLP: neighbor device returned association " 1284 "error %d\n", assc_err); 1285 result = -EINVAL; 1286 goto error_parse; 1287 } 1288 result = 0; 1289error_parse: 1290 if (result < 0) 1291 wlp_remove_neighbor_tmp_info(neighbor); 1292 return result; 1293} 1294 1295/** 1296 * Parse incoming D2 frame, populate attribute values of WSS bein enrolled in 1297 * 1298 * @wss: our WSS that will be enrolled 1299 * @skb: socket buffer in which D2 frame can be found 1300 * @neighbor: the neighbor that sent the D2 frame 1301 * @wssid: the wssid of the WSS in which we want to enroll 1302 * 1303 * Forms part of enrollment sequence. We are trying to enroll in WSS with 1304 * @wssid by using @neighbor as registrar. A D1 message was sent to 1305 * @neighbor and now we need to parse the D2 response. The neighbor's 1306 * response is searched for the requested WSS and if found (and it accepts 1307 * enrollment), we store the information. 1308 */ 1309int wlp_parse_d2_frame_to_enroll(struct wlp_wss *wss, struct sk_buff *skb, 1310 struct wlp_neighbor_e *neighbor, 1311 struct wlp_uuid *wssid) 1312{ 1313 struct wlp *wlp = container_of(wss, struct wlp, wss); 1314 struct device *dev = &wlp->rc->uwb_dev.dev; 1315 void *ptr = skb->data; 1316 size_t len = skb->len; 1317 size_t used; 1318 ssize_t result; 1319 struct wlp_uuid uuid_e; 1320 struct wlp_uuid uuid_r; 1321 struct wlp_device_info nb_info; 1322 enum wlp_assc_error assc_err; 1323 char uuid_bufA[WLP_WSS_UUID_STRSIZE]; 1324 char uuid_bufB[WLP_WSS_UUID_STRSIZE]; 1325 1326 used = sizeof(struct wlp_frame_assoc); 1327 result = wlp_get_uuid_e(wlp, ptr + used, &uuid_e, len - used); 1328 if (result < 0) { 1329 dev_err(dev, "WLP: unable to obtain UUID-E attribute from D2 " 1330 "message.\n"); 1331 goto error_parse; 1332 } 1333 if (memcmp(&uuid_e, &wlp->uuid, sizeof(uuid_e))) { 1334 dev_err(dev, "WLP: UUID-E in incoming D2 does not match " 1335 "local UUID sent in D1. \n"); 1336 goto error_parse; 1337 } 1338 used += result; 1339 result = wlp_get_uuid_r(wlp, ptr + used, &uuid_r, len - used); 1340 if (result < 0) { 1341 dev_err(dev, "WLP: unable to obtain UUID-R attribute from D2 " 1342 "message.\n"); 1343 goto error_parse; 1344 } 1345 if (memcmp(&uuid_r, &neighbor->uuid, sizeof(uuid_r))) { 1346 wlp_wss_uuid_print(uuid_bufA, sizeof(uuid_bufA), 1347 &neighbor->uuid); 1348 wlp_wss_uuid_print(uuid_bufB, sizeof(uuid_bufB), &uuid_r); 1349 dev_err(dev, "WLP: UUID of neighbor does not match UUID " 1350 "learned during discovery. Originally discovered: %s, " 1351 "now from D2 message: %s\n", uuid_bufA, uuid_bufB); 1352 result = -EINVAL; 1353 goto error_parse; 1354 } 1355 used += result; 1356 wss->wssid = *wssid; 1357 result = wlp_get_wss_info_to_enroll(wlp, ptr + used, wss, len - used); 1358 if (result < 0) { 1359 dev_err(dev, "WLP: unable to obtain WSS information " 1360 "from D2 message.\n"); 1361 goto error_parse; 1362 } 1363 if (wss->state != WLP_WSS_STATE_PART_ENROLLED) { 1364 dev_err(dev, "WLP: D2 message did not contain information " 1365 "for successful enrollment. \n"); 1366 result = -EINVAL; 1367 goto error_parse; 1368 } 1369 used += result; 1370 /* Place device information on stack to continue parsing of message */ 1371 result = wlp_get_dev_name(wlp, ptr + used, nb_info.name, 1372 len - used); 1373 if (result < 0) { 1374 dev_err(dev, "WLP: unable to obtain Device Name from D2 " 1375 "message.\n"); 1376 goto error_parse; 1377 } 1378 used += result; 1379 result = wlp_get_variable_info(wlp, ptr + used, &nb_info, len - used); 1380 if (result < 0) { 1381 dev_err(dev, "WLP: unable to obtain Device Information from " 1382 "D2 message.\n"); 1383 goto error_parse; 1384 } 1385 used += result; 1386 result = wlp_get_wlp_assc_err(wlp, ptr + used, &assc_err, len - used); 1387 if (result < 0) { 1388 dev_err(dev, "WLP: unable to obtain WLP Association Error " 1389 "Information from D2 message.\n"); 1390 goto error_parse; 1391 } 1392 if (assc_err != WLP_ASSOC_ERROR_NONE) { 1393 dev_err(dev, "WLP: neighbor device returned association " 1394 "error %d\n", assc_err); 1395 if (wss->state == WLP_WSS_STATE_PART_ENROLLED) { 1396 dev_err(dev, "WLP: Enrolled in WSS (should not " 1397 "happen according to spec). Undoing. \n"); 1398 wlp_wss_reset(wss); 1399 } 1400 result = -EINVAL; 1401 goto error_parse; 1402 } 1403 result = 0; 1404error_parse: 1405 return result; 1406} 1407 1408/** 1409 * Parse C3/C4 frame into provided variables 1410 * 1411 * @wssid: will point to copy of wssid retrieved from C3/C4 frame 1412 * @tag: will point to copy of tag retrieved from C3/C4 frame 1413 * @virt_addr: will point to copy of virtual address retrieved from C3/C4 1414 * frame. 1415 * 1416 * Calling function has to allocate memory for these values. 1417 * 1418 * skb contains a valid C3/C4 frame, return the individual fields of this 1419 * frame in the provided variables. 1420 */ 1421int wlp_parse_c3c4_frame(struct wlp *wlp, struct sk_buff *skb, 1422 struct wlp_uuid *wssid, u8 *tag, 1423 struct uwb_mac_addr *virt_addr) 1424{ 1425 struct device *dev = &wlp->rc->uwb_dev.dev; 1426 int result; 1427 void *ptr = skb->data; 1428 size_t len = skb->len; 1429 size_t used; 1430 struct wlp_frame_assoc *assoc = ptr; 1431 1432 used = sizeof(*assoc); 1433 result = wlp_get_wssid(wlp, ptr + used, wssid, len - used); 1434 if (result < 0) { 1435 dev_err(dev, "WLP: unable to obtain WSSID attribute from " 1436 "%s message.\n", wlp_assoc_frame_str(assoc->type)); 1437 goto error_parse; 1438 } 1439 used += result; 1440 result = wlp_get_wss_tag(wlp, ptr + used, tag, len - used); 1441 if (result < 0) { 1442 dev_err(dev, "WLP: unable to obtain WSS tag attribute from " 1443 "%s message.\n", wlp_assoc_frame_str(assoc->type)); 1444 goto error_parse; 1445 } 1446 used += result; 1447 result = wlp_get_wss_virt(wlp, ptr + used, virt_addr, len - used); 1448 if (result < 0) { 1449 dev_err(dev, "WLP: unable to obtain WSS virtual address " 1450 "attribute from %s message.\n", 1451 wlp_assoc_frame_str(assoc->type)); 1452 goto error_parse; 1453 } 1454error_parse: 1455 return result; 1456} 1457 1458/** 1459 * Allocate memory for and populate fields of C1 or C2 association frame 1460 * 1461 * The C1 and C2 association frames appear identical - except for the type. 1462 */ 1463static 1464int wlp_build_assoc_c1c2(struct wlp *wlp, struct wlp_wss *wss, 1465 struct sk_buff **skb, enum wlp_assoc_type type) 1466{ 1467 struct device *dev = &wlp->rc->uwb_dev.dev; 1468 int result = -ENOMEM; 1469 struct { 1470 struct wlp_frame_assoc c_hdr; 1471 struct wlp_attr_wssid wssid; 1472 } *c; 1473 struct sk_buff *_skb; 1474 1475 _skb = dev_alloc_skb(sizeof(*c)); 1476 if (_skb == NULL) { 1477 dev_err(dev, "WLP: Unable to allocate memory for C1/C2 " 1478 "association frame. \n"); 1479 goto error_alloc; 1480 } 1481 c = (void *) _skb->data; 1482 c->c_hdr.hdr.mux_hdr = cpu_to_le16(WLP_PROTOCOL_ID); 1483 c->c_hdr.hdr.type = WLP_FRAME_ASSOCIATION; 1484 c->c_hdr.type = type; 1485 wlp_set_version(&c->c_hdr.version, WLP_VERSION); 1486 wlp_set_msg_type(&c->c_hdr.msg_type, type); 1487 wlp_set_wssid(&c->wssid, &wss->wssid); 1488 skb_put(_skb, sizeof(*c)); 1489 *skb = _skb; 1490 result = 0; 1491error_alloc: 1492 return result; 1493} 1494 1495 1496static 1497int wlp_build_assoc_c1(struct wlp *wlp, struct wlp_wss *wss, 1498 struct sk_buff **skb) 1499{ 1500 return wlp_build_assoc_c1c2(wlp, wss, skb, WLP_ASSOC_C1); 1501} 1502 1503static 1504int wlp_build_assoc_c2(struct wlp *wlp, struct wlp_wss *wss, 1505 struct sk_buff **skb) 1506{ 1507 return wlp_build_assoc_c1c2(wlp, wss, skb, WLP_ASSOC_C2); 1508} 1509 1510 1511/** 1512 * Allocate memory for and populate fields of C3 or C4 association frame 1513 * 1514 * The C3 and C4 association frames appear identical - except for the type. 1515 */ 1516static 1517int wlp_build_assoc_c3c4(struct wlp *wlp, struct wlp_wss *wss, 1518 struct sk_buff **skb, enum wlp_assoc_type type) 1519{ 1520 struct device *dev = &wlp->rc->uwb_dev.dev; 1521 int result = -ENOMEM; 1522 struct { 1523 struct wlp_frame_assoc c_hdr; 1524 struct wlp_attr_wssid wssid; 1525 struct wlp_attr_wss_tag wss_tag; 1526 struct wlp_attr_wss_virt wss_virt; 1527 } *c; 1528 struct sk_buff *_skb; 1529 1530 _skb = dev_alloc_skb(sizeof(*c)); 1531 if (_skb == NULL) { 1532 dev_err(dev, "WLP: Unable to allocate memory for C3/C4 " 1533 "association frame. \n"); 1534 goto error_alloc; 1535 } 1536 c = (void *) _skb->data; 1537 c->c_hdr.hdr.mux_hdr = cpu_to_le16(WLP_PROTOCOL_ID); 1538 c->c_hdr.hdr.type = WLP_FRAME_ASSOCIATION; 1539 c->c_hdr.type = type; 1540 wlp_set_version(&c->c_hdr.version, WLP_VERSION); 1541 wlp_set_msg_type(&c->c_hdr.msg_type, type); 1542 wlp_set_wssid(&c->wssid, &wss->wssid); 1543 wlp_set_wss_tag(&c->wss_tag, wss->tag); 1544 wlp_set_wss_virt(&c->wss_virt, &wss->virtual_addr); 1545 skb_put(_skb, sizeof(*c)); 1546 *skb = _skb; 1547 result = 0; 1548error_alloc: 1549 return result; 1550} 1551 1552static 1553int wlp_build_assoc_c3(struct wlp *wlp, struct wlp_wss *wss, 1554 struct sk_buff **skb) 1555{ 1556 return wlp_build_assoc_c3c4(wlp, wss, skb, WLP_ASSOC_C3); 1557} 1558 1559static 1560int wlp_build_assoc_c4(struct wlp *wlp, struct wlp_wss *wss, 1561 struct sk_buff **skb) 1562{ 1563 return wlp_build_assoc_c3c4(wlp, wss, skb, WLP_ASSOC_C4); 1564} 1565 1566 1567#define wlp_send_assoc(type, id) \ 1568static int wlp_send_assoc_##type(struct wlp *wlp, struct wlp_wss *wss, \ 1569 struct uwb_dev_addr *dev_addr) \ 1570{ \ 1571 struct device *dev = &wlp->rc->uwb_dev.dev; \ 1572 int result; \ 1573 struct sk_buff *skb = NULL; \ 1574 \ 1575 /* Build the frame */ \ 1576 result = wlp_build_assoc_##type(wlp, wss, &skb); \ 1577 if (result < 0) { \ 1578 dev_err(dev, "WLP: Unable to construct %s association " \ 1579 "frame: %d\n", wlp_assoc_frame_str(id), result);\ 1580 goto error_build_assoc; \ 1581 } \ 1582 /* Send the frame */ \ 1583 BUG_ON(wlp->xmit_frame == NULL); \ 1584 result = wlp->xmit_frame(wlp, skb, dev_addr); \ 1585 if (result < 0) { \ 1586 dev_err(dev, "WLP: Unable to transmit %s association " \ 1587 "message: %d\n", wlp_assoc_frame_str(id), \ 1588 result); \ 1589 if (result == -ENXIO) \ 1590 dev_err(dev, "WLP: Is network interface " \ 1591 "up? \n"); \ 1592 goto error_xmit; \ 1593 } \ 1594 return 0; \ 1595error_xmit: \ 1596 /* We could try again ... */ \ 1597 dev_kfree_skb_any(skb);/*we need to free if tx fails*/ \ 1598error_build_assoc: \ 1599 return result; \ 1600} 1601 1602wlp_send_assoc(d1, WLP_ASSOC_D1) 1603wlp_send_assoc(c1, WLP_ASSOC_C1) 1604wlp_send_assoc(c3, WLP_ASSOC_C3) 1605 1606int wlp_send_assoc_frame(struct wlp *wlp, struct wlp_wss *wss, 1607 struct uwb_dev_addr *dev_addr, 1608 enum wlp_assoc_type type) 1609{ 1610 int result = 0; 1611 struct device *dev = &wlp->rc->uwb_dev.dev; 1612 switch (type) { 1613 case WLP_ASSOC_D1: 1614 result = wlp_send_assoc_d1(wlp, wss, dev_addr); 1615 break; 1616 case WLP_ASSOC_C1: 1617 result = wlp_send_assoc_c1(wlp, wss, dev_addr); 1618 break; 1619 case WLP_ASSOC_C3: 1620 result = wlp_send_assoc_c3(wlp, wss, dev_addr); 1621 break; 1622 default: 1623 dev_err(dev, "WLP: Received request to send unknown " 1624 "association message.\n"); 1625 result = -EINVAL; 1626 break; 1627 } 1628 return result; 1629} 1630 1631/** 1632 * Handle incoming C1 frame 1633 * 1634 * The frame has already been verified to contain an Association header with 1635 * the correct version number. Parse the incoming frame, construct and send 1636 * a C2 frame in response. 1637 */ 1638void wlp_handle_c1_frame(struct work_struct *ws) 1639{ 1640 struct wlp_assoc_frame_ctx *frame_ctx = container_of(ws, 1641 struct wlp_assoc_frame_ctx, 1642 ws); 1643 struct wlp *wlp = frame_ctx->wlp; 1644 struct wlp_wss *wss = &wlp->wss; 1645 struct device *dev = &wlp->rc->uwb_dev.dev; 1646 struct wlp_frame_assoc *c1 = (void *) frame_ctx->skb->data; 1647 unsigned int len = frame_ctx->skb->len; 1648 struct uwb_dev_addr *src = &frame_ctx->src; 1649 int result; 1650 struct wlp_uuid wssid; 1651 struct sk_buff *resp = NULL; 1652 1653 /* Parse C1 frame */ 1654 mutex_lock(&wss->mutex); 1655 result = wlp_get_wssid(wlp, (void *)c1 + sizeof(*c1), &wssid, 1656 len - sizeof(*c1)); 1657 if (result < 0) { 1658 dev_err(dev, "WLP: unable to obtain WSSID from C1 frame.\n"); 1659 goto out; 1660 } 1661 if (!memcmp(&wssid, &wss->wssid, sizeof(wssid)) 1662 && wss->state == WLP_WSS_STATE_ACTIVE) { 1663 /* Construct C2 frame */ 1664 result = wlp_build_assoc_c2(wlp, wss, &resp); 1665 if (result < 0) { 1666 dev_err(dev, "WLP: Unable to construct C2 message.\n"); 1667 goto out; 1668 } 1669 } else { 1670 /* Construct F0 frame */ 1671 result = wlp_build_assoc_f0(wlp, &resp, WLP_ASSOC_ERROR_INV); 1672 if (result < 0) { 1673 dev_err(dev, "WLP: Unable to construct F0 message.\n"); 1674 goto out; 1675 } 1676 } 1677 /* Send C2 frame */ 1678 BUG_ON(wlp->xmit_frame == NULL); 1679 result = wlp->xmit_frame(wlp, resp, src); 1680 if (result < 0) { 1681 dev_err(dev, "WLP: Unable to transmit response association " 1682 "message: %d\n", result); 1683 if (result == -ENXIO) 1684 dev_err(dev, "WLP: Is network interface up? \n"); 1685 /* We could try again ... */ 1686 dev_kfree_skb_any(resp); /* we need to free if tx fails */ 1687 } 1688out: 1689 kfree_skb(frame_ctx->skb); 1690 kfree(frame_ctx); 1691 mutex_unlock(&wss->mutex); 1692} 1693 1694/** 1695 * Handle incoming C3 frame 1696 * 1697 * The frame has already been verified to contain an Association header with 1698 * the correct version number. Parse the incoming frame, construct and send 1699 * a C4 frame in response. If the C3 frame identifies a WSS that is locally 1700 * active then we connect to this neighbor (add it to our EDA cache). 1701 */ 1702void wlp_handle_c3_frame(struct work_struct *ws) 1703{ 1704 struct wlp_assoc_frame_ctx *frame_ctx = container_of(ws, 1705 struct wlp_assoc_frame_ctx, 1706 ws); 1707 struct wlp *wlp = frame_ctx->wlp; 1708 struct wlp_wss *wss = &wlp->wss; 1709 struct device *dev = &wlp->rc->uwb_dev.dev; 1710 struct sk_buff *skb = frame_ctx->skb; 1711 struct uwb_dev_addr *src = &frame_ctx->src; 1712 int result; 1713 struct sk_buff *resp = NULL; 1714 struct wlp_uuid wssid; 1715 u8 tag; 1716 struct uwb_mac_addr virt_addr; 1717 1718 /* Parse C3 frame */ 1719 mutex_lock(&wss->mutex); 1720 result = wlp_parse_c3c4_frame(wlp, skb, &wssid, &tag, &virt_addr); 1721 if (result < 0) { 1722 dev_err(dev, "WLP: unable to obtain values from C3 frame.\n"); 1723 goto out; 1724 } 1725 if (!memcmp(&wssid, &wss->wssid, sizeof(wssid)) 1726 && wss->state >= WLP_WSS_STATE_ACTIVE) { 1727 result = wlp_eda_update_node(&wlp->eda, src, wss, 1728 (void *) virt_addr.data, tag, 1729 WLP_WSS_CONNECTED); 1730 if (result < 0) { 1731 dev_err(dev, "WLP: Unable to update EDA cache " 1732 "with new connected neighbor information.\n"); 1733 result = wlp_build_assoc_f0(wlp, &resp, 1734 WLP_ASSOC_ERROR_INT); 1735 if (result < 0) { 1736 dev_err(dev, "WLP: Unable to construct F0 " 1737 "message.\n"); 1738 goto out; 1739 } 1740 } else { 1741 wss->state = WLP_WSS_STATE_CONNECTED; 1742 /* Construct C4 frame */ 1743 result = wlp_build_assoc_c4(wlp, wss, &resp); 1744 if (result < 0) { 1745 dev_err(dev, "WLP: Unable to construct C4 " 1746 "message.\n"); 1747 goto out; 1748 } 1749 } 1750 } else { 1751 /* Construct F0 frame */ 1752 result = wlp_build_assoc_f0(wlp, &resp, WLP_ASSOC_ERROR_INV); 1753 if (result < 0) { 1754 dev_err(dev, "WLP: Unable to construct F0 message.\n"); 1755 goto out; 1756 } 1757 } 1758 /* Send C4 frame */ 1759 BUG_ON(wlp->xmit_frame == NULL); 1760 result = wlp->xmit_frame(wlp, resp, src); 1761 if (result < 0) { 1762 dev_err(dev, "WLP: Unable to transmit response association " 1763 "message: %d\n", result); 1764 if (result == -ENXIO) 1765 dev_err(dev, "WLP: Is network interface up? \n"); 1766 /* We could try again ... */ 1767 dev_kfree_skb_any(resp); /* we need to free if tx fails */ 1768 } 1769out: 1770 kfree_skb(frame_ctx->skb); 1771 kfree(frame_ctx); 1772 mutex_unlock(&wss->mutex); 1773} 1774