qcacmn: AST based MEC support for HAWKEYE
Implemented MEC support using AST entries rather than using a separate MEC table. Change-Id: Ifaafb4be1f8a981ad28609ea9740e8bbccec9046
This commit is contained in:

committed by
snandini

parent
6c7625b2ca
commit
fb72b637f7
@@ -52,7 +52,7 @@ cdp_dump_flow_pool_info(struct cdp_soc_t *soc)
|
||||
#include "dp_ipa.h"
|
||||
|
||||
#define DP_INTR_POLL_TIMER_MS 10
|
||||
#define DP_WDS_AGING_TIMER_DEFAULT_MS 6000
|
||||
#define DP_WDS_AGING_TIMER_DEFAULT_MS 120000
|
||||
#define DP_MCS_LENGTH (6*MAX_MCS)
|
||||
#define DP_NSS_LENGTH (6*SS_COUNT)
|
||||
#define DP_RXDMA_ERR_LENGTH (6*HAL_RXDMA_ERR_MAX)
|
||||
@@ -2839,12 +2839,13 @@ static void *dp_peer_create_wifi3(struct cdp_vdev *vdev_handle,
|
||||
|
||||
TAILQ_INIT(&peer->ast_entry_list);
|
||||
|
||||
/* store provided params */
|
||||
peer->vdev = vdev;
|
||||
|
||||
dp_peer_add_ast(soc, peer, peer_mac_addr, 1);
|
||||
|
||||
qdf_spinlock_create(&peer->peer_info_lock);
|
||||
|
||||
/* store provided params */
|
||||
peer->vdev = vdev;
|
||||
qdf_mem_copy(
|
||||
&peer->mac_addr.raw[0], peer_mac_addr, OL_TXRX_MAC_ADDR_LEN);
|
||||
|
||||
|
@@ -403,7 +403,7 @@ static inline void dp_peer_map_ast(struct dp_soc *soc,
|
||||
* 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)
|
||||
uint8_t *mac_addr, uint8_t is_self)
|
||||
{
|
||||
struct dp_ast_entry *ast_entry;
|
||||
|
||||
@@ -434,12 +434,23 @@ int dp_peer_add_ast(struct dp_soc *soc, struct dp_peer *peer,
|
||||
qdf_mem_copy(&ast_entry->mac_addr.raw[0], mac_addr, DP_MAC_ADDR_LEN);
|
||||
ast_entry->peer = peer;
|
||||
|
||||
if (is_self) {
|
||||
switch (is_self) {
|
||||
case 1:
|
||||
peer->self_ast_entry = ast_entry;
|
||||
ast_entry->is_static = TRUE;
|
||||
} else {
|
||||
break;
|
||||
case 0:
|
||||
ast_entry->next_hop = 1;
|
||||
ast_entry->is_static = FALSE;
|
||||
break;
|
||||
case 2:
|
||||
ast_entry->is_mec = 1;
|
||||
ast_entry->next_hop = 1;
|
||||
ast_entry->is_static = FALSE;
|
||||
break;
|
||||
default:
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
|
||||
FL("Incorrect AST entry type"));
|
||||
}
|
||||
|
||||
ast_entry->is_active = TRUE;
|
||||
@@ -757,10 +768,10 @@ dp_rx_peer_map_handler(void *soc_handle, uint16_t peer_id, uint16_t hw_peer_id,
|
||||
|
||||
peer = soc->peer_id_to_obj_map[peer_id];
|
||||
|
||||
if ((hw_peer_id < 0) || (hw_peer_id > WLAN_UMAC_PSOC_MAX_PEERS)) {
|
||||
if ((hw_peer_id < 0) || (hw_peer_id > (WLAN_UMAC_PSOC_MAX_PEERS * 2))) {
|
||||
QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
|
||||
"invalid hw_peer_id: %d", hw_peer_id);
|
||||
QDF_ASSERT(0);
|
||||
qdf_assert_always(0);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@@ -54,14 +54,17 @@ 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,
|
||||
uint16_t peer_id, uint8_t *peer_mac);
|
||||
|
||||
struct dp_ast_entry *dp_peer_ast_hash_find(struct dp_soc *soc,
|
||||
uint8_t *ast_mac_addr, int mac_addr_is_aligned);
|
||||
|
||||
#ifdef FEATURE_WDS
|
||||
int dp_peer_add_ast(struct dp_soc *soc, struct dp_peer *peer,
|
||||
uint8_t *mac_addr, bool is_self);
|
||||
uint8_t *mac_addr, uint8_t 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)
|
||||
uint8_t *mac_addr, uint8_t is_self)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
@@ -365,7 +365,6 @@ dp_rx_intrabss_fwd(struct dp_soc *soc,
|
||||
if (da_peer->vdev == sa_peer->vdev && !da_peer->bss_peer) {
|
||||
memset(nbuf->cb, 0x0, sizeof(nbuf->cb));
|
||||
len = qdf_nbuf_len(nbuf);
|
||||
qdf_nbuf_set_ftype(nbuf, CB_FTYPE_INTRABSS_FWD);
|
||||
|
||||
if (!dp_tx_send(sa_peer->vdev, nbuf)) {
|
||||
DP_STATS_INC_PKT(sa_peer, rx.intra_bss.pkts,
|
||||
@@ -393,7 +392,6 @@ dp_rx_intrabss_fwd(struct dp_soc *soc,
|
||||
return false;
|
||||
memset(nbuf_copy->cb, 0x0, sizeof(nbuf_copy->cb));
|
||||
len = qdf_nbuf_len(nbuf_copy);
|
||||
qdf_nbuf_set_ftype(nbuf_copy, CB_FTYPE_INTRABSS_FWD);
|
||||
|
||||
if (dp_tx_send(sa_peer->vdev, nbuf_copy)) {
|
||||
DP_STATS_INC_PKT(sa_peer, rx.intra_bss.fail, 1, len);
|
||||
@@ -1277,7 +1275,6 @@ done:
|
||||
htt_cmn_pkt_type_ethernet) &&
|
||||
(qdf_likely(!vdev->mesh_vdev))) {
|
||||
/* WDS Source Port Learning */
|
||||
if (qdf_likely(vdev->wds_enabled))
|
||||
dp_rx_wds_srcport_learn(soc,
|
||||
rx_tlv_hdr,
|
||||
peer,
|
||||
|
@@ -274,9 +274,6 @@ dp_rx_null_q_desc_handle(struct dp_soc *soc, struct dp_rx_desc *rx_desc,
|
||||
uint16_t peer_id = 0xFFFF;
|
||||
struct dp_peer *peer = NULL;
|
||||
uint32_t sgi, rate_mcs, tid;
|
||||
uint8_t count;
|
||||
struct mect_entry *mect_entry;
|
||||
uint8_t *nbuf_data = NULL;
|
||||
|
||||
rx_bufs_used++;
|
||||
|
||||
@@ -352,26 +349,39 @@ dp_rx_null_q_desc_handle(struct dp_soc *soc, struct dp_rx_desc *rx_desc,
|
||||
*/
|
||||
qdf_nbuf_pull_head(nbuf, (l2_hdr_offset + RX_PKT_TLVS_LEN));
|
||||
|
||||
/*
|
||||
* This is a Multicast echo check, drop the pkt if we meet
|
||||
* the Multicast Echo Check condition
|
||||
*/
|
||||
if (hal_rx_msdu_end_sa_is_valid_get(rx_desc->rx_buf_start)) {
|
||||
struct dp_ast_entry *ase;
|
||||
uint16_t sa_idx;
|
||||
uint8_t *nbuf_data = NULL;
|
||||
|
||||
nbuf_data = qdf_nbuf_data(nbuf);
|
||||
for (count = 0; count < soc->mect_cnt; count++) {
|
||||
mect_entry = &soc->mect_table[count];
|
||||
mect_entry->ts = jiffies_64;
|
||||
if (!(memcmp(mect_entry->mac_addr, &nbuf_data[DP_MAC_ADDR_LEN],
|
||||
DP_MAC_ADDR_LEN))) {
|
||||
sa_idx = hal_rx_msdu_end_sa_idx_get(rx_desc->rx_buf_start);
|
||||
if ((sa_idx < 0) || (sa_idx > (WLAN_UMAC_PSOC_MAX_PEERS * 2))) {
|
||||
QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
|
||||
"invalid sa_idx: %d", sa_idx);
|
||||
qdf_assert_always(0);
|
||||
}
|
||||
|
||||
ase = soc->ast_table[sa_idx];
|
||||
if (ase) {
|
||||
if (ase->is_mec || (ase->peer != peer)) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP,
|
||||
QDF_TRACE_LEVEL_INFO,
|
||||
FL("received pkt with same src MAC"));
|
||||
"received pkt with same src mac %pM",
|
||||
&nbuf_data[DP_MAC_ADDR_LEN]);
|
||||
|
||||
/* Drop & free packet */
|
||||
qdf_nbuf_free(nbuf);
|
||||
/* Statistics */
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* WDS Source Port Learning */
|
||||
if (qdf_likely(vdev->rx_decap_type == htt_cmn_pkt_type_ethernet) &&
|
||||
(vdev->wds_enabled))
|
||||
if (qdf_likely(vdev->rx_decap_type == htt_cmn_pkt_type_ethernet))
|
||||
dp_rx_wds_srcport_learn(soc, rx_desc->rx_buf_start, peer, nbuf);
|
||||
|
||||
if (hal_rx_mpdu_start_mpdu_qos_control_valid_get(
|
||||
|
@@ -1378,53 +1378,11 @@ qdf_nbuf_t dp_tx_send(void *vap_dev, qdf_nbuf_t nbuf)
|
||||
struct dp_tx_msdu_info_s msdu_info;
|
||||
struct dp_tx_seg_info_s seg_info;
|
||||
struct dp_vdev *vdev = (struct dp_vdev *) vap_dev;
|
||||
struct dp_soc *soc = vdev->pdev->soc;
|
||||
uint16_t peer_id = HTT_INVALID_PEER;
|
||||
uint8_t count;
|
||||
uint8_t found = 0;
|
||||
uint8_t oldest_mec_entry_idx = 0;
|
||||
uint64_t oldest_mec_ts = 0;
|
||||
struct mect_entry *mect_entry;
|
||||
|
||||
qdf_mem_set(&msdu_info, sizeof(msdu_info), 0x0);
|
||||
qdf_mem_set(&seg_info, sizeof(seg_info), 0x0);
|
||||
|
||||
if (qdf_nbuf_get_ftype(nbuf) == CB_FTYPE_INTRABSS_FWD)
|
||||
goto out;
|
||||
|
||||
eh = (struct ether_header *)qdf_nbuf_data(nbuf);
|
||||
if (DP_FRAME_IS_MULTICAST((eh)->ether_dhost)) {
|
||||
for (count = 0; count < soc->mect_cnt; count++) {
|
||||
mect_entry = &soc->mect_table[count];
|
||||
if (!memcmp(mect_entry->mac_addr, eh->ether_shost,
|
||||
DP_MAC_ADDR_LEN)) {
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!oldest_mec_ts) {
|
||||
oldest_mec_entry_idx = count;
|
||||
oldest_mec_ts = mect_entry->ts;
|
||||
} else if (mect_entry->ts < oldest_mec_ts) {
|
||||
oldest_mec_entry_idx = count;
|
||||
oldest_mec_ts = mect_entry->ts;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
if (count >= DP_MAX_MECT_ENTRIES)
|
||||
count = oldest_mec_entry_idx;
|
||||
else
|
||||
soc->mect_cnt++;
|
||||
|
||||
mect_entry = &soc->mect_table[count];
|
||||
mect_entry->ts = jiffies_64;
|
||||
memcpy(mect_entry->mac_addr, eh->ether_shost,
|
||||
DP_MAC_ADDR_LEN);
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
|
||||
"%s , skb %0x:%0x:%0x:%0x:%0x:%0x\n",
|
||||
__func__, nbuf->data[0], nbuf->data[1], nbuf->data[2],
|
||||
@@ -1716,6 +1674,57 @@ static inline void dp_tx_comp_free_buf(struct dp_soc *soc,
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* dp_tx_mec_handler() - Tx MEC Notify Handler
|
||||
* @vdev: pointer to dp dev handler
|
||||
* @status : Tx completion status from HTT descriptor
|
||||
*
|
||||
* Handles MEC notify event sent from fw to Host
|
||||
*
|
||||
* Return: none
|
||||
*/
|
||||
#ifdef FEATURE_WDS
|
||||
static void dp_tx_mec_handler(struct dp_vdev *vdev, uint8_t *status)
|
||||
{
|
||||
|
||||
struct dp_soc *soc;
|
||||
uint32_t flags = IEEE80211_NODE_F_WDS_HM;
|
||||
struct dp_peer *peer;
|
||||
uint8_t mac_addr[DP_MAC_ADDR_LEN], i;
|
||||
|
||||
soc = vdev->pdev->soc;
|
||||
qdf_spin_lock_bh(&soc->peer_ref_mutex);
|
||||
peer = TAILQ_FIRST(&vdev->peer_list);
|
||||
qdf_spin_unlock_bh(&soc->peer_ref_mutex);
|
||||
|
||||
if (!peer) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_INFO,
|
||||
FL("peer is NULL"));
|
||||
return;
|
||||
}
|
||||
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_INFO,
|
||||
"%s Tx MEC Handler\n",
|
||||
__func__);
|
||||
|
||||
for (i = 0; i < DP_MAC_ADDR_LEN; i++)
|
||||
mac_addr[(DP_MAC_ADDR_LEN - 1) - i] =
|
||||
status[(DP_MAC_ADDR_LEN - 2) + i];
|
||||
|
||||
if (!dp_peer_add_ast(soc, peer, mac_addr, 2)) {
|
||||
soc->cdp_soc.ol_ops->peer_add_wds_entry(
|
||||
vdev->pdev->osif_pdev,
|
||||
mac_addr,
|
||||
vdev->mac_addr.raw,
|
||||
flags);
|
||||
}
|
||||
}
|
||||
#else
|
||||
static void dp_tx_mec_handler(struct dp_vdev *vdev, uint8_t *status)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* dp_tx_process_htt_completion() - Tx HTT Completion Indication Handler
|
||||
* @tx_desc: software descriptor head pointer
|
||||
@@ -1730,12 +1739,14 @@ void dp_tx_process_htt_completion(struct dp_tx_desc_s *tx_desc, uint8_t *status)
|
||||
{
|
||||
uint8_t tx_status;
|
||||
struct dp_pdev *pdev;
|
||||
struct dp_vdev *vdev;
|
||||
struct dp_soc *soc;
|
||||
uint32_t *htt_status_word = (uint32_t *) status;
|
||||
|
||||
qdf_assert(tx_desc->pdev);
|
||||
|
||||
pdev = tx_desc->pdev;
|
||||
vdev = tx_desc->vdev;
|
||||
soc = pdev->soc;
|
||||
|
||||
tx_status = HTT_TX_WBM_COMPLETION_V2_TX_STATUS_GET(htt_status_word[0]);
|
||||
@@ -1759,6 +1770,11 @@ void dp_tx_process_htt_completion(struct dp_tx_desc_s *tx_desc, uint8_t *status)
|
||||
dp_tx_inspect_handler(tx_desc, status);
|
||||
break;
|
||||
}
|
||||
case HTT_TX_FW2WBM_TX_STATUS_MEC_NOTIFY:
|
||||
{
|
||||
dp_tx_mec_handler(vdev, status);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
|
||||
"%s Invalid HTT tx_status %d\n",
|
||||
|
@@ -83,7 +83,6 @@
|
||||
#define MAX_TX_HW_QUEUES MAX_TCL_DATA_RINGS
|
||||
|
||||
#define DP_MAX_INTERRUPT_CONTEXTS 8
|
||||
#define DP_MAX_MECT_ENTRIES 64
|
||||
|
||||
#ifndef REMOVE_PKT_LOG
|
||||
enum rx_pktlog_mode {
|
||||
@@ -528,17 +527,12 @@ struct dp_ast_entry {
|
||||
bool next_hop;
|
||||
bool is_active;
|
||||
bool is_static;
|
||||
bool is_mec;
|
||||
bool is_bss;
|
||||
TAILQ_ENTRY(dp_ast_entry) ase_list_elem;
|
||||
TAILQ_ENTRY(dp_ast_entry) hash_list_elem;
|
||||
};
|
||||
|
||||
struct mect_entry {
|
||||
uint8_t idx;
|
||||
uint8_t valid;
|
||||
uint8_t mac_addr[6];
|
||||
uint64_t ts;
|
||||
};
|
||||
|
||||
/* SOC level structure for data path */
|
||||
struct dp_soc {
|
||||
/* Common base structure - Should be the first member */
|
||||
@@ -726,7 +720,7 @@ struct dp_soc {
|
||||
/* Enable processing of Tx completion status words */
|
||||
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 * 2];
|
||||
struct {
|
||||
unsigned mask;
|
||||
unsigned idx_bits;
|
||||
@@ -742,8 +736,6 @@ struct dp_soc {
|
||||
|
||||
qdf_list_t reo_desc_freelist;
|
||||
qdf_spinlock_t reo_desc_freelist_lock;
|
||||
struct mect_entry mect_table[DP_MAX_MECT_ENTRIES];
|
||||
uint8_t mect_cnt;
|
||||
|
||||
/* Obj Mgr SoC */
|
||||
struct wlan_objmgr_psoc *psoc;
|
||||
|
@@ -926,7 +926,7 @@ 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;
|
||||
uint16_t sa_idx;
|
||||
|
||||
sa_idx = HAL_RX_MSDU_END_SA_IDX_GET(msdu_end);
|
||||
|
||||
|
Reference in New Issue
Block a user