• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 1999-2019, Broadcom.
3  *
4  *      Unless you and Broadcom execute a separate written software license
5  * agreement governing use of this software, this software is licensed to you
6  * under the terms of the GNU General Public License version 2 (the "GPL"),
7  * available at http://www.broadcom.com/licenses/GPLv2.php, with the
8  * following added to such license:
9  *
10  *      As a special exception, the copyright holders of this software give you
11  * permission to link this software with independent modules, and to copy and
12  * distribute the resulting executable under terms of your choice, provided that
13  * you also meet, for each linked independent module, the terms and conditions
14  * of the license of that module.  An independent module is a module which is
15  * not derived from this software.  The special exception does not apply to any
16  * modifications of the software.
17  *
18  *      Notwithstanding the above, under no circumstances may you combine this
19  * software in any way with any other Broadcom software provided under a license
20  * other than the GPL, without Broadcom's express prior written consent.
21  *
22  *
23  * <<Broadcom-WL-IPTag/Open:>>
24  *
25  * $Id: dhd_wlfc.h 690477 2017-03-16 10:17:17Z $
26  *
27  */
28 #ifndef __wlfc_host_driver_definitions_h__
29 #define __wlfc_host_driver_definitions_h__
30 
31 #define KERNEL_THREAD_RETURN_TYPE int
32 
33 typedef int (*f_commitpkt_t)(void *ctx, void *p);
34 typedef bool (*f_processpkt_t)(void *p, void *arg);
35 
36 #define WLFC_UNSUPPORTED -9999
37 
38 #define WLFC_NO_TRAFFIC -1
39 #define WLFC_MULTI_TRAFFIC 0
40 
41 #define BUS_RETRIES 1 /* # of retries before aborting a bus tx operation */
42 
43 /** 16 bits will provide an absolute max of 65536 slots */
44 #define WLFC_HANGER_MAXITEMS 3072
45 
46 #define WLFC_HANGER_ITEM_STATE_FREE 1
47 #define WLFC_HANGER_ITEM_STATE_INUSE 2
48 #define WLFC_HANGER_ITEM_STATE_INUSE_SUPPRESSED 3
49 #define WLFC_HANGER_ITEM_STATE_FLUSHED 4
50 
51 #define WLFC_HANGER_PKT_STATE_TXSTATUS 1
52 #define WLFC_HANGER_PKT_STATE_BUSRETURNED 2
53 #define WLFC_HANGER_PKT_STATE_COMPLETE                                         \
54     (WLFC_HANGER_PKT_STATE_TXSTATUS | WLFC_HANGER_PKT_STATE_BUSRETURNED)
55 
56 typedef enum {
57     Q_TYPE_PSQ, /**< Power Save Queue, contains both delayed and suppressed
58                    packets */
59     Q_TYPE_AFQ  /**< At Firmware Queue */
60 } q_type_t;
61 
62 typedef enum ewlfc_packet_state {
63     eWLFC_PKTTYPE_NEW,        /**< unused in the code (Jan 2015) */
64     eWLFC_PKTTYPE_DELAYED,    /**< packet did not enter wlfc yet */
65     eWLFC_PKTTYPE_SUPPRESSED, /**< packet entered wlfc and was suppressed by the
66                                  dongle */
67     eWLFC_PKTTYPE_MAX
68 } ewlfc_packet_state_t;
69 
70 typedef enum ewlfc_mac_entry_action {
71     eWLFC_MAC_ENTRY_ACTION_ADD,
72     eWLFC_MAC_ENTRY_ACTION_DEL,
73     eWLFC_MAC_ENTRY_ACTION_UPDATE,
74     eWLFC_MAC_ENTRY_ACTION_MAX
75 } ewlfc_mac_entry_action_t;
76 
77 typedef struct wlfc_hanger_item {
78     uint8 state;
79     uint8 gen;
80     uint8 pkt_state; /**< bitmask containing eg WLFC_HANGER_PKT_STATE_TXCOMPLETE
81                       */
82     uint8 pkt_txstatus;
83     uint32 identifier;
84     void *pkt;
85 #ifdef PROP_TXSTATUS_DEBUG
86     uint32 push_time;
87 #endif // endif
88     struct wlfc_hanger_item *next;
89 } wlfc_hanger_item_t;
90 
91 /** hanger contains packets that have been posted by the dhd to the dongle and
92  * are expected back */
93 typedef struct wlfc_hanger {
94     int max_items;
95     uint32 pushed;
96     uint32 popped;
97     uint32 failed_to_push;
98     uint32 failed_to_pop;
99     uint32 failed_slotfind;
100     uint32 slot_pos;
101     wlfc_hanger_item_t items[1];
102 } wlfc_hanger_t;
103 
104 #define WLFC_HANGER_SIZE(n)                                                    \
105     ((sizeof(wlfc_hanger_t) - sizeof(wlfc_hanger_item_t)) +                    \
106      ((n) * sizeof(wlfc_hanger_item_t)))
107 
108 #define WLFC_STATE_OPEN 1  /**< remote MAC is able to receive packets */
109 #define WLFC_STATE_CLOSE 2 /**< remote MAC is in power save mode */
110 
111 #define WLFC_PSQ_PREC_COUNT                                                    \
112     ((AC_COUNT + 1) * 2) /**< 2 for each AC traffic and bc/mc */
113 #define WLFC_AFQ_PREC_COUNT (AC_COUNT + 1)
114 
115 #define WLFC_PSQ_LEN (4096 * 8)
116 
117 #ifdef BCMDBUS
118 #define WLFC_FLOWCONTROL_HIWATER 512
119 #define WLFC_FLOWCONTROL_LOWATER (WLFC_FLOWCONTROL_HIWATER / 4)
120 #else
121 #define WLFC_FLOWCONTROL_HIWATER ((4096 * 8) - 256)
122 #define WLFC_FLOWCONTROL_LOWATER 256
123 #endif
124 
125 #if (WLFC_FLOWCONTROL_HIWATER >= (WLFC_PSQ_LEN - 256))
126 #undef WLFC_FLOWCONTROL_HIWATER
127 #define WLFC_FLOWCONTROL_HIWATER (WLFC_PSQ_LEN - 256)
128 #undef WLFC_FLOWCONTROL_LOWATER
129 #define WLFC_FLOWCONTROL_LOWATER (WLFC_FLOWCONTROL_HIWATER / 4)
130 #endif // endif
131 
132 #define WLFC_LOG_BUF_SIZE (1024 * 1024)
133 
134 /** Properties related to a remote MAC entity */
135 typedef struct wlfc_mac_descriptor {
136     uint8 occupied; /**< if 0, this descriptor is unused and thus can be
137                        (re)used */
138     uint8 interface_id;
139     uint8 iftype;    /**< eg WLC_E_IF_ROLE_STA */
140     uint8 state;     /**< eg WLFC_STATE_OPEN */
141     uint8 ac_bitmap; /**< automatic power save delivery (APSD) */
142     uint8 requested_credit;
143     uint8 requested_packet; /**< unit: [number of packets] */
144     uint8 ea[ETHER_ADDR_LEN];
145 
146     /** maintain (MAC,AC) based seq count for packets going to the device. As
147      * well as bc/mc. */
148     uint8 seq[AC_COUNT + 1];
149     uint8 generation; /**< toggles between 0 and 1 */
150     struct pktq psq;  /**< contains both 'delayed' and 'suppressed' packets */
151     /** packets at firmware queue */
152     struct pktq afq;
153     /** The AC pending bitmap that was reported to the fw at last change */
154     uint8 traffic_lastreported_bmp;
155     /** The new AC pending bitmap */
156     uint8 traffic_pending_bmp;
157     /** 1= send on next opportunity */
158     uint8 send_tim_signal;
159     uint8 mac_handle; /**< mac handles are assigned by the dongle */
160     /** Number of packets at dongle for this entry. */
161     int transit_count;
162     /** Number of suppression to wait before evict from delayQ */
163     int suppr_transit_count;
164     /** pkt sent to bus but no bus TX complete yet */
165     int onbus_pkts_count;
166     /** flag. TRUE when remote MAC is in suppressed state */
167     uint8 suppressed;
168 
169 #ifdef PROP_TXSTATUS_DEBUG
170     uint32 dstncredit_sent_packets;
171     uint32 dstncredit_acks;
172     uint32 opened_ct;
173     uint32 closed_ct;
174 #endif // endif
175 #ifdef PROPTX_MAXCOUNT
176     /** Max Number of packets at dongle for this entry. */
177     int transit_maxcount;
178 #endif /* PROPTX_MAXCOUNT */
179     struct wlfc_mac_descriptor *prev;
180     struct wlfc_mac_descriptor *next;
181 } wlfc_mac_descriptor_t;
182 
183 /** A 'commit' is the hand over of a packet from the host OS layer to the layer
184  * below (eg DBUS) */
185 typedef struct dhd_wlfc_commit_info {
186     uint8 needs_hdr;
187     uint8 ac_fifo_credit_spent;
188     ewlfc_packet_state_t pkt_type;
189     wlfc_mac_descriptor_t *mac_entry;
190     void *p;
191 } dhd_wlfc_commit_info_t;
192 
193 #define WLFC_DECR_SEQCOUNT(entry, prec)                                        \
194     do {                                                                       \
195         if (entry->seq[(prec)] == 0) {                                         \
196             entry->seq[prec] = 0xff;                                           \
197         } else                                                                 \
198             entry->seq[prec]--;                                                \
199     } while (0)
200 
201 #define WLFC_INCR_SEQCOUNT(entry, prec) entry->seq[(prec)]++
202 #define WLFC_SEQCOUNT(entry, prec) entry->seq[(prec)]
203 
204 typedef struct athost_wl_stat_counters {
205     uint32 pktin;
206     uint32 pktout;
207     uint32 pkt2bus;
208     uint32 pktdropped;
209     uint32 tlv_parse_failed;
210     uint32 rollback;
211     uint32 rollback_failed;
212     uint32 delayq_full_error;
213     uint32 credit_request_failed;
214     uint32 packet_request_failed;
215     uint32 mac_update_failed;
216     uint32 psmode_update_failed;
217     uint32 interface_update_failed;
218     uint32 wlfc_header_only_pkt;
219     uint32 txstatus_in;
220     uint32 d11_suppress;
221     uint32 wl_suppress;
222     uint32 bad_suppress;
223     uint32 pkt_dropped;
224     uint32 pkt_exptime;
225     uint32 pkt_freed;
226     uint32 pkt_free_err;
227     uint32 psq_wlsup_retx;
228     uint32 psq_wlsup_enq;
229     uint32 psq_d11sup_retx;
230     uint32 psq_d11sup_enq;
231     uint32 psq_hostq_retx;
232     uint32 psq_hostq_enq;
233     uint32 mac_handle_notfound;
234     uint32 wlc_tossed_pkts;
235     uint32 dhd_hdrpulls;
236     uint32 generic_error;
237     /* an extra one for bc/mc traffic */
238     uint32 send_pkts[AC_COUNT + 1];
239     uint32 drop_pkts[WLFC_PSQ_PREC_COUNT];
240     uint32 ooo_pkts[AC_COUNT + 1];
241 #ifdef PROP_TXSTATUS_DEBUG
242     /** all pkt2bus -> txstatus latency accumulated */
243     uint32 latency_sample_count;
244     uint32 total_status_latency;
245     uint32 latency_most_recent;
246     int idx_delta;
247     uint32 deltas[10];
248     uint32 fifo_credits_sent[6];
249     uint32 fifo_credits_back[6];
250     uint32 dropped_qfull[6];
251     uint32 signal_only_pkts_sent;
252     uint32 signal_only_pkts_freed;
253 #endif // endif
254     uint32 cleanup_txq_cnt;
255     uint32 cleanup_psq_cnt;
256     uint32 cleanup_fw_cnt;
257 } athost_wl_stat_counters_t;
258 
259 #ifdef PROP_TXSTATUS_DEBUG
260 #define WLFC_HOST_FIFO_CREDIT_INC_SENTCTRS(ctx, ac)                            \
261     do {                                                                       \
262         (ctx)->stats.fifo_credits_sent[(ac)]++;                                \
263     } while (0)
264 #define WLFC_HOST_FIFO_CREDIT_INC_BACKCTRS(ctx, ac)                            \
265     do {                                                                       \
266         (ctx)->stats.fifo_credits_back[(ac)]++;                                \
267     } while (0)
268 #define WLFC_HOST_FIFO_DROPPEDCTR_INC(ctx, ac)                                 \
269     do {                                                                       \
270         (ctx)->stats.dropped_qfull[(ac)]++;                                    \
271     } while (0)
272 #else
273 #define WLFC_HOST_FIFO_CREDIT_INC_SENTCTRS(ctx, ac)                            \
274     do {                                                                       \
275     } while (0)
276 #define WLFC_HOST_FIFO_CREDIT_INC_BACKCTRS(ctx, ac)                            \
277     do {                                                                       \
278     } while (0)
279 #define WLFC_HOST_FIFO_DROPPEDCTR_INC(ctx, ac)                                 \
280     do {                                                                       \
281     } while (0)
282 #endif // endif
283 #define WLFC_PACKET_BOUND 10
284 #define WLFC_FCMODE_NONE 0
285 #define WLFC_FCMODE_IMPLIED_CREDIT 1
286 #define WLFC_FCMODE_EXPLICIT_CREDIT 2
287 #define WLFC_ONLY_AMPDU_HOSTREORDER 3
288 
289 /** Reserved credits ratio when borrowed by hihger priority */
290 #define WLFC_BORROW_LIMIT_RATIO 4
291 
292 /** How long to defer borrowing in milliseconds */
293 #define WLFC_BORROW_DEFER_PERIOD_MS 100
294 
295 /** How long to defer flow control in milliseconds */
296 #define WLFC_FC_DEFER_PERIOD_MS 200
297 
298 /** How long to detect occurance per AC in miliseconds */
299 #define WLFC_RX_DETECTION_THRESHOLD_MS 100
300 
301 /** Mask to represent available ACs (note: BC/MC is ignored) */
302 #define WLFC_AC_MASK 0xF
303 
304 /** flow control specific information, only 1 instance during driver lifetime */
305 typedef struct athost_wl_status_info {
306     uint8 last_seqid_to_wlc;
307 
308     /** OSL handle */
309     osl_t *osh;
310     /** dhd public struct pointer */
311     void *dhdp;
312 
313     f_commitpkt_t fcommit;
314     void *commit_ctx;
315 
316     /** statistics */
317     athost_wl_stat_counters_t stats;
318 
319     /** incremented on eg receiving a credit map event from the dongle */
320     int Init_FIFO_credit[AC_COUNT + 2];
321     /** the additional ones are for bc/mc and ATIM FIFO */
322     int FIFO_credit[AC_COUNT + 2];
323     /** Credit borrow counts for each FIFO from each of the other FIFOs */
324     int credits_borrowed[AC_COUNT + 2][AC_COUNT + 2];
325 
326     /** packet hanger and MAC->handle lookup table */
327     void *hanger;
328 
329     struct {
330         /** table for individual nodes */
331         wlfc_mac_descriptor_t nodes[WLFC_MAC_DESC_TABLE_SIZE];
332         /** table for interfaces */
333         wlfc_mac_descriptor_t interfaces[WLFC_MAX_IFNUM];
334         /* OS may send packets to unknown (unassociated) destinations */
335         /** A place holder for bc/mc and packets to unknown destinations */
336         wlfc_mac_descriptor_t other;
337     } destination_entries;
338 
339     wlfc_mac_descriptor_t *active_entry_head; /**< a chain of MAC descriptors */
340     int active_entry_count;
341 
342     wlfc_mac_descriptor_t *requested_entry[WLFC_MAC_DESC_TABLE_SIZE];
343     int requested_entry_count;
344 
345     /* pkt counts for each interface and ac */
346     int pkt_cnt_in_q[WLFC_MAX_IFNUM][AC_COUNT + 1];
347     int pkt_cnt_per_ac[AC_COUNT + 1];
348     int pkt_cnt_in_drv[WLFC_MAX_IFNUM][AC_COUNT + 1];
349     int pkt_cnt_in_psq;
350     uint8 allow_fc; /**< Boolean */
351     uint32 fc_defer_timestamp;
352     uint32 rx_timestamp[AC_COUNT + 1];
353 
354     /** ON/OFF state for flow control to the host network interface */
355     uint8 hostif_flow_state[WLFC_MAX_IFNUM];
356     uint8 host_ifidx;
357 
358     /** to flow control an OS interface */
359     uint8 toggle_host_if;
360 
361     /** To borrow credits */
362     uint8 allow_credit_borrow;
363 
364     /** ac number for the first single ac traffic */
365     uint8 single_ac;
366 
367     /** Timestamp for the first single ac traffic */
368     uint32 single_ac_timestamp;
369 
370     bool bcmc_credit_supported;
371 } athost_wl_status_info_t;
372 
373 /** Please be mindful that total pkttag space is 32 octets only */
374 typedef struct dhd_pkttag {
375 #ifdef BCM_OBJECT_TRACE
376     /* if use this field, keep it at the first 4 bytes */
377     uint32 sn;
378 #endif /* BCM_OBJECT_TRACE */
379 
380     /**
381     b[15]  - 1 = wlfc packet
382     b[14:13]  - encryption exemption
383     b[12 ] - 1 = event channel
384     b[11 ] - 1 = this packet was sent in response to one time packet request,
385     do not increment credit on status for this one.
386     [WLFC_CTL_TYPE_MAC_REQUEST_PACKET]. b[10 ] - 1 = signal-only-packet to
387     firmware [i.e. nothing to piggyback on] b[9  ] - 1 = packet is
388     host->firmware (transmit direction)
389            - 0 = packet received from firmware (firmware->host)
390     b[8  ] - 1 = packet was sent due to credit_request (pspoll),
391                  packet does not count against FIFO credit.
392            - 0 = normal transaction, packet counts against FIFO credit
393     b[7  ] - 1 = AP, 0 = STA
394     b[6:4] - AC FIFO number
395     b[3:0] - interface index
396     */
397     uint16 if_flags;
398 
399     /**
400      * destination MAC address for this packet so that not every module needs to
401      * open the packet to find this
402      */
403     uint8 dstn_ether[ETHER_ADDR_LEN];
404 
405     /** This 32-bit goes from host to device for every packet. */
406     uint32 htod_tag;
407 
408     /** This 16-bit is original d11seq number for every suppressed packet. */
409     uint16 htod_seq;
410 
411     /** This address is mac entry for every packet. */
412     void *entry;
413 
414     /** bus specific stuff */
415     union {
416         struct {
417             void *stuff;
418             uint32 thing1;
419             uint32 thing2;
420         } sd;
421 
422         struct {
423             void *bus;
424             void *urb;
425         } usb;
426     } bus_specific;
427 } dhd_pkttag_t;
428 
429 #define DHD_PKTTAG_WLFCPKT_MASK 0x1
430 #define DHD_PKTTAG_WLFCPKT_SHIFT 15
431 #define DHD_PKTTAG_WLFCPKT_SET(tag, value)                                     \
432     ((dhd_pkttag_t *)(tag))->if_flags =                                        \
433         (((dhd_pkttag_t *)(tag))->if_flags &                                   \
434          ~(DHD_PKTTAG_WLFCPKT_MASK << DHD_PKTTAG_WLFCPKT_SHIFT)) |             \
435         (((value)&DHD_PKTTAG_WLFCPKT_MASK) << DHD_PKTTAG_WLFCPKT_SHIFT)
436 #define DHD_PKTTAG_WLFCPKT(tag)                                                \
437     ((((dhd_pkttag_t *)(tag))->if_flags >> DHD_PKTTAG_WLFCPKT_SHIFT) &         \
438      DHD_PKTTAG_WLFCPKT_MASK)
439 
440 #define DHD_PKTTAG_EXEMPT_MASK 0x3
441 #define DHD_PKTTAG_EXEMPT_SHIFT 13
442 #define DHD_PKTTAG_EXEMPT_SET(tag, value)                                      \
443     ((dhd_pkttag_t *)(tag))->if_flags =                                        \
444         (((dhd_pkttag_t *)(tag))->if_flags &                                   \
445          ~(DHD_PKTTAG_EXEMPT_MASK << DHD_PKTTAG_EXEMPT_SHIFT)) |               \
446         (((value)&DHD_PKTTAG_EXEMPT_MASK) << DHD_PKTTAG_EXEMPT_SHIFT)
447 #define DHD_PKTTAG_EXEMPT(tag)                                                 \
448     ((((dhd_pkttag_t *)(tag))->if_flags >> DHD_PKTTAG_EXEMPT_SHIFT) &          \
449      DHD_PKTTAG_EXEMPT_MASK)
450 
451 #define DHD_PKTTAG_EVENT_MASK 0x1
452 #define DHD_PKTTAG_EVENT_SHIFT 12
453 #define DHD_PKTTAG_SETEVENT(tag, event)                                        \
454     ((dhd_pkttag_t *)(tag))->if_flags =                                        \
455         (((dhd_pkttag_t *)(tag))->if_flags &                                   \
456          ~(DHD_PKTTAG_EVENT_MASK << DHD_PKTTAG_EVENT_SHIFT)) |                 \
457         (((event)&DHD_PKTTAG_EVENT_MASK) << DHD_PKTTAG_EVENT_SHIFT)
458 #define DHD_PKTTAG_EVENT(tag)                                                  \
459     ((((dhd_pkttag_t *)(tag))->if_flags >> DHD_PKTTAG_EVENT_SHIFT) &           \
460      DHD_PKTTAG_EVENT_MASK)
461 
462 #define DHD_PKTTAG_ONETIMEPKTRQST_MASK 0x1
463 #define DHD_PKTTAG_ONETIMEPKTRQST_SHIFT 11
464 #define DHD_PKTTAG_SETONETIMEPKTRQST(tag)                                      \
465     ((dhd_pkttag_t *)(tag))->if_flags =                                        \
466         (((dhd_pkttag_t *)(tag))->if_flags &                                   \
467          ~(DHD_PKTTAG_ONETIMEPKTRQST_MASK                                      \
468            << DHD_PKTTAG_ONETIMEPKTRQST_SHIFT)) |                              \
469         (1 << DHD_PKTTAG_ONETIMEPKTRQST_SHIFT)
470 #define DHD_PKTTAG_ONETIMEPKTRQST(tag)                                         \
471     ((((dhd_pkttag_t *)(tag))->if_flags >> DHD_PKTTAG_ONETIMEPKTRQST_SHIFT) &  \
472      DHD_PKTTAG_ONETIMEPKTRQST_MASK)
473 
474 #define DHD_PKTTAG_SIGNALONLY_MASK 0x1
475 #define DHD_PKTTAG_SIGNALONLY_SHIFT 10
476 #define DHD_PKTTAG_SETSIGNALONLY(tag, signalonly)                              \
477     ((dhd_pkttag_t *)(tag))->if_flags =                                        \
478         (((dhd_pkttag_t *)(tag))->if_flags &                                   \
479          ~(DHD_PKTTAG_SIGNALONLY_MASK << DHD_PKTTAG_SIGNALONLY_SHIFT)) |       \
480         (((signalonly)&DHD_PKTTAG_SIGNALONLY_MASK)                             \
481          << DHD_PKTTAG_SIGNALONLY_SHIFT)
482 #define DHD_PKTTAG_SIGNALONLY(tag)                                             \
483     ((((dhd_pkttag_t *)(tag))->if_flags >> DHD_PKTTAG_SIGNALONLY_SHIFT) &      \
484      DHD_PKTTAG_SIGNALONLY_MASK)
485 
486 #define DHD_PKTTAG_PKTDIR_MASK 0x1
487 #define DHD_PKTTAG_PKTDIR_SHIFT 9
488 #define DHD_PKTTAG_SETPKTDIR(tag, dir)                                         \
489     ((dhd_pkttag_t *)(tag))->if_flags =                                        \
490         (((dhd_pkttag_t *)(tag))->if_flags &                                   \
491          ~(DHD_PKTTAG_PKTDIR_MASK << DHD_PKTTAG_PKTDIR_SHIFT)) |               \
492         (((dir)&DHD_PKTTAG_PKTDIR_MASK) << DHD_PKTTAG_PKTDIR_SHIFT)
493 #define DHD_PKTTAG_PKTDIR(tag)                                                 \
494     ((((dhd_pkttag_t *)(tag))->if_flags >> DHD_PKTTAG_PKTDIR_SHIFT) &          \
495      DHD_PKTTAG_PKTDIR_MASK)
496 
497 #define DHD_PKTTAG_CREDITCHECK_MASK 0x1
498 #define DHD_PKTTAG_CREDITCHECK_SHIFT 8
499 #define DHD_PKTTAG_SETCREDITCHECK(tag, check)                                  \
500     ((dhd_pkttag_t *)(tag))->if_flags =                                        \
501         (((dhd_pkttag_t *)(tag))->if_flags &                                   \
502          ~(DHD_PKTTAG_CREDITCHECK_MASK << DHD_PKTTAG_CREDITCHECK_SHIFT)) |     \
503         (((check)&DHD_PKTTAG_CREDITCHECK_MASK)                                 \
504          << DHD_PKTTAG_CREDITCHECK_SHIFT)
505 #define DHD_PKTTAG_CREDITCHECK(tag)                                            \
506     ((((dhd_pkttag_t *)(tag))->if_flags >> DHD_PKTTAG_CREDITCHECK_SHIFT) &     \
507      DHD_PKTTAG_CREDITCHECK_MASK)
508 
509 #define DHD_PKTTAG_IFTYPE_MASK 0x1
510 #define DHD_PKTTAG_IFTYPE_SHIFT 7
511 #define DHD_PKTTAG_SETIFTYPE(tag, isAP)                                        \
512     ((dhd_pkttag_t *)(tag))->if_flags =                                        \
513         (((dhd_pkttag_t *)(tag))->if_flags &                                   \
514          ~(DHD_PKTTAG_IFTYPE_MASK << DHD_PKTTAG_IFTYPE_SHIFT)) |               \
515         (((isAP)&DHD_PKTTAG_IFTYPE_MASK) << DHD_PKTTAG_IFTYPE_SHIFT)
516 #define DHD_PKTTAG_IFTYPE(tag)                                                 \
517     ((((dhd_pkttag_t *)(tag))->if_flags >> DHD_PKTTAG_IFTYPE_SHIFT) &          \
518      DHD_PKTTAG_IFTYPE_MASK)
519 
520 #define DHD_PKTTAG_FIFO_MASK 0x7
521 #define DHD_PKTTAG_FIFO_SHIFT 4
522 #define DHD_PKTTAG_SETFIFO(tag, fifo)                                          \
523     ((dhd_pkttag_t *)(tag))->if_flags =                                        \
524         (((dhd_pkttag_t *)(tag))->if_flags &                                   \
525          ~(DHD_PKTTAG_FIFO_MASK << DHD_PKTTAG_FIFO_SHIFT)) |                   \
526         (((fifo)&DHD_PKTTAG_FIFO_MASK) << DHD_PKTTAG_FIFO_SHIFT)
527 #define DHD_PKTTAG_FIFO(tag)                                                   \
528     ((((dhd_pkttag_t *)(tag))->if_flags >> DHD_PKTTAG_FIFO_SHIFT) &            \
529      DHD_PKTTAG_FIFO_MASK)
530 
531 #define DHD_PKTTAG_IF_MASK 0xf
532 #define DHD_PKTTAG_IF_SHIFT 0
533 #define DHD_PKTTAG_SETIF(tag, if)                                              \
534     ((dhd_pkttag_t *)(tag))->if_flags =                                        \
535         (((dhd_pkttag_t *)(tag))->if_flags &                                   \
536          ~(DHD_PKTTAG_IF_MASK << DHD_PKTTAG_IF_SHIFT)) |                       \
537         (((if) & DHD_PKTTAG_IF_MASK) << DHD_PKTTAG_IF_SHIFT)
538 #define DHD_PKTTAG_IF(tag)                                                     \
539     ((((dhd_pkttag_t *)(tag))->if_flags >> DHD_PKTTAG_IF_SHIFT) &              \
540      DHD_PKTTAG_IF_MASK)
541 
542 #define DHD_PKTTAG_SETDSTN(tag, dstn_MAC_ea)                                   \
543     memcpy(((dhd_pkttag_t *)((tag)))->dstn_ether, (dstn_MAC_ea), ETHER_ADDR_LEN)
544 #define DHD_PKTTAG_DSTN(tag) ((dhd_pkttag_t *)(tag))->dstn_ether
545 
546 #define DHD_PKTTAG_SET_H2DTAG(tag, h2dvalue)                                   \
547     ((dhd_pkttag_t *)(tag))->htod_tag = (h2dvalue)
548 #define DHD_PKTTAG_H2DTAG(tag) (((dhd_pkttag_t *)(tag))->htod_tag)
549 
550 #define DHD_PKTTAG_SET_H2DSEQ(tag, seq)                                        \
551     ((dhd_pkttag_t *)(tag))->htod_seq = (seq)
552 #define DHD_PKTTAG_H2DSEQ(tag) (((dhd_pkttag_t *)(tag))->htod_seq)
553 
554 #define DHD_PKTTAG_SET_ENTRY(tag, entry)                                       \
555     ((dhd_pkttag_t *)(tag))->entry = (entry)
556 #define DHD_PKTTAG_ENTRY(tag) (((dhd_pkttag_t *)(tag))->entry)
557 
558 #define PSQ_SUP_IDX(x) (x * 2 + 1)
559 #define PSQ_DLY_IDX(x) (x * 2)
560 
561 #ifdef PROP_TXSTATUS_DEBUG
562 #define DHD_WLFC_CTRINC_MAC_CLOSE(entry)                                       \
563     do {                                                                       \
564         (entry)->closed_ct++;                                                  \
565     } while (0)
566 #define DHD_WLFC_CTRINC_MAC_OPEN(entry)                                        \
567     do {                                                                       \
568         (entry)->opened_ct++;                                                  \
569     } while (0)
570 #else
571 #define DHD_WLFC_CTRINC_MAC_CLOSE(entry)                                       \
572     do {                                                                       \
573     } while (0)
574 #define DHD_WLFC_CTRINC_MAC_OPEN(entry)                                        \
575     do {                                                                       \
576     } while (0)
577 #endif // endif
578 
579 #ifdef BCM_OBJECT_TRACE
580 #define DHD_PKTTAG_SET_SN(tag, val) ((dhd_pkttag_t *)(tag))->sn = (val)
581 #define DHD_PKTTAG_SN(tag) (((dhd_pkttag_t *)(tag))->sn)
582 #endif /* BCM_OBJECT_TRACE */
583 
584 /* public functions */
585 int dhd_wlfc_parse_header_info(dhd_pub_t *dhd, void *pktbuf, int tlv_hdr_len,
586                                uchar *reorder_info_buf, uint *reorder_info_len);
587 KERNEL_THREAD_RETURN_TYPE dhd_wlfc_transfer_packets(void *data);
588 int dhd_wlfc_commit_packets(dhd_pub_t *dhdp, f_commitpkt_t fcommit,
589                             void *commit_ctx, void *pktbuf,
590                             bool need_toggle_host_if);
591 int dhd_wlfc_txcomplete(dhd_pub_t *dhd, void *txp, bool success);
592 int dhd_wlfc_init(dhd_pub_t *dhd);
593 #ifdef SUPPORT_P2P_GO_PS
594 int dhd_wlfc_suspend(dhd_pub_t *dhd);
595 int dhd_wlfc_resume(dhd_pub_t *dhd);
596 #endif /* SUPPORT_P2P_GO_PS */
597 int dhd_wlfc_hostreorder_init(dhd_pub_t *dhd);
598 int dhd_wlfc_cleanup_txq(dhd_pub_t *dhd, f_processpkt_t fn, void *arg);
599 int dhd_wlfc_cleanup(dhd_pub_t *dhd, f_processpkt_t fn, void *arg);
600 int dhd_wlfc_deinit(dhd_pub_t *dhd);
601 int dhd_wlfc_interface_event(dhd_pub_t *dhdp, uint8 action, uint8 ifid,
602                              uint8 iftype, uint8 *ea);
603 int dhd_wlfc_FIFOcreditmap_event(dhd_pub_t *dhdp, uint8 *event_data);
604 #ifdef LIMIT_BORROW
605 int dhd_wlfc_disable_credit_borrow_event(dhd_pub_t *dhdp, uint8 *event_data);
606 #endif /* LIMIT_BORROW */
607 int dhd_wlfc_BCMCCredit_support_event(dhd_pub_t *dhdp);
608 int dhd_wlfc_enable(dhd_pub_t *dhdp);
609 int dhd_wlfc_dump(dhd_pub_t *dhdp, struct bcmstrbuf *strbuf);
610 int dhd_wlfc_clear_counts(dhd_pub_t *dhd);
611 int dhd_wlfc_get_enable(dhd_pub_t *dhd, bool *val);
612 int dhd_wlfc_get_mode(dhd_pub_t *dhd, int *val);
613 int dhd_wlfc_set_mode(dhd_pub_t *dhd, int val);
614 bool dhd_wlfc_is_supported(dhd_pub_t *dhd);
615 bool dhd_wlfc_is_header_only_pkt(dhd_pub_t *dhd, void *pktbuf);
616 int dhd_wlfc_flowcontrol(dhd_pub_t *dhdp, bool state, bool bAcquireLock);
617 int dhd_wlfc_save_rxpath_ac_time(dhd_pub_t *dhd, uint8 prio);
618 
619 int dhd_wlfc_get_module_ignore(dhd_pub_t *dhd, int *val);
620 int dhd_wlfc_set_module_ignore(dhd_pub_t *dhd, int val);
621 int dhd_wlfc_get_credit_ignore(dhd_pub_t *dhd, int *val);
622 int dhd_wlfc_set_credit_ignore(dhd_pub_t *dhd, int val);
623 int dhd_wlfc_get_txstatus_ignore(dhd_pub_t *dhd, int *val);
624 int dhd_wlfc_set_txstatus_ignore(dhd_pub_t *dhd, int val);
625 
626 int dhd_wlfc_get_rxpkt_chk(dhd_pub_t *dhd, int *val);
627 int dhd_wlfc_set_rxpkt_chk(dhd_pub_t *dhd, int val);
628 #ifdef PROPTX_MAXCOUNT
629 int dhd_wlfc_update_maxcount(dhd_pub_t *dhdp, uint8 ifid, int maxcount);
630 #endif /* PROPTX_MAXCOUNT */
631 
632 #endif /* __wlfc_host_driver_definitions_h__ */
633