dhd_wlfc.h 21 KB

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