qcacmn: add CDP function to process CP peer delete response
Add a CDP function which processes the peer delete response and deletes the static ast entry for the peer Change-Id: Id646979ed07bd82609ca08e7ef3201382d07b1de CRs-fixed: 2385115
This commit is contained in:

committed by
nshrivas

parent
12a6840949
commit
1ab908e62b
@@ -363,6 +363,34 @@ static inline void cdp_peer_setup
|
|||||||
peer);
|
peer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* cdp_cp_peer_del_response - Call the peer delete response handler
|
||||||
|
* @soc: Datapath SOC handle
|
||||||
|
* @vdev_hdl: virtual device object
|
||||||
|
* @peer_mac_addr: Mac address of the peer
|
||||||
|
*
|
||||||
|
* Return: void
|
||||||
|
*/
|
||||||
|
static inline void cdp_cp_peer_del_response
|
||||||
|
(ol_txrx_soc_handle soc,
|
||||||
|
struct cdp_vdev *vdev_hdl,
|
||||||
|
uint8_t *peer_mac_addr)
|
||||||
|
{
|
||||||
|
if (!soc || !soc->ops) {
|
||||||
|
QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG,
|
||||||
|
"%s: Invalid Instance:", __func__);
|
||||||
|
QDF_BUG(0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!soc->ops->cmn_drv_ops ||
|
||||||
|
!soc->ops->cmn_drv_ops->txrx_cp_peer_del_response)
|
||||||
|
return;
|
||||||
|
|
||||||
|
return soc->ops->cmn_drv_ops->txrx_cp_peer_del_response(soc,
|
||||||
|
vdev_hdl,
|
||||||
|
peer_mac_addr);
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* cdp_peer_get_ast_info_by_soc() - search the soc AST hash table
|
* cdp_peer_get_ast_info_by_soc() - search the soc AST hash table
|
||||||
* and return ast entry information
|
* and return ast entry information
|
||||||
|
@@ -99,6 +99,10 @@ struct cdp_cmn_ops {
|
|||||||
void (*txrx_peer_setup)
|
void (*txrx_peer_setup)
|
||||||
(struct cdp_vdev *vdev_hdl, void *peer_hdl);
|
(struct cdp_vdev *vdev_hdl, void *peer_hdl);
|
||||||
|
|
||||||
|
void (*txrx_cp_peer_del_response)
|
||||||
|
(ol_txrx_soc_handle soc, struct cdp_vdev *vdev_hdl,
|
||||||
|
uint8_t *peer_mac_addr);
|
||||||
|
|
||||||
void (*txrx_peer_teardown)
|
void (*txrx_peer_teardown)
|
||||||
(struct cdp_vdev *vdev_hdl, void *peer_hdl);
|
(struct cdp_vdev *vdev_hdl, void *peer_hdl);
|
||||||
|
|
||||||
|
@@ -5163,6 +5163,67 @@ static void dp_peer_setup_wifi3(struct cdp_vdev *vdev_hdl, void *peer_hdl)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* dp_cp_peer_del_resp_handler - Handle the peer delete response
|
||||||
|
* @soc_hdl: Datapath SOC handle
|
||||||
|
* @vdev_hdl: virtual device object
|
||||||
|
* @mac_addr: Mac address of the peer
|
||||||
|
*
|
||||||
|
* Return: void
|
||||||
|
*/
|
||||||
|
static void dp_cp_peer_del_resp_handler(struct cdp_soc_t *soc_hdl,
|
||||||
|
struct cdp_vdev *vdev_hdl,
|
||||||
|
uint8_t *mac_addr)
|
||||||
|
{
|
||||||
|
struct dp_soc *soc = (struct dp_soc *)soc_hdl;
|
||||||
|
struct dp_ast_entry *ast_entry = NULL;
|
||||||
|
struct dp_vdev *vdev = (struct dp_vdev *)vdev_hdl;
|
||||||
|
txrx_ast_free_cb cb = NULL;
|
||||||
|
void *cookie;
|
||||||
|
|
||||||
|
qdf_spin_lock_bh(&soc->ast_lock);
|
||||||
|
|
||||||
|
if (soc->ast_override_support)
|
||||||
|
ast_entry =
|
||||||
|
dp_peer_ast_hash_find_by_pdevid(soc, mac_addr,
|
||||||
|
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
|
||||||
|
* with same mac address
|
||||||
|
*
|
||||||
|
* AST entry for this mac address will be created
|
||||||
|
* only for one peer hence it will be NULL here
|
||||||
|
*/
|
||||||
|
if (!ast_entry || ast_entry->peer || !ast_entry->delete_in_progress) {
|
||||||
|
qdf_spin_unlock_bh(&soc->ast_lock);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ast_entry->is_mapped)
|
||||||
|
soc->ast_table[ast_entry->ast_idx] = NULL;
|
||||||
|
|
||||||
|
DP_STATS_INC(soc, ast.deleted, 1);
|
||||||
|
dp_peer_ast_hash_remove(soc, ast_entry);
|
||||||
|
|
||||||
|
cb = ast_entry->callback;
|
||||||
|
cookie = ast_entry->cookie;
|
||||||
|
ast_entry->callback = NULL;
|
||||||
|
ast_entry->cookie = NULL;
|
||||||
|
|
||||||
|
soc->num_ast_entries--;
|
||||||
|
qdf_spin_unlock_bh(&soc->ast_lock);
|
||||||
|
|
||||||
|
if (cb) {
|
||||||
|
cb(soc->ctrl_psoc,
|
||||||
|
soc,
|
||||||
|
cookie,
|
||||||
|
CDP_TXRX_AST_DELETED);
|
||||||
|
}
|
||||||
|
qdf_mem_free(ast_entry);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* dp_set_vdev_tx_encap_type() - set the encap type of the vdev
|
* dp_set_vdev_tx_encap_type() - set the encap type of the vdev
|
||||||
* @vdev_handle: virtual device object
|
* @vdev_handle: virtual device object
|
||||||
@@ -9804,6 +9865,8 @@ static struct cdp_cmn_ops dp_ops_cmn = {
|
|||||||
.set_vdev_pcp_tid_map = dp_set_vdev_pcp_tid_map_wifi3,
|
.set_vdev_pcp_tid_map = dp_set_vdev_pcp_tid_map_wifi3,
|
||||||
.set_vdev_tidmap_prty = dp_set_vdev_tidmap_prty_wifi3,
|
.set_vdev_tidmap_prty = dp_set_vdev_tidmap_prty_wifi3,
|
||||||
.set_vdev_tidmap_tbl_id = dp_set_vdev_tidmap_tbl_id_wifi3,
|
.set_vdev_tidmap_tbl_id = dp_set_vdev_tidmap_tbl_id_wifi3,
|
||||||
|
|
||||||
|
.txrx_cp_peer_del_response = dp_cp_peer_del_resp_handler,
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct cdp_ctrl_ops dp_ops_ctrl = {
|
static struct cdp_ctrl_ops dp_ops_ctrl = {
|
||||||
|
@@ -360,8 +360,8 @@ static inline void dp_peer_ast_hash_add(struct dp_soc *soc,
|
|||||||
*
|
*
|
||||||
* Return: None
|
* Return: None
|
||||||
*/
|
*/
|
||||||
static inline void dp_peer_ast_hash_remove(struct dp_soc *soc,
|
void dp_peer_ast_hash_remove(struct dp_soc *soc,
|
||||||
struct dp_ast_entry *ase)
|
struct dp_ast_entry *ase)
|
||||||
{
|
{
|
||||||
unsigned index;
|
unsigned index;
|
||||||
struct dp_ast_entry *tmpase;
|
struct dp_ast_entry *tmpase;
|
||||||
@@ -823,8 +823,12 @@ add_ast_entry:
|
|||||||
*/
|
*/
|
||||||
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 = ast_entry->peer;
|
struct dp_peer *peer;
|
||||||
uint16_t peer_id = peer->peer_ids[0];
|
|
||||||
|
if (!ast_entry)
|
||||||
|
return;
|
||||||
|
|
||||||
|
peer = ast_entry->peer;
|
||||||
|
|
||||||
dp_peer_ast_send_wds_del(soc, ast_entry);
|
dp_peer_ast_send_wds_del(soc, ast_entry);
|
||||||
|
|
||||||
@@ -836,7 +840,7 @@ 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 (soc->is_peer_map_unmap_v2 && (peer_id != HTT_INVALID_PEER)) {
|
if (soc->is_peer_map_unmap_v2) {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* For HM_SEC and SELF type we do not receive unmap event
|
* For HM_SEC and SELF type we do not receive unmap event
|
||||||
@@ -853,10 +857,10 @@ void dp_peer_del_ast(struct dp_soc *soc, struct dp_ast_entry *ast_entry)
|
|||||||
*/
|
*/
|
||||||
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;
|
||||||
TAILQ_REMOVE(&peer->ast_entry_list, ast_entry, ase_list_elem);
|
|
||||||
|
|
||||||
if (ast_entry == peer->self_ast_entry)
|
/* SELF and STATIC entries are removed in teardown itself */
|
||||||
peer->self_ast_entry = NULL;
|
if (ast_entry->next_hop)
|
||||||
|
TAILQ_REMOVE(&peer->ast_entry_list, ast_entry, ase_list_elem);
|
||||||
|
|
||||||
DP_STATS_INC(soc, ast.deleted, 1);
|
DP_STATS_INC(soc, ast.deleted, 1);
|
||||||
dp_peer_ast_hash_remove(soc, ast_entry);
|
dp_peer_ast_hash_remove(soc, ast_entry);
|
||||||
@@ -1053,6 +1057,13 @@ void dp_peer_ast_send_wds_del(struct dp_soc *soc,
|
|||||||
ast_entry->type);
|
ast_entry->type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Remove SELF and STATIC entries in teardown itself */
|
||||||
|
if (!ast_entry->next_hop) {
|
||||||
|
TAILQ_REMOVE(&peer->ast_entry_list, ast_entry, ase_list_elem);
|
||||||
|
peer->self_ast_entry = NULL;
|
||||||
|
ast_entry->peer = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
ast_entry->delete_in_progress = true;
|
ast_entry->delete_in_progress = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1503,54 +1514,27 @@ dp_rx_peer_unmap_handler(void *soc_handle, 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 (soc->is_peer_map_unmap_v2) {
|
if (soc->is_peer_map_unmap_v2 && is_wds) {
|
||||||
|
|
||||||
qdf_spin_lock_bh(&soc->ast_lock);
|
qdf_spin_lock_bh(&soc->ast_lock);
|
||||||
ast_entry = dp_peer_ast_list_find(soc, peer,
|
ast_entry = dp_peer_ast_list_find(soc, peer,
|
||||||
mac_addr);
|
mac_addr);
|
||||||
|
|
||||||
if (!ast_entry) {
|
|
||||||
/* in case of qwrap we have multiple BSS peers
|
|
||||||
* with same mac address
|
|
||||||
*
|
|
||||||
* AST entry for this mac address will be created
|
|
||||||
* only for one peer
|
|
||||||
*/
|
|
||||||
if (peer->vdev->proxysta_vdev) {
|
|
||||||
qdf_spin_unlock_bh(&soc->ast_lock);
|
|
||||||
goto peer_unmap;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Ideally we should not enter this case where
|
|
||||||
* ast_entry is not present in host table and
|
|
||||||
* we received a unmap event
|
|
||||||
*/
|
|
||||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL,
|
|
||||||
"%s:%d AST entry not found with peer %pK peer_id %u peer_mac %pM mac_addr %pM vdev_id %u next_hop %u\n",
|
|
||||||
__func__, __LINE__, peer, peer->peer_ids[0],
|
|
||||||
peer->mac_addr.raw, mac_addr, vdev_id,
|
|
||||||
is_wds);
|
|
||||||
|
|
||||||
qdf_spin_unlock_bh(&soc->ast_lock);
|
|
||||||
|
|
||||||
if (!is_wds)
|
|
||||||
goto peer_unmap;
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
qdf_spin_unlock_bh(&soc->ast_lock);
|
qdf_spin_unlock_bh(&soc->ast_lock);
|
||||||
|
|
||||||
/* Reuse the AST entry if delete_in_progress
|
if (ast_entry) {
|
||||||
* not set
|
|
||||||
*/
|
|
||||||
if (ast_entry->delete_in_progress)
|
|
||||||
dp_peer_ast_free_entry(soc, ast_entry);
|
dp_peer_ast_free_entry(soc, ast_entry);
|
||||||
|
|
||||||
if (is_wds)
|
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL,
|
||||||
|
"%s:%d AST entry not found with peer %pK peer_id %u peer_mac %pM mac_addr %pM vdev_id %u next_hop %u\n",
|
||||||
|
__func__, __LINE__, peer, peer->peer_ids[0],
|
||||||
|
peer->mac_addr.raw, mac_addr, vdev_id,
|
||||||
|
is_wds);
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
peer_unmap:
|
|
||||||
QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO_HIGH,
|
QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO_HIGH,
|
||||||
"peer_unmap_event (soc:%pK) peer_id %d peer %pK",
|
"peer_unmap_event (soc:%pK) peer_id %d peer %pK",
|
||||||
soc, peer_id, peer);
|
soc, peer_id, peer);
|
||||||
|
@@ -145,6 +145,9 @@ void dp_peer_free_hmwds_cb(void *ctrl_psoc,
|
|||||||
void *cookie,
|
void *cookie,
|
||||||
enum cdp_ast_free_status status);
|
enum cdp_ast_free_status status);
|
||||||
|
|
||||||
|
void dp_peer_ast_hash_remove(struct dp_soc *soc,
|
||||||
|
struct dp_ast_entry *ase);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* dp_get_vdev_from_soc_vdev_id_wifi3() -
|
* dp_get_vdev_from_soc_vdev_id_wifi3() -
|
||||||
* Returns vdev object given the vdev id
|
* Returns vdev object given the vdev id
|
||||||
|
Reference in New Issue
Block a user