qcacmn: Add Non Association WDS(NAWDS) Support for Lithium
Add API to handle NAWDS packets on tx side. Add API to handle invalid peers and pass them to umac. Change-Id: Ie8c2508e4f51c7d6969c9eb6439919c57dd427d4 CRs-Fixed: 2008205
This commit is contained in:

committed by
Sandeep Puligilla

parent
e0a0247ead
commit
9f174c6e2f
@@ -401,7 +401,17 @@ struct cdp_soc_t {
|
||||
struct ol_if_ops *ol_ops;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* cdp_vdev_param_type: different types of parameters
|
||||
* to set values in vdev
|
||||
* @CDP_ENABLE_NAWDS: set nawds enable/disable
|
||||
* @CDP_ENABLE_MCAST_EN: enable/disable multicast enhancement
|
||||
*
|
||||
*/
|
||||
enum cdp_vdev_param_type {
|
||||
CDP_ENABLE_NAWDS,
|
||||
CDP_ENABLE_MCAST_EN,
|
||||
};
|
||||
|
||||
#define TXRX_FW_STATS_TXSTATS 1
|
||||
#define TXRX_FW_STATS_RXSTATS 2
|
||||
|
@@ -288,4 +288,22 @@ static inline void cdp_tx_flush_buffers
|
||||
return;
|
||||
}
|
||||
|
||||
static inline void cdp_txrx_set_vdev_param(ol_txrx_soc_handle soc,
|
||||
struct cdp_vdev *vdev, enum cdp_vdev_param_type type,
|
||||
uint32_t val)
|
||||
{
|
||||
if (soc->ops->ctrl_ops->txrx_set_vdev_param)
|
||||
return soc->ops->ctrl_ops->txrx_set_vdev_param(vdev, type, val);
|
||||
return;
|
||||
}
|
||||
|
||||
static inline void
|
||||
cdp_peer_set_nawds(ol_txrx_soc_handle soc,
|
||||
struct ol_txrx_peer_t *peer, uint8_t value)
|
||||
{
|
||||
if (soc->ops->ctrl_ops->txrx_peer_set_nawds)
|
||||
return soc->ops->ctrl_ops->txrx_peer_set_nawds
|
||||
(peer, value);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
@@ -359,6 +359,10 @@ struct cdp_ctrl_ops {
|
||||
|
||||
int (*txrx_is_target_ar900b)(struct cdp_vdev *vdev);
|
||||
|
||||
void (*txrx_set_vdev_param)(struct cdp_vdev *vdev,
|
||||
enum cdp_vdev_param_type param, uint32_t val);
|
||||
|
||||
void (*txrx_peer_set_nawds)(void *peer, uint8_t value);
|
||||
};
|
||||
|
||||
struct cdp_me_ops {
|
||||
@@ -557,6 +561,7 @@ struct ol_if_ops {
|
||||
struct cdp_lro_hash_config *lro_hash);
|
||||
void (*update_dp_stats)(void *soc, void *stats, uint16_t id,
|
||||
uint8_t type);
|
||||
uint8_t (*rx_invalid_peer)(void *osif_pdev, void *msg);
|
||||
|
||||
/* TODO: Add any other control path calls required to OL_IF/WMA layer */
|
||||
};
|
||||
|
@@ -2960,6 +2960,38 @@ dp_get_peer_stats(struct cdp_pdev *pdev_handle, char *mac_addr)
|
||||
dp_print_peer_stats(peer);
|
||||
return;
|
||||
}
|
||||
/*
|
||||
* dp_set_vdev_param: function to set parameters in vdev
|
||||
* @param: parameter type to be set
|
||||
* @val: value of parameter to be set
|
||||
*
|
||||
* return: void
|
||||
*/
|
||||
static void dp_set_vdev_param(struct cdp_vdev *vdev_handle,
|
||||
enum cdp_vdev_param_type param, uint32_t val)
|
||||
{
|
||||
struct dp_vdev *vdev = (struct dp_vdev *)vdev_handle;
|
||||
|
||||
switch (param) {
|
||||
case CDP_ENABLE_NAWDS:
|
||||
vdev->nawds_enabled = val;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* dp_peer_set_nawds: set nawds bit in peer
|
||||
* @peer_handle: pointer to peer
|
||||
* @value: enable/disable nawds
|
||||
*
|
||||
* return: void
|
||||
*/
|
||||
static void dp_peer_set_nawds(void *peer_handle, uint8_t value)
|
||||
{
|
||||
struct dp_peer *peer = (struct dp_peer *)peer_handle;
|
||||
peer->nawds_enabled = value;
|
||||
}
|
||||
|
||||
/*
|
||||
* dp_set_vdev_dscp_tid_map_wifi3(): Update Map ID selected for particular vdev
|
||||
@@ -3065,6 +3097,8 @@ static struct cdp_ctrl_ops dp_ops_ctrl = {
|
||||
.txrx_set_mesh_mode = dp_peer_set_mesh_mode,
|
||||
.txrx_set_mesh_rx_filter = dp_peer_set_mesh_rx_filter,
|
||||
#endif
|
||||
.txrx_set_vdev_param = dp_set_vdev_param,
|
||||
.txrx_peer_set_nawds = dp_peer_set_nawds,
|
||||
/* TODO: Add other functions */
|
||||
};
|
||||
|
||||
|
@@ -495,6 +495,78 @@ QDF_STATUS dp_rx_filter_mesh_packets(struct dp_vdev *vdev, qdf_nbuf_t nbuf)
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_WIN
|
||||
/**
|
||||
* dp_rx_process_invalid_peer(): Function to pass invalid peer list to umac
|
||||
* @soc: DP SOC handle
|
||||
* @nbuf: nbuf for which peer is invalid
|
||||
*
|
||||
* return: integer type
|
||||
*/
|
||||
uint8_t dp_rx_process_invalid_peer(struct dp_soc *soc, qdf_nbuf_t nbuf)
|
||||
{
|
||||
struct dp_invalid_peer_msg msg;
|
||||
struct dp_vdev *vdev = NULL;
|
||||
struct dp_pdev *pdev = NULL;
|
||||
struct ieee80211_frame *wh;
|
||||
uint8_t i;
|
||||
uint8_t *rx_pkt_hdr;
|
||||
|
||||
rx_pkt_hdr = qdf_nbuf_data(nbuf);
|
||||
wh = (struct ieee80211_frame *)rx_pkt_hdr;
|
||||
|
||||
if (!DP_FRAME_IS_DATA(wh)) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
|
||||
"NAWDS valid only for data frames");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (qdf_nbuf_len(nbuf) < sizeof(struct ieee80211_frame)) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
|
||||
"Invalid nbuf length");
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
for (i = 0; i < MAX_PDEV_CNT; i++) {
|
||||
pdev = soc->pdev_list[i];
|
||||
if (!pdev) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
|
||||
"PDEV not found");
|
||||
continue;
|
||||
}
|
||||
|
||||
TAILQ_FOREACH(vdev, &pdev->vdev_list, vdev_list_elem) {
|
||||
if (qdf_mem_cmp(wh->i_addr1, vdev->mac_addr.raw,
|
||||
DP_MAC_ADDR_LEN) == 0) {
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!vdev) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
|
||||
"VDEV not found");
|
||||
return 1;
|
||||
}
|
||||
|
||||
out:
|
||||
msg.wh = wh;
|
||||
msg.nbuf = nbuf;
|
||||
msg.vdev_id = vdev->vdev_id;
|
||||
if (pdev->soc->cdp_soc.ol_ops->rx_invalid_peer)
|
||||
return pdev->soc->cdp_soc.ol_ops->rx_invalid_peer(
|
||||
pdev->osif_pdev, &msg);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
uint8_t dp_rx_process_invalid_peer(struct dp_soc *soc, qdf_nbuf_t nbuf)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* dp_rx_process() - Brain of the Rx processing functionality
|
||||
* Called from the bottom half (tasklet/NET_RX_SOFTIRQ)
|
||||
@@ -717,6 +789,7 @@ done:
|
||||
/* Peer lookup failed */
|
||||
if (!peer && !vdev) {
|
||||
|
||||
dp_rx_process_invalid_peer(soc, nbuf);
|
||||
/* Drop & free packet */
|
||||
qdf_nbuf_free(nbuf);
|
||||
|
||||
|
@@ -256,6 +256,7 @@ dp_rx_wds_srcport_learn(struct dp_soc *soc,
|
||||
}
|
||||
#endif
|
||||
|
||||
uint8_t dp_rx_process_invalid_peer(struct dp_soc *soc, qdf_nbuf_t nbuf);
|
||||
#define DP_RX_LIST_APPEND(head, tail, elem) \
|
||||
do { \
|
||||
if (!(head)) { \
|
||||
|
@@ -274,7 +274,8 @@ dp_rx_null_q_desc_handle(struct dp_soc *soc, struct dp_rx_desc *rx_desc,
|
||||
if (!peer) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
|
||||
FL("peer is NULL"));
|
||||
qdf_nbuf_free(nbuf);
|
||||
qdf_nbuf_pull_head(nbuf, RX_PKT_TLVS_LEN);
|
||||
dp_rx_process_invalid_peer(soc, nbuf);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
|
@@ -830,20 +830,23 @@ static void dp_tx_classify_tid(struct dp_vdev *vdev, qdf_nbuf_t nbuf,
|
||||
* @nbuf: skb
|
||||
* @tid: TID from HLOS for overriding default DSCP-TID mapping
|
||||
* @tx_q: Tx queue to be used for this Tx frame
|
||||
* @peer_id: peer_id of the peer in case of NAWDS frames
|
||||
*
|
||||
* Return: NULL on success,
|
||||
* nbuf when it fails to send
|
||||
*/
|
||||
static qdf_nbuf_t dp_tx_send_msdu_single(struct dp_vdev *vdev, qdf_nbuf_t nbuf,
|
||||
uint8_t tid, struct dp_tx_queue *tx_q,
|
||||
uint32_t *meta_data)
|
||||
uint32_t *meta_data, uint16_t peer_id)
|
||||
{
|
||||
struct dp_pdev *pdev = vdev->pdev;
|
||||
struct dp_soc *soc = pdev->soc;
|
||||
struct dp_tx_desc_s *tx_desc;
|
||||
QDF_STATUS status;
|
||||
void *hal_srng = soc->tcl_data_ring[tx_q->ring_id].hal_srng;
|
||||
uint16_t htt_tcl_metadata = 0;
|
||||
|
||||
HTT_TX_TCL_METADATA_VALID_HTT_SET(htt_tcl_metadata, 0);
|
||||
/* Setup Tx descriptor for an MSDU, and MSDU extension descriptor */
|
||||
tx_desc = dp_tx_prepare_desc_single(vdev, nbuf, tx_q->desc_pool_id, meta_data);
|
||||
if (!tx_desc) {
|
||||
@@ -862,9 +865,17 @@ static qdf_nbuf_t dp_tx_send_msdu_single(struct dp_vdev *vdev, qdf_nbuf_t nbuf,
|
||||
goto fail_return;
|
||||
}
|
||||
|
||||
if (qdf_unlikely(peer_id != HTT_INVALID_PEER)) {
|
||||
HTT_TX_TCL_METADATA_TYPE_SET(htt_tcl_metadata,
|
||||
HTT_TCL_METADATA_TYPE_PEER_BASED);
|
||||
HTT_TX_TCL_METADATA_PEER_ID_SET(htt_tcl_metadata,
|
||||
peer_id);
|
||||
} else
|
||||
htt_tcl_metadata = vdev->htt_tcl_metadata;
|
||||
|
||||
/* Enqueue the Tx MSDU descriptor to HW for transmit */
|
||||
status = dp_tx_hw_enqueue(soc, vdev, tx_desc, tid,
|
||||
vdev->htt_tcl_metadata, tx_q->ring_id);
|
||||
htt_tcl_metadata, tx_q->ring_id);
|
||||
|
||||
if (status != QDF_STATUS_SUCCESS) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
|
||||
@@ -1160,6 +1171,49 @@ void dp_tx_extract_mesh_meta_data(struct dp_vdev *vdev, qdf_nbuf_t nbuf,
|
||||
|
||||
#endif
|
||||
|
||||
/**
|
||||
* dp_tx_prepare_nawds(): Tramit NAWDS frames
|
||||
* @vdev: dp_vdev handle
|
||||
* @nbuf: skb
|
||||
* @tid: TID from HLOS for overriding default DSCP-TID mapping
|
||||
* @tx_q: Tx queue to be used for this Tx frame
|
||||
* @meta_data: Meta date for mesh
|
||||
* @peer_id: peer_id of the peer in case of NAWDS frames
|
||||
*
|
||||
* return: NULL on success nbuf on failure
|
||||
*/
|
||||
static qdf_nbuf_t dp_tx_prepare_nawds(struct dp_vdev *vdev, qdf_nbuf_t nbuf,
|
||||
uint8_t tid, struct dp_tx_queue *tx_q, uint32_t *meta_data,
|
||||
uint32_t peer_id)
|
||||
{
|
||||
struct dp_peer *peer = NULL;
|
||||
qdf_nbuf_t nbuf_copy;
|
||||
TAILQ_FOREACH(peer, &vdev->peer_list, peer_list_elem) {
|
||||
if ((peer->peer_ids[0] != HTT_INVALID_PEER) &&
|
||||
(peer->nawds_enabled || peer->bss_peer)) {
|
||||
nbuf_copy = qdf_nbuf_copy(nbuf);
|
||||
if (!nbuf_copy) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP,
|
||||
QDF_TRACE_LEVEL_ERROR,
|
||||
"nbuf copy failed");
|
||||
}
|
||||
|
||||
peer_id = peer->peer_ids[0];
|
||||
nbuf_copy = dp_tx_send_msdu_single(vdev, nbuf_copy, tid,
|
||||
tx_q, meta_data, peer_id);
|
||||
if (nbuf_copy != NULL) {
|
||||
qdf_nbuf_free(nbuf);
|
||||
return nbuf_copy;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (peer_id == HTT_INVALID_PEER)
|
||||
return nbuf;
|
||||
|
||||
qdf_nbuf_free(nbuf);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* dp_tx_send() - Transmit a frame on a given VAP
|
||||
* @vap_dev: DP vdev handle
|
||||
@@ -1174,10 +1228,11 @@ void dp_tx_extract_mesh_meta_data(struct dp_vdev *vdev, qdf_nbuf_t nbuf,
|
||||
*/
|
||||
qdf_nbuf_t dp_tx_send(void *vap_dev, qdf_nbuf_t nbuf)
|
||||
{
|
||||
struct ether_header *eh;
|
||||
struct ether_header *eh = NULL;
|
||||
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;
|
||||
uint16_t peer_id = HTT_INVALID_PEER;
|
||||
|
||||
qdf_mem_set(&msdu_info, sizeof(msdu_info), 0x0);
|
||||
qdf_mem_set(&seg_info, sizeof(seg_info), 0x0);
|
||||
@@ -1294,6 +1349,16 @@ qdf_nbuf_t dp_tx_send(void *vap_dev, qdf_nbuf_t nbuf)
|
||||
|
||||
}
|
||||
|
||||
if (vdev->nawds_enabled) {
|
||||
eh = (struct ether_header *)qdf_nbuf_data(nbuf);
|
||||
if (DP_FRAME_IS_MULTICAST((eh)->ether_dhost)) {
|
||||
nbuf = dp_tx_prepare_nawds(vdev, nbuf, msdu_info.tid,
|
||||
&msdu_info.tx_queue,
|
||||
msdu_info.meta_data, peer_id);
|
||||
return nbuf;
|
||||
}
|
||||
}
|
||||
|
||||
/* Single linear frame */
|
||||
/*
|
||||
* If nbuf is a simple linear frame, use send_single function to
|
||||
@@ -1301,7 +1366,7 @@ qdf_nbuf_t dp_tx_send(void *vap_dev, qdf_nbuf_t nbuf)
|
||||
* SRNG. There is no need to setup a MSDU extension descriptor.
|
||||
*/
|
||||
nbuf = dp_tx_send_msdu_single(vdev, nbuf, msdu_info.tid,
|
||||
&msdu_info.tx_queue, msdu_info.meta_data);
|
||||
&msdu_info.tx_queue, msdu_info.meta_data, peer_id);
|
||||
|
||||
return nbuf;
|
||||
|
||||
|
@@ -104,6 +104,10 @@ union dp_rx_desc_list_elem_t;
|
||||
(_a)[4] == 0xff && \
|
||||
(_a)[5] == 0xff)
|
||||
#define IS_LLC_PRESENT(typeorlen) ((typeorlen) >= 0x600)
|
||||
#define DP_FRAME_FC0_TYPE_MASK 0x0c
|
||||
#define DP_FRAME_FC0_TYPE_DATA 0x08
|
||||
#define DP_FRAME_IS_DATA(_frame) \
|
||||
(((_frame)->i_fc[0] & DP_FRAME_FC0_TYPE_MASK) == DP_FRAME_FC0_TYPE_DATA)
|
||||
|
||||
/**
|
||||
* macros to convert hw mac id to sw mac id:
|
||||
@@ -968,4 +972,18 @@ struct dp_peer {
|
||||
TAILQ_HEAD(, dp_ast_entry) ast_entry_list;
|
||||
/* TBD */
|
||||
};
|
||||
|
||||
#ifdef CONFIG_WIN
|
||||
/*
|
||||
* dp_invalid_peer_msg
|
||||
* @nbuf: data buffer
|
||||
* @wh: 802.11 header
|
||||
* @vdev_id: id of vdev
|
||||
*/
|
||||
struct dp_invalid_peer_msg {
|
||||
qdf_nbuf_t nbuf;
|
||||
struct ieee80211_frame *wh;
|
||||
uint8_t vdev_id;
|
||||
};
|
||||
#endif
|
||||
#endif /* _DP_TYPES_H_ */
|
||||
|
Reference in New Issue
Block a user