qcacld-3.0: Get HW mode info from roam fail indication

During roam fail, if firmware doesn't have any interface left on
2.4Ghz it moves to SMM from DBS, But doesn't inform to Host, which
assume DUT is in DBS mode and thus can send VDEV start on 2.4Ghz
without switching to DBS mode. This lead to assert in firmware.

To fix this firmware will indicate the new HW mode in ROAM INVOKE
FAIL and HO FAIL during roam. so handle the new HW mode indication
and update the host HW mode from the new HW mode indication. So
that host and firmware remain in sync

Change-Id: I854faea17c8eccf212b4efb9443b297cadca62b0
CRs-Fixed: 2473532
diff --git a/core/wma/src/wma_scan_roam.c b/core/wma/src/wma_scan_roam.c
index 18d30d3..2006897 100644
--- a/core/wma/src/wma_scan_roam.c
+++ b/core/wma/src/wma_scan_roam.c
@@ -5176,6 +5176,45 @@
 }
 
 /**
+ * wma_handle_hw_mode_in_roam_fail() - Fill hw mode info if present in policy
+ * manager.
+ * @wma: wma handle
+ * @param: roam event params
+ *
+ * Return: None
+ */
+static int wma_handle_hw_mode_transition(tp_wma_handle wma,
+					 WMI_ROAM_EVENTID_param_tlvs *param)
+{
+	struct sir_hw_mode_trans_ind *hw_mode_trans_ind;
+
+	hw_mode_trans_ind = qdf_mem_malloc(sizeof(*hw_mode_trans_ind));
+	if (!hw_mode_trans_ind)
+		return -ENOMEM;
+
+	if (param->hw_mode_transition_fixed_param) {
+		wma_process_pdev_hw_mode_trans_ind(wma,
+		    param->hw_mode_transition_fixed_param,
+		    param->wmi_pdev_set_hw_mode_response_vdev_mac_mapping,
+		    hw_mode_trans_ind);
+
+		WMA_LOGI(FL("Update HW mode"));
+		policy_mgr_hw_mode_transition_cb(
+			hw_mode_trans_ind->old_hw_mode_index,
+			hw_mode_trans_ind->new_hw_mode_index,
+			hw_mode_trans_ind->num_vdev_mac_entries,
+			hw_mode_trans_ind->vdev_mac_map,
+			wma->psoc);
+	} else {
+		WMA_LOGD(FL("hw_mode transition fixed param is NULL"));
+	}
+
+	qdf_mem_free(hw_mode_trans_ind);
+
+	return 0;
+}
+
+/**
  * wma_roam_event_callback() - roam event callback
  * @handle: wma handle
  * @event_buf: event buffer
@@ -5256,6 +5295,7 @@
 	case WMI_ROAM_REASON_HO_FAILED:
 		WMA_LOGE("LFR3:Hand-Off Failed for vdevid %x",
 			 wmi_event->vdev_id);
+		wma_handle_hw_mode_transition(wma_handle, param_buf);
 		wma_roam_ho_fail_handler(wma_handle, wmi_event->vdev_id);
 		wma_handle->interfaces[wmi_event->vdev_id].
 			roaming_in_progress = false;
@@ -5289,6 +5329,7 @@
 		wma_rso_cmd_status_event_handler(wmi_event);
 		break;
 	case WMI_ROAM_REASON_INVOKE_ROAM_FAIL:
+		wma_handle_hw_mode_transition(wma_handle, param_buf);
 		roam_synch_data = qdf_mem_malloc(sizeof(*roam_synch_data));
 		if (!roam_synch_data)
 			return -ENOMEM;