Browse Source

qcacld-3.0: Handle error cases while registering frames

If registration of callback 'hdd_send_action_cnf_cb' fails with PE due
to some error case, then PE is not going give the ack confirmation
for action frames which can lead to in p2p connection failure.

CRs-Fixed: 2075708
Change-Id: Ia7b670f186975f5139e37e79230de56bc8ab868b
Ganesh Kondabattini 7 years ago
parent
commit
0dc1a6e77a
3 changed files with 86 additions and 12 deletions
  1. 68 10
      core/hdd/src/wlan_hdd_cfg80211.c
  2. 12 1
      core/hdd/src/wlan_hdd_cfg80211.h
  3. 6 1
      core/hdd/src/wlan_hdd_main.c

+ 68 - 10
core/hdd/src/wlan_hdd_cfg80211.c

@@ -11634,19 +11634,30 @@ void wlan_hdd_cfg80211_update_wiphy_caps(struct wiphy *wiphy)
 /* This function registers for all frame which supplicant is interested in */
 #if defined(CONVERGED_P2P_ENABLE) || defined(CONVERGED_TDLS_ENABLE)
 
-void wlan_hdd_cfg80211_register_frames(hdd_adapter_t *pAdapter)
+int wlan_hdd_cfg80211_register_frames(hdd_adapter_t *pAdapter)
 {
 	tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
 	/* Register for all P2P action, public action etc frames */
 	uint16_t type = (SIR_MAC_MGMT_FRAME << 2) | (SIR_MAC_MGMT_ACTION << 4);
+	QDF_STATUS status;
 
 	ENTER();
 
 	/* Register frame indication call back */
-	sme_register_mgmt_frame_ind_callback(hHal, hdd_indicate_mgmt_frame);
+	status = sme_register_mgmt_frame_ind_callback(hHal,
+			hdd_indicate_mgmt_frame);
+	if (status != QDF_STATUS_SUCCESS) {
+		hdd_err("Failed to register hdd_indicate_mgmt_frame");
+		goto ret_status;
+	}
 
 	/* Register for p2p ack indication */
-	sme_register_p2p_ack_ind_callback(hHal, hdd_send_action_cnf_cb);
+	status = sme_register_p2p_ack_ind_callback(hHal,
+			hdd_send_action_cnf_cb);
+	if (status != QDF_STATUS_SUCCESS) {
+		hdd_err("Failed to register p2p_ack_ind_callback");
+		goto ret_status;
+	}
 
 	/* Right now we are registering these frame when driver is getting
 	 * initialized. Once we will move to 2.6.37 kernel, in which we have
@@ -11654,37 +11665,84 @@ void wlan_hdd_cfg80211_register_frames(hdd_adapter_t *pAdapter)
 	 */
 
 	/* GAS Initial Request */
-	sme_register_mgmt_frame(hHal, SME_SESSION_ID_ANY, type,
+	status = sme_register_mgmt_frame(hHal, SME_SESSION_ID_ANY, type,
 				(uint8_t *) GAS_INITIAL_REQ,
 				GAS_INITIAL_REQ_SIZE);
+	if (status != QDF_STATUS_SUCCESS) {
+		hdd_err("Failed to register GAS_INITIAL_REQ");
+		goto ret_status;
+	}
 
 	/* GAS Initial Response */
-	sme_register_mgmt_frame(hHal, SME_SESSION_ID_ANY, type,
+	status = sme_register_mgmt_frame(hHal, SME_SESSION_ID_ANY, type,
 				(uint8_t *) GAS_INITIAL_RSP,
 				GAS_INITIAL_RSP_SIZE);
+	if (status != QDF_STATUS_SUCCESS) {
+		hdd_err("Failed to register GAS_INITIAL_RSP");
+		goto dereg_gas_initial_req;
+	}
 
 	/* GAS Comeback Request */
-	sme_register_mgmt_frame(hHal, SME_SESSION_ID_ANY, type,
+	status = sme_register_mgmt_frame(hHal, SME_SESSION_ID_ANY, type,
 				(uint8_t *) GAS_COMEBACK_REQ,
 				GAS_COMEBACK_REQ_SIZE);
+	if (status != QDF_STATUS_SUCCESS) {
+		hdd_err("Failed to register GAS_COMEBACK_REQ");
+		goto dereg_gas_initial_rsp;
+	}
 
 	/* GAS Comeback Response */
-	sme_register_mgmt_frame(hHal, SME_SESSION_ID_ANY, type,
+	status = sme_register_mgmt_frame(hHal, SME_SESSION_ID_ANY, type,
 				(uint8_t *) GAS_COMEBACK_RSP,
 				GAS_COMEBACK_RSP_SIZE);
+	if (status != QDF_STATUS_SUCCESS) {
+		hdd_err("Failed to register GAS_COMEBACK_RSP");
+		goto dereg_gas_comeback_req;
+	}
 
 	/* WNM BSS Transition Request frame */
-	sme_register_mgmt_frame(hHal, SME_SESSION_ID_ANY, type,
+	status = sme_register_mgmt_frame(hHal, SME_SESSION_ID_ANY, type,
 				(uint8_t *) WNM_BSS_ACTION_FRAME,
 				WNM_BSS_ACTION_FRAME_SIZE);
+	if (status != QDF_STATUS_SUCCESS) {
+		hdd_err("Failed to register WNM_BSS_ACTION_FRAME");
+		goto dereg_gas_comeback_rsp;
+	}
 
 	/* WNM-Notification */
-	sme_register_mgmt_frame(hHal, pAdapter->sessionId, type,
+	status = sme_register_mgmt_frame(hHal, pAdapter->sessionId, type,
 				(uint8_t *) WNM_NOTIFICATION_FRAME,
 				WNM_NOTIFICATION_FRAME_SIZE);
+	if (status != QDF_STATUS_SUCCESS) {
+		hdd_err("Failed to register WNM_NOTIFICATION_FRAME");
+		goto dereg_wnm_bss_action_frm;
+	}
+
+dereg_wnm_bss_action_frm:
+	sme_deregister_mgmt_frame(hHal, SME_SESSION_ID_ANY, type,
+			(uint8_t *) WNM_BSS_ACTION_FRAME,
+			WNM_BSS_ACTION_FRAME_SIZE);
+dereg_gas_comeback_rsp:
+	sme_deregister_mgmt_frame(hHal, SME_SESSION_ID_ANY, type,
+			(uint8_t *) GAS_COMEBACK_RSP,
+			GAS_COMEBACK_RSP_SIZE);
+dereg_gas_comeback_req:
+	sme_deregister_mgmt_frame(hHal, SME_SESSION_ID_ANY, type,
+			(uint8_t *) GAS_COMEBACK_REQ,
+			GAS_COMEBACK_REQ_SIZE);
+dereg_gas_initial_rsp:
+	sme_deregister_mgmt_frame(hHal, SME_SESSION_ID_ANY, type,
+			(uint8_t *) GAS_INITIAL_RSP,
+			GAS_INITIAL_RSP_SIZE);
+dereg_gas_initial_req:
+	sme_deregister_mgmt_frame(hHal, SME_SESSION_ID_ANY, type,
+			(uint8_t *) GAS_INITIAL_REQ,
+			GAS_INITIAL_REQ_SIZE);
+ret_status:
+	return qdf_status_to_os_return(status);
 }
 #else
-void wlan_hdd_cfg80211_register_frames(hdd_adapter_t *pAdapter)
+int wlan_hdd_cfg80211_register_frames(hdd_adapter_t *pAdapter)
 {
 	tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
 	/* Register for all P2P action, public action etc frames */

+ 12 - 1
core/hdd/src/wlan_hdd_cfg80211.h

@@ -254,7 +254,18 @@ void wlan_hdd_update_wiphy(hdd_context_t *hdd_ctx);
 void wlan_hdd_update_11n_mode(struct hdd_config *cfg);
 
 int wlan_hdd_cfg80211_register(struct wiphy *wiphy);
-void wlan_hdd_cfg80211_register_frames(hdd_adapter_t *pAdapter);
+
+/**
+ * wlan_hdd_cfg80211_register_frames() - register frame types and callbacks
+ * with the PE.
+ * @pAdapter: pointer to adapter
+ *
+ * This function is used by HDD to register frame types which are interested
+ * by supplicant, callbacks for rx frame indication and ack.
+ *
+ * Return: 0 on success and non zero value on failure
+ */
+int wlan_hdd_cfg80211_register_frames(hdd_adapter_t *pAdapter);
 
 void wlan_hdd_cfg80211_deregister_frames(hdd_adapter_t *pAdapter);
 

+ 6 - 1
core/hdd/src/wlan_hdd_main.c

@@ -1788,7 +1788,12 @@ int hdd_start_adapter(hdd_adapter_t *adapter)
 	 * Action frame registered in one adapter which will
 	 * applicable to all interfaces
 	 */
-	wlan_hdd_cfg80211_register_frames(adapter);
+	ret = wlan_hdd_cfg80211_register_frames(adapter);
+	if (ret < 0) {
+		hdd_err("Failed to register frames - ret %d", ret);
+		goto err_start_adapter;
+	}
+
 	EXIT();
 	return 0;
 err_start_adapter: