1 /* 2 * WSM host interface (HI) implementation for 3 * ST-Ericsson CW1200 mac80211 drivers. 4 * 5 * Copyright (c) 2010, ST-Ericsson 6 * Author: Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no> 7 * 8 * This program is free software; you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License version 2 as 10 * published by the Free Software Foundation. 11 */ 12 13 #include <linux/skbuff.h> 14 #include <linux/wait.h> 15 #include <linux/delay.h> 16 #include <linux/sched.h> 17 #include <linux/random.h> 18 19 #include "cw1200.h" 20 #include "wsm.h" 21 #include "bh.h" 22 #include "sta.h" 23 #include "debug.h" 24 25 #define WSM_CMD_TIMEOUT (2 * HZ) /* With respect to interrupt loss */ 26 #define WSM_CMD_START_TIMEOUT (7 * HZ) 27 #define WSM_CMD_RESET_TIMEOUT (3 * HZ) /* 2 sec. timeout was observed. */ 28 #define WSM_CMD_MAX_TIMEOUT (3 * HZ) 29 30 #define WSM_SKIP(buf, size) \ 31 do { \ 32 if ((buf)->data + size > (buf)->end) \ 33 goto underflow; \ 34 (buf)->data += size; \ 35 } while (0) 36 37 #define WSM_GET(buf, ptr, size) \ 38 do { \ 39 if ((buf)->data + size > (buf)->end) \ 40 goto underflow; \ 41 memcpy(ptr, (buf)->data, size); \ 42 (buf)->data += size; \ 43 } while (0) 44 45 #define __WSM_GET(buf, type, type2, cvt) \ 46 ({ \ 47 type val; \ 48 if ((buf)->data + sizeof(type) > (buf)->end) \ 49 goto underflow; \ 50 val = cvt(*(type2 *)(buf)->data); \ 51 (buf)->data += sizeof(type); \ 52 val; \ 53 }) 54 55 #define WSM_GET8(buf) __WSM_GET(buf, u8, u8, (u8)) 56 #define WSM_GET16(buf) __WSM_GET(buf, u16, __le16, __le16_to_cpu) 57 #define WSM_GET32(buf) __WSM_GET(buf, u32, __le32, __le32_to_cpu) 58 59 #define WSM_PUT(buf, ptr, size) \ 60 do { \ 61 if ((buf)->data + size > (buf)->end) \ 62 if (wsm_buf_reserve((buf), size)) \ 63 goto nomem; \ 64 memcpy((buf)->data, ptr, size); \ 65 (buf)->data += size; \ 66 } while (0) 67 68 #define __WSM_PUT(buf, val, type, type2, cvt) \ 69 do { \ 70 if ((buf)->data + sizeof(type) > (buf)->end) \ 71 if (wsm_buf_reserve((buf), sizeof(type))) \ 72 goto nomem; \ 73 *(type2 *)(buf)->data = cvt(val); \ 74 (buf)->data += sizeof(type); \ 75 } while (0) 76 77 #define WSM_PUT8(buf, val) __WSM_PUT(buf, val, u8, u8, (u8)) 78 #define WSM_PUT16(buf, val) __WSM_PUT(buf, val, u16, __le16, __cpu_to_le16) 79 #define WSM_PUT32(buf, val) __WSM_PUT(buf, val, u32, __le32, __cpu_to_le32) 80 81 static void wsm_buf_reset(struct wsm_buf *buf); 82 static int wsm_buf_reserve(struct wsm_buf *buf, size_t extra_size); 83 84 static int wsm_cmd_send(struct cw1200_common *priv, 85 struct wsm_buf *buf, 86 void *arg, u16 cmd, long tmo); 87 88 #define wsm_cmd_lock(__priv) mutex_lock(&((__priv)->wsm_cmd_mux)) 89 #define wsm_cmd_unlock(__priv) mutex_unlock(&((__priv)->wsm_cmd_mux)) 90 91 /* ******************************************************************** */ 92 /* WSM API implementation */ 93 94 static int wsm_generic_confirm(struct cw1200_common *priv, 95 void *arg, 96 struct wsm_buf *buf) 97 { 98 u32 status = WSM_GET32(buf); 99 if (status != WSM_STATUS_SUCCESS) 100 return -EINVAL; 101 return 0; 102 103 underflow: 104 WARN_ON(1); 105 return -EINVAL; 106 } 107 108 int wsm_configuration(struct cw1200_common *priv, struct wsm_configuration *arg) 109 { 110 int ret; 111 struct wsm_buf *buf = &priv->wsm_cmd_buf; 112 113 wsm_cmd_lock(priv); 114 115 WSM_PUT32(buf, arg->dot11MaxTransmitMsduLifeTime); 116 WSM_PUT32(buf, arg->dot11MaxReceiveLifeTime); 117 WSM_PUT32(buf, arg->dot11RtsThreshold); 118 119 /* DPD block. */ 120 WSM_PUT16(buf, arg->dpdData_size + 12); 121 WSM_PUT16(buf, 1); /* DPD version */ 122 WSM_PUT(buf, arg->dot11StationId, ETH_ALEN); 123 WSM_PUT16(buf, 5); /* DPD flags */ 124 WSM_PUT(buf, arg->dpdData, arg->dpdData_size); 125 126 ret = wsm_cmd_send(priv, buf, arg, 127 WSM_CONFIGURATION_REQ_ID, WSM_CMD_TIMEOUT); 128 129 wsm_cmd_unlock(priv); 130 return ret; 131 132 nomem: 133 wsm_cmd_unlock(priv); 134 return -ENOMEM; 135 } 136 137 static int wsm_configuration_confirm(struct cw1200_common *priv, 138 struct wsm_configuration *arg, 139 struct wsm_buf *buf) 140 { 141 int i; 142 int status; 143 144 status = WSM_GET32(buf); 145 if (WARN_ON(status != WSM_STATUS_SUCCESS)) 146 return -EINVAL; 147 148 WSM_GET(buf, arg->dot11StationId, ETH_ALEN); 149 arg->dot11FrequencyBandsSupported = WSM_GET8(buf); 150 WSM_SKIP(buf, 1); 151 arg->supportedRateMask = WSM_GET32(buf); 152 for (i = 0; i < 2; ++i) { 153 arg->txPowerRange[i].min_power_level = WSM_GET32(buf); 154 arg->txPowerRange[i].max_power_level = WSM_GET32(buf); 155 arg->txPowerRange[i].stepping = WSM_GET32(buf); 156 } 157 return 0; 158 159 underflow: 160 WARN_ON(1); 161 return -EINVAL; 162 } 163 164 /* ******************************************************************** */ 165 166 int wsm_reset(struct cw1200_common *priv, const struct wsm_reset *arg) 167 { 168 int ret; 169 struct wsm_buf *buf = &priv->wsm_cmd_buf; 170 u16 cmd = WSM_RESET_REQ_ID | WSM_TX_LINK_ID(arg->link_id); 171 172 wsm_cmd_lock(priv); 173 174 WSM_PUT32(buf, arg->reset_statistics ? 0 : 1); 175 ret = wsm_cmd_send(priv, buf, NULL, cmd, WSM_CMD_RESET_TIMEOUT); 176 wsm_cmd_unlock(priv); 177 return ret; 178 179 nomem: 180 wsm_cmd_unlock(priv); 181 return -ENOMEM; 182 } 183 184 /* ******************************************************************** */ 185 186 struct wsm_mib { 187 u16 mib_id; 188 void *buf; 189 size_t buf_size; 190 }; 191 192 int wsm_read_mib(struct cw1200_common *priv, u16 mib_id, void *_buf, 193 size_t buf_size) 194 { 195 int ret; 196 struct wsm_buf *buf = &priv->wsm_cmd_buf; 197 struct wsm_mib mib_buf = { 198 .mib_id = mib_id, 199 .buf = _buf, 200 .buf_size = buf_size, 201 }; 202 wsm_cmd_lock(priv); 203 204 WSM_PUT16(buf, mib_id); 205 WSM_PUT16(buf, 0); 206 207 ret = wsm_cmd_send(priv, buf, &mib_buf, 208 WSM_READ_MIB_REQ_ID, WSM_CMD_TIMEOUT); 209 wsm_cmd_unlock(priv); 210 return ret; 211 212 nomem: 213 wsm_cmd_unlock(priv); 214 return -ENOMEM; 215 } 216 217 static int wsm_read_mib_confirm(struct cw1200_common *priv, 218 struct wsm_mib *arg, 219 struct wsm_buf *buf) 220 { 221 u16 size; 222 if (WARN_ON(WSM_GET32(buf) != WSM_STATUS_SUCCESS)) 223 return -EINVAL; 224 225 if (WARN_ON(WSM_GET16(buf) != arg->mib_id)) 226 return -EINVAL; 227 228 size = WSM_GET16(buf); 229 if (size > arg->buf_size) 230 size = arg->buf_size; 231 232 WSM_GET(buf, arg->buf, size); 233 arg->buf_size = size; 234 return 0; 235 236 underflow: 237 WARN_ON(1); 238 return -EINVAL; 239 } 240 241 /* ******************************************************************** */ 242 243 int wsm_write_mib(struct cw1200_common *priv, u16 mib_id, void *_buf, 244 size_t buf_size) 245 { 246 int ret; 247 struct wsm_buf *buf = &priv->wsm_cmd_buf; 248 struct wsm_mib mib_buf = { 249 .mib_id = mib_id, 250 .buf = _buf, 251 .buf_size = buf_size, 252 }; 253 254 wsm_cmd_lock(priv); 255 256 WSM_PUT16(buf, mib_id); 257 WSM_PUT16(buf, buf_size); 258 WSM_PUT(buf, _buf, buf_size); 259 260 ret = wsm_cmd_send(priv, buf, &mib_buf, 261 WSM_WRITE_MIB_REQ_ID, WSM_CMD_TIMEOUT); 262 wsm_cmd_unlock(priv); 263 return ret; 264 265 nomem: 266 wsm_cmd_unlock(priv); 267 return -ENOMEM; 268 } 269 270 static int wsm_write_mib_confirm(struct cw1200_common *priv, 271 struct wsm_mib *arg, 272 struct wsm_buf *buf) 273 { 274 int ret; 275 276 ret = wsm_generic_confirm(priv, arg, buf); 277 if (ret) 278 return ret; 279 280 if (arg->mib_id == WSM_MIB_ID_OPERATIONAL_POWER_MODE) { 281 /* OperationalMode: update PM status. */ 282 const char *p = arg->buf; 283 cw1200_enable_powersave(priv, (p[0] & 0x0F) ? true : false); 284 } 285 return 0; 286 } 287 288 /* ******************************************************************** */ 289 290 int wsm_scan(struct cw1200_common *priv, const struct wsm_scan *arg) 291 { 292 int i; 293 int ret; 294 struct wsm_buf *buf = &priv->wsm_cmd_buf; 295 296 if (arg->num_channels > 48) 297 return -EINVAL; 298 299 if (arg->num_ssids > 2) 300 return -EINVAL; 301 302 if (arg->band > 1) 303 return -EINVAL; 304 305 wsm_cmd_lock(priv); 306 307 WSM_PUT8(buf, arg->band); 308 WSM_PUT8(buf, arg->type); 309 WSM_PUT8(buf, arg->flags); 310 WSM_PUT8(buf, arg->max_tx_rate); 311 WSM_PUT32(buf, arg->auto_scan_interval); 312 WSM_PUT8(buf, arg->num_probes); 313 WSM_PUT8(buf, arg->num_channels); 314 WSM_PUT8(buf, arg->num_ssids); 315 WSM_PUT8(buf, arg->probe_delay); 316 317 for (i = 0; i < arg->num_channels; ++i) { 318 WSM_PUT16(buf, arg->ch[i].number); 319 WSM_PUT16(buf, 0); 320 WSM_PUT32(buf, arg->ch[i].min_chan_time); 321 WSM_PUT32(buf, arg->ch[i].max_chan_time); 322 WSM_PUT32(buf, 0); 323 } 324 325 for (i = 0; i < arg->num_ssids; ++i) { 326 WSM_PUT32(buf, arg->ssids[i].length); 327 WSM_PUT(buf, &arg->ssids[i].ssid[0], 328 sizeof(arg->ssids[i].ssid)); 329 } 330 331 ret = wsm_cmd_send(priv, buf, NULL, 332 WSM_START_SCAN_REQ_ID, WSM_CMD_TIMEOUT); 333 wsm_cmd_unlock(priv); 334 return ret; 335 336 nomem: 337 wsm_cmd_unlock(priv); 338 return -ENOMEM; 339 } 340 341 /* ******************************************************************** */ 342 343 int wsm_stop_scan(struct cw1200_common *priv) 344 { 345 int ret; 346 struct wsm_buf *buf = &priv->wsm_cmd_buf; 347 wsm_cmd_lock(priv); 348 ret = wsm_cmd_send(priv, buf, NULL, 349 WSM_STOP_SCAN_REQ_ID, WSM_CMD_TIMEOUT); 350 wsm_cmd_unlock(priv); 351 return ret; 352 } 353 354 355 static int wsm_tx_confirm(struct cw1200_common *priv, 356 struct wsm_buf *buf, 357 int link_id) 358 { 359 struct wsm_tx_confirm tx_confirm; 360 361 tx_confirm.packet_id = WSM_GET32(buf); 362 tx_confirm.status = WSM_GET32(buf); 363 tx_confirm.tx_rate = WSM_GET8(buf); 364 tx_confirm.ack_failures = WSM_GET8(buf); 365 tx_confirm.flags = WSM_GET16(buf); 366 tx_confirm.media_delay = WSM_GET32(buf); 367 tx_confirm.tx_queue_delay = WSM_GET32(buf); 368 369 cw1200_tx_confirm_cb(priv, link_id, &tx_confirm); 370 return 0; 371 372 underflow: 373 WARN_ON(1); 374 return -EINVAL; 375 } 376 377 static int wsm_multi_tx_confirm(struct cw1200_common *priv, 378 struct wsm_buf *buf, int link_id) 379 { 380 int ret; 381 int count; 382 383 count = WSM_GET32(buf); 384 if (WARN_ON(count <= 0)) 385 return -EINVAL; 386 387 if (count > 1) { 388 /* We already released one buffer, now for the rest */ 389 ret = wsm_release_tx_buffer(priv, count - 1); 390 if (ret < 0) 391 return ret; 392 else if (ret > 0) 393 cw1200_bh_wakeup(priv); 394 } 395 396 cw1200_debug_txed_multi(priv, count); 397 do { 398 ret = wsm_tx_confirm(priv, buf, link_id); 399 } while (!ret && --count); 400 401 return ret; 402 403 underflow: 404 WARN_ON(1); 405 return -EINVAL; 406 } 407 408 /* ******************************************************************** */ 409 410 static int wsm_join_confirm(struct cw1200_common *priv, 411 struct wsm_join_cnf *arg, 412 struct wsm_buf *buf) 413 { 414 arg->status = WSM_GET32(buf); 415 if (WARN_ON(arg->status) != WSM_STATUS_SUCCESS) 416 return -EINVAL; 417 418 arg->min_power_level = WSM_GET32(buf); 419 arg->max_power_level = WSM_GET32(buf); 420 421 return 0; 422 423 underflow: 424 WARN_ON(1); 425 return -EINVAL; 426 } 427 428 int wsm_join(struct cw1200_common *priv, struct wsm_join *arg) 429 { 430 int ret; 431 struct wsm_buf *buf = &priv->wsm_cmd_buf; 432 struct wsm_join_cnf resp; 433 wsm_cmd_lock(priv); 434 435 WSM_PUT8(buf, arg->mode); 436 WSM_PUT8(buf, arg->band); 437 WSM_PUT16(buf, arg->channel_number); 438 WSM_PUT(buf, &arg->bssid[0], sizeof(arg->bssid)); 439 WSM_PUT16(buf, arg->atim_window); 440 WSM_PUT8(buf, arg->preamble_type); 441 WSM_PUT8(buf, arg->probe_for_join); 442 WSM_PUT8(buf, arg->dtim_period); 443 WSM_PUT8(buf, arg->flags); 444 WSM_PUT32(buf, arg->ssid_len); 445 WSM_PUT(buf, &arg->ssid[0], sizeof(arg->ssid)); 446 WSM_PUT32(buf, arg->beacon_interval); 447 WSM_PUT32(buf, arg->basic_rate_set); 448 449 priv->tx_burst_idx = -1; 450 ret = wsm_cmd_send(priv, buf, &resp, 451 WSM_JOIN_REQ_ID, WSM_CMD_TIMEOUT); 452 /* TODO: Update state based on resp.min|max_power_level */ 453 454 priv->join_complete_status = resp.status; 455 456 wsm_cmd_unlock(priv); 457 return ret; 458 459 nomem: 460 wsm_cmd_unlock(priv); 461 return -ENOMEM; 462 } 463 464 /* ******************************************************************** */ 465 466 int wsm_set_bss_params(struct cw1200_common *priv, 467 const struct wsm_set_bss_params *arg) 468 { 469 int ret; 470 struct wsm_buf *buf = &priv->wsm_cmd_buf; 471 472 wsm_cmd_lock(priv); 473 474 WSM_PUT8(buf, (arg->reset_beacon_loss ? 0x1 : 0)); 475 WSM_PUT8(buf, arg->beacon_lost_count); 476 WSM_PUT16(buf, arg->aid); 477 WSM_PUT32(buf, arg->operational_rate_set); 478 479 ret = wsm_cmd_send(priv, buf, NULL, 480 WSM_SET_BSS_PARAMS_REQ_ID, WSM_CMD_TIMEOUT); 481 482 wsm_cmd_unlock(priv); 483 return ret; 484 485 nomem: 486 wsm_cmd_unlock(priv); 487 return -ENOMEM; 488 } 489 490 /* ******************************************************************** */ 491 492 int wsm_add_key(struct cw1200_common *priv, const struct wsm_add_key *arg) 493 { 494 int ret; 495 struct wsm_buf *buf = &priv->wsm_cmd_buf; 496 497 wsm_cmd_lock(priv); 498 499 WSM_PUT(buf, arg, sizeof(*arg)); 500 501 ret = wsm_cmd_send(priv, buf, NULL, 502 WSM_ADD_KEY_REQ_ID, WSM_CMD_TIMEOUT); 503 504 wsm_cmd_unlock(priv); 505 return ret; 506 507 nomem: 508 wsm_cmd_unlock(priv); 509 return -ENOMEM; 510 } 511 512 /* ******************************************************************** */ 513 514 int wsm_remove_key(struct cw1200_common *priv, const struct wsm_remove_key *arg) 515 { 516 int ret; 517 struct wsm_buf *buf = &priv->wsm_cmd_buf; 518 519 wsm_cmd_lock(priv); 520 521 WSM_PUT8(buf, arg->index); 522 WSM_PUT8(buf, 0); 523 WSM_PUT16(buf, 0); 524 525 ret = wsm_cmd_send(priv, buf, NULL, 526 WSM_REMOVE_KEY_REQ_ID, WSM_CMD_TIMEOUT); 527 528 wsm_cmd_unlock(priv); 529 return ret; 530 531 nomem: 532 wsm_cmd_unlock(priv); 533 return -ENOMEM; 534 } 535 536 /* ******************************************************************** */ 537 538 int wsm_set_tx_queue_params(struct cw1200_common *priv, 539 const struct wsm_set_tx_queue_params *arg, u8 id) 540 { 541 int ret; 542 struct wsm_buf *buf = &priv->wsm_cmd_buf; 543 u8 queue_id_to_wmm_aci[] = {3, 2, 0, 1}; 544 545 wsm_cmd_lock(priv); 546 547 WSM_PUT8(buf, queue_id_to_wmm_aci[id]); 548 WSM_PUT8(buf, 0); 549 WSM_PUT8(buf, arg->ackPolicy); 550 WSM_PUT8(buf, 0); 551 WSM_PUT32(buf, arg->maxTransmitLifetime); 552 WSM_PUT16(buf, arg->allowedMediumTime); 553 WSM_PUT16(buf, 0); 554 555 ret = wsm_cmd_send(priv, buf, NULL, 0x0012, WSM_CMD_TIMEOUT); 556 557 wsm_cmd_unlock(priv); 558 return ret; 559 560 nomem: 561 wsm_cmd_unlock(priv); 562 return -ENOMEM; 563 } 564 565 /* ******************************************************************** */ 566 567 int wsm_set_edca_params(struct cw1200_common *priv, 568 const struct wsm_edca_params *arg) 569 { 570 int ret; 571 struct wsm_buf *buf = &priv->wsm_cmd_buf; 572 573 wsm_cmd_lock(priv); 574 575 /* Implemented according to specification. */ 576 577 WSM_PUT16(buf, arg->params[3].cwmin); 578 WSM_PUT16(buf, arg->params[2].cwmin); 579 WSM_PUT16(buf, arg->params[1].cwmin); 580 WSM_PUT16(buf, arg->params[0].cwmin); 581 582 WSM_PUT16(buf, arg->params[3].cwmax); 583 WSM_PUT16(buf, arg->params[2].cwmax); 584 WSM_PUT16(buf, arg->params[1].cwmax); 585 WSM_PUT16(buf, arg->params[0].cwmax); 586 587 WSM_PUT8(buf, arg->params[3].aifns); 588 WSM_PUT8(buf, arg->params[2].aifns); 589 WSM_PUT8(buf, arg->params[1].aifns); 590 WSM_PUT8(buf, arg->params[0].aifns); 591 592 WSM_PUT16(buf, arg->params[3].txop_limit); 593 WSM_PUT16(buf, arg->params[2].txop_limit); 594 WSM_PUT16(buf, arg->params[1].txop_limit); 595 WSM_PUT16(buf, arg->params[0].txop_limit); 596 597 WSM_PUT32(buf, arg->params[3].max_rx_lifetime); 598 WSM_PUT32(buf, arg->params[2].max_rx_lifetime); 599 WSM_PUT32(buf, arg->params[1].max_rx_lifetime); 600 WSM_PUT32(buf, arg->params[0].max_rx_lifetime); 601 602 ret = wsm_cmd_send(priv, buf, NULL, 603 WSM_EDCA_PARAMS_REQ_ID, WSM_CMD_TIMEOUT); 604 wsm_cmd_unlock(priv); 605 return ret; 606 607 nomem: 608 wsm_cmd_unlock(priv); 609 return -ENOMEM; 610 } 611 612 /* ******************************************************************** */ 613 614 int wsm_switch_channel(struct cw1200_common *priv, 615 const struct wsm_switch_channel *arg) 616 { 617 int ret; 618 struct wsm_buf *buf = &priv->wsm_cmd_buf; 619 620 wsm_cmd_lock(priv); 621 622 WSM_PUT8(buf, arg->mode); 623 WSM_PUT8(buf, arg->switch_count); 624 WSM_PUT16(buf, arg->channel_number); 625 626 priv->channel_switch_in_progress = 1; 627 628 ret = wsm_cmd_send(priv, buf, NULL, 629 WSM_SWITCH_CHANNEL_REQ_ID, WSM_CMD_TIMEOUT); 630 if (ret) 631 priv->channel_switch_in_progress = 0; 632 633 wsm_cmd_unlock(priv); 634 return ret; 635 636 nomem: 637 wsm_cmd_unlock(priv); 638 return -ENOMEM; 639 } 640 641 /* ******************************************************************** */ 642 643 int wsm_set_pm(struct cw1200_common *priv, const struct wsm_set_pm *arg) 644 { 645 int ret; 646 struct wsm_buf *buf = &priv->wsm_cmd_buf; 647 priv->ps_mode_switch_in_progress = 1; 648 649 wsm_cmd_lock(priv); 650 651 WSM_PUT8(buf, arg->mode); 652 WSM_PUT8(buf, arg->fast_psm_idle_period); 653 WSM_PUT8(buf, arg->ap_psm_change_period); 654 WSM_PUT8(buf, arg->min_auto_pspoll_period); 655 656 ret = wsm_cmd_send(priv, buf, NULL, 657 WSM_SET_PM_REQ_ID, WSM_CMD_TIMEOUT); 658 659 wsm_cmd_unlock(priv); 660 return ret; 661 662 nomem: 663 wsm_cmd_unlock(priv); 664 return -ENOMEM; 665 } 666 667 /* ******************************************************************** */ 668 669 int wsm_start(struct cw1200_common *priv, const struct wsm_start *arg) 670 { 671 int ret; 672 struct wsm_buf *buf = &priv->wsm_cmd_buf; 673 674 wsm_cmd_lock(priv); 675 676 WSM_PUT8(buf, arg->mode); 677 WSM_PUT8(buf, arg->band); 678 WSM_PUT16(buf, arg->channel_number); 679 WSM_PUT32(buf, arg->ct_window); 680 WSM_PUT32(buf, arg->beacon_interval); 681 WSM_PUT8(buf, arg->dtim_period); 682 WSM_PUT8(buf, arg->preamble); 683 WSM_PUT8(buf, arg->probe_delay); 684 WSM_PUT8(buf, arg->ssid_len); 685 WSM_PUT(buf, arg->ssid, sizeof(arg->ssid)); 686 WSM_PUT32(buf, arg->basic_rate_set); 687 688 priv->tx_burst_idx = -1; 689 ret = wsm_cmd_send(priv, buf, NULL, 690 WSM_START_REQ_ID, WSM_CMD_START_TIMEOUT); 691 692 wsm_cmd_unlock(priv); 693 return ret; 694 695 nomem: 696 wsm_cmd_unlock(priv); 697 return -ENOMEM; 698 } 699 700 /* ******************************************************************** */ 701 702 int wsm_beacon_transmit(struct cw1200_common *priv, 703 const struct wsm_beacon_transmit *arg) 704 { 705 int ret; 706 struct wsm_buf *buf = &priv->wsm_cmd_buf; 707 708 wsm_cmd_lock(priv); 709 710 WSM_PUT32(buf, arg->enable_beaconing ? 1 : 0); 711 712 ret = wsm_cmd_send(priv, buf, NULL, 713 WSM_BEACON_TRANSMIT_REQ_ID, WSM_CMD_TIMEOUT); 714 715 wsm_cmd_unlock(priv); 716 return ret; 717 718 nomem: 719 wsm_cmd_unlock(priv); 720 return -ENOMEM; 721 } 722 723 /* ******************************************************************** */ 724 725 int wsm_start_find(struct cw1200_common *priv) 726 { 727 int ret; 728 struct wsm_buf *buf = &priv->wsm_cmd_buf; 729 730 wsm_cmd_lock(priv); 731 ret = wsm_cmd_send(priv, buf, NULL, 0x0019, WSM_CMD_TIMEOUT); 732 wsm_cmd_unlock(priv); 733 return ret; 734 } 735 736 /* ******************************************************************** */ 737 738 int wsm_stop_find(struct cw1200_common *priv) 739 { 740 int ret; 741 struct wsm_buf *buf = &priv->wsm_cmd_buf; 742 743 wsm_cmd_lock(priv); 744 ret = wsm_cmd_send(priv, buf, NULL, 0x001A, WSM_CMD_TIMEOUT); 745 wsm_cmd_unlock(priv); 746 return ret; 747 } 748 749 /* ******************************************************************** */ 750 751 int wsm_map_link(struct cw1200_common *priv, const struct wsm_map_link *arg) 752 { 753 int ret; 754 struct wsm_buf *buf = &priv->wsm_cmd_buf; 755 u16 cmd = 0x001C | WSM_TX_LINK_ID(arg->link_id); 756 757 wsm_cmd_lock(priv); 758 759 WSM_PUT(buf, &arg->mac_addr[0], sizeof(arg->mac_addr)); 760 WSM_PUT16(buf, 0); 761 762 ret = wsm_cmd_send(priv, buf, NULL, cmd, WSM_CMD_TIMEOUT); 763 764 wsm_cmd_unlock(priv); 765 return ret; 766 767 nomem: 768 wsm_cmd_unlock(priv); 769 return -ENOMEM; 770 } 771 772 /* ******************************************************************** */ 773 774 int wsm_update_ie(struct cw1200_common *priv, 775 const struct wsm_update_ie *arg) 776 { 777 int ret; 778 struct wsm_buf *buf = &priv->wsm_cmd_buf; 779 780 wsm_cmd_lock(priv); 781 782 WSM_PUT16(buf, arg->what); 783 WSM_PUT16(buf, arg->count); 784 WSM_PUT(buf, arg->ies, arg->length); 785 786 ret = wsm_cmd_send(priv, buf, NULL, 0x001B, WSM_CMD_TIMEOUT); 787 788 wsm_cmd_unlock(priv); 789 return ret; 790 791 nomem: 792 wsm_cmd_unlock(priv); 793 return -ENOMEM; 794 } 795 796 /* ******************************************************************** */ 797 int wsm_set_probe_responder(struct cw1200_common *priv, bool enable) 798 { 799 priv->rx_filter.probeResponder = enable; 800 return wsm_set_rx_filter(priv, &priv->rx_filter); 801 } 802 803 /* ******************************************************************** */ 804 /* WSM indication events implementation */ 805 const char * const cw1200_fw_types[] = { 806 "ETF", 807 "WFM", 808 "WSM", 809 "HI test", 810 "Platform test" 811 }; 812 813 static int wsm_startup_indication(struct cw1200_common *priv, 814 struct wsm_buf *buf) 815 { 816 priv->wsm_caps.input_buffers = WSM_GET16(buf); 817 priv->wsm_caps.input_buffer_size = WSM_GET16(buf); 818 priv->wsm_caps.hw_id = WSM_GET16(buf); 819 priv->wsm_caps.hw_subid = WSM_GET16(buf); 820 priv->wsm_caps.status = WSM_GET16(buf); 821 priv->wsm_caps.fw_cap = WSM_GET16(buf); 822 priv->wsm_caps.fw_type = WSM_GET16(buf); 823 priv->wsm_caps.fw_api = WSM_GET16(buf); 824 priv->wsm_caps.fw_build = WSM_GET16(buf); 825 priv->wsm_caps.fw_ver = WSM_GET16(buf); 826 WSM_GET(buf, priv->wsm_caps.fw_label, sizeof(priv->wsm_caps.fw_label)); 827 priv->wsm_caps.fw_label[sizeof(priv->wsm_caps.fw_label) - 1] = 0; /* Do not trust FW too much... */ 828 829 if (WARN_ON(priv->wsm_caps.status)) 830 return -EINVAL; 831 832 if (WARN_ON(priv->wsm_caps.fw_type > 4)) 833 return -EINVAL; 834 835 pr_info("CW1200 WSM init done.\n" 836 " Input buffers: %d x %d bytes\n" 837 " Hardware: %d.%d\n" 838 " %s firmware [%s], ver: %d, build: %d," 839 " api: %d, cap: 0x%.4X\n", 840 priv->wsm_caps.input_buffers, 841 priv->wsm_caps.input_buffer_size, 842 priv->wsm_caps.hw_id, priv->wsm_caps.hw_subid, 843 cw1200_fw_types[priv->wsm_caps.fw_type], 844 priv->wsm_caps.fw_label, priv->wsm_caps.fw_ver, 845 priv->wsm_caps.fw_build, 846 priv->wsm_caps.fw_api, priv->wsm_caps.fw_cap); 847 848 /* Disable unsupported frequency bands */ 849 if (!(priv->wsm_caps.fw_cap & 0x1)) 850 priv->hw->wiphy->bands[NL80211_BAND_2GHZ] = NULL; 851 if (!(priv->wsm_caps.fw_cap & 0x2)) 852 priv->hw->wiphy->bands[NL80211_BAND_5GHZ] = NULL; 853 854 priv->firmware_ready = 1; 855 wake_up(&priv->wsm_startup_done); 856 return 0; 857 858 underflow: 859 WARN_ON(1); 860 return -EINVAL; 861 } 862 863 static int wsm_receive_indication(struct cw1200_common *priv, 864 int link_id, 865 struct wsm_buf *buf, 866 struct sk_buff **skb_p) 867 { 868 struct wsm_rx rx; 869 struct ieee80211_hdr *hdr; 870 size_t hdr_len; 871 __le16 fctl; 872 873 rx.status = WSM_GET32(buf); 874 rx.channel_number = WSM_GET16(buf); 875 rx.rx_rate = WSM_GET8(buf); 876 rx.rcpi_rssi = WSM_GET8(buf); 877 rx.flags = WSM_GET32(buf); 878 879 /* FW Workaround: Drop probe resp or 880 beacon when RSSI is 0 881 */ 882 hdr = (struct ieee80211_hdr *)(*skb_p)->data; 883 884 if (!rx.rcpi_rssi && 885 (ieee80211_is_probe_resp(hdr->frame_control) || 886 ieee80211_is_beacon(hdr->frame_control))) 887 return 0; 888 889 /* If no RSSI subscription has been made, 890 * convert RCPI to RSSI here 891 */ 892 if (!priv->cqm_use_rssi) 893 rx.rcpi_rssi = rx.rcpi_rssi / 2 - 110; 894 895 fctl = *(__le16 *)buf->data; 896 hdr_len = buf->data - buf->begin; 897 skb_pull(*skb_p, hdr_len); 898 if (!rx.status && ieee80211_is_deauth(fctl)) { 899 if (priv->join_status == CW1200_JOIN_STATUS_STA) { 900 /* Shedule unjoin work */ 901 pr_debug("[WSM] Issue unjoin command (RX).\n"); 902 wsm_lock_tx_async(priv); 903 if (queue_work(priv->workqueue, 904 &priv->unjoin_work) <= 0) 905 wsm_unlock_tx(priv); 906 } 907 } 908 cw1200_rx_cb(priv, &rx, link_id, skb_p); 909 if (*skb_p) 910 skb_push(*skb_p, hdr_len); 911 912 return 0; 913 914 underflow: 915 return -EINVAL; 916 } 917 918 static int wsm_event_indication(struct cw1200_common *priv, struct wsm_buf *buf) 919 { 920 int first; 921 struct cw1200_wsm_event *event; 922 923 if (priv->mode == NL80211_IFTYPE_UNSPECIFIED) { 924 /* STA is stopped. */ 925 return 0; 926 } 927 928 event = kzalloc(sizeof(struct cw1200_wsm_event), GFP_KERNEL); 929 if (!event) 930 return -ENOMEM; 931 932 event->evt.id = WSM_GET32(buf); 933 event->evt.data = WSM_GET32(buf); 934 935 pr_debug("[WSM] Event: %d(%d)\n", 936 event->evt.id, event->evt.data); 937 938 spin_lock(&priv->event_queue_lock); 939 first = list_empty(&priv->event_queue); 940 list_add_tail(&event->link, &priv->event_queue); 941 spin_unlock(&priv->event_queue_lock); 942 943 if (first) 944 queue_work(priv->workqueue, &priv->event_handler); 945 946 return 0; 947 948 underflow: 949 kfree(event); 950 return -EINVAL; 951 } 952 953 static int wsm_channel_switch_indication(struct cw1200_common *priv, 954 struct wsm_buf *buf) 955 { 956 WARN_ON(WSM_GET32(buf)); 957 958 priv->channel_switch_in_progress = 0; 959 wake_up(&priv->channel_switch_done); 960 961 wsm_unlock_tx(priv); 962 963 return 0; 964 965 underflow: 966 return -EINVAL; 967 } 968 969 static int wsm_set_pm_indication(struct cw1200_common *priv, 970 struct wsm_buf *buf) 971 { 972 /* TODO: Check buf (struct wsm_set_pm_complete) for validity */ 973 if (priv->ps_mode_switch_in_progress) { 974 priv->ps_mode_switch_in_progress = 0; 975 wake_up(&priv->ps_mode_switch_done); 976 } 977 return 0; 978 } 979 980 static int wsm_scan_started(struct cw1200_common *priv, void *arg, 981 struct wsm_buf *buf) 982 { 983 u32 status = WSM_GET32(buf); 984 if (status != WSM_STATUS_SUCCESS) { 985 cw1200_scan_failed_cb(priv); 986 return -EINVAL; 987 } 988 return 0; 989 990 underflow: 991 WARN_ON(1); 992 return -EINVAL; 993 } 994 995 static int wsm_scan_complete_indication(struct cw1200_common *priv, 996 struct wsm_buf *buf) 997 { 998 struct wsm_scan_complete arg; 999 arg.status = WSM_GET32(buf); 1000 arg.psm = WSM_GET8(buf); 1001 arg.num_channels = WSM_GET8(buf); 1002 cw1200_scan_complete_cb(priv, &arg); 1003 1004 return 0; 1005 1006 underflow: 1007 return -EINVAL; 1008 } 1009 1010 static int wsm_join_complete_indication(struct cw1200_common *priv, 1011 struct wsm_buf *buf) 1012 { 1013 struct wsm_join_complete arg; 1014 arg.status = WSM_GET32(buf); 1015 pr_debug("[WSM] Join complete indication, status: %d\n", arg.status); 1016 cw1200_join_complete_cb(priv, &arg); 1017 1018 return 0; 1019 1020 underflow: 1021 return -EINVAL; 1022 } 1023 1024 static int wsm_find_complete_indication(struct cw1200_common *priv, 1025 struct wsm_buf *buf) 1026 { 1027 pr_warn("Implement find_complete_indication\n"); 1028 return 0; 1029 } 1030 1031 static int wsm_ba_timeout_indication(struct cw1200_common *priv, 1032 struct wsm_buf *buf) 1033 { 1034 u32 dummy; 1035 u8 tid; 1036 u8 dummy2; 1037 u8 addr[ETH_ALEN]; 1038 1039 dummy = WSM_GET32(buf); 1040 tid = WSM_GET8(buf); 1041 dummy2 = WSM_GET8(buf); 1042 WSM_GET(buf, addr, ETH_ALEN); 1043 1044 pr_info("BlockACK timeout, tid %d, addr %pM\n", 1045 tid, addr); 1046 1047 return 0; 1048 1049 underflow: 1050 return -EINVAL; 1051 } 1052 1053 static int wsm_suspend_resume_indication(struct cw1200_common *priv, 1054 int link_id, struct wsm_buf *buf) 1055 { 1056 u32 flags; 1057 struct wsm_suspend_resume arg; 1058 1059 flags = WSM_GET32(buf); 1060 arg.link_id = link_id; 1061 arg.stop = !(flags & 1); 1062 arg.multicast = !!(flags & 8); 1063 arg.queue = (flags >> 1) & 3; 1064 1065 cw1200_suspend_resume(priv, &arg); 1066 1067 return 0; 1068 1069 underflow: 1070 return -EINVAL; 1071 } 1072 1073 1074 /* ******************************************************************** */ 1075 /* WSM TX */ 1076 1077 static int wsm_cmd_send(struct cw1200_common *priv, 1078 struct wsm_buf *buf, 1079 void *arg, u16 cmd, long tmo) 1080 { 1081 size_t buf_len = buf->data - buf->begin; 1082 int ret; 1083 1084 /* Don't bother if we're dead. */ 1085 if (priv->bh_error) { 1086 ret = 0; 1087 goto done; 1088 } 1089 1090 /* Block until the cmd buffer is completed. Tortuous. */ 1091 spin_lock(&priv->wsm_cmd.lock); 1092 while (!priv->wsm_cmd.done) { 1093 spin_unlock(&priv->wsm_cmd.lock); 1094 spin_lock(&priv->wsm_cmd.lock); 1095 } 1096 priv->wsm_cmd.done = 0; 1097 spin_unlock(&priv->wsm_cmd.lock); 1098 1099 if (cmd == WSM_WRITE_MIB_REQ_ID || 1100 cmd == WSM_READ_MIB_REQ_ID) 1101 pr_debug("[WSM] >>> 0x%.4X [MIB: 0x%.4X] (%zu)\n", 1102 cmd, __le16_to_cpu(((__le16 *)buf->begin)[2]), 1103 buf_len); 1104 else 1105 pr_debug("[WSM] >>> 0x%.4X (%zu)\n", cmd, buf_len); 1106 1107 /* Due to buggy SPI on CW1200, we need to 1108 * pad the message by a few bytes to ensure 1109 * that it's completely received. 1110 */ 1111 buf_len += 4; 1112 1113 /* Fill HI message header */ 1114 /* BH will add sequence number */ 1115 ((__le16 *)buf->begin)[0] = __cpu_to_le16(buf_len); 1116 ((__le16 *)buf->begin)[1] = __cpu_to_le16(cmd); 1117 1118 spin_lock(&priv->wsm_cmd.lock); 1119 BUG_ON(priv->wsm_cmd.ptr); 1120 priv->wsm_cmd.ptr = buf->begin; 1121 priv->wsm_cmd.len = buf_len; 1122 priv->wsm_cmd.arg = arg; 1123 priv->wsm_cmd.cmd = cmd; 1124 spin_unlock(&priv->wsm_cmd.lock); 1125 1126 cw1200_bh_wakeup(priv); 1127 1128 /* Wait for command completion */ 1129 ret = wait_event_timeout(priv->wsm_cmd_wq, 1130 priv->wsm_cmd.done, tmo); 1131 1132 if (!ret && !priv->wsm_cmd.done) { 1133 spin_lock(&priv->wsm_cmd.lock); 1134 priv->wsm_cmd.done = 1; 1135 priv->wsm_cmd.ptr = NULL; 1136 spin_unlock(&priv->wsm_cmd.lock); 1137 if (priv->bh_error) { 1138 /* Return ok to help system cleanup */ 1139 ret = 0; 1140 } else { 1141 pr_err("CMD req (0x%04x) stuck in firmware, killing BH\n", priv->wsm_cmd.cmd); 1142 print_hex_dump_bytes("REQDUMP: ", DUMP_PREFIX_NONE, 1143 buf->begin, buf_len); 1144 pr_err("Outstanding outgoing frames: %d\n", priv->hw_bufs_used); 1145 1146 /* Kill BH thread to report the error to the top layer. */ 1147 atomic_add(1, &priv->bh_term); 1148 wake_up(&priv->bh_wq); 1149 ret = -ETIMEDOUT; 1150 } 1151 } else { 1152 spin_lock(&priv->wsm_cmd.lock); 1153 BUG_ON(!priv->wsm_cmd.done); 1154 ret = priv->wsm_cmd.ret; 1155 spin_unlock(&priv->wsm_cmd.lock); 1156 } 1157 done: 1158 wsm_buf_reset(buf); 1159 return ret; 1160 } 1161 1162 /* ******************************************************************** */ 1163 /* WSM TX port control */ 1164 1165 void wsm_lock_tx(struct cw1200_common *priv) 1166 { 1167 wsm_cmd_lock(priv); 1168 if (atomic_add_return(1, &priv->tx_lock) == 1) { 1169 if (wsm_flush_tx(priv)) 1170 pr_debug("[WSM] TX is locked.\n"); 1171 } 1172 wsm_cmd_unlock(priv); 1173 } 1174 1175 void wsm_lock_tx_async(struct cw1200_common *priv) 1176 { 1177 if (atomic_add_return(1, &priv->tx_lock) == 1) 1178 pr_debug("[WSM] TX is locked (async).\n"); 1179 } 1180 1181 bool wsm_flush_tx(struct cw1200_common *priv) 1182 { 1183 unsigned long timestamp = jiffies; 1184 bool pending = false; 1185 long timeout; 1186 int i; 1187 1188 /* Flush must be called with TX lock held. */ 1189 BUG_ON(!atomic_read(&priv->tx_lock)); 1190 1191 /* First check if we really need to do something. 1192 * It is safe to use unprotected access, as hw_bufs_used 1193 * can only decrements. 1194 */ 1195 if (!priv->hw_bufs_used) 1196 return true; 1197 1198 if (priv->bh_error) { 1199 /* In case of failure do not wait for magic. */ 1200 pr_err("[WSM] Fatal error occurred, will not flush TX.\n"); 1201 return false; 1202 } else { 1203 /* Get a timestamp of "oldest" frame */ 1204 for (i = 0; i < 4; ++i) 1205 pending |= cw1200_queue_get_xmit_timestamp( 1206 &priv->tx_queue[i], 1207 ×tamp, 0xffffffff); 1208 /* If there's nothing pending, we're good */ 1209 if (!pending) 1210 return true; 1211 1212 timeout = timestamp + WSM_CMD_LAST_CHANCE_TIMEOUT - jiffies; 1213 if (timeout < 0 || wait_event_timeout(priv->bh_evt_wq, 1214 !priv->hw_bufs_used, 1215 timeout) <= 0) { 1216 /* Hmmm... Not good. Frame had stuck in firmware. */ 1217 priv->bh_error = 1; 1218 wiphy_err(priv->hw->wiphy, "[WSM] TX Frames (%d) stuck in firmware, killing BH\n", priv->hw_bufs_used); 1219 wake_up(&priv->bh_wq); 1220 return false; 1221 } 1222 1223 /* Ok, everything is flushed. */ 1224 return true; 1225 } 1226 } 1227 1228 void wsm_unlock_tx(struct cw1200_common *priv) 1229 { 1230 int tx_lock; 1231 tx_lock = atomic_sub_return(1, &priv->tx_lock); 1232 BUG_ON(tx_lock < 0); 1233 1234 if (tx_lock == 0) { 1235 if (!priv->bh_error) 1236 cw1200_bh_wakeup(priv); 1237 pr_debug("[WSM] TX is unlocked.\n"); 1238 } 1239 } 1240 1241 /* ******************************************************************** */ 1242 /* WSM RX */ 1243 1244 int wsm_handle_exception(struct cw1200_common *priv, u8 *data, size_t len) 1245 { 1246 struct wsm_buf buf; 1247 u32 reason; 1248 u32 reg[18]; 1249 char fname[48]; 1250 unsigned int i; 1251 1252 static const char * const reason_str[] = { 1253 "undefined instruction", 1254 "prefetch abort", 1255 "data abort", 1256 "unknown error", 1257 }; 1258 1259 buf.begin = buf.data = data; 1260 buf.end = &buf.begin[len]; 1261 1262 reason = WSM_GET32(&buf); 1263 for (i = 0; i < ARRAY_SIZE(reg); ++i) 1264 reg[i] = WSM_GET32(&buf); 1265 WSM_GET(&buf, fname, sizeof(fname)); 1266 1267 if (reason < 4) 1268 wiphy_err(priv->hw->wiphy, 1269 "Firmware exception: %s.\n", 1270 reason_str[reason]); 1271 else 1272 wiphy_err(priv->hw->wiphy, 1273 "Firmware assert at %.*s, line %d\n", 1274 (int) sizeof(fname), fname, reg[1]); 1275 1276 for (i = 0; i < 12; i += 4) 1277 wiphy_err(priv->hw->wiphy, 1278 "R%d: 0x%.8X, R%d: 0x%.8X, R%d: 0x%.8X, R%d: 0x%.8X,\n", 1279 i + 0, reg[i + 0], i + 1, reg[i + 1], 1280 i + 2, reg[i + 2], i + 3, reg[i + 3]); 1281 wiphy_err(priv->hw->wiphy, 1282 "R12: 0x%.8X, SP: 0x%.8X, LR: 0x%.8X, PC: 0x%.8X,\n", 1283 reg[i + 0], reg[i + 1], reg[i + 2], reg[i + 3]); 1284 i += 4; 1285 wiphy_err(priv->hw->wiphy, 1286 "CPSR: 0x%.8X, SPSR: 0x%.8X\n", 1287 reg[i + 0], reg[i + 1]); 1288 1289 print_hex_dump_bytes("R1: ", DUMP_PREFIX_NONE, 1290 fname, sizeof(fname)); 1291 return 0; 1292 1293 underflow: 1294 wiphy_err(priv->hw->wiphy, "Firmware exception.\n"); 1295 print_hex_dump_bytes("Exception: ", DUMP_PREFIX_NONE, 1296 data, len); 1297 return -EINVAL; 1298 } 1299 1300 int wsm_handle_rx(struct cw1200_common *priv, u16 id, 1301 struct wsm_hdr *wsm, struct sk_buff **skb_p) 1302 { 1303 int ret = 0; 1304 struct wsm_buf wsm_buf; 1305 int link_id = (id >> 6) & 0x0F; 1306 1307 /* Strip link id. */ 1308 id &= ~WSM_TX_LINK_ID(WSM_TX_LINK_ID_MAX); 1309 1310 wsm_buf.begin = (u8 *)&wsm[0]; 1311 wsm_buf.data = (u8 *)&wsm[1]; 1312 wsm_buf.end = &wsm_buf.begin[__le16_to_cpu(wsm->len)]; 1313 1314 pr_debug("[WSM] <<< 0x%.4X (%td)\n", id, 1315 wsm_buf.end - wsm_buf.begin); 1316 1317 if (id == WSM_TX_CONFIRM_IND_ID) { 1318 ret = wsm_tx_confirm(priv, &wsm_buf, link_id); 1319 } else if (id == WSM_MULTI_TX_CONFIRM_ID) { 1320 ret = wsm_multi_tx_confirm(priv, &wsm_buf, link_id); 1321 } else if (id & 0x0400) { 1322 void *wsm_arg; 1323 u16 wsm_cmd; 1324 1325 /* Do not trust FW too much. Protection against repeated 1326 * response and race condition removal (see above). 1327 */ 1328 spin_lock(&priv->wsm_cmd.lock); 1329 wsm_arg = priv->wsm_cmd.arg; 1330 wsm_cmd = priv->wsm_cmd.cmd & 1331 ~WSM_TX_LINK_ID(WSM_TX_LINK_ID_MAX); 1332 priv->wsm_cmd.cmd = 0xFFFF; 1333 spin_unlock(&priv->wsm_cmd.lock); 1334 1335 if (WARN_ON((id & ~0x0400) != wsm_cmd)) { 1336 /* Note that any non-zero is a fatal retcode. */ 1337 ret = -EINVAL; 1338 goto out; 1339 } 1340 1341 /* Note that wsm_arg can be NULL in case of timeout in 1342 * wsm_cmd_send(). 1343 */ 1344 1345 switch (id) { 1346 case WSM_READ_MIB_RESP_ID: 1347 if (wsm_arg) 1348 ret = wsm_read_mib_confirm(priv, wsm_arg, 1349 &wsm_buf); 1350 break; 1351 case WSM_WRITE_MIB_RESP_ID: 1352 if (wsm_arg) 1353 ret = wsm_write_mib_confirm(priv, wsm_arg, 1354 &wsm_buf); 1355 break; 1356 case WSM_START_SCAN_RESP_ID: 1357 if (wsm_arg) 1358 ret = wsm_scan_started(priv, wsm_arg, &wsm_buf); 1359 break; 1360 case WSM_CONFIGURATION_RESP_ID: 1361 if (wsm_arg) 1362 ret = wsm_configuration_confirm(priv, wsm_arg, 1363 &wsm_buf); 1364 break; 1365 case WSM_JOIN_RESP_ID: 1366 if (wsm_arg) 1367 ret = wsm_join_confirm(priv, wsm_arg, &wsm_buf); 1368 break; 1369 case WSM_STOP_SCAN_RESP_ID: 1370 case WSM_RESET_RESP_ID: 1371 case WSM_ADD_KEY_RESP_ID: 1372 case WSM_REMOVE_KEY_RESP_ID: 1373 case WSM_SET_PM_RESP_ID: 1374 case WSM_SET_BSS_PARAMS_RESP_ID: 1375 case 0x0412: /* set_tx_queue_params */ 1376 case WSM_EDCA_PARAMS_RESP_ID: 1377 case WSM_SWITCH_CHANNEL_RESP_ID: 1378 case WSM_START_RESP_ID: 1379 case WSM_BEACON_TRANSMIT_RESP_ID: 1380 case 0x0419: /* start_find */ 1381 case 0x041A: /* stop_find */ 1382 case 0x041B: /* update_ie */ 1383 case 0x041C: /* map_link */ 1384 WARN_ON(wsm_arg != NULL); 1385 ret = wsm_generic_confirm(priv, wsm_arg, &wsm_buf); 1386 if (ret) { 1387 wiphy_warn(priv->hw->wiphy, 1388 "wsm_generic_confirm failed for request 0x%04x.\n", 1389 id & ~0x0400); 1390 1391 /* often 0x407 and 0x410 occur, this means we're dead.. */ 1392 if (priv->join_status >= CW1200_JOIN_STATUS_JOINING) { 1393 wsm_lock_tx(priv); 1394 if (queue_work(priv->workqueue, &priv->unjoin_work) <= 0) 1395 wsm_unlock_tx(priv); 1396 } 1397 } 1398 break; 1399 default: 1400 wiphy_warn(priv->hw->wiphy, 1401 "Unrecognized confirmation 0x%04x\n", 1402 id & ~0x0400); 1403 } 1404 1405 spin_lock(&priv->wsm_cmd.lock); 1406 priv->wsm_cmd.ret = ret; 1407 priv->wsm_cmd.done = 1; 1408 spin_unlock(&priv->wsm_cmd.lock); 1409 1410 ret = 0; /* Error response from device should ne stop BH. */ 1411 1412 wake_up(&priv->wsm_cmd_wq); 1413 } else if (id & 0x0800) { 1414 switch (id) { 1415 case WSM_STARTUP_IND_ID: 1416 ret = wsm_startup_indication(priv, &wsm_buf); 1417 break; 1418 case WSM_RECEIVE_IND_ID: 1419 ret = wsm_receive_indication(priv, link_id, 1420 &wsm_buf, skb_p); 1421 break; 1422 case 0x0805: 1423 ret = wsm_event_indication(priv, &wsm_buf); 1424 break; 1425 case WSM_SCAN_COMPLETE_IND_ID: 1426 ret = wsm_scan_complete_indication(priv, &wsm_buf); 1427 break; 1428 case 0x0808: 1429 ret = wsm_ba_timeout_indication(priv, &wsm_buf); 1430 break; 1431 case 0x0809: 1432 ret = wsm_set_pm_indication(priv, &wsm_buf); 1433 break; 1434 case 0x080A: 1435 ret = wsm_channel_switch_indication(priv, &wsm_buf); 1436 break; 1437 case 0x080B: 1438 ret = wsm_find_complete_indication(priv, &wsm_buf); 1439 break; 1440 case 0x080C: 1441 ret = wsm_suspend_resume_indication(priv, 1442 link_id, &wsm_buf); 1443 break; 1444 case 0x080F: 1445 ret = wsm_join_complete_indication(priv, &wsm_buf); 1446 break; 1447 default: 1448 pr_warn("Unrecognised WSM ID %04x\n", id); 1449 } 1450 } else { 1451 WARN_ON(1); 1452 ret = -EINVAL; 1453 } 1454 out: 1455 return ret; 1456 } 1457 1458 static bool wsm_handle_tx_data(struct cw1200_common *priv, 1459 struct wsm_tx *wsm, 1460 const struct ieee80211_tx_info *tx_info, 1461 const struct cw1200_txpriv *txpriv, 1462 struct cw1200_queue *queue) 1463 { 1464 bool handled = false; 1465 const struct ieee80211_hdr *frame = 1466 (struct ieee80211_hdr *)&((u8 *)wsm)[txpriv->offset]; 1467 __le16 fctl = frame->frame_control; 1468 enum { 1469 do_probe, 1470 do_drop, 1471 do_wep, 1472 do_tx, 1473 } action = do_tx; 1474 1475 switch (priv->mode) { 1476 case NL80211_IFTYPE_STATION: 1477 if (priv->join_status == CW1200_JOIN_STATUS_MONITOR) 1478 action = do_tx; 1479 else if (priv->join_status < CW1200_JOIN_STATUS_PRE_STA) 1480 action = do_drop; 1481 break; 1482 case NL80211_IFTYPE_AP: 1483 if (!priv->join_status) { 1484 action = do_drop; 1485 } else if (!(BIT(txpriv->raw_link_id) & 1486 (BIT(0) | priv->link_id_map))) { 1487 wiphy_warn(priv->hw->wiphy, 1488 "A frame with expired link id is dropped.\n"); 1489 action = do_drop; 1490 } 1491 if (cw1200_queue_get_generation(wsm->packet_id) > 1492 CW1200_MAX_REQUEUE_ATTEMPTS) { 1493 /* HACK!!! WSM324 firmware has tendency to requeue 1494 * multicast frames in a loop, causing performance 1495 * drop and high power consumption of the driver. 1496 * In this situation it is better just to drop 1497 * the problematic frame. 1498 */ 1499 wiphy_warn(priv->hw->wiphy, 1500 "Too many attempts to requeue a frame; dropped.\n"); 1501 action = do_drop; 1502 } 1503 break; 1504 case NL80211_IFTYPE_ADHOC: 1505 if (priv->join_status != CW1200_JOIN_STATUS_IBSS) 1506 action = do_drop; 1507 break; 1508 case NL80211_IFTYPE_MESH_POINT: 1509 action = do_tx; /* TODO: Test me! */ 1510 break; 1511 case NL80211_IFTYPE_MONITOR: 1512 default: 1513 action = do_drop; 1514 break; 1515 } 1516 1517 if (action == do_tx) { 1518 if (ieee80211_is_nullfunc(fctl)) { 1519 spin_lock(&priv->bss_loss_lock); 1520 if (priv->bss_loss_state) { 1521 priv->bss_loss_confirm_id = wsm->packet_id; 1522 wsm->queue_id = WSM_QUEUE_VOICE; 1523 } 1524 spin_unlock(&priv->bss_loss_lock); 1525 } else if (ieee80211_is_probe_req(fctl)) { 1526 action = do_probe; 1527 } else if (ieee80211_is_deauth(fctl) && 1528 priv->mode != NL80211_IFTYPE_AP) { 1529 pr_debug("[WSM] Issue unjoin command due to tx deauth.\n"); 1530 wsm_lock_tx_async(priv); 1531 if (queue_work(priv->workqueue, 1532 &priv->unjoin_work) <= 0) 1533 wsm_unlock_tx(priv); 1534 } else if (ieee80211_has_protected(fctl) && 1535 tx_info->control.hw_key && 1536 tx_info->control.hw_key->keyidx != priv->wep_default_key_id && 1537 (tx_info->control.hw_key->cipher == WLAN_CIPHER_SUITE_WEP40 || 1538 tx_info->control.hw_key->cipher == WLAN_CIPHER_SUITE_WEP104)) { 1539 action = do_wep; 1540 } 1541 } 1542 1543 switch (action) { 1544 case do_probe: 1545 /* An interesting FW "feature". Device filters probe responses. 1546 * The easiest way to get it back is to convert 1547 * probe request into WSM start_scan command. 1548 */ 1549 pr_debug("[WSM] Convert probe request to scan.\n"); 1550 wsm_lock_tx_async(priv); 1551 priv->pending_frame_id = wsm->packet_id; 1552 if (queue_delayed_work(priv->workqueue, 1553 &priv->scan.probe_work, 0) <= 0) 1554 wsm_unlock_tx(priv); 1555 handled = true; 1556 break; 1557 case do_drop: 1558 pr_debug("[WSM] Drop frame (0x%.4X).\n", fctl); 1559 BUG_ON(cw1200_queue_remove(queue, wsm->packet_id)); 1560 handled = true; 1561 break; 1562 case do_wep: 1563 pr_debug("[WSM] Issue set_default_wep_key.\n"); 1564 wsm_lock_tx_async(priv); 1565 priv->wep_default_key_id = tx_info->control.hw_key->keyidx; 1566 priv->pending_frame_id = wsm->packet_id; 1567 if (queue_work(priv->workqueue, &priv->wep_key_work) <= 0) 1568 wsm_unlock_tx(priv); 1569 handled = true; 1570 break; 1571 case do_tx: 1572 pr_debug("[WSM] Transmit frame.\n"); 1573 break; 1574 default: 1575 /* Do nothing */ 1576 break; 1577 } 1578 return handled; 1579 } 1580 1581 static int cw1200_get_prio_queue(struct cw1200_common *priv, 1582 u32 link_id_map, int *total) 1583 { 1584 static const int urgent = BIT(CW1200_LINK_ID_AFTER_DTIM) | 1585 BIT(CW1200_LINK_ID_UAPSD); 1586 struct wsm_edca_queue_params *edca; 1587 unsigned score, best = -1; 1588 int winner = -1; 1589 int queued; 1590 int i; 1591 1592 /* search for a winner using edca params */ 1593 for (i = 0; i < 4; ++i) { 1594 queued = cw1200_queue_get_num_queued(&priv->tx_queue[i], 1595 link_id_map); 1596 if (!queued) 1597 continue; 1598 *total += queued; 1599 edca = &priv->edca.params[i]; 1600 score = ((edca->aifns + edca->cwmin) << 16) + 1601 ((edca->cwmax - edca->cwmin) * 1602 (get_random_int() & 0xFFFF)); 1603 if (score < best && (winner < 0 || i != 3)) { 1604 best = score; 1605 winner = i; 1606 } 1607 } 1608 1609 /* override winner if bursting */ 1610 if (winner >= 0 && priv->tx_burst_idx >= 0 && 1611 winner != priv->tx_burst_idx && 1612 !cw1200_queue_get_num_queued( 1613 &priv->tx_queue[winner], 1614 link_id_map & urgent) && 1615 cw1200_queue_get_num_queued( 1616 &priv->tx_queue[priv->tx_burst_idx], 1617 link_id_map)) 1618 winner = priv->tx_burst_idx; 1619 1620 return winner; 1621 } 1622 1623 static int wsm_get_tx_queue_and_mask(struct cw1200_common *priv, 1624 struct cw1200_queue **queue_p, 1625 u32 *tx_allowed_mask_p, 1626 bool *more) 1627 { 1628 int idx; 1629 u32 tx_allowed_mask; 1630 int total = 0; 1631 1632 /* Search for a queue with multicast frames buffered */ 1633 if (priv->tx_multicast) { 1634 tx_allowed_mask = BIT(CW1200_LINK_ID_AFTER_DTIM); 1635 idx = cw1200_get_prio_queue(priv, 1636 tx_allowed_mask, &total); 1637 if (idx >= 0) { 1638 *more = total > 1; 1639 goto found; 1640 } 1641 } 1642 1643 /* Search for unicast traffic */ 1644 tx_allowed_mask = ~priv->sta_asleep_mask; 1645 tx_allowed_mask |= BIT(CW1200_LINK_ID_UAPSD); 1646 if (priv->sta_asleep_mask) { 1647 tx_allowed_mask |= priv->pspoll_mask; 1648 tx_allowed_mask &= ~BIT(CW1200_LINK_ID_AFTER_DTIM); 1649 } else { 1650 tx_allowed_mask |= BIT(CW1200_LINK_ID_AFTER_DTIM); 1651 } 1652 idx = cw1200_get_prio_queue(priv, 1653 tx_allowed_mask, &total); 1654 if (idx < 0) 1655 return -ENOENT; 1656 1657 found: 1658 *queue_p = &priv->tx_queue[idx]; 1659 *tx_allowed_mask_p = tx_allowed_mask; 1660 return 0; 1661 } 1662 1663 int wsm_get_tx(struct cw1200_common *priv, u8 **data, 1664 size_t *tx_len, int *burst) 1665 { 1666 struct wsm_tx *wsm = NULL; 1667 struct ieee80211_tx_info *tx_info; 1668 struct cw1200_queue *queue = NULL; 1669 int queue_num; 1670 u32 tx_allowed_mask = 0; 1671 const struct cw1200_txpriv *txpriv = NULL; 1672 int count = 0; 1673 1674 /* More is used only for broadcasts. */ 1675 bool more = false; 1676 1677 if (priv->wsm_cmd.ptr) { /* CMD request */ 1678 ++count; 1679 spin_lock(&priv->wsm_cmd.lock); 1680 BUG_ON(!priv->wsm_cmd.ptr); 1681 *data = priv->wsm_cmd.ptr; 1682 *tx_len = priv->wsm_cmd.len; 1683 *burst = 1; 1684 spin_unlock(&priv->wsm_cmd.lock); 1685 } else { 1686 for (;;) { 1687 int ret; 1688 1689 if (atomic_add_return(0, &priv->tx_lock)) 1690 break; 1691 1692 spin_lock_bh(&priv->ps_state_lock); 1693 1694 ret = wsm_get_tx_queue_and_mask(priv, &queue, 1695 &tx_allowed_mask, &more); 1696 queue_num = queue - priv->tx_queue; 1697 1698 if (priv->buffered_multicasts && 1699 (ret || !more) && 1700 (priv->tx_multicast || !priv->sta_asleep_mask)) { 1701 priv->buffered_multicasts = false; 1702 if (priv->tx_multicast) { 1703 priv->tx_multicast = false; 1704 queue_work(priv->workqueue, 1705 &priv->multicast_stop_work); 1706 } 1707 } 1708 1709 spin_unlock_bh(&priv->ps_state_lock); 1710 1711 if (ret) 1712 break; 1713 1714 if (cw1200_queue_get(queue, 1715 tx_allowed_mask, 1716 &wsm, &tx_info, &txpriv)) 1717 continue; 1718 1719 if (wsm_handle_tx_data(priv, wsm, 1720 tx_info, txpriv, queue)) 1721 continue; /* Handled by WSM */ 1722 1723 wsm->hdr.id &= __cpu_to_le16( 1724 ~WSM_TX_LINK_ID(WSM_TX_LINK_ID_MAX)); 1725 wsm->hdr.id |= cpu_to_le16( 1726 WSM_TX_LINK_ID(txpriv->raw_link_id)); 1727 priv->pspoll_mask &= ~BIT(txpriv->raw_link_id); 1728 1729 *data = (u8 *)wsm; 1730 *tx_len = __le16_to_cpu(wsm->hdr.len); 1731 1732 /* allow bursting if txop is set */ 1733 if (priv->edca.params[queue_num].txop_limit) 1734 *burst = min(*burst, 1735 (int)cw1200_queue_get_num_queued(queue, tx_allowed_mask) + 1); 1736 else 1737 *burst = 1; 1738 1739 /* store index of bursting queue */ 1740 if (*burst > 1) 1741 priv->tx_burst_idx = queue_num; 1742 else 1743 priv->tx_burst_idx = -1; 1744 1745 if (more) { 1746 struct ieee80211_hdr *hdr = 1747 (struct ieee80211_hdr *) 1748 &((u8 *)wsm)[txpriv->offset]; 1749 /* more buffered multicast/broadcast frames 1750 * ==> set MoreData flag in IEEE 802.11 header 1751 * to inform PS STAs 1752 */ 1753 hdr->frame_control |= 1754 cpu_to_le16(IEEE80211_FCTL_MOREDATA); 1755 } 1756 1757 pr_debug("[WSM] >>> 0x%.4X (%zu) %p %c\n", 1758 0x0004, *tx_len, *data, 1759 wsm->more ? 'M' : ' '); 1760 ++count; 1761 break; 1762 } 1763 } 1764 1765 return count; 1766 } 1767 1768 void wsm_txed(struct cw1200_common *priv, u8 *data) 1769 { 1770 if (data == priv->wsm_cmd.ptr) { 1771 spin_lock(&priv->wsm_cmd.lock); 1772 priv->wsm_cmd.ptr = NULL; 1773 spin_unlock(&priv->wsm_cmd.lock); 1774 } 1775 } 1776 1777 /* ******************************************************************** */ 1778 /* WSM buffer */ 1779 1780 void wsm_buf_init(struct wsm_buf *buf) 1781 { 1782 BUG_ON(buf->begin); 1783 buf->begin = kmalloc(FWLOAD_BLOCK_SIZE, GFP_KERNEL | GFP_DMA); 1784 buf->end = buf->begin ? &buf->begin[FWLOAD_BLOCK_SIZE] : buf->begin; 1785 wsm_buf_reset(buf); 1786 } 1787 1788 void wsm_buf_deinit(struct wsm_buf *buf) 1789 { 1790 kfree(buf->begin); 1791 buf->begin = buf->data = buf->end = NULL; 1792 } 1793 1794 static void wsm_buf_reset(struct wsm_buf *buf) 1795 { 1796 if (buf->begin) { 1797 buf->data = &buf->begin[4]; 1798 *(u32 *)buf->begin = 0; 1799 } else { 1800 buf->data = buf->begin; 1801 } 1802 } 1803 1804 static int wsm_buf_reserve(struct wsm_buf *buf, size_t extra_size) 1805 { 1806 size_t pos = buf->data - buf->begin; 1807 size_t size = pos + extra_size; 1808 u8 *tmp; 1809 1810 size = round_up(size, FWLOAD_BLOCK_SIZE); 1811 1812 tmp = krealloc(buf->begin, size, GFP_KERNEL | GFP_DMA); 1813 if (!tmp) { 1814 wsm_buf_deinit(buf); 1815 return -ENOMEM; 1816 } 1817 1818 buf->begin = tmp; 1819 buf->data = &buf->begin[pos]; 1820 buf->end = &buf->begin[size]; 1821 return 0; 1822 } 1823