summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLiangwei Dong <liangwei@codeaurora.org>2020-03-07 20:31:44 +0800
committernshrivas <nshrivas@codeaurora.org>2020-03-27 23:57:27 -0700
commit99b22c0027d7202f7e4f07f2843b90c46382dc7f (patch)
tree4341a2667de5b8e3ddbb9f07aa4e0c1be766dd82
parenta028a3db7100efc1994c54a033c9af4345093f5a (diff)
downloadqcacld-99b22c0027d7202f7e4f07f2843b90c46382dc7f.tar.gz
qcacld-3.0: Process request of send delba indication
Handle send delba indication from DP. It will help DP to do aggregation tid management. Change-Id: I18455107ef8d042644efc8ce549a104612eec05c CRs-Fixed: 2637485
-rw-r--r--core/cds/src/cds_api.c14
-rw-r--r--core/mac/src/include/sir_params.h2
-rw-r--r--core/mac/src/pe/include/lim_global.h13
-rw-r--r--core/mac/src/pe/lim/lim_link_monitoring_algo.c41
-rw-r--r--core/mac/src/pe/lim/lim_process_message_queue.c3
-rw-r--r--core/mac/src/pe/lim/lim_send_management_frames.c171
-rw-r--r--core/mac/src/pe/lim/lim_types.h16
-rw-r--r--core/mac/src/pe/lim/lim_utils.h12
-rw-r--r--core/wma/inc/wma.h15
-rw-r--r--core/wma/src/wma_data.c25
10 files changed, 311 insertions, 1 deletions
diff --git a/core/cds/src/cds_api.c b/core/cds/src/cds_api.c
index 73e7a1eaec..7964a6773b 100644
--- a/core/cds/src/cds_api.c
+++ b/core/cds/src/cds_api.c
@@ -86,6 +86,17 @@ static struct __qdf_device g_qdf_ctx;
static uint8_t cds_multicast_logging;
#ifdef QCA_WIFI_QCA8074
+static inline int
+cds_send_delba(void *pdev_handle, void *ctrl_peer,
+ uint8_t *peer_macaddr, uint8_t tid, void *vdev_handle,
+ uint8_t reason_code)
+{
+ struct wlan_objmgr_vdev *vdev = (struct wlan_objmgr_vdev *)vdev_handle;
+
+ return wma_dp_send_delba_ind(wlan_vdev_get_id(vdev), peer_macaddr, tid,
+ reason_code);
+}
+
static struct ol_if_ops dp_ol_if_ops = {
.peer_set_default_routing = target_if_peer_set_default_routing,
.peer_rx_reorder_queue_setup = target_if_peer_rx_reorder_queue_setup,
@@ -95,7 +106,8 @@ static struct ol_if_ops dp_ol_if_ops = {
.rx_mic_error = wma_rx_mic_error_ind,
.rx_invalid_peer = wma_rx_invalid_peer_ind,
.is_roam_inprogress = wma_is_roam_in_progress,
- .get_con_mode = cds_get_conparam
+ .get_con_mode = cds_get_conparam,
+ .send_delba = cds_send_delba,
/* TODO: Add any other control path calls required to OL_IF/WMA layer */
};
#else
diff --git a/core/mac/src/include/sir_params.h b/core/mac/src/include/sir_params.h
index d25af78b82..11c950fad2 100644
--- a/core/mac/src/include/sir_params.h
+++ b/core/mac/src/include/sir_params.h
@@ -673,6 +673,8 @@ struct sir_cfg_action_frm_tb_ppdu {
#define SIR_HAL_ROAM_SCAN_CH_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 414)
+#define SIR_HAL_REQ_SEND_DELBA_REQ_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 415)
+
#define SIR_HAL_MSG_TYPES_END (SIR_HAL_MSG_TYPES_BEGIN + 0x1FF)
/* LIM message types */
diff --git a/core/mac/src/pe/include/lim_global.h b/core/mac/src/pe/include/lim_global.h
index 9e4c3237f9..be266725c3 100644
--- a/core/mac/src/pe/include/lim_global.h
+++ b/core/mac/src/pe/include/lim_global.h
@@ -489,4 +489,17 @@ typedef struct sLimSpecMgmtInfo {
tLimDot11hChanSwStates dot11hChanSwState;
} tLimSpecMgmtInfo, *tpLimSpecMgmtInfo;
+/**
+ * struct lim_delba_req_info - Delba request struct
+ * @vdev_id: vdev id
+ * @peer_macaddr: peer mac address
+ * @tid: tid
+ * @reason_code: reason code
+ */
+struct lim_delba_req_info {
+ uint8_t vdev_id;
+ tSirMacAddr peer_macaddr;
+ uint8_t tid;
+ uint8_t reason_code;
+};
#endif
diff --git a/core/mac/src/pe/lim/lim_link_monitoring_algo.c b/core/mac/src/pe/lim/lim_link_monitoring_algo.c
index 071fea19a5..48281ca966 100644
--- a/core/mac/src/pe/lim/lim_link_monitoring_algo.c
+++ b/core/mac/src/pe/lim/lim_link_monitoring_algo.c
@@ -44,6 +44,8 @@
#include "lim_ft_defs.h"
#include "lim_session.h"
#include "lim_ser_des_utils.h"
+#include "cdp_txrx_cmn.h"
+#include "cdp_txrx_peer_ops.h"
/**
* lim_delete_sta_util - utility function for deleting station context
@@ -595,3 +597,42 @@ void lim_rx_invalid_peer_process(struct mac_context *mac_ctx,
qdf_mem_free(msg);
lim_msg->bodyptr = NULL;
}
+
+void lim_req_send_delba_ind_process(struct mac_context *mac_ctx,
+ struct scheduler_msg *lim_msg)
+{
+ struct lim_delba_req_info *req =
+ (struct lim_delba_req_info *)lim_msg->bodyptr;
+ QDF_STATUS status;
+ void *soc = cds_get_context(QDF_MODULE_ID_SOC);
+ void *peer, *pdev;
+ uint8_t peer_id;
+
+ if (!req) {
+ pe_err("Invalid body pointer in message");
+ return;
+ }
+ pdev = cds_get_context(QDF_MODULE_ID_TXRX);
+ if (!pdev) {
+ pe_err("delba pdev is NULL");
+ goto error;
+ }
+ peer = cdp_peer_get_ref_by_addr(soc, pdev, req->peer_macaddr, &peer_id,
+ PEER_DEBUG_ID_WMA_DELBA_REQ);
+ if (!peer) {
+ pe_err("delba PEER [%pM] not found", req->peer_macaddr);
+ goto error;
+ }
+
+ status = lim_send_delba_action_frame(mac_ctx, req->vdev_id,
+ req->peer_macaddr,
+ req->tid, req->reason_code);
+ if (status != QDF_STATUS_SUCCESS)
+ cdp_delba_tx_completion(soc, peer, req->tid,
+ WMI_MGMT_TX_COMP_TYPE_DISCARD);
+ cdp_peer_release_ref(soc, peer, PEER_DEBUG_ID_WMA_DELBA_REQ);
+
+error:
+ qdf_mem_free(req);
+ lim_msg->bodyptr = NULL;
+}
diff --git a/core/mac/src/pe/lim/lim_process_message_queue.c b/core/mac/src/pe/lim/lim_process_message_queue.c
index cf80e31c70..749a36a937 100644
--- a/core/mac/src/pe/lim/lim_process_message_queue.c
+++ b/core/mac/src/pe/lim/lim_process_message_queue.c
@@ -1840,6 +1840,9 @@ static void lim_process_messages(struct mac_context *mac_ctx,
case SIR_LIM_RX_INVALID_PEER:
lim_rx_invalid_peer_process(mac_ctx, msg);
break;
+ case SIR_HAL_REQ_SEND_DELBA_REQ_IND:
+ lim_req_send_delba_ind_process(mac_ctx, msg);
+ break;
case SIR_LIM_JOIN_FAIL_TIMEOUT:
case SIR_LIM_PERIODIC_JOIN_PROBE_REQ_TIMEOUT:
case SIR_LIM_AUTH_FAIL_TIMEOUT:
diff --git a/core/mac/src/pe/lim/lim_send_management_frames.c b/core/mac/src/pe/lim/lim_send_management_frames.c
index 23f016f079..505708b4e7 100644
--- a/core/mac/src/pe/lim/lim_send_management_frames.c
+++ b/core/mac/src/pe/lim/lim_send_management_frames.c
@@ -5120,6 +5120,177 @@ error_addba_rsp:
}
/**
+ * lim_delba_tx_complete_cnf() - Confirmation for Delba OTA
+ * @context: pointer to global mac
+ * @buf: buffer which is nothing but entire Del BA frame
+ * @tx_complete : Sent status
+ * @params; tx completion params
+ *
+ * Return: This returns QDF_STATUS
+ */
+static QDF_STATUS lim_delba_tx_complete_cnf(void *context,
+ qdf_nbuf_t buf,
+ uint32_t tx_complete,
+ void *params)
+{
+ struct mac_context *mac_ctx = (struct mac_context *)context;
+ tSirMacMgmtHdr *mac_hdr;
+ struct sDot11fdelba_req frm;
+ void *soc = cds_get_context(QDF_MODULE_ID_SOC);
+ void *peer, *pdev;
+ uint8_t peer_id;
+ uint32_t frame_len;
+ QDF_STATUS status;
+ uint8_t *data;
+
+ if (!mac_ctx || !buf || !soc) {
+ pe_err("delba tx cnf invalid parameters");
+ goto error;
+ }
+ pdev = cds_get_context(QDF_MODULE_ID_TXRX);
+ if (!pdev) {
+ pe_err("delba pdev is NULL");
+ goto error;
+ }
+ data = qdf_nbuf_data(buf);
+ if (!data) {
+ pe_err("delba frame is NULL");
+ goto error;
+ }
+
+ mac_hdr = (tSirMacMgmtHdr *)data;
+ qdf_mem_zero((void *)&frm, sizeof(struct sDot11fdelba_req));
+ frame_len = sizeof(frm);
+ status = dot11f_unpack_delba_req(mac_ctx, (uint8_t *)data +
+ sizeof(*mac_hdr), frame_len,
+ &frm, false);
+ if (DOT11F_FAILED(status)) {
+ pe_err("Failed to unpack and parse delba (0x%08x, %d bytes)",
+ status, frame_len);
+ goto error;
+ }
+ peer = cdp_peer_get_ref_by_addr(soc, pdev, mac_hdr->da, &peer_id,
+ PEER_DEBUG_ID_WMA_DELBA_REQ);
+ if (!peer) {
+ pe_err("delba PEER [%pM] not found", mac_hdr->da);
+ goto error;
+ }
+
+ pe_debug("delba ota done to %pM tid %d status %d",
+ mac_hdr->da, frm.delba_param_set.tid, tx_complete);
+ cdp_delba_tx_completion(soc, peer, frm.delba_param_set.tid,
+ tx_complete);
+ cdp_peer_release_ref(soc, peer, PEER_DEBUG_ID_WMA_DELBA_REQ);
+
+error:
+ if (buf)
+ qdf_nbuf_free(buf);
+
+ return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS lim_send_delba_action_frame(struct mac_context *mac_ctx,
+ uint8_t vdev_id, uint8_t *peer_macaddr,
+ uint8_t tid, uint8_t reason_code)
+{
+ struct pe_session *session;
+ struct sDot11fdelba_req frm;
+ QDF_STATUS qdf_status;
+ tpSirMacMgmtHdr mgmt_hdr;
+ uint32_t num_bytes, payload_size = 0;
+ uint32_t status;
+ void *pkt_ptr = NULL;
+ uint8_t *frame_ptr;
+ uint8_t tx_flag = 0;
+
+ session = pe_find_session_by_sme_session_id(mac_ctx, vdev_id);
+ if (!session) {
+ pe_debug("delba invalid vdev id %d ", vdev_id);
+ return QDF_STATUS_E_INVAL;
+ }
+ pe_debug("send delba vdev %d %pM tid %d reason %d", vdev_id,
+ peer_macaddr, tid, reason_code);
+ qdf_mem_zero((uint8_t *)&frm, sizeof(frm));
+ frm.Category.category = ACTION_CATEGORY_BACK;
+ frm.Action.action = DELBA;
+ frm.delba_param_set.initiator = 0;
+ frm.delba_param_set.tid = tid;
+ frm.Reason.code = reason_code;
+
+ status = dot11f_get_packed_delba_req_size(mac_ctx, &frm, &payload_size);
+ if (DOT11F_FAILED(status)) {
+ pe_err("Failed to calculate the packed size for a DELBA(0x%08x).",
+ status);
+ /* We'll fall back on the worst case scenario: */
+ payload_size = sizeof(struct sDot11fdelba_req);
+ } else if (DOT11F_WARNED(status)) {
+ pe_warn("Warnings in calculating the packed size for a DELBA (0x%08x).",
+ status);
+ }
+ num_bytes = payload_size + sizeof(*mgmt_hdr);
+ qdf_status = cds_packet_alloc(num_bytes, (void **)&frame_ptr,
+ (void **)&pkt_ptr);
+ if (!QDF_IS_STATUS_SUCCESS(qdf_status) || !pkt_ptr) {
+ pe_err("Failed to allocate %d bytes for a DELBA",
+ num_bytes);
+ return QDF_STATUS_E_FAILURE;
+ }
+ qdf_mem_zero(frame_ptr, num_bytes);
+
+ lim_populate_mac_header(mac_ctx, frame_ptr, SIR_MAC_MGMT_FRAME,
+ SIR_MAC_MGMT_ACTION, peer_macaddr,
+ session->self_mac_addr);
+
+ /* Update A3 with the BSSID */
+ mgmt_hdr = (tpSirMacMgmtHdr)frame_ptr;
+ sir_copy_mac_addr(mgmt_hdr->bssId, session->bssId);
+
+ /* DEL is a robust mgmt action frame,
+ * set the "protect" (aka WEP) bit in the FC
+ */
+ lim_set_protected_bit(mac_ctx, session, peer_macaddr, mgmt_hdr);
+
+ status = dot11f_pack_delba_req(mac_ctx, &frm,
+ frame_ptr + sizeof(tSirMacMgmtHdr),
+ payload_size, &payload_size);
+ if (DOT11F_FAILED(status)) {
+ pe_err("Failed to pack a DELBA Response (0x%08x)",
+ status);
+ qdf_status = QDF_STATUS_E_FAILURE;
+ goto error_delba;
+ } else if (DOT11F_WARNED(status)) {
+ pe_warn("There were warnings while packing DELBA Response (0x%08x)",
+ status);
+ }
+ if (BAND_5G == lim_get_rf_band(session->currentOperChannel) ||
+ session->opmode == QDF_P2P_CLIENT_MODE ||
+ session->opmode == QDF_P2P_GO_MODE)
+ tx_flag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
+ MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
+ session->peSessionId, mgmt_hdr->fc.subType));
+ qdf_status = wma_tx_frameWithTxComplete(mac_ctx, pkt_ptr,
+ (uint16_t)num_bytes,
+ TXRX_FRM_802_11_MGMT,
+ ANI_TXDIR_TODS, 7,
+ NULL, frame_ptr,
+ lim_delba_tx_complete_cnf,
+ tx_flag, vdev_id,
+ false, 0, RATEID_DEFAULT);
+ if (qdf_status != QDF_STATUS_SUCCESS) {
+ pe_err("delba wma_tx_frame FAILED! Status [%d]", qdf_status);
+ return qdf_status;
+ } else {
+ return QDF_STATUS_SUCCESS;
+ }
+
+error_delba:
+ if (pkt_ptr)
+ cds_packet_free((void *)pkt_ptr);
+
+ return qdf_status;
+}
+
+/**
* lim_tx_mgmt_frame() - Transmits Auth mgmt frame
* @mac_ctx Pointer to Global MAC structure
* @mb_msg: Received message info
diff --git a/core/mac/src/pe/lim/lim_types.h b/core/mac/src/pe/lim/lim_types.h
index 19eabdea78..99df02bac4 100644
--- a/core/mac/src/pe/lim/lim_types.h
+++ b/core/mac/src/pe/lim/lim_types.h
@@ -1097,6 +1097,22 @@ QDF_STATUS lim_send_addba_response_frame(struct mac_context *mac_ctx,
struct pe_session *session,
uint8_t addba_extn_present,
uint8_t amsdu_support);
+
+/**
+ * lim_send_delba_action_frame() - Send delba to peer
+ * @mac_ctx: mac context
+ * @vdev_id: vdev id
+ * @peer_macaddr: Peer mac addr
+ * @tid: Tid number
+ * @reason_code: reason code
+ *
+ * Return: 0 for success, non-zero for failure
+ */
+QDF_STATUS lim_send_delba_action_frame(struct mac_context *mac_ctx,
+ uint8_t vdev_id,
+ uint8_t *peer_macaddr, uint8_t tid,
+ uint8_t reason_code);
+
/**
* lim_process_join_failure_timeout() - This function is called to process
* JoinFailureTimeout
diff --git a/core/mac/src/pe/lim/lim_utils.h b/core/mac/src/pe/lim/lim_utils.h
index 9c0f053606..6ae3f80465 100644
--- a/core/mac/src/pe/lim/lim_utils.h
+++ b/core/mac/src/pe/lim/lim_utils.h
@@ -1514,6 +1514,18 @@ void lim_rx_invalid_peer_process(struct mac_context *mac_ctx,
struct scheduler_msg *lim_msg);
/**
+ * lim_req_send_delba_ind_process() - process send delba indication
+ * @mac_ctx: mac context
+ * @lim_msg: lim message
+ *
+ * This function will process the send delba indication from DP.
+ *
+ * Return: None
+ */
+void lim_req_send_delba_ind_process(struct mac_context *mac_ctx,
+ struct scheduler_msg *lim_msg);
+
+/**
* lim_send_beacon() - send beacon indication to firmware
* @mac_ctx: Pointer to Global MAC structure
* @session: session pointer
diff --git a/core/wma/inc/wma.h b/core/wma/inc/wma.h
index ab359517a7..3cc4a4d5f1 100644
--- a/core/wma/inc/wma.h
+++ b/core/wma/inc/wma.h
@@ -2573,6 +2573,21 @@ void wma_delete_invalid_peer_entries(uint8_t vdev_id, uint8_t *peer_mac_addr);
uint8_t wma_rx_invalid_peer_ind(uint8_t vdev_id, void *wh);
/**
+ * wma_dp_send_delba_ind() - the callback for DP to notify WMA layer
+ * to del ba of rx
+ * @vdev_id: vdev id
+ * @peer_macaddr: peer mac address
+ * @tid: tid of rx
+ * @reason_code: reason code
+ *
+ * Return: 0 for success or non-zero on failure
+ */
+int wma_dp_send_delba_ind(uint8_t vdev_id,
+ uint8_t *peer_macaddr,
+ uint8_t tid,
+ uint8_t reason_code);
+
+/**
* is_roam_inprogress() - Is vdev in progress
* @vdev_id: vdev of interest
*
diff --git a/core/wma/src/wma_data.c b/core/wma/src/wma_data.c
index 2bb3bf0d20..00888aee82 100644
--- a/core/wma/src/wma_data.c
+++ b/core/wma/src/wma_data.c
@@ -3421,6 +3421,31 @@ uint8_t wma_rx_invalid_peer_ind(uint8_t vdev_id, void *wh)
return 0;
}
+int wma_dp_send_delba_ind(uint8_t vdev_id, uint8_t *peer_macaddr,
+ uint8_t tid, uint8_t reason_code)
+{
+ tp_wma_handle wma = cds_get_context(QDF_MODULE_ID_WMA);
+ struct lim_delba_req_info *req;
+
+ if (!wma || !peer_macaddr) {
+ wma_err("wma handle or mac addr is NULL");
+ return -EINVAL;
+ }
+ req = qdf_mem_malloc(sizeof(*req));
+ if (!req)
+ return -ENOMEM;
+ req->vdev_id = vdev_id;
+ qdf_mem_copy(req->peer_macaddr, peer_macaddr, QDF_MAC_ADDR_SIZE);
+ req->tid = tid;
+ req->reason_code = reason_code;
+ WMA_LOGD("req delba_ind vdev %d %pM tid %d reason %d",
+ vdev_id, peer_macaddr, tid, reason_code);
+ wma_send_msg_high_priority(wma, SIR_HAL_REQ_SEND_DELBA_REQ_IND,
+ (void *)req, 0);
+
+ return 0;
+}
+
bool wma_is_roam_in_progress(uint32_t vdev_id)
{
tp_wma_handle wma = cds_get_context(QDF_MODULE_ID_WMA);