diff options
Diffstat (limited to 'drivers/net/wireless/brcm80211')
-rw-r--r-- | drivers/net/wireless/brcm80211/brcmfmac/Makefile | 1 | ||||
-rw-r--r-- | drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c | 40 | ||||
-rw-r--r-- | drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h | 21 | ||||
-rw-r--r-- | drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c | 4 | ||||
-rw-r--r-- | drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c | 339 | ||||
-rw-r--r-- | drivers/net/wireless/brcm80211/brcmfmac/nvram.c | 94 | ||||
-rw-r--r-- | drivers/net/wireless/brcm80211/brcmfmac/nvram.h | 24 | ||||
-rw-r--r-- | drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c | 593 | ||||
-rw-r--r-- | drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.h | 31 | ||||
-rw-r--r-- | drivers/net/wireless/brcm80211/brcmfmac/usb.c | 4 | ||||
-rw-r--r-- | drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c | 1 | ||||
-rw-r--r-- | drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c | 1 | ||||
-rw-r--r-- | drivers/net/wireless/brcm80211/brcmsmac/main.c | 2 |
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 |
36 | brcmfmac-$(CONFIG_BRCMFMAC_SDIO) += \ | 37 | brcmfmac-$(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 | ||
853 | static int brcmf_sdiod_remove(struct brcmf_sdio_dev *sdiodev) | 867 | static 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 */ |
21 | enum brcmf_bus_state { | 23 | enum 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 | |||
152 | static inline bool brcmf_bus_ready(struct brcmf_bus *bus) | ||
153 | { | ||
154 | return bus->state == BRCMF_BUS_LOAD || bus->state == BRCMF_BUS_DATA; | ||
155 | } | ||
156 | |||
157 | static 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 */ |
369 | struct brcmf_sdio { | 370 | struct 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 | ||
3198 | static bool brcmf_sdio_download_state(struct brcmf_sdio *bus, bool enter) | 3168 | #ifdef DEBUG |
3169 | static bool | ||
3170 | brcmf_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 */ | ||
3214 | static bool | ||
3215 | brcmf_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 | ||
3223 | static int brcmf_sdio_download_code_file(struct brcmf_sdio *bus) | 3222 | static 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) | |
3256 | failure: | 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 | /* | 3256 | static 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 | |||
3271 | static 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; | ||
3331 | err: | ||
3332 | vfree(varbuf); | ||
3333 | return ret; | ||
3334 | } | ||
3335 | 3265 | ||
3336 | static 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 | ||
3352 | static int brcmf_sdio_download_firmware(struct brcmf_sdio *bus) | 3284 | static 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 | ||
3384 | err: | 3335 | err: |
@@ -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 | */ | ||
28 | void *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 | |||
89 | void 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 | |||
20 | void *brcmf_nvram_strip(const struct firmware *nv, u32 *new_length); | ||
21 | void 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 */ |
71 | struct sdiod_drive_str { | 78 | struct sdiod_drive_str { |
@@ -111,7 +118,7 @@ static const struct sdiod_drive_str sdiod_drvstr_tab2_3v3[] = { | |||
111 | }; | 118 | }; |
112 | 119 | ||
113 | u8 | 120 | u8 |
114 | brcmf_sdio_chip_getinfidx(struct chip_info *ci, u16 coreid) | 121 | brcmf_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 | ||
125 | static u32 | 132 | static u32 |
126 | brcmf_sdio_sb_corerev(struct brcmf_sdio_dev *sdiodev, | 133 | brcmf_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 | ||
140 | static u32 | 147 | static u32 |
141 | brcmf_sdio_ai_corerev(struct brcmf_sdio_dev *sdiodev, | 148 | brcmf_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 | ||
151 | static bool | 158 | static bool |
152 | brcmf_sdio_sb_iscoreup(struct brcmf_sdio_dev *sdiodev, | 159 | brcmf_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 | ||
170 | static bool | 177 | static bool |
171 | brcmf_sdio_ai_iscoreup(struct brcmf_sdio_dev *sdiodev, | 178 | brcmf_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 | ||
194 | static void | 201 | static void |
195 | brcmf_sdio_sb_coredisable(struct brcmf_sdio_dev *sdiodev, | 202 | brcmf_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 | ||
280 | static void | 288 | static void |
281 | brcmf_sdio_ai_coredisable(struct brcmf_sdio_dev *sdiodev, | 289 | brcmf_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 | ||
325 | static void | 328 | static void |
326 | brcmf_sdio_sb_resetcore(struct brcmf_sdio_dev *sdiodev, | 329 | brcmf_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 | ||
391 | static void | 396 | static void |
392 | brcmf_sdio_ai_resetcore(struct brcmf_sdio_dev *sdiodev, | 397 | brcmf_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 */ |
426 | static int brcmf_sdio_chip_cichk(struct chip_info *ci) | 428 | static 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 */ |
453 | static inline int brcmf_sdio_chip_cichk(struct chip_info *ci) | 455 | static 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 | ||
459 | static int brcmf_sdio_chip_recognition(struct brcmf_sdio_dev *sdiodev, | 461 | static 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 | ||
638 | static int | 664 | static int |
@@ -682,7 +708,7 @@ brcmf_sdio_chip_buscoreprep(struct brcmf_sdio_dev *sdiodev) | |||
682 | 708 | ||
683 | static void | 709 | static void |
684 | brcmf_sdio_chip_buscoresetup(struct brcmf_sdio_dev *sdiodev, | 710 | brcmf_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 | ||
719 | int brcmf_sdio_chip_attach(struct brcmf_sdio_dev *sdiodev, | 745 | int 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 | ||
755 | void | 780 | void |
756 | brcmf_sdio_chip_detach(struct chip_info **ci_ptr) | 781 | brcmf_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 | ||
773 | void | 798 | void |
774 | brcmf_sdio_chip_drivestrengthinit(struct brcmf_sdio_dev *sdiodev, | 799 | brcmf_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 | ||
846 | static bool | ||
847 | brcmf_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 */ | ||
879 | static inline bool | ||
880 | brcmf_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 | |||
887 | static 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 | |||
930 | static void | 870 | static void |
931 | brcmf_sdio_chip_cm3_enterdl(struct brcmf_sdio_dev *sdiodev, | 871 | brcmf_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 | ||
943 | static bool | 881 | static bool brcmf_sdio_chip_cm3_exitdl(struct brcmf_sdio_dev *sdiodev, |
944 | brcmf_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 | ||
969 | static inline void | 903 | static inline void |
970 | brcmf_sdio_chip_cr4_enterdl(struct brcmf_sdio_dev *sdiodev, | 904 | brcmf_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 | ||
977 | static bool | 925 | static bool brcmf_sdio_chip_cr4_exitdl(struct brcmf_sdio_dev *sdiodev, |
978 | brcmf_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 | ||
1003 | void brcmf_sdio_chip_enter_download(struct brcmf_sdio_dev *sdiodev, | 948 | void 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 | ||
1017 | bool brcmf_sdio_chip_exit_download(struct brcmf_sdio_dev *sdiodev, | 962 | bool 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 | ||
57 | struct chip_core_info { | 57 | struct 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 | ||
66 | struct chip_info { | 66 | struct 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 | ||
89 | struct sbconfig { | 90 | struct sbconfig { |
@@ -216,15 +217,15 @@ struct sdpcmd_regs { | |||
216 | }; | 217 | }; |
217 | 218 | ||
218 | int brcmf_sdio_chip_attach(struct brcmf_sdio_dev *sdiodev, | 219 | int brcmf_sdio_chip_attach(struct brcmf_sdio_dev *sdiodev, |
219 | struct chip_info **ci_ptr); | 220 | struct brcmf_chip **ci_ptr); |
220 | void brcmf_sdio_chip_detach(struct chip_info **ci_ptr); | 221 | void brcmf_sdio_chip_detach(struct brcmf_chip **ci_ptr); |
221 | void brcmf_sdio_chip_drivestrengthinit(struct brcmf_sdio_dev *sdiodev, | 222 | void brcmf_sdio_chip_drivestrengthinit(struct brcmf_sdio_dev *sdiodev, |
222 | struct chip_info *ci, u32 drivestrength); | 223 | struct brcmf_chip *ci, |
223 | u8 brcmf_sdio_chip_getinfidx(struct chip_info *ci, u16 coreid); | 224 | u32 drivestrength); |
225 | u8 brcmf_sdio_chip_getinfidx(struct brcmf_chip *ci, u16 coreid); | ||
224 | void brcmf_sdio_chip_enter_download(struct brcmf_sdio_dev *sdiodev, | 226 | void brcmf_sdio_chip_enter_download(struct brcmf_sdio_dev *sdiodev, |
225 | struct chip_info *ci); | 227 | struct brcmf_chip *ci); |
226 | bool brcmf_sdio_chip_exit_download(struct brcmf_sdio_dev *sdiodev, | 228 | bool 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; |