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