qcacmn: Enable intra-bss in Waikiki

In Beryllium the HW does the ast lookup and match
and sets the intra-bss bit in the msdu_desc_info
structure of reo_destination ring and WBM Rx release ring.

So, change the Beryllium code to make use of this
hardware assistance for intra-bss.

Change-Id: Ic7c89efc741fefe35603082309204fbe3c9a97c7
This commit is contained in:
Pavankumar Nandeshwar
2021-08-23 11:39:47 -07:00
committad av Madan Koyyalamudi
förälder d6a386028b
incheckning 26c6cd1397
7 ändrade filer med 210 tillägg och 51 borttagningar

Visa fil

@@ -20,6 +20,7 @@
#include "hal_hw_headers.h"
#include "dp_types.h"
#include "dp_rx.h"
#include "dp_tx.h"
#include "dp_be_rx.h"
#include "dp_peer.h"
#include "hal_rx.h"
@@ -339,6 +340,9 @@ more_data:
if (msdu_desc_info.msdu_flags & HAL_MSDU_F_SA_IS_VALID)
qdf_nbuf_set_sa_valid(rx_desc->nbuf, 1);
if (msdu_desc_info.msdu_flags & HAL_MSDU_F_INTRA_BSS)
qdf_nbuf_set_intra_bss(rx_desc->nbuf, 1);
qdf_nbuf_set_tid_val(rx_desc->nbuf,
HAL_RX_REO_QUEUE_NUMBER_GET(ring_desc));
#ifdef CONFIG_LITHIUM
@@ -685,8 +689,9 @@ done:
/* Intrabss-fwd */
if (dp_rx_check_ap_bridge(vdev))
if (DP_RX_INTRABSS_FWD(soc, peer, rx_tlv_hdr,
nbuf, msdu_metadata)) {
if (dp_rx_intrabss_fwd_be(soc, peer, rx_tlv_hdr,
nbuf,
msdu_metadata)) {
nbuf = next;
tid_stats->intrabss_cnt++;
continue; /* Get next desc */
@@ -1025,3 +1030,122 @@ uint32_t dp_rx_nf_process(struct dp_intr *int_ctx,
return work_done;
}
#endif
#ifndef QCA_HOST_MODE_WIFI_DISABLED
#if defined(QCA_WIFI_WCN7850) || !defined(INTRA_BSS_FW_OFFLOAD)
bool dp_rx_intrabss_fwd_be(struct dp_soc *soc, struct dp_peer *ta_peer,
uint8_t *rx_tlv_hdr, qdf_nbuf_t nbuf,
struct hal_rx_msdu_metadata msdu_metadata)
{
/* Hamilton V1 uses Lithium path */
return dp_rx_intrabss_fwd(soc, ta_peer, rx_tlv_hdr, nbuf,
msdu_metadata);
}
#else
/*
* dp_rx_intrabss_fwd_be() - API for intrabss fwd. For EAPOL
* pkt with DA not equal to vdev mac addr, fwd is not allowed.
* @soc: core txrx main context
* @ta_peer: source peer entry
* @rx_tlv_hdr: start address of rx tlvs
* @nbuf: nbuf that has to be intrabss forwarded
* @msdu_metadata: msdu metadata
*
* Return: true if it is forwarded else false
*/
bool dp_rx_intrabss_fwd_be(struct dp_soc *soc, struct dp_peer *ta_peer,
uint8_t *rx_tlv_hdr, qdf_nbuf_t nbuf,
struct hal_rx_msdu_metadata msdu_metadata)
{
uint16_t len;
qdf_nbuf_t nbuf_copy;
uint8_t tid = qdf_nbuf_get_tid_val(nbuf);
uint8_t ring_id = QDF_NBUF_CB_RX_CTX_ID(nbuf);
struct cdp_tid_rx_stats *tid_stats = &ta_peer->vdev->pdev->stats.
tid_stats.tid_rx_stats[ring_id][tid];
/* if it is a broadcast pkt (eg: ARP) and it is not its own
* source, then clone the pkt and send the cloned pkt for
* intra BSS forwarding and original pkt up the network stack
* Note: how do we handle multicast pkts. do we forward
* all multicast pkts as is or let a higher layer module
* like igmpsnoop decide whether to forward or not with
* Mcast enhancement.
*/
if (qdf_nbuf_is_da_mcbc(nbuf) && !ta_peer->bss_peer) {
if (dp_rx_intrabss_eapol_drop_check(soc, ta_peer, rx_tlv_hdr,
nbuf))
return true;
if (!dp_rx_check_ndi_mdns_fwding(ta_peer, nbuf))
return false;
/* If the source peer in the isolation list
* then dont forward instead push to bridge stack
*/
if (dp_get_peer_isolation(ta_peer))
return false;
nbuf_copy = qdf_nbuf_copy(nbuf);
if (!nbuf_copy)
return false;
len = QDF_NBUF_CB_RX_PKT_LEN(nbuf);
if (dp_tx_send((struct cdp_soc_t *)soc,
ta_peer->vdev->vdev_id, nbuf_copy)) {
DP_STATS_INC_PKT(ta_peer, rx.intra_bss.fail, 1, len);
tid_stats->fail_cnt[INTRABSS_DROP]++;
qdf_nbuf_free(nbuf_copy);
} else {
DP_STATS_INC_PKT(ta_peer, rx.intra_bss.pkts, 1, len);
tid_stats->intrabss_cnt++;
}
return false;
}
if (qdf_nbuf_is_intra_bss(nbuf)) {
if (dp_rx_intrabss_eapol_drop_check(soc, ta_peer, rx_tlv_hdr,
nbuf))
return true;
len = QDF_NBUF_CB_RX_PKT_LEN(nbuf);
/* linearize the nbuf just before we send to
* dp_tx_send()
*/
if (qdf_unlikely(qdf_nbuf_is_frag(nbuf))) {
if (qdf_nbuf_linearize(nbuf) == -ENOMEM)
return false;
nbuf = qdf_nbuf_unshare(nbuf);
if (!nbuf) {
DP_STATS_INC_PKT(ta_peer,
rx.intra_bss.fail, 1, len);
/* return true even though the pkt is
* not forwarded. Basically skb_unshare
* failed and we want to continue with
* next nbuf.
*/
tid_stats->fail_cnt[INTRABSS_DROP]++;
return true;
}
}
if (!dp_tx_send((struct cdp_soc_t *)soc,
ta_peer->vdev->vdev_id, nbuf)) {
DP_STATS_INC_PKT(ta_peer, rx.intra_bss.pkts, 1,
len);
} else {
DP_STATS_INC_PKT(ta_peer, rx.intra_bss.fail, 1,
len);
tid_stats->fail_cnt[INTRABSS_DROP]++;
return false;
}
return true;
}
return false;
}
#endif
#endif

Visa fil

@@ -22,6 +22,27 @@
#include <dp_types.h>
#include "dp_be.h"
#ifndef QCA_HOST_MODE_WIFI_DISABLED
/*
* dp_rx_intrabss_fwd_be() - API for intrabss fwd. For EAPOL
* pkt with DA not equal to vdev mac addr, fwd is not allowed.
* @soc: core txrx main context
* @ta_peer: source peer entry
* @rx_tlv_hdr: start address of rx tlvs
* @nbuf: nbuf that has to be intrabss forwarded
* @msdu_metadata: msdu metadata
*
* Return: true if it is forwarded else false
*/
bool dp_rx_intrabss_fwd_be(struct dp_soc *soc,
struct dp_peer *ta_peer,
uint8_t *rx_tlv_hdr,
qdf_nbuf_t nbuf,
struct hal_rx_msdu_metadata msdu_metadata);
#endif
uint32_t dp_rx_process_be(struct dp_intr *int_ctx,
hal_ring_handle_t hal_ring_hdl, uint8_t reo_ring_num,
uint32_t quota);

Visa fil

@@ -39,28 +39,6 @@
#include "dp_txrx_wds.h"
#endif
#ifndef QCA_HOST_MODE_WIFI_DISABLED
#ifdef DP_RX_DISABLE_NDI_MDNS_FORWARDING
static inline
bool dp_rx_check_ndi_mdns_fwding(struct dp_peer *ta_peer, qdf_nbuf_t nbuf)
{
if (ta_peer->vdev->opmode == wlan_op_mode_ndi &&
qdf_nbuf_is_ipv6_mdns_pkt(nbuf)) {
DP_STATS_INC(ta_peer, rx.intra_bss.mdns_no_fwd, 1);
return false;
}
return true;
}
#else
static inline
bool dp_rx_check_ndi_mdns_fwding(struct dp_peer *ta_peer, qdf_nbuf_t nbuf)
{
return true;
}
#endif
#endif /* QCA_HOST_MODE_WIFI_DISABLED */
#ifdef DUP_RX_DESC_WAR
void dp_rx_dump_info_and_assert(struct dp_soc *soc,
hal_ring_handle_t hal_ring,
@@ -566,6 +544,9 @@ dp_rx_intrabss_fwd(struct dp_soc *soc,
*/
if ((qdf_nbuf_is_da_valid(nbuf) && !qdf_nbuf_is_da_mcbc(nbuf))) {
if (dp_rx_intrabss_eapol_drop_check(soc, ta_peer, rx_tlv_hdr,
nbuf))
return true;
ast_entry = soc->ast_table[msdu_metadata.da_idx];
if (!ast_entry)
@@ -594,6 +575,16 @@ dp_rx_intrabss_fwd(struct dp_soc *soc,
DP_MOD_ID_RX);
if (!da_peer)
return false;
/* If the source or destination peer in the isolation
* list then dont forward instead push to bridge stack.
*/
if (dp_get_peer_isolation(ta_peer) ||
dp_get_peer_isolation(da_peer)) {
dp_peer_unref_delete(da_peer, DP_MOD_ID_RX);
return false;
}
is_da_bss_peer = da_peer->bss_peer;
dp_peer_unref_delete(da_peer, DP_MOD_ID_RX);
@@ -602,13 +593,6 @@ dp_rx_intrabss_fwd(struct dp_soc *soc,
is_frag = qdf_nbuf_is_frag(nbuf);
memset(nbuf->cb, 0x0, sizeof(nbuf->cb));
/* If the source or destination peer in the isolation
* list then dont forward instead push to bridge stack.
*/
if (dp_get_peer_isolation(ta_peer) ||
dp_get_peer_isolation(da_peer))
return false;
/* linearize the nbuf just before we send to
* dp_tx_send()
*/
@@ -655,6 +639,10 @@ dp_rx_intrabss_fwd(struct dp_soc *soc,
*/
else if (qdf_unlikely((qdf_nbuf_is_da_mcbc(nbuf) &&
!ta_peer->bss_peer))) {
if (dp_rx_intrabss_eapol_drop_check(soc, ta_peer, rx_tlv_hdr,
nbuf))
return true;
if (!dp_rx_check_ndi_mdns_fwding(ta_peer, nbuf))
goto end;
@@ -669,10 +657,6 @@ dp_rx_intrabss_fwd(struct dp_soc *soc,
goto end;
len = QDF_NBUF_CB_RX_PKT_LEN(nbuf);
memset(nbuf_copy->cb, 0x0, sizeof(nbuf_copy->cb));
/* Set cb->ftype to intrabss FWD */
qdf_nbuf_set_tx_ftype(nbuf_copy, CB_FTYPE_INTRABSS_FWD);
if (dp_tx_send((struct cdp_soc_t *)soc,
ta_peer->vdev->vdev_id, nbuf_copy)) {
DP_STATS_INC_PKT(ta_peer, rx.intra_bss.fail, 1, len);

Visa fil

@@ -272,6 +272,27 @@ bool dp_rx_deliver_special_frame(struct dp_soc *soc, struct dp_peer *peer,
}
#endif
#ifndef QCA_HOST_MODE_WIFI_DISABLED
#ifdef DP_RX_DISABLE_NDI_MDNS_FORWARDING
static inline
bool dp_rx_check_ndi_mdns_fwding(struct dp_peer *ta_peer, qdf_nbuf_t nbuf)
{
if (ta_peer->vdev->opmode == wlan_op_mode_ndi &&
qdf_nbuf_is_ipv6_mdns_pkt(nbuf)) {
DP_STATS_INC(ta_peer, rx.intra_bss.mdns_no_fwd, 1);
return false;
}
return true;
}
#else
static inline
bool dp_rx_check_ndi_mdns_fwding(struct dp_peer *ta_peer, qdf_nbuf_t nbuf)
{
return true;
}
#endif
#endif /* QCA_HOST_MODE_WIFI_DISABLED */
/* DOC: Offset to obtain LLC hdr
*
* In the case of Wifi parse error
@@ -1101,20 +1122,19 @@ bool dp_rx_intrabss_fwd(struct dp_soc *soc,
#ifdef DISABLE_EAPOL_INTRABSS_FWD
/*
* dp_rx_intrabss_fwd_wrapper() - Wrapper API for intrabss fwd. For EAPOL
* dp_rx_intrabss_eapol_drop_check() - API For EAPOL
* pkt with DA not equal to vdev mac addr, fwd is not allowed.
* @soc: core txrx main context
* @ta_peer: source peer entry
* @rx_tlv_hdr: start address of rx tlvs
* @nbuf: nbuf that has to be intrabss forwarded
* @msdu_metadata: msdu metadata
*
* Return: true if it is forwarded else false
*/
static inline
bool dp_rx_intrabss_fwd_wrapper(struct dp_soc *soc, struct dp_peer *ta_peer,
uint8_t *rx_tlv_hdr, qdf_nbuf_t nbuf,
struct hal_rx_msdu_metadata msdu_metadata)
bool dp_rx_intrabss_eapol_drop_check(struct dp_soc *soc,
struct dp_peer *ta_peer,
uint8_t *rx_tlv_hdr, qdf_nbuf_t nbuf)
{
if (qdf_unlikely(qdf_nbuf_is_ipv4_eapol_pkt(nbuf) &&
qdf_mem_cmp(qdf_nbuf_data(nbuf) +
@@ -1126,18 +1146,18 @@ bool dp_rx_intrabss_fwd_wrapper(struct dp_soc *soc, struct dp_peer *ta_peer,
return true;
}
return dp_rx_intrabss_fwd(soc, ta_peer, rx_tlv_hdr, nbuf,
msdu_metadata);
return false;
}
#define DP_RX_INTRABSS_FWD(soc, peer, rx_tlv_hdr, nbuf, msdu_metadata) \
dp_rx_intrabss_fwd_wrapper(soc, peer, rx_tlv_hdr, nbuf, \
msdu_metadata)
#else /* DISABLE_EAPOL_INTRABSS_FWD */
#define DP_RX_INTRABSS_FWD(soc, peer, rx_tlv_hdr, nbuf, msdu_metadata) \
dp_rx_intrabss_fwd(soc, peer, rx_tlv_hdr, nbuf, msdu_metadata)
#endif /* DISABLE_EAPOL_INTRABSS_FWD */
static inline
bool dp_rx_intrabss_eapol_drop_check(struct dp_soc *soc,
struct dp_peer *ta_peer,
uint8_t *rx_tlv_hdr, qdf_nbuf_t nbuf)
{
return false;
}
#endif /* DISABLE_EAPOL_INTRABSS_FWD */
/**
* dp_rx_defrag_concat() - Concatenate the fragments
*

Visa fil

@@ -752,7 +752,7 @@ done:
/* Intrabss-fwd */
if (dp_rx_check_ap_bridge(vdev))
if (DP_RX_INTRABSS_FWD(soc, peer, rx_tlv_hdr,
if (dp_rx_intrabss_fwd(soc, peer, rx_tlv_hdr,
nbuf, msdu_metadata)) {
nbuf = next;
tid_stats->intrabss_cnt++;

Visa fil

@@ -166,6 +166,11 @@
RX_MSDU_DESC_INFO_DA_IS_MCBC_OFFSET)) & \
RX_MSDU_DESC_INFO_DA_IS_MCBC_MASK)
#define HAL_RX_MSDU_INTRA_BSS_FLAG_GET(msdu_info_ptr) \
((*_OFFSET_TO_WORD_PTR(msdu_info_ptr, \
RX_MSDU_DESC_INFO_INTRA_BSS_OFFSET)) & \
RX_MSDU_DESC_INFO_INTRA_BSS_MASK)
#define HAL_RX_MPDU_ENCRYPT_TYPE_GET(_rx_mpdu_info) \
(_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \
RX_MPDU_INFO_ENCRYPT_TYPE_OFFSET)), \
@@ -367,6 +372,9 @@ uint32_t hal_rx_msdu_flags_get_be(rx_msdu_desc_info_t msdu_desc_info_hdl)
if (HAL_RX_MSDU_DA_IS_MCBC_FLAG_GET(msdu_desc_info))
flags |= HAL_MSDU_F_DA_IS_MCBC;
if (HAL_RX_MSDU_INTRA_BSS_FLAG_GET(msdu_desc_info))
flags |= HAL_MSDU_F_INTRA_BSS;
return flags;
}

Visa fil

@@ -193,6 +193,7 @@ struct hal_rx_msdu_desc_info {
* @ HAL_MSDU_F_DA_IS_VALID: Found match for DA in AST
* @ HAL_MSDU_F_DA_IS_MCBC: DA is MC/BC address
* @ HAL_MSDU_F_DA_IDX_TIMEOUT: AST search for DA timed out
* @ HAL_MSDU_F_INTRA_BSS: This is an intrabss packet
*/
enum hal_rx_msdu_desc_flags {
HAL_MSDU_F_FIRST_MSDU_IN_MPDU = (0x1 << 0),
@@ -202,7 +203,8 @@ enum hal_rx_msdu_desc_flags {
HAL_MSDU_F_SA_IDX_TIMEOUT = (0x1 << 24),
HAL_MSDU_F_DA_IS_VALID = (0x1 << 25),
HAL_MSDU_F_DA_IS_MCBC = (0x1 << 26),
HAL_MSDU_F_DA_IDX_TIMEOUT = (0x1 << 27)
HAL_MSDU_F_DA_IDX_TIMEOUT = (0x1 << 27),
HAL_MSDU_F_INTRA_BSS = (0x1 << 28),
};
/*