Search Linux Wireless

[RFC v1 202/256] cl8k: add tx/agg_tx_report.c

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Viktor Barna <viktor.barna@xxxxxxxxxx>

(Part of the split. Please, take a look at the cover letter for more
details).

Signed-off-by: Viktor Barna <viktor.barna@xxxxxxxxxx>
---
 .../wireless/celeno/cl8k/tx/agg_tx_report.c   | 196 ++++++++++++++++++
 1 file changed, 196 insertions(+)
 create mode 100644 drivers/net/wireless/celeno/cl8k/tx/agg_tx_report.c

diff --git a/drivers/net/wireless/celeno/cl8k/tx/agg_tx_report.c b/drivers/net/wireless/celeno/cl8k/tx/agg_tx_report.c
new file mode 100644
index 000000000000..478e5e734f08
--- /dev/null
+++ b/drivers/net/wireless/celeno/cl8k/tx/agg_tx_report.c
@@ -0,0 +1,196 @@
+// SPDX-License-Identifier: MIT
+/* Copyright(c) 2019-2021, Celeno Communications Ltd. */
+
+#include "tx/agg_tx_report.h"
+#include "stats.h"
+#include "rate_ctrl.h"
+#include "wrs/wrs_api.h"
+#include "data_rates.h"
+
+static bool is_same_rate(struct cl_agg_tx_report *agg_report, struct cl_wrs_tx_params *tx_params)
+{
+       union cl_rate_ctrl_info rate_ctrl_info = {.word = agg_report->rate_cntrl_info};
+       u8 mcs = U8_MAX, nss = U8_MAX;
+
+       if (agg_report->bw_requested != tx_params->bw ||
+           rate_ctrl_info.field.gi != tx_params->gi)
+               return false;
+
+       cl_rate_ctrl_parse(&rate_ctrl_info, &nss, &mcs);
+
+       return ((mcs == tx_params->mcs) && (nss == tx_params->nss));
+}
+
+static void sync_tx_rate(struct cl_hw *cl_hw, struct cl_sta *cl_sta,
+                        struct cl_agg_tx_report *agg_report,
+                        struct cl_wrs_info *wrs_info, struct cl_wrs_params *wrs_params)
+{
+       if (!agg_report->is_fallback && is_same_rate(agg_report, &wrs_params->tx_params)) {
+               cl_wrs_api_rate_sync(cl_hw, cl_sta, wrs_params);
+
+               wrs_info->synced = true;
+               wrs_info->quick_rate_check = true;
+               wrs_info->quick_rate_agg_cntr = 0;
+               wrs_info->quick_rate_pkt_cntr = 0;
+       } else {
+               wrs_info->sync_attempts++;
+       }
+}
+
+static void ba_not_received_handler(struct cl_hw *cl_hw, struct cl_wrs_info *wrs_info,
+                                   struct cl_agg_tx_report *agg_report)
+{
+       /* Ignore 'BA not received' if station is in power-save or if RTS limit was reached */
+       if (agg_report->is_sta_ps || agg_report->is_rts_retry_limit_reached)
+               return;
+
+       /* Count number of consecutive 'BA not received' */
+       wrs_info->ba_not_rcv_consecutive++;
+
+       /* Save longest sequence of consecutive 'BA not received' */
+       if (wrs_info->ba_not_rcv_consecutive > wrs_info->ba_not_rcv_consecutive_max)
+               wrs_info->ba_not_rcv_consecutive_max = wrs_info->ba_not_rcv_consecutive;
+
+       if (cl_hw->wrs_db.ba_not_rcv_collision_filter) {
+               /*
+                * First 'BA not received' - might just be a collision.
+                * Don't add fail to ba_not_rcv but keep aside.
+                * Second consecutive 'BA not received' - not likely to be a collisions.
+                * Add fail to ba_not_rcv including previous fail that was kept aside.
+                * More than two consecutive 'BA not received' - very unlikely to be a collisions.
+                * Add fail to ba_not_rcv.
+                */
+               if (wrs_info->ba_not_rcv_consecutive == 1)
+                       wrs_info->tx_fail_prev = agg_report->fail;
+               else if (wrs_info->ba_not_rcv_consecutive == 2)
+                       wrs_info->ba_not_rcv += (agg_report->fail + wrs_info->tx_fail_prev);
+               else
+                       wrs_info->ba_not_rcv += agg_report->fail;
+       } else {
+               wrs_info->ba_not_rcv += agg_report->fail;
+       }
+}
+
+void cl_agg_tx_report_handler(struct cl_hw *cl_hw, struct cl_sta *cl_sta,
+                             struct cl_agg_tx_report *agg_report)
+{
+       struct cl_wrs_info *wrs_info = &cl_sta->wrs_info;
+       struct cl_wrs_params *wrs_params = &cl_sta->wrs_sta.su_params;
+       bool skip_epr_update = false;
+       union cl_rate_ctrl_info rate_ctrl_info = {.word = agg_report->rate_cntrl_info};
+
+       /* Retry_count for cl_wlan */
+       cl_sta->retry_count += agg_report->success_after_retry;
+
+       /*
+        * In case of big packets (4300 in VHT and 5400 in HE) and low
+        * rate (BW 20, NSS 1, MCS 0), firmware will increase rate to MCS 1,
+        * and give an indication to driver (set rate_fix_mcs1 in cl_agg_tx_report).
+        * WRS should also move to MCS 1, and give the maximum time
+        * penalty time from MCS 0 toMCS 1.
+        */
+       if (agg_report->rate_fix_mcs1 && !agg_report->is_fallback)
+               if (cl_wrs_api_up_mcs1(cl_hw, cl_sta, wrs_params))
+                       return;
+
+       /* WRS sync mechanism */
+       if (!wrs_info->synced)
+               sync_tx_rate(cl_hw, cl_sta, agg_report, wrs_info, wrs_params);
+
+       if (agg_report->bf && cl_sta->bf_db.is_on && !cl_sta->bf_db.synced) {
+               cl_sta->bf_db.synced = true;
+               /* Resetting the WRS UP weights */
+               cl_wrs_api_beamforming_sync(cl_hw, cl_sta);
+       }
+
+       if (agg_report->ba_not_received) {
+               ba_not_received_handler(cl_hw, wrs_info, agg_report);
+       } else {
+               if (!skip_epr_update)
+                       wrs_info->tx_fail += agg_report->fail;
+
+               wrs_info->ba_not_rcv_consecutive = 0;
+       }
+
+       if (!skip_epr_update) {
+               u8 mcs = 0, nss = 0, bw = 0;
+               u16 data_rate = 0;
+
+               switch (agg_report->bw_requested) {
+               case CHNL_BW_160:
+                       bw = (cl_hw->wrs_db.adjacent_interference20 ||
+                             cl_hw->wrs_db.adjacent_interference40 ||
+                             cl_hw->wrs_db.adjacent_interference80) ?
+                               rate_ctrl_info.field.bw : agg_report->bw_requested;
+                       break;
+               case CHNL_BW_80:
+                       bw = (cl_hw->wrs_db.adjacent_interference20 ||
+                             cl_hw->wrs_db.adjacent_interference40) ?
+                               rate_ctrl_info.field.bw : agg_report->bw_requested;
+                       break;
+               case CHNL_BW_40:
+                       bw = cl_hw->wrs_db.adjacent_interference20 ?
+                               rate_ctrl_info.field.bw : agg_report->bw_requested;
+                       break;
+               case CHNL_BW_20:
+                       bw = agg_report->bw_requested;
+                       break;
+               }
+
+               cl_rate_ctrl_parse(&rate_ctrl_info, &nss, &mcs);
+
+               data_rate = cl_data_rates_get_x10(rate_ctrl_info.field.format_mod,
+                                                 bw,
+                                                 nss,
+                                                 mcs,
+                                                 rate_ctrl_info.field.gi);
+
+               wrs_info->epr_acc += ((u64)agg_report->success * data_rate);
+               wrs_info->tx_success += agg_report->success;
+       }
+
+       if (cl_hw->wrs_db.quick_down_en && wrs_info->quick_rate_check) {
+               if (is_same_rate(agg_report, &wrs_params->tx_params)) {
+                       wrs_info->quick_rate_agg_cntr++;
+                       wrs_info->quick_rate_pkt_cntr += (agg_report->success + agg_report->fail);
+
+                       if (wrs_info->quick_rate_agg_cntr >= cl_hw->wrs_db.quick_down_agg_thr &&
+                           wrs_info->quick_rate_pkt_cntr > cl_hw->wrs_db.quick_down_pkt_thr) {
+                               wrs_info->quick_rate_check = false;
+                               cl_wrs_api_quick_down_check(cl_hw, cl_sta, wrs_params);
+                       }
+               }
+       }
+}
+
+void cl_agg_tx_report_simulate_for_single(struct cl_hw *cl_hw, struct cl_sta *cl_sta,
+                                         struct cl_hw_tx_status *status)
+{
+       /* Assign statistics struct */
+       struct cl_agg_tx_report agg_report;
+       union cl_rate_ctrl_info rate_ctrl_info;
+
+       memset(&agg_report, 0, sizeof(struct cl_agg_tx_report));
+
+       agg_report.bf = status->bf;
+       agg_report.success = status->frm_successful;
+       agg_report.fail = status->num_mpdu_retries + (status->frm_successful ? 0 : 1);
+       agg_report.success_after_retry =
+               (status->frm_successful && status->num_mpdu_retries) ? 1 : 0;
+       agg_report.retry_limit_reached = !status->frm_successful ? 1 : 0;
+       agg_report.success_more_one_retry =
+               (status->frm_successful && (status->num_mpdu_retries > 1)) ? 1 : 0;
+       agg_report.sta_idx = cl_sta->sta_idx;
+       agg_report.bw_requested = status->bw_requested;
+
+       rate_ctrl_info.field.bw = status->bw_transmitted;
+       rate_ctrl_info.field.gi = status->gi;
+       rate_ctrl_info.field.format_mod = status->format_mod;
+       rate_ctrl_info.field.mcs_index = status->mcs_index;
+
+       cl_rate_ctrl_convert(&rate_ctrl_info);
+
+       agg_report.rate_cntrl_info = rate_ctrl_info.word;
+       cl_agg_tx_report_handler(cl_hw, cl_sta, &agg_report);
+       cl_stats_update_tx_single(cl_hw, cl_sta, &agg_report);
+}
--
2.30.0

________________________________
The information transmitted is intended only for the person or entity to which it is addressed and may contain confidential and/or privileged material. Any retransmission, dissemination, copying or other use of, or taking of any action in reliance upon this information is prohibited. If you received this in error, please contact the sender and delete the material from any computer. Nothing contained herein shall be deemed as a representation, warranty or a commitment by Celeno. No warranties are expressed or implied, including, but not limited to, any implied warranties of non-infringement, merchantability and fitness for a particular purpose.
________________________________





[Index of Archives]     [Linux Host AP]     [ATH6KL]     [Linux Wireless Personal Area Network]     [Linux Bluetooth]     [Wireless Regulations]     [Linux Netdev]     [Kernel Newbies]     [Linux Kernel]     [IDE]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite Hiking]     [MIPS Linux]     [ARM Linux]     [Linux RAID]

  Powered by Linux