qcacld-3.0: Add support for 11AX BSS color change
Add support for handling BSS color collision and select new BSS
color. Update beacon template and set new BSS color to FW.
Change-Id: If441990916753bdcf4daaded031e16f0460a0e8f
CRs-Fixed: 2039284
diff --git a/core/mac/src/include/parser_api.h b/core/mac/src/include/parser_api.h
index 4c05a4d..3289066 100644
--- a/core/mac/src/include/parser_api.h
+++ b/core/mac/src/include/parser_api.h
@@ -200,6 +200,9 @@
tSirQCNIE QCN_IE;
tDot11fIEvendor_he_cap vendor_he_cap;
tDot11fIEvendor_he_op vendor_he_op;
+#ifdef WLAN_FEATURE_11AX_BSS_COLOR
+ tDot11fIEbss_color_change vendor_he_bss_color_change;
+#endif
} tSirProbeRespBeacon, *tpSirProbeRespBeacon;
/* probe Request structure */
@@ -1012,6 +1015,19 @@
tDot11fIEvendor_he_cap *);
QDF_STATUS populate_dot11f_he_operation(tpAniSirGlobal , tpPESession ,
tDot11fIEvendor_he_op *);
+#ifdef WLAN_FEATURE_11AX_BSS_COLOR
+QDF_STATUS populate_dot11f_he_bss_color_change(tpAniSirGlobal mac_ctx,
+ tpPESession session,
+ tDot11fIEbss_color_change *bss_color);
+#else
+static inline QDF_STATUS populate_dot11f_he_bss_color_change(
+ tpAniSirGlobal mac_ctx,
+ tpPESession session,
+ tDot11fIEbss_color_change *bss_color)
+{
+ return QDF_STATUS_SUCCESS;
+}
+#endif
#else
static inline QDF_STATUS populate_dot11f_he_caps(tpAniSirGlobal mac_ctx,
tpPESession session, tDot11fIEvendor_he_cap *he_cap)
@@ -1025,5 +1041,12 @@
return QDF_STATUS_SUCCESS;
}
+static inline QDF_STATUS populate_dot11f_he_bss_color_change(
+ tpAniSirGlobal mac_ctx,
+ tpPESession session,
+ tDot11fIEbss_color_change *bss_color)
+{
+ return QDF_STATUS_SUCCESS;
+}
#endif
#endif /* __PARSE_H__ */
diff --git a/core/mac/src/include/sir_params.h b/core/mac/src/include/sir_params.h
index 707dc7a..205e5fd 100644
--- a/core/mac/src/include/sir_params.h
+++ b/core/mac/src/include/sir_params.h
@@ -773,6 +773,7 @@
#define PARAM_RIFS_MODE_CHANGED (1<<8)
#define PARAM_LSIG_TXOP_FULL_SUPPORT_CHANGED (1<<9)
#define PARAM_OBSS_MODE_CHANGED (1<<10)
+#define PARAM_BSS_COLOR_CHANGED (1 << 11)
#define PARAM_BEACON_UPDATE_MASK (PARAM_BCN_INTERVAL_CHANGED | \
PARAM_SHORT_PREAMBLE_CHANGED | \
PARAM_SHORT_SLOT_TIME_CHANGED | \
@@ -783,6 +784,7 @@
PARAM_NON_GF_DEVICES_PRESENT_CHANGED | \
PARAM_RIFS_MODE_CHANGED | \
PARAM_LSIG_TXOP_FULL_SUPPORT_CHANGED | \
- PARAM_OBSS_MODE_CHANGED)
+ PARAM_OBSS_MODE_CHANGED | \
+ PARAM_BSS_COLOR_CHANGED)
#endif
diff --git a/core/mac/src/pe/include/lim_session.h b/core/mac/src/pe/include/lim_session.h
index f54f5a2..33d3fc3 100644
--- a/core/mac/src/pe/include/lim_session.h
+++ b/core/mac/src/pe/include/lim_session.h
@@ -96,6 +96,16 @@
tSirResultCodes result_code;
} join_params;
+#ifdef WLAN_FEATURE_11AX_BSS_COLOR
+#define MAX_BSS_COLOR_VALUE 63
+#define TIME_BEACON_NOT_UPDATED 30000
+#define BSS_COLOR_SWITCH_COUNTDOWN 5
+struct bss_color_info {
+ qdf_time_t timestamp;
+ uint64_t seen_count;
+};
+#endif
+
typedef struct sPESession /* Added to Support BT-AMP */
{
/* To check session table is in use or free */
@@ -497,6 +507,11 @@
bool he_capable;
tDot11fIEvendor_he_cap he_config;
tDot11fIEvendor_he_op he_op;
+#ifdef WLAN_FEATURE_11AX_BSS_COLOR
+ tDot11fIEbss_color_change he_bss_color_change;
+ struct bss_color_info bss_color_info[MAX_BSS_COLOR_VALUE];
+ uint8_t bss_color_changing;
+#endif
#endif
} tPESession, *tpPESession;
diff --git a/core/mac/src/pe/lim/lim_send_sme_rsp_messages.c b/core/mac/src/pe/lim/lim_send_sme_rsp_messages.c
index dd1aa2e..8456e0a 100644
--- a/core/mac/src/pe/lim/lim_send_sme_rsp_messages.c
+++ b/core/mac/src/pe/lim/lim_send_sme_rsp_messages.c
@@ -2499,6 +2499,59 @@
return;
}
+#ifdef WLAN_FEATURE_11AX_BSS_COLOR
+/**
+ * lim_send_bss_color_change_ie_update() - update bss color change IE in
+ * beacon template
+ *
+ * @mac_ctx: pointer to global adapter context
+ * @session: session pointer
+ *
+ * Return: none
+ */
+static void
+lim_send_bss_color_change_ie_update(tpAniSirGlobal mac_ctx,
+ tpPESession session)
+{
+ /* Update the beacon template and send to FW */
+ if (sch_set_fixed_beacon_fields(mac_ctx, session) != eSIR_SUCCESS) {
+ pe_err("Unable to set BSS color change IE in beacon");
+ return;
+ }
+
+ /* Send update beacon template message */
+ lim_send_beacon_ind(mac_ctx, session);
+ pe_info("Updated BSS color change countdown = %d",
+ session->he_bss_color_change.countdown);
+}
+
+static void
+lim_handle_bss_color_change_ie(tpAniSirGlobal mac_ctx,
+ tpPESession session)
+{
+ /* handle bss color change IE */
+ if (LIM_IS_AP_ROLE(session) &&
+ session->he_op.bss_col_disabled) {
+ if (session->he_bss_color_change.countdown > 0) {
+ session->he_bss_color_change.countdown--;
+ } else {
+ session->bss_color_changing = 0;
+ if (session->he_bss_color_change.new_color != 0)
+ session->he_op.bss_col_disabled = 0;
+ }
+
+ lim_send_bss_color_change_ie_update(mac_ctx, session);
+ }
+}
+
+#else
+static void
+lim_handle_bss_color_change_ie(tpAniSirGlobal mac_ctx,
+ tpPESession session)
+{
+}
+#endif
+
/** -----------------------------------------------------------------
\brief lim_process_beacon_tx_success_ind() - This function is used
explicitely to handle successful beacon transmission indication
@@ -2592,5 +2645,8 @@
mmhMsg.bodyval = 0;
lim_sys_process_mmh_msg_api(pMac, &mmhMsg, ePROT);
}
+
+ lim_handle_bss_color_change_ie(pMac, psessionEntry);
+
return;
}
diff --git a/core/mac/src/pe/lim/lim_utils.c b/core/mac/src/pe/lim/lim_utils.c
index dee8558..852f8ae 100644
--- a/core/mac/src/pe/lim/lim_utils.c
+++ b/core/mac/src/pe/lim/lim_utils.c
@@ -7449,6 +7449,15 @@
vht_info->center_freq_seg1);
}
+#ifdef WLAN_FEATURE_11AX_BSS_COLOR
+void lim_log_he_bss_color(tpAniSirGlobal mac,
+ tDot11fIEbss_color_change *he_bss_color)
+{
+ pe_debug("countdown: %d, new_color: %d",
+ he_bss_color->countdown, he_bss_color->new_color);
+}
+#endif
+
void lim_update_sta_he_capable(tpAniSirGlobal mac,
tpAddStaParams add_sta_params, tpDphHashNode sta_ds,
tpPESession session_entry)
diff --git a/core/mac/src/pe/lim/lim_utils.h b/core/mac/src/pe/lim/lim_utils.h
index d7021a8..7f2b162 100644
--- a/core/mac/src/pe/lim/lim_utils.h
+++ b/core/mac/src/pe/lim/lim_utils.h
@@ -767,6 +767,20 @@
*/
void lim_log_he_op(tpAniSirGlobal mac, tDot11fIEvendor_he_op *he_ops);
+#ifdef WLAN_FEATURE_11AX_BSS_COLOR
+/**
+ * lim_log_he_bss_color() - Print HE bss color
+ * @mac: pointer to MAC context
+ * @he_bss_color: pointer to HE bss color
+ *
+ * Print HE bss color IE
+ *
+ * Return: None
+ */
+void lim_log_he_bss_color(tpAniSirGlobal mac,
+ tDot11fIEbss_color_change *he_bss_color);
+#endif
+
/**
* lim_log_he_cap() - Print HE capabilities
* @mac: pointer to MAC context
diff --git a/core/mac/src/pe/sch/sch_beacon_gen.c b/core/mac/src/pe/sch/sch_beacon_gen.c
index c023683..ad6ebf0 100644
--- a/core/mac/src/pe/sch/sch_beacon_gen.c
+++ b/core/mac/src/pe/sch/sch_beacon_gen.c
@@ -383,6 +383,8 @@
&bcn_2->vendor_he_cap);
populate_dot11f_he_operation(mac_ctx, session,
&bcn_2->vendor_he_op);
+ populate_dot11f_he_bss_color_change(mac_ctx, session,
+ &bcn_2->bss_color_change);
}
if (session->limSystemRole != eLIM_STA_IN_IBSS_ROLE)
diff --git a/core/mac/src/pe/sch/sch_beacon_process.c b/core/mac/src/pe/sch/sch_beacon_process.c
index dcfb0a1..1d162ba 100644
--- a/core/mac/src/pe/sch/sch_beacon_process.c
+++ b/core/mac/src/pe/sch/sch_beacon_process.c
@@ -835,6 +835,99 @@
}
}
+#ifdef WLAN_FEATURE_11AX_BSS_COLOR
+static void ap_update_bss_color_info(tpAniSirGlobal mac_ctx,
+ tpPESession session,
+ uint8_t bss_color)
+{
+ if (!session)
+ return;
+
+ if (bss_color < 1 || bss_color > 63) {
+ pe_warn("Invalid BSS color");
+ return;
+ }
+
+ session->bss_color_info[bss_color - 1].seen_count++;
+ session->bss_color_info[bss_color - 1].timestamp =
+ qdf_get_system_timestamp();
+}
+
+static uint8_t ap_get_new_bss_color(tpAniSirGlobal mac_ctx, tpPESession session)
+{
+ int i;
+ uint8_t new_bss_color;
+ struct bss_color_info color_info;
+ qdf_time_t cur_timestamp;
+
+ if (!session)
+ return 0;
+
+ color_info = session->bss_color_info[0];
+ new_bss_color = 0;
+ cur_timestamp = qdf_get_system_timestamp();
+ for (i = 1; i < MAX_BSS_COLOR_VALUE; i++) {
+ if (session->bss_color_info[i].seen_count == 0) {
+ new_bss_color = i + 1;
+ return new_bss_color;
+ }
+
+ if (color_info.seen_count >
+ session->bss_color_info[i].seen_count &&
+ (cur_timestamp - session->bss_color_info[i].
+ timestamp) > TIME_BEACON_NOT_UPDATED) {
+ color_info = session->bss_color_info[i];
+ new_bss_color = i + 1;
+ }
+ }
+ pe_debug("new bss color: %d", new_bss_color);
+ return new_bss_color;
+}
+
+static void sch_check_bss_color_ie(tpAniSirGlobal mac_ctx,
+ tpPESession ap_session,
+ tSchBeaconStruct *bcn,
+ tUpdateBeaconParams *bcn_prm)
+{
+ /* check bss color in the beacon */
+ if (ap_session->he_op.present && !ap_session->he_op.bss_color) {
+ if (bcn->vendor_he_op.present &&
+ (bcn->vendor_he_op.bss_color ==
+ ap_session->he_op.bss_color)) {
+ ap_session->he_op.bss_col_disabled = 1;
+ bcn_prm->paramChangeBitmap |=
+ PARAM_BSS_COLOR_CHANGED;
+ ap_session->he_bss_color_change.countdown =
+ BSS_COLOR_SWITCH_COUNTDOWN;
+ ap_session->he_bss_color_change.new_color =
+ ap_get_new_bss_color(mac_ctx,
+ ap_session);
+ ap_session->he_op.bss_color = ap_session->
+ he_bss_color_change.new_color;
+ WMI_HEOPS_COLOR_SET(bcn_prm->he_ops,
+ ap_session->he_op.bss_color);
+ WMI_HEOPS_BSSCOLORDISABLE_SET(bcn_prm->he_ops,
+ ap_session->he_op.bss_col_disabled);
+ ap_session->bss_color_changing = 1;
+ } else {
+ /* update info for the bss color */
+ if (bcn->vendor_he_op.present)
+ ap_update_bss_color_info(mac_ctx,
+ ap_session,
+ bcn->vendor_he_op.bss_color);
+ }
+ }
+}
+
+#else
+static void sch_check_bss_color_ie(tpAniSirGlobal mac_ctx,
+ tpPESession ap_session,
+ tSchBeaconStruct *bcn,
+ tUpdateBeaconParams *bcn_prm)
+{
+}
+#endif
+
/**
* sch_beacon_process() - process the beacon frame
* @mac_ctx: mac global context
@@ -885,6 +978,9 @@
continue;
bcn_prm.bssIdx = ap_session->bssIdx;
+
+ sch_check_bss_color_ie(mac_ctx, ap_session, &bcn, &bcn_prm);
+
if (ap_session->gLimProtectionControl !=
WNI_CFG_FORCE_POLICY_PROTECTION_DISABLE)
ap_beacon_process(mac_ctx, rx_pkt_info,
diff --git a/core/mac/src/sys/legacy/src/utils/src/parser_api.c b/core/mac/src/sys/legacy/src/utils/src/parser_api.c
index 8d0c060..a8e3c83 100644
--- a/core/mac/src/sys/legacy/src/utils/src/parser_api.c
+++ b/core/mac/src/sys/legacy/src/utils/src/parser_api.c
@@ -6010,6 +6010,34 @@
return QDF_STATUS_SUCCESS;
}
+
+#ifdef WLAN_FEATURE_11AX_BSS_COLOR
+/**
+ * populate_dot11f_he_bss_color_change() - pouldate HE BSS color change IE
+ * @mac_ctx: Global MAC context
+ * @session: PE session
+ * @he_bss_color: pointer to HE BSS color change IE
+ *
+ * Populdate the HE BSS color change IE based on the session.
+ */
+QDF_STATUS populate_dot11f_he_bss_color_change(tpAniSirGlobal mac_ctx,
+ tpPESession session,
+ tDot11fIEbss_color_change *he_bss_color)
+{
+ if (!session->bss_color_changing) {
+ he_bss_color->present = 0;
+ return QDF_STATUS_SUCCESS;
+ }
+
+ he_bss_color->present = 1;
+ he_bss_color->countdown = session->he_bss_color_change.countdown;
+ he_bss_color->new_color = session->he_bss_color_change.new_color;
+
+ lim_log_he_bss_color(mac_ctx, he_bss_color);
+
+ return QDF_STATUS_SUCCESS;
+}
+#endif
#endif
/* parser_api.c ends here. */