qcacmn: remove peer backpointer in DP ast entry

Remove the peer backpointer in ast entry and store
peer_id instead

Assign peer_id in AST entry in AST MAP event,
also add the ast entry to peers ast list

In AST map & AST unmap APIs use ast find by vdev_id

Change-Id: I74d9828dc309149d98f6f577b5c8304cb087fd76
This commit is contained in:
Chaithanya Garrepalli
2020-08-14 14:30:02 +05:30
committed by snandini
parent fdc6a808ae
commit f4701f13ec
8 changed files with 193 additions and 115 deletions

View File

@@ -861,25 +861,32 @@ static bool dp_peer_get_ast_info_by_soc_wifi3
{ {
struct dp_ast_entry *ast_entry = NULL; struct dp_ast_entry *ast_entry = NULL;
struct dp_soc *soc = (struct dp_soc *)soc_hdl; struct dp_soc *soc = (struct dp_soc *)soc_hdl;
struct dp_peer *peer = NULL;
qdf_spin_lock_bh(&soc->ast_lock); qdf_spin_lock_bh(&soc->ast_lock);
ast_entry = dp_peer_ast_hash_find_soc(soc, ast_mac_addr); ast_entry = dp_peer_ast_hash_find_soc(soc, ast_mac_addr);
if (!ast_entry || !ast_entry->peer) { if ((!ast_entry) ||
(ast_entry->delete_in_progress && !ast_entry->callback)) {
qdf_spin_unlock_bh(&soc->ast_lock); qdf_spin_unlock_bh(&soc->ast_lock);
return false; return false;
} }
if (ast_entry->delete_in_progress && !ast_entry->callback) {
peer = dp_peer_get_ref_by_id(soc, ast_entry->peer_id,
DP_MOD_ID_AST);
if (!peer) {
qdf_spin_unlock_bh(&soc->ast_lock); qdf_spin_unlock_bh(&soc->ast_lock);
return false; return false;
} }
ast_entry_info->type = ast_entry->type; ast_entry_info->type = ast_entry->type;
ast_entry_info->pdev_id = ast_entry->pdev_id; ast_entry_info->pdev_id = ast_entry->pdev_id;
ast_entry_info->vdev_id = ast_entry->peer->vdev->vdev_id; ast_entry_info->vdev_id = ast_entry->vdev_id;
ast_entry_info->peer_id = ast_entry->peer->peer_id; ast_entry_info->peer_id = ast_entry->peer_id;
qdf_mem_copy(&ast_entry_info->peer_mac_addr[0], qdf_mem_copy(&ast_entry_info->peer_mac_addr[0],
&ast_entry->peer->mac_addr.raw[0], &peer->mac_addr.raw[0],
QDF_MAC_ADDR_SIZE); QDF_MAC_ADDR_SIZE);
dp_peer_unref_delete(peer, DP_MOD_ID_AST);
qdf_spin_unlock_bh(&soc->ast_lock); qdf_spin_unlock_bh(&soc->ast_lock);
return true; return true;
} }
@@ -905,26 +912,34 @@ static bool dp_peer_get_ast_info_by_pdevid_wifi3
{ {
struct dp_ast_entry *ast_entry; struct dp_ast_entry *ast_entry;
struct dp_soc *soc = (struct dp_soc *)soc_hdl; struct dp_soc *soc = (struct dp_soc *)soc_hdl;
struct dp_peer *peer = NULL;
qdf_spin_lock_bh(&soc->ast_lock); qdf_spin_lock_bh(&soc->ast_lock);
ast_entry = dp_peer_ast_hash_find_by_pdevid(soc, ast_mac_addr, pdev_id); ast_entry = dp_peer_ast_hash_find_by_pdevid(soc, ast_mac_addr,
pdev_id);
if (!ast_entry || !ast_entry->peer) { if ((!ast_entry) ||
(ast_entry->delete_in_progress && !ast_entry->callback)) {
qdf_spin_unlock_bh(&soc->ast_lock); qdf_spin_unlock_bh(&soc->ast_lock);
return false; return false;
} }
if (ast_entry->delete_in_progress && !ast_entry->callback) {
peer = dp_peer_get_ref_by_id(soc, ast_entry->peer_id,
DP_MOD_ID_AST);
if (!peer) {
qdf_spin_unlock_bh(&soc->ast_lock); qdf_spin_unlock_bh(&soc->ast_lock);
return false; return false;
} }
ast_entry_info->type = ast_entry->type; ast_entry_info->type = ast_entry->type;
ast_entry_info->pdev_id = ast_entry->pdev_id; ast_entry_info->pdev_id = ast_entry->pdev_id;
ast_entry_info->vdev_id = ast_entry->peer->vdev->vdev_id; ast_entry_info->vdev_id = ast_entry->vdev_id;
ast_entry_info->peer_id = ast_entry->peer->peer_id; ast_entry_info->peer_id = ast_entry->peer_id;
qdf_mem_copy(&ast_entry_info->peer_mac_addr[0], qdf_mem_copy(&ast_entry_info->peer_mac_addr[0],
&ast_entry->peer->mac_addr.raw[0], &peer->mac_addr.raw[0],
QDF_MAC_ADDR_SIZE); QDF_MAC_ADDR_SIZE);
dp_peer_unref_delete(peer, DP_MOD_ID_AST);
qdf_spin_unlock_bh(&soc->ast_lock); qdf_spin_unlock_bh(&soc->ast_lock);
return true; return true;
} }
@@ -1253,8 +1268,8 @@ void dp_print_ast_stats(struct dp_soc *soc)
" vdev_id = %d", " vdev_id = %d",
++num_entries, ++num_entries,
ase->mac_addr.raw, ase->mac_addr.raw,
ase->peer->mac_addr.raw, peer->mac_addr.raw,
ase->peer->peer_id, ase->peer_id,
type[ase->type], type[ase->type],
ase->next_hop, ase->next_hop,
ase->is_active, ase->is_active,
@@ -5787,12 +5802,9 @@ static QDF_STATUS dp_cp_peer_del_resp_handler(struct cdp_soc_t *soc_hdl,
qdf_spin_lock_bh(&soc->ast_lock); qdf_spin_lock_bh(&soc->ast_lock);
if (soc->ast_override_support) ast_entry =
ast_entry = dp_peer_ast_hash_find_by_vdevid(soc, mac_addr,
dp_peer_ast_hash_find_by_pdevid(soc, mac_addr, vdev_id);
vdev->pdev->pdev_id);
else
ast_entry = dp_peer_ast_hash_find_soc(soc, mac_addr);
/* in case of qwrap we have multiple BSS peers /* in case of qwrap we have multiple BSS peers
* with same mac address * with same mac address
@@ -5800,7 +5812,8 @@ static QDF_STATUS dp_cp_peer_del_resp_handler(struct cdp_soc_t *soc_hdl,
* AST entry for this mac address will be created * AST entry for this mac address will be created
* only for one peer hence it will be NULL here * only for one peer hence it will be NULL here
*/ */
if (!ast_entry || ast_entry->peer || !ast_entry->delete_in_progress) { if ((!ast_entry || !ast_entry->delete_in_progress) ||
(ast_entry->peer_id != HTT_INVALID_PEER)) {
qdf_spin_unlock_bh(&soc->ast_lock); qdf_spin_unlock_bh(&soc->ast_lock);
return QDF_STATUS_E_FAILURE; return QDF_STATUS_E_FAILURE;
} }

View File

@@ -43,7 +43,7 @@
#ifdef FEATURE_WDS #ifdef FEATURE_WDS
static inline bool static inline bool
dp_peer_ast_free_in_unmap_supported(struct dp_peer *peer, dp_peer_ast_free_in_unmap_supported(struct dp_soc *soc,
struct dp_ast_entry *ast_entry) struct dp_ast_entry *ast_entry)
{ {
/* if peer map v2 is enabled we are not freeing ast entry /* if peer map v2 is enabled we are not freeing ast entry
@@ -62,7 +62,7 @@ dp_peer_ast_free_in_unmap_supported(struct dp_peer *peer,
} }
#else #else
static inline bool static inline bool
dp_peer_ast_free_in_unmap_supported(struct dp_peer *peer, dp_peer_ast_free_in_unmap_supported(struct dp_soc *soc,
struct dp_ast_entry *ast_entry) struct dp_ast_entry *ast_entry)
{ {
return false; return false;
@@ -597,27 +597,31 @@ void dp_peer_ast_hash_remove(struct dp_soc *soc,
} }
/* /*
* dp_peer_ast_list_find() - Find AST entry by MAC address from peer ast list * dp_peer_ast_hash_find_by_vdevid() - Find AST entry by MAC address
* @soc: SoC handle * @soc: SoC handle
* @peer: peer handle
* @ast_mac_addr: mac address
* *
* It assumes caller has taken the ast lock to protect the access to ast list * It assumes caller has taken the ast lock to protect the access to
* AST hash table
* *
* Return: AST entry * Return: AST entry
*/ */
struct dp_ast_entry *dp_peer_ast_list_find(struct dp_soc *soc, struct dp_ast_entry *dp_peer_ast_hash_find_by_vdevid(struct dp_soc *soc,
struct dp_peer *peer, uint8_t *ast_mac_addr,
uint8_t *ast_mac_addr) uint8_t vdev_id)
{ {
struct dp_ast_entry *ast_entry = NULL; union dp_align_mac_addr local_mac_addr_aligned, *mac_addr;
union dp_align_mac_addr *mac_addr = uint32_t index;
(union dp_align_mac_addr *)ast_mac_addr; struct dp_ast_entry *ase;
TAILQ_FOREACH(ast_entry, &peer->ast_entry_list, ase_list_elem) { qdf_mem_copy(&local_mac_addr_aligned.raw[0],
if (!dp_peer_find_mac_addr_cmp(mac_addr, ast_mac_addr, QDF_MAC_ADDR_SIZE);
&ast_entry->mac_addr)) { mac_addr = &local_mac_addr_aligned;
return ast_entry;
index = dp_peer_ast_hash_index(soc, mac_addr);
TAILQ_FOREACH(ase, &soc->ast_hash.bins[index], hash_list_elem) {
if ((vdev_id == ase->vdev_id) &&
!dp_peer_find_mac_addr_cmp(mac_addr, &ase->mac_addr)) {
return ase;
} }
} }
@@ -722,7 +726,7 @@ static inline QDF_STATUS dp_peer_map_ast(struct dp_soc *soc,
qdf_spin_lock_bh(&soc->ast_lock); qdf_spin_lock_bh(&soc->ast_lock);
ast_entry = dp_peer_ast_list_find(soc, peer, mac_addr); ast_entry = dp_peer_ast_hash_find_by_vdevid(soc, mac_addr, vdev_id);
if (is_wds) { if (is_wds) {
/* /*
@@ -747,7 +751,7 @@ static inline QDF_STATUS dp_peer_map_ast(struct dp_soc *soc,
cookie = ast_entry->cookie; cookie = ast_entry->cookie;
peer_type = ast_entry->type; peer_type = ast_entry->type;
dp_peer_unlink_ast_entry(soc, ast_entry); dp_peer_unlink_ast_entry(soc, ast_entry, peer);
dp_peer_free_ast_entry(soc, ast_entry); dp_peer_free_ast_entry(soc, ast_entry);
qdf_spin_unlock_bh(&soc->ast_lock); qdf_spin_unlock_bh(&soc->ast_lock);
@@ -781,6 +785,11 @@ static inline QDF_STATUS dp_peer_map_ast(struct dp_soc *soc,
peer_type = ast_entry->type; peer_type = ast_entry->type;
ast_entry->ast_hash_value = ast_hash; ast_entry->ast_hash_value = ast_hash;
ast_entry->is_mapped = TRUE; ast_entry->is_mapped = TRUE;
qdf_assert_always(ast_entry->peer_id == HTT_INVALID_PEER);
ast_entry->peer_id = peer->peer_id;
TAILQ_INSERT_TAIL(&peer->ast_entry_list, ast_entry,
ase_list_elem);
} }
if (ast_entry || (peer->vdev && peer->vdev->proxysta_vdev)) { if (ast_entry || (peer->vdev && peer->vdev->proxysta_vdev)) {
@@ -1012,7 +1021,7 @@ QDF_STATUS dp_peer_add_ast(struct dp_soc *soc,
*/ */
if ((ast_entry->type == CDP_TXRX_AST_TYPE_WDS) && if ((ast_entry->type == CDP_TXRX_AST_TYPE_WDS) &&
(type == CDP_TXRX_AST_TYPE_MEC) && (type == CDP_TXRX_AST_TYPE_MEC) &&
(ast_entry->peer == peer)) { (ast_entry->peer_id == peer->peer_id)) {
ast_entry->is_active = FALSE; ast_entry->is_active = FALSE;
dp_peer_del_ast(soc, ast_entry); dp_peer_del_ast(soc, ast_entry);
} }
@@ -1037,6 +1046,9 @@ add_ast_entry:
ast_entry->pdev_id = vdev->pdev->pdev_id; ast_entry->pdev_id = vdev->pdev->pdev_id;
ast_entry->is_mapped = false; ast_entry->is_mapped = false;
ast_entry->delete_in_progress = false; ast_entry->delete_in_progress = false;
ast_entry->peer_id = HTT_INVALID_PEER;
ast_entry->next_hop = 0;
ast_entry->vdev_id = vdev->vdev_id;
switch (type) { switch (type) {
case CDP_TXRX_AST_TYPE_STATIC: case CDP_TXRX_AST_TYPE_STATIC:
@@ -1060,6 +1072,9 @@ add_ast_entry:
case CDP_TXRX_AST_TYPE_WDS_HM_SEC: case CDP_TXRX_AST_TYPE_WDS_HM_SEC:
ast_entry->next_hop = 1; ast_entry->next_hop = 1;
ast_entry->type = CDP_TXRX_AST_TYPE_WDS_HM_SEC; ast_entry->type = CDP_TXRX_AST_TYPE_WDS_HM_SEC;
ast_entry->peer_id = peer->peer_id;
TAILQ_INSERT_TAIL(&peer->ast_entry_list, ast_entry,
ase_list_elem);
break; break;
case CDP_TXRX_AST_TYPE_MEC: case CDP_TXRX_AST_TYPE_MEC:
ast_entry->next_hop = 1; ast_entry->next_hop = 1;
@@ -1087,15 +1102,11 @@ add_ast_entry:
soc->num_ast_entries++; soc->num_ast_entries++;
dp_peer_ast_hash_add(soc, ast_entry); dp_peer_ast_hash_add(soc, ast_entry);
ast_entry->peer = peer;
if (type == CDP_TXRX_AST_TYPE_MEC) if (type == CDP_TXRX_AST_TYPE_MEC)
qdf_mem_copy(next_node_mac, peer->vdev->mac_addr.raw, 6); qdf_mem_copy(next_node_mac, peer->vdev->mac_addr.raw, 6);
else else
qdf_mem_copy(next_node_mac, peer->mac_addr.raw, 6); qdf_mem_copy(next_node_mac, peer->mac_addr.raw, 6);
TAILQ_INSERT_TAIL(&peer->ast_entry_list, ast_entry, ase_list_elem);
if ((ast_entry->type != CDP_TXRX_AST_TYPE_STATIC) && if ((ast_entry->type != CDP_TXRX_AST_TYPE_STATIC) &&
(ast_entry->type != CDP_TXRX_AST_TYPE_SELF) && (ast_entry->type != CDP_TXRX_AST_TYPE_SELF) &&
(ast_entry->type != CDP_TXRX_AST_TYPE_STA_BSS) && (ast_entry->type != CDP_TXRX_AST_TYPE_STA_BSS) &&
@@ -1156,6 +1167,7 @@ void dp_peer_free_ast_entry(struct dp_soc *soc,
* dp_peer_unlink_ast_entry() - Free up the ast entry memory * dp_peer_unlink_ast_entry() - Free up the ast entry memory
* @soc: SoC handle * @soc: SoC handle
* @ast_entry: Address search entry * @ast_entry: Address search entry
* @peer: peer
* *
* This API is used to remove/unlink AST entry from the peer list * This API is used to remove/unlink AST entry from the peer list
* and hash list. * and hash list.
@@ -1163,14 +1175,20 @@ void dp_peer_free_ast_entry(struct dp_soc *soc,
* Return: None * Return: None
*/ */
void dp_peer_unlink_ast_entry(struct dp_soc *soc, void dp_peer_unlink_ast_entry(struct dp_soc *soc,
struct dp_ast_entry *ast_entry) struct dp_ast_entry *ast_entry,
struct dp_peer *peer)
{ {
if (!peer)
return;
if (ast_entry->peer_id == HTT_INVALID_PEER)
return;
/* /*
* NOTE: Ensure that call to this API is done * NOTE: Ensure that call to this API is done
* after soc->ast_lock is taken * after soc->ast_lock is taken
*/ */
struct dp_peer *peer = ast_entry->peer;
qdf_assert_always(ast_entry->peer_id == peer->peer_id);
TAILQ_REMOVE(&peer->ast_entry_list, ast_entry, ase_list_elem); TAILQ_REMOVE(&peer->ast_entry_list, ast_entry, ase_list_elem);
if (ast_entry == peer->self_ast_entry) if (ast_entry == peer->self_ast_entry)
@@ -1183,7 +1201,7 @@ void dp_peer_unlink_ast_entry(struct dp_soc *soc,
if (ast_entry->is_mapped) if (ast_entry->is_mapped)
soc->ast_table[ast_entry->ast_idx] = NULL; soc->ast_table[ast_entry->ast_idx] = NULL;
ast_entry->peer = NULL; ast_entry->peer_id = HTT_INVALID_PEER;
} }
/* /*
@@ -1199,7 +1217,7 @@ void dp_peer_unlink_ast_entry(struct dp_soc *soc,
*/ */
void dp_peer_del_ast(struct dp_soc *soc, struct dp_ast_entry *ast_entry) void dp_peer_del_ast(struct dp_soc *soc, struct dp_ast_entry *ast_entry)
{ {
struct dp_peer *peer; struct dp_peer *peer = NULL;
if (!ast_entry) if (!ast_entry)
return; return;
@@ -1209,12 +1227,14 @@ void dp_peer_del_ast(struct dp_soc *soc, struct dp_ast_entry *ast_entry)
ast_entry->delete_in_progress = true; ast_entry->delete_in_progress = true;
peer = ast_entry->peer; peer = dp_peer_get_ref_by_id(soc, ast_entry->peer_id,
dp_peer_ast_send_wds_del(soc, ast_entry); DP_MOD_ID_AST);
dp_peer_ast_send_wds_del(soc, ast_entry, peer);
/* Remove SELF and STATIC entries in teardown itself */ /* Remove SELF and STATIC entries in teardown itself */
if (!ast_entry->next_hop) if (!ast_entry->next_hop)
dp_peer_unlink_ast_entry(soc, ast_entry); dp_peer_unlink_ast_entry(soc, ast_entry, peer);
if (ast_entry->is_mapped) if (ast_entry->is_mapped)
soc->ast_table[ast_entry->ast_idx] = NULL; soc->ast_table[ast_entry->ast_idx] = NULL;
@@ -1226,18 +1246,23 @@ void dp_peer_del_ast(struct dp_soc *soc, struct dp_ast_entry *ast_entry)
* if peer_id is invalid we did not get the peer map event * if peer_id is invalid we did not get the peer map event
* for the peer free ast entry from here only in this case * for the peer free ast entry from here only in this case
*/ */
if (dp_peer_ast_free_in_unmap_supported(peer, ast_entry)) if (dp_peer_ast_free_in_unmap_supported(soc, ast_entry))
return; goto end;
/* for WDS secondary entry ast_entry->next_hop would be set so /* for WDS secondary entry ast_entry->next_hop would be set so
* unlinking has to be done explicitly here. * unlinking has to be done explicitly here.
* As this entry is not a mapped entry unmap notification from * As this entry is not a mapped entry unmap notification from
* FW wil not come. Hence unlinkling is done right here. * FW wil not come. Hence unlinkling is done right here.
*/ */
if (ast_entry->type == CDP_TXRX_AST_TYPE_WDS_HM_SEC) if (ast_entry->type == CDP_TXRX_AST_TYPE_WDS_HM_SEC)
dp_peer_unlink_ast_entry(soc, ast_entry); dp_peer_unlink_ast_entry(soc, ast_entry, peer);
dp_peer_free_ast_entry(soc, ast_entry); dp_peer_free_ast_entry(soc, ast_entry);
end:
if (peer)
dp_peer_unref_delete(peer, DP_MOD_ID_AST);
} }
/* /*
@@ -1284,16 +1309,22 @@ int dp_peer_update_ast(struct dp_soc *soc, struct dp_peer *peer,
/* /*
* Avoids flood of WMI update messages sent to FW for same peer. * Avoids flood of WMI update messages sent to FW for same peer.
*/ */
if (qdf_unlikely(ast_entry->peer == peer) && if (qdf_unlikely(ast_entry->peer_id == peer->peer_id) &&
(ast_entry->type == CDP_TXRX_AST_TYPE_WDS) && (ast_entry->type == CDP_TXRX_AST_TYPE_WDS) &&
(ast_entry->peer->vdev == peer->vdev) && (ast_entry->vdev_id == peer->vdev->vdev_id) &&
(ast_entry->is_active)) (ast_entry->is_active))
return 0; return 0;
old_peer = ast_entry->peer; old_peer = dp_peer_get_ref_by_id(soc, ast_entry->peer_id,
DP_MOD_ID_AST);
if (!old_peer)
return 0;
TAILQ_REMOVE(&old_peer->ast_entry_list, ast_entry, ase_list_elem); TAILQ_REMOVE(&old_peer->ast_entry_list, ast_entry, ase_list_elem);
ast_entry->peer = peer; dp_peer_unref_delete(old_peer, DP_MOD_ID_AST);
ast_entry->peer_id = peer->peer_id;
ast_entry->type = CDP_TXRX_AST_TYPE_WDS; ast_entry->type = CDP_TXRX_AST_TYPE_WDS;
ast_entry->pdev_id = peer->vdev->pdev->pdev_id; ast_entry->pdev_id = peer->vdev->pdev->pdev_id;
ast_entry->is_active = TRUE; ast_entry->is_active = TRUE;
@@ -1435,29 +1466,33 @@ int dp_peer_update_ast(struct dp_soc *soc, struct dp_peer *peer,
#endif #endif
void dp_peer_ast_send_wds_del(struct dp_soc *soc, void dp_peer_ast_send_wds_del(struct dp_soc *soc,
struct dp_ast_entry *ast_entry) struct dp_ast_entry *ast_entry,
struct dp_peer *peer)
{ {
struct dp_peer *peer = ast_entry->peer;
struct cdp_soc_t *cdp_soc = &soc->cdp_soc; struct cdp_soc_t *cdp_soc = &soc->cdp_soc;
bool delete_in_fw = false;
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_TRACE, QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_TRACE,
"%s: ast_entry->type: %d pdevid: %u vdev: %u mac_addr: %pM next_hop: %u peer_mac: %pM\n", "%s: ast_entry->type: %d pdevid: %u vdev: %u mac_addr: %pM next_hop: %u peer_id: %uM\n",
__func__, ast_entry->type, peer->vdev->pdev->pdev_id, __func__, ast_entry->type, ast_entry->pdev_id,
peer->vdev->vdev_id, ast_entry->mac_addr.raw, ast_entry->vdev_id, ast_entry->mac_addr.raw,
ast_entry->next_hop, ast_entry->peer->mac_addr.raw); ast_entry->next_hop, ast_entry->peer_id);
/* /*
* If peer delete_in_progress is set, the peer is about to get * If peer is NULL, the peer is about to get
* teared down with a peer delete command to firmware, * teared down with a peer delete command to firmware,
* which will cleanup all the wds ast entries. * which will cleanup all the wds ast entries.
* So, no need to send explicit wds ast delete to firmware. * So, no need to send explicit wds ast delete to firmware.
*/ */
if (ast_entry->next_hop) { if (ast_entry->next_hop) {
if (peer)
delete_in_fw = true;
cdp_soc->ol_ops->peer_del_wds_entry(soc->ctrl_psoc, cdp_soc->ol_ops->peer_del_wds_entry(soc->ctrl_psoc,
peer->vdev->vdev_id, ast_entry->vdev_id,
ast_entry->mac_addr.raw, ast_entry->mac_addr.raw,
ast_entry->type, ast_entry->type,
!peer->delete_in_progress); delete_in_fw);
} }
} }
@@ -1483,18 +1518,18 @@ static uint32_t dp_peer_ast_free_wds_entries(struct dp_soc *soc,
qdf_spin_lock_bh(&soc->ast_lock); qdf_spin_lock_bh(&soc->ast_lock);
DP_PEER_ITERATE_ASE_LIST(peer, ast_entry, temp_ast_entry) { DP_PEER_ITERATE_ASE_LIST(peer, ast_entry, temp_ast_entry) {
if (ast_entry->next_hop) { if (ast_entry->next_hop)
if (ast_entry->is_mapped)
soc->ast_table[ast_entry->ast_idx] = NULL;
dp_peer_unlink_ast_entry(soc, ast_entry);
DP_STATS_INC(soc, ast.deleted, 1);
dp_peer_ast_hash_remove(soc, ast_entry);
TAILQ_INSERT_TAIL(&ast_local_list, ast_entry,
ase_list_elem);
soc->num_ast_entries--;
num_ast++; num_ast++;
}
if (ast_entry->is_mapped)
soc->ast_table[ast_entry->ast_idx] = NULL;
dp_peer_unlink_ast_entry(soc, ast_entry, peer);
DP_STATS_INC(soc, ast.deleted, 1);
dp_peer_ast_hash_remove(soc, ast_entry);
TAILQ_INSERT_TAIL(&ast_local_list, ast_entry,
ase_list_elem);
soc->num_ast_entries--;
} }
qdf_spin_unlock_bh(&soc->ast_lock); qdf_spin_unlock_bh(&soc->ast_lock);
@@ -1551,6 +1586,7 @@ dp_peer_clean_wds_entries(struct dp_soc *soc, struct dp_peer *peer,
* dp_peer_ast_free_entry_by_mac() - find ast entry by MAC address and delete * dp_peer_ast_free_entry_by_mac() - find ast entry by MAC address and delete
* @soc: soc handle * @soc: soc handle
* @peer: peer handle * @peer: peer handle
* @vdev_id: vdev_id
* @mac_addr: mac address of the AST entry to searc and delete * @mac_addr: mac address of the AST entry to searc and delete
* *
* find the ast entry from the peer list using the mac address and free * find the ast entry from the peer list using the mac address and free
@@ -1560,6 +1596,7 @@ dp_peer_clean_wds_entries(struct dp_soc *soc, struct dp_peer *peer,
*/ */
static int dp_peer_ast_free_entry_by_mac(struct dp_soc *soc, static int dp_peer_ast_free_entry_by_mac(struct dp_soc *soc,
struct dp_peer *peer, struct dp_peer *peer,
uint8_t vdev_id,
uint8_t *mac_addr) uint8_t *mac_addr)
{ {
struct dp_ast_entry *ast_entry; struct dp_ast_entry *ast_entry;
@@ -1573,7 +1610,7 @@ static int dp_peer_ast_free_entry_by_mac(struct dp_soc *soc,
qdf_spin_lock_bh(&soc->ast_lock); qdf_spin_lock_bh(&soc->ast_lock);
ast_entry = dp_peer_ast_list_find(soc, peer, mac_addr); ast_entry = dp_peer_ast_hash_find_by_vdevid(soc, mac_addr, vdev_id);
if (!ast_entry) { if (!ast_entry) {
qdf_spin_unlock_bh(&soc->ast_lock); qdf_spin_unlock_bh(&soc->ast_lock);
return QDF_STATUS_E_NOENT; return QDF_STATUS_E_NOENT;
@@ -1585,7 +1622,8 @@ static int dp_peer_ast_free_entry_by_mac(struct dp_soc *soc,
cookie = ast_entry->cookie; cookie = ast_entry->cookie;
dp_peer_unlink_ast_entry(soc, ast_entry); dp_peer_unlink_ast_entry(soc, ast_entry, peer);
dp_peer_free_ast_entry(soc, ast_entry); dp_peer_free_ast_entry(soc, ast_entry);
qdf_spin_unlock_bh(&soc->ast_lock); qdf_spin_unlock_bh(&soc->ast_lock);
@@ -2043,9 +2081,9 @@ dp_rx_peer_unmap_handler(struct dp_soc *soc, uint16_t peer_id,
/* If V2 Peer map messages are enabled AST entry has to be freed here /* If V2 Peer map messages are enabled AST entry has to be freed here
*/ */
if (is_wds) { if (is_wds) {
if (!dp_peer_ast_free_entry_by_mac(soc, peer, mac_addr)) { if (!dp_peer_ast_free_entry_by_mac(soc, peer, vdev_id,
mac_addr))
return; return;
}
dp_alert("AST entry not found with peer %pK peer_id %u peer_mac %pM mac_addr %pM vdev_id %u next_hop %u", dp_alert("AST entry not found with peer %pK peer_id %u peer_mac %pM mac_addr %pM vdev_id %u next_hop %u",
peer, peer->peer_id, peer, peer->peer_id,

View File

@@ -160,13 +160,13 @@ struct dp_ast_entry *dp_peer_ast_hash_find_by_pdevid(struct dp_soc *soc,
uint8_t *ast_mac_addr, uint8_t *ast_mac_addr,
uint8_t pdev_id); uint8_t pdev_id);
struct dp_ast_entry *dp_peer_ast_hash_find_by_vdevid(struct dp_soc *soc,
uint8_t *ast_mac_addr,
uint8_t vdev_id);
struct dp_ast_entry *dp_peer_ast_hash_find_soc(struct dp_soc *soc, struct dp_ast_entry *dp_peer_ast_hash_find_soc(struct dp_soc *soc,
uint8_t *ast_mac_addr); uint8_t *ast_mac_addr);
struct dp_ast_entry *dp_peer_ast_list_find(struct dp_soc *soc,
struct dp_peer *peer,
uint8_t *ast_mac_addr);
uint8_t dp_peer_ast_get_pdev_id(struct dp_soc *soc, uint8_t dp_peer_ast_get_pdev_id(struct dp_soc *soc,
struct dp_ast_entry *ast_entry); struct dp_ast_entry *ast_entry);
@@ -179,7 +179,8 @@ void dp_peer_ast_set_type(struct dp_soc *soc,
enum cdp_txrx_ast_entry_type type); enum cdp_txrx_ast_entry_type type);
void dp_peer_ast_send_wds_del(struct dp_soc *soc, void dp_peer_ast_send_wds_del(struct dp_soc *soc,
struct dp_ast_entry *ast_entry); struct dp_ast_entry *ast_entry,
struct dp_peer *peer);
void dp_peer_free_hmwds_cb(struct cdp_ctrl_objmgr_psoc *ctrl_psoc, void dp_peer_free_hmwds_cb(struct cdp_ctrl_objmgr_psoc *ctrl_psoc,
struct cdp_soc *dp_soc, struct cdp_soc *dp_soc,
@@ -193,7 +194,8 @@ void dp_peer_free_ast_entry(struct dp_soc *soc,
struct dp_ast_entry *ast_entry); struct dp_ast_entry *ast_entry);
void dp_peer_unlink_ast_entry(struct dp_soc *soc, void dp_peer_unlink_ast_entry(struct dp_soc *soc,
struct dp_ast_entry *ast_entry); struct dp_ast_entry *ast_entry,
struct dp_peer *peer);
#define DP_AST_ASSERT(_condition) \ #define DP_AST_ASSERT(_condition) \
do { \ do { \

View File

@@ -567,7 +567,9 @@ dp_rx_intrabss_fwd(struct dp_soc *soc,
{ {
uint16_t len; uint16_t len;
uint8_t is_frag; uint8_t is_frag;
struct dp_peer *da_peer; uint16_t da_peer_id = HTT_INVALID_PEER;
struct dp_peer *da_peer = NULL;
bool is_da_bss_peer = false;
struct dp_ast_entry *ast_entry; struct dp_ast_entry *ast_entry;
qdf_nbuf_t nbuf_copy; qdf_nbuf_t nbuf_copy;
uint8_t tid = qdf_nbuf_get_tid_val(nbuf); uint8_t tid = qdf_nbuf_get_tid_val(nbuf);
@@ -591,18 +593,28 @@ dp_rx_intrabss_fwd(struct dp_soc *soc,
return false; return false;
} }
da_peer = ast_entry->peer; da_peer_id = ast_entry->peer_id;
if (!da_peer) if (da_peer_id == HTT_INVALID_PEER)
return false; return false;
/* TA peer cannot be same as peer(DA) on which AST is present /* TA peer cannot be same as peer(DA) on which AST is present
* this indicates a change in topology and that AST entries * this indicates a change in topology and that AST entries
* are yet to be updated. * are yet to be updated.
*/ */
if (da_peer == ta_peer) if (da_peer_id == ta_peer->peer_id)
return false; return false;
if (da_peer->vdev == ta_peer->vdev && !da_peer->bss_peer) { if (ast_entry->vdev_id != ta_peer->vdev->vdev_id)
return false;
da_peer = dp_peer_get_ref_by_id(soc, da_peer_id,
DP_MOD_ID_RX);
if (!da_peer)
return false;
is_da_bss_peer = da_peer->bss_peer;
dp_peer_unref_delete(da_peer, DP_MOD_ID_RX);
if (!is_da_bss_peer) {
len = QDF_NBUF_CB_RX_PKT_LEN(nbuf); len = QDF_NBUF_CB_RX_PKT_LEN(nbuf);
is_frag = qdf_nbuf_is_frag(nbuf); is_frag = qdf_nbuf_is_frag(nbuf);
memset(nbuf->cb, 0x0, sizeof(nbuf->cb)); memset(nbuf->cb, 0x0, sizeof(nbuf->cb));

View File

@@ -115,8 +115,9 @@ static inline bool dp_rx_mcast_echo_check(struct dp_soc *soc,
* ast is not in ast_table, we use the below API to get * ast is not in ast_table, we use the below API to get
* AST entry for STA's own mac_address. * AST entry for STA's own mac_address.
*/ */
ase = dp_peer_ast_list_find(soc, peer, ase = dp_peer_ast_hash_find_by_vdevid
&data[QDF_MAC_ADDR_SIZE]); (soc, &data[QDF_MAC_ADDR_SIZE],
peer->vdev->vdev_id);
if (ase) { if (ase) {
ase->ast_idx = sa_idx; ase->ast_idx = sa_idx;
soc->ast_table[sa_idx] = ase; soc->ast_table[sa_idx] = ase;
@@ -142,7 +143,7 @@ static inline bool dp_rx_mcast_echo_check(struct dp_soc *soc,
} }
if ((ase->type == CDP_TXRX_AST_TYPE_MEC) || if ((ase->type == CDP_TXRX_AST_TYPE_MEC) ||
(ase->peer != peer)) { (ase->peer_id != peer->peer_id)) {
qdf_spin_unlock_bh(&soc->ast_lock); qdf_spin_unlock_bh(&soc->ast_lock);
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE(QDF_MODULE_ID_DP,
QDF_TRACE_LEVEL_INFO, QDF_TRACE_LEVEL_INFO,

View File

@@ -220,13 +220,14 @@ dp_rx_populate_cdp_indication_ppdu_user(struct dp_pdev *pdev,
} }
ast_entry = soc->ast_table[ast_index]; ast_entry = soc->ast_table[ast_index];
if (!ast_entry) { if (!ast_entry || ast_entry->peer_id == HTT_INVALID_PEER) {
rx_stats_peruser->peer_id = HTT_INVALID_PEER; rx_stats_peruser->peer_id = HTT_INVALID_PEER;
continue; continue;
} }
peer = ast_entry->peer; peer = dp_peer_get_ref_by_id(soc, ast_entry->peer_id,
if (!peer || peer->peer_id == HTT_INVALID_PEER) { DP_MOD_ID_RX_PPDU_STATS);
if (!peer) {
rx_stats_peruser->peer_id = HTT_INVALID_PEER; rx_stats_peruser->peer_id = HTT_INVALID_PEER;
continue; continue;
} }
@@ -286,6 +287,7 @@ dp_rx_populate_cdp_indication_ppdu_user(struct dp_pdev *pdev,
rx_stats_peruser->vdev_id = peer->vdev->vdev_id; rx_stats_peruser->vdev_id = peer->vdev->vdev_id;
rx_stats_peruser->mu_ul_info_valid = 0; rx_stats_peruser->mu_ul_info_valid = 0;
dp_peer_unref_delete(peer, DP_MOD_ID_RX_PPDU_STATS);
if (cdp_rx_ppdu->u.ppdu_type == HAL_RX_TYPE_MU_OFDMA || if (cdp_rx_ppdu->u.ppdu_type == HAL_RX_TYPE_MU_OFDMA ||
cdp_rx_ppdu->u.ppdu_type == HAL_RX_TYPE_MU_MIMO) { cdp_rx_ppdu->u.ppdu_type == HAL_RX_TYPE_MU_MIMO) {
if (rx_user_status->mu_ul_info_valid) { if (rx_user_status->mu_ul_info_valid) {
@@ -372,13 +374,14 @@ dp_rx_populate_cdp_indication_ppdu(struct dp_pdev *pdev,
} }
ast_entry = soc->ast_table[ast_index]; ast_entry = soc->ast_table[ast_index];
if (!ast_entry) { if (!ast_entry || ast_entry->peer_id == HTT_INVALID_PEER) {
cdp_rx_ppdu->peer_id = HTT_INVALID_PEER; cdp_rx_ppdu->peer_id = HTT_INVALID_PEER;
cdp_rx_ppdu->num_users = 0; cdp_rx_ppdu->num_users = 0;
goto end; goto end;
} }
peer = ast_entry->peer; peer = dp_peer_get_ref_by_id(soc, ast_entry->peer_id,
if (!peer || peer->peer_id == HTT_INVALID_PEER) { DP_MOD_ID_RX_PPDU_STATS);
if (!peer) {
cdp_rx_ppdu->peer_id = HTT_INVALID_PEER; cdp_rx_ppdu->peer_id = HTT_INVALID_PEER;
cdp_rx_ppdu->num_users = 0; cdp_rx_ppdu->num_users = 0;
goto end; goto end;
@@ -429,6 +432,8 @@ dp_rx_populate_cdp_indication_ppdu(struct dp_pdev *pdev,
dp_rx_populate_cdp_indication_ppdu_user(pdev, ppdu_info, cdp_rx_ppdu); dp_rx_populate_cdp_indication_ppdu_user(pdev, ppdu_info, cdp_rx_ppdu);
dp_peer_unref_delete(peer, DP_MOD_ID_RX_PPDU_STATS);
return; return;
end: end:
dp_rx_populate_cfr_non_assoc_sta(pdev, ppdu_info, cdp_rx_ppdu); dp_rx_populate_cfr_non_assoc_sta(pdev, ppdu_info, cdp_rx_ppdu);
@@ -1075,19 +1080,21 @@ dp_rx_mon_handle_cfr_mu_info(struct dp_pdev *pdev,
} }
ast_entry = soc->ast_table[ast_index]; ast_entry = soc->ast_table[ast_index];
if (!ast_entry) { if (!ast_entry || ast_entry->peer_id == HTT_INVALID_PEER) {
rx_stats_peruser->peer_id = HTT_INVALID_PEER; rx_stats_peruser->peer_id = HTT_INVALID_PEER;
continue; continue;
} }
peer = ast_entry->peer; peer = dp_peer_get_ref_by_id(soc, ast_entry->peer_id,
if (!peer || peer->peer_id == HTT_INVALID_PEER) { DP_MOD_ID_RX_PPDU_STATS);
if (!peer) {
rx_stats_peruser->peer_id = HTT_INVALID_PEER; rx_stats_peruser->peer_id = HTT_INVALID_PEER;
continue; continue;
} }
qdf_mem_copy(rx_stats_peruser->mac_addr, qdf_mem_copy(rx_stats_peruser->mac_addr,
peer->mac_addr.raw, QDF_MAC_ADDR_SIZE); peer->mac_addr.raw, QDF_MAC_ADDR_SIZE);
dp_peer_unref_delete(peer, DP_MOD_ID_RX_PPDU_STATS);
} }
qdf_spin_unlock_bh(&soc->ast_lock); qdf_spin_unlock_bh(&soc->ast_lock);
@@ -1458,15 +1465,19 @@ dp_rx_process_peer_based_pktlog(struct dp_soc *soc,
if (ast_index < wlan_cfg_get_max_ast_idx(soc->wlan_cfg_ctx)) { if (ast_index < wlan_cfg_get_max_ast_idx(soc->wlan_cfg_ctx)) {
ast_entry = soc->ast_table[ast_index]; ast_entry = soc->ast_table[ast_index];
if (ast_entry) { if (ast_entry) {
peer = ast_entry->peer; peer = dp_peer_get_ref_by_id(soc, ast_entry->peer_id,
if (peer && (peer->peer_id != HTT_INVALID_PEER)) { DP_MOD_ID_RX_PPDU_STATS);
if (peer->peer_based_pktlog_filter) { if (peer) {
if ((peer->peer_id != HTT_INVALID_PEER) &&
(peer->peer_based_pktlog_filter)) {
dp_wdi_event_handler( dp_wdi_event_handler(
WDI_EVENT_RX_DESC, soc, WDI_EVENT_RX_DESC, soc,
status_nbuf, status_nbuf,
peer->peer_id, peer->peer_id,
WDI_NO_VAL, pdev_id); WDI_NO_VAL, pdev_id);
} }
dp_peer_unref_delete(peer,
DP_MOD_ID_RX_PPDU_STATS);
} }
} }
} }

View File

@@ -1665,8 +1665,8 @@ int dp_tx_frame_is_drop(struct dp_vdev *vdev, uint8_t *srcmac, uint8_t *dstmac)
src_ast_entry = dp_peer_ast_hash_find_by_pdevid src_ast_entry = dp_peer_ast_hash_find_by_pdevid
(soc, srcmac, vdev->pdev->pdev_id); (soc, srcmac, vdev->pdev->pdev_id);
if (dst_ast_entry && src_ast_entry) { if (dst_ast_entry && src_ast_entry) {
if (dst_ast_entry->peer->peer_id == if (dst_ast_entry->peer_id ==
src_ast_entry->peer->peer_id) src_ast_entry->peer_id)
return 1; return 1;
} }
@@ -2379,7 +2379,7 @@ void dp_tx_nawds_handler(struct cdp_soc_t *soc, struct dp_vdev *vdev,
qdf_nbuf_t nbuf_clone = NULL; qdf_nbuf_t nbuf_clone = NULL;
struct dp_soc *dp_soc = (struct dp_soc *)soc; struct dp_soc *dp_soc = (struct dp_soc *)soc;
uint16_t peer_id = DP_INVALID_PEER; uint16_t peer_id = DP_INVALID_PEER;
struct dp_peer *sa_peer = NULL; uint16_t sa_peer_id = DP_INVALID_PEER;
struct dp_ast_entry *ast_entry = NULL; struct dp_ast_entry *ast_entry = NULL;
qdf_ether_header_t *eh = (qdf_ether_header_t *)qdf_nbuf_data(nbuf); qdf_ether_header_t *eh = (qdf_ether_header_t *)qdf_nbuf_data(nbuf);
@@ -2392,7 +2392,7 @@ void dp_tx_nawds_handler(struct cdp_soc_t *soc, struct dp_vdev *vdev,
vdev->pdev->pdev_id); vdev->pdev->pdev_id);
if (ast_entry) if (ast_entry)
sa_peer = ast_entry->peer; sa_peer_id = ast_entry->peer_id;
qdf_spin_unlock_bh(&dp_soc->ast_lock); qdf_spin_unlock_bh(&dp_soc->ast_lock);
} }
@@ -2403,7 +2403,7 @@ void dp_tx_nawds_handler(struct cdp_soc_t *soc, struct dp_vdev *vdev,
/* Multicast packets needs to be /* Multicast packets needs to be
* dropped in case of intra bss forwarding * dropped in case of intra bss forwarding
*/ */
if (sa_peer == peer) { if (sa_peer_id == peer->peer_id) {
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE(QDF_MODULE_ID_DP,
QDF_TRACE_LEVEL_DEBUG, QDF_TRACE_LEVEL_DEBUG,
" %s: multicast packet", __func__); " %s: multicast packet", __func__);

View File

@@ -951,9 +951,9 @@ struct dp_ast_free_cb_params {
* dp_ast_entry * dp_ast_entry
* *
* @ast_idx: Hardware AST Index * @ast_idx: Hardware AST Index
* @peer_id: Next Hop peer_id (for non-WDS nodes, this will be point to
* associated peer with this MAC address)
* @mac_addr: MAC Address for this AST entry * @mac_addr: MAC Address for this AST entry
* @peer: Next Hop peer (for non-WDS nodes, this will be point to
* associated peer with this MAC address)
* @next_hop: Set to 1 if this is for a WDS node * @next_hop: Set to 1 if this is for a WDS node
* @is_active: flag to indicate active data traffic on this node * @is_active: flag to indicate active data traffic on this node
* (used for aging out/expiry) * (used for aging out/expiry)
@@ -974,12 +974,13 @@ struct dp_ast_free_cb_params {
*/ */
struct dp_ast_entry { struct dp_ast_entry {
uint16_t ast_idx; uint16_t ast_idx;
uint16_t peer_id;
union dp_align_mac_addr mac_addr; union dp_align_mac_addr mac_addr;
struct dp_peer *peer;
bool next_hop; bool next_hop;
bool is_active; bool is_active;
bool is_mapped; bool is_mapped;
uint8_t pdev_id; uint8_t pdev_id;
uint8_t vdev_id;
uint16_t ast_hash_value; uint16_t ast_hash_value;
qdf_atomic_t ref_cnt; qdf_atomic_t ref_cnt;
enum cdp_txrx_ast_entry_type type; enum cdp_txrx_ast_entry_type type;