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 22 typedef void (*cw1200_queue_skb_dtor_t)(struct cw1200_common *priv, 23 struct sk_buff *skb, 24 const struct cw1200_txpriv *txpriv); 25 26 struct 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 46 struct 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 56 struct cw1200_txpriv { 57 u8 link_id; 58 u8 raw_link_id; 59 u8 tid; 60 u8 rate_id; 61 u8 offset; 62 }; 63 64 int 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); 68 int 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); 73 int cw1200_queue_clear(struct cw1200_queue *queue); 74 void cw1200_queue_stats_deinit(struct cw1200_queue_stats *stats); 75 void cw1200_queue_deinit(struct cw1200_queue *queue); 76 77 size_t cw1200_queue_get_num_queued(struct cw1200_queue *queue, 78 u32 link_id_map); 79 int cw1200_queue_put(struct cw1200_queue *queue, 80 struct sk_buff *skb, 81 struct cw1200_txpriv *txpriv); 82 int 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); 87 int cw1200_queue_requeue(struct cw1200_queue *queue, u32 packet_id); 88 int cw1200_queue_requeue_all(struct cw1200_queue *queue); 89 int cw1200_queue_remove(struct cw1200_queue *queue, 90 u32 packet_id); 91 int cw1200_queue_get_skb(struct cw1200_queue *queue, u32 packet_id, 92 struct sk_buff **skb, 93 const struct cw1200_txpriv **txpriv); 94 void cw1200_queue_lock(struct cw1200_queue *queue); 95 void cw1200_queue_unlock(struct cw1200_queue *queue); 96 bool cw1200_queue_get_xmit_timestamp(struct cw1200_queue *queue, 97 unsigned long *timestamp, 98 u32 pending_frame_id); 99 100 bool cw1200_queue_stats_is_empty(struct cw1200_queue_stats *stats, 101 u32 link_id_map); 102 103 static inline u8 cw1200_queue_get_queue_id(u32 packet_id) 104 { 105 return (packet_id >> 16) & 0xFF; 106 } 107 108 static 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