blob: b00b905d3a9f7d8f1a9258f76f65b79bc410b463 [file] [log] [blame]
/*
* Copyright (c) 2016-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
* above copyright notice and this permission notice appear in all
* copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
/**
* @file cdp_txrx_flow_ctrl_legacy.h
* @brief Define the host data path legacy flow control API
* functions
*/
#ifndef _CDP_TXRX_FC_LEG_H_
#define _CDP_TXRX_FC_LEG_H_
#include <cdp_txrx_mob_def.h>
#include "cdp_txrx_handle.h"
#ifdef QCA_HL_NETDEV_FLOW_CONTROL
/**
* cdp_hl_fc_register() - Register HL flow control callback.
* @soc: data path soc handle
* @pdev_id: datapath pdev identifier
* @flowcontrol: callback function pointer to stop/start OS netdev queues
*
* Register flow control callback.
*
* Returns: 0 for success
*/
static inline int
cdp_hl_fc_register(ol_txrx_soc_handle soc, uint8_t pdev_id,
tx_pause_callback flowcontrol)
{
if (!soc || !soc->ops) {
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
"%s invalid instance", __func__);
QDF_BUG(0);
return -EINVAL;
}
if (!soc->ops->l_flowctl_ops ||
!soc->ops->l_flowctl_ops->register_tx_flow_control)
return -EINVAL;
return soc->ops->l_flowctl_ops->register_tx_flow_control(soc, pdev_id,
flowcontrol);
}
static inline int cdp_hl_fc_set_td_limit(ol_txrx_soc_handle soc,
uint8_t vdev_id, uint32_t chan_freq)
{
if (!soc->ops->l_flowctl_ops->set_vdev_tx_desc_limit)
return 0;
return soc->ops->l_flowctl_ops->set_vdev_tx_desc_limit(soc, vdev_id,
chan_freq);
}
static inline int cdp_hl_fc_set_os_queue_status(ol_txrx_soc_handle soc,
uint8_t vdev_id,
enum netif_action_type action)
{
if (!soc->ops->l_flowctl_ops->set_vdev_os_queue_status)
return -EINVAL;
return soc->ops->l_flowctl_ops->set_vdev_os_queue_status(soc,
vdev_id,
action);
}
#else
static inline int
cdp_hl_fc_register(ol_txrx_soc_handle soc, uint8_t pdev_id,
tx_pause_callback flowcontrol)
{
return 0;
}
static inline int cdp_hl_fc_set_td_limit(ol_txrx_soc_handle soc,
uint8_t vdev_id, uint32_t chan_freq)
{
return 0;
}
static inline int cdp_hl_fc_set_os_queue_status(ol_txrx_soc_handle soc,
uint8_t vdev_id,
enum netif_action_type action)
{
return 0;
}
#endif /* QCA_HL_NETDEV_FLOW_CONTROL */
#ifdef QCA_LL_LEGACY_TX_FLOW_CONTROL
/**
* cdp_fc_register() - Register flow control callback function pointer
* @soc - data path soc handle
* @vdev_id - virtual interface id to register flow control
* @flowControl - callback function pointer
* @osif_fc_ctx - client context pointer
* @flow_control_is_pause: is vdev paused by flow control
*
* Register flow control callback function pointer and client context pointer
*
* return 0 success
*/
static inline int
cdp_fc_register(ol_txrx_soc_handle soc, uint8_t vdev_id,
ol_txrx_tx_flow_control_fp flowcontrol, void *osif_fc_ctx,
ol_txrx_tx_flow_control_is_pause_fp flow_control_is_pause)
{
if (!soc || !soc->ops) {
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
"%s invalid instance", __func__);
QDF_BUG(0);
return 0;
}
if (!soc->ops->l_flowctl_ops ||
!soc->ops->l_flowctl_ops->register_tx_flow_control)
return 0;
return soc->ops->l_flowctl_ops->register_tx_flow_control(
soc, vdev_id, flowcontrol, osif_fc_ctx,
flow_control_is_pause);
}
#else
static inline int
cdp_fc_register(ol_txrx_soc_handle soc, uint8_t vdev_id,
ol_txrx_tx_flow_control_fp flowcontrol, void *osif_fc_ctx,
ol_txrx_tx_flow_control_is_pause_fp flow_control_is_pause)
{
return 0;
}
#endif /* QCA_LL_LEGACY_TX_FLOW_CONTROL */
/**
* cdp_fc_deregister() - remove flow control instance
* @soc - data path soc handle
* @vdev_id - virtual interface id to register flow control
*
* remove flow control instance
*
* return 0 success
*/
static inline int
cdp_fc_deregister(ol_txrx_soc_handle soc, uint8_t vdev_id)
{
if (!soc || !soc->ops) {
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
"%s invalid instance", __func__);
QDF_BUG(0);
return 0;
}
if (!soc->ops->l_flowctl_ops ||
!soc->ops->l_flowctl_ops->deregister_tx_flow_control_cb)
return 0;
return soc->ops->l_flowctl_ops->deregister_tx_flow_control_cb(
soc, vdev_id);
}
/**
* cdp_fc_get_tx_resource() - get data path resource count
* @soc: data path soc handle
* @pdev_id: datapath pdev ID
* @peer_addr: peer mac address
* @low_watermark: low resource threshold
* @high_watermark_offset: high resource threshold
*
* get data path resource count
*
* return true enough data path resource available
* false resource is not avaialbe
*/
static inline bool
cdp_fc_get_tx_resource(ol_txrx_soc_handle soc, uint8_t pdev_id,
struct qdf_mac_addr peer_addr,
unsigned int low_watermark,
unsigned int high_watermark_offset)
{
if (!soc || !soc->ops) {
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
"%s invalid instance", __func__);
QDF_BUG(0);
return false;
}
if (!soc->ops->l_flowctl_ops ||
!soc->ops->l_flowctl_ops->get_tx_resource)
return false;
return soc->ops->l_flowctl_ops->get_tx_resource(soc, pdev_id, peer_addr,
low_watermark,
high_watermark_offset);
}
/**
* cdp_fc_ll_set_tx_pause_q_depth() - set pause queue depth
* @soc - data path soc handle
* @vdev_id - virtual interface id to register flow control
* @pause_q_depth - pending tx queue delth
*
* set pause queue depth
*
* return 0 success
*/
static inline int
cdp_fc_ll_set_tx_pause_q_depth(ol_txrx_soc_handle soc,
uint8_t vdev_id, int pause_q_depth)
{
if (!soc || !soc->ops) {
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
"%s invalid instance", __func__);
QDF_BUG(0);
return 0;
}
if (!soc->ops->l_flowctl_ops ||
!soc->ops->l_flowctl_ops->ll_set_tx_pause_q_depth)
return 0;
return soc->ops->l_flowctl_ops->ll_set_tx_pause_q_depth(
soc, vdev_id, pause_q_depth);
}
/**
* cdp_fc_vdev_flush() - flush tx queue
* @soc: data path soc handle
* @vdev_id: id of vdev
*
* flush tx queue
*
* return None
*/
static inline void
cdp_fc_vdev_flush(ol_txrx_soc_handle soc, uint8_t vdev_id)
{
if (!soc || !soc->ops) {
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
"%s invalid instance", __func__);
QDF_BUG(0);
return;
}
if (!soc->ops->l_flowctl_ops ||
!soc->ops->l_flowctl_ops->vdev_flush)
return;
soc->ops->l_flowctl_ops->vdev_flush(soc, vdev_id);
}
/**
* cdp_fc_vdev_pause() - pause tx scheduler on vdev
* @soc: data path soc handle
* @vdev_id: id of vdev
* @reason: pause reason
* @pause_type: type of pause
*
* pause tx scheduler on vdev
*
* return None
*/
static inline void
cdp_fc_vdev_pause(ol_txrx_soc_handle soc, uint8_t vdev_id,
uint32_t reason, uint32_t pause_type)
{
if (!soc || !soc->ops) {
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
"%s invalid instance", __func__);
QDF_BUG(0);
return;
}
if (!soc->ops->l_flowctl_ops ||
!soc->ops->l_flowctl_ops->vdev_pause)
return;
soc->ops->l_flowctl_ops->vdev_pause(soc, vdev_id, reason, pause_type);
}
/**
* cdp_fc_vdev_unpause() - resume tx scheduler on vdev
* @soc: data path soc handle
* @vdev_id: id of vdev
* @reason: pause reason
* @pause_type: type of pause
*
* resume tx scheduler on vdev
*
* return None
*/
static inline void
cdp_fc_vdev_unpause(ol_txrx_soc_handle soc, uint8_t vdev_id,
uint32_t reason, uint32_t pause_type)
{
if (!soc || !soc->ops) {
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
"%s invalid instance", __func__);
return;
}
if (!soc->ops->l_flowctl_ops ||
!soc->ops->l_flowctl_ops->vdev_unpause)
return;
soc->ops->l_flowctl_ops->vdev_unpause(soc, vdev_id, reason,
pause_type);
}
#endif /* _CDP_TXRX_FC_LEG_H_ */