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:
Sourav Mohapatra 2019-09-03 16:15:03 +05:30 committed by nshrivas
parent 43e6dea453
commit c320ada27c
6 changed files with 110 additions and 52 deletions

View File

@ -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;

View File

@ -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);

View File

@ -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);

View File

@ -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);
}
}
}

View File

@ -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 */

View File

@ -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: