diff options
| author | Himanshu Agarwal <himanaga@codeaurora.org> | 2016-12-05 17:21:12 +0530 |
|---|---|---|
| committer | qcabuildsw <qcabuildsw@localhost> | 2016-12-09 13:22:33 -0800 |
| commit | 3ed01151ef6ca83ea5745baffeb214e21f2f46c3 (patch) | |
| tree | 553e24ff07f89c170bca0d6d11efe5793cbb670f /core | |
| parent | 73bc5c2c99d8f33c4fd1520eb80e6c92b9d9f7ab (diff) | |
Revert "Revert "qcacld-3.0: Dump Tx/Rx packets during connection""
This reverts Change-Id I2aec7253511d2ca7b08ca77d858a46f9c01d4e9d
Adding support for dumping 32 tx/rx packets during connection
by reverting above change as "exceeding skb buffer size and
leading to crash" issue is resolved with this change.
Change-Id: I951355776461706bb52eeee0527819377e7b7857
CRs-Fixed: 1097280
Diffstat (limited to 'core')
| -rw-r--r-- | core/dp/htt/htt_rx.c | 59 | ||||
| -rw-r--r-- | core/dp/htt/htt_types.h | 5 | ||||
| -rw-r--r-- | core/dp/ol/inc/ol_htt_api.h | 6 | ||||
| -rw-r--r-- | core/dp/ol/inc/ol_txrx_api.h | 6 | ||||
| -rw-r--r-- | core/dp/txrx/ol_rx.c | 46 | ||||
| -rw-r--r-- | core/dp/txrx/ol_tx_desc.c | 12 | ||||
| -rw-r--r-- | core/dp/txrx/ol_tx_send.c | 67 | ||||
| -rw-r--r-- | core/dp/txrx/ol_txrx.c | 3 | ||||
| -rw-r--r-- | core/dp/txrx/ol_txrx_types.h | 8 | ||||
| -rw-r--r-- | core/hdd/src/wlan_hdd_assoc.c | 6 | ||||
| -rw-r--r-- | core/hdd/src/wlan_hdd_power.c | 5 | ||||
| -rw-r--r-- | core/sme/inc/csr_api.h | 1 | ||||
| -rw-r--r-- | core/sme/inc/csr_internal.h | 1 | ||||
| -rw-r--r-- | core/sme/src/csr/csr_api_roam.c | 87 | ||||
| -rw-r--r-- | core/utils/logging/inc/wlan_logging_sock_svc.h | 3 | ||||
| -rw-r--r-- | core/utils/logging/src/wlan_logging_sock_svc.c | 286 | ||||
| -rw-r--r-- | core/wma/inc/wma.h | 10 | ||||
| -rw-r--r-- | core/wma/src/wma_data.c | 1 | ||||
| -rw-r--r-- | core/wma/src/wma_mgmt.c | 60 |
19 files changed, 649 insertions, 23 deletions
diff --git a/core/dp/htt/htt_rx.c b/core/dp/htt/htt_rx.c index 317009ce71ab..0dee6b693ffd 100644 --- a/core/dp/htt/htt_rx.c +++ b/core/dp/htt/htt_rx.c @@ -60,6 +60,7 @@ #include <asm/barrier.h> #include <wma_api.h> #endif +#include <pktlog_ac_fmt.h> #ifdef HTT_DEBUG_DATA #define HTT_PKT_DUMP(x) x @@ -1923,6 +1924,7 @@ htt_rx_amsdu_rx_in_order_pop_ll(htt_pdev_handle pdev, uint8_t offload_ind, frag_ind; uint8_t peer_id; struct htt_host_rx_desc_base *rx_desc; + enum rx_pkt_fate status = RX_PKT_FATE_SUCCESS; HTT_ASSERT1(htt_rx_in_order_ring_elems(pdev) != 0); @@ -2011,6 +2013,15 @@ htt_rx_amsdu_rx_in_order_pop_ll(htt_pdev_handle pdev, msdu_count--; + /* calling callback function for packet logging */ + if (pdev->rx_pkt_dump_cb) { + if (qdf_unlikely((*((u_int8_t *) + &rx_desc->fw_desc.u.val)) & + FW_RX_DESC_ANY_ERR_M)) + status = RX_PKT_FATE_FW_DROP_INVALID; + pdev->rx_pkt_dump_cb(msdu, peer_id, status); + } + if (qdf_unlikely((*((u_int8_t *) &rx_desc->fw_desc.u.val)) & FW_RX_DESC_ANY_ERR_M)) { uint8_t tid = @@ -3447,3 +3458,51 @@ int htt_rx_ipa_uc_detach(struct htt_pdev_t *pdev) return 0; } #endif /* IPA_OFFLOAD */ + +/** + * htt_register_rx_pkt_dump_callback() - registers callback to + * get rx pkt status and call callback to do rx packet dump + * + * @pdev: htt pdev handle + * @callback: callback to get rx pkt status and + * call callback to do rx packet dump + * + * This function is used to register the callback to get + * rx pkt status and call callback to do rx packet dump + * + * Return: None + * + */ +void htt_register_rx_pkt_dump_callback(struct htt_pdev_t *pdev, + tp_rx_pkt_dump_cb callback) +{ + if (!pdev) { + qdf_print("%s: htt pdev is NULL, rx packet status callback register unsuccessful\n", + __func__); + return; + } + pdev->rx_pkt_dump_cb = callback; +} + +/** + * htt_deregister_rx_pkt_dump_callback() - deregisters callback to + * get rx pkt status and call callback to do rx packet dump + * + * @pdev: htt pdev handle + * + * This function is used to deregister the callback to get + * rx pkt status and call callback to do rx packet dump + * + * Return: None + * + */ +void htt_deregister_rx_pkt_dump_callback(struct htt_pdev_t *pdev) +{ + if (!pdev) { + qdf_print("%s: htt pdev is NULL, rx packet status callback deregister unsuccessful\n", + __func__); + return; + } + pdev->rx_pkt_dump_cb = NULL; +} + diff --git a/core/dp/htt/htt_types.h b/core/dp/htt/htt_types.h index 0bd12e6a1ec1..cb4e885d5521 100644 --- a/core/dp/htt/htt_types.h +++ b/core/dp/htt/htt_types.h @@ -35,6 +35,7 @@ #include <qdf_atomic.h> /* qdf_atomic_inc */ #include <qdf_nbuf.h> /* qdf_nbuf_t */ #include <htc_api.h> /* HTC_PACKET */ +#include <ol_htt_api.h> #define DEBUG_DMA_DONE @@ -413,6 +414,10 @@ struct htt_pdev_t { qdf_spinlock_t rx_buff_list_lock; int rx_buff_index; #endif + + /* callback function for packetdump */ + tp_rx_pkt_dump_cb rx_pkt_dump_cb; + struct mon_channel mon_ch_info; }; diff --git a/core/dp/ol/inc/ol_htt_api.h b/core/dp/ol/inc/ol_htt_api.h index 21da2649125c..311de8896708 100644 --- a/core/dp/ol/inc/ol_htt_api.h +++ b/core/dp/ol/inc/ol_htt_api.h @@ -384,5 +384,11 @@ static inline void htt_clear_bundle_stats(struct htt_pdev_t *pdev) #endif void htt_mark_first_wakeup_packet(htt_pdev_handle pdev, uint8_t value); +typedef void (*tp_rx_pkt_dump_cb)(qdf_nbuf_t msdu, uint8_t peer_id, + uint8_t status); +void htt_register_rx_pkt_dump_callback(struct htt_pdev_t *pdev, + tp_rx_pkt_dump_cb ol_rx_pkt_dump_call); +void htt_deregister_rx_pkt_dump_callback(struct htt_pdev_t *pdev); +void ol_rx_pkt_dump_call(qdf_nbuf_t msdu, uint8_t peer_id, uint8_t status); #endif /* _OL_HTT_API__H_ */ diff --git a/core/dp/ol/inc/ol_txrx_api.h b/core/dp/ol/inc/ol_txrx_api.h index 7aeb40c21825..b0d56ee1df62 100644 --- a/core/dp/ol/inc/ol_txrx_api.h +++ b/core/dp/ol/inc/ol_txrx_api.h @@ -60,4 +60,10 @@ enum ol_sec_type { ol_sec_type_types }; +typedef void (*tp_ol_packetdump_cb)(qdf_nbuf_t netbuf, + uint8_t status, uint8_t vdev_id, uint8_t type); +void ol_register_packetdump_callback(tp_ol_packetdump_cb ol_tx_packetdump_cb, + tp_ol_packetdump_cb ol_rx_packetdump_cb); +void ol_deregister_packetdump_callback(void); + #endif /* _OL_TXRX_API__H_ */ diff --git a/core/dp/txrx/ol_rx.c b/core/dp/txrx/ol_rx.c index a9bc69129357..20f96cb504bd 100644 --- a/core/dp/txrx/ol_rx.c +++ b/core/dp/txrx/ol_rx.c @@ -59,6 +59,7 @@ #include <ol_vowext_dbg_defs.h> #include <wma.h> #include <cds_concurrency.h> +#include "pktlog_ac_fmt.h" #include <pld_common.h> @@ -1420,6 +1421,51 @@ ol_rx_in_order_indication_handler(ol_txrx_pdev_handle pdev, peer->rx_opt_proc(vdev, peer, tid, head_msdu); } +/** + * ol_rx_pkt_dump_call() - updates status and + * calls packetdump callback to log rx packet + * + * @msdu: rx packet + * @peer_id: peer id + * @status: status of rx packet + * + * This function is used to update the status of rx packet + * and then calls packetdump callback to log that packet. + * + * Return: None + * + */ +void ol_rx_pkt_dump_call( + qdf_nbuf_t msdu, + uint8_t peer_id, + uint8_t status) +{ + v_CONTEXT_t vos_context; + ol_txrx_pdev_handle pdev; + struct ol_txrx_peer_t *peer = NULL; + + vos_context = cds_get_global_context(); + pdev = cds_get_context(QDF_MODULE_ID_TXRX); + + if (!pdev) { + TXRX_PRINT(TXRX_PRINT_LEVEL_ERR, + "%s: pdev is NULL", __func__); + return; + } + + if (pdev->ol_rx_packetdump_cb) { + peer = ol_txrx_peer_find_by_id(pdev, peer_id); + if (!peer) { + TXRX_PRINT(TXRX_PRINT_LEVEL_ERR, + "%s: peer with peer id %d is NULL", __func__, + peer_id); + return; + } + pdev->ol_rx_packetdump_cb(msdu, status, peer->vdev->vdev_id, + RX_DATA_PKT); + } +} + /* the msdu_list passed here must be NULL terminated */ void ol_rx_in_order_deliver(struct ol_txrx_vdev_t *vdev, diff --git a/core/dp/txrx/ol_tx_desc.c b/core/dp/txrx/ol_tx_desc.c index 3f5feef36e36..11490c035e08 100644 --- a/core/dp/txrx/ol_tx_desc.c +++ b/core/dp/txrx/ol_tx_desc.c @@ -92,8 +92,6 @@ static inline void ol_tx_desc_reset_timestamp(struct ol_tx_desc_t *tx_desc) } #endif -#ifdef CONFIG_HL_SUPPORT - /** * ol_tx_desc_vdev_update() - vedv assign. * @tx_desc: tx descriptor pointer @@ -107,15 +105,6 @@ ol_tx_desc_vdev_update(struct ol_tx_desc_t *tx_desc, { tx_desc->vdev = vdev; } -#else - -static inline void -ol_tx_desc_vdev_update(struct ol_tx_desc_t *tx_desc, - struct ol_txrx_vdev_t *vdev) -{ - return; -} -#endif #ifdef CONFIG_PER_VDEV_TX_DESC_POOL @@ -223,6 +212,7 @@ struct ol_tx_desc_t *ol_tx_desc_alloc(struct ol_txrx_pdev_t *pdev, } ol_tx_desc_sanity_checks(pdev, tx_desc); ol_tx_desc_compute_delay(tx_desc); + ol_tx_desc_vdev_update(tx_desc, vdev); qdf_atomic_inc(&tx_desc->ref_cnt); } else { pool->pkt_drop_no_desc++; diff --git a/core/dp/txrx/ol_tx_send.c b/core/dp/txrx/ol_tx_send.c index 0a49d6980723..5da7b534cb05 100644 --- a/core/dp/txrx/ol_tx_send.c +++ b/core/dp/txrx/ol_tx_send.c @@ -61,7 +61,7 @@ #endif #include <ol_tx_queue.h> #include <ol_txrx.h> - +#include <pktlog_ac_fmt.h> #ifdef TX_CREDIT_RECLAIM_SUPPORT @@ -553,6 +553,13 @@ ol_tx_completion_handler(ol_txrx_pdev_handle pdev, tx_desc->status = status; netbuf = tx_desc->netbuf; QDF_NBUF_UPDATE_TX_PKT_COUNT(netbuf, QDF_NBUF_TX_PKT_FREE); + + if (tx_desc->pkt_type != OL_TX_FRM_TSO) { + if (pdev->ol_tx_packetdump_cb) + pdev->ol_tx_packetdump_cb(netbuf, status, + tx_desc->vdev->vdev_id, TX_DATA_PKT); + } + DPTRACE(qdf_dp_trace_ptr(netbuf, QDF_DP_TRACE_FREE_PACKET_PTR_RECORD, qdf_nbuf_data_addr(netbuf), @@ -775,6 +782,10 @@ ol_tx_single_completion_handler(ol_txrx_pdev_handle pdev, /* Do one shot statistics */ TXRX_STATS_UPDATE_TX_STATS(pdev, status, 1, qdf_nbuf_len(netbuf)); + if (pdev->ol_tx_packetdump_cb) + pdev->ol_tx_packetdump_cb(netbuf, status, + tx_desc->vdev->vdev_id, TX_MGMT_PKT); + if (OL_TX_DESC_NO_REFS(tx_desc)) { ol_tx_desc_frame_free_nonstd(pdev, tx_desc, status != htt_tx_status_ok); @@ -1184,3 +1195,57 @@ ol_tx_delay_compute(struct ol_txrx_pdev_t *pdev, } #endif /* QCA_COMPUTE_TX_DELAY */ + +/** + * ol_register_packetdump_callback() - registers + * tx data packet, tx mgmt. packet and rx data packet + * dump callback handler. + * + * @ol_tx_packetdump_cb: tx packetdump cb + * @ol_rx_packetdump_cb: rx packetdump cb + * + * This function is used to register tx data pkt, tx mgmt. + * pkt and rx data pkt dump callback + * + * Return: None + * + */ +void ol_register_packetdump_callback(tp_ol_packetdump_cb ol_tx_packetdump_cb, + tp_ol_packetdump_cb ol_rx_packetdump_cb) +{ + ol_txrx_pdev_handle pdev = cds_get_context(QDF_MODULE_ID_TXRX); + + if (!pdev) { + TXRX_PRINT(TXRX_PRINT_LEVEL_ERR, + "%s: pdev is NULL", __func__); + return; + } + + pdev->ol_tx_packetdump_cb = ol_tx_packetdump_cb; + pdev->ol_rx_packetdump_cb = ol_rx_packetdump_cb; +} + +/** + * ol_deregister_packetdump_callback() - deregidters + * tx data packet, tx mgmt. packet and rx data packet + * dump callback handler + * + * This function is used to deregidter tx data pkt., + * tx mgmt. pkt and rx data pkt. dump callback + * + * Return: None + * + */ +void ol_deregister_packetdump_callback(void) +{ + ol_txrx_pdev_handle pdev = cds_get_context(QDF_MODULE_ID_TXRX); + + if (!pdev) { + TXRX_PRINT(TXRX_PRINT_LEVEL_ERR, + "%s: pdev is NULL", __func__); + return; + } + + pdev->ol_tx_packetdump_cb = NULL; + pdev->ol_rx_packetdump_cb = NULL; +} diff --git a/core/dp/txrx/ol_txrx.c b/core/dp/txrx/ol_txrx.c index 4aa51031b6d7..5ada5f9cadba 100644 --- a/core/dp/txrx/ol_txrx.c +++ b/core/dp/txrx/ol_txrx.c @@ -1017,6 +1017,8 @@ ol_txrx_pdev_attach(ol_pdev_handle ctrl_pdev, if (!pdev->htt_pdev) goto fail3; + htt_register_rx_pkt_dump_callback(pdev->htt_pdev, + ol_rx_pkt_dump_call); return pdev; fail3: @@ -1660,6 +1662,7 @@ void ol_txrx_pdev_detach(ol_txrx_pdev_handle pdev, int force) htt_tx_desc_free(pdev->htt_pdev, htt_tx_desc); } + htt_deregister_rx_pkt_dump_callback(pdev->htt_pdev); ol_tx_deregister_flow_control(pdev); /* Stop the communication between HTT and target at first */ htt_detach_target(pdev->htt_pdev); diff --git a/core/dp/txrx/ol_txrx_types.h b/core/dp/txrx/ol_txrx_types.h index b02c7a2ad2c4..4032fbfdb2be 100644 --- a/core/dp/txrx/ol_txrx_types.h +++ b/core/dp/txrx/ol_txrx_types.h @@ -188,9 +188,9 @@ struct ol_tx_desc_t { * This field is filled in with the ol_tx_frm_type enum. */ uint8_t pkt_type; -#if defined(CONFIG_HL_SUPPORT) + struct ol_txrx_vdev_t *vdev; -#endif + void *txq; #ifdef QCA_SUPPORT_SW_TXRX_ENCAP @@ -668,6 +668,10 @@ struct ol_txrx_pdev_t { } callbacks[OL_TXRX_MGMT_NUM_TYPES]; } tx_mgmt; + /* packetdump callback functions */ + tp_ol_packetdump_cb ol_tx_packetdump_cb; + tp_ol_packetdump_cb ol_rx_packetdump_cb; + struct { uint16_t pool_size; uint16_t num_free; diff --git a/core/hdd/src/wlan_hdd_assoc.c b/core/hdd/src/wlan_hdd_assoc.c index 518792d9f28a..62e5c46dd623 100644 --- a/core/hdd/src/wlan_hdd_assoc.c +++ b/core/hdd/src/wlan_hdd_assoc.c @@ -63,6 +63,7 @@ #include "cdp_txrx_flow_ctrl_legacy.h" #include "cdp_txrx_peer_ops.h" #include "wlan_hdd_napi.h" +#include <wlan_logging_sock_svc.h> /* These are needed to recognize WPA and RSN suite types */ #define HDD_WPA_OUI_SIZE 4 @@ -1537,6 +1538,8 @@ static QDF_STATUS hdd_dis_connect_handler(hdd_adapter_t *pAdapter, hdd_clear_roam_profile_ie(pAdapter); hdd_wmm_init(pAdapter); + hdd_info("Invoking packetdump deregistration API"); + wlan_deregister_txrx_packetdump(); /* indicate 'disconnect' status to wpa_supplicant... */ hdd_send_association_event(dev, pRoamInfo); @@ -2803,6 +2806,9 @@ static QDF_STATUS hdd_association_completion_handler(hdd_adapter_t *pAdapter, MAC_ADDR_ARRAY(pWextState->req_bssId.bytes), roamResult, roamStatus); + hdd_err("Invoking packetdump deregistration API"); + wlan_deregister_txrx_packetdump(); + /* inform association failure event to nl80211 */ if (eCSR_ROAM_RESULT_ASSOC_FAIL_CON_CHANNEL == roamResult) { diff --git a/core/hdd/src/wlan_hdd_power.c b/core/hdd/src/wlan_hdd_power.c index 10136f01b4d7..b63575073712 100644 --- a/core/hdd/src/wlan_hdd_power.c +++ b/core/hdd/src/wlan_hdd_power.c @@ -76,6 +76,7 @@ #include "cdp_txrx_flow_ctrl_v2.h" #include "pld_common.h" #include "wlan_hdd_driver_ops.h" +#include <wlan_logging_sock_svc.h> /* Preprocessor definitions and constants */ #define HDD_SSR_BRING_UP_TIME 30000 @@ -1460,6 +1461,10 @@ QDF_STATUS hdd_wlan_shutdown(void) } cds_clear_concurrent_session_count(); + + hdd_info("Invoking packetdump deregistration API"); + wlan_deregister_txrx_packetdump(); + hdd_cleanup_scan_queue(pHddCtx); hdd_ipa_uc_ssr_deinit(); hdd_reset_all_adapters(pHddCtx); diff --git a/core/sme/inc/csr_api.h b/core/sme/inc/csr_api.h index 105dc689b4fb..818f425cad00 100644 --- a/core/sme/inc/csr_api.h +++ b/core/sme/inc/csr_api.h @@ -1758,5 +1758,6 @@ static inline void csr_roam_fill_tdls_info(tpAniSirGlobal mac_ctx, tCsrRoamInfo tpSirSmeJoinRsp join_rsp) {} #endif +void csr_packetdump_timer_stop(void); #endif diff --git a/core/sme/inc/csr_internal.h b/core/sme/inc/csr_internal.h index 5caf108b46ab..ffb844a2c34f 100644 --- a/core/sme/inc/csr_internal.h +++ b/core/sme/inc/csr_internal.h @@ -1049,6 +1049,7 @@ typedef struct tagCsrRoamStruct { uint32_t deauthRspStatus; uint8_t *pReassocResp; /* reassociation response from new AP */ uint16_t reassocRespLen; /* length of reassociation response */ + qdf_mc_timer_t packetdump_timer; } tCsrRoamStruct; #define GET_NEXT_ROAM_ID(pRoamStruct) (((pRoamStruct)->nextRoamId + 1 == 0) ? \ diff --git a/core/sme/src/csr/csr_api_roam.c b/core/sme/src/csr/csr_api_roam.c index c268abbf5c79..c4a634148e57 100644 --- a/core/sme/src/csr/csr_api_roam.c +++ b/core/sme/src/csr/csr_api_roam.c @@ -57,6 +57,7 @@ #include "cds_concurrency.h" #include "sme_nan_datapath.h" #include "pld_common.h" +#include <wlan_logging_sock_svc.h> #define MAX_PWR_FCC_CHAN_12 8 #define MAX_PWR_FCC_CHAN_13 2 @@ -85,6 +86,10 @@ #define MAX_CB_VALUE_IN_INI (2) #define MAX_SOCIAL_CHANNELS 3 + +/* packet dump timer duration of 60 secs */ +#define PKT_DUMP_TIMER_DURATION 60 + /* Choose the largest possible value that can be accomodates in 8 bit signed */ /* variable. */ #define SNR_HACK_BMPS (127) @@ -956,6 +961,58 @@ void csr_set_global_cfgs(tpAniSirGlobal pMac) csr_set_default_dot11_mode(pMac); } +/** + * csr_packetdump_timer_handler() - packet dump timer + * handler + * @pv: user data + * + * This function is used to handle packet dump timer + * + * Return: None + * + */ +static void csr_packetdump_timer_handler(void *pv) +{ + QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_INFO, + "%s Invoking packetdump deregistration API", __func__); + wlan_deregister_txrx_packetdump(); +} + +/** + * csr_packetdump_timer_stop() - stops packet dump timer + * + * This function is used to stop packet dump timer + * + * Return: None + * + */ +void csr_packetdump_timer_stop(void) +{ + QDF_STATUS status; + tHalHandle hal; + tpAniSirGlobal mac; + v_CONTEXT_t vos_ctx_ptr; + + /* get the global voss context */ + vos_ctx_ptr = cds_get_global_context(); + if (vos_ctx_ptr == NULL) { + QDF_ASSERT(0); + return; + } + + hal = cds_get_context(QDF_MODULE_ID_SME); + if (hal == NULL) { + QDF_ASSERT(0); + return; + } + + mac = PMAC_STRUCT(hal); + status = qdf_mc_timer_stop(&mac->roam.packetdump_timer); + if (!QDF_IS_STATUS_SUCCESS(status)) { + sms_log(mac, LOGE, FL("cannot stop packetdump timer")); + } +} + QDF_STATUS csr_roam_open(tpAniSirGlobal pMac) { QDF_STATUS status = QDF_STATUS_SUCCESS; @@ -982,6 +1039,14 @@ QDF_STATUS csr_roam_open(tpAniSirGlobal pMac) ("cannot allocate memory for WaitForKey time out timer")); break; } + status = qdf_mc_timer_init(&pMac->roam.packetdump_timer, + QDF_TIMER_TYPE_SW, csr_packetdump_timer_handler, + pMac); + if (!QDF_IS_STATUS_SUCCESS(status)) { + sms_log(pMac, LOGE, + FL("cannot allocate memory for packetdump timer")); + break; + } status = qdf_mc_timer_init(&pMac->roam.tlStatsReqInfo.hTlStatsTimer, QDF_TIMER_TYPE_SW, @@ -1006,6 +1071,8 @@ QDF_STATUS csr_roam_close(tpAniSirGlobal pMac) qdf_mc_timer_destroy(&pMac->roam.hTimerWaitForKey); qdf_mc_timer_stop(&pMac->roam.tlStatsReqInfo.hTlStatsTimer); qdf_mc_timer_destroy(&pMac->roam.tlStatsReqInfo.hTlStatsTimer); + qdf_mc_timer_stop(&pMac->roam.packetdump_timer); + qdf_mc_timer_destroy(&pMac->roam.packetdump_timer); return QDF_STATUS_SUCCESS; } @@ -13716,6 +13783,7 @@ QDF_STATUS csr_send_join_req_msg(tpAniSirGlobal pMac, uint32_t sessionId, uint8_t ese_config = 0; tpCsrNeighborRoamControlInfo neigh_roam_info; uint32_t value = 0, value1 = 0; + QDF_STATUS packetdump_timer_status; if (!pSession) { sms_log(pMac, LOGE, FL(" session %d not found "), sessionId); @@ -14369,6 +14437,25 @@ QDF_STATUS csr_send_join_req_msg(tpAniSirGlobal pMac, uint32_t sessionId, csr_join_req = NULL; break; } else { + if (pProfile->csrPersona == QDF_STA_MODE) { + sms_log(pMac, LOG1, + FL(" Invoking packetdump register API")); + wlan_register_txrx_packetdump(); + packetdump_timer_status = + qdf_mc_timer_start( + &pMac->roam.packetdump_timer, + (PKT_DUMP_TIMER_DURATION * + QDF_MC_TIMER_TO_SEC_UNIT)/ + QDF_MC_TIMER_TO_MS_UNIT); + if (!QDF_IS_STATUS_SUCCESS( + packetdump_timer_status)) { + sms_log(pMac, LOGE, + FL("cannot start packetdump timer")); + sms_log(pMac, LOGE, + FL("packetdump_timer_status: %d"), + packetdump_timer_status); + } + } #ifndef WLAN_MDM_CODE_REDUCTION_OPT if (eWNI_SME_JOIN_REQ == messageType) { /* Notify QoS module that join happening */ diff --git a/core/utils/logging/inc/wlan_logging_sock_svc.h b/core/utils/logging/inc/wlan_logging_sock_svc.h index 1edb42cea675..af85ab694352 100644 --- a/core/utils/logging/inc/wlan_logging_sock_svc.h +++ b/core/utils/logging/inc/wlan_logging_sock_svc.h @@ -80,4 +80,7 @@ static inline void wlan_report_log_completion(uint32_t is_fatal, void wlan_pkt_stats_to_logger_thread(void *pl_hdr, void *pkt_dump, void *data); +void wlan_deregister_txrx_packetdump(void); +void wlan_register_txrx_packetdump(void); + #endif /* WLAN_LOGGING_SOCK_SVC_H */ diff --git a/core/utils/logging/src/wlan_logging_sock_svc.c b/core/utils/logging/src/wlan_logging_sock_svc.c index 3661674befb1..ab8950cd9f69 100644 --- a/core/utils/logging/src/wlan_logging_sock_svc.c +++ b/core/utils/logging/src/wlan_logging_sock_svc.c @@ -37,10 +37,39 @@ #include <kthread.h> #include <qdf_time.h> #include <wlan_ptt_sock_svc.h> -#include "pktlog_ac.h" #include <host_diag_core_event.h> #include "cds_utils.h" #include "host_diag_core_log.h" +#include "wma.h" +#include "ol_txrx_api.h" +#include "csr_api.h" +#include "wlan_hdd_main.h" +#include "pktlog_ac.h" + +#define MAX_NUM_PKT_LOG 32 + +/** + * struct tx_status - tx status + * @tx_status_ok: successfully sent + acked + * @tx_status_discard: discard - not sent (congestion control) + * @tx_status_no_ack: no_ack - sent, but no ack + * @tx_status_download_fail: download_fail - + * the host could not deliver the tx frame to the target + * @tx_status_peer_del: peer_del - tx completion for + * alreay deleted peer used for HL case + * + * This enum has tx status types + */ +enum tx_status { + tx_status_ok, + tx_status_discard, + tx_status_no_ack, + tx_status_download_fail, + tx_status_peer_del, +}; + +static uint8_t gtx_count; +static uint8_t grx_count; #define LOGGING_TRACE(level, args ...) \ QDF_TRACE(QDF_MODULE_ID_HDD, level, ## args) @@ -1200,12 +1229,7 @@ void wlan_pkt_stats_to_logger_thread(void *pl_hdr, void *pkt_dump, void *data) } pkt_stats_dump = (struct packet_dump *)pkt_dump; - if (pkt_stats_dump) - total_stats_len = sizeof(struct ath_pktlog_hdr) + - pktlog_hdr->size + - sizeof(struct packet_dump); - else - total_stats_len = sizeof(struct ath_pktlog_hdr) + + total_stats_len = sizeof(struct ath_pktlog_hdr) + pktlog_hdr->size; spin_lock_irqsave(&gwlan_logging.pkt_stats_lock, flags); @@ -1230,16 +1254,24 @@ void wlan_pkt_stats_to_logger_thread(void *pl_hdr, void *pkt_dump, void *data) pktlog_hdr, sizeof(struct ath_pktlog_hdr)); - if (pkt_stats_dump) + if (pkt_stats_dump) { qdf_mem_copy(skb_put(ptr, sizeof(struct packet_dump)), pkt_stats_dump, sizeof(struct packet_dump)); + pktlog_hdr->size -= sizeof(struct packet_dump); + } - qdf_mem_copy(skb_put(ptr, + if (data) + qdf_mem_copy(skb_put(ptr, pktlog_hdr->size), data, pktlog_hdr->size); + if (pkt_stats_dump->type == STOP_MONITOR) { + wake_up_thread = true; + wlan_get_pkt_stats_free_node(); + } + spin_unlock_irqrestore(&gwlan_logging.pkt_stats_lock, flags); /* Wakeup logger thread */ @@ -1249,4 +1281,240 @@ void wlan_pkt_stats_to_logger_thread(void *pl_hdr, void *pkt_dump, void *data) } } +/** + * driver_hal_status_map() - maps driver to hal + * status + * @status: status to be mapped + * + * This function is used to map driver to hal status + * + * Return: None + * + */ +static void driver_hal_status_map(uint8_t *status) +{ + switch (*status) { + case tx_status_ok: + *status = TX_PKT_FATE_ACKED; + break; + case tx_status_discard: + *status = TX_PKT_FATE_DRV_DROP_OTHER; + break; + case tx_status_no_ack: + *status = TX_PKT_FATE_SENT; + break; + case tx_status_download_fail: + *status = TX_PKT_FATE_FW_QUEUED; + break; + default: + *status = TX_PKT_FATE_DRV_DROP_OTHER; + break; + } +} + + +/* + * send_packetdump() - send packet dump + * @netbuf: netbuf + * @status: status of tx packet + * @vdev_id: virtual device id + * @type: type of packet + * + * This function is used to send packet dump to HAL layer + * using wlan_pkt_stats_to_logger_thread + * + * Return: None + * + */ +static void send_packetdump(qdf_nbuf_t netbuf, uint8_t status, + uint8_t vdev_id, uint8_t type) +{ + struct ath_pktlog_hdr pktlog_hdr = {0}; + struct packet_dump pd_hdr = {0}; + hdd_context_t *hdd_ctx; + hdd_adapter_t *adapter; + v_CONTEXT_t vos_ctx; + + vos_ctx = cds_get_global_context(); + if (!vos_ctx) + return; + + hdd_ctx = (hdd_context_t *)cds_get_context(QDF_MODULE_ID_HDD); + if (!hdd_ctx) + return; + + adapter = hdd_get_adapter_by_vdev(hdd_ctx, vdev_id); + if (!adapter) + return; + + /* Send packet dump only for STA interface */ + if (adapter->device_mode != QDF_STA_MODE) + return; + + pktlog_hdr.log_type = PKTLOG_TYPE_PKT_DUMP; + pktlog_hdr.size = sizeof(pd_hdr) + netbuf->len; + + pd_hdr.status = status; + pd_hdr.type = type; + pd_hdr.driver_ts = qdf_get_monotonic_boottime(); + + if ((type == TX_MGMT_PKT) || (type == TX_DATA_PKT)) + gtx_count++; + else if ((type == RX_MGMT_PKT) || (type == RX_DATA_PKT)) + grx_count++; + + wlan_pkt_stats_to_logger_thread(&pktlog_hdr, &pd_hdr, netbuf->data); +} + + +/* + * send_packetdump_monitor() - sends start/stop packet dump indication + * @type: type of packet + * + * This function is used to indicate HAL layer to start/stop monitoring + * of packets + * + * Return: None + * + */ +static void send_packetdump_monitor(uint8_t type) +{ + struct ath_pktlog_hdr pktlog_hdr = {0}; + struct packet_dump pd_hdr = {0}; + + pktlog_hdr.log_type = PKTLOG_TYPE_PKT_DUMP; + pktlog_hdr.size = sizeof(pd_hdr); + + pd_hdr.type = type; + + LOGGING_TRACE(QDF_TRACE_LEVEL_INFO, + "fate Tx-Rx %s: type: %d", __func__, type); + + wlan_pkt_stats_to_logger_thread(&pktlog_hdr, &pd_hdr, NULL); +} + +/** + * wlan_deregister_txrx_packetdump() - tx/rx packet dump + * deregistration + * + * This function is used to deregister tx/rx packet dump callbacks + * with ol, pe and htt layers + * + * Return: None + * + */ +void wlan_deregister_txrx_packetdump(void) +{ + if (gtx_count || grx_count) { + ol_deregister_packetdump_callback(); + wma_deregister_packetdump_callback(); + send_packetdump_monitor(STOP_MONITOR); + csr_packetdump_timer_stop(); + + gtx_count = 0; + grx_count = 0; + } else + LOGGING_TRACE(QDF_TRACE_LEVEL_INFO, + "%s: deregistered packetdump already", __func__); +} + +/* + * check_txrx_packetdump_count() - function to check + * tx/rx packet dump global counts + * + * This function is used to check global counts of tx/rx + * packet dump functionality. + * + * Return: 1 if either gtx_count or grx_count reached 32 + * 0 otherwise + * + */ +static bool check_txrx_packetdump_count(void) +{ + if (gtx_count == MAX_NUM_PKT_LOG || + grx_count == MAX_NUM_PKT_LOG) { + LOGGING_TRACE(QDF_TRACE_LEVEL_INFO, + "%s gtx_count: %d grx_count: %d deregister packetdump", + __func__, gtx_count, grx_count); + wlan_deregister_txrx_packetdump(); + return 1; + } + return 0; +} + +/* + * tx_packetdump_cb() - tx packet dump callback + * @netbuf: netbuf + * @status: status of tx packet + * @vdev_id: virtual device id + * @type: packet type + * + * This function is used to send tx packet dump to HAL layer + * and deregister packet dump callbacks + * + * Return: None + * + */ +static void tx_packetdump_cb(qdf_nbuf_t netbuf, uint8_t status, + uint8_t vdev_id, uint8_t type) +{ + bool temp; + + temp = check_txrx_packetdump_count(); + if (temp) + return; + + driver_hal_status_map(&status); + send_packetdump(netbuf, status, vdev_id, type); +} + + +/* + * rx_packetdump_cb() - rx packet dump callback + * @netbuf: netbuf + * @status: status of rx packet + * @vdev_id: virtual device id + * @type: packet type + * + * This function is used to send rx packet dump to HAL layer + * and deregister packet dump callbacks + * + * Return: None + * + */ +static void rx_packetdump_cb(qdf_nbuf_t netbuf, uint8_t status, + uint8_t vdev_id, uint8_t type) +{ + bool temp; + + temp = check_txrx_packetdump_count(); + if (temp) + return; + + send_packetdump(netbuf, status, vdev_id, type); +} + + +/** + * wlan_register_txrx_packetdump() - tx/rx packet dump + * registration + * + * This function is used to register tx/rx packet dump callbacks + * with ol, pe and htt layers + * + * Return: None + * + */ +void wlan_register_txrx_packetdump(void) +{ + ol_register_packetdump_callback(tx_packetdump_cb, + rx_packetdump_cb); + wma_register_packetdump_callback(tx_packetdump_cb, + rx_packetdump_cb); + send_packetdump_monitor(START_MONITOR); + + gtx_count = 0; + grx_count = 0; +} + #endif /* WLAN_LOGGING_SOCK_SVC_ENABLE */ diff --git a/core/wma/inc/wma.h b/core/wma/inc/wma.h index 2c2542aafaa3..9963706e2697 100644 --- a/core/wma/inc/wma.h +++ b/core/wma/inc/wma.h @@ -511,6 +511,9 @@ typedef void (*encrypt_decrypt_cb)(struct sir_encrypt_decrypt_rsp_params *encrypt_decrypt_rsp_params); +typedef void (*tp_wma_packetdump_cb)(qdf_nbuf_t netbuf, + uint8_t status, uint8_t vdev_id, uint8_t type); + /** * enum t_wma_drv_type - wma driver type * @WMA_DRIVER_TYPE_PRODUCTION: production driver type @@ -1190,6 +1193,7 @@ struct wmi_desc_t { pWMAAckFnTxComp ota_post_proc_cb; qdf_nbuf_t nbuf; uint32_t desc_id; + uint8_t vdev_id; }; /** @@ -1605,6 +1609,8 @@ typedef struct { cds_msg_t *msg); bool fw_timeout_crash; bool sub_20_support; + tp_wma_packetdump_cb wma_mgmt_tx_packetdump_cb; + tp_wma_packetdump_cb wma_mgmt_rx_packetdump_cb; tSirLLStatsResults *link_stats_results; } t_wma_handle, *tp_wma_handle; @@ -2327,6 +2333,10 @@ QDF_STATUS wma_start_oem_data_req(tp_wma_handle wma_handle, QDF_STATUS wma_enable_disable_caevent_ind(tp_wma_handle wma_handle, uint8_t val); +void wma_register_packetdump_callback( + tp_wma_packetdump_cb wma_mgmt_tx_packetdump_cb, + tp_wma_packetdump_cb wma_mgmt_rx_packetdump_cb); +void wma_deregister_packetdump_callback(void); void wma_update_sta_inactivity_timeout(tp_wma_handle wma, struct sme_sta_inactivity_timeout *sta_inactivity_timer); diff --git a/core/wma/src/wma_data.c b/core/wma/src/wma_data.c index 0b2f12ed87d5..9ff8c041e268 100644 --- a/core/wma/src/wma_data.c +++ b/core/wma/src/wma_data.c @@ -2842,6 +2842,7 @@ QDF_STATUS wma_tx_packet(void *wma_context, void *tx_frame, uint16_t frmLen, status = QDF_STATUS_E_FAILURE; } else { mgmt_param.desc_id = wmi_desc->desc_id; + wmi_desc->vdev_id = vdev_id; status = wmi_mgmt_unified_cmd_send( wma_handle->wmi_handle, &mgmt_param); diff --git a/core/wma/src/wma_mgmt.c b/core/wma/src/wma_mgmt.c index 2931d5280632..5d2c6f2f2add 100644 --- a/core/wma/src/wma_mgmt.c +++ b/core/wma/src/wma_mgmt.c @@ -2502,6 +2502,11 @@ static int wma_process_mgmt_tx_completion(tp_wma_handle wma_handle, if (wmi_desc->nbuf) qdf_nbuf_unmap_single(pdev->osdev, wmi_desc->nbuf, QDF_DMA_TO_DEVICE); + + if (wma_handle->wma_mgmt_tx_packetdump_cb) + wma_handle->wma_mgmt_tx_packetdump_cb(wmi_desc->nbuf, + QDF_STATUS_SUCCESS, wmi_desc->vdev_id, TX_MGMT_PKT); + if (wmi_desc->tx_cmpl_cb) wmi_desc->tx_cmpl_cb(wma_handle->mac_context, wmi_desc->nbuf, 1); @@ -3304,6 +3309,13 @@ static int wma_mgmt_rx_process(void *handle, uint8_t *data, return -EINVAL; } + if ((mgt_type == IEEE80211_FC0_TYPE_MGT && + mgt_subtype != IEEE80211_FC0_SUBTYPE_BEACON) && + wma_handle->wma_mgmt_rx_packetdump_cb) + wma_handle->wma_mgmt_rx_packetdump_cb(rx_pkt->pkt_buf, + QDF_STATUS_SUCCESS, rx_pkt->pkt_meta.sessionId, + RX_MGMT_PKT); + wma_handle->mgmt_rx(wma_handle, rx_pkt); return 0; } @@ -3401,3 +3413,51 @@ QDF_STATUS wma_register_mgmt_frm_client( return QDF_STATUS_SUCCESS; } + +/** + * wma_register_packetdump_callback() - stores tx and rx mgmt packet dump + * callback handler + * @wma_mgmt_tx_packetdump_cb: tx mgmt packetdump cb + * @wma_mgmt_rx_packetdump_cb: rx mgmt packetdump cb + * + * This function is used to store tx and rx mgmt. packet dump callback + * + * Return: None + * + */ +void wma_register_packetdump_callback( + tp_wma_packetdump_cb wma_mgmt_tx_packetdump_cb, + tp_wma_packetdump_cb wma_mgmt_rx_packetdump_cb) +{ + tp_wma_handle wma_handle = cds_get_context(QDF_MODULE_ID_WMA); + + if (!wma_handle) { + WMA_LOGE("wma handle is NULL"); + return; + } + + wma_handle->wma_mgmt_tx_packetdump_cb = wma_mgmt_tx_packetdump_cb; + wma_handle->wma_mgmt_rx_packetdump_cb = wma_mgmt_rx_packetdump_cb; +} + +/** + * wma_deregister_packetdump_callback() - removes tx and rx mgmt packet dump + * callback handler + * + * This function is used to remove tx and rx mgmt. packet dump callback + * + * Return: None + * + */ +void wma_deregister_packetdump_callback(void) +{ + tp_wma_handle wma_handle = cds_get_context(QDF_MODULE_ID_WMA); + + if (!wma_handle) { + WMA_LOGE("wma handle is NULL"); + return; + } + + wma_handle->wma_mgmt_tx_packetdump_cb = NULL; + wma_handle->wma_mgmt_rx_packetdump_cb = NULL; +} |
