From 4c1468fb23adfe36aadf23ea1d994845b6efd624 Mon Sep 17 00:00:00 2001 From: "Ruchi, Agrawal" Date: Fri, 8 Dec 2017 00:04:33 +0530 Subject: [PATCH] qcacmn: RAW Mode EAPOL Frame Classification Host CCE Classification changes for RAW Mode workaround RAW Mode EAPOL frame classification for raw mode Change-Id: I533c2e8bb55e3cd5088c6bff046e67066c784053 CRs-fixed: 2132295 --- dp/inc/cdp_txrx_cmn_struct.h | 3 ++ dp/wifi3.0/dp_main.c | 3 ++ dp/wifi3.0/dp_tx.c | 59 ++++++++++++++++++++++++++++++------ qdf/inc/qdf_net_types.h | 5 +++ 4 files changed, 61 insertions(+), 9 deletions(-) diff --git a/dp/inc/cdp_txrx_cmn_struct.h b/dp/inc/cdp_txrx_cmn_struct.h index a1ec253792ad..8c90e79c8ba5 100644 --- a/dp/inc/cdp_txrx_cmn_struct.h +++ b/dp/inc/cdp_txrx_cmn_struct.h @@ -998,6 +998,9 @@ struct cdp_tx_ingress_stats { /*Number of packets classified by CCE*/ uint32_t cce_classified; + + /*Number of raw packets classified by CCE*/ + uint32_t cce_classified_raw; }; struct cdp_vdev_stats { diff --git a/dp/wifi3.0/dp_main.c b/dp/wifi3.0/dp_main.c index 8063ddb7e2bc..0b2bc23fa7d8 100644 --- a/dp/wifi3.0/dp_main.c +++ b/dp/wifi3.0/dp_main.c @@ -4008,6 +4008,7 @@ static inline void dp_aggregate_pdev_stats(struct dp_pdev *pdev) DP_STATS_AGGR(pdev, vdev, tx_i.dropped.desc_na); DP_STATS_AGGR(pdev, vdev, tx_i.dropped.res_full); DP_STATS_AGGR(pdev, vdev, tx_i.cce_classified); + DP_STATS_AGGR(pdev, vdev, tx_i.cce_classified_raw); pdev->stats.tx_i.dropped.dropped_pkt.num = pdev->stats.tx_i.dropped.dma_error + @@ -4125,6 +4126,8 @@ dp_print_pdev_tx_stats(struct dp_pdev *pdev) DP_PRINT_STATS("CCE Classified:"); DP_TRACE(FATAL, " CCE Classified Packets: %u", pdev->stats.tx_i.cce_classified); + DP_TRACE(FATAL, " RAW CCE Classified Packets: %u", + pdev->stats.tx_i.cce_classified_raw); } /** diff --git a/dp/wifi3.0/dp_tx.c b/dp/wifi3.0/dp_tx.c index 58ec24abbb51..ba834025780e 100644 --- a/dp/wifi3.0/dp_tx.c +++ b/dp/wifi3.0/dp_tx.c @@ -878,27 +878,67 @@ static QDF_STATUS dp_tx_hw_enqueue(struct dp_soc *soc, struct dp_vdev *vdev, * Return: bool( true if classified, * else false) */ -static bool dp_cce_classify(qdf_nbuf_t nbuf) +static bool dp_cce_classify(struct dp_vdev *vdev, qdf_nbuf_t nbuf) { struct ether_header *eh = NULL; uint16_t ether_type; qdf_llc_t *llcHdr; qdf_nbuf_t nbuf_clone = NULL; + qdf_dot3_qosframe_t *qos_wh = NULL; - eh = (struct ether_header *) qdf_nbuf_data(nbuf); - ether_type = eh->ether_type; + /* for mesh packets don't do any classification */ + if (qdf_unlikely(vdev->mesh_vdev)) + return false; - llcHdr = (qdf_llc_t *)(nbuf->data + sizeof(struct ether_header)); + if (qdf_likely(vdev->tx_encap_type != htt_cmn_pkt_type_raw)) { + eh = (struct ether_header *) qdf_nbuf_data(nbuf); + ether_type = eh->ether_type; + llcHdr = (qdf_llc_t *)(nbuf->data + + sizeof(struct ether_header)); + } else { + qos_wh = (qdf_dot3_qosframe_t *) nbuf->data; + + if (qdf_unlikely(qos_wh->i_fc[0] & QDF_IEEE80211_FC0_SUBTYPE_QOS)) { + if (qdf_unlikely( + qos_wh->i_fc[1] & QDF_IEEE80211_FC1_TODS && + qos_wh->i_fc[1] & QDF_IEEE80211_FC1_FROMDS)) { + + ether_type = *(uint16_t *)(nbuf->data + + QDF_IEEE80211_4ADDR_HDR_LEN + + sizeof(qdf_llc_t) + - sizeof(ether_type)); + llcHdr = (qdf_llc_t *)(nbuf->data + + QDF_IEEE80211_4ADDR_HDR_LEN); + } else { + ether_type = *(uint16_t *)(nbuf->data + + QDF_IEEE80211_3ADDR_HDR_LEN + + sizeof(qdf_llc_t) + - sizeof(ether_type)); + llcHdr = (qdf_llc_t *)(nbuf->data + + QDF_IEEE80211_3ADDR_HDR_LEN); + } + + if (qdf_unlikely(DP_FRAME_IS_SNAP(llcHdr) + && (ether_type == + qdf_htons(QDF_NBUF_TRAC_EAPOL_ETH_TYPE)))) { + + DP_STATS_INC(vdev, tx_i.cce_classified_raw, 1); + return true; + } + } + + return false; + } if (qdf_unlikely(DP_FRAME_IS_SNAP(llcHdr))) { - ether_type = (uint16_t)*(nbuf->data + 2*ETHER_ADDR_LEN + + ether_type = *(uint16_t *)(nbuf->data + 2*ETHER_ADDR_LEN + sizeof(*llcHdr)); nbuf_clone = qdf_nbuf_clone(nbuf); qdf_nbuf_pull_head(nbuf_clone, sizeof(*llcHdr)); if (ether_type == htons(ETHERTYPE_8021Q)) { - qdf_nbuf_pull_head(nbuf_clone, sizeof(*llcHdr) - +sizeof(qdf_net_vlanhdr_t)); + qdf_nbuf_pull_head(nbuf_clone, + sizeof(qdf_net_vlanhdr_t)); } } else { if (ether_type == htons(ETHERTYPE_8021Q)) { @@ -911,6 +951,7 @@ static bool dp_cce_classify(qdf_nbuf_t nbuf) if (qdf_unlikely(nbuf_clone)) nbuf = nbuf_clone; + if (qdf_unlikely(qdf_nbuf_is_ipv4_eapol_pkt(nbuf) || qdf_nbuf_is_ipv4_arp_pkt(nbuf) || qdf_nbuf_is_ipv4_wapi_pkt(nbuf) @@ -1130,7 +1171,7 @@ static qdf_nbuf_t dp_tx_send_msdu_single(struct dp_vdev *vdev, qdf_nbuf_t nbuf, } if (qdf_unlikely(soc->cce_disable)) { - if (dp_cce_classify(nbuf) == true) { + if (dp_cce_classify(vdev, nbuf) == true) { DP_STATS_INC(vdev, tx_i.cce_classified, 1); tid = DP_VO_TID; tx_desc->flags |= DP_TX_DESC_FLAG_TO_FW; @@ -1222,7 +1263,7 @@ qdf_nbuf_t dp_tx_send_msdu_multiple(struct dp_vdev *vdev, qdf_nbuf_t nbuf, } if (qdf_unlikely(soc->cce_disable)) { - is_cce_classified = dp_cce_classify(nbuf); + is_cce_classified = dp_cce_classify(vdev, nbuf); if (is_cce_classified) { DP_STATS_INC(vdev, tx_i.cce_classified, 1); msdu_info->tid = DP_VO_TID; diff --git a/qdf/inc/qdf_net_types.h b/qdf/inc/qdf_net_types.h index 65411bbeaa40..7272ec42999d 100644 --- a/qdf/inc/qdf_net_types.h +++ b/qdf/inc/qdf_net_types.h @@ -65,6 +65,11 @@ typedef __in6_addr_t in6_addr_t; #define QDF_ETH_TYPE_IPV4 0x0800 /* IPV4 */ #define QDF_ETH_TYPE_IPV6 0x86dd /* IPV6 */ +#define QDF_IEEE80211_4ADDR_HDR_LEN 30 +#define QDF_IEEE80211_3ADDR_HDR_LEN 24 +#define QDF_IEEE80211_FC0_SUBTYPE_QOS 0x80 +#define QDF_IEEE80211_FC1_TODS 0x01 +#define QDF_IEEE80211_FC1_FROMDS 0x02 typedef struct qdf_net_ethaddr { uint8_t addr[QDF_NET_ETH_LEN];