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:
Tallapragada Kalyan
2017-07-07 12:51:58 +05:30
committed by snandini
parent 6c7625b2ca
commit fb72b637f7
8 changed files with 119 additions and 89 deletions

View File

@@ -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);

View File

@@ -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);
}
/*

View File

@@ -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;
}

View File

@@ -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,

View File

@@ -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(

View File

@@ -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",

View File

@@ -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;

View File

@@ -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);