|
@@ -37,6 +37,7 @@
|
|
|
#include "target_if.h"
|
|
|
#include "wlan_vdev_mgr_tgt_if_tx_api.h"
|
|
|
#include "wmi_unified_vdev_api.h"
|
|
|
+#include "../../core/src/wlan_cp_stats_defs.h"
|
|
|
|
|
|
/* quota in milliseconds */
|
|
|
#define MCC_DUTY_CYCLE 70
|
|
@@ -7025,6 +7026,192 @@ static QDF_STATUS wlan_mlme_update_ch_width(struct wlan_objmgr_vdev *vdev,
|
|
|
return QDF_STATUS_SUCCESS;
|
|
|
}
|
|
|
|
|
|
+static uint32_t
|
|
|
+wlan_mlme_get_vht_rate_flags(enum phy_ch_width ch_width)
|
|
|
+{
|
|
|
+ uint32_t rate_flags = 0;
|
|
|
+
|
|
|
+ if (ch_width == CH_WIDTH_80P80MHZ || ch_width == CH_WIDTH_160MHZ)
|
|
|
+ rate_flags |= TX_RATE_VHT160 | TX_RATE_VHT80 | TX_RATE_VHT40 |
|
|
|
+ TX_RATE_VHT20;
|
|
|
+ if (ch_width == CH_WIDTH_80MHZ)
|
|
|
+ rate_flags |= TX_RATE_VHT80 | TX_RATE_VHT40 | TX_RATE_VHT20;
|
|
|
+ else if (ch_width)
|
|
|
+ rate_flags |= TX_RATE_VHT40 | TX_RATE_VHT20;
|
|
|
+ else
|
|
|
+ rate_flags |= TX_RATE_VHT20;
|
|
|
+ return rate_flags;
|
|
|
+}
|
|
|
+
|
|
|
+static uint32_t wlan_mlme_get_ht_rate_flags(enum phy_ch_width ch_width)
|
|
|
+{
|
|
|
+ uint32_t rate_flags = 0;
|
|
|
+
|
|
|
+ if (ch_width)
|
|
|
+ rate_flags |= TX_RATE_HT40 | TX_RATE_HT20;
|
|
|
+ else
|
|
|
+ rate_flags |= TX_RATE_HT20;
|
|
|
+
|
|
|
+ return rate_flags;
|
|
|
+}
|
|
|
+
|
|
|
+#ifdef WLAN_FEATURE_11BE
|
|
|
+static uint32_t
|
|
|
+wlan_mlme_get_eht_rate_flags(enum phy_ch_width ch_width)
|
|
|
+{
|
|
|
+ uint32_t rate_flags = 0;
|
|
|
+
|
|
|
+ if (ch_width == CH_WIDTH_320MHZ)
|
|
|
+ rate_flags |= TX_RATE_EHT320 | TX_RATE_EHT160 |
|
|
|
+ TX_RATE_EHT80 | TX_RATE_EHT40 | TX_RATE_EHT20;
|
|
|
+ else if (ch_width == CH_WIDTH_160MHZ || ch_width == CH_WIDTH_80P80MHZ)
|
|
|
+ rate_flags |= TX_RATE_EHT160 | TX_RATE_EHT80 | TX_RATE_EHT40 |
|
|
|
+ TX_RATE_EHT20;
|
|
|
+ else if (ch_width == CH_WIDTH_80MHZ)
|
|
|
+ rate_flags |= TX_RATE_EHT80 | TX_RATE_EHT40 | TX_RATE_EHT20;
|
|
|
+ else if (ch_width)
|
|
|
+ rate_flags |= TX_RATE_EHT40 | TX_RATE_EHT20;
|
|
|
+ else
|
|
|
+ rate_flags |= TX_RATE_EHT20;
|
|
|
+
|
|
|
+ return rate_flags;
|
|
|
+}
|
|
|
+
|
|
|
+static QDF_STATUS
|
|
|
+wlan_mlme_set_bss_rate_flags_eht(uint32_t *rate_flags, uint8_t eht_present,
|
|
|
+ enum phy_ch_width ch_width)
|
|
|
+{
|
|
|
+ if (!eht_present)
|
|
|
+ return QDF_STATUS_E_NOSUPPORT;
|
|
|
+
|
|
|
+ *rate_flags |= wlan_mlme_get_eht_rate_flags(ch_width);
|
|
|
+
|
|
|
+ return QDF_STATUS_SUCCESS;
|
|
|
+}
|
|
|
+#else
|
|
|
+static inline QDF_STATUS
|
|
|
+wlan_mlme_set_bss_rate_flags_eht(uint32_t *rate_flags, uint8_t eht_present,
|
|
|
+ enum phy_ch_width ch_width)
|
|
|
+{
|
|
|
+ return QDF_STATUS_E_NOSUPPORT;
|
|
|
+}
|
|
|
+#endif
|
|
|
+
|
|
|
+#ifdef WLAN_FEATURE_11AX
|
|
|
+static uint32_t wlan_mlme_get_he_rate_flags(enum phy_ch_width ch_width)
|
|
|
+{
|
|
|
+ uint32_t rate_flags = 0;
|
|
|
+
|
|
|
+ if (ch_width == CH_WIDTH_160MHZ ||
|
|
|
+ ch_width == CH_WIDTH_80P80MHZ)
|
|
|
+ rate_flags |= TX_RATE_HE160 | TX_RATE_HE80 | TX_RATE_HE40 |
|
|
|
+ TX_RATE_HE20;
|
|
|
+ else if (ch_width == CH_WIDTH_80MHZ)
|
|
|
+ rate_flags |= TX_RATE_HE80 | TX_RATE_HE40 | TX_RATE_HE20;
|
|
|
+ else if (ch_width)
|
|
|
+ rate_flags |= TX_RATE_HE40 | TX_RATE_HE20;
|
|
|
+ else
|
|
|
+ rate_flags |= TX_RATE_HE20;
|
|
|
+
|
|
|
+ return rate_flags;
|
|
|
+}
|
|
|
+
|
|
|
+static QDF_STATUS wlan_mlme_set_bss_rate_flags_he(uint32_t *rate_flags,
|
|
|
+ uint8_t he_present,
|
|
|
+ enum phy_ch_width ch_width)
|
|
|
+{
|
|
|
+ if (!he_present)
|
|
|
+ return QDF_STATUS_E_NOSUPPORT;
|
|
|
+
|
|
|
+ *rate_flags |= wlan_mlme_get_he_rate_flags(ch_width);
|
|
|
+
|
|
|
+ return QDF_STATUS_SUCCESS;
|
|
|
+}
|
|
|
+
|
|
|
+#else
|
|
|
+static inline QDF_STATUS
|
|
|
+wlan_mlme_set_bss_rate_flags_he(uint32_t *rate_flags,
|
|
|
+ uint8_t he_present,
|
|
|
+ enum phy_ch_width ch_width)
|
|
|
+{
|
|
|
+ return QDF_STATUS_E_NOSUPPORT;
|
|
|
+}
|
|
|
+#endif
|
|
|
+
|
|
|
+static QDF_STATUS
|
|
|
+wlan_mlme_cp_stats_set_rate_flags(struct wlan_objmgr_vdev *vdev,
|
|
|
+ uint32_t flags)
|
|
|
+{
|
|
|
+ struct vdev_mc_cp_stats *vdev_mc_stats;
|
|
|
+ struct vdev_cp_stats *vdev_cp_stats_priv;
|
|
|
+
|
|
|
+ vdev_cp_stats_priv = wlan_cp_stats_get_vdev_stats_obj(vdev);
|
|
|
+ if (!vdev_cp_stats_priv) {
|
|
|
+ cp_stats_err("vdev cp stats object is null");
|
|
|
+ return QDF_STATUS_E_NULL_VALUE;
|
|
|
+ }
|
|
|
+
|
|
|
+ wlan_cp_stats_vdev_obj_lock(vdev_cp_stats_priv);
|
|
|
+ vdev_mc_stats = vdev_cp_stats_priv->vdev_stats;
|
|
|
+ vdev_mc_stats->tx_rate_flags = flags;
|
|
|
+ wlan_cp_stats_vdev_obj_unlock(vdev_cp_stats_priv);
|
|
|
+
|
|
|
+ return QDF_STATUS_SUCCESS;
|
|
|
+}
|
|
|
+
|
|
|
+QDF_STATUS
|
|
|
+wlan_mlme_update_bss_rate_flags(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id,
|
|
|
+ enum phy_ch_width cw, uint8_t eht_present,
|
|
|
+ uint8_t he_present, uint8_t vht_present,
|
|
|
+ uint8_t ht_present)
|
|
|
+{
|
|
|
+ uint32_t *rate_flags;
|
|
|
+ struct vdev_mlme_obj *vdev_mlme;
|
|
|
+ struct wlan_objmgr_vdev *vdev;
|
|
|
+ QDF_STATUS status;
|
|
|
+
|
|
|
+ if (!eht_present && !he_present && !vht_present && !ht_present)
|
|
|
+ return QDF_STATUS_E_INVAL;
|
|
|
+
|
|
|
+ vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
|
|
|
+ WLAN_HDD_ID_OBJ_MGR);
|
|
|
+ if (!vdev) {
|
|
|
+ mlme_debug("vdev: %d vdev not found", vdev_id);
|
|
|
+ return QDF_STATUS_E_INVAL;
|
|
|
+ }
|
|
|
+
|
|
|
+ vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev);
|
|
|
+ if (!vdev_mlme) {
|
|
|
+ mlme_debug("vdev: %d mlme obj not found", vdev_id);
|
|
|
+ wlan_objmgr_vdev_release_ref(vdev, WLAN_HDD_ID_OBJ_MGR);
|
|
|
+ return QDF_STATUS_E_INVAL;
|
|
|
+ }
|
|
|
+
|
|
|
+ rate_flags = &vdev_mlme->mgmt.rate_info.rate_flags;
|
|
|
+ *rate_flags = 0;
|
|
|
+
|
|
|
+ status = wlan_mlme_set_bss_rate_flags_eht(rate_flags, eht_present, cw);
|
|
|
+ if (QDF_IS_STATUS_ERROR(status)) {
|
|
|
+ status = wlan_mlme_set_bss_rate_flags_he(rate_flags,
|
|
|
+ he_present, cw);
|
|
|
+ if (QDF_IS_STATUS_ERROR(status)) {
|
|
|
+ if (vht_present)
|
|
|
+ *rate_flags = wlan_mlme_get_vht_rate_flags(cw);
|
|
|
+ else if (ht_present)
|
|
|
+ *rate_flags |= wlan_mlme_get_ht_rate_flags(cw);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ mlme_debug("vdev:%d, eht:%u, he:%u, vht:%u, ht:%u, flag:%x, cw:%d",
|
|
|
+ vdev_id, eht_present, he_present, vht_present, ht_present,
|
|
|
+ *rate_flags, cw);
|
|
|
+
|
|
|
+ status = wlan_mlme_cp_stats_set_rate_flags(vdev, *rate_flags);
|
|
|
+
|
|
|
+ wlan_objmgr_vdev_release_ref(vdev, WLAN_HDD_ID_OBJ_MGR);
|
|
|
+ return status;
|
|
|
+}
|
|
|
+
|
|
|
QDF_STATUS
|
|
|
wlan_mlme_send_ch_width_update_with_notify(struct wlan_objmgr_psoc *psoc,
|
|
|
struct wlan_objmgr_vdev *vdev,
|