diff --git a/dp/wifi3.0/be/dp_be_rx.c b/dp/wifi3.0/be/dp_be_rx.c index 427f870caf..d6af8397b1 100644 --- a/dp/wifi3.0/be/dp_be_rx.c +++ b/dp/wifi3.0/be/dp_be_rx.c @@ -780,6 +780,9 @@ done: dp_rx_fill_gro_info(soc, rx_tlv_hdr, nbuf, &rx_ol_pkt_cnt); + dp_rx_mark_first_packet_after_wow_wakeup(vdev->pdev, rx_tlv_hdr, + nbuf); + dp_rx_update_stats(soc, nbuf); DP_RX_LIST_APPEND(deliver_list_head, deliver_list_tail, diff --git a/dp/wifi3.0/dp_main.c b/dp/wifi3.0/dp_main.c index d13e843107..25239d3f42 100644 --- a/dp/wifi3.0/dp_main.c +++ b/dp/wifi3.0/dp_main.c @@ -12938,6 +12938,32 @@ uint32_t dp_get_tx_rings_grp_bitmap(struct cdp_soc_t *soc_hdl) return soc->wlan_cfg_ctx->tx_rings_grp_bitmap; } +#ifdef WLAN_FEATURE_MARK_FIRST_WAKEUP_PACKET +/** + * dp_mark_first_wakeup_packet() - set flag to indicate that + * fw is compatible for marking first packet after wow wakeup + * @soc_hdl: Datapath soc handle + * @pdev_id: id of data path pdev handle + * @value: 1 for enabled/ 0 for disabled + * + * Return: None + */ +static void dp_mark_first_wakeup_packet(struct cdp_soc_t *soc_hdl, + uint8_t pdev_id, uint8_t value) +{ + struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl); + struct dp_pdev *pdev; + + pdev = dp_get_pdev_from_soc_pdev_id_wifi3(soc, pdev_id); + if (!pdev) { + dp_err("pdev is NULL"); + return; + } + + pdev->is_first_wakeup_packet = value; +} +#endif + #ifdef DP_PEER_EXTENDED_API static struct cdp_misc_ops dp_ops_misc = { #ifdef FEATURE_WLAN_TDLS @@ -12968,6 +12994,9 @@ static struct cdp_misc_ops dp_ops_misc = { #endif .display_txrx_hw_info = dp_display_srng_info, .get_tx_rings_grp_bitmap = dp_get_tx_rings_grp_bitmap, +#ifdef WLAN_FEATURE_MARK_FIRST_WAKEUP_PACKET + .mark_first_wakeup_packet = dp_mark_first_wakeup_packet, +#endif }; #endif diff --git a/dp/wifi3.0/dp_rx.c b/dp/wifi3.0/dp_rx.c index d5fd41c291..38d6e2a722 100644 --- a/dp/wifi3.0/dp_rx.c +++ b/dp/wifi3.0/dp_rx.c @@ -2997,3 +2997,21 @@ bool dp_rx_deliver_special_frame(struct dp_soc *soc, return false; } #endif + +#ifdef WLAN_FEATURE_MARK_FIRST_WAKEUP_PACKET +void dp_rx_mark_first_packet_after_wow_wakeup(struct dp_pdev *pdev, + uint8_t *rx_tlv, + qdf_nbuf_t nbuf) +{ + struct dp_soc *soc; + + if (!pdev->is_first_wakeup_packet) + return; + + soc = pdev->soc; + if (hal_get_first_wow_wakeup_packet(soc->hal_soc, rx_tlv)) { + qdf_nbuf_mark_wakeup_frame(nbuf); + dp_info("First packet after WOW Wakeup rcvd"); + } +} +#endif diff --git a/dp/wifi3.0/dp_rx.h b/dp/wifi3.0/dp_rx.h index 39d0f686a7..7189f74e9f 100644 --- a/dp/wifi3.0/dp_rx.h +++ b/dp/wifi3.0/dp_rx.h @@ -2096,6 +2096,27 @@ dp_rx_is_list_ready(qdf_nbuf_t nbuf_head, } #endif +#ifdef WLAN_FEATURE_MARK_FIRST_WAKEUP_PACKET +/** + * dp_rx_mark_first_packet_after_wow_wakeup - get first packet after wow wakeup + * @pdev: pointer to dp_pdev structure + * @rx_tlv: pointer to rx_pkt_tlvs structure + * @nbuf: pointer to skb buffer + * + * Return: None + */ +void dp_rx_mark_first_packet_after_wow_wakeup(struct dp_pdev *pdev, + uint8_t *rx_tlv, + qdf_nbuf_t nbuf); +#else +static inline void +dp_rx_mark_first_packet_after_wow_wakeup(struct dp_pdev *pdev, + uint8_t *rx_tlv, + qdf_nbuf_t nbuf) +{ +} +#endif + #if defined(WLAN_MAX_PDEVS) && (WLAN_MAX_PDEVS == 1) static inline uint8_t dp_rx_get_defrag_bm_id(struct dp_soc *soc) diff --git a/dp/wifi3.0/dp_types.h b/dp/wifi3.0/dp_types.h index 3a2a13c84b..4eed31572e 100644 --- a/dp/wifi3.0/dp_types.h +++ b/dp/wifi3.0/dp_types.h @@ -2866,6 +2866,9 @@ struct dp_pdev { #endif /* Is isolation mode enabled */ bool isolation; +#ifdef WLAN_FEATURE_MARK_FIRST_WAKEUP_PACKET + uint8_t is_first_wakeup_packet; +#endif }; struct dp_peer; diff --git a/dp/wifi3.0/li/dp_li_rx.c b/dp/wifi3.0/li/dp_li_rx.c index 9eb7ac5fa7..0147977218 100644 --- a/dp/wifi3.0/li/dp_li_rx.c +++ b/dp/wifi3.0/li/dp_li_rx.c @@ -904,6 +904,9 @@ done: dp_rx_fill_gro_info(soc, rx_tlv_hdr, nbuf, &rx_ol_pkt_cnt); + dp_rx_mark_first_packet_after_wow_wakeup(vdev->pdev, rx_tlv_hdr, + nbuf); + dp_rx_update_stats(soc, nbuf); dp_pkt_add_timestamp(txrx_peer->vdev, QDF_PKT_RX_DRIVER_ENTRY, diff --git a/hal/wifi3.0/hal_internal.h b/hal/wifi3.0/hal_internal.h index 233c1aace2..118e486474 100644 --- a/hal/wifi3.0/hal_internal.h +++ b/hal/wifi3.0/hal_internal.h @@ -1069,6 +1069,9 @@ struct hal_hw_txrx_ops { uint16_t peer_id, int tid, qdf_dma_addr_t hw_qdesc_paddr); +#ifdef WLAN_FEATURE_MARK_FIRST_WAKEUP_PACKET + uint8_t (*hal_get_first_wow_wakeup_packet)(uint8_t *buf); +#endif }; /** diff --git a/hal/wifi3.0/hal_rx.h b/hal/wifi3.0/hal_rx.h index 2eb8b96634..2590b07b06 100644 --- a/hal/wifi3.0/hal_rx.h +++ b/hal/wifi3.0/hal_rx.h @@ -2952,4 +2952,15 @@ hal_reo_shared_qaddr_is_enable(hal_soc_handle_t hal_soc_hdl) return hal->reo_qref.reo_qref_table_en; } + +#ifdef WLAN_FEATURE_MARK_FIRST_WAKEUP_PACKET +static inline uint8_t +hal_get_first_wow_wakeup_packet(hal_soc_handle_t hal_soc_hdl, uint8_t *buf) +{ + struct hal_soc *hal_soc = (struct hal_soc *)hal_soc_hdl; + + return hal_soc->ops->hal_get_first_wow_wakeup_packet(buf); +} +#endif + #endif /* _HAL_RX_H */ diff --git a/hal/wifi3.0/kiwi/hal_kiwi.c b/hal/wifi3.0/kiwi/hal_kiwi.c index aa5185ea51..c2d7e68260 100644 --- a/hal/wifi3.0/kiwi/hal_kiwi.c +++ b/hal/wifi3.0/kiwi/hal_kiwi.c @@ -1631,6 +1631,24 @@ static uint8_t hal_get_idle_link_bm_id_kiwi(uint8_t chip_id) return WBM_IDLE_DESC_LIST; } +#ifdef WLAN_FEATURE_MARK_FIRST_WAKEUP_PACKET +/** + * hal_get_first_wow_wakeup_packet_kiwi(): Function to get if the buffer + * is the first one that wakes up host from WoW. + * + * @buf: network buffer + * + * Dummy function for KIWI + * + * Returns: 1 to indicate it is first packet received that wakes up host from + * WoW. Otherwise 0 + */ +static inline uint8_t hal_get_first_wow_wakeup_packet_kiwi(uint8_t *buf) +{ + return 0; +} +#endif + static void hal_hw_txrx_ops_attach_kiwi(struct hal_soc *hal_soc) { /* init and setup */ @@ -1859,6 +1877,10 @@ static void hal_hw_txrx_ops_attach_kiwi(struct hal_soc *hal_soc) hal_soc->ops->hal_set_reo_ent_desc_reo_dest_ind = hal_set_reo_ent_desc_reo_dest_ind_be; hal_soc->ops->hal_get_idle_link_bm_id = hal_get_idle_link_bm_id_kiwi; +#ifdef WLAN_FEATURE_MARK_FIRST_WAKEUP_PACKET + hal_soc->ops->hal_get_first_wow_wakeup_packet = + hal_get_first_wow_wakeup_packet_kiwi; +#endif }; struct hal_hw_srng_config hw_srng_table_kiwi[] = { diff --git a/hal/wifi3.0/qca6290/hal_6290.c b/hal/wifi3.0/qca6290/hal_6290.c index 532cc2d9f3..3ee8063e4e 100644 --- a/hal/wifi3.0/qca6290/hal_6290.c +++ b/hal/wifi3.0/qca6290/hal_6290.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2016-2021 The Linux Foundation. All rights reserved. - * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. 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 @@ -1048,6 +1048,24 @@ void hal_compute_reo_remap_ix2_ix3_6290(uint32_t *ring, uint32_t num_rings, } } +#ifdef WLAN_FEATURE_MARK_FIRST_WAKEUP_PACKET +/** + * hal_get_first_wow_wakeup_packet_6290(): Function to get if the buffer + * is the first one that wakes up host from WoW. + * + * @buf: network buffer + * + * Dummy function for QCA6290 + * + * Returns: 1 to indicate it is first packet received that wakes up host from + * WoW. Otherwise 0 + */ +static inline uint8_t hal_get_first_wow_wakeup_packet_6290(uint8_t *buf) +{ + return 0; +} +#endif + static void hal_hw_txrx_ops_attach_6290(struct hal_soc *hal_soc) { /* init and setup */ @@ -1215,6 +1233,10 @@ static void hal_hw_txrx_ops_attach_6290(struct hal_soc *hal_soc) hal_compute_reo_remap_ix2_ix3_6290; hal_soc->ops->hal_setup_link_idle_list = hal_setup_link_idle_list_generic_li; +#ifdef WLAN_FEATURE_MARK_FIRST_WAKEUP_PACKET + hal_soc->ops->hal_get_first_wow_wakeup_packet = + hal_get_first_wow_wakeup_packet_6290; +#endif }; struct hal_hw_srng_config hw_srng_table_6290[] = { diff --git a/hal/wifi3.0/qca6390/hal_6390.c b/hal/wifi3.0/qca6390/hal_6390.c index da3f82b0f9..90a9261170 100644 --- a/hal/wifi3.0/qca6390/hal_6390.c +++ b/hal/wifi3.0/qca6390/hal_6390.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2016-2021 The Linux Foundation. All rights reserved. - * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. 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 @@ -1100,6 +1100,24 @@ void hal_compute_reo_remap_ix2_ix3_6390(uint32_t *ring, uint32_t num_rings, } } +#ifdef WLAN_FEATURE_MARK_FIRST_WAKEUP_PACKET +/** + * hal_get_first_wow_wakeup_packet_6390(): Function to get if the buffer + * is the first one that wakes up host from WoW. + * + * @buf: network buffer + * + * Dummy function for QCA6390 + * + * Returns: 1 to indicate it is first packet received that wakes up host from + * WoW. Otherwise 0 + */ +static inline uint8_t hal_get_first_wow_wakeup_packet_6390(uint8_t *buf) +{ + return 0; +} +#endif + static void hal_hw_txrx_ops_attach_qca6390(struct hal_soc *hal_soc) { /* init and setup */ @@ -1271,6 +1289,10 @@ static void hal_hw_txrx_ops_attach_qca6390(struct hal_soc *hal_soc) hal_compute_reo_remap_ix2_ix3_6390; hal_soc->ops->hal_setup_link_idle_list = hal_setup_link_idle_list_generic_li; +#ifdef WLAN_FEATURE_MARK_FIRST_WAKEUP_PACKET + hal_soc->ops->hal_get_first_wow_wakeup_packet = + hal_get_first_wow_wakeup_packet_6390; +#endif }; struct hal_hw_srng_config hw_srng_table_6390[] = { diff --git a/hal/wifi3.0/qca6490/hal_6490.c b/hal/wifi3.0/qca6490/hal_6490.c index 8d0e80bddd..8d1c79b5ae 100644 --- a/hal/wifi3.0/qca6490/hal_6490.c +++ b/hal/wifi3.0/qca6490/hal_6490.c @@ -1681,6 +1681,28 @@ void hal_compute_reo_remap_ix2_ix3_6490(uint32_t *ring, uint32_t num_rings, } } +#ifdef WLAN_FEATURE_MARK_FIRST_WAKEUP_PACKET +/** + * hal_get_first_wow_wakeup_packet_6490(): Function to retrieve + * rx_msdu_end_1_reserved_1a + * + * reserved_1a is used by target to tag the first packet that wakes up host from + * WoW + * + * @buf: Network buffer + * + * Returns: 1 to indicate it is first packet received that wakes up host from + * WoW. Otherwise 0 + */ +static uint8_t hal_get_first_wow_wakeup_packet_6490(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = hal_rx_get_pkt_tlvs(buf); + struct rx_msdu_end *msdu_end = &pkt_tlvs->msdu_end_tlv.rx_msdu_end; + + return HAL_RX_MSDU_END_RESERVED_1A_GET(msdu_end); +} +#endif + static void hal_hw_txrx_ops_attach_qca6490(struct hal_soc *hal_soc) { /* init and setup */ @@ -1871,6 +1893,10 @@ static void hal_hw_txrx_ops_attach_qca6490(struct hal_soc *hal_soc) hal_rx_msdu_get_reo_destination_indication_6490; hal_soc->ops->hal_setup_link_idle_list = hal_setup_link_idle_list_generic_li; +#ifdef WLAN_FEATURE_MARK_FIRST_WAKEUP_PACKET + hal_soc->ops->hal_get_first_wow_wakeup_packet = + hal_get_first_wow_wakeup_packet_6490; +#endif }; struct hal_hw_srng_config hw_srng_table_6490[] = { diff --git a/hal/wifi3.0/qca6490/hal_6490_rx.h b/hal/wifi3.0/qca6490/hal_6490_rx.h index 98daa4f191..76116cfe6d 100644 --- a/hal/wifi3.0/qca6490/hal_6490_rx.h +++ b/hal/wifi3.0/qca6490/hal_6490_rx.h @@ -1,6 +1,6 @@ /* * Copyright (c) 2019-2021 The Linux Foundation. All rights reserved. - * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. 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 @@ -424,6 +424,12 @@ RX_MSDU_DETAILS_2_RX_MSDU_DESC_INFO_DETAILS_RESERVED_0A_OFFSET)) RX_MSDU_END_18_CUMULATIVE_IP_LENGTH_MASK, \ RX_MSDU_END_18_CUMULATIVE_IP_LENGTH_LSB)) +#define HAL_RX_MSDU_END_RESERVED_1A_GET(_rx_msdu_end) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_msdu_end, \ + RX_MSDU_END_1_RESERVED_1A_OFFSET)), \ + RX_MSDU_END_1_RESERVED_1A_MASK, \ + RX_MSDU_END_1_RESERVED_1A_LSB)) + #if defined(QCA_WIFI_QCA6490) && defined(WLAN_CFR_ENABLE) && \ defined(WLAN_ENH_CFR_ENABLE) static inline diff --git a/hal/wifi3.0/qca6750/hal_6750.c b/hal/wifi3.0/qca6750/hal_6750.c index dff77b3e64..d5ed08c649 100644 --- a/hal/wifi3.0/qca6750/hal_6750.c +++ b/hal/wifi3.0/qca6750/hal_6750.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2020-2021 The Linux Foundation. All rights reserved. - * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. 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 @@ -1834,6 +1834,27 @@ void hal_compute_reo_remap_ix2_ix3_6750(uint32_t *ring, uint32_t num_rings, } } +#ifdef WLAN_FEATURE_MARK_FIRST_WAKEUP_PACKET +/** + * hal_get_first_wow_wakeup_packet_6750(): Function to retrieve + * rx_msdu_end_1_reserved_1a + * + * reserved_1a is used by target to tag the first packet that wakes up host from + * WoW + * + * @buf: Network buffer + * + * Dummy function for QCA6750 + * + * Returns: 1 to indicate it is first packet received that wakes up host from + * WoW. Otherwise 0 + */ +static inline uint8_t hal_get_first_wow_wakeup_packet_6750(uint8_t *buf) +{ + return 0; +} +#endif + static void hal_hw_txrx_ops_attach_qca6750(struct hal_soc *hal_soc) { /* init and setup */ @@ -2030,6 +2051,10 @@ static void hal_hw_txrx_ops_attach_qca6750(struct hal_soc *hal_soc) hal_rx_msdu_get_reo_destination_indication_6750; hal_soc->ops->hal_setup_link_idle_list = hal_setup_link_idle_list_generic_li; +#ifdef WLAN_FEATURE_MARK_FIRST_WAKEUP_PACKET + hal_soc->ops->hal_get_first_wow_wakeup_packet = + hal_get_first_wow_wakeup_packet_6750; +#endif }; struct hal_hw_srng_config hw_srng_table_6750[] = {