qcacld-3.0: Move cache sta info to hash based
Currently in hdd_adapter, the variable cache_sta_info is an array of hdd_station_info structured indexed by the sta_id. As sta_id is no longer used, this array based implementation becomes unnecessary. Move the sta_info implementation to a hash table implementation. Change-Id: Iac11ecd2ae4a454649235cf8763e9a5f80e7eb38 CRs-Fixed: 2515316
This commit is contained in:
parent
43e6dea453
commit
c320ada27c
@ -1042,6 +1042,7 @@ struct hdd_context;
|
||||
* @event_flags: a bitmap of hdd_adapter_flags
|
||||
* @mic_work: mic work information
|
||||
* @gpio_tsf_sync_work: work to sync send TSF CAP WMI command
|
||||
* @cache_sta_count: number of currently cached stations
|
||||
*
|
||||
*/
|
||||
struct hdd_adapter {
|
||||
@ -1145,6 +1146,7 @@ struct hdd_adapter {
|
||||
/* TODO: _list from name will be removed after clean up */
|
||||
struct hdd_sta_info_obj sta_info_list;
|
||||
struct hdd_sta_info_obj cache_sta_info_list;
|
||||
qdf_atomic_t cache_sta_count;
|
||||
|
||||
#ifdef FEATURE_WLAN_WAPI
|
||||
struct hdd_wapi_info wapi_info;
|
||||
|
@ -1443,15 +1443,11 @@ static int hdd_convert_dot11mode_from_phymode(int phymode)
|
||||
static void hdd_fill_station_info(struct hdd_adapter *adapter,
|
||||
tSap_StationAssocReassocCompleteEvent *event)
|
||||
{
|
||||
struct hdd_station_info *stainfo;
|
||||
uint8_t i = 0, oldest_disassoc_sta_idx = WLAN_MAX_STA_COUNT + 1;
|
||||
struct hdd_station_info *stainfo, *cache_sta_info;
|
||||
struct hdd_station_info *oldest_disassoc_sta_info = NULL;
|
||||
uint8_t index = 0;
|
||||
qdf_time_t oldest_disassoc_sta_ts = 0;
|
||||
|
||||
if (event->staId >= WLAN_MAX_STA_COUNT) {
|
||||
hdd_err("invalid sta id");
|
||||
return;
|
||||
}
|
||||
|
||||
stainfo = hdd_get_sta_info_by_mac(&adapter->sta_info_list,
|
||||
event->staMac.bytes);
|
||||
|
||||
@ -1512,48 +1508,57 @@ static void hdd_fill_station_info(struct hdd_adapter *adapter,
|
||||
stainfo->dhcp_phase = DHCP_PHASE_ACK;
|
||||
stainfo->dhcp_nego_status = DHCP_NEGO_STOP;
|
||||
|
||||
while (i < WLAN_MAX_STA_COUNT) {
|
||||
if (!qdf_mem_cmp(adapter->cache_sta_info[i].sta_mac.bytes,
|
||||
event->staMac.bytes,
|
||||
QDF_MAC_ADDR_SIZE))
|
||||
break;
|
||||
i++;
|
||||
}
|
||||
if (i >= WLAN_MAX_STA_COUNT) {
|
||||
i = 0;
|
||||
while (i < WLAN_MAX_STA_COUNT) {
|
||||
if (adapter->cache_sta_info[i].in_use != TRUE)
|
||||
break;
|
||||
cache_sta_info =
|
||||
hdd_get_sta_info_by_mac(&adapter->cache_sta_info_list,
|
||||
event->staMac.bytes);
|
||||
|
||||
if (adapter->cache_sta_info[i].disassoc_ts &&
|
||||
(!oldest_disassoc_sta_ts ||
|
||||
(qdf_system_time_after(
|
||||
oldest_disassoc_sta_ts,
|
||||
adapter->
|
||||
cache_sta_info[i].disassoc_ts)))) {
|
||||
oldest_disassoc_sta_ts =
|
||||
adapter->
|
||||
cache_sta_info[i].disassoc_ts;
|
||||
oldest_disassoc_sta_idx = i;
|
||||
if (!cache_sta_info) {
|
||||
cache_sta_info = qdf_mem_malloc(sizeof(*cache_sta_info));
|
||||
if (!cache_sta_info)
|
||||
return;
|
||||
|
||||
qdf_mem_copy(cache_sta_info, stainfo, sizeof(*cache_sta_info));
|
||||
qdf_mem_zero(&cache_sta_info->sta_node,
|
||||
sizeof(cache_sta_info->sta_node));
|
||||
|
||||
/*
|
||||
* If cache_sta_info is not present and cache limit is not
|
||||
* reached, then create and attach. Else find the cache that is
|
||||
* the oldest and replace that with the new cache.
|
||||
*/
|
||||
if (qdf_atomic_read(&adapter->cache_sta_count) <
|
||||
WLAN_MAX_STA_COUNT) {
|
||||
hdd_sta_info_attach(&adapter->cache_sta_info_list,
|
||||
cache_sta_info);
|
||||
qdf_atomic_inc(&adapter->cache_sta_count);
|
||||
} else {
|
||||
struct hdd_station_info *temp_sta_info;
|
||||
|
||||
hdd_debug("reached max caching, removing oldest");
|
||||
|
||||
/* Find the oldest cached station */
|
||||
hdd_for_each_station(adapter->cache_sta_info_list,
|
||||
temp_sta_info, index) {
|
||||
if (temp_sta_info->disassoc_ts &&
|
||||
(!oldest_disassoc_sta_ts ||
|
||||
qdf_system_time_after(
|
||||
oldest_disassoc_sta_ts,
|
||||
temp_sta_info->disassoc_ts))) {
|
||||
oldest_disassoc_sta_ts =
|
||||
temp_sta_info->disassoc_ts;
|
||||
oldest_disassoc_sta_info =
|
||||
temp_sta_info;
|
||||
}
|
||||
}
|
||||
i++;
|
||||
|
||||
/* Remove the oldest and store the current */
|
||||
hdd_sta_info_detach(&adapter->cache_sta_info_list,
|
||||
oldest_disassoc_sta_info);
|
||||
hdd_sta_info_attach(&adapter->cache_sta_info_list,
|
||||
cache_sta_info);
|
||||
}
|
||||
}
|
||||
|
||||
if ((i == WLAN_MAX_STA_COUNT) && oldest_disassoc_sta_ts) {
|
||||
hdd_debug("reached max cached sta_id, removing oldest stainfo");
|
||||
i = oldest_disassoc_sta_idx;
|
||||
}
|
||||
if (i < WLAN_MAX_STA_COUNT) {
|
||||
qdf_mem_zero(&adapter->cache_sta_info[i],
|
||||
sizeof(*stainfo));
|
||||
qdf_mem_copy(&adapter->cache_sta_info[i],
|
||||
stainfo, sizeof(struct hdd_station_info));
|
||||
|
||||
} else {
|
||||
hdd_debug("reached max sta_id, stainfo can't be cached");
|
||||
}
|
||||
|
||||
hdd_debug("cap %d %d %d %d %d %d %d %d %d %x %d",
|
||||
stainfo->ampdu,
|
||||
stainfo->sgi_enable,
|
||||
@ -2323,8 +2328,9 @@ QDF_STATUS hdd_hostapd_sap_event_cb(struct sap_event *sap_event,
|
||||
memcpy(wrqu.addr.sa_data,
|
||||
&disassoc_comp->staMac, QDF_MAC_ADDR_SIZE);
|
||||
|
||||
cache_stainfo = hdd_get_stainfo(adapter->cache_sta_info,
|
||||
disassoc_comp->staMac);
|
||||
cache_stainfo = hdd_get_sta_info_by_mac(
|
||||
&adapter->cache_sta_info_list,
|
||||
disassoc_comp->staMac.bytes);
|
||||
if (cache_stainfo) {
|
||||
/* Cache the disassoc info */
|
||||
cache_stainfo->rssi = disassoc_comp->rssi;
|
||||
@ -3353,6 +3359,9 @@ QDF_STATUS hdd_init_ap_mode(struct hdd_adapter *adapter, bool reinit)
|
||||
/* Register as a wireless device */
|
||||
hdd_register_hostapd_wext(adapter->dev);
|
||||
|
||||
/* Cache station count initialize to zero */
|
||||
qdf_atomic_init(&adapter->cache_sta_count);
|
||||
|
||||
/* Initialize the data path module */
|
||||
hdd_softap_init_tx_rx(adapter);
|
||||
|
||||
@ -3362,6 +3371,12 @@ QDF_STATUS hdd_init_ap_mode(struct hdd_adapter *adapter, bool reinit)
|
||||
goto error_release_softap_tx_rx;
|
||||
}
|
||||
|
||||
status = hdd_sta_info_init(&adapter->cache_sta_info_list);
|
||||
if (QDF_IS_STATUS_ERROR(status)) {
|
||||
hdd_err("cache sta info init failed");
|
||||
goto error_release_sta_info;
|
||||
}
|
||||
|
||||
status = hdd_wmm_adapter_init(adapter);
|
||||
if (!QDF_IS_STATUS_SUCCESS(status)) {
|
||||
hdd_err("hdd_wmm_adapter_init() failed code: %08d [x%08x]",
|
||||
@ -3402,6 +3417,8 @@ QDF_STATUS hdd_init_ap_mode(struct hdd_adapter *adapter, bool reinit)
|
||||
return status;
|
||||
|
||||
error_release_wmm:
|
||||
hdd_sta_info_deinit(&adapter->cache_sta_info_list);
|
||||
error_release_sta_info:
|
||||
hdd_sta_info_deinit(&adapter->sta_info_list);
|
||||
error_release_softap_tx_rx:
|
||||
hdd_softap_deinit_tx_rx(adapter);
|
||||
|
@ -4233,6 +4233,9 @@ hdd_alloc_station_adapter(struct hdd_context *hdd_ctx, tSirMacAddr mac_addr,
|
||||
adapter->disconnection_in_progress = false;
|
||||
adapter->send_mode_change = true;
|
||||
|
||||
/* Cache station count initialize to zero */
|
||||
qdf_atomic_init(&adapter->cache_sta_count);
|
||||
|
||||
/* Init the net_device structure */
|
||||
strlcpy(dev->name, name, IFNAMSIZ);
|
||||
|
||||
@ -4856,8 +4859,10 @@ static void hdd_cleanup_adapter(struct hdd_context *hdd_ctx,
|
||||
qdf_spinlock_destroy(&adapter->vdev_lock);
|
||||
|
||||
if (adapter->device_mode == QDF_SAP_MODE ||
|
||||
adapter->device_mode == QDF_P2P_GO_MODE)
|
||||
adapter->device_mode == QDF_P2P_GO_MODE) {
|
||||
hdd_sta_info_deinit(&adapter->sta_info_list);
|
||||
hdd_sta_info_deinit(&adapter->cache_sta_info_list);
|
||||
}
|
||||
|
||||
wlan_hdd_debugfs_csr_deinit(adapter);
|
||||
if (adapter->device_mode == QDF_STA_MODE)
|
||||
@ -6048,6 +6053,9 @@ QDF_STATUS hdd_stop_adapter(struct hdd_context *hdd_ctx,
|
||||
qdf_mem_free(adapter->session.ap.beacon);
|
||||
adapter->session.ap.beacon = NULL;
|
||||
|
||||
/* Clear all the cached sta info */
|
||||
hdd_clear_cached_sta_info(&adapter->cache_sta_info_list);
|
||||
|
||||
/*
|
||||
* If Do_Not_Break_Stream was enabled clear avoid channel list.
|
||||
*/
|
||||
@ -6321,8 +6329,10 @@ QDF_STATUS hdd_reset_all_adapters(struct hdd_context *hdd_ctx)
|
||||
|
||||
hdd_softap_deinit_tx_rx(adapter);
|
||||
if (adapter->device_mode == QDF_SAP_MODE ||
|
||||
adapter->device_mode == QDF_P2P_GO_MODE)
|
||||
adapter->device_mode == QDF_P2P_GO_MODE) {
|
||||
hdd_sta_info_deinit(&adapter->sta_info_list);
|
||||
hdd_sta_info_deinit(&adapter->cache_sta_info_list);
|
||||
}
|
||||
|
||||
hdd_deregister_hl_netdev_fc_timer(adapter);
|
||||
hdd_deregister_tx_flow_control(adapter);
|
||||
|
@ -116,3 +116,22 @@ struct hdd_station_info *hdd_get_sta_info_by_mac(
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void hdd_clear_cached_sta_info(struct hdd_sta_info_obj *sta_info_container)
|
||||
{
|
||||
struct hdd_station_info *sta_info = NULL;
|
||||
uint8_t index = 0;
|
||||
struct qdf_ht_entry *tmp;
|
||||
|
||||
if (!sta_info_container) {
|
||||
hdd_err("Parameter null");
|
||||
return;
|
||||
}
|
||||
|
||||
qdf_ht_for_each_safe(sta_info_container->sta_obj, index, tmp, sta_info,
|
||||
sta_node) {
|
||||
if (sta_info) {
|
||||
hdd_sta_info_detach(sta_info_container, sta_info);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -266,5 +266,13 @@ QDF_STATUS hdd_sta_info_attach(struct hdd_sta_info_obj *sta_info_container,
|
||||
struct hdd_station_info *hdd_get_sta_info_by_mac(
|
||||
struct hdd_sta_info_obj *sta_info_container,
|
||||
const uint8_t *mac_addr);
|
||||
/**
|
||||
* hdd_clear_cached_sta_info() - Clear the cached sta info from the container
|
||||
* @sta_info_container: The station info container obj that stores and maintains
|
||||
* the sta_info obj.
|
||||
*
|
||||
* Return: None
|
||||
*/
|
||||
void hdd_clear_cached_sta_info(struct hdd_sta_info_obj *sta_info_container);
|
||||
|
||||
#endif /* __WLAN_HDD_STA_INFO_H */
|
||||
|
@ -996,13 +996,14 @@ static int hdd_get_cached_station_remote(struct hdd_context *hdd_ctx,
|
||||
struct hdd_adapter *adapter,
|
||||
struct qdf_mac_addr mac_addr)
|
||||
{
|
||||
struct hdd_station_info *stainfo = hdd_get_stainfo(
|
||||
adapter->cache_sta_info,
|
||||
mac_addr);
|
||||
struct hdd_station_info *stainfo;
|
||||
struct sk_buff *skb = NULL;
|
||||
uint32_t nl_buf_len = NLMSG_HDRLEN;
|
||||
uint8_t channel_width;
|
||||
|
||||
stainfo = hdd_get_sta_info_by_mac(&adapter->cache_sta_info_list,
|
||||
mac_addr.bytes);
|
||||
|
||||
if (!stainfo) {
|
||||
hdd_err("peer " QDF_MAC_ADDR_STR " not found",
|
||||
QDF_MAC_ADDR_ARRAY(mac_addr.bytes));
|
||||
@ -1081,7 +1082,8 @@ static int hdd_get_cached_station_remote(struct hdd_context *hdd_ctx,
|
||||
}
|
||||
}
|
||||
|
||||
qdf_mem_zero(stainfo, sizeof(*stainfo));
|
||||
hdd_sta_info_detach(&adapter->cache_sta_info_list, stainfo);
|
||||
qdf_atomic_dec(&adapter->cache_sta_count);
|
||||
|
||||
return cfg80211_vendor_cmd_reply(skb);
|
||||
fail:
|
||||
|
Loading…
Reference in New Issue
Block a user