From 6380170e35c0991ac87ef39bc4f1f548e1f9e7b3 Mon Sep 17 00:00:00 2001 From: Karthik Kantamneni Date: Tue, 22 Mar 2022 11:19:45 +0530 Subject: [PATCH] qcacmn: Introduce new QDF API's to handle skb and net dev requirements Introduce new QDF API's to handle skb and net dev handling in os abstract code. Change-Id: If5a460df2c6c1b4068909fed6e5b3036623c2093 CRs-Fixed: 3164916 --- qdf/inc/qdf_nbuf.h | 158 +++++++++++++++++++++++++++++++- qdf/inc/qdf_net_types.h | 6 ++ qdf/inc/qdf_threads.h | 12 +++ qdf/inc/qdf_trace.h | 5 + qdf/inc/qdf_types.h | 10 ++ qdf/linux/src/i_qdf_nbuf.h | 125 +++++++++++++++++++++++++ qdf/linux/src/i_qdf_net_types.h | 6 ++ qdf/linux/src/i_qdf_types.h | 2 + qdf/linux/src/qdf_nbuf.c | 68 ++++++++++++++ qdf/linux/src/qdf_threads.c | 9 ++ 10 files changed, 399 insertions(+), 2 deletions(-) diff --git a/qdf/inc/qdf_nbuf.h b/qdf/inc/qdf_nbuf.h index bc0b83905d..dfb387f826 100644 --- a/qdf/inc/qdf_nbuf.h +++ b/qdf/inc/qdf_nbuf.h @@ -169,8 +169,9 @@ #define QDF_NBUF_TX_PKT_HIF 7 #define QDF_NBUF_TX_PKT_CE 8 #define QDF_NBUF_TX_PKT_FREE 9 -#define QDF_NBUF_TX_PKT_STATE_MAX 10 -#define QDF_NBUF_TX_PKT_LI_DP 11 +#define QDF_NBUF_TX_PKT_LI_DP 10 +#define QDF_NBUF_TX_PKT_DP 11 +#define QDF_NBUF_TX_PKT_STATE_MAX 12 /* nbuf allocations only come from one domain */ #define QDF_DEBUG_NBUF_DOMAIN 0 @@ -2213,6 +2214,32 @@ static inline qdf_nbuf_t qdf_nbuf_unshare(qdf_nbuf_t buf) } #endif /* NBUF_MEMORY_DEBUG */ +/** + * qdf_nbuf_kfree() - Free nbuf using kfree + * @buf: Pointer to network buffer + * + * This function is called to free the skb on failure cases + * + * Return: None + */ +static inline void qdf_nbuf_kfree(qdf_nbuf_t buf) +{ + __qdf_nbuf_kfree(buf); +} + +/** + * qdf_nbuf_dev_kfree() - Free nbuf using dev based os call + * @buf: Pointer to network buffer + * + * This function is called to free the skb on failure cases + * + * Return: None + */ +static inline void qdf_nbuf_dev_kfree(qdf_nbuf_t buf) +{ + __qdf_nbuf_dev_kfree(buf); +} + /** * qdf_nbuf_copy_expand_fraglist() - copy and expand nbuf and * get reference of the fraglist. @@ -2542,6 +2569,43 @@ static inline void qdf_nbuf_set_dev_scratch(qdf_nbuf_t buf, unsigned long value) __qdf_nbuf_set_dev_scratch(buf, value); } +/** + * qdf_nbuf_set_dev() - set dev in network buffer + * @buf: Pointer to network buffer + * @dev: netdev to be set in network buffer + * + * Return: void + */ +static inline +void qdf_nbuf_set_dev(qdf_nbuf_t nbuf, qdf_netdev_t dev) +{ + __qdf_nbuf_set_dev(nbuf, dev); +} + +/** + * qdf_nbuf_get_dev_mtu() - get dev mtu in n/w buffer + * @buf: Pointer to network buffer + * + * Return: dev mtu value in nbuf + */ +static inline +unsigned int qdf_nbuf_get_dev_mtu(qdf_nbuf_t nbuf) +{ + return __qdf_nbuf_get_dev_mtu(nbuf); +} + +/** + * qdf_nbuf_set_protocol_eth_tye_trans() - set protocol using eth trans os API + * @buf: Pointer to network buffer + * + * Return: None + */ +static inline +void qdf_nbuf_set_protocol_eth_tye_trans(qdf_nbuf_t nbuf) +{ + __qdf_nbuf_set_protocol_eth_type_trans(nbuf); +} + /** * qdf_nbuf_peek_header() - return the data pointer & length of the header * @buf: Network nbuf @@ -3786,6 +3850,62 @@ bool qdf_nbuf_is_bcast_pkt(qdf_nbuf_t buf) return __qdf_nbuf_is_bcast_pkt(buf); } +/** + * qdf_nbuf_pkt_type_is_mcast() - check if skb pkt type is mcast + * @buf: Network buffer + * + * Return: TRUE if skb pkt type is mcast + * FALSE if not + */ +static inline +bool qdf_nbuf_pkt_type_is_mcast(qdf_nbuf_t buf) +{ + return __qdf_nbuf_pkt_type_is_mcast(buf); +} + +/** + * qdf_nbuf_pkt_type_is_bcast() - check if skb pkt type is bcast + * @buf: Network buffer + * + * Return: TRUE if skb pkt type is mcast + * FALSE if not + */ +static inline +bool qdf_nbuf_pkt_type_is_bcast(qdf_nbuf_t buf) +{ + return __qdf_nbuf_pkt_type_is_bcast(buf); +} + +/** + * qdf_nbuf_is_mcast_replay() - check if it is multicast replay packet. + * @buf: Network buffer + * + * This func. checks whether packet is multicast replay packet or not. + * + * Return: TRUE if it is multicast packet + * FALSE if not + */ +static inline +bool qdf_nbuf_is_mcast_replay(qdf_nbuf_t buf) +{ + return __qdf_nbuf_is_mcast_replay(buf); +} + +/** + * qdf_nbuf_is_arp_local() - check if it is local or no local arp + * @buf: Network buffer + * + * This func. checks whether packet is local or no local arp. + * + * Return: TRUE if it is broadcast packet + * FALSE if not + */ +static inline +bool qdf_nbuf_is_arp_local(qdf_nbuf_t buf) +{ + return __qdf_nbuf_is_arp_local(buf); +} + /** * qdf_nbuf_reset_num_frags() - decrement the number of fragments * @buf: Network buffer @@ -3883,6 +4003,29 @@ static inline uint16_t qdf_nbuf_get_gso_segs(qdf_nbuf_t nbuf) return __qdf_nbuf_get_gso_segs(nbuf); } +/** + * qdf_nbuf_get_gso_size() - Return the number of gso size in + * nbuf + * @nbuf: Network buffer + * + * Return: number of gso segments in nbuf + */ +static inline unsigned int qdf_nbuf_get_gso_size(qdf_nbuf_t nbuf) +{ + return __qdf_nbuf_get_gso_size(nbuf); +} + +/** + * qdf_nbuf_set_gso_size() - Set the gso size in nbuf + * @skb: Pointer to network buffer + * + * Return: Return the number of gso segments + */ +static inline void qdf_nbuf_set_gso_size(qdf_nbuf_t nbuf, unsigned int val) +{ + __qdf_nbuf_set_gso_size(nbuf, val); +} + /** * qdf_nbuf_inc_users() - function to increment the number of * users referencing this network buffer @@ -4058,6 +4201,17 @@ static inline qdf_size_t qdf_nbuf_l2l3l4_hdr_len(qdf_nbuf_t buf) return __qdf_nbuf_l2l3l4_hdr_len(buf); } +/** + * qdf_nbuf_get_tcp_hdr_len() - return TCP header length of the skb + * @skb: sk buff + * + * Return: size of TCP header length + */ +static inline size_t qdf_nbuf_get_tcp_hdr_len(qdf_nbuf_t nbuf) +{ + return __qdf_nbuf_get_tcp_hdr_len(nbuf); +} + static inline bool qdf_nbuf_is_nonlinear(qdf_nbuf_t buf) { return __qdf_nbuf_is_nonlinear(buf); diff --git a/qdf/inc/qdf_net_types.h b/qdf/inc/qdf_net_types.h index 7205116cb9..f4ce0ef6ba 100644 --- a/qdf/inc/qdf_net_types.h +++ b/qdf/inc/qdf_net_types.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2014-2020 The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. 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 @@ -536,6 +537,11 @@ static inline int32_t qdf_csum_ipv6(const in6_addr_t *saddr, return (int32_t)__qdf_csum_ipv6(saddr, daddr, len, proto, sum); } +static inline char *qdf_netdev_get_devname(qdf_netdev_t dev) +{ + return __qdf_netdev_get_devname(dev); +} + typedef struct { uint8_t i_fc[2]; uint8_t i_dur[2]; diff --git a/qdf/inc/qdf_threads.h b/qdf/inc/qdf_threads.h index 0d67a23260..1917688013 100644 --- a/qdf/inc/qdf_threads.h +++ b/qdf/inc/qdf_threads.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2014-2021 The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. 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 @@ -197,4 +198,15 @@ bool qdf_cpumask_empty(const qdf_cpu_mask *srcp); */ void qdf_cpumask_copy(qdf_cpu_mask *dstp, const qdf_cpu_mask *srcp); + +/** + * qdf_cpumask_or - set *dstp = *src1p | *src2p + * @dstp: the cpumask result + * @src1p: the first input + * @src2p: the second input + * + * Return: None + */ +void qdf_cpumask_or(qdf_cpu_mask *dstp, qdf_cpu_mask *src1p, + qdf_cpu_mask *src2p); #endif /* __QDF_THREADS_H */ diff --git a/qdf/inc/qdf_trace.h b/qdf/inc/qdf_trace.h index 7a3ecd94ce..5929b51b43 100644 --- a/qdf/inc/qdf_trace.h +++ b/qdf/inc/qdf_trace.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2014-2021 The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. 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 @@ -221,7 +222,9 @@ typedef struct s_qdf_trace_data { * @QDF_DP_TRACE_FREE_PACKET_PTR_RECORD - tx completion ptr record * @QDF_DP_TRACE_LOW_VERBOSITY - below this are part of low verbosity * @QDF_DP_TRACE_HDD_TX_PACKET_PTR_RECORD - HDD layer ptr record + * @QDF_DP_TRACE_TX_PACKET_PTR_RECORD - DP component Tx ptr record * @QDF_DP_TRACE_LI_DP_TX_PACKET_PTR_RECORD - Lithium DP layer ptr record + * @QDF_DP_TRACE_RX_PACKET_PTR_RECORD - DP component Rx ptr record * @QDF_DP_TRACE_RX_HDD_PACKET_PTR_RECORD - HDD RX record * @QDF_DP_TRACE_CE_PACKET_PTR_RECORD - CE layer ptr record * @QDF_DP_TRACE_CE_FAST_PACKET_PTR_RECORD- CE fastpath ptr record @@ -267,7 +270,9 @@ enum QDF_DP_TRACE_ID { QDF_DP_TRACE_FREE_PACKET_PTR_RECORD, QDF_DP_TRACE_LOW_VERBOSITY, QDF_DP_TRACE_HDD_TX_PACKET_PTR_RECORD, + QDF_DP_TRACE_TX_PACKET_PTR_RECORD, QDF_DP_TRACE_LI_DP_TX_PACKET_PTR_RECORD, + QDF_DP_TRACE_RX_PACKET_PTR_RECORD, QDF_DP_TRACE_RX_HDD_PACKET_PTR_RECORD, QDF_DP_TRACE_CE_PACKET_PTR_RECORD, QDF_DP_TRACE_CE_FAST_PACKET_PTR_RECORD, diff --git a/qdf/inc/qdf_types.h b/qdf/inc/qdf_types.h index 549625e2ff..f8678df92f 100644 --- a/qdf/inc/qdf_types.h +++ b/qdf/inc/qdf_types.h @@ -174,6 +174,16 @@ typedef __qdf_cpu_mask qdf_cpu_mask; */ typedef __qdf_netdev_t qdf_netdev_t; +/** + * pointer to napi struct + */ +typedef __qdf_napi_struct qdf_napi_struct; + +/** + * pointer to net dev stats + */ +typedef __qdf_net_dev_stats qdf_net_dev_stats; + /** * struct qdf_dma_map_info - Information inside a DMA map. * @nsegs: total number mapped segments diff --git a/qdf/linux/src/i_qdf_nbuf.h b/qdf/linux/src/i_qdf_nbuf.h index 2ca33bcbba..19e183ac7c 100644 --- a/qdf/linux/src/i_qdf_nbuf.h +++ b/qdf/linux/src/i_qdf_nbuf.h @@ -874,6 +874,8 @@ bool __qdf_nbuf_data_is_ipv4_igmp_pkt(uint8_t *data); bool __qdf_nbuf_data_is_ipv6_igmp_pkt(uint8_t *data); bool __qdf_nbuf_data_is_ipv4_arp_pkt(uint8_t *data); bool __qdf_nbuf_is_bcast_pkt(__qdf_nbuf_t nbuf); +bool __qdf_nbuf_is_mcast_replay(__qdf_nbuf_t nbuf); +bool __qdf_nbuf_is_arp_local(struct sk_buff *skb); bool __qdf_nbuf_data_is_arp_req(uint8_t *data); bool __qdf_nbuf_data_is_arp_rsp(uint8_t *data); uint32_t __qdf_nbuf_get_arp_src_ip(uint8_t *data); @@ -2163,6 +2165,17 @@ static inline size_t __qdf_nbuf_l2l3l4_hdr_len(struct sk_buff *skb) return skb_transport_offset(skb) + tcp_hdrlen(skb); } +/** + * __qdf_nbuf_get_tcp_hdr_len() - return TCP header length of the skb + * @skb: sk buff + * + * Return: size of TCP header length + */ +static inline size_t __qdf_nbuf_get_tcp_hdr_len(struct sk_buff *skb) +{ + return tcp_hdrlen(skb); +} + /** * __qdf_nbuf_is_nonlinear() - test whether the nbuf is nonlinear or not * @buf: sk buff @@ -2643,6 +2656,118 @@ static inline uint16_t __qdf_nbuf_get_gso_segs(struct sk_buff *skb) return skb_shinfo(skb)->gso_segs; } +/** + * __qdf_nbuf_get_gso_size() - Return the number of gso size + * @skb: Pointer to network buffer + * + * Return: Return the number of gso segments + */ +static inline unsigned int __qdf_nbuf_get_gso_size(struct sk_buff *skb) +{ + return skb_shinfo(skb)->gso_size; +} + +/** + * __qdf_nbuf_set_gso_size() - Set the gso size in nbuf + * @skb: Pointer to network buffer + * + * Return: Return the number of gso segments + */ +static inline void +__qdf_nbuf_set_gso_size(struct sk_buff *skb, unsigned int val) +{ + skb_shinfo(skb)->gso_size = val; +} + +/** + * __qdf_nbuf_kfree() - Free nbuf using kfree + * @buf: Pointer to network buffer + * + * This function is called to free the skb on failure cases + * + * Return: None + */ +static inline void __qdf_nbuf_kfree(struct sk_buff *skb) +{ + kfree_skb(skb); +} + +/** + * __qdf_nbuf_dev_kfree() - Free nbuf using dev based os call + * @buf: Pointer to network buffer + * + * This function is called to free the skb on failure cases + * + * Return: None + */ +static inline void __qdf_nbuf_dev_kfree(struct sk_buff *skb) +{ + dev_kfree_skb(skb); +} + +/** + * __qdf_nbuf_pkt_type_is_mcast() - check if skb pkt type is mcast + * @buf: Network buffer + * + * Return: TRUE if skb pkt type is mcast + * FALSE if not + */ +static inline +bool __qdf_nbuf_pkt_type_is_mcast(struct sk_buff *skb) +{ + return skb->pkt_type == PACKET_MULTICAST; +} + +/** + * __qdf_nbuf_pkt_type_is_bcast() - check if skb pkt type is bcast + * @buf: Network buffer + * + * Return: TRUE if skb pkt type is mcast + * FALSE if not + */ +static inline +bool __qdf_nbuf_pkt_type_is_bcast(struct sk_buff *skb) +{ + return skb->pkt_type == PACKET_BROADCAST; +} + +/** + * __qdf_nbuf_set_dev_scratch() - set dev_scratch of network buffer + * @buf: Pointer to network buffer + * @value: value to be set in dev_scratch of network buffer + * + * Return: void + */ +static inline +void __qdf_nbuf_set_dev(struct sk_buff *skb, struct net_device *dev) +{ + skb->dev = dev; +} + +/** + * __qdf_nbuf_get_dev_mtu() - get dev mtu in n/w buffer + * @buf: Pointer to network buffer + * + * Return: dev mtu value in nbuf + */ +static inline +unsigned int __qdf_nbuf_get_dev_mtu(struct sk_buff *skb) +{ + return skb->dev->mtu; +} + +/** + * __qdf_nbuf_set_protocol_eth_tye_trans() - set protocol using eth trans os API + * @buf: Pointer to network buffer + * + * Return: None + */ +static inline +void __qdf_nbuf_set_protocol_eth_type_trans(struct sk_buff *skb) +{ + skb->protocol = eth_type_trans(skb, skb->dev); +} + /* * __qdf_nbuf_net_timedelta() - get time delta * @t: time as __qdf_ktime_t object diff --git a/qdf/linux/src/i_qdf_net_types.h b/qdf/linux/src/i_qdf_net_types.h index 796f8b7b1f..dae5160c00 100644 --- a/qdf/linux/src/i_qdf_net_types.h +++ b/qdf/linux/src/i_qdf_net_types.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2014-2017 The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. 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 @@ -41,6 +42,11 @@ static inline int32_t __qdf_csum_ipv6(const struct in6_addr *saddr, (struct in6_addr *)daddr, len, proto, sum); } +static inline char *__qdf_netdev_get_devname(qdf_netdev_t dev) +{ + return dev->name; +} + #define __QDF_TCPHDR_FIN TCPHDR_FIN #define __QDF_TCPHDR_SYN TCPHDR_SYN #define __QDF_TCPHDR_RST TCPHDR_RST diff --git a/qdf/linux/src/i_qdf_types.h b/qdf/linux/src/i_qdf_types.h index f5335a08aa..46275f1e4a 100644 --- a/qdf/linux/src/i_qdf_types.h +++ b/qdf/linux/src/i_qdf_types.h @@ -171,7 +171,9 @@ typedef int (*__qdf_os_intr)(void *); typedef dma_addr_t __qdf_dma_addr_t; typedef size_t __qdf_dma_size_t; typedef dma_addr_t __qdf_dma_context_t; +typedef struct napi_struct __qdf_napi_struct; typedef struct net_device *__qdf_netdev_t; +typedef struct net_device_stats __qdf_net_dev_stats; typedef struct cpumask __qdf_cpu_mask; typedef __le16 __qdf_le16_t; typedef __le32 __qdf_le32_t; diff --git a/qdf/linux/src/qdf_nbuf.c b/qdf/linux/src/qdf_nbuf.c index 319fac542b..daae2bf87f 100644 --- a/qdf/linux/src/qdf_nbuf.c +++ b/qdf/linux/src/qdf_nbuf.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -2465,6 +2466,73 @@ bool __qdf_nbuf_is_bcast_pkt(qdf_nbuf_t nbuf) } qdf_export_symbol(__qdf_nbuf_is_bcast_pkt); +/** + * __qdf_nbuf_is_mcast_replay() - is multicast replay packet + * @nbuf - sk buff + * + * Return: true if packet is multicast replay + * false otherwise + */ +bool __qdf_nbuf_is_mcast_replay(qdf_nbuf_t nbuf) +{ + struct ethhdr *eh = (struct ethhdr *)qdf_nbuf_data(nbuf); + + if (unlikely(nbuf->pkt_type == PACKET_MULTICAST)) { + if (unlikely(ether_addr_equal(eh->h_source, + nbuf->dev->dev_addr))) + return true; + } + return false; +} + +/** + * __qdf_nbuf_is_arp_local() - check if local or non local arp + * @skb: pointer to sk_buff + * + * Return: true if local arp or false otherwise. + */ +bool __qdf_nbuf_is_arp_local(struct sk_buff *skb) +{ + struct arphdr *arp; + struct in_ifaddr **ifap = NULL; + struct in_ifaddr *ifa = NULL; + struct in_device *in_dev; + unsigned char *arp_ptr; + __be32 tip; + + arp = (struct arphdr *)skb->data; + if (arp->ar_op == htons(ARPOP_REQUEST)) { + /* if fail to acquire rtnl lock, assume it's local arp */ + if (!rtnl_trylock()) + return true; + + in_dev = __in_dev_get_rtnl(skb->dev); + if (in_dev) { + for (ifap = &in_dev->ifa_list; (ifa = *ifap) != NULL; + ifap = &ifa->ifa_next) { + if (!strcmp(skb->dev->name, ifa->ifa_label)) + break; + } + } + + if (ifa && ifa->ifa_local) { + arp_ptr = (unsigned char *)(arp + 1); + arp_ptr += (skb->dev->addr_len + 4 + + skb->dev->addr_len); + memcpy(&tip, arp_ptr, 4); + qdf_debug("ARP packet: local IP: %x dest IP: %x", + ifa->ifa_local, tip); + if (ifa->ifa_local == tip) { + rtnl_unlock(); + return true; + } + } + rtnl_unlock(); + } + + return false; +} + #ifdef NBUF_MEMORY_DEBUG static spinlock_t g_qdf_net_buf_track_lock[QDF_NET_BUF_TRACK_MAX_SIZE]; diff --git a/qdf/linux/src/qdf_threads.c b/qdf/linux/src/qdf_threads.c index 83f8e8b38a..2817a103b5 100644 --- a/qdf/linux/src/qdf_threads.c +++ b/qdf/linux/src/qdf_threads.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2014-2021 The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. 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 @@ -304,3 +305,11 @@ void qdf_cpumask_copy(qdf_cpu_mask *dstp, } qdf_export_symbol(qdf_cpumask_copy); + +void qdf_cpumask_or(qdf_cpu_mask *dstp, qdf_cpu_mask *src1p, + qdf_cpu_mask *src2p) +{ + cpumask_or(dstp, src1p, src2p); +} + +qdf_export_symbol(qdf_cpumask_or);