]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
iwlwifi: add support for IEEE802.11ax
authorLuca Coelho <luciano.coelho@intel.com>
Sun, 24 Jun 2018 08:59:54 +0000 (11:59 +0300)
committerLuca Coelho <luciano.coelho@intel.com>
Thu, 26 Jul 2018 10:16:11 +0000 (13:16 +0300)
Add support for the HE in the iwlwifi driver conforming with
P802.11ax_D2.0.

Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
12 files changed:
drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c
drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c
drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
drivers/net/wireless/intel/iwlwifi/mvm/ops.c
drivers/net/wireless/intel/iwlwifi/mvm/rs-fw.c
drivers/net/wireless/intel/iwlwifi/mvm/rs.c
drivers/net/wireless/intel/iwlwifi/mvm/rs.h
drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c
drivers/net/wireless/intel/iwlwifi/mvm/sta.c
drivers/net/wireless/intel/iwlwifi/mvm/sta.h
drivers/net/wireless/intel/iwlwifi/pcie/trans.c

index b815ba38dbdb177e6a2fe2e235c2a4f5cac8d725..941604c24fa12e1e10ddcb8ab22da5600368f828 100644 (file)
@@ -463,6 +463,101 @@ static void iwl_init_vht_hw_capab(const struct iwl_cfg *cfg,
        vht_cap->vht_mcs.tx_mcs_map = vht_cap->vht_mcs.rx_mcs_map;
 }
 
+static struct ieee80211_sband_iftype_data iwl_he_capa = {
+       .types_mask = BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_AP),
+       .he_cap = {
+               .has_he = true,
+               .he_cap_elem = {
+                       .mac_cap_info[0] =
+                               IEEE80211_HE_MAC_CAP0_HTC_HE,
+                       .mac_cap_info[1] =
+                               IEEE80211_HE_MAC_CAP1_TF_MAC_PAD_DUR_16US |
+                               IEEE80211_HE_MAC_CAP1_MULTI_TID_AGG_QOS_8,
+                       .mac_cap_info[2] =
+                               IEEE80211_HE_MAC_CAP2_32BIT_BA_BITMAP |
+                               IEEE80211_HE_MAC_CAP2_ACK_EN,
+                       .mac_cap_info[3] =
+                               IEEE80211_HE_MAC_CAP3_GRP_ADDR_MULTI_STA_BA_DL_MU |
+                               IEEE80211_HE_MAC_CAP3_MAX_A_AMPDU_LEN_EXP_VHT_2,
+                       .mac_cap_info[4] = IEEE80211_HE_MAC_CAP4_AMDSU_IN_AMPDU,
+                       .phy_cap_info[0] =
+                               IEEE80211_HE_PHY_CAP0_DUAL_BAND |
+                               IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_IN_2G |
+                               IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_80MHZ_IN_5G |
+                               IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_160MHZ_IN_5G,
+                       .phy_cap_info[1] =
+                               IEEE80211_HE_PHY_CAP1_DEVICE_CLASS_A |
+                               IEEE80211_HE_PHY_CAP1_LDPC_CODING_IN_PAYLOAD |
+                               IEEE80211_HE_PHY_CAP1_MIDAMBLE_RX_MAX_NSTS,
+                       .phy_cap_info[2] =
+                               IEEE80211_HE_PHY_CAP2_NDP_4x_LTF_AND_3_2US |
+                               IEEE80211_HE_PHY_CAP2_STBC_TX_UNDER_80MHZ |
+                               IEEE80211_HE_PHY_CAP2_STBC_RX_UNDER_80MHZ,
+                       .phy_cap_info[3] =
+                               IEEE80211_HE_PHY_CAP3_DCM_MAX_CONST_TX_BPSK |
+                               IEEE80211_HE_PHY_CAP3_DCM_MAX_TX_NSS_1 |
+                               IEEE80211_HE_PHY_CAP3_DCM_MAX_CONST_RX_BPSK |
+                               IEEE80211_HE_PHY_CAP3_DCM_MAX_RX_NSS_1,
+                       .phy_cap_info[4] =
+                               IEEE80211_HE_PHY_CAP4_SU_BEAMFORMEE |
+                               IEEE80211_HE_PHY_CAP4_BEAMFORMEE_MAX_STS_ABOVE_80MHZ_8 |
+                               IEEE80211_HE_PHY_CAP4_BEAMFORMEE_MAX_STS_UNDER_80MHZ_8,
+                       .phy_cap_info[5] =
+                               IEEE80211_HE_PHY_CAP5_BEAMFORMEE_NUM_SND_DIM_UNDER_80MHZ_2 |
+                               IEEE80211_HE_PHY_CAP5_BEAMFORMEE_NUM_SND_DIM_ABOVE_80MHZ_2,
+                       .phy_cap_info[6] =
+                               IEEE80211_HE_PHY_CAP6_PPE_THRESHOLD_PRESENT,
+                       .phy_cap_info[7] =
+                               IEEE80211_HE_PHY_CAP7_POWER_BOOST_FACTOR_AR |
+                               IEEE80211_HE_PHY_CAP7_HE_SU_MU_PPDU_4XLTF_AND_08_US_GI |
+                               IEEE80211_HE_PHY_CAP7_MAX_NC_7,
+                       .phy_cap_info[8] =
+                               IEEE80211_HE_PHY_CAP8_HE_ER_SU_PPDU_4XLTF_AND_08_US_GI |
+                               IEEE80211_HE_PHY_CAP8_20MHZ_IN_40MHZ_HE_PPDU_IN_2G |
+                               IEEE80211_HE_PHY_CAP8_20MHZ_IN_160MHZ_HE_PPDU |
+                               IEEE80211_HE_PHY_CAP8_80MHZ_IN_160MHZ_HE_PPDU,
+               },
+               /*
+                * Set default Tx/Rx HE MCS NSS Support field. Indicate support
+                * for up to 2 spatial streams and all MCS, without any special
+                * cases
+                */
+               .he_mcs_nss_supp = {
+                       .rx_mcs_80 = cpu_to_le16(0xfffa),
+                       .tx_mcs_80 = cpu_to_le16(0xfffa),
+                       .rx_mcs_160 = cpu_to_le16(0xfffa),
+                       .tx_mcs_160 = cpu_to_le16(0xfffa),
+                       .rx_mcs_80p80 = cpu_to_le16(0xffff),
+                       .tx_mcs_80p80 = cpu_to_le16(0xffff),
+               },
+               /*
+                * Set default PPE thresholds, with PPET16 set to 0, PPET8 set
+                * to 7
+                */
+               .ppe_thres = {0x61, 0x1c, 0xc7, 0x71},
+       },
+};
+
+static void iwl_init_he_hw_capab(struct ieee80211_supported_band *sband,
+                                u8 tx_chains, u8 rx_chains)
+{
+       if (sband->band == NL80211_BAND_2GHZ ||
+           sband->band == NL80211_BAND_5GHZ)
+               sband->iftype_data = &iwl_he_capa;
+       else
+               return;
+
+       sband->n_iftype_data = 1;
+
+       /* If not 2x2, we need to indicate 1x1 in the Midamble RX Max NSTS */
+       if ((tx_chains & rx_chains) != ANT_AB) {
+               iwl_he_capa.he_cap.he_cap_elem.phy_cap_info[1] &=
+                       ~IEEE80211_HE_PHY_CAP1_MIDAMBLE_RX_MAX_NSTS;
+               iwl_he_capa.he_cap.he_cap_elem.phy_cap_info[2] &=
+                       ~IEEE80211_HE_PHY_CAP2_MIDAMBLE_RX_MAX_NSTS;
+       }
+}
+
 static void iwl_init_sbands(struct device *dev, const struct iwl_cfg *cfg,
                            struct iwl_nvm_data *data,
                            const __le16 *nvm_ch_flags, u8 tx_chains,
@@ -483,6 +578,9 @@ static void iwl_init_sbands(struct device *dev, const struct iwl_cfg *cfg,
        iwl_init_ht_hw_capab(cfg, data, &sband->ht_cap, NL80211_BAND_2GHZ,
                             tx_chains, rx_chains);
 
+       if (data->sku_cap_11ax_enable)
+               iwl_init_he_hw_capab(sband, tx_chains, rx_chains);
+
        sband = &data->bands[NL80211_BAND_5GHZ];
        sband->band = NL80211_BAND_5GHZ;
        sband->bitrates = &iwl_cfg80211_rates[RATES_52_OFFS];
@@ -495,6 +593,9 @@ static void iwl_init_sbands(struct device *dev, const struct iwl_cfg *cfg,
                iwl_init_vht_hw_capab(cfg, data, &sband->vht_cap,
                                      tx_chains, rx_chains);
 
+       if (data->sku_cap_11ax_enable)
+               iwl_init_he_hw_capab(sband, tx_chains, rx_chains);
+
        if (n_channels != n_used)
                IWL_ERR_DEV(dev, "NVM: used only %d of %d channels\n",
                            n_used, n_channels);
@@ -1293,6 +1394,8 @@ struct iwl_nvm_data *iwl_get_nvm(struct iwl_trans *trans,
                !!(mac_flags & NVM_MAC_SKU_FLAGS_802_11AC_ENABLED);
        nvm->sku_cap_11n_enable =
                !!(mac_flags & NVM_MAC_SKU_FLAGS_802_11N_ENABLED);
+       nvm->sku_cap_11ax_enable =
+               !!(mac_flags & NVM_MAC_SKU_FLAGS_802_11AX_ENABLED);
        nvm->sku_cap_band_24ghz_enable =
                !!(mac_flags & NVM_MAC_SKU_FLAGS_BAND_2_4_ENABLED);
        nvm->sku_cap_band_52ghz_enable =
index 8ba16fc24e3af0bd6bc07b6de7195e375d3f0cb1..362e9b77974d6249840ee03bfcd60363f55cbcee 100644 (file)
@@ -780,6 +780,9 @@ static int iwl_mvm_mac_ctxt_cmd_sta(struct iwl_mvm *mvm,
        if (vif->probe_req_reg && vif->bss_conf.assoc && vif->p2p)
                cmd.filter_flags |= cpu_to_le32(MAC_FILTER_IN_PROBE_REQUEST);
 
+       if (vif->bss_conf.assoc && vif->bss_conf.he_support)
+               cmd.filter_flags |= cpu_to_le32(MAC_FILTER_IN_11AX);
+
        return iwl_mvm_mac_ctxt_send_cmd(mvm, &cmd);
 }
 
index 26021bc55e981cf727c5682b36f8e3057c05d0a8..5ad98359789bd53c25c453096fb50075f492d9fa 100644 (file)
@@ -36,6 +36,7 @@
  * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
  * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
  * Copyright(c) 2016 - 2017 Intel Deutschland GmbH
+ * Copyright(c) 2018        Intel Corporation
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -914,7 +915,7 @@ static int iwl_mvm_mac_ampdu_action(struct ieee80211_hw *hw,
        enum ieee80211_ampdu_mlme_action action = params->action;
        u16 tid = params->tid;
        u16 *ssn = &params->ssn;
-       u8 buf_size = params->buf_size;
+       u16 buf_size = params->buf_size;
        bool amsdu = params->amsdu;
        u16 timeout = params->timeout;
 
@@ -1897,6 +1898,194 @@ void iwl_mvm_mu_mimo_grp_notif(struct iwl_mvm *mvm,
                        iwl_mvm_mu_mimo_iface_iterator, notif);
 }
 
+static u8 iwl_mvm_he_get_ppe_val(u8 *ppe, u8 ppe_pos_bit)
+{
+       u8 byte_num = ppe_pos_bit / 8;
+       u8 bit_num = ppe_pos_bit % 8;
+       u8 residue_bits;
+       u8 res;
+
+       if (bit_num <= 5)
+               return (ppe[byte_num] >> bit_num) &
+                      (BIT(IEEE80211_PPE_THRES_INFO_PPET_SIZE) - 1);
+
+       /*
+        * If bit_num > 5, we have to combine bits with next byte.
+        * Calculate how many bits we need to take from current byte (called
+        * here "residue_bits"), and add them to bits from next byte.
+        */
+
+       residue_bits = 8 - bit_num;
+
+       res = (ppe[byte_num + 1] &
+              (BIT(IEEE80211_PPE_THRES_INFO_PPET_SIZE - residue_bits) - 1)) <<
+             residue_bits;
+       res += (ppe[byte_num] >> bit_num) & (BIT(residue_bits) - 1);
+
+       return res;
+}
+
+static void iwl_mvm_cfg_he_sta(struct iwl_mvm *mvm,
+                              struct ieee80211_vif *vif, u8 sta_id)
+{
+       struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
+       struct iwl_he_sta_context_cmd sta_ctxt_cmd = {
+               .sta_id = sta_id,
+               .tid_limit = IWL_MAX_TID_COUNT,
+               .bss_color = vif->bss_conf.bss_color,
+               .htc_trig_based_pkt_ext = vif->bss_conf.htc_trig_based_pkt_ext,
+               .frame_time_rts_th =
+                       cpu_to_le16(vif->bss_conf.frame_time_rts_th),
+       };
+       struct ieee80211_sta *sta;
+       u32 flags;
+       int i;
+
+       rcu_read_lock();
+
+       sta = rcu_dereference(mvm->fw_id_to_mac_id[sta_ctxt_cmd.sta_id]);
+       if (IS_ERR(sta)) {
+               rcu_read_unlock();
+               WARN(1, "Can't find STA to configure HE\n");
+               return;
+       }
+
+       if (!sta->he_cap.has_he) {
+               rcu_read_unlock();
+               return;
+       }
+
+       flags = 0;
+
+       /* HTC flags */
+       if (sta->he_cap.he_cap_elem.mac_cap_info[0] &
+           IEEE80211_HE_MAC_CAP0_HTC_HE)
+               sta_ctxt_cmd.htc_flags |= cpu_to_le32(IWL_HE_HTC_SUPPORT);
+       if ((sta->he_cap.he_cap_elem.mac_cap_info[1] &
+             IEEE80211_HE_MAC_CAP1_LINK_ADAPTATION) ||
+           (sta->he_cap.he_cap_elem.mac_cap_info[2] &
+             IEEE80211_HE_MAC_CAP2_LINK_ADAPTATION)) {
+               u8 link_adap =
+                       ((sta->he_cap.he_cap_elem.mac_cap_info[2] &
+                         IEEE80211_HE_MAC_CAP2_LINK_ADAPTATION) << 1) +
+                        (sta->he_cap.he_cap_elem.mac_cap_info[1] &
+                         IEEE80211_HE_MAC_CAP1_LINK_ADAPTATION);
+
+               if (link_adap == 2)
+                       sta_ctxt_cmd.htc_flags |=
+                               cpu_to_le32(IWL_HE_HTC_LINK_ADAP_UNSOLICITED);
+               else if (link_adap == 3)
+                       sta_ctxt_cmd.htc_flags |=
+                               cpu_to_le32(IWL_HE_HTC_LINK_ADAP_BOTH);
+       }
+       if (sta->he_cap.he_cap_elem.mac_cap_info[2] &
+           IEEE80211_HE_MAC_CAP2_UL_MU_RESP_SCHED)
+               sta_ctxt_cmd.htc_flags |=
+                       cpu_to_le32(IWL_HE_HTC_UL_MU_RESP_SCHED);
+       if (sta->he_cap.he_cap_elem.mac_cap_info[2] & IEEE80211_HE_MAC_CAP2_BSR)
+               sta_ctxt_cmd.htc_flags |= cpu_to_le32(IWL_HE_HTC_BSR_SUPP);
+       if (sta->he_cap.he_cap_elem.mac_cap_info[3] &
+           IEEE80211_HE_MAC_CAP3_OMI_CONTROL)
+               sta_ctxt_cmd.htc_flags |= cpu_to_le32(IWL_HE_HTC_OMI_SUPP);
+       if (sta->he_cap.he_cap_elem.mac_cap_info[4] & IEEE80211_HE_MAC_CAP4_BQR)
+               sta_ctxt_cmd.htc_flags |= cpu_to_le32(IWL_HE_HTC_BQR_SUPP);
+
+       /* If PPE Thresholds exist, parse them into a FW-familiar format */
+       if (sta->he_cap.he_cap_elem.phy_cap_info[6] &
+           IEEE80211_HE_PHY_CAP6_PPE_THRESHOLD_PRESENT) {
+               u8 nss = (sta->he_cap.ppe_thres[0] &
+                         IEEE80211_PPE_THRES_NSS_MASK) + 1;
+               u8 ru_index_bitmap =
+                       (sta->he_cap.ppe_thres[0] &
+                        IEEE80211_PPE_THRES_RU_INDEX_BITMASK_MASK) >>
+                       IEEE80211_PPE_THRES_RU_INDEX_BITMASK_POS;
+               u8 *ppe = &sta->he_cap.ppe_thres[0];
+               u8 ppe_pos_bit = 7; /* Starting after PPE header */
+
+               /*
+                * FW currently supports only nss == MAX_HE_SUPP_NSS
+                *
+                * If nss > MAX: we can ignore values we don't support
+                * If nss < MAX: we can set zeros in other streams
+                */
+               if (nss > MAX_HE_SUPP_NSS) {
+                       IWL_INFO(mvm, "Got NSS = %d - trimming to %d\n", nss,
+                                MAX_HE_SUPP_NSS);
+                       nss = MAX_HE_SUPP_NSS;
+               }
+
+               for (i = 0; i < nss; i++) {
+                       u8 ru_index_tmp = ru_index_bitmap << 1;
+                       u8 bw;
+
+                       for (bw = 0; bw < MAX_HE_CHANNEL_BW_INDX; bw++) {
+                               ru_index_tmp >>= 1;
+                               if (!(ru_index_tmp & 1))
+                                       continue;
+
+                               sta_ctxt_cmd.pkt_ext.pkt_ext_qam_th[i][bw][1] =
+                                       iwl_mvm_he_get_ppe_val(ppe,
+                                                              ppe_pos_bit);
+                               ppe_pos_bit +=
+                                       IEEE80211_PPE_THRES_INFO_PPET_SIZE;
+                               sta_ctxt_cmd.pkt_ext.pkt_ext_qam_th[i][bw][0] =
+                                       iwl_mvm_he_get_ppe_val(ppe,
+                                                              ppe_pos_bit);
+                               ppe_pos_bit +=
+                                       IEEE80211_PPE_THRES_INFO_PPET_SIZE;
+                       }
+               }
+
+               flags |= STA_CTXT_HE_PACKET_EXT;
+       }
+       rcu_read_unlock();
+
+       /* Mark MU EDCA as enabled, unless none detected on some AC */
+       flags |= STA_CTXT_HE_MU_EDCA_CW;
+       for (i = 0; i < AC_NUM; i++) {
+               struct ieee80211_he_mu_edca_param_ac_rec *mu_edca =
+                       &mvmvif->queue_params[i].mu_edca_param_rec;
+
+               if (!mvmvif->queue_params[i].mu_edca) {
+                       flags &= ~STA_CTXT_HE_MU_EDCA_CW;
+                       break;
+               }
+
+               sta_ctxt_cmd.trig_based_txf[i].cwmin =
+                       cpu_to_le16(mu_edca->ecw_min_max & 0xf);
+               sta_ctxt_cmd.trig_based_txf[i].cwmax =
+                       cpu_to_le16((mu_edca->ecw_min_max & 0xf0) >> 4);
+               sta_ctxt_cmd.trig_based_txf[i].aifsn =
+                       cpu_to_le16(mu_edca->aifsn);
+               sta_ctxt_cmd.trig_based_txf[i].mu_time =
+                       cpu_to_le16(mu_edca->mu_edca_timer);
+       }
+
+       if (vif->bss_conf.multi_sta_back_32bit)
+               flags |= STA_CTXT_HE_32BIT_BA_BITMAP;
+
+       if (vif->bss_conf.ack_enabled)
+               flags |= STA_CTXT_HE_ACK_ENABLED;
+
+       if (vif->bss_conf.uora_exists) {
+               flags |= STA_CTXT_HE_TRIG_RND_ALLOC;
+
+               sta_ctxt_cmd.rand_alloc_ecwmin =
+                       vif->bss_conf.uora_ocw_range & 0x7;
+               sta_ctxt_cmd.rand_alloc_ecwmax =
+                       (vif->bss_conf.uora_ocw_range >> 3) & 0x7;
+       }
+
+       /* TODO: support Multi BSSID IE */
+
+       sta_ctxt_cmd.flags = cpu_to_le32(flags);
+
+       if (iwl_mvm_send_cmd_pdu(mvm, iwl_cmd_id(STA_HE_CTXT_CMD,
+                                                DATA_PATH_GROUP, 0),
+                                0, sizeof(sta_ctxt_cmd), &sta_ctxt_cmd))
+               IWL_ERR(mvm, "Failed to config FW to work HE!\n");
+}
+
 static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm,
                                             struct ieee80211_vif *vif,
                                             struct ieee80211_bss_conf *bss_conf,
@@ -1910,8 +2099,12 @@ static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm,
         * beacon interval, which was not known when the station interface was
         * added.
         */
-       if (changes & BSS_CHANGED_ASSOC && bss_conf->assoc)
+       if (changes & BSS_CHANGED_ASSOC && bss_conf->assoc) {
+               if (vif->bss_conf.he_support)
+                       iwl_mvm_cfg_he_sta(mvm, vif, mvmvif->ap_sta_id);
+
                iwl_mvm_mac_ctxt_recalc_tsf_id(mvm, vif);
+       }
 
        /*
         * If we're not associated yet, take the (new) BSSID before associating
index 6a4ba160c59ed4accd1a56136e5b5d9ebdbd8061..b3987a0a70181ad2dc6775d044ccf90a3bbd8cf8 100644 (file)
@@ -654,7 +654,7 @@ struct iwl_mvm_tcm {
 struct iwl_mvm_reorder_buffer {
        u16 head_sn;
        u16 num_stored;
-       u8 buf_size;
+       u16 buf_size;
        int queue;
        u16 last_amsdu;
        u8 last_sub_index;
index ff1e518096c511297c107ccf83d685d9ea81bf0e..aa11b35d6f51520c1d21332170764a13def4a188 100644 (file)
@@ -448,6 +448,7 @@ static const struct iwl_hcmd_names iwl_mvm_data_path_names[] = {
        HCMD_NAME(DQA_ENABLE_CMD),
        HCMD_NAME(UPDATE_MU_GROUPS_CMD),
        HCMD_NAME(TRIGGER_RX_QUEUES_NOTIF_CMD),
+       HCMD_NAME(STA_HE_CTXT_CMD),
        HCMD_NAME(STA_PM_NOTIF),
        HCMD_NAME(MU_GROUP_MGMT_NOTIF),
        HCMD_NAME(RX_QUEUES_NOTIFICATION),
index b8b2b819e8e7ea0203d162235f00eccc39959f13..8169d1450b3b9b3954ff45e4b32d44fd3062788b 100644 (file)
@@ -183,6 +183,43 @@ rs_fw_vht_set_enabled_rates(const struct ieee80211_sta *sta,
        }
 }
 
+static u16 rs_fw_he_ieee80211_mcs_to_rs_mcs(u16 mcs)
+{
+       switch (mcs) {
+       case IEEE80211_HE_MCS_SUPPORT_0_7:
+               return BIT(IWL_TLC_MNG_HT_RATE_MCS7 + 1) - 1;
+       case IEEE80211_HE_MCS_SUPPORT_0_9:
+               return BIT(IWL_TLC_MNG_HT_RATE_MCS9 + 1) - 1;
+       case IEEE80211_HE_MCS_SUPPORT_0_11:
+               return BIT(IWL_TLC_MNG_HT_RATE_MCS11 + 1) - 1;
+       case IEEE80211_HE_MCS_NOT_SUPPORTED:
+               return 0;
+       }
+
+       WARN(1, "invalid HE MCS %d\n", mcs);
+       return 0;
+}
+
+static void
+rs_fw_he_set_enabled_rates(const struct ieee80211_sta *sta,
+                          const struct ieee80211_sta_he_cap *he_cap,
+                          struct iwl_tlc_config_cmd *cmd)
+{
+       u16 mcs_160 = le16_to_cpu(sta->he_cap.he_mcs_nss_supp.rx_mcs_160);
+       u16 mcs_80 = le16_to_cpu(sta->he_cap.he_mcs_nss_supp.rx_mcs_80);
+       int i;
+
+       for (i = 0; i < sta->rx_nss && i < MAX_NSS; i++) {
+               u16 _mcs_160 = (mcs_160 >> (2 * i)) & 0x3;
+               u16 _mcs_80 = (mcs_80 >> (2 * i)) & 0x3;
+
+               cmd->ht_rates[i][0] =
+                       cpu_to_le16(rs_fw_he_ieee80211_mcs_to_rs_mcs(_mcs_80));
+               cmd->ht_rates[i][1] =
+                       cpu_to_le16(rs_fw_he_ieee80211_mcs_to_rs_mcs(_mcs_160));
+       }
+}
+
 static void rs_fw_set_supp_rates(struct ieee80211_sta *sta,
                                 struct ieee80211_supported_band *sband,
                                 struct iwl_tlc_config_cmd *cmd)
@@ -192,6 +229,7 @@ static void rs_fw_set_supp_rates(struct ieee80211_sta *sta,
        unsigned long supp; /* must be unsigned long for for_each_set_bit */
        const struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap;
        const struct ieee80211_sta_vht_cap *vht_cap = &sta->vht_cap;
+       const struct ieee80211_sta_he_cap *he_cap = &sta->he_cap;
 
        /* non HT rates */
        supp = 0;
@@ -202,7 +240,11 @@ static void rs_fw_set_supp_rates(struct ieee80211_sta *sta,
        cmd->non_ht_rates = cpu_to_le16(supp);
        cmd->mode = IWL_TLC_MNG_MODE_NON_HT;
 
-       if (vht_cap && vht_cap->vht_supported) {
+       /* HT/VHT rates */
+       if (he_cap && he_cap->has_he) {
+               cmd->mode = IWL_TLC_MNG_MODE_HE;
+               rs_fw_he_set_enabled_rates(sta, he_cap, cmd);
+       } else if (vht_cap && vht_cap->vht_supported) {
                cmd->mode = IWL_TLC_MNG_MODE_VHT;
                rs_fw_vht_set_enabled_rates(sta, vht_cap, cmd);
        } else if (ht_cap && ht_cap->ht_supported) {
index 642da10b0b7fdd448fff8db0ef3d4f82c85308a2..30cfd7d50bc939fae1d0111c2c4694f755c9c947 100644 (file)
@@ -363,7 +363,8 @@ static int iwl_hwrate_to_plcp_idx(u32 rate_n_flags)
                        idx += 1;
                if ((idx >= IWL_FIRST_HT_RATE) && (idx <= IWL_LAST_HT_RATE))
                        return idx;
-       } else if (rate_n_flags & RATE_MCS_VHT_MSK) {
+       } else if (rate_n_flags & RATE_MCS_VHT_MSK ||
+                  rate_n_flags & RATE_MCS_HE_MSK) {
                idx = rate_n_flags & RATE_VHT_MCS_RATE_CODE_MSK;
                idx += IWL_RATE_MCS_0_INDEX;
 
@@ -372,6 +373,9 @@ static int iwl_hwrate_to_plcp_idx(u32 rate_n_flags)
                        idx++;
                if ((idx >= IWL_FIRST_VHT_RATE) && (idx <= IWL_LAST_VHT_RATE))
                        return idx;
+               if ((rate_n_flags & RATE_MCS_HE_MSK) &&
+                   (idx <= IWL_LAST_HE_RATE))
+                       return idx;
        } else {
                /* legacy rate format, search for match in table */
 
@@ -516,6 +520,8 @@ static const char *rs_pretty_lq_type(enum iwl_table_type type)
                [LQ_HT_MIMO2] = "HT MIMO",
                [LQ_VHT_SISO] = "VHT SISO",
                [LQ_VHT_MIMO2] = "VHT MIMO",
+               [LQ_HE_SISO] = "HE SISO",
+               [LQ_HE_MIMO2] = "HE MIMO",
        };
 
        if (type < LQ_NONE || type >= LQ_MAX)
@@ -900,7 +906,8 @@ static int rs_rate_from_ucode_rate(const u32 ucode_rate,
 
        /* Legacy */
        if (!(ucode_rate & RATE_MCS_HT_MSK) &&
-           !(ucode_rate & RATE_MCS_VHT_MSK)) {
+           !(ucode_rate & RATE_MCS_VHT_MSK) &&
+           !(ucode_rate & RATE_MCS_HE_MSK)) {
                if (num_of_ant == 1) {
                        if (band == NL80211_BAND_5GHZ)
                                rate->type = LQ_LEGACY_A;
@@ -911,7 +918,7 @@ static int rs_rate_from_ucode_rate(const u32 ucode_rate,
                return 0;
        }
 
-       /* HT or VHT */
+       /* HT, VHT or HE */
        if (ucode_rate & RATE_MCS_SGI_MSK)
                rate->sgi = true;
        if (ucode_rate & RATE_MCS_LDPC_MSK)
@@ -953,10 +960,24 @@ static int rs_rate_from_ucode_rate(const u32 ucode_rate,
                } else {
                        WARN_ON_ONCE(1);
                }
+       } else if (ucode_rate & RATE_MCS_HE_MSK) {
+               nss = ((ucode_rate & RATE_VHT_MCS_NSS_MSK) >>
+                     RATE_VHT_MCS_NSS_POS) + 1;
+
+               if (nss == 1) {
+                       rate->type = LQ_HE_SISO;
+                       WARN_ONCE(!rate->stbc && !rate->bfer && num_of_ant != 1,
+                                 "stbc %d bfer %d", rate->stbc, rate->bfer);
+               } else if (nss == 2) {
+                       rate->type = LQ_HE_MIMO2;
+                       WARN_ON_ONCE(num_of_ant != 2);
+               } else {
+                       WARN_ON_ONCE(1);
+               }
        }
 
        WARN_ON_ONCE(rate->bw == RATE_MCS_CHAN_WIDTH_80 &&
-                    !is_vht(rate));
+                    !is_he(rate) && !is_vht(rate));
 
        return 0;
 }
@@ -3606,7 +3627,8 @@ int rs_pretty_print_rate(char *buf, int bufsz, const u32 rate)
        u8 ant = (rate & RATE_MCS_ANT_ABC_MSK) >> RATE_MCS_ANT_POS;
 
        if (!(rate & RATE_MCS_HT_MSK) &&
-           !(rate & RATE_MCS_VHT_MSK)) {
+           !(rate & RATE_MCS_VHT_MSK) &&
+           !(rate & RATE_MCS_HE_MSK)) {
                int index = iwl_hwrate_to_plcp_idx(rate);
 
                return scnprintf(buf, bufsz, "Legacy | ANT: %s Rate: %s Mbps\n",
@@ -3625,6 +3647,11 @@ int rs_pretty_print_rate(char *buf, int bufsz, const u32 rate)
                mcs = rate & RATE_HT_MCS_INDEX_MSK;
                nss = ((rate & RATE_HT_MCS_NSS_MSK)
                       >> RATE_HT_MCS_NSS_POS) + 1;
+       } else if (rate & RATE_MCS_HE_MSK) {
+               type = "HE";
+               mcs = rate & RATE_VHT_MCS_RATE_CODE_MSK;
+               nss = ((rate & RATE_VHT_MCS_NSS_MSK)
+                      >> RATE_VHT_MCS_NSS_POS) + 1;
        } else {
                type = "Unknown"; /* shouldn't happen */
        }
@@ -3886,6 +3913,8 @@ static ssize_t rs_sta_dbgfs_drv_tx_stats_read(struct file *file,
                [IWL_RATE_MCS_7_INDEX] = "MCS7",
                [IWL_RATE_MCS_8_INDEX] = "MCS8",
                [IWL_RATE_MCS_9_INDEX] = "MCS9",
+               [IWL_RATE_MCS_10_INDEX] = "MCS10",
+               [IWL_RATE_MCS_11_INDEX] = "MCS11",
        };
 
        char *buff, *pos, *endpos;
index cffb8c852934b2aef96dde32e967b7a21b612d67..d2cf484e2b73be77bd61006d0aeb77683baec58d 100644 (file)
@@ -144,8 +144,13 @@ enum {
 
 #define LINK_QUAL_AGG_FRAME_LIMIT_DEF  (63)
 #define LINK_QUAL_AGG_FRAME_LIMIT_MAX  (63)
-#define LINK_QUAL_AGG_FRAME_LIMIT_GEN2_DEF     (64)
-#define LINK_QUAL_AGG_FRAME_LIMIT_GEN2_MAX     (64)
+/*
+ * FIXME - various places in firmware API still use u8,
+ * e.g. LQ command and SCD config command.
+ * This should be 256 instead.
+ */
+#define LINK_QUAL_AGG_FRAME_LIMIT_GEN2_DEF     (255)
+#define LINK_QUAL_AGG_FRAME_LIMIT_GEN2_MAX     (255)
 #define LINK_QUAL_AGG_FRAME_LIMIT_MIN  (0)
 
 #define LQ_SIZE                2       /* 2 mode tables:  "Active" and "Search" */
@@ -162,6 +167,8 @@ enum iwl_table_type {
        LQ_HT_MIMO2,
        LQ_VHT_SISO,    /* VHT types */
        LQ_VHT_MIMO2,
+       LQ_HE_SISO,     /* HE types */
+       LQ_HE_MIMO2,
        LQ_MAX,
 };
 
@@ -183,11 +190,16 @@ struct rs_rate {
 #define is_type_ht_mimo2(type) ((type) == LQ_HT_MIMO2)
 #define is_type_vht_siso(type) ((type) == LQ_VHT_SISO)
 #define is_type_vht_mimo2(type) ((type) == LQ_VHT_MIMO2)
-#define is_type_siso(type) (is_type_ht_siso(type) || is_type_vht_siso(type))
-#define is_type_mimo2(type) (is_type_ht_mimo2(type) || is_type_vht_mimo2(type))
+#define is_type_he_siso(type) ((type) == LQ_HE_SISO)
+#define is_type_he_mimo2(type) ((type) == LQ_HE_MIMO2)
+#define is_type_siso(type) (is_type_ht_siso(type) || is_type_vht_siso(type) || \
+                           is_type_he_siso(type))
+#define is_type_mimo2(type) (is_type_ht_mimo2(type) || \
+                            is_type_vht_mimo2(type) || is_type_he_mimo2(type))
 #define is_type_mimo(type) (is_type_mimo2(type))
 #define is_type_ht(type) (is_type_ht_siso(type) || is_type_ht_mimo2(type))
 #define is_type_vht(type) (is_type_vht_siso(type) || is_type_vht_mimo2(type))
+#define is_type_he(type) (is_type_he_siso(type) || is_type_he_mimo2(type))
 #define is_type_a_band(type) ((type) == LQ_LEGACY_A)
 #define is_type_g_band(type) ((type) == LQ_LEGACY_G)
 
@@ -201,6 +213,7 @@ struct rs_rate {
 #define is_mimo(rate)         is_type_mimo((rate)->type)
 #define is_ht(rate)           is_type_ht((rate)->type)
 #define is_vht(rate)          is_type_vht((rate)->type)
+#define is_he(rate)           is_type_he((rate)->type)
 #define is_a_band(rate)       is_type_a_band((rate)->type)
 #define is_g_band(rate)       is_type_g_band((rate)->type)
 
index 129c4c09648dcb35972eecbb344a25ad51339870..0d66cb232cf157ce324af6d307ea94b1165169d6 100644 (file)
@@ -8,6 +8,7 @@
  * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
  * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
  * Copyright(c) 2015 - 2017 Intel Deutschland GmbH
+ * Copyright(c) 2018 Intel Corporation
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of version 2 of the GNU General Public License as
@@ -30,6 +31,7 @@
  * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
  * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
  * Copyright(c) 2015 - 2017 Intel Deutschland GmbH
+ * Copyright(c) 2018 Intel Corporation
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -857,6 +859,10 @@ void iwl_mvm_rx_mpdu_mq(struct iwl_mvm *mvm, struct napi_struct *napi,
        struct ieee80211_sta *sta = NULL;
        struct sk_buff *skb;
        u8 crypt_len = 0;
+       u32 he_type = 0xffffffff;
+       /* this is invalid e.g. because puncture type doesn't allow 0b11 */
+#define HE_PHY_DATA_INVAL ((u64)-1)
+       u64 he_phy_data = HE_PHY_DATA_INVAL;
 
        if (unlikely(test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status)))
                return;
@@ -882,6 +888,13 @@ void iwl_mvm_rx_mpdu_mq(struct iwl_mvm *mvm, struct napi_struct *napi,
 
        rx_status = IEEE80211_SKB_RXCB(skb);
 
+       if (rate_n_flags & RATE_MCS_HE_MSK) {
+               if (phy_info & IWL_RX_MPDU_PHY_TSF_OVERLOAD)
+                       he_phy_data =
+                               le64_to_cpu(desc->he_phy_data);
+               he_type = rate_n_flags & RATE_MCS_HE_TYPE_MSK;
+       }
+
        if (iwl_mvm_rx_crypto(mvm, hdr, rx_status, phy_info, desc,
                              le32_to_cpu(pkt->len_n_flags), queue,
                              &crypt_len)) {
@@ -907,7 +920,19 @@ void iwl_mvm_rx_mpdu_mq(struct iwl_mvm *mvm, struct napi_struct *napi,
                rx_status->mactime = le64_to_cpu(desc->tsf_on_air_rise);
                /* TSF as indicated by the firmware is at INA time */
                rx_status->flag |= RX_FLAG_MACTIME_PLCP_START;
+       } else if (he_type == RATE_MCS_HE_TYPE_SU) {
+               if (!queue && !(phy_info & IWL_RX_MPDU_PHY_AMPDU)) {
+                       rx_status->ampdu_reference = mvm->ampdu_ref;
+                       mvm->ampdu_ref++;
+
+                       rx_status->flag |= RX_FLAG_AMPDU_DETAILS;
+                       rx_status->flag |= RX_FLAG_AMPDU_EOF_BIT_KNOWN;
+                       if (FIELD_GET(IWL_RX_HE_PHY_DELIM_EOF,
+                                     le64_to_cpu(desc->he_phy_data)))
+                               rx_status->flag |= RX_FLAG_AMPDU_EOF_BIT;
+               }
        }
+
        rx_status->device_timestamp = le32_to_cpu(desc->gp2_on_air_rise);
        rx_status->band = desc->channel > 14 ? NL80211_BAND_5GHZ :
                                               NL80211_BAND_2GHZ;
@@ -925,6 +950,15 @@ void iwl_mvm_rx_mpdu_mq(struct iwl_mvm *mvm, struct napi_struct *napi,
                if (toggle_bit != mvm->ampdu_toggle) {
                        mvm->ampdu_ref++;
                        mvm->ampdu_toggle = toggle_bit;
+
+                       if (he_phy_data != HE_PHY_DATA_INVAL &&
+                           he_type == RATE_MCS_HE_TYPE_MU) {
+                               rx_status->flag |= RX_FLAG_AMPDU_EOF_BIT_KNOWN;
+                               if (FIELD_GET(IWL_RX_HE_PHY_DELIM_EOF,
+                                             le64_to_cpu(desc->he_phy_data)))
+                                       rx_status->flag |=
+                                               RX_FLAG_AMPDU_EOF_BIT;
+                       }
                }
        }
 
@@ -1033,7 +1067,6 @@ void iwl_mvm_rx_mpdu_mq(struct iwl_mvm *mvm, struct napi_struct *napi,
                }
        }
 
-       /* Set up the HT phy flags */
        switch (rate_n_flags & RATE_MCS_CHAN_WIDTH_MSK) {
        case RATE_MCS_CHAN_WIDTH_20:
                break;
@@ -1048,6 +1081,59 @@ void iwl_mvm_rx_mpdu_mq(struct iwl_mvm *mvm, struct napi_struct *napi,
                break;
        }
 
+       if (he_type == RATE_MCS_HE_TYPE_EXT_SU &&
+           rate_n_flags & RATE_MCS_HE_106T_MSK) {
+               rx_status->bw = RATE_INFO_BW_HE_RU;
+               rx_status->he_ru = NL80211_RATE_INFO_HE_RU_ALLOC_106;
+       }
+
+       if (rate_n_flags & RATE_MCS_HE_MSK &&
+           phy_info & IWL_RX_MPDU_PHY_TSF_OVERLOAD &&
+           he_type == RATE_MCS_HE_TYPE_MU) {
+               /*
+                * Unfortunately, we have to leave the mac80211 data
+                * incorrect for the case that we receive an HE-MU
+                * transmission and *don't* have the he_mu pointer,
+                * i.e. we don't have the phy data (due to the bits
+                * being used for TSF). This shouldn't happen though
+                * as management frames where we need the TSF/timers
+                * are not be transmitted in HE-MU, I think.
+                */
+               u8 ru = FIELD_GET(IWL_RX_HE_PHY_RU_ALLOC_MASK, he_phy_data);
+               u8 offs = 0;
+
+               rx_status->bw = RATE_INFO_BW_HE_RU;
+
+               switch (ru) {
+               case 0 ... 36:
+                       rx_status->he_ru = NL80211_RATE_INFO_HE_RU_ALLOC_26;
+                       offs = ru;
+                       break;
+               case 37 ... 52:
+                       rx_status->he_ru = NL80211_RATE_INFO_HE_RU_ALLOC_52;
+                       offs = ru - 37;
+                       break;
+               case 53 ... 60:
+                       rx_status->he_ru = NL80211_RATE_INFO_HE_RU_ALLOC_106;
+                       offs = ru - 53;
+                       break;
+               case 61 ... 64:
+                       rx_status->he_ru = NL80211_RATE_INFO_HE_RU_ALLOC_242;
+                       offs = ru - 61;
+                       break;
+               case 65 ... 66:
+                       rx_status->he_ru = NL80211_RATE_INFO_HE_RU_ALLOC_484;
+                       offs = ru - 65;
+                       break;
+               case 67:
+                       rx_status->he_ru = NL80211_RATE_INFO_HE_RU_ALLOC_996;
+                       break;
+               case 68:
+                       rx_status->he_ru = NL80211_RATE_INFO_HE_RU_ALLOC_2x996;
+                       break;
+               }
+       }
+
        if (!(rate_n_flags & RATE_MCS_CCK_MSK) &&
            rate_n_flags & RATE_MCS_SGI_MSK)
                rx_status->enc_flags |= RX_ENC_FLAG_SHORT_GI;
@@ -1072,6 +1158,39 @@ void iwl_mvm_rx_mpdu_mq(struct iwl_mvm *mvm, struct napi_struct *napi,
                rx_status->enc_flags |= stbc << RX_ENC_FLAG_STBC_SHIFT;
                if (rate_n_flags & RATE_MCS_BF_MSK)
                        rx_status->enc_flags |= RX_ENC_FLAG_BF;
+       } else if (rate_n_flags & RATE_MCS_HE_MSK) {
+               u8 stbc = (rate_n_flags & RATE_MCS_STBC_MSK) >>
+                               RATE_MCS_STBC_POS;
+               rx_status->nss =
+                       ((rate_n_flags & RATE_VHT_MCS_NSS_MSK) >>
+                                               RATE_VHT_MCS_NSS_POS) + 1;
+               rx_status->rate_idx = rate_n_flags & RATE_VHT_MCS_RATE_CODE_MSK;
+               rx_status->encoding = RX_ENC_HE;
+               rx_status->enc_flags |= stbc << RX_ENC_FLAG_STBC_SHIFT;
+               if (rate_n_flags & RATE_MCS_BF_MSK)
+                       rx_status->enc_flags |= RX_ENC_FLAG_BF;
+
+               rx_status->he_dcm =
+                       !!(rate_n_flags & RATE_HE_DUAL_CARRIER_MODE_MSK);
+
+               switch ((rate_n_flags & RATE_MCS_HE_GI_LTF_MSK) >>
+                       RATE_MCS_HE_GI_LTF_POS) {
+               case 0:
+                       rx_status->he_gi = NL80211_RATE_INFO_HE_GI_0_8;
+                       break;
+               case 1:
+                       rx_status->he_gi = NL80211_RATE_INFO_HE_GI_0_8;
+                       break;
+               case 2:
+                       rx_status->he_gi = NL80211_RATE_INFO_HE_GI_1_6;
+                       break;
+               case 3:
+                       if (rate_n_flags & RATE_MCS_SGI_MSK)
+                               rx_status->he_gi = NL80211_RATE_INFO_HE_GI_0_8;
+                       else
+                               rx_status->he_gi = NL80211_RATE_INFO_HE_GI_3_2;
+                       break;
+               }
        } else {
                int rate = iwl_mvm_legacy_rate_to_mac80211_idx(rate_n_flags,
                                                               rx_status->band);
@@ -1083,7 +1202,6 @@ void iwl_mvm_rx_mpdu_mq(struct iwl_mvm *mvm, struct napi_struct *napi,
                        goto out;
                }
                rx_status->rate_idx = rate;
-
        }
 
        /* management stuff on default queue */
index 9263b9aa8b72fff47dcdee806ac45d8b1fc9253b..18db1ed92d9b09741e0fec60e66389bd5af18dea 100644 (file)
@@ -2184,7 +2184,7 @@ static void iwl_mvm_free_reorder(struct iwl_mvm *mvm,
 
 static void iwl_mvm_init_reorder_buffer(struct iwl_mvm *mvm,
                                        struct iwl_mvm_baid_data *data,
-                                       u16 ssn, u8 buf_size)
+                                       u16 ssn, u16 buf_size)
 {
        int i;
 
@@ -2211,7 +2211,7 @@ static void iwl_mvm_init_reorder_buffer(struct iwl_mvm *mvm,
 }
 
 int iwl_mvm_sta_rx_agg(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
-                      int tid, u16 ssn, bool start, u8 buf_size, u16 timeout)
+                      int tid, u16 ssn, bool start, u16 buf_size, u16 timeout)
 {
        struct iwl_mvm_sta *mvm_sta = iwl_mvm_sta_from_mac80211(sta);
        struct iwl_mvm_add_sta_cmd cmd = {};
@@ -2273,7 +2273,7 @@ int iwl_mvm_sta_rx_agg(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
        if (start) {
                cmd.add_immediate_ba_tid = (u8) tid;
                cmd.add_immediate_ba_ssn = cpu_to_le16(ssn);
-               cmd.rx_ba_window = cpu_to_le16((u16)buf_size);
+               cmd.rx_ba_window = cpu_to_le16(buf_size);
        } else {
                cmd.remove_immediate_ba_tid = (u8) tid;
        }
@@ -2559,7 +2559,7 @@ int iwl_mvm_sta_tx_agg_start(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
 }
 
 int iwl_mvm_sta_tx_agg_oper(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
-                           struct ieee80211_sta *sta, u16 tid, u8 buf_size,
+                           struct ieee80211_sta *sta, u16 tid, u16 buf_size,
                            bool amsdu)
 {
        struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
index 1c43ea8dd8cc15c2ae226c001161f767beba9a8a..0fc211108149ffcf400d1a64a59b421642147910 100644 (file)
@@ -412,7 +412,7 @@ struct iwl_mvm_sta {
        u32 tfd_queue_msk;
        u32 mac_id_n_color;
        u16 tid_disable_agg;
-       u8 max_agg_bufsize;
+       u16 max_agg_bufsize;
        enum iwl_sta_type sta_type;
        enum ieee80211_sta_state sta_state;
        bool bt_reduced_txpower;
@@ -518,11 +518,11 @@ void iwl_mvm_rx_eosp_notif(struct iwl_mvm *mvm,
 
 /* AMPDU */
 int iwl_mvm_sta_rx_agg(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
-                      int tid, u16 ssn, bool start, u8 buf_size, u16 timeout);
+                      int tid, u16 ssn, bool start, u16 buf_size, u16 timeout);
 int iwl_mvm_sta_tx_agg_start(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
                        struct ieee80211_sta *sta, u16 tid, u16 *ssn);
 int iwl_mvm_sta_tx_agg_oper(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
-                           struct ieee80211_sta *sta, u16 tid, u8 buf_size,
+                           struct ieee80211_sta *sta, u16 tid, u16 buf_size,
                            bool amsdu);
 int iwl_mvm_sta_tx_agg_stop(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
                            struct ieee80211_sta *sta, u16 tid);
index 7229991ae70d4ff1d98ee9779b97ba60fd12087d..57f5d8f3bdf649fcc8d0dae654d643ad485accb2 100644 (file)
@@ -2934,7 +2934,7 @@ static struct iwl_trans_dump_data
        struct iwl_txq *cmdq = trans_pcie->txq[trans_pcie->cmd_queue];
        struct iwl_fw_error_dump_txcmd *txcmd;
        struct iwl_trans_dump_data *dump_data;
-       u32 len, num_rbs;
+       u32 len, num_rbs = 0;
        u32 monitor_len;
        int i, ptr;
        bool dump_rbs = test_bit(STATUS_FW_ERROR, &trans->status) &&