linux/drivers/net/wireless/ath/carl9170/rx.c
<<
>>
Prefs
   1/*
   2 * Atheros CARL9170 driver
   3 *
   4 * 802.11 & command trap routines
   5 *
   6 * Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
   7 * Copyright 2009, 2010, Christian Lamparter <chunkeey@googlemail.com>
   8 *
   9 * This program is free software; you can redistribute it and/or modify
  10 * it under the terms of the GNU General Public License as published by
  11 * the Free Software Foundation; either version 2 of the License, or
  12 * (at your option) any later version.
  13 *
  14 * This program is distributed in the hope that it will be useful,
  15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  17 * GNU General Public License for more details.
  18 *
  19 * You should have received a copy of the GNU General Public License
  20 * along with this program; see the file COPYING.  If not, see
  21 * http://www.gnu.org/licenses/.
  22 *
  23 * This file incorporates work covered by the following copyright and
  24 * permission notice:
  25 *    Copyright (c) 2007-2008 Atheros Communications, Inc.
  26 *
  27 *    Permission to use, copy, modify, and/or distribute this software for any
  28 *    purpose with or without fee is hereby granted, provided that the above
  29 *    copyright notice and this permission notice appear in all copies.
  30 *
  31 *    THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  32 *    WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  33 *    MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  34 *    ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  35 *    WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  36 *    ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  37 *    OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  38 */
  39
  40#include <linux/init.h>
  41#include <linux/slab.h>
  42#include <linux/module.h>
  43#include <linux/etherdevice.h>
  44#include <linux/crc32.h>
  45#include <net/mac80211.h>
  46#include "carl9170.h"
  47#include "hw.h"
  48#include "cmd.h"
  49
  50static void carl9170_dbg_message(struct ar9170 *ar, const char *buf, u32 len)
  51{
  52        bool restart = false;
  53        enum carl9170_restart_reasons reason = CARL9170_RR_NO_REASON;
  54
  55        if (len > 3) {
  56                if (memcmp(buf, CARL9170_ERR_MAGIC, 3) == 0) {
  57                        ar->fw.err_counter++;
  58                        if (ar->fw.err_counter > 3) {
  59                                restart = true;
  60                                reason = CARL9170_RR_TOO_MANY_FIRMWARE_ERRORS;
  61                        }
  62                }
  63
  64                if (memcmp(buf, CARL9170_BUG_MAGIC, 3) == 0) {
  65                        ar->fw.bug_counter++;
  66                        restart = true;
  67                        reason = CARL9170_RR_FATAL_FIRMWARE_ERROR;
  68                }
  69        }
  70
  71        wiphy_info(ar->hw->wiphy, "FW: %.*s\n", len, buf);
  72
  73        if (restart)
  74                carl9170_restart(ar, reason);
  75}
  76
  77static void carl9170_handle_ps(struct ar9170 *ar, struct carl9170_rsp *rsp)
  78{
  79        u32 ps;
  80        bool new_ps;
  81
  82        ps = le32_to_cpu(rsp->psm.state);
  83
  84        new_ps = (ps & CARL9170_PSM_COUNTER) != CARL9170_PSM_WAKE;
  85        if (ar->ps.state != new_ps) {
  86                if (!new_ps) {
  87                        ar->ps.sleep_ms = jiffies_to_msecs(jiffies -
  88                                ar->ps.last_action);
  89                }
  90
  91                ar->ps.last_action = jiffies;
  92
  93                ar->ps.state = new_ps;
  94        }
  95}
  96
  97static int carl9170_check_sequence(struct ar9170 *ar, unsigned int seq)
  98{
  99        if (ar->cmd_seq < -1)
 100                return 0;
 101
 102        /*
 103         * Initialize Counter
 104         */
 105        if (ar->cmd_seq < 0)
 106                ar->cmd_seq = seq;
 107
 108        /*
 109         * The sequence is strictly monotonic increasing and it never skips!
 110         *
 111         * Therefore we can safely assume that whenever we received an
 112         * unexpected sequence we have lost some valuable data.
 113         */
 114        if (seq != ar->cmd_seq) {
 115                int count;
 116
 117                count = (seq - ar->cmd_seq) % ar->fw.cmd_bufs;
 118
 119                wiphy_err(ar->hw->wiphy, "lost %d command responses/traps! "
 120                          "w:%d g:%d\n", count, ar->cmd_seq, seq);
 121
 122                carl9170_restart(ar, CARL9170_RR_LOST_RSP);
 123                return -EIO;
 124        }
 125
 126        ar->cmd_seq = (ar->cmd_seq + 1) % ar->fw.cmd_bufs;
 127        return 0;
 128}
 129
 130static void carl9170_cmd_callback(struct ar9170 *ar, u32 len, void *buffer)
 131{
 132        /*
 133         * Some commands may have a variable response length
 134         * and we cannot predict the correct length in advance.
 135         * So we only check if we provided enough space for the data.
 136         */
 137        if (unlikely(ar->readlen != (len - 4))) {
 138                dev_warn(&ar->udev->dev, "received invalid command response:"
 139                         "got %d, instead of %d\n", len - 4, ar->readlen);
 140                print_hex_dump_bytes("carl9170 cmd:", DUMP_PREFIX_OFFSET,
 141                        ar->cmd_buf, (ar->cmd.hdr.len + 4) & 0x3f);
 142                print_hex_dump_bytes("carl9170 rsp:", DUMP_PREFIX_OFFSET,
 143                        buffer, len);
 144                /*
 145                 * Do not complete. The command times out,
 146                 * and we get a stack trace from there.
 147                 */
 148                carl9170_restart(ar, CARL9170_RR_INVALID_RSP);
 149        }
 150
 151        spin_lock(&ar->cmd_lock);
 152        if (ar->readbuf) {
 153                if (len >= 4)
 154                        memcpy(ar->readbuf, buffer + 4, len - 4);
 155
 156                ar->readbuf = NULL;
 157        }
 158        complete(&ar->cmd_wait);
 159        spin_unlock(&ar->cmd_lock);
 160}
 161
 162void carl9170_handle_command_response(struct ar9170 *ar, void *buf, u32 len)
 163{
 164        struct carl9170_rsp *cmd = buf;
 165        struct ieee80211_vif *vif;
 166
 167        if ((cmd->hdr.cmd & CARL9170_RSP_FLAG) != CARL9170_RSP_FLAG) {
 168                if (!(cmd->hdr.cmd & CARL9170_CMD_ASYNC_FLAG))
 169                        carl9170_cmd_callback(ar, len, buf);
 170
 171                return;
 172        }
 173
 174        if (unlikely(cmd->hdr.len != (len - 4))) {
 175                if (net_ratelimit()) {
 176                        wiphy_err(ar->hw->wiphy, "FW: received over-/under"
 177                                "sized event %x (%d, but should be %d).\n",
 178                               cmd->hdr.cmd, cmd->hdr.len, len - 4);
 179
 180                        print_hex_dump_bytes("dump:", DUMP_PREFIX_NONE,
 181                                             buf, len);
 182                }
 183
 184                return;
 185        }
 186
 187        /* hardware event handlers */
 188        switch (cmd->hdr.cmd) {
 189        case CARL9170_RSP_PRETBTT:
 190                /* pre-TBTT event */
 191                rcu_read_lock();
 192                vif = carl9170_get_main_vif(ar);
 193
 194                if (!vif) {
 195                        rcu_read_unlock();
 196                        break;
 197                }
 198
 199                switch (vif->type) {
 200                case NL80211_IFTYPE_STATION:
 201                        carl9170_handle_ps(ar, cmd);
 202                        break;
 203
 204                case NL80211_IFTYPE_AP:
 205                case NL80211_IFTYPE_ADHOC:
 206                case NL80211_IFTYPE_MESH_POINT:
 207                        carl9170_update_beacon(ar, true);
 208                        break;
 209
 210                default:
 211                        break;
 212                }
 213                rcu_read_unlock();
 214
 215                break;
 216
 217
 218        case CARL9170_RSP_TXCOMP:
 219                /* TX status notification */
 220                carl9170_tx_process_status(ar, cmd);
 221                break;
 222
 223        case CARL9170_RSP_BEACON_CONFIG:
 224                /*
 225                 * (IBSS) beacon send notification
 226                 * bytes: 04 c2 XX YY B4 B3 B2 B1
 227                 *
 228                 * XX always 80
 229                 * YY always 00
 230                 * B1-B4 "should" be the number of send out beacons.
 231                 */
 232                break;
 233
 234        case CARL9170_RSP_ATIM:
 235                /* End of Atim Window */
 236                break;
 237
 238        case CARL9170_RSP_WATCHDOG:
 239                /* Watchdog Interrupt */
 240                carl9170_restart(ar, CARL9170_RR_WATCHDOG);
 241                break;
 242
 243        case CARL9170_RSP_TEXT:
 244                /* firmware debug */
 245                carl9170_dbg_message(ar, (char *)buf + 4, len - 4);
 246                break;
 247
 248        case CARL9170_RSP_HEXDUMP:
 249                wiphy_dbg(ar->hw->wiphy, "FW: HD %d\n", len - 4);
 250                print_hex_dump_bytes("FW:", DUMP_PREFIX_NONE,
 251                                     (char *)buf + 4, len - 4);
 252                break;
 253
 254        case CARL9170_RSP_RADAR:
 255                if (!net_ratelimit())
 256                        break;
 257
 258                wiphy_info(ar->hw->wiphy, "FW: RADAR! Please report this "
 259                       "incident to linux-wireless@vger.kernel.org !\n");
 260                break;
 261
 262        case CARL9170_RSP_GPIO:
 263#ifdef CONFIG_CARL9170_WPC
 264                if (ar->wps.pbc) {
 265                        bool state = !!(cmd->gpio.gpio & cpu_to_le32(
 266                                AR9170_GPIO_PORT_WPS_BUTTON_PRESSED));
 267
 268                        if (state != ar->wps.pbc_state) {
 269                                ar->wps.pbc_state = state;
 270                                input_report_key(ar->wps.pbc, KEY_WPS_BUTTON,
 271                                                 state);
 272                                input_sync(ar->wps.pbc);
 273                        }
 274                }
 275#endif /* CONFIG_CARL9170_WPC */
 276                break;
 277
 278        case CARL9170_RSP_BOOT:
 279                complete(&ar->fw_boot_wait);
 280                break;
 281
 282        default:
 283                wiphy_err(ar->hw->wiphy, "FW: received unhandled event %x\n",
 284                        cmd->hdr.cmd);
 285                print_hex_dump_bytes("dump:", DUMP_PREFIX_NONE, buf, len);
 286                break;
 287        }
 288}
 289
 290static int carl9170_rx_mac_status(struct ar9170 *ar,
 291        struct ar9170_rx_head *head, struct ar9170_rx_macstatus *mac,
 292        struct ieee80211_rx_status *status)
 293{
 294        struct ieee80211_channel *chan;
 295        u8 error, decrypt;
 296
 297        BUILD_BUG_ON(sizeof(struct ar9170_rx_head) != 12);
 298        BUILD_BUG_ON(sizeof(struct ar9170_rx_macstatus) != 4);
 299
 300        error = mac->error;
 301
 302        if (error & AR9170_RX_ERROR_WRONG_RA) {
 303                if (!ar->sniffer_enabled)
 304                        return -EINVAL;
 305        }
 306
 307        if (error & AR9170_RX_ERROR_PLCP) {
 308                if (!(ar->filter_state & FIF_PLCPFAIL))
 309                        return -EINVAL;
 310
 311                status->flag |= RX_FLAG_FAILED_PLCP_CRC;
 312        }
 313
 314        if (error & AR9170_RX_ERROR_FCS) {
 315                ar->tx_fcs_errors++;
 316
 317                if (!(ar->filter_state & FIF_FCSFAIL))
 318                        return -EINVAL;
 319
 320                status->flag |= RX_FLAG_FAILED_FCS_CRC;
 321        }
 322
 323        decrypt = ar9170_get_decrypt_type(mac);
 324        if (!(decrypt & AR9170_RX_ENC_SOFTWARE) &&
 325            decrypt != AR9170_ENC_ALG_NONE) {
 326                if ((decrypt == AR9170_ENC_ALG_TKIP) &&
 327                    (error & AR9170_RX_ERROR_MMIC))
 328                        status->flag |= RX_FLAG_MMIC_ERROR;
 329
 330                status->flag |= RX_FLAG_DECRYPTED;
 331        }
 332
 333        if (error & AR9170_RX_ERROR_DECRYPT && !ar->sniffer_enabled)
 334                return -ENODATA;
 335
 336        error &= ~(AR9170_RX_ERROR_MMIC |
 337                   AR9170_RX_ERROR_FCS |
 338                   AR9170_RX_ERROR_WRONG_RA |
 339                   AR9170_RX_ERROR_DECRYPT |
 340                   AR9170_RX_ERROR_PLCP);
 341
 342        /* drop any other error frames */
 343        if (unlikely(error)) {
 344                /* TODO: update netdevice's RX dropped/errors statistics */
 345
 346                if (net_ratelimit())
 347                        wiphy_dbg(ar->hw->wiphy, "received frame with "
 348                               "suspicious error code (%#x).\n", error);
 349
 350                return -EINVAL;
 351        }
 352
 353        chan = ar->channel;
 354        if (chan) {
 355                status->band = chan->band;
 356                status->freq = chan->center_freq;
 357        }
 358
 359        switch (mac->status & AR9170_RX_STATUS_MODULATION) {
 360        case AR9170_RX_STATUS_MODULATION_CCK:
 361                if (mac->status & AR9170_RX_STATUS_SHORT_PREAMBLE)
 362                        status->flag |= RX_FLAG_SHORTPRE;
 363                switch (head->plcp[0]) {
 364                case AR9170_RX_PHY_RATE_CCK_1M:
 365                        status->rate_idx = 0;
 366                        break;
 367                case AR9170_RX_PHY_RATE_CCK_2M:
 368                        status->rate_idx = 1;
 369                        break;
 370                case AR9170_RX_PHY_RATE_CCK_5M:
 371                        status->rate_idx = 2;
 372                        break;
 373                case AR9170_RX_PHY_RATE_CCK_11M:
 374                        status->rate_idx = 3;
 375                        break;
 376                default:
 377                        if (net_ratelimit()) {
 378                                wiphy_err(ar->hw->wiphy, "invalid plcp cck "
 379                                       "rate (%x).\n", head->plcp[0]);
 380                        }
 381
 382                        return -EINVAL;
 383                }
 384                break;
 385
 386        case AR9170_RX_STATUS_MODULATION_DUPOFDM:
 387        case AR9170_RX_STATUS_MODULATION_OFDM:
 388                switch (head->plcp[0] & 0xf) {
 389                case AR9170_TXRX_PHY_RATE_OFDM_6M:
 390                        status->rate_idx = 0;
 391                        break;
 392                case AR9170_TXRX_PHY_RATE_OFDM_9M:
 393                        status->rate_idx = 1;
 394                        break;
 395                case AR9170_TXRX_PHY_RATE_OFDM_12M:
 396                        status->rate_idx = 2;
 397                        break;
 398                case AR9170_TXRX_PHY_RATE_OFDM_18M:
 399                        status->rate_idx = 3;
 400                        break;
 401                case AR9170_TXRX_PHY_RATE_OFDM_24M:
 402                        status->rate_idx = 4;
 403                        break;
 404                case AR9170_TXRX_PHY_RATE_OFDM_36M:
 405                        status->rate_idx = 5;
 406                        break;
 407                case AR9170_TXRX_PHY_RATE_OFDM_48M:
 408                        status->rate_idx = 6;
 409                        break;
 410                case AR9170_TXRX_PHY_RATE_OFDM_54M:
 411                        status->rate_idx = 7;
 412                        break;
 413                default:
 414                        if (net_ratelimit()) {
 415                                wiphy_err(ar->hw->wiphy, "invalid plcp ofdm "
 416                                        "rate (%x).\n", head->plcp[0]);
 417                        }
 418
 419                        return -EINVAL;
 420                }
 421                if (status->band == IEEE80211_BAND_2GHZ)
 422                        status->rate_idx += 4;
 423                break;
 424
 425        case AR9170_RX_STATUS_MODULATION_HT:
 426                if (head->plcp[3] & 0x80)
 427                        status->flag |= RX_FLAG_40MHZ;
 428                if (head->plcp[6] & 0x80)
 429                        status->flag |= RX_FLAG_SHORT_GI;
 430
 431                status->rate_idx = clamp(0, 75, head->plcp[3] & 0x7f);
 432                status->flag |= RX_FLAG_HT;
 433                break;
 434
 435        default:
 436                BUG();
 437                return -ENOSYS;
 438        }
 439
 440        return 0;
 441}
 442
 443static void carl9170_rx_phy_status(struct ar9170 *ar,
 444        struct ar9170_rx_phystatus *phy, struct ieee80211_rx_status *status)
 445{
 446        int i;
 447
 448        BUILD_BUG_ON(sizeof(struct ar9170_rx_phystatus) != 20);
 449
 450        for (i = 0; i < 3; i++)
 451                if (phy->rssi[i] != 0x80)
 452                        status->antenna |= BIT(i);
 453
 454        /* post-process RSSI */
 455        for (i = 0; i < 7; i++)
 456                if (phy->rssi[i] & 0x80)
 457                        phy->rssi[i] = ((phy->rssi[i] & 0x7f) + 1) & 0x7f;
 458
 459        /* TODO: we could do something with phy_errors */
 460        status->signal = ar->noise[0] + phy->rssi_combined;
 461}
 462
 463static struct sk_buff *carl9170_rx_copy_data(u8 *buf, int len)
 464{
 465        struct sk_buff *skb;
 466        int reserved = 0;
 467        struct ieee80211_hdr *hdr = (void *) buf;
 468
 469        if (ieee80211_is_data_qos(hdr->frame_control)) {
 470                u8 *qc = ieee80211_get_qos_ctl(hdr);
 471                reserved += NET_IP_ALIGN;
 472
 473                if (*qc & IEEE80211_QOS_CTL_A_MSDU_PRESENT)
 474                        reserved += NET_IP_ALIGN;
 475        }
 476
 477        if (ieee80211_has_a4(hdr->frame_control))
 478                reserved += NET_IP_ALIGN;
 479
 480        reserved = 32 + (reserved & NET_IP_ALIGN);
 481
 482        skb = dev_alloc_skb(len + reserved);
 483        if (likely(skb)) {
 484                skb_reserve(skb, reserved);
 485                memcpy(skb_put(skb, len), buf, len);
 486        }
 487
 488        return skb;
 489}
 490
 491static u8 *carl9170_find_ie(u8 *data, unsigned int len, u8 ie)
 492{
 493        struct ieee80211_mgmt *mgmt = (void *)data;
 494        u8 *pos, *end;
 495
 496        pos = (u8 *)mgmt->u.beacon.variable;
 497        end = data + len;
 498        while (pos < end) {
 499                if (pos + 2 + pos[1] > end)
 500                        return NULL;
 501
 502                if (pos[0] == ie)
 503                        return pos;
 504
 505                pos += 2 + pos[1];
 506        }
 507        return NULL;
 508}
 509
 510/*
 511 * NOTE:
 512 *
 513 * The firmware is in charge of waking up the device just before
 514 * the AP is expected to transmit the next beacon.
 515 *
 516 * This leaves the driver with the important task of deciding when
 517 * to set the PHY back to bed again.
 518 */
 519static void carl9170_ps_beacon(struct ar9170 *ar, void *data, unsigned int len)
 520{
 521        struct ieee80211_hdr *hdr = data;
 522        struct ieee80211_tim_ie *tim_ie;
 523        u8 *tim;
 524        u8 tim_len;
 525        bool cam;
 526
 527        if (likely(!(ar->hw->conf.flags & IEEE80211_CONF_PS)))
 528                return;
 529
 530        /* check if this really is a beacon */
 531        if (!ieee80211_is_beacon(hdr->frame_control))
 532                return;
 533
 534        /* min. beacon length + FCS_LEN */
 535        if (len <= 40 + FCS_LEN)
 536                return;
 537
 538        /* and only beacons from the associated BSSID, please */
 539        if (!ether_addr_equal(hdr->addr3, ar->common.curbssid) ||
 540            !ar->common.curaid)
 541                return;
 542
 543        ar->ps.last_beacon = jiffies;
 544
 545        tim = carl9170_find_ie(data, len - FCS_LEN, WLAN_EID_TIM);
 546        if (!tim)
 547                return;
 548
 549        if (tim[1] < sizeof(*tim_ie))
 550                return;
 551
 552        tim_len = tim[1];
 553        tim_ie = (struct ieee80211_tim_ie *) &tim[2];
 554
 555        if (!WARN_ON_ONCE(!ar->hw->conf.ps_dtim_period))
 556                ar->ps.dtim_counter = (tim_ie->dtim_count - 1) %
 557                        ar->hw->conf.ps_dtim_period;
 558
 559        /* Check whenever the PHY can be turned off again. */
 560
 561        /* 1. What about buffered unicast traffic for our AID? */
 562        cam = ieee80211_check_tim(tim_ie, tim_len, ar->common.curaid);
 563
 564        /* 2. Maybe the AP wants to send multicast/broadcast data? */
 565        cam |= !!(tim_ie->bitmap_ctrl & 0x01);
 566
 567        if (!cam) {
 568                /* back to low-power land. */
 569                ar->ps.off_override &= ~PS_OFF_BCN;
 570                carl9170_ps_check(ar);
 571        } else {
 572                /* force CAM */
 573                ar->ps.off_override |= PS_OFF_BCN;
 574        }
 575}
 576
 577static void carl9170_ba_check(struct ar9170 *ar, void *data, unsigned int len)
 578{
 579        struct ieee80211_bar *bar = (void *) data;
 580        struct carl9170_bar_list_entry *entry;
 581        unsigned int queue;
 582
 583        if (likely(!ieee80211_is_back(bar->frame_control)))
 584                return;
 585
 586        if (len <= sizeof(*bar) + FCS_LEN)
 587                return;
 588
 589        queue = TID_TO_WME_AC(((le16_to_cpu(bar->control) &
 590                IEEE80211_BAR_CTRL_TID_INFO_MASK) >>
 591                IEEE80211_BAR_CTRL_TID_INFO_SHIFT) & 7);
 592
 593        rcu_read_lock();
 594        list_for_each_entry_rcu(entry, &ar->bar_list[queue], list) {
 595                struct sk_buff *entry_skb = entry->skb;
 596                struct _carl9170_tx_superframe *super = (void *)entry_skb->data;
 597                struct ieee80211_bar *entry_bar = (void *)super->frame_data;
 598
 599#define TID_CHECK(a, b) (                                               \
 600        ((a) & cpu_to_le16(IEEE80211_BAR_CTRL_TID_INFO_MASK)) ==        \
 601        ((b) & cpu_to_le16(IEEE80211_BAR_CTRL_TID_INFO_MASK)))          \
 602
 603                if (bar->start_seq_num == entry_bar->start_seq_num &&
 604                    TID_CHECK(bar->control, entry_bar->control) &&
 605                    compare_ether_addr(bar->ra, entry_bar->ta) == 0 &&
 606                    compare_ether_addr(bar->ta, entry_bar->ra) == 0) {
 607                        struct ieee80211_tx_info *tx_info;
 608
 609                        tx_info = IEEE80211_SKB_CB(entry_skb);
 610                        tx_info->flags |= IEEE80211_TX_STAT_ACK;
 611
 612                        spin_lock_bh(&ar->bar_list_lock[queue]);
 613                        list_del_rcu(&entry->list);
 614                        spin_unlock_bh(&ar->bar_list_lock[queue]);
 615                        kfree_rcu(entry, head);
 616                        break;
 617                }
 618        }
 619        rcu_read_unlock();
 620
 621#undef TID_CHECK
 622}
 623
 624static bool carl9170_ampdu_check(struct ar9170 *ar, u8 *buf, u8 ms,
 625                                 struct ieee80211_rx_status *rx_status)
 626{
 627        __le16 fc;
 628
 629        if ((ms & AR9170_RX_STATUS_MPDU) == AR9170_RX_STATUS_MPDU_SINGLE) {
 630                /*
 631                 * This frame is not part of an aMPDU.
 632                 * Therefore it is not subjected to any
 633                 * of the following content restrictions.
 634                 */
 635                return true;
 636        }
 637
 638        rx_status->flag |= RX_FLAG_AMPDU_DETAILS | RX_FLAG_AMPDU_LAST_KNOWN;
 639        rx_status->ampdu_reference = ar->ampdu_ref;
 640
 641        /*
 642         * "802.11n - 7.4a.3 A-MPDU contents" describes in which contexts
 643         * certain frame types can be part of an aMPDU.
 644         *
 645         * In order to keep the processing cost down, I opted for a
 646         * stateless filter solely based on the frame control field.
 647         */
 648
 649        fc = ((struct ieee80211_hdr *)buf)->frame_control;
 650        if (ieee80211_is_data_qos(fc) && ieee80211_is_data_present(fc))
 651                return true;
 652
 653        if (ieee80211_is_ack(fc) || ieee80211_is_back(fc) ||
 654            ieee80211_is_back_req(fc))
 655                return true;
 656
 657        if (ieee80211_is_action(fc))
 658                return true;
 659
 660        return false;
 661}
 662
 663static int carl9170_handle_mpdu(struct ar9170 *ar, u8 *buf, int len,
 664                                struct ieee80211_rx_status *status)
 665{
 666        struct sk_buff *skb;
 667
 668        /* (driver) frame trap handler
 669         *
 670         * Because power-saving mode handing has to be implemented by
 671         * the driver/firmware. We have to check each incoming beacon
 672         * from the associated AP, if there's new data for us (either
 673         * broadcast/multicast or unicast) we have to react quickly.
 674         *
 675         * So, if you have you want to add additional frame trap
 676         * handlers, this would be the perfect place!
 677         */
 678
 679        carl9170_ps_beacon(ar, buf, len);
 680
 681        carl9170_ba_check(ar, buf, len);
 682
 683        skb = carl9170_rx_copy_data(buf, len);
 684        if (!skb)
 685                return -ENOMEM;
 686
 687        memcpy(IEEE80211_SKB_RXCB(skb), status, sizeof(*status));
 688        ieee80211_rx(ar->hw, skb);
 689        return 0;
 690}
 691
 692/*
 693 * If the frame alignment is right (or the kernel has
 694 * CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS), and there
 695 * is only a single MPDU in the USB frame, then we could
 696 * submit to mac80211 the SKB directly. However, since
 697 * there may be multiple packets in one SKB in stream
 698 * mode, and we need to observe the proper ordering,
 699 * this is non-trivial.
 700 */
 701static void carl9170_rx_untie_data(struct ar9170 *ar, u8 *buf, int len)
 702{
 703        struct ar9170_rx_head *head;
 704        struct ar9170_rx_macstatus *mac;
 705        struct ar9170_rx_phystatus *phy = NULL;
 706        struct ieee80211_rx_status status;
 707        int mpdu_len;
 708        u8 mac_status;
 709
 710        if (!IS_STARTED(ar))
 711                return;
 712
 713        if (unlikely(len < sizeof(*mac)))
 714                goto drop;
 715
 716        memset(&status, 0, sizeof(status));
 717
 718        mpdu_len = len - sizeof(*mac);
 719
 720        mac = (void *)(buf + mpdu_len);
 721        mac_status = mac->status;
 722        switch (mac_status & AR9170_RX_STATUS_MPDU) {
 723        case AR9170_RX_STATUS_MPDU_FIRST:
 724                ar->ampdu_ref++;
 725                /* Aggregated MPDUs start with an PLCP header */
 726                if (likely(mpdu_len >= sizeof(struct ar9170_rx_head))) {
 727                        head = (void *) buf;
 728
 729                        /*
 730                         * The PLCP header needs to be cached for the
 731                         * following MIDDLE + LAST A-MPDU packets.
 732                         *
 733                         * So, if you are wondering why all frames seem
 734                         * to share a common RX status information,
 735                         * then you have the answer right here...
 736                         */
 737                        memcpy(&ar->rx_plcp, (void *) buf,
 738                               sizeof(struct ar9170_rx_head));
 739
 740                        mpdu_len -= sizeof(struct ar9170_rx_head);
 741                        buf += sizeof(struct ar9170_rx_head);
 742
 743                        ar->rx_has_plcp = true;
 744                } else {
 745                        if (net_ratelimit()) {
 746                                wiphy_err(ar->hw->wiphy, "plcp info "
 747                                        "is clipped.\n");
 748                        }
 749
 750                        goto drop;
 751                }
 752                break;
 753
 754        case AR9170_RX_STATUS_MPDU_LAST:
 755                status.flag |= RX_FLAG_AMPDU_IS_LAST;
 756
 757                /*
 758                 * The last frame of an A-MPDU has an extra tail
 759                 * which does contain the phy status of the whole
 760                 * aggregate.
 761                 */
 762                if (likely(mpdu_len >= sizeof(struct ar9170_rx_phystatus))) {
 763                        mpdu_len -= sizeof(struct ar9170_rx_phystatus);
 764                        phy = (void *)(buf + mpdu_len);
 765                } else {
 766                        if (net_ratelimit()) {
 767                                wiphy_err(ar->hw->wiphy, "frame tail "
 768                                        "is clipped.\n");
 769                        }
 770
 771                        goto drop;
 772                }
 773
 774        case AR9170_RX_STATUS_MPDU_MIDDLE:
 775                /*  These are just data + mac status */
 776                if (unlikely(!ar->rx_has_plcp)) {
 777                        if (!net_ratelimit())
 778                                return;
 779
 780                        wiphy_err(ar->hw->wiphy, "rx stream does not start "
 781                                        "with a first_mpdu frame tag.\n");
 782
 783                        goto drop;
 784                }
 785
 786                head = &ar->rx_plcp;
 787                break;
 788
 789        case AR9170_RX_STATUS_MPDU_SINGLE:
 790                /* single mpdu has both: plcp (head) and phy status (tail) */
 791                head = (void *) buf;
 792
 793                mpdu_len -= sizeof(struct ar9170_rx_head);
 794                mpdu_len -= sizeof(struct ar9170_rx_phystatus);
 795
 796                buf += sizeof(struct ar9170_rx_head);
 797                phy = (void *)(buf + mpdu_len);
 798                break;
 799
 800        default:
 801                BUG_ON(1);
 802                break;
 803        }
 804
 805        /* FC + DU + RA + FCS */
 806        if (unlikely(mpdu_len < (2 + 2 + ETH_ALEN + FCS_LEN)))
 807                goto drop;
 808
 809        if (unlikely(carl9170_rx_mac_status(ar, head, mac, &status)))
 810                goto drop;
 811
 812        if (!carl9170_ampdu_check(ar, buf, mac_status, &status))
 813                goto drop;
 814
 815        if (phy)
 816                carl9170_rx_phy_status(ar, phy, &status);
 817        else
 818                status.flag |= RX_FLAG_NO_SIGNAL_VAL;
 819
 820        if (carl9170_handle_mpdu(ar, buf, mpdu_len, &status))
 821                goto drop;
 822
 823        return;
 824drop:
 825        ar->rx_dropped++;
 826}
 827
 828static void carl9170_rx_untie_cmds(struct ar9170 *ar, const u8 *respbuf,
 829                                   const unsigned int resplen)
 830{
 831        struct carl9170_rsp *cmd;
 832        int i = 0;
 833
 834        while (i < resplen) {
 835                cmd = (void *) &respbuf[i];
 836
 837                i += cmd->hdr.len + 4;
 838                if (unlikely(i > resplen))
 839                        break;
 840
 841                if (carl9170_check_sequence(ar, cmd->hdr.seq))
 842                        break;
 843
 844                carl9170_handle_command_response(ar, cmd, cmd->hdr.len + 4);
 845        }
 846
 847        if (unlikely(i != resplen)) {
 848                if (!net_ratelimit())
 849                        return;
 850
 851                wiphy_err(ar->hw->wiphy, "malformed firmware trap:\n");
 852                print_hex_dump_bytes("rxcmd:", DUMP_PREFIX_OFFSET,
 853                                     respbuf, resplen);
 854        }
 855}
 856
 857static void __carl9170_rx(struct ar9170 *ar, u8 *buf, unsigned int len)
 858{
 859        unsigned int i = 0;
 860
 861        /* weird thing, but this is the same in the original driver */
 862        while (len > 2 && i < 12 && buf[0] == 0xff && buf[1] == 0xff) {
 863                i += 2;
 864                len -= 2;
 865                buf += 2;
 866        }
 867
 868        if (unlikely(len < 4))
 869                return;
 870
 871        /* found the 6 * 0xffff marker? */
 872        if (i == 12)
 873                carl9170_rx_untie_cmds(ar, buf, len);
 874        else
 875                carl9170_rx_untie_data(ar, buf, len);
 876}
 877
 878static void carl9170_rx_stream(struct ar9170 *ar, void *buf, unsigned int len)
 879{
 880        unsigned int tlen, wlen = 0, clen = 0;
 881        struct ar9170_stream *rx_stream;
 882        u8 *tbuf;
 883
 884        tbuf = buf;
 885        tlen = len;
 886
 887        while (tlen >= 4) {
 888                rx_stream = (void *) tbuf;
 889                clen = le16_to_cpu(rx_stream->length);
 890                wlen = ALIGN(clen, 4);
 891
 892                /* check if this is stream has a valid tag.*/
 893                if (rx_stream->tag != cpu_to_le16(AR9170_RX_STREAM_TAG)) {
 894                        /*
 895                         * TODO: handle the highly unlikely event that the
 896                         * corrupted stream has the TAG at the right position.
 897                         */
 898
 899                        /* check if the frame can be repaired. */
 900                        if (!ar->rx_failover_missing) {
 901
 902                                /* this is not "short read". */
 903                                if (net_ratelimit()) {
 904                                        wiphy_err(ar->hw->wiphy,
 905                                                "missing tag!\n");
 906                                }
 907
 908                                __carl9170_rx(ar, tbuf, tlen);
 909                                return;
 910                        }
 911
 912                        if (ar->rx_failover_missing > tlen) {
 913                                if (net_ratelimit()) {
 914                                        wiphy_err(ar->hw->wiphy,
 915                                                "possible multi "
 916                                                "stream corruption!\n");
 917                                        goto err_telluser;
 918                                } else {
 919                                        goto err_silent;
 920                                }
 921                        }
 922
 923                        memcpy(skb_put(ar->rx_failover, tlen), tbuf, tlen);
 924                        ar->rx_failover_missing -= tlen;
 925
 926                        if (ar->rx_failover_missing <= 0) {
 927                                /*
 928                                 * nested carl9170_rx_stream call!
 929                                 *
 930                                 * termination is guaranteed, even when the
 931                                 * combined frame also have an element with
 932                                 * a bad tag.
 933                                 */
 934
 935                                ar->rx_failover_missing = 0;
 936                                carl9170_rx_stream(ar, ar->rx_failover->data,
 937                                                   ar->rx_failover->len);
 938
 939                                skb_reset_tail_pointer(ar->rx_failover);
 940                                skb_trim(ar->rx_failover, 0);
 941                        }
 942
 943                        return;
 944                }
 945
 946                /* check if stream is clipped */
 947                if (wlen > tlen - 4) {
 948                        if (ar->rx_failover_missing) {
 949                                /* TODO: handle double stream corruption. */
 950                                if (net_ratelimit()) {
 951                                        wiphy_err(ar->hw->wiphy, "double rx "
 952                                                "stream corruption!\n");
 953                                        goto err_telluser;
 954                                } else {
 955                                        goto err_silent;
 956                                }
 957                        }
 958
 959                        /*
 960                         * save incomplete data set.
 961                         * the firmware will resend the missing bits when
 962                         * the rx - descriptor comes round again.
 963                         */
 964
 965                        memcpy(skb_put(ar->rx_failover, tlen), tbuf, tlen);
 966                        ar->rx_failover_missing = clen - tlen;
 967                        return;
 968                }
 969                __carl9170_rx(ar, rx_stream->payload, clen);
 970
 971                tbuf += wlen + 4;
 972                tlen -= wlen + 4;
 973        }
 974
 975        if (tlen) {
 976                if (net_ratelimit()) {
 977                        wiphy_err(ar->hw->wiphy, "%d bytes of unprocessed "
 978                                "data left in rx stream!\n", tlen);
 979                }
 980
 981                goto err_telluser;
 982        }
 983
 984        return;
 985
 986err_telluser:
 987        wiphy_err(ar->hw->wiphy, "damaged RX stream data [want:%d, "
 988                "data:%d, rx:%d, pending:%d ]\n", clen, wlen, tlen,
 989                ar->rx_failover_missing);
 990
 991        if (ar->rx_failover_missing)
 992                print_hex_dump_bytes("rxbuf:", DUMP_PREFIX_OFFSET,
 993                                     ar->rx_failover->data,
 994                                     ar->rx_failover->len);
 995
 996        print_hex_dump_bytes("stream:", DUMP_PREFIX_OFFSET,
 997                             buf, len);
 998
 999        wiphy_err(ar->hw->wiphy, "please check your hardware and cables, if "
1000                "you see this message frequently.\n");
1001
1002err_silent:
1003        if (ar->rx_failover_missing) {
1004                skb_reset_tail_pointer(ar->rx_failover);
1005                skb_trim(ar->rx_failover, 0);
1006                ar->rx_failover_missing = 0;
1007        }
1008}
1009
1010void carl9170_rx(struct ar9170 *ar, void *buf, unsigned int len)
1011{
1012        if (ar->fw.rx_stream)
1013                carl9170_rx_stream(ar, buf, len);
1014        else
1015                __carl9170_rx(ar, buf, len);
1016}
1017