blob: 6ba0e30b865bbb54ed78cee7944a14be17a8167c [file] [log] [blame]
/*
* Copyright (c) 2011,2013,2015-2016 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
*
* 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.
*/
/*
* This file was originally distributed by Qualcomm Atheros, Inc.
* under proprietary terms before Copyright ownership was assigned
* to the Linux Foundation.
*/
/**
* @ingroup adf_os_public
* @file adf_os_mem.h
* This file abstracts memory operations.
*/
#ifndef _ADF_OS_MEM_H
#define _ADF_OS_MEM_H
#include <adf_os_types.h>
#include <adf_os_mem_pvt.h>
#include "vos_cnss.h"
#ifdef CONFIG_WCNSS_MEM_PRE_ALLOC
#include <net/cnss_prealloc.h>
#endif
#include <i_vos_types.h>
/**
* struct adf_os_mem_dma_page_t - Allocated dmaable page
* @page_v_addr_start: Page start virtual address
* @page_v_addr_end: Page end virtual address
* @page_p_addr: Page start physical address
*/
struct adf_os_mem_dma_page_t {
char *page_v_addr_start;
char *page_v_addr_end;
adf_os_dma_addr_t page_p_addr;
};
/**
* struct adf_os_mem_multi_page_t - multiple page allocation information storage
* @num_element_per_page: Number of element in single page
* @num_pages: Number of allocation needed pages
* @dma_pages: page information storage in case of coherent memory
* @cacheable_pages: page information storage in case of cacheable memory
*/
struct adf_os_mem_multi_page_t {
uint16_t num_element_per_page;
uint16_t num_pages;
struct adf_os_mem_dma_page_t *dma_pages;
void **cacheable_pages;
};
#ifdef MEMORY_DEBUG
#define adf_os_mem_alloc(_osdev, _size) adf_os_mem_alloc_debug(_osdev,\
_size, __FILE__, __LINE__)
void *
adf_os_mem_alloc_debug(adf_os_device_t osdev, adf_os_size_t size,
const char *fileName, a_uint32_t lineNum);
#define adf_os_mem_free(_buf) adf_os_mem_free_debug(_buf)
void
adf_os_mem_free_debug(void *buf);
#else
/**
* @brief Allocate a memory buffer. Note this call can block.
*
* @param[in] size buffer size
*
* @return Buffer pointer or NULL if there's not enough memory.
*/
static inline void *
adf_os_mem_alloc(adf_os_device_t osdev, adf_os_size_t size)
{
#ifdef CONFIG_WCNSS_MEM_PRE_ALLOC
void *p_mem;
#endif
#ifdef CONFIG_WCNSS_MEM_PRE_ALLOC
if (size > WCNSS_PRE_ALLOC_GET_THRESHOLD)
{
p_mem = wcnss_prealloc_get(size);
if (NULL != p_mem)
return p_mem;
}
#endif
return __adf_os_mem_alloc(osdev, size);
}
/**
* @brief Free malloc'ed buffer
*
* @param[in] buf buffer pointer allocated by @ref adf_os_mem_alloc
*/
static inline void
adf_os_mem_free(void *buf)
{
#ifdef CONFIG_WCNSS_MEM_PRE_ALLOC
if (wcnss_prealloc_put(buf))
{
return;
}
#endif
__adf_os_mem_free(buf);
}
#endif
void *
adf_os_mem_alloc_outline(adf_os_device_t osdev, adf_os_size_t size);
void
adf_os_mem_free_outline(void *buf);
static inline void *
adf_os_mem_alloc_consistent(
adf_os_device_t osdev, adf_os_size_t size, adf_os_dma_addr_t *paddr, adf_os_dma_context_t mctx)
{
return __adf_os_mem_alloc_consistent(osdev, size, paddr, mctx);
}
static inline void
adf_os_mem_free_consistent(
adf_os_device_t osdev,
adf_os_size_t size,
void *vaddr,
adf_os_dma_addr_t paddr,
adf_os_dma_context_t memctx)
{
__adf_os_mem_free_consistent(osdev, size, vaddr, paddr, memctx);
}
/**
* @brief Move a memory buffer. Overlapping regions are not allowed.
*
* @param[in] dst destination address
* @param[in] src source address
* @param[in] size buffer size
*/
static inline __ahdecl void
adf_os_mem_copy(void *dst, const void *src, adf_os_size_t size)
{
__adf_os_mem_copy(dst, src, size);
}
/**
* @brief Does a non-destructive copy of memory buffer
*
* @param[in] dst destination address
* @param[in] src source address
* @param[in] size buffer size
*/
static inline void
adf_os_mem_move(void *dst, void *src, adf_os_size_t size)
{
__adf_os_mem_move(dst,src,size);
}
/**
* @brief Fill a memory buffer
*
* @param[in] buf buffer to be filled
* @param[in] b byte to fill
* @param[in] size buffer size
*/
static inline void
adf_os_mem_set(void *buf, a_uint8_t b, adf_os_size_t size)
{
__adf_os_mem_set(buf, b, size);
}
/**
* @brief Zero a memory buffer
*
* @param[in] buf buffer to be zeroed
* @param[in] size buffer size
*/
static inline __ahdecl void
adf_os_mem_zero(void *buf, adf_os_size_t size)
{
__adf_os_mem_zero(buf, size);
}
void
adf_os_mem_zero_outline(void *buf, adf_os_size_t size);
/**
* @brief Compare two memory buffers
*
* @param[in] buf1 first buffer
* @param[in] buf2 second buffer
* @param[in] size buffer size
*
* @retval 0 equal
* @retval 1 not equal
*/
static inline int
adf_os_mem_cmp(const void *buf1, const void *buf2, adf_os_size_t size)
{
return __adf_os_mem_cmp(buf1, buf2, size);
}
/**
* @brief Compare two strings
*
* @param[in] str1 First string
* @param[in] str2 Second string
*
* @retval 0 equal
* @retval >0 not equal, if str1 sorts lexicographically after str2
* @retval <0 not equal, if str1 sorts lexicographically before str2
*/
static inline a_int32_t
adf_os_str_cmp(const char *str1, const char *str2)
{
return __adf_os_str_cmp(str1, str2);
}
/**
* @brief Returns the length of a string
*
* @param[in] str input string
*
* @return length of string
*/
static inline a_int32_t
adf_os_str_len(const char *str)
{
return (a_int32_t)__adf_os_str_len(str);
}
void adf_os_mem_multi_pages_alloc(adf_os_device_t osdev,
struct adf_os_mem_multi_page_t *pages,
size_t element_size,
uint16_t element_num,
adf_os_dma_context_t memctxt,
bool cacheable);
void adf_os_mem_multi_pages_free(adf_os_device_t osdev,
struct adf_os_mem_multi_page_t *pages,
adf_os_dma_context_t memctxt,
bool cacheable);
#endif