M7350/wlan/8192es/DriverSrcPkg/Driver/rtl8192cd_92es/8192cd_dmem.c
2024-09-09 08:59:52 +00:00

287 lines
7.8 KiB
C
Executable File

/*
* D-MEM supporting module for RTL8190 802.11N wireless NIC on RTL865x platform
*
* $Id: 8192cd_dmem.c,v 1.2 2010/01/19 06:04:03 jimmylin Exp $
*
* Copyright (c) 2009 Realtek Semiconductor Corp.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#ifdef __ECOS
#include <cyg/io/eth/rltk/819x/wrapper/sys_support.h>
#include <cyg/io/eth/rltk/819x/wrapper/skbuff.h>
#include <cyg/io/eth/rltk/819x/wrapper/timer.h>
#include <cyg/io/eth/rltk/819x/wrapper/wrapper.h>
#endif
#ifndef _8192CD_DMEM_C_
#define _8192CD_DMEM_C_
#include "./8192cd.h"
//#include "./8190n_fastExtDev.h"
#include "./8192cd_cfg.h"
#ifdef RTL8192CD_VARIABLE_USED_DMEM
#include "./8192cd_dmem.h"
#define RTL8192CD_MAX_SPEEDUP_STA 2
#define RTL8192CD_SPEEDUP_PRIV_COUNT 1
/* ========================== All variables using D-MEM ========================== */
static void rtl8192cd_dmem_AID_OBJ_init(void);
static void *rtl8192cd_dmem_AID_OBJ_alloc(void *miscInfo);
static void rtl8192cd_dmem_AID_OBJ_free(void *miscInfo);
static void rtl8192cd_dmem_pmib_init(void);
static void *rtl8192cd_dmem_pmib_alloc(void *miscInfo);
static void rtl8192cd_dmem_pmib_free(void *miscInfo);
#ifdef PRIV_STA_BUF
extern struct aid_obj *alloc_sta_obj(struct rtl8192cd_priv*);
extern void free_sta_obj(struct rtl8192cd_priv *priv, struct aid_obj *obj);
#endif
static _rtl8192cd_dmem_callBack_t _8192cd_dmem_callBack_list[] =
{
/* ID Init CallBack Allocate CallBack Free CallBack */
{ AID_OBJ, rtl8192cd_dmem_AID_OBJ_init, rtl8192cd_dmem_AID_OBJ_alloc, rtl8192cd_dmem_AID_OBJ_free},
{ PMIB, rtl8192cd_dmem_pmib_init, rtl8192cd_dmem_pmib_alloc, rtl8192cd_dmem_pmib_free},
/* ==================================================================== */
{ _RTL8192CD_DMEM_ITEM_MAX, NULL, NULL},
};
/* ========================== External APIs of D-MEM module ========================== */
/*
Initiation function for DMEM library
*/
void rtl8192cd_dmem_init( void )
{
_rtl8192cd_dmem_callBack_t *ptr;
ptr = &_8192cd_dmem_callBack_list[0];
while ( (ptr->id > _RTL8192CD_DMEM_ITEM_MIN) &&
(ptr->id < _RTL8192CD_DMEM_ITEM_MAX))
{
/* Call the Callback function to decide the memory of allocated */
if (ptr->initCallBackFunc)
{
((_dummyFunc_void_void)(ptr->initCallBackFunc))();
}
/* Next Entry */
ptr ++;
}
}
void *rtl8192cd_dmem_alloc( enum _RTL8192CD_DMEM_ITEM_ID id, void *miscInfo )
{
void *retval;
_rtl8192cd_dmem_callBack_t *ptr;
retval = NULL;
if ( (id <= _RTL8192CD_DMEM_ITEM_MIN) ||
(id >= _RTL8192CD_DMEM_ITEM_MAX))
{
printk("%s %d : ERROR (%d)\n", __FUNCTION__, __LINE__, id);
goto out;
}
ptr = &_8192cd_dmem_callBack_list[0];
while ( ptr->allcateCallBackFunc )
{
if ( ptr->id == id )
{
/* Call the Callback function to decide the memory of allocated */
retval = ((_dummyFunc_voidStar_voidStar)(ptr->allcateCallBackFunc))(miscInfo);
goto out;
}
/* Next Entry */
ptr ++;
}
out:
return retval;
}
void rtl8192cd_dmem_free( enum _RTL8192CD_DMEM_ITEM_ID id, void *miscInfo )
{
_rtl8192cd_dmem_callBack_t *ptr;
if ( (id <= _RTL8192CD_DMEM_ITEM_MIN) ||
(id >= _RTL8192CD_DMEM_ITEM_MAX))
{
printk("%s %d : ERROR (%d)\n", __FUNCTION__, __LINE__, id);
goto out;
}
ptr = &_8192cd_dmem_callBack_list[0];
while ( ptr->freeCallBackFunc )
{
if ( ptr->id == id )
{
/* Call the Callback function to decide the memory of allocated */
((_dummyFunc_void_voidStar)(ptr->freeCallBackFunc))(miscInfo);
goto out;
}
/* Next Entry */
ptr ++;
}
out:
return;
}
/* ========================== Internal APIs for per-variable of D-MEM module ========================== */
/* ==============================================
*
* AID_OBJ
*
*
* ============================================== */
__DRAM_IN_865X struct aid_obj _rtl8192cd_aid_Array[RTL8192CD_MAX_SPEEDUP_STA];
void *_rtl8192cd_aid_externalMem_Array[NUM_STAT];
static void rtl8192cd_dmem_AID_OBJ_init(void)
{
memset(_rtl8192cd_aid_Array, 0, sizeof(struct aid_obj) * RTL8192CD_MAX_SPEEDUP_STA);
memset(_rtl8192cd_aid_externalMem_Array, 0, sizeof(_rtl8192cd_aid_externalMem_Array));
}
static void *rtl8192cd_dmem_AID_OBJ_alloc(void *miscInfo)
{
/* For AID_OBJ : miscInfo would be [unsigned int *] to decision the index of aidarray to allocate */
unsigned int index = *((unsigned int*)miscInfo);
if ( (index < 0) ||
(index >= NUM_STAT))
{
printk("%s %d : ERROR ( Index : %d )\n", __FUNCTION__, __LINE__, index);
return NULL;
}
/* Allocate from external memory */
if ( index >= RTL8192CD_MAX_SPEEDUP_STA )
{
#ifdef PRIV_STA_BUF
_rtl8192cd_aid_externalMem_Array[index] = alloc_sta_obj(NULL);
#else
_rtl8192cd_aid_externalMem_Array[index] = kmalloc(sizeof(struct aid_obj), GFP_ATOMIC);
#endif
if (_rtl8192cd_aid_externalMem_Array[index] == NULL)
{
printk("%s %d : Error : Allocation FAILED!\n", __FUNCTION__, __LINE__);
return NULL;
}
return _rtl8192cd_aid_externalMem_Array[index];
}
memset(&(_rtl8192cd_aid_Array[index]), 0, sizeof(struct aid_obj));
return (void*)(&(_rtl8192cd_aid_Array[index]));
}
static void rtl8192cd_dmem_AID_OBJ_free(void *miscInfo)
{
/* For AID_OBJ : miscInfo would be [unsigned int *] to decision the index of aidarray to free */
unsigned int index = *((unsigned int*)miscInfo);
if ( (index < 0) ||
(index >= NUM_STAT))
{
printk("%s %d : ERROR ( Index : %d )\n", __FUNCTION__, __LINE__, index);
return;
}
/* Free memory to external memory module */
if ( index >= RTL8192CD_MAX_SPEEDUP_STA )
{
if ( _rtl8192cd_aid_externalMem_Array[index] )
{
#ifdef PRIV_STA_BUF
free_sta_obj(NULL, _rtl8192cd_aid_externalMem_Array[index]);
#else
kfree(_rtl8192cd_aid_externalMem_Array[index]);
#endif
_rtl8192cd_aid_externalMem_Array[index] = NULL;
}
return;
}
memset(&(_rtl8192cd_aid_Array[index]), 0, sizeof(struct aid_obj));
}
/* =================== The following variable are mapped to PRIV =================== */
/* ==============================================
*
* PMIB
*
*
* ============================================== */
__DRAM_IN_865X struct wifi_mib _rtl8192cd_pmib[RTL8192CD_SPEEDUP_PRIV_COUNT];
int _rtl8192cd_pmib_usageMap[RTL8192CD_SPEEDUP_PRIV_COUNT];
static void rtl8192cd_dmem_pmib_init(void)
{
memset(_rtl8192cd_pmib_usageMap, 0, sizeof(int) * RTL8192CD_SPEEDUP_PRIV_COUNT);
memset(_rtl8192cd_pmib, 0, sizeof(struct wifi_mib) * RTL8192CD_SPEEDUP_PRIV_COUNT);
}
static void *rtl8192cd_dmem_pmib_alloc(void *miscInfo)
{
int idx ;
/* miscInfo is useless */
for ( idx = 0 ; idx < RTL8192CD_SPEEDUP_PRIV_COUNT ; idx ++ )
{
if ( _rtl8192cd_pmib_usageMap[idx] == 0 )
{ /* Unused entry : use it */
_rtl8192cd_pmib_usageMap[idx] = 1;
memset(&(_rtl8192cd_pmib[idx]), 0, sizeof(struct wifi_mib));
return &(_rtl8192cd_pmib[idx]);
}
}
/* Allocate from externel memory if speedup PMIB is exhausted */
return kmalloc(sizeof(struct wifi_mib), GFP_ATOMIC);
}
static void rtl8192cd_dmem_pmib_free(void *miscInfo)
{
int idx;
/* miscInfo is pointed to the address of PMIB to free */
/* Free PMIB if it is speeded up by DMEM */
for ( idx = 0 ; idx < RTL8192CD_SPEEDUP_PRIV_COUNT ; idx ++ )
{
if ( (unsigned long)(&(_rtl8192cd_pmib[idx])) == (unsigned long)miscInfo )
{ /* Entry is found : free it */
memset(&(_rtl8192cd_pmib[idx]), 0, sizeof(struct wifi_mib));
_rtl8192cd_pmib_usageMap[idx] = 0;
return;
}
}
/* It would be allocated from external memory: kfree it */
kfree(miscInfo);
}
#endif // RTL8192CD_VARIABLE_USED_DMEM
#endif