Merge tag 'wireless-drivers-next-for-davem-2018-02-08' of git://git.kernel.org/pub...
authorDavid S. Miller <davem@davemloft.net>
Thu, 8 Feb 2018 20:32:25 +0000 (15:32 -0500)
committerDavid S. Miller <davem@davemloft.net>
Thu, 8 Feb 2018 20:32:25 +0000 (15:32 -0500)
Kalle Valo says:

====================
wireless-drivers-next patches for 4.16

The most important here is the ssb fix, it has been reported by the
users frequently and the fix just missed the final v4.15. Also
numerous other fixes, mt76 had multiple problems with aggregation and
a long standing unaligned access bug in rtlwifi is finally fixed.

Major changes:

ath10k

* correct firmware RAM dump length for QCA6174/QCA9377

* add new QCA988X device id

* fix a kernel panic during pci probe

* revert a recent commit which broke ath10k firmware metadata parsing

ath9k

* fix a noise floor regression introduced during the merge window

* add new device id

rtlwifi

* fix unaligned access seen on ARM architecture

mt76

* various aggregation fixes which fix connection stalls

ssb

* fix b43 and b44 on non-MIPS which broke in v4.15-rc9
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
18 files changed:
drivers/net/wireless/ath/ath10k/core.c
drivers/net/wireless/ath/ath10k/coredump.c
drivers/net/wireless/ath/ath10k/debug.c
drivers/net/wireless/ath/ath10k/hw.h
drivers/net/wireless/ath/ath10k/pci.c
drivers/net/wireless/ath/ath9k/calib.c
drivers/net/wireless/ath/ath9k/hif_usb.c
drivers/net/wireless/mediatek/mt76/agg-rx.c
drivers/net/wireless/mediatek/mt76/mac80211.c
drivers/net/wireless/mediatek/mt76/mt76.h
drivers/net/wireless/mediatek/mt76/mt76x2.h
drivers/net/wireless/mediatek/mt76/mt76x2_init.c
drivers/net/wireless/mediatek/mt76/mt76x2_mac.c
drivers/net/wireless/mediatek/mt76/mt76x2_main.c
drivers/net/wireless/realtek/rtlwifi/rtl8821ae/hw.c
drivers/net/wireless/realtek/rtlwifi/wifi.h
drivers/ssb/Kconfig
include/linux/pci_ids.h

index b0fdc1023619349bb726a3b238c9556dc1e1668e..f3ec13b80b20c1b27d4aa98dfb31a7751d81db27 100644 (file)
@@ -90,6 +90,35 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
                .target_64bit = false,
                .rx_ring_fill_level = HTT_RX_RING_FILL_LEVEL,
        },
+       {
+               .id = QCA988X_HW_2_0_VERSION,
+               .dev_id = QCA988X_2_0_DEVICE_ID_UBNT,
+               .name = "qca988x hw2.0 ubiquiti",
+               .patch_load_addr = QCA988X_HW_2_0_PATCH_LOAD_ADDR,
+               .uart_pin = 7,
+               .cc_wraparound_type = ATH10K_HW_CC_WRAP_SHIFTED_ALL,
+               .otp_exe_param = 0,
+               .channel_counters_freq_hz = 88000,
+               .max_probe_resp_desc_thres = 0,
+               .cal_data_len = 2116,
+               .fw = {
+                       .dir = QCA988X_HW_2_0_FW_DIR,
+                       .board = QCA988X_HW_2_0_BOARD_DATA_FILE,
+                       .board_size = QCA988X_BOARD_DATA_SZ,
+                       .board_ext_size = QCA988X_BOARD_EXT_DATA_SZ,
+               },
+               .hw_ops = &qca988x_ops,
+               .decap_align_bytes = 4,
+               .spectral_bin_discard = 0,
+               .vht160_mcs_rx_highest = 0,
+               .vht160_mcs_tx_highest = 0,
+               .n_cipher_suites = 8,
+               .num_peers = TARGET_TLV_NUM_PEERS,
+               .ast_skid_limit = 0x10,
+               .num_wds_entries = 0x20,
+               .target_64bit = false,
+               .rx_ring_fill_level = HTT_RX_RING_FILL_LEVEL,
+       },
        {
                .id = QCA9887_HW_1_0_VERSION,
                .dev_id = QCA9887_1_0_DEVICE_ID,
@@ -1276,10 +1305,7 @@ static int ath10k_core_fetch_board_data_api_n(struct ath10k *ar,
                len -= sizeof(*hdr);
                data = hdr->data;
 
-               /* jump over the padding */
-               ie_len = ALIGN(ie_len, 4);
-
-               if (len < ie_len) {
+               if (len < ALIGN(ie_len, 4)) {
                        ath10k_err(ar, "invalid length for board ie_id %d ie_len %zu len %zu\n",
                                   ie_id, ie_len, len);
                        ret = -EINVAL;
@@ -1318,6 +1344,9 @@ static int ath10k_core_fetch_board_data_api_n(struct ath10k *ar,
                        goto out;
                }
 
+               /* jump over the padding */
+               ie_len = ALIGN(ie_len, 4);
+
                len -= ie_len;
                data += ie_len;
        }
@@ -1448,9 +1477,6 @@ int ath10k_core_fetch_firmware_api_n(struct ath10k *ar, const char *name,
                len -= sizeof(*hdr);
                data += sizeof(*hdr);
 
-               /* jump over the padding */
-               ie_len = ALIGN(ie_len, 4);
-
                if (len < ie_len) {
                        ath10k_err(ar, "invalid length for FW IE %d (%zu < %zu)\n",
                                   ie_id, len, ie_len);
@@ -1556,6 +1582,9 @@ int ath10k_core_fetch_firmware_api_n(struct ath10k *ar, const char *name,
                        break;
                }
 
+               /* jump over the padding */
+               ie_len = ALIGN(ie_len, 4);
+
                len -= ie_len;
                data += ie_len;
        }
index 4dde126dab171a0b6eeed842fd8a0c962e089808..7173b3743b43b8256a28ce7df97d239e28d728bf 100644 (file)
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2011-2017 Qualcomm Atheros, Inc.
+ * Copyright (c) 2018, The Linux Foundation. All rights reserved.
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -616,7 +617,7 @@ static const struct ath10k_mem_region qca6174_hw30_mem_regions[] = {
        {
                .type = ATH10K_MEM_REGION_TYPE_DRAM,
                .start = 0x400000,
-               .len = 0x90000,
+               .len = 0xa8000,
                .name = "DRAM",
                .section_table = {
                        .sections = NULL,
index 6d836a26272fe7a7e4ab84c744111552c8d003b7..554cd7856cb6e2949cc5eff17aeb76a414204d63 100644 (file)
@@ -1,6 +1,7 @@
 /*
  * Copyright (c) 2005-2011 Atheros Communications Inc.
  * Copyright (c) 2011-2017 Qualcomm Atheros, Inc.
+ * Copyright (c) 2018, The Linux Foundation. All rights reserved.
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -81,6 +82,8 @@ void ath10k_debug_print_hwfw_info(struct ath10k *ar)
 void ath10k_debug_print_board_info(struct ath10k *ar)
 {
        char boardinfo[100];
+       const struct firmware *board;
+       u32 crc;
 
        if (ar->id.bmi_ids_valid)
                scnprintf(boardinfo, sizeof(boardinfo), "%d:%d",
@@ -88,11 +91,16 @@ void ath10k_debug_print_board_info(struct ath10k *ar)
        else
                scnprintf(boardinfo, sizeof(boardinfo), "N/A");
 
+       board = ar->normal_mode_fw.board;
+       if (!IS_ERR_OR_NULL(board))
+               crc = crc32_le(0, board->data, board->size);
+       else
+               crc = 0;
+
        ath10k_info(ar, "board_file api %d bmi_id %s crc32 %08x",
                    ar->bd_api,
                    boardinfo,
-                   crc32_le(0, ar->normal_mode_fw.board->data,
-                            ar->normal_mode_fw.board->size));
+                   crc);
 }
 
 void ath10k_debug_print_boot_info(struct ath10k *ar)
index 6203bc65799bee7b38a14d7be82bae9d506c7b8c..413b1b4321f77f7dfbd947844e1fad40d36f0e08 100644 (file)
@@ -22,6 +22,7 @@
 
 #define ATH10K_FW_DIR                  "ath10k"
 
+#define QCA988X_2_0_DEVICE_ID_UBNT   (0x11ac)
 #define QCA988X_2_0_DEVICE_ID   (0x003c)
 #define QCA6164_2_1_DEVICE_ID   (0x0041)
 #define QCA6174_2_1_DEVICE_ID   (0x003e)
index 355db6a0fcf3ee9ddc3213bece83da1004c36e4c..1b266cd0c2ec086bd76eae5ffe2bce66a9c6a4a4 100644 (file)
@@ -58,6 +58,9 @@ MODULE_PARM_DESC(reset_mode, "0: auto, 1: warm only (default: 0)");
 #define ATH10K_DIAG_TRANSFER_LIMIT     0x5000
 
 static const struct pci_device_id ath10k_pci_id_table[] = {
+       /* PCI-E QCA988X V2 (Ubiquiti branded) */
+       { PCI_VDEVICE(UBIQUITI, QCA988X_2_0_DEVICE_ID_UBNT) },
+
        { PCI_VDEVICE(ATHEROS, QCA988X_2_0_DEVICE_ID) }, /* PCI-E QCA988X V2 */
        { PCI_VDEVICE(ATHEROS, QCA6164_2_1_DEVICE_ID) }, /* PCI-E QCA6164 V2.1 */
        { PCI_VDEVICE(ATHEROS, QCA6174_2_1_DEVICE_ID) }, /* PCI-E QCA6174 V2.1 */
@@ -74,6 +77,7 @@ static const struct ath10k_pci_supp_chip ath10k_pci_supp_chips[] = {
         * hacks. ath10k doesn't have them and these devices crash horribly
         * because of that.
         */
+       { QCA988X_2_0_DEVICE_ID_UBNT, QCA988X_HW_2_0_CHIP_ID_REV },
        { QCA988X_2_0_DEVICE_ID, QCA988X_HW_2_0_CHIP_ID_REV },
 
        { QCA6164_2_1_DEVICE_ID, QCA6174_HW_2_1_CHIP_ID_REV },
@@ -2193,6 +2197,7 @@ static int ath10k_pci_get_num_banks(struct ath10k *ar)
        struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
 
        switch (ar_pci->pdev->device) {
+       case QCA988X_2_0_DEVICE_ID_UBNT:
        case QCA988X_2_0_DEVICE_ID:
        case QCA99X0_2_0_DEVICE_ID:
        case QCA9888_2_0_DEVICE_ID:
@@ -3424,6 +3429,7 @@ static int ath10k_pci_probe(struct pci_dev *pdev,
        u32 (*targ_cpu_to_ce_addr)(struct ath10k *ar, u32 addr);
 
        switch (pci_dev->device) {
+       case QCA988X_2_0_DEVICE_ID_UBNT:
        case QCA988X_2_0_DEVICE_ID:
                hw_rev = ATH10K_HW_QCA988X;
                pci_ps = false;
index 3d9447e21025f41bc59ea362b3a3e8d26161dd9f..695c779ae8cf7440084b3613daeb090ba86242f0 100644 (file)
@@ -72,7 +72,7 @@ static s16 ath9k_hw_get_default_nf(struct ath_hw *ah,
 s16 ath9k_hw_getchan_noise(struct ath_hw *ah, struct ath9k_channel *chan,
                           s16 nf)
 {
-       s8 noise = ath9k_hw_get_default_nf(ah, chan, 0);
+       s8 noise = ATH_DEFAULT_NOISE_FLOOR;
 
        if (nf) {
                s8 delta = nf - ATH9K_NF_CAL_NOISE_THRESH -
index 56676eaff24c186f323fc79330b061e3d74e6ae5..cb0eef13af1c8d3791832d78d70e5546b2ade346 100644 (file)
@@ -24,6 +24,7 @@ static const struct usb_device_id ath9k_hif_usb_ids[] = {
        { USB_DEVICE(0x0cf3, 0x9271) }, /* Atheros */
        { USB_DEVICE(0x0cf3, 0x1006) }, /* Atheros */
        { USB_DEVICE(0x0846, 0x9030) }, /* Netgear N150 */
+       { USB_DEVICE(0x07b8, 0x9271) }, /* Altai WA1011N-GU */
        { USB_DEVICE(0x07D1, 0x3A10) }, /* Dlink Wireless 150 */
        { USB_DEVICE(0x13D3, 0x3327) }, /* Azurewave */
        { USB_DEVICE(0x13D3, 0x3328) }, /* Azurewave */
index 8027bb7c03c2269e273dadb10f0c18379b9c8a6b..fcb208d1f2762d9076a1e3ca3cf297dfb2e54fdb 100644 (file)
@@ -98,6 +98,7 @@ mt76_rx_aggr_reorder_work(struct work_struct *work)
                                               reorder_work.work);
        struct mt76_dev *dev = tid->dev;
        struct sk_buff_head frames;
+       int nframes;
 
        __skb_queue_head_init(&frames);
 
@@ -105,14 +106,44 @@ mt76_rx_aggr_reorder_work(struct work_struct *work)
 
        spin_lock(&tid->lock);
        mt76_rx_aggr_check_release(tid, &frames);
+       nframes = tid->nframes;
        spin_unlock(&tid->lock);
 
-       ieee80211_queue_delayed_work(tid->dev->hw, &tid->reorder_work, REORDER_TIMEOUT);
+       if (nframes)
+               ieee80211_queue_delayed_work(tid->dev->hw, &tid->reorder_work,
+                                            REORDER_TIMEOUT);
        mt76_rx_complete(dev, &frames, -1);
 
        local_bh_enable();
 }
 
+static void
+mt76_rx_aggr_check_ctl(struct sk_buff *skb, struct sk_buff_head *frames)
+{
+       struct mt76_rx_status *status = (struct mt76_rx_status *) skb->cb;
+       struct ieee80211_bar *bar = (struct ieee80211_bar *) skb->data;
+       struct mt76_wcid *wcid = status->wcid;
+       struct mt76_rx_tid *tid;
+       u16 seqno;
+
+       if (!ieee80211_is_ctl(bar->frame_control))
+               return;
+
+       if (!ieee80211_is_back_req(bar->frame_control))
+               return;
+
+       status->tid = le16_to_cpu(bar->control) >> 12;
+       seqno = le16_to_cpu(bar->start_seq_num) >> 4;
+       tid = rcu_dereference(wcid->aggr[status->tid]);
+       if (!tid)
+               return;
+
+       spin_lock_bh(&tid->lock);
+       mt76_rx_aggr_release_frames(tid, frames, seqno);
+       mt76_rx_aggr_release_head(tid, frames);
+       spin_unlock_bh(&tid->lock);
+}
+
 void mt76_rx_aggr_reorder(struct sk_buff *skb, struct sk_buff_head *frames)
 {
        struct mt76_rx_status *status = (struct mt76_rx_status *) skb->cb;
@@ -126,9 +157,14 @@ void mt76_rx_aggr_reorder(struct sk_buff *skb, struct sk_buff_head *frames)
        __skb_queue_tail(frames, skb);
 
        sta = wcid_to_sta(wcid);
-       if (!sta || !status->aggr)
+       if (!sta)
                return;
 
+       if (!status->aggr) {
+               mt76_rx_aggr_check_ctl(skb, frames);
+               return;
+       }
+
        tid = rcu_dereference(wcid->aggr[status->tid]);
        if (!tid)
                return;
index 5fcb2deb89a242dd061d6636dc93ce444444113f..85f8d324ebf82c3d3f2fc15676d123da396274f7 100644 (file)
@@ -276,6 +276,7 @@ int mt76_register_device(struct mt76_dev *dev, bool vht,
        ieee80211_hw_set(hw, TX_AMSDU);
        ieee80211_hw_set(hw, TX_FRAG_LIST);
        ieee80211_hw_set(hw, MFP_CAPABLE);
+       ieee80211_hw_set(hw, AP_LINK_PS);
 
        wiphy->flags |= WIPHY_FLAG_IBSS_RSN;
 
@@ -470,6 +471,53 @@ mt76_check_ccmp_pn(struct sk_buff *skb)
        return 0;
 }
 
+static void
+mt76_check_ps(struct mt76_dev *dev, struct sk_buff *skb)
+{
+       struct mt76_rx_status *status = (struct mt76_rx_status *) skb->cb;
+       struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
+       struct ieee80211_sta *sta;
+       struct mt76_wcid *wcid = status->wcid;
+       bool ps;
+
+       if (!wcid || !wcid->sta)
+               return;
+
+       sta = container_of((void *) wcid, struct ieee80211_sta, drv_priv);
+
+       if (!test_bit(MT_WCID_FLAG_CHECK_PS, &wcid->flags))
+               return;
+
+       if (ieee80211_is_pspoll(hdr->frame_control)) {
+               ieee80211_sta_pspoll(sta);
+               return;
+       }
+
+       if (ieee80211_has_morefrags(hdr->frame_control) ||
+               !(ieee80211_is_mgmt(hdr->frame_control) ||
+                 ieee80211_is_data(hdr->frame_control)))
+               return;
+
+       ps = ieee80211_has_pm(hdr->frame_control);
+
+       if (ps && (ieee80211_is_data_qos(hdr->frame_control) ||
+                  ieee80211_is_qos_nullfunc(hdr->frame_control)))
+               ieee80211_sta_uapsd_trigger(sta, status->tid);
+
+       if (!!test_bit(MT_WCID_FLAG_PS, &wcid->flags) == ps)
+               return;
+
+       if (ps) {
+               set_bit(MT_WCID_FLAG_PS, &wcid->flags);
+               mt76_stop_tx_queues(dev, sta, true);
+       } else {
+               clear_bit(MT_WCID_FLAG_PS, &wcid->flags);
+       }
+
+       ieee80211_sta_ps_transition(sta, ps);
+       dev->drv->sta_ps(dev, sta, ps);
+}
+
 void mt76_rx_complete(struct mt76_dev *dev, struct sk_buff_head *frames,
                      int queue)
 {
@@ -498,8 +546,10 @@ void mt76_rx_poll_complete(struct mt76_dev *dev, enum mt76_rxq_id q)
 
        __skb_queue_head_init(&frames);
 
-       while ((skb = __skb_dequeue(&dev->rx_skb[q])) != NULL)
+       while ((skb = __skb_dequeue(&dev->rx_skb[q])) != NULL) {
+               mt76_check_ps(dev, skb);
                mt76_rx_aggr_reorder(skb, &frames);
+       }
 
        mt76_rx_complete(dev, &frames, q);
 }
index 129015c9d1169e085639327a3d96a3494731e19b..d2ce15093eddd14cfdfb8bf6a63309433709d495 100644 (file)
@@ -121,11 +121,18 @@ struct mt76_queue_ops {
        void (*kick)(struct mt76_dev *dev, struct mt76_queue *q);
 };
 
+enum mt76_wcid_flags {
+       MT_WCID_FLAG_CHECK_PS,
+       MT_WCID_FLAG_PS,
+};
+
 struct mt76_wcid {
        struct mt76_rx_tid __rcu *aggr[IEEE80211_NUM_TIDS];
 
        struct work_struct aggr_work;
 
+       unsigned long flags;
+
        u8 idx;
        u8 hw_key_idx;
 
@@ -206,6 +213,9 @@ struct mt76_driver_ops {
                       struct sk_buff *skb);
 
        void (*rx_poll_complete)(struct mt76_dev *dev, enum mt76_rxq_id q);
+
+       void (*sta_ps)(struct mt76_dev *dev, struct ieee80211_sta *sta,
+                      bool ps);
 };
 
 struct mt76_channel_state {
index 17df17afd9bf9bbba3d1e2126aa9871a69de62c1..e62131b88102099c97ca581ad85655a4f36889a7 100644 (file)
@@ -218,6 +218,8 @@ void mt76x2_rx_poll_complete(struct mt76_dev *mdev, enum mt76_rxq_id q);
 void mt76x2_queue_rx_skb(struct mt76_dev *mdev, enum mt76_rxq_id q,
                         struct sk_buff *skb);
 
+void mt76x2_sta_ps(struct mt76_dev *dev, struct ieee80211_sta *sta, bool ps);
+
 void mt76x2_update_channel(struct mt76_dev *mdev);
 
 s8 mt76x2_tx_get_max_txpwr_adj(struct mt76x2_dev *dev,
index 1b00ae4465a27becadd27e0a13c02b98248b7fe5..9dbf94947324e3ed2532aef574350783f65f6d76 100644 (file)
@@ -630,6 +630,7 @@ struct mt76x2_dev *mt76x2_alloc_device(struct device *pdev)
                .tx_complete_skb = mt76x2_tx_complete_skb,
                .rx_skb = mt76x2_queue_rx_skb,
                .rx_poll_complete = mt76x2_rx_poll_complete,
+               .sta_ps = mt76x2_sta_ps,
        };
        struct ieee80211_hw *hw;
        struct mt76x2_dev *dev;
index 6c30b5eaa9ca54c8b025e15b7f0fe60487998f28..7ea3d841918e92393ebfd7810b4ec61e365edb84 100644 (file)
@@ -341,7 +341,7 @@ int mt76x2_mac_process_rx(struct mt76x2_dev *dev, struct sk_buff *skb,
 
        mt76x2_remove_hdr_pad(skb, pad_len);
 
-       if (rxinfo & MT_RXINFO_BA)
+       if ((rxinfo & MT_RXINFO_BA) && !(rxinfo & MT_RXINFO_NULL))
                status->aggr = true;
 
        if (WARN_ON_ONCE(len > skb->len))
index bf26284b9989d60376a47e1019ad13546c3b333a..205043b470b208e6a4a04f1bb6c618c62929ff90 100644 (file)
@@ -282,6 +282,9 @@ mt76x2_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
        for (i = 0; i < ARRAY_SIZE(sta->txq); i++)
                mt76x2_txq_init(dev, sta->txq[i]);
 
+       if (vif->type == NL80211_IFTYPE_AP)
+               set_bit(MT_WCID_FLAG_CHECK_PS, &msta->wcid.flags);
+
        rcu_assign_pointer(dev->wcid[idx], &msta->wcid);
 
 out:
@@ -311,23 +314,14 @@ mt76x2_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
        return 0;
 }
 
-static void
-mt76x2_sta_notify(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
-                 enum sta_notify_cmd cmd, struct ieee80211_sta *sta)
+void
+mt76x2_sta_ps(struct mt76_dev *mdev, struct ieee80211_sta *sta, bool ps)
 {
        struct mt76x2_sta *msta = (struct mt76x2_sta *) sta->drv_priv;
-       struct mt76x2_dev *dev = hw->priv;
+       struct mt76x2_dev *dev = container_of(mdev, struct mt76x2_dev, mt76);
        int idx = msta->wcid.idx;
 
-       switch (cmd) {
-       case STA_NOTIFY_SLEEP:
-               mt76x2_mac_wcid_set_drop(dev, idx, true);
-               mt76_stop_tx_queues(&dev->mt76, sta, true);
-               break;
-       case STA_NOTIFY_AWAKE:
-               mt76x2_mac_wcid_set_drop(dev, idx, false);
-               break;
-       }
+       mt76x2_mac_wcid_set_drop(dev, idx, ps);
 }
 
 static int
@@ -549,6 +543,12 @@ static void mt76x2_set_coverage_class(struct ieee80211_hw *hw,
        mutex_unlock(&dev->mutex);
 }
 
+static int
+mt76x2_set_tim(struct ieee80211_hw *hw, struct ieee80211_sta *sta, bool set)
+{
+       return 0;
+}
+
 const struct ieee80211_ops mt76x2_ops = {
        .tx = mt76x2_tx,
        .start = mt76x2_start,
@@ -560,7 +560,6 @@ const struct ieee80211_ops mt76x2_ops = {
        .bss_info_changed = mt76x2_bss_info_changed,
        .sta_add = mt76x2_sta_add,
        .sta_remove = mt76x2_sta_remove,
-       .sta_notify = mt76x2_sta_notify,
        .set_key = mt76x2_set_key,
        .conf_tx = mt76x2_conf_tx,
        .sw_scan_start = mt76x2_sw_scan,
@@ -573,5 +572,6 @@ const struct ieee80211_ops mt76x2_ops = {
        .release_buffered_frames = mt76_release_buffered_frames,
        .set_coverage_class = mt76x2_set_coverage_class,
        .get_survey = mt76_get_survey,
+       .set_tim = mt76x2_set_tim,
 };
 
index f20e77b4bb65fda713fa5445e6963af977c92f3a..317c1b3101dad1607bc670e8a3d5f9662754a05a 100644 (file)
@@ -1123,7 +1123,7 @@ static u8 _rtl8821ae_dbi_read(struct rtl_priv *rtlpriv, u16 addr)
        }
        if (0 == tmp) {
                read_addr = REG_DBI_RDATA + addr % 4;
-               ret = rtl_read_word(rtlpriv, read_addr);
+               ret = rtl_read_byte(rtlpriv, read_addr);
        }
        return ret;
 }
@@ -1165,7 +1165,8 @@ static void _rtl8821ae_enable_aspm_back_door(struct ieee80211_hw *hw)
        }
 
        tmp = _rtl8821ae_dbi_read(rtlpriv, 0x70f);
-       _rtl8821ae_dbi_write(rtlpriv, 0x70f, tmp | BIT(7));
+       _rtl8821ae_dbi_write(rtlpriv, 0x70f, tmp | BIT(7) |
+                            ASPM_L1_LATENCY << 3);
 
        tmp = _rtl8821ae_dbi_read(rtlpriv, 0x719);
        _rtl8821ae_dbi_write(rtlpriv, 0x719, tmp | BIT(3) | BIT(4));
index a7aacbc3984eca1b8bd548b59c11f1d66ce07ba5..46dcb7fef19541b73e67db2172d6c96d90da4365 100644 (file)
@@ -99,6 +99,7 @@
 #define RTL_USB_MAX_RX_COUNT                   100
 #define QBSS_LOAD_SIZE                         5
 #define MAX_WMMELE_LENGTH                      64
+#define ASPM_L1_LATENCY                                7
 
 #define TOTAL_CAM_ENTRY                                32
 
index ee18428a051f2e8dccfec8eb3e70e900cc5a21db..b3f5cae98ea620cb1726a41fef19979d4811ee0a 100644 (file)
@@ -31,7 +31,7 @@ config SSB_BLOCKIO
 
 config SSB_PCIHOST_POSSIBLE
        bool
-       depends on SSB && (PCI = y || PCI = SSB) && PCI_DRIVERS_LEGACY
+       depends on SSB && (PCI = y || PCI = SSB) && (PCI_DRIVERS_LEGACY || !MIPS)
        default y
 
 config SSB_PCIHOST
index eb13e84e1fef3add8cddf88293d860e364a90dc8..a6b30667a33147ed6f6cc9c648e013cfc3126189 100644 (file)
 #define PCI_VENDOR_ID_DYNALINK         0x0675
 #define PCI_DEVICE_ID_DYNALINK_IS64PH  0x1702
 
+#define PCI_VENDOR_ID_UBIQUITI         0x0777
+
 #define PCI_VENDOR_ID_BERKOM                   0x0871
 #define PCI_DEVICE_ID_BERKOM_A1T               0xffa1
 #define PCI_DEVICE_ID_BERKOM_T_CONCEPT         0xffa2