Browse Source

qcacmn: Configure roam trigger bitmap to firmware

Userspace may configure the roam trigger bitmap to WLAN host
driver to enable particular roam trigger reasons. Convert the
bitmap to the format of firmware trigger reason bitmap and send
to firmware.

Change-Id: I9fc78c180bd25c995dfd380f80e52e3eb302fce3
CRs-Fixed: 2507611
Srinivas Dasari 5 years ago
parent
commit
de39f3fc40

+ 3 - 0
wmi/inc/wmi_unified_priv.h

@@ -1999,6 +1999,9 @@ QDF_STATUS (*extract_oem_response_param)
 QDF_STATUS (*extract_hw_mode_resp_event)(wmi_unified_t wmi_handle,
 					 void *evt_buf, uint32_t *cmd_status);
 
+QDF_STATUS (*send_set_roam_trigger_cmd)(wmi_unified_t wmi_handle,
+					uint32_t vdev_id,
+					uint32_t trigger_bitmap);
 };
 
 /* Forward declartion for psoc*/

+ 13 - 0
wmi/inc/wmi_unified_roam_api.h

@@ -381,4 +381,17 @@ QDF_STATUS wmi_unified_invoke_neighbor_report_cmd(
 			wmi_unified_t wmi_handle,
 			struct wmi_invoke_neighbor_report_params *params);
 
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+/**
+ * wmi_unified_set_roam_triggers() - send roam trigger bitmap
+ * @wmi_handle: wmi handle
+ * @triggers: Roam trigger bitmap params as defined @roam_control_trigger_reason
+ *
+ * This function passes the roam trigger bitmap to fw
+ *
+ * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure
+ */
+QDF_STATUS wmi_unified_set_roam_triggers(wmi_unified_t wmi_handle,
+					 struct roam_triggers *triggers);
+#endif
 #endif /* _WMI_UNIFIED_ROAM_API_H_ */

+ 46 - 0
wmi/inc/wmi_unified_roam_param.h

@@ -761,4 +761,50 @@ struct wmi_invoke_neighbor_report_params {
 	struct mac_ssid ssid;
 };
 
+/**
+ * enum roam_control_trigger_reason - Bitmap of roaming triggers
+ *
+ * @ROAM_TRIGGER_REASON_PER: Set if the roam has to be triggered based on
+ *     a bad packet error rates (PER).
+ * @ROAM_TRIGGER_REASON_BEACON_MISS: Set if the roam has to be triggered
+ *     based on beacon misses from the connected AP.
+ * @ROAM_TRIGGER_REASON_POOR_RSSI: Set if the roam has to be triggered
+ *     due to poor RSSI of the connected AP.
+ * @ROAM_TRIGGER_REASON_BETTER_RSSI: Set if the roam has to be triggered
+ *     upon finding a BSSID with a better RSSI than the connected BSSID.
+ *     Here the RSSI of the current BSSID need not be poor.
+ * @ROAM_TRIGGER_REASON_PERIODIC: Set if the roam has to be triggered
+ *     by triggering a periodic scan to find a better AP to roam.
+ * @ROAM_TRIGGER_REASON_DENSE: Set if the roam has to be triggered
+ *     when the connected channel environment is too noisy/congested.
+ * @ROAM_TRIGGER_REASON_BTM: Set if the roam has to be triggered
+ *     when BTM Request frame is received from the connected AP.
+ * @ROAM_TRIGGER_REASON_BSS_LOAD: Set if the roam has to be triggered
+ *     when the channel utilization is goes above the configured threshold.
+ *
+ * Set the corresponding roam trigger reason bit to consider it for roam
+ * trigger.
+ */
+enum roam_control_trigger_reason {
+	ROAM_CONTROL_TRIGGER_REASON_PER			= 1 << 0,
+	ROAM_CONTROL_TRIGGER_REASON_BEACON_MISS		= 1 << 1,
+	ROAM_CONTROL_TRIGGER_REASON_POOR_RSSI		= 1 << 2,
+	ROAM_CONTROL_TRIGGER_REASON_BETTER_RSSI		= 1 << 3,
+	ROAM_CONTROL_TRIGGER_REASON_PERIODIC		= 1 << 4,
+	ROAM_CONTROL_TRIGGER_REASON_DENSE		= 1 << 5,
+	ROAM_CONTROL_TRIGGER_REASON_BTM			= 1 << 6,
+	ROAM_CONTROL_TRIGGER_REASON_BSS_LOAD		= 1 << 7,
+};
+
+/**
+ * struct roam_triggers - vendor configured roam triggers
+ * @vdev_id: vdev id
+ * @trigger_bitmap: vendor configured roam trigger bitmap as
+ *		    defined @enum roam_control_trigger_reason
+ */
+struct roam_triggers {
+	uint32_t vdev_id;
+	uint32_t trigger_bitmap;
+};
+
 #endif /* _WMI_UNIFIED_ROAM_PARAM_H_ */

+ 11 - 0
wmi/src/wmi_unified_roam_api.c

@@ -320,3 +320,14 @@ QDF_STATUS wmi_unified_invoke_neighbor_report_cmd(
 	return QDF_STATUS_E_FAILURE;
 }
 
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+QDF_STATUS wmi_unified_set_roam_triggers(wmi_unified_t wmi_handle,
+					 struct roam_triggers *triggers)
+{
+	if (wmi_handle->ops->send_set_roam_trigger_cmd)
+		return wmi_handle->ops->send_set_roam_trigger_cmd(wmi_handle,
+				triggers->vdev_id, triggers->trigger_bitmap);
+
+	return QDF_STATUS_E_FAILURE;
+}
+#endif

+ 124 - 0
wmi/src/wmi_unified_roam_tlv.c

@@ -2435,6 +2435,121 @@ send_roam_preauth_status_tlv(wmi_unified_t wmi_handle,
 
 	return QDF_STATUS_SUCCESS;
 }
+
+/**
+ * convert_control_roam_trigger_reason_bitmap() - Convert roam trigger bitmap
+ *
+ * @trigger_reason_bitmap: Roam trigger reason bitmap received from upper layers
+ *
+ * Converts the controlled roam trigger reason bitmap of
+ * type @roam_control_trigger_reason to firmware trigger
+ * reason bitmap as defined in
+ * trigger_reason_bitmask @wmi_roam_enable_disable_trigger_reason_fixed_param
+ *
+ * Return: trigger_reason_bitmask as defined in
+ *	   wmi_roam_enable_disable_trigger_reason_fixed_param
+ */
+static uint32_t
+convert_control_roam_trigger_reason_bitmap(uint32_t trigger_reason_bitmap)
+{
+	uint32_t fw_trigger_bitmap = 0, all_bitmap;
+
+	/* Enable the complete trigger bitmap when all bits are set in
+	 * the control config bitmap
+	 */
+	all_bitmap = (ROAM_CONTROL_TRIGGER_REASON_BSS_LOAD << 1) - 1;
+	if (trigger_reason_bitmap == all_bitmap)
+		return (BIT(WMI_ROAM_TRIGGER_REASON_MAX) - 1);
+
+	if (trigger_reason_bitmap & ROAM_CONTROL_TRIGGER_REASON_PER)
+		fw_trigger_bitmap |= BIT(WMI_ROAM_TRIGGER_REASON_PER);
+
+	if (trigger_reason_bitmap & ROAM_CONTROL_TRIGGER_REASON_BEACON_MISS)
+		fw_trigger_bitmap |= BIT(WMI_ROAM_TRIGGER_REASON_BMISS);
+
+	if (trigger_reason_bitmap & ROAM_CONTROL_TRIGGER_REASON_POOR_RSSI)
+		fw_trigger_bitmap |= BIT(WMI_ROAM_TRIGGER_REASON_LOW_RSSI);
+
+	if (trigger_reason_bitmap & ROAM_CONTROL_TRIGGER_REASON_BETTER_RSSI)
+		fw_trigger_bitmap |= BIT(WMI_ROAM_TRIGGER_REASON_HIGH_RSSI);
+
+	if (trigger_reason_bitmap & ROAM_CONTROL_TRIGGER_REASON_PERIODIC)
+		fw_trigger_bitmap |= BIT(WMI_ROAM_TRIGGER_REASON_PERIODIC);
+
+	if (trigger_reason_bitmap & ROAM_CONTROL_TRIGGER_REASON_DENSE)
+		fw_trigger_bitmap |= BIT(WMI_ROAM_TRIGGER_REASON_DENSE);
+
+	if (trigger_reason_bitmap & ROAM_CONTROL_TRIGGER_REASON_BTM)
+		fw_trigger_bitmap |= BIT(WMI_ROAM_TRIGGER_REASON_BTM);
+
+	if (trigger_reason_bitmap & ROAM_CONTROL_TRIGGER_REASON_BSS_LOAD)
+		fw_trigger_bitmap |= BIT(WMI_ROAM_TRIGGER_REASON_BSS_LOAD);
+
+	return fw_trigger_bitmap;
+}
+
+/**
+ * get_internal_mandatory_roam_triggers() - Internal triggers to be added
+ *
+ * Return: the bitmap of mandatory triggers to be sent to firmware but not given
+ * by user.
+ */
+static uint32_t
+get_internal_mandatory_roam_triggers(void)
+{
+	return BIT(WMI_ROAM_TRIGGER_REASON_FORCED);
+}
+
+/**
+ * send_set_roam_trigger_cmd_tlv() - send set roam triggers to fw
+ *
+ * @wmi_handle: wmi handle
+ * @vdev_id: vdev id
+ * @trigger_bitmap: roam trigger bitmap to be enabled
+ *
+ * Send WMI_ROAM_ENABLE_DISABLE_TRIGGER_REASON_CMDID to fw.
+ *
+ * Return: QDF_STATUS
+ */
+static QDF_STATUS send_set_roam_trigger_cmd_tlv(wmi_unified_t wmi_handle,
+						uint32_t vdev_id,
+						uint32_t trigger_bitmap)
+{
+	wmi_buf_t buf;
+	wmi_roam_enable_disable_trigger_reason_fixed_param *cmd;
+	uint16_t len = sizeof(*cmd);
+	int ret;
+
+	buf = wmi_buf_alloc(wmi_handle, len);
+	if (!buf) {
+		WMI_LOGE("%s: Failed to allocate wmi buffer", __func__);
+		return QDF_STATUS_E_NOMEM;
+	}
+
+	cmd = (wmi_roam_enable_disable_trigger_reason_fixed_param *)
+					wmi_buf_data(buf);
+	WMITLV_SET_HDR(&cmd->tlv_header,
+	WMITLV_TAG_STRUC_wmi_roam_enable_disable_trigger_reason_fixed_param,
+		       WMITLV_GET_STRUCT_TLVLEN
+		      (wmi_roam_enable_disable_trigger_reason_fixed_param));
+	cmd->vdev_id = vdev_id;
+	cmd->trigger_reason_bitmask =
+		convert_control_roam_trigger_reason_bitmap(trigger_bitmap);
+	WMI_LOGD("Received trigger bitmap: 0x%x converted trigger_bitmap: 0x%x",
+		 trigger_bitmap, cmd->trigger_reason_bitmask);
+	cmd->trigger_reason_bitmask |= get_internal_mandatory_roam_triggers();
+	WMI_LOGD("WMI_ROAM_ENABLE_DISABLE_TRIGGER_REASON_CMDID vdev id: %d final trigger_bitmap: 0x%x",
+		 cmd->vdev_id, cmd->trigger_reason_bitmask);
+	wmi_mtrace(WMI_ROAM_ENABLE_DISABLE_TRIGGER_REASON_CMDID, vdev_id, 0);
+	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
+			   WMI_ROAM_ENABLE_DISABLE_TRIGGER_REASON_CMDID);
+	if (QDF_IS_STATUS_ERROR(ret)) {
+		WMI_LOGE("Failed to send set roam triggers command ret = %d",
+			 ret);
+		wmi_buf_free(buf);
+	}
+	return ret;
+}
 #else
 static inline QDF_STATUS
 send_disconnect_roam_params_tlv(wmi_unified_t wmi_handle,
@@ -2456,6 +2571,14 @@ send_roam_preauth_status_tlv(wmi_unified_t wmi_handle,
 {
 	return QDF_STATUS_E_FAILURE;
 }
+
+static QDF_STATUS
+send_set_roam_trigger_cmd_tlv(wmi_unified_t wmi_handle,
+			      uint32_t vdev_id,
+			      uint32_t trigger_bitmap)
+{
+	return QDF_STATUS_E_FAILURE;
+}
 #endif
 
 /**
@@ -2630,6 +2753,7 @@ void wmi_roam_attach_tlv(wmi_unified_t wmi_handle)
 	ops->send_idle_roam_params = send_idle_roam_params_tlv;
 	ops->send_disconnect_roam_params = send_disconnect_roam_params_tlv;
 	ops->send_roam_preauth_status = send_roam_preauth_status_tlv;
+	ops->send_set_roam_trigger_cmd = send_set_roam_trigger_cmd_tlv,
 
 	wmi_lfr_subnet_detection_attach_tlv(wmi_handle);
 	wmi_rssi_monitor_attach_tlv(wmi_handle);