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