diff --git a/umac/p2p/core/src/wlan_p2p_off_chan_tx.c b/umac/p2p/core/src/wlan_p2p_off_chan_tx.c index 45208cc1c158..f243fc60f32d 100644 --- a/umac/p2p/core/src/wlan_p2p_off_chan_tx.c +++ b/umac/p2p/core/src/wlan_p2p_off_chan_tx.c @@ -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); diff --git a/umac/p2p/core/src/wlan_p2p_roc.c b/umac/p2p/core/src/wlan_p2p_roc.c index 9c32eb61172e..ca3b7625c837 100644 --- a/umac/p2p/core/src/wlan_p2p_roc.c +++ b/umac/p2p/core/src/wlan_p2p_roc.c @@ -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); diff --git a/umac/p2p/core/src/wlan_p2p_roc.h b/umac/p2p/core/src/wlan_p2p_roc.h index cc460a58a1b2..354d13382afb 100644 --- a/umac/p2p/core/src/wlan_p2p_roc.h +++ b/umac/p2p/core/src/wlan_p2p_roc.h @@ -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; diff --git a/umac/p2p/dispatcher/src/wlan_p2p_tgt_api.c b/umac/p2p/dispatcher/src/wlan_p2p_tgt_api.c index 96fcf15bbf34..b72e52894315 100644 --- a/umac/p2p/dispatcher/src/wlan_p2p_tgt_api.c +++ b/umac/p2p/dispatcher/src/wlan_p2p_tgt_api.c @@ -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;