hc
2023-12-09 b22da3d8526a935aa31e086e63f60ff3246cb61c
kernel/drivers/net/wireless/intel/iwlwifi/mvm/rx.c
....@@ -8,6 +8,7 @@
88 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
99 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
1010 * Copyright(c) 2016 - 2017 Intel Deutschland GmbH
11
+ * Copyright(c) 2018 - 2020 Intel Corporation
1112 *
1213 * This program is free software; you can redistribute it and/or modify
1314 * it under the terms of version 2 of the GNU General Public License as
....@@ -17,11 +18,6 @@
1718 * WITHOUT ANY WARRANTY; without even the implied warranty of
1819 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1920 * General Public License for more details.
20
- *
21
- * You should have received a copy of the GNU General Public License
22
- * along with this program; if not, write to the Free Software
23
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
24
- * USA
2521 *
2622 * The full GNU General Public License is included in this distribution
2723 * in the file called COPYING.
....@@ -34,6 +30,8 @@
3430 *
3531 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
3632 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
33
+ * Copyright(c) 2016 - 2017 Intel Deutschland GmbH
34
+ * Copyright(c) 2018 - 2020 Intel Corporation
3735 * All rights reserved.
3836 *
3937 * Redistribution and use in source and binary forms, with or without
....@@ -228,7 +226,7 @@
228226 !(rx_pkt_status & RX_MPDU_RES_STATUS_TTAK_OK))
229227 return 0;
230228 *crypt_len = IEEE80211_TKIP_IV_LEN;
231
- /* fall through if TTAK OK */
229
+ /* fall through */
232230
233231 case RX_MPDU_RES_STATUS_SEC_WEP_ENC:
234232 if (!(rx_pkt_status & RX_MPDU_RES_STATUS_ICV_OK))
....@@ -355,7 +353,6 @@
355353 u32 rate_n_flags;
356354 u32 rx_pkt_status;
357355 u8 crypt_len = 0;
358
- bool take_ref;
359356
360357 phy_info = &mvm->last_phy_info;
361358 rx_res = (struct iwl_rx_mpdu_res_start *)pkt->data;
....@@ -423,7 +420,7 @@
423420
424421 id >>= RX_MDPU_RES_STATUS_STA_ID_SHIFT;
425422
426
- if (!WARN_ON_ONCE(id >= ARRAY_SIZE(mvm->fw_id_to_mac_id))) {
423
+ if (!WARN_ON_ONCE(id >= mvm->fw->ucode_capa.num_stations)) {
427424 sta = rcu_dereference(mvm->fw_id_to_mac_id[id]);
428425 if (IS_ERR(sta))
429426 sta = NULL;
....@@ -439,13 +436,14 @@
439436 struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
440437 struct ieee80211_vif *tx_blocked_vif =
441438 rcu_dereference(mvm->csa_tx_blocked_vif);
439
+ struct iwl_fw_dbg_trigger_tlv *trig;
440
+ struct ieee80211_vif *vif = mvmsta->vif;
442441
443442 /* We have tx blocked stations (with CS bit). If we heard
444443 * frames from a blocked station on a new channel we can
445444 * TX to it again.
446445 */
447
- if (unlikely(tx_blocked_vif) &&
448
- mvmsta->vif == tx_blocked_vif) {
446
+ if (unlikely(tx_blocked_vif) && vif == tx_blocked_vif) {
449447 struct iwl_mvm_vif *mvmvif =
450448 iwl_mvm_vif_from_mac80211(tx_blocked_vif);
451449
....@@ -456,23 +454,18 @@
456454
457455 rs_update_last_rssi(mvm, mvmsta, rx_status);
458456
459
- if (iwl_fw_dbg_trigger_enabled(mvm->fw, FW_DBG_TRIGGER_RSSI) &&
460
- ieee80211_is_beacon(hdr->frame_control)) {
461
- struct iwl_fw_dbg_trigger_tlv *trig;
457
+ trig = iwl_fw_dbg_trigger_on(&mvm->fwrt,
458
+ ieee80211_vif_to_wdev(vif),
459
+ FW_DBG_TRIGGER_RSSI);
460
+
461
+ if (trig && ieee80211_is_beacon(hdr->frame_control)) {
462462 struct iwl_fw_dbg_trigger_low_rssi *rssi_trig;
463
- bool trig_check;
464463 s32 rssi;
465464
466
- trig = iwl_fw_dbg_get_trigger(mvm->fw,
467
- FW_DBG_TRIGGER_RSSI);
468465 rssi_trig = (void *)trig->data;
469466 rssi = le32_to_cpu(rssi_trig->rssi);
470467
471
- trig_check =
472
- iwl_fw_dbg_trigger_check_stop(&mvm->fwrt,
473
- ieee80211_vif_to_wdev(mvmsta->vif),
474
- trig);
475
- if (trig_check && rx_status->signal < rssi)
468
+ if (rx_status->signal < rssi)
476469 iwl_fw_dbg_collect_trig(&mvm->fwrt, trig,
477470 NULL);
478471 }
....@@ -565,24 +558,10 @@
565558
566559 if (unlikely(ieee80211_is_beacon(hdr->frame_control) ||
567560 ieee80211_is_probe_resp(hdr->frame_control)))
568
- rx_status->boottime_ns = ktime_get_boot_ns();
569
-
570
- /* Take a reference briefly to kick off a d0i3 entry delay so
571
- * we can handle bursts of RX packets without toggling the
572
- * state too often. But don't do this for beacons if we are
573
- * going to idle because the beacon filtering changes we make
574
- * cause the firmware to send us collateral beacons. */
575
- take_ref = !(test_bit(STATUS_TRANS_GOING_IDLE, &mvm->trans->status) &&
576
- ieee80211_is_beacon(hdr->frame_control));
577
-
578
- if (take_ref)
579
- iwl_mvm_ref(mvm, IWL_MVM_REF_RX);
561
+ rx_status->boottime_ns = ktime_get_boottime_ns();
580562
581563 iwl_mvm_pass_packet_to_mac80211(mvm, sta, napi, skb, hdr, len,
582564 crypt_len, rxb);
583
-
584
- if (take_ref)
585
- iwl_mvm_unref(mvm, IWL_MVM_REF_RX);
586565 }
587566
588567 struct iwl_mvm_stat_data {
....@@ -590,7 +569,8 @@
590569 __le32 flags;
591570 __le32 mac_id;
592571 u8 beacon_filter_average_energy;
593
- void *general;
572
+ __le32 *beacon_counter;
573
+ u8 *beacon_average_energy;
594574 };
595575
596576 static void iwl_mvm_stat_iterator(void *_data, u8 *mac,
....@@ -604,32 +584,16 @@
604584 int hyst = vif->bss_conf.cqm_rssi_hyst;
605585 u16 id = le32_to_cpu(data->mac_id);
606586 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
587
+ u16 vif_id = mvmvif->id;
607588
608589 /* This doesn't need the MAC ID check since it's not taking the
609590 * data copied into the "data" struct, but rather the data from
610591 * the notification directly.
611592 */
612
- if (data->general) {
613
- u16 vif_id = mvmvif->id;
614
-
615
- if (iwl_mvm_is_cdb_supported(mvm)) {
616
- struct mvm_statistics_general_cdb *general =
617
- data->general;
618
-
619
- mvmvif->beacon_stats.num_beacons =
620
- le32_to_cpu(general->beacon_counter[vif_id]);
621
- mvmvif->beacon_stats.avg_signal =
622
- -general->beacon_average_energy[vif_id];
623
- } else {
624
- struct mvm_statistics_general_v8 *general =
625
- data->general;
626
-
627
- mvmvif->beacon_stats.num_beacons =
628
- le32_to_cpu(general->beacon_counter[vif_id]);
629
- mvmvif->beacon_stats.avg_signal =
630
- -general->beacon_average_energy[vif_id];
631
- }
632
- }
593
+ mvmvif->beacon_stats.num_beacons =
594
+ le32_to_cpu(data->beacon_counter[vif_id]);
595
+ mvmvif->beacon_stats.avg_signal =
596
+ -data->beacon_average_energy[vif_id];
633597
634598 /* make sure that beacon statistics don't go backwards with TCM
635599 * request to clear statistics
....@@ -707,14 +671,11 @@
707671 struct iwl_fw_dbg_trigger_stats *trig_stats;
708672 u32 trig_offset, trig_thold;
709673
710
- if (!iwl_fw_dbg_trigger_enabled(mvm->fw, FW_DBG_TRIGGER_STATS))
674
+ trig = iwl_fw_dbg_trigger_on(&mvm->fwrt, NULL, FW_DBG_TRIGGER_STATS);
675
+ if (!trig)
711676 return;
712677
713
- trig = iwl_fw_dbg_get_trigger(mvm->fw, FW_DBG_TRIGGER_STATS);
714678 trig_stats = (void *)trig->data;
715
-
716
- if (!iwl_fw_dbg_trigger_check_stop(&mvm->fwrt, NULL, trig))
717
- return;
718679
719680 trig_offset = le32_to_cpu(trig_stats->stop_offset);
720681 trig_thold = le32_to_cpu(trig_stats->stop_threshold);
....@@ -728,18 +689,136 @@
728689 iwl_fw_dbg_collect_trig(&mvm->fwrt, trig, NULL);
729690 }
730691
692
+static void iwl_mvm_update_avg_energy(struct iwl_mvm *mvm,
693
+ u8 energy[IWL_MVM_STATION_COUNT_MAX])
694
+{
695
+ int i;
696
+
697
+ if (WARN_ONCE(mvm->fw->ucode_capa.num_stations >
698
+ IWL_MVM_STATION_COUNT_MAX,
699
+ "Driver and FW station count mismatch %d\n",
700
+ mvm->fw->ucode_capa.num_stations))
701
+ return;
702
+
703
+ rcu_read_lock();
704
+ for (i = 0; i < mvm->fw->ucode_capa.num_stations; i++) {
705
+ struct iwl_mvm_sta *sta;
706
+
707
+ if (!energy[i])
708
+ continue;
709
+
710
+ sta = iwl_mvm_sta_from_staid_rcu(mvm, i);
711
+ if (!sta)
712
+ continue;
713
+ sta->avg_energy = energy[i];
714
+ }
715
+ rcu_read_unlock();
716
+}
717
+
718
+static void
719
+iwl_mvm_update_tcm_from_stats(struct iwl_mvm *mvm, __le32 *air_time_le,
720
+ __le32 *rx_bytes_le)
721
+{
722
+ int i;
723
+
724
+ spin_lock(&mvm->tcm.lock);
725
+ for (i = 0; i < NUM_MAC_INDEX_DRIVER; i++) {
726
+ struct iwl_mvm_tcm_mac *mdata = &mvm->tcm.data[i];
727
+ u32 rx_bytes = le32_to_cpu(rx_bytes_le[i]);
728
+ u32 airtime = le32_to_cpu(air_time_le[i]);
729
+
730
+ mdata->rx.airtime += airtime;
731
+ mdata->uapsd_nonagg_detect.rx_bytes += rx_bytes;
732
+ if (airtime) {
733
+ /* re-init every time to store rate from FW */
734
+ ewma_rate_init(&mdata->uapsd_nonagg_detect.rate);
735
+ ewma_rate_add(&mdata->uapsd_nonagg_detect.rate,
736
+ rx_bytes * 8 / airtime);
737
+ }
738
+ }
739
+ spin_unlock(&mvm->tcm.lock);
740
+}
741
+
742
+static void
743
+iwl_mvm_handle_rx_statistics_tlv(struct iwl_mvm *mvm,
744
+ struct iwl_rx_packet *pkt)
745
+{
746
+ struct iwl_mvm_stat_data data = {
747
+ .mvm = mvm,
748
+ };
749
+ u8 beacon_average_energy[MAC_INDEX_AUX];
750
+ u8 average_energy[IWL_MVM_STATION_COUNT_MAX];
751
+ struct iwl_statistics_operational_ntfy *stats;
752
+ int expected_size;
753
+ __le32 flags;
754
+ int i;
755
+
756
+ expected_size = sizeof(*stats);
757
+ if (WARN_ONCE(iwl_rx_packet_payload_len(pkt) < expected_size,
758
+ "received invalid statistics size (%d)!, expected_size: %d\n",
759
+ iwl_rx_packet_payload_len(pkt), expected_size))
760
+ return;
761
+
762
+ stats = (void *)&pkt->data;
763
+
764
+ if (WARN_ONCE(stats->hdr.type != FW_STATISTICS_OPERATIONAL ||
765
+ stats->hdr.version != 1,
766
+ "received unsupported hdr type %d, version %d\n",
767
+ stats->hdr.type, stats->hdr.version))
768
+ return;
769
+
770
+ flags = stats->flags;
771
+ mvm->radio_stats.rx_time = le64_to_cpu(stats->rx_time);
772
+ mvm->radio_stats.tx_time = le64_to_cpu(stats->tx_time);
773
+ mvm->radio_stats.on_time_rf = le64_to_cpu(stats->on_time_rf);
774
+ mvm->radio_stats.on_time_scan = le64_to_cpu(stats->on_time_scan);
775
+
776
+ iwl_mvm_rx_stats_check_trigger(mvm, pkt);
777
+
778
+ data.mac_id = stats->mac_id;
779
+ data.beacon_filter_average_energy =
780
+ le32_to_cpu(stats->beacon_filter_average_energy);
781
+ data.flags = flags;
782
+ data.beacon_counter = stats->beacon_counter;
783
+ for (i = 0; i < ARRAY_SIZE(beacon_average_energy); i++)
784
+ beacon_average_energy[i] =
785
+ le32_to_cpu(stats->beacon_average_energy[i]);
786
+
787
+ data.beacon_average_energy = beacon_average_energy;
788
+
789
+ ieee80211_iterate_active_interfaces(mvm->hw,
790
+ IEEE80211_IFACE_ITER_NORMAL,
791
+ iwl_mvm_stat_iterator,
792
+ &data);
793
+
794
+ for (i = 0; i < ARRAY_SIZE(average_energy); i++)
795
+ average_energy[i] = le32_to_cpu(stats->average_energy[i]);
796
+ iwl_mvm_update_avg_energy(mvm, average_energy);
797
+
798
+ /*
799
+ * Don't update in case the statistics are not cleared, since
800
+ * we will end up counting twice the same airtime, once in TCM
801
+ * request and once in statistics notification.
802
+ */
803
+ if (le32_to_cpu(flags) & IWL_STATISTICS_REPLY_FLG_CLEAR)
804
+ iwl_mvm_update_tcm_from_stats(mvm, stats->air_time,
805
+ stats->rx_bytes);
806
+}
807
+
731808 void iwl_mvm_handle_rx_statistics(struct iwl_mvm *mvm,
732809 struct iwl_rx_packet *pkt)
733810 {
734811 struct iwl_mvm_stat_data data = {
735812 .mvm = mvm,
736813 };
814
+ __le32 *bytes, *air_time, flags;
737815 int expected_size;
738
- int i;
739816 u8 *energy;
740
- __le32 *bytes;
741
- __le32 *air_time;
742
- __le32 flags;
817
+
818
+ /* From ver 14 and up we use TLV statistics format */
819
+ if (iwl_fw_lookup_notif_ver(mvm->fw, LONG_GROUP,
820
+ STATISTICS_CMD, 0) >= 14)
821
+ return iwl_mvm_handle_rx_statistics_tlv(mvm, pkt);
743822
744823 if (!iwl_mvm_has_new_rx_stats_api(mvm)) {
745824 if (iwl_mvm_has_new_rx_api(mvm))
....@@ -747,7 +826,7 @@
747826 else
748827 expected_size = sizeof(struct iwl_notif_statistics_v10);
749828 } else {
750
- expected_size = sizeof(struct iwl_notif_statistics_cdb);
829
+ expected_size = sizeof(struct iwl_notif_statistics);
751830 }
752831
753832 if (WARN_ONCE(iwl_rx_packet_payload_len(pkt) != expected_size,
....@@ -773,11 +852,12 @@
773852 mvm->radio_stats.on_time_scan =
774853 le64_to_cpu(stats->general.common.on_time_scan);
775854
776
- data.general = &stats->general;
777
-
855
+ data.beacon_counter = stats->general.beacon_counter;
856
+ data.beacon_average_energy =
857
+ stats->general.beacon_average_energy;
778858 flags = stats->flag;
779859 } else {
780
- struct iwl_notif_statistics_cdb *stats = (void *)&pkt->data;
860
+ struct iwl_notif_statistics *stats = (void *)&pkt->data;
781861
782862 data.mac_id = stats->rx.general.mac_id;
783863 data.beacon_filter_average_energy =
....@@ -794,8 +874,9 @@
794874 mvm->radio_stats.on_time_scan =
795875 le64_to_cpu(stats->general.common.on_time_scan);
796876
797
- data.general = &stats->general;
798
-
877
+ data.beacon_counter = stats->general.beacon_counter;
878
+ data.beacon_average_energy =
879
+ stats->general.beacon_average_energy;
799880 flags = stats->flag;
800881 }
801882 data.flags = flags;
....@@ -817,52 +898,23 @@
817898 bytes = (void *)&v11->load_stats.byte_count;
818899 air_time = (void *)&v11->load_stats.air_time;
819900 } else {
820
- struct iwl_notif_statistics_cdb *stats = (void *)&pkt->data;
901
+ struct iwl_notif_statistics *stats = (void *)&pkt->data;
821902
822903 energy = (void *)&stats->load_stats.avg_energy;
823904 bytes = (void *)&stats->load_stats.byte_count;
824905 air_time = (void *)&stats->load_stats.air_time;
825906 }
826907
827
- rcu_read_lock();
828
- for (i = 0; i < ARRAY_SIZE(mvm->fw_id_to_mac_id); i++) {
829
- struct iwl_mvm_sta *sta;
830
-
831
- if (!energy[i])
832
- continue;
833
-
834
- sta = iwl_mvm_sta_from_staid_rcu(mvm, i);
835
- if (!sta)
836
- continue;
837
- sta->avg_energy = energy[i];
838
- }
839
- rcu_read_unlock();
908
+ iwl_mvm_update_avg_energy(mvm, energy);
840909
841910 /*
842911 * Don't update in case the statistics are not cleared, since
843912 * we will end up counting twice the same airtime, once in TCM
844913 * request and once in statistics notification.
845914 */
846
- if (!(le32_to_cpu(flags) & IWL_STATISTICS_REPLY_FLG_CLEAR))
847
- return;
915
+ if (le32_to_cpu(flags) & IWL_STATISTICS_REPLY_FLG_CLEAR)
916
+ iwl_mvm_update_tcm_from_stats(mvm, air_time, bytes);
848917
849
- spin_lock(&mvm->tcm.lock);
850
- for (i = 0; i < NUM_MAC_INDEX_DRIVER; i++) {
851
- struct iwl_mvm_tcm_mac *mdata = &mvm->tcm.data[i];
852
- u32 airtime = le32_to_cpu(air_time[i]);
853
- u32 rx_bytes = le32_to_cpu(bytes[i]);
854
-
855
- mdata->uapsd_nonagg_detect.rx_bytes += rx_bytes;
856
- if (airtime) {
857
- /* re-init every time to store rate from FW */
858
- ewma_rate_init(&mdata->uapsd_nonagg_detect.rate);
859
- ewma_rate_add(&mdata->uapsd_nonagg_detect.rate,
860
- rx_bytes * 8 / airtime);
861
- }
862
-
863
- mdata->rx.airtime += airtime;
864
- }
865
- spin_unlock(&mvm->tcm.lock);
866918 }
867919
868920 void iwl_mvm_rx_statistics(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb)