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