qcacmn: Add qdf API to align the allocated memory

Define qdf_aligned_mem_alloc_consistent() and qdf_aligned_malloc() which
allocates the memory and checks if allocated base address is aligned with
ring_base_align. If not, it frees the memory and re-allocates by adding
7 bytes to alloc_size and returns aligned address to the caller.

Change-Id: I412153c20e4e4566450b006356fe78d98f1fd3f0
Acked-by: Shashikala Prabhu <pshashik@codeaurora.org>
CRs-Fixed: 2336697
This commit is contained in:
Shashikala Prabhu
2018-11-05 16:44:29 +05:30
committed by nshrivas
vanhempi 74e6d8b510
commit f09216fe1b
2 muutettua tiedostoa jossa 117 lisäystä ja 0 poistoa

Näytä tiedosto

@@ -259,6 +259,58 @@ void qdf_mem_free_consistent(qdf_device_t osdev, void *dev,
#endif /* MEMORY_DEBUG */ #endif /* MEMORY_DEBUG */
/**
* qdf_aligned_malloc() - allocates aligned QDF memory.
* @size: Number of bytes of memory to allocate.
* @ring_base_align: Base address alignment.
* @vaddr_unaligned: Unaligned virtual address.
* @func: Function name of the call site.
* @line: Line number of the call site.
*
* This function will dynamically allocate the specified number of bytes of
* memory. Checks if the allocated base address is aligned with base_align.
* If not, it frees the allocated memory, adds base_align to alloc size and
* re-allocates the memory.
*
* Return:
* Upon successful allocate, returns an aligned base address of the allocated
* memory. If this function is unable to allocate the amount of memory
* specified (for any reason) it returns NULL.
*/
#define qdf_aligned_malloc(size, ring_base_align, vaddr_unaligned) \
qdf_aligned_malloc_fl(size, ring_base_align, vaddr_unaligned, \
__func__, __LINE__)
void *qdf_aligned_malloc_fl(qdf_size_t size, uint32_t ring_base_align,
void **vaddr_unaligned,
const char *func, uint32_t line);
/**
* qdf_aligned_mem_alloc_consistent() - allocates consistent qdf memory
* @osdev: OS device handle
* @dev: Pointer to device handle
* @size: Size to be allocated
* @vaddr_unaligned: Unaligned virtual address.
* @paddr_unaligned: Unaligned physical address.
* @paddr_aligned: Aligned physical address.
* @ring_base_align: Base address alignment.
* @func: Function name of the call site.
* @line: Line number of the call site.
*
* Return: pointer of allocated memory or null if memory alloc fails.
*/
#define qdf_aligned_mem_alloc_consistent(osdev, dev, size, vaddr_unaligned, \
paddr_unaligned, paddr_aligned, ring_base_align) \
qdf_aligned_mem_alloc_consistent_fl(osdev, dev, size, vaddr_unaligned, \
paddr_unaligned, paddr_aligned, \
ring_base_align, __func__, __LINE__)
void *qdf_aligned_mem_alloc_consistent_fl(
qdf_device_t osdev, void *dev, qdf_size_t size,
void **vaddr_unaligned, qdf_dma_addr_t *paddr_unaligned,
qdf_dma_addr_t *paddr_aligned, uint32_t ring_base_align,
const char *func, uint32_t line);
void *qdf_mem_alloc_outline(qdf_device_t osdev, qdf_size_t size); void *qdf_mem_alloc_outline(qdf_device_t osdev, qdf_size_t size);
void qdf_mem_set_io(void *ptr, uint32_t num_bytes, uint32_t value); void qdf_mem_set_io(void *ptr, uint32_t num_bytes, uint32_t value);

Näytä tiedosto

@@ -1200,6 +1200,35 @@ void *qdf_mem_malloc_atomic_fl(size_t size, const char *func, uint32_t line)
} }
qdf_export_symbol(qdf_mem_malloc_atomic_fl); qdf_export_symbol(qdf_mem_malloc_atomic_fl);
void *qdf_aligned_malloc_fl(qdf_size_t size, uint32_t ring_base_align,
void **vaddr_unaligned,
const char *func, uint32_t line)
{
void *vaddr_aligned;
*vaddr_unaligned = qdf_mem_malloc(size);
if (!*vaddr_unaligned) {
qdf_warn("Failed to alloc %zuB @ %s:%d", size, func, line);
return NULL;
}
if ((unsigned long)(*vaddr_unaligned) % ring_base_align) {
qdf_mem_free(*vaddr_unaligned);
*vaddr_unaligned = qdf_mem_malloc(size + ring_base_align - 1);
if (!*vaddr_unaligned) {
qdf_warn("Failed to alloc %zuB @ %s:%d",
size, func, line);
return NULL;
}
}
vaddr_aligned = (*vaddr_unaligned) +
((unsigned long)(*vaddr_unaligned) % ring_base_align);
return vaddr_aligned;
}
qdf_export_symbol(qdf_aligned_malloc_fl);
/** /**
* qdf_mem_free() - free QDF memory * qdf_mem_free() - free QDF memory
* @ptr: Pointer to the starting address of the memory to be free'd. * @ptr: Pointer to the starting address of the memory to be free'd.
@@ -1768,6 +1797,42 @@ qdf_export_symbol(qdf_mem_free_consistent);
#endif /* MEMORY_DEBUG */ #endif /* MEMORY_DEBUG */
void *qdf_aligned_mem_alloc_consistent_fl(
qdf_device_t osdev, void *dev, qdf_size_t size,
void **vaddr_unaligned, qdf_dma_addr_t *paddr_unaligned,
qdf_dma_addr_t *paddr_aligned, uint32_t ring_base_align,
const char *func, uint32_t line)
{
void *vaddr_aligned;
*vaddr_unaligned = qdf_mem_alloc_consistent(osdev, dev, size,
paddr_unaligned);
if (!*vaddr_unaligned) {
qdf_warn("Failed to alloc %zuB @ %s:%d", size, func, line);
return NULL;
}
if ((unsigned long)(*vaddr_unaligned) % ring_base_align) {
qdf_mem_free_consistent(osdev, dev, size, *vaddr_unaligned,
*paddr_unaligned, 0);
*vaddr_unaligned = qdf_mem_alloc_consistent(osdev, dev,
size + ring_base_align - 1, paddr_unaligned);
if (!*vaddr_unaligned) {
qdf_warn("Failed to alloc %zuB @ %s:%d",
size, func, line);
return NULL;
}
}
vaddr_aligned = *vaddr_unaligned +
((unsigned long)(*vaddr_unaligned) % ring_base_align);
*paddr_aligned = *paddr_unaligned + ((unsigned long)(vaddr_aligned) -
(unsigned long)(*vaddr_unaligned));
return vaddr_aligned;
}
qdf_export_symbol(qdf_aligned_mem_alloc_consistent_fl);
/** /**
* qdf_mem_dma_sync_single_for_device() - assign memory to device * qdf_mem_dma_sync_single_for_device() - assign memory to device
* @osdev: OS device handle * @osdev: OS device handle