|
@@ -37,14 +37,9 @@
|
|
|
#include <linux/netdevice.h>
|
|
|
#include <linux/etherdevice.h>
|
|
|
#include <linux/dma-mapping.h>
|
|
|
-#include <linux/types.h>
|
|
|
-#include <linux/scatterlist.h>
|
|
|
#include <cdf_types.h>
|
|
|
#include <cdf_status.h>
|
|
|
|
|
|
-#define __CDF_NBUF_NULL NULL
|
|
|
-
|
|
|
-
|
|
|
/*
|
|
|
* Use socket buffer as the underlying implentation as skbuf .
|
|
|
* Linux use sk_buff to represent both packet and data,
|
|
@@ -52,316 +47,286 @@
|
|
|
*/
|
|
|
typedef struct sk_buff *__cdf_nbuf_t;
|
|
|
|
|
|
-typedef void (*__cdf_nbuf_callback_fn)(struct sk_buff *skb);
|
|
|
-#define OSDEP_EAPOL_TID 6 /* send it on VO queue */
|
|
|
-
|
|
|
-/* CVG_NBUF_MAX_OS_FRAGS -
|
|
|
+/* NBUFCB_TX_MAX_OS_FRAGS
|
|
|
* max tx fragments provided by the OS
|
|
|
*/
|
|
|
-#define CVG_NBUF_MAX_OS_FRAGS 1
|
|
|
+#define NBUF_CB_TX_MAX_OS_FRAGS 1
|
|
|
|
|
|
-/* CVG_NBUF_MAX_EXTRA_FRAGS -
|
|
|
+/* NBUF_CB_TX_MAX_EXTRA_FRAGS -
|
|
|
* max tx fragments added by the driver
|
|
|
- * The driver will always add one tx fragment (the tx descriptor) and may
|
|
|
- * add a second tx fragment (e.g. a TSO segment's modified IP header).
|
|
|
+ * The driver will always add one tx fragment (the tx descriptor)
|
|
|
*/
|
|
|
-#define CVG_NBUF_MAX_EXTRA_FRAGS 2
|
|
|
+#define NBUF_CB_TX_MAX_EXTRA_FRAGS 2
|
|
|
|
|
|
-typedef void (*cdf_nbuf_trace_update_t)(char *);
|
|
|
+/*
|
|
|
+ * Make sure that cdf_dma_addr_t in the cb block is always 64 bit aligned
|
|
|
+ */
|
|
|
+typedef union {
|
|
|
+ uint64_t u64;
|
|
|
+ cdf_dma_addr_t dma_addr;
|
|
|
+} cdf_paddr_t;
|
|
|
|
|
|
/**
|
|
|
- * struct cvg_nbuf_cb - network buffer control block
|
|
|
- * @data_attr: Value that is programmed in CE descriptor, contains:
|
|
|
- * 1) CE classification enablement bit
|
|
|
- * 2) Pkt type (802.3 or Ethernet Type II)
|
|
|
- * 3) Pkt Offset (Usually the length of HTT/HTC desc.)
|
|
|
- * @trace: info for DP tracing
|
|
|
- * @mapped_paddr_lo: DMA mapping info
|
|
|
- * @extra_frags: Extra tx fragments
|
|
|
- * @owner_id: Owner id
|
|
|
- * @cdf_nbuf_callback_fn: Callback function
|
|
|
- * @priv_data: IPA specific priv data
|
|
|
- * @proto_type: Protocol type
|
|
|
- * @vdev_id: vdev id
|
|
|
- * @tx_htt2_frm: HTT 2 frame
|
|
|
- * @tx_htt2_reserved: HTT 2 reserved bits
|
|
|
+ * struct cdf_nbuf_cb - network buffer control block contents (skb->cb)
|
|
|
+ * - data passed between layers of the driver.
|
|
|
+ *
|
|
|
+ * Notes:
|
|
|
+ * 1. Hard limited to 48 bytes. Please count your bytes
|
|
|
+ * 2. The size of this structure has to be easily calculatable and
|
|
|
+ * consistently so: do not use any conditional compile flags
|
|
|
+ * 3. Split into a common part followed by a tx/rx overlay
|
|
|
+ * 4. There is only one extra frag, which represents the HTC/HTT header
|
|
|
+ *
|
|
|
+ * @common.paddr : physical addressed retrived by dma_map of nbuf->data
|
|
|
+ * @rx.lro_flags : hardware assisted flags:
|
|
|
+ * @rx.lro_eligible : flag to indicate whether the MSDU is LRO eligible
|
|
|
+ * @rx.tcp_proto : L4 protocol is TCP
|
|
|
+ * @rx.tcp_pure_ack : A TCP ACK packet with no payload
|
|
|
+ * @rx.ipv6_proto : L3 protocol is IPV6
|
|
|
+ * @rx.ip_offset : offset to IP header
|
|
|
+ * @rx.tcp_offset : offset to TCP header
|
|
|
+ * @rx.tcp_udp_chksum : L4 payload checksum
|
|
|
+ * @rx.tcp_seq_num : TCP sequence number
|
|
|
+ * @rx.tcp_ack_num : TCP ACK number
|
|
|
+ * @rx.flow_id_toeplitz: 32-bit 5-tuple Toeplitz hash
|
|
|
+ * @tx.extra_frag : represent HTC/HTT header
|
|
|
+ * @tx.efrag.vaddr : virtual address of ~
|
|
|
+ * @tx.efrag.paddr : physical/DMA address of ~
|
|
|
+ * @tx.efrag.len : length of efrag pointed by the above pointers
|
|
|
+ * @tx.efrag.num : number of extra frags ( 0 or 1)
|
|
|
+ * @tx.efrag.flags.nbuf : flag, nbuf payload to be swapped (wordstream)
|
|
|
+ * @tx.efrag.flags.efrag : flag, efrag payload to be swapped (wordstream)
|
|
|
+ * @tx.efrag.flags.chfrag_start: used by WIN
|
|
|
+ * @tx.efrags.flags.chfrag_end: used by WIN
|
|
|
+ * @tx.data_attr : value that is programmed into CE descr, includes:
|
|
|
+ * + (1) CE classification enablement bit
|
|
|
+ * + (2) packet type (802.3 or Ethernet type II)
|
|
|
+ * + (3) packet offset (usually length of HTC/HTT descr)
|
|
|
+ * @tx.trace : combined structure for DP and protocol trace
|
|
|
+ * @tx.trace.packet_state: {NBUF_TX_PKT_[(HDD)|(TXRX_ENQUEUE)|(TXRX_DEQUEUE)|
|
|
|
+ * + (TXRX)|(HTT)|(HTC)|(HIF)|(CE)|(FREE)]
|
|
|
+ * @tx.trace.packet_track: {NBUF_TX_PKT_[(DATA)|(MGMT)]_TRACK}
|
|
|
+ * @tx.trace.proto_type : bitmap of NBUF_PKT_TRAC_TYPE[(EAPOL)|(DHCP)|
|
|
|
+ * + (MGMT_ACTION)] - 4 bits
|
|
|
+ * @tx.trace.dp_trace : flag (Datapath trace)
|
|
|
+ * @tx.trace.htt2_frm : flag (high-latency path only)
|
|
|
+ * @tx.trace.vdev_id : vdev (for protocol trace)
|
|
|
+ * @tx.ipa.owned : packet owned by IPA
|
|
|
+ * @tx.ipa.priv : private data, used by IPA
|
|
|
*/
|
|
|
-struct cvg_nbuf_cb {
|
|
|
- uint32_t data_attr;
|
|
|
- /*
|
|
|
- * Store info for data path tracing
|
|
|
- */
|
|
|
- struct {
|
|
|
- uint8_t packet_state;
|
|
|
- uint8_t packet_track;
|
|
|
- uint8_t dp_trace;
|
|
|
- } trace;
|
|
|
-
|
|
|
- /*
|
|
|
- * Store the DMA mapping info for the network buffer fragments
|
|
|
- * provided by the OS.
|
|
|
- */
|
|
|
- uint32_t mapped_paddr_lo[CVG_NBUF_MAX_OS_FRAGS];
|
|
|
-#ifdef DEBUG_RX_RING_BUFFER
|
|
|
- uint32_t map_index;
|
|
|
-#endif
|
|
|
-
|
|
|
- /* store extra tx fragments provided by the driver */
|
|
|
- struct {
|
|
|
- /* vaddr -
|
|
|
- * CPU address (a.k.a. virtual address) of the tx fragments
|
|
|
- * added by the driver
|
|
|
- */
|
|
|
- unsigned char *vaddr[CVG_NBUF_MAX_EXTRA_FRAGS];
|
|
|
- /* paddr_lo -
|
|
|
- * bus address (a.k.a. physical address) of the tx fragments
|
|
|
- * added by the driver
|
|
|
- */
|
|
|
- uint32_t paddr_lo[CVG_NBUF_MAX_EXTRA_FRAGS];
|
|
|
- uint16_t len[CVG_NBUF_MAX_EXTRA_FRAGS];
|
|
|
- uint8_t num; /* how many extra frags has the driver added */
|
|
|
- uint8_t
|
|
|
- /*
|
|
|
- * Store a wordstream vs. bytestream flag for each extra
|
|
|
- * fragment, plus one more flag for the original fragment(s)
|
|
|
- * of the netbuf.
|
|
|
- */
|
|
|
-wordstream_flags:CVG_NBUF_MAX_EXTRA_FRAGS + 1;
|
|
|
- } extra_frags;
|
|
|
- uint32_t owner_id;
|
|
|
- __cdf_nbuf_callback_fn cdf_nbuf_callback_fn;
|
|
|
- unsigned long priv_data;
|
|
|
-#ifdef QCA_PKT_PROTO_TRACE
|
|
|
- unsigned char proto_type;
|
|
|
- unsigned char vdev_id;
|
|
|
-#endif /* QCA_PKT_PROTO_TRACE */
|
|
|
-#ifdef QCA_TX_HTT2_SUPPORT
|
|
|
- unsigned char tx_htt2_frm:1;
|
|
|
- unsigned char tx_htt2_reserved:7;
|
|
|
-#endif /* QCA_TX_HTT2_SUPPORT */
|
|
|
-};
|
|
|
-#ifdef DEBUG_RX_RING_BUFFER
|
|
|
-#define NBUF_MAP_ID(skb) \
|
|
|
- (((struct cvg_nbuf_cb *)((skb)->cb))->map_index)
|
|
|
-#endif
|
|
|
-#define NBUF_OWNER_ID(skb) \
|
|
|
- (((struct cvg_nbuf_cb *)((skb)->cb))->owner_id)
|
|
|
-#define NBUF_OWNER_PRIV_DATA(skb) \
|
|
|
- (((struct cvg_nbuf_cb *)((skb)->cb))->priv_data)
|
|
|
-#define NBUF_CALLBACK_FN(skb) \
|
|
|
- (((struct cvg_nbuf_cb *)((skb)->cb))->cdf_nbuf_callback_fn)
|
|
|
-#define NBUF_CALLBACK_FN_EXEC(skb) \
|
|
|
- (((struct cvg_nbuf_cb *)((skb)->cb))->cdf_nbuf_callback_fn)(skb)
|
|
|
-#define NBUF_MAPPED_PADDR_LO(skb) \
|
|
|
- (((struct cvg_nbuf_cb *)((skb)->cb))->mapped_paddr_lo[0])
|
|
|
-#define NBUF_NUM_EXTRA_FRAGS(skb) \
|
|
|
- (((struct cvg_nbuf_cb *)((skb)->cb))->extra_frags.num)
|
|
|
-#define NBUF_EXTRA_FRAG_VADDR(skb, frag_num) \
|
|
|
- (((struct cvg_nbuf_cb *)((skb)->cb))->extra_frags.vaddr[(frag_num)])
|
|
|
-#define NBUF_EXTRA_FRAG_PADDR_LO(skb, frag_num) \
|
|
|
- (((struct cvg_nbuf_cb *)((skb)->cb))->extra_frags.paddr_lo[(frag_num)])
|
|
|
-#define NBUF_EXTRA_FRAG_LEN(skb, frag_num) \
|
|
|
- (((struct cvg_nbuf_cb *)((skb)->cb))->extra_frags.len[(frag_num)])
|
|
|
-#define NBUF_EXTRA_FRAG_WORDSTREAM_FLAGS(skb) \
|
|
|
- (((struct cvg_nbuf_cb *)((skb)->cb))->extra_frags.wordstream_flags)
|
|
|
-
|
|
|
-#ifdef QCA_PKT_PROTO_TRACE
|
|
|
-#define NBUF_SET_PROTO_TYPE(skb, proto_type) \
|
|
|
- (((struct cvg_nbuf_cb *)((skb)->cb))->proto_type = proto_type)
|
|
|
-#define NBUF_GET_PROTO_TYPE(skb) \
|
|
|
- (((struct cvg_nbuf_cb *)((skb)->cb))->proto_type)
|
|
|
-#else
|
|
|
-#define NBUF_SET_PROTO_TYPE(skb, proto_type);
|
|
|
-#define NBUF_GET_PROTO_TYPE(skb) 0;
|
|
|
-#endif /* QCA_PKT_PROTO_TRACE */
|
|
|
-
|
|
|
-#ifdef QCA_TX_HTT2_SUPPORT
|
|
|
-#define NBUF_SET_TX_HTT2_FRM(skb, candi) \
|
|
|
- (((struct cvg_nbuf_cb *)((skb)->cb))->tx_htt2_frm = candi)
|
|
|
-#define NBUF_GET_TX_HTT2_FRM(skb) \
|
|
|
- (((struct cvg_nbuf_cb *)((skb)->cb))->tx_htt2_frm)
|
|
|
-#else
|
|
|
-#define NBUF_SET_TX_HTT2_FRM(skb, candi)
|
|
|
-#define NBUF_GET_TX_HTT2_FRM(skb) 0
|
|
|
-#endif /* QCA_TX_HTT2_SUPPORT */
|
|
|
+struct cdf_nbuf_cb {
|
|
|
+ /* common */
|
|
|
+ cdf_paddr_t paddr; /* of skb->data */
|
|
|
+ /* valid only in one direction */
|
|
|
+ union {
|
|
|
+ /* Note: MAX: 40 bytes */
|
|
|
+ struct {
|
|
|
+ uint32_t lro_eligible:1,
|
|
|
+ tcp_proto:1,
|
|
|
+ tcp_pure_ack:1,
|
|
|
+ ipv6_proto:1,
|
|
|
+ ip_offset:7,
|
|
|
+ tcp_offset:7;
|
|
|
+ uint32_t tcp_udp_chksum:16,
|
|
|
+ tcp_win:16;
|
|
|
+ uint32_t tcp_seq_num;
|
|
|
+ uint32_t tcp_ack_num;
|
|
|
+ uint32_t flow_id_toeplitz;
|
|
|
+ } rx; /* 20 bytes */
|
|
|
+
|
|
|
+ /* Note: MAX: 40 bytes */
|
|
|
+ struct {
|
|
|
+ struct {
|
|
|
+ unsigned char *vaddr;
|
|
|
+ cdf_paddr_t paddr;
|
|
|
+ uint16_t len;
|
|
|
+ uint8_t num; /* 0: cmn.addr; 1: tx.efrag */
|
|
|
+ union {
|
|
|
+ struct {
|
|
|
+ uint8_t flag_efrag:1,
|
|
|
+ flag_nbuf:1,
|
|
|
+ /* following for WIN */
|
|
|
+ flag_chfrag_start:1,
|
|
|
+ flag_chfrag_end:1,
|
|
|
+ reserved:4;
|
|
|
+ } bits;
|
|
|
+ uint8_t u8;
|
|
|
+ } flags;
|
|
|
+ } extra_frag; /* 20 bytes */
|
|
|
+ uint32_t data_attr; /* 4 bytes */
|
|
|
+ union {
|
|
|
+ struct {
|
|
|
+ uint8_t packet_state;
|
|
|
+ uint8_t packet_track:4,
|
|
|
+ proto_type:4;
|
|
|
+ uint8_t dp_trace:1,
|
|
|
+ htt2_frm:1,
|
|
|
+ rsrvd:6;
|
|
|
+ uint8_t vdev_id;
|
|
|
+ } hl;
|
|
|
+ struct {
|
|
|
+ uint8_t packet_state;
|
|
|
+ uint8_t packet_track:4,
|
|
|
+ proto_type:4;
|
|
|
+ uint8_t dp_trace:1,
|
|
|
+ rsrvd:7;
|
|
|
+ uint8_t vdev_id;
|
|
|
+ } ll; /* low latency */
|
|
|
+ } trace; /* 4 bytes */
|
|
|
+ struct {
|
|
|
+ uint32_t owned:1,
|
|
|
+ priv:31;
|
|
|
+ } ipa; /* 4 */
|
|
|
+ } tx; /* 32 bytes */
|
|
|
+ } u;
|
|
|
+}; /* struct cdf_nbuf_cb: MAX 48 bytes */
|
|
|
|
|
|
-#define NBUF_DATA_ATTR_SET(skb, data_attr) \
|
|
|
- (((struct cvg_nbuf_cb *)((skb)->cb))->data_attr = data_attr)
|
|
|
-
|
|
|
-#define NBUF_DATA_ATTR_GET(skb) \
|
|
|
- (((struct cvg_nbuf_cb *)((skb)->cb))->data_attr)
|
|
|
-
|
|
|
-#if defined(FEATURE_LRO)
|
|
|
/**
|
|
|
- * struct nbuf_rx_cb - network buffer control block
|
|
|
- * on the receive path of the skb
|
|
|
- * @lro_eligible: indicates whether the msdu is LRO eligible
|
|
|
- * @tcp_proto: indicates if this is a TCP packet
|
|
|
- * @ipv6_proto: indicates if this is an IPv6 packet
|
|
|
- * @ip_offset: offset to the IP header
|
|
|
- * @tcp_offset: offset to the TCP header
|
|
|
- * @tcp_udp_chksum: TCP payload checksum
|
|
|
- * @tcp_seq_num: TCP sequence number
|
|
|
- * @tcp_ack_num: TCP acknowledgement number
|
|
|
- * @flow_id_toeplitz: 32 bit 5-tuple flow id toeplitz hash
|
|
|
+ * access macros to cdf_nbuf_cb
|
|
|
+ * Note: These macros can be used as L-values as well as R-values.
|
|
|
+ * When used as R-values, they effectively function as "get" macros
|
|
|
+ * When used as L_values, they effectively function as "set" macros
|
|
|
*/
|
|
|
-struct nbuf_rx_cb {
|
|
|
- uint32_t lro_eligible:1,
|
|
|
- tcp_proto:1,
|
|
|
- tcp_pure_ack:1,
|
|
|
- ipv6_proto:1,
|
|
|
- ip_offset:7,
|
|
|
- tcp_offset:7;
|
|
|
- uint32_t tcp_udp_chksum:16,
|
|
|
- tcp_win:16;
|
|
|
- uint32_t tcp_seq_num;
|
|
|
- uint32_t tcp_ack_num;
|
|
|
- uint32_t flow_id_toeplitz;
|
|
|
-};
|
|
|
-
|
|
|
-#define NBUF_LRO_ELIGIBLE(skb) \
|
|
|
- (((struct nbuf_rx_cb *)((skb)->cb))->lro_eligible)
|
|
|
-#define NBUF_TCP_PROTO(skb) \
|
|
|
- (((struct nbuf_rx_cb *)((skb)->cb))->tcp_proto)
|
|
|
-#define NBUF_TCP_PURE_ACK(skb) \
|
|
|
- (((struct nbuf_rx_cb *)((skb)->cb))->tcp_pure_ack)
|
|
|
-#define NBUF_IPV6_PROTO(skb) \
|
|
|
- (((struct nbuf_rx_cb *)((skb)->cb))->ipv6_proto)
|
|
|
-#define NBUF_IP_OFFSET(skb) \
|
|
|
- (((struct nbuf_rx_cb *)((skb)->cb))->ip_offset)
|
|
|
-#define NBUF_TCP_OFFSET(skb) \
|
|
|
- (((struct nbuf_rx_cb *)((skb)->cb))->tcp_offset)
|
|
|
-#define NBUF_TCP_CHKSUM(skb) \
|
|
|
- (((struct nbuf_rx_cb *)((skb)->cb))->tcp_udp_chksum)
|
|
|
-#define NBUF_TCP_SEQ_NUM(skb) \
|
|
|
- (((struct nbuf_rx_cb *)((skb)->cb))->tcp_seq_num)
|
|
|
-#define NBUF_TCP_ACK_NUM(skb) \
|
|
|
- (((struct nbuf_rx_cb *)((skb)->cb))->tcp_ack_num)
|
|
|
-#define NBUF_TCP_WIN(skb) \
|
|
|
- (((struct nbuf_rx_cb *)((skb)->cb))->tcp_win)
|
|
|
-#define NBUF_FLOW_ID_TOEPLITZ(skb) \
|
|
|
- (((struct nbuf_rx_cb *)((skb)->cb))->flow_id_toeplitz)
|
|
|
-#endif /* FEATURE_LRO */
|
|
|
-
|
|
|
-#define NBUF_SET_PACKET_STATE(skb, pkt_state) \
|
|
|
- (((struct cvg_nbuf_cb *)((skb)->cb))->trace.packet_state = \
|
|
|
- pkt_state)
|
|
|
-#define NBUF_GET_PACKET_STATE(skb) \
|
|
|
- (((struct cvg_nbuf_cb *)((skb)->cb))->trace.packet_state)
|
|
|
-
|
|
|
-#define NBUF_SET_PACKET_TRACK(skb, pkt_track) \
|
|
|
- (((struct cvg_nbuf_cb *)((skb)->cb))->trace.packet_track = \
|
|
|
- pkt_track)
|
|
|
-#define NBUF_GET_PACKET_TRACK(skb) \
|
|
|
- (((struct cvg_nbuf_cb *)((skb)->cb))->trace.packet_track)
|
|
|
-
|
|
|
+#define NBUF_CB_PADDR(skb) \
|
|
|
+ (((struct cdf_nbuf_cb *)((skb)->cb))->paddr.dma_addr)
|
|
|
+#define NBUF_CB_RX_LRO_ELIGIBLE(skb) \
|
|
|
+ (((struct cdf_nbuf_cb *)((skb)->cb))->u.rx.lro_eligible)
|
|
|
+#define NBUF_CB_RX_TCP_PROTO(skb) \
|
|
|
+ (((struct cdf_nbuf_cb *)((skb)->cb))->u.rx.tcp_proto)
|
|
|
+#define NBUF_CB_RX_TCP_PURE_ACK(skb) \
|
|
|
+ (((struct cdf_nbuf_cb *)((skb)->cb))->u.rx.tcp_pure_ack)
|
|
|
+#define NBUF_CB_RX_IPV6_PROTO(skb) \
|
|
|
+ (((struct cdf_nbuf_cb *)((skb)->cb))->u.rx.ipv6_proto)
|
|
|
+#define NBUF_CB_RX_IP_OFFSET(skb) \
|
|
|
+ (((struct cdf_nbuf_cb *)((skb)->cb))->u.rx.ip_offset)
|
|
|
+#define NBUF_CB_RX_TCP_OFFSET(skb) \
|
|
|
+ (((struct cdf_nbuf_cb *)((skb)->cb))->u.rx.tcp_offset)
|
|
|
+#define NBUF_CB_RX_TCP_CHKSUM(skb) \
|
|
|
+ (((struct cdf_nbuf_cb *)((skb)->cb))->u.rx.tcp_udp_chksum)
|
|
|
+#define NBUF_CB_RX_TCP_OFFSET(skb) \
|
|
|
+ (((struct cdf_nbuf_cb *)((skb)->cb))->u.rx.tcp_offset)
|
|
|
+#define NBUF_CB_RX_TCP_WIN(skb) \
|
|
|
+ (((struct cdf_nbuf_cb *)((skb)->cb))->u.rx.tcp_win)
|
|
|
+#define NBUF_CB_RX_TCP_SEQ_NUM(skb) \
|
|
|
+ (((struct cdf_nbuf_cb *)((skb)->cb))->u.rx.tcp_seq_num)
|
|
|
+#define NBUF_CB_RX_TCP_ACK_NUM(skb) \
|
|
|
+ (((struct cdf_nbuf_cb *)((skb)->cb))->u.rx.tcp_ack_num)
|
|
|
+#define NBUF_CB_RX_FLOW_ID_TOEPLITZ(skb) \
|
|
|
+ (((struct cdf_nbuf_cb *)((skb)->cb))->u.rx.flow_id_toeplitz)
|
|
|
+
|
|
|
+#define NBUF_CB_TX_EXTRA_FRAG_VADDR(skb) \
|
|
|
+ (((struct cdf_nbuf_cb *)((skb)->cb))->u.tx.extra_frag.vaddr)
|
|
|
+#define NBUF_CB_TX_EXTRA_FRAG_PADDR(skb) \
|
|
|
+ (((struct cdf_nbuf_cb *)((skb)->cb))->u.tx.extra_frag.paddr.dma_addr)
|
|
|
+#define NBUF_CB_TX_EXTRA_FRAG_LEN(skb) \
|
|
|
+ (((struct cdf_nbuf_cb *)((skb)->cb))->u.tx.extra_frag.len)
|
|
|
+#define NBUF_CB_TX_NUM_EXTRA_FRAGS(skb) \
|
|
|
+ (((struct cdf_nbuf_cb *)((skb)->cb))->u.tx.extra_frag.num)
|
|
|
+#define NBUF_CB_TX_EXTRA_FRAG_WORDSTR_FLAGS(skb) \
|
|
|
+ (((struct cdf_nbuf_cb *)((skb)->cb))->u.tx.extra_frag.flags.u8)
|
|
|
+#define NBUF_CB_TX_EXTRA_FRAG_WORDSTR_EFRAG(skb) \
|
|
|
+ (((struct cdf_nbuf_cb *)((skb)->cb))->u.tx.extra_frag.flags.bits.flag_efrag)
|
|
|
+#define NBUF_CB_TX_EXTRA_FRAG_WORDSTR_NBUF(skb) \
|
|
|
+ (((struct cdf_nbuf_cb *)((skb)->cb))->u.tx.extra_frag.flags.bits.flag_nbuf)
|
|
|
+#define NBUF_CB_TX_DATA_ATTR(skb) \
|
|
|
+ (((struct cdf_nbuf_cb *)((skb)->cb))->u.tx.data_attr)
|
|
|
+#define NBUF_CB_TX_PACKET_STATE(skb) \
|
|
|
+ (((struct cdf_nbuf_cb *)((skb)->cb))->u.tx.trace.ll.packet_state)
|
|
|
+#define NBUF_CB_TX_PACKET_TRACK(skb) \
|
|
|
+ (((struct cdf_nbuf_cb *)((skb)->cb))->u.tx.trace.ll.packet_track)
|
|
|
+#define NBUF_CB_TX_PROTO_TYPE(skb) \
|
|
|
+ (((struct cdf_nbuf_cb *)((skb)->cb))->u.tx.trace.ll.proto_type)
|
|
|
#define NBUF_UPDATE_TX_PKT_COUNT(skb, PACKET_STATE) \
|
|
|
cdf_nbuf_set_state(skb, PACKET_STATE)
|
|
|
-
|
|
|
-#define CDF_NBUF_SET_DP_TRACE(skb, enable) \
|
|
|
- (((struct cvg_nbuf_cb *)((skb)->cb))->trace.dp_trace \
|
|
|
- = enable)
|
|
|
-#define CDF_NBUF_GET_DP_TRACE(skb) \
|
|
|
- (((struct cvg_nbuf_cb *)((skb)->cb))->trace.dp_trace)
|
|
|
-
|
|
|
-#define __cdf_nbuf_get_num_frags(skb) \
|
|
|
- /* assume the OS provides a single fragment */ \
|
|
|
- (NBUF_NUM_EXTRA_FRAGS(skb) + 1)
|
|
|
+#define NBUF_CB_TX_DP_TRACE(skb) \
|
|
|
+ (((struct cdf_nbuf_cb *)((skb)->cb))->u.tx.trace.ll.dp_trace)
|
|
|
+#define NBUF_CB_TX_HL_HTT2_FRM(skb) \
|
|
|
+ (((struct cdf_nbuf_cb *)((skb)->cb))->u.tx.trace.hl.htt2_frm)
|
|
|
+#define NBUF_CB_TX_VDEV_ID(skb) \
|
|
|
+ (((struct cdf_nbuf_cb *)((skb)->cb))->u.tx.trace.ll.vdev_id)
|
|
|
+#define NBUF_CB_TX_IPA_OWNED(skb) \
|
|
|
+ (((struct cdf_nbuf_cb *)((skb)->cb))->u.tx.ipa.owned)
|
|
|
+#define NBUF_CB_TX_IPA_PRIV(skb) \
|
|
|
+ (((struct cdf_nbuf_cb *)((skb)->cb))->u.tx.ipa.priv)
|
|
|
+
|
|
|
+#define __cdf_nbuf_get_num_frags(skb) \
|
|
|
+ (NBUF_CB_TX_NUM_EXTRA_FRAGS(skb) + 1)
|
|
|
|
|
|
#if defined(FEATURE_TSO)
|
|
|
-#define __cdf_nbuf_dec_num_frags(skb) \
|
|
|
- (NBUF_NUM_EXTRA_FRAGS(skb)--)
|
|
|
+#define __cdf_nbuf_reset_num_frags(skb) \
|
|
|
+ (NBUF_CB_TX_NUM_EXTRA_FRAGS(skb) = 0)
|
|
|
#endif
|
|
|
+/**
|
|
|
+ * end of nbuf->cb access macros
|
|
|
+ */
|
|
|
+
|
|
|
+typedef void (*cdf_nbuf_trace_update_t)(char *);
|
|
|
|
|
|
-#define __cdf_nbuf_frag_push_head( \
|
|
|
- skb, frag_len, frag_vaddr, frag_paddr_lo, frag_paddr_hi) \
|
|
|
- do { \
|
|
|
- int frag_num = NBUF_NUM_EXTRA_FRAGS(skb)++; \
|
|
|
- NBUF_EXTRA_FRAG_VADDR(skb, frag_num) = frag_vaddr; \
|
|
|
- NBUF_EXTRA_FRAG_PADDR_LO(skb, frag_num) = frag_paddr_lo; \
|
|
|
- NBUF_EXTRA_FRAG_LEN(skb, frag_num) = frag_len; \
|
|
|
+#define __cdf_nbuf_mapped_paddr_get(skb) \
|
|
|
+ NBUF_CB_PADDR(skb)
|
|
|
+
|
|
|
+#define __cdf_nbuf_mapped_paddr_set(skb, paddr) \
|
|
|
+ (NBUF_CB_PADDR(skb) = (paddr))
|
|
|
+
|
|
|
+#define __cdf_nbuf_frag_push_head( \
|
|
|
+ skb, frag_len, frag_vaddr, frag_paddr) \
|
|
|
+ do { \
|
|
|
+ NBUF_CB_TX_NUM_EXTRA_FRAGS(skb) = 1; \
|
|
|
+ NBUF_CB_TX_EXTRA_FRAG_VADDR(skb) = frag_vaddr; \
|
|
|
+ NBUF_CB_TX_EXTRA_FRAG_PADDR(skb) = frag_paddr; \
|
|
|
+ NBUF_CB_TX_EXTRA_FRAG_LEN(skb) = frag_len; \
|
|
|
} while (0)
|
|
|
|
|
|
-#define __cdf_nbuf_get_frag_len(skb, frag_num) \
|
|
|
- ((frag_num < NBUF_NUM_EXTRA_FRAGS(skb)) ? \
|
|
|
- NBUF_EXTRA_FRAG_LEN(skb, frag_num) : (skb)->len)
|
|
|
-
|
|
|
-#define __cdf_nbuf_get_frag_vaddr(skb, frag_num) \
|
|
|
- ((frag_num < NBUF_NUM_EXTRA_FRAGS(skb)) ? \
|
|
|
- NBUF_EXTRA_FRAG_VADDR(skb, frag_num) : ((skb)->data))
|
|
|
-
|
|
|
-#define __cdf_nbuf_get_frag_paddr_lo(skb, frag_num) \
|
|
|
- ((frag_num < NBUF_NUM_EXTRA_FRAGS(skb)) ? \
|
|
|
- NBUF_EXTRA_FRAG_PADDR_LO(skb, frag_num) : \
|
|
|
- /* assume that the OS only provides a single fragment */ \
|
|
|
- NBUF_MAPPED_PADDR_LO(skb))
|
|
|
-
|
|
|
-#define __cdf_nbuf_get_frag_is_wordstream(skb, frag_num) \
|
|
|
- ((frag_num < NBUF_NUM_EXTRA_FRAGS(skb)) ? \
|
|
|
- (NBUF_EXTRA_FRAG_WORDSTREAM_FLAGS(skb) >> \
|
|
|
- (frag_num)) & 0x1 : \
|
|
|
- (NBUF_EXTRA_FRAG_WORDSTREAM_FLAGS(skb) >> \
|
|
|
- (CVG_NBUF_MAX_EXTRA_FRAGS)) & 0x1)
|
|
|
-
|
|
|
-#define __cdf_nbuf_set_frag_is_wordstream(skb, frag_num, is_wordstream) \
|
|
|
- do { \
|
|
|
- if (frag_num >= NBUF_NUM_EXTRA_FRAGS(skb)) { \
|
|
|
- frag_num = CVG_NBUF_MAX_EXTRA_FRAGS; \
|
|
|
- } \
|
|
|
- /* clear the old value */ \
|
|
|
- NBUF_EXTRA_FRAG_WORDSTREAM_FLAGS(skb) &= ~(1 << frag_num); \
|
|
|
- /* set the new value */ \
|
|
|
- NBUF_EXTRA_FRAG_WORDSTREAM_FLAGS(skb) |= \
|
|
|
- ((is_wordstream) << frag_num); \
|
|
|
+#define __cdf_nbuf_get_frag_vaddr(skb, frag_num) \
|
|
|
+ ((frag_num < NBUF_CB_TX_NUM_EXTRA_FRAGS(skb)) ? \
|
|
|
+ NBUF_CB_TX_EXTRA_FRAG_VADDR(skb) : ((skb)->data))
|
|
|
+
|
|
|
+#define __cdf_nbuf_get_frag_paddr(skb, frag_num) \
|
|
|
+ ((frag_num < NBUF_CB_TX_NUM_EXTRA_FRAGS(skb)) ? \
|
|
|
+ NBUF_CB_TX_EXTRA_FRAG_PADDR(skb) : \
|
|
|
+ /* assume that the OS only provides a single fragment */ \
|
|
|
+ NBUF_CB_PADDR(skb))
|
|
|
+
|
|
|
+#define __cdf_nbuf_get_frag_len(skb, frag_num) \
|
|
|
+ ((frag_num < NBUF_CB_TX_NUM_EXTRA_FRAGS(skb)) ? \
|
|
|
+ NBUF_CB_TX_EXTRA_FRAG_LEN(skb) : (skb)->len)
|
|
|
+
|
|
|
+#define __cdf_nbuf_get_frag_is_wordstream(skb, frag) \
|
|
|
+ ((frag_num < NBUF_CB_TX_NUM_EXTRA_FRAGS(skb)) \
|
|
|
+ ? (NBUF_CB_TX_EXTRA_FRAG_WORDSTR_EFRAG(skb)) \
|
|
|
+ : (NBUF_CB_TX_EXTRA_FRAG_WORDSTR_NBUF(skb)))
|
|
|
+
|
|
|
+#define __cdf_nbuf_set_frag_is_wordstream(skb, frag_num, is_wstrm) \
|
|
|
+ do { \
|
|
|
+ if (frag_num >= NBUF_CB_TX_NUM_EXTRA_FRAGS(skb)) \
|
|
|
+ frag_num = NBUF_CB_TX_MAX_EXTRA_FRAGS; \
|
|
|
+ if (frag_num) \
|
|
|
+ NBUF_CB_TX_EXTRA_FRAG_WORDSTR_EFRAG(skb) = is_wstrm; \
|
|
|
+ else \
|
|
|
+ NBUF_CB_TX_EXTRA_FRAG_WORDSTR_NBUF(skb) = is_wstrm; \
|
|
|
} while (0)
|
|
|
|
|
|
#define __cdf_nbuf_trace_set_proto_type(skb, proto_type) \
|
|
|
- NBUF_SET_PROTO_TYPE(skb, proto_type)
|
|
|
+ (NBUF_CB_TX_PROTO_TYPE(skb) = (proto_type))
|
|
|
#define __cdf_nbuf_trace_get_proto_type(skb) \
|
|
|
- NBUF_GET_PROTO_TYPE(skb);
|
|
|
+ NBUF_CB_TX_PROTO_TYPE(skb)
|
|
|
|
|
|
-/**
|
|
|
- * __cdf_nbuf_data_attr_get() - Retrieves the data_attr value
|
|
|
- * from cvg_nbuf_cb (skb->cb)
|
|
|
- * @skb: Pointer to struct sk_buff
|
|
|
- *
|
|
|
- * Return: data_attr
|
|
|
- */
|
|
|
#define __cdf_nbuf_data_attr_get(skb) \
|
|
|
- NBUF_DATA_ATTR_GET(skb)
|
|
|
+ NBUF_CB_TX_DATA_ATTR(skb)
|
|
|
+#define __cdf_nbuf_data_attr_set(skb, data_attr) \
|
|
|
+ (NBUF_CB_TX_DATA_ATTR(skb) = (data_attr))
|
|
|
|
|
|
-/**
|
|
|
- * __cdf_nbuf_data_attr_set() - Sets the data_attr value
|
|
|
- * in cvg_nbuf_cb (skb->cb)
|
|
|
- * @skb: Pointer to struct sk_buff
|
|
|
- * @data_attr: packet type from the enum cdf_txrx_pkt_type
|
|
|
- *
|
|
|
- * Return:
|
|
|
- */
|
|
|
-static inline void
|
|
|
-__cdf_nbuf_data_attr_set(struct sk_buff *skb,
|
|
|
- uint32_t data_attr)
|
|
|
-{
|
|
|
- NBUF_DATA_ATTR_SET(skb, data_attr);
|
|
|
-}
|
|
|
+#define __cdf_nbuf_ipa_owned_get(skb) \
|
|
|
+ NBUF_CB_TX_IPA_OWNED(skb)
|
|
|
|
|
|
-/**
|
|
|
- * typedef struct __cdf_nbuf_queue_t - network buffer queue
|
|
|
- * @head: Head pointer
|
|
|
- * @tail: Tail pointer
|
|
|
- * @qlen: Queue length
|
|
|
- */
|
|
|
-typedef struct __cdf_nbuf_qhead {
|
|
|
- struct sk_buff *head;
|
|
|
- struct sk_buff *tail;
|
|
|
- unsigned int qlen;
|
|
|
-} __cdf_nbuf_queue_t;
|
|
|
+#define __cdf_nbuf_ipa_owned_set(skb) \
|
|
|
+ (NBUF_CB_TX_IPA_OWNED(skb) = 1)
|
|
|
|
|
|
-/*
|
|
|
- * Use sk_buff_head as the implementation of cdf_nbuf_queue_t.
|
|
|
- * Because the queue head will most likely put in some structure,
|
|
|
- * we don't use pointer type as the definition.
|
|
|
- */
|
|
|
+#define __cdf_nbuf_ipa_priv_get(skb) \
|
|
|
+ NBUF_CB_TX_IPA_PRIV(skb)
|
|
|
+
|
|
|
+#define __cdf_nbuf_ipa_priv_set(skb, priv) \
|
|
|
+ (NBUF_CB_TX_IPA_PRIV(skb) = (priv))
|
|
|
|
|
|
/*
|
|
|
* prototypes. Implemented in cdf_nbuf.c
|
|
@@ -417,9 +382,9 @@ static inline size_t __cdf_nbuf_len(struct sk_buff *skb)
|
|
|
{
|
|
|
int i, extra_frag_len = 0;
|
|
|
|
|
|
- i = NBUF_NUM_EXTRA_FRAGS(skb);
|
|
|
- while (i-- > 0)
|
|
|
- extra_frag_len += NBUF_EXTRA_FRAG_LEN(skb, i);
|
|
|
+ i = NBUF_CB_TX_NUM_EXTRA_FRAGS(skb);
|
|
|
+ if (i > 0)
|
|
|
+ extra_frag_len = NBUF_CB_TX_EXTRA_FRAG_LEN(skb);
|
|
|
|
|
|
return extra_frag_len + skb->len;
|
|
|
}
|
|
@@ -460,7 +425,9 @@ __cdf_nbuf_cat(struct sk_buff *dst, struct sk_buff *src)
|
|
|
return __cdf_os_to_status(error);
|
|
|
}
|
|
|
|
|
|
-/**************************nbuf manipulation routines*****************/
|
|
|
+/*
|
|
|
+ * nbuf manipulation routines
|
|
|
+ */
|
|
|
|
|
|
/**
|
|
|
* __cdf_nbuf_headroom() - return the amount of tail space available
|
|
@@ -494,8 +461,8 @@ static inline uint32_t __cdf_nbuf_tailroom(struct sk_buff *skb)
|
|
|
*/
|
|
|
static inline uint8_t *__cdf_nbuf_push_head(struct sk_buff *skb, size_t size)
|
|
|
{
|
|
|
- if (NBUF_MAPPED_PADDR_LO(skb))
|
|
|
- NBUF_MAPPED_PADDR_LO(skb) -= size;
|
|
|
+ if (NBUF_CB_PADDR(skb))
|
|
|
+ NBUF_CB_PADDR(skb) -= size;
|
|
|
|
|
|
return skb_push(skb, size);
|
|
|
}
|
|
@@ -530,8 +497,8 @@ static inline uint8_t *__cdf_nbuf_put_tail(struct sk_buff *skb, size_t size)
|
|
|
*/
|
|
|
static inline uint8_t *__cdf_nbuf_pull_head(struct sk_buff *skb, size_t size)
|
|
|
{
|
|
|
- if (NBUF_MAPPED_PADDR_LO(skb))
|
|
|
- NBUF_MAPPED_PADDR_LO(skb) += size;
|
|
|
+ if (NBUF_CB_PADDR(skb))
|
|
|
+ NBUF_CB_PADDR(skb) += size;
|
|
|
|
|
|
return skb_pull(skb, size);
|
|
|
}
|
|
@@ -548,151 +515,6 @@ static inline void __cdf_nbuf_trim_tail(struct sk_buff *skb, size_t size)
|
|
|
return skb_trim(skb, skb->len - size);
|
|
|
}
|
|
|
|
|
|
-/*********************nbuf private buffer routines*************/
|
|
|
-
|
|
|
-/**
|
|
|
- * __cdf_nbuf_peek_header() - return the header's addr & m_len
|
|
|
- * @skb: Pointer to network buffer
|
|
|
- * @addr: Pointer to store header's addr
|
|
|
- * @m_len: network buffer length
|
|
|
- *
|
|
|
- * Return: none
|
|
|
- */
|
|
|
-static inline void
|
|
|
-__cdf_nbuf_peek_header(struct sk_buff *skb, uint8_t **addr, uint32_t *len)
|
|
|
-{
|
|
|
- *addr = skb->data;
|
|
|
- *len = skb->len;
|
|
|
-}
|
|
|
-
|
|
|
-/******************Custom queue*************/
|
|
|
-
|
|
|
-/**
|
|
|
- * __cdf_nbuf_queue_init() - initiallize the queue head
|
|
|
- * @qhead: Queue head
|
|
|
- *
|
|
|
- * Return: CDF status
|
|
|
- */
|
|
|
-static inline CDF_STATUS __cdf_nbuf_queue_init(__cdf_nbuf_queue_t *qhead)
|
|
|
-{
|
|
|
- memset(qhead, 0, sizeof(struct __cdf_nbuf_qhead));
|
|
|
- return CDF_STATUS_SUCCESS;
|
|
|
-}
|
|
|
-
|
|
|
-/**
|
|
|
- * __cdf_nbuf_queue_add() - add an skb in the tail of the queue
|
|
|
- * @qhead: Queue head
|
|
|
- * @skb: Pointer to network buffer
|
|
|
- *
|
|
|
- * This is a lockless version, driver must acquire locks if it
|
|
|
- * needs to synchronize
|
|
|
- *
|
|
|
- * Return: none
|
|
|
- */
|
|
|
-static inline void
|
|
|
-__cdf_nbuf_queue_add(__cdf_nbuf_queue_t *qhead, struct sk_buff *skb)
|
|
|
-{
|
|
|
- skb->next = NULL; /*Nullify the next ptr */
|
|
|
-
|
|
|
- if (!qhead->head)
|
|
|
- qhead->head = skb;
|
|
|
- else
|
|
|
- qhead->tail->next = skb;
|
|
|
-
|
|
|
- qhead->tail = skb;
|
|
|
- qhead->qlen++;
|
|
|
-}
|
|
|
-
|
|
|
-/**
|
|
|
- * __cdf_nbuf_queue_insert_head() - add an skb at the head of the queue
|
|
|
- * @qhead: Queue head
|
|
|
- * @skb: Pointer to network buffer
|
|
|
- *
|
|
|
- * This is a lockless version, driver must acquire locks if it needs to
|
|
|
- * synchronize
|
|
|
- *
|
|
|
- * Return: none
|
|
|
- */
|
|
|
-static inline void
|
|
|
-__cdf_nbuf_queue_insert_head(__cdf_nbuf_queue_t *qhead, __cdf_nbuf_t skb)
|
|
|
-{
|
|
|
- if (!qhead->head) {
|
|
|
- /*Empty queue Tail pointer Must be updated */
|
|
|
- qhead->tail = skb;
|
|
|
- }
|
|
|
- skb->next = qhead->head;
|
|
|
- qhead->head = skb;
|
|
|
- qhead->qlen++;
|
|
|
-}
|
|
|
-
|
|
|
-/**
|
|
|
- * __cdf_nbuf_queue_remove() - remove a skb from the head of the queue
|
|
|
- * @qhead: Queue head
|
|
|
- *
|
|
|
- * This is a lockless version. Driver should take care of the locks
|
|
|
- *
|
|
|
- * Return: skb or NULL
|
|
|
- */
|
|
|
-static inline
|
|
|
-struct sk_buff *__cdf_nbuf_queue_remove(__cdf_nbuf_queue_t *qhead)
|
|
|
-{
|
|
|
- __cdf_nbuf_t tmp = NULL;
|
|
|
-
|
|
|
- if (qhead->head) {
|
|
|
- qhead->qlen--;
|
|
|
- tmp = qhead->head;
|
|
|
- if (qhead->head == qhead->tail) {
|
|
|
- qhead->head = NULL;
|
|
|
- qhead->tail = NULL;
|
|
|
- } else {
|
|
|
- qhead->head = tmp->next;
|
|
|
- }
|
|
|
- tmp->next = NULL;
|
|
|
- }
|
|
|
- return tmp;
|
|
|
-}
|
|
|
-
|
|
|
-/**
|
|
|
- * __cdf_nbuf_queue_len() - return the queue length
|
|
|
- * @qhead: Queue head
|
|
|
- *
|
|
|
- * Return: Queue length
|
|
|
- */
|
|
|
-static inline uint32_t __cdf_nbuf_queue_len(__cdf_nbuf_queue_t *qhead)
|
|
|
-{
|
|
|
- return qhead->qlen;
|
|
|
-}
|
|
|
-
|
|
|
-/**
|
|
|
- * __cdf_nbuf_queue_next() - return the next skb from packet chain
|
|
|
- * @skb: Pointer to network buffer
|
|
|
- *
|
|
|
- * This API returns the next skb from packet chain, remember the skb is
|
|
|
- * still in the queue
|
|
|
- *
|
|
|
- * Return: NULL if no packets are there
|
|
|
- */
|
|
|
-static inline struct sk_buff *__cdf_nbuf_queue_next(struct sk_buff *skb)
|
|
|
-{
|
|
|
- return skb->next;
|
|
|
-}
|
|
|
-
|
|
|
-/**
|
|
|
- * __cdf_nbuf_is_queue_empty() - check if the queue is empty or not
|
|
|
- * @qhead: Queue head
|
|
|
- *
|
|
|
- * Return: true if length is 0 else false
|
|
|
- */
|
|
|
-static inline bool __cdf_nbuf_is_queue_empty(__cdf_nbuf_queue_t *qhead)
|
|
|
-{
|
|
|
- return qhead->qlen == 0;
|
|
|
-}
|
|
|
-
|
|
|
-/*
|
|
|
- * Use sk_buff_head as the implementation of cdf_nbuf_queue_t.
|
|
|
- * Because the queue head will most likely put in some structure,
|
|
|
- * we don't use pointer type as the definition.
|
|
|
- */
|
|
|
|
|
|
/*
|
|
|
* prototypes. Implemented in cdf_nbuf.c
|
|
@@ -998,9 +820,9 @@ __cdf_nbuf_set_protocol(struct sk_buff *skb, uint16_t protocol)
|
|
|
}
|
|
|
|
|
|
#define __cdf_nbuf_set_tx_htt2_frm(skb, candi) \
|
|
|
- NBUF_SET_TX_HTT2_FRM(skb, candi)
|
|
|
+ (NBUF_CB_TX_HL_HTT2_FRM(skb) = (candi))
|
|
|
#define __cdf_nbuf_get_tx_htt2_frm(skb) \
|
|
|
- NBUF_GET_TX_HTT2_FRM(skb)
|
|
|
+ NBUF_CB_TX_HL_HTT2_FRM(skb)
|
|
|
|
|
|
#if defined(FEATURE_TSO)
|
|
|
uint32_t __cdf_nbuf_get_tso_info(cdf_device_t osdev, struct sk_buff *skb,
|
|
@@ -1065,4 +887,170 @@ do { \
|
|
|
pkt_type = htt_pkt_type_ethernet; \
|
|
|
\
|
|
|
} while (0)
|
|
|
+
|
|
|
+/**
|
|
|
+ * nbuf private buffer routines
|
|
|
+ */
|
|
|
+
|
|
|
+/**
|
|
|
+ * __cdf_nbuf_peek_header() - return the header's addr & m_len
|
|
|
+ * @skb: Pointer to network buffer
|
|
|
+ * @addr: Pointer to store header's addr
|
|
|
+ * @m_len: network buffer length
|
|
|
+ *
|
|
|
+ * Return: none
|
|
|
+ */
|
|
|
+static inline void
|
|
|
+__cdf_nbuf_peek_header(struct sk_buff *skb, uint8_t **addr, uint32_t *len)
|
|
|
+{
|
|
|
+ *addr = skb->data;
|
|
|
+ *len = skb->len;
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * typedef struct __cdf_nbuf_queue_t - network buffer queue
|
|
|
+ * @head: Head pointer
|
|
|
+ * @tail: Tail pointer
|
|
|
+ * @qlen: Queue length
|
|
|
+ */
|
|
|
+typedef struct __cdf_nbuf_qhead {
|
|
|
+ struct sk_buff *head;
|
|
|
+ struct sk_buff *tail;
|
|
|
+ unsigned int qlen;
|
|
|
+} __cdf_nbuf_queue_t;
|
|
|
+
|
|
|
+/******************Functions *************/
|
|
|
+
|
|
|
+/**
|
|
|
+ * __cdf_nbuf_queue_init() - initiallize the queue head
|
|
|
+ * @qhead: Queue head
|
|
|
+ *
|
|
|
+ * Return: CDF status
|
|
|
+ */
|
|
|
+static inline CDF_STATUS __cdf_nbuf_queue_init(__cdf_nbuf_queue_t *qhead)
|
|
|
+{
|
|
|
+ memset(qhead, 0, sizeof(struct __cdf_nbuf_qhead));
|
|
|
+ return CDF_STATUS_SUCCESS;
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * __cdf_nbuf_queue_add() - add an skb in the tail of the queue
|
|
|
+ * @qhead: Queue head
|
|
|
+ * @skb: Pointer to network buffer
|
|
|
+ *
|
|
|
+ * This is a lockless version, driver must acquire locks if it
|
|
|
+ * needs to synchronize
|
|
|
+ *
|
|
|
+ * Return: none
|
|
|
+ */
|
|
|
+static inline void
|
|
|
+__cdf_nbuf_queue_add(__cdf_nbuf_queue_t *qhead, struct sk_buff *skb)
|
|
|
+{
|
|
|
+ skb->next = NULL; /*Nullify the next ptr */
|
|
|
+
|
|
|
+ if (!qhead->head)
|
|
|
+ qhead->head = skb;
|
|
|
+ else
|
|
|
+ qhead->tail->next = skb;
|
|
|
+
|
|
|
+ qhead->tail = skb;
|
|
|
+ qhead->qlen++;
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * __cdf_nbuf_queue_insert_head() - add an skb at the head of the queue
|
|
|
+ * @qhead: Queue head
|
|
|
+ * @skb: Pointer to network buffer
|
|
|
+ *
|
|
|
+ * This is a lockless version, driver must acquire locks if it needs to
|
|
|
+ * synchronize
|
|
|
+ *
|
|
|
+ * Return: none
|
|
|
+ */
|
|
|
+static inline void
|
|
|
+__cdf_nbuf_queue_insert_head(__cdf_nbuf_queue_t *qhead, __cdf_nbuf_t skb)
|
|
|
+{
|
|
|
+ if (!qhead->head) {
|
|
|
+ /*Empty queue Tail pointer Must be updated */
|
|
|
+ qhead->tail = skb;
|
|
|
+ }
|
|
|
+ skb->next = qhead->head;
|
|
|
+ qhead->head = skb;
|
|
|
+ qhead->qlen++;
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * __cdf_nbuf_queue_remove() - remove a skb from the head of the queue
|
|
|
+ * @qhead: Queue head
|
|
|
+ *
|
|
|
+ * This is a lockless version. Driver should take care of the locks
|
|
|
+ *
|
|
|
+ * Return: skb or NULL
|
|
|
+ */
|
|
|
+static inline
|
|
|
+struct sk_buff *__cdf_nbuf_queue_remove(__cdf_nbuf_queue_t *qhead)
|
|
|
+{
|
|
|
+ __cdf_nbuf_t tmp = NULL;
|
|
|
+
|
|
|
+ if (qhead->head) {
|
|
|
+ qhead->qlen--;
|
|
|
+ tmp = qhead->head;
|
|
|
+ if (qhead->head == qhead->tail) {
|
|
|
+ qhead->head = NULL;
|
|
|
+ qhead->tail = NULL;
|
|
|
+ } else {
|
|
|
+ qhead->head = tmp->next;
|
|
|
+ }
|
|
|
+ tmp->next = NULL;
|
|
|
+ }
|
|
|
+ return tmp;
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * __cdf_nbuf_queue_len() - return the queue length
|
|
|
+ * @qhead: Queue head
|
|
|
+ *
|
|
|
+ * Return: Queue length
|
|
|
+ */
|
|
|
+static inline uint32_t __cdf_nbuf_queue_len(__cdf_nbuf_queue_t *qhead)
|
|
|
+{
|
|
|
+ return qhead->qlen;
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * __cdf_nbuf_queue_next() - return the next skb from packet chain
|
|
|
+ * @skb: Pointer to network buffer
|
|
|
+ *
|
|
|
+ * This API returns the next skb from packet chain, remember the skb is
|
|
|
+ * still in the queue
|
|
|
+ *
|
|
|
+ * Return: NULL if no packets are there
|
|
|
+ */
|
|
|
+static inline struct sk_buff *__cdf_nbuf_queue_next(struct sk_buff *skb)
|
|
|
+{
|
|
|
+ return skb->next;
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * __cdf_nbuf_is_queue_empty() - check if the queue is empty or not
|
|
|
+ * @qhead: Queue head
|
|
|
+ *
|
|
|
+ * Return: true if length is 0 else false
|
|
|
+ */
|
|
|
+static inline bool __cdf_nbuf_is_queue_empty(__cdf_nbuf_queue_t *qhead)
|
|
|
+{
|
|
|
+ return qhead->qlen == 0;
|
|
|
+}
|
|
|
+
|
|
|
+/*
|
|
|
+ * Use sk_buff_head as the implementation of cdf_nbuf_queue_t.
|
|
|
+ * Because the queue head will most likely put in some structure,
|
|
|
+ * we don't use pointer type as the definition.
|
|
|
+ */
|
|
|
+
|
|
|
+/*
|
|
|
+ * Use sk_buff_head as the implementation of cdf_nbuf_queue_t.
|
|
|
+ * Because the queue head will most likely put in some structure,
|
|
|
+ * we don't use pointer type as the definition.
|
|
|
+ */
|
|
|
#endif /*_I_CDF_NET_BUF_H */
|