/*
 * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved.
 *
 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
 *
 *
 * Permission to use, copy, modify, and/or distribute this software for
 * any purpose with or without fee is hereby granted, provided that the
 * above copyright notice and this permission notice appear in all
 * copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 * PERFORMANCE OF THIS SOFTWARE.
 */

/*
 * This file was originally distributed by Qualcomm Atheros, Inc.
 * under proprietary terms before Copyright ownership was assigned
 * to the Linux Foundation.
 */

/*
 *
 * This file dph_hash_table.cc implements the member functions of
 * DPH hash table class.
 *
 * Author:      Sandesh Goel
 * Date:        02/25/02
 * History:-
 * Date            Modified by    Modification Information
 * --------------------------------------------------------------------
 *
 */
#include "cds_api.h"
#include "cfg_api.h"
#include "sch_api.h"
#include "dph_global.h"
#include "lim_debug.h"

#include "wma_if.h"

/* --------------------------------------------------------------------- */
/**
 * dphHashTableClass()
 *
 * FUNCTION:
 * Constructor function
 *
 * LOGIC:
 *
 * ASSUMPTIONS:
 *
 * NOTE:
 *
 * @param None
 * @return None
 */

void dph_hash_table_class_init(tpAniSirGlobal pMac,
			       dphHashTableClass *pDphHashTable)
{
	uint16_t i;

	for (i = 0; i < pDphHashTable->size; i++) {
		pDphHashTable->pHashTable[i] = 0;
	}

	for (i = 0; i < pDphHashTable->size; i++) {
		pDphHashTable->pDphNodeArray[i].valid = 0;
		pDphHashTable->pDphNodeArray[i].added = 0;
		pDphHashTable->pDphNodeArray[i].assocId = i;
	}

}

/* --------------------------------------------------------------------- */
/**
 * hash_function
 *
 * FUNCTION:
 * Hashing function
 *
 * LOGIC:
 *
 * ASSUMPTIONS:
 *
 * NOTE:
 *
 * @param staAddr MAC address of the station
 * @return None
 */

uint16_t hash_function(tpAniSirGlobal pMac, uint8_t staAddr[], uint16_t numSta)
{
	int i;
	uint16_t sum = 0;

	for (i = 0; i < 6; i++)
		sum += staAddr[i];

	return (sum % numSta);
}

/* --------------------------------------------------------------------- */
/**
 * dph_lookup_hash_entry
 *
 * FUNCTION:
 * Look up an entry in hash table
 *
 * LOGIC:
 *
 * ASSUMPTIONS:
 *
 * NOTE:
 *
 * @param staAddr MAC address of the station
 * @param pStaId pointer to the Station ID assigned to the station
 * @return pointer to STA hash entry if lookup was a success \n
 *         NULL if lookup was a failure
 */

tpDphHashNode dph_lookup_hash_entry(tpAniSirGlobal pMac, uint8_t staAddr[],
				    uint16_t *pAssocId,
				    dphHashTableClass *pDphHashTable)
{
	tpDphHashNode ptr = NULL;
	uint16_t index = hash_function(pMac, staAddr, pDphHashTable->size);

	for (ptr = pDphHashTable->pHashTable[index]; ptr; ptr = ptr->next) {
		if (dph_compare_mac_addr(staAddr, ptr->staAddr)) {
			*pAssocId = ptr->assocId;
			break;
		}
	}
	return ptr;
}

/* --------------------------------------------------------------------- */
/**
 * dph_get_hash_entry
 *
 * FUNCTION:
 * Get a pointer to the hash node
 *
 * LOGIC:
 *
 * ASSUMPTIONS:
 *
 * NOTE:
 *
 * @param staId Station ID
 * @return pointer to STA hash entry if lookup was a success \n
 *         NULL if lookup was a failure
 */

tpDphHashNode dph_get_hash_entry(tpAniSirGlobal pMac, uint16_t peerIdx,
				 dphHashTableClass *pDphHashTable)
{
	if (peerIdx < pDphHashTable->size) {
		if (pDphHashTable->pDphNodeArray[peerIdx].added)
			return &pDphHashTable->pDphNodeArray[peerIdx];
		else
			return NULL;
	} else
		return NULL;

}

static inline tpDphHashNode get_node(tpAniSirGlobal pMac, uint8_t assocId,
				     dphHashTableClass *pDphHashTable)
{
	return &pDphHashTable->pDphNodeArray[assocId];
}

/* --------------------------------------------------------------------- */
/**
 * dph_lookup_assoc_id
 *
 * FUNCTION:
 * This function looks up assocID given the station Id. It traverses the complete table to do this.
 * Need to find an efficient way to do this.
 * LOGIC:
 *
 * ASSUMPTIONS:
 *
 * NOTE:
 *
 * @param pMac pointer to global Mac structure.
 * @param staIdx station ID
 * @param *assocId pointer to associd to be returned by this function.
 * @return pointer to the dph node.
 */
tpDphHashNode dph_lookup_assoc_id(tpAniSirGlobal pMac, uint16_t staIdx,
				  uint16_t *assocId,
				  dphHashTableClass *pDphHashTable)
{
	uint8_t i;

	for (i = 0; i < pDphHashTable->size; i++) {
		if ((pDphHashTable->pDphNodeArray[i].added) &&
		    (pDphHashTable->pDphNodeArray[i].staIndex == staIdx)) {
			*assocId = i;
			break;
		}

	}
	if (i == pDphHashTable->size)
		return NULL;
	return &pDphHashTable->pDphNodeArray[i];

}

/** -------------------------------------------------------------
   \fn dph_init_sta_state
   \brief Initialize STA state. this function saves the staId from the current entry in the DPH table with given assocId
 \ if validStaIdx flag is set. Otherwise it sets the staId to invalid.
   \param  tpAniSirGlobal    pMac
   \param  tSirMacAddr staAddr
   \param  uint16_t assocId
   \param  uint8_t validStaIdx -   true ==> the staId in the DPH entry with given assocId is valid and restore it back.
 \                                              false ==> set the staId to invalid.
   \return tpDphHashNode - DPH hash node if found.
   -------------------------------------------------------------*/

tpDphHashNode dph_init_sta_state(tpAniSirGlobal pMac, tSirMacAddr staAddr,
				 uint16_t assocId, uint8_t validStaIdx,
				 dphHashTableClass *pDphHashTable)
{
	uint32_t val;

	tpDphHashNode pStaDs;
	uint16_t staIdx = STA_INVALID_IDX;

	if (assocId >= pDphHashTable->size) {
		PELOGE(lim_log(pMac, LOGE, FL("Invalid Assoc Id %d"), assocId);)
		return NULL;
	}

	pStaDs = get_node(pMac, (uint8_t) assocId, pDphHashTable);
	staIdx = pStaDs->staIndex;

	PELOG1(lim_log
		       (pMac, LOG1, FL("Assoc Id %d, Addr %08X"), assocId, pStaDs);
	       )
	/* Clear the STA node except for the next pointer (last 4 bytes) */
	cdf_mem_set((uint8_t *) pStaDs,
		    sizeof(tDphHashNode) - sizeof(tpDphHashNode), 0);

	/* Initialize the assocId */
	pStaDs->assocId = assocId;
	if (true == validStaIdx)
		pStaDs->staIndex = staIdx;
	else
		pStaDs->staIndex = STA_INVALID_IDX;

	/* Initialize STA mac address */
	cdf_mem_copy(pStaDs->staAddr, staAddr, sizeof(tSirMacAddr));

	/* Initialize fragmentation threshold */
	if (wlan_cfg_get_int(pMac, WNI_CFG_FRAGMENTATION_THRESHOLD, &val) !=
	    eSIR_SUCCESS)
		lim_log(pMac, LOGP,
			FL("could not retrieve fragmentation threshold"));
	else
		pStaDs->fragSize = (uint16_t) val;

	pStaDs->added = 1;
	pStaDs->encPolicy = ENC_POLICY_NULL;
	pStaDs->is_disassoc_deauth_in_progress = 0;
#ifdef WLAN_FEATURE_11W
	pStaDs->last_assoc_received_time = 0;
#endif
	pStaDs->valid = 1;
	return pStaDs;
}

/* --------------------------------------------------------------------- */
/**
 * dph_add_hash_entry
 *
 * FUNCTION:
 * Add entry to hash table
 *
 * LOGIC:
 *
 * ASSUMPTIONS:
 *
 * NOTE:
 *
 * @param staAddr MAC address of the station
 * @param staId Station ID assigned to the station
 * @return Pointer to STA hash entry
 */

tpDphHashNode dph_add_hash_entry(tpAniSirGlobal pMac, tSirMacAddr staAddr,
				 uint16_t assocId,
				 dphHashTableClass *pDphHashTable)
{
	tpDphHashNode ptr, node;
	uint16_t index = hash_function(pMac, staAddr, pDphHashTable->size);

	PELOG1(lim_log(pMac, LOG1, FL("assocId %d index %d STA addr"),
		       assocId, index); dph_print_mac_addr(pMac, staAddr, LOG1);
	       )

	if (assocId >= pDphHashTable->size) {
		PELOGE(lim_log(pMac, LOGE, FL("invalid STA id %d"), assocId);)
		return NULL;
	}

	if (pDphHashTable->pDphNodeArray[assocId].added) {
		PELOGE(lim_log(pMac, LOGE, FL("already added STA %d"), assocId);)
		return NULL;
	}

	for (ptr = pDphHashTable->pHashTable[index]; ptr; ptr = ptr->next) {
		if (ptr == ptr->next) {
			PELOGE(lim_log(pMac, LOGE, FL("Infinite Loop"));)
			return NULL;
		}

		if (dph_compare_mac_addr(staAddr, ptr->staAddr)
		    || ptr->assocId == assocId)
			break;
	}

	if (ptr) {
		/* Duplicate entry */
		lim_log(pMac, LOGE, FL("assocId %d hashIndex %d entry exists"),
			assocId, index);
		return NULL;
	} else {
		if (dph_init_sta_state
			    (pMac, staAddr, assocId, false, pDphHashTable) == NULL) {
			PELOGE(lim_log
				       (pMac, LOGE, FL("could not Init STAid=%d"),
				       assocId);
			       )
			return NULL;
		}
		/* Add the node to the link list */
		pDphHashTable->pDphNodeArray[assocId].next =
			pDphHashTable->pHashTable[index];
		pDphHashTable->pHashTable[index] =
			&pDphHashTable->pDphNodeArray[assocId];

		node = pDphHashTable->pHashTable[index];
		return node;
	}
}

/* --------------------------------------------------------------------- */
/**
 * dph_delete_hash_entry
 *
 * FUNCTION:
 * Delete entry from hash table
 *
 * LOGIC:
 *
 * ASSUMPTIONS:
 *
 * NOTE:
 *
 * @param staAddr MAC address of the station
 * @param staId Station ID assigned to the station
 * @return eSIR_SUCCESS if successful,\n
 *         eSIR_FAILURE otherwise
 */

tSirRetStatus dph_delete_hash_entry(tpAniSirGlobal pMac, tSirMacAddr staAddr,
				    uint16_t assocId,
				    dphHashTableClass *pDphHashTable)
{
	tpDphHashNode ptr, prev;
	uint16_t index = hash_function(pMac, staAddr, pDphHashTable->size);

	PELOG1(lim_log(pMac, LOG1, FL("assocId %d index %d STA addr"),
		       assocId, index); dph_print_mac_addr(pMac, staAddr, LOG1);
	       )

	if (assocId >= pDphHashTable->size) {
		PELOGE(lim_log(pMac, LOGE, FL("invalid STA id %d"), assocId);)
		return eSIR_FAILURE;
	}

	if (pDphHashTable->pDphNodeArray[assocId].added == 0) {
		PELOGE(lim_log(pMac, LOGE, FL("STA %d never added"), assocId);)
		return eSIR_FAILURE;
	}

	for (prev = 0, ptr = pDphHashTable->pHashTable[index];
	     ptr; prev = ptr, ptr = ptr->next) {
		if (dph_compare_mac_addr(staAddr, ptr->staAddr))
			break;
		if (prev == ptr) {
			PELOGE(lim_log(pMac, LOGE, FL("Infinite Loop"));)
			return eSIR_FAILURE;
		}
	}

	if (ptr) {
		/* / Delete the entry after invalidating it */
		ptr->valid = 0;
		memset(ptr->staAddr, 0, sizeof(ptr->staAddr));
		if (prev == 0)
			pDphHashTable->pHashTable[index] = ptr->next;
		else
			prev->next = ptr->next;
		ptr->added = 0;
		ptr->is_disassoc_deauth_in_progress = 0;
#ifdef WLAN_FEATURE_11W
		ptr->last_assoc_received_time = 0;
#endif
		ptr->next = 0;
	} else {
		/* / Entry not present */
		PELOGE(lim_log(pMac, LOGE, FL("Entry not present STA addr"));
		       dph_print_mac_addr(pMac, staAddr, LOGE);
		       )
		return eSIR_FAILURE;
	}

	return eSIR_SUCCESS;
}

/* --------------------------------------------------------------------- */
/**
 * dph_print_mac_addr
 *
 * FUNCTION:
 * Print a MAC address
 *
 * LOGIC:
 *
 * ASSUMPTIONS:
 *
 * NOTE:
 *
 * @param addr MAC address
 * @return None
 */

void dph_print_mac_addr(tpAniSirGlobal pMac, uint8_t addr[], uint32_t level)
{
	lim_log(pMac, (uint16_t) level, FL("MAC ADDR = %d:%d:%d:%d:%d:%d"),
		addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
}

/* --------------------------------------------------------------------- */


