diff options
| author | Govind Singh <govinds@qti.qualcomm.com> | 2016-05-23 15:55:11 +0530 |
|---|---|---|
| committer | Anjaneedevi Kapparapu <akappa@codeaurora.org> | 2016-07-07 15:36:26 +0530 |
| commit | a10e352f0dd152798da858267408b366ebfc91c2 (patch) | |
| tree | 4edca57c5c18fb33f1f5088883cd2091140bb883 | |
| parent | 2dd4d5eb774b65e25385dde7bc2f87282e54ec8e (diff) | |
qcacld-2.0: Parse tx packets only once in tx datapath
Classify tx packets at one place and store packet type
in skb cb structure to avoid multiple check to determine
packet type at various layers.
CRs-Fixed: 1022454
Change-Id: I17d05e265612059410463b7577bb5e8ca1176962
| -rw-r--r-- | CORE/CLD_TXRX/TXRX/ol_tx.c | 3 | ||||
| -rw-r--r-- | CORE/HDD/src/wlan_hdd_tx_rx.c | 64 | ||||
| -rw-r--r-- | CORE/HDD/src/wlan_hdd_wmm.c | 17 | ||||
| -rw-r--r-- | CORE/SERVICES/COMMON/adf/adf_nbuf.c | 62 | ||||
| -rw-r--r-- | CORE/SERVICES/COMMON/adf/adf_nbuf.h | 46 | ||||
| -rw-r--r-- | CORE/SERVICES/COMMON/adf/adf_trace.c | 6 | ||||
| -rw-r--r-- | CORE/SERVICES/COMMON/adf/linux/adf_nbuf_pvt.h | 51 |
7 files changed, 194 insertions, 55 deletions
diff --git a/CORE/CLD_TXRX/TXRX/ol_tx.c b/CORE/CLD_TXRX/TXRX/ol_tx.c index dae35b756bbc..890303999a85 100644 --- a/CORE/CLD_TXRX/TXRX/ol_tx.c +++ b/CORE/CLD_TXRX/TXRX/ol_tx.c @@ -671,8 +671,7 @@ ol_tx_hl_base( if (adf_os_atomic_read(&pdev->tx_queue.rsrc_cnt) > TXRX_HL_TX_DESC_HI_PRIO_RESERVED) { tx_desc = ol_tx_desc_hl(pdev, vdev, msdu, &tx_msdu_info); - } else if ((adf_nbuf_is_dhcp_pkt(msdu) == A_STATUS_OK) - || (adf_nbuf_is_eapol_pkt(msdu) == A_STATUS_OK)) { + } else if (ADF_NBUF_GET_IS_DHCP(msdu) || ADF_NBUF_GET_IS_EAPOL(msdu)) { tx_desc = ol_tx_desc_hl(pdev, vdev, msdu, &tx_msdu_info); TXRX_PRINT(TXRX_PRINT_LEVEL_ERR, "Provided tx descriptor from reserve pool for DHCP/EAPOL\n"); diff --git a/CORE/HDD/src/wlan_hdd_tx_rx.c b/CORE/HDD/src/wlan_hdd_tx_rx.c index f86e99f5cf28..cfe12b02face 100644 --- a/CORE/HDD/src/wlan_hdd_tx_rx.c +++ b/CORE/HDD/src/wlan_hdd_tx_rx.c @@ -91,38 +91,6 @@ const v_U8_t hdd_QdiscAcToTlAC[] = { Function definitions and documentation -------------------------------------------------------------------------*/ -/** - * wlan_hdd_is_wai() - Check if frame is EAPOL or WAPI - * @skb: skb data - * - * This function checks if the frame is EAPOL or WAPI. - * single routine call will check for both types, thus avoiding - * data path performance penalty. - * - * Return: true (1) if packet is EAPOL or WAPI - * - */ -static bool wlan_hdd_is_eapol_or_wai(struct sk_buff *skb) -{ - uint16_t ether_type; - - if (!skb) { - hddLog(VOS_TRACE_LEVEL_ERROR, FL("skb is NULL")); - return false; - } - - ether_type = (uint16_t)(*(uint16_t *) - (skb->data + HDD_ETHERTYPE_802_1_X_FRAME_OFFSET)); - - if (ether_type == VOS_SWAP_U16(HDD_ETHERTYPE_802_1_X) || - ether_type == VOS_SWAP_U16(HDD_ETHERTYPE_WAI)) - return true; - - /* No error msg handled since this will happen often */ - return false; -} - - /**============================================================================ @brief hdd_flush_tx_queues() - Utility function to flush the TX queues @@ -404,6 +372,33 @@ void hdd_drop_skb_list(hdd_adapter_t *adapter, struct sk_buff *skb, } } +/** + * wlan_hdd_classify_pkt() - classify skb packet type. + * @data: Pointer to skb + * + * This function classifies skb packet type. + * + * Return: none + */ +void wlan_hdd_classify_pkt(struct sk_buff *skb) +{ + /* classify broadcast/multicast packet */ + if (adf_nbuf_is_bcast_pkt(skb)) + ADF_NBUF_SET_BCAST(skb); + else if (adf_nbuf_is_multicast_pkt(skb)) + ADF_NBUF_SET_MCAST(skb); + + /* classify eapol/arp/dhcp/wai packet */ + if (adf_nbuf_is_eapol_pkt(skb)) + ADF_NBUF_SET_EAPOL(skb); + else if (adf_nbuf_is_ipv4_arp_pkt(skb)) + ADF_NBUF_SET_ARP(skb); + else if (adf_nbuf_is_dhcp_pkt(skb)) + ADF_NBUF_SET_DHCP(skb); + else if (adf_nbuf_is_wai_pkt(skb)) + ADF_NBUF_SET_WAPI(skb); +} + /**============================================================================ @brief hdd_hard_start_xmit() - Function registered with the Linux OS for transmitting packets. This version of the function directly passes the packet @@ -453,6 +448,9 @@ int __hdd_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) while (skb) { skb_next = skb->next; + /* memset skb control block */ + vos_mem_zero(skb->cb, sizeof(skb->cb)); + wlan_hdd_classify_pkt(skb); if (WLAN_HDD_IBSS == pAdapter->device_mode) { v_MACADDR_t *pDestMacAddress = (v_MACADDR_t*)skb->data; @@ -561,7 +559,7 @@ int __hdd_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) likely( pAdapter->hddWmmStatus.wmmAcStatus[ac].wmmAcAccessAllowed)) || ((pHddStaCtx->conn_info.uIsAuthenticated == VOS_FALSE) && - wlan_hdd_is_eapol_or_wai(skb))) + (ADF_NBUF_GET_IS_EAPOL(skb) || ADF_NBUF_GET_IS_WAPI(skb)))) { granted = VOS_TRUE; } diff --git a/CORE/HDD/src/wlan_hdd_wmm.c b/CORE/HDD/src/wlan_hdd_wmm.c index ff929711f767..5d586e9d50fa 100644 --- a/CORE/HDD/src/wlan_hdd_wmm.c +++ b/CORE/HDD/src/wlan_hdd_wmm.c @@ -1634,23 +1634,6 @@ VOS_STATUS hdd_wmm_adapter_close ( hdd_adapter_t* pAdapter ) } /**============================================================================ - @brief is_dhcp_packet() - Function which will check OS packet for - DHCP packet - - @param skb : [in] pointer to OS packet (sk_buff) - @return : VOS_TRUE if the OS packet is DHCP packet - : otherwise VOS_FALSE - ===========================================================================*/ -v_BOOL_t is_dhcp_packet(struct sk_buff *skb) -{ - if (*((u16*)((u8*)skb->data+34)) == DHCP_SOURCE_PORT || - *((u16*)((u8*)skb->data+34)) == DHCP_DESTINATION_PORT) - return VOS_TRUE; - - return VOS_FALSE; -} - -/**============================================================================ @brief hdd_wmm_classify_pkt() - Function which will classify an OS packet into a WMM AC based on either 802.1Q or DSCP diff --git a/CORE/SERVICES/COMMON/adf/adf_nbuf.c b/CORE/SERVICES/COMMON/adf/adf_nbuf.c index 944894f25531..81494f127492 100644 --- a/CORE/SERVICES/COMMON/adf/adf_nbuf.c +++ b/CORE/SERVICES/COMMON/adf/adf_nbuf.c @@ -1159,3 +1159,65 @@ __adf_nbuf_validate_skb_cb(void) BUILD_BUG_ON(sizeof(struct cvg_nbuf_cb) > FIELD_SIZEOF(struct sk_buff, cb)); } + +/** + * __adf_nbuf_is_wai() - Check if frame is WAI + * @data: pointer to skb data buffer + * + * This function checks if the frame is WAPI. + * + * Return: true (1) if WAPI + * + */ +bool __adf_nbuf_is_wai_pkt(uint8_t *data) +{ + uint16_t ether_type; + + ether_type = (uint16_t)(*(uint16_t *) + (data + ADF_NBUF_TRAC_ETH_TYPE_OFFSET)); + + if (ether_type == VOS_SWAP_U16(ADF_NBUF_TRAC_WAI_ETH_TYPE)) + return true; + + return false; +} + +/** + * __adf_nbuf_is_group_pkt() - Check if frame is multicast packet + * @data: pointer to skb data buffer + * + * This function checks if the frame is multicast packet. + * + * Return: true (1) if multicast + * + */ +bool __adf_nbuf_is_multicast_pkt(uint8_t *data) +{ + struct adf_mac_addr *mac_addr = (struct adf_mac_addr*)data; + + if ( mac_addr->bytes[0] & 0x01 ) + return true; + + return false; +} + +/** + * __adf_nbuf_is_bcast_pkt() - Check if frame is broadcast packet + * @data: pointer to skb data buffer + * + * This function checks if the frame is broadcast packet. + * + * Return: true (1) if broadcast + * + */ +bool __adf_nbuf_is_bcast_pkt(uint8_t *data) +{ + struct adf_mac_addr *mac_addr = (struct adf_mac_addr*)data; + struct adf_mac_addr bcast_addr = VOS_MAC_ADDR_BROADCAST_INITIALIZER; + + if (!memcmp( mac_addr, &bcast_addr, VOS_MAC_ADDR_SIZE)) + return true; + + return false; +} + diff --git a/CORE/SERVICES/COMMON/adf/adf_nbuf.h b/CORE/SERVICES/COMMON/adf/adf_nbuf.h index 860aa7f77d28..d827ac23393c 100644 --- a/CORE/SERVICES/COMMON/adf/adf_nbuf.h +++ b/CORE/SERVICES/COMMON/adf/adf_nbuf.h @@ -74,6 +74,7 @@ #define ADF_NBUF_TRAC_TCP_TYPE 6 #define ADF_NBUF_TRAC_UDP_TYPE 17 #define ADF_NBUF_TRAC_ICMPv6_TYPE 0x3a +#define ADF_NBUF_TRAC_WAI_ETH_TYPE 0x88b4 /* EAPOL Related MASK */ #define EAPOL_PACKET_TYPE_OFFSET 15 @@ -1829,6 +1830,51 @@ adf_nbuf_update_skb_mark(adf_nbuf_t skb, uint32_t mask) __adf_nbuf_update_skb_mark(skb, mask); } +/** + * adf_nbuf_is_wai() - Check if frame is WAI + * @skb: Pointer to skb + * + * This function checks if the frame is WAPI. + * + * Return: true (1) if WAPI + * + */ +static inline bool adf_nbuf_is_wai_pkt(struct sk_buff *skb) +{ + return __adf_nbuf_is_wai_pkt(skb->data); +} + +/** + * adf_nbuf_is_multicast_pkt() - Check if frame is multicast packet + * @skb: Pointer to skb + * + * This function checks if the frame is multicast packet. + * + * Return: true (1) if multicast + * + */ +static inline bool adf_nbuf_is_multicast_pkt(struct sk_buff *skb) +{ + return __adf_nbuf_is_multicast_pkt(skb->data); +} + +/** + * adf_nbuf_is_bcast_pkt() - Check if frame is broadcast packet + * @skb: Pointer to skb + * + * This function checks if the frame is broadcast packet. + * + * Return: true (1) if broadcast + * + */ +static inline bool adf_nbuf_is_bcast_pkt(struct sk_buff *skb) +{ + return __adf_nbuf_is_bcast_pkt(skb->data); +} + + + + void adf_nbuf_set_state(adf_nbuf_t nbuf, uint8_t current_state); void adf_nbuf_tx_desc_count_display(void); void adf_nbuf_tx_desc_count_clear(void); diff --git a/CORE/SERVICES/COMMON/adf/adf_trace.c b/CORE/SERVICES/COMMON/adf/adf_trace.c index 0a4fddb95ff3..7720aa6fdc2d 100644 --- a/CORE/SERVICES/COMMON/adf/adf_trace.c +++ b/CORE/SERVICES/COMMON/adf/adf_trace.c @@ -436,7 +436,7 @@ bool adf_log_eapol_pkt(uint8_t session_id, struct sk_buff *skb, enum adf_proto_subtype subtype; if ((adf_dp_get_proto_bitmap() & NBUF_PKT_TRAC_TYPE_EAPOL) && - adf_nbuf_is_eapol_pkt(skb) == A_STATUS_OK) { + ADF_NBUF_GET_IS_EAPOL(skb)) { subtype = adf_nbuf_get_eapol_subtype(skb); DPTRACE(adf_dp_trace_proto_pkt(ADF_DP_TRACE_EAPOL_PACKET_RECORD, @@ -467,7 +467,7 @@ bool adf_log_dhcp_pkt(uint8_t session_id, struct sk_buff *skb, enum adf_proto_subtype subtype = ADF_PROTO_INVALID; if ((adf_dp_get_proto_bitmap() & NBUF_PKT_TRAC_TYPE_DHCP) && - adf_nbuf_is_dhcp_pkt(skb) == A_STATUS_OK) { + ADF_NBUF_GET_IS_DHCP(skb)) { subtype = adf_nbuf_get_dhcp_subtype(skb); DPTRACE(adf_dp_trace_proto_pkt(ADF_DP_TRACE_DHCP_PACKET_RECORD, @@ -499,7 +499,7 @@ bool adf_log_arp_pkt(uint8_t session_id, struct sk_buff *skb, enum adf_proto_subtype proto_subtype; if ((adf_dp_get_proto_bitmap() & NBUF_PKT_TRAC_TYPE_ARP) && - adf_nbuf_is_ipv4_arp_pkt(skb) == true) { + ADF_NBUF_GET_IS_ARP(skb)) { proto_subtype = adf_nbuf_get_arp_subtype(skb); diff --git a/CORE/SERVICES/COMMON/adf/linux/adf_nbuf_pvt.h b/CORE/SERVICES/COMMON/adf/linux/adf_nbuf_pvt.h index 70fd459f891b..7230e5f14444 100644 --- a/CORE/SERVICES/COMMON/adf/linux/adf_nbuf_pvt.h +++ b/CORE/SERVICES/COMMON/adf/linux/adf_nbuf_pvt.h @@ -153,6 +153,15 @@ struct cvg_nbuf_cb { unsigned char tx_htt2_frm: 1; unsigned char tx_htt2_reserved: 7; #endif /* QCA_TX_HTT2_SUPPORT */ + struct { + uint8_t is_eapol: 1; + uint8_t is_arp: 1; + uint8_t is_dhcp: 1; + uint8_t is_wapi: 1; + uint8_t is_mcast: 1; + uint8_t is_bcast: 1; + uint8_t reserved: 2; + } packet_type; } __packed; #ifdef QCA_ARP_SPOOFING_WAR @@ -224,6 +233,25 @@ struct cvg_nbuf_cb { #define NBUF_SET_PACKET_TRACK(skb, pkt_track) \ (((struct cvg_nbuf_cb *)((skb)->cb))->trace.packet_track = \ pkt_track) +#define ADF_NBUF_SET_EAPOL(skb) \ + (((struct cvg_nbuf_cb *)((skb)->cb))->packet_type.is_eapol = \ + true) +#define ADF_NBUF_SET_ARP(skb) \ + (((struct cvg_nbuf_cb *)((skb)->cb))->packet_type.is_arp = \ + true) +#define ADF_NBUF_SET_DHCP(skb) \ + (((struct cvg_nbuf_cb *)((skb)->cb))->packet_type.is_dhcp = \ + true) +#define ADF_NBUF_SET_WAPI(skb) \ + (((struct cvg_nbuf_cb *)((skb)->cb))->packet_type.is_wapi = \ + true) +#define ADF_NBUF_SET_MCAST(skb) \ + (((struct cvg_nbuf_cb *)((skb)->cb))->packet_type.is_mcast = \ + true) +#define ADF_NBUF_SET_BCAST(skb) \ + (((struct cvg_nbuf_cb *)((skb)->cb))->packet_type.is_bcast = \ + true) + #define NBUF_GET_PACKET_TRACK(skb) \ (((struct cvg_nbuf_cb *)((skb)->cb))->trace.packet_track) @@ -233,6 +261,26 @@ struct cvg_nbuf_cb { #define ADF_NBUF_CB_TX_DP_TRACE(skb) \ (((struct cvg_nbuf_cb *)((skb)->cb))->trace.dp_trace) +#define ADF_NBUF_GET_IS_EAPOL(skb) \ + (((struct cvg_nbuf_cb *)((skb)->cb))->packet_type.is_eapol) + +#define ADF_NBUF_GET_IS_ARP(skb) \ + (((struct cvg_nbuf_cb *)((skb)->cb))->packet_type.is_arp) + +#define ADF_NBUF_GET_IS_DHCP(skb) \ + (((struct cvg_nbuf_cb *)((skb)->cb))->packet_type.is_dhcp) + +#define ADF_NBUF_GET_IS_WAPI(skb) \ + (((struct cvg_nbuf_cb *)((skb)->cb))->packet_type.is_wapi) + +#define ADF_NBUF_GET_IS_BCAST(skb) \ + (((struct cvg_nbuf_cb *)((skb)->cb))->packet_type.is_bcast) + +#define ADF_NBUF_GET_IS_MCAST(skb) \ + (((struct cvg_nbuf_cb *)((skb)->cb))->packet_type.is_mcast) + + + #define __adf_nbuf_get_num_frags(skb) \ /* assume the OS provides a single fragment */ \ (NBUF_NUM_EXTRA_FRAGS(skb) + 1) @@ -356,6 +404,9 @@ enum adf_proto_subtype __adf_nbuf_data_get_eapol_subtype(uint8_t *data); enum adf_proto_subtype __adf_nbuf_data_get_arp_subtype(uint8_t *data); enum adf_proto_subtype __adf_nbuf_data_get_icmp_subtype(uint8_t *data); enum adf_proto_subtype __adf_nbuf_data_get_icmpv6_subtype(uint8_t *data); +bool __adf_nbuf_is_bcast_pkt(uint8_t *data); +bool __adf_nbuf_is_multicast_pkt(uint8_t *data); +bool __adf_nbuf_is_wai_pkt(uint8_t *data); #ifdef QCA_PKT_PROTO_TRACE |
