• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2 * Copyright (C) 1999-2013, 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 * $Id: dhd_wlfc.h 398418 2013-04-24 15:18:27Z $
22 *
23 */
24 #ifndef __wlfc_host_driver_definitions_h__
25 #define __wlfc_host_driver_definitions_h__
26 
27 /* 16 bits will provide an absolute max of 65536 slots */
28 #define WLFC_HANGER_MAXITEMS 1024
29 
30 #define WLFC_HANGER_ITEM_STATE_FREE				1
31 #define WLFC_HANGER_ITEM_STATE_INUSE			2
32 #define WLFC_HANGER_ITEM_STATE_INUSE_SUPPRESSED	3
33 
34 #define WLFC_PKTID_HSLOT_MASK			0xffff /* allow 16 bits only */
35 #define WLFC_PKTID_HSLOT_SHIFT			8
36 
37 /* x -> TXSTATUS TAG to/from firmware */
38 #define WLFC_PKTID_HSLOT_GET(x)			\
39 	(((x) >> WLFC_PKTID_HSLOT_SHIFT) & WLFC_PKTID_HSLOT_MASK)
40 #define WLFC_PKTID_HSLOT_SET(var, slot)	\
41 	((var) = ((var) & ~(WLFC_PKTID_HSLOT_MASK << WLFC_PKTID_HSLOT_SHIFT)) | \
42 	(((slot) & WLFC_PKTID_HSLOT_MASK) << WLFC_PKTID_HSLOT_SHIFT))
43 
44 #define WLFC_PKTID_FREERUNCTR_MASK	0xff
45 
46 #define WLFC_PKTID_FREERUNCTR_GET(x)	((x) & WLFC_PKTID_FREERUNCTR_MASK)
47 #define WLFC_PKTID_FREERUNCTR_SET(var, ctr)	\
48 	((var) = (((var) & ~WLFC_PKTID_FREERUNCTR_MASK) | \
49 	(((ctr) & WLFC_PKTID_FREERUNCTR_MASK))))
50 
51 #define WLFC_PKTQ_PENQ(pq, prec, p) ((pktq_full((pq)) || pktq_pfull((pq), (prec)))? \
52 	NULL : pktq_penq((pq), (prec), (p)))
53 #define WLFC_PKTQ_PENQ_HEAD(pq, prec, p) ((pktq_full((pq)) || pktq_pfull((pq), (prec))) ? \
54 	NULL : pktq_penq_head((pq), (prec), (p)))
55 
56 typedef enum ewlfc_packet_state {
57 	eWLFC_PKTTYPE_NEW,
58 	eWLFC_PKTTYPE_DELAYED,
59 	eWLFC_PKTTYPE_SUPPRESSED,
60 	eWLFC_PKTTYPE_MAX
61 } ewlfc_packet_state_t;
62 
63 typedef enum ewlfc_mac_entry_action {
64 	eWLFC_MAC_ENTRY_ACTION_ADD,
65 	eWLFC_MAC_ENTRY_ACTION_DEL,
66 	eWLFC_MAC_ENTRY_ACTION_UPDATE,
67 	eWLFC_MAC_ENTRY_ACTION_MAX
68 } ewlfc_mac_entry_action_t;
69 
70 typedef struct wlfc_hanger_item {
71 	uint8	state;
72 	uint8   gen;
73 	uint8	pad[2];
74 	uint32	identifier;
75 	void*	pkt;
76 #ifdef PROP_TXSTATUS_DEBUG
77 	uint32	push_time;
78 #endif
79 } wlfc_hanger_item_t;
80 
81 typedef struct wlfc_hanger {
82 	int max_items;
83 	uint32 pushed;
84 	uint32 popped;
85 	uint32 failed_to_push;
86 	uint32 failed_to_pop;
87 	uint32 failed_slotfind;
88 	uint32 slot_pos;
89 	wlfc_hanger_item_t items[1];
90 } wlfc_hanger_t;
91 
92 #define WLFC_HANGER_SIZE(n)	((sizeof(wlfc_hanger_t) - \
93 	sizeof(wlfc_hanger_item_t)) + ((n)*sizeof(wlfc_hanger_item_t)))
94 
95 #define WLFC_STATE_OPEN		1
96 #define WLFC_STATE_CLOSE	2
97 
98 #define WLFC_PSQ_PREC_COUNT		((AC_COUNT + 1) * 2) /* 2 for each AC traffic and bc/mc */
99 
100 #define WLFC_PSQ_LEN			2048
101 
102 #define WLFC_FLOWCONTROL_HIWATER	(2048 - 256)
103 #define WLFC_FLOWCONTROL_LOWATER	256
104 
105 typedef struct wlfc_mac_descriptor {
106 	uint8 occupied;
107 	uint8 interface_id;
108 	uint8 iftype;
109 	uint8 state;
110 	uint8 ac_bitmap; /* for APSD */
111 	uint8 requested_credit;
112 	uint8 requested_packet;
113 	uint8 ea[ETHER_ADDR_LEN];
114 	/*
115 	maintain (MAC,AC) based seq count for
116 	packets going to the device. As well as bc/mc.
117 	*/
118 	uint8 seq[AC_COUNT + 1];
119 	uint8 generation;
120 	struct pktq	psq;
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;
128 	/* Number of packets in transit for this entry. */
129 	uint transit_count;
130 	/* Numbe of suppression to wait before evict from delayQ */
131 	uint suppr_transit_count;
132 	/* Used when a new suppress is detected to track the number of
133 	 * packets getting suppressed
134 	 */
135 	uint suppress_count;
136 	/* flag. TRUE when in suppress state */
137 	uint8 suppressed;
138 	uint8 deleting;
139 
140 #ifdef PROP_TXSTATUS_DEBUG
141 	uint32 dstncredit_sent_packets;
142 	uint32 dstncredit_acks;
143 	uint32 opened_ct;
144 	uint32 closed_ct;
145 #endif
146 } wlfc_mac_descriptor_t;
147 
148 #define WLFC_DECR_SEQCOUNT(entry, prec) do { if (entry->seq[(prec)] == 0) {\
149 	entry->seq[prec] = 0xff; } else entry->seq[prec]--;} while (0)
150 
151 #define WLFC_INCR_SEQCOUNT(entry, prec) entry->seq[(prec)]++
152 #define WLFC_SEQCOUNT(entry, prec) entry->seq[(prec)]
153 
154 typedef struct athost_wl_stat_counters {
155 	uint32	pktin;
156 	uint32	pkt2bus;
157 	uint32	pktdropped;
158 	uint32	tlv_parse_failed;
159 	uint32	rollback;
160 	uint32	rollback_failed;
161 	uint32	delayq_full_error;
162 	uint32	credit_request_failed;
163 	uint32	packet_request_failed;
164 	uint32	mac_update_failed;
165 	uint32	psmode_update_failed;
166 	uint32	interface_update_failed;
167 	uint32	wlfc_header_only_pkt;
168 	uint32	txstatus_in;
169 	uint32	d11_suppress;
170 	uint32	wl_suppress;
171 	uint32	bad_suppress;
172 	uint32	pkt_freed;
173 	uint32	pkt_free_err;
174 	uint32	psq_wlsup_retx;
175 	uint32	psq_wlsup_enq;
176 	uint32	psq_d11sup_retx;
177 	uint32	psq_d11sup_enq;
178 	uint32	psq_hostq_retx;
179 	uint32	psq_hostq_enq;
180 	uint32	mac_handle_notfound;
181 	uint32	wlc_tossed_pkts;
182 	uint32	dhd_hdrpulls;
183 	uint32	generic_error;
184 	/* an extra one for bc/mc traffic */
185 	uint32	send_pkts[AC_COUNT + 1];
186 #ifdef PROP_TXSTATUS_DEBUG
187 	/* all pkt2bus -> txstatus latency accumulated */
188 	uint32	latency_sample_count;
189 	uint32	total_status_latency;
190 	uint32	latency_most_recent;
191 	int		idx_delta;
192 	uint32	deltas[10];
193 	uint32	fifo_credits_sent[6];
194 	uint32	fifo_credits_back[6];
195 	uint32	dropped_qfull[6];
196 	uint32	signal_only_pkts_sent;
197 	uint32	signal_only_pkts_freed;
198 #endif
199 } athost_wl_stat_counters_t;
200 
201 #ifdef PROP_TXSTATUS_DEBUG
202 #define WLFC_HOST_FIFO_CREDIT_INC_SENTCTRS(ctx, ac) do { \
203 	(ctx)->stats.fifo_credits_sent[(ac)]++;} while (0)
204 #define WLFC_HOST_FIFO_CREDIT_INC_BACKCTRS(ctx, ac) do { \
205 	(ctx)->stats.fifo_credits_back[(ac)]++;} while (0)
206 #define WLFC_HOST_FIFO_DROPPEDCTR_INC(ctx, ac) do { \
207 	(ctx)->stats.dropped_qfull[(ac)]++;} while (0)
208 #else
209 #define WLFC_HOST_FIFO_CREDIT_INC_SENTCTRS(ctx, ac) do {} while (0)
210 #define WLFC_HOST_FIFO_CREDIT_INC_BACKCTRS(ctx, ac) do {} while (0)
211 #define WLFC_HOST_FIFO_DROPPEDCTR_INC(ctx, ac) do {} while (0)
212 #endif
213 
214 #define WLFC_FCMODE_NONE				0
215 #define WLFC_FCMODE_IMPLIED_CREDIT		1
216 #define WLFC_FCMODE_EXPLICIT_CREDIT		2
217 
218 /* How long to defer borrowing in milliseconds */
219 #define WLFC_BORROW_DEFER_PERIOD_MS 100
220 
221 /* Mask to represent available ACs (note: BC/MC is ignored */
222 #define WLFC_AC_MASK 0xF
223 
224 /* Mask to check for only on-going AC_BE traffic */
225 #define WLFC_AC_BE_TRAFFIC_ONLY 0xD
226 
227 typedef struct athost_wl_status_info {
228 	uint8	last_seqid_to_wlc;
229 
230 	/* OSL handle */
231 	osl_t*	osh;
232 	/* dhd pub */
233 	void*	dhdp;
234 
235 	/* stats */
236 	athost_wl_stat_counters_t stats;
237 
238 	/* the additional ones are for bc/mc and ATIM FIFO */
239 	int		FIFO_credit[AC_COUNT + 2];
240 
241 	/* Credit borrow counts for each FIFO from each of the other FIFOs */
242 	int		credits_borrowed[AC_COUNT + 2][AC_COUNT + 2];
243 
244 	/* packet hanger and MAC->handle lookup table */
245 	void*	hanger;
246 	struct {
247 		/* table for individual nodes */
248 		wlfc_mac_descriptor_t	nodes[WLFC_MAC_DESC_TABLE_SIZE];
249 		/* table for interfaces */
250 		wlfc_mac_descriptor_t	interfaces[WLFC_MAX_IFNUM];
251 		/* OS may send packets to unknown (unassociated) destinations */
252 		/* A place holder for bc/mc and packets to unknown destinations */
253 		wlfc_mac_descriptor_t	other;
254 	} destination_entries;
255 	/* token position for different priority packets */
256 	uint8   token_pos[AC_COUNT+1];
257 	/* ON/OFF state for flow control to the host network interface */
258 	uint8	hostif_flow_state[WLFC_MAX_IFNUM];
259 	uint8	host_ifidx;
260 	/* to flow control an OS interface */
261 	uint8	toggle_host_if;
262 
263 	/*
264 	Mode in which the dhd flow control shall operate. Must be set before
265 	traffic starts to the device.
266 	0 - Do not do any proptxtstatus flow control
267 	1 - Use implied credit from a packet status
268 	2 - Use explicit credit
269 	*/
270 	uint8	proptxstatus_mode;
271 
272 	/* To borrow credits */
273 	uint8   allow_credit_borrow;
274 
275 	/* Timestamp to compute how long to defer borrowing for */
276 	uint32  borrow_defer_timestamp;
277 
278 } athost_wl_status_info_t;
279 
280 int dhd_wlfc_enable(dhd_pub_t *dhd);
281 int dhd_wlfc_interface_event(struct dhd_info *,
282 	ewlfc_mac_entry_action_t action, uint8 ifid, uint8 iftype, uint8* ea);
283 int dhd_wlfc_FIFOcreditmap_event(struct dhd_info *dhd, uint8* event_data);
284 int dhd_wlfc_event(struct dhd_info *dhd);
285 int dhd_os_wlfc_block(dhd_pub_t *pub);
286 int dhd_os_wlfc_unblock(dhd_pub_t *pub);
287 
288 void dhd_wlfc_dump(dhd_pub_t *dhdp, struct bcmstrbuf *strbuf);
289 int dhd_wlfc_init(dhd_pub_t *dhd);
290 void dhd_wlfc_deinit(dhd_pub_t *dhd);
291 int dhd_wlfc_parse_header_info(dhd_pub_t *dhd, void* pktbuf, int tlv_hdr_len,
292 	uchar *reorder_info_buf, uint *reorder_info_len);
293 int dhd_wlfc_commit_packets(void* state, f_commitpkt_t fcommit,
294 	void* commit_ctx, void *pktbuf);
295 void dhd_wlfc_cleanup(dhd_pub_t *dhd, ifpkt_cb_t fn, int arg);
296 bool ifpkt_fn(void* p, int ifid);
297 #endif /* __wlfc_host_driver_definitions_h__ */
298