mirror of
https://gitee.com/Vancouver2017/luban-lite.git
synced 2025-12-24 13:08:55 +00:00
378 lines
11 KiB
C
378 lines
11 KiB
C
/**************************************************************************************************************
|
|
* altobeam RTOS wifi hmac source code
|
|
*
|
|
* Copyright (c) 2018, altobeam.inc All rights reserved.
|
|
*
|
|
* The source code contains proprietary information of AltoBeam, and shall not be distributed,
|
|
* copied, reproduced, or disclosed in whole or in part without prior written permission of AltoBeam.
|
|
*****************************************************************************************************************/
|
|
|
|
|
|
#include "atbm_hal.h"
|
|
int atbm_skb_cnt =0;
|
|
int atbm_skb_free =0;
|
|
|
|
static struct atbm_buff * __atbm_pbuf_alloc(atbm_uint16 length)
|
|
{
|
|
struct atbm_buff *p;
|
|
atbm_uint32 size;
|
|
atbm_skb_cnt++;
|
|
size=ATBM_MEM_ALIGN_SIZE(sizeof(struct atbm_buff) + ATBM_HWBUF_EXTERN_HEADROM_LEN + ATBM_HWBUF_EXTERN_TAILROM_LEN+ length);
|
|
/* If atbm_buff is to be allocated in RAM, allocate memory for it. */
|
|
p = (struct atbm_buff*) atbm_kzalloc(size,GFP_KERNEL);
|
|
if (p == ATBM_NULL) {
|
|
ATBM_WARN("__atbm_pbuf_alloc fail \n");
|
|
return ATBM_NULL;
|
|
}
|
|
/* Set up internal structure of the atbm_buff. */
|
|
ATBM_OS_SKB_DATA(p) = ATBM_MEM_ALIGN((atbm_void *)((atbm_uint8 *)p + sizeof(struct atbm_buff) + ATBM_HWBUF_EXTERN_HEADROM_LEN));
|
|
ATBM_OS_SKB_HEAD(p) = ATBM_MEM_ALIGN((atbm_uint8 *)(p+1));
|
|
//p->dlen =length+ HWBUF_EXTERN_TAILROM_LEN;
|
|
|
|
p->ref = 1;
|
|
p->totalLen = ATBM_MEM_ALIGN_SIZE(ATBM_HWBUF_EXTERN_HEADROM_LEN + ATBM_HWBUF_EXTERN_TAILROM_LEN + length);
|
|
p->bufferLen = ATBM_MEM_ALIGN_SIZE(ATBM_HWBUF_EXTERN_HEADROM_LEN + ATBM_HWBUF_EXTERN_TAILROM_LEN +length);
|
|
//wifi_printk(WIFI_ALWAYS,"****************size*****************=%d:%d:%d\n",size,p->totalLen,p->bufferLen);
|
|
|
|
/*add for wifi*/
|
|
ATBM_OS_SKB_LEN(p) = 0;
|
|
p->Tail = ATBM_OS_SKB_DATA(p);
|
|
|
|
return p;
|
|
}
|
|
|
|
atbm_void atbm_skb_reinit(struct atbm_buff *skb)
|
|
{
|
|
//clear skb struct to 0
|
|
|
|
ATBM_OS_SKB_DATA(skb) = ATBM_MEM_ALIGN((atbm_void *)((atbm_uint8 *)skb + sizeof(struct atbm_buff) + ATBM_HWBUF_EXTERN_HEADROM_LEN));
|
|
ATBM_OS_SKB_HEAD(skb) = (atbm_uint8 *)(skb+1);
|
|
skb->bufferLen = skb->totalLen;
|
|
|
|
//skb->ref = 1;
|
|
//skb->totalLen = (ATBM_MEM_ALIGN_SIZE(sizeof(struct atbm_buff) + HWBUF_EXTERN_HEADROM_LEN + HWBUF_EXTERN_TAILROM_LEN) + ATBM_MEM_ALIGN_SIZE(length));
|
|
|
|
|
|
/*add for wifi*/
|
|
ATBM_OS_SKB_LEN(skb) = 0;
|
|
skb->Tail = ATBM_OS_SKB_DATA(skb);
|
|
}
|
|
static atbm_void __atbm_pbuf_free(struct atbm_buff *p)
|
|
{
|
|
atbm_skb_free++;
|
|
ATBM_ASSERT(p->ref == 1);
|
|
p->ref--;
|
|
atbm_kfree(p);
|
|
}
|
|
|
|
struct atbm_buff * atbm_dev_alloc_skb(atbm_int32 len)
|
|
{
|
|
struct atbm_buff * skb;
|
|
skb = __atbm_pbuf_alloc(len);
|
|
if(skb == ATBM_NULL){
|
|
ATBM_BUG_ON(1);
|
|
return ATBM_NULL;
|
|
}
|
|
return skb;
|
|
}
|
|
|
|
struct atbm_buff * atbm_dev_alloc_skbhdr(void)
|
|
{
|
|
struct atbm_buff *p;
|
|
|
|
/* If atbm_buff is to be allocated in RAM, allocate memory for it. */
|
|
p = (struct atbm_buff*) __atbm_pbuf_alloc(0);
|
|
if (p == ATBM_NULL) {
|
|
ATBM_WARN("atbm_dev_alloc_skbhdr fail \n");
|
|
return ATBM_NULL;
|
|
}
|
|
|
|
return p;
|
|
}
|
|
|
|
|
|
atbm_int32 atbm_dev_kfree_skb(struct atbm_buff * skb)
|
|
{
|
|
#if defined (WLAN_ZERO_COPY1)
|
|
atbm_dev_free_os_skb(skb);
|
|
#endif //#if defined (WLAN_ZERO_COPY1)
|
|
__atbm_pbuf_free(skb);
|
|
return 1;
|
|
}
|
|
|
|
|
|
/*
|
|
* Add data to an atbm_buff
|
|
*/
|
|
atbm_uint8 *atbm_skb_put(struct atbm_buff *skb, atbm_uint32 len)
|
|
{
|
|
atbm_uint8 *tmp = skb->Tail;
|
|
skb->Tail += len;
|
|
ATBM_OS_SKB_LEN(skb) += len;
|
|
return tmp;
|
|
}
|
|
|
|
atbm_uint8 *atbm_skb_push(struct atbm_buff *skb, atbm_uint32 len)
|
|
{
|
|
ATBM_OS_SKB_DATA(skb) -= len;
|
|
ATBM_OS_SKB_LEN(skb) += len;
|
|
return ATBM_OS_SKB_DATA(skb);
|
|
}
|
|
|
|
atbm_uint8 * atbm_skb_pull(struct atbm_buff *skb, atbm_uint32 len)
|
|
{
|
|
ATBM_OS_SKB_LEN(skb) -= len;
|
|
return ATBM_OS_SKB_DATA(skb) += len;
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
* atbm_skb_headroom - bytes at buffer head
|
|
* @skb: buffer to check
|
|
*
|
|
* Return the number of bytes of free space at the head of an &atbm_buff.
|
|
*/
|
|
atbm_uint32 atbm_skb_headroom(const struct atbm_buff *skb)
|
|
{
|
|
return ATBM_OS_SKB_DATA(skb) - (atbm_uint8 *)ATBM_OS_SKB_HEAD(skb);
|
|
}
|
|
|
|
/**
|
|
* skb_tailroom - bytes at buffer end
|
|
* @skb: buffer to check
|
|
*
|
|
* Return the number of bytes of free space at the tail of an atbm_buff
|
|
*/
|
|
atbm_int32 atbm_skb_tailroom(const struct atbm_buff *skb)
|
|
{
|
|
return ((atbm_uint8 *)ATBM_OS_SKB_HEAD(skb)+ skb->bufferLen) - (atbm_uint8 *)skb->Tail;
|
|
}
|
|
|
|
/**
|
|
* skb_reserve - adjust headroom
|
|
* @skb: buffer to alter
|
|
* @len: bytes to move
|
|
*
|
|
* Increase the headroom of an empty &atbm_buff by reducing the tail
|
|
* room. This is only allowed for an empty buffer.
|
|
*/
|
|
atbm_int32 atbm_skb_reserve(struct atbm_buff *skb, atbm_int32 len)
|
|
{
|
|
//atbm_uint8 * buf = OS_SKB_DATA(skb);
|
|
//ATBM_WARN_ON_FUNC(OS_SKB_LEN(skb) > 0);
|
|
//if(skb->dlen < len){
|
|
// return -1;
|
|
//}
|
|
ATBM_OS_SKB_DATA(skb) += len;
|
|
skb->Tail = ATBM_OS_SKB_DATA(skb);
|
|
//skb->tot_len -= len;
|
|
//skb->dlen -= len;
|
|
return 0;
|
|
}
|
|
|
|
|
|
atbm_void atbm_skb_set_tail_pointer(struct atbm_buff *skb, const atbm_int32 offset)
|
|
{
|
|
skb->Tail = ATBM_OS_SKB_DATA(skb) + offset;
|
|
}
|
|
|
|
atbm_void atbm_skb_trim(struct atbm_buff *skb, atbm_uint32 len)
|
|
{
|
|
|
|
ATBM_OS_SKB_LEN(skb) = len;
|
|
atbm_skb_set_tail_pointer(skb, len);
|
|
}
|
|
|
|
static atbm_void __atbm_skb_insert(struct atbm_buff *newsk,
|
|
struct atbm_buff *prev, struct atbm_buff *next,
|
|
struct atbm_buff_head *list)
|
|
{
|
|
newsk->next = next;
|
|
newsk->prev = prev;
|
|
next->prev = prev->next = newsk;
|
|
list->qlen++;
|
|
}
|
|
|
|
/**
|
|
* __skb_queue_after_ - queue a buffer at the list head
|
|
* @list: list to use
|
|
* @prev: place after this buffer
|
|
* @newsk: buffer to queue
|
|
*
|
|
* Queue a buffer int the middle of a list. This function takes no locks
|
|
* and you must therefore hold required locks before calling it.
|
|
*
|
|
* A buffer cannot be placed on two lists at the same time.
|
|
*/
|
|
/*
|
|
static atbm_void __skb_queue_after_(struct atbm_buff_head *list,
|
|
struct atbm_buff *prev,
|
|
struct atbm_buff *newsk)
|
|
{
|
|
__atbm_skb_insert(newsk, prev, prev->next, list);
|
|
}
|
|
*/
|
|
static atbm_void __skb_queue_before_(struct atbm_buff_head *list,
|
|
struct atbm_buff *next,
|
|
struct atbm_buff *newsk)
|
|
{
|
|
__atbm_skb_insert(newsk, next->prev, next, list);
|
|
}
|
|
/*
|
|
static atbm_void __skb_queue_head_(struct atbm_buff_head *list,
|
|
struct atbm_buff *newsk)
|
|
{
|
|
__skb_queue_after_(list, (struct atbm_buff *)list, newsk);
|
|
}
|
|
*/
|
|
/**
|
|
* __skb_queue_tail_ - queue a buffer at the list tail
|
|
* @list: list to use
|
|
* @newsk: buffer to queue
|
|
*
|
|
* Queue a buffer at the end of a list. This function takes no locks
|
|
* and you must therefore hold required locks before calling it.
|
|
*
|
|
* A buffer cannot be placed on two lists at the same time.
|
|
*/
|
|
static atbm_void __skb_queue_tail_(struct atbm_buff_head *list,
|
|
struct atbm_buff *newsk)
|
|
{
|
|
__skb_queue_before_(list, (struct atbm_buff *)list, newsk);
|
|
}
|
|
static atbm_void __skb_unlink_(struct atbm_buff *skb, struct atbm_buff_head *list)
|
|
{
|
|
struct atbm_buff *next, *prev;
|
|
|
|
list->qlen--;
|
|
next = skb->next;
|
|
prev = skb->prev;
|
|
skb->next = skb->prev = ATBM_NULL;
|
|
next->prev = prev;
|
|
prev->next = next;
|
|
}
|
|
|
|
/**
|
|
* atbm_skb_peek_tail - peek at the tail of an &atbm_buff_head
|
|
* @list_: list to peek at
|
|
*
|
|
* Peek an &atbm_buff. Unlike most other operations you _MUST_
|
|
* be careful with this one. A peek leaves the buffer on the
|
|
* list and someone else may run off with it. You must hold
|
|
* the appropriate locks or have a private queue to do this.
|
|
*
|
|
* Returns %NULL for an empty list or a pointer to the tail element.
|
|
* The reference count is not incremented and the reference is therefore
|
|
* volatile. Use with caution.
|
|
*/
|
|
/*
|
|
static struct atbm_buff *atbm_skb_peek_tail(struct atbm_buff_head *list_)
|
|
{
|
|
struct atbm_buff *list = ((struct atbm_buff *)list_)->prev;
|
|
if (list == (struct atbm_buff *)list_)
|
|
list = ATBM_NULL;
|
|
return list;
|
|
}
|
|
*/
|
|
/**
|
|
* atbm_skb_peek - peek at the head of an &atbm_buff_head
|
|
* @list_: list to peek at
|
|
*
|
|
* Peek an &atbm_buff. Unlike most other operations you _MUST_
|
|
* be careful with this one. A peek leaves the buffer on the
|
|
* list and someone else may run off with it. You must hold
|
|
* the appropriate locks or have a private queue to do this.
|
|
*
|
|
* Returns %NULL for an empty list or a pointer to the head element.
|
|
* The reference count is not incremented and the reference is therefore
|
|
* volatile. Use with caution.
|
|
*/
|
|
struct atbm_buff *atbm_skb_peek(struct atbm_buff_head *list_)
|
|
{
|
|
struct atbm_buff *list = ((struct atbm_buff *)list_)->next;
|
|
if (list == (struct atbm_buff *)list_)
|
|
list = ATBM_NULL;
|
|
return list;
|
|
}
|
|
/**
|
|
* __skb_dequeue_tail_ - remove from the tail of the queue
|
|
* @list: list to dequeue from
|
|
*
|
|
* Remove the tail of the list. This function does not take any locks
|
|
* so must be used with appropriate locks held only. The tail item is
|
|
* returned or %NULL if the list is empty.
|
|
*/
|
|
/*
|
|
static struct atbm_buff *__skb_dequeue_tail_(struct atbm_buff_head *list)
|
|
{
|
|
struct atbm_buff *skb = atbm_skb_peek_tail(list);
|
|
if (skb)
|
|
__skb_unlink_(skb, list);
|
|
return skb;
|
|
}
|
|
*/
|
|
/**
|
|
* __skb_dequeue_ - remove from the head of the queue
|
|
* @list: list to dequeue from
|
|
*
|
|
* Remove the head of the list. This function does not take any locks
|
|
* so must be used with appropriate locks held only. The head item is
|
|
* returned or %NULL if the list is empty.
|
|
*/
|
|
static struct atbm_buff *__skb_dequeue_(struct atbm_buff_head *list)
|
|
{
|
|
struct atbm_buff *skb = atbm_skb_peek(list);
|
|
if (skb)
|
|
__skb_unlink_(skb, list);
|
|
return skb;
|
|
}
|
|
|
|
/**
|
|
* skb_dequeue - remove from the head of the queue
|
|
* @list: list to dequeue from
|
|
*
|
|
* Remove the head of the list. The list lock is taken so the function
|
|
* may be used safely with other locking list functions. The head item is
|
|
* returned or %NULL if the list is empty.
|
|
*/
|
|
struct atbm_buff *atbm_skb_dequeue(struct atbm_buff_head *list)
|
|
{
|
|
unsigned long flags;
|
|
struct atbm_buff *result;
|
|
|
|
atbm_spin_lock_irqsave(&list->lock, &flags);
|
|
wifi_printk(WIFI_DBG_MSG,"atbm: atbm_skb_dequeue(), start.\n");
|
|
result = __skb_dequeue_(list);
|
|
wifi_printk(WIFI_DBG_MSG,"atbm: atbm_skb_dequeue(), end.\n");
|
|
atbm_spin_unlock_irqrestore(&list->lock, flags);
|
|
return result;
|
|
}
|
|
|
|
atbm_void atbm_skb_queue_tail(struct atbm_buff_head *list, struct atbm_buff *newsk)
|
|
{
|
|
|
|
unsigned long flags;
|
|
|
|
atbm_spin_lock_irqsave(&list->lock, &flags);
|
|
wifi_printk(WIFI_DBG_MSG,"atbm: atbm_skb_queue_tail(), start.\n");
|
|
__skb_queue_tail_(list, newsk);
|
|
wifi_printk(WIFI_DBG_MSG,"atbm: atbm_skb_queue_tail(), end.\n");
|
|
atbm_spin_unlock_irqrestore(&list->lock, flags);
|
|
}
|
|
/**
|
|
* skb_queue_purge - empty a list
|
|
* @list: list to empty
|
|
*
|
|
* Delete all buffers on an &atbm_buff list. Each buffer is removed from
|
|
* the list and one reference dropped. This function takes the list
|
|
* lock and is atomic with respect to other list locking functions.
|
|
*/
|
|
atbm_void atbm_skb_queue_purge(struct atbm_buff_head *list)
|
|
{
|
|
struct atbm_buff *skb;
|
|
while ((skb = atbm_skb_dequeue(list)) != ATBM_NULL)
|
|
atbm_dev_kfree_skb(skb);
|
|
}
|
|
|