-
Notifications
You must be signed in to change notification settings - Fork 8
/
dhd_wlfc.h
585 lines (501 loc) · 20.6 KB
/
dhd_wlfc.h
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
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
/*
* Copyright (C) 2022, Broadcom.
*
* Unless you and Broadcom execute a separate written software license
* agreement governing use of this software, this software is licensed to you
* under the terms of the GNU General Public License version 2 (the "GPL"),
* available at http://www.broadcom.com/licenses/GPLv2.php, with the
* following added to such license:
*
* As a special exception, the copyright holders of this software give you
* permission to link this software with independent modules, and to copy and
* distribute the resulting executable under terms of your choice, provided that
* you also meet, for each linked independent module, the terms and conditions of
* the license of that module. An independent module is a module which is not
* derived from this software. The special exception does not apply to any
* modifications of the software.
*
*
* <<Broadcom-WL-IPTag/Open:>>
*
* $Id$
*
*/
#ifndef __wlfc_host_driver_definitions_h__
#define __wlfc_host_driver_definitions_h__
#ifdef QMONITOR
#include <dhd_qmon.h>
#endif
/* #define OOO_DEBUG */
#define KERNEL_THREAD_RETURN_TYPE int
typedef int (*f_commitpkt_t)(struct dhd_bus *ctx, void* p);
typedef bool (*f_processpkt_t)(void* p, void* arg);
#define WLFC_UNSUPPORTED -9999
#define WLFC_NO_TRAFFIC -1
#define WLFC_MULTI_TRAFFIC 0
#define BUS_RETRIES 1 /* # of retries before aborting a bus tx operation */
/** 16 bits will provide an absolute max of 65536 slots */
#define WLFC_HANGER_MAXITEMS 3072
#define WLFC_HANGER_ITEM_STATE_FREE 1
#define WLFC_HANGER_ITEM_STATE_INUSE 2
#define WLFC_HANGER_ITEM_STATE_INUSE_SUPPRESSED 3
#define WLFC_HANGER_ITEM_STATE_FLUSHED 4
#define WLFC_HANGER_PKT_STATE_TXSTATUS 1
#define WLFC_HANGER_PKT_STATE_BUSRETURNED 2
#define WLFC_HANGER_PKT_STATE_COMPLETE \
(WLFC_HANGER_PKT_STATE_TXSTATUS | WLFC_HANGER_PKT_STATE_BUSRETURNED)
typedef enum {
Q_TYPE_PSQ, /**< Power Save Queue, contains both delayed and suppressed packets */
Q_TYPE_AFQ /**< At Firmware Queue */
} q_type_t;
typedef enum ewlfc_packet_state {
eWLFC_PKTTYPE_NEW, /**< unused in the code (Jan 2015) */
eWLFC_PKTTYPE_DELAYED, /**< packet did not enter wlfc yet */
eWLFC_PKTTYPE_SUPPRESSED, /**< packet entered wlfc and was suppressed by the dongle */
eWLFC_PKTTYPE_MAX
} ewlfc_packet_state_t;
typedef enum ewlfc_mac_entry_action {
eWLFC_MAC_ENTRY_ACTION_ADD,
eWLFC_MAC_ENTRY_ACTION_DEL,
eWLFC_MAC_ENTRY_ACTION_UPDATE,
eWLFC_MAC_ENTRY_ACTION_MAX
} ewlfc_mac_entry_action_t;
typedef struct wlfc_hanger_item {
uint8 state;
uint8 gen;
uint8 pkt_state; /**< bitmask containing eg WLFC_HANGER_PKT_STATE_TXCOMPLETE */
uint8 pkt_txstatus;
uint32 identifier;
void* pkt;
#ifdef PROP_TXSTATUS_DEBUG
uint32 push_time;
#endif
struct wlfc_hanger_item *next;
} wlfc_hanger_item_t;
/** hanger contains packets that have been posted by the dhd to the dongle and are expected back */
typedef struct wlfc_hanger {
int max_items;
uint32 pushed;
uint32 popped;
uint32 failed_to_push;
uint32 failed_to_pop;
uint32 failed_slotfind;
uint32 slot_pos;
/** XXX: items[1] should be the last element here. Do not add new elements below it. */
wlfc_hanger_item_t items[1];
} wlfc_hanger_t;
#define WLFC_HANGER_SIZE(n) ((sizeof(wlfc_hanger_t) - \
sizeof(wlfc_hanger_item_t)) + ((n)*sizeof(wlfc_hanger_item_t)))
#define WLFC_STATE_OPEN 1 /**< remote MAC is able to receive packets */
#define WLFC_STATE_CLOSE 2 /**< remote MAC is in power save mode */
#define WLFC_PSQ_PREC_COUNT ((AC_COUNT + 1) * 2) /**< 2 for each AC traffic and bc/mc */
#define WLFC_AFQ_PREC_COUNT (AC_COUNT + 1)
#define WLFC_PSQ_LEN (4096 * 8)
#ifdef BCMDBUS
#define WLFC_FLOWCONTROL_HIWATER ((4096 * 8) - 256)
#define WLFC_FLOWCONTROL_LOWATER 256
#else
#define WLFC_FLOWCONTROL_HIWATER ((4096 * 8) - 256)
#define WLFC_FLOWCONTROL_LOWATER 256
#endif
#if (WLFC_FLOWCONTROL_HIWATER >= (WLFC_PSQ_LEN - 256))
#undef WLFC_FLOWCONTROL_HIWATER
#define WLFC_FLOWCONTROL_HIWATER (WLFC_PSQ_LEN - 256)
#undef WLFC_FLOWCONTROL_LOWATER
#define WLFC_FLOWCONTROL_LOWATER (WLFC_FLOWCONTROL_HIWATER / 4)
#endif
#define WLFC_LOG_BUF_SIZE (1024*1024)
/** Properties related to a remote MAC entity */
typedef struct wlfc_mac_descriptor {
uint8 occupied; /**< if 0, this descriptor is unused and thus can be (re)used */
uint8 interface_id;
uint8 iftype; /**< eg WLC_E_IF_ROLE_STA */
uint8 state; /**< eg WLFC_STATE_OPEN */
uint8 ac_bitmap; /**< automatic power save delivery (APSD) */
uint8 requested_credit;
uint8 requested_packet; /**< unit: [number of packets] */
uint8 ea[ETHER_ADDR_LEN];
/** maintain (MAC,AC) based seq count for packets going to the device. As well as bc/mc. */
uint8 seq[AC_COUNT + 1];
uint8 generation; /**< toggles between 0 and 1 */
struct pktq psq; /**< contains both 'delayed' and 'suppressed' packets */
/** packets at firmware queue */
struct pktq afq;
/** The AC pending bitmap that was reported to the fw at last change */
uint8 traffic_lastreported_bmp;
/** The new AC pending bitmap */
uint8 traffic_pending_bmp;
/** 1= send on next opportunity */
uint8 send_tim_signal;
uint8 mac_handle; /**< mac handles are assigned by the dongle */
/** Number of packets at dongle for this entry. */
int transit_count;
/** Number of suppression to wait before evict from delayQ */
int suppr_transit_count;
/** pkt sent to bus but no bus TX complete yet */
int onbus_pkts_count;
/** flag. TRUE when remote MAC is in suppressed state */
uint8 suppressed;
#ifdef QMONITOR
dhd_qmon_t qmon;
#endif /* QMONITOR */
#ifdef PROP_TXSTATUS_DEBUG
uint32 dstncredit_sent_packets;
uint32 dstncredit_acks;
uint32 opened_ct;
uint32 closed_ct;
#endif
#ifdef PROPTX_MAXCOUNT
/** Max Number of packets at dongle for this entry. */
int transit_maxcount;
#endif /* PROPTX_MAXCOUNT */
struct wlfc_mac_descriptor* prev;
struct wlfc_mac_descriptor* next;
#ifdef BULK_DEQUEUE
uint16 release_count[AC_COUNT + 1];
#endif
} wlfc_mac_descriptor_t;
/** A 'commit' is the hand over of a packet from the host OS layer to the layer below (eg DBUS) */
typedef struct dhd_wlfc_commit_info {
uint8 needs_hdr;
uint8 ac_fifo_credit_spent;
ewlfc_packet_state_t pkt_type;
wlfc_mac_descriptor_t* mac_entry;
void* p;
} dhd_wlfc_commit_info_t;
#define WLFC_DECR_SEQCOUNT(entry, prec) do { if (entry->seq[(prec)] == 0) {\
entry->seq[prec] = 0xff; } else entry->seq[prec]--;} while (0)
#define WLFC_INCR_SEQCOUNT(entry, prec) entry->seq[(prec)]++
#define WLFC_SEQCOUNT(entry, prec) entry->seq[(prec)]
typedef struct athost_wl_stat_counters {
uint32 pktin;
uint32 pktout;
uint32 pkt2bus;
uint32 pktdropped;
uint32 tlv_parse_failed;
uint32 rollback;
uint32 rollback_failed;
uint32 delayq_full_error;
uint32 credit_request_failed;
uint32 packet_request_failed;
uint32 mac_update_failed;
uint32 psmode_update_failed;
uint32 interface_update_failed;
uint32 wlfc_header_only_pkt;
uint32 txstatus_in;
uint32 d11_suppress;
uint32 wl_suppress;
uint32 bad_suppress;
uint32 pkt_dropped;
uint32 pkt_exptime;
uint32 pkt_freed;
uint32 pkt_free_err;
uint32 psq_wlsup_retx;
uint32 psq_wlsup_enq;
uint32 psq_d11sup_retx;
uint32 psq_d11sup_enq;
uint32 psq_hostq_retx;
uint32 psq_hostq_enq;
uint32 mac_handle_notfound;
uint32 wlc_tossed_pkts;
uint32 dhd_hdrpulls;
uint32 generic_error;
/* an extra one for bc/mc traffic */
uint32 send_pkts[AC_COUNT + 1];
uint32 drop_pkts[WLFC_PSQ_PREC_COUNT];
uint32 ooo_pkts[AC_COUNT + 1];
#ifdef PROP_TXSTATUS_DEBUG
/** all pkt2bus -> txstatus latency accumulated */
uint32 latency_sample_count;
uint32 total_status_latency;
uint32 latency_most_recent;
int idx_delta;
uint32 deltas[10];
uint32 fifo_credits_sent[6];
uint32 fifo_credits_back[6];
uint32 dropped_qfull[6];
uint32 signal_only_pkts_sent;
uint32 signal_only_pkts_freed;
#endif
uint32 cleanup_txq_cnt;
uint32 cleanup_psq_cnt;
uint32 cleanup_fw_cnt;
} athost_wl_stat_counters_t;
#ifdef PROP_TXSTATUS_DEBUG
#define WLFC_HOST_FIFO_CREDIT_INC_SENTCTRS(ctx, ac) do { \
(ctx)->stats.fifo_credits_sent[(ac)]++;} while (0)
#define WLFC_HOST_FIFO_CREDIT_INC_BACKCTRS(ctx, ac) do { \
(ctx)->stats.fifo_credits_back[(ac)]++;} while (0)
#define WLFC_HOST_FIFO_DROPPEDCTR_INC(ctx, ac) do { \
(ctx)->stats.dropped_qfull[(ac)]++;} while (0)
#else
#define WLFC_HOST_FIFO_CREDIT_INC_SENTCTRS(ctx, ac) do {} while (0)
#define WLFC_HOST_FIFO_CREDIT_INC_BACKCTRS(ctx, ac) do {} while (0)
#define WLFC_HOST_FIFO_DROPPEDCTR_INC(ctx, ac) do {} while (0)
#endif
#define WLFC_PACKET_BOUND 10
#define WLFC_FCMODE_NONE 0
#define WLFC_FCMODE_IMPLIED_CREDIT 1
#define WLFC_FCMODE_EXPLICIT_CREDIT 2
#define WLFC_ONLY_AMPDU_HOSTREORDER 3
/** Reserved credits ratio when borrowed by hihger priority */
#define WLFC_BORROW_LIMIT_RATIO 4
/** How long to defer borrowing in milliseconds */
#define WLFC_BORROW_DEFER_PERIOD_MS 100
/** How long to defer flow control in milliseconds */
#define WLFC_FC_DEFER_PERIOD_MS 200
/** How long to detect occurance per AC in miliseconds */
#define WLFC_RX_DETECTION_THRESHOLD_MS 100
/** Mask to represent available ACs (note: BC/MC is ignored) */
#define WLFC_AC_MASK 0xF
/** flow control specific information, only 1 instance during driver lifetime */
typedef struct athost_wl_status_info {
uint8 last_seqid_to_wlc;
/** OSL handle */
osl_t *osh;
/** dhd public struct pointer */
void *dhdp;
f_commitpkt_t fcommit;
void* commit_ctx;
/** statistics */
athost_wl_stat_counters_t stats;
/** incremented on eg receiving a credit map event from the dongle */
int Init_FIFO_credit[AC_COUNT + 2];
/** the additional ones are for bc/mc and ATIM FIFO */
int FIFO_credit[AC_COUNT + 2];
/** Credit borrow counts for each FIFO from each of the other FIFOs */
int credits_borrowed[AC_COUNT + 2][AC_COUNT + 2];
/** packet hanger and MAC->handle lookup table */
void *hanger;
struct {
/** table for individual nodes */
wlfc_mac_descriptor_t nodes[WLFC_MAC_DESC_TABLE_SIZE];
/** table for interfaces */
wlfc_mac_descriptor_t interfaces[WLFC_MAX_IFNUM];
/* OS may send packets to unknown (unassociated) destinations */
/** A place holder for bc/mc and packets to unknown destinations */
wlfc_mac_descriptor_t other;
} destination_entries;
wlfc_mac_descriptor_t *active_entry_head; /**< a chain of MAC descriptors */
int active_entry_count;
wlfc_mac_descriptor_t *requested_entry[WLFC_MAC_DESC_TABLE_SIZE];
int requested_entry_count;
/* pkt counts for each interface and ac */
int pkt_cnt_in_q[WLFC_MAX_IFNUM][AC_COUNT+1];
int pkt_cnt_per_ac[AC_COUNT+1];
int pkt_cnt_in_drv[WLFC_MAX_IFNUM][AC_COUNT+1];
int pkt_cnt_in_psq;
uint8 allow_fc; /**< Boolean */
uint32 fc_defer_timestamp;
uint32 rx_timestamp[AC_COUNT+1];
/** ON/OFF state for flow control to the host network interface */
uint8 hostif_flow_state[WLFC_MAX_IFNUM];
uint8 host_ifidx;
/** to flow control an OS interface */
uint8 toggle_host_if;
/** To borrow credits */
uint8 allow_credit_borrow;
/** ac number for the first single ac traffic */
uint8 single_ac;
/** Timestamp for the first single ac traffic */
uint32 single_ac_timestamp;
bool bcmc_credit_supported;
#ifdef BULK_DEQUEUE
uint8 max_release_count;
#endif /* total_credit */
} athost_wl_status_info_t;
/** Please be mindful that total pkttag space is 32 octets only */
typedef struct dhd_pkttag {
#ifdef BCM_OBJECT_TRACE
/* if use this field, keep it at the first 4 bytes */
uint32 sn;
#endif /* BCM_OBJECT_TRACE */
/**
b[15] - 1 = wlfc packet
b[14:13] - encryption exemption
b[12 ] - 1 = event channel
b[11 ] - 1 = this packet was sent in response to one time packet request,
do not increment credit on status for this one. [WLFC_CTL_TYPE_MAC_REQUEST_PACKET].
b[10 ] - 1 = signal-only-packet to firmware [i.e. nothing to piggyback on]
b[9 ] - 1 = packet is host->firmware (transmit direction)
- 0 = packet received from firmware (firmware->host)
b[8 ] - 1 = packet was sent due to credit_request (pspoll),
packet does not count against FIFO credit.
- 0 = normal transaction, packet counts against FIFO credit
b[7 ] - 1 = AP, 0 = STA
b[6:4] - AC FIFO number
b[3:0] - interface index
*/
uint16 if_flags;
/**
* destination MAC address for this packet so that not every module needs to open the packet
* to find this
*/
uint8 dstn_ether[ETHER_ADDR_LEN];
/** This 32-bit goes from host to device for every packet. */
uint32 htod_tag;
/** This 16-bit is original d11seq number for every suppressed packet. */
uint16 htod_seq;
/** This address is mac entry for every packet. */
void *entry;
/** bus specific stuff */
union {
struct {
void *stuff;
uint32 thing1;
uint32 thing2;
} sd;
/* XXX: using the USB typedef here will complicate life for anybody using dhd.h */
struct {
void *bus;
void *urb;
} usb;
} bus_specific;
} dhd_pkttag_t;
#define DHD_PKTTAG_WLFCPKT_MASK 0x1
#define DHD_PKTTAG_WLFCPKT_SHIFT 15
#define DHD_PKTTAG_WLFCPKT_SET(tag, value) ((dhd_pkttag_t*)(tag))->if_flags = \
(((dhd_pkttag_t*)(tag))->if_flags & \
~(DHD_PKTTAG_WLFCPKT_MASK << DHD_PKTTAG_WLFCPKT_SHIFT)) | \
(((value) & DHD_PKTTAG_WLFCPKT_MASK) << DHD_PKTTAG_WLFCPKT_SHIFT)
#define DHD_PKTTAG_WLFCPKT(tag) ((((dhd_pkttag_t*)(tag))->if_flags >> \
DHD_PKTTAG_WLFCPKT_SHIFT) & DHD_PKTTAG_WLFCPKT_MASK)
#define DHD_PKTTAG_EXEMPT_MASK 0x3
#define DHD_PKTTAG_EXEMPT_SHIFT 13
#define DHD_PKTTAG_EXEMPT_SET(tag, value) ((dhd_pkttag_t*)(tag))->if_flags = \
(((dhd_pkttag_t*)(tag))->if_flags & \
~(DHD_PKTTAG_EXEMPT_MASK << DHD_PKTTAG_EXEMPT_SHIFT)) | \
(((value) & DHD_PKTTAG_EXEMPT_MASK) << DHD_PKTTAG_EXEMPT_SHIFT)
#define DHD_PKTTAG_EXEMPT(tag) ((((dhd_pkttag_t*)(tag))->if_flags >> \
DHD_PKTTAG_EXEMPT_SHIFT) & DHD_PKTTAG_EXEMPT_MASK)
#define DHD_PKTTAG_EVENT_MASK 0x1
#define DHD_PKTTAG_EVENT_SHIFT 12
#define DHD_PKTTAG_SETEVENT(tag, event) ((dhd_pkttag_t*)(tag))->if_flags = \
(((dhd_pkttag_t*)(tag))->if_flags & \
~(DHD_PKTTAG_EVENT_MASK << DHD_PKTTAG_EVENT_SHIFT)) | \
(((event) & DHD_PKTTAG_EVENT_MASK) << DHD_PKTTAG_EVENT_SHIFT)
#define DHD_PKTTAG_EVENT(tag) ((((dhd_pkttag_t*)(tag))->if_flags >> \
DHD_PKTTAG_EVENT_SHIFT) & DHD_PKTTAG_EVENT_MASK)
#define DHD_PKTTAG_ONETIMEPKTRQST_MASK 0x1
#define DHD_PKTTAG_ONETIMEPKTRQST_SHIFT 11
#define DHD_PKTTAG_SETONETIMEPKTRQST(tag) ((dhd_pkttag_t*)(tag))->if_flags = \
(((dhd_pkttag_t*)(tag))->if_flags & \
~(DHD_PKTTAG_ONETIMEPKTRQST_MASK << DHD_PKTTAG_ONETIMEPKTRQST_SHIFT)) | \
(1 << DHD_PKTTAG_ONETIMEPKTRQST_SHIFT)
#define DHD_PKTTAG_ONETIMEPKTRQST(tag) ((((dhd_pkttag_t*)(tag))->if_flags >> \
DHD_PKTTAG_ONETIMEPKTRQST_SHIFT) & DHD_PKTTAG_ONETIMEPKTRQST_MASK)
#define DHD_PKTTAG_SIGNALONLY_MASK 0x1
#define DHD_PKTTAG_SIGNALONLY_SHIFT 10
#define DHD_PKTTAG_SETSIGNALONLY(tag, signalonly) ((dhd_pkttag_t*)(tag))->if_flags = \
(((dhd_pkttag_t*)(tag))->if_flags & \
~(DHD_PKTTAG_SIGNALONLY_MASK << DHD_PKTTAG_SIGNALONLY_SHIFT)) | \
(((signalonly) & DHD_PKTTAG_SIGNALONLY_MASK) << DHD_PKTTAG_SIGNALONLY_SHIFT)
#define DHD_PKTTAG_SIGNALONLY(tag) ((((dhd_pkttag_t*)(tag))->if_flags >> \
DHD_PKTTAG_SIGNALONLY_SHIFT) & DHD_PKTTAG_SIGNALONLY_MASK)
#define DHD_PKTTAG_PKTDIR_MASK 0x1
#define DHD_PKTTAG_PKTDIR_SHIFT 9
#define DHD_PKTTAG_SETPKTDIR(tag, dir) ((dhd_pkttag_t*)(tag))->if_flags = \
(((dhd_pkttag_t*)(tag))->if_flags & \
~(DHD_PKTTAG_PKTDIR_MASK << DHD_PKTTAG_PKTDIR_SHIFT)) | \
(((dir) & DHD_PKTTAG_PKTDIR_MASK) << DHD_PKTTAG_PKTDIR_SHIFT)
#define DHD_PKTTAG_PKTDIR(tag) ((((dhd_pkttag_t*)(tag))->if_flags >> \
DHD_PKTTAG_PKTDIR_SHIFT) & DHD_PKTTAG_PKTDIR_MASK)
#define DHD_PKTTAG_CREDITCHECK_MASK 0x1
#define DHD_PKTTAG_CREDITCHECK_SHIFT 8
#define DHD_PKTTAG_SETCREDITCHECK(tag, check) ((dhd_pkttag_t*)(tag))->if_flags = \
(((dhd_pkttag_t*)(tag))->if_flags & \
~(DHD_PKTTAG_CREDITCHECK_MASK << DHD_PKTTAG_CREDITCHECK_SHIFT)) | \
(((check) & DHD_PKTTAG_CREDITCHECK_MASK) << DHD_PKTTAG_CREDITCHECK_SHIFT)
#define DHD_PKTTAG_CREDITCHECK(tag) ((((dhd_pkttag_t*)(tag))->if_flags >> \
DHD_PKTTAG_CREDITCHECK_SHIFT) & DHD_PKTTAG_CREDITCHECK_MASK)
#define DHD_PKTTAG_IFTYPE_MASK 0x1
#define DHD_PKTTAG_IFTYPE_SHIFT 7
#define DHD_PKTTAG_SETIFTYPE(tag, isAP) ((dhd_pkttag_t*)(tag))->if_flags = \
(((dhd_pkttag_t*)(tag))->if_flags & \
~(DHD_PKTTAG_IFTYPE_MASK << DHD_PKTTAG_IFTYPE_SHIFT)) | \
(((isAP) & DHD_PKTTAG_IFTYPE_MASK) << DHD_PKTTAG_IFTYPE_SHIFT)
#define DHD_PKTTAG_IFTYPE(tag) ((((dhd_pkttag_t*)(tag))->if_flags >> \
DHD_PKTTAG_IFTYPE_SHIFT) & DHD_PKTTAG_IFTYPE_MASK)
#define DHD_PKTTAG_FIFO_MASK 0x7
#define DHD_PKTTAG_FIFO_SHIFT 4
#define DHD_PKTTAG_SETFIFO(tag, fifo) ((dhd_pkttag_t*)(tag))->if_flags = \
(((dhd_pkttag_t*)(tag))->if_flags & ~(DHD_PKTTAG_FIFO_MASK << DHD_PKTTAG_FIFO_SHIFT)) | \
(((fifo) & DHD_PKTTAG_FIFO_MASK) << DHD_PKTTAG_FIFO_SHIFT)
#define DHD_PKTTAG_FIFO(tag) ((((dhd_pkttag_t*)(tag))->if_flags >> \
DHD_PKTTAG_FIFO_SHIFT) & DHD_PKTTAG_FIFO_MASK)
#define DHD_PKTTAG_IF_MASK 0xf
#define DHD_PKTTAG_IF_SHIFT 0
#define DHD_PKTTAG_SETIF(tag, if) ((dhd_pkttag_t*)(tag))->if_flags = \
(((dhd_pkttag_t*)(tag))->if_flags & ~(DHD_PKTTAG_IF_MASK << DHD_PKTTAG_IF_SHIFT)) | \
(((if) & DHD_PKTTAG_IF_MASK) << DHD_PKTTAG_IF_SHIFT)
#define DHD_PKTTAG_IF(tag) ((((dhd_pkttag_t*)(tag))->if_flags >> \
DHD_PKTTAG_IF_SHIFT) & DHD_PKTTAG_IF_MASK)
#define DHD_PKTTAG_SETDSTN(tag, dstn_MAC_ea) memcpy(((dhd_pkttag_t*)((tag)))->dstn_ether, \
(dstn_MAC_ea), ETHER_ADDR_LEN)
#define DHD_PKTTAG_DSTN(tag) ((dhd_pkttag_t*)(tag))->dstn_ether
#define DHD_PKTTAG_SET_H2DTAG(tag, h2dvalue) ((dhd_pkttag_t*)(tag))->htod_tag = (h2dvalue)
#define DHD_PKTTAG_H2DTAG(tag) (((dhd_pkttag_t*)(tag))->htod_tag)
#define DHD_PKTTAG_SET_H2DSEQ(tag, seq) ((dhd_pkttag_t*)(tag))->htod_seq = (seq)
#define DHD_PKTTAG_H2DSEQ(tag) (((dhd_pkttag_t*)(tag))->htod_seq)
#define DHD_PKTTAG_SET_ENTRY(tag, entry) ((dhd_pkttag_t*)(tag))->entry = (entry)
#define DHD_PKTTAG_ENTRY(tag) (((dhd_pkttag_t*)(tag))->entry)
#define PSQ_SUP_IDX(x) (x * 2 + 1)
#define PSQ_DLY_IDX(x) (x * 2)
#ifdef PROP_TXSTATUS_DEBUG
#define DHD_WLFC_CTRINC_MAC_CLOSE(entry) do { (entry)->closed_ct++; } while (0)
#define DHD_WLFC_CTRINC_MAC_OPEN(entry) do { (entry)->opened_ct++; } while (0)
#else
#define DHD_WLFC_CTRINC_MAC_CLOSE(entry) do {} while (0)
#define DHD_WLFC_CTRINC_MAC_OPEN(entry) do {} while (0)
#endif
#ifdef BCM_OBJECT_TRACE
#define DHD_PKTTAG_SET_SN(tag, val) ((dhd_pkttag_t*)(tag))->sn = (val)
#define DHD_PKTTAG_SN(tag) (((dhd_pkttag_t*)(tag))->sn)
#endif /* BCM_OBJECT_TRACE */
#define DHD_PKTID_IF_SHIFT (16u)
#define DHD_PKTID_FIFO_SHIFT (8u)
/* public functions */
int dhd_wlfc_parse_header_info(dhd_pub_t *dhd, void* pktbuf, int tlv_hdr_len,
uchar *reorder_info_buf, uint *reorder_info_len);
KERNEL_THREAD_RETURN_TYPE dhd_wlfc_transfer_packets(void *data);
int dhd_wlfc_commit_packets(dhd_pub_t *dhdp, f_commitpkt_t fcommit,
struct dhd_bus *commit_ctx, void *pktbuf, bool need_toggle_host_if);
int dhd_wlfc_txcomplete(dhd_pub_t *dhd, void *txp, bool success);
int dhd_wlfc_init(dhd_pub_t *dhd);
#ifdef SUPPORT_P2P_GO_PS
int dhd_wlfc_suspend(dhd_pub_t *dhd);
int dhd_wlfc_resume(dhd_pub_t *dhd);
#endif /* SUPPORT_P2P_GO_PS */
int dhd_wlfc_hostreorder_init(dhd_pub_t *dhd);
int dhd_wlfc_cleanup_txq(dhd_pub_t *dhd, f_processpkt_t fn, void *arg);
int dhd_wlfc_cleanup(dhd_pub_t *dhd, f_processpkt_t fn, void* arg);
int dhd_wlfc_deinit(dhd_pub_t *dhd);
int dhd_wlfc_interface_event(dhd_pub_t *dhdp, uint8 action, uint8 ifid, uint8 iftype, uint8* ea);
int dhd_wlfc_FIFOcreditmap_event(dhd_pub_t *dhdp, uint8* event_data);
#ifdef LIMIT_BORROW
int dhd_wlfc_disable_credit_borrow_event(dhd_pub_t *dhdp, uint8* event_data);
#endif /* LIMIT_BORROW */
int dhd_wlfc_BCMCCredit_support_event(dhd_pub_t *dhdp);
int dhd_wlfc_enable(dhd_pub_t *dhdp);
int dhd_wlfc_dump(dhd_pub_t *dhdp, struct bcmstrbuf *strbuf);
int dhd_wlfc_clear_counts(dhd_pub_t *dhd);
int dhd_wlfc_get_enable(dhd_pub_t *dhd, bool *val);
int dhd_wlfc_get_mode(dhd_pub_t *dhd, int *val);
int dhd_wlfc_set_mode(dhd_pub_t *dhd, int val);
bool dhd_wlfc_is_supported(dhd_pub_t *dhd);
bool dhd_wlfc_is_header_only_pkt(dhd_pub_t * dhd, void *pktbuf);
int dhd_wlfc_flowcontrol(dhd_pub_t *dhdp, bool state, bool bAcquireLock);
int dhd_wlfc_save_rxpath_ac_time(dhd_pub_t * dhd, uint8 prio);
int dhd_wlfc_get_module_ignore(dhd_pub_t *dhd, int *val);
int dhd_wlfc_set_module_ignore(dhd_pub_t *dhd, int val);
int dhd_wlfc_get_credit_ignore(dhd_pub_t *dhd, int *val);
int dhd_wlfc_set_credit_ignore(dhd_pub_t *dhd, int val);
int dhd_wlfc_get_txstatus_ignore(dhd_pub_t *dhd, int *val);
int dhd_wlfc_set_txstatus_ignore(dhd_pub_t *dhd, int val);
int dhd_wlfc_get_rxpkt_chk(dhd_pub_t *dhd, int *val);
int dhd_wlfc_set_rxpkt_chk(dhd_pub_t *dhd, int val);
int dhd_txpkt_log_and_dump(dhd_pub_t *dhdp, void* pkt, uint16 *pktfate_status);
#ifdef PROPTX_MAXCOUNT
int dhd_wlfc_update_maxcount(dhd_pub_t *dhdp, uint8 ifid, int maxcount);
#endif /* PROPTX_MAXCOUNT */
#endif /* __wlfc_host_driver_definitions_h__ */