summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjge <jge@codeaurora.org>2016-10-12 15:31:18 +0800
committerAnjaneedevi Kapparapu <akappa@codeaurora.org>2016-11-11 19:52:17 +0530
commit0f416591184ea67e46528ab340d399a9f5d738be (patch)
tree5474c1700e09376dd4ab8c237455a715022fac1c
parent39a2a26ac766bc42b2e3b04a9e1201e1ef5b06e0 (diff)
qcacld-2.0: Reset IPA disconnect events(AP/STA) during SSR
IPA disconnect events(WLAN_AP_DISCONNECT/WLAN_STA_DISCONNECT) are not sent to IPA driver in case of SSR. This is resulting in mismatch between IPA driver and HOST driver, and headers in IPA can't be freed, which causes memory overflow after multiple times SSR. Change-Id: I9c84cc84d943d6e3c6604db7b859127a7af5a654 CRs-Fixed: 1069083
-rw-r--r--CORE/HDD/src/wlan_hdd_ipa.c159
1 files changed, 121 insertions, 38 deletions
diff --git a/CORE/HDD/src/wlan_hdd_ipa.c b/CORE/HDD/src/wlan_hdd_ipa.c
index 8920b0514756..9ff7b7035fa8 100644
--- a/CORE/HDD/src/wlan_hdd_ipa.c
+++ b/CORE/HDD/src/wlan_hdd_ipa.c
@@ -2179,17 +2179,62 @@ void hdd_ipa_uc_force_pipe_shutdown(hdd_context_t *hdd_ctx)
}
/**
- * hdd_ipa_send_disconnect() - ipa send disconnect clients
+ * hdd_ipa_uc_send_evt() - send event to ipa
+ * @hdd_ctx: pointer to hdd context
+ * @type: event type
+ * @mac_addr: pointer to mac address
*
- * adapter: pointer to hdd adapter
- * Send disconnect evnt to IPA driver during SSR
+ * Send event to IPA driver
*
* Return: 0 - Success
*/
-static int hdd_ipa_send_disconnect(hdd_adapter_t *adapter)
+static int hdd_ipa_uc_send_evt(hdd_adapter_t *adapter,
+ enum ipa_wlan_event type, uint8_t *mac_addr )
{
- struct ipa_msg_meta meta;
- struct ipa_wlan_msg *msg;
+ struct hdd_ipa_priv *hdd_ipa = ghdd_ipa;
+ struct ipa_msg_meta meta;
+ struct ipa_wlan_msg *msg;
+ int ret = 0;
+
+ meta.msg_len = sizeof(struct ipa_wlan_msg);
+ msg = adf_os_mem_alloc(NULL, meta.msg_len);
+ if (msg == NULL) {
+ HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR,
+ "msg allocation failed");
+ return -ENOMEM;
+ }
+
+ meta.msg_type = type;
+ strlcpy(msg->name, adapter->dev->name,
+ IPA_RESOURCE_NAME_MAX);
+ memcpy(msg->mac_addr, mac_addr, ETH_ALEN);
+ HDD_IPA_LOG(VOS_TRACE_LEVEL_INFO, "%s: Evt: %d",
+ msg->name, meta.msg_type);
+ ret = ipa_send_msg(&meta, msg, hdd_ipa_msg_free_fn);
+ if (ret) {
+ HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR,
+ "%s: Evt: %d fail:%d",
+ msg->name, meta.msg_type, ret);
+ adf_os_mem_free(msg);
+ return ret;
+ }
+
+ hdd_ipa->stats.num_send_msg++;
+
+ return ret;
+}
+
+/**
+ * hdd_ipa_uc_disconnect_client() - send client disconnect event
+ * @hdd_ctx: pointer to hdd adapter
+ *
+ * Send disconnect client event to IPA driver during SSR
+ *
+ * Return: 0 - Success
+ */
+static int hdd_ipa_uc_disconnect_client(hdd_adapter_t *adapter)
+{
+ struct hdd_ipa_priv *hdd_ipa = ghdd_ipa;
int ret = 0;
int i;
@@ -2197,29 +2242,11 @@ static int hdd_ipa_send_disconnect(hdd_adapter_t *adapter)
if (vos_is_macaddr_broadcast(&adapter->aStaInfo[i].macAddrSTA))
continue;
if ((adapter->aStaInfo[i].isUsed) &&
- (!adapter->aStaInfo[i].isDeauthInProgress)) {
- meta.msg_len = sizeof(struct ipa_wlan_msg);
- msg = adf_os_mem_alloc(NULL, meta.msg_len);
- if (msg == NULL) {
- HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR,
- "msg allocation failed");
- return -ENOMEM;
- }
- meta.msg_type = WLAN_CLIENT_DISCONNECT;
- strlcpy(msg->name, adapter->dev->name,
- IPA_RESOURCE_NAME_MAX);
- memcpy(msg->mac_addr, adapter->aStaInfo[i].macAddrSTA.bytes,
- ETH_ALEN);
- HDD_IPA_LOG(VOS_TRACE_LEVEL_INFO, "%s: Evt: %d",
- msg->name, meta.msg_type);
- ret = ipa_send_msg(&meta, msg, hdd_ipa_msg_free_fn);
- if (ret) {
- HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR,
- "%s: Evt: %d fail:%d",
- msg->name, meta.msg_type, ret);
- adf_os_mem_free(msg);
- return ret;
- }
+ (!adapter->aStaInfo[i].isDeauthInProgress) &&
+ hdd_ipa->sap_num_connected_sta) {
+ hdd_ipa_uc_send_evt(adapter, WLAN_CLIENT_DISCONNECT,
+ adapter->aStaInfo[i].macAddrSTA.bytes);
+ hdd_ipa->sap_num_connected_sta--;
}
}
@@ -2227,26 +2254,82 @@ static int hdd_ipa_send_disconnect(hdd_adapter_t *adapter)
}
/**
- * hdd_ipa_uc_disconnect_client() - disconnect ipa sap clients
+ * hdd_ipa_uc_disconnect_ap() - send ap disconnect event
+ * @hdd_ctx: pointer to hdd adapter
+ *
+ * Send disconnect ap event to IPA driver during SSR
+ *
+ * Return: 0 - Success
+ */
+
+static int hdd_ipa_uc_disconnect_ap(hdd_adapter_t *adapter)
+{
+ int ret = 0;
+
+ if (adapter->ipa_context)
+ hdd_ipa_uc_send_evt(adapter, WLAN_AP_DISCONNECT,
+ adapter->dev->dev_addr);
+
+ return ret;
+}
+
+#ifdef IPA_UC_STA_OFFLOAD
+/**
+ * hdd_ipa_uc_disconnect_sta() - send sta disconnect event
+ * @hdd_ctx: pointer to hdd adapter
+ *
+ * Send disconnect sta event to IPA driver during SSR
+ *
+ * Return: 0 - Success
+ */
+static int hdd_ipa_uc_disconnect_sta(hdd_adapter_t *adapter)
+{
+ hdd_station_ctx_t *pHddStaCtx;
+ struct hdd_ipa_priv *hdd_ipa = ghdd_ipa;
+ int ret = 0;
+
+ if (hdd_ipa_uc_sta_is_enabled(hdd_ipa) &&
+ hdd_ipa->sta_connected) {
+ pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
+ hdd_ipa_uc_send_evt(adapter, WLAN_STA_DISCONNECT,
+ pHddStaCtx->conn_info.bssId);
+ }
+
+ return ret;
+}
+#else
+static int hdd_ipa_uc_disconnect_sta(hdd_adapter_t *adapter)
+{
+ return 0;
+}
+
+#endif
+
+/**
+ * hdd_ipa_uc_disconnect() - send disconnect ipa event
+ * @hdd_ctx: pointer to hdd context
*
- * hdd_ctx: pointer to hdd context
- * Send disconnect evnt to IPA driver during SSR
+ * Send disconnect event to IPA driver during SSR
*
* Return: 0 - Success
*/
-static int hdd_ipa_uc_disconnect_client(hdd_context_t *hdd_ctx)
+static int hdd_ipa_uc_disconnect(hdd_context_t *hdd_ctx)
{
hdd_adapter_list_node_t *adapter_node = NULL, *next = NULL;
VOS_STATUS status;
hdd_adapter_t *adapter;
int ret = 0;
-
status = hdd_get_front_adapter (hdd_ctx, &adapter_node);
while (NULL != adapter_node && VOS_STATUS_SUCCESS == status) {
adapter = adapter_node->pAdapter;
- if (adapter->device_mode == WLAN_HDD_SOFTAP)
- hdd_ipa_send_disconnect(adapter);
+ if (adapter->device_mode == WLAN_HDD_SOFTAP) {
+ hdd_ipa_uc_disconnect_client(adapter);
+ hdd_ipa_uc_disconnect_ap(adapter);
+ } else if (adapter->device_mode == WLAN_HDD_INFRA_STATION) {
+ hdd_ipa_uc_disconnect_sta(adapter);
+ }
+
status = hdd_get_next_adapter(
hdd_ctx, adapter_node, &next);
adapter_node = next;
@@ -2272,8 +2355,8 @@ int hdd_ipa_uc_ssr_deinit()
if (!hdd_ipa_uc_is_enabled(hdd_ipa))
return 0;
- /* send disconnect to ipa driver for connected clients */
- hdd_ipa_uc_disconnect_client(hdd_ipa->hdd_ctx);
+ /* send disconnect to ipa driver */
+ hdd_ipa_uc_disconnect(hdd_ipa->hdd_ctx);
/* Clean up HDD IPA interfaces */
for (idx = 0; (hdd_ipa->num_iface > 0) &&