blob: 961b05f10d81489caf84c400c807360ca0acab34 [file] [log] [blame]
/*
* Copyright (c) 2019 The Linux Foundation. All rights reserved.
*
* 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.
*/
/**
* DOC: wlan_hdd_sta_info.c
*
* Store and manage station info structure.
*
*/
#include "wlan_hdd_sta_info.h"
#include <wlan_hdd_includes.h>
/* Generate a numeric constant to form the key to be provided for hashing */
#define WLAN_HDD_STA_INFO_HASH(addr) \
(((const uint8_t *)addr)[QDF_MAC_ADDR_SIZE - 1])
QDF_STATUS hdd_sta_info_init(struct hdd_sta_info_obj *sta_info_container)
{
if (!sta_info_container) {
hdd_err("Parameter null");
return QDF_STATUS_E_INVAL;
}
qdf_spinlock_create(&sta_info_container->sta_obj_lock);
qdf_ht_init(sta_info_container->sta_obj);
return QDF_STATUS_SUCCESS;
}
void hdd_sta_info_deinit(struct hdd_sta_info_obj *sta_info_container)
{
if (!sta_info_container) {
hdd_err("Parameter null");
return;
}
qdf_ht_deinit(sta_info_container->sta_obj);
qdf_spinlock_destroy(&sta_info_container->sta_obj_lock);
}
QDF_STATUS hdd_sta_info_attach(struct hdd_sta_info_obj *sta_info_container,
struct hdd_station_info *sta_info)
{
if (!sta_info_container || !sta_info) {
hdd_err("Parameter(s) null");
return QDF_STATUS_E_INVAL;
}
qdf_spin_lock_bh(&sta_info_container->sta_obj_lock);
qdf_ht_add(sta_info_container->sta_obj, &sta_info->sta_node,
WLAN_HDD_STA_INFO_HASH(sta_info->sta_mac.bytes));
qdf_spin_unlock_bh(&sta_info_container->sta_obj_lock);
return QDF_STATUS_SUCCESS;
}
void hdd_sta_info_detach(struct hdd_sta_info_obj *sta_info_container,
struct hdd_station_info *sta_info)
{
if (!sta_info_container || !sta_info) {
hdd_err("Parameter(s) null");
return;
}
qdf_spin_lock_bh(&sta_info_container->sta_obj_lock);
qdf_ht_remove(&sta_info->sta_node);
qdf_spin_unlock_bh(&sta_info_container->sta_obj_lock);
qdf_mem_free(sta_info);
sta_info = NULL;
}
struct hdd_station_info *hdd_get_sta_info_by_mac(
struct hdd_sta_info_obj *sta_info_container,
const uint8_t *mac_addr)
{
struct hdd_station_info *sta_info = NULL;
if (!mac_addr || !sta_info_container) {
hdd_err("Parameter(s) null");
return NULL;
}
qdf_spin_lock_bh(&sta_info_container->sta_obj_lock);
qdf_ht_for_each_in_bucket(sta_info_container->sta_obj, sta_info,
sta_node, WLAN_HDD_STA_INFO_HASH(mac_addr)) {
if (qdf_is_macaddr_equal(&sta_info->sta_mac,
(struct qdf_mac_addr *)mac_addr)) {
qdf_spin_unlock_bh(&sta_info_container->sta_obj_lock);
return sta_info;
}
}
qdf_spin_unlock_bh(&sta_info_container->sta_obj_lock);
return NULL;
}