qcacmn: Support rx p2p public action frame

Support rx p2p public action frame and extend the roc timer for
special frames. Also add scan requtest paramters when trigger scan
request.

Change-Id: I295bdcf9c5ff78320cbe600a483d245d38d05c06
CRs-Fixed: 2024412
This commit is contained in:
Wu Gao 2017-03-24 18:13:42 +08:00 • committed by Sandeep Puligilla
commit 0261c63a51
4 changed files with 105 additions and 24 deletions

View file

@ -589,23 +589,26 @@ static void p2p_init_frame_info(struct p2p_frame_info *frame_info)
/**
* p2p_get_frame_info() - get frame information from packet
* @tx_ctx: tx context
* @data_buf: data buffer address
* @length: buffer length
* @frame_info: frame information
*
* This function gets frame information from packet.
*
* Return: QDF_STATUS_SUCCESS - in case of success
*/
static QDF_STATUS p2p_get_frame_info(struct tx_action_context *tx_ctx)
static QDF_STATUS p2p_get_frame_info(uint8_t *data_buf, uint32_t length,
struct p2p_frame_info *frame_info)
{
uint8_t type;
uint8_t sub_type;
uint8_t action_type;
uint8_t *buf = tx_ctx->buf;
struct p2p_frame_info *frame_info = &(tx_ctx->frame_info);
uint8_t *buf = data_buf;
p2p_init_frame_info(frame_info);
type = P2P_GET_TYPE_FRM_FC(buf[0]);
sub_type = P2P_GET_SUBTYPE_FRM_FC(buf[0]);
p2p_init_frame_info(frame_info);
if (type != P2P_FRAME_MGMT) {
p2p_err("just support mgmt frame");
return QDF_STATUS_E_FAILURE;
@ -635,17 +638,17 @@ static QDF_STATUS p2p_get_frame_info(struct tx_action_context *tx_ctx)
if (buf[0] == P2P_PUBLIC_ACTION_FRAME &&
buf[1] == P2P_PUBLIC_ACTION_VENDOR_SPECIFIC &&
!qdf_mem_cmp(&buf[2], P2P_OUI, P2P_OUI_SIZE)) {
buf = tx_ctx->buf +
buf = data_buf +
P2P_PUBLIC_ACTION_FRAME_TYPE_OFFSET;
action_type = buf[0];
if (action_type >= P2P_PUBLIC_ACTION_NOT_SUPPORT)
if (action_type > P2P_PUBLIC_ACTION_PROV_DIS_RSP)
frame_info->public_action_type =
P2P_PUBLIC_ACTION_NOT_SUPPORT;
else
frame_info->public_action_type = action_type;
} else if (buf[0] == P2P_ACTION_VENDOR_SPECIFIC_CATEGORY &&
!qdf_mem_cmp(&buf[1], P2P_OUI, P2P_OUI_SIZE)) {
buf = tx_ctx->buf +
buf = data_buf +
P2P_ACTION_FRAME_TYPE_OFFSET;
action_type = buf[0];
if (action_type == P2P_ACTION_PRESENCE_RSP)
@ -1003,6 +1006,56 @@ static QDF_STATUS p2p_move_tx_context_to_ack_queue(
return status;
}
/**
* p2p_extend_roc_timer() - extend roc timer
* @p2p_soc_obj: p2p soc private object
* @frame_info: pointer to frame information
*
* This function extends roc timer for some of p2p public action frame.
*
* Return: QDF_STATUS_SUCCESS - in case of success
*/
static QDF_STATUS p2p_extend_roc_timer(
struct p2p_soc_priv_obj *p2p_soc_obj,
struct p2p_frame_info *frame_info)
{
struct p2p_roc_context *curr_roc_ctx;
uint32_t extend_time;
curr_roc_ctx = p2p_find_current_roc_ctx(p2p_soc_obj);
if (!curr_roc_ctx) {
p2p_debug("no running roc request currently");
return QDF_STATUS_SUCCESS;
}
if (!frame_info) {
p2p_err("invalid frame information");
return QDF_STATUS_E_INVAL;
}
switch (frame_info->public_action_type) {
case P2P_PUBLIC_ACTION_NEG_REQ:
case P2P_PUBLIC_ACTION_NEG_RSP:
extend_time = 2 * P2P_ACTION_FRAME_DEFAULT_WAIT;
break;
case P2P_PUBLIC_ACTION_INVIT_REQ:
case P2P_PUBLIC_ACTION_DEV_DIS_REQ:
extend_time = P2P_ACTION_FRAME_DEFAULT_WAIT;
break;
default:
extend_time = 0;
break;
}
if (extend_time) {
p2p_debug("extend roc timer, duration:%d", extend_time);
curr_roc_ctx->duration = extend_time;
return p2p_restart_roc_timer(curr_roc_ctx);
}
return QDF_STATUS_SUCCESS;
}
/**
* p2p_adjust_tx_wait() - adjust tx wait
* @tx_ctx: tx context
@ -1397,7 +1450,8 @@ QDF_STATUS p2p_process_mgmt_tx(struct tx_action_context *tx_ctx)
tx_ctx->buf, tx_ctx->buf_len, tx_ctx->off_chan,
tx_ctx->no_cck, tx_ctx->no_ack, tx_ctx->duration);
status = p2p_get_frame_info(tx_ctx);
status = p2p_get_frame_info(tx_ctx->buf, tx_ctx->buf_len,
&(tx_ctx->frame_info));
if (status != QDF_STATUS_SUCCESS) {
p2p_err("unsupport frame");
status = QDF_STATUS_E_INVAL;
@ -1547,6 +1601,7 @@ QDF_STATUS p2p_process_rx_mgmt(
struct p2p_rx_mgmt_frame *rx_mgmt;
struct p2p_soc_priv_obj *p2p_soc_obj;
struct p2p_start_param *start_param;
struct p2p_frame_info frame_info;
p2p_soc_obj = rx_mgmt_event->p2p_soc_obj;
rx_mgmt = rx_mgmt_event->rx_mgmt;
@ -1562,6 +1617,27 @@ QDF_STATUS p2p_process_rx_mgmt(
rx_mgmt->rx_chan, rx_mgmt->vdev_id, rx_mgmt->frm_type,
rx_mgmt->rx_rssi, rx_mgmt->buf);
if (rx_mgmt->frm_type == MGMT_ACTION_VENDOR_SPECIFIC) {
p2p_get_frame_info(rx_mgmt->buf, rx_mgmt->frame_len,
&frame_info);
p2p_debug("action_sub_type %u, action_type %d",
frame_info.public_action_type,
frame_info.action_type);
if ((frame_info.public_action_type ==
P2P_PUBLIC_ACTION_NOT_SUPPORT) &&
(frame_info.action_type ==
P2P_ACTION_NOT_SUPPORT)) {
p2p_debug("non-p2p frame, drop it");
qdf_mem_free(rx_mgmt);
return QDF_STATUS_SUCCESS;
} else {
p2p_debug("p2p frame, extend roc accordingly");
p2p_extend_roc_timer(p2p_soc_obj, &frame_info);
}
}
start_param = p2p_soc_obj->start_param;
if (start_param->rx_cb)
start_param->rx_cb(start_param->rx_cb_data, rx_mgmt);

View file

@ -49,21 +49,22 @@
static QDF_STATUS p2p_mgmt_rx_ops(struct wlan_objmgr_psoc *psoc,
bool isregister)
{
struct mgmt_txrx_mgmt_frame_cb_info frm_cb_info;
struct mgmt_txrx_mgmt_frame_cb_info frm_cb_info[2];
QDF_STATUS status;
p2p_debug("psoc:%p, is register rx:%d", psoc, isregister);
frm_cb_info.frm_type = MGMT_PROBE_REQ;
frm_cb_info.mgmt_rx_cb = (mgmt_frame_rx_callback)
tgt_p2p_mgmt_frame_rx_cb;
frm_cb_info[0].frm_type = MGMT_PROBE_REQ;
frm_cb_info[0].mgmt_rx_cb = tgt_p2p_mgmt_frame_rx_cb;
frm_cb_info[1].frm_type = MGMT_ACTION_VENDOR_SPECIFIC;
frm_cb_info[1].mgmt_rx_cb = tgt_p2p_mgmt_frame_rx_cb;
if (isregister)
status = wlan_mgmt_txrx_register_rx_cb(psoc,
WLAN_UMAC_COMP_P2P, &frm_cb_info, 1);
WLAN_UMAC_COMP_P2P, frm_cb_info, 2);
else
status = wlan_mgmt_txrx_deregister_rx_cb(psoc,
WLAN_UMAC_COMP_P2P, &frm_cb_info, 1);
WLAN_UMAC_COMP_P2P, frm_cb_info, 2);
return status;
}
@ -107,6 +108,8 @@ static QDF_STATUS p2p_scan_start(struct p2p_roc_context *roc_ctx)
req->scan_req.chan_list[0] = wlan_chan_to_freq(roc_ctx->chan);
req->scan_req.dwell_time_passive = roc_ctx->duration;
req->scan_req.dwell_time_active = 0;
req->scan_req.scan_priority = SCAN_PRIORITY_HIGH;
req->scan_req.num_bssid = 1;
qdf_set_macaddr_broadcast(&req->scan_req.bssid_list[0]);
status = ucfg_scan_start(req);

View file

@ -33,9 +33,11 @@
#ifdef QCA_WIFI_3_0_EMU
#define P2P_ROC_DURATION_MULTI_GO_PRESENT 2
#define P2P_ROC_DURATION_MULTI_GO_ABSENT 3
#define P2P_ACTION_FRAME_DEFAULT_WAIT 500
#else
#define P2P_ROC_DURATION_MULTI_GO_PRESENT 2
#define P2P_ROC_DURATION_MULTI_GO_ABSENT 5
#define P2P_ACTION_FRAME_DEFAULT_WAIT 200
#endif
struct wlan_objmgr_vdev;

View file

@ -140,13 +140,13 @@ QDF_STATUS tgt_p2p_mgmt_ota_comp_cb(void *context, qdf_nbuf_t buf,
p2p_soc_obj = tx_ctx->p2p_soc_obj;
tx_conf_event = qdf_mem_malloc(sizeof(*tx_conf_event));
if (tx_conf_event == NULL) {
if (!tx_conf_event) {
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) {
if (!tx_cnf) {
p2p_err("Failed to allocate tx cnf");
return QDF_STATUS_E_NOMEM;
}
@ -193,14 +193,14 @@ QDF_STATUS tgt_p2p_mgmt_frame_rx_cb(struct wlan_objmgr_psoc *psoc,
p2p_soc_obj = wlan_objmgr_psoc_get_comp_private_obj(psoc,
WLAN_UMAC_COMP_P2P);
if (p2p_soc_obj == NULL) {
if (!p2p_soc_obj) {
p2p_err("p2p ctx is NULL, drop this frame");
return QDF_STATUS_E_FAILURE;
}
if (peer == NULL) {
if (!peer) {
roc_ctx = p2p_find_current_roc_ctx(p2p_soc_obj);
if (roc_ctx == NULL) {
if (!roc_ctx) {
p2p_err("current roc ctx is null, can't get vdev id");
return QDF_STATUS_E_FAILURE;
} else {
@ -210,7 +210,7 @@ QDF_STATUS tgt_p2p_mgmt_frame_rx_cb(struct wlan_objmgr_psoc *psoc,
wlan_peer_obj_lock(peer);
vdev = wlan_peer_get_vdev(peer);
wlan_peer_obj_unlock(peer);
if (vdev == NULL) {
if (!vdev) {
p2p_err("vdev is NULL in peer, drop this frame");
return QDF_STATUS_E_FAILURE;
}
@ -220,14 +220,14 @@ QDF_STATUS tgt_p2p_mgmt_frame_rx_cb(struct wlan_objmgr_psoc *psoc,
}
rx_mgmt_event = qdf_mem_malloc(sizeof(*rx_mgmt_event));
if (rx_mgmt_event == NULL) {
if (!rx_mgmt_event) {
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) {
if (!rx_mgmt) {
p2p_err("Failed to allocate rx mgmt frame");
return QDF_STATUS_E_NOMEM;
}
@ -237,7 +237,7 @@ QDF_STATUS tgt_p2p_mgmt_frame_rx_cb(struct wlan_objmgr_psoc *psoc,
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->frm_type = frm_type;
rx_mgmt->rx_rssi = mgmt_rx_params->snr +
P2P_NOISE_FLOOR_DBM_DEFAULT;
rx_mgmt_event->rx_mgmt = rx_mgmt;