qcacld-3.0: Add vdev pause bitmap (Set/Clear/Update/Get) API's

Currently, Host modify the vdev pause bitmap
directly which may be problematic in scenario
where this value update information need to
notify to other components.

Hence as a part of this fix, Add (set/clear/update) API's
for vdev pause bitmap modification.

Change-Id: I5c8d6576d27076f697463b42632962327306902f
CRs-Fixed: 2013376
This commit is contained in:
Mukul Sharma 2017-03-01 15:57:07 +05:30 • committed by Sandeep Puligilla
commit 6411bb8535
5 changed files with 149 additions and 22 deletions

View file

@ -2377,4 +2377,121 @@ void wma_vdev_set_mlme_state(tp_wma_handle wma, uint8_t vdev_id,
wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_WMA_ID);
}
}
/**
* wma_update_vdev_pause_bitmap() - update vdev pause bitmap
* @vdev_id: the Id of the vdev to configure
* @value: value pause bitmap value
*
* Return: None
*/
static inline
void wma_vdev_update_pause_bitmap(uint8_t vdev_id, uint16_t value)
{
tp_wma_handle wma = (tp_wma_handle)cds_get_context(QDF_MODULE_ID_WMA);
struct wma_txrx_node *iface;
if (vdev_id > wma->max_bssid) {
WMA_LOGE("%s: Invalid vdev_id: %d", __func__, vdev_id);
return;
}
if (!wma) {
WMA_LOGE("%s: WMA context is invald!", __func__);
return;
}
iface = &wma->interfaces[vdev_id];
if (!iface || !iface->handle) {
WMA_LOGE("%s: Failed to get iface handle: %p",
__func__, iface->handle);
return;
}
iface->pause_bitmap = value;
}
/**
* wma_vdev_get_pause_bitmap() - Get vdev pause bitmap
* @vdev_id: the Id of the vdev to configure
*
* Return: Vdev pause bitmap value else 0 on error
*/
static inline
uint16_t wma_vdev_get_pause_bitmap(uint8_t vdev_id)
{
tp_wma_handle wma = (tp_wma_handle)cds_get_context(QDF_MODULE_ID_WMA);
struct wma_txrx_node *iface;
if (!wma) {
WMA_LOGE("%s: WMA context is invald!", __func__);
return 0;
}
iface = &wma->interfaces[vdev_id];
if (!iface || !iface->handle) {
WMA_LOGE("%s: Failed to get iface handle: %p",
__func__, iface->handle);
return 0;
}
return iface->pause_bitmap;
}
/**
* wma_vdev_set_pause_bit() - Set a bit in vdev pause bitmap
* @vdev_id: the Id of the vdev to configure
* @bit_pos: set bit position in pause bitmap
*
* Return: None
*/
static inline
void wma_vdev_set_pause_bit(uint8_t vdev_id, wmi_tx_pause_type bit_pos)
{
tp_wma_handle wma = (tp_wma_handle)cds_get_context(QDF_MODULE_ID_WMA);
struct wma_txrx_node *iface;
if (!wma) {
WMA_LOGE("%s: WMA context is invald!", __func__);
return;
}
iface = &wma->interfaces[vdev_id];
if (!iface || !iface->handle) {
WMA_LOGE("%s: Failed to get iface handle: %p",
__func__, iface->handle);
return;
}
iface->pause_bitmap |= (1 << bit_pos);
}
/**
* wma_vdev_clear_pause_bit() - Clear a bit from vdev pause bitmap
* @vdev_id: the Id of the vdev to configure
* @bit_pos: set bit position in pause bitmap
*
* Return: None
*/
static inline
void wma_vdev_clear_pause_bit(uint8_t vdev_id, wmi_tx_pause_type bit_pos)
{
tp_wma_handle wma = (tp_wma_handle)cds_get_context(QDF_MODULE_ID_WMA);
struct wma_txrx_node *iface;
if (!wma) {
WMA_LOGE("%s: WMA context is invald!", __func__);
return;
}
iface = &wma->interfaces[vdev_id];
if (!iface || !iface->handle) {
WMA_LOGE("%s: Failed to get iface handle: %p",
__func__, iface->handle);
return;
}
iface->pause_bitmap &= ~(1 << bit_pos);
}
#endif

View file

@ -1222,7 +1222,7 @@ void wma_set_linkstate(tp_wma_handle wma, tpLinkStateParams params)
cdp_fc_vdev_pause(soc,
wma->interfaces[vdev_id].handle,
OL_TXQ_PAUSE_REASON_VDEV_STOP);
wma->interfaces[vdev_id].pause_bitmap |= (1 << PAUSE_TYPE_HOST);
wma_vdev_set_pause_bit(vdev_id, PAUSE_TYPE_HOST);
if (wma_send_vdev_stop_to_fw(wma, vdev_id)) {
WMA_LOGP("%s: %d Failed to send vdev stop",
__func__, __LINE__);
@ -1259,11 +1259,11 @@ void wma_unpause_vdev(tp_wma_handle wma)
#if defined(QCA_LL_LEGACY_TX_FLOW_CONTROL) || defined(QCA_LL_TX_FLOW_CONTROL_V2)
/* When host resume, by default, unpause all active vdev */
if (wma->interfaces[vdev_id].pause_bitmap) {
if (wma_vdev_get_pause_bitmap(vdev_id)) {
cdp_fc_vdev_unpause(cds_get_context(QDF_MODULE_ID_SOC),
wma->interfaces[vdev_id].handle,
0xffffffff);
wma->interfaces[vdev_id].pause_bitmap = 0;
wma_vdev_update_pause_bitmap(vdev_id, 0);
}
#endif /* QCA_LL_LEGACY_TX_FLOW_CONTROL */
@ -1650,20 +1650,20 @@ int wma_mcc_vdev_tx_pause_evt_handler(void *handle, uint8_t *event,
* Now only support per-dev pause so it is not
* necessary to pause a paused queue again.
*/
if (!wma->interfaces[vdev_id].pause_bitmap)
if (!wma_vdev_get_pause_bitmap(vdev_id))
cdp_fc_vdev_pause(soc,
wma->
interfaces[vdev_id].handle,
OL_TXQ_PAUSE_REASON_FW);
wma->interfaces[vdev_id].pause_bitmap |=
(1 << wmi_event->pause_type);
wma_vdev_set_pause_bit(vdev_id,
wmi_event->pause_type);
}
/* UNPAUSE action, clean bitmap */
else if (ACTION_UNPAUSE == wmi_event->action) {
/* Handle unpause only if already paused */
if (wma->interfaces[vdev_id].pause_bitmap) {
wma->interfaces[vdev_id].pause_bitmap &=
~(1 << wmi_event->pause_type);
if (wma_vdev_get_pause_bitmap(vdev_id)) {
wma_vdev_clear_pause_bit(vdev_id,
wmi_event->pause_type);
if (!wma->interfaces[vdev_id].
pause_bitmap) {
@ -1682,7 +1682,7 @@ int wma_mcc_vdev_tx_pause_evt_handler(void *handle, uint8_t *event,
WMA_LOGD
("vdev_id %d, pause_map 0x%x, pause type %d, action %d",
vdev_id, wma->interfaces[vdev_id].pause_bitmap,
vdev_id, wma_vdev_get_pause_bitmap(vdev_id),
wmi_event->pause_type, wmi_event->action);
}
/* Test Next VDEV */
@ -2998,7 +2998,7 @@ void wma_tx_abort(uint8_t vdev_id)
return;
}
WMA_LOGI("%s: vdevid %d bssid %pM", __func__, vdev_id, iface->bssid);
iface->pause_bitmap |= (1 << PAUSE_TYPE_HOST);
wma_vdev_set_pause_bit(vdev_id, PAUSE_TYPE_HOST);
cdp_fc_vdev_pause(cds_get_context(QDF_MODULE_ID_SOC),
iface->handle,
OL_TXQ_PAUSE_REASON_TX_ABORT);

View file

@ -911,7 +911,7 @@ int wma_vdev_start_resp_handler(void *handle, uint8_t *cmd_param_info,
cdp_fc_vdev_unpause(cds_get_context(QDF_MODULE_ID_SOC),
iface->handle,
OL_TXQ_PAUSE_REASON_VDEV_STOP);
iface->pause_bitmap &= ~(1 << PAUSE_TYPE_HOST);
wma_vdev_clear_pause_bit(resp_event->vdev_id, PAUSE_TYPE_HOST);
}
req_msg = wma_find_vdev_req(wma, resp_event->vdev_id,
@ -1527,7 +1527,7 @@ int wma_vdev_stop_resp_handler(void *handle, uint8_t *cmd_param_info,
__func__, resp_event->vdev_id);
cdp_fc_vdev_unpause(soc, iface->handle,
OL_TXQ_PAUSE_REASON_VDEV_STOP);
iface->pause_bitmap &= ~(1 << PAUSE_TYPE_HOST);
wma_vdev_clear_pause_bit(resp_event->vdev_id, PAUSE_TYPE_HOST);
qdf_atomic_set(&iface->bss_status, WMA_BSS_STATUS_STOPPED);
WMA_LOGD("%s: (type %d subtype %d) BSS is stopped",
__func__, iface->type, iface->sub_type);
@ -1640,7 +1640,7 @@ struct cdp_vdev *wma_vdev_attach(tp_wma_handle wma_handle,
self_sta_req->self_mac_addr,
self_sta_req->session_id,
txrx_vdev_type);
wma_handle->interfaces[self_sta_req->session_id].pause_bitmap = 0;
wma_vdev_update_pause_bitmap(self_sta_req->session_id, 0);
WMA_LOGD("vdev_id %hu, txrx_vdev_handle = %p", self_sta_req->session_id,
txrx_vdev_handle);
@ -2112,7 +2112,7 @@ QDF_STATUS wma_vdev_start(tp_wma_handle wma,
cdp_fc_vdev_unpause(cds_get_context(QDF_MODULE_ID_SOC),
wma->interfaces[params.vdev_id].handle,
0xffffffff);
wma->interfaces[params.vdev_id].pause_bitmap = 0;
wma_vdev_update_pause_bitmap(params.vdev_id, 0);
}
return wma_send_vdev_start_to_fw(wma, &params);
@ -2607,7 +2607,7 @@ void wma_vdev_resp_timer(void *data)
__func__, tgt_req->vdev_id);
cdp_fc_vdev_unpause(soc, iface->handle,
OL_TXQ_PAUSE_REASON_VDEV_STOP);
iface->pause_bitmap &= ~(1 << PAUSE_TYPE_HOST);
wma_vdev_clear_pause_bit(tgt_req->vdev_id, PAUSE_TYPE_HOST);
qdf_atomic_set(&iface->bss_status, WMA_BSS_STATUS_STOPPED);
WMA_LOGD("%s: (type %d subtype %d) BSS is stopped",
__func__, iface->type, iface->sub_type);
@ -4452,14 +4452,14 @@ void wma_delete_bss_ho_fail(tp_wma_handle wma, tpDeleteBssParams params)
__func__, params->smesessionId);
cdp_fc_vdev_pause(soc, iface->handle,
OL_TXQ_PAUSE_REASON_VDEV_STOP);
iface->pause_bitmap |= (1 << PAUSE_TYPE_HOST);
wma_vdev_set_pause_bit(params->smesessionId, PAUSE_TYPE_HOST);
cdp_fc_vdev_flush(soc, iface->handle);
WMA_LOGD("%s, vdev_id: %d, un-pausing tx_ll_queue for VDEV_STOP rsp",
__func__, params->smesessionId);
cdp_fc_vdev_unpause(soc, iface->handle,
OL_TXQ_PAUSE_REASON_VDEV_STOP);
iface->pause_bitmap &= ~(1 << PAUSE_TYPE_HOST);
wma_vdev_clear_pause_bit(params->smesessionId, PAUSE_TYPE_HOST);
qdf_atomic_set(&iface->bss_status, WMA_BSS_STATUS_STOPPED);
WMA_LOGD("%s: (type %d subtype %d) BSS is stopped",
__func__, iface->type, iface->sub_type);
@ -4602,11 +4602,10 @@ void wma_delete_bss(tp_wma_handle wma, tpDeleteBssParams params)
WMA_LOGD("%s, vdev_id: %d, pausing tx_ll_queue for VDEV_STOP (del_bss)",
__func__, params->smesessionId);
iface->pause_bitmap |= (1 << PAUSE_TYPE_HOST);
wma_vdev_set_pause_bit(params->smesessionId, PAUSE_TYPE_HOST);
cdp_fc_vdev_pause(soc,
wma->interfaces[params->smesessionId].handle,
OL_TXQ_PAUSE_REASON_VDEV_STOP);
iface->pause_bitmap |= (1 << PAUSE_TYPE_HOST);
if (wma_send_vdev_stop_to_fw(wma, params->smesessionId)) {
WMA_LOGP("%s: %d Failed to send vdev stop", __func__, __LINE__);

View file

@ -86,6 +86,7 @@
#include "wlan_global_lmac_if_api.h"
#include "target_if_pmo.h"
#include "wma_he.h"
#include "wlan_pmo_obj_mgmt_api.h"
#include <cdp_txrx_handle.h>
#define WMA_LOG_COMPLETION_TIMER 10000 /* 10 seconds */
@ -2533,6 +2534,11 @@ QDF_STATUS wma_open(struct wlan_objmgr_psoc *psoc, void *cds_context,
wma_ndp_register_all_event_handlers(wma_handle);
wma_register_debug_callback();
/* Register callback with PMO so PMO can update the vdev pause bitmap*/
pmo_register_pause_bitmap_notifier(wma_handle->psoc,
wma_vdev_update_pause_bitmap);
pmo_register_get_pause_bitmap(wma_handle->psoc,
wma_vdev_get_pause_bitmap);
return QDF_STATUS_SUCCESS;
@ -3634,6 +3640,12 @@ QDF_STATUS wma_close(void *cds_ctx)
target_if_close();
wma_target_if_close(wma_handle);
pmo_unregister_pause_bitmap_notifier(wma_handle->psoc,
wma_vdev_update_pause_bitmap);
pmo_unregister_get_pause_bitmap(wma_handle->psoc,
wma_vdev_get_pause_bitmap);
WMA_LOGD("%s: Exit", __func__);
return QDF_STATUS_SUCCESS;
}

View file

@ -2935,8 +2935,7 @@ void wma_hidden_ssid_vdev_restart(tp_wma_handle wma_handle,
wma_handle->
interfaces[pReq->sessionId].handle,
OL_TXQ_PAUSE_REASON_VDEV_STOP);
wma_handle->interfaces[pReq->sessionId].pause_bitmap |=
(1 << PAUSE_TYPE_HOST);
wma_vdev_set_pause_bit(pReq->sessionId, PAUSE_TYPE_HOST);
if (wma_send_vdev_stop_to_fw(wma_handle, pReq->sessionId)) {
WMA_LOGE("%s: %d Failed to send vdev stop", __func__, __LINE__);
qdf_atomic_set(&intr[pReq->sessionId].vdev_restart_params.