diff --git a/dp/wifi3.0/dp_main.c b/dp/wifi3.0/dp_main.c index fbe14d959f63..e56e4af15c5e 100644 --- a/dp/wifi3.0/dp_main.c +++ b/dp/wifi3.0/dp_main.c @@ -1216,9 +1216,9 @@ static int dp_hw_link_desc_pool_setup(struct dp_soc *soc) hal_idle_list_scatter_buf_size(soc->hal_soc); num_entries_per_buf = hal_idle_scatter_buf_num_entries( soc->hal_soc, soc->wbm_idle_scatter_buf_size); - num_scatter_bufs = (total_mem_size / - soc->wbm_idle_scatter_buf_size) + (total_mem_size % - soc->wbm_idle_scatter_buf_size) ? 1 : 0; + num_scatter_bufs = hal_idle_list_num_scatter_bufs( + soc->hal_soc, total_mem_size, + soc->wbm_idle_scatter_buf_size); for (i = 0; i < num_scatter_bufs; i++) { soc->wbm_idle_scatter_buf_base_vaddr[i] = @@ -1259,12 +1259,16 @@ static int dp_hw_link_desc_pool_setup(struct dp_soc *soc) num_link_descs--; desc_id++; paddr += link_desc_size; + rem_entries--; if (rem_entries) { - rem_entries--; - scatter_buf_ptr += link_desc_size; + scatter_buf_ptr += entry_size; } else { rem_entries = num_entries_per_buf; scatter_buf_num++; + + if (scatter_buf_num >= num_scatter_bufs) + break; + scatter_buf_ptr = (uint8_t *)( soc->wbm_idle_scatter_buf_base_vaddr[ scatter_buf_num]); @@ -1277,8 +1281,8 @@ static int dp_hw_link_desc_pool_setup(struct dp_soc *soc) soc->wbm_idle_scatter_buf_base_vaddr, num_scatter_bufs, soc->wbm_idle_scatter_buf_size, (uint32_t)(scatter_buf_ptr - - (uint8_t *)(soc->wbm_idle_scatter_buf_base_vaddr[ - scatter_buf_num]))); + (uint8_t *)(soc->wbm_idle_scatter_buf_base_vaddr[ + scatter_buf_num-1])), total_link_descs); } return 0; diff --git a/hal/wifi3.0/hal_api.h b/hal/wifi3.0/hal_api.h index 3f35fbf2b7e0..52f5173cd58a 100644 --- a/hal/wifi3.0/hal_api.h +++ b/hal/wifi3.0/hal_api.h @@ -754,6 +754,7 @@ static inline void hal_srng_access_end_reap(void *hal_soc, void *hal_ring) #define LINK_DESC_SIZE (NUM_OF_DWORDS_RX_MSDU_LINK << 2) #define LINK_DESC_ALIGN 128 +#define ADDRESS_MATCH_TAG_VAL 0x5 /* Number of mpdu link pointers is 9 in case of TX_MPDU_QUEUE_HEAD and 14 in * of TX_MPDU_QUEUE_EXT. We are defining a common average count here */ @@ -873,6 +874,27 @@ static inline uint32_t hal_idle_scatter_buf_num_entries(void *hal_soc, hal_srng_get_entrysize(hal_soc, WBM_IDLE_LINK); } +/** + * hal_idle_list_num_scatter_bufs - Get the number of sctater buffer + * each given buffer size + * + * @hal_soc: Opaque HAL SOC handle + * @total_mem: size of memory to be scattered + * @scatter_buf_size: Size of scatter buffer + * + */ +static inline uint32_t hal_idle_list_num_scatter_bufs(void *hal_soc, + uint32_t total_mem, uint32_t scatter_buf_size) +{ + uint8_t rem = (total_mem % (scatter_buf_size - + WBM_IDLE_SCATTER_BUF_NEXT_PTR_SIZE)) ? 1 : 0; + + uint32_t num_scatter_bufs = (total_mem / (scatter_buf_size - + WBM_IDLE_SCATTER_BUF_NEXT_PTR_SIZE)) + rem; + + return num_scatter_bufs; +} + /** * hal_idle_scatter_buf_setup - Setup scattered idle list using the buffer list * provided @@ -882,12 +904,15 @@ static inline uint32_t hal_idle_scatter_buf_num_entries(void *hal_soc, * @idle_scatter_bufs_base_vaddr: Array of virtual base addresses * @num_scatter_bufs: Number of scatter buffers in the above lists * @scatter_buf_size: Size of each scatter buffer + * @last_buf_end_offset: Offset to the last entry + * @num_entries: Total entries of all scatter bufs * */ extern void hal_setup_link_idle_list(void *hal_soc, qdf_dma_addr_t scatter_bufs_base_paddr[], void *scatter_bufs_base_vaddr[], uint32_t num_scatter_bufs, - uint32_t scatter_buf_size, uint32_t last_buf_end_offset); + uint32_t scatter_buf_size, uint32_t last_buf_end_offset, + uint32_t num_entries); /* REO parameters to be passed to hal_reo_setup */ struct hal_reo_params { diff --git a/hal/wifi3.0/hal_wbm.c b/hal/wifi3.0/hal_wbm.c index 8ef809897842..5b0945c74aff 100644 --- a/hal/wifi3.0/hal_wbm.c +++ b/hal/wifi3.0/hal_wbm.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016 The Linux Foundation. All rights reserved. + * Copyright (c) 2016-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 @@ -27,44 +27,83 @@ * @scatter_bufs_base_vaddr: Array of virtual base addresses * @num_scatter_bufs: Number of scatter buffers in the above lists * @scatter_buf_size: Size of each scatter buffer + * @last_buf_end_offset: Offset to the last entry + * @num_entries: Total entries of all scatter bufs * */ void hal_setup_link_idle_list(void *hal_soc, qdf_dma_addr_t scatter_bufs_base_paddr[], void *scatter_bufs_base_vaddr[], uint32_t num_scatter_bufs, - uint32_t scatter_buf_size, uint32_t last_buf_end_offset) + uint32_t scatter_buf_size, uint32_t last_buf_end_offset, + uint32_t num_entries) { int i; uint32_t *prev_buf_link_ptr = NULL; struct hal_soc *soc = (struct hal_soc *)hal_soc; + uint32_t reg_scatter_buf_size, reg_tot_scatter_buf_size; /* Link the scatter buffers */ for (i = 0; i < num_scatter_bufs; i++) { if (i > 0) { prev_buf_link_ptr[0] = scatter_bufs_base_paddr[i] & 0xffffffff; - prev_buf_link_ptr[1] = - ((uint64_t)(scatter_bufs_base_paddr[i]) >> 32) & - HWIO_WBM_R0_SCATTERED_LINK_DESC_LIST_BASE_MSB_BASE_ADDRESS_39_32_BMSK; + prev_buf_link_ptr[1] = HAL_SM( + HWIO_WBM_R0_SCATTERED_LINK_DESC_LIST_BASE_MSB, + BASE_ADDRESS_39_32, + ((uint64_t)(scatter_bufs_base_paddr[i]) + >> 32)) | HAL_SM( + HWIO_WBM_R0_SCATTERED_LINK_DESC_LIST_BASE_MSB, + ADDRESS_MATCH_TAG, + ADDRESS_MATCH_TAG_VAL); } prev_buf_link_ptr = (uint32_t *)(scatter_bufs_base_vaddr[i] + scatter_buf_size - WBM_IDLE_SCATTER_BUF_NEXT_PTR_SIZE); } - /* TBD: Setup IDLE_LIST_CTRL and IDLE_LIST_SIZE registers - current - * definitions in HW headers doesn't match those in WBM MLD document - * pending confirmation from HW team + /* TBD: Register programming partly based on MLD & the rest based on + * inputs from HW team. Not complete yet. */ + reg_scatter_buf_size = (scatter_buf_size - + WBM_IDLE_SCATTER_BUF_NEXT_PTR_SIZE)/64; + reg_tot_scatter_buf_size = ((scatter_buf_size - + WBM_IDLE_SCATTER_BUF_NEXT_PTR_SIZE) * num_scatter_bufs)/64; + + HAL_REG_WRITE(soc, + HWIO_WBM_R0_IDLE_LIST_CONTROL_ADDR( + SEQ_WCSS_UMAC_WBM_REG_OFFSET), + HAL_SM(HWIO_WBM_R0_IDLE_LIST_CONTROL, SCATTER_BUFFER_SIZE, + reg_scatter_buf_size) | + HAL_SM(HWIO_WBM_R0_IDLE_LIST_CONTROL, LINK_DESC_IDLE_LIST_MODE, + 0x1)); + + HAL_REG_WRITE(soc, + HWIO_WBM_R0_IDLE_LIST_SIZE_ADDR( + SEQ_WCSS_UMAC_WBM_REG_OFFSET), + HAL_SM(HWIO_WBM_R0_IDLE_LIST_SIZE, + SCATTER_RING_SIZE_OF_IDLE_LINK_DESC_LIST, + reg_tot_scatter_buf_size)); + HAL_REG_WRITE(soc, HWIO_WBM_R0_SCATTERED_LINK_DESC_LIST_BASE_LSB_ADDR( SEQ_WCSS_UMAC_WBM_REG_OFFSET), scatter_bufs_base_paddr[0] & 0xffffffff); + HAL_REG_WRITE(soc, HWIO_WBM_R0_SCATTERED_LINK_DESC_LIST_BASE_MSB_ADDR( SEQ_WCSS_UMAC_WBM_REG_OFFSET), ((uint64_t)(scatter_bufs_base_paddr[0]) >> 32) & HWIO_WBM_R0_SCATTERED_LINK_DESC_LIST_BASE_MSB_BASE_ADDRESS_39_32_BMSK); + + HAL_REG_WRITE(soc, + HWIO_WBM_R0_SCATTERED_LINK_DESC_LIST_BASE_MSB_ADDR( + SEQ_WCSS_UMAC_WBM_REG_OFFSET), + HAL_SM(HWIO_WBM_R0_SCATTERED_LINK_DESC_LIST_BASE_MSB, + BASE_ADDRESS_39_32, ((uint64_t)(scatter_bufs_base_paddr[0]) + >> 32)) | + HAL_SM(HWIO_WBM_R0_SCATTERED_LINK_DESC_LIST_BASE_MSB, + ADDRESS_MATCH_TAG, ADDRESS_MATCH_TAG_VAL)); + /* ADDRESS_MATCH_TAG field in the above register is expected to match * with the upper bits of link pointer. The above write sets this field * to zero and we are also setting the upper bits of link pointers to @@ -75,15 +114,16 @@ void hal_setup_link_idle_list(void *hal_soc, HAL_REG_WRITE(soc, HWIO_WBM_R0_SCATTERED_LINK_DESC_PTR_HEAD_INFO_IX0_ADDR( SEQ_WCSS_UMAC_WBM_REG_OFFSET), - scatter_bufs_base_paddr[0] & 0xffffffff); + scatter_bufs_base_paddr[num_scatter_bufs-1] & 0xffffffff); HAL_REG_WRITE(soc, HWIO_WBM_R0_SCATTERED_LINK_DESC_PTR_HEAD_INFO_IX1_ADDR( SEQ_WCSS_UMAC_WBM_REG_OFFSET), HAL_SM(HWIO_WBM_R0_SCATTERED_LINK_DESC_PTR_HEAD_INFO_IX1, BUFFER_ADDRESS_39_32, - ((uint64_t)(scatter_bufs_base_paddr[0]) >> 32)) | + ((uint64_t)(scatter_bufs_base_paddr[num_scatter_bufs-1]) + >> 32)) | HAL_SM(HWIO_WBM_R0_SCATTERED_LINK_DESC_PTR_HEAD_INFO_IX1, - HEAD_POINTER_OFFSET, 0)); + HEAD_POINTER_OFFSET, last_buf_end_offset >> 2)); HAL_REG_WRITE(soc, HWIO_WBM_R0_SCATTERED_LINK_DESC_PTR_HEAD_INFO_IX0_ADDR( @@ -93,14 +133,25 @@ void hal_setup_link_idle_list(void *hal_soc, HAL_REG_WRITE(soc, HWIO_WBM_R0_SCATTERED_LINK_DESC_PTR_TAIL_INFO_IX0_ADDR( SEQ_WCSS_UMAC_WBM_REG_OFFSET), - scatter_bufs_base_paddr[num_scatter_bufs - 1] & 0xffffffff); + scatter_bufs_base_paddr[0] & 0xffffffff); HAL_REG_WRITE(soc, HWIO_WBM_R0_SCATTERED_LINK_DESC_PTR_TAIL_INFO_IX1_ADDR( SEQ_WCSS_UMAC_WBM_REG_OFFSET), HAL_SM(HWIO_WBM_R0_SCATTERED_LINK_DESC_PTR_TAIL_INFO_IX1, BUFFER_ADDRESS_39_32, - ((uint64_t)(scatter_bufs_base_paddr[num_scatter_bufs - 1]) >> + ((uint64_t)(scatter_bufs_base_paddr[0]) >> 32)) | HAL_SM(HWIO_WBM_R0_SCATTERED_LINK_DESC_PTR_TAIL_INFO_IX1, - TAIL_POINTER_OFFSET, last_buf_end_offset << 2)); + TAIL_POINTER_OFFSET, 0)); + + HAL_REG_WRITE(soc, + HWIO_WBM_R0_SCATTERED_LINK_DESC_PTR_HP_ADDR( + SEQ_WCSS_UMAC_WBM_REG_OFFSET), + 2*num_entries); + + /* Enable the SRNG */ + HAL_REG_WRITE(soc, + HWIO_WBM_R0_WBM_IDLE_LINK_RING_MISC_ADDR( + SEQ_WCSS_UMAC_WBM_REG_OFFSET), + 0x40); }