hc
2024-03-25 edb30157bad0c0001c32b854271ace01d3b9a16a
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
/**
 * aicwf_txrxif.h
 *
 * bus function declarations
 *
 * Copyright (C) AICSemi 2018-2020
 */
 
#ifndef _AICWF_TXRXIF_H_
#define _AICWF_TXRXIF_H_
 
#include <linux/skbuff.h>
#include <linux/sched.h>
#include "aicsdio.h"
 
#define CMD_BUF_MAX                 1536
#define TXPKT_BLOCKSIZE             512
#define MAX_AGGR_TXPKT_LEN          (1536*4)
#define CMD_TX_TIMEOUT              5000
#define TX_ALIGNMENT                4
 
#define RX_HWHRD_LEN                60 //58->60 word allined
#define CCMP_OR_WEP_INFO            8
#define MAX_RXQLEN                  2000
#define RX_ALIGNMENT                4
 
#define DEBUG_ERROR_LEVEL           0
#define DEBUG_DEBUG_LEVEL           1
#define DEBUG_INFO_LEVEL            2
 
#define DBG_LEVEL                   DEBUG_DEBUG_LEVEL
 
#define txrx_err(fmt, ...)          pr_err("aicbsp: txrx_err:<%s,%d>: " fmt, __func__, __LINE__, ##__VA_ARGS__)
#define sdio_err(fmt, ...)          pr_err("aicbsp: sdio_err:<%s,%d>: " fmt, __func__, __LINE__, ##__VA_ARGS__)
#define usb_err(fmt, ...)           pr_err("aicbsp: usb_err:<%s,%d>: " fmt, __func__, __LINE__, ##__VA_ARGS__)
#if DBG_LEVEL >= DEBUG_DEBUG_LEVEL
#define sdio_dbg(fmt, ...)          printk("aicbsp: " fmt, ##__VA_ARGS__)
#define usb_dbg(fmt, ...)           printk("aicbsp: " fmt, ##__VA_ARGS__)
#else
#define sdio_dbg(fmt, ...)
#define usb_dbg(fmt, ...)
#endif
#if DBG_LEVEL >= DEBUG_INFO_LEVEL
#define sdio_info(fmt, ...)         printk("aicbsp: " fmt, ##__VA_ARGS__)
#define usb_info(fmt, ...)          printk("aicbsp: " fmt, ##__VA_ARGS__)
#else
#define sdio_info(fmt, ...)
#define usb_info(fmt, ...)
#endif
 
enum aicwf_bus_state {
   BUS_DOWN_ST,
   BUS_UP_ST
};
 
struct aicwf_bus_ops {
   int (*start) (struct device *dev);
   void (*stop) (struct device *dev);
   int (*txdata) (struct device *dev, struct sk_buff *skb);
   int (*txmsg) (struct device *dev, u8 *msg, uint len);
};
 
struct frame_queue {
   u16              num_prio;
   u16              hi_prio;
   u16              qmax;      /* max number of queued frames */
   u16              qcnt;
   struct sk_buff_head queuelist[8];
};
 
struct aicwf_bus {
   union {
       struct aic_sdio_dev *sdio;
       struct aic_usb_dev *usb;
   } bus_priv;
   struct device *dev;
   struct aicwf_bus_ops *ops;
   enum aicwf_bus_state state;
   u8 *cmd_buf;
   struct completion bustx_trgg;
   struct completion busrx_trgg;
   struct task_struct *bustx_thread;
   struct task_struct *busrx_thread;
};
 
struct aicwf_tx_priv {
#ifdef AICWF_SDIO_SUPPORT
   struct aic_sdio_dev *sdiodev;
   int fw_avail_bufcnt;
   //for cmd tx
   u8 *cmd_buf;
   uint cmd_len;
   bool cmd_txstate;
   bool cmd_tx_succ;
   struct semaphore cmd_txsema;
   wait_queue_head_t cmd_txdone_wait;
   //for data tx
   atomic_t tx_pktcnt;
 
   struct frame_queue txq;
   spinlock_t txqlock;
   struct semaphore txctl_sema;
#endif
#ifdef AICWF_USB_SUPPORT
   struct aic_usb_dev *usbdev;
#endif
   struct sk_buff *aggr_buf;
   atomic_t aggr_count;
   u8 *head;
   u8 *tail;
};
 
 
#define MAX_REORD_RXFRAME       250
#define REORDER_UPDATE_TIME     50
#define AICWF_REORDER_WINSIZE   64
#define SN_LESS(a, b)           (((a-b)&0x800) != 0)
#define SN_EQUAL(a, b)          (a == b)
 
struct reord_ctrl {
   struct aicwf_rx_priv *rx_priv;
   u8 enable;
   u16 ind_sn;
   u8 wsize_b;
   spinlock_t reord_list_lock;
   struct list_head reord_list;
   struct timer_list reord_timer;
   struct work_struct reord_timer_work;
};
 
struct reord_ctrl_info {
   u8 mac_addr[6];
   struct reord_ctrl preorder_ctrl[8];
   struct list_head list;
};
 
struct recv_msdu {
    struct sk_buff  *pkt;
    u8  tid;
    u16 seq_num;
    uint len;
    u8 *rx_data;
    //for pending rx reorder list
   struct list_head reord_pending_list;
   //for total frame list, when rxframe from busif, dequeue, when submit frame to net, enqueue
   struct list_head rxframe_list;
   struct reord_ctrl *preorder_ctrl;
};
 
struct aicwf_rx_priv {
   struct aic_sdio_dev *sdiodev;
   void *rwnx_vif;
   atomic_t rx_cnt;
   u32 data_len;
   spinlock_t rxqlock;
   struct frame_queue rxq;
 
   spinlock_t freeq_lock;
   struct list_head rxframes_freequeue;
   struct list_head stas_reord_list;
   spinlock_t stas_reord_lock;
   struct recv_msdu *recv_frames;
};
 
static inline int aicwf_bus_start(struct aicwf_bus *bus)
{
   return bus->ops->start(bus->dev);
}
 
static inline void aicwf_bus_stop(struct aicwf_bus *bus)
{
   bus->ops->stop(bus->dev);
}
 
static inline int aicwf_bus_txdata(struct aicwf_bus *bus, struct sk_buff *skb)
{
   return bus->ops->txdata(bus->dev, skb);
}
 
static inline int aicwf_bus_txmsg(struct aicwf_bus *bus, u8 *msg, uint len)
{
   return bus->ops->txmsg(bus->dev, msg, len);
}
 
static inline void aicwf_sched_timeout(u32 millisec)
{
   ulong timeout = 0, expires = 0;
   expires = jiffies + msecs_to_jiffies(millisec);
   timeout = millisec;
 
   while (timeout) {
       timeout = schedule_timeout(timeout);
       if (time_after(jiffies, expires))
           break;
   }
}
 
int aicwf_bus_init(uint bus_hdrlen, struct device *dev);
void aicwf_bus_deinit(struct device *dev);
void aicwf_tx_deinit(struct aicwf_tx_priv *tx_priv);
void aicwf_rx_deinit(struct aicwf_rx_priv *rx_priv);
struct aicwf_tx_priv *aicwf_tx_init(void *arg);
struct aicwf_rx_priv *aicwf_rx_init(void *arg);
void aicwf_frame_queue_init(struct frame_queue *pq, int num_prio, int max_len);
void aicwf_frame_queue_flush(struct frame_queue *pq);
bool aicwf_frame_enq(struct device *dev, struct frame_queue *q, struct sk_buff *pkt, int prio);
bool aicwf_rxframe_enqueue(struct device *dev, struct frame_queue *q, struct sk_buff *pkt);
bool aicwf_is_framequeue_empty(struct frame_queue *pq);
void aicwf_frame_tx(void *dev, struct sk_buff *skb);
void aicwf_dev_skb_free(struct sk_buff *skb);
struct sk_buff *aicwf_frame_dequeue(struct frame_queue *pq);
struct sk_buff *aicwf_frame_queue_peek_tail(struct frame_queue *pq, int *prio_out);
 
#endif /* _AICWF_TXRXIF_H_ */