qcacld-3.0: Support stats quota for sta + sap ipa offload
Implement metering stats quota to support ipa offload sta plus sap wifi sharing use cases. Change-Id: Ic9d5ad817ffb4d671a43f3f3aebb2d8cce293873 CRs-Fixed: 2517696
Dieser Commit ist enthalten in:

committet von
nshrivas

Ursprung
44f9ab7ee1
Commit
3bc886df40
@@ -326,6 +326,7 @@ bool wlan_ipa_is_rm_released(struct wlan_ipa_priv *ipa_ctx)
|
||||
|
||||
#ifdef FEATURE_METERING
|
||||
|
||||
#ifndef WDI3_STATS_UPDATE
|
||||
/**
|
||||
* wlan_ipa_uc_op_metering() - IPA uC operation for stats and quota limit
|
||||
* @ipa_ctx: IPA context
|
||||
@@ -334,7 +335,15 @@ bool wlan_ipa_is_rm_released(struct wlan_ipa_priv *ipa_ctx)
|
||||
* Return: QDF_STATUS enumeration
|
||||
*/
|
||||
QDF_STATUS wlan_ipa_uc_op_metering(struct wlan_ipa_priv *ipa_ctx,
|
||||
struct op_msg_type *op_msg);
|
||||
struct op_msg_type *op_msg);
|
||||
#else
|
||||
static inline
|
||||
QDF_STATUS wlan_ipa_uc_op_metering(struct wlan_ipa_priv *ipa_ctx,
|
||||
struct op_msg_type *op_msg)
|
||||
{
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* wlan_ipa_wdi_meter_notifier_cb() - SSR wrapper for
|
||||
@@ -356,6 +365,25 @@ void wlan_ipa_wdi_meter_notifier_cb(qdf_ipa_wdi_meter_evt_type_t evt,
|
||||
* Return: QDF_STATUS enumeration
|
||||
*/
|
||||
void wlan_ipa_init_metering(struct wlan_ipa_priv *ipa_ctx);
|
||||
|
||||
#ifdef WDI3_STATS_UPDATE
|
||||
/**
|
||||
* wlan_ipa_update_tx_stats() - send embedded tx traffic in bytes to IPA
|
||||
* @ipa_ctx: IPA context
|
||||
* @sta_tx: tx in bytes on sta interface
|
||||
* @sap_tx: tx in bytes on sap interface
|
||||
*
|
||||
* Return: void
|
||||
*/
|
||||
void wlan_ipa_update_tx_stats(struct wlan_ipa_priv *ipa_ctx, uint64_t sta_tx,
|
||||
uint64_t sap_tx);
|
||||
#else
|
||||
static inline void wlan_ipa_update_tx_stats(struct wlan_ipa_priv *ipa_ctx,
|
||||
uint64_t sta_tx, uint64_t sap_tx)
|
||||
{
|
||||
}
|
||||
#endif /* WDI3_STATS_UPDATE */
|
||||
|
||||
#else
|
||||
|
||||
static inline
|
||||
@@ -372,6 +400,11 @@ static inline void wlan_ipa_wdi_meter_notifier_cb(void)
|
||||
static inline void wlan_ipa_init_metering(struct wlan_ipa_priv *ipa_ctx)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void wlan_ipa_update_tx_stats(struct wlan_ipa_priv *ipa_ctx,
|
||||
uint64_t sta_tx, uint64_t sap_tx)
|
||||
{
|
||||
}
|
||||
#endif /* FEATURE_METERING */
|
||||
|
||||
/**
|
||||
|
@@ -441,9 +441,15 @@ void ipa_component_config_update(struct wlan_objmgr_psoc *psoc);
|
||||
*
|
||||
* Return: IPA config tx buffer count
|
||||
*/
|
||||
|
||||
uint32_t ipa_get_tx_buf_count(void);
|
||||
|
||||
/**
|
||||
* ipa_update_tx_stats() - Update embedded tx traffic in bytes to IPA
|
||||
*
|
||||
* Return: IPA config tx buffer count
|
||||
*/
|
||||
void ipa_update_tx_stats(struct wlan_objmgr_pdev *pdev, uint64_t sta_tx,
|
||||
uint64_t ap_tx);
|
||||
#else /* Not IPA_OFFLOAD */
|
||||
typedef QDF_STATUS (*wlan_ipa_softap_xmit)(qdf_nbuf_t nbuf, qdf_netdev_t dev);
|
||||
typedef void (*wlan_ipa_send_to_nw)(qdf_nbuf_t nbuf, qdf_netdev_t dev);
|
||||
|
@@ -664,6 +664,7 @@ struct wlan_ipa_priv {
|
||||
|
||||
uint32_t wdi_version;
|
||||
bool is_smmu_enabled; /* IPA caps returned from ipa_wdi_init */
|
||||
qdf_atomic_t stats_quota;
|
||||
};
|
||||
|
||||
#define WLAN_IPA_WLAN_FRAG_HEADER sizeof(struct frag_header)
|
||||
|
@@ -1952,6 +1952,7 @@ static QDF_STATUS __wlan_ipa_wlan_evt(qdf_netdev_t net_dev, uint8_t device_mode,
|
||||
SIR_STA_RX_DATA_OFFLOAD, session_id,
|
||||
true);
|
||||
qdf_mutex_acquire(&ipa_ctx->event_lock);
|
||||
qdf_atomic_set(&ipa_ctx->stats_quota, 1);
|
||||
}
|
||||
|
||||
if (!wlan_ipa_is_sta_only_offload_enabled()) {
|
||||
@@ -2075,6 +2076,7 @@ static QDF_STATUS __wlan_ipa_wlan_evt(qdf_netdev_t net_dev, uint8_t device_mode,
|
||||
if (wlan_ipa_uc_sta_is_enabled(ipa_ctx->config) &&
|
||||
(ipa_ctx->sap_num_connected_sta > 0 ||
|
||||
wlan_ipa_is_sta_only_offload_enabled())) {
|
||||
qdf_atomic_set(&ipa_ctx->stats_quota, 0);
|
||||
qdf_mutex_release(&ipa_ctx->event_lock);
|
||||
wlan_ipa_uc_offload_enable_disable(ipa_ctx,
|
||||
SIR_STA_RX_DATA_OFFLOAD, session_id, false);
|
||||
@@ -2178,6 +2180,7 @@ static QDF_STATUS __wlan_ipa_wlan_evt(qdf_netdev_t net_dev, uint8_t device_mode,
|
||||
SIR_STA_RX_DATA_OFFLOAD,
|
||||
sta_session_id, true);
|
||||
qdf_mutex_acquire(&ipa_ctx->event_lock);
|
||||
qdf_atomic_set(&ipa_ctx->stats_quota, 1);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -2195,6 +2198,8 @@ static QDF_STATUS __wlan_ipa_wlan_evt(qdf_netdev_t net_dev, uint8_t device_mode,
|
||||
ipa_ctx->config) &&
|
||||
ipa_ctx->sta_connected &&
|
||||
!wlan_ipa_is_sta_only_offload_enabled()) {
|
||||
qdf_atomic_set(&ipa_ctx->stats_quota,
|
||||
0);
|
||||
qdf_mutex_release(&ipa_ctx->event_lock);
|
||||
wlan_ipa_uc_offload_enable_disable(
|
||||
ipa_ctx,
|
||||
@@ -2304,6 +2309,7 @@ static QDF_STATUS __wlan_ipa_wlan_evt(qdf_netdev_t net_dev, uint8_t device_mode,
|
||||
if (wlan_ipa_uc_sta_is_enabled(ipa_ctx->config) &&
|
||||
ipa_ctx->sta_connected &&
|
||||
!wlan_ipa_is_sta_only_offload_enabled()) {
|
||||
qdf_atomic_set(&ipa_ctx->stats_quota, 0);
|
||||
qdf_mutex_release(&ipa_ctx->event_lock);
|
||||
wlan_ipa_uc_offload_enable_disable(ipa_ctx,
|
||||
SIR_STA_RX_DATA_OFFLOAD,
|
||||
|
@@ -643,3 +643,20 @@ uint32_t ipa_get_tx_buf_count(void)
|
||||
{
|
||||
return g_ipa_config ? g_ipa_config->txbuf_count : 0;
|
||||
}
|
||||
|
||||
void ipa_update_tx_stats(struct wlan_objmgr_pdev *pdev, uint64_t sta_tx,
|
||||
uint64_t ap_tx)
|
||||
{
|
||||
struct wlan_ipa_priv *ipa_obj;
|
||||
|
||||
if (!ipa_config_is_enabled())
|
||||
return;
|
||||
|
||||
ipa_obj = ipa_pdev_get_priv_obj(pdev);
|
||||
if (!ipa_obj) {
|
||||
ipa_err("IPA object is NULL");
|
||||
return;
|
||||
}
|
||||
|
||||
wlan_ipa_update_tx_stats(ipa_obj, sta_tx, ap_tx);
|
||||
}
|
||||
|
@@ -748,6 +748,39 @@ void wlan_ipa_uc_stat(struct wlan_ipa_priv *ipa_ctx)
|
||||
}
|
||||
|
||||
#ifdef FEATURE_METERING
|
||||
|
||||
#ifdef WDI3_STATS_UPDATE
|
||||
/**
|
||||
* wlan_ipa_wdi_meter_notifier_cb() - WLAN to IPA callback handler.
|
||||
* IPA calls to get WLAN stats or set quota limit.
|
||||
* @priv: pointer to private data registered with IPA (we register a
|
||||
* pointer to the IPA context)
|
||||
* @evt: the IPA event which triggered the callback
|
||||
* @data: data associated with the event
|
||||
*
|
||||
* Return: None
|
||||
*/
|
||||
static void __wlan_ipa_wdi_meter_notifier_cb(qdf_ipa_wdi_meter_evt_type_t evt,
|
||||
void *data)
|
||||
{
|
||||
}
|
||||
|
||||
void wlan_ipa_update_tx_stats(struct wlan_ipa_priv *ipa_ctx, uint64_t sta_tx,
|
||||
uint64_t ap_tx)
|
||||
{
|
||||
qdf_ipa_wdi_tx_info_t tx_stats;
|
||||
|
||||
if (!qdf_atomic_read(&ipa_ctx->stats_quota))
|
||||
return;
|
||||
|
||||
QDF_IPA_WDI_TX_INFO_STA_TX_BYTES(&tx_stats) = sta_tx;
|
||||
QDF_IPA_WDI_TX_INFO_SAP_TX_BYTES(&tx_stats) = ap_tx;
|
||||
|
||||
qdf_ipa_wdi_wlan_stats(&tx_stats);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/**
|
||||
* wlan_ipa_uc_sharing_stats_request() - Get IPA stats from IPA.
|
||||
* @ipa_ctx: IPA context
|
||||
@@ -793,56 +826,6 @@ static void wlan_ipa_uc_set_quota(struct wlan_ipa_priv *ipa_ctx,
|
||||
}
|
||||
}
|
||||
|
||||
QDF_STATUS wlan_ipa_uc_op_metering(struct wlan_ipa_priv *ipa_ctx,
|
||||
struct op_msg_type *op_msg)
|
||||
{
|
||||
struct op_msg_type *msg = op_msg;
|
||||
struct ipa_uc_sharing_stats *uc_sharing_stats;
|
||||
struct ipa_uc_quota_rsp *uc_quota_rsp;
|
||||
struct ipa_uc_quota_ind *uc_quota_ind;
|
||||
struct wlan_ipa_iface_context *iface_ctx;
|
||||
|
||||
if (msg->op_code == WLAN_IPA_UC_OPCODE_SHARING_STATS) {
|
||||
/* fill-up ipa_uc_sharing_stats structure from FW */
|
||||
uc_sharing_stats = (struct ipa_uc_sharing_stats *)
|
||||
((uint8_t *)op_msg + sizeof(struct op_msg_type));
|
||||
|
||||
memcpy(&(ipa_ctx->ipa_sharing_stats), uc_sharing_stats,
|
||||
sizeof(struct ipa_uc_sharing_stats));
|
||||
|
||||
qdf_event_set(&ipa_ctx->ipa_uc_sharing_stats_comp);
|
||||
} else if (msg->op_code == WLAN_IPA_UC_OPCODE_QUOTA_RSP) {
|
||||
/* received set quota response */
|
||||
uc_quota_rsp = (struct ipa_uc_quota_rsp *)
|
||||
((uint8_t *)op_msg + sizeof(struct op_msg_type));
|
||||
|
||||
memcpy(&(ipa_ctx->ipa_quota_rsp), uc_quota_rsp,
|
||||
sizeof(struct ipa_uc_quota_rsp));
|
||||
|
||||
qdf_event_set(&ipa_ctx->ipa_uc_set_quota_comp);
|
||||
} else if (msg->op_code == WLAN_IPA_UC_OPCODE_QUOTA_IND) {
|
||||
/* hit quota limit */
|
||||
uc_quota_ind = (struct ipa_uc_quota_ind *)
|
||||
((uint8_t *)op_msg + sizeof(struct op_msg_type));
|
||||
|
||||
ipa_ctx->ipa_quota_ind.quota_bytes =
|
||||
uc_quota_ind->quota_bytes;
|
||||
|
||||
/* send quota exceeded indication to IPA */
|
||||
iface_ctx = wlan_ipa_get_iface(ipa_ctx, QDF_STA_MODE);
|
||||
if (iface_ctx)
|
||||
qdf_ipa_broadcast_wdi_quota_reach_ind(
|
||||
iface_ctx->dev->ifindex,
|
||||
uc_quota_ind->quota_bytes);
|
||||
else
|
||||
ipa_err("Failed quota_reach_ind: NULL interface");
|
||||
} else {
|
||||
return QDF_STATUS_E_INVAL;
|
||||
}
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* __wlan_ipa_wdi_meter_notifier_cb() - WLAN to IPA callback handler.
|
||||
* IPA calls to get WLAN stats or set quota limit.
|
||||
@@ -940,6 +923,60 @@ static void __wlan_ipa_wdi_meter_notifier_cb(qdf_ipa_wdi_meter_evt_type_t evt,
|
||||
}
|
||||
}
|
||||
|
||||
QDF_STATUS wlan_ipa_uc_op_metering(struct wlan_ipa_priv *ipa_ctx,
|
||||
struct op_msg_type *op_msg)
|
||||
{
|
||||
struct op_msg_type *msg = op_msg;
|
||||
struct ipa_uc_sharing_stats *uc_sharing_stats;
|
||||
struct ipa_uc_quota_rsp *uc_quota_rsp;
|
||||
struct ipa_uc_quota_ind *uc_quota_ind;
|
||||
struct wlan_ipa_iface_context *iface_ctx;
|
||||
uint32_t ifindex;
|
||||
uint64_t quota_bytes;
|
||||
|
||||
if (msg->op_code == WLAN_IPA_UC_OPCODE_SHARING_STATS) {
|
||||
/* fill-up ipa_uc_sharing_stats structure from FW */
|
||||
uc_sharing_stats = (struct ipa_uc_sharing_stats *)
|
||||
((uint8_t *)op_msg + sizeof(struct op_msg_type));
|
||||
|
||||
memcpy(&ipa_ctx->ipa_sharing_stats, uc_sharing_stats,
|
||||
sizeof(struct ipa_uc_sharing_stats));
|
||||
|
||||
qdf_event_set(&ipa_ctx->ipa_uc_sharing_stats_comp);
|
||||
} else if (msg->op_code == WLAN_IPA_UC_OPCODE_QUOTA_RSP) {
|
||||
/* received set quota response */
|
||||
uc_quota_rsp = (struct ipa_uc_quota_rsp *)
|
||||
((uint8_t *)op_msg + sizeof(struct op_msg_type));
|
||||
|
||||
memcpy(&ipa_ctx->ipa_quota_rsp, uc_quota_rsp,
|
||||
sizeof(struct ipa_uc_quota_rsp));
|
||||
|
||||
qdf_event_set(&ipa_ctx->ipa_uc_set_quota_comp);
|
||||
} else if (msg->op_code == WLAN_IPA_UC_OPCODE_QUOTA_IND) {
|
||||
/* hit quota limit */
|
||||
uc_quota_ind = (struct ipa_uc_quota_ind *)
|
||||
((uint8_t *)op_msg + sizeof(struct op_msg_type));
|
||||
|
||||
ipa_ctx->ipa_quota_ind.quota_bytes =
|
||||
uc_quota_ind->quota_bytes;
|
||||
|
||||
/* send quota exceeded indication to IPA */
|
||||
iface_ctx = wlan_ipa_get_iface(ipa_ctx, QDF_STA_MODE);
|
||||
ifindex = iface_ctx->dev->ifindex;
|
||||
quota_bytes = uc_quota_ind->quota_bytes;
|
||||
if (iface_ctx)
|
||||
qdf_ipa_broadcast_wdi_quota_reach_ind(ifindex,
|
||||
quota_bytes);
|
||||
else
|
||||
ipa_err("Failed quota_reach_ind: NULL interface");
|
||||
} else {
|
||||
return QDF_STATUS_E_INVAL;
|
||||
}
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
#endif /* WDI3_STATS_UPDATE */
|
||||
|
||||
/**
|
||||
* wlan_ipa_wdi_meter_notifier_cb() - SSR wrapper for
|
||||
* __wlan_ipa_wdi_meter_notifier_cb
|
||||
@@ -962,5 +999,4 @@ void wlan_ipa_wdi_meter_notifier_cb(qdf_ipa_wdi_meter_evt_type_t evt,
|
||||
|
||||
qdf_op_unprotect(op_sync);
|
||||
}
|
||||
|
||||
#endif /* FEATURE_METERING */
|
||||
|
In neuem Issue referenzieren
Einen Benutzer sperren