linux/drivers/net/wireless/st/cw1200/wsm.c
<<
>>
Prefs
   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        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                                        &timestamp, 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}
1818