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