ソースを参照

qcacld-3.0: Post PEER_UNMAP_RESPONSE cmd to mc thread in ho fail

Unable to send WMI_PEER_UNMAP_RESPONSE_CMDID for peer ids in case
of WOW + ROAM failure scenarios, where target is suspended. This
will cause peer ids leak in the firmware.

Post the PEER_UNMAP_RESPONSE cmd to mc thread in case of ho fail.

Change-Id: I5b9e0fc874ab31f401f7adc8cff22fbc20811acb
CRs-Fixed: 2396094
Rakshith Suresh Patkar 6 年 前
コミット
5f9efa342a

+ 9 - 3
core/dp/txrx/ol_txrx_peer_find.c

@@ -501,12 +501,18 @@ ol_txrx_peer_unmap_conf_handler(ol_txrx_pdev_handle pdev,
 				DEBUG_INVALID_VDEV_ID,
 				1, &peer_id);
 
-		if (status != QDF_STATUS_SUCCESS)
+		if (status == QDF_STATUS_SUCCESS ||
+		    status == QDF_STATUS_E_BUSY) {
+			qdf_atomic_init(
+			&pdev->peer_id_to_obj_map[peer_id].peer_id_unmap_cnt);
+		} else {
+			qdf_atomic_set(
+			&pdev->peer_id_to_obj_map[peer_id].peer_id_unmap_cnt,
+			OL_TXRX_INVALID_PEER_UNMAP_COUNT);
 			ol_txrx_err("unable to send unmap conf cmd [%d]",
 				    peer_id);
+		}
 
-		qdf_atomic_init(
-			&pdev->peer_id_to_obj_map[peer_id].peer_id_unmap_cnt);
 	}
 }
 

+ 1 - 0
core/dp/txrx/ol_txrx_types.h

@@ -529,6 +529,7 @@ struct ol_tx_flow_pool_t {
 
 #endif
 
+#define OL_TXRX_INVALID_PEER_UNMAP_COUNT 0xF
 /*
  * struct ol_txrx_peer_id_map - Map of firmware peer_ids to peers on host
  * @peer: Pointer to peer object

+ 3 - 0
core/mac/src/include/sir_params.h

@@ -658,6 +658,9 @@ struct sir_cfg_action_frm_tb_ppdu {
 #define SIR_HAL_SET_THERMAL_THROTTLE_CFG    (SIR_HAL_ITC_MSG_TYPES_BEGIN + 409)
 #define SIR_HAL_SET_THERMAL_MGMT            (SIR_HAL_ITC_MSG_TYPES_BEGIN + 410)
 #endif /* FW_THERMAL_THROTTLE_SUPPORT */
+
+#define SIR_HAL_SEND_PEER_UNMAP_CONF        (SIR_HAL_ITC_MSG_TYPES_BEGIN + 411)
+
 #define SIR_HAL_MSG_TYPES_END               (SIR_HAL_MSG_TYPES_BEGIN + 0x1FF)
 
 /* LIM message types */

+ 12 - 0
core/wma/inc/wma_if.h

@@ -993,6 +993,18 @@ struct del_sta_self_rsp_params {
 	uint8_t generate_rsp;
 };
 
+/**
+ * struct send_peer_unmap_conf_params - Send Peer Unmap Conf param
+ * @vdev_id: vdev ID
+ * @peer_id_cnt: peer_id count
+ * @peer_id_list: list of peer IDs
+ */
+struct send_peer_unmap_conf_params {
+	uint8_t vdev_id;
+	uint32_t peer_id_cnt;
+	uint16_t *peer_id_list;
+};
+
 /**
  * struct tHalHiddenSsidVdevRestart - hidden ssid vdev restart params
  * @ssidHidden: is hidden ssid or not

+ 3 - 0
core/wma/inc/wma_internal.h

@@ -605,6 +605,9 @@ QDF_STATUS wma_remove_peer(tp_wma_handle wma, uint8_t *bssid,
 			   uint8_t vdev_id, void *peer,
 			   bool roam_synch_in_progress);
 
+QDF_STATUS wma_peer_unmap_conf_send(tp_wma_handle wma,
+				    struct send_peer_unmap_conf_params *msg);
+
 QDF_STATUS wma_create_peer(tp_wma_handle wma, struct cdp_pdev *pdev,
 			  struct cdp_vdev *vdev,
 			  uint8_t peer_addr[IEEE80211_ADDR_LEN],

+ 1 - 0
core/wma/inc/wma_types.h

@@ -143,6 +143,7 @@
 #define WMA_SEND_BCN_RSP               SIR_HAL_SEND_BCN_RSP
 #define WMA_SEND_PROBE_RSP_TMPL        SIR_HAL_SEND_PROBE_RSP_TMPL
 #define WMA_ROAM_BLACLIST_MSG          SIR_HAL_ROAM_BLACKLIST_MSG
+#define WMA_SEND_PEER_UNMAP_CONF       SIR_HAL_SEND_PEER_UNMAP_CONF
 
 #define WMA_SET_BSSKEY_REQ             SIR_HAL_SET_BSSKEY_REQ
 #define WMA_SET_BSSKEY_RSP             SIR_HAL_SET_BSSKEY_RSP

+ 89 - 3
core/wma/src/wma_dev_if.c

@@ -1681,6 +1681,39 @@ QDF_STATUS wma_set_peer_param(void *wma_ctx, uint8_t *peer_addr,
 	return err;
 }
 
+/**
+ * wma_peer_unmap_conf_send - send peer unmap conf cmnd to fw
+ * @wma_ctx: wma handle
+ * @msg: peer unmap conf params
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS wma_peer_unmap_conf_send(tp_wma_handle wma,
+				    struct send_peer_unmap_conf_params *msg)
+{
+	QDF_STATUS qdf_status;
+
+	if (!msg) {
+		WMA_LOGE("%s: null input params", __func__);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	qdf_status = wmi_unified_peer_unmap_conf_send(
+					wma->wmi_handle,
+					msg->vdev_id,
+					msg->peer_id_cnt,
+					msg->peer_id_list);
+
+	if (qdf_status != QDF_STATUS_SUCCESS)
+		WMA_LOGE("%s: peer_unmap_conf_send failed %d",
+			 __func__, qdf_status);
+
+	qdf_mem_free(msg->peer_id_list);
+	msg->peer_id_list = NULL;
+
+	return qdf_status;
+}
+
 /**
  * wma_peer_unmap_conf_cb - send peer unmap conf cmnd to fw
  * @vdev_id: vdev id
@@ -1689,22 +1722,75 @@ QDF_STATUS wma_set_peer_param(void *wma_ctx, uint8_t *peer_addr,
  *
  * Return: QDF_STATUS
  */
-
 QDF_STATUS wma_peer_unmap_conf_cb(uint8_t vdev_id,
 				  uint32_t peer_id_cnt,
 				  uint16_t *peer_id_list)
 {
 	tp_wma_handle wma = cds_get_context(QDF_MODULE_ID_WMA);
+	QDF_STATUS qdf_status;
 
 	if (!wma) {
-		WMA_LOGD("%s: peer_id_cnt: %d, null wma_handle",
+		WMA_LOGE("%s: peer_id_cnt: %d, null wma_handle",
 			 __func__, peer_id_cnt);
 		return QDF_STATUS_E_INVAL;
 	}
 
-	return wmi_unified_peer_unmap_conf_send(wma->wmi_handle,
+	qdf_status = wmi_unified_peer_unmap_conf_send(
+						wma->wmi_handle,
 						vdev_id, peer_id_cnt,
 						peer_id_list);
+
+	if (qdf_status == QDF_STATUS_E_BUSY) {
+		QDF_STATUS retcode;
+		struct scheduler_msg msg = {0};
+		struct send_peer_unmap_conf_params *peer_unmap_conf_req;
+		void *mac_ctx = cds_get_context(QDF_MODULE_ID_PE);
+
+		WMA_LOGD("%s: post unmap_conf cmd to MC thread", __func__);
+
+		if (!mac_ctx) {
+			WMA_LOGE("%s: mac_ctx is NULL", __func__);
+			return QDF_STATUS_E_FAILURE;
+		}
+
+		peer_unmap_conf_req = qdf_mem_malloc(sizeof(
+					struct send_peer_unmap_conf_params));
+
+		if (!peer_unmap_conf_req) {
+			WMA_LOGE("%s: peer_unmap_conf_req memory alloc failed",
+				 __func__);
+			return QDF_STATUS_E_NOMEM;
+		}
+
+		peer_unmap_conf_req->vdev_id = vdev_id;
+		peer_unmap_conf_req->peer_id_cnt = peer_id_cnt;
+		peer_unmap_conf_req->peer_id_list =  qdf_mem_malloc(
+					sizeof(uint16_t) * peer_id_cnt);
+		if (!peer_unmap_conf_req->peer_id_list) {
+			WMA_LOGE("%s: peer_id_list memory alloc failed",
+				 __func__);
+			qdf_mem_free(peer_unmap_conf_req);
+			peer_unmap_conf_req = NULL;
+			return QDF_STATUS_E_NOMEM;
+		}
+		qdf_mem_copy(peer_unmap_conf_req->peer_id_list,
+			     peer_id_list, sizeof(uint16_t) * peer_id_cnt);
+
+		msg.type = WMA_SEND_PEER_UNMAP_CONF;
+		msg.reserved = 0;
+		msg.bodyptr = peer_unmap_conf_req;
+		msg.bodyval = 0;
+
+		retcode = wma_post_ctrl_msg(mac_ctx, &msg);
+		if (retcode != QDF_STATUS_SUCCESS) {
+			WMA_LOGE("%s: wma_post_ctrl_msg failed", __func__);
+			qdf_mem_free(peer_unmap_conf_req->peer_id_list);
+			qdf_mem_free(peer_unmap_conf_req);
+			return QDF_STATUS_E_FAILURE;
+		}
+	}
+
+	return qdf_status;
 }
 
 /**

+ 6 - 0
core/wma/src/wma_main.c

@@ -8302,6 +8302,12 @@ static QDF_STATUS wma_mc_process_msg(struct scheduler_msg *msg)
 	case WMA_ADD_STA_REQ:
 		wma_add_sta(wma_handle, (tpAddStaParams) msg->bodyptr);
 		break;
+	case WMA_SEND_PEER_UNMAP_CONF:
+		wma_peer_unmap_conf_send(
+			wma_handle,
+			(struct send_peer_unmap_conf_params *)msg->bodyptr);
+		qdf_mem_free(msg->bodyptr);
+		break;
 	case WMA_SET_BSSKEY_REQ:
 		wma_set_bsskey(wma_handle, (tpSetBssKeyParams) msg->bodyptr);
 		break;