Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * WSM host interface (HI) implementation for
0004  * ST-Ericsson CW1200 mac80211 drivers.
0005  *
0006  * Copyright (c) 2010, ST-Ericsson
0007  * Author: Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>
0008  */
0009 
0010 #include <linux/skbuff.h>
0011 #include <linux/wait.h>
0012 #include <linux/delay.h>
0013 #include <linux/sched.h>
0014 #include <linux/random.h>
0015 
0016 #include "cw1200.h"
0017 #include "wsm.h"
0018 #include "bh.h"
0019 #include "sta.h"
0020 #include "debug.h"
0021 
0022 #define WSM_CMD_TIMEOUT     (2 * HZ) /* With respect to interrupt loss */
0023 #define WSM_CMD_START_TIMEOUT   (7 * HZ)
0024 #define WSM_CMD_RESET_TIMEOUT   (3 * HZ) /* 2 sec. timeout was observed.   */
0025 #define WSM_CMD_MAX_TIMEOUT (3 * HZ)
0026 
0027 #define WSM_SKIP(buf, size)                     \
0028     do {                                \
0029         if ((buf)->data + size > (buf)->end)            \
0030             goto underflow;                 \
0031         (buf)->data += size;                    \
0032     } while (0)
0033 
0034 #define WSM_GET(buf, ptr, size)                     \
0035     do {                                \
0036         if ((buf)->data + size > (buf)->end)            \
0037             goto underflow;                 \
0038         memcpy(ptr, (buf)->data, size);             \
0039         (buf)->data += size;                    \
0040     } while (0)
0041 
0042 #define __WSM_GET(buf, type, type2, cvt)                \
0043     ({                              \
0044         type val;                       \
0045         if ((buf)->data + sizeof(type) > (buf)->end)        \
0046             goto underflow;                 \
0047         val = cvt(*(type2 *)(buf)->data);           \
0048         (buf)->data += sizeof(type);                \
0049         val;                            \
0050     })
0051 
0052 #define WSM_GET8(buf)  __WSM_GET(buf, u8, u8, (u8))
0053 #define WSM_GET16(buf) __WSM_GET(buf, u16, __le16, __le16_to_cpu)
0054 #define WSM_GET32(buf) __WSM_GET(buf, u32, __le32, __le32_to_cpu)
0055 
0056 #define WSM_PUT(buf, ptr, size)                     \
0057     do {                                \
0058         if ((buf)->data + size > (buf)->end)        \
0059             if (wsm_buf_reserve((buf), size))   \
0060                 goto nomem;             \
0061         memcpy((buf)->data, ptr, size);             \
0062         (buf)->data += size;                    \
0063     } while (0)
0064 
0065 #define __WSM_PUT(buf, val, type, type2, cvt)               \
0066     do {                                \
0067         if ((buf)->data + sizeof(type) > (buf)->end)        \
0068             if (wsm_buf_reserve((buf), sizeof(type))) \
0069                 goto nomem;             \
0070         *(type2 *)(buf)->data = cvt(val);           \
0071         (buf)->data += sizeof(type);                \
0072     } while (0)
0073 
0074 #define WSM_PUT8(buf, val)  __WSM_PUT(buf, val, u8, u8, (u8))
0075 #define WSM_PUT16(buf, val) __WSM_PUT(buf, val, u16, __le16, __cpu_to_le16)
0076 #define WSM_PUT32(buf, val) __WSM_PUT(buf, val, u32, __le32, __cpu_to_le32)
0077 
0078 static void wsm_buf_reset(struct wsm_buf *buf);
0079 static int wsm_buf_reserve(struct wsm_buf *buf, size_t extra_size);
0080 
0081 static int wsm_cmd_send(struct cw1200_common *priv,
0082             struct wsm_buf *buf,
0083             void *arg, u16 cmd, long tmo);
0084 
0085 #define wsm_cmd_lock(__priv) mutex_lock(&((__priv)->wsm_cmd_mux))
0086 #define wsm_cmd_unlock(__priv) mutex_unlock(&((__priv)->wsm_cmd_mux))
0087 
0088 /* ******************************************************************** */
0089 /* WSM API implementation                       */
0090 
0091 static int wsm_generic_confirm(struct cw1200_common *priv,
0092                  void *arg,
0093                  struct wsm_buf *buf)
0094 {
0095     u32 status = WSM_GET32(buf);
0096     if (status != WSM_STATUS_SUCCESS)
0097         return -EINVAL;
0098     return 0;
0099 
0100 underflow:
0101     WARN_ON(1);
0102     return -EINVAL;
0103 }
0104 
0105 int wsm_configuration(struct cw1200_common *priv, struct wsm_configuration *arg)
0106 {
0107     int ret;
0108     struct wsm_buf *buf = &priv->wsm_cmd_buf;
0109 
0110     wsm_cmd_lock(priv);
0111 
0112     WSM_PUT32(buf, arg->dot11MaxTransmitMsduLifeTime);
0113     WSM_PUT32(buf, arg->dot11MaxReceiveLifeTime);
0114     WSM_PUT32(buf, arg->dot11RtsThreshold);
0115 
0116     /* DPD block. */
0117     WSM_PUT16(buf, arg->dpdData_size + 12);
0118     WSM_PUT16(buf, 1); /* DPD version */
0119     WSM_PUT(buf, arg->dot11StationId, ETH_ALEN);
0120     WSM_PUT16(buf, 5); /* DPD flags */
0121     WSM_PUT(buf, arg->dpdData, arg->dpdData_size);
0122 
0123     ret = wsm_cmd_send(priv, buf, arg,
0124                WSM_CONFIGURATION_REQ_ID, WSM_CMD_TIMEOUT);
0125 
0126     wsm_cmd_unlock(priv);
0127     return ret;
0128 
0129 nomem:
0130     wsm_cmd_unlock(priv);
0131     return -ENOMEM;
0132 }
0133 
0134 static int wsm_configuration_confirm(struct cw1200_common *priv,
0135                      struct wsm_configuration *arg,
0136                      struct wsm_buf *buf)
0137 {
0138     int i;
0139     int status;
0140 
0141     status = WSM_GET32(buf);
0142     if (WARN_ON(status != WSM_STATUS_SUCCESS))
0143         return -EINVAL;
0144 
0145     WSM_GET(buf, arg->dot11StationId, ETH_ALEN);
0146     arg->dot11FrequencyBandsSupported = WSM_GET8(buf);
0147     WSM_SKIP(buf, 1);
0148     arg->supportedRateMask = WSM_GET32(buf);
0149     for (i = 0; i < 2; ++i) {
0150         arg->txPowerRange[i].min_power_level = WSM_GET32(buf);
0151         arg->txPowerRange[i].max_power_level = WSM_GET32(buf);
0152         arg->txPowerRange[i].stepping = WSM_GET32(buf);
0153     }
0154     return 0;
0155 
0156 underflow:
0157     WARN_ON(1);
0158     return -EINVAL;
0159 }
0160 
0161 /* ******************************************************************** */
0162 
0163 int wsm_reset(struct cw1200_common *priv, const struct wsm_reset *arg)
0164 {
0165     int ret;
0166     struct wsm_buf *buf = &priv->wsm_cmd_buf;
0167     u16 cmd = WSM_RESET_REQ_ID | WSM_TX_LINK_ID(arg->link_id);
0168 
0169     wsm_cmd_lock(priv);
0170 
0171     WSM_PUT32(buf, arg->reset_statistics ? 0 : 1);
0172     ret = wsm_cmd_send(priv, buf, NULL, cmd, WSM_CMD_RESET_TIMEOUT);
0173     wsm_cmd_unlock(priv);
0174     return ret;
0175 
0176 nomem:
0177     wsm_cmd_unlock(priv);
0178     return -ENOMEM;
0179 }
0180 
0181 /* ******************************************************************** */
0182 
0183 struct wsm_mib {
0184     u16 mib_id;
0185     void *buf;
0186     size_t buf_size;
0187 };
0188 
0189 int wsm_read_mib(struct cw1200_common *priv, u16 mib_id, void *_buf,
0190             size_t buf_size)
0191 {
0192     int ret;
0193     struct wsm_buf *buf = &priv->wsm_cmd_buf;
0194     struct wsm_mib mib_buf = {
0195         .mib_id = mib_id,
0196         .buf = _buf,
0197         .buf_size = buf_size,
0198     };
0199     wsm_cmd_lock(priv);
0200 
0201     WSM_PUT16(buf, mib_id);
0202     WSM_PUT16(buf, 0);
0203 
0204     ret = wsm_cmd_send(priv, buf, &mib_buf,
0205                WSM_READ_MIB_REQ_ID, WSM_CMD_TIMEOUT);
0206     wsm_cmd_unlock(priv);
0207     return ret;
0208 
0209 nomem:
0210     wsm_cmd_unlock(priv);
0211     return -ENOMEM;
0212 }
0213 
0214 static int wsm_read_mib_confirm(struct cw1200_common *priv,
0215                 struct wsm_mib *arg,
0216                 struct wsm_buf *buf)
0217 {
0218     u16 size;
0219     if (WARN_ON(WSM_GET32(buf) != WSM_STATUS_SUCCESS))
0220         return -EINVAL;
0221 
0222     if (WARN_ON(WSM_GET16(buf) != arg->mib_id))
0223         return -EINVAL;
0224 
0225     size = WSM_GET16(buf);
0226     if (size > arg->buf_size)
0227         size = arg->buf_size;
0228 
0229     WSM_GET(buf, arg->buf, size);
0230     arg->buf_size = size;
0231     return 0;
0232 
0233 underflow:
0234     WARN_ON(1);
0235     return -EINVAL;
0236 }
0237 
0238 /* ******************************************************************** */
0239 
0240 int wsm_write_mib(struct cw1200_common *priv, u16 mib_id, void *_buf,
0241             size_t buf_size)
0242 {
0243     int ret;
0244     struct wsm_buf *buf = &priv->wsm_cmd_buf;
0245     struct wsm_mib mib_buf = {
0246         .mib_id = mib_id,
0247         .buf = _buf,
0248         .buf_size = buf_size,
0249     };
0250 
0251     wsm_cmd_lock(priv);
0252 
0253     WSM_PUT16(buf, mib_id);
0254     WSM_PUT16(buf, buf_size);
0255     WSM_PUT(buf, _buf, buf_size);
0256 
0257     ret = wsm_cmd_send(priv, buf, &mib_buf,
0258                WSM_WRITE_MIB_REQ_ID, WSM_CMD_TIMEOUT);
0259     wsm_cmd_unlock(priv);
0260     return ret;
0261 
0262 nomem:
0263     wsm_cmd_unlock(priv);
0264     return -ENOMEM;
0265 }
0266 
0267 static int wsm_write_mib_confirm(struct cw1200_common *priv,
0268                 struct wsm_mib *arg,
0269                 struct wsm_buf *buf)
0270 {
0271     int ret;
0272 
0273     ret = wsm_generic_confirm(priv, arg, buf);
0274     if (ret)
0275         return ret;
0276 
0277     if (arg->mib_id == WSM_MIB_ID_OPERATIONAL_POWER_MODE) {
0278         /* OperationalMode: update PM status. */
0279         const char *p = arg->buf;
0280         cw1200_enable_powersave(priv, (p[0] & 0x0F) ? true : false);
0281     }
0282     return 0;
0283 }
0284 
0285 /* ******************************************************************** */
0286 
0287 int wsm_scan(struct cw1200_common *priv, const struct wsm_scan *arg)
0288 {
0289     int i;
0290     int ret;
0291     struct wsm_buf *buf = &priv->wsm_cmd_buf;
0292 
0293     if (arg->num_channels > 48)
0294         return -EINVAL;
0295 
0296     if (arg->num_ssids > 2)
0297         return -EINVAL;
0298 
0299     if (arg->band > 1)
0300         return -EINVAL;
0301 
0302     wsm_cmd_lock(priv);
0303 
0304     WSM_PUT8(buf, arg->band);
0305     WSM_PUT8(buf, arg->type);
0306     WSM_PUT8(buf, arg->flags);
0307     WSM_PUT8(buf, arg->max_tx_rate);
0308     WSM_PUT32(buf, arg->auto_scan_interval);
0309     WSM_PUT8(buf, arg->num_probes);
0310     WSM_PUT8(buf, arg->num_channels);
0311     WSM_PUT8(buf, arg->num_ssids);
0312     WSM_PUT8(buf, arg->probe_delay);
0313 
0314     for (i = 0; i < arg->num_channels; ++i) {
0315         WSM_PUT16(buf, arg->ch[i].number);
0316         WSM_PUT16(buf, 0);
0317         WSM_PUT32(buf, arg->ch[i].min_chan_time);
0318         WSM_PUT32(buf, arg->ch[i].max_chan_time);
0319         WSM_PUT32(buf, 0);
0320     }
0321 
0322     for (i = 0; i < arg->num_ssids; ++i) {
0323         WSM_PUT32(buf, arg->ssids[i].length);
0324         WSM_PUT(buf, &arg->ssids[i].ssid[0],
0325             sizeof(arg->ssids[i].ssid));
0326     }
0327 
0328     ret = wsm_cmd_send(priv, buf, NULL,
0329                WSM_START_SCAN_REQ_ID, WSM_CMD_TIMEOUT);
0330     wsm_cmd_unlock(priv);
0331     return ret;
0332 
0333 nomem:
0334     wsm_cmd_unlock(priv);
0335     return -ENOMEM;
0336 }
0337 
0338 /* ******************************************************************** */
0339 
0340 int wsm_stop_scan(struct cw1200_common *priv)
0341 {
0342     int ret;
0343     struct wsm_buf *buf = &priv->wsm_cmd_buf;
0344     wsm_cmd_lock(priv);
0345     ret = wsm_cmd_send(priv, buf, NULL,
0346                WSM_STOP_SCAN_REQ_ID, WSM_CMD_TIMEOUT);
0347     wsm_cmd_unlock(priv);
0348     return ret;
0349 }
0350 
0351 
0352 static int wsm_tx_confirm(struct cw1200_common *priv,
0353               struct wsm_buf *buf,
0354               int link_id)
0355 {
0356     struct wsm_tx_confirm tx_confirm;
0357 
0358     tx_confirm.packet_id = WSM_GET32(buf);
0359     tx_confirm.status = WSM_GET32(buf);
0360     tx_confirm.tx_rate = WSM_GET8(buf);
0361     tx_confirm.ack_failures = WSM_GET8(buf);
0362     tx_confirm.flags = WSM_GET16(buf);
0363     tx_confirm.media_delay = WSM_GET32(buf);
0364     tx_confirm.tx_queue_delay = WSM_GET32(buf);
0365 
0366     cw1200_tx_confirm_cb(priv, link_id, &tx_confirm);
0367     return 0;
0368 
0369 underflow:
0370     WARN_ON(1);
0371     return -EINVAL;
0372 }
0373 
0374 static int wsm_multi_tx_confirm(struct cw1200_common *priv,
0375                 struct wsm_buf *buf, int link_id)
0376 {
0377     int ret;
0378     int count;
0379 
0380     count = WSM_GET32(buf);
0381     if (WARN_ON(count <= 0))
0382         return -EINVAL;
0383 
0384     if (count > 1) {
0385         /* We already released one buffer, now for the rest */
0386         ret = wsm_release_tx_buffer(priv, count - 1);
0387         if (ret < 0)
0388             return ret;
0389         else if (ret > 0)
0390             cw1200_bh_wakeup(priv);
0391     }
0392 
0393     cw1200_debug_txed_multi(priv, count);
0394     do {
0395         ret = wsm_tx_confirm(priv, buf, link_id);
0396     } while (!ret && --count);
0397 
0398     return ret;
0399 
0400 underflow:
0401     WARN_ON(1);
0402     return -EINVAL;
0403 }
0404 
0405 /* ******************************************************************** */
0406 
0407 static int wsm_join_confirm(struct cw1200_common *priv,
0408                 struct wsm_join_cnf *arg,
0409                 struct wsm_buf *buf)
0410 {
0411     arg->status = WSM_GET32(buf);
0412     if (WARN_ON(arg->status) != WSM_STATUS_SUCCESS)
0413         return -EINVAL;
0414 
0415     arg->min_power_level = WSM_GET32(buf);
0416     arg->max_power_level = WSM_GET32(buf);
0417 
0418     return 0;
0419 
0420 underflow:
0421     WARN_ON(1);
0422     return -EINVAL;
0423 }
0424 
0425 int wsm_join(struct cw1200_common *priv, struct wsm_join *arg)
0426 {
0427     int ret;
0428     struct wsm_buf *buf = &priv->wsm_cmd_buf;
0429     struct wsm_join_cnf resp;
0430     wsm_cmd_lock(priv);
0431 
0432     WSM_PUT8(buf, arg->mode);
0433     WSM_PUT8(buf, arg->band);
0434     WSM_PUT16(buf, arg->channel_number);
0435     WSM_PUT(buf, &arg->bssid[0], sizeof(arg->bssid));
0436     WSM_PUT16(buf, arg->atim_window);
0437     WSM_PUT8(buf, arg->preamble_type);
0438     WSM_PUT8(buf, arg->probe_for_join);
0439     WSM_PUT8(buf, arg->dtim_period);
0440     WSM_PUT8(buf, arg->flags);
0441     WSM_PUT32(buf, arg->ssid_len);
0442     WSM_PUT(buf, &arg->ssid[0], sizeof(arg->ssid));
0443     WSM_PUT32(buf, arg->beacon_interval);
0444     WSM_PUT32(buf, arg->basic_rate_set);
0445 
0446     priv->tx_burst_idx = -1;
0447     ret = wsm_cmd_send(priv, buf, &resp,
0448                WSM_JOIN_REQ_ID, WSM_CMD_TIMEOUT);
0449     /* TODO:  Update state based on resp.min|max_power_level */
0450 
0451     priv->join_complete_status = resp.status;
0452 
0453     wsm_cmd_unlock(priv);
0454     return ret;
0455 
0456 nomem:
0457     wsm_cmd_unlock(priv);
0458     return -ENOMEM;
0459 }
0460 
0461 /* ******************************************************************** */
0462 
0463 int wsm_set_bss_params(struct cw1200_common *priv,
0464                const struct wsm_set_bss_params *arg)
0465 {
0466     int ret;
0467     struct wsm_buf *buf = &priv->wsm_cmd_buf;
0468 
0469     wsm_cmd_lock(priv);
0470 
0471     WSM_PUT8(buf, (arg->reset_beacon_loss ?  0x1 : 0));
0472     WSM_PUT8(buf, arg->beacon_lost_count);
0473     WSM_PUT16(buf, arg->aid);
0474     WSM_PUT32(buf, arg->operational_rate_set);
0475 
0476     ret = wsm_cmd_send(priv, buf, NULL,
0477                WSM_SET_BSS_PARAMS_REQ_ID, WSM_CMD_TIMEOUT);
0478 
0479     wsm_cmd_unlock(priv);
0480     return ret;
0481 
0482 nomem:
0483     wsm_cmd_unlock(priv);
0484     return -ENOMEM;
0485 }
0486 
0487 /* ******************************************************************** */
0488 
0489 int wsm_add_key(struct cw1200_common *priv, const struct wsm_add_key *arg)
0490 {
0491     int ret;
0492     struct wsm_buf *buf = &priv->wsm_cmd_buf;
0493 
0494     wsm_cmd_lock(priv);
0495 
0496     WSM_PUT(buf, arg, sizeof(*arg));
0497 
0498     ret = wsm_cmd_send(priv, buf, NULL,
0499                WSM_ADD_KEY_REQ_ID, WSM_CMD_TIMEOUT);
0500 
0501     wsm_cmd_unlock(priv);
0502     return ret;
0503 
0504 nomem:
0505     wsm_cmd_unlock(priv);
0506     return -ENOMEM;
0507 }
0508 
0509 /* ******************************************************************** */
0510 
0511 int wsm_remove_key(struct cw1200_common *priv, const struct wsm_remove_key *arg)
0512 {
0513     int ret;
0514     struct wsm_buf *buf = &priv->wsm_cmd_buf;
0515 
0516     wsm_cmd_lock(priv);
0517 
0518     WSM_PUT8(buf, arg->index);
0519     WSM_PUT8(buf, 0);
0520     WSM_PUT16(buf, 0);
0521 
0522     ret = wsm_cmd_send(priv, buf, NULL,
0523                WSM_REMOVE_KEY_REQ_ID, WSM_CMD_TIMEOUT);
0524 
0525     wsm_cmd_unlock(priv);
0526     return ret;
0527 
0528 nomem:
0529     wsm_cmd_unlock(priv);
0530     return -ENOMEM;
0531 }
0532 
0533 /* ******************************************************************** */
0534 
0535 int wsm_set_tx_queue_params(struct cw1200_common *priv,
0536         const struct wsm_set_tx_queue_params *arg, u8 id)
0537 {
0538     int ret;
0539     struct wsm_buf *buf = &priv->wsm_cmd_buf;
0540     static const u8 queue_id_to_wmm_aci[] = { 3, 2, 0, 1 };
0541 
0542     wsm_cmd_lock(priv);
0543 
0544     WSM_PUT8(buf, queue_id_to_wmm_aci[id]);
0545     WSM_PUT8(buf, 0);
0546     WSM_PUT8(buf, arg->ackPolicy);
0547     WSM_PUT8(buf, 0);
0548     WSM_PUT32(buf, arg->maxTransmitLifetime);
0549     WSM_PUT16(buf, arg->allowedMediumTime);
0550     WSM_PUT16(buf, 0);
0551 
0552     ret = wsm_cmd_send(priv, buf, NULL, 0x0012, WSM_CMD_TIMEOUT);
0553 
0554     wsm_cmd_unlock(priv);
0555     return ret;
0556 
0557 nomem:
0558     wsm_cmd_unlock(priv);
0559     return -ENOMEM;
0560 }
0561 
0562 /* ******************************************************************** */
0563 
0564 int wsm_set_edca_params(struct cw1200_common *priv,
0565                 const struct wsm_edca_params *arg)
0566 {
0567     int ret;
0568     struct wsm_buf *buf = &priv->wsm_cmd_buf;
0569 
0570     wsm_cmd_lock(priv);
0571 
0572     /* Implemented according to specification. */
0573 
0574     WSM_PUT16(buf, arg->params[3].cwmin);
0575     WSM_PUT16(buf, arg->params[2].cwmin);
0576     WSM_PUT16(buf, arg->params[1].cwmin);
0577     WSM_PUT16(buf, arg->params[0].cwmin);
0578 
0579     WSM_PUT16(buf, arg->params[3].cwmax);
0580     WSM_PUT16(buf, arg->params[2].cwmax);
0581     WSM_PUT16(buf, arg->params[1].cwmax);
0582     WSM_PUT16(buf, arg->params[0].cwmax);
0583 
0584     WSM_PUT8(buf, arg->params[3].aifns);
0585     WSM_PUT8(buf, arg->params[2].aifns);
0586     WSM_PUT8(buf, arg->params[1].aifns);
0587     WSM_PUT8(buf, arg->params[0].aifns);
0588 
0589     WSM_PUT16(buf, arg->params[3].txop_limit);
0590     WSM_PUT16(buf, arg->params[2].txop_limit);
0591     WSM_PUT16(buf, arg->params[1].txop_limit);
0592     WSM_PUT16(buf, arg->params[0].txop_limit);
0593 
0594     WSM_PUT32(buf, arg->params[3].max_rx_lifetime);
0595     WSM_PUT32(buf, arg->params[2].max_rx_lifetime);
0596     WSM_PUT32(buf, arg->params[1].max_rx_lifetime);
0597     WSM_PUT32(buf, arg->params[0].max_rx_lifetime);
0598 
0599     ret = wsm_cmd_send(priv, buf, NULL,
0600                WSM_EDCA_PARAMS_REQ_ID, WSM_CMD_TIMEOUT);
0601     wsm_cmd_unlock(priv);
0602     return ret;
0603 
0604 nomem:
0605     wsm_cmd_unlock(priv);
0606     return -ENOMEM;
0607 }
0608 
0609 /* ******************************************************************** */
0610 
0611 int wsm_switch_channel(struct cw1200_common *priv,
0612             const struct wsm_switch_channel *arg)
0613 {
0614     int ret;
0615     struct wsm_buf *buf = &priv->wsm_cmd_buf;
0616 
0617     wsm_cmd_lock(priv);
0618 
0619     WSM_PUT8(buf, arg->mode);
0620     WSM_PUT8(buf, arg->switch_count);
0621     WSM_PUT16(buf, arg->channel_number);
0622 
0623     priv->channel_switch_in_progress = 1;
0624 
0625     ret = wsm_cmd_send(priv, buf, NULL,
0626                WSM_SWITCH_CHANNEL_REQ_ID, WSM_CMD_TIMEOUT);
0627     if (ret)
0628         priv->channel_switch_in_progress = 0;
0629 
0630     wsm_cmd_unlock(priv);
0631     return ret;
0632 
0633 nomem:
0634     wsm_cmd_unlock(priv);
0635     return -ENOMEM;
0636 }
0637 
0638 /* ******************************************************************** */
0639 
0640 int wsm_set_pm(struct cw1200_common *priv, const struct wsm_set_pm *arg)
0641 {
0642     int ret;
0643     struct wsm_buf *buf = &priv->wsm_cmd_buf;
0644     priv->ps_mode_switch_in_progress = 1;
0645 
0646     wsm_cmd_lock(priv);
0647 
0648     WSM_PUT8(buf, arg->mode);
0649     WSM_PUT8(buf, arg->fast_psm_idle_period);
0650     WSM_PUT8(buf, arg->ap_psm_change_period);
0651     WSM_PUT8(buf, arg->min_auto_pspoll_period);
0652 
0653     ret = wsm_cmd_send(priv, buf, NULL,
0654                WSM_SET_PM_REQ_ID, WSM_CMD_TIMEOUT);
0655 
0656     wsm_cmd_unlock(priv);
0657     return ret;
0658 
0659 nomem:
0660     wsm_cmd_unlock(priv);
0661     return -ENOMEM;
0662 }
0663 
0664 /* ******************************************************************** */
0665 
0666 int wsm_start(struct cw1200_common *priv, const struct wsm_start *arg)
0667 {
0668     int ret;
0669     struct wsm_buf *buf = &priv->wsm_cmd_buf;
0670 
0671     wsm_cmd_lock(priv);
0672 
0673     WSM_PUT8(buf, arg->mode);
0674     WSM_PUT8(buf, arg->band);
0675     WSM_PUT16(buf, arg->channel_number);
0676     WSM_PUT32(buf, arg->ct_window);
0677     WSM_PUT32(buf, arg->beacon_interval);
0678     WSM_PUT8(buf, arg->dtim_period);
0679     WSM_PUT8(buf, arg->preamble);
0680     WSM_PUT8(buf, arg->probe_delay);
0681     WSM_PUT8(buf, arg->ssid_len);
0682     WSM_PUT(buf, arg->ssid, sizeof(arg->ssid));
0683     WSM_PUT32(buf, arg->basic_rate_set);
0684 
0685     priv->tx_burst_idx = -1;
0686     ret = wsm_cmd_send(priv, buf, NULL,
0687                WSM_START_REQ_ID, WSM_CMD_START_TIMEOUT);
0688 
0689     wsm_cmd_unlock(priv);
0690     return ret;
0691 
0692 nomem:
0693     wsm_cmd_unlock(priv);
0694     return -ENOMEM;
0695 }
0696 
0697 /* ******************************************************************** */
0698 
0699 int wsm_beacon_transmit(struct cw1200_common *priv,
0700             const struct wsm_beacon_transmit *arg)
0701 {
0702     int ret;
0703     struct wsm_buf *buf = &priv->wsm_cmd_buf;
0704 
0705     wsm_cmd_lock(priv);
0706 
0707     WSM_PUT32(buf, arg->enable_beaconing ? 1 : 0);
0708 
0709     ret = wsm_cmd_send(priv, buf, NULL,
0710                WSM_BEACON_TRANSMIT_REQ_ID, WSM_CMD_TIMEOUT);
0711 
0712     wsm_cmd_unlock(priv);
0713     return ret;
0714 
0715 nomem:
0716     wsm_cmd_unlock(priv);
0717     return -ENOMEM;
0718 }
0719 
0720 /* ******************************************************************** */
0721 
0722 int wsm_start_find(struct cw1200_common *priv)
0723 {
0724     int ret;
0725     struct wsm_buf *buf = &priv->wsm_cmd_buf;
0726 
0727     wsm_cmd_lock(priv);
0728     ret = wsm_cmd_send(priv, buf, NULL, 0x0019, WSM_CMD_TIMEOUT);
0729     wsm_cmd_unlock(priv);
0730     return ret;
0731 }
0732 
0733 /* ******************************************************************** */
0734 
0735 int wsm_stop_find(struct cw1200_common *priv)
0736 {
0737     int ret;
0738     struct wsm_buf *buf = &priv->wsm_cmd_buf;
0739 
0740     wsm_cmd_lock(priv);
0741     ret = wsm_cmd_send(priv, buf, NULL, 0x001A, WSM_CMD_TIMEOUT);
0742     wsm_cmd_unlock(priv);
0743     return ret;
0744 }
0745 
0746 /* ******************************************************************** */
0747 
0748 int wsm_map_link(struct cw1200_common *priv, const struct wsm_map_link *arg)
0749 {
0750     int ret;
0751     struct wsm_buf *buf = &priv->wsm_cmd_buf;
0752     u16 cmd = 0x001C | WSM_TX_LINK_ID(arg->link_id);
0753 
0754     wsm_cmd_lock(priv);
0755 
0756     WSM_PUT(buf, &arg->mac_addr[0], sizeof(arg->mac_addr));
0757     WSM_PUT16(buf, 0);
0758 
0759     ret = wsm_cmd_send(priv, buf, NULL, cmd, WSM_CMD_TIMEOUT);
0760 
0761     wsm_cmd_unlock(priv);
0762     return ret;
0763 
0764 nomem:
0765     wsm_cmd_unlock(priv);
0766     return -ENOMEM;
0767 }
0768 
0769 /* ******************************************************************** */
0770 
0771 int wsm_update_ie(struct cw1200_common *priv,
0772           const struct wsm_update_ie *arg)
0773 {
0774     int ret;
0775     struct wsm_buf *buf = &priv->wsm_cmd_buf;
0776 
0777     wsm_cmd_lock(priv);
0778 
0779     WSM_PUT16(buf, arg->what);
0780     WSM_PUT16(buf, arg->count);
0781     WSM_PUT(buf, arg->ies, arg->length);
0782 
0783     ret = wsm_cmd_send(priv, buf, NULL, 0x001B, WSM_CMD_TIMEOUT);
0784 
0785     wsm_cmd_unlock(priv);
0786     return ret;
0787 
0788 nomem:
0789     wsm_cmd_unlock(priv);
0790     return -ENOMEM;
0791 }
0792 
0793 /* ******************************************************************** */
0794 int wsm_set_probe_responder(struct cw1200_common *priv, bool enable)
0795 {
0796     priv->rx_filter.probeResponder = enable;
0797     return wsm_set_rx_filter(priv, &priv->rx_filter);
0798 }
0799 
0800 /* ******************************************************************** */
0801 /* WSM indication events implementation                 */
0802 const char * const cw1200_fw_types[] = {
0803     "ETF",
0804     "WFM",
0805     "WSM",
0806     "HI test",
0807     "Platform test"
0808 };
0809 
0810 static int wsm_startup_indication(struct cw1200_common *priv,
0811                     struct wsm_buf *buf)
0812 {
0813     priv->wsm_caps.input_buffers     = WSM_GET16(buf);
0814     priv->wsm_caps.input_buffer_size = WSM_GET16(buf);
0815     priv->wsm_caps.hw_id      = WSM_GET16(buf);
0816     priv->wsm_caps.hw_subid   = WSM_GET16(buf);
0817     priv->wsm_caps.status     = WSM_GET16(buf);
0818     priv->wsm_caps.fw_cap     = WSM_GET16(buf);
0819     priv->wsm_caps.fw_type    = WSM_GET16(buf);
0820     priv->wsm_caps.fw_api     = WSM_GET16(buf);
0821     priv->wsm_caps.fw_build   = WSM_GET16(buf);
0822     priv->wsm_caps.fw_ver     = WSM_GET16(buf);
0823     WSM_GET(buf, priv->wsm_caps.fw_label, sizeof(priv->wsm_caps.fw_label));
0824     priv->wsm_caps.fw_label[sizeof(priv->wsm_caps.fw_label) - 1] = 0; /* Do not trust FW too much... */
0825 
0826     if (WARN_ON(priv->wsm_caps.status))
0827         return -EINVAL;
0828 
0829     if (WARN_ON(priv->wsm_caps.fw_type > 4))
0830         return -EINVAL;
0831 
0832     pr_info("CW1200 WSM init done.\n"
0833         "   Input buffers: %d x %d bytes\n"
0834         "   Hardware: %d.%d\n"
0835         "   %s firmware [%s], ver: %d, build: %d,"
0836         "   api: %d, cap: 0x%.4X\n",
0837         priv->wsm_caps.input_buffers,
0838         priv->wsm_caps.input_buffer_size,
0839         priv->wsm_caps.hw_id, priv->wsm_caps.hw_subid,
0840         cw1200_fw_types[priv->wsm_caps.fw_type],
0841         priv->wsm_caps.fw_label, priv->wsm_caps.fw_ver,
0842         priv->wsm_caps.fw_build,
0843         priv->wsm_caps.fw_api, priv->wsm_caps.fw_cap);
0844 
0845     /* Disable unsupported frequency bands */
0846     if (!(priv->wsm_caps.fw_cap & 0x1))
0847         priv->hw->wiphy->bands[NL80211_BAND_2GHZ] = NULL;
0848     if (!(priv->wsm_caps.fw_cap & 0x2))
0849         priv->hw->wiphy->bands[NL80211_BAND_5GHZ] = NULL;
0850 
0851     priv->firmware_ready = 1;
0852     wake_up(&priv->wsm_startup_done);
0853     return 0;
0854 
0855 underflow:
0856     WARN_ON(1);
0857     return -EINVAL;
0858 }
0859 
0860 static int wsm_receive_indication(struct cw1200_common *priv,
0861                   int link_id,
0862                   struct wsm_buf *buf,
0863                   struct sk_buff **skb_p)
0864 {
0865     struct wsm_rx rx;
0866     struct ieee80211_hdr *hdr;
0867     size_t hdr_len;
0868     __le16 fctl;
0869 
0870     rx.status = WSM_GET32(buf);
0871     rx.channel_number = WSM_GET16(buf);
0872     rx.rx_rate = WSM_GET8(buf);
0873     rx.rcpi_rssi = WSM_GET8(buf);
0874     rx.flags = WSM_GET32(buf);
0875 
0876     /* FW Workaround: Drop probe resp or
0877        beacon when RSSI is 0
0878     */
0879     hdr = (struct ieee80211_hdr *)(*skb_p)->data;
0880 
0881     if (!rx.rcpi_rssi &&
0882         (ieee80211_is_probe_resp(hdr->frame_control) ||
0883          ieee80211_is_beacon(hdr->frame_control)))
0884         return 0;
0885 
0886     /* If no RSSI subscription has been made,
0887      * convert RCPI to RSSI here
0888      */
0889     if (!priv->cqm_use_rssi)
0890         rx.rcpi_rssi = rx.rcpi_rssi / 2 - 110;
0891 
0892     fctl = *(__le16 *)buf->data;
0893     hdr_len = buf->data - buf->begin;
0894     skb_pull(*skb_p, hdr_len);
0895     if (!rx.status && ieee80211_is_deauth(fctl)) {
0896         if (priv->join_status == CW1200_JOIN_STATUS_STA) {
0897             /* Shedule unjoin work */
0898             pr_debug("[WSM] Issue unjoin command (RX).\n");
0899             wsm_lock_tx_async(priv);
0900             if (queue_work(priv->workqueue,
0901                        &priv->unjoin_work) <= 0)
0902                 wsm_unlock_tx(priv);
0903         }
0904     }
0905     cw1200_rx_cb(priv, &rx, link_id, skb_p);
0906     if (*skb_p)
0907         skb_push(*skb_p, hdr_len);
0908 
0909     return 0;
0910 
0911 underflow:
0912     return -EINVAL;
0913 }
0914 
0915 static int wsm_event_indication(struct cw1200_common *priv, struct wsm_buf *buf)
0916 {
0917     int first;
0918     struct cw1200_wsm_event *event;
0919 
0920     if (priv->mode == NL80211_IFTYPE_UNSPECIFIED) {
0921         /* STA is stopped. */
0922         return 0;
0923     }
0924 
0925     event = kzalloc(sizeof(struct cw1200_wsm_event), GFP_KERNEL);
0926     if (!event)
0927         return -ENOMEM;
0928 
0929     event->evt.id = WSM_GET32(buf);
0930     event->evt.data = WSM_GET32(buf);
0931 
0932     pr_debug("[WSM] Event: %d(%d)\n",
0933          event->evt.id, event->evt.data);
0934 
0935     spin_lock(&priv->event_queue_lock);
0936     first = list_empty(&priv->event_queue);
0937     list_add_tail(&event->link, &priv->event_queue);
0938     spin_unlock(&priv->event_queue_lock);
0939 
0940     if (first)
0941         queue_work(priv->workqueue, &priv->event_handler);
0942 
0943     return 0;
0944 
0945 underflow:
0946     kfree(event);
0947     return -EINVAL;
0948 }
0949 
0950 static int wsm_channel_switch_indication(struct cw1200_common *priv,
0951                      struct wsm_buf *buf)
0952 {
0953     WARN_ON(WSM_GET32(buf));
0954 
0955     priv->channel_switch_in_progress = 0;
0956     wake_up(&priv->channel_switch_done);
0957 
0958     wsm_unlock_tx(priv);
0959 
0960     return 0;
0961 
0962 underflow:
0963     return -EINVAL;
0964 }
0965 
0966 static int wsm_set_pm_indication(struct cw1200_common *priv,
0967                  struct wsm_buf *buf)
0968 {
0969     /* TODO:  Check buf (struct wsm_set_pm_complete) for validity */
0970     if (priv->ps_mode_switch_in_progress) {
0971         priv->ps_mode_switch_in_progress = 0;
0972         wake_up(&priv->ps_mode_switch_done);
0973     }
0974     return 0;
0975 }
0976 
0977 static int wsm_scan_started(struct cw1200_common *priv, void *arg,
0978                 struct wsm_buf *buf)
0979 {
0980     u32 status = WSM_GET32(buf);
0981     if (status != WSM_STATUS_SUCCESS) {
0982         cw1200_scan_failed_cb(priv);
0983         return -EINVAL;
0984     }
0985     return 0;
0986 
0987 underflow:
0988     WARN_ON(1);
0989     return -EINVAL;
0990 }
0991 
0992 static int wsm_scan_complete_indication(struct cw1200_common *priv,
0993                     struct wsm_buf *buf)
0994 {
0995     struct wsm_scan_complete arg;
0996     arg.status = WSM_GET32(buf);
0997     arg.psm = WSM_GET8(buf);
0998     arg.num_channels = WSM_GET8(buf);
0999     cw1200_scan_complete_cb(priv, &arg);
1000 
1001     return 0;
1002 
1003 underflow:
1004     return -EINVAL;
1005 }
1006 
1007 static 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 
1017 underflow:
1018     return -EINVAL;
1019 }
1020 
1021 static 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 
1028 static 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 
1044 underflow:
1045     return -EINVAL;
1046 }
1047 
1048 static 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 
1064 underflow:
1065     return -EINVAL;
1066 }
1067 
1068 
1069 /* ******************************************************************** */
1070 /* WSM TX                               */
1071 
1072 static 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     }
1152 done:
1153     wsm_buf_reset(buf);
1154     return ret;
1155 }
1156 
1157 /* ******************************************************************** */
1158 /* WSM TX port control                          */
1159 
1160 void 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 
1170 void 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 
1176 bool 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 
1223 void 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 
1239 int 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 
1288 underflow:
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 
1295 int 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     }
1449 out:
1450     return ret;
1451 }
1452 
1453 static 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 
1576 static 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 
1618 static 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 
1652 found:
1653     *queue_p = &priv->tx_queue[idx];
1654     *tx_allowed_mask_p = tx_allowed_mask;
1655     return 0;
1656 }
1657 
1658 int 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 
1763 void 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 
1775 void 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 
1783 void wsm_buf_deinit(struct wsm_buf *buf)
1784 {
1785     kfree(buf->begin);
1786     buf->begin = buf->data = buf->end = NULL;
1787 }
1788 
1789 static 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 
1799 static 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 }