qcacmn: skip MEC ast entry creation in wlan fw
MEC ast entry will be created only in software and adding MEC entry to wlan fw is skipped. Change-Id: I6991f9f12ceb22a7c599cdf3cc2a13c996d93671
This commit is contained in:
@@ -402,7 +402,6 @@ enum cdp_txrx_ast_entry_type {
|
|||||||
CDP_TXRX_AST_TYPE_STATIC, /* static ast entry for connected peer */
|
CDP_TXRX_AST_TYPE_STATIC, /* static ast entry for connected peer */
|
||||||
CDP_TXRX_AST_TYPE_SELF, /* static ast entry for self peer (STA mode) */
|
CDP_TXRX_AST_TYPE_SELF, /* static ast entry for self peer (STA mode) */
|
||||||
CDP_TXRX_AST_TYPE_WDS, /* WDS peer ast entry type*/
|
CDP_TXRX_AST_TYPE_WDS, /* WDS peer ast entry type*/
|
||||||
CDP_TXRX_AST_TYPE_MEC, /* Multicast echo ast entry type */
|
|
||||||
CDP_TXRX_AST_TYPE_WDS_HM, /* HM WDS entry */
|
CDP_TXRX_AST_TYPE_WDS_HM, /* HM WDS entry */
|
||||||
CDP_TXRX_AST_TYPE_STA_BSS, /* BSS entry(STA mode) */
|
CDP_TXRX_AST_TYPE_STA_BSS, /* BSS entry(STA mode) */
|
||||||
CDP_TXRX_AST_TYPE_DA, /* AST entry based on Destination address */
|
CDP_TXRX_AST_TYPE_DA, /* AST entry based on Destination address */
|
||||||
|
@@ -1016,7 +1016,13 @@ static inline void dp_update_vdev_stats(struct dp_soc *soc,
|
|||||||
DP_STATS_AGGR(_tgtobj, _srcobj, rx.multipass_rx_pkt_drop); \
|
DP_STATS_AGGR(_tgtobj, _srcobj, rx.multipass_rx_pkt_drop); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
extern int dp_peer_find_attach(struct dp_soc *soc);
|
/**
|
||||||
|
* dp_peer_find_attach() - Allocates memory for peer objects
|
||||||
|
* @soc: SoC handle
|
||||||
|
*
|
||||||
|
* Return: QDF_STATUS
|
||||||
|
*/
|
||||||
|
QDF_STATUS dp_peer_find_attach(struct dp_soc *soc);
|
||||||
extern void dp_peer_find_detach(struct dp_soc *soc);
|
extern void dp_peer_find_detach(struct dp_soc *soc);
|
||||||
extern void dp_peer_find_hash_add(struct dp_soc *soc, struct dp_peer *peer);
|
extern void dp_peer_find_hash_add(struct dp_soc *soc, struct dp_peer *peer);
|
||||||
extern void dp_peer_find_hash_remove(struct dp_soc *soc, struct dp_peer *peer);
|
extern void dp_peer_find_hash_remove(struct dp_soc *soc, struct dp_peer *peer);
|
||||||
|
@@ -652,6 +652,103 @@ static void dp_service_lmac_rings(void *arg)
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef FEATURE_MEC
|
||||||
|
void dp_peer_mec_flush_entries(struct dp_soc *soc)
|
||||||
|
{
|
||||||
|
unsigned int index;
|
||||||
|
struct dp_mec_entry *mecentry, *mecentry_next;
|
||||||
|
|
||||||
|
TAILQ_HEAD(, dp_mec_entry) free_list;
|
||||||
|
TAILQ_INIT(&free_list);
|
||||||
|
|
||||||
|
if (!soc->mec_hash.mask)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!soc->mec_hash.bins)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!qdf_atomic_read(&soc->mec_cnt))
|
||||||
|
return;
|
||||||
|
|
||||||
|
qdf_spin_lock_bh(&soc->mec_lock);
|
||||||
|
for (index = 0; index <= soc->mec_hash.mask; index++) {
|
||||||
|
if (!TAILQ_EMPTY(&soc->mec_hash.bins[index])) {
|
||||||
|
TAILQ_FOREACH_SAFE(mecentry, &soc->mec_hash.bins[index],
|
||||||
|
hash_list_elem, mecentry_next) {
|
||||||
|
dp_peer_mec_detach_entry(soc, mecentry, &free_list);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
qdf_spin_unlock_bh(&soc->mec_lock);
|
||||||
|
|
||||||
|
dp_peer_mec_free_list(soc, &free_list);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* dp_print_mec_entries() - Dump MEC entries in table
|
||||||
|
* @soc: Datapath soc handle
|
||||||
|
*
|
||||||
|
* Return: none
|
||||||
|
*/
|
||||||
|
static void dp_print_mec_stats(struct dp_soc *soc)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
uint32_t index;
|
||||||
|
struct dp_mec_entry *mecentry = NULL, *mec_list;
|
||||||
|
uint32_t num_entries = 0;
|
||||||
|
|
||||||
|
DP_PRINT_STATS("MEC Stats:");
|
||||||
|
DP_PRINT_STATS(" Entries Added = %d", soc->stats.mec.added);
|
||||||
|
DP_PRINT_STATS(" Entries Deleted = %d", soc->stats.mec.deleted);
|
||||||
|
|
||||||
|
if (!qdf_atomic_read(&soc->mec_cnt))
|
||||||
|
return;
|
||||||
|
|
||||||
|
mec_list = qdf_mem_malloc(sizeof(*mecentry) * DP_PEER_MAX_MEC_ENTRY);
|
||||||
|
if (!mec_list) {
|
||||||
|
dp_peer_warn("%pK: failed to allocate mec_list", soc);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
DP_PRINT_STATS("MEC Table:");
|
||||||
|
for (index = 0; index <= soc->mec_hash.mask; index++) {
|
||||||
|
qdf_spin_lock_bh(&soc->mec_lock);
|
||||||
|
if (TAILQ_EMPTY(&soc->mec_hash.bins[index])) {
|
||||||
|
qdf_spin_unlock_bh(&soc->mec_lock);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
TAILQ_FOREACH(mecentry, &soc->mec_hash.bins[index],
|
||||||
|
hash_list_elem) {
|
||||||
|
qdf_mem_copy(&mec_list[num_entries], mecentry,
|
||||||
|
sizeof(*mecentry));
|
||||||
|
num_entries++;
|
||||||
|
}
|
||||||
|
qdf_spin_unlock_bh(&soc->mec_lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!num_entries) {
|
||||||
|
qdf_mem_free(mec_list);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < num_entries; i++) {
|
||||||
|
DP_PRINT_STATS("%6d mac_addr = " QDF_MAC_ADDR_FMT
|
||||||
|
" is_active = %d pdev_id = %d vdev_id = %d",
|
||||||
|
i,
|
||||||
|
QDF_MAC_ADDR_REF(mec_list[i].mac_addr.raw),
|
||||||
|
mec_list[i].is_active,
|
||||||
|
mec_list[i].pdev_id,
|
||||||
|
mec_list[i].vdev_id);
|
||||||
|
}
|
||||||
|
qdf_mem_free(mec_list);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
static void dp_print_mec_stats(struct dp_soc *soc)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static int dp_peer_add_ast_wifi3(struct cdp_soc_t *soc_hdl,
|
static int dp_peer_add_ast_wifi3(struct cdp_soc_t *soc_hdl,
|
||||||
uint8_t vdev_id,
|
uint8_t vdev_id,
|
||||||
uint8_t *peer_mac,
|
uint8_t *peer_mac,
|
||||||
@@ -862,6 +959,7 @@ static void dp_wds_flush_ast_table_wifi3(struct cdp_soc_t *soc_hdl)
|
|||||||
DP_MOD_ID_CDP);
|
DP_MOD_ID_CDP);
|
||||||
|
|
||||||
qdf_spin_unlock_bh(&soc->ast_lock);
|
qdf_spin_unlock_bh(&soc->ast_lock);
|
||||||
|
dp_peer_mec_flush_entries(soc);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1275,7 +1373,7 @@ dp_print_peer_ast_entries(struct dp_soc *soc, struct dp_peer *peer, void *arg)
|
|||||||
struct dp_ast_entry *ase, *tmp_ase;
|
struct dp_ast_entry *ase, *tmp_ase;
|
||||||
uint32_t num_entries = 0;
|
uint32_t num_entries = 0;
|
||||||
char type[CDP_TXRX_AST_TYPE_MAX][10] = {
|
char type[CDP_TXRX_AST_TYPE_MAX][10] = {
|
||||||
"NONE", "STATIC", "SELF", "WDS", "MEC", "HMWDS", "BSS",
|
"NONE", "STATIC", "SELF", "WDS", "HMWDS", "BSS",
|
||||||
"DA", "HMWDS_SEC"};
|
"DA", "HMWDS_SEC"};
|
||||||
|
|
||||||
DP_PEER_ITERATE_ASE_LIST(peer, ase, tmp_ase) {
|
DP_PEER_ITERATE_ASE_LIST(peer, ase, tmp_ase) {
|
||||||
@@ -4803,6 +4901,8 @@ static void dp_soc_deinit(void *txrx_soc)
|
|||||||
|
|
||||||
qdf_spinlock_destroy(&soc->ast_lock);
|
qdf_spinlock_destroy(&soc->ast_lock);
|
||||||
|
|
||||||
|
dp_peer_mec_spinlock_destroy(soc);
|
||||||
|
|
||||||
qdf_nbuf_queue_free(&soc->htt_stats.msg);
|
qdf_nbuf_queue_free(&soc->htt_stats.msg);
|
||||||
|
|
||||||
qdf_nbuf_queue_free(&soc->invalid_buf_queue);
|
qdf_nbuf_queue_free(&soc->invalid_buf_queue);
|
||||||
@@ -8459,6 +8559,7 @@ dp_print_host_stats(struct dp_vdev *vdev,
|
|||||||
break;
|
break;
|
||||||
case TXRX_AST_STATS:
|
case TXRX_AST_STATS:
|
||||||
dp_print_ast_stats(pdev->soc);
|
dp_print_ast_stats(pdev->soc);
|
||||||
|
dp_print_mec_stats(pdev->soc);
|
||||||
dp_print_peer_table(vdev);
|
dp_print_peer_table(vdev);
|
||||||
break;
|
break;
|
||||||
case TXRX_SRNG_PTR_STATS:
|
case TXRX_SRNG_PTR_STATS:
|
||||||
@@ -12526,6 +12627,7 @@ void *dp_soc_init(struct dp_soc *soc, HTC_HANDLE htc_handle,
|
|||||||
qdf_nbuf_queue_init(&soc->htt_stats.msg);
|
qdf_nbuf_queue_init(&soc->htt_stats.msg);
|
||||||
|
|
||||||
qdf_spinlock_create(&soc->ast_lock);
|
qdf_spinlock_create(&soc->ast_lock);
|
||||||
|
dp_peer_mec_spinlock_create(soc);
|
||||||
|
|
||||||
qdf_spinlock_create(&soc->reo_desc_freelist_lock);
|
qdf_spinlock_create(&soc->reo_desc_freelist_lock);
|
||||||
qdf_list_create(&soc->reo_desc_freelist, REO_DESC_FREELIST_SIZE);
|
qdf_list_create(&soc->reo_desc_freelist, REO_DESC_FREELIST_SIZE);
|
||||||
|
@@ -103,7 +103,7 @@ static inline int dp_peer_find_mac_addr_cmp(
|
|||||||
& (mac_addr1->align4.bytes_ef == mac_addr2->align4.bytes_ef));
|
& (mac_addr1->align4.bytes_ef == mac_addr2->align4.bytes_ef));
|
||||||
}
|
}
|
||||||
|
|
||||||
static int dp_peer_ast_table_attach(struct dp_soc *soc)
|
static QDF_STATUS dp_peer_ast_table_attach(struct dp_soc *soc)
|
||||||
{
|
{
|
||||||
uint32_t max_ast_index;
|
uint32_t max_ast_index;
|
||||||
|
|
||||||
@@ -116,16 +116,16 @@ static int dp_peer_ast_table_attach(struct dp_soc *soc)
|
|||||||
dp_peer_err("%pK: ast_table memory allocation failed", soc);
|
dp_peer_err("%pK: ast_table memory allocation failed", soc);
|
||||||
return QDF_STATUS_E_NOMEM;
|
return QDF_STATUS_E_NOMEM;
|
||||||
}
|
}
|
||||||
return 0; /* success */
|
return QDF_STATUS_SUCCESS; /* success */
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* dp_peer_find_map_attach() - allocate memory for peer_id_to_obj_map
|
* dp_peer_find_map_attach() - allocate memory for peer_id_to_obj_map
|
||||||
* @soc: soc handle
|
* @soc: soc handle
|
||||||
*
|
*
|
||||||
* return: none
|
* return: QDF_STATUS
|
||||||
*/
|
*/
|
||||||
static int dp_peer_find_map_attach(struct dp_soc *soc)
|
static QDF_STATUS dp_peer_find_map_attach(struct dp_soc *soc)
|
||||||
{
|
{
|
||||||
uint32_t max_peers, peer_map_size;
|
uint32_t max_peers, peer_map_size;
|
||||||
|
|
||||||
@@ -149,7 +149,7 @@ static int dp_peer_find_map_attach(struct dp_soc *soc)
|
|||||||
qdf_mem_zero(soc->peer_id_to_obj_map, peer_map_size);
|
qdf_mem_zero(soc->peer_id_to_obj_map, peer_map_size);
|
||||||
|
|
||||||
qdf_spinlock_create(&soc->peer_map_lock);
|
qdf_spinlock_create(&soc->peer_map_lock);
|
||||||
return 0; /* success */
|
return QDF_STATUS_SUCCESS; /* success */
|
||||||
}
|
}
|
||||||
|
|
||||||
static int dp_log2_ceil(unsigned int value)
|
static int dp_log2_ceil(unsigned int value)
|
||||||
@@ -176,9 +176,9 @@ static int dp_log2_ceil(unsigned int value)
|
|||||||
* dp_peer_find_hash_attach() - allocate memory for peer_hash table
|
* dp_peer_find_hash_attach() - allocate memory for peer_hash table
|
||||||
* @soc: soc handle
|
* @soc: soc handle
|
||||||
*
|
*
|
||||||
* return: none
|
* return: QDF_STATUS
|
||||||
*/
|
*/
|
||||||
static int dp_peer_find_hash_attach(struct dp_soc *soc)
|
static QDF_STATUS dp_peer_find_hash_attach(struct dp_soc *soc)
|
||||||
{
|
{
|
||||||
int i, hash_elems, log2;
|
int i, hash_elems, log2;
|
||||||
|
|
||||||
@@ -201,7 +201,7 @@ static int dp_peer_find_hash_attach(struct dp_soc *soc)
|
|||||||
TAILQ_INIT(&soc->peer_hash.bins[i]);
|
TAILQ_INIT(&soc->peer_hash.bins[i]);
|
||||||
|
|
||||||
qdf_spinlock_create(&soc->peer_hash_lock);
|
qdf_spinlock_create(&soc->peer_hash_lock);
|
||||||
return 0;
|
return QDF_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -425,14 +425,228 @@ static bool dp_peer_exist_on_pdev(struct dp_soc *soc,
|
|||||||
return found;
|
return found;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef FEATURE_MEC
|
||||||
|
/**
|
||||||
|
* dp_peer_mec_hash_attach() - Allocate and initialize MEC Hash Table
|
||||||
|
* @soc: SoC handle
|
||||||
|
*
|
||||||
|
* Return: QDF_STATUS
|
||||||
|
*/
|
||||||
|
static QDF_STATUS dp_peer_mec_hash_attach(struct dp_soc *soc)
|
||||||
|
{
|
||||||
|
int log2, hash_elems, i;
|
||||||
|
|
||||||
|
log2 = dp_log2_ceil(DP_PEER_MAX_MEC_IDX);
|
||||||
|
hash_elems = 1 << log2;
|
||||||
|
|
||||||
|
soc->mec_hash.mask = hash_elems - 1;
|
||||||
|
soc->mec_hash.idx_bits = log2;
|
||||||
|
|
||||||
|
dp_peer_info("%pK: max mec index: %d",
|
||||||
|
soc, DP_PEER_MAX_MEC_IDX);
|
||||||
|
|
||||||
|
/* allocate an array of TAILQ mec object lists */
|
||||||
|
soc->mec_hash.bins = qdf_mem_malloc(hash_elems *
|
||||||
|
sizeof(TAILQ_HEAD(anonymous_tail_q,
|
||||||
|
dp_mec_entry)));
|
||||||
|
|
||||||
|
if (!soc->mec_hash.bins)
|
||||||
|
return QDF_STATUS_E_NOMEM;
|
||||||
|
|
||||||
|
for (i = 0; i < hash_elems; i++)
|
||||||
|
TAILQ_INIT(&soc->mec_hash.bins[i]);
|
||||||
|
|
||||||
|
return QDF_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* dp_peer_mec_hash_index() - Compute the MEC hash from MAC address
|
||||||
|
* @soc: SoC handle
|
||||||
|
*
|
||||||
|
* Return: MEC hash
|
||||||
|
*/
|
||||||
|
static inline uint32_t dp_peer_mec_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->mec_hash.idx_bits;
|
||||||
|
index &= soc->mec_hash.mask;
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct dp_mec_entry *dp_peer_mec_hash_find_by_pdevid(struct dp_soc *soc,
|
||||||
|
uint8_t pdev_id,
|
||||||
|
uint8_t *mec_mac_addr)
|
||||||
|
{
|
||||||
|
union dp_align_mac_addr local_mac_addr_aligned, *mac_addr;
|
||||||
|
uint32_t index;
|
||||||
|
struct dp_mec_entry *mecentry;
|
||||||
|
|
||||||
|
qdf_mem_copy(&local_mac_addr_aligned.raw[0],
|
||||||
|
mec_mac_addr, QDF_MAC_ADDR_SIZE);
|
||||||
|
mac_addr = &local_mac_addr_aligned;
|
||||||
|
|
||||||
|
index = dp_peer_mec_hash_index(soc, mac_addr);
|
||||||
|
TAILQ_FOREACH(mecentry, &soc->mec_hash.bins[index], hash_list_elem) {
|
||||||
|
if ((pdev_id == mecentry->pdev_id) &&
|
||||||
|
!dp_peer_find_mac_addr_cmp(mac_addr, &mecentry->mac_addr))
|
||||||
|
return mecentry;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* dp_peer_mec_hash_add() - Add MEC entry into hash table
|
||||||
|
* @soc: SoC handle
|
||||||
|
*
|
||||||
|
* This function adds the MEC entry into SoC MEC hash table
|
||||||
|
*
|
||||||
|
* Return: None
|
||||||
|
*/
|
||||||
|
static inline void dp_peer_mec_hash_add(struct dp_soc *soc,
|
||||||
|
struct dp_mec_entry *mecentry)
|
||||||
|
{
|
||||||
|
uint32_t index;
|
||||||
|
|
||||||
|
index = dp_peer_mec_hash_index(soc, &mecentry->mac_addr);
|
||||||
|
qdf_spin_lock_bh(&soc->mec_lock);
|
||||||
|
TAILQ_INSERT_TAIL(&soc->mec_hash.bins[index], mecentry, hash_list_elem);
|
||||||
|
qdf_spin_unlock_bh(&soc->mec_lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
QDF_STATUS dp_peer_mec_add_entry(struct dp_soc *soc,
|
||||||
|
struct dp_vdev *vdev,
|
||||||
|
uint8_t *mac_addr)
|
||||||
|
{
|
||||||
|
struct dp_mec_entry *mecentry = NULL;
|
||||||
|
struct dp_pdev *pdev = NULL;
|
||||||
|
|
||||||
|
if (!vdev) {
|
||||||
|
dp_peer_err("%pK: Peers vdev is NULL", soc);
|
||||||
|
return QDF_STATUS_E_INVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
pdev = vdev->pdev;
|
||||||
|
|
||||||
|
if (qdf_unlikely(qdf_atomic_read(&soc->mec_cnt) >=
|
||||||
|
DP_PEER_MAX_MEC_ENTRY)) {
|
||||||
|
dp_peer_warn("%pK: max MEC entry limit reached mac_addr: "
|
||||||
|
QDF_MAC_ADDR_FMT, soc, QDF_MAC_ADDR_REF(mac_addr));
|
||||||
|
return QDF_STATUS_E_NOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
qdf_spin_lock_bh(&soc->mec_lock);
|
||||||
|
mecentry = dp_peer_mec_hash_find_by_pdevid(soc, pdev->pdev_id,
|
||||||
|
mac_addr);
|
||||||
|
if (qdf_likely(mecentry)) {
|
||||||
|
mecentry->is_active = TRUE;
|
||||||
|
qdf_spin_unlock_bh(&soc->mec_lock);
|
||||||
|
return QDF_STATUS_E_ALREADY;
|
||||||
|
}
|
||||||
|
|
||||||
|
qdf_spin_unlock_bh(&soc->mec_lock);
|
||||||
|
|
||||||
|
dp_peer_debug("%pK: pdevid: %u vdev: %u type: MEC mac_addr: "
|
||||||
|
QDF_MAC_ADDR_FMT,
|
||||||
|
soc, pdev->pdev_id, vdev->vdev_id,
|
||||||
|
QDF_MAC_ADDR_REF(mac_addr));
|
||||||
|
|
||||||
|
mecentry = (struct dp_mec_entry *)
|
||||||
|
qdf_mem_malloc(sizeof(struct dp_mec_entry));
|
||||||
|
|
||||||
|
if (qdf_unlikely(!mecentry)) {
|
||||||
|
dp_peer_err("%pK: fail to allocate mecentry", soc);
|
||||||
|
return QDF_STATUS_E_NOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
qdf_copy_macaddr((struct qdf_mac_addr *)&mecentry->mac_addr.raw[0],
|
||||||
|
(struct qdf_mac_addr *)mac_addr);
|
||||||
|
mecentry->pdev_id = pdev->pdev_id;
|
||||||
|
mecentry->vdev_id = vdev->vdev_id;
|
||||||
|
mecentry->is_active = TRUE;
|
||||||
|
dp_peer_mec_hash_add(soc, mecentry);
|
||||||
|
|
||||||
|
qdf_atomic_inc(&soc->mec_cnt);
|
||||||
|
DP_STATS_INC(soc, mec.added, 1);
|
||||||
|
|
||||||
|
return QDF_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
void dp_peer_mec_detach_entry(struct dp_soc *soc, struct dp_mec_entry *mecentry,
|
||||||
|
void *ptr)
|
||||||
|
{
|
||||||
|
uint32_t index = dp_peer_mec_hash_index(soc, &mecentry->mac_addr);
|
||||||
|
|
||||||
|
TAILQ_HEAD(, dp_mec_entry) * free_list = ptr;
|
||||||
|
|
||||||
|
TAILQ_REMOVE(&soc->mec_hash.bins[index], mecentry,
|
||||||
|
hash_list_elem);
|
||||||
|
TAILQ_INSERT_TAIL(free_list, mecentry, hash_list_elem);
|
||||||
|
}
|
||||||
|
|
||||||
|
void dp_peer_mec_free_list(struct dp_soc *soc, void *ptr)
|
||||||
|
{
|
||||||
|
struct dp_mec_entry *mecentry, *mecentry_next;
|
||||||
|
|
||||||
|
TAILQ_HEAD(, dp_mec_entry) * free_list = ptr;
|
||||||
|
|
||||||
|
TAILQ_FOREACH_SAFE(mecentry, free_list, hash_list_elem,
|
||||||
|
mecentry_next) {
|
||||||
|
dp_peer_debug("%pK: MEC delete for mac_addr " QDF_MAC_ADDR_FMT,
|
||||||
|
soc, QDF_MAC_ADDR_REF(&mecentry->mac_addr));
|
||||||
|
qdf_mem_free(mecentry);
|
||||||
|
qdf_atomic_dec(&soc->mec_cnt);
|
||||||
|
DP_STATS_INC(soc, mec.deleted, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* dp_peer_mec_hash_detach() - Free MEC Hash table
|
||||||
|
* @soc: SoC handle
|
||||||
|
*
|
||||||
|
* Return: None
|
||||||
|
*/
|
||||||
|
static void dp_peer_mec_hash_detach(struct dp_soc *soc)
|
||||||
|
{
|
||||||
|
dp_peer_mec_flush_entries(soc);
|
||||||
|
qdf_mem_free(soc->mec_hash.bins);
|
||||||
|
soc->mec_hash.bins = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void dp_peer_mec_spinlock_destroy(struct dp_soc *soc)
|
||||||
|
{
|
||||||
|
qdf_spinlock_destroy(&soc->mec_lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
void dp_peer_mec_spinlock_create(struct dp_soc *soc)
|
||||||
|
{
|
||||||
|
qdf_spinlock_create(&soc->mec_lock);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
static QDF_STATUS dp_peer_mec_hash_attach(struct dp_soc *soc)
|
||||||
|
{
|
||||||
|
return QDF_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dp_peer_mec_hash_detach(struct dp_soc *soc)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef FEATURE_AST
|
#ifdef FEATURE_AST
|
||||||
/*
|
/*
|
||||||
* dp_peer_ast_hash_attach() - Allocate and initialize AST Hash Table
|
* dp_peer_ast_hash_attach() - Allocate and initialize AST Hash Table
|
||||||
* @soc: SoC handle
|
* @soc: SoC handle
|
||||||
*
|
*
|
||||||
* Return: None
|
* Return: QDF_STATUS
|
||||||
*/
|
*/
|
||||||
static int dp_peer_ast_hash_attach(struct dp_soc *soc)
|
static QDF_STATUS dp_peer_ast_hash_attach(struct dp_soc *soc)
|
||||||
{
|
{
|
||||||
int i, hash_elems, log2;
|
int i, hash_elems, log2;
|
||||||
unsigned int max_ast_idx = wlan_cfg_get_max_ast_idx(soc->wlan_cfg_ctx);
|
unsigned int max_ast_idx = wlan_cfg_get_max_ast_idx(soc->wlan_cfg_ctx);
|
||||||
@@ -460,7 +674,7 @@ static int dp_peer_ast_hash_attach(struct dp_soc *soc)
|
|||||||
for (i = 0; i < hash_elems; i++)
|
for (i = 0; i < hash_elems; i++)
|
||||||
TAILQ_INIT(&soc->ast_hash.bins[i]);
|
TAILQ_INIT(&soc->ast_hash.bins[i]);
|
||||||
|
|
||||||
return 0;
|
return QDF_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -911,13 +1125,10 @@ QDF_STATUS dp_peer_add_ast(struct dp_soc *soc,
|
|||||||
ast_entry = dp_peer_ast_hash_find_by_pdevid(soc, mac_addr,
|
ast_entry = dp_peer_ast_hash_find_by_pdevid(soc, mac_addr,
|
||||||
pdev->pdev_id);
|
pdev->pdev_id);
|
||||||
if (ast_entry) {
|
if (ast_entry) {
|
||||||
if ((type == CDP_TXRX_AST_TYPE_MEC) &&
|
|
||||||
(ast_entry->type == CDP_TXRX_AST_TYPE_MEC))
|
|
||||||
ast_entry->is_active = TRUE;
|
|
||||||
|
|
||||||
qdf_spin_unlock_bh(&soc->ast_lock);
|
qdf_spin_unlock_bh(&soc->ast_lock);
|
||||||
return QDF_STATUS_E_ALREADY;
|
return QDF_STATUS_E_ALREADY;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_peer_found) {
|
if (is_peer_found) {
|
||||||
/* During WDS to static roaming, peer is added
|
/* During WDS to static roaming, peer is added
|
||||||
* to the list before static AST entry create.
|
* to the list before static AST entry create.
|
||||||
@@ -939,10 +1150,6 @@ QDF_STATUS dp_peer_add_ast(struct dp_soc *soc,
|
|||||||
ast_entry = dp_peer_ast_hash_find_soc(soc, mac_addr);
|
ast_entry = dp_peer_ast_hash_find_soc(soc, mac_addr);
|
||||||
|
|
||||||
if (ast_entry) {
|
if (ast_entry) {
|
||||||
if ((type == CDP_TXRX_AST_TYPE_MEC) &&
|
|
||||||
(ast_entry->type == CDP_TXRX_AST_TYPE_MEC))
|
|
||||||
ast_entry->is_active = TRUE;
|
|
||||||
|
|
||||||
if ((ast_entry->type == CDP_TXRX_AST_TYPE_WDS_HM) &&
|
if ((ast_entry->type == CDP_TXRX_AST_TYPE_WDS_HM) &&
|
||||||
!ast_entry->delete_in_progress) {
|
!ast_entry->delete_in_progress) {
|
||||||
qdf_spin_unlock_bh(&soc->ast_lock);
|
qdf_spin_unlock_bh(&soc->ast_lock);
|
||||||
@@ -1006,22 +1213,6 @@ QDF_STATUS dp_peer_add_ast(struct dp_soc *soc,
|
|||||||
return QDF_STATUS_E_AGAIN;
|
return QDF_STATUS_E_AGAIN;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Modify an already existing AST entry from type
|
|
||||||
* WDS to MEC on promption. This serves as a fix when
|
|
||||||
* backbone of interfaces are interchanged wherein
|
|
||||||
* wds entr becomes its own MEC. The entry should be
|
|
||||||
* replaced only when the ast_entry peer matches the
|
|
||||||
* peer received in mec event. This additional check
|
|
||||||
* is needed in wds repeater cases where a multicast
|
|
||||||
* packet from station to the root via the repeater
|
|
||||||
* should not remove the wds entry.
|
|
||||||
*/
|
|
||||||
if ((ast_entry->type == CDP_TXRX_AST_TYPE_WDS) &&
|
|
||||||
(type == CDP_TXRX_AST_TYPE_MEC) &&
|
|
||||||
(ast_entry->peer_id == peer->peer_id)) {
|
|
||||||
ast_entry->is_active = FALSE;
|
|
||||||
dp_peer_del_ast(soc, ast_entry);
|
|
||||||
}
|
|
||||||
qdf_spin_unlock_bh(&soc->ast_lock);
|
qdf_spin_unlock_bh(&soc->ast_lock);
|
||||||
return QDF_STATUS_E_ALREADY;
|
return QDF_STATUS_E_ALREADY;
|
||||||
}
|
}
|
||||||
@@ -1072,10 +1263,6 @@ add_ast_entry:
|
|||||||
TAILQ_INSERT_TAIL(&peer->ast_entry_list, ast_entry,
|
TAILQ_INSERT_TAIL(&peer->ast_entry_list, ast_entry,
|
||||||
ase_list_elem);
|
ase_list_elem);
|
||||||
break;
|
break;
|
||||||
case CDP_TXRX_AST_TYPE_MEC:
|
|
||||||
ast_entry->next_hop = 1;
|
|
||||||
ast_entry->type = CDP_TXRX_AST_TYPE_MEC;
|
|
||||||
break;
|
|
||||||
case CDP_TXRX_AST_TYPE_DA:
|
case CDP_TXRX_AST_TYPE_DA:
|
||||||
vap_bss_peer = dp_vdev_bss_peer_ref_n_get(soc, vdev,
|
vap_bss_peer = dp_vdev_bss_peer_ref_n_get(soc, vdev,
|
||||||
DP_MOD_ID_AST);
|
DP_MOD_ID_AST);
|
||||||
@@ -1097,10 +1284,8 @@ 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);
|
||||||
|
|
||||||
if (type == CDP_TXRX_AST_TYPE_MEC)
|
qdf_copy_macaddr((struct qdf_mac_addr *)next_node_mac,
|
||||||
qdf_mem_copy(next_node_mac, peer->vdev->mac_addr.raw, 6);
|
(struct qdf_mac_addr *)peer->mac_addr.raw);
|
||||||
else
|
|
||||||
qdf_mem_copy(next_node_mac, peer->mac_addr.raw, 6);
|
|
||||||
|
|
||||||
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) &&
|
||||||
@@ -1431,9 +1616,9 @@ struct dp_ast_entry *dp_peer_ast_hash_find_by_pdevid(struct dp_soc *soc,
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int dp_peer_ast_hash_attach(struct dp_soc *soc)
|
static QDF_STATUS dp_peer_ast_hash_attach(struct dp_soc *soc)
|
||||||
{
|
{
|
||||||
return 0;
|
return QDF_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline QDF_STATUS dp_peer_map_ast(struct dp_soc *soc,
|
static inline QDF_STATUS dp_peer_map_ast(struct dp_soc *soc,
|
||||||
@@ -1816,31 +2001,41 @@ static void dp_peer_find_map_detach(struct dp_soc *soc)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int dp_peer_find_attach(struct dp_soc *soc)
|
QDF_STATUS dp_peer_find_attach(struct dp_soc *soc)
|
||||||
{
|
{
|
||||||
if (dp_peer_find_map_attach(soc))
|
QDF_STATUS status;
|
||||||
return 1;
|
|
||||||
|
|
||||||
if (dp_peer_find_hash_attach(soc)) {
|
status = dp_peer_find_map_attach(soc);
|
||||||
dp_peer_find_map_detach(soc);
|
if (!QDF_IS_STATUS_SUCCESS(status))
|
||||||
return 1;
|
return status;
|
||||||
|
|
||||||
|
status = dp_peer_find_hash_attach(soc);
|
||||||
|
if (!QDF_IS_STATUS_SUCCESS(status))
|
||||||
|
goto map_detach;
|
||||||
|
|
||||||
|
status = dp_peer_ast_table_attach(soc);
|
||||||
|
if (!QDF_IS_STATUS_SUCCESS(status))
|
||||||
|
goto hash_detach;
|
||||||
|
|
||||||
|
status = dp_peer_ast_hash_attach(soc);
|
||||||
|
if (!QDF_IS_STATUS_SUCCESS(status))
|
||||||
|
goto ast_table_detach;
|
||||||
|
|
||||||
|
status = dp_peer_mec_hash_attach(soc);
|
||||||
|
if (QDF_IS_STATUS_SUCCESS(status)) {
|
||||||
|
dp_soc_wds_attach(soc);
|
||||||
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dp_peer_ast_table_attach(soc)) {
|
dp_peer_ast_hash_detach(soc);
|
||||||
dp_peer_find_hash_detach(soc);
|
ast_table_detach:
|
||||||
dp_peer_find_map_detach(soc);
|
dp_peer_ast_table_detach(soc);
|
||||||
return 1;
|
hash_detach:
|
||||||
}
|
dp_peer_find_hash_detach(soc);
|
||||||
|
map_detach:
|
||||||
|
dp_peer_find_map_detach(soc);
|
||||||
|
|
||||||
if (dp_peer_ast_hash_attach(soc)) {
|
return status;
|
||||||
dp_peer_ast_table_detach(soc);
|
|
||||||
dp_peer_find_hash_detach(soc);
|
|
||||||
dp_peer_find_map_detach(soc);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
dp_soc_wds_attach(soc);
|
|
||||||
return 0; /* success */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void dp_rx_tid_stats_cb(struct dp_soc *soc, void *cb_ctxt,
|
void dp_rx_tid_stats_cb(struct dp_soc *soc, void *cb_ctxt,
|
||||||
@@ -2180,6 +2375,7 @@ dp_peer_find_detach(struct dp_soc *soc)
|
|||||||
dp_peer_find_hash_detach(soc);
|
dp_peer_find_hash_detach(soc);
|
||||||
dp_peer_ast_hash_detach(soc);
|
dp_peer_ast_hash_detach(soc);
|
||||||
dp_peer_ast_table_detach(soc);
|
dp_peer_ast_table_detach(soc);
|
||||||
|
dp_peer_mec_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,
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2016-2020 The Linux Foundation. All rights reserved.
|
* Copyright (c) 2016-2021 The Linux Foundation. All rights reserved.
|
||||||
*
|
*
|
||||||
* Permission to use, copy, modify, and/or distribute this software for
|
* Permission to use, copy, modify, and/or distribute this software for
|
||||||
* any purpose with or without fee is hereby granted, provided that the
|
* any purpose with or without fee is hereby granted, provided that the
|
||||||
@@ -24,6 +24,9 @@
|
|||||||
|
|
||||||
#define DP_INVALID_PEER_ID 0xffff
|
#define DP_INVALID_PEER_ID 0xffff
|
||||||
|
|
||||||
|
#define DP_PEER_MAX_MEC_IDX 1024 /* maximum index for MEC table */
|
||||||
|
#define DP_PEER_MAX_MEC_ENTRY 4096 /* maximum MEC entries in MEC table */
|
||||||
|
|
||||||
#define DP_FW_PEER_STATS_CMP_TIMEOUT_MSEC 5000
|
#define DP_FW_PEER_STATS_CMP_TIMEOUT_MSEC 5000
|
||||||
|
|
||||||
#define dp_peer_alert(params...) QDF_TRACE_FATAL(QDF_MODULE_ID_DP_PEER, params)
|
#define dp_peer_alert(params...) QDF_TRACE_FATAL(QDF_MODULE_ID_DP_PEER, params)
|
||||||
@@ -601,6 +604,59 @@ 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);
|
struct dp_peer *peer);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* dp_peer_mec_detach_entry() - Detach the MEC entry
|
||||||
|
* @soc: SoC handle
|
||||||
|
* @mecentry: MEC entry of the node
|
||||||
|
* @ptr: pointer to free list
|
||||||
|
*
|
||||||
|
* The MEC entry is detached from MEC table and added to free_list
|
||||||
|
* to free the object outside lock
|
||||||
|
*
|
||||||
|
* Return: None
|
||||||
|
*/
|
||||||
|
void dp_peer_mec_detach_entry(struct dp_soc *soc, struct dp_mec_entry *mecentry,
|
||||||
|
void *ptr);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* dp_peer_mec_free_list() - free the MEC entry from free_list
|
||||||
|
* @soc: SoC handle
|
||||||
|
* @ptr: pointer to free list
|
||||||
|
*
|
||||||
|
* Return: None
|
||||||
|
*/
|
||||||
|
void dp_peer_mec_free_list(struct dp_soc *soc, void *ptr);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* dp_peer_mec_add_entry()
|
||||||
|
* @soc: SoC handle
|
||||||
|
* @vdev: vdev to which mec node belongs
|
||||||
|
* @mac_addr: MAC address of mec node
|
||||||
|
*
|
||||||
|
* This function allocates and adds MEC entry to MEC table.
|
||||||
|
* It assumes caller has taken the mec lock to protect the access to these
|
||||||
|
* tables
|
||||||
|
*
|
||||||
|
* Return: QDF_STATUS
|
||||||
|
*/
|
||||||
|
QDF_STATUS dp_peer_mec_add_entry(struct dp_soc *soc,
|
||||||
|
struct dp_vdev *vdev,
|
||||||
|
uint8_t *mac_addr);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* dp_peer_mec_hash_find_by_pdevid() - Find MEC entry by MAC address
|
||||||
|
* within pdev
|
||||||
|
* @soc: SoC handle
|
||||||
|
*
|
||||||
|
* It assumes caller has taken the mec_lock to protect the access to
|
||||||
|
* MEC hash table
|
||||||
|
*
|
||||||
|
* Return: MEC entry
|
||||||
|
*/
|
||||||
|
struct dp_mec_entry *dp_peer_mec_hash_find_by_pdevid(struct dp_soc *soc,
|
||||||
|
uint8_t pdev_id,
|
||||||
|
uint8_t *mec_mac_addr);
|
||||||
|
|
||||||
#define DP_AST_ASSERT(_condition) \
|
#define DP_AST_ASSERT(_condition) \
|
||||||
do { \
|
do { \
|
||||||
if (!(_condition)) { \
|
if (!(_condition)) { \
|
||||||
@@ -850,4 +906,42 @@ static inline void dp_peer_delete_ast_entries(struct dp_soc *soc,
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef FEATURE_MEC
|
||||||
|
/**
|
||||||
|
* dp_peer_mec_spinlock_create() - Create the MEC spinlock
|
||||||
|
* @soc: SoC handle
|
||||||
|
*
|
||||||
|
* Return: none
|
||||||
|
*/
|
||||||
|
void dp_peer_mec_spinlock_create(struct dp_soc *soc);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* dp_peer_mec_spinlock_destroy() - Destroy the MEC spinlock
|
||||||
|
* @soc: SoC handle
|
||||||
|
*
|
||||||
|
* Return: none
|
||||||
|
*/
|
||||||
|
void dp_peer_mec_spinlock_destroy(struct dp_soc *soc);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* dp_peer_mec_flush_entries() - Delete all mec entries in table
|
||||||
|
* @soc: Datapath SOC
|
||||||
|
*
|
||||||
|
* Return: None
|
||||||
|
*/
|
||||||
|
void dp_peer_mec_flush_entries(struct dp_soc *soc);
|
||||||
|
#else
|
||||||
|
static inline void dp_peer_mec_spinlock_create(struct dp_soc *soc)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void dp_peer_mec_spinlock_destroy(struct dp_soc *soc)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void dp_peer_mec_flush_entries(struct dp_soc *soc)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
#endif
|
||||||
#endif /* _DP_PEER_H_ */
|
#endif /* _DP_PEER_H_ */
|
||||||
|
@@ -45,6 +45,7 @@
|
|||||||
/* Max buffer in invalid peer SG list*/
|
/* Max buffer in invalid peer SG list*/
|
||||||
#define DP_MAX_INVALID_BUFFERS 10
|
#define DP_MAX_INVALID_BUFFERS 10
|
||||||
|
|
||||||
|
#ifdef FEATURE_MEC
|
||||||
/**
|
/**
|
||||||
* dp_rx_mcast_echo_check() - check if the mcast pkt is a loop
|
* dp_rx_mcast_echo_check() - check if the mcast pkt is a loop
|
||||||
* back on same vap or a different vap.
|
* back on same vap or a different vap.
|
||||||
@@ -58,13 +59,13 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
static inline bool dp_rx_mcast_echo_check(struct dp_soc *soc,
|
static inline bool dp_rx_mcast_echo_check(struct dp_soc *soc,
|
||||||
struct dp_peer *peer,
|
struct dp_peer *peer,
|
||||||
uint8_t *rx_tlv_hdr,
|
uint8_t *rx_tlv_hdr,
|
||||||
qdf_nbuf_t nbuf)
|
qdf_nbuf_t nbuf)
|
||||||
{
|
{
|
||||||
struct dp_vdev *vdev = peer->vdev;
|
struct dp_vdev *vdev = peer->vdev;
|
||||||
struct dp_ast_entry *ase = NULL;
|
struct dp_pdev *pdev = vdev->pdev;
|
||||||
uint16_t sa_idx = 0;
|
struct dp_mec_entry *mecentry = NULL;
|
||||||
uint8_t *data;
|
uint8_t *data;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -102,67 +103,30 @@ static inline bool dp_rx_mcast_echo_check(struct dp_soc *soc,
|
|||||||
* wireless STAs MAC addr which are behind the Repeater,
|
* wireless STAs MAC addr which are behind the Repeater,
|
||||||
* then drop the pkt as it is looped back
|
* then drop the pkt as it is looped back
|
||||||
*/
|
*/
|
||||||
qdf_spin_lock_bh(&soc->ast_lock);
|
qdf_spin_lock_bh(&soc->mec_lock);
|
||||||
if (hal_rx_msdu_end_sa_is_valid_get(soc->hal_soc, rx_tlv_hdr)) {
|
|
||||||
sa_idx = hal_rx_msdu_end_sa_idx_get(soc->hal_soc, rx_tlv_hdr);
|
|
||||||
|
|
||||||
if ((sa_idx < 0) ||
|
mecentry = dp_peer_mec_hash_find_by_pdevid(soc, pdev->pdev_id,
|
||||||
(sa_idx >= wlan_cfg_get_max_ast_idx(soc->wlan_cfg_ctx))) {
|
&data[QDF_MAC_ADDR_SIZE]);
|
||||||
qdf_spin_unlock_bh(&soc->ast_lock);
|
if (!mecentry) {
|
||||||
QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
|
qdf_spin_unlock_bh(&soc->mec_lock);
|
||||||
"invalid sa_idx: %d", sa_idx);
|
return false;
|
||||||
qdf_assert_always(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
ase = soc->ast_table[sa_idx];
|
|
||||||
if (!ase) {
|
|
||||||
/* We do not get a peer map event for STA and without
|
|
||||||
* this event we don't know what is STA's sa_idx.
|
|
||||||
* For this reason the AST is still not associated to
|
|
||||||
* any index postion in ast_table.
|
|
||||||
* In these kind of scenarios where sa is valid but
|
|
||||||
* ast is not in ast_table, we use the below API to get
|
|
||||||
* AST entry for STA's own mac_address.
|
|
||||||
*/
|
|
||||||
ase = dp_peer_ast_hash_find_by_vdevid
|
|
||||||
(soc, &data[QDF_MAC_ADDR_SIZE],
|
|
||||||
peer->vdev->vdev_id);
|
|
||||||
if (ase) {
|
|
||||||
ase->ast_idx = sa_idx;
|
|
||||||
soc->ast_table[sa_idx] = ase;
|
|
||||||
ase->is_mapped = TRUE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
ase = dp_peer_ast_hash_find_by_pdevid(soc,
|
|
||||||
&data[QDF_MAC_ADDR_SIZE],
|
|
||||||
vdev->pdev->pdev_id);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ase) {
|
qdf_spin_unlock_bh(&soc->mec_lock);
|
||||||
|
|
||||||
if (ase->pdev_id != vdev->pdev->pdev_id) {
|
dp_rx_err_info("%pK: received pkt with same src mac " QDF_MAC_ADDR_FMT,
|
||||||
qdf_spin_unlock_bh(&soc->ast_lock);
|
soc, QDF_MAC_ADDR_REF(&data[QDF_MAC_ADDR_SIZE]));
|
||||||
dp_rx_err_info("%pK: Detected DBDC Root AP "QDF_MAC_ADDR_FMT", %d %d",
|
return true;
|
||||||
soc, QDF_MAC_ADDR_REF(&data[QDF_MAC_ADDR_SIZE]),
|
}
|
||||||
vdev->pdev->pdev_id,
|
#else
|
||||||
ase->pdev_id);
|
static inline bool dp_rx_mcast_echo_check(struct dp_soc *soc,
|
||||||
return false;
|
struct dp_peer *peer,
|
||||||
}
|
uint8_t *rx_tlv_hdr,
|
||||||
|
qdf_nbuf_t nbuf)
|
||||||
if ((ase->type == CDP_TXRX_AST_TYPE_MEC) ||
|
{
|
||||||
(ase->peer_id != peer->peer_id)) {
|
|
||||||
qdf_spin_unlock_bh(&soc->ast_lock);
|
|
||||||
dp_rx_err_info("%pK: received pkt with same src mac "QDF_MAC_ADDR_FMT,
|
|
||||||
soc, QDF_MAC_ADDR_REF(&data[QDF_MAC_ADDR_SIZE]));
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
qdf_spin_unlock_bh(&soc->ast_lock);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
#endif /* QCA_HOST_MODE_WIFI_DISABLED */
|
#endif /* QCA_HOST_MODE_WIFI_DISABLED */
|
||||||
|
|
||||||
void dp_rx_link_desc_refill_duplicate_check(
|
void dp_rx_link_desc_refill_duplicate_check(
|
||||||
|
@@ -851,6 +851,11 @@ struct dp_soc_stats {
|
|||||||
uint32_t ast_mismatch;
|
uint32_t ast_mismatch;
|
||||||
} ast;
|
} ast;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
uint32_t added;
|
||||||
|
uint32_t deleted;
|
||||||
|
} mec;
|
||||||
|
|
||||||
/* SOC level TX stats */
|
/* SOC level TX stats */
|
||||||
struct {
|
struct {
|
||||||
/* Total packets transmitted */
|
/* Total packets transmitted */
|
||||||
@@ -1085,6 +1090,25 @@ struct dp_ast_entry {
|
|||||||
TAILQ_ENTRY(dp_ast_entry) hash_list_elem;
|
TAILQ_ENTRY(dp_ast_entry) hash_list_elem;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* dp_mec_entry
|
||||||
|
*
|
||||||
|
* @mac_addr: MAC Address for this MEC entry
|
||||||
|
* @is_active: flag to indicate active data traffic on this node
|
||||||
|
* (used for aging out/expiry)
|
||||||
|
* @pdev_id: pdev ID
|
||||||
|
* @vdev_id: vdev ID
|
||||||
|
* @hash_list_elem: node in soc MEC hash list (mac address used as hash)
|
||||||
|
*/
|
||||||
|
struct dp_mec_entry {
|
||||||
|
union dp_align_mac_addr mac_addr;
|
||||||
|
bool is_active;
|
||||||
|
uint8_t pdev_id;
|
||||||
|
uint8_t vdev_id;
|
||||||
|
|
||||||
|
TAILQ_ENTRY(dp_mec_entry) hash_list_elem;
|
||||||
|
};
|
||||||
|
|
||||||
/* SOC level htt stats */
|
/* SOC level htt stats */
|
||||||
struct htt_t2h_stats {
|
struct htt_t2h_stats {
|
||||||
/* lock to protect htt_stats_msg update */
|
/* lock to protect htt_stats_msg update */
|
||||||
@@ -1545,7 +1569,6 @@ struct dp_soc {
|
|||||||
unsigned idx_bits;
|
unsigned idx_bits;
|
||||||
TAILQ_HEAD(, dp_ast_entry) * bins;
|
TAILQ_HEAD(, dp_ast_entry) * bins;
|
||||||
} ast_hash;
|
} ast_hash;
|
||||||
|
|
||||||
struct dp_rx_history *rx_ring_history[MAX_REO_DEST_RINGS];
|
struct dp_rx_history *rx_ring_history[MAX_REO_DEST_RINGS];
|
||||||
struct dp_rx_err_history *rx_err_ring_history;
|
struct dp_rx_err_history *rx_err_ring_history;
|
||||||
struct dp_rx_reinject_history *rx_reinject_ring_history;
|
struct dp_rx_reinject_history *rx_reinject_ring_history;
|
||||||
@@ -1725,6 +1748,21 @@ struct dp_soc {
|
|||||||
#endif
|
#endif
|
||||||
/* Invalid buffer that allocated for RX buffer */
|
/* Invalid buffer that allocated for RX buffer */
|
||||||
qdf_nbuf_queue_t invalid_buf_queue;
|
qdf_nbuf_queue_t invalid_buf_queue;
|
||||||
|
|
||||||
|
#ifdef FEATURE_MEC
|
||||||
|
/** @mec_lock: spinlock for MEC table */
|
||||||
|
qdf_spinlock_t mec_lock;
|
||||||
|
/** @mec_cnt: number of active mec entries */
|
||||||
|
qdf_atomic_t mec_cnt;
|
||||||
|
struct {
|
||||||
|
/** @mask: mask bits */
|
||||||
|
uint32_t mask;
|
||||||
|
/** @idx_bits: index to shift bits */
|
||||||
|
uint32_t idx_bits;
|
||||||
|
/** @bins: MEC table */
|
||||||
|
TAILQ_HEAD(, dp_mec_entry) * bins;
|
||||||
|
} mec_hash;
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef IPA_OFFLOAD
|
#ifdef IPA_OFFLOAD
|
||||||
|
Reference in New Issue
Block a user