qcacmn: Add support for Mesh Rx filters

Added support to filter out received packets on mesh vap based on
rx filter setting.

Change-Id: Ibc541324d928a9d006531c8908f4792e0c7d854e
CRs-Fixed: 2003389
This commit is contained in:
Venkateswara Swamy Bandaru
2017-03-07 11:04:28 +05:30
committed by qcabuildsw
parent ebe927f713
commit ec4f8e61c6
6 changed files with 292 additions and 2 deletions

View File

@@ -262,6 +262,24 @@ static inline void cdp_set_mesh_mode
return;
}
/**
* @brief set mesh rx filter
* @details based on the bits enabled in the filter packets has to be dropped.
*
* @param soc - pointer to the soc
* @param vdev - the data virtual device object
* @param val - value to be set
* @return - void
*/
static inline
void cdp_set_mesh_rx_filter(ol_txrx_soc_handle soc,
struct cdp_vdev *vdev, uint32_t val)
{
if (soc->ops->ctrl_ops->txrx_set_mesh_rx_filter)
return soc->ops->ctrl_ops->txrx_set_mesh_rx_filter(vdev, val);
return;
}
static inline void cdp_tx_flush_buffers
(ol_txrx_soc_handle soc, struct cdp_vdev *vdev)
{

View File

@@ -329,6 +329,16 @@ struct cdp_ctrl_ops {
/* Should be ol_txrx_ctrl_api.h */
void (*txrx_set_mesh_mode)(struct cdp_vdev *vdev, u_int32_t val);
/**
* @brief setting mesh rx filter
* @details
* based on the bits enabled in the filter packets has to be dropped.
*
* @param vdev - the data virtual device object
* @param val - value to set
*/
void (*txrx_set_mesh_rx_filter)(struct cdp_vdev *vdev, uint32_t val);
void (*tx_flush_buffers)(struct cdp_vdev *vdev);
int (*txrx_is_target_ar900b)(struct cdp_vdev *vdev);

View File

@@ -1831,7 +1831,7 @@ static struct cdp_cfg *dp_get_ctrl_pdev_from_vdev_wifi3(struct cdp_vdev *pvdev)
}
#ifdef MESH_MODE_SUPPORT
void dp_peer_set_mesh_mode(struct cdp_vdev *vdev_hdl, u_int32_t val)
void dp_peer_set_mesh_mode(struct cdp_vdev *vdev_hdl, uint32_t val)
{
struct dp_vdev *vdev = (struct dp_vdev *)vdev_hdl;
@@ -1839,6 +1839,22 @@ void dp_peer_set_mesh_mode(struct cdp_vdev *vdev_hdl, u_int32_t val)
FL("%s: val %d"), __func__, val);
vdev->mesh_vdev = val;
}
/*
* dp_peer_set_mesh_rx_filter() - to set the mesh rx filter
* @vdev_hdl: virtual device object
* @val: value to be set
*
* Return: void
*/
void dp_peer_set_mesh_rx_filter(struct cdp_vdev *vdev_hdl, uint32_t val)
{
struct dp_vdev *vdev = (struct dp_vdev *)vdev_hdl;
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_INFO,
FL("val %d"), val);
vdev->mesh_rx_filter = val;
}
#endif
static struct cdp_cmn_ops dp_ops_cmn = {
@@ -1868,6 +1884,7 @@ static struct cdp_ctrl_ops dp_ops_ctrl = {
.txrx_set_tx_encap_type = dp_set_vdev_tx_encap_type,
#ifdef MESH_MODE_SUPPORT
.txrx_set_mesh_mode = dp_peer_set_mesh_mode,
.txrx_set_mesh_rx_filter = dp_peer_set_mesh_rx_filter,
#endif
/* TODO: Add other functions */
};

View File

@@ -291,12 +291,77 @@ void dp_rx_fill_mesh_stats(struct dp_vdev *vdev, qdf_nbuf_t nbuf)
rx_info->rs_keyix);
}
/**
* dp_rx_fill_mesh_stats() - Filters mesh unwanted packets
*
* @vdev: DP Virtual device handle
* @nbuf: Buffer pointer
*
* This checks if the received packet is matching any filter out
* catogery and and drop the packet if it matches.
*
* Return: status(0 indicates drop, 1 indicate to no drop)
*/
static inline
QDF_STATUS dp_rx_filter_mesh_packets(struct dp_vdev *vdev, qdf_nbuf_t nbuf)
{
uint8_t *rx_tlv_hdr = qdf_nbuf_data(nbuf);
union dp_align_mac_addr mac_addr;
if (qdf_unlikely(vdev->mesh_rx_filter)) {
if (vdev->mesh_rx_filter & MESH_FILTER_OUT_FROMDS)
if (hal_rx_mpdu_get_fr_ds(rx_tlv_hdr))
return QDF_STATUS_SUCCESS;
if (vdev->mesh_rx_filter & MESH_FILTER_OUT_TODS)
if (hal_rx_mpdu_get_to_ds(rx_tlv_hdr))
return QDF_STATUS_SUCCESS;
if (vdev->mesh_rx_filter & MESH_FILTER_OUT_NODS)
if (!hal_rx_mpdu_get_fr_ds(rx_tlv_hdr)
&& !hal_rx_mpdu_get_to_ds(rx_tlv_hdr))
return QDF_STATUS_SUCCESS;
if (vdev->mesh_rx_filter & MESH_FILTER_OUT_RA) {
if (hal_rx_mpdu_get_addr1(rx_tlv_hdr,
&mac_addr.raw[0]))
return QDF_STATUS_E_FAILURE;
if (!qdf_mem_cmp(&mac_addr.raw[0],
&vdev->mac_addr.raw[0],
DP_MAC_ADDR_LEN))
return QDF_STATUS_SUCCESS;
}
if (vdev->mesh_rx_filter & MESH_FILTER_OUT_TA) {
if (hal_rx_mpdu_get_addr2(rx_tlv_hdr,
&mac_addr.raw[0]))
return QDF_STATUS_E_FAILURE;
if (!qdf_mem_cmp(&mac_addr.raw[0],
&vdev->mac_addr.raw[0],
DP_MAC_ADDR_LEN))
return QDF_STATUS_SUCCESS;
}
}
return QDF_STATUS_E_FAILURE;
}
#else
static
void dp_rx_fill_mesh_stats(struct dp_vdev *vdev, qdf_nbuf_t nbuf)
{
}
static inline
QDF_STATUS dp_rx_filter_mesh_packets(struct dp_vdev *vdev, qdf_nbuf_t nbuf)
{
return QDF_STATUS_E_FAILURE;
}
#endif
@@ -541,8 +606,18 @@ done:
/* Set length in nbuf */
qdf_nbuf_set_pktlen(nbuf, pkt_len);
if (qdf_unlikely(vdev->mesh_vdev))
if (qdf_unlikely(vdev->mesh_vdev)) {
if (dp_rx_filter_mesh_packets(vdev, nbuf)
== QDF_STATUS_SUCCESS) {
QDF_TRACE(QDF_MODULE_ID_DP,
QDF_TRACE_LEVEL_INFO_MED,
FL("mesh pkt filtered"));
qdf_nbuf_free(nbuf);
continue;
}
dp_rx_fill_mesh_stats(vdev, nbuf);
}
/*
* Advance the packet start pointer by total size of

View File

@@ -578,6 +578,10 @@ union dp_align_mac_addr {
uint32_t bytes_abcd;
uint16_t bytes_ef;
} align4;
struct {
uint16_t bytes_ab;
uint32_t bytes_cdef;
} align4_2;
};
#define MAX_HTT_METADATA_LEN 32
@@ -663,6 +667,9 @@ struct dp_vdev {
/* Mesh mode vdev */
uint32_t mesh_vdev;
/* Mesh mode rx filter setting */
uint32_t mesh_rx_filter;
/* DSCP-TID mapping table ID */
uint8_t dscp_tid_map_id;

View File

@@ -990,6 +990,169 @@ hal_rx_msdu_start_nss_get(uint8_t *buf)
return nss;
}
#define HAL_RX_MPDU_GET_TODS(_rx_mpdu_info) \
(_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \
RX_MPDU_INFO_2_TO_DS_OFFSET)), \
RX_MPDU_INFO_2_TO_DS_MASK, \
RX_MPDU_INFO_2_TO_DS_LSB))
/*
* hal_rx_mpdu_get_tods(): API to get the tods info
* from rx_mpdu_start
*
* @buf: pointer to the start of RX PKT TLV header
* Return: uint32_t(to_ds)
*/
static inline uint32_t
hal_rx_mpdu_get_to_ds(uint8_t *buf)
{
struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf;
struct rx_mpdu_start *mpdu_start =
&pkt_tlvs->mpdu_start_tlv.rx_mpdu_start;
struct rx_mpdu_info *mpdu_info = &mpdu_start->rx_mpdu_info_details;
uint32_t to_ds;
to_ds = HAL_RX_MPDU_GET_TODS(mpdu_info);
return to_ds;
}
#define HAL_RX_MPDU_GET_FROMDS(_rx_mpdu_info) \
(_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \
RX_MPDU_INFO_2_FR_DS_OFFSET)), \
RX_MPDU_INFO_2_FR_DS_MASK, \
RX_MPDU_INFO_2_FR_DS_LSB))
/*
* hal_rx_mpdu_get_fr_ds(): API to get the from ds info
* from rx_mpdu_start
*
* @buf: pointer to the start of RX PKT TLV header
* Return: uint32_t(fr_ds)
*/
static inline uint32_t
hal_rx_mpdu_get_fr_ds(uint8_t *buf)
{
struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf;
struct rx_mpdu_start *mpdu_start =
&pkt_tlvs->mpdu_start_tlv.rx_mpdu_start;
struct rx_mpdu_info *mpdu_info = &mpdu_start->rx_mpdu_info_details;
uint32_t fr_ds;
fr_ds = HAL_RX_MPDU_GET_FROMDS(mpdu_info);
return fr_ds;
}
#define HAL_RX_MPDU_MAC_ADDR_AD1_VALID_GET(_rx_mpdu_info) \
(_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \
RX_MPDU_INFO_2_MAC_ADDR_AD1_VALID_OFFSET)), \
RX_MPDU_INFO_2_MAC_ADDR_AD1_VALID_MASK, \
RX_MPDU_INFO_2_MAC_ADDR_AD1_VALID_LSB))
#define HAL_RX_MPDU_MAC_ADDR_AD2_VALID_GET(_rx_mpdu_info) \
(_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \
RX_MPDU_INFO_2_MAC_ADDR_AD2_VALID_OFFSET)), \
RX_MPDU_INFO_2_MAC_ADDR_AD2_VALID_MASK, \
RX_MPDU_INFO_2_MAC_ADDR_AD2_VALID_LSB))
#define HAL_RX_MPDU_AD1_31_0_GET(_rx_mpdu_info) \
(_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \
RX_MPDU_INFO_15_MAC_ADDR_AD1_31_0_OFFSET)), \
RX_MPDU_INFO_15_MAC_ADDR_AD1_31_0_MASK, \
RX_MPDU_INFO_15_MAC_ADDR_AD1_31_0_LSB))
#define HAL_RX_MPDU_AD1_47_32_GET(_rx_mpdu_info) \
(_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \
RX_MPDU_INFO_16_MAC_ADDR_AD1_47_32_OFFSET)), \
RX_MPDU_INFO_16_MAC_ADDR_AD1_47_32_MASK, \
RX_MPDU_INFO_16_MAC_ADDR_AD1_47_32_LSB))
#define HAL_RX_MPDU_AD2_15_0_GET(_rx_mpdu_info) \
(_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \
RX_MPDU_INFO_16_MAC_ADDR_AD2_15_0_OFFSET)), \
RX_MPDU_INFO_16_MAC_ADDR_AD2_15_0_MASK, \
RX_MPDU_INFO_16_MAC_ADDR_AD2_15_0_LSB))
#define HAL_RX_MPDU_AD2_47_16_GET(_rx_mpdu_info) \
(_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \
RX_MPDU_INFO_17_MAC_ADDR_AD2_47_16_OFFSET)), \
RX_MPDU_INFO_17_MAC_ADDR_AD2_47_16_MASK, \
RX_MPDU_INFO_17_MAC_ADDR_AD2_47_16_LSB))
/*
* hal_rx_mpdu_get_addr1(): API to check get address1 of the mpdu
*
* @buf: pointer to the start of RX PKT TLV headera
* @mac_addr: pointer to mac address
* Return: sucess/failure
*/
static inline
QDF_STATUS hal_rx_mpdu_get_addr1(uint8_t *buf, uint8_t *mac_addr)
{
struct __attribute__((__packed__)) hal_addr1 {
uint32_t ad1_31_0;
uint16_t ad1_47_32;
};
struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf;
struct rx_mpdu_start *mpdu_start =
&pkt_tlvs->mpdu_start_tlv.rx_mpdu_start;
struct rx_mpdu_info *mpdu_info = &mpdu_start->rx_mpdu_info_details;
struct hal_addr1 *addr = (struct hal_addr1 *)mac_addr;
uint32_t mac_addr_ad1_valid;
mac_addr_ad1_valid = HAL_RX_MPDU_MAC_ADDR_AD1_VALID_GET(mpdu_info);
if (mac_addr_ad1_valid) {
addr->ad1_31_0 = HAL_RX_MPDU_AD1_31_0_GET(mpdu_info);
addr->ad1_47_32 = HAL_RX_MPDU_AD1_47_32_GET(mpdu_info);
return QDF_STATUS_SUCCESS;
}
return QDF_STATUS_E_FAILURE;
}
/*
* hal_rx_mpdu_get_addr2(): API to check get address2 of the mpdu
* in the packet
*
* @buf: pointer to the start of RX PKT TLV header
* @mac_addr: pointer to mac address
* Return: sucess/failure
*/
static inline
QDF_STATUS hal_rx_mpdu_get_addr2(uint8_t *buf, uint8_t *mac_addr)
{
struct __attribute__((__packed__)) hal_addr2 {
uint16_t ad2_15_0;
uint32_t ad2_47_16;
};
struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf;
struct rx_mpdu_start *mpdu_start =
&pkt_tlvs->mpdu_start_tlv.rx_mpdu_start;
struct rx_mpdu_info *mpdu_info = &mpdu_start->rx_mpdu_info_details;
struct hal_addr2 *addr = (struct hal_addr2 *)mac_addr;
uint32_t mac_addr_ad2_valid;
mac_addr_ad2_valid = HAL_RX_MPDU_MAC_ADDR_AD2_VALID_GET(mpdu_info);
if (mac_addr_ad2_valid) {
addr->ad2_15_0 = HAL_RX_MPDU_AD2_15_0_GET(mpdu_info);
addr->ad2_47_16 = HAL_RX_MPDU_AD2_47_16_GET(mpdu_info);
return QDF_STATUS_SUCCESS;
}
return QDF_STATUS_E_FAILURE;
}
/*******************************************************************************
* RX ERROR APIS
******************************************************************************/