diff --git a/components/p2p/core/src/wlan_p2p_off_chan_tx.c b/components/p2p/core/src/wlan_p2p_off_chan_tx.c index f0bea5c35d62..aa2cb76b8db4 100644 --- a/components/p2p/core/src/wlan_p2p_off_chan_tx.c +++ b/components/p2p/core/src/wlan_p2p_off_chan_tx.c @@ -165,6 +165,52 @@ static QDF_STATUS p2p_vdev_check_valid(struct tx_action_context *tx_ctx) } #endif /* SUPPORT_P2P_BY_ONE_INTF_WLAN */ +/** + * p2p_check_and_update_channel() - check and update tx channel + * @tx_ctx: tx context + * + * This function checks and updates tx channel if channel is 0 in tx context. + * It will update channel to current roc channel if vdev mode is + * P2P DEVICE/CLIENT/GO. + * + * Return: QDF_STATUS_SUCCESS - in case of success + */ +static QDF_STATUS p2p_check_and_update_channel(struct tx_action_context *tx_ctx) +{ + enum QDF_OPMODE mode; + struct wlan_objmgr_vdev *vdev; + struct wlan_objmgr_psoc *psoc; + struct p2p_soc_priv_obj *p2p_soc_obj; + struct p2p_roc_context *curr_roc_ctx; + + if (!tx_ctx || tx_ctx->chan) { + p2p_err("NULL tx ctx or channel valid"); + return QDF_STATUS_E_INVAL; + } + + p2p_soc_obj = tx_ctx->p2p_soc_obj; + psoc = p2p_soc_obj->soc; + vdev = wlan_objmgr_get_vdev_by_id_from_psoc( + psoc, tx_ctx->vdev_id, WLAN_P2P_ID); + if (!vdev) { + p2p_err("null vdev object"); + return QDF_STATUS_E_INVAL; + } + + mode = wlan_vdev_mlme_get_opmode(vdev); + curr_roc_ctx = p2p_find_current_roc_ctx(p2p_soc_obj); + + if (curr_roc_ctx && + (mode == QDF_P2P_DEVICE_MODE || + mode == QDF_P2P_CLIENT_MODE || + mode == QDF_P2P_GO_MODE)) + tx_ctx->chan = curr_roc_ctx->chan; + + wlan_objmgr_vdev_release_ref(vdev, WLAN_P2P_ID); + + return QDF_STATUS_SUCCESS; +} + /** * p2p_get_p2pie_ptr() - get the pointer to p2p ie * @ie: source ie @@ -948,13 +994,16 @@ static QDF_STATUS p2p_mgmt_tx(struct tx_action_context *tx_ctx, void *mac_addr; uint8_t pdev_id; struct wlan_objmgr_vdev *vdev; + uint16_t chanfreq = 0; psoc = tx_ctx->p2p_soc_obj->soc; mgmt_param.tx_frame = packet; mgmt_param.frm_len = buf_len; mgmt_param.vdev_id = tx_ctx->vdev_id; mgmt_param.pdata = frame; - mgmt_param.chanfreq = wlan_chan_to_freq(tx_ctx->chan); + if (tx_ctx->chan) + chanfreq = (uint16_t)wlan_chan_to_freq(tx_ctx->chan); + mgmt_param.chanfreq = chanfreq; mgmt_param.qdf_ctx = wlan_psoc_get_qdf_dev(psoc); if (!(mgmt_param.qdf_ctx)) { @@ -2786,7 +2835,9 @@ QDF_STATUS p2p_process_mgmt_tx(struct tx_action_context *tx_ctx) tx_ctx->no_ack = 1; } - if (!tx_ctx->off_chan) { + if (!tx_ctx->off_chan || !tx_ctx->chan) { + if (!tx_ctx->chan) + p2p_check_and_update_channel(tx_ctx); status = p2p_execute_tx_action_frame(tx_ctx); if (status != QDF_STATUS_SUCCESS) { p2p_err("execute tx fail"); diff --git a/os_if/p2p/src/wlan_cfg80211_p2p.c b/os_if/p2p/src/wlan_cfg80211_p2p.c index 009b3e88dc54..652a1288f8b2 100644 --- a/os_if/p2p/src/wlan_cfg80211_p2p.c +++ b/os_if/p2p/src/wlan_cfg80211_p2p.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2019 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -425,16 +425,17 @@ int wlan_cfg80211_mgmt_tx(struct wlan_objmgr_vdev *vdev, struct p2p_mgmt_tx mgmt_tx = {0}; struct wlan_objmgr_psoc *psoc; uint8_t vdev_id; + uint32_t channel = 0; if (!vdev) { cfg80211_err("invalid vdev object"); return -EINVAL; } - if (!chan) { - cfg80211_err("invalid channel"); - return -EINVAL; - } + if (chan) + channel = (uint32_t)wlan_freq_to_chan(chan->center_freq); + else + cfg80211_debug("NULL chan, set channel to 0"); psoc = wlan_vdev_get_psoc(vdev); vdev_id = wlan_vdev_get_id(vdev); @@ -450,7 +451,6 @@ int wlan_cfg80211_mgmt_tx(struct wlan_objmgr_vdev *vdev, if (wait > MAX_OFFCHAN_TIME_FOR_DNBS) { int ret; bool ok; - uint32_t channel = wlan_freq_to_chan(chan->center_freq); ret = policy_mgr_is_chan_ok_for_dnbs(psoc, channel, &ok); if (QDF_IS_STATUS_ERROR(ret)) { @@ -466,7 +466,7 @@ int wlan_cfg80211_mgmt_tx(struct wlan_objmgr_vdev *vdev, } mgmt_tx.vdev_id = (uint32_t)vdev_id; - mgmt_tx.chan = (uint32_t)wlan_freq_to_chan(chan->center_freq); + mgmt_tx.chan = channel; mgmt_tx.wait = wait; mgmt_tx.len = len; mgmt_tx.no_cck = (uint32_t)no_cck;