qcacld-3.0: Add traffic end indication support in DP component

Add ucfg APIs to set/get feature status and dscp
values and structure to store values

Change-Id: I839c89696581b8aefd873a120d938a5cbbc32899
CRs-Fixed: 3255692
This commit is contained in:
nakul kachhwaha
2022-05-19 12:52:54 +05:30
committed by Madan Koyyalamudi
parent c41b646825
commit 49baf5f10c
6 changed files with 265 additions and 0 deletions

View File

@@ -286,6 +286,7 @@ struct link_monitoring {
* @conn_info: STA connection information
* @bss_state: AP BSS state
* @qdf_sta_eap_frm_done_event: EAP frame event management
* @traffic_end_ind: store traffic end indication info
*/
struct wlan_dp_intf {
struct wlan_dp_psoc_context *dp_ctx;
@@ -346,6 +347,7 @@ struct wlan_dp_intf {
enum bss_intf_state bss_state;
qdf_event_t qdf_sta_eap_frm_done_event;
struct dp_traffic_end_indication traffic_end_ind;
};
/**

View File

@@ -520,6 +520,94 @@ static void dp_softap_config_tx_pkt_tracing(struct wlan_dp_intf *dp_intf,
QDF_TX));
}
#ifdef DP_TRAFFIC_END_INDICATION
/**
* wlan_dp_traffic_end_indication_update_dscp() - Compare dscp derived from
* provided tos value with
* stored value and update if
* it's equal to special dscp
* @dp_intf: pointer to DP interface
* @tos: pointer to tos
*
* Return: True if tos is updated else False
*/
static inline bool
wlan_dp_traffic_end_indication_update_dscp(struct wlan_dp_intf *dp_intf,
uint8_t *tos)
{
bool update;
uint8_t dscp, ecn;
ecn = (*tos & ~QDF_NBUF_PKT_IPV4_DSCP_MASK);
dscp = (*tos & QDF_NBUF_PKT_IPV4_DSCP_MASK) >>
QDF_NBUF_PKT_IPV4_DSCP_SHIFT;
update = (dp_intf->traffic_end_ind.spl_dscp == dscp);
if (update)
*tos = ((dp_intf->traffic_end_ind.def_dscp <<
QDF_NBUF_PKT_IPV4_DSCP_SHIFT) | ecn);
return update;
}
/**
* dp_softap_inspect_traffic_end_indication_pkt() - Restore tos field for last
* packet in data stream
* @dp_intf: pointer to DP interface
* @nbuf: pointer to OS packet
*
* Return: None
*/
static inline void
dp_softap_inspect_traffic_end_indication_pkt(struct wlan_dp_intf *dp_intf,
qdf_nbuf_t nbuf)
{
uint8_t tos, tc;
bool ret;
if (qdf_nbuf_data_is_ipv4_pkt(qdf_nbuf_data(nbuf))) {
tos = qdf_nbuf_data_get_ipv4_tos(qdf_nbuf_data(nbuf));
ret = wlan_dp_traffic_end_indication_update_dscp(dp_intf, &tos);
if (ret) {
qdf_nbuf_data_set_ipv4_tos(qdf_nbuf_data(nbuf), tos);
if (qdf_nbuf_is_ipv4_last_fragment(nbuf))
QDF_NBUF_CB_GET_PACKET_TYPE(nbuf) =
QDF_NBUF_CB_PACKET_TYPE_END_INDICATION;
}
} else if (qdf_nbuf_is_ipv6_pkt(nbuf)) {
tc = qdf_nbuf_data_get_ipv6_tc(qdf_nbuf_data(nbuf));
ret = wlan_dp_traffic_end_indication_update_dscp(dp_intf, &tc);
if (ret) {
qdf_nbuf_data_set_ipv6_tc(qdf_nbuf_data(nbuf), tc);
QDF_NBUF_CB_GET_PACKET_TYPE(nbuf) =
QDF_NBUF_CB_PACKET_TYPE_END_INDICATION;
}
}
}
/**
* dp_softap_traffic_end_indication_enabled() - Check if traffic end indication
* is enabled or not
* @dp_intf: pointer to DP interface
*
* Return: True or False
*/
static inline bool
dp_softap_traffic_end_indication_enabled(struct wlan_dp_intf *dp_intf)
{
return qdf_unlikely(dp_intf->traffic_end_ind.enabled);
}
#else
static inline bool
dp_softap_traffic_end_indication_enabled(struct wlan_dp_intf *dp_intf)
{
return false;
}
static inline void
dp_softap_inspect_traffic_end_indication_pkt(struct wlan_dp_intf *dp_intf,
qdf_nbuf_t nbuf)
{}
#endif
/**
* dp_softap_start_xmit() - Transmit a frame
* @nbuf: pointer to Network buffer
@@ -579,6 +667,9 @@ QDF_STATUS dp_softap_start_xmit(qdf_nbuf_t nbuf, struct wlan_dp_intf *dp_intf)
dp_event_eapol_log(nbuf, QDF_TX);
}
if (dp_softap_traffic_end_indication_enabled(dp_intf))
dp_softap_inspect_traffic_end_indication_pkt(dp_intf, nbuf);
dp_softap_config_tx_pkt_tracing(dp_intf, nbuf);
/* check whether need to linearize skb, like non-linear udp data */

View File

@@ -720,4 +720,16 @@ struct wlan_dp_user_config {
uint32_t arp_connectivity_map;
};
/**
* struct dp_traffic_end_indication - Trafic end indication
* @enabled: Feature enabled/disabled config
* @def_dscp: Default DSCP value in regular packets in traffic
* @spl_dscp: Special DSCP value to be used by packet to mark
* end of data stream
*/
struct dp_traffic_end_indication {
bool enabled;
uint8_t def_dscp;
uint8_t spl_dscp;
};
#endif /* end of _WLAN_DP_PUBLIC_STRUCT_H_ */

View File

@@ -1231,4 +1231,59 @@ dp_ucfg_enable_link_monitoring(struct wlan_objmgr_psoc *psoc,
void
dp_ucfg_disable_link_monitoring(struct wlan_objmgr_psoc *psoc,
struct wlan_objmgr_vdev *vdev);
#ifdef DP_TRAFFIC_END_INDICATION
/**
* ucfg_dp_traffic_end_indication_get() - Get data end indication info
* @vdev: vdev handle
* @info: variable to hold stored data end indication info
*
* Return: QDF_STATUS
*/
QDF_STATUS
ucfg_dp_traffic_end_indication_get(struct wlan_objmgr_vdev *vdev,
struct dp_traffic_end_indication *info);
/**
* ucfg_dp_traffic_end_indication_set() - Store data end indication info
* @vdev: vdev handle
* @info: variable holding new data end indication info
*
* Return: QDF_STATUS
*/
QDF_STATUS
ucfg_dp_traffic_end_indication_set(struct wlan_objmgr_vdev *vdev,
struct dp_traffic_end_indication info);
/**
* ucfg_dp_traffic_end_indication_update_dscp() - update dscp value to default
* @psoc: psoc handle
* @vdev_id: vdev id
* @dscp: dscp value to be updated
*
* Return: void
*/
void
ucfg_dp_traffic_end_indication_update_dscp(struct wlan_objmgr_psoc *psoc,
uint8_t vdev_id,
unsigned char *dscp);
#else
static inline QDF_STATUS
ucfg_dp_traffic_end_indication_get(struct wlan_objmgr_vdev *vdev,
struct dp_traffic_end_indication *info)
{
return QDF_STATUS_SUCCESS;
}
static inline QDF_STATUS
ucfg_dp_traffic_end_indication_set(struct wlan_objmgr_vdev *vdev,
struct dp_traffic_end_indication info)
{
return QDF_STATUS_SUCCESS;
}
static inline void
ucfg_dp_traffic_end_indication_update_dscp(struct wlan_objmgr_psoc *psoc,
uint8_t vdev_id,
unsigned char *dscp)
{}
#endif
#endif /* _WLAN_DP_UCFG_API_H_ */

View File

@@ -35,6 +35,7 @@
#include "wlan_dp_txrx.h"
#include "wlan_nlink_common.h"
#include "wlan_pkt_capture_ucfg_api.h"
#include <cdp_txrx_ctrl.h>
void ucfg_dp_update_inf_mac(struct wlan_objmgr_psoc *psoc,
struct qdf_mac_addr *cur_mac,
@@ -2185,3 +2186,78 @@ dp_ucfg_disable_link_monitoring(struct wlan_objmgr_psoc *psoc,
dp_intf->link_monitoring.enabled = false;
dp_intf->link_monitoring.rx_linkspeed_threshold = 0;
}
#ifdef DP_TRAFFIC_END_INDICATION
QDF_STATUS
ucfg_dp_traffic_end_indication_get(struct wlan_objmgr_vdev *vdev,
struct dp_traffic_end_indication *info)
{
struct wlan_dp_intf *dp_intf = dp_get_vdev_priv_obj(vdev);
if (!dp_intf) {
dp_err("Unable to get DP interface");
return QDF_STATUS_E_INVAL;
}
info->enabled = dp_intf->traffic_end_ind.enabled;
info->def_dscp = dp_intf->traffic_end_ind.def_dscp;
info->spl_dscp = dp_intf->traffic_end_ind.spl_dscp;
return QDF_STATUS_SUCCESS;
}
QDF_STATUS
ucfg_dp_traffic_end_indication_set(struct wlan_objmgr_vdev *vdev,
struct dp_traffic_end_indication info)
{
struct wlan_dp_intf *dp_intf = dp_get_vdev_priv_obj(vdev);
cdp_config_param_type vdev_param;
if (!dp_intf) {
dp_err("Unable to get DP interface");
return QDF_STATUS_E_INVAL;
}
dp_intf->traffic_end_ind = info;
dp_debug("enabled:%u default dscp:%u special dscp:%u",
dp_intf->traffic_end_ind.enabled,
dp_intf->traffic_end_ind.def_dscp,
dp_intf->traffic_end_ind.spl_dscp);
vdev_param.cdp_vdev_param_traffic_end_ind = info.enabled;
if (cdp_txrx_set_vdev_param(cds_get_context(QDF_MODULE_ID_SOC),
dp_intf->intf_id,
CDP_ENABLE_TRAFFIC_END_INDICATION,
vdev_param))
dp_err("Failed to set traffic end indication param on DP vdev");
return QDF_STATUS_SUCCESS;
}
void ucfg_dp_traffic_end_indication_update_dscp(struct wlan_objmgr_psoc *psoc,
uint8_t vdev_id,
unsigned char *dscp)
{
struct wlan_objmgr_vdev *vdev;
struct wlan_dp_intf *dp_intf;
vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id, WLAN_DP_ID);
if (vdev) {
dp_intf = dp_get_vdev_priv_obj(vdev);
if (!dp_intf) {
dp_err("Unable to get DP interface");
goto end;
}
if (!dp_intf->traffic_end_ind.enabled)
goto end;
if (*dscp == dp_intf->traffic_end_ind.spl_dscp)
*dscp = dp_intf->traffic_end_ind.def_dscp;
end:
wlan_objmgr_vdev_release_ref(vdev, WLAN_DP_ID);
}
}
#endif