aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/brcm80211
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/brcm80211')
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/Makefile1
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c40
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h21
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c4
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c339
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/nvram.c94
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/nvram.h24
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c593
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.h31
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/usb.c4
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c1
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c1
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/main.c2
13 files changed, 607 insertions, 548 deletions
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/Makefile b/drivers/net/wireless/brcm80211/brcmfmac/Makefile
index 5681b9862023..57cddee03252 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/Makefile
+++ b/drivers/net/wireless/brcm80211/brcmfmac/Makefile
@@ -32,6 +32,7 @@ brcmfmac-objs += \
32 bcdc.o \ 32 bcdc.o \
33 dhd_common.o \ 33 dhd_common.o \
34 dhd_linux.o \ 34 dhd_linux.o \
35 nvram.o \
35 btcoex.o 36 btcoex.o
36brcmfmac-$(CONFIG_BRCMFMAC_SDIO) += \ 37brcmfmac-$(CONFIG_BRCMFMAC_SDIO) += \
37 dhd_sdio.o \ 38 dhd_sdio.o \
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
index 34c993dd0602..fa35b23bbaa7 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
@@ -287,6 +287,9 @@ static int brcmf_sdiod_regrw_helper(struct brcmf_sdio_dev *sdiodev, u32 addr,
287 s32 retry = 0; 287 s32 retry = 0;
288 int ret; 288 int ret;
289 289
290 if (sdiodev->bus_if->state == BRCMF_BUS_NOMEDIUM)
291 return -ENOMEDIUM;
292
290 /* 293 /*
291 * figure out how to read the register based on address range 294 * figure out how to read the register based on address range
292 * 0x00 ~ 0x7FF: function 0 CCCR and FBR 295 * 0x00 ~ 0x7FF: function 0 CCCR and FBR
@@ -306,9 +309,12 @@ static int brcmf_sdiod_regrw_helper(struct brcmf_sdio_dev *sdiodev, u32 addr,
306 usleep_range(1000, 2000); 309 usleep_range(1000, 2000);
307 ret = brcmf_sdiod_request_data(sdiodev, func_num, addr, regsz, 310 ret = brcmf_sdiod_request_data(sdiodev, func_num, addr, regsz,
308 data, write); 311 data, write);
309 } while (ret != 0 && retry++ < SDIOH_API_ACCESS_RETRY_LIMIT); 312 } while (ret != 0 && ret != -ENOMEDIUM &&
313 retry++ < SDIOH_API_ACCESS_RETRY_LIMIT);
310 314
311 if (ret != 0) 315 if (ret == -ENOMEDIUM)
316 brcmf_bus_change_state(sdiodev->bus_if, BRCMF_BUS_NOMEDIUM);
317 else if (ret != 0)
312 brcmf_err("failed with %d\n", ret); 318 brcmf_err("failed with %d\n", ret);
313 319
314 return ret; 320 return ret;
@@ -320,6 +326,9 @@ brcmf_sdiod_set_sbaddr_window(struct brcmf_sdio_dev *sdiodev, u32 address)
320 int err = 0, i; 326 int err = 0, i;
321 u8 addr[3]; 327 u8 addr[3];
322 328
329 if (sdiodev->bus_if->state == BRCMF_BUS_NOMEDIUM)
330 return -ENOMEDIUM;
331
323 addr[0] = (address >> 8) & SBSDIO_SBADDRLOW_MASK; 332 addr[0] = (address >> 8) & SBSDIO_SBADDRLOW_MASK;
324 addr[1] = (address >> 16) & SBSDIO_SBADDRMID_MASK; 333 addr[1] = (address >> 16) & SBSDIO_SBADDRMID_MASK;
325 addr[2] = (address >> 24) & SBSDIO_SBADDRHIGH_MASK; 334 addr[2] = (address >> 24) & SBSDIO_SBADDRHIGH_MASK;
@@ -429,6 +438,7 @@ static int brcmf_sdiod_buffrw(struct brcmf_sdio_dev *sdiodev, uint fn,
429 bool write, u32 addr, struct sk_buff *pkt) 438 bool write, u32 addr, struct sk_buff *pkt)
430{ 439{
431 unsigned int req_sz; 440 unsigned int req_sz;
441 int err;
432 442
433 brcmf_sdiod_pm_resume_wait(sdiodev, &sdiodev->request_buffer_wait); 443 brcmf_sdiod_pm_resume_wait(sdiodev, &sdiodev->request_buffer_wait);
434 if (brcmf_sdiod_pm_resume_error(sdiodev)) 444 if (brcmf_sdiod_pm_resume_error(sdiodev))
@@ -439,18 +449,18 @@ static int brcmf_sdiod_buffrw(struct brcmf_sdio_dev *sdiodev, uint fn,
439 req_sz &= (uint)~3; 449 req_sz &= (uint)~3;
440 450
441 if (write) 451 if (write)
442 return sdio_memcpy_toio(sdiodev->func[fn], addr, 452 err = sdio_memcpy_toio(sdiodev->func[fn], addr,
443 ((u8 *)(pkt->data)), 453 ((u8 *)(pkt->data)), req_sz);
444 req_sz);
445 else if (fn == 1) 454 else if (fn == 1)
446 return sdio_memcpy_fromio(sdiodev->func[fn], 455 err = sdio_memcpy_fromio(sdiodev->func[fn], ((u8 *)(pkt->data)),
447 ((u8 *)(pkt->data)), 456 addr, req_sz);
448 addr, req_sz);
449 else 457 else
450 /* function 2 read is FIFO operation */ 458 /* function 2 read is FIFO operation */
451 return sdio_readsb(sdiodev->func[fn], 459 err = sdio_readsb(sdiodev->func[fn], ((u8 *)(pkt->data)), addr,
452 ((u8 *)(pkt->data)), addr, 460 req_sz);
453 req_sz); 461 if (err == -ENOMEDIUM)
462 brcmf_bus_change_state(sdiodev->bus_if, BRCMF_BUS_NOMEDIUM);
463 return err;
454} 464}
455 465
456/** 466/**
@@ -593,7 +603,11 @@ static int brcmf_sdiod_sglist_rw(struct brcmf_sdio_dev *sdiodev, uint fn,
593 mmc_wait_for_req(sdiodev->func[fn]->card->host, &mmc_req); 603 mmc_wait_for_req(sdiodev->func[fn]->card->host, &mmc_req);
594 604
595 ret = mmc_cmd.error ? mmc_cmd.error : mmc_dat.error; 605 ret = mmc_cmd.error ? mmc_cmd.error : mmc_dat.error;
596 if (ret != 0) { 606 if (ret == -ENOMEDIUM) {
607 brcmf_bus_change_state(sdiodev->bus_if,
608 BRCMF_BUS_NOMEDIUM);
609 break;
610 } else if (ret != 0) {
597 brcmf_err("CMD53 sg block %s failed %d\n", 611 brcmf_err("CMD53 sg block %s failed %d\n",
598 write ? "write" : "read", ret); 612 write ? "write" : "read", ret);
599 ret = -EIO; 613 ret = -EIO;
@@ -852,8 +866,6 @@ int brcmf_sdiod_abort(struct brcmf_sdio_dev *sdiodev, uint fn)
852 866
853static int brcmf_sdiod_remove(struct brcmf_sdio_dev *sdiodev) 867static int brcmf_sdiod_remove(struct brcmf_sdio_dev *sdiodev)
854{ 868{
855 sdiodev->bus_if->state = BRCMF_BUS_DOWN;
856
857 if (sdiodev->bus) { 869 if (sdiodev->bus) {
858 brcmf_sdio_remove(sdiodev->bus); 870 brcmf_sdio_remove(sdiodev->bus);
859 sdiodev->bus = NULL; 871 sdiodev->bus = NULL;
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h
index 5c12a07673fa..c4535616064e 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h
@@ -17,8 +17,12 @@
17#ifndef _BRCMF_BUS_H_ 17#ifndef _BRCMF_BUS_H_
18#define _BRCMF_BUS_H_ 18#define _BRCMF_BUS_H_
19 19
20#include "dhd_dbg.h"
21
20/* The level of bus communication with the dongle */ 22/* The level of bus communication with the dongle */
21enum brcmf_bus_state { 23enum brcmf_bus_state {
24 BRCMF_BUS_UNKNOWN, /* Not determined yet */
25 BRCMF_BUS_NOMEDIUM, /* No medium access to dongle */
22 BRCMF_BUS_DOWN, /* Not ready for frame transfers */ 26 BRCMF_BUS_DOWN, /* Not ready for frame transfers */
23 BRCMF_BUS_LOAD, /* Download access only (CPU reset) */ 27 BRCMF_BUS_LOAD, /* Download access only (CPU reset) */
24 BRCMF_BUS_DATA /* Ready for frame transfers */ 28 BRCMF_BUS_DATA /* Ready for frame transfers */
@@ -144,6 +148,23 @@ struct pktq *brcmf_bus_gettxq(struct brcmf_bus *bus)
144 148
145 return bus->ops->gettxq(bus->dev); 149 return bus->ops->gettxq(bus->dev);
146} 150}
151
152static inline bool brcmf_bus_ready(struct brcmf_bus *bus)
153{
154 return bus->state == BRCMF_BUS_LOAD || bus->state == BRCMF_BUS_DATA;
155}
156
157static inline void brcmf_bus_change_state(struct brcmf_bus *bus,
158 enum brcmf_bus_state new_state)
159{
160 /* NOMEDIUM is permanent */
161 if (bus->state == BRCMF_BUS_NOMEDIUM)
162 return;
163
164 brcmf_dbg(TRACE, "%d -> %d\n", bus->state, new_state);
165 bus->state = new_state;
166}
167
147/* 168/*
148 * interface functions from common layer 169 * interface functions from common layer
149 */ 170 */
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
index af39edae8c62..d4d966beb840 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
@@ -934,7 +934,7 @@ int brcmf_bus_start(struct device *dev)
934 p2p_ifp = NULL; 934 p2p_ifp = NULL;
935 935
936 /* signal bus ready */ 936 /* signal bus ready */
937 bus_if->state = BRCMF_BUS_DATA; 937 brcmf_bus_change_state(bus_if, BRCMF_BUS_DATA);
938 938
939 /* Bus is ready, do any initialization */ 939 /* Bus is ready, do any initialization */
940 ret = brcmf_c_preinit_dcmds(ifp); 940 ret = brcmf_c_preinit_dcmds(ifp);
@@ -1029,6 +1029,8 @@ void brcmf_detach(struct device *dev)
1029 /* stop firmware event handling */ 1029 /* stop firmware event handling */
1030 brcmf_fweh_detach(drvr); 1030 brcmf_fweh_detach(drvr);
1031 1031
1032 brcmf_bus_change_state(bus_if, BRCMF_BUS_DOWN);
1033
1032 /* make sure primary interface removed last */ 1034 /* make sure primary interface removed last */
1033 for (i = BRCMF_MAX_IFS-1; i > -1; i--) 1035 for (i = BRCMF_MAX_IFS-1; i > -1; i--)
1034 if (drvr->iflist[i]) { 1036 if (drvr->iflist[i]) {
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
index 9c7f08a13105..3e991897d7ca 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
@@ -41,6 +41,7 @@
41#include <soc.h> 41#include <soc.h>
42#include "sdio_host.h" 42#include "sdio_host.h"
43#include "sdio_chip.h" 43#include "sdio_chip.h"
44#include "nvram.h"
44 45
45#define DCMD_RESP_TIMEOUT 2000 /* In milli second */ 46#define DCMD_RESP_TIMEOUT 2000 /* In milli second */
46 47
@@ -368,9 +369,7 @@ struct brcmf_sdio_hdrinfo {
368/* Private data for SDIO bus interaction */ 369/* Private data for SDIO bus interaction */
369struct brcmf_sdio { 370struct brcmf_sdio {
370 struct brcmf_sdio_dev *sdiodev; /* sdio device handler */ 371 struct brcmf_sdio_dev *sdiodev; /* sdio device handler */
371 struct chip_info *ci; /* Chip info struct */ 372 struct brcmf_chip *ci; /* Chip info struct */
372 char *vars; /* Variables (from CIS and/or other) */
373 uint varsz; /* Size of variables buffer */
374 373
375 u32 ramsize; /* Size of RAM in SOCRAM (bytes) */ 374 u32 ramsize; /* Size of RAM in SOCRAM (bytes) */
376 375
@@ -1083,10 +1082,6 @@ static void brcmf_sdio_rxfail(struct brcmf_sdio *bus, bool abort, bool rtx)
1083 1082
1084 /* Clear partial in any case */ 1083 /* Clear partial in any case */
1085 bus->cur_read.len = 0; 1084 bus->cur_read.len = 0;
1086
1087 /* If we can't reach the device, signal failure */
1088 if (err)
1089 bus->sdiodev->bus_if->state = BRCMF_BUS_DOWN;
1090} 1085}
1091 1086
1092/* return total length of buffer chain */ 1087/* return total length of buffer chain */
@@ -1683,8 +1678,7 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes)
1683 bus->rxpending = true; 1678 bus->rxpending = true;
1684 1679
1685 for (rd->seq_num = bus->rx_seq, rxleft = maxframes; 1680 for (rd->seq_num = bus->rx_seq, rxleft = maxframes;
1686 !bus->rxskip && rxleft && 1681 !bus->rxskip && rxleft && brcmf_bus_ready(bus->sdiodev->bus_if);
1687 bus->sdiodev->bus_if->state != BRCMF_BUS_DOWN;
1688 rd->seq_num++, rxleft--) { 1682 rd->seq_num++, rxleft--) {
1689 1683
1690 /* Handle glomming separately */ 1684 /* Handle glomming separately */
@@ -2233,41 +2227,37 @@ static void brcmf_sdio_bus_stop(struct device *dev)
2233 bus->watchdog_tsk = NULL; 2227 bus->watchdog_tsk = NULL;
2234 } 2228 }
2235 2229
2236 sdio_claim_host(bus->sdiodev->func[1]); 2230 if (bus_if->state == BRCMF_BUS_DOWN) {
2237 2231 sdio_claim_host(sdiodev->func[1]);
2238 /* Enable clock for device interrupts */ 2232
2239 brcmf_sdio_bus_sleep(bus, false, false); 2233 /* Enable clock for device interrupts */
2234 brcmf_sdio_bus_sleep(bus, false, false);
2235
2236 /* Disable and clear interrupts at the chip level also */
2237 w_sdreg32(bus, 0, offsetof(struct sdpcmd_regs, hostintmask));
2238 local_hostintmask = bus->hostintmask;
2239 bus->hostintmask = 0;
2240
2241 /* Force backplane clocks to assure F2 interrupt propagates */
2242 saveclk = brcmf_sdiod_regrb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR,
2243 &err);
2244 if (!err)
2245 brcmf_sdiod_regwb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR,
2246 (saveclk | SBSDIO_FORCE_HT), &err);
2247 if (err)
2248 brcmf_err("Failed to force clock for F2: err %d\n",
2249 err);
2240 2250
2241 /* Disable and clear interrupts at the chip level also */ 2251 /* Turn off the bus (F2), free any pending packets */
2242 w_sdreg32(bus, 0, offsetof(struct sdpcmd_regs, hostintmask)); 2252 brcmf_dbg(INTR, "disable SDIO interrupts\n");
2243 local_hostintmask = bus->hostintmask; 2253 sdio_disable_func(sdiodev->func[SDIO_FUNC_2]);
2244 bus->hostintmask = 0;
2245 2254
2246 /* Change our idea of bus state */ 2255 /* Clear any pending interrupts now that F2 is disabled */
2247 bus->sdiodev->bus_if->state = BRCMF_BUS_DOWN; 2256 w_sdreg32(bus, local_hostintmask,
2257 offsetof(struct sdpcmd_regs, intstatus));
2248 2258
2249 /* Force clocks on backplane to be sure F2 interrupt propagates */ 2259 sdio_release_host(sdiodev->func[1]);
2250 saveclk = brcmf_sdiod_regrb(bus->sdiodev,
2251 SBSDIO_FUNC1_CHIPCLKCSR, &err);
2252 if (!err) {
2253 brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR,
2254 (saveclk | SBSDIO_FORCE_HT), &err);
2255 } 2260 }
2256 if (err)
2257 brcmf_err("Failed to force clock for F2: err %d\n", err);
2258
2259 /* Turn off the bus (F2), free any pending packets */
2260 brcmf_dbg(INTR, "disable SDIO interrupts\n");
2261 sdio_disable_func(bus->sdiodev->func[SDIO_FUNC_2]);
2262
2263 /* Clear any pending interrupts now that F2 is disabled */
2264 w_sdreg32(bus, local_hostintmask,
2265 offsetof(struct sdpcmd_regs, intstatus));
2266
2267 /* Turn off the backplane clock (only) */
2268 brcmf_sdio_clkctl(bus, CLK_SDONLY, false);
2269 sdio_release_host(bus->sdiodev->func[1]);
2270
2271 /* Clear the data packet queues */ 2261 /* Clear the data packet queues */
2272 brcmu_pktq_flush(&bus->txq, true, NULL, NULL); 2262 brcmu_pktq_flush(&bus->txq, true, NULL, NULL);
2273 2263
@@ -2357,20 +2347,11 @@ static void brcmf_sdio_dpc(struct brcmf_sdio *bus)
2357 /* Check for inconsistent device control */ 2347 /* Check for inconsistent device control */
2358 devctl = brcmf_sdiod_regrb(bus->sdiodev, 2348 devctl = brcmf_sdiod_regrb(bus->sdiodev,
2359 SBSDIO_DEVICE_CTL, &err); 2349 SBSDIO_DEVICE_CTL, &err);
2360 if (err) {
2361 brcmf_err("error reading DEVCTL: %d\n", err);
2362 bus->sdiodev->bus_if->state = BRCMF_BUS_DOWN;
2363 }
2364#endif /* DEBUG */ 2350#endif /* DEBUG */
2365 2351
2366 /* Read CSR, if clock on switch to AVAIL, else ignore */ 2352 /* Read CSR, if clock on switch to AVAIL, else ignore */
2367 clkctl = brcmf_sdiod_regrb(bus->sdiodev, 2353 clkctl = brcmf_sdiod_regrb(bus->sdiodev,
2368 SBSDIO_FUNC1_CHIPCLKCSR, &err); 2354 SBSDIO_FUNC1_CHIPCLKCSR, &err);
2369 if (err) {
2370 brcmf_err("error reading CSR: %d\n",
2371 err);
2372 bus->sdiodev->bus_if->state = BRCMF_BUS_DOWN;
2373 }
2374 2355
2375 brcmf_dbg(SDIO, "DPC: PENDING, devctl 0x%02x clkctl 0x%02x\n", 2356 brcmf_dbg(SDIO, "DPC: PENDING, devctl 0x%02x clkctl 0x%02x\n",
2376 devctl, clkctl); 2357 devctl, clkctl);
@@ -2378,19 +2359,9 @@ static void brcmf_sdio_dpc(struct brcmf_sdio *bus)
2378 if (SBSDIO_HTAV(clkctl)) { 2359 if (SBSDIO_HTAV(clkctl)) {
2379 devctl = brcmf_sdiod_regrb(bus->sdiodev, 2360 devctl = brcmf_sdiod_regrb(bus->sdiodev,
2380 SBSDIO_DEVICE_CTL, &err); 2361 SBSDIO_DEVICE_CTL, &err);
2381 if (err) {
2382 brcmf_err("error reading DEVCTL: %d\n",
2383 err);
2384 bus->sdiodev->bus_if->state = BRCMF_BUS_DOWN;
2385 }
2386 devctl &= ~SBSDIO_DEVCTL_CA_INT_ONLY; 2362 devctl &= ~SBSDIO_DEVCTL_CA_INT_ONLY;
2387 brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_DEVICE_CTL, 2363 brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_DEVICE_CTL,
2388 devctl, &err); 2364 devctl, &err);
2389 if (err) {
2390 brcmf_err("error writing DEVCTL: %d\n",
2391 err);
2392 bus->sdiodev->bus_if->state = BRCMF_BUS_DOWN;
2393 }
2394 bus->clkstate = CLK_AVAIL; 2365 bus->clkstate = CLK_AVAIL;
2395 } 2366 }
2396 } 2367 }
@@ -2525,9 +2496,8 @@ static void brcmf_sdio_dpc(struct brcmf_sdio *bus)
2525 txlimit -= framecnt; 2496 txlimit -= framecnt;
2526 } 2497 }
2527 2498
2528 if ((bus->sdiodev->bus_if->state == BRCMF_BUS_DOWN) || (err != 0)) { 2499 if (!brcmf_bus_ready(bus->sdiodev->bus_if) || (err != 0)) {
2529 brcmf_err("failed backplane access over SDIO, halting operation\n"); 2500 brcmf_err("failed backplane access over SDIO, halting operation\n");
2530 bus->sdiodev->bus_if->state = BRCMF_BUS_DOWN;
2531 atomic_set(&bus->intstatus, 0); 2501 atomic_set(&bus->intstatus, 0);
2532 } else if (atomic_read(&bus->intstatus) || 2502 } else if (atomic_read(&bus->intstatus) ||
2533 atomic_read(&bus->ipend) > 0 || 2503 atomic_read(&bus->ipend) > 0 ||
@@ -3195,46 +3165,69 @@ brcmf_sdio_bus_rxctl(struct device *dev, unsigned char *msg, uint msglen)
3195 return rxlen ? (int)rxlen : -ETIMEDOUT; 3165 return rxlen ? (int)rxlen : -ETIMEDOUT;
3196} 3166}
3197 3167
3198static bool brcmf_sdio_download_state(struct brcmf_sdio *bus, bool enter) 3168#ifdef DEBUG
3169static bool
3170brcmf_sdio_verifymemory(struct brcmf_sdio_dev *sdiodev, u32 ram_addr,
3171 u8 *ram_data, uint ram_sz)
3199{ 3172{
3200 struct chip_info *ci = bus->ci; 3173 char *ram_cmp;
3201 3174 int err;
3202 /* To enter download state, disable ARM and reset SOCRAM. 3175 bool ret = true;
3203 * To exit download state, simply reset ARM (default is RAM boot). 3176 int address;
3204 */ 3177 int offset;
3205 if (enter) { 3178 int len;
3206 bus->alp_only = true;
3207
3208 brcmf_sdio_chip_enter_download(bus->sdiodev, ci);
3209 } else {
3210 if (!brcmf_sdio_chip_exit_download(bus->sdiodev, ci, bus->vars,
3211 bus->varsz))
3212 return false;
3213 3179
3214 /* Allow HT Clock now that the ARM is running. */ 3180 /* read back and verify */
3215 bus->alp_only = false; 3181 brcmf_dbg(INFO, "Compare RAM dl & ul at 0x%08x; size=%d\n", ram_addr,
3182 ram_sz);
3183 ram_cmp = kmalloc(MEMBLOCK, GFP_KERNEL);
3184 /* do not proceed while no memory but */
3185 if (!ram_cmp)
3186 return true;
3216 3187
3217 bus->sdiodev->bus_if->state = BRCMF_BUS_LOAD; 3188 address = ram_addr;
3189 offset = 0;
3190 while (offset < ram_sz) {
3191 len = ((offset + MEMBLOCK) < ram_sz) ? MEMBLOCK :
3192 ram_sz - offset;
3193 err = brcmf_sdiod_ramrw(sdiodev, false, address, ram_cmp, len);
3194 if (err) {
3195 brcmf_err("error %d on reading %d membytes at 0x%08x\n",
3196 err, len, address);
3197 ret = false;
3198 break;
3199 } else if (memcmp(ram_cmp, &ram_data[offset], len)) {
3200 brcmf_err("Downloaded RAM image is corrupted, block offset is %d, len is %d\n",
3201 offset, len);
3202 ret = false;
3203 break;
3204 }
3205 offset += len;
3206 address += len;
3218 } 3207 }
3219 3208
3209 kfree(ram_cmp);
3210
3211 return ret;
3212}
3213#else /* DEBUG */
3214static bool
3215brcmf_sdio_verifymemory(struct brcmf_sdio_dev *sdiodev, u32 ram_addr,
3216 u8 *ram_data, uint ram_sz)
3217{
3220 return true; 3218 return true;
3221} 3219}
3220#endif /* DEBUG */
3222 3221
3223static int brcmf_sdio_download_code_file(struct brcmf_sdio *bus) 3222static int brcmf_sdio_download_code_file(struct brcmf_sdio *bus,
3223 const struct firmware *fw)
3224{ 3224{
3225 const struct firmware *fw;
3226 int err; 3225 int err;
3227 int offset; 3226 int offset;
3228 int address; 3227 int address;
3229 int len; 3228 int len;
3230 3229
3231 fw = brcmf_sdio_get_fw(bus, BRCMF_FIRMWARE_BIN); 3230 brcmf_dbg(TRACE, "Enter\n");
3232 if (fw == NULL)
3233 return -ENOENT;
3234
3235 if (brcmf_sdio_chip_getinfidx(bus->ci, BCMA_CORE_ARM_CR4) !=
3236 BRCMF_MAX_CORENUM)
3237 memcpy(&bus->ci->rst_vec, fw->data, sizeof(bus->ci->rst_vec));
3238 3231
3239 err = 0; 3232 err = 0;
3240 offset = 0; 3233 offset = 0;
@@ -3247,138 +3240,96 @@ static int brcmf_sdio_download_code_file(struct brcmf_sdio *bus)
3247 if (err) { 3240 if (err) {
3248 brcmf_err("error %d on writing %d membytes at 0x%08x\n", 3241 brcmf_err("error %d on writing %d membytes at 0x%08x\n",
3249 err, len, address); 3242 err, len, address);
3250 goto failure; 3243 return err;
3251 } 3244 }
3252 offset += len; 3245 offset += len;
3253 address += len; 3246 address += len;
3254 } 3247 }
3255 3248 if (!err)
3256failure: 3249 if (!brcmf_sdio_verifymemory(bus->sdiodev, bus->ci->rambase,
3257 release_firmware(fw); 3250 (u8 *)fw->data, fw->size))
3251 err = -EIO;
3258 3252
3259 return err; 3253 return err;
3260} 3254}
3261 3255
3262/* 3256static int brcmf_sdio_download_nvram(struct brcmf_sdio *bus,
3263 * ProcessVars:Takes a buffer of "<var>=<value>\n" lines read from a file 3257 const struct firmware *nv)
3264 * and ending in a NUL.
3265 * Removes carriage returns, empty lines, comment lines, and converts
3266 * newlines to NULs.
3267 * Shortens buffer as needed and pads with NULs. End of buffer is marked
3268 * by two NULs.
3269*/
3270
3271static int brcmf_sdio_strip_nvram(struct brcmf_sdio *bus,
3272 const struct firmware *nv)
3273{ 3258{
3274 char *varbuf; 3259 void *vars;
3275 char *dp; 3260 u32 varsz;
3276 bool findNewline; 3261 int address;
3277 int column; 3262 int err;
3278 int ret = 0;
3279 uint buf_len, n, len;
3280
3281 len = nv->size;
3282 varbuf = vmalloc(len);
3283 if (!varbuf)
3284 return -ENOMEM;
3285
3286 memcpy(varbuf, nv->data, len);
3287 dp = varbuf;
3288
3289 findNewline = false;
3290 column = 0;
3291
3292 for (n = 0; n < len; n++) {
3293 if (varbuf[n] == 0)
3294 break;
3295 if (varbuf[n] == '\r')
3296 continue;
3297 if (findNewline && varbuf[n] != '\n')
3298 continue;
3299 findNewline = false;
3300 if (varbuf[n] == '#') {
3301 findNewline = true;
3302 continue;
3303 }
3304 if (varbuf[n] == '\n') {
3305 if (column == 0)
3306 continue;
3307 *dp++ = 0;
3308 column = 0;
3309 continue;
3310 }
3311 *dp++ = varbuf[n];
3312 column++;
3313 }
3314 buf_len = dp - varbuf;
3315 while (dp < varbuf + n)
3316 *dp++ = 0;
3317
3318 kfree(bus->vars);
3319 /* roundup needed for download to device */
3320 bus->varsz = roundup(buf_len + 1, 4);
3321 bus->vars = kmalloc(bus->varsz, GFP_KERNEL);
3322 if (bus->vars == NULL) {
3323 bus->varsz = 0;
3324 ret = -ENOMEM;
3325 goto err;
3326 }
3327 3263
3328 /* copy the processed variables and add null termination */ 3264 brcmf_dbg(TRACE, "Enter\n");
3329 memcpy(bus->vars, varbuf, buf_len);
3330 bus->vars[buf_len] = 0;
3331err:
3332 vfree(varbuf);
3333 return ret;
3334}
3335 3265
3336static int brcmf_sdio_download_nvram(struct brcmf_sdio *bus) 3266 vars = brcmf_nvram_strip(nv, &varsz);
3337{
3338 const struct firmware *nv;
3339 int ret;
3340 3267
3341 nv = brcmf_sdio_get_fw(bus, BRCMF_FIRMWARE_NVRAM); 3268 if (vars == NULL)
3342 if (nv == NULL) 3269 return -EINVAL;
3343 return -ENOENT;
3344 3270
3345 ret = brcmf_sdio_strip_nvram(bus, nv); 3271 address = bus->ci->ramsize - varsz + bus->ci->rambase;
3272 err = brcmf_sdiod_ramrw(bus->sdiodev, true, address, vars, varsz);
3273 if (err)
3274 brcmf_err("error %d on writing %d nvram bytes at 0x%08x\n",
3275 err, varsz, address);
3276 else if (!brcmf_sdio_verifymemory(bus->sdiodev, address, vars, varsz))
3277 err = -EIO;
3346 3278
3347 release_firmware(nv); 3279 brcmf_nvram_free(vars);
3348 3280
3349 return ret; 3281 return err;
3350} 3282}
3351 3283
3352static int brcmf_sdio_download_firmware(struct brcmf_sdio *bus) 3284static int brcmf_sdio_download_firmware(struct brcmf_sdio *bus)
3353{ 3285{
3354 int bcmerror = -EFAULT; 3286 int bcmerror = -EFAULT;
3355 3287 const struct firmware *fw;
3288 u32 rstvec;
3356 3289
3357 sdio_claim_host(bus->sdiodev->func[1]); 3290 sdio_claim_host(bus->sdiodev->func[1]);
3358 brcmf_sdio_clkctl(bus, CLK_AVAIL, false); 3291 brcmf_sdio_clkctl(bus, CLK_AVAIL, false);
3359 3292
3360 /* Keep arm in reset */ 3293 /* Keep arm in reset */
3361 if (!brcmf_sdio_download_state(bus, true)) { 3294 brcmf_sdio_chip_enter_download(bus->sdiodev, bus->ci);
3362 brcmf_err("error placing ARM core in reset\n"); 3295
3296 fw = brcmf_sdio_get_fw(bus, BRCMF_FIRMWARE_BIN);
3297 if (fw == NULL) {
3298 bcmerror = -ENOENT;
3363 goto err; 3299 goto err;
3364 } 3300 }
3365 3301
3366 if (brcmf_sdio_download_code_file(bus)) { 3302 rstvec = get_unaligned_le32(fw->data);
3303 brcmf_dbg(SDIO, "firmware rstvec: %x\n", rstvec);
3304
3305 bcmerror = brcmf_sdio_download_code_file(bus, fw);
3306 release_firmware(fw);
3307 if (bcmerror) {
3367 brcmf_err("dongle image file download failed\n"); 3308 brcmf_err("dongle image file download failed\n");
3368 goto err; 3309 goto err;
3369 } 3310 }
3370 3311
3371 if (brcmf_sdio_download_nvram(bus)) { 3312 fw = brcmf_sdio_get_fw(bus, BRCMF_FIRMWARE_NVRAM);
3313 if (fw == NULL) {
3314 bcmerror = -ENOENT;
3315 goto err;
3316 }
3317
3318 bcmerror = brcmf_sdio_download_nvram(bus, fw);
3319 release_firmware(fw);
3320 if (bcmerror) {
3372 brcmf_err("dongle nvram file download failed\n"); 3321 brcmf_err("dongle nvram file download failed\n");
3373 goto err; 3322 goto err;
3374 } 3323 }
3375 3324
3376 /* Take arm out of reset */ 3325 /* Take arm out of reset */
3377 if (!brcmf_sdio_download_state(bus, false)) { 3326 if (!brcmf_sdio_chip_exit_download(bus->sdiodev, bus->ci, rstvec)) {
3378 brcmf_err("error getting out of ARM core reset\n"); 3327 brcmf_err("error getting out of ARM core reset\n");
3379 goto err; 3328 goto err;
3380 } 3329 }
3381 3330
3331 /* Allow HT Clock now that the ARM is running. */
3332 brcmf_bus_change_state(bus->sdiodev->bus_if, BRCMF_BUS_LOAD);
3382 bcmerror = 0; 3333 bcmerror = 0;
3383 3334
3384err: 3335err:
@@ -3567,9 +3518,11 @@ static int brcmf_sdio_bus_init(struct device *dev)
3567 3518
3568 /* try to download image and nvram to the dongle */ 3519 /* try to download image and nvram to the dongle */
3569 if (bus_if->state == BRCMF_BUS_DOWN) { 3520 if (bus_if->state == BRCMF_BUS_DOWN) {
3521 bus->alp_only = true;
3570 err = brcmf_sdio_download_firmware(bus); 3522 err = brcmf_sdio_download_firmware(bus);
3571 if (err) 3523 if (err)
3572 return err; 3524 return err;
3525 bus->alp_only = false;
3573 } 3526 }
3574 3527
3575 if (!bus->sdiodev->bus_if->drvr) 3528 if (!bus->sdiodev->bus_if->drvr)
@@ -3653,7 +3606,7 @@ void brcmf_sdio_isr(struct brcmf_sdio *bus)
3653 return; 3606 return;
3654 } 3607 }
3655 3608
3656 if (bus->sdiodev->bus_if->state == BRCMF_BUS_DOWN) { 3609 if (!brcmf_bus_ready(bus->sdiodev->bus_if)) {
3657 brcmf_err("bus is down. we have nothing to do\n"); 3610 brcmf_err("bus is down. we have nothing to do\n");
3658 return; 3611 return;
3659 } 3612 }
@@ -3664,7 +3617,6 @@ void brcmf_sdio_isr(struct brcmf_sdio *bus)
3664 else 3617 else
3665 if (brcmf_sdio_intr_rstatus(bus)) { 3618 if (brcmf_sdio_intr_rstatus(bus)) {
3666 brcmf_err("failed backplane access\n"); 3619 brcmf_err("failed backplane access\n");
3667 bus->sdiodev->bus_if->state = BRCMF_BUS_DOWN;
3668 } 3620 }
3669 3621
3670 /* Disable additional interrupts (is this needed now)? */ 3622 /* Disable additional interrupts (is this needed now)? */
@@ -3779,8 +3731,6 @@ brcmf_sdio_probe_attach(struct brcmf_sdio *bus)
3779 u32 reg_val; 3731 u32 reg_val;
3780 u32 drivestrength; 3732 u32 drivestrength;
3781 3733
3782 bus->alp_only = true;
3783
3784 sdio_claim_host(bus->sdiodev->func[1]); 3734 sdio_claim_host(bus->sdiodev->func[1]);
3785 3735
3786 pr_debug("F1 signature read @0x18000000=0x%4x\n", 3736 pr_debug("F1 signature read @0x18000000=0x%4x\n",
@@ -3803,6 +3753,11 @@ brcmf_sdio_probe_attach(struct brcmf_sdio *bus)
3803 goto fail; 3753 goto fail;
3804 } 3754 }
3805 3755
3756 /* SDIO register access works so moving
3757 * state from UNKNOWN to DOWN.
3758 */
3759 brcmf_bus_change_state(bus->sdiodev->bus_if, BRCMF_BUS_DOWN);
3760
3806 if (brcmf_sdio_chip_attach(bus->sdiodev, &bus->ci)) { 3761 if (brcmf_sdio_chip_attach(bus->sdiodev, &bus->ci)) {
3807 brcmf_err("brcmf_sdio_chip_attach failed!\n"); 3762 brcmf_err("brcmf_sdio_chip_attach failed!\n");
3808 goto fail; 3763 goto fail;
@@ -4026,7 +3981,6 @@ struct brcmf_sdio *brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev)
4026 /* Disable F2 to clear any intermediate frame state on the dongle */ 3981 /* Disable F2 to clear any intermediate frame state on the dongle */
4027 sdio_disable_func(bus->sdiodev->func[SDIO_FUNC_2]); 3982 sdio_disable_func(bus->sdiodev->func[SDIO_FUNC_2]);
4028 3983
4029 bus->sdiodev->bus_if->state = BRCMF_BUS_DOWN;
4030 bus->rxflow = false; 3984 bus->rxflow = false;
4031 3985
4032 /* Done with backplane-dependent accesses, can drop clock... */ 3986 /* Done with backplane-dependent accesses, can drop clock... */
@@ -4082,17 +4036,26 @@ void brcmf_sdio_remove(struct brcmf_sdio *bus)
4082 } 4036 }
4083 4037
4084 if (bus->ci) { 4038 if (bus->ci) {
4085 sdio_claim_host(bus->sdiodev->func[1]); 4039 if (bus->sdiodev->bus_if->state == BRCMF_BUS_DOWN) {
4086 brcmf_sdio_clkctl(bus, CLK_AVAIL, false); 4040 sdio_claim_host(bus->sdiodev->func[1]);
4087 brcmf_sdio_clkctl(bus, CLK_NONE, false); 4041 brcmf_sdio_clkctl(bus, CLK_AVAIL, false);
4088 sdio_release_host(bus->sdiodev->func[1]); 4042 /* Leave the device in state where it is
4043 * 'quiet'. This is done by putting it in
4044 * download_state which essentially resets
4045 * all necessary cores.
4046 */
4047 msleep(20);
4048 brcmf_sdio_chip_enter_download(bus->sdiodev,
4049 bus->ci);
4050 brcmf_sdio_clkctl(bus, CLK_NONE, false);
4051 sdio_release_host(bus->sdiodev->func[1]);
4052 }
4089 brcmf_sdio_chip_detach(&bus->ci); 4053 brcmf_sdio_chip_detach(&bus->ci);
4090 } 4054 }
4091 4055
4092 brcmu_pkt_buf_free_skb(bus->txglom_sgpad); 4056 brcmu_pkt_buf_free_skb(bus->txglom_sgpad);
4093 kfree(bus->rxbuf); 4057 kfree(bus->rxbuf);
4094 kfree(bus->hdrbuf); 4058 kfree(bus->hdrbuf);
4095 kfree(bus->vars);
4096 kfree(bus); 4059 kfree(bus);
4097 } 4060 }
4098 4061
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/nvram.c b/drivers/net/wireless/brcm80211/brcmfmac/nvram.c
new file mode 100644
index 000000000000..d5ef86db631b
--- /dev/null
+++ b/drivers/net/wireless/brcm80211/brcmfmac/nvram.c
@@ -0,0 +1,94 @@
1/*
2 * Copyright (c) 2013 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/kernel.h>
18#include <linux/slab.h>
19#include <linux/firmware.h>
20
21#include "nvram.h"
22
23/* brcmf_nvram_strip :Takes a buffer of "<var>=<value>\n" lines read from a file
24 * and ending in a NUL. Removes carriage returns, empty lines, comment lines,
25 * and converts newlines to NULs. Shortens buffer as needed and pads with NULs.
26 * End of buffer is completed with token identifying length of buffer.
27 */
28void *brcmf_nvram_strip(const struct firmware *nv, u32 *new_length)
29{
30 u8 *nvram;
31 u32 i;
32 u32 len;
33 u32 column;
34 u8 val;
35 bool comment;
36 u32 token;
37 __le32 token_le;
38
39 /* Alloc for extra 0 byte + roundup by 4 + length field */
40 nvram = kmalloc(nv->size + 1 + 3 + sizeof(token_le), GFP_KERNEL);
41 if (!nvram)
42 return NULL;
43
44 len = 0;
45 column = 0;
46 comment = false;
47 for (i = 0; i < nv->size; i++) {
48 val = nv->data[i];
49 if (val == 0)
50 break;
51 if (val == '\r')
52 continue;
53 if (comment && (val != '\n'))
54 continue;
55 comment = false;
56 if (val == '#') {
57 comment = true;
58 continue;
59 }
60 if (val == '\n') {
61 if (column == 0)
62 continue;
63 nvram[len] = 0;
64 len++;
65 column = 0;
66 continue;
67 }
68 nvram[len] = val;
69 len++;
70 column++;
71 }
72 column = len;
73 *new_length = roundup(len + 1, 4);
74 while (column != *new_length) {
75 nvram[column] = 0;
76 column++;
77 }
78
79 token = *new_length / 4;
80 token = (~token << 16) | (token & 0x0000FFFF);
81 token_le = cpu_to_le32(token);
82
83 memcpy(&nvram[*new_length], &token_le, sizeof(token_le));
84 *new_length += sizeof(token_le);
85
86 return nvram;
87}
88
89void brcmf_nvram_free(void *nvram)
90{
91 kfree(nvram);
92}
93
94
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/nvram.h b/drivers/net/wireless/brcm80211/brcmfmac/nvram.h
new file mode 100644
index 000000000000..d454580928c9
--- /dev/null
+++ b/drivers/net/wireless/brcm80211/brcmfmac/nvram.h
@@ -0,0 +1,24 @@
1/*
2 * Copyright (c) 2013 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#ifndef BRCMFMAC_NVRAM_H
17#define BRCMFMAC_NVRAM_H
18
19
20void *brcmf_nvram_strip(const struct firmware *nv, u32 *new_length);
21void brcmf_nvram_free(void *nvram);
22
23
24#endif /* BRCMFMAC_NVRAM_H */
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c b/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c
index 9fd40675f18e..82bf3c5d3cdc 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c
@@ -51,6 +51,9 @@
51#define BCM43143_CORE_ARM_BASE 0x18003000 51#define BCM43143_CORE_ARM_BASE 0x18003000
52#define BCM43143_RAMSIZE 0x70000 52#define BCM43143_RAMSIZE 0x70000
53 53
54/* All D11 cores, ID 0x812 */
55#define BCM43xx_CORE_D11_BASE 0x18001000
56
54#define SBCOREREV(sbidh) \ 57#define SBCOREREV(sbidh) \
55 ((((sbidh) & SSB_IDHIGH_RCHI) >> SSB_IDHIGH_RCHI_SHIFT) | \ 58 ((((sbidh) & SSB_IDHIGH_RCHI) >> SSB_IDHIGH_RCHI_SHIFT) | \
56 ((sbidh) & SSB_IDHIGH_RCLO)) 59 ((sbidh) & SSB_IDHIGH_RCLO))
@@ -66,6 +69,10 @@
66/* ARM CR4 core specific control flag bits */ 69/* ARM CR4 core specific control flag bits */
67#define ARMCR4_BCMA_IOCTL_CPUHALT 0x0020 70#define ARMCR4_BCMA_IOCTL_CPUHALT 0x0020
68 71
72/* D11 core specific control flag bits */
73#define D11_BCMA_IOCTL_PHYCLOCKEN 0x0004
74#define D11_BCMA_IOCTL_PHYRESET 0x0008
75
69#define SDIOD_DRVSTR_KEY(chip, pmu) (((chip) << 16) | (pmu)) 76#define SDIOD_DRVSTR_KEY(chip, pmu) (((chip) << 16) | (pmu))
70/* SDIO Pad drive strength to select value mappings */ 77/* SDIO Pad drive strength to select value mappings */
71struct sdiod_drive_str { 78struct sdiod_drive_str {
@@ -111,7 +118,7 @@ static const struct sdiod_drive_str sdiod_drvstr_tab2_3v3[] = {
111}; 118};
112 119
113u8 120u8
114brcmf_sdio_chip_getinfidx(struct chip_info *ci, u16 coreid) 121brcmf_sdio_chip_getinfidx(struct brcmf_chip *ci, u16 coreid)
115{ 122{
116 u8 idx; 123 u8 idx;
117 124
@@ -124,7 +131,7 @@ brcmf_sdio_chip_getinfidx(struct chip_info *ci, u16 coreid)
124 131
125static u32 132static u32
126brcmf_sdio_sb_corerev(struct brcmf_sdio_dev *sdiodev, 133brcmf_sdio_sb_corerev(struct brcmf_sdio_dev *sdiodev,
127 struct chip_info *ci, u16 coreid) 134 struct brcmf_chip *ci, u16 coreid)
128{ 135{
129 u32 regdata; 136 u32 regdata;
130 u8 idx; 137 u8 idx;
@@ -139,7 +146,7 @@ brcmf_sdio_sb_corerev(struct brcmf_sdio_dev *sdiodev,
139 146
140static u32 147static u32
141brcmf_sdio_ai_corerev(struct brcmf_sdio_dev *sdiodev, 148brcmf_sdio_ai_corerev(struct brcmf_sdio_dev *sdiodev,
142 struct chip_info *ci, u16 coreid) 149 struct brcmf_chip *ci, u16 coreid)
143{ 150{
144 u8 idx; 151 u8 idx;
145 152
@@ -150,7 +157,7 @@ brcmf_sdio_ai_corerev(struct brcmf_sdio_dev *sdiodev,
150 157
151static bool 158static bool
152brcmf_sdio_sb_iscoreup(struct brcmf_sdio_dev *sdiodev, 159brcmf_sdio_sb_iscoreup(struct brcmf_sdio_dev *sdiodev,
153 struct chip_info *ci, u16 coreid) 160 struct brcmf_chip *ci, u16 coreid)
154{ 161{
155 u32 regdata; 162 u32 regdata;
156 u8 idx; 163 u8 idx;
@@ -169,7 +176,7 @@ brcmf_sdio_sb_iscoreup(struct brcmf_sdio_dev *sdiodev,
169 176
170static bool 177static bool
171brcmf_sdio_ai_iscoreup(struct brcmf_sdio_dev *sdiodev, 178brcmf_sdio_ai_iscoreup(struct brcmf_sdio_dev *sdiodev,
172 struct chip_info *ci, u16 coreid) 179 struct brcmf_chip *ci, u16 coreid)
173{ 180{
174 u32 regdata; 181 u32 regdata;
175 u8 idx; 182 u8 idx;
@@ -193,7 +200,8 @@ brcmf_sdio_ai_iscoreup(struct brcmf_sdio_dev *sdiodev,
193 200
194static void 201static void
195brcmf_sdio_sb_coredisable(struct brcmf_sdio_dev *sdiodev, 202brcmf_sdio_sb_coredisable(struct brcmf_sdio_dev *sdiodev,
196 struct chip_info *ci, u16 coreid, u32 core_bits) 203 struct brcmf_chip *ci, u16 coreid, u32 pre_resetbits,
204 u32 in_resetbits)
197{ 205{
198 u32 regdata, base; 206 u32 regdata, base;
199 u8 idx; 207 u8 idx;
@@ -279,52 +287,48 @@ brcmf_sdio_sb_coredisable(struct brcmf_sdio_dev *sdiodev,
279 287
280static void 288static void
281brcmf_sdio_ai_coredisable(struct brcmf_sdio_dev *sdiodev, 289brcmf_sdio_ai_coredisable(struct brcmf_sdio_dev *sdiodev,
282 struct chip_info *ci, u16 coreid, u32 core_bits) 290 struct brcmf_chip *ci, u16 coreid, u32 pre_resetbits,
291 u32 in_resetbits)
283{ 292{
284 u8 idx; 293 u8 idx;
285 u32 regdata; 294 u32 regdata;
295 u32 wrapbase;
286 296
287 idx = brcmf_sdio_chip_getinfidx(ci, coreid); 297 idx = brcmf_sdio_chip_getinfidx(ci, coreid);
288 if (idx == BRCMF_MAX_CORENUM) 298 if (idx == BRCMF_MAX_CORENUM)
289 return; 299 return;
290 300
301 wrapbase = ci->c_inf[idx].wrapbase;
302
291 /* if core is already in reset, just return */ 303 /* if core is already in reset, just return */
292 regdata = brcmf_sdiod_regrl(sdiodev, 304 regdata = brcmf_sdiod_regrl(sdiodev, wrapbase + BCMA_RESET_CTL, NULL);
293 ci->c_inf[idx].wrapbase+BCMA_RESET_CTL,
294 NULL);
295 if ((regdata & BCMA_RESET_CTL_RESET) != 0) 305 if ((regdata & BCMA_RESET_CTL_RESET) != 0)
296 return; 306 return;
297 307
298 /* ensure no pending backplane operation 308 /* configure reset */
299 * 300uc should be sufficient for backplane ops to be finish 309 brcmf_sdiod_regwl(sdiodev, wrapbase + BCMA_IOCTL, pre_resetbits |
300 * extra 10ms is taken into account for firmware load stage 310 BCMA_IOCTL_FGC | BCMA_IOCTL_CLK, NULL);
301 * after 10300us carry on disabling the core anyway 311 regdata = brcmf_sdiod_regrl(sdiodev, wrapbase + BCMA_IOCTL, NULL);
302 */
303 SPINWAIT(brcmf_sdiod_regrl(sdiodev,
304 ci->c_inf[idx].wrapbase+BCMA_RESET_ST,
305 NULL), 10300);
306 regdata = brcmf_sdiod_regrl(sdiodev,
307 ci->c_inf[idx].wrapbase+BCMA_RESET_ST,
308 NULL);
309 if (regdata)
310 brcmf_err("disabling core 0x%x with reset status %x\n",
311 coreid, regdata);
312 312
313 brcmf_sdiod_regwl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_RESET_CTL, 313 /* put in reset */
314 brcmf_sdiod_regwl(sdiodev, wrapbase + BCMA_RESET_CTL,
314 BCMA_RESET_CTL_RESET, NULL); 315 BCMA_RESET_CTL_RESET, NULL);
315 udelay(1);
316
317 brcmf_sdiod_regwl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_IOCTL,
318 core_bits, NULL);
319 regdata = brcmf_sdiod_regrl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_IOCTL,
320 NULL);
321 usleep_range(10, 20); 316 usleep_range(10, 20);
322 317
318 /* wait till reset is 1 */
319 SPINWAIT(brcmf_sdiod_regrl(sdiodev, wrapbase + BCMA_RESET_CTL, NULL) !=
320 BCMA_RESET_CTL_RESET, 300);
321
322 /* post reset configure */
323 brcmf_sdiod_regwl(sdiodev, wrapbase + BCMA_IOCTL, pre_resetbits |
324 BCMA_IOCTL_FGC | BCMA_IOCTL_CLK, NULL);
325 regdata = brcmf_sdiod_regrl(sdiodev, wrapbase + BCMA_IOCTL, NULL);
323} 326}
324 327
325static void 328static void
326brcmf_sdio_sb_resetcore(struct brcmf_sdio_dev *sdiodev, 329brcmf_sdio_sb_resetcore(struct brcmf_sdio_dev *sdiodev,
327 struct chip_info *ci, u16 coreid, u32 core_bits) 330 struct brcmf_chip *ci, u16 coreid, u32 pre_resetbits,
331 u32 in_resetbits, u32 post_resetbits)
328{ 332{
329 u32 regdata; 333 u32 regdata;
330 u8 idx; 334 u8 idx;
@@ -337,7 +341,8 @@ brcmf_sdio_sb_resetcore(struct brcmf_sdio_dev *sdiodev,
337 * Must do the disable sequence first to work for 341 * Must do the disable sequence first to work for
338 * arbitrary current core state. 342 * arbitrary current core state.
339 */ 343 */
340 brcmf_sdio_sb_coredisable(sdiodev, ci, coreid, 0); 344 brcmf_sdio_sb_coredisable(sdiodev, ci, coreid, pre_resetbits,
345 in_resetbits);
341 346
342 /* 347 /*
343 * Now do the initialization sequence. 348 * Now do the initialization sequence.
@@ -390,40 +395,37 @@ brcmf_sdio_sb_resetcore(struct brcmf_sdio_dev *sdiodev,
390 395
391static void 396static void
392brcmf_sdio_ai_resetcore(struct brcmf_sdio_dev *sdiodev, 397brcmf_sdio_ai_resetcore(struct brcmf_sdio_dev *sdiodev,
393 struct chip_info *ci, u16 coreid, u32 core_bits) 398 struct brcmf_chip *ci, u16 coreid, u32 pre_resetbits,
399 u32 in_resetbits, u32 post_resetbits)
394{ 400{
395 u8 idx; 401 u8 idx;
396 u32 regdata; 402 u32 regdata;
403 u32 wrapbase;
397 404
398 idx = brcmf_sdio_chip_getinfidx(ci, coreid); 405 idx = brcmf_sdio_chip_getinfidx(ci, coreid);
399 if (idx == BRCMF_MAX_CORENUM) 406 if (idx == BRCMF_MAX_CORENUM)
400 return; 407 return;
401 408
409 wrapbase = ci->c_inf[idx].wrapbase;
410
402 /* must disable first to work for arbitrary current core state */ 411 /* must disable first to work for arbitrary current core state */
403 brcmf_sdio_ai_coredisable(sdiodev, ci, coreid, core_bits); 412 brcmf_sdio_ai_coredisable(sdiodev, ci, coreid, pre_resetbits,
413 in_resetbits);
404 414
405 /* now do initialization sequence */ 415 while (brcmf_sdiod_regrl(sdiodev, wrapbase + BCMA_RESET_CTL, NULL) &
406 brcmf_sdiod_regwl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_IOCTL, 416 BCMA_RESET_CTL_RESET) {
407 core_bits | BCMA_IOCTL_FGC | BCMA_IOCTL_CLK, NULL); 417 brcmf_sdiod_regwl(sdiodev, wrapbase + BCMA_RESET_CTL, 0, NULL);
408 regdata = brcmf_sdiod_regrl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_IOCTL, 418 usleep_range(40, 60);
409 NULL); 419 }
410 brcmf_sdiod_regwl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_RESET_CTL,
411 0, NULL);
412 regdata = brcmf_sdiod_regrl(sdiodev,
413 ci->c_inf[idx].wrapbase+BCMA_RESET_CTL,
414 NULL);
415 udelay(1);
416 420
417 brcmf_sdiod_regwl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_IOCTL, 421 brcmf_sdiod_regwl(sdiodev, wrapbase + BCMA_IOCTL, post_resetbits |
418 core_bits | BCMA_IOCTL_CLK, NULL); 422 BCMA_IOCTL_CLK, NULL);
419 regdata = brcmf_sdiod_regrl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_IOCTL, 423 regdata = brcmf_sdiod_regrl(sdiodev, wrapbase + BCMA_IOCTL, NULL);
420 NULL);
421 udelay(1);
422} 424}
423 425
424#ifdef DEBUG 426#ifdef DEBUG
425/* safety check for chipinfo */ 427/* safety check for chipinfo */
426static int brcmf_sdio_chip_cichk(struct chip_info *ci) 428static int brcmf_sdio_chip_cichk(struct brcmf_chip *ci)
427{ 429{
428 u8 core_idx; 430 u8 core_idx;
429 431
@@ -450,189 +452,213 @@ static int brcmf_sdio_chip_cichk(struct chip_info *ci)
450 return 0; 452 return 0;
451} 453}
452#else /* DEBUG */ 454#else /* DEBUG */
453static inline int brcmf_sdio_chip_cichk(struct chip_info *ci) 455static inline int brcmf_sdio_chip_cichk(struct brcmf_chip *ci)
454{ 456{
455 return 0; 457 return 0;
456} 458}
457#endif 459#endif
458 460
459static int brcmf_sdio_chip_recognition(struct brcmf_sdio_dev *sdiodev, 461static int brcmf_sdio_chip_recognition(struct brcmf_sdio_dev *sdiodev,
460 struct chip_info *ci) 462 struct brcmf_chip *ci)
461{ 463{
462 u32 regdata; 464 u32 regdata;
463 int ret; 465 u32 socitype;
464 466
465 /* Get CC core rev 467 /* Get CC core rev
466 * Chipid is assume to be at offset 0 from regs arg 468 * Chipid is assume to be at offset 0 from SI_ENUM_BASE
467 * For different chiptypes or old sdio hosts w/o chipcommon, 469 * For different chiptypes or old sdio hosts w/o chipcommon,
468 * other ways of recognition should be added here. 470 * other ways of recognition should be added here.
469 */ 471 */
470 ci->c_inf[0].id = BCMA_CORE_CHIPCOMMON;
471 ci->c_inf[0].base = SI_ENUM_BASE;
472 regdata = brcmf_sdiod_regrl(sdiodev, 472 regdata = brcmf_sdiod_regrl(sdiodev,
473 CORE_CC_REG(ci->c_inf[0].base, chipid), 473 CORE_CC_REG(SI_ENUM_BASE, chipid),
474 NULL); 474 NULL);
475 ci->chip = regdata & CID_ID_MASK; 475 ci->chip = regdata & CID_ID_MASK;
476 ci->chiprev = (regdata & CID_REV_MASK) >> CID_REV_SHIFT; 476 ci->chiprev = (regdata & CID_REV_MASK) >> CID_REV_SHIFT;
477 if (sdiodev->func[0]->device == SDIO_DEVICE_ID_BROADCOM_4335_4339 && 477 if (sdiodev->func[0]->device == SDIO_DEVICE_ID_BROADCOM_4335_4339 &&
478 ci->chiprev >= 2) 478 ci->chiprev >= 2)
479 ci->chip = BCM4339_CHIP_ID; 479 ci->chip = BCM4339_CHIP_ID;
480 ci->socitype = (regdata & CID_TYPE_MASK) >> CID_TYPE_SHIFT; 480 socitype = (regdata & CID_TYPE_MASK) >> CID_TYPE_SHIFT;
481 481
482 brcmf_dbg(INFO, "chipid=0x%x chiprev=%d\n", ci->chip, ci->chiprev); 482 brcmf_dbg(INFO, "found %s chip: id=0x%x, rev=%d\n",
483 socitype == SOCI_SB ? "SB" : "AXI", ci->chip, ci->chiprev);
483 484
484 /* Address of cores for new chips should be added here */ 485 if (socitype == SOCI_SB) {
485 switch (ci->chip) { 486 if (ci->chip != BCM4329_CHIP_ID) {
486 case BCM43143_CHIP_ID: 487 brcmf_err("SB chip is not supported\n");
487 ci->c_inf[0].wrapbase = ci->c_inf[0].base + 0x00100000; 488 return -ENODEV;
488 ci->c_inf[0].cib = 0x2b000000; 489 }
489 ci->c_inf[1].id = BCMA_CORE_SDIO_DEV; 490 ci->iscoreup = brcmf_sdio_sb_iscoreup;
490 ci->c_inf[1].base = BCM43143_CORE_BUS_BASE; 491 ci->corerev = brcmf_sdio_sb_corerev;
491 ci->c_inf[1].wrapbase = ci->c_inf[1].base + 0x00100000; 492 ci->coredisable = brcmf_sdio_sb_coredisable;
492 ci->c_inf[1].cib = 0x18000000; 493 ci->resetcore = brcmf_sdio_sb_resetcore;
493 ci->c_inf[2].id = BCMA_CORE_INTERNAL_MEM; 494
494 ci->c_inf[2].base = BCM43143_CORE_SOCRAM_BASE; 495 ci->c_inf[0].id = BCMA_CORE_CHIPCOMMON;
495 ci->c_inf[2].wrapbase = ci->c_inf[2].base + 0x00100000; 496 ci->c_inf[0].base = SI_ENUM_BASE;
496 ci->c_inf[2].cib = 0x14000000;
497 ci->c_inf[3].id = BCMA_CORE_ARM_CM3;
498 ci->c_inf[3].base = BCM43143_CORE_ARM_BASE;
499 ci->c_inf[3].wrapbase = ci->c_inf[3].base + 0x00100000;
500 ci->c_inf[3].cib = 0x07000000;
501 ci->ramsize = BCM43143_RAMSIZE;
502 break;
503 case BCM43241_CHIP_ID:
504 ci->c_inf[0].wrapbase = 0x18100000;
505 ci->c_inf[0].cib = 0x2a084411;
506 ci->c_inf[1].id = BCMA_CORE_SDIO_DEV;
507 ci->c_inf[1].base = 0x18002000;
508 ci->c_inf[1].wrapbase = 0x18102000;
509 ci->c_inf[1].cib = 0x0e004211;
510 ci->c_inf[2].id = BCMA_CORE_INTERNAL_MEM;
511 ci->c_inf[2].base = 0x18004000;
512 ci->c_inf[2].wrapbase = 0x18104000;
513 ci->c_inf[2].cib = 0x14080401;
514 ci->c_inf[3].id = BCMA_CORE_ARM_CM3;
515 ci->c_inf[3].base = 0x18003000;
516 ci->c_inf[3].wrapbase = 0x18103000;
517 ci->c_inf[3].cib = 0x07004211;
518 ci->ramsize = 0x90000;
519 break;
520 case BCM4329_CHIP_ID:
521 ci->c_inf[1].id = BCMA_CORE_SDIO_DEV; 497 ci->c_inf[1].id = BCMA_CORE_SDIO_DEV;
522 ci->c_inf[1].base = BCM4329_CORE_BUS_BASE; 498 ci->c_inf[1].base = BCM4329_CORE_BUS_BASE;
523 ci->c_inf[2].id = BCMA_CORE_INTERNAL_MEM; 499 ci->c_inf[2].id = BCMA_CORE_INTERNAL_MEM;
524 ci->c_inf[2].base = BCM4329_CORE_SOCRAM_BASE; 500 ci->c_inf[2].base = BCM4329_CORE_SOCRAM_BASE;
525 ci->c_inf[3].id = BCMA_CORE_ARM_CM3; 501 ci->c_inf[3].id = BCMA_CORE_ARM_CM3;
526 ci->c_inf[3].base = BCM4329_CORE_ARM_BASE; 502 ci->c_inf[3].base = BCM4329_CORE_ARM_BASE;
503 ci->c_inf[4].id = BCMA_CORE_80211;
504 ci->c_inf[4].base = BCM43xx_CORE_D11_BASE;
527 ci->ramsize = BCM4329_RAMSIZE; 505 ci->ramsize = BCM4329_RAMSIZE;
528 break; 506 } else if (socitype == SOCI_AI) {
529 case BCM4330_CHIP_ID:
530 ci->c_inf[0].wrapbase = 0x18100000;
531 ci->c_inf[0].cib = 0x27004211;
532 ci->c_inf[1].id = BCMA_CORE_SDIO_DEV;
533 ci->c_inf[1].base = 0x18002000;
534 ci->c_inf[1].wrapbase = 0x18102000;
535 ci->c_inf[1].cib = 0x07004211;
536 ci->c_inf[2].id = BCMA_CORE_INTERNAL_MEM;
537 ci->c_inf[2].base = 0x18004000;
538 ci->c_inf[2].wrapbase = 0x18104000;
539 ci->c_inf[2].cib = 0x0d080401;
540 ci->c_inf[3].id = BCMA_CORE_ARM_CM3;
541 ci->c_inf[3].base = 0x18003000;
542 ci->c_inf[3].wrapbase = 0x18103000;
543 ci->c_inf[3].cib = 0x03004211;
544 ci->ramsize = 0x48000;
545 break;
546 case BCM4334_CHIP_ID:
547 ci->c_inf[0].wrapbase = 0x18100000;
548 ci->c_inf[0].cib = 0x29004211;
549 ci->c_inf[1].id = BCMA_CORE_SDIO_DEV;
550 ci->c_inf[1].base = 0x18002000;
551 ci->c_inf[1].wrapbase = 0x18102000;
552 ci->c_inf[1].cib = 0x0d004211;
553 ci->c_inf[2].id = BCMA_CORE_INTERNAL_MEM;
554 ci->c_inf[2].base = 0x18004000;
555 ci->c_inf[2].wrapbase = 0x18104000;
556 ci->c_inf[2].cib = 0x13080401;
557 ci->c_inf[3].id = BCMA_CORE_ARM_CM3;
558 ci->c_inf[3].base = 0x18003000;
559 ci->c_inf[3].wrapbase = 0x18103000;
560 ci->c_inf[3].cib = 0x07004211;
561 ci->ramsize = 0x80000;
562 break;
563 case BCM4335_CHIP_ID:
564 ci->c_inf[0].wrapbase = 0x18100000;
565 ci->c_inf[0].cib = 0x2b084411;
566 ci->c_inf[1].id = BCMA_CORE_SDIO_DEV;
567 ci->c_inf[1].base = 0x18005000;
568 ci->c_inf[1].wrapbase = 0x18105000;
569 ci->c_inf[1].cib = 0x0f004211;
570 ci->c_inf[2].id = BCMA_CORE_ARM_CR4;
571 ci->c_inf[2].base = 0x18002000;
572 ci->c_inf[2].wrapbase = 0x18102000;
573 ci->c_inf[2].cib = 0x01084411;
574 ci->ramsize = 0xc0000;
575 ci->rambase = 0x180000;
576 break;
577 case BCM4339_CHIP_ID:
578 ci->c_inf[0].wrapbase = 0x18100000;
579 ci->c_inf[0].cib = 0x2e084411;
580 ci->c_inf[1].id = BCMA_CORE_SDIO_DEV;
581 ci->c_inf[1].base = 0x18005000;
582 ci->c_inf[1].wrapbase = 0x18105000;
583 ci->c_inf[1].cib = 0x15004211;
584 ci->c_inf[2].id = BCMA_CORE_ARM_CR4;
585 ci->c_inf[2].base = 0x18002000;
586 ci->c_inf[2].wrapbase = 0x18102000;
587 ci->c_inf[2].cib = 0x04084411;
588 ci->ramsize = 0xc0000;
589 ci->rambase = 0x180000;
590 break;
591 case BCM43362_CHIP_ID:
592 ci->c_inf[0].wrapbase = 0x18100000;
593 ci->c_inf[0].cib = 0x27004211;
594 ci->c_inf[1].id = BCMA_CORE_SDIO_DEV;
595 ci->c_inf[1].base = 0x18002000;
596 ci->c_inf[1].wrapbase = 0x18102000;
597 ci->c_inf[1].cib = 0x0a004211;
598 ci->c_inf[2].id = BCMA_CORE_INTERNAL_MEM;
599 ci->c_inf[2].base = 0x18004000;
600 ci->c_inf[2].wrapbase = 0x18104000;
601 ci->c_inf[2].cib = 0x08080401;
602 ci->c_inf[3].id = BCMA_CORE_ARM_CM3;
603 ci->c_inf[3].base = 0x18003000;
604 ci->c_inf[3].wrapbase = 0x18103000;
605 ci->c_inf[3].cib = 0x03004211;
606 ci->ramsize = 0x3C000;
607 break;
608 default:
609 brcmf_err("chipid 0x%x is not supported\n", ci->chip);
610 return -ENODEV;
611 }
612
613 ret = brcmf_sdio_chip_cichk(ci);
614 if (ret)
615 return ret;
616
617 switch (ci->socitype) {
618 case SOCI_SB:
619 ci->iscoreup = brcmf_sdio_sb_iscoreup;
620 ci->corerev = brcmf_sdio_sb_corerev;
621 ci->coredisable = brcmf_sdio_sb_coredisable;
622 ci->resetcore = brcmf_sdio_sb_resetcore;
623 break;
624 case SOCI_AI:
625 ci->iscoreup = brcmf_sdio_ai_iscoreup; 507 ci->iscoreup = brcmf_sdio_ai_iscoreup;
626 ci->corerev = brcmf_sdio_ai_corerev; 508 ci->corerev = brcmf_sdio_ai_corerev;
627 ci->coredisable = brcmf_sdio_ai_coredisable; 509 ci->coredisable = brcmf_sdio_ai_coredisable;
628 ci->resetcore = brcmf_sdio_ai_resetcore; 510 ci->resetcore = brcmf_sdio_ai_resetcore;
629 break; 511
630 default: 512 ci->c_inf[0].id = BCMA_CORE_CHIPCOMMON;
631 brcmf_err("socitype %u not supported\n", ci->socitype); 513 ci->c_inf[0].base = SI_ENUM_BASE;
514
515 /* Address of cores for new chips should be added here */
516 switch (ci->chip) {
517 case BCM43143_CHIP_ID:
518 ci->c_inf[0].wrapbase = ci->c_inf[0].base + 0x00100000;
519 ci->c_inf[0].cib = 0x2b000000;
520 ci->c_inf[1].id = BCMA_CORE_SDIO_DEV;
521 ci->c_inf[1].base = BCM43143_CORE_BUS_BASE;
522 ci->c_inf[1].wrapbase = ci->c_inf[1].base + 0x00100000;
523 ci->c_inf[1].cib = 0x18000000;
524 ci->c_inf[2].id = BCMA_CORE_INTERNAL_MEM;
525 ci->c_inf[2].base = BCM43143_CORE_SOCRAM_BASE;
526 ci->c_inf[2].wrapbase = ci->c_inf[2].base + 0x00100000;
527 ci->c_inf[2].cib = 0x14000000;
528 ci->c_inf[3].id = BCMA_CORE_ARM_CM3;
529 ci->c_inf[3].base = BCM43143_CORE_ARM_BASE;
530 ci->c_inf[3].wrapbase = ci->c_inf[3].base + 0x00100000;
531 ci->c_inf[3].cib = 0x07000000;
532 ci->c_inf[4].id = BCMA_CORE_80211;
533 ci->c_inf[4].base = BCM43xx_CORE_D11_BASE;
534 ci->c_inf[4].wrapbase = ci->c_inf[4].base + 0x00100000;
535 ci->ramsize = BCM43143_RAMSIZE;
536 break;
537 case BCM43241_CHIP_ID:
538 ci->c_inf[0].wrapbase = 0x18100000;
539 ci->c_inf[0].cib = 0x2a084411;
540 ci->c_inf[1].id = BCMA_CORE_SDIO_DEV;
541 ci->c_inf[1].base = 0x18002000;
542 ci->c_inf[1].wrapbase = 0x18102000;
543 ci->c_inf[1].cib = 0x0e004211;
544 ci->c_inf[2].id = BCMA_CORE_INTERNAL_MEM;
545 ci->c_inf[2].base = 0x18004000;
546 ci->c_inf[2].wrapbase = 0x18104000;
547 ci->c_inf[2].cib = 0x14080401;
548 ci->c_inf[3].id = BCMA_CORE_ARM_CM3;
549 ci->c_inf[3].base = 0x18003000;
550 ci->c_inf[3].wrapbase = 0x18103000;
551 ci->c_inf[3].cib = 0x07004211;
552 ci->c_inf[4].id = BCMA_CORE_80211;
553 ci->c_inf[4].base = BCM43xx_CORE_D11_BASE;
554 ci->c_inf[4].wrapbase = ci->c_inf[4].base + 0x00100000;
555 ci->ramsize = 0x90000;
556 break;
557 case BCM4330_CHIP_ID:
558 ci->c_inf[0].wrapbase = 0x18100000;
559 ci->c_inf[0].cib = 0x27004211;
560 ci->c_inf[1].id = BCMA_CORE_SDIO_DEV;
561 ci->c_inf[1].base = 0x18002000;
562 ci->c_inf[1].wrapbase = 0x18102000;
563 ci->c_inf[1].cib = 0x07004211;
564 ci->c_inf[2].id = BCMA_CORE_INTERNAL_MEM;
565 ci->c_inf[2].base = 0x18004000;
566 ci->c_inf[2].wrapbase = 0x18104000;
567 ci->c_inf[2].cib = 0x0d080401;
568 ci->c_inf[3].id = BCMA_CORE_ARM_CM3;
569 ci->c_inf[3].base = 0x18003000;
570 ci->c_inf[3].wrapbase = 0x18103000;
571 ci->c_inf[3].cib = 0x03004211;
572 ci->c_inf[4].id = BCMA_CORE_80211;
573 ci->c_inf[4].base = BCM43xx_CORE_D11_BASE;
574 ci->c_inf[4].wrapbase = ci->c_inf[4].base + 0x00100000;
575 ci->ramsize = 0x48000;
576 break;
577 case BCM4334_CHIP_ID:
578 ci->c_inf[0].wrapbase = 0x18100000;
579 ci->c_inf[0].cib = 0x29004211;
580 ci->c_inf[1].id = BCMA_CORE_SDIO_DEV;
581 ci->c_inf[1].base = 0x18002000;
582 ci->c_inf[1].wrapbase = 0x18102000;
583 ci->c_inf[1].cib = 0x0d004211;
584 ci->c_inf[2].id = BCMA_CORE_INTERNAL_MEM;
585 ci->c_inf[2].base = 0x18004000;
586 ci->c_inf[2].wrapbase = 0x18104000;
587 ci->c_inf[2].cib = 0x13080401;
588 ci->c_inf[3].id = BCMA_CORE_ARM_CM3;
589 ci->c_inf[3].base = 0x18003000;
590 ci->c_inf[3].wrapbase = 0x18103000;
591 ci->c_inf[3].cib = 0x07004211;
592 ci->c_inf[4].id = BCMA_CORE_80211;
593 ci->c_inf[4].base = BCM43xx_CORE_D11_BASE;
594 ci->c_inf[4].wrapbase = ci->c_inf[4].base + 0x00100000;
595 ci->ramsize = 0x80000;
596 break;
597 case BCM4335_CHIP_ID:
598 ci->c_inf[0].wrapbase = 0x18100000;
599 ci->c_inf[0].cib = 0x2b084411;
600 ci->c_inf[1].id = BCMA_CORE_SDIO_DEV;
601 ci->c_inf[1].base = 0x18005000;
602 ci->c_inf[1].wrapbase = 0x18105000;
603 ci->c_inf[1].cib = 0x0f004211;
604 ci->c_inf[2].id = BCMA_CORE_ARM_CR4;
605 ci->c_inf[2].base = 0x18002000;
606 ci->c_inf[2].wrapbase = 0x18102000;
607 ci->c_inf[2].cib = 0x01084411;
608 ci->c_inf[3].id = BCMA_CORE_80211;
609 ci->c_inf[3].base = BCM43xx_CORE_D11_BASE;
610 ci->c_inf[3].wrapbase = ci->c_inf[3].base + 0x00100000;
611 ci->ramsize = 0xc0000;
612 ci->rambase = 0x180000;
613 break;
614 case BCM43362_CHIP_ID:
615 ci->c_inf[0].wrapbase = 0x18100000;
616 ci->c_inf[0].cib = 0x27004211;
617 ci->c_inf[1].id = BCMA_CORE_SDIO_DEV;
618 ci->c_inf[1].base = 0x18002000;
619 ci->c_inf[1].wrapbase = 0x18102000;
620 ci->c_inf[1].cib = 0x0a004211;
621 ci->c_inf[2].id = BCMA_CORE_INTERNAL_MEM;
622 ci->c_inf[2].base = 0x18004000;
623 ci->c_inf[2].wrapbase = 0x18104000;
624 ci->c_inf[2].cib = 0x08080401;
625 ci->c_inf[3].id = BCMA_CORE_ARM_CM3;
626 ci->c_inf[3].base = 0x18003000;
627 ci->c_inf[3].wrapbase = 0x18103000;
628 ci->c_inf[3].cib = 0x03004211;
629 ci->c_inf[4].id = BCMA_CORE_80211;
630 ci->c_inf[4].base = BCM43xx_CORE_D11_BASE;
631 ci->c_inf[4].wrapbase = ci->c_inf[4].base + 0x00100000;
632 ci->ramsize = 0x3C000;
633 break;
634 case BCM4339_CHIP_ID:
635 ci->c_inf[0].wrapbase = 0x18100000;
636 ci->c_inf[0].cib = 0x2e084411;
637 ci->c_inf[1].id = BCMA_CORE_SDIO_DEV;
638 ci->c_inf[1].base = 0x18005000;
639 ci->c_inf[1].wrapbase = 0x18105000;
640 ci->c_inf[1].cib = 0x15004211;
641 ci->c_inf[2].id = BCMA_CORE_ARM_CR4;
642 ci->c_inf[2].base = 0x18002000;
643 ci->c_inf[2].wrapbase = 0x18102000;
644 ci->c_inf[2].cib = 0x04084411;
645 ci->c_inf[3].id = BCMA_CORE_80211;
646 ci->c_inf[3].base = BCM43xx_CORE_D11_BASE;
647 ci->c_inf[3].wrapbase = ci->c_inf[3].base + 0x00100000;
648 ci->ramsize = 0xc0000;
649 ci->rambase = 0x180000;
650 break;
651 default:
652 brcmf_err("AXI chip is not supported\n");
653 return -ENODEV;
654 }
655 } else {
656 brcmf_err("chip backplane type %u is not supported\n",
657 socitype);
632 return -ENODEV; 658 return -ENODEV;
633 } 659 }
634 660
635 return 0; 661 return brcmf_sdio_chip_cichk(ci);
636} 662}
637 663
638static int 664static int
@@ -682,7 +708,7 @@ brcmf_sdio_chip_buscoreprep(struct brcmf_sdio_dev *sdiodev)
682 708
683static void 709static void
684brcmf_sdio_chip_buscoresetup(struct brcmf_sdio_dev *sdiodev, 710brcmf_sdio_chip_buscoresetup(struct brcmf_sdio_dev *sdiodev,
685 struct chip_info *ci) 711 struct brcmf_chip *ci)
686{ 712{
687 u32 base = ci->c_inf[0].base; 713 u32 base = ci->c_inf[0].base;
688 714
@@ -713,19 +739,18 @@ brcmf_sdio_chip_buscoresetup(struct brcmf_sdio_dev *sdiodev,
713 * Make sure any on-chip ARM is off (in case strapping is wrong), 739 * Make sure any on-chip ARM is off (in case strapping is wrong),
714 * or downloaded code was already running. 740 * or downloaded code was already running.
715 */ 741 */
716 ci->coredisable(sdiodev, ci, BCMA_CORE_ARM_CM3, 0); 742 ci->coredisable(sdiodev, ci, BCMA_CORE_ARM_CM3, 0, 0);
717} 743}
718 744
719int brcmf_sdio_chip_attach(struct brcmf_sdio_dev *sdiodev, 745int brcmf_sdio_chip_attach(struct brcmf_sdio_dev *sdiodev,
720 struct chip_info **ci_ptr) 746 struct brcmf_chip **ci_ptr)
721{ 747{
722 int ret; 748 int ret;
723 struct chip_info *ci; 749 struct brcmf_chip *ci;
724 750
725 brcmf_dbg(TRACE, "Enter\n"); 751 brcmf_dbg(TRACE, "Enter\n");
726 752
727 /* alloc chip_info_t */ 753 ci = kzalloc(sizeof(*ci), GFP_ATOMIC);
728 ci = kzalloc(sizeof(struct chip_info), GFP_ATOMIC);
729 if (!ci) 754 if (!ci)
730 return -ENOMEM; 755 return -ENOMEM;
731 756
@@ -753,7 +778,7 @@ err:
753} 778}
754 779
755void 780void
756brcmf_sdio_chip_detach(struct chip_info **ci_ptr) 781brcmf_sdio_chip_detach(struct brcmf_chip **ci_ptr)
757{ 782{
758 brcmf_dbg(TRACE, "Enter\n"); 783 brcmf_dbg(TRACE, "Enter\n");
759 784
@@ -772,7 +797,7 @@ static char *brcmf_sdio_chip_name(uint chipid, char *buf, uint len)
772 797
773void 798void
774brcmf_sdio_chip_drivestrengthinit(struct brcmf_sdio_dev *sdiodev, 799brcmf_sdio_chip_drivestrengthinit(struct brcmf_sdio_dev *sdiodev,
775 struct chip_info *ci, u32 drivestrength) 800 struct brcmf_chip *ci, u32 drivestrength)
776{ 801{
777 const struct sdiod_drive_str *str_tab = NULL; 802 const struct sdiod_drive_str *str_tab = NULL;
778 u32 str_mask; 803 u32 str_mask;
@@ -842,107 +867,19 @@ brcmf_sdio_chip_drivestrengthinit(struct brcmf_sdio_dev *sdiodev,
842 } 867 }
843} 868}
844 869
845#ifdef DEBUG
846static bool
847brcmf_sdio_chip_verifynvram(struct brcmf_sdio_dev *sdiodev, u32 nvram_addr,
848 char *nvram_dat, uint nvram_sz)
849{
850 char *nvram_ularray;
851 int err;
852 bool ret = true;
853
854 /* read back and verify */
855 brcmf_dbg(INFO, "Compare NVRAM dl & ul; size=%d\n", nvram_sz);
856 nvram_ularray = kmalloc(nvram_sz, GFP_KERNEL);
857 /* do not proceed while no memory but */
858 if (!nvram_ularray)
859 return true;
860
861 /* Upload image to verify downloaded contents. */
862 memset(nvram_ularray, 0xaa, nvram_sz);
863
864 /* Read the vars list to temp buffer for comparison */
865 err = brcmf_sdiod_ramrw(sdiodev, false, nvram_addr, nvram_ularray,
866 nvram_sz);
867 if (err) {
868 brcmf_err("error %d on reading %d nvram bytes at 0x%08x\n",
869 err, nvram_sz, nvram_addr);
870 } else if (memcmp(nvram_dat, nvram_ularray, nvram_sz)) {
871 brcmf_err("Downloaded NVRAM image is corrupted\n");
872 ret = false;
873 }
874 kfree(nvram_ularray);
875
876 return ret;
877}
878#else /* DEBUG */
879static inline bool
880brcmf_sdio_chip_verifynvram(struct brcmf_sdio_dev *sdiodev, u32 nvram_addr,
881 char *nvram_dat, uint nvram_sz)
882{
883 return true;
884}
885#endif /* DEBUG */
886
887static bool brcmf_sdio_chip_writenvram(struct brcmf_sdio_dev *sdiodev,
888 struct chip_info *ci,
889 char *nvram_dat, uint nvram_sz)
890{
891 int err;
892 u32 nvram_addr;
893 u32 token;
894 __le32 token_le;
895
896 nvram_addr = (ci->ramsize - 4) - nvram_sz + ci->rambase;
897
898 /* Write the vars list */
899 err = brcmf_sdiod_ramrw(sdiodev, true, nvram_addr, nvram_dat, nvram_sz);
900 if (err) {
901 brcmf_err("error %d on writing %d nvram bytes at 0x%08x\n",
902 err, nvram_sz, nvram_addr);
903 return false;
904 }
905
906 if (!brcmf_sdio_chip_verifynvram(sdiodev, nvram_addr,
907 nvram_dat, nvram_sz))
908 return false;
909
910 /* generate token:
911 * nvram size, converted to words, in lower 16-bits, checksum
912 * in upper 16-bits.
913 */
914 token = nvram_sz / 4;
915 token = (~token << 16) | (token & 0x0000FFFF);
916 token_le = cpu_to_le32(token);
917
918 brcmf_dbg(INFO, "RAM size: %d\n", ci->ramsize);
919 brcmf_dbg(INFO, "nvram is placed at %d, size %d, token=0x%08x\n",
920 nvram_addr, nvram_sz, token);
921
922 /* Write the length token to the last word */
923 if (brcmf_sdiod_ramrw(sdiodev, true, (ci->ramsize - 4 + ci->rambase),
924 (u8 *)&token_le, 4))
925 return false;
926
927 return true;
928}
929
930static void 870static void
931brcmf_sdio_chip_cm3_enterdl(struct brcmf_sdio_dev *sdiodev, 871brcmf_sdio_chip_cm3_enterdl(struct brcmf_sdio_dev *sdiodev,
932 struct chip_info *ci) 872 struct brcmf_chip *ci)
933{ 873{
934 u32 zeros = 0; 874 ci->coredisable(sdiodev, ci, BCMA_CORE_ARM_CM3, 0, 0);
935 875 ci->resetcore(sdiodev, ci, BCMA_CORE_80211,
936 ci->coredisable(sdiodev, ci, BCMA_CORE_ARM_CM3, 0); 876 D11_BCMA_IOCTL_PHYRESET | D11_BCMA_IOCTL_PHYCLOCKEN,
937 ci->resetcore(sdiodev, ci, BCMA_CORE_INTERNAL_MEM, 0); 877 D11_BCMA_IOCTL_PHYCLOCKEN, D11_BCMA_IOCTL_PHYCLOCKEN);
938 878 ci->resetcore(sdiodev, ci, BCMA_CORE_INTERNAL_MEM, 0, 0, 0);
939 /* clear length token */
940 brcmf_sdiod_ramrw(sdiodev, true, ci->ramsize - 4, (u8 *)&zeros, 4);
941} 879}
942 880
943static bool 881static bool brcmf_sdio_chip_cm3_exitdl(struct brcmf_sdio_dev *sdiodev,
944brcmf_sdio_chip_cm3_exitdl(struct brcmf_sdio_dev *sdiodev, struct chip_info *ci, 882 struct brcmf_chip *ci)
945 char *nvram_dat, uint nvram_sz)
946{ 883{
947 u8 core_idx; 884 u8 core_idx;
948 u32 reg_addr; 885 u32 reg_addr;
@@ -952,38 +889,45 @@ brcmf_sdio_chip_cm3_exitdl(struct brcmf_sdio_dev *sdiodev, struct chip_info *ci,
952 return false; 889 return false;
953 } 890 }
954 891
955 if (!brcmf_sdio_chip_writenvram(sdiodev, ci, nvram_dat, nvram_sz))
956 return false;
957
958 /* clear all interrupts */ 892 /* clear all interrupts */
959 core_idx = brcmf_sdio_chip_getinfidx(ci, BCMA_CORE_SDIO_DEV); 893 core_idx = brcmf_sdio_chip_getinfidx(ci, BCMA_CORE_SDIO_DEV);
960 reg_addr = ci->c_inf[core_idx].base; 894 reg_addr = ci->c_inf[core_idx].base;
961 reg_addr += offsetof(struct sdpcmd_regs, intstatus); 895 reg_addr += offsetof(struct sdpcmd_regs, intstatus);
962 brcmf_sdiod_regwl(sdiodev, reg_addr, 0xFFFFFFFF, NULL); 896 brcmf_sdiod_regwl(sdiodev, reg_addr, 0xFFFFFFFF, NULL);
963 897
964 ci->resetcore(sdiodev, ci, BCMA_CORE_ARM_CM3, 0); 898 ci->resetcore(sdiodev, ci, BCMA_CORE_ARM_CM3, 0, 0, 0);
965 899
966 return true; 900 return true;
967} 901}
968 902
969static inline void 903static inline void
970brcmf_sdio_chip_cr4_enterdl(struct brcmf_sdio_dev *sdiodev, 904brcmf_sdio_chip_cr4_enterdl(struct brcmf_sdio_dev *sdiodev,
971 struct chip_info *ci) 905 struct brcmf_chip *ci)
972{ 906{
973 ci->resetcore(sdiodev, ci, BCMA_CORE_ARM_CR4, 907 u8 idx;
974 ARMCR4_BCMA_IOCTL_CPUHALT); 908 u32 regdata;
909 u32 wrapbase;
910 idx = brcmf_sdio_chip_getinfidx(ci, BCMA_CORE_ARM_CR4);
911
912 if (idx == BRCMF_MAX_CORENUM)
913 return;
914
915 wrapbase = ci->c_inf[idx].wrapbase;
916 regdata = brcmf_sdiod_regrl(sdiodev, wrapbase + BCMA_IOCTL, NULL);
917 regdata &= ARMCR4_BCMA_IOCTL_CPUHALT;
918 ci->resetcore(sdiodev, ci, BCMA_CORE_ARM_CR4, regdata,
919 ARMCR4_BCMA_IOCTL_CPUHALT, ARMCR4_BCMA_IOCTL_CPUHALT);
920 ci->resetcore(sdiodev, ci, BCMA_CORE_80211,
921 D11_BCMA_IOCTL_PHYRESET | D11_BCMA_IOCTL_PHYCLOCKEN,
922 D11_BCMA_IOCTL_PHYCLOCKEN, D11_BCMA_IOCTL_PHYCLOCKEN);
975} 923}
976 924
977static bool 925static bool brcmf_sdio_chip_cr4_exitdl(struct brcmf_sdio_dev *sdiodev,
978brcmf_sdio_chip_cr4_exitdl(struct brcmf_sdio_dev *sdiodev, struct chip_info *ci, 926 struct brcmf_chip *ci, u32 rstvec)
979 char *nvram_dat, uint nvram_sz)
980{ 927{
981 u8 core_idx; 928 u8 core_idx;
982 u32 reg_addr; 929 u32 reg_addr;
983 930
984 if (!brcmf_sdio_chip_writenvram(sdiodev, ci, nvram_dat, nvram_sz))
985 return false;
986
987 /* clear all interrupts */ 931 /* clear all interrupts */
988 core_idx = brcmf_sdio_chip_getinfidx(ci, BCMA_CORE_SDIO_DEV); 932 core_idx = brcmf_sdio_chip_getinfidx(ci, BCMA_CORE_SDIO_DEV);
989 reg_addr = ci->c_inf[core_idx].base; 933 reg_addr = ci->c_inf[core_idx].base;
@@ -991,17 +935,18 @@ brcmf_sdio_chip_cr4_exitdl(struct brcmf_sdio_dev *sdiodev, struct chip_info *ci,
991 brcmf_sdiod_regwl(sdiodev, reg_addr, 0xFFFFFFFF, NULL); 935 brcmf_sdiod_regwl(sdiodev, reg_addr, 0xFFFFFFFF, NULL);
992 936
993 /* Write reset vector to address 0 */ 937 /* Write reset vector to address 0 */
994 brcmf_sdiod_ramrw(sdiodev, true, 0, (void *)&ci->rst_vec, 938 brcmf_sdiod_ramrw(sdiodev, true, 0, (void *)&rstvec,
995 sizeof(ci->rst_vec)); 939 sizeof(rstvec));
996 940
997 /* restore ARM */ 941 /* restore ARM */
998 ci->resetcore(sdiodev, ci, BCMA_CORE_ARM_CR4, 0); 942 ci->resetcore(sdiodev, ci, BCMA_CORE_ARM_CR4, ARMCR4_BCMA_IOCTL_CPUHALT,
943 0, 0);
999 944
1000 return true; 945 return true;
1001} 946}
1002 947
1003void brcmf_sdio_chip_enter_download(struct brcmf_sdio_dev *sdiodev, 948void brcmf_sdio_chip_enter_download(struct brcmf_sdio_dev *sdiodev,
1004 struct chip_info *ci) 949 struct brcmf_chip *ci)
1005{ 950{
1006 u8 arm_core_idx; 951 u8 arm_core_idx;
1007 952
@@ -1015,15 +960,13 @@ void brcmf_sdio_chip_enter_download(struct brcmf_sdio_dev *sdiodev,
1015} 960}
1016 961
1017bool brcmf_sdio_chip_exit_download(struct brcmf_sdio_dev *sdiodev, 962bool brcmf_sdio_chip_exit_download(struct brcmf_sdio_dev *sdiodev,
1018 struct chip_info *ci, char *nvram_dat, 963 struct brcmf_chip *ci, u32 rstvec)
1019 uint nvram_sz)
1020{ 964{
1021 u8 arm_core_idx; 965 u8 arm_core_idx;
1022 966
1023 arm_core_idx = brcmf_sdio_chip_getinfidx(ci, BCMA_CORE_ARM_CM3); 967 arm_core_idx = brcmf_sdio_chip_getinfidx(ci, BCMA_CORE_ARM_CM3);
1024 if (BRCMF_MAX_CORENUM != arm_core_idx) 968 if (BRCMF_MAX_CORENUM != arm_core_idx)
1025 return brcmf_sdio_chip_cm3_exitdl(sdiodev, ci, nvram_dat, 969 return brcmf_sdio_chip_cm3_exitdl(sdiodev, ci);
1026 nvram_sz);
1027 970
1028 return brcmf_sdio_chip_cr4_exitdl(sdiodev, ci, nvram_dat, nvram_sz); 971 return brcmf_sdio_chip_cr4_exitdl(sdiodev, ci, rstvec);
1029} 972}
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.h b/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.h
index 7ea424e20773..fb0614329ede 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.h
@@ -54,7 +54,7 @@
54 54
55#define BRCMF_MAX_CORENUM 6 55#define BRCMF_MAX_CORENUM 6
56 56
57struct chip_core_info { 57struct brcmf_core {
58 u16 id; 58 u16 id;
59 u16 rev; 59 u16 rev;
60 u32 base; 60 u32 base;
@@ -63,27 +63,28 @@ struct chip_core_info {
63 u32 cib; 63 u32 cib;
64}; 64};
65 65
66struct chip_info { 66struct brcmf_chip {
67 u32 chip; 67 u32 chip;
68 u32 chiprev; 68 u32 chiprev;
69 u32 socitype;
70 /* core info */ 69 /* core info */
71 /* always put chipcommon core at 0, bus core at 1 */ 70 /* always put chipcommon core at 0, bus core at 1 */
72 struct chip_core_info c_inf[BRCMF_MAX_CORENUM]; 71 struct brcmf_core c_inf[BRCMF_MAX_CORENUM];
73 u32 pmurev; 72 u32 pmurev;
74 u32 pmucaps; 73 u32 pmucaps;
75 u32 ramsize; 74 u32 ramsize;
76 u32 rambase; 75 u32 rambase;
77 u32 rst_vec; /* reset vertor for ARM CR4 core */ 76 u32 rst_vec; /* reset vertor for ARM CR4 core */
78 77
79 bool (*iscoreup)(struct brcmf_sdio_dev *sdiodev, struct chip_info *ci, 78 bool (*iscoreup)(struct brcmf_sdio_dev *sdiodev, struct brcmf_chip *ci,
80 u16 coreid); 79 u16 coreid);
81 u32 (*corerev)(struct brcmf_sdio_dev *sdiodev, struct chip_info *ci, 80 u32 (*corerev)(struct brcmf_sdio_dev *sdiodev, struct brcmf_chip *ci,
82 u16 coreid); 81 u16 coreid);
83 void (*coredisable)(struct brcmf_sdio_dev *sdiodev, 82 void (*coredisable)(struct brcmf_sdio_dev *sdiodev,
84 struct chip_info *ci, u16 coreid, u32 core_bits); 83 struct brcmf_chip *ci, u16 coreid, u32 pre_resetbits,
84 u32 in_resetbits);
85 void (*resetcore)(struct brcmf_sdio_dev *sdiodev, 85 void (*resetcore)(struct brcmf_sdio_dev *sdiodev,
86 struct chip_info *ci, u16 coreid, u32 core_bits); 86 struct brcmf_chip *ci, u16 coreid, u32 pre_resetbits,
87 u32 in_resetbits, u32 post_resetbits);
87}; 88};
88 89
89struct sbconfig { 90struct sbconfig {
@@ -216,15 +217,15 @@ struct sdpcmd_regs {
216}; 217};
217 218
218int brcmf_sdio_chip_attach(struct brcmf_sdio_dev *sdiodev, 219int brcmf_sdio_chip_attach(struct brcmf_sdio_dev *sdiodev,
219 struct chip_info **ci_ptr); 220 struct brcmf_chip **ci_ptr);
220void brcmf_sdio_chip_detach(struct chip_info **ci_ptr); 221void brcmf_sdio_chip_detach(struct brcmf_chip **ci_ptr);
221void brcmf_sdio_chip_drivestrengthinit(struct brcmf_sdio_dev *sdiodev, 222void brcmf_sdio_chip_drivestrengthinit(struct brcmf_sdio_dev *sdiodev,
222 struct chip_info *ci, u32 drivestrength); 223 struct brcmf_chip *ci,
223u8 brcmf_sdio_chip_getinfidx(struct chip_info *ci, u16 coreid); 224 u32 drivestrength);
225u8 brcmf_sdio_chip_getinfidx(struct brcmf_chip *ci, u16 coreid);
224void brcmf_sdio_chip_enter_download(struct brcmf_sdio_dev *sdiodev, 226void brcmf_sdio_chip_enter_download(struct brcmf_sdio_dev *sdiodev,
225 struct chip_info *ci); 227 struct brcmf_chip *ci);
226bool brcmf_sdio_chip_exit_download(struct brcmf_sdio_dev *sdiodev, 228bool brcmf_sdio_chip_exit_download(struct brcmf_sdio_dev *sdiodev,
227 struct chip_info *ci, char *nvram_dat, 229 struct brcmf_chip *ci, u32 rstvec);
228 uint nvram_sz);
229 230
230#endif /* _BRCMFMAC_SDIO_CHIP_H_ */ 231#endif /* _BRCMFMAC_SDIO_CHIP_H_ */
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/usb.c b/drivers/net/wireless/brcm80211/brcmfmac/usb.c
index c345c32eb631..24f65cd53859 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/usb.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/usb.c
@@ -522,10 +522,10 @@ brcmf_usb_state_change(struct brcmf_usbdev_info *devinfo, int state)
522 /* update state of upper layer */ 522 /* update state of upper layer */
523 if (state == BRCMFMAC_USB_STATE_DOWN) { 523 if (state == BRCMFMAC_USB_STATE_DOWN) {
524 brcmf_dbg(USB, "DBUS is down\n"); 524 brcmf_dbg(USB, "DBUS is down\n");
525 bcmf_bus->state = BRCMF_BUS_DOWN; 525 brcmf_bus_change_state(bcmf_bus, BRCMF_BUS_DOWN);
526 } else if (state == BRCMFMAC_USB_STATE_UP) { 526 } else if (state == BRCMFMAC_USB_STATE_UP) {
527 brcmf_dbg(USB, "DBUS is up\n"); 527 brcmf_dbg(USB, "DBUS is up\n");
528 bcmf_bus->state = BRCMF_BUS_DATA; 528 brcmf_bus_change_state(bcmf_bus, BRCMF_BUS_DATA);
529 } else { 529 } else {
530 brcmf_dbg(USB, "DBUS current state=%d\n", state); 530 brcmf_dbg(USB, "DBUS current state=%d\n", state);
531 } 531 }
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
index aad83aef7d93..d7718a5fa2f0 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
@@ -2989,6 +2989,7 @@ brcmf_notify_sched_scan_results(struct brcmf_if *ifp,
2989 } 2989 }
2990 2990
2991 set_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status); 2991 set_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
2992 cfg->escan_info.run = brcmf_run_escan;
2992 err = brcmf_do_escan(cfg, wiphy, ifp, request); 2993 err = brcmf_do_escan(cfg, wiphy, ifp, request);
2993 if (err) { 2994 if (err) {
2994 clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status); 2995 clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
index e71ce8c842a2..925034b80e9c 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
@@ -1071,7 +1071,6 @@ static int ieee_hw_init(struct ieee80211_hw *hw)
1071 hw->max_rates = 2; /* Primary rate and 1 fallback rate */ 1071 hw->max_rates = 2; /* Primary rate and 1 fallback rate */
1072 1072
1073 /* channel change time is dependent on chip and band */ 1073 /* channel change time is dependent on chip and band */
1074 hw->channel_change_time = 7 * 1000;
1075 hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | 1074 hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
1076 BIT(NL80211_IFTYPE_AP) | 1075 BIT(NL80211_IFTYPE_AP) |
1077 BIT(NL80211_IFTYPE_ADHOC); 1076 BIT(NL80211_IFTYPE_ADHOC);
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/main.c b/drivers/net/wireless/brcm80211/brcmsmac/main.c
index 8138f1cff4e5..9417cb5a2553 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/main.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c
@@ -7108,7 +7108,6 @@ prep_mac80211_status(struct brcms_c_info *wlc, struct d11rxhdr *rxh,
7108 struct sk_buff *p, 7108 struct sk_buff *p,
7109 struct ieee80211_rx_status *rx_status) 7109 struct ieee80211_rx_status *rx_status)
7110{ 7110{
7111 int preamble;
7112 int channel; 7111 int channel;
7113 u32 rspec; 7112 u32 rspec;
7114 unsigned char *plcp; 7113 unsigned char *plcp;
@@ -7191,7 +7190,6 @@ prep_mac80211_status(struct brcms_c_info *wlc, struct d11rxhdr *rxh,
7191 rx_status->rate_idx -= BRCMS_LEGACY_5G_RATE_OFFSET; 7190 rx_status->rate_idx -= BRCMS_LEGACY_5G_RATE_OFFSET;
7192 7191
7193 /* Determine short preamble and rate_idx */ 7192 /* Determine short preamble and rate_idx */
7194 preamble = 0;
7195 if (is_cck_rate(rspec)) { 7193 if (is_cck_rate(rspec)) {
7196 if (rxh->PhyRxStatus_0 & PRXS0_SHORTH) 7194 if (rxh->PhyRxStatus_0 & PRXS0_SHORTH)
7197 rx_status->flag |= RX_FLAG_SHORTPRE; 7195 rx_status->flag |= RX_FLAG_SHORTPRE;