linux/drivers/net/wireless/intersil/p54/txrx.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * Common code for mac80211 Prism54 drivers
   4 *
   5 * Copyright (c) 2006, Michael Wu <flamingice@sourmilk.net>
   6 * Copyright (c) 2007-2009, Christian Lamparter <chunkeey@web.de>
   7 * Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
   8 *
   9 * Based on:
  10 * - the islsm (softmac prism54) driver, which is:
  11 *   Copyright 2004-2006 Jean-Baptiste Note <jbnote@gmail.com>, et al.
  12 * - stlc45xx driver
  13 *   Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
  14 */
  15
  16#include <linux/export.h>
  17#include <linux/firmware.h>
  18#include <linux/etherdevice.h>
  19#include <asm/div64.h>
  20
  21#include <net/mac80211.h>
  22
  23#include "p54.h"
  24#include "lmac.h"
  25
  26#ifdef P54_MM_DEBUG
  27static void p54_dump_tx_queue(struct p54_common *priv)
  28{
  29        unsigned long flags;
  30        struct ieee80211_tx_info *info;
  31        struct p54_tx_info *range;
  32        struct sk_buff *skb;
  33        struct p54_hdr *hdr;
  34        unsigned int i = 0;
  35        u32 prev_addr;
  36        u32 largest_hole = 0, free;
  37
  38        spin_lock_irqsave(&priv->tx_queue.lock, flags);
  39        wiphy_debug(priv->hw->wiphy, "/ --- tx queue dump (%d entries) ---\n",
  40                    skb_queue_len(&priv->tx_queue));
  41
  42        prev_addr = priv->rx_start;
  43        skb_queue_walk(&priv->tx_queue, skb) {
  44                info = IEEE80211_SKB_CB(skb);
  45                range = (void *) info->rate_driver_data;
  46                hdr = (void *) skb->data;
  47
  48                free = range->start_addr - prev_addr;
  49                wiphy_debug(priv->hw->wiphy,
  50                            "| [%02d] => [skb:%p skb_len:0x%04x "
  51                            "hdr:{flags:%02x len:%04x req_id:%04x type:%02x} "
  52                            "mem:{start:%04x end:%04x, free:%d}]\n",
  53                            i++, skb, skb->len,
  54                            le16_to_cpu(hdr->flags), le16_to_cpu(hdr->len),
  55                            le32_to_cpu(hdr->req_id), le16_to_cpu(hdr->type),
  56                            range->start_addr, range->end_addr, free);
  57
  58                prev_addr = range->end_addr;
  59                largest_hole = max(largest_hole, free);
  60        }
  61        free = priv->rx_end - prev_addr;
  62        largest_hole = max(largest_hole, free);
  63        wiphy_debug(priv->hw->wiphy,
  64                    "\\ --- [free: %d], largest free block: %d ---\n",
  65                    free, largest_hole);
  66        spin_unlock_irqrestore(&priv->tx_queue.lock, flags);
  67}
  68#endif /* P54_MM_DEBUG */
  69
  70/*
  71 * So, the firmware is somewhat stupid and doesn't know what places in its
  72 * memory incoming data should go to. By poking around in the firmware, we
  73 * can find some unused memory to upload our packets to. However, data that we
  74 * want the card to TX needs to stay intact until the card has told us that
  75 * it is done with it. This function finds empty places we can upload to and
  76 * marks allocated areas as reserved if necessary. p54_find_and_unlink_skb or
  77 * p54_free_skb frees allocated areas.
  78 */
  79static int p54_assign_address(struct p54_common *priv, struct sk_buff *skb)
  80{
  81        struct sk_buff *entry, *target_skb = NULL;
  82        struct ieee80211_tx_info *info;
  83        struct p54_tx_info *range;
  84        struct p54_hdr *data = (void *) skb->data;
  85        unsigned long flags;
  86        u32 last_addr = priv->rx_start;
  87        u32 target_addr = priv->rx_start;
  88        u16 len = priv->headroom + skb->len + priv->tailroom + 3;
  89
  90        info = IEEE80211_SKB_CB(skb);
  91        range = (void *) info->rate_driver_data;
  92        len = (range->extra_len + len) & ~0x3;
  93
  94        spin_lock_irqsave(&priv->tx_queue.lock, flags);
  95        if (unlikely(skb_queue_len(&priv->tx_queue) == 32)) {
  96                /*
  97                 * The tx_queue is now really full.
  98                 *
  99                 * TODO: check if the device has crashed and reset it.
 100                 */
 101                spin_unlock_irqrestore(&priv->tx_queue.lock, flags);
 102                return -EBUSY;
 103        }
 104
 105        skb_queue_walk(&priv->tx_queue, entry) {
 106                u32 hole_size;
 107                info = IEEE80211_SKB_CB(entry);
 108                range = (void *) info->rate_driver_data;
 109                hole_size = range->start_addr - last_addr;
 110
 111                if (!target_skb && hole_size >= len) {
 112                        target_skb = entry->prev;
 113                        hole_size -= len;
 114                        target_addr = last_addr;
 115                        break;
 116                }
 117                last_addr = range->end_addr;
 118        }
 119        if (unlikely(!target_skb)) {
 120                if (priv->rx_end - last_addr >= len) {
 121                        target_skb = skb_peek_tail(&priv->tx_queue);
 122                        if (target_skb) {
 123                                info = IEEE80211_SKB_CB(target_skb);
 124                                range = (void *)info->rate_driver_data;
 125                                target_addr = range->end_addr;
 126                        }
 127                } else {
 128                        spin_unlock_irqrestore(&priv->tx_queue.lock, flags);
 129                        return -ENOSPC;
 130                }
 131        }
 132
 133        info = IEEE80211_SKB_CB(skb);
 134        range = (void *) info->rate_driver_data;
 135        range->start_addr = target_addr;
 136        range->end_addr = target_addr + len;
 137        data->req_id = cpu_to_le32(target_addr + priv->headroom);
 138        if (IS_DATA_FRAME(skb) &&
 139            unlikely(GET_HW_QUEUE(skb) == P54_QUEUE_BEACON))
 140                priv->beacon_req_id = data->req_id;
 141
 142        if (target_skb)
 143                __skb_queue_after(&priv->tx_queue, target_skb, skb);
 144        else
 145                __skb_queue_head(&priv->tx_queue, skb);
 146        spin_unlock_irqrestore(&priv->tx_queue.lock, flags);
 147        return 0;
 148}
 149
 150static void p54_tx_pending(struct p54_common *priv)
 151{
 152        struct sk_buff *skb;
 153        int ret;
 154
 155        skb = skb_dequeue(&priv->tx_pending);
 156        if (unlikely(!skb))
 157                return ;
 158
 159        ret = p54_assign_address(priv, skb);
 160        if (unlikely(ret))
 161                skb_queue_head(&priv->tx_pending, skb);
 162        else
 163                priv->tx(priv->hw, skb);
 164}
 165
 166static void p54_wake_queues(struct p54_common *priv)
 167{
 168        unsigned long flags;
 169        unsigned int i;
 170
 171        if (unlikely(priv->mode == NL80211_IFTYPE_UNSPECIFIED))
 172                return ;
 173
 174        p54_tx_pending(priv);
 175
 176        spin_lock_irqsave(&priv->tx_stats_lock, flags);
 177        for (i = 0; i < priv->hw->queues; i++) {
 178                if (priv->tx_stats[i + P54_QUEUE_DATA].len <
 179                    priv->tx_stats[i + P54_QUEUE_DATA].limit)
 180                        ieee80211_wake_queue(priv->hw, i);
 181        }
 182        spin_unlock_irqrestore(&priv->tx_stats_lock, flags);
 183}
 184
 185static int p54_tx_qos_accounting_alloc(struct p54_common *priv,
 186                                       struct sk_buff *skb,
 187                                       const u16 p54_queue)
 188{
 189        struct p54_tx_queue_stats *queue;
 190        unsigned long flags;
 191
 192        if (WARN_ON(p54_queue >= P54_QUEUE_NUM))
 193                return -EINVAL;
 194
 195        queue = &priv->tx_stats[p54_queue];
 196
 197        spin_lock_irqsave(&priv->tx_stats_lock, flags);
 198        if (unlikely(queue->len >= queue->limit && IS_QOS_QUEUE(p54_queue))) {
 199                spin_unlock_irqrestore(&priv->tx_stats_lock, flags);
 200                return -ENOSPC;
 201        }
 202
 203        queue->len++;
 204        queue->count++;
 205
 206        if (unlikely(queue->len == queue->limit && IS_QOS_QUEUE(p54_queue))) {
 207                u16 ac_queue = p54_queue - P54_QUEUE_DATA;
 208                ieee80211_stop_queue(priv->hw, ac_queue);
 209        }
 210
 211        spin_unlock_irqrestore(&priv->tx_stats_lock, flags);
 212        return 0;
 213}
 214
 215static void p54_tx_qos_accounting_free(struct p54_common *priv,
 216                                       struct sk_buff *skb)
 217{
 218        if (IS_DATA_FRAME(skb)) {
 219                unsigned long flags;
 220
 221                spin_lock_irqsave(&priv->tx_stats_lock, flags);
 222                priv->tx_stats[GET_HW_QUEUE(skb)].len--;
 223                spin_unlock_irqrestore(&priv->tx_stats_lock, flags);
 224
 225                if (unlikely(GET_HW_QUEUE(skb) == P54_QUEUE_BEACON)) {
 226                        if (priv->beacon_req_id == GET_REQ_ID(skb)) {
 227                                /* this is the  active beacon set anymore */
 228                                priv->beacon_req_id = 0;
 229                        }
 230                        complete(&priv->beacon_comp);
 231                }
 232        }
 233        p54_wake_queues(priv);
 234}
 235
 236void p54_free_skb(struct ieee80211_hw *dev, struct sk_buff *skb)
 237{
 238        struct p54_common *priv = dev->priv;
 239        if (unlikely(!skb))
 240                return ;
 241
 242        skb_unlink(skb, &priv->tx_queue);
 243        p54_tx_qos_accounting_free(priv, skb);
 244        ieee80211_free_txskb(dev, skb);
 245}
 246EXPORT_SYMBOL_GPL(p54_free_skb);
 247
 248static struct sk_buff *p54_find_and_unlink_skb(struct p54_common *priv,
 249                                               const __le32 req_id)
 250{
 251        struct sk_buff *entry;
 252        unsigned long flags;
 253
 254        spin_lock_irqsave(&priv->tx_queue.lock, flags);
 255        skb_queue_walk(&priv->tx_queue, entry) {
 256                struct p54_hdr *hdr = (struct p54_hdr *) entry->data;
 257
 258                if (hdr->req_id == req_id) {
 259                        __skb_unlink(entry, &priv->tx_queue);
 260                        spin_unlock_irqrestore(&priv->tx_queue.lock, flags);
 261                        p54_tx_qos_accounting_free(priv, entry);
 262                        return entry;
 263                }
 264        }
 265        spin_unlock_irqrestore(&priv->tx_queue.lock, flags);
 266        return NULL;
 267}
 268
 269void p54_tx(struct p54_common *priv, struct sk_buff *skb)
 270{
 271        skb_queue_tail(&priv->tx_pending, skb);
 272        p54_tx_pending(priv);
 273}
 274
 275static int p54_rssi_to_dbm(struct p54_common *priv, int rssi)
 276{
 277        if (priv->rxhw != 5) {
 278                return ((rssi * priv->cur_rssi->mul) / 64 +
 279                         priv->cur_rssi->add) / 4;
 280        } else {
 281                /*
 282                 * TODO: find the correct formula
 283                 */
 284                return rssi / 2 - 110;
 285        }
 286}
 287
 288/*
 289 * Even if the firmware is capable of dealing with incoming traffic,
 290 * while dozing, we have to prepared in case mac80211 uses PS-POLL
 291 * to retrieve outstanding frames from our AP.
 292 * (see comment in net/mac80211/mlme.c @ line 1993)
 293 */
 294static void p54_pspoll_workaround(struct p54_common *priv, struct sk_buff *skb)
 295{
 296        struct ieee80211_hdr *hdr = (void *) skb->data;
 297        struct ieee80211_tim_ie *tim_ie;
 298        u8 *tim;
 299        u8 tim_len;
 300        bool new_psm;
 301
 302        /* only beacons have a TIM IE */
 303        if (!ieee80211_is_beacon(hdr->frame_control))
 304                return;
 305
 306        if (!priv->aid)
 307                return;
 308
 309        /* only consider beacons from the associated BSSID */
 310        if (!ether_addr_equal_64bits(hdr->addr3, priv->bssid))
 311                return;
 312
 313        tim = p54_find_ie(skb, WLAN_EID_TIM);
 314        if (!tim)
 315                return;
 316
 317        tim_len = tim[1];
 318        tim_ie = (struct ieee80211_tim_ie *) &tim[2];
 319
 320        new_psm = ieee80211_check_tim(tim_ie, tim_len, priv->aid);
 321        if (new_psm != priv->powersave_override) {
 322                priv->powersave_override = new_psm;
 323                p54_set_ps(priv);
 324        }
 325}
 326
 327static int p54_rx_data(struct p54_common *priv, struct sk_buff *skb)
 328{
 329        struct p54_rx_data *hdr = (struct p54_rx_data *) skb->data;
 330        struct ieee80211_rx_status *rx_status = IEEE80211_SKB_RXCB(skb);
 331        u16 freq = le16_to_cpu(hdr->freq);
 332        size_t header_len = sizeof(*hdr);
 333        u32 tsf32;
 334        __le16 fc;
 335        u8 rate = hdr->rate & 0xf;
 336
 337        /*
 338         * If the device is in a unspecified state we have to
 339         * ignore all data frames. Else we could end up with a
 340         * nasty crash.
 341         */
 342        if (unlikely(priv->mode == NL80211_IFTYPE_UNSPECIFIED))
 343                return 0;
 344
 345        if (!(hdr->flags & cpu_to_le16(P54_HDR_FLAG_DATA_IN_FCS_GOOD)))
 346                return 0;
 347
 348        if (hdr->decrypt_status == P54_DECRYPT_OK)
 349                rx_status->flag |= RX_FLAG_DECRYPTED;
 350        if ((hdr->decrypt_status == P54_DECRYPT_FAIL_MICHAEL) ||
 351            (hdr->decrypt_status == P54_DECRYPT_FAIL_TKIP))
 352                rx_status->flag |= RX_FLAG_MMIC_ERROR;
 353
 354        rx_status->signal = p54_rssi_to_dbm(priv, hdr->rssi);
 355        if (hdr->rate & 0x10)
 356                rx_status->enc_flags |= RX_ENC_FLAG_SHORTPRE;
 357        if (priv->hw->conf.chandef.chan->band == NL80211_BAND_5GHZ)
 358                rx_status->rate_idx = (rate < 4) ? 0 : rate - 4;
 359        else
 360                rx_status->rate_idx = rate;
 361
 362        rx_status->freq = freq;
 363        rx_status->band =  priv->hw->conf.chandef.chan->band;
 364        rx_status->antenna = hdr->antenna;
 365
 366        tsf32 = le32_to_cpu(hdr->tsf32);
 367        if (tsf32 < priv->tsf_low32)
 368                priv->tsf_high32++;
 369        rx_status->mactime = ((u64)priv->tsf_high32) << 32 | tsf32;
 370        priv->tsf_low32 = tsf32;
 371
 372        /* LMAC API Page 10/29 - s_lm_data_in - clock
 373         * "usec accurate timestamp of hardware clock
 374         * at end of frame (before OFDM SIFS EOF padding"
 375         */
 376        rx_status->flag |= RX_FLAG_MACTIME_END;
 377
 378        if (hdr->flags & cpu_to_le16(P54_HDR_FLAG_DATA_ALIGN))
 379                header_len += hdr->align[0];
 380
 381        skb_pull(skb, header_len);
 382        skb_trim(skb, le16_to_cpu(hdr->len));
 383
 384        fc = ((struct ieee80211_hdr *)skb->data)->frame_control;
 385        if (ieee80211_is_probe_resp(fc) || ieee80211_is_beacon(fc))
 386                rx_status->boottime_ns = ktime_get_boottime_ns();
 387
 388        if (unlikely(priv->hw->conf.flags & IEEE80211_CONF_PS))
 389                p54_pspoll_workaround(priv, skb);
 390
 391        ieee80211_rx_irqsafe(priv->hw, skb);
 392
 393        ieee80211_queue_delayed_work(priv->hw, &priv->work,
 394                           msecs_to_jiffies(P54_STATISTICS_UPDATE));
 395
 396        return -1;
 397}
 398
 399static void p54_rx_frame_sent(struct p54_common *priv, struct sk_buff *skb)
 400{
 401        struct p54_hdr *hdr = (struct p54_hdr *) skb->data;
 402        struct p54_frame_sent *payload = (struct p54_frame_sent *) hdr->data;
 403        struct ieee80211_tx_info *info;
 404        struct p54_hdr *entry_hdr;
 405        struct p54_tx_data *entry_data;
 406        struct sk_buff *entry;
 407        unsigned int pad = 0, frame_len;
 408        int count, idx;
 409
 410        entry = p54_find_and_unlink_skb(priv, hdr->req_id);
 411        if (unlikely(!entry))
 412                return ;
 413
 414        frame_len = entry->len;
 415        info = IEEE80211_SKB_CB(entry);
 416        entry_hdr = (struct p54_hdr *) entry->data;
 417        entry_data = (struct p54_tx_data *) entry_hdr->data;
 418        priv->stats.dot11ACKFailureCount += payload->tries - 1;
 419
 420        /*
 421         * Frames in P54_QUEUE_FWSCAN and P54_QUEUE_BEACON are
 422         * generated by the driver. Therefore tx_status is bogus
 423         * and we don't want to confuse the mac80211 stack.
 424         */
 425        if (unlikely(entry_data->hw_queue < P54_QUEUE_FWSCAN)) {
 426                dev_kfree_skb_any(entry);
 427                return ;
 428        }
 429
 430        /*
 431         * Clear manually, ieee80211_tx_info_clear_status would
 432         * clear the counts too and we need them.
 433         */
 434        memset(&info->status.ack_signal, 0,
 435               sizeof(struct ieee80211_tx_info) -
 436               offsetof(struct ieee80211_tx_info, status.ack_signal));
 437        BUILD_BUG_ON(offsetof(struct ieee80211_tx_info,
 438                              status.ack_signal) != 20);
 439
 440        if (entry_hdr->flags & cpu_to_le16(P54_HDR_FLAG_DATA_ALIGN))
 441                pad = entry_data->align[0];
 442
 443        /* walk through the rates array and adjust the counts */
 444        count = payload->tries;
 445        for (idx = 0; idx < 4; idx++) {
 446                if (count >= info->status.rates[idx].count) {
 447                        count -= info->status.rates[idx].count;
 448                } else if (count > 0) {
 449                        info->status.rates[idx].count = count;
 450                        count = 0;
 451                } else {
 452                        info->status.rates[idx].idx = -1;
 453                        info->status.rates[idx].count = 0;
 454                }
 455        }
 456
 457        if (!(info->flags & IEEE80211_TX_CTL_NO_ACK) &&
 458             !(payload->status & P54_TX_FAILED))
 459                info->flags |= IEEE80211_TX_STAT_ACK;
 460        if (payload->status & P54_TX_PSM_CANCELLED)
 461                info->flags |= IEEE80211_TX_STAT_TX_FILTERED;
 462        info->status.ack_signal = p54_rssi_to_dbm(priv,
 463                                                  (int)payload->ack_rssi);
 464
 465        /* Undo all changes to the frame. */
 466        switch (entry_data->key_type) {
 467        case P54_CRYPTO_TKIPMICHAEL: {
 468                u8 *iv = (u8 *)(entry_data->align + pad +
 469                                entry_data->crypt_offset);
 470
 471                /* Restore the original TKIP IV. */
 472                iv[2] = iv[0];
 473                iv[0] = iv[1];
 474                iv[1] = (iv[0] | 0x20) & 0x7f;  /* WEPSeed - 8.3.2.2 */
 475
 476                frame_len -= 12; /* remove TKIP_MMIC + TKIP_ICV */
 477                break;
 478                }
 479        case P54_CRYPTO_AESCCMP:
 480                frame_len -= 8; /* remove CCMP_MIC */
 481                break;
 482        case P54_CRYPTO_WEP:
 483                frame_len -= 4; /* remove WEP_ICV */
 484                break;
 485        }
 486
 487        skb_trim(entry, frame_len);
 488        skb_pull(entry, sizeof(*hdr) + pad + sizeof(*entry_data));
 489        ieee80211_tx_status_irqsafe(priv->hw, entry);
 490}
 491
 492static void p54_rx_eeprom_readback(struct p54_common *priv,
 493                                   struct sk_buff *skb)
 494{
 495        struct p54_hdr *hdr = (struct p54_hdr *) skb->data;
 496        struct p54_eeprom_lm86 *eeprom = (struct p54_eeprom_lm86 *) hdr->data;
 497        struct sk_buff *tmp;
 498
 499        if (!priv->eeprom)
 500                return ;
 501
 502        if (priv->fw_var >= 0x509) {
 503                memcpy(priv->eeprom, eeprom->v2.data,
 504                       le16_to_cpu(eeprom->v2.len));
 505        } else {
 506                memcpy(priv->eeprom, eeprom->v1.data,
 507                       le16_to_cpu(eeprom->v1.len));
 508        }
 509
 510        priv->eeprom = NULL;
 511        tmp = p54_find_and_unlink_skb(priv, hdr->req_id);
 512        dev_kfree_skb_any(tmp);
 513        complete(&priv->eeprom_comp);
 514}
 515
 516static void p54_rx_stats(struct p54_common *priv, struct sk_buff *skb)
 517{
 518        struct p54_hdr *hdr = (struct p54_hdr *) skb->data;
 519        struct p54_statistics *stats = (struct p54_statistics *) hdr->data;
 520        struct sk_buff *tmp;
 521        struct ieee80211_channel *chan;
 522        unsigned int i, rssi, tx, cca, dtime, dtotal, dcca, dtx, drssi, unit;
 523        u32 tsf32;
 524
 525        if (unlikely(priv->mode == NL80211_IFTYPE_UNSPECIFIED))
 526                return ;
 527
 528        tsf32 = le32_to_cpu(stats->tsf32);
 529        if (tsf32 < priv->tsf_low32)
 530                priv->tsf_high32++;
 531        priv->tsf_low32 = tsf32;
 532
 533        priv->stats.dot11RTSFailureCount = le32_to_cpu(stats->rts_fail);
 534        priv->stats.dot11RTSSuccessCount = le32_to_cpu(stats->rts_success);
 535        priv->stats.dot11FCSErrorCount = le32_to_cpu(stats->rx_bad_fcs);
 536
 537        priv->noise = p54_rssi_to_dbm(priv, le32_to_cpu(stats->noise));
 538
 539        /*
 540         * STSW450X LMAC API page 26 - 3.8 Statistics
 541         * "The exact measurement period can be derived from the
 542         * timestamp member".
 543         */
 544        dtime = tsf32 - priv->survey_raw.timestamp;
 545
 546        /*
 547         * STSW450X LMAC API page 26 - 3.8.1 Noise histogram
 548         * The LMAC samples RSSI, CCA and transmit state at regular
 549         * periods (typically 8 times per 1k [as in 1024] usec).
 550         */
 551        cca = le32_to_cpu(stats->sample_cca);
 552        tx = le32_to_cpu(stats->sample_tx);
 553        rssi = 0;
 554        for (i = 0; i < ARRAY_SIZE(stats->sample_noise); i++)
 555                rssi += le32_to_cpu(stats->sample_noise[i]);
 556
 557        dcca = cca - priv->survey_raw.cached_cca;
 558        drssi = rssi - priv->survey_raw.cached_rssi;
 559        dtx = tx - priv->survey_raw.cached_tx;
 560        dtotal = dcca + drssi + dtx;
 561
 562        /*
 563         * update statistics when more than a second is over since the
 564         * last call, or when a update is badly needed.
 565         */
 566        if (dtotal && (priv->update_stats || dtime >= USEC_PER_SEC) &&
 567            dtime >= dtotal) {
 568                priv->survey_raw.timestamp = tsf32;
 569                priv->update_stats = false;
 570                unit = dtime / dtotal;
 571
 572                if (dcca) {
 573                        priv->survey_raw.cca += dcca * unit;
 574                        priv->survey_raw.cached_cca = cca;
 575                }
 576                if (dtx) {
 577                        priv->survey_raw.tx += dtx * unit;
 578                        priv->survey_raw.cached_tx = tx;
 579                }
 580                if (drssi) {
 581                        priv->survey_raw.rssi += drssi * unit;
 582                        priv->survey_raw.cached_rssi = rssi;
 583                }
 584
 585                /* 1024 usec / 8 times = 128 usec / time */
 586                if (!(priv->phy_ps || priv->phy_idle))
 587                        priv->survey_raw.active += dtotal * unit;
 588                else
 589                        priv->survey_raw.active += (dcca + dtx) * unit;
 590        }
 591
 592        chan = priv->curchan;
 593        if (chan) {
 594                struct survey_info *survey = &priv->survey[chan->hw_value];
 595                survey->noise = clamp(priv->noise, -128, 127);
 596                survey->time = priv->survey_raw.active;
 597                survey->time_tx = priv->survey_raw.tx;
 598                survey->time_busy = priv->survey_raw.tx +
 599                        priv->survey_raw.cca;
 600                do_div(survey->time, 1024);
 601                do_div(survey->time_tx, 1024);
 602                do_div(survey->time_busy, 1024);
 603        }
 604
 605        tmp = p54_find_and_unlink_skb(priv, hdr->req_id);
 606        dev_kfree_skb_any(tmp);
 607        complete(&priv->stat_comp);
 608}
 609
 610static void p54_rx_trap(struct p54_common *priv, struct sk_buff *skb)
 611{
 612        struct p54_hdr *hdr = (struct p54_hdr *) skb->data;
 613        struct p54_trap *trap = (struct p54_trap *) hdr->data;
 614        u16 event = le16_to_cpu(trap->event);
 615        u16 freq = le16_to_cpu(trap->frequency);
 616
 617        switch (event) {
 618        case P54_TRAP_BEACON_TX:
 619                break;
 620        case P54_TRAP_RADAR:
 621                wiphy_info(priv->hw->wiphy, "radar (freq:%d MHz)\n", freq);
 622                break;
 623        case P54_TRAP_NO_BEACON:
 624                if (priv->vif)
 625                        ieee80211_beacon_loss(priv->vif);
 626                break;
 627        case P54_TRAP_SCAN:
 628                break;
 629        case P54_TRAP_TBTT:
 630                break;
 631        case P54_TRAP_TIMER:
 632                break;
 633        case P54_TRAP_FAA_RADIO_OFF:
 634                wiphy_rfkill_set_hw_state(priv->hw->wiphy, true);
 635                break;
 636        case P54_TRAP_FAA_RADIO_ON:
 637                wiphy_rfkill_set_hw_state(priv->hw->wiphy, false);
 638                break;
 639        default:
 640                wiphy_info(priv->hw->wiphy, "received event:%x freq:%d\n",
 641                           event, freq);
 642                break;
 643        }
 644}
 645
 646static int p54_rx_control(struct p54_common *priv, struct sk_buff *skb)
 647{
 648        struct p54_hdr *hdr = (struct p54_hdr *) skb->data;
 649
 650        switch (le16_to_cpu(hdr->type)) {
 651        case P54_CONTROL_TYPE_TXDONE:
 652                p54_rx_frame_sent(priv, skb);
 653                break;
 654        case P54_CONTROL_TYPE_TRAP:
 655                p54_rx_trap(priv, skb);
 656                break;
 657        case P54_CONTROL_TYPE_BBP:
 658                break;
 659        case P54_CONTROL_TYPE_STAT_READBACK:
 660                p54_rx_stats(priv, skb);
 661                break;
 662        case P54_CONTROL_TYPE_EEPROM_READBACK:
 663                p54_rx_eeprom_readback(priv, skb);
 664                break;
 665        default:
 666                wiphy_debug(priv->hw->wiphy,
 667                            "not handling 0x%02x type control frame\n",
 668                            le16_to_cpu(hdr->type));
 669                break;
 670        }
 671        return 0;
 672}
 673
 674/* returns zero if skb can be reused */
 675int p54_rx(struct ieee80211_hw *dev, struct sk_buff *skb)
 676{
 677        struct p54_common *priv = dev->priv;
 678        u16 type = le16_to_cpu(*((__le16 *)skb->data));
 679
 680        if (type & P54_HDR_FLAG_CONTROL)
 681                return p54_rx_control(priv, skb);
 682        else
 683                return p54_rx_data(priv, skb);
 684}
 685EXPORT_SYMBOL_GPL(p54_rx);
 686
 687static void p54_tx_80211_header(struct p54_common *priv, struct sk_buff *skb,
 688                                struct ieee80211_tx_info *info,
 689                                struct ieee80211_sta *sta,
 690                                u8 *queue, u32 *extra_len, u16 *flags, u16 *aid,
 691                                bool *burst_possible)
 692{
 693        struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
 694
 695        if (ieee80211_is_data_qos(hdr->frame_control))
 696                *burst_possible = true;
 697        else
 698                *burst_possible = false;
 699
 700        if (!(info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ))
 701                *flags |= P54_HDR_FLAG_DATA_OUT_SEQNR;
 702
 703        if (info->flags & IEEE80211_TX_CTL_NO_PS_BUFFER)
 704                *flags |= P54_HDR_FLAG_DATA_OUT_NOCANCEL;
 705
 706        if (info->flags & IEEE80211_TX_CTL_CLEAR_PS_FILT)
 707                *flags |= P54_HDR_FLAG_DATA_OUT_NOCANCEL;
 708
 709        *queue = skb_get_queue_mapping(skb) + P54_QUEUE_DATA;
 710
 711        switch (priv->mode) {
 712        case NL80211_IFTYPE_MONITOR:
 713                /*
 714                 * We have to set P54_HDR_FLAG_DATA_OUT_PROMISC for
 715                 * every frame in promiscuous/monitor mode.
 716                 * see STSW45x0C LMAC API - page 12.
 717                 */
 718                *aid = 0;
 719                *flags |= P54_HDR_FLAG_DATA_OUT_PROMISC;
 720                break;
 721        case NL80211_IFTYPE_STATION:
 722                *aid = 1;
 723                break;
 724        case NL80211_IFTYPE_AP:
 725        case NL80211_IFTYPE_ADHOC:
 726        case NL80211_IFTYPE_MESH_POINT:
 727                if (info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM) {
 728                        *aid = 0;
 729                        *queue = P54_QUEUE_CAB;
 730                        return;
 731                }
 732
 733                if (unlikely(ieee80211_is_mgmt(hdr->frame_control))) {
 734                        if (ieee80211_is_probe_resp(hdr->frame_control)) {
 735                                *aid = 0;
 736                                *flags |= P54_HDR_FLAG_DATA_OUT_TIMESTAMP |
 737                                          P54_HDR_FLAG_DATA_OUT_NOCANCEL;
 738                                return;
 739                        } else if (ieee80211_is_beacon(hdr->frame_control)) {
 740                                *aid = 0;
 741
 742                                if (info->flags & IEEE80211_TX_CTL_INJECTED) {
 743                                        /*
 744                                         * Injecting beacons on top of a AP is
 745                                         * not a good idea... nevertheless,
 746                                         * it should be doable.
 747                                         */
 748
 749                                        return;
 750                                }
 751
 752                                *flags |= P54_HDR_FLAG_DATA_OUT_TIMESTAMP;
 753                                *queue = P54_QUEUE_BEACON;
 754                                *extra_len = IEEE80211_MAX_TIM_LEN;
 755                                return;
 756                        }
 757                }
 758
 759                if (sta)
 760                        *aid = sta->aid;
 761                break;
 762        }
 763}
 764
 765static u8 p54_convert_algo(u32 cipher)
 766{
 767        switch (cipher) {
 768        case WLAN_CIPHER_SUITE_WEP40:
 769        case WLAN_CIPHER_SUITE_WEP104:
 770                return P54_CRYPTO_WEP;
 771        case WLAN_CIPHER_SUITE_TKIP:
 772                return P54_CRYPTO_TKIPMICHAEL;
 773        case WLAN_CIPHER_SUITE_CCMP:
 774                return P54_CRYPTO_AESCCMP;
 775        default:
 776                return 0;
 777        }
 778}
 779
 780void p54_tx_80211(struct ieee80211_hw *dev,
 781                  struct ieee80211_tx_control *control,
 782                  struct sk_buff *skb)
 783{
 784        struct p54_common *priv = dev->priv;
 785        struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
 786        struct p54_tx_info *p54info;
 787        struct p54_hdr *hdr;
 788        struct p54_tx_data *txhdr;
 789        unsigned int padding, len, extra_len = 0;
 790        int i, j, ridx;
 791        u16 hdr_flags = 0, aid = 0;
 792        u8 rate, queue = 0, crypt_offset = 0;
 793        u8 cts_rate = 0x20;
 794        u8 rc_flags;
 795        u8 calculated_tries[4];
 796        u8 nrates = 0, nremaining = 8;
 797        bool burst_allowed = false;
 798
 799        p54_tx_80211_header(priv, skb, info, control->sta, &queue, &extra_len,
 800                            &hdr_flags, &aid, &burst_allowed);
 801
 802        if (p54_tx_qos_accounting_alloc(priv, skb, queue)) {
 803                ieee80211_free_txskb(dev, skb);
 804                return;
 805        }
 806
 807        padding = (unsigned long)(skb->data - (sizeof(*hdr) + sizeof(*txhdr))) & 3;
 808        len = skb->len;
 809
 810        if (info->control.hw_key) {
 811                crypt_offset = ieee80211_get_hdrlen_from_skb(skb);
 812                if (info->control.hw_key->cipher == WLAN_CIPHER_SUITE_TKIP) {
 813                        u8 *iv = (u8 *)(skb->data + crypt_offset);
 814                        /*
 815                         * The firmware excepts that the IV has to have
 816                         * this special format
 817                         */
 818                        iv[1] = iv[0];
 819                        iv[0] = iv[2];
 820                        iv[2] = 0;
 821                }
 822        }
 823
 824        txhdr = skb_push(skb, sizeof(*txhdr) + padding);
 825        hdr = skb_push(skb, sizeof(*hdr));
 826
 827        if (padding)
 828                hdr_flags |= P54_HDR_FLAG_DATA_ALIGN;
 829        hdr->type = cpu_to_le16(aid);
 830        hdr->rts_tries = info->control.rates[0].count;
 831
 832        /*
 833         * we register the rates in perfect order, and
 834         * RTS/CTS won't happen on 5 GHz
 835         */
 836        cts_rate = info->control.rts_cts_rate_idx;
 837
 838        memset(&txhdr->rateset, 0, sizeof(txhdr->rateset));
 839
 840        /* see how many rates got used */
 841        for (i = 0; i < dev->max_rates; i++) {
 842                if (info->control.rates[i].idx < 0)
 843                        break;
 844                nrates++;
 845        }
 846
 847        /* limit tries to 8/nrates per rate */
 848        for (i = 0; i < nrates; i++) {
 849                /*
 850                 * The magic expression here is equivalent to 8/nrates for
 851                 * all values that matter, but avoids division and jumps.
 852                 * Note that nrates can only take the values 1 through 4.
 853                 */
 854                calculated_tries[i] = min_t(int, ((15 >> nrates) | 1) + 1,
 855                                                 info->control.rates[i].count);
 856                nremaining -= calculated_tries[i];
 857        }
 858
 859        /* if there are tries left, distribute from back to front */
 860        for (i = nrates - 1; nremaining > 0 && i >= 0; i--) {
 861                int tmp = info->control.rates[i].count - calculated_tries[i];
 862
 863                if (tmp <= 0)
 864                        continue;
 865                /* RC requested more tries at this rate */
 866
 867                tmp = min_t(int, tmp, nremaining);
 868                calculated_tries[i] += tmp;
 869                nremaining -= tmp;
 870        }
 871
 872        ridx = 0;
 873        for (i = 0; i < nrates && ridx < 8; i++) {
 874                /* we register the rates in perfect order */
 875                rate = info->control.rates[i].idx;
 876                if (info->band == NL80211_BAND_5GHZ)
 877                        rate += 4;
 878
 879                /* store the count we actually calculated for TX status */
 880                info->control.rates[i].count = calculated_tries[i];
 881
 882                rc_flags = info->control.rates[i].flags;
 883                if (rc_flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE) {
 884                        rate |= 0x10;
 885                        cts_rate |= 0x10;
 886                }
 887                if (rc_flags & IEEE80211_TX_RC_USE_RTS_CTS) {
 888                        burst_allowed = false;
 889                        rate |= 0x40;
 890                } else if (rc_flags & IEEE80211_TX_RC_USE_CTS_PROTECT) {
 891                        rate |= 0x20;
 892                        burst_allowed = false;
 893                }
 894                for (j = 0; j < calculated_tries[i] && ridx < 8; j++) {
 895                        txhdr->rateset[ridx] = rate;
 896                        ridx++;
 897                }
 898        }
 899
 900        if (burst_allowed)
 901                hdr_flags |= P54_HDR_FLAG_DATA_OUT_BURST;
 902
 903        /* TODO: enable bursting */
 904        hdr->flags = cpu_to_le16(hdr_flags);
 905        hdr->tries = ridx;
 906        txhdr->rts_rate_idx = 0;
 907        if (info->control.hw_key) {
 908                txhdr->key_type = p54_convert_algo(info->control.hw_key->cipher);
 909                txhdr->key_len = min((u8)16, info->control.hw_key->keylen);
 910                memcpy(txhdr->key, info->control.hw_key->key, txhdr->key_len);
 911                if (info->control.hw_key->cipher == WLAN_CIPHER_SUITE_TKIP) {
 912                        /* reserve space for the MIC key */
 913                        len += 8;
 914                        skb_put_data(skb,
 915                                     &(info->control.hw_key->key[NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY]),
 916                                     8);
 917                }
 918                /* reserve some space for ICV */
 919                len += info->control.hw_key->icv_len;
 920                skb_put_zero(skb, info->control.hw_key->icv_len);
 921        } else {
 922                txhdr->key_type = 0;
 923                txhdr->key_len = 0;
 924        }
 925        txhdr->crypt_offset = crypt_offset;
 926        txhdr->hw_queue = queue;
 927        txhdr->backlog = priv->tx_stats[queue].len - 1;
 928        memset(txhdr->durations, 0, sizeof(txhdr->durations));
 929        txhdr->tx_antenna = 2 & priv->tx_diversity_mask;
 930        if (priv->rxhw == 5) {
 931                txhdr->longbow.cts_rate = cts_rate;
 932                txhdr->longbow.output_power = cpu_to_le16(priv->output_power);
 933        } else {
 934                txhdr->normal.output_power = priv->output_power;
 935                txhdr->normal.cts_rate = cts_rate;
 936        }
 937        if (padding)
 938                txhdr->align[0] = padding;
 939
 940        hdr->len = cpu_to_le16(len);
 941        /* modifies skb->cb and with it info, so must be last! */
 942        p54info = (void *) info->rate_driver_data;
 943        p54info->extra_len = extra_len;
 944
 945        p54_tx(priv, skb);
 946}
 947