diff options
author | Liangwei Dong <liangwei@codeaurora.org> | 2020-03-07 20:31:44 +0800 |
---|---|---|
committer | nshrivas <nshrivas@codeaurora.org> | 2020-03-27 23:57:27 -0700 |
commit | 99b22c0027d7202f7e4f07f2843b90c46382dc7f (patch) | |
tree | 4341a2667de5b8e3ddbb9f07aa4e0c1be766dd82 | |
parent | a028a3db7100efc1994c54a033c9af4345093f5a (diff) | |
download | qcacld-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.c | 14 | ||||
-rw-r--r-- | core/mac/src/include/sir_params.h | 2 | ||||
-rw-r--r-- | core/mac/src/pe/include/lim_global.h | 13 | ||||
-rw-r--r-- | core/mac/src/pe/lim/lim_link_monitoring_algo.c | 41 | ||||
-rw-r--r-- | core/mac/src/pe/lim/lim_process_message_queue.c | 3 | ||||
-rw-r--r-- | core/mac/src/pe/lim/lim_send_management_frames.c | 171 | ||||
-rw-r--r-- | core/mac/src/pe/lim/lim_types.h | 16 | ||||
-rw-r--r-- | core/mac/src/pe/lim/lim_utils.h | 12 | ||||
-rw-r--r-- | core/wma/inc/wma.h | 15 | ||||
-rw-r--r-- | core/wma/src/wma_data.c | 25 |
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); |