diff --git a/dp/wifi3.0/dp_htt.c b/dp/wifi3.0/dp_htt.c index 97a8cd47cc..0ee09d90a3 100644 --- a/dp/wifi3.0/dp_htt.c +++ b/dp/wifi3.0/dp_htt.c @@ -24,10 +24,12 @@ #include "dp_internal.h" #include "dp_rx_mon.h" #include "htt_stats.h" +#include "qdf_mem.h" /* qdf_mem_malloc,free */ #define HTT_TLV_HDR_LEN HTT_T2H_EXT_STATS_CONF_TLV_HDR_SIZE #define HTT_HTC_PKT_POOL_INIT_SIZE 64 +#define HTT_T2H_MAX_MSG_SIZE 2048 #define HTT_MSG_BUF_SIZE(msg_bytes) \ ((msg_bytes) + HTC_HEADER_LEN + HTC_HDR_ALIGNMENT_PADDING) @@ -1149,18 +1151,27 @@ static void dp_htt_t2h_msg_handler(void *context, HTC_PACKET *pkt) msg_word, msg_word + 2); break; } -#ifdef notyet +#if defined(CONFIG_WIN) && WDI_EVENT_ENABLE #ifndef REMOVE_PKT_LOG case HTT_T2H_MSG_TYPE_PKTLOG: { u_int32_t *pl_hdr; pl_hdr = (msg_word + 1); - wdi_event_handler(WDI_EVENT_OFFLOAD_ALL, soc->dp_soc, - pl_hdr, HTT_INVALID_PEER, WDI_NO_VAL); + dp_wdi_event_handler(WDI_EVENT_OFFLOAD_ALL, soc->dp_soc, + (void *)pl_hdr, HTT_INVALID_PEER, WDI_NO_VAL, 0); + break; + } + case HTT_T2H_MSG_TYPE_PPDU_STATS_IND: + { + qdf_nbuf_set_pktlen(htt_t2h_msg, HTT_T2H_MAX_MSG_SIZE); + QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO, + "received HTT_T2H_MSG_TYPE_PPDU_STATS_IND\n"); + dp_wdi_event_handler(WDI_EVENT_LITE_T2H, soc->dp_soc, + htt_t2h_msg, HTT_INVALID_PEER, WDI_NO_VAL, 0); break; } #endif -#endif /* notyet */ +#endif case HTT_T2H_MSG_TYPE_VERSION_CONF: { soc->tgt_ver.major = HTT_VER_CONF_MAJOR_GET(*msg_word); diff --git a/dp/wifi3.0/dp_internal.h b/dp/wifi3.0/dp_internal.h index b57eb9e20f..d7035446cf 100644 --- a/dp/wifi3.0/dp_internal.h +++ b/dp/wifi3.0/dp_internal.h @@ -19,6 +19,10 @@ #ifndef _DP_INTERNAL_H_ #define _DP_INTERNAL_H_ +#include "dp_types.h" + +#define RX_BUFFER_SIZE_PKTLOG_LITE 1024 + #if DP_PRINT_ENABLE #include /* va_list */ #include /* qdf_vprint */ @@ -220,6 +224,7 @@ while (0) #endif + extern int dp_peer_find_attach(struct dp_soc *soc); extern void dp_peer_find_detach(struct dp_soc *soc); extern void dp_peer_find_hash_add(struct dp_soc *soc, struct dp_peer *peer); @@ -288,4 +293,59 @@ int dp_peer_rxtid_stats(struct dp_peer *peer); void dp_set_pn_check_wifi3(struct cdp_vdev *vdev_handle, struct cdp_peer *peer_handle, enum cdp_sec_type sec_type, uint32_t *rx_pn); + +#if defined(CONFIG_WIN) && WDI_EVENT_ENABLE +int dp_wdi_event_unsub(struct cdp_pdev *txrx_pdev_handle, + void *event_cb_sub_handle, + uint32_t event); + +int dp_wdi_event_sub(struct cdp_pdev *txrx_pdev_handle, + void *event_cb_sub_handle, + uint32_t event); + +void dp_wdi_event_handler(enum WDI_EVENT event, void *soc, + void *data, u_int16_t peer_id, + int status, u_int8_t pdev_id); + +int dp_wdi_event_attach(struct dp_pdev *txrx_pdev); +int dp_wdi_event_detach(struct dp_pdev *txrx_pdev); +int dp_set_pktlog_wifi3(struct dp_pdev *pdev, uint32_t event, + bool enable); +#else +static inline int dp_wdi_event_unsub(struct cdp_pdev *txrx_pdev_handle, + void *event_cb_sub_handle, + uint32_t event) +{ + return -EPERM; +} + +static inline int dp_wdi_event_sub(struct cdp_pdev *txrx_pdev_handle, + void *event_cb_sub_handle, + uint32_t event) +{ + return -EPERM; +} + +static inline void dp_wdi_event_handler(enum WDI_EVENT event, void *soc, + void *data, u_int16_t peer_id, + int status, u_int8_t pdev_id) +{ +} + +static inline int dp_wdi_event_attach(struct dp_pdev *txrx_pdev) +{ + return -EPERM; +} + +static inline int dp_wdi_event_detach(struct dp_pdev *txrx_pdev) +{ + return -EPERM; +} + +static inline int dp_set_pktlog_wifi3(struct dp_pdev *pdev, uint32_t event, + bool enable) +{ + return -EPERM; +} +#endif /* CONFIG_WIN */ #endif /* #ifndef _DP_INTERNAL_H_ */ diff --git a/dp/wifi3.0/dp_main.c b/dp/wifi3.0/dp_main.c index 9216cb80f6..89717976ad 100644 --- a/dp/wifi3.0/dp_main.c +++ b/dp/wifi3.0/dp_main.c @@ -37,6 +37,7 @@ #include "dp_peer.h" #include "dp_rx_mon.h" #include "htt_stats.h" +#include "qdf_mem.h" /* qdf_mem_malloc,free */ #define DP_INTR_POLL_TIMER_MS 10 #define DP_MCS_LENGTH (6*MAX_MCS) @@ -468,7 +469,7 @@ static QDF_STATUS dp_soc_interrupt_attach(void *txrx_soc) if (rx_mon_mask & (1 << j)) { irq_id_map[num_irq++] = - (rxdma2host_monitor_destination_mac1 + (ppdu_end_interrupts_mac1 - j); } @@ -1294,8 +1295,14 @@ static struct cdp_pdev *dp_pdev_attach_wifi3(struct cdp_soc_t *txrx_soc, /* Rx monitor mode specific init */ if (dp_rx_pdev_mon_attach(pdev)) { QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR, - "dp_rx_pdev_attach failed\n"); - goto fail0; + "dp_rx_pdev_attach failed\n"); + goto fail1; + } + + if (dp_wdi_event_attach(pdev)) { + QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR, + "dp_wdi_evet_attach failed\n"); + goto fail1; } /* set the reo destination to 1 during initialization */ @@ -1370,6 +1377,8 @@ static void dp_pdev_detach_wifi3(struct cdp_pdev *txrx_pdev, int force) struct dp_pdev *pdev = (struct dp_pdev *)txrx_pdev; struct dp_soc *soc = pdev->soc; + dp_wdi_event_detach(pdev); + dp_tx_pdev_detach(pdev); if (wlan_cfg_per_pdev_tx_ring(soc->wlan_cfg_ctx)) { @@ -3872,6 +3881,8 @@ static struct cdp_ctrl_ops dp_ops_ctrl = { .txrx_update_filter_neighbour_peers = dp_update_filter_neighbour_peers, /* TODO: Add other functions */ + .txrx_wdi_event_sub = dp_wdi_event_sub, + .txrx_wdi_event_unsub = dp_wdi_event_unsub, }; static struct cdp_me_ops dp_ops_me = { @@ -4103,3 +4114,106 @@ fail1: fail0: return NULL; } + +#if defined(CONFIG_WIN) && WDI_EVENT_ENABLE +/* +* dp_set_pktlog_wifi3() - attach txrx vdev +* @pdev: Datapath PDEV handle +* @event: which event's notifications are being subscribed to +* @enable: WDI event subscribe or not. (True or False) +* +* Return: Success, NULL on failure +*/ +int dp_set_pktlog_wifi3(struct dp_pdev *pdev, uint32_t event, + bool enable) +{ + struct dp_soc *soc = pdev->soc; + struct htt_rx_ring_tlv_filter htt_tlv_filter = {0}; + + if (enable) { + switch (event) { + case WDI_EVENT_RX_DESC: + if (pdev->monitor_vdev) { + /* Nothing needs to be done if monitor mode is + * enabled + */ + return 0; + } + if (pdev->rx_pktlog_mode != DP_RX_PKTLOG_FULL) { + pdev->rx_pktlog_mode = DP_RX_PKTLOG_FULL; + htt_tlv_filter.mpdu_start = 1; + htt_tlv_filter.msdu_start = 1; + htt_tlv_filter.msdu_end = 1; + htt_tlv_filter.mpdu_end = 1; + htt_tlv_filter.packet_header = 1; + htt_tlv_filter.attention = 1; + htt_tlv_filter.ppdu_start = 1; + htt_tlv_filter.ppdu_end = 1; + htt_tlv_filter.ppdu_end_user_stats = 1; + htt_tlv_filter.ppdu_end_user_stats_ext = 1; + htt_tlv_filter.ppdu_end_status_done = 1; + htt_tlv_filter.enable_fp = 1; + + htt_h2t_rx_ring_cfg(soc->htt_handle, + pdev->pdev_id, + pdev->rxdma_mon_status_ring.hal_srng, + RXDMA_MONITOR_STATUS, RX_BUFFER_SIZE, + &htt_tlv_filter); + } + break; + case WDI_EVENT_LITE_RX: + if (pdev->monitor_vdev) { + /* Nothing needs to be done if monitor mode is + * enabled + */ + return 0; + } + if (pdev->rx_pktlog_mode != DP_RX_PKTLOG_LITE) { + pdev->rx_pktlog_mode = DP_RX_PKTLOG_LITE; + htt_tlv_filter.ppdu_start = 1; + htt_tlv_filter.ppdu_end = 1; + htt_tlv_filter.ppdu_end_user_stats = 1; + htt_tlv_filter.ppdu_end_user_stats_ext = 1; + htt_tlv_filter.ppdu_end_status_done = 1; + htt_tlv_filter.enable_fp = 1; + + htt_h2t_rx_ring_cfg(soc->htt_handle, + pdev->pdev_id, + pdev->rxdma_mon_status_ring.hal_srng, + RXDMA_MONITOR_STATUS, + RX_BUFFER_SIZE_PKTLOG_LITE, + &htt_tlv_filter); + } + break; + default: + /* Nothing needs to be done for other pktlog types */ + break; + } + } else { + switch (event) { + case WDI_EVENT_RX_DESC: + case WDI_EVENT_LITE_RX: + if (pdev->monitor_vdev) { + /* Nothing needs to be done if monitor mode is + * enabled + */ + return 0; + } + if (pdev->rx_pktlog_mode != DP_RX_PKTLOG_DISABLED) { + pdev->rx_pktlog_mode = DP_RX_PKTLOG_DISABLED; + /* htt_tlv_filter is initialized to 0 */ + htt_h2t_rx_ring_cfg(soc->htt_handle, + pdev->pdev_id, + pdev->rxdma_mon_status_ring.hal_srng, + RXDMA_MONITOR_STATUS, RX_BUFFER_SIZE, + &htt_tlv_filter); + } + break; + default: + /* Nothing needs to be done for other pktlog types */ + break; + } + } + return 0; +} +#endif diff --git a/dp/wifi3.0/dp_rx.h b/dp/wifi3.0/dp_rx.h index 72f33e08e6..50359ebeb7 100644 --- a/dp/wifi3.0/dp_rx.h +++ b/dp/wifi3.0/dp_rx.h @@ -29,7 +29,7 @@ #define RX_BUFFER_ALIGNMENT 4 #endif /* RXDMA_OPTIMIZATION */ -#define RX_BUFFER_SIZE 2048 +#define RX_BUFFER_SIZE 2048 #define RX_BUFFER_RESERVATION 0 #define DP_PEER_METADATA_PEER_ID_MASK 0x0000ffff diff --git a/dp/wifi3.0/dp_rx_mon_status.c b/dp/wifi3.0/dp_rx_mon_status.c index 2e3d1a6a9d..ef0eabcb0e 100644 --- a/dp/wifi3.0/dp_rx_mon_status.c +++ b/dp/wifi3.0/dp_rx_mon_status.c @@ -25,6 +25,8 @@ #include "hal_api_mon.h" #include "ieee80211.h" #include "dp_rx_mon.h" +#include "dp_internal.h" +#include "qdf_mem.h" /* qdf_mem_malloc,free */ /** @@ -44,7 +46,7 @@ dp_rx_mon_status_process_tlv(struct dp_soc *soc, uint32_t mac_id, qdf_nbuf_t status_nbuf; uint8_t *rx_tlv; uint8_t *rx_tlv_start; - uint32_t tlv_status; + uint32_t tlv_status = HAL_TLV_STATUS_DUMMY; #ifdef DP_INTR_POLL_BASED if (!pdev) @@ -62,16 +64,24 @@ dp_rx_mon_status_process_tlv(struct dp_soc *soc, uint32_t mac_id, rx_tlv = qdf_nbuf_data(status_nbuf); rx_tlv_start = rx_tlv; - do { - tlv_status = hal_rx_status_get_tlv_info(rx_tlv, - ppdu_info); - rx_tlv = hal_rx_status_get_next_tlv(rx_tlv); +#if defined(CONFIG_WIN) && WDI_EVENT_ENABLE +#ifndef REMOVE_PKT_LOG + dp_wdi_event_handler(WDI_EVENT_RX_DESC, soc, + status_nbuf, HTT_INVALID_PEER, WDI_NO_VAL, 0); +#endif +#endif + if (pdev->monitor_vdev != NULL) { - if ((rx_tlv - rx_tlv_start) >= RX_BUFFER_SIZE) - break; + do { + tlv_status = hal_rx_status_get_tlv_info(rx_tlv, + ppdu_info); + rx_tlv = hal_rx_status_get_next_tlv(rx_tlv); - } while (tlv_status == HAL_TLV_STATUS_PPDU_NOT_DONE); + if ((rx_tlv - rx_tlv_start) >= RX_BUFFER_SIZE) + break; + } while (tlv_status == HAL_TLV_STATUS_PPDU_NOT_DONE); + } qdf_nbuf_free(status_nbuf); if (tlv_status == HAL_TLV_STATUS_PPDU_DONE) { diff --git a/dp/wifi3.0/dp_types.h b/dp/wifi3.0/dp_types.h index 9f907e2d5b..d8ee9d4687 100644 --- a/dp/wifi3.0/dp_types.h +++ b/dp/wifi3.0/dp_types.h @@ -89,6 +89,14 @@ #define DP_MAX_INTERRUPT_CONTEXTS 8 #define DP_MAX_MECT_ENTRIES 64 +#ifndef REMOVE_PKT_LOG +enum rx_pktlog_mode { + DP_RX_PKTLOG_DISABLED = 0, + DP_RX_PKTLOG_FULL, + DP_RX_PKTLOG_LITE, +}; +#endif + struct dp_soc_cmn; struct dp_pdev; struct dp_vdev; @@ -511,11 +519,6 @@ struct dp_soc { /* Rx ring map for interrupt processing */ struct dp_srng *rx_ring_map[DP_MAX_RX_RINGS]; -#ifndef CONFIG_WIN - /* WDI event handlers */ - struct wdi_event_subscribe_t **wdi_event_list; -#endif - /* peer ID to peer object map (array of pointers to peer objects) */ struct dp_peer **peer_id_to_obj_map; @@ -822,6 +825,14 @@ struct dp_pdev { /* map this pdev to a particular Reo Destination ring */ enum cdp_host_reo_dest_ring reo_dest; + +#ifndef REMOVE_PKT_LOG + /* Packet log mode */ + uint8_t rx_pktlog_mode; +#endif + + /* WDI event handlers */ + struct wdi_event_subscribe_t **wdi_event_list; }; struct dp_peer; diff --git a/dp/wifi3.0/dp_wdi_event.c b/dp/wifi3.0/dp_wdi_event.c new file mode 100644 index 0000000000..8bdc623547 --- /dev/null +++ b/dp/wifi3.0/dp_wdi_event.c @@ -0,0 +1,305 @@ +/* + * Copyright (c) 2017 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. + */ + + +#include "dp_internal.h" +#include "qdf_mem.h" /* qdf_mem_malloc,free */ + +#if defined(CONFIG_WIN) && WDI_EVENT_ENABLE + + +/* + * dp_wdi_event_next_sub() - Return handle for Next WDI event + * @wdi_sub: WDI Event handle + * + * Return handle for next WDI event in list + * + * Return: Next WDI event to be subscribe + */ +static inline wdi_event_subscribe * +dp_wdi_event_next_sub(wdi_event_subscribe *wdi_sub) +{ + if (!wdi_sub) { + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, + "Invalid subscriber in %s\n", __func__); + return NULL; + } + return wdi_sub->priv.next; +} + + +/* + * dp_wdi_event_del_subs() -Delete Event subscription + * @wdi_sub: WDI Event handle + * @event_index: Event index from list + * + * This API will delete subscribed event from list + * Return: None + */ +static inline void +dp_wdi_event_del_subs(wdi_event_subscribe *wdi_sub, int event_index) +{ + /* Subscribers should take care of deletion */ +} + + +/* + * dp_wdi_event_iter_sub() - Iterate through all WDI event in the list + * and pass WDI event to callback funtion + * @pdev: DP pdev handle + * @event_index: Event index in list + * @wdi_event: WDI event handle + * @data: pointer to data + * @peer_id: peer id number + * @status: HTT rx status + * + * + * Return: None + */ +static inline void +dp_wdi_event_iter_sub( + struct dp_pdev *pdev, + uint32_t event_index, + wdi_event_subscribe *wdi_sub, + void *data, + uint16_t peer_id, + int status) +{ + enum WDI_EVENT event = event_index + WDI_EVENT_BASE; + + if (wdi_sub) { + do { + wdi_sub->callback(wdi_sub->context, event, data, + peer_id, status); + } while ((wdi_sub = dp_wdi_event_next_sub(wdi_sub))); + } +} + + +/* + * dp_wdi_event_handler() - Event handler for WDI event + * @event: wdi event number + * @soc: soc handle + * @data: pointer to data + * @peer_id: peer id number + * @status: HTT rx status + * @pdev_id: id of pdev + * + * It will be called to register WDI event + * + * Return: None + */ +void +dp_wdi_event_handler( + enum WDI_EVENT event, + void *soc, + void *data, + uint16_t peer_id, + int status, uint8_t pdev_id) +{ + uint32_t event_index; + wdi_event_subscribe *wdi_sub; + struct dp_pdev *txrx_pdev; + struct dp_soc *soc_t = (struct dp_soc *)soc; + txrx_pdev = (struct dp_pdev *)soc_t->pdev_list[pdev_id]; + + if (!event) { + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, + "Invalid WDI event in %s\n", __func__); + return; + } + if (!txrx_pdev) { + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, + "Invalid pdev in WDI event handler\n"); + return; + } + + /* + * There can be NULL data, so no validation for the data + * Subscribers must do the sanity based on the requirements + */ + event_index = event - WDI_EVENT_BASE; + if (!(txrx_pdev->wdi_event_list[event_index]) && + (event == WDI_EVENT_RX_DESC)) { + /* WDI_EVEN_RX_DESC is indicated for RX_LITE also */ + event_index = WDI_EVENT_LITE_RX - WDI_EVENT_BASE; + } + wdi_sub = txrx_pdev->wdi_event_list[event_index]; + + /* Find the subscriber */ + dp_wdi_event_iter_sub(txrx_pdev, event_index, wdi_sub, data, + peer_id, status); +} + + +/* + * dp_wdi_event_sub() - Subscribe WDI event + * @txrx_pdev_handle: cdp_pdev handle + * @event_cb_sub_handle: subcribe evnet handle + * @event: Event to be subscribe + * + * Return: 0 for success. nonzero for failure. + */ +int +dp_wdi_event_sub( + struct cdp_pdev *txrx_pdev_handle, + void *event_cb_sub_handle, + uint32_t event) +{ + uint32_t event_index; + wdi_event_subscribe *wdi_sub; + struct dp_pdev *txrx_pdev = (struct dp_pdev *)txrx_pdev_handle; + wdi_event_subscribe *event_cb_sub = + (wdi_event_subscribe *) event_cb_sub_handle; + + if (!txrx_pdev) { + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, + "Invalid txrx_pdev in %s", __func__); + return -EINVAL; + } + if (!event_cb_sub) { + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, + "Invalid callback in %s", __func__); + return -EINVAL; + } + if ((!event) || (event >= WDI_EVENT_LAST) || (event < WDI_EVENT_BASE)) { + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, + "Invalid event in %s", __func__); + return -EINVAL; + } + dp_set_pktlog_wifi3(txrx_pdev, event, true); + event_index = event - WDI_EVENT_BASE; + wdi_sub = txrx_pdev->wdi_event_list[event_index]; + + /* + * Check if it is the first subscriber of the event + */ + if (!wdi_sub) { + wdi_sub = event_cb_sub; + wdi_sub->priv.next = NULL; + wdi_sub->priv.prev = NULL; + txrx_pdev->wdi_event_list[event_index] = wdi_sub; + return 0; + } + event_cb_sub->priv.next = wdi_sub; + event_cb_sub->priv.prev = NULL; + wdi_sub->priv.prev = event_cb_sub; + txrx_pdev->wdi_event_list[event_index] = event_cb_sub; + return 0; + +} + +/* + * dp_wdi_event_unsub() - WDI event unsubscribe + * @txrx_pdev_handle: cdp_pdev handle + * @event_cb_sub_handle: subscribed event handle + * @event: Event to be unsubscribe + * + * + * Return: 0 for success. nonzero for failure. + */ +int +dp_wdi_event_unsub( + struct cdp_pdev *txrx_pdev_handle, + void *event_cb_sub_handle, + uint32_t event) +{ + uint32_t event_index = event - WDI_EVENT_BASE; + struct dp_pdev *txrx_pdev = (struct dp_pdev *)txrx_pdev_handle; + wdi_event_subscribe *event_cb_sub = + (wdi_event_subscribe *) event_cb_sub_handle; + + if (!event_cb_sub) { + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, + "Invalid callback in %s", __func__); + return -EINVAL; + } + + dp_set_pktlog_wifi3(txrx_pdev, event, false); + + if (!event_cb_sub->priv.prev) { + txrx_pdev->wdi_event_list[event_index] = event_cb_sub->priv.next; + } else { + event_cb_sub->priv.prev->priv.next = event_cb_sub->priv.next; + } + if (event_cb_sub->priv.next) { + event_cb_sub->priv.next->priv.prev = event_cb_sub->priv.prev; + } + + return 0; +} + + +/* + * dp_wdi_event_attach() - Attach wdi event + * @txrx_pdev: DP pdev handle + * + * Return: 0 for success. nonzero for failure. + */ +int +dp_wdi_event_attach(struct dp_pdev *txrx_pdev) +{ + if (!txrx_pdev) { + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, + "Invalid device in %s\nWDI event attach failed\n", + __func__); + return -EINVAL; + } + /* Separate subscriber list for each event */ + txrx_pdev->wdi_event_list = (wdi_event_subscribe **) + qdf_mem_malloc( + sizeof(wdi_event_subscribe *) * WDI_NUM_EVENTS); + if (!txrx_pdev->wdi_event_list) { + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, + "Insufficient memory for the WDI event lists\n"); + return -EINVAL; + } + return 0; +} + + +/* + * dp_wdi_event_detach() - Detach WDI event + * @txrx_pdev: DP pdev handle + * + * Return: 0 for success. nonzero for failure. + */ +int +dp_wdi_event_detach(struct dp_pdev *txrx_pdev) +{ + int i; + wdi_event_subscribe *wdi_sub; + if (!txrx_pdev) { + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, + "Invalid device in %s\nWDI attach failed", __func__); + return -EINVAL; + } + if (!txrx_pdev->wdi_event_list) { + return -EINVAL; + } + for (i = 0; i < WDI_NUM_EVENTS; i++) { + wdi_sub = txrx_pdev->wdi_event_list[i]; + /* Delete all the subscribers */ + dp_wdi_event_del_subs(wdi_sub, i); + } + if (txrx_pdev->wdi_event_list) { + qdf_mem_free(txrx_pdev->wdi_event_list); + } + return 0; +} +#endif /* CONFIG_WIN */ diff --git a/hif/src/ce/ce_assignment.h b/hif/src/ce/ce_assignment.h index 7dfbe3caa5..18b3a83257 100644 --- a/hif/src/ce/ce_assignment.h +++ b/hif/src/ce/ce_assignment.h @@ -569,9 +569,8 @@ static struct CE_attr host_ce_config_wlan_qca8074[] = { /* host->target HTT */ { /* CE4 */ (CE_ATTR_FLAGS | CE_ATTR_DISABLE_INTR), 0, CE_HTT_H2T_MSG_SRC_NENTRIES, 256, 0, NULL,}, - /* ipa_uc->target HTC control */ - { /* CE5 */ (CE_ATTR_FLAGS | CE_ATTR_DISABLE_INTR), 0, - 1024, 512, 0, NULL,}, + /* target -> host PKTLOG */ + { /* CE5 */ CE_ATTR_FLAGS, 0, 0, 2048, 512, NULL,}, /* Target autonomous HIF_memcpy */ { /* CE6 */ CE_ATTR_FLAGS, 0, 0, 0, 0, NULL,}, /* host->target WMI (mac1) */ @@ -582,8 +581,7 @@ static struct CE_attr host_ce_config_wlan_qca8074[] = { { /* CE9 */ CE_ATTR_FLAGS, 0, 32, 2048, 0, NULL,}, /* target->host HTT */ { /* CE10 */ CE_ATTR_FLAGS, 0, 0, 2048, 512, NULL,}, - /* target -> host PKTLOG */ - { /* CE11 */ CE_ATTR_FLAGS, 0, 0, 2048, 512, NULL,}, + /* CE11 unused */ }; static struct CE_pipe_config target_ce_config_wlan_qca8074[] = { @@ -628,9 +626,8 @@ static struct CE_attr host_ce_config_wlan_qca8074_pci[] = { /* host->target HTT */ { /* CE4 */ (CE_ATTR_FLAGS | CE_ATTR_DISABLE_INTR), 0, CE_HTT_H2T_MSG_SRC_NENTRIES, 256, 0, NULL,}, - /* ipa_uc->target HTC control */ - { /* CE5 */ (CE_ATTR_FLAGS | CE_ATTR_DISABLE_INTR), 0, - 1024, 512, 0, NULL,}, + /* target -> host PKTLOG */ + { /* CE5 */ EPPING_CE_FLAGS_POLL, 0, 0, 2048, 512, NULL,}, /* Target autonomous HIF_memcpy */ { /* CE6 */ CE_ATTR_FLAGS, 0, 0, 0, 0, NULL,}, /* host->target WMI (mac1) */ @@ -641,9 +638,9 @@ static struct CE_attr host_ce_config_wlan_qca8074_pci[] = { { /* CE9 */ EPPING_CE_FLAGS_POLL, 0, 32, 2048, 0, NULL,}, /* target->host HTT */ { /* CE10 */ CE_ATTR_FLAGS, 0, 0, 2048, 512, NULL,}, - /* target -> host PKTLOG */ - { /* CE11 */ CE_ATTR_FLAGS, 0, 0, 2048, 512, NULL,}, + /* CE11 unused */ }; + static struct CE_pipe_config target_ce_config_wlan_qca8074_pci[] = { /* host->target HTC control and raw streams */ { /* CE0 */ 0, PIPEDIR_OUT, 32, 2048, CE_ATTR_FLAGS, 0,}, diff --git a/wmi/inc/wmi_unified_api.h b/wmi/inc/wmi_unified_api.h index f413dd01b2..01dccc77d9 100644 --- a/wmi/inc/wmi_unified_api.h +++ b/wmi/inc/wmi_unified_api.h @@ -426,14 +426,14 @@ QDF_STATUS wmi_unified_wow_remove_wakeup_pattern_send(void *wmi_hdl, #ifndef CONFIG_MCL QDF_STATUS wmi_unified_packet_log_enable_send(void *wmi_hdl, - WMI_HOST_PKTLOG_EVENT PKTLOG_EVENT); + WMI_HOST_PKTLOG_EVENT PKTLOG_EVENT, uint8_t mac_id); #else QDF_STATUS wmi_unified_packet_log_enable_send(void *wmi_hdl, uint8_t macaddr[IEEE80211_ADDR_LEN], struct packet_enable_params *param); #endif -QDF_STATUS wmi_unified_packet_log_disable_send(void *wmi_hdl); +QDF_STATUS wmi_unified_packet_log_disable_send(void *wmi_hdl, uint8_t mac_id); QDF_STATUS wmi_unified_suspend_send(void *wmi_hdl, struct suspend_params *param, diff --git a/wmi/inc/wmi_unified_priv.h b/wmi/inc/wmi_unified_priv.h index b35c2a6ed7..65dc5bf1c1 100644 --- a/wmi/inc/wmi_unified_priv.h +++ b/wmi/inc/wmi_unified_priv.h @@ -260,14 +260,15 @@ QDF_STATUS (*send_stats_request_cmd)(wmi_unified_t wmi_handle, #ifdef CONFIG_WIN QDF_STATUS (*send_packet_log_enable_cmd)(wmi_unified_t wmi_handle, - WMI_HOST_PKTLOG_EVENT PKTLOG_EVENT); + WMI_HOST_PKTLOG_EVENT PKTLOG_EVENT, uint8_t mac_id); #else QDF_STATUS (*send_packet_log_enable_cmd)(wmi_unified_t wmi_handle, uint8_t macaddr[IEEE80211_ADDR_LEN], struct packet_enable_params *param); #endif -QDF_STATUS (*send_packet_log_disable_cmd)(wmi_unified_t wmi_handle); +QDF_STATUS (*send_packet_log_disable_cmd)(wmi_unified_t wmi_handle, + uint8_t mac_id); QDF_STATUS (*send_beacon_send_cmd)(wmi_unified_t wmi_handle, struct beacon_params *param); diff --git a/wmi/src/wmi_unified_api.c b/wmi/src/wmi_unified_api.c index 2835a37bfb..3d7192fd5a 100644 --- a/wmi/src/wmi_unified_api.c +++ b/wmi/src/wmi_unified_api.c @@ -648,13 +648,13 @@ QDF_STATUS wmi_unified_packet_log_enable_send(void *wmi_hdl, * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure */ QDF_STATUS wmi_unified_packet_log_enable_send(void *wmi_hdl, - WMI_HOST_PKTLOG_EVENT PKTLOG_EVENT) + WMI_HOST_PKTLOG_EVENT PKTLOG_EVENT, uint8_t mac_id) { wmi_unified_t wmi_handle = (wmi_unified_t) wmi_hdl; if (wmi_handle->ops->send_packet_log_enable_cmd) return wmi_handle->ops->send_packet_log_enable_cmd(wmi_handle, - PKTLOG_EVENT); + PKTLOG_EVENT, mac_id); return QDF_STATUS_E_FAILURE; } @@ -666,12 +666,13 @@ QDF_STATUS wmi_unified_packet_log_enable_send(void *wmi_hdl, * @param PKTLOG_EVENT : packet log event * @return QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure */ -QDF_STATUS wmi_unified_packet_log_disable_send(void *wmi_hdl) +QDF_STATUS wmi_unified_packet_log_disable_send(void *wmi_hdl, uint8_t mac_id) { wmi_unified_t wmi_handle = (wmi_unified_t) wmi_hdl; if (wmi_handle->ops->send_packet_log_disable_cmd) - return wmi_handle->ops->send_packet_log_disable_cmd(wmi_handle); + return wmi_handle->ops->send_packet_log_disable_cmd(wmi_handle, + mac_id); return QDF_STATUS_E_FAILURE; } diff --git a/wmi/src/wmi_unified_non_tlv.c b/wmi/src/wmi_unified_non_tlv.c index f96eb49d18..224d15dd4b 100644 --- a/wmi/src/wmi_unified_non_tlv.c +++ b/wmi/src/wmi_unified_non_tlv.c @@ -1446,10 +1446,11 @@ static QDF_STATUS send_bss_chan_info_request_cmd_non_tlv(wmi_unified_t wmi_handl * * @param wmi_handle : handle to WMI. * @param PKTLOG_EVENT : packet log event + * @mac_id: mac id to have radio context * @return QDF_STATUS_SUCCESS on success and -ve on failure. */ static QDF_STATUS send_packet_log_enable_cmd_non_tlv(wmi_unified_t wmi_handle, - WMI_HOST_PKTLOG_EVENT PKTLOG_EVENT) + WMI_HOST_PKTLOG_EVENT PKTLOG_EVENT, uint8_t mac_id) { wmi_pdev_pktlog_enable_cmd *cmd; int len = 0; @@ -1474,9 +1475,11 @@ static QDF_STATUS send_packet_log_enable_cmd_non_tlv(wmi_unified_t wmi_handle, * send_packet_log_disable_cmd_non_tlv() - WMI disable packet log send function * * @param wmi_handle : handle to WMI. + * @mac_id: mac id to have radio context * @return QDF_STATUS_SUCCESS on success and -ve on failure. */ -static QDF_STATUS send_packet_log_disable_cmd_non_tlv(wmi_unified_t wmi_handle) +static QDF_STATUS send_packet_log_disable_cmd_non_tlv(wmi_unified_t wmi_handle, + uint8_t mac_id) { int len = 0; wmi_buf_t buf; diff --git a/wmi/src/wmi_unified_tlv.c b/wmi/src/wmi_unified_tlv.c index 37330c066f..621369f24d 100644 --- a/wmi/src/wmi_unified_tlv.c +++ b/wmi/src/wmi_unified_tlv.c @@ -1575,17 +1575,79 @@ static QDF_STATUS send_stats_request_cmd_tlv(wmi_unified_t wmi_handle, #ifdef CONFIG_WIN /** - * send_packet_log_enable_cmd_tlv() - WMI request stats function + * send_packet_log_enable_cmd_tlv() - Send WMI command to enable packet-log * @param wmi_handle : handle to WMI. - * @param macaddr : MAC address - * @param param : pointer to hold stats request parameter + * @param PKTLOG_EVENT : packet log event + * @mac_id: mac id to have radio context * * Return: 0 on success and -ve on failure. */ static QDF_STATUS send_packet_log_enable_cmd_tlv(wmi_unified_t wmi_handle, - WMI_HOST_PKTLOG_EVENT PKTLOG_EVENT) + WMI_HOST_PKTLOG_EVENT PKTLOG_EVENT, uint8_t mac_id) { - return 0; + int32_t ret; + wmi_pdev_pktlog_enable_cmd_fixed_param *cmd; + wmi_buf_t buf; + uint16_t len = sizeof(wmi_pdev_pktlog_enable_cmd_fixed_param); + + buf = wmi_buf_alloc(wmi_handle, len); + if (!buf) { + WMI_LOGE("%s: wmi_buf_alloc failed", __func__); + return -QDF_STATUS_E_NOMEM; + } + + cmd = (wmi_pdev_pktlog_enable_cmd_fixed_param *) wmi_buf_data(buf); + WMITLV_SET_HDR(&cmd->tlv_header, + WMITLV_TAG_STRUC_wmi_pdev_pktlog_enable_cmd_fixed_param, + WMITLV_GET_STRUCT_TLVLEN + (wmi_pdev_pktlog_enable_cmd_fixed_param)); + cmd->evlist = PKTLOG_EVENT; + cmd->pdev_id = mac_id; + ret = wmi_unified_cmd_send(wmi_handle, buf, len, + WMI_PDEV_PKTLOG_ENABLE_CMDID); + if (ret) { + WMI_LOGE("Failed to send pktlog enable cmd to FW =%d", ret); + wmi_buf_free(buf); + } + + return ret; +} + +/** + * send_packet_log_disable_cmd_tlv() - Send WMI command to disable packet-log + * @param wmi_handle : handle to WMI. + * @mac_id: mac id to have radio context + * + * Return: 0 on success and -ve on failure. + */ +static QDF_STATUS send_packet_log_disable_cmd_tlv(wmi_unified_t wmi_handle, + WMI_HOST_PKTLOG_EVENT PKTLOG_EVENT, uint8_t mac_id) +{ + int32_t ret; + wmi_pdev_pktlog_disable_cmd_fixed_param *cmd; + wmi_buf_t buf; + uint16_t len = sizeof(wmi_pdev_pktlog_disable_cmd_fixed_param); + + buf = wmi_buf_alloc(wmi_handle, len); + if (!buf) { + WMI_LOGE("%s: wmi_buf_alloc failed", __func__); + return -QDF_STATUS_E_NOMEM; + } + + cmd = (wmi_pdev_pktlog_disable_cmd_fixed_param *) wmi_buf_data(buf); + WMITLV_SET_HDR(&cmd->tlv_header, + WMITLV_TAG_STRUC_wmi_pdev_pktlog_disable_cmd_fixed_param, + WMITLV_GET_STRUCT_TLVLEN + (wmi_pdev_pktlog_disable_cmd_fixed_param)); + cmd->pdev_id = mac_id; + ret = wmi_unified_cmd_send(wmi_handle, buf, len, + WMI_PDEV_PKTLOG_DISABLE_CMDID); + if (ret) { + WMI_LOGE("Failed to send pktlog disable cmd to FW =%d", ret); + wmi_buf_free(buf); + } + + return ret; } #else /**