|
@@ -3729,7 +3729,42 @@ alloc_packet:
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
-QDF_STATUS lim_send_deauth_cnf(struct mac_context *mac_ctx)
|
|
|
+static
|
|
|
+void lim_delete_deauth_all_pending_sta(struct mac_context *mac_ctx,
|
|
|
+ struct pe_session *session)
|
|
|
+{
|
|
|
+ int i = 0;
|
|
|
+ tpDphHashNode sta_ds = NULL;
|
|
|
+
|
|
|
+ if (!session)
|
|
|
+ return;
|
|
|
+
|
|
|
+ for (i = 0; i < session->dph.dphHashTable.size; i++) {
|
|
|
+ sta_ds = dph_get_hash_entry(mac_ctx, i,
|
|
|
+ &session->dph.dphHashTable);
|
|
|
+ /*
|
|
|
+ * In case of multiple STA kickout on SAP interface,
|
|
|
+ * DeauthAckTimer would be started only for the first
|
|
|
+ * deauth queued. So, the ack timeout would not be
|
|
|
+ * fired for other deauth frames. Therefore as part of
|
|
|
+ * of this timer expiry(of first queued deauth), trigger
|
|
|
+ * sta deletion for all the peers with deauth in progress.
|
|
|
+ *
|
|
|
+ * Do not trigger deletion if sta_deletion is already in
|
|
|
+ * progress.
|
|
|
+ */
|
|
|
+
|
|
|
+ if (!sta_ds || !sta_ds->valid ||
|
|
|
+ sta_ds->sta_deletion_in_progress ||
|
|
|
+ !sta_ds->is_disassoc_deauth_in_progress)
|
|
|
+ continue;
|
|
|
+
|
|
|
+ sta_ds->is_disassoc_deauth_in_progress = 0;
|
|
|
+ lim_trigger_sta_deletion(mac_ctx, sta_ds, session);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+QDF_STATUS lim_send_deauth_cnf(struct mac_context *mac_ctx, uint8_t vdev_id)
|
|
|
{
|
|
|
uint16_t aid;
|
|
|
tpDphHashNode sta_ds;
|
|
@@ -3835,6 +3870,17 @@ QDF_STATUS lim_send_deauth_cnf(struct mac_context *mac_ctx)
|
|
|
/* Free up buffer allocated for mlmDeauthReq */
|
|
|
qdf_mem_free(deauth_req);
|
|
|
mac_ctx->lim.limDisassocDeauthCnfReq.pMlmDeauthReq = NULL;
|
|
|
+ } else {
|
|
|
+ session_entry = pe_find_session_by_vdev_id(mac_ctx, vdev_id);
|
|
|
+ if (!session_entry || (session_entry->opmode != QDF_SAP_MODE &&
|
|
|
+ session_entry->opmode !=QDF_P2P_GO_MODE))
|
|
|
+ return QDF_STATUS_SUCCESS;
|
|
|
+ /*
|
|
|
+ * If deauth request is not present, then the deauth could
|
|
|
+ * be from the SB STA kickout queued in SAP context.
|
|
|
+ * Cleanup all the STA which has is_disassoc_deauth_in_progress
|
|
|
+ */
|
|
|
+ lim_delete_deauth_all_pending_sta(mac_ctx, session_entry);
|
|
|
}
|
|
|
return QDF_STATUS_SUCCESS;
|
|
|
end:
|
|
@@ -3989,10 +4035,47 @@ QDF_STATUS lim_deauth_tx_complete_cnf(void *context,
|
|
|
void *params)
|
|
|
{
|
|
|
struct mac_context *mac_ctx = (struct mac_context *)context;
|
|
|
+ struct wmi_mgmt_params *mgmt_params =
|
|
|
+ (struct wmi_mgmt_params *)params;
|
|
|
+ uint8_t vdev_id = WLAN_INVALID_VDEV_ID;
|
|
|
|
|
|
pe_debug("tx_success: %d", tx_success);
|
|
|
+ if (mgmt_params)
|
|
|
+ vdev_id = mgmt_params->vdev_id;
|
|
|
+
|
|
|
+ return lim_send_deauth_cnf(mac_ctx, vdev_id);
|
|
|
+}
|
|
|
+
|
|
|
+static QDF_STATUS lim_ap_delete_sta_upon_deauth_tx(struct mac_context *mac_ctx,
|
|
|
+ struct pe_session *session,
|
|
|
+ tSirMacAddr peer)
|
|
|
+{
|
|
|
+ tpDphHashNode stads;
|
|
|
+ uint16_t aid;
|
|
|
|
|
|
- return lim_send_deauth_cnf(mac_ctx);
|
|
|
+ if (!session || (session->opmode != QDF_SAP_MODE &&
|
|
|
+ session->opmode != QDF_P2P_GO_MODE))
|
|
|
+ return QDF_STATUS_E_FAILURE;
|
|
|
+
|
|
|
+ stads = dph_lookup_hash_entry(mac_ctx, peer, &aid,
|
|
|
+ &session->dph.dphHashTable);
|
|
|
+
|
|
|
+ if (!stads || !stads->ocv_enabled ||
|
|
|
+ stads->last_ocv_done_freq == session->curr_op_freq)
|
|
|
+ return QDF_STATUS_E_FAILURE;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Proceed with sta deletion only if
|
|
|
+ * is_disassoc_deauth_in_progress is set. If unset,
|
|
|
+ * sta deletion will be handled by the deauth ack
|
|
|
+ * timeout handler.
|
|
|
+ */
|
|
|
+ if (!stads->is_disassoc_deauth_in_progress ||
|
|
|
+ stads->sta_deletion_in_progress)
|
|
|
+ return QDF_STATUS_SUCCESS;
|
|
|
+
|
|
|
+ lim_trigger_sta_deletion(mac_ctx, stads, session);
|
|
|
+ return QDF_STATUS_SUCCESS;
|
|
|
}
|
|
|
|
|
|
static QDF_STATUS lim_deauth_tx_complete_cnf_handler(void *context,
|
|
@@ -4001,10 +4084,14 @@ static QDF_STATUS lim_deauth_tx_complete_cnf_handler(void *context,
|
|
|
void *params)
|
|
|
{
|
|
|
struct mac_context *mac_ctx = (struct mac_context *)context;
|
|
|
- QDF_STATUS status_code;
|
|
|
+ QDF_STATUS status_code = QDF_STATUS_E_FAILURE;
|
|
|
struct scheduler_msg msg = {0};
|
|
|
tLimMlmDeauthReq *deauth_req;
|
|
|
struct pe_session *session = NULL;
|
|
|
+ tSirMacMgmtHdr *mac_hdr;
|
|
|
+ uint8_t vdev_id = WLAN_INVALID_VDEV_ID;
|
|
|
+ struct wmi_mgmt_params *mgmt_params =
|
|
|
+ (struct wmi_mgmt_params *)params;
|
|
|
|
|
|
if (params)
|
|
|
wlan_send_tx_complete_event(context, buf, params, tx_success,
|
|
@@ -4016,8 +4103,24 @@ static QDF_STATUS lim_deauth_tx_complete_cnf_handler(void *context,
|
|
|
(tx_success == WMI_MGMT_TX_COMP_TYPE_COMPLETE_OK) ?
|
|
|
"success" : "fail", tx_success);
|
|
|
|
|
|
+ if (buf && (qdf_nbuf_len(buf) > sizeof(struct wlan_frame_hdr) + 2))
|
|
|
+ mac_hdr = (tSirMacMgmtHdr *)qdf_nbuf_data(buf);
|
|
|
+
|
|
|
+ if (!deauth_req && mac_hdr) {
|
|
|
+ if (mgmt_params)
|
|
|
+ vdev_id = mgmt_params->vdev_id;
|
|
|
+ session = pe_find_session_by_vdev_id(mac_ctx, vdev_id);
|
|
|
+ status_code = lim_ap_delete_sta_upon_deauth_tx(mac_ctx, session,
|
|
|
+ (uint8_t *)mac_hdr->da);
|
|
|
+ }
|
|
|
+
|
|
|
if (buf)
|
|
|
qdf_nbuf_free(buf);
|
|
|
+
|
|
|
+ /* Cleanup has been handled for SAP/GO context, return */
|
|
|
+ if (QDF_IS_STATUS_SUCCESS(status_code))
|
|
|
+ return QDF_STATUS_SUCCESS;
|
|
|
+
|
|
|
if (deauth_req)
|
|
|
session = pe_find_session_by_session_id(mac_ctx,
|
|
|
deauth_req->sessionId);
|
|
@@ -4344,7 +4447,7 @@ lim_send_deauth_mgmt_frame(struct mac_context *mac,
|
|
|
}
|
|
|
if (drop_deauth) {
|
|
|
if (waitForAck)
|
|
|
- lim_send_deauth_cnf(mac);
|
|
|
+ lim_send_deauth_cnf(mac, pe_session->vdev_id);
|
|
|
return;
|
|
|
}
|
|
|
} else if (lim_is_ml_peer_state_disconn(mac, pe_session, peer)) {
|
|
@@ -4356,7 +4459,7 @@ lim_send_deauth_mgmt_frame(struct mac_context *mac,
|
|
|
*/
|
|
|
pe_debug("Deauth tx not required for vdev id %d",
|
|
|
pe_session->vdev_id);
|
|
|
- lim_send_deauth_cnf(mac);
|
|
|
+ lim_send_deauth_cnf(mac, pe_session->vdev_id);
|
|
|
return;
|
|
|
}
|
|
|
smeSessionId = pe_session->smeSessionId;
|
|
@@ -4387,7 +4490,7 @@ lim_send_deauth_mgmt_frame(struct mac_context *mac,
|
|
|
pe_err("Failed to allocate %d bytes for a De-Authentication",
|
|
|
nBytes);
|
|
|
if (waitForAck)
|
|
|
- lim_send_deauth_cnf(mac);
|
|
|
+ lim_send_deauth_cnf(mac, pe_session->vdev_id);
|
|
|
return;
|
|
|
}
|
|
|
/* Paranoia: */
|
|
@@ -4410,7 +4513,7 @@ lim_send_deauth_mgmt_frame(struct mac_context *mac,
|
|
|
nStatus);
|
|
|
cds_packet_free((void *)pPacket);
|
|
|
if (waitForAck)
|
|
|
- lim_send_deauth_cnf(mac);
|
|
|
+ lim_send_deauth_cnf(mac, pe_session->vdev_id);
|
|
|
return;
|
|
|
} else if (DOT11F_WARNED(nStatus)) {
|
|
|
pe_warn("There were warnings while packing a De-Authentication (0x%08x)",
|
|
@@ -4476,13 +4579,18 @@ lim_send_deauth_mgmt_frame(struct mac_context *mac,
|
|
|
/* Call lim_process_deauth_ack_timeout which will send
|
|
|
* DeauthCnf for this frame
|
|
|
*/
|
|
|
- lim_process_deauth_ack_timeout(mac);
|
|
|
+ lim_process_deauth_ack_timeout(mac,
|
|
|
+ pe_session->peSessionId);
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
val = SYS_MS_TO_TICKS(LIM_DISASSOC_DEAUTH_ACK_TIMEOUT);
|
|
|
-
|
|
|
- if (tx_timer_change
|
|
|
+ if (tx_timer_change_context(
|
|
|
+ &mac->lim.lim_timers.gLimDeauthAckTimer,
|
|
|
+ pe_session->vdev_id) != TX_SUCCESS) {
|
|
|
+ pe_err("Unable to update the vdev id in the Deauth ack timer");
|
|
|
+ return;
|
|
|
+ } else if (tx_timer_change
|
|
|
(&mac->lim.lim_timers.gLimDeauthAckTimer, val, 0)
|
|
|
!= TX_SUCCESS) {
|
|
|
pe_err("Unable to change Deauth ack Timer val");
|