iwlwifi: mvm: update rx statistics cmd api
authorLiad Kaufman <liad.kaufman@intel.com>
Thu, 18 May 2017 15:00:49 +0000 (18:00 +0300)
committerLuca Coelho <luciano.coelho@intel.com>
Thu, 29 Jun 2017 18:02:47 +0000 (21:02 +0300)
The API has changed - update the code.

Signed-off-by: Liad Kaufman <liad.kaufman@intel.com>
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
drivers/net/wireless/intel/iwlwifi/fw/file.h
drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c
drivers/net/wireless/intel/iwlwifi/mvm/fw-api-stats.h
drivers/net/wireless/intel/iwlwifi/mvm/fw-api.h
drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
drivers/net/wireless/intel/iwlwifi/mvm/ops.c
drivers/net/wireless/intel/iwlwifi/mvm/rx.c

index a216657b3c60e8904bbac6860510ecf48edce777..0fa8c473f1e2738b8490e2555af1ae95319d96dd 100644 (file)
@@ -245,10 +245,12 @@ typedef unsigned int __bitwise iwl_ucode_tlv_api_t;
  *     ADD_MODIFY_STA_KEY_API_S_VER_2.
  * @IWL_UCODE_TLV_API_STA_TYPE: This ucode supports station type assignement.
  * @IWL_UCODE_TLV_API_NAN2_VER2: This ucode supports NAN API version 2
+ * @IWL_UCODE_TLV_API_NEW_RX_STATS: should new RX STATISTICS API be used
  *
  * @NUM_IWL_UCODE_TLV_API: number of bits used
  */
 enum iwl_ucode_tlv_api {
+       /* API Set 0 */
        IWL_UCODE_TLV_API_FRAGMENTED_SCAN       = (__force iwl_ucode_tlv_api_t)8,
        IWL_UCODE_TLV_API_WIFI_MCC_UPDATE       = (__force iwl_ucode_tlv_api_t)9,
        IWL_UCODE_TLV_API_LQ_SS_PARAMS          = (__force iwl_ucode_tlv_api_t)18,
@@ -257,6 +259,8 @@ enum iwl_ucode_tlv_api {
        IWL_UCODE_TLV_API_TKIP_MIC_KEYS         = (__force iwl_ucode_tlv_api_t)29,
        IWL_UCODE_TLV_API_STA_TYPE              = (__force iwl_ucode_tlv_api_t)30,
        IWL_UCODE_TLV_API_NAN2_VER2             = (__force iwl_ucode_tlv_api_t)31,
+       /* API Set 1 */
+       IWL_UCODE_TLV_API_NEW_RX_STATS          = (__force iwl_ucode_tlv_api_t)35,
 
        NUM_IWL_UCODE_TLV_API
 #ifdef __CHECKER__
index 61a5e34140dbeb2cd681e14b644f6c14db7fbd41..c1c9c489edc90b62c4fdefd00203484d40caf03d 100644 (file)
@@ -668,15 +668,15 @@ static ssize_t iwl_dbgfs_fw_rx_stats_read(struct file *file,
        int pos = 0;
        char *buf;
        int ret;
-       /* 43 is the size of each data line, 33 is the size of each header */
-       size_t bufsz =
-               ((sizeof(struct mvm_statistics_rx) / sizeof(__le32)) * 43) +
-               (4 * 33) + 1;
+       size_t bufsz;
 
-       struct mvm_statistics_rx_phy *ofdm;
-       struct mvm_statistics_rx_phy *cck;
-       struct mvm_statistics_rx_non_phy *general;
-       struct mvm_statistics_rx_ht_phy *ht;
+       if (iwl_mvm_has_new_rx_stats_api(mvm))
+               bufsz = ((sizeof(struct mvm_statistics_rx) /
+                         sizeof(__le32)) * 43) + (4 * 33) + 1;
+       else
+               /* 43 = size of each data line; 33 = size of each header */
+               bufsz = ((sizeof(struct mvm_statistics_rx_v3) /
+                         sizeof(__le32)) * 43) + (4 * 33) + 1;
 
        buf = kzalloc(bufsz, GFP_KERNEL);
        if (!buf)
@@ -684,96 +684,157 @@ static ssize_t iwl_dbgfs_fw_rx_stats_read(struct file *file,
 
        mutex_lock(&mvm->mutex);
 
-       ofdm = &mvm->rx_stats.ofdm;
-       cck = &mvm->rx_stats.cck;
-       general = &mvm->rx_stats.general;
-       ht = &mvm->rx_stats.ofdm_ht;
-
        pos += scnprintf(buf + pos, bufsz - pos, fmt_header,
                         "Statistics_Rx - OFDM");
-       PRINT_STATS_LE32(ofdm, ina_cnt);
-       PRINT_STATS_LE32(ofdm, fina_cnt);
-       PRINT_STATS_LE32(ofdm, plcp_err);
-       PRINT_STATS_LE32(ofdm, crc32_err);
-       PRINT_STATS_LE32(ofdm, overrun_err);
-       PRINT_STATS_LE32(ofdm, early_overrun_err);
-       PRINT_STATS_LE32(ofdm, crc32_good);
-       PRINT_STATS_LE32(ofdm, false_alarm_cnt);
-       PRINT_STATS_LE32(ofdm, fina_sync_err_cnt);
-       PRINT_STATS_LE32(ofdm, sfd_timeout);
-       PRINT_STATS_LE32(ofdm, fina_timeout);
-       PRINT_STATS_LE32(ofdm, unresponded_rts);
-       PRINT_STATS_LE32(ofdm, rxe_frame_lmt_overrun);
-       PRINT_STATS_LE32(ofdm, sent_ack_cnt);
-       PRINT_STATS_LE32(ofdm, sent_cts_cnt);
-       PRINT_STATS_LE32(ofdm, sent_ba_rsp_cnt);
-       PRINT_STATS_LE32(ofdm, dsp_self_kill);
-       PRINT_STATS_LE32(ofdm, mh_format_err);
-       PRINT_STATS_LE32(ofdm, re_acq_main_rssi_sum);
-       PRINT_STATS_LE32(ofdm, reserved);
+       if (!iwl_mvm_has_new_rx_stats_api(mvm)) {
+               struct mvm_statistics_rx_phy_v2 *ofdm = &mvm->rx_stats_v3.ofdm;
+
+               PRINT_STATS_LE32(ofdm, ina_cnt);
+               PRINT_STATS_LE32(ofdm, fina_cnt);
+               PRINT_STATS_LE32(ofdm, plcp_err);
+               PRINT_STATS_LE32(ofdm, crc32_err);
+               PRINT_STATS_LE32(ofdm, overrun_err);
+               PRINT_STATS_LE32(ofdm, early_overrun_err);
+               PRINT_STATS_LE32(ofdm, crc32_good);
+               PRINT_STATS_LE32(ofdm, false_alarm_cnt);
+               PRINT_STATS_LE32(ofdm, fina_sync_err_cnt);
+               PRINT_STATS_LE32(ofdm, sfd_timeout);
+               PRINT_STATS_LE32(ofdm, fina_timeout);
+               PRINT_STATS_LE32(ofdm, unresponded_rts);
+               PRINT_STATS_LE32(ofdm, rxe_frame_lmt_overrun);
+               PRINT_STATS_LE32(ofdm, sent_ack_cnt);
+               PRINT_STATS_LE32(ofdm, sent_cts_cnt);
+               PRINT_STATS_LE32(ofdm, sent_ba_rsp_cnt);
+               PRINT_STATS_LE32(ofdm, dsp_self_kill);
+               PRINT_STATS_LE32(ofdm, mh_format_err);
+               PRINT_STATS_LE32(ofdm, re_acq_main_rssi_sum);
+               PRINT_STATS_LE32(ofdm, reserved);
+       } else {
+               struct mvm_statistics_rx_phy *ofdm = &mvm->rx_stats.ofdm;
+
+               PRINT_STATS_LE32(ofdm, unresponded_rts);
+               PRINT_STATS_LE32(ofdm, rxe_frame_lmt_overrun);
+               PRINT_STATS_LE32(ofdm, sent_ba_rsp_cnt);
+               PRINT_STATS_LE32(ofdm, dsp_self_kill);
+               PRINT_STATS_LE32(ofdm, reserved);
+       }
 
        pos += scnprintf(buf + pos, bufsz - pos, fmt_header,
                         "Statistics_Rx - CCK");
-       PRINT_STATS_LE32(cck, ina_cnt);
-       PRINT_STATS_LE32(cck, fina_cnt);
-       PRINT_STATS_LE32(cck, plcp_err);
-       PRINT_STATS_LE32(cck, crc32_err);
-       PRINT_STATS_LE32(cck, overrun_err);
-       PRINT_STATS_LE32(cck, early_overrun_err);
-       PRINT_STATS_LE32(cck, crc32_good);
-       PRINT_STATS_LE32(cck, false_alarm_cnt);
-       PRINT_STATS_LE32(cck, fina_sync_err_cnt);
-       PRINT_STATS_LE32(cck, sfd_timeout);
-       PRINT_STATS_LE32(cck, fina_timeout);
-       PRINT_STATS_LE32(cck, unresponded_rts);
-       PRINT_STATS_LE32(cck, rxe_frame_lmt_overrun);
-       PRINT_STATS_LE32(cck, sent_ack_cnt);
-       PRINT_STATS_LE32(cck, sent_cts_cnt);
-       PRINT_STATS_LE32(cck, sent_ba_rsp_cnt);
-       PRINT_STATS_LE32(cck, dsp_self_kill);
-       PRINT_STATS_LE32(cck, mh_format_err);
-       PRINT_STATS_LE32(cck, re_acq_main_rssi_sum);
-       PRINT_STATS_LE32(cck, reserved);
+       if (!iwl_mvm_has_new_rx_stats_api(mvm)) {
+               struct mvm_statistics_rx_phy_v2 *cck = &mvm->rx_stats_v3.cck;
+
+               PRINT_STATS_LE32(cck, ina_cnt);
+               PRINT_STATS_LE32(cck, fina_cnt);
+               PRINT_STATS_LE32(cck, plcp_err);
+               PRINT_STATS_LE32(cck, crc32_err);
+               PRINT_STATS_LE32(cck, overrun_err);
+               PRINT_STATS_LE32(cck, early_overrun_err);
+               PRINT_STATS_LE32(cck, crc32_good);
+               PRINT_STATS_LE32(cck, false_alarm_cnt);
+               PRINT_STATS_LE32(cck, fina_sync_err_cnt);
+               PRINT_STATS_LE32(cck, sfd_timeout);
+               PRINT_STATS_LE32(cck, fina_timeout);
+               PRINT_STATS_LE32(cck, unresponded_rts);
+               PRINT_STATS_LE32(cck, rxe_frame_lmt_overrun);
+               PRINT_STATS_LE32(cck, sent_ack_cnt);
+               PRINT_STATS_LE32(cck, sent_cts_cnt);
+               PRINT_STATS_LE32(cck, sent_ba_rsp_cnt);
+               PRINT_STATS_LE32(cck, dsp_self_kill);
+               PRINT_STATS_LE32(cck, mh_format_err);
+               PRINT_STATS_LE32(cck, re_acq_main_rssi_sum);
+               PRINT_STATS_LE32(cck, reserved);
+       } else {
+               struct mvm_statistics_rx_phy *cck = &mvm->rx_stats.cck;
+
+               PRINT_STATS_LE32(cck, unresponded_rts);
+               PRINT_STATS_LE32(cck, rxe_frame_lmt_overrun);
+               PRINT_STATS_LE32(cck, sent_ba_rsp_cnt);
+               PRINT_STATS_LE32(cck, dsp_self_kill);
+               PRINT_STATS_LE32(cck, reserved);
+       }
 
        pos += scnprintf(buf + pos, bufsz - pos, fmt_header,
                         "Statistics_Rx - GENERAL");
-       PRINT_STATS_LE32(general, bogus_cts);
-       PRINT_STATS_LE32(general, bogus_ack);
-       PRINT_STATS_LE32(general, non_bssid_frames);
-       PRINT_STATS_LE32(general, filtered_frames);
-       PRINT_STATS_LE32(general, non_channel_beacons);
-       PRINT_STATS_LE32(general, channel_beacons);
-       PRINT_STATS_LE32(general, num_missed_bcon);
-       PRINT_STATS_LE32(general, adc_rx_saturation_time);
-       PRINT_STATS_LE32(general, ina_detection_search_time);
-       PRINT_STATS_LE32(general, beacon_silence_rssi_a);
-       PRINT_STATS_LE32(general, beacon_silence_rssi_b);
-       PRINT_STATS_LE32(general, beacon_silence_rssi_c);
-       PRINT_STATS_LE32(general, interference_data_flag);
-       PRINT_STATS_LE32(general, channel_load);
-       PRINT_STATS_LE32(general, dsp_false_alarms);
-       PRINT_STATS_LE32(general, beacon_rssi_a);
-       PRINT_STATS_LE32(general, beacon_rssi_b);
-       PRINT_STATS_LE32(general, beacon_rssi_c);
-       PRINT_STATS_LE32(general, beacon_energy_a);
-       PRINT_STATS_LE32(general, beacon_energy_b);
-       PRINT_STATS_LE32(general, beacon_energy_c);
-       PRINT_STATS_LE32(general, num_bt_kills);
-       PRINT_STATS_LE32(general, mac_id);
-       PRINT_STATS_LE32(general, directed_data_mpdu);
+       if (!iwl_mvm_has_new_rx_stats_api(mvm)) {
+               struct mvm_statistics_rx_non_phy_v3 *general =
+                       &mvm->rx_stats_v3.general;
+
+               PRINT_STATS_LE32(general, bogus_cts);
+               PRINT_STATS_LE32(general, bogus_ack);
+               PRINT_STATS_LE32(general, non_bssid_frames);
+               PRINT_STATS_LE32(general, filtered_frames);
+               PRINT_STATS_LE32(general, non_channel_beacons);
+               PRINT_STATS_LE32(general, channel_beacons);
+               PRINT_STATS_LE32(general, num_missed_bcon);
+               PRINT_STATS_LE32(general, adc_rx_saturation_time);
+               PRINT_STATS_LE32(general, ina_detection_search_time);
+               PRINT_STATS_LE32(general, beacon_silence_rssi_a);
+               PRINT_STATS_LE32(general, beacon_silence_rssi_b);
+               PRINT_STATS_LE32(general, beacon_silence_rssi_c);
+               PRINT_STATS_LE32(general, interference_data_flag);
+               PRINT_STATS_LE32(general, channel_load);
+               PRINT_STATS_LE32(general, dsp_false_alarms);
+               PRINT_STATS_LE32(general, beacon_rssi_a);
+               PRINT_STATS_LE32(general, beacon_rssi_b);
+               PRINT_STATS_LE32(general, beacon_rssi_c);
+               PRINT_STATS_LE32(general, beacon_energy_a);
+               PRINT_STATS_LE32(general, beacon_energy_b);
+               PRINT_STATS_LE32(general, beacon_energy_c);
+               PRINT_STATS_LE32(general, num_bt_kills);
+               PRINT_STATS_LE32(general, mac_id);
+               PRINT_STATS_LE32(general, directed_data_mpdu);
+       } else {
+               struct mvm_statistics_rx_non_phy *general =
+                       &mvm->rx_stats.general;
+
+               PRINT_STATS_LE32(general, bogus_cts);
+               PRINT_STATS_LE32(general, bogus_ack);
+               PRINT_STATS_LE32(general, non_channel_beacons);
+               PRINT_STATS_LE32(general, channel_beacons);
+               PRINT_STATS_LE32(general, num_missed_bcon);
+               PRINT_STATS_LE32(general, adc_rx_saturation_time);
+               PRINT_STATS_LE32(general, ina_detection_search_time);
+               PRINT_STATS_LE32(general, beacon_silence_rssi_a);
+               PRINT_STATS_LE32(general, beacon_silence_rssi_b);
+               PRINT_STATS_LE32(general, beacon_silence_rssi_c);
+               PRINT_STATS_LE32(general, interference_data_flag);
+               PRINT_STATS_LE32(general, channel_load);
+               PRINT_STATS_LE32(general, beacon_rssi_a);
+               PRINT_STATS_LE32(general, beacon_rssi_b);
+               PRINT_STATS_LE32(general, beacon_rssi_c);
+               PRINT_STATS_LE32(general, beacon_energy_a);
+               PRINT_STATS_LE32(general, beacon_energy_b);
+               PRINT_STATS_LE32(general, beacon_energy_c);
+               PRINT_STATS_LE32(general, num_bt_kills);
+               PRINT_STATS_LE32(general, mac_id);
+       }
 
        pos += scnprintf(buf + pos, bufsz - pos, fmt_header,
                         "Statistics_Rx - HT");
-       PRINT_STATS_LE32(ht, plcp_err);
-       PRINT_STATS_LE32(ht, overrun_err);
-       PRINT_STATS_LE32(ht, early_overrun_err);
-       PRINT_STATS_LE32(ht, crc32_good);
-       PRINT_STATS_LE32(ht, crc32_err);
-       PRINT_STATS_LE32(ht, mh_format_err);
-       PRINT_STATS_LE32(ht, agg_crc32_good);
-       PRINT_STATS_LE32(ht, agg_mpdu_cnt);
-       PRINT_STATS_LE32(ht, agg_cnt);
-       PRINT_STATS_LE32(ht, unsupport_mcs);
+       if (!iwl_mvm_has_new_rx_stats_api(mvm)) {
+               struct mvm_statistics_rx_ht_phy_v1 *ht =
+                       &mvm->rx_stats_v3.ofdm_ht;
+
+               PRINT_STATS_LE32(ht, plcp_err);
+               PRINT_STATS_LE32(ht, overrun_err);
+               PRINT_STATS_LE32(ht, early_overrun_err);
+               PRINT_STATS_LE32(ht, crc32_good);
+               PRINT_STATS_LE32(ht, crc32_err);
+               PRINT_STATS_LE32(ht, mh_format_err);
+               PRINT_STATS_LE32(ht, agg_crc32_good);
+               PRINT_STATS_LE32(ht, agg_mpdu_cnt);
+               PRINT_STATS_LE32(ht, agg_cnt);
+               PRINT_STATS_LE32(ht, unsupport_mcs);
+       } else {
+               struct mvm_statistics_rx_ht_phy *ht =
+                       &mvm->rx_stats.ofdm_ht;
+
+               PRINT_STATS_LE32(ht, mh_format_err);
+               PRINT_STATS_LE32(ht, agg_mpdu_cnt);
+               PRINT_STATS_LE32(ht, agg_cnt);
+               PRINT_STATS_LE32(ht, unsupport_mcs);
+       }
 
        mutex_unlock(&mvm->mutex);
 
index 4286222f54f7dd98f5830b097a6f39eb4950726e..c7531da508fd59203d713611cdf6bbc9c2f6ee4d 100644 (file)
@@ -84,7 +84,55 @@ struct mvm_statistics_div {
        __le32 reserved2;
 } __packed; /* STATISTICS_SLOW_DIV_API_S_VER_2 */
 
+/**
+ * struct mvm_statistics_rx_non_phy
+ * @bogus_cts: CTS received when not expecting CTS
+ * @bogus_ack: ACK received when not expecting ACK
+ * @non_channel_beacons: beacons with our bss id but not on our serving channel
+ * @channel_beacons: beacons with our bss id and in our serving channel
+ * @num_missed_bcon: number of missed beacons
+ * @adc_rx_saturation_time: count in 0.8us units the time the ADC was in
+ *     saturation
+ * @ina_detection_search_time: total time (in 0.8us) searched for INA
+ * @beacon_silence_rssi_a: RSSI silence after beacon frame
+ * @beacon_silence_rssi_b: RSSI silence after beacon frame
+ * @beacon_silence_rssi_c: RSSI silence after beacon frame
+ * @interference_data_flag: flag for interference data availability. 1 when data
+ *     is available.
+ * @channel_load: counts RX Enable time in uSec
+ * @beacon_rssi_a: beacon RSSI on anntena A
+ * @beacon_rssi_b: beacon RSSI on antenna B
+ * @beacon_rssi_c: beacon RSSI on antenna C
+ * @beacon_energy_a: beacon energy on antenna A
+ * @beacon_energy_b: beacon energy on antenna B
+ * @beacon_energy_c: beacon energy on antenna C
+ * @num_bt_kills: number of BT "kills" (frame TX aborts)
+ * @mac_id: mac ID
+ */
 struct mvm_statistics_rx_non_phy {
+       __le32 bogus_cts;
+       __le32 bogus_ack;
+       __le32 non_channel_beacons;
+       __le32 channel_beacons;
+       __le32 num_missed_bcon;
+       __le32 adc_rx_saturation_time;
+       __le32 ina_detection_search_time;
+       __le32 beacon_silence_rssi_a;
+       __le32 beacon_silence_rssi_b;
+       __le32 beacon_silence_rssi_c;
+       __le32 interference_data_flag;
+       __le32 channel_load;
+       __le32 beacon_rssi_a;
+       __le32 beacon_rssi_b;
+       __le32 beacon_rssi_c;
+       __le32 beacon_energy_a;
+       __le32 beacon_energy_b;
+       __le32 beacon_energy_c;
+       __le32 num_bt_kills;
+       __le32 mac_id;
+} __packed; /* STATISTICS_RX_NON_PHY_API_S_VER_4 */
+
+struct mvm_statistics_rx_non_phy_v3 {
        __le32 bogus_cts;       /* CTS received when not expecting CTS */
        __le32 bogus_ack;       /* ACK received when not expecting ACK */
        __le32 non_bssid_frames;        /* number of frames with BSSID that
@@ -121,6 +169,14 @@ struct mvm_statistics_rx_non_phy {
 } __packed; /* STATISTICS_RX_NON_PHY_API_S_VER_3 */
 
 struct mvm_statistics_rx_phy {
+       __le32 unresponded_rts;
+       __le32 rxe_frame_lmt_overrun;
+       __le32 sent_ba_rsp_cnt;
+       __le32 dsp_self_kill;
+       __le32 reserved;
+} __packed; /* STATISTICS_RX_PHY_API_S_VER_3 */
+
+struct mvm_statistics_rx_phy_v2 {
        __le32 ina_cnt;
        __le32 fina_cnt;
        __le32 plcp_err;
@@ -143,7 +199,7 @@ struct mvm_statistics_rx_phy {
        __le32 reserved;
 } __packed; /* STATISTICS_RX_PHY_API_S_VER_2 */
 
-struct mvm_statistics_rx_ht_phy {
+struct mvm_statistics_rx_ht_phy_v1 {
        __le32 plcp_err;
        __le32 overrun_err;
        __le32 early_overrun_err;
@@ -156,7 +212,14 @@ struct mvm_statistics_rx_ht_phy {
        __le32 unsupport_mcs;
 } __packed;  /* STATISTICS_HT_RX_PHY_API_S_VER_1 */
 
-struct mvm_statistics_tx_non_phy {
+struct mvm_statistics_rx_ht_phy {
+       __le32 mh_format_err;
+       __le32 agg_mpdu_cnt;
+       __le32 agg_cnt;
+       __le32 unsupport_mcs;
+} __packed;  /* STATISTICS_HT_RX_PHY_API_S_VER_2 */
+
+struct mvm_statistics_tx_non_phy_v3 {
        __le32 preamble_cnt;
        __le32 rx_detected_cnt;
        __le32 bt_prio_defer_cnt;
@@ -173,6 +236,19 @@ struct mvm_statistics_tx_non_phy {
        __le32 ack_or_ba_timeout_collision;
 } __packed; /* STATISTICS_TX_NON_PHY_API_S_VER_3 */
 
+struct mvm_statistics_tx_non_phy {
+       __le32 bt_prio_defer_cnt;
+       __le32 bt_prio_kill_cnt;
+       __le32 few_bytes_cnt;
+       __le32 cts_timeout;
+       __le32 ack_timeout;
+       __le32 dump_msdu_cnt;
+       __le32 burst_abort_next_frame_mismatch_cnt;
+       __le32 burst_abort_missing_next_frame_cnt;
+       __le32 cts_timeout_collision;
+       __le32 ack_or_ba_timeout_collision;
+} __packed; /* STATISTICS_TX_NON_PHY_API_S_VER_4 */
+
 #define MAX_CHAINS 3
 
 struct mvm_statistics_tx_non_phy_agg {
@@ -202,11 +278,17 @@ struct mvm_statistics_tx_channel_width {
        __le32 fail_per_ch_width[4];
 }; /* STATISTICS_TX_CHANNEL_WIDTH_API_S_VER_1 */
 
+struct mvm_statistics_tx_v4 {
+       struct mvm_statistics_tx_non_phy_v3 general;
+       struct mvm_statistics_tx_non_phy_agg agg;
+       struct mvm_statistics_tx_channel_width channel_width;
+} __packed; /* STATISTICS_TX_API_S_VER_4 */
+
 struct mvm_statistics_tx {
        struct mvm_statistics_tx_non_phy general;
        struct mvm_statistics_tx_non_phy_agg agg;
        struct mvm_statistics_tx_channel_width channel_width;
-} __packed; /* STATISTICS_TX_API_S_VER_4 */
+} __packed; /* STATISTICS_TX_API_S_VER_5 */
 
 
 struct mvm_statistics_bt_activity {
@@ -220,7 +302,7 @@ struct mvm_statistics_bt_activity {
        __le32 lo_priority_rx_denied_cnt;
 } __packed;  /* STATISTICS_BT_ACTIVITY_API_S_VER_1 */
 
-struct mvm_statistics_general_common {
+struct mvm_statistics_general_common_v19 {
        __le32 radio_temperature;
        __le32 radio_voltage;
        struct mvm_statistics_dbg dbg;
@@ -250,20 +332,56 @@ struct mvm_statistics_general_common {
        __le64 tx_time;
 } __packed;
 
+struct mvm_statistics_general_common {
+       __le32 radio_temperature;
+       struct mvm_statistics_dbg dbg;
+       __le32 sleep_time;
+       __le32 slots_out;
+       __le32 slots_idle;
+       __le32 ttl_timestamp;
+       struct mvm_statistics_div slow_div;
+       __le32 rx_enable_counter;
+       /*
+        * num_of_sos_states:
+        *  count the number of times we have to re-tune
+        *  in order to get out of bad PHY status
+        */
+       __le32 num_of_sos_states;
+       __le32 beacon_filtered;
+       __le32 missed_beacons;
+       u8 beacon_filter_average_energy;
+       u8 beacon_filter_reason;
+       u8 beacon_filter_current_energy;
+       u8 beacon_filter_reserved;
+       __le32 beacon_filter_delta_time;
+       struct mvm_statistics_bt_activity bt_activity;
+       __le64 rx_time;
+       __le64 on_time_rf;
+       __le64 on_time_scan;
+       __le64 tx_time;
+} __packed; /* STATISTICS_GENERAL_API_S_VER_10 */
+
 struct mvm_statistics_general_v8 {
-       struct mvm_statistics_general_common common;
+       struct mvm_statistics_general_common_v19 common;
        __le32 beacon_counter[NUM_MAC_INDEX];
        u8 beacon_average_energy[NUM_MAC_INDEX];
        u8 reserved[4 - (NUM_MAC_INDEX % 4)];
 } __packed; /* STATISTICS_GENERAL_API_S_VER_8 */
 
-struct mvm_statistics_general_cdb {
-       struct mvm_statistics_general_common common;
+struct mvm_statistics_general_cdb_v9 {
+       struct mvm_statistics_general_common_v19 common;
        __le32 beacon_counter[NUM_MAC_INDEX_CDB];
        u8 beacon_average_energy[NUM_MAC_INDEX_CDB];
        u8 reserved[4 - (NUM_MAC_INDEX_CDB % 4)];
 } __packed; /* STATISTICS_GENERAL_API_S_VER_9 */
 
+struct mvm_statistics_general_cdb {
+       struct mvm_statistics_general_common common;
+       __le32 beacon_counter[MAC_INDEX_AUX];
+       u8 beacon_average_energy[MAC_INDEX_AUX];
+       u8 reserved[8 - MAC_INDEX_AUX];
+} __packed; /* STATISTICS_GENERAL_API_S_VER_10 */
+
 /**
  * struct mvm_statistics_load - RX statistics for multi-queue devices
  * @air_time: accumulated air time, per mac
@@ -272,24 +390,31 @@ struct mvm_statistics_general_cdb {
  * @avg_energy: average RSSI, per station
  */
 struct mvm_statistics_load {
+       __le32 air_time[MAC_INDEX_AUX];
+       __le32 byte_count[MAC_INDEX_AUX];
+       __le32 pkt_count[MAC_INDEX_AUX];
+       u8 avg_energy[IWL_MVM_STATION_COUNT];
+} __packed; /* STATISTICS_RX_MAC_STATION_S_VER_3 */
+
+struct mvm_statistics_load_v1 {
        __le32 air_time[NUM_MAC_INDEX];
        __le32 byte_count[NUM_MAC_INDEX];
        __le32 pkt_count[NUM_MAC_INDEX];
        u8 avg_energy[IWL_MVM_STATION_COUNT];
 } __packed; /* STATISTICS_RX_MAC_STATION_S_VER_1 */
 
-struct mvm_statistics_load_cdb {
-       __le32 air_time[NUM_MAC_INDEX_CDB];
-       __le32 byte_count[NUM_MAC_INDEX_CDB];
-       __le32 pkt_count[NUM_MAC_INDEX_CDB];
-       u8 avg_energy[IWL_MVM_STATION_COUNT];
-} __packed; /* STATISTICS_RX_MAC_STATION_S_VER_2 */
-
 struct mvm_statistics_rx {
        struct mvm_statistics_rx_phy ofdm;
        struct mvm_statistics_rx_phy cck;
        struct mvm_statistics_rx_non_phy general;
        struct mvm_statistics_rx_ht_phy ofdm_ht;
+} __packed; /* STATISTICS_RX_API_S_VER_4 */
+
+struct mvm_statistics_rx_v3 {
+       struct mvm_statistics_rx_phy_v2 ofdm;
+       struct mvm_statistics_rx_phy_v2 cck;
+       struct mvm_statistics_rx_non_phy_v3 general;
+       struct mvm_statistics_rx_ht_phy_v1 ofdm_ht;
 } __packed; /* STATISTICS_RX_API_S_VER_3 */
 
 /*
@@ -302,17 +427,17 @@ struct mvm_statistics_rx {
 
 struct iwl_notif_statistics_v10 {
        __le32 flag;
-       struct mvm_statistics_rx rx;
-       struct mvm_statistics_tx tx;
+       struct mvm_statistics_rx_v3 rx;
+       struct mvm_statistics_tx_v4 tx;
        struct mvm_statistics_general_v8 general;
 } __packed; /* STATISTICS_NTFY_API_S_VER_10 */
 
 struct iwl_notif_statistics_v11 {
        __le32 flag;
-       struct mvm_statistics_rx rx;
-       struct mvm_statistics_tx tx;
+       struct mvm_statistics_rx_v3 rx;
+       struct mvm_statistics_tx_v4 tx;
        struct mvm_statistics_general_v8 general;
-       struct mvm_statistics_load load_stats;
+       struct mvm_statistics_load_v1 load_stats;
 } __packed; /* STATISTICS_NTFY_API_S_VER_11 */
 
 struct iwl_notif_statistics_cdb {
@@ -320,8 +445,8 @@ struct iwl_notif_statistics_cdb {
        struct mvm_statistics_rx rx;
        struct mvm_statistics_tx tx;
        struct mvm_statistics_general_cdb general;
-       struct mvm_statistics_load_cdb load_stats;
-} __packed; /* STATISTICS_NTFY_API_S_VER_12 */
+       struct mvm_statistics_load load_stats;
+} __packed; /* STATISTICS_NTFY_API_S_VER_13 */
 
 /**
  * enum iwl_statistics_notif_flags - flags used in statistics notification
index 3e297c95e8ff16a248f431caa8e50cb1d2dfd8fd..aad265dcfaf52eb944d53c9536f5a30b95f5910e 100644 (file)
@@ -447,7 +447,11 @@ enum iwl_legacy_cmds {
        TX_ANT_CONFIGURATION_CMD = 0x98,
 
        /**
-        * @STATISTICS_CMD: &struct iwl_statistics_cmd
+        * @STATISTICS_CMD:
+        * one of &struct iwl_statistics_cmd,
+        * &struct iwl_notif_statistics_v11,
+        * &struct iwl_notif_statistics_v10,
+        * &struct iwl_notif_statistics_cdb
         */
        STATISTICS_CMD = 0x9c,
 
index 6b8f7817391dfec26e9182d6efe5b533079f20f4..eaacfaf3720680e8e1bb8cbcd63d268d537d512a 100644 (file)
@@ -780,7 +780,10 @@ struct iwl_mvm {
 
        struct iwl_notif_wait_data notif_wait;
 
-       struct mvm_statistics_rx rx_stats;
+       union {
+               struct mvm_statistics_rx_v3 rx_stats_v3;
+               struct mvm_statistics_rx rx_stats;
+       };
 
        struct {
                u64 rx_time;
@@ -1297,6 +1300,12 @@ static inline bool iwl_mvm_is_cdb_supported(struct iwl_mvm *mvm)
                           IWL_UCODE_TLV_CAPA_CDB_SUPPORT);
 }
 
+static inline bool iwl_mvm_has_new_rx_stats_api(struct iwl_mvm *mvm)
+{
+       return fw_has_api(&mvm->fw->ucode_capa,
+                         IWL_UCODE_TLV_API_NEW_RX_STATS);
+}
+
 static inline struct agg_tx_status *
 iwl_mvm_get_agg_status(struct iwl_mvm *mvm, void *tx_resp)
 {
index 1799a3d367f9214101cf3afc0a04071d3517ca1e..4d1188b8736ab40b36095f4027689d516aaf0100 100644 (file)
@@ -776,7 +776,11 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
        if (err)
                goto out_unregister;
 
-       memset(&mvm->rx_stats, 0, sizeof(struct mvm_statistics_rx));
+       if (!iwl_mvm_has_new_rx_stats_api(mvm))
+               memset(&mvm->rx_stats_v3, 0,
+                      sizeof(struct mvm_statistics_rx_v3));
+       else
+               memset(&mvm->rx_stats, 0, sizeof(struct mvm_statistics_rx));
 
        /* The transport always starts with a taken reference, we can
         * release it now if d0i3 is supported */
index 2c07719aa45c6181de30c9dfbf7be57d11b8a610..622d543abb7044f9ffdf1757d15b5646748d692c 100644 (file)
@@ -504,14 +504,6 @@ void iwl_mvm_rx_rx_mpdu(struct iwl_mvm *mvm, struct napi_struct *napi,
                iwl_mvm_unref(mvm, IWL_MVM_REF_RX);
 }
 
-static void iwl_mvm_update_rx_statistics(struct iwl_mvm *mvm,
-                                        struct mvm_statistics_rx *rx_stats)
-{
-       lockdep_assert_held(&mvm->mutex);
-
-       mvm->rx_stats = *rx_stats;
-}
-
 struct iwl_mvm_stat_data {
        struct iwl_mvm *mvm;
        __le32 mac_id;
@@ -555,7 +547,6 @@ static void iwl_mvm_stat_iterator(void *_data, u8 *mac,
                        mvmvif->beacon_stats.avg_signal =
                                -general->beacon_average_energy[vif_id];
                }
-
        }
 
        if (mvmvif->id != id)
@@ -651,7 +642,6 @@ iwl_mvm_rx_stats_check_trigger(struct iwl_mvm *mvm, struct iwl_rx_packet *pkt)
 void iwl_mvm_handle_rx_statistics(struct iwl_mvm *mvm,
                                  struct iwl_rx_packet *pkt)
 {
-       struct iwl_notif_statistics_cdb *stats = (void *)&pkt->data;
        struct iwl_mvm_stat_data data = {
                .mvm = mvm,
        };
@@ -659,13 +649,16 @@ void iwl_mvm_handle_rx_statistics(struct iwl_mvm *mvm,
        int i;
        u8 *energy;
        __le32 *bytes, *air_time;
+       __le32 flags;
 
-       if (iwl_mvm_is_cdb_supported(mvm))
-               expected_size = sizeof(*stats);
-       else if (iwl_mvm_has_new_rx_api(mvm))
-               expected_size = sizeof(struct iwl_notif_statistics_v11);
-       else
-               expected_size = sizeof(struct iwl_notif_statistics_v10);
+       if (!iwl_mvm_has_new_rx_stats_api(mvm)) {
+               if (iwl_mvm_has_new_rx_api(mvm))
+                       expected_size = sizeof(struct iwl_notif_statistics_v11);
+               else
+                       expected_size = sizeof(struct iwl_notif_statistics_v10);
+       } else {
+               expected_size = sizeof(struct iwl_notif_statistics_cdb);
+       }
 
        if (iwl_rx_packet_payload_len(pkt) != expected_size) {
                IWL_ERR(mvm, "received invalid statistics size (%d)!\n",
@@ -673,20 +666,49 @@ void iwl_mvm_handle_rx_statistics(struct iwl_mvm *mvm,
                return;
        }
 
-       data.mac_id = stats->rx.general.mac_id;
-       data.beacon_filter_average_energy =
-               stats->general.common.beacon_filter_average_energy;
+       if (!iwl_mvm_has_new_rx_stats_api(mvm)) {
+               struct iwl_notif_statistics_v11 *stats = (void *)&pkt->data;
 
-       iwl_mvm_update_rx_statistics(mvm, &stats->rx);
+               data.mac_id = stats->rx.general.mac_id;
+               data.beacon_filter_average_energy =
+                       stats->general.common.beacon_filter_average_energy;
 
-       mvm->radio_stats.rx_time = le64_to_cpu(stats->general.common.rx_time);
-       mvm->radio_stats.tx_time = le64_to_cpu(stats->general.common.tx_time);
-       mvm->radio_stats.on_time_rf =
-               le64_to_cpu(stats->general.common.on_time_rf);
-       mvm->radio_stats.on_time_scan =
-               le64_to_cpu(stats->general.common.on_time_scan);
+               mvm->rx_stats_v3 = stats->rx;
 
-       data.general = &stats->general;
+               mvm->radio_stats.rx_time =
+                       le64_to_cpu(stats->general.common.rx_time);
+               mvm->radio_stats.tx_time =
+                       le64_to_cpu(stats->general.common.tx_time);
+               mvm->radio_stats.on_time_rf =
+                       le64_to_cpu(stats->general.common.on_time_rf);
+               mvm->radio_stats.on_time_scan =
+                       le64_to_cpu(stats->general.common.on_time_scan);
+
+               data.general = &stats->general;
+
+               flags = stats->flag;
+       } else {
+               struct iwl_notif_statistics_cdb *stats = (void *)&pkt->data;
+
+               data.mac_id = stats->rx.general.mac_id;
+               data.beacon_filter_average_energy =
+                       stats->general.common.beacon_filter_average_energy;
+
+               mvm->rx_stats = stats->rx;
+
+               mvm->radio_stats.rx_time =
+                       le64_to_cpu(stats->general.common.rx_time);
+               mvm->radio_stats.tx_time =
+                       le64_to_cpu(stats->general.common.tx_time);
+               mvm->radio_stats.on_time_rf =
+                       le64_to_cpu(stats->general.common.on_time_rf);
+               mvm->radio_stats.on_time_scan =
+                       le64_to_cpu(stats->general.common.on_time_scan);
+
+               data.general = &stats->general;
+
+               flags = stats->flag;
+       }
 
        iwl_mvm_rx_stats_check_trigger(mvm, pkt);
 
@@ -698,14 +720,15 @@ void iwl_mvm_handle_rx_statistics(struct iwl_mvm *mvm,
        if (!iwl_mvm_has_new_rx_api(mvm))
                return;
 
-       if (!iwl_mvm_is_cdb_supported(mvm)) {
-               struct iwl_notif_statistics_v11 *v11 =
-                       (void *)&pkt->data;
+       if (!iwl_mvm_has_new_rx_stats_api(mvm)) {
+               struct iwl_notif_statistics_v11 *v11 = (void *)&pkt->data;
 
                energy = (void *)&v11->load_stats.avg_energy;
                bytes = (void *)&v11->load_stats.byte_count;
                air_time = (void *)&v11->load_stats.air_time;
        } else {
+               struct iwl_notif_statistics_cdb *stats = (void *)&pkt->data;
+
                energy = (void *)&stats->load_stats.avg_energy;
                bytes = (void *)&stats->load_stats.byte_count;
                air_time = (void *)&stats->load_stats.air_time;