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:

işlemeyi yapan:
Sandeep Puligilla

ebeveyn
26781f65dc
işleme
dfc571c521
@@ -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(
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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_ */
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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*/
|
||||
|
@@ -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
@@ -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
|
||||
*/
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
};
|
||||
|
||||
|
@@ -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;
|
||||
}
|
||||
|
||||
|
@@ -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;
|
||||
}
|
||||
|
||||
|
Yeni konuda referans
Bir kullanıcı engelle