|
@@ -1,5 +1,5 @@
|
|
|
/*
|
|
|
- * Copyright (c) 2013-2016 The Linux Foundation. All rights reserved.
|
|
|
+ * Copyright (c) 2013-2017 The Linux Foundation. All rights reserved.
|
|
|
*
|
|
|
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
|
|
|
*
|
|
@@ -2265,48 +2265,75 @@ static void hdd_ipa_msg_free_fn(void *buff, uint32_t len, uint32_t type)
|
|
|
qdf_mem_free(buff);
|
|
|
}
|
|
|
|
|
|
-
|
|
|
/**
|
|
|
- * hdd_ipa_send_disconnect() - ipa send disconnect clients
|
|
|
- * adapter: pointer to hdd adapter
|
|
|
- * Send disconnect evnt to IPA driver during SSR
|
|
|
+ * hdd_ipa_uc_send_evt() - send event to ipa
|
|
|
+ * @hdd_ctx: pointer to hdd context
|
|
|
+ * @type: event type
|
|
|
+ * @mac_addr: pointer to mac address
|
|
|
+ *
|
|
|
+ * 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 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 = qdf_mem_malloc(meta.msg_len);
|
|
|
+ if (msg == NULL) {
|
|
|
+ HDD_IPA_LOG(QDF_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(QDF_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(QDF_TRACE_LEVEL_ERROR,
|
|
|
+ "%s: Evt: %d fail:%d",
|
|
|
+ msg->name, meta.msg_type, ret);
|
|
|
+ qdf_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;
|
|
|
|
|
|
for (i = 0; i < WLAN_MAX_STA_COUNT; i++) {
|
|
|
if (qdf_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 = qdf_mem_malloc(meta.msg_len);
|
|
|
- if (msg == NULL) {
|
|
|
- HDD_IPA_LOG(QDF_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(QDF_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(QDF_TRACE_LEVEL_ERROR,
|
|
|
- "%s: Evt: %d fail:%d",
|
|
|
- msg->name, meta.msg_type, ret);
|
|
|
- qdf_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--;
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -2314,25 +2341,82 @@ static int hdd_ipa_send_disconnect(hdd_adapter_t *adapter)
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * hdd_ipa_uc_disconnect_client() - disconnect ipa sap clients
|
|
|
- * hdd_ctx: pointer to hdd context
|
|
|
- * Send disconnect evnt to IPA driver during SSR
|
|
|
+ * 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_client(hdd_context_t *hdd_ctx)
|
|
|
+
|
|
|
+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
|
|
|
+ *
|
|
|
+ * Send disconnect event to IPA driver during SSR
|
|
|
+ *
|
|
|
+ * Return: 0 - Success
|
|
|
+ */
|
|
|
+static int hdd_ipa_uc_disconnect(hdd_context_t *hdd_ctx)
|
|
|
{
|
|
|
hdd_adapter_list_node_t *adapter_node = NULL, *next = NULL;
|
|
|
QDF_STATUS status;
|
|
|
hdd_adapter_t *adapter;
|
|
|
int ret = 0;
|
|
|
|
|
|
-
|
|
|
status = hdd_get_front_adapter(hdd_ctx, &adapter_node);
|
|
|
while (NULL != adapter_node && QDF_STATUS_SUCCESS == status) {
|
|
|
adapter = adapter_node->pAdapter;
|
|
|
- if (adapter->device_mode == QDF_SAP_MODE)
|
|
|
- hdd_ipa_send_disconnect(adapter);
|
|
|
+ if (adapter->device_mode == QDF_SAP_MODE) {
|
|
|
+ hdd_ipa_uc_disconnect_client(adapter);
|
|
|
+ hdd_ipa_uc_disconnect_ap(adapter);
|
|
|
+ } else if (adapter->device_mode == QDF_STA_MODE) {
|
|
|
+ hdd_ipa_uc_disconnect_sta(adapter);
|
|
|
+ }
|
|
|
+
|
|
|
status = hdd_get_next_adapter(
|
|
|
hdd_ctx, adapter_node, &next);
|
|
|
adapter_node = next;
|
|
@@ -2358,8 +2442,9 @@ static int __hdd_ipa_uc_ssr_deinit(void)
|
|
|
if ((!hdd_ipa) || (!hdd_ipa_uc_is_enabled(hdd_ipa->hdd_ctx)))
|
|
|
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) &&
|
|
|
(idx < HDD_IPA_MAX_IFACE); idx++) {
|