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
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
|
#ifndef __LTE_DF_MAIN_H__
#define __LTE_DF_MAIN_H__
#include <linux/skbuff.h>
#include "eemcs_kal.h"
#define DISPATCH_AFTER_ALL_SKB_DONE 1 // Don't turn on these flag at same time
#define USE_QUE_WORK_DISPATCH_RX 0 // Don't turn on these flag at same time
#define USE_MULTI_QUE_DISPATCH 0
#define IMMEDIATE_RELOAD_DL_SKB 1 //move from makefile to solve compile error
#define FORMAL_DL_FLOW_CONTROL 1
#define FORMAL_DL_FLOW_CONTROL_TEST 0
#define BUFFER_POOL_FOR_EACH_QUE 1
#define EXPT_HELP_WAKELOCK_FOR_UART 1
#ifdef DBG_FEATURE_ADD_CCCI_SEQNO
#define DEBUG_SDIO
#endif
//#define DEV_MAX_PKT_SIZE (65536)
//#define DEV_MAX_PKT_SIZE (4096)
/* Change PKT SIZE to 3584Byte due to AP skb allocate way & page size issue */
#define DEV_MAX_PKT_SIZE (3584)
/* TX Q Threshold */
#define MT_LTE_TX_SWQ_Q0_TH (32)
#define MT_LTE_TX_SWQ_Q1_TH (32)
#define MT_LTE_TX_SWQ_Q2_TH (512) // Enalrge to 512 due to network usage
#define MT_LTE_TX_SWQ_Q3_TH (512) // Enalrge to 512 due to network usage
#define MT_LTE_TX_SWQ_Q4_TH (512) // Enalrge to 512 due to network usage
#define MT_LTE_TX_SWQ_Q5_TH (32)
#define MT_LTE_TX_SWQ_Q6_TH (32)
/* RX Q Threshold */
#define MT_LTE_RX_SWQ_Q0_TH (128)
#define MT_LTE_RX_SWQ_Q1_TH (256)
#define MT_LTE_RX_SWQ_Q2_TH (256)
#define MT_LTE_RX_SWQ_Q3_TH (256)
/* DL Buffer pool Threshold */
#define MT_LTE_DL_BUFF_POOL_TH (512)
typedef enum{
/* TX PORT 1 */
TX_PORT1_Q_MIN = 0 ,
TXQ_Q0 = 0 ,
TXQ_Q1 = 1 ,
TXQ_Q2 = 2 ,
TXQ_Q3 = 3 ,
TXQ_Q4 = 4 ,
TXQ_Q5 = 5 ,
TXQ_Q6 = 6 ,
TX_PORT1_Q_MAX = 6 ,
TXQ_NUM ,
} MTLTE_DF_TX_QUEUE_TYPE ;
#define TXQ_PORT1_Q_NUM (1 + TX_PORT1_Q_MAX - TX_PORT1_Q_MIN) // 7
typedef enum{
RXQ_Q0 = 0,
RXQ_Q1 = 1,
RXQ_Q2 = 2 ,
RXQ_Q3 = 3 ,
RXQ_NUM ,
} MTLTE_DF_RX_QUEUE_TYPE ;
typedef int (*MTLTE_DF_TO_DEV_CALLBACK)(unsigned int data);
typedef int (*MTLTE_DF_TO_HIF_CALLBACK)(unsigned int data);
struct mtlte_df_to_hif_callback {
MTLTE_DF_TO_HIF_CALLBACK callback_func ;
unsigned int private_data ;
} ;
struct mtlte_df_to_dev_callback {
MTLTE_DF_TO_DEV_CALLBACK callback_func ;
unsigned int private_data ;
} ;
typedef struct {
struct work_struct rxq_dispatch_work;
MTLTE_DF_RX_QUEUE_TYPE rxq_num;
} rxq_dispatch_work_t;
struct mtlte_df_core {
struct mtlte_df_to_dev_callback cb_handle[RXQ_NUM] ;
struct mtlte_df_to_dev_callback tx_cb_handle[TXQ_NUM] ;
MTLTE_DF_TO_DEV_CALLBACK cb_sw_int;
MTLTE_DF_TO_DEV_CALLBACK cb_wd_timeout;
MTLTE_DF_TO_DEV_CALLBACK cb_seq_err;
/* For Down Link path */
#if BUFFER_POOL_FOR_EACH_QUE
struct sk_buff_head dl_buffer_pool_queue[RXQ_NUM];
KAL_UINT32 df_skb_alloc_size[RXQ_NUM];
KAL_UINT32 df_buffer_pool_depth[RXQ_NUM];
#else
struct sk_buff_head dl_buffer_pool_queue;
#endif
struct workqueue_struct *dl_reload_work_queue;
struct work_struct dl_reload_work;
struct sk_buff_head dl_recv_wait_queue[RXQ_NUM];
volatile int dl_pkt_in_use[RXQ_NUM];
#if USE_MULTI_QUE_DISPATCH
struct workqueue_struct *rxq_dispatch_work_queue[RXQ_NUM];
rxq_dispatch_work_t rxq_dispatch_work_param[RXQ_NUM];
#else
struct workqueue_struct *dl_dispatch_work_queue;
struct work_struct dl_dispatch_work;
#endif
/* For Up Link path */
struct sk_buff_head ul_xmit_wait_queue[TXQ_NUM];
struct sk_buff_head ul_xmit_free_queue;
struct mtlte_df_to_hif_callback kick_hif_process ;
/* For dl_pkt_in_use */
KAL_MUTEX dl_pkt_lock ;
#if FORMAL_DL_FLOW_CONTROL
/* for Down Link flow control */
bool fl_ctrl_enable[RXQ_NUM];
bool fl_ctrl_free_skb[RXQ_NUM];
KAL_UINT32 fl_ctrl_limit[RXQ_NUM];
KAL_UINT32 fl_ctrl_threshold[RXQ_NUM];
bool fl_ctrl_full[RXQ_NUM];
atomic_t fl_ctrl_counter[RXQ_NUM];
KAL_UINT32 fl_ctrl_record[RXQ_NUM];
#endif
} ;
int mtlte_df_init(void) ;
int mtlte_df_deinit(void) ;
int mtlte_df_probe(void) ;
//int mtlte_df_remove(void) ;
int mtlte_df_remove_phase1(void) ;
int mtlte_df_remove_phase2(void) ;
/******************************************************
*
* API for HIF Layer
*
******************************************************/
/******************************************************
* UL data traffic APIs
******************************************************/
int mtlte_df_UL_pkt_in_swq(MTLTE_DF_TX_QUEUE_TYPE qno) ;
void mtlte_df_UL_callback(MTLTE_DF_TX_QUEUE_TYPE qno) ;
unsigned int mtlte_df_UL_deswq_buf(MTLTE_DF_TX_QUEUE_TYPE qno , void *buf_ptr) ;
/******************************************************
* DL data traffic APIs
******************************************************/
#if BUFFER_POOL_FOR_EACH_QUE
int mtlte_df_DL_pkt_in_buff_pool(MTLTE_DF_TX_QUEUE_TYPE qno);
#else
int mtlte_df_DL_pkt_in_buff_pool(void);
#endif
void mtlte_df_DL_try_reload_swq(void);
int mtlte_df_DL_pkt_in_swq(MTLTE_DF_RX_QUEUE_TYPE qno);
int mtlte_df_DL_enswq_buf(MTLTE_DF_RX_QUEUE_TYPE qno , void *buf, unsigned int len) ;
void mtlte_df_UL_swq_drop_skb(MTLTE_DF_TX_QUEUE_TYPE qno);
int mtlte_df_register_df_to_hif_callback(void *func_ptr , unsigned int data) ;
/******************************************************
* Software Interrupt related APIs
******************************************************/
int mtlte_df_swint_handle(unsigned int swint_status);
#if BUFFER_POOL_FOR_EACH_QUE
void mtlte_df_DL_prepare_skb_for_swq_short(unsigned int target_num, MTLTE_DF_TX_QUEUE_TYPE qno);
#else
void mtlte_df_DL_prepare_skb_for_swq_short(unsigned int target_num);
#endif
/******************************************************
*
* API for Upper (Device) Layer
*
******************************************************/
/******************************************************
* UL data traffic APIs
******************************************************/
int mtlte_df_UL_write_skb_to_swq(MTLTE_DF_TX_QUEUE_TYPE qno , struct sk_buff *skb) ;
int mtlte_df_UL_swq_space(MTLTE_DF_TX_QUEUE_TYPE qno) ;
int mtlte_df_register_tx_callback(MTLTE_DF_TX_QUEUE_TYPE qno, MTLTE_DF_TO_DEV_CALLBACK func_ptr , unsigned int private_data) ;
void mtlte_df_unregister_tx_callback(MTLTE_DF_TX_QUEUE_TYPE qno) ;
void mtlte_df_UL_SWQ_threshold_set(MTLTE_DF_TX_QUEUE_TYPE qno, unsigned int threshold) ;
/******************************************************
* DL data traffic APIs
******************************************************/
struct sk_buff * mtlte_df_DL_read_skb_from_swq(MTLTE_DF_RX_QUEUE_TYPE qno) ;
int mtlte_df_register_rx_callback(MTLTE_DF_RX_QUEUE_TYPE qno, MTLTE_DF_TO_DEV_CALLBACK func_ptr , unsigned int private_data) ;
void mtlte_df_unregister_rx_callback(MTLTE_DF_RX_QUEUE_TYPE qno) ;
int mtlte_df_DL_pkt_handle_complete(MTLTE_DF_RX_QUEUE_TYPE qno);
#if USE_QUE_WORK_DISPATCH_RX
#if USE_MULTI_QUE_DISPATCH
void mtlte_df_DL_try_dispatch_rxque(MTLTE_DF_RX_QUEUE_TYPE qno);
#else
void mtlte_df_DL_try_dispatch_rx(void);
#endif
#endif
#if DISPATCH_AFTER_ALL_SKB_DONE
void mtlte_df_DL_rx_callback(MTLTE_DF_RX_QUEUE_TYPE qno);
#endif
#if BUFFER_POOL_FOR_EACH_QUE
void mtlte_df_DL_set_skb_alloc_size_depth(MTLTE_DF_TX_QUEUE_TYPE qno, unsigned int alloc_size, unsigned int pool_depth);
#endif
/******************************************************
* Software Interrupt related APIs
******************************************************/
int mtlte_df_register_swint_callback(MTLTE_DF_TO_DEV_CALLBACK func_ptr);
int mtlte_df_unregister_swint_callback(void);
/******************************************************
* Other APIs
******************************************************/
/* NOTICE : Only can be called at end of xboot !!!! */
int mtlte_hif_clean_txq_count(void);
int sdio_xboot_mb_wr(KAL_UINT32 *pBuffer, KAL_UINT32 len);
int sdio_xboot_mb_rd(KAL_UINT32 *pBuffer, KAL_UINT32 len);
/******************************************************
* Device Watchdog Timeout related APIs
******************************************************/
int mtlte_df_register_WDT_callback(MTLTE_DF_TO_DEV_CALLBACK func_ptr);
int mtlte_df_unregister_WDT_callback(void);
int mtlte_df_WDT_handle(int wd_handle_data);
void mtlte_enable_WDT_flow(void);
int mtlte_df_register_seq_err_callback(MTLTE_DF_TO_DEV_CALLBACK func_ptr);
int mtlte_df_unregister_seq_err_callback(void);
/******************************************************
* Downlink flow control APIs
******************************************************/
int mtlte_manual_turnoff_DL_port(MTLTE_DF_RX_QUEUE_TYPE qno);
int mtlte_manual_turnon_DL_port(MTLTE_DF_RX_QUEUE_TYPE qno);
#if FORMAL_DL_FLOW_CONTROL
void mtlte_df_Init_DL_flow_ctrl(MTLTE_DF_RX_QUEUE_TYPE qno, bool free_skb, unsigned int limit, unsigned int threshold);
void mtlte_df_DL_release_buff (MTLTE_DF_RX_QUEUE_TYPE qno, unsigned int buff_amount, struct sk_buff *skb);
/* Below is only for internal usage */
bool mtlte_df_DL_check_fl_ctrl_enable(MTLTE_DF_RX_QUEUE_TYPE qno);
bool mtlte_df_DL_check_fl_ctrl_full(MTLTE_DF_RX_QUEUE_TYPE qno);
int mtlte_df_DL_read_fl_ctrl_record(MTLTE_DF_RX_QUEUE_TYPE qno);
#endif
#if FORMAL_DL_FLOW_CONTROL_TEST
void mtlte_df_DL_fl_ctrl_print_status(MTLTE_DF_RX_QUEUE_TYPE qno);
#endif
/******************************************************
* Assertion Dump Flow Related
******************************************************/
#define H2D_INT_except_ack (0x1 << 18)
#define H2D_INT_except_clearQ_ack (0x1 << 19)
#define H2D_INT_except_wakelock_ack (0x1 << 20)
#define D2H_INT_except_init (0x1 << 18)
#define D2H_INT_except_init_done (0x1 << 19)
#define D2H_INT_except_clearQ_done (0x1 << 20)
#define D2H_INT_except_allQ_reset (0x1 << 21)
#define D2H_INT_xboot_D2HMB (1 << 16)
#define H2D_INT_xboot_H2DMB (1 << 17)
#define D2H_INT_PLL_START (1 << 22)
#define D2H_INT_PLL_END (1 << 23)
#define D2H_INT_except_wakelock (1 << 24)
#define H2D_INT_CCCI_force_MD_assert (0x1 << 21)
#define D2H_INT_except_seq_err (0x1 << 25)
#define EX_INIT (0)
#define EX_DHL_DL_RDY (1)
#define EX_INIT_DONE (2)
typedef void (*EEMCS_CCCI_EX_IND)(KAL_UINT32 msgid);
struct mtlte_expt_priv {
EEMCS_CCCI_EX_IND cb_ccci_expt_int;
kal_uint32 non_stop_dlq[RXQ_NUM];
kal_uint32 except_mode_ulq[TXQ_NUM];
kal_uint32 except_mode_dlq[RXQ_NUM];
};
int mtlte_check_excetion_int(unsigned int swint_status);
int mtlte_expt_reset_inform_hif(void);
void mtlte_expt_q_num_init(KAL_UINT32 dhldl_q, KAL_UINT32 except_q);
int mtlte_expt_register_callback(EEMCS_CCCI_EX_IND cb);
int mtlte_expt_check_expt_q_num(KAL_UINT32 is_DL, KAL_UINT32 q_num);
int mtlte_expt_init(void);
int mtlte_expt_probe(void) ;
int mtlte_expt_remove(void) ;
int mtlte_expt_deinit(void);
#ifdef DEBUG_SDIO
#define TX_QUEUE_LEN TXQ_NUM
#define HISTORY_NUM 20
typedef enum {
IN_PHYSICAL_QUE=1,
IN_SDIO_BUFFER,
SDIO_SEND_OUT,
} SKB_LIFE;
struct sdio_memdump {
unsigned int data[2];
unsigned short log_ch;
unsigned short seq;
unsigned int reserved;
SKB_LIFE flag;
};
typedef struct tx_data_kthread_q{
unsigned int index;
struct sdio_memdump dump_data[HISTORY_NUM];
}TX_DATA_KTHREAD_Q;
void DumpKthreadBuffer();
void setBufferFlag(unsigned short qno, unsigned int start, unsigned int length);
void PutInKthreadDumpBuffer(unsigned short qno, struct sk_buff *skb, SKB_LIFE flag);
#endif
#endif
|