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