1/* SPDX-License-Identifier: GPL-2.0-only */
2/*
3 * O(1) TX queue with built-in allocator for ST-Ericsson CW1200 drivers
4 *
5 * Copyright (c) 2010, ST-Ericsson
6 * Author: Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>
7 */
8
9#ifndef CW1200_QUEUE_H_INCLUDED
10#define CW1200_QUEUE_H_INCLUDED
11
12/* private */ struct cw1200_queue_item;
13
14/* extern */ struct sk_buff;
15/* extern */ struct wsm_tx;
16/* extern */ struct cw1200_common;
17/* extern */ struct ieee80211_tx_queue_stats;
18/* extern */ struct cw1200_txpriv;
19
20/* forward */ struct cw1200_queue_stats;
21
22typedef void (*cw1200_queue_skb_dtor_t)(struct cw1200_common *priv,
23					struct sk_buff *skb,
24					const struct cw1200_txpriv *txpriv);
25
26struct cw1200_queue {
27	struct cw1200_queue_stats *stats;
28	size_t			capacity;
29	size_t			num_queued;
30	size_t			num_pending;
31	size_t			num_sent;
32	struct cw1200_queue_item *pool;
33	struct list_head	queue;
34	struct list_head	free_pool;
35	struct list_head	pending;
36	int			tx_locked_cnt;
37	int			*link_map_cache;
38	bool			overfull;
39	spinlock_t		lock; /* Protect queue entry */
40	u8			queue_id;
41	u8			generation;
42	struct timer_list	gc;
43	unsigned long		ttl;
44};
45
46struct cw1200_queue_stats {
47	spinlock_t		lock; /* Protect stats entry */
48	int			*link_map_cache;
49	int			num_queued;
50	size_t			map_capacity;
51	wait_queue_head_t	wait_link_id_empty;
52	cw1200_queue_skb_dtor_t	skb_dtor;
53	struct cw1200_common	*priv;
54};
55
56struct cw1200_txpriv {
57	u8 link_id;
58	u8 raw_link_id;
59	u8 tid;
60	u8 rate_id;
61	u8 offset;
62};
63
64int cw1200_queue_stats_init(struct cw1200_queue_stats *stats,
65			    size_t map_capacity,
66			    cw1200_queue_skb_dtor_t skb_dtor,
67			    struct cw1200_common *priv);
68int cw1200_queue_init(struct cw1200_queue *queue,
69		      struct cw1200_queue_stats *stats,
70		      u8 queue_id,
71		      size_t capacity,
72		      unsigned long ttl);
73int cw1200_queue_clear(struct cw1200_queue *queue);
74void cw1200_queue_stats_deinit(struct cw1200_queue_stats *stats);
75void cw1200_queue_deinit(struct cw1200_queue *queue);
76
77size_t cw1200_queue_get_num_queued(struct cw1200_queue *queue,
78				   u32 link_id_map);
79int cw1200_queue_put(struct cw1200_queue *queue,
80		     struct sk_buff *skb,
81		     struct cw1200_txpriv *txpriv);
82int cw1200_queue_get(struct cw1200_queue *queue,
83		     u32 link_id_map,
84		     struct wsm_tx **tx,
85		     struct ieee80211_tx_info **tx_info,
86		     const struct cw1200_txpriv **txpriv);
87int cw1200_queue_requeue(struct cw1200_queue *queue, u32 packet_id);
88int cw1200_queue_requeue_all(struct cw1200_queue *queue);
89int cw1200_queue_remove(struct cw1200_queue *queue,
90			u32 packet_id);
91int cw1200_queue_get_skb(struct cw1200_queue *queue, u32 packet_id,
92			 struct sk_buff **skb,
93			 const struct cw1200_txpriv **txpriv);
94void cw1200_queue_lock(struct cw1200_queue *queue);
95void cw1200_queue_unlock(struct cw1200_queue *queue);
96bool cw1200_queue_get_xmit_timestamp(struct cw1200_queue *queue,
97				     unsigned long *timestamp,
98				     u32 pending_frame_id);
99
100bool cw1200_queue_stats_is_empty(struct cw1200_queue_stats *stats,
101				 u32 link_id_map);
102
103static inline u8 cw1200_queue_get_queue_id(u32 packet_id)
104{
105	return (packet_id >> 16) & 0xFF;
106}
107
108static inline u8 cw1200_queue_get_generation(u32 packet_id)
109{
110	return (packet_id >>  8) & 0xFF;
111}
112
113#endif /* CW1200_QUEUE_H_INCLUDED */
114