qcacld-3.0: Add debug infra for sta_info ref count

Host driver uses reference count get and put implementation to
synchronize sta_info access. But it is very difficult to debug issues
where these reference count get and put are not used properly.

To address this, add a debug infra to identify the API where sta_info
ref count get and put handling is incorrect.

Change-Id: If384798f353ee66e149b4caabdc359379c69d072
CRs-Fixed: 2733933
This commit is contained in:
Bapiraju Alla
2020-07-14 23:29:34 +05:30
committed by snandini
parent 327afe4640
commit ede5f59a27
10 changed files with 407 additions and 132 deletions

View File

@@ -11249,8 +11249,9 @@ static int __wlan_hdd_cfg80211_get_link_properties(struct wiphy *wiphy,
return -EINVAL;
}
sta_info = hdd_get_sta_info_by_mac(&adapter->sta_info_list,
peer_mac);
sta_info = hdd_get_sta_info_by_mac(
&adapter->sta_info_list, peer_mac,
STA_INFO_CFG80211_GET_LINK_PROPERTIES);
if (!sta_info) {
hdd_err("No active peer with mac = " QDF_MAC_ADDR_STR,
@@ -11261,7 +11262,8 @@ static int __wlan_hdd_cfg80211_get_link_properties(struct wiphy *wiphy,
nss = sta_info->nss;
freq = (WLAN_HDD_GET_AP_CTX_PTR(adapter))->operating_chan_freq;
rate_flags = sta_info->rate_flags;
hdd_put_sta_info_ref(&adapter->sta_info_list, &sta_info, true);
hdd_put_sta_info_ref(&adapter->sta_info_list, &sta_info, true,
STA_INFO_CFG80211_GET_LINK_PROPERTIES);
} else {
hdd_err("Not Associated! with mac "QDF_MAC_ADDR_STR,
QDF_MAC_ADDR_ARRAY(peer_mac));
@@ -21138,11 +21140,15 @@ QDF_STATUS hdd_softap_deauth_current_sta(struct hdd_adapter *adapter,
if (QDF_IS_STATUS_SUCCESS(qdf_status)) {
if(qdf_is_macaddr_broadcast(&sta_info->sta_mac)) {
hdd_for_each_sta_ref_safe(adapter->sta_info_list,
sta_info, tmp) {
hdd_for_each_sta_ref_safe(
adapter->sta_info_list,
sta_info, tmp,
STA_INFO_SOFTAP_DEAUTH_CURRENT_STA) {
sta_info->is_deauth_in_progress = true;
hdd_put_sta_info_ref(&adapter->sta_info_list,
&sta_info, true);
hdd_put_sta_info_ref(
&adapter->sta_info_list,
&sta_info, true,
STA_INFO_SOFTAP_DEAUTH_CURRENT_STA);
}
} else {
sta_info->is_deauth_in_progress = true;
@@ -21199,7 +21205,8 @@ QDF_STATUS hdd_softap_deauth_all_sta(struct hdd_adapter *adapter,
hapd_state, param);
}
hdd_for_each_sta_ref_safe(adapter->sta_info_list, sta_info, tmp) {
hdd_for_each_sta_ref_safe(adapter->sta_info_list, sta_info, tmp,
STA_INFO_SOFTAP_DEAUTH_ALL_STA) {
if (!sta_info->is_deauth_in_progress) {
hdd_debug("Delete STA with MAC:" QDF_MAC_ADDR_STR,
QDF_MAC_ADDR_ARRAY(sta_info->sta_mac.bytes));
@@ -21210,16 +21217,20 @@ QDF_STATUS hdd_softap_deauth_all_sta(struct hdd_adapter *adapter,
hdd_softap_deauth_current_sta(adapter, sta_info,
hapd_state, param);
if (QDF_IS_STATUS_ERROR(status)) {
hdd_put_sta_info_ref(&adapter->sta_info_list,
&sta_info, true);
hdd_put_sta_info_ref(
&adapter->sta_info_list,
&sta_info, true,
STA_INFO_SOFTAP_DEAUTH_ALL_STA);
if (tmp)
hdd_put_sta_info_ref(
&adapter->sta_info_list,
&tmp, true);
&tmp, true,
STA_INFO_SOFTAP_DEAUTH_ALL_STA);
return status;
}
}
hdd_put_sta_info_ref(&adapter->sta_info_list, &sta_info, true);
hdd_put_sta_info_ref(&adapter->sta_info_list, &sta_info, true,
STA_INFO_SOFTAP_DEAUTH_ALL_STA);
}
return QDF_STATUS_SUCCESS;
@@ -21288,8 +21299,10 @@ int __wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
hdd_softap_check_wait_for_tx_eap_pkt(
adapter, (struct qdf_mac_addr *)mac);
sta_info = hdd_get_sta_info_by_mac(&adapter->sta_info_list,
mac);
sta_info = hdd_get_sta_info_by_mac(
&adapter->sta_info_list,
mac,
STA_INFO_CFG80211_DEL_STATION);
if (!sta_info) {
hdd_debug("Skip DEL STA as this is not used::"
@@ -21303,7 +21316,8 @@ int __wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
QDF_MAC_ADDR_STR,
QDF_MAC_ADDR_ARRAY(mac));
hdd_put_sta_info_ref(&adapter->sta_info_list, &sta_info,
true);
true,
STA_INFO_CFG80211_DEL_STATION);
return -ENOENT;
}
@@ -21311,7 +21325,8 @@ int __wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
QDF_MAC_ADDR_ARRAY(mac));
hdd_softap_deauth_current_sta(adapter, sta_info, hapd_state,
param);
hdd_put_sta_info_ref(&adapter->sta_info_list, &sta_info, true);
hdd_put_sta_info_ref(&adapter->sta_info_list, &sta_info, true,
STA_INFO_CFG80211_DEL_STATION);
}
fn_end:

View File

@@ -779,9 +779,11 @@ static void hdd_clear_all_sta(struct hdd_adapter *adapter)
hdd_enter_dev(adapter->dev);
hdd_for_each_sta_ref_safe(adapter->sta_info_list, sta_info, tmp) {
hdd_for_each_sta_ref_safe(adapter->sta_info_list, sta_info, tmp,
STA_INFO_HDD_CLEAR_ALL_STA) {
hdd_clear_sta(adapter, sta_info);
hdd_put_sta_info_ref(&adapter->sta_info_list, &sta_info, true);
hdd_put_sta_info_ref(&adapter->sta_info_list, &sta_info, true,
STA_INFO_HDD_CLEAR_ALL_STA);
}
}
@@ -1456,7 +1458,8 @@ static void hdd_fill_station_info(struct hdd_adapter *adapter,
bool is_dot11_mode_abgn;
stainfo = hdd_get_sta_info_by_mac(&adapter->sta_info_list,
event->staMac.bytes);
event->staMac.bytes,
STA_INFO_FILL_STATION_INFO);
if (!stainfo) {
hdd_err("invalid stainfo");
@@ -1529,7 +1532,8 @@ static void hdd_fill_station_info(struct hdd_adapter *adapter,
cache_sta_info =
hdd_get_sta_info_by_mac(&adapter->cache_sta_info_list,
event->staMac.bytes);
event->staMac.bytes,
STA_INFO_FILL_STATION_INFO);
if (!cache_sta_info) {
cache_sta_info = qdf_mem_malloc(sizeof(*cache_sta_info));
@@ -1566,7 +1570,8 @@ static void hdd_fill_station_info(struct hdd_adapter *adapter,
/* Find the oldest cached station */
hdd_for_each_sta_ref_safe(adapter->cache_sta_info_list,
temp_sta_info, tmp) {
temp_sta_info, tmp,
STA_INFO_FILL_STATION_INFO) {
if (temp_sta_info->disassoc_ts &&
(!oldest_disassoc_sta_ts ||
qdf_system_time_after(
@@ -1577,8 +1582,10 @@ static void hdd_fill_station_info(struct hdd_adapter *adapter,
oldest_disassoc_sta_info =
temp_sta_info;
}
hdd_put_sta_info_ref(sta_list, &temp_sta_info,
true);
hdd_put_sta_info_ref(
sta_list, &temp_sta_info,
true,
STA_INFO_FILL_STATION_INFO);
}
/* Remove the oldest and store the current */
@@ -1589,7 +1596,8 @@ static void hdd_fill_station_info(struct hdd_adapter *adapter,
}
} else {
hdd_put_sta_info_ref(&adapter->cache_sta_info_list,
&cache_sta_info, true);
&cache_sta_info, true,
STA_INFO_FILL_STATION_INFO);
}
hdd_debug("cap %d %d %d %d %d %d %d %d %d %x %d",
@@ -1611,7 +1619,8 @@ static void hdd_fill_station_info(struct hdd_adapter *adapter,
stainfo->rx_mcs_map,
stainfo->tx_mcs_map);
exit:
hdd_put_sta_info_ref(&adapter->sta_info_list, &stainfo, true);
hdd_put_sta_info_ref(&adapter->sta_info_list, &stainfo, true,
STA_INFO_FILL_STATION_INFO);
return;
}
@@ -2367,7 +2376,8 @@ QDF_STATUS hdd_hostapd_sap_event_cb(struct sap_event *sap_event,
cache_stainfo = hdd_get_sta_info_by_mac(
&adapter->cache_sta_info_list,
disassoc_comp->staMac.bytes);
disassoc_comp->staMac.bytes,
STA_INFO_HOSTAPD_SAP_EVENT_CB);
if (cache_stainfo) {
/* Cache the disassoc info */
cache_stainfo->rssi = disassoc_comp->rssi;
@@ -2385,7 +2395,8 @@ QDF_STATUS hdd_hostapd_sap_event_cb(struct sap_event *sap_event,
cache_stainfo->rx_rate,
cache_stainfo->reason_code);
hdd_put_sta_info_ref(&adapter->cache_sta_info_list,
&cache_stainfo, true);
&cache_stainfo, true,
STA_INFO_HOSTAPD_SAP_EVENT_CB);
}
hdd_nofl_info("SAP disassociated " QDF_MAC_ADDR_STR,
QDF_MAC_ADDR_ARRAY(wrqu.addr.sa_data));
@@ -2406,8 +2417,10 @@ QDF_STATUS hdd_hostapd_sap_event_cb(struct sap_event *sap_event,
QDF_TRACE_DEFAULT_PDEV_ID,
QDF_PROTO_TYPE_MGMT, QDF_PROTO_MGMT_DISASSOC));
stainfo = hdd_get_sta_info_by_mac(&adapter->sta_info_list,
disassoc_comp->staMac.bytes);
stainfo = hdd_get_sta_info_by_mac(
&adapter->sta_info_list,
disassoc_comp->staMac.bytes,
STA_INFO_HOSTAPD_SAP_EVENT_CB);
if (!stainfo) {
hdd_err("Failed to find the right station");
return QDF_STATUS_E_INVAL;
@@ -2423,25 +2436,30 @@ QDF_STATUS hdd_hostapd_sap_event_cb(struct sap_event *sap_event,
stainfo->dhcp_nego_status = DHCP_NEGO_STOP;
hdd_softap_deregister_sta(adapter, &stainfo);
hdd_put_sta_info_ref(&adapter->sta_info_list, &stainfo, true);
hdd_put_sta_info_ref(&adapter->sta_info_list, &stainfo, true,
STA_INFO_HOSTAPD_SAP_EVENT_CB);
ap_ctx->ap_active = false;
hdd_for_each_sta_ref_safe(adapter->sta_info_list, stainfo,
tmp) {
tmp, STA_INFO_HOSTAPD_SAP_EVENT_CB) {
if (!qdf_is_macaddr_broadcast(
&stainfo->sta_mac)) {
ap_ctx->ap_active = true;
hdd_put_sta_info_ref(&adapter->sta_info_list,
&stainfo, true);
hdd_put_sta_info_ref(
&adapter->sta_info_list,
&stainfo, true,
STA_INFO_HOSTAPD_SAP_EVENT_CB);
if (tmp)
hdd_put_sta_info_ref(
&adapter->sta_info_list,
&tmp, true);
&tmp, true,
STA_INFO_HOSTAPD_SAP_EVENT_CB);
break;
}
hdd_put_sta_info_ref(&adapter->sta_info_list,
&stainfo, true);
&stainfo, true,
STA_INFO_HOSTAPD_SAP_EVENT_CB);
}
#ifdef FEATURE_WLAN_AUTO_SHUTDOWN
@@ -6806,14 +6824,17 @@ void hdd_sap_indicate_disconnect_for_sta(struct hdd_adapter *adapter)
return;
}
hdd_for_each_sta_ref_safe(adapter->sta_info_list, sta_info, tmp) {
hdd_for_each_sta_ref_safe(adapter->sta_info_list, sta_info, tmp,
STA_INFO_SAP_INDICATE_DISCONNECT_FOR_STA) {
hdd_debug("sta_mac: " QDF_MAC_ADDR_STR,
QDF_MAC_ADDR_ARRAY(sta_info->sta_mac.bytes));
if (qdf_is_macaddr_broadcast(&sta_info->sta_mac)) {
hdd_softap_deregister_sta(adapter, &sta_info);
hdd_put_sta_info_ref(&adapter->sta_info_list,
&sta_info, true);
hdd_put_sta_info_ref(
&adapter->sta_info_list,
&sta_info, true,
STA_INFO_SAP_INDICATE_DISCONNECT_FOR_STA);
continue;
}
@@ -6822,7 +6843,8 @@ void hdd_sap_indicate_disconnect_for_sta(struct hdd_adapter *adapter)
qdf_mem_copy(
&sap_event.sapevt.sapStationDisassocCompleteEvent.staMac,
&sta_info->sta_mac, sizeof(struct qdf_mac_addr));
hdd_put_sta_info_ref(&adapter->sta_info_list, &sta_info, true);
hdd_put_sta_info_ref(&adapter->sta_info_list, &sta_info, true,
STA_INFO_SAP_INDICATE_DISCONNECT_FOR_STA);
sap_event.sapevt.sapStationDisassocCompleteEvent.reason =
eSAP_MAC_INITATED_DISASSOC;
@@ -6845,18 +6867,23 @@ bool hdd_is_peer_associated(struct hdd_adapter *adapter,
return false;
}
hdd_for_each_sta_ref_safe(adapter->sta_info_list, sta_info, tmp) {
hdd_for_each_sta_ref_safe(adapter->sta_info_list, sta_info, tmp,
STA_INFO_IS_PEER_ASSOCIATED) {
if (!qdf_mem_cmp(&sta_info->sta_mac, mac_addr,
QDF_MAC_ADDR_SIZE)) {
is_associated = true;
hdd_put_sta_info_ref(&adapter->sta_info_list,
&sta_info, true);
&sta_info, true,
STA_INFO_IS_PEER_ASSOCIATED);
if (tmp)
hdd_put_sta_info_ref(&adapter->sta_info_list,
&tmp, true);
hdd_put_sta_info_ref(
&adapter->sta_info_list,
&tmp, true,
STA_INFO_IS_PEER_ASSOCIATED);
break;
}
hdd_put_sta_info_ref(&adapter->sta_info_list, &sta_info, true);
hdd_put_sta_info_ref(&adapter->sta_info_list, &sta_info, true,
STA_INFO_IS_PEER_ASSOCIATED);
}
return is_associated;

View File

@@ -177,7 +177,9 @@ static int __iw_softap_set_two_ints_getnone(struct net_device *dev,
ret = cdp_txrx_stats_request(soc, adapter->vdev_id,
&req);
hdd_for_each_sta_ref(adapter->sta_info_list, sta_info) {
hdd_for_each_sta_ref(
adapter->sta_info_list, sta_info,
STA_INFO_SAP_SET_TWO_INTS_GETNONE) {
hdd_debug("bss_id: " QDF_MAC_ADDR_STR,
QDF_MAC_ADDR_ARRAY(
sta_info->sta_mac.bytes));
@@ -186,8 +188,10 @@ static int __iw_softap_set_two_ints_getnone(struct net_device *dev,
&sta_info->sta_mac;
ret = cdp_txrx_stats_request(
soc, adapter->vdev_id, &req);
hdd_put_sta_info_ref(&adapter->sta_info_list,
&sta_info, true);
hdd_put_sta_info_ref(
&adapter->sta_info_list, &sta_info,
true,
STA_INFO_SAP_SET_TWO_INTS_GETNONE);
}
} else {
ret = cdp_txrx_stats_request(soc, adapter->vdev_id,
@@ -1730,14 +1734,16 @@ static __iw_softap_getassoc_stamacaddr(struct net_device *dev,
maclist_index = sizeof(maclist_index);
left = wrqu->data.length - maclist_index;
hdd_for_each_sta_ref(adapter->sta_info_list, sta_info) {
hdd_for_each_sta_ref(adapter->sta_info_list, sta_info,
STA_INFO_SAP_GETASSOC_STAMACADDR) {
if (!qdf_is_macaddr_broadcast(&sta_info->sta_mac)) {
memcpy(&buf[maclist_index], &sta_info->sta_mac,
QDF_MAC_ADDR_SIZE);
maclist_index += QDF_MAC_ADDR_SIZE;
left -= QDF_MAC_ADDR_SIZE;
}
hdd_put_sta_info_ref(&adapter->sta_info_list, &sta_info, true);
hdd_put_sta_info_ref(&adapter->sta_info_list, &sta_info, true,
STA_INFO_SAP_GETASSOC_STAMACADDR);
}
*((u32 *) buf) = maclist_index;
@@ -2232,16 +2238,19 @@ static int hdd_softap_get_sta_info(struct hdd_adapter *adapter,
written = scnprintf(buf, size, "\nstaId staAddress\n");
hdd_for_each_sta_ref(adapter->sta_info_list, sta) {
hdd_for_each_sta_ref(adapter->sta_info_list, sta,
STA_INFO_SOFTAP_GET_STA_INFO) {
if (written >= size - 1) {
hdd_put_sta_info_ref(&adapter->sta_info_list,
&sta, true);
&sta, true,
STA_INFO_SOFTAP_GET_STA_INFO);
break;
}
if (QDF_IS_ADDR_BROADCAST(sta->sta_mac.bytes)) {
hdd_put_sta_info_ref(&adapter->sta_info_list,
&sta, true);
&sta, true,
STA_INFO_SOFTAP_GET_STA_INFO);
continue;
}
@@ -2255,7 +2264,8 @@ static int hdd_softap_get_sta_info(struct hdd_adapter *adapter,
sta->sta_mac.bytes[4],
sta->sta_mac.bytes[5],
sta->ecsa_capable);
hdd_put_sta_info_ref(&adapter->sta_info_list, &sta, true);
hdd_put_sta_info_ref(&adapter->sta_info_list, &sta, true,
STA_INFO_SOFTAP_GET_STA_INFO);
}
hdd_exit();
@@ -2499,17 +2509,21 @@ int __iw_get_softap_linkspeed(struct net_device *dev,
if (wrqu->data.length < 17 || !QDF_IS_STATUS_SUCCESS(status)) {
struct hdd_station_info *sta_info;
hdd_for_each_sta_ref(adapter->sta_info_list, sta_info) {
hdd_for_each_sta_ref(adapter->sta_info_list, sta_info,
STA_INFO_GET_SOFTAP_LINKSPEED) {
if (!qdf_is_macaddr_broadcast(&sta_info->sta_mac)) {
qdf_copy_macaddr(&mac_address,
&sta_info->sta_mac);
status = QDF_STATUS_SUCCESS;
hdd_put_sta_info_ref(&adapter->sta_info_list,
&sta_info, true);
hdd_put_sta_info_ref(
&adapter->sta_info_list,
&sta_info, true,
STA_INFO_GET_SOFTAP_LINKSPEED);
break;
}
hdd_put_sta_info_ref(&adapter->sta_info_list,
&sta_info, true);
&sta_info, true,
STA_INFO_GET_SOFTAP_LINKSPEED);
}
}
if (!QDF_IS_STATUS_SUCCESS(status)) {

View File

@@ -16952,11 +16952,13 @@ static QDF_STATUS hdd_is_connection_in_progress_iterator(
}
} else if ((QDF_SAP_MODE == adapter->device_mode) ||
(QDF_P2P_GO_MODE == adapter->device_mode)) {
hdd_for_each_sta_ref(adapter->sta_info_list, sta_info) {
hdd_for_each_sta_ref(adapter->sta_info_list, sta_info,
STA_INFO_CONNECTION_IN_PROGRESS_ITERATOR) {
if (sta_info->peer_state !=
OL_TXRX_PEER_STATE_CONN) {
hdd_put_sta_info_ref(&adapter->sta_info_list,
&sta_info, true);
hdd_put_sta_info_ref(
&adapter->sta_info_list, &sta_info, true,
STA_INFO_CONNECTION_IN_PROGRESS_ITERATOR);
continue;
}
@@ -16969,8 +16971,9 @@ static QDF_STATUS hdd_is_connection_in_progress_iterator(
context->out_reason = SAP_EAPOL_IN_PROGRESS;
context->connection_in_progress = true;
hdd_put_sta_info_ref(&adapter->sta_info_list,
&sta_info, true);
hdd_put_sta_info_ref(
&adapter->sta_info_list, &sta_info, true,
STA_INFO_CONNECTION_IN_PROGRESS_ITERATOR);
return QDF_STATUS_E_ABORTED;
}

View File

@@ -291,7 +291,8 @@ static void hdd_softap_inspect_tx_eap_pkt(struct hdd_adapter *adapter,
return;
mac_addr = (struct qdf_mac_addr *)skb->data;
sta_info = hdd_get_sta_info_by_mac(&adapter->sta_info_list,
mac_addr->bytes);
mac_addr->bytes,
STA_INFO_SOFTAP_INSPECT_TX_EAP_PKT);
if (!sta_info)
return;
if (tx_comp) {
@@ -306,7 +307,8 @@ static void hdd_softap_inspect_tx_eap_pkt(struct hdd_adapter *adapter,
&sta_info->pending_eap_frm_type);
QDF_NBUF_CB_TX_EXTRA_FRAG_FLAGS_NOTIFY_COMP(skb) = 1;
}
hdd_put_sta_info_ref(&adapter->sta_info_list, &sta_info, true);
hdd_put_sta_info_ref(&adapter->sta_info_list, &sta_info, true,
STA_INFO_SOFTAP_INSPECT_TX_EAP_PKT);
}
void hdd_softap_check_wait_for_tx_eap_pkt(struct hdd_adapter *adapter,
@@ -323,8 +325,10 @@ void hdd_softap_check_wait_for_tx_eap_pkt(struct hdd_adapter *adapter,
hdd_err("Hostapd State is not START");
return;
}
sta_info = hdd_get_sta_info_by_mac(&adapter->sta_info_list,
mac_addr->bytes);
sta_info = hdd_get_sta_info_by_mac(
&adapter->sta_info_list,
mac_addr->bytes,
STA_INFO_SOFTAP_CHECK_WAIT_FOR_TX_EAP_PKT);
if (!sta_info)
return;
if (qdf_atomic_test_bit(PENDING_TYPE_EAP_FAILURE,
@@ -336,7 +340,8 @@ void hdd_softap_check_wait_for_tx_eap_pkt(struct hdd_adapter *adapter,
if (!QDF_IS_STATUS_SUCCESS(qdf_status))
hdd_debug("eap_failure tx timeout");
}
hdd_put_sta_info_ref(&adapter->sta_info_list, &sta_info, true);
hdd_put_sta_info_ref(&adapter->sta_info_list, &sta_info, true,
STA_INFO_SOFTAP_CHECK_WAIT_FOR_TX_EAP_PKT);
}
#ifdef SAP_DHCP_FW_IND
@@ -431,8 +436,10 @@ int hdd_softap_inspect_dhcp_packet(struct hdd_adapter *adapter,
DHCP_CLIENT_MAC_ADDR_OFFSET);
subtype = qdf_nbuf_get_dhcp_subtype(skb);
hdd_sta_info = hdd_get_sta_info_by_mac(&adapter->sta_info_list,
src_mac->bytes);
hdd_sta_info = hdd_get_sta_info_by_mac(
&adapter->sta_info_list,
src_mac->bytes,
STA_INFO_SOFTAP_INSPECT_DHCP_PACKET);
if (!hdd_sta_info) {
hdd_debug("Station not found");
return -EINVAL;
@@ -490,7 +497,7 @@ int hdd_softap_inspect_dhcp_packet(struct hdd_adapter *adapter,
hdd_sta_info->dhcp_phase,
hdd_sta_info->dhcp_nego_status);
hdd_put_sta_info_ref(&adapter->sta_info_list, &hdd_sta_info,
true);
true, STA_INFO_SOFTAP_INSPECT_DHCP_PACKET);
}
return errno;
@@ -582,7 +589,8 @@ static void __hdd_softap_hard_start_xmit(struct sk_buff *skb,
mac_addr = dest_mac_addr;
sta_info = hdd_get_sta_info_by_mac(&adapter->sta_info_list,
mac_addr->bytes);
mac_addr->bytes,
STA_INFO_SOFTAP_HARD_START_XMIT);
if (!QDF_NBUF_CB_GET_IS_BCAST(skb) && !QDF_NBUF_CB_GET_IS_MCAST(skb)) {
if (!sta_info) {
@@ -709,7 +717,8 @@ static void __hdd_softap_hard_start_xmit(struct sk_buff *skb,
netif_trans_update(dev);
wlan_hdd_sar_unsolicited_timer_start(hdd_ctx);
hdd_put_sta_info_ref(&adapter->sta_info_list, &sta_info, true);
hdd_put_sta_info_ref(&adapter->sta_info_list, &sta_info, true,
STA_INFO_SOFTAP_HARD_START_XMIT);
return;
@@ -723,7 +732,8 @@ drop_pkt:
drop_pkt_accounting:
if (sta_info)
hdd_put_sta_info_ref(&adapter->sta_info_list, &sta_info, true);
hdd_put_sta_info_ref(&adapter->sta_info_list, &sta_info, true,
STA_INFO_SOFTAP_HARD_START_XMIT);
++adapter->stats.tx_dropped;
++adapter->hdd_stats.tx_rx_stats.tx_dropped;
}
@@ -941,7 +951,8 @@ static QDF_STATUS hdd_sta_info_re_attach(
hdd_reset_sta_info_during_reattach(sta_info);
/* Add one extra ref for reattach */
qdf_atomic_inc(&sta_info->ref_cnt);
hdd_take_sta_info_ref(sta_info_container, sta_info, false,
STA_INFO_ATTACH_DETACH);
qdf_mem_copy(&sta_info->sta_mac, sta_mac, sizeof(struct qdf_mac_addr));
sta_info->is_attached = true;
qdf_spin_unlock_bh(&sta_info_container->sta_obj_lock);
@@ -956,14 +967,16 @@ QDF_STATUS hdd_softap_init_tx_rx_sta(struct hdd_adapter *adapter,
QDF_STATUS status;
sta_info = hdd_get_sta_info_by_mac(&adapter->sta_info_list,
sta_mac->bytes);
sta_mac->bytes,
STA_INFO_SOFTAP_INIT_TX_RX_STA);
if (sta_info) {
hdd_err("Reinit of in use station " QDF_MAC_ADDR_STR,
QDF_MAC_ADDR_ARRAY(sta_mac->bytes));
status = hdd_sta_info_re_attach(&adapter->sta_info_list,
sta_info, sta_mac);
hdd_put_sta_info_ref(&adapter->sta_info_list, &sta_info, true);
hdd_put_sta_info_ref(&adapter->sta_info_list, &sta_info, true,
STA_INFO_SOFTAP_INIT_TX_RX_STA);
return status;
}
@@ -1104,8 +1117,10 @@ QDF_STATUS hdd_softap_rx_packet_cbk(void *adapter_context, qdf_nbuf_t rx_buf)
/* Send DHCP Indication to FW */
src_mac = (struct qdf_mac_addr *)(skb->data +
QDF_NBUF_SRC_MAC_OFFSET);
sta_info = hdd_get_sta_info_by_mac(&adapter->sta_info_list,
(uint8_t *)src_mac);
sta_info = hdd_get_sta_info_by_mac(
&adapter->sta_info_list,
(uint8_t *)src_mac,
STA_INFO_SOFTAP_RX_PACKET_CBK);
if (sta_info) {
sta_info->rx_packets++;
@@ -1113,7 +1128,8 @@ QDF_STATUS hdd_softap_rx_packet_cbk(void *adapter_context, qdf_nbuf_t rx_buf)
sta_info->last_tx_rx_ts = qdf_system_ticks();
hdd_softap_inspect_dhcp_packet(adapter, skb, QDF_RX);
hdd_put_sta_info_ref(&adapter->sta_info_list, &sta_info,
true);
true,
STA_INFO_SOFTAP_RX_PACKET_CBK);
}
hdd_event_eapol_log(skb, QDF_RX);
@@ -1247,7 +1263,8 @@ QDF_STATUS hdd_softap_register_sta(struct hdd_adapter *adapter,
qdf_status = hdd_softap_init_tx_rx_sta(adapter, sta_mac);
sta_info = hdd_get_sta_info_by_mac(&adapter->sta_info_list,
sta_mac->bytes);
sta_mac->bytes,
STA_INFO_SOFTAP_REGISTER_STA);
if (!sta_info) {
hdd_debug("STA not found");
@@ -1282,7 +1299,8 @@ QDF_STATUS hdd_softap_register_sta(struct hdd_adapter *adapter,
if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
hdd_debug("cdp_peer_register() failed to register. Status = %d [0x%08X]",
qdf_status, qdf_status);
hdd_put_sta_info_ref(&adapter->sta_info_list, &sta_info, true);
hdd_put_sta_info_ref(&adapter->sta_info_list, &sta_info, true,
STA_INFO_SOFTAP_REGISTER_STA);
return qdf_status;
}
@@ -1324,7 +1342,8 @@ QDF_STATUS hdd_softap_register_sta(struct hdd_adapter *adapter,
sta_info->peer_state = OL_TXRX_PEER_STATE_CONN;
}
hdd_put_sta_info_ref(&adapter->sta_info_list, &sta_info, true);
hdd_put_sta_info_ref(&adapter->sta_info_list, &sta_info, true,
STA_INFO_SOFTAP_REGISTER_STA);
hdd_debug("Enabling queues");
wlan_hdd_netif_queue_control(adapter,
WLAN_START_ALL_NETIF_QUEUE_N_CARRIER,
@@ -1382,9 +1401,11 @@ QDF_STATUS hdd_softap_stop_bss(struct hdd_adapter *adapter)
* object leak
*/
hdd_for_each_sta_ref_safe(adapter->sta_info_list, sta_info, tmp) {
hdd_for_each_sta_ref_safe(adapter->sta_info_list, sta_info, tmp,
STA_INFO_SOFTAP_STOP_BSS) {
status = hdd_softap_deregister_sta(adapter, &sta_info);
hdd_put_sta_info_ref(&adapter->sta_info_list, &sta_info, true);
hdd_put_sta_info_ref(&adapter->sta_info_list, &sta_info, true,
STA_INFO_SOFTAP_STOP_BSS);
}
if (adapter->device_mode == QDF_SAP_MODE &&
@@ -1423,7 +1444,8 @@ QDF_STATUS hdd_softap_change_sta_state(struct hdd_adapter *adapter,
hdd_enter_dev(adapter->dev);
sta_info = hdd_get_sta_info_by_mac(&adapter->sta_info_list,
sta_mac->bytes);
sta_mac->bytes,
STA_INFO_SOFTAP_CHANGE_STA_STATE);
if (!sta_info) {
hdd_debug("Failed to find right station MAC: " QDF_MAC_ADDR_STR,
@@ -1452,7 +1474,8 @@ QDF_STATUS hdd_softap_change_sta_state(struct hdd_adapter *adapter,
}
}
hdd_put_sta_info_ref(&adapter->sta_info_list, &sta_info, true);
hdd_put_sta_info_ref(&adapter->sta_info_list, &sta_info, true,
STA_INFO_SOFTAP_CHANGE_STA_STATE);
hdd_exit();
return qdf_status;
}

View File

@@ -28,6 +28,52 @@
#define HDD_MAX_PEERS 32
char *sta_info_string_from_dbgid(wlan_sta_info_dbgid id)
{
static const char *strings[] = {
"STA_INFO_ID_RESERVED",
"STA_INFO_CFG80211_GET_LINK_PROPERTIES",
"STA_INFO_SOFTAP_INSPECT_TX_EAP_PKT",
"STA_INFO_SOFTAP_CHECK_WAIT_FOR_TX_EAP_PKT",
"STA_INFO_SOFTAP_INSPECT_DHCP_PACKET",
"STA_INFO_SOFTAP_HARD_START_XMIT",
"STA_INFO_SOFTAP_INIT_TX_RX_STA",
"STA_INFO_SOFTAP_RX_PACKET_CBK",
"STA_INFO_SOFTAP_REGISTER_STA",
"STA_INFO_GET_CACHED_STATION_REMOTE",
"STA_INFO_HDD_GET_STATION_REMOTE",
"STA_INFO_WLAN_HDD_GET_STATION_REMOTE",
"STA_INFO_SOFTAP_DEAUTH_CURRENT_STA",
"STA_INFO_SOFTAP_DEAUTH_ALL_STA",
"STA_INFO_CFG80211_DEL_STATION",
"STA_INFO_HDD_CLEAR_ALL_STA",
"STA_INFO_FILL_STATION_INFO",
"STA_INFO_HOSTAPD_SAP_EVENT_CB",
"STA_INFO_SAP_INDICATE_DISCONNECT_FOR_STA",
"STA_INFO_IS_PEER_ASSOCIATED",
"STA_INFO_SAP_SET_TWO_INTS_GETNONE",
"STA_INFO_SAP_GETASSOC_STAMACADDR",
"STA_INFO_SOFTAP_GET_STA_INFO",
"STA_INFO_GET_SOFTAP_LINKSPEED",
"STA_INFO_CONNECTION_IN_PROGRESS_ITERATOR",
"STA_INFO_SOFTAP_STOP_BSS",
"STA_INFO_SOFTAP_CHANGE_STA_STATE",
"STA_INFO_CLEAR_CACHED_STA_INFO",
"STA_INFO_ATTACH_DETACH",
"STA_INFO_SHOW",
"STA_INFO_ID_MAX"};
int32_t num_dbg_strings = QDF_ARRAY_SIZE(strings);
if (id >= num_dbg_strings) {
char *ret = "";
hdd_err("Debug string not found for debug id %d", id);
return ret;
}
return (char *)strings[id];
}
QDF_STATUS hdd_sta_info_init(struct hdd_sta_info_obj *sta_info_container)
{
if (!sta_info_container) {
@@ -62,7 +108,8 @@ QDF_STATUS hdd_sta_info_attach(struct hdd_sta_info_obj *sta_info_container,
qdf_spin_lock_bh(&sta_info_container->sta_obj_lock);
qdf_atomic_set(&sta_info->ref_cnt, 1);
hdd_take_sta_info_ref(sta_info_container, sta_info, false,
STA_INFO_ATTACH_DETACH);
qdf_list_insert_front(&sta_info_container->sta_obj,
&sta_info->sta_node);
sta_info->is_attached = true;
@@ -91,7 +138,8 @@ void hdd_sta_info_detach(struct hdd_sta_info_obj *sta_info_container,
if (info->is_attached) {
info->is_attached = false;
hdd_put_sta_info_ref(sta_info_container, sta_info, false);
hdd_put_sta_info_ref(sta_info_container, sta_info, false,
STA_INFO_ATTACH_DETACH);
} else {
hdd_info("Stainfo is already detached");
}
@@ -101,7 +149,8 @@ void hdd_sta_info_detach(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)
const uint8_t *mac_addr,
wlan_sta_info_dbgid sta_info_dbgid)
{
struct hdd_station_info *sta_info = NULL;
@@ -116,7 +165,7 @@ struct hdd_station_info *hdd_get_sta_info_by_mac(
if (qdf_is_macaddr_equal(&sta_info->sta_mac,
(struct qdf_mac_addr *)mac_addr)) {
hdd_take_sta_info_ref(sta_info_container,
sta_info, false);
sta_info, false, sta_info_dbgid);
qdf_spin_unlock_bh(&sta_info_container->sta_obj_lock);
return sta_info;
}
@@ -129,17 +178,24 @@ struct hdd_station_info *hdd_get_sta_info_by_mac(
void hdd_take_sta_info_ref(struct hdd_sta_info_obj *sta_info_container,
struct hdd_station_info *sta_info,
bool lock_required)
bool lock_required,
wlan_sta_info_dbgid sta_info_dbgid)
{
if (!sta_info_container || !sta_info) {
hdd_err("Parameter(s) null");
return;
}
if (sta_info_dbgid >= STA_INFO_ID_MAX) {
hdd_err("Invalid sta_info debug id %d", sta_info_dbgid);
return;
}
if (lock_required)
qdf_spin_lock_bh(&sta_info_container->sta_obj_lock);
qdf_atomic_inc(&sta_info->ref_cnt);
qdf_atomic_inc(&sta_info->ref_cnt_dbgid[sta_info_dbgid]);
if (lock_required)
qdf_spin_unlock_bh(&sta_info_container->sta_obj_lock);
@@ -147,7 +203,8 @@ void hdd_take_sta_info_ref(struct hdd_sta_info_obj *sta_info_container,
void
hdd_put_sta_info_ref(struct hdd_sta_info_obj *sta_info_container,
struct hdd_station_info **sta_info, bool lock_required)
struct hdd_station_info **sta_info, bool lock_required,
wlan_sta_info_dbgid sta_info_dbgid)
{
struct hdd_station_info *info;
struct qdf_mac_addr addr;
@@ -164,6 +221,11 @@ hdd_put_sta_info_ref(struct hdd_sta_info_obj *sta_info_container,
return;
}
if (sta_info_dbgid >= STA_INFO_ID_MAX) {
hdd_err("Invalid sta_info debug id %d", sta_info_dbgid);
return;
}
if (lock_required)
qdf_spin_lock_bh(&sta_info_container->sta_obj_lock);
@@ -173,12 +235,15 @@ hdd_put_sta_info_ref(struct hdd_sta_info_obj *sta_info_container,
* the root cause would be known and the buggy put_ref can be taken
* care of.
*/
if (!qdf_atomic_read(&info->ref_cnt)) {
hdd_alert("sta_info ref count is already 0");
if (!qdf_atomic_read(&info->ref_cnt_dbgid[sta_info_dbgid])) {
hdd_err("Sta_info ref count put is detected without get for debug id %s",
sta_info_string_from_dbgid(sta_info_dbgid));
QDF_BUG(0);
}
qdf_atomic_dec(&info->ref_cnt);
qdf_atomic_dec(&info->ref_cnt_dbgid[sta_info_dbgid]);
if (qdf_atomic_read(&info->ref_cnt)) {
if (lock_required)
@@ -213,10 +278,11 @@ void hdd_clear_cached_sta_info(struct hdd_adapter *adapter)
return;
}
hdd_for_each_sta_ref_safe(adapter->cache_sta_info_list, sta_info, tmp) {
hdd_for_each_sta_ref_safe(adapter->cache_sta_info_list, sta_info, tmp,
STA_INFO_CLEAR_CACHED_STA_INFO) {
hdd_sta_info_detach(&adapter->cache_sta_info_list, &sta_info);
hdd_put_sta_info_ref(&adapter->cache_sta_info_list, &sta_info,
true);
true, STA_INFO_CLEAR_CACHED_STA_INFO);
}
}

View File

@@ -71,6 +71,93 @@ enum dhcp_nego_status {
*/
#define PENDING_TYPE_EAP_FAILURE 0
/**
* enum wlan_sta_info_dbgid - sta info put/get debug id
* @STA_INFO_ID_RESERVED: Reserved
* @STA_INFO_CFG80211_GET_LINK_PROPERTIES: Get link properties
* @STA_INFO_SOFTAP_INSPECT_TX_EAP_PKT: Inspect the EAP-Failure
* @STA_INFO_SOFTAP_CHECK_WAIT_FOR_TX_EAP_PKT: Check and wait for eap failure
* pkt tx completion
* @STA_INFO_SOFTAP_INSPECT_DHCP_PACKET: Inspect DHCP packet
* @STA_INFO_SOFTAP_HARD_START_XMIT: Transmit a frame
* @STA_INFO_SOFTAP_INIT_TX_RX_STA: Initialize Tx/Rx for a softap station
* @STA_INFO_SOFTAP_RX_PACKET_CBK: Receive packet handler
* @STA_INFO_SOFTAP_REGISTER_STA: Register a SoftAP STA
* @STA_INFO_GET_CACHED_STATION_REMOTE: Get cached peer's info
* @STA_INFO_HDD_GET_STATION_REMOTE: Get remote peer's info
* @STA_INFO_WLAN_HDD_GET_STATION_REMOTE: NL80211_CMD_GET_STATION handler for
* SoftAP
* @STA_INFO_SOFTAP_DEAUTH_CURRENT_STA: Deauth current sta
* @STA_INFO_SOFTAP_DEAUTH_ALL_STA: Deauth all sta in the sta list
* @STA_INFO_CFG80211_DEL_STATION: CFG80211 del station handler
* @STA_INFO_HDD_CLEAR_ALL_STA: Clear all stations
* @STA_INFO_FILL_STATION_INFO: Fill stainfo for connected station
* @STA_INFO_HOSTAPD_SAP_EVENT_CB: SAP event handler
* @STA_INFO_SAP_INDICATE_DISCONNECT_FOR_STA: Indicating disconnect indication
* to the supplicant
* @STA_INFO_IS_PEER_ASSOCIATED: Is peer connected to softap
* @STA_INFO_SAP_SET_TWO_INTS_GETNONE: Generic "set two integer" ioctl handler
* @STA_INFO_SAP_GETASSOC_STAMACADDR: Handler to get assoc station mac address
* @STA_INFO_SOFTAP_GET_STA_INFO: Get station info handler
* @STA_INFO_GET_SOFTAP_LINKSPEED: Get link speed handler
* @STA_INFO_CONNECTION_IN_PROGRESS_ITERATOR: Check adapter connection based on
* device mode
* @STA_INFO_SOFTAP_STOP_BSS: Stop BSS
* @STA_INFO_SOFTAP_CHANGE_STA_STATE: Change the state of a SoftAP station
* @STA_INFO_CLEAR_CACHED_STA_INFO: Clear the cached sta info
* @STA_INFO_ATTACH_DETACH: Station info attach/detach
* @STA_INFO_SHOW: Station info show
*
*/
/*
* New value added to the enum must also be reflected in function
* sta_info_string_from_dbgid()
*/
typedef enum {
STA_INFO_ID_RESERVED = 0,
STA_INFO_CFG80211_GET_LINK_PROPERTIES = 1,
STA_INFO_SOFTAP_INSPECT_TX_EAP_PKT = 2,
STA_INFO_SOFTAP_CHECK_WAIT_FOR_TX_EAP_PKT = 3,
STA_INFO_SOFTAP_INSPECT_DHCP_PACKET = 4,
STA_INFO_SOFTAP_HARD_START_XMIT = 5,
STA_INFO_SOFTAP_INIT_TX_RX_STA = 6,
STA_INFO_SOFTAP_RX_PACKET_CBK = 7,
STA_INFO_SOFTAP_REGISTER_STA = 8,
STA_INFO_GET_CACHED_STATION_REMOTE = 9,
STA_INFO_HDD_GET_STATION_REMOTE = 10,
STA_INFO_WLAN_HDD_GET_STATION_REMOTE = 11,
STA_INFO_SOFTAP_DEAUTH_CURRENT_STA = 12,
STA_INFO_SOFTAP_DEAUTH_ALL_STA = 13,
STA_INFO_CFG80211_DEL_STATION = 14,
STA_INFO_HDD_CLEAR_ALL_STA = 15,
STA_INFO_FILL_STATION_INFO = 16,
STA_INFO_HOSTAPD_SAP_EVENT_CB = 17,
STA_INFO_SAP_INDICATE_DISCONNECT_FOR_STA = 18,
STA_INFO_IS_PEER_ASSOCIATED = 19,
STA_INFO_SAP_SET_TWO_INTS_GETNONE = 20,
STA_INFO_SAP_GETASSOC_STAMACADDR = 21,
STA_INFO_SOFTAP_GET_STA_INFO = 22,
STA_INFO_GET_SOFTAP_LINKSPEED = 23,
STA_INFO_CONNECTION_IN_PROGRESS_ITERATOR = 24,
STA_INFO_SOFTAP_STOP_BSS = 25,
STA_INFO_SOFTAP_CHANGE_STA_STATE = 26,
STA_INFO_CLEAR_CACHED_STA_INFO = 27,
STA_INFO_ATTACH_DETACH = 28,
STA_INFO_SHOW = 29,
STA_INFO_ID_MAX,
} wlan_sta_info_dbgid;
/**
* sta_info_string_from_dbgid() - Convert dbgid to respective string
* @id - debug id
*
* Debug support function to convert dbgid to string.
* Please note to add new string in the array at index equal to
* its enum value in wlan_sta_info_dbgid.
*/
char *sta_info_string_from_dbgid(wlan_sta_info_dbgid id);
/**
* struct hdd_station_info - Per station structure kept in HDD for
* multiple station support for SoftAP
@@ -127,6 +214,7 @@ enum dhcp_nego_status {
* @sta_info: The sta_info node for the station info list maintained in adapter
* @assoc_req_ies: Assoc request IEs of the peer station
* @ref_cnt: Reference count to synchronize sta_info access
* @ref_cnt_dbgid: Reference count to debug sta_info synchronization issues
* @pending_eap_frm_type: EAP frame type in tx queue without tx completion
* @is_attached: Flag to check if the stainfo is attached/detached
*/
@@ -179,6 +267,7 @@ struct hdd_station_info {
qdf_list_node_t sta_node;
struct wlan_ies assoc_req_ies;
qdf_atomic_t ref_cnt;
qdf_atomic_t ref_cnt_dbgid[STA_INFO_ID_MAX];
unsigned long pending_eap_frm_type;
bool is_attached;
};
@@ -198,18 +287,23 @@ struct hdd_sta_info_obj {
* @sta_info_container: The station info container obj that stores and maintains
* the sta_info obj.
* @sta_info: Station info structure to be released.
* @lock_required: Flag to acquire lock or not
* @sta_info_dbgid: Debug ID of the caller API
*
* Return: None
*/
void hdd_put_sta_info_ref(struct hdd_sta_info_obj *sta_info_container,
struct hdd_station_info **sta_info,
bool lock_required);
bool lock_required,
wlan_sta_info_dbgid sta_info_dbgid);
/**
* hdd_take_sta_info_ref() - Increment sta info ref.
* @sta_info_container: The station info container obj that stores and maintains
* the sta_info obj.
* @sta_info: Station info structure to be released.
* @lock_required: Flag to acquire lock or not
* @sta_info_dbgid: Debug ID of the caller API
*
* This function has to be accompanied by hdd_put_sta_info when the work with
* the sta info is done. Failure to do so will result in a mem leak.
@@ -218,7 +312,8 @@ void hdd_put_sta_info_ref(struct hdd_sta_info_obj *sta_info_container,
*/
void hdd_take_sta_info_ref(struct hdd_sta_info_obj *sta_info_container,
struct hdd_station_info *sta_info,
bool lock_required);
bool lock_required,
wlan_sta_info_dbgid sta_info_dbgid);
/**
* hdd_get_front_sta_info_no_lock() - Get the first sta_info from the sta list
@@ -261,11 +356,13 @@ hdd_get_next_sta_info_no_lock(struct hdd_sta_info_obj *sta_info_container,
* the sta_info obj.
* @sta_info: The station info structure that acts as the iterator object.
*/
#define __hdd_take_ref_and_fetch_front_sta_info(sta_info_container, sta_info) \
#define __hdd_take_ref_and_fetch_front_sta_info(sta_info_container, sta_info, \
sta_info_dbgid) \
qdf_spin_lock_bh(&sta_info_container.sta_obj_lock), \
hdd_get_front_sta_info_no_lock(&sta_info_container, &sta_info), \
(sta_info) ? hdd_take_sta_info_ref(&sta_info_container, \
sta_info, false) : (false), \
sta_info, false, sta_info_dbgid) : \
(false), \
qdf_spin_unlock_bh(&sta_info_container.sta_obj_lock)
/**
@@ -275,12 +372,14 @@ hdd_get_next_sta_info_no_lock(struct hdd_sta_info_obj *sta_info_container,
* the sta_info obj.
* @sta_info: The station info structure that acts as the iterator object.
*/
#define __hdd_take_ref_and_fetch_next_sta_info(sta_info_container, sta_info) \
#define __hdd_take_ref_and_fetch_next_sta_info(sta_info_container, sta_info, \
sta_info_dbgid) \
qdf_spin_lock_bh(&sta_info_container.sta_obj_lock), \
hdd_get_next_sta_info_no_lock(&sta_info_container, sta_info, \
&sta_info), \
(sta_info) ? hdd_take_sta_info_ref(&sta_info_container, \
sta_info, false) : (false), \
sta_info, false, sta_info_dbgid) : \
(false), \
qdf_spin_unlock_bh(&sta_info_container.sta_obj_lock)
/**
@@ -289,6 +388,7 @@ hdd_get_next_sta_info_no_lock(struct hdd_sta_info_obj *sta_info_container,
* @sta_info_container: The station info container obj that stores and maintains
* the sta_info obj.
* @sta_info: The station info structure that acts as the iterator object.
* @sta_info_dbgid: Debug ID of the caller API
*
* The sta_info will contain the structure that is fetched for that particular
* iteration.
@@ -299,18 +399,19 @@ hdd_get_next_sta_info_no_lock(struct hdd_sta_info_obj *sta_info_container,
* unregister of the netdevice.
*
* Usage example:
* hdd_for_each_sta_ref(sta_info_container, sta_info) {
* hdd_for_each_sta_ref(sta_info_container, sta_info, sta_info_dbgid) {
* <work involving station>
* <some more work>
* hdd_put_sta_info_ref(sta_info_container, sta_info, true)
* hdd_put_sta_info_ref(sta_info_container, sta_info, true,
* sta_info_dbgid)
* }
*/
#define hdd_for_each_sta_ref(sta_info_container, sta_info) \
#define hdd_for_each_sta_ref(sta_info_container, sta_info, sta_info_dbgid) \
for (__hdd_take_ref_and_fetch_front_sta_info(sta_info_container, \
sta_info); \
sta_info, sta_info_dbgid);\
__hdd_is_station_valid(sta_info); \
__hdd_take_ref_and_fetch_next_sta_info(sta_info_container, \
sta_info))
sta_info, sta_info_dbgid))
/**
* __hdd_take_ref_and_fetch_front_sta_info_safe - Helper macro to lock, fetch
@@ -320,15 +421,18 @@ hdd_get_next_sta_info_no_lock(struct hdd_sta_info_obj *sta_info_container,
* @sta_info: The station info structure that acts as the iterator object.
*/
#define __hdd_take_ref_and_fetch_front_sta_info_safe(sta_info_container, \
sta_info, next_sta_info) \
sta_info, next_sta_info, \
sta_info_dbgid) \
qdf_spin_lock_bh(&sta_info_container.sta_obj_lock), \
hdd_get_front_sta_info_no_lock(&sta_info_container, &sta_info), \
(sta_info) ? hdd_take_sta_info_ref(&sta_info_container, \
sta_info, false) : (false), \
sta_info, false, sta_info_dbgid) : \
(false), \
hdd_get_next_sta_info_no_lock(&sta_info_container, sta_info, \
&next_sta_info), \
(next_sta_info) ? hdd_take_sta_info_ref(&sta_info_container, \
next_sta_info, false) : \
next_sta_info, false, \
sta_info_dbgid) : \
(false), \
qdf_spin_unlock_bh(&sta_info_container.sta_obj_lock)
@@ -340,13 +444,16 @@ hdd_get_next_sta_info_no_lock(struct hdd_sta_info_obj *sta_info_container,
* @sta_info: The station info structure that acts as the iterator object.
*/
#define __hdd_take_ref_and_fetch_next_sta_info_safe(sta_info_container, \
sta_info, next_sta_info) \
sta_info, next_sta_info, \
sta_info_dbgid) \
sta_info = next_sta_info, \
qdf_spin_lock_bh(&sta_info_container.sta_obj_lock), \
hdd_get_next_sta_info_no_lock(&sta_info_container, sta_info, \
&next_sta_info), \
(next_sta_info) ? hdd_take_sta_info_ref(&sta_info_container, \
next_sta_info, false) : (false), \
next_sta_info, false, \
sta_info_dbgid) : \
(false), \
qdf_spin_unlock_bh(&sta_info_container.sta_obj_lock)
/**
@@ -356,6 +463,7 @@ hdd_get_next_sta_info_no_lock(struct hdd_sta_info_obj *sta_info_container,
* the sta_info obj.
* @sta_info: The station info structure that acts as the iterator object.
* @next_sta_info: A temporary node for maintaing del safe.
* @sta_info_dbgid: Debug ID of the caller API
*
* The sta_info will contain the structure that is fetched for that particular
* iteration. The next_sta_info is used to store the next station before the
@@ -368,20 +476,25 @@ hdd_get_next_sta_info_no_lock(struct hdd_sta_info_obj *sta_info_container,
* deletion of the station info
*
* Usage example:
* hdd_for_each_sta_ref_safe(sta_info_container, sta_info, next_sta_info) {
* hdd_for_each_sta_ref_safe(sta_info_container, sta_info, next_sta_info,
* sta_info_dbgid) {
* <work involving station>
* <some more work>
* hdd_put_sta_info_ref(sta_info_container, sta_info, true)
* hdd_put_sta_info_ref(sta_info_container, sta_info, true,
* sta_info_dbgid)
* }
*/
#define hdd_for_each_sta_ref_safe(sta_info_container, sta_info, next_sta_info) \
#define hdd_for_each_sta_ref_safe(sta_info_container, sta_info, next_sta_info, \
sta_info_dbgid) \
for (__hdd_take_ref_and_fetch_front_sta_info_safe(sta_info_container, \
sta_info, \
next_sta_info); \
next_sta_info, \
sta_info_dbgid); \
__hdd_is_station_valid(sta_info); \
__hdd_take_ref_and_fetch_next_sta_info_safe(sta_info_container, \
sta_info, \
next_sta_info))
next_sta_info, \
sta_info_dbgid))
/**
* wlan_sta_info_init() - Initialise the wlan hdd station info container obj
@@ -430,13 +543,15 @@ QDF_STATUS hdd_sta_info_attach(struct hdd_sta_info_obj *sta_info_container,
* @sta_info_container: The station info container obj that stores and maintains
* the sta_info obj.
* @mac_addr: The mac addr by which the sta_info has to be fetched.
* @sta_info_dbgid: Debug ID of the caller API
*
* Return: Pointer to the hdd_station_info structure which contains the mac
* address passed
*/
struct hdd_station_info *hdd_get_sta_info_by_mac(
struct hdd_sta_info_obj *sta_info_container,
const uint8_t *mac_addr);
const uint8_t *mac_addr,
wlan_sta_info_dbgid sta_info_dbgid);
/**
* hdd_clear_cached_sta_info() - Clear the cached sta info from the container

View File

@@ -1091,7 +1091,8 @@ static int hdd_get_cached_station_remote(struct hdd_context *hdd_ctx,
uint8_t channel_width;
stainfo = hdd_get_sta_info_by_mac(&adapter->cache_sta_info_list,
mac_addr.bytes);
mac_addr.bytes,
STA_INFO_GET_CACHED_STATION_REMOTE);
if (!stainfo) {
hdd_err("peer " QDF_MAC_ADDR_STR " not found",
@@ -1117,7 +1118,8 @@ static int hdd_get_cached_station_remote(struct hdd_context *hdd_ctx,
skb = cfg80211_vendor_cmd_alloc_reply_skb(hdd_ctx->wiphy, nl_buf_len);
if (!skb) {
hdd_put_sta_info_ref(&adapter->cache_sta_info_list,
&stainfo, true);
&stainfo, true,
STA_INFO_GET_CACHED_STATION_REMOTE);
hdd_err("cfg80211_vendor_cmd_alloc_reply_skb failed");
return -ENOMEM;
}
@@ -1186,12 +1188,14 @@ static int hdd_get_cached_station_remote(struct hdd_context *hdd_ctx,
}
}
hdd_sta_info_detach(&adapter->cache_sta_info_list, &stainfo);
hdd_put_sta_info_ref(&adapter->cache_sta_info_list, &stainfo, true);
hdd_put_sta_info_ref(&adapter->cache_sta_info_list, &stainfo, true,
STA_INFO_GET_CACHED_STATION_REMOTE);
qdf_atomic_dec(&adapter->cache_sta_count);
return cfg80211_vendor_cmd_reply(skb);
fail:
hdd_put_sta_info_ref(&adapter->cache_sta_info_list, &stainfo, true);
hdd_put_sta_info_ref(&adapter->cache_sta_info_list, &stainfo, true,
STA_INFO_GET_CACHED_STATION_REMOTE);
if (skb)
kfree_skb(skb);
@@ -1336,8 +1340,10 @@ static int hdd_get_station_remote(struct hdd_context *hdd_ctx,
int status = 0;
bool is_associated = false;
struct hdd_station_info *stainfo =
hdd_get_sta_info_by_mac(&adapter->sta_info_list,
mac_addr.bytes);
hdd_get_sta_info_by_mac(
&adapter->sta_info_list,
mac_addr.bytes,
STA_INFO_HDD_GET_STATION_REMOTE);
if (!stainfo) {
status = hdd_get_cached_station_remote(hdd_ctx, adapter,
@@ -1349,13 +1355,15 @@ static int hdd_get_station_remote(struct hdd_context *hdd_ctx,
if (!is_associated) {
status = hdd_get_cached_station_remote(hdd_ctx, adapter,
mac_addr);
hdd_put_sta_info_ref(&adapter->sta_info_list, &stainfo, true);
hdd_put_sta_info_ref(&adapter->sta_info_list, &stainfo, true,
STA_INFO_HDD_GET_STATION_REMOTE);
return status;
}
status = hdd_get_connected_station_info(hdd_ctx, adapter,
mac_addr, stainfo);
hdd_put_sta_info_ref(&adapter->sta_info_list, &stainfo, true);
hdd_put_sta_info_ref(&adapter->sta_info_list, &stainfo, true,
STA_INFO_HDD_GET_STATION_REMOTE);
return status;
}

View File

@@ -4231,7 +4231,8 @@ static int wlan_hdd_get_station_remote(struct wiphy *wiphy,
hdd_debug("Peer %pM", mac);
stainfo = hdd_get_sta_info_by_mac(&adapter->sta_info_list, mac);
stainfo = hdd_get_sta_info_by_mac(&adapter->sta_info_list, mac,
STA_INFO_WLAN_HDD_GET_STATION_REMOTE);
if (!stainfo) {
hdd_err("peer %pM not found", mac);
return -EINVAL;
@@ -4240,7 +4241,8 @@ static int wlan_hdd_get_station_remote(struct wiphy *wiphy,
qdf_mem_copy(macaddr.bytes, mac, QDF_MAC_ADDR_SIZE);
status = wlan_hdd_get_peer_info(adapter, macaddr, &peer_info);
if (status) {
hdd_put_sta_info_ref(&adapter->sta_info_list, &stainfo, true);
hdd_put_sta_info_ref(&adapter->sta_info_list, &stainfo, true,
STA_INFO_WLAN_HDD_GET_STATION_REMOTE);
hdd_err("fail to get peer info from fw");
return -EPERM;
}
@@ -4255,7 +4257,8 @@ static int wlan_hdd_get_station_remote(struct wiphy *wiphy,
txrx_stats.rssi = peer_info.rssi + WLAN_HDD_TGT_NOISE_FLOOR_DBM;
wlan_hdd_fill_rate_info(&txrx_stats, &peer_info);
wlan_hdd_fill_station_info(hddctx->psoc, sinfo, stainfo, &txrx_stats);
hdd_put_sta_info_ref(&adapter->sta_info_list, &stainfo, true);
hdd_put_sta_info_ref(&adapter->sta_info_list, &stainfo, true,
STA_INFO_WLAN_HDD_GET_STATION_REMOTE);
return status;
}

View File

@@ -49,10 +49,10 @@ static ssize_t __show_sta_info(struct net_device *net_dev, char *buf)
"%s get_sta_info:\nstaAddress\n",
net_dev->name);
hdd_for_each_sta_ref(adapter->sta_info_list, sta) {
hdd_for_each_sta_ref(adapter->sta_info_list, sta, STA_INFO_SHOW) {
if (QDF_IS_ADDR_BROADCAST(sta->sta_mac.bytes)) {
hdd_put_sta_info_ref(&adapter->sta_info_list, &sta,
true);
true, STA_INFO_SHOW);
continue;
}
ret_val += scnprintf(buf + ret_val, PAGE_SIZE - ret_val,
@@ -65,7 +65,8 @@ static ssize_t __show_sta_info(struct net_device *net_dev, char *buf)
sta->sta_mac.bytes[5],
sta->ecsa_capable);
hdd_put_sta_info_ref(&adapter->sta_info_list, &sta, true);
hdd_put_sta_info_ref(&adapter->sta_info_list, &sta, true,
STA_INFO_SHOW);
}
exit: