1 /*
2  * Copyright (c) 2010 Broadcom Corporation
3  *
4  * Permission to use, copy, modify, and/or distribute this software for any
5  * purpose with or without fee is hereby granted, provided that the above
6  * copyright notice and this permission notice appear in all copies.
7  *
8  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11  * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15  */
16 
17 #include <linux/types.h>
18 #include <bcmdefs.h>
19 #include <linux/netdevice.h>
20 #include <bcmsdh.h>
21 
22 #ifdef BCMEMBEDIMAGE
23 #include BCMEMBEDIMAGE
24 #endif				/* BCMEMBEDIMAGE */
25 
26 #include <bcmdefs.h>
27 #include <bcmutils.h>
28 #include <bcmdevs.h>
29 
30 #include <siutils.h>
31 #include <hndpmu.h>
32 #include <hndsoc.h>
33 #ifdef DHD_DEBUG
34 #include <hndrte_armtrap.h>
35 #include <hndrte_cons.h>
36 #endif				/* DHD_DEBUG */
37 #include <sbchipc.h>
38 #include <sbhnddma.h>
39 
40 #include <sdio.h>
41 #include <sbsdio.h>
42 #include <sbsdpcmdev.h>
43 #include <bcmsdpcm.h>
44 
45 #include <proto/802.11.h>
46 
47 #include <dngl_stats.h>
48 #include <dhd.h>
49 #include <dhd_bus.h>
50 #include <dhd_proto.h>
51 #include <dhd_dbg.h>
52 #include <dhdioctl.h>
53 #include <sdiovar.h>
54 #include <siutils_priv.h>
55 
56 #ifndef DHDSDIO_MEM_DUMP_FNAME
57 #define DHDSDIO_MEM_DUMP_FNAME         "mem_dump"
58 #endif
59 
60 #define TXQLEN		2048	/* bulk tx queue length */
61 #define TXHI		(TXQLEN - 256)	/* turn on flow control above TXHI */
62 #define TXLOW		(TXHI - 256)	/* turn off flow control below TXLOW */
63 #define PRIOMASK	7
64 
65 #define TXRETRIES	2	/* # of retries for tx frames */
66 
67 #if defined(CONFIG_MACH_SANDGATE2G)
68 #define DHD_RXBOUND	250	/* Default for max rx frames in
69 				 one scheduling */
70 #else
71 #define DHD_RXBOUND	50	/* Default for max rx frames in
72 				 one scheduling */
73 #endif				/* defined(CONFIG_MACH_SANDGATE2G) */
74 
75 #define DHD_TXBOUND	20	/* Default for max tx frames in
76 				 one scheduling */
77 
78 #define DHD_TXMINMAX	1	/* Max tx frames if rx still pending */
79 
80 #define MEMBLOCK	2048	/* Block size used for downloading
81 				 of dongle image */
82 #define MAX_DATA_BUF	(32 * 1024)	/* Must be large enough to hold
83 				 biggest possible glom */
84 
85 /* Packet alignment for most efficient SDIO (can change based on platform) */
86 #ifndef DHD_SDALIGN
87 #define DHD_SDALIGN	32
88 #endif
89 #if !ISPOWEROF2(DHD_SDALIGN)
90 #error DHD_SDALIGN is not a power of 2!
91 #endif
92 
93 #ifndef DHD_FIRSTREAD
94 #define DHD_FIRSTREAD	32
95 #endif
96 #if !ISPOWEROF2(DHD_FIRSTREAD)
97 #error DHD_FIRSTREAD is not a power of 2!
98 #endif
99 
100 /* Total length of frame header for dongle protocol */
101 #define SDPCM_HDRLEN	(SDPCM_FRAMETAG_LEN + SDPCM_SWHEADER_LEN)
102 #ifdef SDTEST
103 #define SDPCM_RESERVE	(SDPCM_HDRLEN + SDPCM_TEST_HDRLEN + DHD_SDALIGN)
104 #else
105 #define SDPCM_RESERVE	(SDPCM_HDRLEN + DHD_SDALIGN)
106 #endif
107 
108 /* Space for header read, limit for data packets */
109 #ifndef MAX_HDR_READ
110 #define MAX_HDR_READ	32
111 #endif
112 #if !ISPOWEROF2(MAX_HDR_READ)
113 #error MAX_HDR_READ is not a power of 2!
114 #endif
115 
116 #define MAX_RX_DATASZ	2048
117 
118 /* Maximum milliseconds to wait for F2 to come up */
119 #define DHD_WAIT_F2RDY	3000
120 
121 /* Bump up limit on waiting for HT to account for first startup;
122  * if the image is doing a CRC calculation before programming the PMU
123  * for HT availability, it could take a couple hundred ms more, so
124  * max out at a 1 second (1000000us).
125  */
126 #if (PMU_MAX_TRANSITION_DLY <= 1000000)
127 #undef PMU_MAX_TRANSITION_DLY
128 #define PMU_MAX_TRANSITION_DLY 1000000
129 #endif
130 
131 /* Value for ChipClockCSR during initial setup */
132 #define DHD_INIT_CLKCTL1	(SBSDIO_FORCE_HW_CLKREQ_OFF |	\
133 					SBSDIO_ALP_AVAIL_REQ)
134 #define DHD_INIT_CLKCTL2	(SBSDIO_FORCE_HW_CLKREQ_OFF | SBSDIO_FORCE_ALP)
135 
136 /* Flags for SDH calls */
137 #define F2SYNC	(SDIO_REQ_4BYTE | SDIO_REQ_FIXED)
138 
139 /* Packet free applicable unconditionally for sdio and sdspi.  Conditional if
140  * bufpool was present for gspi bus.
141  */
142 #define PKTFREE2()		if ((bus->bus != SPI_BUS) || bus->usebufpool) \
143 							pkt_buf_free_skb(pkt);
144 
145 /*
146  * Conversion of 802.1D priority to precedence level
147  */
148 #define PRIO2PREC(prio) \
149 	(((prio) == PRIO_8021D_NONE || (prio) == PRIO_8021D_BE) ? \
150 	((prio^2)) : (prio))
151 
152 DHD_SPINWAIT_SLEEP_INIT(sdioh_spinwait_sleep);
153 extern int dhdcdc_set_ioctl(dhd_pub_t *dhd, int ifidx, uint cmd, void *buf,
154 			    uint len);
155 
156 #ifdef DHD_DEBUG
157 /* Device console log buffer state */
158 typedef struct dhd_console {
159 	uint count;		/* Poll interval msec counter */
160 	uint log_addr;		/* Log struct address (fixed) */
161 	hndrte_log_t log;	/* Log struct (host copy) */
162 	uint bufsize;		/* Size of log buffer */
163 	u8 *buf;		/* Log buffer (host copy) */
164 	uint last;		/* Last buffer read index */
165 } dhd_console_t;
166 #endif				/* DHD_DEBUG */
167 
168 /* Private data for SDIO bus interaction */
169 typedef struct dhd_bus {
170 	dhd_pub_t *dhd;
171 
172 	bcmsdh_info_t *sdh;	/* Handle for BCMSDH calls */
173 	si_t *sih;		/* Handle for SI calls */
174 	char *vars;		/* Variables (from CIS and/or other) */
175 	uint varsz;		/* Size of variables buffer */
176 	u32 sbaddr;		/* Current SB window pointer (-1, invalid) */
177 
178 	sdpcmd_regs_t *regs;	/* Registers for SDIO core */
179 	uint sdpcmrev;		/* SDIO core revision */
180 	uint armrev;		/* CPU core revision */
181 	uint ramrev;		/* SOCRAM core revision */
182 	u32 ramsize;		/* Size of RAM in SOCRAM (bytes) */
183 	u32 orig_ramsize;	/* Size of RAM in SOCRAM (bytes) */
184 
185 	u32 bus;		/* gSPI or SDIO bus */
186 	u32 hostintmask;	/* Copy of Host Interrupt Mask */
187 	u32 intstatus;	/* Intstatus bits (events) pending */
188 	bool dpc_sched;		/* Indicates DPC schedule (intrpt rcvd) */
189 	bool fcstate;		/* State of dongle flow-control */
190 
191 	u16 cl_devid;	/* cached devid for dhdsdio_probe_attach() */
192 	char *fw_path;		/* module_param: path to firmware image */
193 	char *nv_path;		/* module_param: path to nvram vars file */
194 	const char *nvram_params;	/* user specified nvram params. */
195 
196 	uint blocksize;		/* Block size of SDIO transfers */
197 	uint roundup;		/* Max roundup limit */
198 
199 	struct pktq txq;	/* Queue length used for flow-control */
200 	u8 flowcontrol;	/* per prio flow control bitmask */
201 	u8 tx_seq;		/* Transmit sequence number (next) */
202 	u8 tx_max;		/* Maximum transmit sequence allowed */
203 
204 	u8 hdrbuf[MAX_HDR_READ + DHD_SDALIGN];
205 	u8 *rxhdr;		/* Header of current rx frame (in hdrbuf) */
206 	u16 nextlen;		/* Next Read Len from last header */
207 	u8 rx_seq;		/* Receive sequence number (expected) */
208 	bool rxskip;		/* Skip receive (awaiting NAK ACK) */
209 
210 	struct sk_buff *glomd;	/* Packet containing glomming descriptor */
211 	struct sk_buff *glom;	/* Packet chain for glommed superframe */
212 	uint glomerr;		/* Glom packet read errors */
213 
214 	u8 *rxbuf;		/* Buffer for receiving control packets */
215 	uint rxblen;		/* Allocated length of rxbuf */
216 	u8 *rxctl;		/* Aligned pointer into rxbuf */
217 	u8 *databuf;		/* Buffer for receiving big glom packet */
218 	u8 *dataptr;		/* Aligned pointer into databuf */
219 	uint rxlen;		/* Length of valid data in buffer */
220 
221 	u8 sdpcm_ver;	/* Bus protocol reported by dongle */
222 
223 	bool intr;		/* Use interrupts */
224 	bool poll;		/* Use polling */
225 	bool ipend;		/* Device interrupt is pending */
226 	bool intdis;		/* Interrupts disabled by isr */
227 	uint intrcount;		/* Count of device interrupt callbacks */
228 	uint lastintrs;		/* Count as of last watchdog timer */
229 	uint spurious;		/* Count of spurious interrupts */
230 	uint pollrate;		/* Ticks between device polls */
231 	uint polltick;		/* Tick counter */
232 	uint pollcnt;		/* Count of active polls */
233 
234 #ifdef DHD_DEBUG
235 	dhd_console_t console;	/* Console output polling support */
236 	uint console_addr;	/* Console address from shared struct */
237 #endif				/* DHD_DEBUG */
238 
239 	uint regfails;		/* Count of R_REG/W_REG failures */
240 
241 	uint clkstate;		/* State of sd and backplane clock(s) */
242 	bool activity;		/* Activity flag for clock down */
243 	s32 idletime;		/* Control for activity timeout */
244 	s32 idlecount;	/* Activity timeout counter */
245 	s32 idleclock;	/* How to set bus driver when idle */
246 	s32 sd_divisor;	/* Speed control to bus driver */
247 	s32 sd_mode;		/* Mode control to bus driver */
248 	s32 sd_rxchain;	/* If bcmsdh api accepts PKT chains */
249 	bool use_rxchain;	/* If dhd should use PKT chains */
250 	bool sleeping;		/* Is SDIO bus sleeping? */
251 	bool rxflow_mode;	/* Rx flow control mode */
252 	bool rxflow;		/* Is rx flow control on */
253 	uint prev_rxlim_hit;	/* Is prev rx limit exceeded
254 					 (per dpc schedule) */
255 	bool alp_only;		/* Don't use HT clock (ALP only) */
256 /* Field to decide if rx of control frames happen in rxbuf or lb-pool */
257 	bool usebufpool;
258 
259 #ifdef SDTEST
260 	/* external loopback */
261 	bool ext_loop;
262 	u8 loopid;
263 
264 	/* pktgen configuration */
265 	uint pktgen_freq;	/* Ticks between bursts */
266 	uint pktgen_count;	/* Packets to send each burst */
267 	uint pktgen_print;	/* Bursts between count displays */
268 	uint pktgen_total;	/* Stop after this many */
269 	uint pktgen_minlen;	/* Minimum packet data len */
270 	uint pktgen_maxlen;	/* Maximum packet data len */
271 	uint pktgen_mode;	/* Configured mode: tx, rx, or echo */
272 	uint pktgen_stop;	/* Number of tx failures causing stop */
273 
274 	/* active pktgen fields */
275 	uint pktgen_tick;	/* Tick counter for bursts */
276 	uint pktgen_ptick;	/* Burst counter for printing */
277 	uint pktgen_sent;	/* Number of test packets generated */
278 	uint pktgen_rcvd;	/* Number of test packets received */
279 	uint pktgen_fail;	/* Number of failed send attempts */
280 	u16 pktgen_len;	/* Length of next packet to send */
281 #endif				/* SDTEST */
282 
283 	/* Some additional counters */
284 	uint tx_sderrs;		/* Count of tx attempts with sd errors */
285 	uint fcqueued;		/* Tx packets that got queued */
286 	uint rxrtx;		/* Count of rtx requests (NAK to dongle) */
287 	uint rx_toolong;	/* Receive frames too long to receive */
288 	uint rxc_errors;	/* SDIO errors when reading control frames */
289 	uint rx_hdrfail;	/* SDIO errors on header reads */
290 	uint rx_badhdr;		/* Bad received headers (roosync?) */
291 	uint rx_badseq;		/* Mismatched rx sequence number */
292 	uint fc_rcvd;		/* Number of flow-control events received */
293 	uint fc_xoff;		/* Number which turned on flow-control */
294 	uint fc_xon;		/* Number which turned off flow-control */
295 	uint rxglomfail;	/* Failed deglom attempts */
296 	uint rxglomframes;	/* Number of glom frames (superframes) */
297 	uint rxglompkts;	/* Number of packets from glom frames */
298 	uint f2rxhdrs;		/* Number of header reads */
299 	uint f2rxdata;		/* Number of frame data reads */
300 	uint f2txdata;		/* Number of f2 frame writes */
301 	uint f1regdata;		/* Number of f1 register accesses */
302 
303 	u8 *ctrl_frame_buf;
304 	u32 ctrl_frame_len;
305 	bool ctrl_frame_stat;
306 } dhd_bus_t;
307 
308 /* clkstate */
309 #define CLK_NONE	0
310 #define CLK_SDONLY	1
311 #define CLK_PENDING	2	/* Not used yet */
312 #define CLK_AVAIL	3
313 
314 #define DHD_NOPMU(dhd)	(false)
315 
316 #ifdef DHD_DEBUG
317 static int qcount[NUMPRIO];
318 static int tx_packets[NUMPRIO];
319 #endif				/* DHD_DEBUG */
320 
321 /* Deferred transmit */
322 const uint dhd_deferred_tx = 1;
323 
324 extern uint dhd_watchdog_ms;
325 extern void dhd_os_wd_timer(void *bus, uint wdtick);
326 
327 /* Tx/Rx bounds */
328 uint dhd_txbound;
329 uint dhd_rxbound;
330 uint dhd_txminmax;
331 
332 /* override the RAM size if possible */
333 #define DONGLE_MIN_MEMSIZE (128 * 1024)
334 int dhd_dongle_memsize;
335 
336 static bool dhd_alignctl;
337 
338 static bool sd1idle;
339 
340 static bool retrydata;
341 #define RETRYCHAN(chan) (((chan) == SDPCM_EVENT_CHANNEL) || retrydata)
342 
343 static const uint watermark = 8;
344 static const uint firstread = DHD_FIRSTREAD;
345 
346 #define HDATLEN (firstread - (SDPCM_HDRLEN))
347 
348 /* Retry count for register access failures */
349 static const uint retry_limit = 2;
350 
351 /* Force even SD lengths (some host controllers mess up on odd bytes) */
352 static bool forcealign;
353 
354 #define ALIGNMENT  4
355 
356 #if defined(OOB_INTR_ONLY) && defined(HW_OOB)
357 extern void bcmsdh_enable_hw_oob_intr(void *sdh, bool enable);
358 #endif
359 
360 #if defined(OOB_INTR_ONLY) && defined(SDIO_ISR_THREAD)
361 #error OOB_INTR_ONLY is NOT working with SDIO_ISR_THREAD
362 #endif	/* defined(OOB_INTR_ONLY) && defined(SDIO_ISR_THREAD) */
363 #define PKTALIGN(_p, _len, _align)				\
364 	do {								\
365 		uint datalign;						\
366 		datalign = (unsigned long)((_p)->data);			\
367 		datalign = roundup(datalign, (_align)) - datalign;	\
368 		ASSERT(datalign < (_align));				\
369 		ASSERT((_p)->len >= ((_len) + datalign));		\
370 		if (datalign)						\
371 			skb_pull((_p), datalign);			\
372 		__skb_trim((_p), (_len));				\
373 	} while (0)
374 
375 /* Limit on rounding up frames */
376 static const uint max_roundup = 512;
377 
378 /* Try doing readahead */
379 static bool dhd_readahead;
380 
381 /* To check if there's window offered */
382 #define DATAOK(bus) \
383 	(((u8)(bus->tx_max - bus->tx_seq) != 0) && \
384 	(((u8)(bus->tx_max - bus->tx_seq) & 0x80) == 0))
385 
386 /* Macros to get register read/write status */
387 /* NOTE: these assume a local dhdsdio_bus_t *bus! */
388 #define R_SDREG(regvar, regaddr, retryvar) \
389 do { \
390 	retryvar = 0; \
391 	do { \
392 		regvar = R_REG(regaddr); \
393 	} while (bcmsdh_regfail(bus->sdh) && (++retryvar <= retry_limit)); \
394 	if (retryvar) { \
395 		bus->regfails += (retryvar-1); \
396 		if (retryvar > retry_limit) { \
397 			DHD_ERROR(("%s: FAILED" #regvar "READ, LINE %d\n", \
398 			__func__, __LINE__)); \
399 			regvar = 0; \
400 		} \
401 	} \
402 } while (0)
403 
404 #define W_SDREG(regval, regaddr, retryvar) \
405 do { \
406 	retryvar = 0; \
407 	do { \
408 		W_REG(regaddr, regval); \
409 	} while (bcmsdh_regfail(bus->sdh) && (++retryvar <= retry_limit)); \
410 	if (retryvar) { \
411 		bus->regfails += (retryvar-1); \
412 		if (retryvar > retry_limit) \
413 			DHD_ERROR(("%s: FAILED REGISTER WRITE, LINE %d\n", \
414 			__func__, __LINE__)); \
415 	} \
416 } while (0)
417 
418 #define DHD_BUS			SDIO_BUS
419 
420 #define PKT_AVAILABLE()		(intstatus & I_HMB_FRAME_IND)
421 
422 #define HOSTINTMASK		(I_HMB_SW_MASK | I_CHIPACTIVE)
423 
424 #define GSPI_PR55150_BAILOUT
425 
426 #ifdef SDTEST
427 static void dhdsdio_testrcv(dhd_bus_t *bus, void *pkt, uint seq);
428 static void dhdsdio_sdtest_set(dhd_bus_t *bus, bool start);
429 #endif
430 
431 #ifdef DHD_DEBUG
432 static int dhdsdio_checkdied(dhd_bus_t *bus, u8 *data, uint size);
433 static int dhdsdio_mem_dump(dhd_bus_t *bus);
434 #endif				/* DHD_DEBUG  */
435 static int dhdsdio_download_state(dhd_bus_t *bus, bool enter);
436 
437 static void dhdsdio_release(dhd_bus_t *bus);
438 static void dhdsdio_release_malloc(dhd_bus_t *bus);
439 static void dhdsdio_disconnect(void *ptr);
440 static bool dhdsdio_chipmatch(u16 chipid);
441 static bool dhdsdio_probe_attach(dhd_bus_t *bus, void *sdh,
442 				 void *regsva, u16 devid);
443 static bool dhdsdio_probe_malloc(dhd_bus_t *bus, void *sdh);
444 static bool dhdsdio_probe_init(dhd_bus_t *bus, void *sdh);
445 static void dhdsdio_release_dongle(dhd_bus_t *bus);
446 
447 static uint process_nvram_vars(char *varbuf, uint len);
448 
449 static void dhd_dongle_setmemsize(struct dhd_bus *bus, int mem_size);
450 static int dhd_bcmsdh_recv_buf(dhd_bus_t *bus, u32 addr, uint fn,
451 			       uint flags, u8 *buf, uint nbytes,
452 			       struct sk_buff *pkt, bcmsdh_cmplt_fn_t complete,
453 			       void *handle);
454 static int dhd_bcmsdh_send_buf(dhd_bus_t *bus, u32 addr, uint fn,
455 			       uint flags, u8 *buf, uint nbytes,
456 			       struct sk_buff *pkt, bcmsdh_cmplt_fn_t complete,
457 			       void *handle);
458 
459 static bool dhdsdio_download_firmware(struct dhd_bus *bus, void *sdh);
460 static int _dhdsdio_download_firmware(struct dhd_bus *bus);
461 
462 static int dhdsdio_download_code_file(struct dhd_bus *bus, char *image_path);
463 static int dhdsdio_download_nvram(struct dhd_bus *bus);
464 #ifdef BCMEMBEDIMAGE
465 static int dhdsdio_download_code_array(struct dhd_bus *bus);
466 #endif
467 
dhd_dongle_setmemsize(struct dhd_bus * bus,int mem_size)468 static void dhd_dongle_setmemsize(struct dhd_bus *bus, int mem_size)
469 {
470 	s32 min_size = DONGLE_MIN_MEMSIZE;
471 	/* Restrict the memsize to user specified limit */
472 	DHD_ERROR(("user: Restrict the dongle ram size to %d, min %d\n",
473 		dhd_dongle_memsize, min_size));
474 	if ((dhd_dongle_memsize > min_size) &&
475 	    (dhd_dongle_memsize < (s32) bus->orig_ramsize))
476 		bus->ramsize = dhd_dongle_memsize;
477 }
478 
dhdsdio_set_siaddr_window(dhd_bus_t * bus,u32 address)479 static int dhdsdio_set_siaddr_window(dhd_bus_t *bus, u32 address)
480 {
481 	int err = 0;
482 	bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_1, SBSDIO_FUNC1_SBADDRLOW,
483 			 (address >> 8) & SBSDIO_SBADDRLOW_MASK, &err);
484 	if (!err)
485 		bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_1, SBSDIO_FUNC1_SBADDRMID,
486 				 (address >> 16) & SBSDIO_SBADDRMID_MASK, &err);
487 	if (!err)
488 		bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_1, SBSDIO_FUNC1_SBADDRHIGH,
489 				 (address >> 24) & SBSDIO_SBADDRHIGH_MASK,
490 				 &err);
491 	return err;
492 }
493 
494 /* Turn backplane clock on or off */
dhdsdio_htclk(dhd_bus_t * bus,bool on,bool pendok)495 static int dhdsdio_htclk(dhd_bus_t *bus, bool on, bool pendok)
496 {
497 	int err;
498 	u8 clkctl, clkreq, devctl;
499 	bcmsdh_info_t *sdh;
500 
501 	DHD_TRACE(("%s: Enter\n", __func__));
502 
503 #if defined(OOB_INTR_ONLY)
504 	pendok = false;
505 #endif
506 	clkctl = 0;
507 	sdh = bus->sdh;
508 
509 	if (on) {
510 		/* Request HT Avail */
511 		clkreq =
512 		    bus->alp_only ? SBSDIO_ALP_AVAIL_REQ : SBSDIO_HT_AVAIL_REQ;
513 
514 		if ((bus->sih->chip == BCM4329_CHIP_ID)
515 		    && (bus->sih->chiprev == 0))
516 			clkreq |= SBSDIO_FORCE_ALP;
517 
518 		bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR,
519 				 clkreq, &err);
520 		if (err) {
521 			DHD_ERROR(("%s: HT Avail request error: %d\n",
522 				   __func__, err));
523 			return BCME_ERROR;
524 		}
525 
526 		if (pendok && ((bus->sih->buscoretype == PCMCIA_CORE_ID)
527 			       && (bus->sih->buscorerev == 9))) {
528 			u32 dummy, retries;
529 			R_SDREG(dummy, &bus->regs->clockctlstatus, retries);
530 		}
531 
532 		/* Check current status */
533 		clkctl =
534 		    bcmsdh_cfg_read(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR,
535 				    &err);
536 		if (err) {
537 			DHD_ERROR(("%s: HT Avail read error: %d\n",
538 				   __func__, err));
539 			return BCME_ERROR;
540 		}
541 
542 		/* Go to pending and await interrupt if appropriate */
543 		if (!SBSDIO_CLKAV(clkctl, bus->alp_only) && pendok) {
544 			/* Allow only clock-available interrupt */
545 			devctl =
546 			    bcmsdh_cfg_read(sdh, SDIO_FUNC_1, SBSDIO_DEVICE_CTL,
547 					    &err);
548 			if (err) {
549 				DHD_ERROR(("%s: Devctl error setting CA: %d\n",
550 					__func__, err));
551 				return BCME_ERROR;
552 			}
553 
554 			devctl |= SBSDIO_DEVCTL_CA_INT_ONLY;
555 			bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_DEVICE_CTL,
556 					 devctl, &err);
557 			DHD_INFO(("CLKCTL: set PENDING\n"));
558 			bus->clkstate = CLK_PENDING;
559 
560 			return BCME_OK;
561 		} else if (bus->clkstate == CLK_PENDING) {
562 			/* Cancel CA-only interrupt filter */
563 			devctl =
564 			    bcmsdh_cfg_read(sdh, SDIO_FUNC_1, SBSDIO_DEVICE_CTL,
565 					    &err);
566 			devctl &= ~SBSDIO_DEVCTL_CA_INT_ONLY;
567 			bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_DEVICE_CTL,
568 					 devctl, &err);
569 		}
570 
571 		/* Otherwise, wait here (polling) for HT Avail */
572 		if (!SBSDIO_CLKAV(clkctl, bus->alp_only)) {
573 			SPINWAIT_SLEEP(sdioh_spinwait_sleep,
574 				       ((clkctl =
575 					 bcmsdh_cfg_read(sdh, SDIO_FUNC_1,
576 						 SBSDIO_FUNC1_CHIPCLKCSR,
577 							 &err)),
578 					!SBSDIO_CLKAV(clkctl, bus->alp_only)),
579 				       PMU_MAX_TRANSITION_DLY);
580 		}
581 		if (err) {
582 			DHD_ERROR(("%s: HT Avail request error: %d\n",
583 				   __func__, err));
584 			return BCME_ERROR;
585 		}
586 		if (!SBSDIO_CLKAV(clkctl, bus->alp_only)) {
587 			DHD_ERROR(("%s: HT Avail timeout (%d): clkctl 0x%02x\n",
588 				   __func__, PMU_MAX_TRANSITION_DLY, clkctl));
589 			return BCME_ERROR;
590 		}
591 
592 		/* Mark clock available */
593 		bus->clkstate = CLK_AVAIL;
594 		DHD_INFO(("CLKCTL: turned ON\n"));
595 
596 #if defined(DHD_DEBUG)
597 		if (bus->alp_only == true) {
598 #if !defined(BCMLXSDMMC)
599 			if (!SBSDIO_ALPONLY(clkctl)) {
600 				DHD_ERROR(("%s: HT Clock, when ALP Only\n",
601 					   __func__));
602 			}
603 #endif				/* !defined(BCMLXSDMMC) */
604 		} else {
605 			if (SBSDIO_ALPONLY(clkctl)) {
606 				DHD_ERROR(("%s: HT Clock should be on.\n",
607 					   __func__));
608 			}
609 		}
610 #endif				/* defined (DHD_DEBUG) */
611 
612 		bus->activity = true;
613 	} else {
614 		clkreq = 0;
615 
616 		if (bus->clkstate == CLK_PENDING) {
617 			/* Cancel CA-only interrupt filter */
618 			devctl =
619 			    bcmsdh_cfg_read(sdh, SDIO_FUNC_1, SBSDIO_DEVICE_CTL,
620 					    &err);
621 			devctl &= ~SBSDIO_DEVCTL_CA_INT_ONLY;
622 			bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_DEVICE_CTL,
623 					 devctl, &err);
624 		}
625 
626 		bus->clkstate = CLK_SDONLY;
627 		bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR,
628 				 clkreq, &err);
629 		DHD_INFO(("CLKCTL: turned OFF\n"));
630 		if (err) {
631 			DHD_ERROR(("%s: Failed access turning clock off: %d\n",
632 				   __func__, err));
633 			return BCME_ERROR;
634 		}
635 	}
636 	return BCME_OK;
637 }
638 
639 /* Change idle/active SD state */
dhdsdio_sdclk(dhd_bus_t * bus,bool on)640 static int dhdsdio_sdclk(dhd_bus_t *bus, bool on)
641 {
642 	int err;
643 	s32 iovalue;
644 
645 	DHD_TRACE(("%s: Enter\n", __func__));
646 
647 	if (on) {
648 		if (bus->idleclock == DHD_IDLE_STOP) {
649 			/* Turn on clock and restore mode */
650 			iovalue = 1;
651 			err = bcmsdh_iovar_op(bus->sdh, "sd_clock", NULL, 0,
652 					      &iovalue, sizeof(iovalue), true);
653 			if (err) {
654 				DHD_ERROR(("%s: error enabling sd_clock: %d\n",
655 					   __func__, err));
656 				return BCME_ERROR;
657 			}
658 
659 			iovalue = bus->sd_mode;
660 			err = bcmsdh_iovar_op(bus->sdh, "sd_mode", NULL, 0,
661 					      &iovalue, sizeof(iovalue), true);
662 			if (err) {
663 				DHD_ERROR(("%s: error changing sd_mode: %d\n",
664 					   __func__, err));
665 				return BCME_ERROR;
666 			}
667 		} else if (bus->idleclock != DHD_IDLE_ACTIVE) {
668 			/* Restore clock speed */
669 			iovalue = bus->sd_divisor;
670 			err = bcmsdh_iovar_op(bus->sdh, "sd_divisor", NULL, 0,
671 					      &iovalue, sizeof(iovalue), true);
672 			if (err) {
673 				DHD_ERROR(("%s: error restoring sd_divisor: %d\n",
674 					__func__, err));
675 				return BCME_ERROR;
676 			}
677 		}
678 		bus->clkstate = CLK_SDONLY;
679 	} else {
680 		/* Stop or slow the SD clock itself */
681 		if ((bus->sd_divisor == -1) || (bus->sd_mode == -1)) {
682 			DHD_TRACE(("%s: can't idle clock, divisor %d mode %d\n",
683 				   __func__, bus->sd_divisor, bus->sd_mode));
684 			return BCME_ERROR;
685 		}
686 		if (bus->idleclock == DHD_IDLE_STOP) {
687 			if (sd1idle) {
688 				/* Change to SD1 mode and turn off clock */
689 				iovalue = 1;
690 				err =
691 				    bcmsdh_iovar_op(bus->sdh, "sd_mode", NULL,
692 						    0, &iovalue,
693 						    sizeof(iovalue), true);
694 				if (err) {
695 					DHD_ERROR(("%s: error changing sd_clock: %d\n",
696 						__func__, err));
697 					return BCME_ERROR;
698 				}
699 			}
700 
701 			iovalue = 0;
702 			err = bcmsdh_iovar_op(bus->sdh, "sd_clock", NULL, 0,
703 					      &iovalue, sizeof(iovalue), true);
704 			if (err) {
705 				DHD_ERROR(("%s: error disabling sd_clock: %d\n",
706 					   __func__, err));
707 				return BCME_ERROR;
708 			}
709 		} else if (bus->idleclock != DHD_IDLE_ACTIVE) {
710 			/* Set divisor to idle value */
711 			iovalue = bus->idleclock;
712 			err = bcmsdh_iovar_op(bus->sdh, "sd_divisor", NULL, 0,
713 					      &iovalue, sizeof(iovalue), true);
714 			if (err) {
715 				DHD_ERROR(("%s: error changing sd_divisor: %d\n",
716 					__func__, err));
717 				return BCME_ERROR;
718 			}
719 		}
720 		bus->clkstate = CLK_NONE;
721 	}
722 
723 	return BCME_OK;
724 }
725 
726 /* Transition SD and backplane clock readiness */
dhdsdio_clkctl(dhd_bus_t * bus,uint target,bool pendok)727 static int dhdsdio_clkctl(dhd_bus_t *bus, uint target, bool pendok)
728 {
729 #ifdef DHD_DEBUG
730 	uint oldstate = bus->clkstate;
731 #endif				/* DHD_DEBUG */
732 
733 	DHD_TRACE(("%s: Enter\n", __func__));
734 
735 	/* Early exit if we're already there */
736 	if (bus->clkstate == target) {
737 		if (target == CLK_AVAIL) {
738 			dhd_os_wd_timer(bus->dhd, dhd_watchdog_ms);
739 			bus->activity = true;
740 		}
741 		return BCME_OK;
742 	}
743 
744 	switch (target) {
745 	case CLK_AVAIL:
746 		/* Make sure SD clock is available */
747 		if (bus->clkstate == CLK_NONE)
748 			dhdsdio_sdclk(bus, true);
749 		/* Now request HT Avail on the backplane */
750 		dhdsdio_htclk(bus, true, pendok);
751 		dhd_os_wd_timer(bus->dhd, dhd_watchdog_ms);
752 		bus->activity = true;
753 		break;
754 
755 	case CLK_SDONLY:
756 		/* Remove HT request, or bring up SD clock */
757 		if (bus->clkstate == CLK_NONE)
758 			dhdsdio_sdclk(bus, true);
759 		else if (bus->clkstate == CLK_AVAIL)
760 			dhdsdio_htclk(bus, false, false);
761 		else
762 			DHD_ERROR(("dhdsdio_clkctl: request for %d -> %d\n",
763 				   bus->clkstate, target));
764 		dhd_os_wd_timer(bus->dhd, dhd_watchdog_ms);
765 		break;
766 
767 	case CLK_NONE:
768 		/* Make sure to remove HT request */
769 		if (bus->clkstate == CLK_AVAIL)
770 			dhdsdio_htclk(bus, false, false);
771 		/* Now remove the SD clock */
772 		dhdsdio_sdclk(bus, false);
773 		dhd_os_wd_timer(bus->dhd, 0);
774 		break;
775 	}
776 #ifdef DHD_DEBUG
777 	DHD_INFO(("dhdsdio_clkctl: %d -> %d\n", oldstate, bus->clkstate));
778 #endif				/* DHD_DEBUG */
779 
780 	return BCME_OK;
781 }
782 
dhdsdio_bussleep(dhd_bus_t * bus,bool sleep)783 int dhdsdio_bussleep(dhd_bus_t *bus, bool sleep)
784 {
785 	bcmsdh_info_t *sdh = bus->sdh;
786 	sdpcmd_regs_t *regs = bus->regs;
787 	uint retries = 0;
788 
789 	DHD_INFO(("dhdsdio_bussleep: request %s (currently %s)\n",
790 		  (sleep ? "SLEEP" : "WAKE"),
791 		  (bus->sleeping ? "SLEEP" : "WAKE")));
792 
793 	/* Done if we're already in the requested state */
794 	if (sleep == bus->sleeping)
795 		return BCME_OK;
796 
797 	/* Going to sleep: set the alarm and turn off the lights... */
798 	if (sleep) {
799 		/* Don't sleep if something is pending */
800 		if (bus->dpc_sched || bus->rxskip || pktq_len(&bus->txq))
801 			return BCME_BUSY;
802 
803 		/* Disable SDIO interrupts (no longer interested) */
804 		bcmsdh_intr_disable(bus->sdh);
805 
806 		/* Make sure the controller has the bus up */
807 		dhdsdio_clkctl(bus, CLK_AVAIL, false);
808 
809 		/* Tell device to start using OOB wakeup */
810 		W_SDREG(SMB_USE_OOB, &regs->tosbmailbox, retries);
811 		if (retries > retry_limit)
812 			DHD_ERROR(("CANNOT SIGNAL CHIP, WILL NOT WAKE UP!!\n"));
813 
814 		/* Turn off our contribution to the HT clock request */
815 		dhdsdio_clkctl(bus, CLK_SDONLY, false);
816 
817 		bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR,
818 				 SBSDIO_FORCE_HW_CLKREQ_OFF, NULL);
819 
820 		/* Isolate the bus */
821 		if (bus->sih->chip != BCM4329_CHIP_ID
822 		    && bus->sih->chip != BCM4319_CHIP_ID) {
823 			bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_DEVICE_CTL,
824 					 SBSDIO_DEVCTL_PADS_ISO, NULL);
825 		}
826 
827 		/* Change state */
828 		bus->sleeping = true;
829 
830 	} else {
831 		/* Waking up: bus power up is ok, set local state */
832 
833 		bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR,
834 				 0, NULL);
835 
836 		/* Force pad isolation off if possible
837 			 (in case power never toggled) */
838 		if ((bus->sih->buscoretype == PCMCIA_CORE_ID)
839 		    && (bus->sih->buscorerev >= 10))
840 			bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_DEVICE_CTL, 0,
841 					 NULL);
842 
843 		/* Make sure the controller has the bus up */
844 		dhdsdio_clkctl(bus, CLK_AVAIL, false);
845 
846 		/* Send misc interrupt to indicate OOB not needed */
847 		W_SDREG(0, &regs->tosbmailboxdata, retries);
848 		if (retries <= retry_limit)
849 			W_SDREG(SMB_DEV_INT, &regs->tosbmailbox, retries);
850 
851 		if (retries > retry_limit)
852 			DHD_ERROR(("CANNOT SIGNAL CHIP TO CLEAR OOB!!\n"));
853 
854 		/* Make sure we have SD bus access */
855 		dhdsdio_clkctl(bus, CLK_SDONLY, false);
856 
857 		/* Change state */
858 		bus->sleeping = false;
859 
860 		/* Enable interrupts again */
861 		if (bus->intr && (bus->dhd->busstate == DHD_BUS_DATA)) {
862 			bus->intdis = false;
863 			bcmsdh_intr_enable(bus->sdh);
864 		}
865 	}
866 
867 	return BCME_OK;
868 }
869 
870 #if defined(OOB_INTR_ONLY)
dhd_enable_oob_intr(struct dhd_bus * bus,bool enable)871 void dhd_enable_oob_intr(struct dhd_bus *bus, bool enable)
872 {
873 #if defined(HW_OOB)
874 	bcmsdh_enable_hw_oob_intr(bus->sdh, enable);
875 #else
876 	sdpcmd_regs_t *regs = bus->regs;
877 	uint retries = 0;
878 
879 	dhdsdio_clkctl(bus, CLK_AVAIL, false);
880 	if (enable == true) {
881 
882 		/* Tell device to start using OOB wakeup */
883 		W_SDREG(SMB_USE_OOB, &regs->tosbmailbox, retries);
884 		if (retries > retry_limit)
885 			DHD_ERROR(("CANNOT SIGNAL CHIP, WILL NOT WAKE UP!!\n"));
886 
887 	} else {
888 		/* Send misc interrupt to indicate OOB not needed */
889 		W_SDREG(0, &regs->tosbmailboxdata, retries);
890 		if (retries <= retry_limit)
891 			W_SDREG(SMB_DEV_INT, &regs->tosbmailbox, retries);
892 	}
893 
894 	/* Turn off our contribution to the HT clock request */
895 	dhdsdio_clkctl(bus, CLK_SDONLY, false);
896 #endif				/* !defined(HW_OOB) */
897 }
898 #endif				/* defined(OOB_INTR_ONLY) */
899 
900 #define BUS_WAKE(bus) \
901 	do { \
902 		if ((bus)->sleeping) \
903 			dhdsdio_bussleep((bus), false); \
904 	} while (0);
905 
906 /* Writes a HW/SW header into the packet and sends it. */
907 /* Assumes: (a) header space already there, (b) caller holds lock */
dhdsdio_txpkt(dhd_bus_t * bus,struct sk_buff * pkt,uint chan,bool free_pkt)908 static int dhdsdio_txpkt(dhd_bus_t *bus, struct sk_buff *pkt, uint chan,
909 			 bool free_pkt)
910 {
911 	int ret;
912 	u8 *frame;
913 	u16 len, pad = 0;
914 	u32 swheader;
915 	uint retries = 0;
916 	bcmsdh_info_t *sdh;
917 	struct sk_buff *new;
918 	int i;
919 
920 	DHD_TRACE(("%s: Enter\n", __func__));
921 
922 	sdh = bus->sdh;
923 
924 	if (bus->dhd->dongle_reset) {
925 		ret = BCME_NOTREADY;
926 		goto done;
927 	}
928 
929 	frame = (u8 *) (pkt->data);
930 
931 	/* Add alignment padding, allocate new packet if needed */
932 	pad = ((unsigned long)frame % DHD_SDALIGN);
933 	if (pad) {
934 		if (skb_headroom(pkt) < pad) {
935 			DHD_INFO(("%s: insufficient headroom %d for %d pad\n",
936 				  __func__, skb_headroom(pkt), pad));
937 			bus->dhd->tx_realloc++;
938 			new = pkt_buf_get_skb(pkt->len + DHD_SDALIGN);
939 			if (!new) {
940 				DHD_ERROR(("%s: couldn't allocate new %d-byte "
941 					"packet\n",
942 					__func__, pkt->len + DHD_SDALIGN));
943 				ret = BCME_NOMEM;
944 				goto done;
945 			}
946 
947 			PKTALIGN(new, pkt->len, DHD_SDALIGN);
948 			memcpy(new->data, pkt->data, pkt->len);
949 			if (free_pkt)
950 				pkt_buf_free_skb(pkt);
951 			/* free the pkt if canned one is not used */
952 			free_pkt = true;
953 			pkt = new;
954 			frame = (u8 *) (pkt->data);
955 			ASSERT(((unsigned long)frame % DHD_SDALIGN) == 0);
956 			pad = 0;
957 		} else {
958 			skb_push(pkt, pad);
959 			frame = (u8 *) (pkt->data);
960 
961 			ASSERT((pad + SDPCM_HDRLEN) <= (int)(pkt->len));
962 			memset(frame, 0, pad + SDPCM_HDRLEN);
963 		}
964 	}
965 	ASSERT(pad < DHD_SDALIGN);
966 
967 	/* Hardware tag: 2 byte len followed by 2 byte ~len check (all LE) */
968 	len = (u16) (pkt->len);
969 	*(u16 *) frame = cpu_to_le16(len);
970 	*(((u16 *) frame) + 1) = cpu_to_le16(~len);
971 
972 	/* Software tag: channel, sequence number, data offset */
973 	swheader =
974 	    ((chan << SDPCM_CHANNEL_SHIFT) & SDPCM_CHANNEL_MASK) | bus->tx_seq |
975 	    (((pad +
976 	       SDPCM_HDRLEN) << SDPCM_DOFFSET_SHIFT) & SDPCM_DOFFSET_MASK);
977 
978 	put_unaligned_le32(swheader, frame + SDPCM_FRAMETAG_LEN);
979 	put_unaligned_le32(0, frame + SDPCM_FRAMETAG_LEN + sizeof(swheader));
980 
981 #ifdef DHD_DEBUG
982 	tx_packets[pkt->priority]++;
983 	if (DHD_BYTES_ON() &&
984 	    (((DHD_CTL_ON() && (chan == SDPCM_CONTROL_CHANNEL)) ||
985 	      (DHD_DATA_ON() && (chan != SDPCM_CONTROL_CHANNEL))))) {
986 		prhex("Tx Frame", frame, len);
987 	} else if (DHD_HDRS_ON()) {
988 		prhex("TxHdr", frame, min_t(u16, len, 16));
989 	}
990 #endif
991 
992 	/* Raise len to next SDIO block to eliminate tail command */
993 	if (bus->roundup && bus->blocksize && (len > bus->blocksize)) {
994 		u16 pad = bus->blocksize - (len % bus->blocksize);
995 		if ((pad <= bus->roundup) && (pad < bus->blocksize))
996 #ifdef NOTUSED
997 			if (pad <= skb_tailroom(pkt))
998 #endif				/* NOTUSED */
999 				len += pad;
1000 	} else if (len % DHD_SDALIGN) {
1001 		len += DHD_SDALIGN - (len % DHD_SDALIGN);
1002 	}
1003 
1004 	/* Some controllers have trouble with odd bytes -- round to even */
1005 	if (forcealign && (len & (ALIGNMENT - 1))) {
1006 #ifdef NOTUSED
1007 		if (skb_tailroom(pkt))
1008 #endif
1009 			len = roundup(len, ALIGNMENT);
1010 #ifdef NOTUSED
1011 		else
1012 			DHD_ERROR(("%s: sending unrounded %d-byte packet\n",
1013 				   __func__, len));
1014 #endif
1015 	}
1016 
1017 	do {
1018 		ret =
1019 		    dhd_bcmsdh_send_buf(bus, bcmsdh_cur_sbwad(sdh), SDIO_FUNC_2,
1020 					F2SYNC, frame, len, pkt, NULL, NULL);
1021 		bus->f2txdata++;
1022 		ASSERT(ret != BCME_PENDING);
1023 
1024 		if (ret < 0) {
1025 			/* On failure, abort the command
1026 			 and terminate the frame */
1027 			DHD_INFO(("%s: sdio error %d, abort command and "
1028 				"terminate frame.\n", __func__, ret));
1029 			bus->tx_sderrs++;
1030 
1031 			bcmsdh_abort(sdh, SDIO_FUNC_2);
1032 			bcmsdh_cfg_write(sdh, SDIO_FUNC_1,
1033 					 SBSDIO_FUNC1_FRAMECTRL, SFC_WF_TERM,
1034 					 NULL);
1035 			bus->f1regdata++;
1036 
1037 			for (i = 0; i < 3; i++) {
1038 				u8 hi, lo;
1039 				hi = bcmsdh_cfg_read(sdh, SDIO_FUNC_1,
1040 						     SBSDIO_FUNC1_WFRAMEBCHI,
1041 						     NULL);
1042 				lo = bcmsdh_cfg_read(sdh, SDIO_FUNC_1,
1043 						     SBSDIO_FUNC1_WFRAMEBCLO,
1044 						     NULL);
1045 				bus->f1regdata += 2;
1046 				if ((hi == 0) && (lo == 0))
1047 					break;
1048 			}
1049 
1050 		}
1051 		if (ret == 0)
1052 			bus->tx_seq = (bus->tx_seq + 1) % SDPCM_SEQUENCE_WRAP;
1053 
1054 	} while ((ret < 0) && retrydata && retries++ < TXRETRIES);
1055 
1056 done:
1057 	/* restore pkt buffer pointer before calling tx complete routine */
1058 	skb_pull(pkt, SDPCM_HDRLEN + pad);
1059 	dhd_os_sdunlock(bus->dhd);
1060 	dhd_txcomplete(bus->dhd, pkt, ret != 0);
1061 	dhd_os_sdlock(bus->dhd);
1062 
1063 	if (free_pkt)
1064 		pkt_buf_free_skb(pkt);
1065 
1066 	return ret;
1067 }
1068 
dhd_bus_txdata(struct dhd_bus * bus,struct sk_buff * pkt)1069 int dhd_bus_txdata(struct dhd_bus *bus, struct sk_buff *pkt)
1070 {
1071 	int ret = BCME_ERROR;
1072 	uint datalen, prec;
1073 
1074 	DHD_TRACE(("%s: Enter\n", __func__));
1075 
1076 	datalen = pkt->len;
1077 
1078 #ifdef SDTEST
1079 	/* Push the test header if doing loopback */
1080 	if (bus->ext_loop) {
1081 		u8 *data;
1082 		skb_push(pkt, SDPCM_TEST_HDRLEN);
1083 		data = pkt->data;
1084 		*data++ = SDPCM_TEST_ECHOREQ;
1085 		*data++ = (u8) bus->loopid++;
1086 		*data++ = (datalen >> 0);
1087 		*data++ = (datalen >> 8);
1088 		datalen += SDPCM_TEST_HDRLEN;
1089 	}
1090 #endif				/* SDTEST */
1091 
1092 	/* Add space for the header */
1093 	skb_push(pkt, SDPCM_HDRLEN);
1094 	ASSERT(IS_ALIGNED((unsigned long)(pkt->data), 2));
1095 
1096 	prec = PRIO2PREC((pkt->priority & PRIOMASK));
1097 
1098 	/* Check for existing queue, current flow-control,
1099 			 pending event, or pending clock */
1100 	if (dhd_deferred_tx || bus->fcstate || pktq_len(&bus->txq)
1101 	    || bus->dpc_sched || (!DATAOK(bus))
1102 	    || (bus->flowcontrol & NBITVAL(prec))
1103 	    || (bus->clkstate != CLK_AVAIL)) {
1104 		DHD_TRACE(("%s: deferring pktq len %d\n", __func__,
1105 			   pktq_len(&bus->txq)));
1106 		bus->fcqueued++;
1107 
1108 		/* Priority based enq */
1109 		dhd_os_sdlock_txq(bus->dhd);
1110 		if (dhd_prec_enq(bus->dhd, &bus->txq, pkt, prec) == false) {
1111 			skb_pull(pkt, SDPCM_HDRLEN);
1112 			dhd_txcomplete(bus->dhd, pkt, false);
1113 			pkt_buf_free_skb(pkt);
1114 			DHD_ERROR(("%s: out of bus->txq !!!\n", __func__));
1115 			ret = BCME_NORESOURCE;
1116 		} else {
1117 			ret = BCME_OK;
1118 		}
1119 		dhd_os_sdunlock_txq(bus->dhd);
1120 
1121 		if (pktq_len(&bus->txq) >= TXHI)
1122 			dhd_txflowcontrol(bus->dhd, 0, ON);
1123 
1124 #ifdef DHD_DEBUG
1125 		if (pktq_plen(&bus->txq, prec) > qcount[prec])
1126 			qcount[prec] = pktq_plen(&bus->txq, prec);
1127 #endif
1128 		/* Schedule DPC if needed to send queued packet(s) */
1129 		if (dhd_deferred_tx && !bus->dpc_sched) {
1130 			bus->dpc_sched = true;
1131 			dhd_sched_dpc(bus->dhd);
1132 		}
1133 	} else {
1134 		/* Lock: we're about to use shared data/code (and SDIO) */
1135 		dhd_os_sdlock(bus->dhd);
1136 
1137 		/* Otherwise, send it now */
1138 		BUS_WAKE(bus);
1139 		/* Make sure back plane ht clk is on, no pending allowed */
1140 		dhdsdio_clkctl(bus, CLK_AVAIL, true);
1141 
1142 #ifndef SDTEST
1143 		DHD_TRACE(("%s: calling txpkt\n", __func__));
1144 		ret = dhdsdio_txpkt(bus, pkt, SDPCM_DATA_CHANNEL, true);
1145 #else
1146 		ret = dhdsdio_txpkt(bus, pkt,
1147 				    (bus->ext_loop ? SDPCM_TEST_CHANNEL :
1148 				     SDPCM_DATA_CHANNEL), true);
1149 #endif
1150 		if (ret)
1151 			bus->dhd->tx_errors++;
1152 		else
1153 			bus->dhd->dstats.tx_bytes += datalen;
1154 
1155 		if ((bus->idletime == DHD_IDLE_IMMEDIATE) && !bus->dpc_sched) {
1156 			bus->activity = false;
1157 			dhdsdio_clkctl(bus, CLK_NONE, true);
1158 		}
1159 
1160 		dhd_os_sdunlock(bus->dhd);
1161 	}
1162 
1163 	return ret;
1164 }
1165 
dhdsdio_sendfromq(dhd_bus_t * bus,uint maxframes)1166 static uint dhdsdio_sendfromq(dhd_bus_t *bus, uint maxframes)
1167 {
1168 	struct sk_buff *pkt;
1169 	u32 intstatus = 0;
1170 	uint retries = 0;
1171 	int ret = 0, prec_out;
1172 	uint cnt = 0;
1173 	uint datalen;
1174 	u8 tx_prec_map;
1175 
1176 	dhd_pub_t *dhd = bus->dhd;
1177 	sdpcmd_regs_t *regs = bus->regs;
1178 
1179 	DHD_TRACE(("%s: Enter\n", __func__));
1180 
1181 	tx_prec_map = ~bus->flowcontrol;
1182 
1183 	/* Send frames until the limit or some other event */
1184 	for (cnt = 0; (cnt < maxframes) && DATAOK(bus); cnt++) {
1185 		dhd_os_sdlock_txq(bus->dhd);
1186 		pkt = pktq_mdeq(&bus->txq, tx_prec_map, &prec_out);
1187 		if (pkt == NULL) {
1188 			dhd_os_sdunlock_txq(bus->dhd);
1189 			break;
1190 		}
1191 		dhd_os_sdunlock_txq(bus->dhd);
1192 		datalen = pkt->len - SDPCM_HDRLEN;
1193 
1194 #ifndef SDTEST
1195 		ret = dhdsdio_txpkt(bus, pkt, SDPCM_DATA_CHANNEL, true);
1196 #else
1197 		ret = dhdsdio_txpkt(bus, pkt,
1198 				    (bus->ext_loop ? SDPCM_TEST_CHANNEL :
1199 				     SDPCM_DATA_CHANNEL), true);
1200 #endif
1201 		if (ret)
1202 			bus->dhd->tx_errors++;
1203 		else
1204 			bus->dhd->dstats.tx_bytes += datalen;
1205 
1206 		/* In poll mode, need to check for other events */
1207 		if (!bus->intr && cnt) {
1208 			/* Check device status, signal pending interrupt */
1209 			R_SDREG(intstatus, &regs->intstatus, retries);
1210 			bus->f2txdata++;
1211 			if (bcmsdh_regfail(bus->sdh))
1212 				break;
1213 			if (intstatus & bus->hostintmask)
1214 				bus->ipend = true;
1215 		}
1216 	}
1217 
1218 	/* Deflow-control stack if needed */
1219 	if (dhd->up && (dhd->busstate == DHD_BUS_DATA) &&
1220 	    dhd->txoff && (pktq_len(&bus->txq) < TXLOW))
1221 		dhd_txflowcontrol(dhd, 0, OFF);
1222 
1223 	return cnt;
1224 }
1225 
dhd_bus_txctl(struct dhd_bus * bus,unsigned char * msg,uint msglen)1226 int dhd_bus_txctl(struct dhd_bus *bus, unsigned char *msg, uint msglen)
1227 {
1228 	u8 *frame;
1229 	u16 len;
1230 	u32 swheader;
1231 	uint retries = 0;
1232 	bcmsdh_info_t *sdh = bus->sdh;
1233 	u8 doff = 0;
1234 	int ret = -1;
1235 	int i;
1236 
1237 	DHD_TRACE(("%s: Enter\n", __func__));
1238 
1239 	if (bus->dhd->dongle_reset)
1240 		return -EIO;
1241 
1242 	/* Back the pointer to make a room for bus header */
1243 	frame = msg - SDPCM_HDRLEN;
1244 	len = (msglen += SDPCM_HDRLEN);
1245 
1246 	/* Add alignment padding (optional for ctl frames) */
1247 	if (dhd_alignctl) {
1248 		doff = ((unsigned long)frame % DHD_SDALIGN);
1249 		if (doff) {
1250 			frame -= doff;
1251 			len += doff;
1252 			msglen += doff;
1253 			memset(frame, 0, doff + SDPCM_HDRLEN);
1254 		}
1255 		ASSERT(doff < DHD_SDALIGN);
1256 	}
1257 	doff += SDPCM_HDRLEN;
1258 
1259 	/* Round send length to next SDIO block */
1260 	if (bus->roundup && bus->blocksize && (len > bus->blocksize)) {
1261 		u16 pad = bus->blocksize - (len % bus->blocksize);
1262 		if ((pad <= bus->roundup) && (pad < bus->blocksize))
1263 			len += pad;
1264 	} else if (len % DHD_SDALIGN) {
1265 		len += DHD_SDALIGN - (len % DHD_SDALIGN);
1266 	}
1267 
1268 	/* Satisfy length-alignment requirements */
1269 	if (forcealign && (len & (ALIGNMENT - 1)))
1270 		len = roundup(len, ALIGNMENT);
1271 
1272 	ASSERT(IS_ALIGNED((unsigned long)frame, 2));
1273 
1274 	/* Need to lock here to protect txseq and SDIO tx calls */
1275 	dhd_os_sdlock(bus->dhd);
1276 
1277 	BUS_WAKE(bus);
1278 
1279 	/* Make sure backplane clock is on */
1280 	dhdsdio_clkctl(bus, CLK_AVAIL, false);
1281 
1282 	/* Hardware tag: 2 byte len followed by 2 byte ~len check (all LE) */
1283 	*(u16 *) frame = cpu_to_le16((u16) msglen);
1284 	*(((u16 *) frame) + 1) = cpu_to_le16(~msglen);
1285 
1286 	/* Software tag: channel, sequence number, data offset */
1287 	swheader =
1288 	    ((SDPCM_CONTROL_CHANNEL << SDPCM_CHANNEL_SHIFT) &
1289 	     SDPCM_CHANNEL_MASK)
1290 	    | bus->tx_seq | ((doff << SDPCM_DOFFSET_SHIFT) &
1291 			     SDPCM_DOFFSET_MASK);
1292 	put_unaligned_le32(swheader, frame + SDPCM_FRAMETAG_LEN);
1293 	put_unaligned_le32(0, frame + SDPCM_FRAMETAG_LEN + sizeof(swheader));
1294 
1295 	if (!DATAOK(bus)) {
1296 		DHD_INFO(("%s: No bus credit bus->tx_max %d, bus->tx_seq %d\n",
1297 			  __func__, bus->tx_max, bus->tx_seq));
1298 		bus->ctrl_frame_stat = true;
1299 		/* Send from dpc */
1300 		bus->ctrl_frame_buf = frame;
1301 		bus->ctrl_frame_len = len;
1302 
1303 		dhd_wait_for_event(bus->dhd, &bus->ctrl_frame_stat);
1304 
1305 		if (bus->ctrl_frame_stat == false) {
1306 			DHD_INFO(("%s: ctrl_frame_stat == false\n", __func__));
1307 			ret = 0;
1308 		} else {
1309 			DHD_INFO(("%s: ctrl_frame_stat == true\n", __func__));
1310 			ret = -1;
1311 		}
1312 	}
1313 
1314 	if (ret == -1) {
1315 #ifdef DHD_DEBUG
1316 		if (DHD_BYTES_ON() && DHD_CTL_ON())
1317 			prhex("Tx Frame", frame, len);
1318 		else if (DHD_HDRS_ON())
1319 			prhex("TxHdr", frame, min_t(u16, len, 16));
1320 #endif
1321 
1322 		do {
1323 			bus->ctrl_frame_stat = false;
1324 			ret =
1325 			    dhd_bcmsdh_send_buf(bus, bcmsdh_cur_sbwad(sdh),
1326 						SDIO_FUNC_2, F2SYNC, frame, len,
1327 						NULL, NULL, NULL);
1328 
1329 			ASSERT(ret != BCME_PENDING);
1330 
1331 			if (ret < 0) {
1332 				/* On failure, abort the command and
1333 				 terminate the frame */
1334 				DHD_INFO(("%s: sdio error %d, abort command and terminate frame.\n",
1335 					__func__, ret));
1336 				bus->tx_sderrs++;
1337 
1338 				bcmsdh_abort(sdh, SDIO_FUNC_2);
1339 
1340 				bcmsdh_cfg_write(sdh, SDIO_FUNC_1,
1341 						 SBSDIO_FUNC1_FRAMECTRL,
1342 						 SFC_WF_TERM, NULL);
1343 				bus->f1regdata++;
1344 
1345 				for (i = 0; i < 3; i++) {
1346 					u8 hi, lo;
1347 					hi = bcmsdh_cfg_read(sdh, SDIO_FUNC_1,
1348 					     SBSDIO_FUNC1_WFRAMEBCHI,
1349 					     NULL);
1350 					lo = bcmsdh_cfg_read(sdh, SDIO_FUNC_1,
1351 					     SBSDIO_FUNC1_WFRAMEBCLO,
1352 							     NULL);
1353 					bus->f1regdata += 2;
1354 					if ((hi == 0) && (lo == 0))
1355 						break;
1356 				}
1357 
1358 			}
1359 			if (ret == 0) {
1360 				bus->tx_seq =
1361 				    (bus->tx_seq + 1) % SDPCM_SEQUENCE_WRAP;
1362 			}
1363 		} while ((ret < 0) && retries++ < TXRETRIES);
1364 	}
1365 
1366 	if ((bus->idletime == DHD_IDLE_IMMEDIATE) && !bus->dpc_sched) {
1367 		bus->activity = false;
1368 		dhdsdio_clkctl(bus, CLK_NONE, true);
1369 	}
1370 
1371 	dhd_os_sdunlock(bus->dhd);
1372 
1373 	if (ret)
1374 		bus->dhd->tx_ctlerrs++;
1375 	else
1376 		bus->dhd->tx_ctlpkts++;
1377 
1378 	return ret ? -EIO : 0;
1379 }
1380 
dhd_bus_rxctl(struct dhd_bus * bus,unsigned char * msg,uint msglen)1381 int dhd_bus_rxctl(struct dhd_bus *bus, unsigned char *msg, uint msglen)
1382 {
1383 	int timeleft;
1384 	uint rxlen = 0;
1385 	bool pending;
1386 
1387 	DHD_TRACE(("%s: Enter\n", __func__));
1388 
1389 	if (bus->dhd->dongle_reset)
1390 		return -EIO;
1391 
1392 	/* Wait until control frame is available */
1393 	timeleft = dhd_os_ioctl_resp_wait(bus->dhd, &bus->rxlen, &pending);
1394 
1395 	dhd_os_sdlock(bus->dhd);
1396 	rxlen = bus->rxlen;
1397 	memcpy(msg, bus->rxctl, min(msglen, rxlen));
1398 	bus->rxlen = 0;
1399 	dhd_os_sdunlock(bus->dhd);
1400 
1401 	if (rxlen) {
1402 		DHD_CTL(("%s: resumed on rxctl frame, got %d expected %d\n",
1403 			 __func__, rxlen, msglen));
1404 	} else if (timeleft == 0) {
1405 		DHD_ERROR(("%s: resumed on timeout\n", __func__));
1406 #ifdef DHD_DEBUG
1407 		dhd_os_sdlock(bus->dhd);
1408 		dhdsdio_checkdied(bus, NULL, 0);
1409 		dhd_os_sdunlock(bus->dhd);
1410 #endif				/* DHD_DEBUG */
1411 	} else if (pending == true) {
1412 		DHD_CTL(("%s: cancelled\n", __func__));
1413 		return -ERESTARTSYS;
1414 	} else {
1415 		DHD_CTL(("%s: resumed for unknown reason?\n", __func__));
1416 #ifdef DHD_DEBUG
1417 		dhd_os_sdlock(bus->dhd);
1418 		dhdsdio_checkdied(bus, NULL, 0);
1419 		dhd_os_sdunlock(bus->dhd);
1420 #endif				/* DHD_DEBUG */
1421 	}
1422 
1423 	if (rxlen)
1424 		bus->dhd->rx_ctlpkts++;
1425 	else
1426 		bus->dhd->rx_ctlerrs++;
1427 
1428 	return rxlen ? (int)rxlen : -ETIMEDOUT;
1429 }
1430 
1431 /* IOVar table */
1432 enum {
1433 	IOV_INTR = 1,
1434 	IOV_POLLRATE,
1435 	IOV_SDREG,
1436 	IOV_SBREG,
1437 	IOV_SDCIS,
1438 	IOV_MEMBYTES,
1439 	IOV_MEMSIZE,
1440 #ifdef DHD_DEBUG
1441 	IOV_CHECKDIED,
1442 #endif
1443 	IOV_DOWNLOAD,
1444 	IOV_FORCEEVEN,
1445 	IOV_SDIOD_DRIVE,
1446 	IOV_READAHEAD,
1447 	IOV_SDRXCHAIN,
1448 	IOV_ALIGNCTL,
1449 	IOV_SDALIGN,
1450 	IOV_DEVRESET,
1451 	IOV_CPU,
1452 #ifdef SDTEST
1453 	IOV_PKTGEN,
1454 	IOV_EXTLOOP,
1455 #endif				/* SDTEST */
1456 	IOV_SPROM,
1457 	IOV_TXBOUND,
1458 	IOV_RXBOUND,
1459 	IOV_TXMINMAX,
1460 	IOV_IDLETIME,
1461 	IOV_IDLECLOCK,
1462 	IOV_SD1IDLE,
1463 	IOV_SLEEP,
1464 	IOV_VARS
1465 };
1466 
1467 const bcm_iovar_t dhdsdio_iovars[] = {
1468 	{"intr", IOV_INTR, 0, IOVT_BOOL, 0},
1469 	{"sleep", IOV_SLEEP, 0, IOVT_BOOL, 0},
1470 	{"pollrate", IOV_POLLRATE, 0, IOVT_UINT32, 0},
1471 	{"idletime", IOV_IDLETIME, 0, IOVT_INT32, 0},
1472 	{"idleclock", IOV_IDLECLOCK, 0, IOVT_INT32, 0},
1473 	{"sd1idle", IOV_SD1IDLE, 0, IOVT_BOOL, 0},
1474 	{"membytes", IOV_MEMBYTES, 0, IOVT_BUFFER, 2 * sizeof(int)},
1475 	{"memsize", IOV_MEMSIZE, 0, IOVT_UINT32, 0},
1476 	{"download", IOV_DOWNLOAD, 0, IOVT_BOOL, 0},
1477 	{"vars", IOV_VARS, 0, IOVT_BUFFER, 0},
1478 	{"sdiod_drive", IOV_SDIOD_DRIVE, 0, IOVT_UINT32, 0},
1479 	{"readahead", IOV_READAHEAD, 0, IOVT_BOOL, 0},
1480 	{"sdrxchain", IOV_SDRXCHAIN, 0, IOVT_BOOL, 0},
1481 	{"alignctl", IOV_ALIGNCTL, 0, IOVT_BOOL, 0},
1482 	{"sdalign", IOV_SDALIGN, 0, IOVT_BOOL, 0},
1483 	{"devreset", IOV_DEVRESET, 0, IOVT_BOOL, 0},
1484 #ifdef DHD_DEBUG
1485 	{"sdreg", IOV_SDREG, 0, IOVT_BUFFER, sizeof(sdreg_t)}
1486 	,
1487 	{"sbreg", IOV_SBREG, 0, IOVT_BUFFER, sizeof(sdreg_t)}
1488 	,
1489 	{"sd_cis", IOV_SDCIS, 0, IOVT_BUFFER, DHD_IOCTL_MAXLEN}
1490 	,
1491 	{"forcealign", IOV_FORCEEVEN, 0, IOVT_BOOL, 0}
1492 	,
1493 	{"txbound", IOV_TXBOUND, 0, IOVT_UINT32, 0}
1494 	,
1495 	{"rxbound", IOV_RXBOUND, 0, IOVT_UINT32, 0}
1496 	,
1497 	{"txminmax", IOV_TXMINMAX, 0, IOVT_UINT32, 0}
1498 	,
1499 	{"cpu", IOV_CPU, 0, IOVT_BOOL, 0}
1500 	,
1501 #ifdef DHD_DEBUG
1502 	{"checkdied", IOV_CHECKDIED, 0, IOVT_BUFFER, 0}
1503 	,
1504 #endif				/* DHD_DEBUG  */
1505 #endif				/* DHD_DEBUG */
1506 #ifdef SDTEST
1507 	{"extloop", IOV_EXTLOOP, 0, IOVT_BOOL, 0}
1508 	,
1509 	{"pktgen", IOV_PKTGEN, 0, IOVT_BUFFER, sizeof(dhd_pktgen_t)}
1510 	,
1511 #endif				/* SDTEST */
1512 
1513 	{NULL, 0, 0, 0, 0}
1514 };
1515 
1516 static void
dhd_dump_pct(struct bcmstrbuf * strbuf,char * desc,uint num,uint div)1517 dhd_dump_pct(struct bcmstrbuf *strbuf, char *desc, uint num, uint div)
1518 {
1519 	uint q1, q2;
1520 
1521 	if (!div) {
1522 		bcm_bprintf(strbuf, "%s N/A", desc);
1523 	} else {
1524 		q1 = num / div;
1525 		q2 = (100 * (num - (q1 * div))) / div;
1526 		bcm_bprintf(strbuf, "%s %d.%02d", desc, q1, q2);
1527 	}
1528 }
1529 
dhd_bus_dump(dhd_pub_t * dhdp,struct bcmstrbuf * strbuf)1530 void dhd_bus_dump(dhd_pub_t *dhdp, struct bcmstrbuf *strbuf)
1531 {
1532 	dhd_bus_t *bus = dhdp->bus;
1533 
1534 	bcm_bprintf(strbuf, "Bus SDIO structure:\n");
1535 	bcm_bprintf(strbuf,
1536 		    "hostintmask 0x%08x intstatus 0x%08x sdpcm_ver %d\n",
1537 		    bus->hostintmask, bus->intstatus, bus->sdpcm_ver);
1538 	bcm_bprintf(strbuf,
1539 		    "fcstate %d qlen %d tx_seq %d, max %d, rxskip %d rxlen %d rx_seq %d\n",
1540 		    bus->fcstate, pktq_len(&bus->txq), bus->tx_seq, bus->tx_max,
1541 		    bus->rxskip, bus->rxlen, bus->rx_seq);
1542 	bcm_bprintf(strbuf, "intr %d intrcount %d lastintrs %d spurious %d\n",
1543 		    bus->intr, bus->intrcount, bus->lastintrs, bus->spurious);
1544 	bcm_bprintf(strbuf, "pollrate %d pollcnt %d regfails %d\n",
1545 		    bus->pollrate, bus->pollcnt, bus->regfails);
1546 
1547 	bcm_bprintf(strbuf, "\nAdditional counters:\n");
1548 	bcm_bprintf(strbuf,
1549 		    "tx_sderrs %d fcqueued %d rxrtx %d rx_toolong %d rxc_errors %d\n",
1550 		    bus->tx_sderrs, bus->fcqueued, bus->rxrtx, bus->rx_toolong,
1551 		    bus->rxc_errors);
1552 	bcm_bprintf(strbuf, "rx_hdrfail %d badhdr %d badseq %d\n",
1553 		    bus->rx_hdrfail, bus->rx_badhdr, bus->rx_badseq);
1554 	bcm_bprintf(strbuf, "fc_rcvd %d, fc_xoff %d, fc_xon %d\n", bus->fc_rcvd,
1555 		    bus->fc_xoff, bus->fc_xon);
1556 	bcm_bprintf(strbuf, "rxglomfail %d, rxglomframes %d, rxglompkts %d\n",
1557 		    bus->rxglomfail, bus->rxglomframes, bus->rxglompkts);
1558 	bcm_bprintf(strbuf, "f2rx (hdrs/data) %d (%d/%d), f2tx %d f1regs %d\n",
1559 		    (bus->f2rxhdrs + bus->f2rxdata), bus->f2rxhdrs,
1560 		    bus->f2rxdata, bus->f2txdata, bus->f1regdata);
1561 	{
1562 		dhd_dump_pct(strbuf, "\nRx: pkts/f2rd", bus->dhd->rx_packets,
1563 			     (bus->f2rxhdrs + bus->f2rxdata));
1564 		dhd_dump_pct(strbuf, ", pkts/f1sd", bus->dhd->rx_packets,
1565 			     bus->f1regdata);
1566 		dhd_dump_pct(strbuf, ", pkts/sd", bus->dhd->rx_packets,
1567 			     (bus->f2rxhdrs + bus->f2rxdata + bus->f1regdata));
1568 		dhd_dump_pct(strbuf, ", pkts/int", bus->dhd->rx_packets,
1569 			     bus->intrcount);
1570 		bcm_bprintf(strbuf, "\n");
1571 
1572 		dhd_dump_pct(strbuf, "Rx: glom pct", (100 * bus->rxglompkts),
1573 			     bus->dhd->rx_packets);
1574 		dhd_dump_pct(strbuf, ", pkts/glom", bus->rxglompkts,
1575 			     bus->rxglomframes);
1576 		bcm_bprintf(strbuf, "\n");
1577 
1578 		dhd_dump_pct(strbuf, "Tx: pkts/f2wr", bus->dhd->tx_packets,
1579 			     bus->f2txdata);
1580 		dhd_dump_pct(strbuf, ", pkts/f1sd", bus->dhd->tx_packets,
1581 			     bus->f1regdata);
1582 		dhd_dump_pct(strbuf, ", pkts/sd", bus->dhd->tx_packets,
1583 			     (bus->f2txdata + bus->f1regdata));
1584 		dhd_dump_pct(strbuf, ", pkts/int", bus->dhd->tx_packets,
1585 			     bus->intrcount);
1586 		bcm_bprintf(strbuf, "\n");
1587 
1588 		dhd_dump_pct(strbuf, "Total: pkts/f2rw",
1589 			     (bus->dhd->tx_packets + bus->dhd->rx_packets),
1590 			     (bus->f2txdata + bus->f2rxhdrs + bus->f2rxdata));
1591 		dhd_dump_pct(strbuf, ", pkts/f1sd",
1592 			     (bus->dhd->tx_packets + bus->dhd->rx_packets),
1593 			     bus->f1regdata);
1594 		dhd_dump_pct(strbuf, ", pkts/sd",
1595 			     (bus->dhd->tx_packets + bus->dhd->rx_packets),
1596 			     (bus->f2txdata + bus->f2rxhdrs + bus->f2rxdata +
1597 			      bus->f1regdata));
1598 		dhd_dump_pct(strbuf, ", pkts/int",
1599 			     (bus->dhd->tx_packets + bus->dhd->rx_packets),
1600 			     bus->intrcount);
1601 		bcm_bprintf(strbuf, "\n\n");
1602 	}
1603 
1604 #ifdef SDTEST
1605 	if (bus->pktgen_count) {
1606 		bcm_bprintf(strbuf, "pktgen config and count:\n");
1607 		bcm_bprintf(strbuf,
1608 			    "freq %d count %d print %d total %d min %d len %d\n",
1609 			    bus->pktgen_freq, bus->pktgen_count,
1610 			    bus->pktgen_print, bus->pktgen_total,
1611 			    bus->pktgen_minlen, bus->pktgen_maxlen);
1612 		bcm_bprintf(strbuf, "send attempts %d rcvd %d fail %d\n",
1613 			    bus->pktgen_sent, bus->pktgen_rcvd,
1614 			    bus->pktgen_fail);
1615 	}
1616 #endif				/* SDTEST */
1617 #ifdef DHD_DEBUG
1618 	bcm_bprintf(strbuf, "dpc_sched %d host interrupt%spending\n",
1619 		    bus->dpc_sched,
1620 		    (bcmsdh_intr_pending(bus->sdh) ? " " : " not "));
1621 	bcm_bprintf(strbuf, "blocksize %d roundup %d\n", bus->blocksize,
1622 		    bus->roundup);
1623 #endif				/* DHD_DEBUG */
1624 	bcm_bprintf(strbuf,
1625 		    "clkstate %d activity %d idletime %d idlecount %d sleeping %d\n",
1626 		    bus->clkstate, bus->activity, bus->idletime, bus->idlecount,
1627 		    bus->sleeping);
1628 }
1629 
dhd_bus_clearcounts(dhd_pub_t * dhdp)1630 void dhd_bus_clearcounts(dhd_pub_t *dhdp)
1631 {
1632 	dhd_bus_t *bus = (dhd_bus_t *) dhdp->bus;
1633 
1634 	bus->intrcount = bus->lastintrs = bus->spurious = bus->regfails = 0;
1635 	bus->rxrtx = bus->rx_toolong = bus->rxc_errors = 0;
1636 	bus->rx_hdrfail = bus->rx_badhdr = bus->rx_badseq = 0;
1637 	bus->tx_sderrs = bus->fc_rcvd = bus->fc_xoff = bus->fc_xon = 0;
1638 	bus->rxglomfail = bus->rxglomframes = bus->rxglompkts = 0;
1639 	bus->f2rxhdrs = bus->f2rxdata = bus->f2txdata = bus->f1regdata = 0;
1640 }
1641 
1642 #ifdef SDTEST
dhdsdio_pktgen_get(dhd_bus_t * bus,u8 * arg)1643 static int dhdsdio_pktgen_get(dhd_bus_t *bus, u8 *arg)
1644 {
1645 	dhd_pktgen_t pktgen;
1646 
1647 	pktgen.version = DHD_PKTGEN_VERSION;
1648 	pktgen.freq = bus->pktgen_freq;
1649 	pktgen.count = bus->pktgen_count;
1650 	pktgen.print = bus->pktgen_print;
1651 	pktgen.total = bus->pktgen_total;
1652 	pktgen.minlen = bus->pktgen_minlen;
1653 	pktgen.maxlen = bus->pktgen_maxlen;
1654 	pktgen.numsent = bus->pktgen_sent;
1655 	pktgen.numrcvd = bus->pktgen_rcvd;
1656 	pktgen.numfail = bus->pktgen_fail;
1657 	pktgen.mode = bus->pktgen_mode;
1658 	pktgen.stop = bus->pktgen_stop;
1659 
1660 	memcpy(arg, &pktgen, sizeof(pktgen));
1661 
1662 	return 0;
1663 }
1664 
dhdsdio_pktgen_set(dhd_bus_t * bus,u8 * arg)1665 static int dhdsdio_pktgen_set(dhd_bus_t *bus, u8 *arg)
1666 {
1667 	dhd_pktgen_t pktgen;
1668 	uint oldcnt, oldmode;
1669 
1670 	memcpy(&pktgen, arg, sizeof(pktgen));
1671 	if (pktgen.version != DHD_PKTGEN_VERSION)
1672 		return BCME_BADARG;
1673 
1674 	oldcnt = bus->pktgen_count;
1675 	oldmode = bus->pktgen_mode;
1676 
1677 	bus->pktgen_freq = pktgen.freq;
1678 	bus->pktgen_count = pktgen.count;
1679 	bus->pktgen_print = pktgen.print;
1680 	bus->pktgen_total = pktgen.total;
1681 	bus->pktgen_minlen = pktgen.minlen;
1682 	bus->pktgen_maxlen = pktgen.maxlen;
1683 	bus->pktgen_mode = pktgen.mode;
1684 	bus->pktgen_stop = pktgen.stop;
1685 
1686 	bus->pktgen_tick = bus->pktgen_ptick = 0;
1687 	bus->pktgen_len = max(bus->pktgen_len, bus->pktgen_minlen);
1688 	bus->pktgen_len = min(bus->pktgen_len, bus->pktgen_maxlen);
1689 
1690 	/* Clear counts for a new pktgen (mode change, or was stopped) */
1691 	if (bus->pktgen_count && (!oldcnt || oldmode != bus->pktgen_mode))
1692 		bus->pktgen_sent = bus->pktgen_rcvd = bus->pktgen_fail = 0;
1693 
1694 	return 0;
1695 }
1696 #endif				/* SDTEST */
1697 
1698 static int
dhdsdio_membytes(dhd_bus_t * bus,bool write,u32 address,u8 * data,uint size)1699 dhdsdio_membytes(dhd_bus_t *bus, bool write, u32 address, u8 *data,
1700 		 uint size)
1701 {
1702 	int bcmerror = 0;
1703 	u32 sdaddr;
1704 	uint dsize;
1705 
1706 	/* Determine initial transfer parameters */
1707 	sdaddr = address & SBSDIO_SB_OFT_ADDR_MASK;
1708 	if ((sdaddr + size) & SBSDIO_SBWINDOW_MASK)
1709 		dsize = (SBSDIO_SB_OFT_ADDR_LIMIT - sdaddr);
1710 	else
1711 		dsize = size;
1712 
1713 	/* Set the backplane window to include the start address */
1714 	bcmerror = dhdsdio_set_siaddr_window(bus, address);
1715 	if (bcmerror) {
1716 		DHD_ERROR(("%s: window change failed\n", __func__));
1717 		goto xfer_done;
1718 	}
1719 
1720 	/* Do the transfer(s) */
1721 	while (size) {
1722 		DHD_INFO(("%s: %s %d bytes at offset 0x%08x in window 0x%08x\n",
1723 			  __func__, (write ? "write" : "read"), dsize,
1724 			  sdaddr, (address & SBSDIO_SBWINDOW_MASK)));
1725 		bcmerror =
1726 		     bcmsdh_rwdata(bus->sdh, write, sdaddr, data, dsize);
1727 		if (bcmerror) {
1728 			DHD_ERROR(("%s: membytes transfer failed\n", __func__));
1729 			break;
1730 		}
1731 
1732 		/* Adjust for next transfer (if any) */
1733 		size -= dsize;
1734 		if (size) {
1735 			data += dsize;
1736 			address += dsize;
1737 			bcmerror = dhdsdio_set_siaddr_window(bus, address);
1738 			if (bcmerror) {
1739 				DHD_ERROR(("%s: window change failed\n",
1740 					   __func__));
1741 				break;
1742 			}
1743 			sdaddr = 0;
1744 			dsize = min_t(uint, SBSDIO_SB_OFT_ADDR_LIMIT, size);
1745 		}
1746 	}
1747 
1748 xfer_done:
1749 	/* Return the window to backplane enumeration space for core access */
1750 	if (dhdsdio_set_siaddr_window(bus, bcmsdh_cur_sbwad(bus->sdh))) {
1751 		DHD_ERROR(("%s: FAILED to set window back to 0x%x\n",
1752 			   __func__, bcmsdh_cur_sbwad(bus->sdh)));
1753 	}
1754 
1755 	return bcmerror;
1756 }
1757 
1758 #ifdef DHD_DEBUG
dhdsdio_readshared(dhd_bus_t * bus,sdpcm_shared_t * sh)1759 static int dhdsdio_readshared(dhd_bus_t *bus, sdpcm_shared_t *sh)
1760 {
1761 	u32 addr;
1762 	int rv;
1763 
1764 	/* Read last word in memory to determine address of
1765 			 sdpcm_shared structure */
1766 	rv = dhdsdio_membytes(bus, false, bus->ramsize - 4, (u8 *)&addr, 4);
1767 	if (rv < 0)
1768 		return rv;
1769 
1770 	addr = le32_to_cpu(addr);
1771 
1772 	DHD_INFO(("sdpcm_shared address 0x%08X\n", addr));
1773 
1774 	/*
1775 	 * Check if addr is valid.
1776 	 * NVRAM length at the end of memory should have been overwritten.
1777 	 */
1778 	if (addr == 0 || ((~addr >> 16) & 0xffff) == (addr & 0xffff)) {
1779 		DHD_ERROR(("%s: address (0x%08x) of sdpcm_shared invalid\n",
1780 			   __func__, addr));
1781 		return BCME_ERROR;
1782 	}
1783 
1784 	/* Read hndrte_shared structure */
1785 	rv = dhdsdio_membytes(bus, false, addr, (u8 *) sh,
1786 			      sizeof(sdpcm_shared_t));
1787 	if (rv < 0)
1788 		return rv;
1789 
1790 	/* Endianness */
1791 	sh->flags = le32_to_cpu(sh->flags);
1792 	sh->trap_addr = le32_to_cpu(sh->trap_addr);
1793 	sh->assert_exp_addr = le32_to_cpu(sh->assert_exp_addr);
1794 	sh->assert_file_addr = le32_to_cpu(sh->assert_file_addr);
1795 	sh->assert_line = le32_to_cpu(sh->assert_line);
1796 	sh->console_addr = le32_to_cpu(sh->console_addr);
1797 	sh->msgtrace_addr = le32_to_cpu(sh->msgtrace_addr);
1798 
1799 	if ((sh->flags & SDPCM_SHARED_VERSION_MASK) != SDPCM_SHARED_VERSION) {
1800 		DHD_ERROR(("%s: sdpcm_shared version %d in dhd "
1801 			   "is different than sdpcm_shared version %d in dongle\n",
1802 			   __func__, SDPCM_SHARED_VERSION,
1803 			   sh->flags & SDPCM_SHARED_VERSION_MASK));
1804 		return BCME_ERROR;
1805 	}
1806 
1807 	return BCME_OK;
1808 }
1809 
dhdsdio_checkdied(dhd_bus_t * bus,u8 * data,uint size)1810 static int dhdsdio_checkdied(dhd_bus_t *bus, u8 *data, uint size)
1811 {
1812 	int bcmerror = 0;
1813 	uint msize = 512;
1814 	char *mbuffer = NULL;
1815 	uint maxstrlen = 256;
1816 	char *str = NULL;
1817 	trap_t tr;
1818 	sdpcm_shared_t sdpcm_shared;
1819 	struct bcmstrbuf strbuf;
1820 
1821 	DHD_TRACE(("%s: Enter\n", __func__));
1822 
1823 	if (data == NULL) {
1824 		/*
1825 		 * Called after a rx ctrl timeout. "data" is NULL.
1826 		 * allocate memory to trace the trap or assert.
1827 		 */
1828 		size = msize;
1829 		mbuffer = data = kmalloc(msize, GFP_ATOMIC);
1830 		if (mbuffer == NULL) {
1831 			DHD_ERROR(("%s: kmalloc(%d) failed\n", __func__,
1832 				   msize));
1833 			bcmerror = BCME_NOMEM;
1834 			goto done;
1835 		}
1836 	}
1837 
1838 	str = kmalloc(maxstrlen, GFP_ATOMIC);
1839 	if (str == NULL) {
1840 		DHD_ERROR(("%s: kmalloc(%d) failed\n", __func__, maxstrlen));
1841 		bcmerror = BCME_NOMEM;
1842 		goto done;
1843 	}
1844 
1845 	bcmerror = dhdsdio_readshared(bus, &sdpcm_shared);
1846 	if (bcmerror < 0)
1847 		goto done;
1848 
1849 	bcm_binit(&strbuf, data, size);
1850 
1851 	bcm_bprintf(&strbuf,
1852 		    "msgtrace address : 0x%08X\nconsole address  : 0x%08X\n",
1853 		    sdpcm_shared.msgtrace_addr, sdpcm_shared.console_addr);
1854 
1855 	if ((sdpcm_shared.flags & SDPCM_SHARED_ASSERT_BUILT) == 0) {
1856 		/* NOTE: Misspelled assert is intentional - DO NOT FIX.
1857 		 * (Avoids conflict with real asserts for programmatic
1858 		 * parsing of output.)
1859 		 */
1860 		bcm_bprintf(&strbuf, "Assrt not built in dongle\n");
1861 	}
1862 
1863 	if ((sdpcm_shared.flags & (SDPCM_SHARED_ASSERT | SDPCM_SHARED_TRAP)) ==
1864 	    0) {
1865 		/* NOTE: Misspelled assert is intentional - DO NOT FIX.
1866 		 * (Avoids conflict with real asserts for programmatic
1867 		 * parsing of output.)
1868 		 */
1869 		bcm_bprintf(&strbuf, "No trap%s in dongle",
1870 			    (sdpcm_shared.flags & SDPCM_SHARED_ASSERT_BUILT)
1871 			    ? "/assrt" : "");
1872 	} else {
1873 		if (sdpcm_shared.flags & SDPCM_SHARED_ASSERT) {
1874 			/* Download assert */
1875 			bcm_bprintf(&strbuf, "Dongle assert");
1876 			if (sdpcm_shared.assert_exp_addr != 0) {
1877 				str[0] = '\0';
1878 				bcmerror = dhdsdio_membytes(bus, false,
1879 						sdpcm_shared.assert_exp_addr,
1880 						(u8 *) str, maxstrlen);
1881 				if (bcmerror < 0)
1882 					goto done;
1883 
1884 				str[maxstrlen - 1] = '\0';
1885 				bcm_bprintf(&strbuf, " expr \"%s\"", str);
1886 			}
1887 
1888 			if (sdpcm_shared.assert_file_addr != 0) {
1889 				str[0] = '\0';
1890 				bcmerror = dhdsdio_membytes(bus, false,
1891 						sdpcm_shared.assert_file_addr,
1892 						(u8 *) str, maxstrlen);
1893 				if (bcmerror < 0)
1894 					goto done;
1895 
1896 				str[maxstrlen - 1] = '\0';
1897 				bcm_bprintf(&strbuf, " file \"%s\"", str);
1898 			}
1899 
1900 			bcm_bprintf(&strbuf, " line %d ",
1901 				    sdpcm_shared.assert_line);
1902 		}
1903 
1904 		if (sdpcm_shared.flags & SDPCM_SHARED_TRAP) {
1905 			bcmerror = dhdsdio_membytes(bus, false,
1906 					sdpcm_shared.trap_addr, (u8 *)&tr,
1907 					sizeof(trap_t));
1908 			if (bcmerror < 0)
1909 				goto done;
1910 
1911 			bcm_bprintf(&strbuf,
1912 				    "Dongle trap type 0x%x @ epc 0x%x, cpsr 0x%x, spsr 0x%x, sp 0x%x,"
1913 				    "lp 0x%x, rpc 0x%x Trap offset 0x%x, "
1914 				    "r0 0x%x, r1 0x%x, r2 0x%x, r3 0x%x, r4 0x%x, r5 0x%x, r6 0x%x, r7 0x%x\n",
1915 				    tr.type, tr.epc, tr.cpsr, tr.spsr, tr.r13,
1916 				    tr.r14, tr.pc, sdpcm_shared.trap_addr,
1917 				    tr.r0, tr.r1, tr.r2, tr.r3, tr.r4, tr.r5,
1918 				    tr.r6, tr.r7);
1919 		}
1920 	}
1921 
1922 	if (sdpcm_shared.flags & (SDPCM_SHARED_ASSERT | SDPCM_SHARED_TRAP))
1923 		DHD_ERROR(("%s: %s\n", __func__, strbuf.origbuf));
1924 
1925 #ifdef DHD_DEBUG
1926 	if (sdpcm_shared.flags & SDPCM_SHARED_TRAP) {
1927 		/* Mem dump to a file on device */
1928 		dhdsdio_mem_dump(bus);
1929 	}
1930 #endif				/* DHD_DEBUG */
1931 
1932 done:
1933 	kfree(mbuffer);
1934 	kfree(str);
1935 
1936 	return bcmerror;
1937 }
1938 
dhdsdio_mem_dump(dhd_bus_t * bus)1939 static int dhdsdio_mem_dump(dhd_bus_t *bus)
1940 {
1941 	int ret = 0;
1942 	int size;		/* Full mem size */
1943 	int start = 0;		/* Start address */
1944 	int read_size = 0;	/* Read size of each iteration */
1945 	u8 *buf = NULL, *databuf = NULL;
1946 
1947 	/* Get full mem size */
1948 	size = bus->ramsize;
1949 	buf = kmalloc(size, GFP_ATOMIC);
1950 	if (!buf) {
1951 		DHD_ERROR(("%s: Out of memory (%d bytes)\n", __func__, size));
1952 		return -1;
1953 	}
1954 
1955 	/* Read mem content */
1956 	printk(KERN_DEBUG "Dump dongle memory");
1957 	databuf = buf;
1958 	while (size) {
1959 		read_size = min(MEMBLOCK, size);
1960 		ret = dhdsdio_membytes(bus, false, start, databuf, read_size);
1961 		if (ret) {
1962 			DHD_ERROR(("%s: Error membytes %d\n", __func__, ret));
1963 			kfree(buf);
1964 			return -1;
1965 		}
1966 		printk(".");
1967 
1968 		/* Decrement size and increment start address */
1969 		size -= read_size;
1970 		start += read_size;
1971 		databuf += read_size;
1972 	}
1973 	printk(KERN_DEBUG "Done\n");
1974 
1975 	/* free buf before return !!! */
1976 	if (write_to_file(bus->dhd, buf, bus->ramsize)) {
1977 		DHD_ERROR(("%s: Error writing to files\n", __func__));
1978 		return -1;
1979 	}
1980 
1981 	/* buf free handled in write_to_file, not here */
1982 	return 0;
1983 }
1984 
1985 #define CONSOLE_LINE_MAX	192
1986 
dhdsdio_readconsole(dhd_bus_t * bus)1987 static int dhdsdio_readconsole(dhd_bus_t *bus)
1988 {
1989 	dhd_console_t *c = &bus->console;
1990 	u8 line[CONSOLE_LINE_MAX], ch;
1991 	u32 n, idx, addr;
1992 	int rv;
1993 
1994 	/* Don't do anything until FWREADY updates console address */
1995 	if (bus->console_addr == 0)
1996 		return 0;
1997 
1998 	/* Read console log struct */
1999 	addr = bus->console_addr + offsetof(hndrte_cons_t, log);
2000 	rv = dhdsdio_membytes(bus, false, addr, (u8 *)&c->log,
2001 				sizeof(c->log));
2002 	if (rv < 0)
2003 		return rv;
2004 
2005 	/* Allocate console buffer (one time only) */
2006 	if (c->buf == NULL) {
2007 		c->bufsize = le32_to_cpu(c->log.buf_size);
2008 		c->buf = kmalloc(c->bufsize, GFP_ATOMIC);
2009 		if (c->buf == NULL)
2010 			return BCME_NOMEM;
2011 	}
2012 
2013 	idx = le32_to_cpu(c->log.idx);
2014 
2015 	/* Protect against corrupt value */
2016 	if (idx > c->bufsize)
2017 		return BCME_ERROR;
2018 
2019 	/* Skip reading the console buffer if the index pointer
2020 	 has not moved */
2021 	if (idx == c->last)
2022 		return BCME_OK;
2023 
2024 	/* Read the console buffer */
2025 	addr = le32_to_cpu(c->log.buf);
2026 	rv = dhdsdio_membytes(bus, false, addr, c->buf, c->bufsize);
2027 	if (rv < 0)
2028 		return rv;
2029 
2030 	while (c->last != idx) {
2031 		for (n = 0; n < CONSOLE_LINE_MAX - 2; n++) {
2032 			if (c->last == idx) {
2033 				/* This would output a partial line.
2034 				 * Instead, back up
2035 				 * the buffer pointer and output this
2036 				 * line next time around.
2037 				 */
2038 				if (c->last >= n)
2039 					c->last -= n;
2040 				else
2041 					c->last = c->bufsize - n;
2042 				goto break2;
2043 			}
2044 			ch = c->buf[c->last];
2045 			c->last = (c->last + 1) % c->bufsize;
2046 			if (ch == '\n')
2047 				break;
2048 			line[n] = ch;
2049 		}
2050 
2051 		if (n > 0) {
2052 			if (line[n - 1] == '\r')
2053 				n--;
2054 			line[n] = 0;
2055 			printk(KERN_DEBUG "CONSOLE: %s\n", line);
2056 		}
2057 	}
2058 break2:
2059 
2060 	return BCME_OK;
2061 }
2062 #endif				/* DHD_DEBUG */
2063 
dhdsdio_downloadvars(dhd_bus_t * bus,void * arg,int len)2064 int dhdsdio_downloadvars(dhd_bus_t *bus, void *arg, int len)
2065 {
2066 	int bcmerror = BCME_OK;
2067 
2068 	DHD_TRACE(("%s: Enter\n", __func__));
2069 
2070 	/* Basic sanity checks */
2071 	if (bus->dhd->up) {
2072 		bcmerror = BCME_NOTDOWN;
2073 		goto err;
2074 	}
2075 	if (!len) {
2076 		bcmerror = BCME_BUFTOOSHORT;
2077 		goto err;
2078 	}
2079 
2080 	/* Free the old ones and replace with passed variables */
2081 	kfree(bus->vars);
2082 
2083 	bus->vars = kmalloc(len, GFP_ATOMIC);
2084 	bus->varsz = bus->vars ? len : 0;
2085 	if (bus->vars == NULL) {
2086 		bcmerror = BCME_NOMEM;
2087 		goto err;
2088 	}
2089 
2090 	/* Copy the passed variables, which should include the
2091 		 terminating double-null */
2092 	memcpy(bus->vars, arg, bus->varsz);
2093 err:
2094 	return bcmerror;
2095 }
2096 
2097 static int
dhdsdio_doiovar(dhd_bus_t * bus,const bcm_iovar_t * vi,u32 actionid,const char * name,void * params,int plen,void * arg,int len,int val_size)2098 dhdsdio_doiovar(dhd_bus_t *bus, const bcm_iovar_t *vi, u32 actionid,
2099 		const char *name, void *params, int plen, void *arg, int len,
2100 		int val_size)
2101 {
2102 	int bcmerror = 0;
2103 	s32 int_val = 0;
2104 	bool bool_val = 0;
2105 
2106 	DHD_TRACE(("%s: Enter, action %d name %s params %p plen %d arg %p "
2107 		"len %d val_size %d\n",
2108 		__func__, actionid, name, params, plen, arg, len, val_size));
2109 
2110 	bcmerror = bcm_iovar_lencheck(vi, arg, len, IOV_ISSET(actionid));
2111 	if (bcmerror != 0)
2112 		goto exit;
2113 
2114 	if (plen >= (int)sizeof(int_val))
2115 		memcpy(&int_val, params, sizeof(int_val));
2116 
2117 	bool_val = (int_val != 0) ? true : false;
2118 
2119 	/* Some ioctls use the bus */
2120 	dhd_os_sdlock(bus->dhd);
2121 
2122 	/* Check if dongle is in reset. If so, only allow DEVRESET iovars */
2123 	if (bus->dhd->dongle_reset && !(actionid == IOV_SVAL(IOV_DEVRESET) ||
2124 					actionid == IOV_GVAL(IOV_DEVRESET))) {
2125 		bcmerror = BCME_NOTREADY;
2126 		goto exit;
2127 	}
2128 
2129 	/* Handle sleep stuff before any clock mucking */
2130 	if (vi->varid == IOV_SLEEP) {
2131 		if (IOV_ISSET(actionid)) {
2132 			bcmerror = dhdsdio_bussleep(bus, bool_val);
2133 		} else {
2134 			int_val = (s32) bus->sleeping;
2135 			memcpy(arg, &int_val, val_size);
2136 		}
2137 		goto exit;
2138 	}
2139 
2140 	/* Request clock to allow SDIO accesses */
2141 	if (!bus->dhd->dongle_reset) {
2142 		BUS_WAKE(bus);
2143 		dhdsdio_clkctl(bus, CLK_AVAIL, false);
2144 	}
2145 
2146 	switch (actionid) {
2147 	case IOV_GVAL(IOV_INTR):
2148 		int_val = (s32) bus->intr;
2149 		memcpy(arg, &int_val, val_size);
2150 		break;
2151 
2152 	case IOV_SVAL(IOV_INTR):
2153 		bus->intr = bool_val;
2154 		bus->intdis = false;
2155 		if (bus->dhd->up) {
2156 			if (bus->intr) {
2157 				DHD_INTR(("%s: enable SDIO device interrupts\n",
2158 					  __func__));
2159 				bcmsdh_intr_enable(bus->sdh);
2160 			} else {
2161 				DHD_INTR(("%s: disable SDIO interrupts\n",
2162 					  __func__));
2163 				bcmsdh_intr_disable(bus->sdh);
2164 			}
2165 		}
2166 		break;
2167 
2168 	case IOV_GVAL(IOV_POLLRATE):
2169 		int_val = (s32) bus->pollrate;
2170 		memcpy(arg, &int_val, val_size);
2171 		break;
2172 
2173 	case IOV_SVAL(IOV_POLLRATE):
2174 		bus->pollrate = (uint) int_val;
2175 		bus->poll = (bus->pollrate != 0);
2176 		break;
2177 
2178 	case IOV_GVAL(IOV_IDLETIME):
2179 		int_val = bus->idletime;
2180 		memcpy(arg, &int_val, val_size);
2181 		break;
2182 
2183 	case IOV_SVAL(IOV_IDLETIME):
2184 		if ((int_val < 0) && (int_val != DHD_IDLE_IMMEDIATE))
2185 			bcmerror = BCME_BADARG;
2186 		else
2187 			bus->idletime = int_val;
2188 		break;
2189 
2190 	case IOV_GVAL(IOV_IDLECLOCK):
2191 		int_val = (s32) bus->idleclock;
2192 		memcpy(arg, &int_val, val_size);
2193 		break;
2194 
2195 	case IOV_SVAL(IOV_IDLECLOCK):
2196 		bus->idleclock = int_val;
2197 		break;
2198 
2199 	case IOV_GVAL(IOV_SD1IDLE):
2200 		int_val = (s32) sd1idle;
2201 		memcpy(arg, &int_val, val_size);
2202 		break;
2203 
2204 	case IOV_SVAL(IOV_SD1IDLE):
2205 		sd1idle = bool_val;
2206 		break;
2207 
2208 	case IOV_SVAL(IOV_MEMBYTES):
2209 	case IOV_GVAL(IOV_MEMBYTES):
2210 		{
2211 			u32 address;
2212 			uint size, dsize;
2213 			u8 *data;
2214 
2215 			bool set = (actionid == IOV_SVAL(IOV_MEMBYTES));
2216 
2217 			ASSERT(plen >= 2 * sizeof(int));
2218 
2219 			address = (u32) int_val;
2220 			memcpy(&int_val, (char *)params + sizeof(int_val),
2221 			       sizeof(int_val));
2222 			size = (uint) int_val;
2223 
2224 			/* Do some validation */
2225 			dsize = set ? plen - (2 * sizeof(int)) : len;
2226 			if (dsize < size) {
2227 				DHD_ERROR(("%s: error on %s membytes, addr "
2228 				"0x%08x size %d dsize %d\n",
2229 				__func__, (set ? "set" : "get"),
2230 				address, size, dsize));
2231 				bcmerror = BCME_BADARG;
2232 				break;
2233 			}
2234 
2235 			DHD_INFO(("%s: Request to %s %d bytes at address "
2236 			"0x%08x\n",
2237 			__func__, (set ? "write" : "read"), size, address));
2238 
2239 			/* If we know about SOCRAM, check for a fit */
2240 			if ((bus->orig_ramsize) &&
2241 			    ((address > bus->orig_ramsize)
2242 			     || (address + size > bus->orig_ramsize))) {
2243 				DHD_ERROR(("%s: ramsize 0x%08x doesn't have %d "
2244 				"bytes at 0x%08x\n",
2245 				__func__, bus->orig_ramsize, size, address));
2246 				bcmerror = BCME_BADARG;
2247 				break;
2248 			}
2249 
2250 			/* Generate the actual data pointer */
2251 			data =
2252 			    set ? (u8 *) params +
2253 			    2 * sizeof(int) : (u8 *) arg;
2254 
2255 			/* Call to do the transfer */
2256 			bcmerror =
2257 			    dhdsdio_membytes(bus, set, address, data, size);
2258 
2259 			break;
2260 		}
2261 
2262 	case IOV_GVAL(IOV_MEMSIZE):
2263 		int_val = (s32) bus->ramsize;
2264 		memcpy(arg, &int_val, val_size);
2265 		break;
2266 
2267 	case IOV_GVAL(IOV_SDIOD_DRIVE):
2268 		int_val = (s32) dhd_sdiod_drive_strength;
2269 		memcpy(arg, &int_val, val_size);
2270 		break;
2271 
2272 	case IOV_SVAL(IOV_SDIOD_DRIVE):
2273 		dhd_sdiod_drive_strength = int_val;
2274 		si_sdiod_drive_strength_init(bus->sih,
2275 					     dhd_sdiod_drive_strength);
2276 		break;
2277 
2278 	case IOV_SVAL(IOV_DOWNLOAD):
2279 		bcmerror = dhdsdio_download_state(bus, bool_val);
2280 		break;
2281 
2282 	case IOV_SVAL(IOV_VARS):
2283 		bcmerror = dhdsdio_downloadvars(bus, arg, len);
2284 		break;
2285 
2286 	case IOV_GVAL(IOV_READAHEAD):
2287 		int_val = (s32) dhd_readahead;
2288 		memcpy(arg, &int_val, val_size);
2289 		break;
2290 
2291 	case IOV_SVAL(IOV_READAHEAD):
2292 		if (bool_val && !dhd_readahead)
2293 			bus->nextlen = 0;
2294 		dhd_readahead = bool_val;
2295 		break;
2296 
2297 	case IOV_GVAL(IOV_SDRXCHAIN):
2298 		int_val = (s32) bus->use_rxchain;
2299 		memcpy(arg, &int_val, val_size);
2300 		break;
2301 
2302 	case IOV_SVAL(IOV_SDRXCHAIN):
2303 		if (bool_val && !bus->sd_rxchain)
2304 			bcmerror = BCME_UNSUPPORTED;
2305 		else
2306 			bus->use_rxchain = bool_val;
2307 		break;
2308 	case IOV_GVAL(IOV_ALIGNCTL):
2309 		int_val = (s32) dhd_alignctl;
2310 		memcpy(arg, &int_val, val_size);
2311 		break;
2312 
2313 	case IOV_SVAL(IOV_ALIGNCTL):
2314 		dhd_alignctl = bool_val;
2315 		break;
2316 
2317 	case IOV_GVAL(IOV_SDALIGN):
2318 		int_val = DHD_SDALIGN;
2319 		memcpy(arg, &int_val, val_size);
2320 		break;
2321 
2322 #ifdef DHD_DEBUG
2323 	case IOV_GVAL(IOV_VARS):
2324 		if (bus->varsz < (uint) len)
2325 			memcpy(arg, bus->vars, bus->varsz);
2326 		else
2327 			bcmerror = BCME_BUFTOOSHORT;
2328 		break;
2329 #endif				/* DHD_DEBUG */
2330 
2331 #ifdef DHD_DEBUG
2332 	case IOV_GVAL(IOV_SDREG):
2333 		{
2334 			sdreg_t *sd_ptr;
2335 			u32 addr, size;
2336 
2337 			sd_ptr = (sdreg_t *) params;
2338 
2339 			addr = (unsigned long)bus->regs + sd_ptr->offset;
2340 			size = sd_ptr->func;
2341 			int_val = (s32) bcmsdh_reg_read(bus->sdh, addr, size);
2342 			if (bcmsdh_regfail(bus->sdh))
2343 				bcmerror = BCME_SDIO_ERROR;
2344 			memcpy(arg, &int_val, sizeof(s32));
2345 			break;
2346 		}
2347 
2348 	case IOV_SVAL(IOV_SDREG):
2349 		{
2350 			sdreg_t *sd_ptr;
2351 			u32 addr, size;
2352 
2353 			sd_ptr = (sdreg_t *) params;
2354 
2355 			addr = (unsigned long)bus->regs + sd_ptr->offset;
2356 			size = sd_ptr->func;
2357 			bcmsdh_reg_write(bus->sdh, addr, size, sd_ptr->value);
2358 			if (bcmsdh_regfail(bus->sdh))
2359 				bcmerror = BCME_SDIO_ERROR;
2360 			break;
2361 		}
2362 
2363 		/* Same as above, but offset is not backplane
2364 		 (not SDIO core) */
2365 	case IOV_GVAL(IOV_SBREG):
2366 		{
2367 			sdreg_t sdreg;
2368 			u32 addr, size;
2369 
2370 			memcpy(&sdreg, params, sizeof(sdreg));
2371 
2372 			addr = SI_ENUM_BASE + sdreg.offset;
2373 			size = sdreg.func;
2374 			int_val = (s32) bcmsdh_reg_read(bus->sdh, addr, size);
2375 			if (bcmsdh_regfail(bus->sdh))
2376 				bcmerror = BCME_SDIO_ERROR;
2377 			memcpy(arg, &int_val, sizeof(s32));
2378 			break;
2379 		}
2380 
2381 	case IOV_SVAL(IOV_SBREG):
2382 		{
2383 			sdreg_t sdreg;
2384 			u32 addr, size;
2385 
2386 			memcpy(&sdreg, params, sizeof(sdreg));
2387 
2388 			addr = SI_ENUM_BASE + sdreg.offset;
2389 			size = sdreg.func;
2390 			bcmsdh_reg_write(bus->sdh, addr, size, sdreg.value);
2391 			if (bcmsdh_regfail(bus->sdh))
2392 				bcmerror = BCME_SDIO_ERROR;
2393 			break;
2394 		}
2395 
2396 	case IOV_GVAL(IOV_SDCIS):
2397 		{
2398 			*(char *)arg = 0;
2399 
2400 			strcat(arg, "\nFunc 0\n");
2401 			bcmsdh_cis_read(bus->sdh, 0x10,
2402 					(u8 *) arg + strlen(arg),
2403 					SBSDIO_CIS_SIZE_LIMIT);
2404 			strcat(arg, "\nFunc 1\n");
2405 			bcmsdh_cis_read(bus->sdh, 0x11,
2406 					(u8 *) arg + strlen(arg),
2407 					SBSDIO_CIS_SIZE_LIMIT);
2408 			strcat(arg, "\nFunc 2\n");
2409 			bcmsdh_cis_read(bus->sdh, 0x12,
2410 					(u8 *) arg + strlen(arg),
2411 					SBSDIO_CIS_SIZE_LIMIT);
2412 			break;
2413 		}
2414 
2415 	case IOV_GVAL(IOV_FORCEEVEN):
2416 		int_val = (s32) forcealign;
2417 		memcpy(arg, &int_val, val_size);
2418 		break;
2419 
2420 	case IOV_SVAL(IOV_FORCEEVEN):
2421 		forcealign = bool_val;
2422 		break;
2423 
2424 	case IOV_GVAL(IOV_TXBOUND):
2425 		int_val = (s32) dhd_txbound;
2426 		memcpy(arg, &int_val, val_size);
2427 		break;
2428 
2429 	case IOV_SVAL(IOV_TXBOUND):
2430 		dhd_txbound = (uint) int_val;
2431 		break;
2432 
2433 	case IOV_GVAL(IOV_RXBOUND):
2434 		int_val = (s32) dhd_rxbound;
2435 		memcpy(arg, &int_val, val_size);
2436 		break;
2437 
2438 	case IOV_SVAL(IOV_RXBOUND):
2439 		dhd_rxbound = (uint) int_val;
2440 		break;
2441 
2442 	case IOV_GVAL(IOV_TXMINMAX):
2443 		int_val = (s32) dhd_txminmax;
2444 		memcpy(arg, &int_val, val_size);
2445 		break;
2446 
2447 	case IOV_SVAL(IOV_TXMINMAX):
2448 		dhd_txminmax = (uint) int_val;
2449 		break;
2450 #endif				/* DHD_DEBUG */
2451 
2452 #ifdef SDTEST
2453 	case IOV_GVAL(IOV_EXTLOOP):
2454 		int_val = (s32) bus->ext_loop;
2455 		memcpy(arg, &int_val, val_size);
2456 		break;
2457 
2458 	case IOV_SVAL(IOV_EXTLOOP):
2459 		bus->ext_loop = bool_val;
2460 		break;
2461 
2462 	case IOV_GVAL(IOV_PKTGEN):
2463 		bcmerror = dhdsdio_pktgen_get(bus, arg);
2464 		break;
2465 
2466 	case IOV_SVAL(IOV_PKTGEN):
2467 		bcmerror = dhdsdio_pktgen_set(bus, arg);
2468 		break;
2469 #endif				/* SDTEST */
2470 
2471 	case IOV_SVAL(IOV_DEVRESET):
2472 		DHD_TRACE(("%s: Called set IOV_DEVRESET=%d dongle_reset=%d "
2473 			"busstate=%d\n",
2474 			__func__, bool_val, bus->dhd->dongle_reset,
2475 			bus->dhd->busstate));
2476 
2477 		dhd_bus_devreset(bus->dhd, (u8) bool_val);
2478 
2479 		break;
2480 
2481 	case IOV_GVAL(IOV_DEVRESET):
2482 		DHD_TRACE(("%s: Called get IOV_DEVRESET\n", __func__));
2483 
2484 		/* Get its status */
2485 		int_val = (bool) bus->dhd->dongle_reset;
2486 		memcpy(arg, &int_val, val_size);
2487 
2488 		break;
2489 
2490 	default:
2491 		bcmerror = BCME_UNSUPPORTED;
2492 		break;
2493 	}
2494 
2495 exit:
2496 	if ((bus->idletime == DHD_IDLE_IMMEDIATE) && !bus->dpc_sched) {
2497 		bus->activity = false;
2498 		dhdsdio_clkctl(bus, CLK_NONE, true);
2499 	}
2500 
2501 	dhd_os_sdunlock(bus->dhd);
2502 
2503 	if (actionid == IOV_SVAL(IOV_DEVRESET) && bool_val == false)
2504 		dhd_preinit_ioctls((dhd_pub_t *) bus->dhd);
2505 
2506 	return bcmerror;
2507 }
2508 
dhdsdio_write_vars(dhd_bus_t * bus)2509 static int dhdsdio_write_vars(dhd_bus_t *bus)
2510 {
2511 	int bcmerror = 0;
2512 	u32 varsize;
2513 	u32 varaddr;
2514 	u8 *vbuffer;
2515 	u32 varsizew;
2516 #ifdef DHD_DEBUG
2517 	char *nvram_ularray;
2518 #endif				/* DHD_DEBUG */
2519 
2520 	/* Even if there are no vars are to be written, we still
2521 		 need to set the ramsize. */
2522 	varsize = bus->varsz ? roundup(bus->varsz, 4) : 0;
2523 	varaddr = (bus->ramsize - 4) - varsize;
2524 
2525 	if (bus->vars) {
2526 		vbuffer = kzalloc(varsize, GFP_ATOMIC);
2527 		if (!vbuffer)
2528 			return BCME_NOMEM;
2529 
2530 		memcpy(vbuffer, bus->vars, bus->varsz);
2531 
2532 		/* Write the vars list */
2533 		bcmerror =
2534 		    dhdsdio_membytes(bus, true, varaddr, vbuffer, varsize);
2535 #ifdef DHD_DEBUG
2536 		/* Verify NVRAM bytes */
2537 		DHD_INFO(("Compare NVRAM dl & ul; varsize=%d\n", varsize));
2538 		nvram_ularray = kmalloc(varsize, GFP_ATOMIC);
2539 		if (!nvram_ularray)
2540 			return BCME_NOMEM;
2541 
2542 		/* Upload image to verify downloaded contents. */
2543 		memset(nvram_ularray, 0xaa, varsize);
2544 
2545 		/* Read the vars list to temp buffer for comparison */
2546 		bcmerror =
2547 		    dhdsdio_membytes(bus, false, varaddr, nvram_ularray,
2548 				     varsize);
2549 		if (bcmerror) {
2550 			DHD_ERROR(("%s: error %d on reading %d nvram bytes at "
2551 			"0x%08x\n", __func__, bcmerror, varsize, varaddr));
2552 		}
2553 		/* Compare the org NVRAM with the one read from RAM */
2554 		if (memcmp(vbuffer, nvram_ularray, varsize)) {
2555 			DHD_ERROR(("%s: Downloaded NVRAM image is corrupted.\n",
2556 				   __func__));
2557 		} else
2558 			DHD_ERROR(("%s: Download/Upload/Compare of NVRAM ok.\n",
2559 				__func__));
2560 
2561 		kfree(nvram_ularray);
2562 #endif				/* DHD_DEBUG */
2563 
2564 		kfree(vbuffer);
2565 	}
2566 
2567 	/* adjust to the user specified RAM */
2568 	DHD_INFO(("Physical memory size: %d, usable memory size: %d\n",
2569 		  bus->orig_ramsize, bus->ramsize));
2570 	DHD_INFO(("Vars are at %d, orig varsize is %d\n", varaddr, varsize));
2571 	varsize = ((bus->orig_ramsize - 4) - varaddr);
2572 
2573 	/*
2574 	 * Determine the length token:
2575 	 * Varsize, converted to words, in lower 16-bits, checksum
2576 	 * in upper 16-bits.
2577 	 */
2578 	if (bcmerror) {
2579 		varsizew = 0;
2580 	} else {
2581 		varsizew = varsize / 4;
2582 		varsizew = (~varsizew << 16) | (varsizew & 0x0000FFFF);
2583 		varsizew = cpu_to_le32(varsizew);
2584 	}
2585 
2586 	DHD_INFO(("New varsize is %d, length token=0x%08x\n", varsize,
2587 		  varsizew));
2588 
2589 	/* Write the length token to the last word */
2590 	bcmerror = dhdsdio_membytes(bus, true, (bus->orig_ramsize - 4),
2591 				    (u8 *)&varsizew, 4);
2592 
2593 	return bcmerror;
2594 }
2595 
dhdsdio_download_state(dhd_bus_t * bus,bool enter)2596 static int dhdsdio_download_state(dhd_bus_t *bus, bool enter)
2597 {
2598 	uint retries;
2599 	int bcmerror = 0;
2600 
2601 	/* To enter download state, disable ARM and reset SOCRAM.
2602 	 * To exit download state, simply reset ARM (default is RAM boot).
2603 	 */
2604 	if (enter) {
2605 
2606 		bus->alp_only = true;
2607 
2608 		if (!(si_setcore(bus->sih, ARM7S_CORE_ID, 0)) &&
2609 		    !(si_setcore(bus->sih, ARMCM3_CORE_ID, 0))) {
2610 			DHD_ERROR(("%s: Failed to find ARM core!\n", __func__));
2611 			bcmerror = BCME_ERROR;
2612 			goto fail;
2613 		}
2614 
2615 		si_core_disable(bus->sih, 0);
2616 		if (bcmsdh_regfail(bus->sdh)) {
2617 			bcmerror = BCME_SDIO_ERROR;
2618 			goto fail;
2619 		}
2620 
2621 		if (!(si_setcore(bus->sih, SOCRAM_CORE_ID, 0))) {
2622 			DHD_ERROR(("%s: Failed to find SOCRAM core!\n",
2623 				   __func__));
2624 			bcmerror = BCME_ERROR;
2625 			goto fail;
2626 		}
2627 
2628 		si_core_reset(bus->sih, 0, 0);
2629 		if (bcmsdh_regfail(bus->sdh)) {
2630 			DHD_ERROR(("%s: Failure trying reset SOCRAM core?\n",
2631 				   __func__));
2632 			bcmerror = BCME_SDIO_ERROR;
2633 			goto fail;
2634 		}
2635 
2636 		/* Clear the top bit of memory */
2637 		if (bus->ramsize) {
2638 			u32 zeros = 0;
2639 			dhdsdio_membytes(bus, true, bus->ramsize - 4,
2640 					 (u8 *)&zeros, 4);
2641 		}
2642 	} else {
2643 		if (!(si_setcore(bus->sih, SOCRAM_CORE_ID, 0))) {
2644 			DHD_ERROR(("%s: Failed to find SOCRAM core!\n",
2645 				   __func__));
2646 			bcmerror = BCME_ERROR;
2647 			goto fail;
2648 		}
2649 
2650 		if (!si_iscoreup(bus->sih)) {
2651 			DHD_ERROR(("%s: SOCRAM core is down after reset?\n",
2652 				   __func__));
2653 			bcmerror = BCME_ERROR;
2654 			goto fail;
2655 		}
2656 
2657 		bcmerror = dhdsdio_write_vars(bus);
2658 		if (bcmerror) {
2659 			DHD_ERROR(("%s: no vars written to RAM\n", __func__));
2660 			bcmerror = 0;
2661 		}
2662 
2663 		if (!si_setcore(bus->sih, PCMCIA_CORE_ID, 0) &&
2664 		    !si_setcore(bus->sih, SDIOD_CORE_ID, 0)) {
2665 			DHD_ERROR(("%s: Can't change back to SDIO core?\n",
2666 				   __func__));
2667 			bcmerror = BCME_ERROR;
2668 			goto fail;
2669 		}
2670 		W_SDREG(0xFFFFFFFF, &bus->regs->intstatus, retries);
2671 
2672 		if (!(si_setcore(bus->sih, ARM7S_CORE_ID, 0)) &&
2673 		    !(si_setcore(bus->sih, ARMCM3_CORE_ID, 0))) {
2674 			DHD_ERROR(("%s: Failed to find ARM core!\n", __func__));
2675 			bcmerror = BCME_ERROR;
2676 			goto fail;
2677 		}
2678 
2679 		si_core_reset(bus->sih, 0, 0);
2680 		if (bcmsdh_regfail(bus->sdh)) {
2681 			DHD_ERROR(("%s: Failure trying to reset ARM core?\n",
2682 				   __func__));
2683 			bcmerror = BCME_SDIO_ERROR;
2684 			goto fail;
2685 		}
2686 
2687 		/* Allow HT Clock now that the ARM is running. */
2688 		bus->alp_only = false;
2689 
2690 		bus->dhd->busstate = DHD_BUS_LOAD;
2691 	}
2692 
2693 fail:
2694 	/* Always return to SDIOD core */
2695 	if (!si_setcore(bus->sih, PCMCIA_CORE_ID, 0))
2696 		si_setcore(bus->sih, SDIOD_CORE_ID, 0);
2697 
2698 	return bcmerror;
2699 }
2700 
2701 int
dhd_bus_iovar_op(dhd_pub_t * dhdp,const char * name,void * params,int plen,void * arg,int len,bool set)2702 dhd_bus_iovar_op(dhd_pub_t *dhdp, const char *name,
2703 		 void *params, int plen, void *arg, int len, bool set)
2704 {
2705 	dhd_bus_t *bus = dhdp->bus;
2706 	const bcm_iovar_t *vi = NULL;
2707 	int bcmerror = 0;
2708 	int val_size;
2709 	u32 actionid;
2710 
2711 	DHD_TRACE(("%s: Enter\n", __func__));
2712 
2713 	ASSERT(name);
2714 	ASSERT(len >= 0);
2715 
2716 	/* Get MUST have return space */
2717 	ASSERT(set || (arg && len));
2718 
2719 	/* Set does NOT take qualifiers */
2720 	ASSERT(!set || (!params && !plen));
2721 
2722 	/* Look up var locally; if not found pass to host driver */
2723 	vi = bcm_iovar_lookup(dhdsdio_iovars, name);
2724 	if (vi == NULL) {
2725 		dhd_os_sdlock(bus->dhd);
2726 
2727 		BUS_WAKE(bus);
2728 
2729 		/* Turn on clock in case SD command needs backplane */
2730 		dhdsdio_clkctl(bus, CLK_AVAIL, false);
2731 
2732 		bcmerror =
2733 		    bcmsdh_iovar_op(bus->sdh, name, params, plen, arg, len,
2734 				    set);
2735 
2736 		/* Check for bus configuration changes of interest */
2737 
2738 		/* If it was divisor change, read the new one */
2739 		if (set && strcmp(name, "sd_divisor") == 0) {
2740 			if (bcmsdh_iovar_op(bus->sdh, "sd_divisor", NULL, 0,
2741 					    &bus->sd_divisor, sizeof(s32),
2742 					    false) != BCME_OK) {
2743 				bus->sd_divisor = -1;
2744 				DHD_ERROR(("%s: fail on %s get\n", __func__,
2745 					   name));
2746 			} else {
2747 				DHD_INFO(("%s: noted %s update, value now %d\n",
2748 					  __func__, name, bus->sd_divisor));
2749 			}
2750 		}
2751 		/* If it was a mode change, read the new one */
2752 		if (set && strcmp(name, "sd_mode") == 0) {
2753 			if (bcmsdh_iovar_op(bus->sdh, "sd_mode", NULL, 0,
2754 					    &bus->sd_mode, sizeof(s32),
2755 					    false) != BCME_OK) {
2756 				bus->sd_mode = -1;
2757 				DHD_ERROR(("%s: fail on %s get\n", __func__,
2758 					   name));
2759 			} else {
2760 				DHD_INFO(("%s: noted %s update, value now %d\n",
2761 					  __func__, name, bus->sd_mode));
2762 			}
2763 		}
2764 		/* Similar check for blocksize change */
2765 		if (set && strcmp(name, "sd_blocksize") == 0) {
2766 			s32 fnum = 2;
2767 			if (bcmsdh_iovar_op
2768 			    (bus->sdh, "sd_blocksize", &fnum, sizeof(s32),
2769 			     &bus->blocksize, sizeof(s32),
2770 			     false) != BCME_OK) {
2771 				bus->blocksize = 0;
2772 				DHD_ERROR(("%s: fail on %s get\n", __func__,
2773 					   "sd_blocksize"));
2774 			} else {
2775 				DHD_INFO(("%s: noted %s update, value now %d\n",
2776 					  __func__, "sd_blocksize",
2777 					  bus->blocksize));
2778 			}
2779 		}
2780 		bus->roundup = min(max_roundup, bus->blocksize);
2781 
2782 		if ((bus->idletime == DHD_IDLE_IMMEDIATE) && !bus->dpc_sched) {
2783 			bus->activity = false;
2784 			dhdsdio_clkctl(bus, CLK_NONE, true);
2785 		}
2786 
2787 		dhd_os_sdunlock(bus->dhd);
2788 		goto exit;
2789 	}
2790 
2791 	DHD_CTL(("%s: %s %s, len %d plen %d\n", __func__,
2792 		 name, (set ? "set" : "get"), len, plen));
2793 
2794 	/* set up 'params' pointer in case this is a set command so that
2795 	 * the convenience int and bool code can be common to set and get
2796 	 */
2797 	if (params == NULL) {
2798 		params = arg;
2799 		plen = len;
2800 	}
2801 
2802 	if (vi->type == IOVT_VOID)
2803 		val_size = 0;
2804 	else if (vi->type == IOVT_BUFFER)
2805 		val_size = len;
2806 	else
2807 		/* all other types are integer sized */
2808 		val_size = sizeof(int);
2809 
2810 	actionid = set ? IOV_SVAL(vi->varid) : IOV_GVAL(vi->varid);
2811 	bcmerror =
2812 	    dhdsdio_doiovar(bus, vi, actionid, name, params, plen, arg, len,
2813 			    val_size);
2814 
2815 exit:
2816 	return bcmerror;
2817 }
2818 
dhd_bus_stop(struct dhd_bus * bus,bool enforce_mutex)2819 void dhd_bus_stop(struct dhd_bus *bus, bool enforce_mutex)
2820 {
2821 	u32 local_hostintmask;
2822 	u8 saveclk;
2823 	uint retries;
2824 	int err;
2825 
2826 	DHD_TRACE(("%s: Enter\n", __func__));
2827 
2828 	if (enforce_mutex)
2829 		dhd_os_sdlock(bus->dhd);
2830 
2831 	BUS_WAKE(bus);
2832 
2833 	/* Enable clock for device interrupts */
2834 	dhdsdio_clkctl(bus, CLK_AVAIL, false);
2835 
2836 	/* Disable and clear interrupts at the chip level also */
2837 	W_SDREG(0, &bus->regs->hostintmask, retries);
2838 	local_hostintmask = bus->hostintmask;
2839 	bus->hostintmask = 0;
2840 
2841 	/* Change our idea of bus state */
2842 	bus->dhd->busstate = DHD_BUS_DOWN;
2843 
2844 	/* Force clocks on backplane to be sure F2 interrupt propagates */
2845 	saveclk =
2846 	    bcmsdh_cfg_read(bus->sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR,
2847 			    &err);
2848 	if (!err) {
2849 		bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR,
2850 				 (saveclk | SBSDIO_FORCE_HT), &err);
2851 	}
2852 	if (err) {
2853 		DHD_ERROR(("%s: Failed to force clock for F2: err %d\n",
2854 			   __func__, err));
2855 	}
2856 
2857 	/* Turn off the bus (F2), free any pending packets */
2858 	DHD_INTR(("%s: disable SDIO interrupts\n", __func__));
2859 	bcmsdh_intr_disable(bus->sdh);
2860 	bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_0, SDIOD_CCCR_IOEN,
2861 			 SDIO_FUNC_ENABLE_1, NULL);
2862 
2863 	/* Clear any pending interrupts now that F2 is disabled */
2864 	W_SDREG(local_hostintmask, &bus->regs->intstatus, retries);
2865 
2866 	/* Turn off the backplane clock (only) */
2867 	dhdsdio_clkctl(bus, CLK_SDONLY, false);
2868 
2869 	/* Clear the data packet queues */
2870 	pktq_flush(&bus->txq, true);
2871 
2872 	/* Clear any held glomming stuff */
2873 	if (bus->glomd)
2874 		pkt_buf_free_skb(bus->glomd);
2875 
2876 	if (bus->glom)
2877 		pkt_buf_free_skb(bus->glom);
2878 
2879 	bus->glom = bus->glomd = NULL;
2880 
2881 	/* Clear rx control and wake any waiters */
2882 	bus->rxlen = 0;
2883 	dhd_os_ioctl_resp_wake(bus->dhd);
2884 
2885 	/* Reset some F2 state stuff */
2886 	bus->rxskip = false;
2887 	bus->tx_seq = bus->rx_seq = 0;
2888 
2889 	if (enforce_mutex)
2890 		dhd_os_sdunlock(bus->dhd);
2891 }
2892 
dhd_bus_init(dhd_pub_t * dhdp,bool enforce_mutex)2893 int dhd_bus_init(dhd_pub_t *dhdp, bool enforce_mutex)
2894 {
2895 	dhd_bus_t *bus = dhdp->bus;
2896 	dhd_timeout_t tmo;
2897 	uint retries = 0;
2898 	u8 ready, enable;
2899 	int err, ret = 0;
2900 	u8 saveclk;
2901 
2902 	DHD_TRACE(("%s: Enter\n", __func__));
2903 
2904 	ASSERT(bus->dhd);
2905 	if (!bus->dhd)
2906 		return 0;
2907 
2908 	if (enforce_mutex)
2909 		dhd_os_sdlock(bus->dhd);
2910 
2911 	/* Make sure backplane clock is on, needed to generate F2 interrupt */
2912 	dhdsdio_clkctl(bus, CLK_AVAIL, false);
2913 	if (bus->clkstate != CLK_AVAIL)
2914 		goto exit;
2915 
2916 	/* Force clocks on backplane to be sure F2 interrupt propagates */
2917 	saveclk =
2918 	    bcmsdh_cfg_read(bus->sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR,
2919 			    &err);
2920 	if (!err) {
2921 		bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR,
2922 				 (saveclk | SBSDIO_FORCE_HT), &err);
2923 	}
2924 	if (err) {
2925 		DHD_ERROR(("%s: Failed to force clock for F2: err %d\n",
2926 			   __func__, err));
2927 		goto exit;
2928 	}
2929 
2930 	/* Enable function 2 (frame transfers) */
2931 	W_SDREG((SDPCM_PROT_VERSION << SMB_DATA_VERSION_SHIFT),
2932 		&bus->regs->tosbmailboxdata, retries);
2933 	enable = (SDIO_FUNC_ENABLE_1 | SDIO_FUNC_ENABLE_2);
2934 
2935 	bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_0, SDIOD_CCCR_IOEN, enable, NULL);
2936 
2937 	/* Give the dongle some time to do its thing and set IOR2 */
2938 	dhd_timeout_start(&tmo, DHD_WAIT_F2RDY * 1000);
2939 
2940 	ready = 0;
2941 	while (ready != enable && !dhd_timeout_expired(&tmo))
2942 		ready =
2943 		    bcmsdh_cfg_read(bus->sdh, SDIO_FUNC_0, SDIOD_CCCR_IORDY,
2944 				    NULL);
2945 
2946 	DHD_INFO(("%s: enable 0x%02x, ready 0x%02x (waited %uus)\n",
2947 		  __func__, enable, ready, tmo.elapsed));
2948 
2949 	/* If F2 successfully enabled, set core and enable interrupts */
2950 	if (ready == enable) {
2951 		/* Make sure we're talking to the core. */
2952 		bus->regs = si_setcore(bus->sih, PCMCIA_CORE_ID, 0);
2953 		if (!(bus->regs))
2954 			bus->regs = si_setcore(bus->sih, SDIOD_CORE_ID, 0);
2955 
2956 		/* Set up the interrupt mask and enable interrupts */
2957 		bus->hostintmask = HOSTINTMASK;
2958 		W_SDREG(bus->hostintmask, &bus->regs->hostintmask, retries);
2959 
2960 		bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_1, SBSDIO_WATERMARK,
2961 				 (u8) watermark, &err);
2962 
2963 		/* Set bus state according to enable result */
2964 		dhdp->busstate = DHD_BUS_DATA;
2965 
2966 		/* bcmsdh_intr_unmask(bus->sdh); */
2967 
2968 		bus->intdis = false;
2969 		if (bus->intr) {
2970 			DHD_INTR(("%s: enable SDIO device interrupts\n",
2971 				  __func__));
2972 			bcmsdh_intr_enable(bus->sdh);
2973 		} else {
2974 			DHD_INTR(("%s: disable SDIO interrupts\n", __func__));
2975 			bcmsdh_intr_disable(bus->sdh);
2976 		}
2977 
2978 	}
2979 
2980 	else {
2981 		/* Disable F2 again */
2982 		enable = SDIO_FUNC_ENABLE_1;
2983 		bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_0, SDIOD_CCCR_IOEN, enable,
2984 				 NULL);
2985 	}
2986 
2987 	/* Restore previous clock setting */
2988 	bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR,
2989 			 saveclk, &err);
2990 
2991 	/* If we didn't come up, turn off backplane clock */
2992 	if (dhdp->busstate != DHD_BUS_DATA)
2993 		dhdsdio_clkctl(bus, CLK_NONE, false);
2994 
2995 exit:
2996 	if (enforce_mutex)
2997 		dhd_os_sdunlock(bus->dhd);
2998 
2999 	return ret;
3000 }
3001 
dhdsdio_rxfail(dhd_bus_t * bus,bool abort,bool rtx)3002 static void dhdsdio_rxfail(dhd_bus_t *bus, bool abort, bool rtx)
3003 {
3004 	bcmsdh_info_t *sdh = bus->sdh;
3005 	sdpcmd_regs_t *regs = bus->regs;
3006 	uint retries = 0;
3007 	u16 lastrbc;
3008 	u8 hi, lo;
3009 	int err;
3010 
3011 	DHD_ERROR(("%s: %sterminate frame%s\n", __func__,
3012 		   (abort ? "abort command, " : ""),
3013 		   (rtx ? ", send NAK" : "")));
3014 
3015 	if (abort)
3016 		bcmsdh_abort(sdh, SDIO_FUNC_2);
3017 
3018 	bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_FRAMECTRL, SFC_RF_TERM,
3019 			 &err);
3020 	bus->f1regdata++;
3021 
3022 	/* Wait until the packet has been flushed (device/FIFO stable) */
3023 	for (lastrbc = retries = 0xffff; retries > 0; retries--) {
3024 		hi = bcmsdh_cfg_read(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_RFRAMEBCHI,
3025 				     NULL);
3026 		lo = bcmsdh_cfg_read(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_RFRAMEBCLO,
3027 				     NULL);
3028 		bus->f1regdata += 2;
3029 
3030 		if ((hi == 0) && (lo == 0))
3031 			break;
3032 
3033 		if ((hi > (lastrbc >> 8)) && (lo > (lastrbc & 0x00ff))) {
3034 			DHD_ERROR(("%s: count growing: last 0x%04x now "
3035 				"0x%04x\n",
3036 				__func__, lastrbc, ((hi << 8) + lo)));
3037 		}
3038 		lastrbc = (hi << 8) + lo;
3039 	}
3040 
3041 	if (!retries) {
3042 		DHD_ERROR(("%s: count never zeroed: last 0x%04x\n",
3043 			   __func__, lastrbc));
3044 	} else {
3045 		DHD_INFO(("%s: flush took %d iterations\n", __func__,
3046 			  (0xffff - retries)));
3047 	}
3048 
3049 	if (rtx) {
3050 		bus->rxrtx++;
3051 		W_SDREG(SMB_NAK, &regs->tosbmailbox, retries);
3052 		bus->f1regdata++;
3053 		if (retries <= retry_limit)
3054 			bus->rxskip = true;
3055 	}
3056 
3057 	/* Clear partial in any case */
3058 	bus->nextlen = 0;
3059 
3060 	/* If we can't reach the device, signal failure */
3061 	if (err || bcmsdh_regfail(sdh))
3062 		bus->dhd->busstate = DHD_BUS_DOWN;
3063 }
3064 
3065 static void
dhdsdio_read_control(dhd_bus_t * bus,u8 * hdr,uint len,uint doff)3066 dhdsdio_read_control(dhd_bus_t *bus, u8 *hdr, uint len, uint doff)
3067 {
3068 	bcmsdh_info_t *sdh = bus->sdh;
3069 	uint rdlen, pad;
3070 
3071 	int sdret;
3072 
3073 	DHD_TRACE(("%s: Enter\n", __func__));
3074 
3075 	/* Control data already received in aligned rxctl */
3076 	if ((bus->bus == SPI_BUS) && (!bus->usebufpool))
3077 		goto gotpkt;
3078 
3079 	ASSERT(bus->rxbuf);
3080 	/* Set rxctl for frame (w/optional alignment) */
3081 	bus->rxctl = bus->rxbuf;
3082 	if (dhd_alignctl) {
3083 		bus->rxctl += firstread;
3084 		pad = ((unsigned long)bus->rxctl % DHD_SDALIGN);
3085 		if (pad)
3086 			bus->rxctl += (DHD_SDALIGN - pad);
3087 		bus->rxctl -= firstread;
3088 	}
3089 	ASSERT(bus->rxctl >= bus->rxbuf);
3090 
3091 	/* Copy the already-read portion over */
3092 	memcpy(bus->rxctl, hdr, firstread);
3093 	if (len <= firstread)
3094 		goto gotpkt;
3095 
3096 	/* Copy the full data pkt in gSPI case and process ioctl. */
3097 	if (bus->bus == SPI_BUS) {
3098 		memcpy(bus->rxctl, hdr, len);
3099 		goto gotpkt;
3100 	}
3101 
3102 	/* Raise rdlen to next SDIO block to avoid tail command */
3103 	rdlen = len - firstread;
3104 	if (bus->roundup && bus->blocksize && (rdlen > bus->blocksize)) {
3105 		pad = bus->blocksize - (rdlen % bus->blocksize);
3106 		if ((pad <= bus->roundup) && (pad < bus->blocksize) &&
3107 		    ((len + pad) < bus->dhd->maxctl))
3108 			rdlen += pad;
3109 	} else if (rdlen % DHD_SDALIGN) {
3110 		rdlen += DHD_SDALIGN - (rdlen % DHD_SDALIGN);
3111 	}
3112 
3113 	/* Satisfy length-alignment requirements */
3114 	if (forcealign && (rdlen & (ALIGNMENT - 1)))
3115 		rdlen = roundup(rdlen, ALIGNMENT);
3116 
3117 	/* Drop if the read is too big or it exceeds our maximum */
3118 	if ((rdlen + firstread) > bus->dhd->maxctl) {
3119 		DHD_ERROR(("%s: %d-byte control read exceeds %d-byte buffer\n",
3120 			   __func__, rdlen, bus->dhd->maxctl));
3121 		bus->dhd->rx_errors++;
3122 		dhdsdio_rxfail(bus, false, false);
3123 		goto done;
3124 	}
3125 
3126 	if ((len - doff) > bus->dhd->maxctl) {
3127 		DHD_ERROR(("%s: %d-byte ctl frame (%d-byte ctl data) exceeds "
3128 			"%d-byte limit\n",
3129 			__func__, len, (len - doff), bus->dhd->maxctl));
3130 		bus->dhd->rx_errors++;
3131 		bus->rx_toolong++;
3132 		dhdsdio_rxfail(bus, false, false);
3133 		goto done;
3134 	}
3135 
3136 	/* Read remainder of frame body into the rxctl buffer */
3137 	sdret =
3138 	    dhd_bcmsdh_recv_buf(bus, bcmsdh_cur_sbwad(sdh), SDIO_FUNC_2, F2SYNC,
3139 				(bus->rxctl + firstread), rdlen, NULL, NULL,
3140 				NULL);
3141 	bus->f2rxdata++;
3142 	ASSERT(sdret != BCME_PENDING);
3143 
3144 	/* Control frame failures need retransmission */
3145 	if (sdret < 0) {
3146 		DHD_ERROR(("%s: read %d control bytes failed: %d\n",
3147 			   __func__, rdlen, sdret));
3148 		bus->rxc_errors++;	/* dhd.rx_ctlerrs is higher level */
3149 		dhdsdio_rxfail(bus, true, true);
3150 		goto done;
3151 	}
3152 
3153 gotpkt:
3154 
3155 #ifdef DHD_DEBUG
3156 	if (DHD_BYTES_ON() && DHD_CTL_ON())
3157 		prhex("RxCtrl", bus->rxctl, len);
3158 #endif
3159 
3160 	/* Point to valid data and indicate its length */
3161 	bus->rxctl += doff;
3162 	bus->rxlen = len - doff;
3163 
3164 done:
3165 	/* Awake any waiters */
3166 	dhd_os_ioctl_resp_wake(bus->dhd);
3167 }
3168 
dhdsdio_rxglom(dhd_bus_t * bus,u8 rxseq)3169 static u8 dhdsdio_rxglom(dhd_bus_t *bus, u8 rxseq)
3170 {
3171 	u16 dlen, totlen;
3172 	u8 *dptr, num = 0;
3173 
3174 	u16 sublen, check;
3175 	struct sk_buff *pfirst, *plast, *pnext, *save_pfirst;
3176 
3177 	int errcode;
3178 	u8 chan, seq, doff, sfdoff;
3179 	u8 txmax;
3180 
3181 	int ifidx = 0;
3182 	bool usechain = bus->use_rxchain;
3183 
3184 	/* If packets, issue read(s) and send up packet chain */
3185 	/* Return sequence numbers consumed? */
3186 
3187 	DHD_TRACE(("dhdsdio_rxglom: start: glomd %p glom %p\n", bus->glomd,
3188 		   bus->glom));
3189 
3190 	/* If there's a descriptor, generate the packet chain */
3191 	if (bus->glomd) {
3192 		dhd_os_sdlock_rxq(bus->dhd);
3193 
3194 		pfirst = plast = pnext = NULL;
3195 		dlen = (u16) (bus->glomd->len);
3196 		dptr = bus->glomd->data;
3197 		if (!dlen || (dlen & 1)) {
3198 			DHD_ERROR(("%s: bad glomd len(%d), ignore descriptor\n",
3199 			__func__, dlen));
3200 			dlen = 0;
3201 		}
3202 
3203 		for (totlen = num = 0; dlen; num++) {
3204 			/* Get (and move past) next length */
3205 			sublen = get_unaligned_le16(dptr);
3206 			dlen -= sizeof(u16);
3207 			dptr += sizeof(u16);
3208 			if ((sublen < SDPCM_HDRLEN) ||
3209 			    ((num == 0) && (sublen < (2 * SDPCM_HDRLEN)))) {
3210 				DHD_ERROR(("%s: descriptor len %d bad: %d\n",
3211 					   __func__, num, sublen));
3212 				pnext = NULL;
3213 				break;
3214 			}
3215 			if (sublen % DHD_SDALIGN) {
3216 				DHD_ERROR(("%s: sublen %d not multiple of %d\n",
3217 				__func__, sublen, DHD_SDALIGN));
3218 				usechain = false;
3219 			}
3220 			totlen += sublen;
3221 
3222 			/* For last frame, adjust read len so total
3223 				 is a block multiple */
3224 			if (!dlen) {
3225 				sublen +=
3226 				    (roundup(totlen, bus->blocksize) - totlen);
3227 				totlen = roundup(totlen, bus->blocksize);
3228 			}
3229 
3230 			/* Allocate/chain packet for next subframe */
3231 			pnext = pkt_buf_get_skb(sublen + DHD_SDALIGN);
3232 			if (pnext == NULL) {
3233 				DHD_ERROR(("%s: pkt_buf_get_skb failed, num %d len %d\n",
3234 					   __func__, num, sublen));
3235 				break;
3236 			}
3237 			ASSERT(!(pnext->prev));
3238 			if (!pfirst) {
3239 				ASSERT(!plast);
3240 				pfirst = plast = pnext;
3241 			} else {
3242 				ASSERT(plast);
3243 				plast->next = pnext;
3244 				plast = pnext;
3245 			}
3246 
3247 			/* Adhere to start alignment requirements */
3248 			PKTALIGN(pnext, sublen, DHD_SDALIGN);
3249 		}
3250 
3251 		/* If all allocations succeeded, save packet chain
3252 			 in bus structure */
3253 		if (pnext) {
3254 			DHD_GLOM(("%s: allocated %d-byte packet chain for %d "
3255 				"subframes\n", __func__, totlen, num));
3256 			if (DHD_GLOM_ON() && bus->nextlen) {
3257 				if (totlen != bus->nextlen) {
3258 					DHD_GLOM(("%s: glomdesc mismatch: nextlen %d glomdesc %d " "rxseq %d\n",
3259 						__func__, bus->nextlen,
3260 						totlen, rxseq));
3261 				}
3262 			}
3263 			bus->glom = pfirst;
3264 			pfirst = pnext = NULL;
3265 		} else {
3266 			if (pfirst)
3267 				pkt_buf_free_skb(pfirst);
3268 			bus->glom = NULL;
3269 			num = 0;
3270 		}
3271 
3272 		/* Done with descriptor packet */
3273 		pkt_buf_free_skb(bus->glomd);
3274 		bus->glomd = NULL;
3275 		bus->nextlen = 0;
3276 
3277 		dhd_os_sdunlock_rxq(bus->dhd);
3278 	}
3279 
3280 	/* Ok -- either we just generated a packet chain,
3281 		 or had one from before */
3282 	if (bus->glom) {
3283 		if (DHD_GLOM_ON()) {
3284 			DHD_GLOM(("%s: try superframe read, packet chain:\n",
3285 				__func__));
3286 			for (pnext = bus->glom; pnext; pnext = pnext->next) {
3287 				DHD_GLOM(("    %p: %p len 0x%04x (%d)\n",
3288 					  pnext, (u8 *) (pnext->data),
3289 					  pnext->len, pnext->len));
3290 			}
3291 		}
3292 
3293 		pfirst = bus->glom;
3294 		dlen = (u16) pkttotlen(pfirst);
3295 
3296 		/* Do an SDIO read for the superframe.  Configurable iovar to
3297 		 * read directly into the chained packet, or allocate a large
3298 		 * packet and and copy into the chain.
3299 		 */
3300 		if (usechain) {
3301 			errcode = dhd_bcmsdh_recv_buf(bus,
3302 						      bcmsdh_cur_sbwad
3303 						      (bus->sdh), SDIO_FUNC_2,
3304 						      F2SYNC,
3305 						      (u8 *) pfirst->data,
3306 						      dlen, pfirst, NULL, NULL);
3307 		} else if (bus->dataptr) {
3308 			errcode = dhd_bcmsdh_recv_buf(bus,
3309 						      bcmsdh_cur_sbwad
3310 						      (bus->sdh), SDIO_FUNC_2,
3311 						      F2SYNC, bus->dataptr,
3312 						      dlen, NULL, NULL, NULL);
3313 			sublen =
3314 			    (u16) pktfrombuf(pfirst, 0, dlen,
3315 						bus->dataptr);
3316 			if (sublen != dlen) {
3317 				DHD_ERROR(("%s: FAILED TO COPY, dlen %d sublen %d\n",
3318 					__func__, dlen, sublen));
3319 				errcode = -1;
3320 			}
3321 			pnext = NULL;
3322 		} else {
3323 			DHD_ERROR(("COULDN'T ALLOC %d-BYTE GLOM, FORCE FAILURE\n",
3324 				dlen));
3325 			errcode = -1;
3326 		}
3327 		bus->f2rxdata++;
3328 		ASSERT(errcode != BCME_PENDING);
3329 
3330 		/* On failure, kill the superframe, allow a couple retries */
3331 		if (errcode < 0) {
3332 			DHD_ERROR(("%s: glom read of %d bytes failed: %d\n",
3333 				   __func__, dlen, errcode));
3334 			bus->dhd->rx_errors++;
3335 
3336 			if (bus->glomerr++ < 3) {
3337 				dhdsdio_rxfail(bus, true, true);
3338 			} else {
3339 				bus->glomerr = 0;
3340 				dhdsdio_rxfail(bus, true, false);
3341 				dhd_os_sdlock_rxq(bus->dhd);
3342 				pkt_buf_free_skb(bus->glom);
3343 				dhd_os_sdunlock_rxq(bus->dhd);
3344 				bus->rxglomfail++;
3345 				bus->glom = NULL;
3346 			}
3347 			return 0;
3348 		}
3349 #ifdef DHD_DEBUG
3350 		if (DHD_GLOM_ON()) {
3351 			prhex("SUPERFRAME", pfirst->data,
3352 			      min_t(int, pfirst->len, 48));
3353 		}
3354 #endif
3355 
3356 		/* Validate the superframe header */
3357 		dptr = (u8 *) (pfirst->data);
3358 		sublen = get_unaligned_le16(dptr);
3359 		check = get_unaligned_le16(dptr + sizeof(u16));
3360 
3361 		chan = SDPCM_PACKET_CHANNEL(&dptr[SDPCM_FRAMETAG_LEN]);
3362 		seq = SDPCM_PACKET_SEQUENCE(&dptr[SDPCM_FRAMETAG_LEN]);
3363 		bus->nextlen = dptr[SDPCM_FRAMETAG_LEN + SDPCM_NEXTLEN_OFFSET];
3364 		if ((bus->nextlen << 4) > MAX_RX_DATASZ) {
3365 			DHD_INFO(("%s: nextlen too large (%d) seq %d\n",
3366 				__func__, bus->nextlen, seq));
3367 			bus->nextlen = 0;
3368 		}
3369 		doff = SDPCM_DOFFSET_VALUE(&dptr[SDPCM_FRAMETAG_LEN]);
3370 		txmax = SDPCM_WINDOW_VALUE(&dptr[SDPCM_FRAMETAG_LEN]);
3371 
3372 		errcode = 0;
3373 		if ((u16)~(sublen ^ check)) {
3374 			DHD_ERROR(("%s (superframe): HW hdr error: len/check "
3375 				"0x%04x/0x%04x\n", __func__, sublen, check));
3376 			errcode = -1;
3377 		} else if (roundup(sublen, bus->blocksize) != dlen) {
3378 			DHD_ERROR(("%s (superframe): len 0x%04x, rounded "
3379 				"0x%04x, expect 0x%04x\n",
3380 				__func__, sublen,
3381 				roundup(sublen, bus->blocksize), dlen));
3382 			errcode = -1;
3383 		} else if (SDPCM_PACKET_CHANNEL(&dptr[SDPCM_FRAMETAG_LEN]) !=
3384 			   SDPCM_GLOM_CHANNEL) {
3385 			DHD_ERROR(("%s (superframe): bad channel %d\n",
3386 				   __func__,
3387 				   SDPCM_PACKET_CHANNEL(&dptr
3388 							[SDPCM_FRAMETAG_LEN])));
3389 			errcode = -1;
3390 		} else if (SDPCM_GLOMDESC(&dptr[SDPCM_FRAMETAG_LEN])) {
3391 			DHD_ERROR(("%s (superframe): got second descriptor?\n",
3392 				   __func__));
3393 			errcode = -1;
3394 		} else if ((doff < SDPCM_HDRLEN) ||
3395 			   (doff > (pfirst->len - SDPCM_HDRLEN))) {
3396 			DHD_ERROR(("%s (superframe): Bad data offset %d: HW %d "
3397 				"pkt %d min %d\n",
3398 				__func__, doff, sublen,
3399 				pfirst->len, SDPCM_HDRLEN));
3400 			errcode = -1;
3401 		}
3402 
3403 		/* Check sequence number of superframe SW header */
3404 		if (rxseq != seq) {
3405 			DHD_INFO(("%s: (superframe) rx_seq %d, expected %d\n",
3406 				  __func__, seq, rxseq));
3407 			bus->rx_badseq++;
3408 			rxseq = seq;
3409 		}
3410 
3411 		/* Check window for sanity */
3412 		if ((u8) (txmax - bus->tx_seq) > 0x40) {
3413 			DHD_ERROR(("%s: unlikely tx max %d with tx_seq %d\n",
3414 				__func__, txmax, bus->tx_seq));
3415 			txmax = bus->tx_seq + 2;
3416 		}
3417 		bus->tx_max = txmax;
3418 
3419 		/* Remove superframe header, remember offset */
3420 		skb_pull(pfirst, doff);
3421 		sfdoff = doff;
3422 
3423 		/* Validate all the subframe headers */
3424 		for (num = 0, pnext = pfirst; pnext && !errcode;
3425 		     num++, pnext = pnext->next) {
3426 			dptr = (u8 *) (pnext->data);
3427 			dlen = (u16) (pnext->len);
3428 			sublen = get_unaligned_le16(dptr);
3429 			check = get_unaligned_le16(dptr + sizeof(u16));
3430 			chan = SDPCM_PACKET_CHANNEL(&dptr[SDPCM_FRAMETAG_LEN]);
3431 			doff = SDPCM_DOFFSET_VALUE(&dptr[SDPCM_FRAMETAG_LEN]);
3432 #ifdef DHD_DEBUG
3433 			if (DHD_GLOM_ON())
3434 				prhex("subframe", dptr, 32);
3435 #endif
3436 
3437 			if ((u16)~(sublen ^ check)) {
3438 				DHD_ERROR(("%s (subframe %d): HW hdr error: "
3439 					   "len/check 0x%04x/0x%04x\n",
3440 					   __func__, num, sublen, check));
3441 				errcode = -1;
3442 			} else if ((sublen > dlen) || (sublen < SDPCM_HDRLEN)) {
3443 				DHD_ERROR(("%s (subframe %d): length mismatch: "
3444 					   "len 0x%04x, expect 0x%04x\n",
3445 					   __func__, num, sublen, dlen));
3446 				errcode = -1;
3447 			} else if ((chan != SDPCM_DATA_CHANNEL) &&
3448 				   (chan != SDPCM_EVENT_CHANNEL)) {
3449 				DHD_ERROR(("%s (subframe %d): bad channel %d\n",
3450 					   __func__, num, chan));
3451 				errcode = -1;
3452 			} else if ((doff < SDPCM_HDRLEN) || (doff > sublen)) {
3453 				DHD_ERROR(("%s (subframe %d): Bad data offset %d: HW %d min %d\n",
3454 					__func__, num, doff, sublen,
3455 					SDPCM_HDRLEN));
3456 				errcode = -1;
3457 			}
3458 		}
3459 
3460 		if (errcode) {
3461 			/* Terminate frame on error, request
3462 				 a couple retries */
3463 			if (bus->glomerr++ < 3) {
3464 				/* Restore superframe header space */
3465 				skb_push(pfirst, sfdoff);
3466 				dhdsdio_rxfail(bus, true, true);
3467 			} else {
3468 				bus->glomerr = 0;
3469 				dhdsdio_rxfail(bus, true, false);
3470 				dhd_os_sdlock_rxq(bus->dhd);
3471 				pkt_buf_free_skb(bus->glom);
3472 				dhd_os_sdunlock_rxq(bus->dhd);
3473 				bus->rxglomfail++;
3474 				bus->glom = NULL;
3475 			}
3476 			bus->nextlen = 0;
3477 			return 0;
3478 		}
3479 
3480 		/* Basic SD framing looks ok - process each packet (header) */
3481 		save_pfirst = pfirst;
3482 		bus->glom = NULL;
3483 		plast = NULL;
3484 
3485 		dhd_os_sdlock_rxq(bus->dhd);
3486 		for (num = 0; pfirst; rxseq++, pfirst = pnext) {
3487 			pnext = pfirst->next;
3488 			pfirst->next = NULL;
3489 
3490 			dptr = (u8 *) (pfirst->data);
3491 			sublen = get_unaligned_le16(dptr);
3492 			chan = SDPCM_PACKET_CHANNEL(&dptr[SDPCM_FRAMETAG_LEN]);
3493 			seq = SDPCM_PACKET_SEQUENCE(&dptr[SDPCM_FRAMETAG_LEN]);
3494 			doff = SDPCM_DOFFSET_VALUE(&dptr[SDPCM_FRAMETAG_LEN]);
3495 
3496 			DHD_GLOM(("%s: Get subframe %d, %p(%p/%d), sublen %d "
3497 				"chan %d seq %d\n",
3498 				__func__, num, pfirst, pfirst->data,
3499 				pfirst->len, sublen, chan, seq));
3500 
3501 			ASSERT((chan == SDPCM_DATA_CHANNEL)
3502 			       || (chan == SDPCM_EVENT_CHANNEL));
3503 
3504 			if (rxseq != seq) {
3505 				DHD_GLOM(("%s: rx_seq %d, expected %d\n",
3506 					  __func__, seq, rxseq));
3507 				bus->rx_badseq++;
3508 				rxseq = seq;
3509 			}
3510 #ifdef DHD_DEBUG
3511 			if (DHD_BYTES_ON() && DHD_DATA_ON())
3512 				prhex("Rx Subframe Data", dptr, dlen);
3513 #endif
3514 
3515 			__skb_trim(pfirst, sublen);
3516 			skb_pull(pfirst, doff);
3517 
3518 			if (pfirst->len == 0) {
3519 				pkt_buf_free_skb(pfirst);
3520 				if (plast) {
3521 					plast->next = pnext;
3522 				} else {
3523 					ASSERT(save_pfirst == pfirst);
3524 					save_pfirst = pnext;
3525 				}
3526 				continue;
3527 			} else if (dhd_prot_hdrpull(bus->dhd, &ifidx, pfirst) !=
3528 				   0) {
3529 				DHD_ERROR(("%s: rx protocol error\n",
3530 					   __func__));
3531 				bus->dhd->rx_errors++;
3532 				pkt_buf_free_skb(pfirst);
3533 				if (plast) {
3534 					plast->next = pnext;
3535 				} else {
3536 					ASSERT(save_pfirst == pfirst);
3537 					save_pfirst = pnext;
3538 				}
3539 				continue;
3540 			}
3541 
3542 			/* this packet will go up, link back into
3543 				 chain and count it */
3544 			pfirst->next = pnext;
3545 			plast = pfirst;
3546 			num++;
3547 
3548 #ifdef DHD_DEBUG
3549 			if (DHD_GLOM_ON()) {
3550 				DHD_GLOM(("%s subframe %d to stack, %p(%p/%d) "
3551 				"nxt/lnk %p/%p\n",
3552 				__func__, num, pfirst, pfirst->data,
3553 				pfirst->len, pfirst->next,
3554 				pfirst->prev));
3555 				prhex("", (u8 *) pfirst->data,
3556 				      min_t(int, pfirst->len, 32));
3557 			}
3558 #endif				/* DHD_DEBUG */
3559 		}
3560 		dhd_os_sdunlock_rxq(bus->dhd);
3561 		if (num) {
3562 			dhd_os_sdunlock(bus->dhd);
3563 			dhd_rx_frame(bus->dhd, ifidx, save_pfirst, num);
3564 			dhd_os_sdlock(bus->dhd);
3565 		}
3566 
3567 		bus->rxglomframes++;
3568 		bus->rxglompkts += num;
3569 	}
3570 	return num;
3571 }
3572 
3573 /* Return true if there may be more frames to read */
dhdsdio_readframes(dhd_bus_t * bus,uint maxframes,bool * finished)3574 static uint dhdsdio_readframes(dhd_bus_t *bus, uint maxframes, bool *finished)
3575 {
3576 	bcmsdh_info_t *sdh = bus->sdh;
3577 
3578 	u16 len, check;	/* Extracted hardware header fields */
3579 	u8 chan, seq, doff;	/* Extracted software header fields */
3580 	u8 fcbits;		/* Extracted fcbits from software header */
3581 	u8 delta;
3582 
3583 	struct sk_buff *pkt;		/* Packet for event or data frames */
3584 	u16 pad;		/* Number of pad bytes to read */
3585 	u16 rdlen;		/* Total number of bytes to read */
3586 	u8 rxseq;		/* Next sequence number to expect */
3587 	uint rxleft = 0;	/* Remaining number of frames allowed */
3588 	int sdret;		/* Return code from bcmsdh calls */
3589 	u8 txmax;		/* Maximum tx sequence offered */
3590 	bool len_consistent;	/* Result of comparing readahead len and
3591 					 len from hw-hdr */
3592 	u8 *rxbuf;
3593 	int ifidx = 0;
3594 	uint rxcount = 0;	/* Total frames read */
3595 
3596 #if defined(DHD_DEBUG) || defined(SDTEST)
3597 	bool sdtest = false;	/* To limit message spew from test mode */
3598 #endif
3599 
3600 	DHD_TRACE(("%s: Enter\n", __func__));
3601 
3602 	ASSERT(maxframes);
3603 
3604 #ifdef SDTEST
3605 	/* Allow pktgen to override maxframes */
3606 	if (bus->pktgen_count && (bus->pktgen_mode == DHD_PKTGEN_RECV)) {
3607 		maxframes = bus->pktgen_count;
3608 		sdtest = true;
3609 	}
3610 #endif
3611 
3612 	/* Not finished unless we encounter no more frames indication */
3613 	*finished = false;
3614 
3615 	for (rxseq = bus->rx_seq, rxleft = maxframes;
3616 	     !bus->rxskip && rxleft && bus->dhd->busstate != DHD_BUS_DOWN;
3617 	     rxseq++, rxleft--) {
3618 
3619 		/* Handle glomming separately */
3620 		if (bus->glom || bus->glomd) {
3621 			u8 cnt;
3622 			DHD_GLOM(("%s: calling rxglom: glomd %p, glom %p\n",
3623 				  __func__, bus->glomd, bus->glom));
3624 			cnt = dhdsdio_rxglom(bus, rxseq);
3625 			DHD_GLOM(("%s: rxglom returned %d\n", __func__, cnt));
3626 			rxseq += cnt - 1;
3627 			rxleft = (rxleft > cnt) ? (rxleft - cnt) : 1;
3628 			continue;
3629 		}
3630 
3631 		/* Try doing single read if we can */
3632 		if (dhd_readahead && bus->nextlen) {
3633 			u16 nextlen = bus->nextlen;
3634 			bus->nextlen = 0;
3635 
3636 			if (bus->bus == SPI_BUS) {
3637 				rdlen = len = nextlen;
3638 			} else {
3639 				rdlen = len = nextlen << 4;
3640 
3641 				/* Pad read to blocksize for efficiency */
3642 				if (bus->roundup && bus->blocksize
3643 				    && (rdlen > bus->blocksize)) {
3644 					pad =
3645 					    bus->blocksize -
3646 					    (rdlen % bus->blocksize);
3647 					if ((pad <= bus->roundup)
3648 					    && (pad < bus->blocksize)
3649 					    && ((rdlen + pad + firstread) <
3650 						MAX_RX_DATASZ))
3651 						rdlen += pad;
3652 				} else if (rdlen % DHD_SDALIGN) {
3653 					rdlen +=
3654 					    DHD_SDALIGN - (rdlen % DHD_SDALIGN);
3655 				}
3656 			}
3657 
3658 			/* We use bus->rxctl buffer in WinXP for initial
3659 			 * control pkt receives.
3660 			 * Later we use buffer-poll for data as well
3661 			 * as control packets.
3662 			 * This is required because dhd receives full
3663 			 * frame in gSPI unlike SDIO.
3664 			 * After the frame is received we have to
3665 			 * distinguish whether it is data
3666 			 * or non-data frame.
3667 			 */
3668 			/* Allocate a packet buffer */
3669 			dhd_os_sdlock_rxq(bus->dhd);
3670 			pkt = pkt_buf_get_skb(rdlen + DHD_SDALIGN);
3671 			if (!pkt) {
3672 				if (bus->bus == SPI_BUS) {
3673 					bus->usebufpool = false;
3674 					bus->rxctl = bus->rxbuf;
3675 					if (dhd_alignctl) {
3676 						bus->rxctl += firstread;
3677 						pad = ((unsigned long)bus->rxctl %
3678 						      DHD_SDALIGN);
3679 						if (pad)
3680 							bus->rxctl +=
3681 							    (DHD_SDALIGN - pad);
3682 						bus->rxctl -= firstread;
3683 					}
3684 					ASSERT(bus->rxctl >= bus->rxbuf);
3685 					rxbuf = bus->rxctl;
3686 					/* Read the entire frame */
3687 					sdret = dhd_bcmsdh_recv_buf(bus,
3688 						    bcmsdh_cur_sbwad
3689 						    (sdh),
3690 						    SDIO_FUNC_2,
3691 						    F2SYNC,
3692 						    rxbuf,
3693 						    rdlen, NULL,
3694 						    NULL, NULL);
3695 					bus->f2rxdata++;
3696 					ASSERT(sdret != BCME_PENDING);
3697 
3698 					/* Control frame failures need
3699 					 retransmission */
3700 					if (sdret < 0) {
3701 						DHD_ERROR(("%s: read %d control bytes failed: %d\n",
3702 							__func__,
3703 							rdlen, sdret));
3704 						/* dhd.rx_ctlerrs is higher */
3705 						bus->rxc_errors++;
3706 						dhd_os_sdunlock_rxq(bus->dhd);
3707 						dhdsdio_rxfail(bus, true,
3708 						       (bus->bus ==
3709 							SPI_BUS) ? false
3710 						       : true);
3711 						continue;
3712 					}
3713 				} else {
3714 					/* Give up on data,
3715 					request rtx of events */
3716 					DHD_ERROR(("%s (nextlen): pkt_buf_get_skb failed: len %d rdlen %d " "expected rxseq %d\n",
3717 						__func__, len, rdlen, rxseq));
3718 					/* Just go try again w/normal
3719 					header read */
3720 					dhd_os_sdunlock_rxq(bus->dhd);
3721 					continue;
3722 				}
3723 			} else {
3724 				if (bus->bus == SPI_BUS)
3725 					bus->usebufpool = true;
3726 
3727 				ASSERT(!(pkt->prev));
3728 				PKTALIGN(pkt, rdlen, DHD_SDALIGN);
3729 				rxbuf = (u8 *) (pkt->data);
3730 				/* Read the entire frame */
3731 				sdret =
3732 				    dhd_bcmsdh_recv_buf(bus,
3733 						bcmsdh_cur_sbwad(sdh),
3734 						SDIO_FUNC_2, F2SYNC,
3735 						rxbuf, rdlen, pkt, NULL,
3736 						NULL);
3737 				bus->f2rxdata++;
3738 				ASSERT(sdret != BCME_PENDING);
3739 
3740 				if (sdret < 0) {
3741 					DHD_ERROR(("%s (nextlen): read %d bytes failed: %d\n",
3742 						__func__, rdlen, sdret));
3743 					pkt_buf_free_skb(pkt);
3744 					bus->dhd->rx_errors++;
3745 					dhd_os_sdunlock_rxq(bus->dhd);
3746 					/* Force retry w/normal header read.
3747 					 * Don't attempt NAK for
3748 					 * gSPI
3749 					 */
3750 					dhdsdio_rxfail(bus, true,
3751 						       (bus->bus ==
3752 							SPI_BUS) ? false :
3753 						       true);
3754 					continue;
3755 				}
3756 			}
3757 			dhd_os_sdunlock_rxq(bus->dhd);
3758 
3759 			/* Now check the header */
3760 			memcpy(bus->rxhdr, rxbuf, SDPCM_HDRLEN);
3761 
3762 			/* Extract hardware header fields */
3763 			len = get_unaligned_le16(bus->rxhdr);
3764 			check = get_unaligned_le16(bus->rxhdr + sizeof(u16));
3765 
3766 			/* All zeros means readahead info was bad */
3767 			if (!(len | check)) {
3768 				DHD_INFO(("%s (nextlen): read zeros in HW "
3769 					"header???\n", __func__));
3770 				dhd_os_sdlock_rxq(bus->dhd);
3771 				PKTFREE2();
3772 				dhd_os_sdunlock_rxq(bus->dhd);
3773 				GSPI_PR55150_BAILOUT;
3774 				continue;
3775 			}
3776 
3777 			/* Validate check bytes */
3778 			if ((u16)~(len ^ check)) {
3779 				DHD_ERROR(("%s (nextlen): HW hdr error: nextlen/len/check" " 0x%04x/0x%04x/0x%04x\n",
3780 					__func__, nextlen, len, check));
3781 				dhd_os_sdlock_rxq(bus->dhd);
3782 				PKTFREE2();
3783 				dhd_os_sdunlock_rxq(bus->dhd);
3784 				bus->rx_badhdr++;
3785 				dhdsdio_rxfail(bus, false, false);
3786 				GSPI_PR55150_BAILOUT;
3787 				continue;
3788 			}
3789 
3790 			/* Validate frame length */
3791 			if (len < SDPCM_HDRLEN) {
3792 				DHD_ERROR(("%s (nextlen): HW hdr length "
3793 					"invalid: %d\n", __func__, len));
3794 				dhd_os_sdlock_rxq(bus->dhd);
3795 				PKTFREE2();
3796 				dhd_os_sdunlock_rxq(bus->dhd);
3797 				GSPI_PR55150_BAILOUT;
3798 				continue;
3799 			}
3800 
3801 			/* Check for consistency withreadahead info */
3802 			len_consistent = (nextlen != (roundup(len, 16) >> 4));
3803 			if (len_consistent) {
3804 				/* Mismatch, force retry w/normal
3805 					header (may be >4K) */
3806 				DHD_ERROR(("%s (nextlen): mismatch, nextlen %d len %d rnd %d; " "expected rxseq %d\n",
3807 					__func__, nextlen,
3808 					len, roundup(len, 16), rxseq));
3809 				dhd_os_sdlock_rxq(bus->dhd);
3810 				PKTFREE2();
3811 				dhd_os_sdunlock_rxq(bus->dhd);
3812 				dhdsdio_rxfail(bus, true,
3813 					       (bus->bus ==
3814 						SPI_BUS) ? false : true);
3815 				GSPI_PR55150_BAILOUT;
3816 				continue;
3817 			}
3818 
3819 			/* Extract software header fields */
3820 			chan =
3821 			    SDPCM_PACKET_CHANNEL(&bus->rxhdr
3822 						 [SDPCM_FRAMETAG_LEN]);
3823 			seq =
3824 			    SDPCM_PACKET_SEQUENCE(&bus->rxhdr
3825 						  [SDPCM_FRAMETAG_LEN]);
3826 			doff =
3827 			    SDPCM_DOFFSET_VALUE(&bus->rxhdr
3828 						[SDPCM_FRAMETAG_LEN]);
3829 			txmax =
3830 			    SDPCM_WINDOW_VALUE(&bus->rxhdr[SDPCM_FRAMETAG_LEN]);
3831 
3832 			bus->nextlen =
3833 			    bus->rxhdr[SDPCM_FRAMETAG_LEN +
3834 				       SDPCM_NEXTLEN_OFFSET];
3835 			if ((bus->nextlen << 4) > MAX_RX_DATASZ) {
3836 				DHD_INFO(("%s (nextlen): got frame w/nextlen too large" " (%d), seq %d\n",
3837 					__func__, bus->nextlen, seq));
3838 				bus->nextlen = 0;
3839 			}
3840 
3841 			bus->dhd->rx_readahead_cnt++;
3842 			/* Handle Flow Control */
3843 			fcbits =
3844 			    SDPCM_FCMASK_VALUE(&bus->rxhdr[SDPCM_FRAMETAG_LEN]);
3845 
3846 			delta = 0;
3847 			if (~bus->flowcontrol & fcbits) {
3848 				bus->fc_xoff++;
3849 				delta = 1;
3850 			}
3851 			if (bus->flowcontrol & ~fcbits) {
3852 				bus->fc_xon++;
3853 				delta = 1;
3854 			}
3855 
3856 			if (delta) {
3857 				bus->fc_rcvd++;
3858 				bus->flowcontrol = fcbits;
3859 			}
3860 
3861 			/* Check and update sequence number */
3862 			if (rxseq != seq) {
3863 				DHD_INFO(("%s (nextlen): rx_seq %d, expected "
3864 					"%d\n", __func__, seq, rxseq));
3865 				bus->rx_badseq++;
3866 				rxseq = seq;
3867 			}
3868 
3869 			/* Check window for sanity */
3870 			if ((u8) (txmax - bus->tx_seq) > 0x40) {
3871 				DHD_ERROR(("%s: got unlikely tx max %d with "
3872 					"tx_seq %d\n",
3873 					__func__, txmax, bus->tx_seq));
3874 				txmax = bus->tx_seq + 2;
3875 			}
3876 			bus->tx_max = txmax;
3877 
3878 #ifdef DHD_DEBUG
3879 			if (DHD_BYTES_ON() && DHD_DATA_ON())
3880 				prhex("Rx Data", rxbuf, len);
3881 			else if (DHD_HDRS_ON())
3882 				prhex("RxHdr", bus->rxhdr, SDPCM_HDRLEN);
3883 #endif
3884 
3885 			if (chan == SDPCM_CONTROL_CHANNEL) {
3886 				if (bus->bus == SPI_BUS) {
3887 					dhdsdio_read_control(bus, rxbuf, len,
3888 							     doff);
3889 					if (bus->usebufpool) {
3890 						dhd_os_sdlock_rxq(bus->dhd);
3891 						pkt_buf_free_skb(pkt);
3892 						dhd_os_sdunlock_rxq(bus->dhd);
3893 					}
3894 					continue;
3895 				} else {
3896 					DHD_ERROR(("%s (nextlen): readahead on control" " packet %d?\n",
3897 						__func__, seq));
3898 					/* Force retry w/normal header read */
3899 					bus->nextlen = 0;
3900 					dhdsdio_rxfail(bus, false, true);
3901 					dhd_os_sdlock_rxq(bus->dhd);
3902 					PKTFREE2();
3903 					dhd_os_sdunlock_rxq(bus->dhd);
3904 					continue;
3905 				}
3906 			}
3907 
3908 			if ((bus->bus == SPI_BUS) && !bus->usebufpool) {
3909 				DHD_ERROR(("Received %d bytes on %d channel. Running out of " "rx pktbuf's or not yet malloced.\n",
3910 					len, chan));
3911 				continue;
3912 			}
3913 
3914 			/* Validate data offset */
3915 			if ((doff < SDPCM_HDRLEN) || (doff > len)) {
3916 				DHD_ERROR(("%s (nextlen): bad data offset %d: HW len %d min %d\n",
3917 					__func__, doff, len, SDPCM_HDRLEN));
3918 				dhd_os_sdlock_rxq(bus->dhd);
3919 				PKTFREE2();
3920 				dhd_os_sdunlock_rxq(bus->dhd);
3921 				ASSERT(0);
3922 				dhdsdio_rxfail(bus, false, false);
3923 				continue;
3924 			}
3925 
3926 			/* All done with this one -- now deliver the packet */
3927 			goto deliver;
3928 		}
3929 		/* gSPI frames should not be handled in fractions */
3930 		if (bus->bus == SPI_BUS)
3931 			break;
3932 
3933 		/* Read frame header (hardware and software) */
3934 		sdret =
3935 		    dhd_bcmsdh_recv_buf(bus, bcmsdh_cur_sbwad(sdh), SDIO_FUNC_2,
3936 					F2SYNC, bus->rxhdr, firstread, NULL,
3937 					NULL, NULL);
3938 		bus->f2rxhdrs++;
3939 		ASSERT(sdret != BCME_PENDING);
3940 
3941 		if (sdret < 0) {
3942 			DHD_ERROR(("%s: RXHEADER FAILED: %d\n", __func__,
3943 				   sdret));
3944 			bus->rx_hdrfail++;
3945 			dhdsdio_rxfail(bus, true, true);
3946 			continue;
3947 		}
3948 #ifdef DHD_DEBUG
3949 		if (DHD_BYTES_ON() || DHD_HDRS_ON())
3950 			prhex("RxHdr", bus->rxhdr, SDPCM_HDRLEN);
3951 #endif
3952 
3953 		/* Extract hardware header fields */
3954 		len = get_unaligned_le16(bus->rxhdr);
3955 		check = get_unaligned_le16(bus->rxhdr + sizeof(u16));
3956 
3957 		/* All zeros means no more frames */
3958 		if (!(len | check)) {
3959 			*finished = true;
3960 			break;
3961 		}
3962 
3963 		/* Validate check bytes */
3964 		if ((u16) ~(len ^ check)) {
3965 			DHD_ERROR(("%s: HW hdr err: len/check 0x%04x/0x%04x\n",
3966 				__func__, len, check));
3967 			bus->rx_badhdr++;
3968 			dhdsdio_rxfail(bus, false, false);
3969 			continue;
3970 		}
3971 
3972 		/* Validate frame length */
3973 		if (len < SDPCM_HDRLEN) {
3974 			DHD_ERROR(("%s: HW hdr length invalid: %d\n",
3975 				   __func__, len));
3976 			continue;
3977 		}
3978 
3979 		/* Extract software header fields */
3980 		chan = SDPCM_PACKET_CHANNEL(&bus->rxhdr[SDPCM_FRAMETAG_LEN]);
3981 		seq = SDPCM_PACKET_SEQUENCE(&bus->rxhdr[SDPCM_FRAMETAG_LEN]);
3982 		doff = SDPCM_DOFFSET_VALUE(&bus->rxhdr[SDPCM_FRAMETAG_LEN]);
3983 		txmax = SDPCM_WINDOW_VALUE(&bus->rxhdr[SDPCM_FRAMETAG_LEN]);
3984 
3985 		/* Validate data offset */
3986 		if ((doff < SDPCM_HDRLEN) || (doff > len)) {
3987 			DHD_ERROR(("%s: Bad data offset %d: HW len %d, min %d "
3988 				"seq %d\n",
3989 				__func__, doff, len, SDPCM_HDRLEN, seq));
3990 			bus->rx_badhdr++;
3991 			ASSERT(0);
3992 			dhdsdio_rxfail(bus, false, false);
3993 			continue;
3994 		}
3995 
3996 		/* Save the readahead length if there is one */
3997 		bus->nextlen =
3998 		    bus->rxhdr[SDPCM_FRAMETAG_LEN + SDPCM_NEXTLEN_OFFSET];
3999 		if ((bus->nextlen << 4) > MAX_RX_DATASZ) {
4000 			DHD_INFO(("%s (nextlen): got frame w/nextlen too large "
4001 				"(%d), seq %d\n",
4002 				__func__, bus->nextlen, seq));
4003 			bus->nextlen = 0;
4004 		}
4005 
4006 		/* Handle Flow Control */
4007 		fcbits = SDPCM_FCMASK_VALUE(&bus->rxhdr[SDPCM_FRAMETAG_LEN]);
4008 
4009 		delta = 0;
4010 		if (~bus->flowcontrol & fcbits) {
4011 			bus->fc_xoff++;
4012 			delta = 1;
4013 		}
4014 		if (bus->flowcontrol & ~fcbits) {
4015 			bus->fc_xon++;
4016 			delta = 1;
4017 		}
4018 
4019 		if (delta) {
4020 			bus->fc_rcvd++;
4021 			bus->flowcontrol = fcbits;
4022 		}
4023 
4024 		/* Check and update sequence number */
4025 		if (rxseq != seq) {
4026 			DHD_INFO(("%s: rx_seq %d, expected %d\n", __func__,
4027 				  seq, rxseq));
4028 			bus->rx_badseq++;
4029 			rxseq = seq;
4030 		}
4031 
4032 		/* Check window for sanity */
4033 		if ((u8) (txmax - bus->tx_seq) > 0x40) {
4034 			DHD_ERROR(("%s: unlikely tx max %d with tx_seq %d\n",
4035 				__func__, txmax, bus->tx_seq));
4036 			txmax = bus->tx_seq + 2;
4037 		}
4038 		bus->tx_max = txmax;
4039 
4040 		/* Call a separate function for control frames */
4041 		if (chan == SDPCM_CONTROL_CHANNEL) {
4042 			dhdsdio_read_control(bus, bus->rxhdr, len, doff);
4043 			continue;
4044 		}
4045 
4046 		ASSERT((chan == SDPCM_DATA_CHANNEL)
4047 		       || (chan == SDPCM_EVENT_CHANNEL)
4048 		       || (chan == SDPCM_TEST_CHANNEL)
4049 		       || (chan == SDPCM_GLOM_CHANNEL));
4050 
4051 		/* Length to read */
4052 		rdlen = (len > firstread) ? (len - firstread) : 0;
4053 
4054 		/* May pad read to blocksize for efficiency */
4055 		if (bus->roundup && bus->blocksize &&
4056 			(rdlen > bus->blocksize)) {
4057 			pad = bus->blocksize - (rdlen % bus->blocksize);
4058 			if ((pad <= bus->roundup) && (pad < bus->blocksize) &&
4059 			    ((rdlen + pad + firstread) < MAX_RX_DATASZ))
4060 				rdlen += pad;
4061 		} else if (rdlen % DHD_SDALIGN) {
4062 			rdlen += DHD_SDALIGN - (rdlen % DHD_SDALIGN);
4063 		}
4064 
4065 		/* Satisfy length-alignment requirements */
4066 		if (forcealign && (rdlen & (ALIGNMENT - 1)))
4067 			rdlen = roundup(rdlen, ALIGNMENT);
4068 
4069 		if ((rdlen + firstread) > MAX_RX_DATASZ) {
4070 			/* Too long -- skip this frame */
4071 			DHD_ERROR(("%s: too long: len %d rdlen %d\n",
4072 				   __func__, len, rdlen));
4073 			bus->dhd->rx_errors++;
4074 			bus->rx_toolong++;
4075 			dhdsdio_rxfail(bus, false, false);
4076 			continue;
4077 		}
4078 
4079 		dhd_os_sdlock_rxq(bus->dhd);
4080 		pkt = pkt_buf_get_skb(rdlen + firstread + DHD_SDALIGN);
4081 		if (!pkt) {
4082 			/* Give up on data, request rtx of events */
4083 			DHD_ERROR(("%s: pkt_buf_get_skb failed: rdlen %d chan %d\n",
4084 				   __func__, rdlen, chan));
4085 			bus->dhd->rx_dropped++;
4086 			dhd_os_sdunlock_rxq(bus->dhd);
4087 			dhdsdio_rxfail(bus, false, RETRYCHAN(chan));
4088 			continue;
4089 		}
4090 		dhd_os_sdunlock_rxq(bus->dhd);
4091 
4092 		ASSERT(!(pkt->prev));
4093 
4094 		/* Leave room for what we already read, and align remainder */
4095 		ASSERT(firstread < pkt->len);
4096 		skb_pull(pkt, firstread);
4097 		PKTALIGN(pkt, rdlen, DHD_SDALIGN);
4098 
4099 		/* Read the remaining frame data */
4100 		sdret =
4101 		    dhd_bcmsdh_recv_buf(bus, bcmsdh_cur_sbwad(sdh), SDIO_FUNC_2,
4102 					F2SYNC, ((u8 *) (pkt->data)), rdlen,
4103 					pkt, NULL, NULL);
4104 		bus->f2rxdata++;
4105 		ASSERT(sdret != BCME_PENDING);
4106 
4107 		if (sdret < 0) {
4108 			DHD_ERROR(("%s: read %d %s bytes failed: %d\n",
4109 				   __func__, rdlen,
4110 				   ((chan ==
4111 				     SDPCM_EVENT_CHANNEL) ? "event" : ((chan ==
4112 					SDPCM_DATA_CHANNEL)
4113 				       ? "data" : "test")),
4114 				   sdret));
4115 			dhd_os_sdlock_rxq(bus->dhd);
4116 			pkt_buf_free_skb(pkt);
4117 			dhd_os_sdunlock_rxq(bus->dhd);
4118 			bus->dhd->rx_errors++;
4119 			dhdsdio_rxfail(bus, true, RETRYCHAN(chan));
4120 			continue;
4121 		}
4122 
4123 		/* Copy the already-read portion */
4124 		skb_push(pkt, firstread);
4125 		memcpy(pkt->data, bus->rxhdr, firstread);
4126 
4127 #ifdef DHD_DEBUG
4128 		if (DHD_BYTES_ON() && DHD_DATA_ON())
4129 			prhex("Rx Data", pkt->data, len);
4130 #endif
4131 
4132 deliver:
4133 		/* Save superframe descriptor and allocate packet frame */
4134 		if (chan == SDPCM_GLOM_CHANNEL) {
4135 			if (SDPCM_GLOMDESC(&bus->rxhdr[SDPCM_FRAMETAG_LEN])) {
4136 				DHD_GLOM(("%s: glom descriptor, %d bytes:\n",
4137 					__func__, len));
4138 #ifdef DHD_DEBUG
4139 				if (DHD_GLOM_ON()) {
4140 					prhex("Glom Data", pkt->data, len);
4141 				}
4142 #endif
4143 				__skb_trim(pkt, len);
4144 				ASSERT(doff == SDPCM_HDRLEN);
4145 				skb_pull(pkt, SDPCM_HDRLEN);
4146 				bus->glomd = pkt;
4147 			} else {
4148 				DHD_ERROR(("%s: glom superframe w/o "
4149 					"descriptor!\n", __func__));
4150 				dhdsdio_rxfail(bus, false, false);
4151 			}
4152 			continue;
4153 		}
4154 
4155 		/* Fill in packet len and prio, deliver upward */
4156 		__skb_trim(pkt, len);
4157 		skb_pull(pkt, doff);
4158 
4159 #ifdef SDTEST
4160 		/* Test channel packets are processed separately */
4161 		if (chan == SDPCM_TEST_CHANNEL) {
4162 			dhdsdio_testrcv(bus, pkt, seq);
4163 			continue;
4164 		}
4165 #endif				/* SDTEST */
4166 
4167 		if (pkt->len == 0) {
4168 			dhd_os_sdlock_rxq(bus->dhd);
4169 			pkt_buf_free_skb(pkt);
4170 			dhd_os_sdunlock_rxq(bus->dhd);
4171 			continue;
4172 		} else if (dhd_prot_hdrpull(bus->dhd, &ifidx, pkt) != 0) {
4173 			DHD_ERROR(("%s: rx protocol error\n", __func__));
4174 			dhd_os_sdlock_rxq(bus->dhd);
4175 			pkt_buf_free_skb(pkt);
4176 			dhd_os_sdunlock_rxq(bus->dhd);
4177 			bus->dhd->rx_errors++;
4178 			continue;
4179 		}
4180 
4181 		/* Unlock during rx call */
4182 		dhd_os_sdunlock(bus->dhd);
4183 		dhd_rx_frame(bus->dhd, ifidx, pkt, 1);
4184 		dhd_os_sdlock(bus->dhd);
4185 	}
4186 	rxcount = maxframes - rxleft;
4187 #ifdef DHD_DEBUG
4188 	/* Message if we hit the limit */
4189 	if (!rxleft && !sdtest)
4190 		DHD_DATA(("%s: hit rx limit of %d frames\n", __func__,
4191 			  maxframes));
4192 	else
4193 #endif				/* DHD_DEBUG */
4194 		DHD_DATA(("%s: processed %d frames\n", __func__, rxcount));
4195 	/* Back off rxseq if awaiting rtx, update rx_seq */
4196 	if (bus->rxskip)
4197 		rxseq--;
4198 	bus->rx_seq = rxseq;
4199 
4200 	return rxcount;
4201 }
4202 
dhdsdio_hostmail(dhd_bus_t * bus)4203 static u32 dhdsdio_hostmail(dhd_bus_t *bus)
4204 {
4205 	sdpcmd_regs_t *regs = bus->regs;
4206 	u32 intstatus = 0;
4207 	u32 hmb_data;
4208 	u8 fcbits;
4209 	uint retries = 0;
4210 
4211 	DHD_TRACE(("%s: Enter\n", __func__));
4212 
4213 	/* Read mailbox data and ack that we did so */
4214 	R_SDREG(hmb_data, &regs->tohostmailboxdata, retries);
4215 	if (retries <= retry_limit)
4216 		W_SDREG(SMB_INT_ACK, &regs->tosbmailbox, retries);
4217 	bus->f1regdata += 2;
4218 
4219 	/* Dongle recomposed rx frames, accept them again */
4220 	if (hmb_data & HMB_DATA_NAKHANDLED) {
4221 		DHD_INFO(("Dongle reports NAK handled, expect rtx of %d\n",
4222 			  bus->rx_seq));
4223 		if (!bus->rxskip)
4224 			DHD_ERROR(("%s: unexpected NAKHANDLED!\n", __func__));
4225 
4226 		bus->rxskip = false;
4227 		intstatus |= I_HMB_FRAME_IND;
4228 	}
4229 
4230 	/*
4231 	 * DEVREADY does not occur with gSPI.
4232 	 */
4233 	if (hmb_data & (HMB_DATA_DEVREADY | HMB_DATA_FWREADY)) {
4234 		bus->sdpcm_ver =
4235 		    (hmb_data & HMB_DATA_VERSION_MASK) >>
4236 		    HMB_DATA_VERSION_SHIFT;
4237 		if (bus->sdpcm_ver != SDPCM_PROT_VERSION)
4238 			DHD_ERROR(("Version mismatch, dongle reports %d, "
4239 				"expecting %d\n",
4240 				bus->sdpcm_ver, SDPCM_PROT_VERSION));
4241 		else
4242 			DHD_INFO(("Dongle ready, protocol version %d\n",
4243 				  bus->sdpcm_ver));
4244 	}
4245 
4246 	/*
4247 	 * Flow Control has been moved into the RX headers and this out of band
4248 	 * method isn't used any more.  Leae this here for possibly
4249 	 * remaining backward
4250 	 * compatible with older dongles
4251 	 */
4252 	if (hmb_data & HMB_DATA_FC) {
4253 		fcbits =
4254 		    (hmb_data & HMB_DATA_FCDATA_MASK) >> HMB_DATA_FCDATA_SHIFT;
4255 
4256 		if (fcbits & ~bus->flowcontrol)
4257 			bus->fc_xoff++;
4258 		if (bus->flowcontrol & ~fcbits)
4259 			bus->fc_xon++;
4260 
4261 		bus->fc_rcvd++;
4262 		bus->flowcontrol = fcbits;
4263 	}
4264 
4265 	/* Shouldn't be any others */
4266 	if (hmb_data & ~(HMB_DATA_DEVREADY |
4267 			 HMB_DATA_NAKHANDLED |
4268 			 HMB_DATA_FC |
4269 			 HMB_DATA_FWREADY |
4270 			 HMB_DATA_FCDATA_MASK | HMB_DATA_VERSION_MASK)) {
4271 		DHD_ERROR(("Unknown mailbox data content: 0x%02x\n", hmb_data));
4272 	}
4273 
4274 	return intstatus;
4275 }
4276 
dhdsdio_dpc(dhd_bus_t * bus)4277 bool dhdsdio_dpc(dhd_bus_t *bus)
4278 {
4279 	bcmsdh_info_t *sdh = bus->sdh;
4280 	sdpcmd_regs_t *regs = bus->regs;
4281 	u32 intstatus, newstatus = 0;
4282 	uint retries = 0;
4283 	uint rxlimit = dhd_rxbound;	/* Rx frames to read before resched */
4284 	uint txlimit = dhd_txbound;	/* Tx frames to send before resched */
4285 	uint framecnt = 0;	/* Temporary counter of tx/rx frames */
4286 	bool rxdone = true;	/* Flag for no more read data */
4287 	bool resched = false;	/* Flag indicating resched wanted */
4288 
4289 	DHD_TRACE(("%s: Enter\n", __func__));
4290 
4291 	/* Start with leftover status bits */
4292 	intstatus = bus->intstatus;
4293 
4294 	dhd_os_sdlock(bus->dhd);
4295 
4296 	/* If waiting for HTAVAIL, check status */
4297 	if (bus->clkstate == CLK_PENDING) {
4298 		int err;
4299 		u8 clkctl, devctl = 0;
4300 
4301 #ifdef DHD_DEBUG
4302 		/* Check for inconsistent device control */
4303 		devctl =
4304 		    bcmsdh_cfg_read(sdh, SDIO_FUNC_1, SBSDIO_DEVICE_CTL, &err);
4305 		if (err) {
4306 			DHD_ERROR(("%s: error reading DEVCTL: %d\n",
4307 				   __func__, err));
4308 			bus->dhd->busstate = DHD_BUS_DOWN;
4309 		} else {
4310 			ASSERT(devctl & SBSDIO_DEVCTL_CA_INT_ONLY);
4311 		}
4312 #endif				/* DHD_DEBUG */
4313 
4314 		/* Read CSR, if clock on switch to AVAIL, else ignore */
4315 		clkctl =
4316 		    bcmsdh_cfg_read(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR,
4317 				    &err);
4318 		if (err) {
4319 			DHD_ERROR(("%s: error reading CSR: %d\n", __func__,
4320 				   err));
4321 			bus->dhd->busstate = DHD_BUS_DOWN;
4322 		}
4323 
4324 		DHD_INFO(("DPC: PENDING, devctl 0x%02x clkctl 0x%02x\n", devctl,
4325 			  clkctl));
4326 
4327 		if (SBSDIO_HTAV(clkctl)) {
4328 			devctl =
4329 			    bcmsdh_cfg_read(sdh, SDIO_FUNC_1, SBSDIO_DEVICE_CTL,
4330 					    &err);
4331 			if (err) {
4332 				DHD_ERROR(("%s: error reading DEVCTL: %d\n",
4333 					   __func__, err));
4334 				bus->dhd->busstate = DHD_BUS_DOWN;
4335 			}
4336 			devctl &= ~SBSDIO_DEVCTL_CA_INT_ONLY;
4337 			bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_DEVICE_CTL,
4338 					 devctl, &err);
4339 			if (err) {
4340 				DHD_ERROR(("%s: error writing DEVCTL: %d\n",
4341 					   __func__, err));
4342 				bus->dhd->busstate = DHD_BUS_DOWN;
4343 			}
4344 			bus->clkstate = CLK_AVAIL;
4345 		} else {
4346 			goto clkwait;
4347 		}
4348 	}
4349 
4350 	BUS_WAKE(bus);
4351 
4352 	/* Make sure backplane clock is on */
4353 	dhdsdio_clkctl(bus, CLK_AVAIL, true);
4354 	if (bus->clkstate == CLK_PENDING)
4355 		goto clkwait;
4356 
4357 	/* Pending interrupt indicates new device status */
4358 	if (bus->ipend) {
4359 		bus->ipend = false;
4360 		R_SDREG(newstatus, &regs->intstatus, retries);
4361 		bus->f1regdata++;
4362 		if (bcmsdh_regfail(bus->sdh))
4363 			newstatus = 0;
4364 		newstatus &= bus->hostintmask;
4365 		bus->fcstate = !!(newstatus & I_HMB_FC_STATE);
4366 		if (newstatus) {
4367 			W_SDREG(newstatus, &regs->intstatus, retries);
4368 			bus->f1regdata++;
4369 		}
4370 	}
4371 
4372 	/* Merge new bits with previous */
4373 	intstatus |= newstatus;
4374 	bus->intstatus = 0;
4375 
4376 	/* Handle flow-control change: read new state in case our ack
4377 	 * crossed another change interrupt.  If change still set, assume
4378 	 * FC ON for safety, let next loop through do the debounce.
4379 	 */
4380 	if (intstatus & I_HMB_FC_CHANGE) {
4381 		intstatus &= ~I_HMB_FC_CHANGE;
4382 		W_SDREG(I_HMB_FC_CHANGE, &regs->intstatus, retries);
4383 		R_SDREG(newstatus, &regs->intstatus, retries);
4384 		bus->f1regdata += 2;
4385 		bus->fcstate =
4386 		    !!(newstatus & (I_HMB_FC_STATE | I_HMB_FC_CHANGE));
4387 		intstatus |= (newstatus & bus->hostintmask);
4388 	}
4389 
4390 	/* Handle host mailbox indication */
4391 	if (intstatus & I_HMB_HOST_INT) {
4392 		intstatus &= ~I_HMB_HOST_INT;
4393 		intstatus |= dhdsdio_hostmail(bus);
4394 	}
4395 
4396 	/* Generally don't ask for these, can get CRC errors... */
4397 	if (intstatus & I_WR_OOSYNC) {
4398 		DHD_ERROR(("Dongle reports WR_OOSYNC\n"));
4399 		intstatus &= ~I_WR_OOSYNC;
4400 	}
4401 
4402 	if (intstatus & I_RD_OOSYNC) {
4403 		DHD_ERROR(("Dongle reports RD_OOSYNC\n"));
4404 		intstatus &= ~I_RD_OOSYNC;
4405 	}
4406 
4407 	if (intstatus & I_SBINT) {
4408 		DHD_ERROR(("Dongle reports SBINT\n"));
4409 		intstatus &= ~I_SBINT;
4410 	}
4411 
4412 	/* Would be active due to wake-wlan in gSPI */
4413 	if (intstatus & I_CHIPACTIVE) {
4414 		DHD_INFO(("Dongle reports CHIPACTIVE\n"));
4415 		intstatus &= ~I_CHIPACTIVE;
4416 	}
4417 
4418 	/* Ignore frame indications if rxskip is set */
4419 	if (bus->rxskip)
4420 		intstatus &= ~I_HMB_FRAME_IND;
4421 
4422 	/* On frame indication, read available frames */
4423 	if (PKT_AVAILABLE()) {
4424 		framecnt = dhdsdio_readframes(bus, rxlimit, &rxdone);
4425 		if (rxdone || bus->rxskip)
4426 			intstatus &= ~I_HMB_FRAME_IND;
4427 		rxlimit -= min(framecnt, rxlimit);
4428 	}
4429 
4430 	/* Keep still-pending events for next scheduling */
4431 	bus->intstatus = intstatus;
4432 
4433 clkwait:
4434 #if defined(OOB_INTR_ONLY)
4435 	bcmsdh_oob_intr_set(1);
4436 #endif				/* (OOB_INTR_ONLY) */
4437 	/* Re-enable interrupts to detect new device events (mailbox, rx frame)
4438 	 * or clock availability.  (Allows tx loop to check ipend if desired.)
4439 	 * (Unless register access seems hosed, as we may not be able to ACK...)
4440 	 */
4441 	if (bus->intr && bus->intdis && !bcmsdh_regfail(sdh)) {
4442 		DHD_INTR(("%s: enable SDIO interrupts, rxdone %d framecnt %d\n",
4443 			  __func__, rxdone, framecnt));
4444 		bus->intdis = false;
4445 		bcmsdh_intr_enable(sdh);
4446 	}
4447 
4448 	if (DATAOK(bus) && bus->ctrl_frame_stat &&
4449 		(bus->clkstate == CLK_AVAIL)) {
4450 		int ret, i;
4451 
4452 		ret =
4453 		    dhd_bcmsdh_send_buf(bus, bcmsdh_cur_sbwad(sdh), SDIO_FUNC_2,
4454 					F2SYNC, (u8 *) bus->ctrl_frame_buf,
4455 					(u32) bus->ctrl_frame_len, NULL,
4456 					NULL, NULL);
4457 		ASSERT(ret != BCME_PENDING);
4458 
4459 		if (ret < 0) {
4460 			/* On failure, abort the command and
4461 				terminate the frame */
4462 			DHD_INFO(("%s: sdio error %d, abort command and "
4463 				"terminate frame.\n", __func__, ret));
4464 			bus->tx_sderrs++;
4465 
4466 			bcmsdh_abort(sdh, SDIO_FUNC_2);
4467 
4468 			bcmsdh_cfg_write(sdh, SDIO_FUNC_1,
4469 					 SBSDIO_FUNC1_FRAMECTRL, SFC_WF_TERM,
4470 					 NULL);
4471 			bus->f1regdata++;
4472 
4473 			for (i = 0; i < 3; i++) {
4474 				u8 hi, lo;
4475 				hi = bcmsdh_cfg_read(sdh, SDIO_FUNC_1,
4476 						     SBSDIO_FUNC1_WFRAMEBCHI,
4477 						     NULL);
4478 				lo = bcmsdh_cfg_read(sdh, SDIO_FUNC_1,
4479 						     SBSDIO_FUNC1_WFRAMEBCLO,
4480 						     NULL);
4481 				bus->f1regdata += 2;
4482 				if ((hi == 0) && (lo == 0))
4483 					break;
4484 			}
4485 
4486 		}
4487 		if (ret == 0)
4488 			bus->tx_seq = (bus->tx_seq + 1) % SDPCM_SEQUENCE_WRAP;
4489 
4490 		DHD_INFO(("Return_dpc value is : %d\n", ret));
4491 		bus->ctrl_frame_stat = false;
4492 		dhd_wait_event_wakeup(bus->dhd);
4493 	}
4494 	/* Send queued frames (limit 1 if rx may still be pending) */
4495 	else if ((bus->clkstate == CLK_AVAIL) && !bus->fcstate &&
4496 		 pktq_mlen(&bus->txq, ~bus->flowcontrol) && txlimit
4497 		 && DATAOK(bus)) {
4498 		framecnt = rxdone ? txlimit : min(txlimit, dhd_txminmax);
4499 		framecnt = dhdsdio_sendfromq(bus, framecnt);
4500 		txlimit -= framecnt;
4501 	}
4502 
4503 	/* Resched if events or tx frames are pending,
4504 		 else await next interrupt */
4505 	/* On failed register access, all bets are off:
4506 		 no resched or interrupts */
4507 	if ((bus->dhd->busstate == DHD_BUS_DOWN) || bcmsdh_regfail(sdh)) {
4508 		DHD_ERROR(("%s: failed backplane access over SDIO, halting "
4509 			"operation %d\n", __func__, bcmsdh_regfail(sdh)));
4510 		bus->dhd->busstate = DHD_BUS_DOWN;
4511 		bus->intstatus = 0;
4512 	} else if (bus->clkstate == CLK_PENDING) {
4513 		DHD_INFO(("%s: rescheduled due to CLK_PENDING awaiting "
4514 			"I_CHIPACTIVE interrupt\n", __func__));
4515 		resched = true;
4516 	} else if (bus->intstatus || bus->ipend ||
4517 		(!bus->fcstate && pktq_mlen(&bus->txq, ~bus->flowcontrol) &&
4518 			DATAOK(bus)) || PKT_AVAILABLE()) {
4519 		resched = true;
4520 	}
4521 
4522 	bus->dpc_sched = resched;
4523 
4524 	/* If we're done for now, turn off clock request. */
4525 	if ((bus->clkstate != CLK_PENDING)
4526 	    && bus->idletime == DHD_IDLE_IMMEDIATE) {
4527 		bus->activity = false;
4528 		dhdsdio_clkctl(bus, CLK_NONE, false);
4529 	}
4530 
4531 	dhd_os_sdunlock(bus->dhd);
4532 
4533 	return resched;
4534 }
4535 
dhd_bus_dpc(struct dhd_bus * bus)4536 bool dhd_bus_dpc(struct dhd_bus *bus)
4537 {
4538 	bool resched;
4539 
4540 	/* Call the DPC directly. */
4541 	DHD_TRACE(("Calling dhdsdio_dpc() from %s\n", __func__));
4542 	resched = dhdsdio_dpc(bus);
4543 
4544 	return resched;
4545 }
4546 
dhdsdio_isr(void * arg)4547 void dhdsdio_isr(void *arg)
4548 {
4549 	dhd_bus_t *bus = (dhd_bus_t *) arg;
4550 	bcmsdh_info_t *sdh;
4551 
4552 	DHD_TRACE(("%s: Enter\n", __func__));
4553 
4554 	if (!bus) {
4555 		DHD_ERROR(("%s : bus is null pointer , exit\n", __func__));
4556 		return;
4557 	}
4558 	sdh = bus->sdh;
4559 
4560 	if (bus->dhd->busstate == DHD_BUS_DOWN) {
4561 		DHD_ERROR(("%s : bus is down. we have nothing to do\n",
4562 			   __func__));
4563 		return;
4564 	}
4565 	/* Count the interrupt call */
4566 	bus->intrcount++;
4567 	bus->ipend = true;
4568 
4569 	/* Shouldn't get this interrupt if we're sleeping? */
4570 	if (bus->sleeping) {
4571 		DHD_ERROR(("INTERRUPT WHILE SLEEPING??\n"));
4572 		return;
4573 	}
4574 
4575 	/* Disable additional interrupts (is this needed now)? */
4576 	if (bus->intr)
4577 		DHD_INTR(("%s: disable SDIO interrupts\n", __func__));
4578 	else
4579 		DHD_ERROR(("dhdsdio_isr() w/o interrupt configured!\n"));
4580 
4581 	bcmsdh_intr_disable(sdh);
4582 	bus->intdis = true;
4583 
4584 #if defined(SDIO_ISR_THREAD)
4585 	DHD_TRACE(("Calling dhdsdio_dpc() from %s\n", __func__));
4586 	while (dhdsdio_dpc(bus))
4587 		;
4588 #else
4589 	bus->dpc_sched = true;
4590 	dhd_sched_dpc(bus->dhd);
4591 #endif
4592 
4593 }
4594 
4595 #ifdef SDTEST
dhdsdio_pktgen_init(dhd_bus_t * bus)4596 static void dhdsdio_pktgen_init(dhd_bus_t *bus)
4597 {
4598 	/* Default to specified length, or full range */
4599 	if (dhd_pktgen_len) {
4600 		bus->pktgen_maxlen = min(dhd_pktgen_len, MAX_PKTGEN_LEN);
4601 		bus->pktgen_minlen = bus->pktgen_maxlen;
4602 	} else {
4603 		bus->pktgen_maxlen = MAX_PKTGEN_LEN;
4604 		bus->pktgen_minlen = 0;
4605 	}
4606 	bus->pktgen_len = (u16) bus->pktgen_minlen;
4607 
4608 	/* Default to per-watchdog burst with 10s print time */
4609 	bus->pktgen_freq = 1;
4610 	bus->pktgen_print = 10000 / dhd_watchdog_ms;
4611 	bus->pktgen_count = (dhd_pktgen * dhd_watchdog_ms + 999) / 1000;
4612 
4613 	/* Default to echo mode */
4614 	bus->pktgen_mode = DHD_PKTGEN_ECHO;
4615 	bus->pktgen_stop = 1;
4616 }
4617 
dhdsdio_pktgen(dhd_bus_t * bus)4618 static void dhdsdio_pktgen(dhd_bus_t *bus)
4619 {
4620 	struct sk_buff *pkt;
4621 	u8 *data;
4622 	uint pktcount;
4623 	uint fillbyte;
4624 	u16 len;
4625 
4626 	/* Display current count if appropriate */
4627 	if (bus->pktgen_print && (++bus->pktgen_ptick >= bus->pktgen_print)) {
4628 		bus->pktgen_ptick = 0;
4629 		printk(KERN_DEBUG "%s: send attempts %d rcvd %d\n",
4630 		       __func__, bus->pktgen_sent, bus->pktgen_rcvd);
4631 	}
4632 
4633 	/* For recv mode, just make sure dongle has started sending */
4634 	if (bus->pktgen_mode == DHD_PKTGEN_RECV) {
4635 		if (!bus->pktgen_rcvd)
4636 			dhdsdio_sdtest_set(bus, true);
4637 		return;
4638 	}
4639 
4640 	/* Otherwise, generate or request the specified number of packets */
4641 	for (pktcount = 0; pktcount < bus->pktgen_count; pktcount++) {
4642 		/* Stop if total has been reached */
4643 		if (bus->pktgen_total
4644 		    && (bus->pktgen_sent >= bus->pktgen_total)) {
4645 			bus->pktgen_count = 0;
4646 			break;
4647 		}
4648 
4649 		/* Allocate an appropriate-sized packet */
4650 		len = bus->pktgen_len;
4651 		pkt = pkt_buf_get_skb(
4652 			(len + SDPCM_HDRLEN + SDPCM_TEST_HDRLEN + DHD_SDALIGN),
4653 			true);
4654 		if (!pkt) {
4655 			DHD_ERROR(("%s: pkt_buf_get_skb failed!\n", __func__));
4656 			break;
4657 		}
4658 		PKTALIGN(pkt, (len + SDPCM_HDRLEN + SDPCM_TEST_HDRLEN),
4659 			 DHD_SDALIGN);
4660 		data = (u8 *) (pkt->data) + SDPCM_HDRLEN;
4661 
4662 		/* Write test header cmd and extra based on mode */
4663 		switch (bus->pktgen_mode) {
4664 		case DHD_PKTGEN_ECHO:
4665 			*data++ = SDPCM_TEST_ECHOREQ;
4666 			*data++ = (u8) bus->pktgen_sent;
4667 			break;
4668 
4669 		case DHD_PKTGEN_SEND:
4670 			*data++ = SDPCM_TEST_DISCARD;
4671 			*data++ = (u8) bus->pktgen_sent;
4672 			break;
4673 
4674 		case DHD_PKTGEN_RXBURST:
4675 			*data++ = SDPCM_TEST_BURST;
4676 			*data++ = (u8) bus->pktgen_count;
4677 			break;
4678 
4679 		default:
4680 			DHD_ERROR(("Unrecognized pktgen mode %d\n",
4681 				   bus->pktgen_mode));
4682 			pkt_buf_free_skb(pkt, true);
4683 			bus->pktgen_count = 0;
4684 			return;
4685 		}
4686 
4687 		/* Write test header length field */
4688 		*data++ = (len >> 0);
4689 		*data++ = (len >> 8);
4690 
4691 		/* Then fill in the remainder -- N/A for burst,
4692 			 but who cares... */
4693 		for (fillbyte = 0; fillbyte < len; fillbyte++)
4694 			*data++ =
4695 			    SDPCM_TEST_FILL(fillbyte, (u8) bus->pktgen_sent);
4696 
4697 #ifdef DHD_DEBUG
4698 		if (DHD_BYTES_ON() && DHD_DATA_ON()) {
4699 			data = (u8 *) (pkt->data) + SDPCM_HDRLEN;
4700 			prhex("dhdsdio_pktgen: Tx Data", data,
4701 			      pkt->len - SDPCM_HDRLEN);
4702 		}
4703 #endif
4704 
4705 		/* Send it */
4706 		if (dhdsdio_txpkt(bus, pkt, SDPCM_TEST_CHANNEL, true)) {
4707 			bus->pktgen_fail++;
4708 			if (bus->pktgen_stop
4709 			    && bus->pktgen_stop == bus->pktgen_fail)
4710 				bus->pktgen_count = 0;
4711 		}
4712 		bus->pktgen_sent++;
4713 
4714 		/* Bump length if not fixed, wrap at max */
4715 		if (++bus->pktgen_len > bus->pktgen_maxlen)
4716 			bus->pktgen_len = (u16) bus->pktgen_minlen;
4717 
4718 		/* Special case for burst mode: just send one request! */
4719 		if (bus->pktgen_mode == DHD_PKTGEN_RXBURST)
4720 			break;
4721 	}
4722 }
4723 
dhdsdio_sdtest_set(dhd_bus_t * bus,bool start)4724 static void dhdsdio_sdtest_set(dhd_bus_t *bus, bool start)
4725 {
4726 	struct sk_buff *pkt;
4727 	u8 *data;
4728 
4729 	/* Allocate the packet */
4730 	pkt = pkt_buf_get_skb(SDPCM_HDRLEN + SDPCM_TEST_HDRLEN + DHD_SDALIGN,
4731 			true);
4732 	if (!pkt) {
4733 		DHD_ERROR(("%s: pkt_buf_get_skb failed!\n", __func__));
4734 		return;
4735 	}
4736 	PKTALIGN(pkt, (SDPCM_HDRLEN + SDPCM_TEST_HDRLEN), DHD_SDALIGN);
4737 	data = (u8 *) (pkt->data) + SDPCM_HDRLEN;
4738 
4739 	/* Fill in the test header */
4740 	*data++ = SDPCM_TEST_SEND;
4741 	*data++ = start;
4742 	*data++ = (bus->pktgen_maxlen >> 0);
4743 	*data++ = (bus->pktgen_maxlen >> 8);
4744 
4745 	/* Send it */
4746 	if (dhdsdio_txpkt(bus, pkt, SDPCM_TEST_CHANNEL, true))
4747 		bus->pktgen_fail++;
4748 }
4749 
dhdsdio_testrcv(dhd_bus_t * bus,struct sk_buff * pkt,uint seq)4750 static void dhdsdio_testrcv(dhd_bus_t *bus, struct sk_buff *pkt, uint seq)
4751 {
4752 	u8 *data;
4753 	uint pktlen;
4754 
4755 	u8 cmd;
4756 	u8 extra;
4757 	u16 len;
4758 	u16 offset;
4759 
4760 	/* Check for min length */
4761 	pktlen = pkt->len;
4762 	if (pktlen < SDPCM_TEST_HDRLEN) {
4763 		DHD_ERROR(("dhdsdio_restrcv: toss runt frame, pktlen %d\n",
4764 			   pktlen));
4765 		pkt_buf_free_skb(pkt, false);
4766 		return;
4767 	}
4768 
4769 	/* Extract header fields */
4770 	data = pkt->data;
4771 	cmd = *data++;
4772 	extra = *data++;
4773 	len = *data++;
4774 	len += *data++ << 8;
4775 
4776 	/* Check length for relevant commands */
4777 	if (cmd == SDPCM_TEST_DISCARD || cmd == SDPCM_TEST_ECHOREQ
4778 	    || cmd == SDPCM_TEST_ECHORSP) {
4779 		if (pktlen != len + SDPCM_TEST_HDRLEN) {
4780 			DHD_ERROR(("dhdsdio_testrcv: frame length mismatch, "
4781 				"pktlen %d seq %d" " cmd %d extra %d len %d\n",
4782 				pktlen, seq, cmd, extra, len));
4783 			pkt_buf_free_skb(pkt, false);
4784 			return;
4785 		}
4786 	}
4787 
4788 	/* Process as per command */
4789 	switch (cmd) {
4790 	case SDPCM_TEST_ECHOREQ:
4791 		/* Rx->Tx turnaround ok (even on NDIS w/current
4792 			 implementation) */
4793 		*(u8 *) (pkt->data) = SDPCM_TEST_ECHORSP;
4794 		if (dhdsdio_txpkt(bus, pkt, SDPCM_TEST_CHANNEL, true) == 0) {
4795 			bus->pktgen_sent++;
4796 		} else {
4797 			bus->pktgen_fail++;
4798 			pkt_buf_free_skb(pkt, false);
4799 		}
4800 		bus->pktgen_rcvd++;
4801 		break;
4802 
4803 	case SDPCM_TEST_ECHORSP:
4804 		if (bus->ext_loop) {
4805 			pkt_buf_free_skb(pkt, false);
4806 			bus->pktgen_rcvd++;
4807 			break;
4808 		}
4809 
4810 		for (offset = 0; offset < len; offset++, data++) {
4811 			if (*data != SDPCM_TEST_FILL(offset, extra)) {
4812 				DHD_ERROR(("dhdsdio_testrcv: echo data mismatch: " "offset %d (len %d) expect 0x%02x rcvd 0x%02x\n",
4813 					offset, len,
4814 					SDPCM_TEST_FILL(offset, extra), *data));
4815 				break;
4816 			}
4817 		}
4818 		pkt_buf_free_skb(pkt, false);
4819 		bus->pktgen_rcvd++;
4820 		break;
4821 
4822 	case SDPCM_TEST_DISCARD:
4823 		pkt_buf_free_skb(pkt, false);
4824 		bus->pktgen_rcvd++;
4825 		break;
4826 
4827 	case SDPCM_TEST_BURST:
4828 	case SDPCM_TEST_SEND:
4829 	default:
4830 		DHD_INFO(("dhdsdio_testrcv: unsupported or unknown command, "
4831 			"pktlen %d seq %d" " cmd %d extra %d len %d\n",
4832 			pktlen, seq, cmd, extra, len));
4833 		pkt_buf_free_skb(pkt, false);
4834 		break;
4835 	}
4836 
4837 	/* For recv mode, stop at limie (and tell dongle to stop sending) */
4838 	if (bus->pktgen_mode == DHD_PKTGEN_RECV) {
4839 		if (bus->pktgen_total
4840 		    && (bus->pktgen_rcvd >= bus->pktgen_total)) {
4841 			bus->pktgen_count = 0;
4842 			dhdsdio_sdtest_set(bus, false);
4843 		}
4844 	}
4845 }
4846 #endif				/* SDTEST */
4847 
dhd_bus_watchdog(dhd_pub_t * dhdp)4848 extern bool dhd_bus_watchdog(dhd_pub_t *dhdp)
4849 {
4850 	dhd_bus_t *bus;
4851 
4852 	DHD_TIMER(("%s: Enter\n", __func__));
4853 
4854 	bus = dhdp->bus;
4855 
4856 	if (bus->dhd->dongle_reset)
4857 		return false;
4858 
4859 	/* Ignore the timer if simulating bus down */
4860 	if (bus->sleeping)
4861 		return false;
4862 
4863 	dhd_os_sdlock(bus->dhd);
4864 
4865 	/* Poll period: check device if appropriate. */
4866 	if (bus->poll && (++bus->polltick >= bus->pollrate)) {
4867 		u32 intstatus = 0;
4868 
4869 		/* Reset poll tick */
4870 		bus->polltick = 0;
4871 
4872 		/* Check device if no interrupts */
4873 		if (!bus->intr || (bus->intrcount == bus->lastintrs)) {
4874 
4875 			if (!bus->dpc_sched) {
4876 				u8 devpend;
4877 				devpend = bcmsdh_cfg_read(bus->sdh, SDIO_FUNC_0,
4878 							  SDIOD_CCCR_INTPEND,
4879 							  NULL);
4880 				intstatus =
4881 				    devpend & (INTR_STATUS_FUNC1 |
4882 					       INTR_STATUS_FUNC2);
4883 			}
4884 
4885 			/* If there is something, make like the ISR and
4886 				 schedule the DPC */
4887 			if (intstatus) {
4888 				bus->pollcnt++;
4889 				bus->ipend = true;
4890 				if (bus->intr)
4891 					bcmsdh_intr_disable(bus->sdh);
4892 
4893 				bus->dpc_sched = true;
4894 				dhd_sched_dpc(bus->dhd);
4895 
4896 			}
4897 		}
4898 
4899 		/* Update interrupt tracking */
4900 		bus->lastintrs = bus->intrcount;
4901 	}
4902 #ifdef DHD_DEBUG
4903 	/* Poll for console output periodically */
4904 	if (dhdp->busstate == DHD_BUS_DATA && dhd_console_ms != 0) {
4905 		bus->console.count += dhd_watchdog_ms;
4906 		if (bus->console.count >= dhd_console_ms) {
4907 			bus->console.count -= dhd_console_ms;
4908 			/* Make sure backplane clock is on */
4909 			dhdsdio_clkctl(bus, CLK_AVAIL, false);
4910 			if (dhdsdio_readconsole(bus) < 0)
4911 				dhd_console_ms = 0;	/* On error,
4912 							 stop trying */
4913 		}
4914 	}
4915 #endif				/* DHD_DEBUG */
4916 
4917 #ifdef SDTEST
4918 	/* Generate packets if configured */
4919 	if (bus->pktgen_count && (++bus->pktgen_tick >= bus->pktgen_freq)) {
4920 		/* Make sure backplane clock is on */
4921 		dhdsdio_clkctl(bus, CLK_AVAIL, false);
4922 		bus->pktgen_tick = 0;
4923 		dhdsdio_pktgen(bus);
4924 	}
4925 #endif
4926 
4927 	/* On idle timeout clear activity flag and/or turn off clock */
4928 	if ((bus->idletime > 0) && (bus->clkstate == CLK_AVAIL)) {
4929 		if (++bus->idlecount >= bus->idletime) {
4930 			bus->idlecount = 0;
4931 			if (bus->activity) {
4932 				bus->activity = false;
4933 				dhd_os_wd_timer(bus->dhd, dhd_watchdog_ms);
4934 			} else {
4935 				dhdsdio_clkctl(bus, CLK_NONE, false);
4936 			}
4937 		}
4938 	}
4939 
4940 	dhd_os_sdunlock(bus->dhd);
4941 
4942 	return bus->ipend;
4943 }
4944 
4945 #ifdef DHD_DEBUG
dhd_bus_console_in(dhd_pub_t * dhdp,unsigned char * msg,uint msglen)4946 extern int dhd_bus_console_in(dhd_pub_t *dhdp, unsigned char *msg, uint msglen)
4947 {
4948 	dhd_bus_t *bus = dhdp->bus;
4949 	u32 addr, val;
4950 	int rv;
4951 	struct sk_buff *pkt;
4952 
4953 	/* Address could be zero if CONSOLE := 0 in dongle Makefile */
4954 	if (bus->console_addr == 0)
4955 		return BCME_UNSUPPORTED;
4956 
4957 	/* Exclusive bus access */
4958 	dhd_os_sdlock(bus->dhd);
4959 
4960 	/* Don't allow input if dongle is in reset */
4961 	if (bus->dhd->dongle_reset) {
4962 		dhd_os_sdunlock(bus->dhd);
4963 		return BCME_NOTREADY;
4964 	}
4965 
4966 	/* Request clock to allow SDIO accesses */
4967 	BUS_WAKE(bus);
4968 	/* No pend allowed since txpkt is called later, ht clk has to be on */
4969 	dhdsdio_clkctl(bus, CLK_AVAIL, false);
4970 
4971 	/* Zero cbuf_index */
4972 	addr = bus->console_addr + offsetof(hndrte_cons_t, cbuf_idx);
4973 	val = cpu_to_le32(0);
4974 	rv = dhdsdio_membytes(bus, true, addr, (u8 *)&val, sizeof(val));
4975 	if (rv < 0)
4976 		goto done;
4977 
4978 	/* Write message into cbuf */
4979 	addr = bus->console_addr + offsetof(hndrte_cons_t, cbuf);
4980 	rv = dhdsdio_membytes(bus, true, addr, (u8 *)msg, msglen);
4981 	if (rv < 0)
4982 		goto done;
4983 
4984 	/* Write length into vcons_in */
4985 	addr = bus->console_addr + offsetof(hndrte_cons_t, vcons_in);
4986 	val = cpu_to_le32(msglen);
4987 	rv = dhdsdio_membytes(bus, true, addr, (u8 *)&val, sizeof(val));
4988 	if (rv < 0)
4989 		goto done;
4990 
4991 	/* Bump dongle by sending an empty event pkt.
4992 	 * sdpcm_sendup (RX) checks for virtual console input.
4993 	 */
4994 	pkt = pkt_buf_get_skb(4 + SDPCM_RESERVE);
4995 	if ((pkt != NULL) && bus->clkstate == CLK_AVAIL)
4996 		dhdsdio_txpkt(bus, pkt, SDPCM_EVENT_CHANNEL, true);
4997 
4998 done:
4999 	if ((bus->idletime == DHD_IDLE_IMMEDIATE) && !bus->dpc_sched) {
5000 		bus->activity = false;
5001 		dhdsdio_clkctl(bus, CLK_NONE, true);
5002 	}
5003 
5004 	dhd_os_sdunlock(bus->dhd);
5005 
5006 	return rv;
5007 }
5008 #endif				/* DHD_DEBUG */
5009 
5010 #ifdef DHD_DEBUG
dhd_dump_cis(uint fn,u8 * cis)5011 static void dhd_dump_cis(uint fn, u8 *cis)
5012 {
5013 	uint byte, tag, tdata;
5014 	DHD_INFO(("Function %d CIS:\n", fn));
5015 
5016 	for (tdata = byte = 0; byte < SBSDIO_CIS_SIZE_LIMIT; byte++) {
5017 		if ((byte % 16) == 0)
5018 			DHD_INFO(("    "));
5019 		DHD_INFO(("%02x ", cis[byte]));
5020 		if ((byte % 16) == 15)
5021 			DHD_INFO(("\n"));
5022 		if (!tdata--) {
5023 			tag = cis[byte];
5024 			if (tag == 0xff)
5025 				break;
5026 			else if (!tag)
5027 				tdata = 0;
5028 			else if ((byte + 1) < SBSDIO_CIS_SIZE_LIMIT)
5029 				tdata = cis[byte + 1] + 1;
5030 			else
5031 				DHD_INFO(("]"));
5032 		}
5033 	}
5034 	if ((byte % 16) != 15)
5035 		DHD_INFO(("\n"));
5036 }
5037 #endif				/* DHD_DEBUG */
5038 
dhdsdio_chipmatch(u16 chipid)5039 static bool dhdsdio_chipmatch(u16 chipid)
5040 {
5041 	if (chipid == BCM4325_CHIP_ID)
5042 		return true;
5043 	if (chipid == BCM4329_CHIP_ID)
5044 		return true;
5045 	if (chipid == BCM4319_CHIP_ID)
5046 		return true;
5047 	return false;
5048 }
5049 
dhdsdio_probe(u16 venid,u16 devid,u16 bus_no,u16 slot,u16 func,uint bustype,void * regsva,void * sdh)5050 static void *dhdsdio_probe(u16 venid, u16 devid, u16 bus_no,
5051 			   u16 slot, u16 func, uint bustype, void *regsva,
5052 			   void *sdh)
5053 {
5054 	int ret;
5055 	dhd_bus_t *bus;
5056 
5057 	/* Init global variables at run-time, not as part of the declaration.
5058 	 * This is required to support init/de-init of the driver.
5059 	 * Initialization
5060 	 * of globals as part of the declaration results in non-deterministic
5061 	 * behavior since the value of the globals may be different on the
5062 	 * first time that the driver is initialized vs subsequent
5063 	 * initializations.
5064 	 */
5065 	dhd_txbound = DHD_TXBOUND;
5066 	dhd_rxbound = DHD_RXBOUND;
5067 	dhd_alignctl = true;
5068 	sd1idle = true;
5069 	dhd_readahead = true;
5070 	retrydata = false;
5071 	dhd_dongle_memsize = 0;
5072 	dhd_txminmax = DHD_TXMINMAX;
5073 
5074 	forcealign = true;
5075 
5076 	dhd_common_init();
5077 
5078 	DHD_TRACE(("%s: Enter\n", __func__));
5079 	DHD_INFO(("%s: venid 0x%04x devid 0x%04x\n", __func__, venid, devid));
5080 
5081 	/* We make assumptions about address window mappings */
5082 	ASSERT((unsigned long)regsva == SI_ENUM_BASE);
5083 
5084 	/* BCMSDH passes venid and devid based on CIS parsing -- but
5085 	 * low-power start
5086 	 * means early parse could fail, so here we should get either an ID
5087 	 * we recognize OR (-1) indicating we must request power first.
5088 	 */
5089 	/* Check the Vendor ID */
5090 	switch (venid) {
5091 	case 0x0000:
5092 	case VENDOR_BROADCOM:
5093 		break;
5094 	default:
5095 		DHD_ERROR(("%s: unknown vendor: 0x%04x\n", __func__, venid));
5096 		return NULL;
5097 	}
5098 
5099 	/* Check the Device ID and make sure it's one that we support */
5100 	switch (devid) {
5101 	case BCM4325_D11DUAL_ID:	/* 4325 802.11a/g id */
5102 	case BCM4325_D11G_ID:	/* 4325 802.11g 2.4Ghz band id */
5103 	case BCM4325_D11A_ID:	/* 4325 802.11a 5Ghz band id */
5104 		DHD_INFO(("%s: found 4325 Dongle\n", __func__));
5105 		break;
5106 	case BCM4329_D11NDUAL_ID:	/* 4329 802.11n dualband device */
5107 	case BCM4329_D11N2G_ID:	/* 4329 802.11n 2.4G device */
5108 	case BCM4329_D11N5G_ID:	/* 4329 802.11n 5G device */
5109 	case 0x4329:
5110 		DHD_INFO(("%s: found 4329 Dongle\n", __func__));
5111 		break;
5112 	case BCM4319_D11N_ID:	/* 4319 802.11n id */
5113 	case BCM4319_D11N2G_ID:	/* 4319 802.11n2g id */
5114 	case BCM4319_D11N5G_ID:	/* 4319 802.11n5g id */
5115 		DHD_INFO(("%s: found 4319 Dongle\n", __func__));
5116 		break;
5117 	case 0:
5118 		DHD_INFO(("%s: allow device id 0, will check chip internals\n",
5119 			  __func__));
5120 		break;
5121 
5122 	default:
5123 		DHD_ERROR(("%s: skipping 0x%04x/0x%04x, not a dongle\n",
5124 			   __func__, venid, devid));
5125 		return NULL;
5126 	}
5127 
5128 	/* Allocate private bus interface state */
5129 	bus = kzalloc(sizeof(dhd_bus_t), GFP_ATOMIC);
5130 	if (!bus) {
5131 		DHD_ERROR(("%s: kmalloc of dhd_bus_t failed\n", __func__));
5132 		goto fail;
5133 	}
5134 	bus->sdh = sdh;
5135 	bus->cl_devid = (u16) devid;
5136 	bus->bus = DHD_BUS;
5137 	bus->tx_seq = SDPCM_SEQUENCE_WRAP - 1;
5138 	bus->usebufpool = false;	/* Use bufpool if allocated,
5139 					 else use locally malloced rxbuf */
5140 
5141 	/* attempt to attach to the dongle */
5142 	if (!(dhdsdio_probe_attach(bus, sdh, regsva, devid))) {
5143 		DHD_ERROR(("%s: dhdsdio_probe_attach failed\n", __func__));
5144 		goto fail;
5145 	}
5146 
5147 	/* Attach to the dhd/OS/network interface */
5148 	bus->dhd = dhd_attach(bus, SDPCM_RESERVE);
5149 	if (!bus->dhd) {
5150 		DHD_ERROR(("%s: dhd_attach failed\n", __func__));
5151 		goto fail;
5152 	}
5153 
5154 	/* Allocate buffers */
5155 	if (!(dhdsdio_probe_malloc(bus, sdh))) {
5156 		DHD_ERROR(("%s: dhdsdio_probe_malloc failed\n", __func__));
5157 		goto fail;
5158 	}
5159 
5160 	if (!(dhdsdio_probe_init(bus, sdh))) {
5161 		DHD_ERROR(("%s: dhdsdio_probe_init failed\n", __func__));
5162 		goto fail;
5163 	}
5164 
5165 	/* Register interrupt callback, but mask it (not operational yet). */
5166 	DHD_INTR(("%s: disable SDIO interrupts (not interested yet)\n",
5167 		  __func__));
5168 	bcmsdh_intr_disable(sdh);
5169 	ret = bcmsdh_intr_reg(sdh, dhdsdio_isr, bus);
5170 	if (ret != 0) {
5171 		DHD_ERROR(("%s: FAILED: bcmsdh_intr_reg returned %d\n",
5172 			   __func__, ret));
5173 		goto fail;
5174 	}
5175 	DHD_INTR(("%s: registered SDIO interrupt function ok\n", __func__));
5176 
5177 	DHD_INFO(("%s: completed!!\n", __func__));
5178 
5179 	/* if firmware path present try to download and bring up bus */
5180 	ret = dhd_bus_start(bus->dhd);
5181 	if (ret != 0) {
5182 		if (ret == BCME_NOTUP) {
5183 			DHD_ERROR(("%s: dongle is not responding\n", __func__));
5184 			goto fail;
5185 		}
5186 	}
5187 	/* Ok, have the per-port tell the stack we're open for business */
5188 	if (dhd_net_attach(bus->dhd, 0) != 0) {
5189 		DHD_ERROR(("%s: Net attach failed!!\n", __func__));
5190 		goto fail;
5191 	}
5192 
5193 	return bus;
5194 
5195 fail:
5196 	dhdsdio_release(bus);
5197 	return NULL;
5198 }
5199 
5200 static bool
dhdsdio_probe_attach(struct dhd_bus * bus,void * sdh,void * regsva,u16 devid)5201 dhdsdio_probe_attach(struct dhd_bus *bus, void *sdh, void *regsva, u16 devid)
5202 {
5203 	u8 clkctl = 0;
5204 	int err = 0;
5205 
5206 	bus->alp_only = true;
5207 
5208 	/* Return the window to backplane enumeration space for core access */
5209 	if (dhdsdio_set_siaddr_window(bus, SI_ENUM_BASE))
5210 		DHD_ERROR(("%s: FAILED to return to SI_ENUM_BASE\n", __func__));
5211 
5212 #ifdef DHD_DEBUG
5213 	printk(KERN_DEBUG "F1 signature read @0x18000000=0x%4x\n",
5214 	       bcmsdh_reg_read(bus->sdh, SI_ENUM_BASE, 4));
5215 
5216 #endif				/* DHD_DEBUG */
5217 
5218 	/* Force PLL off until si_attach() programs PLL control regs */
5219 
5220 	bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR,
5221 			 DHD_INIT_CLKCTL1, &err);
5222 	if (!err)
5223 		clkctl =
5224 		    bcmsdh_cfg_read(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR,
5225 				    &err);
5226 
5227 	if (err || ((clkctl & ~SBSDIO_AVBITS) != DHD_INIT_CLKCTL1)) {
5228 		DHD_ERROR(("dhdsdio_probe: ChipClkCSR access: err %d wrote "
5229 			"0x%02x read 0x%02x\n",
5230 			err, DHD_INIT_CLKCTL1, clkctl));
5231 		goto fail;
5232 	}
5233 #ifdef DHD_DEBUG
5234 	if (DHD_INFO_ON()) {
5235 		uint fn, numfn;
5236 		u8 *cis[SDIOD_MAX_IOFUNCS];
5237 		int err = 0;
5238 
5239 		numfn = bcmsdh_query_iofnum(sdh);
5240 		ASSERT(numfn <= SDIOD_MAX_IOFUNCS);
5241 
5242 		/* Make sure ALP is available before trying to read CIS */
5243 		SPINWAIT(((clkctl = bcmsdh_cfg_read(sdh, SDIO_FUNC_1,
5244 						    SBSDIO_FUNC1_CHIPCLKCSR,
5245 						    NULL)),
5246 			  !SBSDIO_ALPAV(clkctl)), PMU_MAX_TRANSITION_DLY);
5247 
5248 		/* Now request ALP be put on the bus */
5249 		bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR,
5250 				 DHD_INIT_CLKCTL2, &err);
5251 		udelay(65);
5252 
5253 		for (fn = 0; fn <= numfn; fn++) {
5254 			cis[fn] = kzalloc(SBSDIO_CIS_SIZE_LIMIT, GFP_ATOMIC);
5255 			if (!cis[fn]) {
5256 				DHD_INFO(("dhdsdio_probe: fn %d cis malloc "
5257 					"failed\n", fn));
5258 				break;
5259 			}
5260 
5261 			err = bcmsdh_cis_read(sdh, fn, cis[fn],
5262 						SBSDIO_CIS_SIZE_LIMIT);
5263 			if (err) {
5264 				DHD_INFO(("dhdsdio_probe: fn %d cis read "
5265 					"err %d\n", fn, err));
5266 				kfree(cis[fn]);
5267 				break;
5268 			}
5269 			dhd_dump_cis(fn, cis[fn]);
5270 		}
5271 
5272 		while (fn-- > 0) {
5273 			ASSERT(cis[fn]);
5274 			kfree(cis[fn]);
5275 		}
5276 
5277 		if (err) {
5278 			DHD_ERROR(("dhdsdio_probe: error read/parsing CIS\n"));
5279 			goto fail;
5280 		}
5281 	}
5282 #endif				/* DHD_DEBUG */
5283 
5284 	/* si_attach() will provide an SI handle and scan the backplane */
5285 	bus->sih = si_attach((uint) devid, regsva, DHD_BUS, sdh,
5286 				   &bus->vars, &bus->varsz);
5287 	if (!(bus->sih)) {
5288 		DHD_ERROR(("%s: si_attach failed!\n", __func__));
5289 		goto fail;
5290 	}
5291 
5292 	bcmsdh_chipinfo(sdh, bus->sih->chip, bus->sih->chiprev);
5293 
5294 	if (!dhdsdio_chipmatch((u16) bus->sih->chip)) {
5295 		DHD_ERROR(("%s: unsupported chip: 0x%04x\n",
5296 			   __func__, bus->sih->chip));
5297 		goto fail;
5298 	}
5299 
5300 	si_sdiod_drive_strength_init(bus->sih, dhd_sdiod_drive_strength);
5301 
5302 	/* Get info on the ARM and SOCRAM cores... */
5303 	if (!DHD_NOPMU(bus)) {
5304 		if ((si_setcore(bus->sih, ARM7S_CORE_ID, 0)) ||
5305 		    (si_setcore(bus->sih, ARMCM3_CORE_ID, 0))) {
5306 			bus->armrev = si_corerev(bus->sih);
5307 		} else {
5308 			DHD_ERROR(("%s: failed to find ARM core!\n", __func__));
5309 			goto fail;
5310 		}
5311 		bus->orig_ramsize = si_socram_size(bus->sih);
5312 		if (!(bus->orig_ramsize)) {
5313 			DHD_ERROR(("%s: failed to find SOCRAM memory!\n",
5314 				   __func__));
5315 			goto fail;
5316 		}
5317 		bus->ramsize = bus->orig_ramsize;
5318 		if (dhd_dongle_memsize)
5319 			dhd_dongle_setmemsize(bus, dhd_dongle_memsize);
5320 
5321 		DHD_ERROR(("DHD: dongle ram size is set to %d(orig %d)\n",
5322 			   bus->ramsize, bus->orig_ramsize));
5323 	}
5324 
5325 	/* ...but normally deal with the SDPCMDEV core */
5326 	bus->regs = si_setcore(bus->sih, PCMCIA_CORE_ID, 0);
5327 	if (!bus->regs) {
5328 		bus->regs = si_setcore(bus->sih, SDIOD_CORE_ID, 0);
5329 		if (!bus->regs) {
5330 			DHD_ERROR(("%s: failed to find SDIODEV core!\n",
5331 					__func__));
5332 			goto fail;
5333 		}
5334 	}
5335 	bus->sdpcmrev = si_corerev(bus->sih);
5336 
5337 	/* Set core control so an SDIO reset does a backplane reset */
5338 	OR_REG(&bus->regs->corecontrol, CC_BPRESEN);
5339 
5340 	pktq_init(&bus->txq, (PRIOMASK + 1), TXQLEN);
5341 
5342 	/* Locate an appropriately-aligned portion of hdrbuf */
5343 	bus->rxhdr = (u8 *) roundup((unsigned long)&bus->hdrbuf[0], DHD_SDALIGN);
5344 
5345 	/* Set the poll and/or interrupt flags */
5346 	bus->intr = (bool) dhd_intr;
5347 	bus->poll = (bool) dhd_poll;
5348 	if (bus->poll)
5349 		bus->pollrate = 1;
5350 
5351 	return true;
5352 
5353 fail:
5354 	return false;
5355 }
5356 
dhdsdio_probe_malloc(dhd_bus_t * bus,void * sdh)5357 static bool dhdsdio_probe_malloc(dhd_bus_t *bus, void *sdh)
5358 {
5359 	DHD_TRACE(("%s: Enter\n", __func__));
5360 
5361 	if (bus->dhd->maxctl) {
5362 		bus->rxblen =
5363 		    roundup((bus->dhd->maxctl + SDPCM_HDRLEN),
5364 			    ALIGNMENT) + DHD_SDALIGN;
5365 		bus->rxbuf = kmalloc(bus->rxblen, GFP_ATOMIC);
5366 		if (!(bus->rxbuf)) {
5367 			DHD_ERROR(("%s: kmalloc of %d-byte rxbuf failed\n",
5368 				   __func__, bus->rxblen));
5369 			goto fail;
5370 		}
5371 	}
5372 
5373 	/* Allocate buffer to receive glomed packet */
5374 	bus->databuf = kmalloc(MAX_DATA_BUF, GFP_ATOMIC);
5375 	if (!(bus->databuf)) {
5376 		DHD_ERROR(("%s: kmalloc of %d-byte databuf failed\n",
5377 			   __func__, MAX_DATA_BUF));
5378 		/* release rxbuf which was already located as above */
5379 		if (!bus->rxblen)
5380 			kfree(bus->rxbuf);
5381 		goto fail;
5382 	}
5383 
5384 	/* Align the buffer */
5385 	if ((unsigned long)bus->databuf % DHD_SDALIGN)
5386 		bus->dataptr =
5387 		    bus->databuf + (DHD_SDALIGN -
5388 				    ((unsigned long)bus->databuf % DHD_SDALIGN));
5389 	else
5390 		bus->dataptr = bus->databuf;
5391 
5392 	return true;
5393 
5394 fail:
5395 	return false;
5396 }
5397 
dhdsdio_probe_init(dhd_bus_t * bus,void * sdh)5398 static bool dhdsdio_probe_init(dhd_bus_t *bus, void *sdh)
5399 {
5400 	s32 fnum;
5401 
5402 	DHD_TRACE(("%s: Enter\n", __func__));
5403 
5404 #ifdef SDTEST
5405 	dhdsdio_pktgen_init(bus);
5406 #endif				/* SDTEST */
5407 
5408 	/* Disable F2 to clear any intermediate frame state on the dongle */
5409 	bcmsdh_cfg_write(sdh, SDIO_FUNC_0, SDIOD_CCCR_IOEN, SDIO_FUNC_ENABLE_1,
5410 			 NULL);
5411 
5412 	bus->dhd->busstate = DHD_BUS_DOWN;
5413 	bus->sleeping = false;
5414 	bus->rxflow = false;
5415 	bus->prev_rxlim_hit = 0;
5416 
5417 	/* Done with backplane-dependent accesses, can drop clock... */
5418 	bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, 0, NULL);
5419 
5420 	/* ...and initialize clock/power states */
5421 	bus->clkstate = CLK_SDONLY;
5422 	bus->idletime = (s32) dhd_idletime;
5423 	bus->idleclock = DHD_IDLE_ACTIVE;
5424 
5425 	/* Query the SD clock speed */
5426 	if (bcmsdh_iovar_op(sdh, "sd_divisor", NULL, 0,
5427 			    &bus->sd_divisor, sizeof(s32),
5428 			    false) != BCME_OK) {
5429 		DHD_ERROR(("%s: fail on %s get\n", __func__, "sd_divisor"));
5430 		bus->sd_divisor = -1;
5431 	} else {
5432 		DHD_INFO(("%s: Initial value for %s is %d\n",
5433 			  __func__, "sd_divisor", bus->sd_divisor));
5434 	}
5435 
5436 	/* Query the SD bus mode */
5437 	if (bcmsdh_iovar_op(sdh, "sd_mode", NULL, 0,
5438 			    &bus->sd_mode, sizeof(s32), false) != BCME_OK) {
5439 		DHD_ERROR(("%s: fail on %s get\n", __func__, "sd_mode"));
5440 		bus->sd_mode = -1;
5441 	} else {
5442 		DHD_INFO(("%s: Initial value for %s is %d\n",
5443 			  __func__, "sd_mode", bus->sd_mode));
5444 	}
5445 
5446 	/* Query the F2 block size, set roundup accordingly */
5447 	fnum = 2;
5448 	if (bcmsdh_iovar_op(sdh, "sd_blocksize", &fnum, sizeof(s32),
5449 			    &bus->blocksize, sizeof(s32), false) != BCME_OK) {
5450 		bus->blocksize = 0;
5451 		DHD_ERROR(("%s: fail on %s get\n", __func__, "sd_blocksize"));
5452 	} else {
5453 		DHD_INFO(("%s: Initial value for %s is %d\n",
5454 			  __func__, "sd_blocksize", bus->blocksize));
5455 	}
5456 	bus->roundup = min(max_roundup, bus->blocksize);
5457 
5458 	/* Query if bus module supports packet chaining,
5459 		 default to use if supported */
5460 	if (bcmsdh_iovar_op(sdh, "sd_rxchain", NULL, 0,
5461 			    &bus->sd_rxchain, sizeof(s32),
5462 			    false) != BCME_OK) {
5463 		bus->sd_rxchain = false;
5464 	} else {
5465 		DHD_INFO(("%s: bus module (through bcmsdh API) %s chaining\n",
5466 			  __func__,
5467 			  (bus->sd_rxchain ? "supports" : "does not support")));
5468 	}
5469 	bus->use_rxchain = (bool) bus->sd_rxchain;
5470 
5471 	return true;
5472 }
5473 
5474 bool
dhd_bus_download_firmware(struct dhd_bus * bus,char * fw_path,char * nv_path)5475 dhd_bus_download_firmware(struct dhd_bus *bus, char *fw_path, char *nv_path)
5476 {
5477 	bool ret;
5478 	bus->fw_path = fw_path;
5479 	bus->nv_path = nv_path;
5480 
5481 	ret = dhdsdio_download_firmware(bus, bus->sdh);
5482 
5483 	return ret;
5484 }
5485 
5486 static bool
dhdsdio_download_firmware(struct dhd_bus * bus,void * sdh)5487 dhdsdio_download_firmware(struct dhd_bus *bus, void *sdh)
5488 {
5489 	bool ret;
5490 
5491 	/* Download the firmware */
5492 	dhdsdio_clkctl(bus, CLK_AVAIL, false);
5493 
5494 	ret = _dhdsdio_download_firmware(bus) == 0;
5495 
5496 	dhdsdio_clkctl(bus, CLK_SDONLY, false);
5497 
5498 	return ret;
5499 }
5500 
5501 /* Detach and free everything */
dhdsdio_release(dhd_bus_t * bus)5502 static void dhdsdio_release(dhd_bus_t *bus)
5503 {
5504 	DHD_TRACE(("%s: Enter\n", __func__));
5505 
5506 	if (bus) {
5507 		/* De-register interrupt handler */
5508 		bcmsdh_intr_disable(bus->sdh);
5509 		bcmsdh_intr_dereg(bus->sdh);
5510 
5511 		if (bus->dhd) {
5512 
5513 			dhdsdio_release_dongle(bus);
5514 
5515 			dhd_detach(bus->dhd);
5516 			bus->dhd = NULL;
5517 		}
5518 
5519 		dhdsdio_release_malloc(bus);
5520 
5521 		kfree(bus);
5522 	}
5523 
5524 	DHD_TRACE(("%s: Disconnected\n", __func__));
5525 }
5526 
dhdsdio_release_malloc(dhd_bus_t * bus)5527 static void dhdsdio_release_malloc(dhd_bus_t *bus)
5528 {
5529 	DHD_TRACE(("%s: Enter\n", __func__));
5530 
5531 	if (bus->dhd && bus->dhd->dongle_reset)
5532 		return;
5533 
5534 	if (bus->rxbuf) {
5535 		kfree(bus->rxbuf);
5536 		bus->rxctl = bus->rxbuf = NULL;
5537 		bus->rxlen = 0;
5538 	}
5539 
5540 	kfree(bus->databuf);
5541 	bus->databuf = NULL;
5542 }
5543 
dhdsdio_release_dongle(dhd_bus_t * bus)5544 static void dhdsdio_release_dongle(dhd_bus_t *bus)
5545 {
5546 	DHD_TRACE(("%s: Enter\n", __func__));
5547 
5548 	if (bus->dhd && bus->dhd->dongle_reset)
5549 		return;
5550 
5551 	if (bus->sih) {
5552 		dhdsdio_clkctl(bus, CLK_AVAIL, false);
5553 #if !defined(BCMLXSDMMC)
5554 		si_watchdog(bus->sih, 4);
5555 #endif				/* !defined(BCMLXSDMMC) */
5556 		dhdsdio_clkctl(bus, CLK_NONE, false);
5557 		si_detach(bus->sih);
5558 		if (bus->vars && bus->varsz)
5559 			kfree(bus->vars);
5560 		bus->vars = NULL;
5561 	}
5562 
5563 	DHD_TRACE(("%s: Disconnected\n", __func__));
5564 }
5565 
dhdsdio_disconnect(void * ptr)5566 static void dhdsdio_disconnect(void *ptr)
5567 {
5568 	dhd_bus_t *bus = (dhd_bus_t *)ptr;
5569 
5570 	DHD_TRACE(("%s: Enter\n", __func__));
5571 
5572 	if (bus) {
5573 		ASSERT(bus->dhd);
5574 		dhdsdio_release(bus);
5575 	}
5576 
5577 	DHD_TRACE(("%s: Disconnected\n", __func__));
5578 }
5579 
5580 /* Register/Unregister functions are called by the main DHD entry
5581  * point (e.g. module insertion) to link with the bus driver, in
5582  * order to look for or await the device.
5583  */
5584 
5585 static bcmsdh_driver_t dhd_sdio = {
5586 	dhdsdio_probe,
5587 	dhdsdio_disconnect
5588 };
5589 
dhd_bus_register(void)5590 int dhd_bus_register(void)
5591 {
5592 	DHD_TRACE(("%s: Enter\n", __func__));
5593 
5594 	return bcmsdh_register(&dhd_sdio);
5595 }
5596 
dhd_bus_unregister(void)5597 void dhd_bus_unregister(void)
5598 {
5599 	DHD_TRACE(("%s: Enter\n", __func__));
5600 
5601 	bcmsdh_unregister();
5602 }
5603 
5604 #ifdef BCMEMBEDIMAGE
dhdsdio_download_code_array(struct dhd_bus * bus)5605 static int dhdsdio_download_code_array(struct dhd_bus *bus)
5606 {
5607 	int bcmerror = -1;
5608 	int offset = 0;
5609 
5610 	DHD_INFO(("%s: download embedded firmware...\n", __func__));
5611 
5612 	/* Download image */
5613 	while ((offset + MEMBLOCK) < sizeof(dlarray)) {
5614 		bcmerror =
5615 		    dhdsdio_membytes(bus, true, offset, dlarray + offset,
5616 				     MEMBLOCK);
5617 		if (bcmerror) {
5618 			DHD_ERROR(("%s: error %d on writing %d membytes at "
5619 				"0x%08x\n",
5620 				__func__, bcmerror, MEMBLOCK, offset));
5621 			goto err;
5622 		}
5623 
5624 		offset += MEMBLOCK;
5625 	}
5626 
5627 	if (offset < sizeof(dlarray)) {
5628 		bcmerror = dhdsdio_membytes(bus, true, offset,
5629 					    dlarray + offset,
5630 					    sizeof(dlarray) - offset);
5631 		if (bcmerror) {
5632 			DHD_ERROR(("%s: error %d on writing %d membytes at "
5633 				"0x%08x\n", __func__, bcmerror,
5634 				sizeof(dlarray) - offset, offset));
5635 			goto err;
5636 		}
5637 	}
5638 #ifdef DHD_DEBUG
5639 	/* Upload and compare the downloaded code */
5640 	{
5641 		unsigned char *ularray;
5642 
5643 		ularray = kmalloc(bus->ramsize, GFP_ATOMIC);
5644 		if (!ularray) {
5645 			bcmerror = BCME_NOMEM;
5646 			goto err;
5647 		}
5648 		/* Upload image to verify downloaded contents. */
5649 		offset = 0;
5650 		memset(ularray, 0xaa, bus->ramsize);
5651 		while ((offset + MEMBLOCK) < sizeof(dlarray)) {
5652 			bcmerror =
5653 			    dhdsdio_membytes(bus, false, offset,
5654 					     ularray + offset, MEMBLOCK);
5655 			if (bcmerror) {
5656 				DHD_ERROR(("%s: error %d on reading %d membytes"
5657 					" at 0x%08x\n",
5658 					__func__, bcmerror, MEMBLOCK, offset));
5659 				goto free;
5660 			}
5661 
5662 			offset += MEMBLOCK;
5663 		}
5664 
5665 		if (offset < sizeof(dlarray)) {
5666 			bcmerror = dhdsdio_membytes(bus, false, offset,
5667 						    ularray + offset,
5668 						    sizeof(dlarray) - offset);
5669 			if (bcmerror) {
5670 				DHD_ERROR(("%s: error %d on reading %d membytes at 0x%08x\n",
5671 				__func__, bcmerror,
5672 				sizeof(dlarray) - offset, offset));
5673 				goto free;
5674 			}
5675 		}
5676 
5677 		if (memcmp(dlarray, ularray, sizeof(dlarray))) {
5678 			DHD_ERROR(("%s: Downloaded image is corrupted.\n",
5679 				   __func__));
5680 			ASSERT(0);
5681 			goto free;
5682 		} else
5683 			DHD_ERROR(("%s: Download/Upload/Compare succeeded.\n",
5684 				__func__));
5685 free:
5686 		kfree(ularray);
5687 	}
5688 #endif				/* DHD_DEBUG */
5689 
5690 err:
5691 	return bcmerror;
5692 }
5693 #endif				/* BCMEMBEDIMAGE */
5694 
dhdsdio_download_code_file(struct dhd_bus * bus,char * fw_path)5695 static int dhdsdio_download_code_file(struct dhd_bus *bus, char *fw_path)
5696 {
5697 	int bcmerror = -1;
5698 	int offset = 0;
5699 	uint len;
5700 	void *image = NULL;
5701 	u8 *memblock = NULL, *memptr;
5702 
5703 	DHD_INFO(("%s: download firmware %s\n", __func__, fw_path));
5704 
5705 	image = dhd_os_open_image(fw_path);
5706 	if (image == NULL)
5707 		goto err;
5708 
5709 	memptr = memblock = kmalloc(MEMBLOCK + DHD_SDALIGN, GFP_ATOMIC);
5710 	if (memblock == NULL) {
5711 		DHD_ERROR(("%s: Failed to allocate memory %d bytes\n",
5712 			   __func__, MEMBLOCK));
5713 		goto err;
5714 	}
5715 	if ((u32)(unsigned long)memblock % DHD_SDALIGN)
5716 		memptr +=
5717 		    (DHD_SDALIGN - ((u32)(unsigned long)memblock % DHD_SDALIGN));
5718 
5719 	/* Download image */
5720 	while ((len =
5721 		dhd_os_get_image_block((char *)memptr, MEMBLOCK, image))) {
5722 		bcmerror = dhdsdio_membytes(bus, true, offset, memptr, len);
5723 		if (bcmerror) {
5724 			DHD_ERROR(("%s: error %d on writing %d membytes at "
5725 			"0x%08x\n", __func__, bcmerror, MEMBLOCK, offset));
5726 			goto err;
5727 		}
5728 
5729 		offset += MEMBLOCK;
5730 	}
5731 
5732 err:
5733 	kfree(memblock);
5734 
5735 	if (image)
5736 		dhd_os_close_image(image);
5737 
5738 	return bcmerror;
5739 }
5740 
5741 /*
5742  * ProcessVars:Takes a buffer of "<var>=<value>\n" lines read from a file
5743  * and ending in a NUL.
5744  * Removes carriage returns, empty lines, comment lines, and converts
5745  * newlines to NULs.
5746  * Shortens buffer as needed and pads with NULs.  End of buffer is marked
5747  * by two NULs.
5748 */
5749 
process_nvram_vars(char * varbuf,uint len)5750 static uint process_nvram_vars(char *varbuf, uint len)
5751 {
5752 	char *dp;
5753 	bool findNewline;
5754 	int column;
5755 	uint buf_len, n;
5756 
5757 	dp = varbuf;
5758 
5759 	findNewline = false;
5760 	column = 0;
5761 
5762 	for (n = 0; n < len; n++) {
5763 		if (varbuf[n] == 0)
5764 			break;
5765 		if (varbuf[n] == '\r')
5766 			continue;
5767 		if (findNewline && varbuf[n] != '\n')
5768 			continue;
5769 		findNewline = false;
5770 		if (varbuf[n] == '#') {
5771 			findNewline = true;
5772 			continue;
5773 		}
5774 		if (varbuf[n] == '\n') {
5775 			if (column == 0)
5776 				continue;
5777 			*dp++ = 0;
5778 			column = 0;
5779 			continue;
5780 		}
5781 		*dp++ = varbuf[n];
5782 		column++;
5783 	}
5784 	buf_len = dp - varbuf;
5785 
5786 	while (dp < varbuf + n)
5787 		*dp++ = 0;
5788 
5789 	return buf_len;
5790 }
5791 
5792 /*
5793 	EXAMPLE: nvram_array
5794 	nvram_arry format:
5795 	name=value
5796 	Use carriage return at the end of each assignment,
5797 	 and an empty string with
5798 	carriage return at the end of array.
5799 
5800 	For example:
5801 	unsigned char  nvram_array[] = {"name1=value1\n",
5802 	"name2=value2\n", "\n"};
5803 	Hex values start with 0x, and mac addr format: xx:xx:xx:xx:xx:xx.
5804 
5805 	Search "EXAMPLE: nvram_array" to see how the array is activated.
5806 */
5807 
dhd_bus_set_nvram_params(struct dhd_bus * bus,const char * nvram_params)5808 void dhd_bus_set_nvram_params(struct dhd_bus *bus, const char *nvram_params)
5809 {
5810 	bus->nvram_params = nvram_params;
5811 }
5812 
dhdsdio_download_nvram(struct dhd_bus * bus)5813 static int dhdsdio_download_nvram(struct dhd_bus *bus)
5814 {
5815 	int bcmerror = -1;
5816 	uint len;
5817 	void *image = NULL;
5818 	char *memblock = NULL;
5819 	char *bufp;
5820 	char *nv_path;
5821 	bool nvram_file_exists;
5822 
5823 	nv_path = bus->nv_path;
5824 
5825 	nvram_file_exists = ((nv_path != NULL) && (nv_path[0] != '\0'));
5826 	if (!nvram_file_exists && (bus->nvram_params == NULL))
5827 		return 0;
5828 
5829 	if (nvram_file_exists) {
5830 		image = dhd_os_open_image(nv_path);
5831 		if (image == NULL)
5832 			goto err;
5833 	}
5834 
5835 	memblock = kmalloc(MEMBLOCK, GFP_ATOMIC);
5836 	if (memblock == NULL) {
5837 		DHD_ERROR(("%s: Failed to allocate memory %d bytes\n",
5838 			   __func__, MEMBLOCK));
5839 		goto err;
5840 	}
5841 
5842 	/* Download variables */
5843 	if (nvram_file_exists) {
5844 		len = dhd_os_get_image_block(memblock, MEMBLOCK, image);
5845 	} else {
5846 		len = strlen(bus->nvram_params);
5847 		ASSERT(len <= MEMBLOCK);
5848 		if (len > MEMBLOCK)
5849 			len = MEMBLOCK;
5850 		memcpy(memblock, bus->nvram_params, len);
5851 	}
5852 
5853 	if (len > 0 && len < MEMBLOCK) {
5854 		bufp = (char *)memblock;
5855 		bufp[len] = 0;
5856 		len = process_nvram_vars(bufp, len);
5857 		bufp += len;
5858 		*bufp++ = 0;
5859 		if (len)
5860 			bcmerror = dhdsdio_downloadvars(bus, memblock, len + 1);
5861 		if (bcmerror) {
5862 			DHD_ERROR(("%s: error downloading vars: %d\n",
5863 				   __func__, bcmerror));
5864 		}
5865 	} else {
5866 		DHD_ERROR(("%s: error reading nvram file: %d\n",
5867 			   __func__, len));
5868 		bcmerror = BCME_SDIO_ERROR;
5869 	}
5870 
5871 err:
5872 	kfree(memblock);
5873 
5874 	if (image)
5875 		dhd_os_close_image(image);
5876 
5877 	return bcmerror;
5878 }
5879 
_dhdsdio_download_firmware(struct dhd_bus * bus)5880 static int _dhdsdio_download_firmware(struct dhd_bus *bus)
5881 {
5882 	int bcmerror = -1;
5883 
5884 	bool embed = false;	/* download embedded firmware */
5885 	bool dlok = false;	/* download firmware succeeded */
5886 
5887 	/* Out immediately if no image to download */
5888 	if ((bus->fw_path == NULL) || (bus->fw_path[0] == '\0')) {
5889 #ifdef BCMEMBEDIMAGE
5890 		embed = true;
5891 #else
5892 		return bcmerror;
5893 #endif
5894 	}
5895 
5896 	/* Keep arm in reset */
5897 	if (dhdsdio_download_state(bus, true)) {
5898 		DHD_ERROR(("%s: error placing ARM core in reset\n", __func__));
5899 		goto err;
5900 	}
5901 
5902 	/* External image takes precedence if specified */
5903 	if ((bus->fw_path != NULL) && (bus->fw_path[0] != '\0')) {
5904 		if (dhdsdio_download_code_file(bus, bus->fw_path)) {
5905 			DHD_ERROR(("%s: dongle image file download failed\n",
5906 				   __func__));
5907 #ifdef BCMEMBEDIMAGE
5908 			embed = true;
5909 #else
5910 			goto err;
5911 #endif
5912 		} else {
5913 			embed = false;
5914 			dlok = true;
5915 		}
5916 	}
5917 #ifdef BCMEMBEDIMAGE
5918 	if (embed) {
5919 		if (dhdsdio_download_code_array(bus)) {
5920 			DHD_ERROR(("%s: dongle image array download failed\n",
5921 				   __func__));
5922 			goto err;
5923 		} else {
5924 			dlok = true;
5925 		}
5926 	}
5927 #endif
5928 	if (!dlok) {
5929 		DHD_ERROR(("%s: dongle image download failed\n", __func__));
5930 		goto err;
5931 	}
5932 
5933 	/* EXAMPLE: nvram_array */
5934 	/* If a valid nvram_arry is specified as above, it can be passed
5935 		 down to dongle */
5936 	/* dhd_bus_set_nvram_params(bus, (char *)&nvram_array); */
5937 
5938 	/* External nvram takes precedence if specified */
5939 	if (dhdsdio_download_nvram(bus)) {
5940 		DHD_ERROR(("%s: dongle nvram file download failed\n",
5941 			   __func__));
5942 	}
5943 
5944 	/* Take arm out of reset */
5945 	if (dhdsdio_download_state(bus, false)) {
5946 		DHD_ERROR(("%s: error getting out of ARM core reset\n",
5947 			   __func__));
5948 		goto err;
5949 	}
5950 
5951 	bcmerror = 0;
5952 
5953 err:
5954 	return bcmerror;
5955 }
5956 
5957 static int
dhd_bcmsdh_recv_buf(dhd_bus_t * bus,u32 addr,uint fn,uint flags,u8 * buf,uint nbytes,struct sk_buff * pkt,bcmsdh_cmplt_fn_t complete,void * handle)5958 dhd_bcmsdh_recv_buf(dhd_bus_t *bus, u32 addr, uint fn, uint flags,
5959 		    u8 *buf, uint nbytes, struct sk_buff *pkt,
5960 		    bcmsdh_cmplt_fn_t complete, void *handle)
5961 {
5962 	int status;
5963 
5964 	/* 4329: GSPI check */
5965 	status =
5966 	    bcmsdh_recv_buf(bus->sdh, addr, fn, flags, buf, nbytes, pkt,
5967 			    complete, handle);
5968 	return status;
5969 }
5970 
5971 static int
dhd_bcmsdh_send_buf(dhd_bus_t * bus,u32 addr,uint fn,uint flags,u8 * buf,uint nbytes,struct sk_buff * pkt,bcmsdh_cmplt_fn_t complete,void * handle)5972 dhd_bcmsdh_send_buf(dhd_bus_t *bus, u32 addr, uint fn, uint flags,
5973 		    u8 *buf, uint nbytes, struct sk_buff *pkt,
5974 		    bcmsdh_cmplt_fn_t complete, void *handle)
5975 {
5976 	return bcmsdh_send_buf
5977 		(bus->sdh, addr, fn, flags, buf, nbytes, pkt, complete,
5978 		 handle);
5979 }
5980 
dhd_bus_chip(struct dhd_bus * bus)5981 uint dhd_bus_chip(struct dhd_bus *bus)
5982 {
5983 	ASSERT(bus->sih != NULL);
5984 	return bus->sih->chip;
5985 }
5986 
dhd_bus_pub(struct dhd_bus * bus)5987 void *dhd_bus_pub(struct dhd_bus *bus)
5988 {
5989 	return bus->dhd;
5990 }
5991 
dhd_bus_txq(struct dhd_bus * bus)5992 void *dhd_bus_txq(struct dhd_bus *bus)
5993 {
5994 	return &bus->txq;
5995 }
5996 
dhd_bus_hdrlen(struct dhd_bus * bus)5997 uint dhd_bus_hdrlen(struct dhd_bus *bus)
5998 {
5999 	return SDPCM_HDRLEN;
6000 }
6001 
dhd_bus_devreset(dhd_pub_t * dhdp,u8 flag)6002 int dhd_bus_devreset(dhd_pub_t *dhdp, u8 flag)
6003 {
6004 	int bcmerror = 0;
6005 	dhd_bus_t *bus;
6006 
6007 	bus = dhdp->bus;
6008 
6009 	if (flag == true) {
6010 		if (!bus->dhd->dongle_reset) {
6011 			/* Expect app to have torn down any
6012 			 connection before calling */
6013 			/* Stop the bus, disable F2 */
6014 			dhd_bus_stop(bus, false);
6015 
6016 			/* Clean tx/rx buffer pointers,
6017 			 detach from the dongle */
6018 			dhdsdio_release_dongle(bus);
6019 
6020 			bus->dhd->dongle_reset = true;
6021 			bus->dhd->up = false;
6022 
6023 			DHD_TRACE(("%s:  WLAN OFF DONE\n", __func__));
6024 			/* App can now remove power from device */
6025 		} else
6026 			bcmerror = BCME_SDIO_ERROR;
6027 	} else {
6028 		/* App must have restored power to device before calling */
6029 
6030 		DHD_TRACE(("\n\n%s: == WLAN ON ==\n", __func__));
6031 
6032 		if (bus->dhd->dongle_reset) {
6033 			/* Turn on WLAN */
6034 			/* Reset SD client */
6035 			bcmsdh_reset(bus->sdh);
6036 
6037 			/* Attempt to re-attach & download */
6038 			if (dhdsdio_probe_attach(bus, bus->sdh,
6039 						 (u32 *) SI_ENUM_BASE,
6040 						 bus->cl_devid)) {
6041 				/* Attempt to download binary to the dongle */
6042 				if (dhdsdio_probe_init
6043 				    (bus, bus->sdh)
6044 				    && dhdsdio_download_firmware(bus,
6045 								 bus->sdh)) {
6046 
6047 					/* Re-init bus, enable F2 transfer */
6048 					dhd_bus_init((dhd_pub_t *) bus->dhd,
6049 						     false);
6050 
6051 #if defined(OOB_INTR_ONLY)
6052 					dhd_enable_oob_intr(bus, true);
6053 #endif				/* defined(OOB_INTR_ONLY) */
6054 
6055 					bus->dhd->dongle_reset = false;
6056 					bus->dhd->up = true;
6057 
6058 					DHD_TRACE(("%s: WLAN ON DONE\n",
6059 						   __func__));
6060 				} else
6061 					bcmerror = BCME_SDIO_ERROR;
6062 			} else
6063 				bcmerror = BCME_SDIO_ERROR;
6064 		} else {
6065 			bcmerror = BCME_NOTDOWN;
6066 			DHD_ERROR(("%s: Set DEVRESET=false invoked when device "
6067 				"is on\n", __func__));
6068 			bcmerror = BCME_SDIO_ERROR;
6069 		}
6070 	}
6071 	return bcmerror;
6072 }
6073