Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0-only */
0002 /*
0003  * O(1) TX queue with built-in allocator for ST-Ericsson CW1200 drivers
0004  *
0005  * Copyright (c) 2010, ST-Ericsson
0006  * Author: Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>
0007  */
0008 
0009 #ifndef CW1200_QUEUE_H_INCLUDED
0010 #define CW1200_QUEUE_H_INCLUDED
0011 
0012 /* private */ struct cw1200_queue_item;
0013 
0014 /* extern */ struct sk_buff;
0015 /* extern */ struct wsm_tx;
0016 /* extern */ struct cw1200_common;
0017 /* extern */ struct ieee80211_tx_queue_stats;
0018 /* extern */ struct cw1200_txpriv;
0019 
0020 /* forward */ struct cw1200_queue_stats;
0021 
0022 typedef void (*cw1200_queue_skb_dtor_t)(struct cw1200_common *priv,
0023                     struct sk_buff *skb,
0024                     const struct cw1200_txpriv *txpriv);
0025 
0026 struct cw1200_queue {
0027     struct cw1200_queue_stats *stats;
0028     size_t          capacity;
0029     size_t          num_queued;
0030     size_t          num_pending;
0031     size_t          num_sent;
0032     struct cw1200_queue_item *pool;
0033     struct list_head    queue;
0034     struct list_head    free_pool;
0035     struct list_head    pending;
0036     int         tx_locked_cnt;
0037     int         *link_map_cache;
0038     bool            overfull;
0039     spinlock_t      lock; /* Protect queue entry */
0040     u8          queue_id;
0041     u8          generation;
0042     struct timer_list   gc;
0043     unsigned long       ttl;
0044 };
0045 
0046 struct cw1200_queue_stats {
0047     spinlock_t      lock; /* Protect stats entry */
0048     int         *link_map_cache;
0049     int         num_queued;
0050     size_t          map_capacity;
0051     wait_queue_head_t   wait_link_id_empty;
0052     cw1200_queue_skb_dtor_t skb_dtor;
0053     struct cw1200_common    *priv;
0054 };
0055 
0056 struct cw1200_txpriv {
0057     u8 link_id;
0058     u8 raw_link_id;
0059     u8 tid;
0060     u8 rate_id;
0061     u8 offset;
0062 };
0063 
0064 int cw1200_queue_stats_init(struct cw1200_queue_stats *stats,
0065                 size_t map_capacity,
0066                 cw1200_queue_skb_dtor_t skb_dtor,
0067                 struct cw1200_common *priv);
0068 int cw1200_queue_init(struct cw1200_queue *queue,
0069               struct cw1200_queue_stats *stats,
0070               u8 queue_id,
0071               size_t capacity,
0072               unsigned long ttl);
0073 int cw1200_queue_clear(struct cw1200_queue *queue);
0074 void cw1200_queue_stats_deinit(struct cw1200_queue_stats *stats);
0075 void cw1200_queue_deinit(struct cw1200_queue *queue);
0076 
0077 size_t cw1200_queue_get_num_queued(struct cw1200_queue *queue,
0078                    u32 link_id_map);
0079 int cw1200_queue_put(struct cw1200_queue *queue,
0080              struct sk_buff *skb,
0081              struct cw1200_txpriv *txpriv);
0082 int cw1200_queue_get(struct cw1200_queue *queue,
0083              u32 link_id_map,
0084              struct wsm_tx **tx,
0085              struct ieee80211_tx_info **tx_info,
0086              const struct cw1200_txpriv **txpriv);
0087 int cw1200_queue_requeue(struct cw1200_queue *queue, u32 packet_id);
0088 int cw1200_queue_requeue_all(struct cw1200_queue *queue);
0089 int cw1200_queue_remove(struct cw1200_queue *queue,
0090             u32 packet_id);
0091 int cw1200_queue_get_skb(struct cw1200_queue *queue, u32 packet_id,
0092              struct sk_buff **skb,
0093              const struct cw1200_txpriv **txpriv);
0094 void cw1200_queue_lock(struct cw1200_queue *queue);
0095 void cw1200_queue_unlock(struct cw1200_queue *queue);
0096 bool cw1200_queue_get_xmit_timestamp(struct cw1200_queue *queue,
0097                      unsigned long *timestamp,
0098                      u32 pending_frame_id);
0099 
0100 bool cw1200_queue_stats_is_empty(struct cw1200_queue_stats *stats,
0101                  u32 link_id_map);
0102 
0103 static inline u8 cw1200_queue_get_queue_id(u32 packet_id)
0104 {
0105     return (packet_id >> 16) & 0xFF;
0106 }
0107 
0108 static inline u8 cw1200_queue_get_generation(u32 packet_id)
0109 {
0110     return (packet_id >>  8) & 0xFF;
0111 }
0112 
0113 #endif /* CW1200_QUEUE_H_INCLUDED */