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
This commit is contained in:
Liangwei Dong 2020-03-07 20:31:44 +08:00 committed by nshrivas
parent 28c369d508
commit 1a4edd541e
10 changed files with 279 additions and 1 deletions

View File

@ -89,6 +89,14 @@ static struct __qdf_device g_qdf_ctx;
static uint8_t cds_multicast_logging;
#ifdef QCA_WIFI_QCA8074
static inline int
cds_send_delba(struct cdp_ctrl_objmgr_psoc *psoc,
uint8_t vdev_id, uint8_t *peer_macaddr,
uint8_t tid, uint8_t reason_code)
{
return wma_dp_send_delba_ind(vdev_id, 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,
@ -97,7 +105,8 @@ static struct ol_if_ops dp_ol_if_ops = {
.lro_hash_config = target_if_lro_hash_config,
.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

View File

@ -654,6 +654,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 */

View File

@ -491,4 +491,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

View File

@ -584,3 +584,27 @@ 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 *dp_soc = cds_get_context(QDF_MODULE_ID_SOC);
if (!req) {
pe_err("Invalid body pointer in message");
return;
}
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(dp_soc, req->peer_macaddr,
req->vdev_id, req->tid,
WMI_MGMT_TX_COMP_TYPE_DISCARD);
qdf_mem_free(req);
lim_msg->bodyptr = NULL;
}

View File

@ -1841,6 +1841,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:

View File

@ -5116,6 +5116,165 @@ error_addba_rsp:
return qdf_status;
}
/**
* lim_delba_tx_complete_cnf() - Confirmation for Delba OTA
* @context: pointer to global mac
* @buf: netbuf of 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);
uint32_t frame_len;
QDF_STATUS status;
uint8_t *data;
struct wmi_mgmt_params *mgmt_params = (struct wmi_mgmt_params *)params;
if (!mgmt_params || !mac_ctx || !buf || !soc) {
pe_err("delba tx cnf invalid parameters");
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;
}
pe_debug("delba ota done vdev %d %pM tid %d desc_id %d status %d",
mgmt_params->vdev_id, mac_hdr->da, frm.delba_param_set.tid,
mgmt_params->desc_id, tx_complete);
cdp_delba_tx_completion(soc, mac_hdr->da, mgmt_params->vdev_id,
frm.delba_param_set.tid, tx_complete);
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_vdev_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 (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 (0x%08x)",
status);
}
if (wlan_reg_is_5ghz_ch_freq(session->curr_op_freq) ||
wlan_reg_is_6ghz_chan_freq(session->curr_op_freq) ||
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

View File

@ -1163,6 +1163,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, uint8_t is_wep);
/**
* 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

View File

@ -1806,6 +1806,18 @@ static inline void lim_set_peer_twt_cap(struct pe_session *session,
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

View File

@ -2395,6 +2395,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

View File

@ -3196,6 +3196,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);