mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-14 16:46:15 -04:00
qcacmn: Add support for TX path for mgmt_txrx
Add support for Tx path and TX completion path for mgmt_txrx for the converged umac. Change-Id: I964ee78ae4f6ff1fc5f26a6f7d16ae6b4e50bbee CRS Fixed: 1103247
This commit is contained in:
parent
b7388515b9
commit
f0d971512c
5 changed files with 219 additions and 6 deletions
|
|
@ -110,7 +110,8 @@ struct mgmt_txrx_desc_elem_t *wlan_mgmt_txrx_desc_get(
|
|||
!= QDF_STATUS_SUCCESS) {
|
||||
qdf_spin_unlock_bh(
|
||||
&mgmt_txrx_ctx->mgmt_desc_pool.desc_pool_lock);
|
||||
mgmt_txrx_err("mgmt descriptor freelist is empty");
|
||||
mgmt_txrx_err("Descriptor freelist empty for mgmt_txrx_ctx %p",
|
||||
mgmt_txrx_ctx);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
@ -119,8 +120,8 @@ struct mgmt_txrx_desc_elem_t *wlan_mgmt_txrx_desc_get(
|
|||
if (status != QDF_STATUS_SUCCESS) {
|
||||
qdf_spin_unlock_bh(
|
||||
&mgmt_txrx_ctx->mgmt_desc_pool.desc_pool_lock);
|
||||
mgmt_txrx_err("Failed to get mgmt descriptor from freelist with status %d",
|
||||
status);
|
||||
mgmt_txrx_err("Failed to get descriptor from list: status %d",
|
||||
status);
|
||||
qdf_assert_always(0);
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -54,7 +54,8 @@ QDF_STATUS tgt_mgmt_txrx_rx_frame_handler(
|
|||
* @tx_compl_params: tx completion params
|
||||
*
|
||||
* This function handles tx completions of mgmt. frames and is registered to
|
||||
* LMAC_if layer through lmac_if cbs.
|
||||
* LMAC_if layer through lmac_if cbs.The cb needs to free the nbuf. In case no
|
||||
* callback is registered, this function will free the nbuf.
|
||||
*
|
||||
* Return: QDF_STATUS_SUCCESS - in case of success
|
||||
*/
|
||||
|
|
@ -100,7 +101,7 @@ tgt_mgmt_txrx_get_peer_from_desc_id(
|
|||
* This function extracts vdev id from mgmt desc extracted from desc id.
|
||||
*
|
||||
* Return: vdev_id - in case of success
|
||||
* 0 - in case of failure
|
||||
* WLAN_UMAC_VDEV_ID_MAX - in case of failure
|
||||
*/
|
||||
uint8_t tgt_mgmt_txrx_get_vdev_id_from_desc_id(
|
||||
struct wlan_objmgr_psoc *psoc,
|
||||
|
|
|
|||
|
|
@ -884,6 +884,64 @@ QDF_STATUS tgt_mgmt_txrx_tx_completion_handler(
|
|||
uint32_t desc_id, uint32_t status,
|
||||
void *tx_compl_params)
|
||||
{
|
||||
struct mgmt_txrx_priv_context *mgmt_txrx_ctx;
|
||||
struct mgmt_txrx_desc_elem_t *mgmt_desc;
|
||||
void *cb_context;
|
||||
mgmt_tx_download_comp_cb tx_compl_cb;
|
||||
mgmt_ota_comp_cb ota_comp_cb;
|
||||
qdf_nbuf_t nbuf;
|
||||
|
||||
mgmt_txrx_ctx = (struct mgmt_txrx_priv_context *)
|
||||
wlan_objmgr_psoc_get_comp_private_obj(psoc,
|
||||
WLAN_UMAC_COMP_MGMT_TXRX);
|
||||
if (!mgmt_txrx_ctx) {
|
||||
mgmt_txrx_err("Mgmt txrx context empty for psoc %p", psoc);
|
||||
return QDF_STATUS_E_NULL_VALUE;
|
||||
}
|
||||
mgmt_desc = &mgmt_txrx_ctx->mgmt_desc_pool.pool[desc_id];
|
||||
if (!mgmt_desc) {
|
||||
mgmt_txrx_err("Mgmt desc empty for id %d psoc %p ",
|
||||
desc_id, psoc);
|
||||
return QDF_STATUS_E_NULL_VALUE;
|
||||
}
|
||||
tx_compl_cb = mgmt_desc->tx_dwnld_cmpl_cb;
|
||||
ota_comp_cb = mgmt_desc->tx_ota_cmpl_cb;
|
||||
nbuf = mgmt_desc->nbuf;
|
||||
|
||||
/*
|
||||
* TO DO
|
||||
* Make the API more generic to handle tx download completion as well
|
||||
* as OTA completion separately.
|
||||
*/
|
||||
|
||||
/*
|
||||
* 1. If the tx frame is sent by any UMAC converged component then it
|
||||
* passes the context as NULL while calling mgmt txrx API for
|
||||
* sending mgmt frame. If context is NULL, peer will be passed as
|
||||
* cb_context in completion callbacks.
|
||||
* 2. If the tx frame is sent by legacy MLME then it passes the context
|
||||
* as its specific context (for ex- mac context in case of MCL) while
|
||||
* calling mgmt txrx API for sending mgmt frame. This caller specific
|
||||
* context is passed as cb_context in completion callbacks.
|
||||
*/
|
||||
if (mgmt_desc->context)
|
||||
cb_context = mgmt_desc->context;
|
||||
else
|
||||
cb_context = (void *)mgmt_desc->peer;
|
||||
|
||||
if (!tx_compl_cb && !ota_comp_cb) {
|
||||
qdf_nbuf_free(nbuf);
|
||||
goto no_registered_cb;
|
||||
}
|
||||
|
||||
if (tx_compl_cb)
|
||||
tx_compl_cb(cb_context, nbuf, status);
|
||||
|
||||
if (ota_comp_cb)
|
||||
ota_comp_cb(cb_context, nbuf, status, tx_compl_params);
|
||||
|
||||
no_registered_cb:
|
||||
wlan_mgmt_txrx_desc_put(mgmt_txrx_ctx, desc_id);
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
@ -891,6 +949,27 @@ qdf_nbuf_t tgt_mgmt_txrx_get_nbuf_from_desc_id(
|
|||
struct wlan_objmgr_psoc *psoc,
|
||||
uint32_t desc_id)
|
||||
{
|
||||
struct mgmt_txrx_priv_context *mgmt_txrx_ctx;
|
||||
struct mgmt_txrx_desc_elem_t *mgmt_desc;
|
||||
qdf_nbuf_t buf;
|
||||
|
||||
mgmt_txrx_ctx = (struct mgmt_txrx_priv_context *)
|
||||
wlan_objmgr_psoc_get_comp_private_obj(psoc,
|
||||
WLAN_UMAC_COMP_MGMT_TXRX);
|
||||
if (!mgmt_txrx_ctx) {
|
||||
mgmt_txrx_err("Mgmt txrx context empty for psoc %p", psoc);
|
||||
goto fail;
|
||||
}
|
||||
mgmt_desc = &mgmt_txrx_ctx->mgmt_desc_pool.pool[desc_id];
|
||||
if (!mgmt_desc) {
|
||||
mgmt_txrx_err("Mgmt descriptor unavailable for id %d psoc %p",
|
||||
desc_id, psoc);
|
||||
goto fail;
|
||||
}
|
||||
buf = mgmt_desc->nbuf;
|
||||
return buf;
|
||||
|
||||
fail:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
@ -899,6 +978,29 @@ tgt_mgmt_txrx_get_peer_from_desc_id(
|
|||
struct wlan_objmgr_psoc *psoc,
|
||||
uint32_t desc_id)
|
||||
{
|
||||
struct mgmt_txrx_priv_context *mgmt_txrx_ctx;
|
||||
struct mgmt_txrx_desc_elem_t *mgmt_desc;
|
||||
struct wlan_objmgr_peer *peer;
|
||||
|
||||
mgmt_txrx_ctx = (struct mgmt_txrx_priv_context *)
|
||||
wlan_objmgr_psoc_get_comp_private_obj(psoc,
|
||||
WLAN_UMAC_COMP_MGMT_TXRX);
|
||||
if (!mgmt_txrx_ctx) {
|
||||
mgmt_txrx_err("Mgmt txrx context empty for psoc %p", psoc);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
mgmt_desc = &mgmt_txrx_ctx->mgmt_desc_pool.pool[desc_id];
|
||||
if (!mgmt_desc) {
|
||||
mgmt_txrx_err("Mgmt descriptor unavailable for id %d psoc %p",
|
||||
desc_id, psoc);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
peer = mgmt_desc->peer;
|
||||
return peer;
|
||||
|
||||
fail:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
@ -906,5 +1008,28 @@ uint8_t tgt_mgmt_txrx_get_vdev_id_from_desc_id(
|
|||
struct wlan_objmgr_psoc *psoc,
|
||||
uint32_t desc_id)
|
||||
{
|
||||
return 0;
|
||||
struct mgmt_txrx_priv_context *mgmt_txrx_ctx;
|
||||
struct mgmt_txrx_desc_elem_t *mgmt_desc;
|
||||
uint8_t vdev_id;
|
||||
|
||||
mgmt_txrx_ctx = (struct mgmt_txrx_priv_context *)
|
||||
wlan_objmgr_psoc_get_comp_private_obj(psoc,
|
||||
WLAN_UMAC_COMP_MGMT_TXRX);
|
||||
if (!mgmt_txrx_ctx) {
|
||||
mgmt_txrx_err("Mgmt txrx context empty for psoc %p", psoc);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
mgmt_desc = &mgmt_txrx_ctx->mgmt_desc_pool.pool[desc_id];
|
||||
if (!mgmt_desc) {
|
||||
mgmt_txrx_err("Mgmt descriptor unavailable for id %d psoc %p",
|
||||
desc_id, psoc);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
vdev_id = mgmt_desc->vdev_id;
|
||||
return vdev_id;
|
||||
|
||||
fail:
|
||||
return WLAN_UMAC_VDEV_ID_MAX;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,6 +26,9 @@
|
|||
#include "wlan_mgmt_txrx_main_i.h"
|
||||
#include "wlan_objmgr_psoc_obj.h"
|
||||
#include "wlan_objmgr_global_obj.h"
|
||||
#include "wlan_objmgr_pdev_obj.h"
|
||||
#include "wlan_objmgr_vdev_obj.h"
|
||||
#include "wlan_objmgr_peer_obj.h"
|
||||
#include "qdf_nbuf.h"
|
||||
|
||||
/**
|
||||
|
|
@ -210,6 +213,60 @@ QDF_STATUS wlan_mgmt_txrx_mgmt_frame_tx(struct wlan_objmgr_peer *peer,
|
|||
enum wlan_umac_comp_id comp_id,
|
||||
void *mgmt_tx_params)
|
||||
{
|
||||
struct mgmt_txrx_desc_elem_t *desc;
|
||||
struct wlan_objmgr_psoc *psoc;
|
||||
struct mgmt_txrx_priv_context *txrx_ctx;
|
||||
struct wlan_objmgr_vdev *vdev;
|
||||
struct wlan_objmgr_vdev_objmgr *vdev_obj;
|
||||
|
||||
vdev = wlan_peer_get_vdev(peer);
|
||||
if (!vdev) {
|
||||
mgmt_txrx_err("vdev unavailable for peer %p psoc %p",
|
||||
peer, psoc);
|
||||
return QDF_STATUS_E_NULL_VALUE;
|
||||
}
|
||||
|
||||
psoc = wlan_vdev_get_psoc(vdev);
|
||||
if (!psoc) {
|
||||
mgmt_txrx_err("psoc unavailable for peer %p vdev %p",
|
||||
peer, vdev);
|
||||
return QDF_STATUS_E_NULL_VALUE;
|
||||
}
|
||||
|
||||
txrx_ctx = (struct mgmt_txrx_priv_context *)
|
||||
wlan_objmgr_psoc_get_comp_private_obj(psoc,
|
||||
WLAN_UMAC_COMP_MGMT_TXRX);
|
||||
if (!txrx_ctx) {
|
||||
mgmt_txrx_err("No txrx context for peer %p psoc %p",
|
||||
peer, psoc);
|
||||
return QDF_STATUS_E_NULL_VALUE;
|
||||
}
|
||||
|
||||
desc = wlan_mgmt_txrx_desc_get(txrx_ctx);
|
||||
if (!desc)
|
||||
return QDF_STATUS_E_RESOURCES;
|
||||
|
||||
desc->nbuf = buf;
|
||||
desc->tx_ota_cmpl_cb = tx_ota_comp_cb;
|
||||
desc->tx_dwnld_cmpl_cb = tx_comp_cb;
|
||||
desc->peer = peer;
|
||||
desc->vdev_id = vdev_obj->vdev_id;
|
||||
desc->context = context;
|
||||
|
||||
if (!psoc->soc_cb.tx_ops.mgmt_txrx_tx_ops.mgmt_tx_send) {
|
||||
mgmt_txrx_err("mgmt txrx tx op to send mgmt frame is NULL for psoc: %p",
|
||||
psoc);
|
||||
wlan_mgmt_txrx_desc_put(txrx_ctx, desc->desc_id);
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
}
|
||||
|
||||
if (psoc->soc_cb.tx_ops.mgmt_txrx_tx_ops.mgmt_tx_send(
|
||||
vdev, buf, desc->desc_id, mgmt_tx_params)) {
|
||||
mgmt_txrx_err("Mgmt send fail for peer %p psoc %p",
|
||||
peer, psoc);
|
||||
wlan_mgmt_txrx_desc_put(txrx_ctx, desc->desc_id);
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
}
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
@ -217,6 +274,32 @@ QDF_STATUS wlan_mgmt_txrx_beacon_frame_tx(struct wlan_objmgr_peer *peer,
|
|||
qdf_nbuf_t buf,
|
||||
enum wlan_umac_comp_id comp_id)
|
||||
{
|
||||
struct wlan_objmgr_vdev *vdev;
|
||||
struct wlan_objmgr_psoc *psoc;
|
||||
|
||||
vdev = wlan_peer_get_vdev(peer);
|
||||
if (!vdev) {
|
||||
mgmt_txrx_err("vdev unavailable for peer %p", peer);
|
||||
return QDF_STATUS_E_NULL_VALUE;
|
||||
}
|
||||
|
||||
psoc = wlan_vdev_get_psoc(vdev);
|
||||
if (!psoc) {
|
||||
mgmt_txrx_err("psoc unavailable for peer %p", peer);
|
||||
return QDF_STATUS_E_NULL_VALUE;
|
||||
}
|
||||
|
||||
if (!psoc->soc_cb.tx_ops.mgmt_txrx_tx_ops.beacon_send) {
|
||||
mgmt_txrx_err("mgmt txrx tx op to send beacon frame is NULL for psoc: %p",
|
||||
psoc);
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
}
|
||||
|
||||
if (psoc->soc_cb.tx_ops.mgmt_txrx_tx_ops.beacon_send(vdev, buf)) {
|
||||
mgmt_txrx_err("Beacon send fail for peer %p psoc %p",
|
||||
peer, psoc);
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
}
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -48,6 +48,9 @@
|
|||
/* Max no. of peers for STA vap */
|
||||
#define WLAN_UMAC_MAX_STA_PEERS 2
|
||||
|
||||
/* Max vdev_id */
|
||||
#define WLAN_UMAC_VDEV_ID_MAX 0xFF
|
||||
|
||||
/* 802.11 cap info */
|
||||
#define WLAN_CAPINFO_ESS 0x0001
|
||||
#define WLAN_CAPINFO_IBSS 0x0002
|
||||
|
|
|
|||
Loading…
Reference in a new issue