qcacmn: Add support for WDS aging
Add support for monitoring receive traffic from WDS nodes and aging out inactive WDS nodes Change-Id: Iedea826832a5421714c00bccadc6e0dc4acd4c7e CRs-Fixed: 2004658
This commit is contained in:

committed by
snandini

orang tua
a7b6842a72
melakukan
b8bbf16192
@@ -485,6 +485,7 @@ enum cdp_vdev_param_type {
|
|||||||
CDP_ENABLE_WDS,
|
CDP_ENABLE_WDS,
|
||||||
CDP_ENABLE_PROXYSTA,
|
CDP_ENABLE_PROXYSTA,
|
||||||
CDP_UPDATE_TDLS_FLAGS,
|
CDP_UPDATE_TDLS_FLAGS,
|
||||||
|
CDP_CFG_WDS_AGING_TIMER,
|
||||||
};
|
};
|
||||||
|
|
||||||
#define TXRX_FW_STATS_TXSTATS 1
|
#define TXRX_FW_STATS_TXSTATS 1
|
||||||
|
@@ -40,6 +40,7 @@
|
|||||||
#include "qdf_mem.h" /* qdf_mem_malloc,free */
|
#include "qdf_mem.h" /* qdf_mem_malloc,free */
|
||||||
|
|
||||||
#define DP_INTR_POLL_TIMER_MS 10
|
#define DP_INTR_POLL_TIMER_MS 10
|
||||||
|
#define DP_WDS_AGING_TIMER_DEFAULT_MS 6000
|
||||||
#define DP_MCS_LENGTH (6*MAX_MCS)
|
#define DP_MCS_LENGTH (6*MAX_MCS)
|
||||||
#define DP_NSS_LENGTH (6*SS_COUNT)
|
#define DP_NSS_LENGTH (6*SS_COUNT)
|
||||||
#define DP_RXDMA_ERR_LENGTH (6*MAX_RXDMA_ERRORS)
|
#define DP_RXDMA_ERR_LENGTH (6*MAX_RXDMA_ERRORS)
|
||||||
@@ -877,6 +878,97 @@ static void dp_hw_link_desc_pool_cleanup(struct dp_soc *soc)
|
|||||||
#define RXDMA_MONITOR_DESC_RING_SIZE 1024
|
#define RXDMA_MONITOR_DESC_RING_SIZE 1024
|
||||||
#define RXDMA_ERR_DST_RING_SIZE 1024
|
#define RXDMA_ERR_DST_RING_SIZE 1024
|
||||||
|
|
||||||
|
/*
|
||||||
|
* dp_wds_aging_timer_fn() - Timer callback function for WDS aging
|
||||||
|
* @soc: Datapath SOC handle
|
||||||
|
*
|
||||||
|
* This is a timer function used to age out stale WDS nodes from
|
||||||
|
* AST table
|
||||||
|
*/
|
||||||
|
#ifdef FEATURE_WDS
|
||||||
|
static void dp_wds_aging_timer_fn(void *soc_hdl)
|
||||||
|
{
|
||||||
|
struct dp_soc *soc = (struct dp_soc *) soc_hdl;
|
||||||
|
struct dp_pdev *pdev;
|
||||||
|
struct dp_vdev *vdev;
|
||||||
|
struct dp_peer *peer;
|
||||||
|
struct dp_ast_entry *ase;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
qdf_spin_lock_bh(&soc->ast_lock);
|
||||||
|
|
||||||
|
for (i = 0; i < MAX_PDEV_CNT && soc->pdev_list[i]; i++) {
|
||||||
|
pdev = soc->pdev_list[i];
|
||||||
|
DP_PDEV_ITERATE_VDEV_LIST(pdev, vdev) {
|
||||||
|
DP_VDEV_ITERATE_PEER_LIST(vdev, peer) {
|
||||||
|
DP_PEER_ITERATE_ASE_LIST(peer, ase) {
|
||||||
|
/*
|
||||||
|
* Do not expire static ast entries
|
||||||
|
*/
|
||||||
|
if (ase->is_static)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (ase->is_active) {
|
||||||
|
ase->is_active = FALSE;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
soc->cdp_soc.ol_ops->peer_del_wds_entry(
|
||||||
|
pdev->osif_pdev,
|
||||||
|
ase->mac_addr.raw);
|
||||||
|
|
||||||
|
dp_peer_del_ast(soc, ase);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
qdf_spin_unlock_bh(&soc->ast_lock);
|
||||||
|
|
||||||
|
if (qdf_atomic_read(&soc->cmn_init_done))
|
||||||
|
qdf_timer_mod(&soc->wds_aging_timer, DP_WDS_AGING_TIMER_DEFAULT_MS);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* dp_soc_wds_attach() - Setup WDS timer and AST table
|
||||||
|
* @soc: Datapath SOC handle
|
||||||
|
*
|
||||||
|
* Return: None
|
||||||
|
*/
|
||||||
|
static void dp_soc_wds_attach(struct dp_soc *soc)
|
||||||
|
{
|
||||||
|
qdf_spinlock_create(&soc->ast_lock);
|
||||||
|
|
||||||
|
qdf_timer_init(soc->osdev, &soc->wds_aging_timer,
|
||||||
|
dp_wds_aging_timer_fn, (void *)soc,
|
||||||
|
QDF_TIMER_TYPE_WAKE_APPS);
|
||||||
|
|
||||||
|
qdf_timer_mod(&soc->wds_aging_timer, DP_WDS_AGING_TIMER_DEFAULT_MS);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* dp_soc_wds_detach() - Detach WDS data structures and timers
|
||||||
|
* @txrx_soc: DP SOC handle
|
||||||
|
*
|
||||||
|
* Return: None
|
||||||
|
*/
|
||||||
|
static void dp_soc_wds_detach(struct dp_soc *soc)
|
||||||
|
{
|
||||||
|
qdf_timer_stop(&soc->wds_aging_timer);
|
||||||
|
qdf_timer_free(&soc->wds_aging_timer);
|
||||||
|
qdf_spinlock_destroy(&soc->ast_lock);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
static void dp_soc_wds_attach(struct dp_soc *soc)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dp_soc_wds_detach(struct dp_soc *soc)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* dp_soc_cmn_setup() - Common SoC level initializion
|
* dp_soc_cmn_setup() - Common SoC level initializion
|
||||||
* @soc: Datapath SOC handle
|
* @soc: Datapath SOC handle
|
||||||
@@ -1035,6 +1127,8 @@ static int dp_soc_cmn_setup(struct dp_soc *soc)
|
|||||||
goto fail1;
|
goto fail1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dp_soc_wds_attach(soc);
|
||||||
|
|
||||||
/* Setup HW REO */
|
/* Setup HW REO */
|
||||||
qdf_mem_zero(&reo_params, sizeof(reo_params));
|
qdf_mem_zero(&reo_params, sizeof(reo_params));
|
||||||
|
|
||||||
@@ -1578,6 +1672,9 @@ static void dp_soc_detach_wifi3(void *txrx_soc)
|
|||||||
|
|
||||||
dp_reo_desc_freelist_destroy(soc);
|
dp_reo_desc_freelist_destroy(soc);
|
||||||
wlan_cfg_soc_detach(soc->wlan_cfg_ctx);
|
wlan_cfg_soc_detach(soc->wlan_cfg_ctx);
|
||||||
|
|
||||||
|
dp_soc_wds_detach(soc);
|
||||||
|
|
||||||
qdf_mem_free(soc);
|
qdf_mem_free(soc);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1960,11 +2057,8 @@ static void *dp_peer_create_wifi3(struct cdp_vdev *vdev_handle,
|
|||||||
qdf_mem_zero(peer, sizeof(struct dp_peer));
|
qdf_mem_zero(peer, sizeof(struct dp_peer));
|
||||||
|
|
||||||
TAILQ_INIT(&peer->ast_entry_list);
|
TAILQ_INIT(&peer->ast_entry_list);
|
||||||
qdf_mem_copy(&peer->self_ast_entry.mac_addr, peer_mac_addr,
|
|
||||||
DP_MAC_ADDR_LEN);
|
dp_peer_add_ast(soc, peer, peer_mac_addr, 1);
|
||||||
peer->self_ast_entry.peer = peer;
|
|
||||||
TAILQ_INSERT_TAIL(&peer->ast_entry_list, &peer->self_ast_entry,
|
|
||||||
ast_entry_elem);
|
|
||||||
|
|
||||||
qdf_spinlock_create(&peer->peer_info_lock);
|
qdf_spinlock_create(&peer->peer_info_lock);
|
||||||
|
|
||||||
@@ -2008,6 +2102,7 @@ static void *dp_peer_create_wifi3(struct cdp_vdev *vdev_handle,
|
|||||||
vdev->vap_bss_peer = peer;
|
vdev->vap_bss_peer = peer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifndef CONFIG_WIN
|
#ifndef CONFIG_WIN
|
||||||
dp_local_peer_id_alloc(pdev, peer);
|
dp_local_peer_id_alloc(pdev, peer);
|
||||||
#endif
|
#endif
|
||||||
@@ -2257,8 +2352,6 @@ void dp_peer_unref_delete(void *peer_handle)
|
|||||||
struct dp_peer *tmppeer;
|
struct dp_peer *tmppeer;
|
||||||
int found = 0;
|
int found = 0;
|
||||||
uint16_t peer_id;
|
uint16_t peer_id;
|
||||||
uint16_t hw_peer_id;
|
|
||||||
struct dp_ast_entry *ast_entry;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Hold the lock all the way from checking if the peer ref count
|
* Hold the lock all the way from checking if the peer ref count
|
||||||
@@ -2342,17 +2435,6 @@ void dp_peer_unref_delete(void *peer_handle)
|
|||||||
#ifdef notyet
|
#ifdef notyet
|
||||||
qdf_mempool_free(soc->osdev, soc->mempool_ol_ath_peer, peer);
|
qdf_mempool_free(soc->osdev, soc->mempool_ol_ath_peer, peer);
|
||||||
#else
|
#else
|
||||||
TAILQ_FOREACH(ast_entry, &peer->ast_entry_list,
|
|
||||||
ast_entry_elem) {
|
|
||||||
hw_peer_id = ast_entry->ast_idx;
|
|
||||||
if (peer->self_ast_entry.ast_idx != hw_peer_id)
|
|
||||||
qdf_mem_free(ast_entry);
|
|
||||||
else
|
|
||||||
peer->self_ast_entry.ast_idx =
|
|
||||||
HTT_INVALID_PEER;
|
|
||||||
|
|
||||||
soc->ast_table[hw_peer_id] = NULL;
|
|
||||||
}
|
|
||||||
qdf_mem_free(peer);
|
qdf_mem_free(peer);
|
||||||
#endif
|
#endif
|
||||||
if (soc->cdp_soc.ol_ops->peer_unref_delete) {
|
if (soc->cdp_soc.ol_ops->peer_unref_delete) {
|
||||||
@@ -3584,6 +3666,14 @@ static void dp_set_vdev_param(struct cdp_vdev *vdev_handle,
|
|||||||
case CDP_UPDATE_TDLS_FLAGS:
|
case CDP_UPDATE_TDLS_FLAGS:
|
||||||
vdev->tdls_link_connected = val;
|
vdev->tdls_link_connected = val;
|
||||||
break;
|
break;
|
||||||
|
case CDP_CFG_WDS_AGING_TIMER:
|
||||||
|
if (val == 0)
|
||||||
|
qdf_timer_stop(&vdev->pdev->soc->wds_aging_timer);
|
||||||
|
else if (val != vdev->wds_aging_timer_val)
|
||||||
|
qdf_timer_mod(&vdev->pdev->soc->wds_aging_timer, val);
|
||||||
|
|
||||||
|
vdev->wds_aging_timer_val = val;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -3913,6 +4003,48 @@ static struct cdp_wds_ops dp_ops_wds = {
|
|||||||
.vdev_set_wds = dp_vdev_set_wds,
|
.vdev_set_wds = dp_vdev_set_wds,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* dp_peer_delete_ast_entries(): Delete all AST entries for a peer
|
||||||
|
* @soc - datapath soc handle
|
||||||
|
* @peer - datapath peer handle
|
||||||
|
*
|
||||||
|
* Delete the AST entries belonging to a peer
|
||||||
|
*/
|
||||||
|
#ifdef FEATURE_WDS
|
||||||
|
static inline void dp_peer_delete_ast_entries(struct dp_soc *soc,
|
||||||
|
struct dp_peer *peer)
|
||||||
|
{
|
||||||
|
struct dp_ast_entry *ast_entry;
|
||||||
|
qdf_spin_lock_bh(&soc->ast_lock);
|
||||||
|
DP_PEER_ITERATE_ASE_LIST(peer, ast_entry) {
|
||||||
|
if (ast_entry->next_hop) {
|
||||||
|
soc->cdp_soc.ol_ops->peer_del_wds_entry(
|
||||||
|
soc->osif_soc,
|
||||||
|
ast_entry->mac_addr.raw);
|
||||||
|
}
|
||||||
|
|
||||||
|
dp_peer_del_ast(soc, ast_entry);
|
||||||
|
}
|
||||||
|
qdf_spin_unlock_bh(&soc->ast_lock);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
static inline void dp_peer_delete_ast_entries(struct dp_soc *soc,
|
||||||
|
struct dp_peer *peer)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_WIN
|
||||||
|
static void dp_peer_teardown_wifi3(struct cdp_vdev *vdev_hdl, void *peer_hdl)
|
||||||
|
{
|
||||||
|
struct dp_vdev *vdev = (struct dp_vdev *) vdev_hdl;
|
||||||
|
struct dp_peer *peer = (struct dp_peer *) peer_hdl;
|
||||||
|
struct dp_soc *soc = (struct dp_soc *) vdev->pdev->soc;
|
||||||
|
|
||||||
|
dp_peer_delete_ast_entries(soc, peer);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static struct cdp_cmn_ops dp_ops_cmn = {
|
static struct cdp_cmn_ops dp_ops_cmn = {
|
||||||
.txrx_soc_attach_target = dp_soc_attach_target_wifi3,
|
.txrx_soc_attach_target = dp_soc_attach_target_wifi3,
|
||||||
.txrx_vdev_attach = dp_vdev_attach_wifi3,
|
.txrx_vdev_attach = dp_vdev_attach_wifi3,
|
||||||
@@ -3921,7 +4053,11 @@ static struct cdp_cmn_ops dp_ops_cmn = {
|
|||||||
.txrx_pdev_detach = dp_pdev_detach_wifi3,
|
.txrx_pdev_detach = dp_pdev_detach_wifi3,
|
||||||
.txrx_peer_create = dp_peer_create_wifi3,
|
.txrx_peer_create = dp_peer_create_wifi3,
|
||||||
.txrx_peer_setup = dp_peer_setup_wifi3,
|
.txrx_peer_setup = dp_peer_setup_wifi3,
|
||||||
|
#ifdef CONFIG_WIN
|
||||||
|
.txrx_peer_teardown = dp_peer_teardown_wifi3,
|
||||||
|
#else
|
||||||
.txrx_peer_teardown = NULL,
|
.txrx_peer_teardown = NULL,
|
||||||
|
#endif
|
||||||
.txrx_peer_delete = dp_peer_delete_wifi3,
|
.txrx_peer_delete = dp_peer_delete_wifi3,
|
||||||
.txrx_vdev_register = dp_vdev_register_wifi3,
|
.txrx_vdev_register = dp_vdev_register_wifi3,
|
||||||
.txrx_soc_detach = dp_soc_detach_wifi3,
|
.txrx_soc_detach = dp_soc_detach_wifi3,
|
||||||
|
@@ -124,6 +124,9 @@ static int dp_peer_find_add_id_to_obj(
|
|||||||
#define DP_PEER_HASH_LOAD_MULT 2
|
#define DP_PEER_HASH_LOAD_MULT 2
|
||||||
#define DP_PEER_HASH_LOAD_SHIFT 0
|
#define DP_PEER_HASH_LOAD_SHIFT 0
|
||||||
|
|
||||||
|
#define DP_AST_HASH_LOAD_MULT 2
|
||||||
|
#define DP_AST_HASH_LOAD_SHIFT 0
|
||||||
|
|
||||||
static int dp_peer_find_hash_attach(struct dp_soc *soc)
|
static int dp_peer_find_hash_attach(struct dp_soc *soc)
|
||||||
{
|
{
|
||||||
int i, hash_elems, log2;
|
int i, hash_elems, log2;
|
||||||
@@ -186,6 +189,300 @@ void dp_peer_find_hash_add(struct dp_soc *soc, struct dp_peer *peer)
|
|||||||
qdf_spin_unlock_bh(&soc->peer_ref_mutex);
|
qdf_spin_unlock_bh(&soc->peer_ref_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef FEATURE_WDS
|
||||||
|
/*
|
||||||
|
* dp_peer_ast_hash_attach() - Allocate and initialize AST Hash Table
|
||||||
|
* @soc: SoC handle
|
||||||
|
*
|
||||||
|
* Return: None
|
||||||
|
*/
|
||||||
|
static int dp_peer_ast_hash_attach(struct dp_soc *soc)
|
||||||
|
{
|
||||||
|
int i, hash_elems, log2;
|
||||||
|
|
||||||
|
hash_elems = ((WLAN_UMAC_PSOC_MAX_PEERS * DP_AST_HASH_LOAD_MULT) >>
|
||||||
|
DP_AST_HASH_LOAD_SHIFT);
|
||||||
|
|
||||||
|
log2 = dp_log2_ceil(hash_elems);
|
||||||
|
hash_elems = 1 << log2;
|
||||||
|
|
||||||
|
soc->ast_hash.mask = hash_elems - 1;
|
||||||
|
soc->ast_hash.idx_bits = log2;
|
||||||
|
|
||||||
|
/* allocate an array of TAILQ peer object lists */
|
||||||
|
soc->ast_hash.bins = qdf_mem_malloc(
|
||||||
|
hash_elems * sizeof(TAILQ_HEAD(anonymous_tail_q,
|
||||||
|
dp_ast_entry)));
|
||||||
|
|
||||||
|
if (!soc->ast_hash.bins)
|
||||||
|
return QDF_STATUS_E_NOMEM;
|
||||||
|
|
||||||
|
for (i = 0; i < hash_elems; i++)
|
||||||
|
TAILQ_INIT(&soc->ast_hash.bins[i]);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* dp_peer_ast_hash_detach() - Free AST Hash table
|
||||||
|
* @soc: SoC handle
|
||||||
|
*
|
||||||
|
* Return: None
|
||||||
|
*/
|
||||||
|
static void dp_peer_ast_hash_detach(struct dp_soc *soc)
|
||||||
|
{
|
||||||
|
qdf_mem_free(soc->ast_hash.bins);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* dp_peer_ast_hash_index() - Compute the AST hash from MAC address
|
||||||
|
* @soc: SoC handle
|
||||||
|
*
|
||||||
|
* Return: AST hash
|
||||||
|
*/
|
||||||
|
static inline uint32_t dp_peer_ast_hash_index(struct dp_soc *soc,
|
||||||
|
union dp_align_mac_addr *mac_addr)
|
||||||
|
{
|
||||||
|
uint32_t index;
|
||||||
|
|
||||||
|
index =
|
||||||
|
mac_addr->align2.bytes_ab ^
|
||||||
|
mac_addr->align2.bytes_cd ^
|
||||||
|
mac_addr->align2.bytes_ef;
|
||||||
|
index ^= index >> soc->ast_hash.idx_bits;
|
||||||
|
index &= soc->ast_hash.mask;
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* dp_peer_ast_hash_add() - Add AST entry into hash table
|
||||||
|
* @soc: SoC handle
|
||||||
|
*
|
||||||
|
* This function adds the AST entry into SoC AST hash table
|
||||||
|
* It assumes caller has taken the ast lock to protect the access to this table
|
||||||
|
*
|
||||||
|
* Return: None
|
||||||
|
*/
|
||||||
|
static inline void dp_peer_ast_hash_add(struct dp_soc *soc,
|
||||||
|
struct dp_ast_entry *ase)
|
||||||
|
{
|
||||||
|
uint32_t index;
|
||||||
|
|
||||||
|
index = dp_peer_ast_hash_index(soc, &ase->mac_addr);
|
||||||
|
TAILQ_INSERT_TAIL(&soc->ast_hash.bins[index], ase, hash_list_elem);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* dp_peer_ast_hash_remove() - Look up and remove AST entry from hash table
|
||||||
|
* @soc: SoC handle
|
||||||
|
*
|
||||||
|
* This function removes the AST entry from soc AST hash table
|
||||||
|
* It assumes caller has taken the ast lock to protect the access to this table
|
||||||
|
*
|
||||||
|
* Return: None
|
||||||
|
*/
|
||||||
|
static inline void dp_peer_ast_hash_remove(struct dp_soc *soc,
|
||||||
|
struct dp_ast_entry *ase)
|
||||||
|
{
|
||||||
|
unsigned index;
|
||||||
|
struct dp_ast_entry *tmpase;
|
||||||
|
int found = 0;
|
||||||
|
|
||||||
|
index = dp_peer_ast_hash_index(soc, &ase->mac_addr);
|
||||||
|
/* Check if tail is not empty before delete*/
|
||||||
|
QDF_ASSERT(!TAILQ_EMPTY(&soc->ast_hash.bins[index]));
|
||||||
|
|
||||||
|
TAILQ_FOREACH(tmpase, &soc->ast_hash.bins[index], hash_list_elem) {
|
||||||
|
if (tmpase == ase) {
|
||||||
|
found = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QDF_ASSERT(found);
|
||||||
|
TAILQ_REMOVE(&soc->ast_hash.bins[index], ase, hash_list_elem);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* dp_peer_ast_hash_find() - Find AST entry by MAC address
|
||||||
|
* @soc: SoC handle
|
||||||
|
*
|
||||||
|
* It assumes caller has taken the ast lock to protect the access to
|
||||||
|
* AST hash table
|
||||||
|
*
|
||||||
|
* Return: AST entry
|
||||||
|
*/
|
||||||
|
struct dp_ast_entry *dp_peer_ast_hash_find(struct dp_soc *soc,
|
||||||
|
uint8_t *ast_mac_addr, int mac_addr_is_aligned)
|
||||||
|
{
|
||||||
|
union dp_align_mac_addr local_mac_addr_aligned, *mac_addr;
|
||||||
|
unsigned index;
|
||||||
|
struct dp_ast_entry *ase;
|
||||||
|
|
||||||
|
if (mac_addr_is_aligned) {
|
||||||
|
mac_addr = (union dp_align_mac_addr *) ast_mac_addr;
|
||||||
|
} else {
|
||||||
|
qdf_mem_copy(
|
||||||
|
&local_mac_addr_aligned.raw[0],
|
||||||
|
ast_mac_addr, DP_MAC_ADDR_LEN);
|
||||||
|
mac_addr = &local_mac_addr_aligned;
|
||||||
|
}
|
||||||
|
|
||||||
|
index = dp_peer_ast_hash_index(soc, mac_addr);
|
||||||
|
TAILQ_FOREACH(ase, &soc->ast_hash.bins[index], hash_list_elem) {
|
||||||
|
if (dp_peer_find_mac_addr_cmp(mac_addr, &ase->mac_addr) == 0) {
|
||||||
|
return ase;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* dp_peer_map_ast() - Map the ast entry with HW AST Index
|
||||||
|
* @soc: SoC handle
|
||||||
|
* @peer: peer to which ast node belongs
|
||||||
|
* @mac_addr: MAC address of ast node
|
||||||
|
* @hw_peer_id: HW AST Index returned by target in peer map event
|
||||||
|
* @vdev_id: vdev id for VAP to which the peer belongs to
|
||||||
|
*
|
||||||
|
* Return: None
|
||||||
|
*/
|
||||||
|
static inline void dp_peer_map_ast(struct dp_soc *soc,
|
||||||
|
struct dp_peer *peer, uint8_t *mac_addr, uint16_t hw_peer_id,
|
||||||
|
uint8_t vdev_id)
|
||||||
|
{
|
||||||
|
struct dp_ast_entry *ast_entry;
|
||||||
|
|
||||||
|
if (!peer) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
|
||||||
|
"%s: peer %p ID %d vid %d mac %02x:%02x:%02x:%02x:%02x:%02x\n",
|
||||||
|
__func__, peer, hw_peer_id, vdev_id, mac_addr[0],
|
||||||
|
mac_addr[1], mac_addr[2], mac_addr[3],
|
||||||
|
mac_addr[4], mac_addr[5]);
|
||||||
|
|
||||||
|
qdf_spin_lock_bh(&soc->ast_lock);
|
||||||
|
TAILQ_FOREACH(ast_entry, &peer->ast_entry_list, ase_list_elem) {
|
||||||
|
if (!(qdf_mem_cmp(mac_addr, ast_entry->mac_addr.raw,
|
||||||
|
DP_MAC_ADDR_LEN))) {
|
||||||
|
qdf_spin_unlock_bh(&soc->ast_lock);
|
||||||
|
ast_entry->ast_idx = hw_peer_id;
|
||||||
|
soc->ast_table[hw_peer_id] = ast_entry;
|
||||||
|
ast_entry->is_active = TRUE;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
qdf_spin_unlock_bh(&soc->ast_lock);
|
||||||
|
|
||||||
|
if (soc->cdp_soc.ol_ops->peer_map_event) {
|
||||||
|
soc->cdp_soc.ol_ops->peer_map_event(soc->osif_soc,
|
||||||
|
peer->peer_ids[0], hw_peer_id, vdev_id,
|
||||||
|
mac_addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
|
||||||
|
"AST entry not found\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* dp_peer_add_ast() - Allocate and add AST entry into peer list
|
||||||
|
* @soc: SoC handle
|
||||||
|
* @peer: peer to which ast node belongs
|
||||||
|
* @mac_addr: MAC address of ast node
|
||||||
|
* @is_self: Is this base AST entry with peer mac address
|
||||||
|
*
|
||||||
|
* This API is used by WDS source port learning funtion to
|
||||||
|
* add a new AST entry into peer AST list
|
||||||
|
*
|
||||||
|
* Return: 0 if new entry is allocated,
|
||||||
|
* 1 if entry already exists or if allocation has failed
|
||||||
|
*/
|
||||||
|
int dp_peer_add_ast(struct dp_soc *soc, struct dp_peer *peer,
|
||||||
|
uint8_t *mac_addr, bool is_self)
|
||||||
|
{
|
||||||
|
struct dp_ast_entry *ast_entry;
|
||||||
|
|
||||||
|
QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
|
||||||
|
"%s: peer %p mac %02x:%02x:%02x:%02x:%02x:%02x\n",
|
||||||
|
__func__, peer, mac_addr[0], mac_addr[1], mac_addr[2],
|
||||||
|
mac_addr[3], mac_addr[4], mac_addr[5]);
|
||||||
|
|
||||||
|
qdf_spin_lock_bh(&soc->ast_lock);
|
||||||
|
|
||||||
|
/* If AST entry already exists , just return from here */
|
||||||
|
if (dp_peer_ast_hash_find(soc, mac_addr, 0)) {
|
||||||
|
qdf_spin_unlock_bh(&soc->ast_lock);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ast_entry = (struct dp_ast_entry *)
|
||||||
|
qdf_mem_malloc(sizeof(struct dp_ast_entry));
|
||||||
|
|
||||||
|
if (!ast_entry) {
|
||||||
|
qdf_spin_unlock_bh(&soc->ast_lock);
|
||||||
|
QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
|
||||||
|
FL("fail to allocate ast_entry"));
|
||||||
|
QDF_ASSERT(0);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
qdf_mem_copy(&ast_entry->mac_addr.raw[0], mac_addr, DP_MAC_ADDR_LEN);
|
||||||
|
ast_entry->peer = peer;
|
||||||
|
|
||||||
|
if (is_self) {
|
||||||
|
peer->self_ast_entry = ast_entry;
|
||||||
|
ast_entry->is_static = TRUE;
|
||||||
|
} else {
|
||||||
|
ast_entry->next_hop = 1;
|
||||||
|
ast_entry->is_static = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
ast_entry->is_active = TRUE;
|
||||||
|
TAILQ_INSERT_TAIL(&peer->ast_entry_list, ast_entry, ase_list_elem);
|
||||||
|
dp_peer_ast_hash_add(soc, ast_entry);
|
||||||
|
qdf_spin_unlock_bh(&soc->ast_lock);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* dp_peer_del_ast() - Delete and free AST entry
|
||||||
|
* @soc: SoC handle
|
||||||
|
* @ast_entry: AST entry of the node
|
||||||
|
*
|
||||||
|
* This function removes the AST entry from peer and soc tables
|
||||||
|
* It assumes caller has taken the ast lock to protect the access to these
|
||||||
|
* tables
|
||||||
|
*
|
||||||
|
* Return: None
|
||||||
|
*/
|
||||||
|
void dp_peer_del_ast(struct dp_soc *soc,
|
||||||
|
struct dp_ast_entry *ast_entry)
|
||||||
|
{
|
||||||
|
struct dp_peer *peer = ast_entry->peer;
|
||||||
|
soc->ast_table[ast_entry->ast_idx] = NULL;
|
||||||
|
TAILQ_REMOVE(&peer->ast_entry_list, ast_entry, ase_list_elem);
|
||||||
|
dp_peer_ast_hash_remove(soc, ast_entry);
|
||||||
|
qdf_mem_free(ast_entry);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
static int dp_peer_ast_hash_attach(struct dp_soc *soc)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
static void dp_peer_ast_hash_detach(struct dp_soc *soc)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
static inline void dp_peer_map_ast(struct dp_soc *soc, struct dp_peer *peer,
|
||||||
|
uint8_t *mac_addr, uint16_t hw_peer_id, uint8_t vdev_id)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
#if ATH_SUPPORT_WRAP
|
#if ATH_SUPPORT_WRAP
|
||||||
static struct dp_peer *dp_peer_find_hash_find(struct dp_soc *soc,
|
static struct dp_peer *dp_peer_find_hash_find(struct dp_soc *soc,
|
||||||
uint8_t *peer_mac_addr, int mac_addr_is_aligned, uint8_t vdev_id)
|
uint8_t *peer_mac_addr, int mac_addr_is_aligned, uint8_t vdev_id)
|
||||||
@@ -315,6 +612,12 @@ int dp_peer_find_attach(struct dp_soc *soc)
|
|||||||
dp_peer_find_map_detach(soc);
|
dp_peer_find_map_detach(soc);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (dp_peer_ast_hash_attach(soc)) {
|
||||||
|
dp_peer_find_hash_detach(soc);
|
||||||
|
dp_peer_find_map_detach(soc);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
return 0; /* success */
|
return 0; /* success */
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -383,7 +686,7 @@ static void dp_rx_tid_stats_cb(struct dp_soc *soc, void *cb_ctxt,
|
|||||||
queue_status->hole_cnt);
|
queue_status->hole_cnt);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void dp_peer_find_add_id(struct dp_soc *soc,
|
static inline struct dp_peer *dp_peer_find_add_id(struct dp_soc *soc,
|
||||||
uint8_t *peer_mac_addr, uint16_t peer_id, uint16_t hw_peer_id,
|
uint8_t *peer_mac_addr, uint16_t peer_id, uint16_t hw_peer_id,
|
||||||
uint8_t vdev_id)
|
uint8_t vdev_id)
|
||||||
{
|
{
|
||||||
@@ -411,55 +714,16 @@ static inline void dp_peer_find_add_id(struct dp_soc *soc,
|
|||||||
"%s: ref_cnt: %d", __func__,
|
"%s: ref_cnt: %d", __func__,
|
||||||
qdf_atomic_read(&peer->ref_cnt));
|
qdf_atomic_read(&peer->ref_cnt));
|
||||||
soc->peer_id_to_obj_map[peer_id] = peer;
|
soc->peer_id_to_obj_map[peer_id] = peer;
|
||||||
peer->self_ast_entry.ast_idx = hw_peer_id;
|
|
||||||
soc->ast_table[hw_peer_id] = &peer->self_ast_entry;
|
|
||||||
|
|
||||||
if (dp_peer_find_add_id_to_obj(peer, peer_id)) {
|
if (dp_peer_find_add_id_to_obj(peer, peer_id)) {
|
||||||
/* TBDXXX: assert for now */
|
/* TBDXXX: assert for now */
|
||||||
QDF_ASSERT(0);
|
QDF_ASSERT(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return peer;
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void dp_peer_add_ast(struct dp_soc *soc,
|
|
||||||
struct dp_peer *peer, uint8_t *peer_mac_addr, uint16_t hw_peer_id,
|
|
||||||
uint8_t vdev_id)
|
|
||||||
{
|
|
||||||
struct dp_ast_entry *ast_entry;
|
|
||||||
|
|
||||||
QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
|
|
||||||
"%s: peer %p ID %d vid %d mac %02x:%02x:%02x:%02x:%02x:%02x\n",
|
|
||||||
__func__, peer, hw_peer_id, vdev_id, peer_mac_addr[0],
|
|
||||||
peer_mac_addr[1], peer_mac_addr[2], peer_mac_addr[3],
|
|
||||||
peer_mac_addr[4], peer_mac_addr[5]);
|
|
||||||
|
|
||||||
TAILQ_FOREACH(ast_entry, &peer->ast_entry_list, ast_entry_elem) {
|
|
||||||
if (!(qdf_mem_cmp(peer_mac_addr, ast_entry->mac_addr,
|
|
||||||
DP_MAC_ADDR_LEN))) {
|
|
||||||
soc->ast_table[ast_entry->ast_idx] = NULL;
|
|
||||||
ast_entry->ast_idx = hw_peer_id;
|
|
||||||
soc->ast_table[hw_peer_id] = ast_entry;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ast_entry = (struct dp_ast_entry *)
|
return NULL;
|
||||||
qdf_mem_malloc(sizeof(struct dp_ast_entry));
|
|
||||||
|
|
||||||
if (!ast_entry) {
|
|
||||||
QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
|
|
||||||
FL("fail to allocate ast_entry for: %d"), hw_peer_id);
|
|
||||||
QDF_ASSERT(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
qdf_mem_copy(&ast_entry->mac_addr, peer_mac_addr, DP_MAC_ADDR_LEN);
|
|
||||||
ast_entry->peer = peer;
|
|
||||||
ast_entry->next_hop = 1;
|
|
||||||
TAILQ_INSERT_TAIL(&peer->ast_entry_list, ast_entry, ast_entry_elem);
|
|
||||||
soc->ast_table[hw_peer_id] = ast_entry;
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -483,7 +747,6 @@ dp_rx_peer_map_handler(void *soc_handle, uint16_t peer_id, uint16_t hw_peer_id,
|
|||||||
struct dp_soc *soc = (struct dp_soc *)soc_handle;
|
struct dp_soc *soc = (struct dp_soc *)soc_handle;
|
||||||
struct dp_peer *peer = NULL;
|
struct dp_peer *peer = NULL;
|
||||||
|
|
||||||
|
|
||||||
QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO_HIGH,
|
QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO_HIGH,
|
||||||
"peer_map_event (soc:%p): peer_id %di, hw_peer_id %d, peer_mac "
|
"peer_map_event (soc:%p): peer_id %di, hw_peer_id %d, peer_mac "
|
||||||
"%02x:%02x:%02x:%02x:%02x:%02x, vdev_id %d\n", soc, peer_id,
|
"%02x:%02x:%02x:%02x:%02x:%02x, vdev_id %d\n", soc, peer_id,
|
||||||
@@ -506,18 +769,12 @@ dp_rx_peer_map_handler(void *soc_handle, uint16_t peer_id, uint16_t hw_peer_id,
|
|||||||
* in this case just add the ast entry to the existing
|
* in this case just add the ast entry to the existing
|
||||||
* peer ast_list.
|
* peer ast_list.
|
||||||
*/
|
*/
|
||||||
if (!peer) {
|
if (!peer)
|
||||||
dp_peer_find_add_id(soc, peer_mac_addr, peer_id,
|
peer = dp_peer_find_add_id(soc, peer_mac_addr, peer_id,
|
||||||
hw_peer_id, vdev_id);
|
hw_peer_id, vdev_id);
|
||||||
if (soc->cdp_soc.ol_ops->peer_map_event) {
|
|
||||||
soc->cdp_soc.ol_ops->peer_map_event(soc->osif_soc,
|
|
||||||
peer_id, hw_peer_id, vdev_id, peer_mac_addr);
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
dp_peer_map_ast(soc, peer, peer_mac_addr,
|
||||||
dp_peer_add_ast(soc, peer, peer_mac_addr,
|
hw_peer_id, vdev_id);
|
||||||
hw_peer_id, vdev_id);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -565,6 +822,7 @@ dp_peer_find_detach(struct dp_soc *soc)
|
|||||||
{
|
{
|
||||||
dp_peer_find_map_detach(soc);
|
dp_peer_find_map_detach(soc);
|
||||||
dp_peer_find_hash_detach(soc);
|
dp_peer_find_hash_detach(soc);
|
||||||
|
dp_peer_ast_hash_detach(soc);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dp_rx_tid_update_cb(struct dp_soc *soc, void *cb_ctxt,
|
static void dp_rx_tid_update_cb(struct dp_soc *soc, void *cb_ctxt,
|
||||||
|
@@ -54,6 +54,23 @@ void dp_rx_sec_ind_handler(void *soc_handle, uint16_t peer_id,
|
|||||||
uint8_t dp_get_peer_mac_addr_frm_id(struct cdp_soc_t *soc_handle,
|
uint8_t dp_get_peer_mac_addr_frm_id(struct cdp_soc_t *soc_handle,
|
||||||
uint16_t peer_id, uint8_t *peer_mac);
|
uint16_t peer_id, uint8_t *peer_mac);
|
||||||
|
|
||||||
|
#ifdef FEATURE_WDS
|
||||||
|
int dp_peer_add_ast(struct dp_soc *soc, struct dp_peer *peer,
|
||||||
|
uint8_t *mac_addr, bool is_self);
|
||||||
|
void dp_peer_del_ast(struct dp_soc *soc,
|
||||||
|
struct dp_ast_entry *ast_entry);
|
||||||
|
#else
|
||||||
|
static inline int dp_peer_add_ast(struct dp_soc *soc, struct dp_peer *peer,
|
||||||
|
uint8_t *mac_addr, bool is_self)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
static inline void dp_peer_del_ast(struct dp_soc *soc,
|
||||||
|
struct dp_ast_entry *ast_entry)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef DP_LFR
|
#ifdef DP_LFR
|
||||||
/*
|
/*
|
||||||
* dp_get_vdev_from_soc_vdev_id_wifi3() -
|
* dp_get_vdev_from_soc_vdev_id_wifi3() -
|
||||||
|
@@ -344,7 +344,7 @@ void dp_rx_add_to_free_desc_list(union dp_rx_desc_list_elem_t **head,
|
|||||||
*
|
*
|
||||||
* Return: void:
|
* Return: void:
|
||||||
*/
|
*/
|
||||||
#ifndef CONFIG_MCL
|
#ifdef FEATURE_WDS
|
||||||
static inline void
|
static inline void
|
||||||
dp_rx_wds_srcport_learn(struct dp_soc *soc,
|
dp_rx_wds_srcport_learn(struct dp_soc *soc,
|
||||||
uint8_t *rx_tlv_hdr,
|
uint8_t *rx_tlv_hdr,
|
||||||
@@ -359,40 +359,61 @@ dp_rx_wds_srcport_learn(struct dp_soc *soc,
|
|||||||
memcpy(wds_src_mac, (qdf_nbuf_data(nbuf) + IEEE80211_ADDR_LEN),
|
memcpy(wds_src_mac, (qdf_nbuf_data(nbuf) + IEEE80211_ADDR_LEN),
|
||||||
IEEE80211_ADDR_LEN);
|
IEEE80211_ADDR_LEN);
|
||||||
|
|
||||||
if (!hal_rx_msdu_end_sa_is_valid_get(rx_tlv_hdr)) {
|
if (qdf_unlikely(!hal_rx_msdu_end_sa_is_valid_get(rx_tlv_hdr))) {
|
||||||
ret = soc->cdp_soc.ol_ops->peer_add_wds_entry(
|
if (!dp_peer_add_ast(soc, ta_peer, wds_src_mac, 0)) {
|
||||||
ta_peer->vdev->pdev->osif_pdev,
|
ret = soc->cdp_soc.ol_ops->peer_add_wds_entry(
|
||||||
wds_src_mac,
|
ta_peer->vdev->pdev->osif_pdev,
|
||||||
ta_peer->mac_addr.raw,
|
wds_src_mac,
|
||||||
flags);
|
ta_peer->mac_addr.raw,
|
||||||
} else if (sa_sw_peer_id != ta_peer->peer_ids[0]) {
|
flags);
|
||||||
ret = soc->cdp_soc.ol_ops->peer_update_wds_entry(
|
}
|
||||||
ta_peer->vdev->pdev->osif_pdev,
|
} else {
|
||||||
wds_src_mac,
|
/*
|
||||||
ta_peer->mac_addr.raw,
|
* Get the AST entry from HW SA index and mark it as active
|
||||||
flags);
|
*/
|
||||||
|
struct dp_ast_entry *ast;
|
||||||
|
uint16_t sa_idx = hal_rx_msdu_end_sa_idx_get(rx_tlv_hdr);
|
||||||
|
ast = soc->ast_table[sa_idx];
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Ensure we are updating the right AST entry by
|
||||||
|
* validating ast_idx.
|
||||||
|
* There is a possibility we might arrive here without
|
||||||
|
* AST MAP event , so this check is mandatory
|
||||||
|
*/
|
||||||
|
if (ast && (ast->ast_idx == sa_idx)) {
|
||||||
|
ast->is_active = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sa_sw_peer_id != ta_peer->peer_ids[0]) {
|
||||||
|
ret = soc->cdp_soc.ol_ops->peer_update_wds_entry(
|
||||||
|
ta_peer->vdev->pdev->osif_pdev,
|
||||||
|
wds_src_mac,
|
||||||
|
ta_peer->mac_addr.raw,
|
||||||
|
flags);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
static inline void
|
static inline void
|
||||||
dp_rx_wds_srcport_learn(struct dp_soc *soc,
|
dp_rx_wds_srcport_learn(struct dp_soc *soc,
|
||||||
uint8_t *rx_tlv_hdr,
|
uint8_t *rx_tlv_hdr,
|
||||||
struct dp_peer *ta_peer,
|
struct dp_peer *ta_peer,
|
||||||
qdf_nbuf_t nbuf)
|
qdf_nbuf_t nbuf)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
uint8_t dp_rx_process_invalid_peer(struct dp_soc *soc, qdf_nbuf_t nbuf);
|
uint8_t dp_rx_process_invalid_peer(struct dp_soc *soc, qdf_nbuf_t nbuf);
|
||||||
#define DP_RX_LIST_APPEND(head, tail, elem) \
|
#define DP_RX_LIST_APPEND(head, tail, elem) \
|
||||||
do { \
|
do { \
|
||||||
if (!(head)) { \
|
if (!(head)) { \
|
||||||
(head) = (elem); \
|
(head) = (elem); \
|
||||||
} else { \
|
} else { \
|
||||||
qdf_nbuf_set_next((tail), (elem)); \
|
qdf_nbuf_set_next((tail), (elem)); \
|
||||||
} \
|
} \
|
||||||
(tail) = (elem); \
|
(tail) = (elem); \
|
||||||
qdf_nbuf_set_next((tail), NULL); \
|
qdf_nbuf_set_next((tail), NULL); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
|
@@ -104,6 +104,15 @@ union dp_tx_desc_list_elem_t;
|
|||||||
struct dp_soc;
|
struct dp_soc;
|
||||||
union dp_rx_desc_list_elem_t;
|
union dp_rx_desc_list_elem_t;
|
||||||
|
|
||||||
|
#define DP_PDEV_ITERATE_VDEV_LIST(_pdev, _vdev) \
|
||||||
|
TAILQ_FOREACH((_vdev), &(_pdev)->vdev_list, vdev_list_elem)
|
||||||
|
|
||||||
|
#define DP_VDEV_ITERATE_PEER_LIST(_vdev, _peer) \
|
||||||
|
TAILQ_FOREACH((_peer), &(_vdev)->peer_list, peer_list_elem)
|
||||||
|
|
||||||
|
#define DP_PEER_ITERATE_ASE_LIST(_peer, _ase) \
|
||||||
|
TAILQ_FOREACH((_ase), &peer->ast_entry_list, ase_list_elem)
|
||||||
|
|
||||||
#define DP_MUTEX_TYPE qdf_spinlock_t
|
#define DP_MUTEX_TYPE qdf_spinlock_t
|
||||||
|
|
||||||
#define DP_FRAME_IS_MULTICAST(_a) (*(_a) & 0x01)
|
#define DP_FRAME_IS_MULTICAST(_a) (*(_a) & 0x01)
|
||||||
@@ -380,12 +389,48 @@ struct reo_desc_list_node {
|
|||||||
struct dp_rx_tid rx_tid;
|
struct dp_rx_tid rx_tid;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define DP_MAC_ADDR_LEN 6
|
||||||
|
union dp_align_mac_addr {
|
||||||
|
uint8_t raw[DP_MAC_ADDR_LEN];
|
||||||
|
struct {
|
||||||
|
uint16_t bytes_ab;
|
||||||
|
uint16_t bytes_cd;
|
||||||
|
uint16_t bytes_ef;
|
||||||
|
} align2;
|
||||||
|
struct {
|
||||||
|
uint32_t bytes_abcd;
|
||||||
|
uint16_t bytes_ef;
|
||||||
|
} align4;
|
||||||
|
struct {
|
||||||
|
uint16_t bytes_ab;
|
||||||
|
uint32_t bytes_cdef;
|
||||||
|
} align4_2;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* dp_ast_entry
|
||||||
|
*
|
||||||
|
* @ast_idx: Hardware AST Index
|
||||||
|
* @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
|
||||||
|
* @is_active: flag to indicate active data traffic on this node
|
||||||
|
* (used for aging out/expiry)
|
||||||
|
* @is_static: flag to indicate static entry (should not be expired)
|
||||||
|
* @ase_list_elem: node in peer AST list
|
||||||
|
* @hash_list_elem: node in soc AST hash list (mac address used as hash)
|
||||||
|
*/
|
||||||
struct dp_ast_entry {
|
struct dp_ast_entry {
|
||||||
uint16_t ast_idx;
|
uint16_t ast_idx;
|
||||||
uint8_t mac_addr[DP_MAC_ADDR_LEN];
|
/* MAC address */
|
||||||
uint8_t next_hop;
|
union dp_align_mac_addr mac_addr;
|
||||||
struct dp_peer *peer;
|
struct dp_peer *peer;
|
||||||
TAILQ_ENTRY(dp_ast_entry) ast_entry_elem;
|
bool next_hop;
|
||||||
|
bool is_active;
|
||||||
|
bool is_static;
|
||||||
|
TAILQ_ENTRY(dp_ast_entry) ase_list_elem;
|
||||||
|
TAILQ_ENTRY(dp_ast_entry) hash_list_elem;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct mect_entry {
|
struct mect_entry {
|
||||||
@@ -617,6 +662,14 @@ struct dp_soc {
|
|||||||
bool process_tx_status;
|
bool process_tx_status;
|
||||||
|
|
||||||
struct dp_ast_entry *ast_table[WLAN_UMAC_PSOC_MAX_PEERS];
|
struct dp_ast_entry *ast_table[WLAN_UMAC_PSOC_MAX_PEERS];
|
||||||
|
struct {
|
||||||
|
unsigned mask;
|
||||||
|
unsigned idx_bits;
|
||||||
|
TAILQ_HEAD(, dp_ast_entry) * bins;
|
||||||
|
} ast_hash;
|
||||||
|
|
||||||
|
qdf_spinlock_t ast_lock;
|
||||||
|
qdf_timer_t wds_aging_timer;
|
||||||
|
|
||||||
#ifdef DP_INTR_POLL_BASED
|
#ifdef DP_INTR_POLL_BASED
|
||||||
/*interrupt timer*/
|
/*interrupt timer*/
|
||||||
@@ -668,19 +721,6 @@ enum dp_nac_param_cmd {
|
|||||||
/* IEEE80211_NAC_PARAM_LIST */
|
/* IEEE80211_NAC_PARAM_LIST */
|
||||||
DP_NAC_PARAM_LIST,
|
DP_NAC_PARAM_LIST,
|
||||||
};
|
};
|
||||||
#define DP_MAC_ADDR_LEN 6
|
|
||||||
union dp_align_mac_addr {
|
|
||||||
uint8_t raw[DP_MAC_ADDR_LEN];
|
|
||||||
struct {
|
|
||||||
uint16_t bytes_ab;
|
|
||||||
uint16_t bytes_cd;
|
|
||||||
uint16_t bytes_ef;
|
|
||||||
} align2;
|
|
||||||
struct {
|
|
||||||
uint32_t bytes_abcd;
|
|
||||||
uint16_t bytes_ef;
|
|
||||||
} align4;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* struct dp_neighbour_peer - neighbour peer list type for smart mesh
|
* struct dp_neighbour_peer - neighbour peer list type for smart mesh
|
||||||
@@ -920,6 +960,9 @@ struct dp_vdev {
|
|||||||
/* WDS enabled */
|
/* WDS enabled */
|
||||||
bool wds_enabled;
|
bool wds_enabled;
|
||||||
|
|
||||||
|
/* WDS Aging timer period */
|
||||||
|
uint32_t wds_aging_timer_val;
|
||||||
|
|
||||||
/* NAWDS enabled */
|
/* NAWDS enabled */
|
||||||
bool nawds_enabled;
|
bool nawds_enabled;
|
||||||
|
|
||||||
@@ -968,7 +1011,7 @@ struct dp_peer {
|
|||||||
/* VDEV to which this peer is associated */
|
/* VDEV to which this peer is associated */
|
||||||
struct dp_vdev *vdev;
|
struct dp_vdev *vdev;
|
||||||
|
|
||||||
struct dp_ast_entry self_ast_entry;
|
struct dp_ast_entry *self_ast_entry;
|
||||||
|
|
||||||
qdf_atomic_t ref_cnt;
|
qdf_atomic_t ref_cnt;
|
||||||
|
|
||||||
|
@@ -813,6 +813,31 @@ hal_rx_msdu_end_l3_hdr_padding_get(uint8_t *buf)
|
|||||||
return l3_header_padding;
|
return l3_header_padding;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define HAL_RX_MSDU_END_SA_IDX_GET(_rx_msdu_end) \
|
||||||
|
(_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_msdu_end, \
|
||||||
|
RX_MSDU_END_13_SA_IDX_OFFSET)), \
|
||||||
|
RX_MSDU_END_13_SA_IDX_MASK, \
|
||||||
|
RX_MSDU_END_13_SA_IDX_LSB))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* hal_rx_msdu_end_sa_idx_get(): API to get the
|
||||||
|
* sa_idx from rx_msdu_end TLV
|
||||||
|
*
|
||||||
|
* @ buf: pointer to the start of RX PKT TLV headers
|
||||||
|
* Return: sa_idx (SA AST index)
|
||||||
|
*/
|
||||||
|
static inline uint16_t
|
||||||
|
hal_rx_msdu_end_sa_idx_get(uint8_t *buf)
|
||||||
|
{
|
||||||
|
struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf;
|
||||||
|
struct rx_msdu_end *msdu_end = &pkt_tlvs->msdu_end_tlv.rx_msdu_end;
|
||||||
|
uint8_t sa_idx;
|
||||||
|
|
||||||
|
sa_idx = HAL_RX_MSDU_END_SA_IDX_GET(msdu_end);
|
||||||
|
|
||||||
|
return sa_idx;
|
||||||
|
}
|
||||||
|
|
||||||
#define HAL_RX_MSDU_END_SA_IS_VALID_GET(_rx_msdu_end) \
|
#define HAL_RX_MSDU_END_SA_IS_VALID_GET(_rx_msdu_end) \
|
||||||
(_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_msdu_end, \
|
(_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_msdu_end, \
|
||||||
RX_MSDU_END_5_SA_IS_VALID_OFFSET)), \
|
RX_MSDU_END_5_SA_IS_VALID_OFFSET)), \
|
||||||
|
Reference in New Issue
Block a user