From 277f45e2b1a4d94bf6d0dd7db0bbd26a2187c442 Mon Sep 17 00:00:00 2001 From: Kalyan Tallapragada Date: Mon, 30 Jan 2017 14:25:27 +0530 Subject: [PATCH] qcacmn: Add support to handle RAW packets in RX path API to handle pkts received on vdev which has RAW mode enabled. Currently supports only MPDU with single MSDU. Change-Id: Ife00699646bd97c5de0021fc32db434a544058f6 CRs-Fixed: 1111781 --- dp/wifi3.0/dp_main.c | 30 +++++++++++++++++ dp/wifi3.0/dp_rx.c | 66 +++++++++++++++++++++++++++++++++++++- qdf/inc/qdf_nbuf.h | 52 +++++++++++++++++++++++++++--- qdf/linux/src/i_qdf_nbuf.h | 14 +++++++- wmi/src/wmi_unified_tlv.c | 2 ++ 5 files changed, 158 insertions(+), 6 deletions(-) diff --git a/dp/wifi3.0/dp_main.c b/dp/wifi3.0/dp_main.c index ccec8eab0bb2..b61feae7ce40 100644 --- a/dp/wifi3.0/dp_main.c +++ b/dp/wifi3.0/dp_main.c @@ -1589,6 +1589,34 @@ static void dp_peer_setup_wifi3(struct cdp_vdev *vdev_hdl, void *peer_hdl) return; } +/* + * dp_set_vdev_tx_encap_type() - set the encap type of the vdev + * @vdev_handle: virtual device object + * @htt_pkt_type: type of pkt + * + * Return: void + */ +static void dp_set_vdev_tx_encap_type(struct cdp_vdev *vdev_handle, + enum htt_cmn_pkt_type val) +{ + struct dp_vdev *vdev = (struct dp_vdev *)vdev_handle; + vdev->tx_encap_type = val; +} + +/* + * dp_set_vdev_rx_decap_type() - set the decap type of the vdev + * @vdev_handle: virtual device object + * @htt_pkt_type: type of pkt + * + * Return: void + */ +static void dp_set_vdev_rx_decap_type(struct cdp_vdev *vdev_handle, + enum htt_cmn_pkt_type val) +{ + struct dp_vdev *vdev = (struct dp_vdev *)vdev_handle; + vdev->rx_decap_type = val; +} + /* * dp_peer_authorize() - authorize txrx peer * @peer_handle: Datapath peer handle @@ -1824,6 +1852,8 @@ static struct cdp_cmn_ops dp_ops_cmn = { static struct cdp_ctrl_ops dp_ops_ctrl = { .txrx_peer_authorize = dp_peer_authorize, + .txrx_set_vdev_rx_decap_type = dp_set_vdev_rx_decap_type, + .txrx_set_tx_encap_type = dp_set_vdev_tx_encap_type, /* TODO: Add other functions */ }; diff --git a/dp/wifi3.0/dp_rx.c b/dp/wifi3.0/dp_rx.c index 5745559c7b73..10887de4ae11 100644 --- a/dp/wifi3.0/dp_rx.c +++ b/dp/wifi3.0/dp_rx.c @@ -159,6 +159,51 @@ QDF_STATUS dp_rx_buffers_replenish(struct dp_soc *dp_soc, uint32_t mac_id, return QDF_STATUS_SUCCESS; } +/* + * dp_rx_deliver_raw() - process RAW mode pkts and hand over the + * pkts to RAW mode simulation to + * decapsulate the pkt. + * + * @vdev: vdev on which RAW mode is enabled + * @nbuf_list: list of RAW pkts to process + * + * Return: void + */ +static void +dp_rx_deliver_raw(struct dp_vdev *vdev, qdf_nbuf_t nbuf_list) +{ + qdf_nbuf_t deliver_list_head = NULL; + qdf_nbuf_t deliver_list_tail = NULL; + qdf_nbuf_t nbuf; + + nbuf = nbuf_list; + while (nbuf) { + qdf_nbuf_t next = qdf_nbuf_next(nbuf); + + DP_RX_LIST_APPEND(deliver_list_head, deliver_list_tail, nbuf); + + /* + * reset the chfrag_start and chfrag_end bits in nbuf cb + * as this is a non-amsdu pkt and RAW mode simulation expects + * these bit s to be 0 for non-amsdu pkt. + */ + if (qdf_nbuf_is_chfrag_start(nbuf) && + qdf_nbuf_is_chfrag_end(nbuf)) { + qdf_nbuf_set_chfrag_start(nbuf, 0); + qdf_nbuf_set_chfrag_end(nbuf, 0); + } + + nbuf = next; + } + + vdev->osif_rsim_rx_decap(vdev->osif_vdev, &deliver_list_head, + &deliver_list_tail); + + vdev->osif_rx(vdev->osif_vdev, deliver_list_head); +} + + + /** * dp_rx_intrabss_fwd() - Implements the Intra-BSS forwarding logic * @@ -208,6 +253,7 @@ dp_rx_process(struct dp_soc *soc, void *hal_ring, uint32_t quota) struct dp_peer *peer = NULL; struct dp_vdev *vdev = NULL; struct hal_rx_mpdu_desc_info mpdu_desc_info; + struct hal_rx_msdu_desc_info msdu_desc_info; enum hal_reo_error_status error; uint32_t pkt_len; static uint32_t peer_mdata; @@ -292,6 +338,22 @@ dp_rx_process(struct dp_soc *soc, void *hal_ring, uint32_t quota) goto fail; } + /* Get MSDU DESC info */ + hal_rx_msdu_desc_info_get(ring_desc, &msdu_desc_info); + + /* + * save msdu flags first, last and continuation msdu in + * nbuf->cb + */ + if (msdu_desc_info.msdu_flags & HAL_MSDU_F_FIRST_MSDU_IN_MPDU) + qdf_nbuf_set_chfrag_start(rx_desc->nbuf, 1); + + if (msdu_desc_info.msdu_flags & HAL_MSDU_F_MSDU_CONTINUATION) + qdf_nbuf_set_chfrag_cont(rx_desc->nbuf, 1); + + if (msdu_desc_info.msdu_flags & HAL_MSDU_F_LAST_MSDU_IN_MPDU) + qdf_nbuf_set_chfrag_end(rx_desc->nbuf, 1); + qdf_nbuf_queue_add(&vdev->rxq, rx_desc->nbuf); fail: dp_rx_add_to_free_desc_list(&head, &tail, rx_desc); @@ -425,7 +487,9 @@ done: nbuf); } - if (qdf_likely(vdev->osif_rx) && deliver_list_head) + if (qdf_unlikely(vdev->rx_decap_type == htt_pkt_type_raw)) + dp_rx_deliver_raw(vdev, deliver_list_head); + else if (qdf_likely(vdev->osif_rx) && deliver_list_head) vdev->osif_rx(vdev->osif_vdev, deliver_list_head); } diff --git a/qdf/inc/qdf_nbuf.h b/qdf/inc/qdf_nbuf.h index 0c965b58469f..3becfd321b88 100644 --- a/qdf/inc/qdf_nbuf.h +++ b/qdf/inc/qdf_nbuf.h @@ -555,8 +555,12 @@ qdf_nbuf_frag_push_head(qdf_nbuf_t buf, #define qdf_nbuf_num_frags_init(_nbuf) __qdf_nbuf_num_frags_init((_nbuf)) -/* For efficiency, it is the responsibility of the caller to ensure that val - * is either 0 or 1. +/** + * qdf_nbuf_set_chfrag_start() - set msdu start bit + * @buf: Network buffer + * @val: 0/1 + * + * Return: void */ static inline void qdf_nbuf_set_chfrag_start(qdf_nbuf_t buf, uint8_t val) @@ -564,19 +568,59 @@ qdf_nbuf_set_chfrag_start(qdf_nbuf_t buf, uint8_t val) __qdf_nbuf_set_chfrag_start(buf, val); } +/** + * qdf_nbuf_is_chfrag_start() - get msdu start bit + * @buf: Network buffer + * + * Return: integer value - 0/1 + */ static inline int qdf_nbuf_is_chfrag_start(qdf_nbuf_t buf) { return __qdf_nbuf_is_chfrag_start(buf); } -/* For efficiency, it is the responsibility of the caller to ensure that val - * is either 0 or 1. +/** + * qdf_nbuf_set_chfrag_cont() - set msdu continuation bit + * @buf: Network buffer + * @val: 0/1 + * + * Return: void + */ +static inline void +qdf_nbuf_set_chfrag_cont(qdf_nbuf_t buf, uint8_t val) +{ + __qdf_nbuf_set_chfrag_cont(buf, val); +} + +/** + * qdf_nbuf_is_chfrag_cont() - get msdu continuation bit + * @buf: Network buffer + * + * Return: integer value - 0/1 + */ +static inline int qdf_nbuf_is_chfrag_cont(qdf_nbuf_t buf) +{ + return __qdf_nbuf_is_chfrag_cont(buf); +} + +/** + * qdf_nbuf_set_chfrag_end() - set msdu end bit + * @buf: Network buffer + * @val: 0/1 + * + * Return: void */ static inline void qdf_nbuf_set_chfrag_end(qdf_nbuf_t buf, uint8_t val) { __qdf_nbuf_set_chfrag_end(buf, val); } +/** + * qdf_nbuf_is_chfrag_end() - set msdu end bit + * @buf: Network buffer + * + * Return: integer value - 0/1 + */ static inline int qdf_nbuf_is_chfrag_end(qdf_nbuf_t buf) { return __qdf_nbuf_is_chfrag_end(buf); diff --git a/qdf/linux/src/i_qdf_nbuf.h b/qdf/linux/src/i_qdf_nbuf.h index 7d7a4839a10c..fe7659b99ba2 100644 --- a/qdf/linux/src/i_qdf_nbuf.h +++ b/qdf/linux/src/i_qdf_nbuf.h @@ -165,9 +165,10 @@ struct qdf_nbuf_cb { flag_nbuf:1, num:1, flag_chfrag_start:1, + flag_chfrag_cont:1, flag_chfrag_end:1, flag_ext_header:1, - reserved:2; + reserved:1; } bits; uint8_t u8; } flags; @@ -257,6 +258,9 @@ struct qdf_nbuf_cb { #define QDF_NBUF_CB_TX_EXTRA_FRAG_FLAGS_CHFRAG_START(skb) \ (((struct qdf_nbuf_cb *) \ ((skb)->cb))->u.tx.extra_frag.flags.bits.flag_chfrag_start) +#define QDF_NBUF_CB_TX_EXTRA_FRAG_FLAGS_CHFRAG_CONT(skb) \ + (((struct qdf_nbuf_cb *) \ + ((skb)->cb))->u.tx.extra_frag.flags.bits.flag_chfrag_cont) #define QDF_NBUF_CB_TX_EXTRA_FRAG_FLAGS_CHFRAG_END(skb) \ (((struct qdf_nbuf_cb *) \ ((skb)->cb))->u.tx.extra_frag.flags.bits.flag_chfrag_end) @@ -407,6 +411,14 @@ typedef void (*qdf_nbuf_trace_update_t)(char *); #define __qdf_nbuf_is_chfrag_start(skb) \ (QDF_NBUF_CB_TX_EXTRA_FRAG_FLAGS_CHFRAG_START((skb))) +#define __qdf_nbuf_set_chfrag_cont(skb, val) \ + do { \ + (QDF_NBUF_CB_TX_EXTRA_FRAG_FLAGS_CHFRAG_CONT((skb))) = val; \ + } while (0) + +#define __qdf_nbuf_is_chfrag_cont(skb) \ + (QDF_NBUF_CB_TX_EXTRA_FRAG_FLAGS_CHFRAG_CONT((skb))) + #define __qdf_nbuf_set_chfrag_end(skb, val) \ do { \ (QDF_NBUF_CB_TX_EXTRA_FRAG_FLAGS_CHFRAG_END((skb))) = val; \ diff --git a/wmi/src/wmi_unified_tlv.c b/wmi/src/wmi_unified_tlv.c index 310f3f081b5b..debf80adf10a 100644 --- a/wmi/src/wmi_unified_tlv.c +++ b/wmi/src/wmi_unified_tlv.c @@ -14707,6 +14707,8 @@ static void populate_vdev_param_tlv(uint32_t *vdev_param) WMI_VDEV_PARAM_MCC_BROADCAST_PROBE_ENABLE; vdev_param[wmi_vdev_param_mgmt_tx_power] = WMI_VDEV_PARAM_MGMT_TX_POWER; vdev_param[wmi_vdev_param_beacon_rate] = WMI_VDEV_PARAM_BEACON_RATE; + vdev_param[wmi_vdev_param_rx_decap_type] = WMI_VDEV_PARAM_RX_DECAP_TYPE; + vdev_param[wmi_vdev_param_tx_encap_type] = WMI_VDEV_PARAM_TX_ENCAP_TYPE; } #endif