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

243 lines
5.1 KiB
C
Executable File

/*
* a4 sta functions
*
* $Id: 8192cd_a4_sta.c,v 1.1 2010/10/13 06:38:58 davidhsu Exp $
*
* Copyright (c) 2010 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.
*/
#define _8192CD_A4_STA_C_
#ifdef __KERNEL__
#include <linux/slab.h>
#include <linux/sched.h>
#include <linux/timer.h>
#endif
#include "./8192cd_cfg.h"
#ifdef A4_STA
#include "./8192cd.h"
#include "./8192cd_headers.h"
#include "./8192cd_debug.h"
//#define A4_STA_DEBUG
static struct a4_sta_db_entry *alloc_entry(struct rtl8192cd_priv *priv)
{
int i;
for (i=0; i<MAX_A4_TBL_NUM; i++) {
if (!priv->a4_ent[i].used) {
priv->a4_ent[i].used = 1;
return &priv->a4_ent[i].entry;
}
}
return NULL;
}
static void free_entry(struct rtl8192cd_priv *priv, struct a4_sta_db_entry *entry)
{
int i;
for (i=0; i<MAX_A4_TBL_NUM; i++) {
if (priv->a4_ent[i].used && (entry == &priv->a4_ent[i].entry)) {
priv->a4_ent[i].used = 0;
break;
}
}
}
static int mac_hash(unsigned char *networkAddr)
{
unsigned long x;
x = networkAddr[0] ^ networkAddr[1] ^ networkAddr[2] ^ networkAddr[3] ^ networkAddr[4] ^ networkAddr[5];
return x & (A4_STA_HASH_SIZE - 1);
}
static void mac_hash_link(struct rtl8192cd_priv *priv, struct a4_sta_db_entry *ent, int hash)
{
ent->next_hash = priv->machash[hash];
if (ent->next_hash != NULL)
ent->next_hash->pprev_hash = &ent->next_hash;
priv->machash[hash] = ent;
ent->pprev_hash = &priv->machash[hash];
}
static void mac_hash_unlink(struct a4_sta_db_entry *ent)
{
*(ent->pprev_hash) = ent->next_hash;
if (ent->next_hash != NULL)
ent->next_hash->pprev_hash = ent->pprev_hash;
ent->next_hash = NULL;
ent->pprev_hash = NULL;
}
static unsigned long _timeout(struct rtl8192cd_priv *priv)
{
unsigned long timeout;
timeout = jiffies - A4_STA_AGEING_TIME*HZ;
return timeout;
}
static int has_expired(struct rtl8192cd_priv *priv, struct a4_sta_db_entry *fdb)
{
if (time_before_eq(fdb->ageing_timer, _timeout(priv)))
return 1;
return 0;
}
void a4_sta_cleanup(struct rtl8192cd_priv *priv)
{
int i;
if (priv->pshare->rf_ft_var.a4_enable) {
for (i=0; i<A4_STA_HASH_SIZE; i++) {
struct a4_sta_db_entry *f;
f = priv->machash[i];
while (f != NULL) {
struct a4_sta_db_entry *g;
g = f->next_hash;
mac_hash_unlink(f);
free_entry(priv, f);
f = g;
}
}
}
}
void a4_sta_expire(struct rtl8192cd_priv *priv)
{
int i;
if (priv->pshare->rf_ft_var.a4_enable) {
for (i=0; i<A4_STA_HASH_SIZE; i++) {
struct a4_sta_db_entry *f;
f = priv->machash[i];
while (f != NULL) {
struct a4_sta_db_entry *g;
g = f->next_hash;
if (has_expired(priv, f)) {
#ifdef A4_STA_DEBUG
panic_printk("A4 STA Expire (%02d) emac:%02x%02x%02x%02x%02x%02x, wmac:%02x%02x%02x%02x%02x%02x\n",
i,
f->mac[0],
f->mac[1],
f->mac[2],
f->mac[3],
f->mac[4],
f->mac[5],
f->stat->hwaddr[0],
f->stat->hwaddr[1],
f->stat->hwaddr[2],
f->stat->hwaddr[3],
f->stat->hwaddr[4],
f->stat->hwaddr[5]);
#endif
mac_hash_unlink(f);
free_entry(priv, f);
}
f = g;
}
}
}
}
void a4_sta_add(struct rtl8192cd_priv *priv, struct stat_info *pstat, unsigned char *mac)
{
struct a4_sta_db_entry *db;
int hash;
ASSERT(mac);
hash = mac_hash(mac);
db = priv->machash[hash];
while (db != NULL) {
if (!memcmp(db->mac, mac, ETH_ALEN)) {
db->stat = pstat;
db->ageing_timer = jiffies;
return;
}
db = db->next_hash;
}
db = alloc_entry(priv);
if (db == NULL) {
DEBUG_ERR("alloc_entry() failed for a4_sta_db_entry!\n");
return;
}
memcpy(db->mac, mac, ETH_ALEN);
db->stat = pstat;
db->ageing_timer = jiffies;
#ifdef A4_STA_DEBUG
panic_printk("A4 STA Add emac:%02x%02x%02x%02x%02x%02x, wmac:%02x%02x%02x%02x%02x%02x\n",
db->mac[0],
db->mac[1],
db->mac[2],
db->mac[3],
db->mac[4],
db->mac[5],
db->stat->hwaddr[0],
db->stat->hwaddr[1],
db->stat->hwaddr[2],
db->stat->hwaddr[3],
db->stat->hwaddr[4],
db->stat->hwaddr[5]);
#endif
mac_hash_link(priv, db, hash);
}
struct stat_info *a4_sta_lookup(struct rtl8192cd_priv *priv, unsigned char *mac)
{
struct a4_sta_db_entry *db;
ASSERT(mac);
db = priv->machash[mac_hash(mac)];
while (db != NULL) {
if (!memcmp(db->mac, mac, ETH_ALEN)) {
#ifdef A4_STA_DEBUG
panic_printk("A4 STA LOOKUP emac:%02x%02x%02x%02x%02x%02x, wmac:%02x%02x%02x%02x%02x%02x\n",
db->mac[0],
db->mac[1],
db->mac[2],
db->mac[3],
db->mac[4],
db->mac[5],
db->stat->hwaddr[0],
db->stat->hwaddr[1],
db->stat->hwaddr[2],
db->stat->hwaddr[3],
db->stat->hwaddr[4],
db->stat->hwaddr[5]);
#endif
return db->stat;
}
db = db->next_hash;
}
return NULL;
}
#endif /* A4_STA */