~ubuntu-branches/ubuntu/precise/linux-ti-omap4/precise

« back to all changes in this revision

Viewing changes to drivers/net/wireless/ath/ath9k/recv.c

  • Committer: Bazaar Package Importer
  • Author(s): Paolo Pisati
  • Date: 2011-06-29 15:23:51 UTC
  • mfrom: (26.1.1 natty-proposed)
  • Revision ID: james.westby@ubuntu.com-20110629152351-xs96tm303d95rpbk
Tags: 3.0.0-1200.2
* Rebased against 3.0.0-6.7
* BSP from TI based on 3.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
 
 * Copyright (c) 2008-2009 Atheros Communications Inc.
 
2
 * Copyright (c) 2008-2011 Atheros Communications Inc.
3
3
 *
4
4
 * Permission to use, copy, modify, and/or distribute this software for any
5
5
 * purpose with or without fee is hereby granted, provided that the above
28
28
                (alt_rssi_avg > main_rssi_avg + mindelta)) && (pkt_count > 50);
29
29
}
30
30
 
 
31
static inline bool ath_ant_div_comb_alt_check(u8 div_group, int alt_ratio,
 
32
                                        int curr_main_set, int curr_alt_set,
 
33
                                        int alt_rssi_avg, int main_rssi_avg)
 
34
{
 
35
        bool result = false;
 
36
        switch (div_group) {
 
37
        case 0:
 
38
                if (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO)
 
39
                        result = true;
 
40
                break;
 
41
        case 1:
 
42
                if ((((curr_main_set == ATH_ANT_DIV_COMB_LNA2) &&
 
43
                        (curr_alt_set == ATH_ANT_DIV_COMB_LNA1) &&
 
44
                                (alt_rssi_avg >= (main_rssi_avg - 5))) ||
 
45
                        ((curr_main_set == ATH_ANT_DIV_COMB_LNA1) &&
 
46
                        (curr_alt_set == ATH_ANT_DIV_COMB_LNA2) &&
 
47
                                (alt_rssi_avg >= (main_rssi_avg - 2)))) &&
 
48
                                                        (alt_rssi_avg >= 4))
 
49
                        result = true;
 
50
                else
 
51
                        result = false;
 
52
                break;
 
53
        }
 
54
 
 
55
        return result;
 
56
}
 
57
 
31
58
static inline bool ath9k_check_auto_sleep(struct ath_softc *sc)
32
59
{
33
60
        return sc->ps_enabled &&
34
61
               (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_AUTOSLEEP);
35
62
}
36
63
 
37
 
static struct ieee80211_hw * ath_get_virt_hw(struct ath_softc *sc,
38
 
                                             struct ieee80211_hdr *hdr)
39
 
{
40
 
        struct ieee80211_hw *hw = sc->pri_wiphy->hw;
41
 
        int i;
42
 
 
43
 
        spin_lock_bh(&sc->wiphy_lock);
44
 
        for (i = 0; i < sc->num_sec_wiphy; i++) {
45
 
                struct ath_wiphy *aphy = sc->sec_wiphy[i];
46
 
                if (aphy == NULL)
47
 
                        continue;
48
 
                if (compare_ether_addr(hdr->addr1, aphy->hw->wiphy->perm_addr)
49
 
                    == 0) {
50
 
                        hw = aphy->hw;
51
 
                        break;
52
 
                }
53
 
        }
54
 
        spin_unlock_bh(&sc->wiphy_lock);
55
 
        return hw;
56
 
}
57
 
 
58
64
/*
59
65
 * Setup and link descriptors.
60
66
 *
96
102
                *sc->rx.rxlink = bf->bf_daddr;
97
103
 
98
104
        sc->rx.rxlink = &ds->ds_link;
99
 
        ath9k_hw_rxena(ah);
100
105
}
101
106
 
102
107
static void ath_setdefantenna(struct ath_softc *sc, u32 antenna)
230
235
        int error = 0, i;
231
236
        u32 size;
232
237
 
233
 
 
234
 
        common->rx_bufsize = roundup(IEEE80211_MAX_MPDU_LEN +
235
 
                                     ah->caps.rx_status_len,
236
 
                                     min(common->cachelsz, (u16)64));
237
 
 
238
238
        ath9k_hw_set_rx_bufsize(ah, common->rx_bufsize -
239
239
                                    ah->caps.rx_status_len);
240
240
 
321
321
        sc->sc_flags &= ~SC_OP_RXFLUSH;
322
322
        spin_lock_init(&sc->rx.rxbuflock);
323
323
 
 
324
        common->rx_bufsize = IEEE80211_MAX_MPDU_LEN / 2 +
 
325
                             sc->sc_ah->caps.rx_status_len;
 
326
 
324
327
        if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) {
325
328
                return ath_rx_edma_init(sc, nbufs);
326
329
        } else {
327
 
                common->rx_bufsize = roundup(IEEE80211_MAX_MPDU_LEN,
328
 
                                min(common->cachelsz, (u16)64));
329
 
 
330
330
                ath_dbg(common, ATH_DBG_CONFIG, "cachelsz %u rxbufsize %u\n",
331
331
                        common->cachelsz, common->rx_bufsize);
332
332
 
452
452
        else
453
453
                rfilt |= ATH9K_RX_FILTER_BEACON;
454
454
 
455
 
        if ((AR_SREV_9280_20_OR_LATER(sc->sc_ah) ||
456
 
            AR_SREV_9285_12_OR_LATER(sc->sc_ah)) &&
457
 
            (sc->sc_ah->opmode == NL80211_IFTYPE_AP) &&
 
455
        if ((sc->sc_ah->opmode == NL80211_IFTYPE_AP) ||
458
456
            (sc->rx.rxfilter & FIF_PSPOLL))
459
457
                rfilt |= ATH9K_RX_FILTER_PSPOLL;
460
458
 
461
459
        if (conf_is_ht(&sc->hw->conf))
462
460
                rfilt |= ATH9K_RX_FILTER_COMP_BAR;
463
461
 
464
 
        if (sc->sec_wiphy || (sc->nvifs > 1) ||
465
 
            (sc->rx.rxfilter & FIF_OTHER_BSS)) {
 
462
        if (sc->nvifs > 1 || (sc->rx.rxfilter & FIF_OTHER_BSS)) {
466
463
                /* The following may also be needed for other older chips */
467
464
                if (sc->sc_ah->hw_version.macVersion == AR_SREV_VERSION_9160)
468
465
                        rfilt |= ATH9K_RX_FILTER_PROM;
513
510
bool ath_stoprecv(struct ath_softc *sc)
514
511
{
515
512
        struct ath_hw *ah = sc->sc_ah;
516
 
        bool stopped;
 
513
        bool stopped, reset = false;
517
514
 
518
515
        spin_lock_bh(&sc->rx.rxbuflock);
519
516
        ath9k_hw_abortpcurecv(ah);
520
517
        ath9k_hw_setrxfilter(ah, 0);
521
 
        stopped = ath9k_hw_stopdmarecv(ah);
 
518
        stopped = ath9k_hw_stopdmarecv(ah, &reset);
522
519
 
523
520
        if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)
524
521
                ath_edma_stop_recv(sc);
533
530
                        "confusing the DMA engine when we start RX up\n");
534
531
                ATH_DBG_WARN_ON_ONCE(!stopped);
535
532
        }
536
 
        return stopped;
 
533
        return stopped && !reset;
537
534
}
538
535
 
539
536
void ath_flushrecv(struct ath_softc *sc)
586
583
                return;
587
584
 
588
585
        mgmt = (struct ieee80211_mgmt *)skb->data;
589
 
        if (memcmp(common->curbssid, mgmt->bssid, ETH_ALEN) != 0)
 
586
        if (memcmp(common->curbssid, mgmt->bssid, ETH_ALEN) != 0) {
 
587
                /* TODO:  This doesn't work well if you have stations
 
588
                 * associated to two different APs because curbssid
 
589
                 * is just the last AP that any of the stations associated
 
590
                 * with.
 
591
                 */
590
592
                return; /* not from our current AP */
 
593
        }
591
594
 
592
595
        sc->ps_flags &= ~PS_WAIT_FOR_BEACON;
593
596
 
595
598
                sc->ps_flags &= ~PS_BEACON_SYNC;
596
599
                ath_dbg(common, ATH_DBG_PS,
597
600
                        "Reconfigure Beacon timers based on timestamp from the AP\n");
598
 
                ath_beacon_config(sc, NULL);
 
601
                ath_set_beacon(sc);
 
602
                sc->ps_flags &= ~PS_TSFOOR_SYNC;
599
603
        }
600
604
 
601
605
        if (ath_beacon_dtim_pending_cab(skb)) {
660
664
        }
661
665
}
662
666
 
663
 
static void ath_rx_send_to_mac80211(struct ieee80211_hw *hw,
664
 
                                    struct ath_softc *sc, struct sk_buff *skb)
665
 
{
666
 
        struct ieee80211_hdr *hdr;
667
 
 
668
 
        hdr = (struct ieee80211_hdr *)skb->data;
669
 
 
670
 
        /* Send the frame to mac80211 */
671
 
        if (is_multicast_ether_addr(hdr->addr1)) {
672
 
                int i;
673
 
                /*
674
 
                 * Deliver broadcast/multicast frames to all suitable
675
 
                 * virtual wiphys.
676
 
                 */
677
 
                /* TODO: filter based on channel configuration */
678
 
                for (i = 0; i < sc->num_sec_wiphy; i++) {
679
 
                        struct ath_wiphy *aphy = sc->sec_wiphy[i];
680
 
                        struct sk_buff *nskb;
681
 
                        if (aphy == NULL)
682
 
                                continue;
683
 
                        nskb = skb_copy(skb, GFP_ATOMIC);
684
 
                        if (!nskb)
685
 
                                continue;
686
 
                        ieee80211_rx(aphy->hw, nskb);
687
 
                }
688
 
                ieee80211_rx(sc->hw, skb);
689
 
        } else
690
 
                /* Deliver unicast frames based on receiver address */
691
 
                ieee80211_rx(hw, skb);
692
 
}
693
 
 
694
667
static bool ath_edma_get_buffers(struct ath_softc *sc,
695
668
                                 enum ath9k_rx_qtype qtype)
696
669
{
860
833
        if (rx_stats->rs_datalen > (common->rx_bufsize - rx_status_len))
861
834
                return false;
862
835
 
863
 
        /*
864
 
         * rs_more indicates chained descriptors which can be used
865
 
         * to link buffers together for a sort of scatter-gather
866
 
         * operation.
867
 
         * reject the frame, we don't support scatter-gather yet and
868
 
         * the frame is probably corrupt anyway
869
 
         */
 
836
        /* Only use error bits from the last fragment */
870
837
        if (rx_stats->rs_more)
871
 
                return false;
 
838
                return true;
872
839
 
873
840
        /*
874
841
         * The rx_stats->rs_status will not be set until the end of the
972
939
                               struct ieee80211_hdr *hdr,
973
940
                               struct ath_rx_status *rx_stats)
974
941
{
975
 
        struct ath_wiphy *aphy = hw->priv;
 
942
        struct ath_softc *sc = hw->priv;
976
943
        struct ath_hw *ah = common->ah;
977
944
        int last_rssi;
978
945
        __le16 fc;
979
946
 
980
 
        if (ah->opmode != NL80211_IFTYPE_STATION)
 
947
        if ((ah->opmode != NL80211_IFTYPE_STATION) &&
 
948
            (ah->opmode != NL80211_IFTYPE_ADHOC))
981
949
                return;
982
950
 
983
951
        fc = hdr->frame_control;
984
952
        if (!ieee80211_is_beacon(fc) ||
985
 
            compare_ether_addr(hdr->addr3, common->curbssid))
 
953
            compare_ether_addr(hdr->addr3, common->curbssid)) {
 
954
                /* TODO:  This doesn't work well if you have stations
 
955
                 * associated to two different APs because curbssid
 
956
                 * is just the last AP that any of the stations associated
 
957
                 * with.
 
958
                 */
986
959
                return;
 
960
        }
987
961
 
988
962
        if (rx_stats->rs_rssi != ATH9K_RSSI_BAD && !rx_stats->rs_moreaggr)
989
 
                ATH_RSSI_LPF(aphy->last_rssi, rx_stats->rs_rssi);
 
963
                ATH_RSSI_LPF(sc->last_rssi, rx_stats->rs_rssi);
990
964
 
991
 
        last_rssi = aphy->last_rssi;
 
965
        last_rssi = sc->last_rssi;
992
966
        if (likely(last_rssi != ATH_RSSI_DUMMY_MARKER))
993
967
                rx_stats->rs_rssi = ATH_EP_RND(last_rssi,
994
968
                                              ATH_RSSI_EP_MULTIPLIER);
1020
994
        if (!ath9k_rx_accept(common, hdr, rx_status, rx_stats, decrypt_error))
1021
995
                return -EINVAL;
1022
996
 
 
997
        /* Only use status info from the last fragment */
 
998
        if (rx_stats->rs_more)
 
999
                return 0;
 
1000
 
1023
1001
        ath9k_process_rssi(common, hw, hdr, rx_stats);
1024
1002
 
1025
1003
        if (ath9k_process_rate(common, hw, rx_stats, rx_status))
1029
1007
        rx_status->freq = hw->conf.channel->center_freq;
1030
1008
        rx_status->signal = ATH_DEFAULT_NOISE_FLOOR + rx_stats->rs_rssi;
1031
1009
        rx_status->antenna = rx_stats->rs_antenna;
1032
 
        rx_status->flag |= RX_FLAG_TSFT;
 
1010
        rx_status->flag |= RX_FLAG_MACTIME_MPDU;
1033
1011
 
1034
1012
        return 0;
1035
1013
}
1339
1317
        }
1340
1318
}
1341
1319
 
1342
 
static void ath_ant_div_conf_fast_divbias(struct ath_hw_antcomb_conf *ant_conf)
 
1320
static void ath_ant_div_conf_fast_divbias(struct ath_hw_antcomb_conf *ant_conf,
 
1321
                struct ath_ant_comb *antcomb, int alt_ratio)
1343
1322
{
1344
 
        /* Adjust the fast_div_bias based on main and alt lna conf */
1345
 
        switch ((ant_conf->main_lna_conf << 4) | ant_conf->alt_lna_conf) {
1346
 
        case (0x01): /* A-B LNA2 */
1347
 
                ant_conf->fast_div_bias = 0x3b;
1348
 
                break;
1349
 
        case (0x02): /* A-B LNA1 */
1350
 
                ant_conf->fast_div_bias = 0x3d;
1351
 
                break;
1352
 
        case (0x03): /* A-B A+B */
1353
 
                ant_conf->fast_div_bias = 0x1;
1354
 
                break;
1355
 
        case (0x10): /* LNA2 A-B */
1356
 
                ant_conf->fast_div_bias = 0x7;
1357
 
                break;
1358
 
        case (0x12): /* LNA2 LNA1 */
1359
 
                ant_conf->fast_div_bias = 0x2;
1360
 
                break;
1361
 
        case (0x13): /* LNA2 A+B */
1362
 
                ant_conf->fast_div_bias = 0x7;
1363
 
                break;
1364
 
        case (0x20): /* LNA1 A-B */
1365
 
                ant_conf->fast_div_bias = 0x6;
1366
 
                break;
1367
 
        case (0x21): /* LNA1 LNA2 */
1368
 
                ant_conf->fast_div_bias = 0x0;
1369
 
                break;
1370
 
        case (0x23): /* LNA1 A+B */
1371
 
                ant_conf->fast_div_bias = 0x6;
1372
 
                break;
1373
 
        case (0x30): /* A+B A-B */
1374
 
                ant_conf->fast_div_bias = 0x1;
1375
 
                break;
1376
 
        case (0x31): /* A+B LNA2 */
1377
 
                ant_conf->fast_div_bias = 0x3b;
1378
 
                break;
1379
 
        case (0x32): /* A+B LNA1 */
1380
 
                ant_conf->fast_div_bias = 0x3d;
1381
 
                break;
1382
 
        default:
1383
 
                break;
 
1323
        if (ant_conf->div_group == 0) {
 
1324
                /* Adjust the fast_div_bias based on main and alt lna conf */
 
1325
                switch ((ant_conf->main_lna_conf << 4) |
 
1326
                                ant_conf->alt_lna_conf) {
 
1327
                case (0x01): /* A-B LNA2 */
 
1328
                        ant_conf->fast_div_bias = 0x3b;
 
1329
                        break;
 
1330
                case (0x02): /* A-B LNA1 */
 
1331
                        ant_conf->fast_div_bias = 0x3d;
 
1332
                        break;
 
1333
                case (0x03): /* A-B A+B */
 
1334
                        ant_conf->fast_div_bias = 0x1;
 
1335
                        break;
 
1336
                case (0x10): /* LNA2 A-B */
 
1337
                        ant_conf->fast_div_bias = 0x7;
 
1338
                        break;
 
1339
                case (0x12): /* LNA2 LNA1 */
 
1340
                        ant_conf->fast_div_bias = 0x2;
 
1341
                        break;
 
1342
                case (0x13): /* LNA2 A+B */
 
1343
                        ant_conf->fast_div_bias = 0x7;
 
1344
                        break;
 
1345
                case (0x20): /* LNA1 A-B */
 
1346
                        ant_conf->fast_div_bias = 0x6;
 
1347
                        break;
 
1348
                case (0x21): /* LNA1 LNA2 */
 
1349
                        ant_conf->fast_div_bias = 0x0;
 
1350
                        break;
 
1351
                case (0x23): /* LNA1 A+B */
 
1352
                        ant_conf->fast_div_bias = 0x6;
 
1353
                        break;
 
1354
                case (0x30): /* A+B A-B */
 
1355
                        ant_conf->fast_div_bias = 0x1;
 
1356
                        break;
 
1357
                case (0x31): /* A+B LNA2 */
 
1358
                        ant_conf->fast_div_bias = 0x3b;
 
1359
                        break;
 
1360
                case (0x32): /* A+B LNA1 */
 
1361
                        ant_conf->fast_div_bias = 0x3d;
 
1362
                        break;
 
1363
                default:
 
1364
                        break;
 
1365
                }
 
1366
        } else if (ant_conf->div_group == 2) {
 
1367
                /* Adjust the fast_div_bias based on main and alt_lna_conf */
 
1368
                switch ((ant_conf->main_lna_conf << 4) |
 
1369
                                ant_conf->alt_lna_conf) {
 
1370
                case (0x01): /* A-B LNA2 */
 
1371
                        ant_conf->fast_div_bias = 0x1;
 
1372
                        ant_conf->main_gaintb = 0;
 
1373
                        ant_conf->alt_gaintb = 0;
 
1374
                        break;
 
1375
                case (0x02): /* A-B LNA1 */
 
1376
                        ant_conf->fast_div_bias = 0x1;
 
1377
                        ant_conf->main_gaintb = 0;
 
1378
                        ant_conf->alt_gaintb = 0;
 
1379
                        break;
 
1380
                case (0x03): /* A-B A+B */
 
1381
                        ant_conf->fast_div_bias = 0x1;
 
1382
                        ant_conf->main_gaintb = 0;
 
1383
                        ant_conf->alt_gaintb = 0;
 
1384
                        break;
 
1385
                case (0x10): /* LNA2 A-B */
 
1386
                        if (!(antcomb->scan) &&
 
1387
                                (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO))
 
1388
                                ant_conf->fast_div_bias = 0x1;
 
1389
                        else
 
1390
                                ant_conf->fast_div_bias = 0x2;
 
1391
                        ant_conf->main_gaintb = 0;
 
1392
                        ant_conf->alt_gaintb = 0;
 
1393
                        break;
 
1394
                case (0x12): /* LNA2 LNA1 */
 
1395
                        ant_conf->fast_div_bias = 0x1;
 
1396
                        ant_conf->main_gaintb = 0;
 
1397
                        ant_conf->alt_gaintb = 0;
 
1398
                        break;
 
1399
                case (0x13): /* LNA2 A+B */
 
1400
                        if (!(antcomb->scan) &&
 
1401
                                (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO))
 
1402
                                ant_conf->fast_div_bias = 0x1;
 
1403
                        else
 
1404
                                ant_conf->fast_div_bias = 0x2;
 
1405
                        ant_conf->main_gaintb = 0;
 
1406
                        ant_conf->alt_gaintb = 0;
 
1407
                        break;
 
1408
                case (0x20): /* LNA1 A-B */
 
1409
                        if (!(antcomb->scan) &&
 
1410
                                (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO))
 
1411
                                ant_conf->fast_div_bias = 0x1;
 
1412
                        else
 
1413
                                ant_conf->fast_div_bias = 0x2;
 
1414
                        ant_conf->main_gaintb = 0;
 
1415
                        ant_conf->alt_gaintb = 0;
 
1416
                        break;
 
1417
                case (0x21): /* LNA1 LNA2 */
 
1418
                        ant_conf->fast_div_bias = 0x1;
 
1419
                        ant_conf->main_gaintb = 0;
 
1420
                        ant_conf->alt_gaintb = 0;
 
1421
                        break;
 
1422
                case (0x23): /* LNA1 A+B */
 
1423
                        if (!(antcomb->scan) &&
 
1424
                                (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO))
 
1425
                                ant_conf->fast_div_bias = 0x1;
 
1426
                        else
 
1427
                                ant_conf->fast_div_bias = 0x2;
 
1428
                        ant_conf->main_gaintb = 0;
 
1429
                        ant_conf->alt_gaintb = 0;
 
1430
                        break;
 
1431
                case (0x30): /* A+B A-B */
 
1432
                        ant_conf->fast_div_bias = 0x1;
 
1433
                        ant_conf->main_gaintb = 0;
 
1434
                        ant_conf->alt_gaintb = 0;
 
1435
                        break;
 
1436
                case (0x31): /* A+B LNA2 */
 
1437
                        ant_conf->fast_div_bias = 0x1;
 
1438
                        ant_conf->main_gaintb = 0;
 
1439
                        ant_conf->alt_gaintb = 0;
 
1440
                        break;
 
1441
                case (0x32): /* A+B LNA1 */
 
1442
                        ant_conf->fast_div_bias = 0x1;
 
1443
                        ant_conf->main_gaintb = 0;
 
1444
                        ant_conf->alt_gaintb = 0;
 
1445
                        break;
 
1446
                default:
 
1447
                        break;
 
1448
                }
 
1449
 
1384
1450
        }
 
1451
 
1385
1452
}
1386
1453
 
1387
1454
/* Antenna diversity and combining */
1390
1457
        struct ath_hw_antcomb_conf div_ant_conf;
1391
1458
        struct ath_ant_comb *antcomb = &sc->ant_comb;
1392
1459
        int alt_ratio = 0, alt_rssi_avg = 0, main_rssi_avg = 0, curr_alt_set;
1393
 
        int curr_main_set, curr_bias;
 
1460
        int curr_main_set;
1394
1461
        int main_rssi = rs->rs_rssi_ctl0;
1395
1462
        int alt_rssi = rs->rs_rssi_ctl1;
1396
1463
        int rx_ant_conf,  main_ant_conf;
1401
1468
        main_ant_conf = (rs->rs_rssi_ctl2 >> ATH_ANT_RX_MAIN_SHIFT) &
1402
1469
                         ATH_ANT_RX_MASK;
1403
1470
 
1404
 
        /* Record packet only when alt_rssi is positive */
1405
 
        if (alt_rssi > 0) {
 
1471
        /* Record packet only when both main_rssi and  alt_rssi is positive */
 
1472
        if (main_rssi > 0 && alt_rssi > 0) {
1406
1473
                antcomb->total_pkt_count++;
1407
1474
                antcomb->main_total_rssi += main_rssi;
1408
1475
                antcomb->alt_total_rssi  += alt_rssi;
1444
1511
        ath9k_hw_antdiv_comb_conf_get(sc->sc_ah, &div_ant_conf);
1445
1512
        curr_alt_set = div_ant_conf.alt_lna_conf;
1446
1513
        curr_main_set = div_ant_conf.main_lna_conf;
1447
 
        curr_bias = div_ant_conf.fast_div_bias;
1448
1514
 
1449
1515
        antcomb->count++;
1450
1516
 
1463
1529
        }
1464
1530
 
1465
1531
        if (!antcomb->scan) {
1466
 
                if (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO) {
 
1532
                if (ath_ant_div_comb_alt_check(div_ant_conf.div_group,
 
1533
                                        alt_ratio, curr_main_set, curr_alt_set,
 
1534
                                        alt_rssi_avg, main_rssi_avg)) {
1467
1535
                        if (curr_alt_set == ATH_ANT_DIV_COMB_LNA2) {
1468
1536
                                /* Switch main and alt LNA */
1469
1537
                                div_ant_conf.main_lna_conf =
1492
1560
                }
1493
1561
 
1494
1562
                if ((alt_rssi_avg < (main_rssi_avg +
1495
 
                    ATH_ANT_DIV_COMB_LNA1_LNA2_DELTA)))
 
1563
                                                div_ant_conf.lna1_lna2_delta)))
1496
1564
                        goto div_comb_done;
1497
1565
        }
1498
1566
 
1606
1674
        antcomb->quick_scan_cnt++;
1607
1675
 
1608
1676
div_comb_done:
1609
 
        ath_ant_div_conf_fast_divbias(&div_ant_conf);
1610
 
 
 
1677
        ath_ant_div_conf_fast_divbias(&div_ant_conf, antcomb, alt_ratio);
1611
1678
        ath9k_hw_antdiv_comb_conf_set(sc->sc_ah, &div_ant_conf);
1612
1679
 
1613
1680
        antcomb->scan_start_time = jiffies;
1621
1688
int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp)
1622
1689
{
1623
1690
        struct ath_buf *bf;
1624
 
        struct sk_buff *skb = NULL, *requeue_skb;
 
1691
        struct sk_buff *skb = NULL, *requeue_skb, *hdr_skb;
1625
1692
        struct ieee80211_rx_status *rxs;
1626
1693
        struct ath_hw *ah = sc->sc_ah;
1627
1694
        struct ath_common *common = ath9k_hw_common(ah);
1630
1697
         * virtual wiphy so to account for that we iterate over the active
1631
1698
         * wiphys and find the appropriate wiphy and therefore hw.
1632
1699
         */
1633
 
        struct ieee80211_hw *hw = NULL;
 
1700
        struct ieee80211_hw *hw = sc->hw;
1634
1701
        struct ieee80211_hdr *hdr;
1635
1702
        int retval;
1636
1703
        bool decrypt_error = false;
1672
1739
                if (!skb)
1673
1740
                        continue;
1674
1741
 
1675
 
                hdr = (struct ieee80211_hdr *) (skb->data + rx_status_len);
1676
 
                rxs =  IEEE80211_SKB_RXCB(skb);
 
1742
                /*
 
1743
                 * Take frame header from the first fragment and RX status from
 
1744
                 * the last one.
 
1745
                 */
 
1746
                if (sc->rx.frag)
 
1747
                        hdr_skb = sc->rx.frag;
 
1748
                else
 
1749
                        hdr_skb = skb;
1677
1750
 
1678
 
                hw = ath_get_virt_hw(sc, hdr);
 
1751
                hdr = (struct ieee80211_hdr *) (hdr_skb->data + rx_status_len);
 
1752
                rxs = IEEE80211_SKB_RXCB(hdr_skb);
1679
1753
 
1680
1754
                ath_debug_stat_rx(sc, &rs);
1681
1755
 
1684
1758
                 * chain it back at the queue without processing it.
1685
1759
                 */
1686
1760
                if (flush)
1687
 
                        goto requeue;
 
1761
                        goto requeue_drop_frag;
1688
1762
 
1689
1763
                retval = ath9k_rx_skb_preprocess(common, hw, hdr, &rs,
1690
1764
                                                 rxs, &decrypt_error);
1691
1765
                if (retval)
1692
 
                        goto requeue;
 
1766
                        goto requeue_drop_frag;
1693
1767
 
1694
1768
                rxs->mactime = (tsf & ~0xffffffffULL) | rs.rs_tstamp;
1695
1769
                if (rs.rs_tstamp > tsf_lower &&
1709
1783
                 * skb and put it at the tail of the sc->rx.rxbuf list for
1710
1784
                 * processing. */
1711
1785
                if (!requeue_skb)
1712
 
                        goto requeue;
 
1786
                        goto requeue_drop_frag;
1713
1787
 
1714
1788
                /* Unmap the frame */
1715
1789
                dma_unmap_single(sc->dev, bf->bf_buf_addr,
1720
1794
                if (ah->caps.rx_status_len)
1721
1795
                        skb_pull(skb, ah->caps.rx_status_len);
1722
1796
 
1723
 
                ath9k_rx_skb_postprocess(common, skb, &rs,
1724
 
                                         rxs, decrypt_error);
 
1797
                if (!rs.rs_more)
 
1798
                        ath9k_rx_skb_postprocess(common, hdr_skb, &rs,
 
1799
                                                 rxs, decrypt_error);
1725
1800
 
1726
1801
                /* We will now give hardware our shiny new allocated skb */
1727
1802
                bf->bf_mpdu = requeue_skb;
1734
1809
                        bf->bf_mpdu = NULL;
1735
1810
                        bf->bf_buf_addr = 0;
1736
1811
                        ath_err(common, "dma_mapping_error() on RX\n");
1737
 
                        ath_rx_send_to_mac80211(hw, sc, skb);
 
1812
                        ieee80211_rx(hw, skb);
1738
1813
                        break;
1739
1814
                }
1740
1815
 
 
1816
                if (rs.rs_more) {
 
1817
                        /*
 
1818
                         * rs_more indicates chained descriptors which can be
 
1819
                         * used to link buffers together for a sort of
 
1820
                         * scatter-gather operation.
 
1821
                         */
 
1822
                        if (sc->rx.frag) {
 
1823
                                /* too many fragments - cannot handle frame */
 
1824
                                dev_kfree_skb_any(sc->rx.frag);
 
1825
                                dev_kfree_skb_any(skb);
 
1826
                                skb = NULL;
 
1827
                        }
 
1828
                        sc->rx.frag = skb;
 
1829
                        goto requeue;
 
1830
                }
 
1831
 
 
1832
                if (sc->rx.frag) {
 
1833
                        int space = skb->len - skb_tailroom(hdr_skb);
 
1834
 
 
1835
                        sc->rx.frag = NULL;
 
1836
 
 
1837
                        if (pskb_expand_head(hdr_skb, 0, space, GFP_ATOMIC) < 0) {
 
1838
                                dev_kfree_skb(skb);
 
1839
                                goto requeue_drop_frag;
 
1840
                        }
 
1841
 
 
1842
                        skb_copy_from_linear_data(skb, skb_put(hdr_skb, skb->len),
 
1843
                                                  skb->len);
 
1844
                        dev_kfree_skb_any(skb);
 
1845
                        skb = hdr_skb;
 
1846
                }
 
1847
 
1741
1848
                /*
1742
1849
                 * change the default rx antenna if rx diversity chooses the
1743
1850
                 * other antenna 3 times in a row.
1754
1861
                if ((sc->ps_flags & (PS_WAIT_FOR_BEACON |
1755
1862
                                              PS_WAIT_FOR_CAB |
1756
1863
                                              PS_WAIT_FOR_PSPOLL_DATA)) ||
1757
 
                                        unlikely(ath9k_check_auto_sleep(sc)))
 
1864
                                                ath9k_check_auto_sleep(sc))
1758
1865
                        ath_rx_ps(sc, skb);
1759
1866
                spin_unlock_irqrestore(&sc->sc_pm_lock, flags);
1760
1867
 
1761
1868
                if (ah->caps.hw_caps & ATH9K_HW_CAP_ANT_DIV_COMB)
1762
1869
                        ath_ant_comb_scan(sc, &rs);
1763
1870
 
1764
 
                ath_rx_send_to_mac80211(hw, sc, skb);
 
1871
                ieee80211_rx(hw, skb);
1765
1872
 
 
1873
requeue_drop_frag:
 
1874
                if (sc->rx.frag) {
 
1875
                        dev_kfree_skb_any(sc->rx.frag);
 
1876
                        sc->rx.frag = NULL;
 
1877
                }
1766
1878
requeue:
1767
1879
                if (edma) {
1768
1880
                        list_add_tail(&bf->list, &sc->rx.rxbuf);
1770
1882
                } else {
1771
1883
                        list_move_tail(&bf->list, &sc->rx.rxbuf);
1772
1884
                        ath_rx_buf_link(sc, bf);
 
1885
                        ath9k_hw_rxena(ah);
1773
1886
                }
1774
1887
        } while (1);
1775
1888