diff --git a/hif/inc/hif.h b/hif/inc/hif.h index 224b566df7..9642e22336 100644 --- a/hif/inc/hif.h +++ b/hif/inc/hif.h @@ -308,6 +308,8 @@ QDF_STATUS hif_diag_write_access(struct hif_opaque_softc *scn, uint32_t address, QDF_STATUS hif_diag_write_mem(struct hif_opaque_softc *scn, uint32_t address, uint8_t *data, int nbytes); +typedef void (*fastpath_msg_handler)(void *, qdf_nbuf_t *, uint32_t); + /* * Set the FASTPATH_mode_on flag in sc, for use by data path */ @@ -315,8 +317,14 @@ QDF_STATUS hif_diag_write_mem(struct hif_opaque_softc *scn, uint32_t address, void hif_enable_fastpath(struct hif_opaque_softc *hif_ctx); bool hif_is_fastpath_mode_enabled(struct hif_opaque_softc *hif_ctx); void *hif_get_ce_handle(struct hif_opaque_softc *hif_ctx, int); +int hif_ce_fastpath_cb_register(fastpath_msg_handler handler, void *context); +#else +static inline int hif_ce_fastpath_cb_register(fastpath_msg_handler handler, + void *context) +{ + return QDF_STATUS_E_FAILURE; +} #endif -void hif_update_fastpath_recv_bufs_cnt(struct hif_opaque_softc *scn); /* * Enable/disable CDC max performance workaround @@ -386,10 +394,6 @@ struct hif_msg_callbacks { struct hif_bus_id; typedef struct hif_bus_id hif_bus_id; -typedef int (*fastpath_msg_handler)(void *, qdf_nbuf_t *, uint32_t); -int -hif_ce_fastpath_cb_register(fastpath_msg_handler, void *context); - void hif_post_init(struct hif_opaque_softc *scn, void *hHTC, struct hif_msg_callbacks *callbacks); QDF_STATUS hif_start(struct hif_opaque_softc *scn); @@ -515,8 +519,6 @@ void hif_set_target_status(struct hif_opaque_softc *hif_ctx, ol_target_status); void hif_init_ini_config(struct hif_opaque_softc *hif_ctx, struct hif_config_info *cfg); -bool ce_is_fastpath_enabled(struct hif_opaque_softc *scn); -bool ce_is_fastpath_handler_registered(struct CE_state *ce_state); #ifdef __cplusplus } #endif diff --git a/hif/src/ce/ce_internal.h b/hif/src/ce/ce_internal.h index 5d573c1228..2a567ea0c0 100644 --- a/hif/src/ce/ce_internal.h +++ b/hif/src/ce/ce_internal.h @@ -357,8 +357,18 @@ struct ce_sendlist_s { } item[CE_SENDLIST_ITEMS_MAX]; }; +#ifdef WLAN_FEATURE_FASTPATH void ce_h2t_tx_ce_cleanup(struct CE_handle *ce_hdl); void ce_t2h_msg_ce_cleanup(struct CE_handle *ce_hdl); +#else +static inline void ce_h2t_tx_ce_cleanup(struct CE_handle *ce_hdl) +{ +} + +static inline void ce_t2h_msg_ce_cleanup(struct CE_handle *ce_hdl) +{ +} +#endif /* which ring of a CE? */ #define CE_RING_SRC 0 diff --git a/hif/src/ce/ce_main.c b/hif/src/ce/ce_main.c index fafadf71d9..f8745f28d6 100644 --- a/hif/src/ce/ce_main.c +++ b/hif/src/ce/ce_main.c @@ -725,6 +725,53 @@ error_no_dma_mem: } #ifdef WLAN_FEATURE_FASTPATH +/** + * hif_enable_fastpath() Update that we have enabled fastpath mode + * @hif_ctx: HIF context + * + * For use in data path + * + * Retrun: void + */ +void hif_enable_fastpath(struct hif_opaque_softc *hif_ctx) +{ + struct hif_softc *scn = HIF_GET_SOFTC(hif_ctx); + + HIF_INFO("Enabling fastpath mode\n"); + scn->fastpath_mode_on = true; +} + +/** + * hif_is_fastpath_mode_enabled - API to query if fasthpath mode is enabled + * @hif_ctx: HIF Context + * + * For use in data path to skip HTC + * + * Return: bool + */ +bool hif_is_fastpath_mode_enabled(struct hif_opaque_softc *hif_ctx) +{ + struct hif_softc *scn = HIF_GET_SOFTC(hif_ctx); + + return scn->fastpath_mode_on; +} + +/** + * hif_get_ce_handle - API to get CE handle for FastPath mode + * @hif_ctx: HIF Context + * @id: CopyEngine Id + * + * API to return CE handle for fastpath mode + * + * Return: void + */ +void *hif_get_ce_handle(struct hif_opaque_softc *hif_ctx, int id) +{ + struct hif_softc *scn = HIF_GET_SOFTC(hif_ctx); + + return scn->ce_id_to_state[id]; +} + /** * ce_h2t_tx_ce_cleanup() Place holder function for H2T CE cleanup. * No processing is required inside this function. @@ -803,13 +850,49 @@ void ce_t2h_msg_ce_cleanup(struct CE_handle *ce_hdl) qdf_nbuf_free(nbuf); } } + +/** + * hif_update_fastpath_recv_bufs_cnt() - Increments the Rx buf count by 1 + * @scn: HIF handle + * + * Datapath Rx CEs are special case, where we reuse all the message buffers. + * Hence we have to post all the entries in the pipe, even, in the beginning + * unlike for other CE pipes where one less than dest_nentries are filled in + * the beginning. + * + * Return: None + */ +static void hif_update_fastpath_recv_bufs_cnt(struct hif_softc *scn) +{ + int pipe_num; + struct HIF_CE_state *hif_state = HIF_GET_CE_STATE(scn); + + if (scn->fastpath_mode_on == false) + return; + + for (pipe_num = 0; pipe_num < scn->ce_count; pipe_num++) { + struct HIF_CE_pipe_info *pipe_info = + &hif_state->pipe_info[pipe_num]; + struct CE_state *ce_state = + scn->ce_id_to_state[pipe_info->pipe_num]; + + if (ce_state->htt_rx_data) + atomic_inc(&pipe_info->recv_bufs_needed); + } +} #else -void ce_h2t_tx_ce_cleanup(struct CE_handle *ce_hdl) +static inline void hif_update_fastpath_recv_bufs_cnt(struct hif_softc *scn) { } -void ce_t2h_msg_ce_cleanup(struct CE_handle *ce_hdl) +static inline bool ce_is_fastpath_enabled(struct hif_softc *scn) { + return false; +} + +static inline bool ce_is_fastpath_handler_registered(struct CE_state *ce_state) +{ + return false; } #endif /* WLAN_FEATURE_FASTPATH */ @@ -1387,6 +1470,8 @@ QDF_STATUS hif_start(struct hif_opaque_softc *hif_ctx) struct hif_softc *scn = HIF_GET_SOFTC(hif_ctx); struct HIF_CE_state *hif_state = HIF_GET_CE_STATE(scn); + hif_update_fastpath_recv_bufs_cnt(scn); + hif_msg_callbacks_install(scn); if (hif_completion_thread_startup(hif_state)) @@ -1400,55 +1485,6 @@ QDF_STATUS hif_start(struct hif_opaque_softc *hif_ctx) return QDF_STATUS_SUCCESS; } -#ifdef WLAN_FEATURE_FASTPATH -/** - * hif_enable_fastpath() Update that we have enabled fastpath mode - * @hif_ctx: HIF context - * - * For use in data path - * - * Retrun: void - */ -void hif_enable_fastpath(struct hif_opaque_softc *hif_ctx) -{ - struct hif_softc *scn = HIF_GET_SOFTC(hif_ctx); - - HIF_INFO("Enabling fastpath mode\n"); - scn->fastpath_mode_on = true; -} - -/** - * hif_is_fastpath_mode_enabled - API to query if fasthpath mode is enabled - * @hif_ctx: HIF Context - * - * For use in data path to skip HTC - * - * Return: bool - */ -bool hif_is_fastpath_mode_enabled(struct hif_opaque_softc *hif_ctx) -{ - struct hif_softc *scn = HIF_GET_SOFTC(hif_ctx); - - return scn->fastpath_mode_on; -} - -/** - * hif_get_ce_handle - API to get CE handle for FastPath mode - * @hif_ctx: HIF Context - * @id: CopyEngine Id - * - * API to return CE handle for fastpath mode - * - * Return: void - */ -void *hif_get_ce_handle(struct hif_opaque_softc *hif_ctx, int id) -{ - struct hif_softc *scn = HIF_GET_SOFTC(hif_ctx); - - return scn->ce_id_to_state[id]; -} -#endif /* WLAN_FEATURE_FASTPATH */ - void hif_recv_buffer_cleanup_on_pipe(struct HIF_CE_pipe_info *pipe_info) { struct hif_softc *scn; @@ -1731,80 +1767,6 @@ void hif_ce_close(struct hif_softc *hif_sc) { } -#ifdef WLAN_FEATURE_FASTPATH -/** - * ce_is_fastpath_enabled() - returns true if fastpath mode is enabled - * @scn: Handle to HIF context - * - * Return: true if fastpath is enabled else false. - */ -bool ce_is_fastpath_enabled(struct hif_opaque_softc *hif_hdl) -{ - return HIF_GET_SOFTC(hif_hdl)->fastpath_mode_on; -} - -/** - * ce_is_fastpath_handler_registered() - return true for datapath CEs and if - * fastpath is enabled. - * @ce_state: handle to copy engine - * - * Return: true if fastpath handler is registered for datapath CE. - */ -bool ce_is_fastpath_handler_registered(struct CE_state *ce_state) -{ - if (ce_state->fastpath_handler) - return true; - else - return false; -} - -/** - * hif_update_fastpath_recv_bufs_cnt() - Increments the Rx buf count by 1 - * @scn: HIF handle - * - * Datapath Rx CEs are special case, where we reuse all the message buffers. - * Hence we have to post all the entries in the pipe, even, in the beginning - * unlike for other CE pipes where one less than dest_nentries are filled in - * the beginning. - * - * Return: None - */ -void hif_update_fastpath_recv_bufs_cnt(struct hif_opaque_softc *hif_hdl) -{ - int pipe_num; - struct hif_softc *scn = HIF_GET_SOFTC(hif_hdl); - struct HIF_CE_state *hif_state = HIF_GET_CE_STATE(scn); - - if (scn->fastpath_mode_on == false) - return; - - for (pipe_num = 0; pipe_num < scn->ce_count; pipe_num++) { - struct HIF_CE_pipe_info *pipe_info = - &hif_state->pipe_info[pipe_num]; - struct CE_state *ce_state = - scn->ce_id_to_state[pipe_info->pipe_num]; - - if (ce_state->htt_rx_data) - atomic_inc(&pipe_info->recv_bufs_needed); - } -} -#else -bool ce_is_fastpath_enabled(struct hif_opaque_softc *scn) -{ - return false; -} - -void hif_update_fastpath_recv_bufs_cnt(struct hif_opaque_softc *scn) -{ -} - -bool ce_is_fastpath_handler_registered(struct CE_state *ce_state) -{ - return false; -} - -#endif /* WLAN_FEATURE_FASTPATH */ - /** * hif_unconfig_ce() - ensure resources from hif_config_ce are freed * @hif_sc: hif context @@ -2003,11 +1965,6 @@ int hif_ce_fastpath_cb_register(fastpath_msg_handler handler, void *context) return QDF_STATUS_SUCCESS; } -#else -int hif_ce_fastpath_cb_register(fastpath_msg_handler handler, void *context) -{ - return QDF_STATUS_SUCCESS; -} #endif #ifdef IPA_OFFLOAD diff --git a/hif/src/ce/ce_service.c b/hif/src/ce/ce_service.c index cb878fd357..476a288040 100644 --- a/hif/src/ce/ce_service.c +++ b/hif/src/ce/ce_service.c @@ -36,9 +36,6 @@ #include "epping_main.h" #include "hif_main.h" #include "hif_debug.h" -#include "ol_txrx_types.h" -#include -#include #ifdef IPA_OFFLOAD #ifdef QCA_WIFI_3_0 @@ -528,14 +525,30 @@ int ce_send_fast(struct CE_handle *copyeng, qdf_nbuf_t *msdus, u_int32_t ctrl_addr = ce_state->ctrl_addr; unsigned int nentries_mask = src_ring->nentries_mask; unsigned int write_index; + unsigned int sw_index; unsigned int frag_len; qdf_nbuf_t msdu; int i; uint64_t dma_addr; - uint32_t user_flags = 0; + uint32_t user_flags; qdf_spin_lock_bh(&ce_state->ce_index_lock); + Q_TARGET_ACCESS_BEGIN(scn); + + src_ring->sw_index = CE_SRC_RING_READ_IDX_GET_FROM_DDR(scn, ctrl_addr); write_index = src_ring->write_index; + sw_index = src_ring->sw_index; + + if (qdf_unlikely(CE_RING_DELTA(nentries_mask, write_index, sw_index - 1) + < (SLOTS_PER_DATAPATH_TX * num_msdus))) { + HIF_ERROR("Source ring full, required %d, available %d", + (SLOTS_PER_DATAPATH_TX * num_msdus), + CE_RING_DELTA(nentries_mask, write_index, sw_index - 1)); + OL_ATH_CE_PKT_ERROR_COUNT_INCR(scn, CE_RING_DELTA_FAIL); + Q_TARGET_ACCESS_END(scn); + qdf_spin_unlock_bh(&ce_state->ce_index_lock); + return 0; + } /* 2 msdus per packet */ for (i = 0; i < num_msdus; i++) { @@ -631,6 +644,7 @@ int ce_send_fast(struct CE_handle *copyeng, qdf_nbuf_t *msdus, } } + Q_TARGET_ACCESS_END(scn); qdf_spin_unlock_bh(&ce_state->ce_index_lock); /* @@ -641,6 +655,44 @@ int ce_send_fast(struct CE_handle *copyeng, qdf_nbuf_t *msdus, ASSERT(i == num_msdus); return i; } + +/** + * ce_is_fastpath_enabled() - returns true if fastpath mode is enabled + * @scn: Handle to HIF context + * + * Return: true if fastpath is enabled else false. + */ +static bool ce_is_fastpath_enabled(struct hif_softc *scn) +{ + return scn->fastpath_mode_on; +} + +/** + * ce_is_fastpath_handler_registered() - return true for datapath CEs and if + * fastpath is enabled. + * @ce_state: handle to copy engine + * + * Return: true if fastpath handler is registered for datapath CE. + */ +static bool ce_is_fastpath_handler_registered(struct CE_state *ce_state) +{ + if (ce_state->fastpath_handler) + return true; + else + return false; +} + + +#else +static inline bool ce_is_fastpath_enabled(struct hif_softc *scn) +{ + return false; +} + +static inline bool ce_is_fastpath_handler_registered(struct CE_state *ce_state) +{ + return false; +} #endif /* WLAN_FEATURE_FASTPATH */ /** @@ -675,9 +727,7 @@ ce_recv_buf_enqueue(struct CE_handle *copyeng, } if ((CE_RING_DELTA(nentries_mask, write_index, sw_index - 1) > 0) || - (ce_is_fastpath_enabled((struct hif_opaque_softc *)scn) && - CE_state->htt_rx_data && - (CE_RING_DELTA(nentries_mask, write_index, sw_index - 1) == 0))) { + (ce_is_fastpath_enabled(scn) && CE_state->htt_rx_data)) { struct CE_dest_desc *dest_ring_base = (struct CE_dest_desc *)dest_ring->base_addr_owner_space; struct CE_dest_desc *dest_desc = @@ -1272,42 +1322,17 @@ void ce_per_engine_servicereap(struct hif_softc *scn, unsigned int ce_id) #endif /*ATH_11AC_TXCOMPACT */ -#ifdef WLAN_FEATURE_FASTPATH - -/** - * ce_tx_completion() - reap off the CE source ring when CE completion happens - * @ce_state: Handle to CE - * @num_tx_cmpls: Number of completions handled - * - * API to reap off the CE source ring when CE completion happens: - * Update number of src_ring entries based on number of completions. - * - * Return: None +/* + * Number of times to check for any pending tx/rx completion on + * a copy engine, this count should be big enough. Once we hit + * this threashold we'll not check for any Tx/Rx comlpetion in same + * interrupt handling. Note that this threashold is only used for + * Rx interrupt processing, this can be used tor Tx as well if we + * suspect any infinite loop in checking for pending Tx completion. */ -static void -ce_tx_completion(struct CE_state *ce_state, uint32_t num_tx_cmpls) -{ - struct CE_ring_state *src_ring = ce_state->src_ring; - uint32_t nentries_mask = src_ring->nentries_mask; - - ASSERT(num_tx_cmpls); - - qdf_spin_lock(&ce_state->ce_index_lock); - - /* - * This locks the index manipulation of this CE with those done - * in ce_send_fast(). - */ - - /* - * Advance the s/w index: - * This effectively simulates completing the CE ring descriptors - */ - src_ring->sw_index = CE_RING_IDX_ADD(nentries_mask, src_ring->sw_index, - num_tx_cmpls); - qdf_spin_unlock(&ce_state->ce_index_lock); -} +#define CE_TXRX_COMP_CHECK_THRESHOLD 20 +#ifdef WLAN_FEATURE_FASTPATH /** * ce_fastpath_rx_handle() - Updates write_index and calls fastpath msg handler * @ce_state: handle to copy engine state @@ -1323,28 +1348,23 @@ static void ce_fastpath_rx_handle(struct CE_state *ce_state, { struct hif_softc *scn = ce_state->scn; struct CE_ring_state *dest_ring = ce_state->dest_ring; - struct CE_state *ce_tx_cmpl_state = scn->ce_id_to_state[CE_HTT_H2T_MSG]; uint32_t nentries_mask = dest_ring->nentries_mask; - uint32_t tx_cmpls; uint32_t write_index; - tx_cmpls = (ce_state->fastpath_handler)(ce_state->context, cmpl_msdus, - num_cmpls); + (ce_state->fastpath_handler)(ce_state->context, cmpl_msdus, num_cmpls); /* Update Destination Ring Write Index */ write_index = dest_ring->write_index; write_index = CE_RING_IDX_ADD(nentries_mask, write_index, num_cmpls); CE_DEST_RING_WRITE_IDX_SET(scn, ctrl_addr, write_index); dest_ring->write_index = write_index; - ce_tx_completion(ce_tx_cmpl_state, tx_cmpls); } -#define MSG_FLUSH_NUM 20 +#define MSG_FLUSH_NUM 6 /** * ce_per_engine_service_fast() - CE handler routine to service fastpath messages * @scn: hif_context - * @ce_id: COpy engine ID - * Function: + * @ce_id: Copy engine ID * 1) Go through the CE ring, and find the completions * 2) For valid completions retrieve context (nbuf) for per_transfer_context[] * 3) Unmap buffer & accumulate in an array. @@ -1353,8 +1373,7 @@ static void ce_fastpath_rx_handle(struct CE_state *ce_state, * Return: void */ -static int -ce_per_engine_service_fast(struct hif_softc *scn, int ce_id) +static void ce_per_engine_service_fast(struct hif_softc *scn, int ce_id) { struct CE_state *ce_state = scn->ce_id_to_state[ce_id]; struct CE_ring_state *dest_ring = ce_state->dest_ring; @@ -1371,6 +1390,7 @@ ce_per_engine_service_fast(struct hif_softc *scn, int ce_id) qdf_nbuf_t cmpl_msdus[MSG_FLUSH_NUM]; uint32_t ctrl_addr = ce_state->ctrl_addr; uint32_t nbuf_cmpl_idx = 0; + unsigned int more_comp_cnt = 0; more_data: if (ce_int_status == (1 << ce_id)) { @@ -1422,9 +1442,10 @@ more_data: */ paddr_lo = QDF_NBUF_CB_PADDR(nbuf); - OS_SYNC_SINGLE_FOR_CPU(scn->qdf_dev->dev, paddr_lo, - (skb_end_pointer(nbuf) - (nbuf)->data), - DMA_FROM_DEVICE); + qdf_mem_dma_sync_single_for_cpu(scn->qdf_dev, + paddr_lo, + (skb_end_pointer(nbuf) - (nbuf)->data), + DMA_FROM_DEVICE); qdf_nbuf_put_tail(nbuf, nbytes); qdf_assert_always(nbuf->data != NULL); @@ -1462,31 +1483,24 @@ more_data: CE_ENGINE_INT_STATUS_CLEAR(scn, ctrl_addr, HOST_IS_COPY_COMPLETE_MASK); } - ce_int_status = CE_ENGINE_INT_STATUS_GET(scn, ctrl_addr); - if (ce_int_status & CE_WATERMARK_MASK) - goto more_data; - - return QDF_STATUS_SUCCESS; + if (ce_recv_entries_done_nolock(scn, ce_state)) { + if (more_comp_cnt++ < CE_TXRX_COMP_CHECK_THRESHOLD) { + goto more_data; + } else { + HIF_ERROR("%s:Potential infinite loop detected during Rx processing nentries_mask:0x%x sw read_idx:0x%x hw read_idx:0x%x", + __func__, nentries_mask, + ce_state->dest_ring->sw_index, + CE_DEST_RING_READ_IDX_GET(scn, ctrl_addr)); + } + } } #else -static int -ce_per_engine_service_fast(struct hif_softc *scn, int ce_id) +static void ce_per_engine_service_fast(struct hif_softc *scn, int ce_id) { - return QDF_STATUS_E_FAILURE; } #endif /* WLAN_FEATURE_FASTPATH */ -/* - * Number of times to check for any pending tx/rx completion on - * a copy engine, this count should be big enough. Once we hit - * this threashold we'll not check for any Tx/Rx comlpetion in same - * interrupt handling. Note that this threashold is only used for - * Rx interrupt processing, this can be used tor Tx as well if we - * suspect any infinite loop in checking for pending Tx completion. - */ -#define CE_TXRX_COMP_CHECK_THRESHOLD 20 - /* * Guts of interrupt handler for per-engine interrupts on a particular CE. * @@ -1524,12 +1538,12 @@ int ce_per_engine_service(struct hif_softc *scn, unsigned int CE_id) * With below check we make sure CE we are handling is datapath CE and * fastpath is enabled. */ - if (ce_is_fastpath_handler_registered(CE_state)) + if (ce_is_fastpath_handler_registered(CE_state)) { /* For datapath only Rx CEs */ - if (!ce_per_engine_service_fast(scn, CE_id)) { - qdf_spin_unlock(&CE_state->ce_index_lock); - return 0; - } + ce_per_engine_service_fast(scn, CE_id); + qdf_spin_unlock(&CE_state->ce_index_lock); + return CE_state->receive_count; + } /* Clear force_break flag and re-initialize receive_count to 0 */ diff --git a/qdf/inc/osdep.h b/qdf/inc/osdep.h index 69536d7c9d..24c0601287 100644 --- a/qdf/inc/osdep.h +++ b/qdf/inc/osdep.h @@ -184,16 +184,4 @@ static inline unsigned char *os_malloc(osdev_t nic_dev, #define SET_NETDEV_DEV(ndev, pdev) #endif -#define OS_SYNC_SINGLE_FOR_CPU(pdev, paddr_lo, len, oprn) \ -{ \ - dma_sync_single_for_cpu(pdev, paddr_lo, len, oprn); \ -} - -#define OS_SYNC_SINGLE_FOR_DEVICE(pdev, paddr_lo, len, oprn) \ -{ \ - dma_sync_single_for_device(pdev, paddr_lo, len, oprn);\ -} - -#define SLOTS_PER_TX 2 - #endif /* end of _OSDEP_H */ diff --git a/qdf/inc/qdf_mem.h b/qdf/inc/qdf_mem.h index 1de5a149af..8ac3308751 100644 --- a/qdf/inc/qdf_mem.h +++ b/qdf/inc/qdf_mem.h @@ -276,6 +276,10 @@ void qdf_mem_dma_sync_single_for_device(qdf_device_t osdev, qdf_size_t size, __dma_data_direction direction); +void qdf_mem_dma_sync_single_for_cpu(qdf_device_t osdev, + qdf_dma_addr_t bus_addr, + qdf_size_t size, + __dma_data_direction direction); /** * qdf_str_len() - returns the length of a string * @str: input string diff --git a/qdf/inc/qdf_nbuf.h b/qdf/inc/qdf_nbuf.h index f98dfe84bc..bc393610b5 100644 --- a/qdf/inc/qdf_nbuf.h +++ b/qdf/inc/qdf_nbuf.h @@ -429,8 +429,7 @@ static inline void qdf_nbuf_free(qdf_nbuf_t buf) * put, or NULL if there is not enough room in this buf. */ -static inline void -qdf_nbuf_init_fast(qdf_nbuf_t nbuf) +static inline void qdf_nbuf_init_fast(qdf_nbuf_t nbuf) { atomic_set(&nbuf->users, 1); nbuf->data = nbuf->head + NET_SKB_PAD; diff --git a/qdf/linux/src/qdf_mem.c b/qdf/linux/src/qdf_mem.c index d6897c1df6..53c948d94c 100644 --- a/qdf/linux/src/qdf_mem.c +++ b/qdf/linux/src/qdf_mem.c @@ -935,19 +935,37 @@ EXPORT_SYMBOL(qdf_mem_free_consistent); * @osdev: OS device handle * @bus_addr: dma address to give to the device * @size: Size of the memory block - * @direction: direction data will be dma'ed + * @direction: direction data will be DMAed * * Assign memory to the remote device. * The cache lines are flushed to ram or invalidated as needed. * * Return: none */ -inline void -qdf_mem_dma_sync_single_for_device(qdf_device_t osdev, qdf_dma_addr_t bus_addr, - qdf_size_t size, - enum dma_data_direction direction) +void qdf_mem_dma_sync_single_for_device(qdf_device_t osdev, + qdf_dma_addr_t bus_addr, + qdf_size_t size, + enum dma_data_direction direction) { dma_sync_single_for_device(osdev->dev, bus_addr, size, direction); } EXPORT_SYMBOL(qdf_mem_dma_sync_single_for_device); +/** + * qdf_mem_dma_sync_single_for_cpu() - assign memory to CPU + * @osdev: OS device handle + * @bus_addr: dma address to give to the cpu + * @size: Size of the memory block + * @direction: direction data will be DMAed + * + * Assign memory to the CPU. + * + * Return: none + */ +void qdf_mem_dma_sync_single_for_cpu(qdf_device_t osdev, + qdf_dma_addr_t bus_addr, + qdf_size_t size, + enum dma_data_direction direction) +{ + dma_sync_single_for_cpu(osdev->dev, bus_addr, size, direction); +}