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