qcacmn: Handling vlan tagged frames for multipass phrase feature

1. Remove vlan tag in tx and enqueue to hardware.
2. Add vlan tag in rx after peer-vlan_id lookup.

Change-Id: I932202540ac03cabdd20ffd4849fe759ea8a7abb
此提交包含在:
Varsha Mishra
2019-07-27 22:51:42 +05:30
提交者 nshrivas
父節點 abac9eedad
當前提交 6e1760c2c4
共有 11 個檔案被更改,包括 221 行新增8 行删除

查看文件

@@ -1500,6 +1500,7 @@ cdp_get_peer_mac_addr_frm_id(ol_txrx_soc_handle soc, uint16_t peer_id,
/**
* cdp_set_vdev_dscp_tid_map(): function to set DSCP-tid map in the vap
* @soc : soc handle
* @vdev: vdev handle
* @map_id: id of the tid map
*
@@ -1523,6 +1524,36 @@ static inline void cdp_set_vdev_dscp_tid_map(ol_txrx_soc_handle soc,
map_id);
}
#ifdef QCA_MULTIPASS_SUPPORT
/**
* cdp_set_vlan_groupkey(): function to set vlan ID - group key map in the vap
* @soc : soc handle
* @vdev: vdev handle
* @vlan_id: vlan id
* @group_key: corresponding group key to vlan ID
*
* Return: void
*/
static inline
QDF_STATUS cdp_set_vlan_groupkey(ol_txrx_soc_handle soc, struct cdp_vdev *vdev,
uint16_t vlan_id, uint16_t group_key)
{
if (!soc || !soc->ops) {
QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG,
"%s: Invalid Instance:", __func__);
QDF_BUG(0);
return 0;
}
if (!soc->ops->cmn_drv_ops ||
!soc->ops->cmn_drv_ops->set_vlan_groupkey)
return 0;
return soc->ops->cmn_drv_ops->set_vlan_groupkey(vdev, vlan_id,
group_key);
}
#endif
/**
* cdp_ath_get_total_per(): function to get hw retries
* @soc : soc handle

查看文件

@@ -936,7 +936,8 @@ enum cdp_vdev_param_type {
CDP_CFG_WDS_AGING_TIMER,
CDP_ENABLE_AP_BRIDGE,
CDP_ENABLE_CIPHER,
CDP_ENABLE_QWRAP_ISOLATION
CDP_ENABLE_QWRAP_ISOLATION,
CDP_UPDATE_MULTIPASS
};
#define TXRX_FW_STATS_TXSTATS 1

查看文件

@@ -467,6 +467,26 @@ cdp_peer_set_nawds(ol_txrx_soc_handle soc,
(peer, value);
}
#ifdef QCA_MULTIPASS_SUPPORT
static inline void
cdp_peer_set_vlan_id(ol_txrx_soc_handle soc, struct cdp_vdev *vdev,
uint8_t *peer_mac, uint8_t vlan_id)
{
if (!soc || !soc->ops) {
QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG,
"%s: Invalid Instance:", __func__);
QDF_BUG(0);
return;
}
if (!soc->ops->ctrl_ops ||
!soc->ops->ctrl_ops->txrx_peer_set_vlan_id)
return;
soc->ops->ctrl_ops->txrx_peer_set_vlan_id(soc, vdev, peer_mac, vlan_id);
}
#endif
/**
* cdp_txrx_set_pdev_param() - set pdev parameter
* @soc: opaque soc handle

查看文件

@@ -466,6 +466,10 @@ struct cdp_cmn_ops {
QDF_STATUS (*set_vdev_tidmap_prty)(struct cdp_vdev *vdev, uint8_t prty);
QDF_STATUS (*set_vdev_tidmap_tbl_id)(struct cdp_vdev *vdev,
uint8_t mapid);
#ifdef QCA_MULTIPASS_SUPPORT
QDF_STATUS (*set_vlan_groupkey)(struct cdp_vdev *vdev_handle,
uint16_t vlan_id, uint16_t group_key);
#endif
};
struct cdp_ctrl_ops {
@@ -664,6 +668,11 @@ struct cdp_ctrl_ops {
uint16_t protocol_type);
#endif /* WLAN_SUPPORT_RX_TAG_STATISTICS */
#endif /* WLAN_SUPPORT_RX_PROTOCOL_TYPE_TAG */
#ifdef QCA_MULTIPASS_SUPPORT
void (*txrx_peer_set_vlan_id)(ol_txrx_soc_handle soc,
struct cdp_vdev *vdev, uint8_t *peer_mac,
uint16_t vlan_id);
#endif
};
struct cdp_me_ops {

查看文件

@@ -4663,6 +4663,7 @@ static struct cdp_vdev *dp_vdev_attach_wifi3(struct cdp_pdev *txrx_pdev,
*/
TAILQ_INIT(&vdev->peer_list);
dp_peer_multipass_list_init(vdev);
if ((soc->intr_mode == DP_INTR_POLL) &&
wlan_cfg_get_num_contexts(soc->wlan_cfg_ctx) != 0) {
@@ -5913,6 +5914,7 @@ static void dp_peer_delete_wifi3(void *peer_handle, uint32_t bitmap)
dp_peer_rx_bufq_resources_deinit(peer);
qdf_spinlock_destroy(&peer->peer_info_lock);
dp_peer_multipass_list_remove(peer);
/*
* Remove the reference added during peer_attach.
@@ -7654,6 +7656,9 @@ static void dp_set_vdev_param(struct cdp_vdev *vdev_handle,
case CDP_ENABLE_QWRAP_ISOLATION:
vdev->isolation_vdev = val;
break;
case CDP_UPDATE_MULTIPASS:
vdev->multipass_en = val;
break;
default:
break;
}
@@ -9019,6 +9024,9 @@ static struct cdp_cmn_ops dp_ops_cmn = {
.set_vdev_tidmap_tbl_id = dp_set_vdev_tidmap_tbl_id_wifi3,
.txrx_cp_peer_del_response = dp_cp_peer_del_resp_handler,
#ifdef QCA_MULTIPASS_SUPPORT
.set_vlan_groupkey = dp_set_vlan_groupkey,
#endif
};
static struct cdp_ctrl_ops dp_ops_ctrl = {
@@ -9059,6 +9067,9 @@ static struct cdp_ctrl_ops dp_ops_ctrl = {
dp_dump_pdev_rx_protocol_tag_stats,
#endif /* WLAN_SUPPORT_RX_TAG_STATISTICS */
#endif /* WLAN_SUPPORT_RX_PROTOCOL_TYPE_TAG */
#ifdef QCA_MULTIPASS_SUPPORT
.txrx_peer_set_vlan_id = dp_peer_set_vlan_id,
#endif /*QCA_MULTIPASS_SUPPORT*/
};
static struct cdp_me_ops dp_ops_me = {

查看文件

@@ -212,4 +212,66 @@ void
dp_peer_update_inactive_time(struct dp_pdev *pdev, uint32_t tag_type,
uint32_t *tag_buf);
#ifndef QCA_MULTIPASS_SUPPORT
/**
* dp_peer_set_vlan_id: set vlan_id for this peer
* @cdp_soc: soc handle
* @peer_mac: mac address
* @vlan_id: vlan id for peer
*
* return: void
*/
static inline
void dp_peer_set_vlan_id(struct cdp_soc_t *cdp_soc,
struct cdp_vdev *vdev_handle, uint8_t *peer_mac,
uint16_t vlan_id)
{
}
/**
* dp_set_vlan_groupkey: set vlan map for vdev
* @vdev_handle: pointer to vdev
* @vlan_id: vlan_id
* @group_key: group key for vlan
*
* return: set success/failure
*/
static inline
QDF_STATUS dp_set_vlan_groupkey(struct cdp_vdev *vdev_handle,
uint16_t vlan_id, uint16_t group_key)
{
return QDF_STATUS_SUCCESS;
}
/**
* dp_peer_multipass_list_init: initialize multipass peer list
* @vdev: pointer to vdev
*
* return: void
*/
static inline
void dp_peer_multipass_list_init(struct dp_vdev *vdev)
{
}
/**
* dp_peer_multipass_list_remove: remove peer from special peer list
* @peer: peer handle
*
* return: void
*/
static inline
void dp_peer_multipass_list_remove(struct dp_peer *peer)
{
}
#else
void dp_peer_set_vlan_id(struct cdp_soc_t *cdp_soc,
struct cdp_vdev *vdev_handle, uint8_t *peer_mac,
uint16_t vlan_id);
QDF_STATUS dp_set_vlan_groupkey(struct cdp_vdev *vdev_handle,
uint16_t vlan_id, uint16_t group_key);
void dp_peer_multipass_list_init(struct dp_vdev *vdev);
void dp_peer_multipass_list_remove(struct dp_peer *peer);
#endif
#endif /* _DP_PEER_H_ */

查看文件

@@ -2025,6 +2025,13 @@ done:
l2_hdr_offset);
}
/*
* process frame for mulitpass phrase processing
*/
if (qdf_unlikely(vdev->multipass_en)) {
dp_rx_multipass_process(peer, nbuf, tid);
}
if (!dp_wds_rx_policy_check(rx_tlv_hdr, vdev, peer)) {
QDF_TRACE(QDF_MODULE_ID_DP,
QDF_TRACE_LEVEL_ERROR,

查看文件

@@ -1255,4 +1255,16 @@ static inline void dp_rx_flush_rx_cached(struct dp_peer *peer, bool drop)
{
}
#endif
#ifndef QCA_MULTIPASS_SUPPORT
static inline
bool dp_rx_multipass_process(struct dp_peer *peer, qdf_nbuf_t nbuf, uint8_t tid)
{
return false;
}
#else
bool dp_rx_multipass_process(struct dp_peer *peer, qdf_nbuf_t nbuf,
uint8_t tid);
#endif
#endif /* _DP_RX_H */

查看文件

@@ -303,7 +303,7 @@ dp_tx_desc_release(struct dp_tx_desc_s *tx_desc, uint8_t desc_pool_id)
* Return: HTT metadata size
*
*/
static uint8_t dp_tx_prepare_htt_metadata(struct dp_vdev *vdev, qdf_nbuf_t nbuf,
uint8_t dp_tx_prepare_htt_metadata(struct dp_vdev *vdev, qdf_nbuf_t nbuf,
struct dp_tx_msdu_info_s *msdu_info)
{
uint32_t *meta_data = msdu_info->meta_data;
@@ -323,13 +323,27 @@ static uint8_t dp_tx_prepare_htt_metadata(struct dp_vdev *vdev, qdf_nbuf_t nbuf,
htt_desc_size = sizeof(struct htt_tx_msdu_desc_ext2_t);
htt_desc_size_aligned = (htt_desc_size + 7) & ~0x7;
if (vdev->mesh_vdev || msdu_info->is_tx_sniffer) {
if (vdev->mesh_vdev || msdu_info->is_tx_sniffer ||
HTT_TX_MSDU_EXT2_DESC_FLAG_VALID_KEY_FLAGS_GET(msdu_info->
meta_data[0])) {
if (qdf_unlikely(qdf_nbuf_headroom(nbuf) <
htt_desc_size_aligned)) {
nbuf = qdf_nbuf_realloc_headroom(nbuf,
htt_desc_size_aligned);
if (!nbuf) {
/*
* qdf_nbuf_realloc_headroom won't do skb_clone
* as skb_realloc_headroom does. so, no free is
* needed here.
*/
DP_STATS_INC(vdev,
tx_i.dropped.headroom_insufficient, 1);
tx_i.dropped.headroom_insufficient,
1);
qdf_print(" %s[%d] skb_realloc_headroom failed",
__func__, __LINE__);
return 0;
}
}
/* Fill and add HTT metaheader */
hdr = qdf_nbuf_push_head(nbuf, htt_desc_size_aligned);
if (!hdr) {
@@ -746,6 +760,11 @@ struct dp_tx_desc_s *dp_tx_prepare_desc_single(struct dp_vdev *vdev,
dp_tx_trace_pkt(nbuf, tx_desc->id, vdev->vdev_id);
if (qdf_unlikely(vdev->multipass_en)) {
if (!dp_tx_multipass_process(soc, vdev, nbuf, msdu_info))
goto failure;
}
/*
* For special modes (vdev_type == ocb or mesh), data frames should be
* transmitted using varying transmit parameters (tx spec) which include
@@ -3805,6 +3824,7 @@ QDF_STATUS dp_tx_vdev_detach(struct dp_vdev *vdev)
/* Reset TX desc associated to this Vdev as NULL */
dp_tx_desc_flush(pdev, vdev, false);
dp_tx_vdev_multipass_deinit(vdev);
return QDF_STATUS_SUCCESS;
}

查看文件

@@ -237,6 +237,29 @@ static inline void dp_tx_me_exit(struct dp_pdev *pdev)
return;
}
#endif
#ifndef QCA_MULTIPASS_SUPPORT
static inline
bool dp_tx_multipass_process(struct dp_soc *soc, struct dp_vdev *vdev,
qdf_nbuf_t nbuf,
struct dp_tx_msdu_info_s *msdu_info)
{
return true;
}
static inline
void dp_tx_vdev_multipass_deinit(struct dp_vdev *vdev)
{
}
#else
bool dp_tx_multipass_process(struct dp_soc *soc, struct dp_vdev *vdev,
qdf_nbuf_t nbuf,
struct dp_tx_msdu_info_s *msdu_info);
void dp_tx_vdev_multipass_deinit(struct dp_vdev *vdev);
#endif
/**
* dp_tx_get_queue() - Returns Tx queue IDs to be used for this Tx frame
* @vdev: DP Virtual device handle
@@ -310,3 +333,5 @@ static inline void dp_tx_comp_process_exception(struct dp_tx_desc_s *tx_desc)
}
/* TODO TX_FEATURE_NOT_YET */
#endif
uint8_t dp_tx_prepare_htt_metadata(struct dp_vdev *vdev, qdf_nbuf_t nbuf,
struct dp_tx_msdu_info_s *msdu_info);

查看文件

@@ -1817,6 +1817,14 @@ struct dp_vdev {
uint8_t tidmap_prty;
/* Self Peer in STA mode */
struct dp_peer *vap_self_peer;
bool multipass_en;
#ifdef QCA_MULTIPASS_SUPPORT
uint16_t *iv_vlan_map;
/* dp_peer special list */
TAILQ_HEAD(, dp_peer) mpass_peer_list;
#endif
};
@@ -1940,6 +1948,13 @@ struct dp_peer {
/* average sojourn time */
qdf_ewma_tx_lag avg_sojourn_msdu[CDP_DATA_TID_MAX];
#ifdef QCA_MULTIPASS_SUPPORT
/* node in the special peer list element */
TAILQ_ENTRY(dp_peer) mpass_peer_list_elem;
/* vlan id for key */
uint16_t vlan_id;
#endif
#ifdef PEER_CACHE_RX_PKTS
qdf_atomic_t flush_in_progress;
struct dp_peer_cached_bufq bufq_info;