diff --git a/dp/inc/cdp_txrx_ctrl.h b/dp/inc/cdp_txrx_ctrl.h index 228ba4a04d..187ab87daf 100644 --- a/dp/inc/cdp_txrx_ctrl.h +++ b/dp/inc/cdp_txrx_ctrl.h @@ -26,6 +26,7 @@ #define _CDP_TXRX_CTRL_H_ #include "cdp_txrx_handle.h" #include "cdp_txrx_cmn_struct.h" +#include "cdp_txrx_cmn.h" #include "cdp_txrx_ops.h" static inline int cdp_is_target_ar900b @@ -702,6 +703,67 @@ cdp_get_pldev(ol_txrx_soc_handle soc, return soc->ops->ctrl_ops->txrx_get_pldev(pdev); } +#ifdef WLAN_SUPPORT_RX_PROTOCOL_TYPE_TAG +/** + * cdp_update_pdev_rx_protocol_tag() - wrapper function to set the protocol + * tag in CDP layer from cfg layer + * @soc: SOC TXRX handle + * @pdev: CDP pdev pointer + * @protocol_mask: Bitmap for protocol for which tagging is enabled + * @protocol_type: Protocol type for which the tag should be update + * @tag: Actual tag value for the given prototype + * Return: Returns QDF_STATUS_SUCCESS/FAILURE + */ +static inline QDF_STATUS +cdp_update_pdev_rx_protocol_tag(ol_txrx_soc_handle soc, + struct cdp_pdev *pdev, uint32_t protocol_mask, + uint16_t protocol_type, uint16_t tag) +{ + if (!soc || !soc->ops) { + dp_err("Invalid SOC instance"); + QDF_BUG(0); + return QDF_STATUS_E_FAILURE; + } + + if (!soc->ops->ctrl_ops || + !soc->ops->ctrl_ops->txrx_update_pdev_rx_protocol_tag) + return QDF_STATUS_E_FAILURE; + + return soc->ops->ctrl_ops->txrx_update_pdev_rx_protocol_tag + (pdev, protocol_mask, protocol_type, tag); +} + +#ifdef WLAN_SUPPORT_RX_TAG_STATISTICS +/** + * cdp_dump_pdev_rx_protocol_tag_stats() - wrapper function to dump the protocol + tag statistics for given or all protocols + * @soc: SOC TXRX handle + * @pdev: CDP pdev pointer + * @protocol_type: Protocol type for which the tag should be update + * Return: Returns QDF_STATUS_SUCCESS/FAILURE + */ +static inline QDF_STATUS +cdp_dump_pdev_rx_protocol_tag_stats(ol_txrx_soc_handle soc, + struct cdp_pdev *pdev, + uint16_t protocol_type) +{ + if (!soc || !soc->ops) { + dp_err("Invalid SOC instance"); + QDF_BUG(0); + return QDF_STATUS_E_FAILURE; + } + + if (!soc->ops->ctrl_ops || + !soc->ops->ctrl_ops->txrx_dump_pdev_rx_protocol_tag_stats) + return QDF_STATUS_E_FAILURE; + + soc->ops->ctrl_ops->txrx_dump_pdev_rx_protocol_tag_stats(pdev, + protocol_type); + return QDF_STATUS_SUCCESS; +} +#endif /* WLAN_SUPPORT_RX_TAG_STATISTICS */ +#endif /* WLAN_SUPPORT_RX_PROTOCOL_TYPE_TAG */ + #ifdef ATH_SUPPORT_NAC_RSSI /** * cdp_vdev_config_for_nac_rssi(): To invoke dp callback for nac rssi config diff --git a/dp/inc/cdp_txrx_ops.h b/dp/inc/cdp_txrx_ops.h index 5ce82fba31..17e51be681 100644 --- a/dp/inc/cdp_txrx_ops.h +++ b/dp/inc/cdp_txrx_ops.h @@ -649,6 +649,17 @@ struct cdp_ctrl_ops { *txrx_pdev_handle, char *macaddr, uint8_t enb_dsb); void (*calculate_delay_stats)(struct cdp_vdev *vdev, qdf_nbuf_t nbuf); +#ifdef WLAN_SUPPORT_RX_PROTOCOL_TYPE_TAG + QDF_STATUS (*txrx_update_pdev_rx_protocol_tag)( + struct cdp_pdev *txrx_pdev_handle, + uint32_t protocol_mask, uint16_t protocol_type, + uint16_t tag); +#ifdef WLAN_SUPPORT_RX_TAG_STATISTICS + void (*txrx_dump_pdev_rx_protocol_tag_stats)( + struct cdp_pdev *txrx_pdev_handle, + uint16_t protocol_type); +#endif /* WLAN_SUPPORT_RX_TAG_STATISTICS */ +#endif /* WLAN_SUPPORT_RX_PROTOCOL_TYPE_TAG */ }; struct cdp_me_ops { diff --git a/dp/inc/cdp_txrx_stats_struct.h b/dp/inc/cdp_txrx_stats_struct.h index 6e97fbf26f..1d351ab704 100644 --- a/dp/inc/cdp_txrx_stats_struct.h +++ b/dp/inc/cdp_txrx_stats_struct.h @@ -1138,6 +1138,27 @@ struct cdp_htt_rx_pdev_stats { struct cdp_htt_rx_pdev_fw_stats_phy_err_tlv fw_stats_phy_err_tlv; }; +#ifdef WLAN_SUPPORT_RX_PROTOCOL_TYPE_TAG +/* Since protocol type enumeration value is passed as CCE metadata + * to firmware, add a constant offset before passing it to firmware + */ +#define RX_PROTOCOL_TAG_START_OFFSET 128 +/* This should align with packet type enumerations in ieee80211_ioctl.h + * and wmi_unified_param.h files + */ +#define RX_PROTOCOL_TAG_MAX 24 +/* Macro that should be used to dump the statistics counter for all + * protocol types + */ +#define RX_PROTOCOL_TAG_ALL 0xff + +#ifdef WLAN_SUPPORT_RX_TAG_STATISTICS +struct cdp_pdev_rx_protocol_tag_stats { + uint32_t tag_ctr; +}; +#endif /* WLAN_SUPPORT_RX_TAG_STATISTICS */ +#endif /* WLAN_SUPPORT_RX_PROTOCOL_TYPE_TAG */ + /* struct cdp_pdev_stats - pdev stats * @msdu_not_done: packets dropped because msdu done bit not set * @mec:Multicast Echo check @@ -1213,6 +1234,12 @@ struct cdp_pdev_stats { /* Received wdi messages from fw */ uint32_t wdi_event[CDP_WDI_NUM_EVENTS]; struct cdp_tid_stats tid_stats; + +#if defined(WLAN_SUPPORT_RX_TAG_STATISTICS) && \ + defined(WLAN_SUPPORT_RX_PROTOCOL_TYPE_TAG) + struct cdp_pdev_rx_protocol_tag_stats + rx_protocol_tag_stats[RX_PROTOCOL_TAG_MAX]; +#endif /* WLAN_SUPPORT_RX_TAG_STATISTICS */ }; #ifndef BIG_ENDIAN_HOST diff --git a/dp/wifi3.0/dp_main.c b/dp/wifi3.0/dp_main.c index fb0efed19a..a8031373ca 100644 --- a/dp/wifi3.0/dp_main.c +++ b/dp/wifi3.0/dp_main.c @@ -9525,6 +9525,90 @@ dp_enable_peer_based_pktlog( return QDF_STATUS_SUCCESS; } +#ifdef WLAN_SUPPORT_RX_PROTOCOL_TYPE_TAG +/** + * dp_update_pdev_rx_protocol_tag - Add/remove a protocol tag that should be + * applied to the desired protocol type packets + * @txrx_pdev_handle: cdp_pdev handle + * @enable_rx_protocol_tag - bitmask that indicates what protocol types + * are enabled for tagging. zero indicates disable feature, non-zero indicates + * enable feature + * @protocol_type: new protocol type for which the tag is being added + * @tag: user configured tag for the new protocol + * + * Return: QDF_STATUS + */ +static QDF_STATUS +dp_update_pdev_rx_protocol_tag(struct cdp_pdev *pdev_handle, + uint32_t enable_rx_protocol_tag, + uint16_t protocol_type, + uint16_t tag) +{ + struct dp_pdev *pdev = (struct dp_pdev *)pdev_handle; + /* + * dynamically enable/disable tagging based on enable_rx_protocol_tag + * flag. + */ + if (enable_rx_protocol_tag) { + /* Tagging for one or more protocols has been set by user */ + pdev->rx_protocol_tagging_enabled = true; + } else { + /* + * No protocols being tagged, disable feature till next add + * operation + */ + pdev->rx_protocol_tagging_enabled = false; + } + + if (tag == 0) { + /* + * In case of tag deletion, clear the stats for given + * protocol type. + */ + DP_STATS_UPD(pdev, + rx_protocol_tag_stats[protocol_type].tag_ctr, 0); + } + + pdev->rx_proto_tag_map[protocol_type].tag = tag; + + return QDF_STATUS_SUCCESS; +} + +#ifdef WLAN_SUPPORT_RX_TAG_STATISTICS +static void +dp_dump_pdev_rx_protocol_tag_stats(struct cdp_pdev *pdev_handle, + uint16_t protocol_type) +{ + struct dp_pdev *pdev = (struct dp_pdev *)pdev_handle; + + if (protocol_type != RX_PROTOCOL_TAG_ALL && + protocol_type >= RX_PROTOCOL_TAG_MAX) { + DP_PRINT_STATS("%s : Invalid protocol type : %u\n", + __func__, protocol_type); + return; + } + + if (protocol_type == RX_PROTOCOL_TAG_ALL) { + uint8_t protocol_index = 0; + + for (protocol_index = 0; protocol_index < RX_PROTOCOL_TAG_MAX; + protocol_index++) { + DP_PRINT_STATS("PROTO: %d, TAG: %u COUNT = %u\n", + protocol_index, + pdev->rx_proto_tag_map[protocol_index].tag, + pdev->stats. + rx_protocol_tag_stats[protocol_index].tag_ctr); + } + } else { + DP_PRINT_STATS("PROTO: %d, TAG: %u COUNT = %u\n", + protocol_type, + pdev->rx_proto_tag_map[protocol_type].tag, + pdev->stats.rx_protocol_tag_stats[protocol_type].tag_ctr); + } +} +#endif /* WLAN_SUPPORT_RX_TAG_STATISTICS */ +#endif /* WLAN_SUPPORT_RX_PROTOCOL_TYPE_TAG */ + static QDF_STATUS dp_peer_map_attach_wifi3(struct cdp_soc_t *soc_hdl, uint32_t max_peers, uint32_t max_ast_index, @@ -9973,6 +10057,13 @@ static struct cdp_ctrl_ops dp_ops_ctrl = { .txrx_get_vdev_param = dp_get_vdev_param, .enable_peer_based_pktlog = dp_enable_peer_based_pktlog, .calculate_delay_stats = dp_calculate_delay_stats, +#ifdef WLAN_SUPPORT_RX_PROTOCOL_TYPE_TAG + .txrx_update_pdev_rx_protocol_tag = dp_update_pdev_rx_protocol_tag, +#ifdef WLAN_SUPPORT_RX_TAG_STATISTICS + .txrx_dump_pdev_rx_protocol_tag_stats = + dp_dump_pdev_rx_protocol_tag_stats, +#endif /* WLAN_SUPPORT_RX_TAG_STATISTICS */ +#endif /* WLAN_SUPPORT_RX_PROTOCOL_TYPE_TAG */ }; static struct cdp_me_ops dp_ops_me = { diff --git a/dp/wifi3.0/dp_rx.c b/dp/wifi3.0/dp_rx.c index dddd0bbae7..e1f7a440b4 100644 --- a/dp/wifi3.0/dp_rx.c +++ b/dp/wifi3.0/dp_rx.c @@ -1856,6 +1856,9 @@ done: dp_set_rx_queue(nbuf, ring_id); + /* Update the protocol tag in SKB based on CCE metadata */ + dp_rx_update_protocol_tag(soc, vdev, nbuf, rx_tlv_hdr, true); + /* * HW structures call this L3 header padding -- * even though this is actually the offset from diff --git a/dp/wifi3.0/dp_rx.h b/dp/wifi3.0/dp_rx.h index 756fe9f5dc..4e0fe4485b 100644 --- a/dp/wifi3.0/dp_rx.h +++ b/dp/wifi3.0/dp_rx.h @@ -929,6 +929,181 @@ static inline bool check_qwrap_multicast_loopback(struct dp_vdev *vdev, } #endif +#if defined(WLAN_SUPPORT_RX_TAG_STATISTICS) && \ + defined(WLAN_SUPPORT_RX_PROTOCOL_TYPE_TAG) +/* + * dp_rx_update_rx_protocol_tag_stats() - Increments the protocol tag stats + * for the given protocol type + * + * @soc: core txrx main context + * @pdev: TXRX pdev context for which the stats should be incremented + * @protocol_index: Protocol index for which the stats should be incremented + * Return: void + */ +static inline void dp_rx_update_rx_protocol_tag_stats(struct dp_pdev *pdev, + uint16_t protocol_index) +{ + DP_STATS_INC(pdev, rx_protocol_tag_stats[protocol_index].tag_ctr, 1); +} +#else +static inline void dp_rx_update_rx_protocol_tag_stats(struct dp_pdev *pdev, + uint16_t protocol_index) +{ +} +#endif /* WLAN_SUPPORT_RX_TAG_STATISTICS */ + +/* + * dp_rx_update_protocol_tag() - Reads CCE metadata from the RX MSDU end TLV + * and set the corresponding tag in QDF packet + * + * @soc : core txrx main context + * @vdev : vdev on which the packet is received + * @nbuf : QDF packet buffer on which the protocol tag should be set + * @rx_tlv_hdr : base address where the RX TLVs starts + * @update_stats : Flag to indicate whether to update stats or not + * Return : void + */ +#ifdef WLAN_SUPPORT_RX_PROTOCOL_TYPE_TAG +static inline void +dp_rx_update_protocol_tag(struct dp_soc *soc, struct dp_vdev *vdev, + qdf_nbuf_t nbuf, uint8_t *rx_tlv_hdr, + bool update_stats) +{ + uint16_t cce_metadata = RX_PROTOCOL_TAG_START_OFFSET; + bool cce_match = false; + struct dp_pdev *pdev = vdev->pdev; + uint16_t protocol_tag = 0; + + if (qdf_unlikely(pdev->rx_protocol_tagging_enabled)) { + /* + * In case of raw frames, rx_attention and rx_msdu_end tlv + * may be stale or invalid. Do not tag such frames. + * Default decap_type is set to ethernet for monitor vdev, + * therefore, cannot check decap_type for monitor mode. + * We will call this only for eth frames from dp_rx_mon_dest.c. + */ + if (qdf_unlikely((pdev->monitor_vdev && + pdev->monitor_vdev == vdev) || + (vdev->rx_decap_type == htt_cmn_pkt_type_ethernet))) { + /* + * Check whether HW has filled in the CCE metadata in + * this packet, if not filled, just return + */ + if (qdf_unlikely( + hal_rx_msdu_cce_match_get(rx_tlv_hdr))) { + cce_match = true; + /* Get the cce_metadata from RX MSDU TLV */ + cce_metadata = + (hal_rx_msdu_cce_metadata_get(rx_tlv_hdr) & + RX_MSDU_END_16_CCE_METADATA_MASK); + /* + * Received CCE metadata should be within the + * valid limits + */ + qdf_assert_always((cce_metadata >= + RX_PROTOCOL_TAG_START_OFFSET) && + (cce_metadata < + (RX_PROTOCOL_TAG_START_OFFSET + + RX_PROTOCOL_TAG_MAX))); + + /* + * The CCE metadata received is just the + * packet_type + RX_PROTOCOL_TAG_START_OFFSET + */ + cce_metadata -= RX_PROTOCOL_TAG_START_OFFSET; + + /* + * Update the QDF packet with the user-specified + * tag/metadata by looking up tag value for + * received protocol type. + */ + protocol_tag = + pdev->rx_proto_tag_map[cce_metadata].tag; + qdf_nbuf_set_rx_protocol_tag(nbuf, + protocol_tag); + if (qdf_unlikely(update_stats)) + dp_rx_update_rx_protocol_tag_stats( + pdev, cce_metadata); + } + } + + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_INFO_LOW, + "Seq:%u decap:%u CCE Match:%d ProtoID:%u Tag:%u US:%d", + hal_rx_get_rx_sequence(rx_tlv_hdr), + vdev->rx_decap_type, cce_match, cce_metadata, + protocol_tag, update_stats); + } +} +#else +static inline void +dp_rx_update_protocol_tag(struct dp_soc *soc, struct dp_vdev *vdev, + qdf_nbuf_t nbuf, uint8_t *rx_tlv_hdr, + bool update_stats) +{ + /* Stub API */ +} +#endif /* WLAN_SUPPORT_RX_PROTOCOL_TYPE_TAG */ + +/* + * dp_rx_mon_update_protocol_tag() - Performs necessary checks for monitor mode + * and then tags appropriate packets + * @soc : core txrx main context + * @vdev : pdev on which packet is received + * @msdu : QDF packet buffer on which the protocol tag should be set + * @rx_desc : base address where the RX TLVs start + * Return : void + */ +#ifdef WLAN_SUPPORT_RX_PROTOCOL_TYPE_TAG +static inline +void dp_rx_mon_update_protocol_tag(struct dp_soc *soc, struct dp_pdev *dp_pdev, + qdf_nbuf_t msdu, void *rx_desc) +{ + /* + * Update the protocol tag in SKB for packets received on BSS. + * Do not update tag stats since it would double actual received count + */ + if (qdf_unlikely(dp_pdev->rx_protocol_tagging_enabled && + dp_pdev->monitor_vdev && + (1 == dp_pdev->ppdu_info.rx_status.rxpcu_filter_pass) + )) { + uint32_t msdu_ppdu_id = + HAL_RX_HW_DESC_GET_PPDUID_GET(rx_desc); + + if (msdu_ppdu_id != + dp_pdev->ppdu_info.com_info.ppdu_id) { + QDF_TRACE( + QDF_MODULE_ID_DP, + QDF_TRACE_LEVEL_ERROR, + "msdu_ppdu_id=%x,com_info.ppdu_id=%x", + msdu_ppdu_id, + dp_pdev->ppdu_info.com_info.ppdu_id); + } else { + struct mon_rx_status *pmon_rx_status; + + pmon_rx_status = + &dp_pdev->ppdu_info.rx_status; + if (pmon_rx_status-> + frame_control_info_valid && + ((pmon_rx_status->frame_control & + IEEE80211_FC0_TYPE_MASK) == + IEEE80211_FC0_TYPE_DATA)) { + dp_rx_update_protocol_tag( + soc, + dp_pdev->monitor_vdev, + msdu, + rx_desc, false); + } + } + } +} +#else +static inline +void dp_rx_mon_update_protocol_tag(struct dp_soc *soc, struct dp_pdev *dp_pdev, + qdf_nbuf_t msdu, void *rx_desc) +{ + /* Stub API */ +} +#endif /* WLAN_SUPPORT_RX_PROTOCOL_TYPE_TAG */ /* * dp_rx_buffers_replenish() - replenish rxdma ring with rx nbufs * called during dp rx initialization diff --git a/dp/wifi3.0/dp_rx_err.c b/dp/wifi3.0/dp_rx_err.c index b4c50fd271..a7be2808f1 100644 --- a/dp/wifi3.0/dp_rx_err.c +++ b/dp/wifi3.0/dp_rx_err.c @@ -816,6 +816,13 @@ dp_rx_null_q_desc_handle(struct dp_soc *soc, qdf_nbuf_t nbuf, DP_STATS_INC_PKT(peer, rx.to_stack, 1, qdf_nbuf_len(nbuf)); + /* + * Update the protocol tag in SKB based on + * CCE metadata + */ + dp_rx_update_protocol_tag(soc, vdev, nbuf, + rx_tlv_hdr, true); + if (qdf_unlikely(hal_rx_msdu_end_da_is_mcbc_get( rx_tlv_hdr) && (vdev->rx_decap_type == @@ -992,6 +999,9 @@ process_rx: if (qdf_unlikely(vdev->rx_decap_type == htt_cmn_pkt_type_raw)) { dp_rx_deliver_raw(vdev, nbuf, peer); } else { + /* Update the protocol tag in SKB based on CCE metadata */ + dp_rx_update_protocol_tag(soc, vdev, nbuf, + rx_tlv_hdr, true); DP_STATS_INC(peer, rx.to_stack.num, 1); vdev->osif_rx(vdev->osif_vdev, nbuf); } diff --git a/dp/wifi3.0/dp_rx_mon_dest.c b/dp/wifi3.0/dp_rx_mon_dest.c index 8e97108263..0d62057c03 100644 --- a/dp/wifi3.0/dp_rx_mon_dest.c +++ b/dp/wifi3.0/dp_rx_mon_dest.c @@ -352,9 +352,8 @@ dp_rx_mon_mpdu_pop(struct dp_soc *soc, uint32_t mac_id, QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG, - "[%s] i=%d, ppdu_id=%x, num_msdus = %u\n", - __func__, i, *ppdu_id, - num_msdus); + "[%s] i=%d, ppdu_id=%x, num_msdus = %u", + __func__, i, *ppdu_id, num_msdus); if (is_first_msdu) { if (!HAL_RX_HW_DESC_MPDU_VALID( @@ -742,6 +741,9 @@ qdf_nbuf_t dp_rx_mon_restitch_mpdu_from_msdus(struct dp_soc *soc, is_first_frag = 0; } + /* Update protocol tag for MSDU */ + dp_rx_mon_update_protocol_tag(soc, dp_pdev, msdu_orig, rx_desc); + dest = qdf_nbuf_put_tail(prev_buf, msdu_llc_len + amsdu_pad); diff --git a/dp/wifi3.0/dp_types.h b/dp/wifi3.0/dp_types.h index fdd946ac86..d50887a643 100644 --- a/dp/wifi3.0/dp_types.h +++ b/dp/wifi3.0/dp_types.h @@ -1134,6 +1134,13 @@ struct ppdu_info { TAILQ_ENTRY(ppdu_info) ppdu_info_list_elem; }; +#ifdef WLAN_SUPPORT_RX_PROTOCOL_TYPE_TAG +struct rx_protocol_tag_map { + /* This is the user configured tag for the said protocol type */ + uint16_t tag; +}; +#endif /* WLAN_SUPPORT_RX_PROTOCOL_TYPE_TAG */ + /* PDEV level structure for data path */ struct dp_pdev { /** @@ -1430,6 +1437,19 @@ struct dp_pdev { /* unique cookie required for peer session */ uint32_t next_peer_cookie; +#ifdef WLAN_SUPPORT_RX_PROTOCOL_TYPE_TAG + /* + * Run time enabled when the first protocol tag is added, + * run time disabled when the last protocol tag is deleted + */ + bool rx_protocol_tagging_enabled; + + /* + * The protocol type is used as array index to save + * user provided tag info + */ + struct rx_protocol_tag_map rx_proto_tag_map[RX_PROTOCOL_TAG_MAX]; +#endif /* WLAN_SUPPORT_RX_PROTOCOL_TYPE_TAG */ }; struct dp_peer; diff --git a/hal/wifi3.0/hal_generic_api.h b/hal/wifi3.0/hal_generic_api.h index 5aa4cb2861..4459cfa887 100644 --- a/hal/wifi3.0/hal_generic_api.h +++ b/hal/wifi3.0/hal_generic_api.h @@ -1233,8 +1233,12 @@ hal_rx_status_get_tlv_info_generic(void *rx_tlv_hdr, void *ppduinfo, filter_category = HAL_RX_GET(rx_mpdu_start, RX_MPDU_INFO_0, RXPCU_MPDU_FILTER_IN_CATEGORY); - if (filter_category == 1) + + if (filter_category == 0) + ppdu_info->rx_status.rxpcu_filter_pass = 1; + else if (filter_category == 1) ppdu_info->rx_status.monitor_direct_used = 1; + break; } case WIFIRX_MPDU_END_E: diff --git a/hal/wifi3.0/hal_rx.h b/hal/wifi3.0/hal_rx.h index d00874d502..c4bf2eff77 100644 --- a/hal/wifi3.0/hal_rx.h +++ b/hal/wifi3.0/hal_rx.h @@ -852,6 +852,29 @@ hal_rx_attn_phy_ppdu_id_get(uint8_t *buf) return phy_ppdu_id; } +#define HAL_RX_ATTN_CCE_MATCH_GET(_rx_attn) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_attn, \ + RX_ATTENTION_1_CCE_MATCH_OFFSET)), \ + RX_ATTENTION_1_CCE_MATCH_MASK, \ + RX_ATTENTION_1_CCE_MATCH_LSB)) + +/* + * hal_rx_msdu_cce_match_get(): get CCE match bit + * from rx attention + * @buf: pointer to rx_pkt_tlvs + * Return: CCE match value + */ +static inline bool +hal_rx_msdu_cce_match_get(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_attention *rx_attn = &pkt_tlvs->attn_tlv.rx_attn; + bool cce_match_val; + + cce_match_val = HAL_RX_ATTN_CCE_MATCH_GET(rx_attn); + return cce_match_val; +} + /* * Get peer_meta_data from RX_MPDU_INFO within RX_MPDU_START */ @@ -1863,6 +1886,31 @@ hal_rx_msdu_end_last_msdu_get(uint8_t *buf) return last_msdu; } + +#define HAL_RX_MSDU_END_CCE_METADATA_GET(_rx_msdu_end) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_msdu_end, \ + RX_MSDU_END_16_CCE_METADATA_OFFSET)), \ + RX_MSDU_END_16_CCE_METADATA_MASK, \ + RX_MSDU_END_16_CCE_METADATA_LSB)) + +/** + * hal_rx_msdu_cce_metadata_get: API to get CCE metadata + * from rx_msdu_end TLV + * @ buf: pointer to the start of RX PKT TLV headers + * Return: last_msdu + */ + +static inline uint32_t +hal_rx_msdu_cce_metadata_get(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_msdu_end *msdu_end = &pkt_tlvs->msdu_end_tlv.rx_msdu_end; + uint32_t cce_metadata; + + cce_metadata = HAL_RX_MSDU_END_CCE_METADATA_GET(msdu_end); + return cce_metadata; +} + /******************************************************************************* * RX ERROR APIS ******************************************************************************/ @@ -2697,10 +2745,8 @@ uint16_t hal_rx_get_rx_sequence(uint8_t *buf) struct rx_mpdu_info *rx_mpdu_info = hal_rx_get_mpdu_info(pkt_tlvs); uint16_t seq_number = 0; - seq_number = - HAL_RX_MPDU_GET_SEQUENCE_NUMBER(rx_mpdu_info) >> 4; + seq_number = HAL_RX_MPDU_GET_SEQUENCE_NUMBER(rx_mpdu_info); - /* Skip first 4-bits for fragment number */ return seq_number; } diff --git a/qdf/inc/i_qdf_nbuf_api_m.h b/qdf/inc/i_qdf_nbuf_api_m.h index b3f622908b..150e40bb9b 100644 --- a/qdf/inc/i_qdf_nbuf_api_m.h +++ b/qdf/inc/i_qdf_nbuf_api_m.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2017 The Linux Foundation. All rights reserved. + * Copyright (c) 2014-2017,2019 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -55,4 +55,23 @@ static inline void qdf_nbuf_ipa_priv_set(qdf_nbuf_t buf, uint32_t priv) __qdf_nbuf_ipa_priv_set(buf, priv); } +/** + * qdf_nbuf_set_rx_protocol_tag() + * @buf: Network buffer + * @val: Value to be set + * Return: void + */ +static inline void qdf_nbuf_set_rx_protocol_tag(qdf_nbuf_t buf, uint32_t val) +{ +} + +/** + * qdf_nbuf_get_rx_protocol_tag() + * @buf: Network buffer + * Return: void + */ +static inline int qdf_nbuf_get_rx_protocol_tag(qdf_nbuf_t buf) +{ + return 0; +} #endif /* _QDF_NBUF_M_H */ diff --git a/qdf/inc/i_qdf_nbuf_api_w.h b/qdf/inc/i_qdf_nbuf_api_w.h index f1197c9a10..b9ce5e005d 100644 --- a/qdf/inc/i_qdf_nbuf_api_w.h +++ b/qdf/inc/i_qdf_nbuf_api_w.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2017 The Linux Foundation. All rights reserved. + * Copyright (c) 2014-2017,2019 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -64,4 +64,26 @@ qdf_nbuf_set_ext_cb(qdf_nbuf_t buf, void *ref) __qdf_nbuf_set_ext_cb(buf, ref); } +/** + * qdf_nbuf_set_rx_protocol_tag() - set given value in protocol_tag + * field of buf(skb->cb) + * @buf: Network buffer + * @val: Value to be set + * Return: void + */ +static inline void qdf_nbuf_set_rx_protocol_tag(qdf_nbuf_t buf, uint32_t val) +{ + __qdf_nbuf_set_rx_protocol_tag(buf, val); +} + +/** + * qdf_nbuf_get_rx_protocol_tag() - Get the value of protocol_tag + * field of buf(skb->cb) + * @buf: Network buffer + * Return: void + */ +static inline int qdf_nbuf_get_rx_protocol_tag(qdf_nbuf_t buf) +{ + return __qdf_nbuf_get_rx_protocol_tag(buf); +} #endif /* _QDF_NBUF_W_H */ diff --git a/qdf/inc/qdf_nbuf.h b/qdf/inc/qdf_nbuf.h index 893fa4bba4..66d1e480f4 100644 --- a/qdf/inc/qdf_nbuf.h +++ b/qdf/inc/qdf_nbuf.h @@ -226,6 +226,8 @@ * @chan_noise_floor: Channel Noise Floor for the pdev * @data_sequence_control_info_valid: field to indicate validity of seq control * @first_data_seq_ctrl: Sequence ctrl field of first data frame + * @rxpcu_filter_pass: Flag which indicates whether RX packets are received in + * BSS mode(not in promisc mode) */ struct mon_rx_status { uint64_t tsft; @@ -304,6 +306,7 @@ struct mon_rx_status { uint8_t data_sequence_control_info_valid; uint16_t first_data_seq_ctrl; uint8_t ltf_size; + uint8_t rxpcu_filter_pass; }; /** diff --git a/qdf/linux/src/i_qdf_nbuf.h b/qdf/linux/src/i_qdf_nbuf.h index 8c3af1ee20..557fa845b2 100644 --- a/qdf/linux/src/i_qdf_nbuf.h +++ b/qdf/linux/src/i_qdf_nbuf.h @@ -101,7 +101,10 @@ typedef union { * @rx.dev.priv_cb_w.fctx: ctx to handle special pkts defined by ftype * @rx.dev.priv_cb_w.msdu_len: length of RX packet * @rx.dev.priv_cb_w.peer_id: peer_id for RX packet - * @rx.dev.priv_cb_w.reserved1: reserved + * @rx.dev.priv_cb_w.protocol_tag: protocol tag set by application for + * received packet type + * @rx.dev.priv_cb_w.reserved1: reserved for flow tag set by application + * for 5 tuples received * * @rx.dev.priv_cb_m.tcp_seq_num: TCP sequence number * @rx.dev.priv_cb_m.tcp_ack_num: TCP ACK number @@ -207,7 +210,8 @@ struct qdf_nbuf_cb { void *fctx; uint16_t msdu_len; uint16_t peer_id; - uint32_t reserved1; + uint16_t protocol_tag; + uint16_t reserved1; } priv_cb_w; struct { /* ipa_owned bit is common between rx diff --git a/qdf/linux/src/i_qdf_nbuf_w.h b/qdf/linux/src/i_qdf_nbuf_w.h index e10d2dd01e..0ade4ef775 100644 --- a/qdf/linux/src/i_qdf_nbuf_w.h +++ b/qdf/linux/src/i_qdf_nbuf_w.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2014-2019 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -72,6 +72,16 @@ #define __qdf_nbuf_get_tx_fctx(skb) \ QDF_NBUF_CB_TX_FCTX((skb)) +#define QDF_NBUF_CB_RX_PROTOCOL_TAG(skb) \ + (((struct qdf_nbuf_cb *) \ + ((skb)->cb))->u.rx.dev.priv_cb_w.protocol_tag) + +#define __qdf_nbuf_set_rx_protocol_tag(skb, val) \ + ((QDF_NBUF_CB_RX_PROTOCOL_TAG((skb))) = val) + +#define __qdf_nbuf_get_rx_protocol_tag(skb) \ + (QDF_NBUF_CB_RX_PROTOCOL_TAG((skb))) + /** * qdf_nbuf_cb_update_peer_local_id() - update peer local id in skb cb * @skb: skb pointer whose cb is updated with peer local id information diff --git a/umac/cmn_services/obj_mgr/inc/wlan_objmgr_cmn.h b/umac/cmn_services/obj_mgr/inc/wlan_objmgr_cmn.h index 23249782d5..d2f60ff8eb 100644 --- a/umac/cmn_services/obj_mgr/inc/wlan_objmgr_cmn.h +++ b/umac/cmn_services/obj_mgr/inc/wlan_objmgr_cmn.h @@ -234,6 +234,7 @@ typedef void (*wlan_objmgr_peer_status_handler)( * @WLAN_SCHEDULER_ID: mlme scheduler * @WLAN_CFR_ID: CFG Capture method * @WLAN_VDEV_TARGET_IF_ID: Target interface layer + * @WLAN_RX_PKT_TAG_ID: RX protocol tag operations * @WLAN_REF_ID_MAX: Max id used to generate ref count tracking array */ /* New value added to the enum must also be reflected in function @@ -290,6 +291,7 @@ typedef enum { WLAN_SCHEDULER_ID = 47, WLAN_CFR_ID = 48, WLAN_VDEV_TARGET_IF_ID = 49, + WLAN_RX_PKT_TAG_ID = 50, WLAN_REF_ID_MAX, } wlan_objmgr_ref_dbgid; @@ -353,6 +355,7 @@ static inline char *string_from_dbgid(wlan_objmgr_ref_dbgid id) "WLAN_SCHEDULER_ID", "WLAN_CFR_ID", "WLAN_VDEV_TARGET_IF_ID", + "WLAN_RX_PKT_TAG_ID", "WLAN_REF_ID_MAX"}; return (char *)strings[id]; diff --git a/umac/cmn_services/utils/src/wlan_utility.c b/umac/cmn_services/utils/src/wlan_utility.c index 8479f747eb..fac51d9793 100644 --- a/umac/cmn_services/utils/src/wlan_utility.c +++ b/umac/cmn_services/utils/src/wlan_utility.c @@ -251,6 +251,8 @@ QDF_STATUS wlan_util_is_vdev_active(struct wlan_objmgr_pdev *pdev, return QDF_STATUS_E_INVAL; } +qdf_export_symbol(wlan_util_is_vdev_active); + #ifdef CMN_VDEV_MLME_SM_ENABLE void wlan_util_change_map_index(unsigned long *map, uint8_t id, uint8_t set) { diff --git a/wmi/inc/wmi_unified_param.h b/wmi/inc/wmi_unified_param.h index 4dda1d2500..aa19018330 100644 --- a/wmi/inc/wmi_unified_param.h +++ b/wmi/inc/wmi_unified_param.h @@ -7933,4 +7933,104 @@ struct mws_antenna_sharing_info { int32_t mrc_threshold; uint32_t grant_duration; }; + +#ifdef WLAN_SUPPORT_RX_PROTOCOL_TYPE_TAG +/** + * enum wmi_pdev_pkt_routing_op_code_type - packet routing supported opcodes + * @ADD_PKT_ROUTING: Add packet routing command + * @DEL_PKT_ROUTING: Delete packet routing command + * + * Defines supported opcodes for packet routing/tagging + */ +enum wmi_pdev_pkt_routing_op_code_type { + ADD_PKT_ROUTING, + DEL_PKT_ROUTING, +}; + +/** + * enum wmi_pdev_pkt_routing_pkt_type - supported packet types for + * routing & tagging + * @PDEV_PKT_TYPE_ARP_IPV4: Route/Tag for packet type ARP IPv4 (L3) + * @PDEV_PKT_TYPE_NS_IPV6: Route/Tag for packet type NS IPv6 (L3) + * @PDEV_PKT_TYPE_IGMP_IPV4: Route/Tag for packet type IGMP IPv4 (L3) + * @PDEV_PKT_TYPE_MLD_IPV6: Route/Tag for packet type MLD IPv6 (L3) + * @PDEV_PKT_TYPE_DHCP_IPV4: Route/Tag for packet type DHCP IPv4 (APP) + * @PDEV_PKT_TYPE_DHCP_IPV6: Route/Tag for packet type DHCP IPv6 (APP) + * @PDEV_PKT_TYPE_DNS_TCP_IPV4: Route/Tag for packet type TCP DNS IPv4 (APP) + * @PDEV_PKT_TYPE_DNS_TCP_IPV6: Route/Tag for packet type TCP DNS IPv6 (APP) + * @PDEV_PKT_TYPE_DNS_UDP_IPV4: Route/Tag for packet type UDP DNS IPv4 (APP) + * @PDEV_PKT_TYPE_DNS_UDP_IPV6: Route/Tag for packet type UDP DNS IPv6 (APP) + * @PDEV_PKT_TYPE_ICMP_IPV4: Route/Tag for packet type ICMP IPv4 (L3) + * @PDEV_PKT_TYPE_ICMP_IPV6: Route/Tag for packet type ICMP IPv6 (L3) + * @PDEV_PKT_TYPE_TCP_IPV4: Route/Tag for packet type TCP IPv4 (L4) + * @PDEV_PKT_TYPE_TCP_IPV6: Route/Tag for packet type TCP IPv6 (L4) + * @PDEV_PKT_TYPE_UDP_IPV4: Route/Tag for packet type UDP IPv4 (L4) + * @PDEV_PKT_TYPE_UDP_IPV6: Route/Tag for packet type UDP IPv6 (L4) + * @PDEV_PKT_TYPE_IPV4: Route/Tag for packet type IPv4 (L3) + * @PDEV_PKT_TYPE_IPV6: Route/Tag for packet type IPv6 (L3) + * @PDEV_PKT_TYPE_EAP: Route/Tag for packet type EAP (L2) + * + * Defines supported protocol types for routing/tagging + */ +enum wmi_pdev_pkt_routing_pkt_type { + PDEV_PKT_TYPE_ARP_IPV4, + PDEV_PKT_TYPE_NS_IPV6, + PDEV_PKT_TYPE_IGMP_IPV4, + PDEV_PKT_TYPE_MLD_IPV6, + PDEV_PKT_TYPE_DHCP_IPV4, + PDEV_PKT_TYPE_DHCP_IPV6, + PDEV_PKT_TYPE_DNS_TCP_IPV4, + PDEV_PKT_TYPE_DNS_TCP_IPV6, + PDEV_PKT_TYPE_DNS_UDP_IPV4, + PDEV_PKT_TYPE_DNS_UDP_IPV6, + PDEV_PKT_TYPE_ICMP_IPV4, + PDEV_PKT_TYPE_ICMP_IPV6, + PDEV_PKT_TYPE_TCP_IPV4, + PDEV_PKT_TYPE_TCP_IPV6, + PDEV_PKT_TYPE_UDP_IPV4, + PDEV_PKT_TYPE_UDP_IPV6, + PDEV_PKT_TYPE_IPV4, + PDEV_PKT_TYPE_IPV6, + PDEV_PKT_TYPE_EAP, + PDEV_PKT_TYPE_MAX +}; + +/** + * enum wmi_pdev_dest_ring_handler_type - packet routing options post CCE + * tagging + * @PDEV_WIFIRXCCE_USE_CCE_E: Use REO destination ring from CCE + * @PDEV_WIFIRXCCE_USE_ASPT_E: Use REO destination ring from ASPT + * @PDEV_WIFIRXCCE_USE_FT_E: Use REO destination ring from FSE + * @PDEV_WIFIRXCCE_USE_CCE2_E: Use REO destination ring from CCE2 + * + * Defines various options for routing policy + */ +enum wmi_pdev_dest_ring_handler_type { + PDEV_WIFIRXCCE_USE_CCE_E = 0, + PDEV_WIFIRXCCE_USE_ASPT_E = 1, + PDEV_WIFIRXCCE_USE_FT_E = 2, + PDEV_WIFIRXCCE_USE_CCE2_E = 3, +}; + +/** + * struct wmi_rx_pkt_protocol_routing_info - RX packet routing/tagging params + * @pdev_id: pdev id + * @op_code: Opcode option from wmi_pdev_pkt_routing_op_code_type enum + * @routing_type_bitmap: Bitmap of protocol that is being configured. Only + * one protocol can be configured in one command. Supported protocol list + * from enum wmi_pdev_pkt_routing_pkt_type + * @dest_ring_handler: Destination ring selection from enum + * wmi_pdev_dest_ring_handler_type + * @dest_ring: Destination ring number to use if dest ring handler is CCE + * @meta_data: Metadata to tag with for given protocol + */ +struct wmi_rx_pkt_protocol_routing_info { + uint32_t pdev_id; + enum wmi_pdev_pkt_routing_op_code_type op_code; + uint32_t routing_type_bitmap; + uint32_t dest_ring_handler; + uint32_t dest_ring; + uint32_t meta_data; +}; +#endif /* WLAN_SUPPORT_RX_PROTOCOL_TYPE_TAG */ #endif /* _WMI_UNIFIED_PARAM_H_ */ diff --git a/wmi/inc/wmi_unified_priv.h b/wmi/inc/wmi_unified_priv.h index 75aeb9176d..1182281bf9 100644 --- a/wmi/inc/wmi_unified_priv.h +++ b/wmi/inc/wmi_unified_priv.h @@ -1938,6 +1938,11 @@ QDF_STATUS (*send_vdev_tidmap_prec_cmd)(wmi_unified_t wmi_handle, #endif QDF_STATUS (*send_mws_coex_status_req_cmd)(wmi_unified_t wmi_handle, uint32_t vdev_id, uint32_t cmd_id); + +#ifdef WLAN_SUPPORT_RX_PROTOCOL_TYPE_TAG +QDF_STATUS (*set_rx_pkt_type_routing_tag_cmd)( + wmi_unified_t wmi_hdl, struct wmi_rx_pkt_protocol_routing_info *param); +#endif /* WLAN_SUPPORT_RX_PROTOCOL_TYPE_TAG */ }; /* Forward declartion for psoc*/