qcacmn: mgmt frame txrx

Modify P2P IE and tx mgmt frame. Handles tx confirm and rx frame
events.

Change-Id: I0c0ada2e12ee5ebdd3e8d7b7a6f2bd2af4357548
CRs-Fixed: 2015297
Bu işleme şunda yer alıyor:
Wu Gao
2017-03-22 13:18:15 +08:00
işlemeyi yapan: Sandeep Puligilla
ebeveyn 26781f65dc
işleme dfc571c521
13 değiştirilmiş dosya ile 1964 ekleme ve 10 silme

Dosyayı Görüntüle

@@ -127,6 +127,7 @@ static void wlan_p2p_action_tx_cnf_callback(void *user_data,
struct wlan_objmgr_vdev *vdev;
struct vdev_osif_priv *osif_priv;
struct wireless_dev *wdev;
bool is_success;
cfg80211_info("user data:%p, action cookie:%llx, buf:%p, len:%d, tx status:%d",
user_data, tx_cnf->action_cookie, tx_cnf->buf,
@@ -159,11 +160,12 @@ static void wlan_p2p_action_tx_cnf_callback(void *user_data,
goto fail;
}
is_success = tx_cnf->status ? false : true;
cfg80211_mgmt_tx_status(
wdev,
tx_cnf->action_cookie,
tx_cnf->buf, tx_cnf->buf_len,
(bool)tx_cnf->status, GFP_KERNEL);
is_success, GFP_KERNEL);
fail:
wlan_objmgr_vdev_release_ref(vdev, WLAN_P2P_ID);
}
@@ -360,7 +362,7 @@ int wlan_cfg80211_roc(struct wlan_objmgr_vdev *vdev,
wlan_vdev_obj_unlock(vdev);
if (!psoc) {
cfg80211_err("psoc handle is NULL");
return QDF_STATUS_E_INVAL;
return -EINVAL;
}
roc_req.chan = (uint32_t)wlan_freq_to_chan(chan->center_freq);
@@ -386,7 +388,7 @@ int wlan_cfg80211_cancel_roc(struct wlan_objmgr_vdev *vdev,
wlan_vdev_obj_unlock(vdev);
if (!psoc) {
cfg80211_err("psoc handle is NULL");
return QDF_STATUS_E_INVAL;
return -EINVAL;
}
return qdf_status_to_os_return(
@@ -419,7 +421,7 @@ int wlan_cfg80211_mgmt_tx(struct wlan_objmgr_vdev *vdev,
wlan_vdev_obj_unlock(vdev);
if (!psoc) {
cfg80211_err("psoc handle is NULL");
return QDF_STATUS_E_INVAL;
return -EINVAL;
}
mgmt_tx.vdev_id = (uint32_t)vdev_id;
@@ -428,6 +430,7 @@ int wlan_cfg80211_mgmt_tx(struct wlan_objmgr_vdev *vdev,
mgmt_tx.len = len;
mgmt_tx.no_cck = (uint32_t)no_cck;
mgmt_tx.dont_wait_for_ack = (uint32_t)dont_wait_for_ack;
mgmt_tx.off_chan = (uint32_t)offchan;
mgmt_tx.buf = buf;
return qdf_status_to_os_return(
@@ -449,7 +452,7 @@ int wlan_cfg80211_mgmt_tx_cancel(struct wlan_objmgr_vdev *vdev,
wlan_vdev_obj_unlock(vdev);
if (!psoc) {
cfg80211_err("psoc handle is NULL");
return QDF_STATUS_E_INVAL;
return -EINVAL;
}
return qdf_status_to_os_return(

Dosyayı Görüntüle

@@ -462,6 +462,24 @@ struct wlan_frame_hdr {
uint8_t i_seq[2];
} qdf_packed;
/* sequence number offset base on begin of mac header */
#define WLAN_SEQ_CTL_OFFSET 22
#define WLAN_LOW_SEQ_NUM_MASK 0x000F
#define WLAN_HIGH_SEQ_NUM_MASK 0x0FF0
#define WLAN_HIGH_SEQ_NUM_OFFSET 4
/**
* struct wlan_seq_ctl: sequence number control
* @frag_num: frag number
* @seq_num_lo: sequence number low byte
* @seq_num_hi: sequence number high byte
*/
struct wlan_seq_ctl {
uint8_t frag_num:4;
uint8_t seq_num_lo:4;
uint8_t seq_num_hi:8;
} qdf_packed;
/**
* union wlan_capability : wlan_capability info
* @value: capability value
@@ -727,7 +745,6 @@ struct rsn_mdie {
uint8_t ft_capab;
} qdf_packed;
/**
* is_wpa_oui() - If vendor IE is WPA type
* @frm: vendor IE pointer

Dosyayı Görüntüle

@@ -89,6 +89,8 @@
#define WLAN_CHAN_15_FREQ (2512)
#define WLAN_CHAN_170_FREQ (5852)
#define WLAN_MAC_EID_VENDOR 221
/**
* enum wlan_umac_comp_id - UMAC component id
* @WLAN_UMAC_COMP_MLME: MLME

Dosyayı Görüntüle

@@ -49,4 +49,19 @@ bool wlan_is_dsrc_channel(uint16_t center_freq);
*/
uint8_t wlan_freq_to_chan(uint32_t freq);
/**
* wlan_get_vendor_ie_ptr_from_oui() - Find out vendor ie
* @oui: oui buffer
* @oui_size: oui size
* @ie: source ie address
* @ie_len: source ie length
*
* This function find out vendor ie by pass source ie and vendor oui.
*
* Return: vendor ie address - success
* NULL - failure
*/
uint8_t *wlan_get_vendor_ie_ptr_from_oui(uint8_t *oui,
uint8_t oui_size, uint8_t *ie, uint16_t ie_len);
#endif /* _WLAN_UTILITY_H_ */

Dosyayı Görüntüle

@@ -69,3 +69,28 @@ uint8_t wlan_freq_to_chan(uint32_t freq)
return chan;
}
uint8_t *wlan_get_vendor_ie_ptr_from_oui(uint8_t *oui,
uint8_t oui_size, uint8_t *ie, uint16_t ie_len)
{
int32_t left = ie_len;
uint8_t *ptr = ie;
uint8_t elem_id, elem_len;
while (left >= 2) {
elem_id = ptr[0];
elem_len = ptr[1];
left -= 2;
if (elem_len > left)
return NULL;
if (WLAN_MAC_EID_VENDOR == elem_id) {
if (memcmp(&ptr[2], oui, oui_size) == 0)
return ptr;
}
left -= elem_len;
ptr += (elem_len + 2);
}
return NULL;
}

Dosyayı Görüntüle

@@ -579,6 +579,7 @@ QDF_STATUS p2p_psoc_stop(struct wlan_objmgr_psoc *soc)
}
/* clean up queue of p2p psoc private object */
p2p_cleanup_tx_queue(p2p_soc_obj);
p2p_cleanup_roc_queue(p2p_soc_obj);
/* unrgister scan request id*/

Dosyayı Görüntüle

@@ -53,6 +53,7 @@ struct p2p_rx_mgmt_frame;
struct p2p_lo_event;
struct p2p_start_param;
struct p2p_noa_info;
struct tx_action_context;
/**
* enum p2p_cmd_type - P2P request type
@@ -88,10 +89,12 @@ enum p2p_event_type {
* struct p2p_tx_conf_event - p2p tx confirm event
* @p2p_soc_obj: p2p soc private object
* @tx_cnf: p2p tx confirm structure
* @tx_ctx: tx context
*/
struct p2p_tx_conf_event {
struct p2p_soc_priv_obj *p2p_soc_obj;
struct p2p_tx_cnf *tx_cnf;
struct tx_action_context *tx_ctx;
};
/**

Dosya farkı çok büyük olduğundan ihmal edildi Fark Yükle

Dosyayı Görüntüle

@@ -26,18 +26,122 @@
#include <qdf_types.h>
#include <qdf_mc_timer.h>
#define P2P_EID_VENDOR 0xdd
#define P2P_ACTION_VENDOR_SPECIFIC_CATEGORY 0x7F
#define P2P_PUBLIC_ACTION_FRAME 0x4
#define P2P_MAC_MGMT_ACTION 0xD
#define P2P_PUBLIC_ACTION_VENDOR_SPECIFIC 0x9
#define P2P_NOA_ATTR 0xC
#define P2P_MAX_NOA_ATTR_LEN 31
#define P2P_IE_HEADER_LEN 6
#define P2P_MAX_IE_LENGTH 255
#define P2P_ACTION_OFFSET 24
#define P2P_PUBLIC_ACTION_FRAME_TYPE_OFFSET 30
#define P2P_ACTION_FRAME_TYPE_OFFSET 29
#define PROBE_RSP_IE_OFFSET 36
#define P2P_TX_PKT_MIN_HEADROOM (64)
#define P2P_OUI "\x50\x6f\x9a\x09"
#define P2P_OUI_SIZE 4
#define P2P_ACTION_FRAME_RSP_WAIT 500
#define P2P_ACTION_FRAME_ACK_WAIT 300
#define P2P_ACTION_FRAME_TX_TIMEOUT 2000
#define P2P_NOA_STREAM_ARR_SIZE (P2P_MAX_NOA_ATTR_LEN + (2 * P2P_IE_HEADER_LEN))
#define P2P_GET_TYPE_FRM_FC(__fc__) (((__fc__) & 0x0F) >> 2)
#define P2P_GET_SUBTYPE_FRM_FC(__fc__) (((__fc__) & 0xF0) >> 4)
struct p2p_soc_priv_obj;
struct cancel_roc_context;
struct p2p_tx_conf_event;
struct p2p_rx_mgmt_event;
/**
* enum p2p_frame_type - frame type
* @P2P_FRAME_MGMT: mgmt frame
* @P2P_FRAME_NOT_SUPPORT: not support frame type
*/
enum p2p_frame_type {
P2P_FRAME_MGMT = 0,
P2P_FRAME_NOT_SUPPORT,
};
/**
* enum p2p_frame_sub_type - frame sub type
* @P2P_MGMT_PROBE_REQ: probe request frame
* @P2P_MGMT_PROBE_RSP: probe response frame
* @P2P_MGMT_ACTION: action frame
* @P2P_MGMT_NOT_SUPPORT: not support sub frame type
*/
enum p2p_frame_sub_type {
P2P_MGMT_PROBE_REQ = 4,
P2P_MGMT_PROBE_RSP,
P2P_MGMT_ACTION = 13,
P2P_MGMT_NOT_SUPPORT,
};
/**
* enum p2p_public_action_type - public action frame type
* @P2P_PUBLIC_ACTION_NEG_REQ: go negotiation request frame
* @P2P_PUBLIC_ACTION_NEG_RSP: go negotiation response frame
* @P2P_PUBLIC_ACTION_NEG_CNF: go negotiation confirm frame
* @P2P_PUBLIC_ACTION_INVIT_REQ: p2p invitation request frame
* @P2P_PUBLIC_ACTION_INVIT_RSP: p2p invitation response frame
* @P2P_PUBLIC_ACTION_DEV_DIS_REQ: device discoverability request
* @P2P_PUBLIC_ACTION_DEV_DIS_RSP: device discoverability response
* @P2P_PUBLIC_ACTION_PROV_DIS_REQ: provision discovery request
* @P2P_PUBLIC_ACTION_PROV_DIS_RSP: provision discovery response
* @P2P_PUBLIC_ACTION_GAS_INIT_REQ: gas initial request,
* @P2P_PUBLIC_ACTION_GAS_INIT_RSP: gas initial response
* @P2P_PUBLIC_ACTION_GAS_COMB_REQ: gas comeback request
* @P2P_PUBLIC_ACTION_GAS_COMB_RSP: gas comeback response
* @P2P_PUBLIC_ACTION_NOT_SUPPORT: not support p2p public action frame
*/
enum p2p_public_action_type {
P2P_PUBLIC_ACTION_NEG_REQ = 0,
P2P_PUBLIC_ACTION_NEG_RSP,
P2P_PUBLIC_ACTION_NEG_CNF,
P2P_PUBLIC_ACTION_INVIT_REQ,
P2P_PUBLIC_ACTION_INVIT_RSP,
P2P_PUBLIC_ACTION_DEV_DIS_REQ,
P2P_PUBLIC_ACTION_DEV_DIS_RSP,
P2P_PUBLIC_ACTION_PROV_DIS_REQ,
P2P_PUBLIC_ACTION_PROV_DIS_RSP,
P2P_PUBLIC_ACTION_GAS_INIT_REQ = 10,
P2P_PUBLIC_ACTION_GAS_INIT_RSP,
P2P_PUBLIC_ACTION_GAS_COMB_REQ,
P2P_PUBLIC_ACTION_GAS_COMB_RSP,
P2P_PUBLIC_ACTION_NOT_SUPPORT,
};
/**
* enum p2p_action_type - p2p action frame type
* @P2P_ACTION_PRESENCE_RSP: presence response frame
* @P2P_ACTION_NOT_SUPPORT: not support action frame type
*/
enum p2p_action_type {
P2P_ACTION_PRESENCE_RSP = 2,
P2P_ACTION_NOT_SUPPORT,
};
struct p2p_frame_info {
enum p2p_frame_type type;
enum p2p_frame_sub_type sub_type;
enum p2p_public_action_type public_action_type;
enum p2p_action_type action_type;
};
/**
* struct tx_action_context - tx action frame context
* @node: Node for next element in the list
* @p2p_soc_obj: Pointer to SoC global p2p private object
* @vdev_id: Vdev id on which this request has come
* @scan_id: Scan id given by scan component for this roc req
* @action_cookie: Action cookie
* @roc_cookie: Cookie for remain on channel request
* @chan: Chan for which this tx has been requested
* @buf: tx buffer
* @buf_len: Length of tx buffer
@@ -46,13 +150,14 @@ struct p2p_rx_mgmt_event;
* @no_ack: Required ack or not
* @duration: Duration for the RoC
* @tx_timer: RoC timer
* @frame_info: Frame type information
*/
struct tx_action_context {
qdf_list_node_t node;
struct p2p_soc_priv_obj *p2p_soc_obj;
int vdev_id;
int scan_id;
uint64_t action_cookie;
uint64_t roc_cookie;
uint8_t chan;
uint8_t *buf;
int buf_len;
@@ -61,8 +166,43 @@ struct tx_action_context {
bool no_ack;
uint32_t duration;
qdf_mc_timer_t tx_timer;
struct p2p_frame_info frame_info;
};
/**
* p2p_dump_tx_queue() - dump tx queue
* @p2p_soc_obj: p2p soc private object
*
* This function dumps tx queue and output details about tx context in
* queue.
*
* Return: None
*/
void p2p_dump_tx_queue(struct p2p_soc_priv_obj *p2p_soc_obj);
/**
* p2p_ready_to_tx_frame() - dump tx queue
* @p2p_soc_obj: p2p soc private object
* @cookie: cookie is pointer to roc
*
* This function find out the tx context in wait for roc queue and tx
* this frame.
*
* Return: QDF_STATUS_SUCCESS - in case of success
*/
QDF_STATUS p2p_ready_to_tx_frame(struct p2p_soc_priv_obj *p2p_soc_obj,
uint64_t cookie);
/**
* p2p_cleanup_tx_queue() - cleanup tx queue
* @p2p_soc_obj: p2p soc private object
*
* This function cleanup wait for roc queue and wait for ack queue.
*
* Return: QDF_STATUS_SUCCESS - in case of success
*/
QDF_STATUS p2p_cleanup_tx_queue(struct p2p_soc_priv_obj *p2p_soc_obj);
/**
* p2p_process_mgmt_tx() - Process mgmt frame tx request
* @tx_ctx: tx context
@@ -90,7 +230,7 @@ QDF_STATUS p2p_process_mgmt_tx_cancel(
* @tx_cnf_event: tx confirmation event information
*
* This function mgmt frame tx confirmation. It will deliver this
* event to HDD
* event to up layer
*
* Return: QDF_STATUS_SUCCESS - in case of success
*/
@@ -102,7 +242,7 @@ QDF_STATUS p2p_process_mgmt_tx_ack_cnf(
* @rx_mgmt_event: rx mgmt frame event information
*
* This function mgmt frame rx mgmt frame event. It will deliver this
* event to HDD
* event to up layer
*
* Return: QDF_STATUS_SUCCESS - in case of success
*/

Dosyayı Görüntüle

@@ -419,6 +419,7 @@ static QDF_STATUS p2p_process_ready_on_channel_evt(
p2p_debug("roc for off chan tx, ready to send frame");
cookie = (uintptr_t)roc_ctx;
/* ready to tx frame */
p2p_ready_to_tx_frame(p2p_soc_obj, cookie);
}
return status;

Dosyayı Görüntüle

@@ -111,6 +111,7 @@ struct p2p_tx_cnf {
* @len: Length of tx buffer
* @no_cck: Required cck or not
* @dont_wait_for_ack: Wait for ack or not
* @off_chan: Off channel tx or not
* @buf: TX buffer
*/
struct p2p_mgmt_tx {
@@ -120,6 +121,7 @@ struct p2p_mgmt_tx {
uint32_t len;
uint32_t no_cck;
uint32_t dont_wait_for_ack;
uint32_t off_chan;
const uint8_t *buf;
};

Dosyayı Görüntüle

@@ -23,10 +23,19 @@
#include <wlan_objmgr_psoc_obj.h>
#include <wlan_mgmt_txrx_utils_api.h>
#include <scheduler_api.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 "wlan_p2p_tgt_api.h"
#include "wlan_p2p_public_struct.h"
#include "../../core/src/wlan_p2p_main.h"
#include "../../core/src/wlan_p2p_roc.h"
#include "../../core/src/wlan_p2p_off_chan_tx.h"
#define IEEE80211_FC0_TYPE_MASK 0x0c
#define P2P_NOISE_FLOOR_DBM_DEFAULT (-96)
static inline struct wlan_lmac_if_p2p_tx_ops *
wlan_psoc_get_p2p_tx_ops(struct wlan_objmgr_psoc *psoc)
@@ -103,12 +112,59 @@ void tgt_p2p_scan_event_cb(struct wlan_objmgr_vdev *vdev,
QDF_STATUS tgt_p2p_mgmt_download_comp_cb(void *context,
qdf_nbuf_t buf, bool free)
{
p2p_debug("conext:%p, buf:%p, free:%d", context,
qdf_nbuf_data(buf), free);
qdf_nbuf_free(buf);
return QDF_STATUS_SUCCESS;
}
QDF_STATUS tgt_p2p_mgmt_ota_comp_cb(void *context, qdf_nbuf_t buf,
uint32_t status, void *tx_compl_params)
{
struct p2p_tx_cnf *tx_cnf;
struct p2p_tx_conf_event *tx_conf_event;
struct p2p_soc_priv_obj *p2p_soc_obj;
struct tx_action_context *tx_ctx;
struct scheduler_msg msg;
p2p_debug("context:%p, buf:%p, status:%d, tx complete params:%p",
context, buf, status, tx_compl_params);
if (!context) {
p2p_err("invalid context");
return QDF_STATUS_E_INVAL;
}
tx_ctx = (struct tx_action_context *)context;
p2p_soc_obj = tx_ctx->p2p_soc_obj;
tx_conf_event = qdf_mem_malloc(sizeof(*tx_conf_event));
if (tx_conf_event == NULL) {
p2p_err("Failed to allocate tx cnf event");
return QDF_STATUS_E_NOMEM;
}
tx_cnf = qdf_mem_malloc(sizeof(*tx_cnf));
if (tx_cnf == NULL) {
p2p_err("Failed to allocate tx cnf");
return QDF_STATUS_E_NOMEM;
}
qdf_nbuf_free(buf);
tx_cnf->vdev_id = tx_ctx->vdev_id;
tx_cnf->action_cookie = (uintptr_t)tx_ctx;
tx_cnf->buf = tx_ctx->buf;
tx_cnf->buf_len = tx_ctx->buf_len;
tx_cnf->status = status;
tx_conf_event->p2p_soc_obj = p2p_soc_obj;
tx_conf_event->tx_cnf = tx_cnf;
tx_conf_event->tx_ctx = tx_ctx;
msg.type = P2P_EVENT_MGMT_TX_ACK_CNF;
msg.bodyptr = tx_conf_event;
msg.callback = p2p_process_evt;
scheduler_post_msg(QDF_MODULE_ID_TARGET_IF, &msg);
return QDF_STATUS_SUCCESS;
}
@@ -117,6 +173,83 @@ QDF_STATUS tgt_p2p_mgmt_frame_rx_cb(struct wlan_objmgr_psoc *psoc,
struct mgmt_rx_event_params *mgmt_rx_params,
enum mgmt_frame_type frm_type)
{
struct p2p_rx_mgmt_frame *rx_mgmt;
struct p2p_rx_mgmt_event *rx_mgmt_event;
struct p2p_soc_priv_obj *p2p_soc_obj;
struct scheduler_msg msg;
struct wlan_frame_hdr *wh;
struct wlan_objmgr_vdev *vdev;
struct p2p_roc_context *roc_ctx;
uint32_t vdev_id;
uint8_t *pdata;
p2p_debug("psoc:%p, peer:%p, type:%d", psoc, peer, frm_type);
if (!mgmt_rx_params) {
p2p_err("mgmt rx params is NULL");
qdf_nbuf_free(buf);
return QDF_STATUS_E_INVAL;
}
p2p_soc_obj = wlan_objmgr_psoc_get_comp_private_obj(psoc,
WLAN_UMAC_COMP_P2P);
if (p2p_soc_obj == NULL) {
p2p_err("p2p ctx is NULL, drop this frame");
return QDF_STATUS_E_FAILURE;
}
if (peer == NULL) {
roc_ctx = p2p_find_current_roc_ctx(p2p_soc_obj);
if (roc_ctx == NULL) {
p2p_err("current roc ctx is null, can't get vdev id");
return QDF_STATUS_E_FAILURE;
} else {
vdev_id = roc_ctx->vdev_id;
}
} else {
wlan_peer_obj_lock(peer);
vdev = wlan_peer_get_vdev(peer);
wlan_peer_obj_unlock(peer);
if (vdev == NULL) {
p2p_err("vdev is NULL in peer, drop this frame");
return QDF_STATUS_E_FAILURE;
}
wlan_vdev_obj_lock(vdev);
vdev_id = wlan_vdev_get_id(vdev);
wlan_vdev_obj_unlock(vdev);
}
rx_mgmt_event = qdf_mem_malloc(sizeof(*rx_mgmt_event));
if (rx_mgmt_event == NULL) {
p2p_err("Failed to allocate rx mgmt event");
return QDF_STATUS_E_NOMEM;
}
rx_mgmt = qdf_mem_malloc(sizeof(*rx_mgmt) +
mgmt_rx_params->buf_len);
if (rx_mgmt == NULL) {
p2p_err("Failed to allocate rx mgmt frame");
return QDF_STATUS_E_NOMEM;
}
wh = (struct wlan_frame_hdr *)qdf_nbuf_data(buf);
pdata = (uint8_t *)qdf_nbuf_data(buf);
rx_mgmt->frame_len = mgmt_rx_params->buf_len;
rx_mgmt->rx_chan = mgmt_rx_params->channel;
rx_mgmt->vdev_id = vdev_id;
rx_mgmt->frm_type = (wh)->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
rx_mgmt->rx_rssi = mgmt_rx_params->snr +
P2P_NOISE_FLOOR_DBM_DEFAULT;
rx_mgmt_event->rx_mgmt = rx_mgmt;
rx_mgmt_event->p2p_soc_obj = p2p_soc_obj;
qdf_mem_copy(rx_mgmt->buf, pdata, mgmt_rx_params->buf_len);
msg.type = P2P_EVENT_RX_MGMT;
msg.bodyptr = rx_mgmt_event;
msg.callback = p2p_process_evt;
scheduler_post_msg(QDF_MODULE_ID_TARGET_IF, &msg);
qdf_nbuf_free(buf);
return QDF_STATUS_SUCCESS;
}

Dosyayı Görüntüle

@@ -27,6 +27,7 @@
#include "wlan_p2p_public_struct.h"
#include "../../core/src/wlan_p2p_main.h"
#include "../../core/src/wlan_p2p_roc.h"
#include "../../core/src/wlan_p2p_off_chan_tx.h"
static inline struct wlan_lmac_if_p2p_tx_ops *
ucfg_p2p_psoc_get_tx_ops(struct wlan_objmgr_psoc *psoc)
@@ -150,12 +151,96 @@ QDF_STATUS ucfg_p2p_roc_cancel_req(struct wlan_objmgr_psoc *soc,
QDF_STATUS ucfg_p2p_mgmt_tx(struct wlan_objmgr_psoc *soc,
struct p2p_mgmt_tx *mgmt_frm, uint64_t *cookie)
{
struct scheduler_msg msg;
struct p2p_soc_priv_obj *p2p_soc_obj;
struct tx_action_context *tx_action;
p2p_debug("soc:%p, vdev_id:%d, chan:%d, wait:%d, buf_len:%d, cck:%d, no ack:%d, off chan:%d",
soc, mgmt_frm->vdev_id, mgmt_frm->chan,
mgmt_frm->wait, mgmt_frm->len, mgmt_frm->no_cck,
mgmt_frm->dont_wait_for_ack, mgmt_frm->off_chan);
if (soc == NULL) {
p2p_err("psoc context passed is NULL");
return QDF_STATUS_E_INVAL;
}
p2p_soc_obj = wlan_objmgr_psoc_get_comp_private_obj(soc,
WLAN_UMAC_COMP_P2P);
if (p2p_soc_obj == NULL) {
p2p_err("P2P soc context is NULL");
return QDF_STATUS_E_FAILURE;
}
tx_action = qdf_mem_malloc(sizeof(*tx_action));
if (tx_action == NULL) {
p2p_err("Failed to allocate tx action context");
return QDF_STATUS_E_NOMEM;
}
/* return cookie just for ota ack frames */
if (mgmt_frm->dont_wait_for_ack)
*cookie = 0;
else
*cookie = (uintptr_t)tx_action;
tx_action->p2p_soc_obj = p2p_soc_obj;
tx_action->vdev_id = mgmt_frm->vdev_id;
tx_action->chan = mgmt_frm->chan;
tx_action->duration = mgmt_frm->wait;
tx_action->buf_len = mgmt_frm->len;
tx_action->no_cck = mgmt_frm->no_cck;
tx_action->no_ack = mgmt_frm->dont_wait_for_ack;
tx_action->off_chan = mgmt_frm->off_chan;
tx_action->buf = qdf_mem_malloc(tx_action->buf_len);
if (tx_action->buf == NULL) {
p2p_err("Failed to allocate buffer for action frame");
qdf_mem_free(tx_action);
return QDF_STATUS_E_NOMEM;
}
qdf_mem_copy(tx_action->buf, mgmt_frm->buf, tx_action->buf_len);
msg.type = P2P_MGMT_TX;
msg.bodyptr = tx_action;
msg.callback = p2p_process_cmd;
scheduler_post_msg(QDF_MODULE_ID_OS_IF, &msg);
return QDF_STATUS_SUCCESS;
}
QDF_STATUS ucfg_p2p_mgmt_tx_cancel(struct wlan_objmgr_psoc *soc,
uint64_t cookie)
{
struct scheduler_msg msg;
struct p2p_soc_priv_obj *p2p_soc_obj;
struct cancel_roc_context *cancel_tx;
p2p_debug("soc:%p, cookie:0x%llx", soc, cookie);
if (soc == NULL) {
p2p_err("psoc context passed is NULL");
return QDF_STATUS_E_INVAL;
}
p2p_soc_obj = wlan_objmgr_psoc_get_comp_private_obj(soc,
WLAN_UMAC_COMP_P2P);
if (p2p_soc_obj == NULL) {
p2p_err("p2p soc context is NULL");
return QDF_STATUS_E_FAILURE;
}
cancel_tx = qdf_mem_malloc(sizeof(*cancel_tx));
if (cancel_tx == NULL) {
p2p_err("Failed to allocate cancel p2p roc");
return QDF_STATUS_E_NOMEM;
}
cancel_tx->p2p_soc_obj = p2p_soc_obj;
cancel_tx->cookie = cookie;
msg.type = P2P_MGMT_TX_CANCEL;
msg.bodyptr = cancel_tx;
msg.callback = p2p_process_cmd;
scheduler_post_msg(QDF_MODULE_ID_OS_IF, &msg);
return QDF_STATUS_SUCCESS;
}