mirror of https://github.com/brektrou/rtl8821CU
				
				
				
			
			You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
	
	
		
			129 lines
		
	
	
		
			3.3 KiB
		
	
	
	
		
			C
		
	
			
		
		
	
	
			129 lines
		
	
	
		
			3.3 KiB
		
	
	
	
		
			C
		
	
/******************************************************************************
 | 
						|
 *
 | 
						|
 * Copyright(c) 2016 - 2017 Realtek Corporation.
 | 
						|
 *
 | 
						|
 * This program is free software; you can redistribute it and/or modify it
 | 
						|
 * under the terms of version 2 of the GNU General Public License as
 | 
						|
 * published by the Free Software Foundation.
 | 
						|
 *
 | 
						|
 * This program is distributed in the hope that it will be useful, but WITHOUT
 | 
						|
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 | 
						|
 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
 | 
						|
 * more details.
 | 
						|
 *
 | 
						|
 *****************************************************************************/
 | 
						|
 | 
						|
#include <drv_types.h>
 | 
						|
#include <rtw_mem.h>
 | 
						|
 | 
						|
MODULE_LICENSE("GPL");
 | 
						|
MODULE_DESCRIPTION("Realtek Wireless Lan Driver");
 | 
						|
MODULE_AUTHOR("Realtek Semiconductor Corp.");
 | 
						|
MODULE_VERSION("DRIVERVERSION");
 | 
						|
 | 
						|
struct sk_buff_head rtk_skb_mem_q;
 | 
						|
struct u8 *rtk_buf_mem[NR_RECVBUFF];
 | 
						|
 | 
						|
struct u8	*rtw_get_buf_premem(int index)
 | 
						|
{
 | 
						|
	printk("%s, rtk_buf_mem index : %d\n", __func__, index);
 | 
						|
	return rtk_buf_mem[index];
 | 
						|
}
 | 
						|
 | 
						|
u16 rtw_rtkm_get_buff_size(void)
 | 
						|
{
 | 
						|
	return MAX_RTKM_RECVBUF_SZ;
 | 
						|
}
 | 
						|
EXPORT_SYMBOL(rtw_rtkm_get_buff_size);
 | 
						|
 | 
						|
u8 rtw_rtkm_get_nr_recv_skb(void)
 | 
						|
{
 | 
						|
	return MAX_RTKM_NR_PREALLOC_RECV_SKB;
 | 
						|
}
 | 
						|
EXPORT_SYMBOL(rtw_rtkm_get_nr_recv_skb);
 | 
						|
 | 
						|
struct sk_buff *rtw_alloc_skb_premem(u16 in_size)
 | 
						|
{
 | 
						|
	struct sk_buff *skb = NULL;
 | 
						|
 | 
						|
	if (in_size > MAX_RTKM_RECVBUF_SZ) {
 | 
						|
		pr_info("warning %s: driver buffer size(%d) > rtkm buffer size(%d)\n", __func__, in_size, MAX_RTKM_RECVBUF_SZ);
 | 
						|
		WARN_ON(1);
 | 
						|
		return skb;
 | 
						|
	}
 | 
						|
 | 
						|
	skb = skb_dequeue(&rtk_skb_mem_q);
 | 
						|
 | 
						|
	printk("%s, rtk_skb_mem_q len : %d\n", __func__, skb_queue_len(&rtk_skb_mem_q));
 | 
						|
 | 
						|
	return skb;
 | 
						|
}
 | 
						|
EXPORT_SYMBOL(rtw_alloc_skb_premem);
 | 
						|
 | 
						|
int rtw_free_skb_premem(struct sk_buff *pskb)
 | 
						|
{
 | 
						|
	if (!pskb)
 | 
						|
		return -1;
 | 
						|
 | 
						|
	if (skb_queue_len(&rtk_skb_mem_q) >= MAX_RTKM_NR_PREALLOC_RECV_SKB)
 | 
						|
		return -1;
 | 
						|
 | 
						|
	skb_queue_tail(&rtk_skb_mem_q, pskb);
 | 
						|
 | 
						|
	printk("%s, rtk_skb_mem_q len : %d\n", __func__, skb_queue_len(&rtk_skb_mem_q));
 | 
						|
 | 
						|
	return 0;
 | 
						|
}
 | 
						|
EXPORT_SYMBOL(rtw_free_skb_premem);
 | 
						|
 | 
						|
static int __init rtw_mem_init(void)
 | 
						|
{
 | 
						|
	int i;
 | 
						|
	SIZE_PTR tmpaddr = 0;
 | 
						|
	SIZE_PTR alignment = 0;
 | 
						|
	struct sk_buff *pskb = NULL;
 | 
						|
 | 
						|
	printk("%s\n", __func__);
 | 
						|
	pr_info("MAX_RTKM_NR_PREALLOC_RECV_SKB: %d\n", MAX_RTKM_NR_PREALLOC_RECV_SKB);
 | 
						|
	pr_info("MAX_RTKM_RECVBUF_SZ: %d\n", MAX_RTKM_RECVBUF_SZ);
 | 
						|
 | 
						|
#ifdef CONFIG_USE_USB_BUFFER_ALLOC_RX
 | 
						|
	for (i = 0; i < NR_RECVBUFF; i++)
 | 
						|
		rtk_buf_mem[i] = usb_buffer_alloc(dev, size, (in_interrupt() ? GFP_ATOMIC : GFP_KERNEL), dma);
 | 
						|
#endif /* CONFIG_USE_USB_BUFFER_ALLOC_RX */
 | 
						|
 | 
						|
	skb_queue_head_init(&rtk_skb_mem_q);
 | 
						|
 | 
						|
	for (i = 0; i < MAX_RTKM_NR_PREALLOC_RECV_SKB; i++) {
 | 
						|
		pskb = __dev_alloc_skb(MAX_RTKM_RECVBUF_SZ + RECVBUFF_ALIGN_SZ, in_interrupt() ? GFP_ATOMIC : GFP_KERNEL);
 | 
						|
		if (pskb) {
 | 
						|
			tmpaddr = (SIZE_PTR)pskb->data;
 | 
						|
			alignment = tmpaddr & (RECVBUFF_ALIGN_SZ - 1);
 | 
						|
			skb_reserve(pskb, (RECVBUFF_ALIGN_SZ - alignment));
 | 
						|
 | 
						|
			skb_queue_tail(&rtk_skb_mem_q, pskb);
 | 
						|
		} else
 | 
						|
			printk("%s, alloc skb memory fail!\n", __func__);
 | 
						|
 | 
						|
		pskb = NULL;
 | 
						|
	}
 | 
						|
 | 
						|
	printk("%s, rtk_skb_mem_q len : %d\n", __func__, skb_queue_len(&rtk_skb_mem_q));
 | 
						|
 | 
						|
	return 0;
 | 
						|
 | 
						|
}
 | 
						|
 | 
						|
static void __exit rtw_mem_exit(void)
 | 
						|
{
 | 
						|
	if (skb_queue_len(&rtk_skb_mem_q))
 | 
						|
		printk("%s, rtk_skb_mem_q len : %d\n", __func__, skb_queue_len(&rtk_skb_mem_q));
 | 
						|
 | 
						|
	skb_queue_purge(&rtk_skb_mem_q);
 | 
						|
 | 
						|
	printk("%s\n", __func__);
 | 
						|
}
 | 
						|
 | 
						|
module_init(rtw_mem_init);
 | 
						|
module_exit(rtw_mem_exit);
 |