]> Git Repo - linux.git/commitdiff
Merge tag 'wireless-drivers-next-for-davem-2017-01-02' of git://git.kernel.org/pub...
authorDavid S. Miller <[email protected]>
Mon, 2 Jan 2017 20:23:34 +0000 (15:23 -0500)
committerDavid S. Miller <[email protected]>
Mon, 2 Jan 2017 20:23:34 +0000 (15:23 -0500)
Kalle Valo says:

====================
wireless-drivers-next patches for 4.11

The most notable change here is the inclusion of airtime fairness
scheduling to ath9k. It prevents slow clients from hogging all the
airtime and unfairly slowing down faster clients.

Otherwise smaller changes and cleanup.

Major changes:

ath9k

* cleanup eeprom endian handling
* add airtime fairness scheduling

ath10k

* fix issues for new QCA9377 firmware version
* support dev_coredump() for firmware crash dump
* enable channel 169 on 5 GHz band
====================

Signed-off-by: David S. Miller <[email protected]>
1  2 
drivers/net/wireless/ath/ath10k/pci.c
drivers/net/wireless/ath/ath9k/xmit.c
drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
drivers/net/wireless/realtek/rtlwifi/core.c
drivers/net/wireless/realtek/rtlwifi/rtl8723ae/fw.c

index b541a1c74488531fcd39a7b8103acba95c3557f7,85367006a80a057b91b25e35d4f2e75e8f55a237..93b9790cfe8dc1e4c7c619d56ee3a88d3a994609
@@@ -1973,7 -1973,7 +1973,7 @@@ static int ath10k_pci_get_num_banks(str
                }
                break;
        case QCA9377_1_0_DEVICE_ID:
-               return 2;
+               return 4;
        }
  
        ath10k_warn(ar, "unknown number of banks, assuming 1\n");
@@@ -2091,7 -2091,7 +2091,7 @@@ int ath10k_pci_init_config(struct ath10
  
        ret = ath10k_pci_diag_read32(ar, ealloc_targ_addr, &ealloc_value);
        if (ret != 0) {
 -              ath10k_err(ar, "Faile to get early alloc val: %d\n", ret);
 +              ath10k_err(ar, "Failed to get early alloc val: %d\n", ret);
                return ret;
        }
  
@@@ -3132,7 -3132,7 +3132,7 @@@ int ath10k_pci_setup_resource(struct at
        setup_timer(&ar_pci->rx_post_retry, ath10k_pci_rx_replenish_retry,
                    (unsigned long)ar);
  
-       if (QCA_REV_6174(ar))
+       if (QCA_REV_6174(ar) || QCA_REV_9377(ar))
                ath10k_pci_override_ce_config(ar);
  
        ret = ath10k_pci_alloc_pipes(ar);
index 4e2f3ac266c3750d069a2176b97dd1726b310f57,b727f34796af4f8f2650416ded136559979926d0..c35a192861ab8ff9a21abafd42e972206c0a0233
@@@ -97,18 -97,6 +97,6 @@@ static void ath_tx_status(struct ieee80
        dev_kfree_skb(skb);
  }
  
- void ath_txq_lock(struct ath_softc *sc, struct ath_txq *txq)
-       __acquires(&txq->axq_lock)
- {
-       spin_lock_bh(&txq->axq_lock);
- }
- void ath_txq_unlock(struct ath_softc *sc, struct ath_txq *txq)
-       __releases(&txq->axq_lock)
- {
-       spin_unlock_bh(&txq->axq_lock);
- }
  void ath_txq_unlock_complete(struct ath_softc *sc, struct ath_txq *txq)
        __releases(&txq->axq_lock)
  {
                ath_tx_status(hw, skb);
  }
  
- static void ath_tx_queue_tid(struct ath_softc *sc, struct ath_txq *txq,
-                            struct ath_atx_tid *tid)
+ void __ath_tx_queue_tid(struct ath_softc *sc, struct ath_atx_tid *tid)
  {
-       struct list_head *list;
        struct ath_vif *avp = (struct ath_vif *) tid->an->vif->drv_priv;
        struct ath_chanctx *ctx = avp->chanctx;
+       struct ath_acq *acq;
+       struct list_head *tid_list;
+       u8 acno = TID_TO_WME_AC(tid->tidno);
  
-       if (!ctx)
+       if (!ctx || !list_empty(&tid->list))
                return;
  
-       list = &ctx->acq[TID_TO_WME_AC(tid->tidno)];
-       if (list_empty(&tid->list))
-               list_add_tail(&tid->list, list);
+       acq = &ctx->acq[acno];
+       if ((sc->airtime_flags & AIRTIME_USE_NEW_QUEUES) &&
+           tid->an->airtime_deficit[acno] > 0)
+               tid_list = &acq->acq_new;
+       else
+               tid_list = &acq->acq_old;
+       list_add_tail(&tid->list, tid_list);
  }
  
+ void ath_tx_queue_tid(struct ath_softc *sc, struct ath_atx_tid *tid)
+ {
+       struct ath_vif *avp = (struct ath_vif *) tid->an->vif->drv_priv;
+       struct ath_chanctx *ctx = avp->chanctx;
+       struct ath_acq *acq;
+       if (!ctx || !list_empty(&tid->list))
+               return;
+       acq = &ctx->acq[TID_TO_WME_AC(tid->tidno)];
+       spin_lock_bh(&acq->lock);
+       __ath_tx_queue_tid(sc, tid);
+       spin_unlock_bh(&acq->lock);
+ }
  void ath9k_wake_tx_queue(struct ieee80211_hw *hw, struct ieee80211_txq *queue)
  {
        struct ath_softc *sc = hw->priv;
        ath_txq_lock(sc, txq);
  
        tid->has_queued = true;
-       ath_tx_queue_tid(sc, txq, tid);
+       ath_tx_queue_tid(sc, tid);
        ath_txq_schedule(sc, txq);
  
        ath_txq_unlock(sc, txq);
@@@ -660,7 -671,7 +671,7 @@@ static void ath_tx_complete_aggr(struc
  
                skb_queue_splice_tail(&bf_pending, &tid->retry_q);
                if (!an->sleeping) {
-                       ath_tx_queue_tid(sc, txq, tid);
+                       ath_tx_queue_tid(sc, tid);
  
                        if (ts->ts_status & (ATH9K_TXERR_FILT | ATH9K_TXERR_XRETRY))
                                tid->clear_ps_filter = true;
@@@ -688,6 -699,53 +699,53 @@@ static bool bf_is_ampdu_not_probing(str
      return bf_isampdu(bf) && !(info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE);
  }
  
+ static void ath_tx_count_airtime(struct ath_softc *sc, struct ath_txq *txq,
+                                struct ath_buf *bf, struct ath_tx_status *ts)
+ {
+       struct ath_node *an;
+       struct ath_acq *acq = &sc->cur_chan->acq[txq->mac80211_qnum];
+       struct sk_buff *skb;
+       struct ieee80211_hdr *hdr;
+       struct ieee80211_hw *hw = sc->hw;
+       struct ieee80211_tx_rate rates[4];
+       struct ieee80211_sta *sta;
+       int i;
+       u32 airtime = 0;
+       skb = bf->bf_mpdu;
+       if(!skb)
+               return;
+       hdr = (struct ieee80211_hdr *)skb->data;
+       memcpy(rates, bf->rates, sizeof(rates));
+       rcu_read_lock();
+       sta = ieee80211_find_sta_by_ifaddr(hw, hdr->addr1, hdr->addr2);
+       if(!sta)
+               goto exit;
+       an = (struct ath_node *) sta->drv_priv;
+       airtime += ts->duration * (ts->ts_longretry + 1);
+       for(i=0; i < ts->ts_rateindex; i++)
+               airtime += ath9k_hw_get_duration(sc->sc_ah, bf->bf_desc, i) * rates[i].count;
+       if (!!(sc->airtime_flags & AIRTIME_USE_TX)) {
+               spin_lock_bh(&acq->lock);
+               an->airtime_deficit[txq->mac80211_qnum] -= airtime;
+               if (an->airtime_deficit[txq->mac80211_qnum] <= 0)
+                       __ath_tx_queue_tid(sc, ath_get_skb_tid(sc, an, skb));
+               spin_unlock_bh(&acq->lock);
+       }
+       ath_debug_airtime(sc, an, 0, airtime);
+ exit:
+       rcu_read_unlock();
+ }
  static void ath_tx_process_buffer(struct ath_softc *sc, struct ath_txq *txq,
                                  struct ath_tx_status *ts, struct ath_buf *bf,
                                  struct list_head *bf_head)
  
        ts->duration = ath9k_hw_get_duration(sc->sc_ah, bf->bf_desc,
                                             ts->ts_rateindex);
+       ath_tx_count_airtime(sc, txq, bf, ts);
  
        hdr = (struct ieee80211_hdr *) bf->bf_mpdu->data;
        sta = ieee80211_find_sta_by_ifaddr(hw, hdr->addr1, hdr->addr2);
@@@ -1068,8 -1127,8 +1127,8 @@@ finish
   * width  - 0 for 20 MHz, 1 for 40 MHz
   * half_gi - to use 4us v/s 3.6 us for symbol time
   */
static u32 ath_pkt_duration(struct ath_softc *sc, u8 rix, int pktlen,
-                           int width, int half_gi, bool shortPreamble)
+ u32 ath_pkt_duration(struct ath_softc *sc, u8 rix, int pktlen,
+                    int width, int half_gi, bool shortPreamble)
  {
        u32 nbits, nsymbits, duration, nsymbols;
        int streams;
@@@ -1151,8 -1210,9 +1210,9 @@@ static u8 ath_get_rate_txpower(struct a
                if (is_40) {
                        u8 power_ht40delta;
                        struct ar5416_eeprom_def *eep = &ah->eeprom.def;
+                       u16 eeprom_rev = ah->eep_ops->get_eeprom_rev(ah);
  
-                       if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_2) {
+                       if (eeprom_rev >= AR5416_EEP_MINOR_VER_2) {
                                bool is_2ghz;
                                struct modal_eep_header *pmodal;
  
@@@ -1467,7 -1527,7 +1527,7 @@@ ath_tx_form_burst(struct ath_softc *sc
  }
  
  static bool ath_tx_sched_aggr(struct ath_softc *sc, struct ath_txq *txq,
-                             struct ath_atx_tid *tid, bool *stop)
+                             struct ath_atx_tid *tid)
  {
        struct ath_buf *bf;
        struct ieee80211_tx_info *tx_info;
        if ((aggr && txq->axq_ampdu_depth >= ATH_AGGR_MIN_QDEPTH) ||
            (!aggr && txq->axq_depth >= ATH_NON_AGGR_MIN_QDEPTH)) {
                __skb_queue_tail(&tid->retry_q, bf->bf_mpdu);
-               *stop = true;
                return false;
        }
  
@@@ -1613,7 -1672,7 +1672,7 @@@ void ath_tx_aggr_wakeup(struct ath_soft
                ath_txq_lock(sc, txq);
                tid->clear_ps_filter = true;
                if (ath_tid_has_buffered(tid)) {
-                       ath_tx_queue_tid(sc, txq, tid);
+                       ath_tx_queue_tid(sc, tid);
                        ath_txq_schedule(sc, txq);
                }
                ath_txq_unlock_complete(sc, txq);
@@@ -1912,9 -1971,10 +1971,10 @@@ void ath_tx_cleanupq(struct ath_softc *
  void ath_txq_schedule(struct ath_softc *sc, struct ath_txq *txq)
  {
        struct ath_common *common = ath9k_hw_common(sc->sc_ah);
-       struct ath_atx_tid *tid, *last_tid;
+       struct ath_atx_tid *tid;
        struct list_head *tid_list;
-       bool sent = false;
+       struct ath_acq *acq;
+       bool active = AIRTIME_ACTIVE(sc->airtime_flags);
  
        if (txq->mac80211_qnum < 0)
                return;
                return;
  
        spin_lock_bh(&sc->chan_lock);
-       tid_list = &sc->cur_chan->acq[txq->mac80211_qnum];
-       if (list_empty(tid_list)) {
-               spin_unlock_bh(&sc->chan_lock);
-               return;
-       }
        rcu_read_lock();
+       acq = &sc->cur_chan->acq[txq->mac80211_qnum];
  
-       last_tid = list_entry(tid_list->prev, struct ath_atx_tid, list);
-       while (!list_empty(tid_list)) {
-               bool stop = false;
-               if (sc->cur_chan->stopped)
-                       break;
-               tid = list_first_entry(tid_list, struct ath_atx_tid, list);
-               list_del_init(&tid->list);
-               if (ath_tx_sched_aggr(sc, txq, tid, &stop))
-                       sent = true;
-               /*
-                * add tid to round-robin queue if more frames
-                * are pending for the tid
-                */
-               if (ath_tid_has_buffered(tid))
-                       ath_tx_queue_tid(sc, txq, tid);
+       if (sc->cur_chan->stopped)
+               goto out;
  
-               if (stop)
-                       break;
+ begin:
+       tid_list = &acq->acq_new;
+       if (list_empty(tid_list)) {
+               tid_list = &acq->acq_old;
+               if (list_empty(tid_list))
+                       goto out;
+       }
+       tid = list_first_entry(tid_list, struct ath_atx_tid, list);
+       if (active && tid->an->airtime_deficit[txq->mac80211_qnum] <= 0) {
+               spin_lock_bh(&acq->lock);
+               tid->an->airtime_deficit[txq->mac80211_qnum] += ATH_AIRTIME_QUANTUM;
+               list_move_tail(&tid->list, &acq->acq_old);
+               spin_unlock_bh(&acq->lock);
+               goto begin;
+       }
+       if (!ath_tid_has_buffered(tid)) {
+               spin_lock_bh(&acq->lock);
+               if ((tid_list == &acq->acq_new) && !list_empty(&acq->acq_old))
+                       list_move_tail(&tid->list, &acq->acq_old);
+               else {
+                       list_del_init(&tid->list);
+               }
+               spin_unlock_bh(&acq->lock);
+               goto begin;
+       }
  
-               if (tid == last_tid) {
-                       if (!sent)
-                               break;
  
-                       sent = false;
-                       last_tid = list_entry(tid_list->prev,
-                                             struct ath_atx_tid, list);
+       /*
+        * If we succeed in scheduling something, immediately restart to make
+        * sure we keep the HW busy.
+        */
+       if(ath_tx_sched_aggr(sc, txq, tid)) {
+               if (!active) {
+                       spin_lock_bh(&acq->lock);
+                       list_move_tail(&tid->list, &acq->acq_old);
+                       spin_unlock_bh(&acq->lock);
                }
+               goto begin;
        }
  
+ out:
        rcu_read_unlock();
        spin_unlock_bh(&sc->chan_lock);
  }
@@@ -2713,7 -2780,7 +2780,7 @@@ void ath_tx_edma_tasklet(struct ath_sof
                fifo_list = &txq->txq_fifo[txq->txq_tailidx];
                if (list_empty(fifo_list)) {
                        ath_txq_unlock(sc, txq);
 -                      return;
 +                      break;
                }
  
                bf = list_first_entry(fifo_list, struct ath_buf, list);
@@@ -2818,6 -2885,9 +2885,9 @@@ void ath_tx_node_init(struct ath_softc 
        struct ath_atx_tid *tid;
        int tidno, acno;
  
+       for (acno = 0; acno < IEEE80211_NUM_ACS; acno++)
+               an->airtime_deficit[acno] = ATH_AIRTIME_QUANTUM;
        for (tidno = 0; tidno < IEEE80211_NUM_TIDS; tidno++) {
                tid = ath_node_to_tid(an, tidno);
                tid->an        = an;
index 7ffc4aba5bab0683fe993d1d5eef9e8e3d8389d0,13ca3eb2462b18f7d85e6a6534cd9382928fc1f1..15eaf722b54b79581b893fca09e03e361fa35d10
@@@ -3971,7 -3971,7 +3971,7 @@@ brcmf_configure_wpaie(struct brcmf_if *
                        pval |= AES_ENABLED;
                        break;
                default:
-                       brcmf_err("Ivalid unicast security info\n");
+                       brcmf_err("Invalid unicast security info\n");
                }
                offset++;
        }
                        wpa_auth |= WPA2_AUTH_1X_SHA256;
                        break;
                default:
-                       brcmf_err("Ivalid key mgmt info\n");
+                       brcmf_err("Invalid key mgmt info\n");
                }
                offset++;
        }
@@@ -6868,7 -6868,7 +6868,7 @@@ struct brcmf_cfg80211_info *brcmf_cfg80
  
        err = brcmf_p2p_attach(cfg, p2pdev_forced);
        if (err) {
 -              brcmf_err("P2P initilisation failed (%d)\n", err);
 +              brcmf_err("P2P initialisation failed (%d)\n", err);
                goto wiphy_unreg_out;
        }
        err = brcmf_btcoex_attach(cfg);
        err = brcmf_fweh_activate_events(ifp);
        if (err) {
                brcmf_err("FWEH activation failed (%d)\n", err);
 -              goto wiphy_unreg_out;
 +              goto detach;
        }
  
        /* Fill in some of the advertised nl80211 supported features */
  
        return cfg;
  
 +detach:
 +      brcmf_btcoex_detach(cfg);
 +      brcmf_p2p_detach(&cfg->p2p);
  wiphy_unreg_out:
        wiphy_unregister(cfg->wiphy);
  priv_out:
index ded1493fee9c975742ede341b991b4446a48e3d7,9ec72d1d089a1ef1963faa16c6496f5ed6c8a94c..179a699cc6acbe417149e7ae785798729e11a1ec
@@@ -117,8 -117,7 +117,7 @@@ static void rtl_fw_do_work(const struc
        }
  found_alt:
        if (firmware->size > rtlpriv->max_fw_size) {
-               RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-                        "Firmware is too big!\n");
+               pr_err("Firmware is too big!\n");
                release_firmware(firmware);
                return;
        }
@@@ -303,8 -302,8 +302,8 @@@ static int rtl_op_add_interface(struct 
                                (u8 *)(&mac->basic_rates));
                break;
        default:
-               RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-                        "operation mode %d is not support!\n", vif->type);
+               pr_err("operation mode %d is not supported!\n",
+                      vif->type);
                err = -EOPNOTSUPP;
                goto out;
        }
@@@ -764,9 -763,8 +763,8 @@@ static int rtl_op_config(struct ieee802
                        default:
                                        mac->bw_40 = false;
                                        mac->bw_80 = false;
-                                       RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-                                                "switch case %#x not processed\n",
-                                                channel_type);
+                                       pr_err("switch case %#x not processed\n",
+                                              channel_type);
                                        break;
                        }
                }
@@@ -1399,8 -1397,7 +1397,7 @@@ static int rtl_op_ampdu_action(struct i
                         "IEEE80211_AMPDU_RX_STOP:TID:%d\n", tid);
                return rtl_rx_agg_stop(hw, sta, tid);
        default:
-               RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-                        "IEEE80211_AMPDU_ERR!!!!:\n");
+               pr_err("IEEE80211_AMPDU_ERR!!!!:\n");
                return -EOPNOTSUPP;
        }
        return 0;
@@@ -1532,12 -1529,11 +1529,11 @@@ static int rtl_op_set_key(struct ieee80
                key_type = AESCMAC_ENCRYPTION;
                RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, "alg:CMAC\n");
                RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
-                        "HW don't support CMAC encrypiton, use software CMAC encrypiton\n");
+                        "HW don't support CMAC encryption, use software CMAC encryption\n");
                err = -EOPNOTSUPP;
                goto out_unlock;
        default:
-               RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-                        "alg_err:%x!!!!:\n", key->cipher);
+               pr_err("alg_err:%x!!!!:\n", key->cipher);
                goto out_unlock;
        }
        if (key_type == WEP40_ENCRYPTION ||
                        RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
                                 "set pairwise key\n");
                        if (!sta) {
-                               RT_ASSERT(false,
-                                         "pairwise key without mac_addr\n");
+                               WARN_ONCE(true,
+                                         "rtlwifi: pairwise key without mac_addr\n");
  
                                err = -EOPNOTSUPP;
                                goto out_unlock;
                rtl_cam_delete_one_entry(hw, mac_addr, key_idx);
                break;
        default:
-               RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-                        "cmd_err:%x!!!!:\n", cmd);
+               pr_err("cmd_err:%x!!!!:\n", cmd);
        }
  out_unlock:
        mutex_unlock(&rtlpriv->locks.conf_mutex);
@@@ -1804,8 -1799,8 +1799,8 @@@ bool rtl_hal_pwrseqcmdparsing(struct rt
                                         "rtl_hal_pwrseqcmdparsing(): PWR_CMD_END\n");
                                return true;
                        default:
-                               RT_ASSERT(false,
-                                         "rtl_hal_pwrseqcmdparsing(): Unknown CMD!!\n");
+                               WARN_ONCE(true,
+                                         "rtlwifi: rtl_hal_pwrseqcmdparsing(): Unknown CMD!!\n");
                                break;
                        }
                }
@@@ -1829,8 -1824,7 +1824,8 @@@ bool rtl_cmd_send_packet(struct ieee802
  
        spin_lock_irqsave(&rtlpriv->locks.irq_th_lock, flags);
        pskb = __skb_dequeue(&ring->queue);
 -      dev_kfree_skb_irq(pskb);
 +      if (pskb)
 +              dev_kfree_skb_irq(pskb);
  
        /*this is wrong, fill_tx_cmddesc needs update*/
        pdesc = &ring->desc[0];
index e5505387260b49269eb9b3b605ca5b61eac3ccaf,bef3d94228c84611e9a57c12220ac7cf188775a4..a954a87b0ed9bf9f14f937a6e4b8d98e3836306b
@@@ -99,8 -99,7 +99,7 @@@ static void _rtl8723e_fill_h2c_command(
        while (!bwrite_sucess) {
                wait_writeh2c_limmit--;
                if (wait_writeh2c_limmit == 0) {
-                       RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-                                "Write H2C fail because no trigger for FW INT!\n");
+                       pr_err("Write H2C fail because no trigger for FW INT!\n");
                        break;
                }
  
                        box_extreg = REG_HMEBOX_EXT_3;
                        break;
                default:
-                       RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-                                "switch case %#x not processed\n", boxnum);
+                       pr_err("switch case %#x not processed\n",
+                              boxnum);
                        break;
                }
  
                        wait_h2c_limmit--;
                        if (wait_h2c_limmit == 0) {
                                RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
 -                                       "Wating too long for FW read clear HMEBox(%d)!\n",
 +                                       "Waiting too long for FW read clear HMEBox(%d)!\n",
                                         boxnum);
                                break;
                        }
                        }
                        break;
                default:
-                       RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-                                "switch case %#x not processed\n", cmd_len);
+                       pr_err("switch case %#x not processed\n",
+                              cmd_len);
                        break;
                }
  
@@@ -259,8 -258,8 +258,8 @@@ void rtl8723e_fill_h2c_cmd(struct ieee8
        u32 tmp_cmdbuf[2];
  
        if (!rtlhal->fw_ready) {
-               RT_ASSERT(false,
-                         "return H2C cmd because of Fw download fail!!!\n");
+               WARN_ONCE(true,
+                         "rtl8723ae: error H2C cmd because of Fw download fail!!!\n");
                return;
        }
        memset(tmp_cmdbuf, 0, 8);
This page took 0.112688 seconds and 4 git commands to generate.